diff -Nru cgal-4.4/auxiliary/cgal_create_cmake_script.1 cgal-4.5/auxiliary/cgal_create_cmake_script.1 --- cgal-4.4/auxiliary/cgal_create_cmake_script.1 2014-04-03 19:02:08.000000000 +0000 +++ cgal-4.5/auxiliary/cgal_create_cmake_script.1 2014-10-09 19:00:35.000000000 +0000 @@ -1,4 +1,4 @@ -.TH CGAL_CREATE_CMAKE_SCRIPT "1" "April 2014" "CGAL 4.4" "User Commands" +.TH CGAL_CREATE_CMAKE_SCRIPT "1" "October 2014" "CGAL 4.5" "User Commands" .SH NAME cgal_create_cmake_script \- create a cmake script for applications using CGAL .SH SYNOPSIS diff -Nru cgal-4.4/auxiliary/taucs/include/README cgal-4.5/auxiliary/taucs/include/README --- cgal-4.4/auxiliary/taucs/include/README 2013-08-22 14:22:06.000000000 +0000 +++ cgal-4.5/auxiliary/taucs/include/README 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -If the Windows installer is used, this directory will contain headers of -the BLAS, LAPACK, and TAUCS libraries. diff -Nru cgal-4.4/auxiliary/taucs/lib/README cgal-4.5/auxiliary/taucs/lib/README --- cgal-4.4/auxiliary/taucs/lib/README 2013-08-22 14:22:06.000000000 +0000 +++ cgal-4.5/auxiliary/taucs/lib/README 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -If the Windows installer is used, this directory will contain precompiled -binaries of the BLAS, LAPACK, and TAUCS libraries. diff -Nru cgal-4.4/CHANGES cgal-4.5/CHANGES --- cgal-4.4/CHANGES 2014-04-03 19:00:30.000000000 +0000 +++ cgal-4.5/CHANGES 2014-10-06 19:00:05.000000000 +0000 @@ -1,4 +1,177 @@ +-------------------------------- Release 4.5 -------------------------------- + +Release date: October 2014 + + +* Installation + + - Changes in the set of supported platforms: + + - The Microsoft Windows Visual C++ compiler 2008 (VC9) is no longer + supported since CGAL-4.5. + + + - Since CGAL version 4.0, Eigen was the recommended third-party library to + use with Planar Parameterization of Triangulated Surface Meshes, Surface + Reconstruction from Point Sets, Approximation of Ridges and Umbilics on + Triangulated Surface Meshes, and Estimation of Local Differential + Properties of Point-Sampled Surfaces packages. From CGAL version 4.5, + Taucs, Blas and Lapack are no longer supported. + + - CGAL is now compatible with the new CMake version 3.0. + + +* Triangulated Surface Mesh Deformation (new package) + + - This package allows to deform a triangulated surface mesh under positional + constraints of some of its vertices without requiring any additional + structure other than the surface mesh itself. The methods provided + implements an as-rigid-as-possible deformation. Note that the main class + name has changed between the 4.5-beta1 and the 4.5 releases to better match + the CGAL naming conventions (from CGAL::Deform_mesh to CGAL:: + Surface_mesh_deformation). + + +* CGAL and the Boost Graph Library (major changes) + + - Cleanup of the HalfedgeGraph concept. In particular: + + - Introduction of the notion of halfedge_descriptor in the specialization + of the class boost::graph_traits. + + - Deprecation of halfedge_graph_traits. + + - A model of HalfedgeGraph is considered as an undirected graph. Thus any + call to edges() should be replaced by halfedges() and num_edges() now + returns the number of (undirected) edges. + + - Breaking change: is_border_edge and is_border_halfedge properties are + removed. The free functions is_border() and is_border_edge() should be + used instead. + + - Renaming of HalfedgeGraph specific free functions. + + + - Introduction of the FaceGraph concept. + + - Adaptation of the package Triangulated Surface Mesh Simplification and of + the class AABB_halfedge_graph_segment_primitive from the package 3D Fast + Intersection and Distance Computation to the API change. + + - Update of the package Triangulated Surface Mesh Segmentation and of the + class AABB_face_graph_triangle_primitive from the package 3D Fast + Intersection and Distance Computation to accept model of the newly + introduced concepts. + + - Offer Euler operations as free functions for models of the graph concepts + provided by CGAL. + + - Specialization of boost::graph_traits for OpenMesh::PolyMesh_ArrayKernelT + as proof of concept. A OpenMesh::PolyMesh_ArrayKernelT becomes a model of + the aforementioned concepts when including CGAL/boost/graph/ + graph_traits_PolyMesh_ArrayKernelT.h. + + +* dD Geometry Kernel + + - A new model Epick_d of the Kernel_d concept is introduced. It provides + better performance through arithmetic filtering and specializations for + fixed dimensions. It may not work with compilers as old as gcc-4.2, but was + tested with gcc-4.4. + + +* 3D Convex Hulls + + - Clean up the documentation of the concepts + + +* 2D Arrangements + + - Fixed a bug in removing an unbounded curve (e.g., a ray) from an + arrangement induced by unbounded curves. + + +* 2D Snap Rounding + + - Replaced use of private kd_tree with CGAL's official Kd_tree from + Spatial_searching package; results in a small performance gain. Removed the + private kd_tree package. + + +* 3D Triangulations + + - Add an experimental parallel version of the Delaunay triangulation and the + regular triangulation algorithms, which allows parallel insertion and + removal of point ranges. + + +* 3D Mesh Generation + + - Add a new constructor for the class Labeled_mesh_domain_3 which takes an + Iso_cuboid_3. + + - Add a new labeling function wrapper for meshing multi-domain. + + - The meshing functionality in the Qt demos in demo/Polyhedron/ and demo/ + Mesh_3/ can now use the handling of 1d-features, that exists in CGAL since + version 3.8. + + - Add an experimental parallel version of the 3D mesh refinement and mesh + optimization methods. + + - Add caching of circumcenters to Regular_triangulation_cell_base_3. The + cache value is computed when cell->circumcenter() or rt.dual(cell) + functions are called. + + +* Point Set Processing and Surface Reconstruction from Point Sets + + - The former demo has been removed and is fully merge in the Polyhedron demo. + + +* Point Set Processing + + - Workaround a bug in dijsktra shortest path of boost 1.54 by shipping and + using the boost header from the 1.55 release. This header will be used only + if you are using the version 1.54 of boost. + + +* Triangulated Surface Mesh Simplification + + - Breaking change: Due to the cleanup of the concepts of the package CGAL and + the Boost Graph Library, the named parameter edge_is_border_map has been + removed, and the named parameter edge_is_constrained_map now expects a + property map with an edge descriptor as key type (vs. halfedge descriptor + before). + + - Add some optimization in the code making the implementation faster + (depending on the cost and the placement chosen). However, for an edge + which collapse is not topologically valid, the vector of vertices of the + link provided by its profile might contains duplicates, thus also breaking + the orientation guarantee in the vector. This must not be a problem for + users as the edge is not collapsible anyway but if it is a absolute + requirement for user defined cost/placement, defining the macro + CGAL_SMS_EDGE_PROFILE_ALWAYS_NEED_UNIQUE_VERTEX_IN_LINK will restore the + former behavior. + + +* dD Spatial Searching + + - Added methods reserve(size_t size) and size_t capacity() to class Kd_tree + to allocate memory to store size points and to report that number (STL + compliance). + + +* STL Extensions for CGAL + + - Add Compact_container::operator[], allowing a direct access to the ith + element of a compact container. + + - Add Concurrent_compact_container, a compact container which allows + concurrent insertion and removal. + + -------------------------------- Release 4.4 -------------------------------- Release date: April 2014 @@ -77,6 +250,11 @@ the spatial sorting in order to speed up the time needed for the insertion. +* 3D Periodic Triangulations + + - Add a method to locate point with inexact predicates. + + * 3D Alpha Shapes - Add member functions in CGAL::Alpha_shape_3 to give access to the alpha diff -Nru cgal-4.4/cmake/modules/CGALConfig_binary.cmake.in cgal-4.5/cmake/modules/CGALConfig_binary.cmake.in --- cgal-4.4/cmake/modules/CGALConfig_binary.cmake.in 2012-11-17 20:00:25.000000000 +0000 +++ cgal-4.5/cmake/modules/CGALConfig_binary.cmake.in 2014-08-29 13:58:16.000000000 +0000 @@ -138,3 +138,4 @@ set(CGAL_SUPPORTING_3RD_PARTY_LIBRARIES "@CGAL_SUPPORTING_3RD_PARTY_LIBRARIES@") set(CGAL_ESSENTIAL_3RD_PARTY_LIBRARIES "@CGAL_ESSENTIAL_3RD_PARTY_LIBRARIES@") +set(CGAL_DISABLE_GMP "@CGAL_DISABLE_GMP@") diff -Nru cgal-4.4/cmake/modules/CGALConfig_install.cmake.in cgal-4.5/cmake/modules/CGALConfig_install.cmake.in --- cgal-4.4/cmake/modules/CGALConfig_install.cmake.in 2012-11-17 20:00:25.000000000 +0000 +++ cgal-4.5/cmake/modules/CGALConfig_install.cmake.in 2014-08-29 13:58:16.000000000 +0000 @@ -137,3 +137,4 @@ set(CGAL_SUPPORTING_3RD_PARTY_LIBRARIES "@CGAL_SUPPORTING_3RD_PARTY_LIBRARIES@") set(CGAL_ESSENTIAL_3RD_PARTY_LIBRARIES "@CGAL_ESSENTIAL_3RD_PARTY_LIBRARIES@") +set(CGAL_DISABLE_GMP "@CGAL_DISABLE_GMP@") diff -Nru cgal-4.4/cmake/modules/CGAL_Macros.cmake cgal-4.5/cmake/modules/CGAL_Macros.cmake --- cgal-4.4/cmake/modules/CGAL_Macros.cmake 2012-12-08 20:00:20.000000000 +0000 +++ cgal-4.5/cmake/modules/CGAL_Macros.cmake 2014-08-29 13:58:16.000000000 +0000 @@ -361,19 +361,27 @@ # - or even less specific if order becomes less relevant # Eric Berberich 2012/06/29 - if(RS_FOUND) - use_component( RS ) - endif() - - if(MPFI_FOUND) - use_component( MPFI ) - endif() - - use_component( MPFR ) - if (GMPXX_FOUND) - use_component( GMPXX ) - endif() - use_component( GMP ) + if(NOT CGAL_DISABLE_GMP) + if(RS_FOUND) + use_component( RS ) + endif() + + if(MPFI_FOUND) + use_component( MPFI ) + endif() + + if(MPFR_FOUND) + use_component( MPFR ) + endif() + + if (GMPXX_FOUND) + use_component( GMPXX ) + endif() + + if(GMP_FOUND) + use_component( GMP ) + endif() + endif(NOT CGAL_DISABLE_GMP) if(LEDA_FOUND) use_component( LEDA ) diff -Nru cgal-4.4/cmake/modules/CGAL_SetupDependencies.cmake cgal-4.5/cmake/modules/CGAL_SetupDependencies.cmake --- cgal-4.4/cmake/modules/CGAL_SetupDependencies.cmake 2012-12-29 20:00:16.000000000 +0000 +++ cgal-4.5/cmake/modules/CGAL_SetupDependencies.cmake 2014-08-29 13:58:16.000000000 +0000 @@ -56,7 +56,7 @@ if (${lib} STREQUAL "LEDA") # special case for LEDA - add a flag - message( STATUS "$LEDA cxx flags: ${LEDA_CXX_FLAGS}" ) + message( STATUS "LEDA cxx flags: ${LEDA_CXX_FLAGS}" ) uniquely_add_flags( CMAKE_CXX_FLAGS ${LEDA_CXX_FLAGS} ) endif() diff -Nru cgal-4.4/cmake/modules/CGAL_UseLEDA.cmake cgal-4.5/cmake/modules/CGAL_UseLEDA.cmake --- cgal-4.4/cmake/modules/CGAL_UseLEDA.cmake 2012-11-13 13:13:55.000000000 +0000 +++ cgal-4.5/cmake/modules/CGAL_UseLEDA.cmake 2014-08-29 13:58:16.000000000 +0000 @@ -3,7 +3,6 @@ if ( LEDA_FOUND AND NOT LEDA_SETUP ) - message( STATUS "UseLEDA" ) message( STATUS "LEDA include: ${LEDA_INCLUDE_DIR}" ) include_directories ( SYSTEM ${LEDA_INCLUDE_DIR} ) diff -Nru cgal-4.4/cmake/modules/FindLEDA.cmake cgal-4.5/cmake/modules/FindLEDA.cmake --- cgal-4.4/cmake/modules/FindLEDA.cmake 2012-11-13 13:13:55.000000000 +0000 +++ cgal-4.5/cmake/modules/FindLEDA.cmake 2014-08-29 13:58:16.000000000 +0000 @@ -12,22 +12,22 @@ DOC "The directory containing the LEDA header files WITHOUT the LEDA prefix" ) - find_library(LEDA_LIBRARY_RELEASE NAMES "leda" + find_library(LEDA_LIBRARY_RELEASE NAMES "leda_md" "leda" "leda_numbers_md" "leda_numbers" HINTS ENV LEDA_LIB_DIR ENV LEDA_DIR -# PATH_SUFFIXES lib + PATH_SUFFIXES lib DOC "Path to the LEDA library" ) - find_library(LEDA_LIBRARY_DEBUG NAMES "ledaD" + find_library(LEDA_LIBRARY_DEBUG NAMES "leda_mdd" "ledaD" "leda_numbers_mdd" "leda_numbers" HINTS ENV LEDA_LIB_DIR ENV LEDA_DIR -# PATH_SUFFIXES lib + PATH_SUFFIXES lib DOC "Path to the LEDA library" ) if ( NOT LEDA_INCLUDE_DIR ) - typed_cache_set( FILEPATH "The directory containing the LEDA header files WITHOUT the LEDA prefix" LEDA_INCLUDE_DIR "$ENV{LEDA_INC_DIR}" ) + typed_cache_set( PATH "The directory containing the LEDA header files WITHOUT the LEDA prefix" LEDA_INCLUDE_DIR "$ENV{LEDA_INC_DIR}" ) endif() if ( NOT LEDA_DEFINITIONS ) @@ -94,17 +94,17 @@ get_dependency_version (GCC) if ( NOT "${GCC_VERSION}" VERSION_LESS "4.1" ) set(LEDA_CGAL_FRIEND_INJECTION TRUE) - typed_cache_set( STRING "Add -ffriend-injection on gcc >= 4.1" LEDA_CGAL_FRIEND_INJECTION "Using LEDA with gcc version 4.1 or later: Adding -ffriend-injection") + typed_cache_set( INTERNAL "Add -ffriend-injection on gcc >= 4.1" LEDA_CGAL_FRIEND_INJECTION "Using LEDA with gcc version 4.1 or later: Adding -ffriend-injection") uniquely_add_flags (LEDA_CXX_FLAGS "-ffriend-injection") endif() if ( NOT "${GCC_VERSION}" VERSION_LESS "4.4" ) set(LEDA_CGAL_NO_STRICT_ALIASING TRUE) - typed_cache_set( STRING "Add -fno-strict-aliasing on gcc >= 4.4" LEDA_CGAL_NO_STRICT_ALIASING "Using LEDA with gcc version 4.4 or later: Adding -fno-strict-aliasing") + typed_cache_set( INTERNAL "Add -fno-strict-aliasing on gcc >= 4.4" LEDA_CGAL_NO_STRICT_ALIASING "Using LEDA with gcc version 4.4 or later: Adding -fno-strict-aliasing") uniquely_add_flags (LEDA_CXX_FLAGS "-fno-strict-aliasing") endif() - if ( UNIX ) + if ( UNIX AND IS_DIRECTORY "${LEDA_INCLUDE_DIR}/LEDA/graphics") set(LEDA_CGAL_LINK_X11 TRUE) - typed_cache_set( STRING "Link against X11 on *nix" LEDA_CGAL_LINK_X11 "Using LEDA with gcc on *nix: Adding -lX11") + typed_cache_set( INTERNAL "Link against X11 on *nix" LEDA_CGAL_LINK_X11 "Using LEDA with gcc on *nix: Adding -lX11") uniquely_add_flags( LEDA_LINKER_FLAGS "-lX11" ) endif() endif() diff -Nru cgal-4.4/cmake/modules/FindOpenMesh.cmake cgal-4.5/cmake/modules/FindOpenMesh.cmake --- cgal-4.4/cmake/modules/FindOpenMesh.cmake 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/cmake/modules/FindOpenMesh.cmake 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,50 @@ +#This modules tries to find OpenMesh +# Once done this will define +# +# OpenMesh_FOUND - system has OpenMesh +# OPENMESH_INCLUDE_DIR - OpenMesh include directory +# OPENMESH_LIBRARIES - OpenMesh libraries +# + +# Is it already configured? +if (NOT OpenMesh_FOUND) + + find_path(OPENMESH_INCLUDE_DIR + NAMES OpenMesh/Core/Mesh/ArrayKernel.hh + HINTS ENV OPENMESH_INC_DIR + ENV OPENMESH_DIR + /usr/include + /usr/local/include + PATH_SUFFIXES src + DOC "The directory containing the OpenMesh header files WITHOUT the OpenMesh prefix" + ) + + find_library(OPENMESH_LIBRARY_RELEASE NAMES "OpenMeshCore" + HINTS ENV OPENMESH_LIB_DIR + ENV OPENMESH_DIR + PATH_SUFFIXES lib + DOC "Path to the OpenMeshCore library" + ) + + find_library(OPENMESH_LIBRARY_DEBUG NAMES "OpenMeshCored" + HINTS ENV OPENMESH_LIB_DIR + ENV OPENMESH_DIR + PATH_SUFFIXES lib + DOC "Path to the OpenMeshCored library" + ) + + if(OPENMESH_LIBRARY_RELEASE) + if(OPENMESH_LIBRARY_DEBUG) + set(OPENMESH_LIBRARIES optimized ${OPENMESH_LIBRARY_RELEASE} debug ${OPENMESH_LIBRARY_DEBUG}) + else() + set(OPENMESH_LIBRARIES ${OPENMESH_LIBRARY_RELEASE}) + endif() + endif() +endif() + +include( FindPackageHandleStandardArgs ) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenMesh + REQUIRED_VARS OPENMESH_INCLUDE_DIR OPENMESH_LIBRARIES + FOUND_VAR OpenMesh_FOUND + ) diff -Nru cgal-4.4/cmake/modules/FindTBB.cmake cgal-4.5/cmake/modules/FindTBB.cmake --- cgal-4.4/cmake/modules/FindTBB.cmake 2013-07-06 19:00:27.000000000 +0000 +++ cgal-4.5/cmake/modules/FindTBB.cmake 2014-08-29 13:58:16.000000000 +0000 @@ -57,6 +57,25 @@ # TBB_MALLOCPROXY_DEBUG_LIBRARY, the TBB debug malloc_proxy library (not included in TBB_LIBRARIES since it's optionnal) # TBB_MALLOCPROXY_RELEASE_LIBRARY, the TBB release malloc_proxy library (not included in TBB_LIBRARIES since it's optionnal) +include(CheckCXXSourceCompiles) + +# Usage: +# try_TBB_with_pthread( [additional linker args...]) +function(try_TBB_with_pthread result_var) + set(TBB_try_ts_source " + #include + int main() { + tbb::enumerable_thread_specific< + bool*, + tbb::cache_aligned_allocator, + tbb::ets_key_per_instance> grid; + } + ") + set(CMAKE_REQUIRED_LIBRARIES ${ALL_TBB_LIBRARIES} ${ARGN}) + set(CMAKE_REQUIRED_INCLUDES ${TBB_INCLUDE_DIR}) + check_cxx_source_compiles("${TBB_try_ts_source}" ${result_var}) + set(${result_var} ${${result_var}} PARENT_SCOPE) +endfunction(try_TBB_with_pthread) if (WIN32) # has em64t/vc8 em64t/vc9 @@ -309,6 +328,21 @@ endif (TBB_MALLOC_DEBUG_LIBRARY) endif (TBB_MALLOC_RELEASE_LIBRARY) + if(UNIX AND NOT APPLE) + # On Fedora, code using TBB might need -pthread + + # First check without pthread + try_TBB_with_pthread(TBB_without_pthread) + + if(NOT TBB_without_pthread) + # Then check with -pthread + try_TBB_with_pthread(TBB_with_pthread -pthread) + if(TBB_with_pthread) + list(APPEND ALL_TBB_LIBRARIES general -pthread) + endif(TBB_with_pthread) + endif(NOT TBB_without_pthread) + endif(UNIX AND NOT APPLE) + set (TBB_LIBRARIES ${ALL_TBB_LIBRARIES} CACHE PATH "TBB libraries" FORCE) @@ -331,8 +365,10 @@ endif (TBB_INCLUDE_DIR) if (NOT TBB_FOUND) - message("ERROR: Intel TBB NOT found! Please define the TBBROOT (or TBB_INSTALL_DIR) and/or TBB_ARCH_PLATFORM environment variables.") - message(STATUS "Looked for Threading Building Blocks in ${_TBB_INSTALL_DIR}") + if(NOT TBB_FIND_QUIETLY) + message("ERROR: Intel TBB NOT found! Please define the TBBROOT (or TBB_INSTALL_DIR) and/or TBB_ARCH_PLATFORM environment variables.") + message(STATUS "Looked for Threading Building Blocks in ${_TBB_INSTALL_DIR}") + endif(NOT TBB_FIND_QUIETLY) SET(TBB_INSTALL_DIR "TBB_INSTALL_DIR_NOT_FOUND" CACHE STRING "Intel TBB install directory") # do only throw fatal, if this pkg is REQUIRED if (TBB_FIND_REQUIRED) @@ -350,3 +386,8 @@ endif (TBB_FOUND) set(TBB_USE_FILE "UseTBB") + +### ** Emacs settings ** +### Local Variables: +### cmake-tab-width: 4 +### End: diff -Nru cgal-4.4/cmake/modules/UseOpenMesh.cmake cgal-4.5/cmake/modules/UseOpenMesh.cmake --- cgal-4.4/cmake/modules/UseOpenMesh.cmake 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/cmake/modules/UseOpenMesh.cmake 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,5 @@ +# This module setups the compiler for using the OpenMesh library. +# It assumes that find_package(OpenMesh) was already called. + +include_directories ( ${OPENMESH_INCLUDE_DIR} ) +add_definitions( -DNOMINMAX -D_USE_MATH_DEFINES ) diff -Nru cgal-4.4/CMakeLists.txt cgal-4.5/CMakeLists.txt --- cgal-4.4/CMakeLists.txt 2014-02-15 20:00:24.000000000 +0000 +++ cgal-4.5/CMakeLists.txt 2014-08-29 13:58:16.000000000 +0000 @@ -19,6 +19,21 @@ cmake_policy(VERSION 2.6) endif() +# +# Compatibility with CMake 3.0 +# +if(POLICY CMP0026) + # Allow the LOCATION target property + # http://www.cmake.org/cmake/help/v3.0/policy/CMP0026.html + cmake_policy(SET CMP0026 OLD) +endif() +if(POLICY CMP0042) + # Do not enable the use of MACOSX_RPATH + # http://www.cmake.org/cmake/help/v3.0/policy/CMP0042.html + cmake_policy(SET CMP0042 OLD) +endif() + + #-------------------------------------------------------------------------------------------------- # # -= PACKAGE SETUP =- @@ -324,11 +339,11 @@ # CGAL-4.2 : 10.0.1 (Nothing different in CGAL compiled libraries¹.) # CGAL-4.3 : 10.0.2 (Nothing different in CGAL compiled libraries¹.) # CGAL-4.4 : 10.0.3 (Nothing different in CGAL compiled libraries¹.) - -# ¹) According to abi-http://upstream-tracker.org/versions/cgal.html +# CGAL-4.5 : 10.0.4 (Nothing different in CGAL compiled libraries¹.) +# ¹) According to http://upstream-tracker.org/versions/cgal.html set( CGAL_SONAME_VERSION "10" ) -set( CGAL_SOVERSION "10.0.3" ) +set( CGAL_SOVERSION "10.0.4" ) message( STATUS "CGAL_SONAME_VERSION=${CGAL_SONAME_VERSION}" ) message( STATUS "CGAL_SOVERSION =${CGAL_SOVERSION}" ) @@ -512,7 +527,7 @@ # External libs Qt3 and Qt34are configured when Qt3 or Qt4 as lib of cgal are required # Coin is used in KDS, but no FindCoin or FindCOIN exists # There exists FindF2C, FindIPE, FindMKL, but they are only used to support supporting libs -list (INSERT CGAL_SUPPORTING_3RD_PARTY_LIBRARIES 0 GMP MPFR ZLIB OpenGL LEDA MPFI RS RS3 OpenNL TAUCS Eigen3 BLAS LAPACK QGLViewer ESBTL Coin3D NTL IPE) +list (INSERT CGAL_SUPPORTING_3RD_PARTY_LIBRARIES 0 GMP MPFR ZLIB OpenGL LEDA MPFI RS RS3 OpenNL Eigen3 BLAS LAPACK QGLViewer ESBTL Coin3D NTL IPE) if (NOT WIN32) # GMPXX is not supported on WIN32 machines list (INSERT CGAL_SUPPORTING_3RD_PARTY_LIBRARIES 1 GMPXX) @@ -534,7 +549,41 @@ set_special_prefix(Coin3D COIN3D) # some libraries are essential (stl and Boost.Thread are treated in another way) -list (INSERT CGAL_ESSENTIAL_3RD_PARTY_LIBRARIES 0 GMP MPFR) +if($ENV{CGAL_DISABLE_GMP}) + set(CGAL_DISABLE_GMP ON CACHE INTERNAL "") +endif() +if(CGAL_DISABLE_GMP) + message("Disable the GMP support") + list(LENGTH CGAL_ESSENTIAL_3RD_PARTY_LIBRARIES CGAL_ESSENTIAL_LENGTH) + if(NOT CGAL_ESSENTIAL_LENGTH EQUAL 0) + list(REMOVE_ITEM CGAL_ESSENTIAL_3RD_PARTY_LIBRARIES GMP MPFR) + endif() + unset(CGAL_CONFIGURED_LIBRARIES) + unset(CGAL_CONFIGURED_LIBRARIES CACHE) + unset(GMP_FOUND) + unset(GMP_FOUND CACHE) + unset(GMPXX_FOUND) + unset(GMPXX_FOUND CACHE) + unset(MPFR_FOUND) + unset(MPFR_FOUND CACHE) + unset(WITH_CGAL_Core) + unset(WITH_CGAL_Core CACHE) + unset(WITH_GMP) + unset(WITH_GMP CACHE) + unset(WITH_GMPXX) + unset(WITH_GMPXX CACHE) + unset(WITH_MPFR) + unset(WITH_MPFR CACHE) + + # Nasty trick to make sure is not used when CGAL_DISABLE_GMP is TRUE + file(WRITE "${CMAKE_BINARY_DIR}/include/gmp.h" + "#error GMP is disabled by the CMake option CGAL_DISABLE_GMP") +else() + list(APPEND CGAL_ESSENTIAL_3RD_PARTY_LIBRARIES GMP MPFR) + # Where CMake is run several times, to avoid duplicates + list (REMOVE_DUPLICATES CGAL_ESSENTIAL_3RD_PARTY_LIBRARIES) + file(REMOVE "${CMAKE_BINARY_DIR}/include/gmp.h") +endif() hide_variable(CGAL_ESSENTIAL_3RD_PARTY_LIBRARIES) foreach (lib ${CGAL_SUPPORTING_3RD_PARTY_LIBRARIES}) @@ -822,11 +871,6 @@ install(DIRECTORY auxiliary/gmp/lib/ DESTINATION ${CGAL_INSTALL_LIB_DIR} ) endif() -if ( TAUCS_IN_AUXILIARY ) - install(DIRECTORY auxiliary/taucs/include/ DESTINATION ${CGAL_INSTALL_INC_DIR} ) - install(DIRECTORY auxiliary/taucs/lib/ DESTINATION ${CGAL_INSTALL_LIB_DIR} ) -endif() - if ( ZLIB_IN_AUXILIARY ) install(DIRECTORY auxiliary/zlib/include/ DESTINATION ${CGAL_INSTALL_INC_DIR} ) install(DIRECTORY auxiliary/zlib/lib/ DESTINATION ${CGAL_INSTALL_LIB_DIR} ) diff -Nru cgal-4.4/config/support/print_TAUCS_version.cpp cgal-4.5/config/support/print_TAUCS_version.cpp --- cgal-4.4/config/support/print_TAUCS_version.cpp 2012-11-13 13:13:55.000000000 +0000 +++ cgal-4.5/config/support/print_TAUCS_version.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ -// Copyright (c) 2004 -// 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); you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public License as -// published by the Free Software Foundation; either version 3 of the License, -// or (at your option) any later version. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -// -// $URL: svn+ssh://fcacciola@scm.gforge.inria.fr/svn/cgal/trunk/Installation/config/support/test_TAUCS.cpp $ -// $Id: test_TAUCS.cpp 41686 2008-01-18 20:33:57Z spion $ -// -// Author(s) : Laurent Saboret - -// Test if TAUCS is available - - -#include - - -int main(int argc, char* argv[]) -{ - // TAUCS provides no version number :-( - // Version 1 is obsolete, thus we assume version 2 (latest is 2.2 on 03/2006) - std::cout << "version=2.x" << std::endl; - - return 0; -} diff -Nru cgal-4.4/config/support/test_TAUCS.cpp cgal-4.5/config/support/test_TAUCS.cpp --- cgal-4.4/config/support/test_TAUCS.cpp 2012-11-13 13:13:55.000000000 +0000 +++ cgal-4.5/config/support/test_TAUCS.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,96 +0,0 @@ -// Copyright (c) 2004 -// 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); you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public License as -// published by the Free Software Foundation; either version 3 of the License, -// or (at your option) any later version. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -// -// $URL$ -// $Id$ -// -// Author(s) : Laurent Saboret - -// Test if TAUCS is available - - -#include -#include -#include -#include -#include - -#define TAUCS_CORE_DOUBLE - -// In GCC 3.x, includes and -// complains if we include within "extern C {}" -#if defined(__GNUC__) - #undef __DEPRECATED - #include -#endif - -extern "C" -{ - // Include TAUCS main header taucs.h - #include -} - -// Avoid error with std::min() and std::max() -#undef min -#undef max - - -int main(int argc, char* argv[]) -{ - // Create a TAUCS matrix to link with TAUCS main library - int m = 4,n = 4,nnz = 4, i; - taucs_ccs_matrix* pMatrix = taucs_ccs_create(m, n, nnz, TAUCS_DOUBLE); - pMatrix->colptr[0] = 0; - pMatrix->colptr[1] = 4; - for ( i = 0; i < 4; i++ ) - { - pMatrix->rowind[i] = i; - pMatrix->taucs_values[i] = i; - } - - // Call a method needing TAUCS external library Metis - int* perm; - int* invperm; - taucs_ccs_order(pMatrix, - &perm, - &invperm, - (char*)"metis"); - - // Call dpotrf() Lapack routine (Cholesky factorization) - int sn_size = 0; - int lda = 1; - int info; - taucs_potrf((char*)"LOWER", - &sn_size, - NULL, - &lda, - &info); - - // ftime() is in compat lib. on FreeBSD and crypto lib. on MacOSX - struct timeb tb; - ftime(&tb); - - // TAUCS provides no version number :-( - // Version 1 is obsolete, thus we assume version 2 (latest is 2.2 on 03/2006) - std::cout << "version=2.x" << std::endl; - - // clean up - taucs_dccs_free(pMatrix); - - return 0; -} diff -Nru cgal-4.4/debian/changelog cgal-4.5/debian/changelog --- cgal-4.4/debian/changelog 2014-04-26 19:41:40.000000000 +0000 +++ cgal-4.5/debian/changelog 2014-11-06 16:14:40.000000000 +0000 @@ -1,3 +1,34 @@ +cgal (4.5-2ubuntu1) vivid; urgency=medium + + * Merge from Debian unstable. Remaining changes: + - {libcgal10,libcgal-qt4-10,libcgal-dev,libcgal-qt4-dev}.install.armhf: + + Don't install files that dont't build on armhf due to GL/GLES skew. + + -- Logan Rosen Thu, 06 Nov 2014 11:14:08 -0500 + +cgal (4.5-2) unstable; urgency=medium + + * Re-enable support for GMPXX (accidentally disabled in 4.1-1, + Closes: #705803). + * Remove traces of incorrect attempts to enable MPFI and NTL support. + Enabling support for these libraries causes some examples no longer + to build. + * Add libmpfi-dev and libntl-dev to Suggests: of libcgal-dev and + libcgal-demo. + * Remove section about very old versions of libqglviewer from + README.Debian, add section about enabling support for MPFI and NTL. + + -- Joachim Reichel Thu, 16 Oct 2014 21:47:30 +0200 + +cgal (4.5-1) unstable; urgency=medium + + * New upstream release. + * Pass --no-name to gzip to favor reproducible builds. + * Adapt debian/watch to new site structure. + * Update Standards-Version to 3.9.6 (no changes needed). + + -- Joachim Reichel Fri, 10 Oct 2014 18:07:47 +0200 + cgal (4.4-1ubuntu1) utopic; urgency=medium * Merge from Debian unstable (LP: #1155806). Remaining changes: diff -Nru cgal-4.4/debian/control cgal-4.5/debian/control --- cgal-4.4/debian/control 2014-04-26 19:33:55.000000000 +0000 +++ cgal-4.5/debian/control 2014-11-06 16:13:27.000000000 +0000 @@ -5,9 +5,8 @@ # "ipe" is only needed because it contains goodies.lua which is needed by FindIPE.cmake Build-Depends: debhelper (>= 9), dpkg-awk, cmake, zlib1g-dev, libboost-dev, libboost-thread-dev, libboost-program-options-dev, libboost-system-dev, - libgmp10-dev, libmpfr-dev, libmpfi-dev, libqt4-dev, libqt4-opengl-dev, - libipe-dev (>= 7), ipe -Standards-Version: 3.9.5 + libgmp10-dev, libmpfr-dev, libqt4-dev, libqt4-opengl-dev, libipe-dev (>= 7), ipe +Standards-Version: 3.9.6 Section: libs Homepage: http://www.cgal.org/ XS-Autobuild: yes @@ -65,6 +64,7 @@ Depends: libcgal10 (= ${binary:Version}), libboost-dev, libboost-thread-dev, libboost-system-dev, libboost-program-options-dev, libgmp10-dev, libmpfr-dev, zlib1g-dev, ${misc:Depends} +Suggests: libmpfi-dev, libntl-dev Description: C++ library for computational geometry (development files) CGAL (Computational Geometry Algorithms Library) makes the most important of the solutions and methods developed in computational geometry available @@ -100,7 +100,7 @@ Suggests: liblapack-dev, libatlas-base-dev, gfortran, geomview, libqglviewer-dev, libipe-dev (>= 7), libglew1.5-dev | libglew-dev, libmagick++-dev, qt4-dev-tools, libqt4-opengl-dev, libeigen3-dev (>= 3.1.0~beta1-1), - libntl-dev + libmpfi-dev, libntl-dev Description: C++ library for computational geometry (demos) CGAL (Computational Geometry Algorithms Library) makes the most important of the solutions and methods developed in computational geometry available diff -Nru cgal-4.4/debian/README.Debian cgal-4.5/debian/README.Debian --- cgal-4.4/debian/README.Debian 2014-04-26 19:31:48.000000000 +0000 +++ cgal-4.5/debian/README.Debian 2014-11-06 16:13:27.000000000 +0000 @@ -27,24 +27,11 @@ each executed command. -Demos using libQGLViewer +Support for MPFI and NTL ------------------------ -The Debian package of libQGLViewer uses non-standard library names to offer the -library in a Qt3 and Qt4 flavor. The build system of CGAL has been patched to -handle the non-standard library name. If your libQGLViewer packages are older -than 2.3.1-4 you need to work around another problem with the non-standard -include directory. Create an include directory with the expected name -"QGLViewer", e.g., +Support for MPFI and NTL is not enabled in the default configuration. The +support can be manually enabled by defining the macros CGAL_USE_MPFI and +CGAL_USE_NTL and linking with -lmpfi and -lntl, respectively. - mkdir -p /some/dir - ln -s /usr/include/qglviewer-qt4 /some/dir/QGLViewer - -and pass the option - - -DQGLVIEWER_INCLUDE_DIR=/some/dir - -to cmake. See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=522659 for more -information. - - -- Joachim Reichel Sat, 06 Feb 2010 12:29:02 +0100 + -- Joachim Reichel Thu, 16 Oct 2014 21:47:30 +0200 diff -Nru cgal-4.4/debian/README.source cgal-4.5/debian/README.source --- cgal-4.4/debian/README.source 2014-04-26 19:31:48.000000000 +0000 +++ cgal-4.5/debian/README.source 2014-11-06 16:13:27.000000000 +0000 @@ -1,5 +1,5 @@ -normalize-audio for Debian --------------------------- +cgal for Debian +--------------- This package uses quilt to manage all modifications to the upstream source. Changes are stored in the source package as diffs in debian/patches and diff -Nru cgal-4.4/debian/rules cgal-4.5/debian/rules --- cgal-4.4/debian/rules 2014-04-26 19:31:48.000000000 +0000 +++ cgal-4.5/debian/rules 2014-11-06 16:13:27.000000000 +0000 @@ -20,12 +20,12 @@ mkdir -p static cd static && QTDIR= cmake .. \ -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release \ - -DWITH_NTL=ON -DWITH_CGAL_Qt3=OFF -DWITH_demos=OFF -DWITH_examples=OFF \ + -DWITH_GMPXX=ON -DWITH_CGAL_Qt3=OFF -DWITH_demos=OFF -DWITH_examples=OFF \ -DCGAL_ENABLE_PRECONFIG=OFF -DBUILD_SHARED_LIBS=FALSE mkdir -p shared cd shared && QTDIR= cmake .. \ -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release \ - -DWITH_NTL=ON -DWITH_CGAL_Qt3=OFF -DWITH_demos=OFF -DWITH_examples=OFF \ + -DWITH_GMPXX=ON -DWITH_CGAL_Qt3=OFF -DWITH_demos=OFF -DWITH_examples=OFF \ -DCGAL_ENABLE_PRECONFIG=OFF -DBUILD_SHARED_LIBS=TRUE -DCMAKE_SKIP_RPATH=TRUE mkdir -p shared/demo/CGAL_ipelets cd shared/demo/CGAL_ipelets && QTDIR= cmake ../../../demo/CGAL_ipelets \ @@ -67,8 +67,8 @@ rm debian/tmp/usr/share/doc/cgal/LICENSE* rm debian/tmp/usr/share/doc/cgal/AUTHORS - tar cf - examples | gzip --best >debian/tmp/usr/share/doc/cgal/examples.tar.gz - tar cf - demo | gzip --best >debian/tmp/usr/share/doc/cgal/demo.tar.gz + tar cf - examples | gzip --no-name --best >debian/tmp/usr/share/doc/cgal/examples.tar.gz + tar cf - demo | gzip --no-name --best >debian/tmp/usr/share/doc/cgal/demo.tar.gz rm debian/tmp/usr/bin/cgal_make_macosx_app diff -Nru cgal-4.4/debian/watch cgal-4.5/debian/watch --- cgal-4.4/debian/watch 2014-04-26 19:31:48.000000000 +0000 +++ cgal-4.5/debian/watch 2014-11-06 16:13:27.000000000 +0000 @@ -1,5 +1,5 @@ # Note that the file URLs contain unpredictable IDs as directory. The -# uversionmagle options strips this ID. +# uversionmagle option strips this ID. # # Note that only digits and "." are used to match the version number. # Therefore we do not match beta releases. @@ -7,4 +7,4 @@ version=3 opts=uversionmangle=s/(\d+).([\d\.]+)/$2/ \ https://gforge.inria.fr/frs/?group_id=52 \ - /frs/download.php/(\d+)/CGAL-([\d\.]+).tar.gz + /frs/download.php/file/(\d+)/CGAL-([\d\.]+).tar.gz diff -Nru cgal-4.4/demo/AABB_tree/benchmarks.cpp cgal-4.5/demo/AABB_tree/benchmarks.cpp --- cgal-4.4/demo/AABB_tree/benchmarks.cpp 2013-08-03 19:00:28.000000000 +0000 +++ cgal-4.5/demo/AABB_tree/benchmarks.cpp 2014-08-29 13:58:15.000000000 +0000 @@ -16,7 +16,7 @@ std::cout << "Construct AABB tree..."; CGAL::Timer timer; timer.start(); - Facet_tree tree(m_pPolyhedron->facets_begin(),m_pPolyhedron->facets_end(),*m_pPolyhedron); + Facet_tree tree(faces(*m_pPolyhedron).first, faces(*m_pPolyhedron).second,*m_pPolyhedron); std::cout << "done (" << timer.time() << " s)" << std::endl; // generates random queries @@ -76,7 +76,7 @@ CGAL::Timer timer; timer.start(); std::cout << "Construct AABB tree and internal KD tree..."; - Facet_tree tree(m_pPolyhedron->facets_begin(),m_pPolyhedron->facets_end(),*m_pPolyhedron); + Facet_tree tree(faces(*m_pPolyhedron).first, faces(*m_pPolyhedron).second,*m_pPolyhedron); tree.accelerate_distance_queries(); std::cout << "done (" << timer.time() << " s)" << std::endl; @@ -122,7 +122,7 @@ // constructs tree and measure memory before then after typedef CGAL::Memory_sizer::size_type size_type; size_type before = CGAL::Memory_sizer().virtual_size(); - Facet_tree tree(m_pPolyhedron->facets_begin(),m_pPolyhedron->facets_end(),*m_pPolyhedron); + Facet_tree tree(faces(*m_pPolyhedron).first, faces(*m_pPolyhedron).second,*m_pPolyhedron); // tree.accelerate_distance_queries(); // 150 vs 61 bytes per primitive! size_type after = CGAL::Memory_sizer().virtual_size(); @@ -159,12 +159,12 @@ // constructs tree CGAL::Timer time1; time1.start(); - Facet_tree tree1(m_pPolyhedron->facets_begin(),m_pPolyhedron->facets_end(),*m_pPolyhedron); + Facet_tree tree1(faces(*m_pPolyhedron).first, faces(*m_pPolyhedron).second, *m_pPolyhedron); double duration_construction_alone = time1.time(); CGAL::Timer time2; time2.start(); - Facet_tree tree2(m_pPolyhedron->facets_begin(),m_pPolyhedron->facets_end(),*m_pPolyhedron); + Facet_tree tree2(faces(*m_pPolyhedron).first, faces(*m_pPolyhedron).second,*m_pPolyhedron); tree2.accelerate_distance_queries(); double duration_construction_and_kdtree = time2.time(); @@ -203,7 +203,7 @@ refiner.run_nb_splits(nb_splits); // constructs tree (out of timing) - Facet_tree tree(m_pPolyhedron->facets_begin(),m_pPolyhedron->facets_end(),*m_pPolyhedron); + Facet_tree tree(faces(*m_pPolyhedron).first, faces(*m_pPolyhedron).second,*m_pPolyhedron); // calls ray queries CGAL::Timer timer; @@ -247,7 +247,7 @@ refiner.run_nb_splits(nb_splits); // constructs tree (out of timing) - Facet_tree tree(m_pPolyhedron->facets_begin(),m_pPolyhedron->facets_end(),*m_pPolyhedron); + Facet_tree tree(faces(*m_pPolyhedron).first, faces(*m_pPolyhedron).second, *m_pPolyhedron); tree.accelerate_distance_queries(); // calls queries diff -Nru cgal-4.4/demo/AABB_tree/Scene.cpp cgal-4.5/demo/AABB_tree/Scene.cpp --- cgal-4.4/demo/AABB_tree/Scene.cpp 2013-08-03 19:00:28.000000000 +0000 +++ cgal-4.5/demo/AABB_tree/Scene.cpp 2014-08-29 13:58:15.000000000 +0000 @@ -401,7 +401,7 @@ CGAL::Timer timer; timer.start(); std::cout << "Construct Facet AABB tree..."; - m_facet_tree.rebuild(m_pPolyhedron->facets_begin(),m_pPolyhedron->facets_end(),*m_pPolyhedron); + m_facet_tree.rebuild(faces(*m_pPolyhedron).first, faces(*m_pPolyhedron).second,*m_pPolyhedron); m_facet_tree.accelerate_distance_queries(); std::cout << "done (" << timer.time() << " s)" << std::endl; } @@ -421,7 +421,7 @@ CGAL::Timer timer; timer.start(); std::cout << "Construct Edge AABB tree..."; - m_edge_tree.rebuild(boost::edges(*m_pPolyhedron).first,boost::edges(*m_pPolyhedron).second,*m_pPolyhedron); + m_edge_tree.rebuild(edges(*m_pPolyhedron).first,edges(*m_pPolyhedron).second,*m_pPolyhedron); m_edge_tree.accelerate_distance_queries(); std::cout << "done (" << timer.time() << " s)" << std::endl; } @@ -465,7 +465,7 @@ typedef CGAL::AABB_tree Tree; std::cout << "Construct AABB tree..."; - Tree tree(m_pPolyhedron->facets_begin(),m_pPolyhedron->facets_end(), *m_pPolyhedron); + Tree tree(faces(*m_pPolyhedron).first, faces(*m_pPolyhedron).second, *m_pPolyhedron); std::cout << "done." << std::endl; CGAL::Timer timer; @@ -517,7 +517,7 @@ typedef CGAL::AABB_tree Tree; std::cout << "Construct AABB tree..."; - Tree tree(m_pPolyhedron->facets_begin(),m_pPolyhedron->facets_end(),*m_pPolyhedron); + Tree tree(faces(*m_pPolyhedron).first, faces(*m_pPolyhedron).second,*m_pPolyhedron); std::cout << "done." << std::endl; CGAL::Timer timer; @@ -559,7 +559,7 @@ typedef Tree::Object_and_primitive_id Object_and_primitive_id; std::cout << "Construct AABB tree..."; - Tree tree(m_pPolyhedron->facets_begin(),m_pPolyhedron->facets_end(),*m_pPolyhedron); + Tree tree(faces(*m_pPolyhedron).first,faces(*m_pPolyhedron).second,*m_pPolyhedron); std::cout << "done." << std::endl; CGAL::Timer timer; @@ -608,7 +608,7 @@ typedef Tree::Object_and_primitive_id Object_and_primitive_id; std::cout << "Construct AABB tree..."; - Tree tree(m_pPolyhedron->facets_begin(),m_pPolyhedron->facets_end(),*m_pPolyhedron); + Tree tree(faces(*m_pPolyhedron).first, faces(*m_pPolyhedron).second,*m_pPolyhedron); std::cout << "done." << std::endl; CGAL::Timer timer; @@ -657,8 +657,8 @@ typedef Tree::Object_and_primitive_id Object_and_primitive_id; std::cout << "Construct AABB tree..."; - Tree tree( CGAL::undirected_edges(*m_pPolyhedron).first, - CGAL::undirected_edges(*m_pPolyhedron).second, + Tree tree( CGAL::edges(*m_pPolyhedron).first, + CGAL::edges(*m_pPolyhedron).second, *m_pPolyhedron); std::cout << "done." << std::endl; diff -Nru cgal-4.4/demo/AABB_tree/Scene.h cgal-4.5/demo/AABB_tree/Scene.h --- cgal-4.4/demo/AABB_tree/Scene.h 2013-07-27 19:00:33.000000000 +0000 +++ cgal-4.5/demo/AABB_tree/Scene.h 2014-08-29 13:58:15.000000000 +0000 @@ -11,7 +11,7 @@ #include #include -#include +#include #include #include diff -Nru cgal-4.4/demo/CGAL_ipelets/circle_pencils.cpp cgal-4.5/demo/CGAL_ipelets/circle_pencils.cpp --- cgal-4.4/demo/CGAL_ipelets/circle_pencils.cpp 2014-01-04 20:00:21.000000000 +0000 +++ cgal-4.5/demo/CGAL_ipelets/circle_pencils.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -127,6 +127,25 @@ } //end of switch + // detect degenerate case + if (circ==Circle_2()){ + Kernel::Vector_2 v; + if(fn==0) + v=Kernel::Vector_2( + c2.center().y()-c1.center().y(),c2.center().x()-c1.center().x()); + else v=c2.center()-c1.center(); + Kernel::FT sqr_length= 1 / v.squared_length(); + double length = 600 * sqrt( sqr_length); + v = Kernel::FT(length)*v; + Point_2 q1=c.center()+ v; + Point_2 q2=c.center()- v; + print_error_message( + "degenerate case, circle is a line"); + Kernel::Segment_2 s(q1,q2); + draw_in_ipe(s); + return; + } + if (circ.squared_radius()>0){ draw_in_ipe(circ); }else{ diff -Nru cgal-4.4/demo/CGAL_ipelets/CMakeLists.txt cgal-4.5/demo/CGAL_ipelets/CMakeLists.txt --- cgal-4.4/demo/CGAL_ipelets/CMakeLists.txt 2014-01-04 20:00:21.000000000 +0000 +++ cgal-4.5/demo/CGAL_ipelets/CMakeLists.txt 2014-08-29 13:58:16.000000000 +0000 @@ -111,6 +111,7 @@ set(CGAL_IPELETS ${CGAL_IPELETS} triangulation) set(CGAL_IPELETS ${CGAL_IPELETS} circle_pencils) set(CGAL_IPELETS ${CGAL_IPELETS} hyperbolic) + set(CGAL_IPELETS ${CGAL_IPELETS} distance) if ( IPELET_INSTALL_DIR ) diff -Nru cgal-4.4/demo/CGAL_ipelets/distance.cpp cgal-4.5/demo/CGAL_ipelets/distance.cpp --- cgal-4.4/demo/CGAL_ipelets/distance.cpp 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/demo/CGAL_ipelets/distance.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,104 @@ +// Copyright (c) 2013 INRIA Sophia Antipolis - Mediterranee, (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Olivier Devillers + + +#include + +#include +#include + + + +#include +namespace CGAL_distance_ipelet{ + + +typedef CGAL::Exact_circular_kernel_2 Kernel; + +// -------------------------------------------------------------------- + +const std::string sublabel[] = { + "2 marks", + "2 marks (cm)" + "2 marks (inch)" + "Help" +}; + +const std::string helpmsg[] = { + "Distance between two marks in ipe screen pts", + "Distance between two marks in centimeters when printed", + "Distance between two marks in inches when printed", +}; + +class distanceIpelet + : public CGAL::Ipelet_base { +public: + distanceIpelet() + :CGAL::Ipelet_base("Distance",sublabel,helpmsg){} + void protected_run(int); +}; +// -------------------------------------------------------------------- + +void distanceIpelet::protected_run(int fn) +{ + if (fn==3) { + show_help(); + return; + } + + std::list pt_list; + + int i=get_IpePage()->primarySelection(); + + if (i<0) { + print_error_message(("Nothing selected")); + return; + } + + Iso_rectangle_2 bbox= + read_active_objects( + CGAL::dispatch_or_drop_output( + std::back_inserter(pt_list) + ) + ); + + if (pt_list.empty()) {print_error_message(("No mark selected")); return;} + std::list::iterator it=pt_list.begin(); + Point_2 p1=*it; ++it; + if (pt_list.end()==it) { + print_error_message(("Only one mark selected")); return;} + Point_2 p2=*it; ++it; + if (pt_list.end()!=it) { + print_error_message(("More than two marks selected")); return;} + + double length = sqrt( CGAL::squared_distance(p1,p2).to_double() ); + char message[50]; + if (fn==0) + sprintf(message,"Distance between marks is %f in ipe pts",length); + else if (fn==1) + sprintf(message,"Distance between marks is %f cm",0.0353*length); + else if (fn==2) + sprintf(message,"Distance between marks is %f inches",0.0139*length); + print_error_message(message); + return; +} +} + +CGAL_IPELET(CGAL_distance_ipelet::distanceIpelet) diff -Nru cgal-4.4/demo/CGAL_ipelets/hyperbolic.cpp cgal-4.5/demo/CGAL_ipelets/hyperbolic.cpp --- cgal-4.4/demo/CGAL_ipelets/hyperbolic.cpp 2014-01-04 20:00:21.000000000 +0000 +++ cgal-4.5/demo/CGAL_ipelets/hyperbolic.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -164,7 +164,11 @@ circ = compute_circle_orthogonal(p1,p2,poincare); if (orientation(poincare.center(),p1.center(),p2.center())>0) draw_in_ipe(Circular_arc_2(circ,p2.center(),p1.center(),circ.orientation())); - else + else if (orientation(poincare.center(),p1.center(),p2.center())==0){ + print_error_message( + "degenerate case, hyperbolic line is on a diameter of Poincare disk"); + draw_in_ipe(Segment_2(p1.center(),p2.center())); + }else draw_in_ipe(Circular_arc_2(circ,p1.center(),p2.center(),circ.orientation())); return; case 2: @@ -194,6 +198,24 @@ return; } //end of switch + // detect degenerate case + if (circ==Circle_2()){ + Kernel::Vector_2 v; + if (fn==2) v= Kernel::Vector_2 + (p2.center().y()-p1.center().y(),p2.center().x()-p1.center().x()); + else v=p2.center()-p1.center(); + Kernel::FT sqr_length=poincare.squared_radius() / v.squared_length(); + double length = sqrt( sqr_length.to_double()); + v = Kernel::FT(length)*v; + Point_2 q1=poincare.center()+ v; + Point_2 q2=poincare.center()- v; + print_error_message( + "degenerate case, hyperbolic line is a diameter of Poincare disk"); + Kernel::Segment_2 s(q1,q2); + draw_in_ipe(s); + return; + } + // clip circ by poincare std::vector< CGAL::Object > result; Kernel::Circular_arc_point_2 L,R; diff -Nru cgal-4.4/demo/CGAL_ipelets/include/CGAL_ipelets/pencils.h cgal-4.5/demo/CGAL_ipelets/include/CGAL_ipelets/pencils.h --- cgal-4.4/demo/CGAL_ipelets/include/CGAL_ipelets/pencils.h 2014-01-04 20:00:21.000000000 +0000 +++ cgal-4.5/demo/CGAL_ipelets/include/CGAL_ipelets/pencils.h 2014-08-29 13:58:16.000000000 +0000 @@ -30,6 +30,9 @@ typename Kernel::FT l2 = CGAL::squared_distance(c2.center(),origin) - c2.squared_radius() ; l1 += -2*((c1.center()-origin)*(c.center()-origin)); l2 += -2*((c2.center()-origin)*(c.center()-origin)); + if (l1==l2){ // degenerate case, radical axis + return typename Kernel::Circle_2(); + } lambda= - (lambda+l2)/(l1-l2); typename Kernel::Point_2 center=origin+lambda*(c1.center()-origin)+(1-lambda)*(c2.center()-origin); typename Kernel::FT sqradius=- lambda*(CGAL::squared_distance(c1.center(),origin)-c1.squared_radius()) @@ -51,6 +54,9 @@ typename Kernel::FT det=-(c1.center().x() * c2.center().y() - c1.center().y() * c2.center().x()) +(c.center().x() * c2.center().y() - c.center().y() * c2.center().x()) -(c.center().x() * c1.center().y() - c.center().y() * c1.center().x()); + if (det==0.0){ // degenerate casse, radical axis + return typename Kernel::Circle_2(); + } typename Kernel::FT x=( -(z1 * c2.center().y() - c1.center().y() * z2) +(z * c2.center().y() - c.center().y() * z2) -(z * c1.center().y() - c.center().y() * z1))/2/det; diff -Nru cgal-4.4/demo/CGAL_ipelets/lua/libCGAL_distance.lua cgal-4.5/demo/CGAL_ipelets/lua/libCGAL_distance.lua --- cgal-4.4/demo/CGAL_ipelets/lua/libCGAL_distance.lua 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/demo/CGAL_ipelets/lua/libCGAL_distance.lua 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,26 @@ +---------------------------------------------------------------------- +-- CGAL hyperbolic geometry ipelet description +---------------------------------------------------------------------- + +label = "Distance" + +about = [[ +This ipelet is part of the CGAL_ipelet package. See www.cgal.org. +]] + +-- this variable will store the C++ ipelet when it has been loaded +ipelet = false + +function run(model, num) + if not ipelet then ipelet = assert(ipe.Ipelet(dllname)) end + model:runIpelet(methods[num].label, ipelet, num) +end + +methods = { + { label= "Distance between two points" }, + { label= "(centimeters)" }, + { label= "(inches)" }, + { label="Help" }, +} + +---------------------------------------------------------------------- diff -Nru cgal-4.4/demo/Envelope_3/CMakeLists.txt cgal-4.5/demo/Envelope_3/CMakeLists.txt --- cgal-4.4/demo/Envelope_3/CMakeLists.txt 2012-11-13 13:13:55.000000000 +0000 +++ cgal-4.5/demo/Envelope_3/CMakeLists.txt 2014-08-29 13:58:16.000000000 +0000 @@ -22,7 +22,7 @@ # that it can be used together with FindQt4: all its variables are prefixed # by "QT3_" instead of "QT_". - if(CGAL_Qt3_FOUND AND QT3_FOUND) + if(CGAL_Qt3_FOUND AND QT3_FOUND AND CGAL_Core_FOUND) include( Qt3Macros-patched ) qt3_automoc( envelope_3.cpp ) @@ -43,7 +43,7 @@ target_link_libraries(envelope_3 ${QT3_LIBRARIES} ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES} ) else() - message(STATUS "NOTICE: This demo requires Qt3 and the CGAL Qt3 library, and will not be compiled.") + message(STATUS "NOTICE: This demo requires Qt3, the CGAL Qt3 and the CGAL Core libraries, and will not be compiled.") endif() diff -Nru cgal-4.4/demo/Envelope_3/typedefs.h cgal-4.5/demo/Envelope_3/typedefs.h --- cgal-4.4/demo/Envelope_3/typedefs.h 2012-11-13 13:13:55.000000000 +0000 +++ cgal-4.5/demo/Envelope_3/typedefs.h 2014-08-29 13:58:16.000000000 +0000 @@ -27,7 +27,9 @@ #include #include #include +#ifdef CGAL_USE_CORE #include +#endif #include #include #include diff -Nru cgal-4.4/demo/Linear_cell_complex/MainWindow.cpp cgal-4.5/demo/Linear_cell_complex/MainWindow.cpp --- cgal-4.4/demo/Linear_cell_complex/MainWindow.cpp 2013-11-30 20:00:27.000000000 +0000 +++ cgal-4.5/demo/Linear_cell_complex/MainWindow.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -23,6 +23,7 @@ #include #include "MainWindow.moc" #include +#include // Function defined in Linear_cell_complex_3_subivision.cpp void subdivide_lcc_3 (LCC & m); diff -Nru cgal-4.4/demo/Mesh_3/C3t3_type.h cgal-4.5/demo/Mesh_3/C3t3_type.h --- cgal-4.4/demo/Mesh_3/C3t3_type.h 2012-11-13 13:13:57.000000000 +0000 +++ cgal-4.5/demo/Mesh_3/C3t3_type.h 2014-08-29 13:58:16.000000000 +0000 @@ -10,7 +10,9 @@ #include #include +#include #include +#include template struct Wrapper @@ -28,51 +30,31 @@ const Implicit_function_interface& f_; }; -namespace CGAL { -// A specialisation of Triangle_accessor_3 which fits our Polyhedron type -template -class Triangle_accessor_3 -{ -public: - typedef typename K::Triangle_3 Triangle_3; - typedef Polyhedron::Facet_const_iterator Triangle_iterator; - typedef Polyhedron::Facet_const_handle Triangle_handle; - - Triangle_accessor_3() { } - - Triangle_iterator triangles_begin(const Polyhedron& p) const - { - return p.facets_begin(); - } - - Triangle_iterator triangles_end(const Polyhedron& p) const - { - return p.facets_end(); - } - - Triangle_3 triangle(const Triangle_handle& handle) const - { - typedef typename K::Point_3 Point; - const Point& a = handle->halfedge()->vertex()->point(); - const Point& b = handle->halfedge()->next()->vertex()->point(); - const Point& c = handle->halfedge()->next()->next()->vertex()->point(); - return Triangle_3(a,b,c); - } -}; +typedef CGAL::Triangle_accessor_3 T_accessor; -} +typedef CGAL::Polyhedral_mesh_domain_with_features_3 + Polyhedral_mesh_domain; +// The last `Tag_false` says the Patch_id type will be pair, like +// the `Image_mesh_domain`, and `Function_mesh_domain`. -typedef CGAL::Mesh_3::Robust_intersection_traits_3 RKernel; -typedef CGAL::Polyhedral_mesh_domain_3 Polyhedral_mesh_domain; typedef CGAL::Labeled_image_mesh_domain_3 Image_mesh_domain; typedef Wrapper Function_wrapper; -typedef CGAL::Mesh_3::Labeled_mesh_domain_3 Function_mesh_domain; +typedef CGAL::Labeled_mesh_domain_3 Function_mesh_domain; // Triangulation -typedef CGAL::Mesh_triangulation_3::type Tr; +#ifdef CGAL_CONCURRENT_MESH_3 + typedef CGAL::Mesh_triangulation_3::Kernel, + CGAL::Parallel_tag>::type Tr; +#else + typedef CGAL::Mesh_triangulation_3::type Tr; +#endif +typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // 3D complex -typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; #endif // CGAL_DEMO_MESH_3_C3T3_TYPE_H diff -Nru cgal-4.4/demo/Mesh_3/CMakeLists.txt cgal-4.5/demo/Mesh_3/CMakeLists.txt --- cgal-4.4/demo/Mesh_3/CMakeLists.txt 2012-11-13 13:13:57.000000000 +0000 +++ cgal-4.5/demo/Mesh_3/CMakeLists.txt 2014-08-29 13:58:16.000000000 +0000 @@ -9,6 +9,41 @@ cmake_policy(VERSION 2.6) endif() +# Compatibility with CMake 3.0 +if(POLICY CMP0042) + # Do not enable the use of MACOSX_RPATH + # http://www.cmake.org/cmake/help/v3.0/policy/CMP0042.html + cmake_policy(SET CMP0042 OLD) +endif() + +# Creates a new CMake option, turned ON by default +option(ACTIVATE_MSVC_PRECOMPILED_HEADERS + "Activate precompiled headers in MSVC" + OFF) + +# Macro to add precompiled headers for MSVC +# This function does two things: +# 1. Enable precompiled headers on each file which is listed in "SourcesVar". +# 2. Add the content of "PrecompiledSource" (e.g. "StdAfx.cpp") to "SourcesVar". +MACRO(ADD_MSVC_PRECOMPILED_HEADER PrecompiledHeader PrecompiledSource SourcesVar) + IF(MSVC AND ACTIVATE_MSVC_PRECOMPILED_HEADERS) + GET_FILENAME_COMPONENT(PrecompiledBasename ${PrecompiledHeader} NAME_WE) + SET(Sources ${${SourcesVar}}) + + SET_SOURCE_FILES_PROPERTIES(${PrecompiledSource} + PROPERTIES COMPILE_FLAGS "/Yc\"${PrecompiledHeader}\"") + SET_SOURCE_FILES_PROPERTIES(${Sources} + PROPERTIES COMPILE_FLAGS "/Yu\"${PrecompiledHeaders}\" /FI\"${PrecompiledHeader}\"") + # Add precompiled header to SourcesVar + LIST(APPEND ${SourcesVar} ${PrecompiledSource}) + ENDIF(MSVC AND ACTIVATE_MSVC_PRECOMPILED_HEADERS) +ENDMACRO(ADD_MSVC_PRECOMPILED_HEADER) +# The compiler might need more memory because of precompiled headers +if(MSVC AND ACTIVATE_MSVC_PRECOMPILED_HEADERS AND NOT(MSVC_VERSION LESS 1310)) + set(CGAL_C_FLAGS "${CGAL_C_FLAGS} /Zm1000") + set(CGAL_CXX_FLAGS "${CGAL_CXX_FLAGS} /Zm1000") +endif() + # Let plugins be compiled in the same directory as the executable. set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}") @@ -22,14 +57,36 @@ add_definitions(-DCGAL_MESH_3_NO_DEPRECATED_SURFACE_INDEX -DCGAL_MESH_3_NO_DEPRECATED_C3T3_ITERATORS) - # Add specific Find.cmake modules -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules ) +set(CMAKE_MODULE_PATH + ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules) +# Activate concurrency ? (turned OFF by default) +option(ACTIVATE_CONCURRENT_MESH_3 + "Activate parallelism in Mesh_3" + OFF) + # Find CGAL and CGAL Qt4 find_package(CGAL COMPONENTS Qt4 ImageIO) include( ${CGAL_USE_FILE} ) +# And add -DCGAL_CONCURRENT_MESH_3 if that option is ON +if( ACTIVATE_CONCURRENT_MESH_3 ) + add_definitions( -DCGAL_CONCURRENT_MESH_3 ) + find_package( TBB REQUIRED ) +else( ACTIVATE_CONCURRENT_MESH_3 ) + option( LINK_WITH_TBB + "Link with TBB anyway so we can use TBB timers for profiling" + ON) + if( LINK_WITH_TBB ) + find_package( TBB ) + endif( LINK_WITH_TBB ) +endif() + +if( TBB_FOUND ) + include(${TBB_USE_FILE}) +endif() + # Find Qt4 itself set( QT_USE_QTXML TRUE ) set( QT_USE_QTMAIN TRUE ) @@ -133,7 +190,7 @@ set(SCENE_SEGMENTED_IMAGE_ITEM_LIB "${MESH_3_LIB_PREFIX}scene_segmented_image_item") add_library(${SCENE_SEGMENTED_IMAGE_ITEM_LIB} SHARED Scene_segmented_image_item.cpp Scene_segmented_image_item.moc) - target_link_libraries(${SCENE_SEGMENTED_IMAGE_ITEM_LIB} ${SCENE_ITEM_LIB} ${CGAL_LIBRARIES}) + target_link_libraries(${SCENE_SEGMENTED_IMAGE_ITEM_LIB} ${SCENE_ITEM_LIB} ${CGAL_LIBRARIES} ${TBB_LIBRARIES}) set_target_properties(${SCENE_SEGMENTED_IMAGE_ITEM_LIB} PROPERTIES DEFINE_SYMBOL scene_segmented_image_item_EXPORTS) if(GLEW_FOUND) @@ -143,43 +200,49 @@ set(SCENE_POLYHEDRON_ITEM_LIB "${MESH_3_LIB_PREFIX}scene_polyhedron_item") add_library(${SCENE_POLYHEDRON_ITEM_LIB} SHARED Scene_polyhedron_item.cpp Scene_polyhedron_item.moc) - target_link_libraries(${SCENE_POLYHEDRON_ITEM_LIB} ${SCENE_ITEM_LIB} ${CGAL_LIBRARIES}) + target_link_libraries(${SCENE_POLYHEDRON_ITEM_LIB} ${SCENE_ITEM_LIB} ${CGAL_LIBRARIES} ${TBB_LIBRARIES}) set_target_properties(${SCENE_POLYHEDRON_ITEM_LIB} PROPERTIES DEFINE_SYMBOL scene_polyhedron_item_EXPORTS) set(POLYGON_SOUP_LIB "${MESH_3_LIB_PREFIX}polygon_soup") add_library(${POLYGON_SOUP_LIB} SHARED Scene_polygon_soup.cpp Scene_polygon_soup.moc) - target_link_libraries(${POLYGON_SOUP_LIB} ${SCENE_ITEM_LIB} ${CGAL_LIBRARIES}) + target_link_libraries(${POLYGON_SOUP_LIB} ${SCENE_ITEM_LIB} ${CGAL_LIBRARIES} ${TBB_LIBRARIES}) set_target_properties(${POLYGON_SOUP_LIB} PROPERTIES DEFINE_SYMBOL polygon_soup_EXPORTS) set(SCENE_C3T3_ITEM_LIB "${MESH_3_LIB_PREFIX}scene_c3t3_item") + set (SCENE_C3T3_ITEM_LIB_SOURCE_FILES Scene_c3t3_item.cpp) + ADD_MSVC_PRECOMPILED_HEADER("StdAfx.h" "StdAfx.cpp" SCENE_C3T3_ITEM_LIB_SOURCE_FILES) + LIST(APPEND SCENE_C3T3_ITEM_LIB_SOURCE_FILES Scene_c3t3_item.moc) add_library(${SCENE_C3T3_ITEM_LIB} SHARED - Scene_c3t3_item.cpp Scene_c3t3_item.moc) - target_link_libraries(${SCENE_C3T3_ITEM_LIB} ${SCENE_ITEM_LIB} ${QGLVIEWER_LIBRARIES} ${QT_LIBRARIES} ${CGAL_LIBRARIES} ${Boost_LIBRARIES}) + ${SCENE_C3T3_ITEM_LIB_SOURCE_FILES}) + target_link_libraries(${SCENE_C3T3_ITEM_LIB} ${SCENE_ITEM_LIB} ${QGLVIEWER_LIBRARIES} ${QT_LIBRARIES} ${CGAL_LIBRARIES} ${Boost_LIBRARIES} ${TBB_LIBRARIES}) set_target_properties(${SCENE_C3T3_ITEM_LIB} PROPERTIES DEFINE_SYMBOL scene_c3t3_item_EXPORTS) set(SCENE_IMPLICIT_FUNCTION_ITEM_LIB "${MESH_3_LIB_PREFIX}scene_implicit_function_item") add_library(${SCENE_IMPLICIT_FUNCTION_ITEM_LIB} SHARED Scene_implicit_function_item.cpp Scene_implicit_function_item.moc Color_ramp.cpp) - target_link_libraries(${SCENE_IMPLICIT_FUNCTION_ITEM_LIB} ${SCENE_ITEM_LIB} ${QGLVIEWER_LIBRARIES} ${QT_LIBRARIES}) + target_link_libraries(${SCENE_IMPLICIT_FUNCTION_ITEM_LIB} ${SCENE_ITEM_LIB} ${QGLVIEWER_LIBRARIES} ${QT_LIBRARIES} ${TBB_LIBRARIES}) set_target_properties(${SCENE_IMPLICIT_FUNCTION_ITEM_LIB} PROPERTIES DEFINE_SYMBOL scene_implicit_function_item_EXPORTS) - + add_definitions(-DUSE_FORWARD_DECL) add_definitions(-DQT_STATICPLUGIN) - add_executable ( Mesh_3 MainWindow.cpp + set (MESH_3_SOURCE_FILES + MainWindow.cpp Mesh_3.cpp ${DEMO_SRC_DIR}/Scene.cpp MainWindow_moc.cpp - Scene_moc.cpp - ${UI_FILES} ${RESOURCE_FILES} ) + Scene_moc.cpp) + #ADD_MSVC_PRECOMPILED_HEADER("StdAfx.h" "StdAfx.cpp" MESH_3_SOURCE_FILES) + LIST(APPEND MESH_3_SOURCE_FILES ${UI_FILES} ${RESOURCE_FILES}) + add_executable( Mesh_3 ${MESH_3_SOURCE_FILES} ) add_to_cached_list( CGAL_EXECUTABLE_TARGETS Mesh_3 ) # Link with Qt libraries target_link_libraries( Mesh_3 ${QT_LIBRARIES} ) # Link with CGAL - target_link_libraries( Mesh_3 ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES} ) + target_link_libraries( Mesh_3 ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES} ${TBB_LIBRARIES}) # Link with libQGLViewer, OpenGL target_link_libraries( Mesh_3 ${QGLVIEWER_LIBRARIES} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ) @@ -217,7 +280,7 @@ # Link with scene_item target_link_libraries( ${plugin_name} ${SCENE_ITEM_LIB}) # Link with CGAL - target_link_libraries( ${plugin_name} ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES} ) + target_link_libraries( ${plugin_name} ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES} ${TBB_LIBRARIES}) endmacro(polyhedron_demo_plugin) set(IO_IMAGE_PLUGIN_LIB "${MESH_3_LIB_PREFIX}io_image_plugin") @@ -235,7 +298,7 @@ if(GLEW_FOUND) set(VOLUME_PLANES_PLUGIN_LIB "${MESH_3_LIB_PREFIX}volume_planes_plugin") polyhedron_demo_plugin(${VOLUME_PLANES_PLUGIN_LIB} Volume_planes_plugin - ${VOLUME_MOC_OUTFILES} + ${VOLUME_MOC_OUTFILES} Volume_plane_intersection.cpp) target_link_libraries(${VOLUME_PLANES_PLUGIN_LIB} ${SCENE_SEGMENTED_IMAGE_ITEM_LIB} ${VIEWER_LIB}) else() @@ -257,13 +320,25 @@ target_link_libraries(${IO_IMPLICIT_FUNCTION_PLUGIN_LIB} ${SCENE_IMPLICIT_FUNCTION_ITEM_LIB}) set(MESH_3_PLUGIN_LIB "${MESH_3_LIB_PREFIX}mesh_3_plugin") - polyhedron_demo_plugin(${MESH_3_PLUGIN_LIB} Mesh_3_plugin - Mesh_3_plugin_polyhedron_cgal_code.cpp - Mesh_3_plugin_image_cgal_code.cpp - Mesh_3_plugin_implicit_function_cgal_code.cpp - Meshing_thread.cpp - Scene_c3t3_item.moc - ${meshingUI_FILES}) + set(MESH_3_PLUGIN_SOURCE_FILES + Mesh_3_plugin.cpp + Mesh_3_plugin_polyhedron_cgal_code.cpp + Mesh_3_plugin_image_cgal_code.cpp + Mesh_3_plugin_implicit_function_cgal_code.cpp + Meshing_thread.cpp) + ADD_MSVC_PRECOMPILED_HEADER("StdAfx.h" "StdAfx.cpp" MESH_3_PLUGIN_SOURCE_FILES) + LIST(REMOVE_AT MESH_3_PLUGIN_SOURCE_FILES 0) # Remove Mesh_3_plugin.cpp since it's added by polyhedron_demo_plugin + LIST(APPEND MESH_3_PLUGIN_SOURCE_FILES "Scene_c3t3_item.moc" ${meshingUI_FILES}) + polyhedron_demo_plugin(${MESH_3_PLUGIN_LIB} Mesh_3_plugin ${MESH_3_PLUGIN_SOURCE_FILES}) + +# set(MESH_3_PLUGIN_LIB "${MESH_3_LIB_PREFIX}mesh_3_plugin") +# polyhedron_demo_plugin(${MESH_3_PLUGIN_LIB} Mesh_3_plugin +# Mesh_3_plugin_polyhedron_cgal_code.cpp +# Mesh_3_plugin_image_cgal_code.cpp +# Mesh_3_plugin_implicit_function_cgal_code.cpp +# Meshing_thread.cpp +# Scene_c3t3_item.moc +# ${meshingUI_FILES}) target_link_libraries(${MESH_3_PLUGIN_LIB} ${SCENE_C3T3_ITEM_LIB} @@ -272,14 +347,18 @@ ${SCENE_IMPLICIT_FUNCTION_ITEM_LIB} ${QGLVIEWER_LIBRARIES} ${OPENGL_gl_LIBRARY} - ${OPENGL_glu_LIBRARY}) + ${OPENGL_glu_LIBRARY} + ${TBB_LIBRARIES}) - set(MESH_3_OPTIMIZATION_PLUGIN_LIB "${MESH_3_LIB_PREFIX}mesh_3_optimization_plugin") - polyhedron_demo_plugin(${MESH_3_OPTIMIZATION_PLUGIN_LIB} Mesh_3_optimization_plugin - Mesh_3_optimization_plugin_cgal_code.cpp - Optimizer_thread.cpp - Scene_c3t3_item.moc - ${optimUI_FILES}) + set(MESH_3_OPTIMIZATION_PLUGIN_LIB "${MESH_3_LIB_PREFIX}mesh_3_optimization_plugin") + set(MESH_3_OPTIMIZATION_PLUGIN_SOURCE_FILES + Mesh_3_optimization_plugin.cpp + Mesh_3_optimization_plugin_cgal_code.cpp + Optimizer_thread.cpp) + ADD_MSVC_PRECOMPILED_HEADER("StdAfx.h" "StdAfx.cpp" MESH_3_OPTIMIZATION_PLUGIN_SOURCE_FILES) + LIST(REMOVE_AT MESH_3_OPTIMIZATION_PLUGIN_SOURCE_FILES 0) # Remove Mesh_3_optimization_plugin.cpp since it's added by polyhedron_demo_plugin + LIST(APPEND MESH_3_OPTIMIZATION_PLUGIN_SOURCE_FILES "Scene_c3t3_item.moc" ${optimUI_FILES}) + polyhedron_demo_plugin(${MESH_3_OPTIMIZATION_PLUGIN_LIB} Mesh_3_optimization_plugin ${MESH_3_OPTIMIZATION_PLUGIN_SOURCE_FILES}) target_link_libraries(${MESH_3_OPTIMIZATION_PLUGIN_LIB} ${SCENE_C3T3_ITEM_LIB} @@ -288,7 +367,8 @@ ${SCENE_IMPLICIT_FUNCTION_ITEM_LIB} ${QGLVIEWER_LIBRARIES} ${OPENGL_gl_LIBRARY} - ${OPENGL_glu_LIBRARY}) + ${OPENGL_glu_LIBRARY} + ${TBB_LIBRARIES}) else (CGAL_Qt4_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND AND Boost_FOUND) diff -Nru cgal-4.4/demo/Mesh_3/Color_ramp.cpp cgal-4.5/demo/Mesh_3/Color_ramp.cpp --- cgal-4.4/demo/Mesh_3/Color_ramp.cpp 2012-11-13 13:13:57.000000000 +0000 +++ cgal-4.5/demo/Mesh_3/Color_ramp.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -1,3 +1,5 @@ +#include "config.h" + #include "Color_ramp.h" #include diff -Nru cgal-4.4/demo/Mesh_3/concurrent_mesher_config.cfg cgal-4.5/demo/Mesh_3/concurrent_mesher_config.cfg --- cgal-4.4/demo/Mesh_3/concurrent_mesher_config.cfg 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/demo/Mesh_3/concurrent_mesher_config.cfg 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,27 @@ +#========================================== +#======== Worksharing strategy =========== +#========================================== + +locking_grid_num_cells_per_axis = 50 +first_grid_lock_radius = 0 + + +#========================================== +#============= Brute-force ================ +#========================================== + +#locking_grid_num_cells_per_axis = 30 +#first_grid_lock_radius = 2 + + +#========================================== +#=============== Other ==================== +#========================================== + +refinement_grainsize = 10 # for parallel_for techniques +refinement_batch_size = 10000 # for parallel_for technique +work_stats_grid_num_cells_per_axis = 5 # for "task" technique +num_work_items_per_batch = 50 # for "task" technique +min_num_vertices_of_coarse_mesh = 100 +num_vertices_of_coarse_mesh_per_core = 3.5 +num_pseudo_infinite_vertices_per_core = 5.0 \ No newline at end of file diff -Nru cgal-4.4/demo/Mesh_3/config.h cgal-4.5/demo/Mesh_3/config.h --- cgal-4.4/demo/Mesh_3/config.h 2012-11-13 13:13:57.000000000 +0000 +++ cgal-4.5/demo/Mesh_3/config.h 2014-08-29 13:58:16.000000000 +0000 @@ -1,9 +1,20 @@ +#ifndef CGAL_DEMO_MESH_3_CONFIG_H +#define CGAL_DEMO_MESH_3_CONFIG_H + +//#define CGAL_PROFILE + // #define CGAL_POLYHEDRON_DEMO_NO_NEF // #define CGAL_POLYHEDRON_DEMO_NO_SURFACE_MESHER // #define CGAL_POLYHEDRON_DEMO_NO_PARAMETRIZATION -#ifndef CGAL_POLYHEDRON_DEMO_CONFIG_H -#define CGAL_POLYHEDRON_DEMO_CONFIG_H +//#define CGAL_MESH_3_VERBOSE +//#define CGAL_MESH_3_PERTURBER_HIGH_VERBOSITY +//#define CGAL_MESH_3_EXUDER_VERBOSE +//#define CGAL_MESH_3_EXUDER_HIGH_VERBOSITY +//#define CGAL_MESH_3_VERY_VERBOSE +//#define CGAL_MESH_3_IO_VERBOSE + +//#define SHOW_REMAINING_BAD_ELEMENT_IN_RED #ifndef CGAL_POLYHEDRON_DEMO_NO_PARAMETRIZATION # define CGAL_POLYHEDRON_DEMO_USE_PARAMETRIZATION @@ -17,4 +28,94 @@ # define CGAL_POLYHEDRON_DEMO_USE_SURFACE_MESHER #endif -#endif // CGAL_POLYHEDRON_DEMO_CONFIG_H +#define CGAL_MESH_3_DEMO_BIGGER_HISTOGRAM_WITH_WHITE_BACKGROUNG + +// If you define this, implicit function and segmented images won't be available +//#define CGAL_MESH_3_DEMO_ACTIVATE_SHARP_FEATURES_IN_POLYHEDRAL_DOMAIN +#ifndef CGAL_MESH_3_DEMO_ACTIVATE_SHARP_FEATURES_IN_POLYHEDRAL_DOMAIN +# define CGAL_MESH_3_DEMO_ACTIVATE_IMPLICIT_FUNCTIONS +# define CGAL_MESH_3_DEMO_ACTIVATE_SEGMENTED_IMAGES +#endif + +//#define CGAL_MESH_3_DEMO_DONT_COUNT_TETS_ADJACENT_TO_SHARP_FEATURES_FOR_HISTOGRAM + +// Optimizers +//#define CGAL_MESH_3_DEMO_DISABLE_ODT +//#define CGAL_MESH_3_DEMO_DISABLE_LLOYD +//#define CGAL_MESH_3_DEMO_DISABLE_PERTURBER +//#define CGAL_MESH_3_DEMO_DISABLE_EXUDER + +// ========================================================================== +// MESH_3 GENERAL PARAMETERS +// ========================================================================== + +//#define CGAL_MESH_3_USE_OLD_SURFACE_RESTRICTED_DELAUNAY_UPDATE // WARNING: VERY SLOW +//#define CGAL_MESH_3_INITIAL_POINTS_NO_RANDOM_SHOOTING +//#define CGAL_MESHES_DEBUG_REFINEMENT_POINTS +//#define CHECK_AND_DISPLAY_THE_NUMBER_OF_BAD_ELEMENTS_IN_THE_END + +// ========================================================================== +// ========================================================================== +// CONCURRENT MESH_3? +// ========================================================================== +// ========================================================================== + +#ifdef CGAL_CONCURRENT_MESH_3 + +# ifndef CGAL_LINKED_WITH_TBB +# pragma message(" : Warning: CGAL_LINKED_WITH_TBB not defined: EVERYTHING WILL BE SEQUENTIAL.") +# endif + +# define CGAL_MESH_3_USE_LAZY_SORTED_REFINEMENT_QUEUE // default behavior +//# define CGAL_MESH_3_USE_LAZY_UNSORTED_REFINEMENT_QUEUE +# define CGAL_MESH_3_IF_UNSORTED_QUEUE_JUST_SORT_AFTER_SCAN +# include + + // ========================================================================== + // Verbose + // ========================================================================== + +//# define CGAL_CONCURRENT_MESH_3_VERBOSE +//#define CGAL_CONCURRENT_MESH_3_VERY_VERBOSE + + // ========================================================================== + // Concurrency config + // ========================================================================== + + const char * const CONFIG_FILENAME = "concurrent_mesher_config.cfg"; + + // ===================== + // Worksharing strategy + // ===================== + +//# define CGAL_MESH_3_LOAD_BASED_WORKSHARING // Not recommended +//# define CGAL_MESH_3_TASK_SCHEDULER_SORTED_BATCHES_WITH_MULTISET +//# define CGAL_MESH_3_TASK_SCHEDULER_SORTED_BATCHES_WITH_SORT // default + + // ========================================================================== + // Profiling + // ========================================================================== + + // For abortion profiling, etc. +//# define CGAL_CONCURRENT_MESH_3_PROFILING + // Debugging +//# define CGAL_DEBUG_FORCE_SEQUENTIAL_MESH_REFINEMENT + + +// ========================================================================== +// ========================================================================== +// SEQUENTIAL MESH_3? +// ========================================================================== +// ========================================================================== + +#else // !CGAL_CONCURRENT_MESH_3 + +//# define CGAL_MESH_3_USE_LAZY_SORTED_REFINEMENT_QUEUE +//# define CGAL_MESH_3_USE_LAZY_UNSORTED_REFINEMENT_QUEUE +# define CGAL_MESH_3_IF_UNSORTED_QUEUE_JUST_SORT_AFTER_SCAN + +#endif // CGAL_CONCURRENT_MESH_3 + +//#define CGAL_MESH_3_PROFILING + +#endif // CGAL_DEMO_MESH_3_CONFIG_H diff -Nru cgal-4.4/demo/Mesh_3/include/CGAL_demo/Io_plugin_interface.h cgal-4.5/demo/Mesh_3/include/CGAL_demo/Io_plugin_interface.h --- cgal-4.4/demo/Mesh_3/include/CGAL_demo/Io_plugin_interface.h 2012-11-13 13:13:57.000000000 +0000 +++ cgal-4.5/demo/Mesh_3/include/CGAL_demo/Io_plugin_interface.h 2014-08-29 13:58:16.000000000 +0000 @@ -17,7 +17,7 @@ virtual Scene_item* load(QFileInfo fileinfo) = 0; virtual bool canSave(const Scene_item*) = 0; - virtual bool save(const Scene_item*, QFileInfo fileinfo) = 0; + virtual bool save(const Scene_item*, QFileInfo fileinfo, QString selectedFilter) = 0; }; Q_DECLARE_INTERFACE(Io_plugin_interface, diff -Nru cgal-4.4/demo/Mesh_3/Io_c3t3_plugin.cpp cgal-4.5/demo/Mesh_3/Io_c3t3_plugin.cpp --- cgal-4.4/demo/Mesh_3/Io_c3t3_plugin.cpp 2012-11-13 13:13:57.000000000 +0000 +++ cgal-4.5/demo/Mesh_3/Io_c3t3_plugin.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -1,3 +1,5 @@ +#include "config.h" + #include "Scene_c3t3_item.h" #include @@ -17,14 +19,15 @@ virtual Scene_item* load(QFileInfo) { return NULL; } virtual bool canSave(const Scene_item*); - virtual bool save(const Scene_item*, QFileInfo fileinfo); + virtual bool save(const Scene_item*, QFileInfo, QString); }; QStringList Io_c3t3_plugin::nameFilters() const { - return QStringList() << "Mesh (*.mesh)"; + return QStringList() << "Mesh (*.mesh)" + << "Maya - surface only (*.ma)" << "Maya - cells (*.ma)"; } @@ -36,7 +39,7 @@ } bool -Io_c3t3_plugin::save(const Scene_item* item, QFileInfo fileInfo) +Io_c3t3_plugin::save(const Scene_item* item, QFileInfo fileInfo, QString selectedFilter) { const Scene_c3t3_item* c3t3_item = qobject_cast(item); if ( NULL == c3t3_item ) @@ -45,8 +48,17 @@ } QString path = fileInfo.absoluteFilePath(); - std::ofstream medit_file (qPrintable(path)); - c3t3_item->c3t3().output_to_medit(medit_file,true,true); + if (fileInfo.suffix() == "mesh") + { + std::ofstream medit_file (qPrintable(path)); + c3t3_item->c3t3().output_to_medit(medit_file,true,true); + } + else if (fileInfo.suffix() == "ma") + { + std::ofstream maya_file (qPrintable(path)); + c3t3_item->c3t3().output_to_maya( + maya_file, selectedFilter == "Maya - surface only (*.ma)"); + } return true; } diff -Nru cgal-4.4/demo/Mesh_3/Io_image_plugin.cpp cgal-4.5/demo/Mesh_3/Io_image_plugin.cpp --- cgal-4.4/demo/Mesh_3/Io_image_plugin.cpp 2012-11-13 13:13:57.000000000 +0000 +++ cgal-4.5/demo/Mesh_3/Io_image_plugin.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -1,3 +1,5 @@ +#include "config.h" + #ifdef SCENE_SEGMENTED_IMAGE_GL_BUFFERS_AVAILABLE # include #endif @@ -27,7 +29,7 @@ Scene_item* load(QFileInfo fileinfo); bool canSave(const Scene_item*); - bool save(const Scene_item*, QFileInfo) { return false; } + bool save(const Scene_item*, QFileInfo, QString) { return false; } }; QStringList Io_image_plugin::nameFilters() const { diff -Nru cgal-4.4/demo/Mesh_3/Io_implicit_function_plugin.cpp cgal-4.5/demo/Mesh_3/Io_implicit_function_plugin.cpp --- cgal-4.4/demo/Mesh_3/Io_implicit_function_plugin.cpp 2012-11-13 13:13:57.000000000 +0000 +++ cgal-4.5/demo/Mesh_3/Io_implicit_function_plugin.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -21,6 +21,7 @@ //****************************************************************************** // File Description : //****************************************************************************** +#include "config.h" #include #include diff -Nru cgal-4.4/demo/Mesh_3/Io_off_plugin.cpp cgal-4.5/demo/Mesh_3/Io_off_plugin.cpp --- cgal-4.4/demo/Mesh_3/Io_off_plugin.cpp 2012-11-13 13:13:57.000000000 +0000 +++ cgal-4.5/demo/Mesh_3/Io_off_plugin.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -1,3 +1,5 @@ +#include "config.h" + #include "Scene_polyhedron_item.h" #include "Scene_polygon_soup.h" #include "Polyhedron_type.h" @@ -18,7 +20,7 @@ Scene_item* load(QFileInfo fileinfo); bool canSave(const Scene_item*); - bool save(const Scene_item*, QFileInfo fileinfo); + bool save(const Scene_item*, QFileInfo, QString); }; QStringList Io_off_plugin::nameFilters() const { @@ -69,7 +71,8 @@ qobject_cast(item); } -bool Io_off_plugin::save(const Scene_item* item, QFileInfo fileinfo) +bool Io_off_plugin::save(const Scene_item* item, QFileInfo fileinfo, + QString /* `selecterFilter` is not used: only OFF */) { // This plugin supports polyhedrons and polygon soups const Scene_polyhedron_item* poly_item = diff -Nru cgal-4.4/demo/Mesh_3/MainWindow.cpp cgal-4.5/demo/Mesh_3/MainWindow.cpp --- cgal-4.4/demo/Mesh_3/MainWindow.cpp 2012-11-13 13:13:57.000000000 +0000 +++ cgal-4.5/demo/Mesh_3/MainWindow.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -146,6 +146,26 @@ readSettings(); // Among other things, the column widths are stored. + const char *windowTitle = "CGAL 3D mesh generator demo [" +#ifdef CGAL_CONCURRENT_MESH_3 + "Parallel" +#else + "Sequential" +# ifdef CGAL_LINKED_WITH_TBB + " - With TBB" +# else + " - Without TBB" +# endif +#endif +#ifdef _DEBUG + " - Debug]"; +#else + "]"; +#endif + + setWindowTitle(QApplication::translate( + "MainWindow", windowTitle, 0, QApplication::UnicodeUTF8)); + this->dumpObjectTree(); } @@ -482,11 +502,13 @@ return; } + QString selectedFilter; QString filename = QFileDialog::getSaveFileName(this, tr("Save to File..."), QString(), - filters.join(";;")); + filters.join(";;"), + &selectedFilter); QFileInfo fileinfo(filename); if(!fileinfo.isFile() || @@ -499,7 +521,7 @@ { Q_FOREACH(Io_plugin_interface* plugin, canSavePlugins) { - if(plugin->save(item, fileinfo)) + if(plugin->save(item, fileinfo, selectedFilter)) break; } } diff -Nru cgal-4.4/demo/Mesh_3/MainWindow.h cgal-4.5/demo/Mesh_3/MainWindow.h --- cgal-4.4/demo/Mesh_3/MainWindow.h 2012-11-13 13:13:57.000000000 +0000 +++ cgal-4.5/demo/Mesh_3/MainWindow.h 2014-08-29 13:58:16.000000000 +0000 @@ -21,8 +21,6 @@ class MainWindow; } -#include "Polyhedron_type_fwd.h" - #include class MainWindow : diff -Nru cgal-4.4/demo/Mesh_3/Mesh_3.cpp cgal-4.5/demo/Mesh_3/Mesh_3.cpp --- cgal-4.4/demo/Mesh_3/Mesh_3.cpp 2012-11-13 13:13:57.000000000 +0000 +++ cgal-4.5/demo/Mesh_3/Mesh_3.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -1,3 +1,5 @@ +#include "config.h" + #include "MainWindow.h" #include #include diff -Nru cgal-4.4/demo/Mesh_3/Mesh_3_optimization_plugin_cgal_code.cpp cgal-4.5/demo/Mesh_3/Mesh_3_optimization_plugin_cgal_code.cpp --- cgal-4.4/demo/Mesh_3/Mesh_3_optimization_plugin_cgal_code.cpp 2013-12-21 20:00:22.000000000 +0000 +++ cgal-4.5/demo/Mesh_3/Mesh_3_optimization_plugin_cgal_code.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -1,3 +1,5 @@ +#include "config.h" + #include "C3t3_type.h" #include "Scene_c3t3_item.h" #include "Scene_polyhedron_item.h" @@ -88,7 +90,8 @@ // Create domain using real type of c3t3_item.data_item() // ------------------ - + +#ifdef CGAL_MESH_3_DEMO_ACTIVATE_SEGMENTED_IMAGES // Image const Scene_segmented_image_item* image_item = qobject_cast(c3t3_item.data_item()); @@ -110,7 +113,7 @@ return new Optimizer_thread(p_opt_function, p_result_item); } - +#endif // Polyhedron const Scene_polyhedron_item* poly_item = @@ -134,6 +137,7 @@ return new Optimizer_thread(p_opt_function, p_result_item); } +#ifdef CGAL_MESH_3_DEMO_ACTIVATE_IMPLICIT_FUNCTIONS // Function const Scene_implicit_function_item* function_item = qobject_cast(c3t3_item.data_item()); @@ -160,6 +164,7 @@ return new Optimizer_thread(p_opt_function, p_result_item); } +#endif return NULL; } @@ -252,6 +257,9 @@ // ----------------------------------- // Odt // ----------------------------------- + +#ifndef CGAL_MESH_3_DEMO_DISABLE_ODT + struct Odt_parameters { double time_limit; @@ -356,12 +364,16 @@ return cgal_code_optimization(c3t3_item, p, create_new_item); } +#endif // ----------------------------------- // Lloyd // ----------------------------------- + +#ifndef CGAL_MESH_3_DEMO_DISABLE_LLOYD + struct Lloyd_parameters { double time_limit; @@ -466,12 +478,16 @@ return cgal_code_optimization(c3t3_item, p, create_new_item); } +#endif // ----------------------------------- // Perturbation // ----------------------------------- + +#ifndef CGAL_MESH_3_DEMO_DISABLE_PERTURBER + struct Perturb_parameters { double time_limit; @@ -606,11 +622,14 @@ return cgal_code_optimization(c3t3_item, p, create_new_item); } - +#endif // ----------------------------------- // Exudation // ----------------------------------- + +#ifndef CGAL_MESH_3_DEMO_DISABLE_EXUDER + struct Exude_parameters { double time_limit; @@ -696,7 +715,7 @@ if ( NULL != exude_ ) { return CGAL::MESH_OPTIMIZATION_UNKNOWN_ERROR; } // Create exuder - exude_ = new Exuder(c3t3,criterion_); + exude_ = new Exuder(c3t3, criterion_); if ( NULL == exude_ ) { return CGAL::MESH_OPTIMIZATION_UNKNOWN_ERROR; } // Set time_limit @@ -743,3 +762,4 @@ return new Optimizer_thread(p_opt_function, p_result_item); } +#endif diff -Nru cgal-4.4/demo/Mesh_3/Mesh_3_optimization_plugin.cpp cgal-4.5/demo/Mesh_3/Mesh_3_optimization_plugin.cpp --- cgal-4.4/demo/Mesh_3/Mesh_3_optimization_plugin.cpp 2013-07-06 19:00:27.000000000 +0000 +++ cgal-4.5/demo/Mesh_3/Mesh_3_optimization_plugin.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -34,29 +34,37 @@ // declare the CGAL function +#ifndef CGAL_MESH_3_DEMO_DISABLE_ODT Optimizer_thread* cgal_code_odt_mesh_3(Scene_c3t3_item& c3t3_item, const double time_limit, const double convergence_ratio, const double freeze_ratio, const int max_iteration_number, const bool create_new_item); +#endif +#ifndef CGAL_MESH_3_DEMO_DISABLE_LLOYD Optimizer_thread* cgal_code_lloyd_mesh_3(Scene_c3t3_item& c3t3_item, const double time_limit, const double convergence_ratio, const double freeze_ratio, const int max_iteration_number, const bool create_new_item); +#endif +#ifndef CGAL_MESH_3_DEMO_DISABLE_PERTURBER Optimizer_thread* cgal_code_perturb_mesh_3(Scene_c3t3_item& c3t3_item, const double time_limit, const double sliver_bound, const bool create_new_item); +#endif +#ifndef CGAL_MESH_3_DEMO_DISABLE_EXUDER Optimizer_thread* cgal_code_exude_mesh_3(Scene_c3t3_item& c3t3_item, const double time_limit, const double sliver_bound, const bool create_new_item); +#endif QString translate(CGAL::Mesh_optimization_return_code rc); @@ -77,10 +85,18 @@ inline virtual QList actions() const; public slots: +#ifndef CGAL_MESH_3_DEMO_DISABLE_ODT void odt(); +#endif +#ifndef CGAL_MESH_3_DEMO_DISABLE_LLOYD void lloyd(); +#endif +#ifndef CGAL_MESH_3_DEMO_DISABLE_PERTURBER void perturb(); +#endif +#ifndef CGAL_MESH_3_DEMO_DISABLE_EXUDER void exude(); +#endif void optimization_done(Optimizer_thread* t); void status_report(QString s); @@ -127,29 +143,37 @@ this->mw = mainWindow; // Create menu items +#ifndef CGAL_MESH_3_DEMO_DISABLE_ODT actionOdt = this->getActionFromMainWindow(mw, "actionOdt"); if( NULL != actionOdt ) { connect(actionOdt, SIGNAL(triggered()), this, SLOT(odt())); } +#endif +#ifndef CGAL_MESH_3_DEMO_DISABLE_LLOYD actionLloyd = this->getActionFromMainWindow(mw, "actionLloyd"); if( NULL != actionLloyd ) { connect(actionLloyd, SIGNAL(triggered()), this, SLOT(lloyd())); } +#endif +#ifndef CGAL_MESH_3_DEMO_DISABLE_PERTURBER actionPerturb = this->getActionFromMainWindow(mw, "actionPerturb"); if( NULL != actionPerturb ) { connect(actionPerturb, SIGNAL(triggered()), this, SLOT(perturb())); } +#endif +#ifndef CGAL_MESH_3_DEMO_DISABLE_EXUDER actionExude = this->getActionFromMainWindow(mw, "actionExude"); if( NULL != actionExude ) { connect(actionExude, SIGNAL(triggered()), this, SLOT(exude())); } +#endif msg = msg_interface; } @@ -164,6 +188,7 @@ } +#ifndef CGAL_MESH_3_DEMO_DISABLE_ODT void Mesh_3_optimization_plugin::odt() { @@ -228,8 +253,10 @@ launch_thread(opt_thread, "Odt iterations are running..."); QApplication::restoreOverrideCursor(); } +#endif +#ifndef CGAL_MESH_3_DEMO_DISABLE_LLOYD void Mesh_3_optimization_plugin::lloyd() { @@ -294,8 +321,10 @@ launch_thread(opt_thread, "Lloyd iterations are running..."); QApplication::restoreOverrideCursor(); } +#endif +#ifndef CGAL_MESH_3_DEMO_DISABLE_PERTURBER void Mesh_3_optimization_plugin::perturb() { @@ -356,8 +385,10 @@ launch_thread(opt_thread, "Sliver perturbation is running..."); QApplication::restoreOverrideCursor(); } +#endif +#ifndef CGAL_MESH_3_DEMO_DISABLE_EXUDER void Mesh_3_optimization_plugin::exude() { @@ -418,6 +449,7 @@ launch_thread(opt_thread, "Sliver exudation is running..."); QApplication::restoreOverrideCursor(); } +#endif Scene_c3t3_item* diff -Nru cgal-4.4/demo/Mesh_3/Mesh_3_plugin.cpp cgal-4.5/demo/Mesh_3/Mesh_3_plugin.cpp --- cgal-4.4/demo/Mesh_3/Mesh_3_plugin.cpp 2013-03-07 20:00:26.000000000 +0000 +++ cgal-4.5/demo/Mesh_3/Mesh_3_plugin.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -43,21 +43,26 @@ const double sizing, const double approx, const double tets_sizing, - const double tet_shape); + const double tet_shape, + const bool protect_features); +#ifdef CGAL_MESH_3_DEMO_ACTIVATE_SEGMENTED_IMAGES Meshing_thread* cgal_code_mesh_3(const Image*, const double angle, const double sizing, const double approx, const double tets_sizing, const double tet_shape); +#endif +#ifdef CGAL_MESH_3_DEMO_ACTIVATE_IMPLICIT_FUNCTIONS Meshing_thread* cgal_code_mesh_3(const Implicit_function_interface*, const double angle, const double sizing, const double approx, const double tets_sizing, const double tet_shape); +#endif double get_approximate(double d, int precision, int& decimals); @@ -155,6 +160,7 @@ QDialog dialog(mw); Ui::Meshing_dialog ui; ui.setupUi(&dialog); + ui.sharpFeaturesGroup->setVisible(poly_item != 0); connect(ui.buttonBox, SIGNAL(accepted()), &dialog, SLOT(accept())); connect(ui.buttonBox, SIGNAL(rejected()), @@ -218,7 +224,7 @@ const double facet_sizing = !ui.noFacetSizing->isChecked() ? 0 : ui.facetSizing->value(); const double radius_edge = !ui.noTetShape->isChecked() ? 0 : ui.tetShape->value(); const double tet_sizing = !ui.noTetSizing->isChecked() ? 0 : ui.tetSizing->value(); - + const bool protect_features = ui.protect->isChecked(); // ----------------------------------- // Dispatch mesh process @@ -239,9 +245,11 @@ thread = cgal_code_mesh_3(pMesh, angle, facet_sizing, approx, - tet_sizing, radius_edge); + tet_sizing, radius_edge, + protect_features); } - // Image + // Image +#ifdef CGAL_MESH_3_DEMO_ACTIVATE_SEGMENTED_IMAGES else if( NULL != image_item ) { const Image* pImage = image_item->image(); @@ -255,7 +263,10 @@ angle, facet_sizing, approx, tet_sizing, radius_edge); } +#endif + // Function +#ifdef CGAL_MESH_3_DEMO_ACTIVATE_IMPLICIT_FUNCTIONS else if( NULL != function_item ) { const Implicit_function_interface* pFunction = function_item->function(); @@ -270,6 +281,7 @@ tet_sizing, radius_edge); } +#endif if ( NULL == thread ) { @@ -346,10 +358,19 @@ str.append(QString("( %1 )
").arg(param)); } + Scene_c3t3_item* result_item = thread->item(); + const Scene_item::Bbox& bbox = result_item->bbox(); + str.append(QString("BBox (x,y,z): [ %1, %2 ], [ %3, %4 ], [ %5, %6 ],
") + .arg(bbox.xmin) + .arg(bbox.xmax) + .arg(bbox.ymin) + .arg(bbox.ymax) + .arg(bbox.zmin) + .arg(bbox.zmax)); + msg->information(qPrintable(str)); // Treat new c3t3 item - Scene_c3t3_item* result_item = thread->item(); treat_result(*source_item_, *result_item); // close message box diff -Nru cgal-4.4/demo/Mesh_3/Mesh_3_plugin_image_cgal_code.cpp cgal-4.5/demo/Mesh_3/Mesh_3_plugin_image_cgal_code.cpp --- cgal-4.4/demo/Mesh_3/Mesh_3_plugin_image_cgal_code.cpp 2012-11-13 13:13:57.000000000 +0000 +++ cgal-4.5/demo/Mesh_3/Mesh_3_plugin_image_cgal_code.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -1,3 +1,7 @@ +#include "config.h" + +#ifdef CGAL_MESH_3_DEMO_ACTIVATE_SEGMENTED_IMAGES + #include "C3t3_type.h" #include "Scene_c3t3_item.h" #include "Image_type.h" @@ -23,6 +27,7 @@ Scene_c3t3_item* p_new_item = new Scene_c3t3_item(); Mesh_parameters param; + param.protect_features = false; param.facet_angle = facet_angle; param.facet_sizing = facet_sizing; param.facet_approx = facet_approx; @@ -32,3 +37,5 @@ Mesh_function* p_mesh_function = new Mesh_function(p_new_item->c3t3(), p_domain, param); return new Meshing_thread(p_mesh_function, p_new_item); } + +#endif diff -Nru cgal-4.4/demo/Mesh_3/Mesh_3_plugin_implicit_function_cgal_code.cpp cgal-4.5/demo/Mesh_3/Mesh_3_plugin_implicit_function_cgal_code.cpp --- cgal-4.4/demo/Mesh_3/Mesh_3_plugin_implicit_function_cgal_code.cpp 2012-11-13 13:13:57.000000000 +0000 +++ cgal-4.5/demo/Mesh_3/Mesh_3_plugin_implicit_function_cgal_code.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -1,3 +1,7 @@ +#include "config.h" + +#ifdef CGAL_MESH_3_DEMO_ACTIVATE_IMPLICIT_FUNCTIONS + #include "C3t3_type.h" #include "Scene_c3t3_item.h" #include "implicit_functions/Implicit_function_interface.h" @@ -31,6 +35,7 @@ Scene_c3t3_item* p_new_item = new Scene_c3t3_item(); Mesh_parameters param; + param.protect_features = false; param.facet_angle = facet_angle; param.facet_sizing = facet_sizing; param.facet_approx = facet_approx; @@ -40,3 +45,5 @@ Mesh_function* p_mesh_function = new Mesh_function(p_new_item->c3t3(), p_domain, param); return new Meshing_thread(p_mesh_function, p_new_item); } + +#endif // CGAL_MESH_3_DEMO_ACTIVATE_IMPLICIT_FUNCTIONS diff -Nru cgal-4.4/demo/Mesh_3/Mesh_3_plugin_polyhedron_cgal_code.cpp cgal-4.5/demo/Mesh_3/Mesh_3_plugin_polyhedron_cgal_code.cpp --- cgal-4.4/demo/Mesh_3/Mesh_3_plugin_polyhedron_cgal_code.cpp 2012-11-13 13:13:57.000000000 +0000 +++ cgal-4.5/demo/Mesh_3/Mesh_3_plugin_polyhedron_cgal_code.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -1,3 +1,5 @@ +#include "config.h" + #include "C3t3_type.h" #include "Scene_c3t3_item.h" #include "Polyhedron_type.h" @@ -12,13 +14,18 @@ const double facet_sizing, const double facet_approx, const double tet_sizing, - const double tet_shape) + const double tet_shape, + const bool protect_features) { typedef Mesh_function Mesh_function; if( NULL == pMesh ) { return NULL; } Polyhedral_mesh_domain* p_domain = new Polyhedral_mesh_domain(*pMesh); + + if(protect_features) { + p_domain->detect_features(); + } Scene_c3t3_item* p_new_item = new Scene_c3t3_item(); @@ -28,6 +35,7 @@ param.facet_approx = facet_approx; param.tet_sizing = tet_sizing; param.tet_shape = tet_shape; + param.protect_features = protect_features; Mesh_function* p_mesh_function = new Mesh_function(p_new_item->c3t3(), p_domain, param); return new Meshing_thread(p_mesh_function, p_new_item); diff -Nru cgal-4.4/demo/Mesh_3/Mesh_function.h cgal-4.5/demo/Mesh_3/Mesh_function.h --- cgal-4.4/demo/Mesh_3/Mesh_function.h 2012-11-13 13:13:57.000000000 +0000 +++ cgal-4.5/demo/Mesh_3/Mesh_function.h 2014-08-29 13:58:16.000000000 +0000 @@ -25,17 +25,21 @@ #ifndef CGAL_DEMO_MESH_3_MESH_FUNCTION_H #define CGAL_DEMO_MESH_3_MESH_FUNCTION_H -#define CGAL_MESH_3_MESHER_STATUS_ACTIVATED 1 +//#define CGAL_MESH_3_MESHER_STATUS_ACTIVATED 1 + +#include #include #include #include #include +#include #include "C3t3_type.h" #include "Meshing_thread.h" - +#include // for C3t3_initializer +#include struct Mesh_parameters { @@ -45,11 +49,29 @@ double tet_shape; double tet_sizing; + bool protect_features; inline QStringList log() const; }; +template < typename EdgeCriteria > +struct Edge_criteria_sizing_field_wrapper +{ + typedef typename EdgeCriteria::Index Index; + typedef typename EdgeCriteria::FT FT; + typedef typename EdgeCriteria::Point_3 Point_3; + + Edge_criteria_sizing_field_wrapper(const EdgeCriteria& ec) : ec_(ec) {} + FT operator()(const Point_3& p, const int dim, const Index& index) const + { return ec_.sizing_field(p,dim,index); } + +private: + // No need to copy EdgeCriteria here + const EdgeCriteria& ec_; +}; + + template < typename Domain_ > class Mesh_function : public Mesh_function_interface @@ -80,6 +102,7 @@ typedef C3t3::Triangulation Tr; typedef CGAL::Mesh_criteria_3 Mesh_criteria; + typedef Mesh_criteria::Edge_criteria Edge_criteria; typedef Mesh_criteria::Facet_criteria Facet_criteria; typedef Mesh_criteria::Cell_criteria Cell_criteria; @@ -91,7 +114,9 @@ Mesh_parameters p_; bool continue_; Mesher* mesher_; +#ifdef CGAL_MESH_3_MESHER_STATUS_ACTIVATED mutable typename Mesher::Mesher_status last_report_; +#endif }; @@ -109,7 +134,8 @@ << QString("facet max size: %1").arg(facet_sizing) << QString("facet approx error: %1").arg(facet_approx) << QString("tet shape (radius-edge): %1").arg(tet_shape) - << QString("tet max size: %1").arg(tet_sizing); + << QString("tet max size: %1").arg(tet_sizing) + << QString("protect features: %1").arg(protect_features); } @@ -124,8 +150,13 @@ , p_(p) , continue_(true) , mesher_(NULL) +#ifdef CGAL_MESH_3_MESHER_STATUS_ACTIVATED , last_report_(0,0,0) +#endif { +#ifdef CGAL_CONCURRENT_MESH_3 + Concurrent_mesher_config::load_config_file(CONFIG_FILENAME, false); +#endif } @@ -143,35 +174,48 @@ Mesh_function:: launch() { - // Mesh initialization : get some points and add them to the mesh - Initial_points_vector initial_points; - domain_->construct_initial_points_object()(std::back_inserter(initial_points),20); - - // Insert points and set their index and dimension - for ( Ipv_iterator it = initial_points.begin() ; - it != initial_points.end() ; - ++it ) - { - Vertex_handle v = c3t3_.triangulation().insert(it->first); - c3t3_.set_dimension(v,2); // by construction, points are on surface - c3t3_.set_index(v,it->second); - } - +#ifdef CGAL_MESH_3_INITIAL_POINTS_NO_RANDOM_SHOOTING + CGAL::default_random = CGAL::Random(0); +#endif + // Create mesh criteria - Mesh_criteria criteria(Facet_criteria(p_.facet_angle, + Mesh_criteria criteria(Edge_criteria(p_.facet_sizing), + Facet_criteria(p_.facet_angle, p_.facet_sizing, p_.facet_approx), Cell_criteria(p_.tet_shape, p_.tet_sizing)); - + + // Initialization of the mesh, either with the protection of sharp + // features, or with the initial points (or both). + CGAL::internal::Mesh_3::C3t3_initializer< + C3t3, + Domain, + Mesh_criteria, + CGAL::internal::Mesh_3::has_Has_features::value >() + (c3t3_, + *domain_, + criteria, + p_.protect_features); + // Build mesher and launch refinement process mesher_ = new Mesher(c3t3_, *domain_, criteria); - mesher_->initialize(); + mesher_->refine_mesh(); + /*mesher_->initialize(); +#ifdef CGAL_MESH_3_PROFILING + WallClockTimer t; +#endif + while ( ! mesher_->is_algorithm_done() && continue_ ) { mesher_->one_step(); } + +#ifdef CGAL_MESH_3_PROFILING + std::cerr << "Full refinement time (without fix_c3t3): " << t.elapsed() << " seconds." << std::endl; +#endif + */ // Ensure c3t3 is ok (usefull if process has been stop by the user) mesher_->fix_c3t3(); @@ -201,6 +245,12 @@ Mesh_function:: status(double time_period) const { + QString result; + + CGAL_USE(time_period); // to avoid a warning when the macro + // CGAL_MESH_3_MESHER_STATUS_ACTIVATED is not + // defined +#ifdef CGAL_MESH_3_MESHER_STATUS_ACTIVATED // If mesher_ is not yet created, it means that either launch() has not // been called or that initial points have not been founded if ( NULL == mesher_ ) @@ -211,7 +261,7 @@ // Get status and return a string corresponding to it typename Mesher::Mesher_status s = mesher_->status(); - QString result = QString("Vertices: %1 \n" + result = QString("Vertices: %1 \n" "Vertices inserted last %2s: %3 \n\n" "Bad facets: %4 \n" "Bad cells: %5") @@ -222,7 +272,7 @@ .arg(s.cells_queue); last_report_ = s; - +#endif return result; } diff -Nru cgal-4.4/demo/Mesh_3/Meshing_thread.cpp cgal-4.5/demo/Mesh_3/Meshing_thread.cpp --- cgal-4.4/demo/Mesh_3/Meshing_thread.cpp 2012-11-13 13:13:57.000000000 +0000 +++ cgal-4.5/demo/Mesh_3/Meshing_thread.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -22,6 +22,7 @@ // File Description : //****************************************************************************** +#include "config.h" #include #include diff -Nru cgal-4.4/demo/Mesh_3/Optimizer_thread.cpp cgal-4.5/demo/Mesh_3/Optimizer_thread.cpp --- cgal-4.4/demo/Mesh_3/Optimizer_thread.cpp 2012-11-13 13:13:57.000000000 +0000 +++ cgal-4.5/demo/Mesh_3/Optimizer_thread.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -22,6 +22,8 @@ // File Description : //****************************************************************************** +#include "config.h" + #include #include #include "Optimizer_thread.h" diff -Nru cgal-4.4/demo/Mesh_3/Polyhedron_type_fwd.h cgal-4.5/demo/Mesh_3/Polyhedron_type_fwd.h --- cgal-4.4/demo/Mesh_3/Polyhedron_type_fwd.h 2012-11-13 13:13:57.000000000 +0000 +++ cgal-4.5/demo/Mesh_3/Polyhedron_type_fwd.h 2014-08-29 13:58:16.000000000 +0000 @@ -1,13 +1,11 @@ #ifndef POLYHEDRON_TYPE_FWD_H #define POLYHEDRON_TYPE_FWD_H -#include -#include +#include // for std::allocator +#include // for std::pair #ifdef USE_FORWARD_DECL -#include - namespace CGAL { template < typename FT_ > @@ -27,16 +25,21 @@ class Alloc > class Polyhedron_3; - + + namespace Mesh_3 { + template + class Mesh_polyhedron_items; + } // end namespace Mesh_3 } // end namespace CGAL // kernel typedef CGAL::Epick Kernel; +typedef std::pair Patch_id; // surface mesh typedef CGAL::Polyhedron_3, CGAL::HalfedgeDS_default, std::allocator > Polyhedron; diff -Nru cgal-4.4/demo/Mesh_3/Polyhedron_type.h cgal-4.5/demo/Mesh_3/Polyhedron_type.h --- cgal-4.4/demo/Mesh_3/Polyhedron_type.h 2012-11-13 13:13:57.000000000 +0000 +++ cgal-4.5/demo/Mesh_3/Polyhedron_type.h 2014-08-29 13:58:16.000000000 +0000 @@ -9,6 +9,7 @@ // surface mesh #include +#include #include "Polyhedron_type_fwd.h" @@ -23,7 +24,7 @@ typedef Kernel::Iso_cuboid_3 Iso_cuboid; typedef Kernel::Plane_3 Plane_3; -// surface mesh -typedef CGAL::Polyhedron_3 Polyhedron; +// surface mesh, Patch_id is pair +typedef CGAL::Mesh_polyhedron_3::type Polyhedron; #endif // POLYHEDRON_TYPE_H diff -Nru cgal-4.4/demo/Mesh_3/Scene_c3t3_item.cpp cgal-4.5/demo/Mesh_3/Scene_c3t3_item.cpp --- cgal-4.4/demo/Mesh_3/Scene_c3t3_item.cpp 2012-11-13 13:13:57.000000000 +0000 +++ cgal-4.5/demo/Mesh_3/Scene_c3t3_item.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -1,3 +1,5 @@ +#include "config.h" + #include "Scene_c3t3_item.h" #include @@ -219,6 +221,108 @@ sb == ON_NEGATIVE_SIDE && sc == ON_NEGATIVE_SIDE) { +#ifdef SHOW_REMAINING_BAD_ELEMENT_IN_RED + if(mode != DRAW_EDGES) + { + Tr::Facet mirror_facet = c3t3().triangulation().mirror_facet(*fit); + //int mirror_index = c3t3().triangulation().mirror_index(cell, index); + bool blueOrRed = false; + if(cell->mark == index || mirror_facet.first->mark == mirror_facet.second) + { + std::cerr << "================== BAD TRIANGLE =================" << std::endl; + blueOrRed = true; + + if(cell->mark2 != -1) + { + const Kernel::Point_3& pa2 = cell->vertex((cell->mark2+1)&3)->point(); + const Kernel::Point_3& pb2 = cell->vertex((cell->mark2+2)&3)->point(); + const Kernel::Point_3& pc2 = cell->vertex((cell->mark2+3)&3)->point(); + + CGALglcolor(QColor("blue")); + std::cerr << "================== BLUE =================" << std::endl; + draw_triangle(pa2, pb2, pc2); + + const Tr::Facet f_blue(cell, cell->mark2); + Tr::Facet mirror_f_blue = c3t3().triangulation().mirror_facet(f_blue); + const Kernel::Point_3& dual_edge_pa = c3t3().triangulation().dual(f_blue.first); + const Kernel::Point_3& dual_edge_pb = c3t3().triangulation().dual(mirror_f_blue.first); + const Kernel::Point_3& dual_edge_pc = dual_edge_pa + Kernel::Vector_3(0.001, 0., 0.); + CGALglcolor(QColor("yellow")); + draw_triangle(dual_edge_pa, dual_edge_pb, dual_edge_pc); + } + else if(mirror_facet.first->mark2 != -1) + { + const Kernel::Point_3& pa2 = mirror_facet.first->vertex((mirror_facet.first->mark2+1)&3)->point(); + const Kernel::Point_3& pb2 = mirror_facet.first->vertex((mirror_facet.first->mark2+2)&3)->point(); + const Kernel::Point_3& pc2 = mirror_facet.first->vertex((mirror_facet.first->mark2+3)&3)->point(); + + CGALglcolor(QColor("blue")); + std::cerr << "================== BLUE =================" << std::endl; + draw_triangle(pa2, pb2, pc2); + + const Tr::Facet f_blue(mirror_facet.first, mirror_facet.first->mark2); + Tr::Facet mirror_f_blue = c3t3().triangulation().mirror_facet(f_blue); + const Kernel::Point_3& dual_edge_pa = c3t3().triangulation().dual(f_blue.first); + const Kernel::Point_3& dual_edge_pb = c3t3().triangulation().dual(mirror_f_blue.first); + const Kernel::Point_3& dual_edge_pc = dual_edge_pa + Kernel::Vector_3(0.001, 0., 0.); + CGALglcolor(QColor("yellow")); + draw_triangle(dual_edge_pa, dual_edge_pb, dual_edge_pc); + } + + /* + //const Kernel::Point_3& dual_edge_pa = cell->circumcenter(); + //const Kernel::Point_3& dual_edge_pb = mirror_facet.first->circumcenter(); + const Kernel::Point_3& dual_edge_pa = c3t3().triangulation().dual(cell); + const Kernel::Point_3& dual_edge_pb = c3t3().triangulation().dual(mirror_facet.first); + const Kernel::Point_3& dual_edge_pc = dual_edge_pa + Kernel::Vector_3(0.001, 0., 0.); + CGALglcolor(QColor("yellow")); + draw_triangle(dual_edge_pa, dual_edge_pb, dual_edge_pc); + */ + } + else + { + if(cell->subdomain_index() == 0) { + CGALglcolor(d->colors[cell->neighbor(index)->subdomain_index()]); + } + else { + CGALglcolor(d->colors[cell->subdomain_index()]); + } + draw_triangle(pa, pb, pc); + } + } + + /*if(mode != DRAW_EDGES) { + + Tr::Facet mirror_facet = c3t3().triangulation().mirror_facet(*fit); + //int mirror_index = c3t3().triangulation().mirror_index(cell, index); + bool blueOrRed = false; + if(cell->mark == index || mirror_facet.first->mark == mirror_facet.second) { + //if (cell->mark != -1 || cell->neighbor(index)->mark != -1) { + CGALglcolor(QColor("red")); + std::cerr << "================== RED =================" << std::endl; + blueOrRed = true; + } + + if(cell->mark2 == index || mirror_facet.first->mark2 == mirror_facet.second) { + //if(cell->mark2 != -1 || mirror_facet.first->mark2 != -1) { + CGALglcolor(QColor("blue")); + std::cerr << "================== BLUE =================" << std::endl; + blueOrRed = true; + } + + if (!blueOrRed) + { + if(cell->subdomain_index() == 0) { + CGALglcolor(d->colors[cell->neighbor(index)->subdomain_index()]); + } + else { + CGALglcolor(d->colors[cell->subdomain_index()]); + } + } + } + draw_triangle(pa, pb, pc);*/ + +#else if(mode != DRAW_EDGES) { if(cell->subdomain_index() == 0) { CGALglcolor(d->colors[cell->neighbor(index)->subdomain_index()]); @@ -228,6 +332,7 @@ } } draw_triangle(pa, pb, pc); +#endif } } ::glEnd(); @@ -299,6 +404,20 @@ void Scene_c3t3_item::build_histogram() { +#ifdef CGAL_MESH_3_DEMO_BIGGER_HISTOGRAM_WITH_WHITE_BACKGROUNG + // Create an histogram_ and display it + const int height = 280; + const int top_margin = 5; + const int left_margin = 20; + const int drawing_height = height-top_margin*2; + const int width = 804; + const int cell_width = 4; + const int text_margin = 3; + const int text_height = 34; + + histogram_ = QPixmap(width,height+text_height); + histogram_.fill(QColor(255,255,255)); +#else // Create an histogram_ and display it const int height = 140; const int top_margin = 5; @@ -311,7 +430,8 @@ histogram_ = QPixmap(width,height+text_height); histogram_.fill(QColor(192,192,192)); - +#endif + QPainter painter(&histogram_); painter.setPen(Qt::black); painter.setBrush(QColor(128,128,128)); @@ -389,6 +509,14 @@ if( !c3t3.is_in_complex(cit)) continue; +#ifdef CGAL_MESH_3_DEMO_DONT_COUNT_TETS_ADJACENT_TO_SHARP_FEATURES_FOR_HISTOGRAM + if (c3t3.in_dimension(cit->vertex(0)) <= 1 + || c3t3.in_dimension(cit->vertex(1)) <= 1 + || c3t3.in_dimension(cit->vertex(2)) <= 1 + || c3t3.in_dimension(cit->vertex(3)) <= 1) + continue; +#endif //CGAL_MESH_3_DEMO_DONT_COUNT_TETS_ADJACENT_TO_SHARP_FEATURES_FOR_HISTOGRAM + const Point_3& p0 = cit->vertex(0)->point(); const Point_3& p1 = cit->vertex(1)->point(); const Point_3& p2 = cit->vertex(2)->point(); @@ -436,7 +564,7 @@ if ( v < 5 ) { return Qt::red; } else if ( v < 10 ) { return QColor(215,108,0); } else if ( v < 15 ) { return QColor(138,139,0); } - else if ( v < 165 ) { return Qt::darkGreen; } + else if ( v < 165 ) { return QColor(60,136,64); } else if ( v < 170 ) { return QColor(138,139,1); } else if ( v < 175 ) { return QColor(215,108,0); } else /* 175 #include diff -Nru cgal-4.4/demo/Mesh_3/Scene_polygon_soup.cpp cgal-4.5/demo/Mesh_3/Scene_polygon_soup.cpp --- cgal-4.4/demo/Mesh_3/Scene_polygon_soup.cpp 2014-01-11 20:00:27.000000000 +0000 +++ cgal-4.5/demo/Mesh_3/Scene_polygon_soup.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -1,3 +1,5 @@ +#include "config.h" + #include "Scene_polygon_soup.h" #include diff -Nru cgal-4.4/demo/Mesh_3/Scene_polyhedron_item.cpp cgal-4.5/demo/Mesh_3/Scene_polyhedron_item.cpp --- cgal-4.4/demo/Mesh_3/Scene_polyhedron_item.cpp 2013-08-03 19:00:28.000000000 +0000 +++ cgal-4.5/demo/Mesh_3/Scene_polyhedron_item.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -1,3 +1,5 @@ +#include "config.h" + #include "Scene_polyhedron_item.h" #include "Polyhedron_type.h" #include diff -Nru cgal-4.4/demo/Mesh_3/Scene_segmented_image_item.cpp cgal-4.5/demo/Mesh_3/Scene_segmented_image_item.cpp --- cgal-4.4/demo/Mesh_3/Scene_segmented_image_item.cpp 2013-03-07 20:00:26.000000000 +0000 +++ cgal-4.5/demo/Mesh_3/Scene_segmented_image_item.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -1,3 +1,5 @@ +#include "config.h" + #ifdef SCENE_SEGMENTED_IMAGE_GL_BUFFERS_AVAILABLE # include #endif @@ -7,6 +9,7 @@ #include #include #include +#include //#define SCENE_SEGMENTED_IMAGE_GL_BUFFERS_AVAILABLE @@ -471,8 +474,11 @@ int display_scale) : m_image(im) , m_initialized(false) +#ifdef SCENE_SEGMENTED_IMAGE_GL_BUFFERS_AVAILABLE , m_voxel_scale(display_scale) +#endif // SCENE_SEGMENTED_IMAGE_GL_BUFFERS_AVAILABLE { + CGAL_USE(display_scale); #ifdef SCENE_SEGMENTED_IMAGE_GL_BUFFERS_AVAILABLE if(gl_vbo_available()) { ::glGenBuffers(3,m_vbo); diff -Nru cgal-4.4/demo/Mesh_3/Scene_segmented_image_item.h cgal-4.5/demo/Mesh_3/Scene_segmented_image_item.h --- cgal-4.4/demo/Mesh_3/Scene_segmented_image_item.h 2013-03-07 20:00:26.000000000 +0000 +++ cgal-4.5/demo/Mesh_3/Scene_segmented_image_item.h 2014-08-29 13:58:16.000000000 +0000 @@ -49,9 +49,11 @@ private: bool m_initialized; +#ifdef SCENE_SEGMENTED_IMAGE_GL_BUFFERS_AVAILABLE int m_voxel_scale; GLuint m_vbo[3]; GLuint m_ibo; +#endif // SCENE_SEGMENTED_IMAGE_GL_BUFFERS_AVAILABLE }; #endif // SCENE_SEGMENTED_IMAGE_ITEM_H diff -Nru cgal-4.4/demo/Mesh_3/StdAfx.cpp cgal-4.5/demo/Mesh_3/StdAfx.cpp --- cgal-4.4/demo/Mesh_3/StdAfx.cpp 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/demo/Mesh_3/StdAfx.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,2 @@ +// Build the precompiled headers. +#include "StdAfx.h" \ No newline at end of file diff -Nru cgal-4.4/demo/Mesh_3/StdAfx.h cgal-4.5/demo/Mesh_3/StdAfx.h --- cgal-4.4/demo/Mesh_3/StdAfx.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/demo/Mesh_3/StdAfx.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,346 @@ +#ifndef STDAFX_H +#define STDAFX_H + +#ifdef CGAL_CONCURRENT_MESH_3 + // In case some code uses CGAL_PROFILE, it needs to be concurrent + #define CGAL_CONCURRENT_PROFILE +#endif + +#include +#include +#include + +// STL +#include +#include +#include +#include +#include +#include +#include + +// Windows +#include + +// Boost +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Qt +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// QGLViewer +#include +#include +#include +#include +#include +#include +#include + +// CGAL +//#include +//#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include +//#include +#include +#include +//#include +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include +//#include +//#include +//#include +//#include +//#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +#include +#include +#include +#include + +// Mesh_3 +/*#include +#include +#include +#include +#include +#include +#include */ + +#endif //STDAFX_H \ No newline at end of file diff -Nru cgal-4.4/demo/Mesh_3/ui_files/MainWindow.ui cgal-4.5/demo/Mesh_3/ui_files/MainWindow.ui --- cgal-4.4/demo/Mesh_3/ui_files/MainWindow.ui 2012-11-13 13:13:57.000000000 +0000 +++ cgal-4.5/demo/Mesh_3/ui_files/MainWindow.ui 2014-08-29 13:58:16.000000000 +0000 @@ -14,7 +14,7 @@ CGAL 3D mesh generator demo - + :/cgal/icons/resources/cgal_logo.xpm:/cgal/icons/resources/cgal_logo.xpm @@ -128,7 +128,7 @@ + - + :/cgal/icons/plus:/cgal/icons/plus @@ -139,7 +139,7 @@ - - + :/cgal/icons/minus:/cgal/icons/minus @@ -150,7 +150,7 @@ ... - + :/cgal/icons/duplicate:/cgal/icons/duplicate @@ -315,7 +315,7 @@ - + :/cgal/icons/plus:/cgal/icons/plus @@ -327,7 +327,7 @@ - + :/cgal/icons/minus:/cgal/icons/minus @@ -339,7 +339,7 @@ - + :/cgal/icons/duplicate:/cgal/icons/duplicate @@ -465,6 +465,9 @@ Create a tetrahedral mesh + + Ctrl+M + @@ -503,21 +506,33 @@ ODT-smoothing + + Ctrl+O + Lloyd-smoothing + + Ctrl+Y + Sliver perturbation + + Ctrl+P + Sliver exudation + + Ctrl+E + @@ -539,11 +554,11 @@ Viewer QWidget -
CGAL_demo/Viewer.h
+
CGAL_demo/Viewer.h
- + diff -Nru cgal-4.4/demo/Mesh_3/ui_files/Meshing_dialog.ui cgal-4.5/demo/Mesh_3/ui_files/Meshing_dialog.ui --- cgal-4.4/demo/Mesh_3/ui_files/Meshing_dialog.ui 2012-11-13 13:13:57.000000000 +0000 +++ cgal-4.5/demo/Mesh_3/ui_files/Meshing_dialog.ui 2014-08-29 13:58:16.000000000 +0000 @@ -1,9 +1,18 @@ + Meshing_dialog true + + + 0 + 0 + 414 + 355 + + Meshing criteria @@ -30,6 +39,28 @@ + + + Qt::RightToLeft + + + Sharp features + + + + + + &Protect sharp edges + + + true + + + + + + + Qt::Vertical @@ -40,7 +71,7 @@ 20 - 10 + 0 @@ -90,7 +121,7 @@ - Facet max. size + &Facet max. size Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -129,7 +160,7 @@ - Facet min. angle (deg) + Facet min. &angle (deg) Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -175,22 +206,6 @@ - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 10 - - - - - Volume @@ -199,11 +214,14 @@ - Tetrahedron max. size + &Tetrahedron max. size Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + tetSizing + @@ -225,12 +243,15 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Lucida Grande'; font-size:13pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Tetrahedron shape <span style=" font-size:10pt; font-style:italic;">(radius-edge ratio)</span></p></body></html> +</style></head><body style=" font-family:'Sans Serif'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Lucida Grande';">Tetrahedron &amp;shape</span><span style=" font-family:'Lucida Grande'; font-size:13pt;"> </span><span style=" font-family:'Lucida Grande'; font-style:italic;">(radius-edge ratio)</span></p></body></html> Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + tetShape + @@ -279,22 +300,6 @@ - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 10 - - - - - Qt::Horizontal @@ -306,6 +311,19 @@ + + approx + noApprox + facetSizing + noFacetSizing + facetAngle + noAngle + tetSizing + noTetSizing + tetShape + noTetShape + buttonBox + @@ -315,8 +333,8 @@ accept() - 384 - 191 + 388 + 288 157 @@ -331,8 +349,8 @@ reject() - 384 - 191 + 388 + 288 286 diff -Nru cgal-4.4/demo/Mesh_3/Volume_plane_intersection.cpp cgal-4.5/demo/Mesh_3/Volume_plane_intersection.cpp --- cgal-4.4/demo/Mesh_3/Volume_plane_intersection.cpp 2012-11-13 13:13:57.000000000 +0000 +++ cgal-4.5/demo/Mesh_3/Volume_plane_intersection.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -1,3 +1,5 @@ +#include "config.h" + #include "Volume_plane_intersection.h" #include "Volume_plane_interface.h" diff -Nru cgal-4.4/demo/Mesh_3/Volume_planes_plugin.cpp cgal-4.5/demo/Mesh_3/Volume_planes_plugin.cpp --- cgal-4.4/demo/Mesh_3/Volume_planes_plugin.cpp 2012-11-13 13:13:57.000000000 +0000 +++ cgal-4.5/demo/Mesh_3/Volume_planes_plugin.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -1,3 +1,5 @@ +#include "config.h" + #include #include "Volume_plane.h" diff -Nru cgal-4.4/demo/Nef_2/nef_2.cpp cgal-4.5/demo/Nef_2/nef_2.cpp --- cgal-4.4/demo/Nef_2/nef_2.cpp 2012-11-13 13:13:58.000000000 +0000 +++ cgal-4.5/demo/Nef_2/nef_2.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -22,7 +22,7 @@ #if !defined CGAL_USE_GMP #include -int main(int, char*) +int main() { std::cout << "Sorry, this demo needs GMP..."; std::cout << std::endl; diff -Nru cgal-4.4/demo/Nef_3/visualization_SM.cpp cgal-4.5/demo/Nef_3/visualization_SM.cpp --- cgal-4.4/demo/Nef_3/visualization_SM.cpp 2012-11-13 13:13:58.000000000 +0000 +++ cgal-4.5/demo/Nef_3/visualization_SM.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -19,14 +19,14 @@ // Author(s) : Peter Hachenberger #include -#include +#include #include #include #include #include #include -typedef CGAL::Homogeneous Kernel; +typedef CGAL::Homogeneous Kernel; typedef CGAL::Nef_polyhedron_3 Nef_polyhedron_3; diff -Nru cgal-4.4/demo/Nef_3/visualization_SNC.cpp cgal-4.5/demo/Nef_3/visualization_SNC.cpp --- cgal-4.4/demo/Nef_3/visualization_SNC.cpp 2012-11-13 13:13:58.000000000 +0000 +++ cgal-4.5/demo/Nef_3/visualization_SNC.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -19,14 +19,14 @@ // Author(s) : Peter Hachenberger #include -#include +#include #include #include #include #include #include -typedef CGAL::Homogeneous Kernel; +typedef CGAL::Homogeneous Kernel; typedef CGAL::Nef_polyhedron_3 Nef_polyhedron_3; int main(int argc, char* argv[]) { diff -Nru cgal-4.4/demo/Nef_S2/nef_S2.cpp cgal-4.5/demo/Nef_S2/nef_S2.cpp --- cgal-4.4/demo/Nef_S2/nef_S2.cpp 2012-11-13 13:13:58.000000000 +0000 +++ cgal-4.5/demo/Nef_S2/nef_S2.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -20,14 +20,14 @@ #include -#include +#include #include #include #include #include #include -typedef CGAL::Gmpz RT; +typedef CGAL::Exact_integer RT; typedef CGAL::Homogeneous Kernel; typedef CGAL::Nef_polyhedron_S2 Nef_polyhedron_S2; diff -Nru cgal-4.4/demo/Periodic_Lloyd_3/MainWindow.cpp cgal-4.5/demo/Periodic_Lloyd_3/MainWindow.cpp --- cgal-4.4/demo/Periodic_Lloyd_3/MainWindow.cpp 2012-11-13 13:13:59.000000000 +0000 +++ cgal-4.5/demo/Periodic_Lloyd_3/MainWindow.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -1,5 +1,6 @@ #include "MainWindow.h" +#include MainWindow::MainWindow(QWidget* parent): CGAL::Qt::DemosMainWindow(parent) { diff -Nru cgal-4.4/demo/Polygon/CMakeLists.txt cgal-4.5/demo/Polygon/CMakeLists.txt --- cgal-4.4/demo/Polygon/CMakeLists.txt 2012-11-13 13:13:55.000000000 +0000 +++ cgal-4.5/demo/Polygon/CMakeLists.txt 2014-08-29 13:58:16.000000000 +0000 @@ -10,7 +10,7 @@ cmake_policy(VERSION 2.6) endif() -find_package(CGAL COMPONENTS Qt4 Core GMP MPFR) +find_package(CGAL COMPONENTS Qt4 Core) include(${CGAL_USE_FILE}) diff -Nru cgal-4.4/demo/Polyhedron/CGAL_demo/Scene_interface.h cgal-4.5/demo/Polyhedron/CGAL_demo/Scene_interface.h --- cgal-4.4/demo/Polyhedron/CGAL_demo/Scene_interface.h 2013-09-07 19:00:31.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/CGAL_demo/Scene_interface.h 2014-08-29 13:58:17.000000000 +0000 @@ -12,6 +12,7 @@ // OpenGL rendering mode enum RenderingMode { Points = 0, PointsPlusNormals, + Splatting, Wireframe, Flat, FlatPlusEdges, @@ -87,6 +88,7 @@ // Accessors (getters) virtual int numberOfEntries() const = 0; virtual Scene_item* item(Item_id) const = 0; + virtual Item_id item_id(Scene_item*) const = 0; virtual Item_id mainSelectionIndex() const = 0; virtual QList selectionIndices() const = 0; virtual Item_id selectionAindex() const = 0; diff -Nru cgal-4.4/demo/Polyhedron/CMakeLists.txt cgal-4.5/demo/Polyhedron/CMakeLists.txt --- cgal-4.4/demo/Polyhedron/CMakeLists.txt 2014-01-11 20:00:27.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/CMakeLists.txt 2014-08-29 13:58:17.000000000 +0000 @@ -9,6 +9,13 @@ cmake_policy(VERSION 2.6) endif() +# Compatibility with CMake 3.0 +if(POLICY CMP0042) + # Do not enable the use of MACOSX_RPATH + # http://www.cmake.org/cmake/help/v3.0/policy/CMP0042.html + cmake_policy(SET CMP0042 OLD) +endif() + #option(POLYHEDRON_DEMO_ENABLE_FORWARD_DECL "In the Polyhedron demo, enable " OFF) #mark_as_advanced(POLYHEDRON_DEMO_ENABLE_FORWARD_DECL) @@ -49,6 +56,10 @@ endif() find_package(Qt4) +# Find Glew (optional), for splatting +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/GlSplat/cmake) +find_package(GLEW) + # Find OpenGL find_package(OpenGL) @@ -59,26 +70,17 @@ find_package(QGLViewer ) endif(QT4_FOUND) +if(GLEW_FOUND) + include_directories ( ${GLEW_INCLUDE_DIR} ) + add_definitions(-DCGAL_GLEW_ENABLED) +else(GLEW_FOUND) + message(STATUS "NOTICE: GLEW library is not found. Splat rendering will not be available.") +endif(GLEW_FOUND) - -# Eigen is now used by default find_package(Eigen3 3.1.0) #(requires 3.1.0 or greater) -if (NOT EIGEN3_FOUND) - # Find LAPACK (optional), for curvatures estimation - find_package(LAPACK) - if(LAPACK_FOUND) - include( ${LAPACK_USE_FILE} ) - endif(LAPACK_FOUND) - - # Find TAUCS (optionnal), for parametrization - find_package(TAUCS) - if(TAUCS_FOUND) - include( ${TAUCS_USE_FILE} ) - endif(TAUCS_FOUND) -else() +if (EIGEN3_FOUND) include( ${EIGEN3_USE_FILE} ) -endif() - +endif(EIGEN3_FOUND) if(CGAL_Qt4_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND) @@ -87,26 +89,17 @@ include_directories ( ${QGLVIEWER_INCLUDE_DIR} ) - # Parameterization needs Eigen3 or TAUCS - if(NOT EIGEN3_FOUND AND NOT TAUCS_FOUND) - message(STATUS "NOTICE: Eigen 3.1 (or greater) and TAUCS is not found. parametrization will not be available.") - endif(NOT EIGEN3_FOUND AND NOT TAUCS_FOUND) - - # Curvature estimation needs Eigen3 or LAPACK - if(NOT EIGEN3_FOUND AND NOT LAPACK_FOUND) - message(STATUS "NOTICE: Eigen 3.1 (or greater) and LAPACK is not found. curvatures estimation will not be available.") - endif(NOT EIGEN3_FOUND AND NOT LAPACK_FOUND) - qt4_wrap_ui( MainWindowUI_files MainWindow.ui ) qt4_wrap_ui( FileLoaderDialogUI_files FileLoaderDialog.ui ) qt4_wrap_ui( Show_point_dialogUI_FILES Show_point_dialog.ui ) qt4_wrap_ui( remeshingUI_FILES Remeshing_dialog.ui) - qt4_wrap_ui( meshingUI_FILES Meshing_dialog.ui Meshing_pause_widget.ui ) + qt4_wrap_ui( meshingUI_FILES Meshing_dialog.ui ) qt4_wrap_ui( cameraUI_FILES Camera_positions_list.ui ) qt4_wrap_ui( PreferencesUI_FILES Preferences.ui ) qt4_wrap_ui( point_inside_polyhedronUI_FILES Point_inside_polyhedron_widget.ui) qt4_wrap_ui( polyhedron_slicerUI_FILES Polyhedron_slicer_widget.ui) qt4_wrap_ui( segmentationUI_FILES Mesh_segmentation_widget.ui) + qt4_wrap_ui( selectionUI_FILES Selection_widget.ui) qt4_wrap_ui( funcUI_FILES Function_dialog.ui ) qt4_generate_moc( "MainWindow.h" "${CMAKE_CURRENT_BINARY_DIR}/MainWindow_moc.cpp" ) @@ -131,7 +124,6 @@ Scene_polyhedron_item.cpp Scene_polyhedron_transform_item.cpp Scene_polylines_item.cpp - Scene_edit_polyhedron_item.cpp Scene_textured_polyhedron_item.cpp Scene_c2t3_item.cpp Scene_nef_polyhedron_item.cpp @@ -139,6 +131,9 @@ Mesher_base.cpp Camera_positions_list.cpp Scene_points_with_normal_item.cpp + Scene_polyhedron_item_decorator.cpp + Scene_polyhedron_selection_item.cpp + Scene_polyhedron_item_k_ring_selection.cpp ) qt4_automoc( Scene_implicit_function_item.cpp ) @@ -189,19 +184,31 @@ # special target_link_libraries(scene_polyhedron_transform_item scene_polyhedron_item) + if(GLEW_FOUND) + qt4_add_resources(gl_splat_rc GlSplat/glsplat.qrc) + add_library(gl_splat SHARED + GlSplat/GlSplat.cpp GlSplat/Shader.cpp ${gl_splat_rc}) + target_link_libraries(gl_splat ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTOPENGL_LIBRARY} ${GLEW_LIBRARIES}) + endif(GLEW_FOUND) + add_item(scene_combinatorial_map_item Scene_combinatorial_map_item.cpp Scene_combinatorial_map_item.moc) # special target_link_libraries(scene_combinatorial_map_item scene_polyhedron_item) add_item(scene_polylines_item Scene_polylines_item.cpp Scene_polylines_item.moc) - add_item(scene_edit_polyhedron_item Scene_edit_polyhedron_item.cpp Scene_edit_polyhedron_item.moc) - # special - target_link_libraries(scene_edit_polyhedron_item scene_polyhedron_item) - - if(EIGEN3_FOUND OR TAUCS_FOUND) + add_item(scene_polyhedron_item_decorator Scene_polyhedron_item_decorator.cpp Scene_polyhedron_item_decorator.moc) + target_link_libraries(scene_polyhedron_item_decorator scene_polyhedron_item) + + add_item(scene_polyhedron_item_k_ring_selection Scene_polyhedron_item_k_ring_selection.cpp Scene_polyhedron_item_k_ring_selection.moc) + target_link_libraries(scene_polyhedron_item_k_ring_selection scene_polyhedron_item) + + add_item(scene_polyhedron_selection_item Scene_polyhedron_selection_item.cpp Scene_polyhedron_selection_item.moc) + target_link_libraries(scene_polyhedron_selection_item scene_polyhedron_item_decorator scene_polyhedron_item_k_ring_selection) + + if(EIGEN3_FOUND ) add_item(scene_textured_polyhedron_item Scene_textured_polyhedron_item.cpp texture.cpp Scene_textured_polyhedron_item.moc) - endif(EIGEN3_FOUND OR TAUCS_FOUND) + endif() add_item(scene_implicit_function_item Scene_implicit_function_item.cpp Scene_implicit_function_item.moc Color_ramp.cpp) @@ -211,6 +218,10 @@ Scene_nef_rendering.cpp) target_link_libraries(scene_nef_polyhedron_item scene_polyhedron_item) add_item(scene_points_with_normal_item Scene_points_with_normal_item.cpp Scene_points_with_normal_item.moc) + if(GLEW_FOUND) + target_link_libraries( scene_points_with_normal_item gl_splat ${GLEW_LIBRARIES} ) + target_link_libraries( demo_framework gl_splat ${GLEW_LIBRARIES} ) + endif(GLEW_FOUND) foreach( lib demo_framework @@ -234,7 +245,7 @@ # Viewer_moc.cpp ${FileLoaderDialogUI_files} ${MainWindowUI_files} ${PreferencesUI_FILES} ${RESOURCE_FILES} ) add_to_cached_list( CGAL_EXECUTABLE_TARGETS Polyhedron_3 ) - if(EIGEN3_FOUND OR TAUCS_FOUND) + if(EIGEN3_FOUND) # add_executable( Polyhedron_3 Scene_tex_rendering.cpp Scene_tex_polyhedron_operations.cpp ) endif() # else(POLYHEDRON_DEMO_ENABLE_FORWARD_DECL) @@ -255,6 +266,10 @@ target_link_libraries( Polyhedron_3 demo_framework ) target_link_libraries( Polyhedron_3 point_dialog ) + if(GLEW_FOUND) + target_link_libraries( Polyhedron_3 gl_splat ${GLEW_LIBRARIES} ) + endif(GLEW_FOUND) + # Link with CGAL target_link_libraries( Polyhedron_3 ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES} ) @@ -284,7 +299,8 @@ qt4_generate_moc( "Polyhedron_demo_mesh_3_plugin_cgal_code.cpp" "${CMAKE_CURRENT_BINARY_DIR}/Scene_c3t3_item.moc" ) polyhedron_demo_plugin(mesh_3_plugin Polyhedron_demo_mesh_3_plugin - Polyhedron_demo_mesh_3_plugin_cgal_code.cpp Scene_c3t3_item.moc) + Polyhedron_demo_mesh_3_plugin_cgal_code.cpp Scene_c3t3_item.moc + ${meshingUI_FILES}) target_link_libraries(mesh_3_plugin scene_polyhedron_item ${QGLVIEWER_LIBRARIES} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY}) else( Boost_VERSION GREATER 103400 ) message(STATUS "warning: the plugin mesh_3_plugin requires Boost>=1.34.1 and will not be compiled.") @@ -313,6 +329,9 @@ polyhedron_demo_plugin(xyz_plugin Polyhedron_demo_xyz_plugin) target_link_libraries(xyz_plugin scene_points_with_normal_item) + + polyhedron_demo_plugin(selection_io_plugin Polyhedron_demo_selection_io_plugin) + target_link_libraries(selection_io_plugin scene_polyhedron_selection_item) polyhedron_demo_plugin(orient_soup_plugin Polyhedron_demo_orient_soup_plugin) target_link_libraries(orient_soup_plugin scene_polygon_soup_item scene_polyhedron_item) @@ -327,7 +346,7 @@ target_link_libraries(off_to_xyz_plugin scene_points_with_normal_item) polyhedron_demo_plugin(convex_hull_plugin Polyhedron_demo_convex_hull_plugin) - target_link_libraries(convex_hull_plugin scene_polyhedron_item scene_points_with_normal_item scene_polylines_item) + target_link_libraries(convex_hull_plugin scene_polyhedron_item scene_points_with_normal_item scene_polylines_item scene_polyhedron_selection_item) polyhedron_demo_plugin(kernel_plugin Polyhedron_demo_kernel_plugin) target_link_libraries(kernel_plugin scene_polyhedron_item) @@ -335,28 +354,14 @@ polyhedron_demo_plugin(pca_plugin Polyhedron_demo_pca_plugin) target_link_libraries(pca_plugin scene_polyhedron_item scene_basic_objects) - if(EIGEN3_FOUND OR TAUCS_FOUND) + if(EIGEN3_FOUND) polyhedron_demo_plugin(parameterization_plugin Polyhedron_demo_parameterization_plugin) target_link_libraries(parameterization_plugin scene_polyhedron_item scene_textured_polyhedron_item ) - else(EIGEN3_FOUND OR TAUCS_FOUND) - message(STATUS "NOTICE: Neither TAUCS nor Eigen 3.1 (or greater) libraries have been found. Parameterization will not be available.") - endif(EIGEN3_FOUND OR TAUCS_FOUND) - - if(TAUCS_FOUND OR EIGEN3_FOUND) + qt4_wrap_ui( poissonUI_FILES Polyhedron_demo_poisson_plugin.ui) polyhedron_demo_plugin(poisson_plugin Polyhedron_demo_poisson_plugin Polyhedron_demo_poisson_plugin_impl.cpp ${poissonUI_FILES}) target_link_libraries(poisson_plugin scene_polyhedron_item scene_points_with_normal_item) - else(TAUCS_FOUND OR EIGEN3_FOUND) - message(STATUS "NOTICE: Neither TAUCS nor Eigen 3.1 (or greater) libraries have been found. Poisson reconstruction will not be available.") - endif(TAUCS_FOUND OR EIGEN3_FOUND) - - - # Link with BLAS and LAPACK only (optional), for Jet Fitting - if (NOT EIGEN3_FOUND AND LAPACK_FOUND) - include( ${LAPACK_USE_FILE} ) - endif() - - if(EIGEN3_FOUND OR LAPACK_FOUND) + qt4_wrap_ui( normal_estimationUI_FILES Polyhedron_demo_normal_estimation_plugin.ui) polyhedron_demo_plugin(normal_estimation_plugin Polyhedron_demo_normal_estimation_plugin ${normal_estimationUI_FILES}) target_link_libraries(normal_estimation_plugin scene_points_with_normal_item) @@ -369,10 +374,14 @@ polyhedron_demo_plugin(jet_fitting_plugin Polyhedron_demo_jet_fitting_plugin) target_link_libraries(jet_fitting_plugin scene_polyhedron_item scene_polylines_item) - - else(EIGEN3_FOUND OR LAPACK_FOUND) - message(STATUS "NOTICE: Nor Eigen 3.1 (or greater) nor LAPACK library were found. Normal estimation and smoothing will not be available.") - endif(EIGEN3_FOUND OR LAPACK_FOUND) + else(EIGEN3_FOUND) + message(STATUS "NOTICE: Eigen 3.1 (or greater) was not found. Parameterization plugin will not be available.") + message(STATUS "NOTICE: Eigen 3.1 (or greater) was not found. Poisson reconstruction plugin will not be available.") + message(STATUS "NOTICE: Eigen 3.1 (or greater) was not found. Normal estimation plugin will not be available.") + message(STATUS "NOTICE: Eigen 3.1 (or greater) was not found. Smoothing plugin will not be available.") + message(STATUS "NOTICE: Eigen 3.1 (or greater) was not found. Average spacing plugin will not be available.") + message(STATUS "NOTICE: Eigen 3.1 (or greater) was not found. Jet fitting plugin will not be available.") + endif(EIGEN3_FOUND) polyhedron_demo_plugin(self_intersection_plugin Polyhedron_demo_self_intersection_plugin) target_link_libraries(self_intersection_plugin scene_polyhedron_item) @@ -380,6 +389,9 @@ polyhedron_demo_plugin(polyhedron_stitching_plugin Polyhedron_demo_polyhedron_stitching_plugin) target_link_libraries(polyhedron_stitching_plugin scene_polyhedron_item scene_polylines_item) + polyhedron_demo_plugin(join_and_split_polyhedra_plugin Polyhedron_demo_join_and_split_polyhedra_plugin) + target_link_libraries(join_and_split_polyhedra_plugin scene_polyhedron_item) + polyhedron_demo_plugin(subdivision_methods_plugin Polyhedron_demo_subdivision_methods_plugin) target_link_libraries(subdivision_methods_plugin scene_polyhedron_item) @@ -406,9 +418,20 @@ polyhedron_demo_plugin(trivial_plugin Polyhedron_demo_trivial_plugin) - polyhedron_demo_plugin(edit_polyhedron_plugin Polyhedron_demo_edit_polyhedron_plugin) - target_link_libraries(edit_polyhedron_plugin scene_polyhedron_item scene_edit_polyhedron_item) + # Edit polyhedron scene item and plugin + if ( EIGEN3_FOUND AND "${EIGEN3_VERSION}" VERSION_GREATER "3.1.90" ) + qt4_wrap_ui( editionUI_FILES Deform_mesh.ui ) + qt4_automoc( Scene_edit_polyhedron_item.cpp ) + add_item(scene_edit_polyhedron_item Scene_edit_polyhedron_item.cpp Scene_edit_polyhedron_item.moc ${editionUI_FILES}) + target_link_libraries(scene_edit_polyhedron_item scene_polyhedron_item scene_polyhedron_item_k_ring_selection) + + polyhedron_demo_plugin(edit_polyhedron_plugin Polyhedron_demo_edit_polyhedron_plugin ${editionUI_FILES}) + target_link_libraries(edit_polyhedron_plugin scene_polyhedron_item scene_edit_polyhedron_item) + else() + message(STATUS "NOTICE: The polyhedron edit plugin require Eigen 3.2 (or higher) and will not be available.") + endif() + polyhedron_demo_plugin(cut_plugin Polyhedron_demo_cut_plugin) target_link_libraries(cut_plugin scene_polyhedron_item scene_basic_objects) @@ -423,11 +446,14 @@ polyhedron_demo_plugin(point_set_outliers_removal_plugin Polyhedron_demo_point_set_outliers_removal_plugin ${ps_outliers_removal_UI_FILES}) target_link_libraries(point_set_outliers_removal_plugin scene_points_with_normal_item) + polyhedron_demo_plugin(selection_plugin Polyhedron_demo_selection_plugin ${selectionUI_FILES}) + target_link_libraries(selection_plugin scene_polyhedron_selection_item scene_points_with_normal_item) # # Exporting # if(TARGET CGAL_Qt4) export(TARGETS CGAL_Qt4 FILE polyhedron_demo_targets.cmake NAMESPACE Polyhedron_) + export(TARGETS CGAL CGAL_Qt4 FILE polyhedron_demo_targets.cmake NAMESPACE Polyhedron_) else() export(TARGETS FILE polyhedron_demo_targets.cmake) endif() @@ -441,6 +467,14 @@ NAMESPACE Polyhedron_ APPEND FILE polyhedron_demo_targets.cmake) + if(GLEW_FOUND) + export( + TARGETS + gl_splat + NAMESPACE Polyhedron_ + APPEND FILE polyhedron_demo_targets.cmake) + endif(GLEW_FOUND) + configure_file(CGAL_polyhedron_demoConfig.cmake.in CGAL_polyhedron_demoConfig.cmake) else (CGAL_Qt4_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND) diff -Nru cgal-4.4/demo/Polyhedron/data/negative.off cgal-4.5/demo/Polyhedron/data/negative.off --- cgal-4.4/demo/Polyhedron/data/negative.off 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/data/negative.off 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,15 @@ +OFF +7 6 0 +-215.983 70.3187 137.883 +-216.952 39.6826 144.676 +-207.932 -24.8993 148.723 +-247.708 69.538 123.733 +-246.196 45.203 131.288 +-246.937 14.9498 134.175 +-255.988 45.6255 130.774 +3 3 4 0 +3 1 0 4 +3 5 2 4 +3 1 4 2 +3 4 3 6 +3 4 6 5 diff -Nru cgal-4.4/demo/Polyhedron/Deform_mesh.ui cgal-4.5/demo/Polyhedron/Deform_mesh.ui --- cgal-4.4/demo/Polyhedron/Deform_mesh.ui 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Deform_mesh.ui 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,353 @@ + + + DeformMesh + + + + 0 + 0 + 357 + 491 + + + + Surface Mesh Deformation + + + + + + + Selection + + + + + + + + + + + + Brush Size ROI: + + + + + + + Control Vertices Brush Size: + + + + + + + + + + + + + + + + + + + + + + + + + Set All Vertices as ROI + + + + + + + Clear ROI + + + + + + + + + + + + Use Shift + Left Click to paint ROI vertices + + + ROI + + + true + + + + + + + Use Shift + Left Click to paint control vertices + + + Control vertices + + + + + + + + + + + + + Insertion + + + true + + + + + + + Removal + + + + + + + + + + + + + + + + + + + + + + + Isolated Component Size: + + + + + + + 999999999 + + + 8 + + + + + + + Get Minimum + + + + + + + + + Select Isolated Components Below Threshold + + + + + + + + + + + + Group of Control Vertices Navigation + + + + + + + + + 0 + 0 + + + + << + + + + + + + >> + + + + + + + + + + + Create new + + + + + + + Delete + + + + + + + + + Activate Pivoting + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + Update Original Positions + + + + + + + + + Qt::Horizontal + + + + + + + + + Show ROI + + + true + + + + + + + Show As Sphere + + + false + + + + + + + + + + + Save ROI / Control Vertices + + + + + + + Load ROI / Control Vertices + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + Apply and Close + + + + + + + + + + + diff -Nru cgal-4.4/demo/Polyhedron/GlSplat/cmake/FindGLEW.cmake cgal-4.5/demo/Polyhedron/GlSplat/cmake/FindGLEW.cmake --- cgal-4.4/demo/Polyhedron/GlSplat/cmake/FindGLEW.cmake 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/GlSplat/cmake/FindGLEW.cmake 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,105 @@ +# Copyright (c) 2009 Boudewijn Rempt +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. +# +# - try to find glew library and include files +# GLEW_INCLUDE_DIR, where to find GL/glew.h, etc. +# GLEW_LIBRARIES, the libraries to link against +# GLEW_FOUND, If false, do not try to use GLEW. +# Also defined, but not for general use are: +# GLEW_GLEW_LIBRARY = the full path to the glew library. + +IF (WIN32) + + IF(CYGWIN) + + FIND_PATH( GLEW_INCLUDE_DIR GL/glew.h) + + FIND_LIBRARY( GLEW_GLEW_LIBRARY glew32 + ${OPENGL_LIBRARY_DIR} + /usr/lib/w32api + /usr/X11R6/lib + ) + + + ELSE(CYGWIN) + + FIND_PATH( GLEW_INCLUDE_DIR GL/glew.h + $ENV{GLEW_ROOT_PATH}/include + ) + + FIND_LIBRARY( GLEW_GLEW_LIBRARY + NAMES glew glew32 + PATHS + $ENV{GLEW_ROOT_PATH}/lib + ${OPENGL_LIBRARY_DIR} + ) + + ENDIF(CYGWIN) + +ELSE (WIN32) + + IF (APPLE) +# These values for Apple could probably do with improvement. + FIND_PATH( GLEW_INCLUDE_DIR glew.h + /System/Library/Frameworks/GLEW.framework/Versions/A/Headers + ${OPENGL_LIBRARY_DIR} + ) + SET(GLEW_GLEW_LIBRARY "-framework GLEW" CACHE STRING "GLEW library for OSX") + SET(GLEW_cocoa_LIBRARY "-framework Cocoa" CACHE STRING "Cocoa framework for OSX") + ELSE (APPLE) + + FIND_PATH( GLEW_INCLUDE_DIR GL/glew.h + /usr/include/GL + /usr/openwin/share/include + /usr/openwin/include + /usr/X11R6/include + /usr/include/X11 + /opt/graphics/OpenGL/include + /opt/graphics/OpenGL/contrib/libglew + ) + + FIND_LIBRARY( GLEW_GLEW_LIBRARY GLEW + /usr/openwin/lib + /usr/X11R6/lib + ) + + ENDIF (APPLE) + +ENDIF (WIN32) + +SET( GLEW_FOUND "NO" ) +IF(GLEW_INCLUDE_DIR) + IF(GLEW_GLEW_LIBRARY) + # Is -lXi and -lXmu required on all platforms that have it? + # If not, we need some way to figure out what platform we are on. + SET( GLEW_LIBRARIES + ${GLEW_GLEW_LIBRARY} + ${GLEW_cocoa_LIBRARY} + ) + SET( GLEW_FOUND "YES" ) + +#The following deprecated settings are for backwards compatibility with CMake1.4 + SET (GLEW_LIBRARY ${GLEW_LIBRARIES}) + SET (GLEW_INCLUDE_PATH ${GLEW_INCLUDE_DIR}) + + ENDIF(GLEW_GLEW_LIBRARY) +ENDIF(GLEW_INCLUDE_DIR) + +IF(GLEW_FOUND) + IF(NOT GLEW_FIND_QUIETLY) + MESSAGE(STATUS "Found Glew: ${GLEW_LIBRARIES}") + ENDIF(NOT GLEW_FIND_QUIETLY) +ELSE(GLEW_FOUND) + IF(GLEW_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find Glew") + ENDIF(GLEW_FIND_REQUIRED) +ENDIF(GLEW_FOUND) + +MARK_AS_ADVANCED( + GLEW_INCLUDE_DIR + GLEW_GLEW_LIBRARY + GLEW_Xmu_LIBRARY + GLEW_Xi_LIBRARY +) diff -Nru cgal-4.4/demo/Polyhedron/GlSplat/cmake/FindQGLViewer.cmake cgal-4.5/demo/Polyhedron/GlSplat/cmake/FindQGLViewer.cmake --- cgal-4.4/demo/Polyhedron/GlSplat/cmake/FindQGLViewer.cmake 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/GlSplat/cmake/FindQGLViewer.cmake 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,20 @@ + +if (QGLViewer_INCLUDES AND QGLViewer_LIBRARIES) + set(QGLViewer_FIND_QUIETLY TRUE) +endif (QGLViewer_INCLUDES AND QGLViewer_LIBRARIES) + +find_path(QGLViewer_INCLUDES + NAMES + QGLViewer/qglviewer.h + PATHS + $ENV{QGLViewerDIR} + ${INCLUDE_INSTALL_DIR} +) + +find_library(QGLViewer_LIBRARIES QGLViewer PATHS $ENV{QGLVIEWER_DIR} ${LIB_INSTALL_DIR}) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(QGLViewer DEFAULT_MSG + QGLViewer_INCLUDES QGLViewer_LIBRARIES) + +mark_as_advanced(QGLViewer_INCLUDES QGLViewer_LIBRARIES) diff -Nru cgal-4.4/demo/Polyhedron/GlSplat/CMakeLists.txt cgal-4.5/demo/Polyhedron/GlSplat/CMakeLists.txt --- cgal-4.4/demo/Polyhedron/GlSplat/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/GlSplat/CMakeLists.txt 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,35 @@ + +project(GlSplat) + +cmake_minimum_required(VERSION 2.6.0) +if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}" VERSION_GREATER 2.8.3) + cmake_policy(VERSION 2.8.4) +else() + cmake_policy(VERSION 2.6) +endif() +set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) + +find_package(Qt4 REQUIRED) +find_package(GLEW REQUIRED) + +set(QT_USE_QTOPENGL TRUE) +set(QT_USE_QTXML TRUE) +include(${QT_USE_FILE}) +include_directories( ${QT_QTOPENGL_INCLUDE_DIR} ${QT_QTXML_INCLUDE_DIR} ${GLEW_INCLUDE_DIR}) + +set(srcs Shader.cpp GlSplat.cpp) + +qt4_automoc( ${srcs}) +qt4_add_resources(srcs glsplat.qrc) + +add_library(GlSplat SHARED ${srcs}) +target_link_libraries(GlSplat ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTOPENGL_LIBRARY} ${GLEW_LIBRARIES}) + +find_package(QGLViewer) +if(QGLVIEWER_FOUND) + include_directories( ${QGLViewer_INCLUDES}) + add_executable(demo demo.cpp) + target_link_libraries(demo ${QT_QTXML_LIBRARY} ${QGLViewer_LIBRARIES} GlSplat) +else() + message("QGLViewer not found, demo won't be built") +endif() diff -Nru cgal-4.4/demo/Polyhedron/GlSplat/demo.cpp cgal-4.5/demo/Polyhedron/GlSplat/demo.cpp --- cgal-4.4/demo/Polyhedron/GlSplat/demo.cpp 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/GlSplat/demo.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,131 @@ +// This file is part of GlSplat, a simple splatting C++ library +// +// Copyright (C) 2008-2009 Gael Guennebaud +// +// GlSplat is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// GlSplat is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GlSplat. If not, see . + +#include "GlSplat.h" +#include + +class Viewer : public QGLViewer +{ +protected : + virtual void draw(); + virtual void init(); + virtual QString helpString() const; + + virtual void drawpoints(); + GlSplat::SplatRenderer mRenderer; + std::vector mNormals; + std::vector mPositions; + std::vector mRadii; + std::vector mColors; + int mNbPoints; +}; + +void Viewer::draw() +{ + mRenderer.beginVisibilityPass(); + drawpoints(); + mRenderer.beginAttributePass(); + drawpoints(); + mRenderer.finalize(); +} + +void Viewer::drawpoints() +{ + glBegin(GL_POINTS); + for (int i=0; iS i m p l e V i e w e r"); + text += "Use the mouse to move the camera around the object. "; + text += "You can respectively revolve around, zoom and translate with the three mouse buttons. "; + text += "Left and middle buttons pressed together rotate around the camera view direction axis

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

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

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

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

"; + text += "Press Escape to exit the viewer."; + return text; +} + + +#include + +int main(int argc, char** argv) +{ + // Read command lines arguments. + QApplication application(argc,argv); + + // Instantiate the viewer. + Viewer viewer; + + viewer.setWindowTitle("simpleViewer"); + + // Make the viewer window visible on screen. + viewer.show(); + + // Run main loop. + return application.exec(); +} + diff -Nru cgal-4.4/demo/Polyhedron/GlSplat/GlSplat_config.h cgal-4.5/demo/Polyhedron/GlSplat/GlSplat_config.h --- cgal-4.4/demo/Polyhedron/GlSplat/GlSplat_config.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/GlSplat/GlSplat_config.h 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,12 @@ +#ifndef GLSPLAT_CONFIG_H +#define GLSPLAT_CONFIG_H + +#include + +#ifdef gl_splat_EXPORTS + #define GLSPLAT_EXPORT CGAL_DLL_EXPORT +#else + #define GLSPLAT_EXPORT CGAL_DLL_IMPORT +#endif + +#endif // GLSPLAT_CONFIG_H diff -Nru cgal-4.4/demo/Polyhedron/GlSplat/GlSplat.cpp cgal-4.5/demo/Polyhedron/GlSplat/GlSplat.cpp --- cgal-4.4/demo/Polyhedron/GlSplat/GlSplat.cpp 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/GlSplat/GlSplat.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,514 @@ +// This file is part of GlSplat, a simple splatting C++ library +// +// Copyright (C) 2008-2009 Gael Guennebaud +// +// GlSplat is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// GlSplat is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GlSplat. If not, see . + +#include + +#include +#include +#include +#include + +#include "GlSplat.h" +#include "Shader.h" + +#include +#include +#include + + +namespace GlSplat { + +SplatRenderer::SplatRenderer() +{ + mNormalTextureID = 0; + mDepthTextureID = 0; + mIsSupported = false; + mRenderBuffer = 0; + mWorkaroundATI = false; + mBuggedAtiBlending = false; + mDummyTexId = 0; + mIsInitialized = false; + + mFlags = DEFERRED_SHADING_BIT | DEPTH_CORRECTION_BIT | FLOAT_BUFFER_BIT | OUTPUT_DEPTH_BIT; + mCachedFlags = ~mFlags; + // union of bits which controls the render buffer + mRenderBufferMask = DEFERRED_SHADING_BIT | FLOAT_BUFFER_BIT; +} + +QString SplatRenderer::loadSource(const QString& func,const QString& filename) +{ + QString res; + QFile f(":/SplatRenderer/shaders/" + filename); + if (!f.open(QFile::ReadOnly)) + { + std::cerr << "failed to load shader file " << filename.toAscii().data() << "\n"; + return res; + } + else qDebug("Succesfully loaded shader func '%s' in file '%s'",qPrintable(func),qPrintable(filename)); + QTextStream stream(&f); + res = stream.readAll(); + f.close(); + res = QString("#define GLSPLAT__%1__ 1\n").arg(func) + + QString("#define %1 main\n").arg(func) + + res; + return res; +} + +void SplatRenderer::configureShaders() +{ + // const char* passNames[3] = {"Visibility","Attribute","Finalization"}; + QString defines = ""; + if (mFlags & DEFERRED_SHADING_BIT) + defines += "#define ES_DEFERRED_SHADING\n"; + if (mFlags & DEPTH_CORRECTION_BIT) + defines += "#define ES_DEPTH_CORRECTION\n"; + if (mFlags & OUTPUT_DEPTH_BIT) + defines += "#define ES_OUTPUT_DEPTH 1\n"; + if (mFlags & BACKFACE_SHADING_BIT) + defines += "#define ES_BACKFACE_SHADING\n"; + if (mWorkaroundATI) + defines += "#define ES_ATI_WORKAROUND\n"; + + QString shading = +"vec4 meshlabLighting(vec4 color, vec3 eyePos, vec3 normal)" +"{" +" normal = normalize(normal);" +" vec3 lightVec = normalize(gl_LightSource[0].position.xyz);" +" vec3 halfVec = normalize( lightVec - normalize(eyePos) );" +" float aux_dot = dot(normal,lightVec);" +" float diffuseCoeff = clamp(aux_dot, 0.0, 1.0);" +" float specularCoeff = aux_dot>0.0 ? clamp(pow(clamp(dot(halfVec, normal),0.0,1.0),gl_FrontMaterial.shininess), 0.0, 1.0) : 0.0;" +" return vec4(color.rgb * ( gl_FrontLightProduct[0].ambient.rgb + diffuseCoeff * gl_FrontLightProduct[0].diffuse.rgb) + specularCoeff * gl_FrontLightProduct[0].specular.rgb, 1.0);" +"}\n"; + + for (int k=0;k<3;++k) + { + QString vsrc = shading + defines + mShaderSrcs[k*2+0]; + QString fsrc = shading + defines + mShaderSrcs[k*2+1]; + if(!mShaders[k].loadSources(mShaderSrcs[k*2+0]!="" ? vsrc.toAscii().data() : 0, + mShaderSrcs[k*2+1]!="" ? fsrc.toAscii().data() : 0/*, + Shader::Warnings*/)) + mIsSupported = false; + } +} + +void SplatRenderer::init(QGLWidget *qglw) +{ + mIsSupported = true; + if(qglw) + qglw->makeCurrent(); + glewInit(); + + const char* rs = (const char*)glGetString(GL_RENDERER); + QString rendererString(""); + if(rs) + rendererString = QString(rs); + mWorkaroundATI = rendererString.startsWith("ATI") || rendererString.startsWith("AMD"); + // FIXME: maybe some recent HW correctly supports floating point blending... + mBuggedAtiBlending = rendererString.startsWith("ATI") || rendererString.startsWith("AMD"); + + if (mWorkaroundATI && mDummyTexId==0) + { + glActiveTexture(GL_TEXTURE0); + glGenTextures(1,&mDummyTexId); + glBindTexture(GL_TEXTURE_2D, mDummyTexId); + glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 4, 4, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0); + } + + // let's check the GPU capabilities + mSupportedMask = DEPTH_CORRECTION_BIT | BACKFACE_SHADING_BIT; + if (!QGLFramebufferObject::hasOpenGLFramebufferObjects ()) + { + std::cout << "SplatRenderer: error OpenGL frame buffer objects are not supported. (please, try to update your drivers)\n"; + mIsSupported = false; + return; + } + if (GLEW_ARB_texture_float) + mSupportedMask |= FLOAT_BUFFER_BIT; + else + std::cout << "SplatRenderer: warning floating point textures are not supported.\n"; + + if (GLEW_ARB_draw_buffers && (!mBuggedAtiBlending)) + mSupportedMask |= DEFERRED_SHADING_BIT; + else + std::cout << "SplatRenderer: warning deferred shading is not supported.\n"; + + if (GLEW_ARB_shadow) + mSupportedMask |= OUTPUT_DEPTH_BIT; + else + std::cerr << "SplatRenderer: warning copy of the depth buffer is not supported.\n"; + + mFlags = mFlags & mSupportedMask; + + // load shader source + mShaderSrcs[0] = loadSource("VisibilityVP","Raycasting.glsl"); + mShaderSrcs[1] = loadSource("VisibilityFP","Raycasting.glsl"); + mShaderSrcs[2] = loadSource("AttributeVP","Raycasting.glsl"); + mShaderSrcs[3] = loadSource("AttributeFP","Raycasting.glsl"); + mShaderSrcs[4] = ""; + mShaderSrcs[5] = loadSource("Finalization","Finalization.glsl"); + + mCurrentPass = 2; + mBindedPass = -1; + mIsInitialized = true; + GL_TEST_ERR +} + +void SplatRenderer::updateRenderBuffer() +{ + if ( (!mRenderBuffer) + || (mRenderBuffer->width()!=mCachedVP[2]) + || (mRenderBuffer->height()!=mCachedVP[3]) + || ( (mCachedFlags & mRenderBufferMask) != (mFlags & mRenderBufferMask) )) + { + delete mRenderBuffer; + GLenum fmt = (mFlags&FLOAT_BUFFER_BIT) ? GL_RGBA16F_ARB : GL_RGBA; + mRenderBuffer = new QGLFramebufferObject(mCachedVP[2], mCachedVP[3], + (mFlags&OUTPUT_DEPTH_BIT) ? QGLFramebufferObject::NoAttachment : QGLFramebufferObject::Depth, + GL_TEXTURE_RECTANGLE_ARB, fmt); + + if (!mRenderBuffer->isValid()) + { + std::cout << "SplatRenderer: invalid FBO\n"; + } + + GL_TEST_ERR + if (mFlags&DEFERRED_SHADING_BIT) + { + // in deferred shading mode we need an additional buffer to accumulate the normals + if (mNormalTextureID==0) + glGenTextures(1,&mNormalTextureID); + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, mNormalTextureID); + glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, fmt, mCachedVP[2], mCachedVP[3], 0, GL_RGBA, GL_FLOAT, 0); + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + mRenderBuffer->bind(); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_RECTANGLE_ARB, mNormalTextureID, 0); + mRenderBuffer->release(); + GL_TEST_ERR + } + + if (mFlags&OUTPUT_DEPTH_BIT) + { + // to output the depth values to the final depth buffer we need to + // attach a depth buffer as a texture + if (mDepthTextureID==0) + glGenTextures(1,&mDepthTextureID); + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, mDepthTextureID); + glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_DEPTH_COMPONENT24_ARB, mCachedVP[2], mCachedVP[3], 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0); + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + mRenderBuffer->bind(); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_RECTANGLE_ARB, mDepthTextureID, 0); + mRenderBuffer->release(); + GL_TEST_ERR + } + } +} + +bool SplatRenderer::beginVisibilityPass() +{ + if (!mIsInitialized) + { + init(); + } + if (!isSupported()) + { + std::cerr << "SplatRenderer error: not supported hardware\n"; + return false; + } + if (mCurrentPass!=2) + { + std::cerr << "SplatRenderer error: programming error when calling beginVisibilityPass\n"; + return false; + } + + glPushAttrib(GL_ALL_ATTRIB_BITS); + + mCurrentPass = 0; + + // grab projection info + glGetIntegerv(GL_VIEWPORT, mCachedVP); + glGetFloatv(GL_MODELVIEW_MATRIX, mCachedMV); + glGetFloatv(GL_PROJECTION_MATRIX, mCachedProj); + + updateRenderBuffer(); + if (mCachedFlags != mFlags) + configureShaders(); + + // configureShaders may detect that shaders are actually not supported. + if (!isSupported()) + { + std::cerr << "SplatRenderer error: not supported hardware\n"; + return false; + } + + mCachedFlags = mFlags; + + mParams.update(mCachedMV, mCachedProj, mCachedVP); + mParams.loadTo(mShaders[mCurrentPass]); + + mRenderBuffer->bind(); + if (mFlags & DEFERRED_SHADING_BIT) + { + GLenum buf[2] = {GL_COLOR_ATTACHMENT0_EXT,GL_COLOR_ATTACHMENT1_EXT}; + glDrawBuffersARB(2, buf); + } + glViewport(mCachedVP[0],mCachedVP[1],mCachedVP[2],mCachedVP[3]); + glClearColor(0,0,0,0); + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + enablePass(mCurrentPass); + GL_TEST_ERR; + return true; +} +bool SplatRenderer::beginAttributePass() +{ + if (!isSupported()) + { + std::cerr << "SplatRenderer error: not supported hardware\n"; + return false; + } + if (mCurrentPass!=0) + { + std::cerr << "SplatRenderer error: programming error when calling beginAttributePass (must be called after the visiblity pass)\n"; + return false; + } + + mCurrentPass = 1; + mParams.loadTo(mShaders[mCurrentPass]); + enablePass(mCurrentPass); + GL_TEST_ERR; + return true; +} +bool SplatRenderer::finalize() +{ + if (!isSupported()) + { + std::cerr << "SplatRenderer error: not supported hardware\n"; + return false; + } + + // this is the last pass: normalization by the sum of weights + deferred shading + mShaders[mCurrentPass].release(); + mRenderBuffer->release(); + + if ( (mCurrentPass!=0) && (mCurrentPass!=1)) + { + std::cerr << "SplatRenderer error: programming error when calling finalize (must be called after the visiblity or attribute pass)\n"; + return false; + } + + mCurrentPass = 2; + + if (mFlags&DEFERRED_SHADING_BIT) + glDrawBuffer(GL_BACK); + + enablePass(mCurrentPass);GL_TEST_ERR + + // switch to normalized 2D rendering mode + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + + GL_TEST_ERR + mShaders[2].setUniform("viewport",float(mCachedVP[0]),float(mCachedVP[1]),float(mCachedVP[2]),float(mCachedVP[3]));GL_TEST_ERR + mShaders[2].setUniform("ColorWeight",0); GL_TEST_ERR // this is a texture unit + glActiveTexture(GL_TEXTURE0);GL_TEST_ERR + glBindTexture(GL_TEXTURE_RECTANGLE_ARB,mRenderBuffer->texture());GL_TEST_ERR + + if (mFlags&DEFERRED_SHADING_BIT) + { + mShaders[2].setUniform("unproj", mCachedProj[10], mCachedProj[14]);GL_TEST_ERR + mShaders[2].setUniform("NormalWeight",1);GL_TEST_ERR // this is a texture unit + glActiveTexture(GL_TEXTURE1);GL_TEST_ERR + glBindTexture(GL_TEXTURE_RECTANGLE_ARB,mNormalTextureID);GL_TEST_ERR + GL_TEST_ERR + } + + if (mFlags&OUTPUT_DEPTH_BIT) + { + mShaders[2].setUniform("Depth",2);GL_TEST_ERR // this is a texture unit + glActiveTexture(GL_TEXTURE2);GL_TEST_ERR + glBindTexture(GL_TEXTURE_RECTANGLE_ARB,mDepthTextureID);GL_TEST_ERR + GL_TEST_ERR + } + else + { + glDisable(GL_DEPTH_TEST); + glDepthMask(GL_FALSE); + } + + // draw a quad covering the whole screen + float viewVec[] = {1.f/mCachedProj[0], 1.f/mCachedProj[5], -1}; + + glBegin(GL_QUADS); + glColor3f(1, 0, 0); + glTexCoord3f(viewVec[0],viewVec[1],viewVec[2]); + glMultiTexCoord2f(GL_TEXTURE1,1.,1.); + glVertex3f(1,1,0); + + glColor3f(1, 1, 0); + glTexCoord3f(-viewVec[0],viewVec[1],viewVec[2]); + glMultiTexCoord2f(GL_TEXTURE1,0.,1.); + glVertex3f(-1,1,0); + + glColor3f(0, 1, 1); + glTexCoord3f(-viewVec[0],-viewVec[1],viewVec[2]); + glMultiTexCoord2f(GL_TEXTURE1,0.,0.); + glVertex3f(-1,-1,0); + + glColor3f(1, 0, 1); + glTexCoord3f(viewVec[0],-viewVec[1],viewVec[2]); + glMultiTexCoord2f(GL_TEXTURE1,1.,0.); + glVertex3f(1,-1,0); + glEnd(); + if (!(mFlags&OUTPUT_DEPTH_BIT)) + { + glEnable(GL_DEPTH_TEST); + glDepthMask(GL_TRUE); + } + + mShaders[mCurrentPass].release(); + + // restore matrices + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + + glPopAttrib(); + return true; +} + +void SplatRenderer::enablePass(int n) +{ + if (!isSupported()) + { + return; + } + if (mBindedPass!=n) + { + if (mBindedPass>=0) + mShaders[mBindedPass].release(); + mShaders[n].activate(); + mBindedPass = n; + + // set GL states + if (n==0) + { + glDisable(GL_LIGHTING); +// glDisable(GL_POINT_SMOOTH); + glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); + + glAlphaFunc(GL_LESS,1); + glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE); + glDepthMask(GL_TRUE); + glDisable(GL_BLEND); + glEnable(GL_ALPHA_TEST); + glEnable(GL_DEPTH_TEST); + +// glActiveTexture(GL_TEXTURE0); +// glTexEnvf(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE); +// glEnable(GL_POINT_SPRITE_ARB); + } + if (n==1) + { + glDisable(GL_LIGHTING); + glEnable(GL_POINT_SMOOTH); + glActiveTexture(GL_TEXTURE0); + glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); + + glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_ONE,GL_ONE); +// //glBlendFuncSeparate(GL_ONE, GL_ZERO, GL_ONE,GL_ZERO); +// glBlendFunc(GL_ONE,GL_ZERO); + glDepthMask(GL_FALSE); + glEnable(GL_BLEND); + glEnable(GL_DEPTH_TEST); + glDisable(GL_ALPHA_TEST); + +// glActiveTexture(GL_TEXTURE0); + + } + if ( (n==0) || (n==1) ) + { + // enable point sprite rendering mode + glActiveTexture(GL_TEXTURE0); + if (mWorkaroundATI) + { + glBindTexture(GL_TEXTURE_2D, mDummyTexId); + glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 2, 2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0); + glPointParameterf(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT); + // hm... ^^^^ + } + glTexEnvf(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE); + glEnable(GL_POINT_SPRITE_ARB); + } + if (n==2) + { + glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); + glDepthMask(GL_TRUE); + glDisable(GL_LIGHTING); + glDisable(GL_BLEND); + } + } +} + +void SplatRenderer::UniformParameters::update(float* mv, float* proj, GLint* vp) +{ + // extract the uniform scale + float scale = sqrtf(mv[0]*mv[0]+mv[1]*mv[1]+mv[2]*mv[2]); + + radiusScale = scale; + preComputeRadius = - (std::max)(proj[0]*vp[2], proj[5]*vp[3]); + depthOffset = 2.0; + oneOverEwaRadius = 0.70710678118654; + halfVp[0] = 0.5*vp[2]; + halfVp[1] = 0.5*vp[3]; + rayCastParameter1[0] = 2./(proj[0]*vp[2]); + rayCastParameter1[1] = 2./(proj[5]*vp[3]); + rayCastParameter1[2] = 0.0; + rayCastParameter2[0] = -1./proj[0]; + rayCastParameter2[1] = -1./proj[5]; + rayCastParameter2[2] = -1.0; + depthParameterCast[0] = 0.5*proj[14]; + depthParameterCast[1] = 0.5-0.5*proj[10]; +} + +void SplatRenderer::UniformParameters::loadTo(Shader& prg) +{ + prg.activate(); + prg.setUniform("expeRadiusScale", radiusScale); + prg.setUniform("expePreComputeRadius", preComputeRadius); + prg.setUniform("expeDepthOffset", depthOffset); + prg.setUniform("oneOverEwaRadius", oneOverEwaRadius); + prg.setUniform2("halfVp", halfVp); + prg.setUniform3("rayCastParameter1", rayCastParameter1); + prg.setUniform3("rayCastParameter2", rayCastParameter2); + prg.setUniform2("depthParameterCast", depthParameterCast); +} + +void SplatRenderer::setRadiusScale(float v) +{ + mParams.radiusScale = v; +} + +} // namepsace GlSplat + diff -Nru cgal-4.4/demo/Polyhedron/GlSplat/GlSplat.h cgal-4.5/demo/Polyhedron/GlSplat/GlSplat.h --- cgal-4.4/demo/Polyhedron/GlSplat/GlSplat.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/GlSplat/GlSplat.h 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,144 @@ +// This file is part of GlSplat, a simple splatting C++ library +// +// Copyright (C) 2008-2009 Gael Guennebaud +// +// GlSplat is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// GlSplat is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GlSplat. If not, see . + +#ifndef _GLSPLAT_SPLATRENDERER_H_ +#define _GLSPLAT_SPLATRENDERER_H_ + +#include "GlSplat_config.h" +#include "Shader.h" +#include +#include +#include +#include + +class QGLFramebufferObject; +class QGLWidget; + +namespace GlSplat { + +/** \class SplatRenderer + * \brief Helper class to render a set of points using a splatting alogirthm + * + * This class aims to render a set of oriented point with radius (called splats) using an + * OpenGL based splating algorithm. This class is only responsible for the managing of the + * OpenGL stats and shaders related to the splatting. The drawing of the geometry, i.e., + * sending the point data to the GPU has to be done by the user. + * + * Here is an example: + * \code + * SplatRenderer renderer; + * renderer.init(); + * + * renderer.beginVisibilityPass(); + * drawpoints(); + * renderer.beginAttributePass(); + * drawpoints(); + * renderer.finalize(); + * \endcode + * + * Have a look at the demo to see a complete example based on QGLviewer. + */ +class GLSPLAT_EXPORT SplatRenderer +{ + bool mIsSupported; + enum { + DEFERRED_SHADING_BIT = 0x000001, + DEPTH_CORRECTION_BIT = 0x000002, + OUTPUT_DEPTH_BIT = 0x000004, + BACKFACE_SHADING_BIT = 0x000008, + FLOAT_BUFFER_BIT = 0x000010 + }; + int mFlags; + int mCachedFlags; + int mRenderBufferMask; + int mSupportedMask; + + int mCurrentPass; + int mBindedPass; + GLuint mDummyTexId; // on ATI graphics card we need to bind a texture to get point sprite working ! + bool mWorkaroundATI; + bool mBuggedAtiBlending; + bool mIsInitialized; + GLuint mNormalTextureID; + GLuint mDepthTextureID; + Shader mShaders[3]; + QString mShaderSrcs[6]; + QGLFramebufferObject* mRenderBuffer; + float mCachedMV[16]; // modelview matrix + float mCachedProj[16]; // projection matrix + GLint mCachedVP[4]; // viewport + + struct UniformParameters + { + float radiusScale; + float preComputeRadius; + float depthOffset; + float oneOverEwaRadius; + float halfVp[2]; + float rayCastParameter1[3]; + float rayCastParameter2[3]; + float depthParameterCast[2]; + + void loadTo(Shader& prg); + void update(float* mv, float* proj, GLint* vp); + }; + + UniformParameters mParams; + + QString loadSource(const QString& func,const QString& file); + void configureShaders(); + void updateRenderBuffer(); + void enablePass(int n); + +public: + + SplatRenderer(); + + /** Must be called once an OpenGL context has been activated. + * The main OpenGL context must be enabled, or, if you are using a QGLwiget, + * you can pass it to this function without caring about the OpenGL context. + */ + void init(QGLWidget *qglw = 0); + + /** \returns true is the hardware is supported + * Must be called after init. + */ + bool isSupported() { return mIsSupported; } + + /** Starts the first rendering pass + * \returns false if an error occured + */ + bool beginVisibilityPass(); + /** Starts the (optional) second rendering pass + * \returns false if an error occured + */ + bool beginAttributePass(); + /** Draw the rendered splats inside the main render target. + * \returns false if an error occured + */ + bool finalize(); + + /** Sets a global scale factor for the splat radii + * Default value is 1 + */ + void setRadiusScale(float v); + +}; + +} // namepsace GlSplat + +#endif // _GLSPLAT_SPLATRENDERER_H_ + diff -Nru cgal-4.4/demo/Polyhedron/GlSplat/glsplat.qrc cgal-4.5/demo/Polyhedron/GlSplat/glsplat.qrc --- cgal-4.4/demo/Polyhedron/GlSplat/glsplat.qrc 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/GlSplat/glsplat.qrc 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,6 @@ + + + shaders/Raycasting.glsl + shaders/Finalization.glsl + + diff -Nru cgal-4.4/demo/Polyhedron/GlSplat/Shader.cpp cgal-4.5/demo/Polyhedron/GlSplat/Shader.cpp --- cgal-4.4/demo/Polyhedron/GlSplat/Shader.cpp 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/GlSplat/Shader.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,136 @@ +// This file is part of GlSplat, a simple splatting C++ library +// +// Copyright (C) 2008-2009 Gael Guennebaud +// +// GlSplat is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// GlSplat is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GlSplat. If not, see . + +#include "Shader.h" +#include + +#include +#include +#include + +namespace GlSplat { + +void Shader::define(const char* name, const char* value) +{ + mDefines[std::string(name)] = value; +} +//-------------------------------------------------------------------------------- +bool Shader::loadSources(const char* vsrc, const char* fsrc) +{ + bool allIsOk = true; + + mProgramID = glCreateProgram(); + + std::string defineStr = ""; + for(DefineMap::iterator it = mDefines.begin() ; it!=mDefines.end() ; ++it) + { + defineStr += "#define " + it->first + " " + it->second + "\n"; + } + + if(vsrc) + { + GLuint shaderID = glCreateShader(GL_VERTEX_SHADER); + + std::string source = defineStr + std::string(vsrc); + const GLchar * arbSource = source.c_str(); + + glShaderSource(shaderID, 1, (const GLchar **)&arbSource, 0); + glCompileShader(shaderID); + + int compiled; + glGetShaderiv(shaderID,GL_COMPILE_STATUS,&compiled); + allIsOk = allIsOk && compiled; + //printInfoLog(shaderID); + + glAttachShader(mProgramID, shaderID); + } + + if(fsrc) + { + GLuint shaderID = glCreateShader(GL_FRAGMENT_SHADER); + + std::string source = defineStr + std::string(fsrc); + const GLchar * arbSource = source.c_str(); + + glShaderSource(shaderID, 1, (const GLchar **)&arbSource, 0); + glCompileShader(shaderID); + + int compiled; + glGetShaderiv(shaderID,GL_COMPILE_STATUS,&compiled); + allIsOk = allIsOk && compiled; + //printInfoLog(shaderID); + + glAttachShader(mProgramID, shaderID); + } + + glLinkProgram(mProgramID); + + int isLinked; + glGetProgramiv(mProgramID, GL_LINK_STATUS, &isLinked); + allIsOk = allIsOk && isLinked; + mIsValid = isLinked == GL_TRUE; + printInfoLog(mProgramID); + + return allIsOk; +} +//-------------------------------------------------------------------------------- +void Shader::activate(void) const +{ + assert(mIsValid); + glUseProgram(mProgramID); +} +void Shader::release(void) const +{ + glUseProgram(0); +} +//-------------------------------------------------------------------------------- +int Shader::getUniformLocation(const char* name) const +{ + assert(mIsValid); + int loc = glGetUniformLocation(mProgramID, name); + return loc; +} +//-------------------------------------------------------------------------------- +void Shader::setSamplerUnit(const char* sampler, int unit) const +{ + activate(); + glUniform1i(getUniformLocation(sampler), unit); + release(); +} +//-------------------------------------------------------------------------------- +int Shader::getAttribLocation(const char* name) const +{ + assert(mIsValid); + int loc = glGetAttribLocation(mProgramID, name); + return loc; +} +//-------------------------------------------------------------------------------- +void Shader::printInfoLog(GLuint objectID) +{ + int infologLength, charsWritten; + GLchar *infoLog; + glGetProgramiv(objectID,GL_INFO_LOG_LENGTH, &infologLength); + if(infologLength > 0) + { + infoLog = new GLchar[infologLength]; + glGetProgramInfoLog(objectID, infologLength, &charsWritten, infoLog); + if (charsWritten>0) + std::cerr << "Shader info : \n" << infoLog << std::endl; + delete[] infoLog; + } +} + +} // namepsace GlSplat diff -Nru cgal-4.4/demo/Polyhedron/GlSplat/Shader.h cgal-4.5/demo/Polyhedron/GlSplat/Shader.h --- cgal-4.4/demo/Polyhedron/GlSplat/Shader.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/GlSplat/Shader.h 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,148 @@ +// This file is part of GlSplat, a simple splatting C++ library +// +// Copyright (C) 2008-2009 Gael Guennebaud +// +// GlSplat is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// GlSplat is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GlSplat. If not, see . + +#ifndef _GLSPLAT_Shader_h_ +#define _GLSPLAT_Shader_h_ + +#include +#include + +#ifndef NDEBUG + #define GL_TEST_ERR\ + {\ + GLenum eCode;\ + if((eCode=glGetError())!=GL_NO_ERROR)\ + std::cerr << "OpenGL error : " << gluErrorString(eCode) << " in " << __FILE__ << " : " << __LINE__ << std::endl;\ + } +#else + #define GL_TEST_ERR +#endif + +#include +#include + +namespace GlSplat { + +/** Permet de manipuler des shaders en GLSL (OpenGL2.0) + Exemple d'utilisation: + \code + // shader creation: + Shader* myShader = new Shader(); + // loading from files (compilation + linking): + myShader->loadFromFiles("myShaderFile.vtx", "myShaderFile.frg"); + + // ... + + // at rending time: + myShader->enable(); + // draw objects + myShader->disable(); + \endcode +*/ + +class Shader +{ +public: + Shader(void) + : mIsValid(false) + { } + + /** add a \#define + */ + void define(const char* name, const char* value); + + /** Compiles and links the shader from 2 source files + \param fileV vertex shader ("" if no vertex shader) + \param fileF fragment shader ("" if no fragment shader) + \return true if no error occurs + */ +// bool loadFromFiles(const std::string& fileV, const std::string& fileF); + + bool loadSources(const char* vsrc, const char* fsrc); + + /** Enable the shader + */ + void activate() const; + + /** Releases the shader + */ + void release() const; + + /** \return the index of the uniform variable \a name + */ + int getUniformLocation(const char* name) const; + + /** Forces a sampler to a given unit + Example: + \code + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE2D, myTextureID); + myShader->setSamplerUnit("mySampler", 2); + \endcode + */ + void setSamplerUnit(const char* samplerName, int textureUnit) const; + + /** \returns the index of the generic attribute \a name + Tp be used with glVertexAttrib*(...) ou glVertexAttribPointer(...) + Example: + \code + int tangentAttribID = myShader->getAttribLocation("tangent"); + Vector3 tangent(...); + glVertexAttrib3fv(tangentAttribID, tangent); + // ou + Vector3* tangents = new Vector3[...]; + glVertexAttribPointer(tangentAttribID, 3, GL_FLOAT, GL_FALSE, 0, tangents); + glEnableVertexAttribArray(tangentAttribID); + \endcode + */ + int getAttribLocation(const char* name) const; + + inline void setUniform(const char* name, float a) const + { glUniform1f(glGetUniformLocation(mProgramID, name), a); } + + inline void setUniform(const char* name, int a) const + { glUniform1i(glGetUniformLocation(mProgramID, name), a); } + + inline void setUniform2(const char* name, float* a) const + { glUniform2fv(glGetUniformLocation(mProgramID, name), 1, a); } + + inline void setUniform3(const char* name, float* a) const + { glUniform3fv(glGetUniformLocation(mProgramID, name), 1, a); } + + inline void setUniform4(const char* name, float* a) const + { glUniform4fv(glGetUniformLocation(mProgramID, name), 1, a); } + + inline void setUniform(const char* name, float a, float b) const + { glUniform2f(glGetUniformLocation(mProgramID, name), a, b); } + + inline void setUniform(const char* name, float a, float b, float c) const + { glUniform3f(glGetUniformLocation(mProgramID, name), a, b, c); } + + inline void setUniform(const char* name, float a, float b, float c, float d) const + { glUniform4f(glGetUniformLocation(mProgramID, name), a, b, c, d); } + +protected: + + bool mIsValid; + typedef std::map DefineMap; + DefineMap mDefines; + static void printInfoLog(GLuint objectID); + GLuint mProgramID; +}; + +} // namepsace GlSplat + +#endif diff -Nru cgal-4.4/demo/Polyhedron/GlSplat/shaders/Finalization.glsl cgal-4.5/demo/Polyhedron/GlSplat/shaders/Finalization.glsl --- cgal-4.4/demo/Polyhedron/GlSplat/shaders/Finalization.glsl 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/GlSplat/shaders/Finalization.glsl 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,106 @@ +// This file is part of GlSplat, a simple splatting C++ library +// +// Copyright (C) 2008-2009 Gael Guennebaud +// +// GlSplat is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// GlSplat is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GlSplat. If not, see . + +#extension GL_ARB_texture_rectangle : enable + +#ifndef ES_DEPTH_INTERPOLATION + #define ES_DEPTH_INTERPOLATION 0 +#endif + +#ifndef ES_OUTPUT_DEPTH + #define ES_OUTPUT_DEPTH 0 +#endif + +// avoid an annoying bug with the nvidia driver 87XX serie. +#define epsilon 0.000001 + +uniform vec4 viewport; + +#ifndef ES_DEFERRED_SHADING + +uniform sampler2DRect ColorWeight; +#if (ES_OUTPUT_DEPTH==1) +uniform sampler2DRect Depth; +#endif + +void Finalization(void) +{ + vec4 color = texture2DRect(ColorWeight, gl_FragCoord.st - viewport.xy + epsilon); + #if (ES_OUTPUT_DEPTH==1) + gl_FragDepth = texture2DRect(Depth, gl_FragCoord.st + epsilon).x; + #endif + if (color.w<0.001) + discard; + gl_FragColor = color/color.w; + gl_FragColor.a = 1.; +} + +#else + +uniform vec2 unproj; + +uniform sampler2DRect ColorWeight; +uniform sampler2DRect NormalWeight; + +#if ( (ES_DEPTH_INTERPOLATION==0) || (ES_OUTPUT_DEPTH==1)) +uniform sampler2DRect Depth; +#endif + +void Finalization(void) +{ + vec4 color = texture2DRect(ColorWeight, gl_FragCoord.st - viewport.xy + epsilon); + + if (color.w<0.001) + discard; + + + if(color.w>0.001) + color.xyz /= color.w; + + vec3 viewVec = normalize(gl_TexCoord[0].xyz); + vec4 normaldepth = texture2DRect(NormalWeight, gl_FragCoord.st + epsilon); + + normaldepth.xyz = normaldepth.xyz/normaldepth.w; + + #if (ES_OUTPUT_DEPTH==1) + gl_FragDepth = texture2DRect(Depth, gl_FragCoord.st + epsilon).x; + #endif + + #if ES_DEPTH_INTERPOLATION==2 + float depth = -normaldepth.z; + #elif ES_DEPTH_INTERPOLATION==1 + float depth = unproj.y/(2.0*normaldepth.z+unproj.x-1.0); + #else + float depth = texture2DRect(Depth, gl_FragCoord.st + epsilon).x; + depth = unproj.y/(2.0*depth+unproj.x-1.0); + #endif + + vec3 normal = normaldepth.xyz; + #if ES_DEPTH_INTERPOLATION!=0 + normal.z = sqrt(1. - dot(vec3(normal.xy,0),vec3(normal.xy,0))); + #endif + normal = normalize(normal); + vec3 eyePos = gl_TexCoord[0].xyz * depth; + + gl_FragColor = meshlabLighting(color, eyePos, normal); + gl_FragColor.a = 1.0; +} + +#endif + + + diff -Nru cgal-4.4/demo/Polyhedron/GlSplat/shaders/Raycasting.glsl cgal-4.5/demo/Polyhedron/GlSplat/shaders/Raycasting.glsl --- cgal-4.4/demo/Polyhedron/GlSplat/shaders/Raycasting.glsl 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/GlSplat/shaders/Raycasting.glsl 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,335 @@ +// This file is part of GlSplat, a simple splatting C++ library +// +// Copyright (C) 2008-2009 Gael Guennebaud +// +// GlSplat is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// GlSplat is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GlSplat. If not, see . + +#pragma optimize(on) + +#ifndef ES_EWA_HINT + #define ES_EWA_HINT 0 +#endif + +#ifndef ES_DEPTH_INTERPOLATION + #define ES_DEPTH_INTERPOLATION 0 +#endif + +//-------------------------------------------------------------------------------- +// shared variables +//-------------------------------------------------------------------------------- + +// custom vertex attributes +//attribute float radius; + +#ifdef CLIPPED_SPLAT +attribute vec3 secondNormal; +varying vec4 clipLine; +#endif + +// standard uniforms +uniform float expeRadiusScale; +uniform float expePreComputeRadius; +uniform float expeDepthOffset; + +// varying +varying vec4 covmat; +varying vec3 fragNormal; + +varying vec3 fragNoverCdotN; +varying vec3 fragCenter; +varying float scaleSquaredDistance; + +#ifdef ES_ATI_WORKAROUND +varying vec4 fragCenterAndRadius; +#endif + +#ifdef ES_DEPTH_CORRECTION +varying float depthOffset; +#endif + +uniform vec2 halfVp; +uniform float oneOverEwaRadius; + + +#ifdef ES_BACKFACE_SHADING + #undef ES_EARLY_BACK_FACE_CULLING + //#define ES_EWA_HINT 2 +#endif + +//-------------------------------------------------------------------------------- +// Visibility Splatting +// Vertex Shader +//-------------------------------------------------------------------------------- + +#ifdef GLSPLAT__VisibilityVP__ +varying vec2 scaledFragCenter2d; +void VisibilityVP(void) +{ + vec3 normal = normalize(gl_NormalMatrix * gl_Normal); + // Point in eye space + vec4 ePos = gl_ModelViewMatrix * gl_Vertex; + + float dotpn = dot(normal.xyz,ePos.xyz); + + vec4 oPos; + + #ifdef ES_EARLY_BACK_FACE_CULLING + // back_face culling + oPos = vec4(0,0,1,0); + if(dotpn<0.) + { + #endif + + float radius = gl_MultiTexCoord2.x * expeRadiusScale; + + vec4 pointSize; + pointSize.x = radius * expePreComputeRadius / ePos.z; + gl_PointSize = max(1.0, pointSize.x); + + scaleSquaredDistance = 1.0 / (radius * radius); + //fragNormal = normal; + fragCenter = ePos.xyz; + fragNoverCdotN = normal/dot(ePos.xyz,normal); + + #ifndef ES_DEPTH_CORRECTION + ePos.xyz += normalize(ePos.xyz) * expeDepthOffset * radius; + #else + //ePos.xyz += normalize(ePos.xyz) * expeDepthOffset * radius; + depthOffset = expeDepthOffset * radius; + #endif + + oPos = gl_ProjectionMatrix * ePos; + + #if (ES_EWA_HINT>0) + scaledFragCenter2d = 0.5*((oPos.xy/oPos.w)+1.0)*halfVp*oneOverEwaRadius; + #endif + + #ifdef ES_ATI_WORKAROUND + fragCenterAndRadius.xyz = (oPos.xyz/oPos.w) + 1.0; + fragCenterAndRadius.xy = fragCenterAndRadius.xy*halfVp; + fragCenterAndRadius.z = fragCenterAndRadius.z*0.5; + fragCenterAndRadius.w = pointSize.x; + #endif + + #ifndef ES_EARLY_BACK_FACE_CULLING + oPos.w = oPos.w * (dotpn<0.0 ? 1.0 : 0.0); + #else + } + #endif + + gl_Position = oPos; +} + +#endif + +//-------------------------------------------------------------------------------- +// Visibility Splatting +// Fragment Shader +//-------------------------------------------------------------------------------- + +#ifdef GLSPLAT__VisibilityFP__ +varying vec2 scaledFragCenter2d; +uniform vec3 rayCastParameter1; +uniform vec3 rayCastParameter2; +uniform vec2 depthParameterCast; + +void VisibilityFP(void) +{ + #ifdef ES_ATI_WORKAROUND + vec3 fragCoord; + fragCoord.xy = fragCenterAndRadius.xy + (gl_TexCoord[0].st-0.5) * fragCenterAndRadius.w; + fragCoord.z = fragCenterAndRadius.z; + #else + vec3 fragCoord = gl_FragCoord.xyz; + #endif + // compute q in object space + vec3 qOne = rayCastParameter1 * fragCoord + rayCastParameter2; + float oneOverDepth = dot(qOne,-fragNoverCdotN); + float depth = (1.0/oneOverDepth); + vec3 diff = fragCenter + qOne * depth; + float r2 = dot(diff,diff); + + #if (ES_EWA_HINT>0) + vec2 d2 = oneOverEwaRadius*gl_FragCoord.xy - scaledFragCenter2d; + float r2d = dot(d2,d2); + gl_FragColor = vec4(min(r2d,r2*scaleSquaredDistance)); + #else + gl_FragColor = vec4(r2*scaleSquaredDistance); + #endif + + #ifdef ES_DEPTH_CORRECTION + oneOverDepth = 1.0/(-depth+depthOffset); + gl_FragDepth = depthParameterCast.x * oneOverDepth + depthParameterCast.y; + #endif +} + +#endif + +#ifdef GLSPLAT__AttributeVP__ + +varying vec2 scaledFragCenter2d; + +void AttributeVP(void) +{ + // transform normal + vec3 normal = normalize(gl_NormalMatrix * gl_Normal); + // Point in eye space + vec4 ePos = gl_ModelViewMatrix * gl_Vertex; + + float dotpn = dot(normal.xyz,ePos.xyz); + + vec4 oPos; + + #ifdef ES_EARLY_BACK_FACE_CULLING + // back_face culling + oPos = vec4(0,0,1,0); + if(dotpn<0.) + { + #endif + + #ifdef ES_BACKFACE_SHADING + if(dotpn>0.) + { + dotpn = -dotpn; + normal = -normal; + } + #endif + + float radius = gl_MultiTexCoord2.x * expeRadiusScale * 1.1; + + vec4 pointSize; + pointSize.x = radius * expePreComputeRadius / ePos.z; + + #if (ES_EWA_HINT>0) + gl_PointSize = max(2.0, pointSize.x); + #else + gl_PointSize = max(1.0, pointSize.x); + #endif + + scaleSquaredDistance = 1. / (radius * radius); + fragNormal = normal; + fragCenter = ePos.xyz; + fragNoverCdotN = normal/dot(ePos.xyz,normal); + + // Output color + #ifdef ES_DEFERRED_SHADING + fragNormal.xyz = normal.xyz; + gl_FrontColor = gl_Color; + #else + // Output color + #ifdef ES_LIGHTING + gl_FrontColor = expeLighting(gl_Color, ePos.xyz, normal.xyz, 1.); + #else + gl_FrontColor = meshlabLighting(gl_Color, ePos.xyz, normal.xyz); + #endif + #endif + + oPos = gl_ModelViewProjectionMatrix * gl_Vertex; + + #ifdef ES_ATI_WORKAROUND + fragCenterAndRadius.xyz = (oPos.xyz/oPos.w) + 1.0; + fragCenterAndRadius.xy = fragCenterAndRadius.xy*halfVp; + fragCenterAndRadius.z = fragCenterAndRadius.z*0.5; + fragCenterAndRadius.w = pointSize.x; + #endif + + #if (ES_EWA_HINT>0) + scaledFragCenter2d = ((oPos.xy/oPos.w)+1.0)*halfVp*oneOverEwaRadius; + #endif + + #ifndef ES_EARLY_BACK_FACE_CULLING + oPos.w = oPos.w * (dotpn<0. ? 1.0 : 0.0); + #else + } + #endif + + gl_Position = oPos; +} + +#endif + +//-------------------------------------------------------------------------------- +// EWA Splatting +// Fragment Shader +//-------------------------------------------------------------------------------- + +#ifdef GLSPLAT__AttributeFP__ +// this sampler is only used by this fragment shader + +varying vec2 scaledFragCenter2d; +uniform vec3 rayCastParameter1; +uniform vec3 rayCastParameter2; +uniform vec2 depthParameterCast; + +// uniform sampler1D Kernel1dMap; + +void AttributeFP(void) +{ + #ifdef ES_ATI_WORKAROUND + vec3 fragCoord; + fragCoord.xy = fragCenterAndRadius.xy + (gl_TexCoord[0].st-0.5) * fragCenterAndRadius.w; + fragCoord.z = fragCenterAndRadius.z; + #else + vec3 fragCoord = gl_FragCoord.xyz; + #endif + +#if 1 + vec3 qOne = rayCastParameter1 * fragCoord + rayCastParameter2; + float oneOverDepth = dot(qOne,fragNoverCdotN); + float depth = (1.0/oneOverDepth); + vec3 diff = fragCenter - qOne * depth; + float r2 = dot(diff,diff); + + #if (ES_EWA_HINT>0) + vec2 d2 = oneOverEwaRadius*gl_FragCoord.xy - scaledFragCenter2d; + float r2d = dot(d2,d2); +// float weight = texture1D(Kernel1dMap, min(r2d,r2*scaleSquaredDistance)).a; + float weight = min(r2d,r2*scaleSquaredDistance); + weight = clamp(1.-weight,0,1); + weight = weight*weight; + #else + //float weight = texture1D(Kernel1dMap, r2*scaleSquaredDistance).a; + float weight = clamp(1.-r2*scaleSquaredDistance,0.0,1.0); + weight = weight*weight; + #endif + weight *= 0.1; // limits overflow + + #ifdef ES_DEPTH_CORRECTION + gl_FragDepth = depthParameterCast.x * oneOverDepth + depthParameterCast.y; + #endif + + #ifdef ES_DEFERRED_SHADING + gl_FragData[0].rgb = gl_Color.rgb; + gl_FragData[1].xyz = fragNormal.xyz; + gl_FragData[1].w = weight; + gl_FragData[0].w = weight; + + #if ES_DEPTH_INTERPOLATION==2 // linear space + gl_FragData[1].z = -depth; + #elif ES_DEPTH_INTERPOLATION==1 // window space + #ifdef ES_DEPTH_CORRECTION + gl_FragData[1].z = gl_FragDepth; + #else + gl_FragData[1].z = fragCoord.z; + #endif + #endif + + #else + gl_FragColor.rgb = gl_Color.rgb; + gl_FragColor.w = weight; + #endif +#endif +} + +#endif diff -Nru cgal-4.4/demo/Polyhedron/include/Point_set_3.h cgal-4.5/demo/Polyhedron/include/Point_set_3.h --- cgal-4.4/demo/Polyhedron/include/Point_set_3.h 2012-11-13 13:13:59.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/include/Point_set_3.h 2014-08-29 13:58:17.000000000 +0000 @@ -281,6 +281,24 @@ } } + // Draw oriented points with radius using OpenGL calls. + // Preconditions: must be used inbetween calls to GlSplat library + void gl_draw_splats() const + { + // TODO add support for selection + ::glBegin(GL_POINTS); + for (const_iterator it = begin(); it != end(); it++) + { + const UI_point& p = *it; + ::glNormal3dv(&p.normal().x()); +#ifdef CGAL_GLEW_ENABLED + ::glMultiTexCoord1d(GL_TEXTURE2, p.radius()); +#endif + ::glVertex3dv(&p.x()); + } + ::glEnd(); + } + bool are_radii_uptodate() const { return m_radii_are_uptodate; } void set_radii_uptodate(bool /*on*/) { m_radii_are_uptodate = false; } diff -Nru cgal-4.4/demo/Polyhedron/MainWindow.cpp cgal-4.5/demo/Polyhedron/MainWindow.cpp --- cgal-4.4/demo/Polyhedron/MainWindow.cpp 2014-03-05 20:00:23.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/MainWindow.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -13,6 +13,8 @@ #include #include #include +#include +#include #include #include #include @@ -23,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -136,7 +139,19 @@ // setup scene scene = new Scene(this); viewer->setScene(scene); - sceneView->setModel(scene); + + { + QShortcut* shortcut = new QShortcut(QKeySequence(Qt::ALT+Qt::Key_Q), this); + connect(shortcut, SIGNAL(activated()), + this, SLOT(setFocusToQuickSearch())); + } + + proxyModel = new QSortFilterProxyModel(this); + proxyModel->setSourceModel(scene); + + connect(ui->searchEdit, SIGNAL(textChanged(QString)), + proxyModel, SLOT(setFilterFixedString(QString))); + sceneView->setModel(proxyModel); // setup the sceneview: delegation and columns sizing... sceneView->setItemDelegate(new SceneDelegate(this)); @@ -211,8 +226,6 @@ // this, SLOT(showSceneContextMenu(const QPoint &))); connect(ui->actionRecenterScene, SIGNAL(triggered()), - viewer->camera(), SLOT(interpolateToFitScene())); - connect(ui->actionRecenterScene, SIGNAL(triggered()), viewer, SLOT(update())); connect(ui->actionAntiAliasing, SIGNAL(toggled(bool)), @@ -566,8 +579,36 @@ #endif } +void MainWindow::viewerShow(float xmin, + float ymin, + float zmin, + float xmax, + float ymax, + float zmax) +{ + qglviewer::Vec + min_(xmin, ymin, zmin), + max_(xmax, ymax, zmax); +#if QGLVIEWER_VERSION >= 0x020502 + viewer->camera()->setPivotPoint((min_+max_)*0.5); +#else + viewer->camera()->setRevolveAroundPoint((min_+max_)*0.5); +#endif + + qglviewer::ManipulatedCameraFrame backup_frame(*viewer->camera()->frame()); + viewer->camera()->fitBoundingBox(min_, max_); + qglviewer::ManipulatedCameraFrame new_frame(*viewer->camera()->frame()); + *viewer->camera()->frame() = backup_frame; + viewer->camera()->interpolateTo(new_frame, 1.f); + viewer->setVisualHintsMask(1); +} + void MainWindow::viewerShow(float x, float y, float z) { +#if QGLVIEWER_VERSION >= 0x020502 + viewer->camera()->setPivotPoint(qglviewer::Vec(x, y, z)); +#else viewer->camera()->setRevolveAroundPoint(qglviewer::Vec(x, y, z)); +#endif // viewer->camera()->lookAt(qglviewer::Vec(x, y, z)); qglviewer::ManipulatedCameraFrame backup_frame(*viewer->camera()->frame()); @@ -788,7 +829,7 @@ Scene_item* scene_item = load_item(fileinfo, find_loader(load_pair.first)); if(scene_item != 0) { - this->addToRecentFiles(filename); + this->addToRecentFiles(fileinfo.absoluteFilePath()); } selectSceneItem(scene->addItem(scene_item)); } @@ -828,6 +869,11 @@ return item; } +void MainWindow::setFocusToQuickSearch() +{ + ui->searchEdit->setFocus(Qt::ShortcutFocusReason); +} + void MainWindow::selectSceneItem(int i) { if(i < 0 || i >= scene->numberOfEntries()) { @@ -836,8 +882,10 @@ updateDisplayInfo(); } else { - sceneView->selectionModel()->select(scene->createSelection(i), - QItemSelectionModel::ClearAndSelect); + QItemSelection s = + proxyModel->mapSelectionFromSource(scene->createSelection(i)); + sceneView->selectionModel()->select(s, + QItemSelectionModel::ClearAndSelect); } } @@ -857,22 +905,27 @@ void MainWindow::addSceneItemInSelection(int i) { - sceneView->selectionModel()->select(scene->createSelection(i), - QItemSelectionModel::Select); + QItemSelection s = + proxyModel->mapSelectionFromSource(scene->createSelection(i)); + sceneView->selectionModel()->select(s, QItemSelectionModel::Select); scene->itemChanged(i); } void MainWindow::removeSceneItemFromSelection(int i) { - sceneView->selectionModel()->select(scene->createSelection(i), - QItemSelectionModel::Deselect); + QItemSelection s = + proxyModel->mapSelectionFromSource(scene->createSelection(i)); + sceneView->selectionModel()->select(s, + QItemSelectionModel::Deselect); scene->itemChanged(i); } void MainWindow::selectAll() { - sceneView->selectionModel()->select(scene->createSelectionAll(), - QItemSelectionModel::ClearAndSelect); + QItemSelection s = + proxyModel->mapSelectionFromSource(scene->createSelectionAll()); + sceneView->selectionModel()->select(s, + QItemSelectionModel::ClearAndSelect); } int MainWindow::getSelectedSceneItemIndex() const @@ -880,8 +933,10 @@ QModelIndexList selectedRows = sceneView->selectionModel()->selectedRows(); if(selectedRows.size() != 1) return -1; - else - return selectedRows.first().row(); + else { + QModelIndex i = proxyModel->mapToSource(selectedRows.first()); + return i.row(); + } } QList MainWindow::getSelectedSceneItemIndices() const @@ -889,7 +944,7 @@ QModelIndexList selectedRows = sceneView->selectionModel()->selectedRows(); QList result; Q_FOREACH(QModelIndex index, selectedRows) { - result << index.row(); + result << proxyModel->mapToSource(index).row(); } return result; } @@ -938,14 +993,25 @@ const char* prop_name = "Menu modified by MainWindow."; QMenu* menu = item->contextMenu(); - if(menu && !item->property("source filename").toString().isEmpty()) { + if(menu) { bool menuChanged = menu->property(prop_name).toBool(); if(!menuChanged) { menu->addSeparator(); - QAction* reload = menu->addAction(tr("Reload item from file")); - reload->setData(qVariantFromValue(selectedItemIndex)); - connect(reload, SIGNAL(triggered()), - this, SLOT(reload_item())); + if(!item->property("source filename").toString().isEmpty()) { + QAction* reload = menu->addAction(tr("&Reload item from file")); + reload->setData(qVariantFromValue(selectedItemIndex)); + connect(reload, SIGNAL(triggered()), + this, SLOT(reload_item())); + } + QAction* saveas = menu->addAction(tr("&Save as...")); + saveas->setData(qVariantFromValue(selectedItemIndex)); + connect(saveas, SIGNAL(triggered()), + this, SLOT(on_actionSaveAs_triggered())); + QAction* showobject = menu->addAction(tr("&Zoom to this object")); + showobject->setData(qVariantFromValue(selectedItemIndex)); + connect(showobject, SIGNAL(triggered()), + this, SLOT(viewerShowObject())); + menu->setProperty(prop_name, true); } } @@ -962,7 +1028,7 @@ QModelIndex modelIndex = sceneView->indexAt(p); if(!modelIndex.isValid()) return; - index = modelIndex.row(); + index = proxyModel->mapToSource(modelIndex).row(); } else { index = scene->mainSelectionIndex(); @@ -1141,10 +1207,19 @@ void MainWindow::on_actionSaveAs_triggered() { - QModelIndexList selectedRows = sceneView->selectionModel()->selectedRows(); - if(selectedRows.size() != 1) - return; - Scene_item* item = scene->item(getSelectedSceneItemIndex()); + int index = -1; + QAction* sender_action = qobject_cast(sender()); + if(sender_action && !sender_action->data().isNull()) { + index = sender_action->data().toInt(); + } + + if(index < 0) { + QModelIndexList selectedRows = sceneView->selectionModel()->selectedRows(); + if(selectedRows.size() != 1) + return; + index = getSelectedSceneItemIndex(); + } + Scene_item* item = scene->item(index); if(!item) return; @@ -1167,9 +1242,10 @@ return; } + QString caption = tr("Save %1 to File...").arg(item->name()); QString filename = QFileDialog::getSaveFileName(this, - tr("Save to File..."), + caption, QString(), filters.join(";;")); save(filename, item); @@ -1211,7 +1287,7 @@ { Q_FOREACH(QModelIndex index, sceneView->selectionModel()->selectedRows()) { - int i = index.row(); + int i = proxyModel->mapToSource(index).row(); Scene_item* item = scene->item(i); item->setVisible(!item->visible()); scene->itemChanged(i); @@ -1303,6 +1379,20 @@ } } +void MainWindow::viewerShowObject() +{ + int index = -1; + QAction* sender_action = qobject_cast(sender()); + if(sender_action && !sender_action->data().isNull()) { + index = sender_action->data().toInt(); + } + if(index >= 0) { + const Scene::Bbox bbox = scene->item(index)->bbox(); + viewerShow((float)bbox.xmin, (float)bbox.ymin, (float)bbox.zmin, + (float)bbox.xmax, (float)bbox.ymax, (float)bbox.zmax); + } +} + QString MainWindow::camera_string() const { return viewer->dumpCameraCoordinates(); @@ -1329,3 +1419,9 @@ { viewer->setAddKeyFrameKeyboardModifiers(m); } + +void MainWindow::on_actionRecenterScene_triggered() +{ + updateViewerBBox(); + viewer->camera()->interpolateToFitScene(); +} diff -Nru cgal-4.4/demo/Polyhedron/MainWindow.h cgal-4.5/demo/Polyhedron/MainWindow.h --- cgal-4.4/demo/Polyhedron/MainWindow.h 2013-08-03 19:00:28.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/MainWindow.h 2014-08-29 13:58:17.000000000 +0000 @@ -21,6 +21,7 @@ class Polyhedron_demo_io_plugin_interface; class Polyhedron_demo_plugin_interface; class Scene_item; +class QSortFilterProxyModel; namespace Ui { class MainWindow; @@ -71,6 +72,8 @@ bool load_script(QString filename); bool load_script(QFileInfo); + void setFocusToQuickSearch(); + void selectSceneItem(int i); void showSelectedPoint(double, double, double); void unSelectSceneItem(int i); @@ -86,6 +89,8 @@ QString actionText, QString menuName); void viewerShow(float, float, float); + void viewerShow(float, float, float, float, float, float); + void viewerShowObject(); void information(QString); void warning(QString); @@ -143,6 +148,7 @@ void filterOperations(); + void on_actionRecenterScene_triggered(); protected: void loadPlugins(); bool initPlugin(QObject*); @@ -162,6 +168,7 @@ Scene* scene; Viewer* viewer; + QSortFilterProxyModel* proxyModel; QTreeView* sceneView; Ui::MainWindow* ui; QVector io_plugins; diff -Nru cgal-4.4/demo/Polyhedron/MainWindow.ui cgal-4.5/demo/Polyhedron/MainWindow.ui --- cgal-4.4/demo/Polyhedron/MainWindow.ui 2013-03-14 20:00:23.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/MainWindow.ui 2014-08-29 13:58:17.000000000 +0000 @@ -209,6 +209,13 @@
+ + + + Quick filter... <Alt+Q> + + + diff -Nru cgal-4.4/demo/Polyhedron/Meshing_dialog.ui cgal-4.5/demo/Polyhedron/Meshing_dialog.ui --- cgal-4.4/demo/Polyhedron/Meshing_dialog.ui 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Meshing_dialog.ui 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,362 @@ + + + Meshing_dialog + + + true + + + + 0 + 0 + 414 + 355 + + + + Meshing criteria + + + + + + + 15 + 75 + true + + + + NO OBJECT + + + + + + + No size + + + + + + + Qt::RightToLeft + + + Sharp features + + + + + + &Protect sharp edges + + + true + + + + + + + + + + Qt::Vertical + + + QSizePolicy::MinimumExpanding + + + + 20 + 0 + + + + + + + + Surface + + + + + + Approximation &error + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + approx + + + + + + + + 110 + 0 + + + + + + + + Enable/Disable parameter + + + + + + true + + + + + + + &Facet max. size + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + facetSizing + + + + + + + + 110 + 0 + + + + 4 + + + + + + + Enable/Disable parameter + + + + + + true + + + + + + + Facet min. &angle (deg) + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + facetAngle + + + + + + + + 110 + 0 + + + + 1.000000000000000 + + + 30.000000000000000 + + + 25.000000000000000 + + + + + + + Enable/Disable parameter + + + + + + true + + + + + + + + + + Volume + + + + + + &Tetrahedron max. size + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + tetSizing + + + + + + + + 110 + 0 + + + + 4 + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Lucida Grande';">Tetrahedron &amp;shape</span><span style=" font-family:'Lucida Grande'; font-size:13pt;"> </span><span style=" font-family:'Lucida Grande'; font-style:italic;">(radius-edge ratio)</span></p></body></html> + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + tetShape + + + + + + + + 110 + 0 + + + + 1.000000000000000 + + + 3.000000000000000 + + + + + + + Enable/Disable parameter + + + + + + true + + + + + + + Enable/Disable parameter + + + + + + true + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + approx + noApprox + facetSizing + noFacetSizing + facetAngle + noAngle + tetSizing + noTetSizing + tetShape + noTetShape + buttonBox + + + + + buttonBox + accepted() + Meshing_dialog + accept() + + + 388 + 288 + + + 157 + 195 + + + + + buttonBox + rejected() + Meshing_dialog + reject() + + + 388 + 288 + + + 286 + 195 + + + + + diff -Nru cgal-4.4/demo/Polyhedron/Nef_type.h cgal-4.5/demo/Polyhedron/Nef_type.h --- cgal-4.4/demo/Polyhedron/Nef_type.h 2012-11-13 13:13:59.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Nef_type.h 2014-08-29 13:58:17.000000000 +0000 @@ -14,8 +14,7 @@ // Boolean operations work only with exact kernel #ifdef USE_FORWARD_DECL -// struct Exact_Kernel : public CGAL::Exact_predicates_exact_constructions_kernel {}; -struct Exact_Kernel : public CGAL::Simple_cartesian {}; +struct Exact_Kernel : public CGAL::Exact_predicates_exact_constructions_kernel {}; #else typedef CGAL::Exact_predicates_exact_constructions_kernel Exact_Kernel; #endif diff -Nru cgal-4.4/demo/Polyhedron/One_ring_iterators.h cgal-4.5/demo/Polyhedron/One_ring_iterators.h --- cgal-4.4/demo/Polyhedron/One_ring_iterators.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/One_ring_iterators.h 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,89 @@ +#ifndef ONE_RING_ITERATORS_H +#define ONE_RING_ITERATORS_H +#include "Polyhedron_type.h" +/***************************************************************/ +/* For iterating on one ring neighbor, sample usage: + Halfedge_handle h; //or Vertex_handle or Facet_handle + for(One_ring_iterator circ(h); circ; ++circ) { + Halfedge_handle h_neighbor = circ; + } +*/ +template +struct One_ring_iterator; + +template<> +struct One_ring_iterator { + One_ring_iterator(Polyhedron::Vertex_handle v) + : circ(v->vertex_begin()), end(circ), first(true) { } + + operator bool() const { return first || circ != end; } + operator Polyhedron::Vertex_handle() const { return circ->opposite()->vertex(); } + One_ring_iterator& operator++() { + first = false; + ++circ; + return *this; + } + + Polyhedron::Halfedge_around_vertex_circulator circ; + Polyhedron::Halfedge_around_vertex_circulator end; + bool first; + // to be used in One_ring_iterator + operator Polyhedron::Halfedge_handle() const { + if ( &*circ < &*circ->opposite() ) return circ; + return circ->opposite(); + } +}; + +template<> +struct One_ring_iterator { + One_ring_iterator(Polyhedron::Facet_handle f) + : circ(f->facet_begin()), end(circ), first(true) + { + iterate_to_non_border(); // move it to valid location + } + + operator bool() const { return first || circ != end; } + operator Polyhedron::Facet_handle() const { + CGAL_assertion(!circ->opposite()->is_border()); + return circ->opposite()->facet(); + } + One_ring_iterator& operator++() { + first = false; + ++circ; + if(circ != end) { iterate_to_non_border(); } + return *this; + } + + void iterate_to_non_border() { + while(circ->opposite()->is_border()) { + first = false; + ++circ; + if(circ == end) { break; } + } + } + Polyhedron::Halfedge_around_facet_circulator circ; + Polyhedron::Halfedge_around_facet_circulator end; + bool first; +}; + +template<> +struct One_ring_iterator { + One_ring_iterator(Polyhedron::Halfedge_handle h) + : it_1(h->vertex()), it_2(h->opposite()->vertex()) + { } + + operator bool() const { return it_1 || it_2; } + operator Polyhedron::Halfedge_handle() const { + if(it_1) { return it_1; } + return it_2; + } + One_ring_iterator& operator++() { + it_1 ? ++it_1 : ++it_2; + return *this; + } + + One_ring_iterator it_1; + One_ring_iterator it_2; +}; + +#endif diff -Nru cgal-4.4/demo/Polyhedron/opengl_tools.h cgal-4.5/demo/Polyhedron/opengl_tools.h --- cgal-4.4/demo/Polyhedron/opengl_tools.h 2013-03-07 20:00:26.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/opengl_tools.h 2014-08-29 13:58:17.000000000 +0000 @@ -25,7 +25,11 @@ #ifndef CGAL_OPENGL_TOOLS_H #define CGAL_OPENGL_TOOLS_H -#include +#ifdef CGAL_GLEW_ENABLED +# include +#else +# include +#endif namespace CGAL { namespace GL { diff -Nru cgal-4.4/demo/Polyhedron/Polyhedron_demo_convex_hull_plugin.cpp cgal-4.5/demo/Polyhedron/Polyhedron_demo_convex_hull_plugin.cpp --- cgal-4.4/demo/Polyhedron/Polyhedron_demo_convex_hull_plugin.cpp 2013-01-26 20:00:16.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Polyhedron_demo_convex_hull_plugin.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -3,15 +3,18 @@ #include #include +#include "opengl_tools.h" #include "Scene_polyhedron_item.h" #include "Scene_points_with_normal_item.h" #include "Scene_polylines_item.h" +#include "Scene_polyhedron_selection_item.h" #include "Polyhedron_type.h" #include "Polyhedron_demo_plugin_helper.h" #include "Polyhedron_demo_plugin_interface.h" #include +#include class Polyhedron_demo_convex_hull_plugin : public QObject, @@ -30,7 +33,8 @@ return qobject_cast(scene->item(scene->mainSelectionIndex())) || qobject_cast(scene->item(scene->mainSelectionIndex())) || - qobject_cast(scene->item(scene->mainSelectionIndex())); + qobject_cast(scene->item(scene->mainSelectionIndex())) || + qobject_cast(scene->item(scene->mainSelectionIndex())); } public slots: @@ -38,6 +42,12 @@ }; // end Polyhedron_demo_convex_hull_plugin +// for transform iterator +struct Get_point { + typedef const Polyhedron::Point_3& result_type; + result_type operator()(const Polyhedron::Vertex_handle v) const + { return v->point(); } +}; void Polyhedron_demo_convex_hull_plugin::on_actionConvexHull_triggered() { @@ -52,7 +62,10 @@ Scene_polylines_item* lines_item = qobject_cast(scene->item(index)); - if(poly_item || pts_item || lines_item) + Scene_polyhedron_selection_item* selection_item = + qobject_cast(scene->item(index)); + + if(poly_item || pts_item || lines_item || selection_item) { // wait cursor QApplication::setOverrideCursor(Qt::WaitCursor); @@ -63,7 +76,13 @@ // add convex hull as new polyhedron Polyhedron *pConvex_hull = new Polyhedron; - if ( poly_item ){ + if(selection_item) { + CGAL::convex_hull_3( + boost::make_transform_iterator(selection_item->selected_vertices.begin(), Get_point()), + boost::make_transform_iterator(selection_item->selected_vertices.end(), Get_point()), + *pConvex_hull); + } + else if ( poly_item ){ Polyhedron* pMesh = poly_item->polyhedron(); CGAL::convex_hull_3(pMesh->points_begin(),pMesh->points_end(),*pConvex_hull); } diff -Nru cgal-4.4/demo/Polyhedron/Polyhedron_demo_cut_plugin.cpp cgal-4.5/demo/Polyhedron/Polyhedron_demo_cut_plugin.cpp --- cgal-4.4/demo/Polyhedron/Polyhedron_demo_cut_plugin.cpp 2013-07-27 19:00:33.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Polyhedron_demo_cut_plugin.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -266,8 +266,8 @@ if(it == trees.end()) { it = trees.insert(trees.begin(), std::make_pair(poly_item, - new AABB_tree(poly_item->polyhedron()->facets_begin(), - poly_item->polyhedron()->facets_end(), + new AABB_tree(faces(*(poly_item->polyhedron())).first, + faces(*(poly_item->polyhedron())).second, *poly_item->polyhedron() ))); Scene_aabb_item* aabb_item = new Scene_aabb_item(*it->second); aabb_item->setName(tr("AABB tree of %1").arg(poly_item->name())); diff -Nru cgal-4.4/demo/Polyhedron/Polyhedron_demo_edit_polyhedron_plugin.cpp cgal-4.5/demo/Polyhedron/Polyhedron_demo_edit_polyhedron_plugin.cpp --- cgal-4.4/demo/Polyhedron/Polyhedron_demo_edit_polyhedron_plugin.cpp 2012-11-13 13:13:59.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Polyhedron_demo_edit_polyhedron_plugin.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -1,11 +1,14 @@ +#include "Polyhedron_demo_plugin_helper.h" #include "Scene_polyhedron_item.h" #include "Scene_edit_polyhedron_item.h" + #include #include -#include -#include +#include -#include "Polyhedron_demo_plugin_helper.h" +#include + +#include "ui_Deform_mesh.h" class Polyhedron_demo_edit_polyhedron_plugin : public QObject, @@ -16,113 +19,379 @@ public: Polyhedron_demo_edit_polyhedron_plugin() - : Polyhedron_demo_plugin_helper(), size(0) - {} + : Polyhedron_demo_plugin_helper(), dock_widget(NULL) + { } + ~Polyhedron_demo_edit_polyhedron_plugin() + { } void init(QMainWindow* mainWindow, Scene_interface* scene_interface); - QList actions() const { - return QList() << actionToggleEdit; - } + QList actions() const; + bool applicable() const; - //! Applicable if any of the currently selected items is either a Polyhedron or an Edit polyhedron - bool applicable() const { - Q_FOREACH(Scene_interface::Item_id i, scene->selectionIndices()) - { - if(qobject_cast(scene->item(i)) - || qobject_cast(scene->item(i))) - return true; - } - return false; - } public slots: - void on_actionToggleEdit_triggered(); - void edition(); + void on_actionDeformation_triggered(); + /////// Dock window signal handlers ////// + // what they do is simply transmiting required 'action' to selected scene_edit_polyhedron_item object + void on_AddCtrlVertPushButton_clicked(); + void on_PrevCtrlVertPushButton_clicked(); + void on_NextCtrlVertPushButton_clicked(); + void on_SelectAllVerticesPushButton_clicked(); + void on_DeleteCtrlVertPushButton_clicked(); + void on_ApplyAndClosePushButton_clicked(); + void on_ClearROIPushButton_clicked(); + void on_ShowROICheckBox_stateChanged(int state); + void on_ShowAsSphereCheckBox_stateChanged(int state); + void on_ActivatePivotingCheckBox_stateChanged(int state); + void on_OverwritePushButton_clicked(); + void on_SaveROIPushButton_clicked(); + void on_ReadROIPushButton_clicked(); + void dock_widget_visibility_changed(bool visible); + void on_Select_isolated_components_button_clicked(); + void on_Get_minimum_button_clicked(); + + void on_BrushSpinBoxCtrlVert_changed(int); + void on_BrushSpinBoxRoi_changed(int); + void on_ROIRadioButton_toggled(bool); + void new_item_created(int item_id); private: - QAction* actionToggleEdit; - int size; + typedef Scene_interface::Item_id Item_id; + + Scene_edit_polyhedron_item* convert_to_edit_polyhedron(Item_id, Scene_polyhedron_item*); + Scene_polyhedron_item* convert_to_plain_polyhedron(Item_id, Scene_edit_polyhedron_item*); + + Ui::DeformMesh ui_widget; + QDockWidget* dock_widget; + + QAction* actionDeformation; }; // end Polyhedron_demo_edit_polyhedron_plugin -void Polyhedron_demo_edit_polyhedron_plugin::init(QMainWindow* mainWindow, - Scene_interface* scene_interface) +QList Polyhedron_demo_edit_polyhedron_plugin::actions() const { + return QList() << actionDeformation; +} +bool Polyhedron_demo_edit_polyhedron_plugin::applicable() const { + Q_FOREACH(Scene_interface::Item_id i, scene->selectionIndices()) + { + if(qobject_cast(scene->item(i)) + || qobject_cast(scene->item(i))) + return true; + } + return false; +} + +void Polyhedron_demo_edit_polyhedron_plugin::init(QMainWindow* mainWindow, Scene_interface* scene_interface) { - actionToggleEdit = new QAction(tr("Toggle &edition of item(s)"), mainWindow); - actionToggleEdit->setObjectName("actionToggleEdit"); - Polyhedron_demo_plugin_helper::init(mainWindow, scene_interface); + mw = mainWindow; + scene = scene_interface; + + actionDeformation = new QAction("Surface Mesh Deformation", mw); + + actionDeformation->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_E)); + connect(actionDeformation, SIGNAL(triggered()), this, SLOT(on_actionDeformation_triggered())); + + // Connect Scene::newItem so that, if dock_widget is visible, convert + // automatically polyhedron items to "edit polyhedron" items. + QObject* scene = dynamic_cast(scene_interface); + if(scene) { + connect(scene, SIGNAL(newItem(int)), this, SLOT(new_item_created(int))); + } else { + std::cerr << "ERROR " << __FILE__ << ":" << __LINE__ << " :" + << " cannot convert scene_interface to scene!\n"; + } + + ////////////////// Construct widget ///////////////////////////// + // First time, construct docking window + dock_widget = new QDockWidget("Mesh Deformation", mw); + dock_widget->setVisible(false); // do not show at the beginning + + ui_widget.setupUi(dock_widget); + mw->addDockWidget(Qt::LeftDockWidgetArea, dock_widget); + + connect(ui_widget.AddCtrlVertPushButton, SIGNAL(clicked()), this, SLOT(on_AddCtrlVertPushButton_clicked())); + connect(ui_widget.PrevCtrlVertPushButton, SIGNAL(clicked()), this, SLOT(on_PrevCtrlVertPushButton_clicked())); + connect(ui_widget.NextCtrlVertPushButton, SIGNAL(clicked()), this, SLOT(on_NextCtrlVertPushButton_clicked())); + connect(ui_widget.SelectAllVerticesPushButton, SIGNAL(clicked()), this, SLOT(on_SelectAllVerticesPushButton_clicked())); + connect(ui_widget.DeleteCtrlVertPushButton, SIGNAL(clicked()), this, SLOT(on_DeleteCtrlVertPushButton_clicked())); + connect(ui_widget.ApplyAndClosePushButton, SIGNAL(clicked()), this, SLOT(on_ApplyAndClosePushButton_clicked())); + connect(ui_widget.ClearROIPushButton, SIGNAL(clicked()), this, SLOT(on_ClearROIPushButton_clicked())); + connect(ui_widget.ShowROICheckBox, SIGNAL(stateChanged(int)), this, SLOT(on_ShowROICheckBox_stateChanged(int))); + connect(ui_widget.ShowAsSphereCheckBox, SIGNAL(stateChanged(int)), this, SLOT(on_ShowAsSphereCheckBox_stateChanged(int))); + connect(ui_widget.ActivatePivotingCheckBox, SIGNAL(stateChanged(int)), this, SLOT(on_ActivatePivotingCheckBox_stateChanged(int))); + connect(ui_widget.OverwritePushButton, SIGNAL(clicked()), this, SLOT(on_OverwritePushButton_clicked())); + connect(ui_widget.Select_isolated_components_button, SIGNAL(clicked()), this, SLOT(on_Select_isolated_components_button_clicked())); + connect(ui_widget.Get_minimum_button, SIGNAL(clicked()), this, SLOT(on_Get_minimum_button_clicked())); + + connect(ui_widget.SaveROIPushButton, SIGNAL(clicked()), this, SLOT(on_SaveROIPushButton_clicked())); + connect(ui_widget.ReadROIPushButton, SIGNAL(clicked()), this, SLOT(on_ReadROIPushButton_clicked())); + connect(dock_widget, SIGNAL(visibilityChanged(bool)), this, SLOT(dock_widget_visibility_changed(bool)) ); + + connect(ui_widget.BrushSpinBoxRoi, SIGNAL(valueChanged(int)), this, SLOT(on_BrushSpinBoxRoi_changed(int))); + connect(ui_widget.BrushSpinBoxCtrlVert, SIGNAL(valueChanged(int)), this, SLOT(on_BrushSpinBoxCtrlVert_changed(int))); + connect(ui_widget.ROIRadioButton, SIGNAL(toggled(bool)), this, SLOT(on_ROIRadioButton_toggled(bool))); + /////////////////////////////////////////////////////////////////// } -void Polyhedron_demo_edit_polyhedron_plugin::on_actionToggleEdit_triggered() { - bool found_polyhedron = false; - bool edit_needed = false; - QList changed_items; - Q_FOREACH(Scene_interface::Item_id i, scene->selectionIndices()) +void Polyhedron_demo_edit_polyhedron_plugin::on_actionDeformation_triggered() +{ + // dock widget should be constructed in init() + if(dock_widget->isVisible()) { dock_widget->hide(); } + else { dock_widget->show(); } +} + +/////// Dock window signal handlers ////// +// what they do is simply transmitting required 'action' to selected scene_edit_polyhedron_item object +void Polyhedron_demo_edit_polyhedron_plugin::on_AddCtrlVertPushButton_clicked() +{ + int item_id = scene->mainSelectionIndex(); + Scene_edit_polyhedron_item* edit_item = qobject_cast(scene->item(item_id)); + if(!edit_item) return; // the selected item is not of the right type + + edit_item->create_ctrl_vertices_group(); +} +void Polyhedron_demo_edit_polyhedron_plugin::on_PrevCtrlVertPushButton_clicked() +{ + int item_id = scene->mainSelectionIndex(); + Scene_edit_polyhedron_item* edit_item = qobject_cast(scene->item(item_id)); + if(!edit_item) return; // the selected item is not of the right type + + edit_item->prev_ctrl_vertices_group(); + scene->itemChanged(edit_item); // for repaint +} +void Polyhedron_demo_edit_polyhedron_plugin::on_NextCtrlVertPushButton_clicked() +{ + int item_id = scene->mainSelectionIndex(); + Scene_edit_polyhedron_item* edit_item = qobject_cast(scene->item(item_id)); + if(!edit_item) return; // the selected item is not of the right type + + edit_item->next_ctrl_vertices_group(); + scene->itemChanged(edit_item); // for repaint +} +void Polyhedron_demo_edit_polyhedron_plugin::on_SelectAllVerticesPushButton_clicked() +{ + int item_id = scene->mainSelectionIndex(); + Scene_edit_polyhedron_item* edit_item = qobject_cast(scene->item(item_id)); + if(!edit_item) return; // the selected item is not of the right type + + edit_item->set_all_vertices_as_roi(); + scene->itemChanged(edit_item); // for repaint +} +void Polyhedron_demo_edit_polyhedron_plugin::on_DeleteCtrlVertPushButton_clicked() +{ + int item_id = scene->mainSelectionIndex(); + Scene_edit_polyhedron_item* edit_item = qobject_cast(scene->item(item_id)); + if(!edit_item) return; // the selected item is not of the right type + + edit_item->delete_ctrl_vertices_group(); + scene->itemChanged(edit_item); // for repaint +} +void Polyhedron_demo_edit_polyhedron_plugin::on_ClearROIPushButton_clicked() +{ + int item_id = scene->mainSelectionIndex(); + Scene_edit_polyhedron_item* edit_item = qobject_cast(scene->item(item_id)); + if(!edit_item) return; // the selected item is not of the right type + + edit_item->clear_roi(); + scene->itemChanged(edit_item); // for repaint +} +void Polyhedron_demo_edit_polyhedron_plugin::on_ApplyAndClosePushButton_clicked() +{ + dock_widget->setVisible(false); +} +void Polyhedron_demo_edit_polyhedron_plugin::on_ShowROICheckBox_stateChanged(int /*state*/) +{ + for(Scene_interface::Item_id i = 0, end = scene->numberOfEntries(); i < end; ++i) + { + Scene_edit_polyhedron_item* edit_item = qobject_cast(scene->item(i)); + if(!edit_item) { continue; } + + scene->itemChanged(edit_item); // just for redraw + } +} +void Polyhedron_demo_edit_polyhedron_plugin::on_ShowAsSphereCheckBox_stateChanged(int /*state*/) +{ + for(Scene_interface::Item_id i = 0, end = scene->numberOfEntries(); i < end; ++i) + { + Scene_edit_polyhedron_item* edit_item = qobject_cast(scene->item(i)); + if(!edit_item) { continue; } + + scene->itemChanged(edit_item); // just for redraw + } +} +void Polyhedron_demo_edit_polyhedron_plugin::on_ActivatePivotingCheckBox_stateChanged(int state) +{ + for(Scene_interface::Item_id i = 0, end = scene->numberOfEntries(); i < end; ++i) { - if(Scene_polyhedron_item* poly_item = - qobject_cast(scene->item(i))) - { - found_polyhedron = true; - Scene_edit_polyhedron_item* edit_poly = - new Scene_edit_polyhedron_item(poly_item); - edit_poly->setColor(poly_item->color()); - edit_poly->setName(QString("%1 (edit)").arg(poly_item->name())); - scene->replaceItem(i, edit_poly); - changed_items.push_back(scene->item(i)); - edit_needed = true; - connect(edit_poly, SIGNAL(modified()), - this, SLOT(edition())); - } else if(Scene_edit_polyhedron_item* poly_item = - qobject_cast(scene->item(i))) - { - found_polyhedron = true; - scene->replaceItem(i, poly_item->to_polyhedron_item()); - delete poly_item; + Scene_edit_polyhedron_item* edit_item = qobject_cast(scene->item(i)); + if(!edit_item) { continue; } + + if(state == Qt::Checked) { + edit_item->pivoting_begin(); + } + else { + edit_item->pivoting_end(); } + scene->itemChanged(edit_item); } - if(found_polyhedron == false) { - QMessageBox::warning(mw, tr("Warning"), - tr("No polyhedron was selected")); - } - if(edit_needed) { - size = QInputDialog::getInt(mw, - tr("Polyhedron edition zone"), - tr("Size of edition zone:"), - size /* default value */ , - 0 /* min */ ); - std::cerr << "size = " << size << std::endl; - Q_FOREACH(Scene_item* item, changed_items) - { - Scene_edit_polyhedron_item* poly_edit_item = - qobject_cast(item); - if(poly_edit_item) poly_edit_item->setZoneSize(size); +} +void Polyhedron_demo_edit_polyhedron_plugin::on_OverwritePushButton_clicked() +{ + int item_id = scene->mainSelectionIndex(); + Scene_edit_polyhedron_item* edit_item = qobject_cast(scene->item(item_id)); + if(!edit_item) return; // the selected item is not of the right type + + edit_item->overwrite_deform_object(); +} +void Polyhedron_demo_edit_polyhedron_plugin::on_Select_isolated_components_button_clicked() { + int item_id = scene->mainSelectionIndex(); + Scene_edit_polyhedron_item* edit_item = qobject_cast(scene->item(item_id)); + if(!edit_item) return; // the selected item is not of the right type + + boost::optional minimum = + edit_item->select_isolated_components(ui_widget.Threshold_size_spin_box->value()); + if(minimum) { + ui_widget.Threshold_size_spin_box->setValue((int) *minimum); + } +} + +void Polyhedron_demo_edit_polyhedron_plugin::on_Get_minimum_button_clicked() { + int item_id = scene->mainSelectionIndex(); + Scene_edit_polyhedron_item* edit_item = qobject_cast(scene->item(item_id)); + if(!edit_item) return; // the selected item is not of the right type + + boost::optional minimum = edit_item->get_minimum_isolated_component(); + if(minimum) { + ui_widget.Threshold_size_spin_box->setValue((int) *minimum); + } +} + +void Polyhedron_demo_edit_polyhedron_plugin::on_SaveROIPushButton_clicked() +{ + int item_id = scene->mainSelectionIndex(); + Scene_edit_polyhedron_item* edit_item = qobject_cast(scene->item(item_id)); + if(!edit_item) return; + + QString fileName = QFileDialog::getSaveFileName(mw, "Save", + "roi.txt", "Text (*.txt)"); + if(fileName.isNull()) { return; } + + edit_item->save_roi(fileName.toLocal8Bit().data()); +} +void Polyhedron_demo_edit_polyhedron_plugin::on_ReadROIPushButton_clicked() +{ + int item_id = scene->mainSelectionIndex(); + Scene_edit_polyhedron_item* edit_item = qobject_cast(scene->item(item_id)); + if(!edit_item) return; + + QString fileName = QFileDialog::getOpenFileName(mw, "Read", + "roi.txt", "Text (*.txt)"); + if(fileName.isNull()) { return; } + + edit_item->read_roi(fileName.toLocal8Bit().data()); + scene->itemChanged(edit_item); +} +void Polyhedron_demo_edit_polyhedron_plugin::dock_widget_visibility_changed(bool visible) +{ + for(Scene_interface::Item_id i = 0, end = scene->numberOfEntries(); + i < end; ++i) + { + Scene_polyhedron_item* poly_item = qobject_cast(scene->item(i)); + if (poly_item) + { poly_item->update_halfedge_indices(); } + Scene_edit_polyhedron_item* edit_item = qobject_cast(scene->item(i)); + + if(visible && poly_item) { + convert_to_edit_polyhedron(i, poly_item); + } else if(!visible && edit_item) { + convert_to_plain_polyhedron(i, edit_item); } } + + //QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + //if(visible) + //{ + // viewer->camera()->setType(qglviewer::Camera::ORTHOGRAPHIC); + //}else + //{ + // viewer->camera()->setType(qglviewer::Camera::PERSPECTIVE); + //} } -void Polyhedron_demo_edit_polyhedron_plugin::edition() { - QObject* obj = sender(); - Scene_edit_polyhedron_item* edit_item = - qobject_cast(obj); - if(!edit_item) { - std::cerr << "ERROR" << __FILE__ << ":" << __LINE__ - << " : " << "unknown object type" << std::endl; - return; + +void Polyhedron_demo_edit_polyhedron_plugin::on_ROIRadioButton_toggled(bool value) { + int k_ring = value ? ui_widget.BrushSpinBoxRoi->value() : + ui_widget.BrushSpinBoxCtrlVert->value(); + for(Scene_interface::Item_id i = 0, end = scene->numberOfEntries(); i < end; ++i) + { + Scene_edit_polyhedron_item* edit_item = qobject_cast(scene->item(i)); + if(!edit_item) { continue; } + + edit_item->set_k_ring(k_ring); } +} - typedef Kernel::Point_3 Point; - typedef Kernel::Vector_3 Vector; - typedef Polyhedron::Vertex_handle Vertex_handle; +void Polyhedron_demo_edit_polyhedron_plugin::on_BrushSpinBoxCtrlVert_changed(int value) { + if(ui_widget.ROIRadioButton->isChecked()) { return; } + for(Scene_interface::Item_id i = 0, end = scene->numberOfEntries(); i < end; ++i) + { + Scene_edit_polyhedron_item* edit_item = qobject_cast(scene->item(i)); + if(!edit_item) { continue; } - const Point& orig = edit_item->original_position(); - const Vector move_vector = edit_item->current_position() - orig; + edit_item->set_k_ring(value); + } +} - Q_FOREACH(Vertex_handle vh, edit_item->selected_vertices()) +void Polyhedron_demo_edit_polyhedron_plugin::on_BrushSpinBoxRoi_changed(int value) { + if(!ui_widget.ROIRadioButton->isChecked()) { return; } + for(Scene_interface::Item_id i = 0, end = scene->numberOfEntries(); i < end; ++i) { - vh->point() = vh->point() + move_vector; + Scene_edit_polyhedron_item* edit_item = qobject_cast(scene->item(i)); + if(!edit_item) { continue; } + + edit_item->set_k_ring(value); } - edit_item->changed(); // that reset the original_position() - scene->itemChanged(edit_item); } +void Polyhedron_demo_edit_polyhedron_plugin::new_item_created(int item_id) +{ + if(dock_widget->isVisible()) { + Scene_polyhedron_item* poly_item = + qobject_cast(scene->item(item_id)); + if(poly_item) { + convert_to_edit_polyhedron(item_id, poly_item); + } + } +} + +Scene_edit_polyhedron_item* +Polyhedron_demo_edit_polyhedron_plugin::convert_to_edit_polyhedron(Item_id i, + Scene_polyhedron_item* poly_item) +{ + QString poly_item_name = poly_item->name(); + Scene_edit_polyhedron_item* edit_poly = new Scene_edit_polyhedron_item(poly_item, &ui_widget, mw); + edit_poly->setColor(poly_item->color()); + edit_poly->setName(QString("%1 (edit)").arg(poly_item->name())); + edit_poly->setRenderingMode(Gouraud); + poly_item->setName(poly_item_name); // Because it is changed when the + // name of edit_poly is changed. + int k_ring = ui_widget.ROIRadioButton->isChecked() ? ui_widget.BrushSpinBoxRoi->value() : + ui_widget.BrushSpinBoxCtrlVert->value(); + edit_poly->set_k_ring(k_ring); + scene->replaceItem(i, edit_poly); + return edit_poly; +} + +Scene_polyhedron_item* +Polyhedron_demo_edit_polyhedron_plugin::convert_to_plain_polyhedron(Item_id i, + Scene_edit_polyhedron_item* edit_item) +{ + Scene_polyhedron_item* poly_item = edit_item->to_polyhedron_item(); + scene->replaceItem(i, poly_item); + delete edit_item; + return poly_item; +} + + + Q_EXPORT_PLUGIN2(Polyhedron_demo_edit_polyhedron_plugin, Polyhedron_demo_edit_polyhedron_plugin) #include "Polyhedron_demo_edit_polyhedron_plugin.moc" diff -Nru cgal-4.4/demo/Polyhedron/Polyhedron_demo_join_and_split_polyhedra_plugin.cpp cgal-4.5/demo/Polyhedron/Polyhedron_demo_join_and_split_polyhedra_plugin.cpp --- cgal-4.4/demo/Polyhedron/Polyhedron_demo_join_and_split_polyhedra_plugin.cpp 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Polyhedron_demo_join_and_split_polyhedra_plugin.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,134 @@ +#include +#include +#include +#include "Kernel_type.h" +#include "Polyhedron_type.h" +#include "Scene_polyhedron_item.h" +#include "Scene_polylines_item.h" +#include "Messages_interface.h" + +#include "Polyhedron_demo_plugin_helper.h" +#include "Polyhedron_demo_plugin_interface.h" + +#include +#include + +#include +#include + +class Polyhedron_demo_join_and_split_polyhedra_plugin: + public QObject, + public Polyhedron_demo_plugin_helper +{ + Q_OBJECT + Q_INTERFACES(Polyhedron_demo_plugin_interface) + QAction* actionJoinPolyhedra, *actionSplitPolyhedra; + Messages_interface* msg_interface; +public: + QList actions() const { return QList() << actionJoinPolyhedra << actionSplitPolyhedra; } + using Polyhedron_demo_plugin_helper::init; + void init(QMainWindow* mainWindow, Scene_interface* scene_interface, Messages_interface* m) + { + msg_interface = m; + actionJoinPolyhedra= new QAction(tr("Join selected polyhedra"), mainWindow); + actionJoinPolyhedra->setObjectName("actionJoinPolyhedra"); + actionSplitPolyhedra= new QAction(tr("Split selected polyhedra"), mainWindow); + actionSplitPolyhedra->setObjectName("actionSplitPolyhedra"); + Polyhedron_demo_plugin_helper::init(mainWindow, scene_interface); + } + + bool applicable() const { + Q_FOREACH(int index, scene->selectionIndices()) + { + if ( qobject_cast(scene->item(index)) ) + return true; + } + return false; + } + +public slots: + void on_actionJoinPolyhedra_triggered(); + void on_actionSplitPolyhedra_triggered(); + +}; // end Polyhedron_demo_polyhedron_stitching_plugin + +void Polyhedron_demo_join_and_split_polyhedra_plugin::on_actionJoinPolyhedra_triggered() +{ + Scene_interface::Item_id mainSelectionIndex = -1; + Scene_polyhedron_item* mainSelectionItem = NULL; + + + QList indices_to_remove; + Q_FOREACH(int index, scene->selectionIndices()) { + if (mainSelectionIndex==-1){ + mainSelectionItem = + qobject_cast(scene->item(index)); + if(mainSelectionItem!=NULL) mainSelectionIndex=index; + continue; + } + + Scene_polyhedron_item* item = + qobject_cast(scene->item(index)); + if(item) + { + indices_to_remove.push_front(index); + CGAL::Polyhedron_copy_3 + modifier( *(item->polyhedron()) ); + mainSelectionItem->polyhedron()->delegate(modifier); + } + } + + scene->itemChanged(mainSelectionIndex); + + //remove the other items + Q_FOREACH(int index, indices_to_remove) + { + scene->erase(index); + } +} + +struct Polyhedron_appender{ + Polyhedron_appender(std::list& new_polyhedra): + m_new_polyhedra(new_polyhedra) {} + void operator()(const Polyhedron& p){ + m_new_polyhedra.push_back( new Polyhedron(p) ); + } + std::list& m_new_polyhedra; +}; + +void Polyhedron_demo_join_and_split_polyhedra_plugin::on_actionSplitPolyhedra_triggered() +{ + Q_FOREACH(int index, scene->selectionIndices()) { + Scene_polyhedron_item* item = + qobject_cast(scene->item(index)); + if(item) + { + std::list new_polyhedra; + CGAL::internal::extract_connected_components( + *item->polyhedron(), + boost::make_function_output_iterator(Polyhedron_appender(new_polyhedra)) + ); + + if (new_polyhedra.size()==1) + { + delete new_polyhedra.front(); + msg_interface->information( tr("%1 has only one connected component").arg(item->name()) ); + continue; + } + + int cc=0; + BOOST_FOREACH(Polyhedron* polyhedron_ptr, new_polyhedra) + { + Scene_polyhedron_item* new_item=new Scene_polyhedron_item(polyhedron_ptr); + new_item->setName(tr("%1 - CC %2").arg(item->name()).arg(cc)); + ++cc; + scene->addItem(new_item); + } + item->setVisible(false); + } + } +} + +Q_EXPORT_PLUGIN2(Polyhedron_demo_join_and_split_polyhedra_plugin, Polyhedron_demo_join_and_split_polyhedra_plugin) + +#include "Polyhedron_demo_join_and_split_polyhedra_plugin.moc" diff -Nru cgal-4.4/demo/Polyhedron/Polyhedron_demo_kernel_plugin.cpp cgal-4.5/demo/Polyhedron/Polyhedron_demo_kernel_plugin.cpp --- cgal-4.4/demo/Polyhedron/Polyhedron_demo_kernel_plugin.cpp 2012-11-13 13:13:59.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Polyhedron_demo_kernel_plugin.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -11,7 +11,7 @@ #include "Polyhedron_demo_plugin_interface.h" #include -#include +#include #include #include @@ -58,7 +58,7 @@ { Polyhedron* pMesh = item->polyhedron(); - typedef CGAL::Gmpzf ET; // choose exact integral type + typedef CGAL::Exact_integer ET; // choose exact integral type typedef Polyhedron_kernel Polyhedron_kernel; // get triangles from polyhedron diff -Nru cgal-4.4/demo/Polyhedron/Polyhedron_demo_mesh_3_plugin_cgal_code.cpp cgal-4.5/demo/Polyhedron/Polyhedron_demo_mesh_3_plugin_cgal_code.cpp --- cgal-4.4/demo/Polyhedron/Polyhedron_demo_mesh_3_plugin_cgal_code.cpp 2012-11-13 13:13:59.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Polyhedron_demo_mesh_3_plugin_cgal_code.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -7,7 +7,7 @@ #include #include -#include +#include #include #include @@ -15,8 +15,8 @@ #include -// @TODO: Is that the right kernel?! -typedef CGAL::Polyhedral_mesh_domain_3 Mesh_domain; +typedef CGAL::Polyhedral_mesh_domain_with_features_3 Mesh_domain; // Triangulation typedef CGAL::Mesh_triangulation_3::type Tr; @@ -26,6 +26,7 @@ // Mesh Criteria typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef Mesh_criteria::Edge_criteria Edge_criteria; typedef Mesh_criteria::Facet_criteria Facet_criteria; typedef Mesh_criteria::Cell_criteria Cell_criteria; @@ -133,7 +134,7 @@ // Indicate if rendering mode is supported bool supportsRenderingMode(RenderingMode m) const { - return (m != Gouraud && m!=PointsPlusNormals); // CHECK THIS! + return (m != Gouraud && m!=PointsPlusNormals && m!=Splatting); // CHECK THIS! } void draw() const { @@ -279,37 +280,48 @@ }; Scene_item* cgal_code_mesh_3(const Polyhedron* pMesh, - const QString filename, + QString filename, const double angle, - const double sizing, + const double facet_sizing, const double approx, - const double tets_sizing) + const double tet_sizing, + const double tet_shape, + const bool protect_features) { if(!pMesh) return 0; // remesh // Set mesh criteria - Facet_criteria facet_criteria(angle, sizing, approx); // angle, size, approximation - Cell_criteria cell_criteria(4, tets_sizing); // radius-edge ratio, size - Mesh_criteria criteria(facet_criteria, cell_criteria); + Edge_criteria edge_criteria(facet_sizing); + Facet_criteria facet_criteria(angle, facet_sizing, approx); // angle, size, approximation + Cell_criteria cell_criteria(tet_shape, tet_sizing); // radius-edge ratio, size + Mesh_criteria criteria(edge_criteria, facet_criteria, cell_criteria); CGAL::Timer timer; timer.start(); std::cerr << "Meshing file \"" << qPrintable(filename) << "\"\n"; std::cerr << " angle: " << angle << std::endl - << " facets size bound: " << sizing << std::endl + << " facets size bound: " << facet_sizing << std::endl << " approximation bound: " << approx << std::endl - << " tetrahedra size bound: " << tets_sizing << std::endl; + << " tetrahedra size bound: " << tet_sizing << std::endl; std::cerr << "Build AABB tree..."; // Create domain Mesh_domain domain(*pMesh); + if(protect_features) { + domain.detect_features(); + } std::cerr << "done (" << timer.time() << " ms)" << std::endl; // Meshing std::cerr << "Mesh..."; + CGAL::parameters::internal::Features_options features = + protect_features ? + CGAL::parameters::features(domain) : + CGAL::parameters::no_features(); + Scene_c3t3_item* new_item = - new Scene_c3t3_item(CGAL::make_mesh_3(domain, criteria)); + new Scene_c3t3_item(CGAL::make_mesh_3(domain, criteria, features)); std::cerr << "done (" << timer.time() << " ms, " << new_item->c3t3().triangulation().number_of_vertices() << " vertices)" << std::endl; diff -Nru cgal-4.4/demo/Polyhedron/Polyhedron_demo_mesh_3_plugin.cpp cgal-4.5/demo/Polyhedron/Polyhedron_demo_mesh_3_plugin.cpp --- cgal-4.4/demo/Polyhedron/Polyhedron_demo_mesh_3_plugin.cpp 2012-11-13 13:13:59.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Polyhedron_demo_mesh_3_plugin.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -12,6 +12,7 @@ #include #include #include +#include "ui_Meshing_dialog.h" // declare the CGAL function Scene_item* cgal_code_mesh_3(const Polyhedron*, @@ -19,7 +20,9 @@ const double angle, const double sizing, const double approx, - const double tets_sizing); + const double tets_sizing, + const double tet_shape, + const bool protect_features); class Polyhedron_demo_mesh_3_plugin : public QObject, @@ -53,6 +56,20 @@ QAction* actionMesh_3; }; // end class Polyhedron_demo_mesh_3_plugin +double +get_approximate(double d, int precision, int& decimals) +{ + if ( d<0 ) { return 0; } + + double i = std::pow(10.,precision-1); + + decimals = 0; + while ( d > i*10 ) { d = d/10.; ++decimals; } + while ( d < i ) { d = d*10.; --decimals; } + + return std::floor(d)*std::pow(10.,decimals); +} + void Polyhedron_demo_mesh_3_plugin::mesh_3() { const Scene_interface::Item_id index = scene->mainSelectionIndex(); @@ -60,77 +77,107 @@ Scene_polyhedron_item* item = qobject_cast(scene->item(index)); - if(item) - { - Polyhedron* pMesh = item->polyhedron(); - - if(!pMesh) return; - - // TODO: get parameters using ONE dialog box - // sizing and approximation parameters should be expressed as ratio of - // scene bbox diagonal. - - double diag = scene->len_diagonal(); - - bool ok; - const double angle = - QInputDialog::getDouble(mw, tr("Min triangle angle"), - tr("Angle:"), - 25., // default value - 1., // min - 30., // max - 2, // decimals - &ok); - if(!ok) return; - - const double sizing = - QInputDialog::getDouble(mw, "Facets sizing", - "Facets size bound:", - diag * 0.05, // default value - diag * 10e-6, // min - diag, // max - 4, // decimals - &ok); - if(!ok) return; - - const double tets_sizing = - QInputDialog::getDouble(mw, "Tetrahedra sizing", - "Tetrahedra size bound:", - diag * 0.05, // default value - diag * 10e-6, // min - diag, // max - 4, // decimals - &ok); - if(!ok) return; - - const double approx = - QInputDialog::getDouble(mw, "Approximation error", - "Error:", - diag * 0.005, // default value - diag * 10e-7, // min - diag, // max - 6, // decimals - &ok); - if(!ok) return; - - QApplication::setOverrideCursor(Qt::WaitCursor); - - Scene_item* result_item = cgal_code_mesh_3(pMesh, item->name(), angle, sizing, approx, tets_sizing); - if(result_item) { - result_item->setName(tr("%1 3d mesh (%2 %3 %4 %5)") - .arg(item->name()) - .arg(angle) - .arg(sizing) - .arg(tets_sizing) - .arg(approx)); - result_item->setColor(Qt::magenta); - result_item->setRenderingMode(item->renderingMode()); - item->setVisible(false); - scene->itemChanged(index); - scene->addItem(result_item); - } - QApplication::restoreOverrideCursor(); + if(!item) return; + + Polyhedron* pMesh = item->polyhedron(); + + if(!pMesh) return; + + // ----------------------------------- + // Create Mesh dialog + // ----------------------------------- + QDialog dialog(mw); + Ui::Meshing_dialog ui; + ui.setupUi(&dialog); + connect(ui.buttonBox, SIGNAL(accepted()), + &dialog, SLOT(accept())); + connect(ui.buttonBox, SIGNAL(rejected()), + &dialog, SLOT(reject())); + + // Connect checkboxes to spinboxes + connect(ui.noApprox, SIGNAL(toggled(bool)), + ui.approx, SLOT(setEnabled(bool))); + + connect(ui.noFacetSizing, SIGNAL(toggled(bool)), + ui.facetSizing, SLOT(setEnabled(bool))); + + connect(ui.noAngle, SIGNAL(toggled(bool)), + ui.facetAngle, SLOT(setEnabled(bool))); + + connect(ui.noTetSizing, SIGNAL(toggled(bool)), + ui.tetSizing, SLOT(setEnabled(bool))); + + connect(ui.noTetShape, SIGNAL(toggled(bool)), + ui.tetShape, SLOT(setEnabled(bool))); + + // Set default parameters + Scene_interface::Bbox bbox = item->bbox(); + ui.objectName->setText(item->name()); + ui.objectNameSize->setText(tr("Object bbox size (w,h,d): %1, %2, %3") + .arg(bbox.width(),0,'g',3) + .arg(bbox.height(),0,'g',3) + .arg(bbox.depth(),0,'g',3) ); + + double diag = bbox.diagonal_length(); + int decimals = 0; + double sizing_default = get_approximate(diag * 0.05, 2, decimals); + ui.facetSizing->setDecimals(-decimals+2); + ui.facetSizing->setSingleStep(std::pow(10.,decimals)); + ui.facetSizing->setRange(diag * 10e-6, // min + diag); // max + ui.facetSizing->setValue(sizing_default); // default value + + ui.tetSizing->setDecimals(-decimals+2); + ui.tetSizing->setSingleStep(std::pow(10.,decimals)); + ui.tetSizing->setRange(diag * 10e-6, // min + diag); // max + ui.tetSizing->setValue(sizing_default); // default value + + double approx_default = get_approximate(diag * 0.005, 2, decimals); + ui.approx->setDecimals(-decimals+2); + ui.approx->setSingleStep(std::pow(10.,decimals)); + ui.approx->setRange(diag * 10e-7, // min + diag); // max + ui.approx->setValue(approx_default); + + // ----------------------------------- + // Get values + // ----------------------------------- + int i = dialog.exec(); + if( i == QDialog::Rejected ) { return; } + + // 0 means parameter is not considered + const double angle = !ui.noAngle->isChecked() ? 0 : ui.facetAngle->value(); + const double approx = !ui.noApprox->isChecked() ? 0 : ui.approx->value(); + const double facet_sizing = !ui.noFacetSizing->isChecked() ? 0 : ui.facetSizing->value(); + const double radius_edge = !ui.noTetShape->isChecked() ? 0 : ui.tetShape->value(); + const double tet_sizing = !ui.noTetSizing->isChecked() ? 0 : ui.tetSizing->value(); + const bool protect_features = ui.protect->isChecked(); + + QApplication::setOverrideCursor(Qt::WaitCursor); + + Scene_item* result_item = cgal_code_mesh_3(pMesh, + item->name(), + angle, + facet_sizing, + approx, + tet_sizing, + radius_edge, + protect_features); + if(result_item) { + result_item->setName(tr("%1 3d mesh (%2 %3 %4 %5)") + .arg(item->name()) + .arg(angle) + .arg(facet_sizing) + .arg(tet_sizing) + .arg(approx)); + result_item->setColor(Qt::magenta); + result_item->setRenderingMode(item->renderingMode()); + item->setVisible(false); + scene->itemChanged(index); + scene->addItem(result_item); } + QApplication::restoreOverrideCursor(); } Q_EXPORT_PLUGIN2(Polyhedron_demo_mesh_3_plugin, Polyhedron_demo_mesh_3_plugin) diff -Nru cgal-4.4/demo/Polyhedron/Polyhedron_demo_mesh_simplification_plugin.cpp cgal-4.5/demo/Polyhedron/Polyhedron_demo_mesh_simplification_plugin.cpp --- cgal-4.4/demo/Polyhedron/Polyhedron_demo_mesh_simplification_plugin.cpp 2012-11-13 13:13:59.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Polyhedron_demo_mesh_simplification_plugin.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -68,8 +68,8 @@ namespace SMS = CGAL::Surface_mesh_simplification; SMS::Count_stop_predicate< Polyhedron > stop(nb_edges); // target #edges SMS::edge_collapse( *pMesh, stop, - CGAL::vertex_index_map(boost::get(CGAL::vertex_external_index,*pMesh)) - .edge_index_map(boost::get(CGAL::edge_external_index,*pMesh))); + CGAL::vertex_index_map(get(CGAL::vertex_external_index,*pMesh)) + .halfedge_index_map(get(CGAL::halfedge_external_index,*pMesh))); std::cout << "ok (" << time.elapsed() << " ms, " << pMesh->size_of_halfedges() / 2 << " edges)" << std::endl; diff -Nru cgal-4.4/demo/Polyhedron/Polyhedron_demo_normal_estimation_plugin.cpp cgal-4.5/demo/Polyhedron/Polyhedron_demo_normal_estimation_plugin.cpp --- cgal-4.4/demo/Polyhedron/Polyhedron_demo_normal_estimation_plugin.cpp 2013-07-06 19:00:27.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Polyhedron_demo_normal_estimation_plugin.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -169,6 +169,12 @@ CGAL::make_normal_of_point_with_normal_pmap(Point_set::value_type()), dialog.orientationNbNeighbors()); + //indicates that the point set has normals + if (first_unoriented_point!=points->begin()){ + item->set_has_normals(true); + item->setRenderingMode(PointsPlusNormals); + } + std::size_t nb_unoriented_normals = std::distance(first_unoriented_point, points->end()); std::size_t memory = CGAL::Memory_sizer().virtual_size(); std::cerr << "Orient normals: " << nb_unoriented_normals << " point(s) with an unoriented normal are selected (" diff -Nru cgal-4.4/demo/Polyhedron/Polyhedron_demo_off_to_xyz_plugin.cpp cgal-4.5/demo/Polyhedron/Polyhedron_demo_off_to_xyz_plugin.cpp --- cgal-4.4/demo/Polyhedron/Polyhedron_demo_off_to_xyz_plugin.cpp 2012-11-13 13:13:59.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Polyhedron_demo_off_to_xyz_plugin.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -1,6 +1,9 @@ #include "Scene_points_with_normal_item.h" - +#include "Polyhedron_type.h" #include "Polyhedron_demo_io_plugin_interface.h" + +#include + #include class Polyhedron_demo_off_to_xyz_plugin : @@ -30,12 +33,22 @@ if(!in) std::cerr << "Error!\n"; - Scene_points_with_normal_item* item = new Scene_points_with_normal_item(); - if(!item->read_off_point_set(in)) - { - delete item; - return 0; + Scene_points_with_normal_item* item; + + Polyhedron p; + in >> p; + if (in && !p.empty()) + item = new Scene_points_with_normal_item(p); + else{ + in.close(); + in.open(fileinfo.filePath().toUtf8()); + item = new Scene_points_with_normal_item(); + if(!item->read_off_point_set(in)) + { + delete item; + return 0; + } } item->setName(fileinfo.baseName()); diff -Nru cgal-4.4/demo/Polyhedron/Polyhedron_demo_orient_soup_plugin.cpp cgal-4.5/demo/Polyhedron/Polyhedron_demo_orient_soup_plugin.cpp --- cgal-4.4/demo/Polyhedron/Polyhedron_demo_orient_soup_plugin.cpp 2012-11-13 13:13:59.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Polyhedron_demo_orient_soup_plugin.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -113,6 +113,9 @@ } QApplication::restoreOverrideCursor(); } + else{ + messages->warning(tr("This function is only applicable on polygon soups.")); + } } } diff -Nru cgal-4.4/demo/Polyhedron/Polyhedron_demo_plugin_helper.cpp cgal-4.5/demo/Polyhedron/Polyhedron_demo_plugin_helper.cpp --- cgal-4.4/demo/Polyhedron/Polyhedron_demo_plugin_helper.cpp 2012-11-13 13:13:59.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Polyhedron_demo_plugin_helper.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -6,6 +6,7 @@ #include #include #include +#include QAction* Polyhedron_demo_plugin_helper:: @@ -107,3 +108,21 @@ action->objectName().toUtf8().data()); } // end foreach action of actions() } + +void Polyhedron_demo_plugin_helper::add_dock_widget(QDockWidget* dock_widget) +{ + mw->addDockWidget(Qt::LeftDockWidgetArea, dock_widget); + + QList dockWidgets = mw->findChildren(); + int counter = 0; + foreach(QDockWidget* dock, dockWidgets) { + if( mw->dockWidgetArea(dock) != Qt::LeftDockWidgetArea || + dock == dock_widget ) + { continue; } + + if(++counter > 1) { + mw->tabifyDockWidget(dock, dock_widget); + return; + } + } +} diff -Nru cgal-4.4/demo/Polyhedron/Polyhedron_demo_plugin_helper.h cgal-4.5/demo/Polyhedron/Polyhedron_demo_plugin_helper.h --- cgal-4.4/demo/Polyhedron/Polyhedron_demo_plugin_helper.h 2012-11-13 13:13:59.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Polyhedron_demo_plugin_helper.h 2014-08-29 13:58:17.000000000 +0000 @@ -10,9 +10,10 @@ class QAction; struct QMetaObject; class QMainWindow; -class Scene_interface; +class QDockWidget; #include "Polyhedron_demo_plugin_interface.h" +#include "Scene_interface.h" class SCENE_ITEM_EXPORT Polyhedron_demo_plugin_helper : public Polyhedron_demo_plugin_interface @@ -28,6 +29,27 @@ virtual QStringList actionsNames() const; virtual QList actions() const; + // To get a selected item with the type of SceneType + template + SceneType* get_selected_item() const { + int item_id = scene->mainSelectionIndex(); + SceneType* scene_item = qobject_cast(scene->item(item_id)); + if(!scene_item) { + // no selected SceneType - if there is only one in list return it, otherwise NULL + int counter = 0; + for(Scene_interface::Item_id i = 0, end = scene->numberOfEntries(); i < end && counter < 2; ++i) { + if(SceneType* tmp = qobject_cast(scene->item(i))) { + scene_item = tmp; + counter++; + } + } + if(counter != 1) { return NULL; } + } + return scene_item; + } + + void add_dock_widget(QDockWidget* dock); + // Auto-connect actions to slots. Called by init(). void autoConnectActions(); diff -Nru cgal-4.4/demo/Polyhedron/Polyhedron_demo_point_inside_polyhedron_plugin.cpp cgal-4.5/demo/Polyhedron/Polyhedron_demo_point_inside_polyhedron_plugin.cpp --- cgal-4.4/demo/Polyhedron/Polyhedron_demo_point_inside_polyhedron_plugin.cpp 2013-06-29 19:00:35.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Polyhedron_demo_point_inside_polyhedron_plugin.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -1,4 +1,5 @@ #include +#include "opengl_tools.h" #include "Messages_interface.h" #include "Scene_polyhedron_item.h" diff -Nru cgal-4.4/demo/Polyhedron/Polyhedron_demo_poisson_plugin.cpp cgal-4.5/demo/Polyhedron/Polyhedron_demo_poisson_plugin.cpp --- cgal-4.4/demo/Polyhedron/Polyhedron_demo_poisson_plugin.cpp 2013-03-07 20:00:26.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Polyhedron_demo_poisson_plugin.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -41,7 +41,9 @@ //! Applicate for Point_sets with normals. bool applicable() const { - return qobject_cast(scene->item(scene->mainSelectionIndex())); + Scene_points_with_normal_item* item = + qobject_cast(scene->item(scene->mainSelectionIndex())); + return item && item->has_normals(); } QList actions() const { @@ -60,11 +62,7 @@ Polyhedron_demo_poisson_plugin_dialog(QWidget* /*parent*/ = 0) { setupUi(this); - - #ifdef CGAL_TAUCS_ENABLED - m_inputSolver->addItem("Taucs"); - #endif - + #ifdef CGAL_EIGEN3_ENABLED m_inputSolver->addItem("Eigen - built-in simplicial LDLt"); m_inputSolver->addItem("Eigen - built-in CG"); diff -Nru cgal-4.4/demo/Polyhedron/Polyhedron_demo_poisson_plugin_impl.cpp cgal-4.5/demo/Polyhedron/Polyhedron_demo_poisson_plugin_impl.cpp --- cgal-4.4/demo/Polyhedron/Polyhedron_demo_poisson_plugin_impl.cpp 2013-07-27 19:00:33.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Polyhedron_demo_poisson_plugin_impl.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -16,9 +16,6 @@ #include #include -#ifdef CGAL_TAUCS_ENABLED -#include -#endif #ifdef CGAL_EIGEN3_ENABLED #include #endif @@ -90,27 +87,7 @@ points.begin(), points.end(), CGAL::make_normal_of_point_with_normal_pmap(Point_set::value_type())); - bool ok = false; - #ifdef CGAL_TAUCS_ENABLED - if(solver_name=="Taucs") - { - // Creates sparse linear solver: - // TAUCS out-of-core Multifrontal Supernodal Cholesky Factorization - const char* OOC_SUPERNODAL_CHOLESKY_FACTORIZATION[] = - { - "taucs.factor.LLT=true", - "taucs.factor.mf=true", - "taucs.factor.ordering=metis", - "taucs.ooc=true", "taucs.ooc.basename=taucs-ooc", - NULL - }; - unlink("taucs-ooc.0"); // make sure TAUCS ooc file does not exist - CGAL::Taucs_symmetric_solver_traits solver(OOC_SUPERNODAL_CHOLESKY_FACTORIZATION); - - ok = function.compute_implicit_function(solver, use_two_passes); - } - #endif - + bool ok = false; #ifdef CGAL_EIGEN3_ENABLED if(solver_name=="Eigen - built-in simplicial LDLt") { @@ -212,7 +189,7 @@ // Constructs AABB tree and computes internal KD-tree // data structure to accelerate distance queries - AABB_tree tree(output_mesh->facets_begin(), output_mesh->facets_end(), *output_mesh); + AABB_tree tree(faces(*output_mesh).first, faces(*output_mesh).second, *output_mesh); tree.accelerate_distance_queries(); // Computes distance from each input point to reconstructed mesh diff -Nru cgal-4.4/demo/Polyhedron/Polyhedron_demo_polyhedron_stitching_plugin.cpp cgal-4.5/demo/Polyhedron/Polyhedron_demo_polyhedron_stitching_plugin.cpp --- cgal-4.4/demo/Polyhedron/Polyhedron_demo_polyhedron_stitching_plugin.cpp 2013-11-30 20:00:27.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Polyhedron_demo_polyhedron_stitching_plugin.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -22,6 +22,7 @@ QAction* actionStitchBorders; public: QList actions() const { return QList() << actionDetectBorders << actionStitchBorders; } + using Polyhedron_demo_plugin_helper::init; void init(QMainWindow* mainWindow, Scene_interface* scene_interface, Messages_interface* /* m */) { actionDetectBorders= new QAction(tr("Detect polyhedron boundaries"), mainWindow); @@ -32,7 +33,12 @@ } bool applicable() const { - return qobject_cast(scene->item(scene->mainSelectionIndex())); + Q_FOREACH(int index, scene->selectionIndices()) + { + if ( qobject_cast(scene->item(index)) ) + return true; + } + return false; } public slots: @@ -43,53 +49,55 @@ void Polyhedron_demo_polyhedron_stitching_plugin::on_actionDetectBorders_triggered() { - Scene_interface::Item_id index = scene->mainSelectionIndex(); - - Scene_polyhedron_item* item = - qobject_cast(scene->item(index)); - - if(item) + Q_FOREACH(int index, scene->selectionIndices()) { - Scene_polylines_item* new_item = new Scene_polylines_item(); + Scene_polyhedron_item* item = + qobject_cast(scene->item(index)); - Polyhedron* pMesh = item->polyhedron(); - pMesh->normalize_border(); - - for (Polyhedron::Halfedge_iterator - it=pMesh->border_halfedges_begin(), it_end=pMesh->halfedges_end(); - it!=it_end; ++it) - { - if (!it->is_border()) continue; - /// \todo build cycles and graph with nodes of valence 2. - new_item->polylines.push_back( Scene_polylines_item::Polyline() ); - new_item->polylines.back().push_back( it->opposite()->vertex()->point() ); - new_item->polylines.back().push_back( it->vertex()->point() ); - } - if (new_item->polylines.empty()) - { - delete new_item; - } - else + if(item) { - new_item->setName(tr("Boundary of %1").arg(item->name())); - new_item->setColor(Qt::red); - scene->addItem(new_item); + Scene_polylines_item* new_item = new Scene_polylines_item(); + + Polyhedron* pMesh = item->polyhedron(); + pMesh->normalize_border(); + + for (Polyhedron::Halfedge_iterator + it=pMesh->border_halfedges_begin(), it_end=pMesh->halfedges_end(); + it!=it_end; ++it) + { + if (!it->is_border()) continue; + /// \todo build cycles and graph with nodes of valence 2. + new_item->polylines.push_back( Scene_polylines_item::Polyline() ); + new_item->polylines.back().push_back( it->opposite()->vertex()->point() ); + new_item->polylines.back().push_back( it->vertex()->point() ); + } + if (new_item->polylines.empty()) + { + delete new_item; + } + else + { + new_item->setName(tr("Boundary of %1").arg(item->name())); + new_item->setColor(Qt::red); + scene->addItem(new_item); + } } } } void Polyhedron_demo_polyhedron_stitching_plugin::on_actionStitchBorders_triggered() { - Scene_interface::Item_id index = scene->mainSelectionIndex(); - - Scene_polyhedron_item* item = - qobject_cast(scene->item(index)); - - if(item) + Q_FOREACH(int index, scene->selectionIndices()) { - Polyhedron* pMesh = item->polyhedron(); - CGAL::polyhedron_stitching(*pMesh); - scene->itemChanged(item); + Scene_polyhedron_item* item = + qobject_cast(scene->item(index)); + + if(item) + { + Polyhedron* pMesh = item->polyhedron(); + CGAL::polyhedron_stitching(*pMesh); + scene->itemChanged(item); + } } } diff -Nru cgal-4.4/demo/Polyhedron/Polyhedron_demo_selection_io_plugin.cpp cgal-4.5/demo/Polyhedron/Polyhedron_demo_selection_io_plugin.cpp --- cgal-4.4/demo/Polyhedron/Polyhedron_demo_selection_io_plugin.cpp 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Polyhedron_demo_selection_io_plugin.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,42 @@ +#include "Scene_polyhedron_selection_item.h" +#include "Polyhedron_demo_io_plugin_interface.h" +#include + +class Polyhedron_demo_selection_io_plugin : + public QObject, + public Polyhedron_demo_io_plugin_interface +{ + Q_OBJECT + Q_INTERFACES(Polyhedron_demo_io_plugin_interface) + +public: + QString name() const { return "selection_io_plugin"; } + QString nameFilters() const { return "Selection files (*.selection.txt)"; } + + bool canLoad() const { return true; } + Scene_item* load(QFileInfo fileinfo) { + if(fileinfo.suffix().toLower() != "txt") return 0; + // There will be no actual loading at this step. + // Polyhedron_demo_selection_plugin will trigger load when item in new_item_created + Scene_polyhedron_selection_item* item = new Scene_polyhedron_selection_item(); + if(!item->load(fileinfo.filePath().toStdString())) { + delete item; + return NULL; + } + return item; + } + + bool canSave(const Scene_item* scene_item) { + return qobject_cast(scene_item); + } + bool save(const Scene_item* scene_item, QFileInfo fileinfo) { + const Scene_polyhedron_selection_item* item = qobject_cast(scene_item); + if(item == NULL) { return false; } + + return item->save(fileinfo.filePath().toStdString()); + } +}; + +#include +Q_EXPORT_PLUGIN2(Polyhedron_demo_selection_io_plugin, Polyhedron_demo_selection_io_plugin) +#include "Polyhedron_demo_selection_io_plugin.moc" diff -Nru cgal-4.4/demo/Polyhedron/Polyhedron_demo_selection_plugin.cpp cgal-4.5/demo/Polyhedron/Polyhedron_demo_selection_plugin.cpp --- cgal-4.4/demo/Polyhedron/Polyhedron_demo_selection_plugin.cpp 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Polyhedron_demo_selection_plugin.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,283 @@ +#include +#include "opengl_tools.h" + +#include "Messages_interface.h" +#include "Scene_polyhedron_item.h" +#include "Scene_polyhedron_selection_item.h" +#include "Scene_points_with_normal_item.h" + +#include "Scene_interface.h" +#include "Polyhedron_demo_plugin_helper.h" +#include "ui_Selection_widget.h" + +#include +#include +#include + +#include + +class Polyhedron_demo_selection_plugin : + public QObject, + public Polyhedron_demo_plugin_helper +{ + Q_OBJECT + Q_INTERFACES(Polyhedron_demo_plugin_interface) + +public: + bool applicable() const { + return qobject_cast(scene->item(scene->mainSelectionIndex())) + || qobject_cast(scene->item(scene->mainSelectionIndex())); + } + void print_message(QString message) { messages->information(message); } + QList actions() const { return QList() << actionSelection; } + using Polyhedron_demo_plugin_helper::init; + void init(QMainWindow* mainWindow, Scene_interface* scene_interface, Messages_interface* m) { + mw = mainWindow; + scene = scene_interface; + messages = m; + + actionSelection = new QAction(tr("Selection"), mw); + connect(actionSelection, SIGNAL(triggered()), this, SLOT(selection_action())); + + dock_widget = new QDockWidget("Selection", mw); + dock_widget->setVisible(false); + + ui_widget.setupUi(dock_widget); + add_dock_widget(dock_widget); + + connect(ui_widget.Select_all_button, SIGNAL(clicked()), this, SLOT(on_Select_all_button_clicked())); + connect(ui_widget.Clear_button, SIGNAL(clicked()), this, SLOT(on_Clear_button_clicked())); + connect(ui_widget.Select_isolated_components_button, SIGNAL(clicked()), this, SLOT(on_Select_isolated_components_button_clicked())); + connect(ui_widget.Get_minimum_button, SIGNAL(clicked()), this, SLOT(on_Get_minimum_button_clicked())); + connect(ui_widget.Create_selection_item_button, SIGNAL(clicked()), this, SLOT(on_Create_selection_item_button_clicked())); + connect(ui_widget.Selection_type_combo_box, SIGNAL(currentIndexChanged(int)), + this, SLOT(on_Selection_type_combo_box_changed(int))); + connect(ui_widget.Insertion_radio_button, SIGNAL(toggled(bool)), this, SLOT(on_Insertion_radio_button_toggled(bool))); + connect(ui_widget.Brush_size_spin_box, SIGNAL(valueChanged(int)), this, SLOT(on_Brush_size_spin_box_changed(int))); + connect(ui_widget.Create_point_set_item_button, SIGNAL(clicked()), this, SLOT(on_Create_point_set_item_button_clicked())); + connect(ui_widget.Erase_selected_facets_button, SIGNAL(clicked()), this, SLOT(on_Erase_selected_facets_button_clicked())); + connect(ui_widget.Expand_shrink_button, SIGNAL(clicked()), this, SLOT(on_Expand_shrink_button_clicked())); + connect(ui_widget.Create_polyhedron_item_button, SIGNAL(clicked()), this, SLOT(on_Create_polyhedron_item_button_clicked())); + QObject* scene = dynamic_cast(scene_interface); + if(scene) { + connect(scene, SIGNAL(itemAboutToBeDestroyed(Scene_item*)), this, SLOT(item_about_to_be_destroyed(Scene_item*))); + connect(scene, SIGNAL(newItem(int)), this, SLOT(new_item_created(int))); + } + } + +public slots: + void selection_action() { + dock_widget->show(); + dock_widget->raise(); + if(scene->numberOfEntries() < 2) { + Scene_polyhedron_item* poly_item = get_selected_item(); + if(!poly_item || selection_item_map.find(poly_item) != selection_item_map.end()) { return; } + scene->addItem(new Scene_polyhedron_selection_item(poly_item, mw)); + } + } + // Select all + void on_Select_all_button_clicked() { + Scene_polyhedron_selection_item* selection_item = get_selected_item(); + if(!selection_item) { + print_message("Error: there is no selected polyhedron selection item!"); + return; + } + + selection_item->select_all(); + } + // Clear selection + void on_Clear_button_clicked() { + Scene_polyhedron_selection_item* selection_item = get_selected_item(); + if(!selection_item) { + print_message("Error: there is no selected polyhedron selection item!"); + return; + } + + selection_item->clear(); + } + // Isolated component related functions + void on_Select_isolated_components_button_clicked() { + Scene_polyhedron_selection_item* selection_item = get_selected_item(); + if(!selection_item) { + print_message("Error: there is no selected polyhedron selection item!"); + return; + } + + boost::optional minimum = + selection_item->select_isolated_components(ui_widget.Threshold_size_spin_box->value()); + if(minimum) { + ui_widget.Threshold_size_spin_box->setValue((int) *minimum); + } + } + void on_Get_minimum_button_clicked() { + Scene_polyhedron_selection_item* selection_item = get_selected_item(); + if(!selection_item) { + print_message("Error: there is no selected polyhedron selection item!"); + return; + } + boost::optional minimum = selection_item->get_minimum_isolated_component(); + if(minimum) { + ui_widget.Threshold_size_spin_box->setValue((int) *minimum); + } + } + // Create selection item for selected polyhedron item + void on_Create_selection_item_button_clicked() { + Scene_polyhedron_item* poly_item = get_selected_item(); + if(!poly_item) { + print_message("Error: there is no selected polyhedron item!"); + return; + } + // all other arrangements (putting inside selection_item_map), setting names etc, + // other params (e.g. k_ring) will be set inside new_item_created + scene->addItem(new Scene_polyhedron_selection_item(poly_item, mw)); + } + void on_Selection_type_combo_box_changed(int index) { + typedef Scene_polyhedron_selection_item::Active_handle Active_handle; + for(Selection_item_map::iterator it = selection_item_map.begin(); it != selection_item_map.end(); ++it) { + it->second->set_active_handle_type(static_cast(index)); + } + } + void on_Insertion_radio_button_toggled(bool toggle){ + for(Selection_item_map::iterator it = selection_item_map.begin(); it != selection_item_map.end(); ++it) { + it->second->set_is_insert(toggle); + } + } + void on_Brush_size_spin_box_changed(int value) { + for(Selection_item_map::iterator it = selection_item_map.begin(); it != selection_item_map.end(); ++it) { + it->second->set_k_ring(value); + } + } + + void on_Create_point_set_item_button_clicked() { + Scene_polyhedron_selection_item* selection_item = get_selected_item(); + if(!selection_item) { + print_message("Error: there is no selected polyhedron selection item!"); + return; + } + if(selection_item->selected_vertices.empty()) { + print_message("Error: there is no selected vertex in polyhedron selection item!"); + return; + } + Scene_points_with_normal_item* point_item = new Scene_points_with_normal_item(); + point_item->setName(QString("%1-points").arg(selection_item->name())); + for(Scene_polyhedron_selection_item::Selection_set_vertex::iterator begin = selection_item->selected_vertices.begin(); + begin != selection_item->selected_vertices.end(); ++begin) { + point_item->point_set()->push_back((*begin)->point()); + } + + scene->addItem(point_item); + } + void on_Erase_selected_facets_button_clicked() { + Scene_polyhedron_selection_item* selection_item = get_selected_item(); + if(!selection_item) { + print_message("Error: there is no selected polyhedron selection item!"); + return; + } + + selection_item->erase_selected_facets(); + } + void on_Create_polyhedron_item_button_clicked() { + Scene_polyhedron_selection_item* selection_item = get_selected_item(); + if(!selection_item) { + print_message("Error: there is no selected polyhedron selection item!"); + return; + } + + Scene_polyhedron_item* poly_item = new Scene_polyhedron_item(); + if(selection_item->export_selected_facets_as_polyhedron(poly_item->polyhedron())) { + poly_item->setName(QString("%1-facets").arg(selection_item->name())); + poly_item->changed(); // for init() + scene->addItem(poly_item); + } + else { + delete poly_item; + print_message("Error: polyhedron item is not created!"); + } + } + void on_Expand_shrink_button_clicked() { + Scene_polyhedron_selection_item* selection_item = get_selected_item(); + if(!selection_item) { + print_message("Error: there is no selected polyhedron selection item!"); + return; + } + + int steps = ui_widget.Expand_shrink_spin_box->value(); + selection_item->expand_or_shrink(steps); + } + // To handle empty selection items coming from loader + void new_item_created(int item_id) { + typedef Scene_polyhedron_selection_item::Active_handle Active_handle; + Scene_polyhedron_selection_item* selection_item = + qobject_cast(scene->item(item_id)); + if(!selection_item) { return; } + + Scene_polyhedron_item* poly_item = get_selected_item(); + if(!poly_item) { + CGAL_assertion(selection_item->polyhedron_item() == NULL); // which means it is coming from selection_io loader + print_message("Error: please select corresponding polyhedron item from Geometric Objects list."); + scene->erase(item_id); + return; + } + + if(selection_item->polyhedron_item() == NULL) { //coming from selection_io loader + if(!selection_item->actual_load(poly_item, mw)) { + print_message("Error: loading selection item is not successful!"); + scene->erase(item_id); + return; + } + } + // now set default params both for selection items coming from selection_io, or on_Create_selection_item_button_clicked + Active_handle::Type aht = static_cast(ui_widget.Selection_type_combo_box->currentIndex()); + bool is_insert = ui_widget.Insertion_radio_button->isChecked(); + int k_ring = ui_widget.Brush_size_spin_box->value(); + + selection_item->set_active_handle_type(aht); + selection_item->set_is_insert(is_insert); + selection_item->set_k_ring(k_ring); + selection_item->setRenderingMode(Flat); + if(selection_item->name() == "unamed") { + selection_item->setName(tr("%1 (selection)").arg(poly_item->name())); + } + + selection_item_map.insert(std::make_pair(poly_item, selection_item)); + } + void item_about_to_be_destroyed(Scene_item* scene_item) { + // if polyhedron item + Scene_polyhedron_item* poly_item = qobject_cast(scene_item); + if(poly_item) { + std::pair res = + selection_item_map.equal_range(poly_item); + + for(Selection_item_map::iterator begin = res.first; begin != res.second; ) { + Scene_polyhedron_selection_item* selection_item = begin->second; + selection_item_map.erase(begin++); // first erase from map, because scene->erase will cause a call to this function + scene->erase( scene->item_id(selection_item) ); + } + } + // if polyhedron selection item + Scene_polyhedron_selection_item* selection_item = qobject_cast(scene_item); + if(selection_item) { + Scene_polyhedron_item* poly_item = selection_item->polyhedron_item(); + std::pair res = + selection_item_map.equal_range(poly_item); + for(Selection_item_map::iterator begin = res.first; begin != res.second; ++begin) { + if(begin->second == selection_item) { + selection_item_map.erase(begin); break; + } + } + } + } + +private: + Messages_interface* messages; + QAction* actionSelection; + + QDockWidget* dock_widget; + Ui::Selection ui_widget; +typedef std::multimap Selection_item_map; + Selection_item_map selection_item_map; +}; // end Polyhedron_demo_selection_plugin + +Q_EXPORT_PLUGIN2(Polyhedron_demo_selection_plugin, Polyhedron_demo_selection_plugin) + +#include "Polyhedron_demo_selection_plugin.moc" diff -Nru cgal-4.4/demo/Polyhedron/Polyhedron_type.h cgal-4.5/demo/Polyhedron/Polyhedron_type.h --- cgal-4.4/demo/Polyhedron/Polyhedron_type.h 2012-11-13 13:13:59.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Polyhedron_type.h 2014-08-29 13:58:17.000000000 +0000 @@ -8,6 +8,10 @@ // surface mesh #include #include +#include + +#include +#include #include @@ -23,6 +27,8 @@ Set_of_indices indices; std::size_t mID; + std::size_t time_stamp_; + public: int nb_of_feature_edges; @@ -38,6 +44,18 @@ indices.insert(i); } + /// For the determinism of Compact_container iterators + ///@{ + typedef CGAL::Tag_true Has_timestamp; + + std::size_t time_stamp() const { + return time_stamp_; + } + void set_time_stamp(const std::size_t& ts) { + time_stamp_ = ts; + } + ///}@ + const Set_of_indices& incident_patches_ids_set() const { return indices; @@ -57,6 +75,8 @@ private: bool feature_edge; std::size_t mID; + std::size_t time_stamp_; + public: Polyhedron_demo_halfedge() @@ -74,6 +94,17 @@ std::size_t& id() { return mID; } std::size_t id() const { return mID; } + /// For the determinism of Compact_container iterators + ///@{ + typedef CGAL::Tag_true Has_timestamp; + + std::size_t time_stamp() const { + return time_stamp_; + } + void set_time_stamp(const std::size_t& ts) { + time_stamp_ = ts; + } + ///@} }; template @@ -83,6 +114,8 @@ private: Patch_id_ patch_id_; std::size_t mID; + std::size_t time_stamp_; + public: typedef Patch_id_ Patch_id; @@ -100,6 +133,17 @@ std::size_t& id() { return mID; } std::size_t id() const { return mID; } + /// For the determinism of Compact_container iterators + ///@{ + typedef CGAL::Tag_true Has_timestamp; + + std::size_t time_stamp() const { + return time_stamp_; + } + void set_time_stamp(const std::size_t& ts) { + time_stamp_ = ts; + } + ///@} }; template diff -Nru cgal-4.4/demo/Polyhedron/Scene_c2t3_item.h cgal-4.5/demo/Polyhedron/Scene_c2t3_item.h --- cgal-4.4/demo/Polyhedron/Scene_c2t3_item.h 2012-11-13 13:13:59.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Scene_c2t3_item.h 2014-08-29 13:58:17.000000000 +0000 @@ -74,7 +74,7 @@ // Indicate if rendering mode is supported bool supportsRenderingMode(RenderingMode m) const { - return (m != Gouraud && m!=PointsPlusNormals); // CHECK THIS! + return (m != Gouraud && m!=PointsPlusNormals && m!=Splatting); // CHECK THIS! } void draw() const { diff -Nru cgal-4.4/demo/Polyhedron/Scene_combinatorial_map_item.h cgal-4.5/demo/Polyhedron/Scene_combinatorial_map_item.h --- cgal-4.4/demo/Polyhedron/Scene_combinatorial_map_item.h 2013-11-30 20:00:27.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Scene_combinatorial_map_item.h 2014-08-29 13:58:17.000000000 +0000 @@ -37,7 +37,7 @@ QString toolTip() const; // Indicate if rendering mode is supported - virtual bool supportsRenderingMode(RenderingMode m) const { return (m != Gouraud && m!=PointsPlusNormals); } // CHECK THIS! + virtual bool supportsRenderingMode(RenderingMode m) const { return (m != Gouraud && m!=PointsPlusNormals && m!=Splatting); } // CHECK THIS! //Event handling virtual bool keyPressEvent(QKeyEvent*); // OpenGL drawing in a display list diff -Nru cgal-4.4/demo/Polyhedron/Scene.cpp cgal-4.5/demo/Polyhedron/Scene.cpp --- cgal-4.4/demo/Polyhedron/Scene.cpp 2013-09-07 19:00:31.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Scene.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -1,3 +1,9 @@ + +#ifdef CGAL_GLEW_ENABLED +# include "GlSplat/GlSplat.h" +#endif + + #include #include "config.h" #include "Scene.h" @@ -14,6 +20,7 @@ #include #include #include +#include namespace { void CGALglcolor(QColor c) @@ -22,6 +29,16 @@ } } +#ifdef CGAL_GLEW_ENABLED +GlSplat::SplatRenderer* Scene::ms_splatting = 0; +int Scene::ms_splattingCounter = 0; +GlSplat::SplatRenderer* Scene::splatting() +{ + assert(ms_splatting!=0 && "A Scene object must be created before requesting the splatting object"); + return ms_splatting; +} +#endif + Scene::Scene(QObject* parent) : QAbstractListModel(parent), selected_item(-1), @@ -32,16 +49,22 @@ double, double, double)), this, SLOT(setSelectionRay(double, double, double, double, double, double))); +#ifdef CGAL_GLEW_ENABLED + if(ms_splatting==0) + ms_splatting = new GlSplat::SplatRenderer(); + ms_splattingCounter++; +#endif } Scene::Item_id Scene::addItem(Scene_item* item) { + Bbox bbox_before = bbox(); m_entries.push_back(item); - connect(item, SIGNAL(itemChanged()), this, SLOT(itemChanged())); - emit updated_bbox(); + if(bbox_before + item->bbox() != bbox_before) + { emit updated_bbox(); } emit updated(); QAbstractListModel::reset(); Item_id id = m_entries.size() - 1; @@ -139,6 +162,11 @@ delete item_ptr; } m_entries.clear(); + +#ifdef CGAL_GLEW_ENABLED + if((--ms_splattingCounter)==0) + delete ms_splatting; +#endif } Scene_item* @@ -147,6 +175,12 @@ return m_entries.value(index); // QList::value checks bounds } +Scene::Item_id +Scene::item_id(Scene_item* scene_item) const +{ + return m_entries.indexOf(scene_item); +} + int Scene::numberOfEntries() const { @@ -176,6 +210,9 @@ void Scene::initializeGL() { +#ifdef CGAL_GLEW_ENABLED + ms_splatting->init(); +#endif } // workaround for Qt-4.2. @@ -328,10 +365,7 @@ ::glPolygonMode(GL_FRONT_AND_BACK,GL_POINT); ::glPointSize(2.f); ::glLineWidth(1.0f); - if(index == selected_item) - CGALglcolor(Qt::black); - else - CGALglcolor(item.color().lighter(50)); + CGALglcolor(item.color()); if(viewer) item.draw_points(viewer); @@ -343,6 +377,34 @@ } } } + +#ifdef CGAL_GLEW_ENABLED + // Splatting + if(ms_splatting->isSupported()) + { + ms_splatting->beginVisibilityPass(); + for(int index = 0; index < m_entries.size(); ++index) + { + Scene_item& item = *m_entries[index]; + if(item.visible() && item.renderingMode() == Splatting) + { + item.draw_splats(); + } + } + ms_splatting->beginAttributePass(); + for(int index = 0; index < m_entries.size(); ++index) + { + Scene_item& item = *m_entries[index]; + if(item.visible() && item.renderingMode() == Splatting) + { + CGALglcolor(item.color()); + item.draw_splats(); + } + } + ms_splatting->finalize(); + } +#endif + } // workaround for Qt-4.2 (see above) @@ -505,7 +567,12 @@ { RenderingMode rendering_mode = static_cast(value.toInt()); // Find next supported rendering mode - while ( ! item->supportsRenderingMode(rendering_mode) ) { + while ( ! item->supportsRenderingMode(rendering_mode) +#ifdef CGAL_GLEW_ENABLED + || (rendering_mode==Splatting && !Scene::splatting()->isSupported()) +#endif + ) + { rendering_mode = static_cast( (rendering_mode+1) % NumberOfRenderingMode ); } item->setRenderingMode(rendering_mode); @@ -543,14 +610,14 @@ QItemSelection Scene::createSelection(int i) { - return QItemSelection(QAbstractItemModel::createIndex(i, 0), - QAbstractItemModel::createIndex(i, LastColumn)); + return QItemSelection(this->createIndex(i, 0), + this->createIndex(i, LastColumn)); } QItemSelection Scene::createSelectionAll() { - return QItemSelection(QAbstractItemModel::createIndex(0, 0), - QAbstractItemModel::createIndex(m_entries.size() - 1 , LastColumn)); + return QItemSelection(this->createIndex(0, 0), + this->createIndex(m_entries.size() - 1 , LastColumn)); } void Scene::itemChanged() @@ -566,22 +633,24 @@ return; m_entries[i]->changed(); - emit dataChanged(QAbstractItemModel::createIndex(i, 0), - QAbstractItemModel::createIndex(i, LastColumn)); + emit dataChanged(this->createIndex(i, 0), + this->createIndex(i, LastColumn)); } void Scene::itemChanged(Scene_item* item) { item->changed(); - emit dataChanged(QAbstractItemModel::createIndex(0, 0), - QAbstractItemModel::createIndex(m_entries.size() - 1, LastColumn)); + emit dataChanged(this->createIndex(0, 0), + this->createIndex(m_entries.size() - 1, LastColumn)); } bool SceneDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) { - Scene *scene = static_cast(model); + QAbstractProxyModel* proxyModel = dynamic_cast(model); + Q_ASSERT(proxyModel); + Scene *scene = dynamic_cast(proxyModel->sourceModel()); Q_ASSERT(scene); switch(index.column()) { case Scene::VisibleColumn: @@ -648,8 +717,8 @@ else { scene->item_B = index.row(); } - scene->dataChanged(scene->createIndex(Scene::ABColumn, 0), - scene->createIndex(Scene::ABColumn, scene->rowCount())); + scene->dataChanged(scene->createIndex(0, Scene::ABColumn), + scene->createIndex(scene->rowCount() - 1, Scene::ABColumn)); } return false; break; @@ -696,8 +765,8 @@ if( index < 0 || index >= m_entries.size() ) return; m_entries[index]->setVisible(b); - emit dataChanged(QAbstractItemModel::createIndex(index, VisibleColumn), - QAbstractItemModel::createIndex(index, VisibleColumn)); + emit dataChanged(this->createIndex(index, VisibleColumn), + this->createIndex(index, VisibleColumn)); } void Scene::setSelectionRay(double orig_x, @@ -723,8 +792,8 @@ { item_B = -1; } - emit dataChanged(QAbstractItemModel::createIndex(0, ABColumn), - QAbstractItemModel::createIndex(m_entries.size()-1, ABColumn)); + emit dataChanged(this->createIndex(0, ABColumn), + this->createIndex(m_entries.size()-1, ABColumn)); } void Scene::setItemB(int i) @@ -735,8 +804,8 @@ item_A = -1; } emit updated(); - emit dataChanged(QAbstractItemModel::createIndex(0, ABColumn), - QAbstractItemModel::createIndex(m_entries.size()-1, ABColumn)); + emit dataChanged(this->createIndex(0, ABColumn), + this->createIndex(m_entries.size()-1, ABColumn)); } Scene::Bbox Scene::bbox() const diff -Nru cgal-4.4/demo/Polyhedron/Scene_edit_polyhedron_item.cpp cgal-4.5/demo/Polyhedron/Scene_edit_polyhedron_item.cpp --- cgal-4.4/demo/Polyhedron/Scene_edit_polyhedron_item.cpp 2012-11-13 13:13:59.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Scene_edit_polyhedron_item.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -1,126 +1,368 @@ +#include "opengl_tools.h" #include "Scene_edit_polyhedron_item.h" -#include "Kernel_type.h" -#include "Polyhedron_type.h" - #include +#include -#include -#include -#include -#include -#include #include -#include +Scene_edit_polyhedron_item::Scene_edit_polyhedron_item + (Scene_polyhedron_item* poly_item, + Ui::DeformMesh* ui_widget, + QMainWindow* mw) + : ui_widget(ui_widget), + poly_item(poly_item), + deform_mesh(*(poly_item->polyhedron()), Deform_mesh::Vertex_index_map(), Deform_mesh::Hedge_index_map(), Array_based_vertex_point_map(&positions)), + is_rot_free(true), + own_poly_item(true), + k_ring_selector(poly_item, mw, Scene_polyhedron_item_k_ring_selection::Active_handle::VERTEX, true), + quadric(gluNewQuadric()) +{ + mw->installEventFilter(this); + gluQuadricNormals(quadric, GLU_SMOOTH); + // bind vertex picking + connect(&k_ring_selector, SIGNAL(selected(const std::map&)), this, + SLOT(selected(const std::map&))); + + poly_item->set_color_vector_read_only(true); // to prevent recomputation of color vector in changed() + poly_item->update_vertex_indices(); + + length_of_axis = bbox().diagonal_length() / 15.0; + + // interleave events of viewer (there is only one viewer) + QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + viewer->installEventFilter(this); + + // create an empty group of control vertices for starting + create_ctrl_vertices_group(); + + // start QObject's timer for continuous effects + // (deforming mesh while mouse not moving) + startTimer(0); + + // Required for drawing functionality + positions.resize(num_vertices(*polyhedron())*3); + normals.resize(positions.size()); + Polyhedron::Vertex_iterator vb, ve; + std::size_t counter = 0; + for(vb=polyhedron()->vertices_begin(), ve = polyhedron()->vertices_end();vb != ve; ++vb, ++counter) { + positions[counter*3] = vb->point().x(); + positions[counter*3+1] = vb->point().y(); + positions[counter*3+2] = vb->point().z(); + + const Polyhedron::Traits::Vector_3& n = + compute_vertex_normal(*vb); + + normals[counter*3] = n.x(); + normals[counter*3+1] = n.y(); + normals[counter*3+2] = n.z(); + } -typedef Polyhedron::Vertex_handle Vertex_handle; -typedef std::set Selected_vertices; -typedef Selected_vertices::iterator Selected_vertices_it; - -struct Scene_edit_polyhedron_item_priv { - Scene_polyhedron_item* poly_item; - int zone_size; - qglviewer::ManipulatedFrame* frame; - Selected_vertices selected_vertices; - Vertex_handle selected_vertex; - Kernel::Point_3 orig_pos; -}; // end struct Scene_edit_polyhedron_item_priv - -Scene_edit_polyhedron_item::Scene_edit_polyhedron_item(Scene_polyhedron_item* poly_item) - : d(new Scene_edit_polyhedron_item_priv) -{ - d->poly_item = poly_item; - d->zone_size = 0; - d->frame = new ManipulatedFrame(); - d->frame->setProperty("item", QVariant::fromValue(this)); - if(!connect(poly_item, SIGNAL(selected_vertex(void*)), - this, SLOT(vertex_has_been_selected(void*)))) - std::cerr << __FILE__ << ": connection failed!\n"; - poly_item->enable_facets_picking(true); + tris.resize(polyhedron()->size_of_facets()*3); + counter = 0; + for(Polyhedron::Facet_handle fb = polyhedron()->facets_begin(); fb != polyhedron()->facets_end(); ++fb, ++counter) { + tris[counter*3] = static_cast(fb->halfedge()->vertex()->id()); + tris[counter*3+1] = static_cast(fb->halfedge()->next()->vertex()->id()); + tris[counter*3+2] = static_cast(fb->halfedge()->prev()->vertex()->id()); + } + + edges.resize(polyhedron()->size_of_halfedges()); + counter = 0; + for(Polyhedron::Edge_iterator eb = polyhedron()->edges_begin(); eb != polyhedron()->edges_end(); ++eb, ++counter) { + edges[counter*2] = static_cast(eb->vertex()->id()); + edges[counter*2+1] = static_cast(eb->opposite()->vertex()->id()); + } } Scene_edit_polyhedron_item::~Scene_edit_polyhedron_item() { - delete d->frame; - delete d; + while(is_there_any_ctrl_vertices_group()) + { + delete_ctrl_vertices_group(false); + } + gluDeleteQuadric(quadric); + if (own_poly_item) delete poly_item; } -Scene_edit_polyhedron_item* -Scene_edit_polyhedron_item::clone() const { - return 0; +///////////////////////////////////////////////////////// +/////////// Most relevant functions lie here /////////// +void Scene_edit_polyhedron_item::deform() +{ + if(!is_there_any_ctrl_vertices()) { return; } + + for(Ctrl_vertices_group_data_list::iterator it = ctrl_vertex_frame_map.begin(); it != ctrl_vertex_frame_map.end(); ++it) + { it->set_target_positions(); } + deform_mesh.deform(); + + poly_item->changed(); // now we need to call poly_item changed to delete AABB tree + emit itemChanged(); } -QString -Scene_edit_polyhedron_item::toolTip() const +void Scene_edit_polyhedron_item::timerEvent(QTimerEvent* /*event*/) +{ // just handle deformation - paint like selection is handled in eventFilter() + if(state.ctrl_pressing && (state.left_button_pressing || state.right_button_pressing)) { + if(!ui_widget->ActivatePivotingCheckBox->isChecked()) { + deform(); + } + else { + emit itemChanged(); // for redraw while Pivoting (since we close signals of manipulatedFrames while pivoting, + // for now redraw with timer) + } + } +} +bool Scene_edit_polyhedron_item::eventFilter(QObject* /*target*/, QEvent *event) { - if(!d->poly_item->polyhedron()) - return QString(); + // This filter is both filtering events from 'viewer' and 'main window' + Mouse_keyboard_state_deformation old_state = state; + ////////////////// TAKE EVENTS ///////////////////// + // key events + if(event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease) + { + QKeyEvent *keyEvent = static_cast(event); + Qt::KeyboardModifiers modifiers = keyEvent->modifiers(); - return QObject::tr("

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

" - "

Number of vertices: %2
" - "Number of edges: %3
" - "Number of facets: %4

") - .arg(this->name()) - .arg(d->poly_item->polyhedron()->size_of_vertices()) - .arg(d->poly_item->polyhedron()->size_of_halfedges()/2) - .arg(d->poly_item->polyhedron()->size_of_facets()) - .arg(this->renderingModeName()) - .arg(this->color().name()); + state.ctrl_pressing = modifiers.testFlag(Qt::ControlModifier); + state.shift_pressing = modifiers.testFlag(Qt::ShiftModifier); + } + // mouse events + if(event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease) + { + QMouseEvent* mouse_event = static_cast(event); + if(mouse_event->button() == Qt::LeftButton) { + state.left_button_pressing = event->type() == QEvent::MouseButtonPress; + } + if(mouse_event->button() == Qt::RightButton) { + state.right_button_pressing = event->type() == QEvent::MouseButtonPress; + } + } + ////////////////// //////////////// ///////////////////// + + if(!poly_item->visible()) { return false; } // if not visible just update event state but don't do any action + + // check state changes between old and current state + bool ctrl_pressed_now = state.ctrl_pressing && !old_state.ctrl_pressing; + bool ctrl_released_now = !state.ctrl_pressing && old_state.ctrl_pressing; + if(ctrl_pressed_now || ctrl_released_now || event->type() == QEvent::HoverMove) + {// activate a handle manipulated frame + QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + const QPoint& p = viewer->mapFromGlobal(QCursor::pos()); + bool need_repaint = activate_closest_manipulated_frame(p.x(), p.y()); + + if(need_repaint) { emit itemChanged(); } + } + + return false; } #include "opengl_tools.h" +void Scene_edit_polyhedron_item::draw_edges() const { + + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_DOUBLE, 0, positions.data()); + glDrawElements(GL_LINES, (GLsizei) edges.size(), GL_UNSIGNED_INT, edges.data()); + glDisableClientState(GL_VERTEX_ARRAY); + if(rendering_mode == Wireframe) { + draw_ROI_and_control_vertices(); + } +} void Scene_edit_polyhedron_item::draw() const { - d->poly_item->direct_draw(); - if(!d->selected_vertices.empty()) { - CGAL::GL::Point_size point_size; point_size.set_point_size(5); - CGAL::GL::Color color; color.set_rgb_color(0, 0, 0); - ::glBegin(GL_POINTS); - for(Selected_vertices_it - it = d->selected_vertices.begin(), - end = d->selected_vertices.end(); - it != end; ++it) + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + + glVertexPointer(3, GL_DOUBLE, 0, positions.data()); + glNormalPointer(GL_DOUBLE, 0, normals.data()); + glDrawElements(GL_TRIANGLES, (GLsizei) tris.size(), GL_UNSIGNED_INT, tris.data()); + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + + CGAL::GL::Color color; + color.set_rgb_color(0, 0, 0); + draw_edges(); + + draw_ROI_and_control_vertices(); +} + +void Scene_edit_polyhedron_item::draw_ROI_and_control_vertices() const { + GLboolean enable_back_lighting = glIsEnabled(GL_LIGHTING); + glDisable(GL_LIGHTING); + + CGAL::GL::Color color; + CGAL::GL::Point_size point_size; point_size.set_point_size(5); + color.set_rgb_color(0, 1.f, 0); + // draw ROI + if(ui_widget->ShowROICheckBox->isChecked()) { + BOOST_FOREACH(vertex_descriptor vd, deform_mesh.roi_vertices()) { - const Kernel::Point_3& p = (*it)->point(); - ::glVertex3d(p.x(), p.y(), p.z()); + if(!deform_mesh.is_control_vertex(vd)) + gl_draw_point( vd->point() ); + } + } + // draw control vertices related things + QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + + for(Ctrl_vertices_group_data_list::const_iterator hgb_data = ctrl_vertex_frame_map.begin(); hgb_data != ctrl_vertex_frame_map.end(); ++hgb_data) + { + if(hgb_data->frame == viewer->manipulatedFrame()) + { + // draw axis + ::glPushMatrix(); + ::glMultMatrixd(hgb_data->frame->matrix()); + QGLViewer::drawAxis(length_of_axis); + ::glPopMatrix(); + // draw bbox + if(!ui_widget->ActivatePivotingCheckBox->isChecked()) + { + color.set_rgb_color(1.0f, 0, 0); + ::glPushMatrix(); + ::glTranslated(hgb_data->frame->position().x, hgb_data->frame->position().y, hgb_data->frame->position().z); + ::glMultMatrixd(hgb_data->frame->orientation().matrix()); + ::glTranslated(-hgb_data->frame_initial_center.x, -hgb_data->frame_initial_center.y, -hgb_data->frame_initial_center.z); + draw_bbox(hgb_data->bbox); + ::glPopMatrix(); + } + } + // draw control vertices + if(hgb_data == active_group) { color.set_rgb_color(1.0f, 0, 0); } + else { color.set_rgb_color(0, 0, 1.0f); } + for(std::vector::const_iterator hb = hgb_data->ctrl_vertices_group.begin(); hb != hgb_data->ctrl_vertices_group.end(); ++hb) + { gl_draw_point( (*hb)->point() ); } - ::glEnd(); } -} -Polyhedron* -Scene_edit_polyhedron_item::polyhedron() { return d->poly_item->polyhedron(); } -const Polyhedron* -Scene_edit_polyhedron_item::polyhedron() const { return d->poly_item->polyhedron(); } + if(enable_back_lighting) { glEnable(GL_LIGHTING); } +} +void Scene_edit_polyhedron_item::gl_draw_point(const Point& p) const +{ + if(!ui_widget->ShowAsSphereCheckBox->isChecked()) { + ::glBegin(GL_POINTS); + ::glVertex3d(p.x(), p.y(), p.z()); + ::glEnd(); + } + else { + GLint shading; + ::glGetIntegerv(GL_SHADE_MODEL, &shading); + ::glShadeModel(GL_SMOOTH); + + ::glPushMatrix(); + ::glTranslated(p.x(), p.y(), p.z()); + ::gluSphere(quadric, length_of_axis/15, 8, 8); + ::glPopMatrix(); -bool -Scene_edit_polyhedron_item::isEmpty() const { - return d->poly_item->isEmpty(); + ::glShadeModel(shading); + } } +////////////////////////////////////////////////////////// -Scene_edit_polyhedron_item::Bbox -Scene_edit_polyhedron_item::bbox() const { - return d->poly_item->bbox(); +/////////////// from trivial_plugin ////////////////////// +void Scene_edit_polyhedron_item::draw_bbox(const Scene_interface::Bbox& bb ) const { + ::glBegin(GL_LINES); + gl_draw_edge(bb.xmin, bb.ymin, bb.zmin, + bb.xmax, bb.ymin, bb.zmin); + gl_draw_edge(bb.xmin, bb.ymin, bb.zmin, + bb.xmin, bb.ymax, bb.zmin); + gl_draw_edge(bb.xmin, bb.ymin, bb.zmin, + bb.xmin, bb.ymin, bb.zmax); + + gl_draw_edge(bb.xmax, bb.ymin, bb.zmin, + bb.xmax, bb.ymax, bb.zmin); + gl_draw_edge(bb.xmax, bb.ymin, bb.zmin, + bb.xmax, bb.ymin, bb.zmax); + + gl_draw_edge(bb.xmin, bb.ymax, bb.zmin, + bb.xmax, bb.ymax, bb.zmin); + gl_draw_edge(bb.xmin, bb.ymax, bb.zmin, + bb.xmin, bb.ymax, bb.zmax); + + gl_draw_edge(bb.xmin, bb.ymin, bb.zmax, + bb.xmax, bb.ymin, bb.zmax); + gl_draw_edge(bb.xmin, bb.ymin, bb.zmax, + bb.xmin, bb.ymax, bb.zmax); + + gl_draw_edge(bb.xmax, bb.ymax, bb.zmax, + bb.xmin, bb.ymax, bb.zmax); + gl_draw_edge(bb.xmax, bb.ymax, bb.zmax, + bb.xmax, bb.ymin, bb.zmax); + gl_draw_edge(bb.xmax, bb.ymax, bb.zmax, + bb.xmax, bb.ymax, bb.zmin); + ::glEnd(); } +void Scene_edit_polyhedron_item::gl_draw_edge(double px, double py, double pz, + double qx, double qy, double qz) const +{ + ::glVertex3d(px,py,pz); + ::glVertex3d(qx,qy,qz); +} +///////////////////////////////////////////////////////////// +void Scene_edit_polyhedron_item::changed() +{ update_normals(); } -void -Scene_edit_polyhedron_item:: -changed() +Scene_polyhedron_item* Scene_edit_polyhedron_item::to_polyhedron_item() { + Scene_polyhedron_item* poly_item_tmp = poly_item; + poly_item->set_color_vector_read_only(false); + own_poly_item=false; + return poly_item_tmp; +} + +Polyhedron* Scene_edit_polyhedron_item::polyhedron() +{ return poly_item->polyhedron(); } +const Polyhedron* Scene_edit_polyhedron_item::polyhedron() const +{ return poly_item->polyhedron(); } +QString Scene_edit_polyhedron_item::toolTip() const { - d->poly_item->changed(); - Scene_item::changed(); - d->orig_pos = current_position(); + if(!poly_item->polyhedron()) + return QString(); + + return QObject::tr("

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

" + "

Number of vertices: %2
" + "Number of edges: %3
" + "Number of facets: %4

") + .arg(this->name()) + .arg(poly_item->polyhedron()->size_of_vertices()) + .arg(poly_item->polyhedron()->size_of_halfedges()/2) + .arg(poly_item->polyhedron()->size_of_facets()) + .arg(this->renderingModeName()) + .arg(this->color().name()); +} +bool Scene_edit_polyhedron_item::isEmpty() const { + return poly_item->isEmpty(); +} +Scene_edit_polyhedron_item::Bbox Scene_edit_polyhedron_item::bbox() const { + return poly_item->bbox(); } -void -Scene_edit_polyhedron_item::select(double orig_x, - double orig_y, - double orig_z, - double dir_x, - double dir_y, - double dir_z) +void Scene_edit_polyhedron_item::setVisible(bool b) { + poly_item->setVisible(b); + Scene_item::setVisible(b); + if(!b) { + (*QGLViewer::QGLViewerPool().begin())->setManipulatedFrame(NULL); + } +} +void Scene_edit_polyhedron_item::setColor(QColor c) { + poly_item->setColor(c); + Scene_item::setColor(c); +} +void Scene_edit_polyhedron_item::setName(QString n) { + Scene_item::setName(n); + n.replace(" (edit)", ""); + poly_item->setName(n); +} +void Scene_edit_polyhedron_item::setRenderingMode(RenderingMode m) { + poly_item->setRenderingMode(m); + Scene_item::setRenderingMode(m); +} +Scene_edit_polyhedron_item* Scene_edit_polyhedron_item::clone() const { + return 0; +} +void Scene_edit_polyhedron_item::select( + double orig_x, + double orig_y, + double orig_z, + double dir_x, + double dir_y, + double dir_z) { Scene_item::select(orig_x, orig_y, @@ -128,7 +370,7 @@ dir_x, dir_y, dir_z); - d->poly_item->select(orig_x, + poly_item->select(orig_x, orig_y, orig_z, dir_x, @@ -136,104 +378,18 @@ dir_z); } -Scene_polyhedron_item* Scene_edit_polyhedron_item::to_polyhedron_item() const { - return d->poly_item; -} - -void -Scene_edit_polyhedron_item::setZoneSize(int i) { - if(i >= 0) { - std::cerr << "item \"" << qPrintable(name()) - << "\".setZoneSize(" << i << ")\n"; - d->zone_size = i; - } -} - -qglviewer::ManipulatedFrame* -Scene_edit_polyhedron_item::manipulatedFrame() { - return d->frame; -} - -struct Get_vertex_handle : public CGAL::Modifier_base +bool Scene_edit_polyhedron_item::keyPressEvent(QKeyEvent* e) { - Polyhedron::Vertex* vertex_ptr; - Vertex_handle vh; - void operator()(Polyhedron::HDS& hds) { - vh = hds.vertex_handle(vertex_ptr); + //setting/unsetting rotation constraints + if (e->key()==Qt::Key_R && !state.ctrl_pressing) + { + is_rot_free = !is_rot_free; + rot_constraint.setRotationConstraintType( is_rot_free? + qglviewer::AxisPlaneConstraint::FREE: + qglviewer::AxisPlaneConstraint::AXIS); + return true; } -}; - -void Scene_edit_polyhedron_item::vertex_has_been_selected(void* void_ptr) { - Polyhedron* poly = d->poly_item->polyhedron(); - - // Need a modifier to get access to the HDS, to get the vertex handle - // from the vertex pointer. - - Get_vertex_handle get_vertex_handle; - get_vertex_handle.vertex_ptr = static_cast(void_ptr); - - poly->delegate(get_vertex_handle); - Vertex_handle vh = get_vertex_handle.vh; - - std::cerr << "Selected vertex: " << void_ptr << " = " << vh->point() - << std::endl; - d->selected_vertices.clear(); - - d->selected_vertices.insert(vh); - - std::cerr << "d->zone_size = " << d->zone_size << std::endl; - // Naive way to compute the k-neighborhood of vh, with k==d->zone_size. - for(int i = 0; i < d->zone_size; ++i) { - std::set selected_vertices; - for(Selected_vertices_it - it = d->selected_vertices.begin(), - end = d->selected_vertices.end(); - it != end; ++it) { - selected_vertices.insert(*it); - } - BOOST_FOREACH(Vertex_handle v, selected_vertices) { - Polyhedron::Halfedge_around_vertex_circulator - he_it = v->vertex_begin(), he_it_end(he_it); - if(he_it != 0) { - do { - const Vertex_handle other_v = he_it->opposite()->vertex(); - if( d->selected_vertices.find(other_v) == d->selected_vertices.end() ) - { - d->selected_vertices.insert(other_v); - } - } while(++he_it != he_it_end); - } - } - } - const Kernel::Point_3& p = vh->point(); - d->orig_pos = p; - d->frame->setPosition(qglviewer::Vec(p.x(), p.y(), p.z())); - connect(d->frame, SIGNAL(modified()), - this, SIGNAL(modified())); - emit begin_edit(); -} - -Vertex_handle -Scene_edit_polyhedron_item::selected_vertex() const { - return d->selected_vertex; -} - -QList -Scene_edit_polyhedron_item::selected_vertices() const { - QList result; - BOOST_FOREACH(Vertex_handle vh, d->selected_vertices) { - result << vh; - } - return result; -} - -Kernel::Point_3 Scene_edit_polyhedron_item::current_position() const { - const qglviewer::Vec vec = d->frame->position(); - return Kernel::Point_3(vec.x, vec.y, vec.z); -} - -Kernel::Point_3 Scene_edit_polyhedron_item::original_position() const { - return d->orig_pos; + return false; } #include "Scene_edit_polyhedron_item.moc" diff -Nru cgal-4.4/demo/Polyhedron/Scene_edit_polyhedron_item.h cgal-4.5/demo/Polyhedron/Scene_edit_polyhedron_item.h --- cgal-4.4/demo/Polyhedron/Scene_edit_polyhedron_item.h 2012-11-13 13:13:59.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Scene_edit_polyhedron_item.h 2014-10-04 19:00:10.000000000 +0000 @@ -1,18 +1,172 @@ #ifndef SCENE_EDIT_POLYHEDRON_ITEM_H #define SCENE_EDIT_POLYHEDRON_ITEM_H - +//#define CGAL_PROFILE #include "Scene_edit_polyhedron_item_config.h" #include "Scene_polyhedron_item.h" -#include "Polyhedron_type.h" -#include +#include "Scene_polyhedron_item_k_ring_selection.h" +#include "Travel_isolated_components.h" -#include +#include +#include +#include -#include -#include +#include +#include -class QMenu; -struct Scene_edit_polyhedron_item_priv; +#include +#include +#include +#include + +#include "ui_Deform_mesh.h" +#include +#include + + +typedef Polyhedron::Vertex_handle Vertex_handle; +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef boost::graph_traits::vertex_iterator vertex_iterator; +typedef boost::graph_traits::in_edge_iterator in_edge_iterator; +typedef boost::graph_traits::out_edge_iterator out_edge_iterator; + +struct Array_based_vertex_point_map +{ +public: + typedef vertex_descriptor key_type; + typedef Polyhedron::Traits::Point_3 value_type; + typedef value_type& reference; + typedef boost::read_write_property_map_tag category; + Array_based_vertex_point_map(std::vector* positions) : positions(positions) {} + std::vector* positions; +}; + + +Array_based_vertex_point_map::value_type +get(Array_based_vertex_point_map, + Array_based_vertex_point_map::key_type key) { + return key->point(); +} + +void +put(Array_based_vertex_point_map pmap, + Array_based_vertex_point_map::key_type key, + Array_based_vertex_point_map::value_type val) { + key->point() = val; // to make things easy (ray selection after deformation, save to polyhedron after close etc), + // I also change point() of vertex together with positions list + // So that we do not need to pmap everywhere other than draw + std::size_t pos = key->id() * 3; + (*pmap.positions)[pos] = val.x(); + (*pmap.positions)[pos+1] = val.y(); + (*pmap.positions)[pos+2] = val.z(); +} + +typedef CGAL::Surface_mesh_deformation Deform_mesh; + + +typedef Deform_mesh::Point Point; + +/// For storing associated data with a group of control vertices +class Control_vertices_data +{ +public: + std::vector ctrl_vertices_group; + qglviewer::ManipulatedFrame* frame; // manframe assoc with a group of control vertices + qglviewer::Vec frame_initial_center; // initial center of frame + Scene_interface::Bbox bbox; // bbox of control vertices inside group + qglviewer::Vec rot_direction; // vector for constraint rotation +private: + std::vector initial_positions; + Deform_mesh* deform_mesh; + +public: + Control_vertices_data(Deform_mesh* deform_mesh, qglviewer::ManipulatedFrame* frame = 0) + : frame(frame), bbox(0,0,0,0,0,0), rot_direction(0.,0.,1.), deform_mesh(deform_mesh) + { } + void refresh() + { + for(std::vector::iterator it = ctrl_vertices_group.begin(); it != ctrl_vertices_group.end(); ) { + if(!deform_mesh->is_control_vertex(*it)) { + it = ctrl_vertices_group.erase(it); + } + else { ++it; } + } + + reset_initial_positions(); + frame_initial_center = calculate_initial_center(); + bbox = calculate_initial_bbox(); + + bool oldState = frame->blockSignals(true); // do not let it emit modified, which will cause a deformation + // but we are just adjusting the center so it does not require a deformation + frame->setOrientation(qglviewer::Quaternion()); + frame->setPosition(frame_initial_center); + frame->blockSignals(oldState); + } + void set_target_positions() + { + std::vector::iterator hb = ctrl_vertices_group.begin(); + for(std::vector::iterator it = initial_positions.begin(); it != initial_positions.end(); ++it, ++hb) + { + qglviewer::Vec dif_from_initial_center = (*it) - frame_initial_center; + qglviewer::Vec rotated = frame->orientation() * dif_from_initial_center; + qglviewer::Vec rotated_and_translated = rotated + frame->position(); + + deform_mesh->set_target_position(*hb, Point(rotated_and_translated.x, rotated_and_translated.y, rotated_and_translated.z) ); + } + } + +private: + void reset_initial_positions() + { + initial_positions.clear(); + + for(std::vector::iterator hb = ctrl_vertices_group.begin(); hb != ctrl_vertices_group.end(); ++hb) + { + qglviewer::Vec point((*hb)->point().x(), (*hb)->point().y(), (*hb)->point().z() ); + initial_positions.push_back(point); + } + } + qglviewer::Vec calculate_initial_center() + { + qglviewer::Vec center_acc(0, 0, 0); + if(initial_positions.empty()) {return center_acc; } + + for(std::vector::iterator it = initial_positions.begin(); it != initial_positions.end(); ++it) + { + center_acc += (*it); + } + return center_acc / initial_positions.size(); + } + Scene_interface::Bbox calculate_initial_bbox() + { + if(initial_positions.empty()) {return Scene_interface::Bbox(0,0,0,0,0,0); } + + const qglviewer::Vec& p_i = *(initial_positions.begin()); + Scene_interface::Bbox bbox(p_i.x, p_i.y, p_i.z, p_i.x, p_i.y, p_i.z); + + for(std::vector::iterator it = initial_positions.begin(); it != initial_positions.end(); ++it) + { + const qglviewer::Vec& p_i = (*it); + Scene_interface::Bbox bbox_it(p_i.x, p_i.y, p_i.z, p_i.x, p_i.y, p_i.z); + bbox = bbox + bbox_it; + } + return bbox; + } +}; + +// To hold pressing states together +struct Mouse_keyboard_state_deformation +{ + bool ctrl_pressing; + bool shift_pressing; + bool left_button_pressing; + bool right_button_pressing; + + Mouse_keyboard_state_deformation() + : ctrl_pressing(false), shift_pressing(false), left_button_pressing(false), right_button_pressing(false) + { } +}; // This class represents a polyhedron in the OpenGL scene class SCENE_EDIT_POLYHEDRON_ITEM_EXPORT Scene_edit_polyhedron_item @@ -22,68 +176,496 @@ /// Create an Scene_edit_polyhedron_item from a Scene_polyhedron_item. /// The ownership of the polyhedron is moved to the new edit_polyhedron /// item. - Scene_edit_polyhedron_item(Scene_polyhedron_item* poly_item); + Scene_edit_polyhedron_item(Scene_polyhedron_item* poly_item, Ui::DeformMesh* ui_widget, QMainWindow* mw); ~Scene_edit_polyhedron_item(); /// Returns 0, so that one cannot clone an "edit polyhedron" item. Scene_edit_polyhedron_item* clone() const; - - // // IO - // bool load(std::istream& in); - // bool save(std::ostream& out) const; // Function for displaying meta-data of the item QString toolTip() const; - // // Function to override the context menu - // QMenu* contextMenu(); + void setColor(QColor c); + void setName(QString n); + void setVisible(bool b); + void setRenderingMode(RenderingMode m); // Indicate if rendering mode is supported - bool supportsRenderingMode(RenderingMode m) const { return (m!=PointsPlusNormals); } + bool supportsRenderingMode(RenderingMode m) const { + return m == Gouraud; + } // Points/Wireframe/Flat/Gouraud OpenGL drawing in a display list void draw() const; - - bool manipulatable() const { return true; } - qglviewer::ManipulatedFrame* manipulatedFrame(); + void draw_edges() const; + void draw_bbox(const Scene_interface::Bbox& bb ) const; + void gl_draw_edge(double px, double py, double pz, + double qx, double qy, double qz) const; + void gl_draw_point(const Point& p) const; // Get wrapped polyhedron Polyhedron* polyhedron(); const Polyhedron* polyhedron() const; - // Functions related to the edition - Kernel::Point_3 original_position() const; - Kernel::Point_3 current_position() const; - Polyhedron::Vertex_handle selected_vertex() const; - QList selected_vertices() const; - /// Returns a Scene_polyhedron_item from the edit polyhedron item, and /// transfer the ownership of the polyhedron to it. /// The item 'this' must be destroy just after a call to this function. - Scene_polyhedron_item* to_polyhedron_item() const; + Scene_polyhedron_item* to_polyhedron_item(); // Get dimensions bool isFinite() const { return true; } bool isEmpty() const; Bbox bbox() const; + int get_k_ring() { return k_ring_selector.k_ring; } + void set_k_ring(int v) { k_ring_selector.k_ring = v; } + + // take mouse events from viewer, main-window does not work + // take keyboard events from main-window, which is more stable + bool eventFilter(QObject *target, QEvent *event); + +protected: + void timerEvent(QTimerEvent *event); + void draw_ROI_and_control_vertices() const; + public slots: void changed(); + void selected(const std::map& m) + { + bool any_changes = false; + for(std::map::const_iterator it = m.begin(); it != m.end(); ++it) + { + vertex_descriptor vh = it->first; + bool changed = false; + if(ui_widget->ROIRadioButton->isChecked()) { + if(ui_widget->InsertRadioButton->isChecked()) { changed = insert_roi_vertex(vh); } + else { changed = erase_roi_vertex(vh); } + } + else { + if(ui_widget->InsertRadioButton->isChecked()) { changed = insert_control_vertex(vh); } + else { changed = erase_control_vertex(vh); } + } + any_changes |= changed; + } + if(any_changes) { emit itemChanged(); } + } + void select(double orig_x, double orig_y, double orig_z, double dir_x, double dir_y, double dir_z); - void setZoneSize(int i); - void vertex_has_been_selected(void* vertex_handle); - -signals: - void begin_edit(); - void modified(); + void deform(); // deform the mesh +// members +private: + Ui::DeformMesh* ui_widget; + Scene_polyhedron_item* poly_item; + // For drawing + std::vector positions; + std::vector tris; + std::vector edges; + std::vector normals; + + Deform_mesh deform_mesh; + typedef std::list Ctrl_vertices_group_data_list; + Ctrl_vertices_group_data_list::iterator active_group; + Ctrl_vertices_group_data_list ctrl_vertex_frame_map; // keep list of group of control vertices with assoc data + + double length_of_axis; // for drawing axis at a group of control vertices + + // by interleaving 'viewer's events (check constructor), keep followings: + Mouse_keyboard_state_deformation state; + + //For constraint rotation + qglviewer::LocalConstraint rot_constraint; + bool is_rot_free; + + bool own_poly_item; //indicates if the poly_item should be deleted by the destructor + Scene_polyhedron_item_k_ring_selection k_ring_selector; + +public: + // Deformation related functions // + bool insert_control_vertex(vertex_descriptor v) + { + if(!is_there_any_ctrl_vertices_group()) { + print_message("There is no group of control vertices, create one!"); + return false; + } // no group of control vertices to insert + + bool inserted = deform_mesh.insert_control_vertex(v); + if(inserted) { + active_group->ctrl_vertices_group.push_back(v); + active_group->refresh(); + } + return inserted; + } + + bool insert_roi_vertex(vertex_descriptor v) + { + return deform_mesh.insert_roi_vertex(v); + } + + bool erase_control_vertex(vertex_descriptor v) + { + if(deform_mesh.erase_control_vertex(v)) // API should be safe enough to do that (without checking empty group of control vertices etc.) + { + refresh_all_group_centers(); // since we don't know which group of control vertices v is erased from, refresh all + return true; + } + + print_message("Selected vertex is not a control vertex!"); + return false; + } + + bool erase_roi_vertex(vertex_descriptor v) + { + erase_control_vertex(v); // erase control vertex + return deform_mesh.erase_roi_vertex(v); + } + + void set_all_vertices_as_roi() + { + vertex_iterator vb, ve; + for(boost::tie(vb, ve) = vertices(*polyhedron()); vb != ve; ++vb) + { + insert_roi_vertex(*vb); + } + } + + void clear_roi() + { + for(Ctrl_vertices_group_data_list::iterator it = ctrl_vertex_frame_map.begin(); it != ctrl_vertex_frame_map.end(); ++it) + { + delete it->frame; + } + ctrl_vertex_frame_map.clear(); + deform_mesh.clear_roi_vertices(); + + create_ctrl_vertices_group(); // create one new group of control vertices + } + + void create_ctrl_vertices_group() + { + for(Ctrl_vertices_group_data_list::iterator it = ctrl_vertex_frame_map.begin(); it != ctrl_vertex_frame_map.end(); ++it) { + if(it->ctrl_vertices_group.empty()) { + active_group = it; + return; + } + } + + // No empty group of control vertices + qglviewer::ManipulatedFrame* new_frame = new qglviewer::ManipulatedFrame(); + new_frame->setRotationSensitivity(2.0f); + + Control_vertices_data hgd(&deform_mesh, new_frame); + ctrl_vertex_frame_map.push_back(hgd); + hgd.refresh(); + + active_group = --ctrl_vertex_frame_map.end(); + + connect(new_frame, SIGNAL(modified()), this, SLOT(deform())); // OK we are deforming via timer, + // but it makes demo more responsive if we also add this signal + emit itemChanged(); + + print_message("A new empty group of control vertices is created."); + } + + void delete_ctrl_vertices_group(bool create_new = true) + { + if(!is_there_any_ctrl_vertices_group()) { + print_message("There is no group of control vertices to be deleted!"); + return; + } // no group of control vertices + + // delete group representative + for(Ctrl_vertices_group_data_list::iterator it = ctrl_vertex_frame_map.begin(); it != ctrl_vertex_frame_map.end(); ++it) + { + if(it == active_group) + { + delete it->frame; + for(std::vector::iterator v_it = it->ctrl_vertices_group.begin(); v_it != it->ctrl_vertices_group.end(); ++v_it) { + deform_mesh.erase_control_vertex(*v_it); + } + ctrl_vertex_frame_map.erase(it); + break; + } + } + + // assign another ctrl_vertices_group to active_group + Ctrl_vertices_group_data_list::iterator hgb, hge; + if( is_there_any_ctrl_vertices_group(hgb, hge) ) + { + active_group = hgb; + } // no group of control vertices + else if(create_new) + { + create_ctrl_vertices_group(); + } + } + + void prev_ctrl_vertices_group() + { + Ctrl_vertices_group_data_list::iterator hgb, hge; + if( !is_there_any_ctrl_vertices_group(hgb, hge) ) { + print_message("There is no group of control vertices to iterate on!"); + return; + } + // shift + if(hgb == active_group) { active_group = --hge; } + else {--active_group; } + } + + void next_ctrl_vertices_group() + { + Ctrl_vertices_group_data_list::iterator hgb, hge; + if( !is_there_any_ctrl_vertices_group(hgb, hge) ) { + print_message("There is no group of control vertices to iterate on!"); + return; + } + // shift + if(--hge == active_group) { active_group = hgb; } + else {++active_group; } + } + + void pivoting_end() + { + for(Ctrl_vertices_group_data_list::iterator it = ctrl_vertex_frame_map.begin(); it != ctrl_vertex_frame_map.end(); ++it) + { + //update constraint rotation vector, set only for the last group + it->rot_direction = it->frame->rotation().rotate( qglviewer::Vec(0.,0.,1.) ); + //translate center of the frame + qglviewer::Vec vec= it->frame->position(); + it->refresh(); + it->frame_initial_center = vec; + it->frame->setPosition(vec); + } + for(Ctrl_vertices_group_data_list::iterator it = ctrl_vertex_frame_map.begin(); it != ctrl_vertex_frame_map.end(); ++it) + { + it->frame->blockSignals(false); + } + } + + void pivoting_begin() + { + is_rot_free=true; + rot_constraint.setRotationConstraintType(qglviewer::AxisPlaneConstraint::FREE); + + // just block signals to prevent deformation + for(Ctrl_vertices_group_data_list::iterator it = ctrl_vertex_frame_map.begin(); it != ctrl_vertex_frame_map.end(); ++it) + { + it->frame->blockSignals(true); + } + } + + void save_roi(const char* file_name) const + { + std::ofstream out(file_name); + // save roi + out << deform_mesh.roi_vertices().size() << std::endl; + BOOST_FOREACH(vertex_descriptor vd, deform_mesh.roi_vertices()) + { + out << vd->id() << " "; + } + out << std::endl; + // save control vertices + + out << ctrl_vertex_frame_map.size() << std::endl; // control vertices count + for(Ctrl_vertices_group_data_list::const_iterator hgb = ctrl_vertex_frame_map.begin(); hgb != ctrl_vertex_frame_map.end(); ++hgb) { + + out << hgb->ctrl_vertices_group.size() << std::endl; + for(std::vector::const_iterator hb = hgb->ctrl_vertices_group.begin(); hb != hgb->ctrl_vertices_group.end(); ++hb) + { + out << (*hb)->id() << " "; + } + out << std::endl; + } + } + + void read_roi(const char* file_name) + { + clear_roi(); + delete_ctrl_vertices_group(false); + + // put vertices to vector + std::vector all_vertices; + all_vertices.reserve(num_vertices(deform_mesh.halfedge_graph())); + vertex_iterator vb, ve; + for(boost::tie(vb, ve) = vertices(deform_mesh.halfedge_graph()); vb != ve; ++vb) { + all_vertices.push_back(*vb); + } + // read roi + std::ifstream in(file_name); + int roi_size; + in >> roi_size; + while(roi_size-- > 0) + { + std::size_t v_id; + in >> v_id; + insert_roi_vertex(all_vertices[v_id]); + } + // read control vertices + int ctrl_vertices_group_size; + in >> ctrl_vertices_group_size; + while(ctrl_vertices_group_size-- > 0) + { + create_ctrl_vertices_group(); + int ctrl_size; + in >> ctrl_size; + while(ctrl_size-- > 0) + { + std::size_t v_id; + in >> v_id; + insert_control_vertex(all_vertices[v_id]); + } + } + } + + void overwrite_deform_object() + { + deform_mesh.overwrite_initial_geometry(); + + refresh_all_group_centers(); + } + + struct Is_selected { + Deform_mesh& dm; + Is_selected(Deform_mesh& dm) : dm(dm) {} + bool is_selected(Vertex_handle vh) const { + return dm.is_roi_vertex(vh); + } + }; + + boost::optional get_minimum_isolated_component() { + Travel_isolated_components::Minimum_visitor visitor; + Travel_isolated_components().travel + (polyhedron()->vertices_begin(), polyhedron()->vertices_end(), + polyhedron()->size_of_vertices(), Is_selected(deform_mesh), visitor); + return visitor.minimum; + } + + struct Select_roi_output { + Select_roi_output(Deform_mesh* dm) : dm(dm) { } + void operator()(Vertex_handle vh) { + dm->insert_roi_vertex(vh); + } + Deform_mesh* dm; + }; + + boost::optional select_isolated_components(std::size_t threshold) { + typedef boost::function_output_iterator Output_iterator; + Output_iterator out(&deform_mesh); + + Travel_isolated_components::Selection_visitor visitor(threshold, out); + Travel_isolated_components().travel + (polyhedron()->vertices_begin(), polyhedron()->vertices_end(), + polyhedron()->size_of_vertices(), Is_selected(deform_mesh), visitor); + + if(visitor.any_inserted) { emit itemChanged(); } + return visitor.minimum_visitor.minimum; + } protected: - Scene_edit_polyhedron_item_priv* d; - + // Deformation related functions // + void print_message(const QString& /*message*/) + { + // std::cout << message.toStdString() << std::endl; + } + + bool is_there_any_ctrl_vertices_group(Ctrl_vertices_group_data_list::iterator& hgb, Ctrl_vertices_group_data_list::iterator& hge) + { + hgb = ctrl_vertex_frame_map.begin(); hge = ctrl_vertex_frame_map.end(); + return hgb != hge; + } + + bool is_there_any_ctrl_vertices_group() + { + Ctrl_vertices_group_data_list::iterator hgb, hge; + return is_there_any_ctrl_vertices_group(hgb, hge); + } + + bool is_there_any_ctrl_vertices() + { + Ctrl_vertices_group_data_list::iterator hgb, hge; + if(!is_there_any_ctrl_vertices_group(hgb, hge)) { return false; } // there isn't any group of control vertices + + for(; hgb != hge; ++hgb) // check inside groups of control vertices + { + if(!hgb->ctrl_vertices_group.empty()) { return true; } + } + return false; + } + + void refresh_all_group_centers() + { + for(Ctrl_vertices_group_data_list::iterator it = ctrl_vertex_frame_map.begin(); it != ctrl_vertex_frame_map.end(); ++it) + { it->refresh(); } + } + + bool activate_closest_manipulated_frame(int x, int y) + { + if(state.ctrl_pressing && (state.left_button_pressing || state.right_button_pressing) ) + { // user is deforming currently don't change the state + return false; + } + if(ctrl_vertex_frame_map.empty()) { return false; } + + QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + qglviewer::Camera* camera = viewer->camera(); + + if(!state.ctrl_pressing) + { + if(viewer->manipulatedFrame() == NULL) + { return false;} + viewer->setManipulatedFrame(NULL); + return true; + } + + // now find closest frame and make it active manipulated frame + Ctrl_vertices_group_data_list::iterator min_it = ctrl_vertex_frame_map.begin(); + const qglviewer::Vec& pos_it = camera->projectedCoordinatesOf(min_it->frame->position()); + float min_dist = std::pow(pos_it.x - x, 2) + std::pow(pos_it.y - y, 2); + + for(Ctrl_vertices_group_data_list::iterator it = ctrl_vertex_frame_map.begin(); it != ctrl_vertex_frame_map.end(); ++it) + { + const qglviewer::Vec& pos_it = camera->projectedCoordinatesOf(it->frame->position()); + float dist = std::pow(pos_it.x - x, 2) + std::pow(pos_it.y - y, 2); + if(dist < min_dist) { + min_dist = dist; + min_it = it; + } + } + + //set rotation constraint for the manipulated frame + if (!is_rot_free){ + rot_constraint.setRotationConstraintDirection(min_it->rot_direction); + rot_constraint.setRotationConstraintType(qglviewer::AxisPlaneConstraint::AXIS); + min_it->frame->setConstraint(&rot_constraint); + } + else + rot_constraint.setRotationConstraintType(qglviewer::AxisPlaneConstraint::FREE); + + if(viewer->manipulatedFrame() == min_it->frame) + { return false; } + viewer->setManipulatedFrame(min_it->frame); + + return true; + } + + bool keyPressEvent(QKeyEvent* e); + + void update_normals() { + BOOST_FOREACH(vertex_descriptor vd, deform_mesh.roi_vertices()) + { + std::size_t id = vd->id(); + const Polyhedron::Traits::Vector_3& n = + compute_vertex_normal(*vd); + normals[id*3] = n.x(); + normals[id*3+1] = n.y(); + normals[id*3+2] = n.z(); + } + } +protected: + GLUquadric* quadric; // for drawing spheres }; // end class Scene_edit_polyhedron_item #endif // SCENE_EDIT_POLYHEDRON_ITEM_H diff -Nru cgal-4.4/demo/Polyhedron/Scene.h cgal-4.5/demo/Polyhedron/Scene.h --- cgal-4.4/demo/Polyhedron/Scene.h 2013-09-07 19:00:31.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Scene.h 2014-08-29 13:58:17.000000000 +0000 @@ -21,6 +21,7 @@ class QEvent; class QMouseEvent; +namespace GlSplat { class SplatRenderer; } class Viewer_interface; @@ -60,6 +61,7 @@ int numberOfEntries() const; const QList& entries() const { return m_entries; } Q_INVOKABLE Scene_item* item(int) const ; + Item_id item_id(Scene_item*) const; //! \todo Replace Index based selection functionality with those //! functions. @@ -147,7 +149,12 @@ QList selected_items_list; int item_A; int item_B; - +#ifdef CGAL_GLEW_ENABLED + static GlSplat::SplatRenderer* ms_splatting; + static int ms_splattingCounter; +public: + static GlSplat::SplatRenderer* splatting(); +#endif }; // end class Scene class SCENE_EXPORT SceneDelegate : public QItemDelegate diff -Nru cgal-4.4/demo/Polyhedron/Scene_implicit_function_item.cpp cgal-4.5/demo/Polyhedron/Scene_implicit_function_item.cpp --- cgal-4.4/demo/Polyhedron/Scene_implicit_function_item.cpp 2013-02-16 20:00:28.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Scene_implicit_function_item.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -110,6 +110,7 @@ { switch ( m ) { + case Splatting: case Gouraud: return false; diff -Nru cgal-4.4/demo/Polyhedron/Scene_item.cpp cgal-4.5/demo/Polyhedron/Scene_item.cpp --- cgal-4.4/demo/Polyhedron/Scene_item.cpp 2012-11-13 13:13:59.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Scene_item.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -29,6 +29,8 @@ return QObject::tr("Gouraud"); case PointsPlusNormals: return QObject::tr("pts+normals"); + case Splatting: + return QObject::tr("splats"); default: Q_ASSERT(false); return QObject::tr("unknown"); @@ -50,6 +52,8 @@ return SLOT(setGouraudMode()); case PointsPlusNormals: return SLOT(setPointsPlusNormalsMode()); + case Splatting: + return SLOT(setSplattingMode()); default: Q_ASSERT(false); return ""; @@ -61,7 +65,6 @@ { return modeName(renderingMode()); } - QMenu* Scene_item::contextMenu() { if(defaultContextMenu) { diff -Nru cgal-4.4/demo/Polyhedron/Scene_item.h cgal-4.5/demo/Polyhedron/Scene_item.h --- cgal-4.4/demo/Polyhedron/Scene_item.h 2013-03-07 20:00:26.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Scene_item.h 2014-08-29 13:58:17.000000000 +0000 @@ -50,6 +50,9 @@ // Points OpenGL drawing virtual void draw_points() const { draw(); } virtual void draw_points(Viewer_interface*) const { draw_points(); } + // Splats OpenGL drawing + virtual void draw_splats() const {} + virtual void draw_splats(Viewer_interface*) const {draw_splats();} // Functions for displaying meta-data of the item virtual QString toolTip() const = 0; @@ -122,6 +125,10 @@ setRenderingMode(PointsPlusNormals); } + void setSplattingMode(){ + setRenderingMode(Splatting); + } + virtual void itemAboutToBeDestroyed(Scene_item*); virtual void select(double orig_x, diff -Nru cgal-4.4/demo/Polyhedron/Scene_nef_polyhedron_item.h cgal-4.5/demo/Polyhedron/Scene_nef_polyhedron_item.h --- cgal-4.4/demo/Polyhedron/Scene_nef_polyhedron_item.h 2012-11-13 13:13:59.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Scene_nef_polyhedron_item.h 2014-08-29 13:58:17.000000000 +0000 @@ -28,7 +28,7 @@ QString toolTip() const; // Indicate if rendering mode is supported - virtual bool supportsRenderingMode(RenderingMode m) const { return m != Gouraud; } // CHECK THIS! + virtual bool supportsRenderingMode(RenderingMode m) const { return m != Gouraud && m!=Splatting; } // CHECK THIS! // OpenGL drawing in a display list void direct_draw() const; // Wireframe OpenGL drawing diff -Nru cgal-4.4/demo/Polyhedron/Scene_points_with_normal_item.cpp cgal-4.5/demo/Polyhedron/Scene_points_with_normal_item.cpp --- cgal-4.4/demo/Polyhedron/Scene_points_with_normal_item.cpp 2013-10-05 19:00:24.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Scene_points_with_normal_item.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -23,23 +23,29 @@ Scene_points_with_normal_item::Scene_points_with_normal_item() : Scene_item_with_display_list(), - m_points(new Point_set) + m_points(new Point_set), + m_has_normals(false) { - setRenderingMode(PointsPlusNormals); + setRenderingMode(Points); } // Copy constructor Scene_points_with_normal_item::Scene_points_with_normal_item(const Scene_points_with_normal_item& toCopy) : Scene_item_with_display_list(), // do not call superclass' copy constructor - m_points(new Point_set(*toCopy.m_points)) + m_points(new Point_set(*toCopy.m_points)), + m_has_normals(toCopy.m_has_normals) { - setRenderingMode(PointsPlusNormals); + if (m_has_normals) + setRenderingMode(PointsPlusNormals); + else + setRenderingMode(Points); } // Converts polyhedron to point set Scene_points_with_normal_item::Scene_points_with_normal_item(const Polyhedron& input_mesh) : Scene_item_with_display_list(), - m_points(new Point_set) + m_points(new Point_set), + m_has_normals(true) { // Converts Polyhedron vertices to point set. // Computes vertices normal from connectivity. @@ -144,6 +150,19 @@ CGAL::make_normal_of_point_with_normal_pmap(Point_set::value_type())) && !isEmpty(); + if (ok) + { + for (Point_set::iterator it=m_points->begin(), + end=m_points->end();it!=end; ++it) + { + if (it->normal() != CGAL::NULL_VECTOR) + { + m_has_normals=true; + setRenderingMode(PointsPlusNormals); + break; + } + } + } return ok; } @@ -173,7 +192,9 @@ bool Scene_points_with_normal_item::supportsRenderingMode(RenderingMode m) const { - return m==Points || m==PointsPlusNormals; + return m==Points || + ( has_normals() && + ( m==PointsPlusNormals || m==Splatting ) ); } // Points OpenGL drawing in a display list @@ -191,14 +212,24 @@ Q_ASSERT(m_points != NULL); // Draw normals + Kernel::Sphere_3 region_of_interest = m_points->region_of_interest(); + float normal_length = (float)std::sqrt(region_of_interest.squared_radius() / 1000.); + + m_points->gl_draw_normals(normal_length); +} + +void Scene_points_with_normal_item::draw_splats() const +{ + Q_ASSERT(m_points != NULL); + + // Draw splats bool points_have_normals = (m_points->begin() != m_points->end() && m_points->begin()->normal() != CGAL::NULL_VECTOR); - if(points_have_normals) + bool points_have_radii = (m_points->begin() != m_points->end() && + m_points->begin()->radius() != 0); + if(points_have_normals && points_have_radii) { - Kernel::Sphere_3 region_of_interest = m_points->region_of_interest(); - float normal_length = (float)std::sqrt(region_of_interest.squared_radius() / 1000.); - - m_points->gl_draw_normals(normal_length); + m_points->gl_draw_splats(); } } @@ -300,6 +331,22 @@ void Scene_points_with_normal_item::setRenderingMode(RenderingMode m) { Scene_item_with_display_list::setRenderingMode(m); + if (rendering_mode==Splatting && (!m_points->are_radii_uptodate())) + { + computes_local_spacing(6); // default value = small + } } +bool Scene_points_with_normal_item::has_normals() const { return m_has_normals; } + +void Scene_points_with_normal_item::set_has_normals(bool b) { + if (b!=m_has_normals){ + m_has_normals=b; + //reset the context menu + delete this->defaultContextMenu; + this->defaultContextMenu = 0; + } +} + + #include "Scene_points_with_normal_item.moc" diff -Nru cgal-4.4/demo/Polyhedron/Scene_points_with_normal_item.h cgal-4.5/demo/Polyhedron/Scene_points_with_normal_item.h --- cgal-4.4/demo/Polyhedron/Scene_points_with_normal_item.h 2013-07-20 19:00:36.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Scene_points_with_normal_item.h 2014-08-29 13:58:17.000000000 +0000 @@ -53,6 +53,9 @@ void draw_normals() const; virtual void draw_edges() const { draw_normals(); }//to tweak scene + // Splat OpenGL drawing + virtual void draw_splats() const; + // Gets wrapped point set Point_set* point_set(); const Point_set* point_set() const; @@ -67,6 +70,9 @@ // computes the local point spacing (aka radius) of each point void computes_local_spacing(int k); + bool has_normals() const; + void set_has_normals(bool b); + public slots: // Delete selection virtual void deleteSelection(); @@ -78,6 +84,7 @@ // Data private: Point_set* m_points; + bool m_has_normals; QAction* actionDeleteSelection; QAction* actionResetSelection; QAction* actionSelectDuplicatedPoints; diff -Nru cgal-4.4/demo/Polyhedron/Scene_polygon_soup_item.cpp cgal-4.5/demo/Polyhedron/Scene_polygon_soup_item.cpp --- cgal-4.4/demo/Polyhedron/Scene_polygon_soup_item.cpp 2013-08-03 19:00:28.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Scene_polygon_soup_item.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -19,6 +19,7 @@ #include #include +#include typedef Kernel::Point_3 Point_3; @@ -306,7 +307,15 @@ CGAL::Polygon_soup_to_polyhedron_3 builder( soup->points, soup->polygons); out_polyhedron->delegate(builder); - return out_polyhedron->size_of_vertices() > 0; + + if(out_polyhedron->size_of_vertices() > 0) { + // Also check whether the consistent orientation is fine + if(!CGAL::is_oriented(*out_polyhedron)) { + out_polyhedron->inside_out(); + } + return true; + } + return false; } QString diff -Nru cgal-4.4/demo/Polyhedron/Scene_polygon_soup_item.h cgal-4.5/demo/Polyhedron/Scene_polygon_soup_item.h --- cgal-4.4/demo/Polyhedron/Scene_polygon_soup_item.h 2012-11-13 13:13:59.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Scene_polygon_soup_item.h 2014-08-29 13:58:17.000000000 +0000 @@ -26,7 +26,7 @@ QString toolTip() const; // Indicate if rendering mode is supported - virtual bool supportsRenderingMode(RenderingMode m) const { return (m!=Gouraud && m!=PointsPlusNormals); } // CHECK THIS! + virtual bool supportsRenderingMode(RenderingMode m) const { return (m!=Gouraud && m!=PointsPlusNormals && m!=Splatting); } // CHECK THIS! // OpenGL drawing in a display list void direct_draw() const; void draw_points() const; diff -Nru cgal-4.4/demo/Polyhedron/Scene_polyhedron_item.cpp cgal-4.5/demo/Polyhedron/Scene_polyhedron_item.cpp --- cgal-4.4/demo/Polyhedron/Scene_polyhedron_item.cpp 2013-08-03 19:00:28.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Scene_polyhedron_item.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -28,8 +28,8 @@ Polyhedron* poly = item->polyhedron(); if(poly) { Input_facets_AABB_tree* tree = - new Input_facets_AABB_tree(poly->facets_begin(), - poly->facets_end(), + new Input_facets_AABB_tree(faces(*poly).first, + faces(*poly).second, *poly); item->setProperty(aabb_property_name, QVariant::fromValue(tree)); @@ -230,6 +230,7 @@ void Scene_polyhedron_item::set_erase_next_picked_facet(bool b) { + if(b) { facet_picking_m = true; } // automatically activate facet_picking erase_next_picked_facet_m = b; } @@ -299,6 +300,7 @@ Scene_polyhedron_item:: changed() { + emit item_is_about_to_be_changed(); delete_aabb_tree(this); init(); Base::changed(); @@ -377,20 +379,42 @@ nearest_v = v; } } - std::cerr << "Selected vertex: " << v->point() << std::endl; + emit selected_vertex((void*)(&*nearest_v)); } + + if(QObject::receivers(SIGNAL(selected_edge(void*))) > 0 + || QObject::receivers(SIGNAL(selected_halfedge(void*))) > 0) + { + Polyhedron::Halfedge_around_facet_circulator + he_it = selected_fh->facet_begin(), + around_end = he_it; + + Polyhedron::Halfedge_handle nearest_h = he_it; + Kernel::FT sq_dist = CGAL::squared_distance(*closest_point, + Kernel::Segment_3(he_it->vertex()->point(), he_it->opposite()->vertex()->point())); + + while(++he_it != around_end) { + Kernel::FT new_sq_dist = CGAL::squared_distance(*closest_point, + Kernel::Segment_3(he_it->vertex()->point(), he_it->opposite()->vertex()->point())); + if(new_sq_dist < sq_dist) { + sq_dist = new_sq_dist; + nearest_h = he_it; + } + } + + emit selected_halfedge((void*)(&*nearest_h)); + emit selected_edge((void*)(std::min)(&*nearest_h, &*nearest_h->opposite())); + } emit selected_facet((void*)(&*selected_fh)); if(erase_next_picked_facet_m) { polyhedron()->erase_facet(selected_fh->halfedge()); polyhedron()->normalize_border(); - set_erase_next_picked_facet(false); + //set_erase_next_picked_facet(false); changed(); emit itemChanged(); } - std::cerr << "Facet selected. patch_id=" - << selected_fh->patch_id() << std::endl; } } } diff -Nru cgal-4.4/demo/Polyhedron/Scene_polyhedron_item_decorator_config.h cgal-4.5/demo/Polyhedron/Scene_polyhedron_item_decorator_config.h --- cgal-4.4/demo/Polyhedron/Scene_polyhedron_item_decorator_config.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Scene_polyhedron_item_decorator_config.h 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,10 @@ +#ifndef SCENE_POLYHEDRON_ITEM_DECORATOR_CONFIG_H +#define SCENE_POLYHEDRON_ITEM_DECORATOR_CONFIG_H + +#ifdef scene_polyhedron_item_decorator_EXPORTS +# define SCENE_POLYHEDRON_ITEM_DECORATOR_EXPORT Q_DECL_EXPORT +#else +# define SCENE_POLYHEDRON_ITEM_DECORATOR_EXPORT Q_DECL_IMPORT +#endif + +#endif // SCENE_POLYHEDRON_ITEM_DECORATOR_CONFIG_H diff -Nru cgal-4.4/demo/Polyhedron/Scene_polyhedron_item_decorator.cpp cgal-4.5/demo/Polyhedron/Scene_polyhedron_item_decorator.cpp --- cgal-4.4/demo/Polyhedron/Scene_polyhedron_item_decorator.cpp 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Scene_polyhedron_item_decorator.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,102 @@ +#include "Scene_polyhedron_item_decorator.h" +#include "Polyhedron_type.h" + +Scene_polyhedron_item_decorator::Scene_polyhedron_item_decorator + (Scene_polyhedron_item* poly_item, bool delete_item) + : poly_item(poly_item), delete_poly_item(delete_item) +{ } + +Scene_polyhedron_item_decorator::~Scene_polyhedron_item_decorator() +{ + if(delete_poly_item) { delete poly_item; } +} + +Scene_polyhedron_item_decorator* +Scene_polyhedron_item_decorator::clone() const { + return 0; +} + +QString +Scene_polyhedron_item_decorator::toolTip() const +{ + if(!poly_item->polyhedron()) + return QString(); + + return QObject::tr("

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

" + "

Number of vertices: %2
" + "Number of edges: %3
" + "Number of facets: %4

") + .arg(this->name()) + .arg(poly_item->polyhedron()->size_of_vertices()) + .arg(poly_item->polyhedron()->size_of_halfedges()/2) + .arg(poly_item->polyhedron()->size_of_facets()) + .arg(this->renderingModeName()) + .arg(this->color().name()); +} + +void Scene_polyhedron_item_decorator::draw() const { + poly_item->draw(); +} + +void Scene_polyhedron_item_decorator::draw_edges() const { + poly_item->draw_edges(); +} + +Polyhedron* +Scene_polyhedron_item_decorator::polyhedron() +{ return poly_item->polyhedron(); } + +const Polyhedron* +Scene_polyhedron_item_decorator::polyhedron() const +{ return poly_item->polyhedron(); } + +bool +Scene_polyhedron_item_decorator::isEmpty() const { + return poly_item->isEmpty(); +} + +Scene_polyhedron_item_decorator::Bbox +Scene_polyhedron_item_decorator::bbox() const { + return poly_item->bbox(); +} + + +void +Scene_polyhedron_item_decorator:: +changed() +{ + poly_item->changed(); + Scene_item::changed(); +} + +void +Scene_polyhedron_item_decorator::select(double orig_x, + double orig_y, + double orig_z, + double dir_x, + double dir_y, + double dir_z) +{ + Scene_item::select(orig_x, + orig_y, + orig_z, + dir_x, + dir_y, + dir_z); + poly_item->select(orig_x, + orig_y, + orig_z, + dir_x, + dir_y, + dir_z); +} + +Scene_polyhedron_item* Scene_polyhedron_item_decorator::polyhedron_item() const { + return poly_item; +} + +void Scene_polyhedron_item_decorator::set_polyhedron_item(Scene_polyhedron_item* poly_item) { + this->poly_item = poly_item; +} + +#include "Scene_polyhedron_item_decorator.moc" diff -Nru cgal-4.4/demo/Polyhedron/Scene_polyhedron_item_decorator.h cgal-4.5/demo/Polyhedron/Scene_polyhedron_item_decorator.h --- cgal-4.4/demo/Polyhedron/Scene_polyhedron_item_decorator.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Scene_polyhedron_item_decorator.h 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,65 @@ +#ifndef SCENE_POLYHEDRON_ITEM_DECORATOR_H +#define SCENE_POLYHEDRON_ITEM_DECORATOR_H +#include "Scene_polyhedron_item_decorator_config.h" +#include "Scene_polyhedron_item.h" + +// This class is a decorator for Scene_polyhedron_item yet it does not inherit it but Scene_item +class SCENE_POLYHEDRON_ITEM_DECORATOR_EXPORT Scene_polyhedron_item_decorator + : public Scene_item { + Q_OBJECT +public: + /// Create an Scene_polyhedron_item_decorator from a Scene_polyhedron_item. + + Scene_polyhedron_item_decorator(Scene_polyhedron_item* poly_item, bool delete_item = true); + ~Scene_polyhedron_item_decorator(); + + /// Returns 0, so that one cannot clone decorator + Scene_polyhedron_item_decorator* clone() const; + + // // IO + // bool load(std::istream& in); + // bool save(std::ostream& out) const; + + // Function for displaying meta-data of the item + QString toolTip() const; + + // // Function to override the context menu + // QMenu* contextMenu(); + + // Indicate if rendering mode is supported + bool supportsRenderingMode(RenderingMode m) const { return (m!=PointsPlusNormals && m!=Splatting); } + // Points/Wireframe/Flat/Gouraud OpenGL drawing in a display list + // dispatch to poly_item direct_draw and direct_draw_edges + void draw() const; + void draw_edges() const; + + // Get wrapped polyhedron + Polyhedron* polyhedron(); + const Polyhedron* polyhedron() const; + + Scene_polyhedron_item* polyhedron_item() const; + void set_polyhedron_item(Scene_polyhedron_item* poly_item); + + // Get dimensions + bool isFinite() const { return true; } + bool isEmpty() const; + Bbox bbox() const; + + bool delete_item() { return delete_poly_item; } + void set_delete_item(bool delete_item) { delete_poly_item = delete_item; } + +public slots: + void changed(); + void select(double orig_x, + double orig_y, + double orig_z, + double dir_x, + double dir_y, + double dir_z); + +protected: + Scene_polyhedron_item* poly_item; + bool delete_poly_item; +}; // end class Scene_polyhedron_item_decorator + +#endif // SCENE_POLYHEDRON_ITEM_DECORATOR_H diff -Nru cgal-4.4/demo/Polyhedron/Scene_polyhedron_item.h cgal-4.5/demo/Polyhedron/Scene_polyhedron_item.h --- cgal-4.4/demo/Polyhedron/Scene_polyhedron_item.h 2012-11-13 13:13:59.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Scene_polyhedron_item.h 2014-08-29 13:58:17.000000000 +0000 @@ -37,7 +37,7 @@ QMenu* contextMenu(); // Indicate if rendering mode is supported - virtual bool supportsRenderingMode(RenderingMode m) const { return (m!=PointsPlusNormals); } + virtual bool supportsRenderingMode(RenderingMode m) const { return (m!=PointsPlusNormals && m!=Splatting); } // Points/Wireframe/Flat/Gouraud OpenGL drawing in a display list virtual void direct_draw() const; virtual void direct_draw_edges() const; @@ -73,6 +73,9 @@ signals: void selected_vertex(void*); void selected_facet(void*); + void selected_edge(void*); + void selected_halfedge(void*); + void item_is_about_to_be_changed(); // emitted in changed() private: // Initialization diff -Nru cgal-4.4/demo/Polyhedron/Scene_polyhedron_item_k_ring_selection_config.h cgal-4.5/demo/Polyhedron/Scene_polyhedron_item_k_ring_selection_config.h --- cgal-4.4/demo/Polyhedron/Scene_polyhedron_item_k_ring_selection_config.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Scene_polyhedron_item_k_ring_selection_config.h 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,10 @@ +#ifndef SCENE_POLYHEDRON_ITEM_K_RING_SELECTION_CONFIG_H +#define SCENE_POLYHEDRON_ITEM_K_RING_SELECTION_CONFIG_H + +#ifdef scene_polyhedron_item_k_ring_selection_EXPORTS +# define SCENE_POLYHEDRON_ITEM_K_RING_SELECTION_EXPORT Q_DECL_EXPORT +#else +# define SCENE_POLYHEDRON_ITEM_K_RING_SELECTION_EXPORT Q_DECL_IMPORT +#endif + +#endif // SCENE_POLYHEDRON_ITEM_K_RING_SELECTION_CONFIG_H diff -Nru cgal-4.4/demo/Polyhedron/Scene_polyhedron_item_k_ring_selection.cpp cgal-4.5/demo/Polyhedron/Scene_polyhedron_item_k_ring_selection.cpp --- cgal-4.4/demo/Polyhedron/Scene_polyhedron_item_k_ring_selection.cpp 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Scene_polyhedron_item_k_ring_selection.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,2 @@ +#include "Scene_polyhedron_item_k_ring_selection.h" +#include "Scene_polyhedron_item_k_ring_selection.moc" diff -Nru cgal-4.4/demo/Polyhedron/Scene_polyhedron_item_k_ring_selection.h cgal-4.5/demo/Polyhedron/Scene_polyhedron_item_k_ring_selection.h --- cgal-4.4/demo/Polyhedron/Scene_polyhedron_item_k_ring_selection.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Scene_polyhedron_item_k_ring_selection.h 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,154 @@ +#ifndef SCENE_POLYHEDRON_ITEM_K_RING_SELECTION_H +#define SCENE_POLYHEDRON_ITEM_K_RING_SELECTION_H +#include "Scene_polyhedron_item_k_ring_selection_config.h" +#include "Polyhedron_type.h" +#include "Scene_polyhedron_item.h" + +#include +#include +#include +#include +#include + +#include +#include +#include "One_ring_iterators.h" + +class SCENE_POLYHEDRON_ITEM_K_RING_SELECTION_EXPORT Scene_polyhedron_item_k_ring_selection + : public QObject +{ + Q_OBJECT +public: + struct Active_handle { enum Type{ VERTEX = 0, FACET = 1, EDGE = 2 }; }; + + // Hold mouse keyboard state together + struct Mouse_keyboard_state + { + Mouse_keyboard_state() : shift_pressing(false), left_button_pressing(false) { } + bool shift_pressing, left_button_pressing; + }; + + Mouse_keyboard_state state; + + Active_handle::Type active_handle_type; + int k_ring; + Scene_polyhedron_item* poly_item; + + Scene_polyhedron_item_k_ring_selection() {} + + Scene_polyhedron_item_k_ring_selection + (Scene_polyhedron_item* poly_item, QMainWindow* mw, Active_handle::Type aht, int k_ring) + { + init(poly_item, mw, aht, k_ring); + } + + void init(Scene_polyhedron_item* poly_item, QMainWindow* mw, Active_handle::Type aht, int k_ring) { + this->poly_item = poly_item; + this->active_handle_type = aht; + this->k_ring = k_ring; + + poly_item->enable_facets_picking(true); + poly_item->set_color_vector_read_only(true); + + QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + viewer->installEventFilter(this); + mw->installEventFilter(this); + + connect(poly_item, SIGNAL(selected_vertex(void*)), this, SLOT(vertex_has_been_selected(void*))); + connect(poly_item, SIGNAL(selected_facet(void*)), this, SLOT(facet_has_been_selected(void*))); + connect(poly_item, SIGNAL(selected_edge(void*)), this, SLOT(edge_has_been_selected(void*))); + } + +public slots: + // slots are called by signals of polyhedron_item + void vertex_has_been_selected(void* void_ptr) + { + if(active_handle_type != Active_handle::VERTEX) { return; } + process_selection( static_cast(void_ptr)->halfedge()->vertex() ); + } + void facet_has_been_selected(void* void_ptr) + { + if(active_handle_type != Active_handle::FACET) { return; } + process_selection( static_cast(void_ptr)->halfedge()->facet() ); + } + void edge_has_been_selected(void* void_ptr) + { + if(active_handle_type != Active_handle::EDGE) { return; } + process_selection( static_cast(void_ptr)->opposite()->opposite() ); + } + +signals: + void selected(const std::map&); + void selected(const std::map&); + void selected(const std::map&); + +protected: + template + void process_selection(HandleType clicked) { + const std::map& selection = extract_k_ring(clicked, k_ring); + emit selected(selection); + } + + template + std::map extract_k_ring(HandleType v, int k) + { + std::map D; + std::queue Q; + Q.push(v); D[v] = 0; + + int dist_v; + while( !Q.empty() && (dist_v = D[Q.front()]) < k ) { + v = Q.front(); + Q.pop(); + + for(One_ring_iterator circ(v); circ; ++circ) + { + HandleType new_v = circ; + if(D.insert(std::make_pair(new_v, dist_v + 1)).second) { + Q.push(new_v); + } + } + } + return D; + } + + bool eventFilter(QObject* /*target*/, QEvent *event) + { + // This filter is both filtering events from 'viewer' and 'main window' + // key events + if(event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease) { + QKeyEvent *keyEvent = static_cast(event); + Qt::KeyboardModifiers modifiers = keyEvent->modifiers(); + + state.shift_pressing = modifiers.testFlag(Qt::ShiftModifier); + } + // mouse events + if(event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease) { + QMouseEvent* mouse_event = static_cast(event); + if(mouse_event->button() == Qt::LeftButton) { + state.left_button_pressing = event->type() == QEvent::MouseButtonPress; + } + } + + // use mouse move event for paint-like selection + if(event->type() == QEvent::MouseMove && + (state.shift_pressing && state.left_button_pressing) ) + { // paint with mouse move event + QMouseEvent* mouse_event = static_cast(event); + QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + qglviewer::Camera* camera = viewer->camera(); + + bool found = false; + const qglviewer::Vec& point = camera->pointUnderPixel(mouse_event->pos(), found); + if(found) + { + const qglviewer::Vec& orig = camera->position(); + const qglviewer::Vec& dir = point - orig; + poly_item->select(orig.x, orig.y, orig.z, dir.x, dir.y, dir.z); + } + }//end MouseMove + return false; + } +}; + +#endif diff -Nru cgal-4.4/demo/Polyhedron/Scene_polyhedron_selection_item_config.h cgal-4.5/demo/Polyhedron/Scene_polyhedron_selection_item_config.h --- cgal-4.4/demo/Polyhedron/Scene_polyhedron_selection_item_config.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Scene_polyhedron_selection_item_config.h 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,10 @@ +#ifndef SCENE_POLYHEDRON_SELECTION_ITEM_CONFIG_H +#define SCENE_POLYHEDRON_SELECTION_ITEM_CONFIG_H + +#ifdef scene_polyhedron_selection_item_EXPORTS +# define SCENE_POLYHEDRON_SELECTION_ITEM_EXPORT Q_DECL_EXPORT +#else +# define SCENE_POLYHEDRON_SELECTION_ITEM_EXPORT Q_DECL_IMPORT +#endif + +#endif // SCENE_POLYHEDRON_SELECTION_ITEM_CONFIG_H diff -Nru cgal-4.4/demo/Polyhedron/Scene_polyhedron_selection_item.cpp cgal-4.5/demo/Polyhedron/Scene_polyhedron_selection_item.cpp --- cgal-4.4/demo/Polyhedron/Scene_polyhedron_selection_item.cpp 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Scene_polyhedron_selection_item.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,2 @@ +#include "Scene_polyhedron_selection_item.h" +#include "Scene_polyhedron_selection_item.moc" diff -Nru cgal-4.4/demo/Polyhedron/Scene_polyhedron_selection_item.h cgal-4.5/demo/Polyhedron/Scene_polyhedron_selection_item.h --- cgal-4.4/demo/Polyhedron/Scene_polyhedron_selection_item.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Scene_polyhedron_selection_item.h 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,730 @@ +#ifndef SCENE_POLYHEDRON_SELECTION_ITEM_H +#define SCENE_POLYHEDRON_SELECTION_ITEM_H +#include "opengl_tools.h" +#include "Scene_polyhedron_selection_item_config.h" +#include "Scene_polyhedron_item_k_ring_selection.h" +#include "Travel_isolated_components.h" + +#include "Scene_polyhedron_item_decorator.h" +#include "Polyhedron_type.h" +#include +#include + +#include +#include +#include +// Wrapper for holding selected entities +template +class Selection_set : Base +{ +public: +// types from base + typedef typename Base::iterator iterator; + typedef typename Base::const_iterator const_iterator; + typedef typename Base::const_reference const_reference; + typedef typename Base::value_type value_type; +// functions from base + using Base::begin; + using Base::end; + using Base::size; + using Base::clear; + using Base::empty; + + bool insert(const Entity& entity) { + Entity e = edge_filter(entity); + return Base::insert(e).second; + } + bool erase(const Entity& entity) { + Entity e = edge_filter(entity); + return Base::erase(e) != 0; + } + bool is_selected(const Entity& entity) const { + Entity e = edge_filter(entity); + return Base::find(e) != end(); + } + // for back_insert_iterator + void push_back(const Entity& entity) { + Entity e = edge_filter(entity); + insert(e); + } + + Polyhedron::Halfedge_handle edge_filter(Polyhedron::Halfedge_handle h) const { + return &*h < &*h->opposite() ? h : h->opposite(); + } + template E edge_filter(E e) const { return e; } +}; + +// To iterate on each minimum address halfedge as edge +struct Minimum_address_halfedge_iterator { + typedef Polyhedron::Halfedge_iterator Halfedge_iterator; + Minimum_address_halfedge_iterator() {} + Minimum_address_halfedge_iterator(Halfedge_iterator hb, Halfedge_iterator he) + : hb(hb), he(he), current(hb) { } + + Minimum_address_halfedge_iterator& operator++() { + ++current; + while(current != he && (&*current > &*current->opposite())) { + ++current; + } + return *this; + } + operator Polyhedron::Halfedge_handle() { return current; } + bool operator!=(const Minimum_address_halfedge_iterator& other) { + return current != other.he; + } + Halfedge_iterator operator->() {return current;} + + Halfedge_iterator hb, he, current; +}; + +template +struct Selection_traits {}; + +template +struct Selection_traits +{ + typedef typename SelectionItem::Selection_set_vertex Container; + typedef typename SelectionItem::Vertex_iterator Iterator; + Selection_traits(SelectionItem* item) : item(item) { } + + Container& container() { return item->selected_vertices; } + Iterator iterator_begin() { return item->polyhedron()->vertices_begin(); } + Iterator iterator_end() { return item->polyhedron()->vertices_end(); } + std::size_t size() { return item->polyhedron()->size_of_vertices(); } + void update_indices() { item->polyhedron_item()->update_vertex_indices(); } + + SelectionItem* item; +}; + +template +struct Selection_traits +{ + typedef typename SelectionItem::Selection_set_facet Container; + typedef typename SelectionItem::Facet_iterator Iterator; + Selection_traits(SelectionItem* item) : item(item) { } + + Container& container() { return item->selected_facets; } + Iterator iterator_begin() { return item->polyhedron()->facets_begin(); } + Iterator iterator_end() { return item->polyhedron()->facets_end(); } + std::size_t size() { return item->polyhedron()->size_of_facets(); } + void update_indices() { item->polyhedron_item()->update_facet_indices(); } + + SelectionItem* item; +}; + +template +struct Selection_traits +{ + typedef typename SelectionItem::Selection_set_edge Container; + typedef Minimum_address_halfedge_iterator Iterator; + Selection_traits(SelectionItem* item) : item(item) { } + + Container& container() { return item->selected_edges; } + Iterator iterator_begin() + { return Minimum_address_halfedge_iterator(item->polyhedron()->halfedges_begin(), + item->polyhedron()->halfedges_end()); } + Iterator iterator_end() { return iterator_begin(); } + std::size_t size() { return item->polyhedron()->size_of_halfedges(); } + void update_indices() { item->polyhedron_item()->update_halfedge_indices(); } + SelectionItem* item; +}; + +////////////////////////////////////////////////////////////////////////// + +class SCENE_POLYHEDRON_SELECTION_ITEM_EXPORT Scene_polyhedron_selection_item + : public Scene_polyhedron_item_decorator +{ + Q_OBJECT + +friend class Polyhedron_demo_selection_plugin; + +public: + typedef Polyhedron::Vertex_handle Vertex_handle; + typedef Polyhedron::Facet_handle Facet_handle; + typedef Polyhedron::Halfedge_handle Halfedge_handle; + typedef Polyhedron::Vertex_iterator Vertex_iterator; + typedef Polyhedron::Facet_iterator Facet_iterator; + typedef Scene_polyhedron_item_k_ring_selection::Active_handle Active_handle; + // To be used inside loader + Scene_polyhedron_selection_item() + : Scene_polyhedron_item_decorator(NULL, false) + { } + + Scene_polyhedron_selection_item(Scene_polyhedron_item* poly_item, QMainWindow* mw) + : Scene_polyhedron_item_decorator(NULL, false) + { init(poly_item, mw); } + +protected: + void init(Scene_polyhedron_item* poly_item, QMainWindow* mw) + { + this->poly_item = poly_item; + connect(poly_item, SIGNAL(item_is_about_to_be_changed()), this, SLOT(poly_item_changed())); + connect(&k_ring_selector, SIGNAL(selected(const std::map&)), this, + SLOT(selected(const std::map&))); + connect(&k_ring_selector, SIGNAL(selected(const std::map&)), this, + SLOT(selected(const std::map&))); + connect(&k_ring_selector, SIGNAL(selected(const std::map&)), this, + SLOT(selected(const std::map&))); + + k_ring_selector.init(poly_item, mw, Active_handle::VERTEX, -1); + + QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + viewer->installEventFilter(this); + mw->installEventFilter(this); + + facet_color = QColor(87,87,87); + edge_color = QColor(173,35,35); + vertex_color = QColor(255,205,243); + } + + Active_handle::Type get_active_handle_type() + { return k_ring_selector.active_handle_type; } + void set_active_handle_type(Active_handle::Type aht) + { k_ring_selector.active_handle_type = aht; } + + int get_k_ring() { return k_ring_selector.k_ring; } + void set_k_ring(int k) { k_ring_selector.k_ring = k; } + + bool get_is_insert() { return is_insert; } + void set_is_insert(bool i) { is_insert = i; } + +public: + //typedef Selection_set > Selection_set_vertex; + //typedef Selection_set > Selection_set_facet; + //typedef Selection_set > Selection_set_edge; + typedef Selection_set > Selection_set_vertex; + typedef Selection_set > Selection_set_facet; + typedef Selection_set > Selection_set_edge; + +// drawing + void draw() const { + draw_selected_vertices(); + draw_selected_facets(); + draw_selected_edges(); + } + void draw_edges() const { } + + void draw_selected_vertices() const { + GLboolean enable_back_lighting = glIsEnabled(GL_LIGHTING); + glDisable(GL_LIGHTING); + + + CGAL::GL::Point_size point_size; point_size.set_point_size(5); + CGALglcolor(vertex_color); + + ::glBegin(GL_POINTS); + for(Selection_set_vertex::iterator + it = selected_vertices.begin(), + end = selected_vertices.end(); + it != end; ++it) + { + const Kernel::Point_3& p = (*it)->point(); + ::glVertex3d(p.x(), p.y(), p.z()); + } + ::glEnd(); + + if(enable_back_lighting) { glEnable(GL_LIGHTING); } + } + void draw_selected_facets() const { + CGALglcolor(facet_color); + + GLfloat offset_factor; + GLfloat offset_units; + ::glGetFloatv(GL_POLYGON_OFFSET_FACTOR, &offset_factor); + ::glGetFloatv(GL_POLYGON_OFFSET_UNITS, &offset_units); + + ::glPolygonOffset(-1.f, 1.f); + ::glBegin(GL_TRIANGLES); + for(Selection_set_facet::iterator + it = selected_facets.begin(), + end = selected_facets.end(); + it != end; ++it) + { + const Kernel::Vector_3 n = + compute_facet_normal(**it); + ::glNormal3d(n.x(),n.y(),n.z()); + + Polyhedron::Halfedge_around_facet_circulator + he = (*it)->facet_begin(), + cend = he; + + CGAL_For_all(he,cend) + { + const Kernel::Point_3& p = he->vertex()->point(); + ::glVertex3d(p.x(),p.y(),p.z()); + } + } + ::glEnd(); + ::glPolygonOffset(offset_factor, offset_units); + } + void draw_selected_edges() const { + GLboolean enable_back_lighting = glIsEnabled(GL_LIGHTING); + glDisable(GL_LIGHTING); + + CGALglcolor(edge_color); + ::glLineWidth(3.f); + ::glBegin(GL_LINES); + for(Selection_set_edge::iterator it = selected_edges.begin(); it != selected_edges.end(); ++it) { + const Kernel::Point_3& a = (*it)->vertex()->point(); + const Kernel::Point_3& b = (*it)->opposite()->vertex()->point(); + ::glVertex3d(a.x(),a.y(),a.z()); + ::glVertex3d(b.x(),b.y(),b.z()); + } + ::glEnd(); + + if(enable_back_lighting) { glEnable(GL_LIGHTING); } + } + + bool supportsRenderingMode(RenderingMode m) const { return (m==Flat); } + + bool isEmpty() const { + return selected_vertices.empty() && selected_edges.empty() && selected_facets.empty(); + } + Bbox bbox() const + { + boost::optional item_bbox; + + for(Selection_set_vertex::const_iterator v_it = selected_vertices.begin(); + v_it != selected_vertices.end(); ++v_it) { + + if(item_bbox) { *item_bbox = *item_bbox + (*v_it)->point().bbox(); } + else { item_bbox = (*v_it)->point().bbox(); } + } + + for(Selection_set_edge::const_iterator e_it = selected_edges.begin(); + e_it != selected_edges.end(); ++e_it) { + CGAL::Bbox_3 e_bbox = (*e_it)->vertex()->point().bbox(); + e_bbox = e_bbox + (*e_it)->opposite()->vertex()->point().bbox(); + if(item_bbox) { *item_bbox = *item_bbox + e_bbox; } + else { item_bbox = e_bbox; } + } + + for(Selection_set_facet::const_iterator f_it = selected_facets.begin(); + f_it != selected_facets.end(); ++f_it) { + + Polyhedron::Halfedge_around_facet_circulator he = (*f_it)->facet_begin(), cend = he; + CGAL_For_all(he,cend) { + if(item_bbox) { *item_bbox = *item_bbox + he->vertex()->point().bbox(); } + else { item_bbox = he->vertex()->point().bbox(); } + } + } + + if(!item_bbox) { return Bbox(); } + return Bbox(item_bbox->xmin(),item_bbox->ymin(),item_bbox->zmin(), + item_bbox->xmax(),item_bbox->ymax(),item_bbox->zmax()); + } + + bool save(const std::string& file_name) const { + // update id fields before using + if(selected_vertices.size() > 0) { poly_item->update_vertex_indices(); } + if(selected_facets.size() > 0) { poly_item->update_facet_indices(); } + if(selected_edges.size() > 0) { poly_item->update_halfedge_indices(); } + + std::ofstream out(file_name.c_str()); + if(!out) { return false; } + + for(Selection_set_vertex::const_iterator it = selected_vertices.begin(); it != selected_vertices.end(); ++it) + { out << (*it)->id() << " "; } + out << std::endl; + + for(Selection_set_facet::const_iterator it = selected_facets.begin(); it != selected_facets.end(); ++it) + { out << (*it)->id() << " "; } + out << std::endl; + + for(Selection_set_edge::const_iterator it = selected_edges.begin(); it != selected_edges.end(); ++it) + { out << (*it)->id() << " "; } + out << std::endl; + return true; + } + bool load(const std::string& file_name) { + file_name_holder = file_name; + return true; + } + // this function is called by selection_plugin, since at the time of the call of load(...) + // we do not have access to selected polyhedron item + bool actual_load(Scene_polyhedron_item* poly_item, QMainWindow* mw) + { + init(poly_item, mw); + + std::vector all_vertices; + all_vertices.reserve(polyhedron()->size_of_vertices()); + Polyhedron::Vertex_iterator vb(polyhedron()->vertices_begin()), ve(polyhedron()->vertices_end()); + for(;vb != ve; ++vb) { all_vertices.push_back(vb); } + + std::vector all_facets; + all_facets.reserve(polyhedron()->size_of_facets()); + Polyhedron::Facet_iterator fb(polyhedron()->facets_begin()), fe(polyhedron()->facets_end()); + for(;fb != fe; ++fb) { all_facets.push_back(fb); } + + std::vector all_halfedges; + all_facets.reserve(polyhedron()->size_of_halfedges()); + Polyhedron::Halfedge_iterator hb(polyhedron()->halfedges_begin()), he(polyhedron()->halfedges_end()); + for(;hb != he; ++hb) { all_halfedges.push_back(hb); } + + std::ifstream in(file_name_holder.c_str()); + if(!in) { return false; } + + std::string line; + std::size_t id; + + if(!std::getline(in, line)) { return true; } + std::istringstream vertex_line(line); + while(vertex_line >> id) { + if(id >= all_vertices.size()) { return false; } + selected_vertices.insert(all_vertices[id]); + } + + if(!std::getline(in, line)) { return true; } + std::istringstream facet_line(line); + while(facet_line >> id) { + if(id >= all_facets.size()) { return false; } + selected_facets.insert(all_facets[id]); + } + + if(!std::getline(in, line)) { return true; } + std::istringstream edge_line(line); + while(edge_line >> id) { + if(id >= all_halfedges.size()) { return false; } + Halfedge_handle h = all_halfedges[id]; + selected_edges.insert(h); + } + return true; + } + + // select all of `active_handle_type`(vertex, facet or edge) + void select_all() { + switch(get_active_handle_type()) { + case Active_handle::VERTEX: + select_all(); break; + case Active_handle::FACET: + select_all(); break; + case Active_handle::EDGE: + select_all(); break; + } + } + // select all of vertex, facet or edge (use Vertex_handle, Facet_handle, Halfedge_handle as template argument) + template + void select_all() { + typedef Selection_traits Tr; + Tr tr(this); + for(typename Tr::Iterator it = tr.iterator_begin() ; it != tr.iterator_end(); ++it) { + tr.container().insert(it); + } + emit itemChanged(); + } + + // clear all of `active_handle_type`(vertex, facet or edge) + void clear() { + switch(get_active_handle_type()) { + case Active_handle::VERTEX: + clear(); break; + case Active_handle::FACET: + clear(); break; + case Active_handle::EDGE: + clear(); break; + } + } + // select all of vertex, facet or edge (use Vertex_handle, Facet_handle, Halfedge_handle as template argument) + template + void clear() { + + Selection_traits tr(this); + tr.container().clear(); + emit itemChanged(); + } + + boost::optional get_minimum_isolated_component() { + switch(get_active_handle_type()) { + case Active_handle::VERTEX: + return get_minimum_isolated_component(); + case Active_handle::FACET: + return get_minimum_isolated_component(); + default: + return get_minimum_isolated_component(); + } + } + template // use Vertex_handle, Facet_handle, Halfedge_handle + boost::optional get_minimum_isolated_component() { + Selection_traits tr(this); + tr.update_indices(); + Travel_isolated_components::Minimum_visitor visitor; + Travel_isolated_components().travel + (tr.iterator_begin(), tr.iterator_end(), tr.size(), tr.container(), visitor); + return visitor.minimum; + } + + boost::optional select_isolated_components(std::size_t threshold) { + switch(get_active_handle_type()) { + case Active_handle::VERTEX: + return select_isolated_components(threshold); + case Active_handle::FACET: + return select_isolated_components(threshold); + default: + return select_isolated_components(threshold); + } + } + template // use Vertex_handle, Facet_handle, Halfedge_handle + boost::optional select_isolated_components(std::size_t threshold) { + typedef Selection_traits Tr; + Tr tr(this); + tr.update_indices(); + typedef std::back_insert_iterator Output_iterator; + Output_iterator out(tr.container()); + + Travel_isolated_components::Selection_visitor visitor(threshold , out); + Travel_isolated_components().travel + (tr.iterator_begin(), tr.iterator_end(), tr.size(), tr.container(), visitor); + + if(visitor.any_inserted) { emit itemChanged(); } + return visitor.minimum_visitor.minimum; + } + + void expand_or_shrink(int steps) { + switch(get_active_handle_type()) { + case Active_handle::VERTEX: + expand_or_shrink(steps); break; + case Active_handle::FACET: + expand_or_shrink(steps); break; + default: + expand_or_shrink(steps); + } + } + + template + void expand_or_shrink(int steps) { + // It is good for large values of `steps` + if(steps == 0) { return; } + bool expand_req = steps > 0; + steps = std::abs(steps); + expand_req ? expand(steps) : shrink(steps); + } + + template + void shrink(unsigned int steps) { + typedef Selection_traits Tr; + Tr tr(this); + + tr.update_indices(); + std::vector mark(tr.size()); + std::vector to_be_shrink; + std::vector next; + to_be_shrink.reserve(tr.container().size()); + for(typename Tr::Container::iterator it = tr.container().begin(); it != tr.container().end(); ++it) { + for(One_ring_iterator circ(*it); circ; ++circ) { + if(!tr.container().is_selected(circ) && !mark[HandleType(circ)->id()]) { + to_be_shrink.push_back(circ); + mark[HandleType(circ)->id()] = true; + } + } + } + + while(steps-- > 0) { + for(typename std::vector::iterator it = to_be_shrink.begin(); + it != to_be_shrink.end(); ++it) + { + for(One_ring_iterator circ(*it); circ; ++circ) { + HandleType ht = circ; + if(tr.container().is_selected(ht) && !mark[ht->id()]) { + next.push_back(ht); + mark[ht->id()] = true; + } + } + } + + to_be_shrink.swap(next); + next.clear(); + } + + bool any_change = false; + for(typename Tr::Iterator it = tr.iterator_begin() ; it != tr.iterator_end(); ++it) { + if(mark[it->id()]) { + any_change |= tr.container().erase(it); + } + } + if(any_change) { emit itemChanged(); } + } + + template + void expand(unsigned int steps) { + + typedef Selection_traits Tr; + Tr tr(this); + + tr.update_indices(); + std::vector mark(tr.size()); + + std::vector to_be_expand; + std::vector next; + to_be_expand.reserve(tr.container().size()); + for(typename Tr::Container::iterator it = tr.container().begin(); it != tr.container().end(); ++it) { + to_be_expand.push_back(*it); + } + + while(steps-- > 0) { + for(typename std::vector::iterator it = to_be_expand.begin(); + it != to_be_expand.end(); ++it) + { + for(One_ring_iterator circ(*it); circ; ++circ) { + HandleType ht = circ; + + if(!tr.container().is_selected(ht) && !mark[ht->id()]) { + next.push_back(ht); + mark[ht->id()] = true; + } + } + } + + to_be_expand.swap(next); + next.clear(); + } + + bool any_change = false; + for(typename Tr::Iterator it = tr.iterator_begin() ; it != tr.iterator_end(); ++it) { + if(mark[it->id()]) { + any_change |= tr.container().insert(it); + } + } + if(any_change) { emit itemChanged(); } + } + + void erase_selected_facets() { + if(selected_facets.empty()) {return;} + // no-longer-valid vertices and edges will be handled when item_about_to_be_changed() + + // erase facets from poly + for(Selection_set_facet::iterator fb = selected_facets.begin(); fb != selected_facets.end(); ++fb) { + polyhedron()->erase_facet((*fb)->halfedge()); + } + selected_facets.clear(); + changed_with_poly_item(); + } + + bool export_selected_facets_as_polyhedron(Polyhedron* out) { + // Note: might be a more performance wise solution + // assign sequential id to vertices neighbor to selected facets + for(Selection_set_facet::iterator fb = selected_facets.begin(); fb != selected_facets.end(); ++fb) { + Polyhedron::Halfedge_around_facet_circulator hb((*fb)->facet_begin()), hend(hb); + do { + hb->vertex()->id() = 0; + } while(++hb != hend); + } + // construct point vector + std::vector points; + points.reserve(selected_facets.size()); + std::size_t counter = 1; + for(Selection_set_facet::iterator fb = selected_facets.begin(); fb != selected_facets.end(); ++fb) { + Polyhedron::Halfedge_around_facet_circulator hb((*fb)->facet_begin()), hend(hb); + do { + if(hb->vertex()->id() == 0) { + hb->vertex()->id() = counter++; + points.push_back(hb->vertex()->point()); + } + } while(++hb != hend); + } + // construct polygon vector + std::vector > polygons(selected_facets.size()); + counter = 0; + for(Selection_set_facet::iterator fb = selected_facets.begin(); fb != selected_facets.end(); ++fb, ++counter) { + Polyhedron::Halfedge_around_facet_circulator hb((*fb)->facet_begin()), hend(hb); + do { + polygons[counter].push_back(hb->vertex()->id() -1); + } while(++hb != hend); + } + CGAL::Polygon_soup_to_polyhedron_3 builder(points, polygons); + out->delegate(builder); + return out->size_of_vertices() > 0; + } + + void changed_with_poly_item() { + // no need to update indices + poly_item->changed(); + emit itemChanged(); + } + +public slots: + void changed() { + // do not use decorator function, which calls changed on poly_item which cause deletion of AABB + } + // slots are called by signals of polyhedron_k_ring_selector + void selected(const std::map& m) + { has_been_selected(m); } + void selected(const std::map& m) + { has_been_selected(m); } + void selected(const std::map& m) + { has_been_selected(m); } + void poly_item_changed() { + remove_erased_handles(); + remove_erased_handles(); + remove_erased_handles(); + } + +protected: + bool eventFilter(QObject* /*target*/, QEvent * gen_event) + { + if(!visible() || !k_ring_selector.state.shift_pressing) { return false; } + if(gen_event->type() == QEvent::Wheel) + { + QWheelEvent *event = static_cast(gen_event); + int steps = event->delta() / 120; + expand_or_shrink(steps); + return true; + } + return false; + } + + template + void remove_erased_handles() { + typedef Selection_traits Tr; + Tr tr(this); + if(tr.container().empty()) { return;} + + std::vector exists; + for(typename Tr::Iterator it = tr.iterator_begin() ; it != tr.iterator_end(); ++it) { + if(tr.container().is_selected(it)) { + exists.push_back(it); + } + } + tr.container().clear(); + for(typename std::vector::iterator it = exists.begin(); it != exists.end(); ++it) { + tr.container().insert(*it); + } + } + + template + void has_been_selected(const std::map& selection) + { + if(!visible()) { return; } + Selection_traits tr(this); + + bool any_change = false; + if(is_insert) { + for(typename std::map::const_iterator it = selection.begin(); it != selection.end(); ++it) { + any_change |= tr.container().insert(it->first); + } + }else { + for(typename std::map::const_iterator it = selection.begin(); it != selection.end(); ++it) { + any_change |= tr.container().erase(it->first); + } + } + if(any_change) { emit itemChanged(); } + } + +// members + std::string file_name_holder; + Scene_polyhedron_item_k_ring_selection k_ring_selector; + // action state + bool is_insert; + +public: +// selection + Selection_set_vertex selected_vertices; + Selection_set_facet selected_facets; + Selection_set_edge selected_edges; // stores one halfedge for each pair (halfedge with minimum address) +// + QColor vertex_color, facet_color, edge_color; +}; + +#endif diff -Nru cgal-4.4/demo/Polyhedron/Scene_textured_polyhedron_item.h cgal-4.5/demo/Polyhedron/Scene_textured_polyhedron_item.h --- cgal-4.4/demo/Polyhedron/Scene_textured_polyhedron_item.h 2012-11-13 13:13:59.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Scene_textured_polyhedron_item.h 2014-08-29 13:58:17.000000000 +0000 @@ -28,7 +28,7 @@ virtual QString toolTip() const; // Indicate if rendering mode is supported - virtual bool supportsRenderingMode(RenderingMode /* m */) const { return true; } + virtual bool supportsRenderingMode(RenderingMode m) const { return m != Splatting; } // Points/Wireframe/Flat/Gouraud OpenGL drawing in a display list virtual void direct_draw() const; diff -Nru cgal-4.4/demo/Polyhedron/Selection_widget.ui cgal-4.5/demo/Polyhedron/Selection_widget.ui --- cgal-4.4/demo/Polyhedron/Selection_widget.ui 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Selection_widget.ui 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,268 @@ + + + Selection + + + + 0 + 0 + 334 + 402 + + + + Selection + + + + + + + + + + + Selection &Type: + + + Selection_type_combo_box + + + + + + + + Vertex + + + + + Facet + + + + + Edge + + + + + + + + + + + + + + + + + + + + + + + + Insertion + + + true + + + + + + + Removal + + + + + + + + + + + + + Brush &size: + + + Brush_size_spin_box + + + + + + + + + + + + + + + + + + Select &All + + + + + + + &Clear + + + + + + + + + + + + + + + + + + + + + + + + Isolated &Component Size: + + + Threshold_size_spin_box + + + + + + + 999999999 + + + 8 + + + + + + + &Get Minimum + + + + + + + + + Select &Isolated Components Below Threshold + + + + + + + + + + + + + + + + + + Expand or shrink selection: + + + + + + + -50 + + + 50 + + + + + + + Apply + + + + + + + + + + Create Point Set Item from Selected Vertices + + + + + + + Create Polyhedron Item from Selected Facets + + + + + + + Erase Selected Facets from Polyhedron Item + + + + + + + + 75 + true + + + + Create Selection Item + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + diff -Nru cgal-4.4/demo/Polyhedron/Travel_isolated_components.h cgal-4.5/demo/Polyhedron/Travel_isolated_components.h --- cgal-4.4/demo/Polyhedron/Travel_isolated_components.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Travel_isolated_components.h 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,94 @@ +#ifndef TRAVEL_ISOLATED_COMPONENTS_H +#define TRAVEL_ISOLATED_COMPONENTS_H + +#include +#include +#include "One_ring_iterators.h" +#include +class Travel_isolated_components { +public: + // for transform iterator + template + struct Get_handle { + typedef HandleType result_type; + template + result_type operator()(Iterator it) const + { return it; } + }; + + // to be used in get_minimum_isolated_component function + struct Minimum_visitor + { + template + void operator()(const std::vector& C) { + if(!minimum) { minimum = C.size(); } + else { minimum = (std::min)(*minimum, C.size()); } + } + + boost::optional minimum; + }; + + // to be used in select_isolated_components function + template + struct Selection_visitor + { + Selection_visitor(std::size_t threshold_size, OutputIterator out) + : threshold_size(threshold_size), out(out), any_inserted(false) { } + + template + void operator()(const std::vector& C) { + if(C.size() <= threshold_size) { + any_inserted = true; + out = std::copy(C.begin(), C.end(), out); + } + else { + minimum_visitor(C); + } + } + + std::size_t threshold_size; + OutputIterator out; + bool any_inserted; + Minimum_visitor minimum_visitor; // hold minimum of NOT inserted components + }; + + // NOTE: prior to call this function, id fields should be updated + template + void travel(InputIterator begin, + InputIterator end, + std::size_t size, + const IsSelected& selection, + Visitor& visitor) + { + std::vector mark(size, false); + + for(; begin != end; ++begin) + { + HandleType h = begin; + + if(mark[h->id()] || selection.is_selected(h)) { continue; } + + std::vector C; + C.push_back(h); + mark[h->id()] = true; + std::size_t current_index = 0; + + bool neigh_to_selection = false; + while(current_index < C.size()) { + HandleType current = C[current_index++]; + + for(One_ring_iterator circ(current); circ; ++circ) + { + HandleType nv = circ; + neigh_to_selection |= selection.is_selected(nv); + if(!mark[nv->id()] && !selection.is_selected(nv)) { + mark[nv->id()] = true; + C.push_back(nv); + } + } + } + if(neigh_to_selection) { visitor(C); } + } + } +}; +#endif diff -Nru cgal-4.4/demo/Polyhedron/UseCGAL_polyhedron_demo.cmake cgal-4.5/demo/Polyhedron/UseCGAL_polyhedron_demo.cmake --- cgal-4.4/demo/Polyhedron/UseCGAL_polyhedron_demo.cmake 2012-12-08 20:00:21.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/UseCGAL_polyhedron_demo.cmake 2014-08-29 13:58:17.000000000 +0000 @@ -1,4 +1,4 @@ -message(STATUS "Using CGAL_polyhedron_demo from: ${CGAL_POLYHEDRON_DIR}") +message(STATUS "Using CGAL_polyhedron_demo from: ${CGAL_POLYHEDRON_DEMO_DIR}") list(INSERT CMAKE_MODULE_PATH 0 "${CGAL_POLYHEDRON_DEMO_CMAKE_MODULE_PATH}") diff -Nru cgal-4.4/demo/Polyhedron/Viewer.cpp cgal-4.5/demo/Polyhedron/Viewer.cpp --- cgal-4.4/demo/Polyhedron/Viewer.cpp 2014-03-05 20:00:23.000000000 +0000 +++ cgal-4.5/demo/Polyhedron/Viewer.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -26,15 +26,28 @@ d->twosides = false; d->macro_mode = false; setShortcut(EXIT_VIEWER, 0); - setMouseBinding(Qt::SHIFT + Qt::LeftButton, SELECT); - setMouseBindingDescription(Qt::SHIFT + Qt::RightButton, - tr("Selects and display context " - "menu of the selected item")); setKeyDescription(Qt::Key_T, tr("Turn the camera by 180 degrees")); setKeyDescription(Qt::Key_M, tr("Toggle macro mode: useful to view details very near from the camera, " "but decrease the z-buffer precision")); +#if QGLVIEWER_VERSION >= 0x020501 + //modify mouse bindings that have been updated + setMouseBinding(Qt::Key(0), Qt::NoModifier, Qt::LeftButton, RAP_FROM_PIXEL, true, Qt::RightButton); + setMouseBindingDescription(Qt::ShiftModifier, Qt::RightButton, + tr("Select and pop context menu")); + setMouseBinding(Qt::Key_R, Qt::NoModifier, Qt::LeftButton, RAP_FROM_PIXEL); + //use the new API for these + setMouseBinding(Qt::ShiftModifier, Qt::LeftButton, SELECT); + setMouseBindingDescription(Qt::Key(0), Qt::ShiftModifier, Qt::LeftButton, + tr("Selects and display context " + "menu of the selected item")); +#else + setMouseBinding(Qt::SHIFT + Qt::LeftButton, SELECT); + setMouseBindingDescription(Qt::SHIFT + Qt::RightButton, + tr("Selects and display context " + "menu of the selected item")); +#endif // QGLVIEWER_VERSION >= 2.5.0 } Viewer::~Viewer() diff -Nru cgal-4.4/demo/Surface_mesher/File_XT.h cgal-4.5/demo/Surface_mesher/File_XT.h --- cgal-4.4/demo/Surface_mesher/File_XT.h 2012-11-13 13:14:01.000000000 +0000 +++ cgal-4.5/demo/Surface_mesher/File_XT.h 2014-08-29 13:58:17.000000000 +0000 @@ -102,7 +102,9 @@ if ( (fin=fopen(nomfich,"rw"))!=NULL ) { fseek(fin,4,0); - fread(long_trace,4,1,fin); + if (fread(long_trace,4,1,fin) != 1) { + flag = -1; + } permuteLong((char *)long_trace); fclose(fin); } @@ -119,7 +121,9 @@ if ( (fin=fopen(nomfich,"rw"))!=NULL ) { fseek(fin,8,0); - fread(nb_trace,4,1,fin); + if (fread(nb_trace,4,1,fin) != 1) { + flag = -1; + } permuteLong((char *)nb_trace); fclose(fin); } @@ -136,7 +140,9 @@ if ( (fin=fopen(nomfich,"rw"))!=NULL ) { fseek(fin,12,0); - fread(nb_plan,4,1,fin); + if (fread(nb_plan,4,1,fin) != 1) { + flag = -1; + } permuteLong((char *)nb_plan); fclose(fin); } @@ -154,7 +160,9 @@ if ( (fin=fopen(nomfich,"rw"))!=NULL ) { fseek(fin,36,0); - fread(nb_octet,4,1,fin); + if (fread(nb_octet,4,1,fin) != 1) { + flag = -1; + } permuteLong((char *)nb_octet); fclose(fin); } @@ -172,7 +180,9 @@ if ( (fin=fopen(nomfich,"rw"))!=NULL ) { fseek(fin,72,0); - fread(long_entete,4,1,fin); + if (fread(long_entete,4,1,fin) != 1) { + flag = -1; + } permuteLong((char *)long_entete); fclose(fin); } diff -Nru cgal-4.4/demo/Surface_mesher/volume.h cgal-4.5/demo/Surface_mesher/volume.h --- cgal-4.4/demo/Surface_mesher/volume.h 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_mesher/volume.h 2014-08-29 13:58:17.000000000 +0000 @@ -54,7 +54,7 @@ #include #include #include -#include +#include #include #include #include @@ -63,7 +63,7 @@ typedef CGAL::Surface_mesh_vertex_base_3 Vb; typedef CGAL::Triangulation_cell_base_with_info_3 Cb1; typedef CGAL::Surface_mesh_cell_base_3 Cb2; -typedef CGAL::Triangulation_cell_base_with_circumcenter_3 Cb; +typedef CGAL::Delaunay_triangulation_cell_base_with_circumcenter_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; diff -Nru cgal-4.4/demo/Surface_modeling/CMakeLists.txt cgal-4.5/demo/Surface_modeling/CMakeLists.txt --- cgal-4.4/demo/Surface_modeling/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/demo/Surface_modeling/CMakeLists.txt 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,38 @@ +# Created by the script cgal_create_cmake_script +# This is the CMake script for compiling a CGAL application. + + +project( Surface_modeling_demo ) + +cmake_minimum_required(VERSION 2.6.2) +if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" VERSION_GREATER 2.6) + if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}" VERSION_GREATER 2.8.3) + cmake_policy(VERSION 2.8.4) + else() + cmake_policy(VERSION 2.6) + endif() +endif() + +find_package(CGAL QUIET COMPONENTS Core ) + +if ( CGAL_FOUND ) + + include( ${CGAL_USE_FILE} ) + + find_package(Eigen3 3.1.91) #(requires 3.2.0 or greater) + if (EIGEN3_FOUND) + include( ${EIGEN3_USE_FILE} ) + include( CGAL_CreateSingleSourceCGALProgram ) + + include_directories (BEFORE "../../include") + create_single_source_cgal_program( "deform_mesh_for_botsch08_format.cpp" ) + + else() + message(STATUS "NOTICE: This program requires the Eigen library, version 3.2 or later and will not be compiled.") + endif() +else() + + message(STATUS "NOTICE: This program requires the CGAL library, and will not be compiled.") + +endif() + diff -Nru cgal-4.4/demo/Surface_modeling/deform_mesh_for_botsch08_format.cpp cgal-4.5/demo/Surface_modeling/deform_mesh_for_botsch08_format.cpp --- cgal-4.4/demo/Surface_modeling/deform_mesh_for_botsch08_format.cpp 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/demo/Surface_modeling/deform_mesh_for_botsch08_format.cpp 2014-10-04 19:00:10.000000000 +0000 @@ -0,0 +1,96 @@ +#include +#include +#include +#include +// HalfedgeGraph adapters for Polyhedron_3 +#include +#include +#include +// #define CGAL_DEFORM_MESH_USE_EXPERIMENTAL_SR_ARAP +#include + +#include + + +typedef CGAL::Simple_cartesian Kernel; +typedef CGAL::Polyhedron_3 Polyhedron; + +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef boost::graph_traits::vertex_iterator vertex_iterator; + +typedef CGAL::Surface_mesh_deformation Surface_mesh_deformation; + +int main(int argc,char** argv) +{ + if ( argc!=4){ + std::cerr <<"Usage " << argv[0] << " input.off input.sel input.def\n"; + return 1; + } + Polyhedron mesh; + std::ifstream input(argv[1]); + + if ( !input || !(input >> mesh) || mesh.empty() ) { + std::cerr<< argv[1] << " is not a valid off file" << std::endl; + return 1; + } + input.close(); + + // Init the indices of the halfedges and the vertices. + set_halfedgeds_items_id(mesh); + + // Create a deformation object + Surface_mesh_deformation deform_mesh(mesh); + + // Definition of the region of interest (use the whole mesh) + vertex_iterator vb,ve; + boost::tie(vb, ve) = boost::vertices(mesh); + + //the selection is set by a file + input.open(argv[2]); + std::string line; + std::vector control_vertices; + while(getline(input, line)) + { + if (line[0]=='#') continue; + if (line[0]=='1') deform_mesh.insert_roi_vertex(*vb); + if (line[0]=='2') { + deform_mesh.insert_control_vertex(*vb); + control_vertices.push_back(*vb); + } + ++vb; + if (vb==ve) break; + } + input.close(); + + std::cout << "Using " << control_vertices.size() << " control vertices\n"; + // The definition of the ROI and the control vertices is done, call preprocess + bool is_matrix_factorization_OK = deform_mesh.preprocess(); + if(!is_matrix_factorization_OK){ + std::cerr << "Error in preprocessing, check documentation of preprocess()" << std::endl; + return 1; + } + + //define the transformation + input.open(argv[3]); + double m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, hw, sink; + getline(input, line); // skip first comment line + input >> m00 >> m01 >> m02 >> m03; + input >> m10 >> m11 >> m12 >> m13; + input >> m20 >> m21 >> m22 >> m23; + input >> sink >> sink >> sink >> hw; + + Kernel::Aff_transformation_3 aff(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23); + BOOST_FOREACH(vertex_descriptor vd, control_vertices) + { + Surface_mesh_deformation::Point pos = vd->point().transform(aff); + deform_mesh.set_target_position(vd, pos); + } + + // Call the function deform() with one-time parameters: + deform_mesh.deform(1000, 1e-4); + + // Save the deformed mesh into a file + std::ofstream output("deform_res.off"); + output << mesh; + output.close(); +} diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/CMakeLists.txt cgal-4.5/demo/Surface_reconstruction_points_3/CMakeLists.txt --- cgal-4.4/demo/Surface_reconstruction_points_3/CMakeLists.txt 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,313 +0,0 @@ -# This is the CMake script for compiling the CGAL Point Set demo. - -project( Point_set_demo ) - -cmake_minimum_required(VERSION 2.6.2) -if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}" VERSION_GREATER 2.8.3) - cmake_policy(VERSION 2.8.4) -else() - cmake_policy(VERSION 2.6) -endif() - -#option(POINT_SET_DEMO_ENABLE_FORWARD_DECL "In the Point Set demo, enable " OFF) -#mark_as_advanced(POINT_SET_DEMO_ENABLE_FORWARD_DECL) - -# Let plugins be compiled in the same directory as the executable. -set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}") - -# Include this package's headers first -include_directories( BEFORE ./ ./include ../../include ) - -# Find CGAL and CGAL Qt4 -find_package(CGAL COMPONENTS Qt4) -include( ${CGAL_USE_FILE} ) - -# Find Qt4 itself -set( QT_USE_QTXML TRUE ) -set( QT_USE_QTMAIN TRUE ) -set( QT_USE_QTSCRIPT TRUE ) -set( QT_USE_QTOPENGL TRUE ) -find_package(Qt4) - -# Find OpenGL -find_package(OpenGL) - -# Find QGLViewer -if(QT4_FOUND) - include(${QT_USE_FILE}) - find_package(QGLViewer ) -endif(QT4_FOUND) - -# Find BLAS, LAPACK and TAUCS (optional), for Poisson -find_package(TAUCS) - -# Find BLAS and LAPACK only (optional), for Jet Fitting -find_package(LAPACK) - -# Find Eigen3 (requires 3.1.0 or greater) -find_package(Eigen3 3.1.0) - -# Find Glew (optional), for splatting -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/GlSplat/cmake) -find_package(GLEW) - -if(CGAL_Qt4_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND) - - include_directories ( ${QGLVIEWER_INCLUDE_DIR} ) - - # Link with BLAS, LAPACK and TAUCS (optional), for Poisson - if(TAUCS_FOUND) - include( ${TAUCS_USE_FILE} ) - else(TAUCS_FOUND) - message(STATUS "NOTICE: TAUCS library is not found.") - endif(TAUCS_FOUND) - - if(EIGEN3_FOUND) - include( ${EIGEN3_USE_FILE} ) - else() - message(STATUS "NOTICE: Eigen library is not found.") - endif() - - # Link with BLAS and LAPACK only (optional), for Jet Fitting - if(LAPACK_FOUND) - include( ${LAPACK_USE_FILE} ) - else(LAPACK_FOUND) - if (NOT EIGEN3_FOUND) - message(STATUS "NOTICE: Nor Eigen 3.1 (or greater) nor LAPACK library were found. Normal estimation and smoothing will not be available.") - endif() - endif(LAPACK_FOUND) - - if(GLEW_FOUND) - include_directories ( ${GLEW_INCLUDE_DIR} ) - add_definitions(-DCGAL_GLEW_ENABLED) - else(GLEW_FOUND) - message(STATUS "NOTICE: GLEW library is not found. Splat rendering will not be available.") - endif(GLEW_FOUND) - - # VisualC++ optimization for applications dealing with large data - if (MSVC) - # Use /EHa option to catch stack overflows. - # Note: TAUCS needs a stack >= 2MB. CGAL default is 10MB. - string(REGEX REPLACE "/EH[asc]*" "/EHa" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") - - # Use /FR to turn on IntelliSense - SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /FR") - - # Allow Windows applications to use up to 3GB of RAM - SET (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /LARGEADDRESSAWARE") - - # Turn off stupid VC++ warnings - SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4267 /wd4311 /wd4800 /wd4503 /wd4244 /wd4345 /wd4996 /wd4396 /wd4018") - - # Prints new compilation options - message( STATUS "USING DEBUG CXXFLAGS = '${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_DEBUG}'" ) - message( STATUS "USING DEBUG EXEFLAGS = '${CMAKE_EXE_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS_DEBUG}'" ) - message( STATUS "USING RELEASE CXXFLAGS = '${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE}'" ) - message( STATUS "USING RELEASE EXEFLAGS = '${CMAKE_EXE_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS_RELEASE}'" ) - endif() - - # Temporary debugging stuff - ADD_DEFINITIONS( "-DDEBUG_TRACE" ) # turn on traces - - qt4_wrap_ui( UI_FILES MainWindow.ui) - - include(AddFileDependencies) - - qt4_generate_moc( "MainWindow.h" "${CMAKE_CURRENT_BINARY_DIR}/MainWindow_moc.cpp" ) - add_file_dependencies( MainWindow_moc.cpp "${CMAKE_CURRENT_SOURCE_DIR}/MainWindow.h" ) - - qt4_generate_moc( "Viewer.h" "${CMAKE_CURRENT_BINARY_DIR}/Viewer_moc.cpp" ) - add_file_dependencies( Viewer_moc.cpp "${CMAKE_CURRENT_SOURCE_DIR}/Viewer.h" ) - - qt4_generate_moc( "Scene.h" "${CMAKE_CURRENT_BINARY_DIR}/Scene_moc.cpp" ) - add_file_dependencies( Scene_moc.cpp "${CMAKE_CURRENT_SOURCE_DIR}/Scene.h" ) - - qt4_add_resources ( RESOURCE_FILES Point_set_demo.qrc ) - - qt4_automoc(Scene_item.cpp - Scene_plane_item.cpp - Point_set_scene_item.cpp - Scene_polyhedron_item.cpp) - - # AUXILIARY LIBRARIES - - # put plugins (which are shared libraries) at the same location as - # executable files - - set(LIBRARY_OUTPUT_PATH ${RUNTIME_OUTPUT_PATH}) - - add_library(PS_demo_scene_item SHARED - Scene_item.cpp Scene_item.moc - Scene_item_with_display_list.cpp - Polyhedron_demo_plugin_helper.cpp) - target_link_libraries(PS_demo_scene_item ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTOPENGL_LIBRARY} ${GLEW_LIBRARIES} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY}) - - add_library(PS_demo_scene_basic_objects SHARED - Scene_plane_item.cpp Scene_plane_item.moc) - target_link_libraries(PS_demo_scene_basic_objects PS_demo_scene_item ${QGLVIEWER_LIBRARIES} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY}) - - add_library(PS_demo_scene_polyhedron_item SHARED - Scene_polyhedron_item.cpp Scene_polyhedron_item.moc) - target_link_libraries(PS_demo_scene_polyhedron_item PS_demo_scene_item) - - if(GLEW_FOUND) - qt4_add_resources(gl_splat_rc GlSplat/glsplat.qrc) - add_library(gl_splat SHARED - GlSplat/GlSplat.cpp GlSplat/Shader.cpp ${gl_splat_rc}) - target_link_libraries(gl_splat ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTOPENGL_LIBRARY} ${GLEW_LIBRARIES}) - endif(GLEW_FOUND) - - add_library(point_set SHARED - Point_set_scene_item.cpp Point_set_scene_item.moc) - target_link_libraries(point_set PS_demo_scene_item) - - foreach(lib PS_demo_scene_item PS_demo_scene_basic_objects PS_demo_scene_polyhedron_item point_set) - add_to_cached_list(CGAL_EXECUTABLE_TARGETS ${lib}) - endforeach() - - if(GLEW_FOUND) - target_link_libraries( point_set gl_splat ${GLEW_LIBRARIES} ) - endif(GLEW_FOUND) - - add_definitions(-DQT_STATICPLUGIN) - -# if(POINT_SET_DEMO_ENABLE_FORWARD_DECL) - add_definitions(-DUSE_FORWARD_DECL) - add_executable ( Point_set_demo - ${UI_FILES} - MainWindow.cpp - Point_set_demo.cpp - Viewer.cpp - Scene.cpp - MainWindow_moc.cpp - Scene_moc.cpp - Viewer_moc.cpp - ${RESOURCE_FILES} ) - add_to_cached_list( CGAL_EXECUTABLE_TARGETS Point_set_demo ) -# else(POINT_SET_DEMO_ENABLE_FORWARD_DECL) -# add_file_dependencies( Point_set_demo.cpp "${CMAKE_CURRENT_BINARY_DIR}/MainWindow_moc.cpp" -# "${CMAKE_CURRENT_BINARY_DIR}/Scene_moc.cpp" -# "${CMAKE_CURRENT_BINARY_DIR}/Viewer_moc.cpp" ) -# add_executable ( Point_set_demo Point_set_demo.cpp ${UI_FILES} ${RESOURCE_FILES} ) -# endif(POINT_SET_DEMO_ENABLE_FORWARD_DECL) - - - # Link with Qt libraries - target_link_libraries( Point_set_demo ${QT_LIBRARIES} ) - - # Link with CGAL - target_link_libraries( Point_set_demo ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES} ) - - # Link with libQGLViewer, OpenGL - target_link_libraries( Point_set_demo ${QGLVIEWER_LIBRARIES} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ) - - # Link with the scene_item libraries - target_link_libraries( Point_set_demo PS_demo_scene_item PS_demo_scene_polyhedron_item point_set ) - - if(GLEW_FOUND) - target_link_libraries( Point_set_demo gl_splat ${GLEW_LIBRARIES} ) - endif(GLEW_FOUND) - - add_to_cached_list( CGAL_EXECUTABLE_TARGETS Point_set_demo ) - - - ########### - # PLUGINS # - ########### - remove_definitions(-DQT_STATICPLUGIN) - - macro(point_set_demo_plugin plugin_name plugin_implementation_base_name) - list_split(option ARGN_TAIL ${ARGN} ) - if(NOT ${option} STREQUAL "EXCLUDE_FROM_ALL") - set(other_sources ${ARGN}) - set(option "") - else() - set(other_sources ${ARGN_TAIL}) - endif() - qt4_generate_moc( "${CMAKE_CURRENT_SOURCE_DIR}/${plugin_implementation_base_name}.cpp" ${plugin_implementation_base_name}.moc ) - add_file_dependencies( ${plugin_implementation_base_name}.moc "${CMAKE_CURRENT_SOURCE_DIR}/${plugin_implementation_base_name}.cpp" ) - - add_library(${plugin_name} MODULE ${option} ${plugin_implementation_base_name}.moc ${plugin_implementation_base_name}.cpp ${other_sources}) - add_to_cached_list( CGAL_EXECUTABLE_TARGETS ${plugin_name} ) - # Link with Qt - target_link_libraries( ${plugin_name} ${QT_LIBRARIES} ) - # Link with scene_item - target_link_libraries( ${plugin_name} PS_demo_scene_item) - # Link with CGAL - target_link_libraries( ${plugin_name} ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES} ) - endmacro(point_set_demo_plugin) - - if(TAUCS_FOUND OR EIGEN3_FOUND) - qt4_wrap_ui( POISSON_UI_FILES PS_demo_poisson_plugin.ui) - point_set_demo_plugin(PS_demo_poisson_plugin - PS_demo_poisson_plugin - PS_demo_poisson_plugin_cgal_code.cpp - ${POISSON_UI_FILES}) - target_link_libraries(PS_demo_poisson_plugin PS_demo_scene_polyhedron_item point_set) - else() - message(STATUS "NOTICE: Neither TAUCS nor Eigen 3.1 (or greater) libraries have been found. Poisson reconstruction will not be available.") - endif() - - point_set_demo_plugin(PS_demo_inside_out_plugin PS_demo_inside_out_plugin) - target_link_libraries(PS_demo_inside_out_plugin PS_demo_scene_polyhedron_item point_set) - - point_set_demo_plugin(PS_demo_off_plugin PS_demo_off_plugin) - target_link_libraries(PS_demo_off_plugin PS_demo_scene_polyhedron_item point_set) - - point_set_demo_plugin(PS_demo_xyz_plugin PS_demo_xyz_plugin) - target_link_libraries(PS_demo_xyz_plugin PS_demo_scene_polyhedron_item point_set) - - qt4_wrap_ui(SIMPLIFICATION_UI_FILES PS_demo_simplification_plugin.ui) - point_set_demo_plugin(PS_demo_simplification_plugin - PS_demo_simplification_plugin - ${SIMPLIFICATION_UI_FILES}) - target_link_libraries(PS_demo_simplification_plugin point_set) - - point_set_demo_plugin(PS_demo_local_spacing_plugin PS_demo_local_spacing_plugin) - target_link_libraries(PS_demo_local_spacing_plugin point_set) - - point_set_demo_plugin(PS_demo_average_spacing_plugin PS_demo_average_spacing_plugin) - target_link_libraries(PS_demo_average_spacing_plugin point_set) - - if(LAPACK_FOUND OR EIGEN3_FOUND) - point_set_demo_plugin(PS_demo_smoothing_plugin PS_demo_smoothing_plugin) - target_link_libraries(PS_demo_smoothing_plugin point_set) - endif() - - if(LAPACK_FOUND) - qt4_wrap_ui( NORMAL_UI_FILES PS_demo_normal_estimation_plugin.ui) - point_set_demo_plugin(PS_demo_normal_estimation_plugin - PS_demo_normal_estimation_plugin - ${NORMAL_UI_FILES}) - target_link_libraries(PS_demo_normal_estimation_plugin point_set) - endif() - - qt4_wrap_ui( CLEANING_UI_FILES PS_demo_cleaning_plugin.ui) - point_set_demo_plugin(PS_demo_cleaning_plugin - PS_demo_cleaning_plugin - ${CLEANING_UI_FILES}) - target_link_libraries(PS_demo_cleaning_plugin point_set) - -else (CGAL_Qt4_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND) - - set(POINT_SET_DEMO_MISSING_DEPS "") - - if(NOT CGAL_Qt4_FOUND) - set(POINT_SET_DEMO_MISSING_DEPS "the CGAL Qt4 library, ${POINT_SET_DEMO_MISSING_DEPS}") - endif() - - if(NOT QT4_FOUND) - set(POINT_SET_DEMO_MISSING_DEPS "Qt4, ${POINT_SET_DEMO_MISSING_DEPS}") - endif() - - if(NOT OPENGL_FOUND) - set(POINT_SET_DEMO_MISSING_DEPS "OpenGL, ${POINT_SET_DEMO_MISSING_DEPS}") - endif() - - if(NOT QGLVIEWER_FOUND) - set(POINT_SET_DEMO_MISSING_DEPS "QGLViewer, ${POINT_SET_DEMO_MISSING_DEPS}") - endif() - - message(STATUS "NOTICE: This demo requires ${POINT_SET_DEMO_MISSING_DEPS}and will not be compiled.") - -endif (CGAL_Qt4_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND) diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/config.h cgal-4.5/demo/Surface_reconstruction_points_3/config.h --- cgal-4.4/demo/Surface_reconstruction_points_3/config.h 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/config.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -#ifndef CGAL_POINT_SET_DEMO_CONFIG_H -#define CGAL_POINT_SET_DEMO_CONFIG_H - - -// -// Empty -// - - -#endif // CGAL_POINT_SET_DEMO_CONFIG_H diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/data/ChineseDragon-points.off cgal-4.5/demo/Surface_reconstruction_points_3/data/ChineseDragon-points.off --- cgal-4.4/demo/Surface_reconstruction_points_3/data/ChineseDragon-points.off 2012-12-08 20:00:21.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/data/ChineseDragon-points.off 1970-01-01 00:00:00.000000000 +0000 @@ -1,10002 +0,0 @@ -NOFF -10000 0 0 -0.109666 35.3523 -981.072 -0.123149 -0.391088 -0.912077 --3.03435 35.7358 -982.233 0.189852 -0.217919 -0.957323 --27.8031 50.625 -952.974 -0.900035 0.393177 -0.188013 --31.9044 -10.1588 -975.537 -0.912732 -0.317793 -0.256765 -5.88912 35.2545 -981.96 0.645797 -0.247905 -0.722142 -0.730123 34.7988 -980.895 0.113146 0.0136454 -0.993485 -11.545 35.1956 -980.578 0.353096 0.0647083 -0.933347 -5.27728 35.3324 -982.355 0.205224 -0.295974 -0.932889 -2.39139 35.3488 -982.52 -0.387668 -0.380653 -0.839534 --20.0175 45.0415 -971.771 -0.152379 0.739343 -0.655861 --12.4339 34.7349 -982.089 -0.0926451 0.0237748 -0.995415 --13.8284 38.9035 -978.555 -0.53683 0.841169 0.0651827 --20.8664 34.1818 -977.736 0.0232684 0.344849 -0.93837 -8.24862 34.8589 -979.763 -0.22006 -0.21307 -0.951932 --3.10193 34.881 -981.982 0.0647641 -0.0591365 -0.996147 --4.03988 34.8801 -981.925 -0.229035 -0.19557 -0.95357 --19.0622 34.2254 -978.155 0.0528865 0.341919 -0.93824 --21.9072 34.2741 -978.109 0.0821191 0.213006 -0.973594 --32.1346 -7.58666 -980.166 -0.926303 0.181223 -0.330335 -1.44763 34.3541 -981.13 -0.618076 0.024362 -0.785741 --22.8198 33.7269 -977.941 -0.612635 0.0578734 -0.788244 --9.03029 33.4145 -980.313 -0.0880553 0.464111 -0.881389 -10.7257 34.4042 -980.519 -0.0648272 -0.294153 -0.953557 -7.74909 34.2363 -979.468 0.294928 -0.0921484 -0.951066 --16.6324 36.0816 -979.305 -0.930379 0.324796 -0.170005 -3.09859 34.8812 -982.421 -0.144184 -0.272335 -0.951339 -1.18149 33.9069 -981.139 -0.27355 0.339539 -0.899935 -0.200207 33.9887 -981.217 0.221563 0.456802 -0.861535 --30.8604 -46.59 -955.306 -0.813297 0.580146 -0.0444934 --11.7623 33.8775 -981.651 0.353665 -0.226669 -0.907492 --18.4144 33.2452 -978.102 0.239361 0.0402082 -0.970098 -12.8134 33.9763 -979.989 0.496519 -0.303459 -0.813254 -12.3251 33.9881 -980.217 0.227639 -0.386165 -0.8939 -4.95797 34.0074 -982.306 0.227659 -0.0131012 -0.973653 --5.80657 9.31486 -1013.42 -0.195116 0.510876 -0.837219 -8.14482 33.9965 -979.441 -0.182359 -0.0780318 -0.980131 --11.2836 33.3329 -981.267 0.341622 0.0798734 -0.936437 -17.9888 32.8508 -974.549 0.299123 -0.243922 -0.922512 -5.75592 33.5551 -982.251 0.385819 0.531871 -0.753828 --17.7141 32.1876 -977.489 0.273162 -0.297758 -0.914725 -11.1273 33.2816 -979.865 0.152864 -0.536205 -0.83013 --25.8199 29.2383 -952.802 -0.999895 -0.0120578 0.00806259 --11.01 32.5067 -981.383 0.162991 0.50294 -0.848814 --20.2671 32.5903 -978.587 -0.226024 0.165156 -0.960019 --12.4716 32.7444 -981.567 -0.10084 -0.24974 -0.963048 -10.5211 32.7199 -979.745 0.197781 -0.373666 -0.906232 -9.33567 33.1126 -979.854 -0.124655 -0.246654 -0.961053 --24.9071 51.1051 -964.419 -0.857831 0.501822 0.110913 --19.7094 31.822 -978.538 0.272277 -0.157028 -0.949319 --19.4578 31.0489 -978.063 0.166779 -0.309873 -0.936036 --20.4128 31.1414 -978.384 -0.10683 -0.409941 -0.905834 --21.0555 29.4366 -976.398 -0.521293 -0.649133 -0.553967 --23.5191 -5.10352 -1024.44 -0.640507 -0.0187598 -0.767724 -4.57357 31.9907 -985.807 0.0483093 0.860829 -0.506597 --29.4195 38.7895 -965.668 -0.898364 -0.147803 -0.413639 -2.93484 31.9921 -985.802 -0.140973 0.963141 -0.229096 --2.56627 31.8604 -986.184 0.151468 0.77001 -0.619792 --5.9103 31.8567 -986.999 -0.121057 0.777782 -0.616766 --29.444 -6.28634 -952.443 -0.984134 0.164499 -0.0664893 -11.2286 -50.7275 -956.386 -0.76331 -0.38159 0.521293 --18.3161 29.8001 -977.999 0.200366 0.0162071 -0.979587 -2.40889 31.6857 -986.416 -0.180935 0.679753 -0.710773 -12.0415 -50.837 -955.93 -0.2263 -0.3434 0.911518 --24.9624 51.4962 -965.66 -0.883603 0.441298 -0.156532 --4.53626 31.2551 -987.529 0.0840175 0.485352 -0.870273 --18.1934 29.3263 -977.912 0.223878 0.229942 -0.947103 -0.971406 31.1359 -985.558 -0.390236 0.683348 -0.61705 -0.558163 31.1649 -985.42 0.230857 0.68807 -0.687943 --17.4909 32.1218 -935.527 -0.330504 0.870653 0.364322 --1.40744 30.9371 -987.19 0.105468 0.597111 -0.795195 --7.36809 30.7535 -987.442 -0.315577 0.420371 -0.850705 -4.54889 31.1881 -986.895 0.0418064 0.624695 -0.779749 -3.68179 31.2756 -986.618 -0.115076 0.551463 -0.826224 --27.5623 51.236 -951.579 -0.835736 0.531763 0.137019 --26.9095 50.9425 -954.818 -0.679815 0.359899 -0.639002 --3.0667 30.614 -987.246 0.221275 0.474967 -0.85173 -8.24917 30.4391 -983.948 0.393136 0.632194 -0.667664 -1.95287 30.5058 -986.863 -0.378854 0.341443 -0.860166 --24.5007 49.8418 -962.587 -0.533989 0.425218 0.730784 --24.7105 51.4185 -963.57 -0.818851 0.435194 0.374284 -4.64351 30.4317 -987.316 -0.10258 0.169046 -0.980256 -3.17856 30.1131 -986.992 -0.0817235 0.24922 -0.964993 --8.6365 -17.3066 -957.993 -0.146447 -0.986466 -0.0737421 --5.94066 30.348 -987.904 -0.0110217 0.156014 -0.987693 -0.409573 30.1575 -986.128 0.15864 0.236668 -0.958552 -5.48159 30.0888 -987.285 0.306013 0.146435 -0.940698 -11.8528 -36.4086 -1003.26 -0.647243 -0.747404 -0.149882 --2.16921 29.8135 -987.749 -0.0739714 0.223407 -0.971914 --3.7987 29.7445 -987.904 0.246725 0.118229 -0.961847 --24.6262 50.0703 -958.808 -0.633929 0.769544 -0.0770505 --10.6761 29.1655 -986.179 0.0699794 0.549959 -0.832255 -9.62952 29.6005 -984.088 0.0364266 0.689791 -0.723092 -3.70443 29.437 -987.058 0.0606373 -0.122806 -0.990576 --2.97407 29.4708 -987.522 0.0108297 0.251105 -0.967899 --9.32653 28.7537 -985.877 0.150777 0.398341 -0.90476 -2.72109 29.2699 -987.267 -0.0393394 0.0863989 -0.995484 --24.5358 51.6081 -966.376 -0.644547 0.404874 -0.648565 --5.97104 29.1314 -987.655 0.315757 -0.0413793 -0.947937 -22.8682 -22.7431 -978.034 0.0909379 -0.211889 -0.973054 --13.7075 28.8739 -986.463 -0.163014 0.607007 -0.777797 -15.5392 -48.0836 -955.849 -0.604043 0.150199 0.78267 --26.7749 51.4779 -954.027 -0.781422 0.530663 -0.328294 --5.53813 -16.5403 -943.545 -0.868545 -0.330467 0.369353 --12.1694 28.351 -986.469 0.0110894 0.192018 -0.981329 -9.0115 28.8734 -984.466 -0.0404475 0.29794 -0.953727 --24.283 43.2097 -966.423 -0.505192 0.74911 -0.428503 --9.0805 27.7036 -986.109 -0.248448 -0.225401 -0.942055 --15.2063 28.108 -986.371 -0.608425 0.156691 -0.777989 -12.5484 28.3735 -984.721 0.373439 0.3048 -0.876151 --32.6934 -44.3311 -968.133 -0.894657 0.177168 0.410122 --12.4397 39.0822 -979.517 -0.145372 0.838115 -0.525767 -10.7641 28.5203 -985.252 0.00403784 0.380902 -0.924607 -1.38021 28.2973 -986.816 -0.442742 -0.205188 -0.872856 --4.03022 28.5245 -987.717 0.0509529 -0.0111507 -0.998639 -14.8902 -40.155 -962.281 -0.252703 -0.0359439 0.966876 -10.4486 28.1194 -985.296 -0.310528 0.0884702 -0.946438 --11.011 27.485 -986.967 0.356446 -0.0499464 -0.93298 --12.8848 27.349 -986.561 0.163971 -0.014082 -0.986365 --14.4604 27.6311 -986.669 -0.183017 -0.0193934 -0.982918 --11.521 27.6455 -987.005 -0.108729 0.316894 -0.942208 -13.1613 27.5488 -984.665 0.554897 0.16354 -0.815686 -7.6673 27.752 -985.125 0.599154 0.0227603 -0.80031 --16.6148 26.2315 -982.626 0.0274509 0.296086 -0.954767 -6.55056 -18.3039 -971.628 -0.359455 -0.930842 0.0657723 --17.4852 33.4304 -937.734 -0.236076 0.683635 0.690587 --2.30551 27.1738 -987.058 0.337163 -0.625151 -0.703922 --11.7583 26.867 -987.099 0.0839726 -0.273933 -0.958076 --17.5699 25.938 -982.83 -0.239212 0.68436 -0.688788 -9.03285 27.1377 -984.582 -0.303337 -0.190703 -0.933605 -13.795 26.8523 -984.125 0.737336 -0.23081 -0.634872 --13.5619 26.2901 -986.616 -0.129392 -0.15849 -0.978846 -17.69 26.2633 -978.606 0.572126 0.43031 -0.698216 --23.9509 50.3913 -959.328 -0.671134 0.698495 -0.248363 --5.61375 -15.7509 -946.821 -0.900946 -0.414367 -0.128825 --29.3428 -5.88815 -952.025 -0.953747 0.0635473 0.293817 --5.76705 -15.818 -943.958 -0.93757 0.0292262 0.346567 -11.2639 26.6863 -985.482 0.177991 -0.09546 -0.979391 --5.94133 -15.6519 -944.94 -0.978855 -0.203084 0.024469 --21.5373 25.1829 -982.643 -0.302487 0.535911 -0.788227 -17.6125 25.7806 -978.812 0.336515 0.252341 -0.907239 --25.2247 31.967 -969.932 -0.685792 0.722338 -0.0889821 --24.073 39.5029 -969.64 -0.683086 -0.124165 -0.719706 -5.186 25.9479 -985.67 0.278847 -0.266506 -0.922615 --2.54025 25.7778 -985.709 0.407966 -0.33389 -0.849754 --4.30002 25.6933 -985.997 -0.0517219 -0.384679 -0.9216 --28.0503 -46.3569 -951.112 -0.968905 0.124186 -0.214011 --1.2613 14.1907 -1004.97 0.51223 0.788384 -0.340692 -12.4855 25.7049 -984.825 0.424871 -0.217713 -0.878684 -8.53298 25.9124 -983.88 -0.122543 -0.321378 -0.938989 --24.0422 52.3414 -963.744 -0.408787 0.669695 0.620002 --0.562815 25.7232 -984.317 -0.129528 0.0846723 -0.987954 --9.93619 25.4387 -985.368 0.350983 -0.254233 -0.901208 --18.1135 24.5766 -983.695 0.114323 0.283836 -0.952033 -10.7643 26.1936 -985.318 -0.319417 -0.23839 -0.917138 --2.65748 25.3037 -985.645 0.436251 0.350617 -0.828705 --20.2299 24.294 -983.242 -0.230068 0.489974 -0.840829 --26.7603 52.2832 -952.927 -0.650925 0.745415 -0.143709 -17.2199 -40.0085 -962.1 0.117685 0.119697 0.985811 --1.21282 25.1626 -984.595 0.302785 0.41607 -0.857442 --6.30241 24.7199 -985.352 -0.58795 0.00841513 -0.808853 --8.09236 24.711 -984.803 -0.0430079 -0.127389 -0.99092 --9.45397 24.8327 -984.767 0.273236 -0.0908224 -0.95765 -18.9778 24.281 -977.593 0.828981 -0.0242837 -0.558749 -13.0032 24.8251 -983.992 0.50488 -0.583144 -0.636427 -1.89613 24.8158 -985.693 -0.426857 0.128358 -0.895163 --1.62126 24.583 -985.239 0.435309 0.65136 -0.621479 -17.7011 24.0923 -978.844 0.496956 -0.151694 -0.854414 -11.5219 24.9055 -984.743 0.300238 -0.521141 -0.798917 -11.2503 25.1712 -984.987 -0.152363 -0.353925 -0.92278 --26.166 51.8504 -954.595 -0.509014 0.72734 -0.460305 --23.942 50.7093 -956.799 -0.753781 0.629306 -0.18918 --7.08548 24.2364 -984.875 -0.372807 0.0757093 -0.924815 --23.1992 50.4342 -960.406 -0.463705 0.832052 -0.304412 --23.2393 50.2519 -961.801 -0.48756 0.782211 0.387854 --25.3367 31.7304 -968.64 -0.691591 0.66188 0.289167 --10.5774 10.6269 -1012.06 0.19705 0.704851 -0.681437 -8.20765 24.4038 -983.697 0.0765674 -0.276751 -0.957886 --20.7646 23.2137 -983.407 -0.334173 0.167499 -0.927509 --22.0507 23.1609 -982.964 -0.583486 0.0613341 -0.809804 --26.5095 46.8249 -954.024 -0.964103 0.206683 -0.166695 --0.11293 23.8927 -985.431 -0.0884539 0.601407 -0.794031 -16.9895 23.5785 -978.966 0.153796 -0.315817 -0.936273 --9.47614 23.6486 -985.126 0.16733 0.490062 -0.855476 --7.53641 23.2457 -984.976 -0.036667 0.295801 -0.954546 --19.6855 22.5448 -983.988 -0.126086 -0.0897288 -0.987953 --18.9683 22.337 -983.681 0.343556 -0.591362 -0.729562 --28.1338 46.3461 -961.697 -0.80455 0.438936 -0.400043 -19.4433 -40.246 -962.515 0.358858 0.197612 0.912234 -15.0333 30.77 -942.858 0.764068 -0.0469863 0.643422 --27.4151 20.7473 -976.036 -0.387973 0.504434 -0.771378 --7.19092 22.6638 -985.325 -0.188301 0.582864 -0.790451 --26.6023 20.5628 -976.36 -0.402343 0.490332 -0.773107 -15.7793 22.9124 -978.657 0.204206 -0.551422 -0.808847 --23.8209 52.7645 -964.442 -0.520606 0.847742 0.101506 --3.83678 23.0388 -989.613 0.0635786 0.79587 -0.60212 -17.7132 21.5847 -977.75 0.331391 -0.571829 -0.750461 --5.1034 22.7737 -989.706 -0.282895 0.793594 -0.538682 --27.6972 19.7403 -976.302 -0.550301 0.179587 -0.815424 --6.02453 -14.5315 -945.698 -0.85389 -0.302306 0.423654 -3.06807 22.7589 -991.069 -0.656212 0.456849 -0.600563 -14.5878 29.9149 -942.958 0.753397 -0.593761 0.282563 --23.939 54.0594 -951.448 -0.900482 0.337313 -0.274503 --1.93499 22.3402 -989.679 0.366399 0.685307 -0.62937 --4.93627 22.0053 -990.625 -0.142267 0.601632 -0.786002 --26.3296 51.8352 -948.763 -0.787065 0.465121 -0.405205 --26.1401 52.4975 -951.014 -0.620397 0.752571 0.220781 --9.20635 21.1743 -987.119 0.396827 0.655628 -0.642402 --26.4029 19.264 -977.129 -0.446291 0.147742 -0.882608 --25.1207 18.3546 -977.417 -0.274758 -0.260366 -0.92559 --16.7485 45.5197 -972.383 -0.805495 0.592351 -0.017239 --26.3979 48.9065 -955.367 -0.879829 0.145726 -0.452399 -4.4718 20.9516 -996.259 -0.186638 0.834994 -0.51764 --13.0387 20.2543 -995.624 -0.192644 0.71282 -0.674371 --13.4462 19.8017 -995.683 -0.613573 0.203137 -0.763062 --14.0797 8.16115 -1014.37 -0.9915 -0.127024 -0.0281699 --15.7112 -26.3254 -1008.71 -0.49766 -0.3497 0.793753 --23.2603 52.6336 -965.902 -0.259812 0.901483 -0.346158 --26.8246 -25.8161 -956.951 -0.468365 0.0841579 0.879518 --21.6474 16.2026 -976.787 -0.550604 0.0582013 -0.832735 --25.5195 43.8966 -947.241 -0.719489 -0.56283 0.406887 -0.67691 19.4163 -994.351 -0.313093 0.82102 -0.477387 --3.24788 19.6185 -996.033 -0.0386893 0.812616 -0.581514 --26.8248 -20.9283 -957.229 -0.448939 0.0978729 0.888186 --1.27481 19.1416 -996.378 0.216881 0.768427 -0.602066 --16.623 17.1094 -988.603 -0.404913 0.246672 -0.880453 --22.6265 52.1843 -963.141 -0.327951 0.715261 0.61713 -10.8132 17.7699 -990.569 0.0277813 0.467073 -0.883782 --13.6891 17.9489 -1000.32 -0.581028 0.570342 -0.580617 --11.473 17.4485 -1000.35 0.420358 0.687926 -0.591656 -4.44303 18.1454 -1001.81 0.0711621 0.788462 -0.610954 --22.6057 46.871 -947.614 -0.918536 0.0222973 0.394709 -2.67387 17.3768 -1002.04 -0.456964 0.575838 -0.677934 --2.47082 16.5077 -1001.36 0.170953 0.770093 -0.614599 --15.8845 14.8995 -994.804 -0.404045 0.64898 -0.644649 -0.112687 16.2769 -1000.71 -0.139246 0.666059 -0.732787 --8.99984 15.4395 -1000.13 -0.163009 0.868509 -0.468102 --15.9033 14.548 -995.014 -0.241544 0.301436 -0.922384 -13.037 15.0746 -991.853 0.530685 0.450126 -0.718165 -0.108678 15.1793 -1001.33 -0.242365 0.662877 -0.708416 --0.265786 15.4233 -1001.1 0.298959 0.709526 -0.638119 -10.5597 14.7472 -996.734 0.460636 0.576416 -0.674952 --27.139 48.5415 -949.173 -0.983373 -0.117841 -0.138172 --12.3264 15.178 -1005.63 0.347138 0.828725 -0.438988 --0.025138 14.2348 -1002.94 -0.0362991 0.862747 -0.504332 -11.3551 13.5621 -997.148 0.452819 0.336764 -0.825557 --16.3057 45.9178 -971.718 -0.625278 0.775755 0.0850431 -9.17238 13.732 -1000.85 0.309488 0.79265 -0.525284 --8.98425 39.4624 -981.568 -0.903528 0.318287 -0.286932 --1.59371 13.3087 -1006.83 0.358664 0.808095 -0.46727 -12.0863 12.2792 -996.995 0.50604 0.20367 -0.838118 --16.4684 -34.1385 -947.86 0.425668 0.421495 0.800717 -8.88914 12.3257 -1002.87 0.285648 0.764147 -0.578346 --15.9805 11.6778 -1004.54 -0.557058 0.823334 -0.108658 -3.42421 12.9632 -1010.51 -0.057723 0.916354 -0.396185 --12.9607 12.3654 -1010.74 -0.135058 0.840597 -0.524554 --16.1771 10.9162 -1005.87 -0.364303 0.735996 -0.570607 --11.2547 11.3252 -1011.64 0.0473745 0.671739 -0.739272 -3.20197 12.2942 -1011.79 -0.230265 0.844921 -0.48279 -9.47304 11.4159 -1003.67 0.255823 0.626473 -0.736265 --17.9419 9.61768 -1006.32 -0.504559 0.688274 -0.521247 -10.8856 10.5264 -1003.68 0.443295 0.541708 -0.714172 -4.39959 11.5392 -1012.74 0.241031 0.655378 -0.71581 --6.85977 13.0082 -1024.28 -0.297601 0.788927 -0.537612 --18.8256 8.41038 -1004.89 -0.903114 0.215709 0.371288 --12.4287 10.6003 -1013.86 -0.1779 0.957138 -0.228556 --6.33695 12.5137 -1024.58 0.101348 0.393893 -0.913552 --7.61172 12.3457 -1024.55 -0.427228 0.394015 -0.813774 --9.57662 39.689 -979.506 -0.210109 0.900052 -0.381785 --28.4793 -3.43268 -952.013 -0.943026 0.330593 0.0375528 --12.4154 10.2043 -1014.64 0.0496643 0.83129 -0.553616 -11.4526 9.17046 -1004.18 0.409995 0.422314 -0.808428 --13.4964 9.82844 -1014.87 -0.546127 0.772601 -0.323779 --0.233512 9.77042 -1011.28 0.183718 0.711898 -0.677826 -16.3251 -21.1293 -1005.58 0.0710283 -0.834618 0.54623 --21.815 52.7616 -963.914 -0.176183 0.929667 0.323541 --24.1434 -31.0321 -951.437 -0.10188 0.908591 0.405072 --23.9042 53.7369 -952.305 -0.571355 0.803384 -0.167712 --3.46365 15.5737 -1002.64 0.121456 0.895142 -0.428916 -2.07885 9.37439 -1015.8 -0.464138 0.787167 -0.406133 --11.1078 8.77866 -1016.02 0.411352 0.648024 -0.64098 --11.9589 8.82782 -1016.3 0.0426842 0.715774 -0.697026 --17.9206 8.3002 -1003.71 -0.829637 0.0613753 0.55492 -3.48967 9.36054 -1016.21 0.139421 0.814481 -0.563189 -1.6884 9.00905 -1015.95 -0.631827 0.570513 -0.524699 --4.26315 10.6945 -1024.74 0.35505 0.438799 -0.825466 --19.1687 7.05793 -1007.56 -0.203415 0.451032 -0.869018 -9.91996 8.33055 -1008.63 0.345581 0.550338 -0.760067 --4.99471 10.3873 -1025.04 0.125534 0.345088 -0.930137 --20.0811 42.5697 -937.477 -0.98874 0.0535951 0.139718 --24.5127 53.3462 -951.162 -0.484224 0.868969 0.102075 -3.8291 9.02184 -1016.46 0.445041 0.528441 -0.722972 -2.84263 8.8988 -1016.66 -0.180109 0.599551 -0.779808 --10.3862 8.08275 -1015.98 0.61167 0.45934 -0.644102 --12.3928 8.10914 -1016.85 -0.490251 0.481573 -0.726458 -6.74091 7.75606 -1012.51 0.429608 0.698752 -0.571999 --21.2236 52.7534 -962.952 -0.581225 0.786526 0.208695 --6.21666 9.71005 -1025.3 -0.12136 0.352072 -0.928072 --9.41552 7.78933 -1015.24 0.558647 0.502483 -0.659867 -11.545 -49.8847 -956.171 -0.632776 0.108099 0.766753 -18.8071 36.0329 -955.418 0.366388 -0.0999208 0.925081 --15.5463 47.4562 -974.483 -0.523224 0.844859 -0.111582 --12.2164 7.57251 -1017.48 -0.033541 0.763127 -0.645378 --16.3537 6.91381 -1012.18 -0.364723 0.656172 -0.660618 --31.8652 -10.8784 -977.899 -0.969325 -0.227336 0.0934188 -5.62891 7.65201 -1013.16 0.438319 0.533203 -0.723582 --7.81466 8.76873 -1024.96 -0.759609 0.217198 -0.613041 --15.2994 6.35774 -1012.74 -0.23288 0.345324 -0.90913 --21.2337 52.9066 -964.362 -0.148623 0.988178 -0.0376247 --3.61879 8.74096 -1025.59 0.195682 0.461915 -0.865068 --16.5935 -26.0402 -1009.08 -0.283338 -0.38858 0.87677 --20.0147 5.43993 -1008.05 -0.584752 0.325263 -0.743148 -4.46369 43.7568 -976.935 0.0841729 -0.134611 -0.987317 --19.7965 5.03504 -1008.23 -0.321262 0.275467 -0.90604 --8.50287 40.5532 -981.174 -0.660926 0.710524 -0.241521 --13.7747 6.29195 -1018.01 -0.76407 0.510449 -0.394512 --16.4875 5.70179 -1012.78 -0.0826897 0.34629 -0.934476 --16.295 -28.0752 -965.67 0.963571 -0.10239 -0.247076 --23.4366 53.2741 -954.662 -0.656338 0.752866 -0.0491182 --21.1797 52.682 -962.46 -0.912081 0.36028 -0.19572 --20.0092 -38.2039 -945.985 0.319978 0.079933 0.944047 --15.1185 47.3185 -972.456 -0.613153 0.766465 0.191247 -7.8072 6.4896 -1013.2 0.245116 0.572253 -0.782588 --7.13939 7.9329 -1025.82 -0.405173 0.455276 -0.792817 --15.6178 36.9504 -981.023 -0.766132 0.331539 -0.550567 --19.7396 3.7298 -1008.33 -0.414447 0.425454 -0.804502 --12.8564 6.01834 -1019.77 -0.302497 0.536045 -0.788132 --6.29055 7.27469 -1026.47 -0.156027 0.493439 -0.855672 -12.3028 4.87108 -1009.48 0.741063 0.528382 -0.414292 --4.39857 7.07151 -1026.62 0.179692 0.511379 -0.840358 -11.9564 4.9011 -1009.81 0.522961 0.474201 -0.708269 --17.8062 4.15716 -1013.59 0.136781 0.359898 -0.922911 --2.53835 6.70434 -1026.5 0.260275 0.544736 -0.797195 --8.17161 40.2675 -978.923 -0.454361 0.885257 0.0993841 --11.0559 4.95075 -1020.43 0.255563 0.314592 -0.914177 -3.03791 5.70517 -1020.85 0.32382 0.674933 -0.663028 -2.39396 5.56512 -1021.06 -0.134174 0.704953 -0.696447 --7.80566 58.7334 -956.145 -0.308406 0.571063 -0.760771 --18.4412 3.16625 -1014.07 -0.112015 0.492506 -0.86307 -11.7706 3.80495 -1010.45 0.563253 0.558259 -0.609174 -3.63501 4.95844 -1020.85 0.5751 0.165062 -0.801258 --5.29703 -12.5753 -943.91 -0.884967 0.12383 0.448887 -2.40023 4.96002 -1021.48 0.16678 0.169423 -0.971329 --6.65939 35.9005 -936.62 -0.494698 0.461548 0.736375 --28.1234 -2.57035 -952.447 -0.896954 0.367441 -0.24589 --9.89192 4.24853 -1019.91 0.244746 0.457464 -0.854883 --22.0765 53.7106 -954.153 -0.34141 0.806865 0.482086 --17.5283 2.51882 -1014.22 -0.223342 0.624375 -0.748515 --8.99773 3.46243 -1019.88 0.192763 0.646938 -0.737776 --18.9854 2.4482 -1014.35 -0.240871 0.554402 -0.79663 -5.51715 3.96007 -1017.99 0.355277 0.665379 -0.656543 --7.59895 41.0477 -980.336 -0.283792 0.958501 0.0271773 --7.1718 40.6798 -978.877 -0.33374 0.932901 0.135324 --3.89783 5.07834 -1027.81 0.585558 0.53965 -0.604897 --26.4345 48.797 -959.273 -0.567839 0.734959 -0.370667 --13.8081 48.2232 -973.469 -0.307325 0.930085 -0.201229 --13.3574 48.0638 -974.207 -0.00248488 0.824252 -0.566218 --26.1584 30.6045 -967.74 -0.500635 0.664817 0.554421 --25.9978 1.35796 -953.632 -0.704235 -0.0363097 0.709038 -10.3726 3.16098 -1015.06 0.516726 0.538543 -0.665557 -10.9793 37.9748 -939.139 0.830031 -0.242046 0.502456 --15.3706 2.01839 -1017.74 -0.11202 0.546614 -0.829858 --19.8232 1.43177 -1014.79 -0.514525 0.772197 -0.372796 --17.226 8.93386 -1002.88 -0.830266 0.42113 0.365113 -5.44589 3.18581 -1018.54 0.346919 0.281031 -0.894801 --6.5764 4.54722 -1028.17 -0.0855351 0.531687 -0.842611 --19.4983 -33.9716 -975.731 0.879545 0.442792 0.174173 -11.0877 -50.7453 -958.636 -0.47216 -0.878249 -0.0757814 --8.55198 3.90963 -1027.7 -0.744566 0.435407 -0.506006 -18.9625 -38.8783 -962.469 0.239775 -0.0167479 0.970684 --13.9213 1.59287 -1017.35 -0.312833 0.0523351 -0.948365 --16.6572 1.67989 -1017.77 -0.392923 0.725255 -0.565346 --25.809 29.2546 -966.397 -0.768228 0.516292 0.378507 --5.87492 41.1308 -979.901 -0.124757 0.991456 0.038078 --7.32124 3.78312 -1028.48 -0.330858 0.5202 -0.787353 --14.0637 1.17676 -1017.44 0.142448 0.336498 -0.930848 --33.1601 -43.8853 -978.689 -0.875224 -0.434519 -0.212545 -11.5765 1.4446 -1015.56 0.365569 0.516369 -0.774418 -7.45578 2.04111 -1019.03 0.0910949 0.568993 -0.817281 --17.8848 -46.0734 -960.547 0.958975 0.172298 0.225124 -8.65806 1.9767 -1018.65 0.404531 0.722286 -0.560944 --16.9486 53.3741 -963.608 -0.436444 0.843179 -0.313952 --27.9474 -2.26985 -952.055 -0.754746 0.650953 0.0813586 --17.5055 0.602677 -1018.8 -0.0458694 0.746726 -0.663548 --33.402 -43.6302 -975.676 -0.984411 -0.173229 0.0304345 --26.1647 31.6132 -969.429 -0.39474 0.870119 0.295082 -10.4719 -48.0287 -959.16 -0.903492 0.390856 0.175881 -23.2418 28.1857 -961.428 0.824913 0.250786 0.506582 --19.3958 8.50433 -998.498 -0.847246 0.522048 0.0981871 -2.49051 1.59824 -1024.47 0.53529 0.413738 -0.7364 -12.5149 0.294215 -1016.04 0.179538 0.670412 -0.719941 --2.95409 2.02094 -1029.79 0.159642 0.541276 -0.825551 --8.85576 20.0917 -988.69 0.205282 0.928315 -0.309986 --20.9775 -0.415685 -1019.81 0.119869 0.933253 -0.33863 -11.2728 -46.3673 -961 -0.785232 0.557687 0.269065 -1.04799 5.49003 -1020.52 -0.572733 0.622787 -0.533022 --10.4707 20.4844 -989.845 0.463555 0.737899 -0.490533 -10.5051 -23.6107 -1001.03 0.534249 -0.797331 0.280785 -19.8221 35.2107 -969.734 0.714241 0.619277 0.326123 --6.95587 1.42274 -1030.09 -0.132337 0.49812 -0.85695 --23.0212 13.9516 -975.442 -0.729779 -0.287723 -0.620192 --21.5463 -1.19601 -1021.85 0.262721 0.834958 -0.483552 -19.3822 32.9501 -966.357 0.951131 0.301802 0.0653126 -22.5928 37.5735 -959.757 0.881219 -0.0725351 -0.46711 -1.50734 -0.044241 -1024.89 0.756848 0.00272808 -0.653585 --24.3998 -1.40495 -1023.16 -0.363483 0.742652 -0.562448 --15.2528 -19.5189 -965.381 0.785681 -0.602591 0.139963 -2.64037 -0.824073 -1023.97 0.677146 0.0428964 -0.734597 --2.48546 0.255359 -1030.81 0.0796187 0.494532 -0.865505 -16.1229 25.3513 -948.283 0.726286 0.241575 0.643545 -15.9517 -1.17565 -1020.5 -0.0211038 0.883518 -0.467921 -19.1416 34.6087 -968.514 0.848473 0.442342 0.290562 --23.0916 -1.98103 -1024.41 -0.160199 0.76341 -0.625732 -18.6509 36.1372 -969.704 0.411275 0.823789 0.390159 -15.5482 24.4774 -947.08 0.54403 0.515301 0.662191 -19.3057 22.0914 -974.834 0.972088 -0.165987 -0.165812 -15.5663 24.0723 -946.776 0.890194 -0.056024 0.452123 --5.74159 -0.731676 -1031.3 -0.062284 0.450276 -0.890715 -10.9615 -2.0294 -1023.92 0.0571687 0.661308 -0.747933 --8.49294 -0.901272 -1030.96 -0.316093 0.452309 -0.833967 --22.4495 -2.94762 -1025.62 -0.0790345 0.695406 -0.714258 --14.3617 2.66849 -1017.6 -0.142668 0.174276 -0.974307 -13.8582 -1.96678 -1023.64 0.0949553 0.660855 -0.744482 --23.1637 -3.16633 -1025.56 -0.509372 0.413693 -0.754585 -14.8253 23.8426 -946.078 0.258615 0.667073 0.698664 --2.38596 -1.50075 -1031.75 0.0840291 0.442968 -0.892591 -18.319 35.4644 -968.67 0.542717 0.772557 0.329567 -22.0397 39.3011 -957.564 0.631762 0.67134 0.38753 -4.79187 -2.11487 -1028.77 -0.119523 0.901485 -0.41598 --12.8507 -2.44663 -1030.03 0.232766 0.744352 -0.625907 --15.2143 -2.19984 -1030.53 0.0628827 0.778376 -0.624641 -17.9364 -2.80412 -1022.32 0.439902 0.588461 -0.678381 -9.91678 -29.8333 -1006.28 -0.312194 -0.131749 0.940838 -17.8512 36.7971 -970.732 0.316056 0.93191 0.177911 --26.9165 -5.22065 -1022.44 -0.620977 0.262386 -0.738608 --29.5104 -37.5266 -1000.2 -0.282386 -0.947235 0.15167 --16.604 -2.88139 -1031.26 -0.1027 0.521844 -0.846836 -5.95315 -2.6283 -1029.86 -0.0742618 0.697187 -0.713032 -23.272 26.5945 -965.949 0.876583 0.00116505 -0.48125 -13.0021 20.5446 -942.329 0.635297 0.51246 0.577739 --13.305 -3.03991 -1030.7 0.385898 0.404399 -0.829183 --25.368 -19.7247 -1029.84 -0.266643 0.702983 -0.65933 -17.2907 -3.41591 -1022.87 0.2867 0.367949 -0.884543 --14.2899 10.8981 -1009.57 -0.996147 -0.0440482 0.0758298 -0.0375173 -2.73289 -1031.92 0.317966 0.428891 -0.845547 --17.2592 -3.3338 -1031.33 -0.403152 0.333973 -0.852016 --17.9842 -3.25757 -1030.81 -0.700577 0.431876 -0.568044 -18.6369 -4.06451 -1022.93 0.368606 0.532571 -0.761904 -14.9977 -3.81069 -1023.65 0.31594 -0.0895608 -0.944543 --10.0986 -3.37477 -1030.98 -0.739784 0.572212 -0.353969 -8.70313 -3.2286 -1030.32 0.339759 0.449586 -0.826097 --20.4857 0.880674 -1015.74 0.05924 0.943861 -0.324989 --8.33366 -3.14206 -1032.06 -0.196695 0.411836 -0.889776 -15.161 -4.20916 -1023.72 0.0925032 0.450289 -0.888078 -3.38813 -3.16667 -1030.16 -0.0565144 0.786354 -0.615186 --4.24203 -3.27724 -1032.57 -0.0493036 0.394506 -0.91757 --13.4769 -3.88916 -1031.14 -0.00271791 0.401523 -0.915845 --15.4545 -3.96871 -1031.69 0.145033 0.164127 -0.975719 --18.774 -37.339 -946.838 0.280069 0.350455 0.893724 -1.68399 -3.20953 -1030.56 0.72085 0.496621 -0.48347 --18.9857 10.2322 -998.749 -0.844637 0.437655 0.308297 --10.4359 -3.9409 -1031.36 -0.348493 0.686028 -0.638685 -13.2686 -4.5955 -1023.98 0.156379 0.0773451 -0.984664 -7.3311 -3.67055 -1030.76 -0.0153413 0.41382 -0.910229 -5.65533 -3.7595 -1030.62 0.0643672 0.408274 -0.910587 -9.2094 -4.38678 -1030.34 0.557822 -0.0312159 -0.829374 --16.8349 -50.1869 -957.871 0.921405 -0.348557 -0.171817 -18.2059 34.2121 -955.213 0.957673 0.216963 -0.18918 --0.942623 -3.90449 -1032.68 0.150385 0.386205 -0.910072 --16.4851 -4.61714 -1031.69 -0.15177 -0.096857 -0.983659 -2.18891 -3.80157 -1030.88 0.234468 0.721412 -0.651606 --14.6146 -4.74144 -1031.34 0.0287737 -0.0294933 -0.999151 -17.639 31.5214 -947.693 0.790664 0.611877 0.0213937 --29.0456 21.5024 -963.154 -0.775811 -0.549851 -0.309484 -6.79189 -4.59743 -1030.98 0.130965 -0.129435 -0.982901 --29.1738 -42.0417 -983.941 -0.488356 -0.1612 -0.857627 -11.5533 -5.42086 -1024.29 0.174494 0.314893 -0.932949 --13.4829 -5.54325 -1031.67 -0.313585 0.252472 -0.915381 --25.6144 -7.04797 -1023.96 -0.462129 0.274293 -0.843327 -11.627 20.1691 -941.28 0.309177 0.950821 0.0187064 --0.621057 22.7343 -986.868 0.391227 0.816809 -0.423987 -4.24208 -4.77567 -1031.3 0.224125 0.301364 -0.926794 -16.4781 36.49 -969.542 0.371081 0.906415 0.201769 --12.9287 21.5205 -986.77 -0.677905 0.350168 0.646396 --14.1482 44.9871 -976.435 -0.0522471 0.167113 -0.984552 -1.71245 -4.68245 -1031.65 0.306587 0.491095 -0.815371 --17.0836 -36.8527 -981.528 0.575631 0.512291 -0.637343 --17.4088 10.9367 -997.168 -0.754765 0.443087 0.48374 -17.5411 31.4963 -946.909 0.918468 0.183154 0.350529 -14.0865 -5.98507 -1024.93 -0.0280956 0.553588 -0.832317 -8.52064 -5.50822 -1030.16 0.553763 -0.618411 -0.557597 -19.6669 40.6084 -963.418 0.997766 -0.0536816 0.0397584 --28.6347 44.6747 -951.46 -0.77051 0.501126 0.393937 --23.7207 -7.65914 -1025.03 -0.372019 0.291618 -0.881227 --12.8066 17.6412 -1000.81 0.0749711 0.549166 -0.832343 -11.0971 20.7338 -942.046 0.331667 0.934101 0.13211 -17.8178 -6.37652 -1024.8 0.282967 0.502511 -0.816953 -16.0276 -6.07675 -1024.97 0.0817642 0.545853 -0.833882 -16.378 31.1765 -944.861 0.94014 0.234812 0.246982 --9.7694 -5.55319 -1032.8 -0.272113 0.513057 -0.814081 --12.3981 37.5503 -981.131 -0.026465 0.556245 -0.830597 --3.36588 -5.66773 -1033.58 0.0139594 0.368052 -0.9297 --10.7738 39.2578 -980.036 -0.164594 0.734406 -0.65845 -10.5697 20.3478 -940.445 0.246863 0.752131 0.611031 -15.0417 37.1383 -971.685 0.534597 0.844357 -0.0355966 --25.6957 -8.67837 -1024.38 -0.630777 0.178084 -0.755252 --8.48672 15.188 -938.261 -0.00632821 -0.717604 0.696422 --29.6752 23.3734 -963.444 -0.899421 -0.0975533 -0.426058 -14.2007 28.3797 -939.873 0.889089 -0.456909 -0.0274864 -21.3965 43.3552 -955.329 0.928637 0.159411 -0.334996 --12.3277 -6.02006 -1032.52 -0.477885 0.248684 -0.842486 --17.9551 12.3144 -992.483 -0.824348 0.432433 0.365312 -10.1336 -6.94701 -1025.45 0.500955 0.0910596 -0.860669 -18.4244 -7.54888 -1025.19 0.371874 0.404299 -0.835615 -12.1097 -47.1 -957.786 -0.292792 0.810679 0.507023 -18.7646 43.8755 -966.693 0.710203 0.657642 -0.251233 -13.6696 38.1253 -977.229 0.569119 0.805834 -0.163508 -19.0332 -8.07625 -1025.08 0.503217 0.314085 -0.805061 -9.50333 -7.72456 -1025.83 0.173126 0.309562 -0.934986 -3.90991 -7.41572 -1032.13 0.590201 -0.00355972 -0.807249 -0.404184 -6.98096 -1033.57 0.495481 0.270659 -0.825374 --1.40217 -7.01596 -1033.98 0.118664 0.303364 -0.945457 --10.2923 11.7533 -1010.87 0.372162 0.70471 -0.604053 --9.59913 -6.88579 -1033.57 -0.209235 0.435412 -0.875578 -13.5061 38.0389 -975.578 0.518237 0.842444 -0.147372 -18.5766 43.8589 -965.42 0.834754 0.545404 0.0756316 -18.5313 43.8681 -964.078 0.773319 0.555539 0.305538 -20.8934 44.6785 -953.627 0.74271 0.613952 0.267293 -12.2038 -7.9773 -1026.26 -0.00429657 0.541796 -0.840499 --11.3739 -7.19506 -1033.37 -0.247256 0.36982 -0.895599 --17.0421 43.945 -974.409 -0.905911 -0.251806 -0.340469 -12.7842 38.4622 -975.665 0.41078 0.910071 -0.0550476 -18.0757 44.477 -964.401 0.599435 0.765157 0.234973 --22.7343 -9.71471 -1026.21 -0.352972 0.298095 -0.886876 -15.8112 -8.57591 -1026.47 0.145209 0.461003 -0.875438 -17.8435 39.4391 -948.089 0.87168 0.374473 0.31614 --24.784 -10.4271 -1025.4 -0.537637 0.169314 -0.826002 --30.0718 -11.8453 -1018.58 -0.532561 0.390511 -0.75092 --17.4636 43.6516 -973.108 -0.382549 0.0937277 -0.919169 -20.1652 -9.53872 -1024.7 0.706121 0.194055 -0.680982 -14.3509 32.2739 -938.324 0.857935 0.390655 0.333672 -12.4178 38.7287 -976.742 0.25168 0.967596 -0.020378 -7.00748 -9.21798 -1026.85 0.0730227 0.372007 -0.925353 -2.71181 -8.61329 -1032.84 0.258137 0.210356 -0.942929 -0.0674263 -8.86249 -1034.22 0.503238 0.209695 -0.83832 -19.6698 45.1434 -953.44 0.508944 0.790963 0.339636 --4.43617 -8.32867 -1034.53 0.0188341 0.298276 -0.954294 --6.98169 -8.28933 -1034.41 -0.0322049 0.338661 -0.940357 --15.6631 -19.3881 -1032.55 -0.734189 -0.542426 -0.408338 -12.094 -21.3226 -977.521 -0.559265 -0.570033 -0.601901 -7.05559 -30.7788 -1006.52 0.251009 -0.508833 0.823458 --20.1011 -11.0717 -1027.57 -0.316376 0.228546 -0.920692 --30.215 -12.7138 -1019.17 -0.327158 0.636393 -0.698549 -17.5849 44.912 -964.997 0.356565 0.922575 0.147364 -12.162 -9.69941 -1027.27 0.0133563 0.626587 -0.779237 -17.2374 44.1473 -963.13 0.596776 0.764891 0.242486 -3.39616 -9.44103 -1032.61 0.593352 0.127474 -0.794785 -1.03094 -8.93958 -1033.25 0.509001 0.174509 -0.842891 --18.8466 -0.711644 -1020.4 0.186471 0.708394 -0.68074 --4.26963 -13.3833 -941.563 -0.659866 0.0775604 0.747369 -17.3459 39.8775 -947.415 0.765038 0.444596 0.465887 --28.9054 -12.7347 -1019.54 -0.5899 0.300358 -0.749535 -15.0547 -10.0631 -1027.29 0.0971445 0.532575 -0.840789 -6.48236 -29.2589 -1005.17 0.40854 -0.596453 0.690897 --8.62264 -8.93997 -1034.59 -0.103169 0.364836 -0.925338 --29.353 -36.3083 -999.45 -0.286677 -0.0422447 0.957095 -10.3803 -0.0849554 -1019.56 0.800594 0.560069 -0.213006 --16.7157 -47.9931 -958.46 0.984077 0.133995 -0.116777 -17.2101 41.1121 -951.639 0.906758 0.420494 -0.0312223 --32.5865 -9.46644 -978.653 -0.964566 -0.261089 0.0380157 -15.8053 -10.4947 -1027.39 0.279911 0.485795 -0.828042 -16.7952 38.535 -945.555 0.795688 0.346973 0.496479 --29.0856 18.4519 -974.045 -0.958268 -0.225198 -0.176092 -11.057 -45.8018 -962.197 -0.723502 0.499407 0.47659 -10.9067 41.4645 -973.78 0.200628 -0.211206 -0.95663 --18.7305 -12.0605 -1028.28 -0.165342 0.245041 -0.95531 -16.598 -10.8892 -1027.34 0.474461 0.460161 -0.750426 --31.5968 -10.6134 -976.728 -0.964423 -0.204202 0.167898 -1.33986 -10.359 -1033.42 0.254282 0.219283 -0.941942 --10.7286 -9.84754 -1034.48 -0.439347 0.225863 -0.86946 -11.1057 26.452 -932.601 0.636469 -0.436661 0.635794 --23.067 -12.686 -1026.76 -0.421152 0.163101 -0.892204 -19.1113 45.7115 -954.039 0.491457 0.862042 0.123911 --16.213 18.1139 -984.763 -0.602437 0.640259 0.47659 -19.249 -11.4885 -1025.9 0.60987 0.119729 -0.783405 --11.4701 -10.0999 -1034 -0.513803 0.225351 -0.827782 --9.65795 -10.3726 -1034.95 -0.220573 0.282396 -0.933595 -13.8051 32.624 -938.007 0.450916 0.792127 0.411351 -10.3545 38.7001 -978.654 0.0493403 0.958752 -0.279929 -18.2742 -11.9577 -1026.68 0.695198 0.178299 -0.696354 -16.6126 44.7988 -963.782 0.343536 0.864635 0.366591 --7.963 -10.8948 -1035.3 -0.0468749 0.292563 -0.955097 --24.4233 -13.5263 -1026.11 -0.538463 0.094477 -0.837336 --18.7765 8.70428 -946.698 -0.834244 0.396019 0.383674 --5.07257 -11.4284 -1035.44 0.0210175 0.24213 -0.970016 -17.1558 -12.6574 -1028.33 0.652773 0.247667 -0.715925 --28.6348 -37.9714 -948.325 0.165304 -0.342281 0.924942 --12.0492 53.5729 -970.172 0.149243 0.706185 -0.69212 --0.690893 -11.6753 -1035.15 0.241619 0.202002 -0.949113 -13.8188 32.0367 -936.31 0.684955 0.648654 0.331791 -6.28471 -11.8424 -1032.42 -0.0733364 0.862089 -0.501423 -15.4082 -12.1137 -1029.33 0.415876 0.504091 -0.756928 -12.4262 -11.6179 -1030.18 0.21884 0.777664 -0.589362 -16.5772 40.8326 -947.254 0.703223 0.535524 0.467645 --17.669 -12.4351 -1033.1 -0.588307 0.751902 -0.297552 --18.6213 36.5691 -976.359 -0.193534 0.746131 -0.637051 -21.9672 -13.9009 -1019.42 0.54255 0.367123 -0.755553 --20.5524 -29.3868 -953.838 0.0197597 0.695229 0.718517 -14.8718 -12.4471 -1029.74 0.382 0.256068 -0.887978 -9.49091 -12.13 -1033.45 0.151289 0.838349 -0.52372 --1.85815 -12.3598 -1035.43 0.0799853 0.181767 -0.980083 --16.6968 -12.5452 -1034.09 -0.409443 0.612055 -0.676569 -7.52218 -12.2587 -1033.59 -0.130134 0.806846 -0.576251 -1.16345 -12.4138 -1034.03 0.57071 0.133227 -0.810272 --13.6393 -12.9409 -1033.92 0.0875658 0.83793 -0.538707 --16.5517 55.661 -950.433 -0.339678 -0.253954 0.905608 --20.3143 -14.4773 -1029.05 -0.304376 0.827725 -0.471408 -4.82636 -28.8427 -1003.62 0.399639 -0.702815 0.588507 -11.0523 -15.0994 -1033.23 0.627837 -0.73636 -0.252178 -10.3175 26.6158 -932.072 0.47223 0.390423 0.790297 --13.1067 -12.8136 -1033.77 -0.352675 0.591218 -0.725315 --16.2452 -12.7146 -1034.39 -0.115454 0.614621 -0.780328 -10.384 -12.5605 -1033.62 0.455113 0.702297 -0.547403 --6.34752 40.0635 -982.722 -0.106952 0.504943 -0.856501 -15.0053 38.1975 -943.098 0.461483 0.574346 0.676136 --9.20603 -12.8074 -1035.71 -0.195537 0.216959 -0.956396 --9.26698 13.8113 -941.306 0.0200815 -0.907119 0.420395 -13.9343 21.2239 -945.221 0.942705 -0.132521 0.306178 -15.5256 -13.5396 -1029.75 0.496249 0.0702868 -0.86533 --3.51619 -12.9871 -1035.6 0.125125 0.184446 -0.974845 -16.8469 -13.9891 -1028.53 0.656527 -0.253502 -0.710429 -18.4592 45.7073 -953.205 0.378645 0.824153 0.421188 -8.5481 -12.7754 -1034.32 -0.0438016 0.634122 -0.771991 -0.504357 -13.3047 -1034.93 0.548741 0.148461 -0.822705 --10.9072 -13.3171 -1035.14 -0.348354 0.212118 -0.913047 -4.55793 -29.8529 -1004.51 0.460136 -0.734732 0.498441 -14.8158 -13.9859 -1030.04 0.431973 -0.416063 -0.800182 -5.98211 -13.0443 -1033.95 -0.238645 0.611013 -0.754792 -13.0371 33.2783 -938.737 0.227706 0.795511 0.561527 --25.6435 22.149 -966.918 -0.910668 0.0922864 -0.402699 --16.1555 26.1364 -982.767 -0.645767 0.327319 -0.689817 -13.0203 31.6523 -934.196 0.679944 0.462062 0.569364 -1.79146 -13.8746 -1033.64 0.524327 0.18394 -0.831413 -13.6822 50.8965 -948.171 0.966772 -0.236576 0.096874 -18.0627 46.1685 -953.94 0.542598 0.784822 0.299402 --10.9319 42.1588 -975.77 0.426275 -0.0124755 -0.904508 --12.7805 -13.7672 -1034.84 0.0474079 0.628828 -0.776097 --15.402 -13.6502 -1034.99 -0.0545742 0.489745 -0.870156 --20.6459 -15.307 -1029.9 -0.241555 0.552842 -0.797507 -0.661095 32.4739 -982.968 0.00103548 0.875552 -0.483122 -10.5858 -13.7956 -1034.52 0.64027 0.0757051 -0.764411 -10.2055 -13.4903 -1034.63 0.323994 0.541187 -0.77598 --24.5503 22.4938 -956.494 -0.939206 -0.27787 -0.201694 --17.373 -48.0544 -960.433 0.964231 0.179685 -0.194863 -12.37 -12.7021 -1030.88 0.470008 0.457335 -0.754941 --29.8499 -17.382 -1023.66 -0.631013 0.556811 -0.540171 -12.5687 32.9207 -937.575 0.262642 0.911322 0.317036 --27.9323 -29.7589 -969.137 -0.965304 0.102605 -0.240124 --11.5152 -14.1529 -1035.22 -0.238507 0.340342 -0.909551 -3.80849 -14.0324 -1033.89 -0.262832 0.548597 -0.793701 --18.0637 -14.3028 -1035.05 -0.642899 0.0766448 -0.762107 -6.7161 -14.0293 -1034.72 -0.156586 0.254325 -0.954358 --9.95369 44.8325 -975.724 -0.372115 -0.121812 -0.920159 --26.4899 45.4323 -947.492 -0.873366 -0.369579 0.317243 --15.9892 -14.5324 -1035.23 -0.107285 0.17331 -0.979006 -9.04021 -14.2917 -1035.25 0.115248 0.244055 -0.962889 --4.85431 -14.3733 -1036.07 0.112196 0.151935 -0.982002 --17.5386 -14.4063 -1035.32 -0.205016 -0.0138996 -0.97866 --21.7946 -16.1248 -1030.01 -0.311329 0.360142 -0.879416 -19.9844 -16.1282 -1021.29 0.260466 0.530716 -0.806534 -9.93827 -14.4435 -1034.98 0.294212 -0.431522 -0.852776 -4.60073 -14.3377 -1034.29 -0.135549 0.325035 -0.935937 --2.66986 25.4799 -932.154 0.0455523 -0.870131 0.49071 --7.66046 -14.5165 -1036.23 0.00712003 0.204032 -0.978938 --24.9433 -16.8218 -1028.76 -0.439399 0.202915 -0.875074 -7.90371 -14.6597 -1035.2 -0.0680058 -0.217517 -0.973685 -12.3527 32.002 -934.089 0.360139 0.83607 0.413867 --2.95214 -14.6808 -1035.79 0.165732 0.117714 -0.97912 --22.7604 -16.8511 -1029.85 -0.34459 0.0305206 -0.938257 --23.7896 -36.363 -947.057 0.311559 0.317451 0.895631 --26.1233 -16.9314 -1028.01 -0.578771 0.318399 -0.750763 --14.0759 2.97814 -1017.85 -0.692277 -0.259038 -0.673537 --12.9713 -15.0607 -1035.8 0.0439681 0.390653 -0.919488 --14.2709 -15.2666 -1035.9 -0.13673 0.301693 -0.94355 --16.042 -15.3377 -1035.35 0.00379096 0.0347244 -0.99939 --24.8233 24.7522 -956.768 -0.986464 -0.121986 -0.109583 --0.405996 -15.0875 -1035.6 0.292145 0.107782 -0.950281 -18.6559 49.5678 -959.321 0.943015 0.314003 0.110117 -9.72336 -15.5509 -1034.18 0.412535 -0.745027 -0.524165 -8.00944 -15.6457 -1034.78 0.176168 -0.600913 -0.779659 -21.4656 -17.5156 -1022.26 0.283514 0.597101 -0.750393 -5.7889 -15.6822 -1034.76 0.0869834 -0.119359 -0.989033 --8.83806 -15.6286 -1036.36 -0.180055 0.143611 -0.973117 -8.6486 38.4386 -979.063 0.345236 0.688837 -0.637429 --31.9083 -20.1037 -974.811 -0.842246 -0.109044 -0.52795 --15.6729 -39.0424 -981.386 0.795001 0.292022 -0.531692 -18.3839 49.2796 -958.444 0.769571 0.133166 0.624521 --9.87053 -15.5955 -1035.92 -0.28482 0.181854 -0.941173 --29.0424 -19.2132 -1025.58 -0.790441 0.224692 -0.569839 -14.8737 39.9413 -944.598 0.535854 0.41289 0.736466 -19.055 -17.4797 -1022.52 0.500746 0.428304 -0.752203 -1.56831 -16.3527 -1034.69 0.196398 0.320545 -0.926649 -0.760014 -16.1401 -1035.13 0.573156 0.149206 -0.805748 --19.5868 -17.8645 -1030.58 -0.387071 -0.182092 -0.903891 --27.847 -18.8918 -1026.92 -0.719204 0.300053 -0.626669 -4.22082 -16.5055 -1034.52 0.0350235 0.0588431 -0.997653 --19.8957 -18.1766 -1030.35 -0.335486 -0.453617 -0.825639 --25.5274 -18.4799 -1028.7 -0.328507 0.336955 -0.882352 --26.2867 -18.6048 -1028.34 -0.499513 0.508678 -0.701237 -6.29037 -16.4006 -1034.39 0.2122 -0.475077 -0.853975 --17.6943 -34.8691 -979.126 0.510026 0.853861 -0.103899 -2.77715 15.1223 -1006.73 -0.533265 0.585188 -0.610888 -3.28735 -16.5615 -1034.87 0.0845332 0.122047 -0.988918 --3.53905 -16.4402 -1036.04 0.154083 0.0484276 -0.98687 --26.5733 -22.6294 -1034.28 -0.447164 0.712669 -0.540507 --9.97986 -16.5119 -1036.11 -0.0859931 0.17887 -0.980107 --28.2063 28.4844 -959.351 -0.550492 0.636316 0.540427 --12.1843 -16.659 -1036.21 -0.00900695 0.162671 -0.986639 --24.144 -18.5264 -1029.03 -0.219667 -0.0298664 -0.975118 -22.2712 -18.8751 -1022.77 0.586799 0.440882 -0.679183 -17.0705 48.5064 -957.19 0.74002 0.391266 0.547066 -13.8546 -17.7058 -1028.42 0.487215 -0.106658 -0.866744 -11.4599 33.8322 -939.168 0.252575 0.796155 0.549857 --11.3877 -17.0242 -1036.35 -0.00500264 0.141236 -0.989963 --14.919 -17.0431 -1036.06 -0.445506 -0.132705 -0.885389 -21.5739 -19.0517 -1023.42 0.466947 0.57813 -0.669124 -18.283 -18.0438 -1023.67 0.868237 -0.113111 -0.483085 --6.89963 -17.1756 -1036.58 0.0832297 0.0409129 -0.99569 --23.5868 -19.1092 -1029.31 0.0427064 0.501599 -0.864045 -20.601 -18.81 -1023.62 0.148278 0.709831 -0.688588 -13.1829 -18.1253 -1028.75 0.400199 -0.00325623 -0.916422 --22.1575 -39.3438 -946.685 -0.523425 -0.515473 0.678465 -17.2408 47.3699 -953.948 0.77928 0.607643 0.153274 -0.496474 -17.3698 -1035.45 0.311902 0.0165806 -0.94997 --1.67961 -17.1598 -1035.9 0.119759 0.0189646 -0.992622 --2.26347 -17.1699 -1035.88 0.0769592 -0.049286 -0.995815 -16.8711 -44.6337 -960.101 -0.0430484 0.743135 0.667756 -14.958 41.2687 -945.659 0.738434 0.426344 0.522442 --13.3714 -17.4795 -1036.49 -0.0498179 0.100333 -0.993706 --24.0762 -23.146 -1034.32 0.538932 0.417795 -0.731437 --33.3608 -34.6432 -1002.34 -0.707753 0.0877072 0.700994 --5.23439 -17.1248 -1036.39 0.159426 -0.0130078 -0.987124 --15.1594 -2.95825 -1031.26 0.167073 0.554888 -0.814976 -13.8506 46.3671 -970.5 0.756307 0.273985 0.594081 -6.22368 -17.8764 -1033.58 0.525015 -0.395483 -0.753626 -4.74103 -17.6796 -1034.43 0.280952 -0.232242 -0.931198 -1.8368 -18.1402 -1035 0.132047 0.114954 -0.984555 --32.6242 -34.9991 -1002.02 -0.215384 0.0630978 0.974489 --8.65193 -17.7389 -1036.63 -0.188162 0.0730174 -0.97942 -8.23943 27.0751 -930.936 0.361222 0.546102 0.755838 -13.2308 47.1026 -973.567 0.376762 0.773721 -0.50932 --18.5055 -4.44028 -1030.6 -0.631777 -0.0815505 -0.770848 -16.2784 -27.2201 -1005.37 0.1143 0.78757 0.605532 -18.3514 50.2367 -959.796 0.778975 0.625602 0.0426498 --19.4348 -4.6161 -1027.29 -0.216244 0.613312 -0.759662 --13.3434 48.8773 -971.322 -0.37226 0.725107 -0.579346 -15.661 -7.53333 -954.866 0.104331 -0.305474 0.946467 -15.1823 42.9311 -947.777 0.798447 0.430291 0.421108 --14.1795 48.3427 -971.036 -0.779174 0.444509 -0.441927 --13.5239 48.3693 -972.45 -0.28643 0.934675 -0.210573 -11.0172 32.5303 -934.556 0.171272 0.921921 0.347458 --14.1884 48.0579 -971.799 -0.665462 0.742186 -0.0794996 --14.8769 46.843 -970.659 -0.754036 0.616951 -0.22539 --15.5999 46.4568 -970.343 -0.351797 0.837111 -0.418908 -17.8019 49.6992 -958.021 0.688098 0.533754 0.491556 --32.1067 -9.39292 -980.012 -0.940345 -0.157584 -0.301528 --4.23572 42.1034 -977.678 -0.0648144 0.47736 -0.876314 -0.526691 39.6767 -980.369 -0.528917 0.763611 -0.370331 --19.6083 47.053 -968.649 -0.260891 0.608104 -0.749763 --19.3773 46.5304 -969.72 -0.298351 0.817707 -0.492281 --20.1576 46.9162 -968.452 -0.470211 0.375518 -0.798679 -13.2495 46.8162 -970.061 0.727051 0.579507 0.368196 --16.3811 46.6995 -973.619 -0.740306 0.661881 0.117735 --6.2388 41.8284 -977.329 -0.37526 0.489034 -0.787417 -1.1375 39.2121 -982.163 -0.622053 0.642826 -0.447018 -16.4073 48.7451 -956.511 0.65623 0.723966 0.212686 --12.5863 -17.5449 -984.907 -0.481637 -0.860776 0.16459 --8.77037 51.6462 -971.348 -0.391412 -0.0667177 -0.917794 --20.6694 46.3946 -968.18 -0.849436 0.167784 -0.500307 -10.6118 31.4519 -932.253 0.219295 0.716097 0.662658 --13.5798 19.4552 -983.446 -0.624093 0.762037 -0.172651 --7.31267 41.2421 -976.966 -0.492169 0.585006 -0.644622 -17.7493 50.7622 -960.399 0.627601 0.778224 -0.0220194 --17.4956 45.1744 -972.016 -0.325116 0.760306 -0.562347 --25.3906 38.0109 -948.743 -0.903705 0.37486 0.206875 --15.8503 -20.9042 -965.436 0.867893 -0.484101 0.111387 --16.2987 46.3576 -975.603 -0.700784 0.536114 -0.47062 -16.3251 47.9968 -954.48 0.768397 0.607191 0.202199 --20.1256 45.7051 -970.69 -0.253233 0.887629 -0.384691 --17.0446 45.862 -974.099 -0.956568 0.290728 -0.0213377 --23.6636 44.7585 -964.344 -0.665284 0.702697 -0.252219 -0.223496 37.9026 -982.02 -0.827356 0.365128 -0.426806 --6.66409 40.8887 -978.115 -0.372137 0.89103 -0.25996 --17.115 44.5312 -973.021 -0.907588 0.335741 -0.252114 --19.0244 45.1347 -971.99 -0.116246 0.770738 -0.626458 -13.3065 47.7994 -971.098 0.53675 0.79217 0.290457 --16.622 44.1862 -975.509 -0.756394 -0.190509 -0.625759 --24.0632 44.6566 -963.372 -0.690914 0.196515 -0.695715 --7.63868 40.417 -977.708 -0.33109 0.909094 -0.252839 -1.03172 37.9462 -983.034 -0.609565 0.126935 -0.782507 --7.80876 40.6075 -977.24 -0.144584 0.814671 -0.561611 --25.1807 -22.6804 -1034.46 0.0900449 0.72668 -0.681049 -0.671927 14.7586 -1002.08 -0.224178 0.813132 -0.537178 --17.0395 44.6856 -974.884 -0.892855 0.0302492 -0.449328 --21.6679 44.4339 -967.601 -0.788762 0.582391 0.196664 --21.9023 44.1202 -967.253 -0.701032 0.601953 -0.382369 --29.4541 41.4711 -953.68 -0.988872 -0.0635553 -0.134509 --10.0542 41.0242 -976.792 -0.0371918 0.843293 -0.536166 --0.506047 20.9244 -990.235 0.18601 0.799108 -0.571687 -16.4596 48.6393 -955.21 0.799254 0.518545 0.303817 --23.0305 44.691 -969.594 -0.611378 0.755986 0.233886 --25.3649 43.0791 -962.643 -0.936138 0.0609389 -0.346312 --7.69451 12.2707 -1007.37 -0.589123 0.25157 -0.767884 --26.2909 40.8915 -957.191 -0.828888 0.232914 -0.508622 --20.5754 -34.572 -967.743 0.952509 -0.141822 -0.269467 --26.0514 36.1411 -949.542 -0.975207 0.210324 -0.0688108 -17.2139 -47.3557 -955.775 -0.00529151 0.667807 0.744315 --25.4403 42.2964 -962.146 -0.882671 0.447248 0.144437 --19.1241 42.8346 -973.626 0.162228 0.0858318 -0.983013 --27.4964 -9.58194 -999.626 -0.46506 -0.161401 0.870442 --29.5958 42.3162 -952.175 -0.996211 -0.0823638 -0.0279152 -12.3236 -45.6262 -960.67 -0.45422 0.802718 0.38643 -17.3063 50.6428 -958.977 0.636096 0.722567 0.270702 --25.6532 41.3889 -960.926 -0.976478 -0.212898 -0.0341504 --26.2349 35.1149 -948.646 -0.973354 0.146903 0.176071 --9.08077 39.7568 -979.826 -0.66126 0.728911 -0.177266 --19.2986 -36.9468 -963.759 0.92878 0.00237448 -0.370625 --12.6299 40.7811 -976.063 -0.553452 0.152102 -0.818875 --25.8192 40.5302 -959.318 -0.939206 0.312402 -0.142463 --12.4589 40.36 -976.641 -0.607225 0.617746 -0.499668 --25.8937 42.0102 -962.846 -0.497884 0.851195 0.166069 --27.9256 39.5322 -955.582 -0.887078 0.430318 -0.167088 --23.1063 44.3384 -971.776 -0.373746 0.750634 -0.544851 --23.6445 42.6684 -968.717 -0.909388 0.333764 0.248225 --7.72841 12.2198 -1007.36 -0.158456 0.613484 -0.773646 --26.4199 48.2117 -955.718 -0.88994 0.357572 0.283106 --14.9041 39.9355 -973.937 -0.599714 0.266353 -0.754585 --10.5292 24.386 -931.587 -0.0126092 -0.963197 0.268502 --18.3483 -30.7809 -952.404 0.310089 0.837471 0.449985 --9.35498 39.1245 -980.509 -0.587425 0.609606 -0.53227 --12.5804 39.8477 -977.675 -0.54481 0.811433 -0.211564 --24.9876 50.3348 -965.507 -0.900656 0.0274076 -0.433667 --9.3896 0.732588 -1024.31 -0.820822 0.280769 -0.497414 --24.7208 -23.5185 -1034.86 0.267362 0.227767 -0.93629 --24.052 -41.499 -985.319 -0.0111302 -0.0569262 -0.998316 --28.1851 38.3839 -954.412 -0.818006 0.28328 0.500619 --23.5846 -40.7764 -985.205 0.0513099 0.232522 -0.971237 --13.8858 -1.48352 -1027.76 0.00574199 0.997246 0.0739483 --26.5941 39.6309 -960.652 -0.475599 0.362342 0.801569 --26.3803 33.6648 -949.487 -0.995958 0.0348027 -0.0827992 --14.2338 39.4952 -974.859 -0.675874 0.419732 -0.605821 --24.1873 41.9729 -968.532 -0.664068 0.637536 -0.390591 --24.278 -29.2986 -1005.47 -0.0738006 0.653975 0.752908 --26.6017 39.2046 -959.765 -0.894437 0.41453 -0.16777 --28.2644 45.3501 -961.735 -0.590604 -0.178777 -0.786909 --26.1382 48.8199 -956.257 -0.701131 0.712904 -0.0134951 --21.3073 -16.7902 -978.9 0.00349519 -0.562591 -0.826728 --13.5639 39.148 -976.365 -0.717277 0.62317 -0.311725 -16.2581 51.6173 -961.906 0.531453 0.760844 -0.372391 --23.7013 43.2935 -972.491 -0.474567 0.327047 -0.817206 --24.0096 43.1307 -972.234 -0.790328 -0.254045 -0.557533 -16.717 51.0525 -958.185 0.511283 0.607082 0.608311 --25.1498 -49.8938 -951.077 -0.243844 -0.206471 0.947581 --23.9568 42.2913 -970.826 -0.987847 -0.113208 -0.106498 --26.4048 41.7059 -965.723 -0.657665 0.707272 -0.259313 --20.6848 -35.6288 -946.323 0.149695 0.118355 0.981623 --8.99239 38.5823 -982.131 -0.725997 0.201701 -0.657454 --28.0016 38.5468 -958.068 -0.753572 0.511514 -0.412895 -9.04511 33.5695 -937.196 0.205008 0.862464 0.462739 -2.07407 31.8372 -985.071 -0.260802 0.897388 -0.355917 -9.14694 33.1654 -936.217 0.139787 0.943233 0.301284 -26.3502 -45.9081 -968.687 0.963064 0.262817 -0.0586181 --14.0532 38.5212 -976.596 -0.646479 0.762728 0.0176461 --33.1837 -33.7576 -1002.44 -0.436441 0.199144 0.877417 --24.8754 -35.3981 -946.885 0.204809 0.2772 0.93873 -12.2103 47.439 -969.565 0.493674 0.869457 0.0181516 --29.7208 37.7894 -955.278 -0.569631 0.746172 0.344598 --27.1862 38.0347 -959.591 -0.825319 0.246162 -0.508186 --15.9971 38.7004 -974.082 -0.344797 0.643806 -0.683102 --26.8091 40.8512 -966.709 -0.661767 0.622553 -0.417724 --29.1512 37.8284 -956.806 -0.663159 0.645672 -0.378587 --27.1276 37.6117 -960.326 -0.971333 0.0642568 0.228875 --14.5889 38.5234 -978.055 -0.541056 0.837871 0.0723204 --26.8295 40.5303 -967.845 -0.733389 0.568397 -0.372915 --30.6301 37.0984 -955.628 -0.78733 0.613705 0.0589771 -27.0885 -48.7156 -960.692 0.989911 0.0451789 0.134292 --15.1687 37.5686 -975.639 -0.39972 0.748065 -0.529738 -16.5315 51.5455 -960.192 0.645864 0.762502 0.0380822 --14.6368 38.3871 -979.868 -0.534877 0.820879 -0.200158 --18.3471 38.0193 -974.336 -0.317138 0.742374 -0.590173 --26.5375 40.1295 -968.527 -0.460776 0.293402 -0.837616 --30.0826 35.1098 -954.541 -0.951297 -0.146296 0.271352 --26.0211 30.8375 -951.602 -0.990487 -0.136678 -0.0159625 --29.3289 36.6261 -957.746 -0.588633 0.463725 -0.662171 --29.4725 39.0638 -962.424 -0.882313 0.227848 0.411836 --28.0761 36.1589 -959.547 -0.626295 0.140517 -0.766818 --30.5896 36.7737 -956.804 -0.670423 0.589135 -0.451057 --3.35553 32.3271 -983.383 -0.192319 0.850405 -0.489719 --8.54356 31.4986 -929.96 0.0335783 -0.610075 0.791632 --0.876978 -35.1003 -1007.77 0.119796 -0.957654 0.261815 -16.133 47.6737 -945.61 0.627205 0.741494 0.238331 --28.6826 35.7403 -959.024 -0.764458 0.292976 -0.574256 --2.59577 32.2265 -985.472 0.121546 0.951914 -0.281223 --4.65082 32.6568 -982.256 -0.332321 0.653225 -0.680337 --14.908 37.9432 -980.595 -0.568985 0.699318 -0.432678 --28.2892 29.5144 -969.166 -0.867049 0.409853 0.283277 --16.006 37.3687 -978.511 -0.782285 0.621837 0.0367318 -3.97959 -17.0764 -955.772 0.273895 -0.955874 0.106237 --21.0306 35.9737 -969.044 -0.61384 0.498666 -0.61199 --27.6837 38.9444 -968.014 -0.78405 0.381395 -0.489698 --4.95003 32.0187 -982.683 -0.326815 0.806462 -0.492758 --29.0992 31.7167 -955.745 -0.73347 -0.677819 0.0508343 --30.4455 35.8234 -957.683 -0.627587 0.258533 -0.734367 --30.9143 35.6423 -957.059 -0.97637 0.125168 -0.176168 --16.1047 36.5738 -977.349 -0.761031 0.607821 -0.226682 --20.0118 36.9828 -973.19 -0.966241 0.257617 0.00344939 --20.2182 36.0642 -971.198 -0.949477 0.0125785 -0.313586 --30.4145 -51.5133 -955.81 -0.389929 -0.901771 -0.186451 -15.6825 49.479 -954.809 0.731971 0.669326 0.127361 --21.941 44.6202 -972.267 -0.152696 0.741131 -0.653765 -13.3084 -44.9692 -960.975 -0.374001 0.682554 0.627887 --27.7831 38.4171 -967.997 -0.607655 -0.0870189 -0.78942 --17.423 36.0711 -977.038 -0.217991 0.726375 -0.651812 --20.1429 36.8189 -974.582 -0.652668 0.738597 -0.168818 --19.9146 35.4022 -971.735 -0.895638 0.168479 -0.411639 --14.1994 -18.1406 -964.724 0.552209 -0.581499 0.597431 -26.5808 -48.964 -959.055 0.812048 0.241857 0.531115 -5.29532 40.2566 -979.143 0.275554 0.885097 -0.375065 -11.6924 48.305 -971.15 0.130406 0.957661 0.25667 -14.7431 51.4618 -965.284 0.954168 0.250129 -0.164313 --19.836 35.3424 -972.295 -0.95826 0.18439 0.218491 --22.2767 35.6454 -968.978 -0.42948 0.702022 -0.568078 -10.1633 -43.8059 -966.257 -0.961099 0.275504 0.0196737 --16.0941 36.5706 -979.657 -0.803986 0.51541 -0.29658 --19.693 36.4936 -975.899 -0.269533 0.805711 -0.527429 --20.5569 35.7283 -973.389 -0.626151 0.38868 0.675916 --32.257 -10.4294 -974.205 -0.906493 -0.380833 -0.182309 --20.9682 35.1492 -970.404 -0.571696 0.575503 -0.584773 --28.1274 33.7507 -959.535 -0.681984 -0.0971155 -0.724891 -13.5132 6.78282 -1003.36 0.863816 0.435669 -0.253012 -26.2595 -48.3716 -966.024 0.411064 -0.857822 -0.308493 -15.1723 47.0307 -948.621 0.750786 0.557748 0.353889 -26.473 -46.4688 -965.318 0.946081 0.323621 0.0141597 --21.8748 34.7905 -970.472 -0.278852 0.705427 -0.651625 --5.64961 32.0315 -986.642 -0.128064 0.98507 -0.115054 -11.618 -33.1187 -1000.97 -0.781968 0.507447 0.361973 -8.22672 32.348 -933.158 0.0853089 0.9322 0.351746 -15.8745 52.1403 -961.188 0.48968 0.865602 -0.104628 --23.82 -29.9923 -1004.94 -0.0659235 0.708752 0.702371 --15.5667 35.6627 -981.057 -0.610577 0.041483 -0.79087 --22.8322 -30.9236 -1003.81 0.00577433 0.828628 0.559769 --28.3691 -19.9481 -958.404 -0.651678 0.115478 0.749654 --16.7319 35.2047 -978.199 -0.962687 0.165231 -0.214319 --22.8471 -14.7178 -998.84 -0.798396 -0.14054 0.585501 -16.3611 51.6151 -958.72 0.581403 0.786717 0.207479 --22.1122 54.5147 -961.143 -0.289583 0.106073 -0.951257 --17.0184 34.8555 -977.952 -0.493209 0.131677 -0.859887 --20.7381 34.4511 -971.122 -0.52906 0.565457 -0.632735 --25.8612 27.7456 -953.944 -0.992032 -0.00881689 -0.125678 --25.3957 -40.6523 -985.09 -0.166566 0.17586 -0.970221 --26.7093 32.2337 -960.728 -0.931217 0.20917 -0.298469 --25.9327 27.1097 -952.48 -0.993069 -0.00926966 0.117168 -13.5761 43.3182 -941.769 0.875788 0.332411 0.349999 --22.363 -16.4214 -999.758 -0.818744 -0.44414 0.363865 --12.3719 -10.5485 -1033.5 -0.631655 0.226846 -0.741318 --23.8345 34.3888 -968.293 -0.478607 0.216091 -0.851023 --15.1125 34.9271 -981.662 -0.548752 -0.105296 -0.829328 --24.2031 34.0666 -968.236 -0.771658 0.361637 -0.523224 --22.5476 -16.4841 -1000.23 -0.638659 -0.55479 0.53322 --25.3791 27.6623 -955.647 -0.990331 -0.0794959 -0.113687 --7.33719 31.5961 -985.731 -0.449505 0.891463 0.0569162 --7.49952 30.8188 -984.563 -0.619533 0.775101 0.124085 --25.8384 26.6939 -953.682 -0.973478 -0.0476278 -0.223768 --7.52805 31.3943 -986.939 -0.526593 0.687176 -0.500488 --18.0071 -14.2191 -957.528 -0.430512 -0.78634 0.44309 --32.3363 -10.4512 -972.513 -0.947284 -0.316621 0.0490332 --27.186 30.4984 -958.937 -0.990851 0.0674989 0.116869 --7.72022 31.3849 -986.369 -0.791257 0.610551 0.0337635 --21.827 33.0202 -972.051 -0.459029 0.765222 -0.451362 --23.2859 33.7155 -970.842 -0.475409 0.702296 -0.529874 --25.2567 32.5305 -965.955 -0.939677 -0.263918 -0.217612 --25.1522 26.3379 -955.6 -0.965648 -0.084779 -0.245634 --4.88793 -17.8486 -946.375 -0.859051 -0.495343 -0.129095 --11.1379 31.1674 -983.059 -0.264376 0.835421 -0.481847 --8.83084 29.5064 -985.333 -0.15804 0.68991 -0.706433 --22.7767 34.7259 -975.333 -0.813174 0.572291 0.105975 -2.95464 24.2283 -988.825 -0.50579 0.821396 -0.263601 --7.4404 49.79 -971.768 -0.340037 0.166472 -0.92556 --25.8534 25.1383 -953.183 -0.994873 -0.0980648 -0.0247102 -20.3118 -46.4167 -956.953 -0.408785 0.786502 0.462935 --25.1209 -26.0221 -1009.19 -0.0413173 0.843334 0.5358 --23.0707 32.8464 -971.932 -0.418087 0.607738 -0.675173 --24.8381 31.3173 -966.184 -0.985709 -0.0766352 -0.150015 --25.1005 30.6691 -965.269 -0.850455 0.26076 -0.456869 -16.7319 -14.4601 -980.092 0.409589 -0.520068 -0.749511 --24.3702 46.8035 -963.953 -0.81716 -0.447988 -0.362707 --8.19029 30.251 -987.007 -0.893774 0.32837 -0.305517 --11.8832 30.9383 -982.729 -0.58969 0.720436 -0.365018 --25.2521 50.3116 -963.943 -0.964996 0.245453 0.0923883 --8.06146 37.5553 -982.775 -0.422104 -0.285347 -0.860468 --25.0218 32.3842 -968.193 -0.995483 -0.0535057 0.0784305 --27.6544 30.6045 -961.976 -0.878901 0.466666 -0.0987748 --27.9298 -24.9252 -1032.41 -0.973895 0.12091 -0.192116 --22.0869 35.2112 -977.674 -0.311286 0.716698 -0.624056 --21.6166 -25.2991 -974.451 0.12731 -0.385056 -0.91407 --30.1411 -25.7455 -970.933 -0.580468 -0.595146 -0.55575 --12.9884 30.2154 -982.059 -0.779101 0.582713 -0.231187 --24.6211 32.6485 -970.789 -0.719706 0.636858 -0.276468 -15.3136 51.6487 -957.954 0.304008 0.665239 0.681935 --28.0755 29.3931 -960.273 -0.761347 0.574101 0.301262 -14.5387 50.224 -956.865 0.491387 0.714798 0.497597 --2.60603 -17.8451 -952.203 -0.439092 -0.890106 -0.122105 --31.1761 -12.2945 -974.215 -0.994673 -0.0634579 0.0812344 --25.5319 23.2879 -953.199 -0.969814 -0.233813 0.0692207 --8.11049 29.5172 -987.439 -0.720533 0.224958 -0.655917 --23.333 32.6052 -974.33 -0.945772 0.309933 0.0972494 -6.88184 33.842 -937.213 0.0824167 0.870135 0.485873 --13.188 29.8853 -981.779 -0.974929 0.217048 -0.0490229 --22.4585 34.524 -977.94 -0.607188 0.483059 -0.630853 --23.386 31.8592 -972.368 -0.587775 0.536621 -0.605441 --25.514 23.7953 -954.468 -0.963555 -0.157687 -0.216094 -14.4501 52.209 -964.036 0.657011 0.732714 -0.177388 --28.8466 -24.722 -1029.57 -0.93774 -0.0309077 -0.34596 --28.1484 29.3705 -961.291 -0.787198 0.59687 -0.155131 --15.1268 -39.7165 -980.614 0.970634 0.0848297 -0.225108 --12.2647 30.0031 -984.563 -0.360053 0.866565 -0.345581 -23.4234 -9.16963 -980.202 0.374298 -0.139637 -0.916735 --24.6008 32.0941 -971.68 -0.556377 0.606966 -0.567482 -14.3342 48.1364 -948.209 0.876441 0.480337 -0.0335775 --13.4384 29.4618 -982.465 -0.81637 0.482039 0.318085 --24.3189 -42.3216 -985.112 -0.0823341 -0.567064 -0.819548 --23.2681 33.2075 -977.426 -0.831526 -0.149974 -0.534857 --23.4749 33.2623 -976.542 -0.993383 0.0761157 -0.086006 -12.8977 43.0522 -940.078 0.909313 0.36013 0.208461 --26.927 29.255 -965 -0.661799 0.348743 -0.663627 -3.66363 40.4624 -980.414 0.0435527 0.979309 -0.197626 -26.0373 -10.6508 -978.146 0.881845 -0.153469 -0.445867 -9.76847 -48.6367 -964.794 -0.533306 -0.807027 -0.25356 -20.3077 -2.84863 -1020.88 0.506765 0.594895 -0.623931 --27.1135 21.4083 -960.17 0.0558624 -0.813187 0.579315 --13.4923 29.5148 -983.006 -0.654233 0.756079 0.0179868 --25.6525 31.3479 -970.962 -0.544684 0.736398 -0.401294 --13.305 29.6963 -984.37 -0.369808 0.922664 -0.109241 --22.2537 -15.0293 -996.181 -0.971364 -0.213325 0.104618 --26.0649 28.5559 -965.77 -0.974068 0.0592744 -0.218352 -2.10514 22.185 -989.819 -0.767176 0.471904 -0.434451 --28.132 28.6417 -963.816 -0.807234 0.459438 -0.370526 -2.17429 21.5667 -990.29 -0.65954 0.547718 -0.514793 --21.2557 52.3959 -966.052 -0.140129 0.861179 -0.488605 -2.91291 21.8276 -991.265 -0.645831 0.512301 -0.566083 --29.9504 27.9138 -961.296 -0.778797 0.627078 -0.0157293 --25.6007 30.7409 -971.83 -0.474108 0.615513 -0.629576 -14.7457 52.0242 -962.491 0.674791 0.703248 -0.22383 --27.4231 31.1279 -970.261 -0.498002 0.862614 -0.0888284 --27.737 30.7214 -969.08 -0.732232 0.636518 0.24224 --30.0572 27.4171 -959.797 -0.710143 0.572727 0.409488 --1.86817 25.6472 -931.725 -0.184802 -0.866602 0.463517 --27.279 30.9229 -971.036 -0.287342 0.802564 -0.522806 --27.4857 30.1598 -967.973 -0.489847 0.629895 0.602729 -1.26799 21.2076 -990.045 -0.29141 0.817215 -0.497233 --24.4584 49.3063 -966.534 -0.758271 -0.00552413 -0.651917 --28.7369 27.418 -963.691 -0.762419 0.443365 -0.471322 --4.47024 23.8143 -988.038 -0.11907 0.851544 -0.510583 --14.8687 28.5099 -983.427 -0.733304 0.636995 0.237704 --21.4271 -34.0087 -946.588 -0.283536 0.354848 0.890893 --17.8138 28.3428 -978.492 -0.370301 0.655775 -0.657903 --26.0203 21.0637 -960.892 -0.0427805 -0.812273 0.581706 --30.0449 27.5547 -962.076 -0.646895 0.669609 -0.364898 --14.7749 28.9019 -984.924 -0.55676 0.830597 -0.0112811 --28.0104 30.3866 -971.28 -0.696524 0.677162 -0.237289 -1.14395 25.2153 -939.141 -0.0575048 -0.926343 -0.372266 --28.0938 27.4415 -964.828 -0.471313 0.354316 -0.807666 -1.95858 16.265 -1002.08 -0.533442 0.44407 -0.71989 --18.5013 28.0384 -978.146 -0.50402 0.0414607 -0.862696 --26.8456 26.5307 -965.608 -0.43293 0.265005 -0.861594 -1.235 20.5211 -991.716 -0.315161 0.904656 -0.286829 -6.15604 33.6099 -936.587 0.0911493 0.92717 0.363382 --14.9253 27.5518 -982.307 -0.705504 0.652941 0.275558 --7.29489 33.4259 -980.674 -0.227077 0.33386 -0.914862 --11.0326 40.626 -977.265 -0.233043 0.838514 -0.49253 --28.166 29.0395 -967.85 -0.839052 0.408164 0.359713 -3.51046 21.1083 -995.167 -0.410782 0.871793 -0.266898 --14.6782 28.6593 -986.272 -0.437477 0.774644 -0.456662 --15.3535 27.9406 -984.037 -0.884743 0.409649 0.222301 --15.2178 27.3123 -981.849 -0.33707 0.873635 -0.35092 --18.426 27.6244 -978.285 -0.831002 0.349717 -0.43259 --28.6179 26.8195 -964.882 -0.742334 0.334965 -0.580292 -14.3291 52.5652 -961.323 0.355086 0.919825 -0.166842 --28.4326 -23.8032 -1030.33 -0.911771 0.183057 -0.367645 -14.2195 52.6968 -958.896 0.902356 0.429212 -0.0391213 --20.1809 26.3076 -974.097 -0.770395 -0.271531 -0.576855 --30.4375 26.873 -962.396 -0.892527 0.373791 -0.25234 --5.52998 23.3915 -988.178 -0.651077 0.664347 -0.367071 --28.6643 29.6097 -971.339 -0.691461 0.21018 -0.691163 -3.37263 20.8635 -995.526 -0.534032 0.695053 -0.481364 --15.6271 28.2565 -985.561 -0.813383 0.561806 -0.150936 --19.4664 26.1403 -975.69 -0.952109 0.113845 -0.283775 --26.4509 29.2374 -972.563 -0.537862 0.542711 -0.645112 -2.51255 25.3332 -929.57 0.229464 -0.0897287 0.969172 -16.9288 26.9052 -968.931 0.799804 -0.530826 -0.280247 -13.4118 52.4599 -965.297 0.555505 0.79496 -0.243831 --30.495 26.182 -961.846 -0.956691 0.270042 -0.108713 --15.8038 26.8344 -982.383 -0.245478 0.680351 -0.690553 --20.0718 25.6229 -974.109 -0.843397 0.102024 -0.527515 -14.1527 52.0404 -957.985 0.524175 0.444699 0.72628 --29.0378 25.9945 -963.884 -0.877508 0.195763 -0.437785 -2.27883 20.468 -994.161 -0.552542 0.788881 -0.269006 --15.6638 27.8375 -985.782 -0.975387 0.0745617 -0.207512 --17.6418 26.901 -981.345 -0.401525 0.788906 -0.465194 --18.1793 27.0953 -980.051 -0.686221 0.674765 -0.271648 --6.9622 35.0634 -981.379 -0.32393 -0.530367 -0.783441 -3.89111 20.2692 -996.488 -0.417612 0.585369 -0.694941 --18.663 26.8953 -978.797 -0.784646 0.600941 -0.15232 -12.5484 43.1532 -936.6 0.774639 0.115596 0.621749 --29.0909 28.5772 -969.695 -0.954138 0.0504113 0.295092 --28.6256 27.6281 -969.111 -0.966841 0.216113 0.136064 --31.1209 25.6995 -960.708 -0.95736 0.282359 0.0611121 --30.5301 25.6354 -962.871 -0.691737 0.107002 -0.714179 -13.7728 52.7211 -960.533 0.530955 0.82312 -0.201395 --30.7797 25.5072 -962.481 -0.953037 0.100845 -0.285569 -13.97 52.8283 -959.586 0.488425 0.86829 -0.0866778 --20.4004 24.8948 -974.1 -0.658788 0.719656 -0.219302 --20.5829 24.9529 -973.605 -0.594541 0.5049 -0.625777 -2.76531 19.8226 -996.062 -0.559591 0.619616 -0.550395 -13.0644 45.9964 -943.007 0.826645 0.344736 0.444765 --19.551 25.7023 -977.592 -0.762197 0.616158 0.198508 --23.109 -32.8354 -948.23 -0.0672182 0.744315 0.664437 --15.0031 38.9732 -933.933 -0.614196 -0.0464301 0.787786 --29.0893 28.6297 -970.851 -0.931248 -0.13307 -0.339218 -12.6757 52.3076 -966.905 0.569425 0.726922 -0.383848 --26.888 -8.17754 -983.08 -0.190098 -0.156384 -0.96923 --29.2172 24.783 -964.783 -0.946228 0.165317 -0.278071 --20.0347 -33.6506 -976.424 0.375763 0.915054 -0.146556 --21.4389 24.8476 -973.405 -0.1256 0.709493 -0.693429 --28.9183 24.7692 -965.18 -0.593516 0.0207445 -0.804555 --5.71604 21.9292 -990.333 -0.722647 0.485957 -0.491556 -13.5147 51.0222 -955.95 0.867254 0.496553 -0.0361278 --20.1827 24.8242 -976.698 -0.664796 0.725926 0.176287 -13.7545 51.1898 -954.837 0.842177 0.535005 -0.0671441 --30.2798 -50.2919 -959.934 -0.375433 -0.89772 -0.230539 -22.9935 -35.2773 -971.592 0.915928 -0.294952 -0.272175 --27.912 27.4341 -972.027 -0.781287 0.216767 -0.585323 --21.2477 24.078 -976.061 -0.514 0.856209 -0.0520651 --15.5328 -7.9491 -1030.39 -0.536218 -0.412495 -0.736423 --4.20894 20.6629 -991.508 -0.266701 0.673728 -0.689174 --19.3845 25.5841 -982.1 -0.150321 0.878551 -0.453377 --21.4707 25.3137 -978.238 -0.454486 0.751474 0.478257 --19.7581 -13.405 -958.093 -0.461585 -0.398044 0.79278 -3.35701 18.7118 -999.887 -0.271488 0.94018 -0.205806 --24.3422 29.3346 -946.192 -0.874853 -0.256707 0.410773 --12.5375 23.4859 -988.332 -0.254178 0.952836 0.165821 --30.8112 -49.7998 -959.937 -0.974929 -0.165625 0.148597 --29.8807 -24.0314 -1026.43 -0.947063 0.0789641 -0.311185 --23.7604 24.0551 -974.194 -0.295037 0.82501 -0.481987 --12.3177 21.1086 -984.332 -0.52809 0.754477 0.389724 --20.1413 -33.6162 -970.793 0.705198 -0.677405 0.209327 --20.8146 -36.0761 -969.341 0.969237 0.211275 0.126267 --22.3486 24.9626 -978.526 -0.560254 0.709641 0.42723 --3.75474 20.3464 -994.699 -0.0756471 0.948927 -0.306291 --6.77459 19.8566 -990.27 -0.426797 0.896939 -0.115516 -12.0859 45.1737 -940.303 0.790672 0.584717 0.181503 -12.2528 -16.5365 -960.985 -0.217839 -0.500253 0.838029 -12.2039 44.4571 -937.08 0.669747 0.552694 0.495952 --26.7224 21.3017 -966.182 -0.718231 0.627322 -0.301018 --0.608519 42.6244 -975.749 0.251648 0.221922 -0.942032 --4.86188 20.3792 -994.064 -0.190479 0.977812 -0.0871817 --12.8446 22.7725 -987.273 -0.547553 0.57202 0.610719 --31.0687 -12.054 -980.11 -0.803006 -0.308042 -0.510188 --22.0602 25.497 -981.543 -0.605598 0.739417 -0.294133 -13.2364 53.1345 -963.549 0.471998 0.864463 -0.172979 -13.3918 53.1773 -962.107 0.540949 0.837755 -0.0744398 --14.1723 -18.1657 -966.289 0.714183 -0.648446 -0.263551 --27.5692 -14.6703 -959.231 -0.619627 0.280844 0.732932 --22.6543 25.2817 -980.363 -0.701437 0.703983 -0.111329 --28.9817 -39.4162 -958.27 -0.696903 -0.716986 -0.0160308 --23.0548 24.7345 -979.524 -0.831036 0.53944 0.13559 --6.02 36.5202 -982.752 -0.059106 -0.433083 -0.899414 -3.14003 18.0798 -1001.55 -0.284339 0.7756 -0.563556 -11.5828 43.1015 -935.753 0.543197 0.294835 0.786135 --22.4898 23.3716 -977.297 -0.654856 0.649568 0.386297 --23.4206 51.9078 -966.918 -0.174461 0.538876 -0.824122 -14.7012 48.7957 -946.574 0.794154 0.547867 -0.262985 -12.5344 53.1533 -964.208 0.30747 0.947635 -0.0863163 --23.3589 -34.8408 -947.956 0.18468 0.113908 0.976175 --16.1808 -39.7416 -982.256 0.54149 0.150073 -0.827205 --5.63787 19.9341 -994.861 -0.258317 0.906352 -0.334364 --13.2441 20.7318 -986.509 -0.63216 0.714765 0.299142 --31.8723 -47.995 -966.656 -0.520338 -0.847913 -0.101445 --19.3773 -41.9658 -984.642 0.298575 -0.173273 -0.938525 --23.2549 23.8482 -978.554 -0.852165 0.400621 0.336629 -4.98559 33.0026 -934.277 0.177653 0.902432 0.392499 -5.25264 32.5609 -933.389 0.369078 0.916775 0.152659 -2.49181 17.9967 -1000.92 -0.562977 0.771173 -0.297237 --13.7341 22.2778 -987.839 -0.748161 0.4322 0.503447 --18.6659 -41.2897 -984.336 0.404143 0.156384 -0.901228 --31.9909 -47.778 -966.162 -0.896169 -0.415051 0.156886 --23.0248 22.8542 -977.564 -0.734536 0.677432 0.0392734 --29.891 -32.8363 -950.216 -0.435433 0.801162 0.410533 --22.3493 24.4658 -982.46 -0.723328 0.363565 -0.587041 --24.3836 22.7345 -976.285 -0.53785 0.729232 -0.423011 --26.0621 22.7596 -972.98 -0.537362 0.808171 0.241044 --27.8199 19.2392 -963.966 -0.578931 0.669679 0.465155 -1.4348 17.5302 -999.675 -0.433796 0.835514 -0.337249 --4.74495 19.4897 -996.033 -0.149878 0.804104 -0.575285 -12.8573 -43.0664 -962.576 -0.447702 0.380226 0.809316 --26.5627 20.307 -969.001 -0.688822 0.717655 -0.102449 --14.2884 22.0412 -989.001 -0.833978 0.550068 -0.0436551 --13.9496 20.109 -984.719 -0.560933 0.734545 0.381836 --13.589 19.524 -983.973 -0.598683 0.696798 0.395034 --22.9488 23.911 -980.492 -0.891284 0.313059 -0.328035 --25.7095 22.4207 -974.78 -0.498751 0.777376 -0.38332 --22.8803 24.0899 -981.649 -0.909547 0.226761 -0.348286 -19.5915 22.6652 -970.654 0.394408 0.503558 -0.768682 -4.81974 32.6758 -933.03 0.515866 0.843488 -0.149697 --26.6818 22.4207 -973.71 -0.43228 0.887417 -0.160079 --27.3925 19.6742 -968.637 -0.65285 0.663361 -0.365705 -1.37205 16.7664 -1001.05 -0.576413 0.656965 -0.485948 --23.6876 22.9682 -980.002 -0.912906 0.306153 -0.26995 --15.8738 -11.582 -1028.58 -0.629983 0.487295 -0.604702 -18.8431 -40.2174 -975.993 0.0314754 0.220498 -0.974879 --29.0254 18.5274 -965.01 -0.727634 0.661037 0.183245 -7.33569 22.9325 -983.32 0.467179 -0.0165311 -0.884008 --6.58625 18.8861 -996.098 -0.239709 0.708284 -0.663983 --25.249 21.6217 -976.661 -0.581544 0.552199 -0.597396 -7.56157 48.2879 -973.347 0.389684 0.850311 -0.353719 --24.6059 18.1273 -962.425 0.047541 0.434926 0.89921 --27.6687 21.8136 -972.882 -0.630881 0.76735 0.114732 --27.7118 20.8596 -971.17 -0.636332 0.634101 0.439314 -12.2967 53.5864 -965.684 0.565638 0.816529 -0.115473 --27.3498 19.3762 -969.436 -0.805165 0.575051 0.144998 --31.3087 -8.88967 -965.71 -0.893192 -0.448049 0.0382265 --29.3459 17.6957 -963.028 -0.494811 0.67818 0.543354 -3.32556 15.9573 -1003.13 -0.432126 0.473846 -0.767292 --25.8434 21.6026 -975.819 -0.408921 0.689112 -0.598254 -3.28568 16.1945 -1004.64 -0.257193 0.965149 0.0483697 --25.5148 -32.2772 -974.767 0.321904 0.86645 -0.381631 --15.0637 19.5478 -985.731 -0.617778 0.781398 0.0881293 --27.5751 -21.8468 -1030.41 -0.782353 0.39204 -0.483972 --29.8349 17.94 -964.261 -0.585768 0.782828 0.209897 -24.404 -20.6812 -1019.84 0.935751 0.00706172 -0.352592 --3.76426 17.8831 -998.064 0.00798175 0.904351 -0.426715 --18.2623 54.7094 -960.863 -0.514438 0.26763 -0.814695 --11.7829 19.9134 -991.635 -0.170786 0.965117 0.198445 --23.2292 22.2164 -981.307 -0.868582 0.22068 -0.443696 --24.6346 20.9019 -977.491 -0.604527 0.264246 -0.751479 --12.0636 19.7509 -991.295 -0.61526 0.776771 0.134473 --22.5706 21.8901 -982.282 -0.754664 -0.0447246 -0.654585 --23.7246 21.7319 -980.771 -0.909155 -0.0230151 -0.415821 --27.8087 21.4082 -975.19 -0.549159 0.765782 -0.334667 --26.7881 12.8165 -959.21 -0.636374 0.69276 0.339281 --4.59745 17.8825 -997.868 -0.200845 0.932472 -0.300263 --23.1501 21.4508 -981.572 -0.686362 -0.373006 -0.624318 --28.0626 19.9826 -970.627 -0.693828 0.446515 0.565002 --29.3082 18.7903 -967.445 -0.760878 0.629806 -0.156236 -2.58353 15.8206 -1004.69 -0.717763 0.685671 -0.121128 --15.0582 -17.583 -970.063 0.581062 -0.813833 0.00658278 -2.59455 15.3402 -1002.86 -0.618157 0.692704 -0.371542 -5.10722 33.4612 -931.119 0.647507 0.743723 -0.166164 --4.29222 17.7151 -999.173 -0.0877249 0.963295 -0.253705 --12.6861 20.4595 -993.235 -0.263991 0.879622 0.395694 --15.5485 17.8516 -983.779 -0.666607 0.719154 0.196095 --28.0031 18.1112 -970.011 -0.926602 0.262243 0.269512 --12.5012 19.1828 -990.977 -0.765283 0.598393 -0.237208 --28.448 20.9553 -973.451 -0.76979 0.600424 0.216597 --17.8687 -30.1592 -970.764 0.947381 -0.235134 -0.217214 --29.55 17.9095 -968.386 -0.688731 0.499608 -0.525396 -11.0672 45.8282 -938.007 0.609134 0.760277 0.225685 -15.1116 -20.979 -1004.79 0.317072 -0.845239 0.430159 --28.3893 20.8365 -975.184 -0.706921 0.429524 -0.561935 --30.2268 16.9155 -963.402 -0.660516 0.403322 0.633285 --27.1225 -34.2001 -947.779 -0.679452 0.288523 0.674611 -19.0636 30.6352 -960.761 0.763078 -0.154272 0.627624 --29.8493 17.6022 -968.115 -0.896689 0.342725 -0.280157 --29.7634 17.7915 -966.599 -0.840459 0.538492 -0.0604465 --16.3229 17.2114 -983.483 -0.59036 0.770618 -0.240049 --17.6882 -30.5549 -968.049 0.890987 -0.4029 -0.209315 --28.6698 18.8678 -970.94 -0.933222 0.193065 0.303022 -13.6933 53.2606 -954.351 0.958183 -0.182092 0.220744 --13.7789 20.3774 -994.336 -0.740073 0.635381 0.220417 --13.6 19.7939 -993.282 -0.788798 0.43244 0.436799 --26.0677 -3.81943 -949.076 0.0883344 -0.364859 0.926863 --28.9682 20.3242 -973.125 -0.714667 0.537931 0.44708 --31.0613 16.5764 -964.098 -0.777814 0.54733 0.308925 --4.19439 16.8936 -1001.08 -0.0345104 0.872289 -0.487772 -5.11309 33.3682 -930.658 0.833471 0.152896 0.530988 --29.1369 20.1261 -974.453 -0.914303 0.375536 -0.151736 --28.3653 16.9446 -969.781 -0.877658 0.202482 -0.434416 -2.33433 14.9762 -1006.14 -0.892439 0.356041 -0.277105 -25.3576 -43.6333 -967.874 0.895264 0.419793 0.149252 -2.05243 14.5607 -1004.02 -0.67286 0.721023 -0.165483 --13.7353 20.3191 -995.097 -0.665149 0.635589 -0.391924 -17.7285 -13.2106 -1027.77 0.767785 0.0092158 -0.640642 --17.3042 16.9298 -982.237 -0.609533 0.689623 -0.391011 -6.83893 25.0044 -984.392 0.532648 -0.356703 -0.767495 --24.4837 14.2359 -973.819 -0.597384 -0.79496 -0.105693 --30.7721 17.0228 -965.994 -0.799357 0.558161 -0.222451 --16.7531 18.1637 -987.181 -0.629358 0.728448 -0.270686 --26.4119 -34.0615 -947.315 -0.298555 0.438245 0.847825 -10.9452 46.1433 -938.805 0.427167 0.899118 0.0954707 -2.21853 14.8499 -1005.27 -0.925969 0.354386 -0.130354 --16.0541 -33.8173 -961.816 0.802849 -0.346351 -0.485258 -3.52047 33.0827 -933.418 0.311228 0.923082 -0.225957 --25.6269 38.2579 -951.316 -0.707459 -0.446503 0.547848 --6.51535 17.0055 -1000.08 -0.273107 0.895332 -0.351843 --29.4951 16.3869 -969.208 -0.635776 0.137675 -0.759496 -11.1002 53.8336 -965.173 0.0679739 0.961192 0.267375 --27.7745 -33.7836 -948.88 -0.600831 0.188599 0.776809 -13.6192 55.7538 -958.969 0.766924 0.456515 -0.451022 -13.8692 55.0141 -956.44 0.835534 0.452361 0.311854 -13.6144 54.5777 -954.898 0.846435 0.461371 0.265866 -13.604 53.8185 -953.839 0.933128 0.264806 0.243206 --22.5632 -31.0343 -951.547 -0.0386907 0.880754 0.471992 --31.601 15.831 -964.66 -0.977687 0.209297 -0.0179832 -13.7633 -41.7865 -962.545 -0.43213 0.146791 0.889784 -1.73891 14.04 -1005.19 -0.653673 0.668566 -0.354587 -12.208 -41.546 -963.557 -0.721989 0.234056 0.651115 --19.3766 51.2693 -967.602 0.000788544 0.318201 -0.948023 --30.0587 15.9524 -968.685 -0.881184 0.0394022 -0.471129 --14.1321 17.8341 -990.77 -0.760333 0.64595 0.0681291 --31.2258 15.7436 -966.154 -0.941856 -0.0612022 -0.330395 -6.17201 48.7059 -974.768 0.48328 0.869926 -0.098328 -6.28724 48.5885 -973.73 0.350019 0.917096 -0.190847 -0.578612 36.7382 -935.896 0.536661 -0.221125 0.814309 --14.085 17.7547 -992.475 -0.729356 0.668141 -0.147061 --17.7017 16.9817 -985.45 -0.710769 0.618413 0.335221 --17.5127 16.2543 -984.211 -0.628473 0.76555 -0.137673 --21.0244 15.1738 -978.544 -0.796829 0.499091 -0.340545 --9.90604 36.5472 -981.313 0.0709964 -0.376668 -0.923624 --12.1221 18.4614 -996.561 -0.151028 0.532716 -0.832709 --14.2978 16.0668 -989.356 -0.877122 0.404643 -0.258692 --27.6323 9.47784 -959.345 -0.886959 0.44815 0.111646 --11.5245 45.5893 -976.15 0.175695 0.362014 -0.915465 --15.6691 -41.9764 -981.846 0.66421 -0.287591 -0.690012 --29.7993 14.8453 -968.721 -0.644227 -0.354347 -0.677798 --18.3539 16.5522 -986.557 -0.774239 0.632658 0.0172459 -0.53916 36.2499 -935.854 0.670632 0.209523 0.711584 --19.8592 14.8938 -981.922 -0.64587 0.706055 -0.29041 -15.4337 56.4817 -949.372 0.435561 0.857535 0.273715 --14.1361 16.8305 -993.718 -0.664848 0.493216 -0.560995 --18.3115 15.5304 -984.85 -0.734642 0.642686 0.217383 --27.5786 -27.6956 -1030.22 -0.537225 -0.749588 -0.386662 -16.2002 -46.9401 -956.513 -0.282345 0.781558 0.556281 --22.4824 13.7131 -976.377 -0.872208 0.406151 -0.272571 -4.35421 33.7789 -930.176 0.463496 0.840492 0.280613 --25.325 11.792 -969.452 -0.890774 0.132167 -0.434803 -11.3768 -41.1138 -965.076 -0.908326 0.248717 0.336279 --16.7158 -23.1798 -1030.4 -0.629547 0.0163214 -0.776791 --15.3332 15.2242 -989.913 -0.616324 0.78333 -0.0808568 -18.7326 -13.9654 -1026.37 0.779583 -0.23207 -0.581717 -8.58396 22.5266 -982.928 0.0555181 -0.361083 -0.93088 --17.2506 -17.541 -976.788 0.332776 -0.761945 -0.555607 --22.7839 -33.7704 -947.444 -0.534936 0.214774 0.817139 --23.1776 -33.6303 -947.668 -0.198387 0.191259 0.961282 -5.09079 48.9221 -975.524 0.152448 0.969422 -0.192303 --15.8692 16.2229 -992.557 -0.693374 0.696941 -0.183046 --19.1099 14.5056 -984.885 -0.768344 0.637014 -0.0621385 -10.3632 53.9868 -966.611 0.217225 0.914105 -0.342381 --13.8831 17.9845 -999.418 -0.54605 0.831495 0.1022 --19.3038 15.1095 -986.16 -0.837116 0.5038 0.213124 --19.0372 14.6889 -985.353 -0.836087 0.474904 0.274635 --28.1543 9.26801 -964.206 -0.831934 0.550572 0.0689651 --28.9346 7.78815 -959.25 -0.799575 0.555727 0.2277 --4.76175 14.959 -1005 -0.0362324 0.940713 -0.337263 --10.1072 45.3984 -975.686 0.069842 0.127093 -0.989429 --23.3199 34.0844 -976.884 -0.875813 0.444645 -0.187728 --22.3514 12.9611 -978.935 -0.841891 0.506832 -0.185314 --26.5812 46.3905 -954.707 -0.82871 0.544812 0.128139 -3.52547 34.065 -931.197 0.221115 0.969624 -0.104585 -13.9075 -36.666 -998.325 -0.392189 -0.467256 0.792376 -2.00814 12.4474 -1009.95 -0.495264 0.852394 -0.167744 --31.0521 -29.5322 -1008.9 -0.549923 0.560258 0.619432 -5.94504 49.0492 -972.493 0.079876 0.837477 -0.540603 --27.9365 9.41078 -965.251 -0.751382 0.640247 -0.159716 --16.5292 15.4001 -991.739 -0.771155 0.508008 0.383728 -10.8304 48.0661 -940.431 0.795166 0.409517 0.447222 -10.0232 46.384 -937.847 0.627418 0.62744 0.461156 -2.13556 12.1815 -1011.09 -0.55507 0.75415 -0.350936 -10.0276 45.331 -935.468 0.697479 0.547423 0.462439 -9.69903 44.5689 -934.226 0.776425 0.222211 0.589735 --16.3562 14.5235 -990.881 -0.773262 0.540286 0.3319 --27.2006 -18.3016 -957.839 -0.523168 0.203051 0.827687 -19.8649 -5.6547 -954.621 -0.00532362 -0.498297 0.86699 --13.8468 15.1894 -994.95 -0.499364 0.598577 -0.626371 --15.6571 15.4803 -994.171 -0.408001 0.689946 -0.59792 --17.4535 14.243 -988.923 -0.517094 0.576662 -0.632515 -13.3902 56.8574 -957.445 0.713223 0.617778 0.331153 -16.3095 -6.40005 -954.607 0.0538147 -0.194984 0.979329 --24.0325 11.3148 -975.191 -0.860228 0.46929 -0.199434 --25.5844 10.4367 -970.977 -0.834599 0.492624 -0.246509 --14.5135 16.8572 -998.957 -0.955173 0.217762 0.200559 --15.9698 -21.3697 -1031.59 -0.722905 -0.164734 -0.671023 --24.6804 -0.157692 -950.183 -0.82108 0.0150144 0.570615 -9.69928 46.0913 -937.118 0.524977 0.76364 0.375837 --29.365 6.29913 -957.818 -0.746696 0.323349 0.581283 -2.26685 33.4711 -933.625 0.284261 0.948086 0.142576 --13.4616 14.8334 -996.126 -0.732799 0.672888 -0.101133 --21.9958 12.6884 -981.224 -0.808334 0.542225 -0.229323 --0.565511 39.4517 -979.883 0.0140022 0.893088 -0.449664 --19.357 -15.7356 -1030.42 -0.698577 0.29969 -0.649751 --11.1464 36.3255 -981.913 0.273288 0.0198428 -0.961727 --25.2111 -33.4203 -947.441 -0.0812962 0.575482 0.813764 -1.05285 11.5481 -1009.71 -0.503907 0.822659 -0.263267 -13.2382 56.1701 -956.118 0.799093 0.442027 0.407508 --19.0694 -13.7177 -1032.18 -0.961688 0.273752 0.0146761 --20.9778 13.0513 -983.553 -0.716722 0.633678 -0.291138 --9.0272 41.8128 -975.902 -0.307594 0.402537 -0.862177 --26.3804 9.69991 -970.172 -0.749702 0.604764 -0.268714 -2.1204 11.3533 -1012.3 -0.541036 0.692437 -0.477296 -24.2656 -32.53 -999.859 0.877666 0.301447 0.372601 --5.80384 14.2495 -1006.3 -0.100985 0.823062 -0.558901 --14.5971 16.3556 -999.76 -0.961278 -0.0883187 -0.261045 --29.0316 -17.201 -959.706 -0.758138 0.173442 0.628606 -12.7544 55.3146 -954.802 0.593981 0.684967 0.421909 -1.45627 2.66787 -1022.33 0.148187 0.988833 0.0158181 --29.6551 -28.7455 -1025.19 -0.846271 -0.373328 -0.380067 --29.912 6.78438 -961.262 -0.838537 0.537044 0.091868 -2.19486 46.1386 -977.574 -0.328622 -0.124382 -0.936235 -2.54301 35.8362 -937.941 0.526073 -0.103899 0.844069 --17.4757 13.1825 -990.793 -0.696334 0.694386 -0.181514 --20.4575 13.3297 -987.43 -0.809563 0.551569 -0.200947 --20.3082 12.7008 -985.735 -0.808789 0.587807 -0.0185439 --29.5194 7.60386 -964.364 -0.832158 0.553861 -0.0274016 -3.35796 33.7925 -929.329 0.409256 0.706695 0.577141 -3.94583 48.7853 -976.168 -0.048833 0.85269 -0.52013 --17.3829 -12.4864 -1028.43 -0.275618 0.40421 -0.872152 -14.2304 56.7427 -949.151 0.2098 0.709986 0.672238 --30.0088 5.70582 -958.759 -0.88652 0.382638 0.260136 --14.209 13.7561 -995.701 -0.662613 0.610549 -0.433789 --17.1805 14.5012 -992.101 -0.856183 0.40901 0.315693 --24.2952 -10.0812 -982.897 -0.395211 -0.562397 -0.726304 --17.3642 13.0232 -991.684 -0.828683 0.555645 0.0674003 --18.5847 -23.1588 -974.064 0.574136 -0.263186 -0.775307 -10.9664 49.6534 -942.446 0.742759 0.459682 0.486828 --29.2906 7.77608 -965.659 -0.778833 0.615616 -0.120147 --18.9366 -6.44237 -1028.16 -0.769771 -0.432913 -0.469083 --25.0601 9.69121 -974.687 -0.878031 0.438191 -0.192486 --20.7604 -35.549 -981.568 0.00785063 0.774269 -0.632808 -1.34353 10.4095 -1012.4 -0.740908 0.387176 -0.548771 --7.75137 13.8655 -1006.08 -0.4218 0.784852 -0.453973 --14.8218 14.1958 -996.974 -0.583916 0.741631 0.330189 --14.5246 13.5113 -996.08 -0.688718 0.682484 0.24471 --14.8495 13.6737 -995.274 -0.32678 0.334643 -0.883872 -12.4692 56.3551 -955.397 0.474884 0.681113 0.557288 -19.8725 21.3208 -971.454 0.280703 0.253653 -0.925671 --30.1547 6.63067 -963.443 -0.900527 0.434754 0.00627846 --29.7934 -38.2796 -974.25 -0.456128 0.648412 0.609516 -2.81656 35.0351 -938.079 0.546663 0.304695 0.779949 --21.0632 -34.5233 -980.049 -0.101234 0.86634 -0.489088 --17.7294 13.8827 -993.473 -0.749717 0.616651 -0.240137 --18.3791 -7.2353 -1028.17 -0.757634 -0.600087 -0.256684 --11.3201 10.6032 -1012.36 -0.0557329 0.940078 -0.336374 -9.04819 46.6659 -937.185 0.599196 0.528221 0.60162 -1.62974 34.1004 -934.089 0.409314 0.87322 0.264476 --30.6094 5.18224 -960.689 -0.929316 0.350228 0.117098 -13.6732 56.9604 -949.575 0.154958 0.987629 0.0240385 -13.9666 56.4067 -948.816 0.245757 0.459627 0.853432 -1.96693 9.72765 -1013.57 -0.762163 0.574518 -0.298391 --21.095 12.3258 -987.651 -0.85129 0.523338 0.0377024 --26.5177 8.07339 -972.455 -0.746132 0.494023 -0.446351 --18.9226 -4.34577 -1027.33 -0.360103 0.758331 -0.543378 --20.8787 12.2494 -988.105 -0.619306 0.345596 -0.704999 --23.5532 10.4204 -980.404 -0.859478 0.478871 -0.178828 -1.7484 34.0641 -932.098 0.063615 0.962748 -0.262811 --7.80486 13.0973 -1007.04 -0.510087 0.512996 -0.690396 -9.05818 53.2392 -964.391 0.0477087 0.966635 0.251677 --15.8223 13.4296 -997.319 -0.693245 0.59399 0.408152 --18.1979 11.9386 -992.262 -0.764009 0.64025 0.0798097 --28.2818 7.63385 -969.784 -0.757668 0.577825 -0.303409 --16.4082 -25.3548 -1008.47 -0.410729 -0.670385 0.617969 --13.7611 15.5648 -1004.38 -0.339549 0.933049 0.118852 --19.6908 11.5478 -989.49 -0.707812 0.616353 -0.345125 --21.6137 11.0163 -986.304 -0.771648 0.631948 0.0721243 --26.0246 7.82897 -973.861 -0.887412 0.376655 -0.265764 --30.6701 2.74787 -957.922 -0.892964 0.206853 0.399784 --15.9294 12.3856 -996.044 -0.57066 0.714902 -0.404057 -12.3578 57.3993 -956.858 0.487415 0.501879 0.714524 --20.1404 11.6759 -988.604 -0.594999 0.410196 -0.69117 --29.3261 6.82794 -968.566 -0.769261 0.597601 -0.226076 --29.8451 6.62706 -967.119 -0.860413 0.473405 -0.188617 --21.4929 -38.9779 -946.02 -0.179993 -0.500311 0.846931 -15.9488 -47.6951 -955.775 -0.36502 0.546727 0.753559 --16.0598 13.5959 -998.489 -0.617293 0.786202 0.028901 --18.6541 12.2861 -993.642 -0.832484 0.545336 0.0978768 -17.7575 39.8753 -953.746 0.885817 -0.228064 0.404123 -0.941832 33.8192 -932.524 0.370778 0.928306 0.0277704 --24.2139 51.9914 -955.587 -0.56398 0.478741 -0.672855 --29.5276 -32.2827 -1000.41 -0.239363 0.571131 0.785184 --21.9405 10.7981 -987.443 -0.829511 0.203781 -0.519985 -8.7584 53.2724 -963.988 0.277719 0.955354 -0.100854 -12.3668 57.6426 -957.388 0.411546 0.908684 0.0701676 --30.9802 2.90438 -958.937 -0.947978 0.221874 0.228277 --14.6195 14.5857 -1004.07 -0.92578 0.241194 0.291132 -11.6457 55.7666 -954.44 0.468361 0.674422 0.570782 --23.7083 9.417 -982.192 -0.872032 0.446493 -0.200508 -10.7108 51.3984 -944.303 0.586627 0.664321 0.463191 --26.483 7.12668 -973.362 -0.82302 0.395715 -0.407489 --26.2631 27.7083 -965.437 -0.626299 0.183475 -0.757685 --31.1888 3.28306 -960.825 -0.969325 0.216565 0.116228 -1.19386 9.02083 -1014.74 -0.653253 0.737426 -0.171647 --5.93702 11.3607 -1011.16 -0.0978607 0.906489 -0.410733 --7.72318 4.02289 -1019.51 -0.43387 0.576449 -0.692434 --31.0756 4.19994 -962.967 -0.958842 0.281968 0.0333953 --16.2288 13.0348 -1000.02 -0.43754 0.763834 -0.474465 --30.7107 -28.742 -1022.58 -0.914265 -0.252034 -0.317171 -10.5451 -23.9844 -962.609 -0.8799 0.0474417 0.472785 -8.86231 27.8596 -932.581 0.261525 0.36356 0.894108 --14.7364 14.374 -1004.82 -0.927744 0.0200346 -0.37268 --11.9479 41.2739 -976.251 -0.073896 0.466797 -0.881272 --17.1137 11.8476 -995.704 -0.337527 0.506419 -0.793483 --29.1017 -50.7306 -952.496 -0.556452 -0.0131201 0.830776 -19.2437 2.80173 -954.392 0.987373 0.15772 0.0148168 -9.87712 49.5827 -940.29 0.687471 0.576784 0.441252 --22.7278 9.75757 -986.073 -0.908959 0.409633 -0.0774257 -11.4793 -23.9228 -961.223 -0.755648 0.0269627 0.654423 --14.2659 12.6778 -1003.2 -0.842605 0.538444 0.00977884 -1.48748 34.2874 -930.298 0.0892691 0.995887 -0.0154721 -7.54106 52.8776 -968.054 0.637647 0.518366 -0.569827 --30.7126 4.99089 -966.915 -0.898149 0.416742 -0.140195 --31.0053 4.45312 -965.52 -0.943299 0.331189 -0.0223997 --31.0971 0.808874 -958.215 -0.92039 0.106829 0.376126 --16.888 11.3714 -996.603 -0.737427 0.668378 0.0973215 --26.4051 -35.9538 -998.531 -0.354261 -0.107969 0.928893 -11.6202 55.5224 -953.978 0.338736 0.928471 0.152314 --28.5733 6.0106 -971.819 -0.736844 0.550217 -0.392839 -0.634068 8.05624 -1014.99 -0.681724 0.607712 -0.407356 --30.5364 -48.9358 -964.329 -0.268334 -0.926683 -0.263165 --24.9779 7.76485 -979.837 -0.911913 0.370812 -0.175819 -9.30372 48.9476 -938.808 0.658046 0.472714 0.586104 --26.3127 -6.53565 -983.414 -0.42377 -0.0895323 -0.901334 -14.591 -46.3605 -958.593 -0.172838 0.825608 0.53712 --17.3196 12.296 -999.92 -0.626559 0.695519 -0.351677 -2.71052 49.035 -974.717 -0.0848823 0.992374 -0.0893807 --5.60106 10.4389 -1012.6 -0.0806388 0.713839 -0.695651 -8.10124 53.8054 -965.496 0.456607 0.88885 -0.0381452 --19.4498 10.9418 -994.916 -0.733015 0.525366 -0.432064 --27.2233 5.66418 -973.59 -0.697972 0.420593 -0.579601 -12.4126 56.7872 -950.888 0.355023 0.833082 -0.424186 -0.875299 7.46957 -1016.06 -0.592019 0.53255 -0.6049 --22.1073 8.96784 -988.242 -0.81144 0.507502 -0.289837 --23.404 8.50062 -985.443 -0.853556 0.470525 -0.223713 --15.4646 12.0449 -1002.61 -0.670693 0.708848 0.218415 --30.6816 -34.6219 -1000.51 -0.940466 -0.0527996 0.335761 --26.5097 5.37998 -975.163 -0.932973 0.255783 -0.253253 --13.6144 7.92832 -1013.06 -0.99141 0.12966 0.0171878 -1.43816 33.4654 -928.255 0.276129 0.621628 0.733029 --7.72932 10.5223 -1011.97 -0.259855 0.828028 -0.496835 --17.9206 11.8493 -998.941 -0.760351 0.648298 0.0396897 --24.8616 6.98485 -981.808 -0.928468 0.315981 -0.195201 -10.8442 53.5125 -946.68 0.771977 0.545419 0.326451 -1.51475 46.5193 -977.132 -0.503054 0.305955 -0.808288 -19.4878 4.06054 -954.906 0.956352 -0.241965 0.163844 -9.64503 51.0018 -942.296 0.631687 0.646091 0.428412 -8.05085 47.0905 -936.526 0.513564 0.699218 0.49734 --18.1563 11.3694 -998.315 -0.750082 0.515864 0.413837 --20.3806 9.67439 -994.629 -0.741691 0.313873 -0.592772 --30.1537 4.19216 -970.99 -0.826278 0.474049 -0.304206 --23.7953 -24.494 -1034.39 0.550628 -0.0565536 -0.832833 -9.65254 52.1891 -944.281 0.442961 0.801233 0.402257 --20.6105 9.24911 -993.196 -0.766352 0.633909 0.10423 -1.43999 6.2356 -1017.87 -0.534694 0.79927 -0.274353 --26.3106 -31.883 -950.07 -0.227915 0.879463 0.417851 --7.10563 36.0824 -936.771 -0.0391343 0.322653 0.945708 --20.651 9.5493 -994.158 -0.854247 0.513971 -0.0780811 --20.9575 8.8312 -992.532 -0.779645 0.605183 -0.160959 --7.15506 8.40872 -1013.45 -0.150327 0.588429 -0.794452 --18.5131 11.022 -999.895 -0.786246 0.598077 -0.155308 --18.3166 9.76638 -997.663 -0.798946 0.489486 0.349411 --18.7163 9.49845 -996.7 -0.685149 0.678873 -0.264013 -15.5144 34.2002 -975.771 0.770798 -0.430089 -0.469994 --26.2192 4.51821 -977.591 -0.989355 0.0720364 -0.126438 --29.8057 -39.3206 -960.202 -0.9071 -0.199268 0.370758 --23.3922 7.25299 -987.055 -0.801339 0.504181 -0.321957 --29.2106 4.01214 -973.063 -0.699967 0.476803 -0.5317 --31.5902 2.39804 -967.525 -0.946539 0.294197 -0.132333 --16.8883 -27.9065 -968.163 0.952797 -0.223192 -0.205821 --31.6781 2.15355 -966.569 -0.967626 0.252095 0.0121747 --31.8453 0.218517 -961.657 -0.975658 0.195349 0.0996501 -7.25821 46.9629 -935.914 0.215965 0.588056 0.779454 -21.4484 35.517 -962.739 0.315017 0.0219328 -0.948833 --31.178 2.91114 -969.383 -0.932092 0.306582 -0.192905 --31.7626 -1.21361 -959.871 -0.96677 0.0868592 0.240439 --13.9492 12.3891 -1008.93 -0.849656 0.494519 0.183127 -6.77984 54.2858 -966.451 0.371589 0.864054 -0.339606 --30.5685 -23.875 -973.071 -0.496695 -0.61947 -0.607907 -7.4303 -16.8365 -1033.16 0.559436 -0.637903 -0.529255 --28.2953 16.1165 -973.126 -0.720183 -0.638791 -0.270707 --25.8787 4.53503 -979.9 -0.970299 0.179288 -0.162404 --20.3555 8.60514 -995.084 -0.739895 0.476676 -0.474695 -0.449389 34.2121 -930.971 0.287393 0.950284 -0.119853 --1.56608 37.1407 -982.293 0.208891 -0.0294679 -0.977495 -10.4443 57.977 -958.151 0.0187777 0.999197 -0.035396 --28.5186 17.1935 -974.024 -0.851876 -0.393298 -0.345866 --30.7234 2.72375 -971.344 -0.916107 0.294225 -0.27236 --16.7983 9.24879 -1002.26 -0.637813 0.741069 -0.209789 -8.80243 49.5598 -938.909 0.496336 0.669486 0.552666 --17.127 10.6067 -1003.75 -0.675569 0.729099 0.10964 --21.8173 7.62812 -992.154 -0.855308 0.500039 -0.135683 -0.080017 34.58 -932.328 0.539281 0.838084 0.0824095 --25.7987 30.9068 -954.018 -0.996012 -0.0817271 0.0357763 -11.2904 42.749 -974.368 -0.066749 -0.359731 -0.930666 -10.7344 57.6516 -956.278 0.255433 0.825139 0.503884 --32.1865 0.0172883 -964.942 -0.979015 0.198247 0.047197 --5.66772 7.95187 -1015.46 -0.139636 0.943752 -0.299724 --17.8762 9.01987 -1001.26 -0.358023 0.553638 -0.751867 --18.6149 10.3736 -995.692 -0.550151 0.499646 -0.669095 -9.03891 50.5902 -940.63 0.526115 0.724431 0.445425 --7.67973 37.5421 -936.754 0.145125 -0.223913 0.963744 --15.7104 45.945 -976.151 -0.434609 0.209566 -0.875898 -0.351652 34.4024 -929.509 0.298541 0.941769 0.154741 --21.1244 42.0143 -973.469 -0.214627 0.212828 -0.953226 --17.7624 9.85774 -1003.66 -0.803217 0.376125 0.461923 -24.3988 -27.7715 -976.12 0.465735 -0.339483 -0.817216 -8.94349 52.7099 -944.584 0.273916 0.775972 0.568188 --19.7277 9.23574 -999.731 -0.909237 0.408137 0.081926 --18.0588 -5.83684 -1030.49 -0.681667 -0.402468 -0.611024 --31.9898 0.0799409 -968.268 -0.978057 0.123804 -0.16756 --32.2375 -0.293196 -966.818 -0.982541 0.174836 -0.063597 --10.5759 21.3526 -940.758 -0.410797 -0.442035 0.797402 --32.2574 -2.15433 -961.892 -0.986155 0.0998756 0.132376 --24.5646 53.3305 -957.378 -0.982589 0.102318 0.15508 --26.1858 2.38354 -979.865 -0.994226 0.0590568 -0.0895987 --27.3012 1.42732 -976.105 -0.569273 0.541546 -0.618592 -10.2376 54.8336 -947.428 0.097698 0.609136 0.787025 --28.9416 1.69798 -974.944 -0.499057 0.590564 -0.634174 --31.7822 0.151084 -969.155 -0.962878 0.0527842 -0.264727 --7.9123 12.6282 -1023.82 -0.808608 0.581599 -0.0888545 --12.3202 10.0695 -1012.19 -0.717339 0.692313 0.0782744 --14.9503 -17.806 -968.532 0.818526 -0.531547 -0.217883 --22.0647 6.58637 -993.325 -0.868665 0.339141 -0.361115 --21.2943 10.4885 -988.105 -0.779076 0.275454 -0.563174 --26.4949 1.6183 -977.235 -0.906671 0.240785 -0.346367 --8.78843 38.1342 -936.249 0.162582 -0.619142 0.768265 --7.71527 12.2813 -1023.08 -0.582348 0.510939 0.632306 --24.6601 -12.0903 -958.911 -0.171411 0.256468 0.951232 --1.96844 40.3253 -930.939 -0.0292755 0.286932 0.957504 -5.50885 54.3764 -969.109 0.734079 0.64372 -0.216223 -10.4996 57.1196 -951.158 0.0303933 0.984371 -0.173465 --19.4628 -19.9106 -976.071 0.482592 -0.461327 -0.744501 --18.0271 9.87875 -1005.08 -0.788799 0.614277 0.0214261 --19.8745 7.66442 -999.015 -0.925556 0.377781 0.0250374 --20.6977 7.14451 -997.198 -0.853667 0.472109 -0.219921 --19.2818 -28.7029 -954.954 0.306382 0.660931 0.685055 --27.4396 1.06252 -976.37 -0.4454 0.721795 -0.529746 -4.97267 43.6943 -932.355 -0.116808 0.573809 0.810616 --30.2365 1.15692 -974.141 -0.767704 0.493775 -0.408432 --32.4604 -1.51798 -965.735 -0.995112 0.0925739 -0.034382 --13.1743 9.36974 -1011.26 -0.707761 0.414547 -0.572036 --14.3739 9.1293 -1010.02 -0.667671 0.721318 -0.184162 --14.6323 45.8794 -976.357 -0.0385417 0.381756 -0.923459 --13.2012 10.1335 -1013.22 -0.648707 0.706156 0.283766 --18.643 7.90229 -1001.79 -0.599538 0.672755 -0.433538 --31.3269 -17.31 -975.195 -0.970576 -0.230601 0.069323 --24.7409 3.88969 -986.444 -0.944287 0.273072 -0.183724 -21.0816 -45.0706 -960.204 0.0839053 0.86511 0.494514 --26.5454 0.775547 -977.915 -0.723648 0.549789 -0.417212 --30.9075 0.520503 -972.15 -0.985398 0.106317 -0.132994 --14.5223 14.5885 -995.197 -0.351183 0.489064 -0.798428 -11.9011 25.9215 -947.944 0.0786266 0.574806 0.814503 --25.1618 22.0719 -953.768 -0.920782 -0.382104 -0.0784602 --18.3049 -30.3951 -972.103 0.899577 -0.211879 -0.381928 --26.1932 0.623917 -979.235 -0.974752 0.149788 -0.165596 --20.2996 7.6381 -1001.02 -0.917586 0.351914 -0.184914 --0.21005 34.3955 -928.877 0.236279 0.897337 0.372771 --21.1131 53.0761 -961.785 -0.710603 0.555596 -0.431691 --8.12768 11.5569 -1024.31 -0.880571 0.318019 -0.351366 -17.118 -32.0334 -997.785 -0.0825036 0.28327 0.955485 -7.09677 49.0998 -937.411 0.218802 0.653631 0.724495 --1.29265 35.3338 -933.097 0.586596 0.669991 0.454991 --23.1838 20.6734 -960.414 -0.694278 -0.643376 0.32256 --23.7805 4.31376 -990.459 -0.884271 0.379873 -0.271592 --23.2153 46.0355 -944.597 -0.912513 -0.265965 -0.310778 --25.7472 1.82435 -983.676 -0.973752 0.171353 -0.149815 --7.47728 37.8418 -936.456 -0.192793 -0.759962 0.620716 --28.9547 0.588944 -976.165 -0.353499 0.764704 -0.538764 -14.8352 28.1014 -949.78 0.169875 0.24194 0.955305 --30.9258 0.232529 -973.205 -0.909669 0.405982 -0.0876364 --28.0639 44.4353 -955.93 -0.849581 0.217744 -0.480416 --7.36811 7.01182 -1017.4 -0.378499 0.883196 -0.276953 --13.9305 9.52608 -1014.03 -0.910617 0.37521 0.173189 -7.49194 49.9368 -938.459 0.274941 0.738823 0.615262 --27.3513 -0.105703 -978.59 -0.394585 0.791437 -0.46683 --1.19178 35.0375 -931.413 0.28712 0.952528 0.101253 -12.6542 -23.3448 -960.183 -0.58443 -0.035866 0.810651 --32.5994 -3.96886 -963.893 -0.999242 -0.000558758 0.0389147 -5.0153 54.4564 -969.849 0.527939 0.686074 -0.500583 --13.4196 8.57365 -1012.72 -0.894172 0.254525 0.368339 -5.6866 54.3844 -967.063 0.48796 0.84886 -0.203303 -14.9603 44.6726 -946.908 0.916684 -0.274932 0.290003 -8.47506 55.6568 -953.984 0.370079 0.921955 -0.114196 --26.4173 36.24 -953.352 0.0744002 0.0558979 0.995661 --10.2581 35.2919 -936.605 -0.191851 0.237866 0.952162 -8.21878 -25.484 -1001.74 0.472322 -0.747936 0.466372 --27.3278 -37.2619 -946.935 -0.679363 0.149267 0.71846 -7.30416 50.7845 -939.614 0.284165 0.839241 0.463599 --19.2507 16.6611 -979.746 -0.68506 0.581566 -0.438719 -4.80194 25.3883 -930.13 0.241661 -0.567433 0.787159 --32.4453 -2.89728 -966.539 -0.984019 -0.014789 -0.177449 --8.29075 10.7358 -1023.82 -0.995068 0.0680088 0.072212 --6.44082 7.95307 -1020.45 -0.332134 0.394988 0.856546 --26.2799 -0.529553 -980.32 -0.754341 0.532936 -0.383339 --10.1671 37.1783 -935.188 0.589536 -0.520953 0.617297 --25.4083 -31.0495 -951.951 -0.20124 0.925674 0.320359 --8.16956 6.56678 -1017.2 -0.477319 0.792347 -0.379939 --7.80716 10.052 -1022.28 -0.872108 0.111489 0.476443 -18.1041 -26.8141 -1032.23 0.22733 -0.76692 -0.600129 --26.8951 -15.0777 -958.612 -0.490694 0.28495 0.823422 --18.1728 -41.7604 -960.135 0.977116 0.21243 0.0108588 --7.83604 9.28189 -1022.84 -0.947424 0.0219998 0.319224 --14.0806 9.01931 -1014.79 -0.901375 0.263879 -0.343352 -17.4581 -28.0798 -959.927 0.120736 -0.193483 0.973646 -7.35413 52.6394 -944.057 0.0885716 0.912066 0.400364 -4.66322 32.5186 -930.73 0.557645 -0.525845 0.642276 --24.8025 2.71078 -988.159 -0.947453 0.24634 -0.204081 --32.4832 -5.30321 -963.284 -0.986663 -0.151756 0.0588666 --2.09302 35.3783 -932.597 0.390729 0.738418 0.549608 --6.43164 6.72878 -1019.89 -0.650478 0.575147 0.496069 --1.58635 34.8959 -929.72 0.131691 0.96286 0.235706 --1.49586 34.3054 -928.232 0.0824296 0.827204 0.555822 --18.8634 8.56029 -1006.54 -0.71642 0.592271 -0.368725 --21.3933 5.12968 -998.442 -0.89229 0.400188 -0.208969 --23.481 3.80731 -992.353 -0.909931 0.320938 -0.262723 --26.741 -0.835047 -980.138 -0.441427 0.738146 -0.510179 --30.5119 -0.0105523 -975.753 -0.623795 0.709286 -0.328319 --31.3557 -1.09978 -972.236 -0.935685 0.346581 0.0661463 --31.1204 -1.93144 -970.312 -0.978282 0.14025 0.152623 --32.1304 -6.53307 -962.383 -0.953387 -0.257469 0.157366 --20.5629 5.87563 -1000.29 -0.949338 0.311501 -0.0415213 -5.37289 32.3522 -931.672 0.919158 0.2227 0.324891 -7.2693 57.6388 -962.438 0.748764 0.325911 -0.577178 --22.2292 31.9297 -977.68 -0.473305 -0.235683 -0.848785 --32.1524 -3.85625 -967.221 -0.96909 -0.128603 -0.210539 --32.4622 -4.62575 -965.75 -0.981469 -0.12422 -0.145905 -8.81416 56.969 -951.101 -0.135792 0.990705 -0.00805082 --6.8922 6.13611 -1019.48 -0.73262 0.624381 -0.270953 --26.4545 -30.4546 -954.18 -0.279472 0.830593 0.481676 --14.8169 11.6343 -943.68 0.098267 -0.596177 0.796817 -4.79867 54.9945 -967.845 0.43145 0.901025 -0.0447725 --7.76055 7.99284 -1022.18 -0.978239 0.0194885 0.206563 --25.7611 -15.3788 -957.945 -0.338523 0.297061 0.892836 --19.9465 5.88989 -1002.54 -0.72696 0.489286 -0.481796 -8.20597 56.4955 -952.619 0.0382436 0.925512 -0.376783 --15.3485 18.5848 -982.076 -0.607525 0.682295 -0.406677 --7.73918 7.64067 -1021.78 -0.907108 0.0706158 0.414933 --6.2314 20.5306 -989.167 -0.743914 0.615952 -0.259219 --26.8795 19.3072 -963.59 -0.433441 0.366656 0.82322 -4.68895 54.8401 -966.243 0.14202 0.989503 0.0267188 -7.62839 57.737 -960.187 0.614838 0.753952 -0.231367 --27.287 -35.0865 -999.446 -0.42892 0.110738 0.896529 --8.28559 8.52247 -1023.95 -0.969265 0.0924711 -0.22798 --16.4815 7.56081 -1010.85 -0.623178 0.767438 -0.150628 --28.738 19.1115 -975.351 -0.807251 -0.155858 -0.569257 --25.3452 1.04959 -987.303 -0.971061 0.168643 -0.169117 --26.2375 -1.74558 -981.849 -0.742408 0.436729 -0.508034 -3.84695 55.2665 -968.506 0.151301 0.980014 -0.129153 -7.38863 57.8727 -961.098 0.656267 0.739846 -0.14813 --24.2142 49.2118 -946.23 -0.750573 -0.645957 -0.139209 --22.599 3.18117 -995.905 -0.926739 0.290759 -0.237938 -7.88172 56.5061 -952.939 0.652398 0.745924 -0.13407 --30.6231 -0.82382 -977.671 -0.46738 0.782848 -0.410737 --24.1116 15.3837 -975.518 -0.435744 -0.589301 -0.680331 -6.17959 50.8713 -939.349 0.117026 0.864811 0.48827 --32.2702 -6.41417 -964.679 -0.965125 -0.252466 -0.069244 --7.14187 5.56607 -1020.6 -0.936298 0.258236 0.238034 --7.21934 5.15842 -1020.11 -0.93092 0.286633 -0.226338 --18.6322 48.3455 -967.671 0.156057 0.27592 -0.948427 --13.4142 20.2255 -982.315 -0.577789 0.477009 -0.662285 --8.37553 7.63586 -1023.42 -0.956909 0.0664191 0.282689 -7.22527 57.0413 -955.149 0.642055 0.766294 0.023642 --27.228 -29.9198 -955.169 -0.442499 0.661529 0.605453 --27.2673 -1.71683 -980.983 -0.402493 0.685836 -0.606323 --29.233 -1.44449 -979.858 -0.343225 0.757658 -0.555113 --31.4773 -4.75789 -969.803 -0.934712 0.194324 0.297575 --31.3519 -5.50238 -968.42 -0.994695 0.0459523 -0.0920308 --16.9668 6.89572 -1009.92 -0.809398 0.464046 0.359911 --20.3663 4.80369 -1002.91 -0.861794 0.368259 -0.348851 --20.8479 4.84645 -1002.07 -0.878974 0.305169 -0.366439 --31.8324 -6.23748 -967.014 -0.98922 -0.100076 -0.106907 --16.8693 6.14883 -1009.34 -0.806409 0.552712 0.210273 --27.188 -7.47922 -950.677 -0.316002 -0.438921 0.841125 --23.7751 1.78113 -993.151 -0.944645 0.202653 -0.258024 --11.8788 21.2323 -982.896 -0.716128 0.181203 -0.674038 --3.30266 35.8115 -932.452 0.152959 0.97444 0.164533 --3.18422 35.3424 -931.562 0.127838 0.955 0.267643 --31.4628 -1.45611 -977.402 -0.780361 0.52102 -0.345798 --31.9312 -1.58742 -976.484 -0.848237 0.490624 -0.199453 -6.36084 58.0097 -962.703 0.31906 0.865157 -0.386916 --32.3381 -2.26725 -974.463 -0.937623 0.345837 0.0354918 -9.3106 55.8378 -953.842 -0.0200948 0.797675 -0.602753 --7.88533 7.55266 -1025.51 -0.701225 0.405326 -0.586511 -3.51812 32.0158 -930.501 0.32382 -0.666434 0.67157 --6.06263 23.1004 -985.932 -0.824976 0.305966 -0.475183 --17.2203 5.82474 -1008.94 -0.678114 0.677879 -0.283974 --19.8076 6.7453 -1007.31 -0.870142 0.438751 -0.22439 --32.5198 -3.19217 -973.335 -0.947182 0.270335 0.172525 --8.15435 7.46574 -1025.09 -0.939476 0.226417 -0.257137 --14.0992 5.53059 -1013.21 -0.773622 0.491012 -0.40052 --24.6795 0.519156 -990.637 -0.963526 0.132285 -0.232634 -23.07 -46.0437 -974.344 0.200361 -0.856806 -0.475119 --7.75112 5.23222 -1022.25 -0.944907 0.0218882 0.326606 --13.3824 5.98298 -1015.88 -0.770509 0.590712 -0.23953 --26.7785 -3.0395 -982.37 -0.457592 0.510084 -0.728302 --2.19309 51.5834 -970.943 0.418536 0.136246 -0.897922 --31.6467 -6.3926 -969.133 -0.928182 0.175625 0.328076 --31.5278 -7.32938 -967.791 -0.998123 -0.0154999 0.0592487 -7.19904 56.8454 -951.628 0.261894 0.939827 0.2194 --31.5923 -7.68925 -966.859 -0.980814 -0.194879 0.00517906 -2.17575 23.8486 -986.834 -0.655415 0.665188 -0.35771 --13.6878 -29.5467 -1009.04 -0.472805 -0.382933 0.79361 --12.8191 6.71633 -1018.49 -0.370614 0.820808 -0.434649 -5.46231 51.6708 -940.966 0.0119968 0.939557 0.342182 --25.5408 -1.32205 -987.484 -0.98767 0.0110615 -0.156159 --30.7378 -1.96149 -979.193 -0.623594 0.578054 -0.526292 --3.49088 34.8157 -929.216 -0.0268848 0.940569 0.338537 --32.4867 -4.50875 -971.825 -0.92777 0.257633 0.26994 --3.1289 48.8459 -974.984 0.180156 0.854543 -0.487134 --2.68016 -27.2964 -1032.54 0.109166 -0.793659 -0.598488 -14.0075 22.2233 -979.795 0.608465 -0.582332 -0.539128 --8.60059 6.33752 -1024.35 -0.984225 0.146897 -0.0985997 -6.28339 58.4391 -960.84 0.304762 0.952289 -0.0163194 --17.4609 6.40911 -1011.75 -0.678888 0.675679 -0.287349 --22.5655 1.58727 -997.27 -0.954197 0.135313 -0.26683 -20.457 -47.081 -955.907 -0.423667 0.541557 0.7261 -6.67195 56.2568 -950.393 0.123097 0.811084 0.57183 -5.08679 52.8602 -945.502 -0.0684691 0.929846 0.361522 --1.24506 10.536 -944.263 0.611931 -0.330457 0.718568 -17.1835 -46.7514 -956.615 0.2084 0.798029 0.565437 --29.9627 -10.577 -963.575 -0.860277 -0.388638 0.329977 --29.5251 -11.8249 -962.9 -0.869948 0.129416 0.475859 -19.034 5.2037 -951.788 0.830434 0.210263 0.515916 --13.9575 6.12851 -1017.63 -0.866827 0.483505 0.121793 -2.91403 24.3805 -986.985 -0.256916 0.927234 -0.272454 --22.1745 51.3997 -967.098 -0.220056 0.615057 -0.757152 --21.3987 3.04093 -1001.5 -0.947982 0.236463 -0.213111 --25.9727 -3.752 -983.645 -0.810806 0.170103 -0.560053 --28.9885 -2.40686 -981.055 -0.394698 0.610004 -0.687102 -7.0541 57.8327 -954.376 0.77116 0.63265 -0.0711827 --8.59585 5.06549 -1023.75 -0.962506 0.0840046 0.257927 --8.36669 29.8133 -985.535 -0.833719 0.521858 -0.180493 --17.7674 6.09519 -1010.97 -0.86479 0.484671 0.131272 --32.7993 -4.12325 -974.34 -0.986856 0.160589 0.0180538 -4.58427 33.0533 -930.075 0.636882 -0.30934 0.706179 -0.0614745 41.339 -931.637 0.361146 0.234785 0.902468 --18.3358 57.4826 -953.524 -0.992124 0.0670366 -0.105814 -16.9846 53.8752 -950.916 0.941691 0.298427 -0.155435 -6.23838 58.0742 -959.141 0.152443 0.95015 0.271986 --25.2785 -1.68599 -988.809 -0.975627 0.00777976 -0.219298 --25.6034 -3.74923 -984.693 -0.978313 -0.0777812 -0.191972 --31.8597 -3.28686 -978.496 -0.875882 0.296692 -0.380533 --28.7906 -15.2136 -960.224 -0.759629 0.258399 0.59682 -24.2624 -28.7311 -971.518 0.968192 -0.203208 -0.145985 --6.47543 31.0083 -983.089 -0.34949 0.902833 -0.250497 --26.7922 -4.18383 -983.008 -0.397781 0.281282 -0.873299 --30.5308 -10.6169 -965.588 -0.94911 -0.0812318 0.304289 -6.55491 58.2926 -953.994 0.479655 0.859878 0.174758 --17.9342 4.79722 -1010.55 -0.881822 0.380869 0.278082 --7.23128 31.0704 -982.87 -0.0561815 0.895703 -0.441089 --32.7877 -5.88033 -971.904 -0.96454 0.0931176 0.246964 -4.49281 30.3152 -932.11 0.388822 -0.558258 0.732916 --14.3002 5.17971 -1017.75 -0.926157 0.231339 -0.297852 -2.74965 54.8338 -965.917 0.0619386 0.984596 0.163506 --24.282 -0.891602 -992.689 -0.957393 0.0723505 -0.279578 -5.62266 57.5761 -957.558 0.0748928 0.99701 -0.0190497 -1.29709 -7.77518 -1032.88 0.390576 0.246903 -0.886842 --13.4338 41.5051 -975.742 -0.390628 -0.336573 -0.856813 --6.89096 15.3117 -1002.65 -0.171798 0.883355 -0.436084 --31.7562 -8.36731 -968.673 -0.94473 0.0344079 0.32604 -9.72587 53.3004 -967.913 -0.314858 0.745186 -0.587845 --30.1327 -12.7841 -963.778 -0.933172 0.142672 0.329902 --20.9123 2.67358 -1004.03 -0.825939 0.561086 -0.054831 -4.31691 51.1604 -939.753 -0.0763487 0.906008 0.416319 --21.9825 1.15828 -1000.18 -0.929752 0.367823 -0.0163599 -9.20734 56.7686 -959.518 -0.131464 0.686983 -0.714683 -0.185093 43.4678 -933.626 0.268316 0.553919 0.78815 --4.53371 35.3759 -931.613 -0.103533 0.922876 0.370918 -21.3295 -17.1039 -979.062 -0.0405685 -0.22091 -0.97445 -5.52565 57.69 -957.092 0.173836 0.899137 -0.401664 --20.3173 3.12687 -1006.48 -0.745605 0.665894 0.0256569 --22.6931 -0.218555 -997.351 -0.961882 0.0379532 -0.27082 --25.3291 -3.40393 -987.996 -0.979747 -0.130835 -0.151587 --29.4922 -3.84292 -981.772 -0.413614 0.456754 -0.787591 --30.6158 -3.64773 -980.809 -0.673862 0.415676 -0.610838 --32.6745 -4.19936 -976.097 -0.961955 0.185817 -0.200285 -2.18269 55.3659 -967.105 0.0727609 0.970536 0.22971 --20.3112 -14.1493 -958.372 0.0699594 -0.0209845 0.997329 --14.4812 4.52089 -1017.11 -0.919099 0.315386 -0.236198 --15.4988 4.42341 -1014.75 -0.761951 0.638381 0.109085 --28.7742 -28.6289 -957.884 -0.732825 0.368879 0.571749 -3.2829 54.8603 -965.424 -0.0588745 0.920516 -0.386244 --22.3727 -0.111705 -998.666 -0.980821 0.174379 -0.0870741 -10.0692 21.6913 -982.206 0.413153 -0.215963 -0.884683 --8.44353 5.00024 -1026.68 -0.957999 0.243783 -0.151019 -1.01165 45.4685 -935.068 0.307945 0.516004 0.799318 --25.558 -5.45147 -984.183 -0.812381 -0.2302 -0.535765 -6.14505 58.4407 -955.069 0.524025 0.810548 -0.261553 --20.5794 -30.6043 -951.954 0.00843861 0.891735 0.452479 --15.789 3.78828 -1014.28 -0.666211 0.72283 -0.183519 --18.6518 4.63501 -1012.27 -0.917217 0.397505 0.0265003 --21.9591 1.36544 -1002.25 -0.619966 0.752434 0.222453 --22.331 0.162915 -999.98 -0.860769 0.448762 0.240188 -1.05538 41.4533 -976.355 -0.409337 0.477039 -0.777738 -14.0985 52.2245 -952.479 0.476966 0.409142 -0.777886 --4.5034 43.7287 -977.129 -0.0622131 0.0814803 -0.994731 --32.6944 -7.65114 -971.124 -0.969005 -0.0620811 0.239111 -4.97902 58.0191 -958.916 -0.0317981 0.824618 0.564795 --28.9126 42.2017 -955.073 -0.800179 -0.109777 -0.589629 --14.1585 4.06323 -1018.24 -0.864081 -0.0402279 -0.501742 -5.78255 57.4399 -951.79 0.499292 0.69765 0.513802 --19.2262 3.79135 -1009.05 -0.6876 0.622482 -0.373795 --23.0241 20.2378 -980.361 -0.554879 -0.675539 -0.485547 --25.5406 -6.29177 -983.941 -0.478299 -0.257652 -0.839551 --23.538 -10.6477 -999.127 -0.443645 -0.134157 0.886105 --32.9168 -5.56032 -975.126 -0.991756 0.0225246 -0.126143 --32.9931 -6.73971 -973.044 -0.997637 -0.0138827 0.0672829 -5.15179 58.6395 -959.926 0.188392 0.960069 0.206822 -1.91343 48.3416 -976.126 -0.368362 0.704519 -0.606599 -8.91081 -27.1246 -1004.88 0.541519 -0.743187 0.392977 --14.9823 -29.1537 -1008.88 0.211196 -0.0666888 0.975166 --25.0075 -5.79157 -985.61 -0.953919 -0.27173 -0.127285 -2.90402 52.8993 -945.49 0.29662 0.66687 0.683594 --2.94219 -14.089 -941.167 -0.179559 -0.157478 0.971061 --31.2993 -10.9831 -968.123 -0.945236 -0.157639 0.285796 -0.186381 44.9488 -934.222 0.269685 0.574775 0.772596 --30.5241 -13.3139 -964.956 -0.980234 0.0442251 0.192833 --15.9901 3.66153 -1015.9 -0.709842 0.654975 -0.259097 --29.3675 42.4471 -953.407 -0.992727 0.0494418 -0.109762 -0.00806854 13.5857 -1003.73 -0.181832 0.822854 -0.538375 --1.56938 -14.0656 -941.069 0.0699884 -0.198105 0.977679 --21.9229 1.88827 -1004.23 -0.474896 0.874134 0.101805 --22.5897 -1.34761 -998.884 -0.813866 0.41443 0.407271 --24.3756 -2.8489 -992.443 -0.961942 -0.0277777 -0.27184 --31.3047 -4.86079 -980.38 -0.90717 0.234146 -0.349598 --18.6658 3.50316 -1011.47 -0.900502 0.420082 0.112369 --22.8535 0.315179 -1001.1 -0.438442 0.768784 0.465553 --27.8412 -28.6734 -956.756 -0.601844 0.431642 0.671914 --28.9585 43.4011 -954.772 -0.894363 0.383686 -0.229998 --32.3887 -9.47006 -971.048 -0.959176 -0.214918 0.183827 --31.243 -11.4725 -968.398 -0.965818 -0.207248 0.155703 -5.35962 58.4767 -952.462 0.510591 0.782337 0.356716 --8.78583 3.36232 -1025.34 -0.967884 0.199692 -0.152718 --15.6775 3.20704 -1017.04 -0.504371 0.585631 -0.634544 -4.94488 56.7568 -950.414 0.339586 0.674528 0.655511 --21.6946 2.06315 -1006.44 -0.448281 0.890993 -0.0719432 -3.50641 54.2402 -946.987 0.70918 0.358126 0.607297 --30.194 -5.31417 -982.083 -0.627171 0.244507 -0.739509 -0.631191 55.4447 -967.244 0.0530878 0.995445 0.0791868 --27.255 46.9267 -962.343 -0.515174 0.151616 -0.843569 --16.7559 2.77945 -1014.61 -0.746911 0.644138 -0.164953 --24.8329 -6.07406 -987.46 -0.961658 -0.259597 -0.088446 --2.59301 23.1507 -989.151 0.298751 0.80811 -0.507647 --29.9286 -17.0136 -961.124 -0.88021 0.176035 0.440729 -10.5348 22.4872 -982.51 0.298239 -0.614648 -0.730247 --28.9816 43.0585 -950.819 -0.771741 0.249434 0.584977 --25.5313 -9.63564 -999.035 -0.0603135 -0.200337 0.977869 --23.2547 -1.36602 -999.517 -0.531303 0.51932 0.669346 --12.2247 46.5088 -975.748 0.141866 0.571196 -0.808461 --30.6525 -14.2274 -965.895 -0.99188 -0.115103 -0.0540878 --8.65796 2.87615 -1026.87 -0.990348 0.13855 0.00380854 --11.051 2.50212 -1022.4 -0.432745 0.901275 0.0208534 -17.8325 46.6254 -956.422 0.896749 0.405056 0.178244 -3.52668 58.8911 -960.396 0.0411367 0.999153 0.00132721 --24.2402 -4.53672 -992.588 -0.96651 -0.0852804 -0.242044 --15.7245 36.8568 -976.694 -0.636385 0.764987 -0.0990435 -5.06808 58.1666 -951.519 0.40591 0.752268 0.51897 -18.364 48.0175 -958.814 0.931088 0.0409345 0.36249 -22.5726 -27.3993 -976.828 0.0676408 -0.23596 -0.969406 --29.1597 43.265 -953.568 -0.912435 0.343844 -0.221888 --32.0943 -6.55771 -977.925 -0.906778 0.415693 0.0703784 --24.2031 31.8535 -945.782 -0.719518 -0.499333 0.482659 -4.41604 16.5396 -1002.94 0.0444843 0.628122 -0.776843 -3.58296 58.6743 -959.398 0.0509857 0.856929 0.512906 -4.9864 30.9371 -931.936 0.613722 -0.449367 0.649164 --29.5972 -6.57352 -982.785 -0.619032 0.04213 -0.784235 --32.2885 -7.50341 -976.331 -0.99653 -0.0302938 -0.0775268 --32.8852 -7.95009 -974.665 -0.958617 -0.16953 -0.22872 -3.63822 55.563 -948.106 0.570733 0.598327 0.562378 -1.42857 52.3056 -944.478 0.161358 0.848658 0.503729 --31.9283 -21.7009 -973.9 -0.663558 -0.478367 -0.575201 -4.07925 59.028 -954.788 0.15096 0.974312 -0.167115 --31.2153 -6.30976 -980.734 -0.807029 0.21285 -0.550817 --31.8121 -6.48432 -979.569 -0.899818 0.335069 -0.279386 -3.38916 56.1615 -948.689 0.554044 0.762774 0.333483 -1.079 52.571 -944.71 0.44317 0.387869 0.808182 --26.9422 47.5138 -962.273 -0.644494 0.589966 -0.486381 --11.3486 1.96162 -1023.85 -0.41526 0.622201 -0.663646 --0.471099 55.3495 -967.788 0.0205535 0.954549 -0.297346 -7.84258 49.579 -969.613 0.697547 0.601157 -0.38992 --20.9495 1.88429 -1009.1 -0.537927 0.763528 -0.357294 -4.12686 58.8924 -952.662 0.181451 0.959923 0.213594 --24.2097 -8.0509 -986.973 -0.935941 -0.350905 -0.0296826 --32.8104 -8.93189 -973.654 -0.982193 -0.18147 0.0486383 --22.8212 44.8002 -971.09 -0.437071 0.885161 -0.159556 --11.515 0.360404 -1018.96 -0.749096 0.309764 -0.585578 --21.4069 2.04162 -1007.98 -0.754686 0.655053 -0.0368103 --23.2593 -4.6406 -995.676 -0.951558 -0.0255405 -0.306408 -2.49493 56.9873 -958.228 0.00927256 0.85473 0.518989 --30.6558 -6.78464 -981.536 -0.664749 0.231761 -0.710208 --32.2932 -8.19555 -976.709 -0.961845 -0.0694323 0.264638 --30.9467 -17.9409 -976.172 -0.869547 -0.342617 -0.35567 --30.5356 -14.0464 -968.478 -0.964561 -0.199828 0.17231 -10.6946 -34.5001 -1001.41 -0.896529 0.331399 0.293958 --0.348126 55.3811 -965.593 0.249596 0.946539 -0.204366 --19.4194 2.32811 -1014.02 -0.779207 0.532499 -0.330576 --22.6263 -4.82002 -997.662 -0.999689 0.00679599 -0.0239946 --32.4202 -7.32276 -978.901 -0.922356 0.35273 -0.157612 --2.04737 44.2077 -933.225 0.0398007 0.63219 0.77379 --7.06942 48.7805 -975.411 -0.178901 0.983546 -0.0251235 --25.5547 -28.2567 -955.554 -0.315303 0.473 0.822712 -2.95579 56.762 -949.614 0.493212 0.736783 0.462485 --30.1738 -15.3757 -967.532 -0.991416 -0.119675 0.0526537 -0.479419 52.6667 -944.178 0.360059 0.424449 0.830783 --9.13933 1.47733 -1026.11 -0.960844 0.217597 -0.171552 --23.3478 50.4471 -967.091 -0.505726 0.0731987 -0.859583 --19.5072 1.73329 -1013.05 -0.817538 0.573735 -0.049599 --24.3727 1.16796 -1005.21 -0.318992 0.947136 0.0343049 --24.7554 0.0112452 -1001.98 -0.418338 0.798308 0.43324 --22.6475 -5.2461 -997.902 -0.931458 -0.0103029 0.363703 --17.536 -45.5789 -958.446 0.925986 0.308372 -0.217847 --31.2026 -13.1187 -971.768 -0.91167 -0.383594 -0.147357 --31.1065 -13.951 -970.715 -0.987851 -0.144556 0.0570438 --30.449 -15.0009 -968.637 -0.957331 0.0451553 0.285445 --30.442 -18.9014 -961.975 -0.973125 0.065633 0.220726 --12.3073 -0.243216 -1019.12 -0.311502 0.664433 -0.679334 --24.8337 50.9529 -966.131 -0.799403 -0.096907 -0.592929 --21.9765 50.8135 -967.831 -0.32 0.256497 -0.912036 --17.3419 1.61964 -1016.8 -0.732941 0.64741 -0.208947 --24.9906 0.796296 -1004.12 -0.372054 0.890518 0.261828 -1.69716 58.2494 -958.871 -0.0202828 0.761688 0.647626 --31.9744 -33.3331 -1002.29 -0.135131 -0.203136 0.969781 --30.1824 -8.08537 -982.236 -0.621901 0.289324 -0.727688 --19.9045 -1.51041 -1021.37 0.389302 0.627373 -0.674424 --9.01364 1.79887 -1028.69 -0.970895 0.210062 -0.115051 --17.0194 -46.7926 -954.847 0.98782 -0.0661519 0.140838 -0.277508 51.1657 -941.07 0.312825 0.899749 0.304291 --23.8047 -8.48147 -990.266 -0.951481 -0.298126 -0.0761865 -0.410171 50.117 -938.825 0.294503 0.78897 0.539254 --13.9758 -28.3852 -1008.39 -0.625239 -0.41774 0.659219 --17.693 1.08864 -1015.91 -0.590073 0.748976 -0.301411 --20.2096 1.27217 -1013.39 -0.33403 0.933584 -0.129791 --25.3428 -47.683 -948.731 -0.246756 0.102864 0.963603 --17.452 -47.6864 -954.05 0.989583 0.0485634 0.135525 --30.6148 -18.2131 -964.137 -0.997914 -0.0297692 -0.0572823 --18.8427 -26.0815 -973.486 0.461497 -0.167857 -0.871117 -2.98182 56.3052 -947.547 0.61177 0.669818 0.420809 --25.3747 -1.48801 -1000.24 -0.422325 0.601488 0.678124 -1.31769 56.9907 -957.735 0.227171 0.973751 -0.0142353 --24.4131 1.15363 -1008.1 -0.213616 0.969506 0.120109 --23.6377 -7.65036 -993.399 -0.973253 -0.179391 -0.143515 --25.3132 49.8734 -956.06 -0.579898 0.44703 -0.681089 --30.2583 -17.5226 -967.508 -0.917011 0.166719 0.362349 --0.0432404 51.6288 -942.476 0.398798 0.852818 0.337136 --30.0746 -17.9325 -966.123 -0.997948 -0.00769074 -0.0635699 --8.90437 1.26611 -1029.37 -0.662122 0.426165 -0.616424 --31.0131 -14.5106 -973.161 -0.933165 -0.0325451 0.357972 --9.08622 -1.45451 -1025.02 -0.974344 0.13896 -0.17704 --26.1579 0.0323101 -1003.57 -0.515417 0.799193 0.30925 --31.6361 -8.38825 -981.576 -0.684237 0.246317 -0.686402 --30.1223 -18.316 -966.458 -0.968414 0.130982 0.212174 --4.08311 18.3791 -997.283 -0.21806 0.7385 -0.638018 --9.49764 -1.00974 -1026.78 -0.958363 0.275009 -0.0768767 --2.21003 55.769 -966.825 0.229233 0.951849 -0.203556 -2.28171 59.1208 -953.419 -0.0429458 0.99743 0.0573458 --31.297 -15.7658 -970.505 -0.994367 0.0941007 0.0487873 --31.1146 -16.6367 -969.385 -0.901803 0.185379 0.390366 --30.3076 -21.0461 -961.276 -0.954758 -0.0108163 0.297186 --0.319953 52.3762 -943.643 0.424375 0.676069 0.60236 --9.13646 -1.01079 -1027.6 -0.973963 0.208642 -0.0886835 --26.002 0.643433 -1007.68 -0.356962 0.932062 0.0619541 --26.6027 0.368765 -1005.93 -0.448675 0.886676 0.111786 --29.0328 -7.02115 -1000.71 -0.773542 0.159941 0.613231 --26.0297 -2.85587 -999.727 -0.512834 0.389524 0.765031 --23.2705 -9.82013 -992.912 -0.968106 -0.248556 -0.0314737 --8.58829 48.4171 -975.26 -0.48564 0.868792 -0.0967204 --24.6841 1.8129 -1011.81 -0.0200155 0.997123 0.0731125 --23.0378 -8.43787 -995.862 -0.974975 -0.0716643 -0.210445 --0.126231 5.3934 -1018.54 -0.0420699 0.904768 -0.423821 -13.5142 52.3547 -954.91 0.995507 -0.0415311 0.0850928 --30.5431 -21.6134 -962.53 -0.995868 -0.0348452 0.0838588 --21.7584 -24.1215 -974.955 0.286238 -0.330877 -0.899215 --29.3698 43.9877 -952.38 -0.867783 0.470349 -0.160387 --28.1379 -19.1033 -977.12 -0.156887 -0.437418 -0.885467 --18.4292 0.406648 -1018.28 -0.583638 0.799787 -0.14038 --26.2647 48.69 -961.317 -0.633226 0.741055 -0.223298 --11.5217 -28.3848 -1005.92 -0.594465 -0.597061 0.538636 --5.30381 -15.2788 -943.194 -0.945308 0.0582964 0.320927 --27.1327 -1.22057 -1002.64 -0.630846 0.652813 0.419366 --22.6298 -34.2338 -976.188 -0.178 0.973758 -0.141813 --19.0168 30.8315 -934.279 -0.765271 0.542944 0.345791 -2.01812 58.8665 -952.065 -0.00680346 0.950931 0.309328 --31.7938 -12.8596 -977.701 -0.874195 0.452789 -0.175399 --30.9141 -16.5987 -972.419 -0.990221 0.137004 0.0263028 -1.60132 56.8181 -947.27 0.240726 0.820834 0.51796 -1.28788 55.8932 -945.932 0.333732 0.661827 0.671274 --25.5002 1.69414 -1011.41 -0.290861 0.940031 0.178163 --27.1024 -2.67573 -1000.91 -0.642184 0.510498 0.571831 --19.71 -35.1378 -973.672 0.934416 0.244035 0.259449 --6.01994 41.3754 -931.947 -0.122626 0.558025 0.820714 --31.2917 -19.1476 -968.584 -0.963272 0.148413 0.223788 -2.31289 44.3758 -977.027 -0.358308 -0.104645 -0.92772 --22.8465 -11.3424 -992.222 -0.961681 -0.27055 0.044408 -2.02318 57.2789 -948.504 0.46651 0.828307 0.310285 --18.8725 0.0934029 -1019.2 -0.334542 0.901279 -0.275279 --26.1934 0.803622 -1009.27 -0.37895 0.905542 0.190761 -2.21988 2.5369 -1020.51 0.265365 0.109138 -0.957951 --27.5632 -27.2623 -957.137 -0.564647 0.265996 0.781294 --22.9841 -10.9278 -994.368 -0.984025 -0.170919 -0.0498235 --31.2281 -17.2607 -971.278 -0.983843 0.167308 -0.0637222 --4.09308 44.8351 -934.207 -0.0758769 0.688521 0.721236 --9.27189 -0.714007 -1030.04 -0.934522 0.240906 -0.261979 --2.02651 -15.2841 -940.978 -0.0863334 -0.271094 0.958673 --27.8748 -0.433359 -1006.2 -0.646504 0.730356 0.220485 --19.9152 -34.415 -973.046 0.954977 -0.272297 0.117783 --24.4569 -15.6539 -957.547 -0.106838 0.274436 0.955652 -1.52653 58.0158 -950.315 0.0902151 0.909534 0.40572 --21.2718 -21.4683 -976.063 0.316846 -0.413926 -0.853389 --30.4028 -23.1631 -963.419 -0.998594 0.00445909 0.0528261 --26.426 1.55614 -1012.36 -0.373973 0.923564 0.0846988 -15.5133 46.5819 -948.004 0.903801 0.427689 0.0149905 --28.0678 -3.12423 -1001.71 -0.732003 0.485118 0.478365 --31.5919 -27.8143 -1020.17 -0.97669 0.0229091 -0.213429 --31.3892 -18.8629 -970.152 -0.963426 0.161138 0.214112 --30.5539 -22.8669 -964.281 -0.950687 0.149341 0.271829 --24.6276 1.57023 -1015.1 -0.00114232 0.984007 -0.178128 --25.6768 1.72277 -1013.74 -0.14051 0.988543 -0.0551265 --1.00248 57.7219 -962.404 0.406769 0.702205 -0.584335 --31.3085 -21.2437 -967.104 -0.960574 0.12026 0.250668 --0.341834 57.798 -958.168 0.295392 0.889786 0.347885 --9.05427 -1.66953 -1031.02 -0.653167 0.432951 -0.62123 --20.1664 -0.161376 -1018.79 -0.0949809 0.951476 -0.292698 --27.9219 -6.83457 -999.721 -0.605737 0.106348 0.788526 --31.5408 -19.2733 -970.48 -0.876976 0.0294042 0.479634 --0.250182 58.1336 -958.952 -0.134025 0.921213 0.365246 --22.2103 -25.7424 -955.949 -0.00373529 0.286882 0.957959 --27.907 -0.170442 -1008.76 -0.488737 0.860802 0.141973 --27.4208 45.0103 -950.105 -0.491005 0.637925 0.593267 --28.7017 -2.69969 -1003.38 -0.768506 0.536674 0.348396 --22.5831 -11.3146 -997.655 -0.996968 -0.0463957 0.0624634 --27.2525 10.1378 -965.669 -0.943526 0.157744 -0.291334 --30.9323 -31.149 -1018.8 -0.67184 -0.63133 -0.387369 --24.4812 1.01787 -1017.26 0.0203869 0.955886 -0.293028 --27.9066 0.511164 -1011.45 -0.587495 0.785696 0.193731 --28.816 -1.91368 -1005.12 -0.784901 0.566482 0.251057 -14.7709 42.1671 -944.132 0.988475 -0.0350366 0.147277 -1.31754 4.71022 -1021.39 -0.494955 0.300325 -0.815368 --0.00769186 55.9249 -945.68 0.0923924 0.709423 0.6987 --31.4157 -22.1784 -967.507 -0.993285 -0.025779 -0.112788 --26.9998 -6.53407 -999.207 -0.423168 0.0302961 0.905545 --26.4171 1.42291 -1014.9 -0.22088 0.949808 -0.221531 --28.3788 -4.83302 -1000.78 -0.711424 0.33905 0.615565 -1.57188 2.31504 -1020.91 0.388822 0.869407 -0.304874 --12.8474 -1.87365 -1029.05 0.185415 0.93343 -0.307131 --27.565 0.990664 -1012.88 -0.572945 0.818944 0.032633 --0.519536 58.379 -960.891 0.259802 0.903615 -0.340564 --28.7704 -0.91264 -1008.05 -0.703796 0.694309 0.150353 --0.404235 57.7173 -957.237 0.347025 0.935946 -0.0598183 --31.1823 -21.9536 -968.939 -0.975413 -0.168455 0.142103 -0.63463 57.3006 -947.856 0.115693 0.93657 0.330835 --26.9093 1.27907 -1014.73 -0.419219 0.900525 -0.115367 --29.0443 -4.2471 -1002.36 -0.832287 0.385352 0.3985 --31.9352 -19.1983 -973.802 -0.93367 0.325655 -0.149025 --32.2689 -20.1212 -971.507 -0.958732 0.0230935 0.283371 --1.68322 52.0372 -940.61 0.345525 0.872848 0.344599 --0.488885 58.4388 -959.927 0.0735697 0.995042 0.0669251 -12.421 -9.87866 -951.046 0.774723 -0.50423 0.381518 --24.0048 0.343471 -1019.16 -0.0530876 0.923909 -0.378912 --25.8084 0.875772 -1017.3 -0.268892 0.904583 -0.330798 -17.1678 -16.7569 -959.745 0.0555865 -0.00803331 0.998422 --14.5754 -1.64086 -1029.04 0.0161154 0.972639 -0.231761 --29.5548 -3.53217 -1004.51 -0.869369 0.403228 0.285666 --22.5151 -13.6228 -997.186 -0.998404 -0.0536141 -0.0177599 -21.7566 -36.0088 -974.01 0.807734 -0.267139 -0.525551 --30.9855 -25.6534 -964.854 -0.967458 0.0699191 0.243179 --15.4007 -1.75932 -1027.31 -0.267349 0.90642 0.326997 --28.6937 -0.0592298 -1012.45 -0.738851 0.671495 0.056515 --29.6092 -2.08343 -1007.65 -0.830158 0.537418 0.148392 --12.7515 15.8369 -1001.56 -0.179832 0.598626 -0.780582 --15.7815 -1.71976 -1028.43 -0.200129 0.979728 -0.00902777 -7.38879 12.435 -1003.84 0.520243 0.811314 -0.266678 --28.0394 0.508036 -1014.89 -0.706353 0.696356 -0.127095 --29.3725 -5.71019 -1001.78 -0.848399 0.264876 0.458323 --30.5708 -26.9458 -963.525 -0.95662 0.110148 0.269715 --27.3594 0.513784 -1016.56 -0.504494 0.80791 -0.304576 --23.7012 47.8729 -945.033 -0.76442 -0.478839 -0.431711 --2.14202 53.3078 -943.386 0.351607 0.770082 0.532303 -19.7228 -0.761776 -1002.51 0.244597 0.870157 0.427785 --2.18036 52.7015 -942.105 0.318343 0.879156 0.3546 --31.1394 -24.7808 -967.248 -0.812204 -0.149648 -0.563853 --30.2071 -40.508 -960.738 -0.716486 -0.353426 0.601446 --22.6273 -14.378 -998.184 -0.970997 -0.128793 0.201436 --13.9294 13.6658 -1002.85 -0.914963 0.20088 0.349985 --23.2124 50.2506 -944.052 0.245004 0.78957 0.56263 --28.909 -0.401021 -1014.02 -0.827605 0.552069 -0.101436 --29.2932 -0.883134 -1012.33 -0.835769 0.54579 0.0600245 --30.0282 -3.14458 -1006.83 -0.896035 0.389491 0.213113 --16.6417 -2.00036 -1028.32 -0.43617 0.887483 0.148763 -8.98249 44.6283 -974.019 -0.341067 -0.154332 -0.927284 --16.5908 -2.49513 -1026.84 -0.457167 0.693445 0.556895 --26.416 -0.0673232 -1019.03 -0.296985 0.876229 -0.379503 -0.397107 40.3847 -978.149 -0.0555426 0.898334 -0.435788 --1.37919 58.3515 -957.772 0.312232 0.937212 0.155387 --29.8981 -6.04526 -1002.77 -0.910101 0.272291 0.312369 --16.4761 -2.03582 -1030.3 -0.113165 0.902201 -0.416205 --26.8439 -0.296459 -1018.92 -0.627154 0.615641 -0.477141 --28.4727 -0.330342 -1015.93 -0.77645 0.557877 -0.293086 --30.3414 -3.24431 -1008.44 -0.926463 0.36526 0.0908321 --17.9959 -43.9412 -958.826 0.995968 0.0814093 -0.0376804 --29.585 -1.6105 -1013.74 -0.909231 0.404337 -0.0990429 -15.828 -16.5501 -959.807 -0.147145 0.0254365 0.988788 --3.42625 50.9084 -938.259 0.110874 0.738136 0.665479 --25.5764 -0.638526 -1021 -0.605644 0.664566 -0.437662 --1.65537 58.8234 -959.063 0.334921 0.921075 0.198616 --29.9319 -31.2238 -1020.24 -0.317056 -0.876338 -0.362639 --17.2757 -2.2067 -1030.26 -0.380445 0.810796 -0.444828 --17.6633 -2.96005 -1027.25 -0.516558 0.759975 0.394469 --24.9334 49.3174 -944.191 -0.866946 -0.405877 -0.289254 --30.3111 -2.97145 -1010.28 -0.931149 0.364457 -0.0115143 --0.240089 41.6827 -976.157 0.331579 0.64262 -0.690721 --31.0462 -26.881 -967.139 -0.960931 -0.0500432 -0.272225 --30.9064 -46.3127 -956.831 -0.957697 0.281006 -0.0620615 --2.19769 59.1291 -960.883 0.361589 0.930855 -0.0525553 --30.9462 -29.8379 -964.67 -0.975352 -0.2149 -0.0500563 --18.3689 -3.23419 -1027.95 -0.715321 0.650594 0.255038 --32.5727 -32.0949 -1014.54 -0.841704 -0.365458 -0.397461 --1.14984 58.4991 -953.052 0.012311 0.997987 -0.0622134 --11.465 -2.69834 -1024.35 -0.147554 0.988962 0.0135046 --29.1309 -1.46889 -1015.88 -0.870182 0.454924 -0.189281 --30.082 -8.17935 -1002.18 -0.899407 0.100722 0.425348 --18.2566 -3.70229 -1027 -0.630223 0.753556 0.187006 --33.1934 -32.277 -1012.96 -0.930876 -0.192677 -0.310394 --30.1385 -2.99818 -1013.34 -0.953612 0.284573 -0.0981938 --30.7766 -6.07265 -1006.01 -0.94563 0.258143 0.197856 --14.5655 59.3015 -961.413 0.269329 0.905447 -0.328065 --30.6484 -7.65428 -1003.91 -0.944635 0.174819 0.277674 --25.887 -2.18506 -1021.27 -0.557269 0.504027 -0.659855 --27.6014 -1.66733 -1019.36 -0.634189 0.512475 -0.578942 --1.67863 58.2349 -955.309 0.33578 0.935793 -0.107438 --28.9407 -42.7997 -960.425 -0.847596 0.497133 0.185579 --18.5939 -3.15335 -1029.4 -0.729962 0.682264 -0.0408723 --1.2093 58.0452 -950.756 0.0517295 0.941729 0.332372 --1.2275 57.6679 -949.168 0.120578 0.985701 0.117701 --27.2381 -5.16265 -999.631 -0.541757 0.243928 0.804362 --2.9286 51.8045 -939.506 0.165873 0.822219 0.544465 --28.239 -1.94207 -1018.74 -0.754009 0.461444 -0.467482 --19.1084 -4.15118 -1028.63 -0.902763 0.40352 0.148966 --31.2124 -2.40376 -969.419 -0.941429 -0.112567 -0.317868 -5.19614 -1.92438 -1022.17 -0.156053 0.937035 -0.31243 --24.4247 -2.33793 -1023.9 -0.744336 0.30725 -0.592926 --1.35989 58.4494 -951.677 0.229003 0.946483 0.227437 --26.0117 -0.435653 -981.779 -0.981584 0.0912829 -0.16781 -4.85862 -1.91258 -1021.35 -0.108154 0.946356 -0.304487 --29.9311 -3.08725 -1015.19 -0.934326 0.315624 -0.16558 -22.219 -33.5447 -974.55 0.781971 -0.230213 -0.579244 --21.3045 -33.6007 -974.228 -0.353645 0.917109 -0.183973 --29.4429 -2.89571 -1017.06 -0.880864 0.359938 -0.307447 --3.33883 58.871 -963.126 0.459319 0.739449 -0.49218 --30.1264 -43.9851 -956.523 -0.95233 0.30484 -0.0118549 --26.9813 -30.5136 -971.265 -0.190804 0.613317 -0.766444 --31.2243 -6.40815 -1008.28 -0.966627 0.239588 0.0907225 --23.8484 -3.40565 -1024.87 -0.840309 -0.0870345 -0.535076 --30.2445 -10.5675 -1002.4 -0.837985 -0.108845 0.534728 --31.2563 -8.20913 -1006.05 -0.966398 0.177743 0.185694 --28.3123 -30.874 -971.288 -0.371314 0.844242 -0.386498 --28.5436 -30.972 -970.319 -0.784825 0.619254 0.0239612 --31.1346 -5.8371 -1010.98 -0.963901 0.264856 -0.0273187 --29.0475 -34.1945 -964.57 -0.542532 -0.0201924 -0.839792 --29.7557 -37.7495 -964.315 -0.405215 0.705899 -0.580954 --31.2143 -9.19076 -1005.21 -0.965746 0.0818576 0.246242 --26.5586 -31.6157 -973.8 0.12469 0.934828 -0.332489 --3.79844 53.5822 -943.04 0.139119 0.836431 0.530121 --3.65952 53.1168 -942.199 0.321137 0.861165 0.394038 --27.3271 -3.77049 -1021.41 -0.638017 0.427363 -0.640542 --5.39136 59.4644 -963.704 0.173457 0.681451 -0.711011 --27.3502 -31.4724 -973.454 -0.111276 0.953201 -0.281113 -12.2488 35.7797 -980.047 0.410135 0.0153809 -0.911895 --28.7413 -3.75875 -1019.5 -0.823669 0.323876 -0.465482 --2.93014 58.5222 -956.428 0.162907 0.973693 -0.159319 --30.9104 -10.525 -1003.92 -0.941966 0.0257141 0.334723 --21.2791 -33.7519 -977.75 -0.177371 0.971439 -0.157623 -25.3622 -35.3138 -1001.18 0.522428 0.293516 0.800573 -15.826 -29.6958 -1002.29 -0.00654575 0.897788 0.44038 --25.8902 -36.4866 -966.267 -0.809332 0.0291718 -0.586627 -4.256 -1.96089 -1022.27 0.187109 0.977955 -0.0927045 --23.8553 13.559 -973.632 -0.82781 -0.4909 -0.271564 --2.05616 57.8764 -949.615 0.155139 0.937908 0.310259 --27.2743 -36.7175 -965.14 -0.479763 -0.0181537 -0.877211 --31.2353 -6.7198 -1012.39 -0.976101 0.146663 -0.160363 --3.70521 52.3094 -940.216 0.210038 0.887182 0.410843 --21.9364 -34.2073 -978.904 -0.253644 0.902287 -0.348629 --26.1451 -37.4314 -966.45 -0.861256 0.481534 -0.16237 --28.2521 -5.02549 -1020.94 -0.739758 0.255943 -0.622295 -4.05525 21.6618 -993.195 -0.24868 0.927892 -0.277802 -17.9106 46.0961 -957.204 0.934843 0.11979 -0.334244 --26.7322 -37.6176 -965.675 -0.644955 0.324937 -0.691699 --26.7218 -37.9704 -965.976 -0.552657 0.706403 -0.442229 --7.78011 45.2776 -934.816 -0.322697 0.432971 0.841667 --30.3533 -6.0101 -1017.09 -0.951724 0.219515 -0.214559 --31.8002 -8.40071 -1010.83 -0.962674 0.267593 -0.0406496 --3.09313 59.1551 -955.167 0.367726 0.871489 -0.324475 -18.658 -16.9539 -959.966 0.178532 0.0777954 0.980854 -11.6037 -24.0652 -1004.3 0.661032 -0.710334 0.24179 --31.8361 -8.92805 -1008.89 -0.980378 0.139037 0.139742 --18.2917 10.1928 -1000.87 -0.22625 0.290045 -0.929884 --22.2166 45.0231 -969.417 -0.372802 0.921594 -0.108087 --30.8257 -35.723 -963.404 -0.803691 0.0952018 -0.587382 --28.3497 -37.4552 -964.651 -0.400503 0.389278 -0.829494 --30.836 -7.19425 -1015.81 -0.985526 0.0209937 -0.168219 --27.5821 -38.38 -965.985 -0.295058 0.937659 -0.183673 --28.9509 -6.0708 -1020.31 -0.829107 0.138083 -0.54177 --29.8731 -6.2778 -1018.7 -0.896979 0.213205 -0.387261 --31.9178 -9.06642 -1011.37 -0.866178 0.395502 -0.305473 --26.2016 -37.2339 -969.976 -0.820804 0.560611 0.109526 --3.65662 59.6301 -960.699 0.180642 0.969635 0.164853 --4.22862 58.4334 -956.959 -0.227923 0.955666 -0.186421 --12.9426 56.7692 -963.347 0.235609 0.336973 -0.911558 --31.3184 -35.6792 -962.299 -0.958655 0.114502 -0.260518 --18.1549 5.01352 -1012.83 -0.546052 0.604496 -0.58001 --28.57 -38.218 -965.051 -0.242714 0.768464 -0.592075 -12.5277 55.1914 -953.245 0.739997 0.669707 -0.0624251 -19.9028 -45.0189 -959.993 0.110919 0.74131 0.661934 -22.0016 -23.1012 -977.967 -0.0459956 -0.213483 -0.975864 --2.95003 59.4373 -953.475 0.428774 0.901055 -0.0652048 --23.2089 -34.9934 -979.643 -0.182862 0.896242 -0.404117 --29.0402 -32.3965 -976.015 -0.316531 0.934367 -0.163606 --27.1917 -38.2802 -969.219 -0.540905 0.839465 0.0521547 --4.78213 59.7958 -962.892 0.27862 0.896959 -0.343271 --31.1803 -13.9989 -1005.21 -0.899586 -0.155346 0.408182 -19.8827 16.4951 -971.075 0.733409 0.223545 -0.641981 --29.2654 -32.6016 -977.122 -0.413247 0.902952 -0.117915 --14.2285 14.5825 -998.475 -0.756013 0.648569 0.0883316 --31.5836 -13.1187 -1006.35 -0.979058 0.0944396 0.18035 -16.7702 54.7261 -950.752 0.845997 0.384751 -0.369127 --13.7831 -26.5096 -1006.9 -0.635874 -0.540258 0.551167 --22.471 -12.815 -998.466 -0.960631 -0.00676789 0.277746 --30.6024 -8.78407 -1015.88 -0.973572 0.0333257 -0.225934 -24.878 -49.0402 -957.879 0.243265 0.15149 0.958057 --29.3705 -38.6929 -966.179 -0.23088 0.939287 -0.253837 --30.2848 -7.94337 -1018.32 -0.945735 -0.00648011 -0.324874 --30.7384 -9.24167 -1015.7 -0.831641 0.440026 -0.338748 --22.9923 -35.9644 -981.376 -0.156611 0.813384 -0.56025 --3.24661 58.0506 -964.117 0.441263 0.641902 -0.627096 --31.9137 -9.68768 -1013.71 -0.843932 0.488316 -0.222096 --11.2619 41.7211 -932.029 0.269964 -0.253259 0.928967 --12.958 18.7469 -996.086 -0.604765 0.305418 -0.735513 --27.9902 -38.5698 -969.482 -0.353748 0.93292 -0.0672544 --5.74281 52.0391 -939.661 -0.0228853 0.850521 0.525442 --32.4195 -11.1517 -1011.1 -0.991234 0.122318 0.0499331 --27.5354 -38.0244 -972.157 -0.62271 0.740592 0.252499 --26.6338 -9.05334 -1023.61 -0.721155 0.101053 -0.685364 --29.8344 -8.56176 -1019.26 -0.849046 -0.00863244 -0.528248 -13.5516 53.9175 -952.093 0.464056 0.367471 -0.805989 --32.3007 -10.5462 -1013.41 -0.945313 0.293233 -0.142824 --30.4302 -33.4961 -977.098 -0.882161 0.430005 0.19206 --30.4277 -9.93394 -1017.03 -0.825365 0.333157 -0.455828 -16.2781 -31.6646 -998.157 -0.251349 0.600019 0.759474 --0.67793 39.2746 -933.154 0.572054 -0.661605 0.484802 --27.6996 -9.59937 -1022.39 -0.809714 0.00956278 -0.586747 --5.88918 54.674 -944.786 0.18766 0.866475 0.462606 --32.3442 -13.381 -1009.38 -0.982031 0.0392493 0.184593 --31.9954 -14.3195 -1007.74 -0.973453 -0.043759 0.224666 --30.1985 -32.7513 -963.622 -0.779664 -0.178811 -0.600126 --28.2256 -38.2481 -972.847 -0.522814 0.763868 0.37838 --28.5984 -38.9507 -971.505 -0.536827 0.829082 0.15633 --30.319 -39.1625 -967.273 -0.443129 0.895264 -0.0462523 -7.51156 -18.5751 -968.217 -0.48494 -0.86508 0.128338 --5.80274 55.4504 -946.429 0.155075 0.941362 0.299648 --31.7311 -15.4291 -1007.23 -0.935353 -0.198132 0.293017 -11.7876 -25.9645 -1006.09 0.104718 0.186737 0.976813 --30.2654 -33.3464 -979.336 -0.441061 0.822933 -0.358116 -16.4266 -25.7862 -1007.55 0.229158 0.794881 0.561828 -0.466848 3.49063 -1020.46 -0.296472 0.234074 -0.925913 --29.8159 -38.9621 -969.034 -0.311757 0.944018 -0.107879 --30.1306 -10.6623 -1017.89 -0.752048 0.272374 -0.600196 -11.8664 44.2164 -974.869 0.383893 -0.00254333 -0.923374 -9.18056 50.5957 -968.314 -0.0451969 0.175732 -0.9834 -11.1147 -33.8086 -1004.25 -0.994248 -0.0397111 -0.0994649 --29.5124 -10.0279 -1019.62 -0.899844 -0.147504 -0.410515 --5.4588 59.7863 -960.38 0.0511084 0.92882 0.366989 --30.905 -39.675 -967.465 -0.839234 0.538548 0.0751861 --30.6068 -33.7087 -979.386 -0.764014 0.513733 -0.390335 --29.4037 -11.3149 -1019.06 -0.850261 -0.0729662 -0.52128 --32.0023 -11.2703 -1015.95 -0.869789 0.387782 -0.305108 --32.3983 -11.7364 -1014.82 -0.959528 0.203879 -0.194267 -15.5348 53.1942 -952.006 0.216584 0.265379 -0.939503 --22.9776 43.0444 -972.85 -0.385176 0.0102361 -0.922786 --30.4875 -39.3007 -969.369 -0.545595 0.819754 -0.174154 --31.2805 -11.2002 -1017.27 -0.650322 0.494075 -0.577036 -19.7327 -47.6243 -956.462 -0.525137 0.488114 0.69712 -15.0377 -23.7847 -959.325 -0.144992 -0.05599 0.987847 --32.6669 -13.6037 -1011.57 -0.99739 0.0300983 0.0656246 --27.1446 -36.3939 -981.44 -0.0569489 0.694954 -0.716796 --6.1539 60.1769 -961.91 0.0336702 0.998658 0.0393454 --30.5119 -36.4875 -976.142 -0.506959 0.431727 0.746059 --30.2691 -39.9021 -971.38 -0.530536 0.847223 0.0273036 --31.1543 -39.956 -969.029 -0.823532 0.564127 -0.0596352 --31.2053 -34.9601 -979.061 -0.908532 0.413918 -0.056935 -25.8892 -35.3243 -1004.31 0.891452 -0.371111 -0.259981 --31.1654 -35.3586 -977.549 -0.841224 0.366731 0.397305 --11.2598 44.6985 -933.679 0.633385 0.614893 0.469818 --18.7056 10.3822 -1000.52 -0.643541 0.529143 -0.553048 --11.0501 54.6995 -967.481 0.246629 0.940137 -0.235195 --4.89098 59.5725 -951.718 0.110159 0.875953 0.46965 --30.9796 -35.2816 -979.894 -0.704075 0.3968 -0.588921 --18.1284 -17.3403 -958.444 0.573531 0.196579 0.795248 --11.8947 54.583 -968.486 0.108688 0.897346 -0.427735 --31.8703 -12.3636 -1017.26 -0.863518 0.302894 -0.403227 --32.6495 -13.3856 -1014.69 -0.991833 0.0857243 -0.0944349 --32.5922 -15.2456 -1011.28 -0.986561 -0.115665 0.115408 --5.33507 60.1761 -954.122 0.191619 0.969966 -0.149826 --5.15619 60.0625 -953.134 0.0960169 0.976983 0.190488 --27.8624 -13.4838 -1021.13 -0.857463 -0.014842 -0.514331 -8.15265 55.8299 -960.826 0.806074 0.0802154 -0.586354 --32.1122 -16.7055 -1009.98 -0.951829 -0.243136 0.186831 --31.3248 -36.9704 -976.502 -0.688738 0.44741 0.570494 --30.9143 -40.4931 -971.574 -0.744412 0.667649 0.00975702 --25.3441 -13.2118 -1025.36 -0.677493 0.0641448 -0.732727 --25.0872 -5.22423 -998.71 -0.201397 0.148441 0.968196 -22.1287 -45.9509 -957.858 0.352841 0.831441 0.429196 --29.9936 -35.8909 -980.727 -0.297849 0.436813 -0.848811 --7.457 54.6095 -944.294 0.0376674 0.779178 0.62567 --28.1292 -13.881 -1020.89 -0.460355 0.573905 -0.677279 --22.221 -14.8296 -1027.8 -0.449194 0.860561 -0.240125 --32.1502 -13.2803 -1017.08 -0.956414 0.146346 -0.252698 -15.7108 -22.9914 -1008.15 0.0726712 -0.763416 0.641807 --27.2016 -38.2713 -983.283 -0.319078 0.540689 -0.77836 --31.0687 -38.3431 -975.077 -0.585345 0.561564 0.584823 --30.8702 -39.8455 -973.194 -0.604925 0.691921 0.394095 --22.3649 -14.6825 -1027.36 -0.477599 0.388123 -0.7882 -19.0733 -25.316 -1010.77 0.6748 0.211058 0.707177 --7.26406 56.1059 -947.443 0.360112 0.932806 -0.0138946 --18.4404 -43.4172 -952.596 0.976953 0.206363 0.0545662 --28.9326 -37.0252 -981.607 -0.245855 0.539323 -0.805411 --24.9226 -24.3749 -956.432 -0.0847994 0.105133 0.990836 --32.2026 -36.9077 -978.567 -0.923222 0.366792 -0.114565 --32.6698 -14.867 -1014.73 -0.99909 -0.00319459 -0.0425235 -19.1756 -23.3661 -1008.65 0.192001 -0.805025 0.561312 --32.3778 -37.3906 -977.828 -0.868674 0.437972 0.231485 --22.9572 -15.3599 -1029.04 -0.368436 0.751622 -0.547101 --26.5566 -14.876 -1023.36 -0.846637 -0.00962598 -0.532084 --26.9143 -15.0233 -1022.96 -0.539142 0.543288 -0.643556 --29.0414 -14.5045 -1021.45 -0.226387 0.749773 -0.621764 --32.669 -15.7062 -1013.85 -0.994064 -0.108682 -0.0049094 -1.54748 55.4072 -964.236 0.216798 0.885349 -0.411286 --23.6619 -15.7402 -1027.14 -0.587371 0.725002 -0.359676 -24.579 -22.4633 -977.795 0.394794 -0.219125 -0.892257 --32.4985 -42.7804 -968.824 -0.92463 0.301113 0.233219 --24.5963 -15.6658 -1026.16 -0.565663 0.314383 -0.762358 --24.4263 -15.9549 -1026.48 -0.681758 0.316614 -0.659516 --31.047 -14.4651 -1020.04 -0.627474 0.501424 -0.595693 --1.28578 -21.5962 -1035.12 0.134772 -0.235701 -0.962435 --32.8701 -38.9771 -976.841 -0.889193 0.388963 0.240922 --25.6196 -16.374 -1025.1 -0.557333 0.615085 -0.557719 -4.62874 21.9332 -992.394 -0.0717707 0.722752 -0.68737 --31.8399 -38.1106 -980.854 -0.727654 0.351179 -0.589231 --32.3051 -41.5118 -973.309 -0.781271 0.515861 0.351429 --29.8721 -15.234 -1021.88 -0.413394 0.657054 -0.630385 --10.3117 57.3715 -959.291 0.13836 0.871899 0.469732 --9.14161 56.1494 -949.892 0.120137 0.966567 0.22653 --8.51586 56.5137 -947.923 0.288634 0.916501 -0.276978 --32.4298 -42.4754 -971.564 -0.895308 0.441293 0.0606967 --10.9822 50.365 -938.674 0.115032 0.798203 0.591304 --24.4513 -16.0561 -1028.64 -0.485025 0.725183 -0.488735 --30.5473 -38.7242 -982.148 -0.345713 0.516092 -0.783665 --32.4706 -38.5479 -980.128 -0.859602 0.3068 -0.408604 --27.2885 -16.3923 -1024.57 -0.196756 0.875962 -0.440428 --8.98359 55.573 -945.184 -0.0608002 0.602831 0.795549 --31.8133 -15.4102 -1019.16 -0.916966 0.179294 -0.356408 --0.0444005 32.9649 -982.242 0.0867256 0.788324 -0.609117 --32.2153 -18.17 -1014.38 -0.967108 -0.251352 0.0390459 --32.8777 -40.8643 -974.877 -0.830162 0.381428 0.406625 --32.946 -43.4967 -970.074 -0.963056 0.262133 0.0617195 --32.2638 -16.049 -1017.54 -0.980645 0.0211657 -0.194649 --8.85114 56.2123 -945.906 0.110816 0.831468 0.544408 --28.7625 -39.9807 -983.918 -0.401218 0.300342 -0.865343 --31.3085 -38.9405 -981.814 -0.534997 0.400447 -0.743923 --19.7667 -17.9103 -957.836 0.378644 0.184678 0.906931 --10.7918 58.0274 -960.516 0.131428 0.950697 0.280894 --32.8638 -42.9321 -973.145 -0.916843 0.294348 0.269738 --9.05712 56.8448 -947.137 0.307465 0.934283 0.180503 -10.1102 -16.6258 -1029.54 0.484134 -0.407832 -0.774137 --11.3402 51.749 -941.135 -0.062948 0.714503 0.696795 --33.1528 -39.7205 -979.164 -0.952822 0.175548 -0.247614 --33.4475 -40.4671 -977.268 -0.967106 0.233633 0.100609 --14.9122 55.051 -968.323 -0.00338117 0.963058 -0.269274 --25.3486 -30.8063 -1004.05 0.0290436 0.957105 0.288281 --30.585 -40.0544 -982.867 -0.61636 0.20595 -0.760056 --31.858 -39.6469 -981.578 -0.743605 0.215076 -0.633083 --33.0038 -45.8994 -969.094 -0.987704 -0.0257697 0.154194 -25.3739 -31.8973 -1003.71 0.354947 0.881357 0.311805 -13.6918 51.1258 -957.309 0.840796 0.264401 0.472392 --27.921 -16.7836 -1025.1 -0.394877 0.847517 -0.354665 --27.3518 -25.1276 -1012.33 -0.366252 0.809125 0.459539 --10.942 58.0894 -960.987 0.0784597 0.98048 -0.180288 --30.2521 -16.7858 -1022.96 -0.724832 0.386859 -0.570052 --12.2167 52.2981 -943.131 -0.00239262 0.960835 0.277109 --33.0097 -44.1024 -972.702 -0.984356 0.119137 0.129809 -3.22574 -0.929385 -1023.26 0.862697 -0.108134 -0.494025 --27.3 -17.0015 -1026.92 -0.555847 0.685175 -0.470713 --5.85311 39.4922 -982.921 0.148458 1.0276e-005 -0.988919 --31.6723 -17.0918 -1020.08 -0.957648 0.0234111 -0.286987 --27.264 -27.6303 -1007.79 -0.28401 0.707928 0.646665 --8.63259 -19.0089 -1036.59 -0.121175 -0.0891051 -0.988624 --32.1012 -18.311 -1017.85 -0.985097 -0.125967 -0.117115 --12.7523 48.965 -936.545 0.18264 0.667419 0.721938 --33.6039 -42.0529 -976.404 -0.999117 -0.00834201 0.0411701 --27.978 -17.1489 -1026.3 -0.654221 0.571661 -0.495175 --30.9206 -17.1147 -1022.01 -0.854531 0.204453 -0.477468 --28.3153 -25.9473 -1010.67 -0.277025 0.84731 0.453126 --26.9483 -30.9207 -1003.33 0.00849947 0.991954 0.126315 --24.2814 43.7515 -971.82 -0.694179 0.522758 -0.494812 --28.4064 -31.0308 -1002.01 -0.0511527 0.971759 0.230366 -16.7612 -25.2556 -1008.62 0.389843 0.658688 0.643547 --32.5211 -40.6554 -980.923 -0.82787 0.105008 -0.551003 -8.35644 50.122 -968.503 0.397839 0.397397 -0.826922 --27.5984 -29.2063 -1006.44 -0.355199 0.574834 0.737156 --27.5931 -30.5344 -1005.14 -0.145517 0.908263 0.392278 --33.4725 -41.6651 -978.469 -0.984634 -0.00308231 -0.174605 --14.3619 13.1078 -1005 -0.896763 0.0410918 -0.440599 --27.5569 -30.034 -1005.88 -0.288974 0.66528 0.688402 --14.0563 15.6158 -998.75 -0.953916 -0.12441 0.27307 --28.1164 -30.8847 -1003.8 -0.0959531 0.987956 0.121395 --29.7489 -17.8989 -1024.41 -0.786009 0.279576 -0.551387 --15.6753 45.9149 -934.697 -0.117396 0.712678 0.691598 --3.77374 13.873 -1006.72 0.0760694 0.766513 -0.637708 --29.0496 -27.1118 -1009.43 -0.417783 0.70507 0.573005 --29.6597 -31.331 -1001.41 -0.264688 0.869048 0.417967 --25.5969 -17.7973 -957.233 -0.294878 0.196878 0.935033 --31.6355 -19.8724 -1018.74 -0.948526 -0.313955 -0.0416119 --29.5107 -26.1128 -1011.59 -0.423105 0.853104 0.30528 --29.5841 -26.7392 -1010.39 -0.531103 0.726099 0.436702 --31.4651 -19.2623 -1020.68 -0.969668 -0.119094 -0.213448 --12.3038 57.3522 -958.176 0.28138 0.921186 0.268777 --29.1244 -24.8509 -1015.46 -0.581029 0.75623 0.300868 -2.49787 1.86176 -1020.54 0.776654 0.548346 -0.310042 --22.4157 -17.9423 -956.974 0.14958 0.244772 0.957973 -2.3095 3.82834 -1021.41 0.0124342 -0.410974 -0.911562 --30.2027 -26.3154 -1012.24 -0.622071 0.736562 0.265526 --30.2479 -27.9434 -1009.55 -0.603211 0.605922 0.518648 --29.4155 -28.7648 -1007.98 -0.520256 0.537904 0.66332 --29.0572 -29.8675 -1006.94 -0.513683 0.58086 0.631452 --2.96507 52.5246 -971.363 0.398482 0.110861 -0.910451 --12.777 58.2796 -962.673 0.211384 0.820255 -0.531505 --12.8003 58.4663 -960.973 0.514315 0.853704 0.0816739 --29.2486 -24.1825 -1017.15 -0.680155 0.68497 0.261162 --29.3225 -30.6256 -1006.07 -0.441698 0.813685 0.377914 --11.5621 56.6946 -949.799 0.130433 0.942738 0.306973 --30.5529 -31.2455 -1002.91 -0.388701 0.914448 0.112678 --30.0064 -31.0408 -1005.18 -0.295947 0.948982 0.108852 --30.7817 -32.3446 -1001.07 -0.557513 0.459045 0.691705 --31.1577 -31.925 -1001.92 -0.709662 0.534243 0.459309 --13.359 58.5695 -961.684 0.236003 0.897866 -0.371671 --29.1753 -20.9196 -959.143 -0.787909 0.0688837 0.611927 --19.339 -5.29774 -1027.93 -0.700601 0.332073 -0.631575 --31.12 -27.8306 -1011.08 -0.718279 0.607402 0.339318 --30.3626 -30.3346 -1008 -0.52405 0.578901 0.624696 --28.838 -20.6906 -1026.89 -0.778223 0.383008 -0.497669 --30.7645 -25.9942 -1015.31 -0.674048 0.723585 0.148604 --13.7218 52.0164 -940.84 0.112474 0.903604 0.41334 --31.8854 -32.1759 -1002.99 -0.529585 0.763345 0.369925 -10.8553 -34.96 -1000.78 -0.863416 0.149536 0.481821 --26.0806 -21.1302 -1031.13 -0.420297 0.767089 -0.48469 --30.0674 -24.2276 -1020.12 -0.875088 0.462584 0.14226 --0.44668 3.53899 -1020.55 0.377324 0.689497 -0.61824 --30.3832 -25.3446 -1017.36 -0.719207 0.675689 0.161817 -7.60391 -23.9255 -1030.56 0.279663 -0.120653 -0.952487 --29.2817 -21.2952 -1026.38 -0.885989 0.221827 -0.407207 -2.02109 40.7235 -977.589 -0.25439 0.751451 -0.608775 --23.6866 49.63 -942.766 0.364568 0.71861 0.592191 -4.44757 24.5114 -988.3 0.229145 0.9719 0.0538728 --6.64228 41.0115 -981.318 -0.0270285 0.949718 -0.311937 --4.1283 41.3178 -978.762 -0.0567819 0.841667 -0.537003 --4.50884 41.2112 -979.043 0.0666157 0.973944 -0.216787 --13.33 58.6815 -959.367 0.738483 0.592702 0.321478 --29.7413 -41.0559 -965.682 -0.793124 -0.526347 0.306454 --2.70259 41.028 -978.804 0.25948 0.818768 -0.512143 --3.93648 40.5476 -980.758 0.34834 0.843804 -0.408232 --0.820737 40.3875 -978.187 0.246927 0.82103 -0.51472 --4.74417 40.4516 -981.972 0.3149 0.78811 -0.528886 --31.0691 -28.9022 -965.633 -0.993217 -0.102276 -0.0553173 --18.4059 -50.304 -960.278 0.147318 -0.925136 -0.349888 --3.92062 39.7656 -981.94 0.431754 0.61026 -0.664207 --2.75287 39.6562 -981.535 0.389847 0.659026 -0.643198 --1.34506 32.313 -984.051 0.0239324 0.953991 -0.29888 --3.82825 31.9297 -986.74 0.257661 0.805756 -0.533262 --0.514992 32.2065 -983.757 0.171054 0.900058 -0.400795 --14.6944 51.3489 -939.198 0.0676848 0.866175 0.495136 --3.75323 31.5509 -987.146 0.316463 0.586087 -0.745891 --13.6925 58.51 -958.601 0.426003 0.783305 0.45272 --0.720713 31.6194 -986.167 0.314513 0.791267 -0.524383 --12.8622 57.4826 -951.023 0.102698 0.85401 0.51002 -12.8269 -31.101 -1002.18 -0.552384 0.68142 0.480145 -6.69853 33.1676 -981.674 0.679114 0.672192 -0.294894 -5.02222 32.6709 -983.33 0.0379586 0.825174 -0.563601 --12.1936 23.4379 -988.83 0.122842 0.912487 -0.390226 -4.92488 32.3734 -984.088 0.080809 0.967241 -0.240655 --13.8168 59.1666 -960.427 0.28078 0.949292 0.141448 -7.65383 31.7626 -981.28 0.817931 0.531972 -0.219077 -6.63044 31.8511 -984.115 0.557049 0.748911 -0.358927 --14.985 52.3853 -941.809 0.0210737 0.970117 0.241719 -7.98829 31.1658 -983.449 0.705178 0.64471 -0.295081 -7.03151 30.7829 -984.608 0.815199 0.392452 -0.425949 -6.46017 31.7221 -985.892 0.420719 0.824276 -0.3789 -8.60934 30.687 -982.364 0.544343 0.832638 -0.102004 -18.7364 24.5986 -957.105 0.856664 -0.4853 -0.174957 --24.1876 -18.216 -956.905 -0.0702811 0.191823 0.97891 -6.23591 31.1683 -986.561 0.358894 0.591751 -0.721821 -12.9479 30.945 -978.116 0.623804 0.270676 -0.733214 -7.10686 29.4179 -984.99 0.802111 0.32575 -0.500505 -11.5754 14.3154 -948.947 0.922925 -0.0946473 0.373164 -14.4682 28.9471 -974.981 0.509636 0.786322 -0.349239 -14.0493 16.9565 -953.475 0.924957 0.0489108 0.376912 -14.86 18.5485 -955.679 0.94331 -0.279756 0.178614 --14.5133 58.0195 -957.576 0.161956 0.928625 0.333805 -24.2105 -34.6081 -1000.24 0.894391 0.177295 0.410648 --13.4825 58.7502 -953.413 0.34409 0.937915 0.0437881 -14.5861 28.8714 -976.234 0.730557 0.682845 -0.00292918 -26.2003 -33.1185 -1002.28 0.523993 0.641602 0.560159 --30.7152 -33.5852 -1000.55 -0.788592 0.132618 0.600446 -11.0951 30.1557 -983.8 -0.102519 0.937488 -0.332576 --10.9727 20.5266 -993.312 0.185573 0.961618 0.202125 -12.1626 13.1358 -949.623 0.830775 0.2715 0.485901 -5.3259 21.355 -992.157 0.828835 -0.14747 -0.539708 --11.6846 20.7023 -994.884 0.145573 0.951028 -0.272681 --0.877119 3.33231 -1021.41 0.65688 0.683981 -0.317299 -23.8384 -11.8866 -979.514 0.258665 -0.18065 -0.948925 -16.897 26.6452 -969.37 0.960955 0.276668 0.00449608 --20.8206 43.1594 -973.083 -0.128028 0.458143 -0.87961 --16.835 53.0463 -944.721 0.0225278 0.961705 0.273161 -5.8418 52.4392 -970.901 0.442245 0.263009 -0.857464 --13.8265 58.2057 -951.685 0.311011 0.763108 0.566514 -15.5851 19.1007 -958.191 0.951549 0.0394296 0.304958 -17.271 27.269 -970.849 0.97431 0.166824 0.151295 -13.1898 30.0502 -982.376 0.529398 0.784821 -0.322169 --14.2511 59.0569 -953.01 0.361389 0.912726 0.190602 -12.3905 30.1341 -983.108 0.315596 0.887889 -0.334742 -0.117349 5.33802 -1018.93 -0.455626 0.86887 -0.19357 --10.4745 20.4023 -994.314 0.477175 0.875394 -0.0773971 --10.775 20.4301 -994.78 0.513804 0.733861 -0.444357 --11.6959 19.8974 -995.953 0.208614 0.589586 -0.7803 --15.5796 59.4396 -960.984 -0.0385165 0.999044 -0.0206729 --15.1341 -38.7541 -949.62 0.955075 -0.218947 -0.199736 -11.0636 29.8835 -984.255 0.000977252 0.763972 -0.645249 -17.388 25.7273 -968.657 0.733173 0.651844 -0.193796 -17.0431 27.7976 -972.98 0.796019 0.599501 0.0833842 -14.2307 29.0419 -979.352 0.657924 0.639587 -0.397574 -14.0102 29.5411 -981.931 0.663677 0.745109 0.065918 --14.8285 58.4434 -951.324 0.103385 0.775123 0.623294 -15.8056 18.1573 -958.184 0.862062 0.309568 0.40127 -16.9872 28.3663 -975.063 0.459422 0.888045 -0.017556 -4.33147 1.2917 -1018.84 0.327509 -0.0974364 -0.939811 --15.2496 59.4783 -953.421 0.115008 0.985255 -0.12667 -15.4656 27.8594 -977.896 0.614267 0.705187 -0.354101 -14.2552 28.3959 -980.17 0.80143 0.59228 -0.0831541 -12.6633 29.1348 -984.129 0.558062 0.558697 -0.613534 -16.3066 19.8995 -960.664 0.946728 0.137544 0.291183 -18.0505 25.2493 -968.964 0.388964 0.757673 -0.52406 -13.1095 11.5758 -949.799 0.82355 0.451496 0.34339 --18.2395 54.8705 -948.446 0.415442 0.847871 0.329429 --3.12455 21.3828 -990.942 0.102528 0.720137 -0.686215 -18.0846 26.2298 -972.185 0.808298 0.491871 0.3236 --23.1451 13.045 -975.19 -0.913649 0.152188 -0.376939 --18.4754 54.0107 -946.519 0.136951 0.873891 0.466432 -15.1648 27.6155 -979.577 0.863728 0.41787 -0.281706 -3.11792 1.73128 -1019.94 0.622775 -0.132626 -0.771078 -14.6511 28.7028 -982.01 0.849517 0.474881 -0.229801 -4.83788 24.0561 -986.572 0.775075 0.611037 0.16091 --11.6308 18.023 -997.214 0.288656 0.955168 -0.0658218 --25.3752 -3.01791 -999.373 -0.302312 0.346835 0.88787 -16.5895 18.8717 -960.589 0.827317 0.433653 0.35706 -18.3825 26.5854 -972.998 0.677972 0.583895 0.446565 -15.3613 26.9121 -979.124 0.899739 0.293278 -0.323198 -4.86812 24.1828 -987.029 0.363087 0.921089 0.140582 --12.9815 18.2717 -999.169 -0.0438809 0.99874 -0.0243387 -13.4964 10.7952 -949.666 0.903907 0.423445 0.0603883 -3.93818 24.552 -988.858 -0.153147 0.959243 -0.237485 -6.21916 50.8077 -970.53 0.703381 0.128072 -0.69918 --16.57 4.5103 -1012.85 0.190563 0.273917 -0.942685 -17.479 27.7416 -977.264 0.557484 0.7591 -0.336124 -14.8985 27.2701 -981.639 0.989535 0.143514 -0.0149967 -18.5927 -22.2501 -959.444 0.306249 0.0127054 0.951867 -18.5143 27.2667 -975.291 0.71241 0.701762 0.00136266 -20.9909 -2.56352 -1000.58 0.284263 0.723357 0.629245 -14.8424 27.9449 -982.691 0.889865 0.284981 -0.356267 -18.8464 24.1398 -970.257 0.894657 0.445203 0.0371843 -18.7831 24.6043 -972.18 0.913522 0.215492 0.345022 -3.22627 23.39 -990.122 -0.457267 0.74163 -0.490807 --13.4114 12.879 -1009.27 -0.445203 0.888743 -0.109227 -17.2873 27.3288 -978.016 0.221304 0.68257 -0.696508 -15.1097 26.5598 -980.887 0.904422 0.261157 -0.337369 -5.6213 50.6154 -970.956 0.298705 0.0742892 -0.95145 --3.31734 59.5426 -952.612 0.281127 0.925484 0.253866 -14.9067 27.0769 -982.376 0.96713 -0.162178 -0.19585 -5.87667 23.9562 -988.316 0.531407 0.819468 0.214661 -4.66976 24.3926 -989.442 0.050391 0.922343 -0.383073 -14.7361 27.6461 -980.443 0.851563 0.486816 -0.194554 -4.34272 3.23671 -1019.58 0.792682 -0.091211 -0.602773 --10.8529 17.8405 -998.646 0.485303 0.866049 -0.120169 -13.8837 9.51989 -949.357 0.943489 0.23755 0.231082 --30.9189 -15.6484 -978.454 -0.423398 -0.476427 -0.770553 -21.2086 24.3317 -967.83 0.862952 0.49033 -0.122027 -22.8987 -24.8986 -1015.19 0.707786 -0.651591 0.272891 -19.0843 26.3487 -974.623 0.800906 0.596571 0.0514975 -18.2335 27.0692 -977.128 0.629138 0.707863 -0.321117 -14.4397 27.3556 -983.522 0.749468 0.19963 -0.631225 -19.5391 25.741 -973.76 0.867191 0.491093 0.0825075 --25.5146 28.7883 -951.149 -0.926122 -0.135191 0.352166 -15.4944 26.0611 -980.343 0.962324 0.173982 -0.208957 --25.5187 29.4712 -950.585 -0.868084 -0.408645 0.281849 --10.2913 17.0485 -998.857 0.633542 0.769275 -0.0827115 -19.1387 23.3919 -970.634 0.873619 0.396939 -0.281478 -19.9268 25.0209 -973.693 0.845625 0.246673 0.473362 --10.7869 17.4828 -999.601 0.624198 0.698623 -0.349719 --2.02711 20.5478 -993.787 0.140565 0.978267 -0.15243 -4.292 36.5062 -983.238 0.0673161 -0.406473 -0.91118 -18.2535 17.2218 -961.354 0.675483 0.622751 0.394846 -11.4643 34.4513 -939.782 0.230062 0.599002 0.766986 -19.5229 26.1513 -975.838 0.748247 0.662767 0.0294367 -19.2182 26.4575 -976.737 0.88211 0.257937 -0.394146 -14.9896 25.2251 -981.868 0.82211 -0.0082761 -0.569269 -6.47847 22.1975 -986.027 0.616227 0.757557 -0.215341 --2.41218 20.3587 -994.714 0.130156 0.905835 -0.403141 --12.1418 10.6781 -1013.18 -0.168133 0.984306 0.0535976 -15.3445 25.0697 -981.255 0.916692 -0.196723 -0.347816 -18.5624 -24.8967 -1032.67 0.410227 0.176059 -0.894828 -6.67489 23.6741 -989.535 0.702724 0.710869 -0.0290509 -17.7628 -22.0108 -959.261 0.125587 0.031162 0.991593 -21.4174 23.1116 -969.629 0.730908 0.531459 -0.428164 -20.1722 24.4408 -974.48 0.995978 -0.0766207 0.0464469 -18.8546 26.1135 -977.527 0.722363 0.357412 -0.591987 -6.61036 22.1381 -987.658 0.720595 0.682673 0.121245 -6.74671 23.4344 -989.071 0.825882 0.477933 0.299165 -23.0219 21.5859 -965.444 0.807484 0.564397 0.171536 -1.64228 -14.9948 -946.528 0.64749 -0.635446 0.420673 --15.0053 47.3445 -975.285 -0.182212 0.779745 -0.598997 -22.5355 -37.2497 -998.127 0.204328 -0.495736 0.844095 -6.61759 23.297 -990.695 0.581015 0.680184 -0.446958 --23.8459 19.1425 -962.809 -0.243367 0.101914 0.964565 --23.4159 19.097 -962.555 -0.677385 -0.080924 0.731164 -19.7647 24.625 -976.037 0.957268 0.0617509 -0.282532 -22.9482 21.9337 -966.292 0.88278 0.458017 0.104498 -22.1872 21.8829 -968.025 0.715446 0.633755 -0.294096 -19.513 22.4921 -972.746 0.963802 0.266616 0.00144404 -9.66609 -20.0262 -1030.05 0.285278 0.0533946 -0.956956 -23.0437 20.6543 -964.658 0.734623 0.36948 0.569046 -21.7143 22.3072 -969.743 0.939783 0.321998 -0.114566 --11.6537 15.0668 -1002.1 0.383103 0.912798 -0.141533 --30.7133 36.5861 -954.806 -0.986082 -0.023853 0.164539 -8.86765 20.3739 -984.075 0.580696 0.780584 -0.231258 -8.08173 20.8322 -986.033 0.61963 0.779371 -0.0929465 -18.6767 -24.4673 -1009.89 0.282819 -0.69556 0.660461 --13.405 15.5631 -1005.27 -0.0811124 0.907257 -0.41268 -22.0093 39.2011 -960.009 0.347672 0.626455 -0.697623 -23.3772 20.6383 -965.97 0.833461 0.53876 0.122801 -22.4862 38.387 -960.173 0.725717 0.274202 -0.630989 -10.3512 20.1789 -982.858 0.462256 0.657544 -0.594941 -7.6229 21.3136 -988.38 0.553538 0.790083 -0.263371 --11.3653 15.078 -1003.43 0.400386 0.911276 0.0962644 --12.3793 15.5947 -1004.33 0.231613 0.972517 -0.0237811 -3.64483 -1.87743 -1024.48 0.141115 0.989689 0.0245193 -20.3771 16.5502 -962.259 0.593085 0.691485 0.412431 -19.6684 -18.2401 -960.049 0.383104 0.0843822 0.919843 --26.861 -45.7831 -949.828 -0.383116 0.141568 0.912787 --3.7957 3.45722 -941.459 -0.0105665 -0.0302389 0.999487 -23.9654 20.1419 -966.196 0.870845 0.491555 0.00150085 -23.1638 20.5781 -967.323 0.93239 0.361055 0.0169388 -21.9909 20.9966 -969.427 0.79546 0.493398 -0.351856 -8.68004 21.0764 -987.777 0.524689 0.850486 -0.0370847 --31.1836 -40.588 -967.234 -0.802062 0.0224023 0.59682 --11.9288 6.19912 -1019.5 0.140525 0.791805 -0.594389 --10.9093 14.8467 -1004.38 0.567935 0.809657 -0.148001 -23.8326 19.6623 -965.318 0.921259 0.108635 0.373472 -8.81601 20.9084 -988.232 0.471123 0.811636 -0.345382 --13.19 17.7369 -996.791 -0.763439 0.598199 -0.243556 -20.8426 15.3404 -960.907 0.603143 0.662726 0.443862 --15.0412 -32.7742 -959.24 0.989652 -0.00810486 -0.14326 -21.074 1.65314 -978.219 0.936214 -0.12958 -0.326667 -15.5457 30.3451 -943.81 0.687118 -0.675201 0.268275 --11.0475 14.6163 -1005.23 0.602295 0.587902 -0.540011 -22.321 20.1658 -969.799 0.79834 0.446687 -0.403886 --22.4714 -1.20501 -998.444 -0.980832 0.183232 0.0662952 --26.1371 -21.9759 -1032.74 -0.346472 0.864024 -0.365266 --27.572 -23.0601 -1032.92 -0.839263 0.517297 -0.167456 --26.858 -22.274 -1032.23 -0.608746 0.755879 -0.240987 --5.59126 16.4673 -1001.49 -0.175461 0.835515 -0.5207 -21.186 14.3341 -960.129 0.890192 0.373819 0.260416 -23.6788 20.31 -968.478 0.98931 0.134175 0.0571252 -12.4909 19.3106 -982.223 0.516378 0.687613 -0.510433 --14.3273 47.2246 -975.488 0.0325907 0.701898 -0.711532 -10.3875 19.0683 -985.281 0.614423 0.773013 -0.157911 --9.84798 30.6945 -984.275 0.0609195 0.860929 -0.505065 -13.7733 -21.852 -959.653 -0.414516 0.0462789 0.908865 -9.33645 20.1333 -989.05 0.349586 0.665818 -0.659148 -21.1007 13.1878 -958.616 0.820975 0.352721 0.448985 -17.5652 18.3699 -973.383 0.909922 0.320333 -0.263494 -15.4429 18.9539 -978.837 0.788073 0.483386 -0.381155 -10.3238 19.2811 -986.557 0.671233 0.727561 0.141783 -24.0883 18.7716 -967.122 0.994388 -0.0653296 -0.0832111 -23.8788 19.3728 -968.182 0.981154 0.170248 -0.0913939 --19.0745 -15.4438 -987.117 -0.538621 -0.81808 0.201575 --12.6697 13.3966 -1006.76 -0.490971 0.425027 -0.76046 -7.85232 -16.4066 -1033.86 0.285725 -0.857917 -0.427013 -14.0093 24.6927 -982.7 0.730937 -0.323014 -0.60116 -13.8175 18.7036 -981.581 0.624466 0.609738 -0.488121 --25.1183 -10.7898 -982.129 -0.128388 -0.583975 -0.801555 -10.2348 19.819 -988.233 0.677393 0.733222 -0.0593676 -6.82338 20.0564 -994.3 0.872448 0.339133 0.351885 -6.66877 20.4833 -995.062 0.733447 0.679662 0.0107295 -5.01996 22.9352 -935.015 0.0370829 -0.854673 0.517841 -15.8575 -23.5367 -1008.69 0.299151 -0.307111 0.903433 --25.6336 -12.1013 -999.692 -0.162906 -0.293001 0.942132 -5.85994 21.0066 -995.779 0.345633 0.879726 -0.326527 --12.2152 13.3581 -1006.85 0.197284 0.74953 -0.631889 -17.2571 -24.4318 -1009.26 0.406901 -0.154844 0.900253 --23.6953 -13.6119 -999.768 -0.606036 -0.0991635 0.789232 --24.1607 -13.4785 -999.979 -0.26913 -0.236614 0.933586 -20.6939 14.5012 -963.663 0.997028 -0.0685714 -0.0351154 -15.486 0.834077 -1013.87 -0.113444 0.979756 -0.164952 -6.58797 20.3945 -995.883 0.70573 0.611956 -0.35701 --27.1106 41.3138 -949.532 -0.135497 -0.21373 0.96745 --12.2689 12.966 -1007.78 0.0870509 0.991872 -0.0928026 --12.6078 13.1108 -1008.66 -0.0171762 0.995497 -0.0932201 -20.7338 13.9959 -963.751 0.977025 0.213105 -0.00305104 -16.8994 17.6457 -976.682 0.791604 0.544807 -0.276673 --23.7417 -47.777 -948.598 0.0194743 0.145271 0.9892 --0.853765 2.9229 -1022.7 0.754897 0.655429 0.023306 --26.274 -25.3325 -1034.17 -0.28784 -0.290712 -0.912488 -17.4717 -31.3903 -998.248 0.00401712 0.73234 0.680928 -13.7659 17.8241 -982.867 0.631717 0.65047 -0.42169 -11.3231 18.0899 -985.952 0.810379 0.578235 -0.0944938 -7.00384 17.5649 -991.317 0.651478 0.758215 -0.0262062 -6.46661 18.5152 -993.282 0.789218 0.581063 0.19875 --9.23493 32.8508 -933.352 -0.490871 0.869369 -0.0569451 -7.14313 19.6336 -995.605 0.937695 0.193946 -0.288292 -21.2446 9.75281 -956.956 0.981583 -0.00179718 0.191027 --13.456 54.3805 -968.88 0.19058 0.861785 -0.470112 --4.82847 15.1993 -1003.47 -0.0435577 0.893648 -0.446649 -20.5429 8.15108 -954.587 0.90017 0.0864486 0.426873 -19.4347 16.3239 -971.985 0.796231 0.536781 -0.279073 -7.27099 12.6253 -1003.41 0.306716 0.924752 -0.225299 -16.8943 17.2008 -977.965 0.744446 0.614467 -0.26121 -11.3997 17.9181 -986.39 0.974919 0.153011 0.161618 --31.2898 -34.0708 -950.1 -0.777552 0.537206 0.326838 -21.271 12.1343 -961.482 0.938311 0.314047 0.144729 --31.2629 -34.9185 -949.108 -0.728801 0.353072 0.586676 --30.4753 -34.1809 -948.882 -0.379085 0.627795 0.679829 --30.3443 -34.4915 -948.596 -0.296169 0.439423 0.848052 -11.2691 18.6347 -988.759 0.78156 0.623829 0.00118177 --10.7579 12.6663 -1008.36 0.485401 0.873821 -0.0286864 --11.4074 12.8541 -1008.89 0.243985 0.964925 -0.096912 -21.2863 10.3203 -959.287 0.877251 0.322436 0.355621 -7.64601 17.8614 -992.446 0.641085 0.750735 0.159393 -19.7339 34.4241 -971.727 0.734008 0.40083 -0.548241 -16.835 -20.2001 -1025.6 0.188959 0.553664 -0.811018 -7.49842 27.1608 -930.794 0.134093 0.584409 0.800303 -21.1677 -3.62891 -999.573 0.396987 0.551594 0.733584 --12.0536 12.5707 -1010.33 0.119582 0.890452 -0.439084 -14.9704 -21.2804 -1026.79 0.610925 -0.178324 -0.771344 -16.5547 16.9615 -979.351 0.748375 0.562204 -0.35194 -15.0301 -21.7179 -1026.76 0.400549 0.117044 -0.908769 -23.471 -46.8403 -958.321 0.0749324 0.501711 0.861784 -25.4442 -47.1319 -959.19 0.512287 0.674256 0.531921 -12.6857 29.859 -979.584 0.513421 0.838034 -0.184655 -25.6916 -47.8643 -958.655 0.63091 0.412121 0.65735 --13.7466 -16.5842 -960.896 -0.0230235 -0.999637 -0.0140076 -21.1214 13.9903 -966.181 0.973684 0.174911 0.146103 -8.48178 16.9746 -991.614 0.350113 0.810185 -0.470129 -7.34009 17.846 -994.13 0.653016 0.731152 -0.197452 --17.3464 -16.4816 -960.026 0.809057 0.203805 0.551262 --20.7668 -45.4118 -949.608 0.486023 -0.1187 0.865848 --23.3858 -44.5885 -948.972 -0.0381664 0.0784729 0.996185 --21.2055 -44.0815 -949.155 0.182682 -0.11586 0.976322 -14.5753 20.8516 -978.209 0.742316 0.30996 -0.594047 --4.98606 58.4175 -958.887 -0.327959 0.658942 0.676934 --19.5647 -2.09962 -1021.9 0.355714 0.821679 -0.445321 --1.07474 5.62216 -1018.51 0.303145 0.863695 -0.402658 -11.4032 18.1645 -989.926 0.588888 0.692498 -0.416723 -4.72166 18.8086 -999.706 0.428211 0.818295 0.383442 -19.3432 4.1221 -951.555 0.905101 0.3635 0.220589 -19.9941 15.2591 -972.886 0.796772 0.572953 -0.192037 -16.5165 37.1712 -971.761 0.164556 0.986339 0.00757358 -4.70319 17.6601 -998.336 0.625143 0.466047 0.626096 -15.5175 36.9135 -973.021 -0.124119 0.920222 -0.371196 --25.9752 49.0159 -959.45 -0.512769 0.855917 -0.0668873 --10.487 12.1441 -1010.48 0.337692 0.827456 -0.448643 --3.29862 7.697 -1015.29 0.302749 0.871222 -0.386414 --2.1981 6.89723 -1016.59 0.273305 0.901934 -0.334393 -20.9078 14.2621 -970.662 0.868615 0.480229 -0.122015 --2.6104 7.22107 -1015.67 0.316027 0.899396 -0.302016 --30.1009 -36.2898 -999.749 -0.381356 0.0895511 0.920081 -4.71514 16.414 -997.736 0.735449 0.628804 0.252429 --2.46131 14.8056 -1004.87 0.23231 0.892451 -0.386735 --20.3253 41.0845 -935.369 -0.951312 -0.286159 0.114537 -21.4375 13.3765 -967.938 0.968891 0.220669 -0.112053 --20.5407 42.6605 -936.321 -0.974682 -0.0264345 -0.22203 --24.2572 -16.756 -1001.58 -0.325136 -0.625305 0.709422 -8.91393 16.483 -992.52 0.665305 0.73995 0.0992123 -5.08176 18.6582 -1000.66 0.313137 0.906077 -0.284552 --0.834717 -18.4885 -941.831 0.198507 -0.435131 0.878212 -19.7402 3.41374 -952.217 0.58834 0.720029 -0.367987 -5.83357 0.422855 -1019.08 -0.478926 0.124589 -0.86897 -19.6012 32.7659 -971.687 0.918767 -0.0090696 -0.394696 -2.61157 57.4746 -950.055 0.385525 0.668394 0.636097 --18.967 20.0348 -944.006 -0.871379 -0.138557 0.470639 -15.0754 16.0329 -983.713 0.695019 0.609102 -0.382026 --24.3371 -11.5135 -999.484 -0.0784642 -0.199738 0.976703 -22.4877 9.59239 -961.299 0.885048 0.429466 0.179579 --25.4512 -8.0112 -983.452 -0.370603 -0.275016 -0.887141 -12.246 17.1158 -989.607 0.932952 0.352643 0.0724145 -22.1777 11.4134 -965.287 0.925585 0.361222 0.113183 --29.558 43.5865 -952.051 -0.938963 0.241938 0.244569 -16.4021 -2.55444 -1023.37 0.446137 0.17994 -0.876689 -12.3218 16.2532 -987.87 0.818592 0.556123 -0.143645 -5.55088 16.9573 -999.08 0.856471 0.182923 0.482697 -5.98651 17.8814 -1000.13 0.846629 0.454296 0.277189 --16.4855 -20.6763 -962.28 0.958543 -0.00293923 0.284932 -14.6344 -3.14039 -1024.12 0.274884 0.0218872 -0.961228 -15.061 -2.5144 -1023.9 0.270959 0.379418 -0.88466 --29.3189 -42.3827 -953.601 -0.911103 0.107598 0.397886 --29.7631 -44.5448 -955.344 -0.943882 0.267223 0.19411 --29.5495 -44.0332 -954.249 -0.94769 0.292185 0.128495 -5.61028 15.8584 -998.498 0.455787 0.890063 -0.00668602 --22.5389 0.171705 -1019.26 0.166993 0.927005 -0.335821 -22.1476 12.4793 -968.586 0.874048 0.484983 0.0288294 --7.07793 59.8195 -963.361 -0.124802 0.734885 -0.666609 -1.34838 9.09789 -1012.59 -0.607081 0.677785 -0.414801 --4.48093 37.5451 -983.034 0.0728537 -0.0539973 -0.99588 -12.1363 16.2584 -991.427 0.106561 0.51591 -0.849989 -9.7948 15.6962 -992.971 0.557104 0.783758 -0.274514 -10.5716 16.9585 -990.683 -0.134544 0.431764 -0.891895 -12.2084 16.5951 -991.116 0.570236 0.592493 -0.569019 --29.9799 23.4941 -959.556 -0.772368 -0.363237 0.521063 -19.4449 13.8905 -978.087 0.766653 0.576171 -0.283322 -12.6622 15.5041 -988.819 0.845362 0.533309 -0.0307339 -12.7186 16.2331 -990.543 0.876688 0.481057 -0.00159498 -6.00237 15.9068 -999.459 0.844969 0.476508 0.242832 --3.74367 44.0798 -977.024 0.155474 0.16035 -0.974739 --17.7632 -13.0093 -1029.98 -0.602148 0.791723 0.102924 --11.2684 10.6016 -1013.28 0.272847 0.949172 -0.156932 -9.53777 -25.7293 -965.055 -0.975338 -0.0575885 0.213072 --13.3101 47.4942 -974.906 -0.0419404 0.822686 -0.566947 -5.29542 23.8507 -934.07 0.139057 -0.669298 0.729866 -12.3624 -49.5497 -955.963 -0.147603 0.317216 0.936796 --20.7698 30.1694 -940.378 -0.856027 -0.448657 0.256759 -17.8097 14.2353 -981.343 0.753809 0.549561 -0.360214 --12.8511 16.1407 -995.657 -0.982373 -0.111959 -0.149691 -10.118 15.8971 -994.275 0.754041 0.598498 0.270598 --17.8592 25.7766 -933.144 -0.780116 0.0180994 0.625373 --14.6172 54.6617 -969.292 0.160879 0.751055 -0.640339 --14.7566 52.8372 -970.404 -0.152492 0.671758 -0.724905 -21.4604 2.01434 -952.455 0.547501 0.798704 0.24963 -22.9459 8.90958 -964.895 0.932703 0.358462 0.0396241 -12.5867 -28.177 -1005.1 -0.663213 0.242407 0.708087 -22.8051 10.8788 -969.005 0.938373 0.329084 0.105643 --15.1653 54.6102 -969.333 -0.221938 0.744047 -0.630188 --23.5147 -0.461105 -1021.07 0.0397901 0.944775 -0.325294 --25.5061 30.3443 -955.979 -0.817508 -0.528799 0.228151 --29.0029 -9.89812 -1000.74 -0.635854 -0.200704 0.745257 -6.69744 15.3324 -999.636 0.457645 0.835379 -0.304472 --10.8535 10.1901 -1014.07 0.381703 0.830663 -0.405342 --26.8518 31.4279 -955.14 -0.312419 -0.83352 0.455674 -10.4488 14.972 -993.918 0.727133 0.686487 0.00351653 -21.1857 -36.2154 -997.73 0.0706106 0.21887 0.973196 -3.70957 16.1186 -1005.24 -0.0179434 0.943748 -0.330177 --30.285 -13.2345 -979.913 -0.412203 -0.497634 -0.763184 -21.6865 1.94242 -953.657 0.432113 0.846522 -0.310934 -23.3113 8.02484 -964.026 0.912962 0.408038 -0.00219704 --2.07811 -18.4398 -951.714 -0.525866 -0.745455 -0.409587 --1.57958 -18.6471 -951.763 0.18743 -0.871905 -0.452384 -17.3354 -19.4828 -978.753 0.0965442 -0.211135 -0.972677 -13.7735 14.5503 -988.357 0.723733 0.606417 -0.329346 -13.1579 14.8162 -989.677 0.825172 0.564881 0.000382423 -19.0863 -31.2747 -999.663 0.342492 0.804422 0.485391 -10.4525 15.7045 -995.162 0.65896 0.751522 -0.0314137 --9.45314 9.31655 -1013.48 0.485256 0.752826 -0.444724 --1.59337 -19.4103 -950.42 -0.117846 -0.924042 -0.363673 --2.38618 -19.3262 -949.865 -0.567297 -0.740152 -0.361039 --8.67335 -25.0115 -1035.39 -0.0122065 -0.390296 -0.920608 --4.76808 11.6855 -1010.36 -0.0038156 0.981598 -0.190922 -0.588059 43.9286 -975.694 -0.483214 -0.0381328 -0.874671 --8.38768 -22.846 -1035.99 -0.0545051 -0.217015 -0.974645 -10.5544 15.5213 -995.655 0.565179 0.74647 -0.351219 -14.898 -37.7685 -1000.15 -0.064742 -0.992064 -0.107783 -14.495 -1.12892 -1020 -0.200286 0.91768 -0.343146 -8.07101 15.1683 -998.886 0.357185 0.881764 -0.308076 -22.6522 1.36362 -952.37 0.634822 0.726475 0.263125 -22.766 1.43892 -953.422 0.639656 0.723272 -0.260226 -23.8354 6.17692 -959.819 0.87147 0.340771 0.352724 -24.1345 6.30336 -961.559 0.922021 0.381435 0.066218 --4.3569 32.1423 -983.309 -0.276285 0.959483 -0.0553158 -12.8774 -19.5668 -960.544 -0.67567 0.0654224 0.734296 -17.4068 13.2253 -983.517 0.806315 0.436033 -0.399664 --6.04621 31.7237 -983.94 -0.42332 0.86301 0.275705 --30.879 -48.0655 -954.691 -0.950243 -0.194939 0.242973 --25.9846 42.1675 -964.536 -0.641588 0.765739 0.0448114 --30.7042 -46.2627 -954.404 -0.943092 0.260506 0.206672 -17.0779 -30.9942 -998.872 -0.0530952 0.891779 0.449346 -12.2127 -1.3872 -1018.77 -0.0734554 0.949363 -0.305475 --4.11008 11.4845 -1011.01 0.13078 0.917374 -0.375929 -14.2532 44.7493 -972.483 0.940179 0.049711 -0.337033 -2.00491 -1.84866 -1025.52 0.345762 0.919337 -0.187797 -14.6586 46.2429 -972.39 0.789329 0.569635 -0.229076 -23.1794 10.4888 -971.228 0.917724 0.386101 0.0933185 -19.4372 12.2336 -980.455 0.819993 0.400183 -0.409225 -4.73023 15.5088 -1006.11 0.615558 0.766338 -0.183886 -14.0037 46.057 -963.523 0.876744 0.467753 -0.111923 -13.4925 44.109 -973.667 0.683575 0.0415363 -0.728698 -13.9226 46.5813 -973.519 0.772495 0.232672 -0.59086 -22.6398 11.219 -973.911 0.83837 0.528969 -0.131631 -21.7727 11.4684 -976.453 0.804569 0.500485 -0.319663 --27.788 45.4918 -952.819 -0.716471 0.695892 0.0490249 -13.8345 14.2333 -991.509 0.768618 0.449527 -0.45514 -11.8612 13.9261 -993.307 0.586494 0.705433 -0.397981 -20.3101 33.666 -970.945 0.93554 -0.184586 -0.301153 -4.77976 13.7281 -1003.7 0.539825 0.814029 0.214347 -23.2781 0.687323 -953.448 0.726312 0.686329 -0.0377435 -14.5195 46.8497 -962.845 0.614388 0.0144219 -0.788872 --24.8791 31.2955 -967.178 -0.874572 0.377489 0.304346 -23.3668 8.90627 -968.425 0.923265 0.359215 0.136187 --25.1873 29.9724 -965.969 -0.856599 0.508748 -0.0861049 -16.3637 12.5586 -986.095 0.844507 0.346649 -0.408218 --27.5055 16.8848 -975.326 -0.596986 -0.593834 -0.539414 --25.1404 30.4973 -966.688 -0.723954 0.507414 0.467356 -23.0302 0.429874 -954.361 0.606393 0.598477 -0.523558 --26.587 -12.109 -959.605 -0.502284 0.164449 0.848921 -14.2952 53.972 -956.18 0.964271 0.133184 0.229004 --31.9588 -18.8839 -1014 -0.912421 -0.402191 0.0757018 -11.9991 52.0429 -968.423 0.415533 0.645169 -0.641163 --9.11518 8.14394 -1014.51 0.526052 0.634133 -0.566696 -21.9339 0.505828 -955.34 0.649562 0.721366 -0.240211 -14.3713 54.7107 -957.627 0.981167 0.175045 0.0816741 -14.3261 54.7794 -958.208 0.932746 0.24904 -0.260698 --12.7966 42.9316 -976.369 -0.0026661 -0.339788 -0.940498 -21.1898 10.9677 -978.212 0.822515 0.331784 -0.461941 -5.39759 -10.6811 -1027.59 0.548622 0.402807 -0.732639 -15.5822 12.52 -987.858 0.806506 0.483536 -0.340208 -12.8317 13.1485 -993.024 0.664502 0.634129 -0.39537 --12.3339 10.3001 -1011.84 -0.451727 0.402629 -0.796136 -8.24749 0.395352 -1020.15 0.00473836 0.639151 -0.769066 --13.4605 11.3217 -1011.45 -0.697956 0.0935463 -0.710005 --13.0714 11.6752 -1011.43 -0.243838 0.518859 -0.819347 -17.2643 -15.294 -959.444 0.106788 -0.518818 0.848189 -14.233 13.596 -990.842 0.87567 0.480144 0.0516164 --28.5121 -23.097 -958.242 -0.642356 0.0596524 0.764081 -9.85746 13.9809 -999.324 0.749062 0.661845 0.0294565 --3.39612 10.5451 -1012.34 0.108047 0.751111 -0.651274 -24.6261 4.79127 -961.129 0.939482 0.282333 0.194065 -6.83816 -0.505044 -1020.65 -0.382631 0.672113 -0.633923 -9.66943 14.0443 -999.88 0.553301 0.778289 -0.296859 -5.52454 13.265 -1004.55 0.632979 0.757644 -0.159101 -5.33479 13.4105 -1005.02 0.902964 0.377199 0.205854 --16.1273 -41.0729 -968.641 0.817627 0.568424 -0.0915453 --12.808 14.6642 -1006.39 0.199565 0.550189 -0.810842 --11.2487 7.36169 -1017.15 0.507106 0.599322 -0.6194 -24.1352 -0.148671 -953.925 0.750506 0.59456 -0.288511 -15.1696 56.3831 -950.597 0.184901 0.819423 -0.542548 -6.42906 -11.4908 -1028.01 0.0609624 0.853865 -0.516912 --24.9942 13.8388 -971.42 -0.623489 -0.711755 -0.323523 -12.3351 51.3349 -945.913 0.336989 0.725144 0.600503 -12.8445 51.336 -945.84 -0.37408 0.656011 0.655526 -24.671 5.47417 -964.496 0.909296 0.414735 0.0342933 -23.8118 9.31503 -973.235 0.899426 0.433603 -0.0549632 -19.7767 10.4311 -981.302 0.867632 0.292482 -0.402081 -14.5029 46.0881 -965.252 0.73698 0.666327 0.113437 -12.4361 13.1646 -996.402 0.689265 0.477171 -0.545181 --1.09615 35.7369 -981.482 0.291684 -0.215688 -0.931879 --8.68915 43.4593 -976.011 -0.490545 -0.169248 -0.854822 --20.4553 0.126355 -1017.76 0.109479 0.948429 -0.297485 --7.04144 13.1346 -1023.84 -0.217985 0.9686 0.119568 -21.0899 -51.3712 -955.954 0.179653 -0.704253 0.686842 -22.7157 -1.01006 -955.735 0.773989 0.406601 -0.485403 -24.3298 6.36551 -967.351 0.93049 0.360991 0.0622384 -15.3898 45.6114 -965.041 0.35009 0.933855 0.0731533 -23.3634 9.47072 -975.155 0.864298 0.410033 -0.291312 -21.4552 9.37369 -978.622 0.788211 0.180242 -0.588419 -18.0905 10.4654 -984.827 0.826644 0.42985 -0.363165 -13.0539 12.4333 -995.197 0.666551 0.669438 0.327968 -11.2141 -10.4124 -1027.91 -0.0524106 0.843817 -0.534066 -5.20332 12.8202 -1006.8 0.743148 0.309795 -0.593092 -10.3021 -11.3121 -1030.36 0.0821027 0.961361 -0.262762 -4.29056 12.6145 -1008.19 0.735692 0.654804 0.173174 -24.4075 -1.45169 -953.177 0.962868 0.13704 0.232606 -24.3182 8.08861 -971.107 0.919438 0.374011 0.121447 --8.28844 45.0322 -976.871 -0.303882 -0.208844 -0.929538 -15.3187 11.6146 -990.153 0.845181 0.498851 -0.191877 -14.0816 12.1378 -992.346 0.721628 0.494528 -0.484453 --16.4124 40.7269 -972.749 -0.181021 0.27161 -0.94523 -5.7037 -11.1308 -1027.88 0.628639 0.716472 -0.302458 -3.31546 3.83867 -1020.97 0.582706 -0.225968 -0.780636 --9.55907 43.3283 -975.333 -0.245828 -0.084021 -0.965665 --7.10658 43.7196 -976.783 -0.268965 -0.117547 -0.95595 -10.6472 12.3969 -998.66 0.803659 0.585404 -0.10693 -3.67545 13.2399 -1009.72 -0.168195 0.985529 -0.021044 -3.82087 -11.0366 -1032.23 0.442906 0.255081 -0.859516 --8.82794 -26.1928 -1034.79 -0.0812021 -0.593877 -0.800448 --6.25773 56.7283 -964.714 -0.332386 0.298185 -0.894766 --24.9323 -20.0897 -956.688 -0.169113 0.127591 0.977303 --19.0351 -36.8639 -1002.13 0.384723 -0.910096 -0.153991 --31.5777 -36.0481 -1001.99 -0.313967 -0.086767 0.945461 --20.218 -49.1318 -951.127 0.478167 -0.0556007 0.876507 --13.4885 11.8587 -1006.28 -0.727964 0.255112 -0.636385 -13.8557 11.4637 -994.211 0.719124 0.688945 -0.0906408 -4.52259 13.1033 -1009.82 0.391611 0.917814 0.0652634 -23.8218 -3.81151 -951.299 0.676696 -0.206531 0.706702 --17.3746 -36.4694 -947.223 0.0759745 0.322429 0.94354 --18.33 0.426386 -1016.71 -0.334915 0.925116 -0.178864 -0.479947 22.4893 -987.16 -0.127909 0.881842 -0.453866 -21.0005 8.4487 -979.632 0.889276 0.151098 -0.431692 -1.659 22.4964 -988.427 -0.716774 0.564306 -0.409628 -15.1973 51.1849 -963.091 0.524048 0.482732 -0.701672 -24.7906 -1.66117 -953.938 0.960146 0.203011 0.19211 -25.1772 2.05942 -960.643 0.930066 0.23366 0.283515 --1.64152 4.73474 -1021.06 0.920728 0.364242 0.139956 -12.4776 -0.497463 -1016.97 -0.104859 0.854841 -0.508184 -19.1641 9.34646 -983.531 0.87152 0.347592 -0.345881 --17.7861 -0.464547 -1019.68 0.388934 0.399286 -0.830241 --15.7775 -0.274706 -1018.63 0.216126 0.443955 -0.869594 --14.858 -0.135267 -1018.46 0.00139061 0.624641 -0.780911 -10.9417 12.4812 -1000.57 0.847002 0.531415 -0.0136327 -4.90675 -9.98946 -1029.05 0.956233 -0.0625484 -0.285844 --5.57819 12.8793 -1024.15 0.360925 0.893936 -0.265729 -22.3722 8.36659 -977.715 0.741537 0.146226 -0.654783 --16.2032 0.531672 -1018.56 0.216033 0.373979 -0.901925 -15.3079 10.8764 -991.543 0.819287 0.465372 -0.334959 -0.559546 5.83035 -1017.31 -0.267495 0.863191 -0.428192 --25.3841 -7.41485 -998.702 -0.131291 -0.0810448 0.988025 --20.9471 -19.5535 -956.949 0.307808 0.183735 0.933539 -24.6749 7.42204 -972.539 0.943503 0.331238 -0.00912593 -23.1039 8.20279 -976.863 0.816888 0.264219 -0.512721 -1.17232 -27.5589 -1031.25 0.229936 -0.651 -0.723414 -16.8264 9.92259 -988.853 0.835663 0.462935 -0.295565 -1.98249 -28.1676 -1030.21 0.0725674 -0.882767 -0.464172 -5.02056 12.7506 -1010.61 0.653509 0.717053 -0.242406 -13.0006 11.2557 -996.716 0.701069 0.483756 -0.523911 --0.185986 6.49967 -1016 -0.246922 0.801502 -0.544632 --4.97886 7.82999 -1015.98 0.115178 0.922077 -0.369471 --23.2321 -8.23691 -998.817 -0.294534 -0.109036 0.9494 -25.5713 3.14478 -964.285 0.952153 0.300755 0.0543165 -8.42431 36.9896 -979.998 0.0581774 0.178619 -0.982197 -6.77136 34.9498 -980.404 0.719769 -0.299198 -0.626429 -5.68223 11.7597 -1009.88 0.931141 0.266403 0.249008 --28.2378 -11.3401 -981.611 -0.0718921 -0.5429 -0.836715 -7.14339 36.7433 -981.873 0.769311 -0.34583 -0.53718 -24.5485 -4.05448 -952.614 0.957849 -0.169169 0.232178 -6.73189 33.7197 -980.428 0.791602 0.309291 -0.526978 -25.0231 4.77986 -969.185 0.968999 0.200287 0.144659 -8.05763 36.2601 -980.075 0.443042 -0.22885 -0.866799 -10.0901 12.0393 -1002.61 0.427241 0.718164 -0.549277 -7.58718 11.6536 -1006.52 0.446194 0.786787 -0.426471 -5.18755 10.7959 -1008.45 0.787379 0.557773 -0.262534 --31.0365 -46.383 -963.901 -0.93353 0.356712 0.035758 --4.13577 11.9661 -1023.13 0.584842 0.738395 0.335757 --31.2993 -47.6968 -963.793 -0.972612 0.00425275 0.232395 -20.8757 7.08548 -980.316 0.956017 0.0840131 -0.281023 --20.2971 29.1999 -939.718 -0.949292 -0.287682 0.12682 -4.98508 12.3668 -1011.48 0.431972 0.752819 -0.496654 --6.53982 6.91296 -1018.07 -0.0322079 0.960801 -0.275362 --3.9871 11.9632 -1023.61 0.690028 0.723396 -0.0236568 -10.2921 0.533788 -1016.08 0.303956 0.462131 -0.833094 -11.4944 10.9017 -1000.39 0.90754 0.416306 0.0553259 -11.5392 11.3986 -1001.36 0.906525 0.422152 -0.0001501 --3.97192 11.7747 -1024.03 0.603872 0.547218 -0.579561 --0.908802 -12.0495 -941.81 0.728396 0.178066 0.661613 -25.2269 5.3615 -971.021 0.969123 0.235917 0.0717225 --1.62424 -10.9315 -941.682 0.531123 -0.0484063 0.845911 -24.8257 6.64747 -973.969 0.92764 0.31976 -0.19297 --32.1141 -4.4757 -978.32 -0.949167 -0.0206661 -0.314095 --19.1395 0.67301 -1015.75 -0.0687713 0.897104 -0.436434 --0.0364508 -10.8827 -942.329 0.403864 -0.597298 0.692914 -0.471595 -11.2469 -943.715 0.650565 -0.307201 0.694545 -25.6656 2.75728 -966.055 0.962816 0.264086 -0.0569661 -24.3865 6.75644 -975.286 0.884921 0.292394 -0.362519 --24.504 23.0332 -958.174 -0.89847 -0.406991 0.164652 --3.81204 10.6512 -1021.92 0.490881 0.516741 0.701438 -25.2084 3.41595 -968.299 0.985733 0.154993 -0.0656276 --26.3461 22.6984 -959.128 0.0832404 -0.698345 0.710904 -20.2318 6.98094 -982.617 0.925237 0.220887 -0.308457 --26.9997 23.2256 -958.355 0.0847588 -0.577343 0.812091 --12.0595 42.5479 -976.227 0.0868212 -0.160141 -0.983269 --26.1836 25.2292 -957.742 -0.178197 -0.233168 0.95597 --26.0273 24.3182 -957.991 -0.0347841 -0.282546 0.958623 -8.42376 11.1793 -1006.41 0.598206 0.740326 -0.306703 --24.9816 24.0533 -957.997 -0.464971 -0.503214 0.728407 -25.8537 -0.0221641 -961.106 0.940328 0.138248 0.31092 -11.528 11.1658 -1002.29 0.700198 0.617381 -0.358558 -24.7758 -27.686 -975.87 0.744502 -0.372472 -0.554059 -25.4469 -27.3159 -974.494 0.959856 -0.279984 0.0169091 -25.5561 -25.6945 -974.647 0.963464 0.266968 0.0215677 -9.04884 10.8069 -1005.32 0.782195 0.622001 0.0358535 -25.3093 -25.7599 -976.107 0.924816 -0.00694481 -0.380351 -25.2464 -26.6028 -972.963 0.94415 0.0909489 0.316717 --22.1192 -43.3286 -949.031 -0.221809 -0.0390875 0.974306 -25.249 3.22519 -969.684 0.989242 0.0275927 0.143666 --18.7746 -42.9212 -950.878 0.962612 0.115095 0.245217 --18.412 -42.258 -950.258 0.64483 -0.684732 -0.339612 --18.848 -42.5851 -950.178 0.710543 -0.690888 0.133422 --3.74403 6.58136 -1018.01 0.214256 0.948994 -0.231312 --19.3699 -42.1367 -949.133 0.126823 -0.666696 0.73446 --17.6893 -41.875 -948.763 0.30962 -0.827389 0.468575 -22.0413 5.19332 -978.589 0.792387 -0.06925 -0.606076 -18.4484 7.45942 -987.618 0.889797 0.35714 -0.2841 --22.1602 -42.3717 -948.825 -0.281705 -0.405857 0.869438 -8.34807 10.5318 -1007.49 0.423682 0.673471 -0.605748 -6.07762 9.49225 -1009.14 0.561824 0.710812 -0.423203 -12.4959 -14.8114 -1030.39 0.382016 -0.789318 -0.480667 -25.3406 4.86667 -973.832 0.968804 0.222718 -0.108696 -21.5441 4.4482 -979.167 0.8911 -0.334587 -0.306581 -2.67264 2.36812 -1022.06 0.561655 0.798504 0.216644 -15.0458 9.27663 -995.257 0.815632 0.501801 -0.287994 --3.87509 6.54073 -1018.93 0.324822 0.89522 0.305077 -10.773 -15.1562 -1033.67 0.699952 -0.451117 -0.553679 --15.9324 -30.6678 -957.095 0.785433 0.551039 0.281869 --2.71046 10.1715 -1022.75 0.745325 0.563827 0.355795 --3.1201 10.3115 -1024.16 0.63875 0.479217 -0.601954 -12.7466 -14.0609 -1030.77 0.575541 -0.189273 -0.795568 -24.3241 5.37131 -976.214 0.82475 0.182163 -0.535354 -12.1448 9.71304 -1000.9 0.771847 0.569488 -0.282731 -9.73028 9.61637 -1004.67 0.836921 0.547292 -0.0058548 --3.90436 7.37294 -1020.15 0.253385 0.599138 0.759493 --0.143953 -31.8927 -1004.2 0.215696 -0.665764 0.714306 --2.56568 8.86911 -1021.71 0.662256 0.467463 0.585573 -11.4942 -12.955 -1032.67 0.73744 0.542183 -0.402765 -25.6381 3.27967 -971.511 0.989059 0.0914252 0.115776 -11.4919 -14.225 -1033.18 0.858043 -0.0939329 -0.504915 -19.4076 6.30137 -985.798 0.926554 0.273194 -0.258579 -17.3253 7.58927 -991.205 0.863851 0.423345 -0.273022 -11.9954 -13.1382 -1031.65 0.724814 0.523433 -0.447954 -11.2279 -15.2711 -1030.89 0.527193 -0.835783 -0.153408 -11.2056 -43.7076 -963.602 -0.642859 0.39681 0.65519 -11.7434 -14.7906 -1031.33 0.676775 -0.660222 -0.325705 --22.0127 50.9374 -945.331 -0.299282 0.801569 0.517608 --27.9744 15.9037 -971.427 -0.784058 -0.618397 0.0532827 --1.29203 37.5901 -982.086 0.281011 0.474466 -0.834215 -11.0079 -43.174 -964.24 -0.824682 0.356274 0.439281 -26.3716 -0.855948 -962.74 0.979235 0.127419 0.157684 -26.0684 0.785103 -966.571 0.975565 0.158276 -0.152389 -25.6509 1.42098 -967.902 0.946498 0.150153 -0.285651 -25.0962 4.44501 -975.11 0.904887 0.167691 -0.391229 -14.0938 8.90844 -998.487 0.767305 0.537965 -0.349051 --23.0172 51.8075 -946.758 0.0962734 0.805719 0.584422 --7.86566 20.3147 -988.073 -0.153322 0.832406 -0.532535 -10.6738 -11.4448 -1030.61 0.29533 0.86793 -0.399346 -21.1533 3.35859 -979.88 0.966678 -0.177776 -0.184201 -3.72142 5.27266 -1014.68 0.776262 0.530171 -0.341081 --22.1801 -20.0661 -956.589 0.0778178 0.136781 0.98754 -4.34805 9.38212 -1014.15 0.862807 0.49819 0.0858471 --17.8641 43.4193 -973.126 0.360945 -0.205982 -0.909555 --20.1406 -41.0701 -948.429 -0.0295785 -0.713681 0.699846 -23.7516 4.23198 -977.237 0.698103 0.0549236 -0.713888 -21.0919 3.49592 -980.437 0.963287 -0.116835 -0.241717 -15.4868 8.02468 -996.24 0.843645 0.456846 -0.282056 -11.1843 40.0513 -974.137 0.0696963 0.547351 -0.833996 -12.5235 8.77912 -1001.62 0.852051 0.502178 -0.147735 -11.4653 39.24 -974.991 0.239186 0.834664 -0.496111 -26.4612 -0.711324 -964.406 0.986262 0.163735 -0.0218718 -9.07779 39.1976 -977.068 0.340134 0.916657 -0.209878 -10.1005 9.50253 -1006.83 0.732547 0.63048 -0.256651 -4.02935 9.79634 -1015.09 0.621948 0.762618 -0.17775 --2.59896 6.85833 -1020.56 0.659718 0.495731 0.564821 -6.33355 -6.79163 -1029.63 0.510961 -0.62807 -0.586896 -8.87745 39.6501 -974.867 0.48333 0.770907 -0.414844 --9.75343 5.65526 -1018.64 0.397729 0.699677 -0.593519 -9.58524 39.2798 -974.921 0.166814 0.866973 -0.469608 -10.7749 39.1071 -975.445 0.163079 0.969511 -0.182903 --2.34296 5.94597 -1019.6 0.578734 0.813712 -0.0542184 --30.6785 -39.9417 -965.554 -0.881833 -0.43711 0.176933 --1.87644 9.20258 -1023.59 0.83706 0.53474 -0.115686 --22.3861 -38.6561 -946.156 -0.618073 -0.278149 0.735268 --30.5595 -40.0068 -963.789 -0.599445 -0.800186 0.0191745 --30.7973 -39.7977 -962.945 -0.950833 -0.300576 0.0746375 -12.2074 9.36476 -1003.38 0.74993 0.488799 -0.445736 -6.56636 8.71513 -1010.94 0.610463 0.734215 -0.297092 --30.4519 -38.2749 -963.882 -0.92739 0.25287 -0.27569 -6.09514 37.0127 -983.154 0.466954 -0.34118 -0.815813 --30.5847 -40.24 -961.429 -0.946268 0.0151797 0.323026 --30.4277 -40.6874 -961.217 -0.800531 -0.58931 0.10892 --30.2661 -38.9516 -965.734 -0.641724 0.736748 -0.213056 --30.6056 -39.3772 -965.511 -0.943235 0.329362 -0.04276 -4.84742 8.47189 -1015.01 0.993121 0.102807 0.0560496 --1.46878 8.49725 -1023.14 0.853203 0.45426 0.256307 --12.9241 32.6686 -934.651 -0.11319 0.915322 0.386488 --19.4837 40.1037 -935.672 -0.781453 -0.503123 0.369052 -25.7301 2.53223 -973.848 0.987861 0.113798 -0.105736 --29.1582 43.0308 -954.549 -0.938334 0.216163 -0.269819 --14.6688 58.34 -962.354 -0.0273816 0.747277 -0.663949 -10.7258 8.56798 -1006.64 0.892949 0.435656 0.113341 -4.40687 9.09207 -1015.83 0.693415 0.619291 -0.368313 --19.9943 41.0883 -934.377 -0.726452 -0.47621 0.495471 --17.628 40.8572 -933.12 -0.0707373 -0.651632 0.75523 --19.3475 39.1169 -936.22 -0.440003 -0.767937 0.465478 -17.7422 5.93668 -992.144 0.897102 0.348585 -0.271472 -16.2144 6.77738 -995.8 0.87689 0.385315 -0.287396 -12.2722 8.64122 -1003.91 0.627476 0.380021 -0.679601 --1.5035 7.32701 -1022.01 0.843712 0.250309 0.474864 -25.3079 0.432557 -970.641 0.990939 0.026147 0.131746 --18.3318 41.4172 -933.064 -0.458432 -0.155525 0.875016 --18.1354 40.9659 -933.185 -0.314469 -0.572783 0.756987 -25.2299 -0.0260058 -969.684 0.99113 0.117748 -0.0616229 --19.2624 40.5701 -934.161 -0.495681 -0.593656 0.633935 --20.8042 57.0331 -957.768 0.186656 0.981692 -0.0379589 -20.1639 3.63159 -985.217 0.965412 0.159501 -0.206252 -14.4736 7.60248 -999.417 0.831629 0.429341 -0.352221 --25.8724 -5.05683 -998.952 -0.355036 0.147238 0.923185 -10.6848 7.88786 -1005.92 0.909174 0.399395 0.117842 --19.2486 56.3345 -956.24 -0.0713088 0.940352 0.332645 -4.81534 8.23104 -1015.98 0.868974 0.291285 -0.400047 --2.19852 8.05909 -1025.37 0.589203 0.515189 -0.622431 --21.5348 55.7483 -955.192 0.0541305 0.545861 0.836125 --20.5559 56.8687 -956.917 0.218898 0.921805 0.319936 -24.7777 -7.51813 -958.506 0.868173 -0.204757 0.452051 -25.3063 -6.51689 -959.366 0.934317 -0.130508 0.331692 --20.1697 56.1594 -955.844 0.108462 0.718064 0.687473 -10.202 8.50874 -1008.25 0.643517 0.593843 -0.482946 -0.0618149 37.3261 -982.019 -0.35372 0.087504 -0.931249 --19.5712 37.7987 -941.959 -0.630443 -0.180395 0.754983 -26.6636 -2.67245 -964.699 0.999063 0.036465 0.0233213 --20.6418 38.4662 -942.501 -0.693947 -0.408754 0.592755 --18.4842 38.0095 -939.695 -0.403549 -0.891479 0.205947 -21.09 0.947959 -980.807 0.993774 0.055233 -0.0967571 -20.6385 2.15578 -983.436 0.985094 0.0689138 -0.157608 --21.4552 39.6482 -941.729 -0.792958 -0.58606 0.166587 --29.7565 39.7847 -964.397 -0.93731 0.34664 0.0359178 -20.8763 0.304811 -979.297 0.985511 0.167918 -0.0239124 -13.3276 7.33736 -1001.95 0.813496 0.514895 -0.270385 --1.20422 5.94767 -1022.3 0.916511 0.0692464 0.393969 --10.0124 57.1774 -947.661 0.180383 0.97983 0.0859921 --11.7988 57.3623 -948.09 0.0102278 0.994905 -0.100294 --13.1464 56.961 -947.565 -0.534486 0.844876 0.0225723 --11.0937 56.6232 -949.075 0.152503 0.958497 -0.240888 -8.70852 7.26395 -1010.49 0.613758 0.742085 -0.269464 --0.718726 6.64532 -1023.91 0.952749 0.298218 0.0577473 -26.2922 -5.563 -962.36 0.973729 -0.0789284 0.213595 --14.9583 53.3526 -945.726 -0.527747 0.697525 0.484709 --0.890407 6.84961 -1024.38 0.793636 0.456549 -0.402127 --14.7207 54.3354 -946.077 -0.840661 0.295184 0.454044 -25.5809 0.479675 -975.123 0.93674 0.0970335 -0.336307 -12.7452 55.2608 -960.077 0.338879 0.256619 -0.905156 --14.7788 54.0238 -947.417 -0.88215 0.466656 0.0635862 --13.9668 53.1589 -944.913 -0.410908 0.0705889 0.90894 -3.95857 57.5784 -963.742 -0.0757937 0.618479 -0.782138 --14.6303 55.4131 -946.898 -0.888792 0.457491 0.0273895 -25.8403 -0.384515 -972.847 0.992966 0.00995064 0.117979 --27.0956 45.8427 -951.564 -0.616403 0.713846 0.332371 -25.8408 -0.253228 -974.138 0.998545 0.0187747 -0.0505527 --25.1727 -38.5655 -946.622 0.23499 -0.587117 0.774644 -26.6371 -3.85384 -966.008 0.989298 0.0511536 -0.136649 --12.9183 -17.9117 -986.849 -0.330588 -0.904217 0.270378 --11.0896 57.286 -962.155 0.390628 0.569842 -0.722973 --20.2572 16.8874 -977.826 -0.724326 0.300671 -0.620442 --25.4689 -16.5286 -1025.61 -0.403663 0.85298 -0.330879 -26.5103 -5.78826 -963.691 0.988513 -0.0786605 0.129054 --27.7587 -33.6571 -999.623 -0.309981 0.135849 0.940987 --25.8307 36.4727 -948.275 -0.925055 0.262495 0.274534 --26.5775 -16.6408 -1026.53 -0.276397 0.956035 -0.0979902 --1.18592 6.30242 -1025.21 0.773774 0.460303 -0.435194 -25.5314 -2.11558 -971.02 0.99912 0.0418112 -0.00343411 -21.8668 -1.43728 -979.213 0.627946 0.556066 -0.544495 --11.7823 -16.476 -963.84 0.15199 -0.988037 0.0261013 -19.5306 2.6227 -989.326 0.948943 0.218019 -0.227981 -13.0845 6.24224 -1004.27 0.625032 0.433221 -0.649349 -9.21509 6.53995 -1011.84 0.614982 0.736252 -0.282365 --1.65693 6.45207 -1026.26 0.638386 0.522824 -0.564905 -3.70362 57.2717 -957.687 -0.158383 0.929821 -0.332185 --21.1632 21.0558 -982.619 -0.181642 -0.792071 -0.582778 -21.6528 -1.42842 -979.721 0.921151 0.313212 -0.231039 -0.988185 57.9316 -956.263 -0.185166 0.831004 -0.524544 -20.4061 0.873603 -985.71 0.988045 0.0789816 -0.132398 -17.9957 3.64027 -993.972 0.926571 0.281414 -0.249544 -11.5207 6.6716 -1007.88 0.878834 0.474504 -0.0499658 -0.0523158 57.8356 -956.298 0.088326 0.937685 -0.336074 -25.8202 -7.98695 -961.925 0.958081 -0.182155 0.221136 --26.3651 47.1214 -955.147 -0.845499 0.28575 0.451085 --9.83002 6.91706 -1015.93 0.349853 0.696723 -0.626243 -14.3439 5.54517 -1002.17 0.86679 0.415304 -0.276039 -2.48692 57.0146 -957.41 -0.136633 0.908838 -0.394138 -11.7784 5.99435 -1006.62 0.753554 0.605325 -0.256394 -3.51761 58.2457 -956.623 -0.128165 0.79024 -0.599245 -4.32285 5.00817 -1016.19 0.413931 0.908237 -0.0613719 -3.90252 5.31163 -1016.86 0.505846 0.859466 -0.0737427 -0.25714 41.7723 -975.941 0.0242459 0.647152 -0.761975 -3.58353 6.16839 -1019.65 0.414836 0.822925 -0.388208 -25.9857 -3.35647 -969.189 0.968862 0.0954739 -0.228456 -6.53939 -18.4482 -979.33 -0.00105558 -0.999339 -0.036326 --0.208928 4.54293 -1024.21 0.930889 0.0704799 0.358438 -24.9048 -0.730886 -976.652 0.751742 0.18426 -0.633192 --24.0556 21.6081 -978.974 -0.980643 0.1944 0.023404 --21.1923 -46.8087 -949.192 0.283367 0.0900428 0.954775 -20.8681 -1.04284 -983.011 0.987246 0.0343258 -0.155457 -9.27976 -24.4258 -968.17 -0.998085 -0.0414781 0.0458916 --23.0212 -48.3142 -948.78 0.228765 -0.518718 0.823771 --7.80147 7.18673 -1014.57 0.14949 0.757087 -0.635982 --28.9733 -42.244 -964.879 -0.985187 -0.130097 0.111721 --19.9405 -47.302 -951.394 0.615898 -0.384399 0.687682 -3.83358 5.16722 -1017.84 0.599789 0.782691 -0.166274 --22.2555 -48.1319 -949.235 0.43701 -0.504109 0.744914 -26.6373 -5.64328 -965.933 0.997659 -0.0648653 -0.0216678 -13.3701 5.52426 -1004.63 0.698922 0.568083 -0.434499 --29.8084 33.1951 -955.271 -0.847505 -0.505758 0.161069 -4.00743 5.87069 -1019.5 0.734687 0.673872 -0.0783012 --0.752361 3.37736 -1023.46 0.912819 0.0875177 0.398876 --0.406137 5.06415 -1025.46 0.818287 0.442837 -0.366471 --33.6134 -32.2529 -1005.63 -0.588604 0.79746 0.132674 -16.8827 3.30456 -997.653 0.925183 0.213026 -0.314095 -4.12736 4.88773 -1018.62 0.854707 0.431996 0.287847 -25.6274 -3.67528 -970.508 0.97727 0.2119 0.00643016 --30.3555 -30.6334 -1007.63 -0.410369 0.816254 0.406604 -25.3093 -1.42627 -976.155 0.854281 0.156708 -0.495628 --32.4768 -31.9064 -1004.85 -0.290872 0.940664 0.17477 -25.7425 -2.63697 -973.727 0.996607 0.0107333 0.081599 --32.2473 -31.6023 -1006.79 -0.358641 0.914951 0.185044 -15.7842 3.52204 -1000.41 0.9767 0.0807068 -0.198855 -14.0598 4.88165 -1003.98 0.857451 0.422453 -0.293787 -12.1771 5.23015 -1007.59 0.812017 0.575421 -0.0975637 --30.9466 -31.5277 -1005.45 -0.375265 0.918159 0.127121 --30.4299 26.7347 -960.016 -0.905715 0.365688 0.214368 -4.24516 5.10499 -1020.21 0.778127 0.291737 -0.556245 -26.3443 -7.62681 -964.535 0.987573 -0.132625 0.0843256 --17.5729 49.8946 -968.119 -0.54087 -0.350246 -0.764714 -8.4889 4.24349 -1014.59 0.123345 0.5394 -0.832967 -20.0731 0.332283 -988.889 0.980642 0.111378 -0.161045 -15.1708 3.58412 -1002.3 0.931544 0.247581 -0.266324 -9.25733 5.67932 -1013.32 0.443061 0.666515 -0.599546 --31.9824 -31.0496 -1007.88 -0.480727 0.763933 0.430473 --1.2537 4.85552 -1027.27 0.664728 0.504582 -0.550939 -25.0825 -10.5118 -961.404 0.911809 -0.275286 0.304668 -26.211 -5.30826 -968.648 0.996387 0.0804169 -0.027308 --8.1589 8.54341 -1013.52 0.315494 0.705078 -0.635082 --24.2732 -1.38563 -949.887 -0.113134 -0.024139 0.993287 --0.041145 20.2691 -991.611 -0.00635797 0.973654 -0.227941 --12.3839 44.0791 -976.754 0.143889 -0.064649 -0.98748 --22.6821 -3.14407 -950.173 -0.407692 -0.382449 0.829168 -20.6017 -1.49688 -985.258 0.993357 0.0267685 -0.111913 -10.3949 5.13819 -1012.33 0.868116 0.47361 -0.148553 --21.6632 -3.13818 -949.336 -0.71702 -0.506787 0.47859 -5.3943 4.31255 -1017.52 0.43447 0.842694 -0.317967 --23.1601 -2.17128 -949.667 -0.656692 -0.660795 0.363463 -24.5032 -2.40865 -978.017 0.70778 0.346619 -0.61555 -23.6788 -2.28015 -978.748 0.527818 0.495498 -0.689847 -1.78696 37.9569 -983.473 -0.271487 0.271178 -0.923449 --23.02 -2.02563 -948.607 -0.739906 -0.669459 0.0660629 --23.9428 -1.22092 -949.721 -0.709066 -0.34844 0.613038 -6.68152 3.90664 -1015.48 0.565024 0.820542 -0.0863634 --8.38371 5.16112 -1018.64 -0.34393 0.611268 -0.712786 -18.5405 1.27321 -994.374 0.941383 0.210027 -0.263984 --23.1084 55.6571 -959.609 -0.740059 0.520018 -0.42649 -3.13874 37.6918 -983.623 0.0458207 0.102423 -0.993685 -10.6199 4.1193 -1011.82 0.866198 0.45559 -0.205279 --32.5954 -45.535 -974.211 -0.660988 -0.724059 -0.197063 -25.8908 -3.5417 -974.543 0.980755 0.189908 -0.0453319 --32.9204 -45.2682 -973.051 -0.932656 -0.353496 -0.0720616 -25.3733 -2.84856 -976.565 0.89777 0.241977 -0.368044 -0.683211 42.0801 -975.944 -0.350644 0.181552 -0.918743 -6.77753 4.01865 -1016.4 0.543032 0.838351 -0.04779 --32.6378 -46.246 -972.218 -0.693275 -0.686934 -0.217925 -0.133732 2.45721 -1024.9 0.907175 0.341295 0.246073 -6.20123 -18.442 -981.145 0.103839 -0.993921 0.0365712 -22.5115 -9.41821 -1015.14 0.919129 -0.346686 -0.187112 --16.9465 18.8583 -980.228 -0.470965 0.17229 -0.865164 -24.5982 -8.49439 -1011.07 0.811294 -0.0543406 -0.582108 -24.9789 -6.64153 -1012.16 0.869292 -0.399218 -0.291474 --0.516128 3.44657 -1027.21 0.747355 0.485785 -0.453291 -24.0855 -7.08234 -1014.68 0.729834 -0.682694 0.0356463 --1.83786 9.46747 -1012.88 0.345313 0.568504 -0.746701 -23.532 -8.12469 -1016.77 0.742128 -0.623085 0.247003 -22.882 -9.38513 -1014.3 0.702441 0.524648 -0.480959 -20.8355 -4.35493 -982.841 0.963188 -0.000439137 -0.268827 -26.259 -8.6944 -966.786 0.994758 -0.0990497 -0.0253959 -26.4339 -4.87901 -973.149 0.941973 0.335623 0.00670916 -21.0854 -5.24703 -981.785 0.876356 -0.0300433 -0.480726 -22.2873 -10.2701 -1017.47 0.861669 -0.410798 0.297946 -10.7157 3.77051 -1012.43 0.927716 0.36839 0.0602628 -10.8094 3.96106 -1013.24 0.918464 0.385647 -0.0877501 -24.0192 -8.54191 -1011.88 0.873042 -0.118613 -0.472999 -0.0521378 2.95751 -1026.94 0.795885 0.466292 -0.386185 -26.2252 -8.25335 -968.118 0.998553 -0.0490101 0.0221315 -26.3926 -7.7769 -969.057 0.97215 0.00702031 0.234256 -24.3031 -5.25525 -953.822 0.774648 -0.629569 -0.0596916 --5.08075 57.73 -964.688 -0.0654634 0.395957 -0.915933 -7.97319 2.80136 -1015.87 0.674878 0.731708 -0.0956216 --6.24243 28.0263 -987.522 -0.175166 -0.596444 -0.783308 --1.63883 5.33992 -1019.77 0.606952 0.67775 -0.415047 --27.9354 -41.4196 -959.293 -0.97125 0.196018 0.135095 -2.46602 2.4863 -1023.23 0.281028 0.94378 -0.174079 -0.324756 10.1252 -1011.02 -0.405296 0.612864 -0.678331 -10.5976 3.79291 -1014.17 0.79547 0.462103 -0.392031 -24.6239 -4.44005 -954.367 0.742872 -0.340315 -0.576478 --0.575688 4.94648 -1019.21 -0.0235326 0.800546 -0.598809 -2.41666 2.29739 -1023.77 0.314346 0.784587 -0.534425 -0.529557 2.06567 -1026.21 0.96543 0.259543 -0.0241351 -26.7397 -5.93004 -971.807 0.966646 0.248259 0.0629496 -26.178 -4.62754 -975.664 0.947561 0.287122 -0.140316 -21.7347 -5.27547 -980.823 0.724434 0.0959119 -0.682639 -23.3216 -4.80918 -956.31 0.812577 -0.0758525 0.577897 -23.1187 -2.71576 -956.178 0.957374 0.181342 0.224836 -7.32198 3.27441 -1017.93 0.436867 0.783181 -0.442465 -22.4278 -5.63146 -980.357 0.519947 0.125615 -0.844912 -23.1659 -3.47932 -956.289 0.967498 0.0280208 0.251321 -23.3261 -2.71795 -955.642 0.77265 0.0355002 -0.633839 -11.1525 3.03619 -1012.52 0.799405 0.573489 -0.179057 --28.7055 -7.26613 -951.079 -0.797329 -0.230836 0.557658 -3.20375 1.97361 -1023.35 0.697423 0.67006 -0.254207 -24.7103 -4.47451 -953.982 0.988222 -0.152072 0.0170858 -26.8706 -7.26312 -970.864 0.971881 0.163968 0.169005 -23.11 -4.78975 -955.444 0.804817 -0.539137 -0.248196 -24.7566 -1.59693 -954.457 0.85401 0.215156 -0.473682 -19.1484 -1.05035 -993.799 0.955682 0.182645 -0.230895 -24.6517 -2.94229 -954.817 0.825346 -0.0576261 -0.56168 -15.7141 1.58295 -1003.79 0.828489 0.553031 -0.088105 -14.3702 2.72442 -1007.26 0.74272 0.638441 -0.201891 -25.5972 -11.7139 -964.685 0.934034 -0.218493 0.28256 --8.76744 54.259 -967.823 -0.175612 0.880215 0.440887 --9.59054 54.0568 -967.306 -0.00747693 0.998882 0.0466725 -25.8306 -5.06734 -977.254 0.897853 0.260873 -0.35469 -24.5522 -5.15544 -979.211 0.59918 0.222286 -0.769137 -21.5894 -6.95859 -981.054 0.717526 -0.0183504 -0.69629 -20.6554 -6.79673 -982.647 0.949313 -0.122993 -0.289273 --12.0257 55.6303 -964.081 0.176761 0.846617 -0.501991 --9.49936 54.7525 -964.736 0.0640082 0.919252 -0.38843 -26.248 -9.44206 -968.714 0.9595 -0.0934454 0.265759 --9.02359 0.733285 -1028.1 -0.985545 0.156012 -0.0660479 -20.5074 -5.23252 -985.559 0.992736 -0.0749049 -0.0941487 -19.5681 -2.17767 -992.838 0.966353 0.10705 -0.233885 -22.5305 -42.2888 -974.503 0.684033 0.277691 -0.674527 --25.8812 -0.156892 -984.549 -0.994397 0.0280433 -0.101925 -15.5912 1.62745 -1006.21 0.600148 0.799691 0.0178077 --10.4974 54.9224 -964.942 0.314094 0.918938 -0.238532 --0.587158 1.76259 -1029.15 0.66841 0.518499 -0.53328 --12.1516 55.2314 -965.389 -0.0729715 0.972067 -0.22307 -26.9071 -6.41063 -973.7 0.977938 0.203088 -0.0489182 --8.41646 54.8568 -964.731 -0.305833 0.724381 -0.61785 --12.9548 -16.3731 -956.821 -0.288305 -0.940659 0.178998 -16.7677 -0.059373 -1000.76 0.929196 0.361193 -0.0783229 -11.9143 -21.0295 -1029.14 0.433901 -0.12243 -0.892604 -3.50061 0.736288 -1021.72 0.954909 0.173544 0.240898 -0.271486 1.71183 -1028.05 0.816131 0.456338 -0.354522 -25.3404 -5.32298 -978.389 0.827708 0.225074 -0.514043 --23.0117 -5.48876 -998.429 -0.443639 -0.000584094 0.896205 --13.1679 9.11486 -1016 -0.376161 0.610857 -0.696675 --13.2539 8.63247 -1016.18 -0.756746 0.0668828 -0.650279 -17.8682 -1.16355 -997.859 0.937195 0.252472 -0.240671 -14.1674 2.30473 -1009.12 0.763897 0.615006 -0.195521 --13.0398 6.58544 -1016.4 -0.944963 0.327136 0.00513194 --27.9201 -35.2551 -948.976 -0.507058 0.172627 0.844448 -9.05668 1.97075 -1017.38 0.775828 0.629697 0.0396561 -25.9987 -11.6806 -966.5 0.98939 -0.0539579 0.134892 -26.0168 -10.6499 -968.329 0.994718 0.0224725 0.100158 --6.94733 13.4885 -1006.98 -0.182442 0.70158 -0.68884 --16.3849 20.4379 -980.771 0.0462389 -0.447442 -0.893117 -27.0608 -8.78217 -971.292 0.990295 0.0381401 0.133647 -16.8841 -0.306106 -1001.23 0.810111 0.583866 0.0531228 -16.5858 0.564642 -1003.79 0.481683 0.852473 0.203156 -13.9376 2.26201 -1009.65 0.591526 0.666033 -0.454419 --13.0117 7.63013 -1016.34 -0.906883 0.0785823 -0.41399 --15.9706 22.2673 -981.713 0.228609 -0.52252 -0.821408 --0.131019 20.1089 -993.14 0.18589 0.938204 -0.291922 -3.6876 1.12542 -1023.42 0.876334 0.104369 -0.470262 --6.59813 43.0205 -976.972 -0.303586 0.130748 -0.94379 --13.8368 7.10096 -1012.9 -0.684813 0.407735 -0.603973 --12.8608 7.31758 -1017.03 -0.761303 0.599924 -0.245986 -20.3686 -7.16443 -984 0.975785 -0.196154 -0.0967843 -17.7251 -1.34464 -998.79 0.917027 0.364503 -0.16186 -15.267 1.75321 -1008.1 0.454632 0.88268 -0.119106 -3.82663 1.01761 -1022.61 0.945819 0.298328 0.128169 --13.6613 6.30795 -1014.79 -0.864481 0.453511 -0.216797 --13.5502 6.70239 -1014.58 -0.990596 0.0505414 -0.127145 --13.7967 6.21312 -1013.94 -0.902398 0.425966 -0.0650454 -0.102761 12.7112 -1005.41 0.180397 0.909089 -0.375517 -22.87 -16.2876 -963.061 0.763136 -0.064237 0.643038 -19.992 -3.86928 -991.477 0.983638 0.0594868 -0.170052 --19.4439 26.1479 -980.439 -0.423397 0.881183 -0.21036 -12.5337 1.54743 -1012.66 0.581694 0.705218 -0.405339 --29.5861 -33.1296 -1000.04 -0.31038 0.296155 0.903303 -27.0005 -7.43253 -974.536 0.991789 0.100362 -0.0792587 -20.2683 -6.77536 -986.342 0.987243 -0.149571 -0.0545887 --17.2513 21.8991 -982.024 0.408013 -0.531042 -0.742644 -18.8737 -2.73527 -995.513 0.953376 0.168775 -0.250179 -17.3895 -0.0755726 -1003.02 0.332125 0.86588 0.374091 --20.8872 25.7925 -978.95 -0.344415 0.911133 0.226308 -14.8259 1.64122 -1009.94 0.2898 0.925765 -0.24285 --20.8571 26.0408 -980.411 -0.205707 0.977475 -0.0471965 -26.5558 -6.79842 -976.501 0.944767 0.159356 -0.286393 --19.5671 25.8737 -978.042 -0.534796 0.83201 0.147485 -20.1247 -9.24114 -982.78 0.901799 -0.29578 -0.315077 -3.35459 -1.29377 -1021.18 0.95252 0.285036 -0.107051 -26.0642 -13.2673 -967.074 0.966412 -0.136312 0.21787 -26.391 -12.039 -968.315 0.988274 0.0764178 0.132192 -8.83797 54.5024 -961.556 0.138585 0.912251 -0.385477 -9.43575 -23.1612 -966.349 -0.996627 0.0110197 0.0813271 --31.0275 -48.6911 -964.33 -0.693956 -0.719007 0.0381305 --33.1598 -31.7324 -1008.35 -0.693236 0.703935 0.154591 -5.47637 10.1942 -1010.38 0.953677 0.277191 -0.116899 -3.8452 9.69557 -1013.32 0.869977 0.486382 0.0810651 -4.1544 9.23828 -1012.65 0.720193 0.354322 -0.596471 -1.79942 55.689 -963.822 -0.198123 0.56266 -0.802597 -12.3721 1.22066 -1013.56 0.564648 0.786131 -0.251339 --13.068 22.0932 -981.977 -0.503374 -0.209922 -0.838181 --13.0592 20.7384 -994.181 -0.20549 0.978597 0.011065 -9.56412 0.714513 -1017.07 0.853638 0.238339 0.463138 -0.872929 -0.438985 -1027.66 0.939065 0.318525 -0.129226 -5.2018 11.351 -1012.24 0.774238 0.153123 -0.614093 -27.1574 -9.32234 -972.985 0.99873 -0.0501102 -0.00525007 -2.69597 10.9346 -1013.3 -0.261206 0.786106 -0.560186 -11.8797 1.62488 -1015.12 0.729165 0.610199 -0.309799 -11.001 -23.3388 -1001.55 0.526941 -0.813435 0.246287 -5.62165 11.3562 -1011.42 0.961351 0.0807981 -0.263202 -26.8545 -10.7803 -970.971 0.956362 -0.157884 0.245854 -3.09238 11.1858 -1013.15 -0.102193 0.679795 -0.726248 -20.026 -4.75967 -991.464 0.992462 0.0120735 -0.121956 --3.81819 -11.59 -941.227 -0.8447 0.0716922 0.530418 -18.0588 -2.01707 -999.231 0.815123 0.560859 0.144955 -3.47083 10.4969 -1013.47 0.631127 0.450711 -0.631299 -5.15221 9.29974 -1011.86 0.643536 0.520819 -0.5609 -1.28625 -1.45859 -1026.43 0.837043 0.524915 -0.154348 -4.95124 9.71076 -1011.97 0.844574 -0.0660532 -0.53135 -24.7886 -7.93145 -979.536 0.578898 0.032579 -0.814749 -16.7198 1.35617 -1009.42 0.183686 0.982407 0.0337076 --12.6213 23.2266 -983.246 -0.446125 -0.698854 -0.559085 -26.5035 -12.5104 -969.228 0.995886 -0.0862993 -0.0276285 --3.05441 49.3737 -973.678 0.101552 0.900555 -0.422716 -18.4618 -3.00118 -998.146 0.932209 0.36063 -0.0305531 -17.562 0.866032 -1007.1 0.319825 0.937918 0.134245 -22.9794 -43.1986 -963.341 0.626743 0.51991 0.58042 -3.10759 -1.53604 -1023.82 0.694437 0.605414 -0.388885 -0.446333 48.633 -973.947 -0.0868119 0.980087 -0.178589 -0.990065 49.2965 -971.116 0.119973 0.905781 -0.406408 -22.8544 -19.1618 -962.856 0.815173 0.0202988 0.578862 -25.6714 -14.8469 -966.864 0.906306 -0.259089 0.333891 -4.96473 48.9893 -972.84 0.0924775 0.977112 -0.191574 -26.4337 -11.8486 -970.561 0.984298 -0.0492586 0.169505 -23.4297 17.2152 -967.107 0.972777 -0.224467 0.0576206 --0.931894 49.1385 -973.235 0.254504 0.862608 -0.43719 -23.7502 -17.816 -964.319 0.639618 0.296676 0.709135 -26.3347 -12.2988 -970.541 0.96375 -0.266316 0.0161701 -3.15973 49.3152 -971.538 -0.181207 0.814135 -0.551678 --3.61392 38.1597 -982.789 0.351857 0.27894 -0.893526 -12.4364 0.929247 -1015.43 0.58631 0.703172 -0.402231 -1.52498 -1.55874 -1027.67 0.826345 0.547112 -0.1335 -1.04071 -0.844407 -1029.38 0.937564 0.317923 -0.141065 -24.6353 -16.366 -965.633 0.867944 -0.144446 0.475193 -4.62846 7.00696 -1014.92 0.873991 -0.344251 -0.342974 --17.3218 52.3173 -970.175 -0.577284 0.300211 -0.759352 -26.8698 -8.98904 -976.035 0.981512 0.0166463 -0.190673 -26.2328 -8.51934 -977.915 0.890653 0.063619 -0.45021 -25.6916 -8.52379 -978.713 0.751207 0.0507719 -0.658111 --32.4643 -13.5418 -977.576 -0.940046 0.234559 -0.247581 --0.684056 48.4771 -974.356 0.124121 0.84376 -0.522172 -0.735878 -0.906317 -1030.2 0.716226 0.479905 -0.506667 -26.2634 -14.1014 -968.794 0.980148 -0.195029 0.0356846 -4.09491 48.9815 -972.651 -0.167525 0.976393 -0.136355 -18.8712 -3.66942 -998.221 0.777805 0.532701 0.333539 -16.3022 1.29066 -1011.25 0.035798 0.993976 -0.103589 --19.1575 -4.43195 -1029.51 -0.943745 0.0513774 -0.326659 --18.9434 6.25726 -1005.02 -0.910477 0.412781 0.0253452 -13.2557 0.493157 -1015.02 0.147884 0.945772 -0.289215 -1.86693 -1.80975 -1027.56 0.404072 0.908052 -0.110308 --17.4022 -48.0809 -961.824 0.984 -0.09528 0.150549 -26.6996 -12.0993 -971.881 0.963935 -0.255622 0.0740771 --16.727 -49.3851 -956.068 0.97074 0.158673 0.180239 -10.2543 0.193481 -1018.53 0.924732 0.350418 0.148583 -19.7868 -8.83061 -988.496 0.971882 -0.234572 -0.0205142 -19.6368 -5.72526 -993.687 0.984248 0.0811578 -0.157067 -19.0563 0.23009 -1006.33 0.317108 0.93344 0.167727 --16.6368 -49.5787 -956.579 0.994202 -0.0917312 0.0561081 -10.3293 -0.801618 -1017.93 0.776216 0.627262 -0.0634899 --17.3921 -49.3424 -960.394 0.922057 -0.255476 -0.290762 --20.5968 36.2435 -976.108 -0.293072 0.929016 -0.225918 -26.9409 -10.7175 -975.076 0.985442 -0.142439 -0.0928165 --18.0477 -45.7718 -959.743 0.95796 0.249411 -0.1418 --16.7612 -48.818 -958.813 0.967129 -0.0619731 -0.246618 --17.6609 -45.3314 -961.223 0.91016 0.0950195 0.403213 -19.9353 -7.3314 -991.856 0.993353 -0.0792343 -0.0834938 -11.6652 -21.1458 -961.591 -0.810857 0.0673716 0.581354 --4.24652 8.7718 -1020.85 0.199647 0.431828 0.879583 -1.44296 -2.21366 -1029.32 0.646987 0.701583 -0.298646 -0.527219 -1.55996 -1030.98 0.601912 0.428187 -0.674061 -22.6861 -21.2113 -962.761 0.853118 -0.0337133 0.520627 -23.2262 -20.4976 -963.82 0.879859 -0.0544515 0.472106 -26.7649 -11.8428 -973.852 0.844553 -0.429862 -0.319294 --6.39388 6.66256 -1019.12 -0.336394 0.928535 -0.157039 --4.52167 11.8096 -1022.34 0.3072 0.743611 0.593862 --4.7475 11.1203 -1021.74 0.190613 0.48165 0.855383 -19.2631 -5.33383 -996.333 0.952242 0.295563 0.0766629 -10.6909 -1.03878 -1018.13 0.167056 0.887862 -0.428711 -25.5965 -14.4369 -971.23 0.962811 -0.246093 -0.111507 --6.78297 10.5656 -1021.77 -0.478874 0.345257 0.807142 -17.3511 1.25476 -1012.57 0.0052264 0.993371 -0.114833 --5.17813 8.82226 -1020.72 0.0286818 0.436582 0.899207 -19.1422 -10.877 -987.549 0.881818 -0.471076 0.022019 --5.41544 7.48914 -1019.99 -0.128512 0.606031 0.784991 -24.9297 -17.2934 -967.122 0.96197 -0.235996 0.137549 --5.48402 6.78368 -1019.03 -0.0392536 0.974409 0.22133 --7.02337 9.28764 -1021.48 -0.628346 0.252801 0.735713 --22.8963 -37.9925 -946.894 -0.673239 -0.577047 0.462349 -19.5511 -5.67305 -997.353 0.821743 0.352806 0.447511 --8.83126 18.285 -995.703 -0.0860653 0.814888 -0.573193 -21.253 -0.594391 -1004.45 0.31106 0.934405 0.173577 -10.8323 -1.3628 -1018.98 0.469998 0.874453 -0.120141 -10.6441 -0.959283 -1019.78 0.928075 0.352147 0.121117 --8.71071 19.2342 -993.594 0.104185 0.959062 -0.263335 --6.034 11.3045 -1021.85 -0.130298 0.528724 0.838733 -25.3162 -15.9231 -970.657 0.959892 -0.269372 -0.0777549 -21.9482 -1.71125 -1002.14 0.354991 0.765575 0.536541 -19.3838 0.967579 -1010.25 0.270515 0.954518 0.125369 -20.0183 -7.165 -997.317 0.789616 0.204712 0.578446 -1.10285 55.8811 -963.63 -0.232443 0.512769 -0.826462 -24.121 -19.7962 -965.228 0.883509 -0.0525558 0.465456 --26.4974 -3.52244 -949.115 -0.206163 0.137404 0.968823 -18.7269 1.18415 -1011.67 0.123131 0.992207 -0.019105 --7.80929 24.6239 -930.768 0.107888 -0.972904 0.204496 -19.5268 -6.94482 -995.967 0.987452 0.107893 0.115311 --4.83174 39.6573 -982.599 0.287338 0.287593 -0.913634 --12.9665 24.3029 -932.481 -0.172651 -0.884138 0.434156 --10.0015 25.1448 -929.567 -0.174875 -0.0727711 0.981898 -10.9562 -1.42184 -1020.53 0.606287 0.791381 -0.0783035 -24.8224 -18.2369 -976.398 0.995713 -0.0276678 0.0882669 --10.4258 24.9045 -929.811 -0.0959715 -0.843705 0.528159 --8.55174 24.3346 -932.485 0.095325 -0.917195 0.386869 -22.7413 -1.46866 -1003.31 0.435488 0.849728 0.297176 -25.0684 -17.7049 -969.09 0.999393 -0.0296903 0.0182266 --11.8645 23.9328 -933.028 -0.035896 -0.870843 0.49025 -19.5986 -9.60357 -993.339 0.978361 -0.203161 -0.0391726 -6.53923 -1.51317 -1026.74 0.0231297 0.995551 0.0913365 -24.6867 -19.8499 -966.599 0.950263 -0.0270419 0.310271 --14.0879 56.0795 -963.643 -0.112911 0.213987 -0.970289 -26.2221 -13.4872 -976.575 0.962809 0.181528 0.200115 -26.1655 -13.1179 -977.462 0.975476 0.201816 -0.0878432 -1.28954 -17.8815 -947.535 0.934125 -0.31534 -0.167244 -19.5629 -8.70968 -994.701 0.996167 -0.0703504 -0.0519797 -23.2069 -2.31318 -1002.23 0.519827 0.688698 0.505445 -19.8426 0.963726 -1012.17 0.301305 0.953349 -0.0184834 -11.8551 -1.76764 -1020.93 0.0727921 0.995662 -0.0579596 -1.35629 2.66219 -1020.67 0.288803 0.588964 -0.754794 -25.0017 -16.5257 -972.718 0.951231 -0.169023 -0.258051 -26.167 -14.1185 -976.414 0.98916 -0.0879782 0.117565 -25.8685 -13.3288 -978.229 0.884501 0.0010929 -0.466537 --14.5774 41.6417 -975.049 -0.599736 -0.48331 -0.637752 -7.51694 -1.73321 -1026.07 0.229558 0.94693 0.225003 --5.48201 20.5943 -991.235 -0.423145 0.542521 -0.725685 -6.51699 -1.60612 -1027.89 -0.00689571 0.97383 -0.227175 --16.9433 42.4467 -973.166 -0.419344 -0.403659 -0.813148 -25.1253 -16.9408 -971.925 0.983958 -0.15284 -0.0920139 -24.4279 -16.3414 -974.26 0.982968 -0.173556 -0.0604316 --7.20373 17.8064 -996.934 -0.195398 0.823016 -0.533352 -18.9963 -11.3386 -991.502 0.933235 -0.358566 0.0224066 --14.0926 43.2405 -976.468 -0.156455 -0.326873 -0.932028 --23.8362 -41.2096 -949.918 -0.191452 -0.519025 0.833042 --16.2804 39.2195 -973.567 -0.299251 0.508282 -0.807526 -22.1463 -0.682335 -1008.14 0.410087 0.907705 0.0888862 -20.9469 0.398837 -1010.74 0.444706 0.888476 0.113345 -17.6892 0.715135 -1015.69 0.013078 0.979686 -0.200109 --19.031 -21.4592 -957.479 0.492644 0.152031 0.856848 --17.4051 42.1882 -973.046 0.145455 -0.107049 -0.983557 -23.6009 -3.48123 -1001.35 0.585948 0.51894 0.622388 -1.47648 -17.2939 -947.045 0.996923 -0.0582172 -0.0524878 -7.50728 -1.61386 -1027.06 0.244329 0.967933 -0.058381 --17.0089 41.2794 -972.682 0.101134 -0.120093 -0.987598 --15.8637 43.4522 -975.833 -0.569446 -0.507425 -0.646723 -23.3147 -1.32475 -1005.6 0.469524 0.879169 0.081303 --16.6563 42.61 -973.551 -0.633078 -0.534999 -0.559454 -22.4697 -25.9522 -962.68 0.836203 -0.0624461 0.544853 --13.6129 40.3845 -975.285 -0.653365 -0.129537 -0.745878 -19.6986 0.806718 -1014.05 0.18608 0.969272 -0.160893 -8.70824 -2.52248 -1024.88 0.417575 0.907453 0.0464813 -24.7215 -17.4948 -973.545 0.996286 -0.0832309 -0.0220804 -19.5876 -9.2821 -996.213 0.941133 -0.0668807 0.331355 -22.8147 -5.26254 -999.587 0.540737 0.368753 0.756059 -24.1624 -2.36266 -1003.62 0.705858 0.662532 0.250632 -9.78977 54.5353 -961.736 0.0197639 0.915089 -0.402767 -23.8289 -1.72444 -1005.07 0.634457 0.769294 0.075172 -20.8931 0.529781 -1012.7 0.499415 0.865631 -0.0356049 -8.62986 53.7289 -965.552 0.0302259 0.999483 0.0109699 --11.518 49.4939 -970.837 0.10776 0.681121 -0.724197 -12.0116 -1.45581 -1022.83 0.0666597 0.997663 -0.0149792 -11.8978 -1.53668 -1023.24 0.0339287 0.931745 -0.361525 --9.17295 19.4248 -993.537 0.547499 0.799198 -0.248048 --7.23689 40.1166 -982.228 -0.399025 0.235389 -0.886211 -25.0482 -18.977 -971.208 0.979588 -0.0532892 -0.193823 -22.7665 -0.967723 -1009.04 0.574099 0.818098 0.0335535 -9.22676 53.3903 -963.307 0.107137 0.884791 -0.453505 -20.5653 0.502865 -1014.11 0.406218 0.891727 -0.199521 -18.4826 0.416834 -1016.59 0.141281 0.944025 -0.298088 -11.2412 53.298 -963.938 -0.00570127 0.998008 -0.0628347 -11.6847 54.0633 -961.821 0.329714 0.905798 -0.266117 --10.2124 14.0895 -1004.41 0.610183 0.692968 -0.384021 -7.19983 -2.27525 -1029.71 -0.0190848 0.783832 -0.62068 -10.8848 54.2469 -961.964 0.117819 0.900611 -0.418351 -18.9802 -11.7691 -995.055 0.95563 -0.287497 0.0641639 -24.1776 -4.89554 -1000.99 0.752192 0.334594 0.567674 -24.3888 -3.37692 -1002.51 0.764202 0.489879 0.41954 -25.254 -15.6736 -978.543 0.778201 -0.167122 -0.60537 -11.4765 54.6682 -960.555 0.232681 0.766224 -0.598966 -25.2497 -21.1078 -968.764 0.996962 0.0134237 0.0767275 -14.0781 -1.63057 -1021.27 0.0191519 0.970374 -0.240848 -9.92609 -3.68814 -1025.37 0.722783 0.658534 -0.209565 --20.104 5.86139 -1007.14 -0.941843 0.168887 0.290534 --19.7254 4.29101 -1006.2 -0.928582 0.361484 0.08405 -19.3892 -10.815 -996.631 0.878075 -0.31918 0.356522 -22.239 -0.349862 -1012.37 0.629477 0.775782 -0.0438273 -23.2937 -26.0102 -964.216 0.865494 -0.0543756 0.49796 --5.50495 56.1019 -965.268 -0.306596 0.515061 -0.800444 -22.9194 -6.50852 -999.194 0.596 0.154118 0.788055 --28.8408 -6.81568 -983.052 -0.31564 0.0480118 -0.947663 -24.9479 -3.27473 -1004.27 0.87734 0.445623 0.178028 --6.66883 20.1804 -989.048 -0.450728 0.807154 -0.381243 -9.9766 -3.10207 -1026.33 0.828205 0.509398 0.233647 -9.79091 -2.53135 -1027.33 0.528597 0.844845 0.0825953 -8.11027 -2.25148 -1029.54 0.218095 0.879588 -0.422799 --19.4181 5.65349 -1006.11 -0.865662 0.043342 0.498749 -24.2479 -19.7264 -973.271 0.994666 -0.0716974 -0.0741537 -24.9515 -4.18999 -1002.95 0.910719 0.264693 0.317061 --28.1932 47.6699 -960.054 -0.62236 0.507673 -0.595765 --20.7079 3.52284 -1007.73 -0.937099 0.253353 -0.24012 --20.8976 3.271 -1008.07 -0.820064 0.427767 -0.380145 -24.2405 -19.9299 -973.782 0.943549 0.104102 0.31445 -23.8962 -6.34132 -1000.09 0.736592 0.146793 0.660216 -20.0871 -0.0538281 -1016.75 0.383166 0.872787 -0.302367 -10.0129 -2.71675 -1027.81 0.721108 0.674132 -0.159842 -24.6495 -5.4567 -1001.51 0.872436 0.178238 0.455069 -21.6326 -6.65039 -998.394 0.448679 0.267323 0.852775 -24.939 -2.86065 -1007.06 0.83073 0.55665 -0.00533199 --6.4994 52.2844 -971.783 -0.0768329 0.110468 -0.990905 -21.9931 -0.465061 -1014.15 0.645561 0.740475 -0.186941 --5.77778 32.9177 -981.393 -0.373159 0.361465 -0.854456 --7.81508 34.3201 -980.549 -0.344566 -0.132902 -0.929307 --9.20861 34.1932 -980.016 0.0707292 0.102842 -0.99218 -17.8817 -0.689824 -1019.46 0.119967 0.874162 -0.470583 --8.88647 36.4157 -981.375 -0.362196 -0.515095 -0.776847 -14.3496 -1.67726 -1022.46 0.098646 0.992156 -0.0767756 -9.2741 -2.55587 -1029.1 0.552293 0.73018 -0.402255 --5.99557 34.1094 -981.105 -0.336192 -0.153169 -0.929255 -23.6002 -1.63855 -1011.71 0.737531 0.669139 -0.0911085 -14.9044 21.5841 -977.656 0.541698 -0.373583 -0.752994 -19.0931 -0.341493 -1018.28 0.228916 0.889571 -0.395298 -3.11175 -1.92136 -1027.24 0.00649268 0.989199 -0.146434 --8.94805 5.00527 -1018.79 0.199911 0.549945 -0.810923 --18.2035 -35.4293 -1007.38 0.170903 -0.955031 -0.242296 --9.89901 35.1817 -980.346 0.441822 -0.185995 -0.87761 --9.00856 37.3325 -981.681 -0.631022 0.0498147 -0.774164 -10.4662 -3.37021 -1028.25 0.925431 0.339223 -0.168837 --13.7095 -25.4556 -1004.81 -0.566893 -0.733498 0.374983 --9.09573 35.1432 -980.169 -0.179967 -0.441804 -0.878875 -24.0779 -26.3378 -965.489 0.86038 -0.0613933 0.505942 -24.8876 -19.6498 -975.753 0.911414 0.404907 0.0733151 -6.94244 22.436 -983.913 0.668589 0.421193 -0.61285 -13.5958 52.2423 -956.531 0.968613 -0.191607 0.158355 -15.6462 26.9591 -978.699 0.405328 0.503064 -0.763305 -25.355 -3.70065 -1006.28 0.940993 0.337977 0.017422 --18.2005 53.0342 -965.453 -0.0536274 0.964162 -0.25984 -8.26039 21.3113 -983.31 0.598297 0.559644 -0.573445 -25.2563 -20.3137 -975.275 0.893584 0.354901 0.274868 -3.94293 22.8332 -991.56 -0.248127 0.724703 -0.642836 -24.6438 -7.03811 -1001.08 0.858894 0.0720286 0.507064 -21.4674 -0.823641 -1016.48 0.626861 0.718566 -0.301179 -20.8777 -0.720882 -1017.33 0.498551 0.775792 -0.386774 -25.1679 -24.7656 -967.948 0.981595 -0.0170853 0.190207 -19.5984 -1.0148 -1019.21 0.351475 0.772726 -0.528544 --6.43081 21.178 -988.017 -0.559115 0.684248 -0.468183 -17.3125 -2.1 -1021.77 0.22155 0.852889 -0.472753 --26.9989 -37.2145 -999.254 -0.311745 -0.292162 0.904133 -9.6932 23.7178 -983.783 -0.384403 -0.272411 -0.882058 --26.9268 41.2826 -962.458 -0.45679 0.736604 0.498756 -24.1718 -8.09212 -1000.31 0.796311 -0.0250658 0.604367 -10.1658 24.7447 -984.34 -0.377482 -0.298247 -0.876673 -16.4288 -2.13727 -1023 0.318136 0.810167 -0.49236 --1.75221 54.5505 -969.186 0.344231 0.598477 -0.723416 -23.8645 -9.33581 -1000.08 0.759275 -0.165124 0.629473 -25.6485 -4.95043 -1005.24 0.963722 0.227104 0.140229 -16.3222 24.7443 -979.227 0.42089 0.0388326 -0.90628 -25.5069 -20.3465 -976.634 0.971654 0.233471 0.0371496 -24.1321 -2.62304 -1012.3 0.865582 0.469411 -0.174416 -22.9815 -1.81076 -1014.75 0.80766 0.530417 -0.257572 -15.3961 22.7841 -978.77 0.599201 -0.584717 -0.546867 -1.44017 51.6935 -970.631 -0.446629 -0.232554 -0.863968 -24.6206 -26.9807 -966.593 0.92302 -0.0622943 0.379676 -9.85164 21.245 -982.366 0.466471 0.264618 -0.844027 -25.2544 -20.1056 -977.569 0.931793 0.172177 -0.319557 -25.2515 -3.85694 -1009.19 0.924756 0.36411 -0.110679 -25.1868 -24.9899 -969.29 0.985072 -0.0590764 -0.161688 -12.9011 22.5297 -981.23 0.4671 -0.629827 -0.620592 -15.4565 24.7994 -980.157 0.87515 -0.237983 -0.42128 -24.9946 -3.71969 -1010.5 0.925816 0.328396 -0.187138 -22.3704 -1.84508 -1016.56 0.750279 0.556787 -0.356469 --7.26033 21.8786 -986.252 -0.0567047 0.740942 -0.669171 -24.1485 -23.8375 -972.531 0.988254 -0.0655442 -0.138052 -14.6337 24.1174 -981.519 0.723458 -0.494864 -0.481371 --8.85258 22.2569 -986.246 0.246206 0.645431 -0.72305 -24.2036 -28.5312 -966.081 0.877094 -0.105781 0.468526 -13.4877 21.1073 -979.615 0.729781 -0.270323 -0.627969 -11.8573 20.8928 -981.243 0.652996 0.156497 -0.741016 -24.2265 -23.566 -973.299 0.943706 -0.00861039 0.330673 -12.2901 21.573 -980.903 0.558648 -0.290484 -0.776873 -20.5977 -1.84674 -1019.5 0.598307 0.648365 -0.470799 -25.0734 -27.1857 -968.038 0.983581 -0.103046 0.148154 -24.2986 -24.8696 -972.181 0.953344 0.262839 0.148495 --0.1478 23.0527 -986.222 0.0540389 0.768672 -0.637356 -24.7666 -9.99053 -1001.53 0.840612 -0.137446 0.523908 --15.7109 10.4122 -1001.52 -0.881242 0.468386 0.0634523 -24.7084 -24.2658 -974.286 0.946694 0.207738 0.246202 -25.8106 -8.98307 -1003.14 0.918303 0.0276622 0.39491 --13.7315 18.0933 -992.709 -0.906951 0.38585 0.168998 --16.1074 10.4288 -1000.87 -0.403475 0.396253 -0.824737 -24.9855 -28.1033 -968.994 0.989757 -0.130214 -0.0585316 -24.5683 -26.0142 -971.906 0.932058 0.147134 0.331087 --15.3924 11.2941 -1001.5 -0.793533 0.607694 -0.0318352 -25.9098 -5.90078 -1008.41 0.962688 0.22544 -0.149693 --15.3173 11.9347 -1001.11 -0.492224 0.309061 -0.813755 -21.4912 -2.79099 -1019.45 0.70611 0.517227 -0.483616 --27.4783 49.9535 -954.427 -0.89176 0.018575 -0.452127 -3.676 25.1995 -986.177 0.328911 0.493762 -0.804995 -17.1764 21.0346 -977.231 0.103276 -0.63002 -0.769681 -12.4754 -36.364 -1004.45 -0.313543 -0.920154 -0.234537 --14.1194 19.1942 -994.65 -0.991392 0.0942241 -0.0909005 -25.4355 -5.51476 -1010.59 0.964431 0.138052 -0.225419 -24.0521 -4.3137 -1015.02 0.909946 0.310434 -0.275007 --14.0811 15.6017 -1000.18 -0.922131 -0.210845 -0.324375 -24.5094 -27.0151 -971.159 0.997044 -0.0683032 0.0351812 -25.2786 -23.1185 -976.921 0.919814 -0.14876 -0.363061 --14.1098 14.9405 -1003.42 -0.710017 0.543468 0.447792 -26.2743 -7.19387 -1006.8 0.980632 0.195732 0.00708482 --18.7506 52.4724 -966.726 -0.208644 0.735029 -0.645135 -22.5014 -3.78408 -1018.66 0.827685 0.403834 -0.389687 -6.33418 56.2729 -963.98 0.606476 0.339408 -0.719019 --13.6494 16.4025 -1000.92 -0.675433 0.142699 -0.723483 --13.3113 15.0264 -997.313 -0.772092 0.609439 0.180162 -9.59641 -28.623 -1028.14 0.0855076 -0.78075 -0.618965 -24.9649 -24.8999 -975.543 0.91104 0.410116 -0.0425503 -26.361 -8.78547 -1005.34 0.963599 0.102429 0.246953 -25.0072 -24.8888 -976.493 0.956445 0.0673286 0.284042 -8.22551 52.5928 -967.655 0.372269 0.723858 -0.580901 -23.2907 -4.74204 -1017.69 0.89448 0.263636 -0.361112 -20.9718 -3.96537 -1021.16 0.692466 0.444058 -0.568598 -25.7873 -6.98593 -1009.89 0.920717 -0.10471 -0.375921 --12.8347 15.23 -1002.41 -0.256592 0.962893 0.0836557 --13.2565 14.9855 -1001.62 -0.90273 0.32325 -0.28388 --0.489838 53.7622 -969.51 0.002672 0.5082 -0.861235 -20.1028 -4.4106 -1022.29 0.546526 0.477682 -0.687844 -22.0255 -34.8906 -963.757 0.78013 0.0197869 0.625304 --13.4798 17.6045 -995.754 -0.933377 -0.0981274 -0.345223 --16.3432 12.1031 -1000.98 -0.300999 0.391539 -0.869538 -23.7644 -5.59591 -1016.88 0.938467 0.151945 -0.310148 -8.44825 15.556 -996.985 0.350979 0.751067 -0.559207 -22.2357 -4.70991 -1019.92 0.812674 0.31297 -0.49154 --13.6532 13.1168 -1001.33 -0.911273 0.387127 -0.140407 -16.4443 -21.9711 -959.201 -0.0164319 0.0172043 0.999717 --13.9669 17.2935 -993.632 -0.9539 0.139014 -0.265988 -26.1113 -7.94515 -1009.03 0.910425 0.144556 -0.387596 --13.9694 14.3932 -999.96 -0.858679 0.302885 -0.413439 --13.9914 13.2116 -1002.61 -0.774803 0.628307 0.070076 -25.2641 -12.556 -1003.22 0.821279 -0.228154 0.522921 --13.4919 14.8914 -1002.75 -0.742354 0.539982 0.396648 --13.9325 12.6874 -1001.35 -0.738105 0.674579 -0.011998 -26.1071 -11.5529 -1004.45 0.912424 -0.107769 0.394803 -26.4317 -10.9754 -1005.18 0.960737 -0.0161429 0.27699 -13.1934 50.0009 -944.56 -0.397551 0.518142 0.757286 -21.0416 -5.48229 -1022.06 0.699914 0.353284 -0.620734 -23.0104 -24.1437 -1023.96 0.939443 -0.00166192 -0.342701 --13.6442 17.3286 -997.83 -0.931493 0.0854111 0.353589 -15.3232 -49.8421 -956.146 -0.409386 0.116572 0.904883 -23.9994 -30.3848 -971.68 0.938626 -0.148512 -0.311328 --0.225616 44.0001 -975.443 0.0758249 0.0784719 -0.994029 -26.7747 -10.2446 -1006.97 0.988176 0.101402 0.115001 -23.9495 -7.0024 -1016.75 0.961651 -0.179682 -0.207222 --13.3602 17.2398 -996.083 -0.995946 -0.0844949 0.030873 -22.5559 1.1269 -977.226 0.318899 -0.095732 -0.942942 --17.6564 37.197 -940.136 -0.70722 -0.0864185 0.701692 -19.937 -6.33998 -1023.6 0.529317 0.41649 -0.739161 -24.3158 -32.4093 -969.268 0.974206 -0.223571 0.0306404 --17.5229 -16.0465 -959.756 0.454722 -0.379466 0.805751 -23.2426 -35.1159 -966.603 0.978156 -0.153023 0.140695 -23.2097 -30.8115 -974.188 0.8434 -0.525341 -0.112663 -24.3825 -9.37069 -1012.62 0.533634 0.77396 -0.340911 --16.0239 -15.1251 -957.158 -0.415109 -0.869197 0.268664 --17.3255 -20.384 -959.869 0.913405 -0.002442 0.407045 -26.6765 -10.1051 -1008.91 0.957564 0.210278 -0.197114 --22.8429 -22.6785 -956.324 -0.00184757 0.0988321 0.995102 -25.7094 -13.6492 -1004.56 0.883639 -0.259766 0.389491 --16.7224 -17.5323 -961.295 0.880456 -0.154864 0.448124 -26.399 -10.1173 -1009.89 0.815521 0.43374 -0.383137 -23.3288 -7.77364 -1018.93 0.938256 0.0344669 -0.344221 -22.5073 -7.1036 -1020.65 0.881496 0.165487 -0.442243 -22.8967 -36.597 -966.04 0.951157 -0.0797438 0.298231 --17.4473 -18.197 -959.244 0.852668 0.00394649 0.522438 -17.2746 20.4467 -976.581 0.494777 -0.669815 -0.553664 --11.7079 31.8643 -981.734 -0.350583 0.364575 -0.862657 --6.49483 32.0364 -981.659 -0.196869 0.67112 -0.714731 -21.1291 -7.37566 -1022.86 0.784551 0.219564 -0.579889 --1.44538 -18.0294 -941.667 -0.0949091 -0.22481 0.969769 --16.735 -15.6365 -959.288 -0.0945177 -0.860124 0.501252 --30.2751 -31.6245 -963.999 -0.722325 -0.370671 -0.583823 --14.7517 -28.2742 -1008.71 -0.215203 -0.242119 0.946079 --17.8708 -18.9066 -958.914 0.695815 0.0100053 0.718152 -26.5845 -12.7637 -1006.39 0.946861 -0.171372 0.272185 -26.9155 -11.9114 -1007.63 0.989102 -0.0396177 0.1418 --25.5799 -35.8827 -967.01 -0.979543 0.124362 -0.158206 -22.2783 -10.0877 -1015.96 0.983699 -0.0777672 -0.162137 --29.1077 -29.6466 -967.283 -0.640757 -0.566818 -0.51783 -23.972 -33.3435 -970.964 0.948524 -0.191945 -0.251912 -12.353 -36.4588 -999.289 -0.708635 -0.370439 0.60051 -25.4775 -10.2983 -1012.7 0.69492 0.63237 -0.342336 --28.2715 -31.2341 -967.662 -0.987212 0.0814906 0.137008 -23.0223 -33.6986 -973.225 0.876241 -0.194656 -0.440807 -26.9738 -11.8452 -1008.56 0.99842 0.0513725 -0.0227767 --31.6082 -33.1811 -1002.01 -0.726542 -0.00957343 0.687055 -23.245 -9.17059 -1018.89 0.93114 -0.353698 -0.0887441 --28.0311 -37.2966 -974.02 -0.525792 0.594142 0.608719 --29.4178 -35.9944 -975.648 -0.522344 0.239302 0.818469 --13.6189 9.35885 -1007.52 -0.536151 0.735535 -0.414161 --25.7899 -34.962 -967.119 -0.833562 -0.522859 -0.178306 -0.170597 57.6099 -962.183 -0.0362557 0.777969 -0.627256 --25.6074 -35.4031 -967.049 -0.928014 -0.201497 -0.313352 -22.1052 -10.7156 -1017.28 0.992532 -0.0948684 -0.0766872 --29.1001 -31.8483 -973.391 -0.559511 0.801269 -0.211932 -23.3684 -35.8593 -969.23 0.990264 -0.136423 -0.0276681 -23.4097 -34.1601 -972.039 0.889213 -0.3345 -0.312105 --29.5749 -32.0098 -972.19 -0.998983 -0.0357157 0.0275074 -26.6459 -11.6287 -1010.85 0.954342 0.209191 -0.213238 --26.4008 -35.8894 -973.933 -0.649916 0.414114 0.637274 -23.7997 -10.5465 -1015.41 0.438672 0.766902 -0.468433 --29.5052 -31.6136 -971.471 -0.790639 0.612258 -0.00557131 -24.9023 -10.6607 -1014.43 0.597775 0.680139 -0.424354 -22.2585 -11.2076 -1017.21 0.590129 0.545919 -0.594743 --26.2234 -34.0261 -969.94 -0.591245 -0.806119 0.0245347 -22.9787 -9.86861 -1019.2 0.905764 -0.422936 0.0267652 --20.4389 39.2163 -937.777 -0.648265 -0.727428 0.224947 --29.1559 -35.1294 -975.58 -0.569622 -0.137809 0.810271 --27.6746 -32.9318 -966.418 -0.792489 -0.604362 0.0818996 -23.3082 -38.7064 -967.179 0.952349 0.22408 0.206928 -23.3795 -37.7182 -968.916 0.995278 0.0963412 -0.0118074 -26.4044 -49.4217 -962.658 0.370049 -0.894163 -0.252066 --29.8238 -33.8942 -975.572 -0.78679 -0.400675 0.469491 -26.0288 -11.6567 -1013.02 0.905512 0.285886 -0.313555 --29.2667 -33.8108 -974.751 -0.396379 -0.81522 0.422256 -3.96868 55.995 -964.543 -0.149645 0.531975 -0.833432 -21.9294 -9.80521 -1022.22 0.871856 0.0301362 -0.488834 --29.3405 -32.9072 -973.127 -0.589657 -0.723049 0.359868 -23.4144 -39.7994 -966.504 0.894589 0.334652 0.296173 -25.0597 -11.306 -1014.96 0.792068 0.431965 -0.431318 -5.52724 1.51376 -1019 -0.321819 0.199203 -0.925608 -22.5611 -10.0631 -1020.81 0.920074 -0.133977 -0.368123 --25.7079 -34.5835 -969.72 -0.836866 -0.545482 -0.0458669 --25.745 -22.2727 -956.693 -0.262364 0.0923987 0.960535 --28.4609 -31.0465 -966.782 -0.883236 -0.352229 -0.309563 -24.2946 -11.3459 -1016.05 0.554015 0.599378 -0.577766 -23.1523 -37.7236 -970.322 0.974307 0.0359224 -0.22234 --26.2626 -34.9035 -973.942 -0.67335 -0.22062 0.705639 -2.0148 -1.39589 -1024.63 0.707038 0.434569 -0.557895 --29.6492 -32.4975 -973.277 -0.985248 -0.0625168 0.159304 --27.2632 -33.8408 -973.251 -0.412859 -0.843309 0.344061 --29.921 -32.9024 -975.841 -0.814567 0.579776 0.0184653 --25.7423 -34.5927 -972.368 -0.860704 -0.482478 0.162491 -20.3598 -11.1973 -1024.82 0.776728 0.032205 -0.629012 -2.30731 33.3386 -981.994 -0.126629 0.768952 -0.626641 -2.67508 -2.24952 -1028.51 0.0600893 0.893848 -0.444326 -26.7788 -14.6614 -1008.82 0.969676 -0.158498 0.186027 -22.1646 -37.3997 -973.145 0.879896 -0.0371778 -0.473709 -26.2339 -15.8397 -1008.01 0.917445 -0.250358 0.309217 --30.3667 -50.3795 -953.601 -0.816056 0.138054 0.561243 -7.01432 -26.1095 -1030.24 0.283 -0.298756 -0.911403 -25.499 -12.5958 -1015.09 0.869943 0.279887 -0.406031 --28.2942 -35.5512 -948.979 0.130957 0.220393 0.96658 --25.5707 28.3827 -973.654 -0.0952176 -0.0202811 -0.99525 --26.6877 -34.655 -974.102 -0.473517 -0.632346 0.613124 --29.1409 -32.0406 -969.656 -0.974575 -0.0354892 0.221233 -23.5392 -39.348 -970.073 0.925198 0.22326 -0.306863 --8.91739 32.5847 -981.239 -0.00378119 0.761549 -0.648096 -8.99801 -23.117 -1030.18 0.371311 -0.117358 -0.921062 -4.21631 33.5575 -982.374 -0.0830597 0.353206 -0.931851 --28.7761 -32.6332 -968.88 -0.732957 -0.660127 0.164338 -26.7175 -14.2916 -1012.23 0.972102 0.0978576 -0.213169 --13.8573 53.7919 -969.732 0.0810159 0.718606 -0.690682 --27.6894 -33.1116 -968.121 -0.520482 -0.852095 0.0550727 --22.7139 -23.3771 -1010.15 -0.389929 -0.784187 0.482707 --26.049 41.4824 -967.54 -0.582975 0.703878 -0.405827 --18.3102 52.0774 -967.498 -0.662665 0.557243 -0.500355 --0.0950694 17.0906 -999.832 0.15144 0.762425 -0.629106 -23.9786 -40.3439 -969.676 0.897578 0.393186 -0.199395 --25.9541 -35.3128 -973.638 -0.900683 0.0137236 0.434259 --28.8628 -32.616 -971.262 -0.666601 -0.724562 0.17508 --26.7294 29.7257 -971.964 -0.210694 0.589168 -0.780057 --27.8992 30.0277 -971.629 -0.283363 0.541355 -0.791606 -24.3312 -13.5841 -1017.83 0.712105 0.40046 -0.576661 -23.4699 -13.6124 -1018.61 0.478527 0.532232 -0.698385 -24.6808 -41.7311 -968.675 0.920083 0.380373 0.0936137 -26.8435 -15.6238 -1011.4 0.994401 -0.0490717 -0.0935831 -17.7833 -22.7296 -1029.27 -0.158041 0.905123 -0.394683 -26.7896 -16.5103 -1010.6 0.990782 -0.133938 0.0202839 -19.0849 -27.4149 -1030.68 0.424193 -0.767301 -0.480947 -18.7795 -25.8956 -1032.49 0.502527 -0.255418 -0.825971 -1.24137 -15.6364 -943.776 0.925237 0.11344 0.362034 -19.9225 -26.0932 -1031.42 0.7132 -0.376297 -0.591393 --24.8078 -35.3004 -980.107 0.0444874 0.843664 -0.535025 --13.4976 37.5871 -981.372 0.0697209 0.538061 -0.840017 -17.4059 -27.2871 -1005.59 0.15878 0.790716 0.591233 --29.5991 -42.4588 -962.957 -0.93539 0.333955 -0.116277 -26.016 -19.1587 -1009.71 0.910369 -0.308229 0.276086 -25.3569 -15.037 -1016.85 0.900082 0.180302 -0.396665 -19.8679 -25.5779 -1031.54 0.802529 0.0536431 -0.594196 -10.3309 -26.8588 -1028.68 0.277295 -0.117011 -0.953633 -17.1947 -24.3216 -1032.45 -0.490343 0.502331 -0.712199 -26.2589 -16.5279 -1014.73 0.974006 -0.00180172 -0.226514 -12.8057 -27.2785 -1028.69 -0.382419 0.118472 -0.916362 -18.7481 -26.9043 -1006.78 0.336565 0.817982 0.466508 -12.4688 -28.5031 -1028.12 -0.0842894 -0.701478 -0.70769 -24.0095 -15.1368 -1019.17 0.753259 0.303773 -0.583372 --22.8626 -35.0466 -947.786 -0.416701 0.115006 0.901739 -19.6438 -24.7624 -1031.62 0.768691 0.331594 -0.546954 -23.3723 -16.2746 -1020.44 0.627081 0.38451 -0.677438 -15.5684 -27.8542 -1030.02 -0.421142 -0.58548 -0.692714 -16.2694 -25.0666 -1031.87 -0.787018 0.0694146 -0.613013 -9.14231 -1.02231 -1021.58 0.132264 0.811911 -0.568601 -16.658 -19.8084 -1025.63 0.669439 -0.00234031 -0.742864 -19.6704 -30.0597 -1003.34 0.368587 0.882918 0.290861 -19.5045 -29.746 -1003.73 0.371057 0.759562 0.534212 -19.4239 -26.2824 -1009.13 0.425644 0.845391 0.322708 -16.0924 -26.8257 -1031.32 -0.759355 -0.199737 -0.619262 --9.79789 40.5943 -977.794 -0.0126857 0.90778 -0.419255 -19.9696 -27.3276 -1007.04 0.441132 0.762821 0.472764 -17.1537 -26.7737 -1032.39 -0.379807 -0.561786 -0.734945 -16.105 -24.5494 -1031.25 -0.793359 0.423557 -0.437243 -26.1267 -19.9639 -1012.74 0.94605 -0.321735 0.0384282 -26.3389 -18.517 -1013.97 0.984227 -0.122788 -0.127357 -26.07 -18.7563 -1015.23 0.96634 -0.0760324 -0.245776 -25.2079 -17.6274 -1017.92 0.930551 0.032919 -0.364679 --21.7899 -4.92264 -950.153 -0.770869 -0.415362 0.482945 -20.7543 -30.4741 -1003.65 0.455141 0.886661 0.0817186 -20.735 -27.3492 -1007.84 0.458156 0.82182 0.338682 --28.7806 -6.61753 -956.45 -0.845338 -0.186732 0.500535 --16.5096 -34.3225 -1006.91 0.956073 -0.245199 0.160632 -21.5166 -30.5852 -1002.49 0.306056 0.950308 -0.0569632 -20.6937 -29.9974 -1004.6 0.577654 0.649064 0.495007 --28.069 -8.40931 -951.581 -0.388813 -0.827635 0.404778 --25.3796 -5.32372 -949.588 0.22915 -0.285884 0.930463 -20.9034 -28.9607 -1005.76 0.560319 0.616058 0.553637 -20.4068 -26.447 -1010.25 0.504115 0.819692 0.271981 --28.1225 -3.5259 -955.185 -0.822894 0.0488819 0.566089 --28.6211 -22.3768 -1014.2 -0.48045 -0.802472 0.353846 --28.4412 -5.70537 -955.549 -0.968765 0.215346 -0.122962 -23.2528 -18.961 -1021.74 0.727521 0.311453 -0.611318 --22.153 -4.62659 -950.316 -0.489563 -0.445414 0.749623 --23.67 -24.8737 -1010.85 -0.155237 0.607262 0.779188 --22.9968 -7.49646 -953.942 0.231917 -0.886009 0.401501 -21.6487 -30.5424 -1005.26 0.582299 0.683078 0.44083 --28.9018 -7.78873 -952.878 -0.547733 -0.805356 -0.226693 --24.5707 -6.56491 -950.683 0.452232 -0.471826 0.756879 -4.57419 3.57231 -1019.22 0.825718 0.417221 -0.379627 -20.8864 -25.9861 -1012.42 0.762912 0.452123 0.462114 --29.4034 -7.11468 -952.641 -0.919544 -0.229181 0.31924 --27.1067 -7.71538 -955.418 -0.391428 -0.919644 0.0322419 --21.8726 -5.85346 -951.515 -0.465586 -0.692825 0.550657 -25.3161 -20.2917 -1017.45 0.95161 -0.0854549 -0.295188 -22.0136 -31.0799 -1004.69 0.388979 0.882813 0.263317 -22.127 -27.9091 -1008.56 0.547752 0.756645 0.357009 --3.44128 -18.0698 -957.192 -0.0599181 -0.998118 -0.0130232 --25.0514 -8.20143 -955.608 -0.081045 -0.984323 0.15665 -22.7413 -31.3625 -1003.5 0.406017 0.913851 0.00512979 --26.7562 -8.44626 -951.03 -0.133733 -0.823679 0.551061 --28.2012 -7.40411 -956.331 -0.595885 -0.667395 0.44666 --33.5275 -31.9514 -1011.48 -0.944737 0.32621 -0.0325498 -20.5727 -20.516 -1025.5 0.376439 0.689762 -0.618484 --20.1558 28.3651 -940.701 -0.90173 0.0624119 0.42777 -22.5639 -28.7794 -1007.8 0.661321 0.570504 0.48701 -25.3564 -21.6711 -1016.39 0.955681 -0.263548 -0.131214 --27.7205 -7.59214 -954.771 -0.41939 -0.820221 -0.389038 --29.3932 -7.17471 -953.163 -0.893634 -0.403292 -0.19691 --26.1982 -8.05713 -954.449 -0.23304 -0.950389 -0.206044 --28.6467 -7.03333 -954.572 -0.619964 -0.603926 -0.500917 --18.5163 -35.3441 -1001.66 0.934096 -0.0076795 0.356939 --28.7401 -7.98088 -951.586 -0.669431 -0.619028 0.41069 --28.1599 40.4732 -966.471 -0.384389 0.557171 -0.736075 -22.6446 -30.1627 -1006.63 0.616889 0.59503 0.515158 --23.9587 -5.58926 -950.315 0.291351 -0.344511 0.892428 --28.6817 -6.58116 -954.904 -0.849284 -0.457002 -0.264321 --26.6577 -8.06754 -956.118 -0.295097 -0.815934 0.497162 --22.5978 -4.81256 -950.546 0.230915 -0.487191 0.842213 --22.9093 -5.83625 -951.342 0.546714 -0.673334 0.49772 -22.8046 -27.3188 -1012.5 0.605179 0.776172 0.176964 -24.4047 -23.2567 -1019.2 0.964597 -0.239684 -0.110022 --26.1652 -7.32408 -950.083 0.0213265 -0.439612 0.897934 --16.2836 47.0857 -969.427 -0.0558275 0.815507 -0.576048 -23.3567 -30.8365 -1006.53 0.474996 0.818257 0.323781 --19.8229 47.7331 -968.279 -0.00631549 0.227458 -0.973767 --22.4178 -6.63011 -952.925 0.0392736 -0.793959 0.606702 --25.9632 -8.60745 -951.876 0.29881 -0.937716 0.177202 --9.43916 49.037 -970.702 -0.204628 0.644987 -0.736287 -22.7047 -26.5103 -1015.61 0.8236 0.495634 0.275737 -24.1559 -24.1128 -1018.81 0.910198 -0.414165 -0.00259949 -22.6146 -22.2852 -1024.44 0.828131 0.247756 -0.502808 -21.8928 -22.5286 -1025.79 0.741612 0.390459 -0.545485 -23.9777 -28.9412 -1009.87 0.783294 0.557854 0.274318 -23.6657 -28.1931 -1011.15 0.639604 0.744364 0.191907 --24.5111 -8.04495 -953.27 0.348257 -0.935389 0.0613586 -20.7962 -22.3031 -1027.06 0.63368 0.532133 -0.561501 --26.2007 -8.59112 -952.489 0.0609527 -0.995271 -0.0756298 --26.7456 -32.8812 -999.027 -0.491815 0.169127 0.854116 -22.9638 -25.8061 -1017.7 0.965533 -0.0675613 0.251358 -19.7409 -22.5964 -1028.46 0.330716 0.768008 -0.548444 -24.5412 -31.4117 -1006.36 0.520225 0.853966 0.0103921 -8.74946 41.0375 -973.541 0.167487 0.462873 -0.870458 -24.3468 -30.3992 -1009.25 0.916909 0.332756 0.220346 -19.3537 -26.3089 -977.441 0.122104 -0.166948 -0.978376 -18.99 -22.9608 -1029.69 0.319256 0.857227 -0.404027 -26.122 -32.1205 -1004.16 0.520831 0.845937 0.114567 -9.5144 56.8241 -952.421 -0.0670264 0.930689 -0.359619 -24.4549 -30.9799 -1008.49 0.729825 0.636121 0.250411 -24.1259 -28.3287 -1012.89 0.748273 0.655494 0.102051 -8.84651 46.5736 -973.967 0.289686 0.257421 -0.921855 -7.74503 46.38 -975.392 0.743531 -0.151835 -0.651236 -24.6244 -29.2876 -1011.22 0.8863 0.422153 0.190416 -7.43841 41.9864 -974.075 0.805277 0.372025 -0.461655 -8.39973 42.5818 -973.323 0.00706184 -0.184995 -0.982714 -26.2822 -32.2961 -1004.61 0.888801 0.447033 -0.100962 -0.332213 2.17881 -1024.49 0.3657 0.897611 -0.246084 -6.52684 43.108 -975.417 0.774541 0.0294951 -0.631836 -21.9298 -24.2175 -1026.62 0.883548 0.19147 -0.427412 -1.82329 53.393 -971.189 -0.240488 0.547813 -0.801291 -20.381 -23.4715 -1028.79 0.68353 0.541745 -0.489182 -8.40939 45.208 -974.07 0.270375 -0.175567 -0.946612 --16.5451 47.8925 -968.276 -0.403509 0.551944 -0.729752 -14.2625 -17.3621 -979.497 0.204918 -0.448009 -0.870228 -23.6106 -27.3216 -1017.8 0.933168 0.358718 0.0227919 --16.4891 -30.9267 -1007.9 0.715943 0.28362 0.637954 -6.51494 42.4258 -975.788 0.625113 0.582532 -0.519509 --13.0294 49.7223 -970.943 -0.0214127 0.161228 -0.986685 -18.019 -24.1121 -1032.5 0.100562 0.48456 -0.868958 -8.8309 46.092 -974.037 -0.296369 0.0799818 -0.951718 -6.66207 44.6516 -975.784 0.716956 -0.267952 -0.643565 -24.783 -29.3966 -1012.58 0.943387 0.331695 0.000255264 -7.67748 43.0077 -973.685 0.661188 -0.182847 -0.727597 -23.4444 -25.4919 -1022.32 0.966617 -0.0953588 -0.237819 -25.9078 -32.3452 -1006.7 0.693393 0.70967 -0.124799 -2.81444 24.9461 -986.203 -0.419545 0.455082 -0.785419 --30.5785 -48.0338 -959.695 -0.994749 -0.00250492 -0.102318 --28.3568 -51.7529 -952.215 -0.284312 -0.577847 0.765022 --30.9237 -49.3237 -957.67 -0.987993 -0.118921 0.0986299 -5.21737 20.0078 -997.23 -0.021385 0.546948 -0.836893 -7.03083 16.9779 -995.656 0.951004 -0.0420919 -0.306299 -1.28575 49.5299 -970.754 0.035154 0.710843 -0.702472 --21.2727 -33.5176 -999.459 0.486099 0.509227 0.710208 -6.14695 16.0697 -996.825 0.287906 0.834194 -0.470351 -0.98237 1.3348 -1025.2 0.478644 0.619647 -0.622043 -19.0825 -23.9677 -1031.72 0.526841 0.640437 -0.558819 -26.1909 -33.2621 -1005.33 0.976542 -0.134532 -0.168125 --0.773384 14.4549 -1003.04 0.506 0.766824 -0.394898 -3.97767 18.8726 -999.391 -0.0704862 0.99271 0.0977629 -25.5043 -32.2052 -1008.37 0.829313 0.556745 -0.047701 -16.3173 -48.2633 -955.391 -0.233933 0.243698 0.941215 --0.394993 19.5166 -995.183 0.380046 0.827385 -0.41352 -26.8072 -34.637 -1002.51 0.958339 -0.221922 -0.179827 --19.4367 -25.9364 -1009.21 -0.108761 0.177455 0.978101 -24.9873 -31.0797 -1010.7 0.945636 0.314011 0.0846771 -6.97854 18.356 -994.433 0.974452 0.22393 0.0172914 -26.0922 -32.8216 -1007.46 0.915092 0.365633 -0.170055 -24.6238 -29.6592 -1014.92 0.984175 0.123227 -0.12734 -3.38746 0.350235 -1019.69 0.740207 0.289057 -0.607075 --0.55469 18.417 -996.764 0.304528 0.754614 -0.581223 -1.67185 18.7853 -996.014 -0.289893 0.867839 -0.403506 --2.30089 17.6939 -999.4 0.0695632 0.921229 -0.382751 -0.572004 17.319 -999.471 -0.0584351 0.910763 -0.408775 -23.6201 -28.7289 -1019.02 0.978425 -0.0180266 -0.205815 -5.94421 20.1225 -996.888 0.509858 0.404837 -0.759046 -6.71931 17.7306 -995.901 0.82634 0.0252944 -0.562604 -26.1437 -33.3244 -1007.41 0.987796 -0.11037 -0.109898 --24.4827 -51.5261 -956.717 -0.00948074 -0.952892 -0.303161 -24.9613 -17.1152 -976.358 0.908544 -0.362329 0.208005 -5.98101 17.3258 -1001.38 0.87264 0.00486903 -0.48834 -25.168 -31.8053 -1011.27 0.97115 0.226622 -0.0742245 -7.75917 15.551 -997.608 0.372132 0.886284 -0.275714 --28.1201 -41.8407 -959.084 -0.8904 0.348602 -0.292685 -25.6811 -32.9965 -1009.41 0.976124 0.0857521 -0.19957 --30.0643 -34.7628 -976.409 -0.722142 0.110693 0.682831 --22.8613 49.8643 -967.499 -0.429545 -0.0618496 -0.900925 -4.94604 19.2002 -997.414 0.153665 0.0992671 -0.983124 -5.79498 19.3461 -997.157 0.580734 -0.0258366 -0.813683 --0.34164 50.6464 -970.23 0.37183 0.526227 -0.76474 -24.6874 -31.1297 -1014.52 0.974606 -0.0480066 -0.218722 -11.4609 7.63835 -1004.73 0.587154 0.506079 -0.631771 -3.00242 18.5518 -997.454 0.0797221 0.709111 -0.700575 -3.33315 19.2644 -996.992 -0.420447 0.551021 -0.720834 -6.04453 17.3042 -996.472 0.490751 -0.0837126 -0.867269 -20.9595 -26.4001 -1029.28 0.921434 -0.078556 -0.380512 -20.7542 -26.8415 -1029.51 0.764935 -0.478656 -0.431003 --31.1472 -47.7693 -958.069 -0.994978 0.038114 -0.092552 -24 -50.065 -961.602 0.017632 -0.960541 -0.277579 -3.86206 17.7311 -997.828 0.700032 0.674975 0.233161 -16.3145 -50.5576 -959.969 0.0208547 -0.945469 -0.325042 -6.5445 16.5899 -996.28 0.488988 0.390182 -0.78016 -4.64369 16.6485 -997.286 0.64115 0.51294 -0.570806 -14.9877 -50.5765 -960.022 -0.01716 -0.935158 -0.353815 -2.44423 18.26 -998.541 -0.23505 0.963151 -0.130738 -3.104 18.2409 -997.826 0.419559 0.905632 0.0616587 --12.768 52.6846 -970.951 0.344952 0.30569 -0.887447 -17.2546 -49.6212 -963.01 -0.0155794 -0.951873 -0.306095 -14.4647 -49.9737 -961.473 0.019264 -0.952549 -0.303776 --21.7098 53.8823 -953.862 -0.372603 0.83033 -0.41439 --19.2789 55.1824 -952.936 0.270825 0.877096 -0.39668 --18.0859 57.0399 -951.314 -0.905693 0.343007 0.249132 -19.9636 -48.5203 -966.515 0.00274812 -0.953328 -0.301925 -13.5179 -49.7381 -962.699 0.0183843 -0.951253 -0.307864 --19.4961 56.4985 -951.248 0.403011 0.896402 -0.184513 --20.6867 54.5255 -953.758 -0.259191 0.662339 -0.702941 --18.7574 55.466 -951.643 0.528984 0.839109 -0.126776 -14.1164 -48.9739 -965.459 0.0517131 -0.966655 -0.250807 -15.4486 -48.7963 -965.433 0.0333521 -0.962983 -0.267492 --18.3357 55.1206 -952.548 -0.454931 0.889656 -0.0393815 --18.6637 55.0405 -953.506 -0.414362 0.900338 0.133023 --31.1044 -46.6743 -961.416 -0.959295 0.111263 0.259565 -2.73727 51.2925 -971.019 -0.288616 -0.115673 -0.950432 -16.7361 -48.087 -967.798 0.0211227 -0.953843 -0.299562 --20.2401 56.1376 -952.236 0.0682389 0.805931 -0.588063 -10.5453 -48.7138 -965.01 -0.182847 -0.915799 -0.357602 -20.2577 -47.1613 -970.694 0.00423142 -0.959999 -0.279971 -13.1711 -48.1083 -967.425 -0.0236295 -0.939751 -0.341041 -4.00596 50.5734 -971.16 -0.0155105 0.243651 -0.969739 --17.7567 55.8447 -951.08 -0.462697 0.445728 0.766315 -1.61511 6.47027 -1019.44 -0.261277 0.912533 -0.31467 --17.9656 55.7812 -951.53 -0.952201 0.122466 0.279848 --25.2199 -24.71 -1011.41 -0.366788 0.58769 0.721171 --17.9307 55.4891 -950.727 -0.12215 0.970128 0.209596 -19.0886 -46.8828 -971.614 -0.0167292 -0.952938 -0.302704 --5.76379 57.6606 -957.275 -0.353451 0.888938 -0.291311 --20.8061 51.4778 -967.683 -0.115002 0.603142 -0.7893 -16.5013 -46.6926 -972.198 -0.0107441 -0.95299 -0.302812 --27.1246 -37.5881 -999.555 -0.181609 -0.875919 0.446972 -12.0609 -46.8897 -971.15 -0.309127 -0.847636 -0.431224 -1.12951 -17.7227 -955.068 0.221209 -0.973537 0.0573709 --24.9192 -32.9011 -998.779 0.159221 0.392824 0.905725 --1.34479 -18.1106 -953.261 -0.0233891 -0.999572 -0.0175762 -11.703 -46.5907 -971.256 -0.77796 -0.364258 -0.511952 --15.2359 58.1284 -956.975 0.0662553 0.953429 -0.29425 --1.29291 -18.1521 -954.664 0.103123 -0.994642 0.00728893 -2.50396 49.6743 -971.037 -0.258998 0.325103 -0.909521 --11.9625 58.2249 -953.316 0.250064 0.933705 0.256248 --8.60565 56.9326 -956.466 -0.271915 0.683089 -0.677828 --7.4064 57.1702 -957.124 -0.322846 0.679989 -0.65832 -14.0103 -46.0143 -974.133 -0.243394 -0.836237 -0.491394 --7.87351 38.4896 -982.852 -0.218458 0.13385 -0.966623 --16.5953 -32.056 -1007.18 0.91221 0.126101 0.389835 --9.14798 56.5327 -958.592 0.104117 0.965007 0.240666 -1.0788 -17.7455 -958.085 0.145542 -0.989221 -0.0161173 --4.43856 -17.893 -953.942 -0.115584 -0.982155 0.148361 --14.1156 58.9264 -955.097 0.216247 0.902304 -0.37294 --13.9379 57.5746 -956.996 0.295771 0.954168 -0.0456415 -3.53436 -17.3646 -959.63 0.179177 -0.982824 0.0441883 --27.1677 -23.5627 -1014.18 -0.734968 -0.275643 0.619551 --4.61628 50.0702 -972.531 -0.209982 0.713847 -0.668079 --9.29313 58.1901 -955.669 -0.266112 0.54171 -0.79733 --11.5797 57.1834 -957.902 0.241181 0.951471 0.191142 --10.1794 57.771 -952.292 -0.559003 0.72811 0.3967 --5.61754 -17.8804 -956.179 -0.130269 -0.991441 -0.00864717 --10.7878 57.9681 -953.016 -0.117145 0.96268 0.243977 --8.06789 -17.4088 -954.288 -0.19599 -0.964279 0.178198 --1.20422 -17.9655 -959.922 0.0499776 -0.998643 -0.014623 --11.3646 58.1549 -954.656 0.185715 0.964572 -0.18738 --27.0312 48.0697 -960.375 -0.512459 0.720608 -0.467022 --20.1261 52.5481 -966.573 -0.136181 0.868135 -0.47728 --13.4515 58.8484 -954.643 0.327229 0.943888 -0.0446892 --9.98993 57.2845 -951.501 -0.0883783 0.827833 0.55397 --2.76671 -17.8922 -960.595 -0.102543 -0.992645 -0.0643559 --10.455 58.1935 -954.98 -0.359474 0.850124 -0.384795 --16.7539 -26.8666 -1009.27 -0.0913797 0.0100364 0.995766 --9.74632 58.6043 -954.814 -0.528402 0.845589 -0.0759639 -6.27545 -17.9361 -967.987 -0.249625 -0.961823 0.112179 --17.2406 -50.8246 -957.672 0.676723 -0.705457 -0.210656 --9.24009 -17.3051 -955.702 -0.214091 -0.975176 0.0565412 -2.9472 -17.71 -965.406 0.0598172 -0.997592 0.0351078 -5.44089 -17.7719 -967.152 -0.047612 -0.994221 0.0962157 -10.6595 -1.42563 -1021.97 0.175906 0.981346 -0.0775676 --10.757 57.1899 -956.473 0.0356623 0.868692 -0.494067 --17.6638 -51.0307 -957.76 0.285246 -0.911269 -0.297023 -22.7214 -15.2552 -1020.21 0.310161 0.554302 -0.772366 --21.2462 53.8226 -961.253 -0.26922 0.477172 -0.836557 -4.64148 -17.7451 -966.901 0.0283149 -0.996793 0.0748441 --9.47529 56.7513 -956.599 0.107722 0.878319 -0.46578 --16.45 41.2308 -972.701 -0.510716 -0.272001 -0.815588 --18.9552 54.5984 -960.673 -0.0452905 0.51316 -0.857097 -15.1867 54.7041 -947.729 0.523754 0.562068 0.640126 --18.9073 -51.1154 -958.065 0.0609009 -0.951183 -0.302558 --28.2729 -23.3306 -1015.21 -0.767593 -0.484535 0.419556 --0.0922351 -17.8806 -964.581 0.00337112 -0.999976 -0.00602144 --10.3741 55.6446 -962.684 -0.161258 0.638989 -0.752123 -14.3498 50.8913 -950.046 0.648836 0.217225 0.729263 --26.0668 51.1471 -955.274 -0.435068 0.447093 -0.781552 -14.0006 51.0834 -949.586 0.918392 -0.0286031 0.394637 --9.88392 55.7897 -962.699 -0.417316 0.508022 -0.753499 -14.8226 52.1196 -950.391 0.425168 -0.122026 0.896851 -15.4491 54.7728 -949.315 0.954021 -0.296206 -0.0458931 -15.4905 49.3092 -943.677 0.65074 -0.217505 0.727481 --1.80794 -17.7976 -965.227 -0.128899 -0.990898 -0.0388164 -15.4462 53.9177 -947.47 0.956441 0.147306 0.252034 -15.4804 51.3007 -944.239 0.496377 0.477833 0.724766 -13.6522 49.8898 -947.531 0.964954 0.180151 -0.190813 -3.44435 -1.10329 -1022.51 0.997733 -0.0148562 -0.0656367 --22.4316 43.6926 -972.805 -0.233301 0.4588 -0.857364 -10.6349 -21.3797 -975.697 -0.756029 -0.471711 -0.453772 --12.2991 -16.6924 -958.098 -0.0774064 -0.995419 0.0561171 -15.2489 53.6934 -950.052 0.801757 -0.354208 0.481376 --20.3943 -29.5515 -1006.24 0.228953 0.733904 0.639504 -15.7554 50.9874 -945.062 0.966828 -0.135701 -0.216399 -15.3304 47.8496 -945.132 0.783614 0.611048 0.112112 -15.7364 49.6295 -943.941 0.928969 -0.0142598 0.369884 -14.6399 -42.5529 -961.992 -0.298798 0.317122 0.900085 -4.87086 -17.9585 -971.207 -0.0920559 -0.992924 0.0750215 -14.7353 49.1047 -946.215 0.889599 0.0725753 -0.45094 -5.96397 -20.7103 -1031.72 0.71841 -0.377858 -0.584047 -15.8379 51.8603 -945.006 0.810454 0.459048 0.363922 -15.6446 52.4 -946.126 0.988622 0.117135 -0.094375 --10.1645 57.8968 -961.658 -0.423078 0.589605 -0.688019 -15.3874 48.3406 -944.214 0.984413 -0.101939 0.143315 --7.54182 -16.9373 -962.321 -0.133878 -0.984951 -0.109305 -12.3284 18.1725 -941.493 0.878382 -0.342392 0.333485 --19.8737 31.0236 -936.883 -0.709395 0.559408 0.428743 --20.246 -50.2864 -960.68 0.064308 -0.951703 -0.300208 --12.969 -16.8703 -958.916 -0.122338 -0.989676 0.0746697 --6.43262 59.1569 -956.013 -0.0840425 0.65081 -0.754575 --2.18846 38.3973 -982.052 0.321947 0.312757 -0.893607 --19.3053 -24.5324 -956.861 0.455245 0.128496 0.881045 -18.2784 28.7409 -950.229 0.989176 -0.100191 0.107208 -8.74847 -19.3335 -976.08 -0.42009 -0.882047 -0.21335 -17.0477 25.4873 -951.05 0.886546 -0.411297 0.211826 --12.0566 -16.6626 -960.807 -0.0279755 -0.997056 -0.071395 --4.7828 -17.0314 -965.883 -0.203701 -0.977412 -0.0563133 -5.31736 -18.3053 -974.088 -0.134086 -0.990463 0.0316708 -7.11737 -18.6736 -975.619 -0.400793 -0.914364 -0.0574741 -4.28379 58.5487 -962.377 0.0369171 0.916243 -0.398917 --2.53496 -17.5733 -967.652 -0.194405 -0.980642 -0.0234318 -0.512546 -17.8655 -970.59 -0.0659047 -0.997749 0.0124167 -12.6571 18.8542 -940.88 0.890462 -0.164356 0.424341 --34.2434 -33.1297 -1005.58 -0.946189 0.319146 0.0535865 -13.0136 18.8026 -943.247 0.937894 -0.149157 0.313219 -9.78452 -19.3382 -977.6 -0.446963 -0.788803 -0.421917 --25.2957 -26.9896 -956.024 -0.266638 0.251353 0.930444 -23.2598 16.9818 -964.979 0.693272 -0.46093 0.554001 --28.5058 -31.7066 -965.674 -0.747 -0.470307 -0.469896 -7.817 -18.7072 -977.619 -0.220858 -0.967782 -0.120916 -12.8531 19.458 -941.598 0.958951 -0.133286 0.250297 -14.3192 22.9316 -945.055 0.72128 0.249562 0.646123 --28.718 27.0098 -969.747 -0.997997 0.0212342 -0.0595933 -13.7464 21.3592 -943.915 0.914346 0.0319334 0.403672 --7.73812 -16.5392 -966 -0.132584 -0.989084 -0.0643019 -2.69425 -18.1305 -973.917 -0.0404265 -0.998024 0.0480917 -15.5421 23.1176 -949.552 0.878549 0.000522812 0.477652 -16.1636 24.657 -948.191 0.911044 -0.140338 0.387692 --24.4613 -49.9808 -961.777 -0.00431903 -0.954938 -0.296772 -17.1037 25.6887 -949.701 0.876725 -0.353009 0.326708 -17.8296 27.2619 -949.93 0.741661 -0.168841 0.649178 --10.0681 -16.4325 -964.407 -0.0608881 -0.99433 -0.0871821 --15.7883 44.1926 -976.171 -0.359271 -0.0969097 -0.928188 --0.54724 -17.8666 -972.023 -0.13738 -0.99044 0.0124326 -18.0163 27.4765 -950.404 0.939033 -0.338209 0.0619076 -14.7357 22.2279 -947.681 0.943396 -0.203622 0.261806 --6.15003 -16.7237 -967.716 -0.17777 -0.983776 -0.0241389 -13.4229 21.8116 -943.782 0.193215 0.694011 0.693554 --8.59703 58.9209 -963.368 -0.507542 0.415212 -0.754983 --20.3463 34.2221 -971.872 -0.785512 0.587554 -0.194297 --1.84395 -17.5451 -971.84 -0.206041 -0.978522 -0.00644239 --19.8452 -49.0041 -964.832 0.0175407 -0.955527 -0.294382 --3.59363 -17.216 -970.415 -0.214806 -0.976625 -0.00786222 -16.8978 26.2976 -949.267 0.508212 0.238985 0.82741 -8.65359 -18.3513 -979.962 -0.0246406 -0.968334 -0.24844 --27.5797 -50.1231 -951.7 -0.334815 0.0134683 0.942188 -9.89946 -17.9765 -980.573 0.241491 -0.92631 -0.289192 -10.5968 -50.1325 -960.222 -0.462974 -0.866894 -0.184799 --22.9666 55.2005 -960.589 -0.621361 0.405665 -0.670334 --32.6783 -29.932 -1015.5 -0.970693 -0.0393086 -0.237087 --23.9528 52.347 -955.878 -0.999257 -0.0138436 0.0359669 --22.0026 -22.9798 -1032.24 0.578082 0.317385 -0.751723 --24.1838 54.2168 -958.993 -0.950212 0.165741 -0.263871 --23.7575 51.2189 -958.499 -0.982978 -0.00410222 -0.183677 --23.8073 51.443 -956.094 -0.858191 0.250957 -0.447805 -3.87457 -18.2758 -976.847 -0.0272064 -0.998324 0.051083 --23.5384 51.8176 -959.33 -0.837313 -0.125012 -0.53224 --23.7872 50.9787 -958.146 -0.951028 0.303711 -0.0574997 -9.84145 -17.7884 -981.48 0.335392 -0.931808 -0.138731 -18.7393 -24.3733 -959.64 0.291453 -0.0990294 0.951445 --16.3949 57.8595 -962.394 -0.302969 0.623296 -0.72091 --21.6014 51.5609 -961.929 -0.913694 0.343885 -0.21658 -13.2722 -16.064 -983.397 0.482793 -0.87563 -0.0135351 --7.55158 -16.4547 -968.869 -0.147459 -0.988963 -0.0144092 -8.33758 -18.1628 -981.451 0.1914 -0.980322 -0.0483138 --7.29641 55.54 -964.819 -0.451887 0.382716 -0.805808 --24.5447 53.0497 -957.758 -0.966812 -0.211596 -0.143183 --23.3289 51.009 -959.648 -0.79776 0.271334 -0.538476 --23.5909 54.8466 -959.916 -0.788599 0.0883409 -0.608529 --13.1917 55.3957 -964.349 -0.19096 0.881798 -0.431238 --22.3428 50.4578 -961.527 -0.506368 0.80072 0.32006 -11.0585 -17.2329 -983.414 0.387938 -0.921402 0.0228572 --22.2905 50.5965 -961.092 -0.698678 0.587718 -0.407967 --20.4845 -24.5248 -956.417 0.240904 0.155528 0.958006 --12.3362 -16.4387 -966.648 0.356981 -0.932332 -0.0576286 -2.69638 53.169 -971.349 -0.00137003 0.11926 -0.992862 -1.0472 52.8825 -970.983 -0.584309 0.0803066 -0.807548 --12.7326 -16.6568 -966.646 0.645035 -0.74269 -0.179838 -8.77442 56.641 -959.664 0.265221 0.525455 -0.808428 -6.72514 57.3325 -956.62 0.528622 0.795457 -0.296321 -10.6522 56.9306 -955.022 0.196695 0.722921 0.662341 --10.9381 -16.111 -967.996 0.00760189 -0.999369 -0.0346994 -8.72007 57.6062 -958.756 0.0995476 0.910604 -0.401112 -8.90927 57.7678 -956.861 -0.177981 0.966151 0.186749 -9.45108 57.2657 -955.312 -0.131052 0.733167 0.667302 -8.22561 57.7001 -957.849 -0.0947993 0.9933 0.0660963 -0.534206 -18.1132 -977.46 -0.114271 -0.990872 0.0715166 --19.086 -31.0119 -1005.25 0.415229 0.713208 0.564729 --31.0233 -45.9904 -962.953 -0.959256 0.27717 -0.0548129 -8.64233 55.7486 -954.464 0.213053 0.830779 0.514213 -8.06272 56.7322 -955.257 0.0965702 0.713933 0.693523 --19.4453 -47.6293 -969.302 0.0152661 -0.9545 -0.29782 -7.70539 57.0625 -955.8 0.00616875 0.96743 0.253063 --3.0174 -17.4673 -975.506 -0.227798 -0.967116 0.113111 -7.41774 -18.4302 -983.928 0.175869 -0.984384 0.00767287 --22.0211 -35.1704 -946.643 -0.582475 0.157801 0.797384 -4.2079 -18.6083 -981.56 0.0448307 -0.995178 0.0872406 --5.04623 -16.8533 -974.373 -0.179317 -0.983161 0.0352185 --24.6415 -48.2677 -967.198 -0.00561983 -0.953737 -0.30059 --9.29837 -16.2597 -971.523 -0.0800966 -0.99641 0.027428 -5.58089 -18.7237 -983.392 0.158805 -0.98171 0.105006 -11.1667 48.2665 -968.944 0.357859 0.562265 -0.745516 --31.5041 -0.368453 -969.926 -0.91945 -0.151604 -0.362806 -14.5621 51.1778 -966.153 0.924836 -0.0667457 -0.374464 --11.4852 -16.1672 -970.53 0.187162 -0.982283 0.00947116 -8.24085 48.6737 -970.737 0.48842 0.82611 -0.281048 -18.1706 -3.47149 -952.35 -0.487211 -0.842892 0.228384 -9.71525 -17.9899 -986.151 0.302545 -0.950942 0.0646261 --21.6075 -31.209 -1003.49 0.13459 0.84673 0.514717 -18.1591 49.0128 -961.357 0.967972 0.24979 -0.0252015 -13.6949 51.3316 -967.552 0.757395 0.198969 -0.621904 --11.2474 57.0776 -957.247 0.219687 0.972329 -0.0794562 --5.51322 -16.8669 -975.585 -0.18927 -0.967401 0.168264 -13.7434 50.6431 -967.505 0.78405 -0.153523 -0.601412 -13.1161 50.7705 -968.132 0.503218 -0.086879 -0.859781 --28.4274 27.1813 -971.349 -0.879125 -0.00611169 -0.476553 -10.6789 48.1851 -969.413 0.316578 0.874268 -0.368014 -12.764 51.7666 -968.177 0.528592 0.518358 -0.672231 -15.3943 45.9594 -962.454 0.624102 0.350057 -0.698539 --15.8338 -46.0368 -972.9 0.750499 -0.612835 -0.247354 -14.3864 51.4885 -966.387 0.692936 0.627391 -0.355274 -17.1569 44.8026 -960.755 0.80454 -0.191889 -0.562044 --13.963 -17.0875 -970.322 0.425687 -0.904564 0.0235443 -13.6911 48.4641 -965.855 0.976505 0.148126 -0.156514 -13.4667 48.9864 -966.947 0.852939 -0.165694 -0.495016 -1.61039 -18.6536 -981.781 -0.0181835 -0.993242 0.114632 -15.0157 48.8052 -963.255 0.515822 -0.262551 -0.815472 -7.31746 -17.7217 -1032.32 0.747427 -0.531903 -0.398035 -18.4673 48.2625 -961.631 0.940274 0.157522 -0.301781 --3.68946 -17.6205 -977.473 -0.326884 -0.921051 0.211688 --17.3629 -23.6877 -1030.12 -0.156458 0.295568 -0.942423 -14.9174 51.2281 -963.513 0.90327 0.233242 -0.36014 --17.7905 35.2928 -977.5 -0.127643 0.43529 -0.891196 -8.42668 48.0996 -971.837 0.451803 0.839848 -0.300879 -8.63452 49.0433 -968.857 0.458523 0.65518 -0.600413 --28.7004 -50.0135 -952.11 -0.54274 0.140761 0.828021 --18.9248 -23.0615 -1030.25 0.338715 0.395541 -0.853709 -8.59186 -30.6962 -1006.73 -0.0521314 -0.449654 0.89168 --30.6077 -48.3079 -966.824 -0.120353 -0.955533 -0.269206 --26.5628 -21.8437 -1031.57 -0.60012 0.67384 -0.43104 -17.8361 47.5139 -957.046 0.824676 0.45757 0.332475 --7.32609 -16.6554 -975.699 -0.0996602 -0.989959 0.100248 -17.2114 44.7018 -958.335 0.930159 -0.340588 -0.137129 -18.6045 47.3971 -961.221 0.771196 -0.313026 -0.554321 -10.2191 48.4583 -971.881 -0.0505504 0.981916 -0.182444 -3.84277 -19.0756 -984.577 0.0721022 -0.979844 0.186299 --27.7285 -47.8139 -968.526 -0.0121875 -0.953595 -0.300846 --23.5429 -20.8725 -1031.35 0.115385 0.779338 -0.615888 -11.854 48.9971 -968.298 0.469465 0.145814 -0.870827 -15.1615 50.4612 -963.386 0.666461 0.0978593 -0.739089 -14.6091 49.811 -964.278 0.910877 -0.215003 -0.352246 --7.1199 -16.9272 -977.022 -0.122929 -0.972851 0.196086 -5.07276 0.60735 -1018.83 0.0812418 0.401052 -0.912446 -13.9415 47.0889 -963.404 0.779695 -0.175492 -0.601065 -16.4661 50.0944 -963.01 0.383009 0.0648492 -0.921466 -20.1356 -37.3608 -1001.68 0.102571 -0.96745 -0.231342 -17.2147 44.5251 -960.45 0.967252 0.253816 -0.000558114 --15.0912 -17.8408 -971.513 0.501738 -0.86225 0.0691612 --10.6965 -16.3009 -974.201 -0.0150529 -0.997875 0.0633898 --17.2271 19.8525 -940.527 -0.39299 0.783208 0.481814 -18.523 46.7923 -958.355 0.951309 -0.199716 0.234786 -6.22458 -19.3034 -987.601 0.204463 -0.955752 0.211502 -7.88259 -18.9673 -988.219 0.314728 -0.927189 0.203142 -8.94341 48.3183 -971.209 0.0608367 0.98791 -0.142594 -11.8287 51.5581 -968.62 0.18284 0.117113 -0.976142 --29.7734 -49.5944 -953.401 -0.716037 0.20812 0.666316 -18.7901 47.1137 -960.086 0.995178 -0.0974295 -0.0113206 -17.0212 44.2856 -959.138 0.999884 0.00113611 0.0152108 -18.1531 47.9338 -961.804 0.496134 -0.218136 -0.840397 --18.3828 -45.7204 -975.271 0.0290939 -0.95292 -0.301824 --4.13177 -18.112 -980 -0.113217 -0.969634 0.216778 -13.4868 48.1756 -966.823 0.886157 0.361945 -0.289347 -11.3812 49.2116 -968.372 0.113261 0.133705 -0.984528 -11.009 48.0339 -970.192 0.232913 0.950881 0.203905 --21.3764 -30.454 -1004.77 0.09895 0.782729 0.614446 -9.86489 -45.4635 -965.812 -0.989517 0.133541 0.0549877 --27.1005 -21.1777 -1030.42 -0.663586 0.519139 -0.538654 -17.441 45.7034 -960.833 0.57242 -0.395519 -0.718261 --8.08721 40.4583 -981.832 -0.414975 0.59983 -0.684105 -9.64685 -1.39499 -1022.2 0.00294144 0.958433 -0.285303 --14.8548 -17.6351 -973.377 0.554567 -0.826934 -0.0929324 --13.6216 -16.9436 -973.395 0.392146 -0.916892 -0.0743661 -16.6105 50.5031 -962.862 0.58196 0.328887 -0.743744 --0.515972 -18.9555 -983.743 -0.0331508 -0.981409 0.189044 -16.9592 46.5484 -961.655 0.472561 -0.315321 -0.822958 -4.44479 -22.9897 -1031.66 0.567671 -0.388759 -0.725683 -18.7051 46.9827 -960.55 0.83204 -0.432515 -0.347332 --6.1443 35.4271 -934.128 -0.662461 0.721623 0.201011 -24.4441 -36.1489 -1005.05 0.219364 -0.928355 -0.300062 -16.3572 45.0384 -961.911 0.7753 0.507872 -0.375468 -13.7197 47.6834 -964.853 0.781296 0.507927 0.362747 --10.2119 -16.4971 -976.292 -0.0535705 -0.993794 0.0974832 --18.8157 39.1791 -973.381 0.338764 0.111783 -0.934207 --28.756 -40.6536 -956.238 -0.968123 0.232815 -0.0923886 --9.71179 -16.6589 -977.125 -0.111923 -0.977356 0.179579 --3.99675 -18.396 -981.364 0.061912 -0.975837 0.209543 --28.7006 -39.8042 -956.75 -0.868958 -0.487683 -0.0841237 -8.25773 -19.4755 -974.161 -0.628009 -0.766467 -0.134659 --28.5066 -40.8291 -957.191 -0.879209 0.344508 -0.3291 -2.17813 -19.7011 -986.746 0.048321 -0.961127 0.271845 -21.6913 -36.4472 -1004.41 0.0833732 -0.957639 -0.275639 --29.2598 -43.1677 -963.922 -0.910432 0.253323 -0.327018 --13.2383 9.78896 -1007.65 -0.983334 0.178569 -0.034178 --27.9468 -40.919 -959.356 -0.962133 -0.246332 0.116704 -10.282 -49.6922 -960.217 -0.976535 -0.215144 -0.00961183 --28.6236 -41.8989 -960.292 -0.856418 0.0253598 0.515659 --29.3929 -42.2587 -962.012 -0.942586 0.0259175 0.332956 --20.103 -21.107 -1029.69 0.392242 0.528947 -0.75257 --28.2708 -40.0896 -959.027 -0.71661 -0.612252 0.334091 -18.1399 -16.7791 -1000.52 0.492271 -0.658277 0.569509 -3.6106 -1.69259 -1021.42 0.637668 0.735202 -0.229906 --23.2995 -37.6382 -946.971 -0.0629701 -0.212055 0.975227 -9.95634 -21.6021 -964.514 -0.90582 -0.0471399 0.421031 --23.8398 -41.7188 -950.05 -0.238722 0.0205426 0.970871 --28.3428 -40.2187 -954.011 -0.946393 0.274163 0.170804 --27.982 -42.0274 -951.735 -0.79467 0.123991 0.594244 -19.2468 -36.8993 -1003.15 -0.00947245 -0.944422 -0.328599 --28.7658 -39.5322 -955.587 -0.936002 -0.245087 0.252651 --16.778 -19.5397 -973.526 0.809321 -0.501009 -0.306576 -17.1198 -25.306 -959.414 0.053376 -0.128531 0.990268 --29.8272 -37.6932 -947.745 0.256091 -0.131151 0.957714 --23.1774 -45.9627 -974.472 -0.00329839 -0.952799 -0.303583 --30.8017 -37.6617 -947.742 -0.388471 0.0265855 0.921078 --30.6492 -38.7256 -948.46 0.000571056 -0.987826 0.155564 --15.8188 -17.8546 -974.916 0.543301 -0.77942 -0.311975 --12.783 -16.533 -975.821 0.142963 -0.98909 -0.0355301 --6.92252 -13.6667 -945.645 -0.334573 -0.53115 0.778422 --29.636 -40.6545 -963.227 -0.837384 -0.543226 -0.0607804 --29.4356 -41.4518 -961.278 -0.801782 -0.535439 0.265426 --28.1745 -33.6603 -949.073 -0.1366 -0.0326614 0.990088 --22.1212 52.9453 -960.861 -0.692391 0.130213 -0.709676 -4.17821 -20.0159 -988.841 0.158267 -0.956788 0.243944 --28.0299 -39.6113 -953.665 -0.941692 0.150477 0.300954 --28.9906 -38.3386 -953.847 -0.594984 -0.792502 0.133918 --25.5083 -42.3975 -949.881 -0.238903 0.149542 0.959459 --25.9038 -38.0234 -946.247 -0.0947405 -0.428088 0.898757 --25.9163 -37.5439 -946.184 -0.246526 0.120577 0.961606 --28.1223 -39.2243 -953.539 -0.865309 -0.489206 0.109166 --14.0308 -16.7531 -975.908 0.273013 -0.929074 -0.249569 --30.7241 -38.5483 -948.038 -0.00355433 -0.630233 0.776398 --7.15251 -17.9206 -980.974 -0.140395 -0.969695 0.199952 --24.5971 -37.9162 -946.418 0.28829 -0.348776 0.891765 --26.0434 -41.3783 -949.929 -0.670786 -0.48304 0.562777 --25.8679 -39.7456 -947.618 0.014218 -0.72095 0.692841 --33.8697 -32.5384 -1006.51 -0.725871 0.686063 0.049278 --31.6932 -35.9371 -953.116 -0.99843 -0.0482057 -0.0285116 --1.21645 -19.6561 -986.639 -0.0571727 -0.959703 0.27514 --30.3402 -37.4503 -947.678 0.0619497 0.0490829 0.996872 -13.1058 -37.3269 -1001.47 -0.193306 -0.960943 -0.198044 --27.1616 -38.2263 -946.823 -0.554196 -0.286562 0.781505 --28.9945 -46.4654 -972.758 -0.0146369 -0.95341 -0.301322 --28.2574 -38.2709 -948.332 -0.509629 -0.294232 0.808521 --27.662 -38.8952 -948.461 -0.590038 -0.724507 0.356294 --28.4023 44.784 -953.286 -0.841403 0.527768 -0.116203 --31.0987 -37.3663 -952.305 -0.390073 -0.83134 -0.395875 --3.77309 -19.0389 -985.205 0.0651436 -0.972439 0.223871 --20.4037 -25.8906 -956.117 0.313127 0.319091 0.894501 --0.982518 7.3485 -1014.69 0.101091 0.893918 -0.436682 --28.8274 -38.502 -952.669 -0.643139 -0.750713 -0.151001 --31.3181 -36.817 -953.109 -0.683688 -0.726902 -0.0646845 --31.9074 -38.1247 -950.255 -0.838838 -0.486742 -0.243787 -17.8841 -39.1444 -975.68 -0.148464 0.14338 -0.978468 --1.2868 28.8734 -987.63 0.394331 -0.243263 -0.886186 --11.4406 -16.946 -979.71 -0.142749 -0.977844 0.153115 -4.0793 26.3589 -985.813 0.135943 -0.204768 -0.969324 -0.524245 26.1114 -984.91 -0.391193 -0.489392 -0.779399 -5.23781 29.6238 -987.208 0.219851 -0.3701 -0.902603 --16.0772 4.39864 -1012.98 -0.297209 0.451459 -0.841339 --1.04328 25.6196 -984.42 0.377553 -0.442149 -0.813608 -0.450001 28.2233 -985.972 -0.163745 -0.335309 -0.927769 --14.0991 -16.4917 -978.669 -0.125835 -0.990844 0.0489248 --17.7096 6.68507 -1007.32 -0.196045 0.534453 -0.822148 --0.93203 -20.4833 -989.043 -0.0257543 -0.9359 0.351324 -6.72849 27.5492 -986.023 0.500638 -0.0582871 -0.863692 -1.04037 41.7855 -932.547 0.665719 -0.342536 0.662938 --16.7045 -16.824 -977.64 0.021196 -0.97451 -0.223341 -6.75328 26.7422 -985.763 0.476465 -0.372163 -0.79654 -2.40653 26.7982 -986.289 -0.0579574 -0.288645 -0.95568 --0.381438 27.7695 -985.782 0.408259 -0.524984 -0.746804 --0.722229 30.0498 -987.491 0.510525 0.106548 -0.853236 --1.41813 28.1162 -987.322 0.499432 -0.469481 -0.728118 --5.01464 -19.2354 -986.479 -0.105968 -0.955936 0.273782 --31.6953 -46.1675 -973.415 -0.208918 -0.935013 -0.286538 --18.5268 -43.8404 -981.221 0.0266205 -0.95119 -0.307457 -5.43049 28.737 -986.573 0.382227 -0.244609 -0.891105 -3.43275 28.1305 -987.058 0.12026 -0.32345 -0.938572 --25.7266 -44.8939 -977.747 -0.00426243 -0.952848 -0.303417 --1.2497 44.8443 -976.092 0.59343 0.317509 -0.739614 --15.2601 -16.4305 -978.721 0.0334231 -0.984889 -0.169932 --12.5182 -16.9981 -981.674 -0.267095 -0.954877 0.129885 --17.2982 29.589 -977.449 0.205347 0.317743 -0.925674 --26.028 -14.3251 -1024.59 -0.766162 0.042648 -0.641231 --13.1432 28.4055 -980.333 -0.946065 0.201598 -0.253612 --16.4938 35.2694 -979.875 -0.900653 -0.0441599 -0.432289 --15.3732 33.5791 -980.486 -0.728229 -0.470042 -0.498742 -21.2489 -39.8638 -974.785 0.591237 0.180209 -0.786107 --13.6447 27.9971 -981.358 -0.741126 0.577446 0.342474 -21.6442 -34.6028 -1010.2 0.0232835 -0.951326 -0.307306 --14.1673 33.8487 -981.696 -0.262563 -0.0757288 -0.961939 --16.3814 27.538 -981.012 -0.185703 0.871669 -0.45355 --29.4178 -6.13458 -982.815 -0.367819 0.207666 -0.906413 -22.3736 18.4551 -970.895 0.64729 -0.15595 -0.74612 --13.2768 32.1348 -980.971 -0.519576 -0.367493 -0.771355 --13.3814 27.9643 -980.432 -0.394088 0.89851 -0.193325 -17.1571 -35.2322 -1008.41 0.00333414 -0.952366 -0.304939 --16.9376 31.6755 -977.068 -0.048854 -0.0629487 -0.99682 --15.9246 29.4509 -977.723 -0.225643 0.511461 -0.829152 --13.4614 30.4555 -980.311 -0.887545 0.14987 -0.435663 --19.0708 -16.2929 -979.148 -0.176982 -0.966364 -0.186599 --13.4843 29.9728 -980.345 -0.927245 -0.0621303 -0.369266 --9.15127 -18.6095 -986.153 -0.177596 -0.95753 0.227147 --13.6138 28.1331 -980.045 -0.581707 0.231821 -0.779664 -15.3228 -35.4627 -1007.67 -0.0146841 -0.953591 -0.300747 --16.0348 33.2231 -978.55 -0.788816 -0.420149 -0.448602 --29.4923 -44.9955 -977.436 -0.0425294 -0.953112 -0.299614 --16.159 32.5424 -977.829 -0.537678 -0.419538 -0.731362 --15.3273 30.5926 -977.729 -0.648531 -0.0417454 -0.760043 --15.6127 31.7917 -977.813 -0.664852 -0.388548 -0.637967 --13.6406 31.3984 -980.23 -0.731423 -0.256797 -0.631725 --12.7763 30.9536 -981.13 -0.755939 0.262625 -0.599654 --20.0987 -6.00818 -1027.55 -0.514966 -0.279078 -0.810509 --6.43348 48.5698 -976.28 -0.0500454 0.903742 -0.425143 --23.2623 1.28742 -1015.99 0.129208 0.973726 -0.187518 --17.3187 -15.8334 -980.752 -0.180796 -0.962809 -0.200777 --17.1971 13.6363 -994.785 -0.523985 0.508423 -0.683334 -10.0774 40.7541 -973.889 -0.0639904 0.117846 -0.990968 --30.7243 -45.8895 -959.515 -0.961578 0.258182 0.0933232 --19.8811 -16.0053 -979.566 -0.142616 -0.828567 -0.541422 --29.968 -10.2173 -1018.17 -0.930429 -0.0242512 -0.365668 -8.86929 -17.5245 -962.934 -0.38829 -0.764855 0.514031 --18.503 -13.4991 -1028.54 -0.462981 0.722686 -0.513198 --16.5843 -11.9595 -1032.11 -0.28296 0.959132 6.20901e-005 --16.0867 -12.0335 -1033.06 -0.0504195 0.949066 -0.311016 --29.8205 -21.7286 -960.061 -0.879474 0.0288468 0.475071 --18.5073 -15.3123 -981.44 -0.338634 -0.883634 -0.323293 -19.6712 -33.7709 -1012.83 0.0125186 -0.948763 -0.315742 --18.902 -8.74244 -1026.87 -0.265391 0.268865 -0.925894 --13.7589 -6.54972 -1031.8 -0.458339 0.0656479 -0.886349 --15.5835 -16.4324 -984.365 -0.336536 -0.922753 0.187803 --7.72797 12.2059 -1007.36 -0.195537 0.715474 -0.670718 --9.94709 -19.2911 -988.917 -0.189412 -0.924518 0.33074 --0.480173 7.47181 -1014.61 -0.317325 0.805893 -0.499841 --20.9403 -6.84547 -1026.18 -0.572317 -0.401405 -0.715071 -15.4068 -34.295 -1011.18 -0.00515307 -0.950501 -0.310679 --23.0794 -2.23065 -999.006 -0.641372 0.28222 0.713438 --21.612 -14.5959 -980.524 -0.205408 -0.606515 -0.76808 --20.8402 -14.5641 -981.007 -0.471942 -0.674664 -0.567538 --18.5993 -8.33102 -1026.99 -0.461988 -0.17124 -0.870198 --29.8626 -43.8796 -980.884 -0.0463656 -0.93488 -0.351923 --21.4176 25.6463 -972.865 -0.181629 0.263837 -0.947313 --18.5901 -13.0587 -1031.33 -0.630099 0.756118 0.176806 --14.9781 -8.90517 -1030.39 -0.756398 -0.263122 -0.598857 --13.6025 -9.2605 -1032.45 -0.687391 0.0668487 -0.723205 --16.6369 -5.88315 -1031.15 -0.287848 -0.298918 -0.909831 --22.7719 -4.15081 -1026.09 -0.705347 -0.0837742 -0.703895 --32.2199 -44.0045 -980.015 -0.37036 -0.842427 -0.391345 --23.9585 -5.06801 -1024.09 -0.506622 0.239637 -0.828196 --21.7876 -4.51696 -1026.83 -0.352791 0.314006 -0.881441 --22.6867 -13.3831 -980.86 -0.283467 -0.516422 -0.808056 --28.2258 -49.0503 -952.284 -0.431746 0.240032 0.869471 --25.3813 -14.8893 -979.492 -0.204295 -0.448349 -0.870199 --13.4282 -11.4484 -1032.13 -0.755978 0.406378 -0.51318 -19.879 -41.247 -976.066 0.294073 0.230542 -0.927562 --15.8877 29.1097 -978.106 -0.337419 0.718276 -0.608464 --32.8793 -30.0674 -1012.07 -0.922733 0.379076 0.069754 -24.878 -45.8738 -972.924 0.762726 -0.26782 -0.588661 --20.9113 -8.13577 -1026.05 -0.429362 0.0488667 -0.901809 -21.824 -43.4492 -975.911 0.523452 0.234166 -0.819246 --23.6533 -12.5761 -981.133 -0.190984 -0.540304 -0.81951 --21.6041 -5.03989 -1026.96 -0.576778 -0.15396 -0.802261 --22.2604 -6.04056 -1025.26 -0.660459 -0.284855 -0.694731 --31.043 -43.4627 -981.949 -0.225595 -0.853596 -0.469554 -13.0409 -33.7367 -1012.93 0.00706812 -0.951919 -0.30627 -3.51933 -1.23965 -1020.77 0.416263 0.675365 -0.608775 --15.2334 -11.7462 -1031.21 -0.3223 0.933312 -0.158274 -24.3465 -44.1957 -973.708 0.803809 0.226476 -0.550091 -9.41153 49.2402 -968.601 0.165402 0.479943 -0.861566 -24.4498 -22.2024 -972.459 0.974252 -0.0536493 -0.218987 -3.17562 0.536042 -1023.99 0.664977 -0.171963 -0.726797 --15.8783 -11.9067 -1030.72 -0.36082 0.927912 0.0937435 --16.091 -11.9853 -1028.82 -0.529524 0.798421 -0.28658 -17.753 -32.758 -1016.01 0.0125995 -0.951604 -0.307068 -5.86185 22.555 -986.289 0.653215 0.75703 0.0147087 -14.8048 -33.2154 -1014.47 -0.00237603 -0.951558 -0.307461 --14.8284 -8.01746 -1030.89 -0.720406 -0.078758 -0.689067 --13.8086 -9.64643 -1032.22 -0.799538 -0.120853 -0.588332 --29.3269 -14.1135 -979.544 -0.0932436 -0.521672 -0.848035 --17.1602 -8.7753 -1027.87 -0.669324 -0.495748 -0.553389 --15.5368 -10.4939 -1028.78 -0.768936 -0.0738401 -0.635047 -8.36886 -34.2041 -1011.67 -0.00883688 -0.965787 -0.259185 --26.5485 -49.0629 -951.573 -0.570067 -0.359313 0.738863 --31.5832 -46.5975 -965.314 -0.870144 0.355322 0.341462 --17.496 -6.4616 -1030.52 -0.523402 -0.553751 -0.647619 --17.0698 -10.0389 -1027.6 -0.387885 0.101295 -0.916125 -18.996 -31.5971 -1019.59 0.014226 -0.950083 -0.311672 --13.867 20.2078 -986.934 -0.647231 0.756047 -0.0973941 --14.6538 20.875 -988.56 -0.968035 -0.0831006 0.23665 --14.514 15.8929 -989.812 -0.760219 0.536361 0.366584 --19.1103 39.926 -973.505 0.149197 -0.124577 -0.980928 -2.86216 -34.6506 -1010.25 0.0230012 -0.962819 -0.269166 --29.9897 -48.6197 -953.802 -0.701809 -0.144774 0.697499 --13.7779 22.4658 -989.697 -0.636538 0.279368 -0.718869 --18.4321 15.6493 -988.078 -0.347431 0.293343 -0.890641 -5.47935 -33.8887 -1012.5 -0.00572175 -0.957475 -0.288458 --11.9445 22.3685 -990.002 0.400583 0.562199 -0.723509 --14.0155 38.212 -980.803 -0.20661 0.765454 -0.60942 --14.6442 15.9349 -989.011 -0.461385 0.376853 -0.803185 --15.4468 15.9482 -988.767 -0.262197 0.0961767 -0.96021 --8.10909 6.90069 -1015.22 -0.287864 0.927054 -0.240219 --27.69 45.3186 -955.503 -0.882992 0.413185 0.222719 --14.4869 19.4191 -987.917 -0.697364 0.570561 -0.433755 --18.8866 15.5219 -987.862 -0.725162 0.537978 -0.429789 --12.8127 22.3054 -990.146 -0.0594223 0.412731 -0.908913 -4.44623 5.1226 -1019.64 0.965588 0.259472 -0.0177198 -7.57799 -32.9575 -1015.48 0.00238683 -0.95017 -0.311722 -14.241 -31.4223 -1020.11 0.00336811 -0.952761 -0.303703 -9.2295 -32.1536 -1017.82 0.0065123 -0.952304 -0.30508 -11.8126 -31.6066 -1019.55 0.00325431 -0.952967 -0.303056 --14.1607 17.2908 -989.977 -0.898978 0.297701 0.321269 --14.4806 17.403 -989.184 -0.547975 0.0992997 -0.83058 --4.09212 -35.2073 -1008.48 -0.049663 -0.98376 -0.17248 --14.0023 18.0128 -989.553 -0.835851 0.350781 -0.422263 --14.2678 19.8063 -987.931 -0.925079 0.336022 0.176969 -17.1668 -30.4183 -1023.27 0.0162494 -0.94804 -0.317735 -3.08657 -33.2532 -1014.32 0.00164561 -0.955722 -0.294266 -12.7542 -21.3002 -1028.61 0.537825 -0.230872 -0.810828 --13.3541 22.832 -989.654 -0.327615 0.821934 -0.465932 --12.0323 20.6252 -990.559 0.128295 0.431084 -0.893145 --9.48453 40.7521 -933.099 0.483337 0.130302 0.865683 --12.1278 19.9152 -990.84 -0.512115 0.432975 -0.741802 --14.4958 18.4978 -988.776 -0.515405 0.503977 -0.693084 --13.476 18.9646 -989.818 -0.855388 0.0451912 -0.516013 --14.6167 20.5814 -988.98 -0.934472 -0.0893279 -0.34465 -0.70004 1.37219 -1025.75 0.897256 0.411492 -0.160021 --31.3373 -47.8578 -961.35 -0.958414 0.129956 0.254074 --30.2997 -49.1266 -954.511 -0.92561 -0.114849 0.360634 -7.99503 -18.5662 -966.531 -0.63611 -0.735312 0.233837 -8.16366 11.8327 -1004.9 0.625281 0.77505 -0.0912219 -4.95119 15.1839 -1004.3 0.919384 0.374729 0.119628 -1.63138 -32.8319 -1015.72 0.0671816 -0.960519 -0.269982 -5.89361 14.3386 -1001.48 0.469777 0.544638 -0.694751 -14.7663 -30.3789 -1023.41 -0.00013759 -0.951179 -0.308641 --19.2683 43.9537 -973.043 -0.107868 0.585573 -0.803411 --30.8946 -45.3324 -960.841 -0.954312 0.264499 0.139029 -2.90191 -32.5877 -1016.64 -0.0306137 -0.963824 -0.264777 -5.39714 17.3029 -1002.04 0.585221 0.429436 -0.687824 --0.0897797 -33.447 -1014.13 0.0134109 -0.95181 -0.306396 -0.4066 -33.1375 -1015.35 -0.0445643 -0.945404 -0.322839 -6.14103 17.1936 -1000.89 0.998444 0.0454544 0.0323168 -6.07071 17.7331 -1001.04 0.831011 0.444599 -0.334294 -7.13059 13.3461 -1002.15 0.169635 0.790175 -0.588937 -2.59003 -32.4215 -1017.43 -0.0661359 -0.964583 -0.255354 -5.50923 -31.8063 -1019.05 -0.0129505 -0.950699 -0.309845 -6.13041 15.4769 -1000.27 0.902345 0.237391 -0.359747 --5.64241 -33.9958 -1012.26 -0.00570784 -0.962211 -0.272244 -13.1771 -31.0315 -974.18 -0.634841 -0.208004 -0.744118 -5.89364 12.886 -1002.77 0.230774 0.930613 -0.284081 -17.2248 -29.0028 -1027.47 0.0414281 -0.931109 -0.36238 -4.96268 13.3708 -1002.5 0.508821 0.56647 -0.648238 -5.50849 15.1567 -1001.54 0.828753 -0.00366987 -0.559603 -4.78505 15.6031 -1002.87 0.930747 -0.0868408 -0.355203 -4.55917 15.8779 -1003.33 0.657451 0.522469 -0.54294 -10.8615 -30.3176 -1023.58 0.00343093 -0.94845 -0.316908 -1.81148 -32.1865 -1017.81 -0.0528051 -0.957675 -0.282968 -19.0458 -51.5528 -956.166 0.0729701 -0.912116 0.403386 -26.5158 -46.8261 -968.628 0.993184 0.00665655 -0.116368 -9.12788 17.5971 -990.303 0.169864 0.517173 -0.838855 --20.6627 -37.1115 -1002.21 0.0661118 -0.955792 -0.286513 --1.67935 -32.8974 -1015.62 0.00870264 -0.955391 -0.295215 --3.46203 39.8669 -931.562 -0.146365 -0.646899 0.748398 -9.45354 18.9206 -990.041 0.138869 0.479631 -0.866412 -14.1341 41.3909 -971.483 0.873495 -0.393985 -0.285978 --3.08232 -32.9524 -1015.23 -0.00334512 -0.964487 -0.264109 -6.99154 -30.8569 -1022.09 -0.0463765 -0.943622 -0.32776 -23.0359 -45.6751 -974.717 0.544668 -0.426866 -0.721888 -5.03729 20.1626 -991.872 0.962636 0.270791 0.00190598 --32.6673 -30.5414 -1010.11 -0.797354 0.547283 0.254378 --18.9222 -36.2633 -1004.56 0.132778 -0.956978 -0.257999 -22.3001 34.9427 -956.623 0.908778 -0.192718 0.370112 -2.85583 -31.4749 -1020.14 -0.00749702 -0.951212 -0.308448 --3.13092 36.9456 -982.544 0.163678 -0.149766 -0.975079 -7.74398 20.6974 -989.304 0.608055 0.557117 -0.565588 -6.06688 22.9713 -991.462 0.320665 0.577173 -0.75103 --5.96793 -33.1499 -1014.82 -0.0144952 -0.95148 -0.307369 --4.67171 -32.9164 -1015.66 0.00179887 -0.963746 -0.266814 -7.21212 22.1293 -990.508 0.863856 0.109861 -0.491614 --3.4833 20.4981 -992.524 -0.0975682 0.965761 -0.240387 -7.82971 -30.0481 -1024.4 -0.0399524 -0.94272 -0.331183 -11.7417 -29.1648 -1027 -0.0120279 -0.912649 -0.408566 -7.75548 19.7259 -989.803 0.405848 0.273982 -0.871907 -0.376304 -31.6518 -1019.75 -0.0183689 -0.948636 -0.315837 -5.07943 21.417 -993.134 0.683179 0.724337 -0.0927494 --24.9174 -36.8528 -1003.05 -0.00209139 -0.952483 -0.304583 --16.6263 -34.743 -1007.73 0.817633 -0.572921 0.0569032 -8.30715 17.8062 -990.71 0.275213 0.65543 -0.703327 -19.5208 2.13611 -954.763 0.627536 0.763083 -0.154606 -7.32337 21.5994 -989.289 0.936343 0.342865 -0.0755269 -5.21288 20.1343 -991.409 0.720903 -0.163001 -0.673595 -7.39269 18.8004 -990.297 0.217711 0.394779 -0.892609 --1.35581 39.8387 -931.133 0.38821 -0.611143 0.689781 -6.95602 20.5753 -990.425 0.761787 -0.0507007 -0.64584 --3.04328 -31.9283 -1018.75 -0.00183469 -0.952415 -0.3048 -6.03193 19.1294 -990.608 0.714494 0.394091 -0.578092 --0.335775 -31.2826 -1020.66 -0.00230746 -0.951024 -0.309108 -5.08912 21.7697 -992.368 0.623614 0.4003 -0.671466 -2.85318 -30.4836 -1023.16 -0.00759859 -0.949023 -0.315117 --14.3497 9.03011 -1007.91 -0.666 0.74262 0.0704308 --16.8244 -34.6504 -1009.31 0.369644 -0.919982 -0.130372 --13.8274 9.57507 -1009.09 -0.856935 0.453602 0.244759 --1.51297 -31.2877 -1020.82 0.00376395 -0.9519 -0.306385 --15.5105 11.8526 -1003.84 -0.56113 0.823895 -0.0795691 --12.6704 12.9074 -1007.49 -0.565976 0.822129 -0.0614393 --13.6191 10.7163 -1006.73 -0.762314 0.337996 -0.551939 --21.887 -35.6493 -1006.89 0.00960327 -0.952889 -0.303168 --14.5977 12.0439 -1005.27 -0.70511 0.589461 -0.394152 --12.8906 12.8685 -1006.81 -0.905037 0.353995 -0.235786 --13.4016 11.4221 -1007.06 -0.974681 0.202711 0.0943666 --15.296 7.85059 -1007.81 -0.695101 0.669995 -0.260657 -22.0557 -2.61937 -979.842 0.713656 0.240104 -0.658062 --14.9225 8.4942 -1007.39 -0.459724 0.447885 -0.766846 --18.1463 -34.3981 -1010.72 0.0221443 -0.965919 -0.257895 --9.65875 -32.462 -1016.92 -0.00098977 -0.952795 -0.303613 --14.2872 15.2242 -1005.22 -0.709246 0.673481 -0.208313 --14.5288 9.11492 -1007.35 -0.462489 0.616106 -0.637587 -4.83762 -29.3977 -1026.6 -0.0026062 -0.948986 -0.315307 --30.4382 -27.1824 -1024.38 -0.931926 -0.15177 -0.329364 --16.4797 9.46777 -1006.98 -0.15421 0.395319 -0.905506 --14.1946 11.8274 -1005.83 -0.327491 0.575628 -0.749268 --2.93178 -30.7261 -1022.3 -0.00863424 -0.952019 -0.305917 --0.637191 -30.2546 -1023.89 0.00367051 -0.951953 -0.306223 --14.5328 12.438 -1004.43 -0.994048 -0.0549146 0.094095 --13.3807 -32.9543 -1015.44 -0.00127841 -0.951702 -0.307019 -7.73144 3.38118 -1015.11 0.322031 0.627613 -0.7088 -22.7722 35.6656 -958.833 0.982686 -0.184287 -0.0191532 --25.766 -35.349 -1007.78 -0.00629439 -0.95225 -0.305254 --8.48846 -31.7848 -1019.16 -0.00739579 -0.951124 -0.30872 -4.58862 8.15888 -1013.74 0.915248 0.379767 -0.13453 -9.9377 2.32468 -1015.72 0.174917 0.411399 -0.894514 -8.55865 -20.1562 -972.22 -0.861525 -0.499677 -0.0899857 -8.8495 1.72836 -1016.36 0.795149 0.596644 -0.108414 -4.77191 7.79108 -1015.97 0.904443 -0.300833 -0.30246 -3.62974 7.74025 -1017.28 0.535075 0.196475 -0.82164 -11.2958 -40.5883 -966.424 -0.968109 0.232913 0.0922849 -5.29992 6.59708 -1013.92 0.565989 0.0982542 -0.818537 -2.73359 6.79869 -1018.51 0.274593 0.944271 -0.181523 -4.91069 6.50256 -1014.18 0.573898 -0.525639 -0.627968 -9.07928 1.9647 -1015.95 0.232702 0.523802 -0.819439 -4.98388 4.97144 -1014.41 0.307131 0.694344 -0.650812 -6.88923 3.9927 -1014.97 0.336439 0.71756 -0.60985 --21.6183 -17.2835 -997.97 -0.754821 -0.579231 0.307794 -7.12714 4.78648 -1014.53 0.108228 0.482275 -0.869309 -3.0093 6.49225 -1017.82 0.966456 0.245685 -0.0748491 --26.2203 -26.2352 -1033.95 -0.400102 -0.388002 -0.830285 --3.44285 -30.0851 -1024.47 0.00338157 -0.954154 -0.299297 --7.6782 -30.9308 -1021.7 -0.0151853 -0.949189 -0.314339 -1.06347 -29.1203 -1027.37 0.00337766 -0.949215 -0.314611 -3.17989 5.79817 -1016.49 0.940933 0.230282 -0.248223 -3.40097 6.87673 -1017.18 0.811301 -0.40303 -0.423507 -2.71413 7.17181 -1017.84 -0.0108069 0.641869 -0.766738 -4.01853 7.61966 -1016.95 0.722289 -0.0301325 -0.690935 --20.7798 -33.443 -1013.72 -0.00983477 -0.955637 -0.294382 --14.4237 -31.9905 -1018.4 -0.000319269 -0.950842 -0.309675 --5.62279 -30.2169 -1024.07 -0.00903506 -0.951943 -0.306142 --16.5098 -32.4837 -1016.94 -0.000963438 -0.951929 -0.306317 --4.6115 38.5886 -933.638 -0.720565 -0.502105 0.478201 --30.5079 -35.2431 -1007.98 -0.0204882 -0.950605 -0.309728 -25.568 -12.9498 -975.423 0.981965 0.0974301 0.162026 --4.70956 38.9752 -933.194 -0.452499 -0.684012 0.572165 -25.8865 -11.7134 -977.65 0.904927 -0.365121 -0.218618 -25.7607 -12.2491 -977.711 0.97505 -0.0137694 -0.22156 -25.7334 -12.7086 -975.076 0.886926 -0.428508 -0.172463 -25.8078 -15.5824 -976.578 0.917177 -0.353688 0.183553 -26.5932 -10.7411 -976.924 0.940963 -0.137887 -0.309155 -25.195 -14.7702 -973.843 0.941174 -0.330217 0.0717494 -25.5308 -13.494 -974.951 0.991089 -0.063792 0.116934 -21.2817 -13.7292 -1020.06 0.869816 -0.200284 -0.450895 --28.1183 45.2004 -951.802 -0.620123 0.771177 0.143994 --11.4704 37.557 -934.128 0.312374 -0.581642 0.751076 --14.8094 -31.3632 -1020.27 -0.0012338 -0.951258 -0.308394 -11.8391 -16.6327 -1029.13 0.285427 0.000352701 -0.9584 --19.5288 -32.4316 -1017.05 -0.00695066 -0.953111 -0.302541 --10.6892 44.117 -975.68 0.313428 -0.110804 -0.943125 -18.4319 -27.0431 -959.932 0.317521 -0.165577 0.933683 --9.51508 -30.3306 -1023.59 0.0025711 -0.952431 -0.304742 -17.7712 -16.8305 -1025.81 0.636892 -0.356478 -0.683587 --19.5206 55.9872 -949.516 0.36924 0.866838 0.335041 -12.4595 -15.4594 -1029.11 0.289136 -0.377594 -0.879672 --23.3294 -33.0002 -1015.05 -0.00791308 -0.953041 -0.302739 --26.8671 -47.7116 -949.412 -0.45797 -0.402388 0.792683 -17.1083 -14.8407 -1027.77 0.458178 -0.583689 -0.670358 --12.7598 -30.5665 -1022.89 -0.00344618 -0.953019 -0.302892 --25.4041 -33.1148 -1014.69 -0.003611 -0.952694 -0.303908 -9.82363 -17.5349 -1029.54 0.293537 0.0351274 -0.955302 -14.788 -15.1955 -1028.67 0.292353 -0.655491 -0.69632 -17.5006 -16.1747 -1026.41 0.331927 -0.519373 -0.787449 --8.24867 -29.415 -1026.45 -0.00703011 -0.951456 -0.307704 -1.33483 -25.0631 -1032.59 0.432982 -0.404088 -0.805754 -15.3558 -16.0303 -1027.87 0.401872 -0.283167 -0.870813 --17.0077 -31.3842 -1020.25 0.00425802 -0.950015 -0.312174 -12.5954 -15.1005 -1029.27 0.310307 -0.732383 -0.606073 --20.3333 35.3603 -977.073 0.102059 0.60412 -0.790331 -19.0343 -15.7961 -1023.78 0.891717 -0.387325 -0.234137 --1.01866 -27.8075 -1031.35 0.0499052 -0.902747 -0.427268 -20.52 -14.4281 -1021.13 0.854582 -0.444837 -0.267974 -21.3503 -13.078 -1020.61 0.929735 -0.338813 -0.144219 --2.37118 -27.9882 -1030.87 0.00763575 -0.940638 -0.339325 --20.8978 22.9893 -945.965 -0.699331 0.223677 0.6789 --24.4113 27.2954 -950.048 -0.995924 -0.0880887 -0.0193697 --18.3415 19.6766 -941.417 -0.93781 -0.102797 0.331579 --30.8278 -33.4923 -1013.36 -0.0904777 -0.943535 -0.318678 --20.0046 21.7458 -944.371 -0.816135 0.0440897 0.576177 --21.0542 22.1284 -945.992 -0.893948 -0.258917 0.365814 --21.4736 21.2126 -947.92 -0.774691 0.126364 0.619585 --22.9136 -10.9992 -988.561 -0.925783 -0.377235 0.0248959 --21.7364 1.68843 -1008.79 -0.240367 0.960246 -0.141954 --6.67764 -28.6154 -1029.03 -0.0108507 -0.949696 -0.312986 --19.7148 -31.3552 -1020.4 -0.00599367 -0.950873 -0.309522 --11.0981 -29.5024 -1026.17 -0.000261954 -0.951395 -0.307974 --1.65458 -26.4457 -1033.05 0.217099 -0.538662 -0.814071 --24.1242 -32.0081 -1018.15 -0.0244054 -0.95288 -0.302365 --21.5215 22.0373 -947.905 -0.835589 -0.317879 0.448045 --28.5411 -32.8257 -1015.51 -0.0168689 -0.952299 -0.3047 -23.486 -31.4635 -1001.3 0.517305 0.855535 -0.0213434 --26.7097 -33.0886 -948.268 -0.452465 0.649969 0.610586 -19.5561 -15.9863 -1021.53 0.74557 0.0376204 -0.665364 --18.2716 20.7975 -942.3 -0.266231 0.745437 0.611101 --28.0498 -32.3642 -1017.06 -0.0206375 -0.951753 -0.306169 -20.1478 -12.5188 -1024.94 0.805177 -0.132518 -0.578038 --22.8746 23.6293 -947.658 -0.786356 -0.232744 0.572254 --11.7002 -29.0043 -1027.7 -0.00768545 -0.950127 -0.311769 --8.99981 6.25401 -1017.19 -0.267281 0.832058 -0.486045 --20.7962 -27.4508 -955.361 0.126499 0.4955 0.859347 --20.2334 -14.2169 -984.922 -0.587303 -0.798261 0.133623 --14.4405 -29.3903 -1026.5 -0.00291625 -0.954033 -0.299687 --16.9792 -30.0415 -1024.34 -0.0014952 -0.952014 -0.306052 --20.6315 -14.4976 -987.56 -0.623868 -0.750124 0.219321 --27.4605 42.3735 -956.246 -0.764331 -0.231762 -0.601735 --25.4128 47.6821 -962.985 -0.672061 0.0561081 -0.738367 --20.2754 -30.0804 -1024.09 -0.00443431 -0.951029 -0.30907 --20.8837 50.0331 -967.987 -0.0798842 0.0870533 -0.992996 --27.6839 -32.5826 -949.783 -0.290179 0.764944 0.575028 --20.4891 48.167 -968.095 -0.447185 0.0261846 -0.894058 --24.656 -3.62343 -1023.27 -0.449926 0.41672 -0.78988 --29.09 45.0443 -960.231 -0.951852 -0.117699 -0.283062 --9.71814 -27.7399 -1031.6 -0.00861862 -0.943507 -0.33124 -23.8968 -43.0924 -973.565 0.74362 0.227457 -0.628723 -24.836 -43.6889 -972.373 0.868284 0.309722 -0.387498 --25.2713 48.7173 -963.371 -0.998683 0.0189307 0.0476831 --24.2699 -30.558 -1022.79 -0.0217653 -0.95175 -0.306103 --8.10159 -27.1942 -1033.17 -0.00899113 -0.940782 -0.338894 --24.832 47.9735 -965.34 -0.809221 -0.498238 -0.31132 --22.3361 45.7573 -966.126 -0.56677 -0.509625 -0.647343 --24.3156 46.1885 -963.47 -0.713381 -0.306688 -0.630103 --10.9144 -27.003 -1033.54 -0.144395 -0.773469 -0.617168 --28.3483 44.2792 -960.963 -0.661432 -0.55484 -0.504639 --29.3843 44.797 -959.108 -0.980924 -0.0600982 -0.184867 -18.4591 -29.888 -1002.76 0.126346 0.941729 0.311742 -14.1769 -34.8117 -974.259 -0.591364 -0.119717 -0.797468 --13.2881 -27.5844 -1031.95 -0.171664 -0.851316 -0.495774 --27.1205 -30.0704 -1024.03 -0.0286074 -0.948775 -0.314654 --27.2825 42.5039 -956.683 -0.806129 -0.578091 -0.126359 --22.2196 -27.8118 -955.065 -0.0300406 0.536581 0.843314 --21.7247 49.0881 -967.646 -0.331526 -0.263547 -0.905888 --22.0298 -29.0882 -1027.3 -0.00268351 -0.949492 -0.313779 --24.6929 -29.4291 -1026.28 -0.0411272 -0.94927 -0.311762 --26.3387 42.4144 -960.428 -0.739408 -0.524536 -0.422064 --20.1632 -28.6015 -1028.84 -0.00394686 -0.948596 -0.316464 --26.4352 41.3627 -957.046 -0.872551 -0.339978 -0.350813 --18.0187 31.3005 -933.7 -0.481725 0.811371 0.331087 --24.5652 -28.0028 -1030.39 -0.0537052 -0.94713 -0.316322 --24.1752 -27.5556 -1031.96 -0.116413 -0.935765 -0.332855 --26.0501 -26.8853 -1033.57 -0.0608926 -0.756061 -0.651662 --6.17067 23.2143 -934.516 0.155487 -0.987162 -0.0365482 --24.5184 48.1746 -966.097 -0.698846 -0.407529 -0.587822 --30.7005 -48.2094 -960.267 -0.944315 0.101273 0.31307 -0.575711 -24.8338 -1033.16 0.351916 -0.438423 -0.827007 -18.7848 -46.772 -957.463 0.113605 0.802262 0.586063 --28.2343 43.8044 -960.37 -0.694483 -0.649506 -0.309574 -10.3797 27.0418 -941.494 0.333088 -0.882951 -0.330832 --24.4349 48.5443 -966.395 -0.519468 -0.24495 -0.818628 -11.6174 28.9264 -944.893 0.291877 -0.869013 -0.399531 -24.1641 -18.2036 -1020.18 0.843901 0.177469 -0.506296 --22.8656 45.4012 -964.82 -0.790075 -0.254332 -0.55776 --22.8219 45.9604 -965.625 -0.694807 -0.59529 -0.403575 --23.2183 45.0906 -964.479 -0.67921 0.615779 -0.399362 -0.350124 -35.0541 -1008.84 0.0727052 -0.993456 -0.0880842 --23.0518 -37.7762 -1000.23 0.00818944 -0.981907 -0.189184 --25.2736 44.0213 -962.832 -0.434241 -0.12213 -0.892479 --20.2254 -37.6778 -999.682 0.194168 -0.963937 0.182001 -3.79695 41.6318 -932.03 -0.0172296 -0.635935 0.77155 --25.5954 43.3172 -962.432 -0.627608 -0.392926 -0.6721 --22.4658 19.9193 -959.161 -0.884036 -0.464983 0.047655 --19.5141 -37.4068 -999.616 0.665897 -0.686448 0.292182 --28.8018 45.2775 -961.136 -0.859233 -0.0720209 -0.506489 --18.4901 -36.3437 -1002.43 0.893184 -0.391218 0.221743 --21.4848 35.5294 -974.119 -0.572504 0.672741 0.468677 --17.4873 -17.4383 -990.494 -0.475148 -0.833534 0.281877 -20.2242 -39.913 -975.574 0.530866 0.235538 -0.814066 --17.4064 -35.4674 -1005.9 0.537134 -0.839842 -0.0784351 -5.961 -16.4416 -955.919 0.355603 -0.922312 0.151283 --26.4996 42.1474 -959.438 -0.70505 -0.695089 -0.140554 --28.9538 43.9783 -957.947 -0.808407 -0.525115 0.265955 -6.68693 -16.4846 -958.227 0.320294 -0.941811 0.102002 --29.3111 45.3531 -957.584 -0.963849 -0.0461586 0.262419 -6.90824 -16.5139 -959.477 0.303888 -0.93247 0.195326 --5.49866 -20.3058 -989.515 -0.139318 -0.909638 0.391343 --27.7903 43.3364 -956.812 -0.929994 -0.343996 0.129525 -9.65954 -18.8876 -990.196 0.361151 -0.884406 0.295629 --28.9136 43.8268 -958.444 -0.735694 -0.675067 -0.0551369 -11.073 -17.4923 -987.2 0.444445 -0.88483 0.139801 -13.2211 -16.2241 -986.78 0.565534 -0.803506 0.185876 --29.7855 -39.1736 -959.294 -0.626921 -0.762515 0.159812 --33.9311 -36.102 -1004.33 -0.51649 -0.830363 -0.209131 --30.9418 -48.6481 -958.482 -0.988177 -0.0223432 -0.151683 -11.7117 -35.4365 -1006.5 -0.602967 -0.791737 -0.0978901 --28.0237 39.9004 -955.268 -0.820634 -0.136486 -0.554916 --27.0172 37.6112 -953.563 -0.27324 0.0918643 0.957549 --28.9809 40.0264 -952.381 -0.855396 -0.500991 0.131551 -11.3627 -35.1851 -1005.66 -0.926891 -0.373727 0.0346478 --7.23276 -17.1522 -952.619 -0.179618 -0.944859 0.273822 --27.9068 -47.946 -950.342 -0.747123 -0.649191 0.142681 --2.51749 -35.2721 -1008.29 0.0161545 -0.994014 -0.108055 -26.5606 -50.4473 -959.235 0.511104 -0.854524 0.0925245 -25.3493 -50.7828 -958.632 0.255226 -0.95318 0.162198 --27.2281 -24.3103 -1034.03 -0.632854 -0.231125 -0.73897 -22.7394 -51.0947 -957.605 0.197872 -0.976826 0.0815894 --29.0226 40.6197 -951.395 -0.949207 -0.244345 0.198245 -26.6371 -49.8876 -960.935 0.631401 -0.747206 -0.207401 --21.7264 45.2056 -971.183 -0.329308 0.91307 -0.24054 --25.1324 35.0659 -953.059 -0.992024 -0.110604 0.0604564 --25.5378 36.2463 -953.235 -0.731421 -0.35679 0.58114 --29.2579 40.6002 -953.664 -0.921452 -0.321846 -0.21758 -19.0543 -51.2337 -957.771 0.00579637 -0.97204 -0.234745 --26.4472 39.8205 -950.179 -0.253846 -0.600861 0.757976 -1.0752 35.1368 -981.158 -0.409744 -0.475306 -0.778585 -26.8585 -49.1397 -962.762 0.566293 -0.798616 -0.203775 -19.6589 -38.5119 -975.535 0.357142 0.108871 -0.927683 -15.7506 -51.0954 -958.735 -0.000587466 -0.959136 -0.282944 -25.3142 -49.0536 -964.552 0.140835 -0.944775 -0.295917 -12.4209 -50.8395 -959.146 -0.0788106 -0.951748 -0.296587 --22.7652 -29.2024 -954.03 -0.063907 0.535085 0.842377 --25.2728 39.3203 -950.315 -0.420093 -0.416785 0.806109 --25.9806 36.9385 -953.058 -0.829875 -0.42146 0.365621 --28.79 40.2239 -951.245 -0.647587 -0.591841 0.479953 -24.9433 -47.9446 -968.053 0.0932426 -0.944936 -0.31369 -12.6664 -50.0686 -961.705 -0.0245399 -0.965687 -0.258548 -10.7505 -50.1198 -961.008 -0.224656 -0.948883 -0.221701 -11.9379 -49.52 -963.027 -0.0442464 -0.96839 -0.245487 -11.8289 -18.1259 -991.191 0.487935 -0.823349 0.289855 --1.08331 -20.2924 -945.07 -0.0850639 -0.993122 0.080452 --25.5766 36.8666 -952.028 -0.968375 -0.15641 0.194384 -10.1455 -49.3027 -962.817 -0.575252 -0.805278 -0.143569 --28.1154 38.773 -954.115 -0.894894 -0.441424 0.0656498 -12.4253 -49.2439 -964.569 -0.0653717 -0.95026 -0.30452 --0.639233 -20.1663 -946.908 0.196385 -0.973533 -0.116906 --26.9584 38.0414 -953.367 -0.640311 -0.334001 0.691698 -10.2894 -49.2504 -963.757 -0.362335 -0.905385 -0.22134 -23.8024 -46.8013 -971.803 0.0964814 -0.947682 -0.304285 -1.4936 -16.2979 -948.711 0.626188 -0.739315 0.247592 -9.63168 -48.4621 -964.38 -0.969218 -0.243636 0.0354814 --2.2108 -19.9915 -947.734 -0.268049 -0.954331 -0.131915 -12.5337 -17.0235 -989.083 0.55092 -0.818064 0.165099 -1.02372 -16.975 -949.119 0.930917 -0.34261 -0.126536 -22.2876 -46.5502 -973.088 0.0101966 -0.952822 -0.30336 -18.7592 -21.2987 -1027.16 0.0206776 0.807585 -0.589389 -10.9717 -47.6659 -968.599 -0.272342 -0.888215 -0.370007 -21.015 -38.1871 -974.665 0.300251 0.0543207 -0.952312 --22.2447 -41.3782 -947.816 -0.637241 -0.470566 0.610321 -10.6122 -47.3555 -968.618 -0.886441 -0.186406 -0.423645 --0.300888 -17.8427 -951.869 0.354062 -0.9352 -0.00631269 -21.407 1.26984 -956.041 0.656772 0.443136 0.610149 -21.3305 0.936586 -955.586 0.658825 0.733605 0.166652 -19.7804 -37.0924 -975.417 0.653828 -0.0586861 -0.754364 --13.1546 -33.832 -1011.2 -0.0238287 -0.964964 0.2613 -22.2686 -31.0442 -975.545 0.653232 -0.406362 -0.638872 -20.963 6.58538 -956.85 0.697931 0.114567 0.706942 -18.3537 -36.1907 -975.651 -0.0219495 -0.0582266 -0.998062 --18.3467 39.3982 -935.11 -0.275327 -0.817926 0.505165 -24.0469 -28.831 -975.735 0.501062 -0.46265 -0.731363 --30.6253 -49.2301 -956.398 -0.966496 -0.140284 0.214957 --0.684945 -16.6076 -941.733 0.211934 -0.206575 0.955202 --21.3759 1.43604 -1010.51 -0.106015 0.985189 -0.134771 -1.65572 -21.8581 -1034.14 0.366383 -0.382896 -0.848029 -21.2323 8.29169 -957.774 0.773026 0.296402 0.560871 -5.83673 -17.137 -961.575 0.167085 -0.977842 0.126129 -20.9769 8.11915 -956.816 0.983732 -0.0931623 0.153597 -24.0997 -25.124 -977.21 0.334027 -0.277527 -0.90078 -21.0947 1.46902 -954.645 0.510131 0.798156 -0.32049 -22.1265 -29.0463 -976.5 0.128732 -0.203314 -0.970614 -20.6683 1.7029 -955.297 0.634807 0.667134 0.38981 -7.07961 -17.3022 -963.479 -0.117231 -0.970729 0.209622 -18.8318 -33.6309 -975.991 0.0276208 -0.176605 -0.983894 -23.338 -26.8766 -1021.26 0.977419 -0.101 0.185612 -7.77728 -17.7407 -964.593 -0.337057 -0.868813 0.362708 -20.0377 5.50914 -953.823 0.953487 -0.221728 0.204203 --31.6741 -45.7816 -966.102 -0.780668 0.322109 0.53554 -21.1069 -26.7959 -976.987 0.0810431 -0.185204 -0.979353 --20.2497 -52.5845 -952.889 0.0693367 -0.997287 0.0247139 -18.5087 -31.3088 -976.416 -0.0571117 -0.209031 -0.97624 -19.3876 3.89262 -953.113 0.997719 -0.0510184 0.0441961 -19.8148 4.69864 -955.617 0.922833 -0.172496 0.344418 --17.7885 -51.9002 -954.642 0.3838 -0.909403 -0.160258 -24.8589 -28.7995 -974.647 0.82089 -0.550087 -0.153441 -20.1853 5.48825 -955.738 0.916948 -0.39127 -0.0781983 -19.4063 3.11941 -953.515 0.759827 0.591515 -0.269764 -19.9451 4.25079 -955.793 0.598937 0.100023 0.794525 -19.949 -24.8412 -977.534 0.190817 -0.155252 -0.969271 --13.3606 31.5137 -931.369 0.0747225 0.671928 0.736837 --20.9442 -52.3959 -953.985 0.0193278 -0.967615 -0.251689 --7.87711 28.8402 -930.789 -0.304107 0.260944 0.916203 -15.7444 -30.1815 -976.349 -0.420646 -0.255488 -0.870507 -16.1055 -29.8729 -976.536 -0.178218 -0.239843 -0.954313 --6.4015 29.0039 -930.846 0.0667129 0.180134 0.981377 --18.9137 -51.914 -955.378 0.115432 -0.964094 -0.239163 -24.9132 -27.5776 -972.363 0.896955 -0.209045 0.38958 --9.99535 32.8721 -929.578 -0.712829 0.371851 0.594645 --6.17557 30.9253 -930.473 -0.0692409 -0.468316 0.880844 --8.97101 33.2 -929.041 -0.41587 0.572634 0.7065 -18.3411 -23.915 -977.993 0.0918255 -0.17134 -0.980923 -20.579 -19.3728 -978.288 0.00736838 -0.210533 -0.977559 --6.8272 32.1194 -928.638 -0.280262 -0.750552 0.598436 -14.9821 -27.386 -976.926 -0.40133 -0.281314 -0.871663 -21.5441 -45.6423 -958.28 -0.0124895 0.936965 0.349199 --7.03497 30.6141 -930.357 0.0469721 -0.157236 0.986443 --3.86756 30.7391 -928.144 -0.304927 -0.583512 0.752684 --4.99525 31.5004 -928.292 -0.500283 -0.669093 0.549575 --7.14917 32.6282 -928.241 -0.270726 -0.498936 0.823268 --4.71244 30.0756 -930.337 -0.573522 -0.462621 0.676058 -14.5363 -23.6126 -977.844 -0.253668 -0.270731 -0.928632 -24.4833 -8.96073 -1011.35 0.707495 0.493158 -0.506207 --13.7827 -24.2179 -1002.95 -0.487425 -0.762226 0.425944 -12.5228 -22.9716 -976.806 -0.684834 -0.349787 -0.639258 --6.90347 32.9154 -928.107 -0.347552 0.0226928 0.937386 -22.1867 -9.42066 -980.545 0.310186 -0.298598 -0.902565 --30.3425 -44.5435 -963.016 -0.887288 0.41095 -0.209379 --28.0387 -52.0077 -955.048 -0.185843 -0.918701 -0.348497 -14.9745 42.9699 -947.305 0.961392 0.105125 0.25431 -13.1392 -21.5633 -978.068 -0.425415 -0.400638 -0.811487 -9.12212 -23.0477 -971.541 -0.961462 -0.146661 -0.232552 -17.8314 -14.4424 -979.706 0.21744 -0.331691 -0.917987 -13.3732 51.7533 -953.456 0.86697 0.392994 -0.306462 --27.0513 38.5663 -960.658 -0.77751 0.222766 0.588093 -13.4334 -20.7226 -978.447 -0.181997 -0.354686 -0.917101 -14.8737 -19.5047 -978.859 -0.00239529 -0.235467 -0.971879 -20.9057 -9.6972 -981.135 0.644286 -0.469938 -0.603369 -8.76368 -2.36234 -1024.3 0.0296306 0.889369 -0.456229 --18.1444 -49.7218 -961.544 0.606117 -0.758118 -0.240582 -9.29158 -24.7495 -970.707 -0.975161 -0.189468 -0.114729 -16.8288 47.7548 -952.634 0.906879 0.399788 -0.133194 --3.82774 -17.6714 -961.436 -0.172381 -0.980717 -0.0920778 -18.5017 -12.8749 -980.37 0.505749 -0.603891 -0.616062 --31.0782 -48.0296 -956.393 -0.999308 0.01148 -0.0353691 -16.011 -15.65 -979.791 0.229595 -0.336263 -0.913353 -19.6513 -11.0563 -981.231 0.688044 -0.661388 -0.2986 -15.8513 43.9886 -950.12 0.949834 0.202256 0.238555 -17.5865 48.2413 -949.921 0.559931 0.0225103 0.828233 -17.3237 47.1806 -950.504 0.852931 -0.521895 -0.011557 -15.0088 51.1375 -952.561 0.373749 0.289716 -0.881122 -16.9352 53.1131 -950.424 0.471195 0.122823 0.873436 -13.5646 -16.9836 -979.943 0.364618 -0.655954 -0.660892 -15.0687 -15.4806 -980.477 0.490401 -0.662642 -0.56605 -17.0409 47.0321 -949.577 0.133334 0.381735 0.914604 -18.4286 -11.9742 -982.323 0.72043 -0.686196 -0.100574 -11.7581 -18.4493 -979.328 0.0721051 -0.599972 -0.796765 -17.8767 50.9235 -951.178 0.713553 0.140913 -0.686284 -16.9385 48.0417 -952.272 0.727123 0.146382 -0.670719 -14.0041 -16.0337 -980.764 0.480202 -0.733163 -0.481538 -16.9062 -13.4738 -981.611 0.628655 -0.730871 -0.265746 -10.4309 -19.3783 -978.176 -0.350739 -0.625206 -0.697209 --17.4165 -48.7668 -964.847 0.338598 -0.928606 -0.1518 -15.3128 -14.7894 -981.548 0.577054 -0.792278 -0.198253 -10.4877 -18.3179 -979.587 0.0140752 -0.845178 -0.5343 -12.4544 -16.8551 -980.971 0.385664 -0.827754 -0.407536 --18.1805 -48.7373 -965.481 0.092463 -0.958233 -0.270629 --19.9116 35.2373 -977.205 -0.162689 0.600064 -0.783234 -16.8531 47.0547 -952.314 0.952055 -0.305927 -4.55174e-005 -15.337 -14.6623 -982.534 0.645962 -0.761242 -0.0569531 -0.514878 36.3841 -982.013 -0.50104 -0.452527 -0.737685 -15.9252 45.6854 -951.993 0.808609 0.0166842 0.58811 --15.9377 -47.955 -967.196 0.366267 -0.913943 -0.174805 -15.858 49.9915 -952.514 0.52307 0.239189 -0.818038 -10.0449 -22.5108 -998.234 0.454786 -0.787448 0.416048 -16.2899 53.2555 -951.741 0.465437 0.235089 -0.853288 --15.5189 -47.3129 -968.795 0.721478 -0.663662 -0.19754 --28.7926 -49.0766 -964.486 -0.0632987 -0.954591 -0.291117 -15.9296 45.8941 -951.268 0.914132 -0.403221 -0.0421413 --30.8527 -49.2043 -963.446 -0.351278 -0.885855 -0.30309 -17.0504 49.414 -951.872 0.471705 0.174042 -0.864409 -2.25751 37.2652 -983.506 -0.273968 -0.321236 -0.906504 --17.3837 -46.8543 -971.611 0.0959869 -0.950006 -0.297111 -17.9919 51.2377 -950.805 0.941185 0.275 0.196331 -24.3244 -37.2236 -1001.65 0.209505 -0.951871 -0.223718 -14.4658 50.4894 -953.74 0.768055 0.620694 -0.157578 --10.1188 10.051 -1012.56 0.387023 0.822554 -0.416674 --15.2175 37.2132 -936.069 -0.582731 -0.697718 0.416671 -18.0317 50.0768 -950.4 0.424071 0.170799 0.889377 -18.2296 49.8662 -950.656 0.993344 0.0131769 0.114425 -16.0458 -8.74829 -955.318 0.017686 -0.427791 0.903705 -18.0471 48.7037 -950.795 0.944379 -0.212728 -0.250787 --15.7268 -44.5606 -975.756 0.897655 -0.428573 -0.102672 -18.6947 24.39 -955.51 0.879395 -0.474232 0.0420593 -16.0456 -19.1814 -1001.88 0.602565 -0.74705 0.280769 -16.5287 45.8882 -949.244 0.905575 -0.360878 0.222936 -23.767 -36.5371 -1004.08 0.0467116 -0.952875 -0.299745 -25.1344 -20.5209 -977.826 0.841554 -0.0699089 -0.53563 --16.7994 -45.2603 -976.245 0.259219 -0.917369 -0.302058 -15.6303 44.049 -949.181 0.983869 -0.093487 0.15252 -0.961171 -17.8776 -969.061 -0.00563286 -0.999692 0.0241783 -16.3574 45.9788 -948.802 0.767743 0.308281 0.561723 --16.3346 -44.6241 -977.924 0.492694 -0.827596 -0.268956 --32.2949 -47.1713 -969.716 -0.372191 -0.898208 -0.233872 --15.8463 -43.9489 -979.093 0.634323 -0.734102 -0.24234 -25.2929 -35.0232 -1007.55 0.613984 -0.745208 -0.260172 -16.9407 -18.8628 -1002.3 0.346578 -0.775584 0.527592 -15.0902 49.8856 -953.222 0.677271 0.437263 -0.591697 -24.6946 -19.744 -978.236 0.631554 -0.0566963 -0.773256 -16.0427 45.2571 -948.195 0.89167 -0.12892 0.43394 --16.9876 -43.8873 -980.713 0.25078 -0.90922 -0.332308 -0.949156 -20.8144 -990.219 0.0726025 -0.92356 0.376519 -24.9462 -34.558 -1009.3 0.448828 -0.824102 -0.345555 --9.91657 48.9855 -970.876 0.102246 0.848872 -0.518615 -24.715 -18.8176 -978.275 0.918226 -0.0358488 -0.39443 --7.53607 48.4344 -972.667 -0.305446 0.828146 -0.469975 -23.3847 -33.9225 -1012.14 0.10673 -0.940142 -0.323637 --32.6791 -45.1768 -975.801 -0.616944 -0.765547 -0.182532 --28.2043 46.9569 -960.365 -0.746776 0.385026 -0.542292 --18.8833 49.9324 -967.78 -0.029026 0.00874062 -0.99954 --13.1476 50.1492 -970.971 -0.202585 -0.185889 -0.96146 --14.2917 49.0259 -970.514 -0.59811 0.0757078 -0.79783 --11.1348 48.1024 -973.649 0.0574728 0.927191 -0.370154 --32.5609 -44.4555 -978.333 -0.32095 -0.900066 -0.294741 -12.3326 -40.0078 -970.97 -0.931968 0.0216011 -0.361896 -23.1703 -33.1292 -1014.42 0.198783 -0.915608 -0.349495 -24.9534 -15.9678 -978.776 0.466858 -0.118485 -0.876359 --11.0284 49.9266 -970.461 0.20301 0.418268 -0.885347 --12.8834 51.3064 -971.19 0.152839 0.0298788 -0.987799 --9.84599 51.4522 -970.506 -0.48623 -0.0432709 -0.872759 -23.5907 -32.4878 -1015.51 0.531494 -0.759118 -0.375836 --10.7442 51.5172 -970.343 0.0974268 0.104521 -0.989739 --9.78587 49.6885 -970.246 -0.26644 0.0903693 -0.959606 --15.8842 51.69 -970.972 -0.273505 -0.159576 -0.948541 --32.0566 -29.9267 -1009.77 -0.699046 0.581785 0.415764 --23.374 1.61629 -1010.49 0.0228473 0.999523 0.0207737 --15.7546 52.1653 -970.976 -0.258152 0.47947 -0.838729 --4.46124 38.1261 -933.682 -0.828101 -0.0636162 0.556958 --16.4407 48.396 -968.209 -0.540608 -0.0887811 -0.836577 --21.8339 35.9936 -976.088 -0.443497 0.886971 -0.128811 --17.8897 -15.6083 -984.78 -0.440775 -0.875918 0.196176 --18.1129 50.7784 -968.001 -0.692125 0.0505246 -0.720007 --7.86774 49.0244 -971.899 -0.404384 0.496712 -0.767952 --8.31433 48.0613 -973.233 -0.21158 0.975482 -0.0605637 --9.83813 47.6852 -973.956 -0.211863 0.838314 -0.502338 -18.5991 -15.9518 -960.005 0.286831 -0.0962864 0.95313 --17.8511 51.9084 -969.572 -0.889232 -0.128565 -0.439018 --23.14 -12.0395 -981.7 -0.333122 -0.662328 -0.671082 -8.8341 -19.9418 -974.4 -0.701312 -0.665554 -0.255341 --22.5681 -11.688 -982.47 -0.479484 -0.734183 -0.480697 --30.6682 -46.7057 -960.193 -0.996063 -0.0352507 0.0813435 -24.6128 -13.4757 -979.097 0.240639 -0.0860249 -0.966795 -22.0206 -31.6619 -1018.85 0.270964 -0.892466 -0.360669 --22.1693 35.73 -975.147 -0.678822 0.727241 0.101596 --14.6077 49.946 -970.587 -0.414145 -0.364661 -0.83397 -22.4089 -30.7881 -1020.45 0.523156 -0.758495 -0.388578 -6.86695 37.9782 -935.526 0.180318 -0.77194 0.609586 --17.2374 51.3265 -969.941 -0.580735 -0.420819 -0.696892 --15.1044 48.6663 -969.479 -0.631629 -0.361454 -0.685854 --15.2882 48.2572 -969.178 -0.74517 0.146699 -0.650539 -7.91869 -17.7085 -1030.82 0.699794 -0.519417 -0.490402 -18.8604 -49.7975 -955.799 0.529467 0.100793 0.842322 -19.3303 42.8004 -966.486 0.920205 0.385768 -0.0663745 -20.8072 -31.0092 -1021.2 0.0840853 -0.942148 -0.324478 --11.2487 -22.9423 -997.946 -0.282751 -0.868041 0.408113 --12.844 -16.9098 -964.454 0.527632 -0.813486 0.244632 -6.87236 45.1104 -933.573 -0.0383876 0.715005 0.698064 --24.2779 -31.9326 -949.33 -0.0310231 0.866567 0.498096 -20.7325 -30.1408 -1023.65 0.179791 -0.916456 -0.357469 --29.523 -41.7595 -962.5 -0.998836 0.0168261 -0.0452118 --12.9423 -23.2267 -999.973 -0.362866 -0.846811 0.388896 --14.8065 -22.5021 -1000.32 -0.43144 -0.847777 0.308439 -19.4784 41.9891 -966.331 0.926011 -0.144538 -0.348729 -19.1526 -28.5215 -1028.31 0.176618 -0.898305 -0.40231 -15.8037 -39.6427 -975.013 -0.496688 0.112916 -0.860553 -16.2166 -31.5899 -960.605 -0.0677996 -0.200161 0.977414 -13.1924 41.5543 -973.19 0.57841 -0.479507 -0.659936 -13.0395 42.8435 -974.275 0.250481 -0.380391 -0.89026 -15.1274 -29.1307 -1027.08 -0.00160645 -0.941679 -0.336509 -15.0474 41.3974 -969.461 0.421954 -0.362731 -0.830892 --9.84788 -34.0726 -1011.94 -0.0413149 -0.980162 -0.193846 -15.4488 43.279 -969.433 0.708539 0.273173 -0.650653 -14.7949 42.0382 -970.146 0.84521 -0.328578 -0.421492 -16.3359 -28.0059 -1029.94 -0.0427523 -0.892065 -0.449881 --28.2225 -37.3709 -1001.38 -0.0367111 -0.967785 -0.249087 --12.6313 -33.8288 -1012.76 0.0285456 -0.984433 -0.173429 --27.6865 -32.1494 -950.591 -0.242752 0.892267 0.380698 -7.57997 -29.2089 -1027.13 0.0291236 -0.931169 -0.363424 -16.8441 41.4717 -968.728 0.524115 -0.353331 -0.774894 --14.8703 -36.6779 -955.554 0.99054 -0.123727 -0.0593409 -18.8584 39.7258 -963.009 0.709914 -0.697103 -0.100343 -8.33462 -28.4426 -1028.67 0.14491 -0.769271 -0.622273 -9.41846 -25.8397 -1029.27 0.441784 -0.210897 -0.87198 -19.138 40.5682 -965.482 0.972781 -0.138251 -0.185968 --8.28248 39.4303 -933.84 0.141996 -0.597479 0.789212 --20.9716 -31.9821 -948.531 -0.0785958 0.872157 0.482872 -14.4079 39.7113 -969.182 0.821343 0.0214838 -0.57003 --32.6568 -36.3589 -1004.43 -0.120693 -0.962939 -0.24121 -5.0787 -28.6445 -1028.73 0.0430785 -0.913402 -0.404773 --19.9428 41.6726 -973.888 -0.131155 0.0841797 -0.987781 --3.60115 -34.3847 -1006.33 -0.130957 -0.780066 0.61184 -19.1783 42.2319 -966.982 0.754983 -0.11896 -0.644863 -4.26086 -27.1276 -1030.63 0.234775 -0.36272 -0.90184 -8.49555 -16.8036 -1031.81 0.559011 -0.767452 -0.313885 -9.95137 -16.0534 -1032.48 0.470411 -0.866483 -0.167094 -10.2107 5.81811 -1010.06 0.758263 0.580508 -0.296728 -15.0149 37.9596 -968.979 0.860063 0.317692 -0.399203 -4.7113 -23.4621 -1031.37 0.348826 -0.188798 -0.917974 -16.6991 43.429 -968.918 0.439991 0.377482 -0.81481 -21.3948 -8.91061 -981.059 0.633202 -0.139265 -0.761355 --33.9774 -35.0864 -1007.1 -0.583512 -0.746161 -0.320559 --33.2059 -35.2626 -1007.61 -0.213811 -0.920805 -0.326195 -6.73792 18.0479 -990.679 0.334273 0.62776 -0.702979 -1.30369 41.4696 -932.909 0.358367 -0.182569 0.915555 -6.16286 -19.2503 -1032.75 0.720009 -0.443201 -0.534004 -4.61571 -21.4992 -1033.02 0.616162 -0.462306 -0.637666 --21.1224 33.5109 -972.441 -0.655276 0.606232 0.450662 -16.946 36.9233 -967.072 0.744756 0.627236 -0.227847 -3.19331 -21.3349 -1033.75 0.389645 -0.385555 -0.836375 --32.4394 -33.571 -1012.44 -0.313018 -0.881719 -0.352974 --32.9162 -33.323 -1012.46 -0.674088 -0.630149 -0.38538 -0.159261 -22.8277 -1034.32 0.294938 -0.344179 -0.891377 -19.0981 39.7185 -962.22 0.796041 0.0264648 -0.604664 -18.4496 40.4093 -966.678 0.660398 -0.455837 -0.59673 -16.9241 42.3193 -969.044 0.58329 -0.065476 -0.809621 -17.3138 38.0674 -963.298 0.671749 -0.0362056 -0.739894 -16.9462 36.937 -964.457 0.966978 0.250149 -0.0487783 -16.6476 37.6717 -966.626 0.888711 0.1964 -0.414271 -17.0334 38.3584 -966.139 0.823574 -0.367217 -0.432294 --1.30793 -23.99 -1034.28 0.172596 -0.435047 -0.883711 --4.27253 -26.6608 -1033.42 0.165333 -0.624122 -0.763634 -18.7356 39.7597 -965.651 0.744302 -0.589833 -0.313228 --20.8032 -13.803 -982.346 -0.675487 -0.707925 -0.2063 --4.14784 -25.9748 -1033.78 0.201359 -0.425032 -0.882498 --31.2752 -32.3689 -1016.5 -0.514251 -0.75393 -0.408821 --30.9426 -32.3224 -1016.84 -0.219758 -0.90466 -0.365099 --3.65691 -23.2062 -1034.88 0.0499844 -0.383978 -0.921988 -17.0709 38.0713 -963.741 0.941037 -0.264021 -0.211525 -14.2077 40.1875 -969.482 0.682833 -0.299096 -0.666544 -16.676 39.3442 -967.37 0.509792 -0.447525 -0.734733 -16.8897 38.8036 -966.792 0.65212 -0.431862 -0.623085 --4.57166 -23.1458 -1034.9 0.195512 -0.393403 -0.898337 -16.977 37.1463 -965.775 0.956844 0.289451 -0.0258494 --6.002 -24.5717 -1034.99 0.260908 -0.402675 -0.877371 -17.2207 38.303 -965.344 0.840418 -0.532942 -0.098333 --8.05527 -26.8622 -1034 0.0294305 -0.863468 -0.503544 --7.74985 -26.546 -1034.38 0.122045 -0.619541 -0.775419 --16.0969 -28.7337 -1028.79 -0.0388956 -0.937567 -0.345624 --6.81918 -24.426 -1035.3 0.240197 -0.319835 -0.916521 --17.4668 -28.7751 -1028.33 -0.0300008 -0.940896 -0.337364 --20.0521 56.936 -959.055 -0.0608988 0.955822 -0.287569 --19.793 53.4331 -964.443 -0.158099 0.97316 -0.167224 -23.2272 21.1938 -968.383 0.621303 0.678511 -0.391925 --14.4063 -27.9461 -1030.75 -0.0732891 -0.911321 -0.40512 -15.527 -19.7874 -959.457 -0.164096 0.100222 0.98134 -23.806 -6.77903 -980.008 0.42899 0.100119 -0.897744 --11.3092 19.9387 -991.582 0.0647317 0.98249 0.174711 --19.3032 55.5332 -960.365 -0.0153659 0.468489 -0.883336 --18.7689 56.0442 -960.239 -0.709644 0.307744 -0.633797 --17.9283 53.4987 -963.08 -0.0486708 0.960567 -0.273754 --18.5755 54.389 -960.91 -0.213582 0.719264 -0.661092 --18.8471 -28.2572 -1029.82 0.0427895 -0.882973 -0.46747 --17.5544 -41.8327 -949.733 0.613128 -0.771406 -0.170313 --17.6126 57.4653 -962.185 -0.670003 0.474394 -0.571005 --16.8763 57.2461 -962.698 -0.406973 0.242021 -0.880794 --16.0425 54.284 -963.503 -0.614827 0.511821 -0.600023 -19.0056 -44.005 -976.79 0.057742 0.0435113 -0.997383 --20.8991 -28.0256 -1030.47 0.0408851 -0.918186 -0.394034 --28.1622 -29.0227 -1027.1 -0.279774 -0.885171 -0.371751 --21.25 -27.3361 -1031.58 0.2463 -0.695446 -0.675049 --20.8962 -13.5693 -983.778 -0.660913 -0.750372 0.0116547 --17.6886 56.9529 -962.265 -0.708186 0.0122843 -0.705919 --27.2484 -28.3982 -1029.09 -0.220205 -0.909174 -0.353428 --19.8385 53.4225 -962.679 -0.343848 0.896341 -0.279896 --24.1773 -27.165 -1032.95 0.0401482 -0.868901 -0.493356 --23.9176 -26.4689 -1033.58 0.292954 -0.565975 -0.770617 --26.6291 -27.372 -1032.32 -0.179729 -0.918634 -0.351865 --29.085 29.1286 -970.845 -0.90555 0.421259 -0.0502098 --26.7638 -27.0333 -1033.04 -0.5603 -0.655277 -0.506631 --25.0691 -26.3224 -1033.99 -0.00687725 -0.463414 -0.886116 --25.2801 -32.8164 -948.055 -0.100103 0.760344 0.64176 --24.6538 -24.6651 -1034.72 0.262501 -0.303856 -0.915841 --25.5627 -23.7633 -1034.97 -0.143429 -0.168944 -0.975134 --18.2258 11.763 -995.489 -0.463898 0.336661 -0.819426 -14.9314 -15.0682 -987.05 0.579357 -0.692591 0.429725 -20.9979 41.5671 -955.313 0.939527 -0.329876 -0.0920365 --21.5729 -41.1357 -947.551 0.2096 -0.657813 0.723429 --21.1503 -41.9657 -948.927 0.255542 -0.483565 0.837176 --20.955 -40.4638 -947.235 0.0637502 -0.724711 0.686098 --12.2366 -20.8262 -993.754 -0.242627 -0.887271 0.392278 --20.5813 -40.8857 -948.17 0.267627 -0.772359 0.576053 -20.2124 42.7773 -957.258 0.616252 0.164106 -0.770261 --19.2453 -44.6591 -949.769 0.410336 -0.18783 0.892381 --19.2446 -32.9383 -947.324 0.234201 0.623302 0.746086 --18.5436 -45.6874 -950.632 0.748027 -0.276171 0.603478 --18.4493 -47.9373 -952.462 0.591794 -0.341956 0.729963 --31.3533 -44.1024 -966.7 -0.6498 0.295964 0.700118 -17.488 41.2491 -952.572 0.519668 -0.396151 0.756974 --18.1047 -41.5654 -958.082 0.994364 -0.0390605 0.0985629 -18.217 38.762 -955.597 0.437612 0.129398 0.889804 -23.4483 20.7559 -968.629 0.729646 0.403057 -0.552414 -20.4117 41.0611 -953.72 0.463677 -0.811874 0.354774 -13.2395 -18.9684 -995.135 0.5345 -0.767752 0.353364 -20.7932 41.3446 -953.923 0.827961 -0.510415 0.232286 --17.4312 -42.3294 -964.576 0.698722 0.01041 0.715317 -0.490602 38.2025 -934.98 -0.252079 -0.796962 0.548915 --18.1562 -36.6405 -962.348 0.846673 -0.204025 -0.491446 -20.427 40.1483 -957.675 0.661584 0.749323 0.0286636 -20.2795 40.122 -956.875 0.945417 -0.305785 0.11262 -17.9157 38.8196 -955.187 0.842475 -0.191597 0.503513 -19.7664 39.9863 -956.053 0.618386 -0.542705 0.568392 -16.3727 -14.2705 -989.024 0.62698 -0.757734 0.180928 --19.1048 -34.9132 -964.675 0.715743 -0.491658 -0.495968 --0.971906 -15.19 -941.137 0.273064 -0.108009 0.955913 -20.0572 41.4784 -952.748 0.335321 -0.637829 0.693349 -20.2579 39.3977 -956.483 0.559629 0.486148 0.671174 -14.934 -16.3705 -991.871 0.582118 -0.755161 0.301446 -20.4057 41.0831 -957.013 0.874495 0.0491064 -0.482541 --15.7288 -34.7051 -960.83 0.845758 -0.292181 -0.446458 -18.2101 40.6016 -953.431 0.379625 -0.738802 0.556827 --16.2606 -33.01 -962.928 0.811477 -0.491157 -0.316655 --17.349 -33.0152 -965.157 0.593171 -0.647558 -0.478349 --15.794 -32.2115 -962.087 0.935109 -0.18512 -0.30216 -8.55647 11.1209 -1004.02 0.5703 0.643012 -0.511169 --16.4413 -32.7802 -964.173 0.780292 -0.470231 -0.412344 --18.9491 -32.6173 -968.939 0.716954 -0.695332 -0.0498995 --18.6813 -15.5027 -959.148 0.160133 -0.51945 0.839362 --16.2371 -31.594 -964.528 0.935982 -0.184677 -0.299721 --19.5525 27.6935 -939.118 -0.961034 -0.0986303 0.258235 --29.3698 -38.7122 -949.592 -0.120663 -0.992366 0.0254979 -17.1402 -44.8126 -976.777 -0.0499626 -0.242126 -0.968958 --18.0671 -14.9236 -958.567 -0.158563 -0.73762 0.656335 --19.2135 27.8478 -935.312 -0.850404 -0.449944 0.272696 --16.1727 -25.242 -962.575 0.985633 0.0156752 0.168169 -16.9733 -13.4703 -987.552 0.699651 -0.689411 0.187619 -17.8439 -12.4913 -985.484 0.779691 -0.626164 -0.000322993 --24.0548 1.76944 -1012.65 0.105976 0.992976 -0.0526155 -4.83645 16.7372 -937.645 0.352627 -0.189839 0.916305 -15.4911 -16.3114 -992.933 0.653847 -0.700723 0.285433 -20.2802 -38.0026 -998.959 0.0801794 -0.933171 0.350376 --24.3548 -33.6331 -947.34 0.142555 0.343188 0.928386 --12.4162 13.7494 -940.165 0.0558147 -0.874186 0.482372 --30.6734 -46.7369 -957.643 -0.957435 0.281838 -0.0623374 -7.32296 16.6765 -938.313 0.189592 0.21274 0.958539 -6.13433 16.8415 -938.177 0.251711 0.107226 0.961844 --10.7287 13.7175 -941.17 0.126908 -0.917155 0.377785 -6.02 16.3528 -938.323 0.170704 -0.392422 0.903806 -23.6554 2.21347 -977.116 0.474722 -0.140165 -0.868903 -8.32883 -18.2699 -1030.21 0.563595 -0.172215 -0.8079 --6.98564 24.8896 -930.236 0.161737 -0.911369 0.378481 --20.9945 45.6985 -968.764 -0.580092 0.78086 -0.231842 --20.0818 -34.1486 -946.452 0.111567 0.273233 0.955456 --7.85554 23.1539 -934.563 0.091104 -0.911846 0.400296 --7.73275 23.499 -933.929 0.102148 -0.833793 0.542545 -11.92 18.2884 -940.171 0.527372 0.20317 0.824985 -7.28571 16.2597 -938.459 0.175955 -0.478567 0.86024 --19.6546 -34.0087 -946.61 0.469325 0.171377 0.866236 --2.62197 42.1665 -977.397 0.325832 0.551607 -0.76783 --6.03077 24.9496 -931.626 0.194458 -0.963402 0.184508 -11.3907 17.5886 -939.905 0.70927 -0.350255 0.611766 -10.9618 12.6826 -997.456 0.530796 0.402743 -0.74569 -19.4115 -10.5467 -983.287 0.809915 -0.559156 -0.177151 -4.89502 25.8022 -929.923 0.228819 -0.21807 0.948729 --21.2702 -15.2858 -957.981 0.30183 0.220662 0.927473 --1.7693 12.7405 -940.852 0.192185 -0.879377 0.435616 --1.4666 11.9297 -942.203 0.48242 -0.657726 0.578504 --5.80215 24.8268 -932.137 0.11627 -0.850661 0.512696 --16.16 39.5126 -935.054 -0.604756 -0.424681 0.673733 --1.09319 11.2688 -943.758 0.629986 -0.569829 0.527648 -0.203015 13.8423 -939.284 0.166991 -0.855925 0.489394 -1.39048 25.2161 -929.402 -0.0176813 -0.721369 0.692325 -0.13545 23.2146 -933.859 -0.0561636 -0.880555 0.470605 --0.0755349 12.1562 -943.46 0.337315 -0.804398 0.489043 -10.1801 13.3591 -997.591 0.541951 0.494988 -0.679173 -22.7444 -37.9081 -999.367 0.17211 -0.985039 0.00868958 -0.635076 13.2766 -941.47 0.299609 -0.8915 0.339797 --2.41057 24.9711 -932.698 -0.0446986 -0.652958 0.756074 -0.971059 11.7777 -944.384 0.261042 -0.605908 0.751487 --22.8066 -21.2675 -1006.05 -0.348349 -0.823731 0.447348 -2.39344 13.5342 -942.054 0.186824 -0.903722 0.385206 --4.92835 26.1622 -929.186 0.0822755 -0.0904695 0.992495 -3.19832 14.7346 -939.022 0.161716 -0.836004 0.524353 -2.95611 23.3861 -933.843 0.103721 -0.744145 0.659916 -26.6852 -11.3047 -975.794 0.878592 -0.434719 -0.197725 --30.2321 -44.3863 -965.215 -0.735979 0.520664 0.432717 -2.98508 22.8396 -934.775 0.0018792 -0.952779 0.303658 --2.85496 26.4225 -929.727 0.123998 -0.819459 0.559564 -19.5272 -44.9525 -976.614 0.175269 -0.530569 -0.829324 -3.10355 14.1547 -940.284 0.136053 -0.93461 0.328623 --22.5591 -23.0062 -1009.12 -0.356367 -0.847115 0.394207 --2.22745 26.12 -930.376 -0.51778 -0.787353 0.334634 -14.499 12.9253 -991.386 0.85662 0.395082 -0.331831 -3.88613 24.0138 -933.645 0.173457 -0.740143 0.649693 -23.7702 -37.5648 -998.876 0.5815 -0.717159 0.38411 -2.39372 12.4086 -944.056 0.12603 -0.77006 0.625399 --29.4848 -34.5926 -948.56 0.118533 0.365348 0.923294 --1.66985 26.5733 -929.412 -0.205159 -0.250515 0.946125 --28.0756 -40.2595 -958.261 -0.966699 -0.203433 -0.155267 --20.9582 -23.6443 -1008.86 -0.464641 -0.674644 0.573554 --20.6074 -22.5543 -1006.83 -0.381323 -0.81862 0.429482 -0.255587 24.7535 -932.19 -0.229346 -0.93705 0.263321 -8.5546 -11.0346 -946.928 0.540568 -0.566623 0.621872 -1.65381 24.4937 -932.411 -0.0801982 -0.948557 0.30628 --2.65562 26.7676 -929.421 0.0824824 -0.514126 0.85374 --5.31889 25.5366 -929.707 0.232131 -0.857624 0.458908 --17.2602 -38.2299 -959.467 0.759934 -0.552005 -0.343206 --18.555 -22.8857 -1005.35 -0.409803 -0.815969 0.407745 --22.8611 47.9496 -947.327 -0.82077 -0.521897 0.232295 -10.1699 -7.32631 -944.892 0.620447 -0.661999 0.42048 -5.92189 24.6604 -933.044 0.144847 -0.925421 0.350165 -9.46051 -12.0736 -949.414 0.592938 -0.686407 0.421034 -10.3805 -7.66414 -946.636 0.678252 -0.488279 0.549143 -10.3772 -7.41702 -946.186 0.681121 -0.709991 0.178851 --2.4336 -33.9384 -1012.42 0.00622816 -0.96684 -0.255309 -12.5449 -23.5759 -1027.92 0.524251 -0.174365 -0.833521 --22.4696 47.2258 -946.354 -0.951294 -0.185152 -0.246491 --18.3829 -24.4159 -1008.05 -0.299127 -0.722522 0.623286 -9.33726 -13.641 -952.373 0.57831 -0.748647 0.324169 -6.40425 24.4254 -933.659 0.149007 -0.854432 0.497738 --18.2419 -25.242 -1008.88 -0.150788 -0.459293 0.875393 -10.3972 -10.8592 -948.924 0.669086 -0.587747 0.454838 -7.07902 21.8106 -985.005 0.658807 0.725656 -0.198487 --22.6684 47.6648 -946.427 -0.899144 -0.435933 -0.0387716 --25.7144 52.4594 -946.636 -0.935735 -0.088918 0.341312 --22.2877 44.2973 -942.832 -0.857245 -0.39089 0.335166 --10.633 54.0896 -968.735 0.234956 0.879252 -0.414382 --10.0633 42.6825 -975.338 0.180907 0.117902 -0.976408 --4.2145 59.5266 -955.404 0.235885 0.853495 -0.464655 -7.20912 14.0249 -941.007 0.120397 -0.859199 0.497274 --25.2824 52.8166 -945.83 -0.0157319 0.789596 0.613425 --24.8767 52.9364 -946.151 0.337346 0.774583 0.534994 -7.70629 22.6975 -935.359 0.116816 -0.861633 0.493906 -10.0308 -14.2098 -955.379 0.558591 -0.792667 0.244245 -10.9333 -11.899 -951.737 0.662286 -0.66587 0.343505 -6.86052 -21.1123 -1030.92 0.3957 -0.0872738 -0.914224 -8.20573 24.1878 -934.391 0.274739 -0.734485 0.620524 --23.0322 44.991 -942.866 -0.540154 -0.794169 0.278439 -10.6312 -13.3277 -954.217 0.646418 -0.707743 0.285034 --22.8637 45.0932 -945.856 -0.987618 0.153375 0.0329624 -8.12333 22.9624 -935.205 0.369852 -0.651882 0.662012 --25.4937 51.5039 -944.426 -0.752857 0.422766 0.504455 -11.7598 -6.44036 -947.696 0.782589 -0.455638 0.424203 --28.8255 -41.315 -960.355 -0.646515 -0.446758 0.618406 -8.20276 13.6011 -942.141 0.156174 -0.914381 0.37352 --22.8537 44.0244 -945.389 -0.911919 -0.0406348 0.408353 --25.3862 50.6586 -947.145 -0.417594 -0.346063 0.840152 -7.40218 12.2132 -944.858 0.11436 -0.738596 0.664378 -8.76428 14.8343 -940.252 0.28379 -0.724945 0.627629 --25.1627 50.7375 -946.72 -0.866672 -0.481073 0.132094 -9.18516 25.7453 -932.075 0.323164 -0.831488 0.451877 -9.16989 25.2983 -933.137 0.266256 -0.851118 0.452444 -12.3361 -5.6593 -947.621 0.688697 -0.724854 -0.0168406 --31.3225 -11.9191 -975.13 -0.96073 0.247395 0.125669 -10.0161 -14.8627 -957.894 0.489254 -0.829295 0.270001 --24.7483 47.3803 -941.354 -0.722176 -0.2551 0.642951 -11.3742 -13.4709 -956.503 0.585324 -0.747618 0.31379 -25.7502 -34.3713 -1008.14 0.846408 -0.47256 -0.245519 -9.33824 14.2893 -941.315 0.296569 -0.827893 0.476068 -12.1073 -11.3052 -952.996 0.746599 -0.575454 0.33383 --22.698 44.5261 -943.707 -0.825187 -0.548318 0.1357 -8.58376 12.8231 -944.483 0.326788 -0.760074 0.561692 -5.27779 23.3838 -984.829 0.796258 0.465554 -0.386307 --18.8863 -15.6249 -1031.68 -0.952819 -0.17933 -0.244903 --18.941 -14.575 -1033.29 -0.96852 -0.154215 -0.195412 -13.0376 -6.08901 -949.116 0.795747 -0.287757 0.5329 --18.8317 -13.8336 -1033.9 -0.906992 0.197234 -0.372107 -10.0837 24.8295 -934.98 0.504294 -0.724235 0.470289 -17.8395 -23.694 -1032.09 -0.0382183 0.8583 -0.511723 -10.6898 -15.2738 -959.583 0.300879 -0.839311 0.452802 -13.1193 -4.82591 -948.454 0.727054 -0.68597 -0.0289378 -10.1688 24.5899 -935.431 0.633329 -0.753035 0.178417 --29.4111 -43.0155 -965.727 -0.777437 0.326187 0.537768 -4.91152 24.2808 -985.675 0.784449 0.113171 -0.609781 --30.1231 -19.2736 -960.932 -0.900756 0.0779319 0.427277 --24.986 47.7605 -941.705 -0.961412 -0.133489 0.240556 --25.3605 50.239 -943.86 -0.992405 -0.115782 0.0415495 -13.2671 -4.7989 -948.87 0.812685 -0.399492 0.424205 -24.8298 -32.8093 -1012.71 0.836685 -0.440182 -0.32588 -9.82122 13.4376 -944.591 0.600628 -0.77929 0.178754 --0.475203 -32.8083 -1015.5 -0.080072 -0.927631 -0.364815 -10.3599 14.0669 -942.713 0.443046 -0.854001 0.27275 -10.8004 14.6748 -941.939 0.555032 -0.715447 0.424353 --25.0305 49.6467 -942.526 -0.422667 0.543364 0.725333 -13.737 -7.92211 -951.984 0.854955 -0.374356 0.359039 --24.0416 45.8287 -941.971 -0.805299 -0.587939 0.0762943 -10.9291 14.3847 -943.28 0.707523 -0.702656 0.0754042 --25.1671 49.1809 -942.307 -0.754785 0.296397 0.585192 -23.3956 -22.5743 -1010.59 0.5427 -0.748808 0.380477 --16.3737 -24.8611 -1031 -0.531643 0.12162 -0.838191 --24.3246 49.2522 -947.278 -0.60713 -0.60623 0.51369 -12.5666 -13.3191 -957.969 0.434026 -0.730181 0.52769 -10.4172 14.0795 -945.253 0.800933 -0.584904 0.12804 -23.8656 -31.8846 -1016.14 0.763566 -0.526228 -0.374233 -14.5408 -3.61802 -947.922 0.82281 -0.472171 0.316288 --11.6245 31.8779 -932.316 -0.288177 0.906737 0.307867 --11.8004 31.1868 -931.905 0.0247316 0.0334077 0.999136 -13.4296 -12.9552 -957.938 0.154347 -0.67244 0.723879 -18.8391 -47.5733 -956.639 0.182357 0.650486 0.737301 --7.79263 30.4714 -930.444 -0.247679 -0.34253 0.906272 --9.32705 30.4025 -931.117 -0.278431 -0.613746 0.738777 -14.7857 -3.441 -948.707 0.716967 -0.695157 -0.0521094 --11.6291 30.3632 -932.064 0.813105 0.0351776 0.581052 -13.7753 -10.9498 -956.186 0.560064 -0.650932 0.512462 --10.9109 32.2118 -931.016 -0.849503 0.214815 0.481871 --9.86312 32.4262 -929.689 -0.528733 -0.296779 0.795213 -14.3531 -8.40929 -954.232 0.816441 -0.414841 0.401661 -24.432 -31.5737 -1015.1 0.909865 -0.261551 -0.322082 --10.0629 29.3733 -932.134 -0.381158 -0.298694 0.874929 -19.5039 -51.5261 -956.505 0.0391138 -0.992022 -0.119846 -14.4315 -9.08438 -955.032 0.658177 -0.494849 0.567387 -24.6252 -20.4168 -1008.4 0.617572 -0.664152 0.421316 -12.1584 15.9739 -944.299 0.787919 -0.614095 -0.0455081 -10.467 36.3382 -940.076 0.668535 -0.312905 0.674649 -12.4176 26.2452 -937.343 0.635488 -0.764389 -0.108924 -20.4276 -36.7828 -962.808 0.520069 -0.0866824 0.849714 -16.1784 46.9885 -946.83 0.87685 0.156165 -0.454694 -23.7602 -44.3469 -962.891 0.584945 0.593642 0.552656 -15.3798 -2.28773 -950.514 0.523732 -0.847358 0.0876854 -15.0935 -9.89207 -955.959 0.226555 -0.549079 0.804478 -15.1789 -7.47929 -954.632 0.496623 -0.396965 0.771871 -15.4155 -2.42051 -951.003 0.729551 -0.570471 0.377251 -15.8972 -2.0978 -949.737 0.683445 -0.728668 0.0441087 -4.41482 14.2417 -1002.7 0.819854 0.0887379 -0.565655 -20.2801 24.3693 -969.221 0.367843 0.620506 -0.692577 -4.26435 14.1651 -1003.22 0.97861 0.154731 0.135578 -20.076 -30.705 -961.423 0.439298 -0.168882 0.882324 --18.4468 57.18 -959.026 -0.561787 0.803707 -0.196087 --19.0515 56.9522 -958.508 -0.311059 0.930935 0.191318 --15.8611 -18.3365 -1034.2 -0.707386 -0.591276 -0.387295 --18.5405 -15.0584 -983.114 -0.427039 -0.904035 0.0189367 -1.07292 37.804 -935.59 0.419137 -0.602579 0.679134 --21.2925 21.7729 -983.22 -0.469978 -0.342021 -0.813721 -22.7702 -30.8638 -1019.69 0.757587 -0.537784 -0.369933 -12.1992 16.5171 -946.471 0.833705 -0.552014 0.0147132 -5.6499 19.2967 -991.496 0.762375 0.647135 0.000630757 -12.3338 16.4479 -947.743 0.842779 -0.492231 0.21779 -23.4501 -30.6243 -1018.4 0.883981 -0.326103 -0.335013 --14.04 -11.6005 -1031.59 -0.229849 0.901503 -0.366692 -16.6875 -4.02775 -953.722 0.204479 -0.666392 0.717014 --14.3273 -11.274 -1030.96 -0.587931 0.638376 -0.496802 -20.892 -26.3984 -961.01 0.598841 -0.128254 0.790532 --12.9143 15.6325 -995.778 -0.875964 0.405354 -0.261485 --13.0143 15.6687 -996.966 -0.934621 0.0821389 0.346031 -24.7896 -44.6012 -963.821 0.662698 0.617661 0.423469 --21.6098 -12.6777 -982.406 -0.741734 -0.624897 -0.243587 -13.2251 16.4676 -950.783 0.910191 -0.305238 0.27997 -18.8618 -13.8925 -957.939 0.0685353 -0.694056 0.716651 -21.9615 -28.8369 -962.574 0.797316 -0.11566 0.592377 -21.3143 11.6957 -958.223 0.98558 0.0885342 0.144202 -19.2457 -12.9477 -979.997 0.273961 -0.485883 -0.829977 -19.8069 -9.34585 -955.214 0.154825 -0.319302 0.93492 --2.36275 38.6526 -933.176 0.0263192 -0.734 0.678639 -12.1765 -39.5219 -964.064 -0.835485 0.0472514 0.547479 -19.6558 -15.411 -960.187 0.376321 -0.547658 0.747297 --32.2184 -28.2621 -1017.28 -0.966441 0.237423 -0.0980886 -16.0595 19.7007 -976.945 0.762975 0.073678 -0.642215 -20.9046 -10.085 -955.78 0.348883 -0.384371 0.854716 -20.7252 -12.3457 -957.024 0.233219 -0.564147 0.792053 -20.9413 -13.383 -958.056 0.354249 -0.709998 0.608614 --11.6077 -18.7661 -1036.38 0.0566594 1.44279e-005 -0.998394 -21.2065 -15.041 -960.835 0.47935 -0.72952 0.487877 -20.9638 16.3862 -964.018 0.939831 0.259671 0.22201 -21.5282 -6.43706 -955.327 0.370068 -0.219492 0.902703 -22.876 -44.5937 -961.838 0.43701 0.733162 0.521051 -21.1347 -5.84667 -954.862 0.162697 -0.771164 0.615497 -22.4228 -6.00431 -953.215 -0.0955908 -0.990065 -0.10312 -19.0976 23.272 -972.889 0.966541 0.0973333 0.23733 -21.9482 -11.2681 -956.992 0.525033 -0.459576 0.716331 -22.4944 -5.96664 -952.718 0.0404944 -0.936104 0.349385 -25.5278 -20.3688 -1010.16 0.821225 -0.513685 0.248428 -20.4752 19.5618 -971.226 0.277522 -0.108618 -0.95456 -22.7105 -5.0426 -951.586 0.265454 -0.527048 0.807313 --17.2268 -21.1888 -1030.17 -0.665612 -0.255869 -0.701065 --13.7032 34.3887 -937.289 -0.32488 0.145084 0.934561 -22.1837 -12.8023 -958.45 0.5941 -0.587714 0.549215 -21.9738 -5.60878 -954.581 0.197732 -0.978989 0.0498205 --28.9605 -26.4767 -1028.36 -0.888635 -0.27139 -0.369697 --31.0729 -46.7518 -956.264 -0.962559 0.268915 -0.0341325 --18.3324 -21.1014 -1029.37 -0.464844 -0.152252 -0.872204 --27.5966 -23.5931 -1033.67 -0.840725 0.27076 -0.468904 -23.736 -5.51078 -952.66 0.495743 -0.753368 0.43206 -21.8822 16.8532 -964.5 0.258018 -0.429311 0.865516 -21.2809 14.7897 -961.953 0.989408 0.0610761 -0.131688 -23.6864 -5.70003 -953.59 0.341056 -0.924456 -0.170478 --29.7973 -43.6263 -961.078 -0.847609 0.499554 0.178897 -21.393 12.9284 -960.174 0.998898 -0.00816453 -0.0462282 -23.3201 -12.3663 -959.503 0.677225 -0.584913 0.446366 -23.2883 -11.7469 -958.752 0.736105 -0.459866 0.496661 -23.2727 -10.2946 -957.631 0.723573 -0.352433 0.593492 -21.2923 11.7718 -960.199 0.999788 0.0205256 0.00146822 --26.3465 -34.0716 -967.864 -0.695753 -0.715275 -0.065646 -21.7409 21.0646 -970.974 0.791564 0.329471 -0.514661 -0.200993 49.6854 -970.903 0.341268 0.752329 -0.563505 -22.1491 18.9125 -971.116 0.321662 -0.0553306 -0.945236 -23.7494 -14.6917 -963.505 0.766548 -0.407513 0.496324 -15.6654 20.1915 -957.37 0.896261 -0.443245 0.0158208 -16.3229 21.317 -954.243 0.781719 -0.62178 0.0480075 --10.8368 55.6826 -962.824 0.351331 0.660742 -0.663315 -25.1791 -21.6856 -1012.45 0.769109 -0.613279 0.179889 -16.4539 20.0506 -976.75 0.432131 -0.450216 -0.781389 -24.4183 -11.2929 -960.481 0.829266 -0.394029 0.396307 -22.6052 15.8754 -968.073 0.772662 -0.580115 -0.257797 -17.0253 29.5017 -949.208 0.111278 -0.632863 0.766226 --25.4953 33.4111 -952.136 -0.961091 0.137373 -0.239651 -23.3349 16.5624 -966.719 0.907104 -0.420349 -0.0216731 -21.3675 14.295 -967.923 0.946755 -0.319123 0.0426102 -16.6362 21.7119 -955.678 0.822599 -0.56638 -0.050451 --31.4374 -40.5595 -967.987 -0.902444 0.336566 0.26892 --7.98527 25.2758 -929.319 0.00386287 -0.605879 0.795548 -24.6754 -14.0605 -964.509 0.847946 -0.339808 0.406839 -18.6936 22.4247 -977.398 0.789324 -0.31326 -0.52805 --18.8575 1.1534 -1015.06 -0.0907817 0.72241 -0.685479 -21.4522 20.6984 -971.226 0.319938 0.225981 -0.920093 -23.3515 18.4367 -969.493 0.918466 0.122864 -0.375931 --18.7261 -26.1295 -1031.02 0.190806 -0.101995 -0.976315 -23.1041 17.7408 -969.772 0.850687 -0.390037 -0.352424 -22.8906 16.2424 -965.441 0.676279 -0.648577 0.349279 -25.7612 -15.6599 -969.483 0.917025 -0.366951 -0.156244 --16.6473 -21.9306 -1001.59 -0.4453 -0.829287 0.337626 -13.3481 -20.0159 -997.517 0.561201 -0.755042 0.339066 -19.2725 22.8569 -973.568 0.993921 0.0908834 0.0621394 -14.7644 -18.2672 -996.103 0.60285 -0.732396 0.316493 -13.0991 -22.0392 -1001.92 0.674763 -0.71835 0.169315 -16.7356 18.5821 -975.991 0.906412 0.157129 -0.392082 -18.8258 18.7388 -971.069 0.382926 -0.31834 -0.867195 -19.6203 21.0811 -971.721 0.711114 0.265141 -0.651166 --18.8974 -35.4089 -947.935 0.458016 0.0818136 0.885171 -23.5797 -25.116 -1018.87 0.82732 -0.537807 0.162187 -14.4169 -19.7805 -999.089 0.678207 -0.683242 0.270585 --12.3173 -25.7104 -1034.01 -0.420088 -0.467519 -0.777787 -18.0417 -12.4792 -988.325 0.741593 -0.663576 0.0985203 -4.06896 16.0271 -1003.57 0.188131 0.926296 -0.326471 -21.297 15.5407 -964.893 0.572392 -0.487548 0.659291 -20.8057 14.5699 -965.034 0.963558 -0.149352 0.221924 -21.0199 15.5247 -964.397 0.915299 -0.242793 0.32137 --19.1052 21.4624 -943.43 -0.427404 0.630526 0.647891 -23.5025 -25.8335 -1020.42 0.953665 -0.261384 0.148998 --30.8748 -13.8316 -972.675 -0.9952 -0.0307374 0.0929095 -21.4115 14.8491 -968.696 0.838569 -0.446318 -0.312413 -19.4082 21.423 -972.029 0.992052 -0.0053803 -0.125717 --12.729 -19.265 -1036.36 -0.160234 -0.214648 -0.963458 -3.01975 -19.3797 -1034.54 0.29712 -0.255029 -0.920152 -15.2103 -19.913 -1001.18 0.700824 -0.66136 0.267298 -18.5593 21.4774 -976.704 0.783115 -0.493649 -0.378208 -18.7328 20.0926 -972.02 0.275619 -0.279345 -0.919783 -19.3212 21.0327 -972.071 0.695686 -0.319806 -0.64323 -15.9912 -18.5624 -1000.71 0.645618 -0.672461 0.361904 -17.1727 -16.1746 -997.212 0.757565 -0.612794 0.224896 -20.8101 16.8189 -970.69 0.242437 -0.112181 -0.96366 --16.0326 -25.9938 -1031.15 -0.332734 -0.129021 -0.934153 -23.1346 17.0069 -968.612 0.892883 -0.395511 -0.215245 --20.0942 7.45712 -1001.39 -0.507323 0.450154 -0.734837 -26.3825 -47.2697 -968.86 0.784842 -0.550887 -0.283806 -19.5907 21.6983 -973.864 0.9776 -0.166983 -0.12812 -17.7995 18.9216 -971.863 0.733213 -0.194312 -0.651645 -20.5972 15.0454 -970.426 0.925096 0.183475 -0.332467 -0.144945 -17.6324 -950.656 0.671739 -0.723089 -0.160962 --15.4156 -37.2394 -951.193 0.948892 -0.309478 -0.0618631 -17.0644 -17.1884 -999.787 0.680463 -0.662051 0.314099 --28.2198 -25.3288 -1031.18 -0.93985 -0.121581 -0.319219 --17.503 -51.7279 -954.407 0.788318 -0.589102 0.177522 -21.382 14.7043 -966.187 0.756494 -0.569938 0.32076 -22.7926 15.7513 -966.593 0.754049 -0.656811 -0.00309593 -18.3433 -14.3941 -997.723 0.880046 -0.414879 0.231073 -20.7985 15.4983 -970.157 0.671303 -0.310283 -0.67311 --15.9329 -46.5246 -971.797 0.349727 -0.88732 -0.30059 -17.3601 -19.5661 -1003.36 0.0886664 -0.784267 0.614055 -17.9512 -15.7723 -999.104 0.747427 -0.556745 0.362475 -16.929 19.3078 -975.791 0.792827 -0.341597 -0.504715 --5.82893 40.2891 -931.49 -0.451273 -0.44529 0.773349 -18.5578 -18.5473 -1002.48 0.20752 -0.691096 0.692331 -18.8077 -14.2573 -998.631 0.738731 -0.480565 0.472581 -11.2254 0.134663 -1016.12 0.127805 0.714753 -0.6876 -19.1545 -14.2327 -998.992 0.539154 -0.505414 0.673698 --21.5749 -35.799 -946.332 -0.246127 0.162918 0.955447 -19.2536 -16.8611 -1001.26 0.33626 -0.593843 0.730944 -19.6711 -19.3593 -1003.35 0.158609 -0.673939 0.72156 -19.982 -10.0616 -997.277 0.700053 -0.241441 0.672036 --25.2126 -37.5443 -946.171 0.217631 0.0529119 0.974596 --21.3092 -37.628 -999.132 0.112549 -0.581286 0.805878 -19.0509 22.5819 -976.211 0.918931 -0.272626 -0.285026 -20.693 -9.3893 -997.686 0.534037 -0.124623 0.836226 -20.1926 -20.665 -1004.88 0.142806 -0.784143 0.603925 -20.7677 -21.567 -1006.45 0.304392 -0.797439 0.520995 -21.1554 -20.0015 -1004.46 0.338309 -0.693845 0.635709 -21.0453 16.6823 -964.289 0.54486 -0.145806 0.825753 -21.1691 -13.1019 -999.479 0.486396 -0.44613 0.751257 -10.8371 -13.4202 -1034.09 0.747062 0.343287 -0.569256 --4.17169 -18.4871 -947.747 -0.796277 -0.534233 -0.283792 -17.5206 19.4058 -974.356 0.821842 -0.50798 -0.257939 -20.8212 -28.9756 -1026.06 0.48234 -0.771443 -0.414999 --2.6773 -12.7519 -940.556 -0.088877 -0.153813 0.984095 -22.3287 -10.5268 -999.006 0.563976 -0.270669 0.780172 -22.6215 -19.6955 -1005.14 0.528145 -0.641991 0.555797 -22.3241 -18.9082 -1004.11 0.429429 -0.570132 0.700386 --21.7573 15.0366 -977.092 -0.791861 0.174703 -0.585179 --25.599 -36.0423 -968.977 -0.977614 0.210218 0.00890294 --27.7191 6.91688 -954.153 -0.967605 0.0162308 0.251948 -22.681 -9.05343 -998.902 0.640923 -0.0763882 0.763795 --22.118 -13.6117 -958.326 0.0580981 0.272041 0.96053 --9.08557 35.7834 -936.468 0.0485043 -0.0107367 0.998765 -22.7132 -20.5428 -1006.43 0.446827 -0.754725 0.480349 -12.6733 13.0695 -995.947 0.787549 0.611306 -0.0779191 --17.7923 -15.6668 -1034.68 -0.598946 -0.417932 -0.683079 --26.9603 -1.50153 -953.298 -0.892187 0.22233 -0.393156 --28.9927 17.0235 -972.287 -0.924848 -0.380169 0.0113054 -23.3969 -10.2968 -999.855 0.681327 -0.242836 0.690525 -24.0053 -18.6601 -1005.44 0.656679 -0.509486 0.556055 -1.96343 42.6319 -976.841 -0.596452 0.140142 -0.79032 --27.5998 5.40976 -954.655 -0.98584 -0.0521464 0.159373 -24.5687 -15.8214 -1003.96 0.780736 -0.356308 0.513319 --18.5353 -35.6752 -947.981 -0.0424123 0.283828 0.957937 --27.7428 11.5819 -958.851 -0.972916 0.224152 -0.056478 -24.6057 -19.4344 -1007.06 0.75227 -0.485627 0.445259 -25.4276 -16.9072 -1006.65 0.872266 -0.308328 0.379586 --21.385 -52.4284 -952.269 0.0322002 -0.864813 0.501061 --19.7413 -51.8706 -951.583 0.175618 -0.531567 0.82861 --18.8713 -52.3847 -953 0.361295 -0.909699 0.204726 --18.8184 -51.573 -951.881 0.699553 -0.307438 0.645064 --19.9884 -46.2884 -950.342 0.538578 -0.412177 0.734877 --17.8021 -50.9762 -953.259 0.893602 -0.0887808 0.439992 --29.0095 -30.9461 -954.69 -0.42303 0.828661 0.366562 --30.3246 15.8865 -967.575 -0.911514 0.222631 -0.345801 --17.1565 -51.0745 -955.145 0.942857 -0.257813 0.211076 --23.4861 17.3242 -977.274 -0.250778 -0.492347 -0.83349 --16.7836 -39.4465 -946.508 0.200571 -0.51992 0.830334 --16.3257 -40.8678 -948.556 0.698312 -0.702181 0.138929 --15.8308 -39.8307 -947.62 0.559001 -0.623865 0.546178 --18.7851 -41.4221 -953.021 0.933261 -0.347479 -0.0910062 --27.8334 9.12644 -955.715 -0.903813 0.265746 0.335412 --15.4312 -39.5467 -948.204 0.928797 -0.327489 0.173456 --17.6613 -40.1243 -952.397 0.683041 -0.601107 -0.41488 --18.2992 -40.4015 -953.565 0.861612 -0.469839 -0.192029 --15.9369 -39.8002 -950.871 0.769595 -0.471754 -0.430315 --15.5677 -39.7164 -950.109 0.832936 -0.522907 -0.181066 --26.2918 -36.0008 -946.821 -0.275739 0.267706 0.923202 --18.2209 -39.4105 -955.229 0.678869 -0.734044 -0.0177693 --15.1365 -37.0309 -948.107 0.934369 0.0266839 0.355306 --16.1556 -38.2734 -952.681 0.686517 -0.716521 -0.123658 --15.9703 -38.4904 -951.861 0.801899 -0.519327 -0.295393 --17.8536 -39.4534 -956.445 0.641673 -0.756302 0.127528 --15.4643 -37.5844 -951.956 0.839865 -0.538903 0.0648908 --27.4907 12.8408 -961.786 -0.598569 -0.259132 0.758001 --27.5902 12.2108 -962.408 -0.452835 -0.697445 0.555438 --17.2015 -48.6858 -964.402 0.76168 -0.640458 0.0982708 --17.204 -45.8866 -962.191 0.95085 0.110744 0.28917 --16.3058 -38.7473 -955.689 0.55474 -0.831584 -0.0270562 --16.6862 -38.6205 -957.336 0.713016 -0.657268 -0.244147 --14.7963 -36.1126 -951.621 0.940612 -0.298721 0.161291 --15.1188 -37.7295 -954.048 0.770884 -0.636789 0.015379 --31.0538 14.283 -964.539 -0.84811 -0.519001 0.106524 --16.7728 -46.6291 -963.734 0.93034 -0.0360077 0.364927 --15.9043 -37.9545 -956.932 0.760123 -0.578586 -0.295723 --16.2239 -48.0999 -965.246 0.746212 -0.620844 0.240251 --24.67 -0.589861 -950.133 -0.511269 0.397295 0.762077 --15.5977 -27.2319 -1030.88 -0.372771 -0.308682 -0.875076 --16.2609 -36.3481 -960.334 0.751946 -0.485327 -0.446134 --15.1691 -36.7207 -956.994 0.85567 -0.426924 -0.292514 --15.5786 -47.6909 -966.951 0.829611 -0.554842 0.062423 -13.7615 42.8377 -973.704 0.684838 -0.0936088 -0.722658 --27.1593 12.7216 -961.251 -0.965446 0.0315395 0.258689 --15.4743 -35.9903 -958.988 0.873389 -0.381541 -0.302685 -8.30364 31.9256 -979.76 0.46699 0.34242 -0.815273 --15.2197 -46.1834 -966.483 0.901985 -0.148306 0.405498 --15.0186 -46.5435 -967.913 0.969312 -0.24575 0.0064532 --27.802 14.0713 -969.248 -0.394831 -0.528909 -0.751241 -2.33728 42.6124 -977.08 -0.222297 0.308259 -0.924965 --14.9365 -45.152 -968.584 0.995052 -0.0145345 -0.0982846 --14.8948 -44.1025 -967.359 0.979391 0.0538851 0.19465 --15.2852 -46.1876 -970.507 0.974165 -0.149091 -0.16963 --27.0783 4.82869 -952.841 -0.88204 -0.0565208 0.467772 --15.6371 -44.3388 -974.459 0.995818 -0.0913151 -0.00290872 -13.3798 9.81345 -947.699 0.784121 0.414671 0.461738 --27.1304 10.644 -960.197 -0.990666 0.0995875 -0.0930727 --15.9819 -17.0569 -961.737 0.380317 -0.760568 0.526208 --30.3649 14.4831 -967.447 -0.893744 -0.190473 -0.40613 --30.1691 -44.8323 -953.497 -0.922275 0.352224 0.15921 --26.2321 2.18103 -953.574 -0.885103 -0.253836 0.390077 --15.418 -43.1511 -979.85 0.899009 -0.416861 -0.1342 --16.3149 39.9082 -934.711 -0.0394619 -0.783967 0.619547 --31.3953 14.9465 -965.018 -0.947246 -0.295344 -0.12449 --16.279 -17.3112 -1034.76 -0.654044 -0.458054 -0.602007 --15.0207 -41.7687 -979.361 0.987083 -0.154988 -0.0405728 --14.9728 -41.0619 -978.646 0.998485 -0.0132319 0.0534149 --15.611 -43.0458 -980.843 0.724811 -0.586359 -0.361706 --30.3257 -44.2199 -962.114 -0.900964 0.433893 -0.00133603 --14.067 -16.8126 -962.781 0.276035 -0.933971 0.226942 --14.2257 -17.0955 -964.03 0.4158 -0.789521 0.451406 --0.587918 -20.0771 -943.841 0.229659 -0.938632 0.257346 --26.7405 11.0425 -966.84 -0.77557 -0.388072 -0.497887 --21.2588 -32.6699 -947.572 -0.180063 0.653344 0.735336 -0.0993762 -19.7426 -943.537 0.511014 -0.819138 0.260533 -0.288175 -19.198 -942.847 0.519095 -0.660129 0.542927 -19.1696 -37.24 -962.281 0.381655 -0.142613 0.913237 -0.811134 -19.281 -944.551 0.804514 -0.574067 0.152327 --24.4902 -37.4146 -998.653 0.0479546 -0.44038 0.89653 --24.7654 -36.7598 -998.525 0.101874 -0.0269056 0.994433 -0.840761 -17.0694 -942.622 0.778832 -0.00566007 0.627207 --13.3474 -20.9594 -1035.25 -0.655443 -0.343005 -0.672862 -0.533277 -19.6999 -946.591 0.662903 -0.742893 -0.0931095 --23.3914 -37.8505 -999.351 0.0570403 -0.921898 0.38321 -1.16736 -17.5765 -943.191 0.933144 -0.142546 0.330034 --0.52148 -19.5252 -949.539 0.361752 -0.870427 -0.333906 --0.150067 -19.3952 -949.319 0.6352 -0.653468 -0.411703 -0.503286 -18.7758 -948.954 0.836564 -0.437465 -0.329824 -0.661022 -10.8314 -943.479 0.369107 -0.813235 0.449899 --27.8763 10.7909 -958.236 -0.997721 0.049009 -0.0463813 -1.3266 -14.0681 -945.147 0.52683 -0.541238 0.655371 -1.28294 -9.97389 -941.589 0.18303 -0.56793 0.802468 --28.3924 -36.4621 -948.557 0.264858 0.234262 0.935399 --20.7415 -37.6681 -1000.36 0.119154 -0.971658 -0.204164 -2.1362 -10.9043 -944.149 0.279449 -0.514601 0.810614 --26.4527 10.3804 -967.818 -0.831801 0.487453 -0.265512 --19.6535 -37.1319 -999.335 0.565259 -0.287678 0.773125 --24.1857 13.2486 -971.902 -0.862968 -0.367662 -0.346569 -2.85526 -14.1294 -946.335 0.413697 -0.764232 0.494777 -3.26324 -10.1523 -942.824 0.283347 -0.883327 0.373427 --22.7914 15.0605 -976.185 -0.356326 -0.331257 -0.873671 -1.8757 -17.0365 -951.497 0.331755 -0.92794 0.169899 -3.12229 -10.4155 -943.988 0.264335 -0.784651 0.560758 -13.5904 -0.034092 -1016.59 -0.174579 0.893659 -0.413396 -2.41403 -16.2305 -949.791 0.387821 -0.855419 0.343297 --14.6005 -20.4168 -1033.72 -0.803222 -0.420266 -0.42215 --28.4433 15.6887 -969.728 -0.637757 -0.329464 -0.696218 --30.1456 13.1863 -964.273 -0.72811 -0.666145 0.161577 --14.4574 -16.5573 -982.293 -0.29118 -0.95469 0.0614929 --27.2972 15.6312 -973.735 -0.488651 -0.787155 -0.376308 -3.69708 -16.6143 -952.304 0.336146 -0.914156 0.226549 --25.2806 13.1579 -969.944 -0.5941 -0.567076 -0.570499 -4.20385 -15.5199 -949.766 0.360156 -0.83111 0.423727 --28.7939 13.2151 -961.704 -0.263201 -0.56138 0.784587 -5.65898 -9.25593 -942.951 0.408321 -0.701642 0.583929 --27.2002 10.4109 -960.944 -0.924204 0.377418 0.058325 --27.5364 9.69517 -958.845 -0.983354 0.0516691 -0.174197 -5.59589 -12.4551 -946.12 0.424447 -0.650986 0.629335 -18.5147 36.0118 -963.075 0.318497 0.202312 -0.926083 -5.4015 -13.8178 -947.699 0.41979 -0.772835 0.475923 -5.56182 -12.0306 -945.797 0.369834 -0.481611 0.794527 -16.6365 -36.7233 -961.692 0.00501487 -0.175301 0.984502 --28.3476 16.5824 -970.447 -0.975202 -0.216737 0.0447809 -5.16862 -15.569 -950.843 0.406239 -0.845792 0.345841 --23.9584 12.7269 -972.633 -0.942758 0.216093 -0.253991 -21.278 -14.7693 -979.276 0.241336 -0.046928 -0.969306 --27.3129 11.125 -965.741 -0.750039 -0.571555 -0.332816 -7.34174 -9.39685 -945.121 0.425789 -0.751559 0.503848 --11.656 19.9366 -991.166 -0.124137 0.932094 -0.34028 -7.72636 -9.57591 -945.534 0.516113 -0.511297 0.68717 -7.65317 -8.83567 -944.115 0.504902 -0.768395 0.393247 --30.3346 13.878 -966.947 -0.813938 -0.481749 -0.324687 --17.8931 -19.3997 -995.82 -0.485914 -0.81316 0.320404 -6.59197 -15.6544 -953.233 0.431957 -0.873167 0.225815 -7.03293 -12.9466 -947.855 0.495914 -0.706114 0.505443 --30.7936 -25.3991 -1021.89 -0.934712 0.355312 -0.00818757 --29.5687 13.5189 -967.732 -0.548038 -0.646329 -0.530955 -20.4007 -13.8316 -979.595 0.203478 -0.00238092 -0.979077 -7.08064 -14.8975 -951.77 0.492457 -0.818535 0.29578 -8.38409 -8.07701 -943.816 0.49931 -0.611117 0.614187 --28.3202 -44.3131 -950.115 -0.524497 0.165179 0.835236 -8.6056 -8.65061 -945.359 0.589067 -0.735699 0.334288 --29.2059 12.3811 -964.168 -0.595517 -0.797253 0.0987261 --17.4003 -20.4893 -998.038 -0.453755 -0.844201 0.285362 --26.1999 11.5848 -967.904 -0.766614 -0.290491 -0.57264 --27.191 12.0358 -967.486 -0.51857 -0.666014 -0.536201 --25.5824 -0.280637 -951.804 -0.738129 0.587438 0.331786 --25.1959 14.8416 -974.165 -0.47333 -0.790245 -0.389195 --27.2562 10.7457 -963.56 -0.933802 0.112804 0.339541 --29.6384 12.7964 -966.189 -0.636675 -0.749062 -0.183171 --1.6278 7.8433 -1013.58 0.239969 0.842681 -0.481979 --27.7052 15.5774 -972.783 -0.599075 -0.789807 -0.131581 --15.8511 -33.9654 -1009.43 0.708894 -0.61628 0.343028 --29.2649 12.8438 -962.682 -0.544183 -0.748722 0.378524 --28.3283 12.7501 -967.732 -0.422779 -0.731346 -0.535155 --16.1936 -23.925 -1004.87 -0.458373 -0.783854 0.418888 --5.14308 8.5455 -1014.15 -0.094525 0.748149 -0.656763 --17.722 -37.8456 -960.82 0.836484 -0.345717 -0.425176 --16.5083 -24.6349 -1006.9 -0.41306 -0.824691 0.386349 -22.2359 -51.2913 -956.74 0.1921 -0.98117 -0.0200945 -22.0654 -51.2502 -956.181 0.488394 -0.666469 0.563285 --15.0329 -32.6124 -1009.71 0.486413 -0.318459 0.813625 --27.3206 15.0757 -970.538 -0.654704 -0.714999 -0.245234 --14.5625 -33.8734 -1010.79 0.389101 -0.766898 0.51036 --27.4239 11.1519 -964.901 -0.798179 -0.602366 -0.00807134 --25.538 0.362284 -952.836 -0.929712 0.0382954 0.36629 --3.52129 8.77784 -1013.76 0.239026 0.725441 -0.645447 --27.3684 11.2931 -963.645 -0.888801 -0.380825 0.254962 -9.01005 -15.4957 -958.203 0.398418 -0.895008 0.200556 --13.8624 -33.4225 -1010.55 0.0613514 -0.712806 0.698673 --13.8864 -32.0631 -1009.75 -0.0027284 -0.364598 0.931161 --10.7592 -23.9501 -999.59 -0.336446 -0.818055 0.466466 --8.65519 -22.9026 -996.394 -0.247897 -0.847141 0.469999 --11.0864 -25.9714 -1002.71 -0.432714 -0.663323 0.610541 -23.5454 -50.7477 -957.759 0.564648 -0.542723 0.621791 --26.0322 32.2481 -953.903 -0.315129 -0.4883 0.813792 -10.2744 38.0091 -979.818 0.115854 0.691923 -0.712615 --12.2946 1.83847 -1023.13 -0.761299 0.624063 -0.175978 -22.6857 -42.3606 -963.687 0.529491 0.390326 0.753183 -24.2539 -50.4698 -957.939 0.275918 -0.281836 0.918933 --6.11594 21.7602 -987.604 -0.894729 0.359095 -0.26554 -19.6476 -43.4579 -961.437 0.248648 0.557474 0.792084 --12.2312 40.4681 -933.58 -0.0922932 -0.435046 0.895665 -16.1003 0.541701 -1016.26 -0.0807139 0.968123 -0.237114 -19.728 -30.6905 -1000.47 -0.0468299 0.810957 0.583228 -19.7178 -30.6873 -1000.48 -0.232727 0.937949 0.25708 --14.7645 36.7749 -981.631 -0.334293 0.327942 -0.883574 -25.7767 -50.0571 -958.166 0.454636 -0.0551128 0.888971 --8.90465 9.55554 -1012.47 0.138849 0.75201 -0.644362 --9.64349 -1.54318 -1029.52 -0.919226 0.379747 -0.104002 -18.9773 33.2499 -972.544 0.868136 0.262696 -0.421107 -26.0374 -50.3435 -958.4 0.586383 -0.355153 0.728026 --9.81451 2.90259 -1020.82 -0.200265 0.81847 -0.538517 --31.7533 -27.0748 -1018.35 -0.906141 0.421404 -0.0364346 --30.9429 -42.7668 -966.853 -0.428097 0.154771 0.890381 --22.8401 -1.53504 -1023.63 0.12263 0.903918 -0.409748 --21.2997 -1.8059 -1022.91 0.346796 0.882767 -0.316946 --2.33833 -23.0581 -994.533 -0.0157499 -0.8547 0.518883 -26.8858 -50.1365 -959.334 0.911156 -0.327474 0.250112 --25.4613 -35.2231 -971.499 -0.991355 0.0768314 0.106359 --17.7353 -3.11757 -1022.47 0.249768 0.909845 -0.331358 --10.4037 -2.47514 -1029.51 -0.329643 0.887298 -0.322549 --21.4242 -12.3564 -958.617 -0.212664 -0.018412 0.976952 --7.52331 3.83639 -1021.05 -0.968305 0.141872 0.205567 --8.04646 3.33851 -1022.55 -0.914294 0.294132 0.278484 -27.1646 -49.0115 -961.898 0.903019 -0.424336 -0.0670453 --10.4955 12.8442 -1006.06 0.329128 0.813533 -0.479415 --1.48408 -33.8289 -1005.7 0.120139 -0.74701 0.653867 --11.5258 4.63145 -1020.42 -0.167334 -0.158967 -0.973 --7.74506 2.99057 -1021.08 -0.823464 0.563621 -0.0651064 -27.0189 -48.4223 -964.57 0.932462 -0.300629 -0.200342 --29.0576 21.1501 -962.18 -0.553784 -0.832646 -0.00493694 --5.96998 23.3315 -987.357 -0.898346 0.389023 -0.204048 -2.48167 -21.015 -991.359 0.147028 -0.935897 0.320124 --11.1903 -2.35317 -1029.16 0.149483 0.945391 -0.28964 -9.77241 42.4029 -973.898 -0.27271 -0.204738 -0.940059 -1.36536 -22.2556 -993.687 0.149136 -0.863873 0.481125 --19.6567 -2.93093 -1025.04 0.132548 0.887182 -0.441971 --11.032 1.11811 -1019.37 -0.867545 0.158395 -0.471463 -26.5842 -47.8404 -966.528 0.940259 -0.28393 -0.187875 --8.87971 2.37457 -1023.51 -0.55834 0.752246 -0.349832 -0.874513 -28.0364 -1001 0.1358 -0.683999 0.716731 -1.66489 -24.9836 -997.776 0.111937 -0.804664 0.583083 --15.1983 -2.94155 -1025.44 -0.343614 0.8165 0.463958 -0.757485 -34.2769 -1007.1 0.254168 -0.791805 0.555378 --10.5549 2.25292 -1023.83 0.0333896 0.654368 -0.755439 -0.548199 -32.7691 -1005.24 0.256316 -0.689022 0.677901 --27.6796 -40.6091 -951.706 -0.91053 -0.149432 0.385493 --10.1804 3.51312 -1020.23 -0.312617 0.499362 -0.808028 --10.9208 3.51319 -1020.04 -0.129233 0.0187165 -0.991438 --10.2046 2.75022 -1020.72 -0.668014 0.414881 -0.617763 --9.40764 -1.79206 -1028.13 -0.718222 0.691734 -0.0752464 --12.0877 1.69946 -1023.5 -0.520233 -0.0803678 -0.850235 --9.3809 1.55125 -1024.93 -0.97896 0.20393 -0.00711486 -1.72249 -31.0743 -1004.14 0.346051 -0.665711 0.661118 --12.3737 4.74876 -1020.18 -0.379553 -0.0746219 -0.922156 --30.4725 -24.3935 -1023.2 -0.986868 0.161192 -0.0104539 -3.81481 -24.9503 -998.303 0.190876 -0.764973 0.615129 -3.77083 -23.353 -996.148 0.178754 -0.816335 0.549221 --1.81444 15.2359 -1002.45 0.364362 0.765611 -0.530169 -7.01752 -19.8445 -990.333 0.239344 -0.926073 0.291726 -0.460215 19.0162 -995.122 0.150136 0.884896 -0.440929 --12.1987 -2.67058 -1022.33 -0.297673 0.893734 -0.335605 -8.27889 35.7245 -938.965 0.334344 -0.461574 0.821684 --14.221 -2.42522 -1021.66 -0.08243 0.879536 -0.468638 --16.6808 -3.76267 -1025.65 -0.198393 0.979861 0.0226437 --11.415 18.0633 -996.749 0.387838 0.616224 -0.685456 --28.6295 41.2046 -964.041 -0.616997 0.770462 0.160324 -5.51153 -26.1468 -1000.53 0.336802 -0.763482 0.551053 --12.7991 1.552 -1018.05 -0.58082 -0.24833 -0.775229 --13.0443 5.59016 -1019.83 -0.701471 0.091169 -0.706843 -4.58634 -34.2154 -1008.99 0.197116 -0.862013 0.466989 --10.8222 2.55577 -1022.87 -0.251568 0.958101 -0.136951 --13.1712 3.4787 -1019.11 -0.576263 -0.359355 -0.73402 -7.52786 -21.4731 -994.618 0.226698 -0.874683 0.428413 --10.9627 -25.9816 -1034.34 -0.240456 -0.40503 -0.882118 -8.66442 35.2608 -939.078 0.302171 0.375042 0.876377 -5.04764 -34.5046 -1010.27 0.0460847 -0.987123 -0.153178 -20.5328 -42.0401 -962.481 0.423875 0.320094 0.847272 -7.79757 -22.8161 -997.034 0.276988 -0.809642 0.517453 --9.29683 -1.25981 -1024.29 -0.757144 0.224107 -0.613603 --29.781 -43.5464 -957.306 -0.927908 0.366591 -0.0678063 --18.071 -3.68467 -1026.14 0.00711833 0.992346 -0.123286 --18.4865 -3.14856 -1023.64 0.310985 0.927266 -0.208487 --16.8934 -3.72071 -1026.19 -0.376125 0.826108 0.419614 -9.77614 -20.1279 -993.508 0.367356 -0.838488 0.402477 --12.5375 -2.36501 -1021.56 -0.323121 0.777496 -0.53953 --30.0679 -29.5069 -960.295 -0.949278 0.198492 0.243868 --6.24239 -34.7343 -1007.98 -0.313074 -0.85383 0.415885 -24.4517 -28.3726 -972.427 0.824477 -0.49003 0.283034 --10.9359 -1.50365 -1022.95 -0.787872 -0.139063 -0.599932 -6.82376 -34.4413 -1010.49 0.0551463 -0.995284 0.0798 --10.405 -0.982561 -1023.54 -0.514932 -0.215976 -0.829578 -10.8973 -19.8825 -994.113 0.455105 -0.80443 0.3818 --11.7899 -0.762183 -1020.7 -0.932059 -0.240026 0.27139 -24.9025 -28.2562 -973.114 0.871037 -0.429749 0.237929 -7.17515 -34.1978 -1009.73 -0.0097561 -0.871038 0.491118 --9.67697 0.863298 -1024.01 -0.439327 0.0545311 -0.896671 -15.2572 -51.1745 -956.026 -0.571962 -0.400026 0.716127 -14.5717 -38.7358 -962.34 -0.32021 -0.0702017 0.944742 -12.9394 -39.3742 -963.31 -0.59926 -0.00448591 0.800542 --12.4571 -2.38236 -1025.49 -0.0534103 0.933367 0.354927 -12.6115 -36.9059 -963.28 -0.824505 -0.135813 0.549314 --23.702 25.6137 -972.993 0.00803879 -0.0219705 -0.999726 --12.6622 0.467531 -1022.78 -0.864582 -0.294315 -0.40728 -11.7319 -33.9739 -963.946 -0.892777 -0.215823 0.395436 --11.3057 0.357027 -1019.46 -0.905319 0.370649 0.207403 --11.6768 -1.40995 -1021.42 -0.891485 0.266038 -0.366712 --11.675 0.116501 -1020.13 -0.841987 -0.0752447 0.534224 --9.66751 -2.47793 -1025.34 -0.615064 0.788353 -0.014009 --30.6488 -25.3055 -1019.7 -0.829061 0.554604 0.0712192 --9.2391 1.9918 -1023.59 -0.129482 0.340271 -0.93137 -11.5316 -30.6634 -962.662 -0.807386 -0.214994 0.549459 -11.3067 -33.8186 -965.246 -0.957766 -0.228494 0.174568 -11.3542 -27.2604 -961.777 -0.706346 -0.143142 0.693243 --30.1475 -44.4056 -958.571 -0.908137 0.417824 0.0266612 -11.3825 -34.5141 -965.879 -0.981643 -0.141731 0.12763 --24.5008 25.8438 -972.94 -0.0966745 -0.132586 -0.986446 -10.8119 -26.8362 -962.385 -0.838964 -0.123382 0.530016 -18.2724 -8.4607 -954.874 -0.0450923 -0.294091 0.954713 --12.2928 -1.70593 -1027.29 0.145331 0.982781 0.11411 --20.9634 -47.202 -949.416 0.676051 -0.28292 0.680376 -11.5655 -34.6783 -969.901 -0.978085 -0.160996 -0.132022 --10.0719 -2.52631 -1025.56 -0.0951445 0.966631 0.23785 -10.3957 -15.7863 -1030.09 0.507747 -0.817018 -0.273266 -10.6206 -29.9768 -964.154 -0.915561 -0.209517 0.343294 --10.0636 -2.01162 -1026.9 -0.585885 0.795169 0.156352 --14.4351 34.9734 -937.598 -0.471535 -0.250198 0.845609 --22.8592 28.7389 -974.177 -0.539855 -0.397452 -0.742016 --9.33221 20.5528 -987.925 0.376032 0.79271 -0.479803 --1.9864 23.1144 -988.594 0.508309 0.765739 -0.394036 --10.7787 -2.36037 -1023.72 -0.591232 0.679397 -0.434586 -18.4724 -37.8416 -998.205 -0.0568432 -0.869529 0.4906 -10.1935 -26.4059 -963.409 -0.906877 -0.101322 0.409034 --10.0263 21.0585 -988.159 0.71346 0.506967 -0.483693 --21.7246 -38.2295 -945.868 -0.113405 0.00684479 0.993525 --14.541 -3.01938 -1023.45 -0.163884 0.97697 -0.136643 --12.7044 0.596055 -1021.58 -0.961939 -0.0663184 0.265096 --15.1086 -3.15897 -1024.47 -0.321436 0.926074 0.197649 -10.3504 -28.5542 -971.172 -0.944337 -0.220957 -0.243733 --2.33325 23.7701 -987.531 0.271649 0.84744 -0.456127 --10.9609 -23.1345 -1035.16 -0.182898 -0.352443 -0.917787 --28.102 38.0393 -954.114 -0.476845 0.459717 0.749186 --29.4968 -42.9728 -957.979 -0.843002 0.504118 -0.18765 --21.7839 -12.8188 -985.589 -0.770269 -0.624866 0.127386 -19.5072 -8.01886 -954.804 0.160916 -0.153433 0.974969 --16.8586 8.13037 -944.914 -0.346573 -0.25627 0.902337 --22.5048 -11.3375 -984.228 -0.832143 -0.554274 -0.0178675 --20.6614 41.1565 -973.672 -0.321245 -0.0899937 -0.94271 --17.2772 -22.3009 -1003.15 -0.431549 -0.803814 0.409449 --22.7224 -11.1512 -983.513 -0.632573 -0.691043 -0.349731 -0.815957 50.7147 -940.078 0.0541409 0.91992 0.38835 --27.9164 39.2592 -966.997 -0.603077 0.390714 -0.695443 --27.9323 18.3774 -969.544 -0.773636 0.459181 -0.436624 --29.6388 38.2041 -963.574 -0.92772 0.305078 0.215088 --20.4332 30.1752 -977.494 -0.190706 -0.6134 -0.766402 --19.5348 40.5317 -973.76 0.206624 -0.129496 -0.969813 --19.3411 -20.0283 -1000.09 -0.482973 -0.823315 0.298143 --30.3812 -24.5943 -1024.71 -0.979969 0.0872358 -0.179025 --21.8292 -13.8706 -991.018 -0.864583 -0.482386 0.140713 --29.405 35.2464 -958.364 -0.589067 0.520528 -0.618103 --27.2199 30.6779 -958.442 -0.82804 -0.548267 -0.117275 --21.2369 30.5524 -977.748 -0.412201 -0.589997 -0.694257 --17.0218 -38.6051 -946.31 0.0804692 0.0171042 0.99661 --28.537 38.2675 -966.829 -0.820015 0.106392 -0.562366 --18.8763 -21.5685 -1003.3 -0.393596 -0.814996 0.42528 --25.3778 -37.7913 -998.91 -0.160688 -0.730257 0.664007 --0.548597 30.5761 -987.139 0.549509 0.471029 -0.690052 --12.8197 37.4498 -933.884 -0.0166413 -0.839908 0.542473 --18.9455 38.359 -973.668 -0.240253 0.426865 -0.871817 --20.0015 40.3899 -973.687 -0.273369 -0.344584 -0.898071 --22.5555 1.60613 -1008.25 -0.219062 0.975486 -0.020944 --23.6787 -9.25745 -984.822 -0.898458 -0.430965 -0.0839221 --28.7192 31.3984 -955.976 -0.480235 -0.874683 0.0656103 --21.1143 -18.7873 -999.916 -0.589341 -0.721609 0.36326 --30.9364 34.5708 -955.796 -0.943209 -0.043666 0.329319 -12.756 -33.3865 -998.939 -0.506302 0.421429 0.752367 --27.0332 31.7147 -959.916 -0.824824 -0.285995 -0.487721 --20.4949 -20.398 -1002.46 -0.418992 -0.819058 0.391906 --22.1249 -16.188 -997.501 -0.913206 -0.359437 0.19199 --28.3858 33.0624 -958.936 -0.720245 -0.228086 -0.655151 --21.9619 -18.5929 -1000.85 -0.792013 -0.468576 0.391347 --27.7745 -37.6208 -1000.25 -0.0674593 -0.995727 -0.0630691 --31.7298 -26.9529 -1016.43 -0.847455 0.528389 0.0512442 --20.269 -38.8681 -945.984 0.172116 -0.322147 0.930912 --23.1259 -17.5322 -1001.81 -0.550136 -0.573518 0.606982 --22.8469 -19.8544 -1003.63 -0.502333 -0.69395 0.515844 --24.197 -15.3777 -1000.62 -0.452606 -0.444264 0.77316 --27.1374 35.14 -960.27 -0.653461 0.0306998 -0.756337 --29.3367 -44.9957 -950.847 -0.556647 -0.173922 0.812339 --15.4661 23.8806 -934.836 -0.437717 -0.850557 0.291472 --24.4975 -19.2227 -1004.13 -0.328573 -0.686995 0.648134 --30.6042 -36.8497 -1000.23 -0.742187 -0.353798 0.569197 --25.0375 49.1482 -962.656 -0.798213 0.601781 0.0267676 --27.0938 32.2519 -959.992 -0.741268 -0.0889065 -0.665295 --29.0317 -43.2143 -964.715 -0.90376 0.416261 0.0997207 --19.9874 -5.16609 -947.459 -0.744889 -0.65409 0.131555 --29.6498 -45.2145 -951.216 -0.759949 -0.24557 0.601808 --10.5683 -21.935 -1035.84 -0.124773 -0.300058 -0.945725 -6.4201 36.7728 -937.734 -0.0964097 -0.814417 0.572215 --17.2172 25.2201 -932.913 -0.451143 -0.775713 0.441293 --25.6171 25.1846 -972.478 -0.291215 -0.348023 -0.891108 --20.129 -5.28386 -947.897 -0.805362 -0.313626 0.503021 --30.1173 -46.7095 -952.81 -0.718171 -0.415337 0.558323 --20.5711 -4.76669 -946.309 -0.690139 -0.718164 0.0891498 --24.7634 40.6084 -968.962 -0.58584 0.206974 -0.783552 --30.5713 -47.8737 -953.89 -0.714806 -0.319691 0.621973 --23.6375 41.772 -971.535 -0.870898 -0.267716 -0.412147 --30.9925 34.3926 -956.685 -0.939302 -0.264678 -0.218306 --20.0108 -9.61513 -951.982 -0.840613 -0.455978 0.292326 --30.6043 34.6189 -957.449 -0.788143 -0.200091 -0.58206 --24.5468 -20.2012 -1005.37 -0.334988 -0.770806 0.541887 -20.6787 32.7249 -961.417 0.795212 -0.602243 -0.0703013 --25.6667 -17.4546 -1002.71 -0.341436 -0.657194 0.67195 --0.881896 0.890293 -1030.11 0.354015 0.528833 -0.771368 --30.8632 -51.0169 -956.491 -0.959383 -0.269637 0.0829485 --18.2242 28.2079 -933.097 -0.673242 -0.533134 0.512361 --27.2159 30.7067 -957.115 -0.472502 -0.846066 0.246809 --26.7947 30.0507 -957.997 -0.791483 -0.41129 0.452101 --25.8883 -16.255 -1001.78 -0.353171 -0.553573 0.754206 --31.0111 -50.5703 -957.754 -0.939185 -0.323199 -0.116076 --26.1229 33.5433 -960.968 -0.89267 0.0928274 -0.441049 --0.932205 50.3488 -971.031 0.377157 0.780438 -0.498667 --31.2139 -36.7886 -1001.91 -0.6609 -0.498796 0.560725 --31.1462 -36.9182 -1002.43 -0.198742 -0.978931 -0.0468521 -0.386008 50.2858 -970.208 -0.146222 0.267857 -0.952298 --25.6796 32.0439 -964.247 -0.944673 0.0542009 -0.323503 --25.8121 -18.9605 -1004.41 -0.351319 -0.728198 0.588475 --28.7824 -38.7639 -954.815 -0.700915 -0.653271 0.286279 --19.5441 56.319 -950.788 0.49294 0.843525 0.21325 -23.8297 -31.7789 -966.305 0.947937 -0.163715 0.273152 --26.8006 36.7797 -967.94 -0.446238 -0.409716 -0.795616 --20.7192 36.7942 -969.156 -0.890296 -0.1081 -0.442366 --16.5314 -18.1075 -990.98 -0.365833 -0.864721 0.344128 --26.5502 37.9115 -968.456 -0.352352 -0.185047 -0.917391 --31.6698 -27.2669 -1014.41 -0.794595 0.578853 0.183161 --26.0316 31.9938 -963.453 -0.78805 0.402456 -0.465839 --27.1141 36.1291 -960.825 -0.860345 -0.298263 0.413335 --21.516 -6.50809 -951.897 -0.740965 -0.551812 0.382719 --17.9582 15.0746 -946.266 -0.835552 -0.511663 0.200135 --29.5453 32.8515 -957.023 -0.772421 -0.590813 -0.233038 --31.2213 -34.4718 -1001.75 -0.726926 -0.079226 0.68213 --5.68252 23.8377 -986.666 -0.742285 0.537143 -0.400612 --18.304 19.3577 -942.804 -0.938374 -0.261663 0.225801 --8.4864 2.9031 -1020.54 -0.0789129 0.92186 -0.379404 -15.857 -40.2517 -962.067 -0.0732174 -0.155147 0.985174 --9.37413 23.1944 -936.357 0.254233 -0.926191 -0.278452 --21.4495 -8.71484 -954.901 -0.710035 -0.593884 0.378354 --31.3022 -48.2017 -964.058 -0.790289 -0.386589 0.475386 --20.7214 -11.1944 -957.524 -0.749139 -0.544192 0.377685 --25.4141 -20.4894 -1006.32 -0.337524 -0.803855 0.489791 --29.6451 -38.8576 -956.761 -0.633236 -0.755525 0.167909 --31.3633 -49.4682 -961.339 -0.886098 -0.462386 -0.0321004 --22.1091 -7.29743 -953.624 -0.313943 -0.78002 0.541302 --26.9331 35.4121 -960.545 -0.943619 -0.178792 -0.278597 --18.5296 16.0643 -945.522 -0.792596 -0.597895 0.119637 --29.3046 -39.8082 -959.739 -0.646288 -0.501971 0.57475 --25.9913 33.8691 -961.414 -0.971202 -0.157622 -0.178665 --28.8703 37.8977 -966.214 -0.887116 -0.167488 -0.430085 --22.3338 40.9736 -972.876 -0.545441 -0.351419 -0.76092 --31.6745 -36.7788 -954.092 -0.898241 -0.394307 0.194127 --21.0517 37.0846 -968.863 -0.416942 -0.41046 -0.810976 --16.5302 38.7211 -936.561 -0.484325 -0.733208 0.477322 --21.4497 35.9609 -968.837 -0.20952 0.377002 -0.902203 --21.633 -10.6315 -958.177 -0.515053 -0.539971 0.665696 --31.5239 -37.3699 -955.087 -0.618378 -0.760492 0.198142 --27.6655 36.7393 -961.291 -0.75561 -0.128166 0.642361 --22.5927 36.2798 -968.736 -0.13961 -0.056805 -0.988576 --4.09266 22.5789 -937.389 -0.0606654 -0.049288 0.996941 --29.6978 -43.0409 -955.414 -0.960277 0.263492 0.091869 --23.9888 40.9862 -969.824 -0.913767 0.160173 -0.373329 --20.57 37.2841 -970.754 -0.869536 -0.245386 -0.428595 --29.1223 36.5235 -963.358 -0.729861 -0.577507 0.365771 --23.1588 37.4132 -969.034 -0.0654665 -0.405289 -0.911841 --22.4354 -10.9733 -958.674 -0.198706 -0.450525 0.87037 --19.15 15.5549 -949.859 -0.868085 -0.439027 0.231697 --22.3362 -10.3172 -958.185 -0.184783 -0.70367 0.686078 --31.4956 -37.7664 -957.56 -0.699273 -0.714503 0.0224218 --19.9502 17.67 -945.858 -0.813829 -0.497486 0.300318 -9.92151 -3.30882 -1024.94 0.337154 0.626686 -0.70256 --31.7813 -37.2964 -956.479 -0.959524 -0.279138 0.0373489 --28.4517 37.025 -966.894 -0.75533 -0.283693 -0.590758 --31.5458 -37.8325 -948.267 -0.810803 -0.0366652 0.58417 --30.4857 -38.3436 -961.762 -0.869753 -0.489822 0.0600366 --17.661 37.4849 -939.83 -0.668062 -0.635275 0.387451 -26.999 -47.8797 -962.009 0.951539 0.305109 0.0384955 --23.4836 35.5583 -968.495 -0.254767 -0.164946 -0.952831 --22.8026 40.3824 -972.085 -0.64979 -0.526495 -0.548248 --23.8498 40.2017 -970.121 -0.824649 -0.330782 -0.458844 --25.9074 33.6009 -964.539 -0.882249 -0.46508 -0.073061 --31.5556 -37.5969 -959.831 -0.876992 -0.472811 -0.0856448 --19.9455 16.8146 -949.983 -0.838145 -0.517625 0.17198 --1.77641 37.9261 -933.752 0.712792 0.00931603 0.701314 -14.089 30.1814 -948.017 0.206792 -0.876156 0.435416 --32.0067 -47.2907 -965.956 -0.946662 -0.0390617 0.319853 --20.1804 21.1876 -945.774 -0.861307 -0.3402 0.377378 --25.0288 -8.73285 -956.441 -0.141783 -0.830799 0.538211 --31.757 -36.7326 -959.641 -0.994892 -0.0489016 -0.0883117 --31.524 -37.2771 -960.817 -0.924552 -0.323684 -0.201076 --30.7013 -37.8905 -962.41 -0.934026 -0.29316 -0.204092 --33.3504 -36.1586 -1002.39 -0.490721 -0.261704 0.831086 --33.0365 -36.6298 -1002.54 -0.355571 -0.813411 0.460361 --25.2242 33.8596 -966.938 -0.759479 -0.329955 -0.560644 --19.0991 38.498 -937.727 -0.339125 -0.898506 0.278714 --23.782 43.6647 -969.636 -0.814225 0.405807 0.415161 --27.9995 35.6025 -965.515 -0.637303 -0.744106 -0.200378 --24.5035 -10.0086 -958.045 -0.143142 -0.723651 0.675159 --24.9545 -11.0709 -959.078 -0.247845 -0.264819 0.931903 --23.7452 40.9814 -971.149 -0.87933 -0.221979 -0.421311 --28.0114 48.2473 -959.423 -0.609425 0.698935 -0.374288 -25.8839 -44.8774 -970.361 0.943337 0.259567 -0.20674 --28.0521 -17.9787 -1004.85 -0.447099 -0.686127 0.573874 --27.346 -19.366 -1006.05 -0.421639 -0.748716 0.511513 --26.0711 35.3807 -967.432 -0.524484 -0.560924 -0.640532 --30.7139 -40.3993 -966.356 -0.691592 -0.48164 0.53826 --30.8844 -41.3986 -966.971 -0.630492 -0.0833674 0.771705 --20.8778 38.8763 -972.081 -0.603185 -0.549501 -0.578115 --29.2864 -43.9484 -951.422 -0.784074 0.474441 0.400167 --20.1079 38.3867 -972.659 -0.696176 -0.121627 -0.707493 --29.5276 -26.6727 -959.839 -0.913875 0.0305982 0.404841 --20.3431 39.4173 -937.322 -0.859176 -0.244005 0.449752 --26.9751 35.4215 -961.594 -0.783801 -0.593893 0.181514 --30.687 33.6914 -956.149 -0.802424 -0.596132 -0.0272294 --33.8147 -36.2864 -1003.11 -0.741879 -0.615275 0.266556 --26.2417 34.5258 -966.15 -0.697381 -0.633854 -0.334499 --21.7703 31.4213 -940.592 -0.783917 -0.499701 0.368475 --20.9635 17.9019 -951.708 -0.758099 -0.64678 0.083436 --24.4746 38.8659 -969.278 -0.429561 -0.0628537 -0.900848 --34.1128 -36.0247 -1003.87 -0.893726 -0.4486 0.00350041 -7.07374 38.9275 -934.728 0.161589 -0.36406 0.917251 --27.1027 35.053 -962.959 -0.654379 -0.742879 0.141133 --22.3157 19.6089 -948.994 -0.816204 -0.475376 0.328372 --25.8982 32.9038 -962.767 -0.865915 0.405041 -0.293484 --26.7038 -10.8808 -959.675 -0.47557 -0.294478 0.828925 --34.2769 -34.8227 -1003.74 -0.949208 0.0445206 0.311484 --22.6852 39.4283 -970.784 -0.544191 -0.649599 -0.530922 --19.6781 37.7532 -973.269 -0.693811 0.500671 -0.517643 --28.4173 -8.49045 -957.667 -0.445802 -0.683121 0.578451 --23.1161 39.064 -970.05 -0.393275 -0.429688 -0.812836 --29.5221 -19.0082 -1007.64 -0.433838 -0.691235 0.577909 --34.4333 -34.7915 -1005.21 -0.997477 -0.0707429 0.00598882 --29.4891 36.8549 -964.103 -0.872951 -0.477675 -0.0989042 --22.7976 31.7341 -942.546 -0.761045 -0.585817 0.27862 --25.8871 -35.7016 -973.2 -0.851529 0.444571 0.277948 --28.6464 36.5866 -966.187 -0.806151 -0.456729 -0.37619 --22.3857 19.183 -953.947 -0.69444 -0.718161 -0.0446905 --27.5235 35.7855 -966.713 -0.566607 -0.624744 -0.537263 --30.6484 -28.8075 -967.168 -0.628876 -0.602638 -0.491266 --34.0629 -33.987 -1009.06 -0.862867 -0.404335 -0.303271 --24.6556 34.6991 -967.86 -0.464768 -0.244007 -0.851147 --21.8186 40.357 -941.732 -0.971025 -0.205246 0.122414 --25.6415 37.1915 -968.527 -0.259999 -0.297165 -0.918746 --30.9992 -28.3875 -967.137 -0.914161 -0.302239 -0.270112 --34.1043 -33.4539 -1009.19 -0.985037 0.103824 -0.137561 --27.9643 -11.0939 -960.76 -0.62046 -0.511064 0.594848 -26.2425 -46.2003 -964.027 0.846349 0.522474 0.103509 --21.9851 18.7626 -957.42 -0.875892 -0.482044 -0.0211348 --23.559 20.022 -952.591 -0.655588 -0.755106 -0.00434576 --29.1842 -9.67266 -959.79 -0.52411 -0.70233 0.481707 --22.5601 19.6547 -956.776 -0.845812 -0.507467 -0.164561 --28.6322 -11.8019 -961.556 -0.740646 0.185519 0.645776 -26.7445 -47.6004 -960.876 0.826882 0.504238 0.249019 -22.3122 -39.0501 -964.455 0.819832 0.123937 0.559031 --26.6756 34.5959 -964.371 -0.672267 -0.739207 -0.0403673 -19.0431 -42.2593 -961.812 0.22396 0.306017 0.925308 --22.976 20.04 -956.052 -0.752857 -0.638433 -0.160029 --25.1317 33.0595 -966.858 -0.979125 0.0480094 -0.19751 --30.1521 -8.72889 -959.621 -0.706942 -0.529643 0.468733 --29.0467 -10.6829 -961.75 -0.632885 -0.727822 0.264069 --30.4599 -30.1773 -1021.62 -0.679146 -0.636208 -0.366059 --27.1298 50.5329 -947.742 -0.957474 0.176499 0.228236 --24.5241 20.912 -952.955 -0.807257 -0.583025 0.0917454 --25.9791 34.3517 -953.356 0.157992 -0.122884 0.979764 -0.313794 34.9261 -934.837 0.677102 0.488037 0.550774 --30.1373 -9.57849 -960.967 -0.674074 -0.689889 0.263965 --31.2812 -29.9441 -1019.79 -0.880958 -0.347278 -0.32142 -12.6903 26.5085 -935.329 0.67181 -0.694952 0.256345 --20.7248 29.1874 -941.807 -0.823821 0.0620025 0.563448 --24.3275 20.8485 -954.45 -0.787188 -0.597806 -0.151535 --24.0611 55.1203 -950.304 -0.912967 0.402934 -0.0643146 --23.8548 54.9638 -949.306 -0.914848 0.375332 0.148927 --24.2254 53.1118 -948.409 0.0226999 0.630961 0.775482 --28.0883 49.1139 -950.818 -0.901699 -0.331044 0.278117 --30.1884 -10.0889 -963.383 -0.80723 -0.554231 0.202996 --27.3555 -41.7015 -951.068 -0.720399 0.319069 0.615808 --22.7016 42.167 -945.638 -0.766472 -0.346893 0.540542 --31.2371 -8.61854 -961.903 -0.850218 -0.488054 0.197315 --26.6809 47.6357 -953.836 -0.876519 -0.328124 -0.352207 --24.0721 22.0945 -958.845 -0.819883 -0.572531 0.000844462 --24.4012 22.2755 -959.17 -0.338904 -0.745473 0.573946 --24.3581 21.0139 -960.726 0.134643 -0.802493 0.581271 -18.5841 18.2717 -971.071 0.432555 0.030152 -0.901103 --13.7041 37.496 -934.083 -0.314423 -0.752979 0.578066 -21.677 -38.9467 -963.775 0.6468 0.0479977 0.761148 -15.6908 45.8135 -946.794 0.776831 -0.624626 0.0798449 --27.929 -27.3097 -1030.16 -0.831464 -0.431797 -0.349598 --24.3818 53.769 -949.024 -0.771829 0.616325 0.15628 --31.9111 -7.5952 -963.929 -0.939876 -0.339385 0.0380975 --24.28 53.6156 -948.545 -0.438143 0.395047 0.807446 --26.2421 53.2933 -947.877 -0.691042 0.617114 -0.376339 --23.5699 55.2336 -951.769 -0.789818 0.469072 -0.39517 --21.9052 -14.2918 -992.757 -0.906443 -0.395826 0.14725 --30.2631 -23.8456 -1022.03 -0.983794 0.12746 0.126105 --24.3975 53.3272 -949.967 -0.803444 0.580843 -0.130761 --27.7899 -25.6822 -1032.61 -0.880618 -0.231297 -0.413538 --15.8223 53.2777 -945.686 0.00786529 0.971541 0.236742 -25.6041 -46.4078 -960.733 0.592057 0.728485 0.344641 --26.3844 43.8912 -949.38 -0.300263 -0.0542739 0.952311 --29.8312 -23.477 -1019.41 -0.92559 -0.223962 0.305162 --27.0727 47.5879 -952.491 -0.910574 -0.358884 -0.205081 --28.9772 21.658 -960.138 -0.341124 -0.841369 0.419205 --29.5432 22.7509 -959.223 -0.718607 -0.385094 0.579056 --23.6162 41.1118 -948.223 -0.931078 0.121883 0.343859 --29.7974 24.858 -958.851 -0.695154 -0.150516 0.702926 --25.9585 43.88 -949.07 -0.803707 -0.225596 0.550601 --29.4478 32.4765 -954.456 -0.797223 -0.549061 0.250932 --23.1588 -12.5991 -999.372 -0.637422 -0.0875915 0.76552 --22.9434 -8.61069 -998.66 -0.766211 -0.038288 0.641447 --27.4461 -42.7264 -950.325 -0.48184 0.446387 0.754035 --2.68029 23.4521 -933.804 -0.0450447 -0.973937 0.2223 --26.394 -14.0947 -1000.74 -0.356212 -0.407252 0.840987 -11.3468 -16.2826 -960.971 -0.0392608 -0.718609 0.694306 --26.2671 -9.44289 -999.12 -0.272895 -0.128408 0.953436 -7.21276 30.6745 -985.976 0.930497 0.217179 -0.294972 --26.918 -10.9156 -999.651 -0.393961 -0.274946 0.87704 --28.7276 -43.141 -952.814 -0.875692 0.28948 0.386477 --27.8201 -12.5841 -1000.77 -0.515719 -0.341543 0.785737 -24.5809 -22.0274 -1011.46 0.667948 -0.684388 0.292334 -12.4912 -24.0868 -1027.9 0.233122 0.138946 -0.96247 --26.8396 46.6068 -952.349 -0.978611 0.186304 0.0872417 --28.3826 -16.1508 -1003.25 -0.501594 -0.572578 0.648504 --26.9931 -33.5698 -971.568 -0.501003 -0.85932 0.102789 -18.7544 -15.5109 -1024.98 0.839122 -0.399147 -0.369535 -10.464 24.887 -936.661 0.600435 -0.769846 -0.216368 --10.9628 -34.067 -1011.12 -0.209775 -0.950794 0.228004 --24.7306 53.5857 -948.688 -0.163696 0.985671 0.040692 --28.9488 -14.8853 -1002.8 -0.57949 -0.41607 0.700769 -25.4962 -44.6892 -965.474 0.805523 0.558837 0.197065 --29.5824 -41.8866 -966.186 -0.715925 -0.0830176 0.693224 --28.0979 49.6201 -952.714 -0.985735 -0.00736207 -0.168144 --27.2667 49.5994 -949.517 -0.888937 -0.0522881 0.455035 --28.464 -9.25815 -1000.16 -0.562612 -0.0936704 0.821397 --29.2555 -12.0687 -1001.67 -0.675888 -0.277344 0.682829 -25.6824 -45.5203 -963.724 0.678799 0.66243 0.316888 --29.0869 -8.31124 -1000.63 -0.743935 -0.00602127 0.668225 --27.8957 48.8308 -952.641 -0.910635 -0.373837 -0.176041 --27.2473 47.8238 -952.023 -0.869899 -0.479263 0.116545 --30.3289 -15.4612 -1004.47 -0.707378 -0.38962 0.589757 -15.2776 -0.07824 -1018.19 -0.10916 0.932948 -0.343064 --27.5233 48.4809 -947.923 -0.994533 -0.00692182 0.104196 -14.8525 -50.9275 -956.118 -0.129616 -0.171797 0.976568 --30.1231 -18.4045 -1007.15 -0.607415 -0.626943 0.487842 --25.2514 52.9912 -949.062 -0.623675 0.673277 -0.39715 --28.7654 -21.0337 -1010.27 -0.466244 -0.782119 0.413409 --29.3378 -21.2404 -1011.41 -0.485629 -0.819884 0.30324 --30.9106 -18.622 -1008.89 -0.763474 -0.552482 0.334472 --26.1673 46.3125 -950.657 -0.918102 0.123312 0.376674 --30.8056 -16.4425 -1005.92 -0.803181 -0.38995 0.450377 --30.6245 -20.0412 -1010.9 -0.649137 -0.685238 0.330256 --30.4676 -22.6008 -1022.65 -0.98712 -0.148598 -0.0592742 --26.6843 51.1114 -948.817 -0.924436 0.379293 0.0394272 --30.6847 -20.6376 -1012.67 -0.636276 -0.735744 0.232021 --23.5287 42.2856 -946.69 -0.736974 -0.560621 0.377589 -10.2436 25.7819 -947.199 0.600366 -0.0516846 0.798054 --27.1913 46.9904 -947.699 -0.952772 -0.303625 0.00604985 --31.5652 -17.1808 -1008.36 -0.86029 -0.408392 0.305151 -25.4714 -43.523 -969.752 0.920607 0.38355 -0.0732968 --31.3127 -19.4848 -1011.72 -0.835024 -0.510251 0.205861 --7.3605 35.1768 -935.986 -0.234537 0.71517 0.658426 --30.9455 -20.9276 -1014.9 -0.754518 -0.640971 0.14092 --28.0879 48.101 -957.227 -0.669704 0.696303 0.258184 --25.9444 45.9696 -949.857 -0.967355 0.0874285 0.237868 --31.8965 -18.1825 -1011.49 -0.932695 -0.329 0.147779 -17.0903 -42.6623 -961.468 -0.0514778 0.375227 0.925503 --29.6852 -24.103 -1018.72 -0.87957 0.417698 0.227783 --30.8309 -21.7026 -1019.23 -0.856658 -0.504418 0.108166 --30.4332 -22.7893 -1021.68 -0.960956 -0.26232 0.0880384 --14.964 40.8847 -933.892 0.00374417 -0.725999 0.687686 --26.2674 45.12 -948.272 -0.941625 -0.217019 -0.257381 --15.0889 40.4512 -934.202 -0.380141 -0.152435 0.912281 --20.9998 56.5881 -949.682 0.184063 0.938426 0.292365 -15.9452 -51.2638 -955.448 -0.486184 -0.183801 0.854308 -15.9563 -51.6181 -955.743 -0.245752 -0.907092 0.341745 -15.304 -51.4909 -956.528 -0.178462 -0.946094 0.27029 -11.8479 -51.3046 -956.863 -0.15222 -0.984359 -0.0886902 --26.1 46.7437 -949.83 -0.933159 -0.352741 -0.0691938 -10.252 -49.3566 -957.882 -0.95782 0.0488543 0.283187 -10.365 -50.3778 -958.663 -0.817845 -0.575021 -0.021929 --30.4369 -38.8125 -961.997 -0.916348 -0.0549094 0.396599 --26.3503 45.172 -949.688 -0.494502 0.460066 0.737433 -14.9036 -34.9511 -961.555 -0.293565 -0.200294 0.93472 --27.0114 48.3945 -949.951 -0.868918 -0.456833 0.190488 -20.9081 -5.59137 -952.652 -0.409808 -0.906894 0.0979845 --26.9534 -41.5867 -950.793 -0.586451 0.230316 0.77655 -19.8625 -4.75096 -951.861 -0.390512 -0.720048 0.573612 -20.9882 -5.40566 -953.975 -0.271946 -0.930921 0.243787 --31.6079 -12.8969 -978.429 -0.977144 0.0312282 -0.210272 --31.7047 -13.9599 -978.903 -0.797607 -0.0876358 -0.596777 --24.0463 -43.0766 -949.542 -0.0410115 0.344729 0.937806 -14.4782 -29.6025 -960.397 -0.220238 -0.190071 0.956749 -21.3848 21.9906 -970.713 0.375021 0.500853 -0.780068 --16.225 -0.701052 -943.347 -0.406403 0.0840666 0.909818 -13.7977 -35.8312 -962.2 -0.495342 -0.146846 0.856196 --17.6758 56.9527 -955.336 -0.852434 0.286292 -0.437485 -18.7715 -3.57038 -951.599 -0.559578 -0.596462 0.575417 --29.7942 -33.8095 -980.014 -0.328105 0.455103 -0.827785 --32.2073 -19.592 -973.022 -0.951473 0.30728 0.016686 --30.7717 -23.4581 -969.047 -0.986134 -0.160246 -0.0431437 -9.59012 -47.9859 -966.046 -0.986445 -0.0958504 -0.133187 --6.27027 24.4132 -936.598 0.0787677 -0.975513 -0.205353 -17.7657 -11.0955 -956.064 -0.158427 -0.442561 0.882633 -17.5722 -12.897 -957.189 -0.083995 -0.57953 0.810611 -12.8498 -34.3755 -962.469 -0.572406 -0.203708 0.794263 -9.87948 -47.9374 -966.812 -0.683311 -0.614837 -0.393779 -13.0838 -30.6385 -961.174 -0.44599 -0.219171 0.867789 -22.1049 -15.1867 -961.778 0.601457 -0.486331 0.633823 -13.9943 -25.083 -959.703 -0.330354 -0.103879 0.938123 --24.4765 -29.6246 -953.957 -0.171774 0.694368 0.698818 --4.90804 23.4622 -934.355 0.0474105 -0.997564 0.051177 --28.7342 -9.77595 -982.403 -0.165892 -0.35774 -0.918968 --30.8013 -10.9195 -981.457 -0.390763 -0.466972 -0.793247 -12.3058 -33.6911 -962.837 -0.769089 -0.200006 0.607042 -12.5142 -29.8378 -961.335 -0.65474 -0.186513 0.73248 --17.3751 -31.2747 -966.626 0.725116 -0.461767 -0.51086 --20.0851 -35.9739 -966.353 0.94605 0.19107 -0.261689 --20.7635 -50.0686 -951.113 0.0913521 -0.135635 0.986538 --32.7849 -42.9985 -980.391 -0.882771 -0.101722 -0.458659 -15.7552 -15.1346 -959.427 -0.111424 -0.549045 0.828332 -24.0321 -32.0146 -1000.34 0.702991 0.693831 0.156211 -12.865 -26.266 -960.388 -0.491855 -0.14914 0.857809 -15.436 -15.7866 -959.817 -0.11695 -0.268723 0.956091 -23.6592 -41.1548 -971.66 0.769782 0.517213 -0.374067 --32.3159 -21.0422 -972.172 -0.963507 -0.0489519 0.263168 --32.3272 -13.4544 -975.792 -0.897891 0.401991 0.179429 -10.2238 35.8884 -980.739 -0.165333 0.0111445 -0.986175 -15.2488 -12.6272 -957.722 -0.111803 -0.53937 0.834614 --25.4801 -29.3109 -954.776 -0.373968 0.584846 0.719794 -14.1856 -16.3697 -960.24 -0.286045 -0.158142 0.945076 --25.3497 48.856 -962.42 -0.65067 0.452126 -0.610091 -12.2882 -16.9992 -961.127 -0.490545 -0.0897456 0.866782 --16.0661 -26.6848 -963.361 0.996569 0.0587406 0.0583064 --28.1676 -15.3622 -978.74 0.00268648 -0.458722 -0.888576 -3.37695 24.4658 -938.392 -0.0916366 -0.843819 -0.528745 -11.4033 -18.2118 -961.927 -0.651635 -0.154314 0.74267 --31.0379 -8.86811 -982.099 -0.55054 0.0475314 -0.833455 -2.65745 36.5977 -937.741 0.371917 -0.414508 0.830579 -10.7704 -20.2636 -963.03 -0.790153 -0.148256 0.594709 --18.3186 -37.7629 -961.898 0.853395 -0.199857 -0.481428 -10.037 -18.5612 -963.155 -0.594961 -0.430833 0.678531 --1.3661 -19.344 -942.449 -0.0680049 -0.694059 0.716699 -18.5008 -38.0664 -999.262 -0.0209251 -0.99856 0.0493987 --1.37802 -19.8216 -943.216 -0.137031 -0.886418 0.442137 --2.6328 -18.65 -942.341 -0.522927 -0.514269 0.679761 --13.2772 -17.6801 -965.165 0.714264 -0.693721 0.0926213 --16.0088 -24.0859 -964.267 0.999476 -0.0310701 -0.00906203 -16.3869 -37.0716 -997.812 -0.360348 -0.734233 0.57537 --2.43129 -16.1582 -941.742 -0.353602 -0.45892 0.815082 -3.15401 38.791 -936.3 0.146293 -0.582077 0.799865 --3.0148 -17.3575 -942.154 -0.494605 -0.316414 0.809474 --19.7505 -37.1758 -970.939 0.83677 0.449233 0.313057 --2.74759 -19.2138 -942.957 -0.547601 -0.716051 0.432902 --2.56771 -19.7848 -944.507 -0.495771 -0.856323 0.144644 --31.2043 -41.0663 -982.556 -0.701987 -0.0502365 -0.710415 -6.93138 13.6998 -941.647 0.0298115 -0.933297 0.357866 --17.7769 -42.7724 -983.703 0.372879 -0.564547 -0.736375 --18.9701 -34.5483 -976.203 0.70624 0.526889 0.472877 --3.50271 -14.8439 -941.289 -0.380715 -0.247236 0.891028 --3.11188 -19.1007 -943.641 -0.693144 -0.581175 0.426365 -15.7873 -37.7254 -999.474 -0.212178 -0.912321 0.350215 --7.65075 21.6858 -938.628 -0.207456 -0.40637 0.889846 --32.1583 -21.7653 -970.684 -0.937602 -0.245865 0.245872 --26.1875 -34.4586 -973.266 -0.597747 -0.745084 0.295884 --3.98039 -18.3069 -943.319 -0.599901 -0.647189 0.470389 -23.6835 28.5313 -962.245 0.876634 0.364665 0.313898 -5.80552 22.6799 -935.262 -0.0682947 -0.950076 0.304454 -14.798 -37.6273 -999.169 -0.165725 -0.854592 0.492145 --3.6249 -12.9775 -940.906 -0.623874 -0.0590046 0.779294 --4.21425 -15.2217 -941.876 -0.543637 -0.695786 0.469406 --25.9112 -39.6431 -984.668 -0.270973 0.468655 -0.840795 -14.2555 -37.7006 -999.69 -0.225923 -0.962845 0.147946 --3.1394 -19.4644 -948.058 -0.578594 -0.801342 -0.151919 -9.45205 27.028 -944.899 0.774438 -0.63255 0.0112341 -7.21211 23.6024 -945.435 0.741531 -0.0680514 0.667459 --4.94735 -14.6794 -942.176 -0.783444 -0.259685 0.564605 --4.14746 -18.8385 -946.435 -0.69891 -0.713672 -0.0468795 --4.61685 -17.7799 -943.675 -0.698067 -0.586408 0.410886 --4.77174 -18.1107 -944.888 -0.725876 -0.674473 0.134869 --5.31358 -16.3323 -943.182 -0.70574 -0.249236 0.663183 --20.8141 -34.7628 -969.931 0.983501 -0.119124 0.136141 --20.6475 -34.3204 -970.278 0.91432 -0.370649 0.163212 --16.1117 -27.3737 -964.567 0.993837 0.00728664 -0.110609 --4.54753 -10.3813 -941.928 -0.329513 -0.78207 0.52895 --15.9504 -20.5376 -964.197 0.940395 -0.313895 0.130868 --28.7556 -41.0993 -953.188 -0.877733 0.413288 0.242442 --4.83676 -9.6659 -941.355 -0.135645 -0.309819 0.94107 -12.4687 -36.8345 -999.511 -0.552103 -0.723333 0.414694 -12.3606 -37.0775 -1000.86 -0.534998 -0.844128 0.0349933 -2.09809 23.1025 -934.367 0.000631196 -0.85953 0.511085 --1.6167 23.4909 -936.047 0.0337688 -0.999077 -0.0265561 --4.45302 -11.0139 -943.03 -0.789568 -0.199317 0.580392 --4.82868 -10.7137 -943.107 -0.435375 -0.750992 0.496447 --31.5394 -11.5613 -979.47 -0.9149 -0.312994 -0.254937 --3.99985 -17.1851 -949.695 -0.729923 -0.652459 -0.20374 -15.9654 -43.8998 -960.964 -0.2274 0.556255 0.799293 -5.28381 41.0818 -934.969 0.079006 -0.259199 0.962587 --31.6664 -9.20572 -981.544 -0.825306 -0.17845 -0.535748 --32.7048 -8.09934 -978.042 -0.99328 0.108054 -0.0414725 --19.571 -43.5556 -949.772 0.58256 -0.122671 0.803477 --31.3273 -10.9957 -980.779 -0.793474 -0.414763 -0.445388 --0.745544 38.5769 -981.065 0.140848 0.682557 -0.717131 --22.1693 34.3024 -973.418 -0.556458 0.466388 0.687631 --4.50711 -16.779 -949.451 -0.519546 -0.852109 0.0630983 --15.4076 -18.0468 -963.78 0.623433 -0.576534 0.528148 --5.54898 -11.2235 -943.919 -0.31899 -0.547542 0.773591 --5.93097 -12.7512 -944.714 -0.607293 -0.251988 0.753457 --5.76113 -15.6326 -947.344 -0.517128 -0.815361 0.260319 --20.3331 -33.5229 -969.396 0.797254 -0.601536 -0.0504061 --20.3256 -34.2465 -967.366 0.799333 -0.487196 -0.351721 -11.4351 -36.1297 -1001.18 -0.813867 -0.578387 0.0555833 --0.611567 25.2721 -930.08 -0.309183 -0.912737 0.267052 --7.07154 -9.6144 -941.401 -0.0787485 -0.598799 0.797018 --5.01559 -16.6022 -949.644 -0.255221 -0.93405 0.249826 --20.8567 -35.0308 -968.644 0.986721 -0.0666358 -0.148129 --6.39056 23.4506 -937.925 -0.204746 -0.403467 0.891792 -0.719366 23.0035 -934.688 -0.10832 -0.993084 -0.0452773 --0.670624 17.8928 -997.677 0.0853634 0.903075 -0.420914 --3.69756 -17.8492 -953.432 -0.149413 -0.962275 0.227383 -17.9983 -19.0355 -1024.25 0.491154 0.435625 -0.75432 --6.77874 -10.2439 -942.942 -0.153222 -0.903859 0.399453 --15.7986 -41.0855 -982.128 0.728084 0.0083213 -0.685438 --7.00502 -14.9806 -947.154 -0.310283 -0.785554 0.535378 --31.2762 -43.0901 -982.159 -0.608642 -0.415728 -0.675814 -10.5942 36.3287 -980.68 0.240049 0.286662 -0.927471 --25.4808 -41.6142 -985.048 -0.169329 -0.176201 -0.969681 --16.355 -37.4684 -981.262 0.684113 0.430416 -0.588839 -6.58658 42.3784 -933.08 0.351547 -0.83655 0.420237 --19.3419 -35.9092 -964.097 0.812067 -0.297442 -0.502072 --18.3236 -34.8449 -979.941 0.4344 0.784973 -0.441717 -5.6428 42.9922 -931.997 0.135821 0.309576 0.941124 --13.62 35.9739 -981.878 -0.121552 0.210863 -0.969929 --19.254 -34.4907 -979.768 0.228894 0.899149 -0.373014 -5.96376 42.6044 -932.086 0.351789 -0.444874 0.823609 --7.5093 -12.9986 -945.364 -0.14491 -0.558082 0.817035 -18.0759 -25.3769 -1009.66 0.593623 0.573749 0.56429 --21.2919 -32.9941 -972.523 -0.256123 0.757798 -0.600119 --10.8008 34.0969 -936.008 -0.235956 0.634804 0.735764 --27.9139 -35.275 -980.671 0.0273948 0.538466 -0.842202 -14.7989 -44.2097 -961.102 -0.275347 0.549299 0.788958 --30.695 -24.2965 -969.424 -0.993425 -0.0495392 0.103216 --32.0082 -21.5966 -970.241 -0.917805 0.0636473 0.391896 --17.9536 -34.8718 -977.174 0.631697 0.730183 0.260368 --2.22237 13.6342 -939.169 -0.0182947 -0.831562 0.55513 --31.7318 -13.2622 -974.384 -0.893841 0.137603 0.426747 --24.3911 -31.607 -972.54 0.339433 0.721024 -0.604077 --1.84942 24.2813 -933.067 -0.0522469 -0.574339 0.816948 --9.42717 22.833 -937.992 0.268246 -0.808014 0.524554 --2.56713 16.3929 -936.875 -0.0347442 -0.512148 0.858194 --9.25035 -9.72832 -942.089 -0.200731 -0.89919 0.388799 --7.63917 -16.1074 -949.776 -0.235862 -0.905671 0.35232 -26.0527 -3.41904 -960.853 0.955536 -0.00102018 0.294874 -4.06036 25.0455 -939.574 -0.011144 -0.971307 -0.237568 --2.76737 12.3802 -941.207 0.0166994 -0.750393 0.660781 --14.1197 -17.1343 -968.072 0.555158 -0.812802 -0.176501 --9.65707 -13.2437 -945.968 -0.208875 -0.66636 0.715776 --9.02372 -15.1047 -948.321 -0.256447 -0.850316 0.459563 --2.9541 23.6841 -933.43 -0.0397088 -0.749415 0.660908 --9.03051 -10.1729 -943.521 -0.182982 -0.794951 0.578421 -10.3163 16.5508 -991.008 0.232879 0.71476 -0.659458 --28.3984 41.0763 -965.696 -0.440517 0.782261 -0.440468 --19.9658 -41.4434 -984.791 0.203539 0.104208 -0.973505 --31.3281 -36.5077 -962.422 -0.933277 -0.104569 -0.343599 --28.5536 41.1811 -965.167 -0.614093 0.764955 -0.194251 -10.6464 -33.7418 -1006.75 -0.835483 -0.302618 0.458684 -20.5521 -13.0094 -1023.86 0.862947 -0.327538 -0.384761 --16.3135 -36.0982 -979.491 0.712451 0.666189 -0.220467 --10.4047 -13.5104 -946.599 -0.280327 -0.776163 0.564789 --17.4746 -40.218 -947.304 0.125928 -0.687517 0.715166 -11.3858 -34.8332 -1009.42 -0.139432 -0.97158 -0.191286 --10.9941 -12.6589 -945.87 -0.314351 -0.673063 0.669455 -10.5937 -34.2774 -1007.4 -0.728145 -0.604189 0.323669 --17.0447 -40.3423 -983.157 0.533286 0.26633 -0.802916 --4.72512 23.826 -933.573 0.0390245 -0.798993 0.600073 --11.8257 -9.17224 -942.555 -0.335376 -0.86767 0.366976 -1.7428 -21.6196 -992.539 0.15754 -0.902727 0.40033 --18.9497 -39.0808 -946.572 0.238305 -0.126499 0.962917 --18.3976 -41.4909 -948.248 -0.0635738 -0.669003 0.740536 -9.97539 -31.4096 -1006.57 -0.584351 -0.3117 0.749251 -7.63362 41.8863 -935.038 0.172865 -0.785425 0.594328 --18.6504 -39.4341 -946.771 0.0343849 -0.551793 0.833272 -9.87045 -33.7706 -1007.83 -0.61533 -0.415098 0.670121 -10.398 -34.6713 -1009.73 -0.300055 -0.937352 0.177027 --6.02003 14.3418 -938.987 -0.118814 -0.798872 0.58965 --19.3483 -34.0262 -976.667 0.532013 0.845267 0.0498608 --12.1587 -9.48912 -943.954 -0.351093 -0.704639 0.616618 --12.0873 -13.1118 -946.969 -0.366633 -0.740673 0.563014 -9.56209 -26.6882 -1005.15 0.532024 -0.606706 0.590642 --5.35249 13.0658 -941.48 -0.242918 -0.811461 0.531527 --17.0466 -46.5004 -957.85 0.959343 0.281028 -0.026152 --19.4438 -39.4279 -984.03 0.300841 0.367557 -0.879998 --21.9098 -51.5974 -951.35 0.0780237 -0.450701 0.889258 -23.6976 0.342814 -952.666 0.811825 0.532386 0.239804 --11.2322 -15.4378 -950.425 -0.288008 -0.886555 0.36204 -8.52326 -31.8469 -1007.45 -0.234728 -0.568194 0.788707 -8.57801 -33.8862 -1008.99 -0.406574 -0.668213 0.623048 -16.9329 -0.955372 -950.856 0.772482 -0.530066 0.349717 --7.0809 17.2559 -936.645 -0.101984 -0.399001 0.911262 -16.9573 -1.46336 -951.601 0.39598 -0.572278 0.718121 -8.6769 -28.9106 -1005.93 0.152692 -0.259054 0.953717 --15.1071 -39.0075 -979.691 0.962798 0.252972 -0.0950007 --20.0533 -42.9719 -983.933 0.0320001 -0.911639 -0.409743 -10.0312 42.4716 -934.708 0.484167 -0.363043 0.796104 -9.21422 7.42305 -1009.51 0.46553 0.631169 -0.620409 --12.2481 -14.5948 -949.444 -0.350627 -0.825427 0.442415 --30.4778 -41.2635 -983.137 -0.57003 -0.000645333 -0.821624 -8.55838 -34.4454 -1010.64 -0.0834436 -0.996232 0.0236289 --18.2114 -43.099 -983.384 0.161338 -0.879623 -0.447475 --13.2735 -8.8684 -943.844 -0.43846 -0.819046 0.370022 -5.93879 23.0007 -936.782 -0.0115206 -0.832812 -0.553436 --17.9338 -36.1984 -981.529 0.297518 0.692024 -0.657713 --18.211 -37.3868 -982.545 0.385272 0.462046 -0.798798 --10.3538 -16.6294 -953.12 -0.270307 -0.934621 0.231123 --20.4774 -36.7915 -968.142 0.916147 0.3474 -0.199969 --17.3658 -30.5579 -967.176 0.876151 -0.276787 -0.39465 --31.5592 -16.5166 -974.875 -0.879294 -0.346923 0.326322 --32.3342 -15.0863 -977.161 -0.824057 -0.392042 -0.408941 --6.68858 12.4292 -942.71 -0.248965 -0.658154 0.710527 --23.017 -49.346 -950.623 0.192999 -0.754293 0.62753 -5.72595 6.13681 -1013.91 0.230453 0.418401 -0.87854 --23.8075 -52.6576 -951.923 -0.00632881 -0.778254 0.627917 --8.77795 14.5514 -939.27 -0.0323959 -0.916211 0.399385 --24.8738 -39.7538 -984.865 -0.0396458 0.427448 -0.90317 --7.82693 13.5696 -941.616 -0.126019 -0.85878 0.496605 --15.7881 -36.9783 -979.866 0.868988 0.432985 -0.239549 --24.3814 -51.5151 -951.099 -0.0578339 -0.325697 0.943704 --8.53063 23.1785 -934.015 0.132684 -0.894597 0.42672 --17.035 -46.3079 -954.923 0.972081 0.229906 0.0469266 --14.7135 -10.8384 -946.193 -0.461174 -0.657588 0.595732 --24.6058 -48.6895 -949.191 -0.170451 -0.808601 0.563127 --24.2571 -52.6971 -952.213 -0.10312 -0.955305 0.277054 -12.4434 8.81531 -946.264 0.565389 -0.333742 0.754289 --14.8113 -8.09684 -943.299 -0.457386 -0.833068 0.31112 --31.1638 -16.2209 -973.648 -0.934081 -0.161964 0.318213 --14.2576 -13.3339 -949.028 -0.473575 -0.760941 0.443504 --12.6837 -15.4523 -951.989 -0.39855 -0.872077 0.283971 --18.2375 -44.7845 -959.829 0.996355 0.0668331 -0.0530119 --22.7262 -41.4051 -949.22 -0.72917 -0.288244 0.620666 --14.6554 -8.73692 -944.733 -0.467989 -0.560152 0.683532 --22.8319 -39.2577 -947.773 -0.604533 -0.482359 0.633932 --24.6581 -52.5912 -953.031 -0.0226123 -0.98688 -0.159864 --27.5969 -32.8435 -978.273 0.241289 0.8618 -0.446184 --25.1439 -34.0494 -977.937 0.504707 0.809115 -0.301004 --20.7324 -33.3848 -975.342 -0.25584 0.958348 -0.126946 -11.1629 26.4432 -947.82 0.311619 0.381651 0.870193 --17.0295 -35.8451 -977.252 0.727255 0.499814 0.47041 --17.453 -42.2997 -983.722 0.601217 -0.12339 -0.789502 --19.4177 -42.5121 -984.455 0.157989 -0.637258 -0.754282 -0.882383 25.3384 -939.614 0.336617 -0.928282 0.158055 --25.1311 -0.575867 -1021.32 -0.159841 0.931124 -0.327808 --21.979 -37.9764 -983.897 0.0574761 0.52088 -0.851693 --21.0552 -39.5097 -984.488 0.151762 0.355686 -0.922201 --21.9361 -37.3541 -983.415 -0.0777068 0.701955 -0.70797 --24.5492 -49.4893 -950.651 -0.244496 -0.712216 0.658004 --25.7287 -50.9586 -951.437 -0.264208 -0.322016 0.90912 --24.1116 -42.6259 -984.822 -0.00899287 -0.779164 -0.626756 --10.5891 23.0083 -934.476 0.0644582 -0.903746 0.423188 --9.76794 13.1514 -942.423 -0.00144891 -0.815617 0.57859 --15.5596 -7.91512 -944.757 -0.54347 -0.698944 0.464884 --27.4036 -41.3921 -984.696 -0.285361 0.0247059 -0.958102 --27.0378 -42.0885 -984.727 -0.226579 -0.319259 -0.920182 --29.0738 -42.8118 -983.696 -0.312094 -0.586272 -0.747585 --16.3557 -9.66158 -946.433 -0.56749 -0.535404 0.625537 --11.0275 30.5449 -984.695 -0.0693243 0.80449 -0.589906 --26.3244 -48.2926 -949.826 -0.373713 -0.846671 0.378796 --26.3361 -52.2348 -952.471 -0.248956 -0.733575 0.632368 --15.4767 -19.7524 -966.932 0.887845 -0.43815 -0.140553 --15.679 -19.4608 -964.25 0.873012 -0.298382 0.385769 --32.5639 -14.9693 -976.189 -0.96258 -0.195721 0.187437 --31.6259 -12.3046 -977.629 -0.996621 0.0570277 0.059116 --28.135 -28.9032 -969.235 -0.775574 -0.32664 -0.540176 --16.4277 -10.9409 -947.979 -0.57763 -0.65116 0.492274 --23.2338 28.5437 -946.18 -0.467243 -0.882879 0.0469937 --26.2512 -44.6451 -949.365 -0.254192 -0.106355 0.961288 --26.7614 -44.002 -949.548 -0.264637 0.242892 0.933258 --11.5619 22.6253 -935.409 0.136729 -0.990598 -0.00456583 --12.1781 15.9038 -938.078 -0.174769 -0.557575 0.811521 --19.7305 -33.5225 -973.514 0.921759 0.187933 -0.339178 --12.438 14.2893 -939.257 -0.0391204 -0.771718 0.634761 --26.9127 -52.4202 -953.128 -0.140632 -0.968458 0.205699 --16.7233 -7.441 -945.334 -0.551614 -0.408156 0.727414 --0.885733 23.7429 -937.838 0.739405 -0.637244 0.217255 --27.3591 -48.1409 -950.959 -0.576928 -0.815385 0.0479687 --26.6654 -48.5802 -951.213 -0.510133 -0.764783 0.393537 --17.1983 -6.92981 -944.217 -0.528323 -0.83493 0.154162 --12.3896 22.9105 -934.517 -0.0875567 -0.806476 0.584748 --21.5283 -42.2258 -984.905 0.11215 -0.367671 -0.923169 --17.0648 -42.8979 -982.997 0.541043 -0.650647 -0.532851 --19.5633 -33.5779 -973.036 0.906523 -0.320334 -0.274956 --22.2086 -33.7772 -973.993 -0.00750396 0.941014 -0.338284 --15.7607 -13.9439 -952.372 -0.492013 -0.817551 0.299223 --28.0687 -47.4498 -950.145 -0.82001 -0.0441204 0.570646 --28.5622 -32.7083 -978.141 -0.0555361 0.957981 -0.281403 --27.2757 -48.3495 -951.785 -0.768293 -0.610743 0.191622 --26.1662 -34.9691 -980.007 0.260454 0.728184 -0.633965 --13.2949 22.4086 -935.411 -0.0431756 -0.978696 0.200722 -9.91057 27.5082 -944.501 0.750037 -0.578834 -0.319994 --13.7484 15.4752 -938.809 -0.339824 -0.402801 0.849865 --18.4302 -8.74222 -947.848 -0.679873 -0.542624 0.493287 --17.583 -43.0037 -961.019 0.991312 0.131317 0.00757579 --13.6189 22.6245 -935.016 -0.176611 -0.822336 0.540899 --27.5555 -29.664 -969.984 -0.700236 0.490113 -0.519095 --30.639 -26.9359 -968.966 -0.774034 -0.441499 -0.453818 --31.0437 -24.2179 -970.625 -0.920439 -0.252265 0.298588 --14.5354 13.8002 -940.172 -0.219091 -0.794607 0.566215 --31.1878 -18.2053 -974.757 -0.965359 0.0971161 -0.242178 --31.397 -17.8764 -973.981 -0.973776 0.190338 -0.124626 --28.1395 -32.4201 -1000.14 -0.32282 0.445956 0.834812 -17.2005 -14.4126 -992.59 0.730952 -0.651097 0.204405 --27.9099 -47.5301 -952.444 -0.638021 -0.169512 0.751129 --25.6246 -30.7495 -971.57 0.0214724 0.817807 -0.575092 -14.4926 -45.5244 -960.05 -0.217772 0.758634 0.614044 --18.7502 -6.19287 -946.517 -0.714894 -0.436255 0.546451 --17.6178 -12.516 -951.926 -0.562454 -0.73468 0.37933 --29.4842 -51.6684 -952.78 -0.604628 -0.466398 0.645676 --28.3719 -52.3099 -954.278 -0.169808 -0.955678 -0.240509 --1.46918 -25.0518 -997.393 -0.000143454 -0.800723 0.599035 --13.8877 12.7277 -942.194 0.036615 -0.865981 0.498735 --25.0544 -32.8482 -975.459 0.505843 0.765637 -0.397396 --28.1741 -47.147 -952.514 -0.487161 -0.285026 0.825491 --29.1066 -52.2127 -953.541 -0.370503 -0.92657 0.0647771 --2.69658 -24.2213 -996.428 -0.104035 -0.81895 0.564357 --1.0441 -26.3697 -999.033 0.00905392 -0.754444 0.656301 --18.9883 -5.89604 -946.482 -0.637689 -0.723242 0.265093 --19.1602 -5.80571 -945.367 -0.62032 -0.748584 0.234148 -4.19868 34.6553 -938.235 0.0901085 0.759956 0.643698 --30.1541 -51.3781 -953.307 -0.809124 -0.347566 0.473832 --15.8195 -20.6664 -967.052 0.684705 -0.71956 -0.115812 -3.86427 5.67978 -1014.5 0.646919 -0.23374 -0.725852 -6.51736 35.714 -938.682 0.0735205 -0.163333 0.983828 --7.36453 39.1195 -934.39 0.170159 -0.470896 0.865623 --1.97407 -29.1776 -1001.73 -0.0502399 -0.645551 0.762063 -7.93848 26.2736 -943.362 0.576967 -0.797123 0.178055 --31.7215 -35.2919 -958.347 -0.992376 0.122136 -0.0165069 --15.5515 16.7982 -938.607 -0.634892 -0.445655 0.631113 --15.1054 15.7242 -939.453 -0.595805 -0.38292 0.705966 --31.6187 -35.2879 -959.981 -0.975083 0.187384 -0.118741 --15.4615 13.4338 -941.451 -0.655593 -0.643097 0.395758 --18.5532 -11.864 -952.207 -0.690538 -0.630154 0.355054 -13.0475 26.8778 -935.989 0.931897 -0.305558 0.195455 -15.306 42.5919 -969.723 0.470426 -0.0845696 -0.878378 --24.5961 -34.4888 -978.389 0.284468 0.890475 -0.35515 --14.9616 12.212 -943.189 -0.29216 -0.701871 0.649631 --18.4811 -12.7054 -953.955 -0.624274 -0.737499 0.257638 -20.8961 -14.7918 -1000.5 0.435917 -0.518216 0.735819 --24.5697 -45.7087 -949.232 -0.105412 0.0114199 0.994363 --16.337 15.2302 -940.505 -0.755709 -0.299095 0.582621 -6.40774 25.0433 -939.314 0.125095 -0.929172 -0.347836 --30.4821 -51.4518 -954.71 -0.889294 -0.431325 0.152035 --19.1549 -10.3763 -951.036 -0.769483 -0.514643 0.378204 --23.1412 -34.5756 -978.433 -0.156959 0.960394 -0.230233 --2.92556 -26.3852 -999.309 -0.15285 -0.768113 0.621803 --16.397 -25.6312 -967.389 0.985597 -0.106797 -0.131123 --17.7411 -44.2745 -955.036 0.932088 0.357322 0.0594443 --18.7151 -13.3053 -956.661 -0.651823 -0.701639 0.287801 --18.2074 -45.0969 -951.718 0.958293 0.143353 0.247235 --17.0019 17.3878 -940.121 -0.774856 -0.498242 0.389042 --28.0887 45.3291 -953.907 -0.785053 0.607706 -0.119935 --28.3512 -28.0012 -969.842 -0.570613 -0.618334 -0.540429 --19.6106 -11.6589 -954.283 -0.788184 -0.560652 0.253839 -3.83106 38.4154 -936.435 -0.297757 -0.70883 0.639453 --4.635 -33.196 -1005.42 -0.265552 -0.648946 0.712987 --19.6522 -12.1659 -956.338 -0.738814 -0.629829 0.239727 --19.1787 -13.2295 -957.355 -0.578196 -0.642728 0.502583 --4.30593 -27.2879 -1000.58 -0.202819 -0.664736 0.719021 --4.5101 -29.8544 -1002.66 -0.205067 -0.611001 0.764608 --5.16042 -34.1871 -1006.63 -0.285886 -0.741687 0.606769 --4.22003 -35.2156 -1007.93 -0.112738 -0.959626 0.2577 --17.1188 -2.30085 -1020.58 0.110777 0.814563 -0.569399 --30.7864 -49.7583 -959.468 -0.992142 0.121308 -0.0306224 --30.8613 -25.0166 -970.408 -0.968354 -0.246755 -0.0374352 --22.7661 34.2776 -974.009 -0.826506 0.426489 0.367417 --24.8473 -38.1277 -983.693 -0.125178 0.668967 -0.732676 --18.2392 -41.2207 -959.929 0.997682 0.0298881 -0.0611387 --6.68281 -25.5021 -999.581 -0.254926 -0.759787 0.598111 --6.47337 -29.5321 -1003.18 -0.351623 -0.605537 0.713923 --6.78167 -26.7316 -1000.99 -0.325665 -0.673256 0.663829 --18.3897 -44.2063 -951.144 0.964635 0.129895 0.229362 --6.76018 -32.5008 -1005.85 -0.392446 -0.614755 0.684151 --26.9137 -22.9213 -975.344 -0.200415 -0.512105 -0.835214 --23.4771 -33.8253 -974.925 0.368188 0.849974 -0.376806 --23.5674 -34.1806 -976.089 0.196946 0.948693 -0.247375 --7.06239 -33.9558 -1007.48 -0.402932 -0.682864 0.609378 --26.5609 -29.7939 -970.894 -0.522877 0.135361 -0.841592 --6.53061 -34.9033 -1008.96 -0.171999 -0.98482 0.0233473 -13.3855 -46.5836 -958.224 -0.0626563 0.80183 0.594258 --27.5609 -28.4323 -970.398 -0.671009 -0.432784 -0.602034 --15.66 24.4388 -939.4 -0.422228 -0.906409 0.012084 --26.5103 -29.0335 -971.018 -0.44776 -0.414031 -0.792521 -25.0718 -12.7846 -978.957 0.610964 -0.0586326 -0.789484 --31.8677 -22.9423 -972.222 -0.940824 -0.337129 0.0345611 -18.7411 38.7259 -962.638 0.264931 0.252666 -0.930576 --9.11248 -31.0347 -1006.04 -0.494331 -0.57771 0.64953 --19.4067 -23.3176 -974.518 0.398509 -0.279881 -0.873417 --18.0828 -18.3201 -976.386 0.410877 -0.623405 -0.665241 --30.2041 -15.9797 -978.519 -0.156366 -0.476133 -0.86536 --32.4078 -47.401 -968.311 -0.804577 -0.593577 -0.0179651 -9.02348 37.9034 -936.895 0.436785 -0.669851 0.600432 --18.7411 -42.2379 -955.268 0.980562 0.195594 -0.0155494 --25.7913 -41.1886 -949.58 -0.0464808 -0.613227 0.788538 --10.1188 -31.9736 -1007.71 -0.459222 -0.592066 0.662248 --32.6359 -47.0163 -967.996 -0.945363 -0.276251 0.173129 --10.8609 -30.4104 -1006.98 -0.553914 -0.513516 0.655347 --30.8819 -23.8783 -972.745 -0.639909 -0.629203 -0.441157 --19.2883 -32.4374 -972.935 0.656889 -0.0951564 -0.747959 --11.5387 -25.0616 -1001.98 -0.421616 -0.741379 0.522109 --11.1267 -33.4129 -1009.79 -0.401468 -0.733772 0.54809 --24.5834 -30.4946 -971.436 -0.12115 0.347255 -0.929912 --12.2745 -33.4278 -1010.43 -0.198505 -0.769929 0.606469 --16.022 -19.392 -970.489 0.923891 -0.3389 -0.177684 --19.1671 27.1081 -937.785 -0.946447 -0.0868885 0.310946 --17.7914 -39.8743 -958.113 0.921084 -0.387257 -0.0404589 --21.3298 -19.2201 -1029.01 -0.136628 -0.266131 -0.954205 --18.7342 -41.9049 -955.632 0.994515 -0.0659274 0.0812045 --23.8119 50.4763 -962.464 -0.439504 0.564506 0.698691 --30.799 -33.9604 -962.579 -0.955176 0.153171 -0.253334 --27.4107 50.4685 -949.814 -0.848447 0.360308 0.387706 --27.0625 50.0668 -947.603 -0.909057 0.141588 0.391879 --28.066 49.6418 -950.845 -0.973796 0.132193 0.18506 --24.8702 49.1739 -947.503 -0.0606485 -0.270251 0.960878 --23.6498 47.5083 -948.108 0.00488093 -0.057499 0.998334 --23.1741 47.6231 -948.018 -0.580893 -0.311244 0.752124 --27.2998 48.6472 -947.517 -0.675728 0.0148864 0.737001 --23.417 46.8182 -948.028 -0.000113493 0.336534 0.941671 --22.9712 46.853 -947.961 -0.392285 0.297932 0.870258 --26.5972 -39.8309 -947.885 -0.430389 -0.716008 0.549635 --20.7936 47.5163 -939.571 -0.90281 0.180845 0.390166 --28.0518 47.0389 -956.055 -0.565066 0.384584 0.729929 --29.2559 46.4767 -958.007 -0.944423 0.31646 0.0889866 -13.4426 28.2539 -949.445 0.351558 -0.201231 0.914283 --26.1755 -45.1663 -949.563 -0.355382 -0.217422 0.909083 --27.4876 45.791 -955.456 -0.624177 0.217505 0.750396 --28.8668 45.3822 -956.502 -0.772685 -0.15702 0.615063 --20.8771 -32.666 -972.522 -0.474612 0.205378 -0.855899 --21.5521 45.2093 -941.465 -0.712659 -0.0141345 0.701368 --26.1475 45.4724 -947.156 -0.323417 0.0754232 0.943246 -3.56436 -24.9518 -1031.43 0.314745 -0.265285 -0.91135 --23.0923 44.8222 -946.273 -0.622692 0.413133 0.664512 --22.1449 44.9613 -942.175 -0.506798 -0.463569 0.726815 --16.1396 -20.7865 -969.705 0.953058 -0.276522 -0.123354 --24.4354 44.2134 -946.484 -0.197607 0.364438 0.91002 --16.2269 -23.0882 -969.378 0.993977 -0.0803712 -0.0744939 --21.8859 43.8655 -941.963 -0.950598 -0.0569844 0.30515 --18.7903 -30.1594 -972.997 0.672908 -0.132964 -0.727678 --22.345 43.3025 -944.534 -0.928191 -0.242101 0.282576 -11.4931 -44.0267 -970.565 -0.916177 0.0958564 -0.389142 -4.93063 23.74 -942.272 0.5818 -0.44983 0.677615 --28.1442 43.4906 -949.71 -0.6955 0.247409 0.674588 --27.8911 43.0322 -949.465 -0.242021 0.110415 0.963968 --18.5129 -40.0427 -955.599 0.930263 -0.35571 0.089896 --19.867 -28.6879 -973.398 0.0443841 -0.154863 -0.986938 --21.9902 42.8347 -942.81 -0.979798 -0.122155 0.158349 -7.53769 20.6903 -942.704 -0.129296 0.830534 0.541753 --21.5488 42.8473 -940.51 -0.944708 0.0732565 0.319625 --20.0012 42.5143 -934.291 -0.763129 0.216746 0.608814 --29.1145 42.2369 -950.871 -0.852972 -0.0988492 0.51251 -0.65158 24.3989 -940.26 0.599965 -0.119252 0.791089 --5.24351 38.105 -934.564 -0.593629 -0.462088 0.658847 -25.7929 -15.77 -977.431 0.942299 -0.296459 -0.155514 --28.1668 42.1891 -949.64 -0.666015 -0.015549 0.745776 --20.828 41.6725 -938.724 -0.895075 0.0667059 0.440898 --5.74544 37.159 -935.236 -0.832474 0.0937643 0.546073 --22.1296 40.9768 -944.906 -0.938093 -0.0114724 0.346195 --27.6731 39.7867 -961.613 -0.438359 0.475936 0.762447 -6.71266 -11.1757 -1027.69 -0.0238925 0.553504 -0.832504 --23.372 40.8592 -947.443 -0.820633 0.359532 0.444182 --15.158 -34.7962 -948.731 0.868079 0.369073 0.332001 --28.4708 39.4287 -961.68 -0.472606 0.305607 0.826588 --17.0665 -18.6252 -975.165 0.574156 -0.61652 -0.538746 --28.0557 40.9431 -950.016 -0.531022 -0.403447 0.745148 -13.0119 36.3701 -979.89 0.465877 0.0820463 -0.881037 --21.5191 40.5085 -940.148 -0.951483 -0.0956311 0.292463 --28.7123 -21.4113 -975.769 -0.238465 -0.480364 -0.844029 --16.2706 -22.2768 -970.482 0.979075 -0.0492129 -0.19746 -21.0039 -23.9583 -960.851 0.646761 -0.0415978 0.761557 --28.1435 38.6935 -961.479 -0.527371 0.104178 0.843224 --21.7051 39.7191 -943.634 -0.943858 -0.105079 0.313194 --6.43704 35.4612 -935.724 -0.724457 0.582373 0.368788 --14.169 38.4955 -933.464 -0.319346 -0.164132 0.933316 --20.8143 39.4811 -938.423 -0.888284 -0.377106 0.262189 --24.9442 39.2543 -949.96 -0.878178 0.224807 0.422214 --15.2389 38.2157 -934.364 -0.626766 -0.448538 0.637164 --29.672 38.2449 -962.647 -0.868539 -0.151971 0.471746 --28.5461 37.8761 -961.807 -0.632997 -0.168182 0.755665 --11.7326 22.1626 -940.359 -0.334925 -0.861154 0.382412 --24.5071 38.9629 -947.365 -0.797262 0.430881 0.422746 --16.3487 37.9548 -937.2 -0.670619 -0.47676 0.568304 --22.2828 38.4693 -943.838 -0.635753 0.409931 0.654045 --20.8777 38.1316 -942.697 -0.456003 0.310997 0.833872 --22.862 37.7462 -943.85 -0.724454 0.433963 0.535576 --17.4878 -20.5469 -973.996 0.773752 -0.325077 -0.543721 --31.3063 -33.5335 -958.244 -0.967649 0.249866 -0.0349521 --15.3163 -38.7282 -947.814 0.933503 -0.157067 0.32234 --17.7458 36.4433 -940.049 -0.470732 0.405012 0.783822 --16.0498 24.1856 -936.941 -0.613159 -0.774717 -0.154433 --21.0509 37.0935 -941.909 -0.320684 0.572844 0.754328 --16.174 35.896 -938.744 -0.733656 -0.3416 0.587417 -3.92308 23.771 -941.534 0.422833 -0.403641 0.811348 --21.1969 -29.1669 -973.154 -0.226363 -0.25361 -0.940448 -18.508 36.3595 -970.419 0.686117 0.709877 -0.159115 --19.9744 -31.3972 -973.107 -0.204064 -0.0739127 -0.976163 --17.199 25.4987 -932.56 -0.598481 -0.417629 0.683671 --25.0333 36.6526 -946.688 -0.856721 0.256575 0.447434 --30.9966 -22.3507 -974.147 -0.452647 -0.550284 -0.701639 --21.9059 -31.2452 -972.221 -0.351406 -0.183618 -0.918041 --16.4272 35.3632 -938.888 -0.427153 0.322603 0.84467 --25.2803 35.4381 -953.333 -0.430932 -0.138566 0.891682 --19.136 35.1304 -939.979 -0.33808 0.531614 0.776588 --27.6297 -27.076 -971.778 -0.583863 -0.621161 -0.522746 --14.9276 -35.0689 -957.544 0.974703 -0.132716 -0.179836 --18.6658 -32.3894 -971.363 0.890664 -0.434122 -0.135117 --30.4295 36.4088 -954.004 -0.753214 0.407804 0.516104 --8.38607 25.4558 -929.316 -0.132805 0.0636343 0.989097 --21.5596 35.6718 -941.16 -0.420432 0.49617 0.759639 --21.2593 -26.9347 -973.834 -0.0181417 -0.304608 -0.952305 --22.7388 -47.4164 -948.815 0.283758 0.0433002 0.957918 --25.3027 -21.8345 -976.225 -0.140491 -0.470846 -0.870957 -20.2881 -23.8321 -960.32 0.478351 -0.0740792 0.875038 --28.543 35.988 -952.829 -0.166616 0.262401 0.950465 --23.0812 35.7509 -942.613 -0.830558 0.298192 0.470378 --16.5637 34.3731 -938.103 -0.229269 0.556873 0.798328 --30.7995 35.4915 -956.253 -0.96206 0.039927 0.269902 -12.6869 -47.9485 -956.738 -0.12247 0.616046 0.778131 --33.0476 -46.1369 -970.122 -0.968018 -0.248487 -0.0345568 --19.0767 -34.4994 -947.657 0.748179 -0.194573 0.634326 --20.07 -32.7756 -973.296 -0.0938624 0.742045 -0.663747 --22.6382 35.0256 -941.529 -0.704054 0.352954 0.616223 --29.8231 35.1921 -953.053 -0.578636 0.0138101 0.815469 --23.5228 34.8652 -942.886 -0.885256 0.167799 0.43378 --24.5876 34.6056 -945.476 -0.886456 0.0311639 0.461763 --28.6861 -24.4352 -973.677 -0.426592 -0.603459 -0.673689 --30.4184 -20.5607 -975.644 -0.445408 -0.43373 -0.783256 --25.8597 34.5226 -947.401 -0.886731 0.115676 0.447579 -20.5669 -47.7882 -955.607 -0.218299 0.212674 0.952426 --25.4974 32.9789 -953.25 -0.93182 0.349065 0.0993226 --16.7993 -20.4655 -972.591 0.937434 -0.173707 -0.301733 --19.1463 -33.177 -971.754 0.78671 -0.614477 0.059203 --29.8068 33.9515 -953.454 -0.871922 -0.324654 0.36654 --23.7444 33.3517 -943.258 -0.927837 -0.0935033 0.361076 --26.2034 33.7022 -948.027 -0.928264 -0.0275952 0.370896 --22.0619 33.6184 -940.331 -0.645194 0.263824 0.717023 --19.8216 33.0822 -938.855 -0.411637 0.539633 0.734405 --22.9827 33.3111 -941.552 -0.864235 -0.0168355 0.502807 --5.36427 29.0936 -930.867 -0.300941 0.0545506 0.952081 --30.6406 -31.6687 -962.88 -0.980499 -0.0565782 -0.188205 --24.2017 32.5057 -945.164 -0.86593 -0.307538 0.394445 --23.2884 32.4171 -942.638 -0.855942 -0.358232 0.372871 --26.1855 32.3938 -948.357 -0.943906 -0.183568 0.274489 --25.0317 -48.117 -948.721 -0.19069 -0.429187 0.882857 --25.4039 32.3237 -946.994 -0.812658 -0.259303 0.521871 --16.3838 -23.1466 -970.667 0.963953 -0.156209 -0.21539 --31.7332 -34.4586 -951.228 -0.962065 0.27148 0.0270225 --25.2198 31.525 -947.253 -0.689846 -0.513148 0.510677 --19.826 -26.3897 -973.806 0.20838 -0.246151 -0.946566 --20.9046 31.5566 -938.794 -0.876754 -0.127772 0.463655 --27.6731 28.5346 -967.033 -0.531786 0.315356 0.785974 --25.9232 31.1499 -948.794 -0.796469 -0.450529 0.403312 --22.6303 -21.6492 -976.325 0.204475 -0.427582 -0.880547 --17.8977 -27.3637 -972.329 0.857063 -0.16121 -0.48934 --26.109 31.0378 -949.707 -0.960533 -0.261647 0.0944355 --24.554 30.5848 -947.741 -0.785614 -0.40875 0.464473 --10.9016 28.4133 -932.279 -0.307769 0.662477 0.682936 --28.5062 28.1818 -967.573 -0.856961 0.292579 0.424282 --29.5419 -22.7814 -974.595 -0.316327 -0.546792 -0.775213 --27.5886 28.9978 -959.27 -0.590782 0.37049 0.716738 --24.4709 30.0633 -947.586 -0.937527 0.157732 0.310103 --22.5554 29.9948 -943.77 -0.62714 0.546195 0.555308 --24.6088 -20.1013 -977.237 -0.0385157 -0.458034 -0.8881 --26.4934 28.5483 -958.487 -0.651982 0.0254704 0.757807 --24.6641 29.545 -948.666 -0.954229 -0.207429 0.215453 --20.0465 30.2759 -936.305 -0.940909 0.165254 0.295604 --18.2457 30.7479 -932.891 -0.594525 0.611738 0.52184 --17.8288 30.3683 -932.104 -0.519671 0.446485 0.728419 --25.6322 27.9933 -957.565 -0.794668 -0.02449 0.60655 -14.5379 -47.8167 -956.788 -0.227851 0.550145 0.803383 --23.3934 29.4949 -944.422 -0.664293 0.590611 0.458141 --25.3269 -37.8623 -999.444 -0.0685013 -0.997111 0.0328309 --14.7659 -34.0391 -956.189 0.998866 0.0184038 -0.0439075 --19.0987 30.0531 -933.601 -0.863175 0.0815793 0.49827 --10.876 27.4453 -931.014 -0.359341 0.677667 0.641593 --23.4846 28.8696 -945.068 -0.708932 -0.663654 0.238703 --20.0782 29.2767 -936.711 -0.966426 -0.180358 0.183009 --19.6596 29.775 -934.913 -0.947895 -0.0164165 0.318159 --18.1826 29.6429 -932.336 -0.725704 0.0276778 0.68745 -19.2528 -50.0164 -961.651 0.005386 -0.953588 -0.301065 --23.3628 29.0251 -944.181 -0.849568 -0.179766 0.495902 --16.5818 -22.9189 -971.386 0.912262 -0.138988 -0.385305 --12.643 27.5028 -931.651 -0.0438522 0.666496 0.744218 --24.5085 28.0617 -950.103 -0.859491 -0.220594 0.4611 --19.9869 28.6678 -937.26 -0.912973 -0.395688 0.0995531 -22.5775 -50.4345 -956.287 0.600652 -0.150525 0.785213 --21.2703 -17.8392 -978.153 0.229504 -0.573927 -0.786089 --23.861 -16.5694 -979.025 -0.102064 -0.461242 -0.881385 --26.5437 27.1644 -957.83 -0.374666 0.359399 0.854668 --17.5655 -22.4796 -973.276 0.754116 -0.20841 -0.622795 --17.8854 28.7039 -932.303 -0.665119 -0.315529 0.6768 -12.8909 -40.8381 -972.334 -0.878224 0.146931 -0.45512 --25.4644 26.6202 -957.329 -0.421203 0.0882837 0.902659 --14.8221 -36.2815 -949.588 0.995962 -0.0787867 0.0430355 --19.1776 28.5253 -934.376 -0.851052 -0.301689 0.42976 --12.4312 26.4209 -930.569 -0.078386 0.552088 0.830093 -12.2309 14.2354 -992.552 0.488117 0.500392 -0.715087 --24.8741 25.5614 -956.737 -0.919863 -0.164202 0.356215 --17.3986 27.1284 -933.362 -0.75733 -0.0425669 0.651644 --29.5373 26.686 -958.579 -0.690023 0.299941 0.658714 -8.70449 26.7237 -942.543 0.44779 -0.878821 -0.164799 --19.4187 -30.7976 -973.202 0.175219 -0.113517 -0.977963 --19.1275 25.1871 -947.632 -0.374529 0.30894 0.874234 --20.0371 26.8463 -939.165 -0.785393 0.338383 0.518319 --13.6163 26.0988 -930.411 -0.143936 0.353915 0.924135 --25.7681 -18.3513 -977.85 -0.255832 -0.34438 -0.903301 --25.4556 26.5247 -951.198 -0.802737 -0.088678 0.589703 --15.7785 26.8956 -931.694 -0.633585 0.129229 0.762804 --29.2857 26.1077 -958.171 -0.450555 0.207285 0.868351 --28.948 -33.2516 -949.255 -0.201806 0.481114 0.853114 --28.3519 26.1566 -957.84 -0.226697 0.212968 0.950396 --22.0125 -28.7601 -973.074 -0.249126 -0.391394 -0.88586 --30.3193 -17.7415 -977.283 -0.499739 -0.531235 -0.684142 --18.2216 26.7263 -935.084 -0.867477 -0.304851 0.393128 --15.1469 26.1127 -930.792 -0.500843 0.154395 0.851657 --23.4752 -28.0172 -973.007 -0.256544 -0.525245 -0.811359 --18.8759 26.0176 -936.283 -0.950294 -0.0798096 0.300951 --17.368 26.6247 -933.203 -0.599917 0.275704 0.751057 --23.5968 -25.3536 -974.417 -0.0862934 -0.447802 -0.889959 --30.3987 25.4179 -959.144 -0.779186 -0.0349403 0.625818 --24.3616 25.2358 -950.544 -0.873399 -0.185603 0.450251 --23.3114 25.2025 -948.339 -0.448472 0.228243 0.864163 --19.841 24.149 -946.853 -0.105533 0.667153 0.737407 -11.1096 -30.2822 -972.091 -0.873161 -0.228042 -0.430798 --15.7872 24.4017 -938.185 -0.500377 -0.850165 -0.163837 --29.6328 -19.0902 -976.75 -0.426778 -0.421968 -0.799877 --25.7814 25.4696 -952.228 -0.949587 -0.155047 0.27248 --29.1142 24.7977 -958.038 -0.627706 -0.0972471 0.772352 -18.6907 -20.128 -1025.67 0.0169565 0.775833 -0.630711 --30.4537 -30.6897 -961.346 -0.979022 0.146329 0.14179 --18.387 25.5113 -934.465 -0.819784 -0.491793 0.293419 --3.93571 19.9555 -937.763 -0.14645 -0.104618 0.98367 --31.1809 24.8106 -960.452 -0.998603 -0.00553924 0.0525421 --22.1119 -17.4249 -978.58 0.0990046 -0.48976 -0.866218 -19.2359 -48.4681 -956.305 0.0705223 0.289067 0.954708 -13.2553 46.5707 -974.074 0.431327 0.277131 -0.858577 -25.3988 -15.1543 -972.634 0.904161 -0.350333 -0.24446 --21.6824 23.5981 -946.756 -0.390412 0.483499 0.783458 -7.95104 -13.1577 -949.239 0.505072 -0.763733 0.402011 --26.432 -25.9513 -973.391 -0.285121 -0.566756 -0.772977 --30.5951 -33.9012 -963.014 -0.839141 0.0931013 -0.535887 --31.4508 -19.4165 -975.433 -0.812768 0.013317 -0.582435 --14.9136 -32.9846 -957.593 0.973465 0.225915 0.0364584 -10.9401 -35.423 -1000.9 -0.886587 -0.426936 0.178011 --13.9665 12.124 -1010.22 -0.72988 0.556029 -0.397625 --0.873921 21.6775 -937.808 0.493337 0.410915 0.76666 --14.8057 -33.6184 -953.457 0.961267 0.264546 0.0773359 --5.24804 19.3495 -937.675 -0.0922003 0.4547 0.885859 --8.58112 19.8856 -938.425 -0.418441 0.384324 0.822923 -3.93405 41.3805 -932.453 0.333667 -0.822032 0.461443 --23.1331 23.0019 -949.649 -0.803449 -0.571564 0.166684 --18.882 22.4401 -944.626 -0.185009 0.74297 0.643247 --14.6995 -34.977 -951.099 0.994327 -0.0339331 0.100813 --4.99401 18.863 -937.117 -0.101322 0.658902 0.745374 --27.1712 20.0253 -970.077 -0.503708 0.711481 0.489971 -12.0997 57.4539 -958.941 0.351024 0.829635 -0.434152 --22.4138 21.995 -949.105 -0.747993 0.0235324 0.663289 -25.6804 -35.9597 -1003.9 0.639157 -0.722163 -0.264496 -20.1083 -37.5129 -997.991 0.141428 -0.606817 0.782158 --30.3903 -31.2481 -958.528 -0.932517 0.359758 0.0314188 --29.1943 19.5348 -972.867 -0.965147 0.0686208 0.252551 -18.1355 18.1419 -971.404 0.70725 0.256415 -0.658824 --23.6163 21.7891 -950.053 -0.722143 -0.0252235 0.691284 --23.2355 19.4894 -962.237 -0.698016 -0.437575 0.566835 -14.6292 -48.6461 -956.468 0.0527337 0.262712 0.963432 --28.8261 19.0889 -972.259 -0.830504 0.2439 0.500775 -23.6691 -31.245 -1005.37 0.286167 0.943425 0.167503 --14.2758 20.8325 -939.625 -0.000711371 0.729817 0.683643 --9.97991 18.8916 -938.533 -0.338314 0.643277 0.686832 --8.47392 18.4867 -937.586 -0.219083 0.588689 0.778105 --24.0439 19.6754 -962.803 -0.214664 -0.580323 0.785586 --22.4361 18.9914 -961.24 -0.91311 -0.237579 0.33134 -21.8428 -12.2602 -1018.51 0.894959 0.160967 -0.416098 --13.0917 39.0512 -933.255 0.0498827 0.124949 0.990908 -22.5721 -25.5964 -1015.72 0.802464 -0.532114 0.270011 --22.4424 20.622 -948.683 -0.801328 -0.00332329 0.598216 --19.9106 20.6307 -945.371 -0.864312 -0.0548714 0.499954 -26.5084 -34.0176 -1001.89 0.508238 0.259579 0.821166 -23.8537 -31.9977 -1002.51 0.529199 0.81824 0.22457 -2.85703 -27.7134 -1030.72 0.184544 -0.613285 -0.768001 --15.2726 19.8704 -938.981 -0.249983 0.476882 0.84267 --25.6146 18.9794 -963.044 -0.138833 0.428784 0.892676 --17.5722 19.4316 -940.29 -0.631685 0.421998 0.650301 --11.5426 18.1339 -938.183 0.00520308 0.647604 0.761959 --29.2003 18.9193 -966.515 -0.816779 0.564119 0.121008 --21.9114 -13.0253 -987.947 -0.869219 -0.487321 0.0835238 --22.284 17.6453 -961.114 -0.847792 0.162435 0.50484 --29.2334 39.8804 -966.039 -0.792247 0.256514 -0.553666 -26.1774 -36.1493 -1002.13 0.853551 -0.518444 -0.0516457 --21.7892 17.9801 -958.36 -0.959505 -0.225243 0.16916 --20.9569 19.3095 -946.432 -0.833737 0.0167062 0.551908 --1.68016 33.4328 -982.203 0.182256 0.62528 -0.75882 --23.2393 17.3501 -962.183 -0.355746 0.214063 0.909737 --9.81297 37.7434 -981.286 -0.0522392 0.371281 -0.92705 --10.4947 17.2165 -937.175 -0.203167 0.303074 0.931058 --27.5616 18.609 -962.73 -0.19621 0.71063 0.675652 --31.662 -38.6195 -949.504 -0.332673 -0.928464 -0.165177 --17.6829 18.8582 -940.307 -0.843844 -0.244399 0.4777 -21.8226 -24.6042 -1012.53 0.540999 -0.694724 0.474003 -24.0656 -36.9207 -998.651 0.776474 -0.210708 0.593877 --16.6701 18.9262 -939.254 -0.553676 0.233441 0.799343 --26.1392 18.0284 -962.08 -0.0197727 0.510875 0.859428 --23.5201 16.6113 -962.098 -0.456376 0.444463 0.770827 -24.9638 -33.2723 -1001.61 0.460655 0.519015 0.720014 --22.1797 16.6193 -960.222 -0.826932 0.394535 0.400657 -26.87 -34.327 -1002.11 0.940503 0.0531529 0.335603 -24.5912 -32.98 -1001.44 0.860982 0.33594 0.38191 --27.432 18.211 -962.424 -0.141852 0.435253 0.889063 -5.7612 54.9965 -965.561 0.190219 0.860503 -0.472601 -18.8918 28.4624 -960.179 0.793998 -0.119 0.59616 --15.8316 18.1134 -938.634 -0.358182 0.202244 0.911484 -20.9746 30.1217 -967.526 0.642003 0.572863 -0.509569 --23.2588 16.3912 -961.681 -0.665326 0.493932 0.559796 -10.7445 -33.8644 -1002.49 -0.902569 0.407864 0.137899 --21.6591 16.3144 -958.354 -0.945575 0.149847 0.288849 --20.9697 17.1956 -955.069 -0.907609 -0.386683 0.163471 -10.3072 -27.4993 -1005.83 -0.159703 0.135534 0.977817 -11.189 -35.4382 -1002.79 -0.904754 -0.403611 -0.13608 --28.0656 17.5739 -962.199 -0.361493 0.616968 0.699052 --24.2961 16.2618 -962.014 0.0239747 0.360953 0.932276 --18.997 17.6803 -943.65 -0.85084 -0.149799 0.503619 --16.0823 17.6662 -938.697 -0.608614 -0.120476 0.784267 --14.4633 16.91 -937.95 -0.344246 -0.0985778 0.93369 -17.8925 -34.4196 -997.508 0.0389106 0.0935399 0.994855 --19.1507 -15.8028 -959.098 0.671811 -0.318945 0.668539 --26.1417 16.3544 -961.6 0.0796613 0.261019 0.962041 -25.041 -37.114 -1001.13 0.612675 -0.77468 0.156528 --20.8786 15.7972 -956.135 -0.935122 0.0393291 0.352136 -25.7206 -35.0416 -1005.58 0.911233 -0.386711 -0.141808 --17.4959 17.6401 -941.372 -0.8889 -0.215254 0.404379 --22.6145 -37.4559 -999.102 0.0805823 -0.242971 0.966681 --25.3866 15.7236 -961.596 0.0313016 0.249326 0.967913 --18.7448 -33.0865 -966.282 0.671235 -0.623829 -0.400351 --18.9319 -14.1774 -1029.32 -0.621123 0.690742 -0.370246 -23.4309 -31.5707 -1003.51 0.224684 0.95247 0.205712 --17.9615 17.0593 -942.014 -0.826824 -0.163146 0.538281 --17.068 17.0832 -940.998 -0.800722 -0.312666 0.510963 -26.6893 -33.1315 -1003.09 0.899353 0.422577 0.112219 --29.2747 16.6125 -962.258 -0.590768 0.321563 0.739994 --23.0773 15.1483 -960.044 -0.728762 0.519162 0.446516 -24.6138 -36.7231 -1000.21 0.788587 -0.349316 0.506072 --21.8077 -34.4681 -998.965 0.0833017 0.0969796 0.991794 -24.4692 -35.8882 -1000 0.841847 0.146624 0.519417 -23.9647 -37.4453 -1000.05 0.496531 -0.863689 0.0865947 --19.9251 15.6136 -953.223 -0.910617 -0.316023 0.266282 -19.24 29.3264 -958.579 0.977079 0.0606583 -0.204052 --14.9486 27.2949 -931.264 -0.253389 -0.0276859 0.966968 -21.3593 -30.5703 -1001.19 0.293551 0.943318 0.154853 -18.4911 -25.0299 -1010.29 0.592469 -0.291118 0.751153 --28.1425 15.5652 -961.36 -0.229096 0.207519 0.951026 -21.5417 -25.8818 -1013.61 0.881598 -0.145718 0.448944 --25.7955 14.6498 -961.172 -0.33081 0.558861 0.76042 --13.9794 23.681 -934.007 -0.259013 -0.783661 0.564613 --5.28382 11.2761 -942.613 -0.666719 -0.15898 0.728156 --19.5145 -16.5264 -958.378 0.545938 0.221496 0.808017 -18.2743 -36.7737 -997.237 -0.00193563 -0.451517 0.89226 --20.8926 13.7764 -954.766 -0.784501 0.404656 0.469907 --15.55 14.9191 -939.821 -0.580208 -0.409214 0.704204 --14.3521 14.7731 -939.167 -0.340564 -0.432667 0.834755 --24.2843 13.7235 -959.684 -0.327145 0.695633 0.639586 --31.4565 15.3849 -963.805 -0.926971 -0.0948297 0.362949 --19.0598 14.0738 -951.648 -0.884705 0.108091 0.453447 --30.7652 14.7935 -963.374 -0.782418 -0.0317621 0.621943 --26.0221 13.8077 -960.255 -0.41755 0.76434 0.491362 --14.8375 25.7714 -930.706 -0.399657 -0.487231 0.776454 -3.30068 -34.6659 -1009.31 0.168062 -0.95718 0.235716 -19.599 -34.368 -997.92 0.530984 0.317534 0.785639 --17.6348 38.8276 -936.578 -0.106813 -0.911098 0.39811 --27.0708 13.7014 -961.342 -0.279228 0.026699 0.959853 -11.9684 -30.7512 -1003.91 -0.766361 0.482151 0.424525 --30.4008 14.227 -962.634 -0.807834 -0.144424 0.571443 -10.6869 -34.5815 -1002.32 -0.962372 -0.252802 -0.0996554 --29.5421 13.6541 -961.808 -0.630889 -0.34712 0.693892 --28.8385 13.9845 -961.475 -0.251218 -0.120148 0.960445 --26.8038 13.2783 -961.028 -0.751877 0.442997 0.488298 --18.2126 13.3918 -950.06 -0.907872 -0.0252248 0.418489 --23.6686 -39.4531 -948.077 0.0367546 -0.663759 0.747043 --19.6794 13.0839 -952.224 -0.788173 0.297012 0.539043 -19.6913 -25.5796 -1011.27 0.642675 0.515489 0.56678 --6.69192 9.67797 -944.098 -0.316628 0.0517789 0.947136 -21.5889 -25.4857 -1013.39 0.739244 -0.510535 0.439173 -14.6971 -31.5458 -999.07 -0.396728 0.698721 0.595312 -22.6406 -31.3361 -1000.09 0.369948 0.87008 0.325729 -23.8064 -34.5034 -999.037 0.867511 0.111862 0.484677 -21.2244 -36.6805 -997.733 0.155625 -0.198293 0.967709 --22.1454 32.7621 -972.787 -0.706536 0.542359 0.454591 --23.989 12.4936 -957.899 -0.623584 0.594318 0.507866 -11.2894 -28.2664 -1005.75 -0.283839 0.0656188 0.956624 -10.9916 -32.1526 -1005.36 -0.918589 0.0340086 0.393749 --3.18142 9.01235 -942.104 0.237435 0.130944 0.962537 -20.2935 -21.8942 -977.977 0.0308781 -0.154793 -0.987464 --15.4534 -31.9833 -955.219 0.758529 0.618068 0.20646 --5.64837 8.95574 -943.505 -0.703547 -0.0191485 0.710391 --19.3082 12.3284 -951.155 -0.667628 0.475411 0.572937 -26.4216 -35.5228 -1001.8 0.755991 -0.119372 0.643605 --17.2226 12.0351 -947.645 -0.950005 0.0744733 0.303223 --16.4816 12.3045 -945.9 -0.922876 -0.174355 0.343366 --15.5875 11.9953 -943.685 -0.729457 -0.326864 0.600876 --7.64449 8.9277 -944.185 -0.193577 0.231973 0.953266 --5.82038 8.51763 -943.587 -0.472666 0.1651 0.865638 --24.6394 11.8226 -957.763 -0.249535 0.651887 0.716084 -21.0626 -30.7318 -1000.35 0.161979 0.864192 0.476377 --21.9361 11.636 -953.837 -0.699371 0.513334 0.497361 --17.7988 11.4323 -949.009 -0.793445 0.330456 0.511121 --24.1813 11.477 -957.021 -0.69662 0.468476 0.543371 --17.1186 11.3212 -947.029 -0.900467 0.376687 0.217406 -11.4281 -31.8702 -1004.05 -0.941683 0.282608 0.182662 -11.7809 -30.2731 -1004.7 -0.886772 0.3593 0.290755 -20.1258 -31.9566 -999.432 -0.0138702 0.491188 0.870943 -15.988 -30.4237 -1000.73 -0.277169 0.847058 0.453508 --16.072 11.0089 -944.73 -0.803052 0.0912529 0.588881 --15.5346 10.8782 -944.153 -0.395264 -0.301387 0.867717 -20.6805 -25.3203 -1012.14 0.701877 -0.212413 0.67989 -15.1342 -24.1624 -1028.52 -0.574821 0.586833 -0.57027 --17.7329 10.7429 -948.246 -0.783994 0.566974 0.252772 -17.5943 -23.1838 -1008.13 0.0175063 -0.761889 0.647471 -10.1272 -28.6827 -969.097 -0.975775 -0.207502 -0.0693204 --5.32557 7.17279 -942.877 -0.741926 0.0111453 0.670389 -16.3688 -24.604 -1008.9 0.393689 0.29286 0.871345 -15.9241 -29.1876 -1003.08 -0.061407 0.785019 0.616421 -18.6827 -31.7079 -998.11 0.278379 0.711887 0.644765 --5.60901 6.83605 -943.047 -0.273133 0.251429 0.928538 --10.5671 8.32782 -944.462 -0.16922 0.301801 0.938233 --26.3375 11.2567 -956.855 -0.0925616 0.737567 0.6689 --21.0454 10.4777 -951.565 -0.693586 0.441516 0.569212 --18.6113 10.0689 -948.891 -0.732182 0.543421 0.410614 -14.2096 -24.7234 -1007.63 0.415442 0.438785 0.796791 -20.2843 30.5758 -968.547 0.946131 0.306809 -0.103458 -19.7131 -30.6869 -1000.48 -0.248452 0.725514 0.641795 -14.1034 -29.5412 -1002.91 -0.228687 0.778424 0.584601 -13.5283 -28.5521 -1004.24 -0.397422 0.580952 0.710318 --15.9676 9.70483 -944.424 -0.374546 -0.0401566 0.926338 -23.5014 -36.2177 -998.075 0.543006 0.014774 0.839599 --4.93921 5.79864 -942.637 -0.770989 0.0806037 0.631727 --24.6282 9.49502 -955.811 -0.378391 0.583922 0.71823 --15.3027 -33.2076 -951.019 0.828454 0.522889 0.200626 -13.8279 -24.1645 -1007.52 0.595603 -0.0419937 0.802181 -20.4396 -24.2139 -1010.6 0.363938 -0.768528 0.526226 --4.36371 5.54739 -941.815 -0.8204 -0.120602 0.558927 --27.7286 10.1766 -956.553 -0.703914 0.556097 0.441883 -21.1561 -34.7969 -998.157 -0.240708 0.293447 0.925175 --12.98 7.80011 -944.741 -0.165425 0.187829 0.968171 --26.2167 9.98092 -955.547 0.191354 0.667992 0.719145 --17.6264 8.98764 -945.342 -0.718792 0.14884 0.679106 --5.18283 4.94445 -942.515 -0.367986 0.343066 0.864229 -11.6219 -26.9949 -1005.88 -0.15213 0.2603 0.953468 --27.1861 9.96296 -955.879 -0.401234 0.625039 0.669579 --23.2054 34.2709 -975.744 -0.926803 0.346445 0.144952 -12.7291 -24.9326 -1006.59 0.524955 0.118797 0.842799 -12.0488 -24.7988 -1006 0.59459 -0.294494 0.748155 -13.0668 -26.1076 -1006.33 0.220073 0.364767 0.904717 --15.8928 -30.0724 -958.535 0.864322 0.454281 0.215814 -14.4481 -26.3644 -1006.3 0.0530264 0.677087 0.73399 -23.0655 -35.609 -997.995 0.177043 0.0770144 0.981185 -10.6641 -31.0137 -970.316 -0.966716 -0.217717 -0.134387 -18.2677 -30.3938 -1001.13 0.135747 0.920924 0.365338 --23.1079 8.05224 -952.643 -0.754331 0.392028 0.526591 --8.81532 5.39836 -942.935 -0.147777 0.335434 0.930401 --26.2198 9.03447 -954.71 0.167574 0.652206 0.739287 -5.46628 37.991 -983.075 0.41713 0.369068 -0.830537 --14.303 6.50153 -944.659 -0.262002 0.277245 0.924386 -5.94655 -10.0732 -1027.2 0.284553 0.199456 -0.937682 -13.7789 -10.5199 -1027.89 0.117871 0.399319 -0.909203 --26.8317 8.55624 -954.435 -0.293853 0.581006 0.759001 --19.4333 7.63411 -947.775 -0.802876 0.304455 0.512541 -8.92618 -11.6492 -1032.7 0.0346959 0.931005 -0.363354 --18.8008 7.81869 -946.266 -0.737465 -0.0200481 0.675088 -16.603 -35.8445 -997.276 -0.182295 0.0224998 0.982986 -1.0252 34.3212 -934.944 0.491056 0.836151 0.244369 -5.20613 -12.3225 -1032.74 -0.133999 0.684813 -0.716293 --24.9289 6.97604 -953.797 0.237093 0.679939 0.69388 -12.0873 -3.20588 -1024.5 0.213752 0.25128 -0.944017 -4.39272 -10.5081 -1031.57 0.830741 0.401037 -0.386056 --17.275 6.58732 -945.722 -0.379532 0.00473823 0.925166 -10.4717 -11.9047 -1032.36 0.483818 0.811046 -0.328822 --16.1385 -32.6141 -950.253 0.602212 0.718843 0.347284 -4.91462 -8.41645 -1030.5 0.744192 0.42706 -0.513613 --27.7752 7.68354 -956.536 -0.945599 0.146909 0.290276 -8.04457 -7.9465 -1026.2 0.447082 -0.231396 -0.864045 --27.5895 7.31812 -954.074 -0.679096 0.359457 0.640015 --23.1044 6.22149 -951.273 -0.772144 0.328825 0.543754 --18.9764 6.44686 -946.737 -0.659901 0.130151 0.739994 --24.2954 5.77298 -952.526 -0.15049 0.695938 0.702156 --20.9237 6.52989 -948.726 -0.705368 0.348012 0.61753 -10.6271 27.7543 -943.599 0.445791 -0.838217 -0.314107 --28.7204 -27.2727 -958.335 -0.80861 0.0919054 0.581123 -5.6371 -5.16178 -1030.97 0.332931 0.0359675 -0.942265 --3.88607 54.615 -970.6 0.375908 0.664614 -0.645741 --28.1645 7.17124 -956.923 -0.707734 0.115844 0.696916 -6.00161 -8.9804 -1027.53 0.780005 -0.428549 -0.456002 --6.30075 2.61925 -941.945 -0.183706 0.181298 0.966118 --9.91855 38.9709 -934.931 0.339432 -0.627235 0.700972 -12.1154 -27.8843 -1028.39 -0.276562 -0.144118 -0.950128 -2.98507 -13.448 -1032.99 0.0255823 0.447464 -0.893936 --2.83019 56.2923 -965.714 0.135258 0.902011 -0.409978 --25.5473 5.77113 -952.239 0.0421726 0.652575 0.75655 --23.6773 4.67183 -951.24 -0.469679 0.506722 0.722934 -10.6792 -4.37651 -1027.43 0.998509 -0.0429205 -0.0337172 -20.0128 25.3721 -964.064 0.236273 -0.898212 0.370663 --19.165 4.9372 -946.295 -0.623512 0.265486 0.735357 --11.8139 2.95096 -942.646 -0.209954 0.30596 0.928605 -10.7035 -4.24423 -1025.09 0.623154 0.350149 -0.699339 --28.9792 40.4455 -962.845 -0.65513 0.598812 0.460684 --5.43886 40.5722 -931.362 -0.111642 0.0568132 0.992123 --20.7706 4.55153 -947.692 -0.734715 0.203444 0.647151 -4.76542 -10.7929 -1031.33 0.450268 0.878902 -0.157447 -8.89618 -11.3061 -1031.4 0.0724908 0.98011 -0.184743 --17.2691 3.44413 -944.629 -0.457561 0.261738 0.849783 --27.955 5.24534 -955.368 -0.703481 0.317547 0.635828 --26.4249 5.72615 -952.362 -0.455606 0.409501 0.7904 --13.2347 2.66956 -942.912 -0.27751 0.289095 0.916195 -5.3393 -8.56135 -1029.44 0.846945 -0.288877 -0.446356 -5.64145 -5.97813 -1030.79 0.724097 -0.2721 -0.633754 --20.1028 -18.4334 -997.06 -0.561309 -0.767708 0.309122 -5.42103 -11.2777 -1031.73 0.268111 0.771855 -0.576504 --27.657 4.63404 -954.885 -0.775939 0.0963309 0.623409 -7.15968 -11.6225 -1028.76 -0.102021 0.985612 -0.134761 --17.162 -31.1531 -952.774 0.431646 0.823699 0.367698 --22.079 2.78681 -949.074 -0.693178 0.201864 0.691921 --29.8736 4.66807 -957.449 -0.809678 0.316419 0.494268 -9.46488 -7.06357 -1025.96 0.608551 -0.504933 -0.612135 --22.912 2.81406 -949.621 -0.254364 0.540577 0.80192 --20.9655 2.53922 -947.48 -0.770348 0.0892811 0.631342 -19.1624 -16.1756 -1022.22 0.882414 -0.356214 -0.307338 --26.5973 3.76259 -952.306 -0.886059 -0.159707 0.435193 -11.3403 -5.08467 -1024.39 0.591979 -0.116615 -0.797472 -20.4779 32.6716 -959.03 0.484312 -0.851389 0.201441 --19.6169 2.85985 -946.104 -0.675253 0.129944 0.72605 --15.8743 36.2798 -937.405 -0.674845 -0.491585 0.550389 --27.1691 17.6942 -976.328 -0.448608 -0.459855 -0.766345 -20.8679 -35.7769 -974.941 0.490497 -0.188845 -0.850735 --18.5668 2.52553 -945.19 -0.57137 0.163299 0.804282 --24.8458 3.13045 -950.287 -0.474763 0.398986 0.784481 -7.21122 -11.3604 -1031.24 0.0451829 0.982829 -0.178904 -9.69677 -11.1545 -1029.41 -0.122258 0.978323 -0.167141 --22.3157 1.63459 -948.798 -0.267584 0.517325 0.81288 --15.4642 1.39692 -943.307 -0.35194 0.238134 0.905224 --28.8091 38.372 -956.142 -0.651994 0.756018 -0.0578044 -6.23115 -11.55 -1028.53 0.345633 0.936558 -0.0582925 --27.0808 2.97054 -954.258 -0.567797 0.0330588 0.822505 --20.4104 1.26025 -946.722 -0.729879 0.0355927 0.682649 --13.8058 40.9021 -933.752 -0.16306 -0.344069 0.924677 --17.2639 1.74012 -944.207 -0.494723 0.136884 0.858202 --13.7938 0.767813 -942.566 -0.281525 0.177194 0.943051 -19.178 32.4841 -957.608 0.63446 -0.62585 0.453621 -17.1737 -25.752 -1032.77 -0.332806 0.0271109 -0.942606 -10.0866 -4.00065 -1029.39 0.822108 0.0754607 -0.564309 -10.5655 -4.64569 -1025.75 0.942309 0.288216 -0.170253 -20.3956 29.2095 -968.953 0.719344 -0.182187 -0.670337 --24.8773 2.38518 -950.049 -0.835963 0.000275395 0.548786 -6.93766 -8.30117 -1026.95 0.639386 -0.481761 -0.599243 -3.07951 5.57617 -1017.4 0.71036 0.70241 -0.0448166 --14.9736 56.9931 -963.455 -0.250416 0.132282 -0.959059 -9.9507 -4.88351 -1029.03 0.735723 -0.522244 -0.431246 -10.4099 -30.5 -967.072 -0.975555 -0.219738 -0.00287861 -10.5509 -4.61733 -1027.95 0.926162 -0.267256 -0.266081 --17.3718 -32.8562 -948.433 0.426312 0.692177 0.582365 --14.7448 24.1532 -933.658 -0.267033 -0.861589 0.431692 --29.5063 2.20903 -955.95 -0.700764 0.148568 0.697752 --23.474 1.30355 -948.424 -0.227458 0.546728 0.805824 -9.92013 -6.09214 -1026.74 0.790717 -0.55611 -0.255946 -10.1288 -47.0182 -964.291 -0.966206 0.175574 0.188731 --28.4819 2.11091 -955.03 -0.608101 0.102541 0.787209 --20.956 0.100519 -947.156 -0.476071 0.346987 0.808057 --18.5421 0.0185632 -944.915 -0.634418 0.0311278 0.772363 -10.4563 -5.79105 -1025.63 0.867059 -0.325839 -0.37688 --24.165 0.935662 -948.716 -0.821275 0.0373781 0.569307 -9.19388 -5.77666 -1028.77 0.571093 -0.725867 -0.383367 --23.5569 0.52161 -948.16 -0.756044 0.0308374 0.653793 --20.7107 -0.717178 -946.655 -0.192482 0.539685 0.819568 -7.64065 -5.63591 -1030.55 0.231744 -0.494782 -0.837547 --20.6516 21.2057 -983.183 -0.0333558 -0.728304 -0.684442 --16.9223 -1.30934 -943.68 -0.548308 -0.0187058 0.836067 --18.2435 -1.7348 -944.77 -0.582954 0.0931311 0.80715 -14.5367 -22.8843 -1027.28 -0.07335 0.509279 -0.85747 --19.3985 -1.78184 -945.535 -0.311184 0.489201 0.814768 --30.1536 0.111019 -956.346 -0.803394 0.0534801 0.593041 -19.9061 24.8902 -964.989 0.748352 -0.299378 0.591897 --28.0115 -0.0687747 -954.47 -0.522042 0.0544904 0.851177 --15.8515 26.2243 -983.203 -0.883283 0.421539 -0.205223 --15.587 -2.45332 -942.991 -0.426025 -0.0546687 0.903058 --4.82453 28.4843 -987.803 -0.0172026 -0.284199 -0.958611 --12.2457 23.1125 -987.215 -0.21477 0.790858 0.573077 --22.6988 -1.38438 -946.909 -0.811005 -0.0786785 0.579725 -12.1999 -33.3158 -999.572 -0.71831 0.458913 0.522904 --30.6667 -0.626123 -957.096 -0.875269 -0.039036 0.482058 --16.4262 -3.10989 -943.624 -0.471961 0.033242 0.880993 --22.9642 -1.80654 -947.696 -0.883643 -0.338671 0.32323 --28.7784 -1.19074 -955.047 -0.65356 -0.0278399 0.756362 -0.147653 -18.5439 -942.246 0.607374 -0.318579 0.727739 --18.0261 -3.1981 -944.126 -0.276718 0.396134 0.875502 --26.7107 -1.2813 -950.89 -0.607953 0.72361 0.326774 --3.27873 27.6577 -987.505 0.0449818 -0.384492 -0.922032 --20.4057 -2.6424 -945.019 -0.269349 0.461299 0.845372 --10.3927 22.3994 -987.57 0.627059 0.742527 -0.235479 -16.7309 -22.1691 -1027.46 -0.320806 0.742185 -0.588426 --11.0827 22.4813 -986.305 -0.280043 0.919243 0.27671 --21.2627 -2.48383 -945.488 -0.551798 0.137883 0.822501 --18.0031 17.7993 -980.114 -0.611141 0.568523 -0.550716 --11.9371 20.8275 -983.141 -0.733486 0.629646 -0.256018 --21.7765 -2.84806 -945.98 -0.737326 -0.146888 0.659375 --11.2905 23.1638 -988.573 0.569744 0.800162 -0.187434 --11.8622 22.3058 -986.409 -0.386697 0.426131 0.817849 --1.53287 -9.61709 -941.149 0.26253 -0.249392 0.932138 --22.1928 -2.95395 -946.878 -0.830221 -0.466479 0.305172 -17.5958 -26.0818 -1032.8 0.0794434 -0.285264 -0.955151 -21.5661 -19.2075 -961.263 0.752598 0.0105101 0.658396 --7.89321 29.1148 -987.555 -0.342668 -0.289676 -0.893681 --25.9941 32.1718 -951.577 -0.97108 0.198079 -0.133296 --25.4289 -2.45057 -949.576 0.0231556 0.214992 0.976341 --4.4633 -8.64763 -941.28 0.0537137 0.471108 0.880439 --8.64951 27.5599 -986.142 -0.274229 -0.542566 -0.79399 --26.811 -2.26755 -950.066 -0.474005 0.476746 0.740292 --8.82815 26.6537 -985.381 0.0986867 -0.42863 -0.898074 --3.48937 -8.91314 -941.055 -0.099159 0.315347 0.943782 -21.0026 25.5027 -965.273 0.297863 -0.93533 -0.190882 --9.29154 -7.63171 -941.64 0.0250041 0.358174 0.93332 --5.70323 -8.75267 -941.08 0.0802365 0.15693 0.984345 --27.676 -2.46831 -950.569 -0.635202 0.619851 0.460764 --29.5342 -3.03291 -956.086 -0.741485 -0.13769 0.65669 --29.0865 -2.78138 -955.558 -0.591601 -0.188946 0.783778 --28.7555 -11.4354 -1020.5 -0.865846 -0.161165 -0.473643 --13.3272 -6.19361 -942.179 -0.057387 0.321678 0.945108 -12.0071 -47.6681 -957.174 -0.350033 0.631232 0.692115 --7.89804 -8.54649 -941.114 -0.0152929 0.325193 0.945524 --19.8397 16.5842 -978.599 -0.731375 0.560333 -0.388738 --1.84234 10.0959 -943.09 0.890902 -0.237072 0.387415 --22.2017 17.8332 -977.617 -0.0143998 -0.441582 -0.897105 --19.9503 -4.61375 -944.69 -0.698996 -0.543891 0.464313 --19.2595 -4.67833 -944.02 -0.611721 -0.173477 0.771819 --24.1431 21.3796 -977.787 -0.882677 0.377113 -0.280477 --18.3991 -4.66433 -943.515 -0.400979 0.113522 0.909026 --28.7342 -29.6446 -956.82 -0.654867 0.622499 0.428537 --2.68187 -10.1567 -940.747 0.287667 0.13184 0.948613 --6.99629 -8.90948 -941.031 -0.0623126 -0.243042 0.968012 --3.34454 -10.5467 -940.849 -0.492888 -0.0636641 0.867761 --28.2941 -2.96598 -950.862 -0.891508 0.400276 0.212114 --22.896 -49.7795 -950.898 0.0707014 -0.362974 0.929113 --6.74877 36.8038 -936.765 -0.607647 -0.154199 0.779095 --10.9723 -8.03269 -941.391 -0.0856165 0.177837 0.980328 --20.3597 17.6971 -977.65 -0.540385 -0.33554 -0.771619 -3.37789 39.8265 -935.719 0.261575 -0.612462 0.745969 --28.0657 -3.25165 -950.244 -0.727388 0.237695 0.643745 --3.93194 -10.664 -941.451 -0.773206 -0.355619 0.52506 --18.7499 17.7456 -979.409 -0.69648 0.146233 -0.702518 -11.9095 26.0665 -938 0.437082 -0.843289 -0.312766 --31.3527 -4.17483 -958.903 -0.894157 -0.110141 0.433996 --28.4596 -3.95649 -951.193 -0.907298 0.19703 0.371469 --17.2224 -6.2855 -943.164 -0.569213 -0.444302 0.691804 -1.40666 -15.8975 -944.512 0.985699 0.139495 0.0945474 --5.44766 27.0203 -986.679 -0.157462 -0.63461 -0.756622 --15.678 -6.78581 -942.422 -0.461747 -0.401288 0.791048 --11.7333 -8.5563 -941.631 -0.242958 -0.501505 0.83034 --19.0901 -32.7509 -969.945 0.633774 -0.767924 0.0928605 --10.1102 22.3908 -986.729 0.234397 0.812329 -0.534023 --32.1562 -4.74343 -961.136 -0.965041 -0.0577181 0.255666 --20.4347 -6.14762 -948.64 -0.783468 -0.358693 0.507461 --23.1736 -27.6688 -955.218 -0.193247 0.505143 0.841122 --20.2605 -52.3665 -952.022 0.0932688 -0.873788 0.477279 --9.2137 -9.44706 -941.622 -0.169675 -0.687137 0.706437 --27.8516 -4.14895 -950.177 -0.644662 0.0350301 0.763665 --13.9474 -7.95256 -942.165 -0.416036 -0.660227 0.625312 --17.2439 -3.23355 -1022.63 0.025041 0.965882 -0.25777 --31.9487 -35.5744 -950.464 -0.9771 0.14663 0.154189 --11.8394 20.9048 -983.603 -0.709581 0.679027 0.188193 --21.4654 17.4995 -977.081 -0.0956516 -0.52043 -0.84853 --24.4978 19.8695 -977.664 -0.618368 -0.190846 -0.762364 --10.6142 22.7966 -985.249 -0.871514 0.329036 -0.363591 --28.7228 -4.69702 -950.836 -0.849118 0.147298 0.507249 --15.0807 20.6113 -981.016 -0.356731 -0.0531025 -0.932697 --18.4989 -7.75613 -947.083 -0.687561 -0.431476 0.584028 --11.493 21.6159 -983.479 -0.913361 0.310578 -0.263273 --7.79936 27.1892 -986.166 -0.178418 -0.581996 -0.793378 --31.2689 -6.25879 -959.396 -0.857145 -0.27551 0.435196 --17.503 -8.16101 -946.33 -0.610764 -0.414248 0.674808 --6.04307 28.3895 -987.773 0.138367 -0.24492 -0.959619 --31.75 -6.60581 -960.847 -0.908588 -0.26927 0.319314 --22.3565 20.8286 -981.757 -0.429917 -0.687055 -0.585771 --11.0068 -11.0385 -944.533 -0.229502 -0.57508 0.785246 --30.2575 -6.50973 -957.91 -0.759026 -0.27764 0.588894 --5.52787 25.4306 -985.753 -0.426041 0.324216 -0.844614 --7.23305 25.7957 -985.174 -0.162644 -0.353818 -0.921065 --14.1197 -10.3874 -945.349 -0.418277 -0.53217 0.736097 --31.6204 -34.6055 -953.681 -0.997483 0.0465275 -0.0535104 --6.57504 26.2346 -985.553 -0.25185 -0.341372 -0.905559 --28.2631 -6.33469 -950.257 -0.534426 -0.267475 0.801776 -21.2501 -50.0623 -955.59 0.227493 -0.121731 0.966141 --19.2622 18.4983 -979.198 -0.488717 -0.490164 -0.721731 -13.3439 -32.567 -999.219 -0.585082 0.636107 0.503037 -14.8956 47.727 -943.906 0.16189 -0.224581 0.960914 -24.3724 -19.6361 -972.726 0.952478 -0.098015 -0.288406 --22.0134 45.7437 -941.863 -0.0843548 -0.113264 0.989978 --19.5558 20.3674 -981.375 0.135883 -0.804004 -0.578889 --29.4892 -28.7741 -959.103 -0.880014 0.257653 0.398986 --26.2321 42.4407 -949.549 -0.0333623 -0.0482877 0.998276 --24.9463 42.1036 -949.438 -0.0744828 -0.279192 0.957342 -13.1098 43.6274 -938.313 0.968436 0.244146 -0.0502459 -5.01901 11.0642 -1008.91 0.941786 0.216908 0.256886 --25.7728 40.7249 -949.646 0.106993 -0.350693 0.930359 --24.5349 41.4824 -949.867 -0.187931 -0.283943 0.940244 --10.3044 24.1002 -985.204 0.135034 -0.0973586 -0.986046 -14.4033 -33.0549 -998.462 -0.318388 0.215319 0.923183 --18.0003 -29.0469 -955.578 0.551946 0.659383 0.510459 --21.1892 18.8061 -978.755 -0.219858 -0.788005 -0.575074 -0.100118 38.9505 -934.362 0.138443 -0.665176 0.73374 -5.1819 39.2971 -934.902 -0.29072 -0.124541 0.948668 -12.5205 -33.8231 -999.002 -0.59643 0.0951362 0.797007 --14.9262 22.0875 -981.413 -0.109517 -0.410672 -0.905182 -9.64358 13.9234 -997.742 0.672096 0.630898 -0.387628 -11.3359 -34.2323 -967.983 -0.990223 -0.13168 -0.0460248 --24.03 20.2341 -978.244 -0.90424 -0.10914 -0.412841 --29.838 36.0643 -953.273 -0.396573 0.446044 0.802356 --14.8769 25.9273 -985.997 -0.502234 -0.474865 -0.722679 --19.1374 37.2072 -941.485 -0.447162 0.41112 0.794372 -20.9956 -18.9167 -960.763 0.60875 0.0671378 0.790516 --15.8434 -30.3033 -963.375 0.980584 -0.0255427 -0.194428 --3.70836 24.9989 -986.166 0.101865 0.40732 -0.907587 --27.861 34.9575 -952.613 0.162688 0.0545552 0.985168 -9.73597 16.7645 -938.943 0.363149 -0.0998007 0.926371 --28.8739 34.3174 -952.749 -0.252014 -0.223179 0.941637 --27.592 33.7699 -952.912 0.10738 -0.359306 0.927021 --29.0776 32.8278 -953.666 -0.318973 -0.589067 0.742467 --22.3232 18.9369 -978.449 -0.239965 -0.744074 -0.623515 --15.5755 34.3329 -938.032 -0.250843 0.517228 0.818262 -13.6666 9.52555 -948.067 0.95063 -0.0220764 0.30954 --28.7487 31.8681 -954.529 -0.328638 -0.821222 0.466467 --28.6532 47.182 -959.659 -0.870607 0.395526 -0.292578 -22.9717 18.8713 -963.97 0.634087 0.0874354 0.768303 --17.2007 55.2314 -962.261 -0.664378 -0.0385713 -0.746401 --11.2935 29.1744 -932.513 0.404631 -0.116756 0.906996 --11.3205 28.6184 -932.49 0.252007 0.192198 0.948447 --10.8501 28.9048 -932.512 -0.292005 0.14358 0.945578 --22.8478 -10.8242 -998.612 -0.833377 -0.113643 0.540895 --13.4666 22.903 -982.281 -0.311853 -0.607018 -0.730942 --23.8431 26.2093 -948.679 -0.192738 -0.0399985 0.980435 --23.4488 20.445 -980.145 -0.700264 -0.569509 -0.430453 --15.7291 27.486 -931.597 -0.541242 -0.386735 0.746654 -14.4463 25.8178 -982.364 0.885868 -0.136849 -0.443294 --28.0618 24.7887 -957.742 -0.154867 -0.109161 0.981886 --28.8191 24.3581 -957.978 -0.386982 -0.33858 0.857676 -17.201 -50.7758 -955.072 -0.0125654 -0.0394419 0.999143 -13.7971 28.9676 -943.36 0.649043 -0.747005 -0.143969 --28.3482 23.1879 -958.356 -0.100515 -0.413243 0.905056 --18.6791 19.1528 -979.89 -0.122972 -0.580302 -0.805063 -17.7281 -50.6328 -955.173 0.325771 -0.0683476 0.942975 --13.278 25.4234 -930.332 -0.259105 -0.563631 0.784337 --28.5181 22.2526 -959.117 -0.223092 -0.664502 0.713209 --11.8 22.3694 -983.161 -0.719936 -0.311344 -0.620288 --5.18454 21.2372 -937.135 -0.32893 -0.106382 0.938343 --3.8674 21.2378 -936.848 -0.0638144 0.221416 0.973089 -12.8398 28.158 -942.63 0.381936 -0.863658 -0.328969 --7.11914 20.5652 -937.997 -0.276516 0.0688226 0.958542 --3.50917 20.8033 -936.891 -0.121528 -0.42249 0.898183 --2.37199 21.1777 -936.885 0.126362 0.271088 0.954224 --13.6083 20.4657 -939.511 0.38763 0.580702 0.715911 --4.75634 20.0231 -937.899 -0.158014 -0.255486 0.953812 --1.55099 20.6009 -936.885 0.106905 -0.161821 0.981012 --0.240916 20.4868 -937.224 0.353356 0.268551 0.896114 --9.98453 23.4636 -985.325 -0.359567 0.591966 -0.72131 -20.4689 -50.5889 -955.629 -0.0784949 -0.200927 0.976456 -0.572728 20.2885 -937.573 0.210727 -0.474265 0.85479 --1.07482 19.8969 -937.317 -0.0150119 -0.346723 0.937847 --11.7554 24.5769 -985.512 0.164316 -0.500551 -0.84997 --2.39263 18.5311 -936.823 -0.00600697 0.602972 0.79774 --14.1 17.2777 -937.922 -0.159497 0.248189 0.955491 -6.02091 17.7244 -938.699 0.273924 0.654881 0.704341 -17.6616 24.4691 -959.726 0.9057 -0.399655 -0.141364 --5.32426 17.7305 -936.298 -0.0925423 0.268475 0.958831 --15.6184 26.3469 -985.266 -0.881593 -0.21522 -0.420089 --6.68532 17.6109 -936.504 -0.174284 0.218208 0.960214 --2.00334 17.3161 -936.018 -0.0498759 -0.0772939 0.99576 --14.7171 22.7669 -981.835 -0.0281027 -0.604566 -0.796059 --14.2372 16.4818 -938.07 -0.351674 -0.536828 0.766903 --12.5688 16.5503 -937.581 -0.170198 -0.337279 0.925892 -16.537 -23.5845 -1030.64 -0.549412 0.762147 -0.342459 --18.2552 20.7791 -981.471 0.243914 -0.710493 -0.66008 -2.8202 17.0614 -936.8 0.330285 0.130843 0.934768 -13.698 -24.2947 -1027.99 -0.212587 0.430723 -0.877089 --30.0336 -26.8499 -961.225 -0.96532 0.052253 0.255787 --17.1268 23.7594 -983.075 0.348052 -0.270372 -0.897641 --7.18473 16.42 -937.297 -0.0798908 -0.522507 0.848884 --9.22091 15.5639 -937.99 -0.0376687 -0.619039 0.784456 --6.02355 15.5802 -937.478 -0.108587 -0.55936 0.821782 --2.463 15.4637 -937.193 -0.0128407 -0.513848 0.857785 --15.377 25.8254 -985.239 -0.745118 -0.510342 -0.429361 -4.1683 15.2995 -938.566 0.176829 -0.652548 0.736826 --15.2367 24.7016 -983.769 -0.553755 -0.617233 -0.558909 --12.7477 25.0077 -985.989 -0.096879 -0.602167 -0.792471 --12.7831 14.935 -938.656 -0.17463 -0.502224 0.846921 -0.096971 15.0976 -937.592 0.119035 -0.639922 0.759164 --14.8087 23.981 -983.164 -0.310773 -0.757858 -0.573648 --16.0155 24.4519 -983.112 -0.392084 -0.279455 -0.876456 --2.77554 14.4397 -938.16 -0.0557217 -0.744462 0.665335 --15.9144 25.4118 -983.378 -0.885975 -0.147731 -0.439572 --11.2365 23.1706 -984.529 -0.472423 -0.420126 -0.774797 --13.4385 24.8469 -985.677 -0.291172 -0.746112 -0.598778 --4.15222 12.6242 -941.471 -0.269446 -0.70827 0.652497 --7.65934 19.906 -989.043 -0.0831678 0.962224 -0.259246 --25.1396 10.1213 -956.418 0.167521 0.628763 0.759338 -0.467238 31.8714 -984.503 0.111134 0.927139 -0.357859 --12.8179 11.6197 -944.434 0.128968 -0.721188 0.680628 --32.5149 -21.5034 -972.74 -0.945446 -0.189663 -0.264878 -8.63005 11.8307 -945.362 0.0201304 -0.578493 0.815439 --26.6089 -10.5378 -959.351 -0.302354 -0.684687 0.663163 --5.4627 12.1365 -942.369 -0.395209 -0.406883 0.823563 -3.32292 -0.400236 -942.063 0.201774 0.0806989 0.976102 -2.72695 11.3516 -944.963 0.163186 -0.412837 0.896067 --30.8559 -32.8385 -960.974 -0.974618 0.215804 -0.0595744 --12.1869 11.2067 -944.776 -0.07149 -0.521429 0.850294 --9.35165 16.1144 -999.417 0.441365 0.73847 -0.509764 -1.34643 -15.2051 -946.133 0.959572 -0.15427 0.23542 --7.16925 11.2093 -943.877 -0.260567 -0.473226 0.841523 -0.00249411 12.3406 -1007.03 0.329386 0.876027 -0.352253 -5.51564 14.2747 -1005.48 0.970491 0.223587 0.0903112 -12.1454 38.9777 -941.685 0.820078 -0.261443 0.509038 -8.77451 11.0914 -945.706 -0.288515 -0.430637 0.855167 -5.27357 14.8047 -1006.49 0.829493 0.378523 -0.410685 --24.4358 26.5444 -949.034 -0.880129 -0.259629 0.397448 --30.5669 -31.4081 -963.667 -0.832522 -0.399514 -0.383791 -0.419235 10.7263 -1010.59 -0.489874 0.670827 -0.55679 --1.53377 10.5769 -1011.62 0.305956 0.765804 -0.565628 --12.1358 10.4472 -945.006 -0.0527027 -0.129527 0.990174 --27.7979 -45.4572 -950.346 -0.702693 -0.100055 0.704422 -6.18791 10.6965 -945.837 0.171215 -0.214123 0.961684 --25.0368 8.45306 -955.133 0.128295 0.64291 0.75512 --10.4932 14.5022 -1003.57 0.478387 0.876034 -0.0609165 --13.6627 10.4848 -944.965 0.265357 -0.34683 0.899608 --8.01699 10.2968 -944.409 -0.190917 -0.160623 0.968375 --6.6076 10.5015 -943.98 -0.455882 -0.298302 0.838563 -4.1299 24.6652 -931.425 0.0596458 -0.966197 0.250809 --3.40669 11.1906 -941.994 0.00441995 -0.379209 0.925301 -10.3787 9.95015 -945.7 0.11575 -0.0962108 0.988608 --12.2782 9.63528 -945.015 -0.124793 0.122707 0.984566 --4.5398 10.0597 -942.263 -0.275486 -0.0189377 0.961118 -8.88232 9.59637 -946.561 0.0102333 -0.152663 0.988225 -9.38716 9.51894 -946.545 -0.314574 -0.405975 0.858037 --15.0092 9.61346 -944.382 0.179304 -0.313842 0.932391 --3.37504 10.1391 -942.149 0.0555013 -0.0307214 0.997986 --8.64333 10.7919 -1010.27 -0.158523 0.913004 -0.375891 --11.0295 12.7068 -1007.05 0.381827 0.911676 -0.151839 --7.77584 11.411 -1009.78 -0.288617 0.899339 -0.328466 --31.1479 -8.32934 -1012.83 -0.916932 0.299734 -0.26343 --9.51101 15.5172 -1000.17 0.422711 0.64298 -0.638665 --0.284514 9.23388 -944.353 0.124155 0.313623 0.941396 -25.1133 -17.0611 -978.061 0.959205 -0.260349 -0.110201 --5.96662 20.7938 -990.413 -0.829728 0.500485 -0.247118 --16.1145 8.43442 -944.641 -0.05267 -0.319929 0.945976 --14.3778 8.73331 -945.051 0.0952156 -0.0935029 0.991056 -4.5283 35.7327 -938.869 0.177844 -0.0223347 0.983805 -17.0914 -51.2874 -955.195 0.0938918 -0.529524 0.843083 -10.153 8.45095 -946.592 -0.144962 -0.173033 0.97419 -11.5151 8.06642 -946.482 0.0841717 -0.393742 0.915359 --0.929746 11.4581 -1008.69 0.0997443 0.917477 -0.385081 -18.7024 7.56682 -953.434 0.269888 0.538754 0.798063 -1.01088 11.6208 -1008.43 -0.267741 0.940848 -0.207654 --28.3232 -39.1719 -950.874 -0.558037 -0.817582 0.141967 -2.60097 12.4921 -1008.19 -0.473726 0.851796 -0.223666 -1.7891 7.88926 -944.05 0.157735 0.343007 0.925995 -2.45408 12.7142 -1008.89 -0.4778 0.864595 0.155507 --15.7751 7.35106 -945.267 -0.0515815 -0.218642 0.974441 -11.5567 -38.2675 -966.704 -0.999922 0.00987242 0.00768957 --4.86672 7.86184 -942.093 -0.552614 0.0401947 0.832468 -4.50647 40.6759 -935.087 0.00457808 -0.539619 0.841897 --25.0314 -2.62943 -1022.34 -0.760703 0.227126 -0.608066 -17.3304 5.37252 -951.465 0.0181443 0.54075 0.840988 --0.801186 12.8023 -1006.82 0.576465 0.786558 -0.221394 -4.24418 14.7298 -1007.43 0.0952529 0.602435 -0.792464 --2.22517 5.78249 -941.784 0.509685 0.10417 0.854032 -11.6479 -39.2076 -965.461 -0.953487 0.0833117 0.289692 --29.457 -38.5755 -951.103 -0.34557 -0.914915 -0.208594 --0.322945 10.8966 -1010.27 0.112988 0.790697 -0.601691 -16.7211 4.23393 -950.912 0.403869 0.312513 0.859782 --0.863511 5.06566 -942.71 0.250286 0.298581 0.920981 --2.35983 11.626 -1009.29 0.0871433 0.924971 -0.369911 -4.42481 4.92944 -943.517 0.213538 0.297698 0.930472 --7.53869 5.03014 -942.662 -0.0827387 0.293976 0.952225 --4.01173 4.6587 -941.488 -0.44938 0.101592 0.887545 -10.3749 -46.5151 -963.246 -0.926675 0.243503 0.286323 --1.88607 12.4342 -1007.77 0.194817 0.761115 -0.618668 -10.3755 -47.5316 -962.051 -0.941591 0.288533 0.173654 -3.24039 34.8369 -938.223 0.242974 0.513554 0.822937 --5.90903 3.63353 -942.13 -0.364607 0.359445 0.858988 -15.6813 2.59478 -949.908 0.480664 0.241041 0.843126 --1.84889 3.27565 -942.129 0.327884 0.0474874 0.943524 --13.6132 46.3534 -934.64 -0.049477 0.587024 0.808056 --9.65482 18.2726 -995.845 0.215785 0.64235 -0.735407 -1.75246 3.02854 -942.445 0.14399 0.263887 0.953746 -3.11443 40.9167 -933.09 0.224464 -0.829985 0.510627 -18.5323 -0.137574 -1003.48 0.243996 0.925064 0.291071 -15.0393 2.16666 -949.323 0.739888 -0.000841097 0.67273 --7.34319 16.986 -999.187 -0.370526 0.872904 -0.317411 -14.9835 -27.0642 -1029.84 -0.631696 -0.067764 -0.772248 --7.58353 2.77035 -941.976 -0.0575077 0.217911 0.974273 --10.0572 2.37981 -942.14 -0.150831 0.259559 0.953876 --8.6515 16.6143 -998.419 -0.02618 0.892989 -0.449316 -18.9765 -51.0893 -955.761 0.316619 -0.22336 0.92188 --4.18327 1.79405 -941.78 0.14208 -0.107877 0.983959 -3.71156 13.0005 -1007.81 0.329004 0.502661 -0.79943 -0.0467522 2.01996 -942.028 0.0868141 0.20367 0.975183 -4.16438 12.8014 -1007.75 0.563809 0.697912 -0.441632 -4.46482 1.76609 -942.638 0.221398 0.207657 0.952818 -17.8512 0.406495 -950.993 0.454191 -0.280442 0.845614 -18.2593 0.0953454 -951.066 -0.196062 0.0989586 0.975585 -23.8702 -29.8964 -974.122 0.774684 -0.557351 0.298704 -23.8383 -29.459 -973.115 0.914377 -0.404199 -0.0232169 --9.60214 19.674 -992.584 0.338539 0.940935 0.00579133 --5.47161 -17.075 -944.31 -0.877819 -0.47373 0.070804 -19.5624 0.00474631 -950.582 -0.291819 0.269236 0.917798 -12.4156 40.2309 -938.709 0.605738 -0.649048 0.460237 -21.4758 -0.194573 -950.51 0.572403 0.640165 0.512389 --15.5213 -25.4535 -1007.77 -0.529333 -0.723629 0.442909 --6.38875 1.16881 -941.665 -0.0199564 0.103968 0.99438 -3.49319 12.8432 -1008.22 0.00697285 0.978193 -0.207579 --22.6179 -0.500955 -947.026 -0.425215 0.392339 0.815636 -3.09657 13.6095 -1007.44 -0.328223 0.439232 -0.836269 --15.6724 55.4725 -963.176 -0.418323 0.161771 -0.893776 --9.91084 11.9696 -1007.65 0.452055 0.879195 -0.150539 --0.0732661 23.2194 -934.713 -0.106971 -0.994092 0.0183929 --28.6054 46.4174 -956.276 -0.795036 0.246371 0.554274 --28.9025 17.6867 -973.021 -0.99045 -0.133986 0.0325075 --11.1898 0.140639 -941.818 -0.154011 0.14999 0.976618 --8.35851 19.2943 -993.203 -0.117405 0.98703 -0.109486 -18.3491 -1.75624 -1000.44 0.467554 0.755001 0.459747 -17.6875 -0.960723 -951.458 -0.284913 -0.335156 0.898051 --5.68172 17.7735 -997.126 -0.209186 0.855873 -0.472994 --8.78219 -0.0585517 -941.505 -0.0712873 0.0888914 0.993487 -9.38111 -27.9973 -1028.61 0.23273 -0.36389 -0.901898 --6.47972 19.9781 -991.46 -0.388137 0.890071 -0.239007 --18.6499 20.5801 -942.461 -0.838842 0.140596 0.525906 -20.5061 -1.37833 -950.042 -0.141662 -0.0467524 0.98881 --3.709 12.0679 -1008.46 0.00303799 0.783652 -0.621192 --9.34699 13.5553 -1004.34 -0.0521035 0.857729 -0.511456 --7.27227 14.8264 -1004.22 -0.292285 0.904824 -0.309617 -19.0649 -1.64232 -950.685 -0.34485 -0.0712263 0.935952 --24.0559 -2.16419 -950.084 0.245911 0.0174407 0.969135 --10.5851 -2.08904 -1027.56 -0.0466711 0.997907 -0.0447498 -4.62115 14.4903 -1007.39 0.552618 0.207973 -0.807069 --2.28365 -0.724151 -941.468 0.039321 0.101893 0.994018 --8.67547 11.131 -1009.57 0.314327 0.891026 -0.327523 --12.5871 -0.712722 -941.993 -0.231411 0.0752836 0.969939 --7.57789 -1.13122 -941.386 -0.0202447 0.0256925 0.999465 --9.06793 11.4755 -1008.35 0.0191394 0.904822 -0.42536 --10.9568 14.7956 -1001.59 0.314275 0.794995 -0.518858 --9.27533 19.7378 -990.877 0.129837 0.979644 -0.153101 -16.7541 -3.06689 -952.675 0.0148899 -0.729091 0.684255 -18.9159 -2.59484 -950.813 -0.409675 -0.211524 0.887369 --4.42699 20.2836 -991.706 -0.271816 0.789195 -0.550715 --8.31695 13.168 -1006.38 -0.645067 0.634304 -0.426084 --7.84844 15.5793 -1001.66 -0.350214 0.858847 -0.373807 -23.0673 -2.69845 -950.531 0.27032 -0.385664 0.882151 -19.916 -2.72068 -950.732 -0.231674 -0.118098 0.965598 --0.833677 -1.99893 -941.48 0.0581945 0.012172 0.998231 -23.6777 -48.3499 -957.858 0.46919 0.162153 0.868082 -8.79284 41.3567 -935.664 0.376686 -0.478663 0.793088 --8.77801 12.3231 -1006.56 -0.400373 0.66707 -0.628267 --4.59463 -2.30647 -941.426 0.015403 -0.065134 0.997758 --23.6489 -3.83149 -950.047 0.385764 -0.264679 0.883816 --13.3791 -2.39485 -942.147 -0.304784 -0.001774 0.95242 --5.41996 11.9013 -1008.5 -0.0516339 0.756799 -0.651605 -22.8717 -48.34 -956.388 0.74252 0.0862271 0.66425 -22.3108 0.09346 -956.144 0.845105 0.400766 0.353814 -20.917 -3.48049 -950.496 -0.165159 -0.340831 0.925504 --25.2152 -3.82601 -949.188 0.262335 -0.0594248 0.963146 --11.1607 -2.8632 -941.702 -0.151193 -0.0479938 0.987338 -1.4358 -2.26552 -941.657 0.122922 0.0249203 0.992103 --24.3296 25.8909 -949.35 -0.934154 -0.167269 0.315243 -6.78478 34.758 -938.29 0.0761435 0.517345 0.852383 -20.7726 -16.2651 -961.075 0.556258 -0.0724342 0.827847 -2.38339 13.8443 -1006.69 -0.720976 0.42708 -0.545707 -3.95964 -2.95378 -942.095 0.216445 -0.0279168 0.975896 --8.76172 15.4258 -1000.82 -0.417472 0.840489 -0.345393 --9.77386 -3.471 -941.601 -0.08115 -0.0736472 0.993977 --7.23845 -3.45257 -941.476 -0.0116491 -0.122763 0.992368 --24.603 -5.0618 -949.983 0.364378 -0.26104 0.893917 -19.636 -3.86402 -998.814 0.45269 0.586675 0.671479 --6.88405 12.1361 -1008.06 -0.330702 0.617947 -0.713286 --9.49137 14.3537 -1002.92 0.0983819 0.938471 -0.331048 --7.30255 11.7819 -1008.59 -0.122148 0.941813 -0.313159 --26.2149 -4.66061 -949.479 -0.248077 -0.219363 0.943577 --18.2048 57.9126 -953.477 -0.848832 0.525158 -0.0607707 -2.74872 32.2858 -983.505 -0.119302 0.907387 -0.403008 -22.2295 -47.9752 -955.904 0.396386 0.127738 0.909154 --5.79012 55.1743 -966.202 -0.406748 0.756447 -0.512195 --15.3433 -4.33669 -943.045 -0.295862 0.170302 0.939927 --26.3369 -5.65478 -949.643 -0.121573 -0.26695 0.956011 -22.6696 -47.4689 -956.397 0.733423 0.347369 0.584316 -22.276 -5.28667 -951.642 0.133954 -0.638581 0.757806 --27.6917 -5.80301 -949.818 -0.287597 -0.250257 0.924478 --13.0617 35.4197 -937.018 -0.1247 -0.38824 0.913082 --26.8827 -32.4525 -999.28 -0.290453 0.622973 0.726321 -11.2228 -47.087 -958.686 -0.642352 0.666311 0.378699 --17.1515 -5.00443 -943.021 -0.175115 0.343126 0.922821 -1.26215 -4.35369 -941.749 0.0757259 -0.112608 0.99075 -16.135 -23.4906 -1029.13 -0.536367 0.789629 -0.297986 -4.40252 49.7437 -971.561 -0.220076 0.603487 -0.7664 -5.35678 -4.14338 -942.546 0.303928 -0.111292 0.946172 --3.88133 -4.54661 -941.744 0.00655926 -0.183357 0.983024 -22.0292 -47.1597 -956.073 0.501553 0.494889 0.709598 -25.7795 -14.0686 -972.98 0.675442 -0.455508 -0.579905 --29.3984 -22.7883 -1017.36 -0.742918 -0.624651 0.240589 --19.867 -36.0167 -999.252 0.421053 0.175242 0.889947 --27.6361 -31.4804 -1000.89 -0.165319 0.790228 0.590093 --12.9672 -5.32515 -942.378 -0.194494 0.0615845 0.978969 --21.1522 -36.6196 -998.883 0.113156 -0.0858618 0.98986 --25.8585 -33.0429 -998.699 -0.104161 0.318391 0.942219 --15.8492 -5.92094 -942.467 -0.221207 0.168975 0.960476 --18.8999 -13.3862 -1028.32 -0.312648 0.220969 -0.92381 --10.3713 -5.93903 -942.053 -0.051947 -0.0249591 0.998338 -6.48412 -5.72604 -943.137 0.308353 0.136727 0.941395 -18.2142 36.5812 -955.018 0.841227 0.359736 0.403643 --17.4857 53.7545 -968.766 -0.590003 0.621803 -0.515032 -20.4344 -6.00205 -998.069 0.531916 0.339109 0.775931 -24.2507 -18.3977 -978.676 0.376517 -0.164301 -0.911724 --23.0063 -23.7473 -1010.8 -0.485273 -0.454982 0.74666 --5.18292 -6.51701 -942.18 0.0313692 0.0530426 0.998099 -15.0915 -25.8864 -1029.74 -0.71109 0.215356 -0.669308 -7.96994 53.9317 -963.172 0.634384 0.736643 -0.23434 --25.4916 -32.0184 -999.403 0.00403407 0.733212 0.679989 -23.3564 -46.2353 -958.886 0.39903 0.766119 0.503821 --26.2429 -1.44832 -950.01 -0.354626 0.456132 0.816201 --16.951 -25.666 -959.468 0.923459 0.131771 0.360361 -4.86497 -6.23723 -942.689 0.2421 0.0337465 0.969664 --26.1327 -21.843 -1009.72 -0.335348 -0.909997 0.24382 -21.2972 -46.9187 -955.982 0.105528 0.651154 0.751573 --16.018 -33.0038 -1008.64 0.91741 -0.0939701 0.38669 -2.17029 -6.6348 -942.19 0.0555677 0.148472 0.987354 --31.2205 -9.52141 -967.078 -0.953798 -0.263429 0.144479 --4.49654 -7.21698 -942.106 0.0537876 0.392317 0.918256 --25.4928 -31.1857 -1001.86 0.0883178 0.973651 0.210248 --16.9814 -34.9321 -1005.47 0.875483 -0.454727 0.163563 --24.8734 50.9308 -943.787 0.178583 0.733594 0.655704 --12.6199 39.6696 -933.576 0.17526 0.145024 0.973782 --26.2694 -31.5632 -1000.31 -0.0528077 0.902067 0.428352 --5.25801 -13.8254 -942.819 -0.914273 0.127786 0.384415 --12.1593 38.3105 -933.381 0.246059 -0.0797386 0.965969 --15.3934 -31.0158 -960.196 0.984415 0.172487 0.0342885 --10.6667 38.0238 -934.224 0.549852 -0.226155 0.804062 --27.1207 -21.5062 -1009.58 -0.355923 -0.874349 0.329898 --26.4454 -24.7021 -1012.23 -0.416283 0.584341 0.696602 --4.67809 49.0779 -974.183 -0.174673 0.929069 -0.326068 --28.2299 -23.905 -1015.34 -0.813457 0.337014 0.474035 -9.54864 40.7864 -936.553 0.709741 -0.294546 0.63993 -7.3787 39.7312 -934.723 0.0818925 0.0604326 0.994807 -8.29824 39.7977 -935.14 0.467894 0.0286612 0.88332 -9.35144 40.1769 -935.929 0.74212 0.104785 0.662026 --21.5114 -33.8565 -999.143 0.207845 0.336239 0.918555 -7.90857 39.0378 -934.994 0.47946 -0.368249 0.796562 -9.7962 39.4859 -936.438 0.841119 -0.0284923 0.540099 --20.0348 -25.2666 -1009.31 -0.407241 -0.30402 0.861235 -9.70424 39.0171 -936.362 0.72941 -0.362532 0.580113 --21.3791 -32.8012 -1000.18 0.50223 0.698924 0.509186 --13.2778 14.5987 -1006.41 -0.444394 0.341223 -0.8283 --28.9315 -22.5488 -1015.05 -0.617458 -0.741519 0.262479 --12.4674 29.141 -931.155 0.632535 -0.0887123 0.769435 --13.5646 27.5899 -931.429 0.310556 0.0311233 0.950045 --11.879 25.4896 -929.944 -0.226669 -0.221909 0.948355 --20.585 -33.7243 -999.919 0.607857 0.556468 0.566439 --22.2257 -32.1786 -1000.53 0.292839 0.853438 0.431149 --27.2918 -2.3942 -954.023 -0.921877 0.364768 0.130716 --13.2475 19.1651 -938.948 0.258679 0.614388 0.745394 --13.4613 18.4872 -938.471 0.0950868 0.472457 0.87621 --25.8568 -22.8715 -1012.13 -0.570093 -0.596354 0.565116 --1.75322 -32.522 -1004.44 0.0873532 -0.663544 0.74302 --24.4638 -23.4696 -1011.44 -0.481714 -0.493221 0.724351 -20.4733 -7.27453 -997.687 0.588868 0.12838 0.797968 -4.60778 36.4636 -938.432 -0.0108693 -0.599072 0.800622 -17.5887 22.5033 -962.498 0.746955 -0.18877 0.637514 -17.8434 -47.9081 -955.501 0.340043 0.39224 0.854704 --24.2783 -25.4169 -1010.31 -0.184241 0.788358 0.586981 --3.15451 19.3144 -937.509 -0.0456352 0.391847 0.918898 --24.6426 -23.9881 -1011.62 -0.425228 0.190382 0.884837 -16.6845 21.6427 -961.746 0.953658 -0.20007 0.224741 --22.4042 -32.8914 -999.46 0.251723 0.585536 0.770573 -8.80049 -10.8695 -1027.99 -0.156636 0.753435 -0.638593 -18.4245 21.7365 -963.422 0.436271 -0.157558 0.885914 --15.8346 -31.5821 -1009.01 0.75856 -0.0300894 0.650908 -17.6401 21.2631 -963.383 0.450813 -0.317329 0.834308 -22.7567 -45.5486 -959.878 0.281989 0.897338 0.339509 --0.566723 37.407 -935.364 0.552675 -0.16694 0.816506 --3.72141 17.4797 -936.165 -0.0644472 -0.0529651 0.996515 --17.9801 -32.7048 -1004.53 0.607574 0.585964 0.53619 --0.385298 19.2398 -937.518 0.196596 0.202115 0.959427 -16.8467 19.9553 -962.647 0.916982 0.0810149 0.390616 --0.738812 -22.6956 -993.986 0.107915 -0.872076 0.477323 -17.3707 20.0527 -963.413 0.701896 0.151669 0.695944 --16.9853 -34.6117 -1005.2 0.940532 -0.0398351 0.337361 -3.50857 19.905 -939.361 0.502788 0.688258 0.522978 -18.7558 20.6688 -963.826 -0.0202428 -0.174043 0.98453 --16.1726 -29.9213 -1008.43 0.576181 0.105125 0.810533 -2.55309 19.7806 -938.394 0.442488 0.266812 0.856163 -16.818 19.5287 -962.31 0.820708 0.413681 0.394089 -20.0217 20.9647 -963.643 -0.0999718 0.0295973 0.99455 --0.408461 18.4722 -936.767 0.0933993 0.617804 0.780766 -1.76547 19.2292 -938.131 0.288349 0.0220606 0.957271 -18.0622 19.671 -963.777 0.385195 0.190636 0.90293 --15.4289 -34.838 -948.296 0.60955 0.291562 0.737184 --24.15 -31.8681 -1000.05 0.189125 0.866383 0.462183 --18.8769 -33.5854 -1002.2 0.696914 0.525986 0.487493 -22.2238 -8.06948 -998.53 0.528777 0.0489014 0.847351 -1.49955 18.3351 -937.131 0.268799 0.641195 0.71876 -3.20187 18.7458 -938.42 0.340013 0.510885 0.789549 --33.7697 -33.1013 -1003.58 -0.772608 0.476533 0.419516 --0.41427 17.1334 -936.014 0.114911 -0.355379 0.927632 --0.00330759 17.345 -936.093 0.0720978 0.450186 0.890019 -4.65331 18.8801 -939.44 0.492112 0.631589 0.5991 -17.9576 18.687 -963.14 0.606345 0.536053 0.587361 --22.4538 -31.7344 -1001.76 0.183371 0.939446 0.28951 -20.8621 19.8921 -963.429 -0.0489518 -0.0299096 0.998353 --26.1769 -23.9594 -1012.71 -0.627025 0.355055 0.69338 --19.1078 -35.7671 -999.896 0.804793 0.210297 0.555053 --18.9007 -34.9247 -1000.99 0.821836 0.339965 0.457176 -1.17038 17.3536 -936.341 0.236705 0.299487 0.924272 --16.9836 -30.1227 -1007.74 0.486221 0.303957 0.819267 -22.2749 19.5009 -963.702 0.338154 0.137553 0.930984 --16.5268 -29.0124 -1008.52 0.308417 0.331447 0.89164 -2.37614 16.8592 -936.728 0.204991 -0.530987 0.822212 --21.8781 -25.2112 -1010.3 -0.301889 0.342674 0.889628 -18.8081 17.4229 -962.497 0.465576 0.71435 0.52244 -19.4647 17.8776 -963.484 0.476175 0.636693 0.60653 --20.6572 -31.6945 -1003.1 0.342457 0.838599 0.423646 --19.3374 -32.4676 -1003.09 0.544387 0.677641 0.494415 --20.7134 -26.2608 -1009.2 -0.0546967 0.620466 0.782324 -20.6071 17.8389 -963.977 0.0305724 -0.110966 0.993354 -20.2105 17.5428 -963.869 0.584791 0.405164 0.702753 -21.0318 18.1031 -963.8 -0.0384985 -0.261687 0.964385 -10.3813 -50.1599 -957.87 -0.848844 -0.40625 0.338268 -16.4638 17.0336 -958.167 0.712684 0.515465 0.475791 -22.5137 18.2694 -963.764 0.25117 -0.312135 0.916234 --20.7308 31.8988 -938.601 -0.652296 0.38521 0.652781 --22.6416 -26.8953 -1008.48 0.0959946 0.741577 0.663964 -15.0126 16.0223 -955.128 0.841931 0.289295 0.455478 --19.4873 -27.2895 -1008.59 0.146745 0.552186 0.820705 --21.7121 -24.7034 -1010.4 -0.461609 -0.0276359 0.886653 -12.8152 14.9334 -950.746 0.869447 -0.0359224 0.492718 -24.0323 -42.8196 -964.943 0.782261 0.427992 0.452648 -14.5658 15.1218 -953.825 0.765578 0.343788 0.543783 --1.42989 9.73701 -944.37 0.429293 0.0625135 0.900999 -19.4834 14.8797 -959.264 0.505073 0.65335 0.563945 --17.8348 -27.4231 -1008.9 0.25676 0.431973 0.864566 --17.8628 -29.657 -1007.41 0.42962 0.512147 0.743729 -13.338 13.437 -951.26 0.822203 0.168478 0.543688 --2.11125 10.0806 -942.632 0.54789 -0.137995 0.82509 --26.8811 -1.22538 -953.787 -0.818019 0.263261 0.511408 -2.96722 10.5047 -945.133 0.186383 0.0295498 0.982033 -10.3053 12.8396 -946.344 0.718087 -0.0157412 0.695775 --9.27611 16.9904 -937.003 -0.10453 -0.379652 0.919205 -25.5883 -45.2565 -971.724 0.898509 0.0292142 -0.437981 -9.18908 12.5475 -945.277 0.720295 -0.430353 0.544033 -10.2355 -17.484 -962.319 -0.259099 -0.603896 0.753776 -5.81011 -9.71422 -1027.3 0.64601 -0.16687 -0.744867 -18.1337 13.5963 -956.423 0.664755 0.490648 0.563352 --1.63536 38.3838 -933.645 0.431085 -0.535972 0.725879 --2.05832 8.77438 -942.749 0.833662 0.0670375 0.548191 --1.72757 8.28652 -943.533 0.819608 0.239638 0.5204 -2.75848 9.76319 -944.967 0.217337 0.266139 0.939114 -12.0884 12.5409 -948.726 0.836368 0.35981 0.413552 -13.0743 12.2545 -950.382 0.722344 0.381691 0.576655 --8.80847 22.9159 -934.971 0.123995 -0.990939 0.0516197 -25.7373 -46.835 -970.663 0.517058 -0.733497 -0.441173 -20.7213 13.4005 -958.431 0.519617 0.628282 0.579017 -9.40902 11.6868 -945.597 0.438994 -0.138654 0.887727 -10.5227 11.6665 -946.303 0.411126 0.183698 0.892878 --34.2413 -34.5503 -1007.54 -0.934999 -0.313617 -0.165596 --24.3201 47.4631 -941.096 -0.268988 0.25535 0.928677 --3.83421 -22.9417 -994.509 -0.0859404 -0.880347 0.46648 -9.27466 -20.4573 -965.771 -0.902162 -0.326922 0.281472 -8.23648 -16.6756 -961.048 0.0447751 -0.924058 0.379622 --2.07715 7.57318 -942.331 0.741989 0.200592 0.639699 -24.6719 -46.3376 -972.696 0.441478 -0.7446 -0.500668 -13.7541 -25.126 -976.986 -0.560554 -0.299578 -0.772032 -16.1541 11.9409 -952.98 0.669386 0.38511 0.635305 -9.49649 -21.4908 -965.869 -0.979482 -0.1071 0.170716 --6.85994 30.1851 -930.369 0.0687931 -0.166476 0.983643 -11.8518 10.5684 -946.498 0.530309 0.337435 0.77776 -9.05615 -20.6941 -967.979 -0.916618 -0.389443 0.0902546 --3.28465 6.26966 -941.584 0.0505335 0.109436 0.992708 -0.103589 -17.708 -942.014 0.440336 -0.0730637 0.894855 -4.62111 13.3848 -1002.92 0.730606 0.677224 -0.0870815 -20.6699 12.1479 -957.241 0.465094 0.567787 0.679195 --20.4307 38.7085 -941.776 -0.554716 -0.802573 0.21947 -9.83745 -46.5463 -966.859 -0.959948 0.076395 -0.269561 -19.1017 11.4031 -956.063 0.487732 0.503669 0.713046 --31.2978 -33.4622 -951.876 -0.789756 0.585512 0.182923 --16.2245 -28.1648 -960.091 0.909996 0.303007 0.283009 -13.4036 -27.1675 -975.896 -0.650593 -0.288368 -0.702547 -6.62688 28.9536 -985.783 0.667823 0.047338 -0.742814 -23.0672 -41.4127 -964.52 0.635634 0.269803 0.723309 -13.4107 -38.5835 -973.14 -0.784137 -0.0572739 -0.61794 -13.7948 -36.7806 -973.717 -0.683864 -0.0614057 -0.72702 -14.8534 9.76039 -950.511 0.693488 0.347671 0.63103 --11.6441 36.1263 -936.438 0.0137941 -0.768181 0.640084 -9.12623 -18.8788 -964.398 -0.708232 -0.544978 0.448783 -7.77731 37.0032 -937.487 0.147446 -0.786957 0.599131 -8.47027 8.57431 -946.157 0.261047 0.350992 0.899255 -17.0902 -37.2307 -975.415 -0.260644 -0.0202577 -0.965223 -16.4464 -33.6119 -975.702 -0.302835 -0.177632 -0.936343 -5.50511 38.4414 -935.052 -0.304259 -0.440975 0.844374 -11.7738 -38.942 -969.174 -0.986823 -0.00202116 -0.161793 --11.4621 36.7108 -935.694 0.0796286 -0.867973 0.490186 -19.2542 10.1204 -955.287 0.287031 0.542326 0.789617 -10.3786 -27.2112 -972.356 -0.865483 -0.206815 -0.456252 --1.36707 5.02132 -942.547 0.604353 0.171507 0.778038 --21.0806 -14.641 -989.603 -0.799326 -0.57825 0.163415 --28.5738 -28.7222 -1027.19 -0.699264 -0.584429 -0.41167 -11.8514 -34.6833 -971.373 -0.912028 -0.151767 -0.381014 -9.09888 -22.0703 -971.196 -0.991918 -0.126691 0.00689509 --16.3765 -7.2319 -943.469 -0.558152 -0.704029 0.4391 -1.9927 39.9415 -933.634 0.24528 -0.675499 0.69537 -18.6635 9.74496 -954.676 0.601711 0.375365 0.705014 -0.0377747 29.3039 -986.269 0.595043 -0.2839 -0.751881 -7.73143 6.93368 -945.138 0.290198 0.381364 0.877694 -4.74043 -17.4262 -963.408 0.112252 -0.991409 0.0671423 -12.6584 -34.5948 -972.868 -0.761211 -0.155121 -0.629679 -19.7899 -16.4778 -979.195 0.0676338 -0.198613 -0.977742 --14.7832 36.5912 -936.398 -0.381489 -0.630694 0.67579 -20.431 9.58879 -955.19 0.536808 0.465986 0.703345 --2.54292 3.89235 -941.551 0.298291 -0.103312 0.948867 --5.56734 -23.9381 -996.789 -0.188184 -0.830795 0.5238 -13.7891 8.3995 -948.683 0.832317 0.0424091 0.552675 -11.9959 -37.8709 -970.631 -0.969002 -0.0986464 -0.226506 -16.7731 8.82734 -952.215 0.731599 0.262731 0.629075 --14.47 33.1842 -936.467 -0.194152 0.81155 0.551082 -17.013 -39.511 -975.49 -0.32081 0.135377 -0.937419 -14.5139 -30.3931 -975.457 -0.564999 -0.272306 -0.778862 -9.19144 -21.572 -972.341 -0.914476 -0.317619 -0.250701 -12.2526 7.82944 -946.915 0.531003 -0.239543 0.812807 -20.0187 8.98513 -954.556 0.242719 0.569252 0.785519 -13.5112 -36.3705 -998.409 -0.434384 -0.0953038 0.895672 -7.58667 6.20729 -944.782 0.261134 0.345341 0.901415 -11.3638 7.6133 -946.583 0.31514 0.15436 0.936408 -10.337 -43.5662 -967.235 -0.95563 0.208566 -0.20802 --13.9862 37.0042 -935.472 -0.190621 -0.856464 0.479721 -9.77984 -20.189 -964.344 -0.818451 -0.274314 0.504867 -21.4743 8.81563 -958.376 0.698817 0.393031 0.597647 -7.95882 -19.3413 -972.267 -0.675201 -0.737132 0.0271998 -10.3489 -23.1261 -973.928 -0.808902 -0.291208 -0.51076 -15.7717 7.42737 -950.383 0.744534 0.200658 0.636715 -11.3633 -40.9744 -968.354 -0.956793 0.211917 -0.199094 -21.7067 -45.3753 -975.664 0.120964 -0.555023 -0.822993 --15.7765 -43.2755 -973.15 0.981446 0.191578 0.00790022 --1.8211 39.8347 -930.951 -0.0430364 -0.382637 0.922896 -12.1183 -41.0649 -970.755 -0.919898 0.176769 -0.350057 -14.9295 -38.2754 -974.469 -0.520734 -0.0507898 -0.852207 -11.0503 -27.4533 -973.268 -0.757163 -0.215914 -0.616511 -22.8714 7.88536 -959.469 0.790228 0.416097 0.449892 --28.578 -4.06083 -953.075 -0.909024 0.353333 -0.22098 -8.55573 4.46256 -944.492 0.323014 0.257883 0.910581 -14.7807 -32.803 -975.022 -0.535263 -0.200308 -0.820591 -6.72853 41.5001 -935.132 0.268855 -0.247101 0.930945 -12.4224 5.83527 -946.574 0.488211 0.215373 0.845733 -13.5724 6.07691 -947.482 0.642062 0.178107 0.745677 -13.5883 -45.2515 -974.211 -0.745548 -0.0205218 -0.666136 -16.7257 -45.3476 -976.272 0.00279262 -0.854912 -0.518765 -1.0275 0.597438 -1025.59 0.840715 0.210759 -0.498777 -19.9506 -45.7597 -974.951 0.0241746 -0.935366 -0.352855 -12.0994 -45.0802 -972.11 -0.863066 0.0590544 -0.501626 -13.6503 -40.1644 -973.417 -0.759393 0.0520943 -0.648543 -16.4966 5.99395 -951.058 0.731103 0.0906896 0.676213 -16.9138 6.11483 -951.504 0.632156 0.238025 0.737375 --30.7656 -32.333 -954.913 -0.842515 0.533664 0.073291 -19.847 6.97515 -953.227 0.659051 0.307571 0.686332 -16.3621 -44.7009 -976.543 -0.464076 0.0709243 -0.882951 -14.7911 5.19817 -948.557 0.775623 0.0745272 0.626781 -13.6961 -45.6938 -974.272 -0.588186 -0.446783 -0.674108 -10.7583 3.58409 -945.219 0.440638 0.164283 0.882525 -18.886 5.94273 -952.026 0.283395 0.539166 0.793087 -21.7429 -44.3283 -976.026 0.331816 -0.192228 -0.923551 -20.2817 -43.6676 -976.598 0.252939 0.0916345 -0.963133 -1.87681 1.33618 -942.064 0.119917 0.150202 0.981356 -11.9484 3.64149 -945.915 0.580937 0.0767135 0.810326 --1.66801 -13.0668 -940.766 0.411582 0.0380858 0.910577 -12.8086 9.0152 -946.568 0.792151 -0.0206862 0.609974 -16.7094 -45.0394 -976.674 -0.274893 -0.53296 -0.800242 -6.80839 -32.7483 -1008 0.207109 -0.678472 0.704827 -10.7618 -43.3943 -968.474 -0.929115 0.130493 -0.346002 -11.8932 -26.7871 -974.501 -0.726907 -0.236826 -0.644609 -13.7474 46.825 -963.778 0.919395 0.0823401 -0.38462 -21.3518 -40.1746 -963.456 0.502575 0.0740541 0.861356 -3.7569 0.254976 -1022.94 0.975847 -0.190774 -0.106432 -14.3348 3.79749 -947.998 0.725931 -0.0318008 0.687032 -19.1674 -45.493 -975.945 0.0821171 -0.86452 -0.495845 -14.9306 -44.127 -975.411 -0.636628 0.106001 -0.763851 -12.9557 43.0945 -937.29 0.932977 -0.107829 0.343406 -18.2566 4.43684 -950.808 0.270431 0.390163 0.880136 -22.7598 4.9074 -957.487 0.646809 0.239425 0.724095 -23.4876 5.09569 -958.322 0.760147 0.301686 0.575467 --21.2367 -19.6713 -1028.93 0.160854 0.354506 -0.921114 -19.092 4.42819 -951.199 0.675262 0.323514 0.662843 -8.45992 1.22908 -943.754 0.378291 0.121685 0.917654 --11.5007 22.743 -934.653 0.0727891 -0.907227 0.414295 -15.4102 53.1246 -947.079 0.976546 -0.155101 -0.149335 -17.555 3.15832 -950.417 0.306227 0.173602 0.935995 -19.1549 3.41419 -951.042 0.561582 -0.0445746 0.82622 --18.334 -13.5911 -1034.55 -0.535069 0.592862 -0.601843 -24.0093 4.24449 -958.8 0.876926 0.211402 0.431637 -5.90513 -0.225556 -942.689 0.296273 0.10329 0.949502 -9.95713 0.968336 -944.451 0.500227 0.0496914 0.864467 -13.0273 53.0046 -947.894 -0.230914 0.592342 0.771887 -21.4881 -45.7372 -975.335 -0.0502835 -0.761154 -0.646619 --22.2424 -25.9416 -1032.87 0.469594 -0.264731 -0.842258 --17.7865 -49.3677 -953.527 0.768555 -0.0132434 0.639646 --18.925 -19.9093 -1029.54 -0.423984 -0.448534 -0.7868 --19.2797 -20.5349 -1029.16 -0.0443952 0.117192 -0.992117 -21.218 2.43729 -956.106 0.497992 0.180246 0.848242 --19.5588 -16.5521 -1030.58 -0.370632 0.134102 -0.919048 --3.25062 -33.4467 -1005.29 -0.0659888 -0.690382 0.720429 -24.5992 -19.2576 -974.865 0.966325 0.140709 0.215444 -13.4486 1.05084 -947.219 0.746164 -0.00724827 0.665723 -16.3924 1.43372 -949.39 0.250318 0.371382 0.894101 -18.1251 2.25169 -951.203 0.519092 -0.13069 0.844668 -19.7082 2.73087 -951.545 0.445337 0.233141 0.864477 -22.5495 2.17323 -956.683 0.496691 0.111333 0.860757 --18.7928 -27.1609 -1030.72 -0.0951487 -0.385943 -0.917603 --21.84 -24.6627 -1032.69 0.60848 0.110922 -0.785779 -11.7591 0.440486 -945.664 0.631031 -0.0141779 0.775628 -14.9933 1.26038 -949.081 0.485506 0.288321 0.825321 -16.8176 1.64066 -949.656 0.647347 0.072914 0.7587 --18.2451 -17.3049 -1031.43 -0.689591 -0.391276 -0.6094 --12.2605 -22.7165 -1035.26 -0.259904 -0.333844 -0.906089 --30.7021 -32.785 -951.833 -0.632623 0.739456 0.230203 --14.7678 -27.7589 -1030.95 -0.280913 -0.625022 -0.72831 --16.5791 -28.1555 -1029.87 -0.0408366 -0.760867 -0.647622 -8.70181 -1.10156 -943.762 0.435348 -0.00942406 0.900213 -23.3306 1.79245 -957.226 0.692611 0.113187 0.712375 -10.562 -0.562731 -944.834 0.56646 -0.0795818 0.820238 --21.5621 -45.1407 -949.319 0.184385 -0.133132 0.973796 -23.9332 1.61637 -957.938 0.784094 0.130932 0.606674 --16.0622 -16.6559 -1035.25 -0.318911 -0.215868 -0.922874 --2.56419 -35.129 -1007.35 0.0528618 -0.860284 0.507067 -17.194 0.406888 -950.257 0.788624 -0.173191 0.589981 -20.4596 1.65461 -951.279 0.451556 0.64379 0.617764 -6.44772 -2.29331 -942.811 0.331434 -0.0187004 0.943293 -23.3191 0.768469 -957.16 0.630097 0.109882 0.768703 --28.5773 -51.3209 -957.242 -0.0640717 -0.955144 -0.289127 --26.3491 28.0532 -966.297 -0.714843 0.12234 0.688501 -15.7729 -0.0775718 -948.62 0.42924 0.290615 0.855159 -23.0821 -31.7969 -973.559 0.899662 -0.20518 -0.385369 -13.3014 -0.892148 -947.138 0.545089 0.140173 0.826577 --17.1632 -26.885 -1030.71 -0.0992242 -0.33696 -0.936276 --18.5872 -27.9159 -1030.23 0.0560061 -0.668847 -0.741287 --19.2898 -24.8936 -1031.18 0.412086 0.156169 -0.897662 --19.6247 -49.8096 -951.206 0.432355 0.0414175 0.900752 --18.9896 32.1336 -937.257 -0.46575 0.684187 0.561218 -6.93003 -1.44511 -1021.92 -0.0968678 0.870804 -0.481993 --18.7922 -16.7338 -1031.11 -0.719875 -0.115838 -0.684369 --17.63 -17.5777 -1032.04 -0.673404 -0.647225 -0.357249 -5.41102 41.4334 -934.616 0.307172 -0.838941 0.449247 --9.03931 -25.55 -1000.91 -0.349172 -0.756546 0.552917 --17.4799 -19.3704 -1031.09 -0.540857 -0.368568 -0.756064 --14.0604 -22.033 -1033.9 -0.808579 -0.161718 -0.565728 --12.7043 -23.4011 -1034.84 -0.517251 -0.323281 -0.792427 -20.9615 0.422379 -950.511 0.276273 0.522199 0.806834 -22.0535 1.15588 -951.437 0.436641 0.635276 0.636999 --17.9805 -16.2501 -1033.9 -0.683265 -0.563043 -0.4649 --14.7483 -18.4531 -1035.69 -0.547277 -0.365875 -0.752744 -8.40763 -2.75315 -943.753 0.45455 -0.0756102 0.887506 --12.6293 -21.1073 -1035.63 -0.371833 -0.330529 -0.867462 -7.43869 35.7895 -938.719 0.0661651 -0.68161 0.728718 -22.0655 3.97149 -978.381 0.603498 -0.229784 -0.763538 --15.3474 -20.2511 -1032.27 -0.722983 -0.275767 -0.633442 -2.07387 27.9559 -986.94 -0.18072 -0.352798 -0.918082 -15.2237 -1.5407 -947.991 0.716001 -0.0162714 0.69791 --18.5849 -15.5066 -1033.54 -0.86499 -0.339778 -0.369246 -10.2839 -2.55834 -944.963 0.569231 -0.027957 0.821702 -22.8362 0.561999 -951.715 0.597904 0.560099 0.573411 --25.3907 28.7666 -956.976 -0.92499 -0.143241 0.35196 --17.9734 -26.1793 -1030.85 0.0808655 -0.0773802 -0.993717 --17.4395 -16.0641 -1034.61 -0.442866 -0.332927 -0.832484 -25.4611 -0.498234 -959.882 0.892484 0.1285 0.43239 -1.17259 4.15427 -1021.27 -0.335419 -0.216181 -0.916929 -13.4026 -3.08172 -946.315 0.482962 0.20858 0.850437 --7.69657 54.0064 -966.185 -0.131458 0.975519 -0.176298 -10.8068 -3.25073 -945.239 0.462944 0.11571 0.878803 --10.2403 -28.3295 -1004.53 -0.502192 -0.585765 0.636147 --15.75 12.7604 -943.19 -0.772622 -0.522517 0.360599 --0.666986 -7.13514 -942.244 -0.0315263 -0.0775909 0.996487 -13.657 -3.47888 -946.502 0.739385 -0.203877 0.641672 -14.2558 -21.2529 -1004.33 0.62768 -0.742046 0.23534 --17.518 -24.8134 -1030.57 -0.00396536 0.258892 -0.965898 --24.7122 27.7261 -948.702 -0.976809 -0.183543 0.110257 -22.1492 -0.799934 -950.322 0.492328 0.2885 0.821207 -5.80776 -2.05454 -1024.75 0.11761 0.947713 0.296661 -10.8532 -4.0782 -944.998 0.315603 0.323391 0.892083 -15.3452 -4.23675 -952.49 0.834916 -0.369956 0.40749 -3.16415 0.906597 -1020.09 0.948216 0.233403 -0.21543 --10.6648 17.2566 -996.758 0.285823 0.816789 -0.50116 --0.652639 8.64697 -1012.72 0.0112021 0.747769 -0.663865 -23.6046 -0.598124 -951.292 0.623148 0.353849 0.69748 --17.9779 -47.2186 -952.207 0.573483 -0.514036 0.637874 --29.9935 21.9813 -961.001 -0.778297 -0.58965 0.215792 -7.02445 -2.38256 -1024.14 0.0591639 0.997048 -0.0489343 -15.94 -4.6344 -953.751 0.570441 -0.503263 0.649094 --1.68097 -9.18272 -941.158 0.11893 0.432467 0.893772 --29.9926 34.0049 -954.723 -0.876743 -0.302628 0.373814 --29.8434 38.9492 -964.385 -0.982909 -0.047627 -0.177824 -0.444504 2.83249 -1020.97 0.309553 0.855949 -0.414161 --17.698 -47.1772 -952.627 0.895564 -0.144498 0.420814 --6.67759 -22.5922 -994.863 -0.189584 -0.874078 0.447264 -11.9566 -4.82288 -945.189 0.581769 -0.0441091 0.812157 --25.2336 19.2316 -962.974 -0.180782 -0.33278 0.925514 -14.6015 -5.47748 -951.668 0.866838 -0.331245 0.372652 -23.5591 -34.7213 -969.865 0.960152 -0.232306 -0.155377 -23.6258 -1.87731 -951.426 0.738837 0.0846009 0.668553 -10.2336 -16.3561 -961.144 0.0531058 -0.777637 0.626467 -9.62021 -5.92299 -943.871 0.34524 0.153418 0.92589 --23.2165 32.4288 -975.152 -0.990939 0.130115 0.033319 --25.3797 21.3055 -970.03 -0.872329 0.475109 0.115382 -24.3805 -3.69577 -957.586 0.789739 0.0637956 0.610117 -3.75838 -7.88105 -942.072 0.113486 0.347531 0.930775 --24.0747 40.8516 -949.781 -0.741611 -0.0116112 0.67073 -23.2058 -2.23692 -950.529 0.499985 0.0711527 0.863107 -24.3997 -2.04458 -951.987 0.877231 0.0932162 0.470931 -0.165863 -9.29056 -941.188 0.0610119 -0.0681827 0.995806 --30.9531 23.7688 -960.82 -0.864334 -0.402791 0.301142 -11.0595 -5.99198 -944.767 0.642434 -0.375092 0.66827 --29.3379 24.1827 -963.7 -0.880439 0.166227 -0.444067 --26.9465 19.7388 -963.485 -0.641732 -0.607277 0.468395 -23.5301 -49.9591 -957.589 0.696453 -0.0602487 0.715069 -0.796082 -19.6264 -1035.15 0.186737 -0.130251 -0.973737 --25.503 19.9795 -962.465 -0.025731 -0.738143 0.674153 -3.37674 -8.72764 -941.596 0.157286 0.140048 0.977572 --5.6372 23.6905 -933.419 0.0765116 -0.866728 0.492878 -6.91488 -7.42932 -942.712 0.270321 0.187954 0.944246 --27.5105 20.7265 -961.82 -0.247459 -0.878941 0.407709 -21.7577 -3.5684 -950.574 0.220925 -0.304801 0.926439 -22.2084 -3.46647 -950.906 0.31128 -0.489864 0.814333 --28.3336 27.4185 -967.304 -0.607324 -0.0608128 0.792124 --25.8129 29.6244 -973.005 -0.392597 0.528552 -0.752662 -5.36348 -8.2286 -942.156 0.375049 -0.348511 0.858999 --23.4006 31.5954 -972.749 -0.775218 0.604902 -0.182018 -14.4108 -21.8296 -1006.17 0.390625 -0.80115 0.453398 -25.485 -4.42137 -959.441 0.906511 0.0025683 0.422174 -3.69216 -9.10748 -941.792 0.320289 -0.511632 0.797275 --22.7419 31.5407 -977.08 -0.685435 -0.428234 -0.588893 --21.5756 32.3786 -977.985 -0.196586 -0.00873591 -0.980448 --9.70438 36.9376 -935.845 0.329359 -0.520403 0.787847 --19.1448 26.9801 -976.751 -0.951511 0.0811368 -0.296722 --21.5381 26.1244 -972.901 -0.343886 -0.219322 -0.913039 -7.52357 -8.0014 -943.104 0.469877 -0.374324 0.799436 --1.66765 8.90756 -944.049 0.808284 0.112537 0.577939 --18.6711 -44.4844 -950.274 0.800669 0.114772 0.588011 -24.1893 -4.34572 -951.997 0.764221 -0.324232 0.55753 --19.8749 40.8305 -936.66 -0.975909 -0.216902 0.0235788 --30.9816 24.0097 -961.629 -0.917984 -0.263411 -0.296513 -12.5092 -8.1054 -949.544 0.813506 -0.362354 0.45487 -24.4729 -6.15458 -957.531 0.822539 -0.0433131 0.567058 --16.0575 -16.8991 -986.844 -0.338252 -0.900799 0.272299 -10.8395 -8.90187 -947.666 0.71535 -0.396447 0.575417 --23.6052 30.6659 -973.829 -0.930887 0.271682 -0.244209 -23.9517 -6.72805 -956.984 0.712017 -0.151334 0.68566 -9.02183 -10.1218 -946.633 0.574818 -0.413113 0.706344 --27.4485 19.9971 -964.263 -0.967056 -0.080512 0.241497 --30.1113 22.2206 -961.707 -0.886237 -0.463213 0.00412179 --0.741048 -8.53801 -941.624 0.0171347 0.47393 0.880396 -21.3068 -8.20159 -955.358 0.374499 -0.186164 0.908346 -22.5176 -8.16396 -956.074 0.557119 -0.21724 0.801515 -13.8133 56.7044 -950.004 0.243639 0.756537 -0.60687 -14.8929 53.1484 -946.259 -0.0654026 0.762011 0.644252 -12.1734 57.2397 -950.179 0.178622 0.960459 -0.213573 --19.375 -17.0804 -992.665 -0.546324 -0.779803 0.305676 --15.9861 -38.861 -946.706 0.663483 -0.0513402 0.746428 -14.566 51.7768 -944.76 -0.28147 0.66644 0.690386 --23.195 31.6473 -976.375 -0.925912 -0.216145 -0.309786 -11.8432 56.4759 -952.302 0.537167 0.717529 -0.4434 -11.099 57.1331 -949.573 -0.102468 0.961716 0.254172 -9.10466 42.4981 -934.294 0.252873 -0.79601 0.54993 --28.8331 23.9505 -965.056 -0.642246 -0.026691 -0.766034 -25.0082 -21.7715 -973.902 0.924388 0.0607288 0.376588 -12.1306 -22.8272 -1001.81 0.565352 -0.772532 0.289086 --24.41 25.0434 -972.92 -0.386125 0.17376 -0.905933 -11.0461 56.7989 -952.298 0.163 0.882673 -0.440817 -18.75 34.8123 -963.58 0.621102 0.626612 -0.470733 --12.9246 -31.9957 -1009.39 -0.384615 -0.466584 0.796474 --26.7043 24.9702 -966.335 -0.998001 -0.0622447 -0.0109264 -10.4897 57.7008 -959.243 -0.0234748 0.800233 -0.599229 -9.65555 56.6217 -949.166 -0.232135 0.845048 0.48167 -9.52194 57.5186 -955.72 -0.0396208 0.924332 0.379526 --27.8748 20.6333 -963.515 -0.678677 -0.734135 -0.0210378 -9.18841 56.1227 -948.668 -0.13473 0.716303 0.684659 --14.1871 -34.0712 -1011.6 0.173585 -0.965508 0.194067 -7.58563 56.4346 -950.332 -0.267927 0.874014 0.405357 --23.7458 27.3006 -973.332 -0.0404824 -0.267717 -0.962647 -7.7162 55.4137 -948.264 -0.355058 0.785153 0.507414 -3.54409 58.1323 -950.707 0.201686 0.722686 0.661096 -6.08168 52.7492 -944.607 -0.0604457 0.973517 0.22048 -14.1638 -22.3395 -1006.7 0.60193 -0.623036 0.499507 -10.5096 52.982 -968.322 0.119777 0.605275 -0.786953 --8.76394 35.0054 -936.221 -0.132025 0.482201 0.866055 -2.07215 59.0324 -954.918 -0.124786 0.942474 -0.310114 -24.4493 -21.9429 -973.151 0.965133 -0.0307349 0.259949 --24.8894 -51.7535 -951.308 -0.297788 -0.495865 0.815745 --12.9732 -18.8591 -989.797 -0.271512 -0.902371 0.334674 -1.36499 59.0064 -954.474 -0.286251 0.895885 -0.339781 -4.05757 51.6334 -941.095 -0.129455 0.9481 0.290426 --25.023 -8.01347 -951.61 0.526153 -0.774225 0.351765 -0.340696 24.7502 -938.266 0.22323 -0.890698 -0.396012 --11.0315 1.86693 -1019.56 -0.525178 -0.281397 -0.803121 --16.6769 -44.933 -964.575 0.773069 0.0891309 0.628029 -3.13282 40.0308 -935.265 0.458702 -0.745635 0.483343 -4.57978 50.1763 -938.188 0.0252886 0.768153 0.639767 -2.39819 58.7936 -959.996 -0.090796 0.977415 0.190829 -3.59527 57.2664 -958.215 -0.139792 0.877367 0.459005 -8.02982 27.1499 -984.666 0.415113 -0.344943 -0.841841 -6.9573 30.576 -986.387 0.661516 -0.12322 -0.739738 -2.36667 58.6072 -961.833 -0.146208 0.949627 -0.277184 -3.24683 -24.2407 -1031.92 0.497221 -0.4444 -0.745171 --25.1008 24.025 -972.434 -0.808051 -0.179507 -0.561098 -16.3879 -36.289 -997.327 -0.168749 -0.379617 0.909623 -2.94397 52.0891 -943.779 -0.0922541 0.949773 0.299032 -3.35535 50.3123 -938.528 -0.102397 0.760537 0.64117 --15.8447 -34.2511 -1010.72 0.267419 -0.959496 0.0886232 -26.1245 -46.6069 -970.372 0.932295 -0.129549 -0.337703 --27.9334 -3.67165 -954.33 -0.928075 0.361774 -0.0882992 -4.29461 45.3475 -934.435 -0.125604 0.795892 0.592266 -0.643811 58.259 -961.579 -0.223744 0.893092 -0.390288 -3.83606 44.5204 -933.479 -0.26268 0.720476 0.641804 --7.21531 9.70116 -1012.97 -0.231944 0.56839 -0.789389 --20.9514 27.6528 -974.113 -0.466323 -0.555522 -0.688432 --2.68298 56.4488 -946.434 -0.0878421 0.847368 0.523689 --29.9728 -30.38 -958.468 -0.85968 0.467578 0.205723 --3.15815 57.2497 -948.34 -0.1556 0.853769 0.496857 --24.7539 23.9354 -973.281 -0.742353 0.580449 -0.334649 --6.38677 22.1788 -986.318 -0.546162 0.662319 -0.512875 --4.26577 58.6312 -950.526 0.00664833 0.80838 0.588624 --8.27764 30.1671 -984.706 -0.278582 0.852352 -0.442592 -10.4212 -25.4749 -1005.1 0.641023 -0.598005 0.481124 --28.9098 -38.5992 -948.85 -0.0987851 -0.862565 0.496208 --3.44303 56.2328 -946.33 -0.191219 0.823672 0.533853 --2.97156 58.6687 -957.908 -0.0407476 0.975428 0.216517 -1.96791 55.3085 -968.591 -0.0770528 0.914713 -0.396689 -16.8907 -33.6637 -997.755 -0.234762 0.0543605 0.970532 --27.0363 21.3815 -965.347 -0.788744 -0.00169977 -0.61472 --4.12721 57.481 -948.877 -0.31336 0.724809 0.613562 --3.00447 33.2187 -982.442 -0.195237 0.519511 -0.83186 --25.3224 22.8658 -971.648 -0.970543 0.233322 0.0600523 --19.7525 29.0709 -977.292 -0.573331 -0.335398 -0.747529 -1.16669 55.0179 -965.513 0.177967 0.974209 -0.138725 --4.02672 59.1296 -959.363 -0.125006 0.836417 0.533647 --16.6258 -19.9222 -995.38 -0.407366 -0.852615 0.327263 --4.75007 56.1032 -947.579 -0.29386 0.834559 0.466002 -13.0895 -23.7661 -1006.7 0.690216 -0.370518 0.621545 --4.66102 54.8164 -944.813 -0.0209486 0.755525 0.654785 --17.1843 -44.3927 -964.001 0.874263 0.285606 0.392547 -0.312688 54.74 -968.968 -0.249187 0.70877 -0.659963 --7.3984 60.1911 -954.261 -0.147567 0.973219 -0.176262 --31.9156 -31.0642 -1016.83 -0.840969 -0.395642 -0.369105 --4.60454 58.136 -958.043 -0.415841 0.889126 0.191132 --24.1778 30.1418 -973.072 -0.615711 0.252814 -0.746315 -5.64147 -1.23631 -1020.27 -0.195567 0.740861 -0.642556 --23.2783 28.1336 -973.693 -0.247461 -0.415153 -0.875449 --24.0044 28.5458 -973.557 -0.219557 0.0272011 -0.97522 --26.1459 23.6335 -968.2 -0.715213 -0.696782 0.0544505 --30.0046 3.10538 -956.852 -0.766302 0.240359 0.595826 --6.22295 56.9806 -949.952 -0.326796 0.603718 0.727137 --5.29153 54.3459 -944.227 -0.0125498 0.837944 0.545612 --7.21265 59.8616 -952.145 -0.0718834 0.905662 0.417862 --29.4329 23.1037 -964.166 -0.793606 -0.28024 -0.540051 --29.0545 26.135 -969.536 -0.997639 -0.0327384 -0.0603647 --8.30614 59.2316 -955.42 -0.348974 0.796472 -0.49381 --8.33119 59.997 -953.262 -0.495402 0.867482 0.0452922 -19.2705 -32.8123 -997.902 0.414248 0.229541 0.880744 -14.7828 -23.0833 -1007.97 0.441774 -0.540169 0.716277 --28.022 25.1881 -971.186 -0.601384 -0.705942 -0.374143 --8.09632 59.8185 -952.407 -0.385855 0.858168 0.338619 --6.94329 56.0192 -948.654 0.0167102 0.988872 0.147825 --7.37246 60.0228 -962.996 -0.0320234 0.931894 -0.361313 --7.33816 59.9248 -960.805 -0.131657 0.87784 0.460504 --1.84195 44.7971 -933.914 -0.0332922 0.695744 0.717518 --2.74674 55.4582 -968.239 0.132522 0.925631 -0.354463 --28.9163 26.9991 -968.11 -0.907655 -0.188237 0.375139 --27.3249 20.6625 -964.997 -0.883794 0.4677 0.0128562 --27.5792 20.4251 -964.183 -0.860014 -0.343593 -0.377253 --7.57196 59.1717 -959.851 -0.211549 0.593304 0.776684 --6.22832 57.3539 -958.762 -0.376871 0.785565 0.49077 --7.33762 53.487 -942.865 -0.0899948 0.839776 0.535422 --24.8898 22.6765 -951.637 -0.858564 -0.237804 0.454221 --9.50786 58.9212 -953.604 -0.737687 0.6648 0.117723 --8.29458 60.0259 -962.589 -0.32547 0.882769 -0.338804 --27.0031 24.6793 -967.685 -0.765378 -0.557644 0.321292 --8.26302 56.354 -950.325 -0.257632 0.672944 0.693378 --4.03572 55.4083 -967.677 -0.187541 0.965237 -0.182061 --8.47227 59.8827 -961.332 -0.47235 0.836606 0.277445 --8.37183 59.1527 -960.189 -0.517966 0.683731 0.514027 --12.5814 37.9962 -933.392 0.011969 -0.503511 0.863906 --19.9376 -35.6296 -946.625 0.621185 0.018888 0.783437 --9.63225 58.5157 -952.335 -0.671971 0.611233 0.41815 --26.6869 -23.3405 -1034.64 -0.532101 0.0213089 -0.846413 --8.7041 59.8422 -962.312 -0.715106 0.66747 -0.207624 --25.2379 22.2719 -969.93 -0.973804 -0.221698 -0.0505484 --25.3389 23.0585 -971.195 -0.912426 -0.351233 -0.210031 --26.2409 -23.2496 -1034.81 -0.15458 0.364217 -0.918396 -2.16452 48.6058 -973.028 -0.0815182 0.987477 -0.135074 --28.6495 25.4299 -969.505 -0.74215 -0.654795 0.143026 --9.50204 57.5188 -951.487 -0.499186 0.499952 0.707716 --26.789 27.7258 -973.401 -0.25911 -0.173481 -0.95014 --27.2009 25.3315 -967.235 -0.766588 -0.229767 0.599625 --8.07072 56.5964 -958.023 -0.276308 0.957256 -0.0855216 --26.9243 24.7015 -965.984 -0.667043 0.375056 -0.643729 --8.92933 58.293 -959.995 -0.741849 0.579624 0.337188 --26.0671 24.6813 -971.939 -0.480121 -0.606406 -0.633842 --8.18841 56.6108 -958.546 -0.182279 0.87804 0.442515 --26.5178 24.3487 -966.766 -0.861089 -0.508243 0.0146239 -1.56209 48.6668 -975.261 -0.302159 0.886952 -0.349308 --8.51295 56.5768 -957.265 -0.184703 0.952935 -0.240416 -1.44193 -12.5719 -944.479 0.497676 -0.265537 0.825717 -10.4202 15.6047 -940.412 0.618875 -0.529415 0.580271 --8.23018 51.5055 -939.334 -0.18565 0.814949 0.548991 --22.72 29.3369 -974.745 -0.521877 -0.619529 -0.586368 --19.572 27.5032 -976.182 -0.795804 -0.393377 -0.46038 -2.32332 34.0067 -936.19 0.320619 0.8844 0.339174 -22.5079 -32.0376 -998.936 0.0361976 0.649905 0.759153 --9.5388 58.554 -961.408 -0.688009 0.71955 0.0942911 -11.9036 16.4143 -941.535 0.780367 -0.34576 0.521035 --9.26339 52.8576 -942.654 -0.298355 0.816761 0.493848 --5.3454 55.5079 -969.269 -0.139762 0.986619 0.0839609 --25.5115 21.6655 -967.697 -0.89263 0.388334 -0.228931 --9.3025 57.6863 -959.683 -0.256534 0.754007 0.604701 --25.3773 22.1211 -969.115 -0.987075 0.121215 -0.10483 --11.6532 57.1139 -947.15 -0.0769009 0.879087 0.470418 --6.49385 39.304 -933.964 -0.425587 -0.71683 0.552296 --26.821 46.2349 -947.356 -0.32107 -0.0798072 0.943687 -0.503425 48.0598 -975.271 -0.342764 0.715348 -0.608925 --28.7463 26.2198 -971.173 -0.91322 0.135871 -0.384145 --27.6181 26.9615 -972.867 -0.624945 -0.256974 -0.737163 --5.5545 54.7732 -967.165 -0.478948 0.858823 -0.181744 --5.85862 54.5448 -967.411 -0.34639 0.925097 0.155597 --23.5096 30.3104 -974.196 -0.908412 -0.134116 -0.395981 -22.1707 -11.2691 -1021.14 0.902491 -0.369075 -0.222021 --5.61267 43.7819 -933.27 -0.252082 0.464149 0.849129 --25.7041 23.1193 -969.902 -0.808511 -0.57611 -0.120035 --31.7636 -38.5174 -948.974 -0.913595 -0.356781 0.195067 --19.2896 -35.0546 -975.499 0.835686 0.394195 0.382413 -1.20605 -18.4837 -944.589 0.93417 -0.345225 0.0902525 --10.4862 51.6832 -940.819 -0.212855 0.846413 0.488137 --25.5372 22.4767 -967.217 -0.970767 -0.078079 -0.226971 --13.0375 56.4203 -946.484 -0.233014 0.756507 0.611066 --7.28323 54.5516 -967.963 -0.159141 0.851956 0.498844 -9.48278 -26.1492 -966.041 -0.985346 -0.166272 0.0380389 --12.8572 56.628 -949.463 -0.346368 0.935203 0.0736571 --26.3682 23.9384 -970.603 -0.659897 -0.689594 -0.298323 --7.77908 55.3831 -969.162 -0.224051 0.97456 0.00581244 --28.6868 25.7222 -971.051 -0.809031 -0.465983 -0.358229 --7.65359 55.3097 -968.8 -0.148307 0.850215 0.505114 --13.8025 56.4018 -946.938 -0.420066 0.817032 0.394972 --21.9673 30.286 -943.586 -0.798316 0.361925 0.481354 --14.0315 56.1276 -948.035 -0.772301 0.592819 -0.228292 --15.1866 -41.9273 -980.887 0.943909 -0.160695 -0.288467 --15.1318 59.2436 -952.612 0.133456 0.896213 0.423073 --13.6233 56.1484 -949.55 -0.633907 0.657827 0.406725 -5.42359 13.0618 -1006.23 0.991703 -0.0410213 -0.121825 --19.4512 26.0979 -937.923 -0.902775 -0.165661 0.396931 --12.4761 52.7311 -944.311 -0.166382 0.708592 0.685722 --17.0879 24.474 -935.302 -0.447379 -0.891837 -0.0669294 --14.117 55.4303 -948.613 -0.881414 0.40523 -0.24269 --29.4891 -32.2119 -951.458 -0.297973 0.895474 0.330664 --9.22679 54.866 -968.817 -0.379954 0.873574 0.304145 --14.0552 55.3849 -945.881 -0.5105 0.537283 0.671355 --14.9561 -16.4523 -960.935 -0.06991 -0.969092 0.236586 --9.53093 54.6912 -969.217 -0.586637 0.780534 -0.215926 --16.2609 59.4753 -953.238 -0.129365 0.972632 0.193004 --17.164 59.2659 -953.276 -0.442734 0.880168 -0.171145 --9.91948 54.3055 -968.55 -0.523214 0.851968 0.0199411 --19.5811 -36.7669 -964.75 0.956948 0.244151 -0.156974 --16.7032 58.4644 -951.865 -0.266716 0.803938 0.53155 --4.30827 35.8984 -932.479 -0.13805 0.793731 0.592397 --15.0212 -43.0368 -968.353 0.978694 0.188678 -0.0809881 --15.3868 58.6128 -958.275 -0.0113339 0.921966 0.387105 --9.66485 53.8941 -970.671 -0.716871 0.550054 -0.428412 --18.4922 -36.3334 -975.513 0.701932 0.462055 0.54203 --16.7954 58.4986 -955.416 -0.471888 0.756158 -0.453372 --15.4844 54.5175 -949.243 -0.281951 0.800572 0.528761 --22.982 27.0569 -948.756 -0.0360452 -0.224155 0.973887 --22.9562 27.5615 -948.574 -0.186563 -0.53816 0.821936 --15.8692 58.0336 -957.137 -0.460338 0.886417 -0.0485146 --15.2667 53.8077 -947.675 -0.247024 0.911148 0.329831 --21.0361 -16.2228 -993.829 -0.757613 -0.605173 0.244515 --27.3453 -22.6856 -1031.27 -0.808348 0.483961 -0.335194 -12.2323 29.5408 -947.718 0.544545 -0.736237 0.401778 --15.2398 52.0258 -940.606 -0.0283696 0.925552 0.377556 --4.65606 34.6288 -929.107 -0.206607 0.923027 0.324554 --17.613 58.3089 -952.499 -0.472082 0.730716 0.493146 -14.0075 -19.3986 -1028.22 0.529975 -0.12047 -0.839412 --11.7859 -0.907092 -1021.54 -0.864826 -0.484395 -0.132053 --16.5524 -35.8675 -978.433 0.741179 0.65461 0.148794 --14.8263 22.7573 -935.533 -0.497209 -0.794865 0.347811 --5.72267 48.7587 -974.038 -0.305863 0.948664 -0.0805197 --27.7006 25.621 -971.994 -0.4841 -0.542269 -0.686725 --5.52023 35.2502 -932.09 -0.46258 0.835778 0.295796 --0.260282 -7.48131 -942.205 -0.0307552 0.18237 0.982749 --17.7765 -44.0662 -961.537 0.975032 0.112994 0.191166 --12.4781 54.9731 -967.309 0.00841649 0.991794 -0.127572 --25.7073 32.8412 -953.644 -0.72195 0.0774146 0.687601 --18.0024 -33.8922 -947.827 -0.0704707 -0.00684927 0.99749 --5.91697 34.994 -931.846 -0.639894 0.75915 0.119276 --15.6146 -43.8462 -972.339 0.963934 0.210787 -0.162483 --17.9536 57.8826 -954.657 -0.812527 0.45103 -0.369285 --23.4953 30.8083 -945.553 -0.753508 -0.0780331 0.652791 --23.4314 30.3607 -945.44 -0.47206 0.415284 0.777624 --21.8197 30.3983 -943.21 -0.889133 -0.288221 0.355487 --17.0706 58.1611 -958.172 -0.496868 0.755912 0.426285 --16.701 57.0481 -956.881 -0.597837 0.695709 0.398221 --15.7697 51.0085 -938.708 -0.127437 0.831007 0.541468 --5.8016 34.2245 -928.839 -0.275616 0.826229 0.491306 --21.9832 26.2927 -948.726 -0.152242 0.25083 0.955985 -10.1635 19.7847 -939.863 0.0216843 0.377005 0.925957 --17.4315 53.5583 -946.097 0.184293 0.923291 0.337003 --16.5474 34.4027 -978.594 -0.874367 -0.263612 -0.407419 --6.29885 34.4027 -930.073 -0.708542 0.703859 -0.0505018 --13.4508 54.9422 -965.75 -0.25534 0.955276 -0.149161 --17.2022 59.1352 -960.761 -0.568487 0.818476 -0.0831857 --17.5823 58.0845 -959.243 -0.732083 0.662953 0.156676 --16.8126 52.1221 -941.269 -0.161981 0.92008 0.356672 -10.0045 24.6833 -947.12 0.315019 0.213056 0.924862 -10.8446 28.6637 -946.633 0.773126 -0.533271 0.343363 --6.30931 34.3853 -931.191 -0.48076 0.875746 0.0440251 --29.5498 -30.9936 -955.491 -0.635751 0.73154 0.246314 --17.826 57.7913 -958.739 -0.598078 0.770794 0.219497 --17.0126 56.7937 -956.548 -0.568788 0.822483 0.00111358 -19.8595 -33.8212 -975.818 0.400971 -0.178651 -0.898502 -15.0042 28.5329 -949.783 0.05764 -0.26128 0.96354 --17.4895 58.0109 -961.366 -0.585554 0.599144 -0.546034 --12.9021 17.9652 -1000.48 0.0853522 0.919876 -0.382809 -9.71022 24.9155 -937.626 0.408863 -0.747424 -0.52363 --17.8575 56.5793 -955.207 -0.694213 0.718586 -0.0412586 --18.4966 -33.13 -947.716 0.487646 0.027031 0.872623 --15.5293 -45.458 -965.821 0.822778 -0.0730411 0.56365 -4.1682 22.8369 -936.066 -0.114145 -0.970792 -0.211028 --17.4699 51.3491 -939.918 -0.286734 0.853635 0.434847 --7.53006 48.4373 -974.085 -0.201221 0.957803 0.20524 --18.4081 -43.1749 -956.958 0.969702 0.239488 0.0482009 --26.4147 25.9857 -966.158 -0.971938 0.221427 -0.079418 --14.5531 22.5354 -935.957 -0.386551 -0.903806 -0.183611 --19.1189 25.7088 -937.863 -0.572547 -0.816247 0.0770099 --17.9542 52.8388 -944.098 -0.0771679 0.924668 0.372873 --18.1491 56.0688 -954.443 -0.848114 0.501497 0.170892 --7.53438 33.8735 -929.498 -0.319394 0.929407 0.184906 --18.1698 57.4305 -960.975 -0.834926 0.519123 -0.182784 --22.3694 30.9398 -944.307 -0.827172 -0.306887 0.470751 --15.1605 54.5541 -966.367 -0.309089 0.920901 0.237497 --15.0453 54.7968 -964.343 -0.478179 0.819484 -0.315897 --6.08832 25.8205 -929.118 0.0566414 -0.228052 0.972 -20.5212 -6.95301 -1023.36 0.666133 0.298105 -0.683666 --15.5913 54.9846 -967.832 -0.209625 0.965061 0.157211 --15.5446 54.1741 -965.228 -0.507927 0.858913 -0.0654214 --19.2305 53.0183 -944.923 -0.0898398 0.843469 0.529611 --17.904 50.545 -938.852 -0.37225 0.749884 0.546903 --17.7213 49.3764 -937.408 -0.40364 0.624447 0.668686 --15.3669 -42.4604 -966.848 0.897096 0.387107 0.212997 --8.82539 48.1812 -975.552 -0.709264 0.590388 -0.38521 --14.5138 23.4114 -937.649 -0.46342 -0.848906 -0.254164 --7.73217 23.5145 -935.835 0.251292 -0.87827 -0.40681 --8.55778 33.641 -932.054 -0.425603 0.877756 -0.220013 -5.5753 24.6747 -938.837 0.0766345 -0.824515 -0.560627 --19.1422 -38.1728 -966.081 0.861472 0.490661 -0.130833 -4.30394 24.9811 -940.436 0.248109 -0.903721 0.348898 --17.2439 -48.7146 -962.973 0.925138 -0.351197 0.144153 --19.4963 52.2582 -943.841 -0.385192 0.808572 0.444791 --18.9979 51.202 -941.054 -0.530495 0.728572 0.43331 -11.0788 28.989 -945.599 0.570852 -0.811766 -0.123138 --18.931 -31.8878 -949.143 0.227223 0.881183 0.414592 --16.6748 45.2081 -933.756 -0.174915 0.737042 0.65282 --9.10133 33.6341 -930.747 -0.367458 0.926475 0.0813597 --16.8887 -30.5436 -954.677 0.663046 0.689388 0.291744 --15.3004 -23.915 -1031.81 -0.693959 -0.016581 -0.719824 --17.0346 46.2369 -935.144 -0.356965 0.664171 0.65685 --16.6155 54.6326 -968.242 -0.484859 0.862097 -0.147309 --24.5538 27.8513 -948.24 -0.223745 -0.599735 0.768281 --16.2747 -42.0221 -971.462 0.920597 0.374281 -0.111424 -14.2073 29.359 -949.189 0.218964 -0.611462 0.760374 -13.2089 27.3881 -949.252 0.273151 0.373544 0.886484 -11.4021 28.542 -947.711 0.700534 -0.357328 0.617712 --22.269 56.63 -949.556 -0.0784731 0.909676 0.407837 -12.9691 29.0634 -948.801 0.493827 -0.509165 0.704901 -5.68191 25.1398 -941.474 0.530088 -0.765327 0.365078 -5.93153 38.1414 -935.328 -0.128056 -0.799004 0.587533 -7.00869 25.5833 -942.966 0.643739 -0.683301 0.344528 --17.5789 44.9022 -933.872 -0.496072 0.615708 0.612222 --17.0658 54.1882 -967.18 -0.632335 0.723699 0.276427 --19.8778 54.8386 -954.597 -0.350453 0.760055 0.547265 --19.8062 54.6278 -954.095 -0.274398 0.938773 -0.208354 --22.5417 56.7911 -950.715 -0.299883 0.947525 -0.110752 --26.1383 38.8718 -951.203 -0.524191 -0.649824 0.550411 --17.7371 24.8375 -934.655 -0.590258 -0.788958 0.170704 --21.8353 56.5099 -951.567 -0.120459 0.832016 -0.541515 --22.4864 56.0942 -948.793 -0.20762 0.705608 0.677504 --18.0178 -42.9254 -963.564 0.930496 0.312117 0.191727 --25.928 -7.91528 -950.555 0.367912 -0.688783 0.624675 --17.3188 53.0646 -964.867 -0.156717 0.980639 -0.117418 -6.36608 31.005 -932.725 -0.40301 0.0745638 0.912153 --10.1363 33.0967 -931.601 -0.484868 0.83445 -0.261909 --17.1218 53.1095 -965.671 -0.488975 0.869627 0.0682087 -12.9178 30.008 -947.466 0.330977 -0.938544 0.0979246 -13.0757 30.0262 -946.947 0.25623 -0.943036 -0.2122 --10.546 32.9141 -930.928 -0.643977 0.763531 0.0480972 -8.08133 26.1806 -941.746 0.340479 -0.901158 -0.268306 -2.52418 -28.4271 -1001.89 0.274295 -0.705327 0.653664 --20.9608 51.8052 -945.012 -0.61625 0.673477 0.408246 --25.8414 31.1373 -954.411 -0.841451 -0.472541 0.26204 --30.1695 -21.6737 -1024.47 -0.960435 0.0484153 -0.274262 --20.4068 26.2641 -948.235 -0.439868 -0.382938 0.812327 -17.7589 24.2912 -952.335 0.824058 -0.155841 0.544649 --24.3478 28.8427 -946.924 -0.245166 -0.899215 0.362361 -24.2933 -12.9619 -1002.02 0.743914 -0.283437 0.60519 --21.0811 56.2489 -960.358 0.115455 0.73369 -0.669603 --8.52339 21.4018 -939.107 -0.427004 -0.188873 0.884305 --22.4878 56.9822 -956.603 -0.552953 0.71891 0.421202 --22.8281 55.7871 -951.96 -0.409657 0.637521 -0.652493 --20.5118 49.5057 -940.758 -0.740673 0.502882 0.445549 -23.826 -15.2683 -1002.7 0.607465 -0.410686 0.679943 --17.6256 53.0329 -966.239 -0.0100757 0.943966 -0.329887 --21.0462 54.2561 -954.466 -0.207403 0.787034 0.581 -12.889 27.751 -949.191 0.413058 0.128259 0.901628 -17.1956 24.5833 -951.704 0.787589 -0.125025 0.603383 -23.4754 -16.7692 -1003.35 0.584011 -0.484019 0.651657 --17.7628 53.4286 -968.512 -0.85142 0.524102 0.0200321 --23.1714 57.0609 -958.109 -0.564765 0.819953 -0.0933677 --17.8164 52.7925 -967.474 -0.896211 0.428697 0.114127 -8.52677 25.0256 -938.479 0.247973 -0.832082 -0.496135 --10.9589 32.2811 -931.912 -0.458775 0.816257 -0.35107 -0.282621 23.5848 -936.24 -0.00133666 -0.95096 -0.309311 --17.9042 53.0169 -968.8 -0.920641 0.324414 -0.217199 -16.8952 21.2519 -962.607 0.76072 -0.323839 0.562524 --23.4573 54.5601 -947.998 -0.495772 0.316993 0.808533 -22.9559 -12.0911 -1000.23 0.596664 -0.352787 0.720786 --19.7233 25.7022 -947.977 -0.584884 -0.241452 0.774346 --22.1314 55.9546 -960.488 -0.324473 0.667772 -0.669924 --23.2201 56.7932 -958.541 -0.556104 0.672173 -0.488806 --22.9658 55.705 -955.604 -0.678168 0.524402 0.514869 --18.9666 -14.8961 -1030.7 -0.96037 0.265836 -0.0837864 --17.0455 -29.6668 -956.052 0.719982 0.562424 0.406577 --18.0732 52.2023 -967.98 -0.962223 0.205385 -0.17873 --21.6801 49.7195 -942.95 -0.543405 0.598659 0.588488 --19.5645 44.5519 -935.959 -0.750212 0.589074 0.300288 -0.701483 23.9078 -936.94 -0.0252246 -0.883067 -0.468568 -8.28778 22.8673 -936.153 0.242726 -0.80135 -0.546737 --19.8661 44.1449 -937.218 -0.954318 0.285865 -0.0869343 --24.0195 55.6866 -958.159 -0.873003 0.408059 -0.267119 -6.49354 22.6175 -936.062 0.0268719 -0.980088 -0.196736 --23.5942 54.9652 -956.338 -0.842308 0.357725 0.403175 --23.4417 53.7728 -953.029 -0.502624 0.753356 -0.424056 --3.77988 23.6579 -935.935 -0.182107 -0.971654 0.15075 --12.8931 32.0054 -932.107 -0.0159127 0.914996 0.40315 --25.8715 53.6616 -947.261 -0.566626 0.737682 0.367097 -5.73221 25.2401 -940.689 0.256466 -0.966103 -0.0295152 --25.7184 52.3145 -949.779 -0.671007 0.741314 -0.0142906 -9.3511 19.9822 -940.068 -0.263339 0.622038 0.737375 --26.8921 51.4318 -947.576 -0.922153 0.147835 0.357462 -9.97873 21.2808 -943.279 0.0160862 0.914817 0.403548 --16.3732 32.4961 -935.793 -0.183967 0.87662 0.444627 --16.9334 31.6854 -933.469 -0.261199 0.892996 0.366516 -21.4357 25.7208 -960.665 -0.316523 -0.820004 0.476871 -14.1646 52.5831 -958.018 0.962511 -0.175657 0.206683 --23.013 28.1646 -947.924 -0.241965 -0.826205 0.508761 --22.1668 28.0809 -946.939 -0.505852 -0.858227 0.086946 -13.2761 -45.7633 -959.815 -0.160675 0.855354 0.492497 --15.9824 -37.3747 -977.559 0.832012 0.388206 0.396299 --15.7916 -36.995 -978.63 0.880015 0.443458 0.170055 -13.5467 56.5881 -957.848 0.885427 0.464525 -0.0153829 --7.14183 24.2167 -937.5 0.0845671 -0.909954 0.405994 -16.6424 54.622 -950.284 0.739216 0.0239017 0.673044 -13.722 50.8926 -947.704 0.849759 -0.303708 -0.430894 -12.0783 45.0043 -939.399 0.836551 0.546678 -0.0364142 -5.81293 19.8857 -941.605 0.408124 0.646546 0.644526 -7.89756 43.2358 -932.696 0.453958 -0.547889 0.702666 -16.4408 47.0042 -945.198 0.876837 0.332728 0.347059 -16.4908 46.8115 -945.665 0.961773 -0.273714 -0.00852709 -10.9965 21.9626 -944.124 -0.125586 0.778529 0.614915 -15.6635 45.714 -947.553 0.96459 -0.259626 0.0464903 --18.8099 -38.6819 -964.955 0.856333 0.513405 0.0557535 --1.49124 50.9489 -970.804 0.41077 0.252405 -0.876105 -9.38565 -25.4992 -1003.09 0.601941 -0.696745 0.390147 --16.0416 -18.5525 -973.451 0.734683 -0.670214 -0.105136 --15.7309 59.0152 -962.035 -0.148518 0.709824 -0.688543 -13.4957 56.1266 -950.702 0.554876 0.5868 -0.589727 -3.05427 42.0221 -932.103 -0.4398 0.062443 0.895922 --12.5788 57.8515 -963.019 0.441895 0.408828 -0.798492 --13.3134 57.5506 -963.426 0.179463 0.354421 -0.917703 -9.0577 23.3374 -936.243 0.60016 -0.731412 -0.323799 -16.3028 55.7943 -950.335 0.779092 0.619339 -0.0971329 --0.59687 23.8333 -937.118 0.315523 -0.916588 -0.245586 -13.3193 55.2378 -951.662 0.701957 0.435048 -0.563906 -13.7468 54.9032 -951.523 0.251066 0.549328 -0.796997 --7.63983 24.1195 -937.443 0.31529 -0.913744 0.256252 --4.33668 8.00856 -1015.16 0.0925752 0.904921 -0.415388 --3.59272 57.9585 -964.392 0.264758 0.499043 -0.825142 -13.2563 53.7802 -952.585 0.983719 0.149972 -0.0990202 --2.86579 57.1815 -964.434 0.37417 0.659464 -0.652 --19.6453 26.0073 -947.583 -0.676333 -0.643225 0.358937 --18.5202 24.7935 -947.148 -0.713998 -0.293631 0.6356 -6.419 57.4023 -963.457 0.437944 0.557955 -0.704906 --24.8349 43.8377 -946.556 -0.52254 -0.0876042 0.848102 -0.0665074 40.9447 -931.632 0.672757 -0.33693 0.658693 -12.2605 56.4603 -959.851 0.427925 0.469433 -0.772342 -0.0646614 56.1147 -963.493 0.257114 0.7973 -0.546082 -8.696 55.2906 -960.33 0.72759 0.336169 -0.597999 -7.40681 55.8507 -962.632 0.849293 0.260761 -0.459027 -13.5342 55.0987 -959.595 0.714767 0.237299 -0.657873 -12.9411 24.6424 -946.605 0.00771144 0.710717 0.703436 -19.6896 -46.4812 -957.742 -0.281503 0.821707 0.495534 --1.04124 22.8562 -938.134 0.733047 -0.0649382 0.677071 --3.66171 40.2297 -931.431 -0.145616 0.244682 0.958607 -9.76223 23.4061 -946.276 -0.12127 0.662317 0.739344 -6.89776 55.0372 -964.08 0.667834 0.621632 -0.409355 --29.4878 -33.4777 -979.855 0.0259032 0.73465 -0.677952 -12.9004 54.0145 -960.18 0.64693 0.356947 -0.673848 -8.11689 22.4079 -945.564 0.131575 0.76014 0.636298 --5.95831 55.2534 -970.611 0.103195 0.86068 -0.498579 -22.2 25.372 -960.858 0.0285687 -0.646954 0.761994 --20.6444 26.6382 -948.11 -0.511873 -0.691533 0.509674 -7.74666 53.6327 -966.712 0.415325 0.824928 -0.383405 --1.55963 53.0404 -970.22 0.42152 0.373589 -0.826288 --3.65675 53.125 -971.479 0.37206 0.399948 -0.837623 -0.741433 16.1644 -937.21 0.104176 -0.618479 0.778865 -12.2935 53.3853 -966.144 0.566177 0.687136 -0.455289 -5.8224 53.4453 -969.354 0.628951 0.676479 -0.383141 -5.25255 53.3165 -970.38 0.530086 0.607721 -0.591341 -4.56112 53.1108 -971.02 0.335367 0.471915 -0.815368 -17.8303 50.3095 -961.285 0.86078 0.438348 -0.258669 --12.4151 19.9781 -940.112 0.317662 0.626162 0.712048 -6.32419 52.7118 -970.352 0.695124 0.464628 -0.548566 -7.54026 50.8863 -968.585 0.651595 0.25726 -0.713611 -14.1601 -25.1128 -1028.61 -0.380727 0.392388 -0.837305 --16.591 30.1092 -931.206 -0.449624 0.095459 0.888102 -12.3394 26.721 -933.997 0.865486 -0.193973 0.461853 --10.7348 22.8416 -936.86 0.173662 -0.982444 0.0681636 --20.3641 -34.0945 -979.165 0.0320724 0.952893 -0.301606 -6.2475 49.9754 -970.896 0.49037 0.611501 -0.62097 --13.2925 22.9556 -937.587 -0.123736 -0.980938 -0.149832 --4.85531 23.181 -937.432 -0.335327 -0.405689 0.850278 -18.0769 43.007 -958.367 0.55422 0.378163 -0.741507 -6.82802 48.1089 -974.321 0.603907 0.715723 -0.350766 -21.0188 37.2337 -962.649 0.450153 0.300276 -0.84095 -6.21879 21.116 -942.809 0.365436 0.621906 0.692596 -17.7816 35.6973 -963.732 0.632134 0.44356 -0.635344 -22.4465 25.7539 -960.69 0.436714 -0.313087 0.843361 -18.902 35.1491 -963.207 0.416798 0.319351 -0.851055 -8.21028 37.7135 -979.944 0.768609 0.123148 -0.627754 --15.5319 20.4436 -939.644 -0.381353 0.759485 0.527022 --0.815043 58.4516 -953.487 -0.156409 0.948639 -0.27499 -15.6116 55.6465 -951.085 0.299566 0.483302 -0.822605 -11.2613 56.9592 -959.806 0.0175193 0.528473 -0.848769 --21.3837 56.5867 -959.499 -0.0970934 0.919857 -0.380047 --6.09512 58.9098 -964.148 -0.12693 0.462031 -0.877733 -11.694 55.4629 -960.161 0.0217447 0.31465 -0.948959 -10.4823 55.4088 -960.018 -0.0659375 0.347803 -0.935246 -5.25877 57.5259 -963.752 0.18898 0.652956 -0.733441 -1.36747 57.7016 -962.996 -0.345295 0.685571 -0.640909 --9.94112 57.4051 -962.282 -0.6663 0.218951 -0.712814 -9.12342 55.0626 -960.19 0.263506 0.665778 -0.698072 --14.1973 57.5907 -963.415 -0.132153 0.539799 -0.831356 --21.1454 55.6397 -960.862 0.0955934 0.457088 -0.884269 --16.7046 -27.9247 -958.906 0.878684 0.320021 0.354262 --20.5731 54.849 -960.954 0.210957 0.427964 -0.878831 -8.35078 54.7315 -961.543 0.611889 0.649466 -0.451426 --27.4616 -14.5107 -979.24 -0.0809985 -0.535683 -0.840525 --4.42839 56.6895 -965.129 -0.120836 0.690326 -0.713336 -5.63242 55.8524 -964.639 0.282072 0.543704 -0.790456 -8.99093 25.7128 -946.072 0.726678 -0.363081 0.58319 -7.35135 25.1918 -944.566 0.741832 -0.335888 0.5804 -8.71382 53.426 -966.762 -0.0567964 0.824446 -0.563084 --0.883419 54.901 -968.534 0.0560428 0.764957 -0.641639 -8.7123 24.5391 -946.431 0.583766 -0.207254 0.785024 -1.65071 25.051 -940.541 0.288592 -0.5218 0.80277 -3.80354 54.3804 -970.458 0.0916555 0.737329 -0.669287 --12.5882 21.5619 -941.251 -0.09647 0.27633 0.956209 -10.0523 52.7309 -968.4 -0.231154 0.215771 -0.948689 -8.83021 52.0883 -967.891 -0.0301611 0.454912 -0.890026 --11.1924 53.3799 -969.726 0.346721 0.416216 -0.840564 --31.4857 -38.668 -948.65 -0.493466 -0.727448 0.476772 --10.363 52.9526 -969.951 -0.497439 0.395486 -0.772105 --13.6556 52.6927 -971.066 -0.0529821 0.456102 -0.888349 -23.2936 26.6217 -961.299 0.858646 -0.0873579 0.50507 -3.32277 50.2158 -971.149 -0.225654 0.0757378 -0.971259 -18.5842 43.5216 -967.454 0.734381 0.302736 -0.607483 --24.1935 41.645 -949.589 -0.648151 -0.481589 0.589892 --4.21089 58.6245 -956.51 0.00189758 0.790679 -0.612227 --5.28137 58.3714 -956.442 -0.168345 0.631375 -0.756985 -5.83066 21.8806 -943.061 0.606997 0.389431 0.692747 --17.1063 58.6705 -954.395 -0.544308 0.778993 -0.311286 -8.08178 22.9185 -946.005 0.371749 0.482746 0.792943 -2.80831 23.4322 -941.133 0.408281 -0.0310901 0.912327 -1.64939 56.9913 -963.628 -0.329681 0.335026 -0.882648 --9.39452 58.5328 -962.713 -0.7981 0.383201 -0.464966 --25.2554 17.5959 -976.831 -0.258225 -0.574863 -0.776436 --13.1934 55.6965 -963.958 -0.133347 0.592734 -0.794283 --14.437 55.3517 -963.806 -0.374578 0.607535 -0.700423 -0.0416289 53.7275 -969.708 -0.510738 0.293549 -0.808069 --20.3685 26.275 -942.097 -0.591255 -0.806458 0.0065379 -1.72334 52.8521 -971.271 -0.268797 -0.115075 -0.956298 -0.718076 52.5355 -970.422 -0.657557 -0.151897 -0.737933 --0.134166 52.105 -969.86 -0.00287099 0.15927 -0.987231 --9.55236 53.537 -971.023 -0.639046 0.265145 -0.722024 --5.98302 49.8885 -972.023 -0.328196 0.597627 -0.731525 --7.68524 33.9729 -933.936 -0.572439 0.808537 0.136317 --16.7343 42.3064 -932.241 -0.413381 -0.162699 0.895905 --8.29501 54.9415 -971.03 -0.331972 0.828789 -0.450448 -11.785 27.0213 -933.304 0.651926 0.272364 0.707679 --8.02203 54.6685 -971.322 -0.109116 0.29418 -0.949501 --5.02081 54.3149 -971.354 0.207891 0.3765 -0.90279 --6.64698 54.4118 -971.313 -0.055006 0.116829 -0.991628 --8.6994 54.0925 -971.159 -0.386609 0.397493 -0.832186 --6.56151 53.6003 -971.735 -0.0729464 0.223452 -0.971982 --16.7595 22.6445 -945.069 -0.193203 0.711307 0.675807 --4.38762 52.8108 -971.728 0.110022 0.133808 -0.984881 --9.30421 53.0703 -971.273 -0.456044 0.0321109 -0.889378 --7.08599 52.7657 -971.634 -0.120687 0.0367407 -0.99201 --1.75472 23.3841 -937.037 0.425549 -0.807294 0.408881 --4.52525 51.525 -971.779 0.206348 0.156874 -0.965821 --3.55094 50.6643 -971.955 0.176975 0.67865 -0.712821 -8.96161 20.8274 -942.3 -0.0758717 0.963276 0.257571 --5.06808 50.7343 -971.989 -0.085049 0.308771 -0.947326 --17.995 -27.7731 -956.745 0.713377 0.390522 0.581882 --5.7373 48.3805 -976.497 0.125882 0.696804 -0.706129 --14.3464 22.8543 -941.496 -0.498229 -0.548663 0.67137 --26.9479 -8.48706 -952.69 -0.203064 -0.950743 -0.234207 --0.744223 47.6197 -975.379 0.0416711 0.633924 -0.772272 --15.1736 21.4989 -941.504 -0.448296 0.771048 0.452233 --2.87832 48.0793 -975.846 0.299915 0.591395 -0.748534 -5.5172 47.8429 -977.1 0.319622 0.458084 -0.829458 -2.80169 47.7901 -977.044 -0.235554 0.548913 -0.802003 -3.10704 21.4235 -940.717 0.536542 0.376096 0.75543 -10.4474 47.6662 -973.77 0.0920754 0.761076 -0.642094 -3.24944 20.7664 -940.328 0.519238 0.591454 0.616907 --4.15746 47.3013 -976.869 0.261382 0.424466 -0.866896 --7.51709 47.6542 -977.071 -0.221845 0.575246 -0.787323 -4.01542 47.5055 -977.41 0.0331559 0.40748 -0.912612 --1.84956 22.5719 -937.608 0.311561 -0.224339 0.923364 --5.76211 47.3888 -977.219 0.108968 0.432655 -0.89495 --8.60226 47.1685 -976.833 -0.639198 0.278994 -0.716651 --10.0018 46.6827 -975.175 -0.181034 0.636449 -0.749773 -11.4601 -51.1655 -956.535 -0.434081 -0.833106 0.342793 -8.78825 47.6086 -973.18 0.14442 0.832668 -0.534609 --26.8983 51.8286 -947.743 -0.94242 0.33443 0.000955323 -0.473749 46.6999 -976.178 -0.312003 0.199445 -0.928911 --21.4748 27.9059 -941.662 -0.778253 0.192193 0.597816 --6.82159 47.3148 -977.297 -0.100834 0.178161 -0.978821 --18.9661 -27.6463 -955.963 0.522549 0.450809 0.72368 --17.6531 23.9569 -946.394 -0.496972 0.312463 0.809559 --1.87812 46.506 -976.236 0.279333 0.236805 -0.930535 --23.9503 -9.20309 -983.93 -0.710271 -0.456372 -0.535948 --20.4339 43.6494 -935.858 -0.915414 0.363249 0.173399 -5.56798 46.5569 -977.164 0.460774 0.21691 -0.860603 --17.672 24.4218 -946.32 -0.76968 -0.523959 0.364775 --3.4821 46.2387 -977.02 0.341907 0.212575 -0.915375 --4.41013 46.0632 -977.267 0.120397 0.00941232 -0.992681 -16.0542 47.7534 -946.538 0.776683 0.607191 -0.167579 -11.6527 46.1799 -974.46 0.225531 0.463236 -0.857058 -10.4499 46.5383 -974.639 -0.162717 0.410988 -0.897002 -5.87185 46.1529 -977.256 0.532208 0.0765548 -0.843146 -3.19354 46.3107 -977.722 -0.0156389 0.154483 -0.987872 --20.695 26.6756 -940.589 -0.810416 -0.519207 0.271384 --7.91118 46.5177 -977.148 -0.245802 -0.0405139 -0.968473 --11.3812 22.5405 -938.769 -0.0938568 -0.982976 0.157954 -12.7892 45.3093 -974.298 0.436199 0.0922057 -0.895114 -10.9565 45.7494 -974.927 0.175285 0.247515 -0.952896 -5.29859 45.6181 -977.379 0.243915 -0.216637 -0.94529 -8.21722 26.5783 -930.834 0.373589 -0.147581 0.915779 --2.13964 45.1693 -976.491 0.403046 0.127157 -0.906303 -4.62254 22.2504 -942.133 0.578735 0.0948347 0.809983 -10.5193 44.7599 -974.993 -0.241218 -0.135955 -0.960901 --16.5559 -26.1314 -960.496 0.951337 0.14197 0.273499 -5.37352 43.6751 -976.653 0.535439 -0.170564 -0.827172 --0.0875174 24.7695 -939.055 0.742986 -0.65281 0.147685 -4.96587 42.3105 -977.059 0.365544 0.37043 -0.853908 -5.63471 41.9238 -977.049 0.324816 0.628001 -0.707184 --16.3782 22.1763 -944.356 -0.535908 0.645681 0.543966 -3.96066 41.6142 -977.715 0.133796 0.639665 -0.75692 --14.9639 22.1253 -942.048 -0.791094 0.305383 0.530012 --14.3625 21.5701 -941.121 -0.17688 0.924469 0.337743 -11.9179 40.756 -973.485 0.391083 0.44951 -0.803116 -1.6116 39.4997 -982.21 -0.334805 0.676286 -0.656158 -3.70244 39.277 -982.929 0.00377729 0.714749 -0.699371 --8.26485 58.7857 -951.073 -0.376955 0.548374 0.746452 -4.60594 38.611 -983.263 0.208767 0.359408 -0.909529 -19.0887 -31.9591 -998.16 0.808874 0.444439 0.384964 -9.83784 37.2786 -980.303 -0.146304 0.438061 -0.88696 -5.71202 37.3342 -983.332 0.30041 0.108878 -0.947576 --18.3427 -39.446 -961.181 0.97279 -0.0814436 -0.216902 --8.95127 22.3479 -938.673 0.167158 -0.469282 0.867083 --1.85837 22.1093 -937.545 0.225047 0.383374 0.895755 -11.6293 36.5331 -980.107 0.349508 0.06059 -0.934972 -6.09578 24.7467 -942.961 0.734014 -0.437058 0.519811 -13.706 35.1223 -979.065 0.684925 0.0115382 -0.728522 -16.7299 34.2571 -974.724 0.375348 0.0809019 -0.923346 -23.234 -32.4507 -998.832 0.434602 0.323702 0.840439 -2.94541 22.5708 -941.101 0.490772 0.224104 0.841974 -16.1035 33.1125 -974.573 0.23926 -0.271696 -0.932167 -16.2491 32.1189 -974.442 0.154252 -0.254279 -0.954751 -7.99358 23.3947 -946.13 0.53287 0.0870387 0.841709 -2.3618 25.2702 -940.268 -0.0584866 -0.955302 0.289788 --9.87429 -23.5543 -1035.39 -0.247351 -0.272896 -0.929702 --8.1365 48.3716 -976.05 -0.34414 0.822602 -0.452651 --9.00736 47.9169 -974.794 -0.801381 0.454751 -0.388574 -14.3317 26.2841 -948.518 0.119754 0.68994 0.713892 --4.98067 59.3645 -955.816 0.0399882 0.832019 -0.553304 --7.42899 41.4753 -932.517 -0.612246 -0.0713716 0.78744 --9.24916 47.0451 -975.679 -0.671735 0.364659 -0.644822 -11.3748 27.9279 -933.392 0.572829 -0.232142 0.786115 -3.20925 40.4927 -978.665 -0.137895 0.86057 -0.49031 --20.7757 26.6956 -944.557 -0.588386 -0.806253 -0.0613011 --18.2577 25.0083 -945.868 -0.614423 -0.788928 0.00879775 --14.984 -40.1281 -978.669 0.993228 0.0851737 0.079023 -1.90307 40.2996 -978.938 -0.183395 0.968377 -0.169153 -1.81394 40.301 -980.524 -0.377645 0.915906 -0.136016 --9.03964 45.6457 -976.584 -0.633183 0.0157758 -0.773842 --16.5798 23.1224 -945.243 -0.806557 0.0805882 0.585638 -16.9491 41.6218 -949.511 0.928489 0.367493 -0.0534589 -19.9309 -11.2904 -997.815 0.473548 -0.365057 0.801552 -18.6271 47.1892 -958.722 0.928286 0.263252 0.262647 -18.5914 47.8842 -960.36 0.978487 0.205658 0.0163518 -4.39133 24.5068 -941.266 0.516142 -0.637373 0.572148 --18.1075 6.00792 -1007.91 -0.244736 0.531603 -0.810865 -13.0868 48.0867 -967.764 0.599364 0.569777 -0.562242 -18.6709 45.7407 -955.642 0.653234 0.739876 -0.160836 -9.61993 20.5965 -940.739 -0.222371 0.889863 0.398366 -5.89421 48.3025 -976.477 0.598331 0.616969 -0.511223 --14.5397 8.16931 -1011.75 -0.394353 0.66253 -0.63682 --9.70681 20.5642 -940.082 -0.521234 0.504725 0.688163 -6.64912 47.3456 -975.908 0.656873 0.467104 -0.591889 --13.4048 8.45402 -1012.26 -0.819914 0.52167 -0.2358 --16.1272 -41.003 -967.339 0.772778 0.619029 0.140057 -3.61481 39.4389 -935.929 -0.318531 -0.419132 0.850216 --7.02586 7.78654 -1014.17 -0.395177 0.850649 -0.346744 -14.1684 45.8995 -963.982 0.58486 0.810597 0.0295096 -14.222 46.4743 -965.349 0.899019 0.421914 0.117275 -11.1873 48.2234 -972.674 0.190368 0.88853 -0.417462 -7.70758 46.8064 -975.349 0.664956 0.442365 -0.601786 -14.1257 31.2517 -936.502 0.952528 0.125893 0.277201 -20.5417 44.6979 -954.802 0.676111 0.7317 -0.0865385 -12.6625 48.1819 -971.545 0.383867 0.900405 -0.204738 -1.20869 22.4328 -940.065 0.556237 0.364391 0.746873 -20.2923 44.6645 -955.782 0.642398 0.657061 -0.394456 --14.0822 9.58528 -1010.02 -0.961082 0.12712 -0.245281 -17.7989 44.6637 -957.547 0.596113 0.208076 -0.77547 -17.1025 44.261 -958.327 0.853661 0.258938 -0.4519 -14.2142 46.8196 -967.361 0.884601 0.460658 -0.072632 -15.8399 27.0886 -949.337 0.262095 0.601451 0.754694 -19.1996 44.5332 -957.054 0.498355 0.490379 -0.714962 --21.6499 27.5271 -942.344 -0.877948 -0.177588 0.444601 -12.153 47.6612 -973.055 0.713109 0.700802 0.018761 -18.256 39.3082 -949.267 0.932234 0.350958 0.0881439 --3.01207 23.3131 -936.835 -0.0126716 -0.809607 0.586835 -5.01079 22.962 -942.543 0.693184 -0.0629861 0.718004 --17.5923 -25.5088 -958.221 0.847839 0.151278 0.508216 -14.1341 46.6602 -968.755 0.732366 0.6318 -0.253907 --30.4896 -47.0454 -953.59 -0.926627 0.0324681 0.374577 -20.1808 43.5333 -957.016 0.645275 0.398586 -0.651728 -17.4426 43.2156 -959.129 0.871373 0.49042 -0.0140415 --13.4937 21.6474 -941.179 0.117837 0.765975 0.631978 --10.2373 20.9276 -940.66 -0.41702 0.228179 0.879789 -14.9459 45.298 -967.775 0.780323 0.595514 -0.190944 -17.9699 42.7221 -958.726 0.783424 0.56347 -0.262198 -18.0416 43.4052 -961.346 0.730158 0.675329 -0.103927 -24.582 2.46174 -976.399 0.709829 0.0652448 -0.701346 -6.51388 20.0299 -942.027 0.115851 0.733972 0.669226 -14.5694 45.8798 -969.47 0.745257 0.61981 -0.245819 -15.2403 45.1921 -967.439 0.460935 0.606548 -0.647795 --12.5916 22.8389 -939.049 -0.379505 -0.924427 0.0375557 --6.07832 24.1659 -937.361 -0.296743 -0.765593 0.570798 --5.45739 22.6594 -937.662 -0.240625 0.0567226 0.968959 -14.6331 46.3464 -971.849 0.924643 0.256248 0.281732 --19.8225 25.9353 -941.288 -0.526554 -0.847658 0.0649288 -18.6527 37.8021 -948.976 0.946301 0.169012 0.27559 -11.3775 -24.5574 -1005 0.691096 -0.610403 0.387033 --21.0729 27.3078 -940.886 -0.897779 -0.104102 0.427967 -21.5123 42.9641 -954.552 0.99223 0.0236259 0.122157 -14.2104 45.4841 -970.752 0.927076 0.363431 0.0919128 -18.9024 37.9829 -951.065 0.927328 0.357509 -0.110679 -17.0154 45.0742 -966.962 0.391095 0.846104 -0.362149 -17.5738 44.9597 -966.248 0.586641 0.808941 -0.0383055 -15.7093 44.346 -968.378 0.374404 0.663807 -0.647442 -15.3473 44.4346 -968.774 0.841491 0.484137 -0.239802 --14.4533 22.5391 -941.731 -0.505832 0.207286 0.837357 --18.3543 -24.9351 -957.466 0.620672 0.183194 0.762369 -25.3557 -22.5252 -976.109 0.995632 -0.0886729 -0.0292371 -18.5526 36.2792 -948.497 0.921484 -0.0642398 0.383068 -18.3598 42.109 -960.436 0.864772 0.469215 0.178902 -19.1858 40.9068 -958.004 0.723629 0.503201 -0.472387 --24.5548 12.4232 -970.722 -0.911111 0.10609 -0.398274 -18.6739 42.6951 -963.1 0.842984 0.497512 0.204599 -18.8375 42.424 -961.756 0.840113 0.532559 0.102911 -16.785 44.2865 -968.239 0.347232 0.702192 -0.621575 -12.4259 41.7518 -937.802 0.843078 -0.349441 0.408792 -22.3213 28.0768 -960.386 0.584172 0.144523 0.798659 -21.8887 27.8143 -960.151 0.142183 0.123643 0.982088 -14.9278 44.1166 -971.641 0.842718 0.420718 -0.33589 --26.3846 -42.6018 -984.504 -0.0890695 -0.747566 -0.658188 -19.2237 36.5843 -951.137 0.988993 0.135577 0.0592638 -18.9977 37.0347 -952.041 0.935439 0.214807 -0.280733 -18.0716 37.5817 -954.216 0.975508 0.192674 -0.106114 --15.699 22.4237 -943.415 -0.885415 0.0367854 0.463344 -15.2781 43.5664 -971.129 0.966622 -0.0365518 -0.253587 -19.4736 40.7109 -959.829 0.761535 0.64661 -0.044267 -18.9318 41.2039 -961.287 0.937726 0.343976 0.0484825 -19.1442 41.7652 -962.08 0.934132 0.307393 0.1814 --11.5984 19.8109 -940.156 -0.0542629 0.684609 0.726888 -14.5382 43.4194 -972.814 0.822429 0.130929 -0.553595 -1.80369 40.1596 -981.231 -0.297079 0.883066 -0.363232 -19.2088 35.3286 -950.639 0.974393 -0.0205346 0.22391 -18.2464 36.2496 -954.227 0.914013 0.162342 -0.371787 --17.9403 -39.6573 -965.839 0.739177 0.645213 0.193177 -20.1797 40.0872 -959.39 0.514339 0.816375 -0.262654 -14.3819 42.9887 -972.986 0.81554 -0.339075 -0.468959 -19.2593 41.5373 -963.458 0.963379 0.266147 0.0326479 -19.2663 42.5233 -965.718 0.835899 0.515593 0.188244 --20.9027 -48.2688 -950.343 0.495546 -0.498962 0.710964 -19.5675 41.864 -964.947 0.962337 0.244148 0.11958 -17.571 42.4503 -968.295 0.679259 -0.0279909 -0.733364 -16.8153 32.2186 -948.355 0.816389 0.537561 0.211038 -14.9031 -20.0166 -1027.38 0.619879 -0.250581 -0.743612 -20.4568 27.0065 -960.267 -0.1219 -0.259192 0.958102 -7.19419 40.5392 -977.728 0.389779 0.742744 -0.54443 -20.0135 26.7341 -960.497 -0.106849 -0.257241 0.960422 -19.8518 40.0649 -961.166 0.713305 0.600337 -0.36165 -18.0695 28.0063 -951.693 0.920534 -0.206168 0.331833 --15.8001 24.4138 -940.124 -0.406951 -0.89573 0.17905 -21.9895 38.7323 -956.604 0.578461 0.552665 0.599953 --13.5661 23.1723 -940.173 -0.503541 -0.802903 0.31905 -19.3579 34.4422 -952.456 0.96882 0.141685 -0.203255 -22.081 39.6588 -958.461 0.567864 0.813438 0.125892 -19.6165 40.3419 -963.857 0.898665 -0.428751 -0.0925982 -8.65033 39.5411 -976.409 0.079228 0.986804 -0.141214 -20.8656 39.2491 -960.208 0.33008 0.671128 -0.663803 --16.1309 -38.4441 -976.541 0.739898 0.449964 0.500084 -8.38414 40.9043 -973.834 0.555306 0.528391 -0.642214 -13.6141 39.8892 -970.29 0.980846 -0.0282864 -0.192722 -13.6578 40.3159 -971.625 0.878549 -0.451157 -0.156873 -5.71779 39.7118 -981.095 0.507804 0.821975 -0.25786 --16.0385 23.6013 -942.671 -0.598741 -0.720201 0.350457 -4.65341 39.7295 -982.083 0.195764 0.880474 -0.431789 --13.7499 28.915 -979.831 -0.707216 0.116265 -0.697372 --17.3272 24.3704 -943.674 -0.592374 -0.797073 0.117334 -14.3187 40.6189 -943.801 0.905839 -0.248493 0.343085 -22.5369 39.2271 -958.972 0.930746 0.36541 0.0136827 -13.7225 39.3739 -970.234 0.895737 0.378845 -0.232664 -13.4214 40.2178 -972.457 0.878709 0.109901 -0.464535 -12.1488 40.0998 -973.816 0.381081 0.638594 -0.668561 -8.55667 39.2567 -977.901 0.621627 0.697967 -0.355558 -18.0016 30.8355 -948.957 0.954003 0.287007 0.0866363 -22.3594 39.4307 -959.389 0.49507 0.80837 -0.318504 --15.5784 22.9726 -942.803 -0.774452 -0.416137 0.476501 -6.16324 39.4617 -980.478 0.579166 0.769567 -0.268948 -7.2613 39.475 -979.536 0.420664 0.763939 -0.489325 -17.7647 30.8763 -950.098 0.915722 0.394072 0.0784876 --18.294 -40.4484 -962.748 0.977085 0.150571 0.150444 -13.5708 39.5853 -972.855 0.897867 0.429584 -0.0963959 -22.2835 -40.7715 -973.682 0.828486 0.324384 -0.456494 --17.4498 24.7535 -941.574 -0.422098 -0.892414 0.159469 -20.223 38.6762 -962.201 0.491865 0.49192 -0.718389 -0.122527 25.7881 -929.199 0.0451515 0.0651987 0.99685 -5.71173 39.0455 -982.587 0.472065 0.60117 -0.644787 -18.8726 33.553 -954.176 0.887923 0.24087 -0.391886 -22.7567 37.9411 -957.559 0.92816 0.18057 0.325443 -8.72467 41.5947 -973.324 -0.181137 0.0546275 -0.98194 --9.37551 18.7197 -995.208 0.384759 0.727275 -0.568358 -19.3701 32.3732 -952.878 0.997863 0.0194396 0.0623821 -22.5559 36.7933 -956.866 0.933356 0.0322423 0.3575 -17.185 36.474 -963.885 0.861437 0.320514 -0.393951 -17.6056 -14.4098 -994.315 0.855414 -0.496386 0.147879 -22.9192 37.4712 -958.244 0.999032 0.0406511 -0.0168222 --24.991 22.132 -952.331 -0.90225 -0.343571 0.260584 -7.60838 38.5837 -980.51 0.593347 0.649869 -0.474983 -6.68061 38.2937 -981.738 0.603533 0.631525 -0.486748 -7.98155 -24.8597 -1030.26 0.348556 -0.227279 -0.909314 -21.3463 37.6952 -961.869 0.745221 0.506326 -0.433912 -18.2631 29.6219 -950.004 0.961009 0.040821 0.273486 -0.305787 -16.0413 -942.222 0.664257 -0.0612229 0.744993 -12.3562 29.8266 -933.054 0.695626 -0.0137635 0.718272 -19.9137 35.3691 -955.608 0.00187939 -0.423804 0.905752 -21.616 37.4914 -960.956 0.866367 0.267308 -0.421846 --11.7936 1.43196 -1020.53 -0.692353 0.550348 0.466652 -18.9677 32.5129 -954.792 0.926965 0.293659 -0.233452 --18.5534 23.068 -983.891 0.410567 -0.264448 -0.872641 -14.9234 37.4085 -970.41 0.52095 0.843889 -0.128304 -1.63411 26.7039 -930.143 0.109541 0.671252 0.733091 -22.6919 35.7142 -957.542 0.972192 -0.189505 0.137586 -15.5131 37.1623 -969.286 0.703266 0.700412 -0.121818 -19.2018 32.4179 -973.524 0.655371 -0.224903 -0.721046 --18.0805 -39.3295 -971.322 0.834535 0.529005 0.153962 -13.8553 38.5184 -974.423 0.615867 0.690814 -0.378794 -22.033 29.5135 -966.941 0.755153 0.302559 -0.581551 -6.00038 24.0717 -984.406 0.537599 -0.250383 -0.805168 -18.8865 28.829 -952.427 0.858909 -0.190438 0.475403 -11.6586 38.7353 -978.391 0.298879 0.82823 -0.474032 -7.07333 37.6665 -982.313 0.684658 0.331741 -0.648992 -18.7433 33.5146 -974.101 0.865979 0.256034 -0.429567 --0.390135 -14.7763 -941.358 0.512172 -0.0469444 0.857599 -0.694295 -14.4934 -942.488 0.904472 0.139073 0.403224 -18.5452 33.049 -956.512 0.949415 0.0290926 0.312674 -22.7622 36.3721 -959.364 0.862445 -0.1704 -0.476605 -17.4576 36.395 -967.428 0.684985 0.71738 -0.127126 -18.8774 32.1625 -957.378 0.973278 -0.0539519 0.223203 -14.9505 28.6586 -976.229 0.324203 0.922071 -0.211368 -19.105 29.863 -952.613 0.959762 -0.0970093 0.263527 -17.992 35.0543 -964.45 0.825304 0.558899 -0.0806503 -14.8438 37.7967 -973.366 0.80683 0.586578 -0.0703615 -22.1474 -27.6681 -1025.09 0.911783 -0.257891 -0.319599 -21.5161 -28.241 -1026.18 0.754528 -0.535602 -0.379233 --15.3943 -38.7331 -977.766 0.934415 0.269743 0.232609 --8.82979 28.9122 -985.874 -0.596442 0.488726 -0.636713 -10.1143 38.1793 -938.177 0.818006 -0.295205 0.493681 -19.4448 30.1869 -953.889 0.988898 0.034973 0.144423 -20.5117 -30.4491 -1000.88 0.113541 0.97063 0.212099 -22.522 34.9332 -959.307 0.99254 -0.0831583 -0.0891581 --26.9676 28.2163 -973.298 -0.659823 0.349658 -0.665111 -19.4047 30.7831 -956.064 0.96259 0.261501 -0.0709717 -0.208124 -13.8391 -942.062 0.725179 0.26423 0.635845 -18.3779 34.6897 -965.369 0.843052 0.431421 0.321152 -10.5972 31.4743 -979.172 0.293455 0.112221 -0.949363 -13.4765 37.4225 -978.107 0.586608 0.665175 -0.461989 -14.4641 37.1844 -976.132 0.714573 0.653283 -0.250215 -9.5247 30.1261 -983.244 0.201261 0.940019 -0.275424 -14.3458 37.4001 -977.489 0.733858 0.595256 -0.327296 -0.227683 24.5714 -932.548 -0.0777725 -0.782387 0.617918 --29.4604 -37.2169 -999.68 -0.301029 -0.55021 0.778878 -16.6361 28.3692 -976.405 0.228446 0.927973 -0.294412 -17.3206 37.0076 -972.148 0.388515 0.897341 -0.209369 -15.7388 36.5198 -973.834 0.470193 0.78009 -0.41277 -12.9031 37.645 -979.286 0.605053 0.585374 -0.539675 -18.9074 34.5493 -966.178 0.873795 0.463294 0.147787 -21.4335 23.2071 -966.449 0.850945 0.515706 0.0997006 -0.875848 -12.9846 -943.936 0.818068 0.00902779 0.575051 -12.4057 37.2189 -979.937 0.323497 0.34864 -0.879659 --14.2661 12.6682 -1001 -0.411259 0.539553 -0.734675 -15.5319 36.6253 -975.451 0.790318 0.563637 -0.240229 -20.9034 31.2173 -962.007 0.639882 0.356588 0.680732 -20.1486 33.4258 -963.319 0.769083 0.574524 -0.28006 -17.2682 36.4752 -973.298 0.381987 0.784803 -0.488027 -18.0465 36.4561 -972.09 0.817181 0.517554 -0.25368 --13.8999 -7.52142 -941.889 -0.285526 -0.19205 0.938931 --14.6319 33.6226 -981.333 -0.524029 -0.316023 -0.7909 -25.1866 -22.1705 -1014.37 0.874573 -0.480571 0.0645977 -20.7051 34.9127 -955.984 -0.229914 -0.871766 0.432625 -19.8471 29.0145 -955.96 0.990038 0.128521 -0.0575124 -22.4145 34.095 -960.75 0.74861 -0.607866 -0.264732 -13.8339 40.7838 -940.667 0.848625 -0.434124 0.302278 -20.2472 33.3009 -963.841 0.73273 0.665752 -0.140997 -18.8732 28.1877 -959.661 0.962356 -0.177483 -0.205839 -13.4889 39.2113 -943.04 0.565794 0.310497 0.763852 -19.232 29.9291 -960.878 0.438975 0.190107 0.878157 -15.9621 35.8644 -974.468 0.796981 0.384531 -0.465786 -14.6139 36.4239 -978.134 0.855716 0.157306 -0.492955 -13.428 36.4277 -979.506 0.700049 0.34419 -0.625671 -21.7536 22.7969 -966.465 0.642923 0.753589 -0.136942 --14.8819 28.6887 -979.272 -0.627528 0.175916 -0.758461 -15.0108 35.7745 -977.108 0.860428 0.333108 -0.385621 -14.1898 19.4748 -945.474 0.929391 -0.0701454 0.362371 -17.942 29.5833 -949.547 0.569945 -0.43202 0.698942 -8.84062 16.8577 -938.794 0.0834578 0.527432 0.845488 -19.6374 33.9405 -967.482 0.895917 0.390844 0.211126 -18.0742 35.2871 -972.244 0.879861 0.34189 -0.330084 -17.9976 35.9288 -973.297 0.877505 0.426997 -0.218307 -19.8364 27.609 -955.846 0.981462 -0.118884 0.150329 -19.8057 28.0059 -956.764 0.974049 -0.0825248 -0.210754 -15.8192 34.8616 -975.389 0.918873 0.00973301 -0.394433 -20.1566 31.2786 -966.797 0.65289 0.608426 -0.451168 -14.8884 20.4182 -947.511 0.924402 0.0375184 0.37957 -19.3889 26.5538 -954.991 0.928789 -0.26272 0.261398 -23.5611 26.2179 -962.027 0.952205 -0.198494 0.232176 -15.8955 35.2553 -976.282 0.937902 0.143529 -0.315814 -2.05268 27.0746 -930.726 0.206786 0.666064 0.716657 -18.944 30.2191 -960.481 0.984339 -0.0448437 0.170489 -19.6395 32.4566 -966.258 0.856076 0.493234 -0.154449 -20.029 34.9273 -970.145 0.791776 0.586688 -0.169965 -8.78781 30.6371 -980.535 0.327668 0.868149 -0.372762 -15.5092 34.9139 -977.113 0.861801 -0.100445 -0.497203 --1.39763 8.06226 -1013.21 0.0537962 0.72451 -0.687161 -20.4253 32.2299 -965.813 0.598711 0.648426 -0.4702 --16.3759 -39.179 -975.442 0.631668 0.613945 0.473357 -20.4844 34.0853 -970.121 0.970495 0.197077 0.138923 -18.4824 33.9835 -972.87 0.877442 0.377102 -0.296463 -10.4412 39.173 -938.823 0.784807 -0.1981 0.587227 -17.5469 23.4998 -952.273 0.885859 -0.248161 0.392008 -21.334 31.8433 -964.099 0.871527 0.48679 -0.058959 -20.1122 32.8402 -968.201 0.966819 0.237059 0.0952032 -19.52 26.3416 -956.465 0.952184 -0.300455 -0.0554356 -8.09753 42.201 -973.348 0.458688 0.185015 -0.869123 -19.8962 32.2182 -967.604 0.961496 0.144363 0.233846 -12.9491 43.9999 -938.15 0.834032 0.511985 0.205575 -19.9312 33.0569 -969.508 0.733474 -0.462867 0.497765 -19.2792 28.2743 -960.435 0.0989261 0.128711 0.986736 -19.1096 25.7562 -957.449 0.911077 -0.283177 -0.299581 -18.1579 34.1405 -974.534 0.427173 0.142197 -0.892918 -21.88 30.4185 -963.761 0.791946 0.607055 0.0656247 -14.2178 30.4999 -974.469 0.546716 -0.060725 -0.835113 -19.8782 32.4627 -970.151 0.999897 -0.0142762 0.00177008 -22.3799 29.7286 -961.493 0.664835 0.676493 0.316783 -12.1607 42.4135 -936.413 0.74757 -0.407579 0.524422 -21.3702 1.96747 -977.959 0.650596 -0.27877 -0.706408 -22.7063 29.9032 -962.56 0.757805 0.618111 0.208977 --15.3884 -42.2906 -969.044 0.88039 0.456453 -0.128702 -23.0031 29.2134 -962.153 0.763115 0.554602 0.331772 -20.5634 28.9885 -960.416 0.0337383 0.367418 0.929444 -17.9472 26.0128 -968.068 0.286029 0.551306 -0.78374 -20.3619 31.6828 -970.003 0.978688 0.189072 -0.0801333 -19.8689 32.0066 -971.564 0.891845 0.398882 -0.213319 -19.6015 22.8507 -964.05 0.176866 0.327543 0.928135 -20.2518 31.5152 -970.786 0.961331 -0.10549 -0.254389 -18.5596 27.4702 -960.448 0.948094 -0.312293 0.0599225 -22.0343 29.7857 -964.776 0.830799 0.484378 -0.274136 --25.3523 49.1871 -965.12 -0.957431 -0.133168 -0.256111 -22.2029 29.8726 -966.302 0.860217 0.453486 -0.23319 -0.351046 8.6475 -1013.1 -0.415374 0.828013 -0.376643 -18.9137 31.5807 -958.402 0.997772 -0.0623034 0.0238686 -23.2519 29.2744 -963.917 0.763506 0.625905 -0.159065 -23.1444 17.9173 -964.2 0.804962 -0.213305 0.553659 --22.2689 -32.868 -972.342 0.21253 0.713981 -0.667129 -23.8847 28.3797 -963.282 0.982648 0.176459 -0.0571498 -23.352 28.6123 -964.404 0.803906 0.317881 -0.50268 -8.01117 25.9868 -983.937 0.301958 -0.312508 -0.900644 -23.3417 26.9503 -961.74 0.970632 0.0214974 0.239609 -10.9218 13.7004 -947.445 0.905335 -0.220263 0.363114 --21.9013 -32.5619 -972.137 -0.0708173 0.339494 -0.937939 -23.7763 26.6515 -964.016 0.991761 -0.0135817 -0.127381 -23.1736 27.222 -965.297 0.896062 0.336619 -0.289413 -5.0164 24.8831 -931.128 0.224732 -0.899253 0.375287 -6.59738 25.2398 -931.572 0.287126 -0.804137 0.520503 -11.1842 26.1979 -933.025 0.482702 -0.775242 0.407429 -12.5826 16.9979 -942.541 0.904322 -0.254462 0.342712 -13.6501 18.2156 -944.841 0.876343 -0.467601 0.11564 -13.2705 30.8711 -977.708 0.917117 0.320623 -0.236848 --17.2215 -48.0819 -955.797 0.985597 0.0581334 0.158803 -10.2082 30.3451 -981.842 -0.134511 0.973882 -0.18292 -10.7555 30.5115 -980.313 0.0891792 0.981786 -0.167762 -20.263 32.1125 -961.34 0.77072 -0.416625 0.482093 -14.1925 19.1545 -949.364 0.801655 -0.596958 0.0314742 -19.0423 33.1981 -956.777 0.349508 -0.537329 0.767542 -14.7066 19.6444 -951.127 0.844745 -0.520024 0.126416 -15.612 20.8062 -950.37 0.788094 -0.607688 0.098093 -11.1921 42.4204 -935.474 0.547126 -0.4128 0.728182 -15.7528 21.1001 -950.013 0.895958 -0.374999 0.237979 -16.2881 22.4014 -950.465 0.848171 -0.0640619 0.525834 -16.2162 24.51 -950.346 0.867801 -0.388934 0.309275 -15.7792 28.9168 -973.797 0.664043 0.6543 -0.361854 -17.7944 23.3553 -953.148 0.875157 -0.441505 0.197923 -17.3872 22.488 -954.269 0.792717 -0.608721 0.0325423 -11.556 30.4029 -979.881 0.306576 0.951266 -0.0332213 --16.9594 -39.7286 -973.511 0.778813 0.528014 0.338601 -13.3717 30.9561 -934.381 0.880294 0.090427 0.465731 --17.5311 -38.3324 -974.684 0.745377 0.556783 0.366614 --14.601 42.1421 -931.769 -0.0789329 -0.69312 0.716487 -11.3241 31.1812 -932.349 0.490518 0.318111 0.811294 -17.2795 23.129 -961.766 0.882685 -0.314024 0.349653 -14.9835 32.3701 -974.685 0.530312 -0.419523 -0.736729 -11.4965 55.0466 -947.358 -0.00175788 0.287549 0.957764 -21.7135 27.4317 -967.552 0.581825 -0.233485 -0.779079 -6.63012 55.4905 -949.63 -0.0585421 0.763021 0.643718 --26.3869 -33.2425 -978.073 0.444374 0.796287 -0.410438 -17.2663 23.7785 -960.032 0.910351 -0.412437 0.0340011 --5.34115 57.911 -950.095 -0.278369 0.587542 0.759806 -25.6944 -15.8656 -968.224 0.941257 -0.314294 0.123508 -6.01108 54.3107 -948.151 -0.204639 0.820581 0.533638 -5.47687 54.3529 -948.158 0.23799 0.707476 0.665461 -7.79429 53.7976 -946.16 -0.181693 0.836168 0.517504 --1.31997 26.8744 -929.455 0.167779 0.414361 0.894514 -11.4594 30.5469 -981.665 0.0852167 0.994844 -0.0549792 -10.9285 30.7948 -979.481 0.351591 0.782982 -0.513151 -5.05788 53.4262 -946.724 -0.0428784 0.876726 0.479075 --25.213 49.7303 -956.539 -0.68717 0.693841 -0.215363 -8.38946 30.7865 -980.896 0.678852 0.708376 -0.193298 -14.5581 50.6161 -943.829 -0.364846 0.458962 0.810087 --0.11223 54.3401 -944.469 0.109803 0.339528 0.934165 --13.7711 57.2656 -950.846 -0.147399 0.677223 0.720863 -20.4336 21.946 -963.622 0.131455 0.322187 0.937505 -13.9917 49.2367 -943.736 -0.380879 0.153139 0.911855 -21.2502 22.5334 -964.439 0.517368 0.559229 0.64776 --17.9662 -39.3992 -968.64 0.698045 0.715383 -0.0309747 --16.87 57.7219 -950.714 -0.346813 0.705768 0.617747 -0.943271 27.9576 -930.924 0.315184 0.675516 0.666587 --3.61814 54.4697 -944.142 -0.0208928 0.753781 0.656794 --17.7757 57.2569 -950.987 -0.644718 0.14085 0.751332 -22.4762 33.8413 -958.586 0.932472 -0.354591 0.069005 --18.4231 -13.5382 -1030.23 -0.844417 0.501945 0.187113 --17.2219 -46.0814 -956.669 0.973094 0.228313 0.0309979 --22.067 57.3545 -957.479 0.0298203 0.997038 0.0708964 --11.5006 56.0161 -945.689 -0.0765793 0.737003 0.671537 -19.0528 31.7153 -958.855 0.822992 -0.520775 0.226888 -22.4301 35.0318 -961.737 0.903639 0.124503 -0.409799 -20.9244 33.717 -962.222 0.672983 -0.418378 -0.609962 -20.5078 33.072 -962.6 0.93741 0.305191 -0.167692 --21.9901 56.7648 -956.031 -0.078612 0.805452 0.587425 --15.7612 55.428 -950.35 -0.169964 0.289877 0.941851 --8.66716 53.9481 -943.779 -0.249681 0.705323 0.66346 -19.9495 34.2326 -962.986 0.591048 0.0868975 -0.801942 -21.8933 35.3592 -962.431 0.661002 -0.1393 -0.737341 -22.5543 34.6884 -961.359 0.896727 -0.297492 -0.327688 --10.1207 53.7321 -944.562 -0.386126 0.615052 0.687472 -9.90026 30.9869 -931.691 0.216611 0.395497 0.892559 -1.41674 50.9302 -940.653 -0.136621 0.946465 0.292469 -22.5578 35.053 -961.271 0.972529 0.19886 -0.121003 -16.9349 22.4368 -957.659 0.893571 -0.441833 -0.0794688 --17.7799 -41.2293 -963.864 0.754907 -0.112844 0.646051 -16.1165 44.6327 -951.75 0.733671 0.255121 0.629794 -22.1365 33.5166 -958.84 0.574939 -0.815839 0.0620564 --22.5745 55.7958 -955.328 -0.388376 0.500707 0.7736 --12.7794 54.1584 -944.734 -0.296976 0.307535 0.904006 --10.8573 53.126 -944.424 -0.167444 0.599984 0.782293 --6.31404 37.7067 -935.88 -0.594339 -0.464988 0.656161 --24.141 55.4375 -957.415 -0.914387 0.329051 0.235845 --21.1898 55.8935 -948.579 0.0950236 0.748124 0.65672 --23.2055 56.2676 -949.372 -0.655789 0.673598 0.34089 --12.2862 53.0955 -944.536 -0.136682 0.350096 0.926688 --24.1721 54.5869 -957.339 -0.948351 0.216144 0.23219 --20.1824 55.0917 -947.952 -0.0902459 0.673623 0.733545 -19.9118 23.4102 -964.492 0.476247 0.466334 0.745468 -14.0266 33.9091 -978.889 0.727796 -0.304955 -0.61426 -12.4156 30.2566 -980.851 0.350473 0.933581 0.0748018 --17.316 -39.8358 -967.587 0.673746 0.738068 0.0363602 -1.2546 49.0697 -937.585 -0.162759 0.55058 0.818762 --22.8347 54.8992 -947.956 -0.121156 0.41222 0.902993 --23.5655 54.1233 -955.413 -0.792695 0.311437 0.524063 -13.4326 31.9389 -977.38 0.856764 -0.352555 -0.376378 -2.98842 48.2615 -936.522 -0.135633 0.603842 0.78548 --6.41505 50.8738 -938.214 -0.0498918 0.711549 0.700863 -3.42412 47.674 -936.083 -0.152697 0.421543 0.89386 -18.0992 30.3792 -951.005 0.952301 0.0114988 0.304944 -23.4889 -16.2616 -979.123 0.171195 -0.0464951 -0.984139 -16.1916 -36.9469 -1002.81 -0.0076755 -0.951764 -0.306734 -19.5703 2.30525 -955.205 0.77749 0.281294 0.56248 --21.7256 53.4042 -947.738 -0.243026 0.175475 0.954016 -14.0068 -35.3251 -998.357 -0.298051 0.128163 0.945907 -6.41922 46.8512 -935.687 0.0639111 0.378272 0.923486 --3.62939 49.5918 -937.02 0.0563624 0.640864 0.765583 --25.0994 53.4978 -946.823 0.360893 0.864946 0.348748 --21.6292 52.6145 -947.345 -0.529448 0.586409 0.613033 --6.19448 49.8116 -937.232 -0.0884452 0.620847 0.778927 -5.19305 46.1414 -935.389 -0.0404014 0.625424 0.779239 --25.5112 -35.0867 -969.74 -0.971102 -0.236137 -0.0346321 --10.0725 50.4391 -938.68 -0.139686 0.795973 0.588995 -17.7303 23.7972 -962.793 0.854657 -0.154701 0.49561 -4.09744 46.1047 -935.49 -0.186464 0.593684 0.782797 -15.5091 31.297 -974.406 0.290789 -0.341085 -0.893926 -19.6898 31.9438 -972.845 0.920789 0.0211495 -0.389488 --4.48691 48.1508 -935.885 0.0283789 0.560161 0.827898 -20.089 30.1063 -961.003 0.248348 0.379905 0.891064 --6.46364 48.7364 -936.452 -0.12953 0.535809 0.834345 --32.7688 -43.4151 -980.195 -0.738974 -0.481657 -0.471089 --10.0152 49.4638 -937.665 -0.024205 0.655859 0.754495 -19.1297 28.1439 -969.097 0.42559 -0.708929 -0.562399 -14.5463 31.5116 -938.585 0.954385 0.0153821 0.298182 -20.9472 23.4293 -965.598 0.67857 0.597802 0.42682 -20.6488 32.5731 -961.88 0.963519 0.0461508 0.263632 -16.8293 30.5288 -973.537 0.343489 -0.461744 -0.817806 -2.30175 45.2028 -935.316 0.0395463 0.543144 0.838707 --26.4898 52.5269 -947.258 -0.753092 0.0669015 0.654505 --13.1532 50.0678 -937.594 0.115353 0.748056 0.653533 --5.2187 47.5618 -935.607 -0.0989988 0.414502 0.904648 --14.8383 50.4052 -937.771 -0.00775322 0.780795 0.624739 --6.7203 47.5479 -935.845 -0.160337 0.399355 0.902667 --8.74556 56.2893 -963.692 -0.592433 0.128666 -0.795279 -20.1558 26.6512 -967.332 0.409094 -0.187064 -0.893112 --16.5414 49.9394 -937.511 -0.19838 0.724297 0.660333 --6.66203 46.2526 -935.356 -0.106851 0.493317 0.863262 --15.2313 49.0604 -936.398 -0.0775901 0.676309 0.73252 -19.5117 26.2102 -967.673 0.411672 0.514018 -0.752537 -17.266 26.5671 -968.188 0.614331 0.139514 -0.776616 -19.4169 25.6186 -963.252 0.445077 -0.714634 0.539633 -18.3018 26.903 -961.015 0.693701 -0.579844 0.42727 -22.7073 25.1993 -961.44 0.575392 -0.734788 0.35918 --18.5842 -38.8553 -962.29 0.960582 0.0886741 -0.263475 --8.96141 46.3375 -935.809 -0.241896 0.384027 0.891072 -3.23784 43.1678 -932.523 -0.370989 0.536051 0.758298 -20.003 31.4257 -961.556 0.555461 -0.025512 0.831151 --19.1396 48.7896 -937.972 -0.601099 0.570702 0.559446 --17.1675 48.6782 -936.542 -0.30509 0.552275 0.77583 -2.19531 42.4571 -933.028 -0.437906 0.340715 0.831957 --16.2302 48.0752 -935.855 -0.183666 0.485801 0.854555 -23.5439 -32.2393 -999.157 0.503545 0.61843 0.603314 -19.1512 31.2729 -972.961 0.524869 -0.501494 -0.687762 --12.8243 46.4116 -934.769 0.256819 0.762693 0.593585 --12.4375 46.2258 -934.765 0.558129 0.829482 -0.021271 -15.1954 19.727 -953.741 0.855165 -0.511775 0.0823345 --21.3891 48.3877 -941.579 -0.773859 0.182036 0.606634 --19.9116 48.1461 -938.396 -0.758577 0.379239 0.529849 -22.2496 26.1542 -966.435 0.384864 -0.686089 -0.617382 --15.7587 -42.7963 -974.024 0.965389 0.15142 0.21236 -20.41 27.7449 -968.152 0.278785 -0.535269 -0.79735 -10.9291 -48.8716 -957.047 -0.662533 0.435464 0.609443 -23.2266 25.3862 -963.263 0.817558 -0.575608 0.0165695 --0.0692094 42.4011 -932.489 0.0892826 0.653868 0.751323 --18.5338 -38.5367 -971.48 0.762885 0.611765 0.209165 -21.4577 0.514166 -977.643 0.526713 0.0896264 -0.845305 -20.4003 25.21 -966.081 0.99173 -0.128197 -0.00601855 -22.9131 25.0744 -962.94 0.4531 -0.877675 -0.156159 -0.881248 28.7767 -932.011 0.340831 0.421483 0.840349 --8.78085 44.1417 -934.902 -0.319388 0.457517 0.829861 -21.4341 27.0138 -967.463 0.219238 -0.589761 -0.777249 --4.65899 43.868 -933.084 -0.114712 0.683423 0.720954 -1.91054 -18.2074 -976.707 -0.0626578 -0.996478 0.0557321 --21.6067 47.4502 -941.748 -0.401953 -0.0162597 0.915516 --18.7116 47.5592 -936.71 -0.561069 0.387247 0.731602 --0.94757 28.6158 -930.484 0.573079 0.255099 0.778784 --16.8649 46.9535 -935.563 -0.307793 0.453188 0.836591 --2.05452 28.0484 -929.793 0.394524 0.0483705 0.917611 -13.5199 30.9342 -975.749 0.96879 0.15616 -0.192512 --20.0328 47.066 -937.996 -0.796751 0.176956 0.577819 -16.9252 28.401 -972.301 0.720129 0.195773 -0.665648 --15.4684 -43.2301 -966.099 0.804973 0.110827 0.582869 --14.2397 -24.6498 -1032.77 -0.673007 -0.197739 -0.712714 -20.1731 25.8131 -967.359 0.846995 0.167384 -0.504561 --6.78192 43.2365 -933.547 -0.261743 0.473559 0.840971 --5.4996 42.777 -933.011 -0.204636 0.27256 0.940125 --21.2342 46.8236 -941.051 -0.955378 0.0715662 0.286584 --18.598 -38.8736 -966.205 0.713794 0.700182 0.0156204 --3.99409 41.9064 -932.482 -0.384433 0.261963 0.885205 --17.8703 46.0531 -935.633 -0.592674 0.467735 0.655714 --14.1064 45.1849 -933.247 -0.0650183 0.733133 0.67697 --12.8843 44.6568 -932.737 0.209571 0.641112 0.738278 -18.9511 30.1268 -971.982 0.700721 -0.432626 -0.567296 -21.4708 -30.8239 -976.155 0.309953 -0.307893 -0.899517 -22.3049 -5.97588 -955.646 0.604136 -0.421462 0.676305 --20.6455 -37.1936 -983.232 0.160801 0.590422 -0.790914 --19.2334 45.2833 -936.484 -0.761318 0.405993 0.505534 --19.8043 44.7426 -937.283 -0.921254 0.168981 0.350337 -20.5951 25.8091 -966.482 0.554163 -0.619778 -0.555679 -22.8555 -29.8945 -1020.97 0.890942 -0.333604 -0.308109 --23.4074 -35.0784 -998.843 0.116221 0.120314 0.985909 --8.6879 41.648 -933.849 -0.366869 -0.0849189 0.926388 --13.8964 43.3515 -931.71 -0.00977282 0.454008 0.890944 --18.995 44.3425 -934.846 -0.603766 0.57098 0.55628 -13.0435 32.4667 -978.567 0.542286 -0.479695 -0.689796 --17.0774 43.8851 -932.632 -0.465399 0.346873 0.814299 --28.3081 -4.8268 -955.627 -0.871735 -0.0134616 0.489792 -0.0870456 28.9399 -931.68 0.607088 0.150133 0.780323 --16.3567 43.6011 -932.212 -0.221246 0.499572 0.837543 --7.52287 40.4722 -933.741 -0.670125 -0.606183 0.428339 --18.2623 43.5411 -933.493 -0.639173 0.301416 0.707535 --20.1169 43.7682 -935.443 -0.640773 0.562471 0.522529 --15.3099 42.7716 -931.631 -0.289412 0.0699527 0.954645 --19.0145 43.1834 -934.08 -0.572005 0.344874 0.744226 -21.6873 0.0246431 -977.726 0.430841 0.520073 -0.737496 --4.08756 37.4168 -933.336 -0.22682 0.113567 0.967293 -21.212 0.174045 -977.969 0.797355 0.366203 -0.479708 -19.4002 24.2074 -964.453 0.545585 0.197539 0.814442 --5.12032 36.0803 -933.078 -0.613344 0.576623 0.539736 --27.5715 -15.4428 -1002.13 -0.469557 -0.474344 0.744656 --4.37336 34.2459 -928.252 -0.13168 0.795048 0.592081 --4.65863 33.5138 -927.681 -0.224521 0.438614 0.870177 --17.6015 48.2052 -967.731 -0.208873 0.395568 -0.89437 --9.85364 32.6831 -934.17 -0.319509 0.852714 0.413272 -4.09204 25.9466 -929.978 0.0494976 0.408346 0.911484 --15.5668 29.7733 -977.702 -0.463132 0.412755 -0.78431 --3.68812 28.9128 -929.742 -0.519127 -0.413768 0.747866 -20.1667 30.4218 -969.438 0.945232 -0.0759912 -0.317429 --3.59417 28.3643 -929.835 -0.319403 -0.1361 0.937794 -19.7874 29.7143 -969.966 0.922048 -0.0732311 -0.380085 --15.1009 31.095 -931.304 -0.287722 0.721265 0.630074 --25.4002 -26.9634 -1007.96 -0.091508 0.77186 0.629173 --14.4107 30.7906 -930.887 -0.16507 0.451213 0.877017 --2.04121 28.7651 -929.544 0.311974 -0.516941 0.797147 --8.57928 28.2431 -930.498 -0.151955 0.530013 0.834264 --9.77795 28.1603 -930.819 -0.370953 0.661788 0.651484 -22.2127 34.121 -957.057 0.39189 -0.796544 0.460369 --15.2105 29.51 -930.727 -0.12378 0.0207899 0.992092 -8.35008 18.9025 -940.15 -0.4062 0.557718 0.723846 -23.4435 26.0838 -965.29 0.750853 -0.56314 -0.345098 -7.83387 18.5732 -940.01 -0.0509698 0.686396 0.72544 -15.918 29.2312 -973.483 0.663092 0.0642089 -0.745779 -21.933 -25.2438 -961.846 0.749314 -0.0714862 0.658345 --6.57719 58.9554 -950.898 -0.0999564 0.638129 0.763413 -18.3526 -36.2604 -997.173 0.12928 -0.0081115 0.991575 --15.7332 57.918 -950.69 0.0927806 0.390146 0.916067 --14.3794 57.8818 -951.143 0.252554 0.450641 0.856235 -8.1564 31.8013 -932.042 0.0176572 0.782422 0.622498 -18.8569 26.9595 -961.261 0.0259718 -0.803894 0.594205 --16.1869 57.1219 -950.566 -0.179319 0.0832786 0.98026 -19.0584 -10.8071 -955.789 0.0397205 -0.468314 0.882669 --11.9197 55.3951 -945.185 -0.148698 0.575124 0.804438 -22.4753 25.0155 -963.195 -0.108618 -0.994061 -0.00670444 --10.8372 54.6851 -944.716 -0.0132338 0.329094 0.944204 --30.2001 -37.7784 -964.009 -0.739582 0.0574146 -0.670613 -13.831 54.3303 -947.927 -0.0566567 0.400855 0.914388 -17.4374 28.9525 -972.1 0.438519 -0.303526 -0.845916 -22.3807 -34.4431 -964.193 0.837074 -0.0958316 0.538631 -13.6711 31.4111 -975.524 0.869477 -0.31466 -0.380788 -17.7285 -4.0866 -953.809 -0.180329 -0.750884 0.635339 -16.1792 29.5869 -973.361 0.456467 -0.314956 -0.83213 -17.6908 -4.6973 -954.365 0.0460541 -0.484116 0.873791 --22.2758 52.801 -947.887 -0.227541 0.485384 0.844172 -12.9452 53.4151 -948.049 0.138761 -0.011019 0.990265 -15.2872 50.2198 -943.538 0.220631 0.136414 0.965771 -16.8705 -20.9512 -978.558 0.094329 -0.15146 -0.983952 --22.5286 49.2119 -943.115 0.0987034 0.653518 0.750448 -13.4204 48.688 -944.177 -0.235149 0.268215 0.934219 --22.5835 -31.9443 -949.414 -0.0770003 0.891816 0.445797 --14.3942 48.3052 -935.792 0.0339874 0.595524 0.802618 --22.4186 47.5465 -941.798 0.0283544 0.325714 0.945043 --18.8712 -37.6424 -972.757 0.811821 0.513154 0.278603 -18.2894 28.0878 -969.69 0.533459 -0.742827 -0.404511 --23.8296 46.3086 -941.246 -0.20641 -0.407165 0.889726 -2.23175 46.8352 -936.085 -0.116256 0.430168 0.895232 -21.182 29.136 -968.045 0.802893 0.228122 -0.550748 -15.635 33.3853 -941.013 0.907396 -0.0164047 0.419957 -23.0641 25.7921 -965.371 0.373548 -0.842109 -0.388992 --23.6839 45.5037 -941.806 -0.453708 -0.770028 0.44856 -2.78017 24.1397 -933.136 0.0951908 -0.89155 0.442806 -2.06193 46.021 -935.68 0.121629 0.512934 0.849768 --28.9911 -36.1146 -964.613 -0.347574 -0.0587665 -0.935809 -18.2461 25.6253 -962.016 0.897525 -0.396044 0.193903 --9.07869 44.9451 -935.38 -0.187797 0.398595 0.897694 --18.2714 -42.0934 -962.729 0.986028 0.163464 -0.0320757 -20.7226 25.4515 -963.329 -0.231676 -0.962498 0.141154 -17.9538 43.6406 -951.63 0.00131551 0.0572349 0.99836 --19.7133 -38.0141 -968.722 0.734831 0.677938 -0.020588 -19.2905 43.2897 -951.785 0.340621 -0.0150815 0.94008 -17.9399 26.9637 -967.993 0.303428 -0.624101 -0.720021 -2.01725 43.6335 -933.833 -0.197198 0.648871 0.734901 -19.7174 42.1709 -952.138 0.274478 -0.334737 0.90145 -17.4009 27.8501 -971.094 0.886954 -0.392319 -0.243717 -18.1768 41.9174 -952.158 0.0234318 -0.457778 0.888758 --9.15268 42.8431 -934.169 -0.228091 0.362815 0.903515 --3.88792 43.1737 -932.55 -0.217086 0.366718 0.90465 --12.4314 42.6203 -931.634 0.221247 0.301526 0.927433 -10.0949 55.5829 -954.093 0.00452604 0.99928 -0.0376691 --14.2352 42.4335 -931.505 -0.0678314 -0.254799 0.964612 -12.8106 40.6684 -938.768 0.823747 -0.241401 0.512997 -13.1158 29.309 -944.881 0.283779 -0.870148 -0.40288 -1.76109 42.6254 -933.138 0.265384 0.28981 0.919555 -16.8761 30.4019 -948.016 0.309126 -0.856011 0.414351 --16.7932 -41.579 -964.888 0.76303 0.190606 0.61762 -4.60871 42.3701 -931.792 0.0408717 -0.052578 0.99778 --16.4565 -41.4494 -965.598 0.80385 0.426004 0.415146 --9.41751 42.1192 -933.972 0.315156 0.473516 0.822472 --5.02816 41.7031 -932.689 -0.021798 0.550816 0.834342 --7.37261 41.9477 -932.62 -0.310013 0.459357 0.832396 --11.4857 41.2958 -932.299 -0.0833205 -0.707348 0.701938 --1.12406 41.634 -931.76 0.106967 0.559538 0.821873 -2.1481 41.2677 -932.844 -0.215361 -0.301132 0.928945 --9.83897 40.4961 -932.993 0.315912 -0.267092 0.910418 -0.704374 40.0543 -933.719 0.634483 -0.593553 0.495102 --11.0496 39.8649 -933.94 0.274225 -0.275079 0.921484 -16.3363 -4.66162 -954.071 0.36759 -0.460889 0.807749 -20.8042 37.8256 -955.619 0.135095 0.221033 0.965864 -0.956854 12.6895 -1006.38 -0.518256 0.727277 -0.449977 -21.3495 36.6978 -955.454 0.187796 0.00794741 0.982176 --2.35138 37.2826 -933.263 0.316524 0.271425 0.908923 --3.23036 33.6688 -927.554 -0.0522007 0.588474 0.806829 --1.61014 33.7265 -927.617 0.105877 0.516084 0.849969 --3.11274 33.2046 -927.359 -0.0506497 0.186676 0.981115 -13.4011 27.4843 -937.167 0.894998 -0.419826 0.150744 --0.722402 32.8728 -927.433 0.166286 0.123847 0.978269 -12.4851 26.9771 -939.457 0.376745 -0.875297 -0.303179 -14.6206 33.3532 -939.669 0.596848 0.451812 0.663052 --5.64454 27.9171 -930.273 -0.0603771 0.477891 0.876342 --4.50545 32.0177 -927.595 -0.252388 -0.332708 0.908629 -18.6667 33.5499 -949.938 0.636837 -0.74798 0.186988 --30.0839 -44.5456 -964.335 -0.841327 0.54013 0.0207098 --2.22018 32.32 -927.312 0.0311307 -0.215378 0.976034 -7.90714 31.4585 -931.822 -0.201998 0.385879 0.900163 -12.8463 29.0743 -933.839 0.801476 -0.308636 0.512231 -14.3699 41.4227 -942.328 0.96257 0.0709232 0.261591 --16.4525 -41.5036 -972.282 0.856422 0.487113 0.171066 --2.90339 30.8514 -927.879 -0.0717484 -0.487812 0.869995 -15.527 34.2676 -940.896 0.826004 0.139141 0.54622 -7.73528 30.4641 -931.754 -0.414774 -0.0610843 0.907872 -8.65746 30.5844 -931.418 -0.0601904 0.0578411 0.99651 --13.6683 30.3623 -930.783 0.241433 0.236121 0.941253 --1.25289 30.5512 -928.094 0.125929 -0.530917 0.838015 -9.89196 30.4282 -931.614 0.316888 -0.0693245 0.945926 -16.5574 28.357 -949.61 0.0874722 -0.0827056 0.992728 -10.5045 40.0113 -937.897 0.330651 -0.726142 0.602816 -14.0732 29.2805 -975.181 0.855488 0.460481 -0.236849 -9.03185 29.8055 -931.57 -0.0507903 -0.325273 0.944255 -14.1731 29.6917 -944.88 0.396546 -0.899931 -0.181313 -15.4484 31.5235 -943.75 0.921103 0.124331 0.368933 --13.1466 29.1063 -930.74 0.293456 -0.156142 0.943135 -10.634 28.9194 -932.261 0.259463 -0.45731 0.850615 --18.0115 -42.7792 -959.408 0.997511 0.00916333 0.0699105 -21.2694 -36.3927 -963.314 0.581853 -0.0699553 0.81028 -11.6436 28.9011 -932.73 0.537582 -0.345769 0.769057 -5.0981 12.3682 -1007.23 0.407201 0.590325 -0.696924 -18.9585 33.8621 -950.342 0.898521 -0.259498 0.354006 -12.4752 27.7618 -934.778 0.867369 -0.133087 0.479541 --15.4125 28.2285 -930.953 -0.341783 -0.29666 0.891727 --14.0288 28.2965 -930.797 0.0827152 -0.335279 0.938481 --2.55477 28.8598 -929.42 -0.0952374 -0.591382 0.800748 -10.4638 27.842 -932.943 0.336044 0.0114893 0.941776 --3.39458 27.0185 -929.379 -0.0481864 0.146818 0.987989 -13.6203 27.713 -940.216 0.612221 -0.769314 -0.182595 --8.04618 26.9297 -929.641 -0.0792251 0.415309 0.906224 --10.182 26.6073 -929.943 -0.261154 0.456749 0.850399 -5.83824 32.1218 -933.027 0.17507 0.644513 0.74428 -9.66772 26.2613 -931.659 0.436038 -0.474365 0.764754 -9.09481 42.8537 -933.919 0.631966 -0.315912 0.707685 -17.1403 31.182 -945.989 0.884372 -0.0404901 0.465023 --0.357504 25.5675 -929.269 -0.289535 -0.59232 0.751882 -11.9561 23.6423 -945.81 -0.143724 0.703142 0.696372 -2.19913 24.9851 -929.731 0.05408 -0.895632 0.441495 -16.2779 30.7297 -944.676 0.806855 -0.546419 0.224525 -15.7562 30.4172 -947.104 0.193662 -0.980624 0.0295211 --18.077 -42.2889 -963.945 0.879511 0.0514671 0.473086 --27.7671 -34.1951 -965.206 -0.613868 -0.258466 -0.745896 -9.16324 18.5124 -939.631 -0.0680056 0.430002 0.900263 -17.116 31.0153 -946.377 0.596305 -0.787739 0.154554 -15.7402 -1.74976 -948.738 0.838808 -0.307107 0.44954 --23.9202 52.5036 -947.255 0.468847 0.782671 0.4094 --17.4169 54.6438 -949.267 0.147791 0.882781 0.445933 --16.6236 53.9078 -948.096 0.140529 0.917603 0.371829 -11.3794 14.9587 -947.893 0.930652 -0.262663 0.254745 --23.8972 48.8187 -941.84 0.231363 0.58931 0.77407 --28.4467 -33.063 -965.146 -0.592623 -0.218003 -0.775418 --2.30906 54.4555 -944.331 0.198498 0.557368 0.806188 --23.4423 47.2711 -941.175 0.290168 0.145579 0.945838 -3.16099 55.0376 -946.542 0.702894 0.408129 0.582556 -1.37276 54.6421 -944.995 0.386702 0.389594 0.835869 -16.0116 33.087 -942.433 0.930507 -0.327522 0.16397 -15.9206 32.7139 -945.518 0.920457 -0.377637 0.100744 --1.07964 53.4567 -944.382 0.344127 0.535974 0.770914 -11.7407 56.6723 -948.54 -0.00859225 0.792849 0.609358 -13.9631 29.8652 -936.183 0.937583 -0.212746 0.275094 -2.44406 54.0807 -945.34 0.60592 0.196145 0.770966 -12.0545 56.1291 -948.094 0.134531 0.532472 0.835689 --9.52246 37.9618 -935.981 0.599205 -0.19068 0.777557 -16.3361 32.7004 -947.649 0.912434 -0.249059 0.324706 --26.8494 -15.8096 -978.593 -0.152834 -0.423049 -0.893124 -16.5816 32.9635 -948.004 0.885112 -0.294495 0.360345 -15.7227 56.1155 -949.21 0.85992 0.206595 0.466751 -12.2411 54.8907 -947.383 0.270999 0.180724 0.945462 -13.3979 55.2632 -948.37 0.297401 0.424675 0.855104 -15.1807 32.0794 -940.281 0.949576 -0.24915 0.190342 -10.6428 54.21 -947.146 0.483459 0.416541 0.769909 -7.95006 8.67202 -1008.91 0.28171 0.600614 -0.748266 -23.9239 0.674285 -976.911 0.391123 0.174489 -0.903646 --12.0207 47.9235 -935.898 0.216948 0.56036 0.799331 -15.5014 31.9535 -943.549 0.947515 -0.285591 0.143711 --10.6479 47.6919 -936.307 0.28245 0.446714 0.848922 --9.75949 47.7283 -936.505 -0.0638988 0.461836 0.884661 --27.8568 -47.1267 -952.149 -0.817855 -0.51492 0.256847 -11.4316 52.5643 -947.22 0.579822 0.53141 0.617584 -15.7747 32.0065 -945.156 0.937531 0.279205 0.207558 -15.2936 53.904 -947.031 0.550879 0.559515 0.619254 --20.5584 -36.9595 -969.324 0.861178 0.489929 0.135431 -15.8939 32.4158 -946.369 0.919217 0.298328 0.256984 -4.26422 17.5496 -997.293 0.546737 0.295213 -0.783535 --1.98211 49.417 -937.159 0.160347 0.641462 0.75021 -22.3244 -32.4906 -998.709 -0.0353981 0.339006 0.940118 --11.4164 45.3112 -934.885 0.632498 0.576106 0.517734 -0.449107 49.3205 -937.847 0.149212 0.693757 0.704582 -14.3188 28.9228 -939.25 0.955019 -0.243868 0.168725 -18.5021 -33.7504 -961.382 0.284439 -0.188554 0.939969 --21.1423 1.16961 -1014.13 0.095665 0.991511 -0.0880594 --11.1929 13.4686 -1006.03 0.549306 0.523537 -0.651285 --1.15781 48.0022 -936.246 0.207026 0.567425 0.796975 -10.35 -44.7609 -964.159 -0.92174 0.241125 0.303733 --29.4883 33.3569 -957.839 -0.727257 -0.472456 -0.497878 -15.4047 51.9729 -944.834 0.160671 0.728921 0.665477 --6.79747 13.0211 -1023.5 -0.0126757 0.84356 0.536886 -8.04649 27.8238 -932.129 0.247696 0.745867 0.618328 -11.7784 15.7011 -942.118 0.791494 -0.54924 0.268091 --10.3508 43.9577 -934.812 0.204159 0.43115 0.878879 -21.677 34.9052 -955.954 0.332235 -0.460452 0.823167 --7.84768 57.9897 -964.024 -0.328649 0.218519 -0.918825 -13.5224 25.4057 -983.901 0.668383 -0.346808 -0.658018 --10.7589 43.8107 -934.48 0.73913 0.47051 0.481982 -16.783 35.2164 -943.866 0.938128 0.0151036 0.34596 --11.3752 44.0069 -932.915 0.58121 0.506756 0.636705 -3.41271 27.6849 -931.516 0.0975513 0.730764 0.675624 --1.55302 46.3355 -935.112 0.117339 0.584259 0.80304 -5.53263 28.5128 -932.349 0.0297943 0.728372 0.684534 -15.8334 50.1442 -950.42 0.13584 0.120603 0.983363 -0.883248 47.3147 -936.487 0.0785596 0.550808 0.830927 -13.52 34.425 -940.096 0.194503 0.605074 0.772045 -12.4936 49.5536 -944.235 0.509297 0.521978 0.684218 -12.6648 49.8152 -944.555 -0.066502 0.560285 0.825626 -6.59181 28.6032 -932.577 -0.220102 0.220658 0.950192 -14.5181 49.344 -949.399 0.712114 0.340029 0.614227 -8.00177 28.6453 -932.264 0.011172 -0.266064 0.963891 -5.32228 48.3965 -936.508 0.0300506 0.610677 0.791309 --0.659699 21.8198 -989.244 0.300111 0.8257 -0.477653 -16.3857 49.0852 -956.928 0.458805 0.45564 0.762817 -7.24985 28.2042 -932.265 0.0698321 0.437869 0.896322 --11.6361 43.0396 -932.111 0.450796 0.357229 0.818029 --1.51251 29.6094 -928.783 0.156058 -0.667234 0.728317 --9.78006 -21.538 -1035.94 -0.135225 -0.197709 -0.970889 -4.94445 28.8869 -932.951 -0.0565804 0.431942 0.900125 -22.2634 29.456 -961.043 0.535806 0.493243 0.685291 -0.30621 29.3571 -931.777 0.414807 -0.522681 0.744808 -8.01105 48.3784 -937.251 0.490366 0.524692 0.695873 --10.5456 42.1219 -932.591 0.649998 0.298379 0.698908 -5.6699 30.3794 -932.967 0.103117 -0.188678 0.97661 -15.4163 47.5098 -949.396 0.49051 0.451726 0.745214 -16.1081 48.2941 -950.031 0.222076 0.312224 0.923687 -12.9001 -5.28539 -946.549 0.76268 -0.527402 0.374389 -17.3935 35.2299 -946.357 0.910013 -0.327277 0.254493 -15.6616 35.624 -941.64 0.630444 0.401244 0.664488 -13.1348 47.7423 -944.041 0.241233 0.0657794 0.968235 --0.647682 29.9103 -928.901 0.461763 -0.695892 0.550008 -5.90503 31.1074 -932.826 0.488354 -0.217536 0.845097 -12.357 -5.96577 -946.639 0.663736 -0.743782 0.0790157 --24.3469 43.7783 -971.348 -0.982392 0.18376 0.033749 --0.830402 43.8843 -933.191 0.316552 0.481888 0.817055 -6.54977 13.0731 -943.475 0.0630786 -0.887688 0.456104 --0.281654 29.4403 -931.211 0.710009 -0.445636 0.545249 -15.5928 47.1451 -944.176 0.614267 -0.0795522 0.785078 --1.07711 28.936 -930.153 0.645759 -0.615688 0.451578 --3.50908 -21.544 -1035.33 0.15405 -0.312267 -0.937421 -14.0926 46.1816 -944.551 -0.188924 -0.500162 0.845071 -18.2716 34.0797 -956.044 0.64522 -0.245282 0.723552 -25.0387 -23.2766 -974.4 0.912992 -0.17583 0.368143 -1.05602 22.9933 -986.626 -0.512654 0.625545 -0.588114 --17.0935 38.0547 -937.801 -0.448482 -0.748113 0.489072 -16.2096 46.7474 -944.891 0.748149 -0.533851 0.394051 -17.0204 45.8652 -952.601 0.537394 0.428087 0.726601 -17.8423 35.4115 -947.345 0.842061 -0.336633 0.42144 --15.2893 37.9324 -934.778 -0.681037 -0.598753 0.421524 --8.96571 10.3768 -1011.48 -0.000209694 0.852478 -0.522763 -14.0792 45.2449 -944.558 0.877701 0.172313 0.447158 -1.63021 32.3269 -928.273 0.485967 -0.490434 0.723402 -8.45264 45.2873 -934.02 0.31604 0.704107 0.635886 -10.4107 45.4903 -936.363 0.571503 0.644543 0.507887 -14.5388 45.223 -945.16 0.527206 -0.504443 0.683807 -8.59563 22.8237 -935.792 0.427811 -0.902047 0.05734 -14.7101 44.3732 -946.056 0.951859 0.0121443 0.306296 -10.3925 44.3516 -935.947 0.771945 0.31719 0.550901 -16.7116 44.1913 -951.884 0.176512 0.200066 0.963752 --2.5943 45.6865 -934.716 -0.048747 0.506819 0.860673 -10.1493 43.9186 -935.093 0.744703 0.202934 0.635794 -18.9682 44.7404 -952.111 0.316476 0.611112 0.725524 -8.08593 43.6579 -932.713 0.414777 0.185462 0.890822 -16.0164 43.589 -950.144 0.853743 0.373392 0.362906 -3.50254 24.4055 -987.095 -0.0297055 0.983141 0.180422 -0.336917 30.1907 -930.185 0.544229 -0.777237 0.315781 --10.0232 -19.7545 -1036.2 -0.0529468 -0.0941353 -0.994151 -19.1586 44.2883 -951.924 0.487314 0.371738 0.790149 -16.6175 42.7544 -951.359 0.916862 0.267267 0.296535 --2.63569 24.2396 -986.797 0.000656213 0.788572 -0.614942 -16.9137 42.8115 -951.889 0.313673 -0.0616927 0.947525 --0.237846 31.4639 -927.869 0.276037 -0.391685 0.877716 -21.1055 43.6273 -953.44 0.816084 0.0678031 0.573942 -2.17804 32.9302 -928.328 0.51983 -0.117143 0.8462 --1.24042 37.8617 -934.368 0.72287 -0.266664 0.637456 -19.9217 42.6113 -952.181 0.653704 -0.074787 0.753046 -4.27835 29.3034 -932.846 0.251064 -0.31937 0.913767 --6.69847 -20.0176 -1036.3 0.16014 -0.152932 -0.975175 -14.7656 41.4933 -945.234 0.976966 0.0124037 0.213036 --5.45609 -19.9099 -1036.04 0.163749 -0.161713 -0.973157 -13.8245 41.5869 -940.567 0.902143 0.192438 0.386142 -20.3955 41.4573 -953.035 0.73485 -0.406606 0.542833 -10.6864 17.6692 -939.504 0.365573 0.20087 0.908849 --2.87718 40.5396 -931.222 -0.385674 0.163946 0.907952 -2.83441 30.4818 -931.735 0.183178 -0.614515 0.767344 -11.6647 40.8706 -937.387 0.481688 -0.631625 0.607476 -2.78478 32.0193 -929.952 0.504482 -0.703174 0.501044 -17.4285 40.4409 -952.559 0.970745 0.203285 0.127783 --1.07645 36.6311 -933.603 0.662816 0.299569 0.686246 --0.343704 36.4698 -935.111 0.78646 0.310154 0.534121 -17.9259 35.0601 -974.309 0.463791 0.495018 -0.734748 -23.6005 -44.3868 -974.599 0.686958 0.0555625 -0.72457 -1.02694 32.7899 -927.862 0.319303 -0.0262275 0.94729 -11.7211 -26.6675 -1028.43 -0.0592458 0.0864359 -0.994494 -20.781 38.6927 -956.02 0.253477 0.524163 0.813021 -13.0645 42.2101 -939.401 0.969386 0.00750195 0.245427 --11.9298 -0.286368 -1022.7 -0.613866 -0.489872 -0.619027 -11.7395 37.4997 -941.354 0.540202 0.232708 0.808721 -2.51216 28.8283 -932.481 0.212149 0.322083 0.922635 -11.3841 37.4417 -941.012 0.822009 -0.197344 0.534187 --17.6081 -1.67827 -1019.98 0.378586 0.490061 -0.785184 -17.9371 38.3866 -947.511 0.883157 0.193854 0.427146 -18.5212 36.9063 -955.209 0.372392 0.0487259 0.926795 --20.4089 27.7728 -974.878 -0.758377 -0.460025 -0.461781 --10.439 2.47339 -1021.07 -0.583998 0.797448 0.15173 -11.2237 36.321 -940.548 0.385781 0.251338 0.887695 --15.5796 59.0581 -954.983 -0.162735 0.921769 -0.351936 -21.7363 37.5213 -955.768 0.573231 0.274157 0.772169 -17.5434 36.6949 -946.351 0.91593 0.0672661 0.395662 -22.668 -19.8028 -978.567 -0.0335477 -0.1743 -0.984121 -12.8176 57.0254 -958.76 0.640136 0.680501 -0.356573 -11.6106 38.9293 -939.957 0.643742 -0.617835 0.451527 -9.12741 34.9018 -938.932 0.256754 0.708951 0.65686 -16.0863 36.9452 -943.049 0.80447 0.334851 0.490615 -21.8188 36.6227 -955.638 0.663842 -0.0236664 0.747499 -14.3839 36.0925 -941.222 0.26413 0.495561 0.827439 -3.74763 13.4079 -942.762 0.0508864 -0.91495 0.400347 diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/GlSplat/cmake/FindGLEW.cmake cgal-4.5/demo/Surface_reconstruction_points_3/GlSplat/cmake/FindGLEW.cmake --- cgal-4.4/demo/Surface_reconstruction_points_3/GlSplat/cmake/FindGLEW.cmake 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/GlSplat/cmake/FindGLEW.cmake 1970-01-01 00:00:00.000000000 +0000 @@ -1,105 +0,0 @@ -# Copyright (c) 2009 Boudewijn Rempt -# -# Redistribution and use is allowed according to the terms of the BSD license. -# For details see the accompanying COPYING-CMAKE-SCRIPTS file. -# -# - try to find glew library and include files -# GLEW_INCLUDE_DIR, where to find GL/glew.h, etc. -# GLEW_LIBRARIES, the libraries to link against -# GLEW_FOUND, If false, do not try to use GLEW. -# Also defined, but not for general use are: -# GLEW_GLEW_LIBRARY = the full path to the glew library. - -IF (WIN32) - - IF(CYGWIN) - - FIND_PATH( GLEW_INCLUDE_DIR GL/glew.h) - - FIND_LIBRARY( GLEW_GLEW_LIBRARY glew32 - ${OPENGL_LIBRARY_DIR} - /usr/lib/w32api - /usr/X11R6/lib - ) - - - ELSE(CYGWIN) - - FIND_PATH( GLEW_INCLUDE_DIR GL/glew.h - $ENV{GLEW_ROOT_PATH}/include - ) - - FIND_LIBRARY( GLEW_GLEW_LIBRARY - NAMES glew glew32 - PATHS - $ENV{GLEW_ROOT_PATH}/lib - ${OPENGL_LIBRARY_DIR} - ) - - ENDIF(CYGWIN) - -ELSE (WIN32) - - IF (APPLE) -# These values for Apple could probably do with improvement. - FIND_PATH( GLEW_INCLUDE_DIR glew.h - /System/Library/Frameworks/GLEW.framework/Versions/A/Headers - ${OPENGL_LIBRARY_DIR} - ) - SET(GLEW_GLEW_LIBRARY "-framework GLEW" CACHE STRING "GLEW library for OSX") - SET(GLEW_cocoa_LIBRARY "-framework Cocoa" CACHE STRING "Cocoa framework for OSX") - ELSE (APPLE) - - FIND_PATH( GLEW_INCLUDE_DIR GL/glew.h - /usr/include/GL - /usr/openwin/share/include - /usr/openwin/include - /usr/X11R6/include - /usr/include/X11 - /opt/graphics/OpenGL/include - /opt/graphics/OpenGL/contrib/libglew - ) - - FIND_LIBRARY( GLEW_GLEW_LIBRARY GLEW - /usr/openwin/lib - /usr/X11R6/lib - ) - - ENDIF (APPLE) - -ENDIF (WIN32) - -SET( GLEW_FOUND "NO" ) -IF(GLEW_INCLUDE_DIR) - IF(GLEW_GLEW_LIBRARY) - # Is -lXi and -lXmu required on all platforms that have it? - # If not, we need some way to figure out what platform we are on. - SET( GLEW_LIBRARIES - ${GLEW_GLEW_LIBRARY} - ${GLEW_cocoa_LIBRARY} - ) - SET( GLEW_FOUND "YES" ) - -#The following deprecated settings are for backwards compatibility with CMake1.4 - SET (GLEW_LIBRARY ${GLEW_LIBRARIES}) - SET (GLEW_INCLUDE_PATH ${GLEW_INCLUDE_DIR}) - - ENDIF(GLEW_GLEW_LIBRARY) -ENDIF(GLEW_INCLUDE_DIR) - -IF(GLEW_FOUND) - IF(NOT GLEW_FIND_QUIETLY) - MESSAGE(STATUS "Found Glew: ${GLEW_LIBRARIES}") - ENDIF(NOT GLEW_FIND_QUIETLY) -ELSE(GLEW_FOUND) - IF(GLEW_FIND_REQUIRED) - MESSAGE(FATAL_ERROR "Could not find Glew") - ENDIF(GLEW_FIND_REQUIRED) -ENDIF(GLEW_FOUND) - -MARK_AS_ADVANCED( - GLEW_INCLUDE_DIR - GLEW_GLEW_LIBRARY - GLEW_Xmu_LIBRARY - GLEW_Xi_LIBRARY -) diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/GlSplat/cmake/FindQGLViewer.cmake cgal-4.5/demo/Surface_reconstruction_points_3/GlSplat/cmake/FindQGLViewer.cmake --- cgal-4.4/demo/Surface_reconstruction_points_3/GlSplat/cmake/FindQGLViewer.cmake 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/GlSplat/cmake/FindQGLViewer.cmake 1970-01-01 00:00:00.000000000 +0000 @@ -1,20 +0,0 @@ - -if (QGLViewer_INCLUDES AND QGLViewer_LIBRARIES) - set(QGLViewer_FIND_QUIETLY TRUE) -endif (QGLViewer_INCLUDES AND QGLViewer_LIBRARIES) - -find_path(QGLViewer_INCLUDES - NAMES - QGLViewer/qglviewer.h - PATHS - $ENV{QGLViewerDIR} - ${INCLUDE_INSTALL_DIR} -) - -find_library(QGLViewer_LIBRARIES QGLViewer PATHS $ENV{QGLVIEWER_DIR} ${LIB_INSTALL_DIR}) - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(QGLViewer DEFAULT_MSG - QGLViewer_INCLUDES QGLViewer_LIBRARIES) - -mark_as_advanced(QGLViewer_INCLUDES QGLViewer_LIBRARIES) diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/GlSplat/CMakeLists.txt cgal-4.5/demo/Surface_reconstruction_points_3/GlSplat/CMakeLists.txt --- cgal-4.4/demo/Surface_reconstruction_points_3/GlSplat/CMakeLists.txt 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/GlSplat/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,35 +0,0 @@ - -project(GlSplat) - -cmake_minimum_required(VERSION 2.6.0) -if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}" VERSION_GREATER 2.8.3) - cmake_policy(VERSION 2.8.4) -else() - cmake_policy(VERSION 2.6) -endif() -set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) - -find_package(Qt4 REQUIRED) -find_package(GLEW REQUIRED) - -set(QT_USE_QTOPENGL TRUE) -set(QT_USE_QTXML TRUE) -include(${QT_USE_FILE}) -include_directories( ${QT_QTOPENGL_INCLUDE_DIR} ${QT_QTXML_INCLUDE_DIR} ${GLEW_INCLUDE_DIR}) - -set(srcs Shader.cpp GlSplat.cpp) - -qt4_automoc( ${srcs}) -qt4_add_resources(srcs glsplat.qrc) - -add_library(GlSplat SHARED ${srcs}) -target_link_libraries(GlSplat ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTOPENGL_LIBRARY} ${GLEW_LIBRARIES}) - -find_package(QGLViewer) -if(QGLVIEWER_FOUND) - include_directories( ${QGLViewer_INCLUDES}) - add_executable(demo demo.cpp) - target_link_libraries(demo ${QT_QTXML_LIBRARY} ${QGLViewer_LIBRARIES} GlSplat) -else() - message("QGLViewer not found, demo won't be built") -endif() diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/GlSplat/demo.cpp cgal-4.5/demo/Surface_reconstruction_points_3/GlSplat/demo.cpp --- cgal-4.4/demo/Surface_reconstruction_points_3/GlSplat/demo.cpp 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/GlSplat/demo.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,131 +0,0 @@ -// This file is part of GlSplat, a simple splatting C++ library -// -// Copyright (C) 2008-2009 Gael Guennebaud -// -// GlSplat is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// GlSplat is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with GlSplat. If not, see . - -#include "GlSplat.h" -#include - -class Viewer : public QGLViewer -{ -protected : - virtual void draw(); - virtual void init(); - virtual QString helpString() const; - - virtual void drawpoints(); - GlSplat::SplatRenderer mRenderer; - std::vector mNormals; - std::vector mPositions; - std::vector mRadii; - std::vector mColors; - int mNbPoints; -}; - -void Viewer::draw() -{ - mRenderer.beginVisibilityPass(); - drawpoints(); - mRenderer.beginAttributePass(); - drawpoints(); - mRenderer.finalize(); -} - -void Viewer::drawpoints() -{ - glBegin(GL_POINTS); - for (int i=0; iS i m p l e V i e w e r"); - text += "Use the mouse to move the camera around the object. "; - text += "You can respectively revolve around, zoom and translate with the three mouse buttons. "; - text += "Left and middle buttons pressed together rotate around the camera view direction axis

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

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

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

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

"; - text += "Press Escape to exit the viewer."; - return text; -} - - -#include - -int main(int argc, char** argv) -{ - // Read command lines arguments. - QApplication application(argc,argv); - - // Instantiate the viewer. - Viewer viewer; - - viewer.setWindowTitle("simpleViewer"); - - // Make the viewer window visible on screen. - viewer.show(); - - // Run main loop. - return application.exec(); -} - diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/GlSplat/GlSplat_config.h cgal-4.5/demo/Surface_reconstruction_points_3/GlSplat/GlSplat_config.h --- cgal-4.4/demo/Surface_reconstruction_points_3/GlSplat/GlSplat_config.h 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/GlSplat/GlSplat_config.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,12 +0,0 @@ -#ifndef GLSPLAT_CONFIG_H -#define GLSPLAT_CONFIG_H - -#include - -#ifdef gl_splat_EXPORTS - #define GLSPLAT_EXPORT CGAL_DLL_EXPORT -#else - #define GLSPLAT_EXPORT CGAL_DLL_IMPORT -#endif - -#endif // GLSPLAT_CONFIG_H diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/GlSplat/GlSplat.cpp cgal-4.5/demo/Surface_reconstruction_points_3/GlSplat/GlSplat.cpp --- cgal-4.4/demo/Surface_reconstruction_points_3/GlSplat/GlSplat.cpp 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/GlSplat/GlSplat.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,514 +0,0 @@ -// This file is part of GlSplat, a simple splatting C++ library -// -// Copyright (C) 2008-2009 Gael Guennebaud -// -// GlSplat is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// GlSplat is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with GlSplat. If not, see . - -#include - -#include -#include -#include -#include - -#include "GlSplat.h" -#include "Shader.h" - -#include -#include -#include - - -namespace GlSplat { - -SplatRenderer::SplatRenderer() -{ - mNormalTextureID = 0; - mDepthTextureID = 0; - mIsSupported = false; - mRenderBuffer = 0; - mWorkaroundATI = false; - mBuggedAtiBlending = false; - mDummyTexId = 0; - mIsInitialized = false; - - mFlags = DEFERRED_SHADING_BIT | DEPTH_CORRECTION_BIT | FLOAT_BUFFER_BIT | OUTPUT_DEPTH_BIT; - mCachedFlags = ~mFlags; - // union of bits which controls the render buffer - mRenderBufferMask = DEFERRED_SHADING_BIT | FLOAT_BUFFER_BIT; -} - -QString SplatRenderer::loadSource(const QString& func,const QString& filename) -{ - QString res; - QFile f(":/SplatRenderer/shaders/" + filename); - if (!f.open(QFile::ReadOnly)) - { - std::cerr << "failed to load shader file " << filename.toAscii().data() << "\n"; - return res; - } - else qDebug("Succesfully loaded shader func '%s' in file '%s'",qPrintable(func),qPrintable(filename)); - QTextStream stream(&f); - res = stream.readAll(); - f.close(); - res = QString("#define __%1__ 1\n").arg(func) - + QString("#define %1 main\n").arg(func) - + res; - return res; -} - -void SplatRenderer::configureShaders() -{ - // const char* passNames[3] = {"Visibility","Attribute","Finalization"}; - QString defines = ""; - if (mFlags & DEFERRED_SHADING_BIT) - defines += "#define ES_DEFERRED_SHADING\n"; - if (mFlags & DEPTH_CORRECTION_BIT) - defines += "#define ES_DEPTH_CORRECTION\n"; - if (mFlags & OUTPUT_DEPTH_BIT) - defines += "#define ES_OUTPUT_DEPTH 1\n"; - if (mFlags & BACKFACE_SHADING_BIT) - defines += "#define ES_BACKFACE_SHADING\n"; - if (mWorkaroundATI) - defines += "#define ES_ATI_WORKAROUND\n"; - - QString shading = -"vec4 meshlabLighting(vec4 color, vec3 eyePos, vec3 normal)" -"{" -" normal = normalize(normal);" -" vec3 lightVec = normalize(gl_LightSource[0].position.xyz);" -" vec3 halfVec = normalize( lightVec - normalize(eyePos) );" -" float aux_dot = dot(normal,lightVec);" -" float diffuseCoeff = clamp(aux_dot, 0.0, 1.0);" -" float specularCoeff = aux_dot>0.0 ? clamp(pow(clamp(dot(halfVec, normal),0.0,1.0),gl_FrontMaterial.shininess), 0.0, 1.0) : 0.0;" -" return vec4(color.rgb * ( gl_FrontLightProduct[0].ambient.rgb + diffuseCoeff * gl_FrontLightProduct[0].diffuse.rgb) + specularCoeff * gl_FrontLightProduct[0].specular.rgb, 1.0);" -"}\n"; - - for (int k=0;k<3;++k) - { - QString vsrc = shading + defines + mShaderSrcs[k*2+0]; - QString fsrc = shading + defines + mShaderSrcs[k*2+1]; - if(!mShaders[k].loadSources(mShaderSrcs[k*2+0]!="" ? vsrc.toAscii().data() : 0, - mShaderSrcs[k*2+1]!="" ? fsrc.toAscii().data() : 0/*, - Shader::Warnings*/)) - mIsSupported = false; - } -} - -void SplatRenderer::init(QGLWidget *qglw) -{ - mIsSupported = true; - if(qglw) - qglw->makeCurrent(); - glewInit(); - - const char* rs = (const char*)glGetString(GL_RENDERER); - QString rendererString(""); - if(rs) - rendererString = QString(rs); - mWorkaroundATI = rendererString.startsWith("ATI") || rendererString.startsWith("AMD"); - // FIXME: maybe some recent HW correctly supports floating point blending... - mBuggedAtiBlending = rendererString.startsWith("ATI") || rendererString.startsWith("AMD"); - - if (mWorkaroundATI && mDummyTexId==0) - { - glActiveTexture(GL_TEXTURE0); - glGenTextures(1,&mDummyTexId); - glBindTexture(GL_TEXTURE_2D, mDummyTexId); - glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 4, 4, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0); - } - - // let's check the GPU capabilities - mSupportedMask = DEPTH_CORRECTION_BIT | BACKFACE_SHADING_BIT; - if (!QGLFramebufferObject::hasOpenGLFramebufferObjects ()) - { - std::cout << "SplatRenderer: error OpenGL frame buffer objects are not supported. (please, try to update your drivers)\n"; - mIsSupported = false; - return; - } - if (GLEW_ARB_texture_float) - mSupportedMask |= FLOAT_BUFFER_BIT; - else - std::cout << "SplatRenderer: warning floating point textures are not supported.\n"; - - if (GLEW_ARB_draw_buffers && (!mBuggedAtiBlending)) - mSupportedMask |= DEFERRED_SHADING_BIT; - else - std::cout << "SplatRenderer: warning deferred shading is not supported.\n"; - - if (GLEW_ARB_shadow) - mSupportedMask |= OUTPUT_DEPTH_BIT; - else - std::cerr << "SplatRenderer: warning copy of the depth buffer is not supported.\n"; - - mFlags = mFlags & mSupportedMask; - - // load shader source - mShaderSrcs[0] = loadSource("VisibilityVP","Raycasting.glsl"); - mShaderSrcs[1] = loadSource("VisibilityFP","Raycasting.glsl"); - mShaderSrcs[2] = loadSource("AttributeVP","Raycasting.glsl"); - mShaderSrcs[3] = loadSource("AttributeFP","Raycasting.glsl"); - mShaderSrcs[4] = ""; - mShaderSrcs[5] = loadSource("Finalization","Finalization.glsl"); - - mCurrentPass = 2; - mBindedPass = -1; - mIsInitialized = true; - GL_TEST_ERR -} - -void SplatRenderer::updateRenderBuffer() -{ - if ( (!mRenderBuffer) - || (mRenderBuffer->width()!=mCachedVP[2]) - || (mRenderBuffer->height()!=mCachedVP[3]) - || ( (mCachedFlags & mRenderBufferMask) != (mFlags & mRenderBufferMask) )) - { - delete mRenderBuffer; - GLenum fmt = (mFlags&FLOAT_BUFFER_BIT) ? GL_RGBA16F_ARB : GL_RGBA; - mRenderBuffer = new QGLFramebufferObject(mCachedVP[2], mCachedVP[3], - (mFlags&OUTPUT_DEPTH_BIT) ? QGLFramebufferObject::NoAttachment : QGLFramebufferObject::Depth, - GL_TEXTURE_RECTANGLE_ARB, fmt); - - if (!mRenderBuffer->isValid()) - { - std::cout << "SplatRenderer: invalid FBO\n"; - } - - GL_TEST_ERR - if (mFlags&DEFERRED_SHADING_BIT) - { - // in deferred shading mode we need an additional buffer to accumulate the normals - if (mNormalTextureID==0) - glGenTextures(1,&mNormalTextureID); - glBindTexture(GL_TEXTURE_RECTANGLE_ARB, mNormalTextureID); - glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, fmt, mCachedVP[2], mCachedVP[3], 0, GL_RGBA, GL_FLOAT, 0); - glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - mRenderBuffer->bind(); - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_RECTANGLE_ARB, mNormalTextureID, 0); - mRenderBuffer->release(); - GL_TEST_ERR - } - - if (mFlags&OUTPUT_DEPTH_BIT) - { - // to output the depth values to the final depth buffer we need to - // attach a depth buffer as a texture - if (mDepthTextureID==0) - glGenTextures(1,&mDepthTextureID); - glBindTexture(GL_TEXTURE_RECTANGLE_ARB, mDepthTextureID); - glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_DEPTH_COMPONENT24_ARB, mCachedVP[2], mCachedVP[3], 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0); - glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - mRenderBuffer->bind(); - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_RECTANGLE_ARB, mDepthTextureID, 0); - mRenderBuffer->release(); - GL_TEST_ERR - } - } -} - -bool SplatRenderer::beginVisibilityPass() -{ - if (!mIsInitialized) - { - init(); - } - if (!isSupported()) - { - std::cerr << "SplatRenderer error: not supported hardware\n"; - return false; - } - if (mCurrentPass!=2) - { - std::cerr << "SplatRenderer error: programming error when calling beginVisibilityPass\n"; - return false; - } - - glPushAttrib(GL_ALL_ATTRIB_BITS); - - mCurrentPass = 0; - - // grab projection info - glGetIntegerv(GL_VIEWPORT, mCachedVP); - glGetFloatv(GL_MODELVIEW_MATRIX, mCachedMV); - glGetFloatv(GL_PROJECTION_MATRIX, mCachedProj); - - updateRenderBuffer(); - if (mCachedFlags != mFlags) - configureShaders(); - - // configureShaders may detect that shaders are actually not supported. - if (!isSupported()) - { - std::cerr << "SplatRenderer error: not supported hardware\n"; - return false; - } - - mCachedFlags = mFlags; - - mParams.update(mCachedMV, mCachedProj, mCachedVP); - mParams.loadTo(mShaders[mCurrentPass]); - - mRenderBuffer->bind(); - if (mFlags & DEFERRED_SHADING_BIT) - { - GLenum buf[2] = {GL_COLOR_ATTACHMENT0_EXT,GL_COLOR_ATTACHMENT1_EXT}; - glDrawBuffersARB(2, buf); - } - glViewport(mCachedVP[0],mCachedVP[1],mCachedVP[2],mCachedVP[3]); - glClearColor(0,0,0,0); - glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); - enablePass(mCurrentPass); - GL_TEST_ERR; - return true; -} -bool SplatRenderer::beginAttributePass() -{ - if (!isSupported()) - { - std::cerr << "SplatRenderer error: not supported hardware\n"; - return false; - } - if (mCurrentPass!=0) - { - std::cerr << "SplatRenderer error: programming error when calling beginAttributePass (must be called after the visiblity pass)\n"; - return false; - } - - mCurrentPass = 1; - mParams.loadTo(mShaders[mCurrentPass]); - enablePass(mCurrentPass); - GL_TEST_ERR; - return true; -} -bool SplatRenderer::finalize() -{ - if (!isSupported()) - { - std::cerr << "SplatRenderer error: not supported hardware\n"; - return false; - } - - // this is the last pass: normalization by the sum of weights + deferred shading - mShaders[mCurrentPass].release(); - mRenderBuffer->release(); - - if ( (mCurrentPass!=0) && (mCurrentPass!=1)) - { - std::cerr << "SplatRenderer error: programming error when calling finalize (must be called after the visiblity or attribute pass)\n"; - return false; - } - - mCurrentPass = 2; - - if (mFlags&DEFERRED_SHADING_BIT) - glDrawBuffer(GL_BACK); - - enablePass(mCurrentPass);GL_TEST_ERR - - // switch to normalized 2D rendering mode - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - - - GL_TEST_ERR - mShaders[2].setUniform("viewport",float(mCachedVP[0]),float(mCachedVP[1]),float(mCachedVP[2]),float(mCachedVP[3]));GL_TEST_ERR - mShaders[2].setUniform("ColorWeight",0); GL_TEST_ERR // this is a texture unit - glActiveTexture(GL_TEXTURE0);GL_TEST_ERR - glBindTexture(GL_TEXTURE_RECTANGLE_ARB,mRenderBuffer->texture());GL_TEST_ERR - - if (mFlags&DEFERRED_SHADING_BIT) - { - mShaders[2].setUniform("unproj", mCachedProj[10], mCachedProj[14]);GL_TEST_ERR - mShaders[2].setUniform("NormalWeight",1);GL_TEST_ERR // this is a texture unit - glActiveTexture(GL_TEXTURE1);GL_TEST_ERR - glBindTexture(GL_TEXTURE_RECTANGLE_ARB,mNormalTextureID);GL_TEST_ERR - GL_TEST_ERR - } - - if (mFlags&OUTPUT_DEPTH_BIT) - { - mShaders[2].setUniform("Depth",2);GL_TEST_ERR // this is a texture unit - glActiveTexture(GL_TEXTURE2);GL_TEST_ERR - glBindTexture(GL_TEXTURE_RECTANGLE_ARB,mDepthTextureID);GL_TEST_ERR - GL_TEST_ERR - } - else - { - glDisable(GL_DEPTH_TEST); - glDepthMask(GL_FALSE); - } - - // draw a quad covering the whole screen - float viewVec[] = {1.f/mCachedProj[0], 1.f/mCachedProj[5], -1}; - - glBegin(GL_QUADS); - glColor3f(1, 0, 0); - glTexCoord3f(viewVec[0],viewVec[1],viewVec[2]); - glMultiTexCoord2f(GL_TEXTURE1,1.,1.); - glVertex3f(1,1,0); - - glColor3f(1, 1, 0); - glTexCoord3f(-viewVec[0],viewVec[1],viewVec[2]); - glMultiTexCoord2f(GL_TEXTURE1,0.,1.); - glVertex3f(-1,1,0); - - glColor3f(0, 1, 1); - glTexCoord3f(-viewVec[0],-viewVec[1],viewVec[2]); - glMultiTexCoord2f(GL_TEXTURE1,0.,0.); - glVertex3f(-1,-1,0); - - glColor3f(1, 0, 1); - glTexCoord3f(viewVec[0],-viewVec[1],viewVec[2]); - glMultiTexCoord2f(GL_TEXTURE1,1.,0.); - glVertex3f(1,-1,0); - glEnd(); - if (!(mFlags&OUTPUT_DEPTH_BIT)) - { - glEnable(GL_DEPTH_TEST); - glDepthMask(GL_TRUE); - } - - mShaders[mCurrentPass].release(); - - // restore matrices - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - - glPopAttrib(); - return true; -} - -void SplatRenderer::enablePass(int n) -{ - if (!isSupported()) - { - return; - } - if (mBindedPass!=n) - { - if (mBindedPass>=0) - mShaders[mBindedPass].release(); - mShaders[n].activate(); - mBindedPass = n; - - // set GL states - if (n==0) - { - glDisable(GL_LIGHTING); -// glDisable(GL_POINT_SMOOTH); - glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); - - glAlphaFunc(GL_LESS,1); - glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE); - glDepthMask(GL_TRUE); - glDisable(GL_BLEND); - glEnable(GL_ALPHA_TEST); - glEnable(GL_DEPTH_TEST); - -// glActiveTexture(GL_TEXTURE0); -// glTexEnvf(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE); -// glEnable(GL_POINT_SPRITE_ARB); - } - if (n==1) - { - glDisable(GL_LIGHTING); - glEnable(GL_POINT_SMOOTH); - glActiveTexture(GL_TEXTURE0); - glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); - - glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); - glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_ONE,GL_ONE); -// //glBlendFuncSeparate(GL_ONE, GL_ZERO, GL_ONE,GL_ZERO); -// glBlendFunc(GL_ONE,GL_ZERO); - glDepthMask(GL_FALSE); - glEnable(GL_BLEND); - glEnable(GL_DEPTH_TEST); - glDisable(GL_ALPHA_TEST); - -// glActiveTexture(GL_TEXTURE0); - - } - if ( (n==0) || (n==1) ) - { - // enable point sprite rendering mode - glActiveTexture(GL_TEXTURE0); - if (mWorkaroundATI) - { - glBindTexture(GL_TEXTURE_2D, mDummyTexId); - glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 2, 2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0); - glPointParameterf(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT); - // hm... ^^^^ - } - glTexEnvf(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE); - glEnable(GL_POINT_SPRITE_ARB); - } - if (n==2) - { - glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); - glDepthMask(GL_TRUE); - glDisable(GL_LIGHTING); - glDisable(GL_BLEND); - } - } -} - -void SplatRenderer::UniformParameters::update(float* mv, float* proj, GLint* vp) -{ - // extract the uniform scale - float scale = sqrtf(mv[0]*mv[0]+mv[1]*mv[1]+mv[2]*mv[2]); - - radiusScale = scale; - preComputeRadius = - (std::max)(proj[0]*vp[2], proj[5]*vp[3]); - depthOffset = 2.0; - oneOverEwaRadius = 0.70710678118654; - halfVp[0] = 0.5*vp[2]; - halfVp[1] = 0.5*vp[3]; - rayCastParameter1[0] = 2./(proj[0]*vp[2]); - rayCastParameter1[1] = 2./(proj[5]*vp[3]); - rayCastParameter1[2] = 0.0; - rayCastParameter2[0] = -1./proj[0]; - rayCastParameter2[1] = -1./proj[5]; - rayCastParameter2[2] = -1.0; - depthParameterCast[0] = 0.5*proj[14]; - depthParameterCast[1] = 0.5-0.5*proj[10]; -} - -void SplatRenderer::UniformParameters::loadTo(Shader& prg) -{ - prg.activate(); - prg.setUniform("expeRadiusScale", radiusScale); - prg.setUniform("expePreComputeRadius", preComputeRadius); - prg.setUniform("expeDepthOffset", depthOffset); - prg.setUniform("oneOverEwaRadius", oneOverEwaRadius); - prg.setUniform2("halfVp", halfVp); - prg.setUniform3("rayCastParameter1", rayCastParameter1); - prg.setUniform3("rayCastParameter2", rayCastParameter2); - prg.setUniform2("depthParameterCast", depthParameterCast); -} - -void SplatRenderer::setRadiusScale(float v) -{ - mParams.radiusScale = v; -} - -} // namepsace GlSplat - diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/GlSplat/GlSplat.h cgal-4.5/demo/Surface_reconstruction_points_3/GlSplat/GlSplat.h --- cgal-4.4/demo/Surface_reconstruction_points_3/GlSplat/GlSplat.h 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/GlSplat/GlSplat.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,144 +0,0 @@ -// This file is part of GlSplat, a simple splatting C++ library -// -// Copyright (C) 2008-2009 Gael Guennebaud -// -// GlSplat is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// GlSplat is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with GlSplat. If not, see . - -#ifndef _GLSPLAT_SPLATRENDERER_H_ -#define _GLSPLAT_SPLATRENDERER_H_ - -#include "GlSplat_config.h" -#include "Shader.h" -#include -#include -#include -#include - -class QGLFramebufferObject; -class QGLWidget; - -namespace GlSplat { - -/** \class SplatRenderer - * \brief Helper class to render a set of points using a splatting alogirthm - * - * This class aims to render a set of oriented point with radius (called splats) using an - * OpenGL based splating algorithm. This class is only responsible for the managing of the - * OpenGL stats and shaders related to the splatting. The drawing of the geometry, i.e., - * sending the point data to the GPU has to be done by the user. - * - * Here is an example: - * \code - * SplatRenderer renderer; - * renderer.init(); - * - * renderer.beginVisibilityPass(); - * drawpoints(); - * renderer.beginAttributePass(); - * drawpoints(); - * renderer.finalize(); - * \endcode - * - * Have a look at the demo to see a complete example based on QGLviewer. - */ -class GLSPLAT_EXPORT SplatRenderer -{ - bool mIsSupported; - enum { - DEFERRED_SHADING_BIT = 0x000001, - DEPTH_CORRECTION_BIT = 0x000002, - OUTPUT_DEPTH_BIT = 0x000004, - BACKFACE_SHADING_BIT = 0x000008, - FLOAT_BUFFER_BIT = 0x000010 - }; - int mFlags; - int mCachedFlags; - int mRenderBufferMask; - int mSupportedMask; - - int mCurrentPass; - int mBindedPass; - GLuint mDummyTexId; // on ATI graphics card we need to bind a texture to get point sprite working ! - bool mWorkaroundATI; - bool mBuggedAtiBlending; - bool mIsInitialized; - GLuint mNormalTextureID; - GLuint mDepthTextureID; - Shader mShaders[3]; - QString mShaderSrcs[6]; - QGLFramebufferObject* mRenderBuffer; - float mCachedMV[16]; // modelview matrix - float mCachedProj[16]; // projection matrix - GLint mCachedVP[4]; // viewport - - struct UniformParameters - { - float radiusScale; - float preComputeRadius; - float depthOffset; - float oneOverEwaRadius; - float halfVp[2]; - float rayCastParameter1[3]; - float rayCastParameter2[3]; - float depthParameterCast[2]; - - void loadTo(Shader& prg); - void update(float* mv, float* proj, GLint* vp); - }; - - UniformParameters mParams; - - QString loadSource(const QString& func,const QString& file); - void configureShaders(); - void updateRenderBuffer(); - void enablePass(int n); - -public: - - SplatRenderer(); - - /** Must be called once an OpenGL context has been activated. - * The main OpenGL context must be enabled, or, if you are using a QGLwiget, - * you can pass it to this function without caring about the OpenGL context. - */ - void init(QGLWidget *qglw = 0); - - /** \returns true is the hardware is supported - * Must be called after init. - */ - bool isSupported() { return mIsSupported; } - - /** Starts the first rendering pass - * \returns false if an error occured - */ - bool beginVisibilityPass(); - /** Starts the (optional) second rendering pass - * \returns false if an error occured - */ - bool beginAttributePass(); - /** Draw the rendered splats inside the main render target. - * \returns false if an error occured - */ - bool finalize(); - - /** Sets a global scale factor for the splat radii - * Default value is 1 - */ - void setRadiusScale(float v); - -}; - -} // namepsace GlSplat - -#endif // _GLSPLAT_SPLATRENDERER_H_ - diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/GlSplat/glsplat.qrc cgal-4.5/demo/Surface_reconstruction_points_3/GlSplat/glsplat.qrc --- cgal-4.4/demo/Surface_reconstruction_points_3/GlSplat/glsplat.qrc 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/GlSplat/glsplat.qrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ - - - shaders/Raycasting.glsl - shaders/Finalization.glsl - - diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/GlSplat/Shader.cpp cgal-4.5/demo/Surface_reconstruction_points_3/GlSplat/Shader.cpp --- cgal-4.4/demo/Surface_reconstruction_points_3/GlSplat/Shader.cpp 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/GlSplat/Shader.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,136 +0,0 @@ -// This file is part of GlSplat, a simple splatting C++ library -// -// Copyright (C) 2008-2009 Gael Guennebaud -// -// GlSplat is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// GlSplat is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with GlSplat. If not, see . - -#include "Shader.h" -#include - -#include -#include -#include - -namespace GlSplat { - -void Shader::define(const char* name, const char* value) -{ - mDefines[std::string(name)] = value; -} -//-------------------------------------------------------------------------------- -bool Shader::loadSources(const char* vsrc, const char* fsrc) -{ - bool allIsOk = false; - - mProgramID = glCreateProgram(); - - std::string defineStr = ""; - for(DefineMap::iterator it = mDefines.begin() ; it!=mDefines.end() ; ++it) - { - defineStr += "#define " + it->first + " " + it->second + "\n"; - } - - if(vsrc) - { - GLuint shaderID = glCreateShader(GL_VERTEX_SHADER); - - std::string source = defineStr + std::string(vsrc); - const GLchar * arbSource = source.c_str(); - - glShaderSource(shaderID, 1, (const GLchar **)&arbSource, 0); - glCompileShader(shaderID); - - int compiled; - glGetShaderiv(shaderID,GL_COMPILE_STATUS,&compiled); - allIsOk = allIsOk && compiled; - //printInfoLog(shaderID); - - glAttachShader(mProgramID, shaderID); - } - - if(fsrc) - { - GLuint shaderID = glCreateShader(GL_FRAGMENT_SHADER); - - std::string source = defineStr + std::string(fsrc); - const GLchar * arbSource = source.c_str(); - - glShaderSource(shaderID, 1, (const GLchar **)&arbSource, 0); - glCompileShader(shaderID); - - int compiled; - glGetShaderiv(shaderID,GL_COMPILE_STATUS,&compiled); - allIsOk = allIsOk && compiled; - //printInfoLog(shaderID); - - glAttachShader(mProgramID, shaderID); - } - - glLinkProgram(mProgramID); - - int isLinked; - glGetProgramiv(mProgramID, GL_LINK_STATUS, &isLinked); - allIsOk = allIsOk && isLinked; - mIsValid = isLinked == GL_TRUE; - printInfoLog(mProgramID); - - return allIsOk; -} -//-------------------------------------------------------------------------------- -void Shader::activate(void) const -{ - assert(mIsValid); - glUseProgram(mProgramID); -} -void Shader::release(void) const -{ - glUseProgram(0); -} -//-------------------------------------------------------------------------------- -int Shader::getUniformLocation(const char* name) const -{ - assert(mIsValid); - int loc = glGetUniformLocation(mProgramID, name); - return loc; -} -//-------------------------------------------------------------------------------- -void Shader::setSamplerUnit(const char* sampler, int unit) const -{ - activate(); - glUniform1i(getUniformLocation(sampler), unit); - release(); -} -//-------------------------------------------------------------------------------- -int Shader::getAttribLocation(const char* name) const -{ - assert(mIsValid); - int loc = glGetAttribLocation(mProgramID, name); - return loc; -} -//-------------------------------------------------------------------------------- -void Shader::printInfoLog(GLuint objectID) -{ - int infologLength, charsWritten; - GLchar *infoLog; - glGetProgramiv(objectID,GL_INFO_LOG_LENGTH, &infologLength); - if(infologLength > 0) - { - infoLog = new GLchar[infologLength]; - glGetProgramInfoLog(objectID, infologLength, &charsWritten, infoLog); - if (charsWritten>0) - std::cerr << "Shader info : \n" << infoLog << std::endl; - delete[] infoLog; - } -} - -} // namepsace GlSplat diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/GlSplat/Shader.h cgal-4.5/demo/Surface_reconstruction_points_3/GlSplat/Shader.h --- cgal-4.4/demo/Surface_reconstruction_points_3/GlSplat/Shader.h 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/GlSplat/Shader.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,148 +0,0 @@ -// This file is part of GlSplat, a simple splatting C++ library -// -// Copyright (C) 2008-2009 Gael Guennebaud -// -// GlSplat is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// GlSplat is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with GlSplat. If not, see . - -#ifndef _GLSPLAT_Shader_h_ -#define _GLSPLAT_Shader_h_ - -#include -#include - -#ifndef NDEBUG - #define GL_TEST_ERR\ - {\ - GLenum eCode;\ - if((eCode=glGetError())!=GL_NO_ERROR)\ - std::cerr << "OpenGL error : " << gluErrorString(eCode) << " in " << __FILE__ << " : " << __LINE__ << std::endl;\ - } -#else - #define GL_TEST_ERR -#endif - -#include -#include - -namespace GlSplat { - -/** Permet de manipuler des shaders en GLSL (OpenGL2.0) - Exemple d'utilisation: - \code - // shader creation: - Shader* myShader = new Shader(); - // loading from files (compilation + linking): - myShader->loadFromFiles("myShaderFile.vtx", "myShaderFile.frg"); - - // ... - - // at rending time: - myShader->enable(); - // draw objects - myShader->disable(); - \endcode -*/ - -class Shader -{ -public: - Shader(void) - : mIsValid(false) - { } - - /** add a \#define - */ - void define(const char* name, const char* value); - - /** Compiles and links the shader from 2 source files - \param fileV vertex shader ("" if no vertex shader) - \param fileF fragment shader ("" if no fragment shader) - \return true if no error occurs - */ -// bool loadFromFiles(const std::string& fileV, const std::string& fileF); - - bool loadSources(const char* vsrc, const char* fsrc); - - /** Enable the shader - */ - void activate() const; - - /** Releases the shader - */ - void release() const; - - /** \return the index of the uniform variable \a name - */ - int getUniformLocation(const char* name) const; - - /** Forces a sampler to a given unit - Example: - \code - glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE2D, myTextureID); - myShader->setSamplerUnit("mySampler", 2); - \endcode - */ - void setSamplerUnit(const char* samplerName, int textureUnit) const; - - /** \returns the index of the generic attribute \a name - Tp be used with glVertexAttrib*(...) ou glVertexAttribPointer(...) - Example: - \code - int tangentAttribID = myShader->getAttribLocation("tangent"); - Vector3 tangent(...); - glVertexAttrib3fv(tangentAttribID, tangent); - // ou - Vector3* tangents = new Vector3[...]; - glVertexAttribPointer(tangentAttribID, 3, GL_FLOAT, GL_FALSE, 0, tangents); - glEnableVertexAttribArray(tangentAttribID); - \endcode - */ - int getAttribLocation(const char* name) const; - - inline void setUniform(const char* name, float a) const - { glUniform1f(glGetUniformLocation(mProgramID, name), a); } - - inline void setUniform(const char* name, int a) const - { glUniform1i(glGetUniformLocation(mProgramID, name), a); } - - inline void setUniform2(const char* name, float* a) const - { glUniform2fv(glGetUniformLocation(mProgramID, name), 1, a); } - - inline void setUniform3(const char* name, float* a) const - { glUniform3fv(glGetUniformLocation(mProgramID, name), 1, a); } - - inline void setUniform4(const char* name, float* a) const - { glUniform4fv(glGetUniformLocation(mProgramID, name), 1, a); } - - inline void setUniform(const char* name, float a, float b) const - { glUniform2f(glGetUniformLocation(mProgramID, name), a, b); } - - inline void setUniform(const char* name, float a, float b, float c) const - { glUniform3f(glGetUniformLocation(mProgramID, name), a, b, c); } - - inline void setUniform(const char* name, float a, float b, float c, float d) const - { glUniform4f(glGetUniformLocation(mProgramID, name), a, b, c, d); } - -protected: - - bool mIsValid; - typedef std::map DefineMap; - DefineMap mDefines; - static void printInfoLog(GLuint objectID); - GLuint mProgramID; -}; - -} // namepsace GlSplat - -#endif diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/GlSplat/shaders/Finalization.glsl cgal-4.5/demo/Surface_reconstruction_points_3/GlSplat/shaders/Finalization.glsl --- cgal-4.4/demo/Surface_reconstruction_points_3/GlSplat/shaders/Finalization.glsl 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/GlSplat/shaders/Finalization.glsl 1970-01-01 00:00:00.000000000 +0000 @@ -1,106 +0,0 @@ -// This file is part of GlSplat, a simple splatting C++ library -// -// Copyright (C) 2008-2009 Gael Guennebaud -// -// GlSplat is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// GlSplat is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with GlSplat. If not, see . - -#extension GL_ARB_texture_rectangle : enable - -#ifndef ES_DEPTH_INTERPOLATION - #define ES_DEPTH_INTERPOLATION 0 -#endif - -#ifndef ES_OUTPUT_DEPTH - #define ES_OUTPUT_DEPTH 0 -#endif - -// avoid an annoying bug with the nvidia driver 87XX serie. -#define epsilon 0.000001 - -uniform vec4 viewport; - -#ifndef ES_DEFERRED_SHADING - -uniform sampler2DRect ColorWeight; -#if (ES_OUTPUT_DEPTH==1) -uniform sampler2DRect Depth; -#endif - -void Finalization(void) -{ - vec4 color = texture2DRect(ColorWeight, gl_FragCoord.st - viewport.xy + epsilon); - #if (ES_OUTPUT_DEPTH==1) - gl_FragDepth = texture2DRect(Depth, gl_FragCoord.st + epsilon).x; - #endif - if (color.w<0.001) - discard; - gl_FragColor = color/color.w; - gl_FragColor.a = 1.; -} - -#else - -uniform vec2 unproj; - -uniform sampler2DRect ColorWeight; -uniform sampler2DRect NormalWeight; - -#if ( (ES_DEPTH_INTERPOLATION==0) || (ES_OUTPUT_DEPTH==1)) -uniform sampler2DRect Depth; -#endif - -void Finalization(void) -{ - vec4 color = texture2DRect(ColorWeight, gl_FragCoord.st - viewport.xy + epsilon); - - if (color.w<0.001) - discard; - - - if(color.w>0.001) - color.xyz /= color.w; - - vec3 viewVec = normalize(gl_TexCoord[0].xyz); - vec4 normaldepth = texture2DRect(NormalWeight, gl_FragCoord.st + epsilon); - - normaldepth.xyz = normaldepth.xyz/normaldepth.w; - - #if (ES_OUTPUT_DEPTH==1) - gl_FragDepth = texture2DRect(Depth, gl_FragCoord.st + epsilon).x; - #endif - - #if ES_DEPTH_INTERPOLATION==2 - float depth = -normaldepth.z; - #elif ES_DEPTH_INTERPOLATION==1 - float depth = unproj.y/(2.0*normaldepth.z+unproj.x-1.0); - #else - float depth = texture2DRect(Depth, gl_FragCoord.st + epsilon).x; - depth = unproj.y/(2.0*depth+unproj.x-1.0); - #endif - - vec3 normal = normaldepth.xyz; - #if ES_DEPTH_INTERPOLATION!=0 - normal.z = sqrt(1. - dot(vec3(normal.xy,0),vec3(normal.xy,0))); - #endif - normal = normalize(normal); - vec3 eyePos = gl_TexCoord[0].xyz * depth; - - gl_FragColor = meshlabLighting(color, eyePos, normal); - gl_FragColor.a = 1.0; -} - -#endif - - - diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/GlSplat/shaders/Raycasting.glsl cgal-4.5/demo/Surface_reconstruction_points_3/GlSplat/shaders/Raycasting.glsl --- cgal-4.4/demo/Surface_reconstruction_points_3/GlSplat/shaders/Raycasting.glsl 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/GlSplat/shaders/Raycasting.glsl 1970-01-01 00:00:00.000000000 +0000 @@ -1,335 +0,0 @@ -// This file is part of GlSplat, a simple splatting C++ library -// -// Copyright (C) 2008-2009 Gael Guennebaud -// -// GlSplat is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// GlSplat is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with GlSplat. If not, see . - -#pragma optimize(on) - -#ifndef ES_EWA_HINT - #define ES_EWA_HINT 0 -#endif - -#ifndef ES_DEPTH_INTERPOLATION - #define ES_DEPTH_INTERPOLATION 0 -#endif - -//-------------------------------------------------------------------------------- -// shared variables -//-------------------------------------------------------------------------------- - -// custom vertex attributes -//attribute float radius; - -#ifdef CLIPPED_SPLAT -attribute vec3 secondNormal; -varying vec4 clipLine; -#endif - -// standard uniforms -uniform float expeRadiusScale; -uniform float expePreComputeRadius; -uniform float expeDepthOffset; - -// varying -varying vec4 covmat; -varying vec3 fragNormal; - -varying vec3 fragNoverCdotN; -varying vec3 fragCenter; -varying float scaleSquaredDistance; - -#ifdef ES_ATI_WORKAROUND -varying vec4 fragCenterAndRadius; -#endif - -#ifdef ES_DEPTH_CORRECTION -varying float depthOffset; -#endif - -uniform vec2 halfVp; -uniform float oneOverEwaRadius; - - -#ifdef ES_BACKFACE_SHADING - #undef ES_EARLY_BACK_FACE_CULLING - //#define ES_EWA_HINT 2 -#endif - -//-------------------------------------------------------------------------------- -// Visibility Splatting -// Vertex Shader -//-------------------------------------------------------------------------------- - -#ifdef __VisibilityVP__ -varying vec2 scaledFragCenter2d; -void VisibilityVP(void) -{ - vec3 normal = normalize(gl_NormalMatrix * gl_Normal); - // Point in eye space - vec4 ePos = gl_ModelViewMatrix * gl_Vertex; - - float dotpn = dot(normal.xyz,ePos.xyz); - - vec4 oPos; - - #ifdef ES_EARLY_BACK_FACE_CULLING - // back_face culling - oPos = vec4(0,0,1,0); - if(dotpn<0.) - { - #endif - - float radius = gl_MultiTexCoord2.x * expeRadiusScale; - - vec4 pointSize; - pointSize.x = radius * expePreComputeRadius / ePos.z; - gl_PointSize = max(1.0, pointSize.x); - - scaleSquaredDistance = 1.0 / (radius * radius); - //fragNormal = normal; - fragCenter = ePos.xyz; - fragNoverCdotN = normal/dot(ePos.xyz,normal); - - #ifndef ES_DEPTH_CORRECTION - ePos.xyz += normalize(ePos.xyz) * expeDepthOffset * radius; - #else - //ePos.xyz += normalize(ePos.xyz) * expeDepthOffset * radius; - depthOffset = expeDepthOffset * radius; - #endif - - oPos = gl_ProjectionMatrix * ePos; - - #if (ES_EWA_HINT>0) - scaledFragCenter2d = 0.5*((oPos.xy/oPos.w)+1.0)*halfVp*oneOverEwaRadius; - #endif - - #ifdef ES_ATI_WORKAROUND - fragCenterAndRadius.xyz = (oPos.xyz/oPos.w) + 1.0; - fragCenterAndRadius.xy = fragCenterAndRadius.xy*halfVp; - fragCenterAndRadius.z = fragCenterAndRadius.z*0.5; - fragCenterAndRadius.w = pointSize.x; - #endif - - #ifndef ES_EARLY_BACK_FACE_CULLING - oPos.w = oPos.w * (dotpn<0.0 ? 1.0 : 0.0); - #else - } - #endif - - gl_Position = oPos; -} - -#endif - -//-------------------------------------------------------------------------------- -// Visibility Splatting -// Fragment Shader -//-------------------------------------------------------------------------------- - -#ifdef __VisibilityFP__ -varying vec2 scaledFragCenter2d; -uniform vec3 rayCastParameter1; -uniform vec3 rayCastParameter2; -uniform vec2 depthParameterCast; - -void VisibilityFP(void) -{ - #ifdef ES_ATI_WORKAROUND - vec3 fragCoord; - fragCoord.xy = fragCenterAndRadius.xy + (gl_TexCoord[0].st-0.5) * fragCenterAndRadius.w; - fragCoord.z = fragCenterAndRadius.z; - #else - vec3 fragCoord = gl_FragCoord.xyz; - #endif - // compute q in object space - vec3 qOne = rayCastParameter1 * fragCoord + rayCastParameter2; - float oneOverDepth = dot(qOne,-fragNoverCdotN); - float depth = (1.0/oneOverDepth); - vec3 diff = fragCenter + qOne * depth; - float r2 = dot(diff,diff); - - #if (ES_EWA_HINT>0) - vec2 d2 = oneOverEwaRadius*gl_FragCoord.xy - scaledFragCenter2d; - float r2d = dot(d2,d2); - gl_FragColor = vec4(min(r2d,r2*scaleSquaredDistance)); - #else - gl_FragColor = vec4(r2*scaleSquaredDistance); - #endif - - #ifdef ES_DEPTH_CORRECTION - oneOverDepth = 1.0/(-depth+depthOffset); - gl_FragDepth = depthParameterCast.x * oneOverDepth + depthParameterCast.y; - #endif -} - -#endif - -#ifdef __AttributeVP__ - -varying vec2 scaledFragCenter2d; - -void AttributeVP(void) -{ - // transform normal - vec3 normal = normalize(gl_NormalMatrix * gl_Normal); - // Point in eye space - vec4 ePos = gl_ModelViewMatrix * gl_Vertex; - - float dotpn = dot(normal.xyz,ePos.xyz); - - vec4 oPos; - - #ifdef ES_EARLY_BACK_FACE_CULLING - // back_face culling - oPos = vec4(0,0,1,0); - if(dotpn<0.) - { - #endif - - #ifdef ES_BACKFACE_SHADING - if(dotpn>0.) - { - dotpn = -dotpn; - normal = -normal; - } - #endif - - float radius = gl_MultiTexCoord2.x * expeRadiusScale * 1.1; - - vec4 pointSize; - pointSize.x = radius * expePreComputeRadius / ePos.z; - - #if (ES_EWA_HINT>0) - gl_PointSize = max(2.0, pointSize.x); - #else - gl_PointSize = max(1.0, pointSize.x); - #endif - - scaleSquaredDistance = 1. / (radius * radius); - fragNormal = normal; - fragCenter = ePos.xyz; - fragNoverCdotN = normal/dot(ePos.xyz,normal); - - // Output color - #ifdef ES_DEFERRED_SHADING - fragNormal.xyz = normal.xyz; - gl_FrontColor = gl_Color; - #else - // Output color - #ifdef ES_LIGHTING - gl_FrontColor = expeLighting(gl_Color, ePos.xyz, normal.xyz, 1.); - #else - gl_FrontColor = meshlabLighting(gl_Color, ePos.xyz, normal.xyz); - #endif - #endif - - oPos = gl_ModelViewProjectionMatrix * gl_Vertex; - - #ifdef ES_ATI_WORKAROUND - fragCenterAndRadius.xyz = (oPos.xyz/oPos.w) + 1.0; - fragCenterAndRadius.xy = fragCenterAndRadius.xy*halfVp; - fragCenterAndRadius.z = fragCenterAndRadius.z*0.5; - fragCenterAndRadius.w = pointSize.x; - #endif - - #if (ES_EWA_HINT>0) - scaledFragCenter2d = ((oPos.xy/oPos.w)+1.0)*halfVp*oneOverEwaRadius; - #endif - - #ifndef ES_EARLY_BACK_FACE_CULLING - oPos.w = oPos.w * (dotpn<0. ? 1.0 : 0.0); - #else - } - #endif - - gl_Position = oPos; -} - -#endif - -//-------------------------------------------------------------------------------- -// EWA Splatting -// Fragment Shader -//-------------------------------------------------------------------------------- - -#ifdef __AttributeFP__ -// this sampler is only used by this fragment shader - -varying vec2 scaledFragCenter2d; -uniform vec3 rayCastParameter1; -uniform vec3 rayCastParameter2; -uniform vec2 depthParameterCast; - -// uniform sampler1D Kernel1dMap; - -void AttributeFP(void) -{ - #ifdef ES_ATI_WORKAROUND - vec3 fragCoord; - fragCoord.xy = fragCenterAndRadius.xy + (gl_TexCoord[0].st-0.5) * fragCenterAndRadius.w; - fragCoord.z = fragCenterAndRadius.z; - #else - vec3 fragCoord = gl_FragCoord.xyz; - #endif - -#if 1 - vec3 qOne = rayCastParameter1 * fragCoord + rayCastParameter2; - float oneOverDepth = dot(qOne,fragNoverCdotN); - float depth = (1.0/oneOverDepth); - vec3 diff = fragCenter - qOne * depth; - float r2 = dot(diff,diff); - - #if (ES_EWA_HINT>0) - vec2 d2 = oneOverEwaRadius*gl_FragCoord.xy - scaledFragCenter2d; - float r2d = dot(d2,d2); -// float weight = texture1D(Kernel1dMap, min(r2d,r2*scaleSquaredDistance)).a; - float weight = min(r2d,r2*scaleSquaredDistance); - weight = clamp(1.-weight,0,1); - weight = weight*weight; - #else - //float weight = texture1D(Kernel1dMap, r2*scaleSquaredDistance).a; - float weight = clamp(1.-r2*scaleSquaredDistance,0.0,1.0); - weight = weight*weight; - #endif - weight *= 0.1; // limits overflow - - #ifdef ES_DEPTH_CORRECTION - gl_FragDepth = depthParameterCast.x * oneOverDepth + depthParameterCast.y; - #endif - - #ifdef ES_DEFERRED_SHADING - gl_FragData[0].rgb = gl_Color.rgb; - gl_FragData[1].xyz = fragNormal.xyz; - gl_FragData[1].w = weight; - gl_FragData[0].w = weight; - - #if ES_DEPTH_INTERPOLATION==2 // linear space - gl_FragData[1].z = -depth; - #elif ES_DEPTH_INTERPOLATION==1 // window space - #ifdef ES_DEPTH_CORRECTION - gl_FragData[1].z = gl_FragDepth; - #else - gl_FragData[1].z = fragCoord.z; - #endif - #endif - - #else - gl_FragColor.rgb = gl_Color.rgb; - gl_FragColor.w = weight; - #endif -#endif -} - -#endif diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/include/CGAL/compute_normal.h cgal-4.5/demo/Surface_reconstruction_points_3/include/CGAL/compute_normal.h --- cgal-4.4/demo/Surface_reconstruction_points_3/include/CGAL/compute_normal.h 2013-02-23 20:00:18.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/include/CGAL/compute_normal.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +0,0 @@ -#ifndef _COMPUTE_NORMAL_ -#define _COMPUTE_NORMAL_ - -template -typename Kernel::Vector_3 compute_facet_normal(const Facet& f) -{ - typedef typename Kernel::Point_3 Point; - typedef typename Kernel::Vector_3 Vector; - typedef typename Facet::Halfedge_around_facet_const_circulator HF_circulator; - Vector normal = CGAL::NULL_VECTOR; - HF_circulator he = f.facet_begin(); - HF_circulator end = he; - CGAL_For_all(he,end) - { - const Point& prev = he->prev()->vertex()->point(); - const Point& curr = he->vertex()->point(); - const Point& next = he->next()->vertex()->point(); - Vector n = CGAL::cross_product(next-curr,prev-curr); - normal = normal + (n / std::sqrt(n*n)); - } - return normal / std::sqrt(normal * normal); -} - -template -typename Kernel::Vector_3 compute_vertex_normal(const Vertex& v) -{ - typedef typename Kernel::Vector_3 Vector; - typedef typename Vertex::Halfedge_around_vertex_const_circulator HV_circulator; - typedef typename Vertex::Facet Facet; - Vector normal = CGAL::NULL_VECTOR; - HV_circulator he = v.vertex_begin(); - HV_circulator end = he; - CGAL_For_all(he,end) - { - if(!he->is_border()) - { - Vector n = compute_facet_normal(*he->facet()); - normal = normal + (n / std::sqrt(n*n)); - } - } - return normal / std::sqrt(normal * normal); -} - -#endif // _COMPUTE_NORMAL_ diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/include/CGAL/gl_render.h cgal-4.5/demo/Surface_reconstruction_points_3/include/CGAL/gl_render.h --- cgal-4.4/demo/Surface_reconstruction_points_3/include/CGAL/gl_render.h 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/include/CGAL/gl_render.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,80 +0,0 @@ -#ifndef _GL_RENDER_ -#define _GL_RENDER_ - -#include -#include "CGAL/compute_normal.h" - -template -void gl_render_facets(Polyhedron& polyhedron) -{ - typedef typename Polyhedron::Traits Kernel; - typedef typename Kernel::Point_3 Point; - typedef typename Kernel::Vector_3 Vector; - typedef typename Polyhedron::Facet Facet; - typedef typename Polyhedron::Facet_iterator Facet_iterator; - typedef typename Polyhedron::Halfedge_around_facet_circulator HF_circulator; - - // Gets current shading model - GLint shading; - ::glGetIntegerv(GL_SHADE_MODEL, &shading); - - Facet_iterator f; - for(f = polyhedron.facets_begin(); - f != polyhedron.facets_end(); - f++) - { - ::glBegin(GL_POLYGON); - - // If Flat shading: 1 normal per polygon - if (shading == GL_FLAT) - { - Vector n = compute_facet_normal(*f); - ::glNormal3d(n.x(),n.y(),n.z()); - } - - // revolve around current face to get vertices - HF_circulator he = f->facet_begin(); - HF_circulator end = he; - CGAL_For_all(he,end) - { - // If Gouraud shading: 1 normal per vertex - if (shading == GL_SMOOTH) - { - Vector n = compute_vertex_normal(*he->vertex()); - ::glNormal3d(n.x(),n.y(),n.z()); - } - - const Point& p = he->vertex()->point(); - ::glVertex3d(p.x(),p.y(),p.z()); - } - ::glEnd(); - } -} // end gl_render_facets - -template -void gl_render_edges(Polyhedron& polyhedron) -{ - typedef typename Polyhedron::Traits Kernel; - typedef typename Kernel::Point_3 Point; - typedef typename Polyhedron::Edge_iterator Edge_iterator; - - ::glBegin(GL_LINES); - Edge_iterator he; - for(he = polyhedron.edges_begin(); - he != polyhedron.edges_end(); - he++) - { - const Point& a = he->vertex()->point(); - const Point& b = he->opposite()->vertex()->point(); - ::glVertex3d(a.x(),a.y(),a.z()); - ::glVertex3d(b.x(),b.y(),b.z()); - } - ::glEnd(); -} // end gl_render_edges - - -#endif // _GL_RENDER_ - - - - diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/include/CGAL/Make_bar.h cgal-4.5/demo/Surface_reconstruction_points_3/include/CGAL/Make_bar.h --- cgal-4.4/demo/Surface_reconstruction_points_3/include/CGAL/Make_bar.h 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/include/CGAL/Make_bar.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,96 +0,0 @@ -#ifndef _MAKE_BAR_ -#define _MAKE_BAR_ - -#include - -template -class CModifierBar : public CGAL::Modifier_base -{ -private: - typedef typename Kernel::Point_3 Point; - typedef typename CGAL::Polyhedron_incremental_builder_3 builder; - Point m_points[8]; - -public: - - // life cycle - CModifierBar(Point points[8]) - { - for(int i=0;i<8;i++) - m_points[i] = points[i]; - } - ~CModifierBar() {} - - void operator()( HDS& hds) - { - builder B(hds,true); - B.begin_surface(3,1,6); - - for(int i=0;i<8;i++) - B.add_vertex(m_points[i]); - - B.begin_facet(); - B.add_vertex_to_facet(0); - B.add_vertex_to_facet(1); - B.add_vertex_to_facet(2); - B.add_vertex_to_facet(3); - B.end_facet(); - - B.begin_facet(); - B.add_vertex_to_facet(0); - B.add_vertex_to_facet(4); - B.add_vertex_to_facet(5); - B.add_vertex_to_facet(1); - B.end_facet(); - - B.begin_facet(); - B.add_vertex_to_facet(1); - B.add_vertex_to_facet(5); - B.add_vertex_to_facet(6); - B.add_vertex_to_facet(2); - B.end_facet(); - - B.begin_facet(); - B.add_vertex_to_facet(2); - B.add_vertex_to_facet(6); - B.add_vertex_to_facet(7); - B.add_vertex_to_facet(3); - B.end_facet(); - - B.begin_facet(); - B.add_vertex_to_facet(3); - B.add_vertex_to_facet(7); - B.add_vertex_to_facet(4); - B.add_vertex_to_facet(0); - B.end_facet(); - - B.begin_facet(); - B.add_vertex_to_facet(4); - B.add_vertex_to_facet(7); - B.add_vertex_to_facet(6); - B.add_vertex_to_facet(5); - B.end_facet(); - - B.end_surface(); - } -}; - -template -class Make_bar -{ -public: - typedef typename Polyhedron::HalfedgeDS HalfedgeDS; - typedef typename Kernel::Point_3 Point; - Make_bar() {} - ~Make_bar() {} - -public: - void run(Point points[8], - Polyhedron &output) - { - CModifierBar bar(points); - output.delegate(bar); - } -}; - -#endif // _MAKE_BAR_ diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/include/Point_set_3.h cgal-4.5/demo/Surface_reconstruction_points_3/include/Point_set_3.h --- cgal-4.4/demo/Surface_reconstruction_points_3/include/Point_set_3.h 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/include/Point_set_3.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,377 +0,0 @@ -// Author: Laurent Saboret, Nader Salman, Gael Guennebaud - -#ifndef POINT_SET_3_H -#define POINT_SET_3_H - -#include -#include -#include - -#include - -#include -#include - -#ifdef CGAL_GLEW_ENABLED -# include -#else -# include -#endif - - -/// The Point_set_3 class is array of points + normals of type -/// Point_with_normal_3 (in fact -/// UI_point_3 to support a selection flag and an optional radius). -/// It provides: -/// - accessors: points and normals iterators, property maps -/// - OpenGL rendering -/// - bounding box -/// -/// CAUTION: -/// - User is responsible to call invalidate_bounds() after adding, moving or removing points. -/// -/// @heading Parameters: -/// @param Gt Geometric traits class. - -template -class Point_set_3 : public std::deque > -{ -// Private types -private: - - // Base class - typedef std::deque > Base; - -// Public types -public: - - // Repeat base class' types - /// @cond SKIP_IN_MANUAL - typedef typename Base::iterator iterator; - typedef typename Base::const_iterator const_iterator; - - using Base::erase; - - /// @endcond - - // Classic CGAL geometric types - typedef Gt Geom_traits; ///< Geometric traits class. - typedef typename Geom_traits::FT FT; - typedef typename Geom_traits::Point_3 Point; ///< typedef to Geom_traits::Point_3 - typedef typename Geom_traits::Vector_3 Vector; ///< typedef to Geom_traits::Vector_3 - typedef typename Geom_traits::Iso_cuboid_3 Iso_cuboid; - typedef typename Geom_traits::Sphere_3 Sphere; - - /// Type of points in Point_set_3 - typedef UI_point_3 UI_point; ///< Position + normal + selection flag - // Its superclass: - typedef typename UI_point::Point_with_normal Point_with_normal; ///< Position + normal - - // Iterator over Point_3 points - typedef typename std::deque::iterator Point_iterator; - typedef typename std::deque::const_iterator Point_const_iterator; - -// Data members -private: - - // Indicate if m_barycenter, m_bounding_box, m_bounding_sphere and - // m_diameter_standard_deviation below are valid. - mutable bool m_bounding_box_is_valid; - - mutable Iso_cuboid m_bounding_box; // point set's bounding box - mutable Sphere m_bounding_sphere; // point set's bounding sphere - mutable Point m_barycenter; // point set's barycenter - mutable FT m_diameter_standard_deviation; // point set's standard deviation - - unsigned int m_nb_selected_points; // number of selected points - - bool m_radii_are_uptodate; - -// Public methods -public: - - /// Default constructor. - Point_set_3() - { - m_nb_selected_points = 0; - m_bounding_box_is_valid = false; - m_radii_are_uptodate = false; - } - - // Default copy constructor and operator =() are fine. - - // Repeat base class' public methods used below - /// @cond SKIP_IN_MANUAL - using Base::begin; - using Base::end; - using Base::size; - /// @endcond - - /// Gets the number of selected points. - unsigned int nb_selected_points() const { return m_nb_selected_points; } - - /// Mark a point as selected/not selected. - void select(UI_point* point, bool is_selected = true) - { - if (point->is_selected() != is_selected) - { - point->select(is_selected); - m_nb_selected_points += (is_selected ? 1 : -1); - } - } - - /// Mark a range of points as selected/not selected. - /// - /// @param first Iterator over first point to select/unselect. - /// @param beyond Past-the-end iterator. - void select(iterator first, iterator beyond, - bool is_selected = true) - { - for (iterator it = first; it != beyond; it++) - it->select(is_selected); - - m_nb_selected_points = std::count_if(begin(), end(), - std::mem_fun_ref(&UI_point::is_selected)); - } - - /// Deletes selected points. - void delete_selection() - { - // Deletes selected points using erase-remove idiom - erase(std::remove_if(begin(), end(), std::mem_fun_ref(&UI_point::is_selected)), - end()); - - // after erase(), use Scott Meyer's "swap trick" to trim excess capacity - Point_set_3(*this).swap(*this); - - m_nb_selected_points = 0; - invalidate_bounds(); - } - - /// Gets the bounding box. - Iso_cuboid bounding_box() const - { - if (!m_bounding_box_is_valid) - update_bounds(); - - return m_bounding_box; - } - - /// Gets bounding sphere. - Sphere bounding_sphere() const - { - if (!m_bounding_box_is_valid) - update_bounds(); - - return m_bounding_sphere; - } - - /// Gets points barycenter. - Point barycenter() const - { - if (!m_bounding_box_is_valid) - update_bounds(); - - return m_barycenter; - } - - /// Gets the standard deviation of the distance to barycenter. - FT diameter_standard_deviation() const - { - if (!m_bounding_box_is_valid) - update_bounds(); - - return m_diameter_standard_deviation; - } - - // Gets the region of interest, ignoring the outliers. - // This method is used to define the OpenGL arcball sphere. - Sphere region_of_interest() const - { - if (!m_bounding_box_is_valid) - update_bounds(); - - // A good candidate is a sphere containing the dense region of the point cloud: - // - center point is barycenter - // - Radius is 2 * standard deviation - float radius = 2.f * (float)m_diameter_standard_deviation; - return Sphere(m_barycenter, radius*radius); - } - - /// Update barycenter, bounding box, bounding sphere and standard deviation. - /// User is responsible to call invalidate_bounds() after adding, moving or removing points. - void invalidate_bounds() - { - m_bounding_box_is_valid = false; - } - - // Draw points using OpenGL calls. - // Preconditions: OpenGL point size and color must be set. - void gl_draw_vertices() const - { - // Draw *non-selected* points - if (m_nb_selected_points < size()) - { - ::glBegin(GL_POINTS); - for (const_iterator it = begin(); it != end(); it++) - { - const UI_point& p = *it; - if ( ! p.is_selected() ) - ::glVertex3dv(&p.x()); - } - ::glEnd(); - } - - // Draw *selected* points - if (m_nb_selected_points > 0) - { - ::glPointSize(4.f); // selected => bigger - ::glColor3ub(255,0,0); // selected => red - ::glBegin(GL_POINTS); - for (const_iterator it = begin(); it != end(); it++) - { - const UI_point& p = *it; - if (p.is_selected()) - ::glVertex3dv(&p.x()); - } - ::glEnd(); - } - } - - // Draw normals using OpenGL calls. - // Preconditions: OpenGL line width and color must be set. - void gl_draw_normals(float scale = 1.0) const // scale applied to normal length - { - // Draw normals of *non-selected* points - if (m_nb_selected_points < size()) - { - // Draw normals - ::glBegin(GL_LINES); - for (const_iterator it = begin(); it != end(); it++) - { - const UI_point& p = *it; - const Vector& n = p.normal(); - if (!p.is_selected()) - { - Point q = p + scale * n; - ::glVertex3d(p.x(),p.y(),p.z()); - ::glVertex3d(q.x(),q.y(),q.z()); - } - } - ::glEnd(); - } - - // Draw normals of *selected* points - if (m_nb_selected_points > 0) - { - ::glColor3ub(255,0,0); // selected => red - ::glBegin(GL_LINES); - for (const_iterator it = begin(); it != end(); it++) - { - const UI_point& p = *it; - const Vector& n = p.normal(); - if (p.is_selected()) - { - Point q = p + scale * n; - ::glVertex3d(p.x(),p.y(),p.z()); - ::glVertex3d(q.x(),q.y(),q.z()); - } - } - ::glEnd(); - } - } - - // Draw oriented points with radius using OpenGL calls. - // Preconditions: must be used inbetween calls to GlSplat library - void gl_draw_splats() const - { - // TODO add support for selection - ::glBegin(GL_POINTS); - for (const_iterator it = begin(); it != end(); it++) - { - const UI_point& p = *it; - ::glNormal3dv(&p.normal().x()); -#ifdef CGAL_GLEW_ENABLED - ::glMultiTexCoord1d(GL_TEXTURE2, p.radius()); -#endif - ::glVertex3dv(&p.x()); - } - ::glEnd(); - } - - - bool are_radii_uptodate() const { return m_radii_are_uptodate; } - void set_radii_uptodate(bool /*on*/) { m_radii_are_uptodate = false; } - -// Private methods: -private: - - /// Recompute barycenter, bounding box, bounding sphere and standard deviation. - void update_bounds() const - { - if (begin() == end()) - return; - - // Update bounding box and barycenter. - // TODO: we should use the functions in PCA component instead. - FT xmin,xmax,ymin,ymax,zmin,zmax; - xmin = ymin = zmin = 1e38; - xmax = ymax = zmax = -1e38; - Vector v = CGAL::NULL_VECTOR; - FT norm = 0; - for (Point_const_iterator it = begin(); it != end(); it++) - { - const Point& p = *it; - - // update bbox - xmin = (std::min)(p.x(),xmin); - ymin = (std::min)(p.y(),ymin); - zmin = (std::min)(p.z(),zmin); - xmax = (std::max)(p.x(),xmax); - ymax = (std::max)(p.y(),ymax); - zmax = (std::max)(p.z(),zmax); - - // update barycenter - v = v + (p - CGAL::ORIGIN); - norm += 1; - } - // - Point p(xmin,ymin,zmin); - Point q(xmax,ymax,zmax); - m_bounding_box = Iso_cuboid(p,q); - // - m_barycenter = CGAL::ORIGIN + v / norm; - - // Computes bounding sphere - typedef CGAL::Min_sphere_of_spheres_d_traits_3 Traits; - typedef CGAL::Min_sphere_of_spheres_d Min_sphere; - typedef typename Traits::Sphere Traits_sphere; - // - // Represents points by a set of spheres with 0 radius - std::vector spheres; - for (Point_const_iterator it = begin(); it != end(); it++) - spheres.push_back(Traits_sphere(*it,0)); - // - // Computes min sphere - Min_sphere ms(spheres.begin(),spheres.end()); - typename Min_sphere::Cartesian_const_iterator coord = ms.center_cartesian_begin(); - FT cx = *coord++; - FT cy = *coord++; - FT cz = *coord++; - m_bounding_sphere = Sphere(Point(cx,cy,cz), ms.radius()*ms.radius()); - - // Computes standard deviation of the distance to barycenter - typename Geom_traits::Compute_squared_distance_3 sqd; - FT sq_radius = 0; - for (Point_const_iterator it = begin(); it != end(); it++) - sq_radius += sqd(*it, m_barycenter); - sq_radius /= size(); - m_diameter_standard_deviation = CGAL::sqrt(sq_radius); - - m_bounding_box_is_valid = true; - } - -}; // end of class Point_set_3 - - -#endif // POINT_SET_3_H diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/include/UI_point_3.h cgal-4.5/demo/Surface_reconstruction_points_3/include/UI_point_3.h --- cgal-4.4/demo/Surface_reconstruction_points_3/include/UI_point_3.h 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/include/UI_point_3.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,132 +0,0 @@ -// Author: Laurent Saboret - -#ifndef UI_POINT_3_H -#define UI_POINT_3_H - -#include -#include - -#include -#include - - -/// The UI_point_3 class represents a 3D point in Surface_reconstruction_points_3 demo. -/// It contains: -/// - a position, -/// - a normal, -/// - a radius, -/// - a selection flag. -/// -/// @heading Parameters: -/// @param Gt Geometric traits class. - -template -class UI_point_3 - : public CGAL::Point_with_normal_3 -{ -// Private types -private: - - // Base class - typedef CGAL::Point_with_normal_3 Base; - -// Public types -public: - - /// Base class - typedef Base Point_with_normal; - - // Repeat base class public types - typedef Gt Geom_traits; ///< Geometric traits class. - typedef typename Geom_traits::FT FT; - typedef typename Geom_traits::RT RT; - typedef typename Geom_traits::Point_2 Point_2; ///< typedef to Geom_traits::Point_2 - typedef typename Geom_traits::Point_3 Point_3; ///< typedef to Geom_traits::Point_3 - typedef typename Geom_traits::Vector_3 Vector_3; ///< typedef to Geom_traits::Vector_3 - -// Public methods -public: - - /// Point is (0,0,0) by default. - /// Normal is (0,0,0) by default. - UI_point_3(const CGAL::Origin& o = CGAL::ORIGIN) - : Base(o) - { - m_is_selected = false; - m_radius = FT(0); - } - UI_point_3(FT x, FT y, FT z, - const Vector_3& normal = CGAL::NULL_VECTOR) - : Base(x,y,z,normal) - { - m_is_selected = false; - m_radius = FT(0); - } - UI_point_3(RT hx, RT hy, RT hz, RT hw, - const Vector_3& normal = CGAL::NULL_VECTOR) - : Base(hx,hy,hz,hw,normal) - { - m_is_selected = false; - m_radius = FT(0); - } - UI_point_3(const Point_3& point, - const Vector_3& normal = CGAL::NULL_VECTOR) - : Base(point, normal) - { - m_is_selected = false; - m_radius = FT(0); - } - template - UI_point_3(const CGAL::Point_with_normal_3& pwn) - : Base(pwn) - { - m_is_selected = false; - m_radius = FT(0); - } - - /// Copy constructor - UI_point_3(const UI_point_3& upt) - : Base(upt) - { - m_is_selected = upt.m_is_selected; - m_radius = upt.m_radius; - } - template - UI_point_3(const UI_point_3& upt) - : Base(upt) - { - m_is_selected = upt.is_selected(); - m_radius = upt.radius(); - } - /// Operator =() - UI_point_3& operator=(const UI_point_3& upt) - { - Base::operator=(upt); - m_is_selected = upt.m_is_selected; - m_radius = upt.m_radius; - return *this; - } - - // Inherited operators ==() and !=() are fine. - - /// Selection flag. - bool is_selected() const { return m_is_selected; } - void select(bool is_selected=true) { m_is_selected = is_selected; } - - /// Gets/sets radius. - FT radius() const { return m_radius; } - FT& radius() { return m_radius; } - -// Data -private: - - // Selection flag. - bool m_is_selected; - - /// radius. - FT m_radius; -}; - - -#endif //UI_POINT_3_H - diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/Kernel_type.h cgal-4.5/demo/Surface_reconstruction_points_3/Kernel_type.h --- cgal-4.4/demo/Surface_reconstruction_points_3/Kernel_type.h 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/Kernel_type.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,20 +0,0 @@ -#ifndef KERNEL_TYPE_H -#define KERNEL_TYPE_H - -#include - -// (Main) CGAL kernel used by this demo -typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; - -// simple geometric types -typedef Kernel::FT FT; -typedef Kernel::Line_3 Line; -typedef Kernel::Point_3 Point; -typedef Kernel::Plane_3 Plane; -typedef Kernel::Sphere_3 Sphere; -typedef Kernel::Vector_3 Vector; -typedef Kernel::Triangle_3 Triangle; -typedef Kernel::Iso_cuboid_3 Iso_cuboid; -typedef Kernel::Plane_3 Plane_3; - -#endif // KERNEL_TYPE_H diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/MainWindow.cpp cgal-4.5/demo/Surface_reconstruction_points_3/MainWindow.cpp --- cgal-4.4/demo/Surface_reconstruction_points_3/MainWindow.cpp 2014-03-05 20:00:23.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/MainWindow.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,520 +0,0 @@ -#include "config.h" -#include "MainWindow.h" -#include "Scene.h" -#include "Scene_item.h" -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "Polyhedron_demo_plugin_interface.h" -#include "Polyhedron_demo_io_plugin_interface.h" - -#include "ui_MainWindow.h" - -MainWindow::~MainWindow() -{ - delete ui; -} - -MainWindow::MainWindow(QWidget* parent) - : CGAL::Qt::DemosMainWindow(parent) -{ - ui = new Ui::MainWindow; - ui->setupUi(this); - - // Saves some pointers from ui, for latter use. - treeView = ui->treeView; - viewer = ui->viewer; - - // Setup the submenu of the View menu that can toggle the dockwidgets - Q_FOREACH(QDockWidget* widget, findChildren()) { - ui->menuDockWindows->addAction(widget->toggleViewAction()); - } - ui->menuDockWindows->removeAction(ui->dummyAction); - - // do not save the state of the viewer (anoying) - viewer->setStateFileName(QString::null); - - // accept drop events - setAcceptDrops(true); - - // setup scene - scene = new Scene(this); - viewer->setScene(scene); - treeView->setModel(scene); - - // setup the treeview: delegation and columns sizing... - treeView->setItemDelegate(new SceneDelegate(this)); - - treeView->header()->setStretchLastSection(false); - treeView->header()->setResizeMode(Scene::NameColumn, QHeaderView::Stretch); - treeView->header()->setResizeMode(Scene::NameColumn, QHeaderView::Stretch); - treeView->header()->setResizeMode(Scene::ColorColumn, QHeaderView::ResizeToContents); - treeView->header()->setResizeMode(Scene::RenderingModeColumn, QHeaderView::Fixed); - treeView->header()->setResizeMode(Scene::VisibleColumn, QHeaderView::Fixed); - - treeView->resizeColumnToContents(Scene::ColorColumn); - treeView->resizeColumnToContents(Scene::RenderingModeColumn); - treeView->resizeColumnToContents(Scene::VisibleColumn); - - // setup connections - connect(scene, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex & )), - this, SLOT(updateInfo())); - - connect(scene, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex & )), - viewer, SLOT(updateGL())); - - connect(scene, SIGNAL(updated()), - viewer, SLOT(update())); - - connect(scene, SIGNAL(itemAboutToBeDestroyed(Scene_item*)), - this, SLOT(removeManipulatedFrame(Scene_item*))); - - connect(scene, SIGNAL(updated_bbox()), - this, SLOT(updateViewerBBox())); - - connect(treeView->selectionModel(), - SIGNAL(selectionChanged ( const QItemSelection & , const QItemSelection & ) ), - this, SLOT(updateInfo())); - - connect(treeView->selectionModel(), - SIGNAL(selectionChanged ( const QItemSelection & , const QItemSelection & ) ), - this, SLOT(selectionChanged())); - - connect(viewer, SIGNAL(selected(int)), - this, SLOT(selectSceneItem(int))); - - connect(ui->actionAntiAliasing, SIGNAL(toggled(bool)), - viewer, SLOT(setAntiAliasing(bool))); - - connect(ui->actionDraw_two_sides, SIGNAL(toggled(bool)), - viewer, SLOT(setTwoSides(bool))); - - // enable anti-aliasing by default - ui->actionAntiAliasing->setChecked(true); - - // add the "About CGAL..." and "About demo..." entries - this->addAboutCGAL(); - this->addAboutDemo(":/cgal/Point_set_demo/about.html"); - - // Connect the button "addButton" with actionFileOpen - ui->addButton->setDefaultAction(ui->actionFileOpen); - // Same with "removeButton" and "duplicateButton" - ui->removeButton->setDefaultAction(ui->actionFileClose); - ui->duplicateButton->setDefaultAction(ui->actionDuplicate); - - // Connect actionQuit (Ctrl+Q) and qApp->quit() - connect(ui->actionQuit, SIGNAL(triggered()), - this, SLOT(quit())); - - // Recent files menu - this->addRecentFiles(ui->menuFile, ui->actionQuit); - connect(this, SIGNAL(openRecentFile(QString)), - this, SLOT(open(QString))); - - // Empty the menus implemented by plugins: - // "Analysis", "Processing", "Reconstruction". - clearMenu(ui->menuAnalysis); - clearMenu(ui->menuProcessing); - clearMenu(ui->menuReconstruction); - - // Loads plugins, and re-enable actions that need it. - loadPlugins(); - - readSettings(); // Among other things, the column widths are stored. -} - -void MainWindow::loadPlugins() -{ - Q_FOREACH(QObject *obj, QPluginLoader::staticInstances()) - { - initPlugin(obj); - initIOPlugin(obj); - } - - QDir pluginsDir(qApp->applicationDirPath()); - Q_FOREACH (QString fileName, pluginsDir.entryList(QDir::Files)) { - if(fileName.contains("plugin") && QLibrary::isLibrary(fileName)) { - qDebug("### Loading \"%s\"...", fileName.toUtf8().data()); - QPluginLoader loader; - loader.setFileName(pluginsDir.absoluteFilePath(fileName)); - QObject *obj = loader.instance(); - if(obj) { - initPlugin(obj); - initIOPlugin(obj); - } - else { - qDebug("Error loading \"%s\": %s", - qPrintable(fileName), - qPrintable(loader.errorString())); - } - } - } -} - -bool MainWindow::initPlugin(QObject* obj) -{ - QObjectList childs = this->children(); - Polyhedron_demo_plugin_interface* plugin = - qobject_cast(obj); - if(plugin) { - // Calls plugin's init() method - plugin->init(this, this->scene, this); - - Q_FOREACH(QAction* action, plugin->actions()) { - // If action does not belong to the menus, add it to "Edit" menu. - // TODO: implement something less naive. - if(!childs.contains(action)) { - std::cerr << "Add " << action->text().toStdString() << " menu item to the Edit menu\n"; - ui->menuEdit->addAction(action); - } - // Show and enable menu item - addAction(action); - } - return true; - } - else - return false; -} - -bool MainWindow::initIOPlugin(QObject* obj) -{ - Polyhedron_demo_io_plugin_interface* plugin = - qobject_cast(obj); - if(plugin) { -// std::cerr << "I/O plugin\n"; - io_plugins << plugin; - return true; - } - else - return false; -} - -void MainWindow::clearMenu(QMenu* menu) -{ - Q_FOREACH(QAction* action, menu->actions()) - { - QMenu* menu = action->menu(); - if(menu) { - clearMenu(menu); - } - action->setVisible(false); - } - menu->menuAction()->setEnabled(false); -} - -void MainWindow::addAction(QAction* action) -{ - if(!action) return; - - action->setVisible(true); - action->setEnabled(true); - Q_FOREACH(QWidget* widget, action->associatedWidgets()) - { -// qDebug() << QString("%1 (%2)\n") -// .arg(widget->objectName()) -// .arg(widget->metaObject()->className()); - QMenu* menu = qobject_cast(widget); - if(menu) - { - addAction(menu->menuAction()); - } - } -} - -void MainWindow::message(QString message, QString colorName, QString /*font*/) { - if (message.endsWith('\n')) { - message.remove(message.length()-1, 1); - } - statusBar()->showMessage(message, 5000); - message = "" + message + "
"; - message = "[" + QTime::currentTime().toString() + "] " + message; - ui->consoleTextEdit->insertHtml(message); - ui->consoleTextEdit->verticalScrollBar()->setValue(ui->consoleTextEdit->verticalScrollBar()->maximum()); -} - -void MainWindow::information(QString text) { - this->message("INFO: " + text, ""); -} - -void MainWindow::warning(QString text) { - this->message("WARNING: " + text, "blue"); -} - -void MainWindow::error(QString text) { - this->message("ERROR: " + text, "red"); -} - - -void MainWindow::updateViewerBBox() -{ - const Scene::Bbox bbox = scene->bbox(); - const double xmin = bbox.xmin; - const double ymin = bbox.ymin; - const double zmin = bbox.zmin; - const double xmax = bbox.xmax; - const double ymax = bbox.ymax; - const double zmax = bbox.zmax; - // qDebug() << QString("Bounding box: (%1, %2, %3) - (%4, %5, %6)\n") - // .arg(xmin).arg(ymin).arg(zmin).arg(xmax).arg(ymax).arg(zmax); - qglviewer::Vec - vec_min(xmin, ymin, zmin), - vec_max(xmax, ymax, zmax); - viewer->setSceneBoundingBox(vec_min, - vec_max); - viewer->camera()->showEntireScene(); -} - -void MainWindow::open(QString filename) -{ - QFileInfo fileinfo(filename); - Scene_item* item = 0; - if(fileinfo.isFile() && fileinfo.isReadable()) { - Q_FOREACH(Polyhedron_demo_io_plugin_interface* plugin, - io_plugins) - { - if(plugin->canLoad()) { - item = plugin->load(fileinfo); - if(item) break; // go out of the loop - } - } - if(item) { - Scene::Item_id index = scene->addItem(item); - QSettings settings; - settings.setValue("Point set open directory", - fileinfo.absoluteDir().absolutePath()); - this->addToRecentFiles(filename); - selectSceneItem(index); - } - else { - QMessageBox::critical(this, - tr("Cannot open file"), - tr("File %1 has not a known file format.") - .arg(filename)); - } - } - else { - QMessageBox::critical(this, - tr("Cannot open file"), - tr("File %1 is not a readable file.") - .arg(filename)); - } -} - -void MainWindow::selectSceneItem(int i) -{ - if(i < 0) return; - if((unsigned int)i >= scene->numberOfEntries()) return; - - treeView->selectionModel()->select(scene->createSelection(i), - QItemSelectionModel::ClearAndSelect); -} - -int MainWindow::getSelectedSceneItemIndex() const -{ - QModelIndexList selectedRows = treeView->selectionModel()->selectedRows(); - if(selectedRows.empty()) - return -1; - else - return selectedRows.first().row(); -} - -void MainWindow::selectionChanged() -{ - scene->setSelectedItem(getSelectedSceneItemIndex()); - Scene_item* item = scene->item(getSelectedSceneItemIndex()); - if(item != NULL && item->manipulatable()) { - viewer->setManipulatedFrame(item->manipulatedFrame()); - connect(viewer->manipulatedFrame(), SIGNAL(modified()), - this, SLOT(updateInfo())); - } - - viewer->updateGL(); -} - -void MainWindow::removeManipulatedFrame(Scene_item* item) -{ - if(item->manipulatable() && - item->manipulatedFrame() == viewer->manipulatedFrame()) { - viewer->setManipulatedFrame(0); - } -} - -void MainWindow::updateInfo() { - Scene_item* item = scene->item(getSelectedSceneItemIndex()); - if(item) - ui->infoLabel->setText(item->toolTip()); - else - ui->infoLabel->clear(); -} - -void MainWindow::readSettings() -{ - this->readState("MainWindow", Size|State); -} - -void MainWindow::writeSettings() -{ - this->writeState("MainWindow"); - std::cerr << "Write setting... done.\n"; -} - -void MainWindow::quit() -{ - close(); -} - -void MainWindow::closeEvent(QCloseEvent *event) -{ - writeSettings(); - event->accept(); -} - -void MainWindow::on_actionFileOpen_triggered() -{ - QStringList filters; - Q_FOREACH(Polyhedron_demo_io_plugin_interface* plugin, io_plugins) { - if(plugin->canLoad()) { - filters += plugin->nameFilters(); - } - } - filters << tr("All files (*)"); - - QSettings settings; - QString directory = settings.value("Point set open directory", - QDir::current().dirName()).toString(); - QStringList filenames = - QFileDialog::getOpenFileNames(this, - tr("Open File..."), - directory, - filters.join(";;")); - if(!filenames.isEmpty()) { - Q_FOREACH(QString filename, filenames) { - open(filename); - } - } -} - -void MainWindow::on_actionSaveAs_triggered() -{ - QModelIndexList selectedRows = treeView->selectionModel()->selectedRows(); - if(selectedRows.size() != 1) - return; - Scene_item* item = scene->item(getSelectedSceneItemIndex()); - if(!item) - return; - - QVector canSavePlugins; - QStringList filters; - Q_FOREACH(Polyhedron_demo_io_plugin_interface* plugin, io_plugins) { - if(plugin->canSave(item)) { - canSavePlugins << plugin; - filters += plugin->nameFilters(); - } - } - filters << tr("All files (*)"); - - if(canSavePlugins.isEmpty()) { - QMessageBox::warning(this, - tr("Cannot save"), - tr("The selected object %1 cannot be saved.") - .arg(item->name())); - return; - } - - QSettings settings; - QString directory = settings.value("Point set save directory", - QDir::current().dirName()).toString(); - QString filename = - QFileDialog::getSaveFileName(this, - tr("Save As..."), - directory, - filters.join(";;")); - if (filename.isEmpty()) - return; - - QFileInfo fileinfo(filename); - - bool saved = false; - Q_FOREACH(Polyhedron_demo_io_plugin_interface* plugin, canSavePlugins) { - if(plugin->save(item, fileinfo)) { - saved = true; - break; - } - } - if (saved) { - settings.setValue("Point set save directory", - fileinfo.absoluteDir().absolutePath()); - } - else { - QMessageBox::warning(this, - tr("Cannot save"), - tr("Error while saving object %1 as %2.") - .arg(item->name()) - .arg(filename)); - } -} - -bool MainWindow::on_actionFileClose_triggered() -{ - int index = scene->erase(getSelectedSceneItemIndex()); - selectSceneItem(index); - return index >= 0; -} - -void MainWindow::on_actionFileCloseAll_triggered() -{ - while(on_actionFileClose_triggered()) { - } -} - -void MainWindow::on_actionDuplicate_triggered() -{ - int index = scene->duplicate(getSelectedSceneItemIndex()); - selectSceneItem(index); -} - -void MainWindow::on_actionConvertToPointSet_triggered() -{ - int index = scene->convertToPointSet(getSelectedSceneItemIndex()); - selectSceneItem(index); -} - -void MainWindow::on_actionDeleteSelection_triggered() -{ - scene->deleteSelection(getSelectedSceneItemIndex()); -} - -void MainWindow::on_actionResetSelection_triggered() -{ - scene->resetSelection(getSelectedSceneItemIndex()); -} - -void MainWindow::on_actionShowHide_triggered() -{ - Q_FOREACH(QModelIndex index, treeView->selectionModel()->selectedRows()) - { - int i = index.row(); - Scene_item* item = scene->item(i); - item->setVisible(!item->visible()); - scene->itemChanged(i); - } -} - -void MainWindow::setAddKeyFrameKeyboardModifiers(::Qt::KeyboardModifiers m) -{ - viewer->setAddKeyFrameKeyboardModifiers(m); -} diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/MainWindow.h cgal-4.5/demo/Surface_reconstruction_points_3/MainWindow.h --- cgal-4.4/demo/Surface_reconstruction_points_3/MainWindow.h 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/MainWindow.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,98 +0,0 @@ -#ifndef MAINWINDOW_H -#define MAINWINDOW_H -#include "config.h" - -#include -#include - -#include - -class Scene; -class Viewer; -class QTreeView; -class QMenu; -class Polyhedron_demo_io_plugin_interface; - -class Scene_item; - -namespace Ui { - class MainWindow; -} - -#include "Polyhedron_type_fwd.h" - -#include "Messages_interface.h" - -class MainWindow : - public CGAL::Qt::DemosMainWindow, - public Messages_interface -{ - Q_OBJECT - Q_INTERFACES(Messages_interface) -public: - MainWindow(QWidget* parent = 0); - ~MainWindow(); - -public slots: - void updateViewerBBox(); - void open(QString filename); - - void selectSceneItem(int i); - - void setAddKeyFrameKeyboardModifiers(Qt::KeyboardModifiers); - - void clearMenu(QMenu*); - void addAction(QAction*); - - void information(QString); - void warning(QString); - void error(QString); - -protected slots: - void selectionChanged(); - void updateInfo(); - void removeManipulatedFrame(Scene_item*); - - // settings - void quit(); - void readSettings(); - void writeSettings(); - - // load, erase, duplicate - void on_actionFileCloseAll_triggered(); - void on_actionFileOpen_triggered(); - bool on_actionFileClose_triggered(); - void on_actionDuplicate_triggered(); - void on_actionConvertToPointSet_triggered(); - - // selection - void on_actionDeleteSelection_triggered(); - void on_actionResetSelection_triggered(); - - // Show/Hide - void on_actionShowHide_triggered(); - - // save as... - void on_actionSaveAs_triggered(); - -protected: - void message(QString, QString, QString = QString("normal")); - void loadPlugins(); - bool initPlugin(QObject*); - bool initIOPlugin(QObject*); - - void closeEvent(QCloseEvent *event); - - int getSelectedSceneItemIndex() const; - -private: - QString strippedName(const QString &fullFileName); - - Scene* scene; - Viewer* viewer; - QTreeView* treeView; - Ui::MainWindow* ui; - QVector io_plugins; -}; - -#endif // ifndef MAINWINDOW_H diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/MainWindow.ui cgal-4.5/demo/Surface_reconstruction_points_3/MainWindow.ui --- cgal-4.4/demo/Surface_reconstruction_points_3/MainWindow.ui 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/MainWindow.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,429 +0,0 @@ - - - MainWindow - - - - 0 - 0 - 636 - 578 - - - - CGAL Point Set demo - - - - :/cgal/icons/resources/cgal_logo.xpm:/cgal/icons/resources/cgal_logo.xpm - - - - - - - - 0 - 1 - - - - - - - - - - - - - 0 - 0 - 636 - 26 - - - - - &File - - - - - - - - - - - &Edit - - - - - - - - - - - - &View - - - - Dock windows - - - - - - - - - - Analysis - - - - - - - Processing - - - - - - - - - - Reconstruction - - - - - - - - - - - - - - - - - - - Point sets and surfaces - - - 1 - - - - - - - - - - - + - - - - :/cgal/icons/plus:/cgal/icons/plus - - - - - - - - - - - - :/cgal/icons/minus:/cgal/icons/minus - - - - - - - ... - - - - :/cgal/icons/duplicate:/cgal/icons/duplicate - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed|QAbstractItemView::SelectedClicked - - - true - - - 0 - - - - - - - - - - - Qt::BottomDockWidgetArea|Qt::LeftDockWidgetArea|Qt::TopDockWidgetArea - - - Console - - - 8 - - - - - - - true - - - - - - - - - &Quit - - - Ctrl+Q - - - - - &Simplification - - - - - - :/cgal/icons/plus:/cgal/icons/plus - - - &Open... - - - Ctrl+O - - - - - - :/cgal/icons/minus:/cgal/icons/minus - - - &Close - - - Ctrl+W - - - - - - :/cgal/icons/duplicate:/cgal/icons/duplicate - - - &Duplicate - - - Ctrl+D - - - - - true - - - &Antialiasing - - - - - n/a - - - - - &Close All - - - - - &Options... - - - - - Save &as... - - - Ctrl+Alt+S - - - - - &Save - - - - - Save a&ll - - - - - Mer&ge all - - - - - &Merge - - - - - Select &all - - - - - Select &none - - - - - &Invert selection - - - - - Show/Hide - - - Ctrl+Space - - - - - Inside-out - - - - - APSS Reconstruction - - - - - Point radius from density - - - - - Outlier removal - - - - - Jet smoothing - - - - - Normal estimation - - - - - true - - - Draw two sides - - - - - Convert to Point Set - - - Convert Mesh to Point Set - - - - - Delete Selection - - - Del - - - - - Reset Selection - - - - - Poisson reconstruction - - - - - Average spacing - - - - - Normal inversion - - - - - - Viewer - QWidget -
Viewer.h
-
-
- - - - -
diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/marching_cubes.h cgal-4.5/demo/Surface_reconstruction_points_3/marching_cubes.h --- cgal-4.4/demo/Surface_reconstruction_points_3/marching_cubes.h 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/marching_cubes.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,574 +0,0 @@ - -#ifndef MARCHINGCUBES_H -#define MARCHINGCUBES_H - -#include - -namespace internal -{ - -//************************************************************************ -// Static precalculated table -//************************************************************************ -int msEdgeTable[256]={ - 0x0 , 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c, - 0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00, - 0x190, 0x99 , 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c, - 0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90, - 0x230, 0x339, 0x33 , 0x13a, 0x636, 0x73f, 0x435, 0x53c, - 0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30, - 0x3a0, 0x2a9, 0x1a3, 0xaa , 0x7a6, 0x6af, 0x5a5, 0x4ac, - 0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0, - 0x460, 0x569, 0x663, 0x76a, 0x66 , 0x16f, 0x265, 0x36c, - 0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60, - 0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff , 0x3f5, 0x2fc, - 0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0, - 0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55 , 0x15c, - 0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950, - 0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc , - 0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0, - 0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc, - 0xcc , 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0, - 0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c, - 0x15c, 0x55 , 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650, - 0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc, - 0x2fc, 0x3f5, 0xff , 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0, - 0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c, - 0x36c, 0x265, 0x16f, 0x66 , 0x76a, 0x663, 0x569, 0x460, - 0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac, - 0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa , 0x1a3, 0x2a9, 0x3a0, - 0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c, - 0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33 , 0x339, 0x230, - 0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c, - 0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99 , 0x190, - 0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c, - 0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0}; - -int msTriTable[256][16] = { - {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1}, - {3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1}, - {3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1}, - {3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1}, - {9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1}, - {1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1}, - {9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1}, - {2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1}, - {8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1}, - {9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1}, - {4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1}, - {3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1}, - {1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1}, - {4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1}, - {4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1}, - {9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1}, - {1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1}, - {5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1}, - {2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1}, - {9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1}, - {0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1}, - {2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1}, - {10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1}, - {4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1}, - {5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1}, - {5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1}, - {9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1}, - {0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1}, - {1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1}, - {10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1}, - {8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1}, - {2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1}, - {7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1}, - {9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1}, - {2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1}, - {11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1}, - {9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1}, - {5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1}, - {11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1}, - {11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1}, - {1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1}, - {9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1}, - {5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1}, - {2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1}, - {0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1}, - {5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1}, - {6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1}, - {0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1}, - {3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1}, - {6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1}, - {5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1}, - {1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1}, - {10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1}, - {6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1}, - {1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1}, - {8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1}, - {7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1}, - {3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1}, - {5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1}, - {0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1}, - {9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1}, - {8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1}, - {5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1}, - {0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1}, - {6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1}, - {10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1}, - {10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1}, - {8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1}, - {1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1}, - {3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1}, - {0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1}, - {10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1}, - {0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1}, - {3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1}, - {6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1}, - {9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1}, - {8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1}, - {3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1}, - {6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1}, - {0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1}, - {10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1}, - {10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1}, - {1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1}, - {2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1}, - {7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1}, - {7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1}, - {2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1}, - {1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1}, - {11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1}, - {8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1}, - {0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1}, - {7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1}, - {10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1}, - {2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1}, - {6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1}, - {7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1}, - {2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1}, - {1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1}, - {10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1}, - {10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1}, - {0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1}, - {7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1}, - {6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1}, - {8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1}, - {9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1}, - {6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1}, - {1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1}, - {4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1}, - {10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1}, - {8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1}, - {0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1}, - {1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1}, - {8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1}, - {10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1}, - {4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1}, - {10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1}, - {5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1}, - {11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1}, - {9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1}, - {6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1}, - {7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1}, - {3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1}, - {7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1}, - {9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1}, - {3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1}, - {6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1}, - {9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1}, - {1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1}, - {4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1}, - {7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1}, - {6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1}, - {3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1}, - {0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1}, - {6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1}, - {1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1}, - {0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1}, - {11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1}, - {6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1}, - {5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1}, - {9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1}, - {1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1}, - {1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1}, - {10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1}, - {0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1}, - {5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1}, - {10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1}, - {11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1}, - {0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1}, - {9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1}, - {7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1}, - {2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1}, - {8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1}, - {9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1}, - {9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1}, - {1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1}, - {9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1}, - {9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1}, - {5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1}, - {0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1}, - {10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1}, - {2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1}, - {0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1}, - {0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1}, - {9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1}, - {5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1}, - {3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1}, - {5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1}, - {8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1}, - {0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1}, - {9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1}, - {0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1}, - {1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1}, - {3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1}, - {4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1}, - {9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1}, - {11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1}, - {11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1}, - {2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1}, - {9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1}, - {3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1}, - {1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1}, - {4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1}, - {4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1}, - {0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1}, - {3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1}, - {3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1}, - {0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1}, - {9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1}, - {1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, - {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}; - -} // end of namespace internal - -namespace CGAL { - -template -class Marching_cubes : public CGAL::Modifier_base -{ - typedef typename Surface::Geom_traits Traits; - typedef typename Traits::FT FT; - typedef typename Traits::Point_3 Point_3; - typedef typename Traits::Vector_3 Vector_3; - typedef typename Surface::BBox BBox; - - // represent a vertices of the lattice - struct GridElement - { - Point_3 position; - FT value; - inline bool isInvalid() const { return value == Invalid; } - inline void markInvalid() { value = Invalid; } - }; - static const long Invalid = 987654321; - - public: - - Marching_cubes(const Surface& s, int gs) : surface(s), grid_size(gs) {} - - void operator() (HDS& hds) - { - const FT iso_value = FT(0); - - // size of the blocks - static const int maxBlockSize = 128; - - // precomputed offsets to access the cell corners - static const int offsets[8] = { - 0, - 1, - 1+maxBlockSize*maxBlockSize, - maxBlockSize*maxBlockSize, - maxBlockSize, - 1+maxBlockSize, - 1+maxBlockSize+maxBlockSize*maxBlockSize, - maxBlockSize+maxBlockSize*maxBlockSize}; - - // returns the local extremity indices of an edge from its local index - static const int edge_to_vertex[12][2] = { - {0,1}, // 0 - {1,2}, // 1 - {2,3}, // 2 - {0,3}, // 3 - {4,5}, // 4 - {5,6}, // 5 - {6,7}, // 6 - {4,7}, // 7 - {0,4}, // 8 - {1,5}, // 9 - {2,6}, // 10 - {3,7}}; // 11 - - // get the bouding box: - BBox bbox = surface.bounding_box(); - - Vector_3 diag = Vector_3(bbox.xmax() - bbox.xmin(), bbox.ymax() - bbox.ymin(), bbox.zmax() - bbox.zmin()); - - if ( (diag.x()<=0.) - || (diag.y()<=0.) - || (diag.z()<=0.) - || (grid_size<=0)) - { - return; - } - - std::vector grid(maxBlockSize*maxBlockSize*maxBlockSize); - - // start a new 3D mesh - int vertex_count = 0; - Polyhedron_incremental_builder_3 B(hds, true); // true means verbose ?? - B.begin_surface(10,10,10); - - typedef std::pair EdgeKey; - - FT step = (std::max)( (std::max)(diag.x(), diag.y()), diag.z())/FT(grid_size); - - unsigned int nbCells[3]; - unsigned int nbBlocks[3]; - - for (int k=0 ; k<3 ; ++k) - { - nbCells[k] = int(diag[k]/step)+2; - nbBlocks[k] = nbCells[k]/maxBlockSize + ( (nbCells[k]%maxBlockSize)==0 ? 0 : 1); - } - - // for each macro block - uint bi[3]; // block id - for(bi[2]=0 ; bi[2] unique_vertex_map; - - // compute the size of the local grid - uint gridSize[3]; - for (uint k=0 ; k<3 ; ++k) - { - gridSize[k] = std::min(maxBlockSize, nbCells[k]-(maxBlockSize-1)*bi[k]); - } - Point_3 origin = Point_3(bbox.xmin(),bbox.ymin(),bbox.zmin()) + step * (maxBlockSize-1) * Vector_3(bi[0],bi[1],bi[2]); - - // fill the grid - uint ci[3]; // local cell id - - // for each vertex... - for(ci[0]=0 ; ci[0]v1) - std::swap(v0,v1); - - EdgeKey key(v0,v1); - std::map::iterator it = unique_vertex_map.find(key); - - if (it!=unique_vertex_map.end()) - { - //int count - // the vertex already exist - auxId[j] = it->second; - } - else - { - const Point_3& p = edges[::internal::msTriTable[mask][i+j]]; - // add a new vertex - auxId[j] = vertex_count; - countAddedVertex++; - B.add_vertex(p); - unique_vertex_map[key] = vertex_count; - vertex_count++; - } - } - if (auxId[0]!=auxId[1] && auxId[1]!=auxId[2] && auxId[2]!=auxId[0]) - { - B.begin_facet(); - for (uint j=0;j<3;++j) - B.add_vertex_to_facet(auxId[j]); - B.end_facet(); - } - } - } - } - } - } - B.end_surface(); - } - - protected: - inline Point_3 interpolEdge(const GridElement& v1, const GridElement& v2) - { - FT epsilon = 1e-6; // FIXME not very nice ;) - - if (std::abs(v1.value) < epsilon) - return v1.position; - if (std::abs(v2.value) < epsilon) - return v2.position; - if (std::abs(v1.value-v2.value) < epsilon) - return v1.position + FT(0.5) * (v2.position - v1.position); - - FT a = (-v1.value) / (v2.value - v1.value); - return v1.position + a * (v2.position - v1.position); - } - - inline bool is_finite(FT x) - { - return (x >= -(std::numeric_limits::max)()) && (x <= (std::numeric_limits::max)()); - } - - protected: - const Surface surface; - int grid_size; -}; - - - - -template -void marching_cubes(const Surface& surface, int grid_size, Polyhedron& target) -{ - Marching_cubes mc(surface, grid_size); - target.delegate(mc); -} - -} // end of namespace CGAL - -#endif // MARCHINGCUBES_H diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/Messages_interface.h cgal-4.5/demo/Surface_reconstruction_points_3/Messages_interface.h --- cgal-4.4/demo/Surface_reconstruction_points_3/Messages_interface.h 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/Messages_interface.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ -#ifndef MESSAGES_INTERFACE_H -#define MESSAGES_INTERFACE_H - -#include -#include - -class Messages_interface { -public: - virtual ~Messages_interface() {} - virtual void warning(QString) = 0; - virtual void error(QString) = 0; - virtual void information(QString) = 0; -}; - -Q_DECLARE_INTERFACE(Messages_interface, - "com.geometryfactory.PolyhedronDemo.MessagesInterface/1.0") - -#endif // MESSAGES_INTERFACE_H diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/Point_set_demo.cpp cgal-4.5/demo/Surface_reconstruction_points_3/Point_set_demo.cpp --- cgal-4.4/demo/Surface_reconstruction_points_3/Point_set_demo.cpp 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/Point_set_demo.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,41 +0,0 @@ -#include "MainWindow.h" -#include -#include - -int main(int argc, char **argv) -{ - QApplication app(argc, argv); - app.setOrganizationDomain("cgal.org"); - app.setOrganizationName("CGAL"); - app.setApplicationName("Point Set Demo"); - - // Import resources from libCGALQt4. - // See http://doc.trolltech.com/4.4/qdir.html#Q_INIT_RESOURCE - CGAL_QT4_INIT_RESOURCES; - - MainWindow mainWindow; - mainWindow.show(); - QStringList args = app.arguments(); - args.removeAt(0); - - if(!args.empty() && args[0] == "--use-meta") - { - mainWindow.setAddKeyFrameKeyboardModifiers(::Qt::MetaModifier); - args.removeAt(0); - } - - Q_FOREACH(QString filename, args) { - mainWindow.open(filename); - } - return app.exec(); -} - -#ifndef USE_FORWARD_DECL -# include "Scene.cpp" -# include "Scene_item.cpp" -# include "Scene_moc.cpp" -# include "Viewer.cpp" -# include "Viewer_moc.cpp" -# include "MainWindow.cpp" -# include "MainWindow_moc.cpp" -#endif diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/Point_set_demo.qrc cgal-4.5/demo/Surface_reconstruction_points_3/Point_set_demo.qrc --- cgal-4.4/demo/Surface_reconstruction_points_3/Point_set_demo.qrc 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/Point_set_demo.qrc 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ - - - resources/cgal_logo.xpm - resources/simplification.png - resources/editcopy.png - resources/check-on.png - resources/plus.png - resources/check-off.png - resources/minus.png - - - resources/about.html - - diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/Point_set_scene_item_config.h cgal-4.5/demo/Surface_reconstruction_points_3/Point_set_scene_item_config.h --- cgal-4.4/demo/Surface_reconstruction_points_3/Point_set_scene_item_config.h 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/Point_set_scene_item_config.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -#ifndef POINT_SET_ITEM_CONFIG_H -#define POINT_SET_ITEM_CONFIG_H - -#ifdef point_set_EXPORTS -# define POINT_SET_ITEM_EXPORT Q_DECL_EXPORT -#else -# define POINT_SET_ITEM_EXPORT Q_DECL_IMPORT -#endif - -#endif // POINT_SET_ITEM_CONFIG_H diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/Point_set_scene_item.cpp cgal-4.5/demo/Surface_reconstruction_points_3/Point_set_scene_item.cpp --- cgal-4.4/demo/Surface_reconstruction_points_3/Point_set_scene_item.cpp 2013-06-15 19:00:26.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/Point_set_scene_item.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,292 +0,0 @@ -#include "Point_set_scene_item.h" -#include "Polyhedron_type.h" -#include "CGAL/compute_normal.h" - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include -#include -#include -#include - - -Point_set_scene_item::Point_set_scene_item() - : Scene_item_with_display_list(), - m_points(new Point_set) -{ - setRenderingMode(PointsPlusNormals); -} - -// Copy constructor -Point_set_scene_item::Point_set_scene_item(const Point_set_scene_item& toCopy) - : Scene_item_with_display_list(), // do not call superclass' copy constructor - m_points(new Point_set(*toCopy.m_points)) -{ - setRenderingMode(PointsPlusNormals); -} - -// Converts polyhedron to point set -Point_set_scene_item::Point_set_scene_item(const Polyhedron& input_mesh) - : Scene_item_with_display_list(), - m_points(new Point_set) -{ - // Converts Polyhedron vertices to point set. - // Computes vertices normal from connectivity. - Polyhedron::Vertex_const_iterator v; - for (v = input_mesh.vertices_begin(); v != input_mesh.vertices_end(); v++) - { - const Point& p = v->point(); - Vector n = compute_vertex_normal(*v); - m_points->push_back(UI_point(p,n)); - } - - setRenderingMode(PointsPlusNormals); -} - -Point_set_scene_item::~Point_set_scene_item() -{ - Q_ASSERT(m_points != NULL); - delete m_points; m_points = NULL; -} - -// Duplicates scene item -Point_set_scene_item* -Point_set_scene_item::clone() const -{ - return new Point_set_scene_item(*this); -} - -// Is selection empty? -bool Point_set_scene_item::isSelectionEmpty() const -{ - return (m_points->nb_selected_points() == 0); -} - -// Delete selection -void Point_set_scene_item::deleteSelection() -{ - CGAL::Timer task_timer; task_timer.start(); - std::cerr << "Delete " << m_points->nb_selected_points() << " points..."; - - // Delete selected points - m_points->delete_selection(); - - long memory = CGAL::Memory_sizer().virtual_size(); - std::cerr << "done: " << task_timer.time() << " seconds, " - << (memory>>20) << " Mb allocated" - << std::endl; -} - -// Reset selection mark -void Point_set_scene_item::resetSelection() -{ - // Un-select all points - m_points->select(m_points->begin(), m_points->end(), false); -} - -// Loads point set from .OFF file -bool Point_set_scene_item::read_off_point_set(std::istream& stream) -{ - Q_ASSERT(m_points != NULL); - - m_points->clear(); - bool ok = stream && - CGAL::read_off_points_and_normals(stream, - std::back_inserter(*m_points), -#ifdef CGAL_USE_PROPERTY_MAPS_API_V1 - CGAL::make_normal_of_point_with_normal_pmap(std::back_inserter(*m_points)) -#else - CGAL::make_normal_of_point_with_normal_pmap(Point_set::value_type()) -#endif - ) && - !isEmpty(); - - return ok; -} - -// Write point set to .OFF file -bool Point_set_scene_item::write_off_point_set(std::ostream& stream) const -{ - Q_ASSERT(m_points != NULL); - - return stream && - CGAL::write_off_points_and_normals(stream, - m_points->begin(), m_points->end(), -#ifdef CGAL_USE_PROPERTY_MAPS_API_V1 - CGAL::make_normal_of_point_with_normal_pmap(m_points->begin()) -#else - CGAL::make_normal_of_point_with_normal_pmap(Point_set::value_type()) -#endif - ); -} - -// Loads point set from .XYZ file -bool Point_set_scene_item::read_xyz_point_set(std::istream& stream) -{ - Q_ASSERT(m_points != NULL); - - m_points->clear(); - bool ok = stream && - CGAL::read_xyz_points_and_normals(stream, - std::back_inserter(*m_points), -#ifdef CGAL_USE_PROPERTY_MAPS_API_V1 - CGAL::make_normal_of_point_with_normal_pmap(std::back_inserter(*m_points)) -#else - CGAL::make_normal_of_point_with_normal_pmap(Point_set::value_type()) -#endif - ) && - !isEmpty(); - - return ok; -} - -// Write point set to .XYZ file -bool Point_set_scene_item::write_xyz_point_set(std::ostream& stream) const -{ - Q_ASSERT(m_points != NULL); - - return stream && - CGAL::write_xyz_points_and_normals(stream, - m_points->begin(), m_points->end(), -#ifdef CGAL_USE_PROPERTY_MAPS_API_V1 - CGAL::make_normal_of_point_with_normal_pmap(m_points->begin()) -#else - CGAL::make_normal_of_point_with_normal_pmap(Point_set::value_type()) -#endif - ); -} - -QString -Point_set_scene_item::toolTip() const -{ - Q_ASSERT(m_points != NULL); - - return QObject::tr("

%1 (color: %4)
" - "Point set

" - "

Number of points: %2

") - .arg(name()) - .arg(m_points->size()) - .arg(color().name()); -} - -bool Point_set_scene_item::supportsRenderingMode(RenderingMode m) const -{ - return m==Points || m==PointsPlusNormals || m==Splatting; -} - -// Points OpenGL drawing in a display list -void Point_set_scene_item::direct_draw() const -{ - Q_ASSERT(m_points != NULL); - - // Draw points - m_points->gl_draw_vertices(); -} - -// Normals OpenGL drawing -void Point_set_scene_item::draw_normals() const -{ - Q_ASSERT(m_points != NULL); - - // Draw normals - bool points_have_normals = (m_points->begin() != m_points->end() && - m_points->begin()->normal() != CGAL::NULL_VECTOR); - if(points_have_normals) - { - Sphere region_of_interest = m_points->region_of_interest(); - float normal_length = (float)std::sqrt(region_of_interest.squared_radius() / 1000.); - - m_points->gl_draw_normals(normal_length); - } -} - -void Point_set_scene_item::draw_splats() const -{ - Q_ASSERT(m_points != NULL); - - // Draw splats - bool points_have_normals = (m_points->begin() != m_points->end() && - m_points->begin()->normal() != CGAL::NULL_VECTOR); - bool points_have_radii = (m_points->begin() != m_points->end() && - m_points->begin()->radius() != FT(0)); - if(points_have_normals && points_have_radii) - { - m_points->gl_draw_splats(); - } -} - -// Gets wrapped point set -Point_set* Point_set_scene_item::point_set() -{ - Q_ASSERT(m_points != NULL); - return m_points; -} -const Point_set* Point_set_scene_item::point_set() const -{ - Q_ASSERT(m_points != NULL); - return m_points; -} - -bool -Point_set_scene_item::isEmpty() const -{ - Q_ASSERT(m_points != NULL); - return m_points->empty(); -} - -Point_set_scene_item::Bbox -Point_set_scene_item::bbox() const -{ - Q_ASSERT(m_points != NULL); - - Iso_cuboid bbox = m_points->bounding_box(); - return Bbox(bbox.xmin(),bbox.ymin(),bbox.zmin(), - bbox.xmax(),bbox.ymax(),bbox.zmax()); -} - -void Point_set_scene_item::computes_local_spacing(int k) -{ - typedef Kernel Geom_traits; - typedef CGAL::Search_traits_3 TreeTraits; - typedef CGAL::Orthogonal_k_neighbor_search Neighbor_search; - typedef Neighbor_search::Tree Tree; - - Point_set::iterator end(m_points->end()); - - // build kdtree - Tree tree(m_points->begin(), end); - - // Compute the radius of each point = (distance max to k nearest neighbors)/2. - { - int i=0; - for (Point_set::iterator it=m_points->begin(); it!=end; ++it, ++i) - { - Neighbor_search search(tree, *it, k+1); - double maxdist2 = (--search.end())->second; // squared distance to furthest neighbor - it->radius() = sqrt(maxdist2)/2.; - } - } - - m_points->set_radii_uptodate(true); -} - -void Point_set_scene_item::setRenderingMode(RenderingMode m) -{ - Scene_item_with_display_list::setRenderingMode(m); - if (rendering_mode==Splatting && (!m_points->are_radii_uptodate())) - { - computes_local_spacing(6); // default value = small - } -} - -#include "Point_set_scene_item.moc" diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/Point_set_scene_item.h cgal-4.5/demo/Surface_reconstruction_points_3/Point_set_scene_item.h --- cgal-4.4/demo/Surface_reconstruction_points_3/Point_set_scene_item.h 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/Point_set_scene_item.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,77 +0,0 @@ -#ifndef POINT_SET_ITEM_H -#define POINT_SET_ITEM_H - -#include "Point_set_scene_item_config.h" -#include "Polyhedron_type_fwd.h" -#include "Kernel_type.h" -#include "Point_set_3.h" -#include "Scene_item_with_display_list.h" - -#include - - -// point set -typedef Point_set_3 Point_set; -typedef Point_set::UI_point UI_point; // type of points in Point_set_3 - - -// This class represents a point set in the OpenGL scene -class POINT_SET_ITEM_EXPORT Point_set_scene_item - : public Scene_item_with_display_list -{ - Q_OBJECT - -public: - Point_set_scene_item(); - Point_set_scene_item(const Point_set_scene_item& toCopy); - Point_set_scene_item(const Polyhedron& p); - ~Point_set_scene_item(); - Point_set_scene_item* clone() const; - - // Is selection empty? - virtual bool isSelectionEmpty() const; - // Delete selection - virtual void deleteSelection(); - // Reset selection mark - void resetSelection(); - - // IO - bool read_off_point_set(std::istream& in); - bool write_off_point_set(std::ostream& out) const; - bool read_xyz_point_set(std::istream& in); - bool write_xyz_point_set(std::ostream& out) const; - - // Function for displaying meta-data of the item - virtual QString toolTip() const; - - // Indicate if rendering mode is supported - virtual bool supportsRenderingMode(RenderingMode m) const; - // Points OpenGL drawing in a display list - virtual void direct_draw() const; - // Normals OpenGL drawing - virtual void draw_normals() const; - // Draws oriented points with radius - virtual void draw_splats() const; - - // Gets wrapped point set - Point_set* point_set(); - const Point_set* point_set() const; - - // Gets dimensions - virtual bool isFinite() const { return true; } - virtual bool isEmpty() const; - virtual Bbox bbox() const; - - virtual void setRenderingMode(RenderingMode m); - - // computes the local point spacing (aka radius) of each point - void computes_local_spacing(int k); - -// Data -private: - Point_set* m_points; - -}; // end class Point_set_scene_item - - -#endif // POINT_SET_ITEM_H diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/Polyhedron_demo_io_plugin_interface.h cgal-4.5/demo/Surface_reconstruction_points_3/Polyhedron_demo_io_plugin_interface.h --- cgal-4.4/demo/Surface_reconstruction_points_3/Polyhedron_demo_io_plugin_interface.h 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/Polyhedron_demo_io_plugin_interface.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -#ifndef POLYHEDRON_DEMO_IO_PLUGIN_INTERFACE_H -#define POLYHEDRON_DEMO_IO_PLUGIN_INTERFACE_H - -#include -#include - -class Scene_item; - -class Polyhedron_demo_io_plugin_interface -{ -public: - virtual ~Polyhedron_demo_io_plugin_interface() {} - virtual QStringList nameFilters() const = 0; - - virtual bool canLoad() const = 0; - virtual Scene_item* load(QFileInfo fileinfo) = 0; - - virtual bool canSave(const Scene_item*) = 0; - virtual bool save(const Scene_item*, QFileInfo fileinfo) = 0; -}; - -Q_DECLARE_INTERFACE(Polyhedron_demo_io_plugin_interface, - "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0") - -#endif // POLYHEDRON_DEMO_IO_PLUGIN_INTERFACE_H diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/Polyhedron_demo_plugin_helper.cpp cgal-4.5/demo/Surface_reconstruction_points_3/Polyhedron_demo_plugin_helper.cpp --- cgal-4.4/demo/Surface_reconstruction_points_3/Polyhedron_demo_plugin_helper.cpp 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/Polyhedron_demo_plugin_helper.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,109 +0,0 @@ -#include "Polyhedron_demo_plugin_helper.h" -#include -#include -#include -#include -#include -#include -#include - -QAction* -Polyhedron_demo_plugin_helper:: -getActionFromMainWindow(QMainWindow* mw, - QString action_name) -{ - return mw->findChild(action_name); -} - -QStringList -Polyhedron_demo_plugin_helper::actionsNames() const -{ - return QStringList(); -} - -void -Polyhedron_demo_plugin_helper:: -init(QMainWindow* mainWindow, Scene_interface* scene_interface) { - mw = mainWindow; - scene = scene_interface; - Q_FOREACH(QString actionName, actionsNames()) - { - actions_map[actionName] = getActionFromMainWindow(mw, actionName); - } - autoConnectActions(); -} - -QList -Polyhedron_demo_plugin_helper::actions() const -{ - return actions_map.values(); -} - -// Auto-connect actions to slots -void Polyhedron_demo_plugin_helper::autoConnectActions() -{ - QObject* thisObject = dynamic_cast(this); - if(!thisObject) - return; - - const QMetaObject* metaObject = thisObject->metaObject(); - QVector methods; - QVector methodsNames; - QSet connected; - for(int i = metaObject->methodOffset(); - i < metaObject->methodCount(); - ++i) - { - const int pos = QString(metaObject->method(i).signature()).indexOf('('); - methodsNames << QString(metaObject->method(i).signature()).left(pos); - methods << metaObject->method(i); - } - - Q_FOREACH(QAction* action, actions()) - { - bool success = false; -// qDebug("Autoconnecting action \"%s\"...", -// action->objectName().toUtf8().data()); - const QMetaObject* action_metaObject = action->metaObject(); - for(int i = action_metaObject->methodOffset(); - i < action_metaObject->methodCount(); ++i) - { - QMetaMethod action_method = action_metaObject->method(i); - - if(action_method.methodType() == QMetaMethod::Signal) - { - const int pos = QString(action_method.signature()).indexOf('('); - QString methodName = QString(action_method.signature()).left(pos); - QString slotName = - QString("on_%1_%2").arg(action->objectName()).arg(methodName); -// qDebug() << thisObject->tr("Slot %1 (%2)...").arg(slotName).arg(i); - int index = methodsNames.indexOf(slotName); - if(index>=0 && !connected.contains(slotName)) { - const bool ok = - QObject::connect(action, - qPrintable(QString("2%1").arg(action_method.signature())), - thisObject, - qPrintable(QString("1%1").arg(methods[index].signature()))); - if(!ok) - { - qDebug() << thisObject->tr("Cannot connect method %1.%2 to slot %3!") - .arg(action->objectName()) - .arg(action_method.signature()) - .arg(methods[index].signature()); - } - else { -// qDebug(" ->Connected!"); - success = true; - connected << slotName; - } - } -// else { -// qDebug(" nothing found!\n"); -// } - } - } // end for each method of action - if(!success) - qDebug("ERROR: Failed to autoconnect the action \"%s\"!", - action->objectName().toUtf8().data()); - } // end foreach action of actions() -} diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/Polyhedron_demo_plugin_helper.h cgal-4.5/demo/Surface_reconstruction_points_3/Polyhedron_demo_plugin_helper.h --- cgal-4.4/demo/Surface_reconstruction_points_3/Polyhedron_demo_plugin_helper.h 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/Polyhedron_demo_plugin_helper.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ -#ifndef POLYHEDRON_DEMO_OPERATION_HELPER_H -#define POLYHEDRON_DEMO_OPERATION_HELPER_H - -#include "Scene_item_config.h" //defines SCENE_ITEM_EXPORT - -#include -#include -#include - -class QAction; -struct QMetaObject; -class QMainWindow; -class Scene_interface; - -#include "Polyhedron_demo_plugin_interface.h" - -class SCENE_ITEM_EXPORT Polyhedron_demo_plugin_helper - : public Polyhedron_demo_plugin_interface -{ -public: - // Gets action object from its name - static QAction* getActionFromMainWindow(QMainWindow*, QString action_name); - - // Init plugin - virtual void init(QMainWindow* mainWindow, Scene_interface* scene_interface); - - // Gets list of actions supported by this plugin - virtual QStringList actionsNames() const; - virtual QList actions() const; - - // Auto-connect actions to slots. Called by init(). - void autoConnectActions(); - -protected: - QMap actions_map; - Scene_interface* scene; - QMainWindow* mw; -}; - -#endif // POLYHEDRON_DEMO_OPERATION_HELPER_H diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/Polyhedron_demo_plugin_interface.h cgal-4.5/demo/Surface_reconstruction_points_3/Polyhedron_demo_plugin_interface.h --- cgal-4.4/demo/Surface_reconstruction_points_3/Polyhedron_demo_plugin_interface.h 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/Polyhedron_demo_plugin_interface.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ -#ifndef POLYHEDRON_DEMO_PLUGIN_INTERFACE_H -#define POLYHEDRON_DEMO_PLUGIN_INTERFACE_H - -#include -#include -#include - -class QAction; -class QMainWindow; -class Scene_interface; -class Messages_interface; - -class Polyhedron_demo_plugin_interface -{ -public: - virtual ~Polyhedron_demo_plugin_interface() {} - virtual void init(QMainWindow*, Scene_interface*) {}; - virtual void init(QMainWindow* mw, Scene_interface* sc, Messages_interface*) { - init(mw, sc); - }; - virtual QList actions() const = 0; -}; - -Q_DECLARE_INTERFACE(Polyhedron_demo_plugin_interface, - "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") - -#endif // POLYHEDRON_DEMO_PLUGIN_INTERFACE_H diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/Polyhedron_type_fwd.h cgal-4.5/demo/Surface_reconstruction_points_3/Polyhedron_type_fwd.h --- cgal-4.4/demo/Surface_reconstruction_points_3/Polyhedron_type_fwd.h 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/Polyhedron_type_fwd.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,49 +0,0 @@ -#ifndef POLYHEDRON_TYPE_FWD_H -#define POLYHEDRON_TYPE_FWD_H - -#include -#include - -#ifdef USE_FORWARD_DECL - -#include - -namespace CGAL { - - template < typename FT_ > - struct Simple_cartesian; - - class Polyhedron_items_3; - - template < class T, class I, class A> - class HalfedgeDS_default; - - template < class PolyhedronTraits_3, - class PolyhedronItems_3, - template < class T, class I, class A> - class T_HDS, - class Alloc - > - class Polyhedron_3; - - class Epick; - -} // end namespace CGAL - -// kernel - -typedef CGAL::Epick Kernel; - -// surface mesh -typedef CGAL::Polyhedron_3 > Polyhedron; - -#else // USE_FORWARD_DECL - -#include "Polyhedron_type.h" - -#endif // USE_FORWARD_DECL - -#endif // POLYHEDRON_TYPE_FWD_H diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/Polyhedron_type.h cgal-4.5/demo/Surface_reconstruction_points_3/Polyhedron_type.h --- cgal-4.4/demo/Surface_reconstruction_points_3/Polyhedron_type.h 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/Polyhedron_type.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ -#ifndef POLYHEDRON_TYPE_H -#define POLYHEDRON_TYPE_H - -// (Main) CGAL kernel and simple geometric types -#include "Kernel_type.h" - -// surface mesh -#include - -#include "Polyhedron_type_fwd.h" - -typedef CGAL::Polyhedron_3 Polyhedron; - -#endif // POLYHEDRON_TYPE_H diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/PS_demo_average_spacing_plugin.cpp cgal-4.5/demo/Surface_reconstruction_points_3/PS_demo_average_spacing_plugin.cpp --- cgal-4.4/demo/Surface_reconstruction_points_3/PS_demo_average_spacing_plugin.cpp 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/PS_demo_average_spacing_plugin.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,107 +0,0 @@ -#include "config.h" -#include "Point_set_scene_item.h" -#include "Polyhedron_demo_plugin_helper.h" -#include "Polyhedron_demo_plugin_interface.h" - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -class PS_demo_average_spacing_plugin : - public QObject, - public Polyhedron_demo_plugin_helper -{ - Q_OBJECT - Q_INTERFACES(Polyhedron_demo_plugin_interface) - -private: - QAction* actionAverageSpacing; - -public: - void init(QMainWindow* mainWindow, Scene_interface* scene_interface) { - this->scene = scene_interface; - this->mw = mainWindow; - actionAverageSpacing = this->getActionFromMainWindow(mw, "actionAverageSpacing"); - if(actionAverageSpacing) { - connect(actionAverageSpacing, SIGNAL(triggered()), - this, SLOT(on_actionAverageSpacing_triggered())); - } - } - - QList actions() const { - return QList() << actionAverageSpacing; - } - -public slots: - void on_actionAverageSpacing_triggered(); - -}; // end PS_demo_average_spacing_plugin - -void PS_demo_average_spacing_plugin::on_actionAverageSpacing_triggered() -{ - const Scene_interface::Item_id index = scene->mainSelectionIndex(); - - Point_set_scene_item* item = - qobject_cast(scene->item(index)); - - if(item) - { - // Gets point set - Point_set* points = item->point_set(); - if(points == NULL) - return; - - // Gets options - bool ok; - const int nb_neighbors = - QInputDialog::getInteger((QWidget*)mw, - tr("Average Spacing"), // dialog title - tr("Number of neighbors:"), // field label - 6, // default value = 1 ring - 6, // min - 1000, // max - 1, // step - &ok); - if(!ok) - return; - - QApplication::setOverrideCursor(Qt::WaitCursor); - - CGAL::Timer task_timer; task_timer.start(); - std::cerr << "Average spacing (k=" << nb_neighbors <<")...\n"; - - // Computes average spacing - double average_spacing = CGAL::compute_average_spacing( - points->begin(), points->end(), - nb_neighbors); - - // Print result - Sphere bsphere = points->bounding_sphere(); - FT radius = std::sqrt(bsphere.squared_radius()); - long memory = CGAL::Memory_sizer().virtual_size(); - std::cerr << "Average spacing = " << average_spacing - << " = " << average_spacing/radius << " * point set radius (" - << task_timer.time() << " seconds, " - << (memory>>20) << " Mb allocated)" - << std::endl; - QApplication::restoreOverrideCursor(); - - QMessageBox::information(NULL, - tr("Average Spacing"), - tr("Average Spacing = %1 = %2 * point set radius") - .arg(average_spacing) - .arg(average_spacing/radius)); - } -} - -Q_EXPORT_PLUGIN2(PS_demo_average_spacing_plugin, PS_demo_average_spacing_plugin) - -#include "PS_demo_average_spacing_plugin.moc" diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/PS_demo_cleaning_plugin.cpp cgal-4.5/demo/Surface_reconstruction_points_3/PS_demo_cleaning_plugin.cpp --- cgal-4.4/demo/Surface_reconstruction_points_3/PS_demo_cleaning_plugin.cpp 2012-12-08 20:00:21.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/PS_demo_cleaning_plugin.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,124 +0,0 @@ -#include "config.h" -#include "Point_set_scene_item.h" -#include "Polyhedron_demo_plugin_helper.h" -#include "Polyhedron_demo_plugin_interface.h" - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "ui_PS_demo_cleaning_plugin.h" - -class PS_demo_cleaning_plugin : - public QObject, - public Polyhedron_demo_plugin_helper -{ - Q_OBJECT - Q_INTERFACES(Polyhedron_demo_plugin_interface) - -private: - QAction* actionOutlierRemoval; - -public: - void init(QMainWindow* mainWindow, Scene_interface* scene_interface) { - this->scene = scene_interface; - this->mw = mainWindow; - actionOutlierRemoval = this->getActionFromMainWindow(mw, "actionOutlierRemoval"); - if(actionOutlierRemoval) { - connect(actionOutlierRemoval, SIGNAL(triggered()), - this, SLOT(on_actionOutlierRemoval_triggered())); - } - } - - QList actions() const { - return QList() << actionOutlierRemoval; - } - -public slots: - void on_actionOutlierRemoval_triggered(); - -}; // end PS_demo_cleaning_plugin - -class Point_set_demo_outlier_removal_dialog : public QDialog, private Ui::OutlierRemovalDialog -{ - Q_OBJECT - public: - Point_set_demo_outlier_removal_dialog(QWidget * /*parent*/ = 0) - { - setupUi(this); - } - - double percentage() const { return m_inputPercentage->value(); } - int nbNeighbors() const { return m_inputNbNeighbors->value(); } -}; - -void PS_demo_cleaning_plugin::on_actionOutlierRemoval_triggered() -{ - const Scene_interface::Item_id index = scene->mainSelectionIndex(); - - Point_set_scene_item* item = - qobject_cast(scene->item(index)); - - if(item) - { - // Gets point set - Point_set* points = item->point_set(); - if(points == NULL) - return; - - // Gets options - Point_set_demo_outlier_removal_dialog dialog; - if(!dialog.exec()) - return; - const double removed_percentage = dialog.percentage(); // percentage of points to remove - const int nb_neighbors = dialog.nbNeighbors(); - - QApplication::setOverrideCursor(Qt::WaitCursor); - - CGAL::Timer task_timer; task_timer.start(); - std::cerr << "Remove outliers (" << removed_percentage <<"%)...\n"; - - // Computes outliers - Point_set::iterator first_point_to_remove = - CGAL::remove_outliers(points->begin(), points->end(), - nb_neighbors, - removed_percentage); - - int nb_points_to_remove = std::distance(first_point_to_remove, points->end()); - long memory = CGAL::Memory_sizer().virtual_size(); - std::cerr << "Simplification: " << nb_points_to_remove << " point(s) are selected for removal (" - << task_timer.time() << " seconds, " - << (memory>>20) << " Mb allocated)" - << std::endl; - - // Selects points to delete - points->select(points->begin(), points->end(), false); - points->select(first_point_to_remove, points->end(), true); - - // Updates scene - scene->itemChanged(index); - - QApplication::restoreOverrideCursor(); - - // Warns user - if (nb_points_to_remove > 0) - { - QMessageBox::information(NULL, - tr("Points selected from removal"), - tr("%1 point(s) are selected for removal.\nYou may remove them with the \"Delete selection\" menu item.") - .arg(nb_points_to_remove)); - } - } -} - -Q_EXPORT_PLUGIN2(PS_demo_cleaning_plugin, PS_demo_cleaning_plugin) - -#include "PS_demo_cleaning_plugin.moc" diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/PS_demo_cleaning_plugin.ui cgal-4.5/demo/Surface_reconstruction_points_3/PS_demo_cleaning_plugin.ui --- cgal-4.4/demo/Surface_reconstruction_points_3/PS_demo_cleaning_plugin.ui 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/PS_demo_cleaning_plugin.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,109 +0,0 @@ - - OutlierRemovalDialog - - - - 0 - 0 - 331 - 120 - - - - Outlier Removal - - - - - - Removed percentage: - - - - - - - % - - - 0.010000000000000 - - - 100.000000000000000 - - - 0.100000000000000 - - - 5.000000000000000 - - - - - - - Neighbors - - - - - - - 6 - - - 9999 - - - 24 - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok - - - - - - - - - buttonBox - accepted() - OutlierRemovalDialog - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - OutlierRemovalDialog - reject() - - - 316 - 260 - - - 286 - 274 - - - - - diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/PS_demo_inside_out_plugin.cpp cgal-4.5/demo/Surface_reconstruction_points_3/PS_demo_inside_out_plugin.cpp --- cgal-4.4/demo/Surface_reconstruction_points_3/PS_demo_inside_out_plugin.cpp 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/PS_demo_inside_out_plugin.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,55 +0,0 @@ -#include -#include -#include - -#include "Scene_polyhedron_item.h" -#include "Polyhedron_type.h" - -#include "Polyhedron_demo_plugin_helper.h" -#include "Polyhedron_demo_plugin_interface.h" - -class PS_demo_inside_out_plugin : - public QObject, - public Polyhedron_demo_plugin_helper -{ - Q_OBJECT - Q_INTERFACES(Polyhedron_demo_plugin_interface) - -public: - // used by Polyhedron_demo_plugin_helper - QStringList actionsNames() const { - return QStringList() << "actionInsideOut"; - } -public slots: - void on_actionInsideOut_triggered(); - -}; // end PS_demo_inside_out_plugin - -void PS_demo_inside_out_plugin::on_actionInsideOut_triggered() -{ - const Scene_interface::Item_id index = scene->mainSelectionIndex(); - - Scene_polyhedron_item* poly_item = - qobject_cast(scene->item(index)); - - if(poly_item) - { - QApplication::setOverrideCursor(Qt::WaitCursor); - - Polyhedron* pMesh = poly_item->polyhedron(); - if(!pMesh) return; - - // inside out - pMesh->inside_out(); - - // update scene - scene->itemChanged(index); - - // default cursor - QApplication::restoreOverrideCursor(); - } -} - -Q_EXPORT_PLUGIN2(PS_demo_inside_out_plugin, PS_demo_inside_out_plugin) - -#include "PS_demo_inside_out_plugin.moc" diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/PS_demo_local_spacing_plugin.cpp cgal-4.5/demo/Surface_reconstruction_points_3/PS_demo_local_spacing_plugin.cpp --- cgal-4.4/demo/Surface_reconstruction_points_3/PS_demo_local_spacing_plugin.cpp 2012-12-08 20:00:21.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/PS_demo_local_spacing_plugin.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,78 +0,0 @@ -#include "config.h" -#include "Point_set_scene_item.h" -#include "Polyhedron_demo_plugin_helper.h" -#include "Polyhedron_demo_plugin_interface.h" - -#include -#include -#include -#include -#include -#include - -class PS_demo_local_spacing_plugin : - public QObject, - protected Polyhedron_demo_plugin_helper -{ - Q_OBJECT - Q_INTERFACES(Polyhedron_demo_plugin_interface) - -public: - void init(QMainWindow* mainWindow, Scene_interface* scene_interface) { - this->scene = scene_interface; - this->mw = mainWindow; - actionRadiusFromDensity = this->getActionFromMainWindow(mw, "actionRadiusFromDensity"); - if(actionRadiusFromDensity) { - connect(actionRadiusFromDensity, SIGNAL(triggered()), - this, SLOT(on_actionRadiusFromDensity_triggered())); - } - } - - QList actions() const { - return QList() << actionRadiusFromDensity; - } - -public slots: - void on_actionRadiusFromDensity_triggered(); - -private: - QAction* actionRadiusFromDensity; -}; // end PS_demo_local_spacing_plugin - -void PS_demo_local_spacing_plugin::on_actionRadiusFromDensity_triggered() -{ - const Scene_interface::Item_id index = scene->mainSelectionIndex(); - - Point_set_scene_item* item = - qobject_cast(scene->item(index)); - - if(item) - { - // Check there is a point set - if(item->point_set() == NULL) - return; - - // Gets options - bool ok; - const int k = - QInputDialog::getInteger((QWidget*)mw, - tr("Local spacing"), // dialog title - tr("Number of neighbors:"), // field label - 6, // default value = small - 1, // min - 1000, // max - 1, // step - &ok); - if(!ok) return; - - QApplication::setOverrideCursor(Qt::WaitCursor); - - item->computes_local_spacing(k); - - QApplication::restoreOverrideCursor(); - } -} - -Q_EXPORT_PLUGIN2(PS_demo_local_spacing_plugin, PS_demo_local_spacing_plugin) - -#include "PS_demo_local_spacing_plugin.moc" diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/PS_demo_normal_estimation_plugin.cpp cgal-4.5/demo/Surface_reconstruction_points_3/PS_demo_normal_estimation_plugin.cpp --- cgal-4.4/demo/Surface_reconstruction_points_3/PS_demo_normal_estimation_plugin.cpp 2013-06-15 19:00:26.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/PS_demo_normal_estimation_plugin.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,215 +0,0 @@ -#include "config.h" -#include "Point_set_scene_item.h" -#include "Polyhedron_demo_plugin_helper.h" -#include "Polyhedron_demo_plugin_interface.h" - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "ui_PS_demo_normal_estimation_plugin.h" - -class PS_demo_normal_estimation_plugin : - public QObject, - public Polyhedron_demo_plugin_helper -{ - Q_OBJECT - Q_INTERFACES(Polyhedron_demo_plugin_interface) - QAction* actionNormalEstimation; - QAction* actionNormalInversion; - -public: - void init(QMainWindow* mainWindow, Scene_interface* scene_interface) { - this->scene = scene_interface; - this->mw = mainWindow; - actionNormalEstimation = this->getActionFromMainWindow(mw, "actionNormalEstimation"); - if(actionNormalEstimation) { - connect(actionNormalEstimation, SIGNAL(triggered()), - this, SLOT(on_actionNormalEstimation_triggered())); - } - - actionNormalInversion = this->getActionFromMainWindow(mw, "actionNormalInversion"); - if(actionNormalInversion) { - connect(actionNormalInversion, SIGNAL(triggered()), - this, SLOT(on_actionNormalInversion_triggered())); - } - } - - QList actions() const { - return QList() << actionNormalEstimation << actionNormalInversion; - } - -public slots: - void on_actionNormalEstimation_triggered(); - void on_actionNormalInversion_triggered(); - -}; // end PS_demo_smoothing_plugin - -class Point_set_demo_normal_estimation_dialog : public QDialog, private Ui::NormalEstimationDialog -{ - Q_OBJECT - public: - Point_set_demo_normal_estimation_dialog(QWidget* = 0) - { - setupUi(this); - } - - QString directionMethod() const { return m_inputDirection->currentText(); } - int directionNbNeighbors() const { return m_inputNbNeighborsDirection->value(); } - - QString orientationMethod() const { return m_inputOrientation->currentText(); } - int orientationNbNeighbors() const { return m_inputNbNeighborsOrientation->value(); } -}; - - -void PS_demo_normal_estimation_plugin::on_actionNormalInversion_triggered() -{ - const Scene_interface::Item_id index = scene->mainSelectionIndex(); - - Point_set_scene_item* item = - qobject_cast(scene->item(index)); - - if(item) - { - // Gets point set - Point_set* points = item->point_set(); - if(points == NULL) - return; - - for(Point_set::iterator it = points->begin(); it != points->end(); ++it){ - it->normal() = -1 * it->normal(); - } - } -} - -void PS_demo_normal_estimation_plugin::on_actionNormalEstimation_triggered() -{ - const Scene_interface::Item_id index = scene->mainSelectionIndex(); - - Point_set_scene_item* item = - qobject_cast(scene->item(index)); - - if(item) - { - // Gets point set - Point_set* points = item->point_set(); - if(points == NULL) - return; - - // Gets options - Point_set_demo_normal_estimation_dialog dialog; - if(!dialog.exec()) - return; - - QApplication::setOverrideCursor(Qt::WaitCursor); - - // First point to delete - Point_set::iterator first_unoriented_point = points->end(); - - //*************************************** - // normal estimation - //*************************************** - - if (dialog.directionMethod() == "plane") - { - CGAL::Timer task_timer; task_timer.start(); - std::cerr << "Estimates normal direction by PCA (k=" << dialog.directionNbNeighbors() <<")...\n"; - - // Estimates normals direction. - CGAL::pca_estimate_normals(points->begin(), points->end(), -#ifdef CGAL_USE_PROPERTY_MAPS_API_V1 - CGAL::make_normal_of_point_with_normal_pmap(points->begin()), -#else - CGAL::make_normal_of_point_with_normal_pmap(Point_set::value_type()), -#endif - - dialog.directionNbNeighbors()); - - // Mark all normals as unoriented - first_unoriented_point = points->begin(); - - long memory = CGAL::Memory_sizer().virtual_size(); - std::cerr << "Estimates normal direction: " << task_timer.time() << " seconds, " - << (memory>>20) << " Mb allocated" - << std::endl; - } - else if (dialog.directionMethod() == "quadric") - { - CGAL::Timer task_timer; task_timer.start(); - std::cerr << "Estimates normal direction by Jet Fitting (k=" << dialog.directionNbNeighbors() <<")...\n"; - - // Estimates normals direction. - CGAL::jet_estimate_normals(points->begin(), points->end(), -#ifdef CGAL_USE_PROPERTY_MAPS_API_V1 - CGAL::make_normal_of_point_with_normal_pmap(points->begin()), -#else - CGAL::make_normal_of_point_with_normal_pmap(Point_set::value_type()), -#endif - dialog.directionNbNeighbors()); - - // Mark all normals as unoriented - first_unoriented_point = points->begin(); - - long memory = CGAL::Memory_sizer().virtual_size(); - std::cerr << "Estimates normal direction: " << task_timer.time() << " seconds, " - << (memory>>20) << " Mb allocated" - << std::endl; - } - - //*************************************** - // normal orientation - //*************************************** - - CGAL::Timer task_timer; task_timer.start(); - std::cerr << "Orient normals with a Minimum Spanning Tree (k=" << dialog.orientationNbNeighbors() << ")...\n"; - - // Tries to orient normals - first_unoriented_point = - CGAL::mst_orient_normals(points->begin(), points->end(), -#ifdef CGAL_USE_PROPERTY_MAPS_API_V1 - CGAL::make_normal_of_point_with_normal_pmap(points->begin()), -#else - CGAL::make_normal_of_point_with_normal_pmap(Point_set::value_type()), -#endif - dialog.orientationNbNeighbors()); - - int nb_unoriented_normals = std::distance(first_unoriented_point, points->end()); - long memory = CGAL::Memory_sizer().virtual_size(); - std::cerr << "Orient normals: " << nb_unoriented_normals << " point(s) with an unoriented normal are selected (" - << task_timer.time() << " seconds, " - << (memory>>20) << " Mb allocated)" - << std::endl; - - // Selects points with an unoriented normal - points->select(points->begin(), points->end(), false); - points->select(first_unoriented_point, points->end(), true); - - // Updates scene - scene->itemChanged(index); - - QApplication::restoreOverrideCursor(); - - // Warns user - if (nb_unoriented_normals > 0) - { - QMessageBox::information(NULL, - tr("Points with an unoriented normal"), - tr("%1 point(s) with an unoriented normal are selected.\nPlease orient them or remove them before running Poisson reconstruction.") - .arg(nb_unoriented_normals)); - } - } -} - -Q_EXPORT_PLUGIN2(PS_demo_normal_estimation_plugin, PS_demo_normal_estimation_plugin) - -#include "PS_demo_normal_estimation_plugin.moc" diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/PS_demo_normal_estimation_plugin.ui cgal-4.5/demo/Surface_reconstruction_points_3/PS_demo_normal_estimation_plugin.ui --- cgal-4.4/demo/Surface_reconstruction_points_3/PS_demo_normal_estimation_plugin.ui 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/PS_demo_normal_estimation_plugin.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,132 +0,0 @@ - - NormalEstimationDialog - - - - 0 - 0 - 311 - 120 - - - - Normal estimation - - - - - - Direction: - - - - - - - - quadric - - - - - plane - - - - - - - - neighbors - - - 6 - - - 9999 - - - 18 - - - - - - - Orientation: - - - - - - - - MST - - - - - - - - neighbors - - - 6 - - - 9999 - - - 18 - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok - - - - - - - - - buttonBox - accepted() - NormalEstimationDialog - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - NormalEstimationDialog - reject() - - - 316 - 260 - - - 286 - 274 - - - - - diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/PS_demo_off_plugin.cpp cgal-4.5/demo/Surface_reconstruction_points_3/PS_demo_off_plugin.cpp --- cgal-4.4/demo/Surface_reconstruction_points_3/PS_demo_off_plugin.cpp 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/PS_demo_off_plugin.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,100 +0,0 @@ -#include "Point_set_scene_item.h" -#include "Scene_polyhedron_item.h" -#include "Polyhedron_type.h" - -#include "Polyhedron_demo_io_plugin_interface.h" -#include - -class PS_demo_off_plugin : - public QObject, - public Polyhedron_demo_io_plugin_interface -{ - Q_OBJECT - Q_INTERFACES(Polyhedron_demo_io_plugin_interface) - -public: - QStringList nameFilters() const; - bool canLoad() const; - Scene_item* load(QFileInfo fileinfo); - - bool canSave(const Scene_item*); - bool save(const Scene_item*, QFileInfo fileinfo); -}; - -QStringList PS_demo_off_plugin::nameFilters() const { - return QStringList() << "OFF files (*.off)"; -} - -bool PS_demo_off_plugin::canLoad() const { - return true; -} - - -Scene_item* -PS_demo_off_plugin::load(QFileInfo fileinfo) { - - // Check extension (quietly) - std::string extension = fileinfo.suffix().toUtf8().data(); - if (extension != "off" && extension != "OFF") - return NULL; - - // Open file - std::ifstream in(fileinfo.filePath().toUtf8().data()); - if(!in) { - std::cerr << "Error! Cannot open file " << fileinfo.filePath().toStdString() << std::endl; - return NULL; - } - - // Try to read .off in a polyhedron - Scene_polyhedron_item* item = new Scene_polyhedron_item(); - item->setName(fileinfo.completeBaseName()); - if(!item->load(in)) - { - delete item; - - // Try to read .off in a point set - Point_set_scene_item* point_set_item = new Point_set_scene_item; - point_set_item->setName(fileinfo.completeBaseName()); - in.close(); - std::ifstream in2(fileinfo.filePath().toUtf8().data()); - if(!point_set_item->read_off_point_set(in2)) { - delete point_set_item; - return 0; - } - return point_set_item; - } - - return item; -} - -bool PS_demo_off_plugin::canSave(const Scene_item* item) -{ - // This plugin supports polyhedrons and point sets - return qobject_cast(item) || - qobject_cast(item); -} - -bool PS_demo_off_plugin::save(const Scene_item* item, QFileInfo fileinfo) -{ - // Check extension (quietly) - std::string extension = fileinfo.suffix().toUtf8().data(); - if (extension != "off" && extension != "OFF") - return false; - - // This plugin supports polyhedrons and point sets - const Scene_polyhedron_item* poly_item = - qobject_cast(item); - const Point_set_scene_item* point_set_item = - qobject_cast(item); - if(!poly_item && !point_set_item) - return false; - - // Save polyhedron/point set as .off - std::ofstream out(fileinfo.filePath().toUtf8().data()); - return (poly_item && poly_item->save(out)) || - (point_set_item && point_set_item->write_off_point_set(out)); -} - -#include -Q_EXPORT_PLUGIN2(PS_demo_off_plugin, PS_demo_off_plugin) -#include "PS_demo_off_plugin.moc" diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/PS_demo_poisson_plugin_cgal_code.cpp cgal-4.5/demo/Surface_reconstruction_points_3/PS_demo_poisson_plugin_cgal_code.cpp --- cgal-4.4/demo/Surface_reconstruction_points_3/PS_demo_poisson_plugin_cgal_code.cpp 2013-07-27 19:00:34.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/PS_demo_poisson_plugin_cgal_code.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,248 +0,0 @@ -//---------------------------------------------------------- -// Poisson reconstruction method: -// Reconstructs a surface mesh from a point set and returns it as a polyhedron. -//---------------------------------------------------------- - - - -// CGAL -#include // must be included before kernel -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef CGAL_TAUCS_ENABLED -#include -#endif -#ifdef CGAL_EIGEN3_ENABLED -#include -#endif - -#include - -#include "Kernel_type.h" -#include "Polyhedron_type.h" -#include "Point_set_scene_item.h" - - -// Poisson implicit function -typedef CGAL::Poisson_reconstruction_function Poisson_reconstruction_function; - -// Surface mesher -typedef CGAL::Surface_mesh_default_triangulation_3 STr; -typedef CGAL::Surface_mesh_complex_2_in_triangulation_3 C2t3; -typedef CGAL::Poisson_implicit_surface_3 Surface_3; - -// AABB tree -typedef CGAL::AABB_face_graph_triangle_primitive Primitive; -typedef CGAL::AABB_traits AABB_traits; -typedef CGAL::AABB_tree AABB_tree; - - -// Poisson reconstruction method: -// Reconstructs a surface mesh from a point set and returns it as a polyhedron. -Polyhedron* poisson_reconstruct(const Point_set& points, - FT sm_angle, // Min triangle angle (degrees). - FT sm_radius, // Max triangle size w.r.t. point set average spacing. - FT sm_distance, // Approximation error w.r.t. point set average spacing. - const QString& solver_name) // solver name -{ - CGAL::Timer task_timer; task_timer.start(); - - //*************************************** - // Checks requirements - //*************************************** - - int nb_points = points.size(); - if (nb_points == 0) - { - std::cerr << "Error: empty point set" << std::endl; - return NULL; - } - - bool points_have_normals = (points.begin()->normal() != CGAL::NULL_VECTOR); - if ( ! points_have_normals ) - { - std::cerr << "Input point set not supported: this reconstruction method requires oriented normals" << std::endl; - return NULL; - } - - - CGAL::Timer reconstruction_timer; reconstruction_timer.start(); - - //*************************************** - // Computes implicit function - //*************************************** - - std::cerr << "Computes Poisson implicit function " - << "using " << solver_name.toAscii().data() << " solver...\n"; - - - // Creates implicit function from the point set. - // Note: this method requires an iterator over points - // + property maps to access each point's position and normal. - // The position property map can be omitted here as we use iterators over Point_3 elements. - Poisson_reconstruction_function function( - points.begin(), points.end(), -#ifdef CGAL_USE_PROPERTY_MAPS_API_V1 - CGAL::make_normal_of_point_with_normal_pmap(points.begin()) -#else - CGAL::make_normal_of_point_with_normal_pmap(Point_set::value_type()) -#endif - ); - - bool ok = false; - #ifdef CGAL_TAUCS_ENABLED - if(solver_name=="Taucs") - { - // Creates sparse linear solver: - // TAUCS out-of-core Multifrontal Supernodal Cholesky Factorization - const char* OOC_SUPERNODAL_CHOLESKY_FACTORIZATION[] = - { - "taucs.factor.LLT=true", - "taucs.factor.mf=true", - "taucs.factor.ordering=metis", - "taucs.ooc=true", "taucs.ooc.basename=taucs-ooc", - NULL - }; - unlink("taucs-ooc.0"); // make sure TAUCS ooc file does not exist - CGAL::Taucs_symmetric_solver_traits solver(OOC_SUPERNODAL_CHOLESKY_FACTORIZATION); - - ok = function.compute_implicit_function(solver); - } - #endif - - #ifdef CGAL_EIGEN3_ENABLED - if(solver_name=="Eigen - built-in simplicial LDLt") - { - CGAL::Eigen_solver_traits::EigenType> > solver; - ok = function.compute_implicit_function(solver); - } - if(solver_name=="Eigen - built-in CG") - { - CGAL::Eigen_solver_traits::EigenType> > solver; - solver.solver().setTolerance(1e-6); - solver.solver().setMaxIterations(1000); - ok = function.compute_implicit_function(solver); - } - #endif - - // Computes the Poisson indicator function f() - // at each vertex of the triangulation. - - if ( ! ok ) - { - std::cerr << "Error: cannot compute implicit function" << std::endl; - return NULL; - } - - // Prints status - std::cerr << "Total implicit function (triangulation+refinement+solver): " << task_timer.time() << " seconds\n"; - task_timer.reset(); - - //*************************************** - // Surface mesh generation - //*************************************** - - std::cerr << "Surface meshing...\n"; - - // Computes average spacing - FT average_spacing = CGAL::compute_average_spacing(points.begin(), points.end(), - 6 /* knn = 1 ring */); - - - // Gets one point inside the implicit surface - Point inner_point = function.get_inner_point(); - FT inner_point_value = function(inner_point); - if(inner_point_value >= 0.0) - { - std::cerr << "Error: unable to seed (" << inner_point_value << " at inner_point)" << std::endl; - return NULL; - } - - // Gets implicit function's radius - Sphere bsphere = function.bounding_sphere(); - FT radius = std::sqrt(bsphere.squared_radius()); - - // Defines the implicit surface: requires defining a - // conservative bounding sphere centered at inner point. - FT sm_sphere_radius = 5.0 * radius; - FT sm_dichotomy_error = sm_distance*average_spacing/1000.0; // Dichotomy error must be << sm_distance - Surface_3 surface(function, - Sphere(inner_point,sm_sphere_radius*sm_sphere_radius), - sm_dichotomy_error/sm_sphere_radius); - - // Defines surface mesh generation criteria - CGAL::Surface_mesh_default_criteria_3 criteria(sm_angle, // Min triangle angle (degrees) - sm_radius*average_spacing, // Max triangle size - sm_distance*average_spacing); // Approximation error - - CGAL_TRACE_STREAM << " make_surface_mesh(sphere center=("<facets_begin(), output_mesh->facets_end(), *output_mesh); - tree.accelerate_distance_queries(); - - // Computes distance from each input point to reconstructed mesh - double max_distance = DBL_MIN; - double avg_distance = 0; - for (Point_set::const_iterator p=points.begin(); p!=points.end(); p++) - { - double distance = std::sqrt(tree.squared_distance(*p)); - - max_distance = (std::max)(max_distance, distance); - avg_distance += distance; - } - avg_distance /= double(points.size()); - - std::cerr << "Reconstruction error:\n" - << " max = " << max_distance << " = " << max_distance/average_spacing << " * average spacing\n" - << " avg = " << avg_distance << " = " << avg_distance/average_spacing << " * average spacing\n"; - - return output_mesh; -} - diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/PS_demo_poisson_plugin.cpp cgal-4.5/demo/Surface_reconstruction_points_3/PS_demo_poisson_plugin.cpp --- cgal-4.4/demo/Surface_reconstruction_points_3/PS_demo_poisson_plugin.cpp 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/PS_demo_poisson_plugin.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,128 +0,0 @@ -#include "config.h" -#include "Point_set_scene_item.h" -#include "Polyhedron_demo_plugin_helper.h" -#include "Polyhedron_demo_plugin_interface.h" -#include "Scene_polyhedron_item.h" - -#include -#include -#include -#include -#include -#include - -#include "ui_PS_demo_poisson_plugin.h" - -// Poisson reconstruction method: -// Reconstructs a surface mesh from a point set and returns it as a polyhedron. -Polyhedron* poisson_reconstruct(const Point_set& points, - FT sm_angle, // Min triangle angle (degrees). - FT sm_radius, // Max triangle size w.r.t. point set average spacing. - FT sm_distance, // Approximation error w.r.t. point set average spacing. - const QString& solver); // solver name - -class PS_demo_poisson_plugin : - public QObject, - protected Polyhedron_demo_plugin_helper -{ - Q_OBJECT - Q_INTERFACES(Polyhedron_demo_plugin_interface) - -public: - void init(QMainWindow* mainWindow, Scene_interface* scene_interface) { - this->scene = scene_interface; - this->mw = mainWindow; - actionPoissonReconstruction = this->getActionFromMainWindow(mw, "actionPoissonReconstruction"); - if(actionPoissonReconstruction) { - connect(actionPoissonReconstruction, SIGNAL(triggered()), - this, SLOT(reconstruct())); - } - } - - QList actions() const { - return QList() << actionPoissonReconstruction; - } - -public slots: - void reconstruct(); - -private: - QAction* actionPoissonReconstruction; - -}; // end class PS_demo_poisson_plugin - - -class PS_demo_poisson_plugin_dialog : public QDialog, private Ui::PoissonDialog -{ - Q_OBJECT - public: - PS_demo_poisson_plugin_dialog(QWidget* /*parent*/ = 0) - { - setupUi(this); - - #ifdef CGAL_TAUCS_ENABLED - m_inputSolver->addItem("Taucs"); - #endif - - #ifdef CGAL_EIGEN3_ENABLED - m_inputSolver->addItem("Eigen - built-in simplicial LDLt"); - m_inputSolver->addItem("Eigen - built-in CG"); - #endif - } - - double triangleAngle() const { return m_inputAngle->value(); } - double triangleRadius() const { return m_inputRadius->value(); } - double triangleError() const { return m_inputDistance->value(); } - QString solver() const { return m_inputSolver->currentText(); } -}; - -void PS_demo_poisson_plugin::reconstruct() -{ - const Scene_interface::Item_id index = scene->mainSelectionIndex(); - - Point_set_scene_item* point_set_item = - qobject_cast(scene->item(index)); - - if(point_set_item) - { - // Gets point set - Point_set* points = point_set_item->point_set(); - if(!points) return; - - // Gets options - PS_demo_poisson_plugin_dialog dialog; - if(!dialog.exec()) - return; - const double sm_angle = dialog.triangleAngle(); - const double sm_radius = dialog.triangleRadius(); - const double sm_distance = dialog.triangleError(); - const QString sm_solver = dialog.solver(); - - QApplication::setOverrideCursor(Qt::WaitCursor); - - // Reconstruct point set as a polyhedron - Polyhedron* pRemesh = poisson_reconstruct(*points, sm_angle, sm_radius, sm_distance, sm_solver); - if(pRemesh) - { - // Add polyhedron to scene - Scene_polyhedron_item* new_item = new Scene_polyhedron_item(pRemesh); - new_item->setName(tr("%1 Poisson (%2 %3 %4)") - .arg(point_set_item->name()) - .arg(sm_angle) - .arg(sm_radius) - .arg(sm_distance)); - new_item->setColor(Qt::lightGray); - scene->addItem(new_item); - - // Hide point set - point_set_item->setVisible(false); - scene->itemChanged(index); - } - - QApplication::restoreOverrideCursor(); - } -} - -Q_EXPORT_PLUGIN2(PS_demo_poisson_plugin, PS_demo_poisson_plugin) - -#include "PS_demo_poisson_plugin.moc" diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/PS_demo_poisson_plugin.ui cgal-4.5/demo/Surface_reconstruction_points_3/PS_demo_poisson_plugin.ui --- cgal-4.4/demo/Surface_reconstruction_points_3/PS_demo_poisson_plugin.ui 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/PS_demo_poisson_plugin.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,156 +0,0 @@ - - - PoissonDialog - - - - 0 - 0 - 376 - 170 - - - - Poisson reconstruction - - - - - - Min triangle angle: - - - - - - - ° - - - 1.000000000000000 - - - 30.000000000000000 - - - 20.000000000000000 - - - - - - - Max triangle size: - - - - - - - * average spacing - - - 0 - - - 1.000000000000000 - - - 1000.000000000000000 - - - 1.000000000000000 - - - 100.000000000000000 - - - - - - - Approximation error: - - - - - - - * average spacing - - - 6 - - - 0.010000000000000 - - - 100.000000000000000 - - - 0.010000000000000 - - - 0.250000000000000 - - - - - - - Solver: - - - - - - - - - - - - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - - buttonBox - accepted() - PoissonDialog - accept() - - - 177 - 123 - - - 53 - 125 - - - - - buttonBox - rejected() - PoissonDialog - reject() - - - 257 - 119 - - - 257 - 143 - - - - - diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/PS_demo_simplification_plugin.cpp cgal-4.5/demo/Surface_reconstruction_points_3/PS_demo_simplification_plugin.cpp --- cgal-4.4/demo/Surface_reconstruction_points_3/PS_demo_simplification_plugin.cpp 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/PS_demo_simplification_plugin.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,142 +0,0 @@ -#include "config.h" -#include "Point_set_scene_item.h" -#include "Polyhedron_demo_plugin_helper.h" -#include "Polyhedron_demo_plugin_interface.h" - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "ui_PS_demo_simplification_plugin.h" - -class PS_demo_simplification_plugin : - public QObject, - public Polyhedron_demo_plugin_helper -{ - Q_OBJECT - Q_INTERFACES(Polyhedron_demo_plugin_interface) - QAction* actionSimplify; - -public: - void init(QMainWindow* mainWindow, Scene_interface* scene_interface) { - this->scene = scene_interface; - this->mw = mainWindow; - actionSimplify = this->getActionFromMainWindow(mw, "actionSimplify"); - if(actionSimplify) { - connect(actionSimplify, SIGNAL(triggered()), - this, SLOT(on_actionSimplify_triggered())); - } - } - - QList actions() const { - return QList() << actionSimplify; - } - -public slots: - void on_actionSimplify_triggered(); - -}; // end PS_demo_simplification_plugin - -class Point_set_demo_point_set_simplification_dialog : public QDialog, private Ui::PointSetSimplificationDialog -{ - Q_OBJECT - public: - Point_set_demo_point_set_simplification_dialog(QWidget * /*parent*/ = 0) - { - setupUi(this); - } - - QString simplificationMethod() const { return m_simplificationMethod->currentText(); } - float randomSimplificationPercentage() const { return m_randomSimplificationPercentage->value(); } - float gridCellSize() const { return m_gridCellSize->value(); } -}; - -void PS_demo_simplification_plugin::on_actionSimplify_triggered() -{ - const Scene_interface::Item_id index = scene->mainSelectionIndex(); - - Point_set_scene_item* item = - qobject_cast(scene->item(index)); - - if(item) - { - // Gets point set - Point_set* points = item->point_set(); - if(points == NULL) - return; - - // Gets options - Point_set_demo_point_set_simplification_dialog dialog; - if(!dialog.exec()) - return; - - QApplication::setOverrideCursor(Qt::WaitCursor); - - CGAL::Timer task_timer; task_timer.start(); - - // First point to delete - Point_set::iterator first_point_to_remove = points->end(); - - if (dialog.simplificationMethod() == "Random") - { - std::cerr << "Random point cloud simplification (" << dialog.randomSimplificationPercentage() <<"%)...\n"; - - // Computes points to remove by random simplification - first_point_to_remove = - CGAL::random_simplify_point_set(points->begin(), points->end(), - dialog.randomSimplificationPercentage()); - } - else if (dialog.simplificationMethod() == "Grid Clustering") - { - std::cerr << "Point cloud simplification by clustering (cell size = " << dialog.gridCellSize() <<" * average spacing)...\n"; - - // Computes average spacing - double average_spacing = CGAL::compute_average_spacing( - points->begin(), points->end(), - 6 /* knn = 1 ring */); - - // Computes points to remove by Grid Clustering - first_point_to_remove = - CGAL::grid_simplify_point_set(points->begin(), points->end(), - dialog.gridCellSize()*average_spacing); - } - - int nb_points_to_remove = std::distance(first_point_to_remove, points->end()); - long memory = CGAL::Memory_sizer().virtual_size(); - std::cerr << "Simplification: " << nb_points_to_remove << " point(s) are selected for removal (" - << task_timer.time() << " seconds, " - << (memory>>20) << " Mb allocated)" - << std::endl; - - // Selects points to delete - points->select(points->begin(), points->end(), false); - points->select(first_point_to_remove, points->end(), true); - - // Updates scene - scene->itemChanged(index); - - QApplication::restoreOverrideCursor(); - - // Warns user - if (nb_points_to_remove > 0) - { - QMessageBox::information(NULL, - tr("Points selected from removal"), - tr("%1 point(s) are selected for removal.\nYou may remove them with the \"Delete selection\" menu item.") - .arg(nb_points_to_remove)); - } - } -} - -Q_EXPORT_PLUGIN2(PS_demo_simplification_plugin, PS_demo_simplification_plugin) - -#include "PS_demo_simplification_plugin.moc" diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/PS_demo_simplification_plugin.ui cgal-4.5/demo/Surface_reconstruction_points_3/PS_demo_simplification_plugin.ui --- cgal-4.4/demo/Surface_reconstruction_points_3/PS_demo_simplification_plugin.ui 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/PS_demo_simplification_plugin.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,142 +0,0 @@ - - PointSetSimplificationDialog - - - - 0 - 0 - 403 - 153 - - - - Simplification - - - - - - Method: - - - - - - - - Random - - - - - Grid Clustering - - - - - - - - Points to Remove Randomly - - - - - - - % - - - 2 - - - 0.100000000000000 - - - 100.000000000000000 - - - 0.100000000000000 - - - 50.000000000000000 - - - - - - - Grid Cell Size - - - - - - - * average spacing - - - 2 - - - 0.100000000000000 - - - 10.000000000000000 - - - 0.100000000000000 - - - 1.000000000000000 - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok - - - - - - - - - buttonBox - accepted() - PointSetSimplificationDialog - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - PointSetSimplificationDialog - reject() - - - 316 - 260 - - - 286 - 274 - - - - - diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/PS_demo_smoothing_plugin.cpp cgal-4.5/demo/Surface_reconstruction_points_3/PS_demo_smoothing_plugin.cpp --- cgal-4.4/demo/Surface_reconstruction_points_3/PS_demo_smoothing_plugin.cpp 2012-12-08 20:00:21.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/PS_demo_smoothing_plugin.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,83 +0,0 @@ -#include "config.h" -#include "Point_set_scene_item.h" -#include "Polyhedron_demo_plugin_helper.h" -#include "Polyhedron_demo_plugin_interface.h" - -#include -#include -#include -#include -#include -#include - -#include - -class PS_demo_smoothing_plugin : - public QObject, - public Polyhedron_demo_plugin_helper -{ - Q_OBJECT - Q_INTERFACES(Polyhedron_demo_plugin_interface) - QAction* actionJetSmoothing; - -public: - void init(QMainWindow* mainWindow, Scene_interface* scene_interface) { - this->scene = scene_interface; - this->mw = mainWindow; - actionJetSmoothing = this->getActionFromMainWindow(mw, "actionJetSmoothing"); - if(actionJetSmoothing) { - connect(actionJetSmoothing, SIGNAL(triggered()), - this, SLOT(on_actionJetSmoothing_triggered())); - } - } - - QList actions() const { - return QList() << actionJetSmoothing; - } - -public slots: - void on_actionJetSmoothing_triggered(); - -}; // end PS_demo_smoothing_plugin - -void PS_demo_smoothing_plugin::on_actionJetSmoothing_triggered() -{ - const Scene_interface::Item_id index = scene->mainSelectionIndex(); - - Point_set_scene_item* item = - qobject_cast(scene->item(index)); - - if(item) - { - Point_set* points = item->point_set(); - if(!points) return; - - // Gets options - bool ok; - const unsigned int nb_neighbors = - QInputDialog::getInteger((QWidget*)mw, - tr("Jet Smoothing"), // dialog title - tr("Number of neighbors:"), // field label - 24, // default value = fast - 6, // min - 1000, // max - 1, // step - &ok); - if(!ok) return; - - QApplication::setOverrideCursor(Qt::WaitCursor); - - CGAL::jet_smooth_point_set(points->begin(), points->end(), nb_neighbors); - - points->invalidate_bounds(); - - // update scene - scene->itemChanged(index); - - QApplication::restoreOverrideCursor(); - } -} - -Q_EXPORT_PLUGIN2(PS_demo_smoothing_plugin, PS_demo_smoothing_plugin) - -#include "PS_demo_smoothing_plugin.moc" diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/PS_demo_xyz_plugin.cpp cgal-4.5/demo/Surface_reconstruction_points_3/PS_demo_xyz_plugin.cpp --- cgal-4.4/demo/Surface_reconstruction_points_3/PS_demo_xyz_plugin.cpp 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/PS_demo_xyz_plugin.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,86 +0,0 @@ -#include "Point_set_scene_item.h" -#include "Kernel_type.h" - -#include "Polyhedron_demo_io_plugin_interface.h" -#include - -class PS_demo_xyz_plugin : - public QObject, - public Polyhedron_demo_io_plugin_interface -{ - Q_OBJECT - Q_INTERFACES(Polyhedron_demo_io_plugin_interface) - -public: - QStringList nameFilters() const; - bool canLoad() const; - Scene_item* load(QFileInfo fileinfo); - - bool canSave(const Scene_item*); - bool save(const Scene_item*, QFileInfo fileinfo); -}; - -QStringList PS_demo_xyz_plugin::nameFilters() const { - return QStringList() << "XYZ files (*.xyz)" - << "Point Sets with Normal (*.pwn)"; -} - -bool PS_demo_xyz_plugin::canLoad() const { - return true; -} - - -Scene_item* -PS_demo_xyz_plugin::load(QFileInfo fileinfo) -{ - // Check extension (quietly) - std::string extension = fileinfo.suffix().toUtf8().data(); - if (extension != "xyz" && extension != "XYZ" && - extension != "pwn" && extension != "PWN") - return NULL; - - // Open file - std::ifstream in(fileinfo.filePath().toUtf8().data()); - if(!in) { - std::cerr << "Error! Cannot open file " << fileinfo.filePath().toStdString() << std::endl; - return NULL; - } - - // Read .xyz in a point set - Point_set_scene_item* point_set_item = new Point_set_scene_item; - point_set_item->setName(fileinfo.completeBaseName()); - if(!point_set_item->read_xyz_point_set(in)) { - delete point_set_item; - return NULL; - } - return point_set_item; -} - -bool PS_demo_xyz_plugin::canSave(const Scene_item* item) -{ - // This plugin supports point sets - return qobject_cast(item); -} - -bool PS_demo_xyz_plugin::save(const Scene_item* item, QFileInfo fileinfo) -{ - // Check extension (quietly) - std::string extension = fileinfo.suffix().toUtf8().data(); - if (extension != "xyz" && extension != "XYZ" && - extension != "pwn" && extension != "PWN") - return false; - - // This plugin supports point sets - const Point_set_scene_item* point_set_item = - qobject_cast(item); - if(!point_set_item) - return false; - - // Save point set as .xyz - std::ofstream out(fileinfo.filePath().toUtf8().data()); - return point_set_item->write_xyz_point_set(out); -} - -#include -Q_EXPORT_PLUGIN2(PS_demo_xyz_plugin, PS_demo_xyz_plugin) -#include "PS_demo_xyz_plugin.moc" diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/resources/about.html cgal-4.5/demo/Surface_reconstruction_points_3/resources/about.html --- cgal-4.4/demo/Surface_reconstruction_points_3/resources/about.html 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/resources/about.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ - - -

Point Set Demo

-

Copyright ©2008-2009 - GeometryFactory - and INRIA Sophia Antipolis - Mediterranee

-

This application illustrates CGAL - algorithms on point sets.

-

See also the following chapters of the manual: -

-

- - diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/resources/cgal_logo.xpm cgal-4.5/demo/Surface_reconstruction_points_3/resources/cgal_logo.xpm --- cgal-4.4/demo/Surface_reconstruction_points_3/resources/cgal_logo.xpm 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/resources/cgal_logo.xpm 1970-01-01 00:00:00.000000000 +0000 @@ -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 */ -"................", -"...++++...++++..", -"..+....+.+....+.", -"..+......+......", -"..+......+..+++.", -"..+......+....+.", -"..+....+.+....+.", -"...++++...++++..", -"................", -"...++++...+.....", -"..+....+..+.....", -"..+....+..+.....", -"..++++++..+.....", -"..+....+..+.....", -"..+....+..+++++.", -"................"}; Binary files /tmp/MIP0fTspK1/cgal-4.4/demo/Surface_reconstruction_points_3/resources/check-off.png and /tmp/V6WHqzMysX/cgal-4.5/demo/Surface_reconstruction_points_3/resources/check-off.png differ diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/resources/check-off.svg cgal-4.5/demo/Surface_reconstruction_points_3/resources/check-off.svg --- cgal-4.4/demo/Surface_reconstruction_points_3/resources/check-off.svg 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/resources/check-off.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - Binary files /tmp/MIP0fTspK1/cgal-4.4/demo/Surface_reconstruction_points_3/resources/check-on.png and /tmp/V6WHqzMysX/cgal-4.5/demo/Surface_reconstruction_points_3/resources/check-on.png differ diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/resources/check.svg cgal-4.5/demo/Surface_reconstruction_points_3/resources/check.svg --- cgal-4.4/demo/Surface_reconstruction_points_3/resources/check.svg 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/resources/check.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1,103 +0,0 @@ - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - Binary files /tmp/MIP0fTspK1/cgal-4.4/demo/Surface_reconstruction_points_3/resources/editcopy.png and /tmp/V6WHqzMysX/cgal-4.5/demo/Surface_reconstruction_points_3/resources/editcopy.png differ Binary files /tmp/MIP0fTspK1/cgal-4.4/demo/Surface_reconstruction_points_3/resources/minus.png and /tmp/V6WHqzMysX/cgal-4.5/demo/Surface_reconstruction_points_3/resources/minus.png differ Binary files /tmp/MIP0fTspK1/cgal-4.4/demo/Surface_reconstruction_points_3/resources/plus.png and /tmp/V6WHqzMysX/cgal-4.5/demo/Surface_reconstruction_points_3/resources/plus.png differ Binary files /tmp/MIP0fTspK1/cgal-4.4/demo/Surface_reconstruction_points_3/resources/simplification.png and /tmp/V6WHqzMysX/cgal-4.5/demo/Surface_reconstruction_points_3/resources/simplification.png differ diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/Scene_basic_objects_config.h cgal-4.5/demo/Surface_reconstruction_points_3/Scene_basic_objects_config.h --- cgal-4.4/demo/Surface_reconstruction_points_3/Scene_basic_objects_config.h 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/Scene_basic_objects_config.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -#ifndef SCENE_BASIC_OBJECTS_CONFIG_H -#define SCENE_BASIC_OBJECTS_CONFIG_H - -#ifdef PS_demo_scene_basic_objects_EXPORTS -# define SCENE_BASIC_OBJECTS_EXPORT Q_DECL_EXPORT -#else -# define SCENE_BASIC_OBJECTS_EXPORT Q_DECL_IMPORT -#endif - -#endif // SCENE_BASIC_OBJECTS_CONFIG_H diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/Scene.cpp cgal-4.5/demo/Surface_reconstruction_points_3/Scene.cpp --- cgal-4.4/demo/Surface_reconstruction_points_3/Scene.cpp 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/Scene.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,674 +0,0 @@ - -#ifdef CGAL_GLEW_ENABLED -# include "GlSplat/GlSplat.h" -#endif - -#include "config.h" -#include "Scene.h" -#include "Scene_item.h" -#include "Scene_polyhedron_item.h" -#include "Point_set_scene_item.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace { - void CGALglcolor(QColor c) - { - ::glColor4f(c.red()/255.0, c.green()/255.0, c.blue()/255.0, c.alpha()/255.0); - } -} - -#ifdef CGAL_GLEW_ENABLED -GlSplat::SplatRenderer* Scene::ms_splatting = 0; -int Scene::ms_splattingCounter = 0; -GlSplat::SplatRenderer* Scene::splatting() -{ - assert(ms_splatting!=0 && "A Scene object must be created before requesting the splatting object"); - return ms_splatting; -} -#endif - -Scene::Scene(QObject* parent) - : QAbstractListModel(parent), - selected_item(-1) -{ -#ifdef CGAL_GLEW_ENABLED - if(ms_splatting==0) - ms_splatting = new GlSplat::SplatRenderer(); - ms_splattingCounter++; -#endif -} - -Scene::Item_id -Scene::addItem(Scene_item* item) -{ - entries.push_back(item); - - emit updated_bbox(); - emit updated(); - QAbstractListModel::reset(); - return entries.size() - 1; -} - -// Erases a scene item. -// Returns the index of the polyhedra just before the one that is erased, -// or just after. Returns -1 if the list is empty. -Scene::Item_id Scene::erase(Item_id index) -{ - if(index < 0 || index >= entries.size()) - return -1; - - Scene_item* item = entries[index]; - emit itemAboutToBeDestroyed(item); - delete item; - entries.removeAt(index); - - selected_item = -1; - emit updated(); - QAbstractListModel::reset(); - - if(--index >= 0) - return index; - if(!entries.isEmpty()) - return 0; - return -1; -} - -Scene::~Scene() -{ - Q_FOREACH(Scene_item* item_ptr, entries) - { - delete item_ptr; - } - entries.clear(); - -#ifdef CGAL_GLEW_ENABLED - if((--ms_splattingCounter)==0) - delete ms_splatting; -#endif -} - -Scene_item* -Scene::item(Item_id index) const -{ - return entries.value(index); // QList::value checks bounds -} - -size_t -Scene::numberOfEntries() const -{ - return entries.size(); -} - -// Duplicates a scene item. -// Returns the ID of the new item (-1 on error). -Scene::Item_id -Scene::duplicate(Item_id index) -{ - if(index < 0 || index >= entries.size()) - return -1; - - const Scene_item* item = entries[index]; - Scene_item* new_item = item->clone(); - if(new_item) { - new_item->setName(tr("%1 (copy)").arg(item->name())); - new_item->setColor(item->color()); - new_item->setVisible(item->visible()); - Item_id new_index = addItem(new_item); - return new_index; - } - else - return -1; -} - -// Converts a polyhedron to a point set. -// Returns the ID of the new item (-1 on error). -Scene::Item_id -Scene::convertToPointSet(Item_id index) -{ - // Check index - if(index < 0 || index >= entries.size()) - return -1; - - // Check if scene item is a polyhedron - Scene_item* item = entries[index]; - Scene_polyhedron_item* poly_item = - qobject_cast(item); - if(poly_item == NULL || poly_item->polyhedron() == NULL) - return -1; - - // Converts polyhedron to a point set - Point_set_scene_item* new_item = new Point_set_scene_item(*poly_item->polyhedron()); - if(new_item) { - new_item->setName(tr("%1 (point set)").arg(item->name())); - new_item->setColor(item->color()); - new_item->setVisible(item->visible()); - Item_id new_index = addItem(new_item); - - // Hide polyhedron - poly_item->setVisible(false); - itemChanged(index); - - return new_index; - } - else - return -1; -} - -// Delete selection in a scene item -void Scene::deleteSelection(Item_id index) -{ - // Check index - if(index < 0 || index >= entries.size()) - return; - - Scene_item* item = entries[index]; - if (item->isSelectionEmpty()) - return; - - item->deleteSelection(); - itemChanged(index); -} - -// Reset selection mark in a scene item -void Scene::resetSelection(Item_id index) -{ - if(index < 0 || index >= entries.size()) - return; - - Scene_item* item = entries[index]; - item->resetSelection(); - itemChanged(index); -} - -void Scene::initializeGL() -{ -#ifdef CGAL_GLEW_ENABLED - ms_splatting->init(); -#endif -} - -// workaround for Qt-4.2. -#if QT_VERSION < 0x040300 -# define lighter light -#endif - -void -Scene::draw() -{ - draw_aux(false); -} -void -Scene::drawWithNames() -{ - draw_aux(true); -} - -void -Scene::draw_aux(bool with_names) -{ - // Flat/Gouraud OpenGL drawing - for(int index = 0; index < entries.size(); ++index) - { - if(with_names) { - ::glPushName(index); - } - Scene_item& item = *entries[index]; - if(item.visible()) - { - if(item.renderingMode() == Flat || item.renderingMode() == FlatPlusEdges || item.renderingMode() == Gouraud) - { - ::glEnable(GL_LIGHTING); - ::glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); - ::glPointSize(2.f); - ::glLineWidth(1.0f); - if(index == selected_item) - CGALglcolor(item.color().lighter(120)); - else - CGALglcolor(item.color()); - if(item.renderingMode() == Gouraud) - ::glShadeModel(GL_SMOOTH); - else - ::glShadeModel(GL_FLAT); - - item.draw(); - } - } - if(with_names) { - ::glPopName(); - } - } - - // Wireframe OpenGL drawing - for(int index = 0; index < entries.size(); ++index) - { - if(with_names) { - ::glPushName(index); - } - Scene_item& item = *entries[index]; - if(item.visible()) - { - if(item.renderingMode() == FlatPlusEdges || item.renderingMode() == Wireframe) - { - ::glDisable(GL_LIGHTING); - ::glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); - ::glPointSize(2.f); - ::glLineWidth(1.0f); - if(index == selected_item) - CGALglcolor(Qt::black); - else - CGALglcolor(item.color().lighter(50)); - - item.draw_edges(); - } - if(with_names) { - ::glPopName(); - } - } - } - - // Points OpenGL drawing - for(int index = 0; index < entries.size(); ++index) - { - if(with_names) { - ::glPushName(index); - } - Scene_item& item = *entries[index]; - if(item.visible()) - { - if(item.renderingMode() == Points || item.renderingMode() == PointsPlusNormals) - { - ::glDisable(GL_LIGHTING); - ::glPolygonMode(GL_FRONT_AND_BACK,GL_POINT); - ::glPointSize(2.f); - ::glLineWidth(1.0f); - if(index == selected_item) - CGALglcolor(Qt::black); - else - CGALglcolor(item.color().lighter(50)); - - item.draw_points(); - } - if(with_names) { - ::glPopName(); - } - } - } - -#ifdef CGAL_GLEW_ENABLED - // Splatting - if(ms_splatting->isSupported()) - { - ms_splatting->beginVisibilityPass(); - for(int index = 0; index < entries.size(); ++index) - { - Scene_item& item = *entries[index]; - if(item.visible() && item.renderingMode() == Splatting) - { - item.draw_splats(); - } - } - ms_splatting->beginAttributePass(); - for(int index = 0; index < entries.size(); ++index) - { - Scene_item& item = *entries[index]; - if(item.visible() && item.renderingMode() == Splatting) - { - if(index == selected_item) - CGALglcolor(item.color().lighter(120)); - else - CGALglcolor(item.color()); - item.draw_splats(); - } - } - ms_splatting->finalize(); - } -#endif - - // Normals OpenGL drawing - for(int index = 0; index < entries.size(); ++index) - { - if(with_names) { - ::glPushName(index); - } - Scene_item& item = *entries[index]; - if(item.visible()) - { - if(item.renderingMode() == PointsPlusNormals) - { - ::glDisable(GL_LIGHTING); - ::glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); - ::glPointSize(2.f); - ::glLineWidth(1.0f); - if(index == selected_item) - CGALglcolor(item.color().lighter(120)); - else - CGALglcolor(item.color()); - - item.draw_normals(); - } - if(with_names) { - ::glPopName(); - } - } - } -} - -// workaround for Qt-4.2 (see above) -#undef lighter - -int -Scene::rowCount(const QModelIndex & parent) const -{ - if (parent.isValid()) - return 0; - else - return entries.size(); -} - -int -Scene::columnCount(const QModelIndex & parent) const -{ - if (parent.isValid()) - return 0; - else - return NumberOfColumns; -} - -QVariant -Scene::data(const QModelIndex &index, int role) const -{ - if (!index.isValid()) - return QVariant(); - - if(index.row() < 0 || index.row() >= entries.size()) - return QVariant(); - - if(role == ::Qt::ToolTipRole) - { - return entries[index.row()]->toolTip(); - } - switch(index.column()) - { - case ColorColumn: - if(role == ::Qt::DisplayRole || role == ::Qt::EditRole) - return entries.value(index.row())->color(); - else if(role == ::Qt::DecorationRole) - return entries.value(index.row())->color(); - break; - case NameColumn: - if(role == ::Qt::DisplayRole || role == ::Qt::EditRole) - return entries.value(index.row())->name(); - if(role == ::Qt::FontRole) - return entries.value(index.row())->font(); - break; - case RenderingModeColumn: - if(role == ::Qt::DisplayRole) { - return entries.value(index.row())->renderingModeName(); - } - else if(role == ::Qt::EditRole) { - return static_cast(entries.value(index.row())->renderingMode()); - } - else if(role == ::Qt::TextAlignmentRole) { - return ::Qt::AlignCenter; - } - break; - case VisibleColumn: - if(role == ::Qt::DisplayRole || role == ::Qt::EditRole) - return entries.value(index.row())->visible(); - break; - default: - return QVariant(); - } - return QVariant(); -} - -QVariant -Scene::headerData ( int section, ::Qt::Orientation orientation, int role ) const -{ - if(orientation == ::Qt::Horizontal) { - if (role == ::Qt::DisplayRole) - { - switch(section) - { - case NameColumn: - return tr("Name"); - break; - case ColorColumn: - return tr("Color"); - break; - case RenderingModeColumn: - return tr("Mode"); - case VisibleColumn: - return tr("View"); - break; - default: - return QVariant(); - } - } - else if(role == ::Qt::ToolTipRole) { - if(section == RenderingModeColumn) { - return Scene_item::renderingModeNameList(); - } - } - } - return QAbstractListModel::headerData(section, orientation, role); -} - -Qt::ItemFlags -Scene::flags ( const QModelIndex & index ) const -{ - if (index.isValid() && index.column() == NameColumn) { - return QAbstractListModel::flags(index) | ::Qt::ItemIsEditable; - } - else { - return QAbstractListModel::flags(index); - } -} - -bool -Scene::setData(const QModelIndex &index, - const QVariant &value, - int role) -{ - if( role != ::Qt::EditRole || !index.isValid() ) - return false; - - if(index.row() < 0 || index.row() >= entries.size()) - return false; - - Scene_item* item = entries[index.row()]; - if(!item) return false; - switch(index.column()) - { - case NameColumn: - item->setName(value.toString()); - item->changed(); - emit dataChanged(index, index); - return true; - break; - case ColorColumn: - item->setColor(value.value()); - item->changed(); - emit dataChanged(index, index); - return true; - break; - case RenderingModeColumn: - { - RenderingMode rendering_mode = static_cast(value.toInt()); - // Find next supported rendering mode - while ( !item->supportsRenderingMode(rendering_mode) -#ifdef CGAL_GLEW_ENABLED - || (rendering_mode==Splatting && !Scene::splatting()->isSupported()) -#endif - ) - { - rendering_mode = static_cast( (rendering_mode+1) % NumberOfRenderingMode ); - } - item->setRenderingMode(rendering_mode); - item->changed(); - emit dataChanged(index, index); - return true; - break; - } - case VisibleColumn: - item->setVisible(value.toBool()); - item->changed(); - emit dataChanged(index, index); - return true; - default: - return false; - } - return false; -} - -Scene::Item_id Scene::mainSelectionIndex() const { - return selected_item; -} - -QItemSelection Scene::createSelection(int i) -{ - return QItemSelection(QAbstractItemModel::createIndex(i, 0), - QAbstractItemModel::createIndex(i, LastColumn)); -} - -void Scene::itemChanged(Item_id i) -{ - if(i < 0 || i >= entries.size()) - return; - - entries[i]->changed(); - emit dataChanged(QAbstractItemModel::createIndex(i, 0), - QAbstractItemModel::createIndex(i, LastColumn)); -} - -void Scene::itemChanged(Scene_item* item) -{ - item->changed(); - emit dataChanged(QAbstractItemModel::createIndex(0, 0), - QAbstractItemModel::createIndex(entries.size() - 1, LastColumn)); -} - -bool SceneDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, - const QStyleOptionViewItem &option, - const QModelIndex &index) -{ -// Scene *scene = static_cast(model); - switch(index.column()) { - case Scene::VisibleColumn: - if (event->type() == QEvent::MouseButtonPress) { - QMouseEvent *mouseEvent = static_cast(event); - if(mouseEvent->button() == ::Qt::LeftButton) { - int x = mouseEvent->pos().x() - option.rect.x(); - if(x >= (option.rect.width() - size)/2 && - x <= (option.rect.width() + size)/2) { - model->setData(index, ! model->data(index).toBool() ); - } - } - return false; //so that the selection can change - } - return true; - break; - case Scene::ColorColumn: - if (event->type() == QEvent::MouseButtonPress) { - QColor color = - QColorDialog::getColor(model->data(index).value(), - 0/*, - tr("Select color"), - QColorDialog::ShowAlphaChannel*/); - if (color.isValid()) { - model->setData(index, color ); - } - } - else if(event->type() == QEvent::MouseButtonDblClick) { - return true; // block double-click - } - return false; - break; - case Scene::RenderingModeColumn: - if (event->type() == QEvent::MouseButtonPress) { - // Switch rendering mode - /*RenderingMode*/int rendering_mode = model->data(index, ::Qt::EditRole).toInt(); - rendering_mode = (rendering_mode+1) % NumberOfRenderingMode; - model->setData(index, rendering_mode); - } - else if(event->type() == QEvent::MouseButtonDblClick) { - return true; // block double-click - } - return false; - break; - default: - return QItemDelegate::editorEvent(event, model, option, index); - } -} - -void SceneDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, - const QModelIndex &index) const -{ - if (index.column() != Scene::VisibleColumn) { - QItemDelegate::paint(painter, option, index); - } else { - const QAbstractItemModel *model = index.model(); - QPalette::ColorGroup cg = (option.state & QStyle::State_Enabled) ? - (option.state & QStyle::State_Active) ? QPalette::Normal : QPalette::Inactive : QPalette::Disabled; - - if (option.state & QStyle::State_Selected) - painter->fillRect(option.rect, option.palette.color(cg, QPalette::Highlight)); - - bool checked = model->data(index, ::Qt::DisplayRole).toBool(); - int width = option.rect.width(); - int height = option.rect.height(); - size = (std::min)(width, height); - int x = option.rect.x() + (option.rect.width() / 2) - (size / 2);; - int y = option.rect.y() + (option.rect.height() / 2) - (size / 2); - if(checked) { - painter->drawPixmap(x, y, checkOnPixmap.scaled(QSize(size, size), - ::Qt::KeepAspectRatio, - ::Qt::SmoothTransformation)); - } - else { - painter->drawPixmap(x, y, checkOffPixmap.scaled(QSize(size, size), - ::Qt::KeepAspectRatio, - ::Qt::SmoothTransformation)); - } - drawFocus(painter, option, option.rect); // since we draw the grid ourselves - } -} - -void Scene::setItemVisible(int index, bool b) -{ - if( index < 0 || index >= entries.size() ) - return; - entries[index]->setVisible(b); - emit dataChanged(QAbstractItemModel::createIndex(index, VisibleColumn), - QAbstractItemModel::createIndex(index, VisibleColumn)); -} - -Scene::Bbox Scene::bbox() const -{ - if(entries.empty()) - return Bbox(); - - bool bbox_initialized = false; - Bbox bbox; - Q_FOREACH(Scene_item* item, entries) - { - if(item->isFinite() && !item->isEmpty()) { - if(bbox_initialized) { - bbox = bbox + item->bbox(); - } - else { - bbox = item->bbox(); - bbox_initialized = true; - } - } - } - return bbox; -} diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/Scene_draw_interface.h cgal-4.5/demo/Surface_reconstruction_points_3/Scene_draw_interface.h --- cgal-4.4/demo/Surface_reconstruction_points_3/Scene_draw_interface.h 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/Scene_draw_interface.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,12 +0,0 @@ -#ifndef SCENE_DRAW_INTERFACE_H -#define SCENE_DRAW_INTERFACE_H - -class Scene_draw_interface { -public: - virtual ~Scene_draw_interface(){} - virtual void initializeGL() = 0; - virtual void draw() = 0; - virtual void drawWithNames() = 0; -}; - -#endif // SCENE_DRAW_INTERFACE_H; diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/Scene.h cgal-4.5/demo/Surface_reconstruction_points_3/Scene.h --- cgal-4.4/demo/Surface_reconstruction_points_3/Scene.h 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/Scene.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,148 +0,0 @@ -#ifndef SCENE_H -#define SCENE_H -#include "config.h" - -#include "Scene_interface.h" -#include "Scene_draw_interface.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -class QEvent; -class QMouseEvent; -namespace GlSplat { class SplatRenderer; } - -class Scene : - public QAbstractListModel, public Scene_interface, public Scene_draw_interface -{ - Q_OBJECT - - friend class SceneDelegate; - -public: - enum Columns { NameColumn = 0, - ColorColumn, - RenderingModeColumn, - VisibleColumn, - LastColumn = VisibleColumn, - NumberOfColumns = LastColumn + 1}; - - Scene(QObject* parent); - ~Scene(); - - Item_id addItem(Scene_item* item); - - // Erases a scene item. - // Returns the index of the polyhedra just before the one that is erased, - // or just after. Returns -1 if the list is empty. - Item_id erase(Item_id index); - - // Duplicates a scene item. Returns the ID of the new item (-1 on error). - Item_id duplicate(Item_id index); - // Converts a polyhedron to a point set. - // Returns the ID of the new item (-1 on error). - Item_id convertToPointSet(Item_id index); - - // Delete selection in a scene item - void deleteSelection(Item_id index); - // Reset selection mark in a scene item. - void resetSelection(Item_id index); - - // Accessors (getters) - size_t numberOfEntries() const; - Scene_item* item(Item_id) const ; - Item_id mainSelectionIndex() const; - - // initializeGL() is called by Viewer::initializeGL() - void initializeGL(); - // draw() is called by Viewer::draw() - void draw(); - void drawWithNames(); - - // Gets scene bounding box - Bbox bbox() const; - double len_diagonal() const - { - Bbox box = bbox(); - double dx = box.xmax - box.xmin; - double dy = box.ymax - box.ymin; - double dz = box.zmax - box.zmin; - return std::sqrt(dx*dx + dy*dy + dz*dz); - } - - // QAbstractItemModel functions - int rowCount ( const QModelIndex & parent = QModelIndex() ) const; - int columnCount ( const QModelIndex & parent = QModelIndex() ) const; - QVariant data ( const QModelIndex & index, int role = ::Qt::DisplayRole ) const; - QVariant headerData ( int section, ::Qt::Orientation orientation, int role = ::Qt::DisplayRole ) const; - ::Qt::ItemFlags flags ( const QModelIndex & index ) const; - bool setData(const QModelIndex &index, const QVariant &value, int role); - - // auxiliary public function for QMainWindow - QItemSelection createSelection(int i); - -public slots: - // Notify the scene that an item was modified - void itemChanged(Item_id i); - void itemChanged(Scene_item*); - - void setSelectedItem(Item_id i ) - { - selected_item = i; - }; - - // Accessors (setters) - void setItemVisible(int, bool b); - -signals: - void updated_bbox(); - void updated(); - void itemAboutToBeDestroyed(Scene_item*); - -private: - void draw_aux(bool with_names); - typedef QList Entries; - Entries entries; - int selected_item; -#ifdef CGAL_GLEW_ENABLED - static GlSplat::SplatRenderer* ms_splatting; - static int ms_splattingCounter; -public: - static GlSplat::SplatRenderer* splatting(); -#endif - -}; // end class Scene - -class SceneDelegate : public QItemDelegate -{ -public: - SceneDelegate(QObject * parent = 0) - : QItemDelegate(parent), - checkOnPixmap(":/cgal/icons/check-on.png"), - checkOffPixmap(":/cgal/icons/check-off.png") - { - } - - bool editorEvent(QEvent *event, QAbstractItemModel *model, - const QStyleOptionViewItem &option, - const QModelIndex &index); - void paint(QPainter *painter, const QStyleOptionViewItem &option, - const QModelIndex &index) const; - -private: - QPixmap checkOnPixmap; - QPixmap checkOffPixmap; - mutable int size; -}; // end class SceneDelegate - -#endif // SCENE_H diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/Scene_interface.h cgal-4.5/demo/Surface_reconstruction_points_3/Scene_interface.h --- cgal-4.4/demo/Surface_reconstruction_points_3/Scene_interface.h 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/Scene_interface.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,82 +0,0 @@ -#ifndef SCENE_INTERFACE_H -#define SCENE_INTERFACE_H - -#include -#include -#include - -class Scene_item; - -// OpenGL rendering mode -enum RenderingMode { Points = 0, - PointsPlusNormals, - Splatting, - Wireframe, - Flat, - FlatPlusEdges, - Gouraud, - LastRenderingMode = Gouraud, - NumberOfRenderingMode = LastRenderingMode+1 }; - -// Interface of Scene class exported to plugins -class Scene_interface { -public: - struct Bbox { - double xmin, ymin, zmin; - double xmax, ymax, zmax; - Bbox(const double _xmin,const double _ymin,const double _zmin, - const double _xmax,const double _ymax,const double _zmax) - : xmin(_xmin), ymin(_ymin), zmin(_zmin), - xmax(_xmax), ymax(_ymax), zmax(_zmax) - { - } - Bbox() - : xmin(0.0), ymin(0.0), zmin(0.0), - xmax(1.0), ymax(1.0), zmax(1.0) - { - } - - Bbox operator+(const Bbox& b) const { - return Bbox((std::min)(xmin, b.xmin), - (std::min)(ymin, b.ymin), - (std::min)(zmin, b.zmin), - (std::max)(xmax, b.xmax), - (std::max)(ymax, b.ymax), - (std::max)(zmax, b.zmax)); - } - - }; // struct BBox (ad hoc class, does not depend on CGAL kernels - - typedef int Item_id; - - virtual ~Scene_interface() {}; - - virtual Item_id addItem(Scene_item* item) = 0; - - virtual Item_id erase(Item_id) = 0; - // Returns the index of the item just before the one that is erased, - // or just after. Returns -1 if the list is empty. - - virtual Item_id duplicate(Item_id) = 0; - // Returns the index of the new item - // If no new item has been created (because the item type is note - // clonable), returns -1. - - // Accessors (getters) - virtual size_t numberOfEntries() const = 0; - virtual Scene_item* item(Item_id) const = 0; - virtual Item_id mainSelectionIndex() const = 0; - - // Gets scene bounding box - virtual Bbox bbox() const = 0; - virtual double len_diagonal() const = 0; - -public: - // Notify the scene that an item was modified - virtual void itemChanged(Item_id i) = 0; - virtual void itemChanged(Scene_item*) = 0; - -}; // end interface Scene_interface - - -#endif // SCENE_INTERFACE_H diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/Scene_item_config.h cgal-4.5/demo/Surface_reconstruction_points_3/Scene_item_config.h --- cgal-4.4/demo/Surface_reconstruction_points_3/Scene_item_config.h 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/Scene_item_config.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,12 +0,0 @@ -#ifndef SCENE_ITEM_CONFIG_H -#define SCENE_ITEM_CONFIG_H - -#include - -#ifdef PS_demo_scene_item_EXPORTS -# define SCENE_ITEM_EXPORT Q_DECL_EXPORT -#else -# define SCENE_ITEM_EXPORT Q_DECL_IMPORT -#endif - -#endif // SCENE_ITEM_CONFIG_H diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/Scene_item.cpp cgal-4.5/demo/Surface_reconstruction_points_3/Scene_item.cpp --- cgal-4.4/demo/Surface_reconstruction_points_3/Scene_item.cpp 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/Scene_item.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +0,0 @@ -#include "Scene_item.h" - -const QColor Scene_item::defaultColor = QColor(100, 100, 255); - -Scene_item::~Scene_item() {} - -void Scene_item::itemAboutToBeDestroyed(Scene_item* item) { - if(this == item) - emit aboutToBeDestroyed(); -} - -// Rendering mode list as a human readable string -QString Scene_item::renderingModeNameList() -{ - return tr("Rendering mode (points/points+normals/splatting/wireframe/flat/flat+edges/Gouraud)"); -} - -// Rendering mode as a human readable string -QString Scene_item::renderingModeName() const -{ - switch(renderingMode()) - { - case Points: - return tr("points"); - case PointsPlusNormals: - return tr("pts+normals"); - case Splatting: - return tr("splats"); - case Wireframe: - return tr("wire"); - case Flat: - return tr("flat"); - case FlatPlusEdges: - return tr("flat+edges"); - case Gouraud: - return tr("Gouraud"); - default: - Q_ASSERT(false); - return tr("unknown"); - } -} - -#include "Scene_item.moc" - diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/Scene_item.h cgal-4.5/demo/Surface_reconstruction_points_3/Scene_item.h --- cgal-4.4/demo/Surface_reconstruction_points_3/Scene_item.h 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/Scene_item.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,106 +0,0 @@ -#ifndef SCENE_ITEM_H -#define SCENE_ITEM_H - -#include "Scene_item_config.h" -#include "Scene_interface.h" -#include -#include - -namespace qglviewer { - class ManipulatedFrame; -} - -// This class represents an object in the OpenGL scene -class SCENE_ITEM_EXPORT Scene_item : public QObject { - Q_OBJECT - Q_PROPERTY(QColor color READ color WRITE setColor) - Q_PROPERTY(QString name READ name WRITE setName) - Q_PROPERTY(bool visible READ visible WRITE setVisible) - Q_ENUMS(RenderingMode) - Q_PROPERTY(RenderingMode renderingMode READ renderingMode WRITE setRenderingMode) -public: - typedef Scene_interface::Bbox Bbox; - typedef qglviewer::ManipulatedFrame ManipulatedFrame; - - static const QColor defaultColor; // defined in Scene_item.cpp - - static QString renderingModeNameList(); // Rendering mode list as a human readable string - - Scene_item() - : name_("unamed"), - color_(defaultColor), - visible_(true), - rendering_mode(FlatPlusEdges) - {}; - virtual ~Scene_item(); - virtual Scene_item* clone() const = 0; - - // Is selection empty? - virtual bool isSelectionEmpty() const { return true; } - // Delete selection - virtual void deleteSelection() {} - // Reset selection mark - virtual void resetSelection() {} - - // Indicate if rendering mode is supported - virtual bool supportsRenderingMode(RenderingMode m) const = 0; - // Flat/Gouraud OpenGL drawing - virtual void draw() const = 0; - // Wireframe OpenGL drawing - virtual void draw_edges() const { draw(); } - // Points OpenGL drawing - virtual void draw_points() const { draw(); } - // Normals OpenGL drawing - virtual void draw_normals() const {} - // Draws oriented points with radius - virtual void draw_splats() const {} - - // Functions for displaying meta-data of the item - virtual QString toolTip() const = 0; - virtual QFont font() const { return QFont(); } - - // Functions that help the Scene to compute its bbox - virtual bool isFinite() const { return true; } - virtual bool isEmpty() const { return true; } - virtual Bbox bbox() const { return Bbox(); } - - // Function about manipulation - virtual bool manipulatable() const { return false; } - virtual ManipulatedFrame* manipulatedFrame() { return 0; } - - // Getters for the four basic properties - virtual QColor color() const { return color_; } - virtual QString name() const { return name_; } - virtual bool visible() const { return visible_; } - virtual RenderingMode renderingMode() const { return rendering_mode; } - virtual QString renderingModeName() const; // Rendering mode as a human readable string - -public slots: - // Call that once you have finished changing something in the item - // (either the properties or internal data) - virtual void changed() {} - - // Setters for the four basic properties - virtual void setColor(QColor c) { color_ = c; } - virtual void setName(QString n) { name_ = n; } - virtual void setVisible(bool b) { visible_ = b; } - virtual void setRenderingMode(RenderingMode m) { - if (supportsRenderingMode(m)) - rendering_mode = m; - } - - virtual void itemAboutToBeDestroyed(Scene_item*); - -signals: - void aboutToBeDestroyed(); - -protected: - // The four basic properties - QString name_; - QColor color_; - bool visible_; - RenderingMode rendering_mode; - -}; // end class Scene_item - -#endif // SCENE_ITEM_H diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/Scene_item_with_display_list.cpp cgal-4.5/demo/Surface_reconstruction_points_3/Scene_item_with_display_list.cpp --- cgal-4.4/demo/Surface_reconstruction_points_3/Scene_item_with_display_list.cpp 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/Scene_item_with_display_list.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,51 +0,0 @@ -#include "Scene_item_with_display_list.h" -#include - -Scene_item_with_display_list::Scene_item_with_display_list() - : display_list(0), - display_list_built(false) -{} - -// Scene_item_with_display_list:: -// Scene_item_with_display_list(const Scene_item_with_display_list& item) -// : Scene_item(item), -// display_list(0), -// display_list_built(false) -// {} - -Scene_item_with_display_list::~Scene_item_with_display_list() -{ - if(display_list_built && display_list != 0) { - ::glDeleteLists(display_list,1); - } -} - -// Points/Wireframe/Flat/Gouraud OpenGL drawing in a display list -void Scene_item_with_display_list::draw() const -{ - if(!display_list_built) - { - if(display_list == 0) { - display_list = ::glGenLists(1); - if(display_list == 0) - { - std::cerr << "Unable to create display list" << std::endl; - return; - } - } - // draw the item in a display list - ::glNewList(display_list,GL_COMPILE_AND_EXECUTE); - direct_draw(); - ::glEndList(); - display_list_built = true; - } - else { - // draw using the display list - ::glCallList(display_list); - } -} - -void Scene_item_with_display_list::changed() -{ - display_list_built = false; -} diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/Scene_item_with_display_list.h cgal-4.5/demo/Surface_reconstruction_points_3/Scene_item_with_display_list.h --- cgal-4.4/demo/Surface_reconstruction_points_3/Scene_item_with_display_list.h 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/Scene_item_with_display_list.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -#ifndef SCENE_ITEM_WITH_DISPLAY_LIST_H -#define SCENE_ITEM_WITH_DISPLAY_LIST_H - -#include "Scene_item.h" -#include - -// This class represents an object in the scene with an OpenGL rendering using display lists -class SCENE_ITEM_EXPORT Scene_item_with_display_list - : public Scene_item -{ -public: - Scene_item_with_display_list(); -// Scene_item_with_display_list(const Scene_item_with_display_list&); - ~Scene_item_with_display_list(); - - // Points/Wireframe/Flat/Gouraud OpenGL drawing in a display list - virtual void direct_draw() const = 0; - // OpenGL drawing using a display list - virtual void draw() const; - -public slots: - // Call that once you have finished changing something in the item - // (either the properties or internal data). - virtual void changed(); - -private: - // display lists - mutable GLuint display_list; - mutable bool display_list_built; - -}; // end class Scene_item_with_display_list - -#endif // SCENE_ITEM_WITH_DISPLAY_LIST_H diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/Scene_plane_item.cpp cgal-4.5/demo/Surface_reconstruction_points_3/Scene_plane_item.cpp --- cgal-4.4/demo/Surface_reconstruction_points_3/Scene_plane_item.cpp 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/Scene_plane_item.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -#include "Scene_plane_item.h" - -#include "Scene_plane_item.moc" diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/Scene_plane_item.h cgal-4.5/demo/Surface_reconstruction_points_3/Scene_plane_item.h --- cgal-4.4/demo/Surface_reconstruction_points_3/Scene_plane_item.h 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/Scene_plane_item.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,168 +0,0 @@ -#ifndef SCENE_PLANE_ITEM_H -#define SCENE_PLANE_ITEM_H - -#include "Scene_item.h" -#include "Scene_interface.h" - -#include "Scene_basic_objects_config.h" - -#include -#include - -#include - -#include "Kernel_type.h" - -class SCENE_BASIC_OBJECTS_EXPORT Scene_plane_item - : public Scene_item -{ - Q_OBJECT -public: - typedef qglviewer::ManipulatedFrame ManipulatedFrame; - - Scene_plane_item(const Scene_interface* scene_interface) - : scene(scene_interface), - manipulable(false), - can_clone(true), - frame(new ManipulatedFrame()) - { - setNormal(0., 0., 1.); - } - - ~Scene_plane_item() { - delete frame; - } - - bool isFinite() const { return false; } - bool isEmpty() const { return false; } - Bbox bbox() const { return Bbox(); } - - bool manipulatable() const { - return manipulable; - } - ManipulatedFrame* manipulatedFrame() { - return frame; - } - - Scene_plane_item* clone() const { - if(can_clone) - { - Scene_plane_item* item = new Scene_plane_item(scene); - item->manipulable = manipulable; - item->can_clone = true; - item->frame = new ManipulatedFrame; - item->frame->setPosition(frame->position()); - item->frame->setOrientation(frame->orientation()); - return item; - } - else - return 0; - } - - QString toolTip() const { - const qglviewer::Vec& pos = frame->position(); - const qglviewer::Vec& n = frame->orientation().axis(); - return - tr("

%1 (mode: %2, color: %3)
") - .arg(this->name()) - .arg(this->renderingModeName()) - .arg(this->color().name()) - - + - tr("Plane

" - "

Equation: %1*x + %2*y + %3*z + %4 = 0
" - "Normal vector: (%1, %2, %3)
" - "Point: (%5, %6, %7)

") - .arg(n[0]).arg(n[1]).arg(n[2]) - .arg( - pos * n) - .arg(pos[0]).arg(pos[1]).arg(pos[2]) - + - tr("

Can clone: %1
" - "Manipulatable: %2

") - .arg(can_clone?tr("true"):tr("false")) - .arg(manipulable?tr("true"):tr("false")); - } - - // Indicate if rendering mode is supported - bool supportsRenderingMode(RenderingMode m) const { - return (m == Wireframe || m == Flat); - } - - // Flat OpenGL drawing - void draw() const { - const double diag = scene_diag(); - ::glPushMatrix(); - ::glMultMatrixd(frame->matrix()); - GLboolean lighting; - ::glGetBooleanv(GL_LIGHTING, &lighting); - ::glDisable(GL_LIGHTING); - ::glBegin(GL_POLYGON); - ::glVertex3d(-diag, -diag, 0.); - ::glVertex3d(-diag, diag, 0.); - ::glVertex3d( diag, diag, 0.); - ::glVertex3d( diag, -diag, 0.); - ::glEnd(); - if(lighting) - ::glEnable(GL_LIGHTING); - ::glPopMatrix(); - }; - - // Wireframe OpenGL drawing - void draw_edges() const { - ::glPushMatrix(); - ::glMultMatrixd(frame->matrix()); - QGLViewer::drawGrid((float)scene_diag()); - ::glPopMatrix(); - } - - Plane_3 plane() const { - const qglviewer::Vec& pos = frame->position(); - const qglviewer::Vec& n = - frame->inverseTransformOf(qglviewer::Vec(0.f, 0.f, 1.f)); - return Plane_3(n[0], n[1], n[2], - n * pos); - } - -private: - double scene_diag() const { - const Bbox& bbox = scene->bbox(); - const double& xdelta = bbox.xmax-bbox.xmin; - const double& ydelta = bbox.ymax-bbox.ymin; - const double& zdelta = bbox.zmax-bbox.zmin; - const double diag = std::sqrt(xdelta*xdelta + - ydelta*ydelta + - zdelta*zdelta); - return diag * 0.7; - } - -public slots: - void setPosition(float x, float y, float z) { - frame->setPosition(x, y, z); - } - - void setPosition(double x, double y, double z) { - frame->setPosition((float)x, (float)y, (float)z); - } - - void setNormal(float x, float y, float z) { - frame->setOrientation(x, y, z, 0.f); - } - - void setNormal(double x, double y, double z) { - frame->setOrientation((float)x, (float)y, (float)z, 0.f); - } - - void setClonable(bool b = true) { - can_clone = b; - } - - void setManipulatable(bool b = true) { - manipulable = b; - } -private: - const Scene_interface* scene; - bool manipulable; - bool can_clone; - qglviewer::ManipulatedFrame* frame; -}; - -#endif // SCENE_PLANE_ITEM_H diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/Scene_polyhedron_item_config.h cgal-4.5/demo/Surface_reconstruction_points_3/Scene_polyhedron_item_config.h --- cgal-4.4/demo/Surface_reconstruction_points_3/Scene_polyhedron_item_config.h 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/Scene_polyhedron_item_config.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -#ifndef SCENE_POLYHEDRON_ITEM_CONFIG_H -#define SCENE_POLYHEDRON_ITEM_CONFIG_H - -#ifdef PS_demo_scene_polyhedron_item_EXPORTS -# define SCENE_POLYHEDRON_ITEM_EXPORT Q_DECL_EXPORT -#else -# define SCENE_POLYHEDRON_ITEM_EXPORT Q_DECL_IMPORT -#endif - -#endif // SCENE_POLYHEDRON_ITEM_CONFIG_H diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/Scene_polyhedron_item.cpp cgal-4.5/demo/Surface_reconstruction_points_3/Scene_polyhedron_item.cpp --- cgal-4.4/demo/Surface_reconstruction_points_3/Scene_polyhedron_item.cpp 2013-08-03 19:00:28.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/Scene_polyhedron_item.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,109 +0,0 @@ -#include "Scene_polyhedron_item.h" -#include "Polyhedron_type.h" -#include - -#include -#include - -Scene_polyhedron_item::Scene_polyhedron_item() - : Scene_item_with_display_list(), - poly(new Polyhedron) -{ -} - -Scene_polyhedron_item::Scene_polyhedron_item(Polyhedron* const p) - : Scene_item_with_display_list(), - poly(p) -{ -} - -Scene_polyhedron_item::Scene_polyhedron_item(const Polyhedron& p) - : Scene_item_with_display_list(), - poly(new Polyhedron(p)) -{ -} - -// Scene_polyhedron_item::Scene_polyhedron_item(const Scene_polyhedron_item& item) -// : Scene_item_with_display_list(item), -// poly(new Polyhedron(*item.poly)) -// { -// } - -Scene_polyhedron_item::~Scene_polyhedron_item() -{ - delete poly; -} - -Scene_polyhedron_item* -Scene_polyhedron_item::clone() const { - return new Scene_polyhedron_item(*poly); -} - -// Loads polyhedron from .OFF file -bool -Scene_polyhedron_item::load(std::istream& in) -{ - in >> *poly; - return in && !isEmpty(); -} - -// Write polyhedron to .OFF file -bool -Scene_polyhedron_item::save(std::ostream& out) const -{ - out << *poly; - return (bool) out; -} - -QString -Scene_polyhedron_item::toolTip() const -{ - if(!poly) - return QString(); - - return QObject::tr("

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

" - "

Number of vertices: %2
" - "Number of edges: %3
" - "Number of facets: %4

") - .arg(this->name()) - .arg(poly->size_of_vertices()) - .arg(poly->size_of_halfedges()/2) - .arg(poly->size_of_facets()) - .arg(this->renderingModeName()) - .arg(this->color().name()); -} - - -bool Scene_polyhedron_item::supportsRenderingMode(RenderingMode m) const { - return m != PointsPlusNormals && m != Splatting; -} - -// Points/Wireframe/Flat/Gouraud OpenGL drawing in a display list -void Scene_polyhedron_item::direct_draw() const { - gl_render_facets(*poly); -} - -Polyhedron* -Scene_polyhedron_item::polyhedron() { return poly; } -const Polyhedron* -Scene_polyhedron_item::polyhedron() const { return poly; } - -bool -Scene_polyhedron_item::isEmpty() const { - return (poly == 0) || poly->empty(); -} - -Scene_polyhedron_item::Bbox -Scene_polyhedron_item::bbox() const { - const Point& p = *(poly->points_begin()); - CGAL::Bbox_3 bbox(p.x(), p.y(), p.z(), p.x(), p.y(), p.z()); - for(Polyhedron::Point_iterator it = poly->points_begin(); - it != poly->points_end(); - ++it) { - bbox = bbox + it->bbox(); - } - return Bbox(bbox.xmin(),bbox.ymin(),bbox.zmin(), - bbox.xmax(),bbox.ymax(),bbox.zmax()); -} - -#include "Scene_polyhedron_item.moc" diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/Scene_polyhedron_item.h cgal-4.5/demo/Surface_reconstruction_points_3/Scene_polyhedron_item.h --- cgal-4.4/demo/Surface_reconstruction_points_3/Scene_polyhedron_item.h 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/Scene_polyhedron_item.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,48 +0,0 @@ -#ifndef SCENE_POLYHEDRON_ITEM_H -#define SCENE_POLYHEDRON_ITEM_H - -#include "Scene_polyhedron_item_config.h" -#include "Scene_item_with_display_list.h" -#include "Polyhedron_type_fwd.h" -#include - -// This class represents a polyhedron in the OpenGL scene -class SCENE_POLYHEDRON_ITEM_EXPORT Scene_polyhedron_item - : public Scene_item_with_display_list { - Q_OBJECT -public: - Scene_polyhedron_item(); -// Scene_polyhedron_item(const Scene_polyhedron_item&); - Scene_polyhedron_item(const Polyhedron& p); - Scene_polyhedron_item(Polyhedron* const p); - ~Scene_polyhedron_item(); - - Scene_polyhedron_item* clone() const; - - // IO - bool load(std::istream& in); - bool save(std::ostream& out) const; - - // Function for displaying meta-data of the item - virtual QString toolTip() const; - - // Indicate if rendering mode is supported - virtual bool supportsRenderingMode(RenderingMode m) const; - // Points/Wireframe/Flat/Gouraud OpenGL drawing in a display list - virtual void direct_draw() const; - - // Gets wrapped polyhedron - Polyhedron* polyhedron(); - const Polyhedron* polyhedron() const; - - // Gets dimensions - bool isFinite() const { return true; } - bool isEmpty() const; - Bbox bbox() const; - -private: - Polyhedron* poly; - -}; // end class Scene_polyhedron_item - -#endif // SCENE_POLYHEDRON_ITEM_H diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/Viewer.cpp cgal-4.5/demo/Surface_reconstruction_points_3/Viewer.cpp --- cgal-4.4/demo/Surface_reconstruction_points_3/Viewer.cpp 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/Viewer.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,92 +0,0 @@ -#include "Viewer.h" -#include "Scene_draw_interface.h" - -Viewer::Viewer(QWidget* parent, bool antialiasing) - : QGLViewer(parent), - scene(0), - antialiasing(antialiasing), - twosides(false), - m_isInitialized(false) -{ - setBackgroundColor(::Qt::white); -} - -void Viewer::setScene(Scene_draw_interface* scene) -{ - this->scene = scene; -} - -void Viewer::setAntiAliasing(bool b) -{ - antialiasing = b; - if(m_isInitialized) - updateGL(); -} - -void Viewer::setTwoSides(bool b) -{ - twosides = b; - if(m_isInitialized) - updateGL(); -} - -void Viewer::draw() -{ - draw_aux(false); -} - -void Viewer::initializeGL() -{ - m_isInitialized = true; - QGLViewer::initializeGL(); - scene->initializeGL(); -} - -void Viewer::draw_aux(bool with_names) -{ - QGLViewer::draw(); - if(scene == 0) - return; - - ::glLineWidth(1.0f); - ::glPointSize(2.f); - ::glEnable(GL_POLYGON_OFFSET_FILL); - ::glPolygonOffset(1.0f,1.0f); - ::glClearColor(1.0f,1.0f,1.0f,0.0f); - ::glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); - - if(twosides) - ::glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); - else - ::glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); - - if(antiAliasing()) - { - ::glEnable(GL_BLEND); - ::glEnable(GL_LINE_SMOOTH); - ::glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); - ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } - else - { - ::glDisable(GL_BLEND); - ::glDisable(GL_LINE_SMOOTH); - ::glDisable(GL_POLYGON_SMOOTH_HINT); - ::glBlendFunc(GL_ONE, GL_ZERO); - ::glHint(GL_LINE_SMOOTH_HINT, GL_FASTEST); - } - if(with_names) - scene->drawWithNames(); - else - scene->draw(); -} - -void Viewer::drawWithNames() -{ - draw_aux(true); -} - -void Viewer::postSelection(const QPoint&) -{ - emit selected(this->selectedName()); -} diff -Nru cgal-4.4/demo/Surface_reconstruction_points_3/Viewer.h cgal-4.5/demo/Surface_reconstruction_points_3/Viewer.h --- cgal-4.4/demo/Surface_reconstruction_points_3/Viewer.h 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Surface_reconstruction_points_3/Viewer.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,43 +0,0 @@ -#ifndef VIEWER_H -#define VIEWER_H - -#include - -// forward declarations -class QWidget; -class Scene_draw_interface; - -class Viewer : public QGLViewer { - - Q_OBJECT - -public: - Viewer(QWidget * parent, bool antialiasing = false); - - // overload several QGLViewer virtual functions - void draw(); - void initializeGL(); - void drawWithNames(); - void postSelection(const QPoint&); - - void setScene(Scene_draw_interface* scene); - bool antiAliasing() const { return antialiasing; } - -signals: - void selected(int); - -public slots: - void setAntiAliasing(bool b); - void setTwoSides(bool b); - -private: - void draw_aux(bool with_names); - - Scene_draw_interface* scene; - bool antialiasing; - bool twosides; - bool m_isInitialized; - -}; // end class Viewer - -#endif // VIEWER_H diff -Nru cgal-4.4/demo/Triangulation_3/CMakeLists.txt cgal-4.5/demo/Triangulation_3/CMakeLists.txt --- cgal-4.4/demo/Triangulation_3/CMakeLists.txt 2013-02-23 20:00:18.000000000 +0000 +++ cgal-4.5/demo/Triangulation_3/CMakeLists.txt 2014-08-29 13:58:17.000000000 +0000 @@ -27,6 +27,28 @@ find_package(QGLViewer) endif(QT4_FOUND) +# Activate concurrency ? (turned OFF by default) +option(ACTIVATE_CONCURRENT_TRIANGULATION_3 + "Activate parallelism in Triangulation_3" + OFF) + +# And add -DCGAL_CONCURRENT_TRIANGULATION_3 if that option is ON +if( ACTIVATE_CONCURRENT_TRIANGULATION_3 ) + add_definitions( -DCGAL_CONCURRENT_TRIANGULATION_3 ) + find_package( TBB REQUIRED ) +else( ACTIVATE_CONCURRENT_TRIANGULATION_3 ) + option( LINK_WITH_TBB + "Link with TBB anyway so we can use TBB timers for profiling" + ON) + if( LINK_WITH_TBB ) + find_package( TBB ) + endif( LINK_WITH_TBB ) +endif() + +if( TBB_FOUND ) + include(${TBB_USE_FILE}) +endif() + if ( CGAL_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND ) include(${QT_USE_FILE}) @@ -53,7 +75,7 @@ add_to_cached_list( CGAL_EXECUTABLE_TARGETS T3_demo ) target_link_libraries( T3_demo ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES}) - target_link_libraries( T3_demo ${QT_LIBRARIES} ${QGLVIEWER_LIBRARIES} ) + target_link_libraries( T3_demo ${QT_LIBRARIES} ${QGLVIEWER_LIBRARIES} ${TBB_LIBRARIES}) target_link_libraries( T3_demo ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ) else( CGAL_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND ) diff -Nru cgal-4.4/demo/Triangulation_3/Scene.cpp cgal-4.5/demo/Triangulation_3/Scene.cpp --- cgal-4.4/demo/Triangulation_3/Scene.cpp 2012-12-22 20:00:18.000000000 +0000 +++ cgal-4.5/demo/Triangulation_3/Scene.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -36,6 +36,14 @@ /* Insert the points to build a Delaunay triangulation */ /* Note: this function returns the number of inserted points; it is not guaranteed to insert the points following the order of iteraror. */ +#ifdef CGAL_CONCURRENT_TRIANGULATION_3 + // To define the max number of threads TBB can use + //tbb::task_scheduler_init init(10); + + Lock_ds locking_ds(CGAL::Bbox_3(-1.,-1.,-1.,1,1,1), 50); + m_dt.set_lock_data_structure(&locking_ds); +#endif + m_dt.insert( pts.begin(), pts.end() ); /* Check the combinatorial validity of the triangulation */ /* Note: when it is set to be true, diff -Nru cgal-4.4/demo/Triangulation_3/typedefs.h cgal-4.5/demo/Triangulation_3/typedefs.h --- cgal-4.4/demo/Triangulation_3/typedefs.h 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Triangulation_3/typedefs.h 2014-08-29 13:58:17.000000000 +0000 @@ -1,6 +1,8 @@ #ifndef TYPEDEFS_H #define TYPEDEFS_H +#define CGAL_CONCURRENT_TRIANGULATION_3_PROFILING + #include //dynamic array #include //linked list @@ -32,12 +34,15 @@ /* * The user has several ways to add his own data in the vertex - * and cell base classes used by the TDS. He can either: * 1. use the classes Triangulation vertex base with info + * and cell base classes used by the TDS. He can either: + * 1. use the classes Triangulation vertex base with info * and Triangulation cell base with info, which allow to - * add one data member of a user provided type, and give access to it. * 2. derive his own classes from the default base classes + * add one data member of a user provided type, and give access to it. + * 2. derive his own classes from the default base classes * Triangulation ds vertex base, and Triangulation ds cell base * (or the geometric versions typically used by the geometric layer, - * Triangulation vertex base, and Triangulation cell base). * 3. write his own base classes following the requirements given by the concepts + * Triangulation vertex base, and Triangulation cell base). + * 3. write his own base classes following the requirements given by the concepts * TriangulationCellBase 3 and TriangulationVertexBase 3 * (described in page 2494 and page 2495). */ @@ -69,7 +74,6 @@ bool m_isSelected; // whether it is selected }; -typedef CGAL::Triangulation_data_structure_3< Vertex_base > Tds; /* * Delaunay_triangulation_3 * arg1: a model of the DelaunayTriangulationTraits_3 concept @@ -81,7 +85,21 @@ * Compact_location saves memory by avoiding the separate data structure * and point location is then O(n^(1/3)) time */ -typedef CGAL::Delaunay_triangulation_3 DT3; +#ifdef CGAL_CONCURRENT_TRIANGULATION_3 +typedef CGAL::Spatial_lock_grid_3< + CGAL::Tag_priority_blocking> Lock_ds; +typedef CGAL::Triangulation_data_structure_3< + Vertex_base, + CGAL::Triangulation_ds_cell_base_3<>, + CGAL::Parallel_tag > Tds; +typedef CGAL::Delaunay_triangulation_3< + Kernel, Tds, CGAL::Default, Lock_ds> DT3; + +#else +typedef CGAL::Triangulation_data_structure_3< Vertex_base > Tds; +typedef CGAL::Delaunay_triangulation_3< + Kernel, Tds/*, CGAL::Fast_location*/> DT3; +#endif typedef DT3::Object Object_3; typedef DT3::Point Point_3; diff -Nru cgal-4.4/demo/Triangulation_3/Viewer.cpp cgal-4.5/demo/Triangulation_3/Viewer.cpp --- cgal-4.4/demo/Triangulation_3/Viewer.cpp 2013-02-23 20:00:18.000000000 +0000 +++ cgal-4.5/demo/Triangulation_3/Viewer.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -69,7 +69,19 @@ tr("Cancel insertion in Input-Point mode;
") + tr("Cancel current selection in Select mode") ); setKeyDescription( Qt::Key_Delete, tr("Delete selected vertices in Select mode") ); - +#if QGLVIEWER_VERSION >= 0x020500 + setMouseBindingDescription(Qt::NoModifier, Qt::LeftButton, + tr("Hold to move new point in Input-Point mode;
") + + tr("Hold to move a vertex in Move mode") ); + setMouseBindingDescription(Qt::ShiftModifier, Qt::LeftButton, + tr("Click to insert a vertex in Input-Vertex mode;
") + + tr("Click to insert a point in Input-Point mode;
") + + tr("Click or Drag to select multiple points in Select mode;
") + + tr("Click to place a query point in Find-Nearest-Neighbor mode;
") + + tr("Click to place a query point in Show-Empty-Sphere mode") ); + setMouseBindingDescription(Qt::ControlModifier, Qt::LeftButton, + tr("Drag to add vertices to current selection in Select mode") ); +#else setMouseBindingDescription( Qt::LeftButton, tr("Hold to move new point in Input-Point mode;
") + tr("Hold to move a vertex in Move mode") ); @@ -81,6 +93,7 @@ + tr("Click to place a query point in Show-Empty-Sphere mode") ); setMouseBindingDescription( Qt::CTRL + Qt::LeftButton, tr("Drag to add vertices to current selection in Select mode") ); +#endif } QString Viewer::helpString() const @@ -979,8 +992,8 @@ // note: most mouse types work in steps of 15 degrees // positive value: rotate forwards away from the user; // negative value: rotate backwards toward the user. - m_fRadius += (event->delta()*1. / m_iStep ); // inc-/decrease by 0.1 per step - if( m_fRadius < 0.1 ) + m_fRadius += (event->delta()*1.f / m_iStep ); // inc-/decrease by 0.1 per step + if( m_fRadius < 0.1f ) m_fRadius = 0.1f; // redraw @@ -993,8 +1006,8 @@ // positive value: rotate forwards away from the user; // negative value: rotate backwards toward the user. float origR = m_fRadius; - m_fRadius += (event->delta()*1. / m_iStep ); // inc-/decrease by 0.1 per step - if( m_fRadius < 0.1 ) + m_fRadius += (event->delta()*1.f / m_iStep ); // inc-/decrease by 0.1 per step + if( m_fRadius < 0.1f ) m_fRadius = 0.1f; // update the new point and its conflict region if( m_hasNewPt ) { @@ -1011,8 +1024,8 @@ // resize the trackball when moving a point else if( m_curMode == MOVE && modifiers == Qt::SHIFT && m_isMoving ) { float origR = m_fRadius; - m_fRadius += (event->delta()*1. / m_iStep ); // inc-/decrease by 0.1 per step - if( m_fRadius < 0.1 ) + m_fRadius += (event->delta()*1.f / m_iStep ); // inc-/decrease by 0.1 per step + if( m_fRadius < 0.1f ) m_fRadius = 0.1f; origR = m_fRadius / origR; Point_3 pt = m_pScene->m_vhArray.at( m_vidMoving )->point(); diff -Nru cgal-4.4/demo/Triangulation_3_Geomview_demos/Triangulation_3_voronoi_demo.cpp cgal-4.5/demo/Triangulation_3_Geomview_demos/Triangulation_3_voronoi_demo.cpp --- cgal-4.4/demo/Triangulation_3_Geomview_demos/Triangulation_3_voronoi_demo.cpp 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/demo/Triangulation_3_Geomview_demos/Triangulation_3_voronoi_demo.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -34,7 +34,7 @@ #include #include -#include +#include #include @@ -45,7 +45,7 @@ typedef CGAL::Exact_predicates_exact_constructions_kernel K; typedef CGAL::Triangulation_vertex_base_3 Vb; -typedef CGAL::Triangulation_cell_base_with_circumcenter_3 Cb; +typedef CGAL::Delaunay_triangulation_cell_base_with_circumcenter_3 Cb; typedef CGAL::Triangulation_data_structure_3 TDS; typedef CGAL::Delaunay_triangulation_3 Triangulation; // typedef CGAL::Delaunay_triangulation_3 Triangulation; diff -Nru cgal-4.4/examples/AABB_tree/AABB_face_graph_triangle_example.cpp cgal-4.5/examples/AABB_tree/AABB_face_graph_triangle_example.cpp --- cgal-4.4/examples/AABB_tree/AABB_face_graph_triangle_example.cpp 2013-07-27 19:00:33.000000000 +0000 +++ cgal-4.5/examples/AABB_tree/AABB_face_graph_triangle_example.cpp 2014-08-29 13:58:15.000000000 +0000 @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #include #include @@ -15,7 +15,7 @@ typedef K::Point_3 Point; typedef K::Segment_3 Segment; typedef CGAL::Polyhedron_3 Polyhedron; -typedef CGAL::AABB_face_graph_triangle_primitive Primitive; +typedef CGAL::AABB_face_graph_triangle_primitive Primitive; typedef CGAL::AABB_traits Traits; typedef CGAL::AABB_tree Tree; @@ -26,7 +26,7 @@ // constructs the AABB tree and the internal search tree for // efficient distance queries. - Tree tree( graph.facets_begin(), graph.facets_end(), graph); + Tree tree( faces(graph).first, faces(graph).second, graph); tree.accelerate_distance_queries(); // counts #intersections with a triangle query diff -Nru cgal-4.4/examples/AABB_tree/AABB_halfedge_graph_edge_example.cpp cgal-4.5/examples/AABB_tree/AABB_halfedge_graph_edge_example.cpp --- cgal-4.4/examples/AABB_tree/AABB_halfedge_graph_edge_example.cpp 2013-07-27 19:00:33.000000000 +0000 +++ cgal-4.5/examples/AABB_tree/AABB_halfedge_graph_edge_example.cpp 2014-08-29 13:58:15.000000000 +0000 @@ -5,8 +5,7 @@ #include #include #include -#include -#include +#include #include #include #include @@ -28,8 +27,8 @@ // constructs the AABB tree and the internal search tree for // efficient distance queries. - Tree tree( CGAL::undirected_edges(graph).first, - CGAL::undirected_edges(graph).second, graph); + Tree tree( CGAL::edges(graph).first, + CGAL::edges(graph).second, graph); tree.accelerate_distance_queries(); // counts #intersections with a triangle query diff -Nru cgal-4.4/examples/AABB_tree/AABB_insertion_example.cpp cgal-4.5/examples/AABB_tree/AABB_insertion_example.cpp --- cgal-4.4/examples/AABB_tree/AABB_insertion_example.cpp 2013-08-03 19:00:28.000000000 +0000 +++ cgal-4.5/examples/AABB_tree/AABB_insertion_example.cpp 2014-08-29 13:58:15.000000000 +0000 @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include @@ -35,11 +35,11 @@ polyhedron2.make_tetrahedron(p2, q2, r2, s2); // constructs AABB tree and computes internal KD-tree // data structure to accelerate distance queries - Tree tree(polyhedron1.facets_begin(),polyhedron1.facets_end(), polyhedron1); + Tree tree(faces(polyhedron1).first, faces(polyhedron1).second, polyhedron1); tree.accelerate_distance_queries(); - tree.insert(polyhedron2.facets_begin(),polyhedron2.facets_end(), polyhedron2); + tree.insert(faces(polyhedron2).first, faces(polyhedron2).second, polyhedron2); // query point Point query(0.0, 0.0, 3.0); diff -Nru cgal-4.4/examples/AABB_tree/AABB_polyhedron_edge_example.cpp cgal-4.5/examples/AABB_tree/AABB_polyhedron_edge_example.cpp --- cgal-4.4/examples/AABB_tree/AABB_polyhedron_edge_example.cpp 2013-08-03 19:00:28.000000000 +0000 +++ cgal-4.5/examples/AABB_tree/AABB_polyhedron_edge_example.cpp 2014-08-29 13:58:15.000000000 +0000 @@ -5,10 +5,8 @@ #include #include #include -#include +#include #include -#include -#include typedef CGAL::Simple_cartesian K; typedef K::FT FT; @@ -30,8 +28,8 @@ // constructs the AABB tree and the internal search tree for // efficient distance queries. - Tree tree( CGAL::undirected_edges(polyhedron).first, - CGAL::undirected_edges(polyhedron).second, + Tree tree( CGAL::edges(polyhedron).first, + CGAL::edges(polyhedron).second, polyhedron); tree.accelerate_distance_queries(); diff -Nru cgal-4.4/examples/AABB_tree/AABB_polyhedron_facet_distance_example.cpp cgal-4.5/examples/AABB_tree/AABB_polyhedron_facet_distance_example.cpp --- cgal-4.4/examples/AABB_tree/AABB_polyhedron_facet_distance_example.cpp 2013-08-03 19:00:28.000000000 +0000 +++ cgal-4.5/examples/AABB_tree/AABB_polyhedron_facet_distance_example.cpp 2014-08-29 13:58:15.000000000 +0000 @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include typedef CGAL::Simple_cartesian K; @@ -30,7 +30,7 @@ // constructs AABB tree and computes internal KD-tree // data structure to accelerate distance queries - Tree tree(polyhedron.facets_begin(),polyhedron.facets_end(),polyhedron); + Tree tree(faces(polyhedron).first, faces(polyhedron).second, polyhedron); tree.accelerate_distance_queries(); // query point diff -Nru cgal-4.4/examples/AABB_tree/AABB_polyhedron_facet_intersection_example.cpp cgal-4.5/examples/AABB_tree/AABB_polyhedron_facet_intersection_example.cpp --- cgal-4.4/examples/AABB_tree/AABB_polyhedron_facet_intersection_example.cpp 2013-08-03 19:00:28.000000000 +0000 +++ cgal-4.5/examples/AABB_tree/AABB_polyhedron_facet_intersection_example.cpp 2014-08-29 13:58:15.000000000 +0000 @@ -5,8 +5,8 @@ #include #include #include +#include #include -#include typedef CGAL::Simple_cartesian K; typedef K::Point_3 Point; @@ -31,7 +31,7 @@ polyhedron.make_tetrahedron(p, q, r, s); // constructs AABB tree - Tree tree(polyhedron.facets_begin(),polyhedron.facets_end(),polyhedron); + Tree tree(faces(polyhedron).first, faces(polyhedron).second, polyhedron); // constructs segment query Point a(-0.2, 0.2, -0.2); diff -Nru cgal-4.4/examples/Arrangement_on_surface_2/algebraic_segments.cpp cgal-4.5/examples/Arrangement_on_surface_2/algebraic_segments.cpp --- cgal-4.4/examples/Arrangement_on_surface_2/algebraic_segments.cpp 2012-11-13 13:13:53.000000000 +0000 +++ cgal-4.5/examples/Arrangement_on_surface_2/algebraic_segments.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -1,4 +1,5 @@ -#include +#include +#include #include #if (!CGAL_USE_CORE) && (!CGAL_USE_LEDA) && (!(CGAL_USE_GMP && CGAL_USE_MPFI)) @@ -64,7 +65,7 @@ for(size_t i = 0; i < pre_segs.size(); i++ ) { X_monotone_curve_2 curr; bool check = CGAL::assign(curr,pre_segs[i]); - assert(check); + assert(check); CGAL_USE(check); segs.push_back(curr); } // Construct an ellipse with equation 2*x^2+5*y^2-7=0 diff -Nru cgal-4.4/examples/Arrangement_on_surface_2/bgl_primal_adapter.cpp cgal-4.5/examples/Arrangement_on_surface_2/bgl_primal_adapter.cpp --- cgal-4.4/examples/Arrangement_on_surface_2/bgl_primal_adapter.cpp 2013-02-23 20:00:17.000000000 +0000 +++ cgal-4.5/examples/Arrangement_on_surface_2/bgl_primal_adapter.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -8,14 +8,9 @@ #include #include -#include -#include +#include -#if BOOST_VERSION > 104000 -#include -#else -#include -#endif +#include typedef CGAL::Cartesian Kernel; typedef CGAL::Arr_segment_traits_2 Traits_2; diff -Nru cgal-4.4/examples/Arrangement_on_surface_2/global_removal.cpp cgal-4.5/examples/Arrangement_on_surface_2/global_removal.cpp --- cgal-4.4/examples/Arrangement_on_surface_2/global_removal.cpp 2012-11-13 13:13:53.000000000 +0000 +++ cgal-4.5/examples/Arrangement_on_surface_2/global_removal.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -2,7 +2,7 @@ // Using the global removal functions. #include -#include +#include #include #include @@ -10,7 +10,7 @@ typedef int Number_type; typedef CGAL::Cartesian Kernel; -typedef CGAL::Arr_segment_traits_2 Traits_2; +typedef CGAL::Arr_linear_traits_2 Traits_2; typedef Traits_2::Point_2 Point_2; typedef Traits_2::X_monotone_curve_2 Segment_2; typedef CGAL::Arrangement_2 Arrangement_2; @@ -22,28 +22,24 @@ { // Create an arrangement of four line segments forming an H-shape: Arrangement_2 arr; - Naive_pl pl (arr); - Segment_2 s1 (Point_2 (1, 3), Point_2 (4, 3)); - Halfedge_handle e1 = arr.insert_in_face_interior (s1, arr.unbounded_face()); - Segment_2 s2 (Point_2 (1, 4), Point_2 (4, 4)); - Halfedge_handle e2 = arr.insert_in_face_interior (s2, arr.unbounded_face()); - Segment_2 s3 (Point_2 (1, 1), Point_2 (1, 6)); - Segment_2 s4 (Point_2 (4, 1), Point_2 (4, 6)); - - insert (arr, s3, pl); - insert (arr, s4, pl); + Segment_2 s1 (Point_2(1, 3), Point_2(4, 3)); + Halfedge_handle e1 = arr.insert_in_face_interior (s1, arr.unbounded_face()); + Segment_2 s2 (Point_2(1, 4), Point_2(4, 4)); + Halfedge_handle e2 = arr.insert_in_face_interior (s2, arr.unbounded_face()); + insert(arr, Segment_2(Point_2(1, 1), Point_2(1, 6))); + insert(arr, Segment_2(Point_2(4, 1), Point_2(4, 6))); std::cout << "The initial arrangement:" << std::endl; print_arrangement (arr); - // Remove the horizontal edge from the arrangement, and its end vertices: + // Remove e1 and its incident vertices using the function remove_edge(). Vertex_handle v1 = e1->source(), v2 = e1->target(); - arr.remove_edge (e1); - remove_vertex (arr, v1); - remove_vertex (arr, v2); + arr.remove_edge(e1); + remove_vertex(arr, v1); + remove_vertex(arr, v2); - // Remove the second horizontal edge e2 from the arrangement: + // Remove e2 using the free remove_edge() function. remove_edge (arr, e2); std::cout << "The final arrangement:" << std::endl; diff -Nru cgal-4.4/examples/Arrangement_on_surface_2/spherical_insert.cpp cgal-4.5/examples/Arrangement_on_surface_2/spherical_insert.cpp --- cgal-4.4/examples/Arrangement_on_surface_2/spherical_insert.cpp 2012-11-13 13:13:53.000000000 +0000 +++ cgal-4.5/examples/Arrangement_on_surface_2/spherical_insert.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -1,14 +1,14 @@ //! \file examples/Arrangement_on_surface_2/aggregated_insertion.cpp // Using the global aggregated insertion functions. -#include +#include #include #include #include #include #include -typedef CGAL::Gmpq Number_type; +typedef CGAL::Exact_rational Number_type; typedef CGAL::Cartesian Kernel; typedef CGAL::Arr_geodesic_arc_on_sphere_traits_2 Geom_traits_2; typedef Geom_traits_2::Point_2 Point_2; diff -Nru cgal-4.4/examples/BGL_arrangement_2/primal.cpp cgal-4.5/examples/BGL_arrangement_2/primal.cpp --- cgal-4.4/examples/BGL_arrangement_2/primal.cpp 2013-02-23 20:00:17.000000000 +0000 +++ cgal-4.5/examples/BGL_arrangement_2/primal.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -8,14 +8,9 @@ #include #include -#include -#include +#include -#if BOOST_VERSION > 104000 -#include -#else -#include -#endif +#include typedef CGAL::Cartesian Kernel; typedef CGAL::Arr_segment_traits_2 Traits_2; diff -Nru cgal-4.4/examples/BGL_polyhedron_3/CMakeLists.txt cgal-4.5/examples/BGL_polyhedron_3/CMakeLists.txt --- cgal-4.4/examples/BGL_polyhedron_3/CMakeLists.txt 2014-04-03 19:01:52.000000000 +0000 +++ cgal-4.5/examples/BGL_polyhedron_3/CMakeLists.txt 2014-10-09 19:00:26.000000000 +0000 @@ -24,8 +24,12 @@ include_directories (BEFORE "../../include") create_single_source_cgal_program( "distance.cpp" ) + create_single_source_cgal_program( "incident_vertices.cpp" ) create_single_source_cgal_program( "kruskal.cpp" ) create_single_source_cgal_program( "kruskal_with_stored_id.cpp" ) + create_single_source_cgal_program( "normals.cpp" ) + create_single_source_cgal_program( "range.cpp" ) + create_single_source_cgal_program( "transform_iterator.cpp" ) else() diff -Nru cgal-4.4/examples/BGL_polyhedron_3/distance.cmd cgal-4.5/examples/BGL_polyhedron_3/distance.cmd --- cgal-4.4/examples/BGL_polyhedron_3/distance.cmd 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/examples/BGL_polyhedron_3/distance.cmd 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1 @@ +cube.off diff -Nru cgal-4.4/examples/BGL_polyhedron_3/distance.cpp cgal-4.5/examples/BGL_polyhedron_3/distance.cpp --- cgal-4.4/examples/BGL_polyhedron_3/distance.cpp 2013-09-14 19:00:19.000000000 +0000 +++ cgal-4.5/examples/BGL_polyhedron_3/distance.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -3,7 +3,6 @@ #include #include #include -#include #include @@ -18,12 +17,10 @@ -int main() { +int main(int, char** argv) { - Polyhedron P; - - std::ifstream in("cube.off"); - + Polyhedron P; + std::ifstream in(argv[1]); in >> P ; // associate indices to the vertices using the "id()" field of the vertex. @@ -32,7 +29,7 @@ // boost::tie assigns the first and second element of the std::pair // returned by boost::vertices to the variables vit and ve - for(boost::tie(vb,ve)=boost::vertices(P); vb!=ve; ++vb ){ + for(boost::tie(vb,ve)=vertices(P); vb!=ve; ++vb ){ vertex_descriptor vd = *vb; vd->id() = index++; } @@ -43,7 +40,7 @@ // Here we start at an arbitrary vertex // Any other vertex could be the starting point - boost::tie(vb,ve)=boost::vertices(P); + boost::tie(vb,ve)=vertices(P); vertex_descriptor vd = *vb; std::cout << "We compute distances to " << vd->point() << std::endl; @@ -60,7 +57,7 @@ // Traverse all vertices and show at what distance they are - for(boost::tie(vb,ve)=boost::vertices(P); vb!=ve; ++vb ){ + for(boost::tie(vb,ve)=vertices(P); vb!=ve; ++vb ){ vd = *vb; std::cout << vd->point() << " is " << distance[vd->id()] << " hops away" << std::endl; } diff -Nru cgal-4.4/examples/BGL_polyhedron_3/incident_vertices.cmd cgal-4.5/examples/BGL_polyhedron_3/incident_vertices.cmd --- cgal-4.4/examples/BGL_polyhedron_3/incident_vertices.cmd 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/examples/BGL_polyhedron_3/incident_vertices.cmd 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1 @@ +cube.off diff -Nru cgal-4.4/examples/BGL_polyhedron_3/incident_vertices.cpp cgal-4.5/examples/BGL_polyhedron_3/incident_vertices.cpp --- cgal-4.4/examples/BGL_polyhedron_3/incident_vertices.cpp 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/examples/BGL_polyhedron_3/incident_vertices.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,61 @@ +#include +#include +#include +#include +#include +#include +#include + + +typedef CGAL::Simple_cartesian Kernel; +typedef CGAL::Polyhedron_3 Polyhedron; + +typedef boost::graph_traits GraphTraits; +typedef GraphTraits::vertex_descriptor vertex_descriptor; +typedef CGAL::Halfedge_around_target_iterator halfedge_around_target_iterator; + +template +OutputIterator +adjacent_vertices_V1(const Polyhedron& g, + vertex_descriptor vd, + OutputIterator out) +{ + typename GraphTraits::halfedge_descriptor hb = halfedge(vd,g), done(hb); + do { + *out++ = source(hb,g); + hb = opposite(next(hb,g),g); + } while(hb!= done); + + return out; +} + + +template +OutputIterator +adjacent_vertices_V2(const Polyhedron& g, + vertex_descriptor vd, + OutputIterator out) +{ + halfedge_around_target_iterator hi, he; + + for(boost::tie(hi, he) = halfedges_around_target(halfedge(vd,g),g); hi != he; ++hi) + { + *out++ = source(*hi,g); + } + return out; +} + + +int main(int, char** argv) +{ + std::ifstream in(argv[1]); + Polyhedron P; + in >> P; + GraphTraits::vertex_iterator vi = vertices(P).first; + std::list V; + adjacent_vertices_V1(P, *vi, std::back_inserter(V)); + ++vi; + adjacent_vertices_V2(P, *vi, std::back_inserter(V)); + std::cerr << "done\n"; + return 0; +} diff -Nru cgal-4.4/examples/BGL_polyhedron_3/kruskal.cpp cgal-4.5/examples/BGL_polyhedron_3/kruskal.cpp --- cgal-4.4/examples/BGL_polyhedron_3/kruskal.cpp 2013-09-14 19:00:19.000000000 +0000 +++ cgal-4.5/examples/BGL_polyhedron_3/kruskal.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -2,7 +2,6 @@ #include #include #include -#include #include #include @@ -22,82 +21,79 @@ // The BGL makes heavy use of indices associated to the vertices // We use a std::map to store the index -typedef std::map VertexIndexMap; -VertexIndexMap vertex_id_map; +typedef std::map Vertex_index_map; +Vertex_index_map vertex_index_map; // A std::map is not a property map, because it is not lightweight -typedef boost::associative_property_map VertexIdPropertyMap; -VertexIdPropertyMap vertex_index_pmap(vertex_id_map); +typedef boost::associative_property_map Vertex_index_pmap; +Vertex_index_pmap vertex_index_pmap(vertex_index_map); void kruskal(const Polyhedron& P) { // associate indices to the vertices - { - vertex_iterator vb, ve; - int index = 0; - - // boost::tie assigns the first and second element of the std::pair - // returned by boost::vertices to the variables vit and ve - for(boost::tie(vb,ve)=boost::vertices(P); vb!=ve; ++vb ){ - vertex_descriptor vd = *vb; - vertex_id_map[vd]= index++; - } + vertex_iterator vb, ve; + int index = 0; + + // boost::tie assigns the first and second element of the std::pair + // returned by boost::vertices to the variables vb and ve + for(boost::tie(vb, ve)=vertices(P); vb!=ve; ++vb){ + vertex_index_pmap[*vb]= index++; } + // We use the default edge weight which is the squared length of the edge // This property map is defined in graph_traits_Polyhedron_3.h // In the function call you can see a named parameter: vertex_index_map - std::list mst; + std::list mst; + + boost::kruskal_minimum_spanning_tree(P, + std::back_inserter(mst), + boost::vertex_index_map(vertex_index_pmap)); + + std::cout << "#VRML V2.0 utf8\n" + "Shape {\n" + " appearance Appearance {\n" + " material Material { emissiveColor 1 0 0}}\n" + " geometry\n" + " IndexedLineSet {\n" + " coord Coordinate {\n" + " point [ \n"; + + for(boost::tie(vb, ve) = vertices(P); vb!=ve; ++vb){ + std::cout << " " << (*vb)->point() << "\n"; + } + + std::cout << " ]\n" + " }\n" + " coordIndex [\n"; + + for(std::list::iterator it = mst.begin(); it != mst.end(); ++it) + { + edge_descriptor e = *it ; + vertex_descriptor s = source(e,P); + vertex_descriptor t = target(e,P); + std::cout << " " << vertex_index_pmap[s] << ", " << vertex_index_pmap[t] << ", -1\n"; + } - boost::kruskal_minimum_spanning_tree(P, - std::back_inserter(mst), - boost::vertex_index_map(vertex_index_pmap) ); - - std::cout << "#VRML V2.0 utf8\n" - "Shape {\n" - "appearance Appearance {\n" - "material Material { emissiveColor 1 0 0}}\n" - "geometry\n" - "IndexedLineSet {\n" - "coord Coordinate {\n" - "point [ \n"; - - vertex_iterator vb, ve; - for(boost::tie(vb,ve) = boost::vertices(P); vb!=ve; ++vb){ - std::cout << (*vb)->point() << "\n"; - } - - std::cout << "]\n" - "}\n" - "coordIndex [\n"; - - for(std::list::iterator it = mst.begin(); it != mst.end(); ++it) - { - edge_descriptor e = *it ; - vertex_descriptor s = boost::source(e,P); - vertex_descriptor t = boost::target(e,P); - std::cout << vertex_id_map[s] << ", " << vertex_id_map[t] << ", -1\n"; - } - - std::cout << "]\n" - "}#IndexedLineSet\n" - "}# Shape\n"; + std::cout << "]\n" + " }#IndexedLineSet\n" + "}# Shape\n"; } int main() { - Polyhedron P; - Point a(1,0,0); - Point b(0,1,0); - Point c(0,0,1); - Point d(0,0,0); + Polyhedron P; + Point a(1,0,0); + Point b(0,1,0); + Point c(0,0,1); + Point d(0,0,0); - P.make_tetrahedron(a,b,c,d); + P.make_tetrahedron(a,b,c,d); - kruskal(P); + kruskal(P); - return 0; + return 0; } diff -Nru cgal-4.4/examples/BGL_polyhedron_3/kruskal_with_stored_id.cpp cgal-4.5/examples/BGL_polyhedron_3/kruskal_with_stored_id.cpp --- cgal-4.4/examples/BGL_polyhedron_3/kruskal_with_stored_id.cpp 2013-09-14 19:00:19.000000000 +0000 +++ cgal-4.5/examples/BGL_polyhedron_3/kruskal_with_stored_id.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -3,7 +3,6 @@ #include #include #include -#include #include #include @@ -29,7 +28,7 @@ // This function call requires a vertex_index_map named parameter which // when ommitted defaults to "get(vertex_index,graph)". - // That default works here because the vertex type supports the "id()" + // That default works here because the vertex type has an "id()" method // field which is used by the vertex_index internal property. std::list mst; boost::kruskal_minimum_spanning_tree(P,std::back_inserter(mst)); @@ -44,7 +43,7 @@ "point [ \n"; vertex_iterator vb, ve; - for(boost::tie(vb,ve) = boost::vertices(P); vb!=ve; ++vb){ + for(boost::tie(vb,ve) = vertices(P); vb!=ve; ++vb){ std::cout << (*vb)->point() << "\n"; } @@ -53,8 +52,8 @@ "coordIndex [\n"; for(std::list::iterator it = mst.begin(); it != mst.end(); ++it){ - std::cout << boost::source(*it,P)->id() - << ", " << boost::target(*it,P)->id() << ", -1\n"; + std::cout << source(*it,P)->id() + << ", " << target(*it,P)->id() << ", -1\n"; } std::cout << "]\n" @@ -80,7 +79,7 @@ // boost::tie assigns the first and second element of the std::pair // returned by boost::vertices to the variables vit and ve - for(boost::tie(vb,ve)=boost::vertices(P); vb!=ve; ++vb ){ + for(boost::tie(vb,ve)=vertices(P); vb!=ve; ++vb ){ vertex_descriptor vd = *vb; vd->id() = index++; } diff -Nru cgal-4.4/examples/BGL_polyhedron_3/normals.cmd cgal-4.5/examples/BGL_polyhedron_3/normals.cmd --- cgal-4.4/examples/BGL_polyhedron_3/normals.cmd 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/examples/BGL_polyhedron_3/normals.cmd 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1 @@ +cube.off diff -Nru cgal-4.4/examples/BGL_polyhedron_3/normals.cpp cgal-4.5/examples/BGL_polyhedron_3/normals.cpp --- cgal-4.4/examples/BGL_polyhedron_3/normals.cpp 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/examples/BGL_polyhedron_3/normals.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,109 @@ +#include + +#include +#include + +#include +#include + +// Polyhedron +#include +#include +#include +#include + +// Graph traits adaptors +#include + +typedef CGAL::Cartesian Kernel; +typedef Kernel::Point_3 Point; +typedef Kernel::Vector_3 Vector; +typedef CGAL::Polyhedron_3 Polyhedron; + +template +void calculate_face_normals(const HalfedgeGraph& g, + PointMap pm, + NormalMap nm) +{ + typedef boost::graph_traits GraphTraits; + typedef typename GraphTraits::face_iterator face_iterator; + typedef typename GraphTraits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::property_traits::value_type point; + typedef typename boost::property_traits::value_type normal; + + face_iterator fb, fe; + for(boost::tie(fb, fe) = faces(g); fb != fe; ++fb) + { + halfedge_descriptor edg = halfedge(*fb, g); + halfedge_descriptor edgb = edg; + + point p0 = pm[target(edg, g)]; + edg = next(edg, g); + point p1 = pm[target(edg, g)]; + edg = next(edg, g); + point p2 = pm[target(edg, g)]; + edg = next(edg, g); + + if(edg == edgb) { + // triangle + nm[*fb] = CGAL::unit_normal(p1, p2, p0); + } else { + // not a triangle + normal n(CGAL::NULL_VECTOR); + + do { + n = n + CGAL::normal(p1, p2, p0); + p0 = p1; + p1 = p2; + + edg = next(edg, g); + p2 = pm[target(edg, g)]; + } while(edg != edgb); + + nm[*fb] = n / CGAL::sqrt(n.squared_length()); + } + } +} + +int main(int, char** argv) +{ + typedef boost::property_map< + Polyhedron, + CGAL::face_index_t + >::const_type Face_index_map; + + std::ifstream in(argv[1]); + Polyhedron P; + in >> P ; + + // initialize facet indices + std::size_t i = 0; + for(Polyhedron::Facet_iterator it = P.facets_begin(); it != P.facets_end(); ++it, ++i) + { + it->id() = i; + } + + // Ad hoc property_map to store normals. Face_index_map is used to + // map face_descriptors to a contiguous range of indices. See + // http://www.boost.org/libs/property_map/doc/vector_property_map.html + // for details. + boost::vector_property_map + normals(get(CGAL::face_index, P)); + + calculate_face_normals( + P // Graph + , get(CGAL::vertex_point, P) // map from vertex_descriptor to point + , normals // map from face_descriptor to Vector_3 + ); + + std::cout << "Normals" << std::endl; + for(Polyhedron::Facet_iterator it = P.facets_begin(); it != P.facets_end(); ++it) { + // Facet_iterator is a face_descriptor, so we can use it as the + // key here + std::cout << normals[it] << std::endl; + } + + return 0; +} diff -Nru cgal-4.4/examples/BGL_polyhedron_3/range.cmd cgal-4.5/examples/BGL_polyhedron_3/range.cmd --- cgal-4.4/examples/BGL_polyhedron_3/range.cmd 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/examples/BGL_polyhedron_3/range.cmd 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1 @@ +cube.off diff -Nru cgal-4.4/examples/BGL_polyhedron_3/range.cpp cgal-4.5/examples/BGL_polyhedron_3/range.cpp --- cgal-4.4/examples/BGL_polyhedron_3/range.cpp 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/examples/BGL_polyhedron_3/range.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,68 @@ +#include +#include +#include +#include +#include +#include + + +#include +#include +#include +#include + + +typedef CGAL::Simple_cartesian Kernel; +typedef CGAL::Polyhedron_3 Polyhedron; + +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef boost::graph_traits::vertex_iterator vertex_iterator; + +typedef CGAL::iterator_range vertex_range; + + +vertex_range vertices_range(const Polyhedron& p) +{ + return vertex_range(vertices(p)); +} + +struct Fct +{ + void operator()(const vertex_descriptor& vd) const + { + std::cout << vd->point() << std::endl; + } +}; + +void fct(const Polyhedron& p) +{ + vertex_range vr(vertices(p)); + +#ifndef CGAL_NO_CPP0X_RANGE_BASED_FOR + std::cout << "new for loop" << std::endl; + for(vertex_descriptor vd : vr){ + std::cout << vd->point() << std::endl; + } +#endif + + std::cout << "BOOST_FOREACH" << std::endl; + BOOST_FOREACH(vertex_descriptor vd, vr){ + std::cout << vd->point() << std::endl; + } + + std::cout << "boost::tie + std::for_each" << std::endl; + vertex_iterator vb, ve; + + boost::tie(vb,ve) = vertices_range(p); + std::for_each(vb,ve, Fct()); +} + +int main(int, char** argv) +{ + Polyhedron P; + std::ifstream in(argv[1]); + in >> P ; + + fct(P); + return 0; +} diff -Nru cgal-4.4/examples/BGL_polyhedron_3/transform_iterator.cmd cgal-4.5/examples/BGL_polyhedron_3/transform_iterator.cmd --- cgal-4.4/examples/BGL_polyhedron_3/transform_iterator.cmd 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/examples/BGL_polyhedron_3/transform_iterator.cmd 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1 @@ +cube.off diff -Nru cgal-4.4/examples/BGL_polyhedron_3/transform_iterator.cpp cgal-4.5/examples/BGL_polyhedron_3/transform_iterator.cpp --- cgal-4.4/examples/BGL_polyhedron_3/transform_iterator.cpp 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/examples/BGL_polyhedron_3/transform_iterator.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,59 @@ +#include +#include +#include +#include +#include +#include + +#include +#include + +typedef CGAL::Simple_cartesian Kernel; +typedef CGAL::Polyhedron_3 Polyhedron; + +typedef boost::graph_traits GraphTraits; +typedef GraphTraits::vertex_descriptor vertex_descriptor; +typedef GraphTraits::halfedge_descriptor halfedge_descriptor; +typedef CGAL::Halfedge_around_target_iterator halfedge_around_target_iterator; + + +template +struct Source { + const G* g; + + Source() + : g(NULL) + {} + + Source(const G& g) + : g(&g) + {} + + typedef typename boost::graph_traits::vertex_descriptor result_type; + typedef typename boost::graph_traits::halfedge_descriptor argument_type; + + result_type operator()(argument_type h) const + { + return source(h, *g); + } +}; + +int main(int, char** argv) +{ + std::ifstream in(argv[1]); + Polyhedron P; + in >> P; + GraphTraits::vertex_descriptor vd = *(vertices(P).first); + + typedef boost::transform_iterator,halfedge_around_target_iterator> adjacent_vertex_iterator; + + halfedge_around_target_iterator hb,he; + boost::tie(hb,he) = halfedges_around_target(halfedge(vd,P),P); + adjacent_vertex_iterator avib, avie; + avib = boost::make_transform_iterator(hb, Source(P)); + avie = boost::make_transform_iterator(he, Source(P)); + + std::list V; + std::copy(avib,avie, std::back_inserter(V)); + return 0; +} diff -Nru cgal-4.4/examples/BGL_triangulation_2/dijkstra.cpp cgal-4.5/examples/BGL_triangulation_2/dijkstra.cpp --- cgal-4.4/examples/BGL_triangulation_2/dijkstra.cpp 2012-11-13 13:13:53.000000000 +0000 +++ cgal-4.5/examples/BGL_triangulation_2/dijkstra.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -2,8 +2,7 @@ #include #include -#include -#include +#include #include typedef CGAL::Exact_predicates_inexact_constructions_kernel K; diff -Nru cgal-4.4/examples/BGL_triangulation_2/dijkstra_with_internal_properties.cpp cgal-4.5/examples/BGL_triangulation_2/dijkstra_with_internal_properties.cpp --- cgal-4.4/examples/BGL_triangulation_2/dijkstra_with_internal_properties.cpp 2012-11-13 13:13:53.000000000 +0000 +++ cgal-4.5/examples/BGL_triangulation_2/dijkstra_with_internal_properties.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -3,8 +3,7 @@ #include #include -#include -#include +#include #include typedef CGAL::Exact_predicates_inexact_constructions_kernel K; diff -Nru cgal-4.4/examples/Convex_hull_2/array_convex_hull_2.cpp cgal-4.5/examples/Convex_hull_2/array_convex_hull_2.cpp --- cgal-4.4/examples/Convex_hull_2/array_convex_hull_2.cpp 2012-11-13 13:13:55.000000000 +0000 +++ cgal-4.5/examples/Convex_hull_2/array_convex_hull_2.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -11,6 +11,9 @@ Point_2 result[5]; Point_2 *ptr = CGAL::convex_hull_2( points, points+5, result ); - std::cout << ptr - result << " points on the convex hull" << std::endl; + std::cout << ptr - result << " points on the convex hull:" << std::endl; + for(int i = 0; i < ptr - result; i++){ + std::cout << result[i] << std::endl; + } return 0; } diff -Nru cgal-4.4/examples/Core/CMakeLists.txt cgal-4.5/examples/Core/CMakeLists.txt --- cgal-4.4/examples/Core/CMakeLists.txt 2014-04-03 19:01:52.000000000 +0000 +++ cgal-4.5/examples/Core/CMakeLists.txt 2014-08-29 13:58:16.000000000 +0000 @@ -1,9 +1,6 @@ -# Created by the script cgal_create_cmake_script -# This is the CMake script for compiling a CGAL application. +project( Core_examples ) -project( Core_example ) - cmake_minimum_required(VERSION 2.6.2) if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" VERSION_GREATER 2.6) if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}" VERSION_GREATER 2.8.3) @@ -13,21 +10,48 @@ endif() endif() -find_package(CGAL QUIET COMPONENTS Core ) +set( CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true ) + +if ( COMMAND cmake_policy ) + + cmake_policy( SET CMP0003 NEW ) + +endif() + +# CGAL and its components +find_package( CGAL QUIET COMPONENTS Core ) + +if ( NOT CGAL_Core_FOUND ) + + message(STATUS "This project requires the CGAL_Core library, and will not be compiled.") + return() + +endif() + +# include helper file +include( ${CGAL_USE_FILE} ) -if ( CGAL_FOUND ) - include( ${CGAL_USE_FILE} ) +# Boost and its components +find_package( Boost REQUIRED ) - include( CGAL_CreateSingleSourceCGALProgram ) +if ( NOT Boost_FOUND ) - include_directories (BEFORE "../../include") + message(STATUS "This project requires the Boost library, and will not be compiled.") - create_single_source_cgal_program( "delaunay.cpp" ) + return() -else() - - message(STATUS "This program requires the CGAL library, and will not be compiled.") - endif() +# include for local directory + +# include for local package +include_directories( BEFORE ../../include ) + + +# Creating entries for all .cpp/.C files with "main" routine +# ########################################################## + +include( CGAL_CreateSingleSourceCGALProgram ) + +create_single_source_cgal_program( "delaunay.cpp" ) diff -Nru cgal-4.4/examples/Envelope_2/convex_hull.cpp cgal-4.5/examples/Envelope_2/convex_hull.cpp --- cgal-4.4/examples/Envelope_2/convex_hull.cpp 2012-11-13 13:13:55.000000000 +0000 +++ cgal-4.5/examples/Envelope_2/convex_hull.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -2,7 +2,7 @@ // Compute the convex hull of set of points using the lower envelope and upper // envelopes of their dual line. -#include +#include #include #include #include @@ -10,7 +10,7 @@ #include #include -typedef CGAL::Gmpq Number_type; +typedef CGAL::Exact_rational Number_type; typedef CGAL::Cartesian Kernel; typedef CGAL::Arr_linear_traits_2 Linear_traits_2; typedef Linear_traits_2::Point_2 Point_2; diff -Nru cgal-4.4/examples/Envelope_2/envelope_circles.cpp cgal-4.5/examples/Envelope_2/envelope_circles.cpp --- cgal-4.4/examples/Envelope_2/envelope_circles.cpp 2012-11-13 13:13:55.000000000 +0000 +++ cgal-4.5/examples/Envelope_2/envelope_circles.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -2,14 +2,14 @@ // Constructing the envelopes of a set of circles using the circle-segment // traits. -#include +#include #include #include #include #include #include -typedef CGAL::Gmpq Number_type; +typedef CGAL::Exact_rational Number_type; typedef CGAL::Cartesian Kernel; typedef Kernel::Point_2 Kernel_point_2; typedef Kernel::Circle_2 Circle_2; diff -Nru cgal-4.4/examples/Envelope_2/envelope_segments.cpp cgal-4.5/examples/Envelope_2/envelope_segments.cpp --- cgal-4.4/examples/Envelope_2/envelope_segments.cpp 2012-11-13 13:13:55.000000000 +0000 +++ cgal-4.5/examples/Envelope_2/envelope_segments.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -1,7 +1,7 @@ //! \file examples/Example_2/ex_envelope_segments.cpp // Constructing the lower envelope of a set of segments. -#include +#include #include #include #include @@ -11,7 +11,7 @@ #include #include -typedef CGAL::Gmpq Number_type; +typedef CGAL::Exact_rational Number_type; typedef CGAL::Cartesian Kernel; typedef CGAL::Arr_segment_traits_2 Segment_traits_2; typedef Segment_traits_2::X_monotone_curve_2 Segment_2; diff -Nru cgal-4.4/examples/Envelope_3/envelope_planes.cpp cgal-4.5/examples/Envelope_3/envelope_planes.cpp --- cgal-4.4/examples/Envelope_3/envelope_planes.cpp 2012-11-13 13:13:55.000000000 +0000 +++ cgal-4.5/examples/Envelope_3/envelope_planes.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -1,14 +1,14 @@ //! \file examples/Envelope_3/ex_envelope_planes.cpp // Constructing the lower and the upper envelope of a set of planes. -#include +#include #include #include #include #include #include -typedef CGAL::Gmpq Number_type; +typedef CGAL::Exact_rational Number_type; typedef CGAL::Cartesian Kernel; typedef Kernel::Plane_3 Plane_3; typedef CGAL::Env_plane_traits_3 Traits_3; diff -Nru cgal-4.4/examples/Envelope_3/envelope_triangles.cpp cgal-4.5/examples/Envelope_3/envelope_triangles.cpp --- cgal-4.4/examples/Envelope_3/envelope_triangles.cpp 2012-11-13 13:13:55.000000000 +0000 +++ cgal-4.5/examples/Envelope_3/envelope_triangles.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -1,7 +1,7 @@ //! \file examples/Envelope_3/ex_envelope_triangles.cpp // Constructing the lower and the upper envelope of a set of triangles. -#include +#include #include #include #include @@ -9,7 +9,7 @@ #include #include -typedef CGAL::Gmpq Number_type; +typedef CGAL::Exact_rational Number_type; typedef CGAL::Cartesian Kernel; typedef CGAL::Env_triangle_traits_3 Traits_3; typedef Kernel::Point_3 Point_3; diff -Nru cgal-4.4/examples/Mesh_3/CMakeLists.txt cgal-4.5/examples/Mesh_3/CMakeLists.txt --- cgal-4.4/examples/Mesh_3/CMakeLists.txt 2012-11-13 13:13:57.000000000 +0000 +++ cgal-4.5/examples/Mesh_3/CMakeLists.txt 2014-08-29 13:58:16.000000000 +0000 @@ -28,6 +28,30 @@ include( ${CGAL_USE_FILE} ) find_package(Boost) + # Activate concurrency ? (turned OFF by default) + option(ACTIVATE_CONCURRENT_MESH_3 + "Activate parallelism in Mesh_3" + OFF) + + # And add -DCGAL_CONCURRENT_MESH_3 if that option is ON + if( ACTIVATE_CONCURRENT_MESH_3 OR ENV{ACTIVATE_CONCURRENT_MESH_3} ) + add_definitions( -DCGAL_CONCURRENT_MESH_3 ) + find_package( TBB REQUIRED ) + else( ACTIVATE_CONCURRENT_MESH_3 OR ENV{ACTIVATE_CONCURRENT_MESH_3} ) + option( LINK_WITH_TBB + "Link with TBB anyway so we can use TBB timers for profiling" + ON) + if( LINK_WITH_TBB ) + find_package( TBB ) + endif( LINK_WITH_TBB ) + endif() + + if( TBB_FOUND ) + include(${TBB_USE_FILE}) + list(APPEND CGAL_3RD_PARTY_LIBRARIES ${TBB_LIBRARIES}) + endif() + + if ( Boost_FOUND AND Boost_VERSION GREATER 103400 ) include( CGAL_CreateSingleSourceCGALProgram ) @@ -35,7 +59,10 @@ create_single_source_cgal_program( "mesh_implicit_sphere.cpp" ) create_single_source_cgal_program( "mesh_implicit_sphere_variable_size.cpp" ) create_single_source_cgal_program( "mesh_two_implicit_spheres_with_balls.cpp" ) -# create_single_source_cgal_program( "mesh_implicit_domains.cpp" "implicit_functions.cpp" ) + create_single_source_cgal_program( "mesh_implicit_domains_2.cpp" "implicit_functions.cpp" ) + create_single_source_cgal_program( "mesh_cubes_intersection.cpp" ) + create_single_source_cgal_program( "mesh_cubes_intersection_with_features.cpp" ) + create_single_source_cgal_program( "mesh_implicit_domains.cpp" "implicit_functions.cpp" ) create_single_source_cgal_program( "mesh_polyhedral_domain.cpp" ) create_single_source_cgal_program( "mesh_polyhedral_domain_with_features.cpp" ) if( WITH_CGAL_ImageIO ) diff -Nru cgal-4.4/examples/Mesh_3/data/cheese.off cgal-4.5/examples/Mesh_3/data/cheese.off --- cgal-4.4/examples/Mesh_3/data/cheese.off 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/examples/Mesh_3/data/cheese.off 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,26417 @@ +OFF +8629 17786 0 +0.0313356780 0.0187550001 0.0386509448 +0.0500000007 0.0500000007 0.0500000007 +0.0500000007 0.0500000007 -0.0500000007 +0.0500000007 0.0437499993 0.0125000002 +0.0500000007 0.0437499993 -0.0125000002 +0.0500000007 0.0437499993 -0.0375000015 +0.0500000007 0.0437420011 0.0378109999 +0.0500000007 0.0436200015 0.0362300016 +0.0500000007 0.0435619988 0.0140230004 +0.0500000007 0.0435619988 0.0109770000 +0.0500000007 0.0435619988 -0.0109770000 +0.0500000007 0.0435619988 -0.0140230004 +0.0500000007 0.0435369983 -0.0358819999 +0.0500000007 0.0435369983 -0.0391179994 +0.0500000007 0.0434629992 0.0393720008 +0.0500000007 0.0431029983 0.0347299986 +0.0500000007 0.0430079997 0.0154539999 +0.0500000007 0.0430079997 0.0095459996 +0.0500000007 0.0430079997 -0.0095459996 +0.0500000007 0.0430079997 -0.0154539999 +0.0500000007 0.0429130010 -0.0343750007 +0.0500000007 0.0429130010 -0.0406249985 +0.0500000007 0.0428000018 0.0408129990 +0.0500000007 0.0422249995 0.0334089994 +0.0500000007 0.0421219990 0.0167069994 +0.0500000007 0.0421219990 0.0082930000 +0.0500000007 0.0421219990 -0.0082930000 +0.0500000007 0.0421219990 -0.0167069994 +0.0500000007 0.0419190004 -0.0330809988 +0.0500000007 0.0419190004 -0.0419190004 +0.0500000007 0.0417950004 0.0420400016 +0.0500000007 0.0410429984 0.0323509984 +0.0500000007 0.0409570001 0.0177069996 +0.0500000007 0.0409570001 0.0072929999 +0.0500000007 0.0409570001 -0.0072929999 +0.0500000007 0.0409570001 -0.0177069996 +0.0500000007 0.0406249985 -0.0320869982 +0.0500000007 0.0406249985 -0.0429130010 +0.0500000007 0.0405139998 0.0429750010 +0.0500000007 0.0396329984 0.0316249989 +0.0500000007 0.0395850018 0.0183920003 +0.0500000007 0.0395850018 0.0066080000 +0.0500000007 0.0395850018 -0.0066080000 +0.0500000007 0.0395850018 -0.0183920003 +0.0500000007 0.0391179994 -0.0314630009 +0.0500000007 0.0391179994 -0.0435369983 +0.0500000007 0.0390390009 0.0435580015 +0.0500000007 0.0380860008 0.0312779993 +0.0500000007 0.0380860008 0.0187219996 +0.0500000007 0.0380860008 0.0062779998 +0.0500000007 0.0380860008 -0.0062779998 +0.0500000007 0.0380860008 -0.0187219996 +0.0500000007 0.0380860008 -0.0255469996 +0.0500000007 0.0378339998 -0.0274580009 +0.0500000007 0.0375000015 -0.0312500000 +0.0500000007 0.0375000015 -0.0437499993 +0.0500000007 0.0374649987 0.0437499993 +0.0500000007 0.0370969996 -0.0292380005 +0.0500000007 0.0359239988 -0.0307669993 +0.0500000007 0.0358930007 0.0435400009 +0.0500000007 0.0358819999 -0.0314630009 +0.0500000007 0.0358819999 -0.0435369983 +0.0500000007 0.0344239995 0.0429410003 +0.0500000007 0.0343950018 -0.0319410004 +0.0500000007 0.0343750007 -0.0320869982 +0.0500000007 0.0343750007 -0.0429130010 +0.0500000007 0.0331539996 0.0419909991 +0.0500000007 0.0330809988 -0.0330809988 +0.0500000007 0.0330809988 -0.0419190004 +0.0500000007 0.0326140001 -0.0326780006 +0.0500000007 0.0321630016 0.0407529995 +0.0500000007 0.0320869982 -0.0343750007 +0.0500000007 0.0320869982 -0.0406249985 +0.0500000007 0.0314630009 -0.0358819999 +0.0500000007 0.0314630009 -0.0391179994 +0.0500000007 0.0312500000 -0.0375000015 +0.0500000007 0.0307030007 0.0408979990 +0.0500000007 0.0307030007 -0.0329300016 +0.0500000007 0.0243749991 0.0408979990 +0.0500000007 0.0227719992 0.0407220013 +0.0500000007 0.0212450009 0.0402019992 +0.0500000007 0.0198679995 0.0393630005 +0.0500000007 0.0187170003 -0.0368579999 +0.0500000007 0.0187049992 0.0382449999 +0.0500000007 0.0186919998 -0.0383489989 +0.0500000007 0.0183879994 -0.0354040004 +0.0500000007 0.0183169991 0.0397869982 +0.0500000007 0.0183150005 -0.0397909991 +0.0500000007 0.0177239999 -0.0340690017 +0.0500000007 0.0176069997 -0.0411030017 +0.0500000007 0.0175509993 0.0411810018 +0.0500000007 0.0169920009 0.0331550017 +0.0500000007 0.0169920009 0.0168450009 +0.0500000007 0.0169920009 0.0081550004 +0.0500000007 0.0169920009 -0.0081550004 +0.0500000007 0.0167629998 -0.0329300016 +0.0500000007 0.0166079998 -0.0422100015 +0.0500000007 0.0164589994 0.0423370004 +0.0500000007 0.0160370003 0.0323470011 +0.0500000007 0.0160370003 0.0073469998 +0.0500000007 0.0157960001 0.0178100001 +0.0500000007 0.0157680009 -0.0071720001 +0.0500000007 0.0153759997 -0.0430490002 +0.0500000007 0.0151100000 0.0431790017 +0.0500000007 0.0149400001 0.0317460001 +0.0500000007 0.0149400001 0.0067460001 +0.0500000007 0.0144010000 0.0184540004 +0.0500000007 0.0143370004 -0.0065259999 +0.0500000007 0.0139800003 -0.0435720012 +0.0500000007 0.0137449997 0.0313749984 +0.0500000007 0.0137449997 0.0063749999 +0.0500000007 0.0135920001 0.0436539985 +0.0500000007 0.0128910001 0.0187379997 +0.0500000007 0.0127910003 -0.0062569999 +0.0500000007 0.0125000002 0.0312500000 +0.0500000007 0.0125000002 0.0062500001 +0.0500000007 0.0125000002 -0.0437499993 +0.0500000007 0.0120029999 0.0437299982 +0.0500000007 0.0113570001 0.0186449997 +0.0500000007 0.0112260003 -0.0063809999 +0.0500000007 0.0110200001 -0.0435720012 +0.0500000007 0.0109750004 0.0064389999 +0.0500000007 0.0109219998 0.0314520001 +0.0500000007 0.0104470002 0.0434029996 +0.0500000007 0.0098919999 0.0181799997 +0.0500000007 0.0097420001 -0.0068919999 +0.0500000007 0.0096239997 -0.0430490002 +0.0500000007 0.0095419995 0.0069940002 +0.0500000007 0.0094470000 0.0320460014 +0.0500000007 0.0090229996 0.0426939987 +0.0500000007 0.0085850004 0.0173719991 +0.0500000007 0.0084309997 -0.0077559999 +0.0500000007 0.0083919996 -0.0422100015 +0.0500000007 0.0082879998 0.0078819999 +0.0500000007 0.0082369996 -0.0329300016 +0.0500000007 0.0081690000 0.0329939984 +0.0500000007 0.0078250002 0.0416480005 +0.0500000007 0.0075150002 0.0162700005 +0.0500000007 0.0073930002 -0.0411030017 +0.0500000007 0.0073779998 -0.0089189997 +0.0500000007 0.0072889999 0.0090490002 +0.0500000007 0.0072760000 -0.0340690017 +0.0500000007 0.0071720001 0.0342320018 +0.0500000007 0.0069289999 0.0403329991 +0.0500000007 0.0067460001 0.0149400001 +0.0500000007 0.0066849999 -0.0397909991 +0.0500000007 0.0066470001 -0.0103080003 +0.0500000007 0.0066120001 -0.0354040004 +0.0500000007 0.0066049998 0.0104250005 +0.0500000007 0.0065199998 0.0356829986 +0.0500000007 0.0063939998 0.0388359986 +0.0500000007 0.0063240002 0.0134619996 +0.0500000007 0.0063080001 -0.0383489989 +0.0500000007 0.0062850001 -0.0118359998 +0.0500000007 0.0062830001 -0.0368579999 +0.0500000007 0.0062759998 0.0119260000 +0.0500000007 0.0062549999 0.0372509994 +0.0500000007 -0.0062500001 0.0375000015 +0.0500000007 -0.0062500001 0.0125000002 +0.0500000007 -0.0062830001 -0.0368579999 +0.0500000007 -0.0062850001 -0.0118359998 +0.0500000007 -0.0063080001 -0.0383489989 +0.0500000007 -0.0064630001 0.0391179994 +0.0500000007 -0.0064630001 0.0358819999 +0.0500000007 -0.0064630001 0.0141179999 +0.0500000007 -0.0064630001 0.0108820004 +0.0500000007 -0.0066120001 -0.0354040004 +0.0500000007 -0.0066320002 -0.0103489999 +0.0500000007 -0.0066849999 -0.0397909991 +0.0500000007 -0.0070870002 0.0406249985 +0.0500000007 -0.0070870002 0.0343750007 +0.0500000007 -0.0070870002 0.0156250000 +0.0500000007 -0.0070870002 0.0093750004 +0.0500000007 -0.0072760000 -0.0340690017 +0.0500000007 -0.0073279999 -0.0089910002 +0.0500000007 -0.0073930002 -0.0411030017 +0.0500000007 -0.0080810003 0.0419190004 +0.0500000007 -0.0080810003 0.0330809988 +0.0500000007 -0.0080810003 0.0169190001 +0.0500000007 -0.0080810003 0.0080810003 +0.0500000007 -0.0082369996 -0.0329300016 +0.0500000007 -0.0083320001 -0.0078419996 +0.0500000007 -0.0083919996 -0.0422100015 +0.0500000007 -0.0093750004 0.0429130010 +0.0500000007 -0.0093750004 0.0320869982 +0.0500000007 -0.0093750004 0.0179130007 +0.0500000007 -0.0093750004 0.0070870002 +0.0500000007 -0.0095859999 -0.0069710002 +0.0500000007 -0.0096239997 -0.0430490002 +0.0500000007 -0.0108820004 0.0435369983 +0.0500000007 -0.0108820004 0.0314630009 +0.0500000007 -0.0108820004 0.0185369998 +0.0500000007 -0.0108820004 0.0064630001 +0.0500000007 -0.0110130003 -0.0064300001 +0.0500000007 -0.0110200001 -0.0435720012 +0.0500000007 -0.0125000002 0.0437499993 +0.0500000007 -0.0125000002 0.0312500000 +0.0500000007 -0.0125000002 0.0187500007 +0.0500000007 -0.0125000002 0.0062500001 +0.0500000007 -0.0125000002 -0.0437499993 +0.0500000007 -0.0125280004 -0.0062500001 +0.0500000007 -0.0139800003 -0.0435720012 +0.0500000007 -0.0140420003 -0.0064429999 +0.0500000007 -0.0141179999 0.0435369983 +0.0500000007 -0.0141179999 0.0314630009 +0.0500000007 -0.0141179999 0.0185369998 +0.0500000007 -0.0141179999 0.0064630001 +0.0500000007 -0.0153759997 -0.0430490002 +0.0500000007 -0.0154640004 -0.0069980002 +0.0500000007 -0.0156250000 0.0429130010 +0.0500000007 -0.0156250000 0.0320869982 +0.0500000007 -0.0156250000 0.0179130007 +0.0500000007 -0.0156250000 0.0070870002 +0.0500000007 -0.0166079998 -0.0422100015 +0.0500000007 -0.0167089999 -0.0078800004 +0.0500000007 -0.0167629998 -0.0329300016 +0.0500000007 -0.0169190001 0.0419190004 +0.0500000007 -0.0169190001 0.0330809988 +0.0500000007 -0.0169190001 0.0169190001 +0.0500000007 -0.0169190001 0.0080810003 +0.0500000007 -0.0176069997 -0.0411030017 +0.0500000007 -0.0177040007 -0.0090380004 +0.0500000007 -0.0177239999 -0.0340690017 +0.0500000007 -0.0178120006 -0.0329300016 +0.0500000007 -0.0179130007 0.0406249985 +0.0500000007 -0.0179130007 0.0343750007 +0.0500000007 -0.0179130007 0.0156250000 +0.0500000007 -0.0179130007 0.0093750004 +0.0500000007 -0.0183150005 -0.0397909991 +0.0500000007 -0.0183879994 -0.0104019996 +0.0500000007 -0.0183879994 -0.0354040004 +0.0500000007 -0.0185369998 0.0391179994 +0.0500000007 -0.0185369998 0.0358819999 +0.0500000007 -0.0185369998 0.0141179999 +0.0500000007 -0.0185369998 0.0108820004 +0.0500000007 -0.0186919998 -0.0383489989 +0.0500000007 -0.0187170003 -0.0368579999 +0.0500000007 -0.0187199991 -0.0118920002 +0.0500000007 -0.0187500007 0.0375000015 +0.0500000007 -0.0187500007 0.0125000002 +0.0500000007 -0.0197230000 -0.0326780006 +0.0500000007 -0.0204450004 -0.0123210000 +0.0500000007 -0.0215039998 -0.0319410004 +0.0500000007 -0.0220160000 -0.0131500000 +0.0500000007 -0.0230330005 -0.0307669993 +0.0500000007 -0.0233449992 -0.0143299997 +0.0500000007 -0.0242059994 -0.0292380005 +0.0500000007 -0.0243519992 -0.0157929994 +0.0500000007 -0.0249439999 -0.0274580009 +0.0500000007 -0.0249819998 -0.0174550004 +0.0500000007 -0.0251950007 -0.0192189999 +0.0500000007 -0.0251950007 -0.0255469996 +0.0500000007 -0.0312500000 0.0375000015 +0.0500000007 -0.0312500000 0.0125000002 +0.0500000007 -0.0312500000 -0.0125000002 +0.0500000007 -0.0312500000 -0.0375000015 +0.0500000007 -0.0314630009 0.0391179994 +0.0500000007 -0.0314630009 0.0358819999 +0.0500000007 -0.0314630009 0.0141179999 +0.0500000007 -0.0314630009 0.0108820004 +0.0500000007 -0.0314630009 -0.0108820004 +0.0500000007 -0.0314630009 -0.0141179999 +0.0500000007 -0.0314630009 -0.0358819999 +0.0500000007 -0.0314630009 -0.0391179994 +0.0500000007 -0.0320869982 0.0406249985 +0.0500000007 -0.0320869982 0.0343750007 +0.0500000007 -0.0320869982 0.0156250000 +0.0500000007 -0.0320869982 0.0093750004 +0.0500000007 -0.0320869982 -0.0093750004 +0.0500000007 -0.0320869982 -0.0156250000 +0.0500000007 -0.0320869982 -0.0343750007 +0.0500000007 -0.0320869982 -0.0406249985 +0.0500000007 -0.0330809988 0.0419190004 +0.0500000007 -0.0330809988 0.0330809988 +0.0500000007 -0.0330809988 0.0169190001 +0.0500000007 -0.0330809988 0.0080810003 +0.0500000007 -0.0330809988 -0.0080810003 +0.0500000007 -0.0330809988 -0.0169190001 +0.0500000007 -0.0330809988 -0.0330809988 +0.0500000007 -0.0330809988 -0.0419190004 +0.0500000007 -0.0343750007 0.0429130010 +0.0500000007 -0.0343750007 0.0320869982 +0.0500000007 -0.0343750007 0.0179130007 +0.0500000007 -0.0343750007 0.0070870002 +0.0500000007 -0.0343750007 -0.0070870002 +0.0500000007 -0.0343750007 -0.0179130007 +0.0500000007 -0.0343750007 -0.0320869982 +0.0500000007 -0.0343750007 -0.0429130010 +0.0500000007 -0.0358819999 0.0435369983 +0.0500000007 -0.0358819999 0.0314630009 +0.0500000007 -0.0358819999 0.0185369998 +0.0500000007 -0.0358819999 0.0064630001 +0.0500000007 -0.0358819999 -0.0064630001 +0.0500000007 -0.0358819999 -0.0185369998 +0.0500000007 -0.0358819999 -0.0314630009 +0.0500000007 -0.0358819999 -0.0435369983 +0.0500000007 -0.0375000015 0.0437499993 +0.0500000007 -0.0375000015 0.0312500000 +0.0500000007 -0.0375000015 0.0187500007 +0.0500000007 -0.0375000015 0.0062500001 +0.0500000007 -0.0375000015 0.0050889999 +0.0500000007 -0.0375000015 -0.0062500001 +0.0500000007 -0.0375000015 -0.0187500007 +0.0500000007 -0.0375000015 -0.0312500000 +0.0500000007 -0.0375000015 -0.0437499993 +0.0500000007 -0.0391030014 -0.0185410008 +0.0500000007 -0.0391179994 0.0435369983 +0.0500000007 -0.0391179994 0.0314630009 +0.0500000007 -0.0391179994 0.0185369998 +0.0500000007 -0.0391179994 0.0064630001 +0.0500000007 -0.0391179994 -0.0314630009 +0.0500000007 -0.0391179994 -0.0435369983 +0.0500000007 -0.0405989997 -0.0179270003 +0.0500000007 -0.0406249985 0.0429130010 +0.0500000007 -0.0406249985 0.0320869982 +0.0500000007 -0.0406249985 0.0179130007 +0.0500000007 -0.0406249985 0.0070870002 +0.0500000007 -0.0406249985 -0.0320869982 +0.0500000007 -0.0406249985 -0.0429130010 +0.0500000007 -0.0418879986 -0.0169510003 +0.0500000007 -0.0419190004 0.0419190004 +0.0500000007 -0.0419190004 0.0330809988 +0.0500000007 -0.0419190004 0.0169190001 +0.0500000007 -0.0419190004 0.0080810003 +0.0500000007 -0.0419190004 -0.0330809988 +0.0500000007 -0.0419190004 -0.0419190004 +0.0500000007 -0.0428830013 -0.0156759992 +0.0500000007 -0.0429130010 0.0406249985 +0.0500000007 -0.0429130010 0.0343750007 +0.0500000007 -0.0429130010 0.0156250000 +0.0500000007 -0.0429130010 0.0093750004 +0.0500000007 -0.0429130010 -0.0343750007 +0.0500000007 -0.0429130010 -0.0406249985 +0.0500000007 -0.0435170010 -0.0141890002 +0.0500000007 -0.0435369983 0.0391179994 +0.0500000007 -0.0435369983 0.0358819999 +0.0500000007 -0.0435369983 0.0141179999 +0.0500000007 -0.0435369983 0.0108820004 +0.0500000007 -0.0435369983 -0.0358819999 +0.0500000007 -0.0435369983 -0.0391179994 +0.0500000007 -0.0437490009 -0.0125890002 +0.0500000007 -0.0437499993 0.0375000015 +0.0500000007 -0.0437499993 0.0125000002 +0.0500000007 -0.0437499993 -0.0375000015 +0.0500000007 -0.0500000007 0.0500000007 +0.0500000007 -0.0500000007 0.0050889999 +0.0500000007 -0.0500000007 -0.0125890002 +0.0500000007 -0.0500000007 -0.0500000007 +0.0487929992 -0.0436140001 -0.0137949996 +0.0476359986 -0.0432480015 -0.0149529995 +0.0465699993 -0.0426659994 -0.0160179995 +0.0456379987 -0.0418879986 -0.0169510003 +0.0448740013 -0.0409450009 -0.0177149996 +0.0443059988 -0.0398709998 -0.0182830002 +0.0439569987 -0.0387080014 -0.0186320003 +0.0438680016 -0.0381070003 -0.0187199991 +0.0438390002 -0.0375000015 -0.0187500007 +0.0437499993 0.0500000007 0.0375000015 +0.0437499993 0.0500000007 0.0125000002 +0.0437499993 0.0500000007 -0.0125000002 +0.0437499993 0.0500000007 -0.0375000015 +0.0437499993 0.0437499993 0.0375000015 +0.0437499993 0.0437499993 0.0125000002 +0.0437499993 0.0437499993 -0.0125000002 +0.0437499993 0.0437499993 -0.0375000015 +0.0437499993 0.0375000015 0.0500000007 +0.0437499993 0.0375000015 0.0437499993 +0.0437499993 0.0375000015 -0.0312500000 +0.0437499993 0.0375000015 -0.0437499993 +0.0437499993 0.0375000015 -0.0500000007 +0.0437499993 0.0312500000 -0.0375000015 +0.0437499993 0.0187500007 -0.0375000015 +0.0437499993 0.0125000002 0.0500000007 +0.0437499993 0.0125000002 0.0437499993 +0.0437499993 0.0125000002 0.0312500000 +0.0437499993 0.0125000002 0.0187500007 +0.0437499993 0.0125000002 0.0062500001 +0.0437499993 0.0125000002 -0.0062500001 +0.0437499993 0.0125000002 -0.0437499993 +0.0437499993 0.0125000002 -0.0500000007 +0.0437499993 0.0062500001 0.0375000015 +0.0437499993 0.0062500001 0.0125000002 +0.0437499993 0.0062500001 -0.0375000015 +0.0437499993 -0.0062500001 0.0375000015 +0.0437499993 -0.0062500001 0.0125000002 +0.0437499993 -0.0062500001 -0.0375000015 +0.0437499993 -0.0125000002 0.0500000007 +0.0437499993 -0.0125000002 0.0437499993 +0.0437499993 -0.0125000002 0.0312500000 +0.0437499993 -0.0125000002 0.0187500007 +0.0437499993 -0.0125000002 0.0062500001 +0.0437499993 -0.0125000002 -0.0062500001 +0.0437499993 -0.0125000002 -0.0437499993 +0.0437499993 -0.0125000002 -0.0500000007 +0.0437499993 -0.0187500007 0.0375000015 +0.0437499993 -0.0187500007 0.0125000002 +0.0437499993 -0.0187500007 -0.0375000015 +0.0437499993 -0.0312500000 0.0375000015 +0.0437499993 -0.0312500000 0.0125000002 +0.0437499993 -0.0312500000 -0.0125000002 +0.0437499993 -0.0312500000 -0.0375000015 +0.0437499993 -0.0375000015 0.0500000007 +0.0437499993 -0.0375000015 0.0437499993 +0.0437499993 -0.0375000015 0.0312500000 +0.0437499993 -0.0375000015 0.0187500007 +0.0437499993 -0.0375000015 0.0062500001 +0.0437499993 -0.0375000015 -0.0011610000 +0.0437499993 -0.0375000015 -0.0062500001 +0.0437499993 -0.0375000015 -0.0188389998 +0.0437499993 -0.0375000015 -0.0312500000 +0.0437499993 -0.0375000015 -0.0437499993 +0.0437499993 -0.0375000015 -0.0500000007 +0.0437499993 -0.0437499993 0.0375000015 +0.0437499993 -0.0437499993 0.0125000002 +0.0437499993 -0.0437499993 -0.0375000015 +0.0437499993 -0.0500000007 0.0375000015 +0.0437499993 -0.0500000007 0.0125000002 +0.0437499993 -0.0500000007 -0.0375000015 +0.0437479988 0.0376459993 -0.0280569997 +0.0437470004 -0.0204029996 -0.0123060001 +0.0437370017 0.0370990001 -0.0292349998 +0.0437319987 0.0379780009 -0.0268029999 +0.0437220000 0.0380860008 0.0312779993 +0.0437220000 0.0380860008 0.0187219996 +0.0437220000 0.0380860008 0.0062779998 +0.0437220000 0.0380860008 -0.0062779998 +0.0437220000 0.0380860008 -0.0187219996 +0.0437220000 0.0380860008 -0.0255469996 +0.0437220000 -0.0380889997 -0.0188669991 +0.0437210016 -0.0219470002 -0.0131019996 +0.0437199995 0.0437199995 0.0381130017 +0.0437199995 0.0437199995 0.0368870012 +0.0437199995 0.0437199995 0.0131130004 +0.0437199995 0.0437199995 0.0118869999 +0.0437199995 0.0437199995 -0.0118869999 +0.0437199995 0.0437199995 -0.0131130004 +0.0437199995 0.0437199995 -0.0368870012 +0.0437199995 0.0437199995 -0.0381130017 +0.0437199995 0.0381130017 0.0437199995 +0.0437199995 0.0381130017 -0.0312799998 +0.0437199995 0.0381130017 -0.0437199995 +0.0437199995 0.0368870012 0.0437199995 +0.0437199995 0.0368870012 -0.0312799998 +0.0437199995 0.0368870012 -0.0437199995 +0.0437199995 0.0312799998 -0.0368870012 +0.0437199995 0.0312799998 -0.0381130017 +0.0437199995 0.0187199991 -0.0368870012 +0.0437199995 0.0187199991 -0.0381130017 +0.0437199995 0.0131130004 0.0437199995 +0.0437199995 0.0131130004 0.0312799998 +0.0437199995 0.0131130004 0.0187199991 +0.0437199995 0.0131130004 0.0062799999 +0.0437199995 0.0131130004 -0.0062799999 +0.0437199995 0.0131130004 -0.0437199995 +0.0437199995 0.0118869999 0.0437199995 +0.0437199995 0.0118869999 0.0312799998 +0.0437199995 0.0118869999 0.0187199991 +0.0437199995 0.0118869999 0.0062799999 +0.0437199995 0.0118869999 -0.0062799999 +0.0437199995 0.0118869999 -0.0437199995 +0.0437199995 0.0062799999 0.0381130017 +0.0437199995 0.0062799999 0.0368870012 +0.0437199995 0.0062799999 0.0131130004 +0.0437199995 0.0062799999 0.0118869999 +0.0437199995 0.0062799999 -0.0368870012 +0.0437199995 0.0062799999 -0.0381130017 +0.0437199995 -0.0062799999 0.0381130017 +0.0437199995 -0.0062799999 0.0368870012 +0.0437199995 -0.0062799999 0.0131130004 +0.0437199995 -0.0062799999 0.0118869999 +0.0437199995 -0.0062799999 -0.0368870012 +0.0437199995 -0.0062799999 -0.0381130017 +0.0437199995 -0.0118869999 0.0437199995 +0.0437199995 -0.0118869999 0.0312799998 +0.0437199995 -0.0118869999 0.0187199991 +0.0437199995 -0.0118869999 0.0062799999 +0.0437199995 -0.0118869999 -0.0062799999 +0.0437199995 -0.0118869999 -0.0437199995 +0.0437199995 -0.0131130004 0.0437199995 +0.0437199995 -0.0131130004 0.0312799998 +0.0437199995 -0.0131130004 0.0187199991 +0.0437199995 -0.0131130004 0.0062799999 +0.0437199995 -0.0131130004 -0.0062799999 +0.0437199995 -0.0131130004 -0.0437199995 +0.0437199995 -0.0187199991 0.0381130017 +0.0437199995 -0.0187199991 0.0368870012 +0.0437199995 -0.0187199991 0.0131130004 +0.0437199995 -0.0187199991 0.0118869999 +0.0437199995 -0.0187199991 -0.0118920002 +0.0437199995 -0.0187199991 -0.0368870012 +0.0437199995 -0.0187199991 -0.0381130017 +0.0437199995 -0.0312799998 0.0381130017 +0.0437199995 -0.0312799998 0.0368870012 +0.0437199995 -0.0312799998 0.0131130004 +0.0437199995 -0.0312799998 0.0118869999 +0.0437199995 -0.0312799998 -0.0118869999 +0.0437199995 -0.0312799998 -0.0131130004 +0.0437199995 -0.0312799998 -0.0368870012 +0.0437199995 -0.0312799998 -0.0381130017 +0.0437199995 -0.0368870012 0.0437199995 +0.0437199995 -0.0368870012 0.0312799998 +0.0437199995 -0.0368870012 0.0187199991 +0.0437199995 -0.0368870012 0.0062799999 +0.0437199995 -0.0368870012 -0.0062799999 +0.0437199995 -0.0368870012 -0.0187199991 +0.0437199995 -0.0368870012 -0.0312799998 +0.0437199995 -0.0368870012 -0.0437199995 +0.0437199995 -0.0381130017 0.0437199995 +0.0437199995 -0.0381130017 0.0312799998 +0.0437199995 -0.0381130017 0.0187199991 +0.0437199995 -0.0381130017 0.0062799999 +0.0437199995 -0.0381130017 -0.0312799998 +0.0437199995 -0.0381130017 -0.0437199995 +0.0437199995 -0.0437199995 0.0381130017 +0.0437199995 -0.0437199995 0.0368870012 +0.0437199995 -0.0437199995 0.0131130004 +0.0437199995 -0.0437199995 0.0118869999 +0.0437199995 -0.0437199995 -0.0368870012 +0.0437199995 -0.0437199995 -0.0381130017 +0.0437150002 0.0062850001 -0.0118359998 +0.0437150002 -0.0062850001 -0.0118359998 +0.0437050015 0.0187049992 0.0382449999 +0.0436550006 -0.0385870002 -0.0012560000 +0.0436489992 -0.0226210002 -0.0136160003 +0.0436469987 0.0363700017 -0.0302779991 +0.0436390005 -0.0386740007 -0.0189500004 +0.0436300002 0.0436300002 0.0387189984 +0.0436300002 0.0436300002 0.0362810008 +0.0436300002 0.0436300002 0.0137189999 +0.0436300002 0.0436300002 0.0112810005 +0.0436300002 0.0436300002 -0.0112810005 +0.0436300002 0.0436300002 -0.0137189999 +0.0436300002 0.0436300002 -0.0362810008 +0.0436300002 0.0436300002 -0.0387189984 +0.0436300002 0.0387189984 0.0436300002 +0.0436300002 0.0387189984 -0.0313699991 +0.0436300002 0.0387189984 -0.0436300002 +0.0436300002 0.0362810008 0.0436300002 +0.0436300002 0.0362810008 -0.0313699991 +0.0436300002 0.0362810008 -0.0436300002 +0.0436300002 0.0313699991 -0.0362810008 +0.0436300002 0.0313699991 -0.0387189984 +0.0436300002 0.0186299998 -0.0362810008 +0.0436300002 0.0186299998 -0.0387189984 +0.0436300002 0.0137189999 0.0436300002 +0.0436300002 0.0137189999 0.0313699991 +0.0436300002 0.0137189999 0.0186299998 +0.0436300002 0.0137189999 0.0063700001 +0.0436300002 0.0137189999 -0.0063700001 +0.0436300002 0.0137189999 -0.0436300002 +0.0436300002 0.0112810005 0.0436300002 +0.0436300002 0.0112810005 0.0313699991 +0.0436300002 0.0112810005 0.0186299998 +0.0436300002 0.0112810005 0.0063700001 +0.0436300002 0.0112810005 -0.0063700001 +0.0436300002 0.0112810005 -0.0436300002 +0.0436300002 0.0063700001 0.0387189984 +0.0436300002 0.0063700001 0.0362810008 +0.0436300002 0.0063700001 0.0137189999 +0.0436300002 0.0063700001 0.0112810005 +0.0436300002 0.0063700001 -0.0362810008 +0.0436300002 0.0063700001 -0.0387189984 +0.0436300002 -0.0063700001 0.0387189984 +0.0436300002 -0.0063700001 0.0362810008 +0.0436300002 -0.0063700001 0.0137189999 +0.0436300002 -0.0063700001 0.0112810005 +0.0436300002 -0.0063700001 -0.0362810008 +0.0436300002 -0.0063700001 -0.0387189984 +0.0436300002 -0.0112810005 0.0436300002 +0.0436300002 -0.0112810005 0.0313699991 +0.0436300002 -0.0112810005 0.0186299998 +0.0436300002 -0.0112810005 0.0063700001 +0.0436300002 -0.0112810005 -0.0063700001 +0.0436300002 -0.0112810005 -0.0436300002 +0.0436300002 -0.0137189999 0.0436300002 +0.0436300002 -0.0137189999 0.0313699991 +0.0436300002 -0.0137189999 0.0186299998 +0.0436300002 -0.0137189999 0.0063700001 +0.0436300002 -0.0137189999 -0.0063700001 +0.0436300002 -0.0137189999 -0.0436300002 +0.0436300002 -0.0186299998 0.0387189984 +0.0436300002 -0.0186299998 0.0362810008 +0.0436300002 -0.0186299998 0.0137189999 +0.0436300002 -0.0186299998 0.0112810005 +0.0436300002 -0.0186299998 -0.0362810008 +0.0436300002 -0.0186299998 -0.0387189984 +0.0436300002 -0.0313699991 0.0387189984 +0.0436300002 -0.0313699991 0.0362810008 +0.0436300002 -0.0313699991 0.0137189999 +0.0436300002 -0.0313699991 0.0112810005 +0.0436300002 -0.0313699991 -0.0112810005 +0.0436300002 -0.0313699991 -0.0137189999 +0.0436300002 -0.0313699991 -0.0362810008 +0.0436300002 -0.0313699991 -0.0387189984 +0.0436300002 -0.0362810008 0.0436300002 +0.0436300002 -0.0362810008 0.0313699991 +0.0436300002 -0.0362810008 0.0186299998 +0.0436300002 -0.0362810008 0.0063700001 +0.0436300002 -0.0362810008 -0.0063700001 +0.0436300002 -0.0362810008 -0.0186299998 +0.0436300002 -0.0362810008 -0.0313699991 +0.0436300002 -0.0362810008 -0.0436300002 +0.0436300002 -0.0387189984 0.0436300002 +0.0436300002 -0.0387189984 0.0313699991 +0.0436300002 -0.0387189984 0.0186299998 +0.0436300002 -0.0387189984 0.0063700001 +0.0436300002 -0.0387189984 -0.0313699991 +0.0436300002 -0.0387189984 -0.0436300002 +0.0436300002 -0.0436300002 0.0387189984 +0.0436300002 -0.0436300002 0.0362810008 +0.0436300002 -0.0436300002 0.0137189999 +0.0436300002 -0.0436300002 0.0112810005 +0.0436300002 -0.0436300002 -0.0362810008 +0.0436300002 -0.0436300002 -0.0387189984 +0.0435400009 0.0358939990 0.0500000007 +0.0435389988 0.0391100012 0.0500000007 +0.0435369983 0.0500000007 0.0391179994 +0.0435369983 0.0500000007 0.0358819999 +0.0435369983 0.0500000007 0.0141179999 +0.0435369983 0.0500000007 0.0108820004 +0.0435369983 0.0500000007 -0.0108820004 +0.0435369983 0.0500000007 -0.0141179999 +0.0435369983 0.0500000007 -0.0358819999 +0.0435369983 0.0500000007 -0.0391179994 +0.0435369983 0.0391179994 -0.0500000007 +0.0435369983 0.0358819999 -0.0500000007 +0.0435369983 0.0141179999 0.0500000007 +0.0435369983 0.0141179999 -0.0500000007 +0.0435369983 0.0108820004 0.0500000007 +0.0435369983 0.0108820004 -0.0500000007 +0.0435369983 -0.0108820004 0.0500000007 +0.0435369983 -0.0108820004 -0.0500000007 +0.0435369983 -0.0141179999 0.0500000007 +0.0435369983 -0.0141179999 -0.0500000007 +0.0435369983 -0.0358819999 0.0500000007 +0.0435369983 -0.0358819999 -0.0500000007 +0.0435369983 -0.0391179994 0.0500000007 +0.0435369983 -0.0391179994 -0.0500000007 +0.0435369983 -0.0500000007 0.0391179994 +0.0435369983 -0.0500000007 0.0358819999 +0.0435369983 -0.0500000007 0.0141179999 +0.0435369983 -0.0500000007 0.0108820004 +0.0435369983 -0.0500000007 -0.0358819999 +0.0435369983 -0.0500000007 -0.0391179994 +0.0435290001 0.0391479991 0.0314709991 +0.0435290001 0.0391479991 0.0185289998 +0.0435290001 0.0391479991 0.0064710001 +0.0435290001 0.0391479991 -0.0064710001 +0.0435290001 0.0391479991 -0.0185289998 +0.0435249992 -0.0185250007 -0.0108359996 +0.0435170010 -0.0232170001 -0.0141890002 +0.0435130000 0.0064869998 -0.0107960002 +0.0435130000 -0.0064869998 -0.0107960002 +0.0434960015 0.0184959993 0.0392629988 +0.0434670001 0.0198640004 0.0393600017 +0.0434210002 0.0354989991 -0.0311600007 +0.0433720015 -0.0396410003 -0.0015390000 +0.0433089994 -0.0398049988 -0.0192799997 +0.0432940014 -0.0237590000 -0.0148440003 +0.0432740003 0.0432740003 0.0398919992 +0.0432740003 0.0432740003 0.0351080000 +0.0432740003 0.0432740003 0.0148919998 +0.0432740003 0.0432740003 0.0101079997 +0.0432740003 0.0432740003 -0.0101079997 +0.0432740003 0.0432740003 -0.0148919998 +0.0432740003 0.0432740003 -0.0351080000 +0.0432740003 0.0432740003 -0.0398919992 +0.0432740003 0.0398919992 0.0432740003 +0.0432740003 0.0398919992 -0.0317259990 +0.0432740003 0.0398919992 -0.0432740003 +0.0432740003 0.0351080000 0.0432740003 +0.0432740003 0.0351080000 -0.0317259990 +0.0432740003 0.0351080000 -0.0432740003 +0.0432740003 0.0317259990 -0.0351080000 +0.0432740003 0.0317259990 -0.0398919992 +0.0432740003 0.0182739999 -0.0351080000 +0.0432740003 0.0182739999 -0.0398919992 +0.0432740003 0.0148919998 0.0432740003 +0.0432740003 0.0148919998 0.0317259990 +0.0432740003 0.0148919998 0.0182739999 +0.0432740003 0.0148919998 0.0067260000 +0.0432740003 0.0148919998 -0.0067260000 +0.0432740003 0.0148919998 -0.0432740003 +0.0432740003 0.0101079997 0.0432740003 +0.0432740003 0.0101079997 0.0317259990 +0.0432740003 0.0101079997 0.0182739999 +0.0432740003 0.0101079997 0.0067260000 +0.0432740003 0.0101079997 -0.0067260000 +0.0432740003 0.0101079997 -0.0432740003 +0.0432740003 0.0067260000 0.0398919992 +0.0432740003 0.0067260000 0.0351080000 +0.0432740003 0.0067260000 0.0148919998 +0.0432740003 0.0067260000 0.0101079997 +0.0432740003 0.0067260000 -0.0351080000 +0.0432740003 0.0067260000 -0.0398919992 +0.0432740003 -0.0067260000 0.0398919992 +0.0432740003 -0.0067260000 0.0351080000 +0.0432740003 -0.0067260000 0.0148919998 +0.0432740003 -0.0067260000 0.0101079997 +0.0432740003 -0.0067260000 -0.0351080000 +0.0432740003 -0.0067260000 -0.0398919992 +0.0432740003 -0.0101079997 0.0432740003 +0.0432740003 -0.0101079997 0.0317259990 +0.0432740003 -0.0101079997 0.0182739999 +0.0432740003 -0.0101079997 0.0067260000 +0.0432740003 -0.0101079997 -0.0067260000 +0.0432740003 -0.0101079997 -0.0432740003 +0.0432740003 -0.0148919998 0.0432740003 +0.0432740003 -0.0148919998 0.0317259990 +0.0432740003 -0.0148919998 0.0182739999 +0.0432740003 -0.0148919998 0.0067260000 +0.0432740003 -0.0148919998 -0.0067260000 +0.0432740003 -0.0148919998 -0.0432740003 +0.0432740003 -0.0182739999 0.0398919992 +0.0432740003 -0.0182739999 0.0351080000 +0.0432740003 -0.0182739999 0.0148919998 +0.0432740003 -0.0182739999 0.0101079997 +0.0432740003 -0.0182739999 -0.0351080000 +0.0432740003 -0.0182739999 -0.0398919992 +0.0432740003 -0.0317259990 0.0398919992 +0.0432740003 -0.0317259990 0.0351080000 +0.0432740003 -0.0317259990 0.0148919998 +0.0432740003 -0.0317259990 0.0101079997 +0.0432740003 -0.0317259990 -0.0101079997 +0.0432740003 -0.0317259990 -0.0148919998 +0.0432740003 -0.0317259990 -0.0351080000 +0.0432740003 -0.0317259990 -0.0398919992 +0.0432740003 -0.0351080000 0.0432740003 +0.0432740003 -0.0351080000 0.0317259990 +0.0432740003 -0.0351080000 0.0182739999 +0.0432740003 -0.0351080000 0.0067260000 +0.0432740003 -0.0351080000 -0.0067260000 +0.0432740003 -0.0351080000 -0.0182739999 +0.0432740003 -0.0351080000 -0.0317259990 +0.0432740003 -0.0351080000 -0.0432740003 +0.0432740003 -0.0398919992 0.0432740003 +0.0432740003 -0.0398919992 0.0317259990 +0.0432740003 -0.0398919992 0.0182739999 +0.0432740003 -0.0398919992 0.0067260000 +0.0432740003 -0.0398919992 -0.0317259990 +0.0432740003 -0.0398919992 -0.0432740003 +0.0432740003 -0.0432740003 0.0398919992 +0.0432740003 -0.0432740003 0.0351080000 +0.0432740003 -0.0432740003 0.0148919998 +0.0432740003 -0.0432740003 0.0101079997 +0.0432740003 -0.0432740003 -0.0351080000 +0.0432740003 -0.0432740003 -0.0398919992 +0.0431560017 0.0401600003 0.0318440013 +0.0431560017 0.0401600003 0.0181559995 +0.0431560017 0.0401600003 0.0068440000 +0.0431560017 0.0401600003 -0.0068440000 +0.0431560017 0.0401600003 -0.0181559995 +0.0431509987 -0.0181510001 -0.0098299999 +0.0431389995 0.0068609999 -0.0098040001 +0.0431389995 -0.0068609999 -0.0098040001 +0.0431360006 0.0212440006 0.0402019992 +0.0431209989 0.0181210004 0.0402319990 +0.0429750010 0.0344859995 -0.0318869986 +0.0429629982 -0.0242110007 -0.0155360000 +0.0429240018 0.0343950018 0.0500000007 +0.0429200009 0.0406120010 0.0500000007 +0.0429130010 0.0500000007 0.0406249985 +0.0429130010 0.0500000007 0.0343750007 +0.0429130010 0.0500000007 0.0156250000 +0.0429130010 0.0500000007 0.0093750004 +0.0429130010 0.0500000007 -0.0093750004 +0.0429130010 0.0500000007 -0.0156250000 +0.0429130010 0.0500000007 -0.0343750007 +0.0429130010 0.0500000007 -0.0406249985 +0.0429130010 0.0406249985 -0.0500000007 +0.0429130010 0.0343750007 -0.0500000007 +0.0429130010 0.0156250000 0.0500000007 +0.0429130010 0.0156250000 -0.0500000007 +0.0429130010 0.0093750004 0.0500000007 +0.0429130010 0.0093750004 -0.0500000007 +0.0429130010 -0.0093750004 0.0500000007 +0.0429130010 -0.0093750004 -0.0500000007 +0.0429130010 -0.0156250000 0.0500000007 +0.0429130010 -0.0156250000 -0.0500000007 +0.0429130010 -0.0343750007 0.0500000007 +0.0429130010 -0.0343750007 -0.0500000007 +0.0429130010 -0.0406249985 0.0500000007 +0.0429130010 -0.0406249985 -0.0500000007 +0.0429130010 -0.0500000007 0.0406249985 +0.0429130010 -0.0500000007 0.0343750007 +0.0429130010 -0.0500000007 0.0156250000 +0.0429130010 -0.0500000007 0.0093750004 +0.0429130010 -0.0500000007 -0.0343750007 +0.0429130010 -0.0500000007 -0.0406249985 +0.0429099984 -0.0406300016 -0.0020020001 +0.0428549983 0.0227760002 0.0407229997 +0.0428370014 0.0321630016 0.0407529995 +0.0427730009 -0.0408550017 -0.0198160000 +0.0427450016 0.0307030007 0.0408979990 +0.0427450016 0.0243749991 0.0408979990 +0.0426970012 0.0426970012 0.0409720019 +0.0426970012 0.0426970012 0.0340280011 +0.0426970012 0.0426970012 0.0159719996 +0.0426970012 0.0426970012 0.0090279998 +0.0426970012 0.0426970012 -0.0090279998 +0.0426970012 0.0426970012 -0.0159719996 +0.0426970012 0.0426970012 -0.0340280011 +0.0426970012 0.0426970012 -0.0409720019 +0.0426970012 0.0409720019 0.0426970012 +0.0426970012 0.0409720019 -0.0323030017 +0.0426970012 0.0409720019 -0.0426970012 +0.0426970012 0.0340280011 0.0426970012 +0.0426970012 0.0340280011 -0.0323030017 +0.0426970012 0.0340280011 -0.0426970012 +0.0426970012 0.0323030017 -0.0340280011 +0.0426970012 0.0323030017 -0.0409720019 +0.0426970012 0.0176970009 -0.0340280011 +0.0426970012 0.0176970009 -0.0409720019 +0.0426970012 0.0159719996 0.0426970012 +0.0426970012 0.0159719996 0.0323030017 +0.0426970012 0.0159719996 0.0176970009 +0.0426970012 0.0159719996 0.0073030000 +0.0426970012 0.0159719996 -0.0073030000 +0.0426970012 0.0159719996 -0.0426970012 +0.0426970012 0.0090279998 0.0426970012 +0.0426970012 0.0090279998 0.0323030017 +0.0426970012 0.0090279998 0.0176970009 +0.0426970012 0.0090279998 0.0073030000 +0.0426970012 0.0090279998 -0.0073030000 +0.0426970012 0.0090279998 -0.0426970012 +0.0426970012 0.0073030000 0.0409720019 +0.0426970012 0.0073030000 0.0340280011 +0.0426970012 0.0073030000 0.0159719996 +0.0426970012 0.0073030000 0.0090279998 +0.0426970012 0.0073030000 -0.0340280011 +0.0426970012 0.0073030000 -0.0409720019 +0.0426970012 -0.0073030000 0.0409720019 +0.0426970012 -0.0073030000 0.0340280011 +0.0426970012 -0.0073030000 0.0159719996 +0.0426970012 -0.0073030000 0.0090279998 +0.0426970012 -0.0073030000 -0.0340280011 +0.0426970012 -0.0073030000 -0.0409720019 +0.0426970012 -0.0090279998 0.0426970012 +0.0426970012 -0.0090279998 0.0323030017 +0.0426970012 -0.0090279998 0.0176970009 +0.0426970012 -0.0090279998 0.0073030000 +0.0426970012 -0.0090279998 -0.0073030000 +0.0426970012 -0.0090279998 -0.0426970012 +0.0426970012 -0.0159719996 0.0426970012 +0.0426970012 -0.0159719996 0.0323030017 +0.0426970012 -0.0159719996 0.0176970009 +0.0426970012 -0.0159719996 0.0073030000 +0.0426970012 -0.0159719996 -0.0073030000 +0.0426970012 -0.0159719996 -0.0426970012 +0.0426970012 -0.0176970009 0.0409720019 +0.0426970012 -0.0176970009 0.0340280011 +0.0426970012 -0.0176970009 0.0159719996 +0.0426970012 -0.0176970009 0.0090279998 +0.0426970012 -0.0176970009 -0.0340280011 +0.0426970012 -0.0176970009 -0.0409720019 +0.0426970012 -0.0323030017 0.0409720019 +0.0426970012 -0.0323030017 0.0340280011 +0.0426970012 -0.0323030017 0.0159719996 +0.0426970012 -0.0323030017 0.0090279998 +0.0426970012 -0.0323030017 -0.0090279998 +0.0426970012 -0.0323030017 -0.0159719996 +0.0426970012 -0.0323030017 -0.0340280011 +0.0426970012 -0.0323030017 -0.0409720019 +0.0426970012 -0.0340280011 0.0426970012 +0.0426970012 -0.0340280011 0.0323030017 +0.0426970012 -0.0340280011 0.0176970009 +0.0426970012 -0.0340280011 0.0073030000 +0.0426970012 -0.0340280011 -0.0073030000 +0.0426970012 -0.0340280011 -0.0176970009 +0.0426970012 -0.0340280011 -0.0323030017 +0.0426970012 -0.0340280011 -0.0426970012 +0.0426970012 -0.0409720019 0.0426970012 +0.0426970012 -0.0409720019 0.0323030017 +0.0426970012 -0.0409720019 0.0176970009 +0.0426970012 -0.0409720019 0.0073030000 +0.0426970012 -0.0409720019 -0.0323030017 +0.0426970012 -0.0409720019 -0.0426970012 +0.0426970012 -0.0426970012 0.0409720019 +0.0426970012 -0.0426970012 0.0340280011 +0.0426970012 -0.0426970012 0.0159719996 +0.0426970012 -0.0426970012 0.0090279998 +0.0426970012 -0.0426970012 -0.0340280011 +0.0426970012 -0.0426970012 -0.0409720019 +0.0426140018 0.0410929993 0.0323860012 +0.0426140018 0.0410929993 0.0176139995 +0.0426140018 0.0410929993 0.0073859999 +0.0426140018 0.0410929993 -0.0073859999 +0.0426140018 0.0410929993 -0.0176139995 +0.0426109992 -0.0176110007 -0.0089020003 +0.0426019989 0.0073980000 -0.0088910004 +0.0426019989 -0.0073980000 -0.0088910004 +0.0425910018 0.0175909996 0.0411260016 +0.0425399989 -0.0245479997 -0.0161969997 +0.0423199981 0.0335219987 -0.0323700011 +0.0422820002 -0.0415240005 -0.0026290000 +0.0420700014 0.0167629998 -0.0329300016 +0.0420700014 0.0082369996 -0.0329300016 +0.0420700014 -0.0082369996 -0.0329300016 +0.0420700014 -0.0167629998 -0.0329300016 +0.0420489982 -0.0417860001 -0.0205400009 +0.0420279987 -0.0247910004 -0.0168079995 +0.0419920012 0.0169920009 0.0331550017 +0.0419920012 0.0169920009 0.0168450009 +0.0419920012 0.0169920009 0.0081550004 +0.0419920012 0.0169920009 -0.0081550004 +0.0419440009 0.0331050009 0.0500000007 +0.0419359989 0.0419030003 0.0500000007 +0.0419190004 0.0500000007 0.0419190004 +0.0419190004 0.0500000007 0.0330809988 +0.0419190004 0.0500000007 0.0169190001 +0.0419190004 0.0500000007 0.0080810003 +0.0419190004 0.0500000007 -0.0080810003 +0.0419190004 0.0500000007 -0.0169190001 +0.0419190004 0.0500000007 -0.0330809988 +0.0419190004 0.0500000007 -0.0419190004 +0.0419190004 0.0419190004 0.0419190004 +0.0419190004 0.0419190004 0.0330809988 +0.0419190004 0.0419190004 0.0169190001 +0.0419190004 0.0419190004 0.0080810003 +0.0419190004 0.0419190004 -0.0080810003 +0.0419190004 0.0419190004 -0.0169190001 +0.0419190004 0.0419190004 -0.0330809988 +0.0419190004 0.0419190004 -0.0419190004 +0.0419190004 0.0419190004 -0.0500000007 +0.0419190004 0.0330809988 0.0419190004 +0.0419190004 0.0330809988 -0.0330809988 +0.0419190004 0.0330809988 -0.0419190004 +0.0419190004 0.0330809988 -0.0500000007 +0.0419190004 0.0169190001 0.0500000007 +0.0419190004 0.0169190001 0.0419190004 +0.0419190004 0.0169190001 0.0330809988 +0.0419190004 0.0169190001 0.0169190001 +0.0419190004 0.0169190001 0.0080810003 +0.0419190004 0.0169190001 -0.0080810003 +0.0419190004 0.0169190001 -0.0330809988 +0.0419190004 0.0169190001 -0.0419190004 +0.0419190004 0.0169190001 -0.0500000007 +0.0419190004 0.0080810003 0.0500000007 +0.0419190004 0.0080810003 0.0419190004 +0.0419190004 0.0080810003 0.0330809988 +0.0419190004 0.0080810003 0.0169190001 +0.0419190004 0.0080810003 0.0080810003 +0.0419190004 0.0080810003 -0.0080810003 +0.0419190004 0.0080810003 -0.0330809988 +0.0419190004 0.0080810003 -0.0419190004 +0.0419190004 0.0080810003 -0.0500000007 +0.0419190004 -0.0080810003 0.0500000007 +0.0419190004 -0.0080810003 0.0419190004 +0.0419190004 -0.0080810003 0.0330809988 +0.0419190004 -0.0080810003 0.0169190001 +0.0419190004 -0.0080810003 0.0080810003 +0.0419190004 -0.0080810003 -0.0080810003 +0.0419190004 -0.0080810003 -0.0330809988 +0.0419190004 -0.0080810003 -0.0419190004 +0.0419190004 -0.0080810003 -0.0500000007 +0.0419190004 -0.0169190001 0.0500000007 +0.0419190004 -0.0169190001 0.0419190004 +0.0419190004 -0.0169190001 0.0330809988 +0.0419190004 -0.0169190001 0.0169190001 +0.0419190004 -0.0169190001 0.0080810003 +0.0419190004 -0.0169190001 -0.0080810003 +0.0419190004 -0.0169190001 -0.0330809988 +0.0419190004 -0.0169190001 -0.0419190004 +0.0419190004 -0.0169190001 -0.0500000007 +0.0419190004 -0.0330809988 0.0500000007 +0.0419190004 -0.0330809988 0.0419190004 +0.0419190004 -0.0330809988 0.0330809988 +0.0419190004 -0.0330809988 0.0169190001 +0.0419190004 -0.0330809988 0.0080810003 +0.0419190004 -0.0330809988 -0.0080810003 +0.0419190004 -0.0330809988 -0.0169190001 +0.0419190004 -0.0330809988 -0.0330809988 +0.0419190004 -0.0330809988 -0.0419190004 +0.0419190004 -0.0330809988 -0.0500000007 +0.0419190004 -0.0419190004 0.0500000007 +0.0419190004 -0.0419190004 0.0419190004 +0.0419190004 -0.0419190004 0.0330809988 +0.0419190004 -0.0419190004 0.0169190001 +0.0419190004 -0.0419190004 0.0080810003 +0.0419190004 -0.0419190004 -0.0330809988 +0.0419190004 -0.0419190004 -0.0419190004 +0.0419190004 -0.0419190004 -0.0500000007 +0.0419190004 -0.0500000007 0.0419190004 +0.0419190004 -0.0500000007 0.0330809988 +0.0419190004 -0.0500000007 0.0169190001 +0.0419190004 -0.0500000007 0.0080810003 +0.0419190004 -0.0500000007 -0.0330809988 +0.0419190004 -0.0500000007 -0.0419190004 +0.0418450013 0.0169920009 0.0330080017 +0.0418450013 0.0169920009 0.0169920009 +0.0418450013 0.0169920009 0.0080080004 +0.0418450013 0.0169920009 -0.0080080004 +0.0417630002 0.0307030007 -0.0329300016 +0.0417630002 0.0170699991 -0.0329300016 +0.0417630002 0.0079300003 -0.0329300016 +0.0417630002 -0.0079300003 -0.0329300016 +0.0417630002 -0.0170699991 -0.0329300016 +0.0417630002 -0.0178120006 -0.0329300016 +0.0417010002 -0.0187279992 -0.0328730009 +0.0416910015 0.0316909999 -0.0328629985 +0.0415100008 -0.0422939993 -0.0034020001 +0.0415030010 -0.0196390003 -0.0326999985 +0.0414600000 0.0326640010 -0.0326640010 +0.0414209999 -0.0249589998 -0.0173669998 +0.0411720015 -0.0204489995 -0.0324429981 +0.0411639996 -0.0425640009 -0.0214249995 +0.0411499999 0.0324259996 0.0425739996 +0.0409720019 0.0426970012 0.0426970012 +0.0409720019 0.0426970012 0.0323030017 +0.0409720019 0.0426970012 0.0176970009 +0.0409720019 0.0426970012 0.0073030000 +0.0409720019 0.0426970012 -0.0073030000 +0.0409720019 0.0426970012 -0.0176970009 +0.0409720019 0.0426970012 -0.0323030017 +0.0409720019 0.0426970012 -0.0426970012 +0.0409720019 0.0323030017 -0.0426970012 +0.0409720019 0.0176970009 0.0426970012 +0.0409720019 0.0176970009 -0.0426970012 +0.0409720019 0.0073030000 0.0426970012 +0.0409720019 0.0073030000 0.0323030017 +0.0409720019 0.0073030000 0.0176970009 +0.0409720019 0.0073030000 0.0073030000 +0.0409720019 0.0073030000 -0.0073030000 +0.0409720019 0.0073030000 -0.0426970012 +0.0409720019 -0.0073030000 0.0426970012 +0.0409720019 -0.0073030000 0.0323030017 +0.0409720019 -0.0073030000 0.0176970009 +0.0409720019 -0.0073030000 0.0073030000 +0.0409720019 -0.0073030000 -0.0073030000 +0.0409720019 -0.0073030000 -0.0426970012 +0.0409720019 -0.0176970009 0.0426970012 +0.0409720019 -0.0176970009 0.0323030017 +0.0409720019 -0.0176970009 0.0176970009 +0.0409720019 -0.0176970009 0.0073030000 +0.0409720019 -0.0176970009 -0.0073030000 +0.0409720019 -0.0176970009 -0.0426970012 +0.0409720019 -0.0323030017 0.0426970012 +0.0409720019 -0.0323030017 0.0323030017 +0.0409720019 -0.0323030017 0.0176970009 +0.0409720019 -0.0323030017 0.0073030000 +0.0409720019 -0.0323030017 -0.0073030000 +0.0409720019 -0.0323030017 -0.0176970009 +0.0409720019 -0.0323030017 -0.0323030017 +0.0409720019 -0.0323030017 -0.0426970012 +0.0409720019 -0.0426970012 0.0426970012 +0.0409720019 -0.0426970012 0.0323030017 +0.0409720019 -0.0426970012 0.0176970009 +0.0409720019 -0.0426970012 0.0073030000 +0.0409720019 -0.0426970012 -0.0323030017 +0.0409720019 -0.0426970012 -0.0426970012 +0.0407299995 -0.0250669997 -0.0178510007 +0.0406729989 -0.0211830009 -0.0321150012 +0.0406650007 0.0321110003 0.0500000007 +0.0406519994 0.0428970009 0.0500000007 +0.0406249985 0.0500000007 0.0429130010 +0.0406249985 0.0500000007 0.0320869982 +0.0406249985 0.0500000007 0.0179130007 +0.0406249985 0.0500000007 0.0070870002 +0.0406249985 0.0500000007 -0.0070870002 +0.0406249985 0.0500000007 -0.0179130007 +0.0406249985 0.0500000007 -0.0320869982 +0.0406249985 0.0500000007 -0.0429130010 +0.0406249985 0.0429130010 -0.0500000007 +0.0406249985 0.0320869982 -0.0500000007 +0.0406249985 0.0179130007 0.0500000007 +0.0406249985 0.0179130007 -0.0500000007 +0.0406249985 0.0070870002 0.0500000007 +0.0406249985 0.0070870002 -0.0500000007 +0.0406249985 -0.0070870002 0.0500000007 +0.0406249985 -0.0070870002 -0.0500000007 +0.0406249985 -0.0179130007 0.0500000007 +0.0406249985 -0.0179130007 -0.0500000007 +0.0406249985 -0.0320869982 0.0500000007 +0.0406249985 -0.0320869982 -0.0500000007 +0.0406249985 -0.0429130010 0.0500000007 +0.0406249985 -0.0429130010 -0.0500000007 +0.0406249985 -0.0500000007 0.0429130010 +0.0406249985 -0.0500000007 0.0320869982 +0.0406249985 -0.0500000007 0.0179130007 +0.0406249985 -0.0500000007 0.0070870002 +0.0406249985 -0.0500000007 -0.0320869982 +0.0406249985 -0.0500000007 -0.0429130010 +0.0406140015 -0.0429189987 -0.0042969999 +0.0402849987 0.0319049992 0.0430950001 +0.0401480012 -0.0431619994 -0.0224409997 +0.0400439985 -0.0217509996 -0.0317910016 +0.0399719998 -0.0251300000 -0.0182399992 +0.0398919992 0.0432740003 0.0432740003 +0.0398919992 0.0432740003 0.0317259990 +0.0398919992 0.0432740003 0.0182739999 +0.0398919992 0.0432740003 0.0067260000 +0.0398919992 0.0432740003 -0.0067260000 +0.0398919992 0.0432740003 -0.0182739999 +0.0398919992 0.0432740003 -0.0317259990 +0.0398919992 0.0432740003 -0.0432740003 +0.0398919992 0.0317259990 -0.0432740003 +0.0398919992 0.0182739999 0.0432740003 +0.0398919992 0.0182739999 -0.0432740003 +0.0398919992 0.0067260000 0.0432740003 +0.0398919992 0.0067260000 0.0317259990 +0.0398919992 0.0067260000 0.0182739999 +0.0398919992 0.0067260000 0.0067260000 +0.0398919992 0.0067260000 -0.0067260000 +0.0398919992 0.0067260000 -0.0432740003 +0.0398919992 -0.0067260000 0.0432740003 +0.0398919992 -0.0067260000 0.0317259990 +0.0398919992 -0.0067260000 0.0182739999 +0.0398919992 -0.0067260000 0.0067260000 +0.0398919992 -0.0067260000 -0.0067260000 +0.0398919992 -0.0067260000 -0.0432740003 +0.0398919992 -0.0182739999 0.0432740003 +0.0398919992 -0.0182739999 0.0317259990 +0.0398919992 -0.0182739999 0.0182739999 +0.0398919992 -0.0182739999 0.0067260000 +0.0398919992 -0.0182739999 -0.0067260000 +0.0398919992 -0.0182739999 -0.0432740003 +0.0398919992 -0.0317259990 0.0432740003 +0.0398919992 -0.0317259990 0.0317259990 +0.0398919992 -0.0317259990 0.0182739999 +0.0398919992 -0.0317259990 0.0067260000 +0.0398919992 -0.0317259990 -0.0067260000 +0.0398919992 -0.0317259990 -0.0182739999 +0.0398919992 -0.0317259990 -0.0317259990 +0.0398919992 -0.0317259990 -0.0432740003 +0.0398919992 -0.0432740003 0.0432740003 +0.0398919992 -0.0432740003 0.0317259990 +0.0398919992 -0.0432740003 0.0182739999 +0.0398919992 -0.0432740003 0.0067260000 +0.0398919992 -0.0432740003 -0.0317259990 +0.0398919992 -0.0432740003 -0.0432740003 +0.0396240018 -0.0433779992 -0.0052870000 +0.0393470004 0.0315289982 0.0434710011 +0.0392730013 -0.0221699998 -0.0315070003 +0.0391729996 0.0314779989 0.0500000007 +0.0391659997 -0.0251630004 -0.0185240004 +0.0391549990 0.0435269997 0.0500000007 +0.0391179994 0.0500000007 0.0435369983 +0.0391179994 0.0500000007 0.0314630009 +0.0391179994 0.0500000007 0.0185369998 +0.0391179994 0.0500000007 0.0064630001 +0.0391179994 0.0500000007 -0.0064630001 +0.0391179994 0.0500000007 -0.0185369998 +0.0391179994 0.0500000007 -0.0314630009 +0.0391179994 0.0500000007 -0.0435369983 +0.0391179994 0.0435369983 -0.0500000007 +0.0391179994 0.0314630009 -0.0500000007 +0.0391179994 0.0185369998 0.0500000007 +0.0391179994 0.0185369998 -0.0500000007 +0.0391179994 0.0064630001 0.0500000007 +0.0391179994 0.0064630001 -0.0500000007 +0.0391179994 -0.0064630001 0.0500000007 +0.0391179994 -0.0064630001 -0.0500000007 +0.0391179994 -0.0185369998 0.0500000007 +0.0391179994 -0.0185369998 -0.0500000007 +0.0391179994 -0.0314630009 0.0500000007 +0.0391179994 -0.0314630009 -0.0500000007 +0.0391179994 -0.0435369983 0.0500000007 +0.0391179994 -0.0435369983 -0.0500000007 +0.0391179994 -0.0500000007 0.0435369983 +0.0391179994 -0.0500000007 0.0314630009 +0.0391179994 -0.0500000007 0.0185369998 +0.0391179994 -0.0500000007 0.0064630001 +0.0391179994 -0.0500000007 -0.0314630009 +0.0391179994 -0.0500000007 -0.0435369983 +0.0390370004 -0.0435580015 -0.0235510003 +0.0387189984 0.0436300002 0.0436300002 +0.0387189984 0.0436300002 0.0313699991 +0.0387189984 0.0436300002 0.0186299998 +0.0387189984 0.0436300002 0.0063700001 +0.0387189984 0.0436300002 -0.0063700001 +0.0387189984 0.0436300002 -0.0186299998 +0.0387189984 0.0436300002 -0.0313699991 +0.0387189984 0.0436300002 -0.0436300002 +0.0387189984 0.0313699991 -0.0436300002 +0.0387189984 0.0186299998 0.0436300002 +0.0387189984 0.0186299998 -0.0436300002 +0.0387189984 0.0063700001 0.0436300002 +0.0387189984 0.0063700001 0.0313699991 +0.0387189984 0.0063700001 0.0186299998 +0.0387189984 0.0063700001 0.0063700001 +0.0387189984 0.0063700001 -0.0063700001 +0.0387189984 0.0063700001 -0.0436300002 +0.0387189984 -0.0063700001 0.0436300002 +0.0387189984 -0.0063700001 0.0313699991 +0.0387189984 -0.0063700001 0.0186299998 +0.0387189984 -0.0063700001 0.0063700001 +0.0387189984 -0.0063700001 -0.0063700001 +0.0387189984 -0.0063700001 -0.0436300002 +0.0387189984 -0.0186299998 0.0436300002 +0.0387189984 -0.0186299998 0.0313699991 +0.0387189984 -0.0186299998 0.0186299998 +0.0387189984 -0.0186299998 0.0063700001 +0.0387189984 -0.0186299998 -0.0063700001 +0.0387189984 -0.0186299998 -0.0436300002 +0.0387189984 -0.0313699991 0.0436300002 +0.0387189984 -0.0313699991 0.0313699991 +0.0387189984 -0.0313699991 0.0186299998 +0.0387189984 -0.0313699991 0.0063700001 +0.0387189984 -0.0313699991 -0.0063700001 +0.0387189984 -0.0313699991 -0.0186299998 +0.0387189984 -0.0313699991 -0.0313699991 +0.0387189984 -0.0313699991 -0.0436300002 +0.0387189984 -0.0436300002 0.0436300002 +0.0387189984 -0.0436300002 0.0313699991 +0.0387189984 -0.0436300002 0.0186299998 +0.0387189984 -0.0436300002 0.0063700001 +0.0387189984 -0.0436300002 -0.0313699991 +0.0387189984 -0.0436300002 -0.0436300002 +0.0385689996 -0.0436579995 -0.0063419999 +0.0385689996 -0.0500000007 -0.0063419999 +0.0383989997 -0.0224210005 -0.0313149989 +0.0383620001 0.0313099995 0.0436899997 +0.0383340009 -0.0251770001 -0.0186940003 +0.0381130017 0.0437199995 0.0437199995 +0.0381130017 0.0437199995 0.0312799998 +0.0381130017 0.0437199995 0.0187199991 +0.0381130017 0.0437199995 0.0062799999 +0.0381130017 0.0437199995 -0.0062799999 +0.0381130017 0.0437199995 -0.0187199991 +0.0381130017 0.0437199995 -0.0312799998 +0.0381130017 0.0437199995 -0.0437199995 +0.0381130017 0.0312799998 -0.0437199995 +0.0381130017 0.0187199991 0.0437199995 +0.0381130017 0.0187199991 -0.0437199995 +0.0381130017 0.0062799999 0.0437199995 +0.0381130017 0.0062799999 0.0312799998 +0.0381130017 0.0062799999 0.0187199991 +0.0381130017 0.0062799999 0.0062799999 +0.0381130017 0.0062799999 -0.0062799999 +0.0381130017 0.0062799999 -0.0437199995 +0.0381130017 -0.0062799999 0.0437199995 +0.0381130017 -0.0062799999 0.0312799998 +0.0381130017 -0.0062799999 0.0187199991 +0.0381130017 -0.0062799999 0.0062799999 +0.0381130017 -0.0062799999 -0.0062799999 +0.0381130017 -0.0062799999 -0.0437199995 +0.0381130017 -0.0187199991 0.0437199995 +0.0381130017 -0.0187199991 0.0312799998 +0.0381130017 -0.0187199991 0.0187199991 +0.0381130017 -0.0187199991 0.0062799999 +0.0381130017 -0.0187199991 -0.0062799999 +0.0381130017 -0.0187199991 -0.0437199995 +0.0381130017 -0.0312799998 0.0437199995 +0.0381130017 -0.0312799998 0.0312799998 +0.0381130017 -0.0312799998 0.0187199991 +0.0381130017 -0.0312799998 0.0062799999 +0.0381130017 -0.0312799998 -0.0062799999 +0.0381130017 -0.0312799998 -0.0187199991 +0.0381130017 -0.0312799998 -0.0312799998 +0.0381130017 -0.0312799998 -0.0437199995 +0.0381130017 -0.0437199995 0.0437199995 +0.0381130017 -0.0437199995 0.0312799998 +0.0381130017 -0.0437199995 0.0187199991 +0.0381130017 -0.0437199995 0.0062799999 +0.0381130017 -0.0437199995 -0.0312799998 +0.0381130017 -0.0437199995 -0.0437199995 +0.0378729999 -0.0437389985 -0.0247159991 +0.0378260016 -0.0437409990 -0.0062589999 +0.0375690013 0.0312500000 0.0500000007 +0.0375460014 0.0437499993 0.0500000007 +0.0375000015 0.0500000007 0.0437499993 +0.0375000015 0.0500000007 0.0312500000 +0.0375000015 0.0500000007 0.0187500007 +0.0375000015 0.0500000007 0.0062500001 +0.0375000015 0.0500000007 -0.0062500001 +0.0375000015 0.0500000007 -0.0187500007 +0.0375000015 0.0500000007 -0.0312500000 +0.0375000015 0.0500000007 -0.0437499993 +0.0375000015 0.0437499993 0.0437499993 +0.0375000015 0.0437499993 0.0312500000 +0.0375000015 0.0437499993 0.0187500007 +0.0375000015 0.0437499993 0.0062500001 +0.0375000015 0.0437499993 -0.0062500001 +0.0375000015 0.0437499993 -0.0187500007 +0.0375000015 0.0437499993 -0.0312500000 +0.0375000015 0.0437499993 -0.0437499993 +0.0375000015 0.0437499993 -0.0500000007 +0.0375000015 0.0312500000 -0.0437499993 +0.0375000015 0.0312500000 -0.0500000007 +0.0375000015 0.0187500007 0.0500000007 +0.0375000015 0.0187500007 0.0437499993 +0.0375000015 0.0187500007 -0.0437499993 +0.0375000015 0.0187500007 -0.0500000007 +0.0375000015 0.0062500001 0.0500000007 +0.0375000015 0.0062500001 0.0437499993 +0.0375000015 0.0062500001 0.0312500000 +0.0375000015 0.0062500001 0.0187500007 +0.0375000015 0.0062500001 0.0062500001 +0.0375000015 0.0062500001 -0.0062500001 +0.0375000015 0.0062500001 -0.0437499993 +0.0375000015 0.0062500001 -0.0500000007 +0.0375000015 -0.0062500001 0.0500000007 +0.0375000015 -0.0062500001 0.0437499993 +0.0375000015 -0.0062500001 0.0312500000 +0.0375000015 -0.0062500001 0.0187500007 +0.0375000015 -0.0062500001 0.0062500001 +0.0375000015 -0.0062500001 -0.0062500001 +0.0375000015 -0.0062500001 -0.0437499993 +0.0375000015 -0.0062500001 -0.0500000007 +0.0375000015 -0.0187500007 0.0500000007 +0.0375000015 -0.0187500007 0.0437499993 +0.0375000015 -0.0187500007 0.0312500000 +0.0375000015 -0.0187500007 0.0187500007 +0.0375000015 -0.0187500007 0.0062500001 +0.0375000015 -0.0187500007 -0.0062500001 +0.0375000015 -0.0187500007 -0.0437499993 +0.0375000015 -0.0187500007 -0.0500000007 +0.0375000015 -0.0225009993 -0.0312500000 +0.0375000015 -0.0251800008 -0.0187500007 +0.0375000015 -0.0312500000 0.0500000007 +0.0375000015 -0.0312500000 0.0437499993 +0.0375000015 -0.0312500000 0.0312500000 +0.0375000015 -0.0312500000 0.0187500007 +0.0375000015 -0.0312500000 0.0062500001 +0.0375000015 -0.0312500000 -0.0062500001 +0.0375000015 -0.0312500000 -0.0187500007 +0.0375000015 -0.0312500000 -0.0312500000 +0.0375000015 -0.0312500000 -0.0437499993 +0.0375000015 -0.0312500000 -0.0500000007 +0.0375000015 -0.0437499993 0.0500000007 +0.0375000015 -0.0437499993 0.0437499993 +0.0375000015 -0.0437499993 0.0312500000 +0.0375000015 -0.0437499993 0.0187500007 +0.0375000015 -0.0437499993 0.0062500001 +0.0375000015 -0.0437499993 -0.0312500000 +0.0375000015 -0.0437499993 -0.0437499993 +0.0375000015 -0.0437499993 -0.0500000007 +0.0375000015 -0.0500000007 0.0437499993 +0.0375000015 -0.0500000007 0.0312500000 +0.0375000015 -0.0500000007 0.0187500007 +0.0375000015 -0.0500000007 0.0062500001 +0.0375000015 -0.0500000007 -0.0312500000 +0.0375000015 -0.0500000007 -0.0437499993 +0.0373530015 0.0312520005 0.0437479988 +0.0372780003 0.0255820006 0.0500000007 +0.0372640006 0.0251700003 0.0437459983 +0.0372340009 0.0263030007 0.0437440015 +0.0370789990 0.0270990003 0.0500000007 +0.0370789990 0.0240659993 0.0500000007 +0.0370789990 -0.0437359996 -0.0062640002 +0.0370789990 -0.0500000007 -0.0062640002 +0.0370679982 0.0240279995 0.0437350012 +0.0369759984 0.0274410006 0.0437280014 +0.0368870012 0.0437199995 0.0437199995 +0.0368870012 0.0437199995 0.0312799998 +0.0368870012 0.0437199995 0.0187199991 +0.0368870012 0.0437199995 0.0062799999 +0.0368870012 0.0437199995 -0.0062799999 +0.0368870012 0.0437199995 -0.0187199991 +0.0368870012 0.0437199995 -0.0312799998 +0.0368870012 0.0437199995 -0.0437199995 +0.0368870012 0.0312799998 -0.0437199995 +0.0368870012 0.0187199991 0.0437199995 +0.0368870012 0.0187199991 -0.0437199995 +0.0368870012 0.0062799999 0.0437199995 +0.0368870012 0.0062799999 0.0312799998 +0.0368870012 0.0062799999 0.0187199991 +0.0368870012 0.0062799999 0.0062799999 +0.0368870012 0.0062799999 -0.0062799999 +0.0368870012 0.0062799999 -0.0437199995 +0.0368870012 -0.0062799999 0.0437199995 +0.0368870012 -0.0062799999 0.0312799998 +0.0368870012 -0.0062799999 0.0187199991 +0.0368870012 -0.0062799999 0.0062799999 +0.0368870012 -0.0062799999 -0.0062799999 +0.0368870012 -0.0062799999 -0.0437199995 +0.0368870012 -0.0187199991 0.0437199995 +0.0368870012 -0.0187199991 0.0312799998 +0.0368870012 -0.0187199991 0.0187199991 +0.0368870012 -0.0187199991 0.0062799999 +0.0368870012 -0.0187199991 -0.0062799999 +0.0368870012 -0.0187199991 -0.0437199995 +0.0368870012 -0.0312799998 0.0437199995 +0.0368870012 -0.0312799998 0.0312799998 +0.0368870012 -0.0312799998 0.0187199991 +0.0368870012 -0.0312799998 0.0062799999 +0.0368870012 -0.0312799998 -0.0062799999 +0.0368870012 -0.0312799998 -0.0187199991 +0.0368870012 -0.0312799998 -0.0312799998 +0.0368870012 -0.0312799998 -0.0437199995 +0.0368870012 -0.0437199995 0.0437199995 +0.0368870012 -0.0437199995 0.0312799998 +0.0368870012 -0.0437199995 0.0187199991 +0.0368870012 -0.0437199995 0.0062799999 +0.0368870012 -0.0437199995 -0.0312799998 +0.0368870012 -0.0437199995 -0.0437199995 +0.0366940014 -0.0436980017 -0.0258939993 +0.0366659984 -0.0251770001 -0.0186940003 +0.0366440006 0.0229310002 0.0436910018 +0.0366009995 -0.0224210005 -0.0313149989 +0.0364929996 0.0285119992 0.0500000007 +0.0364929996 0.0285119992 0.0436679982 +0.0364929996 0.0226520002 0.0500000007 +0.0363489985 0.0313570015 0.0436430015 +0.0363369994 -0.0436410010 -0.0063590002 +0.0362810008 0.0436300002 0.0436300002 +0.0362810008 0.0436300002 0.0313699991 +0.0362810008 0.0436300002 0.0186299998 +0.0362810008 0.0436300002 0.0063700001 +0.0362810008 0.0436300002 -0.0063700001 +0.0362810008 0.0436300002 -0.0186299998 +0.0362810008 0.0436300002 -0.0313699991 +0.0362810008 0.0436300002 -0.0436300002 +0.0362810008 0.0313699991 -0.0436300002 +0.0362810008 0.0186299998 0.0436300002 +0.0362810008 0.0186299998 -0.0436300002 +0.0362810008 0.0063700001 0.0436300002 +0.0362810008 0.0063700001 0.0313699991 +0.0362810008 0.0063700001 0.0186299998 +0.0362810008 0.0063700001 0.0063700001 +0.0362810008 0.0063700001 -0.0063700001 +0.0362810008 0.0063700001 -0.0436300002 +0.0362810008 -0.0063700001 0.0436300002 +0.0362810008 -0.0063700001 0.0313699991 +0.0362810008 -0.0063700001 0.0186299998 +0.0362810008 -0.0063700001 0.0063700001 +0.0362810008 -0.0063700001 -0.0063700001 +0.0362810008 -0.0063700001 -0.0436300002 +0.0362810008 -0.0186299998 0.0436300002 +0.0362810008 -0.0186299998 0.0313699991 +0.0362810008 -0.0186299998 0.0186299998 +0.0362810008 -0.0186299998 0.0063700001 +0.0362810008 -0.0186299998 -0.0063700001 +0.0362810008 -0.0186299998 -0.0436300002 +0.0362810008 -0.0313699991 0.0436300002 +0.0362810008 -0.0313699991 0.0313699991 +0.0362810008 -0.0313699991 0.0186299998 +0.0362810008 -0.0313699991 0.0063700001 +0.0362810008 -0.0313699991 -0.0063700001 +0.0362810008 -0.0313699991 -0.0186299998 +0.0362810008 -0.0313699991 -0.0313699991 +0.0362810008 -0.0313699991 -0.0436300002 +0.0362810008 -0.0436300002 0.0436300002 +0.0362810008 -0.0436300002 0.0313699991 +0.0362810008 -0.0436300002 0.0186299998 +0.0362810008 -0.0436300002 0.0063700001 +0.0362810008 -0.0436300002 -0.0313699991 +0.0362810008 -0.0436300002 -0.0436300002 +0.0360210016 0.0219550002 0.0435720012 +0.0359609984 0.0314429998 0.0500000007 +0.0359349996 0.0435510017 0.0500000007 +0.0358819999 0.0500000007 0.0435369983 +0.0358819999 0.0500000007 0.0314630009 +0.0358819999 0.0500000007 0.0185369998 +0.0358819999 0.0500000007 0.0064630001 +0.0358819999 0.0500000007 -0.0064630001 +0.0358819999 0.0500000007 -0.0185369998 +0.0358819999 0.0500000007 -0.0314630009 +0.0358819999 0.0500000007 -0.0435369983 +0.0358819999 0.0435369983 -0.0500000007 +0.0358819999 0.0314630009 -0.0500000007 +0.0358819999 0.0185369998 0.0500000007 +0.0358819999 0.0185369998 -0.0500000007 +0.0358819999 0.0064630001 0.0500000007 +0.0358819999 0.0064630001 -0.0500000007 +0.0358819999 -0.0064630001 0.0500000007 +0.0358819999 -0.0064630001 -0.0500000007 +0.0358819999 -0.0185369998 0.0500000007 +0.0358819999 -0.0185369998 -0.0500000007 +0.0358819999 -0.0314630009 0.0500000007 +0.0358819999 -0.0314630009 -0.0500000007 +0.0358819999 -0.0435369983 0.0500000007 +0.0358819999 -0.0435369983 -0.0500000007 +0.0358819999 -0.0500000007 0.0435369983 +0.0358819999 -0.0500000007 0.0314630009 +0.0358819999 -0.0500000007 0.0185369998 +0.0358819999 -0.0500000007 0.0064630001 +0.0358819999 -0.0500000007 -0.0314630009 +0.0358819999 -0.0500000007 -0.0435369983 +0.0358339995 -0.0251630004 -0.0185240004 +0.0357270017 -0.0221699998 -0.0315070003 +0.0356130004 -0.0434579998 -0.0065420000 +0.0356130004 -0.0500000007 -0.0065420000 +0.0355620012 0.0214389991 0.0500000007 +0.0355449989 -0.0434359983 -0.0270440001 +0.0353740007 0.0316229984 0.0433770008 +0.0352550000 0.0211529993 0.0433330014 +0.0351080000 0.0432740003 0.0432740003 +0.0351080000 0.0432740003 0.0317259990 +0.0351080000 0.0432740003 0.0182739999 +0.0351080000 0.0432740003 0.0067260000 +0.0351080000 0.0432740003 -0.0067260000 +0.0351080000 0.0432740003 -0.0182739999 +0.0351080000 0.0432740003 -0.0317259990 +0.0351080000 0.0432740003 -0.0432740003 +0.0351080000 0.0317259990 -0.0432740003 +0.0351080000 0.0182739999 0.0432740003 +0.0351080000 0.0182739999 -0.0432740003 +0.0351080000 0.0067260000 0.0432740003 +0.0351080000 0.0067260000 0.0317259990 +0.0351080000 0.0067260000 0.0182739999 +0.0351080000 0.0067260000 0.0067260000 +0.0351080000 0.0067260000 -0.0067260000 +0.0351080000 0.0067260000 -0.0432740003 +0.0351080000 -0.0067260000 0.0432740003 +0.0351080000 -0.0067260000 0.0317259990 +0.0351080000 -0.0067260000 0.0182739999 +0.0351080000 -0.0067260000 0.0067260000 +0.0351080000 -0.0067260000 -0.0067260000 +0.0351080000 -0.0067260000 -0.0432740003 +0.0351080000 -0.0182739999 0.0432740003 +0.0351080000 -0.0182739999 0.0317259990 +0.0351080000 -0.0182739999 0.0182739999 +0.0351080000 -0.0182739999 0.0067260000 +0.0351080000 -0.0182739999 -0.0067260000 +0.0351080000 -0.0182739999 -0.0432740003 +0.0351080000 -0.0317259990 0.0432740003 +0.0351080000 -0.0317259990 0.0317259990 +0.0351080000 -0.0317259990 0.0182739999 +0.0351080000 -0.0317259990 0.0067260000 +0.0351080000 -0.0317259990 -0.0067260000 +0.0351080000 -0.0317259990 -0.0182739999 +0.0351080000 -0.0317259990 -0.0317259990 +0.0351080000 -0.0317259990 -0.0432740003 +0.0351080000 -0.0432740003 0.0432740003 +0.0351080000 -0.0432740003 0.0317259990 +0.0351080000 -0.0432740003 0.0182739999 +0.0351080000 -0.0432740003 0.0067260000 +0.0351080000 -0.0432740003 -0.0317259990 +0.0351080000 -0.0432740003 -0.0432740003 +0.0350279994 -0.0251300000 -0.0182399992 +0.0349560007 -0.0217509996 -0.0317910016 +0.0349150002 -0.0431899987 -0.0068100002 +0.0344650000 -0.0429640003 -0.0281240009 +0.0344550014 0.0320420004 0.0500000007 +0.0344550014 0.0320420004 0.0429579988 +0.0344289988 0.0429430008 0.0500000007 +0.0343750007 0.0500000007 0.0429130010 +0.0343750007 0.0500000007 0.0320869982 +0.0343750007 0.0500000007 0.0179130007 +0.0343750007 0.0500000007 0.0070870002 +0.0343750007 0.0500000007 -0.0070870002 +0.0343750007 0.0500000007 -0.0179130007 +0.0343750007 0.0500000007 -0.0320869982 +0.0343750007 0.0500000007 -0.0429130010 +0.0343750007 0.0429130010 -0.0500000007 +0.0343750007 0.0320869982 -0.0500000007 +0.0343750007 0.0179130007 0.0500000007 +0.0343750007 0.0179130007 -0.0500000007 +0.0343750007 0.0070870002 0.0500000007 +0.0343750007 0.0070870002 -0.0500000007 +0.0343750007 -0.0070870002 0.0500000007 +0.0343750007 -0.0070870002 -0.0500000007 +0.0343750007 -0.0179130007 0.0500000007 +0.0343750007 -0.0179130007 -0.0500000007 +0.0343750007 -0.0320869982 0.0500000007 +0.0343750007 -0.0320869982 -0.0500000007 +0.0343750007 -0.0429130010 0.0500000007 +0.0343750007 -0.0429130010 -0.0500000007 +0.0343750007 -0.0500000007 0.0429130010 +0.0343750007 -0.0500000007 0.0320869982 +0.0343750007 -0.0500000007 0.0179130007 +0.0343750007 -0.0500000007 0.0070870002 +0.0343750007 -0.0500000007 -0.0320869982 +0.0343750007 -0.0500000007 -0.0429130010 +0.0343489982 0.0205080006 0.0500000007 +0.0343489982 0.0205080006 0.0428970009 +0.0343270004 -0.0211830009 -0.0321150012 +0.0342699997 -0.0250669997 -0.0178510007 +0.0342539996 -0.0428409986 -0.0071589998 +0.0342539996 -0.0500000007 -0.0071589998 +0.0340280011 0.0426970012 0.0426970012 +0.0340280011 0.0426970012 0.0323030017 +0.0340280011 0.0426970012 0.0176970009 +0.0340280011 0.0426970012 0.0073030000 +0.0340280011 0.0426970012 -0.0073030000 +0.0340280011 0.0426970012 -0.0176970009 +0.0340280011 0.0426970012 -0.0323030017 +0.0340280011 0.0426970012 -0.0426970012 +0.0340280011 0.0323030017 -0.0426970012 +0.0340280011 0.0176970009 0.0426970012 +0.0340280011 0.0176970009 -0.0426970012 +0.0340280011 0.0073030000 0.0426970012 +0.0340280011 0.0073030000 0.0323030017 +0.0340280011 0.0073030000 0.0176970009 +0.0340280011 0.0073030000 0.0073030000 +0.0340280011 0.0073030000 -0.0073030000 +0.0340280011 0.0073030000 -0.0426970012 +0.0340280011 -0.0073030000 0.0426970012 +0.0340280011 -0.0073030000 0.0323030017 +0.0340280011 -0.0073030000 0.0176970009 +0.0340280011 -0.0073030000 0.0073030000 +0.0340280011 -0.0073030000 -0.0073030000 +0.0340280011 -0.0073030000 -0.0426970012 +0.0340280011 -0.0176970009 0.0426970012 +0.0340280011 -0.0176970009 0.0323030017 +0.0340280011 -0.0176970009 0.0176970009 +0.0340280011 -0.0176970009 0.0073030000 +0.0340280011 -0.0176970009 -0.0073030000 +0.0340280011 -0.0176970009 -0.0426970012 +0.0340280011 -0.0323030017 0.0426970012 +0.0340280011 -0.0323030017 0.0323030017 +0.0340280011 -0.0323030017 0.0176970009 +0.0340280011 -0.0323030017 0.0073030000 +0.0340280011 -0.0323030017 -0.0073030000 +0.0340280011 -0.0323030017 -0.0176970009 +0.0340280011 -0.0323030017 -0.0323030017 +0.0340280011 -0.0323030017 -0.0426970012 +0.0340280011 -0.0426970012 0.0426970012 +0.0340280011 -0.0426970012 0.0323030017 +0.0340280011 -0.0426970012 0.0176970009 +0.0340280011 -0.0426970012 0.0073030000 +0.0340280011 -0.0426970012 -0.0323030017 +0.0340280011 -0.0426970012 -0.0426970012 +0.0338280015 -0.0204489995 -0.0324429981 +0.0335789993 -0.0249589998 -0.0173669998 +0.0335399993 0.0326640010 -0.0326640010 +0.0334969983 -0.0196390003 -0.0326999985 +0.0334930010 -0.0422969982 -0.0290959999 +0.0333090015 0.0316909999 -0.0328629985 +0.0332989991 -0.0187279992 -0.0328730009 +0.0332369991 0.0307030007 -0.0329300016 +0.0332369991 0.0170699991 -0.0329300016 +0.0332369991 0.0079300003 -0.0329300016 +0.0332369991 -0.0079300003 -0.0329300016 +0.0332369991 -0.0170699991 -0.0329300016 +0.0332369991 -0.0178120006 -0.0329300016 +0.0332069993 0.0198490005 0.0420419984 +0.0331550017 0.0169920009 0.0330080017 +0.0331550017 0.0169920009 0.0169920009 +0.0331550017 0.0169920009 0.0080080004 +0.0331550017 0.0169920009 -0.0080080004 +0.0331300013 0.0419679992 0.0500000007 +0.0330809988 0.0500000007 0.0419190004 +0.0330809988 0.0500000007 0.0330809988 +0.0330809988 0.0500000007 0.0169190001 +0.0330809988 0.0500000007 0.0080810003 +0.0330809988 0.0500000007 -0.0080810003 +0.0330809988 0.0500000007 -0.0169190001 +0.0330809988 0.0500000007 -0.0330809988 +0.0330809988 0.0500000007 -0.0419190004 +0.0330809988 0.0419190004 0.0419190004 +0.0330809988 0.0419190004 0.0330809988 +0.0330809988 0.0419190004 0.0169190001 +0.0330809988 0.0419190004 0.0080810003 +0.0330809988 0.0419190004 -0.0080810003 +0.0330809988 0.0419190004 -0.0169190001 +0.0330809988 0.0419190004 -0.0330809988 +0.0330809988 0.0419190004 -0.0419190004 +0.0330809988 0.0419190004 -0.0500000007 +0.0330809988 0.0330809988 -0.0330809988 +0.0330809988 0.0330809988 -0.0419190004 +0.0330809988 0.0330809988 -0.0500000007 +0.0330809988 0.0169190001 0.0500000007 +0.0330809988 0.0169190001 0.0419190004 +0.0330809988 0.0169190001 0.0330809988 +0.0330809988 0.0169190001 0.0169190001 +0.0330809988 0.0169190001 0.0080810003 +0.0330809988 0.0169190001 -0.0080810003 +0.0330809988 0.0169190001 -0.0330809988 +0.0330809988 0.0169190001 -0.0419190004 +0.0330809988 0.0169190001 -0.0500000007 +0.0330809988 0.0080810003 0.0500000007 +0.0330809988 0.0080810003 0.0419190004 +0.0330809988 0.0080810003 0.0330809988 +0.0330809988 0.0080810003 0.0169190001 +0.0330809988 0.0080810003 0.0080810003 +0.0330809988 0.0080810003 -0.0080810003 +0.0330809988 0.0080810003 -0.0330809988 +0.0330809988 0.0080810003 -0.0419190004 +0.0330809988 0.0080810003 -0.0500000007 +0.0330809988 -0.0080810003 0.0500000007 +0.0330809988 -0.0080810003 0.0419190004 +0.0330809988 -0.0080810003 0.0330809988 +0.0330809988 -0.0080810003 0.0169190001 +0.0330809988 -0.0080810003 0.0080810003 +0.0330809988 -0.0080810003 -0.0080810003 +0.0330809988 -0.0080810003 -0.0330809988 +0.0330809988 -0.0080810003 -0.0419190004 +0.0330809988 -0.0080810003 -0.0500000007 +0.0330809988 -0.0169190001 0.0500000007 +0.0330809988 -0.0169190001 0.0419190004 +0.0330809988 -0.0169190001 0.0330809988 +0.0330809988 -0.0169190001 0.0169190001 +0.0330809988 -0.0169190001 0.0080810003 +0.0330809988 -0.0169190001 -0.0080810003 +0.0330809988 -0.0169190001 -0.0330809988 +0.0330809988 -0.0169190001 -0.0419190004 +0.0330809988 -0.0169190001 -0.0500000007 +0.0330809988 -0.0330809988 0.0500000007 +0.0330809988 -0.0330809988 0.0419190004 +0.0330809988 -0.0330809988 0.0330809988 +0.0330809988 -0.0330809988 0.0169190001 +0.0330809988 -0.0330809988 0.0080810003 +0.0330809988 -0.0330809988 -0.0080810003 +0.0330809988 -0.0330809988 -0.0169190001 +0.0330809988 -0.0330809988 -0.0330809988 +0.0330809988 -0.0330809988 -0.0419190004 +0.0330809988 -0.0330809988 -0.0500000007 +0.0330809988 -0.0419190004 0.0500000007 +0.0330809988 -0.0419190004 0.0419190004 +0.0330809988 -0.0419190004 0.0330809988 +0.0330809988 -0.0419190004 0.0169190001 +0.0330809988 -0.0419190004 0.0080810003 +0.0330809988 -0.0419190004 -0.0080810003 +0.0330809988 -0.0419190004 -0.0330809988 +0.0330809988 -0.0419190004 -0.0419190004 +0.0330809988 -0.0419190004 -0.0500000007 +0.0330809988 -0.0500000007 0.0419190004 +0.0330809988 -0.0500000007 0.0330809988 +0.0330809988 -0.0500000007 0.0169190001 +0.0330809988 -0.0500000007 0.0080810003 +0.0330809988 -0.0500000007 -0.0080810003 +0.0330809988 -0.0500000007 -0.0330809988 +0.0330809988 -0.0500000007 -0.0419190004 +0.0330080017 0.0169920009 0.0331550017 +0.0330080017 0.0169920009 0.0168450009 +0.0330080017 0.0169920009 0.0081550004 +0.0330080017 0.0169920009 -0.0081550004 +0.0329720005 -0.0247910004 -0.0168079995 +0.0329300016 0.0167629998 -0.0329300016 +0.0329300016 0.0082369996 -0.0329300016 +0.0329300016 -0.0082369996 -0.0329300016 +0.0329300016 -0.0167629998 -0.0329300016 +0.0326800011 0.0335219987 -0.0323700011 +0.0326640010 -0.0414590016 -0.0299249999 +0.0324600004 -0.0245479997 -0.0161969997 +0.0324090011 0.0175909996 0.0411260016 +0.0324090011 -0.0411260016 -0.0324090011 +0.0323980004 0.0073980000 -0.0088910004 +0.0323980004 -0.0073980000 -0.0088910004 +0.0323890001 -0.0176110007 -0.0089020003 +0.0323860012 0.0410929993 0.0323860012 +0.0323860012 0.0410929993 0.0176139995 +0.0323860012 0.0410929993 0.0073859999 +0.0323860012 0.0410929993 -0.0073859999 +0.0323860012 0.0410929993 -0.0176139995 +0.0323159993 0.0409919992 0.0426840000 +0.0323030017 0.0426970012 0.0409720019 +0.0323030017 0.0426970012 0.0340280011 +0.0323030017 0.0426970012 0.0159719996 +0.0323030017 0.0426970012 0.0090279998 +0.0323030017 0.0426970012 -0.0090279998 +0.0323030017 0.0426970012 -0.0159719996 +0.0323030017 0.0426970012 -0.0340280011 +0.0323030017 0.0426970012 -0.0409720019 +0.0323030017 0.0409720019 -0.0323030017 +0.0323030017 0.0409720019 -0.0426970012 +0.0323030017 0.0340280011 -0.0323030017 +0.0323030017 0.0340280011 -0.0426970012 +0.0323030017 0.0323030017 -0.0340280011 +0.0323030017 0.0323030017 -0.0409720019 +0.0323030017 0.0176970009 -0.0340280011 +0.0323030017 0.0176970009 -0.0409720019 +0.0323030017 0.0159719996 0.0426970012 +0.0323030017 0.0159719996 0.0323030017 +0.0323030017 0.0159719996 0.0176970009 +0.0323030017 0.0159719996 0.0073030000 +0.0323030017 0.0159719996 -0.0073030000 +0.0323030017 0.0159719996 -0.0426970012 +0.0323030017 0.0090279998 0.0426970012 +0.0323030017 0.0090279998 0.0323030017 +0.0323030017 0.0090279998 0.0176970009 +0.0323030017 0.0090279998 0.0073030000 +0.0323030017 0.0090279998 -0.0073030000 +0.0323030017 0.0090279998 -0.0426970012 +0.0323030017 0.0073030000 0.0409720019 +0.0323030017 0.0073030000 0.0340280011 +0.0323030017 0.0073030000 0.0159719996 +0.0323030017 0.0073030000 0.0090279998 +0.0323030017 0.0073030000 -0.0340280011 +0.0323030017 0.0073030000 -0.0409720019 +0.0323030017 -0.0073030000 0.0409720019 +0.0323030017 -0.0073030000 0.0340280011 +0.0323030017 -0.0073030000 0.0159719996 +0.0323030017 -0.0073030000 0.0090279998 +0.0323030017 -0.0073030000 -0.0340280011 +0.0323030017 -0.0073030000 -0.0409720019 +0.0323030017 -0.0090279998 0.0426970012 +0.0323030017 -0.0090279998 0.0323030017 +0.0323030017 -0.0090279998 0.0176970009 +0.0323030017 -0.0090279998 0.0073030000 +0.0323030017 -0.0090279998 -0.0073030000 +0.0323030017 -0.0090279998 -0.0426970012 +0.0323030017 -0.0159719996 0.0426970012 +0.0323030017 -0.0159719996 0.0323030017 +0.0323030017 -0.0159719996 0.0176970009 +0.0323030017 -0.0159719996 0.0073030000 +0.0323030017 -0.0159719996 -0.0073030000 +0.0323030017 -0.0159719996 -0.0426970012 +0.0323030017 -0.0176970009 0.0409720019 +0.0323030017 -0.0176970009 0.0340280011 +0.0323030017 -0.0176970009 0.0159719996 +0.0323030017 -0.0176970009 0.0090279998 +0.0323030017 -0.0176970009 -0.0340280011 +0.0323030017 -0.0176970009 -0.0409720019 +0.0323030017 -0.0323030017 0.0409720019 +0.0323030017 -0.0323030017 0.0340280011 +0.0323030017 -0.0323030017 0.0159719996 +0.0323030017 -0.0323030017 0.0090279998 +0.0323030017 -0.0323030017 -0.0090279998 +0.0323030017 -0.0323030017 -0.0159719996 +0.0323030017 -0.0323030017 -0.0340280011 +0.0323030017 -0.0323030017 -0.0409720019 +0.0323030017 -0.0340280011 0.0426970012 +0.0323030017 -0.0340280011 0.0323030017 +0.0323030017 -0.0340280011 0.0176970009 +0.0323030017 -0.0340280011 0.0073030000 +0.0323030017 -0.0340280011 -0.0073030000 +0.0323030017 -0.0340280011 -0.0176970009 +0.0323030017 -0.0340280011 -0.0323030017 +0.0323030017 -0.0340280011 -0.0426970012 +0.0323030017 -0.0409720019 0.0426970012 +0.0323030017 -0.0409720019 0.0323030017 +0.0323030017 -0.0409720019 0.0176970009 +0.0323030017 -0.0409720019 0.0073030000 +0.0323030017 -0.0409720019 -0.0073030000 +0.0323030017 -0.0409720019 -0.0426970012 +0.0323030017 -0.0426970012 0.0409720019 +0.0323030017 -0.0426970012 0.0340280011 +0.0323030017 -0.0426970012 0.0159719996 +0.0323030017 -0.0426970012 0.0090279998 +0.0323030017 -0.0426970012 -0.0340280011 +0.0323030017 -0.0426970012 -0.0409720019 +0.0322889984 0.0193189997 0.0409509987 +0.0321590006 -0.0428409986 -0.0092540001 +0.0321590006 -0.0500000007 -0.0092540001 +0.0321259983 0.0406920016 0.0500000007 +0.0320869982 0.0500000007 0.0406249985 +0.0320869982 0.0500000007 0.0343750007 +0.0320869982 0.0500000007 0.0156250000 +0.0320869982 0.0500000007 0.0093750004 +0.0320869982 0.0500000007 -0.0093750004 +0.0320869982 0.0500000007 -0.0156250000 +0.0320869982 0.0500000007 -0.0343750007 +0.0320869982 0.0500000007 -0.0406249985 +0.0320869982 0.0406249985 -0.0500000007 +0.0320869982 0.0343750007 -0.0500000007 +0.0320869982 0.0156250000 0.0500000007 +0.0320869982 0.0156250000 -0.0500000007 +0.0320869982 0.0093750004 0.0500000007 +0.0320869982 0.0093750004 -0.0500000007 +0.0320869982 -0.0093750004 0.0500000007 +0.0320869982 -0.0093750004 -0.0500000007 +0.0320869982 -0.0156250000 0.0500000007 +0.0320869982 -0.0156250000 -0.0500000007 +0.0320869982 -0.0343750007 0.0500000007 +0.0320869982 -0.0343750007 -0.0500000007 +0.0320869982 -0.0406249985 0.0500000007 +0.0320869982 -0.0406249985 -0.0500000007 +0.0320869982 -0.0500000007 0.0406249985 +0.0320869982 -0.0500000007 0.0343750007 +0.0320869982 -0.0500000007 0.0156250000 +0.0320869982 -0.0500000007 0.0093750004 +0.0320869982 -0.0500000007 -0.0343750007 +0.0320869982 -0.0500000007 -0.0406249985 +0.0320370011 -0.0242110007 -0.0155360000 +0.0320249982 0.0344859995 -0.0318869986 +0.0320059992 -0.0404799990 -0.0305819996 +0.0318790004 0.0181210004 0.0402319990 +0.0318790004 -0.0402319990 -0.0318790004 +0.0318609998 0.0068609999 -0.0098040001 +0.0318609998 -0.0068609999 -0.0098040001 +0.0318490006 -0.0181510001 -0.0098299999 +0.0318440013 0.0401600003 0.0318440013 +0.0318440013 0.0401600003 0.0181559995 +0.0318440013 0.0401600003 0.0068440000 +0.0318440013 0.0401600003 -0.0068440000 +0.0318440013 0.0401600003 -0.0181559995 +0.0318100005 -0.0431899987 -0.0099149998 +0.0317439996 0.0399339981 0.0432559997 +0.0317259990 0.0432740003 0.0398919992 +0.0317259990 0.0432740003 0.0351080000 +0.0317259990 0.0432740003 0.0148919998 +0.0317259990 0.0432740003 0.0101079997 +0.0317259990 0.0432740003 -0.0101079997 +0.0317259990 0.0432740003 -0.0148919998 +0.0317259990 0.0432740003 -0.0351080000 +0.0317259990 0.0432740003 -0.0398919992 +0.0317259990 0.0398919992 -0.0317259990 +0.0317259990 0.0398919992 -0.0432740003 +0.0317259990 0.0351080000 -0.0317259990 +0.0317259990 0.0351080000 -0.0432740003 +0.0317259990 0.0317259990 -0.0351080000 +0.0317259990 0.0317259990 -0.0398919992 +0.0317259990 0.0182739999 -0.0351080000 +0.0317259990 0.0182739999 -0.0398919992 +0.0317259990 0.0148919998 0.0432740003 +0.0317259990 0.0148919998 0.0317259990 +0.0317259990 0.0148919998 0.0182739999 +0.0317259990 0.0148919998 0.0067260000 +0.0317259990 0.0148919998 -0.0067260000 +0.0317259990 0.0148919998 -0.0432740003 +0.0317259990 0.0101079997 0.0432740003 +0.0317259990 0.0101079997 0.0317259990 +0.0317259990 0.0101079997 0.0182739999 +0.0317259990 0.0101079997 0.0067260000 +0.0317259990 0.0101079997 -0.0067260000 +0.0317259990 0.0101079997 -0.0432740003 +0.0317259990 0.0067260000 0.0398919992 +0.0317259990 0.0067260000 0.0351080000 +0.0317259990 0.0067260000 0.0148919998 +0.0317259990 0.0067260000 0.0101079997 +0.0317259990 0.0067260000 -0.0351080000 +0.0317259990 0.0067260000 -0.0398919992 +0.0317259990 -0.0067260000 0.0398919992 +0.0317259990 -0.0067260000 0.0351080000 +0.0317259990 -0.0067260000 0.0148919998 +0.0317259990 -0.0067260000 0.0101079997 +0.0317259990 -0.0067260000 -0.0351080000 +0.0317259990 -0.0067260000 -0.0398919992 +0.0317259990 -0.0101079997 0.0432740003 +0.0317259990 -0.0101079997 0.0317259990 +0.0317259990 -0.0101079997 0.0182739999 +0.0317259990 -0.0101079997 0.0067260000 +0.0317259990 -0.0101079997 -0.0067260000 +0.0317259990 -0.0101079997 -0.0432740003 +0.0317259990 -0.0148919998 0.0432740003 +0.0317259990 -0.0148919998 0.0317259990 +0.0317259990 -0.0148919998 0.0182739999 +0.0317259990 -0.0148919998 0.0067260000 +0.0317259990 -0.0148919998 -0.0067260000 +0.0317259990 -0.0148919998 -0.0432740003 +0.0317259990 -0.0182739999 0.0398919992 +0.0317259990 -0.0182739999 0.0351080000 +0.0317259990 -0.0182739999 0.0148919998 +0.0317259990 -0.0182739999 0.0101079997 +0.0317259990 -0.0182739999 -0.0351080000 +0.0317259990 -0.0182739999 -0.0398919992 +0.0317259990 -0.0317259990 0.0398919992 +0.0317259990 -0.0317259990 0.0351080000 +0.0317259990 -0.0317259990 0.0148919998 +0.0317259990 -0.0317259990 0.0101079997 +0.0317259990 -0.0317259990 -0.0101079997 +0.0317259990 -0.0317259990 -0.0148919998 +0.0317259990 -0.0317259990 -0.0351080000 +0.0317259990 -0.0317259990 -0.0398919992 +0.0317259990 -0.0351080000 0.0432740003 +0.0317259990 -0.0351080000 0.0317259990 +0.0317259990 -0.0351080000 0.0182739999 +0.0317259990 -0.0351080000 0.0067260000 +0.0317259990 -0.0351080000 -0.0067260000 +0.0317259990 -0.0351080000 -0.0182739999 +0.0317259990 -0.0351080000 -0.0317259990 +0.0317259990 -0.0351080000 -0.0432740003 +0.0317259990 -0.0398919992 0.0432740003 +0.0317259990 -0.0398919992 0.0317259990 +0.0317259990 -0.0398919992 0.0182739999 +0.0317259990 -0.0398919992 0.0067260000 +0.0317259990 -0.0398919992 -0.0067260000 +0.0317259990 -0.0398919992 -0.0432740003 +0.0317259990 -0.0432740003 0.0398919992 +0.0317259990 -0.0432740003 0.0351080000 +0.0317259990 -0.0432740003 0.0148919998 +0.0317259990 -0.0432740003 0.0101079997 +0.0317259990 -0.0432740003 -0.0351080000 +0.0317259990 -0.0432740003 -0.0398919992 +0.0317060016 -0.0237590000 -0.0148440003 +0.0316420011 0.0189449992 0.0396800004 +0.0315789990 0.0354989991 -0.0311600007 +0.0315439999 -0.0393959992 -0.0310440008 +0.0315419994 -0.0434579998 -0.0106130000 +0.0315419994 -0.0500000007 -0.0106130000 +0.0315040015 0.0184959993 0.0392629988 +0.0315040015 -0.0392620005 -0.0315040015 +0.0314869992 0.0064869998 -0.0107960002 +0.0314869992 -0.0064869998 -0.0107960002 +0.0314849988 0.0391989984 0.0500000007 +0.0314829983 -0.0232170001 -0.0141890002 +0.0314750001 -0.0185250007 -0.0108359996 +0.0314709991 0.0391479991 0.0314709991 +0.0314709991 0.0391479991 0.0185289998 +0.0314709991 0.0391479991 0.0064710001 +0.0314709991 0.0391479991 -0.0064710001 +0.0314709991 0.0391479991 -0.0185289998 +0.0314630009 0.0500000007 0.0391179994 +0.0314630009 0.0500000007 0.0358819999 +0.0314630009 0.0500000007 0.0141179999 +0.0314630009 0.0500000007 0.0108820004 +0.0314630009 0.0500000007 -0.0108820004 +0.0314630009 0.0500000007 -0.0141179999 +0.0314630009 0.0500000007 -0.0358819999 +0.0314630009 0.0500000007 -0.0391179994 +0.0314630009 0.0391179994 -0.0500000007 +0.0314630009 0.0358819999 -0.0500000007 +0.0314630009 0.0141179999 0.0500000007 +0.0314630009 0.0141179999 -0.0500000007 +0.0314630009 0.0108820004 0.0500000007 +0.0314630009 0.0108820004 -0.0500000007 +0.0314630009 -0.0108820004 0.0500000007 +0.0314630009 -0.0108820004 -0.0500000007 +0.0314630009 -0.0141179999 0.0500000007 +0.0314630009 -0.0141179999 -0.0500000007 +0.0314630009 -0.0358819999 0.0500000007 +0.0314630009 -0.0358819999 -0.0500000007 +0.0314630009 -0.0391179994 0.0500000007 +0.0314630009 -0.0391179994 -0.0500000007 +0.0314630009 -0.0500000007 0.0391179994 +0.0314630009 -0.0500000007 0.0358819999 +0.0314630009 -0.0500000007 0.0141179999 +0.0314630009 -0.0500000007 0.0108820004 +0.0314630009 -0.0500000007 -0.0358819999 +0.0314630009 -0.0500000007 -0.0391179994 +0.0313839987 0.0387869999 0.0436160006 +0.0313699991 0.0436300002 0.0387189984 +0.0313699991 0.0436300002 0.0362810008 +0.0313699991 0.0436300002 0.0137189999 +0.0313699991 0.0436300002 0.0112810005 +0.0313699991 0.0436300002 -0.0112810005 +0.0313699991 0.0436300002 -0.0137189999 +0.0313699991 0.0436300002 -0.0362810008 +0.0313699991 0.0436300002 -0.0387189984 +0.0313699991 0.0387189984 -0.0313699991 +0.0313699991 0.0387189984 -0.0436300002 +0.0313699991 0.0362810008 -0.0313699991 +0.0313699991 0.0362810008 -0.0436300002 +0.0313699991 0.0313699991 -0.0362810008 +0.0313699991 0.0313699991 -0.0387189984 +0.0313699991 0.0186299998 -0.0362810008 +0.0313699991 0.0186299998 -0.0387189984 +0.0313699991 0.0137189999 0.0436300002 +0.0313699991 0.0137189999 0.0313699991 +0.0313699991 0.0137189999 0.0186299998 +0.0313699991 0.0137189999 0.0063700001 +0.0313699991 0.0137189999 -0.0063700001 +0.0313699991 0.0137189999 -0.0436300002 +0.0313699991 0.0112810005 0.0436300002 +0.0313699991 0.0112810005 0.0313699991 +0.0313699991 0.0112810005 0.0186299998 +0.0313699991 0.0112810005 0.0063700001 +0.0313699991 0.0112810005 -0.0063700001 +0.0313699991 0.0112810005 -0.0436300002 +0.0313699991 0.0063700001 0.0387189984 +0.0313699991 0.0063700001 0.0362810008 +0.0313699991 0.0063700001 0.0137189999 +0.0313699991 0.0063700001 0.0112810005 +0.0313699991 0.0063700001 -0.0362810008 +0.0313699991 0.0063700001 -0.0387189984 +0.0313699991 -0.0063700001 0.0387189984 +0.0313699991 -0.0063700001 0.0362810008 +0.0313699991 -0.0063700001 0.0137189999 +0.0313699991 -0.0063700001 0.0112810005 +0.0313699991 -0.0063700001 -0.0362810008 +0.0313699991 -0.0063700001 -0.0387189984 +0.0313699991 -0.0112810005 0.0436300002 +0.0313699991 -0.0112810005 0.0313699991 +0.0313699991 -0.0112810005 0.0186299998 +0.0313699991 -0.0112810005 0.0063700001 +0.0313699991 -0.0112810005 -0.0063700001 +0.0313699991 -0.0112810005 -0.0436300002 +0.0313699991 -0.0137189999 0.0436300002 +0.0313699991 -0.0137189999 0.0313699991 +0.0313699991 -0.0137189999 0.0186299998 +0.0313699991 -0.0137189999 0.0063700001 +0.0313699991 -0.0137189999 -0.0063700001 +0.0313699991 -0.0137189999 -0.0436300002 +0.0313699991 -0.0186299998 0.0387189984 +0.0313699991 -0.0186299998 0.0362810008 +0.0313699991 -0.0186299998 0.0137189999 +0.0313699991 -0.0186299998 0.0112810005 +0.0313699991 -0.0186299998 -0.0362810008 +0.0313699991 -0.0186299998 -0.0387189984 +0.0313699991 -0.0313699991 0.0387189984 +0.0313699991 -0.0313699991 0.0362810008 +0.0313699991 -0.0313699991 0.0137189999 +0.0313699991 -0.0313699991 0.0112810005 +0.0313699991 -0.0313699991 -0.0112810005 +0.0313699991 -0.0313699991 -0.0137189999 +0.0313699991 -0.0313699991 -0.0362810008 +0.0313699991 -0.0313699991 -0.0387189984 +0.0313699991 -0.0362810008 0.0436300002 +0.0313699991 -0.0362810008 0.0313699991 +0.0313699991 -0.0362810008 0.0186299998 +0.0313699991 -0.0362810008 0.0063700001 +0.0313699991 -0.0362810008 -0.0063700001 +0.0313699991 -0.0362810008 -0.0186299998 +0.0313699991 -0.0362810008 -0.0313699991 +0.0313699991 -0.0362810008 -0.0436300002 +0.0313699991 -0.0387189984 0.0436300002 +0.0313699991 -0.0387189984 0.0313699991 +0.0313699991 -0.0387189984 0.0186299998 +0.0313699991 -0.0387189984 0.0063700001 +0.0313699991 -0.0387189984 -0.0063700001 +0.0313699991 -0.0387189984 -0.0436300002 +0.0313699991 -0.0436300002 0.0387189984 +0.0313699991 -0.0436300002 0.0362810008 +0.0313699991 -0.0436300002 0.0137189999 +0.0313699991 -0.0436300002 0.0112810005 +0.0313699991 -0.0436300002 -0.0362810008 +0.0313699991 -0.0436300002 -0.0387189984 +0.0313589983 -0.0436410010 -0.0113369999 +0.0313530006 0.0363700017 -0.0302779991 +0.0313510001 -0.0226210002 -0.0136160003 +0.0313419998 -0.0436579995 -0.0135690002 +0.0313419998 -0.0500000007 -0.0135690002 +0.0312950015 0.0187049992 0.0382449999 +0.0312939994 -0.0382440016 -0.0312939994 +0.0312890001 0.0381929986 0.0437109992 +0.0312849991 0.0062850001 -0.0118359998 +0.0312849991 -0.0062850001 -0.0118359998 +0.0312799998 0.0437199995 0.0381130017 +0.0312799998 0.0437199995 0.0368870012 +0.0312799998 0.0437199995 0.0131130004 +0.0312799998 0.0437199995 0.0118869999 +0.0312799998 0.0437199995 -0.0118869999 +0.0312799998 0.0437199995 -0.0131130004 +0.0312799998 0.0437199995 -0.0368870012 +0.0312799998 0.0437199995 -0.0381130017 +0.0312799998 0.0381130017 -0.0312799998 +0.0312799998 0.0381130017 -0.0437199995 +0.0312799998 0.0368870012 -0.0312799998 +0.0312799998 0.0368870012 -0.0437199995 +0.0312799998 0.0312799998 -0.0368870012 +0.0312799998 0.0312799998 -0.0381130017 +0.0312799998 0.0187199991 -0.0368870012 +0.0312799998 0.0187199991 -0.0381130017 +0.0312799998 0.0131130004 0.0437199995 +0.0312799998 0.0131130004 0.0312799998 +0.0312799998 0.0131130004 0.0187199991 +0.0312799998 0.0131130004 0.0062799999 +0.0312799998 0.0131130004 -0.0062799999 +0.0312799998 0.0131130004 -0.0437199995 +0.0312799998 0.0118869999 0.0437199995 +0.0312799998 0.0118869999 0.0312799998 +0.0312799998 0.0118869999 0.0187199991 +0.0312799998 0.0118869999 0.0062799999 +0.0312799998 0.0118869999 -0.0062799999 +0.0312799998 0.0118869999 -0.0437199995 +0.0312799998 0.0062799999 0.0381130017 +0.0312799998 0.0062799999 0.0368870012 +0.0312799998 0.0062799999 0.0131130004 +0.0312799998 0.0062799999 0.0118869999 +0.0312799998 0.0062799999 -0.0368870012 +0.0312799998 0.0062799999 -0.0381130017 +0.0312799998 -0.0062799999 0.0381130017 +0.0312799998 -0.0062799999 0.0368870012 +0.0312799998 -0.0062799999 0.0131130004 +0.0312799998 -0.0062799999 0.0118869999 +0.0312799998 -0.0062799999 -0.0368870012 +0.0312799998 -0.0062799999 -0.0381130017 +0.0312799998 -0.0118869999 0.0437199995 +0.0312799998 -0.0118869999 0.0312799998 +0.0312799998 -0.0118869999 0.0187199991 +0.0312799998 -0.0118869999 0.0062799999 +0.0312799998 -0.0118869999 -0.0062799999 +0.0312799998 -0.0118869999 -0.0437199995 +0.0312799998 -0.0131130004 0.0437199995 +0.0312799998 -0.0131130004 0.0312799998 +0.0312799998 -0.0131130004 0.0187199991 +0.0312799998 -0.0131130004 0.0062799999 +0.0312799998 -0.0131130004 -0.0062799999 +0.0312799998 -0.0131130004 -0.0437199995 +0.0312799998 -0.0187199991 0.0381130017 +0.0312799998 -0.0187199991 0.0368870012 +0.0312799998 -0.0187199991 0.0131130004 +0.0312799998 -0.0187199991 0.0118869999 +0.0312799998 -0.0187199991 -0.0118920002 +0.0312799998 -0.0187199991 -0.0368870012 +0.0312799998 -0.0187199991 -0.0381130017 +0.0312799998 -0.0312799998 0.0381130017 +0.0312799998 -0.0312799998 0.0368870012 +0.0312799998 -0.0312799998 0.0131130004 +0.0312799998 -0.0312799998 0.0118869999 +0.0312799998 -0.0312799998 -0.0118869999 +0.0312799998 -0.0312799998 -0.0131130004 +0.0312799998 -0.0312799998 -0.0368870012 +0.0312799998 -0.0312799998 -0.0381130017 +0.0312799998 -0.0368870012 0.0437199995 +0.0312799998 -0.0368870012 0.0312799998 +0.0312799998 -0.0368870012 0.0187199991 +0.0312799998 -0.0368870012 0.0062799999 +0.0312799998 -0.0368870012 -0.0062799999 +0.0312799998 -0.0368870012 -0.0187199991 +0.0312799998 -0.0368870012 -0.0312799998 +0.0312799998 -0.0368870012 -0.0437199995 +0.0312799998 -0.0381130017 0.0437199995 +0.0312799998 -0.0381130017 0.0312799998 +0.0312799998 -0.0381130017 0.0187199991 +0.0312799998 -0.0381130017 0.0062799999 +0.0312799998 -0.0381130017 -0.0062799999 +0.0312799998 -0.0381130017 -0.0437199995 +0.0312799998 -0.0437199995 0.0381130017 +0.0312799998 -0.0437199995 0.0368870012 +0.0312799998 -0.0437199995 0.0131130004 +0.0312799998 -0.0437199995 0.0118869999 +0.0312799998 -0.0437199995 -0.0368870012 +0.0312799998 -0.0437199995 -0.0381130017 +0.0312790014 -0.0219470002 -0.0131019996 +0.0312779993 0.0380860008 0.0312779993 +0.0312779993 0.0380860008 0.0187219996 +0.0312779993 0.0380860008 0.0062779998 +0.0312779993 0.0380860008 -0.0062779998 +0.0312779993 0.0380860008 -0.0187219996 +0.0312779993 0.0380860008 -0.0255469996 +0.0312680006 0.0379780009 -0.0268029999 +0.0312639996 -0.0437359996 -0.0120789995 +0.0312639996 -0.0500000007 -0.0120789995 +0.0312630013 0.0370990001 -0.0292349998 +0.0312590003 -0.0437409990 -0.0128260003 +0.0312529989 -0.0204029996 -0.0123060001 +0.0312520005 0.0376459993 -0.0280569997 +0.0312509984 0.0375920013 0.0500000007 +0.0312509984 0.0375920013 0.0437490009 +0.0312500000 0.0500000007 0.0375000015 +0.0312500000 0.0500000007 0.0125000002 +0.0312500000 0.0500000007 -0.0125000002 +0.0312500000 0.0500000007 -0.0375000015 +0.0312500000 0.0437499993 0.0375000015 +0.0312500000 0.0437499993 0.0125000002 +0.0312500000 0.0437499993 -0.0125000002 +0.0312500000 0.0437499993 -0.0375000015 +0.0312500000 0.0375000015 -0.0312500000 +0.0312500000 0.0375000015 -0.0437499993 +0.0312500000 0.0375000015 -0.0500000007 +0.0312500000 0.0312500000 -0.0375000015 +0.0312500000 0.0187500007 -0.0375000015 +0.0312500000 0.0125000002 0.0500000007 +0.0312500000 0.0125000002 0.0437499993 +0.0312500000 0.0125000002 0.0312500000 +0.0312500000 0.0125000002 0.0187500007 +0.0312500000 0.0125000002 0.0062500001 +0.0312500000 0.0125000002 -0.0062500001 +0.0312500000 0.0125000002 -0.0437499993 +0.0312500000 0.0125000002 -0.0500000007 +0.0312500000 0.0062500001 0.0375000015 +0.0312500000 0.0062500001 0.0125000002 +0.0312500000 0.0062500001 -0.0375000015 +0.0312500000 -0.0062500001 0.0375000015 +0.0312500000 -0.0062500001 0.0125000002 +0.0312500000 -0.0062500001 -0.0375000015 +0.0312500000 -0.0125000002 0.0500000007 +0.0312500000 -0.0125000002 0.0437499993 +0.0312500000 -0.0125000002 0.0312500000 +0.0312500000 -0.0125000002 0.0187500007 +0.0312500000 -0.0125000002 0.0062500001 +0.0312500000 -0.0125000002 -0.0062500001 +0.0312500000 -0.0125000002 -0.0437499993 +0.0312500000 -0.0125000002 -0.0500000007 +0.0312500000 -0.0187500007 0.0375000015 +0.0312500000 -0.0187500007 0.0125000002 +0.0312500000 -0.0187500007 -0.0375000015 +0.0312500000 -0.0312500000 0.0375000015 +0.0312500000 -0.0312500000 0.0125000002 +0.0312500000 -0.0312500000 -0.0125000002 +0.0312500000 -0.0312500000 -0.0375000015 +0.0312500000 -0.0375000015 0.0500000007 +0.0312500000 -0.0375000015 0.0437499993 +0.0312500000 -0.0375000015 0.0312500000 +0.0312500000 -0.0375000015 0.0187500007 +0.0312500000 -0.0375000015 0.0062500001 +0.0312500000 -0.0375000015 -0.0062500001 +0.0312500000 -0.0375000015 -0.0187500007 +0.0312500000 -0.0375000015 -0.0312500000 +0.0312500000 -0.0375000015 -0.0437499993 +0.0312500000 -0.0375000015 -0.0500000007 +0.0312500000 -0.0437499993 0.0375000015 +0.0312500000 -0.0437499993 0.0125000002 +0.0312500000 -0.0437499993 -0.0375000015 +0.0312500000 -0.0500000007 0.0375000015 +0.0312500000 -0.0500000007 0.0125000002 +0.0312500000 -0.0500000007 -0.0375000015 +0.0310600009 0.0186090004 0.0388190001 +0.0310440008 -0.0393959992 -0.0315439999 +0.0309660006 0.0380860008 0.0312779993 +0.0309660006 0.0380860008 0.0187219996 +0.0309660006 0.0380860008 0.0062779998 +0.0309660006 0.0380860008 -0.0003910000 +0.0308020003 0.0184599999 0.0393819995 +0.0306340009 0.0386609994 0.0500000007 +0.0306340009 0.0386609994 0.0436410010 +0.0306340009 0.0386609994 0.0313589983 +0.0306340009 0.0386609994 0.0186410006 +0.0306340009 0.0386609994 0.0063590002 +0.0306340009 0.0386609994 -0.0003910000 +0.0305819996 -0.0404799990 -0.0320059992 +0.0302869994 -0.0433779992 -0.0146239996 +0.0300190002 0.0180079993 0.0404540002 +0.0300179999 0.0395330004 0.0434099995 +0.0299510006 0.0396099985 0.0316170007 +0.0299510006 0.0396099985 0.0183830000 +0.0299510006 0.0396099985 0.0066169999 +0.0299249999 -0.0414590016 -0.0326640010 +0.0298059992 0.0397679992 0.0500000007 +0.0297030006 0.0398739986 -0.0003910000 +0.0292969998 -0.0429189987 -0.0156140001 +0.0292739999 0.0402619988 0.0431060009 +0.0291220006 0.0403829999 0.0319550000 +0.0291220006 0.0403829999 0.0180450007 +0.0291220006 0.0403829999 0.0069550001 +0.0290959999 -0.0422969982 -0.0334930010 +0.0289050005 0.0173649993 0.0414230004 +0.0287420005 0.0406510010 0.0500000007 +0.0284889992 0.0408050008 -0.0003910000 +0.0284519996 0.0408269987 0.0427910015 +0.0284020007 -0.0422939993 -0.0165100005 +0.0282589998 0.0169920009 0.0331550017 +0.0282589998 0.0169920009 0.0168450009 +0.0282589998 0.0169920009 0.0081550004 +0.0282589998 0.0169920009 -0.0003910000 +0.0281889997 0.0409669988 0.0322999991 +0.0281889997 0.0409669988 0.0176999997 +0.0281889997 0.0409669988 0.0073000002 +0.0281240009 -0.0429640003 -0.0344650000 +0.0276289992 -0.0415240005 -0.0172819998 +0.0274999999 0.0500000007 0.0500000007 +0.0274999999 0.0500000007 0.0375000015 +0.0274999999 0.0437499993 0.0375000015 +0.0274999999 0.0435840003 0.0389330015 +0.0274999999 0.0430929996 0.0402900018 +0.0274999999 0.0423040017 0.0414980017 +0.0274999999 0.0412600003 0.0500000007 +0.0274999999 0.0412600003 0.0424930006 +0.0274999999 0.0165539999 0.0500000007 +0.0274999999 0.0165539999 0.0422569998 +0.0274999999 0.0152340000 0.0431200005 +0.0274999999 0.0137409996 0.0436259992 +0.0274999999 0.0121680005 0.0437409990 +0.0274999999 0.0106170001 0.0434600003 +0.0274999999 0.0091850003 0.0427989997 +0.0274999999 0.0079650003 0.0418009982 +0.0274999999 0.0070329998 0.0405290015 +0.0274999999 0.0064490000 0.0390640013 +0.0274999999 0.0062500001 0.0375000015 +0.0274999999 -0.0062500001 0.0375000015 +0.0274999999 -0.0064630001 0.0391179994 +0.0274999999 -0.0070870002 0.0406249985 +0.0274999999 -0.0080810003 0.0419190004 +0.0274999999 -0.0093750004 0.0429130010 +0.0274999999 -0.0108820004 0.0435369983 +0.0274999999 -0.0125000002 0.0437499993 +0.0274999999 -0.0141179999 0.0435369983 +0.0274999999 -0.0156250000 0.0429130010 +0.0274999999 -0.0169190001 0.0419190004 +0.0274999999 -0.0179130007 0.0406249985 +0.0274999999 -0.0185369998 0.0391179994 +0.0274999999 -0.0187500007 0.0375000015 +0.0274999999 -0.0312500000 0.0375000015 +0.0274999999 -0.0314630009 0.0391179994 +0.0274999999 -0.0320869982 0.0406249985 +0.0274999999 -0.0330809988 0.0419190004 +0.0274999999 -0.0343750007 0.0429130010 +0.0274999999 -0.0358819999 0.0435369983 +0.0274999999 -0.0375000015 0.0437499993 +0.0274999999 -0.0391179994 0.0435369983 +0.0274999999 -0.0406249985 0.0429130010 +0.0274999999 -0.0419190004 0.0419190004 +0.0274999999 -0.0429130010 0.0406249985 +0.0274999999 -0.0435369983 0.0391179994 +0.0274999999 -0.0437499993 0.0375000015 +0.0274999999 -0.0500000007 0.0500000007 +0.0274999999 -0.0500000007 0.0375000015 +0.0271070004 0.0413819999 0.0326020010 +0.0271070004 0.0413819999 0.0173979998 +0.0271070004 0.0413819999 0.0076020001 +0.0270760003 0.0413910002 -0.0003910000 +0.0270440001 -0.0434359983 -0.0355449989 +0.0270019993 -0.0406300016 -0.0179099999 +0.0265389998 -0.0396410003 -0.0183719993 +0.0262560006 -0.0385870002 -0.0186550003 +0.0262230001 0.0158159994 0.0322020017 +0.0262230001 0.0158159994 0.0177979991 +0.0262230001 0.0158159994 0.0072019999 +0.0261610001 -0.0375000015 -0.0187500007 +0.0259559993 0.0415770002 0.0327630006 +0.0259559993 0.0415770002 0.0172370002 +0.0259559993 0.0415770002 0.0077630002 +0.0258939993 -0.0436980017 -0.0366940014 +0.0255600009 0.0415900014 -0.0003910000 +0.0248140004 0.0415429994 0.0327339992 +0.0248140004 0.0415429994 0.0172659997 +0.0248140004 0.0415429994 0.0077340002 +0.0247159991 -0.0437389985 -0.0378729999 +0.0240429994 0.0413910002 -0.0003910000 +0.0238499995 0.0144459996 0.0315609984 +0.0238499995 0.0144459996 0.0184390005 +0.0238499995 0.0144459996 0.0065609999 +0.0236740001 0.0412780009 0.0325209983 +0.0236740001 0.0412780009 0.0174790006 +0.0236740001 0.0412780009 0.0075210002 +0.0235510003 -0.0435580015 -0.0390370004 +0.0226300005 0.0408050008 0.0321960002 +0.0226300005 0.0408050008 0.0178040005 +0.0226300005 0.0408050008 0.0071959998 +0.0226300005 0.0408050008 -0.0003910000 +0.0224409997 -0.0431619994 -0.0401480012 +0.0214249995 -0.0425640009 -0.0411639996 +0.0205400009 -0.0417860001 -0.0420489982 +0.0198160000 -0.0408550017 -0.0427730009 +0.0192799997 -0.0398049988 -0.0433089994 +0.0189500004 -0.0386740007 -0.0436390005 +0.0188669991 -0.0380889997 -0.0437220000 +0.0188389998 -0.0375000015 -0.0437499993 +0.0187500007 0.0500000007 0.0375000015 +0.0187500007 0.0500000007 0.0125000002 +0.0187500007 0.0500000007 -0.0125000002 +0.0187500007 0.0500000007 -0.0375000015 +0.0187500007 0.0437499993 0.0375000015 +0.0187500007 0.0437499993 0.0125000002 +0.0187500007 0.0437499993 -0.0125000002 +0.0187500007 0.0437499993 -0.0375000015 +0.0187500007 0.0375000015 -0.0312500000 +0.0187500007 0.0375000015 -0.0437499993 +0.0187500007 0.0375000015 -0.0500000007 +0.0187500007 0.0312500000 -0.0375000015 +0.0187500007 0.0187500007 -0.0375000015 +0.0187500007 0.0125000002 -0.0062500001 +0.0187500007 0.0125000002 -0.0437499993 +0.0187500007 0.0125000002 -0.0500000007 +0.0187500007 0.0062500001 0.0375000015 +0.0187500007 0.0062500001 0.0125000002 +0.0187500007 0.0062500001 -0.0375000015 +0.0187500007 -0.0062500001 0.0375000015 +0.0187500007 -0.0062500001 0.0125000002 +0.0187500007 -0.0062500001 -0.0375000015 +0.0187500007 -0.0125000002 0.0312500000 +0.0187500007 -0.0125000002 0.0187500007 +0.0187500007 -0.0125000002 0.0062500001 +0.0187500007 -0.0125000002 -0.0062500001 +0.0187500007 -0.0125000002 -0.0437499993 +0.0187500007 -0.0125000002 -0.0500000007 +0.0187500007 -0.0187500007 0.0375000015 +0.0187500007 -0.0187500007 0.0125000002 +0.0187500007 -0.0187500007 -0.0375000015 +0.0187500007 -0.0208839998 -0.0125050005 +0.0187500007 -0.0312500000 0.0375000015 +0.0187500007 -0.0312500000 0.0125000002 +0.0187500007 -0.0312500000 -0.0125000002 +0.0187500007 -0.0312500000 -0.0375000015 +0.0187500007 -0.0375000015 0.0312500000 +0.0187500007 -0.0375000015 0.0187500007 +0.0187500007 -0.0375000015 0.0062500001 +0.0187500007 -0.0375000015 -0.0062500001 +0.0187500007 -0.0375000015 -0.0187500007 +0.0187500007 -0.0375000015 -0.0261610001 +0.0187500007 -0.0375000015 -0.0312500000 +0.0187500007 -0.0375000015 -0.0438390002 +0.0187500007 -0.0375000015 -0.0500000007 +0.0187500007 -0.0437499993 0.0375000015 +0.0187500007 -0.0437499993 0.0125000002 +0.0187500007 -0.0437499993 -0.0125000002 +0.0187500007 -0.0500000007 0.0375000015 +0.0187500007 -0.0500000007 0.0125000002 +0.0187500007 -0.0500000007 -0.0125000002 +0.0187470000 0.0376869999 -0.0279399995 +0.0187420007 0.0371880010 -0.0290750004 +0.0187379997 -0.0198199991 -0.0121139996 +0.0187330004 0.0129620004 -0.0003910000 +0.0187309999 0.0379879996 -0.0267430004 +0.0187260006 -0.0218690000 -0.0130500002 +0.0187219996 0.0380860008 -0.0003910000 +0.0187219996 0.0380860008 -0.0062779998 +0.0187219996 0.0380860008 -0.0187219996 +0.0187219996 0.0380860008 -0.0255469996 +0.0187199991 0.0437199995 0.0368870012 +0.0187199991 0.0437199995 0.0131130004 +0.0187199991 0.0437199995 0.0118869999 +0.0187199991 0.0437199995 -0.0118869999 +0.0187199991 0.0437199995 -0.0131130004 +0.0187199991 0.0437199995 -0.0368870012 +0.0187199991 0.0437199995 -0.0381130017 +0.0187199991 0.0381130017 -0.0312799998 +0.0187199991 0.0381130017 -0.0437199995 +0.0187199991 0.0368870012 -0.0312799998 +0.0187199991 0.0368870012 -0.0437199995 +0.0187199991 0.0312799998 -0.0368870012 +0.0187199991 0.0312799998 -0.0381130017 +0.0187199991 0.0187199991 -0.0368870012 +0.0187199991 0.0187199991 -0.0381130017 +0.0187199991 0.0131130004 -0.0062799999 +0.0187199991 0.0131130004 -0.0437199995 +0.0187199991 0.0118869999 -0.0062799999 +0.0187199991 0.0118869999 -0.0437199995 +0.0187199991 0.0062799999 0.0368870012 +0.0187199991 0.0062799999 0.0131130004 +0.0187199991 0.0062799999 0.0118869999 +0.0187199991 0.0062799999 -0.0368870012 +0.0187199991 0.0062799999 -0.0381130017 +0.0187199991 -0.0062799999 0.0368870012 +0.0187199991 -0.0062799999 0.0131130004 +0.0187199991 -0.0062799999 0.0118869999 +0.0187199991 -0.0062799999 -0.0368870012 +0.0187199991 -0.0062799999 -0.0381130017 +0.0187199991 -0.0118869999 0.0312799998 +0.0187199991 -0.0118869999 0.0187199991 +0.0187199991 -0.0118869999 0.0062799999 +0.0187199991 -0.0118869999 -0.0062799999 +0.0187199991 -0.0118869999 -0.0437199995 +0.0187199991 -0.0131130004 0.0312799998 +0.0187199991 -0.0131130004 0.0187199991 +0.0187199991 -0.0131130004 0.0062799999 +0.0187199991 -0.0131130004 -0.0062799999 +0.0187199991 -0.0131130004 -0.0437199995 +0.0187199991 -0.0187199991 0.0368870012 +0.0187199991 -0.0187199991 0.0131130004 +0.0187199991 -0.0187199991 0.0118869999 +0.0187199991 -0.0187199991 -0.0118920002 +0.0187199991 -0.0187199991 -0.0368870012 +0.0187199991 -0.0187199991 -0.0381130017 +0.0187199991 -0.0312799998 0.0368870012 +0.0187199991 -0.0312799998 0.0131130004 +0.0187199991 -0.0312799998 0.0118869999 +0.0187199991 -0.0312799998 -0.0118869999 +0.0187199991 -0.0312799998 -0.0131130004 +0.0187199991 -0.0312799998 -0.0368870012 +0.0187199991 -0.0312799998 -0.0381130017 +0.0187199991 -0.0368870012 0.0312799998 +0.0187199991 -0.0368870012 0.0187199991 +0.0187199991 -0.0368870012 0.0062799999 +0.0187199991 -0.0368870012 -0.0062799999 +0.0187199991 -0.0368870012 -0.0187199991 +0.0187199991 -0.0368870012 -0.0312799998 +0.0187199991 -0.0368870012 -0.0437199995 +0.0187199991 -0.0381070003 -0.0438680016 +0.0187199991 -0.0381130017 0.0312799998 +0.0187199991 -0.0381130017 0.0187199991 +0.0187199991 -0.0381130017 0.0062799999 +0.0187199991 -0.0381130017 -0.0062799999 +0.0187199991 -0.0381130017 -0.0187199991 +0.0187199991 -0.0437199995 0.0368870012 +0.0187199991 -0.0437199995 0.0131130004 +0.0187199991 -0.0437199995 0.0118869999 +0.0187199991 -0.0437199995 -0.0118869999 +0.0187199991 -0.0437199995 -0.0131130004 +0.0187149998 0.0062850001 -0.0118359998 +0.0187149998 -0.0062850001 -0.0118359998 +0.0186730009 0.0365209989 -0.0300929993 +0.0186669994 0.0385169983 0.0313329995 +0.0186669994 0.0385169983 0.0186669994 +0.0186669994 0.0385169983 0.0063330000 +0.0186669994 0.0385169983 -0.0003910000 +0.0186609998 0.0114510003 0.0313390009 +0.0186609998 0.0114510003 0.0186609998 +0.0186609998 0.0114510003 0.0063390001 +0.0186609998 0.0114510003 -0.0003910000 +0.0186550003 -0.0385870002 -0.0262560006 +0.0186320003 -0.0387080014 -0.0439569987 +0.0186299998 0.0436300002 0.0362810008 +0.0186299998 0.0436300002 0.0137189999 +0.0186299998 0.0436300002 0.0112810005 +0.0186299998 0.0436300002 -0.0112810005 +0.0186299998 0.0436300002 -0.0137189999 +0.0186299998 0.0436300002 -0.0362810008 +0.0186299998 0.0436300002 -0.0387189984 +0.0186299998 0.0387189984 -0.0313699991 +0.0186299998 0.0387189984 -0.0436300002 +0.0186299998 0.0362810008 -0.0313699991 +0.0186299998 0.0362810008 -0.0436300002 +0.0186299998 0.0313699991 -0.0362810008 +0.0186299998 0.0313699991 -0.0387189984 +0.0186299998 0.0186299998 -0.0362810008 +0.0186299998 0.0186299998 -0.0387189984 +0.0186299998 0.0137189999 -0.0063700001 +0.0186299998 0.0137189999 -0.0436300002 +0.0186299998 0.0112810005 -0.0063700001 +0.0186299998 0.0112810005 -0.0436300002 +0.0186299998 0.0063700001 0.0362810008 +0.0186299998 0.0063700001 0.0137189999 +0.0186299998 0.0063700001 0.0112810005 +0.0186299998 0.0063700001 -0.0362810008 +0.0186299998 0.0063700001 -0.0387189984 +0.0186299998 -0.0063700001 0.0362810008 +0.0186299998 -0.0063700001 0.0137189999 +0.0186299998 -0.0063700001 0.0112810005 +0.0186299998 -0.0063700001 -0.0362810008 +0.0186299998 -0.0063700001 -0.0387189984 +0.0186299998 -0.0112810005 0.0313699991 +0.0186299998 -0.0112810005 0.0186299998 +0.0186299998 -0.0112810005 0.0063700001 +0.0186299998 -0.0112810005 -0.0063700001 +0.0186299998 -0.0112810005 -0.0436300002 +0.0186299998 -0.0137189999 0.0313699991 +0.0186299998 -0.0137189999 0.0186299998 +0.0186299998 -0.0137189999 0.0063700001 +0.0186299998 -0.0137189999 -0.0063700001 +0.0186299998 -0.0137189999 -0.0436300002 +0.0186299998 -0.0186299998 0.0362810008 +0.0186299998 -0.0186299998 0.0137189999 +0.0186299998 -0.0186299998 0.0112810005 +0.0186299998 -0.0186299998 -0.0362810008 +0.0186299998 -0.0186299998 -0.0387189984 +0.0186299998 -0.0227359999 -0.0137179997 +0.0186299998 -0.0313699991 0.0362810008 +0.0186299998 -0.0313699991 0.0137189999 +0.0186299998 -0.0313699991 0.0112810005 +0.0186299998 -0.0313699991 -0.0112810005 +0.0186299998 -0.0313699991 -0.0137189999 +0.0186299998 -0.0313699991 -0.0362810008 +0.0186299998 -0.0313699991 -0.0387189984 +0.0186299998 -0.0362810008 0.0313699991 +0.0186299998 -0.0362810008 0.0186299998 +0.0186299998 -0.0362810008 0.0063700001 +0.0186299998 -0.0362810008 -0.0063700001 +0.0186299998 -0.0362810008 -0.0186299998 +0.0186299998 -0.0362810008 -0.0313699991 +0.0186299998 -0.0362810008 -0.0436300002 +0.0186299998 -0.0387189984 0.0313699991 +0.0186299998 -0.0387189984 0.0186299998 +0.0186299998 -0.0387189984 0.0063700001 +0.0186299998 -0.0387189984 -0.0063700001 +0.0186299998 -0.0387189984 -0.0186299998 +0.0186299998 -0.0436300002 0.0362810008 +0.0186299998 -0.0436300002 0.0137189999 +0.0186299998 -0.0436300002 0.0112810005 +0.0186299998 -0.0436300002 -0.0112810005 +0.0186299998 -0.0436300002 -0.0137189999 +0.0185410008 -0.0391030014 -0.0500000007 +0.0185369998 0.0500000007 0.0358819999 +0.0185369998 0.0500000007 0.0141179999 +0.0185369998 0.0500000007 0.0108820004 +0.0185369998 0.0500000007 -0.0108820004 +0.0185369998 0.0500000007 -0.0141179999 +0.0185369998 0.0500000007 -0.0358819999 +0.0185369998 0.0500000007 -0.0391179994 +0.0185369998 0.0391179994 -0.0500000007 +0.0185369998 0.0358819999 -0.0500000007 +0.0185369998 0.0141179999 -0.0500000007 +0.0185369998 0.0108820004 -0.0500000007 +0.0185369998 -0.0108820004 -0.0500000007 +0.0185369998 -0.0141179999 -0.0500000007 +0.0185369998 -0.0358819999 -0.0500000007 +0.0185369998 -0.0500000007 0.0358819999 +0.0185369998 -0.0500000007 0.0141179999 +0.0185369998 -0.0500000007 0.0108820004 +0.0185369998 -0.0500000007 -0.0108820004 +0.0185369998 -0.0500000007 -0.0141179999 +0.0185289998 0.0391479991 -0.0064710001 +0.0185289998 0.0391479991 -0.0185289998 +0.0185250007 -0.0185250007 -0.0108359996 +0.0185129996 0.0064869998 -0.0107960002 +0.0185129996 -0.0064869998 -0.0107960002 +0.0184920002 0.0357219987 -0.0309609994 +0.0184390005 0.0144459996 -0.0003910000 +0.0184349995 0.0394599997 0.0315649994 +0.0184349995 0.0394599997 0.0184349995 +0.0184349995 0.0394599997 0.0065649999 +0.0184269994 0.0105170002 0.0315730013 +0.0184269994 0.0105170002 0.0184269994 +0.0184269994 0.0105170002 0.0065730000 +0.0184209999 -0.0234910008 -0.0145009998 +0.0183719993 -0.0396410003 -0.0265389998 +0.0182830002 -0.0398709998 -0.0443059988 +0.0182739999 0.0432740003 0.0351080000 +0.0182739999 0.0432740003 0.0148919998 +0.0182739999 0.0432740003 0.0101079997 +0.0182739999 0.0432740003 -0.0101079997 +0.0182739999 0.0432740003 -0.0148919998 +0.0182739999 0.0432740003 -0.0351080000 +0.0182739999 0.0432740003 -0.0398919992 +0.0182739999 0.0398919992 -0.0317259990 +0.0182739999 0.0398919992 -0.0432740003 +0.0182739999 0.0351080000 -0.0317259990 +0.0182739999 0.0351080000 -0.0432740003 +0.0182739999 0.0317259990 -0.0351080000 +0.0182739999 0.0317259990 -0.0398919992 +0.0182739999 0.0182739999 -0.0351080000 +0.0182739999 0.0182739999 -0.0398919992 +0.0182739999 0.0148919998 -0.0067260000 +0.0182739999 0.0148919998 -0.0432740003 +0.0182739999 0.0101079997 -0.0067260000 +0.0182739999 0.0101079997 -0.0432740003 +0.0182739999 0.0067260000 0.0351080000 +0.0182739999 0.0067260000 0.0148919998 +0.0182739999 0.0067260000 0.0101079997 +0.0182739999 0.0067260000 -0.0351080000 +0.0182739999 0.0067260000 -0.0398919992 +0.0182739999 -0.0067260000 0.0351080000 +0.0182739999 -0.0067260000 0.0148919998 +0.0182739999 -0.0067260000 0.0101079997 +0.0182739999 -0.0067260000 -0.0351080000 +0.0182739999 -0.0067260000 -0.0398919992 +0.0182739999 -0.0101079997 0.0317259990 +0.0182739999 -0.0101079997 0.0182739999 +0.0182739999 -0.0101079997 0.0067260000 +0.0182739999 -0.0101079997 -0.0067260000 +0.0182739999 -0.0101079997 -0.0432740003 +0.0182739999 -0.0148919998 0.0317259990 +0.0182739999 -0.0148919998 0.0182739999 +0.0182739999 -0.0148919998 0.0067260000 +0.0182739999 -0.0148919998 -0.0067260000 +0.0182739999 -0.0148919998 -0.0432740003 +0.0182739999 -0.0182739999 0.0351080000 +0.0182739999 -0.0182739999 0.0148919998 +0.0182739999 -0.0182739999 0.0101079997 +0.0182739999 -0.0182739999 -0.0351080000 +0.0182739999 -0.0182739999 -0.0398919992 +0.0182739999 -0.0317259990 0.0351080000 +0.0182739999 -0.0317259990 0.0148919998 +0.0182739999 -0.0317259990 0.0101079997 +0.0182739999 -0.0317259990 -0.0101079997 +0.0182739999 -0.0317259990 -0.0148919998 +0.0182739999 -0.0317259990 -0.0351080000 +0.0182739999 -0.0317259990 -0.0398919992 +0.0182739999 -0.0351080000 0.0317259990 +0.0182739999 -0.0351080000 0.0182739999 +0.0182739999 -0.0351080000 0.0067260000 +0.0182739999 -0.0351080000 -0.0067260000 +0.0182739999 -0.0351080000 -0.0182739999 +0.0182739999 -0.0351080000 -0.0317259990 +0.0182739999 -0.0351080000 -0.0432740003 +0.0182739999 -0.0398919992 0.0317259990 +0.0182739999 -0.0398919992 0.0182739999 +0.0182739999 -0.0398919992 0.0067260000 +0.0182739999 -0.0398919992 -0.0067260000 +0.0182739999 -0.0398919992 -0.0182739999 +0.0182739999 -0.0432740003 0.0351080000 +0.0182739999 -0.0432740003 0.0148919998 +0.0182739999 -0.0432740003 0.0101079997 +0.0182739999 -0.0432740003 -0.0101079997 +0.0182739999 -0.0432740003 -0.0148919998 +0.0181559995 0.0401600003 -0.0068440000 +0.0181559995 0.0401600003 -0.0181559995 +0.0181510001 -0.0181510001 -0.0098299999 +0.0181389991 0.0068609999 -0.0098040001 +0.0181389991 -0.0068609999 -0.0098040001 +0.0181239992 0.0347750001 -0.0317060016 +0.0180600006 0.0403550006 0.0319399983 +0.0180600006 0.0403550006 0.0180600006 +0.0180600006 0.0403550006 0.0069400002 +0.0180520006 0.0096300002 0.0319480002 +0.0180520006 0.0096300002 0.0180520006 +0.0180520006 0.0096300002 0.0069479998 +0.0180430003 -0.0241240002 -0.0153879998 +0.0179270003 -0.0405989997 -0.0500000007 +0.0179130007 0.0500000007 0.0343750007 +0.0179130007 0.0500000007 0.0156250000 +0.0179130007 0.0500000007 0.0093750004 +0.0179130007 0.0500000007 -0.0093750004 +0.0179130007 0.0500000007 -0.0156250000 +0.0179130007 0.0500000007 -0.0343750007 +0.0179130007 0.0500000007 -0.0406249985 +0.0179130007 0.0406249985 -0.0500000007 +0.0179130007 0.0343750007 -0.0500000007 +0.0179130007 0.0156250000 -0.0500000007 +0.0179130007 0.0093750004 -0.0500000007 +0.0179130007 -0.0093750004 -0.0500000007 +0.0179130007 -0.0156250000 -0.0500000007 +0.0179130007 -0.0343750007 -0.0500000007 +0.0179130007 -0.0500000007 0.0343750007 +0.0179130007 -0.0500000007 0.0156250000 +0.0179130007 -0.0500000007 0.0093750004 +0.0179130007 -0.0500000007 -0.0093750004 +0.0179130007 -0.0500000007 -0.0156250000 +0.0179099999 -0.0406300016 -0.0270019993 +0.0177979991 0.0158159994 -0.0003910000 +0.0177149996 -0.0409450009 -0.0448740013 +0.0176970009 0.0426970012 0.0340280011 +0.0176970009 0.0426970012 0.0159719996 +0.0176970009 0.0426970012 0.0090279998 +0.0176970009 0.0426970012 -0.0090279998 +0.0176970009 0.0426970012 -0.0159719996 +0.0176970009 0.0426970012 -0.0340280011 +0.0176970009 0.0426970012 -0.0409720019 +0.0176970009 0.0409720019 -0.0323030017 +0.0176970009 0.0409720019 -0.0426970012 +0.0176970009 0.0340280011 -0.0323030017 +0.0176970009 0.0340280011 -0.0426970012 +0.0176970009 0.0323030017 -0.0340280011 +0.0176970009 0.0323030017 -0.0409720019 +0.0176970009 0.0176970009 -0.0340280011 +0.0176970009 0.0176970009 -0.0409720019 +0.0176970009 0.0159719996 -0.0073030000 +0.0176970009 0.0159719996 -0.0426970012 +0.0176970009 0.0090279998 -0.0073030000 +0.0176970009 0.0090279998 -0.0426970012 +0.0176970009 0.0073030000 0.0340280011 +0.0176970009 0.0073030000 0.0159719996 +0.0176970009 0.0073030000 0.0090279998 +0.0176970009 0.0073030000 -0.0340280011 +0.0176970009 0.0073030000 -0.0409720019 +0.0176970009 -0.0073030000 0.0340280011 +0.0176970009 -0.0073030000 0.0159719996 +0.0176970009 -0.0073030000 0.0090279998 +0.0176970009 -0.0073030000 -0.0340280011 +0.0176970009 -0.0073030000 -0.0409720019 +0.0176970009 -0.0090279998 0.0323030017 +0.0176970009 -0.0090279998 0.0176970009 +0.0176970009 -0.0090279998 0.0073030000 +0.0176970009 -0.0090279998 -0.0073030000 +0.0176970009 -0.0090279998 -0.0426970012 +0.0176970009 -0.0159719996 0.0323030017 +0.0176970009 -0.0159719996 0.0176970009 +0.0176970009 -0.0159719996 0.0073030000 +0.0176970009 -0.0159719996 -0.0073030000 +0.0176970009 -0.0159719996 -0.0426970012 +0.0176970009 -0.0176970009 0.0340280011 +0.0176970009 -0.0176970009 0.0159719996 +0.0176970009 -0.0176970009 0.0090279998 +0.0176970009 -0.0176970009 -0.0340280011 +0.0176970009 -0.0176970009 -0.0409720019 +0.0176970009 -0.0323030017 0.0340280011 +0.0176970009 -0.0323030017 0.0159719996 +0.0176970009 -0.0323030017 0.0090279998 +0.0176970009 -0.0323030017 -0.0090279998 +0.0176970009 -0.0323030017 -0.0159719996 +0.0176970009 -0.0323030017 -0.0340280011 +0.0176970009 -0.0323030017 -0.0409720019 +0.0176970009 -0.0340280011 0.0323030017 +0.0176970009 -0.0340280011 0.0176970009 +0.0176970009 -0.0340280011 0.0073030000 +0.0176970009 -0.0340280011 -0.0073030000 +0.0176970009 -0.0340280011 -0.0176970009 +0.0176970009 -0.0340280011 -0.0323030017 +0.0176970009 -0.0340280011 -0.0426970012 +0.0176970009 -0.0409720019 0.0323030017 +0.0176970009 -0.0409720019 0.0176970009 +0.0176970009 -0.0409720019 0.0073030000 +0.0176970009 -0.0409720019 -0.0073030000 +0.0176970009 -0.0409720019 -0.0176970009 +0.0176970009 -0.0426970012 0.0340280011 +0.0176970009 -0.0426970012 0.0159719996 +0.0176970009 -0.0426970012 0.0090279998 +0.0176970009 -0.0426970012 -0.0090279998 +0.0176970009 -0.0426970012 -0.0159719996 +0.0176139995 0.0410929993 -0.0073859999 +0.0176139995 0.0410929993 -0.0176139995 +0.0176110007 -0.0176110007 -0.0089020003 +0.0176020004 0.0073980000 -0.0088910004 +0.0176020004 -0.0073980000 -0.0088910004 +0.0175630003 0.0338359997 -0.0322320014 +0.0175500009 0.0411820002 0.0324500017 +0.0175500009 0.0411820002 0.0175500009 +0.0175500009 0.0411820002 0.0074499999 +0.0175460000 0.0088120000 0.0324539989 +0.0175460000 0.0088120000 0.0175460000 +0.0175460000 0.0088120000 0.0074539999 +0.0175080001 -0.0245670006 -0.0162390005 +0.0172819998 -0.0415240005 -0.0276289992 +0.0170699991 0.0167629998 -0.0329300016 +0.0170699991 0.0082369996 -0.0329300016 +0.0170699991 -0.0082369996 -0.0329300016 +0.0170699991 -0.0167629998 -0.0329300016 +0.0169920009 0.0169920009 -0.0081550004 +0.0169510003 -0.0418879986 -0.0456379987 +0.0169510003 -0.0418879986 -0.0500000007 +0.0169190001 0.0500000007 0.0330809988 +0.0169190001 0.0500000007 0.0169190001 +0.0169190001 0.0500000007 0.0080810003 +0.0169190001 0.0500000007 -0.0080810003 +0.0169190001 0.0500000007 -0.0169190001 +0.0169190001 0.0500000007 -0.0330809988 +0.0169190001 0.0500000007 -0.0419190004 +0.0169190001 0.0419190004 0.0330809988 +0.0169190001 0.0419190004 0.0169190001 +0.0169190001 0.0419190004 0.0080810003 +0.0169190001 0.0419190004 -0.0080810003 +0.0169190001 0.0419190004 -0.0169190001 +0.0169190001 0.0419190004 -0.0330809988 +0.0169190001 0.0419190004 -0.0419190004 +0.0169190001 0.0419190004 -0.0500000007 +0.0169190001 0.0330809988 -0.0330809988 +0.0169190001 0.0330809988 -0.0419190004 +0.0169190001 0.0330809988 -0.0500000007 +0.0169190001 0.0169190001 -0.0080810003 +0.0169190001 0.0169190001 -0.0330809988 +0.0169190001 0.0169190001 -0.0419190004 +0.0169190001 0.0169190001 -0.0500000007 +0.0169190001 0.0080810003 0.0330809988 +0.0169190001 0.0080810003 0.0169190001 +0.0169190001 0.0080810003 0.0080810003 +0.0169190001 0.0080810003 -0.0080810003 +0.0169190001 0.0080810003 -0.0330809988 +0.0169190001 0.0080810003 -0.0419190004 +0.0169190001 0.0080810003 -0.0500000007 +0.0169190001 -0.0080810003 0.0330809988 +0.0169190001 -0.0080810003 0.0169190001 +0.0169190001 -0.0080810003 0.0080810003 +0.0169190001 -0.0080810003 -0.0080810003 +0.0169190001 -0.0080810003 -0.0330809988 +0.0169190001 -0.0080810003 -0.0419190004 +0.0169190001 -0.0080810003 -0.0500000007 +0.0169190001 -0.0169190001 0.0330809988 +0.0169190001 -0.0169190001 0.0169190001 +0.0169190001 -0.0169190001 0.0080810003 +0.0169190001 -0.0169190001 -0.0080810003 +0.0169190001 -0.0169190001 -0.0330809988 +0.0169190001 -0.0169190001 -0.0419190004 +0.0169190001 -0.0169190001 -0.0500000007 +0.0169190001 -0.0330809988 0.0330809988 +0.0169190001 -0.0330809988 0.0169190001 +0.0169190001 -0.0330809988 0.0080810003 +0.0169190001 -0.0330809988 -0.0080810003 +0.0169190001 -0.0330809988 -0.0169190001 +0.0169190001 -0.0330809988 -0.0330809988 +0.0169190001 -0.0330809988 -0.0419190004 +0.0169190001 -0.0330809988 -0.0500000007 +0.0169190001 -0.0419190004 0.0330809988 +0.0169190001 -0.0419190004 0.0169190001 +0.0169190001 -0.0419190004 0.0080810003 +0.0169190001 -0.0419190004 -0.0080810003 +0.0169190001 -0.0419190004 -0.0169190001 +0.0169190001 -0.0500000007 0.0330809988 +0.0169190001 -0.0500000007 0.0169190001 +0.0169190001 -0.0500000007 0.0080810003 +0.0169190001 -0.0500000007 -0.0080810003 +0.0169190001 -0.0500000007 -0.0169190001 +0.0168450009 0.0169920009 -0.0003910000 +0.0168450009 0.0169920009 -0.0080080004 +0.0167970005 0.0329609998 -0.0003910000 +0.0167970005 0.0329609998 -0.0079610003 +0.0167970005 0.0329609998 -0.0170389991 +0.0167970005 0.0329609998 -0.0325759985 +0.0167970005 0.0318460017 -0.0328410007 +0.0167970005 0.0307030007 -0.0329300016 +0.0167970005 0.0170389991 -0.0003910000 +0.0167970005 0.0170389991 -0.0079610003 +0.0167970005 0.0170389991 -0.0170389991 +0.0167970005 0.0170389991 -0.0329300016 +0.0167970005 0.0079610003 -0.0170389991 +0.0167970005 0.0079610003 -0.0329300016 +0.0167970005 -0.0079610003 -0.0170389991 +0.0167970005 -0.0079610003 -0.0329300016 +0.0167970005 -0.0170389991 -0.0170389991 +0.0167970005 -0.0170389991 -0.0329300016 +0.0167970005 -0.0178120006 -0.0329300016 +0.0167970005 -0.0197230000 -0.0326780006 +0.0167970005 -0.0215039998 -0.0319410004 +0.0167970005 -0.0230330005 -0.0307669993 +0.0167970005 -0.0242059994 -0.0292380005 +0.0167970005 -0.0248659998 -0.0170389991 +0.0167970005 -0.0249439999 -0.0274580009 +0.0167970005 -0.0251129996 -0.0181159992 +0.0167970005 -0.0251950007 -0.0192189999 +0.0167970005 -0.0251950007 -0.0255469996 +0.0165100005 -0.0422939993 -0.0284020007 +0.0162470005 0.0074979998 0.0324979983 +0.0162470005 0.0074979998 0.0175020006 +0.0162470005 0.0074979998 0.0074979998 +0.0160179995 -0.0426659994 -0.0465699993 +0.0159719996 0.0426970012 0.0323030017 +0.0159719996 0.0426970012 0.0176970009 +0.0159719996 0.0426970012 0.0073030000 +0.0159719996 0.0426970012 -0.0073030000 +0.0159719996 0.0426970012 -0.0176970009 +0.0159719996 0.0426970012 -0.0323030017 +0.0159719996 0.0426970012 -0.0426970012 +0.0159719996 0.0323030017 -0.0323030017 +0.0159719996 0.0323030017 -0.0426970012 +0.0159719996 0.0176970009 -0.0323030017 +0.0159719996 0.0176970009 -0.0426970012 +0.0159719996 0.0073030000 -0.0073030000 +0.0159719996 0.0073030000 -0.0323030017 +0.0159719996 0.0073030000 -0.0426970012 +0.0159719996 -0.0073030000 0.0323030017 +0.0159719996 -0.0073030000 0.0176970009 +0.0159719996 -0.0073030000 0.0073030000 +0.0159719996 -0.0073030000 -0.0073030000 +0.0159719996 -0.0073030000 -0.0323030017 +0.0159719996 -0.0073030000 -0.0426970012 +0.0159719996 -0.0176970009 0.0323030017 +0.0159719996 -0.0176970009 0.0176970009 +0.0159719996 -0.0176970009 0.0073030000 +0.0159719996 -0.0176970009 -0.0073030000 +0.0159719996 -0.0176970009 -0.0323030017 +0.0159719996 -0.0176970009 -0.0426970012 +0.0159719996 -0.0323030017 0.0323030017 +0.0159719996 -0.0323030017 0.0176970009 +0.0159719996 -0.0323030017 0.0073030000 +0.0159719996 -0.0323030017 -0.0073030000 +0.0159719996 -0.0323030017 -0.0176970009 +0.0159719996 -0.0323030017 -0.0323030017 +0.0159719996 -0.0323030017 -0.0426970012 +0.0159719996 -0.0426970012 0.0323030017 +0.0159719996 -0.0426970012 0.0176970009 +0.0159719996 -0.0426970012 0.0073030000 +0.0159719996 -0.0426970012 -0.0073030000 +0.0159719996 -0.0426970012 -0.0176970009 +0.0158469994 0.0322219990 -0.0072220000 +0.0158469994 0.0322219990 -0.0177779999 +0.0158469994 0.0177779999 -0.0072220000 +0.0158469994 0.0177779999 -0.0177779999 +0.0158469994 0.0072220000 -0.0177779999 +0.0158469994 -0.0072220000 -0.0177779999 +0.0158469994 -0.0177779999 -0.0177779999 +0.0156759992 -0.0428830013 -0.0500000007 +0.0156250000 0.0500000007 0.0320869982 +0.0156250000 0.0500000007 0.0179130007 +0.0156250000 0.0500000007 0.0070870002 +0.0156250000 0.0500000007 -0.0070870002 +0.0156250000 0.0500000007 -0.0179130007 +0.0156250000 0.0500000007 -0.0320869982 +0.0156250000 0.0500000007 -0.0429130010 +0.0156250000 0.0429130010 -0.0500000007 +0.0156250000 0.0320869982 -0.0500000007 +0.0156250000 0.0179130007 -0.0500000007 +0.0156250000 0.0070870002 -0.0500000007 +0.0156250000 -0.0070870002 -0.0500000007 +0.0156250000 -0.0179130007 -0.0500000007 +0.0156250000 -0.0320869982 -0.0500000007 +0.0156250000 -0.0500000007 0.0320869982 +0.0156250000 -0.0500000007 0.0179130007 +0.0156250000 -0.0500000007 0.0070870002 +0.0156250000 -0.0500000007 -0.0070870002 +0.0156250000 -0.0500000007 -0.0179130007 +0.0156140001 -0.0429189987 -0.0292969998 +0.0155900000 0.0320670009 -0.0003910000 +0.0155229997 0.0179699995 -0.0003910000 +0.0154980002 0.0070159999 0.0320160016 +0.0154980002 0.0070159999 0.0179839991 +0.0154980002 0.0070159999 0.0070159999 +0.0149529995 -0.0432480015 -0.0476359986 +0.0148919998 0.0432740003 0.0317259990 +0.0148919998 0.0432740003 0.0182739999 +0.0148919998 0.0432740003 0.0067260000 +0.0148919998 0.0432740003 -0.0067260000 +0.0148919998 0.0432740003 -0.0182739999 +0.0148919998 0.0432740003 -0.0317259990 +0.0148919998 0.0432740003 -0.0432740003 +0.0148919998 0.0317259990 -0.0317259990 +0.0148919998 0.0317259990 -0.0432740003 +0.0148919998 0.0182739999 -0.0317259990 +0.0148919998 0.0182739999 -0.0432740003 +0.0148919998 0.0067260000 -0.0067260000 +0.0148919998 0.0067260000 -0.0317259990 +0.0148919998 0.0067260000 -0.0432740003 +0.0148919998 -0.0067260000 0.0317259990 +0.0148919998 -0.0067260000 0.0182739999 +0.0148919998 -0.0067260000 0.0067260000 +0.0148919998 -0.0067260000 -0.0067260000 +0.0148919998 -0.0067260000 -0.0317259990 +0.0148919998 -0.0067260000 -0.0432740003 +0.0148919998 -0.0182739999 0.0317259990 +0.0148919998 -0.0182739999 0.0182739999 +0.0148919998 -0.0182739999 0.0067260000 +0.0148919998 -0.0182739999 -0.0067260000 +0.0148919998 -0.0182739999 -0.0317259990 +0.0148919998 -0.0182739999 -0.0432740003 +0.0148919998 -0.0317259990 0.0317259990 +0.0148919998 -0.0317259990 0.0182739999 +0.0148919998 -0.0317259990 0.0067260000 +0.0148919998 -0.0317259990 -0.0067260000 +0.0148919998 -0.0317259990 -0.0182739999 +0.0148919998 -0.0317259990 -0.0317259990 +0.0148919998 -0.0317259990 -0.0432740003 +0.0148919998 -0.0432740003 0.0317259990 +0.0148919998 -0.0432740003 0.0182739999 +0.0148919998 -0.0432740003 0.0067260000 +0.0148919998 -0.0432740003 -0.0067260000 +0.0148919998 -0.0432740003 -0.0182739999 +0.0147730000 0.0316779986 -0.0066780001 +0.0147730000 0.0316779986 -0.0183220003 +0.0147730000 0.0183220003 -0.0066780001 +0.0147730000 0.0183220003 -0.0183220003 +0.0147730000 0.0066780001 -0.0183220003 +0.0147730000 -0.0066780001 -0.0183220003 +0.0147730000 -0.0183220003 -0.0183220003 +0.0146890003 0.0066459998 0.0316459984 +0.0146890003 0.0066459998 0.0183540005 +0.0146890003 0.0066459998 0.0066459998 +0.0146239996 -0.0433779992 -0.0302869994 +0.0142050004 0.0314869992 -0.0003910000 +0.0141890002 -0.0435170010 -0.0500000007 +0.0141179999 0.0500000007 0.0314630009 +0.0141179999 0.0500000007 0.0185369998 +0.0141179999 0.0500000007 0.0064630001 +0.0141179999 0.0500000007 -0.0064630001 +0.0141179999 0.0500000007 -0.0185369998 +0.0141179999 0.0500000007 -0.0314630009 +0.0141179999 0.0500000007 -0.0435369983 +0.0141179999 0.0435369983 -0.0500000007 +0.0141179999 0.0314630009 -0.0500000007 +0.0141179999 0.0185369998 -0.0500000007 +0.0141179999 0.0064630001 -0.0500000007 +0.0141179999 -0.0064630001 -0.0500000007 +0.0141179999 -0.0185369998 -0.0500000007 +0.0141179999 -0.0314630009 -0.0500000007 +0.0141179999 -0.0500000007 0.0314630009 +0.0141179999 -0.0500000007 0.0185369998 +0.0141179999 -0.0500000007 0.0064630001 +0.0141179999 -0.0500000007 -0.0064630001 +0.0141179999 -0.0500000007 -0.0185369998 +0.0140559999 0.0185529999 -0.0003910000 +0.0138349999 0.0063939998 0.0313940011 +0.0138349999 0.0063939998 0.0186059996 +0.0138349999 0.0063939998 0.0063939998 +0.0137949996 -0.0436140001 -0.0487929992 +0.0137189999 0.0436300002 0.0313699991 +0.0137189999 0.0436300002 0.0186299998 +0.0137189999 0.0436300002 0.0063700001 +0.0137189999 0.0436300002 -0.0063700001 +0.0137189999 0.0436300002 -0.0186299998 +0.0137189999 0.0436300002 -0.0313699991 +0.0137189999 0.0436300002 -0.0436300002 +0.0137189999 0.0313699991 -0.0313699991 +0.0137189999 0.0313699991 -0.0436300002 +0.0137189999 0.0186299998 -0.0313699991 +0.0137189999 0.0186299998 -0.0436300002 +0.0137189999 0.0063700001 -0.0063700001 +0.0137189999 0.0063700001 -0.0313699991 +0.0137189999 0.0063700001 -0.0436300002 +0.0137189999 -0.0063700001 0.0313699991 +0.0137189999 -0.0063700001 0.0186299998 +0.0137189999 -0.0063700001 0.0063700001 +0.0137189999 -0.0063700001 -0.0063700001 +0.0137189999 -0.0063700001 -0.0313699991 +0.0137189999 -0.0063700001 -0.0436300002 +0.0137189999 -0.0186299998 0.0313699991 +0.0137189999 -0.0186299998 0.0186299998 +0.0137189999 -0.0186299998 0.0063700001 +0.0137189999 -0.0186299998 -0.0063700001 +0.0137189999 -0.0186299998 -0.0313699991 +0.0137189999 -0.0186299998 -0.0436300002 +0.0137189999 -0.0313699991 0.0313699991 +0.0137189999 -0.0313699991 0.0186299998 +0.0137189999 -0.0313699991 0.0063700001 +0.0137189999 -0.0313699991 -0.0063700001 +0.0137189999 -0.0313699991 -0.0186299998 +0.0137189999 -0.0313699991 -0.0313699991 +0.0137189999 -0.0313699991 -0.0436300002 +0.0137189999 -0.0436300002 0.0313699991 +0.0137189999 -0.0436300002 0.0186299998 +0.0137189999 -0.0436300002 0.0063700001 +0.0137189999 -0.0436300002 -0.0063700001 +0.0137189999 -0.0436300002 -0.0186299998 +0.0136139998 0.0313500017 -0.0063499999 +0.0136139998 0.0313500017 -0.0186500009 +0.0136139998 0.0186500009 -0.0063499999 +0.0136139998 0.0186500009 -0.0186500009 +0.0136139998 0.0063499999 -0.0186500009 +0.0136139998 -0.0063499999 -0.0186500009 +0.0136139998 -0.0186500009 -0.0186500009 +0.0135690002 -0.0436579995 -0.0313419998 +0.0135690002 -0.0500000007 -0.0313419998 +0.0131130004 0.0437199995 0.0312799998 +0.0131130004 0.0437199995 0.0187199991 +0.0131130004 0.0437199995 0.0062799999 +0.0131130004 0.0437199995 -0.0062799999 +0.0131130004 0.0437199995 -0.0187199991 +0.0131130004 0.0437199995 -0.0312799998 +0.0131130004 0.0437199995 -0.0437199995 +0.0131130004 0.0312799998 -0.0312799998 +0.0131130004 0.0312799998 -0.0437199995 +0.0131130004 0.0187199991 -0.0312799998 +0.0131130004 0.0187199991 -0.0437199995 +0.0131130004 0.0062799999 -0.0062799999 +0.0131130004 0.0062799999 -0.0312799998 +0.0131130004 0.0062799999 -0.0437199995 +0.0131130004 -0.0062799999 0.0312799998 +0.0131130004 -0.0062799999 0.0187199991 +0.0131130004 -0.0062799999 0.0062799999 +0.0131130004 -0.0062799999 -0.0062799999 +0.0131130004 -0.0062799999 -0.0312799998 +0.0131130004 -0.0062799999 -0.0437199995 +0.0131130004 -0.0187199991 0.0312799998 +0.0131130004 -0.0187199991 0.0187199991 +0.0131130004 -0.0187199991 0.0062799999 +0.0131130004 -0.0187199991 -0.0062799999 +0.0131130004 -0.0187199991 -0.0312799998 +0.0131130004 -0.0187199991 -0.0437199995 +0.0131130004 -0.0312799998 0.0312799998 +0.0131130004 -0.0312799998 0.0187199991 +0.0131130004 -0.0312799998 0.0062799999 +0.0131130004 -0.0312799998 -0.0062799999 +0.0131130004 -0.0312799998 -0.0187199991 +0.0131130004 -0.0312799998 -0.0312799998 +0.0131130004 -0.0312799998 -0.0437199995 +0.0131130004 -0.0437199995 0.0312799998 +0.0131130004 -0.0437199995 0.0187199991 +0.0131130004 -0.0437199995 0.0062799999 +0.0131130004 -0.0437199995 -0.0062799999 +0.0131130004 -0.0437199995 -0.0187199991 +0.0130169997 0.0312709995 -0.0062710000 +0.0130169997 0.0312709995 -0.0187289994 +0.0130169997 0.0187289994 -0.0062710000 +0.0130169997 0.0187289994 -0.0187289994 +0.0130169997 0.0062710000 -0.0187289994 +0.0130169997 -0.0062710000 -0.0187289994 +0.0130169997 -0.0187289994 -0.0187289994 +0.0129540004 0.0062670000 0.0312669985 +0.0129540004 0.0062670000 0.0187330004 +0.0129540004 0.0062670000 0.0062670000 +0.0128260003 -0.0437409990 -0.0312590003 +0.0127219995 0.0312540010 -0.0003910000 +0.0125890002 -0.0437490009 -0.0500000007 +0.0125890002 -0.0500000007 -0.0500000007 +0.0125000002 0.0500000007 0.0312500000 +0.0125000002 0.0500000007 0.0187500007 +0.0125000002 0.0500000007 0.0062500001 +0.0125000002 0.0500000007 -0.0062500001 +0.0125000002 0.0500000007 -0.0187500007 +0.0125000002 0.0500000007 -0.0312500000 +0.0125000002 0.0500000007 -0.0437499993 +0.0125000002 0.0437499993 0.0312500000 +0.0125000002 0.0437499993 0.0187500007 +0.0125000002 0.0437499993 0.0062500001 +0.0125000002 0.0437499993 -0.0062500001 +0.0125000002 0.0437499993 -0.0187500007 +0.0125000002 0.0437499993 -0.0312500000 +0.0125000002 0.0437499993 -0.0437499993 +0.0125000002 0.0437499993 -0.0500000007 +0.0125000002 0.0312500000 -0.0312500000 +0.0125000002 0.0312500000 -0.0437499993 +0.0125000002 0.0312500000 -0.0500000007 +0.0125000002 0.0187500007 -0.0312500000 +0.0125000002 0.0187500007 -0.0437499993 +0.0125000002 0.0187500007 -0.0500000007 +0.0125000002 0.0062500001 -0.0062500001 +0.0125000002 0.0062500001 -0.0312500000 +0.0125000002 0.0062500001 -0.0437499993 +0.0125000002 0.0062500001 -0.0500000007 +0.0125000002 -0.0062500001 0.0312500000 +0.0125000002 -0.0062500001 0.0187500007 +0.0125000002 -0.0062500001 0.0062500001 +0.0125000002 -0.0062500001 -0.0062500001 +0.0125000002 -0.0062500001 -0.0312500000 +0.0125000002 -0.0062500001 -0.0437499993 +0.0125000002 -0.0062500001 -0.0500000007 +0.0125000002 -0.0187500007 0.0312500000 +0.0125000002 -0.0187500007 0.0187500007 +0.0125000002 -0.0187500007 0.0062500001 +0.0125000002 -0.0187500007 -0.0062500001 +0.0125000002 -0.0187500007 -0.0312500000 +0.0125000002 -0.0187500007 -0.0437499993 +0.0125000002 -0.0187500007 -0.0500000007 +0.0125000002 -0.0312500000 0.0312500000 +0.0125000002 -0.0312500000 0.0187500007 +0.0125000002 -0.0312500000 0.0062500001 +0.0125000002 -0.0312500000 -0.0062500001 +0.0125000002 -0.0312500000 -0.0187500007 +0.0125000002 -0.0312500000 -0.0312500000 +0.0125000002 -0.0312500000 -0.0437499993 +0.0125000002 -0.0312500000 -0.0500000007 +0.0125000002 -0.0437499993 0.0312500000 +0.0125000002 -0.0437499993 0.0187500007 +0.0125000002 -0.0437499993 0.0062500001 +0.0125000002 -0.0437499993 -0.0062500001 +0.0125000002 -0.0437499993 -0.0187500007 +0.0125000002 -0.0500000007 0.0312500000 +0.0125000002 -0.0500000007 0.0187500007 +0.0125000002 -0.0500000007 0.0062500001 +0.0125000002 -0.0500000007 -0.0062500001 +0.0125000002 -0.0500000007 -0.0187500007 +0.0124899996 0.0187500007 -0.0003910000 +0.0124150002 0.0312509984 -0.0062509999 +0.0124150002 0.0312509984 -0.0187490005 +0.0124150002 0.0187490005 -0.0062509999 +0.0124150002 0.0187490005 -0.0187490005 +0.0124150002 0.0062509999 -0.0187490005 +0.0124150002 -0.0062509999 -0.0187490005 +0.0124150002 -0.0187490005 -0.0187490005 +0.0120789995 -0.0437359996 -0.0312639996 +0.0120789995 -0.0500000007 -0.0312639996 +0.0120639997 0.0062650000 0.0312650017 +0.0120639997 0.0062650000 0.0187350009 +0.0120639997 0.0062650000 0.0062650000 +0.0118869999 0.0437199995 0.0312799998 +0.0118869999 0.0437199995 0.0187199991 +0.0118869999 0.0437199995 0.0062799999 +0.0118869999 0.0437199995 -0.0062799999 +0.0118869999 0.0437199995 -0.0187199991 +0.0118869999 0.0437199995 -0.0312799998 +0.0118869999 0.0437199995 -0.0437199995 +0.0118869999 0.0312799998 -0.0312799998 +0.0118869999 0.0312799998 -0.0437199995 +0.0118869999 0.0187199991 -0.0312799998 +0.0118869999 0.0187199991 -0.0437199995 +0.0118869999 0.0062799999 -0.0062799999 +0.0118869999 0.0062799999 -0.0312799998 +0.0118869999 0.0062799999 -0.0437199995 +0.0118869999 -0.0062799999 0.0312799998 +0.0118869999 -0.0062799999 0.0187199991 +0.0118869999 -0.0062799999 0.0062799999 +0.0118869999 -0.0062799999 -0.0062799999 +0.0118869999 -0.0062799999 -0.0312799998 +0.0118869999 -0.0062799999 -0.0437199995 +0.0118869999 -0.0187199991 0.0312799998 +0.0118869999 -0.0187199991 0.0187199991 +0.0118869999 -0.0187199991 0.0062799999 +0.0118869999 -0.0187199991 -0.0062799999 +0.0118869999 -0.0187199991 -0.0312799998 +0.0118869999 -0.0187199991 -0.0437199995 +0.0118869999 -0.0312799998 0.0312799998 +0.0118869999 -0.0312799998 0.0187199991 +0.0118869999 -0.0312799998 0.0062799999 +0.0118869999 -0.0312799998 -0.0062799999 +0.0118869999 -0.0312799998 -0.0187199991 +0.0118869999 -0.0312799998 -0.0312799998 +0.0118869999 -0.0312799998 -0.0437199995 +0.0118869999 -0.0437199995 0.0312799998 +0.0118869999 -0.0437199995 0.0187199991 +0.0118869999 -0.0437199995 0.0062799999 +0.0118869999 -0.0437199995 -0.0062799999 +0.0118869999 -0.0437199995 -0.0187199991 +0.0118129998 0.0312880017 -0.0062879999 +0.0118129998 0.0312880017 -0.0187120009 +0.0118129998 0.0187120009 -0.0062879999 +0.0118129998 0.0187120009 -0.0187120009 +0.0118129998 0.0062879999 -0.0187120009 +0.0118129998 -0.0062879999 -0.0187120009 +0.0118129998 -0.0187120009 -0.0187120009 +0.0113369999 -0.0436410010 -0.0313589983 +0.0112810005 0.0436300002 0.0313699991 +0.0112810005 0.0436300002 0.0186299998 +0.0112810005 0.0436300002 0.0063700001 +0.0112810005 0.0436300002 -0.0063700001 +0.0112810005 0.0436300002 -0.0186299998 +0.0112810005 0.0436300002 -0.0313699991 +0.0112810005 0.0436300002 -0.0436300002 +0.0112810005 0.0313699991 -0.0313699991 +0.0112810005 0.0313699991 -0.0436300002 +0.0112810005 0.0186299998 -0.0313699991 +0.0112810005 0.0186299998 -0.0436300002 +0.0112810005 0.0063700001 -0.0063700001 +0.0112810005 0.0063700001 -0.0313699991 +0.0112810005 0.0063700001 -0.0436300002 +0.0112810005 -0.0063700001 0.0313699991 +0.0112810005 -0.0063700001 0.0186299998 +0.0112810005 -0.0063700001 0.0063700001 +0.0112810005 -0.0063700001 -0.0063700001 +0.0112810005 -0.0063700001 -0.0313699991 +0.0112810005 -0.0063700001 -0.0436300002 +0.0112810005 -0.0186299998 0.0313699991 +0.0112810005 -0.0186299998 0.0186299998 +0.0112810005 -0.0186299998 0.0063700001 +0.0112810005 -0.0186299998 -0.0063700001 +0.0112810005 -0.0186299998 -0.0313699991 +0.0112810005 -0.0186299998 -0.0436300002 +0.0112810005 -0.0313699991 0.0313699991 +0.0112810005 -0.0313699991 0.0186299998 +0.0112810005 -0.0313699991 0.0063700001 +0.0112810005 -0.0313699991 -0.0063700001 +0.0112810005 -0.0313699991 -0.0186299998 +0.0112810005 -0.0313699991 -0.0313699991 +0.0112810005 -0.0313699991 -0.0436300002 +0.0112810005 -0.0436300002 0.0313699991 +0.0112810005 -0.0436300002 0.0186299998 +0.0112810005 -0.0436300002 0.0063700001 +0.0112810005 -0.0436300002 -0.0063700001 +0.0112810005 -0.0436300002 -0.0186299998 +0.0112260003 0.0313809998 -0.0003910000 +0.0112180002 0.0313830003 -0.0063829999 +0.0112180002 0.0313830003 -0.0186170004 +0.0112180002 0.0186170004 -0.0063829999 +0.0112180002 0.0186170004 -0.0186170004 +0.0112180002 0.0063829999 -0.0186170004 +0.0112180002 -0.0063829999 -0.0186170004 +0.0112180002 -0.0186170004 -0.0186170004 +0.0111830002 0.0063900002 0.0313900001 +0.0111830002 0.0063900002 0.0186100006 +0.0111830002 0.0063900002 0.0063900002 +0.0109249996 0.0185480006 -0.0003910000 +0.0108820004 0.0500000007 0.0314630009 +0.0108820004 0.0500000007 0.0185369998 +0.0108820004 0.0500000007 0.0064630001 +0.0108820004 0.0500000007 -0.0064630001 +0.0108820004 0.0500000007 -0.0185369998 +0.0108820004 0.0500000007 -0.0314630009 +0.0108820004 0.0500000007 -0.0435369983 +0.0108820004 0.0435369983 -0.0500000007 +0.0108820004 0.0314630009 -0.0500000007 +0.0108820004 0.0185369998 -0.0500000007 +0.0108820004 0.0064630001 -0.0500000007 +0.0108820004 -0.0064630001 -0.0500000007 +0.0108820004 -0.0185369998 -0.0500000007 +0.0108820004 -0.0314630009 -0.0500000007 +0.0108820004 -0.0500000007 0.0314630009 +0.0108820004 -0.0500000007 0.0185369998 +0.0108820004 -0.0500000007 0.0064630001 +0.0108820004 -0.0500000007 -0.0064630001 +0.0108820004 -0.0500000007 -0.0185369998 +0.0106130000 -0.0434579998 -0.0315419994 +0.0106130000 -0.0500000007 -0.0315419994 +0.0103280004 0.0066399998 0.0316400006 +0.0103280004 0.0066399998 0.0183600001 +0.0103280004 0.0066399998 0.0066399998 +0.0103280004 0.0066399998 -0.0003910000 +0.0101079997 0.0432740003 0.0317259990 +0.0101079997 0.0432740003 0.0182739999 +0.0101079997 0.0432740003 0.0067260000 +0.0101079997 0.0432740003 -0.0067260000 +0.0101079997 0.0432740003 -0.0182739999 +0.0101079997 0.0432740003 -0.0317259990 +0.0101079997 0.0432740003 -0.0432740003 +0.0101079997 0.0317259990 -0.0317259990 +0.0101079997 0.0317259990 -0.0432740003 +0.0101079997 0.0182739999 -0.0317259990 +0.0101079997 0.0182739999 -0.0432740003 +0.0101079997 0.0067260000 -0.0067260000 +0.0101079997 0.0067260000 -0.0317259990 +0.0101079997 0.0067260000 -0.0432740003 +0.0101079997 -0.0067260000 0.0317259990 +0.0101079997 -0.0067260000 0.0182739999 +0.0101079997 -0.0067260000 0.0067260000 +0.0101079997 -0.0067260000 -0.0067260000 +0.0101079997 -0.0067260000 -0.0317259990 +0.0101079997 -0.0067260000 -0.0432740003 +0.0101079997 -0.0182739999 0.0317259990 +0.0101079997 -0.0182739999 0.0182739999 +0.0101079997 -0.0182739999 0.0067260000 +0.0101079997 -0.0182739999 -0.0067260000 +0.0101079997 -0.0182739999 -0.0317259990 +0.0101079997 -0.0182739999 -0.0432740003 +0.0101079997 -0.0317259990 0.0317259990 +0.0101079997 -0.0317259990 0.0182739999 +0.0101079997 -0.0317259990 0.0067260000 +0.0101079997 -0.0317259990 -0.0067260000 +0.0101079997 -0.0317259990 -0.0182739999 +0.0101079997 -0.0317259990 -0.0317259990 +0.0101079997 -0.0317259990 -0.0432740003 +0.0101079997 -0.0432740003 0.0317259990 +0.0101079997 -0.0432740003 0.0182739999 +0.0101079997 -0.0432740003 0.0067260000 +0.0101079997 -0.0432740003 -0.0067260000 +0.0101079997 -0.0432740003 -0.0182739999 +0.0100689996 0.0317419991 -0.0067420001 +0.0100689996 0.0317419991 -0.0182579998 +0.0100689996 0.0182579998 -0.0067420001 +0.0100689996 0.0182579998 -0.0182579998 +0.0100689996 0.0067420001 -0.0182579998 +0.0100689996 -0.0067420001 -0.0182579998 +0.0100689996 -0.0182579998 -0.0182579998 +0.0099149998 -0.0431899987 -0.0318100005 +0.0098029999 0.0318619981 -0.0003910000 +0.0094659999 0.0061420002 0.0320359990 +0.0094659999 0.0061420002 0.0179639999 +0.0094659999 0.0061420002 0.0070360000 +0.0094600003 0.0179609992 -0.0003910000 +0.0093750004 0.0500000007 0.0320869982 +0.0093750004 0.0500000007 0.0179130007 +0.0093750004 0.0500000007 0.0070870002 +0.0093750004 0.0500000007 -0.0070870002 +0.0093750004 0.0500000007 -0.0179130007 +0.0093750004 0.0500000007 -0.0320869982 +0.0093750004 0.0500000007 -0.0429130010 +0.0093750004 0.0429130010 -0.0500000007 +0.0093750004 0.0320869982 -0.0500000007 +0.0093750004 0.0179130007 -0.0500000007 +0.0093750004 0.0070870002 -0.0500000007 +0.0093750004 -0.0070870002 -0.0500000007 +0.0093750004 -0.0179130007 -0.0500000007 +0.0093750004 -0.0320869982 -0.0500000007 +0.0093750004 -0.0500000007 0.0320869982 +0.0093750004 -0.0500000007 0.0179130007 +0.0093750004 -0.0500000007 0.0070870002 +0.0093750004 -0.0500000007 -0.0070870002 +0.0093750004 -0.0500000007 -0.0179130007 +0.0092540001 -0.0428409986 -0.0321590006 +0.0092540001 -0.0500000007 -0.0321590006 +0.0090279998 0.0426970012 0.0323030017 +0.0090279998 0.0426970012 0.0176970009 +0.0090279998 0.0426970012 0.0073030000 +0.0090279998 0.0426970012 -0.0073030000 +0.0090279998 0.0426970012 -0.0176970009 +0.0090279998 0.0426970012 -0.0323030017 +0.0090279998 0.0426970012 -0.0426970012 +0.0090279998 0.0323030017 -0.0323030017 +0.0090279998 0.0323030017 -0.0426970012 +0.0090279998 0.0176970009 -0.0323030017 +0.0090279998 0.0176970009 -0.0426970012 +0.0090279998 0.0073030000 -0.0073030000 +0.0090279998 0.0073030000 -0.0323030017 +0.0090279998 0.0073030000 -0.0426970012 +0.0090279998 -0.0073030000 0.0323030017 +0.0090279998 -0.0073030000 0.0176970009 +0.0090279998 -0.0073030000 0.0073030000 +0.0090279998 -0.0073030000 -0.0073030000 +0.0090279998 -0.0073030000 -0.0323030017 +0.0090279998 -0.0073030000 -0.0426970012 +0.0090279998 -0.0176970009 0.0323030017 +0.0090279998 -0.0176970009 0.0176970009 +0.0090279998 -0.0176970009 0.0073030000 +0.0090279998 -0.0176970009 -0.0073030000 +0.0090279998 -0.0176970009 -0.0323030017 +0.0090279998 -0.0176970009 -0.0426970012 +0.0090279998 -0.0323030017 0.0323030017 +0.0090279998 -0.0323030017 0.0176970009 +0.0090279998 -0.0323030017 0.0073030000 +0.0090279998 -0.0323030017 -0.0073030000 +0.0090279998 -0.0323030017 -0.0176970009 +0.0090279998 -0.0323030017 -0.0323030017 +0.0090279998 -0.0323030017 -0.0426970012 +0.0090279998 -0.0426970012 0.0323030017 +0.0090279998 -0.0426970012 0.0176970009 +0.0090279998 -0.0426970012 0.0073030000 +0.0090279998 -0.0426970012 -0.0073030000 +0.0090279998 -0.0426970012 -0.0176970009 +0.0090100002 0.0323150009 -0.0073150001 +0.0090100002 0.0323150009 -0.0176849999 +0.0090100002 0.0176849999 -0.0073150001 +0.0090100002 0.0176849999 -0.0176849999 +0.0090100002 0.0073150001 -0.0176849999 +0.0090100002 -0.0073150001 -0.0176849999 +0.0090100002 -0.0176849999 -0.0176849999 +0.0089290002 0.0073699998 -0.0003910000 +0.0086740004 0.0056840000 0.0325580016 +0.0086740004 0.0056840000 0.0174419992 +0.0086740004 0.0056840000 0.0075579998 +0.0085359998 0.0326679982 0.0326679982 +0.0085359998 0.0326679982 0.0173320007 +0.0085359998 0.0326679982 0.0076680002 +0.0085359998 0.0326679982 -0.0003910000 +0.0081890002 0.0170249995 -0.0003910000 +0.0080810003 0.0500000007 0.0330809988 +0.0080810003 0.0500000007 0.0169190001 +0.0080810003 0.0500000007 0.0080810003 +0.0080810003 0.0500000007 -0.0080810003 +0.0080810003 0.0500000007 -0.0169190001 +0.0080810003 0.0500000007 -0.0330809988 +0.0080810003 0.0500000007 -0.0419190004 +0.0080810003 0.0419190004 0.0330809988 +0.0080810003 0.0419190004 0.0169190001 +0.0080810003 0.0419190004 0.0080810003 +0.0080810003 0.0419190004 -0.0080810003 +0.0080810003 0.0419190004 -0.0169190001 +0.0080810003 0.0419190004 -0.0330809988 +0.0080810003 0.0419190004 -0.0419190004 +0.0080810003 0.0419190004 -0.0500000007 +0.0080810003 0.0330809988 0.0330809988 +0.0080810003 0.0330809988 0.0169190001 +0.0080810003 0.0330809988 0.0080810003 +0.0080810003 0.0330809988 -0.0080810003 +0.0080810003 0.0330809988 -0.0169190001 +0.0080810003 0.0330809988 -0.0330809988 +0.0080810003 0.0330809988 -0.0419190004 +0.0080810003 0.0330809988 -0.0500000007 +0.0080810003 0.0169190001 -0.0080810003 +0.0080810003 0.0169190001 -0.0169190001 +0.0080810003 0.0169190001 -0.0330809988 +0.0080810003 0.0169190001 -0.0419190004 +0.0080810003 0.0169190001 -0.0500000007 +0.0080810003 0.0080810003 -0.0080810003 +0.0080810003 0.0080810003 -0.0169190001 +0.0080810003 0.0080810003 -0.0330809988 +0.0080810003 0.0080810003 -0.0419190004 +0.0080810003 0.0080810003 -0.0500000007 +0.0080810003 -0.0080810003 0.0330809988 +0.0080810003 -0.0080810003 0.0169190001 +0.0080810003 -0.0080810003 0.0080810003 +0.0080810003 -0.0080810003 -0.0080810003 +0.0080810003 -0.0080810003 -0.0169190001 +0.0080810003 -0.0080810003 -0.0330809988 +0.0080810003 -0.0080810003 -0.0419190004 +0.0080810003 -0.0080810003 -0.0500000007 +0.0080810003 -0.0169190001 0.0330809988 +0.0080810003 -0.0169190001 0.0169190001 +0.0080810003 -0.0169190001 0.0080810003 +0.0080810003 -0.0169190001 -0.0080810003 +0.0080810003 -0.0169190001 -0.0169190001 +0.0080810003 -0.0169190001 -0.0330809988 +0.0080810003 -0.0169190001 -0.0419190004 +0.0080810003 -0.0169190001 -0.0500000007 +0.0080810003 -0.0330809988 0.0330809988 +0.0080810003 -0.0330809988 0.0169190001 +0.0080810003 -0.0330809988 0.0080810003 +0.0080810003 -0.0330809988 -0.0080810003 +0.0080810003 -0.0330809988 -0.0169190001 +0.0080810003 -0.0330809988 -0.0330809988 +0.0080810003 -0.0330809988 -0.0419190004 +0.0080810003 -0.0330809988 -0.0500000007 +0.0080810003 -0.0419190004 0.0330809988 +0.0080810003 -0.0419190004 0.0169190001 +0.0080810003 -0.0419190004 0.0080810003 +0.0080810003 -0.0419190004 -0.0080810003 +0.0080810003 -0.0419190004 -0.0169190001 +0.0080810003 -0.0419190004 -0.0330809988 +0.0080810003 -0.0500000007 0.0330809988 +0.0080810003 -0.0500000007 0.0169190001 +0.0080810003 -0.0500000007 0.0080810003 +0.0080810003 -0.0500000007 -0.0080810003 +0.0080810003 -0.0500000007 -0.0169190001 +0.0080810003 -0.0500000007 -0.0330809988 +0.0079690004 0.0052780001 0.0331950001 +0.0079690004 0.0052780001 0.0168050006 +0.0079690004 0.0052780001 0.0081949998 +0.0078480002 0.0322710015 0.0333260000 +0.0078480002 0.0322710015 0.0166740008 +0.0078480002 0.0322710015 0.0083259996 +0.0077579999 0.0084279999 -0.0003910000 +0.0075530000 0.0325529985 0.0336810015 +0.0075530000 0.0325529985 0.0163189992 +0.0075530000 0.0325529985 0.0086810002 +0.0073699998 0.0049319998 0.0339299999 +0.0073699998 0.0049319998 0.0160700008 +0.0073699998 0.0049319998 0.0089299995 +0.0073030000 0.0426970012 0.0340280011 +0.0073030000 0.0426970012 0.0159719996 +0.0073030000 0.0426970012 0.0090279998 +0.0073030000 0.0426970012 -0.0090279998 +0.0073030000 0.0426970012 -0.0159719996 +0.0073030000 0.0426970012 -0.0340280011 +0.0073030000 0.0426970012 -0.0409720019 +0.0073030000 0.0409720019 0.0323030017 +0.0073030000 0.0409720019 0.0176970009 +0.0073030000 0.0409720019 0.0073030000 +0.0073030000 0.0409720019 -0.0073030000 +0.0073030000 0.0409720019 -0.0176970009 +0.0073030000 0.0409720019 -0.0323030017 +0.0073030000 0.0409720019 -0.0426970012 +0.0073030000 0.0340280011 0.0323030017 +0.0073030000 0.0340280011 0.0176970009 +0.0073030000 0.0340280011 0.0073030000 +0.0073030000 0.0340280011 -0.0073030000 +0.0073030000 0.0340280011 -0.0176970009 +0.0073030000 0.0340280011 -0.0323030017 +0.0073030000 0.0340280011 -0.0426970012 +0.0073030000 0.0323030017 -0.0090279998 +0.0073030000 0.0323030017 -0.0159719996 +0.0073030000 0.0323030017 -0.0340280011 +0.0073030000 0.0323030017 -0.0409720019 +0.0073030000 0.0176970009 -0.0090279998 +0.0073030000 0.0176970009 -0.0159719996 +0.0073030000 0.0176970009 -0.0340280011 +0.0073030000 0.0176970009 -0.0409720019 +0.0073030000 0.0159719996 -0.0073030000 +0.0073030000 0.0159719996 -0.0176970009 +0.0073030000 0.0159719996 -0.0323030017 +0.0073030000 0.0159719996 -0.0426970012 +0.0073030000 0.0090279998 -0.0073030000 +0.0073030000 0.0090279998 -0.0176970009 +0.0073030000 0.0090279998 -0.0323030017 +0.0073030000 0.0090279998 -0.0426970012 +0.0073030000 0.0073030000 -0.0090279998 +0.0073030000 0.0073030000 -0.0159719996 +0.0073030000 0.0073030000 -0.0340280011 +0.0073030000 0.0073030000 -0.0409720019 +0.0073030000 -0.0073030000 0.0340280011 +0.0073030000 -0.0073030000 0.0159719996 +0.0073030000 -0.0073030000 0.0090279998 +0.0073030000 -0.0073030000 -0.0090279998 +0.0073030000 -0.0073030000 -0.0159719996 +0.0073030000 -0.0073030000 -0.0340280011 +0.0073030000 -0.0073030000 -0.0409720019 +0.0073030000 -0.0090279998 0.0323030017 +0.0073030000 -0.0090279998 0.0176970009 +0.0073030000 -0.0090279998 0.0073030000 +0.0073030000 -0.0090279998 -0.0073030000 +0.0073030000 -0.0090279998 -0.0176970009 +0.0073030000 -0.0090279998 -0.0323030017 +0.0073030000 -0.0090279998 -0.0426970012 +0.0073030000 -0.0159719996 0.0323030017 +0.0073030000 -0.0159719996 0.0176970009 +0.0073030000 -0.0159719996 0.0073030000 +0.0073030000 -0.0159719996 -0.0073030000 +0.0073030000 -0.0159719996 -0.0176970009 +0.0073030000 -0.0159719996 -0.0323030017 +0.0073030000 -0.0159719996 -0.0426970012 +0.0073030000 -0.0176970009 0.0340280011 +0.0073030000 -0.0176970009 0.0159719996 +0.0073030000 -0.0176970009 0.0090279998 +0.0073030000 -0.0176970009 -0.0090279998 +0.0073030000 -0.0176970009 -0.0159719996 +0.0073030000 -0.0176970009 -0.0340280011 +0.0073030000 -0.0176970009 -0.0409720019 +0.0073030000 -0.0323030017 0.0340280011 +0.0073030000 -0.0323030017 0.0159719996 +0.0073030000 -0.0323030017 0.0090279998 +0.0073030000 -0.0323030017 -0.0090279998 +0.0073030000 -0.0323030017 -0.0159719996 +0.0073030000 -0.0323030017 -0.0340280011 +0.0073030000 -0.0323030017 -0.0409720019 +0.0073030000 -0.0340280011 0.0323030017 +0.0073030000 -0.0340280011 0.0176970009 +0.0073030000 -0.0340280011 0.0073030000 +0.0073030000 -0.0340280011 -0.0073030000 +0.0073030000 -0.0340280011 -0.0176970009 +0.0073030000 -0.0340280011 -0.0323030017 +0.0073030000 -0.0340280011 -0.0426970012 +0.0073030000 -0.0409720019 0.0323030017 +0.0073030000 -0.0409720019 0.0176970009 +0.0073030000 -0.0409720019 0.0073030000 +0.0073030000 -0.0409720019 -0.0073030000 +0.0073030000 -0.0409720019 -0.0176970009 +0.0073030000 -0.0409720019 -0.0323030017 +0.0073030000 -0.0426970012 0.0340280011 +0.0073030000 -0.0426970012 0.0159719996 +0.0073030000 -0.0426970012 0.0090279998 +0.0073030000 -0.0426970012 -0.0090279998 +0.0073030000 -0.0426970012 -0.0159719996 +0.0072679999 0.0319360010 0.0340819992 +0.0072679999 0.0319360010 0.0159179997 +0.0072679999 0.0319360010 0.0090819998 +0.0071930001 0.0158009995 -0.0003910000 +0.0071589998 -0.0428409986 -0.0342539996 +0.0071589998 -0.0500000007 -0.0342539996 +0.0071060001 0.0321060009 0.0343430005 +0.0071060001 0.0321060009 0.0156570002 +0.0071060001 0.0321060009 0.0093430001 +0.0070870002 0.0500000007 0.0343750007 +0.0070870002 0.0500000007 0.0156250000 +0.0070870002 0.0500000007 0.0093750004 +0.0070870002 0.0500000007 -0.0093750004 +0.0070870002 0.0500000007 -0.0156250000 +0.0070870002 0.0500000007 -0.0343750007 +0.0070870002 0.0500000007 -0.0406249985 +0.0070870002 0.0406249985 -0.0500000007 +0.0070870002 0.0343750007 -0.0500000007 +0.0070870002 0.0156250000 -0.0500000007 +0.0070870002 0.0093750004 -0.0500000007 +0.0070870002 -0.0093750004 -0.0500000007 +0.0070870002 -0.0156250000 -0.0500000007 +0.0070870002 -0.0343750007 -0.0500000007 +0.0070870002 -0.0500000007 0.0343750007 +0.0070870002 -0.0500000007 0.0156250000 +0.0070870002 -0.0500000007 0.0093750004 +0.0070870002 -0.0500000007 -0.0093750004 +0.0070870002 -0.0500000007 -0.0156250000 +0.0068890001 0.0097460002 -0.0003910000 +0.0068890001 0.0046540000 0.0347479992 +0.0068890001 0.0046540000 0.0152519997 +0.0068890001 0.0046540000 0.0097479997 +0.0068100002 -0.0431899987 -0.0349150002 +0.0068089999 0.0316709988 0.0349159986 +0.0068089999 0.0316709988 0.0150840003 +0.0068089999 0.0316709988 0.0099160001 +0.0067469999 0.0317469984 0.0350570008 +0.0067469999 0.0317469984 0.0149429999 +0.0067469999 0.0317469984 0.0100570004 +0.0067260000 0.0432740003 0.0351080000 +0.0067260000 0.0432740003 0.0148919998 +0.0067260000 0.0432740003 0.0101079997 +0.0067260000 0.0432740003 -0.0101079997 +0.0067260000 0.0432740003 -0.0148919998 +0.0067260000 0.0432740003 -0.0351080000 +0.0067260000 0.0432740003 -0.0398919992 +0.0067260000 0.0398919992 0.0317259990 +0.0067260000 0.0398919992 0.0182739999 +0.0067260000 0.0398919992 0.0067260000 +0.0067260000 0.0398919992 -0.0067260000 +0.0067260000 0.0398919992 -0.0182739999 +0.0067260000 0.0398919992 -0.0317259990 +0.0067260000 0.0398919992 -0.0432740003 +0.0067260000 0.0351080000 0.0317259990 +0.0067260000 0.0351080000 0.0182739999 +0.0067260000 0.0351080000 0.0067260000 +0.0067260000 0.0351080000 -0.0067260000 +0.0067260000 0.0351080000 -0.0182739999 +0.0067260000 0.0351080000 -0.0317259990 +0.0067260000 0.0351080000 -0.0432740003 +0.0067260000 0.0317259990 -0.0101079997 +0.0067260000 0.0317259990 -0.0148919998 +0.0067260000 0.0317259990 -0.0351080000 +0.0067260000 0.0317259990 -0.0398919992 +0.0067260000 0.0182739999 -0.0101079997 +0.0067260000 0.0182739999 -0.0148919998 +0.0067260000 0.0182739999 -0.0351080000 +0.0067260000 0.0182739999 -0.0398919992 +0.0067260000 0.0148919998 -0.0067260000 +0.0067260000 0.0148919998 -0.0182739999 +0.0067260000 0.0148919998 -0.0317259990 +0.0067260000 0.0148919998 -0.0432740003 +0.0067260000 0.0101079997 -0.0067260000 +0.0067260000 0.0101079997 -0.0182739999 +0.0067260000 0.0101079997 -0.0317259990 +0.0067260000 0.0101079997 -0.0432740003 +0.0067260000 0.0067260000 -0.0101079997 +0.0067260000 0.0067260000 -0.0148919998 +0.0067260000 0.0067260000 -0.0351080000 +0.0067260000 0.0067260000 -0.0398919992 +0.0067260000 -0.0067260000 0.0351080000 +0.0067260000 -0.0067260000 0.0148919998 +0.0067260000 -0.0067260000 0.0101079997 +0.0067260000 -0.0067260000 -0.0101079997 +0.0067260000 -0.0067260000 -0.0148919998 +0.0067260000 -0.0067260000 -0.0351080000 +0.0067260000 -0.0067260000 -0.0398919992 +0.0067260000 -0.0101079997 0.0317259990 +0.0067260000 -0.0101079997 0.0182739999 +0.0067260000 -0.0101079997 0.0067260000 +0.0067260000 -0.0101079997 -0.0067260000 +0.0067260000 -0.0101079997 -0.0182739999 +0.0067260000 -0.0101079997 -0.0317259990 +0.0067260000 -0.0101079997 -0.0432740003 +0.0067260000 -0.0148919998 0.0317259990 +0.0067260000 -0.0148919998 0.0182739999 +0.0067260000 -0.0148919998 0.0067260000 +0.0067260000 -0.0148919998 -0.0067260000 +0.0067260000 -0.0148919998 -0.0182739999 +0.0067260000 -0.0148919998 -0.0317259990 +0.0067260000 -0.0148919998 -0.0432740003 +0.0067260000 -0.0182739999 0.0351080000 +0.0067260000 -0.0182739999 0.0148919998 +0.0067260000 -0.0182739999 0.0101079997 +0.0067260000 -0.0182739999 -0.0101079997 +0.0067260000 -0.0182739999 -0.0148919998 +0.0067260000 -0.0182739999 -0.0351080000 +0.0067260000 -0.0182739999 -0.0398919992 +0.0067260000 -0.0317259990 0.0351080000 +0.0067260000 -0.0317259990 0.0148919998 +0.0067260000 -0.0317259990 0.0101079997 +0.0067260000 -0.0317259990 -0.0101079997 +0.0067260000 -0.0317259990 -0.0148919998 +0.0067260000 -0.0317259990 -0.0351080000 +0.0067260000 -0.0317259990 -0.0398919992 +0.0067260000 -0.0351080000 0.0317259990 +0.0067260000 -0.0351080000 0.0182739999 +0.0067260000 -0.0351080000 0.0067260000 +0.0067260000 -0.0351080000 -0.0067260000 +0.0067260000 -0.0351080000 -0.0182739999 +0.0067260000 -0.0351080000 -0.0317259990 +0.0067260000 -0.0351080000 -0.0432740003 +0.0067260000 -0.0398919992 0.0317259990 +0.0067260000 -0.0398919992 0.0182739999 +0.0067260000 -0.0398919992 0.0067260000 +0.0067260000 -0.0398919992 -0.0067260000 +0.0067260000 -0.0398919992 -0.0182739999 +0.0067260000 -0.0398919992 -0.0317259990 +0.0067260000 -0.0432740003 0.0351080000 +0.0067260000 -0.0432740003 0.0148919998 +0.0067260000 -0.0432740003 0.0101079997 +0.0067260000 -0.0432740003 -0.0101079997 +0.0067260000 -0.0432740003 -0.0148919998 +0.0065420000 -0.0434579998 -0.0356130004 +0.0065420000 -0.0500000007 -0.0356130004 +0.0065370002 0.0044499999 0.0356290005 +0.0065370002 0.0044499999 0.0143710002 +0.0065370002 0.0044499999 0.0106290001 +0.0065350002 0.0143670002 -0.0003910000 +0.0064829998 0.0314829983 0.0358109996 +0.0064829998 0.0314829983 0.0141890002 +0.0064829998 0.0314829983 0.0108110001 +0.0064630001 0.0500000007 0.0358819999 +0.0064630001 0.0500000007 0.0141179999 +0.0064630001 0.0500000007 0.0108820004 +0.0064630001 0.0500000007 -0.0108820004 +0.0064630001 0.0500000007 -0.0141179999 +0.0064630001 0.0500000007 -0.0358819999 +0.0064630001 0.0500000007 -0.0391179994 +0.0064630001 0.0391179994 -0.0500000007 +0.0064630001 0.0358819999 -0.0500000007 +0.0064630001 0.0141179999 -0.0500000007 +0.0064630001 0.0108820004 -0.0500000007 +0.0064630001 -0.0108820004 -0.0500000007 +0.0064630001 -0.0141179999 -0.0500000007 +0.0064630001 -0.0358819999 -0.0500000007 +0.0064630001 -0.0500000007 0.0358819999 +0.0064630001 -0.0500000007 0.0141179999 +0.0064630001 -0.0500000007 0.0108820004 +0.0064630001 -0.0500000007 -0.0108820004 +0.0064630001 -0.0500000007 -0.0141179999 +0.0063780001 0.0112389997 -0.0003910000 +0.0063700001 0.0436300002 0.0362810008 +0.0063700001 0.0436300002 0.0137189999 +0.0063700001 0.0436300002 0.0112810005 +0.0063700001 0.0436300002 -0.0112810005 +0.0063700001 0.0436300002 -0.0137189999 +0.0063700001 0.0436300002 -0.0362810008 +0.0063700001 0.0436300002 -0.0387189984 +0.0063700001 0.0387189984 0.0313699991 +0.0063700001 0.0387189984 0.0186299998 +0.0063700001 0.0387189984 0.0063700001 +0.0063700001 0.0387189984 -0.0063700001 +0.0063700001 0.0387189984 -0.0186299998 +0.0063700001 0.0387189984 -0.0313699991 +0.0063700001 0.0387189984 -0.0436300002 +0.0063700001 0.0362810008 0.0313699991 +0.0063700001 0.0362810008 0.0186299998 +0.0063700001 0.0362810008 0.0063700001 +0.0063700001 0.0362810008 -0.0063700001 +0.0063700001 0.0362810008 -0.0186299998 +0.0063700001 0.0362810008 -0.0313699991 +0.0063700001 0.0362810008 -0.0436300002 +0.0063700001 0.0313699991 -0.0112810005 +0.0063700001 0.0313699991 -0.0137189999 +0.0063700001 0.0313699991 -0.0362810008 +0.0063700001 0.0313699991 -0.0387189984 +0.0063700001 0.0186299998 -0.0112810005 +0.0063700001 0.0186299998 -0.0137189999 +0.0063700001 0.0186299998 -0.0362810008 +0.0063700001 0.0186299998 -0.0387189984 +0.0063700001 0.0137189999 -0.0063700001 +0.0063700001 0.0137189999 -0.0186299998 +0.0063700001 0.0137189999 -0.0313699991 +0.0063700001 0.0137189999 -0.0436300002 +0.0063700001 0.0112810005 -0.0063700001 +0.0063700001 0.0112810005 -0.0186299998 +0.0063700001 0.0112810005 -0.0313699991 +0.0063700001 0.0112810005 -0.0436300002 +0.0063700001 0.0063700001 -0.0112810005 +0.0063700001 0.0063700001 -0.0137189999 +0.0063700001 0.0063700001 -0.0362810008 +0.0063700001 0.0063700001 -0.0387189984 +0.0063700001 -0.0063700001 0.0362810008 +0.0063700001 -0.0063700001 0.0137189999 +0.0063700001 -0.0063700001 0.0112810005 +0.0063700001 -0.0063700001 -0.0112810005 +0.0063700001 -0.0063700001 -0.0137189999 +0.0063700001 -0.0063700001 -0.0362810008 +0.0063700001 -0.0063700001 -0.0387189984 +0.0063700001 -0.0112810005 0.0313699991 +0.0063700001 -0.0112810005 0.0186299998 +0.0063700001 -0.0112810005 0.0063700001 +0.0063700001 -0.0112810005 -0.0063700001 +0.0063700001 -0.0112810005 -0.0186299998 +0.0063700001 -0.0112810005 -0.0313699991 +0.0063700001 -0.0112810005 -0.0436300002 +0.0063700001 -0.0137189999 0.0313699991 +0.0063700001 -0.0137189999 0.0186299998 +0.0063700001 -0.0137189999 0.0063700001 +0.0063700001 -0.0137189999 -0.0063700001 +0.0063700001 -0.0137189999 -0.0186299998 +0.0063700001 -0.0137189999 -0.0313699991 +0.0063700001 -0.0137189999 -0.0436300002 +0.0063700001 -0.0186299998 0.0362810008 +0.0063700001 -0.0186299998 0.0137189999 +0.0063700001 -0.0186299998 0.0112810005 +0.0063700001 -0.0186299998 -0.0112810005 +0.0063700001 -0.0186299998 -0.0137189999 +0.0063700001 -0.0186299998 -0.0362810008 +0.0063700001 -0.0186299998 -0.0387189984 +0.0063700001 -0.0313699991 0.0362810008 +0.0063700001 -0.0313699991 0.0137189999 +0.0063700001 -0.0313699991 0.0112810005 +0.0063700001 -0.0313699991 -0.0112810005 +0.0063700001 -0.0313699991 -0.0137189999 +0.0063700001 -0.0313699991 -0.0362810008 +0.0063700001 -0.0313699991 -0.0387189984 +0.0063700001 -0.0362810008 0.0313699991 +0.0063700001 -0.0362810008 0.0186299998 +0.0063700001 -0.0362810008 0.0063700001 +0.0063700001 -0.0362810008 -0.0063700001 +0.0063700001 -0.0362810008 -0.0186299998 +0.0063700001 -0.0362810008 -0.0313699991 +0.0063700001 -0.0362810008 -0.0436300002 +0.0063700001 -0.0387189984 0.0313699991 +0.0063700001 -0.0387189984 0.0186299998 +0.0063700001 -0.0387189984 0.0063700001 +0.0063700001 -0.0387189984 -0.0063700001 +0.0063700001 -0.0387189984 -0.0186299998 +0.0063700001 -0.0387189984 -0.0313699991 +0.0063700001 -0.0436300002 0.0362810008 +0.0063700001 -0.0436300002 0.0137189999 +0.0063700001 -0.0436300002 0.0112810005 +0.0063700001 -0.0436300002 -0.0112810005 +0.0063700001 -0.0436300002 -0.0137189999 +0.0063590002 -0.0436410010 -0.0363369994 +0.0063419999 -0.0436579995 -0.0385689996 +0.0063419999 -0.0500000007 -0.0385689996 +0.0063220002 0.0043270001 0.0365540013 +0.0063220002 0.0043270001 0.0134460004 +0.0063220002 0.0043270001 0.0115540000 +0.0062799999 0.0437199995 0.0368870012 +0.0062799999 0.0437199995 0.0131130004 +0.0062799999 0.0437199995 0.0118869999 +0.0062799999 0.0437199995 -0.0118869999 +0.0062799999 0.0437199995 -0.0131130004 +0.0062799999 0.0437199995 -0.0368870012 +0.0062799999 0.0437199995 -0.0381130017 +0.0062799999 0.0381130017 0.0312799998 +0.0062799999 0.0381130017 0.0187199991 +0.0062799999 0.0381130017 0.0062799999 +0.0062799999 0.0381130017 -0.0062799999 +0.0062799999 0.0381130017 -0.0187199991 +0.0062799999 0.0381130017 -0.0312799998 +0.0062799999 0.0381130017 -0.0437199995 +0.0062799999 0.0368870012 0.0312799998 +0.0062799999 0.0368870012 0.0187199991 +0.0062799999 0.0368870012 0.0062799999 +0.0062799999 0.0368870012 -0.0062799999 +0.0062799999 0.0368870012 -0.0187199991 +0.0062799999 0.0368870012 -0.0312799998 +0.0062799999 0.0368870012 -0.0437199995 +0.0062799999 0.0312799998 -0.0118869999 +0.0062799999 0.0312799998 -0.0131130004 +0.0062799999 0.0312799998 -0.0368870012 +0.0062799999 0.0312799998 -0.0381130017 +0.0062799999 0.0187199991 -0.0118869999 +0.0062799999 0.0187199991 -0.0131130004 +0.0062799999 0.0187199991 -0.0368870012 +0.0062799999 0.0187199991 -0.0381130017 +0.0062799999 0.0131130004 -0.0062799999 +0.0062799999 0.0131130004 -0.0187199991 +0.0062799999 0.0131130004 -0.0312799998 +0.0062799999 0.0131130004 -0.0437199995 +0.0062799999 0.0118869999 -0.0062799999 +0.0062799999 0.0118869999 -0.0187199991 +0.0062799999 0.0118869999 -0.0312799998 +0.0062799999 0.0118869999 -0.0437199995 +0.0062799999 0.0062799999 -0.0118869999 +0.0062799999 0.0062799999 -0.0131130004 +0.0062799999 0.0062799999 -0.0368870012 +0.0062799999 0.0062799999 -0.0381130017 +0.0062799999 -0.0062799999 0.0368870012 +0.0062799999 -0.0062799999 0.0131130004 +0.0062799999 -0.0062799999 0.0118869999 +0.0062799999 -0.0062799999 -0.0118869999 +0.0062799999 -0.0062799999 -0.0131130004 +0.0062799999 -0.0062799999 -0.0368870012 +0.0062799999 -0.0062799999 -0.0381130017 +0.0062799999 -0.0118869999 0.0312799998 +0.0062799999 -0.0118869999 0.0187199991 +0.0062799999 -0.0118869999 0.0062799999 +0.0062799999 -0.0118869999 -0.0062799999 +0.0062799999 -0.0118869999 -0.0187199991 +0.0062799999 -0.0118869999 -0.0312799998 +0.0062799999 -0.0118869999 -0.0437199995 +0.0062799999 -0.0131130004 0.0312799998 +0.0062799999 -0.0131130004 0.0187199991 +0.0062799999 -0.0131130004 0.0062799999 +0.0062799999 -0.0131130004 -0.0062799999 +0.0062799999 -0.0131130004 -0.0187199991 +0.0062799999 -0.0131130004 -0.0312799998 +0.0062799999 -0.0131130004 -0.0437199995 +0.0062799999 -0.0187199991 0.0368870012 +0.0062799999 -0.0187199991 0.0131130004 +0.0062799999 -0.0187199991 0.0118869999 +0.0062799999 -0.0187199991 -0.0118869999 +0.0062799999 -0.0187199991 -0.0131130004 +0.0062799999 -0.0187199991 -0.0368870012 +0.0062799999 -0.0187199991 -0.0381130017 +0.0062799999 -0.0312799998 0.0368870012 +0.0062799999 -0.0312799998 0.0131130004 +0.0062799999 -0.0312799998 0.0118869999 +0.0062799999 -0.0312799998 -0.0118869999 +0.0062799999 -0.0312799998 -0.0131130004 +0.0062799999 -0.0312799998 -0.0368870012 +0.0062799999 -0.0312799998 -0.0381130017 +0.0062799999 -0.0368870012 0.0312799998 +0.0062799999 -0.0368870012 0.0187199991 +0.0062799999 -0.0368870012 0.0062799999 +0.0062799999 -0.0368870012 -0.0062799999 +0.0062799999 -0.0368870012 -0.0187199991 +0.0062799999 -0.0368870012 -0.0312799998 +0.0062799999 -0.0368870012 -0.0437199995 +0.0062799999 -0.0381130017 0.0312799998 +0.0062799999 -0.0381130017 0.0187199991 +0.0062799999 -0.0381130017 0.0062799999 +0.0062799999 -0.0381130017 -0.0062799999 +0.0062799999 -0.0381130017 -0.0187199991 +0.0062799999 -0.0381130017 -0.0312799998 +0.0062799999 -0.0437199995 0.0368870012 +0.0062799999 -0.0437199995 0.0131130004 +0.0062799999 -0.0437199995 0.0118869999 +0.0062799999 -0.0437199995 -0.0118869999 +0.0062799999 -0.0437199995 -0.0131130004 +0.0062640002 -0.0437359996 -0.0370789990 +0.0062640002 -0.0500000007 -0.0370789990 +0.0062589999 -0.0437409990 -0.0378260016 +0.0062580002 0.0128130000 -0.0003910000 +0.0062500001 0.0500000007 0.0375000015 +0.0062500001 0.0500000007 0.0125000002 +0.0062500001 0.0500000007 -0.0125000002 +0.0062500001 0.0500000007 -0.0375000015 +0.0062500001 0.0437499993 0.0375000015 +0.0062500001 0.0437499993 0.0125000002 +0.0062500001 0.0437499993 -0.0125000002 +0.0062500001 0.0437499993 -0.0375000015 +0.0062500001 0.0375000015 0.0312500000 +0.0062500001 0.0375000015 0.0187500007 +0.0062500001 0.0375000015 0.0062500001 +0.0062500001 0.0375000015 -0.0062500001 +0.0062500001 0.0375000015 -0.0187500007 +0.0062500001 0.0375000015 -0.0312500000 +0.0062500001 0.0375000015 -0.0437499993 +0.0062500001 0.0375000015 -0.0500000007 +0.0062500001 0.0312500000 -0.0125000002 +0.0062500001 0.0312500000 -0.0375000015 +0.0062500001 0.0187500007 -0.0125000002 +0.0062500001 0.0187500007 -0.0375000015 +0.0062500001 0.0125000002 -0.0062500001 +0.0062500001 0.0125000002 -0.0187500007 +0.0062500001 0.0125000002 -0.0312500000 +0.0062500001 0.0125000002 -0.0437499993 +0.0062500001 0.0125000002 -0.0500000007 +0.0062500001 0.0062500001 -0.0125000002 +0.0062500001 0.0062500001 -0.0375000015 +0.0062500001 0.0042849998 0.0375000015 +0.0062500001 0.0042849998 0.0125000002 +0.0062500001 -0.0062500001 0.0375000015 +0.0062500001 -0.0062500001 0.0125000002 +0.0062500001 -0.0062500001 -0.0125000002 +0.0062500001 -0.0062500001 -0.0375000015 +0.0062500001 -0.0125000002 0.0312500000 +0.0062500001 -0.0125000002 0.0187500007 +0.0062500001 -0.0125000002 0.0062500001 +0.0062500001 -0.0125000002 -0.0062500001 +0.0062500001 -0.0125000002 -0.0187500007 +0.0062500001 -0.0125000002 -0.0312500000 +0.0062500001 -0.0125000002 -0.0437499993 +0.0062500001 -0.0125000002 -0.0500000007 +0.0062500001 -0.0187500007 0.0375000015 +0.0062500001 -0.0187500007 0.0125000002 +0.0062500001 -0.0187500007 -0.0125000002 +0.0062500001 -0.0187500007 -0.0375000015 +0.0062500001 -0.0312500000 0.0375000015 +0.0062500001 -0.0312500000 0.0125000002 +0.0062500001 -0.0312500000 -0.0125000002 +0.0062500001 -0.0312500000 -0.0375000015 +0.0062500001 -0.0375000015 0.0312500000 +0.0062500001 -0.0375000015 0.0187500007 +0.0062500001 -0.0375000015 0.0062500001 +0.0062500001 -0.0375000015 -0.0062500001 +0.0062500001 -0.0375000015 -0.0187500007 +0.0062500001 -0.0375000015 -0.0312500000 +0.0062500001 -0.0375000015 -0.0437499993 +0.0062500001 -0.0375000015 -0.0500000007 +0.0062500001 -0.0437499993 0.0375000015 +0.0062500001 -0.0437499993 0.0125000002 +0.0062500001 -0.0437499993 -0.0125000002 +0.0062500001 -0.0500000007 0.0375000015 +0.0062500001 -0.0500000007 0.0125000002 +0.0062500001 -0.0500000007 -0.0125000002 +0.0061809998 0.0313079990 0.0366469994 +0.0061809998 0.0313079990 0.0133530004 +0.0061809998 0.0313079990 0.0116470000 +0.0061050002 0.0312650017 0.0370730013 +0.0061050002 0.0312650017 0.0129270004 +0.0061050002 0.0312650017 0.0120730000 +0.0060800002 0.0312500000 0.0375000015 +0.0060800002 0.0312500000 0.0125000002 +0.0052870000 -0.0433779992 -0.0396240018 +0.0042969999 -0.0429189987 -0.0406140015 +0.0034020001 -0.0422939993 -0.0415100008 +0.0026290000 -0.0415240005 -0.0422820002 +0.0024999999 0.0500000007 0.0500000007 +0.0024999999 0.0500000007 0.0375000015 +0.0024999999 0.0437499993 0.0375000015 +0.0024999999 0.0435369983 0.0391179994 +0.0024999999 0.0429130010 0.0406249985 +0.0024999999 0.0419190004 0.0419190004 +0.0024999999 0.0406249985 0.0429130010 +0.0024999999 0.0391179994 0.0435369983 +0.0024999999 0.0375000015 0.0437499993 +0.0024999999 0.0358819999 0.0435369983 +0.0024999999 0.0343750007 0.0429130010 +0.0024999999 0.0330809988 0.0419190004 +0.0024999999 0.0320869982 0.0406249985 +0.0024999999 0.0314630009 0.0391179994 +0.0024999999 0.0312500000 0.0375000015 +0.0024999999 0.0291830003 0.0500000007 +0.0024999999 0.0291830003 0.0375000015 +0.0024999999 0.0021200001 0.0500000007 +0.0024999999 0.0021200001 0.0375000015 +0.0024999999 -0.0062500001 0.0375000015 +0.0024999999 -0.0064630001 0.0391179994 +0.0024999999 -0.0070870002 0.0406249985 +0.0024999999 -0.0080810003 0.0419190004 +0.0024999999 -0.0093750004 0.0429130010 +0.0024999999 -0.0108820004 0.0435369983 +0.0024999999 -0.0125000002 0.0437499993 +0.0024999999 -0.0141179999 0.0435369983 +0.0024999999 -0.0156250000 0.0429130010 +0.0024999999 -0.0169190001 0.0419190004 +0.0024999999 -0.0179130007 0.0406249985 +0.0024999999 -0.0185369998 0.0391179994 +0.0024999999 -0.0187500007 0.0375000015 +0.0024999999 -0.0312500000 0.0375000015 +0.0024999999 -0.0314630009 0.0391179994 +0.0024999999 -0.0320869982 0.0406249985 +0.0024999999 -0.0330809988 0.0419190004 +0.0024999999 -0.0343750007 0.0429130010 +0.0024999999 -0.0358819999 0.0435369983 +0.0024999999 -0.0375000015 0.0437499993 +0.0024999999 -0.0391179994 0.0435369983 +0.0024999999 -0.0406249985 0.0429130010 +0.0024999999 -0.0419190004 0.0419190004 +0.0024999999 -0.0429130010 0.0406249985 +0.0024999999 -0.0435369983 0.0391179994 +0.0024999999 -0.0437499993 0.0375000015 +0.0024999999 -0.0500000007 0.0500000007 +0.0024999999 -0.0500000007 0.0375000015 +0.0020020001 -0.0406300016 -0.0429099984 +0.0015390000 -0.0396410003 -0.0433720015 +0.0012560000 -0.0385870002 -0.0436550006 +0.0011610000 -0.0375000015 -0.0437499993 +0.0001880000 0.0007850000 0.0500000007 +0.0001880000 0.0007850000 -0.0003910000 +0.0000000000 -0.0287500005 0.0500000007 +0.0000000000 -0.0287500005 0.0250000004 +0.0000000000 -0.0312500000 0.0375000015 +0.0000000000 -0.0314630009 0.0391179994 +0.0000000000 -0.0314630009 0.0358819999 +0.0000000000 -0.0320869982 0.0406249985 +0.0000000000 -0.0320869982 0.0343750007 +0.0000000000 -0.0330809988 0.0419190004 +0.0000000000 -0.0330809988 0.0330809988 +0.0000000000 -0.0343750007 0.0429130010 +0.0000000000 -0.0343750007 0.0320869982 +0.0000000000 -0.0358819999 0.0435369983 +0.0000000000 -0.0358819999 0.0314630009 +0.0000000000 -0.0375000015 0.0437499993 +0.0000000000 -0.0375000015 0.0312500000 +0.0000000000 -0.0391179994 0.0435369983 +0.0000000000 -0.0391179994 0.0314630009 +0.0000000000 -0.0406249985 0.0429130010 +0.0000000000 -0.0406249985 0.0320869982 +0.0000000000 -0.0419190004 0.0419190004 +0.0000000000 -0.0419190004 0.0330809988 +0.0000000000 -0.0429130010 0.0406249985 +0.0000000000 -0.0429130010 0.0343750007 +0.0000000000 -0.0435369983 0.0391179994 +0.0000000000 -0.0435369983 0.0358819999 +0.0000000000 -0.0437499993 0.0375000015 +0.0000000000 -0.0500000007 0.0500000007 +0.0000000000 -0.0500000007 0.0250000004 +-0.0001280000 -0.0277789999 0.0500000007 +-0.0001280000 -0.0277789999 0.0250000004 +-0.0001280000 -0.0287500005 0.0240289997 +-0.0001280000 -0.0500000007 0.0240289997 +-0.0003470000 -0.0276640002 0.0238589998 +-0.0005020000 -0.0268750004 0.0500000007 +-0.0005020000 -0.0268750004 0.0250000004 +-0.0005020000 -0.0287500005 0.0231250003 +-0.0005020000 -0.0500000007 0.0231250003 +-0.0008140000 -0.0266350005 0.0240150001 +-0.0008150000 -0.0279510003 0.0228070002 +-0.0009370000 -0.0271259993 0.0231250003 +-0.0010980000 -0.0260979999 0.0500000007 +-0.0010980000 -0.0260979999 0.0250000004 +-0.0010980000 -0.0287500005 0.0223479997 +-0.0010980000 -0.0500000007 0.0223479997 +-0.0012250000 0.0002000000 0.0500000007 +-0.0012250000 0.0002000000 -0.0003910000 +-0.0014540000 -0.0264539998 0.0231250003 +-0.0014540000 -0.0274240002 0.0223479997 +-0.0014780000 -0.0259300005 0.0240269993 +-0.0014820000 -0.0281390008 0.0220769998 +-0.0018750000 -0.0255020000 0.0500000007 +-0.0018750000 -0.0255020000 0.0250000004 +-0.0018750000 -0.0268750004 0.0223479997 +-0.0018750000 -0.0287500005 0.0217519999 +-0.0018750000 -0.0500000007 0.0217519999 +-0.0021259999 -0.0259370003 0.0231250003 +-0.0021259999 -0.0278120004 0.0217519999 +-0.0021850001 -0.0254929997 0.0239979997 +-0.0022090001 -0.0282830000 0.0216130000 +-0.0024240001 -0.0264539998 0.0223479997 +-0.0024240001 -0.0274240002 0.0217519999 +-0.0027419999 -0.0000000000 0.0500000007 +-0.0027419999 -0.0000000000 -0.0003910000 +-0.0027790000 -0.0251279995 0.0500000007 +-0.0027790000 -0.0251279995 0.0250000004 +-0.0027790000 -0.0287500005 0.0213779993 +-0.0027790000 -0.0500000007 0.0213779993 +-0.0028120000 -0.0271259993 0.0217519999 +-0.0028619999 -0.0285710003 0.0213610008 +-0.0028639999 -0.0251599997 0.0243759993 +-0.0029090000 -0.0282649994 0.0213779993 +-0.0029190001 -0.0254170001 0.0234960001 +-0.0029879999 -0.0258970000 0.0226889998 +-0.0030640000 -0.0280639995 0.0213779993 +-0.0031699999 -0.0265859999 0.0219930001 +-0.0032649999 -0.0279089995 0.0213779993 +-0.0034159999 -0.0275030006 0.0214789994 +-0.0037499999 -0.0250000004 0.0500000007 +-0.0037499999 -0.0250000004 0.0250000004 +-0.0037499999 -0.0251279995 0.0240289997 +-0.0037499999 -0.0255020000 0.0231250003 +-0.0037499999 -0.0260979999 0.0223479997 +-0.0037499999 -0.0268750004 0.0217519999 +-0.0037499999 -0.0277789999 0.0213779993 +-0.0037499999 -0.0287500005 0.0212500002 +-0.0037499999 -0.0500000007 0.0212500002 +-0.0050889999 -0.0375000015 -0.0500000007 +-0.0050889999 -0.0500000007 -0.0500000007 +-0.0062500001 0.0500000007 0.0375000015 +-0.0062500001 0.0500000007 0.0125000002 +-0.0062500001 0.0500000007 -0.0125000002 +-0.0062500001 0.0500000007 -0.0375000015 +-0.0062500001 0.0437499993 0.0375000015 +-0.0062500001 0.0437499993 0.0125000002 +-0.0062500001 0.0437499993 -0.0125000002 +-0.0062500001 0.0437499993 -0.0375000015 +-0.0062500001 0.0375000015 0.0500000007 +-0.0062500001 0.0375000015 0.0437499993 +-0.0062500001 0.0375000015 0.0312500000 +-0.0062500001 0.0375000015 0.0187500007 +-0.0062500001 0.0375000015 0.0062500001 +-0.0062500001 0.0375000015 -0.0062500001 +-0.0062500001 0.0375000015 -0.0187500007 +-0.0062500001 0.0375000015 -0.0312500000 +-0.0062500001 0.0375000015 -0.0437499993 +-0.0062500001 0.0375000015 -0.0500000007 +-0.0062500001 0.0312500000 0.0375000015 +-0.0062500001 0.0312500000 0.0125000002 +-0.0062500001 0.0312500000 -0.0125000002 +-0.0062500001 0.0312500000 -0.0375000015 +-0.0062500001 0.0241310000 0.0375000015 +-0.0062500001 0.0241310000 0.0125000002 +-0.0062500001 0.0187500007 -0.0125000002 +-0.0062500001 0.0187500007 -0.0375000015 +-0.0062500001 0.0125000002 -0.0003910000 +-0.0062500001 0.0125000002 -0.0062500001 +-0.0062500001 0.0125000002 -0.0187500007 +-0.0062500001 0.0125000002 -0.0312500000 +-0.0062500001 0.0125000002 -0.0437499993 +-0.0062500001 0.0125000002 -0.0500000007 +-0.0062500001 0.0062500001 -0.0125000002 +-0.0062500001 0.0062500001 -0.0375000015 +-0.0062500001 -0.0000000000 0.0375000015 +-0.0062500001 -0.0000000000 0.0125000002 +-0.0062500001 -0.0062500001 0.0375000015 +-0.0062500001 -0.0062500001 0.0125000002 +-0.0062500001 -0.0062500001 -0.0125000002 +-0.0062500001 -0.0062500001 -0.0375000015 +-0.0062500001 -0.0125000002 0.0500000007 +-0.0062500001 -0.0125000002 0.0437499993 +-0.0062500001 -0.0125000002 0.0312500000 +-0.0062500001 -0.0125000002 0.0187500007 +-0.0062500001 -0.0125000002 0.0062500001 +-0.0062500001 -0.0125000002 -0.0062500001 +-0.0062500001 -0.0125000002 -0.0187500007 +-0.0062500001 -0.0125000002 -0.0312500000 +-0.0062500001 -0.0125000002 -0.0437499993 +-0.0062500001 -0.0125000002 -0.0500000007 +-0.0062500001 -0.0187500007 0.0375000015 +-0.0062500001 -0.0187500007 0.0125000002 +-0.0062500001 -0.0187500007 -0.0125000002 +-0.0062500001 -0.0187500007 -0.0375000015 +-0.0062500001 -0.0250000004 0.0375000015 +-0.0062500001 -0.0312500000 0.0125000002 +-0.0062500001 -0.0312500000 -0.0125000002 +-0.0062500001 -0.0312500000 -0.0375000015 +-0.0062500001 -0.0375000015 0.0212500002 +-0.0062500001 -0.0375000015 0.0187500007 +-0.0062500001 -0.0375000015 0.0062500001 +-0.0062500001 -0.0375000015 -0.0062500001 +-0.0062500001 -0.0375000015 -0.0187500007 +-0.0062500001 -0.0375000015 -0.0312500000 +-0.0062500001 -0.0375000015 -0.0437499993 +-0.0062500001 -0.0375000015 -0.0500000007 +-0.0062500001 -0.0437499993 0.0125000002 +-0.0062500001 -0.0437499993 -0.0125000002 +-0.0062500001 -0.0437499993 -0.0375000015 +-0.0062500001 -0.0500000007 0.0125000002 +-0.0062500001 -0.0500000007 -0.0125000002 +-0.0062500001 -0.0500000007 -0.0375000015 +-0.0062799999 0.0437199995 0.0381130017 +-0.0062799999 0.0437199995 0.0368870012 +-0.0062799999 0.0437199995 0.0131130004 +-0.0062799999 0.0437199995 0.0118869999 +-0.0062799999 0.0437199995 -0.0118869999 +-0.0062799999 0.0437199995 -0.0131130004 +-0.0062799999 0.0437199995 -0.0368870012 +-0.0062799999 0.0437199995 -0.0381130017 +-0.0062799999 0.0381130017 0.0437199995 +-0.0062799999 0.0381130017 0.0312799998 +-0.0062799999 0.0381130017 0.0187199991 +-0.0062799999 0.0381130017 0.0062799999 +-0.0062799999 0.0381130017 -0.0062799999 +-0.0062799999 0.0381130017 -0.0187199991 +-0.0062799999 0.0381130017 -0.0312799998 +-0.0062799999 0.0381130017 -0.0437199995 +-0.0062799999 0.0368870012 0.0437199995 +-0.0062799999 0.0368870012 0.0312799998 +-0.0062799999 0.0368870012 0.0187199991 +-0.0062799999 0.0368870012 0.0062799999 +-0.0062799999 0.0368870012 -0.0062799999 +-0.0062799999 0.0368870012 -0.0187199991 +-0.0062799999 0.0368870012 -0.0312799998 +-0.0062799999 0.0368870012 -0.0437199995 +-0.0062799999 0.0312799998 0.0381130017 +-0.0062799999 0.0312799998 0.0368870012 +-0.0062799999 0.0312799998 0.0131130004 +-0.0062799999 0.0312799998 0.0118869999 +-0.0062799999 0.0312799998 -0.0118869999 +-0.0062799999 0.0312799998 -0.0131130004 +-0.0062799999 0.0312799998 -0.0368870012 +-0.0062799999 0.0312799998 -0.0381130017 +-0.0062799999 0.0187199991 -0.0118869999 +-0.0062799999 0.0187199991 -0.0131130004 +-0.0062799999 0.0187199991 -0.0368870012 +-0.0062799999 0.0187199991 -0.0381130017 +-0.0062799999 0.0131130004 -0.0062799999 +-0.0062799999 0.0131130004 -0.0187199991 +-0.0062799999 0.0131130004 -0.0312799998 +-0.0062799999 0.0131130004 -0.0437199995 +-0.0062799999 0.0118869999 -0.0062799999 +-0.0062799999 0.0118869999 -0.0187199991 +-0.0062799999 0.0118869999 -0.0312799998 +-0.0062799999 0.0118869999 -0.0437199995 +-0.0062799999 0.0062799999 -0.0118869999 +-0.0062799999 0.0062799999 -0.0131130004 +-0.0062799999 0.0062799999 -0.0368870012 +-0.0062799999 0.0062799999 -0.0381130017 +-0.0062799999 -0.0062799999 0.0381130017 +-0.0062799999 -0.0062799999 0.0368870012 +-0.0062799999 -0.0062799999 0.0131130004 +-0.0062799999 -0.0062799999 0.0118869999 +-0.0062799999 -0.0062799999 -0.0118869999 +-0.0062799999 -0.0062799999 -0.0131130004 +-0.0062799999 -0.0062799999 -0.0368870012 +-0.0062799999 -0.0062799999 -0.0381130017 +-0.0062799999 -0.0118869999 0.0437199995 +-0.0062799999 -0.0118869999 0.0312799998 +-0.0062799999 -0.0118869999 0.0187199991 +-0.0062799999 -0.0118869999 0.0062799999 +-0.0062799999 -0.0118869999 -0.0062799999 +-0.0062799999 -0.0118869999 -0.0187199991 +-0.0062799999 -0.0118869999 -0.0312799998 +-0.0062799999 -0.0118869999 -0.0437199995 +-0.0062799999 -0.0131130004 0.0437199995 +-0.0062799999 -0.0131130004 0.0312799998 +-0.0062799999 -0.0131130004 0.0187199991 +-0.0062799999 -0.0131130004 0.0062799999 +-0.0062799999 -0.0131130004 -0.0062799999 +-0.0062799999 -0.0131130004 -0.0187199991 +-0.0062799999 -0.0131130004 -0.0312799998 +-0.0062799999 -0.0131130004 -0.0437199995 +-0.0062799999 -0.0187199991 0.0381130017 +-0.0062799999 -0.0187199991 0.0368870012 +-0.0062799999 -0.0187199991 0.0131130004 +-0.0062799999 -0.0187199991 0.0118869999 +-0.0062799999 -0.0187199991 -0.0118869999 +-0.0062799999 -0.0187199991 -0.0131130004 +-0.0062799999 -0.0187199991 -0.0368870012 +-0.0062799999 -0.0187199991 -0.0381130017 +-0.0062799999 -0.0312799998 0.0131130004 +-0.0062799999 -0.0312799998 0.0118869999 +-0.0062799999 -0.0312799998 -0.0118869999 +-0.0062799999 -0.0312799998 -0.0131130004 +-0.0062799999 -0.0312799998 -0.0368870012 +-0.0062799999 -0.0312799998 -0.0381130017 +-0.0062799999 -0.0368870012 0.0187199991 +-0.0062799999 -0.0368870012 0.0062799999 +-0.0062799999 -0.0368870012 -0.0062799999 +-0.0062799999 -0.0368870012 -0.0187199991 +-0.0062799999 -0.0368870012 -0.0312799998 +-0.0062799999 -0.0368870012 -0.0437199995 +-0.0062799999 -0.0381130017 0.0187199991 +-0.0062799999 -0.0381130017 0.0062799999 +-0.0062799999 -0.0381130017 -0.0062799999 +-0.0062799999 -0.0381130017 -0.0187199991 +-0.0062799999 -0.0381130017 -0.0312799998 +-0.0062799999 -0.0381130017 -0.0437199995 +-0.0062799999 -0.0437199995 0.0131130004 +-0.0062799999 -0.0437199995 0.0118869999 +-0.0062799999 -0.0437199995 -0.0118869999 +-0.0062799999 -0.0437199995 -0.0131130004 +-0.0062799999 -0.0437199995 -0.0368870012 +-0.0062799999 -0.0437199995 -0.0381130017 +-0.0063270000 0.0240870006 0.0384810008 +-0.0063270000 0.0240870006 0.0365189984 +-0.0063270000 0.0240870006 0.0134810004 +-0.0063270000 0.0240870006 0.0115189999 +-0.0063700001 0.0436300002 0.0387189984 +-0.0063700001 0.0436300002 0.0362810008 +-0.0063700001 0.0436300002 0.0137189999 +-0.0063700001 0.0436300002 0.0112810005 +-0.0063700001 0.0436300002 -0.0112810005 +-0.0063700001 0.0436300002 -0.0137189999 +-0.0063700001 0.0436300002 -0.0362810008 +-0.0063700001 0.0436300002 -0.0387189984 +-0.0063700001 0.0387189984 0.0436300002 +-0.0063700001 0.0387189984 0.0313699991 +-0.0063700001 0.0387189984 0.0186299998 +-0.0063700001 0.0387189984 0.0063700001 +-0.0063700001 0.0387189984 -0.0063700001 +-0.0063700001 0.0387189984 -0.0186299998 +-0.0063700001 0.0387189984 -0.0313699991 +-0.0063700001 0.0387189984 -0.0436300002 +-0.0063700001 0.0362810008 0.0436300002 +-0.0063700001 0.0362810008 0.0313699991 +-0.0063700001 0.0362810008 0.0186299998 +-0.0063700001 0.0362810008 0.0063700001 +-0.0063700001 0.0362810008 -0.0063700001 +-0.0063700001 0.0362810008 -0.0186299998 +-0.0063700001 0.0362810008 -0.0313699991 +-0.0063700001 0.0362810008 -0.0436300002 +-0.0063700001 0.0313699991 0.0387189984 +-0.0063700001 0.0313699991 0.0362810008 +-0.0063700001 0.0313699991 0.0137189999 +-0.0063700001 0.0313699991 0.0112810005 +-0.0063700001 0.0313699991 -0.0112810005 +-0.0063700001 0.0313699991 -0.0137189999 +-0.0063700001 0.0313699991 -0.0362810008 +-0.0063700001 0.0313699991 -0.0387189984 +-0.0063700001 0.0186299998 -0.0112810005 +-0.0063700001 0.0186299998 -0.0137189999 +-0.0063700001 0.0186299998 -0.0362810008 +-0.0063700001 0.0186299998 -0.0387189984 +-0.0063700001 0.0137189999 -0.0063700001 +-0.0063700001 0.0137189999 -0.0186299998 +-0.0063700001 0.0137189999 -0.0313699991 +-0.0063700001 0.0137189999 -0.0436300002 +-0.0063700001 0.0112810005 -0.0063700001 +-0.0063700001 0.0112810005 -0.0186299998 +-0.0063700001 0.0112810005 -0.0313699991 +-0.0063700001 0.0112810005 -0.0436300002 +-0.0063700001 0.0063700001 -0.0112810005 +-0.0063700001 0.0063700001 -0.0137189999 +-0.0063700001 0.0063700001 -0.0362810008 +-0.0063700001 0.0063700001 -0.0387189984 +-0.0063700001 -0.0063700001 0.0387189984 +-0.0063700001 -0.0063700001 0.0362810008 +-0.0063700001 -0.0063700001 0.0137189999 +-0.0063700001 -0.0063700001 0.0112810005 +-0.0063700001 -0.0063700001 -0.0112810005 +-0.0063700001 -0.0063700001 -0.0137189999 +-0.0063700001 -0.0063700001 -0.0362810008 +-0.0063700001 -0.0063700001 -0.0387189984 +-0.0063700001 -0.0112810005 0.0436300002 +-0.0063700001 -0.0112810005 0.0313699991 +-0.0063700001 -0.0112810005 0.0186299998 +-0.0063700001 -0.0112810005 0.0063700001 +-0.0063700001 -0.0112810005 -0.0063700001 +-0.0063700001 -0.0112810005 -0.0186299998 +-0.0063700001 -0.0112810005 -0.0313699991 +-0.0063700001 -0.0112810005 -0.0436300002 +-0.0063700001 -0.0137189999 0.0436300002 +-0.0063700001 -0.0137189999 0.0313699991 +-0.0063700001 -0.0137189999 0.0186299998 +-0.0063700001 -0.0137189999 0.0063700001 +-0.0063700001 -0.0137189999 -0.0063700001 +-0.0063700001 -0.0137189999 -0.0186299998 +-0.0063700001 -0.0137189999 -0.0313699991 +-0.0063700001 -0.0137189999 -0.0436300002 +-0.0063700001 -0.0186299998 0.0387189984 +-0.0063700001 -0.0186299998 0.0362810008 +-0.0063700001 -0.0186299998 0.0137189999 +-0.0063700001 -0.0186299998 0.0112810005 +-0.0063700001 -0.0186299998 -0.0112810005 +-0.0063700001 -0.0186299998 -0.0137189999 +-0.0063700001 -0.0186299998 -0.0362810008 +-0.0063700001 -0.0186299998 -0.0387189984 +-0.0063700001 -0.0313699991 0.0137189999 +-0.0063700001 -0.0313699991 0.0112810005 +-0.0063700001 -0.0313699991 -0.0112810005 +-0.0063700001 -0.0313699991 -0.0137189999 +-0.0063700001 -0.0313699991 -0.0362810008 +-0.0063700001 -0.0313699991 -0.0387189984 +-0.0063700001 -0.0362810008 0.0186299998 +-0.0063700001 -0.0362810008 0.0063700001 +-0.0063700001 -0.0362810008 -0.0063700001 +-0.0063700001 -0.0362810008 -0.0186299998 +-0.0063700001 -0.0362810008 -0.0313699991 +-0.0063700001 -0.0362810008 -0.0436300002 +-0.0063700001 -0.0387189984 0.0186299998 +-0.0063700001 -0.0387189984 0.0063700001 +-0.0063700001 -0.0387189984 -0.0063700001 +-0.0063700001 -0.0387189984 -0.0186299998 +-0.0063700001 -0.0387189984 -0.0313699991 +-0.0063700001 -0.0387189984 -0.0436300002 +-0.0063700001 -0.0436300002 0.0137189999 +-0.0063700001 -0.0436300002 0.0112810005 +-0.0063700001 -0.0436300002 -0.0112810005 +-0.0063700001 -0.0436300002 -0.0137189999 +-0.0063700001 -0.0436300002 -0.0362810008 +-0.0063700001 -0.0436300002 -0.0387189984 +-0.0064630001 0.0500000007 0.0391179994 +-0.0064630001 0.0500000007 0.0358819999 +-0.0064630001 0.0500000007 0.0141179999 +-0.0064630001 0.0500000007 0.0108820004 +-0.0064630001 0.0500000007 -0.0108820004 +-0.0064630001 0.0500000007 -0.0141179999 +-0.0064630001 0.0500000007 -0.0358819999 +-0.0064630001 0.0500000007 -0.0391179994 +-0.0064630001 0.0391179994 0.0500000007 +-0.0064630001 0.0391179994 -0.0500000007 +-0.0064630001 0.0358819999 0.0500000007 +-0.0064630001 0.0358819999 -0.0500000007 +-0.0064630001 0.0141179999 -0.0003910000 +-0.0064630001 0.0141179999 -0.0500000007 +-0.0064630001 0.0108820004 -0.0003910000 +-0.0064630001 0.0108820004 -0.0500000007 +-0.0064630001 -0.0000000000 0.0391179994 +-0.0064630001 -0.0000000000 0.0358819999 +-0.0064630001 -0.0000000000 0.0141179999 +-0.0064630001 -0.0000000000 0.0108820004 +-0.0064630001 -0.0108820004 0.0500000007 +-0.0064630001 -0.0108820004 -0.0500000007 +-0.0064630001 -0.0141179999 0.0500000007 +-0.0064630001 -0.0141179999 -0.0500000007 +-0.0064630001 -0.0250000004 0.0391179994 +-0.0064630001 -0.0250000004 0.0358819999 +-0.0064630001 -0.0358819999 0.0212500002 +-0.0064630001 -0.0358819999 -0.0500000007 +-0.0064630001 -0.0391179994 0.0212500002 +-0.0064630001 -0.0391179994 -0.0500000007 +-0.0064630001 -0.0500000007 0.0141179999 +-0.0064630001 -0.0500000007 0.0108820004 +-0.0064630001 -0.0500000007 -0.0108820004 +-0.0064630001 -0.0500000007 -0.0141179999 +-0.0064630001 -0.0500000007 -0.0358819999 +-0.0064630001 -0.0500000007 -0.0391179994 +-0.0065580001 0.0239540003 0.0394380018 +-0.0065580001 0.0239540003 0.0355620012 +-0.0065580001 0.0239540003 0.0144379996 +-0.0065580001 0.0239540003 0.0105619999 +-0.0067260000 0.0432740003 0.0398919992 +-0.0067260000 0.0432740003 0.0351080000 +-0.0067260000 0.0432740003 0.0148919998 +-0.0067260000 0.0432740003 0.0101079997 +-0.0067260000 0.0432740003 -0.0101079997 +-0.0067260000 0.0432740003 -0.0148919998 +-0.0067260000 0.0432740003 -0.0351080000 +-0.0067260000 0.0432740003 -0.0398919992 +-0.0067260000 0.0398919992 0.0432740003 +-0.0067260000 0.0398919992 0.0317259990 +-0.0067260000 0.0398919992 0.0182739999 +-0.0067260000 0.0398919992 0.0067260000 +-0.0067260000 0.0398919992 -0.0067260000 +-0.0067260000 0.0398919992 -0.0182739999 +-0.0067260000 0.0398919992 -0.0317259990 +-0.0067260000 0.0398919992 -0.0432740003 +-0.0067260000 0.0351080000 0.0432740003 +-0.0067260000 0.0351080000 0.0317259990 +-0.0067260000 0.0351080000 0.0182739999 +-0.0067260000 0.0351080000 0.0067260000 +-0.0067260000 0.0351080000 -0.0067260000 +-0.0067260000 0.0351080000 -0.0182739999 +-0.0067260000 0.0351080000 -0.0317259990 +-0.0067260000 0.0351080000 -0.0432740003 +-0.0067260000 0.0317259990 0.0398919992 +-0.0067260000 0.0317259990 0.0351080000 +-0.0067260000 0.0317259990 0.0148919998 +-0.0067260000 0.0317259990 0.0101079997 +-0.0067260000 0.0317259990 -0.0101079997 +-0.0067260000 0.0317259990 -0.0148919998 +-0.0067260000 0.0317259990 -0.0351080000 +-0.0067260000 0.0317259990 -0.0398919992 +-0.0067260000 0.0182739999 -0.0101079997 +-0.0067260000 0.0182739999 -0.0148919998 +-0.0067260000 0.0182739999 -0.0351080000 +-0.0067260000 0.0182739999 -0.0398919992 +-0.0067260000 0.0148919998 -0.0067260000 +-0.0067260000 0.0148919998 -0.0182739999 +-0.0067260000 0.0148919998 -0.0317259990 +-0.0067260000 0.0148919998 -0.0432740003 +-0.0067260000 0.0101079997 -0.0067260000 +-0.0067260000 0.0101079997 -0.0182739999 +-0.0067260000 0.0101079997 -0.0317259990 +-0.0067260000 0.0101079997 -0.0432740003 +-0.0067260000 0.0067260000 -0.0101079997 +-0.0067260000 0.0067260000 -0.0148919998 +-0.0067260000 0.0067260000 -0.0351080000 +-0.0067260000 0.0067260000 -0.0398919992 +-0.0067260000 -0.0067260000 0.0398919992 +-0.0067260000 -0.0067260000 0.0351080000 +-0.0067260000 -0.0067260000 0.0148919998 +-0.0067260000 -0.0067260000 0.0101079997 +-0.0067260000 -0.0067260000 -0.0101079997 +-0.0067260000 -0.0067260000 -0.0148919998 +-0.0067260000 -0.0067260000 -0.0351080000 +-0.0067260000 -0.0067260000 -0.0398919992 +-0.0067260000 -0.0101079997 0.0432740003 +-0.0067260000 -0.0101079997 0.0317259990 +-0.0067260000 -0.0101079997 0.0182739999 +-0.0067260000 -0.0101079997 0.0067260000 +-0.0067260000 -0.0101079997 -0.0067260000 +-0.0067260000 -0.0101079997 -0.0182739999 +-0.0067260000 -0.0101079997 -0.0317259990 +-0.0067260000 -0.0101079997 -0.0432740003 +-0.0067260000 -0.0148919998 0.0432740003 +-0.0067260000 -0.0148919998 0.0317259990 +-0.0067260000 -0.0148919998 0.0182739999 +-0.0067260000 -0.0148919998 0.0067260000 +-0.0067260000 -0.0148919998 -0.0067260000 +-0.0067260000 -0.0148919998 -0.0182739999 +-0.0067260000 -0.0148919998 -0.0317259990 +-0.0067260000 -0.0148919998 -0.0432740003 +-0.0067260000 -0.0182739999 0.0398919992 +-0.0067260000 -0.0182739999 0.0351080000 +-0.0067260000 -0.0182739999 0.0148919998 +-0.0067260000 -0.0182739999 0.0101079997 +-0.0067260000 -0.0182739999 -0.0101079997 +-0.0067260000 -0.0182739999 -0.0148919998 +-0.0067260000 -0.0182739999 -0.0351080000 +-0.0067260000 -0.0182739999 -0.0398919992 +-0.0067260000 -0.0317259990 0.0148919998 +-0.0067260000 -0.0317259990 0.0101079997 +-0.0067260000 -0.0317259990 -0.0101079997 +-0.0067260000 -0.0317259990 -0.0148919998 +-0.0067260000 -0.0317259990 -0.0351080000 +-0.0067260000 -0.0317259990 -0.0398919992 +-0.0067260000 -0.0351080000 0.0182739999 +-0.0067260000 -0.0351080000 0.0067260000 +-0.0067260000 -0.0351080000 -0.0067260000 +-0.0067260000 -0.0351080000 -0.0182739999 +-0.0067260000 -0.0351080000 -0.0317259990 +-0.0067260000 -0.0351080000 -0.0432740003 +-0.0067260000 -0.0398919992 0.0182739999 +-0.0067260000 -0.0398919992 0.0067260000 +-0.0067260000 -0.0398919992 -0.0067260000 +-0.0067260000 -0.0398919992 -0.0182739999 +-0.0067260000 -0.0398919992 -0.0317259990 +-0.0067260000 -0.0398919992 -0.0432740003 +-0.0067260000 -0.0432740003 0.0148919998 +-0.0067260000 -0.0432740003 0.0101079997 +-0.0067260000 -0.0432740003 -0.0101079997 +-0.0067260000 -0.0432740003 -0.0148919998 +-0.0067260000 -0.0432740003 -0.0351080000 +-0.0067260000 -0.0432740003 -0.0398919992 +-0.0069360002 0.0237349998 0.0403469987 +-0.0069360002 0.0237349998 0.0346530005 +-0.0069360002 0.0237349998 0.0153470002 +-0.0069360002 0.0237349998 0.0096530002 +-0.0070870002 0.0500000007 0.0406249985 +-0.0070870002 0.0500000007 0.0343750007 +-0.0070870002 0.0500000007 0.0156250000 +-0.0070870002 0.0500000007 0.0093750004 +-0.0070870002 0.0500000007 -0.0093750004 +-0.0070870002 0.0500000007 -0.0156250000 +-0.0070870002 0.0500000007 -0.0343750007 +-0.0070870002 0.0500000007 -0.0406249985 +-0.0070870002 0.0406249985 0.0500000007 +-0.0070870002 0.0406249985 -0.0500000007 +-0.0070870002 0.0343750007 0.0500000007 +-0.0070870002 0.0343750007 -0.0500000007 +-0.0070870002 0.0156250000 -0.0003910000 +-0.0070870002 0.0156250000 -0.0500000007 +-0.0070870002 0.0093750004 -0.0003910000 +-0.0070870002 0.0093750004 -0.0500000007 +-0.0070870002 -0.0000000000 0.0406249985 +-0.0070870002 -0.0000000000 0.0343750007 +-0.0070870002 -0.0000000000 0.0156250000 +-0.0070870002 -0.0000000000 0.0093750004 +-0.0070870002 -0.0093750004 0.0500000007 +-0.0070870002 -0.0093750004 -0.0500000007 +-0.0070870002 -0.0156250000 0.0500000007 +-0.0070870002 -0.0156250000 -0.0500000007 +-0.0070870002 -0.0250000004 0.0406249985 +-0.0070870002 -0.0250000004 0.0343750007 +-0.0070870002 -0.0343750007 0.0212500002 +-0.0070870002 -0.0343750007 -0.0500000007 +-0.0070870002 -0.0406249985 0.0212500002 +-0.0070870002 -0.0406249985 -0.0500000007 +-0.0070870002 -0.0500000007 0.0156250000 +-0.0070870002 -0.0500000007 0.0093750004 +-0.0070870002 -0.0500000007 -0.0093750004 +-0.0070870002 -0.0500000007 -0.0156250000 +-0.0070870002 -0.0500000007 -0.0343750007 +-0.0070870002 -0.0500000007 -0.0406249985 +-0.0073030000 0.0426970012 0.0409720019 +-0.0073030000 0.0426970012 0.0340280011 +-0.0073030000 0.0426970012 0.0159719996 +-0.0073030000 0.0426970012 0.0090279998 +-0.0073030000 0.0426970012 -0.0090279998 +-0.0073030000 0.0426970012 -0.0159719996 +-0.0073030000 0.0426970012 -0.0340280011 +-0.0073030000 0.0426970012 -0.0409720019 +-0.0073030000 0.0409720019 0.0426970012 +-0.0073030000 0.0409720019 0.0323030017 +-0.0073030000 0.0409720019 0.0176970009 +-0.0073030000 0.0409720019 0.0073030000 +-0.0073030000 0.0409720019 -0.0073030000 +-0.0073030000 0.0409720019 -0.0176970009 +-0.0073030000 0.0409720019 -0.0323030017 +-0.0073030000 0.0409720019 -0.0426970012 +-0.0073030000 0.0340280011 0.0426970012 +-0.0073030000 0.0340280011 0.0323030017 +-0.0073030000 0.0340280011 0.0176970009 +-0.0073030000 0.0340280011 0.0073030000 +-0.0073030000 0.0340280011 -0.0073030000 +-0.0073030000 0.0340280011 -0.0176970009 +-0.0073030000 0.0340280011 -0.0323030017 +-0.0073030000 0.0340280011 -0.0426970012 +-0.0073030000 0.0323030017 0.0409720019 +-0.0073030000 0.0323030017 0.0340280011 +-0.0073030000 0.0323030017 0.0159719996 +-0.0073030000 0.0323030017 0.0090279998 +-0.0073030000 0.0323030017 -0.0090279998 +-0.0073030000 0.0323030017 -0.0159719996 +-0.0073030000 0.0323030017 -0.0340280011 +-0.0073030000 0.0323030017 -0.0409720019 +-0.0073030000 0.0176970009 -0.0090279998 +-0.0073030000 0.0176970009 -0.0159719996 +-0.0073030000 0.0176970009 -0.0340280011 +-0.0073030000 0.0176970009 -0.0409720019 +-0.0073030000 0.0159719996 -0.0073030000 +-0.0073030000 0.0159719996 -0.0176970009 +-0.0073030000 0.0159719996 -0.0323030017 +-0.0073030000 0.0159719996 -0.0426970012 +-0.0073030000 0.0090279998 -0.0073030000 +-0.0073030000 0.0090279998 -0.0176970009 +-0.0073030000 0.0090279998 -0.0323030017 +-0.0073030000 0.0090279998 -0.0426970012 +-0.0073030000 0.0073030000 -0.0090279998 +-0.0073030000 0.0073030000 -0.0159719996 +-0.0073030000 0.0073030000 -0.0340280011 +-0.0073030000 0.0073030000 -0.0409720019 +-0.0073030000 -0.0073030000 0.0409720019 +-0.0073030000 -0.0073030000 0.0340280011 +-0.0073030000 -0.0073030000 0.0159719996 +-0.0073030000 -0.0073030000 0.0090279998 +-0.0073030000 -0.0073030000 -0.0090279998 +-0.0073030000 -0.0073030000 -0.0159719996 +-0.0073030000 -0.0073030000 -0.0340280011 +-0.0073030000 -0.0073030000 -0.0409720019 +-0.0073030000 -0.0090279998 0.0426970012 +-0.0073030000 -0.0090279998 0.0323030017 +-0.0073030000 -0.0090279998 0.0176970009 +-0.0073030000 -0.0090279998 0.0073030000 +-0.0073030000 -0.0090279998 -0.0073030000 +-0.0073030000 -0.0090279998 -0.0176970009 +-0.0073030000 -0.0090279998 -0.0323030017 +-0.0073030000 -0.0090279998 -0.0426970012 +-0.0073030000 -0.0159719996 0.0426970012 +-0.0073030000 -0.0159719996 0.0323030017 +-0.0073030000 -0.0159719996 0.0176970009 +-0.0073030000 -0.0159719996 0.0073030000 +-0.0073030000 -0.0159719996 -0.0073030000 +-0.0073030000 -0.0159719996 -0.0176970009 +-0.0073030000 -0.0159719996 -0.0323030017 +-0.0073030000 -0.0159719996 -0.0426970012 +-0.0073030000 -0.0176970009 0.0409720019 +-0.0073030000 -0.0176970009 0.0340280011 +-0.0073030000 -0.0176970009 0.0159719996 +-0.0073030000 -0.0176970009 0.0090279998 +-0.0073030000 -0.0176970009 -0.0090279998 +-0.0073030000 -0.0176970009 -0.0159719996 +-0.0073030000 -0.0176970009 -0.0340280011 +-0.0073030000 -0.0176970009 -0.0409720019 +-0.0073030000 -0.0323030017 0.0159719996 +-0.0073030000 -0.0323030017 0.0090279998 +-0.0073030000 -0.0323030017 -0.0090279998 +-0.0073030000 -0.0323030017 -0.0159719996 +-0.0073030000 -0.0323030017 -0.0340280011 +-0.0073030000 -0.0323030017 -0.0409720019 +-0.0073030000 -0.0340280011 0.0176970009 +-0.0073030000 -0.0340280011 0.0073030000 +-0.0073030000 -0.0340280011 -0.0073030000 +-0.0073030000 -0.0340280011 -0.0176970009 +-0.0073030000 -0.0340280011 -0.0323030017 +-0.0073030000 -0.0340280011 -0.0426970012 +-0.0073030000 -0.0409720019 0.0176970009 +-0.0073030000 -0.0409720019 0.0073030000 +-0.0073030000 -0.0409720019 -0.0073030000 +-0.0073030000 -0.0409720019 -0.0176970009 +-0.0073030000 -0.0409720019 -0.0323030017 +-0.0073030000 -0.0409720019 -0.0426970012 +-0.0073030000 -0.0426970012 0.0159719996 +-0.0073030000 -0.0426970012 0.0090279998 +-0.0073030000 -0.0426970012 -0.0090279998 +-0.0073030000 -0.0426970012 -0.0159719996 +-0.0073030000 -0.0426970012 -0.0340280011 +-0.0073030000 -0.0426970012 -0.0409720019 +-0.0074519999 0.0234379992 0.0500000007 +-0.0074519999 0.0234379992 0.0411849990 +-0.0074519999 0.0234379992 0.0338150002 +-0.0074519999 0.0234379992 0.0161850005 +-0.0074519999 0.0234379992 0.0088149998 +-0.0074519999 0.0234379992 -0.0003910000 +-0.0080810003 0.0500000007 0.0419190004 +-0.0080810003 0.0500000007 0.0330809988 +-0.0080810003 0.0500000007 0.0169190001 +-0.0080810003 0.0500000007 0.0080810003 +-0.0080810003 0.0500000007 -0.0080810003 +-0.0080810003 0.0500000007 -0.0169190001 +-0.0080810003 0.0500000007 -0.0330809988 +-0.0080810003 0.0500000007 -0.0419190004 +-0.0080810003 0.0419190004 0.0500000007 +-0.0080810003 0.0419190004 0.0419190004 +-0.0080810003 0.0419190004 0.0330809988 +-0.0080810003 0.0419190004 0.0169190001 +-0.0080810003 0.0419190004 0.0080810003 +-0.0080810003 0.0419190004 -0.0080810003 +-0.0080810003 0.0419190004 -0.0169190001 +-0.0080810003 0.0419190004 -0.0330809988 +-0.0080810003 0.0419190004 -0.0419190004 +-0.0080810003 0.0419190004 -0.0500000007 +-0.0080810003 0.0330809988 0.0500000007 +-0.0080810003 0.0330809988 0.0419190004 +-0.0080810003 0.0330809988 0.0330809988 +-0.0080810003 0.0330809988 0.0169190001 +-0.0080810003 0.0330809988 0.0080810003 +-0.0080810003 0.0330809988 -0.0080810003 +-0.0080810003 0.0330809988 -0.0169190001 +-0.0080810003 0.0330809988 -0.0330809988 +-0.0080810003 0.0330809988 -0.0419190004 +-0.0080810003 0.0330809988 -0.0500000007 +-0.0080810003 0.0169190001 -0.0003910000 +-0.0080810003 0.0169190001 -0.0080810003 +-0.0080810003 0.0169190001 -0.0169190001 +-0.0080810003 0.0169190001 -0.0330809988 +-0.0080810003 0.0169190001 -0.0419190004 +-0.0080810003 0.0169190001 -0.0500000007 +-0.0080810003 0.0080810003 -0.0003910000 +-0.0080810003 0.0080810003 -0.0080810003 +-0.0080810003 0.0080810003 -0.0169190001 +-0.0080810003 0.0080810003 -0.0330809988 +-0.0080810003 0.0080810003 -0.0419190004 +-0.0080810003 0.0080810003 -0.0500000007 +-0.0080810003 -0.0000000000 0.0419190004 +-0.0080810003 -0.0000000000 0.0330809988 +-0.0080810003 -0.0000000000 0.0169190001 +-0.0080810003 -0.0000000000 0.0080810003 +-0.0080810003 -0.0080810003 0.0500000007 +-0.0080810003 -0.0080810003 0.0419190004 +-0.0080810003 -0.0080810003 0.0330809988 +-0.0080810003 -0.0080810003 0.0169190001 +-0.0080810003 -0.0080810003 0.0080810003 +-0.0080810003 -0.0080810003 -0.0080810003 +-0.0080810003 -0.0080810003 -0.0169190001 +-0.0080810003 -0.0080810003 -0.0330809988 +-0.0080810003 -0.0080810003 -0.0419190004 +-0.0080810003 -0.0080810003 -0.0500000007 +-0.0080810003 -0.0169190001 0.0500000007 +-0.0080810003 -0.0169190001 0.0419190004 +-0.0080810003 -0.0169190001 0.0330809988 +-0.0080810003 -0.0169190001 0.0169190001 +-0.0080810003 -0.0169190001 0.0080810003 +-0.0080810003 -0.0169190001 -0.0080810003 +-0.0080810003 -0.0169190001 -0.0169190001 +-0.0080810003 -0.0169190001 -0.0330809988 +-0.0080810003 -0.0169190001 -0.0419190004 +-0.0080810003 -0.0169190001 -0.0500000007 +-0.0080810003 -0.0250000004 0.0419190004 +-0.0080810003 -0.0250000004 0.0330809988 +-0.0080810003 -0.0330809988 0.0212500002 +-0.0080810003 -0.0330809988 0.0169190001 +-0.0080810003 -0.0330809988 0.0080810003 +-0.0080810003 -0.0330809988 -0.0080810003 +-0.0080810003 -0.0330809988 -0.0169190001 +-0.0080810003 -0.0330809988 -0.0330809988 +-0.0080810003 -0.0330809988 -0.0419190004 +-0.0080810003 -0.0330809988 -0.0500000007 +-0.0080810003 -0.0419190004 0.0212500002 +-0.0080810003 -0.0419190004 0.0169190001 +-0.0080810003 -0.0419190004 0.0080810003 +-0.0080810003 -0.0419190004 -0.0080810003 +-0.0080810003 -0.0419190004 -0.0169190001 +-0.0080810003 -0.0419190004 -0.0330809988 +-0.0080810003 -0.0419190004 -0.0419190004 +-0.0080810003 -0.0419190004 -0.0500000007 +-0.0080810003 -0.0500000007 0.0169190001 +-0.0080810003 -0.0500000007 0.0080810003 +-0.0080810003 -0.0500000007 -0.0080810003 +-0.0080810003 -0.0500000007 -0.0169190001 +-0.0080810003 -0.0500000007 -0.0330809988 +-0.0080810003 -0.0500000007 -0.0419190004 +-0.0085260002 0.0234379992 0.0423239991 +-0.0085260002 0.0234379992 0.0326760001 +-0.0085260002 0.0234379992 0.0173240006 +-0.0085260002 0.0234379992 0.0076759998 +-0.0090279998 0.0426970012 0.0426970012 +-0.0090279998 0.0426970012 0.0323030017 +-0.0090279998 0.0426970012 0.0176970009 +-0.0090279998 0.0426970012 0.0073030000 +-0.0090279998 0.0426970012 -0.0073030000 +-0.0090279998 0.0426970012 -0.0176970009 +-0.0090279998 0.0426970012 -0.0323030017 +-0.0090279998 0.0426970012 -0.0426970012 +-0.0090279998 0.0323030017 0.0426970012 +-0.0090279998 0.0323030017 0.0323030017 +-0.0090279998 0.0323030017 0.0176970009 +-0.0090279998 0.0323030017 0.0073030000 +-0.0090279998 0.0323030017 -0.0073030000 +-0.0090279998 0.0323030017 -0.0176970009 +-0.0090279998 0.0323030017 -0.0323030017 +-0.0090279998 0.0323030017 -0.0426970012 +-0.0090279998 0.0176970009 -0.0073030000 +-0.0090279998 0.0176970009 -0.0176970009 +-0.0090279998 0.0176970009 -0.0323030017 +-0.0090279998 0.0176970009 -0.0426970012 +-0.0090279998 0.0073030000 -0.0073030000 +-0.0090279998 0.0073030000 -0.0176970009 +-0.0090279998 0.0073030000 -0.0323030017 +-0.0090279998 0.0073030000 -0.0426970012 +-0.0090279998 -0.0073030000 0.0426970012 +-0.0090279998 -0.0073030000 0.0323030017 +-0.0090279998 -0.0073030000 0.0176970009 +-0.0090279998 -0.0073030000 0.0073030000 +-0.0090279998 -0.0073030000 -0.0073030000 +-0.0090279998 -0.0073030000 -0.0176970009 +-0.0090279998 -0.0073030000 -0.0323030017 +-0.0090279998 -0.0073030000 -0.0426970012 +-0.0090279998 -0.0176970009 0.0426970012 +-0.0090279998 -0.0176970009 0.0323030017 +-0.0090279998 -0.0176970009 0.0176970009 +-0.0090279998 -0.0176970009 0.0073030000 +-0.0090279998 -0.0176970009 -0.0073030000 +-0.0090279998 -0.0176970009 -0.0176970009 +-0.0090279998 -0.0176970009 -0.0323030017 +-0.0090279998 -0.0176970009 -0.0426970012 +-0.0090279998 -0.0323030017 0.0176970009 +-0.0090279998 -0.0323030017 0.0073030000 +-0.0090279998 -0.0323030017 -0.0073030000 +-0.0090279998 -0.0323030017 -0.0176970009 +-0.0090279998 -0.0323030017 -0.0323030017 +-0.0090279998 -0.0323030017 -0.0426970012 +-0.0090279998 -0.0426970012 0.0176970009 +-0.0090279998 -0.0426970012 0.0073030000 +-0.0090279998 -0.0426970012 -0.0073030000 +-0.0090279998 -0.0426970012 -0.0176970009 +-0.0090279998 -0.0426970012 -0.0323030017 +-0.0090279998 -0.0426970012 -0.0426970012 +-0.0093750004 0.0500000007 0.0429130010 +-0.0093750004 0.0500000007 0.0320869982 +-0.0093750004 0.0500000007 0.0179130007 +-0.0093750004 0.0500000007 0.0070870002 +-0.0093750004 0.0500000007 -0.0070870002 +-0.0093750004 0.0500000007 -0.0179130007 +-0.0093750004 0.0500000007 -0.0320869982 +-0.0093750004 0.0500000007 -0.0429130010 +-0.0093750004 0.0429130010 0.0500000007 +-0.0093750004 0.0429130010 -0.0500000007 +-0.0093750004 0.0320869982 0.0500000007 +-0.0093750004 0.0320869982 -0.0500000007 +-0.0093750004 0.0179130007 -0.0003910000 +-0.0093750004 0.0179130007 -0.0500000007 +-0.0093750004 0.0070870002 -0.0003910000 +-0.0093750004 0.0070870002 -0.0500000007 +-0.0093750004 -0.0000000000 0.0429130010 +-0.0093750004 -0.0000000000 0.0320869982 +-0.0093750004 -0.0000000000 0.0179130007 +-0.0093750004 -0.0000000000 0.0070870002 +-0.0093750004 -0.0070870002 0.0500000007 +-0.0093750004 -0.0070870002 -0.0500000007 +-0.0093750004 -0.0179130007 0.0500000007 +-0.0093750004 -0.0179130007 -0.0500000007 +-0.0093750004 -0.0250000004 0.0429130010 +-0.0093750004 -0.0250000004 0.0320869982 +-0.0093750004 -0.0320869982 0.0212500002 +-0.0093750004 -0.0320869982 -0.0500000007 +-0.0093750004 -0.0429130010 0.0212500002 +-0.0093750004 -0.0429130010 -0.0500000007 +-0.0093750004 -0.0500000007 0.0179130007 +-0.0093750004 -0.0500000007 0.0070870002 +-0.0093750004 -0.0500000007 -0.0070870002 +-0.0093750004 -0.0500000007 -0.0179130007 +-0.0093750004 -0.0500000007 -0.0320869982 +-0.0093750004 -0.0500000007 -0.0429130010 +-0.0098489998 0.0234379992 0.0431599990 +-0.0098489998 0.0234379992 0.0318400003 +-0.0098489998 0.0234379992 0.0181600004 +-0.0098489998 0.0234379992 0.0068399999 +-0.0101079997 0.0432740003 0.0432740003 +-0.0101079997 0.0432740003 0.0317259990 +-0.0101079997 0.0432740003 0.0182739999 +-0.0101079997 0.0432740003 0.0067260000 +-0.0101079997 0.0432740003 -0.0067260000 +-0.0101079997 0.0432740003 -0.0182739999 +-0.0101079997 0.0432740003 -0.0317259990 +-0.0101079997 0.0432740003 -0.0432740003 +-0.0101079997 0.0317259990 0.0432740003 +-0.0101079997 0.0317259990 0.0317259990 +-0.0101079997 0.0317259990 0.0182739999 +-0.0101079997 0.0317259990 0.0067260000 +-0.0101079997 0.0317259990 -0.0067260000 +-0.0101079997 0.0317259990 -0.0182739999 +-0.0101079997 0.0317259990 -0.0317259990 +-0.0101079997 0.0317259990 -0.0432740003 +-0.0101079997 0.0182739999 -0.0067260000 +-0.0101079997 0.0182739999 -0.0182739999 +-0.0101079997 0.0182739999 -0.0317259990 +-0.0101079997 0.0182739999 -0.0432740003 +-0.0101079997 0.0067260000 -0.0067260000 +-0.0101079997 0.0067260000 -0.0182739999 +-0.0101079997 0.0067260000 -0.0317259990 +-0.0101079997 0.0067260000 -0.0432740003 +-0.0101079997 -0.0067260000 0.0432740003 +-0.0101079997 -0.0067260000 0.0317259990 +-0.0101079997 -0.0067260000 0.0182739999 +-0.0101079997 -0.0067260000 0.0067260000 +-0.0101079997 -0.0067260000 -0.0067260000 +-0.0101079997 -0.0067260000 -0.0182739999 +-0.0101079997 -0.0067260000 -0.0317259990 +-0.0101079997 -0.0067260000 -0.0432740003 +-0.0101079997 -0.0182739999 0.0432740003 +-0.0101079997 -0.0182739999 0.0317259990 +-0.0101079997 -0.0182739999 0.0182739999 +-0.0101079997 -0.0182739999 0.0067260000 +-0.0101079997 -0.0182739999 -0.0067260000 +-0.0101079997 -0.0182739999 -0.0182739999 +-0.0101079997 -0.0182739999 -0.0317259990 +-0.0101079997 -0.0182739999 -0.0432740003 +-0.0101079997 -0.0317259990 0.0182739999 +-0.0101079997 -0.0317259990 0.0067260000 +-0.0101079997 -0.0317259990 -0.0067260000 +-0.0101079997 -0.0317259990 -0.0182739999 +-0.0101079997 -0.0317259990 -0.0317259990 +-0.0101079997 -0.0317259990 -0.0432740003 +-0.0101079997 -0.0432740003 0.0182739999 +-0.0101079997 -0.0432740003 0.0067260000 +-0.0101079997 -0.0432740003 -0.0067260000 +-0.0101079997 -0.0432740003 -0.0182739999 +-0.0101079997 -0.0432740003 -0.0317259990 +-0.0101079997 -0.0432740003 -0.0432740003 +-0.0108820004 0.0500000007 0.0435369983 +-0.0108820004 0.0500000007 0.0314630009 +-0.0108820004 0.0500000007 0.0185369998 +-0.0108820004 0.0500000007 0.0064630001 +-0.0108820004 0.0500000007 -0.0064630001 +-0.0108820004 0.0500000007 -0.0185369998 +-0.0108820004 0.0500000007 -0.0314630009 +-0.0108820004 0.0500000007 -0.0435369983 +-0.0108820004 0.0435369983 0.0500000007 +-0.0108820004 0.0435369983 -0.0500000007 +-0.0108820004 0.0314630009 0.0500000007 +-0.0108820004 0.0314630009 -0.0500000007 +-0.0108820004 0.0185369998 -0.0003910000 +-0.0108820004 0.0185369998 -0.0500000007 +-0.0108820004 0.0064630001 -0.0003910000 +-0.0108820004 0.0064630001 -0.0500000007 +-0.0108820004 -0.0000000000 0.0435369983 +-0.0108820004 -0.0000000000 0.0314630009 +-0.0108820004 -0.0000000000 0.0185369998 +-0.0108820004 -0.0000000000 0.0064630001 +-0.0108820004 -0.0064630001 0.0500000007 +-0.0108820004 -0.0064630001 -0.0500000007 +-0.0108820004 -0.0185369998 0.0500000007 +-0.0108820004 -0.0185369998 -0.0500000007 +-0.0108820004 -0.0250000004 0.0435369983 +-0.0108820004 -0.0250000004 0.0314630009 +-0.0108820004 -0.0314630009 0.0212500002 +-0.0108820004 -0.0314630009 -0.0500000007 +-0.0108820004 -0.0435369983 0.0212500002 +-0.0108820004 -0.0435369983 -0.0500000007 +-0.0108820004 -0.0500000007 0.0185369998 +-0.0108820004 -0.0500000007 0.0064630001 +-0.0108820004 -0.0500000007 -0.0064630001 +-0.0108820004 -0.0500000007 -0.0185369998 +-0.0108820004 -0.0500000007 -0.0314630009 +-0.0108820004 -0.0500000007 -0.0435369983 +-0.0112810005 0.0436300002 0.0436300002 +-0.0112810005 0.0436300002 0.0313699991 +-0.0112810005 0.0436300002 0.0186299998 +-0.0112810005 0.0436300002 0.0063700001 +-0.0112810005 0.0436300002 -0.0063700001 +-0.0112810005 0.0436300002 -0.0186299998 +-0.0112810005 0.0436300002 -0.0313699991 +-0.0112810005 0.0436300002 -0.0436300002 +-0.0112810005 0.0313699991 0.0436300002 +-0.0112810005 0.0313699991 0.0313699991 +-0.0112810005 0.0313699991 0.0186299998 +-0.0112810005 0.0313699991 0.0063700001 +-0.0112810005 0.0313699991 -0.0063700001 +-0.0112810005 0.0313699991 -0.0186299998 +-0.0112810005 0.0313699991 -0.0313699991 +-0.0112810005 0.0313699991 -0.0436300002 +-0.0112810005 0.0186299998 -0.0063700001 +-0.0112810005 0.0186299998 -0.0186299998 +-0.0112810005 0.0186299998 -0.0313699991 +-0.0112810005 0.0186299998 -0.0436300002 +-0.0112810005 0.0063700001 -0.0063700001 +-0.0112810005 0.0063700001 -0.0186299998 +-0.0112810005 0.0063700001 -0.0313699991 +-0.0112810005 0.0063700001 -0.0436300002 +-0.0112810005 -0.0063700001 0.0436300002 +-0.0112810005 -0.0063700001 0.0313699991 +-0.0112810005 -0.0063700001 0.0186299998 +-0.0112810005 -0.0063700001 0.0063700001 +-0.0112810005 -0.0063700001 -0.0063700001 +-0.0112810005 -0.0063700001 -0.0186299998 +-0.0112810005 -0.0063700001 -0.0313699991 +-0.0112810005 -0.0063700001 -0.0436300002 +-0.0112810005 -0.0186299998 0.0436300002 +-0.0112810005 -0.0186299998 0.0313699991 +-0.0112810005 -0.0186299998 0.0186299998 +-0.0112810005 -0.0186299998 0.0063700001 +-0.0112810005 -0.0186299998 -0.0063700001 +-0.0112810005 -0.0186299998 -0.0186299998 +-0.0112810005 -0.0186299998 -0.0313699991 +-0.0112810005 -0.0186299998 -0.0436300002 +-0.0112810005 -0.0313699991 0.0186299998 +-0.0112810005 -0.0313699991 0.0063700001 +-0.0112810005 -0.0313699991 -0.0063700001 +-0.0112810005 -0.0313699991 -0.0186299998 +-0.0112810005 -0.0313699991 -0.0313699991 +-0.0112810005 -0.0313699991 -0.0436300002 +-0.0112810005 -0.0436300002 0.0186299998 +-0.0112810005 -0.0436300002 0.0063700001 +-0.0112810005 -0.0436300002 -0.0063700001 +-0.0112810005 -0.0436300002 -0.0186299998 +-0.0112810005 -0.0436300002 -0.0313699991 +-0.0112810005 -0.0436300002 -0.0436300002 +-0.0113390004 0.0234379992 0.0436410010 +-0.0113390004 0.0234379992 0.0313589983 +-0.0113390004 0.0234379992 0.0186410006 +-0.0113390004 0.0234379992 0.0063590002 +-0.0118869999 0.0437199995 0.0437199995 +-0.0118869999 0.0437199995 0.0312799998 +-0.0118869999 0.0437199995 0.0187199991 +-0.0118869999 0.0437199995 0.0062799999 +-0.0118869999 0.0437199995 -0.0062799999 +-0.0118869999 0.0437199995 -0.0187199991 +-0.0118869999 0.0437199995 -0.0312799998 +-0.0118869999 0.0437199995 -0.0437199995 +-0.0118869999 0.0312799998 0.0437199995 +-0.0118869999 0.0312799998 0.0312799998 +-0.0118869999 0.0312799998 0.0187199991 +-0.0118869999 0.0312799998 0.0062799999 +-0.0118869999 0.0312799998 -0.0062799999 +-0.0118869999 0.0312799998 -0.0187199991 +-0.0118869999 0.0312799998 -0.0312799998 +-0.0118869999 0.0312799998 -0.0437199995 +-0.0118869999 0.0187199991 -0.0062799999 +-0.0118869999 0.0187199991 -0.0187199991 +-0.0118869999 0.0187199991 -0.0312799998 +-0.0118869999 0.0187199991 -0.0437199995 +-0.0118869999 0.0062799999 -0.0062799999 +-0.0118869999 0.0062799999 -0.0187199991 +-0.0118869999 0.0062799999 -0.0312799998 +-0.0118869999 0.0062799999 -0.0437199995 +-0.0118869999 -0.0062799999 0.0437199995 +-0.0118869999 -0.0062799999 0.0312799998 +-0.0118869999 -0.0062799999 0.0187199991 +-0.0118869999 -0.0062799999 0.0062799999 +-0.0118869999 -0.0062799999 -0.0062799999 +-0.0118869999 -0.0062799999 -0.0187199991 +-0.0118869999 -0.0062799999 -0.0312799998 +-0.0118869999 -0.0062799999 -0.0437199995 +-0.0118869999 -0.0187199991 0.0437199995 +-0.0118869999 -0.0187199991 0.0312799998 +-0.0118869999 -0.0187199991 0.0187199991 +-0.0118869999 -0.0187199991 0.0062799999 +-0.0118869999 -0.0187199991 -0.0062799999 +-0.0118869999 -0.0187199991 -0.0187199991 +-0.0118869999 -0.0187199991 -0.0312799998 +-0.0118869999 -0.0187199991 -0.0437199995 +-0.0118869999 -0.0312799998 0.0187199991 +-0.0118869999 -0.0312799998 0.0062799999 +-0.0118869999 -0.0312799998 -0.0062799999 +-0.0118869999 -0.0312799998 -0.0187199991 +-0.0118869999 -0.0312799998 -0.0312799998 +-0.0118869999 -0.0312799998 -0.0437199995 +-0.0118869999 -0.0437199995 0.0187199991 +-0.0118869999 -0.0437199995 0.0062799999 +-0.0118869999 -0.0437199995 -0.0062799999 +-0.0118869999 -0.0437199995 -0.0187199991 +-0.0118869999 -0.0437199995 -0.0312799998 +-0.0118869999 -0.0437199995 -0.0437199995 +-0.0125000002 0.0500000007 0.0437499993 +-0.0125000002 0.0500000007 0.0312500000 +-0.0125000002 0.0500000007 0.0187500007 +-0.0125000002 0.0500000007 0.0062500001 +-0.0125000002 0.0500000007 -0.0062500001 +-0.0125000002 0.0500000007 -0.0187500007 +-0.0125000002 0.0500000007 -0.0312500000 +-0.0125000002 0.0500000007 -0.0437499993 +-0.0125000002 0.0437499993 0.0500000007 +-0.0125000002 0.0437499993 0.0437499993 +-0.0125000002 0.0437499993 0.0312500000 +-0.0125000002 0.0437499993 0.0187500007 +-0.0125000002 0.0437499993 0.0062500001 +-0.0125000002 0.0437499993 -0.0062500001 +-0.0125000002 0.0437499993 -0.0187500007 +-0.0125000002 0.0437499993 -0.0312500000 +-0.0125000002 0.0437499993 -0.0437499993 +-0.0125000002 0.0437499993 -0.0500000007 +-0.0125000002 0.0312500000 0.0500000007 +-0.0125000002 0.0312500000 0.0437499993 +-0.0125000002 0.0312500000 0.0312500000 +-0.0125000002 0.0312500000 0.0187500007 +-0.0125000002 0.0312500000 0.0062500001 +-0.0125000002 0.0312500000 -0.0062500001 +-0.0125000002 0.0312500000 -0.0187500007 +-0.0125000002 0.0312500000 -0.0312500000 +-0.0125000002 0.0312500000 -0.0437499993 +-0.0125000002 0.0312500000 -0.0500000007 +-0.0125000002 0.0187500007 -0.0003910000 +-0.0125000002 0.0187500007 -0.0062500001 +-0.0125000002 0.0187500007 -0.0187500007 +-0.0125000002 0.0187500007 -0.0312500000 +-0.0125000002 0.0187500007 -0.0437499993 +-0.0125000002 0.0187500007 -0.0500000007 +-0.0125000002 0.0062500001 -0.0003910000 +-0.0125000002 0.0062500001 -0.0062500001 +-0.0125000002 0.0062500001 -0.0187500007 +-0.0125000002 0.0062500001 -0.0312500000 +-0.0125000002 0.0062500001 -0.0437499993 +-0.0125000002 0.0062500001 -0.0500000007 +-0.0125000002 -0.0000000000 0.0437499993 +-0.0125000002 -0.0000000000 0.0312500000 +-0.0125000002 -0.0000000000 0.0187500007 +-0.0125000002 -0.0000000000 0.0062500001 +-0.0125000002 -0.0062500001 0.0500000007 +-0.0125000002 -0.0062500001 0.0437499993 +-0.0125000002 -0.0062500001 0.0312500000 +-0.0125000002 -0.0062500001 0.0187500007 +-0.0125000002 -0.0062500001 0.0062500001 +-0.0125000002 -0.0062500001 -0.0062500001 +-0.0125000002 -0.0062500001 -0.0187500007 +-0.0125000002 -0.0062500001 -0.0312500000 +-0.0125000002 -0.0062500001 -0.0437499993 +-0.0125000002 -0.0062500001 -0.0500000007 +-0.0125000002 -0.0187500007 0.0500000007 +-0.0125000002 -0.0187500007 0.0437499993 +-0.0125000002 -0.0187500007 0.0312500000 +-0.0125000002 -0.0187500007 0.0187500007 +-0.0125000002 -0.0187500007 0.0062500001 +-0.0125000002 -0.0187500007 -0.0062500001 +-0.0125000002 -0.0187500007 -0.0187500007 +-0.0125000002 -0.0187500007 -0.0312500000 +-0.0125000002 -0.0187500007 -0.0437499993 +-0.0125000002 -0.0187500007 -0.0500000007 +-0.0125000002 -0.0250000004 0.0437499993 +-0.0125000002 -0.0250000004 0.0312500000 +-0.0125000002 -0.0312500000 0.0212500002 +-0.0125000002 -0.0312500000 0.0187500007 +-0.0125000002 -0.0312500000 0.0062500001 +-0.0125000002 -0.0312500000 -0.0062500001 +-0.0125000002 -0.0312500000 -0.0187500007 +-0.0125000002 -0.0312500000 -0.0312500000 +-0.0125000002 -0.0312500000 -0.0437499993 +-0.0125000002 -0.0312500000 -0.0500000007 +-0.0125000002 -0.0437499993 0.0212500002 +-0.0125000002 -0.0437499993 0.0187500007 +-0.0125000002 -0.0437499993 0.0062500001 +-0.0125000002 -0.0437499993 -0.0062500001 +-0.0125000002 -0.0437499993 -0.0187500007 +-0.0125000002 -0.0437499993 -0.0312500000 +-0.0125000002 -0.0437499993 -0.0437499993 +-0.0125000002 -0.0437499993 -0.0500000007 +-0.0125000002 -0.0500000007 0.0187500007 +-0.0125000002 -0.0500000007 0.0062500001 +-0.0125000002 -0.0500000007 -0.0062500001 +-0.0125000002 -0.0500000007 -0.0187500007 +-0.0125000002 -0.0500000007 -0.0312500000 +-0.0125000002 -0.0500000007 -0.0437499993 +-0.0129009997 0.0234379992 0.0437370017 +-0.0129009997 0.0234379992 0.0312630013 +-0.0129009997 0.0234379992 0.0187369995 +-0.0129009997 0.0234379992 0.0062630000 +-0.0131130004 0.0437199995 0.0437199995 +-0.0131130004 0.0437199995 0.0312799998 +-0.0131130004 0.0437199995 0.0187199991 +-0.0131130004 0.0437199995 0.0062799999 +-0.0131130004 0.0437199995 -0.0062799999 +-0.0131130004 0.0437199995 -0.0187199991 +-0.0131130004 0.0437199995 -0.0312799998 +-0.0131130004 0.0437199995 -0.0437199995 +-0.0131130004 0.0312799998 0.0437199995 +-0.0131130004 0.0312799998 0.0312799998 +-0.0131130004 0.0312799998 0.0187199991 +-0.0131130004 0.0312799998 0.0062799999 +-0.0131130004 0.0312799998 -0.0062799999 +-0.0131130004 0.0312799998 -0.0187199991 +-0.0131130004 0.0312799998 -0.0312799998 +-0.0131130004 0.0312799998 -0.0437199995 +-0.0131130004 0.0187199991 -0.0062799999 +-0.0131130004 0.0187199991 -0.0187199991 +-0.0131130004 0.0187199991 -0.0312799998 +-0.0131130004 0.0187199991 -0.0437199995 +-0.0131130004 0.0062799999 -0.0062799999 +-0.0131130004 0.0062799999 -0.0187199991 +-0.0131130004 0.0062799999 -0.0312799998 +-0.0131130004 0.0062799999 -0.0437199995 +-0.0131130004 -0.0062799999 0.0437199995 +-0.0131130004 -0.0062799999 0.0312799998 +-0.0131130004 -0.0062799999 0.0187199991 +-0.0131130004 -0.0062799999 0.0062799999 +-0.0131130004 -0.0062799999 -0.0062799999 +-0.0131130004 -0.0062799999 -0.0187199991 +-0.0131130004 -0.0062799999 -0.0312799998 +-0.0131130004 -0.0062799999 -0.0437199995 +-0.0131130004 -0.0187199991 0.0437199995 +-0.0131130004 -0.0187199991 0.0312799998 +-0.0131130004 -0.0187199991 0.0187199991 +-0.0131130004 -0.0187199991 0.0062799999 +-0.0131130004 -0.0187199991 -0.0062799999 +-0.0131130004 -0.0187199991 -0.0187199991 +-0.0131130004 -0.0187199991 -0.0312799998 +-0.0131130004 -0.0187199991 -0.0437199995 +-0.0131130004 -0.0312799998 0.0187199991 +-0.0131130004 -0.0312799998 0.0062799999 +-0.0131130004 -0.0312799998 -0.0062799999 +-0.0131130004 -0.0312799998 -0.0187199991 +-0.0131130004 -0.0312799998 -0.0312799998 +-0.0131130004 -0.0312799998 -0.0437199995 +-0.0131130004 -0.0437199995 0.0187199991 +-0.0131130004 -0.0437199995 0.0062799999 +-0.0131130004 -0.0437199995 -0.0062799999 +-0.0131130004 -0.0437199995 -0.0187199991 +-0.0131130004 -0.0437199995 -0.0312799998 +-0.0131130004 -0.0437199995 -0.0437199995 +-0.0137189999 0.0436300002 0.0436300002 +-0.0137189999 0.0436300002 0.0313699991 +-0.0137189999 0.0436300002 0.0186299998 +-0.0137189999 0.0436300002 0.0063700001 +-0.0137189999 0.0436300002 -0.0063700001 +-0.0137189999 0.0436300002 -0.0186299998 +-0.0137189999 0.0436300002 -0.0313699991 +-0.0137189999 0.0436300002 -0.0436300002 +-0.0137189999 0.0313699991 0.0436300002 +-0.0137189999 0.0313699991 0.0313699991 +-0.0137189999 0.0313699991 0.0186299998 +-0.0137189999 0.0313699991 0.0063700001 +-0.0137189999 0.0313699991 -0.0063700001 +-0.0137189999 0.0313699991 -0.0186299998 +-0.0137189999 0.0313699991 -0.0313699991 +-0.0137189999 0.0313699991 -0.0436300002 +-0.0137189999 0.0186299998 -0.0063700001 +-0.0137189999 0.0186299998 -0.0186299998 +-0.0137189999 0.0186299998 -0.0313699991 +-0.0137189999 0.0186299998 -0.0436300002 +-0.0137189999 0.0063700001 -0.0063700001 +-0.0137189999 0.0063700001 -0.0186299998 +-0.0137189999 0.0063700001 -0.0313699991 +-0.0137189999 0.0063700001 -0.0436300002 +-0.0137189999 -0.0063700001 0.0436300002 +-0.0137189999 -0.0063700001 0.0313699991 +-0.0137189999 -0.0063700001 0.0186299998 +-0.0137189999 -0.0063700001 0.0063700001 +-0.0137189999 -0.0063700001 -0.0063700001 +-0.0137189999 -0.0063700001 -0.0186299998 +-0.0137189999 -0.0063700001 -0.0313699991 +-0.0137189999 -0.0063700001 -0.0436300002 +-0.0137189999 -0.0186299998 0.0436300002 +-0.0137189999 -0.0186299998 0.0313699991 +-0.0137189999 -0.0186299998 0.0186299998 +-0.0137189999 -0.0186299998 0.0063700001 +-0.0137189999 -0.0186299998 -0.0063700001 +-0.0137189999 -0.0186299998 -0.0186299998 +-0.0137189999 -0.0186299998 -0.0313699991 +-0.0137189999 -0.0186299998 -0.0436300002 +-0.0137189999 -0.0313699991 0.0186299998 +-0.0137189999 -0.0313699991 0.0063700001 +-0.0137189999 -0.0313699991 -0.0063700001 +-0.0137189999 -0.0313699991 -0.0186299998 +-0.0137189999 -0.0313699991 -0.0313699991 +-0.0137189999 -0.0313699991 -0.0436300002 +-0.0137189999 -0.0436300002 0.0186299998 +-0.0137189999 -0.0436300002 0.0063700001 +-0.0137189999 -0.0436300002 -0.0063700001 +-0.0137189999 -0.0436300002 -0.0186299998 +-0.0137189999 -0.0436300002 -0.0313699991 +-0.0137189999 -0.0436300002 -0.0436300002 +-0.0141179999 0.0500000007 0.0435369983 +-0.0141179999 0.0500000007 0.0314630009 +-0.0141179999 0.0500000007 0.0185369998 +-0.0141179999 0.0500000007 0.0064630001 +-0.0141179999 0.0500000007 -0.0064630001 +-0.0141179999 0.0500000007 -0.0185369998 +-0.0141179999 0.0500000007 -0.0314630009 +-0.0141179999 0.0500000007 -0.0435369983 +-0.0141179999 0.0435369983 0.0500000007 +-0.0141179999 0.0435369983 -0.0500000007 +-0.0141179999 0.0314630009 0.0500000007 +-0.0141179999 0.0314630009 -0.0500000007 +-0.0141179999 0.0185369998 -0.0003910000 +-0.0141179999 0.0185369998 -0.0500000007 +-0.0141179999 0.0064630001 -0.0003910000 +-0.0141179999 0.0064630001 -0.0500000007 +-0.0141179999 -0.0000000000 0.0435369983 +-0.0141179999 -0.0000000000 0.0314630009 +-0.0141179999 -0.0000000000 0.0185369998 +-0.0141179999 -0.0000000000 0.0064630001 +-0.0141179999 -0.0064630001 0.0500000007 +-0.0141179999 -0.0064630001 -0.0500000007 +-0.0141179999 -0.0185369998 0.0500000007 +-0.0141179999 -0.0185369998 -0.0500000007 +-0.0141179999 -0.0250000004 0.0435369983 +-0.0141179999 -0.0250000004 0.0314630009 +-0.0141179999 -0.0314630009 0.0212500002 +-0.0141179999 -0.0314630009 -0.0500000007 +-0.0141179999 -0.0435369983 0.0212500002 +-0.0141179999 -0.0435369983 -0.0500000007 +-0.0141179999 -0.0500000007 0.0185369998 +-0.0141179999 -0.0500000007 0.0064630001 +-0.0141179999 -0.0500000007 -0.0064630001 +-0.0141179999 -0.0500000007 -0.0185369998 +-0.0141179999 -0.0500000007 -0.0314630009 +-0.0141179999 -0.0500000007 -0.0435369983 +-0.0144379996 0.0234379992 0.0434419997 +-0.0144379996 0.0234379992 0.0315579996 +-0.0144379996 0.0234379992 0.0184419993 +-0.0144379996 0.0234379992 0.0065580001 +-0.0148919998 0.0432740003 0.0432740003 +-0.0148919998 0.0432740003 0.0317259990 +-0.0148919998 0.0432740003 0.0182739999 +-0.0148919998 0.0432740003 0.0067260000 +-0.0148919998 0.0432740003 -0.0067260000 +-0.0148919998 0.0432740003 -0.0182739999 +-0.0148919998 0.0432740003 -0.0317259990 +-0.0148919998 0.0432740003 -0.0432740003 +-0.0148919998 0.0317259990 0.0432740003 +-0.0148919998 0.0317259990 0.0317259990 +-0.0148919998 0.0317259990 0.0182739999 +-0.0148919998 0.0317259990 0.0067260000 +-0.0148919998 0.0317259990 -0.0067260000 +-0.0148919998 0.0317259990 -0.0182739999 +-0.0148919998 0.0317259990 -0.0317259990 +-0.0148919998 0.0317259990 -0.0432740003 +-0.0148919998 0.0182739999 -0.0067260000 +-0.0148919998 0.0182739999 -0.0182739999 +-0.0148919998 0.0182739999 -0.0317259990 +-0.0148919998 0.0182739999 -0.0432740003 +-0.0148919998 0.0067260000 -0.0067260000 +-0.0148919998 0.0067260000 -0.0182739999 +-0.0148919998 0.0067260000 -0.0317259990 +-0.0148919998 0.0067260000 -0.0432740003 +-0.0148919998 -0.0067260000 0.0432740003 +-0.0148919998 -0.0067260000 0.0317259990 +-0.0148919998 -0.0067260000 0.0182739999 +-0.0148919998 -0.0067260000 0.0067260000 +-0.0148919998 -0.0067260000 -0.0067260000 +-0.0148919998 -0.0067260000 -0.0182739999 +-0.0148919998 -0.0067260000 -0.0317259990 +-0.0148919998 -0.0067260000 -0.0432740003 +-0.0148919998 -0.0182739999 0.0432740003 +-0.0148919998 -0.0182739999 0.0317259990 +-0.0148919998 -0.0182739999 0.0182739999 +-0.0148919998 -0.0182739999 0.0067260000 +-0.0148919998 -0.0182739999 -0.0067260000 +-0.0148919998 -0.0182739999 -0.0182739999 +-0.0148919998 -0.0182739999 -0.0317259990 +-0.0148919998 -0.0182739999 -0.0432740003 +-0.0148919998 -0.0317259990 0.0182739999 +-0.0148919998 -0.0317259990 0.0067260000 +-0.0148919998 -0.0317259990 -0.0067260000 +-0.0148919998 -0.0317259990 -0.0182739999 +-0.0148919998 -0.0317259990 -0.0317259990 +-0.0148919998 -0.0317259990 -0.0432740003 +-0.0148919998 -0.0432740003 0.0182739999 +-0.0148919998 -0.0432740003 0.0067260000 +-0.0148919998 -0.0432740003 -0.0067260000 +-0.0148919998 -0.0432740003 -0.0182739999 +-0.0148919998 -0.0432740003 -0.0317259990 +-0.0148919998 -0.0432740003 -0.0432740003 +-0.0156250000 0.0500000007 0.0429130010 +-0.0156250000 0.0500000007 0.0320869982 +-0.0156250000 0.0500000007 0.0179130007 +-0.0156250000 0.0500000007 0.0070870002 +-0.0156250000 0.0500000007 -0.0070870002 +-0.0156250000 0.0500000007 -0.0179130007 +-0.0156250000 0.0500000007 -0.0320869982 +-0.0156250000 0.0500000007 -0.0429130010 +-0.0156250000 0.0429130010 0.0500000007 +-0.0156250000 0.0429130010 -0.0500000007 +-0.0156250000 0.0320869982 0.0500000007 +-0.0156250000 0.0320869982 -0.0500000007 +-0.0156250000 0.0179130007 -0.0003910000 +-0.0156250000 0.0179130007 -0.0500000007 +-0.0156250000 0.0070870002 -0.0003910000 +-0.0156250000 0.0070870002 -0.0500000007 +-0.0156250000 -0.0000000000 0.0429130010 +-0.0156250000 -0.0000000000 0.0320869982 +-0.0156250000 -0.0000000000 0.0179130007 +-0.0156250000 -0.0000000000 0.0070870002 +-0.0156250000 -0.0070870002 0.0500000007 +-0.0156250000 -0.0070870002 -0.0500000007 +-0.0156250000 -0.0179130007 0.0500000007 +-0.0156250000 -0.0179130007 -0.0500000007 +-0.0156250000 -0.0250000004 0.0429130010 +-0.0156250000 -0.0250000004 0.0320869982 +-0.0156250000 -0.0320869982 0.0212500002 +-0.0156250000 -0.0320869982 -0.0500000007 +-0.0156250000 -0.0429130010 0.0212500002 +-0.0156250000 -0.0429130010 -0.0500000007 +-0.0156250000 -0.0500000007 0.0179130007 +-0.0156250000 -0.0500000007 0.0070870002 +-0.0156250000 -0.0500000007 -0.0070870002 +-0.0156250000 -0.0500000007 -0.0179130007 +-0.0156250000 -0.0500000007 -0.0320869982 +-0.0156250000 -0.0500000007 -0.0429130010 +-0.0158539992 0.0234379992 0.0427739993 +-0.0158539992 0.0234379992 0.0322260000 +-0.0158539992 0.0234379992 0.0177740008 +-0.0158539992 0.0234379992 0.0072260001 +-0.0159719996 0.0426970012 0.0426970012 +-0.0159719996 0.0426970012 0.0323030017 +-0.0159719996 0.0426970012 0.0176970009 +-0.0159719996 0.0426970012 0.0073030000 +-0.0159719996 0.0426970012 -0.0073030000 +-0.0159719996 0.0426970012 -0.0176970009 +-0.0159719996 0.0426970012 -0.0323030017 +-0.0159719996 0.0426970012 -0.0426970012 +-0.0159719996 0.0323030017 0.0426970012 +-0.0159719996 0.0323030017 0.0323030017 +-0.0159719996 0.0323030017 0.0176970009 +-0.0159719996 0.0323030017 0.0073030000 +-0.0159719996 0.0323030017 -0.0073030000 +-0.0159719996 0.0323030017 -0.0176970009 +-0.0159719996 0.0323030017 -0.0323030017 +-0.0159719996 0.0323030017 -0.0426970012 +-0.0159719996 0.0176970009 -0.0073030000 +-0.0159719996 0.0176970009 -0.0176970009 +-0.0159719996 0.0176970009 -0.0323030017 +-0.0159719996 0.0176970009 -0.0426970012 +-0.0159719996 0.0073030000 -0.0073030000 +-0.0159719996 0.0073030000 -0.0176970009 +-0.0159719996 0.0073030000 -0.0323030017 +-0.0159719996 0.0073030000 -0.0426970012 +-0.0159719996 -0.0073030000 0.0426970012 +-0.0159719996 -0.0073030000 0.0323030017 +-0.0159719996 -0.0073030000 0.0176970009 +-0.0159719996 -0.0073030000 0.0073030000 +-0.0159719996 -0.0073030000 -0.0073030000 +-0.0159719996 -0.0073030000 -0.0176970009 +-0.0159719996 -0.0073030000 -0.0323030017 +-0.0159719996 -0.0073030000 -0.0426970012 +-0.0159719996 -0.0176970009 0.0426970012 +-0.0159719996 -0.0176970009 0.0323030017 +-0.0159719996 -0.0176970009 0.0176970009 +-0.0159719996 -0.0176970009 0.0073030000 +-0.0159719996 -0.0176970009 -0.0073030000 +-0.0159719996 -0.0176970009 -0.0176970009 +-0.0159719996 -0.0176970009 -0.0323030017 +-0.0159719996 -0.0176970009 -0.0426970012 +-0.0159719996 -0.0323030017 0.0176970009 +-0.0159719996 -0.0323030017 0.0073030000 +-0.0159719996 -0.0323030017 -0.0073030000 +-0.0159719996 -0.0323030017 -0.0176970009 +-0.0159719996 -0.0323030017 -0.0323030017 +-0.0159719996 -0.0323030017 -0.0426970012 +-0.0159719996 -0.0426970012 0.0176970009 +-0.0159719996 -0.0426970012 0.0073030000 +-0.0159719996 -0.0426970012 -0.0073030000 +-0.0159719996 -0.0426970012 -0.0176970009 +-0.0159719996 -0.0426970012 -0.0323030017 +-0.0159719996 -0.0426970012 -0.0426970012 +-0.0169190001 0.0500000007 0.0419190004 +-0.0169190001 0.0500000007 0.0330809988 +-0.0169190001 0.0500000007 0.0169190001 +-0.0169190001 0.0500000007 0.0080810003 +-0.0169190001 0.0500000007 -0.0080810003 +-0.0169190001 0.0500000007 -0.0169190001 +-0.0169190001 0.0500000007 -0.0330809988 +-0.0169190001 0.0500000007 -0.0419190004 +-0.0169190001 0.0419190004 0.0500000007 +-0.0169190001 0.0419190004 0.0419190004 +-0.0169190001 0.0419190004 0.0330809988 +-0.0169190001 0.0419190004 0.0169190001 +-0.0169190001 0.0419190004 0.0080810003 +-0.0169190001 0.0419190004 -0.0080810003 +-0.0169190001 0.0419190004 -0.0169190001 +-0.0169190001 0.0419190004 -0.0330809988 +-0.0169190001 0.0419190004 -0.0419190004 +-0.0169190001 0.0419190004 -0.0500000007 +-0.0169190001 0.0330809988 0.0500000007 +-0.0169190001 0.0330809988 0.0419190004 +-0.0169190001 0.0330809988 0.0330809988 +-0.0169190001 0.0330809988 0.0169190001 +-0.0169190001 0.0330809988 0.0080810003 +-0.0169190001 0.0330809988 -0.0080810003 +-0.0169190001 0.0330809988 -0.0169190001 +-0.0169190001 0.0330809988 -0.0330809988 +-0.0169190001 0.0330809988 -0.0419190004 +-0.0169190001 0.0330809988 -0.0500000007 +-0.0169190001 0.0169190001 -0.0003910000 +-0.0169190001 0.0169190001 -0.0080810003 +-0.0169190001 0.0169190001 -0.0169190001 +-0.0169190001 0.0169190001 -0.0330809988 +-0.0169190001 0.0169190001 -0.0419190004 +-0.0169190001 0.0169190001 -0.0500000007 +-0.0169190001 0.0080810003 -0.0003910000 +-0.0169190001 0.0080810003 -0.0080810003 +-0.0169190001 0.0080810003 -0.0169190001 +-0.0169190001 0.0080810003 -0.0330809988 +-0.0169190001 0.0080810003 -0.0419190004 +-0.0169190001 0.0080810003 -0.0500000007 +-0.0169190001 -0.0000000000 0.0419190004 +-0.0169190001 -0.0000000000 0.0330809988 +-0.0169190001 -0.0000000000 0.0169190001 +-0.0169190001 -0.0000000000 0.0080810003 +-0.0169190001 -0.0080810003 0.0500000007 +-0.0169190001 -0.0080810003 0.0419190004 +-0.0169190001 -0.0080810003 0.0330809988 +-0.0169190001 -0.0080810003 0.0169190001 +-0.0169190001 -0.0080810003 0.0080810003 +-0.0169190001 -0.0080810003 -0.0080810003 +-0.0169190001 -0.0080810003 -0.0169190001 +-0.0169190001 -0.0080810003 -0.0330809988 +-0.0169190001 -0.0080810003 -0.0419190004 +-0.0169190001 -0.0080810003 -0.0500000007 +-0.0169190001 -0.0169190001 0.0500000007 +-0.0169190001 -0.0169190001 0.0419190004 +-0.0169190001 -0.0169190001 0.0330809988 +-0.0169190001 -0.0169190001 0.0169190001 +-0.0169190001 -0.0169190001 0.0080810003 +-0.0169190001 -0.0169190001 -0.0080810003 +-0.0169190001 -0.0169190001 -0.0169190001 +-0.0169190001 -0.0169190001 -0.0330809988 +-0.0169190001 -0.0169190001 -0.0419190004 +-0.0169190001 -0.0169190001 -0.0500000007 +-0.0169190001 -0.0250000004 0.0419190004 +-0.0169190001 -0.0250000004 0.0330809988 +-0.0169190001 -0.0330809988 0.0212500002 +-0.0169190001 -0.0330809988 0.0169190001 +-0.0169190001 -0.0330809988 0.0080810003 +-0.0169190001 -0.0330809988 -0.0080810003 +-0.0169190001 -0.0330809988 -0.0169190001 +-0.0169190001 -0.0330809988 -0.0330809988 +-0.0169190001 -0.0330809988 -0.0419190004 +-0.0169190001 -0.0330809988 -0.0500000007 +-0.0169190001 -0.0419190004 0.0212500002 +-0.0169190001 -0.0419190004 0.0169190001 +-0.0169190001 -0.0419190004 0.0080810003 +-0.0169190001 -0.0419190004 -0.0080810003 +-0.0169190001 -0.0419190004 -0.0169190001 +-0.0169190001 -0.0419190004 -0.0330809988 +-0.0169190001 -0.0419190004 -0.0419190004 +-0.0169190001 -0.0419190004 -0.0500000007 +-0.0169190001 -0.0500000007 0.0169190001 +-0.0169190001 -0.0500000007 0.0080810003 +-0.0169190001 -0.0500000007 -0.0080810003 +-0.0169190001 -0.0500000007 -0.0169190001 +-0.0169190001 -0.0500000007 -0.0330809988 +-0.0169190001 -0.0500000007 -0.0419190004 +-0.0170590002 0.0234379992 0.0417749994 +-0.0170590002 0.0234379992 0.0332249999 +-0.0170590002 0.0234379992 0.0167750008 +-0.0170590002 0.0234379992 0.0082250005 +-0.0176970009 0.0426970012 0.0409720019 +-0.0176970009 0.0426970012 0.0340280011 +-0.0176970009 0.0426970012 0.0159719996 +-0.0176970009 0.0426970012 0.0090279998 +-0.0176970009 0.0426970012 -0.0090279998 +-0.0176970009 0.0426970012 -0.0159719996 +-0.0176970009 0.0426970012 -0.0340280011 +-0.0176970009 0.0426970012 -0.0409720019 +-0.0176970009 0.0409720019 0.0426970012 +-0.0176970009 0.0409720019 0.0323030017 +-0.0176970009 0.0409720019 0.0176970009 +-0.0176970009 0.0409720019 0.0073030000 +-0.0176970009 0.0409720019 -0.0073030000 +-0.0176970009 0.0409720019 -0.0176970009 +-0.0176970009 0.0409720019 -0.0323030017 +-0.0176970009 0.0409720019 -0.0426970012 +-0.0176970009 0.0340280011 0.0426970012 +-0.0176970009 0.0340280011 0.0323030017 +-0.0176970009 0.0340280011 0.0176970009 +-0.0176970009 0.0340280011 0.0073030000 +-0.0176970009 0.0340280011 -0.0073030000 +-0.0176970009 0.0340280011 -0.0176970009 +-0.0176970009 0.0340280011 -0.0323030017 +-0.0176970009 0.0340280011 -0.0426970012 +-0.0176970009 0.0323030017 0.0409720019 +-0.0176970009 0.0323030017 0.0340280011 +-0.0176970009 0.0323030017 0.0159719996 +-0.0176970009 0.0323030017 0.0090279998 +-0.0176970009 0.0323030017 -0.0090279998 +-0.0176970009 0.0323030017 -0.0159719996 +-0.0176970009 0.0323030017 -0.0340280011 +-0.0176970009 0.0323030017 -0.0409720019 +-0.0176970009 0.0176970009 -0.0090279998 +-0.0176970009 0.0176970009 -0.0159719996 +-0.0176970009 0.0176970009 -0.0340280011 +-0.0176970009 0.0176970009 -0.0409720019 +-0.0176970009 0.0159719996 -0.0073030000 +-0.0176970009 0.0159719996 -0.0176970009 +-0.0176970009 0.0159719996 -0.0323030017 +-0.0176970009 0.0159719996 -0.0426970012 +-0.0176970009 0.0090279998 -0.0073030000 +-0.0176970009 0.0090279998 -0.0176970009 +-0.0176970009 0.0090279998 -0.0323030017 +-0.0176970009 0.0090279998 -0.0426970012 +-0.0176970009 0.0073030000 -0.0090279998 +-0.0176970009 0.0073030000 -0.0159719996 +-0.0176970009 0.0073030000 -0.0340280011 +-0.0176970009 0.0073030000 -0.0409720019 +-0.0176970009 -0.0073030000 0.0409720019 +-0.0176970009 -0.0073030000 0.0340280011 +-0.0176970009 -0.0073030000 0.0159719996 +-0.0176970009 -0.0073030000 0.0090279998 +-0.0176970009 -0.0073030000 -0.0090279998 +-0.0176970009 -0.0073030000 -0.0159719996 +-0.0176970009 -0.0073030000 -0.0340280011 +-0.0176970009 -0.0073030000 -0.0409720019 +-0.0176970009 -0.0090279998 0.0426970012 +-0.0176970009 -0.0090279998 0.0323030017 +-0.0176970009 -0.0090279998 0.0176970009 +-0.0176970009 -0.0090279998 0.0073030000 +-0.0176970009 -0.0090279998 -0.0073030000 +-0.0176970009 -0.0090279998 -0.0176970009 +-0.0176970009 -0.0090279998 -0.0323030017 +-0.0176970009 -0.0090279998 -0.0426970012 +-0.0176970009 -0.0159719996 0.0426970012 +-0.0176970009 -0.0159719996 0.0323030017 +-0.0176970009 -0.0159719996 0.0176970009 +-0.0176970009 -0.0159719996 0.0073030000 +-0.0176970009 -0.0159719996 -0.0073030000 +-0.0176970009 -0.0159719996 -0.0176970009 +-0.0176970009 -0.0159719996 -0.0323030017 +-0.0176970009 -0.0159719996 -0.0426970012 +-0.0176970009 -0.0176970009 0.0409720019 +-0.0176970009 -0.0176970009 0.0340280011 +-0.0176970009 -0.0176970009 0.0159719996 +-0.0176970009 -0.0176970009 0.0090279998 +-0.0176970009 -0.0176970009 -0.0090279998 +-0.0176970009 -0.0176970009 -0.0159719996 +-0.0176970009 -0.0176970009 -0.0340280011 +-0.0176970009 -0.0176970009 -0.0409720019 +-0.0176970009 -0.0323030017 0.0159719996 +-0.0176970009 -0.0323030017 0.0090279998 +-0.0176970009 -0.0323030017 -0.0090279998 +-0.0176970009 -0.0323030017 -0.0159719996 +-0.0176970009 -0.0323030017 -0.0340280011 +-0.0176970009 -0.0323030017 -0.0409720019 +-0.0176970009 -0.0340280011 0.0176970009 +-0.0176970009 -0.0340280011 0.0073030000 +-0.0176970009 -0.0340280011 -0.0073030000 +-0.0176970009 -0.0340280011 -0.0176970009 +-0.0176970009 -0.0340280011 -0.0323030017 +-0.0176970009 -0.0340280011 -0.0426970012 +-0.0176970009 -0.0409720019 0.0176970009 +-0.0176970009 -0.0409720019 0.0073030000 +-0.0176970009 -0.0409720019 -0.0073030000 +-0.0176970009 -0.0409720019 -0.0176970009 +-0.0176970009 -0.0409720019 -0.0323030017 +-0.0176970009 -0.0409720019 -0.0426970012 +-0.0176970009 -0.0426970012 0.0159719996 +-0.0176970009 -0.0426970012 0.0090279998 +-0.0176970009 -0.0426970012 -0.0090279998 +-0.0176970009 -0.0426970012 -0.0159719996 +-0.0176970009 -0.0426970012 -0.0340280011 +-0.0176970009 -0.0426970012 -0.0409720019 +-0.0179130007 0.0500000007 0.0406249985 +-0.0179130007 0.0500000007 0.0343750007 +-0.0179130007 0.0500000007 0.0156250000 +-0.0179130007 0.0500000007 0.0093750004 +-0.0179130007 0.0500000007 -0.0093750004 +-0.0179130007 0.0500000007 -0.0156250000 +-0.0179130007 0.0500000007 -0.0343750007 +-0.0179130007 0.0500000007 -0.0406249985 +-0.0179130007 0.0406249985 0.0500000007 +-0.0179130007 0.0406249985 -0.0500000007 +-0.0179130007 0.0343750007 0.0500000007 +-0.0179130007 0.0343750007 -0.0500000007 +-0.0179130007 0.0156250000 -0.0003910000 +-0.0179130007 0.0156250000 -0.0500000007 +-0.0179130007 0.0093750004 -0.0003910000 +-0.0179130007 0.0093750004 -0.0500000007 +-0.0179130007 -0.0000000000 0.0406249985 +-0.0179130007 -0.0000000000 0.0343750007 +-0.0179130007 -0.0000000000 0.0156250000 +-0.0179130007 -0.0000000000 0.0093750004 +-0.0179130007 -0.0093750004 0.0500000007 +-0.0179130007 -0.0093750004 -0.0500000007 +-0.0179130007 -0.0156250000 0.0500000007 +-0.0179130007 -0.0156250000 -0.0500000007 +-0.0179130007 -0.0250000004 0.0406249985 +-0.0179130007 -0.0250000004 0.0343750007 +-0.0179130007 -0.0343750007 0.0212500002 +-0.0179130007 -0.0343750007 -0.0500000007 +-0.0179130007 -0.0406249985 0.0212500002 +-0.0179130007 -0.0406249985 -0.0500000007 +-0.0179130007 -0.0500000007 0.0156250000 +-0.0179130007 -0.0500000007 0.0093750004 +-0.0179130007 -0.0500000007 -0.0093750004 +-0.0179130007 -0.0500000007 -0.0156250000 +-0.0179130007 -0.0500000007 -0.0343750007 +-0.0179130007 -0.0500000007 -0.0406249985 +-0.0179779995 0.0234379992 0.0405079983 +-0.0179779995 0.0234379992 0.0344920009 +-0.0179779995 0.0234379992 0.0155079998 +-0.0179779995 0.0234379992 0.0094919996 +-0.0182739999 0.0432740003 0.0398919992 +-0.0182739999 0.0432740003 0.0351080000 +-0.0182739999 0.0432740003 0.0148919998 +-0.0182739999 0.0432740003 0.0101079997 +-0.0182739999 0.0432740003 -0.0101079997 +-0.0182739999 0.0432740003 -0.0148919998 +-0.0182739999 0.0432740003 -0.0351080000 +-0.0182739999 0.0432740003 -0.0398919992 +-0.0182739999 0.0398919992 0.0432740003 +-0.0182739999 0.0398919992 0.0317259990 +-0.0182739999 0.0398919992 0.0182739999 +-0.0182739999 0.0398919992 0.0067260000 +-0.0182739999 0.0398919992 -0.0067260000 +-0.0182739999 0.0398919992 -0.0182739999 +-0.0182739999 0.0398919992 -0.0317259990 +-0.0182739999 0.0398919992 -0.0432740003 +-0.0182739999 0.0351080000 0.0432740003 +-0.0182739999 0.0351080000 0.0317259990 +-0.0182739999 0.0351080000 0.0182739999 +-0.0182739999 0.0351080000 0.0067260000 +-0.0182739999 0.0351080000 -0.0067260000 +-0.0182739999 0.0351080000 -0.0182739999 +-0.0182739999 0.0351080000 -0.0317259990 +-0.0182739999 0.0351080000 -0.0432740003 +-0.0182739999 0.0317259990 0.0398919992 +-0.0182739999 0.0317259990 0.0351080000 +-0.0182739999 0.0317259990 0.0148919998 +-0.0182739999 0.0317259990 0.0101079997 +-0.0182739999 0.0317259990 -0.0101079997 +-0.0182739999 0.0317259990 -0.0148919998 +-0.0182739999 0.0317259990 -0.0351080000 +-0.0182739999 0.0317259990 -0.0398919992 +-0.0182739999 0.0182739999 -0.0101079997 +-0.0182739999 0.0182739999 -0.0148919998 +-0.0182739999 0.0182739999 -0.0351080000 +-0.0182739999 0.0182739999 -0.0398919992 +-0.0182739999 0.0148919998 -0.0067260000 +-0.0182739999 0.0148919998 -0.0182739999 +-0.0182739999 0.0148919998 -0.0317259990 +-0.0182739999 0.0148919998 -0.0432740003 +-0.0182739999 0.0101079997 -0.0067260000 +-0.0182739999 0.0101079997 -0.0182739999 +-0.0182739999 0.0101079997 -0.0317259990 +-0.0182739999 0.0101079997 -0.0432740003 +-0.0182739999 0.0067260000 -0.0101079997 +-0.0182739999 0.0067260000 -0.0148919998 +-0.0182739999 0.0067260000 -0.0351080000 +-0.0182739999 0.0067260000 -0.0398919992 +-0.0182739999 -0.0067260000 0.0398919992 +-0.0182739999 -0.0067260000 0.0351080000 +-0.0182739999 -0.0067260000 0.0148919998 +-0.0182739999 -0.0067260000 0.0101079997 +-0.0182739999 -0.0067260000 -0.0101079997 +-0.0182739999 -0.0067260000 -0.0148919998 +-0.0182739999 -0.0067260000 -0.0351080000 +-0.0182739999 -0.0067260000 -0.0398919992 +-0.0182739999 -0.0101079997 0.0432740003 +-0.0182739999 -0.0101079997 0.0317259990 +-0.0182739999 -0.0101079997 0.0182739999 +-0.0182739999 -0.0101079997 0.0067260000 +-0.0182739999 -0.0101079997 -0.0067260000 +-0.0182739999 -0.0101079997 -0.0182739999 +-0.0182739999 -0.0101079997 -0.0317259990 +-0.0182739999 -0.0101079997 -0.0432740003 +-0.0182739999 -0.0148919998 0.0432740003 +-0.0182739999 -0.0148919998 0.0317259990 +-0.0182739999 -0.0148919998 0.0182739999 +-0.0182739999 -0.0148919998 0.0067260000 +-0.0182739999 -0.0148919998 -0.0067260000 +-0.0182739999 -0.0148919998 -0.0182739999 +-0.0182739999 -0.0148919998 -0.0317259990 +-0.0182739999 -0.0148919998 -0.0432740003 +-0.0182739999 -0.0182739999 0.0398919992 +-0.0182739999 -0.0182739999 0.0351080000 +-0.0182739999 -0.0182739999 0.0148919998 +-0.0182739999 -0.0182739999 0.0101079997 +-0.0182739999 -0.0182739999 -0.0101079997 +-0.0182739999 -0.0182739999 -0.0148919998 +-0.0182739999 -0.0182739999 -0.0351080000 +-0.0182739999 -0.0182739999 -0.0398919992 +-0.0182739999 -0.0317259990 0.0148919998 +-0.0182739999 -0.0317259990 0.0101079997 +-0.0182739999 -0.0317259990 -0.0101079997 +-0.0182739999 -0.0317259990 -0.0148919998 +-0.0182739999 -0.0317259990 -0.0351080000 +-0.0182739999 -0.0317259990 -0.0398919992 +-0.0182739999 -0.0351080000 0.0182739999 +-0.0182739999 -0.0351080000 0.0067260000 +-0.0182739999 -0.0351080000 -0.0067260000 +-0.0182739999 -0.0351080000 -0.0182739999 +-0.0182739999 -0.0351080000 -0.0317259990 +-0.0182739999 -0.0351080000 -0.0432740003 +-0.0182739999 -0.0398919992 0.0182739999 +-0.0182739999 -0.0398919992 0.0067260000 +-0.0182739999 -0.0398919992 -0.0067260000 +-0.0182739999 -0.0398919992 -0.0182739999 +-0.0182739999 -0.0398919992 -0.0317259990 +-0.0182739999 -0.0398919992 -0.0432740003 +-0.0182739999 -0.0432740003 0.0148919998 +-0.0182739999 -0.0432740003 0.0101079997 +-0.0182739999 -0.0432740003 -0.0101079997 +-0.0182739999 -0.0432740003 -0.0148919998 +-0.0182739999 -0.0432740003 -0.0351080000 +-0.0182739999 -0.0432740003 -0.0398919992 +-0.0185369998 0.0500000007 0.0391179994 +-0.0185369998 0.0500000007 0.0358819999 +-0.0185369998 0.0500000007 0.0141179999 +-0.0185369998 0.0500000007 0.0108820004 +-0.0185369998 0.0500000007 -0.0108820004 +-0.0185369998 0.0500000007 -0.0141179999 +-0.0185369998 0.0500000007 -0.0358819999 +-0.0185369998 0.0500000007 -0.0391179994 +-0.0185369998 0.0391179994 0.0500000007 +-0.0185369998 0.0391179994 -0.0500000007 +-0.0185369998 0.0358819999 0.0500000007 +-0.0185369998 0.0358819999 -0.0500000007 +-0.0185369998 0.0141179999 -0.0003910000 +-0.0185369998 0.0141179999 -0.0500000007 +-0.0185369998 0.0108820004 -0.0003910000 +-0.0185369998 0.0108820004 -0.0500000007 +-0.0185369998 -0.0000000000 0.0391179994 +-0.0185369998 -0.0000000000 0.0358819999 +-0.0185369998 -0.0000000000 0.0141179999 +-0.0185369998 -0.0000000000 0.0108820004 +-0.0185369998 -0.0108820004 0.0500000007 +-0.0185369998 -0.0108820004 -0.0500000007 +-0.0185369998 -0.0141179999 0.0500000007 +-0.0185369998 -0.0141179999 -0.0500000007 +-0.0185369998 -0.0250000004 0.0391179994 +-0.0185369998 -0.0250000004 0.0358819999 +-0.0185369998 -0.0358819999 0.0212500002 +-0.0185369998 -0.0358819999 -0.0500000007 +-0.0185369998 -0.0391179994 0.0212500002 +-0.0185369998 -0.0391179994 -0.0500000007 +-0.0185369998 -0.0500000007 0.0141179999 +-0.0185369998 -0.0500000007 0.0108820004 +-0.0185369998 -0.0500000007 -0.0108820004 +-0.0185369998 -0.0500000007 -0.0141179999 +-0.0185369998 -0.0500000007 -0.0358819999 +-0.0185369998 -0.0500000007 -0.0391179994 +-0.0185540002 0.0234379992 0.0390530005 +-0.0185540002 0.0234379992 0.0359469987 +-0.0185540002 0.0234379992 0.0140530001 +-0.0185540002 0.0234379992 0.0109470002 +-0.0186299998 0.0436300002 0.0387189984 +-0.0186299998 0.0436300002 0.0362810008 +-0.0186299998 0.0436300002 0.0137189999 +-0.0186299998 0.0436300002 0.0112810005 +-0.0186299998 0.0436300002 -0.0112810005 +-0.0186299998 0.0436300002 -0.0137189999 +-0.0186299998 0.0436300002 -0.0362810008 +-0.0186299998 0.0436300002 -0.0387189984 +-0.0186299998 0.0387189984 0.0436300002 +-0.0186299998 0.0387189984 0.0313699991 +-0.0186299998 0.0387189984 0.0186299998 +-0.0186299998 0.0387189984 0.0063700001 +-0.0186299998 0.0387189984 -0.0063700001 +-0.0186299998 0.0387189984 -0.0186299998 +-0.0186299998 0.0387189984 -0.0313699991 +-0.0186299998 0.0387189984 -0.0436300002 +-0.0186299998 0.0362810008 0.0436300002 +-0.0186299998 0.0362810008 0.0313699991 +-0.0186299998 0.0362810008 0.0186299998 +-0.0186299998 0.0362810008 0.0063700001 +-0.0186299998 0.0362810008 -0.0063700001 +-0.0186299998 0.0362810008 -0.0186299998 +-0.0186299998 0.0362810008 -0.0313699991 +-0.0186299998 0.0362810008 -0.0436300002 +-0.0186299998 0.0313699991 0.0387189984 +-0.0186299998 0.0313699991 0.0362810008 +-0.0186299998 0.0313699991 0.0137189999 +-0.0186299998 0.0313699991 0.0112810005 +-0.0186299998 0.0313699991 -0.0112810005 +-0.0186299998 0.0313699991 -0.0137189999 +-0.0186299998 0.0313699991 -0.0362810008 +-0.0186299998 0.0313699991 -0.0387189984 +-0.0186299998 0.0186299998 -0.0112810005 +-0.0186299998 0.0186299998 -0.0137189999 +-0.0186299998 0.0186299998 -0.0362810008 +-0.0186299998 0.0186299998 -0.0387189984 +-0.0186299998 0.0137189999 -0.0063700001 +-0.0186299998 0.0137189999 -0.0186299998 +-0.0186299998 0.0137189999 -0.0313699991 +-0.0186299998 0.0137189999 -0.0436300002 +-0.0186299998 0.0112810005 -0.0063700001 +-0.0186299998 0.0112810005 -0.0186299998 +-0.0186299998 0.0112810005 -0.0313699991 +-0.0186299998 0.0112810005 -0.0436300002 +-0.0186299998 0.0063700001 -0.0112810005 +-0.0186299998 0.0063700001 -0.0137189999 +-0.0186299998 0.0063700001 -0.0362810008 +-0.0186299998 0.0063700001 -0.0387189984 +-0.0186299998 -0.0063700001 0.0387189984 +-0.0186299998 -0.0063700001 0.0362810008 +-0.0186299998 -0.0063700001 0.0137189999 +-0.0186299998 -0.0063700001 0.0112810005 +-0.0186299998 -0.0063700001 -0.0112810005 +-0.0186299998 -0.0063700001 -0.0137189999 +-0.0186299998 -0.0063700001 -0.0362810008 +-0.0186299998 -0.0063700001 -0.0387189984 +-0.0186299998 -0.0112810005 0.0436300002 +-0.0186299998 -0.0112810005 0.0313699991 +-0.0186299998 -0.0112810005 0.0186299998 +-0.0186299998 -0.0112810005 0.0063700001 +-0.0186299998 -0.0112810005 -0.0063700001 +-0.0186299998 -0.0112810005 -0.0186299998 +-0.0186299998 -0.0112810005 -0.0313699991 +-0.0186299998 -0.0112810005 -0.0436300002 +-0.0186299998 -0.0137189999 0.0436300002 +-0.0186299998 -0.0137189999 0.0313699991 +-0.0186299998 -0.0137189999 0.0186299998 +-0.0186299998 -0.0137189999 0.0063700001 +-0.0186299998 -0.0137189999 -0.0063700001 +-0.0186299998 -0.0137189999 -0.0186299998 +-0.0186299998 -0.0137189999 -0.0313699991 +-0.0186299998 -0.0137189999 -0.0436300002 +-0.0186299998 -0.0186299998 0.0387189984 +-0.0186299998 -0.0186299998 0.0362810008 +-0.0186299998 -0.0186299998 0.0137189999 +-0.0186299998 -0.0186299998 0.0112810005 +-0.0186299998 -0.0186299998 -0.0112810005 +-0.0186299998 -0.0186299998 -0.0137189999 +-0.0186299998 -0.0186299998 -0.0362810008 +-0.0186299998 -0.0186299998 -0.0387189984 +-0.0186299998 -0.0313699991 0.0137189999 +-0.0186299998 -0.0313699991 0.0112810005 +-0.0186299998 -0.0313699991 -0.0112810005 +-0.0186299998 -0.0313699991 -0.0137189999 +-0.0186299998 -0.0313699991 -0.0362810008 +-0.0186299998 -0.0313699991 -0.0387189984 +-0.0186299998 -0.0362810008 0.0186299998 +-0.0186299998 -0.0362810008 0.0063700001 +-0.0186299998 -0.0362810008 -0.0063700001 +-0.0186299998 -0.0362810008 -0.0186299998 +-0.0186299998 -0.0362810008 -0.0313699991 +-0.0186299998 -0.0362810008 -0.0436300002 +-0.0186299998 -0.0387189984 0.0186299998 +-0.0186299998 -0.0387189984 0.0063700001 +-0.0186299998 -0.0387189984 -0.0063700001 +-0.0186299998 -0.0387189984 -0.0186299998 +-0.0186299998 -0.0387189984 -0.0313699991 +-0.0186299998 -0.0387189984 -0.0436300002 +-0.0186299998 -0.0436300002 0.0137189999 +-0.0186299998 -0.0436300002 0.0112810005 +-0.0186299998 -0.0436300002 -0.0112810005 +-0.0186299998 -0.0436300002 -0.0137189999 +-0.0186299998 -0.0436300002 -0.0362810008 +-0.0186299998 -0.0436300002 -0.0387189984 +-0.0187199991 0.0437199995 0.0381130017 +-0.0187199991 0.0437199995 0.0368870012 +-0.0187199991 0.0437199995 0.0131130004 +-0.0187199991 0.0437199995 0.0118869999 +-0.0187199991 0.0437199995 -0.0118869999 +-0.0187199991 0.0437199995 -0.0131130004 +-0.0187199991 0.0437199995 -0.0368870012 +-0.0187199991 0.0437199995 -0.0381130017 +-0.0187199991 0.0381130017 0.0437199995 +-0.0187199991 0.0381130017 0.0312799998 +-0.0187199991 0.0381130017 0.0187199991 +-0.0187199991 0.0381130017 0.0062799999 +-0.0187199991 0.0381130017 -0.0062799999 +-0.0187199991 0.0381130017 -0.0187199991 +-0.0187199991 0.0381130017 -0.0312799998 +-0.0187199991 0.0381130017 -0.0437199995 +-0.0187199991 0.0368870012 0.0437199995 +-0.0187199991 0.0368870012 0.0312799998 +-0.0187199991 0.0368870012 0.0187199991 +-0.0187199991 0.0368870012 0.0062799999 +-0.0187199991 0.0368870012 -0.0062799999 +-0.0187199991 0.0368870012 -0.0187199991 +-0.0187199991 0.0368870012 -0.0312799998 +-0.0187199991 0.0368870012 -0.0437199995 +-0.0187199991 0.0312799998 0.0381130017 +-0.0187199991 0.0312799998 0.0368870012 +-0.0187199991 0.0312799998 0.0131130004 +-0.0187199991 0.0312799998 0.0118869999 +-0.0187199991 0.0312799998 -0.0118869999 +-0.0187199991 0.0312799998 -0.0131130004 +-0.0187199991 0.0312799998 -0.0368870012 +-0.0187199991 0.0312799998 -0.0381130017 +-0.0187199991 0.0187199991 -0.0118869999 +-0.0187199991 0.0187199991 -0.0131130004 +-0.0187199991 0.0187199991 -0.0368870012 +-0.0187199991 0.0187199991 -0.0381130017 +-0.0187199991 0.0131130004 -0.0062799999 +-0.0187199991 0.0131130004 -0.0187199991 +-0.0187199991 0.0131130004 -0.0312799998 +-0.0187199991 0.0131130004 -0.0437199995 +-0.0187199991 0.0118869999 -0.0062799999 +-0.0187199991 0.0118869999 -0.0187199991 +-0.0187199991 0.0118869999 -0.0312799998 +-0.0187199991 0.0118869999 -0.0437199995 +-0.0187199991 0.0062799999 -0.0118869999 +-0.0187199991 0.0062799999 -0.0131130004 +-0.0187199991 0.0062799999 -0.0368870012 +-0.0187199991 0.0062799999 -0.0381130017 +-0.0187199991 -0.0062799999 0.0381130017 +-0.0187199991 -0.0062799999 0.0368870012 +-0.0187199991 -0.0062799999 0.0131130004 +-0.0187199991 -0.0062799999 0.0118869999 +-0.0187199991 -0.0062799999 -0.0118869999 +-0.0187199991 -0.0062799999 -0.0131130004 +-0.0187199991 -0.0062799999 -0.0368870012 +-0.0187199991 -0.0062799999 -0.0381130017 +-0.0187199991 -0.0118869999 0.0437199995 +-0.0187199991 -0.0118869999 0.0312799998 +-0.0187199991 -0.0118869999 0.0187199991 +-0.0187199991 -0.0118869999 0.0062799999 +-0.0187199991 -0.0118869999 -0.0062799999 +-0.0187199991 -0.0118869999 -0.0187199991 +-0.0187199991 -0.0118869999 -0.0312799998 +-0.0187199991 -0.0118869999 -0.0437199995 +-0.0187199991 -0.0131130004 0.0437199995 +-0.0187199991 -0.0131130004 0.0312799998 +-0.0187199991 -0.0131130004 0.0187199991 +-0.0187199991 -0.0131130004 0.0062799999 +-0.0187199991 -0.0131130004 -0.0062799999 +-0.0187199991 -0.0131130004 -0.0187199991 +-0.0187199991 -0.0131130004 -0.0312799998 +-0.0187199991 -0.0131130004 -0.0437199995 +-0.0187199991 -0.0187199991 0.0381130017 +-0.0187199991 -0.0187199991 0.0368870012 +-0.0187199991 -0.0187199991 0.0131130004 +-0.0187199991 -0.0187199991 0.0118869999 +-0.0187199991 -0.0187199991 -0.0118869999 +-0.0187199991 -0.0187199991 -0.0131130004 +-0.0187199991 -0.0187199991 -0.0368870012 +-0.0187199991 -0.0187199991 -0.0381130017 +-0.0187199991 -0.0312799998 0.0131130004 +-0.0187199991 -0.0312799998 0.0118869999 +-0.0187199991 -0.0312799998 -0.0118869999 +-0.0187199991 -0.0312799998 -0.0131130004 +-0.0187199991 -0.0312799998 -0.0368870012 +-0.0187199991 -0.0312799998 -0.0381130017 +-0.0187199991 -0.0368870012 0.0187199991 +-0.0187199991 -0.0368870012 0.0062799999 +-0.0187199991 -0.0368870012 -0.0062799999 +-0.0187199991 -0.0368870012 -0.0187199991 +-0.0187199991 -0.0368870012 -0.0312799998 +-0.0187199991 -0.0368870012 -0.0437199995 +-0.0187199991 -0.0381130017 0.0187199991 +-0.0187199991 -0.0381130017 0.0062799999 +-0.0187199991 -0.0381130017 -0.0062799999 +-0.0187199991 -0.0381130017 -0.0187199991 +-0.0187199991 -0.0381130017 -0.0312799998 +-0.0187199991 -0.0381130017 -0.0437199995 +-0.0187199991 -0.0437199995 0.0131130004 +-0.0187199991 -0.0437199995 0.0118869999 +-0.0187199991 -0.0437199995 -0.0118869999 +-0.0187199991 -0.0437199995 -0.0131130004 +-0.0187199991 -0.0437199995 -0.0368870012 +-0.0187199991 -0.0437199995 -0.0381130017 +-0.0187500007 0.0500000007 0.0375000015 +-0.0187500007 0.0500000007 0.0125000002 +-0.0187500007 0.0500000007 -0.0125000002 +-0.0187500007 0.0500000007 -0.0375000015 +-0.0187500007 0.0437499993 0.0375000015 +-0.0187500007 0.0437499993 0.0125000002 +-0.0187500007 0.0437499993 -0.0125000002 +-0.0187500007 0.0437499993 -0.0375000015 +-0.0187500007 0.0375000015 0.0500000007 +-0.0187500007 0.0375000015 0.0437499993 +-0.0187500007 0.0375000015 0.0312500000 +-0.0187500007 0.0375000015 0.0187500007 +-0.0187500007 0.0375000015 0.0062500001 +-0.0187500007 0.0375000015 -0.0062500001 +-0.0187500007 0.0375000015 -0.0187500007 +-0.0187500007 0.0375000015 -0.0312500000 +-0.0187500007 0.0375000015 -0.0437499993 +-0.0187500007 0.0375000015 -0.0500000007 +-0.0187500007 0.0312500000 0.0375000015 +-0.0187500007 0.0312500000 0.0125000002 +-0.0187500007 0.0312500000 -0.0125000002 +-0.0187500007 0.0312500000 -0.0375000015 +-0.0187500007 0.0234379992 0.0375000015 +-0.0187500007 0.0234379992 0.0125000002 +-0.0187500007 0.0187500007 -0.0125000002 +-0.0187500007 0.0187500007 -0.0375000015 +-0.0187500007 0.0125000002 -0.0003910000 +-0.0187500007 0.0125000002 -0.0062500001 +-0.0187500007 0.0125000002 -0.0187500007 +-0.0187500007 0.0125000002 -0.0312500000 +-0.0187500007 0.0125000002 -0.0437499993 +-0.0187500007 0.0125000002 -0.0500000007 +-0.0187500007 0.0062500001 -0.0125000002 +-0.0187500007 0.0062500001 -0.0375000015 +-0.0187500007 -0.0000000000 0.0375000015 +-0.0187500007 -0.0000000000 0.0125000002 +-0.0187500007 -0.0062500001 0.0375000015 +-0.0187500007 -0.0062500001 0.0125000002 +-0.0187500007 -0.0062500001 -0.0125000002 +-0.0187500007 -0.0062500001 -0.0375000015 +-0.0187500007 -0.0125000002 0.0500000007 +-0.0187500007 -0.0125000002 0.0437499993 +-0.0187500007 -0.0125000002 0.0312500000 +-0.0187500007 -0.0125000002 0.0187500007 +-0.0187500007 -0.0125000002 0.0062500001 +-0.0187500007 -0.0125000002 -0.0062500001 +-0.0187500007 -0.0125000002 -0.0187500007 +-0.0187500007 -0.0125000002 -0.0312500000 +-0.0187500007 -0.0125000002 -0.0437499993 +-0.0187500007 -0.0125000002 -0.0500000007 +-0.0187500007 -0.0187500007 0.0375000015 +-0.0187500007 -0.0187500007 0.0125000002 +-0.0187500007 -0.0187500007 -0.0125000002 +-0.0187500007 -0.0187500007 -0.0375000015 +-0.0187500007 -0.0250000004 0.0375000015 +-0.0187500007 -0.0312500000 0.0125000002 +-0.0187500007 -0.0312500000 -0.0125000002 +-0.0187500007 -0.0312500000 -0.0375000015 +-0.0187500007 -0.0375000015 0.0212500002 +-0.0187500007 -0.0375000015 0.0187500007 +-0.0187500007 -0.0375000015 0.0062500001 +-0.0187500007 -0.0375000015 -0.0062500001 +-0.0187500007 -0.0375000015 -0.0187500007 +-0.0187500007 -0.0375000015 -0.0312500000 +-0.0187500007 -0.0375000015 -0.0437499993 +-0.0187500007 -0.0375000015 -0.0500000007 +-0.0187500007 -0.0437499993 0.0125000002 +-0.0187500007 -0.0437499993 -0.0125000002 +-0.0187500007 -0.0437499993 -0.0375000015 +-0.0187500007 -0.0500000007 0.0125000002 +-0.0187500007 -0.0500000007 -0.0125000002 +-0.0187500007 -0.0500000007 -0.0375000015 +-0.0300479997 0.0234379992 0.0500000007 +-0.0300479997 0.0234379992 -0.0003910000 +-0.0312500000 0.0500000007 0.0375000015 +-0.0312500000 0.0500000007 0.0125000002 +-0.0312500000 0.0500000007 -0.0125000002 +-0.0312500000 0.0500000007 -0.0375000015 +-0.0312500000 0.0437499993 0.0375000015 +-0.0312500000 0.0437499993 0.0125000002 +-0.0312500000 0.0437499993 -0.0125000002 +-0.0312500000 0.0437499993 -0.0375000015 +-0.0312500000 0.0375000015 0.0500000007 +-0.0312500000 0.0375000015 0.0437499993 +-0.0312500000 0.0375000015 0.0312500000 +-0.0312500000 0.0375000015 0.0187500007 +-0.0312500000 0.0375000015 0.0062500001 +-0.0312500000 0.0375000015 -0.0062500001 +-0.0312500000 0.0375000015 -0.0187500007 +-0.0312500000 0.0375000015 -0.0312500000 +-0.0312500000 0.0375000015 -0.0437499993 +-0.0312500000 0.0375000015 -0.0500000007 +-0.0312500000 0.0312500000 0.0375000015 +-0.0312500000 0.0312500000 0.0125000002 +-0.0312500000 0.0312500000 -0.0125000002 +-0.0312500000 0.0312500000 -0.0375000015 +-0.0312500000 0.0241310000 0.0375000015 +-0.0312500000 0.0241310000 0.0125000002 +-0.0312500000 0.0187500007 -0.0125000002 +-0.0312500000 0.0187500007 -0.0375000015 +-0.0312500000 0.0125000002 -0.0003910000 +-0.0312500000 0.0125000002 -0.0062500001 +-0.0312500000 0.0125000002 -0.0187500007 +-0.0312500000 0.0125000002 -0.0312500000 +-0.0312500000 0.0125000002 -0.0437499993 +-0.0312500000 0.0125000002 -0.0500000007 +-0.0312500000 0.0062500001 -0.0125000002 +-0.0312500000 0.0062500001 -0.0375000015 +-0.0312500000 -0.0062500001 0.0375000015 +-0.0312500000 -0.0062500001 0.0125000002 +-0.0312500000 -0.0062500001 -0.0125000002 +-0.0312500000 -0.0062500001 -0.0375000015 +-0.0312500000 -0.0125000002 0.0500000007 +-0.0312500000 -0.0125000002 0.0437499993 +-0.0312500000 -0.0125000002 0.0312500000 +-0.0312500000 -0.0125000002 0.0187500007 +-0.0312500000 -0.0125000002 0.0062500001 +-0.0312500000 -0.0125000002 -0.0062500001 +-0.0312500000 -0.0125000002 -0.0187500007 +-0.0312500000 -0.0125000002 -0.0312500000 +-0.0312500000 -0.0125000002 -0.0437499993 +-0.0312500000 -0.0125000002 -0.0500000007 +-0.0312500000 -0.0187500007 0.0375000015 +-0.0312500000 -0.0187500007 0.0125000002 +-0.0312500000 -0.0187500007 -0.0125000002 +-0.0312500000 -0.0187500007 -0.0375000015 +-0.0312500000 -0.0250000004 0.0375000015 +-0.0312500000 -0.0312500000 0.0125000002 +-0.0312500000 -0.0312500000 -0.0125000002 +-0.0312500000 -0.0312500000 -0.0375000015 +-0.0312500000 -0.0375000015 0.0212500002 +-0.0312500000 -0.0375000015 0.0187500007 +-0.0312500000 -0.0375000015 0.0062500001 +-0.0312500000 -0.0375000015 -0.0062500001 +-0.0312500000 -0.0375000015 -0.0187500007 +-0.0312500000 -0.0375000015 -0.0312500000 +-0.0312500000 -0.0375000015 -0.0437499993 +-0.0312500000 -0.0375000015 -0.0500000007 +-0.0312500000 -0.0437499993 0.0125000002 +-0.0312500000 -0.0437499993 -0.0125000002 +-0.0312500000 -0.0437499993 -0.0375000015 +-0.0312500000 -0.0500000007 0.0125000002 +-0.0312500000 -0.0500000007 -0.0125000002 +-0.0312500000 -0.0500000007 -0.0375000015 +-0.0312799998 0.0437199995 0.0381130017 +-0.0312799998 0.0437199995 0.0368870012 +-0.0312799998 0.0437199995 0.0131130004 +-0.0312799998 0.0437199995 0.0118869999 +-0.0312799998 0.0437199995 -0.0118869999 +-0.0312799998 0.0437199995 -0.0131130004 +-0.0312799998 0.0437199995 -0.0368870012 +-0.0312799998 0.0437199995 -0.0381130017 +-0.0312799998 0.0381130017 0.0437199995 +-0.0312799998 0.0381130017 0.0312799998 +-0.0312799998 0.0381130017 0.0187199991 +-0.0312799998 0.0381130017 0.0062799999 +-0.0312799998 0.0381130017 -0.0062799999 +-0.0312799998 0.0381130017 -0.0187199991 +-0.0312799998 0.0381130017 -0.0312799998 +-0.0312799998 0.0381130017 -0.0437199995 +-0.0312799998 0.0368870012 0.0437199995 +-0.0312799998 0.0368870012 0.0312799998 +-0.0312799998 0.0368870012 0.0187199991 +-0.0312799998 0.0368870012 0.0062799999 +-0.0312799998 0.0368870012 -0.0062799999 +-0.0312799998 0.0368870012 -0.0187199991 +-0.0312799998 0.0368870012 -0.0312799998 +-0.0312799998 0.0368870012 -0.0437199995 +-0.0312799998 0.0312799998 0.0381130017 +-0.0312799998 0.0312799998 0.0368870012 +-0.0312799998 0.0312799998 0.0131130004 +-0.0312799998 0.0312799998 0.0118869999 +-0.0312799998 0.0312799998 -0.0118869999 +-0.0312799998 0.0312799998 -0.0131130004 +-0.0312799998 0.0312799998 -0.0368870012 +-0.0312799998 0.0312799998 -0.0381130017 +-0.0312799998 0.0187199991 -0.0118869999 +-0.0312799998 0.0187199991 -0.0131130004 +-0.0312799998 0.0187199991 -0.0368870012 +-0.0312799998 0.0187199991 -0.0381130017 +-0.0312799998 0.0131130004 -0.0062799999 +-0.0312799998 0.0131130004 -0.0187199991 +-0.0312799998 0.0131130004 -0.0312799998 +-0.0312799998 0.0131130004 -0.0437199995 +-0.0312799998 0.0118869999 -0.0062799999 +-0.0312799998 0.0118869999 -0.0187199991 +-0.0312799998 0.0118869999 -0.0312799998 +-0.0312799998 0.0118869999 -0.0437199995 +-0.0312799998 0.0062799999 -0.0118869999 +-0.0312799998 0.0062799999 -0.0131130004 +-0.0312799998 0.0062799999 -0.0368870012 +-0.0312799998 0.0062799999 -0.0381130017 +-0.0312799998 -0.0062799999 0.0381130017 +-0.0312799998 -0.0062799999 0.0368870012 +-0.0312799998 -0.0062799999 0.0131130004 +-0.0312799998 -0.0062799999 0.0118869999 +-0.0312799998 -0.0062799999 -0.0118869999 +-0.0312799998 -0.0062799999 -0.0131130004 +-0.0312799998 -0.0062799999 -0.0368870012 +-0.0312799998 -0.0062799999 -0.0381130017 +-0.0312799998 -0.0118869999 0.0437199995 +-0.0312799998 -0.0118869999 0.0312799998 +-0.0312799998 -0.0118869999 0.0187199991 +-0.0312799998 -0.0118869999 0.0062799999 +-0.0312799998 -0.0118869999 -0.0062799999 +-0.0312799998 -0.0118869999 -0.0187199991 +-0.0312799998 -0.0118869999 -0.0312799998 +-0.0312799998 -0.0118869999 -0.0437199995 +-0.0312799998 -0.0131130004 0.0437199995 +-0.0312799998 -0.0131130004 0.0312799998 +-0.0312799998 -0.0131130004 0.0187199991 +-0.0312799998 -0.0131130004 0.0062799999 +-0.0312799998 -0.0131130004 -0.0062799999 +-0.0312799998 -0.0131130004 -0.0187199991 +-0.0312799998 -0.0131130004 -0.0312799998 +-0.0312799998 -0.0131130004 -0.0437199995 +-0.0312799998 -0.0187199991 0.0381130017 +-0.0312799998 -0.0187199991 0.0368870012 +-0.0312799998 -0.0187199991 0.0131130004 +-0.0312799998 -0.0187199991 0.0118869999 +-0.0312799998 -0.0187199991 -0.0118869999 +-0.0312799998 -0.0187199991 -0.0131130004 +-0.0312799998 -0.0187199991 -0.0368870012 +-0.0312799998 -0.0187199991 -0.0381130017 +-0.0312799998 -0.0312799998 0.0131130004 +-0.0312799998 -0.0312799998 0.0118869999 +-0.0312799998 -0.0312799998 -0.0118869999 +-0.0312799998 -0.0312799998 -0.0131130004 +-0.0312799998 -0.0312799998 -0.0368870012 +-0.0312799998 -0.0312799998 -0.0381130017 +-0.0312799998 -0.0368870012 0.0187199991 +-0.0312799998 -0.0368870012 0.0062799999 +-0.0312799998 -0.0368870012 -0.0062799999 +-0.0312799998 -0.0368870012 -0.0187199991 +-0.0312799998 -0.0368870012 -0.0312799998 +-0.0312799998 -0.0368870012 -0.0437199995 +-0.0312799998 -0.0381130017 0.0187199991 +-0.0312799998 -0.0381130017 0.0062799999 +-0.0312799998 -0.0381130017 -0.0062799999 +-0.0312799998 -0.0381130017 -0.0187199991 +-0.0312799998 -0.0381130017 -0.0312799998 +-0.0312799998 -0.0381130017 -0.0437199995 +-0.0312799998 -0.0437199995 0.0131130004 +-0.0312799998 -0.0437199995 0.0118869999 +-0.0312799998 -0.0437199995 -0.0118869999 +-0.0312799998 -0.0437199995 -0.0131130004 +-0.0312799998 -0.0437199995 -0.0368870012 +-0.0312799998 -0.0437199995 -0.0381130017 +-0.0312980004 -0.0000000000 0.0382729992 +-0.0312980004 -0.0000000000 0.0367270000 +-0.0312980004 -0.0000000000 0.0132729998 +-0.0312980004 -0.0000000000 0.0117269997 +-0.0313600004 0.0241950005 0.0386650003 +-0.0313600004 0.0241950005 0.0363349989 +-0.0313600004 0.0241950005 0.0136650000 +-0.0313600004 0.0241950005 0.0113350004 +-0.0313699991 0.0436300002 0.0387189984 +-0.0313699991 0.0436300002 0.0362810008 +-0.0313699991 0.0436300002 0.0137189999 +-0.0313699991 0.0436300002 0.0112810005 +-0.0313699991 0.0436300002 -0.0112810005 +-0.0313699991 0.0436300002 -0.0137189999 +-0.0313699991 0.0436300002 -0.0362810008 +-0.0313699991 0.0436300002 -0.0387189984 +-0.0313699991 0.0387189984 0.0436300002 +-0.0313699991 0.0387189984 0.0313699991 +-0.0313699991 0.0387189984 0.0186299998 +-0.0313699991 0.0387189984 0.0063700001 +-0.0313699991 0.0387189984 -0.0063700001 +-0.0313699991 0.0387189984 -0.0186299998 +-0.0313699991 0.0387189984 -0.0313699991 +-0.0313699991 0.0387189984 -0.0436300002 +-0.0313699991 0.0362810008 0.0436300002 +-0.0313699991 0.0362810008 0.0313699991 +-0.0313699991 0.0362810008 0.0186299998 +-0.0313699991 0.0362810008 0.0063700001 +-0.0313699991 0.0362810008 -0.0063700001 +-0.0313699991 0.0362810008 -0.0186299998 +-0.0313699991 0.0362810008 -0.0313699991 +-0.0313699991 0.0362810008 -0.0436300002 +-0.0313699991 0.0313699991 0.0387189984 +-0.0313699991 0.0313699991 0.0362810008 +-0.0313699991 0.0313699991 0.0137189999 +-0.0313699991 0.0313699991 0.0112810005 +-0.0313699991 0.0313699991 -0.0112810005 +-0.0313699991 0.0313699991 -0.0137189999 +-0.0313699991 0.0313699991 -0.0362810008 +-0.0313699991 0.0313699991 -0.0387189984 +-0.0313699991 0.0186299998 -0.0112810005 +-0.0313699991 0.0186299998 -0.0137189999 +-0.0313699991 0.0186299998 -0.0362810008 +-0.0313699991 0.0186299998 -0.0387189984 +-0.0313699991 0.0137189999 -0.0063700001 +-0.0313699991 0.0137189999 -0.0186299998 +-0.0313699991 0.0137189999 -0.0313699991 +-0.0313699991 0.0137189999 -0.0436300002 +-0.0313699991 0.0112810005 -0.0063700001 +-0.0313699991 0.0112810005 -0.0186299998 +-0.0313699991 0.0112810005 -0.0313699991 +-0.0313699991 0.0112810005 -0.0436300002 +-0.0313699991 0.0063700001 -0.0112810005 +-0.0313699991 0.0063700001 -0.0137189999 +-0.0313699991 0.0063700001 -0.0362810008 +-0.0313699991 0.0063700001 -0.0387189984 +-0.0313699991 -0.0063700001 0.0387189984 +-0.0313699991 -0.0063700001 0.0362810008 +-0.0313699991 -0.0063700001 0.0137189999 +-0.0313699991 -0.0063700001 0.0112810005 +-0.0313699991 -0.0063700001 -0.0112810005 +-0.0313699991 -0.0063700001 -0.0137189999 +-0.0313699991 -0.0063700001 -0.0362810008 +-0.0313699991 -0.0063700001 -0.0387189984 +-0.0313699991 -0.0112810005 0.0436300002 +-0.0313699991 -0.0112810005 0.0313699991 +-0.0313699991 -0.0112810005 0.0186299998 +-0.0313699991 -0.0112810005 0.0063700001 +-0.0313699991 -0.0112810005 -0.0063700001 +-0.0313699991 -0.0112810005 -0.0186299998 +-0.0313699991 -0.0112810005 -0.0313699991 +-0.0313699991 -0.0112810005 -0.0436300002 +-0.0313699991 -0.0137189999 0.0436300002 +-0.0313699991 -0.0137189999 0.0313699991 +-0.0313699991 -0.0137189999 0.0186299998 +-0.0313699991 -0.0137189999 0.0063700001 +-0.0313699991 -0.0137189999 -0.0063700001 +-0.0313699991 -0.0137189999 -0.0186299998 +-0.0313699991 -0.0137189999 -0.0313699991 +-0.0313699991 -0.0137189999 -0.0436300002 +-0.0313699991 -0.0186299998 0.0387189984 +-0.0313699991 -0.0186299998 0.0362810008 +-0.0313699991 -0.0186299998 0.0137189999 +-0.0313699991 -0.0186299998 0.0112810005 +-0.0313699991 -0.0186299998 -0.0112810005 +-0.0313699991 -0.0186299998 -0.0137189999 +-0.0313699991 -0.0186299998 -0.0362810008 +-0.0313699991 -0.0186299998 -0.0387189984 +-0.0313699991 -0.0313699991 0.0137189999 +-0.0313699991 -0.0313699991 0.0112810005 +-0.0313699991 -0.0313699991 -0.0112810005 +-0.0313699991 -0.0313699991 -0.0137189999 +-0.0313699991 -0.0313699991 -0.0362810008 +-0.0313699991 -0.0313699991 -0.0387189984 +-0.0313699991 -0.0362810008 0.0186299998 +-0.0313699991 -0.0362810008 0.0063700001 +-0.0313699991 -0.0362810008 -0.0063700001 +-0.0313699991 -0.0362810008 -0.0186299998 +-0.0313699991 -0.0362810008 -0.0313699991 +-0.0313699991 -0.0362810008 -0.0436300002 +-0.0313699991 -0.0387189984 0.0186299998 +-0.0313699991 -0.0387189984 0.0063700001 +-0.0313699991 -0.0387189984 -0.0063700001 +-0.0313699991 -0.0387189984 -0.0186299998 +-0.0313699991 -0.0387189984 -0.0313699991 +-0.0313699991 -0.0387189984 -0.0436300002 +-0.0313699991 -0.0436300002 0.0137189999 +-0.0313699991 -0.0436300002 0.0112810005 +-0.0313699991 -0.0436300002 -0.0112810005 +-0.0313699991 -0.0436300002 -0.0137189999 +-0.0313699991 -0.0436300002 -0.0362810008 +-0.0313699991 -0.0436300002 -0.0387189984 +-0.0314630009 0.0500000007 0.0391179994 +-0.0314630009 0.0500000007 0.0358819999 +-0.0314630009 0.0500000007 0.0141179999 +-0.0314630009 0.0500000007 0.0108820004 +-0.0314630009 0.0500000007 -0.0108820004 +-0.0314630009 0.0500000007 -0.0141179999 +-0.0314630009 0.0500000007 -0.0358819999 +-0.0314630009 0.0500000007 -0.0391179994 +-0.0314630009 0.0391179994 0.0500000007 +-0.0314630009 0.0391179994 -0.0500000007 +-0.0314630009 0.0358819999 0.0500000007 +-0.0314630009 0.0358819999 -0.0500000007 +-0.0314630009 0.0141179999 -0.0003910000 +-0.0314630009 0.0141179999 -0.0500000007 +-0.0314630009 0.0108820004 -0.0003910000 +-0.0314630009 0.0108820004 -0.0500000007 +-0.0314630009 -0.0108820004 0.0500000007 +-0.0314630009 -0.0108820004 -0.0500000007 +-0.0314630009 -0.0141179999 0.0500000007 +-0.0314630009 -0.0141179999 -0.0500000007 +-0.0314630009 -0.0250000004 0.0391179994 +-0.0314630009 -0.0250000004 0.0358819999 +-0.0314630009 -0.0358819999 0.0212500002 +-0.0314630009 -0.0358819999 -0.0500000007 +-0.0314630009 -0.0391179994 0.0212500002 +-0.0314630009 -0.0391179994 -0.0500000007 +-0.0314630009 -0.0500000007 0.0141179999 +-0.0314630009 -0.0500000007 0.0108820004 +-0.0314630009 -0.0500000007 -0.0108820004 +-0.0314630009 -0.0500000007 -0.0141179999 +-0.0314630009 -0.0500000007 -0.0358819999 +-0.0314630009 -0.0500000007 -0.0391179994 +-0.0316779986 -0.0000000000 0.0397729985 +-0.0316779986 -0.0000000000 0.0352270007 +-0.0316779986 -0.0000000000 0.0147730000 +-0.0316779986 -0.0000000000 0.0102270003 +-0.0316840000 0.0243820008 0.0397889987 +-0.0316840000 0.0243820008 0.0352110006 +-0.0316840000 0.0243820008 0.0147890002 +-0.0316840000 0.0243820008 0.0102110002 +-0.0317259990 0.0432740003 0.0398919992 +-0.0317259990 0.0432740003 0.0351080000 +-0.0317259990 0.0432740003 0.0148919998 +-0.0317259990 0.0432740003 0.0101079997 +-0.0317259990 0.0432740003 -0.0101079997 +-0.0317259990 0.0432740003 -0.0148919998 +-0.0317259990 0.0432740003 -0.0351080000 +-0.0317259990 0.0432740003 -0.0398919992 +-0.0317259990 0.0398919992 0.0432740003 +-0.0317259990 0.0398919992 0.0317259990 +-0.0317259990 0.0398919992 0.0182739999 +-0.0317259990 0.0398919992 0.0067260000 +-0.0317259990 0.0398919992 -0.0067260000 +-0.0317259990 0.0398919992 -0.0182739999 +-0.0317259990 0.0398919992 -0.0317259990 +-0.0317259990 0.0398919992 -0.0432740003 +-0.0317259990 0.0351080000 0.0432740003 +-0.0317259990 0.0351080000 0.0317259990 +-0.0317259990 0.0351080000 0.0182739999 +-0.0317259990 0.0351080000 0.0067260000 +-0.0317259990 0.0351080000 -0.0067260000 +-0.0317259990 0.0351080000 -0.0182739999 +-0.0317259990 0.0351080000 -0.0317259990 +-0.0317259990 0.0351080000 -0.0432740003 +-0.0317259990 0.0317259990 0.0398919992 +-0.0317259990 0.0317259990 0.0351080000 +-0.0317259990 0.0317259990 0.0148919998 +-0.0317259990 0.0317259990 0.0101079997 +-0.0317259990 0.0317259990 -0.0101079997 +-0.0317259990 0.0317259990 -0.0148919998 +-0.0317259990 0.0317259990 -0.0351080000 +-0.0317259990 0.0317259990 -0.0398919992 +-0.0317259990 0.0182739999 -0.0101079997 +-0.0317259990 0.0182739999 -0.0148919998 +-0.0317259990 0.0182739999 -0.0351080000 +-0.0317259990 0.0182739999 -0.0398919992 +-0.0317259990 0.0148919998 -0.0067260000 +-0.0317259990 0.0148919998 -0.0182739999 +-0.0317259990 0.0148919998 -0.0317259990 +-0.0317259990 0.0148919998 -0.0432740003 +-0.0317259990 0.0101079997 -0.0067260000 +-0.0317259990 0.0101079997 -0.0182739999 +-0.0317259990 0.0101079997 -0.0317259990 +-0.0317259990 0.0101079997 -0.0432740003 +-0.0317259990 0.0067260000 -0.0101079997 +-0.0317259990 0.0067260000 -0.0148919998 +-0.0317259990 0.0067260000 -0.0351080000 +-0.0317259990 0.0067260000 -0.0398919992 +-0.0317259990 -0.0067260000 0.0398919992 +-0.0317259990 -0.0067260000 0.0351080000 +-0.0317259990 -0.0067260000 0.0148919998 +-0.0317259990 -0.0067260000 0.0101079997 +-0.0317259990 -0.0067260000 -0.0101079997 +-0.0317259990 -0.0067260000 -0.0148919998 +-0.0317259990 -0.0067260000 -0.0351080000 +-0.0317259990 -0.0067260000 -0.0398919992 +-0.0317259990 -0.0101079997 0.0432740003 +-0.0317259990 -0.0101079997 0.0317259990 +-0.0317259990 -0.0101079997 0.0182739999 +-0.0317259990 -0.0101079997 0.0067260000 +-0.0317259990 -0.0101079997 -0.0067260000 +-0.0317259990 -0.0101079997 -0.0182739999 +-0.0317259990 -0.0101079997 -0.0317259990 +-0.0317259990 -0.0101079997 -0.0432740003 +-0.0317259990 -0.0148919998 0.0432740003 +-0.0317259990 -0.0148919998 0.0317259990 +-0.0317259990 -0.0148919998 0.0182739999 +-0.0317259990 -0.0148919998 0.0067260000 +-0.0317259990 -0.0148919998 -0.0067260000 +-0.0317259990 -0.0148919998 -0.0182739999 +-0.0317259990 -0.0148919998 -0.0317259990 +-0.0317259990 -0.0148919998 -0.0432740003 +-0.0317259990 -0.0182739999 0.0398919992 +-0.0317259990 -0.0182739999 0.0351080000 +-0.0317259990 -0.0182739999 0.0148919998 +-0.0317259990 -0.0182739999 0.0101079997 +-0.0317259990 -0.0182739999 -0.0101079997 +-0.0317259990 -0.0182739999 -0.0148919998 +-0.0317259990 -0.0182739999 -0.0351080000 +-0.0317259990 -0.0182739999 -0.0398919992 +-0.0317259990 -0.0317259990 0.0148919998 +-0.0317259990 -0.0317259990 0.0101079997 +-0.0317259990 -0.0317259990 -0.0101079997 +-0.0317259990 -0.0317259990 -0.0148919998 +-0.0317259990 -0.0317259990 -0.0351080000 +-0.0317259990 -0.0317259990 -0.0398919992 +-0.0317259990 -0.0351080000 0.0182739999 +-0.0317259990 -0.0351080000 0.0067260000 +-0.0317259990 -0.0351080000 -0.0067260000 +-0.0317259990 -0.0351080000 -0.0182739999 +-0.0317259990 -0.0351080000 -0.0317259990 +-0.0317259990 -0.0351080000 -0.0432740003 +-0.0317259990 -0.0398919992 0.0182739999 +-0.0317259990 -0.0398919992 0.0067260000 +-0.0317259990 -0.0398919992 -0.0067260000 +-0.0317259990 -0.0398919992 -0.0182739999 +-0.0317259990 -0.0398919992 -0.0317259990 +-0.0317259990 -0.0398919992 -0.0432740003 +-0.0317259990 -0.0432740003 0.0148919998 +-0.0317259990 -0.0432740003 0.0101079997 +-0.0317259990 -0.0432740003 -0.0101079997 +-0.0317259990 -0.0432740003 -0.0148919998 +-0.0317259990 -0.0432740003 -0.0351080000 +-0.0317259990 -0.0432740003 -0.0398919992 +-0.0320869982 0.0500000007 0.0406249985 +-0.0320869982 0.0500000007 0.0343750007 +-0.0320869982 0.0500000007 0.0156250000 +-0.0320869982 0.0500000007 0.0093750004 +-0.0320869982 0.0500000007 -0.0093750004 +-0.0320869982 0.0500000007 -0.0156250000 +-0.0320869982 0.0500000007 -0.0343750007 +-0.0320869982 0.0500000007 -0.0406249985 +-0.0320869982 0.0406249985 0.0500000007 +-0.0320869982 0.0406249985 -0.0500000007 +-0.0320869982 0.0343750007 0.0500000007 +-0.0320869982 0.0343750007 -0.0500000007 +-0.0320869982 0.0156250000 -0.0003910000 +-0.0320869982 0.0156250000 -0.0500000007 +-0.0320869982 0.0093750004 -0.0003910000 +-0.0320869982 0.0093750004 -0.0500000007 +-0.0320869982 -0.0093750004 0.0500000007 +-0.0320869982 -0.0093750004 -0.0500000007 +-0.0320869982 -0.0156250000 0.0500000007 +-0.0320869982 -0.0156250000 -0.0500000007 +-0.0320869982 -0.0250000004 0.0406249985 +-0.0320869982 -0.0250000004 0.0343750007 +-0.0320869982 -0.0343750007 0.0212500002 +-0.0320869982 -0.0343750007 -0.0500000007 +-0.0320869982 -0.0406249985 0.0212500002 +-0.0320869982 -0.0406249985 -0.0500000007 +-0.0320869982 -0.0500000007 0.0156250000 +-0.0320869982 -0.0500000007 0.0093750004 +-0.0320869982 -0.0500000007 -0.0093750004 +-0.0320869982 -0.0500000007 -0.0156250000 +-0.0320869982 -0.0500000007 -0.0343750007 +-0.0320869982 -0.0500000007 -0.0406249985 +-0.0322129987 0.0246869996 0.0408330001 +-0.0322129987 0.0246869996 0.0341669992 +-0.0322129987 0.0246869996 0.0158329997 +-0.0322129987 0.0246869996 0.0091669997 +-0.0323030017 0.0426970012 0.0409720019 +-0.0323030017 0.0426970012 0.0340280011 +-0.0323030017 0.0426970012 0.0159719996 +-0.0323030017 0.0426970012 0.0090279998 +-0.0323030017 0.0426970012 -0.0090279998 +-0.0323030017 0.0426970012 -0.0159719996 +-0.0323030017 0.0426970012 -0.0340280011 +-0.0323030017 0.0426970012 -0.0409720019 +-0.0323030017 0.0409720019 0.0426970012 +-0.0323030017 0.0409720019 0.0323030017 +-0.0323030017 0.0409720019 0.0176970009 +-0.0323030017 0.0409720019 0.0073030000 +-0.0323030017 0.0409720019 -0.0073030000 +-0.0323030017 0.0409720019 -0.0176970009 +-0.0323030017 0.0409720019 -0.0323030017 +-0.0323030017 0.0409720019 -0.0426970012 +-0.0323030017 0.0340280011 0.0426970012 +-0.0323030017 0.0340280011 0.0323030017 +-0.0323030017 0.0340280011 0.0176970009 +-0.0323030017 0.0340280011 0.0073030000 +-0.0323030017 0.0340280011 -0.0073030000 +-0.0323030017 0.0340280011 -0.0176970009 +-0.0323030017 0.0340280011 -0.0323030017 +-0.0323030017 0.0340280011 -0.0426970012 +-0.0323030017 0.0323030017 0.0409720019 +-0.0323030017 0.0323030017 0.0340280011 +-0.0323030017 0.0323030017 0.0159719996 +-0.0323030017 0.0323030017 0.0090279998 +-0.0323030017 0.0323030017 -0.0090279998 +-0.0323030017 0.0323030017 -0.0159719996 +-0.0323030017 0.0323030017 -0.0340280011 +-0.0323030017 0.0323030017 -0.0409720019 +-0.0323030017 0.0176970009 -0.0090279998 +-0.0323030017 0.0176970009 -0.0159719996 +-0.0323030017 0.0176970009 -0.0340280011 +-0.0323030017 0.0176970009 -0.0409720019 +-0.0323030017 0.0159719996 -0.0073030000 +-0.0323030017 0.0159719996 -0.0176970009 +-0.0323030017 0.0159719996 -0.0323030017 +-0.0323030017 0.0159719996 -0.0426970012 +-0.0323030017 0.0090279998 -0.0073030000 +-0.0323030017 0.0090279998 -0.0176970009 +-0.0323030017 0.0090279998 -0.0323030017 +-0.0323030017 0.0090279998 -0.0426970012 +-0.0323030017 0.0073030000 -0.0090279998 +-0.0323030017 0.0073030000 -0.0159719996 +-0.0323030017 0.0073030000 -0.0340280011 +-0.0323030017 0.0073030000 -0.0409720019 +-0.0323030017 -0.0073030000 0.0409720019 +-0.0323030017 -0.0073030000 0.0340280011 +-0.0323030017 -0.0073030000 0.0159719996 +-0.0323030017 -0.0073030000 0.0090279998 +-0.0323030017 -0.0073030000 -0.0090279998 +-0.0323030017 -0.0073030000 -0.0159719996 +-0.0323030017 -0.0073030000 -0.0340280011 +-0.0323030017 -0.0073030000 -0.0409720019 +-0.0323030017 -0.0090279998 0.0426970012 +-0.0323030017 -0.0090279998 0.0323030017 +-0.0323030017 -0.0090279998 0.0176970009 +-0.0323030017 -0.0090279998 0.0073030000 +-0.0323030017 -0.0090279998 -0.0073030000 +-0.0323030017 -0.0090279998 -0.0176970009 +-0.0323030017 -0.0090279998 -0.0323030017 +-0.0323030017 -0.0090279998 -0.0426970012 +-0.0323030017 -0.0159719996 0.0426970012 +-0.0323030017 -0.0159719996 0.0323030017 +-0.0323030017 -0.0159719996 0.0176970009 +-0.0323030017 -0.0159719996 0.0073030000 +-0.0323030017 -0.0159719996 -0.0073030000 +-0.0323030017 -0.0159719996 -0.0176970009 +-0.0323030017 -0.0159719996 -0.0323030017 +-0.0323030017 -0.0159719996 -0.0426970012 +-0.0323030017 -0.0176970009 0.0409720019 +-0.0323030017 -0.0176970009 0.0340280011 +-0.0323030017 -0.0176970009 0.0159719996 +-0.0323030017 -0.0176970009 0.0090279998 +-0.0323030017 -0.0176970009 -0.0090279998 +-0.0323030017 -0.0176970009 -0.0159719996 +-0.0323030017 -0.0176970009 -0.0340280011 +-0.0323030017 -0.0176970009 -0.0409720019 +-0.0323030017 -0.0323030017 0.0159719996 +-0.0323030017 -0.0323030017 0.0090279998 +-0.0323030017 -0.0323030017 -0.0090279998 +-0.0323030017 -0.0323030017 -0.0159719996 +-0.0323030017 -0.0323030017 -0.0340280011 +-0.0323030017 -0.0323030017 -0.0409720019 +-0.0323030017 -0.0340280011 0.0176970009 +-0.0323030017 -0.0340280011 0.0073030000 +-0.0323030017 -0.0340280011 -0.0073030000 +-0.0323030017 -0.0340280011 -0.0176970009 +-0.0323030017 -0.0340280011 -0.0323030017 +-0.0323030017 -0.0340280011 -0.0426970012 +-0.0323030017 -0.0409720019 0.0176970009 +-0.0323030017 -0.0409720019 0.0073030000 +-0.0323030017 -0.0409720019 -0.0073030000 +-0.0323030017 -0.0409720019 -0.0176970009 +-0.0323030017 -0.0409720019 -0.0323030017 +-0.0323030017 -0.0409720019 -0.0426970012 +-0.0323030017 -0.0426970012 0.0159719996 +-0.0323030017 -0.0426970012 0.0090279998 +-0.0323030017 -0.0426970012 -0.0090279998 +-0.0323030017 -0.0426970012 -0.0159719996 +-0.0323030017 -0.0426970012 -0.0340280011 +-0.0323030017 -0.0426970012 -0.0409720019 +-0.0324149989 -0.0000000000 0.0411330014 +-0.0324149989 -0.0000000000 0.0338670015 +-0.0324149989 -0.0000000000 0.0161329992 +-0.0324149989 -0.0000000000 0.0088670002 +-0.0329269990 0.0251000002 0.0417609997 +-0.0329269990 0.0251000002 0.0332389995 +-0.0329269990 0.0251000002 0.0167609993 +-0.0329269990 0.0251000002 0.0082390001 +-0.0330809988 0.0500000007 0.0419190004 +-0.0330809988 0.0500000007 0.0330809988 +-0.0330809988 0.0500000007 0.0169190001 +-0.0330809988 0.0500000007 0.0080810003 +-0.0330809988 0.0500000007 -0.0080810003 +-0.0330809988 0.0500000007 -0.0169190001 +-0.0330809988 0.0500000007 -0.0330809988 +-0.0330809988 0.0500000007 -0.0419190004 +-0.0330809988 0.0419190004 0.0500000007 +-0.0330809988 0.0419190004 0.0419190004 +-0.0330809988 0.0419190004 0.0330809988 +-0.0330809988 0.0419190004 0.0169190001 +-0.0330809988 0.0419190004 0.0080810003 +-0.0330809988 0.0419190004 -0.0080810003 +-0.0330809988 0.0419190004 -0.0169190001 +-0.0330809988 0.0419190004 -0.0330809988 +-0.0330809988 0.0419190004 -0.0419190004 +-0.0330809988 0.0419190004 -0.0500000007 +-0.0330809988 0.0330809988 0.0500000007 +-0.0330809988 0.0330809988 0.0419190004 +-0.0330809988 0.0330809988 0.0330809988 +-0.0330809988 0.0330809988 0.0169190001 +-0.0330809988 0.0330809988 0.0080810003 +-0.0330809988 0.0330809988 -0.0080810003 +-0.0330809988 0.0330809988 -0.0169190001 +-0.0330809988 0.0330809988 -0.0330809988 +-0.0330809988 0.0330809988 -0.0419190004 +-0.0330809988 0.0330809988 -0.0500000007 +-0.0330809988 0.0169190001 -0.0003910000 +-0.0330809988 0.0169190001 -0.0080810003 +-0.0330809988 0.0169190001 -0.0169190001 +-0.0330809988 0.0169190001 -0.0330809988 +-0.0330809988 0.0169190001 -0.0419190004 +-0.0330809988 0.0169190001 -0.0500000007 +-0.0330809988 0.0080810003 -0.0003910000 +-0.0330809988 0.0080810003 -0.0080810003 +-0.0330809988 0.0080810003 -0.0169190001 +-0.0330809988 0.0080810003 -0.0330809988 +-0.0330809988 0.0080810003 -0.0419190004 +-0.0330809988 0.0080810003 -0.0500000007 +-0.0330809988 -0.0080810003 0.0500000007 +-0.0330809988 -0.0080810003 0.0419190004 +-0.0330809988 -0.0080810003 0.0330809988 +-0.0330809988 -0.0080810003 0.0169190001 +-0.0330809988 -0.0080810003 0.0080810003 +-0.0330809988 -0.0080810003 -0.0080810003 +-0.0330809988 -0.0080810003 -0.0169190001 +-0.0330809988 -0.0080810003 -0.0330809988 +-0.0330809988 -0.0080810003 -0.0419190004 +-0.0330809988 -0.0080810003 -0.0500000007 +-0.0330809988 -0.0169190001 0.0500000007 +-0.0330809988 -0.0169190001 0.0419190004 +-0.0330809988 -0.0169190001 0.0330809988 +-0.0330809988 -0.0169190001 0.0169190001 +-0.0330809988 -0.0169190001 0.0080810003 +-0.0330809988 -0.0169190001 -0.0080810003 +-0.0330809988 -0.0169190001 -0.0169190001 +-0.0330809988 -0.0169190001 -0.0330809988 +-0.0330809988 -0.0169190001 -0.0419190004 +-0.0330809988 -0.0169190001 -0.0500000007 +-0.0330809988 -0.0250000004 0.0419190004 +-0.0330809988 -0.0250000004 0.0330809988 +-0.0330809988 -0.0330809988 0.0212500002 +-0.0330809988 -0.0330809988 0.0169190001 +-0.0330809988 -0.0330809988 0.0080810003 +-0.0330809988 -0.0330809988 -0.0080810003 +-0.0330809988 -0.0330809988 -0.0169190001 +-0.0330809988 -0.0330809988 -0.0330809988 +-0.0330809988 -0.0330809988 -0.0419190004 +-0.0330809988 -0.0330809988 -0.0500000007 +-0.0330809988 -0.0419190004 0.0212500002 +-0.0330809988 -0.0419190004 0.0169190001 +-0.0330809988 -0.0419190004 0.0080810003 +-0.0330809988 -0.0419190004 -0.0080810003 +-0.0330809988 -0.0419190004 -0.0169190001 +-0.0330809988 -0.0419190004 -0.0330809988 +-0.0330809988 -0.0419190004 -0.0419190004 +-0.0330809988 -0.0419190004 -0.0500000007 +-0.0330809988 -0.0500000007 0.0169190001 +-0.0330809988 -0.0500000007 0.0080810003 +-0.0330809988 -0.0500000007 -0.0080810003 +-0.0330809988 -0.0500000007 -0.0169190001 +-0.0330809988 -0.0500000007 -0.0330809988 +-0.0330809988 -0.0500000007 -0.0419190004 +-0.0334630013 -0.0000000000 0.0422709994 +-0.0334630013 -0.0000000000 0.0327289999 +-0.0334630013 -0.0000000000 0.0172710009 +-0.0334630013 -0.0000000000 0.0077289999 +-0.0338019989 0.0256050006 0.0425379984 +-0.0338019989 0.0256050006 0.0324620008 +-0.0338019989 0.0256050006 0.0175379999 +-0.0338019989 0.0256050006 0.0074620000 +-0.0340280011 0.0426970012 0.0426970012 +-0.0340280011 0.0426970012 0.0323030017 +-0.0340280011 0.0426970012 0.0176970009 +-0.0340280011 0.0426970012 0.0073030000 +-0.0340280011 0.0426970012 -0.0073030000 +-0.0340280011 0.0426970012 -0.0176970009 +-0.0340280011 0.0426970012 -0.0323030017 +-0.0340280011 0.0426970012 -0.0426970012 +-0.0340280011 0.0323030017 0.0426970012 +-0.0340280011 0.0323030017 0.0323030017 +-0.0340280011 0.0323030017 0.0176970009 +-0.0340280011 0.0323030017 0.0073030000 +-0.0340280011 0.0323030017 -0.0073030000 +-0.0340280011 0.0323030017 -0.0176970009 +-0.0340280011 0.0323030017 -0.0323030017 +-0.0340280011 0.0323030017 -0.0426970012 +-0.0340280011 0.0176970009 -0.0073030000 +-0.0340280011 0.0176970009 -0.0176970009 +-0.0340280011 0.0176970009 -0.0323030017 +-0.0340280011 0.0176970009 -0.0426970012 +-0.0340280011 0.0073030000 -0.0073030000 +-0.0340280011 0.0073030000 -0.0176970009 +-0.0340280011 0.0073030000 -0.0323030017 +-0.0340280011 0.0073030000 -0.0426970012 +-0.0340280011 -0.0073030000 0.0426970012 +-0.0340280011 -0.0073030000 0.0323030017 +-0.0340280011 -0.0073030000 0.0176970009 +-0.0340280011 -0.0073030000 0.0073030000 +-0.0340280011 -0.0073030000 -0.0073030000 +-0.0340280011 -0.0073030000 -0.0176970009 +-0.0340280011 -0.0073030000 -0.0323030017 +-0.0340280011 -0.0073030000 -0.0426970012 +-0.0340280011 -0.0176970009 0.0426970012 +-0.0340280011 -0.0176970009 0.0323030017 +-0.0340280011 -0.0176970009 0.0176970009 +-0.0340280011 -0.0176970009 0.0073030000 +-0.0340280011 -0.0176970009 -0.0073030000 +-0.0340280011 -0.0176970009 -0.0176970009 +-0.0340280011 -0.0176970009 -0.0323030017 +-0.0340280011 -0.0176970009 -0.0426970012 +-0.0340280011 -0.0323030017 0.0176970009 +-0.0340280011 -0.0323030017 0.0073030000 +-0.0340280011 -0.0323030017 -0.0073030000 +-0.0340280011 -0.0323030017 -0.0176970009 +-0.0340280011 -0.0323030017 -0.0323030017 +-0.0340280011 -0.0323030017 -0.0426970012 +-0.0340280011 -0.0426970012 0.0176970009 +-0.0340280011 -0.0426970012 0.0073030000 +-0.0340280011 -0.0426970012 -0.0073030000 +-0.0340280011 -0.0426970012 -0.0176970009 +-0.0340280011 -0.0426970012 -0.0323030017 +-0.0340280011 -0.0426970012 -0.0426970012 +-0.0343750007 0.0500000007 0.0429130010 +-0.0343750007 0.0500000007 0.0320869982 +-0.0343750007 0.0500000007 0.0179130007 +-0.0343750007 0.0500000007 0.0070870002 +-0.0343750007 0.0500000007 -0.0070870002 +-0.0343750007 0.0500000007 -0.0179130007 +-0.0343750007 0.0500000007 -0.0320869982 +-0.0343750007 0.0500000007 -0.0429130010 +-0.0343750007 0.0429130010 0.0500000007 +-0.0343750007 0.0429130010 -0.0500000007 +-0.0343750007 0.0320869982 0.0500000007 +-0.0343750007 0.0320869982 -0.0500000007 +-0.0343750007 0.0179130007 -0.0003910000 +-0.0343750007 0.0179130007 -0.0500000007 +-0.0343750007 0.0070870002 -0.0003910000 +-0.0343750007 0.0070870002 -0.0500000007 +-0.0343750007 -0.0070870002 0.0500000007 +-0.0343750007 -0.0070870002 -0.0500000007 +-0.0343750007 -0.0179130007 0.0500000007 +-0.0343750007 -0.0179130007 -0.0500000007 +-0.0343750007 -0.0250000004 0.0429130010 +-0.0343750007 -0.0250000004 0.0320869982 +-0.0343750007 -0.0320869982 0.0212500002 +-0.0343750007 -0.0320869982 -0.0500000007 +-0.0343750007 -0.0429130010 0.0212500002 +-0.0343750007 -0.0429130010 -0.0500000007 +-0.0343750007 -0.0500000007 0.0179130007 +-0.0343750007 -0.0500000007 0.0070870002 +-0.0343750007 -0.0500000007 -0.0070870002 +-0.0343750007 -0.0500000007 -0.0179130007 +-0.0343750007 -0.0500000007 -0.0320869982 +-0.0343750007 -0.0500000007 -0.0429130010 +-0.0347580016 -0.0000000000 0.0500000007 +-0.0347580016 -0.0000000000 0.0431159995 +-0.0347580016 -0.0000000000 0.0318839997 +-0.0347580016 -0.0000000000 0.0181159992 +-0.0347580016 -0.0000000000 0.0068839998 +-0.0347580016 -0.0000000000 -0.0003910000 +-0.0348059982 0.0261840001 0.0431389995 +-0.0348059982 0.0261840001 0.0318609998 +-0.0348059982 0.0261840001 0.0181389991 +-0.0348059982 0.0261840001 0.0068609999 +-0.0351080000 0.0432740003 0.0432740003 +-0.0351080000 0.0432740003 0.0317259990 +-0.0351080000 0.0432740003 0.0182739999 +-0.0351080000 0.0432740003 0.0067260000 +-0.0351080000 0.0432740003 -0.0067260000 +-0.0351080000 0.0432740003 -0.0182739999 +-0.0351080000 0.0432740003 -0.0317259990 +-0.0351080000 0.0432740003 -0.0432740003 +-0.0351080000 0.0317259990 0.0432740003 +-0.0351080000 0.0317259990 0.0317259990 +-0.0351080000 0.0317259990 0.0182739999 +-0.0351080000 0.0317259990 0.0067260000 +-0.0351080000 0.0317259990 -0.0067260000 +-0.0351080000 0.0317259990 -0.0182739999 +-0.0351080000 0.0317259990 -0.0317259990 +-0.0351080000 0.0317259990 -0.0432740003 +-0.0351080000 0.0182739999 -0.0067260000 +-0.0351080000 0.0182739999 -0.0182739999 +-0.0351080000 0.0182739999 -0.0317259990 +-0.0351080000 0.0182739999 -0.0432740003 +-0.0351080000 0.0067260000 -0.0067260000 +-0.0351080000 0.0067260000 -0.0182739999 +-0.0351080000 0.0067260000 -0.0317259990 +-0.0351080000 0.0067260000 -0.0432740003 +-0.0351080000 -0.0067260000 0.0432740003 +-0.0351080000 -0.0067260000 0.0317259990 +-0.0351080000 -0.0067260000 0.0182739999 +-0.0351080000 -0.0067260000 0.0067260000 +-0.0351080000 -0.0067260000 -0.0067260000 +-0.0351080000 -0.0067260000 -0.0182739999 +-0.0351080000 -0.0067260000 -0.0317259990 +-0.0351080000 -0.0067260000 -0.0432740003 +-0.0351080000 -0.0182739999 0.0432740003 +-0.0351080000 -0.0182739999 0.0317259990 +-0.0351080000 -0.0182739999 0.0182739999 +-0.0351080000 -0.0182739999 0.0067260000 +-0.0351080000 -0.0182739999 -0.0067260000 +-0.0351080000 -0.0182739999 -0.0182739999 +-0.0351080000 -0.0182739999 -0.0317259990 +-0.0351080000 -0.0182739999 -0.0432740003 +-0.0351080000 -0.0317259990 0.0182739999 +-0.0351080000 -0.0317259990 0.0067260000 +-0.0351080000 -0.0317259990 -0.0067260000 +-0.0351080000 -0.0317259990 -0.0182739999 +-0.0351080000 -0.0317259990 -0.0317259990 +-0.0351080000 -0.0317259990 -0.0432740003 +-0.0351080000 -0.0432740003 0.0182739999 +-0.0351080000 -0.0432740003 0.0067260000 +-0.0351080000 -0.0432740003 -0.0067260000 +-0.0351080000 -0.0432740003 -0.0182739999 +-0.0351080000 -0.0432740003 -0.0317259990 +-0.0351080000 -0.0432740003 -0.0432740003 +-0.0354919992 0.0000460000 0.0434189998 +-0.0354919992 0.0000460000 0.0315809995 +-0.0354919992 0.0000460000 0.0184189994 +-0.0354919992 0.0000460000 0.0065810001 +-0.0358819999 0.0500000007 0.0435369983 +-0.0358819999 0.0500000007 0.0314630009 +-0.0358819999 0.0500000007 0.0185369998 +-0.0358819999 0.0500000007 0.0064630001 +-0.0358819999 0.0500000007 -0.0064630001 +-0.0358819999 0.0500000007 -0.0185369998 +-0.0358819999 0.0500000007 -0.0314630009 +-0.0358819999 0.0500000007 -0.0435369983 +-0.0358819999 0.0435369983 0.0500000007 +-0.0358819999 0.0435369983 -0.0500000007 +-0.0358819999 0.0314630009 0.0500000007 +-0.0358819999 0.0314630009 -0.0500000007 +-0.0358819999 0.0185369998 -0.0003910000 +-0.0358819999 0.0185369998 -0.0500000007 +-0.0358819999 0.0064630001 -0.0003910000 +-0.0358819999 0.0064630001 -0.0500000007 +-0.0358819999 -0.0064630001 0.0500000007 +-0.0358819999 -0.0064630001 -0.0500000007 +-0.0358819999 -0.0185369998 0.0500000007 +-0.0358819999 -0.0185369998 -0.0500000007 +-0.0358819999 -0.0250000004 0.0435369983 +-0.0358819999 -0.0250000004 0.0314630009 +-0.0358819999 -0.0314630009 0.0212500002 +-0.0358819999 -0.0314630009 -0.0500000007 +-0.0358819999 -0.0435369983 0.0212500002 +-0.0358819999 -0.0435369983 -0.0500000007 +-0.0358819999 -0.0500000007 0.0185369998 +-0.0358819999 -0.0500000007 0.0064630001 +-0.0358819999 -0.0500000007 -0.0064630001 +-0.0358819999 -0.0500000007 -0.0185369998 +-0.0358819999 -0.0500000007 -0.0314630009 +-0.0358819999 -0.0500000007 -0.0435369983 +-0.0359040014 0.0268190000 0.0435429998 +-0.0359040014 0.0268190000 0.0314569995 +-0.0359040014 0.0268190000 0.0185429994 +-0.0359040014 0.0268190000 0.0064570000 +-0.0362549983 0.0001950000 0.0436250009 +-0.0362549983 0.0001950000 0.0313749984 +-0.0362549983 0.0001950000 0.0186250005 +-0.0362549983 0.0001950000 0.0063749999 +-0.0362749994 0.0002000000 0.0500000007 +-0.0362749994 0.0002000000 -0.0003910000 +-0.0362810008 0.0436300002 0.0436300002 +-0.0362810008 0.0436300002 0.0313699991 +-0.0362810008 0.0436300002 0.0186299998 +-0.0362810008 0.0436300002 0.0063700001 +-0.0362810008 0.0436300002 -0.0063700001 +-0.0362810008 0.0436300002 -0.0186299998 +-0.0362810008 0.0436300002 -0.0313699991 +-0.0362810008 0.0436300002 -0.0436300002 +-0.0362810008 0.0313699991 0.0436300002 +-0.0362810008 0.0313699991 0.0313699991 +-0.0362810008 0.0313699991 0.0186299998 +-0.0362810008 0.0313699991 0.0063700001 +-0.0362810008 0.0313699991 -0.0063700001 +-0.0362810008 0.0313699991 -0.0186299998 +-0.0362810008 0.0313699991 -0.0313699991 +-0.0362810008 0.0313699991 -0.0436300002 +-0.0362810008 0.0186299998 -0.0063700001 +-0.0362810008 0.0186299998 -0.0186299998 +-0.0362810008 0.0186299998 -0.0313699991 +-0.0362810008 0.0186299998 -0.0436300002 +-0.0362810008 0.0063700001 -0.0063700001 +-0.0362810008 0.0063700001 -0.0186299998 +-0.0362810008 0.0063700001 -0.0313699991 +-0.0362810008 0.0063700001 -0.0436300002 +-0.0362810008 -0.0063700001 0.0436300002 +-0.0362810008 -0.0063700001 0.0313699991 +-0.0362810008 -0.0063700001 0.0186299998 +-0.0362810008 -0.0063700001 0.0063700001 +-0.0362810008 -0.0063700001 -0.0063700001 +-0.0362810008 -0.0063700001 -0.0186299998 +-0.0362810008 -0.0063700001 -0.0313699991 +-0.0362810008 -0.0063700001 -0.0436300002 +-0.0362810008 -0.0186299998 0.0436300002 +-0.0362810008 -0.0186299998 0.0313699991 +-0.0362810008 -0.0186299998 0.0186299998 +-0.0362810008 -0.0186299998 0.0063700001 +-0.0362810008 -0.0186299998 -0.0063700001 +-0.0362810008 -0.0186299998 -0.0186299998 +-0.0362810008 -0.0186299998 -0.0313699991 +-0.0362810008 -0.0186299998 -0.0436300002 +-0.0362810008 -0.0313699991 0.0186299998 +-0.0362810008 -0.0313699991 0.0063700001 +-0.0362810008 -0.0313699991 -0.0063700001 +-0.0362810008 -0.0313699991 -0.0186299998 +-0.0362810008 -0.0313699991 -0.0313699991 +-0.0362810008 -0.0313699991 -0.0436300002 +-0.0362810008 -0.0436300002 0.0186299998 +-0.0362810008 -0.0436300002 0.0063700001 +-0.0362810008 -0.0436300002 -0.0063700001 +-0.0362810008 -0.0436300002 -0.0186299998 +-0.0362810008 -0.0436300002 -0.0313699991 +-0.0362810008 -0.0436300002 -0.0436300002 +-0.0368870012 0.0437199995 0.0437199995 +-0.0368870012 0.0437199995 0.0312799998 +-0.0368870012 0.0437199995 0.0187199991 +-0.0368870012 0.0437199995 0.0062799999 +-0.0368870012 0.0437199995 -0.0062799999 +-0.0368870012 0.0437199995 -0.0187199991 +-0.0368870012 0.0437199995 -0.0312799998 +-0.0368870012 0.0437199995 -0.0437199995 +-0.0368870012 0.0312799998 0.0437199995 +-0.0368870012 0.0312799998 0.0312799998 +-0.0368870012 0.0312799998 0.0187199991 +-0.0368870012 0.0312799998 0.0062799999 +-0.0368870012 0.0312799998 -0.0062799999 +-0.0368870012 0.0312799998 -0.0187199991 +-0.0368870012 0.0312799998 -0.0312799998 +-0.0368870012 0.0312799998 -0.0437199995 +-0.0368870012 0.0187199991 -0.0062799999 +-0.0368870012 0.0187199991 -0.0187199991 +-0.0368870012 0.0187199991 -0.0312799998 +-0.0368870012 0.0187199991 -0.0437199995 +-0.0368870012 0.0062799999 -0.0062799999 +-0.0368870012 0.0062799999 -0.0187199991 +-0.0368870012 0.0062799999 -0.0312799998 +-0.0368870012 0.0062799999 -0.0437199995 +-0.0368870012 -0.0062799999 0.0437199995 +-0.0368870012 -0.0062799999 0.0312799998 +-0.0368870012 -0.0062799999 0.0187199991 +-0.0368870012 -0.0062799999 0.0062799999 +-0.0368870012 -0.0062799999 -0.0062799999 +-0.0368870012 -0.0062799999 -0.0187199991 +-0.0368870012 -0.0062799999 -0.0312799998 +-0.0368870012 -0.0062799999 -0.0437199995 +-0.0368870012 -0.0187199991 0.0437199995 +-0.0368870012 -0.0187199991 0.0312799998 +-0.0368870012 -0.0187199991 0.0187199991 +-0.0368870012 -0.0187199991 0.0062799999 +-0.0368870012 -0.0187199991 -0.0062799999 +-0.0368870012 -0.0187199991 -0.0187199991 +-0.0368870012 -0.0187199991 -0.0312799998 +-0.0368870012 -0.0187199991 -0.0437199995 +-0.0368870012 -0.0312799998 0.0187199991 +-0.0368870012 -0.0312799998 0.0062799999 +-0.0368870012 -0.0312799998 -0.0062799999 +-0.0368870012 -0.0312799998 -0.0187199991 +-0.0368870012 -0.0312799998 -0.0312799998 +-0.0368870012 -0.0312799998 -0.0437199995 +-0.0368870012 -0.0437199995 0.0187199991 +-0.0368870012 -0.0437199995 0.0062799999 +-0.0368870012 -0.0437199995 -0.0062799999 +-0.0368870012 -0.0437199995 -0.0187199991 +-0.0368870012 -0.0437199995 -0.0312799998 +-0.0368870012 -0.0437199995 -0.0437199995 +-0.0370000005 0.0004460000 0.0437299982 +-0.0370000005 0.0004460000 0.0312700011 +-0.0370000005 0.0004460000 0.0187299997 +-0.0370000005 0.0004460000 0.0062699998 +-0.0370590016 0.0274850000 0.0437339991 +-0.0370590016 0.0274850000 0.0312660001 +-0.0370590016 0.0274850000 0.0187340006 +-0.0370590016 0.0274850000 0.0062660002 +-0.0375000015 0.0500000007 0.0437499993 +-0.0375000015 0.0500000007 0.0312500000 +-0.0375000015 0.0500000007 0.0187500007 +-0.0375000015 0.0500000007 0.0062500001 +-0.0375000015 0.0500000007 -0.0062500001 +-0.0375000015 0.0500000007 -0.0187500007 +-0.0375000015 0.0500000007 -0.0312500000 +-0.0375000015 0.0500000007 -0.0437499993 +-0.0375000015 0.0437499993 0.0500000007 +-0.0375000015 0.0437499993 0.0437499993 +-0.0375000015 0.0437499993 0.0312500000 +-0.0375000015 0.0437499993 0.0187500007 +-0.0375000015 0.0437499993 0.0062500001 +-0.0375000015 0.0437499993 -0.0062500001 +-0.0375000015 0.0437499993 -0.0187500007 +-0.0375000015 0.0437499993 -0.0312500000 +-0.0375000015 0.0437499993 -0.0437499993 +-0.0375000015 0.0437499993 -0.0500000007 +-0.0375000015 0.0312500000 0.0500000007 +-0.0375000015 0.0312500000 0.0437499993 +-0.0375000015 0.0312500000 0.0312500000 +-0.0375000015 0.0312500000 0.0187500007 +-0.0375000015 0.0312500000 0.0062500001 +-0.0375000015 0.0312500000 -0.0062500001 +-0.0375000015 0.0312500000 -0.0187500007 +-0.0375000015 0.0312500000 -0.0312500000 +-0.0375000015 0.0312500000 -0.0437499993 +-0.0375000015 0.0312500000 -0.0500000007 +-0.0375000015 0.0187500007 -0.0003910000 +-0.0375000015 0.0187500007 -0.0062500001 +-0.0375000015 0.0187500007 -0.0187500007 +-0.0375000015 0.0187500007 -0.0312500000 +-0.0375000015 0.0187500007 -0.0437499993 +-0.0375000015 0.0187500007 -0.0500000007 +-0.0375000015 0.0062500001 -0.0003910000 +-0.0375000015 0.0062500001 -0.0062500001 +-0.0375000015 0.0062500001 -0.0187500007 +-0.0375000015 0.0062500001 -0.0312500000 +-0.0375000015 0.0062500001 -0.0437499993 +-0.0375000015 0.0062500001 -0.0500000007 +-0.0375000015 -0.0062500001 0.0500000007 +-0.0375000015 -0.0062500001 0.0437499993 +-0.0375000015 -0.0062500001 0.0312500000 +-0.0375000015 -0.0062500001 0.0187500007 +-0.0375000015 -0.0062500001 0.0062500001 +-0.0375000015 -0.0062500001 -0.0062500001 +-0.0375000015 -0.0062500001 -0.0187500007 +-0.0375000015 -0.0062500001 -0.0312500000 +-0.0375000015 -0.0062500001 -0.0437499993 +-0.0375000015 -0.0062500001 -0.0500000007 +-0.0375000015 -0.0187500007 0.0500000007 +-0.0375000015 -0.0187500007 0.0437499993 +-0.0375000015 -0.0187500007 0.0312500000 +-0.0375000015 -0.0187500007 0.0187500007 +-0.0375000015 -0.0187500007 0.0062500001 +-0.0375000015 -0.0187500007 -0.0062500001 +-0.0375000015 -0.0187500007 -0.0187500007 +-0.0375000015 -0.0187500007 -0.0312500000 +-0.0375000015 -0.0187500007 -0.0437499993 +-0.0375000015 -0.0187500007 -0.0500000007 +-0.0375000015 -0.0250000004 0.0437499993 +-0.0375000015 -0.0250000004 0.0312500000 +-0.0375000015 -0.0312500000 0.0212500002 +-0.0375000015 -0.0312500000 0.0187500007 +-0.0375000015 -0.0312500000 0.0062500001 +-0.0375000015 -0.0312500000 -0.0062500001 +-0.0375000015 -0.0312500000 -0.0187500007 +-0.0375000015 -0.0312500000 -0.0312500000 +-0.0375000015 -0.0312500000 -0.0437499993 +-0.0375000015 -0.0312500000 -0.0500000007 +-0.0375000015 -0.0437499993 0.0212500002 +-0.0375000015 -0.0437499993 0.0187500007 +-0.0375000015 -0.0437499993 0.0062500001 +-0.0375000015 -0.0437499993 -0.0062500001 +-0.0375000015 -0.0437499993 -0.0187500007 +-0.0375000015 -0.0437499993 -0.0312500000 +-0.0375000015 -0.0437499993 -0.0437499993 +-0.0375000015 -0.0437499993 -0.0500000007 +-0.0375000015 -0.0500000007 0.0187500007 +-0.0375000015 -0.0500000007 0.0062500001 +-0.0375000015 -0.0500000007 -0.0062500001 +-0.0375000015 -0.0500000007 -0.0187500007 +-0.0375000015 -0.0500000007 -0.0312500000 +-0.0375000015 -0.0500000007 -0.0437499993 +-0.0376879983 0.0007850000 0.0500000007 +-0.0376879983 0.0007850000 0.0437470004 +-0.0376879983 0.0007850000 0.0312529989 +-0.0376879983 0.0007850000 0.0187470000 +-0.0376879983 0.0007850000 0.0062529999 +-0.0376879983 0.0007850000 -0.0003910000 +-0.0381130017 0.0437199995 0.0437199995 +-0.0381130017 0.0437199995 0.0312799998 +-0.0381130017 0.0437199995 0.0187199991 +-0.0381130017 0.0437199995 0.0062799999 +-0.0381130017 0.0437199995 -0.0062799999 +-0.0381130017 0.0437199995 -0.0187199991 +-0.0381130017 0.0437199995 -0.0312799998 +-0.0381130017 0.0437199995 -0.0437199995 +-0.0381130017 0.0312799998 0.0437199995 +-0.0381130017 0.0312799998 0.0312799998 +-0.0381130017 0.0312799998 0.0187199991 +-0.0381130017 0.0312799998 0.0062799999 +-0.0381130017 0.0312799998 -0.0062799999 +-0.0381130017 0.0312799998 -0.0187199991 +-0.0381130017 0.0312799998 -0.0312799998 +-0.0381130017 0.0312799998 -0.0437199995 +-0.0381130017 0.0187199991 -0.0062799999 +-0.0381130017 0.0187199991 -0.0187199991 +-0.0381130017 0.0187199991 -0.0312799998 +-0.0381130017 0.0187199991 -0.0437199995 +-0.0381130017 0.0062799999 -0.0062799999 +-0.0381130017 0.0062799999 -0.0187199991 +-0.0381130017 0.0062799999 -0.0312799998 +-0.0381130017 0.0062799999 -0.0437199995 +-0.0381130017 -0.0062799999 0.0437199995 +-0.0381130017 -0.0062799999 0.0312799998 +-0.0381130017 -0.0062799999 0.0187199991 +-0.0381130017 -0.0062799999 0.0062799999 +-0.0381130017 -0.0062799999 -0.0062799999 +-0.0381130017 -0.0062799999 -0.0187199991 +-0.0381130017 -0.0062799999 -0.0312799998 +-0.0381130017 -0.0062799999 -0.0437199995 +-0.0381130017 -0.0187199991 0.0437199995 +-0.0381130017 -0.0187199991 0.0312799998 +-0.0381130017 -0.0187199991 0.0187199991 +-0.0381130017 -0.0187199991 0.0062799999 +-0.0381130017 -0.0187199991 -0.0062799999 +-0.0381130017 -0.0187199991 -0.0187199991 +-0.0381130017 -0.0187199991 -0.0312799998 +-0.0381130017 -0.0187199991 -0.0437199995 +-0.0381130017 -0.0312799998 0.0187199991 +-0.0381130017 -0.0312799998 0.0062799999 +-0.0381130017 -0.0312799998 -0.0062799999 +-0.0381130017 -0.0312799998 -0.0187199991 +-0.0381130017 -0.0312799998 -0.0312799998 +-0.0381130017 -0.0312799998 -0.0437199995 +-0.0381130017 -0.0437199995 0.0187199991 +-0.0381130017 -0.0437199995 0.0062799999 +-0.0381130017 -0.0437199995 -0.0062799999 +-0.0381130017 -0.0437199995 -0.0187199991 +-0.0381130017 -0.0437199995 -0.0312799998 +-0.0381130017 -0.0437199995 -0.0437199995 +-0.0382289998 0.0281610005 0.0437069982 +-0.0382289998 0.0281610005 0.0312930010 +-0.0382289998 0.0281610005 0.0187069997 +-0.0382289998 0.0281610005 0.0062930002 +-0.0387189984 0.0436300002 0.0436300002 +-0.0387189984 0.0436300002 0.0313699991 +-0.0387189984 0.0436300002 0.0186299998 +-0.0387189984 0.0436300002 0.0063700001 +-0.0387189984 0.0436300002 -0.0063700001 +-0.0387189984 0.0436300002 -0.0186299998 +-0.0387189984 0.0436300002 -0.0313699991 +-0.0387189984 0.0436300002 -0.0436300002 +-0.0387189984 0.0313699991 0.0436300002 +-0.0387189984 0.0313699991 0.0313699991 +-0.0387189984 0.0313699991 0.0186299998 +-0.0387189984 0.0313699991 0.0063700001 +-0.0387189984 0.0313699991 -0.0063700001 +-0.0387189984 0.0313699991 -0.0186299998 +-0.0387189984 0.0313699991 -0.0313699991 +-0.0387189984 0.0313699991 -0.0436300002 +-0.0387189984 0.0186299998 -0.0063700001 +-0.0387189984 0.0186299998 -0.0186299998 +-0.0387189984 0.0186299998 -0.0313699991 +-0.0387189984 0.0186299998 -0.0436300002 +-0.0387189984 0.0063700001 -0.0063700001 +-0.0387189984 0.0063700001 -0.0186299998 +-0.0387189984 0.0063700001 -0.0313699991 +-0.0387189984 0.0063700001 -0.0436300002 +-0.0387189984 -0.0063700001 0.0436300002 +-0.0387189984 -0.0063700001 0.0313699991 +-0.0387189984 -0.0063700001 0.0186299998 +-0.0387189984 -0.0063700001 0.0063700001 +-0.0387189984 -0.0063700001 -0.0063700001 +-0.0387189984 -0.0063700001 -0.0186299998 +-0.0387189984 -0.0063700001 -0.0313699991 +-0.0387189984 -0.0063700001 -0.0436300002 +-0.0387189984 -0.0186299998 0.0436300002 +-0.0387189984 -0.0186299998 0.0313699991 +-0.0387189984 -0.0186299998 0.0186299998 +-0.0387189984 -0.0186299998 0.0063700001 +-0.0387189984 -0.0186299998 -0.0063700001 +-0.0387189984 -0.0186299998 -0.0186299998 +-0.0387189984 -0.0186299998 -0.0313699991 +-0.0387189984 -0.0186299998 -0.0436300002 +-0.0387189984 -0.0313699991 0.0186299998 +-0.0387189984 -0.0313699991 0.0063700001 +-0.0387189984 -0.0313699991 -0.0063700001 +-0.0387189984 -0.0313699991 -0.0186299998 +-0.0387189984 -0.0313699991 -0.0313699991 +-0.0387189984 -0.0313699991 -0.0436300002 +-0.0387189984 -0.0436300002 0.0186299998 +-0.0387189984 -0.0436300002 0.0063700001 +-0.0387189984 -0.0436300002 -0.0063700001 +-0.0387189984 -0.0436300002 -0.0186299998 +-0.0387189984 -0.0436300002 -0.0313699991 +-0.0387189984 -0.0436300002 -0.0436300002 +-0.0388800018 0.0014730000 0.0435959995 +-0.0388800018 0.0014730000 0.0314039998 +-0.0388800018 0.0014730000 0.0185959991 +-0.0388800018 0.0014730000 0.0064039999 +-0.0391179994 0.0500000007 0.0435369983 +-0.0391179994 0.0500000007 0.0314630009 +-0.0391179994 0.0500000007 0.0185369998 +-0.0391179994 0.0500000007 0.0064630001 +-0.0391179994 0.0500000007 -0.0064630001 +-0.0391179994 0.0500000007 -0.0185369998 +-0.0391179994 0.0500000007 -0.0314630009 +-0.0391179994 0.0500000007 -0.0435369983 +-0.0391179994 0.0435369983 0.0500000007 +-0.0391179994 0.0435369983 -0.0500000007 +-0.0391179994 0.0314630009 0.0500000007 +-0.0391179994 0.0314630009 -0.0500000007 +-0.0391179994 0.0185369998 -0.0003910000 +-0.0391179994 0.0185369998 -0.0500000007 +-0.0391179994 0.0064630001 -0.0003910000 +-0.0391179994 0.0064630001 -0.0500000007 +-0.0391179994 -0.0064630001 0.0500000007 +-0.0391179994 -0.0064630001 -0.0500000007 +-0.0391179994 -0.0185369998 0.0500000007 +-0.0391179994 -0.0185369998 -0.0500000007 +-0.0391179994 -0.0250000004 0.0435369983 +-0.0391179994 -0.0250000004 0.0314630009 +-0.0391179994 -0.0314630009 0.0212500002 +-0.0391179994 -0.0314630009 -0.0500000007 +-0.0391179994 -0.0435369983 0.0212500002 +-0.0391179994 -0.0435369983 -0.0500000007 +-0.0391179994 -0.0500000007 0.0185369998 +-0.0391179994 -0.0500000007 0.0064630001 +-0.0391179994 -0.0500000007 -0.0064630001 +-0.0391179994 -0.0500000007 -0.0185369998 +-0.0391179994 -0.0500000007 -0.0314630009 +-0.0391179994 -0.0500000007 -0.0435369983 +-0.0393729992 0.0288210008 0.0434629992 +-0.0393729992 0.0288210008 0.0315370001 +-0.0393729992 0.0288210008 0.0184630007 +-0.0393729992 0.0288210008 0.0065370002 +-0.0398919992 0.0432740003 0.0432740003 +-0.0398919992 0.0432740003 0.0317259990 +-0.0398919992 0.0432740003 0.0182739999 +-0.0398919992 0.0432740003 0.0067260000 +-0.0398919992 0.0432740003 -0.0067260000 +-0.0398919992 0.0432740003 -0.0182739999 +-0.0398919992 0.0432740003 -0.0317259990 +-0.0398919992 0.0432740003 -0.0432740003 +-0.0398919992 0.0317259990 0.0432740003 +-0.0398919992 0.0317259990 0.0317259990 +-0.0398919992 0.0317259990 0.0182739999 +-0.0398919992 0.0317259990 0.0067260000 +-0.0398919992 0.0317259990 -0.0067260000 +-0.0398919992 0.0317259990 -0.0182739999 +-0.0398919992 0.0317259990 -0.0317259990 +-0.0398919992 0.0317259990 -0.0432740003 +-0.0398919992 0.0182739999 -0.0067260000 +-0.0398919992 0.0182739999 -0.0182739999 +-0.0398919992 0.0182739999 -0.0317259990 +-0.0398919992 0.0182739999 -0.0432740003 +-0.0398919992 0.0067260000 -0.0067260000 +-0.0398919992 0.0067260000 -0.0182739999 +-0.0398919992 0.0067260000 -0.0317259990 +-0.0398919992 0.0067260000 -0.0432740003 +-0.0398919992 -0.0067260000 0.0432740003 +-0.0398919992 -0.0067260000 0.0317259990 +-0.0398919992 -0.0067260000 0.0182739999 +-0.0398919992 -0.0067260000 0.0067260000 +-0.0398919992 -0.0067260000 -0.0067260000 +-0.0398919992 -0.0067260000 -0.0182739999 +-0.0398919992 -0.0067260000 -0.0317259990 +-0.0398919992 -0.0067260000 -0.0432740003 +-0.0398919992 -0.0182739999 0.0432740003 +-0.0398919992 -0.0182739999 0.0317259990 +-0.0398919992 -0.0182739999 0.0182739999 +-0.0398919992 -0.0182739999 0.0067260000 +-0.0398919992 -0.0182739999 -0.0067260000 +-0.0398919992 -0.0182739999 -0.0182739999 +-0.0398919992 -0.0182739999 -0.0317259990 +-0.0398919992 -0.0182739999 -0.0432740003 +-0.0398919992 -0.0317259990 0.0182739999 +-0.0398919992 -0.0317259990 0.0067260000 +-0.0398919992 -0.0317259990 -0.0067260000 +-0.0398919992 -0.0317259990 -0.0182739999 +-0.0398919992 -0.0317259990 -0.0317259990 +-0.0398919992 -0.0317259990 -0.0432740003 +-0.0398919992 -0.0432740003 0.0182739999 +-0.0398919992 -0.0432740003 0.0067260000 +-0.0398919992 -0.0432740003 -0.0067260000 +-0.0398919992 -0.0432740003 -0.0182739999 +-0.0398919992 -0.0432740003 -0.0317259990 +-0.0398919992 -0.0432740003 -0.0432740003 +-0.0400209986 0.0021319999 0.0432190001 +-0.0400209986 0.0021319999 0.0317809992 +-0.0400209986 0.0021319999 0.0182189997 +-0.0400209986 0.0021319999 0.0067810002 +-0.0404519998 0.0294439998 0.0430090018 +-0.0404519998 0.0294439998 0.0319910012 +-0.0404519998 0.0294439998 0.0180089995 +-0.0404519998 0.0294439998 0.0069909999 +-0.0406249985 0.0500000007 0.0429130010 +-0.0406249985 0.0500000007 0.0320869982 +-0.0406249985 0.0500000007 0.0179130007 +-0.0406249985 0.0500000007 0.0070870002 +-0.0406249985 0.0500000007 -0.0070870002 +-0.0406249985 0.0500000007 -0.0179130007 +-0.0406249985 0.0500000007 -0.0320869982 +-0.0406249985 0.0500000007 -0.0429130010 +-0.0406249985 0.0429130010 0.0500000007 +-0.0406249985 0.0429130010 -0.0500000007 +-0.0406249985 0.0320869982 0.0500000007 +-0.0406249985 0.0320869982 -0.0500000007 +-0.0406249985 0.0179130007 -0.0003910000 +-0.0406249985 0.0179130007 -0.0500000007 +-0.0406249985 0.0070870002 -0.0003910000 +-0.0406249985 0.0070870002 -0.0500000007 +-0.0406249985 -0.0070870002 0.0500000007 +-0.0406249985 -0.0070870002 -0.0500000007 +-0.0406249985 -0.0179130007 0.0500000007 +-0.0406249985 -0.0179130007 -0.0500000007 +-0.0406249985 -0.0250000004 0.0429130010 +-0.0406249985 -0.0250000004 0.0320869982 +-0.0406249985 -0.0320869982 0.0212500002 +-0.0406249985 -0.0320869982 -0.0500000007 +-0.0406249985 -0.0429130010 0.0212500002 +-0.0406249985 -0.0429130010 -0.0500000007 +-0.0406249985 -0.0500000007 0.0179130007 +-0.0406249985 -0.0500000007 0.0070870002 +-0.0406249985 -0.0500000007 -0.0070870002 +-0.0406249985 -0.0500000007 -0.0179130007 +-0.0406249985 -0.0500000007 -0.0320869982 +-0.0406249985 -0.0500000007 -0.0429130010 +-0.0409720019 0.0426970012 0.0426970012 +-0.0409720019 0.0426970012 0.0323030017 +-0.0409720019 0.0426970012 0.0176970009 +-0.0409720019 0.0426970012 0.0073030000 +-0.0409720019 0.0426970012 -0.0073030000 +-0.0409720019 0.0426970012 -0.0176970009 +-0.0409720019 0.0426970012 -0.0323030017 +-0.0409720019 0.0426970012 -0.0426970012 +-0.0409720019 0.0323030017 0.0426970012 +-0.0409720019 0.0323030017 0.0323030017 +-0.0409720019 0.0323030017 0.0176970009 +-0.0409720019 0.0323030017 0.0073030000 +-0.0409720019 0.0323030017 -0.0073030000 +-0.0409720019 0.0323030017 -0.0176970009 +-0.0409720019 0.0323030017 -0.0323030017 +-0.0409720019 0.0323030017 -0.0426970012 +-0.0409720019 0.0176970009 -0.0073030000 +-0.0409720019 0.0176970009 -0.0176970009 +-0.0409720019 0.0176970009 -0.0323030017 +-0.0409720019 0.0176970009 -0.0426970012 +-0.0409720019 0.0073030000 -0.0073030000 +-0.0409720019 0.0073030000 -0.0176970009 +-0.0409720019 0.0073030000 -0.0323030017 +-0.0409720019 0.0073030000 -0.0426970012 +-0.0409720019 -0.0073030000 0.0426970012 +-0.0409720019 -0.0073030000 0.0323030017 +-0.0409720019 -0.0073030000 0.0176970009 +-0.0409720019 -0.0073030000 0.0073030000 +-0.0409720019 -0.0073030000 -0.0073030000 +-0.0409720019 -0.0073030000 -0.0176970009 +-0.0409720019 -0.0073030000 -0.0323030017 +-0.0409720019 -0.0073030000 -0.0426970012 +-0.0409720019 -0.0176970009 0.0426970012 +-0.0409720019 -0.0176970009 0.0323030017 +-0.0409720019 -0.0176970009 0.0176970009 +-0.0409720019 -0.0176970009 0.0073030000 +-0.0409720019 -0.0176970009 -0.0073030000 +-0.0409720019 -0.0176970009 -0.0176970009 +-0.0409720019 -0.0176970009 -0.0323030017 +-0.0409720019 -0.0176970009 -0.0426970012 +-0.0409720019 -0.0323030017 0.0176970009 +-0.0409720019 -0.0323030017 0.0073030000 +-0.0409720019 -0.0323030017 -0.0073030000 +-0.0409720019 -0.0323030017 -0.0176970009 +-0.0409720019 -0.0323030017 -0.0323030017 +-0.0409720019 -0.0323030017 -0.0426970012 +-0.0409720019 -0.0426970012 0.0176970009 +-0.0409720019 -0.0426970012 0.0073030000 +-0.0409720019 -0.0426970012 -0.0073030000 +-0.0409720019 -0.0426970012 -0.0176970009 +-0.0409720019 -0.0426970012 -0.0323030017 +-0.0409720019 -0.0426970012 -0.0426970012 +-0.0410690010 0.0027369999 0.0426310003 +-0.0410690010 0.0027369999 0.0323689990 +-0.0410690010 0.0027369999 0.0176309999 +-0.0410690010 0.0027369999 0.0073690000 +-0.0414270014 0.0300069991 0.0423620008 +-0.0414270014 0.0300069991 0.0326379985 +-0.0414270014 0.0300069991 0.0173620004 +-0.0414270014 0.0300069991 0.0076380000 +-0.0419190004 0.0500000007 0.0419190004 +-0.0419190004 0.0500000007 0.0330809988 +-0.0419190004 0.0500000007 0.0169190001 +-0.0419190004 0.0500000007 0.0080810003 +-0.0419190004 0.0500000007 -0.0080810003 +-0.0419190004 0.0500000007 -0.0169190001 +-0.0419190004 0.0500000007 -0.0330809988 +-0.0419190004 0.0500000007 -0.0419190004 +-0.0419190004 0.0419190004 0.0500000007 +-0.0419190004 0.0419190004 0.0419190004 +-0.0419190004 0.0419190004 0.0330809988 +-0.0419190004 0.0419190004 0.0169190001 +-0.0419190004 0.0419190004 0.0080810003 +-0.0419190004 0.0419190004 -0.0080810003 +-0.0419190004 0.0419190004 -0.0169190001 +-0.0419190004 0.0419190004 -0.0330809988 +-0.0419190004 0.0419190004 -0.0419190004 +-0.0419190004 0.0419190004 -0.0500000007 +-0.0419190004 0.0330809988 0.0500000007 +-0.0419190004 0.0330809988 0.0419190004 +-0.0419190004 0.0330809988 0.0330809988 +-0.0419190004 0.0330809988 0.0169190001 +-0.0419190004 0.0330809988 0.0080810003 +-0.0419190004 0.0330809988 -0.0080810003 +-0.0419190004 0.0330809988 -0.0169190001 +-0.0419190004 0.0330809988 -0.0330809988 +-0.0419190004 0.0330809988 -0.0419190004 +-0.0419190004 0.0330809988 -0.0500000007 +-0.0419190004 0.0169190001 -0.0003910000 +-0.0419190004 0.0169190001 -0.0080810003 +-0.0419190004 0.0169190001 -0.0169190001 +-0.0419190004 0.0169190001 -0.0330809988 +-0.0419190004 0.0169190001 -0.0419190004 +-0.0419190004 0.0169190001 -0.0500000007 +-0.0419190004 0.0080810003 -0.0003910000 +-0.0419190004 0.0080810003 -0.0080810003 +-0.0419190004 0.0080810003 -0.0169190001 +-0.0419190004 0.0080810003 -0.0330809988 +-0.0419190004 0.0080810003 -0.0419190004 +-0.0419190004 0.0080810003 -0.0500000007 +-0.0419190004 -0.0080810003 0.0500000007 +-0.0419190004 -0.0080810003 0.0419190004 +-0.0419190004 -0.0080810003 0.0330809988 +-0.0419190004 -0.0080810003 0.0169190001 +-0.0419190004 -0.0080810003 0.0080810003 +-0.0419190004 -0.0080810003 -0.0080810003 +-0.0419190004 -0.0080810003 -0.0169190001 +-0.0419190004 -0.0080810003 -0.0330809988 +-0.0419190004 -0.0080810003 -0.0419190004 +-0.0419190004 -0.0080810003 -0.0500000007 +-0.0419190004 -0.0169190001 0.0500000007 +-0.0419190004 -0.0169190001 0.0419190004 +-0.0419190004 -0.0169190001 0.0330809988 +-0.0419190004 -0.0169190001 0.0169190001 +-0.0419190004 -0.0169190001 0.0080810003 +-0.0419190004 -0.0169190001 -0.0080810003 +-0.0419190004 -0.0169190001 -0.0169190001 +-0.0419190004 -0.0169190001 -0.0330809988 +-0.0419190004 -0.0169190001 -0.0419190004 +-0.0419190004 -0.0169190001 -0.0500000007 +-0.0419190004 -0.0250000004 0.0419190004 +-0.0419190004 -0.0250000004 0.0330809988 +-0.0419190004 -0.0330809988 0.0212500002 +-0.0419190004 -0.0330809988 0.0169190001 +-0.0419190004 -0.0330809988 0.0080810003 +-0.0419190004 -0.0330809988 -0.0080810003 +-0.0419190004 -0.0330809988 -0.0169190001 +-0.0419190004 -0.0330809988 -0.0330809988 +-0.0419190004 -0.0330809988 -0.0419190004 +-0.0419190004 -0.0330809988 -0.0500000007 +-0.0419190004 -0.0419190004 0.0212500002 +-0.0419190004 -0.0419190004 0.0169190001 +-0.0419190004 -0.0419190004 0.0080810003 +-0.0419190004 -0.0419190004 -0.0080810003 +-0.0419190004 -0.0419190004 -0.0169190001 +-0.0419190004 -0.0419190004 -0.0330809988 +-0.0419190004 -0.0419190004 -0.0419190004 +-0.0419190004 -0.0419190004 -0.0500000007 +-0.0419190004 -0.0500000007 0.0169190001 +-0.0419190004 -0.0500000007 0.0080810003 +-0.0419190004 -0.0500000007 -0.0080810003 +-0.0419190004 -0.0500000007 -0.0169190001 +-0.0419190004 -0.0500000007 -0.0330809988 +-0.0419190004 -0.0500000007 -0.0419190004 +-0.0419850014 0.0032660000 0.0418529995 +-0.0419850014 0.0032660000 0.0331469998 +-0.0419850014 0.0032660000 0.0168529991 +-0.0419850014 0.0032660000 0.0081470003 +-0.0422650017 0.0304910000 0.0415449999 +-0.0422650017 0.0304910000 0.0334549993 +-0.0422650017 0.0304910000 0.0165449996 +-0.0422650017 0.0304910000 0.0084549999 +-0.0425710008 0.0324289985 0.0411540009 +-0.0425710008 0.0324289985 0.0338459983 +-0.0425710008 0.0324289985 0.0161540005 +-0.0425710008 0.0324289985 0.0088459998 +-0.0426970012 0.0426970012 0.0409720019 +-0.0426970012 0.0426970012 0.0340280011 +-0.0426970012 0.0426970012 0.0159719996 +-0.0426970012 0.0426970012 0.0090279998 +-0.0426970012 0.0426970012 -0.0090279998 +-0.0426970012 0.0426970012 -0.0159719996 +-0.0426970012 0.0426970012 -0.0340280011 +-0.0426970012 0.0426970012 -0.0409720019 +-0.0426970012 0.0409720019 0.0426970012 +-0.0426970012 0.0409720019 0.0323030017 +-0.0426970012 0.0409720019 0.0176970009 +-0.0426970012 0.0409720019 0.0073030000 +-0.0426970012 0.0409720019 -0.0073030000 +-0.0426970012 0.0409720019 -0.0176970009 +-0.0426970012 0.0409720019 -0.0323030017 +-0.0426970012 0.0409720019 -0.0426970012 +-0.0426970012 0.0340280011 0.0426970012 +-0.0426970012 0.0340280011 0.0323030017 +-0.0426970012 0.0340280011 0.0176970009 +-0.0426970012 0.0340280011 0.0073030000 +-0.0426970012 0.0340280011 -0.0073030000 +-0.0426970012 0.0340280011 -0.0176970009 +-0.0426970012 0.0340280011 -0.0323030017 +-0.0426970012 0.0340280011 -0.0426970012 +-0.0426970012 0.0323030017 -0.0090279998 +-0.0426970012 0.0323030017 -0.0159719996 +-0.0426970012 0.0323030017 -0.0340280011 +-0.0426970012 0.0323030017 -0.0409720019 +-0.0426970012 0.0176970009 -0.0090279998 +-0.0426970012 0.0176970009 -0.0159719996 +-0.0426970012 0.0176970009 -0.0340280011 +-0.0426970012 0.0176970009 -0.0409720019 +-0.0426970012 0.0159719996 -0.0073030000 +-0.0426970012 0.0159719996 -0.0176970009 +-0.0426970012 0.0159719996 -0.0323030017 +-0.0426970012 0.0159719996 -0.0426970012 +-0.0426970012 0.0090279998 -0.0073030000 +-0.0426970012 0.0090279998 -0.0176970009 +-0.0426970012 0.0090279998 -0.0323030017 +-0.0426970012 0.0090279998 -0.0426970012 +-0.0426970012 0.0073030000 -0.0090279998 +-0.0426970012 0.0073030000 -0.0159719996 +-0.0426970012 0.0073030000 -0.0340280011 +-0.0426970012 0.0073030000 -0.0409720019 +-0.0426970012 -0.0073030000 0.0409720019 +-0.0426970012 -0.0073030000 0.0340280011 +-0.0426970012 -0.0073030000 0.0159719996 +-0.0426970012 -0.0073030000 0.0090279998 +-0.0426970012 -0.0073030000 -0.0090279998 +-0.0426970012 -0.0073030000 -0.0159719996 +-0.0426970012 -0.0073030000 -0.0340280011 +-0.0426970012 -0.0073030000 -0.0409720019 +-0.0426970012 -0.0090279998 0.0426970012 +-0.0426970012 -0.0090279998 0.0323030017 +-0.0426970012 -0.0090279998 0.0176970009 +-0.0426970012 -0.0090279998 0.0073030000 +-0.0426970012 -0.0090279998 -0.0073030000 +-0.0426970012 -0.0090279998 -0.0176970009 +-0.0426970012 -0.0090279998 -0.0323030017 +-0.0426970012 -0.0090279998 -0.0426970012 +-0.0426970012 -0.0159719996 0.0426970012 +-0.0426970012 -0.0159719996 0.0323030017 +-0.0426970012 -0.0159719996 0.0176970009 +-0.0426970012 -0.0159719996 0.0073030000 +-0.0426970012 -0.0159719996 -0.0073030000 +-0.0426970012 -0.0159719996 -0.0176970009 +-0.0426970012 -0.0159719996 -0.0323030017 +-0.0426970012 -0.0159719996 -0.0426970012 +-0.0426970012 -0.0176970009 0.0409720019 +-0.0426970012 -0.0176970009 0.0340280011 +-0.0426970012 -0.0176970009 0.0159719996 +-0.0426970012 -0.0176970009 0.0090279998 +-0.0426970012 -0.0176970009 -0.0090279998 +-0.0426970012 -0.0176970009 -0.0159719996 +-0.0426970012 -0.0176970009 -0.0340280011 +-0.0426970012 -0.0176970009 -0.0409720019 +-0.0426970012 -0.0323030017 0.0159719996 +-0.0426970012 -0.0323030017 0.0090279998 +-0.0426970012 -0.0323030017 -0.0090279998 +-0.0426970012 -0.0323030017 -0.0159719996 +-0.0426970012 -0.0323030017 -0.0340280011 +-0.0426970012 -0.0323030017 -0.0409720019 +-0.0426970012 -0.0340280011 0.0176970009 +-0.0426970012 -0.0340280011 0.0073030000 +-0.0426970012 -0.0340280011 -0.0073030000 +-0.0426970012 -0.0340280011 -0.0176970009 +-0.0426970012 -0.0340280011 -0.0323030017 +-0.0426970012 -0.0340280011 -0.0426970012 +-0.0426970012 -0.0409720019 0.0176970009 +-0.0426970012 -0.0409720019 0.0073030000 +-0.0426970012 -0.0409720019 -0.0073030000 +-0.0426970012 -0.0409720019 -0.0176970009 +-0.0426970012 -0.0409720019 -0.0323030017 +-0.0426970012 -0.0409720019 -0.0426970012 +-0.0426970012 -0.0426970012 0.0159719996 +-0.0426970012 -0.0426970012 0.0090279998 +-0.0426970012 -0.0426970012 -0.0090279998 +-0.0426970012 -0.0426970012 -0.0159719996 +-0.0426970012 -0.0426970012 -0.0340280011 +-0.0426970012 -0.0426970012 -0.0409720019 +-0.0427349992 0.0036990000 0.0409139991 +-0.0427349992 0.0036990000 0.0340860002 +-0.0427349992 0.0036990000 0.0159140006 +-0.0427349992 0.0036990000 0.0090859998 +-0.0429130010 0.0500000007 0.0406249985 +-0.0429130010 0.0500000007 0.0343750007 +-0.0429130010 0.0500000007 0.0156250000 +-0.0429130010 0.0500000007 0.0093750004 +-0.0429130010 0.0500000007 -0.0093750004 +-0.0429130010 0.0500000007 -0.0156250000 +-0.0429130010 0.0500000007 -0.0343750007 +-0.0429130010 0.0500000007 -0.0406249985 +-0.0429130010 0.0406249985 0.0500000007 +-0.0429130010 0.0406249985 -0.0500000007 +-0.0429130010 0.0343750007 0.0500000007 +-0.0429130010 0.0343750007 -0.0500000007 +-0.0429130010 0.0156250000 -0.0003910000 +-0.0429130010 0.0156250000 -0.0500000007 +-0.0429130010 0.0093750004 -0.0003910000 +-0.0429130010 0.0093750004 -0.0500000007 +-0.0429130010 -0.0093750004 0.0500000007 +-0.0429130010 -0.0093750004 -0.0500000007 +-0.0429130010 -0.0156250000 0.0500000007 +-0.0429130010 -0.0156250000 -0.0500000007 +-0.0429130010 -0.0250000004 0.0406249985 +-0.0429130010 -0.0250000004 0.0343750007 +-0.0429130010 -0.0343750007 0.0212500002 +-0.0429130010 -0.0343750007 -0.0500000007 +-0.0429130010 -0.0406249985 0.0212500002 +-0.0429130010 -0.0406249985 -0.0500000007 +-0.0429130010 -0.0500000007 0.0156250000 +-0.0429130010 -0.0500000007 0.0093750004 +-0.0429130010 -0.0500000007 -0.0093750004 +-0.0429130010 -0.0500000007 -0.0156250000 +-0.0429130010 -0.0500000007 -0.0343750007 +-0.0429130010 -0.0500000007 -0.0406249985 +-0.0429349989 0.0308780000 0.0405859984 +-0.0429349989 0.0308780000 0.0344140008 +-0.0429349989 0.0308780000 0.0155859999 +-0.0429349989 0.0308780000 0.0094140004 +-0.0430909991 0.0319090001 0.0402939990 +-0.0430909991 0.0319090001 0.0347060002 +-0.0430909991 0.0319090001 0.0152939996 +-0.0430909991 0.0319090001 0.0097059999 +-0.0432740003 0.0432740003 0.0398919992 +-0.0432740003 0.0432740003 0.0351080000 +-0.0432740003 0.0432740003 0.0148919998 +-0.0432740003 0.0432740003 0.0101079997 +-0.0432740003 0.0432740003 -0.0101079997 +-0.0432740003 0.0432740003 -0.0148919998 +-0.0432740003 0.0432740003 -0.0351080000 +-0.0432740003 0.0432740003 -0.0398919992 +-0.0432740003 0.0398919992 0.0432740003 +-0.0432740003 0.0398919992 0.0317259990 +-0.0432740003 0.0398919992 0.0182739999 +-0.0432740003 0.0398919992 0.0067260000 +-0.0432740003 0.0398919992 -0.0067260000 +-0.0432740003 0.0398919992 -0.0182739999 +-0.0432740003 0.0398919992 -0.0317259990 +-0.0432740003 0.0398919992 -0.0432740003 +-0.0432740003 0.0351080000 0.0432740003 +-0.0432740003 0.0351080000 0.0317259990 +-0.0432740003 0.0351080000 0.0182739999 +-0.0432740003 0.0351080000 0.0067260000 +-0.0432740003 0.0351080000 -0.0067260000 +-0.0432740003 0.0351080000 -0.0182739999 +-0.0432740003 0.0351080000 -0.0317259990 +-0.0432740003 0.0351080000 -0.0432740003 +-0.0432740003 0.0317259990 -0.0101079997 +-0.0432740003 0.0317259990 -0.0148919998 +-0.0432740003 0.0317259990 -0.0351080000 +-0.0432740003 0.0317259990 -0.0398919992 +-0.0432740003 0.0182739999 -0.0101079997 +-0.0432740003 0.0182739999 -0.0148919998 +-0.0432740003 0.0182739999 -0.0351080000 +-0.0432740003 0.0182739999 -0.0398919992 +-0.0432740003 0.0148919998 -0.0067260000 +-0.0432740003 0.0148919998 -0.0182739999 +-0.0432740003 0.0148919998 -0.0317259990 +-0.0432740003 0.0148919998 -0.0432740003 +-0.0432740003 0.0101079997 -0.0067260000 +-0.0432740003 0.0101079997 -0.0182739999 +-0.0432740003 0.0101079997 -0.0317259990 +-0.0432740003 0.0101079997 -0.0432740003 +-0.0432740003 0.0067260000 -0.0101079997 +-0.0432740003 0.0067260000 -0.0148919998 +-0.0432740003 0.0067260000 -0.0351080000 +-0.0432740003 0.0067260000 -0.0398919992 +-0.0432740003 -0.0067260000 0.0398919992 +-0.0432740003 -0.0067260000 0.0351080000 +-0.0432740003 -0.0067260000 0.0148919998 +-0.0432740003 -0.0067260000 0.0101079997 +-0.0432740003 -0.0067260000 -0.0101079997 +-0.0432740003 -0.0067260000 -0.0148919998 +-0.0432740003 -0.0067260000 -0.0351080000 +-0.0432740003 -0.0067260000 -0.0398919992 +-0.0432740003 -0.0101079997 0.0432740003 +-0.0432740003 -0.0101079997 0.0317259990 +-0.0432740003 -0.0101079997 0.0182739999 +-0.0432740003 -0.0101079997 0.0067260000 +-0.0432740003 -0.0101079997 -0.0067260000 +-0.0432740003 -0.0101079997 -0.0182739999 +-0.0432740003 -0.0101079997 -0.0317259990 +-0.0432740003 -0.0101079997 -0.0432740003 +-0.0432740003 -0.0148919998 0.0432740003 +-0.0432740003 -0.0148919998 0.0317259990 +-0.0432740003 -0.0148919998 0.0182739999 +-0.0432740003 -0.0148919998 0.0067260000 +-0.0432740003 -0.0148919998 -0.0067260000 +-0.0432740003 -0.0148919998 -0.0182739999 +-0.0432740003 -0.0148919998 -0.0317259990 +-0.0432740003 -0.0148919998 -0.0432740003 +-0.0432740003 -0.0182739999 0.0398919992 +-0.0432740003 -0.0182739999 0.0351080000 +-0.0432740003 -0.0182739999 0.0148919998 +-0.0432740003 -0.0182739999 0.0101079997 +-0.0432740003 -0.0182739999 -0.0101079997 +-0.0432740003 -0.0182739999 -0.0148919998 +-0.0432740003 -0.0182739999 -0.0351080000 +-0.0432740003 -0.0182739999 -0.0398919992 +-0.0432740003 -0.0317259990 0.0148919998 +-0.0432740003 -0.0317259990 0.0101079997 +-0.0432740003 -0.0317259990 -0.0101079997 +-0.0432740003 -0.0317259990 -0.0148919998 +-0.0432740003 -0.0317259990 -0.0351080000 +-0.0432740003 -0.0317259990 -0.0398919992 +-0.0432740003 -0.0351080000 0.0182739999 +-0.0432740003 -0.0351080000 0.0067260000 +-0.0432740003 -0.0351080000 -0.0067260000 +-0.0432740003 -0.0351080000 -0.0182739999 +-0.0432740003 -0.0351080000 -0.0317259990 +-0.0432740003 -0.0351080000 -0.0432740003 +-0.0432740003 -0.0398919992 0.0182739999 +-0.0432740003 -0.0398919992 0.0067260000 +-0.0432740003 -0.0398919992 -0.0067260000 +-0.0432740003 -0.0398919992 -0.0182739999 +-0.0432740003 -0.0398919992 -0.0317259990 +-0.0432740003 -0.0398919992 -0.0432740003 +-0.0432740003 -0.0432740003 0.0148919998 +-0.0432740003 -0.0432740003 0.0101079997 +-0.0432740003 -0.0432740003 -0.0101079997 +-0.0432740003 -0.0432740003 -0.0148919998 +-0.0432740003 -0.0432740003 -0.0351080000 +-0.0432740003 -0.0432740003 -0.0398919992 +-0.0432920009 0.0040210001 0.0398479998 +-0.0432920009 0.0040210001 0.0351519994 +-0.0432920009 0.0040210001 0.0148480004 +-0.0432920009 0.0040210001 0.0101520000 +-0.0434149988 0.0311549995 0.0395190008 +-0.0434149988 0.0311549995 0.0354809985 +-0.0434149988 0.0311549995 0.0145190004 +-0.0434149988 0.0311549995 0.0104809999 +-0.0434660017 0.0315340012 0.0393610001 +-0.0434660017 0.0315340012 0.0356389992 +-0.0434660017 0.0315340012 0.0143609997 +-0.0434660017 0.0315340012 0.0106389998 +-0.0435369983 0.0500000007 0.0391179994 +-0.0435369983 0.0500000007 0.0358819999 +-0.0435369983 0.0500000007 0.0141179999 +-0.0435369983 0.0500000007 0.0108820004 +-0.0435369983 0.0500000007 -0.0108820004 +-0.0435369983 0.0500000007 -0.0141179999 +-0.0435369983 0.0500000007 -0.0358819999 +-0.0435369983 0.0500000007 -0.0391179994 +-0.0435369983 0.0391179994 0.0500000007 +-0.0435369983 0.0391179994 -0.0500000007 +-0.0435369983 0.0358819999 0.0500000007 +-0.0435369983 0.0358819999 -0.0500000007 +-0.0435369983 0.0141179999 -0.0003910000 +-0.0435369983 0.0141179999 -0.0500000007 +-0.0435369983 0.0108820004 -0.0003910000 +-0.0435369983 0.0108820004 -0.0500000007 +-0.0435369983 -0.0108820004 0.0500000007 +-0.0435369983 -0.0108820004 -0.0500000007 +-0.0435369983 -0.0141179999 0.0500000007 +-0.0435369983 -0.0141179999 -0.0500000007 +-0.0435369983 -0.0250000004 0.0391179994 +-0.0435369983 -0.0250000004 0.0358819999 +-0.0435369983 -0.0358819999 0.0212500002 +-0.0435369983 -0.0358819999 -0.0500000007 +-0.0435369983 -0.0391179994 0.0212500002 +-0.0435369983 -0.0391179994 -0.0500000007 +-0.0435369983 -0.0500000007 0.0141179999 +-0.0435369983 -0.0500000007 0.0108820004 +-0.0435369983 -0.0500000007 -0.0108820004 +-0.0435369983 -0.0500000007 -0.0141179999 +-0.0435369983 -0.0500000007 -0.0358819999 +-0.0435369983 -0.0500000007 -0.0391179994 +-0.0436300002 0.0436300002 0.0387189984 +-0.0436300002 0.0436300002 0.0362810008 +-0.0436300002 0.0436300002 0.0137189999 +-0.0436300002 0.0436300002 0.0112810005 +-0.0436300002 0.0436300002 -0.0112810005 +-0.0436300002 0.0436300002 -0.0137189999 +-0.0436300002 0.0436300002 -0.0362810008 +-0.0436300002 0.0436300002 -0.0387189984 +-0.0436300002 0.0387189984 0.0436300002 +-0.0436300002 0.0387189984 0.0313699991 +-0.0436300002 0.0387189984 0.0186299998 +-0.0436300002 0.0387189984 0.0063700001 +-0.0436300002 0.0387189984 -0.0063700001 +-0.0436300002 0.0387189984 -0.0186299998 +-0.0436300002 0.0387189984 -0.0313699991 +-0.0436300002 0.0387189984 -0.0436300002 +-0.0436300002 0.0362810008 0.0436300002 +-0.0436300002 0.0362810008 0.0313699991 +-0.0436300002 0.0362810008 0.0186299998 +-0.0436300002 0.0362810008 0.0063700001 +-0.0436300002 0.0362810008 -0.0063700001 +-0.0436300002 0.0362810008 -0.0186299998 +-0.0436300002 0.0362810008 -0.0313699991 +-0.0436300002 0.0362810008 -0.0436300002 +-0.0436300002 0.0313699991 -0.0112810005 +-0.0436300002 0.0313699991 -0.0137189999 +-0.0436300002 0.0313699991 -0.0362810008 +-0.0436300002 0.0313699991 -0.0387189984 +-0.0436300002 0.0186299998 -0.0112810005 +-0.0436300002 0.0186299998 -0.0137189999 +-0.0436300002 0.0186299998 -0.0362810008 +-0.0436300002 0.0186299998 -0.0387189984 +-0.0436300002 0.0137189999 -0.0063700001 +-0.0436300002 0.0137189999 -0.0186299998 +-0.0436300002 0.0137189999 -0.0313699991 +-0.0436300002 0.0137189999 -0.0436300002 +-0.0436300002 0.0112810005 -0.0063700001 +-0.0436300002 0.0112810005 -0.0186299998 +-0.0436300002 0.0112810005 -0.0313699991 +-0.0436300002 0.0112810005 -0.0436300002 +-0.0436300002 0.0063700001 -0.0112810005 +-0.0436300002 0.0063700001 -0.0137189999 +-0.0436300002 0.0063700001 -0.0362810008 +-0.0436300002 0.0063700001 -0.0387189984 +-0.0436300002 -0.0063700001 0.0387189984 +-0.0436300002 -0.0063700001 0.0362810008 +-0.0436300002 -0.0063700001 0.0137189999 +-0.0436300002 -0.0063700001 0.0112810005 +-0.0436300002 -0.0063700001 -0.0112810005 +-0.0436300002 -0.0063700001 -0.0137189999 +-0.0436300002 -0.0063700001 -0.0362810008 +-0.0436300002 -0.0063700001 -0.0387189984 +-0.0436300002 -0.0112810005 0.0436300002 +-0.0436300002 -0.0112810005 0.0313699991 +-0.0436300002 -0.0112810005 0.0186299998 +-0.0436300002 -0.0112810005 0.0063700001 +-0.0436300002 -0.0112810005 -0.0063700001 +-0.0436300002 -0.0112810005 -0.0186299998 +-0.0436300002 -0.0112810005 -0.0313699991 +-0.0436300002 -0.0112810005 -0.0436300002 +-0.0436300002 -0.0137189999 0.0436300002 +-0.0436300002 -0.0137189999 0.0313699991 +-0.0436300002 -0.0137189999 0.0186299998 +-0.0436300002 -0.0137189999 0.0063700001 +-0.0436300002 -0.0137189999 -0.0063700001 +-0.0436300002 -0.0137189999 -0.0186299998 +-0.0436300002 -0.0137189999 -0.0313699991 +-0.0436300002 -0.0137189999 -0.0436300002 +-0.0436300002 -0.0186299998 0.0387189984 +-0.0436300002 -0.0186299998 0.0362810008 +-0.0436300002 -0.0186299998 0.0137189999 +-0.0436300002 -0.0186299998 0.0112810005 +-0.0436300002 -0.0186299998 -0.0112810005 +-0.0436300002 -0.0186299998 -0.0137189999 +-0.0436300002 -0.0186299998 -0.0362810008 +-0.0436300002 -0.0186299998 -0.0387189984 +-0.0436300002 -0.0313699991 0.0137189999 +-0.0436300002 -0.0313699991 0.0112810005 +-0.0436300002 -0.0313699991 -0.0112810005 +-0.0436300002 -0.0313699991 -0.0137189999 +-0.0436300002 -0.0313699991 -0.0362810008 +-0.0436300002 -0.0313699991 -0.0387189984 +-0.0436300002 -0.0362810008 0.0186299998 +-0.0436300002 -0.0362810008 0.0063700001 +-0.0436300002 -0.0362810008 -0.0063700001 +-0.0436300002 -0.0362810008 -0.0186299998 +-0.0436300002 -0.0362810008 -0.0313699991 +-0.0436300002 -0.0362810008 -0.0436300002 +-0.0436300002 -0.0387189984 0.0186299998 +-0.0436300002 -0.0387189984 0.0063700001 +-0.0436300002 -0.0387189984 -0.0063700001 +-0.0436300002 -0.0387189984 -0.0186299998 +-0.0436300002 -0.0387189984 -0.0313699991 +-0.0436300002 -0.0387189984 -0.0436300002 +-0.0436300002 -0.0436300002 0.0137189999 +-0.0436300002 -0.0436300002 0.0112810005 +-0.0436300002 -0.0436300002 -0.0112810005 +-0.0436300002 -0.0436300002 -0.0137189999 +-0.0436300002 -0.0436300002 -0.0362810008 +-0.0436300002 -0.0436300002 -0.0387189984 +-0.0436340012 0.0042180000 0.0386959985 +-0.0436340012 0.0042180000 0.0363040008 +-0.0436340012 0.0042180000 0.0136960000 +-0.0436340012 0.0042180000 0.0113040004 +-0.0436879992 0.0313120000 0.0383800007 +-0.0436879992 0.0313120000 0.0366199985 +-0.0436879992 0.0313120000 0.0133800004 +-0.0436879992 0.0313120000 0.0116200000 +-0.0437199995 0.0437199995 0.0381130017 +-0.0437199995 0.0437199995 0.0368870012 +-0.0437199995 0.0437199995 0.0131130004 +-0.0437199995 0.0437199995 0.0118869999 +-0.0437199995 0.0437199995 -0.0118869999 +-0.0437199995 0.0437199995 -0.0131130004 +-0.0437199995 0.0437199995 -0.0368870012 +-0.0437199995 0.0437199995 -0.0381130017 +-0.0437199995 0.0381130017 0.0437199995 +-0.0437199995 0.0381130017 0.0312799998 +-0.0437199995 0.0381130017 0.0187199991 +-0.0437199995 0.0381130017 0.0062799999 +-0.0437199995 0.0381130017 -0.0062799999 +-0.0437199995 0.0381130017 -0.0187199991 +-0.0437199995 0.0381130017 -0.0312799998 +-0.0437199995 0.0381130017 -0.0437199995 +-0.0437199995 0.0368870012 0.0437199995 +-0.0437199995 0.0368870012 0.0312799998 +-0.0437199995 0.0368870012 0.0187199991 +-0.0437199995 0.0368870012 0.0062799999 +-0.0437199995 0.0368870012 -0.0062799999 +-0.0437199995 0.0368870012 -0.0187199991 +-0.0437199995 0.0368870012 -0.0312799998 +-0.0437199995 0.0368870012 -0.0437199995 +-0.0437199995 0.0312799998 -0.0118869999 +-0.0437199995 0.0312799998 -0.0131130004 +-0.0437199995 0.0312799998 -0.0368870012 +-0.0437199995 0.0312799998 -0.0381130017 +-0.0437199995 0.0187199991 -0.0118869999 +-0.0437199995 0.0187199991 -0.0131130004 +-0.0437199995 0.0187199991 -0.0368870012 +-0.0437199995 0.0187199991 -0.0381130017 +-0.0437199995 0.0131130004 -0.0062799999 +-0.0437199995 0.0131130004 -0.0187199991 +-0.0437199995 0.0131130004 -0.0312799998 +-0.0437199995 0.0131130004 -0.0437199995 +-0.0437199995 0.0118869999 -0.0062799999 +-0.0437199995 0.0118869999 -0.0187199991 +-0.0437199995 0.0118869999 -0.0312799998 +-0.0437199995 0.0118869999 -0.0437199995 +-0.0437199995 0.0062799999 -0.0118869999 +-0.0437199995 0.0062799999 -0.0131130004 +-0.0437199995 0.0062799999 -0.0368870012 +-0.0437199995 0.0062799999 -0.0381130017 +-0.0437199995 -0.0062799999 0.0381130017 +-0.0437199995 -0.0062799999 0.0368870012 +-0.0437199995 -0.0062799999 0.0131130004 +-0.0437199995 -0.0062799999 0.0118869999 +-0.0437199995 -0.0062799999 -0.0118869999 +-0.0437199995 -0.0062799999 -0.0131130004 +-0.0437199995 -0.0062799999 -0.0368870012 +-0.0437199995 -0.0062799999 -0.0381130017 +-0.0437199995 -0.0118869999 0.0437199995 +-0.0437199995 -0.0118869999 0.0312799998 +-0.0437199995 -0.0118869999 0.0187199991 +-0.0437199995 -0.0118869999 0.0062799999 +-0.0437199995 -0.0118869999 -0.0062799999 +-0.0437199995 -0.0118869999 -0.0187199991 +-0.0437199995 -0.0118869999 -0.0312799998 +-0.0437199995 -0.0118869999 -0.0437199995 +-0.0437199995 -0.0131130004 0.0437199995 +-0.0437199995 -0.0131130004 0.0312799998 +-0.0437199995 -0.0131130004 0.0187199991 +-0.0437199995 -0.0131130004 0.0062799999 +-0.0437199995 -0.0131130004 -0.0062799999 +-0.0437199995 -0.0131130004 -0.0187199991 +-0.0437199995 -0.0131130004 -0.0312799998 +-0.0437199995 -0.0131130004 -0.0437199995 +-0.0437199995 -0.0187199991 0.0381130017 +-0.0437199995 -0.0187199991 0.0368870012 +-0.0437199995 -0.0187199991 0.0131130004 +-0.0437199995 -0.0187199991 0.0118869999 +-0.0437199995 -0.0187199991 -0.0118869999 +-0.0437199995 -0.0187199991 -0.0131130004 +-0.0437199995 -0.0187199991 -0.0368870012 +-0.0437199995 -0.0187199991 -0.0381130017 +-0.0437199995 -0.0312799998 0.0131130004 +-0.0437199995 -0.0312799998 0.0118869999 +-0.0437199995 -0.0312799998 -0.0118869999 +-0.0437199995 -0.0312799998 -0.0131130004 +-0.0437199995 -0.0312799998 -0.0368870012 +-0.0437199995 -0.0312799998 -0.0381130017 +-0.0437199995 -0.0368870012 0.0187199991 +-0.0437199995 -0.0368870012 0.0062799999 +-0.0437199995 -0.0368870012 -0.0062799999 +-0.0437199995 -0.0368870012 -0.0187199991 +-0.0437199995 -0.0368870012 -0.0312799998 +-0.0437199995 -0.0368870012 -0.0437199995 +-0.0437199995 -0.0381130017 0.0187199991 +-0.0437199995 -0.0381130017 0.0062799999 +-0.0437199995 -0.0381130017 -0.0062799999 +-0.0437199995 -0.0381130017 -0.0187199991 +-0.0437199995 -0.0381130017 -0.0312799998 +-0.0437199995 -0.0381130017 -0.0437199995 +-0.0437199995 -0.0437199995 0.0131130004 +-0.0437199995 -0.0437199995 0.0118869999 +-0.0437199995 -0.0437199995 -0.0118869999 +-0.0437199995 -0.0437199995 -0.0131130004 +-0.0437199995 -0.0437199995 -0.0368870012 +-0.0437199995 -0.0437199995 -0.0381130017 +-0.0437499993 0.0500000007 0.0375000015 +-0.0437499993 0.0500000007 0.0125000002 +-0.0437499993 0.0500000007 -0.0125000002 +-0.0437499993 0.0500000007 -0.0375000015 +-0.0437499993 0.0437499993 0.0375000015 +-0.0437499993 0.0437499993 0.0125000002 +-0.0437499993 0.0437499993 -0.0125000002 +-0.0437499993 0.0437499993 -0.0375000015 +-0.0437499993 0.0375000015 0.0500000007 +-0.0437499993 0.0375000015 0.0437499993 +-0.0437499993 0.0375000015 0.0312500000 +-0.0437499993 0.0375000015 0.0187500007 +-0.0437499993 0.0375000015 0.0062500001 +-0.0437499993 0.0375000015 -0.0062500001 +-0.0437499993 0.0375000015 -0.0187500007 +-0.0437499993 0.0375000015 -0.0312500000 +-0.0437499993 0.0375000015 -0.0437499993 +-0.0437499993 0.0375000015 -0.0500000007 +-0.0437499993 0.0312500000 -0.0125000002 +-0.0437499993 0.0312500000 -0.0375000015 +-0.0437499993 0.0187500007 -0.0125000002 +-0.0437499993 0.0187500007 -0.0375000015 +-0.0437499993 0.0125000002 -0.0003910000 +-0.0437499993 0.0125000002 -0.0062500001 +-0.0437499993 0.0125000002 -0.0187500007 +-0.0437499993 0.0125000002 -0.0312500000 +-0.0437499993 0.0125000002 -0.0437499993 +-0.0437499993 0.0125000002 -0.0500000007 +-0.0437499993 0.0062500001 -0.0125000002 +-0.0437499993 0.0062500001 -0.0375000015 +-0.0437499993 0.0042849998 0.0375000015 +-0.0437499993 0.0042849998 0.0125000002 +-0.0437499993 -0.0062500001 0.0375000015 +-0.0437499993 -0.0062500001 0.0125000002 +-0.0437499993 -0.0062500001 -0.0125000002 +-0.0437499993 -0.0062500001 -0.0375000015 +-0.0437499993 -0.0125000002 0.0500000007 +-0.0437499993 -0.0125000002 0.0437499993 +-0.0437499993 -0.0125000002 0.0312500000 +-0.0437499993 -0.0125000002 0.0187500007 +-0.0437499993 -0.0125000002 0.0062500001 +-0.0437499993 -0.0125000002 -0.0062500001 +-0.0437499993 -0.0125000002 -0.0187500007 +-0.0437499993 -0.0125000002 -0.0312500000 +-0.0437499993 -0.0125000002 -0.0437499993 +-0.0437499993 -0.0125000002 -0.0500000007 +-0.0437499993 -0.0187500007 0.0375000015 +-0.0437499993 -0.0187500007 0.0125000002 +-0.0437499993 -0.0187500007 -0.0125000002 +-0.0437499993 -0.0187500007 -0.0375000015 +-0.0437499993 -0.0250000004 0.0375000015 +-0.0437499993 -0.0312500000 0.0125000002 +-0.0437499993 -0.0312500000 -0.0125000002 +-0.0437499993 -0.0312500000 -0.0375000015 +-0.0437499993 -0.0375000015 0.0212500002 +-0.0437499993 -0.0375000015 0.0187500007 +-0.0437499993 -0.0375000015 0.0062500001 +-0.0437499993 -0.0375000015 -0.0062500001 +-0.0437499993 -0.0375000015 -0.0187500007 +-0.0437499993 -0.0375000015 -0.0312500000 +-0.0437499993 -0.0375000015 -0.0437499993 +-0.0437499993 -0.0375000015 -0.0500000007 +-0.0437499993 -0.0437499993 0.0125000002 +-0.0437499993 -0.0437499993 -0.0125000002 +-0.0437499993 -0.0437499993 -0.0375000015 +-0.0437499993 -0.0500000007 0.0125000002 +-0.0437499993 -0.0500000007 -0.0125000002 +-0.0437499993 -0.0500000007 -0.0375000015 +-0.0439650007 0.0314729996 0.0391529985 +-0.0439650007 0.0314729996 0.0358470008 +-0.0439650007 0.0314729996 0.0141530000 +-0.0439650007 0.0314729996 0.0108470004 +-0.0444089994 0.0317290016 0.0398989990 +-0.0444089994 0.0317290016 0.0351010002 +-0.0444089994 0.0317290016 0.0148989996 +-0.0444089994 0.0317290016 0.0101009998 +-0.0450120009 0.0320769995 0.0406070016 +-0.0450120009 0.0320769995 0.0343930013 +-0.0450120009 0.0320769995 0.0156070003 +-0.0450120009 0.0320769995 0.0093930000 +-0.0457639992 0.0325109996 0.0412649997 +-0.0457639992 0.0325109996 0.0337349996 +-0.0457639992 0.0325109996 0.0162649993 +-0.0457639992 0.0325109996 0.0087350002 +-0.0471529998 0.0062500001 0.0375000015 +-0.0471529998 0.0062500001 0.0125000002 +-0.0472000018 0.0062770001 0.0380790010 +-0.0472000018 0.0062770001 0.0369209982 +-0.0472000018 0.0062770001 0.0130789997 +-0.0472000018 0.0062770001 0.0119209997 +-0.0473389998 0.0063570002 0.0386530012 +-0.0473389998 0.0063570002 0.0363470018 +-0.0473389998 0.0063570002 0.0136529999 +-0.0473389998 0.0063570002 0.0113469996 +-0.0475700013 0.0064900001 0.0392169990 +-0.0475700013 0.0064900001 0.0357830003 +-0.0475700013 0.0064900001 0.0142170005 +-0.0475700013 0.0064900001 0.0107829999 +-0.0476679988 0.0336109996 0.0423920006 +-0.0476679988 0.0336109996 0.0326079987 +-0.0476679988 0.0336109996 0.0173920002 +-0.0476679988 0.0336109996 0.0076080002 +-0.0478900000 0.0066749998 0.0397659987 +-0.0478900000 0.0066749998 0.0352340005 +-0.0478900000 0.0066749998 0.0147660002 +-0.0478900000 0.0066749998 0.0102340002 +-0.0487870015 0.0071930001 0.0408019982 +-0.0487870015 0.0071930001 0.0341980010 +-0.0487870015 0.0071930001 0.0158019997 +-0.0487870015 0.0071930001 0.0091979997 +-0.0500000007 0.0500000007 0.0500000007 +-0.0500000007 0.0500000007 -0.0500000007 +-0.0500000007 0.0437499993 -0.0125000002 +-0.0500000007 0.0437499993 -0.0375000015 +-0.0500000007 0.0437440015 0.0372200012 +-0.0500000007 0.0437440015 0.0122199999 +-0.0500000007 0.0436130017 0.0388000011 +-0.0500000007 0.0436130017 0.0137999998 +-0.0500000007 0.0435369983 -0.0108820004 +-0.0500000007 0.0435369983 -0.0141179999 +-0.0500000007 0.0435369983 -0.0358819999 +-0.0500000007 0.0435369983 -0.0391179994 +-0.0500000007 0.0434719995 0.0356579982 +-0.0500000007 0.0434719995 0.0106579997 +-0.0500000007 0.0430900007 0.0402959995 +-0.0500000007 0.0430900007 0.0152960001 +-0.0500000007 0.0429130010 -0.0093750004 +-0.0500000007 0.0429130010 -0.0156250000 +-0.0500000007 0.0429130010 -0.0343750007 +-0.0500000007 0.0429130010 -0.0406249985 +-0.0500000007 0.0428170003 0.0342149995 +-0.0500000007 0.0428170003 0.0092150001 +-0.0500000007 0.0422060005 0.0416130014 +-0.0500000007 0.0422060005 0.0166129991 +-0.0500000007 0.0419190004 -0.0080810003 +-0.0500000007 0.0419190004 -0.0169190001 +-0.0500000007 0.0419190004 -0.0330809988 +-0.0500000007 0.0419190004 -0.0419190004 +-0.0500000007 0.0418189988 0.0329830013 +-0.0500000007 0.0418189988 0.0079830000 +-0.0500000007 0.0410199985 0.0426639989 +-0.0500000007 0.0410199985 0.0176640004 +-0.0500000007 0.0406249985 -0.0070870002 +-0.0500000007 0.0406249985 -0.0179130007 +-0.0500000007 0.0406249985 -0.0320869982 +-0.0500000007 0.0406249985 -0.0429130010 +-0.0500000007 0.0405439995 0.0320409983 +-0.0500000007 0.0405439995 0.0070409998 +-0.0500000007 0.0396069996 0.0433840007 +-0.0500000007 0.0396069996 0.0183840003 +-0.0500000007 0.0391179994 -0.0064630001 +-0.0500000007 0.0391179994 -0.0185369998 +-0.0500000007 0.0391179994 -0.0314630009 +-0.0500000007 0.0391179994 -0.0435369983 +-0.0500000007 0.0390730016 0.0314510018 +-0.0500000007 0.0390730016 0.0064510000 +-0.0500000007 0.0380589999 0.0437249988 +-0.0500000007 0.0380589999 0.0187250003 +-0.0500000007 0.0375000015 0.0312500000 +-0.0500000007 0.0375000015 0.0062500001 +-0.0500000007 0.0375000015 -0.0062500001 +-0.0500000007 0.0375000015 -0.0187500007 +-0.0500000007 0.0375000015 -0.0312500000 +-0.0500000007 0.0375000015 -0.0437499993 +-0.0500000007 0.0364749990 0.0436649993 +-0.0500000007 0.0364749990 0.0186650008 +-0.0500000007 0.0362000018 0.0313870013 +-0.0500000007 0.0362000018 0.0063870000 +-0.0500000007 0.0358819999 -0.0064630001 +-0.0500000007 0.0358819999 -0.0185369998 +-0.0500000007 0.0358819999 -0.0314630009 +-0.0500000007 0.0358819999 -0.0435369983 +-0.0500000007 0.0349569991 0.0500000007 +-0.0500000007 0.0349569991 0.0432090014 +-0.0500000007 0.0349569991 0.0317910016 +-0.0500000007 0.0349569991 0.0182089992 +-0.0500000007 0.0349569991 0.0067909998 +-0.0500000007 0.0349569991 -0.0003910000 +-0.0500000007 0.0343750007 -0.0070870002 +-0.0500000007 0.0343750007 -0.0179130007 +-0.0500000007 0.0343750007 -0.0320869982 +-0.0500000007 0.0343750007 -0.0429130010 +-0.0500000007 0.0330809988 -0.0080810003 +-0.0500000007 0.0330809988 -0.0169190001 +-0.0500000007 0.0330809988 -0.0330809988 +-0.0500000007 0.0330809988 -0.0419190004 +-0.0500000007 0.0320869982 -0.0093750004 +-0.0500000007 0.0320869982 -0.0156250000 +-0.0500000007 0.0320869982 -0.0343750007 +-0.0500000007 0.0320869982 -0.0406249985 +-0.0500000007 0.0314630009 -0.0108820004 +-0.0500000007 0.0314630009 -0.0141179999 +-0.0500000007 0.0314630009 -0.0358819999 +-0.0500000007 0.0314630009 -0.0391179994 +-0.0500000007 0.0312500000 -0.0125000002 +-0.0500000007 0.0312500000 -0.0375000015 +-0.0500000007 0.0187500007 -0.0125000002 +-0.0500000007 0.0187500007 -0.0375000015 +-0.0500000007 0.0185369998 -0.0108820004 +-0.0500000007 0.0185369998 -0.0141179999 +-0.0500000007 0.0185369998 -0.0358819999 +-0.0500000007 0.0185369998 -0.0391179994 +-0.0500000007 0.0179130007 -0.0093750004 +-0.0500000007 0.0179130007 -0.0156250000 +-0.0500000007 0.0179130007 -0.0343750007 +-0.0500000007 0.0179130007 -0.0406249985 +-0.0500000007 0.0169190001 -0.0080810003 +-0.0500000007 0.0169190001 -0.0169190001 +-0.0500000007 0.0169190001 -0.0330809988 +-0.0500000007 0.0169190001 -0.0419190004 +-0.0500000007 0.0156250000 -0.0070870002 +-0.0500000007 0.0156250000 -0.0179130007 +-0.0500000007 0.0156250000 -0.0320869982 +-0.0500000007 0.0156250000 -0.0429130010 +-0.0500000007 0.0141179999 -0.0064630001 +-0.0500000007 0.0141179999 -0.0185369998 +-0.0500000007 0.0141179999 -0.0314630009 +-0.0500000007 0.0141179999 -0.0435369983 +-0.0500000007 0.0125000002 -0.0062500001 +-0.0500000007 0.0125000002 -0.0187500007 +-0.0500000007 0.0125000002 -0.0312500000 +-0.0500000007 0.0125000002 -0.0437499993 +-0.0500000007 0.0108820004 -0.0064630001 +-0.0500000007 0.0108820004 -0.0185369998 +-0.0500000007 0.0108820004 -0.0314630009 +-0.0500000007 0.0108820004 -0.0435369983 +-0.0500000007 0.0093750004 -0.0070870002 +-0.0500000007 0.0093750004 -0.0179130007 +-0.0500000007 0.0093750004 -0.0320869982 +-0.0500000007 0.0093750004 -0.0429130010 +-0.0500000007 0.0080810003 -0.0080810003 +-0.0500000007 0.0080810003 -0.0169190001 +-0.0500000007 0.0080810003 -0.0330809988 +-0.0500000007 0.0080810003 -0.0419190004 +-0.0500000007 0.0078929998 0.0500000007 +-0.0500000007 0.0078929998 0.0417240001 +-0.0500000007 0.0078929998 0.0332759991 +-0.0500000007 0.0078929998 0.0167239998 +-0.0500000007 0.0078929998 0.0082759997 +-0.0500000007 0.0078929998 -0.0003910000 +-0.0500000007 0.0070870002 -0.0093750004 +-0.0500000007 0.0070870002 -0.0156250000 +-0.0500000007 0.0070870002 -0.0343750007 +-0.0500000007 0.0070870002 -0.0406249985 +-0.0500000007 0.0069990000 0.0404679999 +-0.0500000007 0.0069990000 0.0345319994 +-0.0500000007 0.0069990000 0.0154680004 +-0.0500000007 0.0069990000 0.0095319999 +-0.0500000007 0.0064630001 -0.0108820004 +-0.0500000007 0.0064630001 -0.0141179999 +-0.0500000007 0.0064630001 -0.0358819999 +-0.0500000007 0.0064630001 -0.0391179994 +-0.0500000007 0.0064400001 0.0390300006 +-0.0500000007 0.0064400001 0.0359699987 +-0.0500000007 0.0064400001 0.0140300002 +-0.0500000007 0.0064400001 0.0109700002 +-0.0500000007 0.0062500001 0.0375000015 +-0.0500000007 0.0062500001 0.0125000002 +-0.0500000007 0.0062500001 -0.0125000002 +-0.0500000007 0.0062500001 -0.0375000015 +-0.0500000007 -0.0062500001 0.0375000015 +-0.0500000007 -0.0062500001 0.0125000002 +-0.0500000007 -0.0062500001 -0.0125000002 +-0.0500000007 -0.0062500001 -0.0375000015 +-0.0500000007 -0.0064630001 0.0391179994 +-0.0500000007 -0.0064630001 0.0358819999 +-0.0500000007 -0.0064630001 0.0141179999 +-0.0500000007 -0.0064630001 0.0108820004 +-0.0500000007 -0.0064630001 -0.0108820004 +-0.0500000007 -0.0064630001 -0.0141179999 +-0.0500000007 -0.0064630001 -0.0358819999 +-0.0500000007 -0.0064630001 -0.0391179994 +-0.0500000007 -0.0070870002 0.0406249985 +-0.0500000007 -0.0070870002 0.0343750007 +-0.0500000007 -0.0070870002 0.0156250000 +-0.0500000007 -0.0070870002 0.0093750004 +-0.0500000007 -0.0070870002 -0.0093750004 +-0.0500000007 -0.0070870002 -0.0156250000 +-0.0500000007 -0.0070870002 -0.0343750007 +-0.0500000007 -0.0070870002 -0.0406249985 +-0.0500000007 -0.0080810003 0.0419190004 +-0.0500000007 -0.0080810003 0.0330809988 +-0.0500000007 -0.0080810003 0.0169190001 +-0.0500000007 -0.0080810003 0.0080810003 +-0.0500000007 -0.0080810003 -0.0080810003 +-0.0500000007 -0.0080810003 -0.0169190001 +-0.0500000007 -0.0080810003 -0.0330809988 +-0.0500000007 -0.0080810003 -0.0419190004 +-0.0500000007 -0.0093750004 0.0429130010 +-0.0500000007 -0.0093750004 0.0320869982 +-0.0500000007 -0.0093750004 0.0179130007 +-0.0500000007 -0.0093750004 0.0070870002 +-0.0500000007 -0.0093750004 -0.0070870002 +-0.0500000007 -0.0093750004 -0.0179130007 +-0.0500000007 -0.0093750004 -0.0320869982 +-0.0500000007 -0.0093750004 -0.0429130010 +-0.0500000007 -0.0108820004 0.0435369983 +-0.0500000007 -0.0108820004 0.0314630009 +-0.0500000007 -0.0108820004 0.0185369998 +-0.0500000007 -0.0108820004 0.0064630001 +-0.0500000007 -0.0108820004 -0.0064630001 +-0.0500000007 -0.0108820004 -0.0185369998 +-0.0500000007 -0.0108820004 -0.0314630009 +-0.0500000007 -0.0108820004 -0.0435369983 +-0.0500000007 -0.0125000002 0.0437499993 +-0.0500000007 -0.0125000002 0.0312500000 +-0.0500000007 -0.0125000002 0.0187500007 +-0.0500000007 -0.0125000002 0.0062500001 +-0.0500000007 -0.0125000002 -0.0062500001 +-0.0500000007 -0.0125000002 -0.0187500007 +-0.0500000007 -0.0125000002 -0.0312500000 +-0.0500000007 -0.0125000002 -0.0437499993 +-0.0500000007 -0.0141179999 0.0435369983 +-0.0500000007 -0.0141179999 0.0314630009 +-0.0500000007 -0.0141179999 0.0185369998 +-0.0500000007 -0.0141179999 0.0064630001 +-0.0500000007 -0.0141179999 -0.0064630001 +-0.0500000007 -0.0141179999 -0.0185369998 +-0.0500000007 -0.0141179999 -0.0314630009 +-0.0500000007 -0.0141179999 -0.0435369983 +-0.0500000007 -0.0156250000 0.0429130010 +-0.0500000007 -0.0156250000 0.0320869982 +-0.0500000007 -0.0156250000 0.0179130007 +-0.0500000007 -0.0156250000 0.0070870002 +-0.0500000007 -0.0156250000 -0.0070870002 +-0.0500000007 -0.0156250000 -0.0179130007 +-0.0500000007 -0.0156250000 -0.0320869982 +-0.0500000007 -0.0156250000 -0.0429130010 +-0.0500000007 -0.0169190001 0.0419190004 +-0.0500000007 -0.0169190001 0.0330809988 +-0.0500000007 -0.0169190001 0.0169190001 +-0.0500000007 -0.0169190001 0.0080810003 +-0.0500000007 -0.0169190001 -0.0080810003 +-0.0500000007 -0.0169190001 -0.0169190001 +-0.0500000007 -0.0169190001 -0.0330809988 +-0.0500000007 -0.0169190001 -0.0419190004 +-0.0500000007 -0.0179130007 0.0406249985 +-0.0500000007 -0.0179130007 0.0343750007 +-0.0500000007 -0.0179130007 0.0156250000 +-0.0500000007 -0.0179130007 0.0093750004 +-0.0500000007 -0.0179130007 -0.0093750004 +-0.0500000007 -0.0179130007 -0.0156250000 +-0.0500000007 -0.0179130007 -0.0343750007 +-0.0500000007 -0.0179130007 -0.0406249985 +-0.0500000007 -0.0185369998 0.0391179994 +-0.0500000007 -0.0185369998 0.0358819999 +-0.0500000007 -0.0185369998 0.0141179999 +-0.0500000007 -0.0185369998 0.0108820004 +-0.0500000007 -0.0185369998 -0.0108820004 +-0.0500000007 -0.0185369998 -0.0141179999 +-0.0500000007 -0.0185369998 -0.0358819999 +-0.0500000007 -0.0185369998 -0.0391179994 +-0.0500000007 -0.0187500007 0.0375000015 +-0.0500000007 -0.0187500007 0.0125000002 +-0.0500000007 -0.0187500007 -0.0125000002 +-0.0500000007 -0.0187500007 -0.0375000015 +-0.0500000007 -0.0250000004 0.0500000007 +-0.0500000007 -0.0250000004 0.0250000004 +-0.0500000007 -0.0251279995 0.0240289997 +-0.0500000007 -0.0255020000 0.0231250003 +-0.0500000007 -0.0260979999 0.0223479997 +-0.0500000007 -0.0268750004 0.0217519999 +-0.0500000007 -0.0277789999 0.0213779993 +-0.0500000007 -0.0287500005 0.0212500002 +-0.0500000007 -0.0312500000 0.0125000002 +-0.0500000007 -0.0312500000 -0.0125000002 +-0.0500000007 -0.0312500000 -0.0375000015 +-0.0500000007 -0.0314630009 0.0141179999 +-0.0500000007 -0.0314630009 0.0108820004 +-0.0500000007 -0.0314630009 -0.0108820004 +-0.0500000007 -0.0314630009 -0.0141179999 +-0.0500000007 -0.0314630009 -0.0358819999 +-0.0500000007 -0.0314630009 -0.0391179994 +-0.0500000007 -0.0320869982 0.0156250000 +-0.0500000007 -0.0320869982 0.0093750004 +-0.0500000007 -0.0320869982 -0.0093750004 +-0.0500000007 -0.0320869982 -0.0156250000 +-0.0500000007 -0.0320869982 -0.0343750007 +-0.0500000007 -0.0320869982 -0.0406249985 +-0.0500000007 -0.0330809988 0.0169190001 +-0.0500000007 -0.0330809988 0.0080810003 +-0.0500000007 -0.0330809988 -0.0080810003 +-0.0500000007 -0.0330809988 -0.0169190001 +-0.0500000007 -0.0330809988 -0.0330809988 +-0.0500000007 -0.0330809988 -0.0419190004 +-0.0500000007 -0.0343750007 0.0179130007 +-0.0500000007 -0.0343750007 0.0070870002 +-0.0500000007 -0.0343750007 -0.0070870002 +-0.0500000007 -0.0343750007 -0.0179130007 +-0.0500000007 -0.0343750007 -0.0320869982 +-0.0500000007 -0.0343750007 -0.0429130010 +-0.0500000007 -0.0358819999 0.0185369998 +-0.0500000007 -0.0358819999 0.0064630001 +-0.0500000007 -0.0358819999 -0.0064630001 +-0.0500000007 -0.0358819999 -0.0185369998 +-0.0500000007 -0.0358819999 -0.0314630009 +-0.0500000007 -0.0358819999 -0.0435369983 +-0.0500000007 -0.0375000015 0.0187500007 +-0.0500000007 -0.0375000015 0.0062500001 +-0.0500000007 -0.0375000015 -0.0062500001 +-0.0500000007 -0.0375000015 -0.0187500007 +-0.0500000007 -0.0375000015 -0.0312500000 +-0.0500000007 -0.0375000015 -0.0437499993 +-0.0500000007 -0.0391179994 0.0185369998 +-0.0500000007 -0.0391179994 0.0064630001 +-0.0500000007 -0.0391179994 -0.0064630001 +-0.0500000007 -0.0391179994 -0.0185369998 +-0.0500000007 -0.0391179994 -0.0314630009 +-0.0500000007 -0.0391179994 -0.0435369983 +-0.0500000007 -0.0406249985 0.0179130007 +-0.0500000007 -0.0406249985 0.0070870002 +-0.0500000007 -0.0406249985 -0.0070870002 +-0.0500000007 -0.0406249985 -0.0179130007 +-0.0500000007 -0.0406249985 -0.0320869982 +-0.0500000007 -0.0406249985 -0.0429130010 +-0.0500000007 -0.0419190004 0.0169190001 +-0.0500000007 -0.0419190004 0.0080810003 +-0.0500000007 -0.0419190004 -0.0080810003 +-0.0500000007 -0.0419190004 -0.0169190001 +-0.0500000007 -0.0419190004 -0.0330809988 +-0.0500000007 -0.0419190004 -0.0419190004 +-0.0500000007 -0.0429130010 0.0156250000 +-0.0500000007 -0.0429130010 0.0093750004 +-0.0500000007 -0.0429130010 -0.0093750004 +-0.0500000007 -0.0429130010 -0.0156250000 +-0.0500000007 -0.0429130010 -0.0343750007 +-0.0500000007 -0.0429130010 -0.0406249985 +-0.0500000007 -0.0435369983 0.0141179999 +-0.0500000007 -0.0435369983 0.0108820004 +-0.0500000007 -0.0435369983 -0.0108820004 +-0.0500000007 -0.0435369983 -0.0141179999 +-0.0500000007 -0.0435369983 -0.0358819999 +-0.0500000007 -0.0435369983 -0.0391179994 +-0.0500000007 -0.0437499993 0.0125000002 +-0.0500000007 -0.0437499993 -0.0125000002 +-0.0500000007 -0.0437499993 -0.0375000015 +-0.0500000007 -0.0500000007 0.0212500002 +-0.0500000007 -0.0500000007 -0.0500000007 +0.0314685032 0.0188249983 0.0389624983 +0.0313510001 0.0187769998 0.0392495021 +3 8523 8572 8522 +3 8572 8571 8522 +3 8475 8474 8421 +3 8373 8397 8396 +3 8425 8470 8462 +3 8487 8494 8486 +3 8496 8497 8504 +3 8520 8570 8569 +3 8520 8569 8563 +3 8520 8563 8528 +3 8563 8557 8528 +3 8557 8536 8528 +3 8542 8557 8553 +3 8536 8557 8542 +3 8535 8553 8556 +3 8542 8553 8535 +3 8455 8443 8450 +3 8428 8472 8464 +3 8625 8617 8618 +3 8625 8618 8623 +3 8611 8612 8618 +3 8612 8605 8606 +3 8599 8600 8606 +3 8587 8588 8593 +3 8582 8588 8587 +3 8582 8587 8581 +3 8582 8581 8576 +3 8506 8507 8514 +3 8515 8522 8514 +3 8522 8565 8530 +3 8543 8559 8554 +3 8543 8554 8537 +3 8564 8537 8558 +3 8537 8554 8558 +3 8529 8537 8564 +3 8521 8564 8570 +3 8529 8564 8521 +3 8474 8483 8482 +3 8408 8409 8412 +3 8447 8451 8437 +3 8429 8428 8419 +3 8428 8415 8419 +3 8411 8415 8428 +3 8411 8428 8407 +3 8428 8403 8407 +3 8399 8403 8428 +3 8358 8369 8368 +3 8368 8373 8372 +3 8383 8385 8379 +3 8323 8320 8315 +3 8315 8312 8307 +3 8307 8304 8301 +3 8300 8308 8301 +3 8614 8607 8608 +3 8601 8602 8608 +3 8595 8589 8590 +3 8589 8583 8590 +3 8583 8584 8590 +3 8571 8578 8577 +3 8578 8583 8577 +3 8584 8583 8578 +3 8530 8559 8538 +3 8559 8543 8538 +3 8565 8559 8530 +3 8571 8565 8522 +3 8578 8571 8572 +3 8626 8620 8624 +3 8626 8624 8621 +3 8626 8621 8615 +3 8626 8615 8609 +3 8626 8609 8603 +3 8626 8603 8597 +3 8626 8597 8591 +3 8626 8591 8585 +3 8626 8508 8500 +3 8572 8531 8566 +3 8531 8560 8566 +3 8523 8531 8572 +3 8515 8523 8522 +3 8507 8515 8514 +3 8499 8507 8506 +3 8499 8506 8498 +3 8499 8498 8491 +3 8544 8560 8539 +3 8560 8531 8539 +3 8555 8560 8544 +3 8555 8544 8561 +3 8544 8540 8561 +3 8540 8532 8561 +3 8532 8567 8561 +3 8573 8567 8532 +3 8573 8532 8524 +3 8573 8524 8579 +3 8524 8516 8579 +3 8516 8508 8579 +3 8508 8585 8579 +3 8626 8585 8508 +3 8410 8626 8500 +3 8410 8500 8414 +3 8500 8492 8414 +3 8492 8484 8414 +3 8484 8418 8414 +3 8422 8418 8484 +3 8422 8484 8476 +3 8422 8476 8432 +3 8476 8468 8432 +3 8468 8460 8432 +3 8460 8440 8432 +3 8448 8440 8460 +3 8448 8460 8452 +3 8448 8452 8459 +3 8448 8459 8439 +3 8475 8431 8467 +3 8431 8459 8467 +3 8439 8459 8431 +3 8482 8491 8490 +3 8491 8498 8490 +3 8483 8491 8482 +3 8475 8483 8474 +3 8431 8475 8421 +3 8473 8428 8465 +3 8428 8429 8465 +3 8429 8437 8465 +3 8437 8457 8465 +3 8451 8457 8437 +3 8458 8451 8447 +3 8458 8447 8438 +3 8458 8438 8430 +3 8458 8430 8466 +3 8430 8420 8466 +3 8420 8474 8466 +3 8421 8474 8420 +3 8421 8420 8416 +3 8421 8416 8417 +3 8416 8412 8417 +3 8412 8413 8417 +3 8409 8413 8412 +3 8405 8409 8408 +3 8405 8408 8404 +3 8405 8404 8401 +3 8300 8360 8352 +3 8370 8398 8374 +3 8374 8394 8378 +3 8384 8390 8386 +3 8384 8386 8389 +3 8384 8389 8381 +3 8397 8377 8393 +3 8377 8389 8393 +3 8381 8389 8377 +3 8396 8401 8400 +3 8401 8404 8400 +3 8397 8401 8396 +3 8377 8397 8373 +3 8395 8371 8391 +3 8371 8375 8391 +3 8375 8379 8391 +3 8379 8387 8391 +3 8385 8387 8379 +3 8388 8385 8383 +3 8388 8383 8380 +3 8388 8380 8376 +3 8388 8376 8392 +3 8376 8372 8392 +3 8372 8396 8392 +3 8373 8396 8372 +3 8369 8373 8368 +3 8359 8369 8358 +3 8359 8358 8351 +3 8340 8351 8350 +3 8351 8358 8350 +3 8341 8351 8340 +3 8341 8340 8333 +3 8302 8309 8300 +3 8302 8300 8310 +3 8300 8318 8310 +3 8326 8318 8300 +3 8326 8300 8334 +3 8300 8342 8334 +3 8352 8342 8300 +3 8527 8550 8549 +3 8550 8535 8551 +3 8602 8595 8596 +3 8595 8590 8596 +3 8601 8595 8602 +3 8607 8601 8608 +3 8613 8607 8614 +3 8613 8614 8619 +3 8614 8620 8619 +3 8620 8626 8619 +3 8626 8623 8619 +3 8625 8623 8626 +3 8378 8390 8382 +3 8390 8384 8382 +3 8394 8390 8378 +3 8398 8394 8374 +3 8402 8398 8370 +3 8402 8370 8360 +3 8402 8360 8406 +3 8360 8300 8406 +3 8300 8410 8406 +3 8626 8410 8300 +3 8300 8304 8299 +3 8361 8353 8362 +3 8345 8353 8361 +3 8345 8361 8337 +3 8361 8299 8337 +3 8299 8329 8337 +3 8321 8329 8299 +3 8321 8299 8313 +3 8299 8305 8313 +3 8303 8305 8299 +3 8303 8299 8311 +3 8319 8322 8327 +3 8327 8330 8335 +3 8335 8338 8343 +3 8343 8346 8347 +3 8347 8354 8355 +3 8355 8364 8363 +3 8354 8364 8355 +3 8346 8354 8347 +3 8338 8346 8343 +3 8330 8338 8335 +3 8322 8330 8327 +3 8314 8322 8319 +3 8314 8319 8311 +3 8314 8311 8306 +3 8311 8299 8306 +3 8299 8304 8306 +3 8324 8333 8332 +3 8333 8340 8332 +3 8325 8333 8324 +3 8325 8324 8316 +3 8325 8316 8317 +3 8316 8308 8317 +3 8308 8309 8317 +3 8300 8309 8308 +3 8304 8300 8301 +3 8312 8304 8307 +3 8320 8312 8315 +3 8328 8320 8323 +3 8328 8323 8331 +3 8328 8331 8336 +3 8331 8339 8336 +3 8339 8344 8336 +3 8365 8356 8366 +3 8356 8348 8366 +3 8348 8344 8366 +3 8344 8339 8366 +3 8339 8349 8366 +3 8349 8357 8366 +3 8357 8367 8366 +3 8367 8371 8366 +3 8371 8395 8366 +3 8395 8399 8366 +3 8399 8428 8366 +3 8427 8428 8436 +3 8569 8576 8575 +3 8576 8581 8575 +3 8570 8576 8569 +3 8521 8570 8520 +3 8521 8520 8513 +3 8520 8512 8513 +3 8512 8504 8513 +3 8504 8505 8513 +3 8497 8505 8504 +3 8489 8497 8496 +3 8489 8496 8488 +3 8489 8488 8480 +3 8489 8480 8481 +3 8480 8472 8481 +3 8472 8473 8481 +3 8428 8473 8472 +3 8436 8428 8464 +3 8436 8464 8456 +3 8436 8456 8444 +3 8456 8450 8444 +3 8450 8446 8444 +3 8443 8446 8450 +3 8435 8443 8455 +3 8435 8455 8463 +3 8435 8463 8426 +3 8494 8495 8502 +3 8495 8503 8502 +3 8487 8495 8494 +3 8479 8487 8486 +3 8479 8486 8478 +3 8479 8478 8470 +3 8479 8470 8471 +3 8470 8426 8471 +3 8426 8463 8471 +3 8425 8426 8470 +3 8434 8425 8462 +3 8434 8462 8454 +3 8434 8454 8442 +3 8454 8449 8442 +3 8449 8445 8442 +3 8441 8445 8449 +3 8441 8449 8453 +3 8441 8453 8433 +3 8493 8423 8485 +3 8423 8477 8485 +3 8469 8477 8423 +3 8469 8423 8461 +3 8423 8433 8461 +3 8433 8453 8461 +3 8424 8433 8423 +3 8533 8541 8545 +3 8533 8545 8525 +3 8545 8517 8525 +3 8509 8517 8545 +3 8509 8545 8501 +3 8545 8493 8501 +3 8423 8493 8545 +3 8600 8593 8594 +3 8593 8588 8594 +3 8599 8593 8600 +3 8605 8599 8606 +3 8611 8605 8612 +3 8617 8611 8618 +3 8622 8617 8625 +3 8622 8625 8616 +3 8625 8610 8616 +3 8604 8610 8625 +3 8604 8625 8598 +3 8625 8592 8598 +3 8586 8592 8625 +3 8586 8625 8552 +3 8586 8552 8580 +3 8552 8574 8580 +3 8568 8574 8552 +3 8568 8552 8562 +3 8552 8551 8562 +3 8551 8556 8562 +3 8535 8556 8551 +3 8527 8535 8550 +3 8519 8527 8549 +3 8519 8549 8548 +3 8519 8548 8547 +3 8519 8547 8511 +3 8547 8546 8511 +3 8546 8503 8511 +3 8502 8503 8546 +3 8502 8546 8510 +3 8546 8518 8510 +3 8526 8518 8546 +3 8526 8546 8534 +3 8546 8541 8534 +3 8545 8541 8546 +3 779 955 964 +3 964 1070 1072 +3 773 775 630 +3 2220 2339 1981 +3 1072 1152 1154 +3 1152 1309 1154 +3 1070 1152 1072 +3 955 1070 964 +3 777 955 779 +3 777 779 634 +3 777 634 632 +3 344 1156 1319 +3 1074 1156 344 +3 1074 344 974 +3 344 781 974 +3 636 781 344 +3 636 344 401 +3 344 634 401 +3 632 634 344 +3 632 344 386 +3 771 905 928 +3 928 1052 1064 +3 2206 1975 2302 +3 2206 2302 1977 +3 1830 1661 1652 +3 1455 1453 1541 +3 1283 1453 1455 +3 1283 1455 1291 +3 1283 1291 1148 +3 1068 1148 1150 +3 1148 1291 1150 +3 1066 1148 1068 +3 1066 1068 937 +3 1457 1309 1299 +3 1309 1152 1299 +3 1459 1309 1457 +3 1459 1457 1545 +3 1457 1543 1545 +3 1543 1670 1545 +3 1670 1679 1545 +3 1836 1679 1670 +3 1836 1670 1834 +3 1836 1834 1983 +3 1834 1981 1983 +3 1981 2339 1983 +3 2339 2235 1983 +3 1985 2235 2339 +3 1985 2339 1838 +3 2339 1689 1838 +3 1547 1689 2339 +3 1547 2339 1461 +3 2339 1319 1461 +3 344 1319 2339 +3 1652 1541 1539 +3 1541 1453 1539 +3 1661 1541 1652 +3 1832 1661 1830 +3 1832 1830 1979 +3 1830 1977 1979 +3 1977 2302 1979 +3 2302 2220 1979 +3 2339 2220 2302 +3 1390 1439 1524 +3 1258 1439 1390 +3 1258 1390 1337 +3 1258 1337 1133 +3 1643 2302 1828 +3 2302 1975 1828 +3 1555 2302 1643 +3 1555 1643 1537 +3 1555 1537 1451 +3 1555 1451 1473 +3 1451 1279 1473 +3 1279 1392 1473 +3 1338 1392 1279 +3 1338 1279 1146 +3 1338 1146 1334 +3 1146 1064 1334 +3 1064 1133 1334 +3 1133 1337 1334 +3 1052 1133 1064 +3 905 1052 928 +3 759 905 771 +3 759 771 626 +3 759 626 614 +3 2272 1957 1817 +3 1957 2258 2191 +3 2272 2258 1957 +3 2281 2272 1817 +3 775 937 946 +3 937 1068 946 +3 773 937 775 +3 628 773 630 +3 628 630 372 +3 630 386 372 +3 386 344 372 +3 344 1 372 +3 1 626 372 +3 614 626 1 +3 614 1 365 +3 1 615 365 +3 760 615 1 +3 760 1 906 +3 1 1053 906 +3 1135 1053 1 +3 1135 1 1259 +3 1 2294 1259 +3 2294 1440 1259 +3 1526 1440 2294 +3 1526 2294 1622 +3 2294 1817 1622 +3 2281 1817 2294 +3 2281 2294 2300 +3 6296 6394 6542 +3 7276 7342 7432 +3 8250 8182 7974 +3 7198 7078 7284 +3 7582 7665 7666 +3 7582 7666 7528 +3 7582 7528 7490 +3 7528 7432 7490 +3 7432 7398 7490 +3 7342 7398 7432 +3 7275 7342 7276 +3 7275 7276 7192 +3 7276 7076 7192 +3 7076 7140 7192 +3 7042 7140 7076 +3 7042 7076 6978 +3 7042 6978 6948 +3 6978 6880 6948 +3 6880 6879 6948 +3 6790 6879 6880 +3 6790 6880 6686 +3 6790 6686 6650 +3 6686 6542 6650 +3 6542 6506 6650 +3 6394 6506 6542 +3 6295 6394 6296 +3 6295 6296 6400 +3 6296 6544 6400 +3 6544 6512 6400 +3 6656 6512 6544 +3 6656 6544 6688 +3 6656 6688 6796 +3 6688 6888 6796 +3 6888 6887 6796 +3 6954 6887 6888 +3 6954 6888 6980 +3 6954 6980 7048 +3 6980 7078 7048 +3 7078 7146 7048 +3 7198 7146 7078 +3 7283 7198 7284 +3 7283 7284 7348 +3 7284 7434 7348 +3 7434 7404 7348 +3 7496 7404 7434 +3 7496 7434 7530 +3 7496 7530 7588 +3 7530 7674 7588 +3 7674 7673 7588 +3 7786 7673 7674 +3 7786 7674 7822 +3 7786 7822 7930 +3 7822 7974 7930 +3 7974 8074 7930 +3 8182 8074 7974 +3 8249 8182 8250 +3 8249 8250 8176 +3 8250 7972 8176 +3 7972 8068 8176 +3 7924 8068 7972 +3 7924 7972 7820 +3 7924 7820 7780 +3 7820 7666 7780 +3 7666 7665 7780 +3 6280 6366 6536 +3 7256 7328 7426 +3 7646 7752 7814 +3 7814 7896 7966 +3 8234 8156 7968 +3 7266 7186 7072 +3 7568 7645 7646 +3 7568 7646 7522 +3 7568 7522 7476 +3 7522 7426 7476 +3 7426 7384 7476 +3 7328 7384 7426 +3 7255 7328 7256 +3 7255 7256 7178 +3 7256 7070 7178 +3 7070 7126 7178 +3 7028 7126 7070 +3 7028 7070 6972 +3 7028 6972 6934 +3 6972 6860 6934 +3 6860 6859 6934 +3 6762 6859 6860 +3 6762 6860 6680 +3 6762 6680 6622 +3 6680 6536 6622 +3 6536 6478 6622 +3 6366 6478 6536 +3 6279 6366 6280 +3 6279 6280 6374 +3 6280 6538 6374 +3 6538 6486 6374 +3 6630 6486 6538 +3 6630 6538 6682 +3 6630 6682 6770 +3 6682 6870 6770 +3 6870 6869 6770 +3 6942 6869 6870 +3 6942 6870 6974 +3 6942 6974 7036 +3 6974 7072 7036 +3 7072 7134 7036 +3 7186 7134 7072 +3 7265 7186 7266 +3 7265 7266 7336 +3 7266 7428 7336 +3 7428 7392 7336 +3 7484 7392 7428 +3 7484 7428 7524 +3 7484 7524 7576 +3 7524 7656 7576 +3 7656 7655 7576 +3 7760 7655 7656 +3 7760 7656 7816 +3 7760 7816 7904 +3 7816 7968 7904 +3 7968 8048 7904 +3 8156 8048 7968 +3 8233 8156 8234 +3 8233 8234 8148 +3 8234 7966 8148 +3 7966 8040 8148 +3 7896 8040 7966 +3 7752 7896 7814 +3 7645 7752 7646 +3 6264 6342 6532 +3 8216 8128 7964 +3 7246 7170 7068 +3 7629 7630 7556 +3 7556 7518 7464 +3 7240 7316 7422 +3 7239 7316 7240 +3 7239 7240 7166 +3 7240 7066 7166 +3 7066 7114 7166 +3 7016 7114 7066 +3 7016 7066 6968 +3 7016 6968 6922 +3 6968 6844 6922 +3 6844 6843 6922 +3 6738 6843 6844 +3 6738 6844 6676 +3 6738 6676 6598 +3 6676 6532 6598 +3 6532 6454 6598 +3 6342 6454 6532 +3 6263 6342 6264 +3 6263 6264 6346 +3 6264 6534 6346 +3 6534 6458 6346 +3 6602 6458 6534 +3 6602 6534 6678 +3 6602 6678 6742 +3 6678 6850 6742 +3 6850 6849 6742 +3 6926 6849 6850 +3 6926 6850 6970 +3 6926 6970 7020 +3 6970 7068 7020 +3 7068 7118 7020 +3 7170 7118 7068 +3 7245 7170 7246 +3 7245 7246 7320 +3 7246 7424 7320 +3 7424 7376 7320 +3 7468 7376 7424 +3 7468 7424 7520 +3 7468 7520 7560 +3 7520 7636 7560 +3 7636 7635 7560 +3 7732 7635 7636 +3 7732 7636 7812 +3 7732 7812 7876 +3 7812 7964 7876 +3 7964 8020 7876 +3 8128 8020 7964 +3 8215 8128 8216 +3 8215 8216 8124 +3 8216 7962 8124 +3 7962 8016 8124 +3 7872 7962 7810 +3 8016 7962 7872 +3 7728 7810 7630 +3 7872 7810 7728 +3 7464 7422 7372 +3 7422 7316 7372 +3 7518 7422 7464 +3 7630 7518 7556 +3 7728 7630 7629 +3 6250 6318 6528 +3 7960 7860 7808 +3 7808 7716 7624 +3 7234 7162 7064 +3 7614 7544 7613 +3 7544 7514 7452 +3 7224 7304 7418 +3 7223 7304 7224 +3 7223 7224 7154 +3 7224 7062 7154 +3 7062 7102 7154 +3 7004 7102 7062 +3 7004 7062 6964 +3 7004 6964 6910 +3 6964 6828 6910 +3 6828 6827 6910 +3 6714 6827 6828 +3 6714 6828 6672 +3 6714 6672 6574 +3 6672 6528 6574 +3 6528 6430 6574 +3 6318 6430 6528 +3 6249 6318 6250 +3 6249 6250 6326 +3 6250 6530 6326 +3 6530 6438 6326 +3 6582 6438 6530 +3 6582 6530 6674 +3 6582 6674 6722 +3 6674 6838 6722 +3 6838 6837 6722 +3 6918 6837 6838 +3 6918 6838 6966 +3 6918 6966 7012 +3 6966 7064 7012 +3 7064 7110 7012 +3 7162 7110 7064 +3 7233 7162 7234 +3 7233 7234 7312 +3 7234 7420 7312 +3 7420 7368 7312 +3 7460 7368 7420 +3 7460 7420 7516 +3 7460 7516 7552 +3 7516 7624 7552 +3 7624 7623 7552 +3 7716 7623 7624 +3 7860 7716 7808 +3 8004 7860 7960 +3 8004 7960 8112 +3 7960 8206 8112 +3 8206 8205 8112 +3 8104 8205 8206 +3 8104 8206 7958 +3 8104 7958 7996 +3 7852 7958 7806 +3 7996 7958 7852 +3 7708 7806 7614 +3 7852 7806 7708 +3 7452 7418 7360 +3 7418 7304 7360 +3 7514 7418 7452 +3 7614 7514 7544 +3 7708 7614 7613 +3 4298 4396 4544 +3 5898 5938 5794 +3 5940 5904 5796 +3 5796 5760 5652 +3 5272 5190 5076 +3 5643 5644 5564 +3 5564 5506 5472 +3 5264 5328 5414 +3 5263 5328 5264 +3 5263 5264 5184 +3 5264 5074 5184 +3 5074 5128 5184 +3 5040 5128 5074 +3 5040 5074 4982 +3 5040 4982 4948 +3 4982 4884 4948 +3 4884 4883 4948 +3 4792 4883 4884 +3 4792 4884 4692 +3 4792 4692 4648 +3 4692 4544 4648 +3 4544 4504 4648 +3 4396 4504 4544 +3 4297 4396 4298 +3 4297 4298 4402 +3 4298 4546 4402 +3 4546 4510 4402 +3 4654 4510 4546 +3 4654 4546 4694 +3 4654 4694 4798 +3 4694 4892 4798 +3 4892 4891 4798 +3 4954 4891 4892 +3 4954 4892 4984 +3 4954 4984 5046 +3 4984 5076 5046 +3 5076 5134 5046 +3 5190 5134 5076 +3 5271 5190 5272 +3 5271 5272 5334 +3 5272 5416 5334 +3 5416 5386 5334 +3 5478 5386 5416 +3 5478 5416 5508 +3 5478 5508 5570 +3 5508 5652 5570 +3 5652 5651 5570 +3 5760 5651 5652 +3 5904 5760 5796 +3 6048 5904 5940 +3 6048 5940 6152 +3 5940 6224 6152 +3 6224 6223 6152 +3 6146 6223 6224 +3 6146 6224 5938 +3 6146 5938 6042 +3 5938 5898 6042 +3 5754 5794 5644 +3 5898 5794 5754 +3 5472 5414 5380 +3 5414 5328 5380 +3 5506 5414 5472 +3 5644 5506 5564 +3 5754 5644 5643 +3 4282 4368 4538 +3 5244 5314 5408 +3 6208 6126 5934 +3 5254 5178 5070 +3 5550 5623 5624 +3 5550 5624 5500 +3 5550 5500 5458 +3 5500 5408 5458 +3 5408 5366 5458 +3 5314 5366 5408 +3 5243 5314 5244 +3 5243 5244 5170 +3 5244 5068 5170 +3 5068 5114 5170 +3 5026 5114 5068 +3 5026 5068 4976 +3 5026 4976 4934 +3 4976 4864 4934 +3 4864 4863 4934 +3 4764 4863 4864 +3 4764 4864 4686 +3 4764 4686 4620 +3 4686 4538 4620 +3 4538 4476 4620 +3 4368 4476 4538 +3 4281 4368 4282 +3 4281 4282 4376 +3 4282 4540 4376 +3 4540 4484 4376 +3 4628 4484 4540 +3 4628 4540 4688 +3 4628 4688 4772 +3 4688 4874 4772 +3 4874 4873 4772 +3 4942 4873 4874 +3 4942 4874 4978 +3 4942 4978 5034 +3 4978 5070 5034 +3 5070 5122 5034 +3 5178 5122 5070 +3 5253 5178 5254 +3 5253 5254 5322 +3 5254 5410 5322 +3 5410 5374 5322 +3 5466 5374 5410 +3 5466 5410 5502 +3 5466 5502 5558 +3 5502 5634 5558 +3 5634 5633 5558 +3 5734 5633 5634 +3 5734 5634 5790 +3 5734 5790 5878 +3 5790 5934 5878 +3 5934 6022 5878 +3 6126 6022 5934 +3 6207 6126 6208 +3 6207 6208 6118 +3 6208 5932 6118 +3 5932 6014 6118 +3 5870 6014 5932 +3 5870 5932 5788 +3 5870 5788 5726 +3 5788 5624 5726 +3 5624 5623 5726 +3 4264 4344 4530 +3 5224 5302 5400 +3 6190 6098 5926 +3 5230 5162 5062 +3 5538 5603 5604 +3 5538 5604 5492 +3 5538 5492 5446 +3 5492 5400 5446 +3 5400 5354 5446 +3 5302 5354 5400 +3 5223 5302 5224 +3 5223 5224 5158 +3 5224 5060 5158 +3 5060 5102 5158 +3 5014 5102 5060 +3 5014 5060 4968 +3 5014 4968 4922 +3 4968 4844 4922 +3 4844 4843 4922 +3 4740 4843 4844 +3 4740 4844 4678 +3 4740 4678 4596 +3 4678 4530 4596 +3 4530 4452 4596 +3 4344 4452 4530 +3 4263 4344 4264 +3 4263 4264 4348 +3 4264 4532 4348 +3 4532 4456 4348 +3 4600 4456 4532 +3 4600 4532 4680 +3 4600 4680 4744 +3 4680 4850 4744 +3 4850 4849 4744 +3 4926 4849 4850 +3 4926 4850 4970 +3 4926 4970 5018 +3 4970 5062 5018 +3 5062 5106 5018 +3 5162 5106 5062 +3 5229 5162 5230 +3 5229 5230 5306 +3 5230 5402 5306 +3 5402 5358 5306 +3 5450 5358 5402 +3 5450 5402 5494 +3 5450 5494 5542 +3 5494 5610 5542 +3 5610 5609 5542 +3 5706 5609 5610 +3 5706 5610 5782 +3 5706 5782 5850 +3 5782 5926 5850 +3 5926 5994 5850 +3 6098 5994 5926 +3 6189 6098 6190 +3 6189 6190 6094 +3 6190 5924 6094 +3 5924 5990 6094 +3 5846 5990 5924 +3 5846 5924 5780 +3 5846 5780 5702 +3 5780 5604 5702 +3 5604 5603 5702 +3 4250 4320 4526 +3 5588 5678 5776 +3 5776 5822 5920 +3 6176 6078 5922 +3 5218 5154 5058 +3 5587 5588 5526 +3 5526 5488 5434 +3 5208 5290 5396 +3 5207 5290 5208 +3 5207 5208 5146 +3 5208 5056 5146 +3 5056 5090 5146 +3 5002 5090 5056 +3 5002 5056 4964 +3 5002 4964 4910 +3 4964 4828 4910 +3 4828 4827 4910 +3 4716 4827 4828 +3 4716 4828 4674 +3 4716 4674 4572 +3 4674 4526 4572 +3 4526 4428 4572 +3 4320 4428 4526 +3 4249 4320 4250 +3 4249 4250 4328 +3 4250 4528 4328 +3 4528 4436 4328 +3 4580 4436 4528 +3 4580 4528 4676 +3 4580 4676 4724 +3 4676 4838 4724 +3 4838 4837 4724 +3 4918 4837 4838 +3 4918 4838 4966 +3 4918 4966 5010 +3 4966 5058 5010 +3 5058 5098 5010 +3 5154 5098 5058 +3 5217 5154 5218 +3 5217 5218 5298 +3 5218 5398 5298 +3 5398 5350 5298 +3 5442 5350 5398 +3 5442 5398 5490 +3 5442 5490 5534 +3 5490 5598 5534 +3 5598 5597 5534 +3 5686 5597 5598 +3 5686 5598 5778 +3 5686 5778 5830 +3 5778 5922 5830 +3 5922 5974 5830 +3 6078 5974 5922 +3 6175 6078 6176 +3 6175 6176 6070 +3 6176 5920 6070 +3 5920 5966 6070 +3 5822 5966 5920 +3 5678 5822 5776 +3 5434 5396 5342 +3 5396 5290 5342 +3 5488 5396 5434 +3 5588 5488 5526 +3 5678 5588 5587 +3 2425 2426 2502 +3 3040 3162 3064 +3 3040 3064 2989 +3 3040 2989 2963 +3 2989 2917 2963 +3 2917 2823 2963 +3 2734 2823 2822 +3 2823 2917 2822 +3 2712 2823 2734 +3 2712 2734 2630 +3 2712 2630 2595 +3 2426 2501 2609 +3 2726 2792 2874 +3 3210 3266 3343 +3 4072 4073 4001 +3 4073 3812 4001 +3 3812 3901 4001 +3 3778 3901 3812 +3 3778 3812 3679 +3 3778 3679 3645 +3 3679 3537 3645 +3 3537 3536 3645 +3 3459 3536 3537 +3 3459 3537 3419 +3 3459 3419 3387 +3 3419 3343 3387 +3 3343 3312 3387 +3 3266 3312 3343 +3 3209 3266 3210 +3 3209 3210 3144 +3 3210 3054 3144 +3 3054 3097 3144 +3 3022 3097 3054 +3 3022 3054 2977 +3 3022 2977 2950 +3 2977 2874 2950 +3 2874 2873 2950 +3 2792 2873 2874 +3 2688 2792 2726 +3 2688 2726 2609 +3 2688 2609 2584 +3 2609 2501 2584 +3 2502 2595 2525 +3 2595 2630 2525 +3 2426 2595 2502 +3 2501 2426 2425 +3 2409 2476 2607 +3 3677 3750 3810 +3 3811 3757 3678 +3 3678 3624 3529 +3 3202 3137 3053 +3 3520 3521 3446 +3 3417 3374 3446 +3 3195 3253 3341 +3 3194 3253 3195 +3 3194 3195 3131 +3 3195 3052 3131 +3 3052 3084 3131 +3 3009 3084 3052 +3 3009 3052 2975 +3 3009 2975 2937 +3 2975 2859 2937 +3 2859 2858 2937 +3 2768 2858 2859 +3 2768 2859 2724 +3 2768 2724 2664 +3 2724 2607 2664 +3 2607 2559 2664 +3 2476 2559 2607 +3 2408 2476 2409 +3 2408 2409 2481 +3 2409 2608 2481 +3 2608 2564 2481 +3 2669 2564 2608 +3 2669 2608 2725 +3 2669 2725 2773 +3 2725 2866 2773 +3 2866 2865 2773 +3 2943 2865 2866 +3 2943 2866 2976 +3 2943 2976 3015 +3 2976 3053 3015 +3 3053 3090 3015 +3 3137 3090 3053 +3 3201 3137 3202 +3 3201 3202 3259 +3 3202 3342 3259 +3 3342 3305 3259 +3 3380 3305 3342 +3 3380 3342 3418 +3 3380 3418 3452 +3 3418 3529 3452 +3 3529 3528 3452 +3 3624 3528 3529 +3 3757 3624 3678 +3 3880 3757 3811 +3 3880 3811 3980 +3 3811 4057 3980 +3 4057 4056 3980 +3 3973 4056 4057 +3 3973 4057 3810 +3 3973 3810 3873 +3 3810 3750 3873 +3 3617 3677 3521 +3 3750 3677 3617 +3 3374 3341 3299 +3 3341 3253 3299 +3 3417 3341 3374 +3 3521 3417 3446 +3 3617 3521 3520 +3 2397 2459 2605 +3 3508 3595 3675 +3 3808 3951 4041 +3 3809 3732 3676 +3 3676 3599 3513 +3 3188 3125 3051 +3 3507 3508 3437 +3 3437 3415 3365 +3 3184 3244 3339 +3 3183 3244 3184 +3 3183 3184 3122 +3 3184 3050 3122 +3 3050 3075 3122 +3 3000 3075 3050 +3 3000 3050 2973 +3 3000 2973 2928 +3 2973 2845 2928 +3 2845 2844 2928 +3 2751 2844 2845 +3 2751 2845 2722 +3 2751 2722 2647 +3 2722 2605 2647 +3 2605 2542 2647 +3 2459 2542 2605 +3 2396 2459 2397 +3 2396 2397 2461 +3 2397 2606 2461 +3 2606 2544 2461 +3 2649 2544 2606 +3 2649 2606 2723 +3 2649 2723 2753 +3 2723 2852 2753 +3 2852 2851 2753 +3 2931 2851 2852 +3 2931 2852 2974 +3 2931 2974 3003 +3 2974 3051 3003 +3 3051 3078 3003 +3 3125 3078 3051 +3 3187 3125 3188 +3 3187 3188 3247 +3 3188 3340 3247 +3 3340 3293 3247 +3 3368 3293 3340 +3 3368 3340 3416 +3 3368 3416 3440 +3 3416 3513 3440 +3 3513 3512 3440 +3 3599 3512 3513 +3 3732 3599 3676 +3 3855 3732 3809 +3 3855 3809 3955 +3 3809 4041 3955 +3 4041 4040 3955 +3 3951 4040 4041 +3 3851 3951 3808 +3 3851 3808 3728 +3 3808 3675 3728 +3 3675 3595 3728 +3 3365 3339 3290 +3 3339 3244 3290 +3 3415 3339 3365 +3 3508 3415 3437 +3 3595 3508 3507 +3 2392 2451 2603 +3 3495 3576 3673 +3 3806 3932 4032 +3 3807 3716 3674 +3 3674 3583 3503 +3 3181 3120 3049 +3 3494 3495 3433 +3 3433 3413 3361 +3 3178 3240 3337 +3 3177 3240 3178 +3 3177 3178 3118 +3 3178 3048 3118 +3 3048 3071 3118 +3 2996 3071 3048 +3 2996 3048 2971 +3 2996 2971 2924 +3 2971 2838 2924 +3 2838 2837 2924 +3 2743 2837 2838 +3 2743 2838 2720 +3 2743 2720 2639 +3 2720 2603 2639 +3 2603 2534 2639 +3 2451 2534 2603 +3 2391 2451 2392 +3 2391 2392 2453 +3 2392 2604 2453 +3 2604 2536 2453 +3 2641 2536 2604 +3 2641 2604 2721 +3 2641 2721 2745 +3 2721 2841 2745 +3 2841 2840 2745 +3 2926 2840 2841 +3 2926 2841 2972 +3 2926 2972 2998 +3 2972 3049 2998 +3 3049 3073 2998 +3 3120 3073 3049 +3 3180 3120 3181 +3 3180 3181 3242 +3 3181 3338 3242 +3 3338 3288 3242 +3 3363 3288 3338 +3 3363 3338 3414 +3 3363 3414 3435 +3 3414 3503 3435 +3 3503 3502 3435 +3 3583 3502 3503 +3 3716 3583 3674 +3 3839 3716 3807 +3 3839 3807 3939 +3 3807 4032 3939 +3 4032 4031 3939 +3 3932 4031 4032 +3 3832 3932 3806 +3 3832 3806 3709 +3 3806 3673 3709 +3 3673 3576 3709 +3 3361 3337 3286 +3 3337 3240 3286 +3 3413 3337 3361 +3 3495 3413 3433 +3 3576 3495 3494 +3 411 506 635 +3 1986 1940 1839 +3 1839 1807 1697 +3 1326 1255 1157 +3 1687 1688 1597 +3 1597 1546 1513 +3 1318 1379 1460 +3 1317 1379 1318 +3 1317 1318 1249 +3 1318 1155 1249 +3 1155 1201 1249 +3 1123 1201 1155 +3 1123 1155 1073 +3 1123 1073 1043 +3 1073 973 1043 +3 973 972 1043 +3 870 972 973 +3 870 973 780 +3 870 780 734 +3 780 635 734 +3 635 601 734 +3 506 601 635 +3 410 506 411 +3 410 411 512 +3 411 637 512 +3 637 607 512 +3 740 607 637 +3 740 637 782 +3 740 782 876 +3 782 981 876 +3 981 980 876 +3 1049 980 981 +3 1049 981 1075 +3 1049 1075 1129 +3 1075 1157 1129 +3 1157 1207 1129 +3 1255 1207 1157 +3 1325 1255 1326 +3 1325 1326 1385 +3 1326 1462 1385 +3 1462 1437 1385 +3 1519 1437 1462 +3 1519 1462 1548 +3 1519 1548 1603 +3 1548 1697 1603 +3 1697 1696 1603 +3 1807 1696 1697 +3 1940 1807 1839 +3 2073 1940 1986 +3 2073 1986 2170 +3 1986 2244 2170 +3 2244 2243 2170 +3 2164 2243 2244 +3 2164 2244 1984 +3 2164 1984 2067 +3 1934 1984 1837 +3 2067 1984 1934 +3 1801 1837 1688 +3 1934 1837 1801 +3 1513 1460 1431 +3 1460 1379 1431 +3 1546 1460 1513 +3 1688 1546 1597 +3 1801 1688 1687 +3 393 477 631 +3 1669 1773 1833 +3 1980 2135 2227 +3 1982 1912 1835 +3 1835 1779 1678 +3 1306 1241 1153 +3 1668 1669 1583 +3 1583 1542 1499 +3 1298 1365 1456 +3 1297 1365 1298 +3 1297 1298 1235 +3 1298 1151 1235 +3 1151 1187 1235 +3 1109 1187 1151 +3 1109 1151 1069 +3 1109 1069 1029 +3 1069 954 1029 +3 954 953 1029 +3 842 953 954 +3 842 954 776 +3 842 776 706 +3 776 631 706 +3 631 573 706 +3 477 573 631 +3 392 477 393 +3 392 393 483 +3 393 633 483 +3 633 579 483 +3 712 579 633 +3 712 633 778 +3 712 778 848 +3 778 963 848 +3 963 962 848 +3 1035 962 963 +3 1035 963 1071 +3 1035 1071 1115 +3 1071 1153 1115 +3 1153 1193 1115 +3 1241 1193 1153 +3 1305 1241 1306 +3 1305 1306 1371 +3 1306 1458 1371 +3 1458 1423 1371 +3 1505 1423 1458 +3 1505 1458 1544 +3 1505 1544 1589 +3 1544 1678 1589 +3 1678 1677 1589 +3 1779 1677 1678 +3 1912 1779 1835 +3 2045 1912 1982 +3 2045 1982 2141 +3 1982 2227 2141 +3 2227 2226 2141 +3 2135 2226 2227 +3 2039 2135 1980 +3 2039 1980 1906 +3 1980 1833 1906 +3 1833 1773 1906 +3 1499 1456 1417 +3 1456 1365 1417 +3 1542 1456 1499 +3 1669 1542 1583 +3 1773 1669 1668 +3 453 627 379 +3 1651 1749 1829 +3 1829 1882 1976 +3 2213 2117 1978 +3 1290 1229 1149 +3 1650 1651 1571 +3 1571 1538 1487 +3 1282 1353 1452 +3 1281 1353 1282 +3 1281 1282 1223 +3 1282 1147 1223 +3 1147 1175 1223 +3 1097 1175 1147 +3 1097 1147 1065 +3 1097 1065 1017 +3 1065 936 1017 +3 936 935 1017 +3 818 935 936 +3 818 936 772 +3 818 772 682 +3 772 627 682 +3 627 549 682 +3 453 549 627 +3 378 453 379 +3 378 379 459 +3 379 629 459 +3 629 555 459 +3 688 555 629 +3 688 629 774 +3 688 774 824 +3 774 945 824 +3 945 944 824 +3 1023 944 945 +3 1023 945 1067 +3 1023 1067 1103 +3 1067 1149 1103 +3 1149 1181 1103 +3 1229 1181 1149 +3 1289 1229 1290 +3 1289 1290 1359 +3 1290 1454 1359 +3 1454 1411 1359 +3 1493 1411 1454 +3 1493 1454 1540 +3 1493 1540 1577 +3 1540 1660 1577 +3 1660 1659 1577 +3 1755 1659 1660 +3 1755 1660 1831 +3 1755 1831 1888 +3 1831 1978 1888 +3 1978 2021 1888 +3 2117 2021 1978 +3 2212 2117 2213 +3 2212 2213 2111 +3 2213 1976 2111 +3 1976 2015 2111 +3 1882 2015 1976 +3 1749 1882 1829 +3 1487 1452 1405 +3 1452 1353 1405 +3 1538 1452 1487 +3 1651 1538 1571 +3 1749 1651 1650 +3 440 624 369 +3 1276 1350 1449 +3 2203 2101 1974 +3 1278 1221 1145 +3 1568 1638 1639 +3 1568 1639 1535 +3 1568 1535 1484 +3 1535 1449 1484 +3 1449 1402 1484 +3 1350 1402 1449 +3 1275 1350 1276 +3 1275 1276 1220 +3 1276 1144 1220 +3 1144 1172 1220 +3 1094 1172 1144 +3 1094 1144 1062 +3 1094 1062 1014 +3 1062 923 1014 +3 923 922 1014 +3 805 922 923 +3 805 923 769 +3 805 769 669 +3 769 624 669 +3 624 536 669 +3 440 536 624 +3 368 440 369 +3 368 369 443 +3 369 625 443 +3 625 539 443 +3 672 539 625 +3 672 625 770 +3 672 770 808 +3 770 927 808 +3 927 926 808 +3 1015 926 927 +3 1015 927 1063 +3 1015 1063 1095 +3 1063 1145 1095 +3 1145 1173 1095 +3 1221 1173 1145 +3 1277 1221 1278 +3 1277 1278 1351 +3 1278 1450 1351 +3 1450 1403 1351 +3 1485 1403 1450 +3 1485 1450 1536 +3 1485 1536 1569 +3 1536 1642 1569 +3 1642 1641 1569 +3 1739 1641 1642 +3 1739 1642 1827 +3 1739 1827 1872 +3 1827 1974 1872 +3 1974 2005 1872 +3 2101 2005 1974 +3 2202 2101 2203 +3 2202 2203 2099 +3 2203 1973 2099 +3 1973 2003 2099 +3 1870 2003 1973 +3 1870 1973 1826 +3 1870 1826 1737 +3 1826 1639 1737 +3 1639 1638 1737 +3 6236 6309 6525 +3 7213 7303 7415 +3 7603 7699 7803 +3 7803 7843 7955 +3 8192 8096 7956 +3 7214 7154 7060 +3 7543 7612 7603 +3 7543 7603 7511 +3 7543 7511 7451 +3 7511 7415 7451 +3 7415 7359 7451 +3 7303 7359 7415 +3 7222 7303 7213 +3 7222 7213 7153 +3 7213 7059 7153 +3 7059 7101 7153 +3 7003 7101 7059 +3 7003 7059 6961 +3 7003 6961 6909 +3 6961 6817 6909 +3 6817 6826 6909 +3 6705 6826 6817 +3 6705 6817 6669 +3 6705 6669 6565 +3 6669 6525 6565 +3 6525 6421 6565 +3 6309 6421 6525 +3 6240 6309 6236 +3 6240 6236 6310 +3 6236 6526 6310 +3 6526 6422 6310 +3 6566 6422 6526 +3 6566 6526 6670 +3 6566 6670 6706 +3 6670 6818 6706 +3 6818 6827 6706 +3 6910 6827 6818 +3 6910 6818 6962 +3 6910 6962 7004 +3 6962 7060 7004 +3 7060 7102 7004 +3 7154 7102 7060 +3 7223 7154 7214 +3 7223 7214 7304 +3 7214 7416 7304 +3 7416 7360 7304 +3 7452 7360 7416 +3 7452 7416 7512 +3 7452 7512 7544 +3 7512 7604 7544 +3 7604 7613 7544 +3 7700 7613 7604 +3 7700 7604 7804 +3 7700 7804 7844 +3 7804 7956 7844 +3 7956 7988 7844 +3 8096 7988 7956 +3 8196 8096 8192 +3 8196 8192 8095 +3 8192 7955 8095 +3 7955 7987 8095 +3 7843 7987 7955 +3 7699 7843 7803 +3 7612 7699 7603 +3 6307 6523 6235 +3 7211 7301 7413 +3 7601 7697 7801 +3 7801 7841 7953 +3 7954 8191 8094 +3 7212 7152 7058 +3 7541 7610 7601 +3 7541 7601 7509 +3 7541 7509 7449 +3 7509 7413 7449 +3 7413 7357 7449 +3 7301 7357 7413 +3 7220 7301 7211 +3 7220 7211 7151 +3 7211 7057 7151 +3 7057 7099 7151 +3 7001 7099 7057 +3 7001 7057 6959 +3 7001 6959 6907 +3 6959 6815 6907 +3 6815 6824 6907 +3 6703 6824 6815 +3 6703 6815 6667 +3 6703 6667 6563 +3 6667 6523 6563 +3 6523 6419 6563 +3 6307 6419 6523 +3 6239 6307 6235 +3 6239 6235 6308 +3 6235 6524 6308 +3 6524 6420 6308 +3 6564 6420 6524 +3 6564 6524 6668 +3 6564 6668 6704 +3 6668 6816 6704 +3 6816 6825 6704 +3 6908 6825 6816 +3 6908 6816 6960 +3 6908 6960 7002 +3 6960 7058 7002 +3 7058 7100 7002 +3 7152 7100 7058 +3 7221 7152 7212 +3 7221 7212 7302 +3 7212 7414 7302 +3 7414 7358 7302 +3 7450 7358 7414 +3 7450 7414 7510 +3 7450 7510 7542 +3 7510 7602 7542 +3 7602 7611 7542 +3 7698 7611 7602 +3 7698 7602 7802 +3 7698 7802 7842 +3 7802 7954 7842 +3 7954 7986 7842 +3 8094 7986 7954 +3 8195 8094 8191 +3 8195 8191 8093 +3 8191 7953 8093 +3 7953 7985 8093 +3 7841 7985 7953 +3 7697 7841 7801 +3 7610 7697 7601 +3 6234 6305 6521 +3 7695 7799 7599 +3 7951 8091 8190 +3 7952 7840 7800 +3 7800 7696 7600 +3 7150 7056 7210 +3 7599 7539 7608 +3 7507 7447 7539 +3 7209 7299 7411 +3 7218 7299 7209 +3 7218 7209 7149 +3 7209 7055 7149 +3 7055 7097 7149 +3 6999 7097 7055 +3 6999 7055 6957 +3 6999 6957 6905 +3 6957 6813 6905 +3 6813 6822 6905 +3 6701 6822 6813 +3 6701 6813 6665 +3 6701 6665 6561 +3 6665 6521 6561 +3 6521 6417 6561 +3 6305 6417 6521 +3 6238 6305 6234 +3 6238 6234 6306 +3 6234 6522 6306 +3 6522 6418 6306 +3 6562 6418 6522 +3 6562 6522 6666 +3 6562 6666 6702 +3 6666 6814 6702 +3 6814 6823 6702 +3 6906 6823 6814 +3 6906 6814 6958 +3 6906 6958 7000 +3 6958 7056 7000 +3 7056 7098 7000 +3 7150 7098 7056 +3 7219 7150 7210 +3 7219 7210 7300 +3 7210 7412 7300 +3 7412 7356 7300 +3 7448 7356 7412 +3 7448 7412 7508 +3 7448 7508 7540 +3 7508 7600 7540 +3 7600 7609 7540 +3 7696 7609 7600 +3 7840 7696 7800 +3 7984 7840 7952 +3 7984 7952 8092 +3 7952 8190 8092 +3 8190 8194 8092 +3 8091 8194 8190 +3 7983 8091 7951 +3 7983 7951 7839 +3 7951 7799 7839 +3 7799 7695 7839 +3 7447 7411 7355 +3 7411 7299 7355 +3 7507 7411 7447 +3 7599 7507 7539 +3 7695 7599 7608 +3 6233 6303 6519 +3 7797 7837 7949 +3 7950 7838 7798 +3 7798 7694 7598 +3 7208 7148 7054 +3 7606 7597 7537 +3 7537 7505 7445 +3 7207 7297 7409 +3 7216 7297 7207 +3 7216 7207 7147 +3 7207 7053 7147 +3 7053 7095 7147 +3 6997 7095 7053 +3 6997 7053 6955 +3 6997 6955 6903 +3 6955 6811 6903 +3 6811 6820 6903 +3 6699 6820 6811 +3 6699 6811 6663 +3 6699 6663 6559 +3 6663 6519 6559 +3 6519 6415 6559 +3 6303 6415 6519 +3 6237 6303 6233 +3 6237 6233 6304 +3 6233 6520 6304 +3 6520 6416 6304 +3 6560 6416 6520 +3 6560 6520 6664 +3 6560 6664 6700 +3 6664 6812 6700 +3 6812 6821 6700 +3 6904 6821 6812 +3 6904 6812 6956 +3 6904 6956 6998 +3 6956 7054 6998 +3 7054 7096 6998 +3 7148 7096 7054 +3 7217 7148 7208 +3 7217 7208 7298 +3 7208 7410 7298 +3 7410 7354 7298 +3 7446 7354 7410 +3 7446 7410 7506 +3 7446 7506 7538 +3 7506 7598 7538 +3 7598 7607 7538 +3 7694 7607 7598 +3 7838 7694 7798 +3 7982 7838 7950 +3 7982 7950 8090 +3 7950 8189 8090 +3 8189 8193 8090 +3 8089 8193 8189 +3 8089 8189 7949 +3 8089 7949 7981 +3 7949 7837 7981 +3 7693 7797 7597 +3 7837 7797 7693 +3 7445 7409 7353 +3 7409 7297 7353 +3 7505 7409 7445 +3 7597 7505 7537 +3 7693 7597 7606 +3 4236 4311 4523 +3 5197 5289 5393 +3 5577 5669 5773 +3 5773 5813 5917 +3 6162 6062 5918 +3 5198 5146 5054 +3 5525 5586 5577 +3 5525 5577 5485 +3 5525 5485 5433 +3 5485 5393 5433 +3 5393 5341 5433 +3 5289 5341 5393 +3 5206 5289 5197 +3 5206 5197 5145 +3 5197 5053 5145 +3 5053 5089 5145 +3 5001 5089 5053 +3 5001 5053 4961 +3 5001 4961 4909 +3 4961 4817 4909 +3 4817 4826 4909 +3 4707 4826 4817 +3 4707 4817 4671 +3 4707 4671 4563 +3 4671 4523 4563 +3 4523 4419 4563 +3 4311 4419 4523 +3 4240 4311 4236 +3 4240 4236 4312 +3 4236 4524 4312 +3 4524 4420 4312 +3 4564 4420 4524 +3 4564 4524 4672 +3 4564 4672 4708 +3 4672 4818 4708 +3 4818 4827 4708 +3 4910 4827 4818 +3 4910 4818 4962 +3 4910 4962 5002 +3 4962 5054 5002 +3 5054 5090 5002 +3 5146 5090 5054 +3 5207 5146 5198 +3 5207 5198 5290 +3 5198 5394 5290 +3 5394 5342 5290 +3 5434 5342 5394 +3 5434 5394 5486 +3 5434 5486 5526 +3 5486 5578 5526 +3 5578 5587 5526 +3 5670 5587 5578 +3 5670 5578 5774 +3 5670 5774 5814 +3 5774 5918 5814 +3 5918 5958 5814 +3 6062 5958 5918 +3 6166 6062 6162 +3 6166 6162 6061 +3 6162 5917 6061 +3 5917 5957 6061 +3 5813 5957 5917 +3 5669 5813 5773 +3 5586 5669 5577 +3 4235 4309 4521 +3 5575 5667 5771 +3 5771 5811 5915 +3 5916 6161 6060 +3 5196 5144 5052 +3 5575 5523 5584 +3 5523 5483 5431 +3 5195 5287 5391 +3 5204 5287 5195 +3 5204 5195 5143 +3 5195 5051 5143 +3 5051 5087 5143 +3 4999 5087 5051 +3 4999 5051 4959 +3 4999 4959 4907 +3 4959 4815 4907 +3 4815 4824 4907 +3 4705 4824 4815 +3 4705 4815 4669 +3 4705 4669 4561 +3 4669 4521 4561 +3 4521 4417 4561 +3 4309 4417 4521 +3 4239 4309 4235 +3 4239 4235 4310 +3 4235 4522 4310 +3 4522 4418 4310 +3 4562 4418 4522 +3 4562 4522 4670 +3 4562 4670 4706 +3 4670 4816 4706 +3 4816 4825 4706 +3 4908 4825 4816 +3 4908 4816 4960 +3 4908 4960 5000 +3 4960 5052 5000 +3 5052 5088 5000 +3 5144 5088 5052 +3 5205 5144 5196 +3 5205 5196 5288 +3 5196 5392 5288 +3 5392 5340 5288 +3 5432 5340 5392 +3 5432 5392 5484 +3 5432 5484 5524 +3 5484 5576 5524 +3 5576 5585 5524 +3 5668 5585 5576 +3 5668 5576 5772 +3 5668 5772 5812 +3 5772 5916 5812 +3 5916 5956 5812 +3 6060 5956 5916 +3 6165 6060 6161 +3 6165 6161 6059 +3 6161 5915 6059 +3 5915 5955 6059 +3 5811 5955 5915 +3 5667 5811 5771 +3 5431 5391 5339 +3 5391 5287 5339 +3 5483 5391 5431 +3 5575 5483 5523 +3 5667 5575 5584 +3 4307 4519 4234 +3 5914 5810 5770 +3 5770 5666 5574 +3 5194 5142 5050 +3 5582 5573 5521 +3 5521 5481 5429 +3 5193 5285 5389 +3 5202 5285 5193 +3 5202 5193 5141 +3 5193 5049 5141 +3 5049 5085 5141 +3 4997 5085 5049 +3 4997 5049 4957 +3 4997 4957 4905 +3 4957 4813 4905 +3 4813 4822 4905 +3 4703 4822 4813 +3 4703 4813 4667 +3 4703 4667 4559 +3 4667 4519 4559 +3 4519 4415 4559 +3 4307 4415 4519 +3 4238 4307 4234 +3 4238 4234 4308 +3 4234 4520 4308 +3 4520 4416 4308 +3 4560 4416 4520 +3 4560 4520 4668 +3 4560 4668 4704 +3 4668 4814 4704 +3 4814 4823 4704 +3 4906 4823 4814 +3 4906 4814 4958 +3 4906 4958 4998 +3 4958 5050 4998 +3 5050 5086 4998 +3 5142 5086 5050 +3 5203 5142 5194 +3 5203 5194 5286 +3 5194 5390 5286 +3 5390 5338 5286 +3 5430 5338 5390 +3 5430 5390 5482 +3 5430 5482 5522 +3 5482 5574 5522 +3 5574 5583 5522 +3 5666 5583 5574 +3 5810 5666 5770 +3 5954 5810 5914 +3 5954 5914 6058 +3 5914 6160 6058 +3 6160 6164 6058 +3 6057 6164 6160 +3 6057 6160 5913 +3 6057 5913 5953 +3 5809 5913 5769 +3 5953 5913 5809 +3 5665 5769 5573 +3 5809 5769 5665 +3 5429 5389 5337 +3 5389 5285 5337 +3 5481 5389 5429 +3 5573 5481 5521 +3 5665 5573 5582 +3 4233 4305 4517 +3 5571 5663 5767 +3 5767 5807 5911 +3 6159 6056 5912 +3 5192 5140 5048 +3 5580 5571 5519 +3 5519 5479 5427 +3 5191 5283 5387 +3 5200 5283 5191 +3 5200 5191 5139 +3 5191 5047 5139 +3 5047 5083 5139 +3 4995 5083 5047 +3 4995 5047 4955 +3 4995 4955 4903 +3 4955 4811 4903 +3 4811 4820 4903 +3 4701 4820 4811 +3 4701 4811 4665 +3 4701 4665 4557 +3 4665 4517 4557 +3 4517 4413 4557 +3 4305 4413 4517 +3 4237 4305 4233 +3 4237 4233 4306 +3 4233 4518 4306 +3 4518 4414 4306 +3 4558 4414 4518 +3 4558 4518 4666 +3 4558 4666 4702 +3 4666 4812 4702 +3 4812 4821 4702 +3 4904 4821 4812 +3 4904 4812 4956 +3 4904 4956 4996 +3 4956 5048 4996 +3 5048 5084 4996 +3 5140 5084 5048 +3 5201 5140 5192 +3 5201 5192 5284 +3 5192 5388 5284 +3 5388 5336 5284 +3 5428 5336 5388 +3 5428 5388 5480 +3 5428 5480 5520 +3 5480 5572 5520 +3 5572 5581 5520 +3 5664 5581 5572 +3 5664 5572 5768 +3 5664 5768 5808 +3 5768 5912 5808 +3 5912 5952 5808 +3 6056 5952 5912 +3 6163 6056 6159 +3 6163 6159 6055 +3 6159 5911 6055 +3 5911 5951 6055 +3 5807 5951 5911 +3 5663 5807 5767 +3 5427 5387 5335 +3 5387 5283 5335 +3 5479 5387 5427 +3 5571 5479 5519 +3 5663 5571 5580 +3 2448 2601 2385 +3 3169 3239 3335 +3 4020 3925 3805 +3 3170 3118 3047 +3 3432 3493 3486 +3 3432 3486 3411 +3 3432 3411 3360 +3 3411 3335 3360 +3 3335 3285 3360 +3 3239 3285 3335 +3 3176 3239 3169 +3 3176 3169 3117 +3 3169 3046 3117 +3 3046 3070 3117 +3 2995 3070 3046 +3 2995 3046 2969 +3 2995 2969 2923 +3 2969 2829 2923 +3 2829 2836 2923 +3 2740 2836 2829 +3 2740 2829 2718 +3 2740 2718 2636 +3 2718 2601 2636 +3 2601 2531 2636 +3 2448 2531 2601 +3 2389 2448 2385 +3 2389 2385 2449 +3 2385 2602 2449 +3 2602 2532 2449 +3 2637 2532 2602 +3 2637 2602 2719 +3 2637 2719 2741 +3 2719 2830 2741 +3 2830 2837 2741 +3 2924 2837 2830 +3 2924 2830 2970 +3 2924 2970 2996 +3 2970 3047 2996 +3 3047 3071 2996 +3 3118 3071 3047 +3 3177 3118 3170 +3 3177 3170 3240 +3 3170 3336 3240 +3 3336 3286 3240 +3 3361 3286 3336 +3 3361 3336 3412 +3 3361 3412 3433 +3 3412 3487 3433 +3 3487 3494 3433 +3 3569 3494 3487 +3 3569 3487 3672 +3 3569 3672 3702 +3 3672 3805 3702 +3 3805 3825 3702 +3 3925 3825 3805 +3 4024 3925 4020 +3 4024 4020 3924 +3 4020 3804 3924 +3 3804 3824 3924 +3 3701 3824 3804 +3 3701 3804 3671 +3 3701 3671 3568 +3 3671 3486 3568 +3 3486 3493 3568 +3 2384 2446 2599 +3 3484 3566 3669 +3 3802 3922 4019 +3 3803 3700 3670 +3 3670 3567 3485 +3 3168 3116 3045 +3 3491 3484 3430 +3 3430 3409 3358 +3 3167 3237 3333 +3 3174 3237 3167 +3 3174 3167 3115 +3 3167 3044 3115 +3 3044 3068 3115 +3 2993 3068 3044 +3 2993 3044 2967 +3 2993 2967 2921 +3 2967 2827 2921 +3 2827 2834 2921 +3 2738 2834 2827 +3 2738 2827 2716 +3 2738 2716 2634 +3 2716 2599 2634 +3 2599 2529 2634 +3 2446 2529 2599 +3 2388 2446 2384 +3 2388 2384 2447 +3 2384 2600 2447 +3 2600 2530 2447 +3 2635 2530 2600 +3 2635 2600 2717 +3 2635 2717 2739 +3 2717 2828 2739 +3 2828 2835 2739 +3 2922 2835 2828 +3 2922 2828 2968 +3 2922 2968 2994 +3 2968 3045 2994 +3 3045 3069 2994 +3 3116 3069 3045 +3 3175 3116 3168 +3 3175 3168 3238 +3 3168 3334 3238 +3 3334 3284 3238 +3 3359 3284 3334 +3 3359 3334 3410 +3 3359 3410 3431 +3 3410 3485 3431 +3 3485 3492 3431 +3 3567 3492 3485 +3 3700 3567 3670 +3 3823 3700 3803 +3 3823 3803 3923 +3 3803 4019 3923 +3 4019 4023 3923 +3 3922 4023 4019 +3 3822 3922 3802 +3 3822 3802 3699 +3 3802 3669 3699 +3 3669 3566 3699 +3 3358 3333 3283 +3 3333 3237 3283 +3 3409 3333 3358 +3 3484 3409 3430 +3 3566 3484 3491 +3 2383 2444 2597 +3 3482 3564 3667 +3 3800 3920 4018 +3 3801 3698 3668 +3 3668 3565 3483 +3 3166 3114 3043 +3 3489 3482 3428 +3 3428 3407 3356 +3 3165 3235 3331 +3 3172 3235 3165 +3 3172 3165 3113 +3 3165 3042 3113 +3 3042 3066 3113 +3 2991 3066 3042 +3 2991 3042 2965 +3 2991 2965 2919 +3 2965 2825 2919 +3 2825 2832 2919 +3 2736 2832 2825 +3 2736 2825 2714 +3 2736 2714 2632 +3 2714 2597 2632 +3 2597 2527 2632 +3 2444 2527 2597 +3 2387 2444 2383 +3 2387 2383 2445 +3 2383 2598 2445 +3 2598 2528 2445 +3 2633 2528 2598 +3 2633 2598 2715 +3 2633 2715 2737 +3 2715 2826 2737 +3 2826 2833 2737 +3 2920 2833 2826 +3 2920 2826 2966 +3 2920 2966 2992 +3 2966 3043 2992 +3 3043 3067 2992 +3 3114 3067 3043 +3 3173 3114 3166 +3 3173 3166 3236 +3 3166 3332 3236 +3 3332 3282 3236 +3 3357 3282 3332 +3 3357 3332 3408 +3 3357 3408 3429 +3 3408 3483 3429 +3 3483 3490 3429 +3 3565 3490 3483 +3 3698 3565 3668 +3 3821 3698 3801 +3 3821 3801 3921 +3 3801 4018 3921 +3 4018 4022 3921 +3 3920 4022 4018 +3 3820 3920 3800 +3 3820 3800 3697 +3 3800 3667 3697 +3 3667 3564 3697 +3 3356 3331 3281 +3 3331 3235 3281 +3 3407 3331 3356 +3 3482 3407 3428 +3 3564 3482 3489 +3 360 436 622 +3 2196 2097 1972 +3 1267 1220 1143 +3 1637 1629 1567 +3 1567 1533 1483 +3 1266 1349 1447 +3 1274 1349 1266 +3 1274 1266 1219 +3 1266 1142 1219 +3 1142 1171 1219 +3 1093 1171 1142 +3 1093 1142 1060 +3 1093 1060 1013 +3 1060 913 1013 +3 913 921 1013 +3 801 921 913 +3 801 913 767 +3 801 767 665 +3 767 622 665 +3 622 532 665 +3 436 532 622 +3 364 436 360 +3 364 360 437 +3 360 623 437 +3 623 533 437 +3 666 533 623 +3 666 623 768 +3 666 768 802 +3 768 914 802 +3 914 922 802 +3 1014 922 914 +3 1014 914 1061 +3 1014 1061 1094 +3 1061 1143 1094 +3 1143 1172 1094 +3 1220 1172 1143 +3 1275 1220 1267 +3 1275 1267 1350 +3 1267 1448 1350 +3 1448 1402 1350 +3 1484 1402 1448 +3 1484 1448 1534 +3 1484 1534 1568 +3 1534 1630 1568 +3 1630 1638 1568 +3 1735 1638 1630 +3 1735 1630 1825 +3 1735 1825 1868 +3 1825 1972 1868 +3 1972 2001 1868 +3 2097 2001 1972 +3 2200 2097 2196 +3 2200 2196 2096 +3 2196 1971 2096 +3 1971 2000 2096 +3 1867 1971 1824 +3 2000 1971 1867 +3 1734 1824 1629 +3 1867 1824 1734 +3 1483 1447 1401 +3 1447 1349 1401 +3 1533 1447 1483 +3 1629 1533 1567 +3 1734 1629 1637 +3 359 434 620 +3 1627 1732 1822 +3 1822 1865 1969 +3 1970 2195 2095 +3 1265 1218 1141 +3 1627 1565 1635 +3 1481 1565 1531 +3 1264 1347 1445 +3 1272 1347 1264 +3 1272 1264 1217 +3 1264 1140 1217 +3 1140 1169 1217 +3 1091 1169 1140 +3 1091 1140 1058 +3 1091 1058 1011 +3 1058 911 1011 +3 911 919 1011 +3 799 919 911 +3 799 911 765 +3 799 765 663 +3 765 620 663 +3 620 530 663 +3 434 530 620 +3 363 434 359 +3 363 359 435 +3 359 621 435 +3 621 531 435 +3 664 531 621 +3 664 621 766 +3 664 766 800 +3 766 912 800 +3 912 920 800 +3 1012 920 912 +3 1012 912 1059 +3 1012 1059 1092 +3 1059 1141 1092 +3 1141 1170 1092 +3 1218 1170 1141 +3 1273 1218 1265 +3 1273 1265 1348 +3 1265 1446 1348 +3 1446 1400 1348 +3 1482 1400 1446 +3 1482 1446 1532 +3 1482 1532 1566 +3 1532 1628 1566 +3 1628 1636 1566 +3 1733 1636 1628 +3 1733 1628 1823 +3 1733 1823 1866 +3 1823 1970 1866 +3 1970 1999 1866 +3 2095 1999 1970 +3 2199 2095 2195 +3 2199 2195 2094 +3 2195 1969 2094 +3 1969 1998 2094 +3 1865 1998 1969 +3 1732 1865 1822 +3 1481 1445 1399 +3 1445 1347 1399 +3 1531 1445 1481 +3 1627 1531 1565 +3 1732 1627 1635 +3 358 432 618 +3 1820 1863 1967 +3 1968 1864 1821 +3 1821 1731 1626 +3 1263 1216 1139 +3 1633 1625 1563 +3 1479 1563 1529 +3 1262 1345 1443 +3 1270 1345 1262 +3 1270 1262 1215 +3 1262 1138 1215 +3 1138 1167 1215 +3 1089 1167 1138 +3 1089 1138 1056 +3 1089 1056 1009 +3 1056 909 1009 +3 909 917 1009 +3 797 917 909 +3 797 909 763 +3 797 763 661 +3 763 618 661 +3 618 528 661 +3 432 528 618 +3 362 432 358 +3 362 358 433 +3 358 619 433 +3 619 529 433 +3 662 529 619 +3 662 619 764 +3 662 764 798 +3 764 910 798 +3 910 918 798 +3 1010 918 910 +3 1010 910 1057 +3 1010 1057 1090 +3 1057 1139 1090 +3 1139 1168 1090 +3 1216 1168 1139 +3 1271 1216 1263 +3 1271 1263 1346 +3 1263 1444 1346 +3 1444 1398 1346 +3 1480 1398 1444 +3 1480 1444 1530 +3 1480 1530 1564 +3 1530 1626 1564 +3 1626 1634 1564 +3 1731 1634 1626 +3 1864 1731 1821 +3 1997 1864 1968 +3 1997 1968 2093 +3 1968 2194 2093 +3 2194 2198 2093 +3 2092 2198 2194 +3 2092 2194 1967 +3 2092 1967 1996 +3 1967 1863 1996 +3 1730 1820 1625 +3 1863 1820 1730 +3 1479 1443 1397 +3 1443 1345 1397 +3 1529 1443 1479 +3 1625 1529 1563 +3 1730 1625 1633 +3 357 430 616 +3 1966 1862 1819 +3 1729 1624 1819 +3 1261 1214 1137 +3 1623 1561 1631 +3 1561 1527 1477 +3 1260 1343 1441 +3 1268 1343 1260 +3 1268 1260 1213 +3 1260 1136 1213 +3 1136 1165 1213 +3 1087 1165 1136 +3 1087 1136 1054 +3 1087 1054 1007 +3 1054 907 1007 +3 907 915 1007 +3 795 915 907 +3 795 907 761 +3 795 761 659 +3 761 616 659 +3 616 526 659 +3 430 526 616 +3 361 430 357 +3 361 357 431 +3 357 617 431 +3 617 527 431 +3 660 527 617 +3 660 617 762 +3 660 762 796 +3 762 908 796 +3 908 916 796 +3 1008 916 908 +3 1008 908 1055 +3 1008 1055 1088 +3 1055 1137 1088 +3 1137 1166 1088 +3 1214 1166 1137 +3 1269 1214 1261 +3 1269 1261 1344 +3 1261 1442 1344 +3 1442 1396 1344 +3 1478 1396 1442 +3 1478 1442 1528 +3 1478 1528 1562 +3 1528 1624 1562 +3 1624 1632 1562 +3 1729 1632 1624 +3 1862 1729 1819 +3 1995 1862 1966 +3 1995 1966 2091 +3 1966 2193 2091 +3 2193 2197 2091 +3 2090 2197 2193 +3 2090 2193 1965 +3 2090 1965 1994 +3 1861 1965 1818 +3 1994 1965 1861 +3 1728 1818 1623 +3 1861 1818 1728 +3 1477 1441 1395 +3 1441 1343 1395 +3 1527 1441 1477 +3 1623 1527 1561 +3 1728 1623 1631 +3 415 513 412 +3 415 412 514 +3 415 514 639 +3 742 639 609 +3 639 514 609 +3 784 639 742 +3 784 742 878 +3 784 878 983 +3 1045 983 976 +3 983 878 976 +3 1077 983 1045 +3 1077 1045 1125 +3 1077 1125 1159 +3 1251 1159 1203 +3 1159 1125 1203 +3 1328 1159 1251 +3 1328 1251 1321 +3 1328 1321 1381 +3 1328 1381 1464 +3 1515 1464 1433 +3 1464 1381 1433 +3 1550 1464 1515 +3 1550 1515 1599 +3 1550 1599 1699 +3 1809 1699 1691 +3 1699 1599 1691 +3 1841 1699 1809 +3 1841 1809 1942 +3 1841 1942 1988 +3 2172 1988 2075 +3 1988 1942 2075 +3 2248 1988 2172 +3 2248 2172 2245 +3 2248 2245 2171 +3 2248 2171 1987 +3 1941 1987 2074 +3 1987 2171 2074 +3 1840 1987 1941 +3 1840 1941 1808 +3 1840 1808 1698 +3 1598 1698 1690 +3 1698 1808 1690 +3 1549 1698 1598 +3 1549 1598 1514 +3 1549 1514 1463 +3 1380 1463 1432 +3 1463 1514 1432 +3 1327 1463 1380 +3 1327 1380 1320 +3 1327 1320 1250 +3 1327 1250 1158 +3 1124 1158 1202 +3 1158 1250 1202 +3 1076 1158 1124 +3 1076 1124 1044 +3 1076 1044 982 +3 877 982 975 +3 982 1044 975 +3 783 982 877 +3 783 877 741 +3 783 741 638 +3 741 608 638 +3 608 513 638 +3 513 415 638 +3 1319 1380 1461 +3 2235 2157 1983 +3 1309 1242 1154 +3 634 594 499 +3 727 594 634 +3 727 634 779 +3 727 779 863 +3 779 964 863 +3 964 965 863 +3 1036 965 964 +3 1036 964 1072 +3 1036 1072 1116 +3 1072 1154 1116 +3 1154 1194 1116 +3 1242 1194 1154 +3 1310 1242 1309 +3 1310 1309 1372 +3 1309 1459 1372 +3 1459 1424 1372 +3 1506 1424 1459 +3 1506 1459 1545 +3 1506 1545 1590 +3 1545 1679 1590 +3 1679 1680 1590 +3 1794 1680 1679 +3 1794 1679 1836 +3 1794 1836 1927 +3 1836 1983 1927 +3 1983 2060 1927 +3 2157 2060 1983 +3 2236 2157 2235 +3 2236 2235 2165 +3 2235 1985 2165 +3 1985 2068 2165 +3 1935 2068 1985 +3 1935 1985 1838 +3 1935 1838 1802 +3 1838 1689 1802 +3 1689 1690 1802 +3 1598 1690 1689 +3 1598 1689 1547 +3 1598 1547 1514 +3 1547 1461 1514 +3 1461 1432 1514 +3 1380 1432 1461 +3 1320 1380 1319 +3 1320 1319 1250 +3 1319 1156 1250 +3 1156 1202 1250 +3 1124 1202 1156 +3 1124 1156 1074 +3 1124 1074 1044 +3 1074 974 1044 +3 974 975 1044 +3 871 975 974 +3 871 974 781 +3 871 781 735 +3 781 636 735 +3 636 602 735 +3 507 602 636 +3 507 636 401 +3 507 401 402 +3 401 499 402 +3 634 499 401 +3 341 513 334 +3 296 499 288 +3 252 492 257 +3 289 595 500 +3 728 595 289 +3 728 289 281 +3 728 281 864 +3 281 273 864 +3 273 966 864 +3 856 966 273 +3 856 273 265 +3 856 265 720 +3 265 257 720 +3 257 587 720 +3 492 587 257 +3 397 492 252 +3 397 252 491 +3 252 256 491 +3 256 586 491 +3 719 586 256 +3 719 256 264 +3 719 264 855 +3 264 272 855 +3 272 965 855 +3 863 965 272 +3 863 272 280 +3 863 280 727 +3 280 288 727 +3 288 594 727 +3 499 594 288 +3 402 499 296 +3 402 296 507 +3 296 306 507 +3 306 602 507 +3 735 602 306 +3 735 306 313 +3 735 313 871 +3 313 320 871 +3 320 975 871 +3 877 975 320 +3 877 320 327 +3 877 327 741 +3 327 334 741 +3 334 608 741 +3 513 608 334 +3 412 513 341 +3 412 341 514 +3 341 335 514 +3 335 609 514 +3 742 609 335 +3 742 335 328 +3 742 328 878 +3 328 321 878 +3 321 976 878 +3 872 976 321 +3 872 321 314 +3 872 314 736 +3 314 307 736 +3 307 603 736 +3 508 603 307 +3 508 307 297 +3 508 297 403 +3 297 500 403 +3 289 500 297 +3 1681 2786 1795 +3 1795 2682 1928 +3 1928 2578 2061 +3 1936 2689 1803 +3 1803 2793 1691 +3 1691 2875 1809 +3 2798 1942 1809 +3 1942 2694 2075 +3 2150 2571 2053 +3 2053 2675 1920 +3 2332 2165 2333 +3 2075 2590 2172 +3 2694 2590 2075 +3 2798 2694 1942 +3 2875 2798 1809 +3 2793 2875 1691 +3 2689 2793 1803 +3 2585 2689 1936 +3 2585 1936 2069 +3 2585 2069 2503 +3 2237 2503 2166 +3 2503 2069 2166 +3 2418 2503 2237 +3 2418 2237 2495 +3 2061 2495 2158 +3 2495 2237 2158 +3 2578 2495 2061 +3 2682 2578 1928 +3 2786 2682 1795 +3 2867 2786 1681 +3 2867 1681 2779 +3 1920 2779 1787 +3 2779 1681 1787 +3 2675 2779 1920 +3 2571 2675 2053 +3 2488 2571 2150 +3 2427 2338 2508 +3 2338 2172 2508 +3 2172 2590 2508 +3 2245 2172 2338 +3 2245 2338 2171 +3 2338 2337 2171 +3 2337 2074 2171 +3 1941 2074 2337 +3 1941 2337 2336 +3 1941 2336 1808 +3 2336 2335 1808 +3 2335 1690 1808 +3 1802 1690 2335 +3 1802 2335 2334 +3 1802 2334 1935 +3 2334 2333 1935 +3 2333 2068 1935 +3 2165 2068 2333 +3 2236 2165 2332 +3 2236 2332 2157 +3 2332 2331 2157 +3 2331 2060 2157 +3 1927 2060 2331 +3 1927 2331 2330 +3 1927 2330 1794 +3 2330 2329 1794 +3 2329 1680 1794 +3 1786 1680 2329 +3 1786 2329 2328 +3 1786 2328 1919 +3 2328 2327 1919 +3 2327 2052 1919 +3 2149 2052 2327 +3 2149 2327 2326 +3 2149 2326 2231 +3 2326 2150 2231 +3 2488 2150 2326 +3 2488 2326 2414 +3 7267 7179 7073 +3 6285 6376 6540 +3 7268 7330 7430 +3 7970 8050 8158 +3 7906 8050 7970 +3 7906 7970 7818 +3 7906 7818 7762 +3 7818 7658 7762 +3 7658 7649 7762 +3 7570 7649 7658 +3 7570 7658 7526 +3 7570 7526 7478 +3 7526 7430 7478 +3 7430 7386 7478 +3 7330 7386 7430 +3 7259 7330 7268 +3 7259 7268 7180 +3 7268 7074 7180 +3 7074 7128 7180 +3 7030 7128 7074 +3 7030 7074 6976 +3 7030 6976 6936 +3 6976 6872 6936 +3 6872 6863 6936 +3 6772 6863 6872 +3 6772 6872 6684 +3 6772 6684 6632 +3 6684 6540 6632 +3 6540 6488 6632 +3 6376 6488 6540 +3 6281 6376 6285 +3 6281 6285 6375 +3 6285 6539 6375 +3 6539 6487 6375 +3 6631 6487 6539 +3 6631 6539 6683 +3 6631 6683 6771 +3 6683 6871 6771 +3 6871 6862 6771 +3 6935 6862 6871 +3 6935 6871 6975 +3 6935 6975 7029 +3 6975 7073 7029 +3 7073 7127 7029 +3 7179 7127 7073 +3 7258 7179 7267 +3 7258 7267 7329 +3 7267 7429 7329 +3 7429 7385 7329 +3 7477 7385 7429 +3 7477 7429 7525 +3 7477 7525 7569 +3 7525 7657 7569 +3 7657 7648 7569 +3 7761 7648 7657 +3 7761 7657 7817 +3 7761 7817 7905 +3 7817 7969 7905 +3 7969 8049 7905 +3 8157 8049 7969 +3 8157 7969 8239 +3 8157 8239 8235 +3 8239 8158 8235 +3 7970 8158 8239 +3 7257 7329 7427 +3 8225 8141 7965 +3 7247 7171 7069 +3 6535 6471 6359 +3 6615 6471 6535 +3 6615 6535 6679 +3 6615 6679 6755 +3 6679 6851 6755 +3 6851 6852 6755 +3 6927 6852 6851 +3 6927 6851 6971 +3 6927 6971 7021 +3 6971 7069 7021 +3 7069 7119 7021 +3 7171 7119 7069 +3 7248 7171 7247 +3 7248 7247 7321 +3 7247 7425 7321 +3 7425 7377 7321 +3 7469 7377 7425 +3 7469 7425 7521 +3 7469 7521 7561 +3 7521 7637 7561 +3 7637 7638 7561 +3 7745 7638 7637 +3 7745 7637 7813 +3 7745 7813 7889 +3 7813 7965 7889 +3 7965 8033 7889 +3 8141 8033 7965 +3 8226 8141 8225 +3 8226 8225 8149 +3 8225 7967 8149 +3 7967 8041 8149 +3 7897 8041 7967 +3 7897 7967 7815 +3 7897 7815 7753 +3 7815 7647 7753 +3 7647 7648 7753 +3 7569 7648 7647 +3 7569 7647 7523 +3 7569 7523 7477 +3 7523 7427 7477 +3 7427 7385 7477 +3 7329 7385 7427 +3 7258 7329 7257 +3 7258 7257 7179 +3 7257 7071 7179 +3 7071 7127 7179 +3 7029 7127 7071 +3 7029 7071 6973 +3 7029 6973 6935 +3 6973 6861 6935 +3 6861 6862 6935 +3 6763 6862 6861 +3 6763 6861 6681 +3 6763 6681 6623 +3 6681 6537 6623 +3 6537 6479 6623 +3 6367 6479 6537 +3 6367 6537 6271 +3 6367 6271 6272 +3 6271 6359 6272 +3 6535 6359 6271 +3 5255 5171 5071 +3 4287 4378 4542 +3 5256 5316 5412 +3 5936 6024 6128 +3 5880 6024 5936 +3 5880 5936 5792 +3 5880 5792 5736 +3 5792 5636 5736 +3 5636 5627 5736 +3 5552 5627 5636 +3 5552 5636 5504 +3 5552 5504 5460 +3 5504 5412 5460 +3 5412 5368 5460 +3 5316 5368 5412 +3 5247 5316 5256 +3 5247 5256 5172 +3 5256 5072 5172 +3 5072 5116 5172 +3 5028 5116 5072 +3 5028 5072 4980 +3 5028 4980 4936 +3 4980 4876 4936 +3 4876 4867 4936 +3 4774 4867 4876 +3 4774 4876 4690 +3 4774 4690 4630 +3 4690 4542 4630 +3 4542 4486 4630 +3 4378 4486 4542 +3 4283 4378 4287 +3 4283 4287 4377 +3 4287 4541 4377 +3 4541 4485 4377 +3 4629 4485 4541 +3 4629 4541 4689 +3 4629 4689 4773 +3 4689 4875 4773 +3 4875 4866 4773 +3 4935 4866 4875 +3 4935 4875 4979 +3 4935 4979 5027 +3 4979 5071 5027 +3 5071 5115 5027 +3 5171 5115 5071 +3 5246 5171 5255 +3 5246 5255 5315 +3 5255 5411 5315 +3 5411 5367 5315 +3 5459 5367 5411 +3 5459 5411 5503 +3 5459 5503 5551 +3 5503 5635 5551 +3 5635 5626 5551 +3 5735 5626 5635 +3 5735 5635 5791 +3 5735 5791 5879 +3 5791 5935 5879 +3 5935 6023 5879 +3 6127 6023 5935 +3 6127 5935 6213 +3 6127 6213 6209 +3 6213 6128 6209 +3 5936 6128 6213 +3 5245 5315 5409 +3 6199 6111 5931 +3 5235 5163 5067 +3 4537 4469 4361 +3 4613 4469 4537 +3 4613 4537 4685 +3 4613 4685 4757 +3 4685 4855 4757 +3 4855 4856 4757 +3 4927 4856 4855 +3 4927 4855 4975 +3 4927 4975 5019 +3 4975 5067 5019 +3 5067 5107 5019 +3 5163 5107 5067 +3 5236 5163 5235 +3 5236 5235 5307 +3 5235 5407 5307 +3 5407 5359 5307 +3 5451 5359 5407 +3 5451 5407 5499 +3 5451 5499 5543 +3 5499 5615 5543 +3 5615 5616 5543 +3 5719 5616 5615 +3 5719 5615 5787 +3 5719 5787 5863 +3 5787 5931 5863 +3 5931 6007 5863 +3 6111 6007 5931 +3 6200 6111 6199 +3 6200 6199 6119 +3 6199 5933 6119 +3 5933 6015 6119 +3 5871 6015 5933 +3 5871 5933 5789 +3 5871 5789 5727 +3 5789 5625 5727 +3 5625 5626 5727 +3 5551 5626 5625 +3 5551 5625 5501 +3 5551 5501 5459 +3 5501 5409 5459 +3 5409 5367 5459 +3 5315 5367 5409 +3 5246 5315 5245 +3 5246 5245 5171 +3 5245 5069 5171 +3 5069 5115 5171 +3 5027 5115 5069 +3 5027 5069 4977 +3 5027 4977 4935 +3 4977 4865 4935 +3 4865 4866 4935 +3 4765 4866 4865 +3 4765 4865 4687 +3 4765 4687 4621 +3 4687 4539 4621 +3 4539 4477 4621 +3 4369 4477 4539 +3 4369 4539 4273 +3 4369 4273 4274 +3 4273 4361 4274 +3 4537 4361 4273 +3 1424 1418 1372 +3 1372 1366 1310 +3 1310 1300 1242 +3 1236 1194 1242 +3 1036 956 965 +3 586 580 491 +3 491 484 397 +3 397 394 492 +3 492 485 587 +3 587 581 720 +3 720 714 856 +3 1787 1914 1920 +3 2231 2228 2149 +3 1919 1780 1786 +3 1672 1681 1585 +3 1585 1591 1501 +3 1501 1507 1419 +3 1419 1425 1367 +3 1367 1373 1301 +3 1301 1311 1237 +3 1111 1037 1031 +3 856 850 966 +3 714 850 856 +3 581 714 720 +3 485 581 587 +3 394 485 492 +3 484 394 397 +3 580 484 491 +3 713 580 586 +3 713 586 719 +3 713 719 849 +3 965 849 855 +3 849 719 855 +3 956 849 965 +3 1030 956 1036 +3 1030 1036 1110 +3 1036 1116 1110 +3 1116 1194 1110 +3 1194 1188 1110 +3 1236 1188 1194 +3 1300 1236 1242 +3 1366 1300 1310 +3 1418 1366 1372 +3 1500 1418 1424 +3 1500 1424 1506 +3 1500 1506 1584 +3 1506 1590 1584 +3 1590 1671 1584 +3 1786 1671 1680 +3 1671 1590 1680 +3 1780 1671 1786 +3 1913 1780 1919 +3 1913 1919 2052 +3 1913 2052 2046 +3 2052 2149 2046 +3 2149 2142 2046 +3 2228 2142 2149 +3 2143 2228 2231 +3 2143 2231 2150 +3 2143 2150 2053 +3 2143 2053 2047 +3 2053 1920 2047 +3 1920 1914 2047 +3 1781 1787 1681 +3 1914 1787 1781 +3 1031 966 957 +3 966 850 957 +3 1037 966 1031 +3 1117 1037 1111 +3 1117 1111 1189 +3 1117 1189 1195 +3 1189 1237 1195 +3 1237 1243 1195 +3 1311 1243 1237 +3 1373 1311 1301 +3 1425 1373 1367 +3 1507 1425 1419 +3 1591 1507 1501 +3 1681 1591 1585 +3 1781 1681 1672 +3 1299 1366 1457 +3 2220 2130 1979 +3 1291 1230 1150 +3 630 568 472 +3 701 568 630 +3 701 630 775 +3 701 775 837 +3 775 946 837 +3 946 947 837 +3 1024 947 946 +3 1024 946 1068 +3 1024 1068 1104 +3 1068 1150 1104 +3 1150 1182 1104 +3 1230 1182 1150 +3 1292 1230 1291 +3 1292 1291 1360 +3 1291 1455 1360 +3 1455 1412 1360 +3 1494 1412 1455 +3 1494 1455 1541 +3 1494 1541 1578 +3 1541 1661 1578 +3 1661 1662 1578 +3 1768 1662 1661 +3 1768 1661 1832 +3 1768 1832 1901 +3 1832 1979 1901 +3 1979 2034 1901 +3 2130 2034 1979 +3 2221 2130 2220 +3 2221 2220 2136 +3 2220 1981 2136 +3 1981 2040 2136 +3 1907 2040 1981 +3 1907 1981 1834 +3 1907 1834 1774 +3 1834 1670 1774 +3 1670 1671 1774 +3 1584 1671 1670 +3 1584 1670 1543 +3 1584 1543 1500 +3 1543 1457 1500 +3 1457 1418 1500 +3 1366 1418 1457 +3 1300 1366 1299 +3 1300 1299 1236 +3 1299 1152 1236 +3 1152 1188 1236 +3 1110 1188 1152 +3 1110 1152 1070 +3 1110 1070 1030 +3 1070 955 1030 +3 955 956 1030 +3 843 956 955 +3 843 955 777 +3 843 777 707 +3 777 632 707 +3 632 574 707 +3 478 574 632 +3 478 632 386 +3 478 386 387 +3 386 472 387 +3 630 472 386 +3 8494 8142 8486 +3 8449 8133 8453 +3 8493 8149 8501 +3 8541 8158 8534 +3 7746 7639 8470 +3 7746 8470 8478 +3 7746 8478 7890 +3 8478 8486 7890 +3 8486 8034 7890 +3 8142 8034 8486 +3 8227 8142 8494 +3 8227 8494 8150 +3 8494 8502 8150 +3 8502 8042 8150 +3 7898 8042 8502 +3 7898 8502 8510 +3 7898 8510 7754 +3 8510 8518 7754 +3 8518 7649 7754 +3 7762 7649 8518 +3 7762 8518 8526 +3 7762 8526 7906 +3 8526 8534 7906 +3 8534 8050 7906 +3 8158 8050 8534 +3 8235 8158 8541 +3 8235 8541 8157 +3 8541 8533 8157 +3 8533 8049 8157 +3 7905 8049 8533 +3 7905 8533 8525 +3 7905 8525 7761 +3 8525 8517 7761 +3 8517 7648 7761 +3 7753 7648 8517 +3 7753 8517 8509 +3 7753 8509 7897 +3 8509 8501 7897 +3 8501 8041 7897 +3 8149 8041 8501 +3 8226 8149 8493 +3 8226 8493 8141 +3 8493 8485 8141 +3 8485 8033 8141 +3 7889 8033 8485 +3 7889 8485 8477 +3 7889 8477 7745 +3 8477 8469 7745 +3 8469 7638 7745 +3 7737 7638 8469 +3 7737 8469 8461 +3 7737 8461 7881 +3 8461 8453 7881 +3 8453 8025 7881 +3 8133 8025 8453 +3 8221 8133 8449 +3 8221 8449 8134 +3 8449 8454 8134 +3 8454 8026 8134 +3 7882 8026 8454 +3 7882 8454 8462 +3 7882 8462 7738 +3 8462 8470 7738 +3 8470 7639 7738 +3 238 484 231 +3 195 472 189 +3 157 467 163 +3 190 569 473 +3 702 569 190 +3 702 190 184 +3 702 184 838 +3 184 177 838 +3 177 948 838 +3 832 948 177 +3 832 177 170 +3 832 170 696 +3 170 163 696 +3 163 563 696 +3 467 563 163 +3 383 467 157 +3 383 157 466 +3 157 162 466 +3 162 562 466 +3 695 562 162 +3 695 162 169 +3 695 169 831 +3 169 176 831 +3 176 947 831 +3 837 947 176 +3 837 176 183 +3 837 183 701 +3 183 189 701 +3 189 568 701 +3 472 568 189 +3 387 472 195 +3 387 195 478 +3 195 203 478 +3 203 574 478 +3 707 574 203 +3 707 203 209 +3 707 209 843 +3 209 216 843 +3 216 956 843 +3 849 956 216 +3 849 216 224 +3 849 224 713 +3 224 231 713 +3 231 580 713 +3 484 580 231 +3 394 484 238 +3 394 238 485 +3 238 232 485 +3 232 581 485 +3 714 581 232 +3 714 232 225 +3 714 225 850 +3 225 217 850 +3 217 957 850 +3 844 957 217 +3 844 217 210 +3 844 210 708 +3 210 204 708 +3 204 575 708 +3 479 575 204 +3 479 204 196 +3 479 196 388 +3 196 473 388 +3 190 473 196 +3 1902 2660 2035 +3 2035 2555 2131 +3 2131 2472 2222 +3 2222 2404 2137 +3 2477 2041 2137 +3 2041 2560 1908 +3 1908 2665 1775 +3 1672 1775 2769 +3 2565 2143 2047 +3 1913 2323 1780 +3 2550 2029 2125 +3 2029 2655 1896 +3 2759 1763 1896 +3 2313 2467 2125 +3 2313 2125 2217 +3 2313 2217 2124 +3 2313 2124 2314 +3 1895 2314 2028 +3 2314 2124 2028 +3 2315 2314 1895 +3 2315 1895 1762 +3 2315 1762 2316 +3 1768 2316 1662 +3 2316 1762 1662 +3 2317 2316 1768 +3 2317 1768 1901 +3 2317 1901 2318 +3 2130 2318 2034 +3 2318 1901 2034 +3 2319 2318 2130 +3 2319 2130 2221 +3 2319 2221 2136 +3 2319 2136 2320 +3 1907 2320 2040 +3 2320 2136 2040 +3 2321 2320 1907 +3 2321 1907 1774 +3 2321 1774 2322 +3 1780 2322 1671 +3 2322 1774 1671 +3 2323 2322 1780 +3 2324 2323 1913 +3 2324 1913 2046 +3 2324 2046 2142 +3 2324 2142 2325 +3 2142 2228 2325 +3 2228 2143 2325 +3 2143 2482 2325 +3 2482 2410 2325 +3 2565 2482 2143 +3 2670 2565 2047 +3 2670 2047 1914 +3 2670 1914 2774 +3 1914 1781 2774 +3 1781 1672 2774 +3 1672 2860 2774 +3 2769 2860 1672 +3 2665 2769 1775 +3 2560 2665 1908 +3 2477 2560 2041 +3 2404 2477 2137 +3 2472 2404 2222 +3 2555 2472 2131 +3 2660 2555 2035 +3 2764 2660 1902 +3 2764 1902 1769 +3 2764 1769 2853 +3 1763 2853 1663 +3 2853 1769 1663 +3 2759 2853 1763 +3 2655 2759 1896 +3 2550 2655 2029 +3 2467 2550 2125 +3 2401 2467 2313 +3 4757 4115 4613 +3 4119 4765 4621 +3 4773 4121 4629 +3 4378 3881 4486 +3 4486 3758 4630 +3 3625 4774 4630 +3 4774 3522 4867 +3 4766 4867 3618 +3 4766 3751 4622 +3 4614 3744 4758 +3 4758 3611 4857 +3 3514 4750 4857 +3 4750 3604 4606 +3 4606 3737 4462 +3 4462 3860 4354 +3 4605 4113 4749 +3 3981 4378 4123 +3 4378 4283 4123 +3 4283 4377 4123 +3 4377 4122 4123 +3 4629 4122 4485 +3 4122 4377 4485 +3 4121 4122 4629 +3 4120 4121 4773 +3 4765 4120 4866 +3 4120 4773 4866 +3 4119 4120 4765 +3 4118 4119 4621 +3 4118 4621 4477 +3 4118 4477 4369 +3 4118 4369 4117 +3 4369 4274 4117 +3 4274 4361 4117 +3 4361 4116 4117 +3 4613 4116 4469 +3 4116 4361 4469 +3 4115 4116 4613 +3 4114 4115 4757 +3 4749 4114 4856 +3 4114 4757 4856 +3 4113 4114 4749 +3 4112 4113 4605 +3 4112 4605 4461 +3 4112 4461 4353 +3 4112 4353 4111 +3 4353 4269 4111 +3 4269 4354 4111 +3 4354 3960 4111 +3 3960 4046 4111 +3 3860 3960 4354 +3 3737 3860 4462 +3 3604 3737 4606 +3 3514 3604 4750 +3 3611 3514 4857 +3 3744 3611 4758 +3 3867 3744 4614 +3 3867 4614 4470 +3 3867 4470 4362 +3 3867 4362 3967 +3 4362 4275 3967 +3 4275 4050 3967 +3 3974 4050 4275 +3 3974 4275 4370 +3 3974 4370 3874 +3 4622 3874 4478 +3 3874 4370 4478 +3 3751 3874 4622 +3 3618 3751 4766 +3 3522 3618 4867 +3 3625 3522 4774 +3 3758 3625 4630 +3 3881 3758 4486 +3 3981 3881 4378 +3 4058 3981 4123 +3 5720 6616 5864 +3 5864 6472 6008 +3 6008 6360 6112 +3 6112 6273 6201 +3 6764 5627 5728 +3 6024 6488 6128 +3 6128 6376 6209 +3 6127 6209 6281 +3 6023 6127 6375 +3 6487 5879 6023 +3 5616 6747 5711 +3 5999 6351 6103 +3 6103 6267 6195 +3 6195 6352 6104 +3 6104 6464 6000 +3 6000 6608 5856 +3 6471 6007 6359 +3 6359 6111 6272 +3 6272 6200 6367 +3 6479 6367 6119 +3 6479 6015 6623 +3 5879 6631 5735 +3 6487 6631 5879 +3 6375 6487 6023 +3 6281 6375 6127 +3 6376 6281 6209 +3 6488 6376 6128 +3 6632 6488 6024 +3 6632 6024 5880 +3 6632 5880 6772 +3 5880 5736 6772 +3 5736 5627 6772 +3 5627 6863 6772 +3 6764 6863 5627 +3 6624 6764 5728 +3 6624 5728 5872 +3 6624 5872 6480 +3 5872 6016 6480 +3 6016 6368 6480 +3 6201 6368 6120 +3 6368 6016 6120 +3 6273 6368 6201 +3 6360 6273 6112 +3 6472 6360 6008 +3 6616 6472 5864 +3 6756 6616 5720 +3 6756 5720 5617 +3 6756 5617 6853 +3 5617 6748 6853 +3 5856 6748 5712 +3 6748 5617 5712 +3 6608 6748 5856 +3 6464 6608 6000 +3 6352 6464 6104 +3 6267 6352 6195 +3 6351 6267 6103 +3 6463 6351 5999 +3 6463 5999 5855 +3 6463 5855 6607 +3 5855 5711 6607 +3 5711 6747 6607 +3 6862 5735 6771 +3 5735 6631 6771 +3 5626 5735 6862 +3 5626 6862 6763 +3 5626 6763 5727 +3 6763 6623 5727 +3 6623 5871 5727 +3 6015 5871 6623 +3 6119 6015 6479 +3 6200 6119 6367 +3 6111 6200 6272 +3 6007 6111 6359 +3 5863 6007 6471 +3 5863 6471 6615 +3 5863 6615 5719 +3 6615 6755 5719 +3 6755 6852 5719 +3 6852 5616 5719 +3 6747 5616 6852 +3 6407 6463 6551 +3 6551 6607 6803 +3 7021 7049 6988 +3 7119 7089 7049 +3 7089 7171 7199 +3 7248 7292 7199 +3 7292 7321 7405 +3 7589 7638 7681 +3 7681 7737 7793 +3 7793 7881 7937 +3 7937 8025 8081 +3 8081 8133 8219 +3 7938 7882 7794 +3 7794 7738 7682 +3 7590 7682 7639 +3 7498 7590 7562 +3 7498 7470 7406 +3 7200 7172 7090 +3 7090 7120 7050 +3 7120 7022 7050 +3 7172 7120 7090 +3 7249 7172 7200 +3 7249 7200 7293 +3 7249 7293 7322 +3 7293 7406 7322 +3 7406 7378 7322 +3 7470 7378 7406 +3 7562 7470 7498 +3 7639 7562 7590 +3 7738 7639 7682 +3 7882 7738 7794 +3 8026 7882 7938 +3 8026 7938 8082 +3 8026 8082 8134 +3 8082 8219 8134 +3 8219 8221 8134 +3 8133 8221 8219 +3 8025 8133 8081 +3 7881 8025 7937 +3 7737 7881 7793 +3 7638 7737 7681 +3 7561 7638 7589 +3 7561 7589 7497 +3 7561 7497 7469 +3 7497 7405 7469 +3 7405 7377 7469 +3 7321 7377 7405 +3 7248 7321 7292 +3 7171 7248 7199 +3 7119 7171 7089 +3 7021 7119 7049 +3 6927 7021 6988 +3 6927 6988 6895 +3 6927 6895 6852 +3 6895 6803 6852 +3 6803 6747 6852 +3 6607 6747 6803 +3 6463 6607 6551 +3 6351 6463 6407 +3 6351 6407 6267 +3 6407 6408 6267 +3 6408 6352 6267 +3 6464 6352 6408 +3 6464 6408 6552 +3 6464 6552 6608 +3 6552 6804 6608 +3 6804 6748 6608 +3 6853 6748 6804 +3 6853 6804 6896 +3 6853 6896 6928 +3 6896 6989 6928 +3 6989 7022 6928 +3 7050 7022 6989 +3 5232 5164 5064 +3 4267 4353 4533 +3 5231 5307 5403 +3 5927 5999 6103 +3 5855 5999 5927 +3 5855 5927 5783 +3 5855 5783 5711 +3 5783 5611 5711 +3 5611 5616 5711 +3 5543 5616 5611 +3 5543 5611 5495 +3 5543 5495 5451 +3 5495 5403 5451 +3 5403 5359 5451 +3 5307 5359 5403 +3 5236 5307 5231 +3 5236 5231 5163 +3 5231 5063 5163 +3 5063 5107 5163 +3 5019 5107 5063 +3 5019 5063 4971 +3 5019 4971 4927 +3 4971 4851 4927 +3 4851 4856 4927 +3 4749 4856 4851 +3 4749 4851 4681 +3 4749 4681 4605 +3 4681 4533 4605 +3 4533 4461 4605 +3 4353 4461 4533 +3 4269 4353 4267 +3 4269 4267 4354 +3 4267 4534 4354 +3 4534 4462 4354 +3 4606 4462 4534 +3 4606 4534 4682 +3 4606 4682 4750 +3 4682 4852 4750 +3 4852 4857 4750 +3 4928 4857 4852 +3 4928 4852 4972 +3 4928 4972 5020 +3 4972 5064 5020 +3 5064 5108 5020 +3 5164 5108 5064 +3 5237 5164 5232 +3 5237 5232 5308 +3 5232 5404 5308 +3 5404 5360 5308 +3 5452 5360 5404 +3 5452 5404 5496 +3 5452 5496 5544 +3 5496 5612 5544 +3 5612 5617 5544 +3 5712 5617 5612 +3 5712 5612 5784 +3 5712 5784 5856 +3 5784 5928 5856 +3 5928 6000 5856 +3 6104 6000 5928 +3 6104 5928 6193 +3 6104 6193 6195 +3 6193 6103 6195 +3 5927 6103 6193 +3 3960 3916 4044 +3 3860 3792 3916 +3 3792 3737 3686 +3 3686 3604 3560 +3 3369 3351 3402 +3 3351 3294 3326 +3 3248 3231 3326 +3 3231 3189 3157 +3 3157 3126 3061 +3 3061 3079 3035 +3 3035 3004 2986 +3 2986 2932 2914 +3 2550 2462 2545 +3 2398 2462 2401 +3 2462 2467 2401 +3 2550 2467 2462 +3 2655 2550 2545 +3 2655 2545 2650 +3 2655 2650 2759 +3 2650 2754 2759 +3 2754 2853 2759 +3 2914 2853 2846 +3 2853 2754 2846 +3 2932 2853 2914 +3 3004 2932 2986 +3 3079 3004 3035 +3 3126 3079 3061 +3 3189 3126 3157 +3 3248 3189 3231 +3 3294 3248 3326 +3 3369 3294 3351 +3 3441 3369 3402 +3 3441 3402 3473 +3 3441 3473 3514 +3 3560 3514 3550 +3 3514 3473 3550 +3 3604 3514 3560 +3 3737 3604 3686 +3 3860 3737 3792 +3 3960 3860 3916 +3 4046 3960 4044 +3 1578 1662 1653 +3 1572 1494 1578 +3 1494 1488 1412 +3 1412 1406 1360 +3 1360 1354 1292 +3 1230 1292 1284 +3 1182 1230 1224 +3 1182 1176 1104 +3 1104 1098 1024 +3 1024 1018 947 +3 831 947 938 +3 831 825 695 +3 562 695 689 +3 562 556 466 +3 466 460 383 +3 383 380 467 +3 563 467 461 +3 696 563 557 +3 832 696 690 +3 832 826 948 +3 939 1025 948 +3 1025 1019 1105 +3 1099 1183 1105 +3 1177 1231 1183 +3 2125 2029 2023 +3 2028 2022 1895 +3 1889 1762 1895 +3 1762 1756 1662 +3 1355 1413 1361 +3 1355 1361 1285 +3 1361 1293 1285 +3 1293 1231 1285 +3 1231 1225 1285 +3 1177 1225 1231 +3 1099 1177 1183 +3 1019 1099 1105 +3 939 1019 1025 +3 826 939 948 +3 690 826 832 +3 557 690 696 +3 461 557 563 +3 380 461 467 +3 460 380 383 +3 556 460 466 +3 689 556 562 +3 825 689 695 +3 938 825 831 +3 1018 938 947 +3 1098 1018 1024 +3 1176 1098 1104 +3 1224 1176 1182 +3 1284 1224 1230 +3 1354 1284 1292 +3 1406 1354 1360 +3 1488 1406 1412 +3 1572 1488 1494 +3 1653 1572 1578 +3 1756 1653 1662 +3 1889 1756 1762 +3 2022 1889 1895 +3 2118 2022 2028 +3 2118 2028 2124 +3 2118 2124 2217 +3 2118 2217 2214 +3 2217 2125 2214 +3 2125 2119 2214 +3 2023 2119 2125 +3 1890 2029 1896 +3 2023 2029 1890 +3 1663 1757 1763 +3 1757 1896 1763 +3 1890 1896 1757 +3 1489 1413 1407 +3 1413 1355 1407 +3 1495 1413 1489 +3 1495 1489 1573 +3 1495 1573 1579 +3 1573 1654 1579 +3 1654 1663 1579 +3 1757 1663 1654 +3 1354 1453 1283 +3 2206 2106 1975 +3 1279 1222 1146 +3 626 544 448 +3 677 544 626 +3 677 626 771 +3 677 771 813 +3 771 928 813 +3 928 929 813 +3 1016 929 928 +3 1016 928 1064 +3 1016 1064 1096 +3 1064 1146 1096 +3 1146 1174 1096 +3 1222 1174 1146 +3 1280 1222 1279 +3 1280 1279 1352 +3 1279 1451 1352 +3 1451 1404 1352 +3 1486 1404 1451 +3 1486 1451 1537 +3 1486 1537 1570 +3 1537 1643 1570 +3 1643 1644 1570 +3 1744 1644 1643 +3 1744 1643 1828 +3 1744 1828 1877 +3 1828 1975 1877 +3 1975 2010 1877 +3 2106 2010 1975 +3 2207 2106 2206 +3 2207 2206 2112 +3 2206 1977 2112 +3 1977 2016 2112 +3 1883 2016 1977 +3 1883 1977 1830 +3 1883 1830 1750 +3 1830 1652 1750 +3 1652 1653 1750 +3 1572 1653 1652 +3 1572 1652 1539 +3 1572 1539 1488 +3 1539 1453 1488 +3 1453 1406 1488 +3 1354 1406 1453 +3 1284 1354 1283 +3 1284 1283 1224 +3 1283 1148 1224 +3 1148 1176 1224 +3 1098 1176 1148 +3 1098 1148 1066 +3 1098 1066 1018 +3 1066 937 1018 +3 937 938 1018 +3 819 938 937 +3 819 937 773 +3 819 773 683 +3 773 628 683 +3 628 550 683 +3 454 550 628 +3 454 628 372 +3 454 372 373 +3 372 448 373 +3 626 448 372 +3 756 653 86 +3 550 123 683 +3 825 143 689 +3 690 557 149 +3 690 142 826 +3 814 98 930 +3 930 91 901 +3 98 91 930 +3 104 98 814 +3 104 814 678 +3 104 678 109 +3 449 109 545 +3 109 678 545 +3 114 109 449 +3 114 449 374 +3 114 374 455 +3 114 455 122 +3 684 122 551 +3 122 455 551 +3 128 122 684 +3 128 684 820 +3 128 820 135 +3 826 135 939 +3 135 820 939 +3 142 135 826 +3 149 142 690 +3 156 149 557 +3 156 557 461 +3 156 461 380 +3 156 380 460 +3 156 460 150 +3 689 150 556 +3 150 460 556 +3 143 150 689 +3 136 143 825 +3 136 825 938 +3 136 938 129 +3 938 819 129 +3 819 683 129 +3 683 123 129 +3 373 117 454 +3 117 550 454 +3 123 550 117 +3 111 373 448 +3 117 373 111 +3 677 111 544 +3 111 448 544 +3 103 111 677 +3 103 677 813 +3 103 813 97 +3 813 929 97 +3 929 90 97 +3 756 90 891 +3 90 929 891 +3 86 90 756 +3 83 86 653 +3 83 653 521 +3 7225 7305 7419 +3 8197 8097 7957 +3 7215 7147 7061 +3 6527 6423 6311 +3 6567 6423 6527 +3 6567 6527 6671 +3 6567 6671 6707 +3 6671 6819 6707 +3 6819 6820 6707 +3 6903 6820 6819 +3 6903 6819 6963 +3 6903 6963 6997 +3 6963 7061 6997 +3 7061 7095 6997 +3 7147 7095 7061 +3 7216 7147 7215 +3 7216 7215 7297 +3 7215 7417 7297 +3 7417 7353 7297 +3 7445 7353 7417 +3 7445 7417 7513 +3 7445 7513 7537 +3 7513 7605 7537 +3 7605 7606 7537 +3 7701 7606 7605 +3 7701 7605 7805 +3 7701 7805 7845 +3 7805 7957 7845 +3 7957 7989 7845 +3 8097 7989 7957 +3 8198 8097 8197 +3 8198 8197 8105 +3 8197 7959 8105 +3 7959 7997 8105 +3 7853 7997 7959 +3 7853 7959 7807 +3 7853 7807 7709 +3 7807 7615 7709 +3 7615 7616 7709 +3 7545 7616 7615 +3 7545 7615 7515 +3 7545 7515 7453 +3 7515 7419 7453 +3 7419 7361 7453 +3 7305 7361 7419 +3 7226 7305 7225 +3 7226 7225 7155 +3 7225 7063 7155 +3 7063 7103 7155 +3 7005 7103 7063 +3 7005 7063 6965 +3 7005 6965 6911 +3 6965 6829 6911 +3 6829 6830 6911 +3 6715 6830 6829 +3 6715 6829 6673 +3 6715 6673 6575 +3 6673 6529 6575 +3 6529 6431 6575 +3 6319 6431 6529 +3 6319 6529 6241 +3 6319 6241 6242 +3 6241 6311 6242 +3 6527 6311 6241 +3 4553 4437 4409 +3 4409 4329 4255 +3 4554 4582 4662 +3 4662 4726 4807 +3 4807 4831 4900 +3 4900 4912 4992 +3 4992 5004 5136 +3 5804 5832 5948 +3 6079 5947 6181 +3 5659 5590 5515 +3 4911 4830 4899 +3 4911 4899 4991 +3 4911 4991 5003 +3 4991 5135 5003 +3 5135 5091 5003 +3 5147 5091 5135 +3 5147 5135 5279 +3 5147 5279 5210 +3 5279 5291 5210 +3 5343 5291 5279 +3 5343 5279 5423 +3 5343 5423 5435 +3 5423 5515 5435 +3 5515 5527 5435 +3 5590 5527 5515 +3 5687 5590 5659 +3 5687 5659 5803 +3 5687 5803 5831 +3 5803 5947 5831 +3 5947 5975 5831 +3 6079 5975 5947 +3 6177 6079 6181 +3 6177 6181 6080 +3 6181 5948 6080 +3 5948 5976 6080 +3 5832 5976 5948 +3 5688 5832 5804 +3 5688 5804 5660 +3 5688 5660 5591 +3 5660 5516 5591 +3 5516 5528 5591 +3 5436 5528 5516 +3 5436 5516 5424 +3 5436 5424 5344 +3 5424 5280 5344 +3 5280 5292 5344 +3 5211 5292 5280 +3 5211 5280 5148 +3 5280 5136 5148 +3 5136 5092 5148 +3 5004 5092 5136 +3 4912 5004 4992 +3 4831 4912 4900 +3 4726 4831 4807 +3 4582 4726 4662 +3 4438 4582 4554 +3 4438 4554 4410 +3 4438 4410 4330 +3 4410 4255 4330 +3 4255 4251 4330 +3 4329 4251 4255 +3 4437 4329 4409 +3 4581 4437 4553 +3 4581 4553 4661 +3 4581 4661 4725 +3 4661 4806 4725 +3 4806 4830 4725 +3 4899 4830 4806 +3 5209 5291 5397 +3 6167 6063 5919 +3 5199 5139 5055 +3 4525 4421 4313 +3 4565 4421 4525 +3 4565 4525 4673 +3 4565 4673 4709 +3 4673 4819 4709 +3 4819 4820 4709 +3 4903 4820 4819 +3 4903 4819 4963 +3 4903 4963 4995 +3 4963 5055 4995 +3 5055 5083 4995 +3 5139 5083 5055 +3 5200 5139 5199 +3 5200 5199 5283 +3 5199 5395 5283 +3 5395 5335 5283 +3 5427 5335 5395 +3 5427 5395 5487 +3 5427 5487 5519 +3 5487 5579 5519 +3 5579 5580 5519 +3 5671 5580 5579 +3 5671 5579 5775 +3 5671 5775 5815 +3 5775 5919 5815 +3 5919 5959 5815 +3 6063 5959 5919 +3 6168 6063 6167 +3 6168 6167 6071 +3 6167 5921 6071 +3 5921 5967 6071 +3 5823 5967 5921 +3 5823 5921 5777 +3 5823 5777 5679 +3 5777 5589 5679 +3 5589 5590 5679 +3 5527 5590 5589 +3 5527 5589 5489 +3 5527 5489 5435 +3 5489 5397 5435 +3 5397 5343 5435 +3 5291 5343 5397 +3 5210 5291 5209 +3 5210 5209 5147 +3 5209 5057 5147 +3 5057 5091 5147 +3 5003 5091 5057 +3 5003 5057 4965 +3 5003 4965 4911 +3 4965 4829 4911 +3 4829 4830 4911 +3 4717 4830 4829 +3 4717 4829 4675 +3 4717 4675 4573 +3 4675 4527 4573 +3 4527 4429 4573 +3 4321 4429 4527 +3 4321 4527 4241 +3 4321 4241 4242 +3 4241 4313 4242 +3 4525 4313 4241 +3 2191 2087 1957 +3 1259 1213 1135 +3 441 614 365 +3 1258 1393 1439 +3 1439 1475 1524 +3 1475 1525 1524 +3 1393 1475 1439 +3 1333 1393 1258 +3 1333 1258 1211 +3 1258 1133 1211 +3 1133 1131 1211 +3 1083 1131 1133 +3 1083 1133 1052 +3 1083 1052 1006 +3 1052 905 1006 +3 905 924 1006 +3 806 924 905 +3 806 905 759 +3 806 759 670 +3 759 614 670 +3 614 537 670 +3 441 537 614 +3 366 441 365 +3 366 365 438 +3 365 615 438 +3 615 534 438 +3 667 534 615 +3 667 615 760 +3 667 760 803 +3 760 906 803 +3 906 915 803 +3 1007 915 906 +3 1007 906 1053 +3 1007 1053 1087 +3 1053 1135 1087 +3 1135 1165 1087 +3 1213 1165 1135 +3 1268 1213 1259 +3 1268 1259 1343 +3 1259 1440 1343 +3 1440 1395 1343 +3 1477 1395 1440 +3 1477 1440 1526 +3 1477 1526 1561 +3 1526 1622 1561 +3 1622 1631 1561 +3 1727 1631 1622 +3 1727 1622 1817 +3 1727 1817 1860 +3 1817 1957 1860 +3 1957 1993 1860 +3 2087 1993 1957 +3 2192 2087 2191 +3 6072 6169 6243 +3 6072 6320 5968 +3 5968 6432 5824 +3 5824 6576 5680 +3 5680 6716 5591 +3 6831 5688 5591 +3 5688 6724 5832 +3 5832 6584 5976 +3 5976 6440 6080 +3 6080 6328 6177 +3 6079 6177 6251 +3 6079 6327 5975 +3 5975 6439 5831 +3 5823 5679 6715 +3 5823 6575 5967 +3 6071 5967 6431 +3 6055 6237 6163 +3 6163 6304 6056 +3 6056 6416 5952 +3 5952 6560 5808 +3 5808 6700 5664 +3 6707 5815 6567 +3 6567 5959 6423 +3 6423 6063 6311 +3 6071 6319 6168 +3 6431 6319 6071 +3 6575 6431 5967 +3 6715 6575 5823 +3 6830 6715 5679 +3 6830 5679 5590 +3 6830 5590 6723 +3 5590 5687 6723 +3 5687 5831 6723 +3 5831 6583 6723 +3 6439 6583 5831 +3 6327 6439 5975 +3 6251 6327 6079 +3 6328 6251 6177 +3 6440 6328 6080 +3 6584 6440 5976 +3 6724 6584 5832 +3 6831 6724 5688 +3 6716 6831 5591 +3 6576 6716 5680 +3 6432 6576 5824 +3 6320 6432 5968 +3 6243 6320 6072 +3 6312 6243 6169 +3 6312 6169 6064 +3 6312 6064 6424 +3 5816 6424 5960 +3 6424 6064 5960 +3 6568 6424 5816 +3 6568 5816 6708 +3 5816 5672 6708 +3 5672 6821 6708 +3 5664 6821 5581 +3 6821 5672 5581 +3 6700 6821 5664 +3 6560 6700 5808 +3 6416 6560 5952 +3 6304 6416 6056 +3 6237 6304 6163 +3 6303 6237 6055 +3 6303 6055 5951 +3 6303 5951 6415 +3 5951 5807 6415 +3 5807 6559 6415 +3 6699 5807 5663 +3 6559 5807 6699 +3 6311 6168 6242 +3 6168 6319 6242 +3 6063 6168 6311 +3 5959 6063 6423 +3 5815 5959 6567 +3 5671 5815 6707 +3 5671 6707 6820 +3 5671 6820 5580 +3 6820 5663 5580 +3 6699 5663 6820 +3 7286 7344 7436 +3 7975 8254 8183 +3 7285 7193 7079 +3 6545 6513 6401 +3 6657 6513 6545 +3 6657 6545 6689 +3 6657 6689 6797 +3 6689 6889 6797 +3 6889 6882 6797 +3 6949 6882 6889 +3 6949 6889 6981 +3 6949 6981 7043 +3 6981 7079 7043 +3 7079 7141 7043 +3 7193 7141 7079 +3 7278 7193 7285 +3 7278 7285 7343 +3 7285 7435 7343 +3 7435 7399 7343 +3 7491 7399 7435 +3 7491 7435 7531 +3 7491 7531 7583 +3 7531 7675 7583 +3 7675 7668 7583 +3 7787 7668 7675 +3 7787 7675 7823 +3 7787 7823 7931 +3 7823 7975 7931 +3 7975 8075 7931 +3 8183 8075 7975 +3 8251 8183 8254 +3 8251 8254 8184 +3 8254 7976 8184 +3 7976 8076 8184 +3 7932 8076 7976 +3 7932 7976 7824 +3 7932 7824 7788 +3 7824 7676 7788 +3 7676 7669 7788 +3 7584 7669 7676 +3 7584 7676 7532 +3 7584 7532 7492 +3 7532 7436 7492 +3 7436 7400 7492 +3 7344 7400 7436 +3 7279 7344 7286 +3 7279 7286 7194 +3 7286 7080 7194 +3 7080 7142 7194 +3 7044 7142 7080 +3 7044 7080 6982 +3 7044 6982 6950 +3 6982 6890 6950 +3 6890 6883 6950 +3 6798 6883 6890 +3 6798 6890 6690 +3 6798 6690 6658 +3 6690 6546 6658 +3 6546 6514 6658 +3 6402 6514 6546 +3 6402 6546 6300 +3 6402 6300 6297 +3 6300 6401 6297 +3 6545 6401 6300 +3 7269 7187 7075 +3 6289 6395 6543 +3 7277 7343 7433 +3 7973 8069 8177 +3 7925 8069 7973 +3 7925 7973 7821 +3 7925 7821 7781 +3 7821 7667 7781 +3 7667 7668 7781 +3 7583 7668 7667 +3 7583 7667 7529 +3 7583 7529 7491 +3 7529 7433 7491 +3 7433 7399 7491 +3 7343 7399 7433 +3 7278 7343 7277 +3 7278 7277 7193 +3 7277 7077 7193 +3 7077 7141 7193 +3 7043 7141 7077 +3 7043 7077 6979 +3 7043 6979 6949 +3 6979 6881 6949 +3 6881 6882 6949 +3 6791 6882 6881 +3 6791 6881 6687 +3 6791 6687 6651 +3 6687 6543 6651 +3 6543 6507 6651 +3 6395 6507 6543 +3 6290 6395 6289 +3 6290 6289 6389 +3 6289 6541 6389 +3 6541 6501 6389 +3 6645 6501 6541 +3 6645 6541 6685 +3 6645 6685 6785 +3 6685 6873 6785 +3 6873 6874 6785 +3 6943 6874 6873 +3 6943 6873 6977 +3 6943 6977 7037 +3 6977 7075 7037 +3 7075 7135 7037 +3 7187 7135 7075 +3 7270 7187 7269 +3 7270 7269 7337 +3 7269 7431 7337 +3 7431 7393 7337 +3 7485 7393 7431 +3 7485 7431 7527 +3 7485 7527 7577 +3 7527 7659 7577 +3 7659 7660 7577 +3 7775 7660 7659 +3 7775 7659 7819 +3 7775 7819 7919 +3 7819 7971 7919 +3 7971 8063 7919 +3 8171 8063 7971 +3 8171 7971 8243 +3 8171 8243 8244 +3 8243 8177 8244 +3 7973 8177 8243 +3 5274 5330 5418 +3 5941 6228 6153 +3 5273 5185 5077 +3 4547 4511 4403 +3 4655 4511 4547 +3 4655 4547 4695 +3 4655 4695 4799 +3 4695 4893 4799 +3 4893 4886 4799 +3 4949 4886 4893 +3 4949 4893 4985 +3 4949 4985 5041 +3 4985 5077 5041 +3 5077 5129 5041 +3 5185 5129 5077 +3 5266 5185 5273 +3 5266 5273 5329 +3 5273 5417 5329 +3 5417 5381 5329 +3 5473 5381 5417 +3 5473 5417 5509 +3 5473 5509 5565 +3 5509 5653 5565 +3 5653 5646 5565 +3 5761 5646 5653 +3 5761 5653 5797 +3 5761 5797 5905 +3 5797 5941 5905 +3 5941 6049 5905 +3 6153 6049 5941 +3 6225 6153 6228 +3 6225 6228 6154 +3 6228 5942 6154 +3 5942 6050 6154 +3 5906 6050 5942 +3 5906 5942 5798 +3 5906 5798 5762 +3 5798 5654 5762 +3 5654 5647 5762 +3 5566 5647 5654 +3 5566 5654 5510 +3 5566 5510 5474 +3 5510 5418 5474 +3 5418 5382 5474 +3 5330 5382 5418 +3 5267 5330 5274 +3 5267 5274 5186 +3 5274 5078 5186 +3 5078 5130 5186 +3 5042 5130 5078 +3 5042 5078 4986 +3 5042 4986 4950 +3 4986 4894 4950 +3 4894 4887 4950 +3 4800 4887 4894 +3 4800 4894 4696 +3 4800 4696 4656 +3 4696 4548 4656 +3 4548 4512 4656 +3 4404 4512 4548 +3 4404 4548 4302 +3 4404 4302 4299 +3 4302 4403 4299 +3 4547 4403 4302 +3 5257 5179 5073 +3 4291 4397 4545 +3 5265 5329 5415 +3 5939 6043 6147 +3 5899 6043 5939 +3 5899 5939 5795 +3 5899 5795 5755 +3 5795 5645 5755 +3 5645 5646 5755 +3 5565 5646 5645 +3 5565 5645 5507 +3 5565 5507 5473 +3 5507 5415 5473 +3 5415 5381 5473 +3 5329 5381 5415 +3 5266 5329 5265 +3 5266 5265 5185 +3 5265 5075 5185 +3 5075 5129 5185 +3 5041 5129 5075 +3 5041 5075 4983 +3 5041 4983 4949 +3 4983 4885 4949 +3 4885 4886 4949 +3 4793 4886 4885 +3 4793 4885 4693 +3 4793 4693 4649 +3 4693 4545 4649 +3 4545 4505 4649 +3 4397 4505 4545 +3 4292 4397 4291 +3 4292 4291 4391 +3 4291 4543 4391 +3 4543 4499 4391 +3 4643 4499 4543 +3 4643 4543 4691 +3 4643 4691 4787 +3 4691 4877 4787 +3 4877 4878 4787 +3 4943 4878 4877 +3 4943 4877 4981 +3 4943 4981 5035 +3 4981 5073 5035 +3 5073 5123 5035 +3 5179 5123 5073 +3 5258 5179 5257 +3 5258 5257 5323 +3 5257 5413 5323 +3 5413 5375 5323 +3 5467 5375 5413 +3 5467 5413 5505 +3 5467 5505 5559 +3 5505 5637 5559 +3 5637 5638 5559 +3 5749 5638 5637 +3 5749 5637 5793 +3 5749 5793 5893 +3 5793 5937 5893 +3 5937 6037 5893 +3 6141 6037 5937 +3 6141 5937 6217 +3 6141 6217 6218 +3 6217 6147 6218 +3 5939 6147 6217 +3 3218 3269 3346 +3 4009 3814 4078 +3 3217 3146 3056 +3 2611 2591 2509 +3 2695 2591 2611 +3 2695 2611 2728 +3 2695 2728 2799 +3 2728 2881 2799 +3 2881 2876 2799 +3 2952 2876 2881 +3 2952 2881 2979 +3 2952 2979 3024 +3 2979 3056 3024 +3 3056 3099 3024 +3 3146 3099 3056 +3 3212 3146 3217 +3 3212 3217 3268 +3 3217 3345 3268 +3 3345 3314 3268 +3 3389 3314 3345 +3 3389 3345 3421 +3 3389 3421 3461 +3 3421 3545 3461 +3 3545 3539 3461 +3 3653 3539 3545 +3 3653 3545 3681 +3 3653 3681 3786 +3 3681 3814 3786 +3 3814 3909 3786 +3 4009 3909 3814 +3 4075 4009 4078 +3 4075 4078 4010 +3 4078 3815 4010 +3 3815 3910 4010 +3 3787 3910 3815 +3 3787 3815 3682 +3 3787 3682 3654 +3 3682 3546 3654 +3 3546 3540 3654 +3 3462 3540 3546 +3 3462 3546 3422 +3 3462 3422 3390 +3 3422 3346 3390 +3 3346 3315 3390 +3 3269 3315 3346 +3 3213 3269 3218 +3 3213 3218 3147 +3 3218 3057 3147 +3 3057 3100 3147 +3 3025 3100 3057 +3 3025 3057 2980 +3 3025 2980 2953 +3 2980 2882 2953 +3 2882 2877 2953 +3 2800 2877 2882 +3 2800 2882 2729 +3 2800 2729 2696 +3 2729 2612 2696 +3 2612 2592 2696 +3 2510 2592 2612 +3 2510 2612 2431 +3 2510 2431 2428 +3 2431 2509 2428 +3 2611 2509 2431 +3 3539 3460 3461 +3 3388 3389 3461 +3 3389 3313 3314 +3 3314 3267 3268 +3 3211 3212 3268 +3 3212 3145 3146 +3 2951 2876 2952 +3 2876 2875 2794 +3 2794 2793 2690 +3 2586 2690 2689 +3 2586 2585 2504 +3 2504 2503 2419 +3 2419 2418 2496 +3 3646 3647 3780 +3 3647 3538 3539 +3 3382 3306 3381 +3 3306 3307 3260 +3 3203 3260 3261 +3 3203 3204 3138 +3 3138 3139 3091 +3 2944 2868 2867 +3 2867 2787 2786 +3 2786 2683 2682 +3 2496 2495 2579 +3 2418 2495 2496 +3 2503 2418 2419 +3 2585 2503 2504 +3 2689 2585 2586 +3 2793 2689 2690 +3 2875 2793 2794 +3 2951 2875 2876 +3 3023 2951 2952 +3 3023 2952 3024 +3 3023 3024 3098 +3 3146 3098 3099 +3 3098 3024 3099 +3 3145 3098 3146 +3 3211 3145 3212 +3 3267 3211 3268 +3 3313 3267 3314 +3 3388 3313 3389 +3 3460 3388 3461 +3 3538 3460 3539 +3 3646 3538 3647 +3 3779 3646 3780 +3 3779 3780 3903 +3 3779 3903 3902 +3 3903 4003 3902 +3 4003 4002 3902 +3 4066 4002 4003 +3 4066 4003 4067 +3 4066 4067 3995 +3 3896 3995 3996 +3 3995 4067 3996 +3 3895 3995 3896 +3 3895 3896 3773 +3 3895 3773 3772 +3 3639 3773 3640 +3 3772 3773 3639 +3 2682 2579 2578 +3 2579 2495 2578 +3 2683 2579 2682 +3 2787 2683 2786 +3 2868 2787 2867 +3 2945 2868 2944 +3 2945 2944 3016 +3 2945 3016 3017 +3 3016 3091 3017 +3 3091 3092 3017 +3 3139 3092 3091 +3 3204 3139 3138 +3 3261 3204 3203 +3 3307 3261 3260 +3 3382 3307 3306 +3 3454 3382 3381 +3 3454 3381 3453 +3 3454 3453 3531 +3 3453 3530 3531 +3 3530 3640 3531 +3 3639 3640 3530 +3 1330 1383 1466 +3 2173 1989 2249 +3 1329 1252 1160 +3 640 610 515 +3 743 610 640 +3 743 640 785 +3 743 785 879 +3 785 984 879 +3 984 977 879 +3 1046 977 984 +3 1046 984 1078 +3 1046 1078 1126 +3 1078 1160 1126 +3 1160 1204 1126 +3 1252 1204 1160 +3 1322 1252 1329 +3 1322 1329 1382 +3 1329 1465 1382 +3 1465 1434 1382 +3 1516 1434 1465 +3 1516 1465 1551 +3 1516 1551 1600 +3 1551 1700 1600 +3 1700 1692 1600 +3 1810 1692 1700 +3 1810 1700 1842 +3 1810 1842 1943 +3 1842 1989 1943 +3 1989 2076 1943 +3 2173 2076 1989 +3 2246 2173 2249 +3 2246 2249 2174 +3 2249 1990 2174 +3 1990 2077 2174 +3 1944 2077 1990 +3 1944 1990 1843 +3 1944 1843 1811 +3 1843 1701 1811 +3 1701 1693 1811 +3 1601 1693 1701 +3 1601 1701 1552 +3 1601 1552 1517 +3 1552 1466 1517 +3 1466 1435 1517 +3 1383 1435 1466 +3 1323 1383 1330 +3 1323 1330 1253 +3 1330 1161 1253 +3 1161 1205 1253 +3 1127 1205 1161 +3 1127 1161 1079 +3 1127 1079 1047 +3 1079 985 1047 +3 985 978 1047 +3 880 978 985 +3 880 985 786 +3 880 786 744 +3 786 641 744 +3 641 611 744 +3 516 611 641 +3 516 641 416 +3 516 416 413 +3 416 515 413 +3 640 515 416 +3 1515 1516 1600 +3 1516 1433 1434 +3 873 736 737 +3 737 603 604 +3 501 500 596 +3 595 729 596 +3 729 728 865 +3 1796 1928 1929 +3 1929 2061 2062 +3 2238 2166 2167 +3 1425 1426 1373 +3 1196 1195 1243 +3 1195 1118 1117 +3 1117 1038 1037 +3 865 864 967 +3 728 864 865 +3 595 728 729 +3 500 595 596 +3 403 500 501 +3 403 501 404 +3 403 404 508 +3 604 508 509 +3 508 404 509 +3 603 508 604 +3 736 603 737 +3 872 736 873 +3 872 873 977 +3 872 977 976 +3 977 1046 976 +3 1046 1045 976 +3 1125 1045 1046 +3 1125 1046 1126 +3 1125 1126 1203 +3 1126 1204 1203 +3 1204 1251 1203 +3 1322 1251 1252 +3 1251 1204 1252 +3 1321 1251 1322 +3 1321 1322 1381 +3 1434 1381 1382 +3 1381 1322 1382 +3 1433 1381 1434 +3 1515 1433 1516 +3 1599 1515 1600 +3 1599 1600 1692 +3 1599 1692 1691 +3 1692 1804 1691 +3 1804 1803 1691 +3 1936 1803 1804 +3 1936 1804 1937 +3 1936 1937 2069 +3 2167 2069 2070 +3 2069 1937 2070 +3 2166 2069 2167 +3 2237 2166 2238 +3 2237 2238 2158 +3 2062 2158 2159 +3 2158 2238 2159 +3 2061 2158 2062 +3 1928 2061 1929 +3 1795 1796 1682 +3 1928 1796 1795 +3 1037 967 966 +3 967 864 966 +3 1038 967 1037 +3 1118 1038 1117 +3 1196 1118 1195 +3 1244 1196 1243 +3 1244 1243 1311 +3 1244 1311 1312 +3 1311 1373 1312 +3 1373 1374 1312 +3 1426 1374 1373 +3 1508 1426 1425 +3 1508 1425 1507 +3 1508 1507 1592 +3 1507 1591 1592 +3 1591 1681 1592 +3 1681 1682 1592 +3 1795 1682 1681 +3 8557 8166 8553 +3 8556 7913 8562 +3 8562 7769 8568 +3 8586 8177 8592 +3 8622 8184 8617 +3 7661 8569 7776 +3 7776 8575 7920 +3 8587 8172 8581 +3 8245 8172 8587 +3 8245 8587 8178 +3 8587 8593 8178 +3 8593 8070 8178 +3 7926 8070 8593 +3 7926 8593 8599 +3 7926 8599 7782 +3 8599 8605 7782 +3 8605 7669 7782 +3 7788 7669 8605 +3 7788 8605 8611 +3 7788 8611 7932 +3 8611 8617 7932 +3 8617 8076 7932 +3 8184 8076 8617 +3 8251 8184 8622 +3 8251 8622 8183 +3 8622 8616 8183 +3 8616 8075 8183 +3 7931 8075 8616 +3 7931 8616 8610 +3 7931 8610 7787 +3 8610 8604 7787 +3 8604 7668 7787 +3 7781 7668 8604 +3 7781 8604 8598 +3 7781 8598 7925 +3 8598 8592 7925 +3 8592 8069 7925 +3 8177 8069 8592 +3 8244 8177 8586 +3 8244 8586 8171 +3 8586 8580 8171 +3 8580 8063 8171 +3 7919 8063 8580 +3 7919 8580 8574 +3 7919 8574 7775 +3 8574 8568 7775 +3 8568 7660 7775 +3 7769 7660 8568 +3 7913 7769 8562 +3 8057 7913 8556 +3 8057 8556 8165 +3 8556 8553 8165 +3 8553 8240 8165 +3 8166 8240 8553 +3 8058 8166 8557 +3 7914 8557 8563 +3 8058 8557 7914 +3 7770 8563 8569 +3 7914 8563 7770 +3 7920 8581 8064 +3 8581 8172 8064 +3 8575 8581 7920 +3 8569 8575 7776 +3 7770 8569 7661 +3 342 515 336 +3 298 501 290 +3 253 494 259 +3 291 597 502 +3 730 597 291 +3 730 291 283 +3 730 283 866 +3 283 275 866 +3 275 968 866 +3 858 968 275 +3 858 275 267 +3 858 267 722 +3 267 259 722 +3 259 589 722 +3 494 589 259 +3 398 494 253 +3 398 253 493 +3 253 258 493 +3 258 588 493 +3 721 588 258 +3 721 258 266 +3 721 266 857 +3 266 274 857 +3 274 967 857 +3 865 967 274 +3 865 274 282 +3 865 282 729 +3 282 290 729 +3 290 596 729 +3 501 596 290 +3 404 501 298 +3 404 298 509 +3 298 308 509 +3 308 604 509 +3 737 604 308 +3 737 308 315 +3 737 315 873 +3 315 322 873 +3 322 977 873 +3 879 977 322 +3 879 322 329 +3 879 329 743 +3 329 336 743 +3 336 610 743 +3 515 610 336 +3 413 515 342 +3 413 342 516 +3 342 337 516 +3 337 611 516 +3 744 611 337 +3 744 337 330 +3 744 330 880 +3 330 323 880 +3 323 978 880 +3 874 978 323 +3 874 323 316 +3 874 316 738 +3 316 309 738 +3 309 605 738 +3 510 605 309 +3 510 309 299 +3 510 299 405 +3 299 502 405 +3 291 502 299 +3 1930 2580 2063 +3 2063 2497 2160 +3 2160 2420 2239 +3 2239 2505 2168 +3 2071 2168 2587 +3 2071 2691 1938 +3 1938 2795 1805 +3 1805 2877 1693 +3 1693 2800 1811 +3 1811 2696 1944 +3 2246 2428 2173 +3 2173 2509 2076 +3 2076 2591 1943 +3 1943 2695 1810 +3 2572 2054 1921 +3 1922 2677 1789 +3 2781 1683 1789 +3 2868 1682 2787 +3 2787 1796 2683 +3 2683 1929 2579 +3 2579 2062 2496 +3 2586 2504 2070 +3 1937 2690 2586 +3 2690 1804 2794 +3 1810 2799 1692 +3 2695 2799 1810 +3 2591 2695 1943 +3 2509 2591 2076 +3 2428 2509 2173 +3 2510 2428 2246 +3 2510 2246 2174 +3 2510 2174 2592 +3 1944 2592 2077 +3 2592 2174 2077 +3 2696 2592 1944 +3 2800 2696 1811 +3 2877 2800 1693 +3 2795 2877 1805 +3 2691 2795 1938 +3 2587 2691 2071 +3 2505 2587 2168 +3 2420 2505 2239 +3 2497 2420 2160 +3 2580 2497 2063 +3 2684 2580 1930 +3 2684 1930 1797 +3 2684 1797 2788 +3 1797 1683 2788 +3 1683 2869 2788 +3 2781 2869 1683 +3 2677 2781 1789 +3 2573 2677 1922 +3 2573 1922 2055 +3 2573 2055 2490 +3 2232 2490 2152 +3 2490 2055 2152 +3 2415 2490 2232 +3 2415 2232 2151 +3 2415 2151 2489 +3 2151 2054 2489 +3 2054 2572 2489 +3 2676 1921 1788 +3 2572 1921 2676 +3 2780 1788 1682 +3 2676 1788 2780 +3 2794 1692 2876 +3 1692 2799 2876 +3 1804 1692 2794 +3 1937 1804 2690 +3 2070 1937 2586 +3 2167 2070 2504 +3 2167 2504 2238 +3 2504 2419 2238 +3 2419 2496 2238 +3 2496 2159 2238 +3 2062 2159 2496 +3 1929 2062 2579 +3 1796 1929 2683 +3 1682 1796 2787 +3 2780 1682 2868 +3 3997 4293 4068 +3 3648 4887 3540 +3 4655 3786 3909 +3 3633 4781 3766 +3 3990 4494 3890 +3 4292 4067 4397 +3 4505 4397 4003 +3 3786 4799 3653 +3 4799 3539 3653 +3 4655 4799 3786 +3 4511 4655 3909 +3 4511 3909 4403 +3 4075 4403 4009 +3 4403 3909 4009 +3 4299 4403 4075 +3 4299 4075 4010 +3 4299 4010 4404 +3 4010 3910 4404 +3 3910 4512 4404 +3 4656 4512 3910 +3 4656 3910 3787 +3 4656 3787 4800 +3 3540 4800 3654 +3 4800 3787 3654 +3 4887 4800 3540 +3 4794 4887 3648 +3 4794 3648 3781 +3 4794 3781 4650 +3 3781 3904 4650 +3 3904 4506 4650 +3 4398 4506 3904 +3 4068 4398 4004 +3 4398 3904 4004 +3 4293 4398 4068 +3 4392 4293 3997 +3 4392 3997 4500 +3 3997 3897 4500 +3 3897 3774 4500 +3 3774 4644 4500 +3 4788 4644 3774 +3 4788 3774 3641 +3 4788 3641 4879 +3 3641 3532 4879 +3 3532 3634 4879 +3 3634 4782 4879 +3 4638 4782 3634 +3 3890 4638 3767 +3 4638 3634 3767 +3 4494 4638 3890 +3 4386 4494 3990 +3 4386 3990 4288 +3 3990 4063 4288 +3 4063 3989 4288 +3 3989 4385 4288 +3 4493 4385 3989 +3 4493 3989 3889 +3 4493 3889 3766 +3 4493 3766 4637 +3 3766 4781 4637 +3 4793 3539 4886 +3 3539 4799 4886 +3 3647 3539 4793 +3 3647 4793 4649 +3 3647 4649 3780 +3 4649 4505 3780 +3 4505 3903 3780 +3 4003 3903 4505 +3 4067 4003 4397 +3 3996 4067 4292 +3 3996 4292 4391 +3 3996 4391 3896 +3 4391 4499 3896 +3 4499 4643 3896 +3 4643 3773 3896 +3 3640 3773 4643 +3 3640 4643 4787 +3 3640 4787 3531 +3 4787 4878 3531 +3 4878 3633 3531 +3 4781 3633 4878 +3 6875 5750 5639 +3 5750 6786 5894 +3 5894 6646 6038 +3 6038 6502 6142 +3 6219 6142 6390 +3 6219 6291 6148 +3 6396 6044 6148 +3 5647 6883 5762 +3 6050 6402 6154 +3 6154 6297 6225 +3 6225 6401 6153 +3 6153 6513 6049 +3 6496 5888 6032 +3 6874 5638 6785 +3 6785 5749 6645 +3 5893 6501 6645 +3 6501 6037 6389 +3 6389 6141 6290 +3 6507 5899 6651 +3 5755 6791 6651 +3 6882 6791 5646 +3 6049 6657 5905 +3 6657 5761 5905 +3 6513 6657 6049 +3 6401 6513 6153 +3 6297 6401 6225 +3 6402 6297 6154 +3 6514 6402 6050 +3 6514 6050 5906 +3 6514 5906 6658 +3 5906 5762 6658 +3 5762 6798 6658 +3 6883 6798 5762 +3 6792 6883 5647 +3 6792 5647 5756 +3 6792 5756 5900 +3 6792 5900 6652 +3 5900 6044 6652 +3 6044 6508 6652 +3 6396 6508 6044 +3 6291 6396 6148 +3 6390 6291 6219 +3 6502 6390 6142 +3 6646 6502 6038 +3 6786 6646 5894 +3 6875 6786 5750 +3 6780 6875 5639 +3 6780 5639 5744 +3 6780 5744 6640 +3 5744 5888 6640 +3 5888 6496 6640 +3 6384 6032 6136 +3 6496 6032 6384 +3 6135 6286 6214 +3 6286 6136 6214 +3 6384 6136 6286 +3 6383 6135 6031 +3 6286 6135 6383 +3 6495 6031 5887 +3 6383 6031 6495 +3 6639 5887 5743 +3 6495 5887 6639 +3 6779 5743 5638 +3 6639 5743 6779 +3 6882 5761 6797 +3 5761 6657 6797 +3 5646 5761 6882 +3 5755 5646 6791 +3 5899 5755 6651 +3 6043 5899 6507 +3 6043 6507 6395 +3 6043 6395 6147 +3 6395 6290 6147 +3 6290 6218 6147 +3 6141 6218 6290 +3 6037 6141 6389 +3 5893 6037 6501 +3 5749 5893 6645 +3 5638 5749 6785 +3 6779 5638 6874 +3 7577 7571 7485 +3 7485 7479 7393 +3 7393 7387 7337 +3 7337 7331 7270 +3 7187 7270 7260 +3 7135 7187 7181 +3 7135 7129 7037 +3 7037 7031 6943 +3 6943 6937 6874 +3 6874 6864 6779 +3 6779 6773 6639 +3 6633 6495 6639 +3 6495 6489 6383 +3 6383 6377 6286 +3 6282 6384 6286 +3 6384 6378 6496 +3 6496 6490 6640 +3 6944 6938 7038 +3 7038 7032 7136 +3 7136 7130 7188 +3 7188 7182 7271 +3 7271 7261 7338 +3 7486 7572 7578 +3 7578 7651 7661 +3 7572 7651 7578 +3 7480 7572 7486 +3 7480 7486 7394 +3 7480 7394 7388 +3 7394 7338 7388 +3 7338 7332 7388 +3 7261 7332 7338 +3 7182 7261 7271 +3 7130 7182 7188 +3 7032 7130 7136 +3 6938 7032 7038 +3 6865 6938 6944 +3 6865 6944 6875 +3 6865 6875 6780 +3 6865 6780 6774 +3 6780 6640 6774 +3 6640 6634 6774 +3 6490 6634 6640 +3 6378 6490 6496 +3 6282 6378 6384 +3 6377 6282 6286 +3 6489 6377 6383 +3 6633 6489 6495 +3 6773 6633 6639 +3 6864 6773 6779 +3 6937 6864 6874 +3 7031 6937 6943 +3 7129 7031 7037 +3 7181 7129 7135 +3 7260 7181 7187 +3 7331 7260 7270 +3 7387 7331 7337 +3 7479 7387 7393 +3 7571 7479 7485 +3 7650 7571 7577 +3 7650 7577 7660 +3 7650 7660 7763 +3 7913 7763 7769 +3 7763 7660 7769 +3 7907 7763 7913 +3 7907 7913 8057 +3 7907 8057 8051 +3 8057 8165 8051 +3 8165 8159 8051 +3 8236 8159 8165 +3 8236 8165 8240 +3 8236 8240 8160 +3 8240 8166 8160 +3 8166 8058 8160 +3 8058 8052 8160 +3 7908 8052 8058 +3 7908 8058 7914 +3 7908 7914 7764 +3 7914 7770 7764 +3 7770 7661 7764 +3 7661 7651 7764 +3 7570 7571 7650 +3 7571 7478 7479 +3 7387 7479 7386 +3 7330 7331 7387 +3 7331 7259 7260 +3 7031 7030 6937 +3 6937 6936 6864 +3 6864 6863 6765 +3 6765 6764 6625 +3 6625 6624 6481 +3 6481 6480 6369 +3 6369 6368 6274 +3 8228 8227 8151 +3 7899 7754 7755 +3 7755 7649 7650 +3 7470 7471 7378 +3 7378 7379 7322 +3 7322 7323 7249 +3 7249 7250 7172 +3 7120 7172 7173 +3 6928 6854 6853 +3 6853 6757 6756 +3 6756 6617 6616 +3 6616 6473 6472 +3 6274 6273 6361 +3 6368 6273 6274 +3 6480 6368 6369 +3 6624 6480 6481 +3 6764 6624 6625 +3 6863 6764 6765 +3 6936 6863 6864 +3 7030 6936 6937 +3 7128 7030 7031 +3 7128 7031 7129 +3 7128 7129 7180 +3 7260 7180 7181 +3 7180 7129 7181 +3 7259 7180 7260 +3 7330 7259 7331 +3 7386 7330 7387 +3 7478 7386 7479 +3 7570 7478 7571 +3 7649 7570 7650 +3 7754 7649 7755 +3 7898 7754 7899 +3 7898 7899 8043 +3 7898 8043 8042 +3 8043 8151 8042 +3 8151 8150 8042 +3 8227 8150 8151 +3 8142 8227 8228 +3 8142 8228 8143 +3 8142 8143 8035 +3 8142 8035 8034 +3 7890 8035 7891 +3 8034 8035 7890 +3 7746 7891 7747 +3 7890 7891 7746 +3 6472 6361 6360 +3 6361 6273 6360 +3 6473 6361 6472 +3 6617 6473 6616 +3 6757 6617 6756 +3 6854 6757 6853 +3 6929 6854 6928 +3 6929 6928 7022 +3 6929 7022 7023 +3 7022 7120 7023 +3 7120 7121 7023 +3 7173 7121 7120 +3 7250 7173 7172 +3 7323 7250 7249 +3 7379 7323 7322 +3 7471 7379 7378 +3 7563 7471 7470 +3 7563 7470 7562 +3 7563 7562 7640 +3 7562 7639 7640 +3 7639 7747 7640 +3 7746 7747 7639 +3 5638 5553 5559 +3 5559 5461 5467 +3 5467 5369 5375 +3 5317 5323 5375 +3 5323 5248 5258 +3 4943 4937 4878 +3 4878 4868 4781 +3 4781 4775 4637 +3 4637 4631 4493 +3 4385 4493 4487 +3 4385 4379 4288 +3 4386 4288 4284 +3 4386 4380 4494 +3 4494 4488 4638 +3 5036 4944 4938 +3 5036 5030 5124 +3 5124 5118 5180 +3 5174 5259 5180 +3 5744 5882 5888 +3 6214 6210 6135 +3 5737 5743 5887 +3 5743 5628 5638 +3 5462 5376 5370 +3 5259 5249 5324 +3 5174 5249 5259 +3 5118 5174 5180 +3 5030 5118 5124 +3 4938 5030 5036 +3 4869 4938 4944 +3 4869 4944 4879 +3 4869 4879 4782 +3 4869 4782 4776 +3 4782 4638 4776 +3 4638 4632 4776 +3 4488 4632 4638 +3 4380 4488 4494 +3 4284 4380 4386 +3 4379 4284 4288 +3 4487 4379 4385 +3 4631 4487 4493 +3 4775 4631 4637 +3 4868 4775 4781 +3 4937 4868 4878 +3 5029 4937 4943 +3 5029 4943 5035 +3 5029 5035 5117 +3 5035 5123 5117 +3 5123 5173 5117 +3 5258 5173 5179 +3 5173 5123 5179 +3 5248 5173 5258 +3 5317 5248 5323 +3 5369 5317 5375 +3 5461 5369 5467 +3 5553 5461 5559 +3 5628 5553 5638 +3 5737 5628 5743 +3 5881 5737 5887 +3 5881 5887 6031 +3 5881 6031 6025 +3 6031 6135 6025 +3 6135 6129 6025 +3 6210 6129 6135 +3 6130 6210 6214 +3 6130 6214 6136 +3 6130 6136 6032 +3 6130 6032 6026 +3 6032 5888 6026 +3 5888 5882 6026 +3 5738 5744 5639 +3 5882 5744 5738 +3 5370 5324 5318 +3 5324 5249 5318 +3 5376 5324 5370 +3 5468 5376 5462 +3 5468 5462 5554 +3 5468 5554 5560 +3 5554 5629 5560 +3 5629 5639 5560 +3 5738 5639 5629 +3 5552 5553 5628 +3 5461 5553 5460 +3 5461 5368 5369 +3 5369 5316 5317 +3 5317 5247 5248 +3 5029 5028 4937 +3 4937 4936 4868 +3 4868 4867 4767 +3 4767 4766 4623 +3 4623 4622 4479 +3 4479 4478 4371 +3 4371 4370 4276 +3 4276 4275 4363 +3 6009 6008 6113 +3 5873 5728 5729 +3 5729 5627 5628 +3 5452 5453 5360 +3 5360 5361 5308 +3 5308 5309 5237 +3 5237 5238 5164 +3 5165 5108 5164 +3 5108 5109 5020 +3 4758 4857 4759 +3 4614 4758 4615 +3 4363 4362 4471 +3 4275 4362 4363 +3 4370 4275 4276 +3 4478 4370 4371 +3 4622 4478 4479 +3 4766 4622 4623 +3 4867 4766 4767 +3 4936 4867 4868 +3 5028 4936 4937 +3 5116 5028 5029 +3 5116 5029 5117 +3 5116 5117 5172 +3 5248 5172 5173 +3 5172 5117 5173 +3 5247 5172 5248 +3 5316 5247 5317 +3 5368 5316 5369 +3 5460 5368 5461 +3 5552 5460 5553 +3 5627 5552 5628 +3 5728 5627 5729 +3 5872 5728 5873 +3 5872 5873 6017 +3 5872 6017 6016 +3 6017 6121 6016 +3 6121 6120 6016 +3 6201 6120 6121 +3 6201 6121 6202 +3 6201 6202 6112 +3 6202 6113 6112 +3 6113 6008 6112 +3 5864 6009 5865 +3 6008 6009 5864 +3 5720 5865 5721 +3 5864 5865 5720 +3 4614 4471 4470 +3 4471 4362 4470 +3 4615 4471 4614 +3 4759 4615 4758 +3 4858 4759 4857 +3 4858 4857 4928 +3 4858 4928 4929 +3 4928 5020 4929 +3 5020 5021 4929 +3 5109 5021 5020 +3 5165 5109 5108 +3 5238 5165 5164 +3 5309 5238 5237 +3 5361 5309 5308 +3 5453 5361 5360 +3 5545 5453 5452 +3 5545 5452 5544 +3 5545 5544 5618 +3 5544 5617 5618 +3 5617 5721 5618 +3 5720 5721 5617 +3 3448 3454 3531 +3 3454 3376 3382 +3 3382 3301 3307 +3 3139 3133 3092 +3 3092 3086 3017 +3 3017 3011 2945 +3 2945 2939 2868 +3 2868 2861 2780 +3 2775 2676 2780 +3 2671 2572 2676 +3 2572 2566 2489 +3 2489 2483 2415 +3 2490 2415 2411 +3 2490 2484 2573 +3 2573 2567 2677 +3 2677 2672 2781 +3 2781 2776 2869 +3 2869 2862 2946 +3 3093 3134 3140 +3 3140 3198 3205 +3 3262 3205 3256 +3 3262 3302 3308 +3 3308 3377 3383 +3 3383 3449 3455 +3 3766 3626 3633 +3 3523 3531 3633 +3 3455 3524 3532 +3 3449 3524 3455 +3 3377 3449 3383 +3 3302 3377 3308 +3 3256 3302 3262 +3 3198 3256 3205 +3 3134 3198 3140 +3 3087 3134 3093 +3 3087 3093 3018 +3 3087 3018 3012 +3 3018 2946 3012 +3 2946 2940 3012 +3 2862 2940 2946 +3 2776 2862 2869 +3 2672 2776 2781 +3 2567 2672 2677 +3 2484 2567 2573 +3 2411 2484 2490 +3 2483 2411 2415 +3 2566 2483 2489 +3 2671 2566 2572 +3 2775 2671 2676 +3 2861 2775 2780 +3 2939 2861 2868 +3 3011 2939 2945 +3 3086 3011 3017 +3 3133 3086 3092 +3 3197 3133 3139 +3 3197 3139 3204 +3 3197 3204 3255 +3 3307 3255 3261 +3 3255 3204 3261 +3 3301 3255 3307 +3 3376 3301 3382 +3 3448 3376 3454 +3 3523 3448 3531 +3 3626 3523 3633 +3 3759 3626 3766 +3 3759 3766 3889 +3 3759 3889 3882 +3 3889 3989 3882 +3 3989 3982 3882 +3 4059 3982 3989 +3 4059 3989 4063 +3 4059 4063 3983 +3 3890 3983 3990 +3 3983 4063 3990 +3 3883 3983 3890 +3 3883 3890 3767 +3 3883 3767 3760 +3 3767 3627 3760 +3 3532 3627 3634 +3 3627 3767 3634 +3 3524 3627 3532 +3 3523 3447 3448 +3 3375 3376 3448 +3 3376 3300 3301 +3 3301 3254 3255 +3 3196 3197 3255 +3 3197 3132 3133 +3 3133 3085 3086 +3 3086 3010 3011 +3 2938 2939 3011 +3 2666 2665 2561 +3 2560 2478 2561 +3 2477 2405 2478 +3 2405 2404 2473 +3 2473 2472 2556 +3 2556 2555 2661 +3 2661 2660 2765 +3 2765 2764 2854 +3 2854 2853 2933 +3 2933 2932 3005 +3 3005 3004 3080 +3 3080 3079 3127 +3 3126 3190 3127 +3 3190 3189 3249 +3 3249 3248 3295 +3 3752 3618 3619 +3 3619 3522 3523 +3 3295 3294 3370 +3 3248 3294 3295 +3 3189 3248 3249 +3 3126 3189 3190 +3 3079 3126 3127 +3 3004 3079 3080 +3 2932 3004 3005 +3 2853 2932 2933 +3 2764 2853 2854 +3 2660 2764 2765 +3 2555 2660 2661 +3 2472 2555 2556 +3 2404 2472 2473 +3 2477 2404 2405 +3 2560 2477 2478 +3 2665 2560 2561 +3 2769 2665 2666 +3 2769 2666 2770 +3 2769 2770 2860 +3 2939 2860 2861 +3 2860 2770 2861 +3 2938 2860 2939 +3 3010 2938 3011 +3 3085 3010 3086 +3 3132 3085 3133 +3 3196 3132 3197 +3 3254 3196 3255 +3 3300 3254 3301 +3 3375 3300 3376 +3 3447 3375 3448 +3 3522 3447 3523 +3 3618 3522 3619 +3 3751 3618 3752 +3 3751 3752 3875 +3 3751 3875 3874 +3 3875 3975 3874 +3 3975 3974 3874 +3 4050 3974 3975 +3 4050 3975 4051 +3 4050 4051 3967 +3 3868 3967 3968 +3 3967 4051 3968 +3 3867 3967 3868 +3 3867 3868 3745 +3 3867 3745 3744 +3 3611 3745 3612 +3 3744 3745 3611 +3 3441 3370 3369 +3 3370 3294 3369 +3 3442 3370 3441 +3 3442 3441 3514 +3 3442 3514 3515 +3 3514 3612 3515 +3 3611 3612 3514 +3 1238 1196 1244 +3 1196 1190 1118 +3 1118 1112 1038 +3 1789 1916 1922 +3 1921 1915 1788 +3 1788 1782 1682 +3 1674 1683 1587 +3 1587 1593 1503 +3 1421 1503 1509 +3 1421 1427 1369 +3 1369 1375 1303 +3 1239 1303 1313 +3 1239 1245 1191 +3 1191 1197 1113 +3 1119 1033 1113 +3 1039 959 1033 +3 959 968 852 +3 852 858 716 +3 716 722 583 +3 583 589 487 +3 487 494 395 +3 395 398 486 +3 493 582 486 +3 1038 1032 967 +3 1112 1032 1038 +3 1190 1112 1118 +3 1238 1190 1196 +3 1302 1238 1244 +3 1302 1244 1312 +3 1302 1312 1368 +3 1312 1374 1368 +3 1374 1420 1368 +3 1508 1420 1426 +3 1420 1374 1426 +3 1502 1420 1508 +3 1502 1508 1592 +3 1502 1592 1586 +3 1592 1682 1586 +3 1682 1673 1586 +3 1782 1673 1682 +3 1915 1782 1788 +3 2048 1915 1921 +3 2048 1921 2054 +3 2048 2054 2144 +3 2054 2151 2144 +3 2151 2232 2144 +3 2232 2229 2144 +3 2145 2229 2232 +3 2145 2232 2152 +3 2145 2152 2055 +3 2145 2055 2049 +3 2055 1922 2049 +3 1922 1916 2049 +3 1783 1789 1683 +3 1916 1789 1783 +3 851 967 958 +3 967 1032 958 +3 857 967 851 +3 857 851 715 +3 857 715 721 +3 715 582 721 +3 582 588 721 +3 493 588 582 +3 398 493 486 +3 494 398 395 +3 589 494 487 +3 722 589 583 +3 858 722 716 +3 968 858 852 +3 1039 968 959 +3 1119 1039 1033 +3 1197 1119 1113 +3 1245 1197 1191 +3 1313 1245 1239 +3 1375 1313 1303 +3 1427 1375 1369 +3 1509 1427 1421 +3 1593 1509 1503 +3 1683 1593 1587 +3 1783 1683 1674 +3 1673 1672 1586 +3 1585 1502 1586 +3 1502 1501 1420 +3 1302 1237 1238 +3 1238 1189 1190 +3 1190 1111 1112 +3 1112 1031 1032 +3 1032 957 958 +3 958 844 845 +3 845 708 709 +3 389 388 474 +3 474 473 570 +3 570 569 703 +3 703 702 839 +3 839 838 949 +3 949 948 1026 +3 1026 1025 1106 +3 1184 1106 1105 +3 1183 1232 1184 +3 1232 1231 1294 +3 1903 1770 1902 +3 2138 2223 2222 +3 1776 1775 1673 +3 1495 1414 1413 +3 1294 1293 1362 +3 1231 1293 1294 +3 1183 1231 1232 +3 1105 1183 1184 +3 1025 1105 1106 +3 948 1025 1026 +3 838 948 949 +3 702 838 839 +3 569 702 703 +3 473 569 570 +3 388 473 474 +3 479 388 389 +3 479 389 480 +3 479 480 575 +3 709 575 576 +3 575 480 576 +3 708 575 709 +3 844 708 845 +3 957 844 958 +3 1031 957 1032 +3 1111 1031 1112 +3 1189 1111 1190 +3 1237 1189 1238 +3 1301 1237 1302 +3 1301 1302 1368 +3 1301 1368 1367 +3 1368 1420 1367 +3 1420 1419 1367 +3 1501 1419 1420 +3 1585 1501 1502 +3 1672 1585 1586 +3 1775 1672 1673 +3 1908 1775 1776 +3 1908 1776 1909 +3 1908 1909 2042 +3 1908 2042 2041 +3 2042 2138 2041 +3 2138 2137 2041 +3 2222 2137 2138 +3 2131 2222 2223 +3 2131 2223 2132 +3 2131 2132 2036 +3 2131 2036 2035 +3 2036 1903 2035 +3 1903 1902 2035 +3 1769 1770 1664 +3 1902 1770 1769 +3 1413 1362 1361 +3 1362 1293 1361 +3 1414 1362 1413 +3 1496 1414 1495 +3 1496 1495 1579 +3 1496 1579 1580 +3 1579 1663 1580 +3 1663 1664 1580 +3 1769 1664 1663 +3 8450 8135 8455 +3 8495 8151 8503 +3 8542 8160 8536 +3 7641 8472 7748 +3 7748 8480 7892 +3 8496 8144 8488 +3 8229 8144 8496 +3 8229 8496 8152 +3 8496 8504 8152 +3 8504 8044 8152 +3 7900 8044 8504 +3 7900 8504 8512 +3 7900 8512 7756 +3 8512 8520 7756 +3 8520 7651 7756 +3 7764 7651 8520 +3 7764 8520 8528 +3 7764 8528 7908 +3 8528 8536 7908 +3 8536 8052 7908 +3 8160 8052 8536 +3 8236 8160 8542 +3 8236 8542 8159 +3 8542 8535 8159 +3 8535 8051 8159 +3 7907 8051 8535 +3 7907 8535 8527 +3 7907 8527 7763 +3 8527 8519 7763 +3 8519 7650 7763 +3 7755 7650 8519 +3 7755 8519 8511 +3 7755 8511 7899 +3 8511 8503 7899 +3 8503 8043 7899 +3 8151 8043 8503 +3 8228 8151 8495 +3 8228 8495 8143 +3 8495 8487 8143 +3 8487 8035 8143 +3 7891 8035 8487 +3 7891 8487 8479 +3 7891 8479 7747 +3 8479 8471 7747 +3 8471 7640 7747 +3 7739 7640 8471 +3 7739 8471 8463 +3 7739 8463 7883 +3 8463 8455 7883 +3 8455 8027 7883 +3 8135 8027 8455 +3 8222 8135 8450 +3 8222 8450 8136 +3 8450 8456 8136 +3 8456 8028 8136 +3 7884 8456 8464 +3 8028 8456 7884 +3 7740 8464 8472 +3 7884 8464 7740 +3 7892 8488 8036 +3 8488 8144 8036 +3 8480 8488 7892 +3 8472 8480 7748 +3 7740 8472 7641 +3 239 486 233 +3 197 474 191 +3 158 469 165 +3 192 571 475 +3 704 571 192 +3 704 192 186 +3 704 186 840 +3 186 179 840 +3 179 950 840 +3 834 950 179 +3 834 179 172 +3 834 172 698 +3 172 165 698 +3 165 565 698 +3 469 565 165 +3 384 469 158 +3 384 158 468 +3 158 164 468 +3 164 564 468 +3 697 564 164 +3 697 164 171 +3 697 171 833 +3 171 178 833 +3 178 949 833 +3 839 949 178 +3 839 178 185 +3 839 185 703 +3 185 191 703 +3 191 570 703 +3 474 570 191 +3 389 474 197 +3 389 197 480 +3 197 205 480 +3 205 576 480 +3 709 576 205 +3 709 205 211 +3 709 211 845 +3 211 218 845 +3 218 958 845 +3 851 958 218 +3 851 218 226 +3 851 226 715 +3 226 233 715 +3 233 582 715 +3 486 582 233 +3 395 486 239 +3 395 239 487 +3 239 234 487 +3 234 583 487 +3 716 583 234 +3 716 234 227 +3 716 227 852 +3 227 219 852 +3 219 959 852 +3 846 959 219 +3 846 219 212 +3 846 212 710 +3 212 206 710 +3 206 577 710 +3 481 577 206 +3 481 206 198 +3 481 198 390 +3 198 475 390 +3 192 475 198 +3 2855 1771 1665 +3 2766 1904 1771 +3 2662 2037 1904 +3 2557 2133 2037 +3 2133 2474 2224 +3 2139 2224 2406 +3 1764 2760 1897 +3 2126 2468 2218 +3 2127 2218 2402 +3 2469 2031 2127 +3 2552 1898 2031 +3 2657 1765 1898 +3 1765 2761 1665 +3 2661 1903 2556 +3 2036 2473 2556 +3 2561 2478 2042 +3 2561 1909 2666 +3 2666 1776 2770 +3 2770 1673 2861 +3 2861 1782 2775 +3 2775 1915 2671 +3 2671 2048 2566 +3 2566 2144 2483 +3 2483 2229 2411 +3 2411 2145 2484 +3 2567 2484 2049 +3 2567 1916 2672 +3 2672 1783 2776 +3 2862 2776 1674 +3 1777 2771 2862 +3 2771 1910 2667 +3 2139 2479 2043 +3 2406 2479 2139 +3 2474 2406 2224 +3 2557 2474 2133 +3 2662 2557 2037 +3 2766 2662 1904 +3 2855 2766 1771 +3 2761 2855 1665 +3 2657 2761 1765 +3 2552 2657 1898 +3 2469 2552 2031 +3 2402 2469 2127 +3 2468 2402 2218 +3 2551 2468 2126 +3 2551 2126 2030 +3 2551 2030 2656 +3 2030 1897 2656 +3 1897 2760 2656 +3 2667 2043 2562 +3 2043 2479 2562 +3 1910 2043 2667 +3 1777 1910 2771 +3 1674 1777 2862 +3 1783 1674 2776 +3 1916 1783 2672 +3 2049 1916 2567 +3 2145 2049 2484 +3 2229 2145 2411 +3 2144 2229 2483 +3 2048 2144 2566 +3 1915 2048 2671 +3 1782 1915 2775 +3 1673 1782 2861 +3 1776 1673 2770 +3 1909 1776 2666 +3 2042 1909 2561 +3 2138 2042 2478 +3 2138 2478 2223 +3 2478 2405 2223 +3 2405 2473 2223 +3 2473 2132 2223 +3 2036 2132 2473 +3 1903 2036 2556 +3 1770 1903 2661 +3 1770 2661 2765 +3 1770 2765 1664 +3 2765 2854 1664 +3 2854 1764 1664 +3 2760 1764 2854 +3 3746 4616 3869 +3 3753 4768 3620 +3 4380 3983 3883 +3 3983 4284 4059 +3 3982 4059 4379 +3 4767 3619 3523 +3 3619 4623 3752 +3 4371 4051 3975 +3 4051 4276 3968 +3 3612 4759 3515 +3 3861 4463 3961 +3 3961 4355 4047 +3 4047 4270 3962 +3 3962 4356 3862 +3 3739 3862 4464 +3 3606 3739 4608 +3 3515 4858 3605 +3 4759 4858 3515 +3 4615 4759 3612 +3 4615 3612 3745 +3 4615 3745 4471 +3 3745 3868 4471 +3 3868 3968 4471 +3 3968 4363 4471 +3 4276 4363 3968 +3 4371 4276 4051 +3 4479 4371 3975 +3 3752 4479 3875 +3 4479 3975 3875 +3 4623 4479 3752 +3 4767 4623 3619 +3 4868 4767 3523 +3 4868 3523 4775 +3 3523 3626 4775 +3 3626 3759 4775 +3 3759 4631 4775 +3 4487 4631 3759 +3 3982 4487 3882 +3 4487 3759 3882 +3 4379 4487 3982 +3 4284 4379 4059 +3 4380 4284 3983 +3 4488 4380 3883 +3 4488 3883 4632 +3 3627 4632 3760 +3 4632 3883 3760 +3 4776 4632 3627 +3 4776 3627 4869 +3 3620 4869 3524 +3 4869 3627 3524 +3 4768 4869 3620 +3 4624 4768 3753 +3 4624 3753 3876 +3 4624 3876 4480 +3 3876 3976 4480 +3 3976 4372 4480 +3 4277 4372 3976 +3 4277 3976 4052 +3 4277 4052 3969 +3 4277 3969 4364 +3 3969 3869 4364 +3 3869 4472 4364 +3 4616 4472 3869 +3 4760 4616 3746 +3 4760 3746 3613 +3 4760 3613 4859 +3 3613 3516 4859 +3 3516 3606 4859 +3 3606 4752 4859 +3 4608 4752 3606 +3 4464 4608 3739 +3 4356 4464 3862 +3 4270 4356 3962 +3 4355 4270 4047 +3 4463 4355 3961 +3 4607 4463 3861 +3 4607 3861 3738 +3 4607 3738 4751 +3 3738 3605 4751 +3 3605 4858 4751 +3 5619 6855 5722 +3 5722 6758 5866 +3 5866 6618 6010 +3 6010 6474 6114 +3 6114 6362 6203 +3 6018 6626 5874 +3 5874 6766 5730 +3 6130 6282 6210 +3 6489 5881 6025 +3 5881 6633 5737 +3 5729 6625 5873 +3 5873 6481 6017 +3 6017 6369 6121 +3 5865 6009 6473 +3 5865 6617 5721 +3 5857 6465 6001 +3 6001 6353 6105 +3 6002 6466 5858 +3 5858 6610 5714 +3 5714 6750 5619 +3 5721 6757 5618 +3 6757 6854 5618 +3 6617 6757 5721 +3 6473 6617 5865 +3 6361 6473 6009 +3 6361 6009 6113 +3 6361 6113 6274 +3 6121 6274 6202 +3 6274 6113 6202 +3 6369 6274 6121 +3 6481 6369 6017 +3 6625 6481 5873 +3 6765 6625 5729 +3 6765 5729 5628 +3 6765 5628 6864 +3 5628 5737 6864 +3 5737 6773 6864 +3 6633 6773 5737 +3 6489 6633 5881 +3 6377 6489 6025 +3 6210 6377 6129 +3 6377 6025 6129 +3 6282 6377 6210 +3 6378 6282 6130 +3 6378 6130 6490 +3 5882 6490 6026 +3 6490 6130 6026 +3 6634 6490 5882 +3 6634 5882 5738 +3 6634 5738 6774 +3 5738 6865 6774 +3 5730 6865 5629 +3 6865 5738 5629 +3 6766 6865 5730 +3 6626 6766 5874 +3 6482 6626 6018 +3 6482 6018 6122 +3 6482 6122 6370 +3 6122 6203 6370 +3 6203 6275 6370 +3 6362 6275 6203 +3 6474 6362 6114 +3 6618 6474 6010 +3 6758 6618 5866 +3 6855 6758 5722 +3 6750 6855 5619 +3 6610 6750 5714 +3 6466 6610 5858 +3 6354 6466 6002 +3 6354 6002 6106 +3 6354 6106 6268 +3 6105 6268 6196 +3 6268 6106 6196 +3 6353 6268 6105 +3 6465 6353 6001 +3 6609 6465 5857 +3 6609 5857 5713 +3 6609 5713 6749 +3 5713 5618 6749 +3 5618 6854 6749 +3 6409 6465 6553 +3 6553 6609 6805 +3 6990 7023 7051 +3 7051 7121 7091 +3 7173 7201 7091 +3 7250 7294 7201 +3 7323 7407 7294 +3 7591 7640 7683 +3 7683 7739 7795 +3 7939 7795 7883 +3 7939 8027 8083 +3 8083 8135 8220 +3 7940 7884 7796 +3 7796 7740 7684 +3 7592 7684 7641 +3 7592 7564 7500 +3 7500 7472 7408 +3 7202 7174 7092 +3 7092 7122 7052 +3 7122 7024 7052 +3 7174 7122 7092 +3 7251 7174 7202 +3 7251 7202 7295 +3 7251 7295 7324 +3 7295 7408 7324 +3 7408 7380 7324 +3 7472 7380 7408 +3 7564 7472 7500 +3 7641 7564 7592 +3 7740 7641 7684 +3 7884 7740 7796 +3 8028 7884 7940 +3 8028 7940 8084 +3 8028 8084 8136 +3 8084 8220 8136 +3 8220 8222 8136 +3 8135 8222 8220 +3 8027 8135 8083 +3 7883 8027 7939 +3 7739 7883 7795 +3 7640 7739 7683 +3 7563 7640 7591 +3 7563 7591 7499 +3 7563 7499 7471 +3 7499 7407 7471 +3 7407 7379 7471 +3 7323 7379 7407 +3 7250 7323 7294 +3 7173 7250 7201 +3 7121 7173 7091 +3 7023 7121 7051 +3 6929 7023 6990 +3 6929 6990 6897 +3 6929 6897 6854 +3 6897 6805 6854 +3 6805 6749 6854 +3 6609 6749 6805 +3 6465 6609 6553 +3 6353 6465 6409 +3 6353 6409 6268 +3 6409 6410 6268 +3 6410 6354 6268 +3 6466 6354 6410 +3 6466 6410 6554 +3 6466 6554 6610 +3 6554 6806 6610 +3 6806 6750 6610 +3 6855 6750 6806 +3 6855 6806 6898 +3 6855 6898 6930 +3 6898 6991 6930 +3 6991 7024 6930 +3 7052 7024 6991 +3 5234 5166 5066 +3 4268 4355 4535 +3 5233 5309 5405 +3 5929 6001 6105 +3 5857 6001 5929 +3 5857 5929 5785 +3 5857 5785 5713 +3 5785 5613 5713 +3 5613 5618 5713 +3 5545 5618 5613 +3 5545 5613 5497 +3 5545 5497 5453 +3 5497 5405 5453 +3 5405 5361 5453 +3 5309 5361 5405 +3 5238 5309 5233 +3 5238 5233 5165 +3 5233 5065 5165 +3 5065 5109 5165 +3 5021 5109 5065 +3 5021 5065 4973 +3 5021 4973 4929 +3 4973 4853 4929 +3 4853 4858 4929 +3 4751 4858 4853 +3 4751 4853 4683 +3 4751 4683 4607 +3 4683 4535 4607 +3 4535 4463 4607 +3 4355 4463 4535 +3 4270 4355 4268 +3 4270 4268 4356 +3 4268 4536 4356 +3 4536 4464 4356 +3 4608 4464 4536 +3 4608 4536 4684 +3 4608 4684 4752 +3 4684 4854 4752 +3 4854 4859 4752 +3 4930 4859 4854 +3 4930 4854 4974 +3 4930 4974 5022 +3 4974 5066 5022 +3 5066 5110 5022 +3 5166 5110 5066 +3 5239 5166 5234 +3 5239 5234 5310 +3 5234 5406 5310 +3 5406 5362 5310 +3 5454 5362 5406 +3 5454 5406 5498 +3 5454 5498 5546 +3 5498 5614 5546 +3 5614 5619 5546 +3 5714 5619 5614 +3 5714 5614 5786 +3 5714 5786 5858 +3 5786 5930 5858 +3 5930 6002 5858 +3 6106 6002 5930 +3 6106 5930 6194 +3 6106 6194 6196 +3 6194 6105 6196 +3 5929 6105 6194 +3 3370 3352 3295 +3 3295 3327 3249 +3 3249 3232 3190 +3 3190 3158 3127 +3 3127 3062 3080 +3 3080 3036 3005 +3 3005 2987 2933 +3 2933 2915 2854 +3 2854 2847 2760 +3 2656 2760 2755 +3 2656 2651 2551 +3 2551 2546 2468 +3 2468 2463 2402 +3 2402 2399 2469 +3 2469 2464 2552 +3 3739 3794 3862 +3 3862 3918 3962 +3 3861 3793 3738 +3 3738 3687 3605 +3 3605 3561 3515 +3 3233 3191 3159 +3 3159 3128 3063 +3 3063 3081 3037 +3 3037 3006 2988 +3 2934 2916 2988 +3 2855 2848 2916 +3 2848 2761 2756 +3 2552 2547 2657 +3 2464 2547 2552 +3 2399 2464 2469 +3 2463 2399 2402 +3 2546 2463 2468 +3 2651 2546 2551 +3 2755 2651 2656 +3 2847 2755 2760 +3 2915 2847 2854 +3 2987 2915 2933 +3 3036 2987 3005 +3 3062 3036 3080 +3 3158 3062 3127 +3 3232 3158 3190 +3 3327 3232 3249 +3 3352 3327 3295 +3 3403 3352 3370 +3 3403 3370 3442 +3 3403 3442 3474 +3 3442 3515 3474 +3 3515 3551 3474 +3 3561 3551 3515 +3 3687 3561 3605 +3 3793 3687 3738 +3 3917 3793 3861 +3 3917 3861 3961 +3 3917 3961 4045 +3 3962 4045 4047 +3 4045 3961 4047 +3 3918 4045 3962 +3 3794 3918 3862 +3 3688 3794 3739 +3 3688 3739 3606 +3 3688 3606 3562 +3 3606 3516 3562 +3 3516 3552 3562 +3 3475 3516 3443 +3 3552 3516 3475 +3 3404 3443 3371 +3 3475 3443 3404 +3 2756 2657 2652 +3 2657 2547 2652 +3 2761 2657 2756 +3 2855 2761 2848 +3 2934 2855 2916 +3 3006 2934 2988 +3 3081 3006 3037 +3 3128 3081 3063 +3 3191 3128 3159 +3 3250 3191 3233 +3 3250 3233 3328 +3 3250 3328 3296 +3 3328 3353 3296 +3 3353 3371 3296 +3 3404 3371 3353 +3 1664 1574 1580 +3 1580 1490 1496 +3 1496 1408 1414 +3 1100 1026 1106 +3 1026 1020 949 +3 468 462 384 +3 384 381 469 +3 565 469 463 +3 565 559 698 +3 2030 1891 1897 +3 1758 1764 1897 +3 1655 1664 1764 +3 1409 1491 1415 +3 1409 1363 1357 +3 1357 1295 1287 +3 1287 1233 1227 +3 1185 1179 1227 +3 1179 1107 1101 +3 1027 1021 1101 +3 1021 950 941 +3 698 692 834 +3 559 692 698 +3 463 559 565 +3 381 463 469 +3 462 381 384 +3 558 462 468 +3 697 558 564 +3 558 468 564 +3 691 558 697 +3 691 697 833 +3 691 833 827 +3 833 949 827 +3 949 940 827 +3 1020 940 949 +3 1100 1020 1026 +3 1178 1100 1106 +3 1178 1106 1184 +3 1178 1184 1226 +3 1294 1226 1232 +3 1226 1184 1232 +3 1286 1226 1294 +3 1286 1294 1356 +3 1414 1356 1362 +3 1356 1294 1362 +3 1408 1356 1414 +3 1490 1408 1496 +3 1574 1490 1580 +3 1655 1574 1664 +3 1758 1655 1764 +3 1891 1758 1897 +3 2024 1891 2030 +3 2024 2030 2126 +3 2024 2126 2120 +3 2215 2126 2218 +3 2120 2126 2215 +3 2031 2121 2127 +3 2121 2218 2127 +3 2215 2218 2121 +3 2025 2031 1898 +3 2121 2031 2025 +3 1892 1898 1765 +3 2025 1898 1892 +3 1759 1765 1665 +3 1892 1765 1759 +3 941 834 828 +3 834 692 828 +3 950 834 941 +3 1027 950 1021 +3 1107 1027 1101 +3 1185 1107 1179 +3 1233 1185 1227 +3 1295 1233 1287 +3 1363 1295 1357 +3 1415 1363 1409 +3 1497 1415 1491 +3 1497 1491 1575 +3 1497 1575 1581 +3 1575 1656 1581 +3 1656 1665 1581 +3 1759 1665 1656 +3 7157 7104 7105 +3 7105 7006 7007 +3 7007 6912 6913 +3 6913 6831 6832 +3 6569 6425 6568 +3 6708 6709 6569 +3 6999 6998 7097 +3 7097 7096 7149 +3 7149 7148 7218 +3 8200 8106 8107 +3 8107 7998 7999 +3 7999 7854 7855 +3 7710 7711 7855 +3 7711 7617 7618 +3 7538 7447 7446 +3 7355 7299 7298 +3 7299 7218 7298 +3 7218 7217 7298 +3 7148 7217 7218 +3 7096 7148 7149 +3 6998 7096 7097 +3 6904 6998 6999 +3 6904 6999 6905 +3 6904 6905 6821 +3 6709 6821 6822 +3 6821 6905 6822 +3 6708 6821 6709 +3 6568 6708 6569 +3 6424 6568 6425 +3 6424 6425 6312 +3 6244 6312 6313 +3 6312 6425 6313 +3 6243 6312 6244 +3 6243 6244 6321 +3 6243 6321 6320 +3 6321 6433 6320 +3 6433 6432 6320 +3 6576 6432 6433 +3 6576 6433 6577 +3 6576 6577 6716 +3 6832 6716 6717 +3 6716 6577 6717 +3 6831 6716 6832 +3 6912 6831 6913 +3 7006 6912 7007 +3 7104 7006 7105 +3 7156 7104 7157 +3 7156 7157 7228 +3 7156 7228 7227 +3 7228 7307 7227 +3 7307 7306 7227 +3 7362 7306 7307 +3 7362 7307 7363 +3 7362 7363 7454 +3 7363 7455 7454 +3 7455 7546 7454 +3 7618 7546 7547 +3 7546 7455 7547 +3 7617 7546 7618 +3 7710 7617 7711 +3 7854 7710 7855 +3 7998 7854 7999 +3 8106 7998 8107 +3 8199 8106 8200 +3 8199 8200 8098 +3 7991 8098 8099 +3 8098 8200 8099 +3 7990 8098 7991 +3 7846 7991 7847 +3 7990 7991 7846 +3 7702 7847 7703 +3 7846 7847 7702 +3 7446 7355 7354 +3 7355 7298 7354 +3 7447 7355 7446 +3 7539 7447 7538 +3 7539 7538 7607 +3 7539 7607 7608 +3 7607 7703 7608 +3 7702 7703 7607 +3 4833 4809 4728 +3 4728 4664 4584 +3 4584 4556 4440 +3 4440 4412 4332 +3 4439 4555 4583 +3 4583 4663 4727 +3 5690 5662 5593 +3 4727 4808 4832 +3 4663 4808 4727 +3 4555 4663 4583 +3 4411 4555 4439 +3 4411 4439 4331 +3 4411 4331 4256 +3 4332 4256 4252 +3 4256 4331 4252 +3 4412 4256 4332 +3 4556 4412 4440 +3 4664 4556 4584 +3 4809 4664 4728 +3 4902 4833 4914 +3 4809 4833 4902 +3 4994 4914 5006 +3 4902 4914 4994 +3 5150 5138 5094 +3 5138 5006 5094 +3 4994 5006 5138 +3 5282 5150 5213 +3 5138 5150 5282 +3 5346 5282 5294 +3 5282 5213 5294 +3 5426 5282 5346 +3 5426 5346 5438 +3 5426 5438 5518 +3 5593 5518 5530 +3 5518 5438 5530 +3 5662 5518 5593 +3 5806 5662 5690 +3 5806 5690 5834 +3 5806 5834 5950 +3 6082 5950 5978 +3 5950 5834 5978 +3 6182 5950 6082 +3 6182 6082 6178 +3 6182 6178 6081 +3 6182 6081 5949 +3 5833 5949 5977 +3 5949 6081 5977 +3 5805 5949 5833 +3 5805 5833 5689 +3 5805 5689 5661 +3 5689 5592 5661 +3 5592 5517 5661 +3 5437 5517 5529 +3 5517 5592 5529 +3 5425 5517 5437 +3 5425 5437 5345 +3 5425 5345 5281 +3 5345 5293 5281 +3 5293 5212 5281 +3 5212 5149 5281 +3 5149 5137 5281 +3 5005 5137 5093 +3 5137 5149 5093 +3 4993 5137 5005 +3 4993 5005 4913 +3 4993 4913 4901 +3 4913 4832 4901 +3 4832 4808 4901 +3 5592 5591 5529 +3 5529 5528 5437 +3 5211 5212 5293 +3 5212 5148 5149 +3 5149 5092 5093 +3 5005 5093 5004 +3 4913 5005 4912 +3 4832 4913 4831 +3 4832 4718 4719 +3 4574 4575 4719 +3 4431 4575 4430 +3 4431 4322 4323 +3 4243 4244 4323 +3 4567 4566 4711 +3 4711 4710 4822 +3 4822 4821 4905 +3 4905 4904 4997 +3 4997 4996 5085 +3 5085 5084 5141 +3 5141 5140 5202 +3 5202 5201 5285 +3 6170 6169 6073 +3 5680 5592 5681 +3 5285 5284 5337 +3 5201 5284 5285 +3 5140 5201 5202 +3 5084 5140 5141 +3 4996 5084 5085 +3 4904 4996 4997 +3 4821 4904 4905 +3 4710 4821 4822 +3 4566 4710 4711 +3 4422 4566 4567 +3 4422 4567 4423 +3 4422 4423 4314 +3 4244 4314 4315 +3 4314 4423 4315 +3 4243 4314 4244 +3 4322 4243 4323 +3 4430 4322 4431 +3 4574 4430 4575 +3 4718 4574 4719 +3 4831 4718 4832 +3 4912 4831 4913 +3 5004 4912 5005 +3 5092 5004 5093 +3 5148 5092 5149 +3 5211 5148 5212 +3 5292 5211 5293 +3 5292 5293 5345 +3 5292 5345 5344 +3 5345 5437 5344 +3 5437 5436 5344 +3 5528 5436 5437 +3 5591 5528 5529 +3 5680 5591 5592 +3 5824 5680 5681 +3 5824 5681 5825 +3 5824 5825 5968 +3 5825 5969 5968 +3 5969 6073 5968 +3 6073 6072 5968 +3 6169 6072 6073 +3 5961 6064 6065 +3 6064 6170 6065 +3 6169 6170 6064 +3 5960 5961 5817 +3 6064 5961 5960 +3 5816 5817 5673 +3 5960 5817 5816 +3 5672 5673 5582 +3 5816 5673 5672 +3 5428 5337 5336 +3 5337 5284 5336 +3 5429 5337 5428 +3 5429 5428 5520 +3 5429 5520 5521 +3 5520 5581 5521 +3 5581 5582 5521 +3 5672 5582 5581 +3 4423 4567 3704 +3 4085 4332 4252 +3 4332 4082 4440 +3 4440 3798 4584 +3 3835 4432 4576 +3 4424 3828 4568 +3 4712 4568 3705 +3 4712 3572 4823 +3 4823 3490 4704 +3 4704 3565 4560 +3 4238 4022 4307 +3 4307 3920 4415 +3 3558 4832 3497 +3 4719 3578 3497 +3 4575 3711 3578 +3 4323 3934 4431 +3 4026 3934 4323 +3 4026 4323 4244 +3 4026 4244 3927 +3 4244 4315 3927 +3 4315 4423 3927 +3 4423 3827 3927 +3 3704 3827 4423 +3 3571 3704 4567 +3 3571 4567 4711 +3 3571 4711 3489 +3 4703 3489 4822 +3 3489 4711 4822 +3 3564 3489 4703 +3 3564 4703 4559 +3 3564 4559 3697 +3 4559 4415 3697 +3 4415 3820 3697 +3 3920 3820 4415 +3 4022 3920 4307 +3 3921 4022 4238 +3 3921 4238 4308 +3 3921 4308 3821 +3 4308 4416 3821 +3 4416 4560 3821 +3 4560 3698 3821 +3 3565 3698 4560 +3 3490 3565 4704 +3 3572 3490 4823 +3 3705 3572 4712 +3 3828 3705 4568 +3 3928 3828 4424 +3 4245 3928 4316 +3 3928 4424 4316 +3 4027 3928 4245 +3 4027 4245 3935 +3 4432 3935 4324 +3 3935 4245 4324 +3 3835 3935 4432 +3 3712 3835 4576 +3 3712 4576 4720 +3 3712 4720 3579 +3 4720 4833 3579 +3 4833 3498 3579 +3 3559 3498 4833 +3 3559 4833 4728 +3 3559 4728 3665 +3 4728 4584 3665 +3 4584 3695 3665 +3 3798 3695 4584 +3 4082 3798 4440 +3 4085 4082 4332 +3 4087 4085 4252 +3 4084 4252 4331 +3 4087 4252 4084 +3 4081 4331 4439 +3 4084 4331 4081 +3 3711 4431 3834 +3 4431 3934 3834 +3 4575 4431 3711 +3 4719 4575 3578 +3 4832 4719 3497 +3 4727 4832 3558 +3 4727 3558 3664 +3 4727 3664 4583 +3 3664 3694 4583 +3 3694 3797 4583 +3 3797 4439 4583 +3 4081 4439 3797 +3 5818 6570 5962 +3 5962 6426 6066 +3 6066 6314 6171 +3 6074 6171 6245 +3 5826 6718 5682 +3 5834 6586 5978 +3 5978 6442 6082 +3 6082 6330 6178 +3 6178 6252 6081 +3 6058 6418 5954 +3 5954 6562 5810 +3 5810 6702 5666 +3 6569 5817 6425 +3 5961 6313 6425 +3 6313 6065 6244 +3 6321 6244 6170 +3 6073 6433 6321 +3 6577 6433 5969 +3 6577 5825 6717 +3 6717 5681 6832 +3 6081 6329 5977 +3 6252 6329 6081 +3 6330 6252 6178 +3 6442 6330 6082 +3 6586 6442 5978 +3 6726 6586 5834 +3 6726 5834 5690 +3 6726 5690 6833 +3 5682 6833 5593 +3 6833 5690 5593 +3 6718 6833 5682 +3 6578 6718 5826 +3 6578 5826 5970 +3 6578 5970 6434 +3 5970 6074 6434 +3 6074 6322 6434 +3 6245 6322 6074 +3 6314 6245 6171 +3 6426 6314 6066 +3 6570 6426 5962 +3 6710 6570 5818 +3 6710 5818 5674 +3 6710 5674 6823 +3 5666 6823 5583 +3 6823 5674 5583 +3 6702 6823 5666 +3 6562 6702 5810 +3 6418 6562 5954 +3 6306 6418 6058 +3 6306 6058 6164 +3 6306 6164 6238 +3 6305 6164 6057 +3 6238 6164 6305 +3 6417 6057 5953 +3 6305 6057 6417 +3 6561 5953 5809 +3 6417 5953 6561 +3 6701 5809 5665 +3 6561 5809 6701 +3 6585 5977 6441 +3 5977 6329 6441 +3 5833 5977 6585 +3 5833 6585 6725 +3 5833 6725 5689 +3 6725 6832 5689 +3 6832 5592 5689 +3 5681 5592 6832 +3 5825 5681 6717 +3 5969 5825 6577 +3 6073 5969 6433 +3 6170 6073 6321 +3 6065 6170 6244 +3 5961 6065 6313 +3 5817 5961 6425 +3 5673 5817 6569 +3 5673 6569 6709 +3 5673 6709 5582 +3 6709 6822 5582 +3 6822 5665 5582 +3 6701 5665 6822 +3 6403 6298 6301 +3 6298 6404 6301 +3 6404 6548 6301 +3 6660 6548 6516 +3 6548 6404 6516 +3 6692 6548 6660 +3 6692 6660 6800 +3 6692 6800 6892 +3 6952 6892 6885 +3 6892 6800 6885 +3 6984 6892 6952 +3 6984 6952 7046 +3 6984 7046 7082 +3 7196 7082 7144 +3 7082 7046 7144 +3 7288 7082 7196 +3 7288 7196 7281 +3 7288 7281 7346 +3 7288 7346 7438 +3 7494 7438 7402 +3 7438 7346 7402 +3 7534 7438 7494 +3 7534 7494 7586 +3 7534 7586 7678 +3 7790 7678 7671 +3 7678 7586 7671 +3 7826 7678 7790 +3 7826 7790 7934 +3 7826 7934 7978 +3 8186 7978 8078 +3 7978 7934 8078 +3 8255 7978 8186 +3 8255 8186 8252 +3 8255 8252 8185 +3 8255 8185 7977 +3 7933 7977 8077 +3 7977 8185 8077 +3 7825 7977 7933 +3 7825 7933 7789 +3 7825 7789 7677 +3 7585 7677 7670 +3 7677 7789 7670 +3 7533 7677 7585 +3 7533 7585 7493 +3 7533 7493 7437 +3 7345 7437 7401 +3 7437 7493 7401 +3 7287 7437 7345 +3 7287 7345 7280 +3 7287 7280 7195 +3 7287 7195 7081 +3 7045 7081 7143 +3 7081 7195 7143 +3 6983 7081 7045 +3 6983 7045 6951 +3 6983 6951 6891 +3 6799 6891 6884 +3 6891 6951 6884 +3 6691 6891 6799 +3 6691 6799 6659 +3 6691 6659 6547 +3 6659 6515 6547 +3 6515 6403 6547 +3 6403 6301 6547 +3 7670 7584 7585 +3 7585 7492 7493 +3 6951 7045 7044 +3 6951 6950 6884 +3 6884 6883 6793 +3 6653 6793 6792 +3 6653 6652 6509 +3 8179 8178 8071 +3 7783 7669 7670 +3 7487 7394 7486 +3 7136 7188 7189 +3 6875 6944 6876 +3 6875 6787 6786 +3 6786 6647 6646 +3 6391 6390 6503 +3 6291 6390 6391 +3 6291 6391 6292 +3 6291 6292 6397 +3 6291 6397 6396 +3 6397 6509 6396 +3 6509 6508 6396 +3 6652 6508 6509 +3 6792 6652 6653 +3 6883 6792 6793 +3 6950 6883 6884 +3 7044 6950 6951 +3 7142 7044 7045 +3 7142 7045 7143 +3 7142 7143 7195 +3 7142 7195 7194 +3 7195 7280 7194 +3 7280 7279 7194 +3 7344 7279 7280 +3 7344 7280 7345 +3 7344 7345 7400 +3 7493 7400 7401 +3 7400 7345 7401 +3 7492 7400 7493 +3 7584 7492 7585 +3 7669 7584 7670 +3 7782 7669 7783 +3 7782 7783 7927 +3 7782 7927 7926 +3 7927 8071 7926 +3 8071 8070 7926 +3 8178 8070 8071 +3 8245 8178 8179 +3 8173 8245 8246 +3 8245 8179 8246 +3 8172 8245 8173 +3 8172 8173 8065 +3 8172 8065 8064 +3 7920 8065 7921 +3 8064 8065 7920 +3 7776 7921 7777 +3 7920 7921 7776 +3 6646 6503 6502 +3 6503 6390 6502 +3 6647 6503 6646 +3 6787 6647 6786 +3 6876 6787 6875 +3 6945 6876 6944 +3 6945 6944 7038 +3 6945 7038 7039 +3 7038 7136 7039 +3 7136 7137 7039 +3 7189 7137 7136 +3 7272 7189 7188 +3 7272 7188 7271 +3 7272 7271 7338 +3 7272 7338 7339 +3 7338 7394 7339 +3 7394 7395 7339 +3 7487 7395 7394 +3 7579 7487 7486 +3 7579 7486 7578 +3 7579 7578 7662 +3 7578 7661 7662 +3 7661 7777 7662 +3 7776 7777 7661 +3 5276 5332 5420 +3 6229 6155 5943 +3 5275 5187 5079 +3 4549 4513 4405 +3 4657 4513 4549 +3 4657 4549 4697 +3 4657 4697 4801 +3 4697 4895 4801 +3 4895 4888 4801 +3 4951 4888 4895 +3 4951 4895 4987 +3 4951 4987 5043 +3 4987 5079 5043 +3 5079 5131 5043 +3 5187 5131 5079 +3 5268 5187 5275 +3 5268 5275 5331 +3 5275 5419 5331 +3 5419 5383 5331 +3 5475 5383 5419 +3 5475 5419 5511 +3 5475 5511 5567 +3 5511 5655 5567 +3 5655 5648 5567 +3 5763 5648 5655 +3 5763 5655 5799 +3 5763 5799 5907 +3 5799 5943 5907 +3 5943 6051 5907 +3 6155 6051 5943 +3 6226 6155 6229 +3 6226 6229 6156 +3 6229 5944 6156 +3 5944 6052 6156 +3 5908 6052 5944 +3 5908 5944 5800 +3 5908 5800 5764 +3 5800 5656 5764 +3 5656 5649 5764 +3 5568 5649 5656 +3 5568 5656 5512 +3 5568 5512 5476 +3 5512 5420 5476 +3 5420 5384 5476 +3 5332 5384 5420 +3 5269 5332 5276 +3 5269 5276 5188 +3 5276 5080 5188 +3 5080 5132 5188 +3 5044 5132 5080 +3 5044 5080 4988 +3 5044 4988 4952 +3 4988 4896 4952 +3 4896 4889 4952 +3 4802 4889 4896 +3 4802 4896 4698 +3 4802 4698 4658 +3 4698 4550 4658 +3 4550 4514 4658 +3 4406 4514 4550 +3 4406 4550 4303 +3 4406 4303 4300 +3 4303 4405 4300 +3 4549 4405 4303 +3 5648 5566 5567 +3 5567 5474 5475 +3 5475 5382 5383 +3 5043 5042 4951 +3 4888 4951 4950 +3 4887 4795 4888 +3 4795 4794 4651 +3 4651 4650 4507 +3 5750 5895 5751 +3 6039 5895 5894 +3 6149 6148 6045 +3 5757 5647 5648 +3 5468 5469 5376 +3 5180 5181 5124 +3 4944 4880 4879 +3 4879 4789 4788 +3 4788 4645 4644 +3 4393 4392 4501 +3 4293 4392 4393 +3 4293 4393 4294 +3 4293 4294 4399 +3 4293 4399 4398 +3 4399 4507 4398 +3 4507 4506 4398 +3 4650 4506 4507 +3 4794 4650 4651 +3 4887 4794 4795 +3 4950 4887 4888 +3 5042 4950 4951 +3 5130 5042 5043 +3 5130 5043 5131 +3 5130 5131 5187 +3 5130 5187 5186 +3 5187 5268 5186 +3 5268 5267 5186 +3 5330 5267 5268 +3 5383 5330 5331 +3 5330 5268 5331 +3 5382 5330 5383 +3 5474 5382 5475 +3 5566 5474 5567 +3 5647 5566 5648 +3 5756 5647 5757 +3 5756 5757 5901 +3 5756 5901 5900 +3 5901 6045 5900 +3 6045 6044 5900 +3 6148 6044 6045 +3 6219 6148 6149 +3 6219 6149 6220 +3 6219 6220 6143 +3 6219 6143 6142 +3 6143 6039 6142 +3 6039 6038 6142 +3 5894 6038 6039 +3 5750 5894 5895 +3 4644 4501 4500 +3 4501 4392 4500 +3 4645 4501 4644 +3 4789 4645 4788 +3 4880 4789 4879 +3 4945 4880 4944 +3 4945 4944 5036 +3 4945 5036 5037 +3 5036 5124 5037 +3 5124 5125 5037 +3 5181 5125 5124 +3 5260 5181 5180 +3 5260 5180 5259 +3 5260 5259 5324 +3 5260 5324 5325 +3 5324 5376 5325 +3 5376 5377 5325 +3 5469 5377 5376 +3 5561 5469 5468 +3 5561 5468 5560 +3 5561 5560 5640 +3 5560 5639 5640 +3 5639 5751 5640 +3 5750 5751 5639 +3 2432 2511 2429 +3 2432 2429 2512 +3 2432 2512 2614 +3 2698 2614 2594 +3 2614 2512 2594 +3 2731 2614 2698 +3 2731 2698 2802 +3 2731 2802 2884 +3 2955 2884 2879 +3 2884 2802 2879 +3 2982 2884 2955 +3 2982 2955 3027 +3 2982 3027 3059 +3 3149 3059 3102 +3 3059 3027 3102 +3 3220 3059 3149 +3 3220 3149 3215 +3 3220 3215 3271 +3 3220 3271 3348 +3 3392 3348 3317 +3 3348 3271 3317 +3 3424 3348 3392 +3 3424 3392 3464 +3 3424 3464 3548 +3 3656 3548 3542 +3 3548 3464 3542 +3 3684 3548 3656 +3 3684 3656 3789 +3 3684 3789 3817 +3 4012 3817 3912 +3 3817 3789 3912 +3 4079 3817 4012 +3 4079 4012 4076 +3 4079 4076 4011 +3 4079 4011 3816 +3 3788 3816 3911 +3 3816 4011 3911 +3 3683 3816 3788 +3 3683 3788 3655 +3 3683 3655 3547 +3 3463 3547 3541 +3 3547 3655 3541 +3 3423 3547 3463 +3 3423 3463 3391 +3 3423 3391 3347 +3 3270 3347 3316 +3 3347 3391 3316 +3 3219 3347 3270 +3 3219 3270 3214 +3 3219 3214 3148 +3 3219 3148 3058 +3 3026 3058 3101 +3 3058 3148 3101 +3 2981 3058 3026 +3 2981 3026 2954 +3 2981 2954 2883 +3 2801 2883 2878 +3 2883 2954 2878 +3 2730 2883 2801 +3 2730 2801 2697 +3 2730 2697 2613 +3 2697 2593 2613 +3 2593 2511 2613 +3 2511 2432 2613 +3 3774 3898 3775 +3 3383 3384 3308 +3 3262 3308 3309 +3 3205 3262 3263 +3 3205 3206 3140 +3 3140 3141 3093 +3 3093 3094 3018 +3 3018 3019 2946 +3 2946 2947 2869 +3 2497 2580 2581 +3 2497 2498 2420 +3 2420 2421 2505 +3 2505 2506 2587 +3 2587 2588 2691 +3 2692 2795 2691 +3 2795 2796 2877 +3 2877 2878 2953 +3 2953 2954 3025 +3 3147 3214 3213 +3 3213 3270 3269 +3 3269 3316 3315 +3 3390 3315 3391 +3 3462 3390 3463 +3 3462 3541 3540 +3 3540 3649 3648 +3 3648 3782 3781 +3 4004 3905 4005 +3 4004 4005 4068 +3 3998 4068 4069 +3 4068 4005 4069 +3 3997 4068 3998 +3 3997 3998 3898 +3 3997 3898 3897 +3 3898 3774 3897 +3 3641 3775 3642 +3 3774 3775 3641 +3 3781 3905 3904 +3 3905 4004 3904 +3 3782 3905 3781 +3 3649 3782 3648 +3 3541 3649 3540 +3 3463 3541 3462 +3 3391 3463 3390 +3 3316 3391 3315 +3 3270 3316 3269 +3 3214 3270 3213 +3 3148 3214 3147 +3 3148 3147 3100 +3 3148 3100 3101 +3 3100 3025 3101 +3 3025 3026 3101 +3 2954 3026 3025 +3 2878 2954 2953 +3 2796 2878 2877 +3 2692 2796 2795 +3 2588 2692 2691 +3 2506 2588 2587 +3 2421 2506 2505 +3 2498 2421 2420 +3 2581 2498 2497 +3 2685 2581 2580 +3 2685 2580 2684 +3 2685 2684 2788 +3 2685 2788 2789 +3 2788 2869 2789 +3 2869 2870 2789 +3 2947 2870 2869 +3 3019 2947 2946 +3 3094 3019 3018 +3 3141 3094 3093 +3 3206 3141 3140 +3 3263 3206 3205 +3 3309 3263 3262 +3 3384 3309 3308 +3 3456 3384 3383 +3 3456 3383 3455 +3 3456 3455 3533 +3 3455 3532 3533 +3 3532 3642 3533 +3 3641 3642 3532 +3 2084 2083 2188 +3 2084 2188 2186 +3 2080 2186 2185 +3 2186 2188 2185 +3 1952 2186 2080 +3 1859 1952 1951 +3 1952 2080 1951 +3 1816 1952 1859 +3 1816 1859 1815 +3 1816 1815 1702 +3 1559 1702 1694 +3 1702 1815 1694 +3 1560 1702 1559 +3 1560 1559 1522 +3 1560 1522 1472 +3 1394 1472 1471 +3 1472 1522 1471 +3 1340 1472 1394 +3 1340 1394 1339 +3 1340 1339 1257 +3 1340 1257 1209 +3 1257 1208 1209 +3 8554 8167 8558 +3 8588 8179 8594 +3 8623 8186 8619 +3 7663 8571 7778 +3 7778 8577 7922 +3 8589 8174 8583 +3 8247 8174 8589 +3 8247 8589 8180 +3 8589 8595 8180 +3 8595 8072 8180 +3 7928 8072 8595 +3 7928 8595 8601 +3 7928 8601 7784 +3 8601 8607 7784 +3 8607 7671 7784 +3 7790 7671 8607 +3 7790 8607 8613 +3 7790 8613 7934 +3 8613 8619 7934 +3 8619 8078 7934 +3 8186 8078 8619 +3 8252 8186 8623 +3 8252 8623 8185 +3 8623 8618 8185 +3 8618 8077 8185 +3 7933 8077 8618 +3 7933 8618 8612 +3 7933 8612 7789 +3 8612 8606 7789 +3 8606 7670 7789 +3 7783 7670 8606 +3 7783 8606 8600 +3 7783 8600 7927 +3 8600 8594 7927 +3 8594 8071 7927 +3 8179 8071 8594 +3 8246 8179 8588 +3 8246 8588 8173 +3 8588 8582 8173 +3 8582 8065 8173 +3 7921 8065 8582 +3 7921 8582 8576 +3 7921 8576 7777 +3 8576 8570 7777 +3 8570 7662 7777 +3 7771 7662 8570 +3 7771 8570 8564 +3 7771 8564 7915 +3 8564 8558 7915 +3 8558 8059 7915 +3 8167 8059 8558 +3 8241 8167 8554 +3 8241 8554 8168 +3 8554 8559 8168 +3 8559 8060 8168 +3 7916 8559 8565 +3 8060 8559 7916 +3 7772 8565 8571 +3 7916 8565 7772 +3 7922 8583 8066 +3 8583 8174 8066 +3 8577 8583 7922 +3 8571 8577 7778 +3 7772 8571 7663 +3 3906 4652 3783 +3 3783 4796 3650 +3 3650 4889 3542 +3 3788 3911 4657 +3 3541 4795 3649 +3 3649 4651 3782 +3 4069 4005 4399 +3 3998 4069 4294 +3 3998 4393 3898 +3 3891 4495 3991 +3 3892 4496 3769 +3 3769 4640 3636 +3 3533 4880 3635 +3 4789 4880 3533 +3 4789 3533 3642 +3 4789 3642 4645 +3 3642 3775 4645 +3 3775 3898 4645 +3 3898 4501 4645 +3 4393 4501 3898 +3 4294 4393 3998 +3 4399 4294 4069 +3 4507 4399 4005 +3 3782 4507 3905 +3 4507 4005 3905 +3 4651 4507 3782 +3 4795 4651 3649 +3 4888 4795 3541 +3 4888 3541 4801 +3 3788 4801 3655 +3 4801 3541 3655 +3 4657 4801 3788 +3 4513 4657 3911 +3 4513 3911 4405 +3 4076 4405 4011 +3 4405 3911 4011 +3 4300 4405 4076 +3 4300 4076 4012 +3 4300 4012 4406 +3 4012 3912 4406 +3 3912 4514 4406 +3 4658 4514 3912 +3 4658 3912 3789 +3 4658 3789 4802 +3 3542 4802 3656 +3 4802 3789 3656 +3 4889 4802 3542 +3 4796 4889 3650 +3 4652 4796 3783 +3 4508 4652 3906 +3 4508 3906 4400 +3 3906 4006 4400 +3 4006 4070 4400 +3 4070 4295 4400 +3 4394 4295 4070 +3 4394 4070 3999 +3 4394 3999 4502 +3 3999 3899 4502 +3 3899 3776 4502 +3 3776 4646 4502 +3 4790 4646 3776 +3 4790 3776 3643 +3 4790 3643 4881 +3 3643 3534 4881 +3 3534 3636 4881 +3 3636 4784 4881 +3 4640 4784 3636 +3 4496 4640 3769 +3 4388 4496 3892 +3 4388 3892 3992 +3 4388 3992 4064 +3 4388 4064 4289 +3 4064 3991 4289 +3 3991 4387 4289 +3 4495 4387 3991 +3 4639 4495 3891 +3 4639 3891 3768 +3 4639 3768 4783 +3 3768 3635 4783 +3 3635 4880 4783 +3 5641 6877 5752 +3 5752 6788 5896 +3 5896 6648 6040 +3 6040 6504 6144 +3 6144 6392 6221 +3 6221 6293 6150 +3 6398 6046 6150 +3 6046 6510 5902 +3 5902 6654 5758 +3 5758 6794 5649 +3 5764 5649 6885 +3 6052 6404 6156 +3 6156 6298 6226 +3 6137 6033 6385 +3 6137 6385 6215 +3 6138 6215 6287 +3 6138 6386 6034 +3 6498 5890 6034 +3 5890 6642 5746 +3 6782 5641 5746 +3 6503 6039 6391 +3 6391 6143 6292 +3 6509 5901 6653 +3 6653 5757 6793 +3 6793 5648 6884 +3 5907 6659 5763 +3 6515 6659 5907 +3 6515 5907 6051 +3 6515 6051 6403 +3 6226 6403 6155 +3 6403 6051 6155 +3 6298 6403 6226 +3 6404 6298 6156 +3 6516 6404 6052 +3 6516 6052 6660 +3 6052 5908 6660 +3 5908 5764 6660 +3 5764 6800 6660 +3 6885 6800 5764 +3 6794 6885 5649 +3 6654 6794 5758 +3 6510 6654 5902 +3 6398 6510 6046 +3 6293 6398 6150 +3 6392 6293 6221 +3 6504 6392 6144 +3 6648 6504 6040 +3 6788 6648 5896 +3 6877 6788 5752 +3 6782 6877 5641 +3 6642 6782 5746 +3 6498 6642 5890 +3 6386 6498 6034 +3 6287 6386 6138 +3 6385 6287 6215 +3 6497 6033 5889 +3 6385 6033 6497 +3 6641 5889 5745 +3 6497 5889 6641 +3 6781 5745 5640 +3 6641 5745 6781 +3 6884 5763 6799 +3 5763 6659 6799 +3 5648 5763 6884 +3 5757 5648 6793 +3 5901 5757 6653 +3 6045 5901 6509 +3 6045 6509 6397 +3 6045 6397 6149 +3 6397 6292 6149 +3 6292 6220 6149 +3 6143 6220 6292 +3 6039 6143 6391 +3 5895 6039 6503 +3 5895 6503 6647 +3 5895 6647 5751 +3 6647 6787 5751 +3 6787 6876 5751 +3 6876 5640 5751 +3 6781 5640 6876 +3 7579 7481 7487 +3 7189 7183 7137 +3 7137 7131 7039 +3 7039 7033 6945 +3 6945 6939 6876 +3 6876 6866 6781 +3 6781 6775 6641 +3 6641 6635 6497 +3 6497 6491 6385 +3 6385 6379 6287 +3 6283 6386 6287 +3 6386 6380 6498 +3 6498 6492 6642 +3 6946 6940 7040 +3 7040 7034 7138 +3 7132 7190 7138 +3 7772 7910 7916 +3 8241 8237 8167 +3 7915 7765 7771 +3 7396 7390 7482 +3 7340 7273 7263 +3 7273 7190 7263 +3 7190 7184 7263 +3 7132 7184 7190 +3 7034 7132 7138 +3 6940 7034 7040 +3 6867 6940 6946 +3 6867 6946 6877 +3 6867 6877 6782 +3 6867 6782 6776 +3 6782 6642 6776 +3 6642 6636 6776 +3 6492 6636 6642 +3 6380 6492 6498 +3 6283 6380 6386 +3 6379 6283 6287 +3 6491 6379 6385 +3 6635 6491 6497 +3 6775 6635 6641 +3 6866 6775 6781 +3 6939 6866 6876 +3 7033 6939 6945 +3 7131 7033 7039 +3 7183 7131 7137 +3 7262 7183 7189 +3 7262 7189 7272 +3 7262 7272 7333 +3 7272 7339 7333 +3 7339 7389 7333 +3 7487 7389 7395 +3 7389 7339 7395 +3 7481 7389 7487 +3 7573 7481 7579 +3 7573 7579 7652 +3 7771 7652 7662 +3 7652 7579 7662 +3 7765 7652 7771 +3 7909 7765 7915 +3 7909 7915 8059 +3 7909 8059 8053 +3 8059 8167 8053 +3 8167 8161 8053 +3 8237 8161 8167 +3 8162 8237 8241 +3 8162 8241 8168 +3 8162 8168 8060 +3 8162 8060 8054 +3 8060 7916 8054 +3 7916 7910 8054 +3 7766 7772 7663 +3 7910 7772 7766 +3 7390 7340 7334 +3 7340 7263 7334 +3 7396 7340 7390 +3 7488 7396 7482 +3 7488 7482 7574 +3 7488 7574 7580 +3 7574 7653 7580 +3 7653 7663 7580 +3 7766 7663 7653 +3 7572 7573 7652 +3 7573 7480 7481 +3 7033 7032 6939 +3 6939 6938 6866 +3 6866 6865 6767 +3 6767 6766 6627 +3 6627 6626 6483 +3 7893 7749 7748 +3 7893 7892 8037 +3 8153 8152 8045 +3 7651 7652 7757 +3 7473 7380 7472 +3 7122 7174 7175 +3 6856 6855 6930 +3 6855 6759 6758 +3 6758 6619 6618 +3 6363 6362 6475 +3 6275 6362 6363 +3 6275 6363 6276 +3 6275 6276 6371 +3 6275 6371 6370 +3 6371 6483 6370 +3 6483 6482 6370 +3 6626 6482 6483 +3 6766 6626 6627 +3 6865 6766 6767 +3 6938 6865 6866 +3 7032 6938 6939 +3 7130 7032 7033 +3 7130 7033 7131 +3 7130 7131 7183 +3 7130 7183 7182 +3 7183 7262 7182 +3 7262 7261 7182 +3 7332 7261 7262 +3 7332 7262 7333 +3 7332 7333 7388 +3 7481 7388 7389 +3 7388 7333 7389 +3 7480 7388 7481 +3 7572 7480 7573 +3 7651 7572 7652 +3 7756 7651 7757 +3 7756 7757 7901 +3 7756 7901 7900 +3 7901 8045 7900 +3 8045 8044 7900 +3 8152 8044 8045 +3 8229 8152 8153 +3 8229 8153 8230 +3 8229 8230 8145 +3 8229 8145 8144 +3 8145 8037 8144 +3 8037 8036 8144 +3 7892 8036 8037 +3 7748 7892 7893 +3 6618 6475 6474 +3 6475 6362 6474 +3 6619 6475 6618 +3 6759 6619 6758 +3 6856 6759 6855 +3 6931 6856 6930 +3 6931 6930 7024 +3 6931 7024 7025 +3 7024 7122 7025 +3 7122 7123 7025 +3 7175 7123 7122 +3 7252 7175 7174 +3 7252 7174 7251 +3 7252 7251 7324 +3 7252 7324 7325 +3 7324 7380 7325 +3 7380 7381 7325 +3 7473 7381 7380 +3 7565 7473 7472 +3 7565 7472 7564 +3 7565 7564 7642 +3 7564 7641 7642 +3 7641 7749 7642 +3 7748 7749 7641 +3 5640 5555 5561 +3 5463 5469 5561 +3 5469 5371 5377 +3 5037 5031 4945 +3 4945 4939 4880 +3 4880 4870 4783 +3 4783 4777 4639 +3 4639 4633 4495 +3 4495 4489 4387 +3 4387 4381 4289 +3 4388 4289 4285 +3 4388 4382 4496 +3 4490 4640 4496 +3 4946 4940 5038 +3 5038 5032 5126 +3 5120 5182 5126 +3 5182 5176 5261 +3 5641 5740 5746 +3 5740 5890 5746 +3 5890 5884 6034 +3 5889 5739 5745 +3 5745 5630 5640 +3 5464 5378 5372 +3 5261 5251 5326 +3 5176 5251 5261 +3 5120 5176 5182 +3 5032 5120 5126 +3 4940 5032 5038 +3 4871 4940 4946 +3 4871 4946 4881 +3 4871 4881 4784 +3 4871 4784 4778 +3 4784 4640 4778 +3 4640 4634 4778 +3 4490 4634 4640 +3 4382 4490 4496 +3 4285 4382 4388 +3 4381 4285 4289 +3 4489 4381 4387 +3 4633 4489 4495 +3 4777 4633 4639 +3 4870 4777 4783 +3 4939 4870 4880 +3 5031 4939 4945 +3 5119 5031 5037 +3 5119 5037 5125 +3 5119 5125 5175 +3 5260 5175 5181 +3 5175 5125 5181 +3 5250 5175 5260 +3 5250 5260 5319 +3 5377 5319 5325 +3 5319 5260 5325 +3 5371 5319 5377 +3 5463 5371 5469 +3 5555 5463 5561 +3 5630 5555 5640 +3 5739 5630 5745 +3 5883 5739 5889 +3 5883 5889 6033 +3 5883 6033 6027 +3 6033 6137 6027 +3 6137 6131 6027 +3 6211 6131 6137 +3 6211 6137 6215 +3 6211 6215 6132 +3 6215 6138 6132 +3 6138 6034 6132 +3 6034 6028 6132 +3 5884 6028 6034 +3 5740 5884 5890 +3 5372 5326 5320 +3 5326 5251 5320 +3 5378 5326 5372 +3 5470 5378 5464 +3 5470 5464 5556 +3 5470 5556 5562 +3 5556 5631 5562 +3 5631 5641 5562 +3 5740 5641 5631 +3 5554 5555 5630 +3 5555 5462 5463 +3 5370 5371 5463 +3 5031 5030 4939 +3 4870 4939 4938 +3 4870 4869 4769 +3 4769 4768 4625 +3 4625 4624 4481 +3 4481 4480 4373 +3 4278 4373 4372 +3 4278 4277 4365 +3 4365 4364 4473 +3 4472 4617 4473 +3 4860 4930 4931 +3 5111 5110 5167 +3 5166 5240 5167 +3 5311 5240 5239 +3 5311 5310 5363 +3 5362 5455 5363 +3 5455 5454 5547 +3 5547 5546 5620 +3 5867 5723 5722 +3 6011 5867 5866 +3 5731 5875 5730 +3 5629 5630 5731 +3 5620 5619 5723 +3 5546 5619 5620 +3 5454 5546 5547 +3 5362 5454 5455 +3 5310 5362 5363 +3 5239 5310 5311 +3 5166 5239 5240 +3 5110 5166 5167 +3 5022 5110 5111 +3 4931 5022 5023 +3 5022 5111 5023 +3 4930 5022 4931 +3 4859 4930 4860 +3 4859 4860 4761 +3 4859 4761 4760 +3 4761 4617 4760 +3 4617 4616 4760 +3 4472 4616 4617 +3 4364 4472 4473 +3 4277 4364 4365 +3 4372 4277 4278 +3 4480 4372 4373 +3 4624 4480 4481 +3 4768 4624 4625 +3 4869 4768 4769 +3 4938 4869 4870 +3 5030 4938 4939 +3 5118 5030 5031 +3 5118 5031 5119 +3 5118 5119 5175 +3 5118 5175 5174 +3 5175 5250 5174 +3 5250 5249 5174 +3 5318 5249 5250 +3 5371 5318 5319 +3 5318 5250 5319 +3 5370 5318 5371 +3 5462 5370 5463 +3 5554 5462 5555 +3 5629 5554 5630 +3 5730 5629 5731 +3 5874 5730 5875 +3 5874 5875 6019 +3 5874 6019 6018 +3 6019 6123 6018 +3 6123 6122 6018 +3 6203 6122 6123 +3 6203 6123 6204 +3 6203 6204 6114 +3 6204 6115 6114 +3 6115 6011 6114 +3 6011 6010 6114 +3 5866 6010 6011 +3 5722 5866 5867 +3 5619 5722 5723 +3 3450 3456 3533 +3 3456 3378 3384 +3 3384 3303 3309 +3 3141 3135 3094 +3 3094 3088 3019 +3 3019 3013 2947 +3 2947 2941 2870 +3 2678 2617 2574 +3 2574 2485 2491 +3 3095 3109 3142 +3 3156 3207 3142 +3 3207 3228 3264 +3 3264 3278 3310 +3 3310 3325 3385 +3 3385 3399 3457 +3 3471 3534 3457 +3 3892 3885 3992 +3 3992 3985 4064 +3 4064 4060 3991 +3 3768 3628 3635 +3 3635 3525 3533 +3 2815 2783 2711 +3 2711 2679 2628 +3 2575 2570 2628 +3 2570 2492 2438 +3 2491 2435 2416 +3 2485 2435 2491 +3 2617 2485 2574 +3 2701 2617 2678 +3 2701 2678 2782 +3 2701 2782 2805 +3 2782 2870 2805 +3 2870 2863 2805 +3 2941 2863 2870 +3 3013 2941 2947 +3 3088 3013 3019 +3 3135 3088 3094 +3 3199 3135 3141 +3 3199 3141 3206 +3 3199 3206 3257 +3 3309 3257 3263 +3 3257 3206 3263 +3 3303 3257 3309 +3 3378 3303 3384 +3 3450 3378 3456 +3 3525 3450 3533 +3 3628 3525 3635 +3 3761 3628 3768 +3 3761 3768 3891 +3 3761 3891 3884 +3 3891 3991 3884 +3 3991 3984 3884 +3 4060 3984 3991 +3 3985 4060 4064 +3 3885 3985 3992 +3 3762 3885 3892 +3 3762 3892 3769 +3 3762 3769 3629 +3 3769 3636 3629 +3 3636 3534 3629 +3 3534 3526 3629 +3 3471 3526 3534 +3 3399 3471 3457 +3 3325 3399 3385 +3 3278 3325 3310 +3 3228 3278 3264 +3 3156 3228 3207 +3 3109 3156 3142 +3 3034 3109 3095 +3 3034 3095 3020 +3 3034 3020 2962 +3 2438 2416 2413 +3 2416 2435 2413 +3 2492 2416 2438 +3 2575 2492 2570 +3 2679 2575 2628 +3 2783 2679 2711 +3 2871 2783 2815 +3 2871 2815 2908 +3 2871 2908 2948 +3 2908 2962 2948 +3 2962 3020 2948 +3 2901 2962 2908 +3 3614 3746 3747 +3 3516 3517 3443 +3 3443 3444 3371 +3 3371 3372 3296 +3 3296 3297 3250 +3 3250 3251 3191 +3 3191 3192 3128 +3 3129 3081 3128 +3 3081 3082 3006 +3 3006 3007 2934 +3 2934 2935 2855 +3 2855 2856 2766 +3 2767 2662 2766 +3 2662 2663 2557 +3 2474 2557 2558 +3 2475 2406 2474 +3 2406 2407 2479 +3 2479 2480 2562 +3 2667 2562 2563 +3 2667 2668 2771 +3 2862 2771 2772 +3 3012 3088 3087 +3 3134 3087 3135 +3 3134 3199 3198 +3 3257 3256 3198 +3 3256 3303 3302 +3 3302 3378 3377 +3 3377 3450 3449 +3 3449 3525 3524 +3 3524 3621 3620 +3 3620 3754 3753 +3 3753 3877 3876 +3 4053 4052 3977 +3 3969 4052 4053 +3 3969 4053 3970 +3 3969 3970 3870 +3 3969 3870 3869 +3 3870 3747 3869 +3 3747 3746 3869 +3 3613 3614 3517 +3 3746 3614 3613 +3 3876 3977 3976 +3 3977 4052 3976 +3 3877 3977 3876 +3 3754 3877 3753 +3 3621 3754 3620 +3 3525 3621 3524 +3 3450 3525 3449 +3 3378 3450 3377 +3 3303 3378 3302 +3 3257 3303 3256 +3 3199 3257 3198 +3 3135 3199 3134 +3 3088 3135 3087 +3 3013 3088 3012 +3 3013 3012 2940 +3 3013 2940 2941 +3 2940 2862 2941 +3 2862 2863 2941 +3 2772 2863 2862 +3 2668 2772 2771 +3 2563 2668 2667 +3 2480 2563 2562 +3 2407 2480 2479 +3 2475 2407 2406 +3 2558 2475 2474 +3 2663 2558 2557 +3 2767 2663 2662 +3 2856 2767 2766 +3 2935 2856 2855 +3 3007 2935 2934 +3 3082 3007 3006 +3 3129 3082 3081 +3 3192 3129 3128 +3 3251 3192 3191 +3 3297 3251 3250 +3 3372 3297 3296 +3 3444 3372 3371 +3 3517 3444 3443 +3 3613 3517 3516 +3 1428 1510 1422 +3 1314 1304 1246 +3 1246 1240 1198 +3 1198 1192 1120 +3 1120 1114 1040 +3 1040 1034 969 +3 723 649 590 +3 419 399 495 +3 399 429 496 +3 496 523 591 +3 591 650 724 +3 1429 1469 1511 +3 2177 2233 2154 +3 2233 2189 2153 +3 2153 2146 2056 +3 2056 1959 1923 +3 1923 1853 1790 +3 1790 1721 1684 +3 590 488 495 +3 649 488 590 +3 752 649 723 +3 752 723 859 +3 752 859 888 +3 859 969 888 +3 969 960 888 +3 1034 960 969 +3 1114 1034 1040 +3 1192 1114 1120 +3 1240 1192 1198 +3 1304 1240 1246 +3 1370 1304 1314 +3 1428 1370 1376 +3 1370 1314 1376 +3 1422 1370 1428 +3 1504 1422 1510 +3 1504 1510 1594 +3 1504 1594 1588 +3 1594 1684 1588 +3 1684 1675 1588 +3 1721 1675 1684 +3 1853 1721 1790 +3 1959 1853 1923 +3 2146 1959 2056 +3 2189 2146 2153 +3 2177 2189 2233 +3 2082 2177 2154 +3 2082 2154 2057 +3 2082 2057 1958 +3 2057 1924 1958 +3 1924 1947 1958 +3 1846 1947 1924 +3 1846 1924 1791 +3 1846 1791 1716 +3 1791 1685 1716 +3 1685 1709 1716 +3 1605 1709 1685 +3 1605 1685 1595 +3 1605 1595 1558 +3 1595 1511 1558 +3 1511 1520 1558 +3 1469 1520 1511 +3 1387 1469 1429 +3 1387 1429 1377 +3 1387 1377 1308 +3 1247 1308 1315 +3 1308 1377 1315 +3 1212 1308 1247 +3 1212 1247 1199 +3 1212 1199 1134 +3 1199 1121 1134 +3 1121 1086 1134 +3 1050 1086 1121 +3 1050 1121 1041 +3 1050 1041 1003 +3 1041 970 1003 +3 970 900 1003 +3 892 900 970 +3 892 970 860 +3 892 860 758 +3 860 724 758 +3 724 658 758 +3 650 658 724 +3 523 650 591 +3 429 523 496 +3 419 429 399 +3 488 419 495 +3 1588 1675 1674 +3 2225 2224 2140 +3 1415 1416 1363 +3 1295 1363 1364 +3 1233 1295 1296 +3 1185 1233 1234 +3 1107 1185 1186 +3 1027 1107 1108 +3 950 1027 1028 +3 950 951 840 +3 840 841 704 +3 704 705 571 +3 572 475 571 +3 475 476 390 +3 481 390 391 +3 481 482 577 +3 710 577 578 +3 959 1034 1033 +3 1033 1114 1113 +3 1192 1191 1113 +3 1191 1240 1239 +3 1239 1304 1303 +3 1369 1303 1370 +3 1369 1422 1421 +3 1588 1587 1504 +3 1674 1587 1588 +3 1777 1674 1675 +3 1777 1675 1778 +3 1777 1778 1910 +3 2044 1910 1911 +3 1910 1778 1911 +3 2043 1910 2044 +3 2043 2044 2140 +3 2043 2140 2139 +3 2140 2224 2139 +3 2038 2133 2134 +3 2133 2225 2134 +3 2224 2225 2133 +3 2037 2038 1905 +3 2133 2038 2037 +3 1904 1905 1772 +3 2037 1905 1904 +3 1771 1772 1666 +3 1904 1772 1771 +3 1421 1504 1503 +3 1504 1587 1503 +3 1422 1504 1421 +3 1370 1422 1369 +3 1304 1370 1303 +3 1240 1304 1239 +3 1192 1240 1191 +3 1114 1192 1113 +3 1034 1114 1033 +3 960 1034 959 +3 960 959 846 +3 960 846 847 +3 846 710 847 +3 710 711 847 +3 578 711 710 +3 482 578 577 +3 391 482 481 +3 476 391 390 +3 572 476 475 +3 705 572 571 +3 841 705 704 +3 951 841 840 +3 1028 951 950 +3 1108 1028 1027 +3 1186 1108 1107 +3 1234 1186 1185 +3 1296 1234 1233 +3 1364 1296 1295 +3 1416 1364 1363 +3 1498 1416 1415 +3 1498 1415 1497 +3 1498 1497 1582 +3 1497 1581 1582 +3 1581 1665 1582 +3 1665 1666 1582 +3 1771 1666 1665 +3 8474 7742 8466 +3 8458 8138 8451 +3 8457 7885 8465 +3 8465 7741 8473 +3 8497 8153 8505 +3 8543 8162 8538 +3 7643 8474 7750 +3 7750 8482 7894 +3 8498 8146 8490 +3 8231 8146 8498 +3 8231 8498 8154 +3 8498 8506 8154 +3 8506 8046 8154 +3 7902 8046 8506 +3 7902 8506 8514 +3 7902 8514 7758 +3 8514 8522 7758 +3 8522 7653 7758 +3 7766 7653 8522 +3 7766 8522 8530 +3 7766 8530 7910 +3 8530 8538 7910 +3 8538 8054 7910 +3 8162 8054 8538 +3 8237 8162 8543 +3 8237 8543 8161 +3 8543 8537 8161 +3 8537 8053 8161 +3 7909 8053 8537 +3 7909 8537 8529 +3 7909 8529 7765 +3 8529 8521 7765 +3 8521 7652 7765 +3 7757 7652 8521 +3 7757 8521 8513 +3 7757 8513 7901 +3 8513 8505 7901 +3 8505 8045 7901 +3 8153 8045 8505 +3 8230 8153 8497 +3 8230 8497 8145 +3 8497 8489 8145 +3 8489 8037 8145 +3 7893 8037 8489 +3 7893 8489 8481 +3 7893 8481 7749 +3 8481 8473 7749 +3 8473 7642 7749 +3 7741 7642 8473 +3 7885 7741 8465 +3 8029 7885 8457 +3 8029 8457 8137 +3 8457 8451 8137 +3 8451 8223 8137 +3 8138 8223 8451 +3 8030 8138 8458 +3 8030 8458 7886 +3 8458 8466 7886 +3 8466 7742 7886 +3 7894 8490 8038 +3 8490 8146 8038 +3 8482 8490 7894 +3 8474 8482 7750 +3 7742 8474 7643 +3 237 649 229 +3 752 221 229 +3 208 711 202 +3 200 476 193 +3 181 951 174 +3 652 520 160 +3 652 160 167 +3 652 167 754 +3 167 174 754 +3 174 890 754 +3 951 890 174 +3 841 951 181 +3 841 181 187 +3 841 187 705 +3 187 193 705 +3 193 572 705 +3 476 572 193 +3 391 476 200 +3 391 200 482 +3 200 202 482 +3 202 578 482 +3 711 578 202 +3 847 711 208 +3 847 208 214 +3 847 214 960 +3 214 221 960 +3 221 888 960 +3 752 888 221 +3 649 752 229 +3 488 649 237 +3 1959 2617 1853 +3 1853 2701 1721 +3 1721 2805 1675 +3 1911 2563 2044 +3 2134 2475 2038 +3 2038 2558 1905 +3 1905 2663 1772 +3 1772 2767 1666 +3 1666 2856 1720 +3 1720 2807 1852 +3 1852 2703 1956 +3 1956 2619 2089 +3 2619 2514 2089 +3 2703 2619 1956 +3 2807 2703 1852 +3 2856 2807 1720 +3 2767 2856 1666 +3 2663 2767 1772 +3 2558 2663 1905 +3 2475 2558 2038 +3 2407 2475 2134 +3 2407 2134 2225 +3 2407 2225 2480 +3 2044 2480 2140 +3 2480 2225 2140 +3 2563 2480 2044 +3 2668 2563 1911 +3 2668 1911 1778 +3 2668 1778 2772 +3 1778 1675 2772 +3 1675 2863 2772 +3 2805 2863 1675 +3 2701 2805 1721 +3 2617 2701 1853 +3 2485 2617 1959 +3 2485 1959 2146 +3 3748 4618 3871 +3 3755 4770 3622 +3 3622 4871 3526 +3 3526 4778 3629 +3 3629 4634 3762 +3 3762 4490 3885 +3 3885 4382 3985 +3 3985 4285 4060 +3 4060 4381 3984 +3 4489 3884 3984 +3 3884 4633 3761 +3 3977 4373 4053 +3 4617 3614 3747 +3 3614 4761 3517 +3 3963 3863 4465 +3 3963 4357 4048 +3 4048 4271 3964 +3 3964 4358 3864 +3 3864 4466 3741 +3 3741 4610 3608 +3 3517 4860 3607 +3 4761 4860 3517 +3 4617 4761 3614 +3 4473 4617 3747 +3 4473 3747 3870 +3 4473 3870 3970 +3 4473 3970 4365 +3 3970 4053 4365 +3 4053 4278 4365 +3 4373 4278 4053 +3 4481 4373 3977 +3 3754 4481 3877 +3 4481 3977 3877 +3 4625 4481 3754 +3 4625 3754 3621 +3 4625 3621 4769 +3 3621 3525 4769 +3 3525 4870 4769 +3 4777 4870 3525 +3 3761 4777 3628 +3 4777 3525 3628 +3 4633 4777 3761 +3 4489 4633 3884 +3 4381 4489 3984 +3 4285 4381 4060 +3 4382 4285 3985 +3 4490 4382 3885 +3 4634 4490 3762 +3 4778 4634 3629 +3 4871 4778 3526 +3 4770 4871 3622 +3 4626 4770 3755 +3 4626 3755 3878 +3 4626 3878 4482 +3 3878 3978 4482 +3 3978 4374 4482 +3 4279 4374 3978 +3 4279 3978 4054 +3 4279 4054 3971 +3 4279 3971 4366 +3 3971 3871 4366 +3 3871 4474 4366 +3 4618 4474 3871 +3 4762 4618 3748 +3 4762 3748 3615 +3 4762 3615 4861 +3 3615 3518 4861 +3 3518 3608 4861 +3 3608 4754 4861 +3 4610 4754 3608 +3 4466 4610 3741 +3 4358 4466 3864 +3 4271 4358 3964 +3 4357 4271 4048 +3 4465 4357 3963 +3 4609 4465 3863 +3 4609 3863 3740 +3 4609 3740 4753 +3 3740 3607 4753 +3 3607 4860 4753 +3 6857 5724 5621 +3 5724 6760 5868 +3 6620 6012 5868 +3 6205 6372 6124 +3 6124 6484 6020 +3 6020 6628 5876 +3 5876 6768 5732 +3 5732 6867 5631 +3 5631 6776 5740 +3 5884 5740 6636 +3 5884 6492 6028 +3 6132 6028 6380 +3 6132 6283 6211 +3 6211 6379 6131 +3 6131 6491 6027 +3 5620 6751 5715 +3 6108 6356 6004 +3 6004 6468 5860 +3 5860 6612 5716 +3 5716 6752 5621 +3 5620 6759 6856 +3 6759 5723 6619 +3 6619 5867 6475 +3 6475 6011 6363 +3 6363 6115 6276 +3 6627 6483 5875 +3 6627 5731 6767 +3 6866 6767 5630 +3 6027 6635 5883 +3 6635 5739 5883 +3 6491 6635 6027 +3 6379 6491 6131 +3 6283 6379 6211 +3 6380 6283 6132 +3 6492 6380 6028 +3 6636 6492 5884 +3 6776 6636 5740 +3 6867 6776 5631 +3 6768 6867 5732 +3 6628 6768 5876 +3 6484 6628 6020 +3 6372 6484 6124 +3 6277 6372 6205 +3 6277 6205 6116 +3 6277 6116 6364 +3 6116 6012 6364 +3 6012 6476 6364 +3 6620 6476 6012 +3 6760 6620 5868 +3 6857 6760 5724 +3 6752 6857 5621 +3 6612 6752 5716 +3 6468 6612 5860 +3 6356 6468 6004 +3 6269 6356 6108 +3 6269 6108 6197 +3 6269 6197 6355 +3 6003 6355 6107 +3 6355 6197 6107 +3 6467 6355 6003 +3 6467 6003 5859 +3 6467 5859 6611 +3 5859 5715 6611 +3 5715 6751 6611 +3 6866 5739 6775 +3 5739 6635 6775 +3 5630 5739 6866 +3 5731 5630 6767 +3 5875 5731 6627 +3 6019 5875 6483 +3 6019 6483 6371 +3 6019 6371 6123 +3 6371 6276 6123 +3 6276 6204 6123 +3 6115 6204 6276 +3 6011 6115 6363 +3 5867 6011 6475 +3 5723 5867 6619 +3 5620 5723 6759 +3 6751 5620 6856 +3 7473 7465 7381 +3 7381 7373 7325 +3 7252 7325 7317 +3 7175 7252 7242 +3 7175 7167 7123 +3 7123 7115 7025 +3 7017 6931 7025 +3 6931 6923 6856 +3 6856 6846 6751 +3 6743 6611 6751 +3 6603 6467 6611 +3 6355 6467 6459 +3 6355 6347 6269 +3 6269 6265 6356 +3 6468 6356 6348 +3 6460 6612 6468 +3 6752 6612 6604 +3 6752 6744 6857 +3 6857 6847 6932 +3 6924 7026 6932 +3 7124 7026 7018 +3 7382 7326 7318 +3 7886 7742 7734 +3 8223 8217 8137 +3 7885 7733 7741 +3 7382 7374 7474 +3 7318 7374 7382 +3 7243 7318 7326 +3 7243 7326 7253 +3 7243 7253 7168 +3 7253 7176 7168 +3 7176 7124 7168 +3 7124 7116 7168 +3 7018 7116 7124 +3 6924 7018 7026 +3 6847 6924 6932 +3 6744 6847 6857 +3 6604 6744 6752 +3 6460 6604 6612 +3 6348 6460 6468 +3 6265 6348 6356 +3 6347 6265 6269 +3 6459 6347 6355 +3 6603 6459 6467 +3 6743 6603 6611 +3 6846 6743 6751 +3 6923 6846 6856 +3 7017 6923 6931 +3 7115 7017 7025 +3 7167 7115 7123 +3 7242 7167 7175 +3 7317 7242 7252 +3 7373 7317 7325 +3 7465 7373 7381 +3 7557 7465 7473 +3 7557 7473 7565 +3 7557 7565 7632 +3 7741 7632 7642 +3 7632 7565 7642 +3 7733 7632 7741 +3 7877 7733 7885 +3 7877 7885 8029 +3 7877 8029 8021 +3 8029 8137 8021 +3 8137 8129 8021 +3 8217 8129 8137 +3 8130 8217 8223 +3 8130 8223 8138 +3 8130 8138 8030 +3 8130 8030 8022 +3 8030 7886 8022 +3 7886 7878 8022 +3 7734 7878 7886 +3 7558 7474 7466 +3 7474 7374 7466 +3 7566 7474 7558 +3 7566 7558 7643 +3 7558 7633 7643 +3 7633 7742 7643 +3 7734 7742 7633 +3 7235 7163 7065 +3 6259 6343 6533 +3 7317 7423 7241 +3 7963 8017 8125 +3 7873 8017 7963 +3 7873 7963 7811 +3 7873 7811 7729 +3 7811 7631 7729 +3 7631 7632 7729 +3 7557 7632 7631 +3 7557 7631 7519 +3 7557 7519 7465 +3 7519 7423 7465 +3 7423 7373 7465 +3 7317 7373 7423 +3 7242 7317 7241 +3 7242 7241 7167 +3 7241 7067 7167 +3 7067 7115 7167 +3 7017 7115 7067 +3 7017 7067 6969 +3 7017 6969 6923 +3 6969 6845 6923 +3 6845 6846 6923 +3 6739 6846 6845 +3 6739 6845 6677 +3 6739 6677 6599 +3 6677 6533 6599 +3 6533 6455 6599 +3 6343 6455 6533 +3 6260 6343 6259 +3 6260 6259 6339 +3 6259 6531 6339 +3 6531 6451 6339 +3 6595 6451 6531 +3 6595 6531 6675 +3 6595 6675 6735 +3 6675 6839 6735 +3 6839 6840 6735 +3 6919 6840 6839 +3 6919 6839 6967 +3 6919 6967 7013 +3 6967 7065 7013 +3 7065 7111 7013 +3 7163 7111 7065 +3 7236 7163 7235 +3 7236 7235 7313 +3 7235 7421 7313 +3 7421 7369 7313 +3 7461 7369 7421 +3 7461 7421 7517 +3 7461 7517 7553 +3 7517 7625 7553 +3 7625 7626 7553 +3 7725 7626 7625 +3 7725 7625 7809 +3 7725 7809 7869 +3 7809 7961 7869 +3 7961 8013 7869 +3 8121 8013 7961 +3 8121 7961 8211 +3 8121 8211 8212 +3 8211 8125 8212 +3 7963 8125 8211 +3 5620 5539 5547 +3 5447 5455 5547 +3 5111 5103 5023 +3 5023 5015 4931 +3 4931 4923 4860 +3 4860 4846 4753 +3 4609 4753 4745 +3 4465 4609 4601 +3 4465 4457 4357 +3 4357 4349 4271 +3 4271 4265 4358 +3 4358 4350 4466 +3 4466 4458 4610 +3 4610 4602 4754 +3 4754 4746 4861 +3 4847 4932 4861 +3 4932 4924 5024 +3 5112 5024 5016 +3 5364 5312 5304 +3 5860 5996 6004 +3 5707 5715 5859 +3 5606 5620 5715 +3 5548 5607 5621 +3 5540 5607 5548 +3 5540 5548 5456 +3 5540 5456 5448 +3 5456 5364 5448 +3 5364 5356 5448 +3 5304 5356 5364 +3 5227 5304 5312 +3 5227 5312 5241 +3 5227 5241 5168 +3 5227 5168 5160 +3 5168 5112 5160 +3 5112 5104 5160 +3 5016 5104 5112 +3 4924 5016 5024 +3 4847 4924 4932 +3 4746 4847 4861 +3 4602 4746 4754 +3 4458 4602 4610 +3 4350 4458 4466 +3 4265 4350 4358 +3 4349 4265 4271 +3 4457 4349 4357 +3 4601 4457 4465 +3 4745 4601 4609 +3 4846 4745 4753 +3 4923 4846 4860 +3 5015 4923 4931 +3 5103 5015 5023 +3 5159 5103 5111 +3 5240 5159 5167 +3 5159 5111 5167 +3 5226 5159 5240 +3 5226 5240 5303 +3 5240 5311 5303 +3 5311 5355 5303 +3 5455 5355 5363 +3 5355 5311 5363 +3 5447 5355 5455 +3 5539 5447 5547 +3 5606 5539 5620 +3 5707 5606 5715 +3 5851 5707 5859 +3 5851 5859 6003 +3 5851 6003 5995 +3 6003 6107 5995 +3 6107 6099 5995 +3 6191 6099 6107 +3 6191 6107 6197 +3 6191 6197 6100 +3 6004 6100 6108 +3 6100 6197 6108 +3 5996 6100 6004 +3 5852 5996 5860 +3 5852 5860 5716 +3 5852 5716 5708 +3 5716 5621 5708 +3 5621 5607 5708 +3 5015 4969 4923 +3 4737 4593 4677 +3 6091 6185 6186 +3 6185 6095 6186 +3 5923 6185 6091 +3 5843 5923 5987 +3 5923 6091 5987 +3 5779 5923 5843 +3 5779 5843 5699 +3 5779 5699 5599 +3 5535 5599 5600 +3 5599 5699 5600 +3 5491 5599 5535 +3 5491 5535 5443 +3 5491 5443 5399 +3 5299 5399 5351 +3 5399 5443 5351 +3 5219 5399 5299 +3 5219 5299 5220 +3 5219 5220 5155 +3 5219 5155 5059 +3 5011 5059 5099 +3 5059 5155 5099 +3 4967 5059 5011 +3 4967 5011 4919 +3 4967 4919 4839 +3 4737 4839 4840 +3 4839 4919 4840 +3 4677 4839 4737 +3 4529 4677 4593 +3 4529 4593 4449 +3 4529 4449 4341 +3 4529 4341 4259 +3 4345 4259 4260 +3 4259 4341 4260 +3 4531 4259 4345 +3 4531 4345 4453 +3 4531 4453 4597 +3 4531 4597 4679 +3 4597 4741 4679 +3 4741 4845 4679 +3 4923 4845 4846 +3 4845 4741 4846 +3 4969 4845 4923 +3 5061 4969 5015 +3 5061 5015 5103 +3 5061 5103 5159 +3 5061 5159 5225 +3 5159 5226 5225 +3 5226 5303 5225 +3 5303 5401 5225 +3 5447 5401 5355 +3 5401 5303 5355 +3 5493 5401 5447 +3 5493 5447 5539 +3 5493 5539 5605 +3 5703 5605 5606 +3 5605 5539 5606 +3 5781 5605 5703 +3 5781 5703 5847 +3 5781 5847 5925 +3 6095 5925 5991 +3 5925 5847 5991 +3 6185 5925 6095 +3 3032 3033 2961 +3 3033 3107 3108 +3 3108 3154 3155 +3 3226 3227 3155 +3 3227 3276 3277 +3 3323 3324 3277 +3 3398 3324 3397 +3 3398 3469 3470 +3 3470 3510 3518 +3 3518 3601 3608 +3 3608 3734 3741 +3 3741 3857 3864 +3 3600 3607 3740 +3 3607 3509 3517 +3 3444 3517 3438 +3 3444 3366 3372 +3 3007 3001 2935 +3 2856 2935 2929 +3 2856 2849 2807 +3 2807 2806 2703 +3 2703 2702 2619 +3 2619 2618 2514 +3 2618 2513 2514 +3 2702 2618 2619 +3 2806 2702 2703 +3 2849 2806 2807 +3 2929 2849 2856 +3 3001 2929 2935 +3 3076 3001 3007 +3 3076 3007 3082 +3 3076 3082 3129 +3 3076 3129 3123 +3 3129 3192 3123 +3 3192 3185 3123 +3 3245 3185 3192 +3 3245 3192 3251 +3 3245 3251 3291 +3 3372 3291 3297 +3 3291 3251 3297 +3 3366 3291 3372 +3 3438 3366 3444 +3 3509 3438 3517 +3 3600 3509 3607 +3 3733 3600 3740 +3 3733 3740 3863 +3 3733 3863 3856 +3 3863 3963 3856 +3 3963 3956 3856 +3 4042 3956 3963 +3 4042 3963 4048 +3 4042 4048 3957 +3 3864 3957 3964 +3 3957 4048 3964 +3 3857 3957 3864 +3 3734 3857 3741 +3 3601 3734 3608 +3 3510 3601 3518 +3 3469 3510 3470 +3 3397 3469 3398 +3 3323 3397 3324 +3 3276 3323 3277 +3 3226 3276 3227 +3 3154 3226 3155 +3 3107 3154 3108 +3 3032 3107 3033 +3 2960 3032 2961 +3 2960 2961 2897 +3 2961 2899 2897 +3 8408 8122 8404 +3 8385 8117 8387 +3 8407 8125 8411 +3 8447 8130 8438 +3 7726 7627 8396 +3 7726 8396 8400 +3 7726 8400 7870 +3 8400 8404 7870 +3 8404 8014 7870 +3 8122 8014 8404 +3 8213 8122 8408 +3 8213 8408 8126 +3 8408 8412 8126 +3 8412 8018 8126 +3 7874 8018 8412 +3 7874 8412 8416 +3 7874 8416 7730 +3 8416 8420 7730 +3 8420 7633 7730 +3 7734 7633 8420 +3 7734 8420 8430 +3 7734 8430 7878 +3 8430 8438 7878 +3 8438 8022 7878 +3 8130 8022 8438 +3 8217 8130 8447 +3 8217 8447 8129 +3 8447 8437 8129 +3 8437 8021 8129 +3 7877 8021 8437 +3 7877 8437 8429 +3 7877 8429 7733 +3 8429 8419 7733 +3 8419 7632 7733 +3 7729 7632 8419 +3 7729 8419 8415 +3 7729 8415 7873 +3 8415 8411 7873 +3 8411 8017 7873 +3 8125 8017 8411 +3 8212 8125 8407 +3 8212 8407 8121 +3 8407 8403 8121 +3 8403 8013 8121 +3 7869 8013 8403 +3 7869 8403 8399 +3 7869 8399 7725 +3 8399 8395 7725 +3 8395 7626 7725 +3 7721 7626 8395 +3 7721 8395 8391 +3 7721 8391 7865 +3 8391 8387 7865 +3 8387 8009 7865 +3 8117 8009 8387 +3 8209 8117 8385 +3 8209 8385 8118 +3 8385 8388 8118 +3 8388 8010 8118 +3 7866 8010 8388 +3 7866 8388 8392 +3 7866 8392 7722 +3 8392 8396 7722 +3 8396 7627 7722 +3 817 101 681 +3 107 548 681 +3 519 651 153 +3 146 651 753 +3 153 651 146 +3 942 139 889 +3 139 753 889 +3 146 753 139 +3 131 942 823 +3 139 942 131 +3 125 823 687 +3 131 823 125 +3 458 119 554 +3 119 687 554 +3 125 687 119 +3 113 458 377 +3 119 458 113 +3 548 113 452 +3 113 377 452 +3 107 113 548 +3 101 107 681 +3 94 101 817 +3 94 817 933 +3 94 933 904 +3 2750 1748 2646 +3 2646 1881 2541 +3 2541 2014 2458 +3 2460 2020 2543 +3 2543 1887 2648 +3 1754 2752 2648 +3 2752 1657 2849 +3 2849 1719 2806 +3 2806 1851 2702 +3 1955 2618 2702 +3 2618 2088 2513 +3 1955 2088 2618 +3 1851 1955 2702 +3 1719 1851 2806 +3 1657 1719 2849 +3 1754 1657 2752 +3 1887 1754 2648 +3 2020 1887 2543 +3 2116 2020 2460 +3 2116 2460 2211 +3 2460 2395 2211 +3 2395 2458 2211 +3 2458 2110 2211 +3 2014 2110 2458 +3 1881 2014 2541 +3 1748 1881 2646 +3 1648 1748 2750 +3 1648 2750 2842 +3 1648 2842 2821 +3 1648 2821 1708 +3 3505 4841 3593 +3 4738 3726 3593 +3 3726 4594 3849 +3 3853 3953 4346 +3 4602 3734 3601 +3 4458 3857 3734 +3 4350 3957 3857 +3 3957 4265 4042 +3 3956 4042 4349 +3 3956 4457 3856 +3 3856 4601 3733 +3 3733 4745 3600 +3 4846 3509 3600 +3 4741 3596 3509 +3 3596 4597 3729 +3 3592 3725 4593 +3 3844 4445 3944 +3 3944 4337 4035 +3 4035 4257 3945 +3 3945 4338 3845 +3 3845 4446 3722 +3 3722 4590 3589 +3 3589 4734 3505 +3 3592 4737 3504 +3 4737 4840 3504 +3 4593 4737 3592 +3 4449 4593 3725 +3 4449 3725 3848 +3 4449 3848 4341 +3 3848 3948 4341 +3 3948 4037 4341 +3 4037 4260 4341 +3 4345 4260 4037 +3 4345 4037 3952 +3 4345 3952 4453 +3 3729 4453 3852 +3 4453 3952 3852 +3 4597 4453 3729 +3 4741 4597 3596 +3 4846 4741 3509 +3 4745 4846 3600 +3 4601 4745 3733 +3 4457 4601 3856 +3 4349 4457 3956 +3 4265 4349 4042 +3 4350 4265 3957 +3 4458 4350 3857 +3 4602 4458 3734 +3 4746 4602 3601 +3 4746 3601 4847 +3 3597 4847 3510 +3 4847 3601 3510 +3 4742 4847 3597 +3 4742 3597 3730 +3 4742 3730 4598 +3 3730 3853 4598 +3 3853 4454 4598 +3 4346 4454 3853 +3 4261 4346 3953 +3 4261 3953 4038 +3 4261 4038 3949 +3 4261 3949 4342 +3 3949 3849 4342 +3 3849 4450 4342 +3 4594 4450 3849 +3 4738 4594 3726 +3 4841 4738 3593 +3 4734 4841 3505 +3 4590 4734 3589 +3 4446 4590 3722 +3 4338 4446 3845 +3 4257 4338 3945 +3 4337 4257 4035 +3 4445 4337 3944 +3 4589 4445 3844 +3 4589 3844 3721 +3 4589 3721 4733 +3 3721 3588 4733 +3 3588 3504 4733 +3 3504 4840 4733 +3 5601 6841 5700 +3 5700 6736 5844 +3 5844 6596 5988 +3 5988 6452 6092 +3 5984 6448 5840 +3 6595 5843 6451 +3 6451 5987 6339 +3 6339 6091 6260 +3 6260 6186 6343 +3 6343 6095 6455 +3 6455 5991 6599 +3 6599 5847 6739 +3 6743 5851 6603 +3 5995 6459 6603 +3 6459 6099 6347 +3 6347 6191 6265 +3 6265 6100 6348 +3 6460 6348 5996 +3 6604 6460 5852 +3 5708 6744 6604 +3 6744 5607 6847 +3 6847 5704 6740 +3 6740 5848 6600 +3 6600 5992 6456 +3 6456 6096 6344 +3 6092 6340 6187 +3 6452 6340 6092 +3 6596 6452 5988 +3 6736 6596 5844 +3 6841 6736 5700 +3 6732 6841 5601 +3 6732 5601 5696 +3 6732 5696 6592 +3 5696 5840 6592 +3 5840 6448 6592 +3 6336 5984 6088 +3 6448 5984 6336 +3 6257 6088 6183 +3 6336 6088 6257 +3 6335 6183 6087 +3 6257 6183 6335 +3 6447 6087 5983 +3 6335 6087 6447 +3 6591 5983 5839 +3 6447 5983 6591 +3 6731 5839 5695 +3 6591 5839 6731 +3 6344 6187 6261 +3 6187 6340 6261 +3 6096 6187 6344 +3 5992 6096 6456 +3 5848 5992 6600 +3 5704 5848 6740 +3 5607 5704 6847 +3 5708 5607 6744 +3 5852 5708 6604 +3 5996 5852 6460 +3 6100 5996 6348 +3 6191 6100 6265 +3 6099 6191 6347 +3 5995 6099 6459 +3 5851 5995 6603 +3 5707 5851 6743 +3 5707 6743 6846 +3 5707 6846 5606 +3 6846 6739 5606 +3 6739 5703 5606 +3 5847 5703 6739 +3 5991 5847 6599 +3 6095 5991 6455 +3 6186 6095 6343 +3 6091 6186 6260 +3 5987 6091 6339 +3 5843 5987 6451 +3 5699 5843 6595 +3 5699 6595 6735 +3 5699 6735 5600 +3 6735 6840 5600 +3 6840 5695 5600 +3 6731 5695 6840 +3 7549 7553 7626 +3 7553 7457 7461 +3 7461 7365 7369 +3 7369 7309 7313 +3 7313 7230 7236 +3 7236 7159 7163 +3 7163 7107 7111 +3 7111 7009 7013 +3 7013 6915 6919 +3 6591 6587 6447 +3 6447 6443 6335 +3 6335 6331 6257 +3 6336 6257 6253 +3 6336 6332 6448 +3 7014 7010 7112 +3 7722 7718 7866 +3 8114 8118 8010 +3 8118 8207 8209 +3 8209 8113 8117 +3 8005 8009 8117 +3 8009 7861 7865 +3 7865 7717 7721 +3 7721 7620 7626 +3 7550 7462 7458 +3 7458 7370 7366 +3 7366 7314 7310 +3 7310 7237 7231 +3 7112 7108 7164 +3 7010 7108 7112 +3 6916 7010 7014 +3 6916 7014 6920 +3 6916 6920 6835 +3 6732 6835 6841 +3 6835 6920 6841 +3 6728 6835 6732 +3 6728 6732 6592 +3 6728 6592 6588 +3 6592 6448 6588 +3 6448 6444 6588 +3 6332 6444 6448 +3 6253 6332 6336 +3 6331 6253 6257 +3 6443 6331 6335 +3 6587 6443 6447 +3 6727 6587 6591 +3 6727 6591 6731 +3 6727 6731 6834 +3 6919 6834 6840 +3 6834 6731 6840 +3 6915 6834 6919 +3 7009 6915 7013 +3 7107 7009 7111 +3 7159 7107 7163 +3 7230 7159 7236 +3 7309 7230 7313 +3 7365 7309 7369 +3 7457 7365 7461 +3 7549 7457 7553 +3 7620 7549 7626 +3 7717 7620 7721 +3 7861 7717 7865 +3 8005 7861 8009 +3 8113 8005 8117 +3 8207 8113 8209 +3 8114 8207 8118 +3 8006 8114 8010 +3 8006 8010 7862 +3 8010 7866 7862 +3 7866 7718 7862 +3 7231 7164 7160 +3 7164 7108 7160 +3 7237 7164 7231 +3 7314 7237 7310 +3 7370 7314 7366 +3 7462 7370 7458 +3 7554 7462 7550 +3 7554 7550 7621 +3 7554 7621 7627 +3 7621 7722 7627 +3 7718 7722 7621 +3 7364 7365 7457 +3 7309 7365 7308 +3 7309 7229 7230 +3 7230 7158 7159 +3 7705 7848 7849 +3 7992 7993 7849 +3 7356 7448 7449 +3 7300 7356 7357 +3 7300 7301 7219 +3 7219 7220 7150 +3 7151 7098 7150 +3 7099 7000 7098 +3 7001 6906 7000 +3 6907 6823 6906 +3 6710 6823 6824 +3 6710 6711 6570 +3 6570 6571 6426 +3 6427 6314 6426 +3 6578 6435 6579 +3 6578 6579 6719 +3 6578 6719 6718 +3 6719 6834 6718 +3 6834 6833 6718 +3 6914 6833 6834 +3 6914 6834 6915 +3 6914 6915 7008 +3 6915 7009 7008 +3 7009 7106 7008 +3 7159 7106 7107 +3 7106 7009 7107 +3 7158 7106 7159 +3 7229 7158 7230 +3 7308 7229 7309 +3 7364 7308 7365 +3 7456 7364 7457 +3 7456 7457 7549 +3 7456 7549 7548 +3 7549 7620 7548 +3 7620 7619 7548 +3 7712 7619 7620 +3 7857 7712 7713 +3 7712 7620 7713 +3 7856 7712 7857 +3 7856 7857 8001 +3 7856 8001 8000 +3 8001 8109 8000 +3 8109 8108 8000 +3 8201 8108 8109 +3 8201 8109 8202 +3 8201 8202 8100 +3 7993 8100 8101 +3 8100 8202 8101 +3 7992 8100 7993 +3 7848 7992 7849 +3 7704 7848 7705 +3 6322 6435 6434 +3 6435 6578 6434 +3 6323 6435 6322 +3 6323 6322 6246 +3 6322 6245 6246 +3 6245 6314 6246 +3 6314 6315 6246 +3 6427 6315 6314 +3 6571 6427 6426 +3 6711 6571 6570 +3 6824 6711 6710 +3 6907 6824 6823 +3 7001 6907 6906 +3 7099 7001 7000 +3 7151 7099 7098 +3 7220 7151 7150 +3 7301 7220 7219 +3 7357 7301 7300 +3 7449 7357 7356 +3 7541 7449 7448 +3 7541 7448 7540 +3 7541 7540 7610 +3 7540 7609 7610 +3 7609 7705 7610 +3 7704 7705 7609 +3 5351 5347 5299 +3 5299 5295 5220 +3 5220 5214 5155 +3 5155 5151 5099 +3 5099 5095 5011 +3 5007 4919 5011 +3 4919 4915 4840 +3 4589 4441 4445 +3 4337 4445 4333 +3 4337 4253 4257 +3 4257 4334 4338 +3 4734 4730 4841 +3 4841 4835 4920 +3 4920 4916 5012 +3 5012 5008 5100 +3 5100 5096 5156 +3 5352 5300 5348 +3 5352 5440 5444 +3 5536 5444 5532 +3 5980 5984 5840 +3 5984 6084 6088 +3 6088 6179 6183 +3 6183 6083 6087 +3 6087 5979 5983 +3 5839 5983 5835 +3 5839 5691 5695 +3 5695 5594 5600 +3 5536 5595 5601 +3 5532 5595 5536 +3 5440 5532 5444 +3 5348 5440 5352 +3 5296 5348 5300 +3 5296 5300 5221 +3 5296 5221 5215 +3 5221 5156 5215 +3 5156 5152 5215 +3 5096 5152 5156 +3 5008 5096 5100 +3 4916 5008 5012 +3 4835 4916 4920 +3 4730 4835 4841 +3 4586 4730 4734 +3 4586 4734 4590 +3 4586 4590 4442 +3 4338 4442 4446 +3 4442 4590 4446 +3 4334 4442 4338 +3 4253 4334 4257 +3 4333 4253 4337 +3 4441 4333 4445 +3 4585 4441 4589 +3 4585 4589 4733 +3 4585 4733 4729 +3 4733 4840 4729 +3 4840 4834 4729 +3 4915 4834 4840 +3 5007 4915 4919 +3 5095 5007 5011 +3 5151 5095 5099 +3 5214 5151 5155 +3 5295 5214 5220 +3 5347 5295 5299 +3 5439 5347 5351 +3 5439 5351 5443 +3 5439 5443 5531 +3 5600 5531 5535 +3 5531 5443 5535 +3 5594 5531 5600 +3 5691 5594 5695 +3 5835 5691 5839 +3 5979 5835 5983 +3 6083 5979 6087 +3 6179 6083 6183 +3 6084 6179 6088 +3 5980 6084 5984 +3 5836 5980 5840 +3 5836 5840 5696 +3 5836 5696 5692 +3 5696 5601 5692 +3 5601 5595 5692 +3 5531 5594 5593 +3 5347 5294 5295 +3 5295 5213 5214 +3 5151 5214 5150 +3 5151 5094 5095 +3 5095 5006 5007 +3 5007 4914 4915 +3 4833 4834 4915 +3 4834 4720 4721 +3 4721 4576 4577 +3 4569 4568 4713 +3 4713 4712 4824 +3 4907 4824 4823 +3 4999 4907 4906 +3 4999 4998 5087 +3 5087 5086 5143 +3 5204 5143 5142 +3 5287 5204 5203 +3 5287 5286 5339 +3 5431 5339 5338 +3 5675 5584 5674 +3 5818 5819 5675 +3 5962 5963 5819 +3 6172 6171 6075 +3 5683 5682 5594 +3 5583 5584 5523 +3 5583 5523 5522 +3 5523 5431 5522 +3 5431 5430 5522 +3 5338 5430 5431 +3 5286 5338 5339 +3 5203 5286 5287 +3 5142 5203 5204 +3 5086 5142 5143 +3 4998 5086 5087 +3 4906 4998 4999 +3 4823 4906 4907 +3 4712 4823 4824 +3 4568 4712 4713 +3 4424 4568 4569 +3 4424 4569 4425 +3 4424 4425 4317 +3 4424 4317 4316 +3 4317 4246 4316 +3 4246 4245 4316 +3 4324 4245 4246 +3 4324 4246 4325 +3 4324 4325 4432 +3 4577 4432 4433 +3 4432 4325 4433 +3 4576 4432 4577 +3 4720 4576 4721 +3 4833 4720 4834 +3 4914 4833 4915 +3 5006 4914 5007 +3 5094 5006 5095 +3 5150 5094 5151 +3 5213 5150 5214 +3 5294 5213 5295 +3 5346 5294 5347 +3 5346 5347 5439 +3 5346 5439 5438 +3 5439 5531 5438 +3 5531 5530 5438 +3 5593 5530 5531 +3 5682 5593 5594 +3 5826 5682 5683 +3 5826 5683 5827 +3 5826 5827 5971 +3 5826 5971 5970 +3 5971 6075 5970 +3 6075 6074 5970 +3 6171 6074 6075 +3 6066 6171 6172 +3 5963 6066 6067 +3 6066 6172 6067 +3 5962 6066 5963 +3 5818 5962 5819 +3 5674 5818 5675 +3 5583 5674 5584 +3 2821 2842 2886 +3 2811 2834 2803 +3 2834 2833 2921 +3 2921 2920 2993 +3 2993 2992 3068 +3 3068 3067 3115 +3 3430 3490 3491 +3 3572 3573 3491 +3 3573 3705 3706 +3 3713 3712 3580 +3 3580 3579 3499 +3 2956 2887 2888 +3 2984 2956 3028 +3 2887 2956 2984 +3 3039 3028 3103 +3 2984 3028 3039 +3 3161 3103 3150 +3 3039 3103 3161 +3 3272 3161 3222 +3 3161 3150 3222 +3 3318 3161 3272 +3 3393 3318 3319 +3 3318 3272 3319 +3 3401 3318 3393 +3 3401 3393 3465 +3 3401 3465 3479 +3 3465 3499 3479 +3 3499 3498 3479 +3 3498 3478 3479 +3 3579 3498 3499 +3 3712 3579 3580 +3 3835 3712 3713 +3 3835 3713 3836 +3 3835 3836 3936 +3 3835 3936 3935 +3 3936 4028 3935 +3 4028 4027 3935 +3 3928 4027 4028 +3 3928 4028 3929 +3 3928 3929 3828 +3 3706 3828 3829 +3 3828 3929 3829 +3 3705 3828 3706 +3 3572 3705 3573 +3 3490 3572 3491 +3 3429 3490 3430 +3 3429 3430 3358 +3 3429 3358 3357 +3 3358 3283 3357 +3 3283 3282 3357 +3 3236 3282 3283 +3 3236 3283 3237 +3 3236 3237 3173 +3 3237 3174 3173 +3 3174 3115 3173 +3 3115 3114 3173 +3 3067 3114 3115 +3 2992 3067 3068 +3 2920 2992 2993 +3 2833 2920 2921 +3 2811 2833 2834 +3 2707 2811 2803 +3 2707 2803 2699 +3 2707 2699 2624 +3 2440 2439 2519 +3 2440 2519 2615 +3 2519 2624 2615 +3 2624 2699 2615 +3 2518 2624 2519 +3 904 933 991 +3 8308 8094 8301 +3 8307 7841 8315 +3 8315 7697 8323 +3 8349 8109 8357 +3 8383 8114 8380 +3 8324 7706 7611 +3 7706 8332 7850 +3 8350 8102 8340 +3 8203 8102 8350 +3 8203 8350 8110 +3 8350 8358 8110 +3 8358 8002 8110 +3 7858 8002 8358 +3 7858 8358 8368 +3 7858 8368 7714 +3 8368 8372 7714 +3 8372 7621 7714 +3 7718 7621 8372 +3 7718 8372 8376 +3 7718 8376 7862 +3 8376 8380 7862 +3 8380 8006 7862 +3 8114 8006 8380 +3 8207 8114 8383 +3 8207 8383 8113 +3 8383 8379 8113 +3 8379 8005 8113 +3 7861 8005 8379 +3 7861 8379 8375 +3 7861 8375 7717 +3 8375 8371 7717 +3 8371 7620 7717 +3 7713 7620 8371 +3 7713 8371 8367 +3 7713 8367 7857 +3 8367 8357 7857 +3 8357 8001 7857 +3 8109 8001 8357 +3 8202 8109 8349 +3 8202 8349 8101 +3 8349 8339 8101 +3 8339 7993 8101 +3 7849 7993 8339 +3 7849 8339 8331 +3 7849 8331 7705 +3 8331 8323 7705 +3 8323 7610 7705 +3 7697 7610 8323 +3 7841 7697 8315 +3 7985 7841 8307 +3 7985 8307 8093 +3 8307 8301 8093 +3 8301 8195 8093 +3 8094 8195 8301 +3 7986 8094 8308 +3 7842 8308 8316 +3 7986 8308 7842 +3 7698 8316 8324 +3 7842 8316 7698 +3 7850 8340 7994 +3 8340 8102 7994 +3 8332 8340 7850 +3 8324 8332 7706 +3 7698 8324 7611 +3 50 647 42 +3 42 750 34 +3 18 663 10 +3 4 435 11 +3 27 920 35 +3 648 426 51 +3 648 51 43 +3 648 43 751 +3 43 35 751 +3 35 887 751 +3 920 887 35 +3 800 920 27 +3 800 27 19 +3 800 19 664 +3 19 11 664 +3 11 531 664 +3 435 531 11 +3 363 435 4 +3 363 4 434 +3 4 10 434 +3 10 530 434 +3 663 530 10 +3 799 663 18 +3 799 18 26 +3 799 26 919 +3 26 34 919 +3 34 886 919 +3 750 886 34 +3 647 750 42 +3 425 647 50 +3 1963 2615 1857 +3 1857 2699 1725 +3 1725 2803 1635 +3 1635 2834 1732 +3 1732 2738 1865 +3 1998 1865 2634 +3 2094 1998 2529 +3 2094 2446 2199 +3 2199 2388 2095 +3 2447 1999 2095 +3 2182 1964 2441 +3 1964 2616 2441 +3 2700 2616 1964 +3 2700 1964 1858 +3 2700 1858 2804 +3 1858 1726 2804 +3 1726 2835 2804 +3 1733 2835 1636 +3 2835 1726 1636 +3 2739 2835 1733 +3 2739 1733 1866 +3 2739 1866 2635 +3 1866 1999 2635 +3 1999 2530 2635 +3 2447 2530 1999 +3 2388 2447 2095 +3 2446 2388 2199 +3 2529 2446 2094 +3 2634 2529 1998 +3 2738 2634 1865 +3 2834 2738 1732 +3 2803 2834 1635 +3 2699 2803 1725 +3 2615 2699 1857 +3 2440 2615 1963 +3 2440 1963 2181 +3 3492 4825 3574 +3 3574 4714 3707 +3 3707 4570 3830 +3 3930 3830 4426 +3 3937 4434 3837 +3 3837 4578 3714 +3 3714 4722 3581 +3 4834 3499 3584 +3 3499 4721 3580 +3 3580 4577 3713 +3 4561 3699 3566 +3 3567 3700 4562 +3 3567 4706 3492 +3 4713 4824 3491 +3 4569 4713 3573 +3 4569 3706 4425 +3 3713 4433 3836 +3 4433 3936 3836 +3 4577 4433 3713 +3 4721 4577 3580 +3 4834 4721 3499 +3 4729 4834 3584 +3 4729 3584 3717 +3 4729 3717 4585 +3 3717 4441 4585 +3 3940 4441 3840 +3 4441 3717 3840 +3 4333 4441 3940 +3 4333 3940 4253 +3 3941 4253 4033 +3 4253 3940 4033 +3 4334 4253 3941 +3 4334 3941 4442 +3 3941 3841 4442 +3 3841 4586 4442 +3 3585 4586 3718 +3 4586 3841 3718 +3 4730 4586 3585 +3 4730 3585 4835 +3 3581 4835 3500 +3 4835 3585 3500 +3 4722 4835 3581 +3 4578 4722 3714 +3 4434 4578 3837 +3 4326 4434 3937 +3 4326 3937 4247 +3 3937 4029 4247 +3 4029 3930 4247 +3 3930 4318 4247 +3 4426 4318 3930 +3 4570 4426 3830 +3 4714 4570 3707 +3 4825 4714 3574 +3 4706 4825 3492 +3 4562 4706 3567 +3 4418 4562 3700 +3 4418 3700 3823 +3 4418 3823 4310 +3 3823 3923 4310 +3 3923 4023 4310 +3 4023 4239 4310 +3 4309 4239 4023 +3 4309 4023 3922 +3 4309 3922 4417 +3 3922 3822 4417 +3 3822 3699 4417 +3 3699 4561 4417 +3 4705 3566 3491 +3 4561 3566 4705 +3 4246 3936 4325 +3 3936 4433 4325 +3 4028 3936 4246 +3 4028 4246 4317 +3 4028 4317 3929 +3 4317 4425 3929 +3 4425 3829 3929 +3 3706 3829 4425 +3 3573 3706 4569 +3 3491 3573 4713 +3 4705 3491 4824 +3 5820 6572 5964 +3 5964 6428 6068 +3 5811 6563 5955 +3 6059 6239 6165 +3 6165 6308 6060 +3 6060 6420 5956 +3 5956 6564 5812 +3 5668 5812 6704 +3 6571 5819 6427 +3 5963 6315 6427 +3 6315 6067 6246 +3 6246 6172 6323 +3 6323 6075 6435 +3 5971 6579 6435 +3 6579 5827 6719 +3 6719 5683 6834 +3 6834 5594 6727 +3 6331 6083 6253 +3 6332 6253 6179 +3 6332 6084 6444 +3 6588 6444 5980 +3 5836 6728 6588 +3 6835 6728 5692 +3 6436 6580 5972 +3 6436 6076 6324 +3 6068 6316 6173 +3 6428 6316 6068 +3 6572 6428 5964 +3 6712 6572 5820 +3 6712 5820 5676 +3 6712 5676 6825 +3 5668 6825 5585 +3 6825 5676 5585 +3 6704 6825 5668 +3 6564 6704 5812 +3 6420 6564 5956 +3 6308 6420 6060 +3 6239 6308 6165 +3 6307 6239 6059 +3 6307 6059 5955 +3 6307 5955 6419 +3 5955 6563 6419 +3 6703 5811 5667 +3 6563 5811 6703 +3 6324 6173 6247 +3 6173 6316 6247 +3 6076 6173 6324 +3 5972 6076 6436 +3 5828 5972 6580 +3 5828 6580 6720 +3 5828 6720 5684 +3 6720 6835 5684 +3 6835 5595 5684 +3 5692 5595 6835 +3 5836 5692 6728 +3 5980 5836 6588 +3 6084 5980 6444 +3 6179 6084 6332 +3 6083 6179 6253 +3 5979 6083 6331 +3 5979 6331 6443 +3 5979 6443 6587 +3 5979 6587 5835 +3 6587 6727 5835 +3 6727 5691 5835 +3 5594 5691 6727 +3 5683 5594 6834 +3 5827 5683 6719 +3 5971 5827 6579 +3 6075 5971 6435 +3 6172 6075 6323 +3 6067 6172 6246 +3 5963 6067 6315 +3 5819 5963 6427 +3 5675 5819 6571 +3 5675 6571 6711 +3 5675 6711 5584 +3 6711 6824 5584 +3 6824 5667 5584 +3 6703 5667 6824 +3 6801 6661 6693 +3 7935 7791 7827 +3 6302 6405 6299 +3 6302 6299 6406 +3 6302 6406 6550 +3 6662 6550 6518 +3 6550 6406 6518 +3 6694 6550 6662 +3 6694 6662 6802 +3 6694 6802 6894 +3 6954 6894 6887 +3 6894 6802 6887 +3 6986 6894 6954 +3 6986 6954 7048 +3 6986 7048 7084 +3 7198 7084 7146 +3 7084 7048 7146 +3 7290 7084 7198 +3 7290 7198 7283 +3 7290 7283 7348 +3 7290 7348 7440 +3 7496 7440 7404 +3 7440 7348 7404 +3 7536 7440 7496 +3 7536 7496 7588 +3 7536 7588 7680 +3 7792 7680 7673 +3 7680 7588 7673 +3 7828 7680 7792 +3 7828 7792 7936 +3 7828 7936 7980 +3 8188 7980 8080 +3 7980 7936 8080 +3 8256 7980 8188 +3 8256 8188 8253 +3 8256 8253 8187 +3 8256 8187 7979 +3 7935 7979 8079 +3 7979 8187 8079 +3 7827 7979 7935 +3 7679 7827 7791 +3 7679 7791 7672 +3 7679 7672 7587 +3 7679 7587 7535 +3 7587 7495 7535 +3 7495 7439 7535 +3 7347 7439 7403 +3 7439 7495 7403 +3 7289 7439 7347 +3 7289 7347 7282 +3 7289 7282 7197 +3 7289 7197 7083 +3 7047 7083 7145 +3 7083 7197 7145 +3 6985 7083 7047 +3 6985 7047 6953 +3 6985 6953 6893 +3 6801 6893 6886 +3 6893 6953 6886 +3 6693 6893 6801 +3 6549 6693 6661 +3 6405 6549 6517 +3 6549 6661 6517 +3 6302 6549 6405 +3 7672 7586 7587 +3 7494 7495 7587 +3 7403 7495 7402 +3 7403 7346 7347 +3 7046 6953 7047 +3 6953 6952 6886 +3 6886 6885 6795 +3 6655 6795 6794 +3 6655 6654 6511 +3 6399 6511 6510 +3 6399 6398 6294 +3 6505 6648 6649 +3 6788 6789 6649 +3 6789 6877 6878 +3 6878 6946 6947 +3 6947 7040 7041 +3 7041 7138 7139 +3 7341 7274 7273 +3 7341 7340 7397 +3 7489 7397 7396 +3 7488 7581 7489 +3 7580 7664 7581 +3 8067 8066 8175 +3 8175 8174 8248 +3 8073 7928 7929 +3 7785 7929 7784 +3 7785 7671 7672 +3 7664 7663 7779 +3 7580 7663 7664 +3 7488 7580 7581 +3 7396 7488 7489 +3 7340 7396 7397 +3 7273 7340 7341 +3 7190 7273 7274 +3 7139 7190 7191 +3 7190 7274 7191 +3 7138 7190 7139 +3 7040 7138 7041 +3 6946 7040 6947 +3 6877 6946 6878 +3 6788 6877 6789 +3 6648 6788 6649 +3 6504 6648 6505 +3 6504 6505 6393 +3 6504 6393 6392 +3 6393 6294 6392 +3 6294 6293 6392 +3 6398 6293 6294 +3 6510 6398 6399 +3 6654 6510 6511 +3 6794 6654 6655 +3 6885 6794 6795 +3 6952 6885 6886 +3 7046 6952 6953 +3 7144 7046 7047 +3 7144 7047 7145 +3 7144 7145 7196 +3 7145 7197 7196 +3 7197 7281 7196 +3 7347 7281 7282 +3 7281 7197 7282 +3 7346 7281 7347 +3 7402 7346 7403 +3 7494 7402 7495 +3 7586 7494 7587 +3 7671 7586 7672 +3 7784 7671 7785 +3 7928 7784 7929 +3 8072 7928 8073 +3 8072 8073 8181 +3 8072 8181 8180 +3 8181 8248 8180 +3 8248 8247 8180 +3 8174 8247 8248 +3 8066 8174 8175 +3 7922 8066 8067 +3 7922 8067 7923 +3 7922 7923 7778 +3 7923 7779 7778 +3 7779 7663 7778 +3 5278 5334 5422 +3 6230 6157 5945 +3 5277 5189 5081 +3 4551 4515 4407 +3 4659 4515 4551 +3 4659 4551 4699 +3 4659 4699 4803 +3 4699 4897 4803 +3 4897 4890 4803 +3 4953 4890 4897 +3 4953 4897 4989 +3 4953 4989 5045 +3 4989 5081 5045 +3 5081 5133 5045 +3 5189 5133 5081 +3 5270 5189 5277 +3 5270 5277 5333 +3 5277 5421 5333 +3 5421 5385 5333 +3 5477 5385 5421 +3 5477 5421 5513 +3 5477 5513 5569 +3 5513 5657 5569 +3 5657 5650 5569 +3 5765 5650 5657 +3 5765 5657 5801 +3 5765 5801 5909 +3 5801 5945 5909 +3 5945 6053 5909 +3 6157 6053 5945 +3 6227 6157 6230 +3 6227 6230 6158 +3 6230 5946 6158 +3 5946 6054 6158 +3 5910 6054 5946 +3 5910 5946 5802 +3 5910 5802 5766 +3 5802 5658 5766 +3 5658 5651 5766 +3 5570 5651 5658 +3 5570 5658 5514 +3 5570 5514 5478 +3 5514 5422 5478 +3 5422 5386 5478 +3 5334 5386 5422 +3 5271 5334 5278 +3 5271 5278 5190 +3 5278 5082 5190 +3 5082 5134 5190 +3 5046 5134 5082 +3 5046 5082 4990 +3 5046 4990 4954 +3 4990 4898 4954 +3 4898 4891 4954 +3 4804 4891 4898 +3 4804 4898 4700 +3 4804 4700 4660 +3 4700 4552 4660 +3 4552 4516 4660 +3 4408 4516 4552 +3 4408 4552 4304 +3 4408 4304 4301 +3 4304 4407 4301 +3 4551 4407 4304 +3 5650 5568 5569 +3 5569 5476 5477 +3 5385 5477 5384 +3 5333 5385 5332 +3 5269 5270 5333 +3 5189 5270 5188 +3 4953 4952 4890 +3 4797 4890 4889 +3 4796 4653 4797 +3 4652 4509 4653 +3 4509 4508 4401 +3 4401 4400 4296 +3 4296 4295 4395 +3 6046 6047 6151 +3 6047 5902 5903 +3 5758 5759 5903 +3 5759 5649 5650 +3 5471 5378 5470 +3 5378 5379 5326 +3 5326 5327 5261 +3 5126 5039 5038 +3 5038 4947 4946 +3 4946 4882 4881 +3 4881 4791 4790 +3 4790 4647 4646 +3 4395 4394 4503 +3 4295 4394 4395 +3 4400 4295 4296 +3 4508 4400 4401 +3 4652 4508 4509 +3 4796 4652 4653 +3 4889 4796 4797 +3 4952 4889 4890 +3 5044 4952 4953 +3 5044 4953 5045 +3 5044 5045 5132 +3 5189 5132 5133 +3 5132 5045 5133 +3 5188 5132 5189 +3 5269 5188 5270 +3 5332 5269 5333 +3 5384 5332 5385 +3 5476 5384 5477 +3 5568 5476 5569 +3 5649 5568 5650 +3 5758 5649 5759 +3 5902 5758 5903 +3 6046 5902 6047 +3 6150 6046 6151 +3 6150 6151 6222 +3 6150 6222 6221 +3 6144 6222 6145 +3 6221 6222 6144 +3 6040 6145 6041 +3 6144 6145 6040 +3 5896 6041 5897 +3 6040 6041 5896 +3 5752 5897 5753 +3 5896 5897 5752 +3 4646 4503 4502 +3 4503 4394 4502 +3 4647 4503 4646 +3 4791 4647 4790 +3 4882 4791 4881 +3 4947 4882 4946 +3 5039 4947 5038 +3 5127 5039 5126 +3 5127 5126 5182 +3 5127 5182 5183 +3 5182 5261 5183 +3 5261 5262 5183 +3 5327 5262 5261 +3 5379 5327 5326 +3 5471 5379 5378 +3 5563 5471 5470 +3 5563 5470 5562 +3 5563 5562 5642 +3 5562 5641 5642 +3 5641 5753 5642 +3 5752 5753 5641 +3 3534 3535 3457 +3 3457 3458 3385 +3 3386 3310 3385 +3 3310 3311 3264 +3 3264 3265 3207 +3 3207 3208 3142 +3 3142 3143 3095 +3 3095 3096 3020 +3 2871 2791 2790 +3 2790 2687 2686 +3 2686 2583 2582 +3 2816 2879 2797 +3 3027 3038 3102 +3 3102 3110 3149 +3 3160 3215 3149 +3 3271 3215 3229 +3 3271 3279 3317 +3 3317 3349 3392 +3 3542 3651 3650 +3 3650 3784 3783 +3 3906 3783 3907 +3 3906 4007 4006 +3 3899 3900 3776 +3 3776 3777 3643 +3 3643 3644 3534 +3 2582 2500 2499 +3 2583 2500 2582 +3 2687 2583 2686 +3 2791 2687 2790 +3 2872 2791 2871 +3 2872 2871 2948 +3 2872 2948 2949 +3 2948 3020 2949 +3 3020 3021 2949 +3 3096 3021 3020 +3 3143 3096 3095 +3 3208 3143 3142 +3 3265 3208 3207 +3 3311 3265 3264 +3 3386 3311 3310 +3 3458 3386 3385 +3 3535 3458 3457 +3 3644 3535 3534 +3 3777 3644 3643 +3 3900 3777 3776 +3 4000 3900 3899 +3 4000 3899 3999 +3 4000 3999 4071 +3 4006 4071 4070 +3 4071 3999 4070 +3 4007 4071 4006 +3 3907 4007 3906 +3 3784 3907 3783 +3 3651 3784 3650 +3 3543 3651 3542 +3 3543 3542 3464 +3 3543 3464 3425 +3 3464 3392 3425 +3 3392 3400 3425 +3 3349 3400 3392 +3 3279 3349 3317 +3 3229 3279 3271 +3 3160 3229 3215 +3 3110 3160 3149 +3 3038 3110 3102 +3 2983 3038 3027 +3 2983 3027 2955 +3 2983 2955 2913 +3 2955 2879 2913 +3 2879 2816 2913 +3 2732 2797 2693 +3 2816 2797 2732 +3 2629 2693 2589 +3 2732 2693 2629 +3 2524 2589 2507 +3 2629 2589 2524 +3 2423 2500 2424 +3 2499 2500 2423 +3 2499 2423 2422 +3 2423 2507 2422 +3 2524 2507 2423 +3 1332 1385 1468 +3 2250 2175 1991 +3 1331 1254 1162 +3 642 612 517 +3 745 612 642 +3 745 642 787 +3 745 787 881 +3 787 986 881 +3 986 979 881 +3 1048 979 986 +3 1048 986 1080 +3 1048 1080 1128 +3 1080 1162 1128 +3 1162 1206 1128 +3 1254 1206 1162 +3 1324 1254 1331 +3 1324 1331 1384 +3 1331 1467 1384 +3 1467 1436 1384 +3 1518 1436 1467 +3 1518 1467 1553 +3 1518 1553 1602 +3 1553 1703 1602 +3 1703 1695 1602 +3 1812 1695 1703 +3 1812 1703 1844 +3 1812 1844 1945 +3 1844 1991 1945 +3 1991 2078 1945 +3 2175 2078 1991 +3 2247 2175 2250 +3 2247 2250 2176 +3 2250 1992 2176 +3 1992 2079 2176 +3 1946 2079 1992 +3 1946 1992 1845 +3 1946 1845 1813 +3 1845 1704 1813 +3 1704 1696 1813 +3 1603 1696 1704 +3 1603 1704 1554 +3 1603 1554 1519 +3 1554 1468 1519 +3 1468 1437 1519 +3 1385 1437 1468 +3 1325 1385 1332 +3 1325 1332 1255 +3 1332 1163 1255 +3 1163 1207 1255 +3 1129 1207 1163 +3 1129 1163 1081 +3 1129 1081 1049 +3 1081 987 1049 +3 987 980 1049 +3 882 980 987 +3 882 987 788 +3 882 788 746 +3 788 643 746 +3 643 613 746 +3 518 613 643 +3 518 643 417 +3 518 417 414 +3 417 517 414 +3 642 517 417 +3 511 525 428 +3 525 606 657 +3 657 739 792 +3 792 875 899 +3 899 979 1005 +3 1005 1048 1084 +3 1084 1128 1164 +3 1523 1602 1608 +3 1608 1695 1715 +3 1715 1718 1848 +3 1848 1850 1950 +3 733 732 869 +3 868 971 869 +3 1800 1932 1933 +3 1933 2065 2066 +3 2241 2242 2162 +3 2066 2162 2163 +3 2162 2242 2163 +3 2065 2162 2066 +3 1932 2065 1933 +3 1799 1932 1800 +3 1799 1800 1686 +3 1799 1686 1685 +3 1686 1596 1685 +3 1596 1595 1685 +3 1511 1595 1596 +3 1511 1596 1512 +3 1511 1512 1429 +3 1378 1429 1430 +3 1429 1512 1430 +3 1377 1429 1378 +3 1377 1378 1316 +3 1377 1316 1315 +3 1316 1248 1315 +3 1248 1247 1315 +3 1199 1247 1248 +3 1122 1199 1200 +3 1199 1248 1200 +3 1121 1199 1122 +3 1121 1122 1042 +3 1121 1042 1041 +3 1042 971 1041 +3 971 970 1041 +3 868 970 971 +3 732 868 869 +3 599 732 733 +3 599 733 600 +3 599 600 504 +3 1950 1954 2086 +3 1850 1954 1950 +3 1718 1850 1848 +3 1695 1718 1715 +3 1602 1695 1608 +3 1518 1602 1523 +3 1518 1523 1474 +3 1518 1474 1436 +3 1474 1386 1436 +3 1386 1384 1436 +3 1324 1384 1386 +3 1324 1386 1256 +3 1324 1256 1254 +3 1256 1164 1254 +3 1164 1206 1254 +3 1128 1206 1164 +3 1048 1128 1084 +3 979 1048 1005 +3 875 979 899 +3 739 875 792 +3 606 739 657 +3 511 606 525 +3 409 511 428 +3 409 428 408 +3 409 408 505 +3 408 504 505 +3 504 600 505 +3 8560 7917 8566 +3 8566 7773 8572 +3 8590 8181 8596 +3 8624 8188 8621 +3 7665 8573 7780 +3 8579 7924 7780 +3 8591 8176 8585 +3 8249 8176 8591 +3 8249 8591 8182 +3 8591 8597 8182 +3 8597 8074 8182 +3 7930 8074 8597 +3 7930 8597 8603 +3 7930 8603 7786 +3 8603 8609 7786 +3 8609 7673 7786 +3 7792 7673 8609 +3 7792 8609 8615 +3 7792 8615 7936 +3 8615 8621 7936 +3 8621 8080 7936 +3 8188 8080 8621 +3 8253 8188 8624 +3 8253 8624 8187 +3 8624 8620 8187 +3 8620 8079 8187 +3 7935 8079 8620 +3 7935 8620 8614 +3 7935 8614 7791 +3 8614 8608 7791 +3 8608 7672 7791 +3 7785 7672 8608 +3 7785 8608 8602 +3 7785 8602 7929 +3 8602 8596 7929 +3 8596 8073 7929 +3 8181 8073 8596 +3 8248 8181 8590 +3 8248 8590 8175 +3 8590 8584 8175 +3 8584 8067 8175 +3 7923 8067 8584 +3 7923 8584 8578 +3 7923 8578 7779 +3 8578 8572 7779 +3 8572 7664 7779 +3 7773 7664 8572 +3 7917 7773 8566 +3 8061 7917 8560 +3 8061 8560 8169 +3 8560 8555 8169 +3 8555 8242 8169 +3 8170 8242 8555 +3 8170 8555 8561 +3 8170 8561 8062 +3 7918 8561 8567 +3 8062 8561 7918 +3 7774 8567 8573 +3 7918 8567 7774 +3 7924 8585 8068 +3 8585 8176 8068 +3 8579 8585 7924 +3 8573 8579 7780 +3 7774 8573 7665 +3 343 517 338 +3 303 505 294 +3 255 498 263 +3 295 601 506 +3 734 601 295 +3 734 295 287 +3 734 287 870 +3 287 279 870 +3 279 972 870 +3 862 972 279 +3 862 279 271 +3 862 271 726 +3 271 263 726 +3 263 593 726 +3 498 593 263 +3 400 498 255 +3 400 255 497 +3 255 262 497 +3 262 592 497 +3 725 592 262 +3 725 262 270 +3 725 270 861 +3 270 278 861 +3 278 971 861 +3 869 971 278 +3 869 278 286 +3 869 286 733 +3 286 294 733 +3 294 600 733 +3 505 600 294 +3 409 505 303 +3 409 303 511 +3 303 310 511 +3 310 606 511 +3 739 606 310 +3 739 310 317 +3 739 317 875 +3 317 324 875 +3 324 979 875 +3 881 979 324 +3 881 324 331 +3 881 331 745 +3 331 338 745 +3 338 612 745 +3 517 612 338 +3 414 517 343 +3 414 343 518 +3 343 339 518 +3 339 613 518 +3 746 613 339 +3 746 339 332 +3 746 332 882 +3 332 325 882 +3 325 980 882 +3 876 980 325 +3 876 325 318 +3 876 318 740 +3 318 311 740 +3 311 607 740 +3 512 607 311 +3 512 311 304 +3 512 304 410 +3 304 506 410 +3 295 506 304 +3 2425 2381 2501 +3 2584 1934 2688 +3 2688 1801 2792 +3 2494 2234 2417 +3 2417 2155 2493 +3 2058 2576 2493 +3 2576 1925 2680 +3 2680 1792 2784 +3 2872 2784 1686 +3 2872 1800 2791 +3 2791 1933 2687 +3 2500 2163 2424 +3 2163 2242 2424 +3 2066 2163 2500 +3 2687 2066 2583 +3 2066 2500 2583 +3 1933 2066 2687 +3 1800 1933 2791 +3 1686 1800 2872 +3 1792 1686 2784 +3 1925 1792 2680 +3 2058 1925 2576 +3 2155 2058 2493 +3 2234 2155 2417 +3 2156 2234 2494 +3 2156 2494 2577 +3 2156 2577 2059 +3 2577 2681 2059 +3 2681 1926 2059 +3 1793 1926 2681 +3 1793 2681 2785 +3 1793 2785 1687 +3 1696 2375 1813 +3 1812 1945 2292 +3 1695 1812 2279 +3 1695 2271 1718 +3 1718 2264 1850 +3 1850 2252 1954 +3 2252 2086 1954 +3 2264 2252 1850 +3 2271 2264 1718 +3 2279 2271 1695 +3 2292 2279 1812 +3 2345 2292 1945 +3 2345 1945 2078 +3 2345 2078 2356 +3 2247 2356 2175 +3 2356 2078 2175 +3 2361 2356 2247 +3 2079 2361 2176 +3 2361 2247 2176 +3 2369 2361 2079 +3 2369 2079 1946 +3 2369 1946 2374 +3 1946 1813 2374 +3 1813 2375 2374 +3 2376 1696 1807 +3 2375 1696 2376 +3 2377 1807 1940 +3 2376 1807 2377 +3 2378 1940 2073 +3 2377 1940 2378 +3 2379 2073 2170 +3 2378 2073 2379 +3 2380 2170 2243 +3 2379 2170 2380 +3 2792 1687 2873 +3 1687 2785 2873 +3 1801 1687 2792 +3 1934 1801 2688 +3 2067 1934 2584 +3 2067 2584 2501 +3 2067 2501 2164 +3 2501 2381 2164 +3 2381 2243 2164 +3 2380 2243 2381 +3 4142 4001 4396 +3 4882 3644 4791 +3 4791 3777 4647 +3 4647 3900 4503 +3 4653 3651 4797 +3 4407 4013 4301 +3 4015 4408 4301 +3 3914 4516 4408 +3 4516 4088 4660 +3 4660 4089 4804 +3 4804 4090 4891 +3 4891 4091 4798 +3 4798 4139 4654 +3 4140 4510 4654 +3 4510 4141 4402 +3 4883 4792 3645 +3 4883 3536 4786 +3 3638 4642 4786 +3 4642 3771 4498 +3 4498 3894 4390 +3 4785 3535 4882 +3 4402 4142 4297 +3 4142 4396 4297 +3 4141 4142 4402 +3 4140 4141 4510 +3 4139 4140 4654 +3 4091 4139 4798 +3 4090 4091 4891 +3 4089 4090 4804 +3 4088 4089 4660 +3 3914 4088 4516 +3 4015 3914 4408 +3 4013 4015 4301 +3 3913 4013 4407 +3 3913 4407 4515 +3 3913 4515 3790 +3 4515 4659 3790 +3 4659 3689 3790 +3 3661 3689 4659 +3 3661 4659 4803 +3 3661 4803 3543 +3 4797 3543 4890 +3 3543 4803 4890 +3 3651 3543 4797 +3 3784 3651 4653 +3 3784 4653 4509 +3 3784 4509 3907 +3 4509 4401 3907 +3 4401 4007 3907 +3 4071 4007 4401 +3 4071 4401 4296 +3 4071 4296 4000 +3 4503 4000 4395 +3 4000 4296 4395 +3 3900 4000 4503 +3 3777 3900 4647 +3 3644 3777 4791 +3 3535 3644 4882 +3 3637 3535 4785 +3 3637 4785 4641 +3 3637 4641 3770 +3 4641 4497 3770 +3 4497 3893 3770 +3 3993 3893 4497 +3 3993 4497 4389 +3 3993 4389 4065 +3 4389 4290 4065 +3 4290 4390 4065 +3 4390 3994 4065 +3 3894 3994 4390 +3 3771 3894 4498 +3 3638 3771 4642 +3 3536 3638 4786 +3 3645 3536 4883 +3 3778 3645 4792 +3 3778 4792 4648 +3 3778 4648 3901 +3 4396 3901 4504 +3 3901 4648 4504 +3 4001 3901 4396 +3 4072 4001 4142 +3 5643 6790 5754 +3 6650 5898 5754 +3 5898 6506 6042 +3 6042 6394 6146 +3 6048 6512 5904 +3 6656 5760 5904 +3 5760 6796 5651 +3 5651 6887 5766 +3 6158 6406 6227 +3 6227 6299 6157 +3 6157 6405 6053 +3 6053 6517 5909 +3 6661 5765 5909 +3 5903 6655 6047 +3 6047 6511 6151 +3 6151 6399 6222 +3 6222 6294 6145 +3 5891 6499 6035 +3 6216 6388 6140 +3 6140 6500 6036 +3 6036 6644 5892 +3 6145 6393 6041 +3 6294 6393 6145 +3 6399 6294 6222 +3 6511 6399 6151 +3 6655 6511 6047 +3 6795 6655 5903 +3 6795 5903 5759 +3 6795 5759 5650 +3 6795 5650 6886 +3 5650 5765 6886 +3 5765 6801 6886 +3 6661 6801 5765 +3 6517 6661 5909 +3 6405 6517 6053 +3 6299 6405 6157 +3 6406 6299 6227 +3 6518 6406 6158 +3 6518 6158 6054 +3 6518 6054 6662 +3 6054 5910 6662 +3 5910 5766 6662 +3 5766 6802 6662 +3 6887 6802 5766 +3 6796 6887 5651 +3 6656 6796 5760 +3 6512 6656 5904 +3 6400 6512 6048 +3 6400 6048 6152 +3 6400 6152 6295 +3 6146 6295 6223 +3 6295 6152 6223 +3 6394 6295 6146 +3 6506 6394 6042 +3 6650 6506 5898 +3 6790 6650 5754 +3 6879 6790 5643 +3 6879 5643 6784 +3 5892 6784 5748 +3 6784 5643 5748 +3 6644 6784 5892 +3 6500 6644 6036 +3 6388 6500 6140 +3 6288 6388 6216 +3 6288 6216 6139 +3 6288 6139 6387 +3 6139 6035 6387 +3 6035 6499 6387 +3 6643 5891 5747 +3 6499 5891 6643 +3 6783 5747 5642 +3 6643 5747 6783 +3 6649 6041 6505 +3 6041 6393 6505 +3 5897 6041 6649 +3 5897 6649 5753 +3 6649 6789 5753 +3 6789 6878 5753 +3 6878 5642 5753 +3 6783 5642 6878 +3 7581 7575 7489 +3 7483 7397 7489 +3 7397 7391 7341 +3 7191 7133 7139 +3 7139 7035 7041 +3 7041 6941 6947 +3 6637 6499 6643 +3 6499 6493 6387 +3 6387 6381 6288 +3 6388 6288 6284 +3 6388 6382 6500 +3 6494 6644 6500 +3 7768 7774 7665 +3 7917 7767 7773 +3 7036 6948 6942 +3 6942 6879 6869 +3 6644 6638 6784 +3 6494 6638 6644 +3 6382 6494 6500 +3 6284 6382 6388 +3 6381 6284 6288 +3 6493 6381 6387 +3 6637 6493 6499 +3 6777 6637 6643 +3 6777 6643 6783 +3 6777 6783 6868 +3 6947 6868 6878 +3 6868 6783 6878 +3 6941 6868 6947 +3 7035 6941 7041 +3 7133 7035 7139 +3 7185 7133 7191 +3 7185 7191 7264 +3 7191 7274 7264 +3 7274 7341 7264 +3 7341 7335 7264 +3 7391 7335 7341 +3 7483 7391 7397 +3 7575 7483 7489 +3 7654 7575 7581 +3 7773 7654 7664 +3 7654 7581 7664 +3 7767 7654 7773 +3 7911 7767 7917 +3 7911 7917 8061 +3 7911 8061 8055 +3 8061 8169 8055 +3 8169 8163 8055 +3 8238 8163 8169 +3 8238 8169 8242 +3 8238 8242 8164 +3 8062 8164 8170 +3 8164 8242 8170 +3 8056 8164 8062 +3 8056 8062 7918 +3 8056 7918 7912 +3 7918 7774 7912 +3 7774 7768 7912 +3 6869 6784 6778 +3 6784 6638 6778 +3 6879 6784 6869 +3 6948 6879 6942 +3 7042 6948 7036 +3 7042 7036 7134 +3 7042 7134 7140 +3 7134 7186 7140 +3 7186 7192 7140 +3 7275 7192 7186 +3 7275 7186 7265 +3 7275 7265 7336 +3 7275 7336 7342 +3 7336 7392 7342 +3 7392 7398 7342 +3 7490 7398 7392 +3 7490 7392 7484 +3 7490 7484 7582 +3 7484 7576 7582 +3 7576 7655 7582 +3 7655 7665 7582 +3 7768 7665 7655 +3 7574 7575 7654 +3 7575 7482 7483 +3 7391 7483 7390 +3 7334 7335 7391 +3 7263 7264 7335 +3 7035 7034 6941 +3 6941 6940 6868 +3 6868 6867 6769 +3 6769 6768 6629 +3 6628 6485 6629 +3 6485 6484 6373 +3 6373 6372 6278 +3 8038 8147 8039 +3 8232 8154 8155 +3 8046 8047 8155 +3 8047 7902 7903 +3 7759 7903 7758 +3 7759 7653 7654 +3 7475 7382 7474 +3 7382 7383 7326 +3 7326 7327 7253 +3 7253 7254 7176 +3 7026 6933 6932 +3 6932 6858 6857 +3 6760 6857 6761 +3 6760 6621 6620 +3 6476 6620 6477 +3 6278 6277 6365 +3 6372 6277 6278 +3 6484 6372 6373 +3 6628 6484 6485 +3 6768 6628 6629 +3 6867 6768 6769 +3 6940 6867 6868 +3 7034 6940 6941 +3 7132 7034 7035 +3 7132 7035 7133 +3 7132 7133 7184 +3 7264 7184 7185 +3 7184 7133 7185 +3 7263 7184 7264 +3 7334 7263 7335 +3 7390 7334 7391 +3 7482 7390 7483 +3 7574 7482 7575 +3 7653 7574 7654 +3 7758 7653 7759 +3 7902 7758 7903 +3 8046 7902 8047 +3 8154 8046 8155 +3 8231 8154 8232 +3 8231 8232 8146 +3 8232 8147 8146 +3 8147 8038 8146 +3 7894 8039 7895 +3 8038 8039 7894 +3 7750 7895 7751 +3 7894 7895 7750 +3 6476 6365 6364 +3 6365 6277 6364 +3 6477 6365 6476 +3 6621 6477 6620 +3 6761 6621 6760 +3 6858 6761 6857 +3 6933 6858 6932 +3 7027 6933 7026 +3 7027 7026 7124 +3 7027 7124 7125 +3 7124 7176 7125 +3 7176 7177 7125 +3 7254 7177 7176 +3 7327 7254 7253 +3 7383 7327 7326 +3 7475 7383 7382 +3 7567 7475 7474 +3 7567 7474 7566 +3 7567 7566 7644 +3 7566 7643 7644 +3 7643 7751 7644 +3 7750 7751 7643 +3 5471 5465 5379 +3 5379 5373 5327 +3 5327 5321 5262 +3 5262 5252 5183 +3 5183 5177 5127 +3 4641 4635 4497 +3 4497 4491 4389 +3 4389 4383 4290 +3 4290 4286 4390 +3 4390 4384 4498 +3 4498 4492 4642 +3 4642 4636 4786 +3 5128 5040 5034 +3 5128 5122 5184 +3 5891 5741 5747 +3 5322 5380 5328 +3 5322 5328 5253 +3 5328 5263 5253 +3 5263 5184 5253 +3 5184 5178 5253 +3 5122 5178 5184 +3 5034 5122 5128 +3 4942 5034 5040 +3 4942 5040 4948 +3 4942 4948 4883 +3 4942 4883 4873 +3 4883 4786 4873 +3 4786 4780 4873 +3 4636 4780 4786 +3 4492 4636 4642 +3 4384 4492 4498 +3 4286 4384 4390 +3 4383 4286 4290 +3 4491 4383 4389 +3 4635 4491 4497 +3 4779 4635 4641 +3 4779 4641 4785 +3 4779 4785 4872 +3 4947 4872 4882 +3 4872 4785 4882 +3 4941 4872 4947 +3 4941 4947 5039 +3 4941 5039 5033 +3 5039 5127 5033 +3 5127 5121 5033 +3 5177 5121 5127 +3 5252 5177 5183 +3 5321 5252 5262 +3 5373 5321 5327 +3 5465 5373 5379 +3 5557 5465 5471 +3 5557 5471 5563 +3 5557 5563 5632 +3 5747 5632 5642 +3 5632 5563 5642 +3 5741 5632 5747 +3 5885 5741 5891 +3 5885 5891 6035 +3 5885 6035 6029 +3 6035 6139 6029 +3 6139 6133 6029 +3 6212 6139 6216 +3 6133 6139 6212 +3 6036 6134 6140 +3 6134 6216 6140 +3 6212 6216 6134 +3 6030 6036 5892 +3 6134 6036 6030 +3 5886 5892 5748 +3 6030 5892 5886 +3 5742 5748 5643 +3 5886 5748 5742 +3 5466 5380 5374 +3 5380 5322 5374 +3 5472 5380 5466 +3 5472 5466 5558 +3 5472 5558 5564 +3 5558 5633 5564 +3 5633 5643 5564 +3 5742 5643 5633 +3 5632 5556 5557 +3 5557 5464 5465 +3 5372 5373 5465 +3 5320 5321 5373 +3 5321 5251 5252 +3 5033 5032 4941 +3 4941 4940 4872 +3 4771 4872 4871 +3 4771 4770 4627 +3 4627 4626 4483 +3 4375 4483 4482 +3 4375 4374 4280 +3 4280 4279 4367 +3 4367 4366 4475 +3 5868 6013 5869 +3 6021 5876 5877 +3 5732 5733 5877 +3 5733 5631 5632 +3 5457 5364 5456 +3 5364 5365 5312 +3 5312 5313 5241 +3 5241 5242 5168 +3 5168 5169 5112 +3 4932 4862 4861 +3 4861 4763 4762 +3 4475 4474 4619 +3 4366 4474 4475 +3 4279 4366 4367 +3 4374 4279 4280 +3 4482 4374 4375 +3 4626 4482 4483 +3 4770 4626 4627 +3 4871 4770 4771 +3 4940 4871 4872 +3 5032 4940 4941 +3 5120 5032 5033 +3 5120 5033 5121 +3 5120 5121 5176 +3 5252 5176 5177 +3 5176 5121 5177 +3 5251 5176 5252 +3 5320 5251 5321 +3 5372 5320 5373 +3 5464 5372 5465 +3 5556 5464 5557 +3 5631 5556 5632 +3 5732 5631 5733 +3 5876 5732 5877 +3 6020 5876 6021 +3 6020 6021 6125 +3 6020 6125 6124 +3 6125 6206 6124 +3 6206 6205 6124 +3 6116 6205 6206 +3 6116 6206 6117 +3 6116 6117 6012 +3 6117 6013 6012 +3 6013 5868 6012 +3 5724 5869 5725 +3 5868 5869 5724 +3 4762 4619 4618 +3 4619 4474 4618 +3 4763 4619 4762 +3 4862 4763 4861 +3 4933 4862 4932 +3 4933 4932 5024 +3 4933 5024 5025 +3 5024 5112 5025 +3 5112 5113 5025 +3 5169 5113 5112 +3 5242 5169 5168 +3 5313 5242 5241 +3 5365 5313 5312 +3 5457 5365 5364 +3 5549 5457 5456 +3 5549 5456 5548 +3 5549 5548 5622 +3 5548 5621 5622 +3 5621 5725 5622 +3 5724 5725 5621 +3 3535 3527 3458 +3 3458 3451 3386 +3 3386 3379 3311 +3 3311 3304 3265 +3 3258 3208 3265 +3 3208 3200 3143 +3 3136 3096 3143 +3 3089 3021 3096 +3 3014 2949 3021 +3 2949 2942 2872 +3 2864 2784 2872 +3 2784 2777 2680 +3 2680 2673 2576 +3 2568 2493 2576 +3 2493 2486 2417 +3 2412 2494 2417 +3 2494 2487 2577 +3 2577 2569 2681 +3 2681 2674 2785 +3 3993 3986 3893 +3 3637 3630 3535 +3 3528 3536 3452 +3 3452 3459 3380 +3 3387 3305 3380 +3 3305 3312 3259 +3 3259 3266 3201 +3 3137 3201 3209 +3 3015 2950 2943 +3 2785 2778 2873 +3 2674 2778 2785 +3 2569 2674 2681 +3 2487 2569 2577 +3 2412 2487 2494 +3 2486 2412 2417 +3 2568 2486 2493 +3 2673 2568 2576 +3 2777 2673 2680 +3 2864 2777 2784 +3 2942 2864 2872 +3 3014 2942 2949 +3 3089 3014 3021 +3 3136 3089 3096 +3 3200 3136 3143 +3 3258 3200 3208 +3 3304 3258 3265 +3 3379 3304 3311 +3 3451 3379 3386 +3 3527 3451 3458 +3 3630 3527 3535 +3 3763 3630 3637 +3 3763 3637 3770 +3 3763 3770 3886 +3 3770 3893 3886 +3 3893 3986 3886 +3 4061 3993 4065 +3 3986 3993 4061 +3 3987 4065 3994 +3 4061 4065 3987 +3 3771 3887 3894 +3 3887 3994 3894 +3 3987 3994 3887 +3 3764 3771 3638 +3 3887 3771 3764 +3 3631 3638 3536 +3 3764 3638 3631 +3 2943 2873 2865 +3 2873 2778 2865 +3 2950 2873 2943 +3 3022 2950 3015 +3 3022 3015 3090 +3 3022 3090 3097 +3 3090 3137 3097 +3 3137 3144 3097 +3 3209 3144 3137 +3 3266 3209 3201 +3 3312 3266 3259 +3 3387 3312 3305 +3 3459 3387 3380 +3 3536 3459 3452 +3 3631 3536 3528 +3 3008 3033 3083 +3 3083 3108 3130 +3 3130 3155 3193 +3 3227 3252 3193 +3 3252 3277 3298 +3 3298 3324 3373 +3 3373 3398 3445 +3 3445 3470 3519 +3 3749 3871 3872 +3 3872 3971 3972 +3 3972 4054 4055 +3 4055 3978 3979 +3 3878 3879 3979 +3 3879 3755 3756 +3 3756 3622 3623 +3 3623 3526 3527 +3 3527 3471 3451 +3 3451 3399 3379 +3 3379 3325 3304 +3 3304 3278 3258 +3 3228 3200 3258 +3 3200 3156 3136 +3 3109 3089 3136 +3 3089 3034 3014 +3 3014 2962 2942 +3 2820 2864 2902 +3 2864 2942 2902 +3 2942 2901 2902 +3 2962 2901 2942 +3 3034 2962 3014 +3 3109 3034 3089 +3 3156 3109 3136 +3 3228 3156 3200 +3 3278 3228 3258 +3 3325 3278 3304 +3 3399 3325 3379 +3 3471 3399 3451 +3 3526 3471 3527 +3 3622 3526 3623 +3 3755 3622 3756 +3 3878 3755 3879 +3 3978 3878 3979 +3 4054 3978 4055 +3 3971 4054 3972 +3 3871 3971 3872 +3 3748 3871 3749 +3 3748 3749 3616 +3 3748 3616 3615 +3 3616 3519 3615 +3 3519 3518 3615 +3 3470 3518 3519 +3 3398 3470 3445 +3 3324 3398 3373 +3 3277 3324 3298 +3 3227 3277 3252 +3 3155 3227 3193 +3 3108 3155 3130 +3 3033 3108 3083 +3 2961 3033 3008 +3 2961 3008 2936 +3 2961 2936 2899 +3 2819 2900 2857 +3 2900 2936 2857 +3 2899 2936 2900 +3 8476 7744 8468 +3 8460 8140 8452 +3 7887 8467 8459 +3 8467 7743 8475 +3 8499 8155 8507 +3 8544 8164 8540 +3 7645 8476 7752 +3 8484 7896 7752 +3 8500 8148 8492 +3 8233 8148 8500 +3 8233 8500 8156 +3 8500 8508 8156 +3 8508 8048 8156 +3 7904 8048 8508 +3 7904 8508 8516 +3 7904 8516 7760 +3 8516 8524 7760 +3 8524 7655 7760 +3 7768 7655 8524 +3 7768 8524 8532 +3 7768 8532 7912 +3 8532 8540 7912 +3 8540 8056 7912 +3 8164 8056 8540 +3 8238 8164 8544 +3 8238 8544 8163 +3 8544 8539 8163 +3 8539 8055 8163 +3 7911 8055 8539 +3 7911 8539 8531 +3 7911 8531 7767 +3 8531 8523 7767 +3 8523 7654 7767 +3 7759 7654 8523 +3 7759 8523 8515 +3 7759 8515 7903 +3 8515 8507 7903 +3 8507 8047 7903 +3 8155 8047 8507 +3 8232 8155 8499 +3 8232 8499 8147 +3 8499 8491 8147 +3 8491 8039 8147 +3 7895 8039 8491 +3 7895 8491 8483 +3 7895 8483 7751 +3 8483 8475 7751 +3 8475 7644 7751 +3 7743 7644 8475 +3 7887 7743 8467 +3 8031 7887 8459 +3 8031 8459 8139 +3 8459 8452 8139 +3 8452 8224 8139 +3 8140 8224 8452 +3 8032 8140 8460 +3 8032 8460 7888 +3 8460 8468 7888 +3 8468 7744 7888 +3 7896 8492 8040 +3 8492 8148 8040 +3 8484 8492 7896 +3 8476 8484 7752 +3 7744 8476 7645 +3 180 952 173 +3 567 168 161 +3 182 842 188 +3 188 706 194 +3 199 483 201 +3 962 220 213 +3 220 854 228 +3 235 396 236 +3 898 215 961 +3 215 222 961 +3 222 853 961 +3 717 853 222 +3 717 222 230 +3 717 230 584 +3 230 236 584 +3 236 489 584 +3 396 489 236 +3 490 396 235 +3 490 235 585 +3 235 228 585 +3 228 718 585 +3 854 718 228 +3 962 854 220 +3 848 962 213 +3 848 213 207 +3 848 207 712 +3 207 201 712 +3 201 579 712 +3 483 579 201 +3 392 483 199 +3 392 199 477 +3 199 194 477 +3 194 573 477 +3 706 573 194 +3 842 706 188 +3 953 842 182 +3 953 182 175 +3 953 175 836 +3 175 168 836 +3 168 700 836 +3 567 700 168 +3 471 567 161 +3 471 161 385 +3 161 159 385 +3 159 470 385 +3 566 470 159 +3 566 159 166 +3 566 166 699 +3 166 173 699 +3 173 835 699 +3 952 835 173 +3 897 952 180 +3 1899 2553 2032 +3 2032 2470 2128 +3 2128 2403 2219 +3 2219 2471 2129 +3 2129 2554 2033 +3 1906 2559 2039 +3 2141 2226 2408 +3 2141 2481 2045 +3 2045 2564 1912 +3 1912 2669 1779 +3 2773 1677 1779 +3 2147 2486 2050 +3 2050 2568 1917 +3 1917 2673 1784 +3 1784 2777 1676 +3 1713 1676 2820 +3 1676 2864 2820 +3 2777 2864 1676 +3 2673 2777 1784 +3 2568 2673 1917 +3 2486 2568 2050 +3 2412 2486 2147 +3 2412 2147 2230 +3 2412 2230 2487 +3 2230 2148 2487 +3 2148 2569 2487 +3 1918 2569 2051 +3 2569 2148 2051 +3 2674 2569 1918 +3 2674 1918 1785 +3 2674 1785 2778 +3 1785 1677 2778 +3 1677 2865 2778 +3 2773 2865 1677 +3 2669 2773 1779 +3 2564 2669 1912 +3 2481 2564 2045 +3 2408 2481 2141 +3 2476 2408 2226 +3 2039 2476 2135 +3 2476 2226 2135 +3 2559 2476 2039 +3 2664 2559 1906 +3 2664 1906 1773 +3 2664 1773 2768 +3 1773 1668 2768 +3 1668 2858 2768 +3 2763 2858 1668 +3 2763 1668 1767 +3 2763 1767 2659 +3 2033 2659 1900 +3 2659 1767 1900 +3 2554 2659 2033 +3 2471 2554 2129 +3 2403 2471 2219 +3 2470 2403 2128 +3 2553 2470 2032 +3 2658 2553 1899 +3 2658 1899 1766 +3 2658 1766 2762 +3 1766 1667 2762 +3 1667 2857 2762 +3 2819 2857 1667 +3 2819 1667 1712 +3 4863 3617 3520 +3 4764 3750 3617 +3 3750 4620 3873 +3 3865 3742 4611 +3 3965 3865 4467 +3 3965 4359 4049 +3 4049 4272 3966 +3 3966 4360 3866 +3 3866 4468 3743 +3 3610 3743 4612 +3 3610 4756 3520 +3 4475 4619 3749 +3 4375 3979 4483 +3 4771 3527 4872 +3 4872 3630 4779 +3 4779 3763 4635 +3 3886 4491 4635 +3 4491 3986 4383 +3 4383 4061 4286 +3 4286 3987 4384 +3 4384 3887 4492 +3 3764 4636 4492 +3 4636 3631 4780 +3 4780 3528 4873 +3 4873 3624 4772 +3 4772 3757 4628 +3 3980 4376 3880 +3 4281 4376 3980 +3 4281 3980 4056 +3 4281 4056 3973 +3 4281 3973 4368 +3 3973 3873 4368 +3 3873 4476 4368 +3 4620 4476 3873 +3 4764 4620 3750 +3 4863 4764 3617 +3 4756 4863 3520 +3 4612 4756 3610 +3 4468 4612 3743 +3 4360 4468 3866 +3 4272 4360 3966 +3 4359 4272 4049 +3 4467 4359 3965 +3 4611 4467 3865 +3 4755 3742 3609 +3 4611 3742 4755 +3 4628 3880 4484 +3 3880 4376 4484 +3 3757 3880 4628 +3 3624 3757 4772 +3 3528 3624 4873 +3 3631 3528 4780 +3 3764 3631 4636 +3 3887 3764 4492 +3 3987 3887 4384 +3 4061 3987 4286 +3 3986 4061 4383 +3 3886 3986 4491 +3 3763 3886 4635 +3 3630 3763 4779 +3 3527 3630 4872 +3 3623 3527 4771 +3 3623 4771 4627 +3 3623 4627 3756 +3 4627 4483 3756 +3 4483 3879 3756 +3 3979 3879 4483 +3 4055 3979 4375 +3 4055 4375 4280 +3 4055 4280 4367 +3 4055 4367 3972 +3 4367 4475 3972 +3 4475 3872 3972 +3 3749 3872 4475 +3 3616 3749 4619 +3 3616 4619 4763 +3 3616 4763 3519 +3 4763 4862 3519 +3 4862 3609 3519 +3 4755 3609 4862 +3 5623 6762 5726 +3 6622 5870 5726 +3 6014 5870 6478 +3 6366 6118 6014 +3 6118 6279 6207 +3 6207 6374 6126 +3 6126 6486 6022 +3 6022 6630 5878 +3 5878 6770 5734 +3 5734 6869 5633 +3 5633 6778 5742 +3 6134 6382 6212 +3 6212 6284 6133 +3 6133 6381 6029 +3 6029 6493 5885 +3 5717 6613 5861 +3 6005 5861 6469 +3 6005 6357 6109 +3 6109 6270 6198 +3 6198 6358 6110 +3 6110 6470 6006 +3 6614 5862 6006 +3 6013 6365 6477 +3 6365 6117 6278 +3 6278 6206 6373 +3 6373 6125 6485 +3 6021 6629 6485 +3 5885 6637 5741 +3 6493 6637 5885 +3 6381 6493 6029 +3 6284 6381 6133 +3 6382 6284 6212 +3 6494 6382 6134 +3 6494 6134 6030 +3 6494 6030 6638 +3 5742 6638 5886 +3 6638 6030 5886 +3 6778 6638 5742 +3 6869 6778 5633 +3 6770 6869 5734 +3 6630 6770 5878 +3 6486 6630 6022 +3 6374 6486 6126 +3 6279 6374 6207 +3 6366 6279 6118 +3 6478 6366 6014 +3 6622 6478 5870 +3 6762 6622 5726 +3 6859 6762 5623 +3 6859 5623 6754 +3 5862 6754 5718 +3 6754 5623 5718 +3 6614 6754 5862 +3 6470 6614 6006 +3 6358 6470 6110 +3 6270 6358 6198 +3 6357 6270 6109 +3 6469 6357 6005 +3 6613 6469 5861 +3 6753 5717 5622 +3 6613 5717 6753 +3 6868 5741 6777 +3 5741 6637 6777 +3 5632 5741 6868 +3 5632 6868 6769 +3 5632 6769 5733 +3 6769 6629 5733 +3 6629 5877 5733 +3 6021 5877 6629 +3 6125 6021 6485 +3 6206 6125 6373 +3 6117 6206 6278 +3 6013 6117 6365 +3 5869 6013 6477 +3 5869 6477 6621 +3 5869 6621 5725 +3 6621 6761 5725 +3 6761 6858 5725 +3 6858 5622 5725 +3 6753 5622 6858 +3 7383 7375 7327 +3 7327 7319 7254 +3 7177 7254 7244 +3 7177 7169 7125 +3 7027 7125 7117 +3 7019 6933 7027 +3 6925 6858 6933 +3 6858 6848 6753 +3 6613 6753 6745 +3 6613 6605 6469 +3 6614 6746 6754 +3 7887 8031 7879 +3 7735 7743 7887 +3 7743 7634 7644 +3 7384 7376 7468 +3 7376 7328 7320 +3 7320 7255 7245 +3 7170 7245 7178 +3 7170 7126 7118 +3 7118 7028 7020 +3 6754 6849 6859 +3 6849 6934 6859 +3 6746 6849 6754 +3 6606 6746 6614 +3 6606 6614 6470 +3 6606 6470 6462 +3 6470 6358 6462 +3 6358 6350 6462 +3 6266 6350 6358 +3 6266 6358 6270 +3 6266 6270 6357 +3 6266 6357 6349 +3 6357 6469 6349 +3 6469 6461 6349 +3 6605 6461 6469 +3 6745 6605 6613 +3 6848 6745 6753 +3 6925 6848 6858 +3 7019 6925 6933 +3 7117 7019 7027 +3 7169 7117 7125 +3 7244 7169 7177 +3 7319 7244 7254 +3 7375 7319 7327 +3 7467 7375 7383 +3 7467 7383 7475 +3 7467 7475 7559 +3 7644 7559 7567 +3 7559 7475 7567 +3 7634 7559 7644 +3 7735 7634 7743 +3 7879 7735 7887 +3 8023 7879 8031 +3 8023 8031 8139 +3 8023 8139 8131 +3 8218 8139 8224 +3 8131 8139 8218 +3 8032 8132 8140 +3 8132 8224 8140 +3 8218 8224 8132 +3 8024 8032 7888 +3 8132 8032 8024 +3 7880 7888 7744 +3 8024 7888 7880 +3 7736 7744 7645 +3 7880 7744 7736 +3 7020 6934 6926 +3 6934 6849 6926 +3 7028 6934 7020 +3 7126 7028 7118 +3 7178 7126 7170 +3 7255 7178 7245 +3 7328 7255 7320 +3 7384 7328 7376 +3 7476 7384 7468 +3 7476 7468 7560 +3 7476 7560 7568 +3 7560 7635 7568 +3 7635 7645 7568 +3 7736 7645 7635 +3 7634 7558 7559 +3 7559 7466 7467 +3 7374 7375 7467 +3 7318 7319 7375 +3 7319 7243 7244 +3 7168 7169 7244 +3 7169 7116 7117 +3 6925 6924 6848 +3 6847 6741 6848 +3 6741 6740 6601 +3 6601 6600 6457 +3 6456 6345 6457 +3 6262 6345 6344 +3 6262 6261 6341 +3 8123 8213 8214 +3 8214 8126 8127 +3 8018 8019 8127 +3 8019 7874 7875 +3 7730 7731 7875 +3 7731 7633 7634 +3 7462 7463 7370 +3 7370 7371 7314 +3 7314 7315 7237 +3 7237 7238 7164 +3 7014 6921 6920 +3 6920 6842 6841 +3 6841 6737 6736 +3 6736 6597 6596 +3 6341 6340 6453 +3 6261 6340 6341 +3 6344 6261 6262 +3 6456 6344 6345 +3 6600 6456 6457 +3 6740 6600 6601 +3 6847 6740 6741 +3 6924 6847 6848 +3 7018 6924 6925 +3 7117 7018 7019 +3 7018 6925 7019 +3 7116 7018 7117 +3 7168 7116 7169 +3 7243 7168 7244 +3 7318 7243 7319 +3 7374 7318 7375 +3 7466 7374 7467 +3 7558 7466 7559 +3 7633 7558 7634 +3 7730 7633 7731 +3 7874 7730 7875 +3 8018 7874 8019 +3 8126 8018 8127 +3 8213 8126 8214 +3 8122 8213 8123 +3 8122 8123 8015 +3 8122 8015 8014 +3 7870 8015 7871 +3 8014 8015 7870 +3 7726 7871 7727 +3 7870 7871 7726 +3 6596 6453 6452 +3 6453 6340 6452 +3 6597 6453 6596 +3 6737 6597 6736 +3 6842 6737 6841 +3 6921 6842 6920 +3 7015 6921 7014 +3 7015 7014 7112 +3 7015 7112 7113 +3 7112 7164 7113 +3 7164 7165 7113 +3 7238 7165 7164 +3 7315 7238 7237 +3 7371 7315 7314 +3 7463 7371 7370 +3 7555 7463 7462 +3 7555 7462 7554 +3 7555 7554 7628 +3 7554 7627 7628 +3 7627 7727 7628 +3 7726 7727 7627 +3 5541 5549 5622 +3 5549 5449 5457 +3 5025 5017 4933 +3 4933 4925 4862 +3 4848 4755 4862 +3 4611 4755 4747 +3 4467 4611 4603 +3 4459 4359 4467 +3 4272 4359 4351 +3 4272 4266 4360 +3 4360 4352 4468 +3 4468 4460 4612 +3 4612 4604 4756 +3 4756 4748 4863 +3 4863 4849 4934 +3 4934 4926 5026 +3 5026 5018 5114 +3 5854 5862 5718 +3 6198 6192 6109 +3 5709 5717 5861 +3 5717 5608 5622 +3 5314 5306 5366 +3 5229 5306 5314 +3 5229 5314 5243 +3 5229 5243 5170 +3 5229 5170 5162 +3 5170 5114 5162 +3 5114 5106 5162 +3 5018 5106 5114 +3 4926 5018 5026 +3 4849 4926 4934 +3 4748 4849 4863 +3 4604 4748 4756 +3 4460 4604 4612 +3 4352 4460 4468 +3 4266 4352 4360 +3 4351 4266 4272 +3 4459 4351 4359 +3 4603 4459 4467 +3 4747 4603 4611 +3 4848 4747 4755 +3 4925 4848 4862 +3 5017 4925 4933 +3 5105 5017 5025 +3 5105 5025 5113 +3 5105 5113 5169 +3 5105 5169 5161 +3 5169 5242 5161 +3 5242 5228 5161 +3 5305 5228 5242 +3 5305 5242 5313 +3 5305 5313 5357 +3 5457 5357 5365 +3 5357 5313 5365 +3 5449 5357 5457 +3 5541 5449 5549 +3 5608 5541 5622 +3 5709 5608 5717 +3 5853 5709 5861 +3 5853 5861 6005 +3 5853 6005 5997 +3 6005 6109 5997 +3 6109 6101 5997 +3 6192 6101 6109 +3 6102 6192 6198 +3 6102 6198 6110 +3 6102 6110 6006 +3 6102 6006 5998 +3 6006 5862 5998 +3 5862 5854 5998 +3 5710 5718 5623 +3 5854 5718 5710 +3 5450 5366 5358 +3 5366 5306 5358 +3 5458 5366 5450 +3 5458 5450 5542 +3 5458 5542 5550 +3 5542 5609 5550 +3 5609 5623 5550 +3 5710 5623 5609 +3 5608 5540 5541 +3 5541 5448 5449 +3 5449 5356 5357 +3 5305 5357 5304 +3 5227 5228 5305 +3 5228 5160 5161 +3 5104 5105 5161 +3 4848 4847 4743 +3 4346 4262 4347 +3 4262 4261 4343 +3 4343 4342 4451 +3 4450 4595 4451 +3 4595 4594 4739 +3 4842 4739 4738 +3 4842 4841 4921 +3 4921 4920 5013 +3 5012 5101 5013 +3 5101 5100 5157 +3 5156 5222 5157 +3 5222 5221 5301 +3 5301 5300 5353 +3 5353 5352 5445 +3 5445 5444 5537 +3 5845 5988 5989 +3 5989 6092 6093 +3 6093 6187 6188 +3 6188 6096 6097 +3 5992 5993 6097 +3 5848 5849 5993 +3 5849 5704 5705 +3 5607 5608 5705 +3 5537 5536 5602 +3 5536 5601 5602 +3 5444 5536 5537 +3 5352 5444 5445 +3 5300 5352 5353 +3 5221 5300 5301 +3 5156 5221 5222 +3 5100 5156 5157 +3 5012 5100 5101 +3 4920 5012 5013 +3 4841 4920 4921 +3 4738 4841 4842 +3 4594 4738 4739 +3 4450 4594 4595 +3 4342 4450 4451 +3 4261 4342 4343 +3 4346 4261 4262 +3 4454 4346 4347 +3 4454 4347 4455 +3 4454 4455 4598 +3 4455 4599 4598 +3 4599 4743 4598 +3 4743 4742 4598 +3 4847 4742 4743 +3 4924 4847 4848 +3 4924 4848 4925 +3 4924 4925 5016 +3 5105 5016 5017 +3 5016 4925 5017 +3 5104 5016 5105 +3 5160 5104 5161 +3 5227 5160 5228 +3 5304 5227 5305 +3 5356 5304 5357 +3 5448 5356 5449 +3 5540 5448 5541 +3 5607 5540 5608 +3 5704 5607 5705 +3 5848 5704 5849 +3 5992 5848 5993 +3 6096 5992 6097 +3 6187 6096 6188 +3 6092 6187 6093 +3 5988 6092 5989 +3 5844 5988 5845 +3 5844 5845 5701 +3 5844 5701 5700 +3 5701 5602 5700 +3 5602 5601 5700 +3 3519 3439 3445 +3 3445 3367 3373 +3 2936 3008 3002 +3 2936 2930 2857 +3 2857 2850 2762 +3 2762 2757 2658 +3 2658 2653 2553 +3 2470 2553 2548 +3 2403 2470 2465 +3 2403 2400 2471 +3 2554 2471 2466 +3 2554 2549 2659 +3 2763 2659 2654 +3 2858 2763 2758 +3 2858 2851 2937 +3 2937 2931 3009 +3 3084 3009 3003 +3 3084 3078 3131 +3 3736 3743 3610 +3 4049 4043 3965 +3 3742 3602 3609 +3 3511 3519 3609 +3 3247 3299 3253 +3 3247 3253 3187 +3 3253 3194 3187 +3 3194 3131 3187 +3 3131 3125 3187 +3 3078 3125 3131 +3 3003 3078 3084 +3 2931 3003 3009 +3 2851 2931 2937 +3 2758 2851 2858 +3 2654 2758 2763 +3 2549 2654 2659 +3 2466 2549 2554 +3 2400 2466 2471 +3 2465 2400 2403 +3 2548 2465 2470 +3 2653 2548 2553 +3 2757 2653 2658 +3 2850 2757 2762 +3 2930 2850 2857 +3 3002 2930 2936 +3 3077 3002 3008 +3 3077 3008 3083 +3 3077 3083 3130 +3 3077 3130 3124 +3 3130 3193 3124 +3 3193 3186 3124 +3 3246 3186 3193 +3 3246 3193 3252 +3 3246 3252 3292 +3 3373 3292 3298 +3 3292 3252 3298 +3 3367 3292 3373 +3 3439 3367 3445 +3 3511 3439 3519 +3 3602 3511 3609 +3 3735 3602 3742 +3 3735 3742 3865 +3 3735 3865 3858 +3 3865 3965 3858 +3 3965 3958 3858 +3 4043 3958 3965 +3 3959 4043 4049 +3 3959 4049 3966 +3 3959 3966 3866 +3 3959 3866 3859 +3 3866 3743 3859 +3 3743 3736 3859 +3 3603 3610 3520 +3 3736 3610 3603 +3 3368 3299 3293 +3 3299 3247 3293 +3 3374 3299 3368 +3 3374 3368 3440 +3 3374 3440 3446 +3 3440 3512 3446 +3 3512 3520 3446 +3 3603 3520 3512 +3 3074 2999 3031 +3 3106 3121 3074 +3 3121 3153 3182 +3 3182 3225 3243 +3 3243 3275 3289 +3 3289 3322 3364 +3 3364 3396 3436 +3 3468 3506 3436 +3 3727 3849 3850 +3 3850 3949 3950 +3 4038 4039 3950 +3 3953 3954 4039 +3 3367 3323 3292 +3 3292 3276 3246 +3 3246 3226 3186 +3 3186 3154 3124 +3 3124 3107 3077 +3 3077 3032 3002 +3 3002 2960 2930 +3 2818 2850 2898 +3 2850 2930 2898 +3 2930 2897 2898 +3 2960 2897 2930 +3 3032 2960 3002 +3 3107 3032 3077 +3 3154 3107 3124 +3 3226 3154 3186 +3 3276 3226 3246 +3 3323 3276 3292 +3 3397 3323 3367 +3 3397 3367 3439 +3 3397 3439 3469 +3 3439 3511 3469 +3 3511 3510 3469 +3 3597 3510 3511 +3 3597 3511 3598 +3 3597 3598 3730 +3 3598 3731 3730 +3 3731 3853 3730 +3 3954 3853 3854 +3 3853 3731 3854 +3 3953 3853 3954 +3 4038 3953 4039 +3 3949 4038 3950 +3 3849 3949 3850 +3 3726 3849 3727 +3 3726 3727 3594 +3 3726 3594 3593 +3 3594 3506 3593 +3 3506 3505 3593 +3 3468 3505 3506 +3 3396 3468 3436 +3 3322 3396 3364 +3 3275 3322 3289 +3 3225 3275 3243 +3 3153 3225 3182 +3 3106 3153 3121 +3 3031 3106 3074 +3 2959 3031 2999 +3 2959 2999 2927 +3 2959 2927 2895 +3 2817 2896 2843 +3 2896 2927 2843 +3 2895 2927 2896 +3 8389 7867 8393 +3 8393 7723 8397 +3 8409 8127 8413 +3 8132 8440 8448 +3 7629 8398 7728 +3 7728 8402 7872 +3 8410 8124 8406 +3 8215 8124 8410 +3 8215 8410 8128 +3 8410 8414 8128 +3 8414 8020 8128 +3 7876 8020 8414 +3 7876 8414 8418 +3 7876 8418 7732 +3 8418 8422 7732 +3 8422 7635 7732 +3 7736 7635 8422 +3 7736 8422 8432 +3 7736 8432 7880 +3 8432 8440 7880 +3 8440 8024 7880 +3 8132 8024 8440 +3 8218 8132 8448 +3 8218 8448 8131 +3 8448 8439 8131 +3 8439 8023 8131 +3 7879 8023 8439 +3 7879 8439 8431 +3 7879 8431 7735 +3 8431 8421 7735 +3 8421 7634 7735 +3 7731 7634 8421 +3 7731 8421 8417 +3 7731 8417 7875 +3 8417 8413 7875 +3 8413 8019 7875 +3 8127 8019 8413 +3 8214 8127 8409 +3 8214 8409 8123 +3 8409 8405 8123 +3 8405 8015 8123 +3 7871 8015 8405 +3 7871 8405 8401 +3 7871 8401 7727 +3 8401 8397 7727 +3 8397 7628 7727 +3 7723 7628 8397 +3 7867 7723 8393 +3 8011 7867 8389 +3 8011 8389 8119 +3 8389 8386 8119 +3 8386 8210 8119 +3 8120 8210 8386 +3 8120 8386 8390 +3 8120 8390 8012 +3 7868 8390 8394 +3 8012 8390 7868 +3 7724 8394 8398 +3 7868 8394 7724 +3 7872 8406 8016 +3 8406 8124 8016 +3 8402 8406 7872 +3 8398 8402 7728 +3 7724 8398 7629 +3 95 934 88 +3 84 543 87 +3 96 818 102 +3 102 682 108 +3 116 459 120 +3 132 944 138 +3 138 830 145 +3 152 382 154 +3 896 134 943 +3 134 141 943 +3 141 829 943 +3 693 829 141 +3 693 141 147 +3 693 147 560 +3 147 154 560 +3 154 464 560 +3 382 464 154 +3 465 382 152 +3 465 152 561 +3 152 145 561 +3 145 694 561 +3 830 694 145 +3 944 830 138 +3 824 944 132 +3 824 132 126 +3 824 126 688 +3 126 120 688 +3 120 555 688 +3 459 555 120 +3 378 459 116 +3 378 116 453 +3 116 108 453 +3 108 549 453 +3 682 549 108 +3 818 682 102 +3 935 818 96 +3 935 96 89 +3 935 89 812 +3 89 87 812 +3 87 676 812 +3 543 676 87 +3 447 543 84 +3 447 84 371 +3 84 82 371 +3 82 446 371 +3 542 446 82 +3 542 82 85 +3 542 85 675 +3 85 88 675 +3 88 811 675 +3 934 811 88 +3 895 934 95 +3 1742 2644 1875 +3 1875 2539 2008 +3 2104 2008 2456 +3 2104 2394 2205 +3 2205 2457 2105 +3 2540 2009 2105 +3 2009 2645 1876 +3 1876 2749 1743 +3 1743 2844 1650 +3 2015 2542 2111 +3 2111 2459 2212 +3 2021 2649 1888 +3 1888 2753 1755 +3 1755 2851 1659 +3 2027 2549 2123 +3 2123 2466 2216 +3 2216 2400 2122 +3 2122 2465 2026 +3 2548 1893 2026 +3 1893 2653 1760 +3 2818 1711 1658 +3 2818 1658 2850 +3 1658 1760 2850 +3 1760 2757 2850 +3 2653 2757 1760 +3 2548 2653 1893 +3 2465 2548 2026 +3 2400 2465 2122 +3 2466 2400 2216 +3 2549 2466 2123 +3 2654 2549 2027 +3 2654 2027 1894 +3 2654 1894 2758 +3 1659 2758 1761 +3 2758 1894 1761 +3 2851 2758 1659 +3 2753 2851 1755 +3 2649 2753 1888 +3 2544 2649 2021 +3 2544 2021 2117 +3 2544 2117 2461 +3 2117 2212 2461 +3 2212 2396 2461 +3 2459 2396 2212 +3 2542 2459 2111 +3 2647 2542 2015 +3 2647 2015 1882 +3 2647 1882 2751 +3 1650 2751 1749 +3 2751 1882 1749 +3 2844 2751 1650 +3 2749 2844 1743 +3 2645 2749 1876 +3 2540 2645 2009 +3 2457 2540 2105 +3 2394 2457 2205 +3 2456 2394 2104 +3 2539 2456 2008 +3 2644 2539 1875 +3 2748 2644 1742 +3 2748 1742 2843 +3 1710 2843 1649 +3 2843 1742 1649 +3 2817 2843 1710 +3 3507 4843 3595 +3 3595 4740 3728 +3 3851 3728 4596 +3 3946 3846 4447 +3 3946 4339 4036 +3 4036 4258 3947 +3 3947 4340 3847 +3 3847 4448 3724 +3 3591 3724 4592 +3 3507 3591 4736 +3 3727 4451 4595 +3 4451 3850 4343 +3 4743 3511 4848 +3 3602 4747 4848 +3 4747 3735 4603 +3 3858 4459 4603 +3 4459 3958 4351 +3 4351 4043 4266 +3 4266 3959 4352 +3 4352 3859 4460 +3 4604 4460 3736 +3 4604 3603 4748 +3 4748 3512 4849 +3 4849 3599 4744 +3 3732 4600 4744 +3 3955 4348 3855 +3 4263 4348 3955 +3 4263 3955 4040 +3 4263 4040 3951 +3 4263 3951 4344 +3 3951 3851 4344 +3 3851 4452 4344 +3 4596 4452 3851 +3 4740 4596 3728 +3 4843 4740 3595 +3 4736 4843 3507 +3 4592 4736 3591 +3 4448 4592 3724 +3 4340 4448 3847 +3 4258 4340 3947 +3 4339 4258 4036 +3 4447 4339 3946 +3 4591 3846 3723 +3 4447 3846 4591 +3 4735 3723 3590 +3 4591 3723 4735 +3 4600 3855 4456 +3 3855 4348 4456 +3 3732 3855 4600 +3 3599 3732 4744 +3 3512 3599 4849 +3 3603 3512 4748 +3 3736 3603 4604 +3 3859 3736 4460 +3 3959 3859 4352 +3 4043 3959 4266 +3 3958 4043 4351 +3 3858 3958 4459 +3 3735 3858 4603 +3 3602 3735 4747 +3 3511 3602 4848 +3 3598 3511 4743 +3 3598 4743 4599 +3 3598 4599 3731 +3 4599 4455 3731 +3 4455 3854 3731 +3 3954 3854 4455 +3 3954 4455 4347 +3 3954 4347 4039 +3 4347 4262 4039 +3 4262 4343 4039 +3 4343 3950 4039 +3 3850 3950 4343 +3 3727 3850 4451 +3 3594 3727 4595 +3 3594 4595 4739 +3 3594 4739 3506 +3 4739 4842 3506 +3 4842 3590 3506 +3 4735 3590 4842 +3 5846 5702 6738 +3 5990 5846 6598 +3 5990 6454 6094 +3 6094 6342 6189 +3 6189 6263 6098 +3 6098 6346 5994 +3 5994 6458 5850 +3 6602 5706 5850 +3 5706 6742 5609 +3 5609 6849 5710 +3 5710 6746 5854 +3 5854 6606 5998 +3 5998 6462 6102 +3 6102 6350 6192 +3 6192 6266 6101 +3 6101 6349 5997 +3 5997 6461 5853 +3 5853 6605 5709 +3 5849 6601 5993 +3 6457 6097 5993 +3 5697 6733 5841 +3 5985 6337 6089 +3 6089 6258 6184 +3 6090 6184 6338 +3 6450 5986 6090 +3 5986 6594 5842 +3 6737 5845 6597 +3 6597 5989 6453 +3 6453 6093 6341 +3 6097 6345 6188 +3 6457 6345 6097 +3 6601 6457 5993 +3 6741 6601 5849 +3 6741 5849 5705 +3 6741 5705 6848 +3 5705 5608 6848 +3 5608 5709 6848 +3 5709 6745 6848 +3 6605 6745 5709 +3 6461 6605 5853 +3 6349 6461 5997 +3 6266 6349 6101 +3 6350 6266 6192 +3 6462 6350 6102 +3 6606 6462 5998 +3 6746 6606 5854 +3 6849 6746 5710 +3 6742 6849 5609 +3 6602 6742 5706 +3 6458 6602 5850 +3 6346 6458 5994 +3 6263 6346 6098 +3 6342 6263 6189 +3 6454 6342 6094 +3 6598 6454 5990 +3 6738 6598 5846 +3 6843 6738 5702 +3 6843 5702 5603 +3 6843 5603 6734 +3 5842 6734 5698 +3 6734 5603 5698 +3 6594 6734 5842 +3 6450 6594 5986 +3 6338 6450 6090 +3 6258 6338 6184 +3 6337 6258 6089 +3 6449 6337 5985 +3 6449 5985 6593 +3 5985 5841 6593 +3 5841 6733 6593 +3 6341 6188 6262 +3 6188 6345 6262 +3 6093 6188 6341 +3 5989 6093 6453 +3 5845 5989 6597 +3 5701 5845 6737 +3 5701 6737 6842 +3 5701 6842 5602 +3 6842 5697 5602 +3 6733 5697 6842 +3 7463 7459 7371 +3 7371 7367 7315 +3 7315 7311 7238 +3 7011 7015 7113 +3 7015 6917 6921 +3 6593 6589 6449 +3 6445 6337 6449 +3 6337 6333 6258 +3 6258 6254 6338 +3 6338 6334 6450 +3 6450 6446 6594 +3 6594 6590 6734 +3 6730 6843 6734 +3 7016 7110 7114 +3 7114 7162 7166 +3 7166 7233 7239 +3 8008 8012 7868 +3 8012 8116 8120 +3 8120 8208 8210 +3 8210 8115 8119 +3 8119 8007 8011 +3 8011 7863 7867 +3 7867 7719 7723 +3 7464 7460 7552 +3 7239 7312 7316 +3 7312 7372 7316 +3 7233 7312 7239 +3 7162 7233 7166 +3 7110 7162 7114 +3 7012 7110 7016 +3 7012 7016 6922 +3 7012 6922 6918 +3 6922 6843 6918 +3 6843 6837 6918 +3 6730 6837 6843 +3 6590 6730 6734 +3 6446 6590 6594 +3 6334 6446 6450 +3 6254 6334 6338 +3 6333 6254 6258 +3 6445 6333 6337 +3 6589 6445 6449 +3 6729 6589 6593 +3 6729 6593 6733 +3 6729 6733 6836 +3 6921 6836 6842 +3 6836 6733 6842 +3 6917 6836 6921 +3 7011 6917 7015 +3 7109 7011 7113 +3 7109 7113 7165 +3 7109 7165 7161 +3 7165 7238 7161 +3 7238 7232 7161 +3 7311 7232 7238 +3 7367 7311 7315 +3 7459 7367 7371 +3 7551 7459 7463 +3 7551 7463 7555 +3 7551 7555 7622 +3 7723 7622 7628 +3 7622 7555 7628 +3 7719 7622 7723 +3 7863 7719 7867 +3 8007 7863 8011 +3 8115 8007 8119 +3 8208 8115 8210 +3 8116 8208 8120 +3 8008 8116 8012 +3 7864 8008 7868 +3 7864 7868 7724 +3 7864 7724 7720 +3 7460 7372 7368 +3 7372 7312 7368 +3 7464 7372 7460 +3 7556 7464 7552 +3 7556 7552 7623 +3 7556 7623 7629 +3 7623 7724 7629 +3 7720 7724 7623 +3 7367 7366 7311 +3 7311 7310 7232 +3 7109 7010 7011 +3 7011 6916 6917 +3 6835 6836 6917 +3 6437 6436 6325 +3 6325 6324 6248 +3 6429 6572 6573 +3 6573 6712 6713 +3 6825 6826 6713 +3 7101 7100 7153 +3 7707 7612 7706 +3 7707 7706 7851 +3 8103 8102 8204 +3 7858 7859 8003 +3 7859 7714 7715 +3 7715 7621 7622 +3 7450 7359 7358 +3 7358 7303 7302 +3 7153 7152 7222 +3 7100 7152 7153 +3 7002 7100 7101 +3 7002 7101 7003 +3 7002 7003 6908 +3 6826 6908 6909 +3 6908 7003 6909 +3 6825 6908 6826 +3 6712 6825 6713 +3 6572 6712 6573 +3 6428 6572 6429 +3 6428 6429 6317 +3 6428 6317 6316 +3 6317 6248 6316 +3 6248 6247 6316 +3 6324 6247 6248 +3 6436 6324 6325 +3 6580 6436 6437 +3 6580 6437 6581 +3 6580 6581 6720 +3 6836 6720 6721 +3 6720 6581 6721 +3 6835 6720 6836 +3 6916 6835 6917 +3 7010 6916 7011 +3 7108 7010 7109 +3 7108 7109 7161 +3 7108 7161 7160 +3 7161 7232 7160 +3 7232 7231 7160 +3 7310 7231 7232 +3 7366 7310 7311 +3 7458 7366 7367 +3 7458 7367 7459 +3 7458 7459 7550 +3 7622 7550 7551 +3 7550 7459 7551 +3 7621 7550 7622 +3 7714 7621 7715 +3 7858 7714 7859 +3 8002 7858 8003 +3 8002 8003 8111 +3 8002 8111 8110 +3 8111 8204 8110 +3 8204 8203 8110 +3 8102 8203 8204 +3 7994 8102 8103 +3 7994 8103 7995 +3 7994 7995 7850 +3 7995 7851 7850 +3 7851 7706 7850 +3 7302 7222 7221 +3 7222 7152 7221 +3 7303 7222 7302 +3 7359 7303 7358 +3 7451 7359 7450 +3 7451 7450 7542 +3 7451 7542 7543 +3 7542 7611 7543 +3 7611 7612 7543 +3 7706 7612 7611 +3 5537 5533 5445 +3 5445 5441 5353 +3 5301 5353 5349 +3 5157 5097 5101 +3 5009 5013 5101 +3 4917 4921 5013 +3 4591 4587 4447 +3 4258 4336 4340 +3 4340 4444 4448 +3 4588 4592 4448 +3 4592 4732 4736 +3 4837 4843 4736 +3 4918 4922 4843 +3 5010 5014 4922 +3 5014 5098 5102 +3 5154 5158 5102 +3 5158 5217 5223 +3 5223 5298 5302 +3 5302 5350 5354 +3 5354 5442 5446 +3 5986 6086 6090 +3 6090 6180 6184 +3 6184 6085 6089 +3 6089 5981 5985 +3 5985 5837 5841 +3 5693 5697 5841 +3 5597 5698 5603 +3 5597 5603 5534 +3 5446 5534 5538 +3 5534 5603 5538 +3 5442 5534 5446 +3 5350 5442 5354 +3 5298 5350 5302 +3 5217 5298 5223 +3 5154 5217 5158 +3 5098 5154 5102 +3 5010 5098 5014 +3 4918 5010 4922 +3 4837 4918 4843 +3 4732 4837 4736 +3 4588 4732 4592 +3 4444 4588 4448 +3 4336 4444 4340 +3 4254 4336 4258 +3 4254 4258 4339 +3 4254 4339 4335 +3 4339 4447 4335 +3 4447 4443 4335 +3 4587 4443 4447 +3 4731 4587 4591 +3 4731 4591 4735 +3 4731 4735 4836 +3 4921 4836 4842 +3 4836 4735 4842 +3 4917 4836 4921 +3 5009 4917 5013 +3 5097 5009 5101 +3 5153 5097 5157 +3 5153 5157 5222 +3 5153 5222 5216 +3 5222 5301 5216 +3 5301 5297 5216 +3 5349 5297 5301 +3 5441 5349 5353 +3 5533 5441 5445 +3 5596 5533 5537 +3 5697 5596 5602 +3 5596 5537 5602 +3 5693 5596 5697 +3 5837 5693 5841 +3 5981 5837 5985 +3 6085 5981 6089 +3 6180 6085 6184 +3 6086 6180 6090 +3 5982 6086 5986 +3 5982 5986 5842 +3 5982 5842 5838 +3 5842 5698 5838 +3 5698 5694 5838 +3 5597 5694 5698 +3 5596 5595 5533 +3 5533 5532 5441 +3 5441 5440 5349 +3 5349 5348 5297 +3 5153 5096 5097 +3 5097 5008 5009 +3 4916 4917 5009 +3 4917 4835 4836 +3 4836 4722 4723 +3 4327 4326 4248 +3 4248 4247 4319 +3 4319 4318 4427 +3 4571 4427 4426 +3 4571 4570 4715 +3 4715 4714 4826 +3 4826 4825 4909 +3 4909 4908 5001 +3 5001 5000 5089 +3 5089 5088 5145 +3 5145 5144 5206 +3 5206 5205 5289 +3 6174 6069 6173 +3 6174 6173 6077 +3 6077 6076 5973 +3 5973 5972 5829 +3 5828 5685 5829 +3 5685 5684 5596 +3 5289 5288 5341 +3 5205 5288 5289 +3 5144 5205 5206 +3 5088 5144 5145 +3 5000 5088 5089 +3 4908 5000 5001 +3 4825 4908 4909 +3 4714 4825 4826 +3 4570 4714 4715 +3 4426 4570 4571 +3 4318 4426 4427 +3 4247 4318 4319 +3 4326 4247 4248 +3 4434 4326 4327 +3 4434 4327 4435 +3 4434 4435 4578 +3 4723 4578 4579 +3 4578 4435 4579 +3 4722 4578 4723 +3 4835 4722 4836 +3 4916 4835 4917 +3 5008 4916 5009 +3 5096 5008 5097 +3 5152 5096 5153 +3 5152 5153 5216 +3 5152 5216 5215 +3 5216 5297 5215 +3 5297 5296 5215 +3 5348 5296 5297 +3 5440 5348 5349 +3 5532 5440 5441 +3 5595 5532 5533 +3 5684 5595 5596 +3 5828 5684 5685 +3 5972 5828 5829 +3 6076 5972 5973 +3 6173 6076 6077 +3 6068 6069 5965 +3 6173 6069 6068 +3 5964 5965 5821 +3 6068 5965 5964 +3 5820 5821 5677 +3 5964 5821 5820 +3 5676 5677 5586 +3 5820 5677 5676 +3 5432 5341 5340 +3 5341 5288 5340 +3 5433 5341 5432 +3 5433 5432 5524 +3 5433 5524 5525 +3 5524 5585 5525 +3 5585 5586 5525 +3 5676 5586 5585 +3 3506 3434 3436 +3 3436 3362 3364 +3 3364 3287 3289 +3 3241 3243 3289 +3 3243 3179 3182 +3 3182 3119 3121 +3 3121 3072 3074 +3 2839 2843 2927 +3 2539 2537 2456 +3 2456 2454 2394 +3 2394 2393 2457 +3 2457 2455 2540 +3 2540 2538 2645 +3 2643 2749 2645 +3 2749 2747 2844 +3 3000 3073 3075 +3 3075 3120 3122 +3 3288 3365 3290 +3 3365 3363 3437 +3 3507 3587 3591 +3 3591 3720 3724 +3 3843 3847 3724 +3 3943 3947 3847 +3 3947 4034 4036 +3 3942 3946 4036 +3 3946 3842 3846 +3 3719 3723 3846 +3 3723 3586 3590 +3 3590 3501 3506 +3 3437 3435 3507 +3 3435 3502 3507 +3 3363 3435 3437 +3 3288 3363 3365 +3 3242 3288 3290 +3 3242 3290 3244 +3 3242 3244 3180 +3 3122 3180 3183 +3 3180 3244 3183 +3 3120 3180 3122 +3 3073 3120 3075 +3 2998 3073 3000 +3 2998 3000 2928 +3 2998 2928 2926 +3 2928 2844 2926 +3 2844 2840 2926 +3 2747 2840 2844 +3 2643 2747 2749 +3 2538 2643 2645 +3 2455 2538 2540 +3 2393 2455 2457 +3 2454 2393 2394 +3 2537 2454 2456 +3 2642 2537 2539 +3 2642 2539 2644 +3 2642 2644 2746 +3 2843 2746 2748 +3 2746 2644 2748 +3 2839 2746 2843 +3 2925 2839 2927 +3 2925 2927 2997 +3 3074 2997 2999 +3 2997 2927 2999 +3 3072 2997 3074 +3 3119 3072 3121 +3 3179 3119 3182 +3 3241 3179 3243 +3 3287 3241 3289 +3 3362 3287 3364 +3 3434 3362 3436 +3 3501 3434 3506 +3 3586 3501 3590 +3 3719 3586 3723 +3 3842 3719 3846 +3 3942 3842 3946 +3 4034 3942 4036 +3 3943 4034 3947 +3 3843 3943 3847 +3 3720 3843 3724 +3 3587 3720 3591 +3 3502 3587 3507 +3 3320 3287 3362 +3 3241 3287 3273 +3 3241 3223 3179 +3 3179 3151 3119 +3 3119 3104 3072 +3 3029 2997 3072 +3 2638 2533 2616 +3 2638 2700 2742 +3 2804 2836 2742 +3 2836 2835 2923 +3 2923 2922 2995 +3 2994 3070 2995 +3 3070 3069 3117 +3 3117 3116 3176 +3 3176 3175 3239 +3 3360 3431 3432 +3 3432 3492 3493 +3 3493 3574 3575 +3 3707 3708 3575 +3 3708 3830 3831 +3 3831 3930 3931 +3 3837 3715 3838 +3 3715 3714 3582 +3 3582 3581 3501 +3 2434 2452 2515 +3 2535 2620 2515 +3 2704 2620 2640 +3 2744 2808 2704 +3 2808 2839 2890 +3 2997 2957 2925 +3 3029 2957 2997 +3 3104 3029 3072 +3 3151 3104 3119 +3 3223 3151 3179 +3 3273 3223 3241 +3 3320 3273 3287 +3 3394 3320 3362 +3 3394 3362 3434 +3 3394 3434 3466 +3 3434 3501 3466 +3 3501 3500 3466 +3 3581 3500 3501 +3 3714 3581 3582 +3 3837 3714 3715 +3 3937 3837 3838 +3 3937 3838 3938 +3 3937 3938 4029 +3 3931 4029 4030 +3 4029 3938 4030 +3 3930 4029 3931 +3 3830 3930 3831 +3 3707 3830 3708 +3 3574 3707 3575 +3 3492 3574 3493 +3 3431 3492 3432 +3 3359 3431 3360 +3 3359 3360 3285 +3 3359 3285 3284 +3 3285 3239 3284 +3 3239 3238 3284 +3 3175 3238 3239 +3 3116 3175 3176 +3 3069 3116 3117 +3 2994 3069 3070 +3 2922 2994 2995 +3 2835 2922 2923 +3 2804 2835 2836 +3 2700 2804 2742 +3 2616 2700 2638 +3 2441 2616 2533 +3 2890 2925 2889 +3 2925 2957 2889 +3 2839 2925 2890 +3 2744 2839 2808 +3 2640 2744 2704 +3 2535 2640 2620 +3 2452 2535 2515 +3 2390 2452 2434 +3 2390 2434 2433 +3 2390 2433 2450 +3 2433 2437 2450 +3 2437 2442 2450 +3 2442 2533 2450 +3 2441 2533 2442 +3 8352 8104 8342 +3 8302 8095 8309 +3 8351 8111 8359 +3 8384 8116 8382 +3 7708 7613 8326 +3 7708 8326 8334 +3 7708 8334 7852 +3 8334 8342 7852 +3 8342 7996 7852 +3 8104 7996 8342 +3 8205 8104 8352 +3 8205 8352 8112 +3 8352 8360 8112 +3 8360 8004 8112 +3 7860 8004 8360 +3 7860 8360 8370 +3 7860 8370 7716 +3 8370 8374 7716 +3 8374 7623 7716 +3 7720 7623 8374 +3 7720 8374 8378 +3 7720 8378 7864 +3 8378 8382 7864 +3 8382 8008 7864 +3 8116 8008 8382 +3 8208 8116 8384 +3 8208 8384 8115 +3 8384 8381 8115 +3 8381 8007 8115 +3 7863 8007 8381 +3 7863 8381 8377 +3 7863 8377 7719 +3 8377 8373 7719 +3 8373 7622 7719 +3 7715 7622 8373 +3 7715 8373 8369 +3 7715 8369 7859 +3 8369 8359 7859 +3 8359 8003 7859 +3 8111 8003 8359 +3 8204 8111 8351 +3 8204 8351 8103 +3 8351 8341 8103 +3 8341 7995 8103 +3 7851 7995 8341 +3 7851 8341 8333 +3 7851 8333 7707 +3 8333 8325 7707 +3 8325 7612 7707 +3 7699 7612 8325 +3 7699 8325 8317 +3 7699 8317 7843 +3 8317 8309 7843 +3 8309 7987 7843 +3 8095 7987 8309 +3 8196 8095 8302 +3 8196 8302 8096 +3 8302 8310 8096 +3 8310 7988 8096 +3 7844 7988 8310 +3 7844 8310 8318 +3 7844 8318 7700 +3 8318 8326 7700 +3 8326 7613 7700 +3 75 444 73 +3 54 439 44 +3 5 437 13 +3 45 536 440 +3 669 536 45 +3 669 45 37 +3 669 37 805 +3 37 29 805 +3 29 922 805 +3 802 922 29 +3 802 29 21 +3 802 21 666 +3 21 13 666 +3 13 533 666 +3 437 533 13 +3 364 437 5 +3 364 5 436 +3 5 12 436 +3 12 532 436 +3 665 532 12 +3 665 12 20 +3 665 20 801 +3 20 28 801 +3 28 921 801 +3 804 921 28 +3 804 28 36 +3 804 36 668 +3 36 44 668 +3 44 535 668 +3 439 535 44 +3 367 439 54 +3 367 54 442 +3 54 60 442 +3 60 538 442 +3 671 538 60 +3 671 60 64 +3 671 64 807 +3 64 67 807 +3 67 925 807 +3 809 925 67 +3 809 67 71 +3 809 71 673 +3 71 73 673 +3 73 540 673 +3 444 540 73 +3 370 444 75 +3 370 75 445 +3 75 74 445 +3 74 541 445 +3 674 541 74 +3 674 74 72 +3 674 72 810 +3 72 68 810 +3 68 926 810 +3 808 926 68 +3 808 68 65 +3 808 65 672 +3 65 61 672 +3 61 539 672 +3 443 539 61 +3 443 61 55 +3 443 55 368 +3 55 440 368 +3 45 440 55 +3 2743 1737 1638 +3 1737 2639 1870 +3 2003 1870 2534 +3 2003 2451 2099 +3 2099 2391 2202 +3 1739 2840 1641 +3 2103 2455 2204 +3 2204 2393 2102 +3 2102 2454 2006 +3 2537 1873 2006 +3 1873 2642 1740 +3 1740 2746 1640 +3 1640 2839 1738 +3 1738 2744 1871 +3 2640 2004 1871 +3 2004 2535 2100 +3 2000 2448 2096 +3 2096 2389 2200 +3 2200 2449 2097 +3 2532 2001 2097 +3 1868 2001 2637 +3 1735 1868 2741 +3 1735 2837 1638 +3 2742 1869 2638 +3 2638 2002 2533 +3 2098 2201 2390 +3 2201 2100 2390 +3 2100 2452 2390 +3 2535 2452 2100 +3 2640 2535 2004 +3 2744 2640 1871 +3 2839 2744 1738 +3 2746 2839 1640 +3 2642 2746 1740 +3 2537 2642 1873 +3 2454 2537 2006 +3 2393 2454 2102 +3 2455 2393 2204 +3 2538 2455 2103 +3 2538 2103 2007 +3 2538 2007 2643 +3 2007 1874 2643 +3 1874 2747 2643 +3 1641 2747 1741 +3 2747 1874 1741 +3 2840 2747 1641 +3 2745 2840 1739 +3 2745 1739 2641 +3 2005 2641 1872 +3 2641 1739 1872 +3 2536 2641 2005 +3 2536 2005 2453 +3 2202 2453 2101 +3 2453 2005 2101 +3 2391 2453 2202 +3 2451 2391 2099 +3 2534 2451 2003 +3 2639 2534 1870 +3 2743 2639 1737 +3 2837 2743 1638 +3 2741 2837 1735 +3 2637 2741 1868 +3 2532 2637 2001 +3 2449 2532 2097 +3 2389 2449 2200 +3 2448 2389 2096 +3 2531 2448 2000 +3 2531 2000 1867 +3 2531 1867 2636 +3 2740 1867 1734 +3 2636 1867 2740 +3 2533 2098 2450 +3 2098 2390 2450 +3 2002 2098 2533 +3 1869 2002 2638 +3 1736 1869 2742 +3 1736 2742 2836 +3 1736 2836 1637 +3 2836 1734 1637 +3 2740 1734 2836 +3 3494 4827 3576 +3 3576 4716 3709 +3 4572 3832 3709 +3 3832 4428 3932 +3 4031 3932 4320 +3 4031 4249 3939 +3 3839 3939 4328 +3 4436 3716 3839 +3 3583 3716 4580 +3 3502 3583 4724 +3 3502 4837 3587 +3 4732 3720 3587 +3 3843 3720 4588 +3 3843 4444 3943 +3 4443 3842 3942 +3 3719 3842 4587 +3 3719 4731 3586 +3 3586 4836 3501 +3 4723 3582 3501 +3 3582 4579 3715 +3 4435 3838 3715 +3 4030 4248 3931 +3 3568 4707 3701 +3 3701 4563 3824 +3 4419 3924 3824 +3 3924 4311 4024 +3 4024 4240 3925 +3 3825 3925 4312 +3 3702 3825 4420 +3 3569 3702 4564 +3 3494 3569 4708 +3 4826 3568 3493 +3 4826 3493 4715 +3 3708 4715 3575 +3 4715 3493 3575 +3 4571 4715 3708 +3 4571 3708 3831 +3 4571 3831 4427 +3 3831 3931 4427 +3 3931 4319 4427 +3 4248 4319 3931 +3 4327 4248 4030 +3 3838 4327 3938 +3 4327 4030 3938 +3 4435 4327 3838 +3 4579 4435 3715 +3 4723 4579 3582 +3 4836 4723 3501 +3 4731 4836 3586 +3 4587 4731 3719 +3 4443 4587 3842 +3 4335 4443 3942 +3 4335 3942 4254 +3 3942 4034 4254 +3 4034 3943 4254 +3 3943 4336 4254 +3 4444 4336 3943 +3 4588 4444 3843 +3 4732 4588 3720 +3 4837 4732 3587 +3 4724 4837 3502 +3 4580 4724 3583 +3 4436 4580 3716 +3 4328 4436 3839 +3 4249 4328 3939 +3 4320 4249 4031 +3 4428 4320 3932 +3 4572 4428 3832 +3 4716 4572 3709 +3 4827 4716 3576 +3 4708 4827 3494 +3 4564 4708 3569 +3 4420 4564 3702 +3 4312 4420 3825 +3 4240 4312 3925 +3 4311 4240 4024 +3 4419 4311 3924 +3 4563 4419 3824 +3 4707 4563 3701 +3 4826 4707 3568 +3 6078 6175 6249 +3 6078 6326 5974 +3 5830 5974 6438 +3 5830 6582 5686 +3 6722 5597 5686 +3 5597 6837 5694 +3 5694 6730 5838 +3 5838 6590 5982 +3 6446 6086 5982 +3 6086 6334 6180 +3 6180 6254 6085 +3 6085 6333 5981 +3 6445 5837 5981 +3 5685 6721 5829 +3 5829 6581 5973 +3 5973 6437 6077 +3 5669 6705 5813 +3 6061 6240 6166 +3 6166 6310 6062 +3 6422 5958 6062 +3 5958 6566 5814 +3 6706 5670 5814 +3 5670 6827 5587 +3 6713 5821 6573 +3 6573 5965 6429 +3 6317 6429 6069 +3 6077 6325 6174 +3 6437 6325 6077 +3 6581 6437 5973 +3 6721 6581 5829 +3 6836 6721 5685 +3 6836 5685 5596 +3 6836 5596 6729 +3 5596 5693 6729 +3 5693 5837 6729 +3 5837 6589 6729 +3 6445 6589 5837 +3 6333 6445 5981 +3 6254 6333 6085 +3 6334 6254 6180 +3 6446 6334 6086 +3 6590 6446 5982 +3 6730 6590 5838 +3 6837 6730 5694 +3 6722 6837 5597 +3 6582 6722 5686 +3 6438 6582 5830 +3 6326 6438 5974 +3 6249 6326 6078 +3 6318 6249 6175 +3 6318 6175 6070 +3 6318 6070 6430 +3 5822 6430 5966 +3 6430 6070 5966 +3 6574 6430 5822 +3 6574 5822 6714 +3 5587 6714 5678 +3 6714 5822 5678 +3 6827 6714 5587 +3 6706 6827 5670 +3 6566 6706 5814 +3 6422 6566 5958 +3 6310 6422 6062 +3 6240 6310 6166 +3 6309 6240 6061 +3 6309 6061 5957 +3 6309 5957 6421 +3 5957 5813 6421 +3 5813 6565 6421 +3 6705 6565 5813 +3 6317 6174 6248 +3 6174 6325 6248 +3 6069 6174 6317 +3 5965 6069 6429 +3 5821 5965 6573 +3 5677 5821 6713 +3 5677 6713 6826 +3 5677 6826 5586 +3 6826 5669 5586 +3 6705 5669 6826 +3 1296 1288 1234 +3 1022 951 1028 +3 951 942 890 +3 754 890 889 +3 753 652 754 +3 652 651 520 +3 651 519 520 +3 753 651 652 +3 889 753 754 +3 942 889 890 +3 1022 942 951 +3 1102 1022 1028 +3 1102 1028 1108 +3 1102 1108 1180 +3 1108 1186 1180 +3 1186 1234 1180 +3 1234 1228 1180 +3 1288 1228 1234 +3 1358 1288 1296 +3 1358 1296 1364 +3 1358 1364 1410 +3 1498 1410 1416 +3 1410 1364 1416 +3 1492 1410 1498 +3 1492 1498 1582 +3 1492 1582 1576 +3 1582 1666 1576 +3 1666 1657 1576 +3 1719 1657 1666 +3 1719 1666 1720 +3 1719 1720 1852 +3 1719 1852 1851 +3 1852 1956 1851 +3 1956 1955 1851 +3 2088 1955 1956 +3 2088 1956 2089 +3 1667 1614 1712 +3 897 995 952 +3 996 898 961 +3 1615 1676 1713 +3 1926 1918 2051 +3 1918 1793 1785 +3 1505 1513 1423 +3 1423 1431 1371 +3 1371 1379 1305 +3 1241 1305 1317 +3 1115 1043 1035 +3 585 593 490 +3 490 498 396 +3 396 400 489 +3 489 497 584 +3 592 717 584 +3 717 725 853 +3 853 861 961 +3 1210 1248 1307 +3 1596 1686 1607 +3 1512 1470 1430 +3 1430 1389 1378 +3 1200 1210 1132 +3 1248 1210 1200 +3 1051 1122 1085 +3 1122 1132 1085 +3 1200 1132 1122 +3 1001 1042 1004 +3 1042 1051 1004 +3 1122 1051 1042 +3 971 1001 998 +3 1042 1001 971 +3 996 961 997 +3 961 971 997 +3 971 998 997 +3 861 971 961 +3 725 861 853 +3 592 725 717 +3 497 592 584 +3 400 497 489 +3 498 400 396 +3 593 498 490 +3 726 593 585 +3 726 585 718 +3 726 718 862 +3 718 854 862 +3 854 972 862 +3 1035 972 962 +3 972 854 962 +3 1043 972 1035 +3 1123 1043 1115 +3 1123 1115 1193 +3 1123 1193 1201 +3 1193 1241 1201 +3 1241 1249 1201 +3 1317 1249 1241 +3 1379 1317 1305 +3 1431 1379 1371 +3 1513 1431 1423 +3 1597 1513 1505 +3 1597 1505 1589 +3 1597 1589 1687 +3 1785 1687 1677 +3 1687 1589 1677 +3 1793 1687 1785 +3 1926 1793 1918 +3 2059 1926 2051 +3 2059 2051 2148 +3 2059 2148 2156 +3 2234 2148 2230 +3 2156 2148 2234 +3 2050 2155 2147 +3 2155 2230 2147 +3 2234 2230 2155 +3 2058 2050 1917 +3 2155 2050 2058 +3 1925 1917 1784 +3 2058 1917 1925 +3 1792 1784 1676 +3 1925 1784 1792 +3 1378 1307 1316 +3 1307 1248 1316 +3 1389 1307 1378 +3 1470 1389 1430 +3 1521 1470 1512 +3 1521 1512 1557 +3 1512 1596 1557 +3 1596 1604 1557 +3 1607 1604 1596 +3 1610 1607 1686 +3 1610 1686 1616 +3 1686 1676 1616 +3 1676 1615 1616 +3 1792 1676 1686 +3 1649 1612 1710 +3 934 895 993 +3 994 896 943 +3 1613 1658 1711 +3 1893 1899 2026 +3 2123 2129 2027 +3 1761 1668 1659 +3 1659 1583 1577 +3 1499 1493 1577 +3 1493 1417 1411 +3 1411 1365 1359 +3 1359 1297 1289 +3 1289 1235 1229 +3 1229 1187 1181 +3 1181 1109 1103 +3 830 944 953 +3 694 830 836 +3 694 700 561 +3 465 561 567 +3 471 382 465 +3 382 385 464 +3 560 464 470 +3 560 566 693 +3 693 699 829 +3 829 835 943 +3 943 952 994 +3 952 995 994 +3 835 952 943 +3 699 835 829 +3 566 699 693 +3 470 566 560 +3 385 470 464 +3 471 385 382 +3 567 471 465 +3 700 567 561 +3 836 700 694 +3 953 836 830 +3 1029 953 944 +3 1103 1029 1023 +3 1029 944 1023 +3 1109 1029 1103 +3 1187 1109 1181 +3 1235 1187 1229 +3 1297 1235 1289 +3 1365 1297 1359 +3 1417 1365 1411 +3 1499 1417 1493 +3 1583 1499 1577 +3 1668 1583 1659 +3 1767 1668 1761 +3 1767 1761 1894 +3 1767 1894 1900 +3 1894 2027 1900 +3 2027 2033 1900 +3 2129 2033 2027 +3 2219 2129 2123 +3 2219 2123 2216 +3 2219 2216 2122 +3 2219 2122 2128 +3 2122 2026 2128 +3 2026 2032 2128 +3 1899 2032 2026 +3 1766 1899 1893 +3 1766 1893 1760 +3 1766 1760 1667 +3 1760 1658 1667 +3 1658 1613 1667 +3 1613 1614 1667 +3 1740 1875 1873 +3 2006 1873 2008 +3 2102 2006 2104 +3 2102 2205 2204 +3 2105 2103 2204 +3 2103 2009 2007 +3 2007 1876 1874 +3 1874 1743 1741 +3 1487 1403 1485 +3 1403 1405 1351 +3 1351 1353 1277 +3 1095 1173 1097 +3 1095 1017 1015 +3 674 676 541 +3 543 445 541 +3 445 447 370 +3 370 371 444 +3 444 446 540 +3 540 542 673 +3 809 673 675 +3 999 1002 925 +3 999 925 992 +3 993 992 934 +3 992 925 934 +3 925 809 934 +3 809 811 934 +3 675 811 809 +3 542 675 673 +3 446 542 540 +3 371 446 444 +3 447 371 370 +3 543 447 445 +3 676 543 541 +3 812 676 674 +3 812 674 810 +3 812 810 935 +3 1015 935 926 +3 935 810 926 +3 1017 935 1015 +3 1097 1017 1095 +3 1175 1097 1173 +3 1175 1173 1221 +3 1175 1221 1223 +3 1221 1277 1223 +3 1277 1281 1223 +3 1353 1281 1277 +3 1405 1353 1351 +3 1487 1405 1403 +3 1571 1487 1485 +3 1571 1485 1569 +3 1571 1569 1650 +3 1741 1650 1641 +3 1650 1569 1641 +3 1743 1650 1741 +3 1876 1743 1874 +3 2009 1876 2007 +3 2105 2009 2103 +3 2205 2105 2204 +3 2104 2205 2102 +3 2008 2104 2006 +3 1875 2008 1873 +3 1742 1875 1740 +3 1742 1740 1640 +3 1742 1640 1649 +3 1640 1611 1649 +3 1611 1612 1649 +3 1609 1611 1640 +3 1609 1640 1606 +3 1636 1567 1566 +3 1400 1349 1348 +3 1092 1170 1171 +3 1012 1092 1093 +3 1012 1013 920 +3 920 921 887 +3 751 887 804 +3 751 668 648 +3 420 442 524 +3 524 538 655 +3 757 655 671 +3 757 807 893 +3 893 925 1002 +3 807 925 893 +3 671 807 757 +3 538 671 655 +3 442 538 524 +3 367 442 420 +3 367 420 418 +3 367 418 439 +3 418 421 439 +3 421 427 439 +3 427 535 439 +3 648 535 426 +3 535 427 426 +3 668 535 648 +3 804 668 751 +3 921 804 887 +3 1013 921 920 +3 1093 1013 1012 +3 1171 1093 1092 +3 1219 1171 1170 +3 1219 1170 1218 +3 1219 1218 1274 +3 1348 1274 1273 +3 1274 1218 1273 +3 1349 1274 1348 +3 1401 1349 1400 +3 1401 1400 1482 +3 1401 1482 1483 +3 1482 1566 1483 +3 1566 1567 1483 +3 1637 1636 1726 +3 1567 1636 1637 +3 1736 1726 1858 +3 1637 1726 1736 +3 1869 1858 1964 +3 1736 1858 1869 +3 2002 1964 2182 +3 1869 1964 2002 +3 2098 2190 2201 +3 2201 2187 2100 +3 2100 2081 2004 +3 2004 1949 1871 +3 1871 1847 1738 +3 1738 1714 1640 +3 1714 1606 1640 +3 1847 1714 1738 +3 1949 1847 1871 +3 2081 1949 2004 +3 2187 2081 2100 +3 2190 2187 2201 +3 2184 2190 2098 +3 2184 2098 2183 +3 2098 2002 2183 +3 2002 2182 2183 +3 2956 2958 3028 +3 3028 3030 3103 +3 3222 3274 3272 +3 3272 3321 3319 +3 3319 3395 3393 +3 3467 3465 3393 +3 3465 3504 3499 +3 3941 4033 3945 +3 3941 3845 3841 +3 3841 3722 3718 +3 3500 3468 3466 +3 3466 3396 3394 +3 3394 3322 3320 +3 3320 3275 3273 +3 3273 3225 3223 +3 3223 3153 3151 +3 3151 3106 3104 +3 3104 3031 3029 +3 3029 2959 2957 +3 2957 2895 2889 +3 2959 2895 2957 +3 3031 2959 3029 +3 3106 3031 3104 +3 3153 3106 3151 +3 3225 3153 3223 +3 3275 3225 3273 +3 3322 3275 3320 +3 3396 3322 3394 +3 3468 3396 3466 +3 3505 3468 3500 +3 3505 3500 3589 +3 3718 3589 3585 +3 3589 3500 3585 +3 3722 3589 3718 +3 3845 3722 3841 +3 3945 3845 3941 +3 4035 3945 4033 +3 4035 4033 3940 +3 4035 3940 3944 +3 3940 3840 3944 +3 3840 3844 3944 +3 3721 3844 3840 +3 3721 3840 3717 +3 3721 3717 3588 +3 3499 3588 3584 +3 3588 3717 3584 +3 3504 3588 3499 +3 3467 3504 3465 +3 3395 3467 3393 +3 3321 3395 3319 +3 3274 3321 3272 +3 3224 3274 3222 +3 3224 3222 3150 +3 3224 3150 3152 +3 3150 3103 3152 +3 3103 3105 3152 +3 3030 3105 3103 +3 2958 3030 3028 +3 2894 2958 2956 +3 2894 2956 2888 +3 3695 3692 3665 +3 3559 3665 3659 +3 3559 3555 3498 +3 3555 3478 3498 +3 3659 3555 3559 +3 3692 3659 3665 +3 3798 3692 3695 +3 2351 1880 1747 +3 1886 2710 1753 +3 1656 1753 2814 +3 1759 1656 2848 +3 1759 2756 1892 +3 1892 2652 2025 +3 2025 2547 2121 +3 2121 2464 2215 +3 2120 2215 2399 +3 2120 2463 2024 +3 2546 1891 2024 +3 1655 2813 1752 +3 1885 1752 2709 +3 2626 2018 1885 +3 2286 1646 1746 +3 1706 1646 2286 +3 2350 1746 1879 +3 2286 1746 2350 +3 2108 2364 2012 +3 2364 1879 2012 +3 2350 1879 2364 +3 2521 2108 2209 +3 2364 2108 2521 +3 2018 2521 2114 +3 2521 2209 2114 +3 2626 2521 2018 +3 2709 2626 1885 +3 2813 2709 1752 +3 2847 2813 1655 +3 2847 1655 2755 +3 1655 1758 2755 +3 1758 1891 2755 +3 1891 2651 2755 +3 2546 2651 1891 +3 2463 2546 2024 +3 2399 2463 2120 +3 2464 2399 2215 +3 2547 2464 2121 +3 2652 2547 2025 +3 2756 2652 1892 +3 2848 2756 1759 +3 2814 2848 1656 +3 2710 2814 1753 +3 2627 2710 1886 +3 2627 1886 2019 +3 2627 2019 2522 +3 2019 2115 2522 +3 2115 2210 2522 +3 2210 2109 2522 +3 2109 2365 2522 +3 1880 2365 2013 +3 2365 2109 2013 +3 2351 2365 1880 +3 1707 2287 1647 +3 2287 1747 1647 +3 2351 1747 2287 +3 990 932 903 +3 902 931 989 +3 1646 1706 1619 +3 1647 1620 1707 +3 678 679 545 +3 545 546 449 +3 449 450 374 +3 374 375 455 +3 684 821 820 +3 820 940 939 +3 1020 1019 939 +3 1019 1100 1099 +3 1177 1099 1178 +3 1226 1225 1177 +3 1225 1286 1285 +3 1489 1490 1573 +3 1573 1574 1654 +3 1654 1655 1751 +3 1751 1752 1884 +3 1884 1885 2017 +3 2017 2018 2113 +3 2012 2011 2107 +3 1879 1878 2011 +3 1878 1746 1745 +3 1646 1619 1618 +3 1745 1646 1645 +3 1646 1618 1645 +3 1746 1646 1745 +3 1879 1746 1878 +3 2012 1879 2011 +3 2108 2012 2107 +3 2108 2107 2209 +3 2107 2208 2209 +3 2208 2113 2209 +3 2113 2114 2209 +3 2018 2114 2113 +3 1885 2018 2017 +3 1752 1885 1884 +3 1655 1752 1751 +3 1574 1655 1654 +3 1490 1574 1573 +3 1408 1490 1489 +3 1408 1489 1407 +3 1408 1407 1356 +3 1285 1356 1355 +3 1356 1407 1355 +3 1286 1356 1285 +3 1226 1286 1225 +3 1178 1226 1177 +3 1100 1178 1099 +3 1020 1100 1019 +3 940 1020 939 +3 821 940 820 +3 685 821 684 +3 685 684 551 +3 685 551 552 +3 551 455 552 +3 455 456 552 +3 375 456 455 +3 450 375 374 +3 546 450 449 +3 679 546 545 +3 815 679 678 +3 815 678 814 +3 815 814 931 +3 988 931 930 +3 931 814 930 +3 989 931 988 +3 1335 1280 1341 +3 1341 1352 1388 +3 1388 1404 1438 +3 1948 1953 8627 +3 1849 1953 1948 +3 1849 1948 1814 +3 1849 1814 1717 +3 1814 1617 1717 +3 1617 1644 1717 +3 1570 1644 1617 +3 1570 1617 1556 +3 1570 1556 1486 +3 1174 1131 1096 +3 929 924 891 +3 791 793 924 +3 521 653 654 +3 653 756 654 +3 756 755 654 +3 790 755 756 +3 790 756 891 +3 790 891 794 +3 891 793 794 +3 924 793 891 +3 1006 924 929 +3 1006 929 1016 +3 1006 1016 1083 +3 1016 1096 1083 +3 1096 1131 1083 +3 1211 1174 1222 +3 1131 1174 1211 +3 1333 1222 1280 +3 1211 1222 1333 +3 1438 1486 1476 +3 1486 1556 1476 +3 1404 1486 1438 +3 1352 1404 1388 +3 1280 1352 1341 +3 1333 1280 1335 +3 1333 1335 1336 +3 1333 1336 1342 +3 1333 1342 1393 +3 1342 1391 1393 +3 1391 1475 1393 +3 1525 1475 1391 +3 1705 1645 1618 +3 988 930 901 +3 93 932 99 +3 99 816 105 +3 680 110 105 +3 115 457 121 +3 133 941 140 +3 151 558 144 +3 130 821 124 +3 124 685 118 +3 100 815 92 +3 92 931 902 +3 815 931 92 +3 679 815 100 +3 679 100 106 +3 679 106 546 +3 106 112 546 +3 112 450 546 +3 375 450 112 +3 375 112 456 +3 112 118 456 +3 118 552 456 +3 685 552 118 +3 821 685 124 +3 940 821 130 +3 940 130 137 +3 940 137 827 +3 137 144 827 +3 144 691 827 +3 558 691 144 +3 462 558 151 +3 462 151 381 +3 151 155 381 +3 155 463 381 +3 559 463 155 +3 559 155 148 +3 559 148 692 +3 148 140 692 +3 140 828 692 +3 941 828 140 +3 822 941 133 +3 822 133 127 +3 822 127 686 +3 127 121 686 +3 121 553 686 +3 457 553 121 +3 376 457 115 +3 376 115 451 +3 115 110 451 +3 110 547 451 +3 680 547 110 +3 816 680 105 +3 932 816 99 +3 903 932 93 +3 1621 1648 1708 +3 547 680 681 +3 457 458 553 +3 822 942 941 +3 941 1022 1021 +3 1021 1102 1101 +3 1491 1492 1575 +3 1575 1576 1656 +3 1753 1656 1657 +3 1886 1753 1754 +3 1886 1887 2019 +3 1880 1748 1747 +3 1621 1620 1648 +3 1747 1648 1647 +3 1648 1620 1647 +3 1748 1648 1747 +3 1881 1748 1880 +3 1881 1880 2013 +3 1881 2013 2014 +3 2013 2109 2014 +3 2109 2110 2014 +3 2211 2110 2109 +3 2211 2109 2210 +3 2211 2210 2115 +3 2211 2115 2116 +3 2115 2019 2116 +3 2019 2020 2116 +3 1887 2020 2019 +3 1754 1887 1886 +3 1657 1754 1753 +3 1576 1657 1656 +3 1492 1576 1575 +3 1410 1492 1491 +3 1410 1491 1409 +3 1410 1409 1357 +3 1410 1357 1358 +3 1357 1287 1358 +3 1287 1288 1358 +3 1228 1288 1287 +3 1228 1287 1227 +3 1228 1227 1180 +3 1101 1180 1179 +3 1180 1227 1179 +3 1102 1180 1101 +3 1022 1102 1021 +3 942 1022 941 +3 823 942 822 +3 823 822 686 +3 823 686 687 +3 686 553 687 +3 553 554 687 +3 458 554 553 +3 377 458 457 +3 377 457 376 +3 377 376 451 +3 377 451 452 +3 451 547 452 +3 547 548 452 +3 681 548 547 +3 817 681 680 +3 817 680 816 +3 817 816 933 +3 990 933 932 +3 933 816 932 +3 991 933 990 +3 796 15 660 +3 526 14 659 +3 659 22 795 +3 62 806 670 +3 806 66 924 +3 924 70 791 +3 66 70 924 +3 62 66 806 +3 59 62 670 +3 59 670 537 +3 59 537 441 +3 59 441 56 +3 441 366 56 +3 366 438 56 +3 438 46 56 +3 667 46 534 +3 46 438 534 +3 38 46 667 +3 38 667 803 +3 38 803 30 +3 795 30 915 +3 30 803 915 +3 22 30 795 +3 14 22 659 +3 6 14 526 +3 6 526 430 +3 6 430 361 +3 6 361 431 +3 6 431 7 +3 660 7 527 +3 7 431 527 +3 15 7 660 +3 23 15 796 +3 23 796 916 +3 23 916 31 +3 747 31 883 +3 31 916 883 +3 39 31 747 +3 39 747 644 +3 39 644 47 +3 644 422 47 +3 749 646 41 +3 798 17 662 +3 24 917 797 +3 645 48 423 +3 40 48 645 +3 40 645 748 +3 40 748 32 +3 917 32 884 +3 32 748 884 +3 24 32 917 +3 16 24 797 +3 16 797 661 +3 16 661 8 +3 432 8 528 +3 8 661 528 +3 3 8 432 +3 3 432 362 +3 3 362 433 +3 3 433 9 +3 662 9 529 +3 9 433 529 +3 17 9 662 +3 25 17 798 +3 25 798 918 +3 25 918 33 +3 749 33 885 +3 33 918 885 +3 41 33 749 +3 49 41 646 +3 49 646 424 +3 1961 1960 2178 +3 1960 1855 1854 +3 1854 1723 1722 +3 1722 1633 1632 +3 1632 1563 1562 +3 1562 1479 1478 +3 1478 1397 1396 +3 1396 1345 1344 +3 1344 1270 1269 +3 1088 1089 1008 +3 1009 916 1008 +3 916 917 883 +3 883 884 747 +3 747 748 644 +3 644 645 422 +3 645 423 422 +3 748 645 644 +3 884 748 747 +3 917 884 883 +3 1009 917 916 +3 1089 1009 1008 +3 1167 1089 1088 +3 1167 1088 1166 +3 1167 1166 1215 +3 1269 1215 1214 +3 1215 1166 1214 +3 1270 1215 1269 +3 1345 1270 1344 +3 1397 1345 1396 +3 1479 1397 1478 +3 1563 1479 1562 +3 1633 1563 1632 +3 1723 1633 1722 +3 1855 1723 1854 +3 1961 1855 1960 +3 2179 1961 2178 +3 1857 1856 1962 +3 1856 1725 1724 +3 1724 1635 1634 +3 1565 1564 1634 +3 1481 1480 1564 +3 1271 1346 1347 +3 1090 1091 1010 +3 918 1010 1011 +3 918 919 885 +3 749 885 886 +3 750 646 749 +3 424 646 425 +3 646 647 425 +3 750 647 646 +3 886 750 749 +3 919 886 885 +3 1011 919 918 +3 1091 1011 1010 +3 1169 1091 1090 +3 1169 1090 1168 +3 1169 1168 1216 +3 1169 1216 1217 +3 1216 1271 1217 +3 1271 1272 1217 +3 1347 1272 1271 +3 1399 1347 1346 +3 1480 1399 1398 +3 1399 1346 1398 +3 1481 1399 1480 +3 1565 1481 1564 +3 1635 1565 1634 +3 1725 1635 1724 +3 1857 1725 1856 +3 1963 1857 1962 +3 1963 1962 2181 +3 1962 2180 2181 +3 76 794 793 +3 78 794 76 +3 2088 2089 2514 +3 2088 2514 2513 +3 2911 1308 250 +3 1716 1709 2815 +3 1716 2815 1846 +3 1846 2711 1947 +3 1958 1947 2628 +3 1958 2570 2082 +3 2082 2438 2177 +3 2189 2177 2413 +3 2189 2435 2146 +3 2435 2485 2146 +3 2413 2435 2189 +3 2438 2413 2177 +3 2570 2438 2082 +3 2628 2570 1958 +3 2711 2628 1947 +3 2815 2711 1846 +3 241 419 237 +3 419 488 237 +3 429 419 241 +3 429 241 243 +3 429 243 523 +3 243 245 523 +3 245 650 523 +3 658 650 245 +3 658 245 247 +3 658 247 758 +3 247 892 758 +3 900 892 247 +3 900 247 249 +3 900 249 1003 +3 249 1050 1003 +3 1086 1050 249 +3 1086 249 250 +3 1086 250 1134 +3 250 1212 1134 +3 1308 1212 250 +3 1387 1308 2911 +3 1387 2911 1469 +3 2911 2910 1469 +3 2910 1520 1469 +3 1558 1520 2910 +3 1558 2910 1605 +3 2910 2908 1605 +3 2908 1709 1605 +3 2815 1709 2908 +3 994 134 896 +3 180 134 994 +3 180 994 995 +3 180 995 897 +3 2184 2433 2190 +3 2190 2434 2187 +3 2515 2081 2187 +3 2081 2620 1949 +3 1949 2704 1847 +3 1847 2808 1714 +3 2890 1606 1714 +3 1606 2891 1609 +3 1609 2892 1611 +3 2891 2892 1609 +3 2890 2891 1606 +3 2808 2890 1714 +3 2704 2808 1847 +3 2620 2704 1949 +3 2515 2620 2081 +3 2434 2515 2187 +3 2433 2434 2190 +3 2437 2433 2184 +3 2437 2184 2183 +3 2437 2183 2442 +3 2892 2895 2896 +3 2889 2895 2892 +3 2889 2892 2891 +3 2889 2891 2890 +3 94 904 93 +3 904 903 93 +3 990 903 904 +3 990 904 991 +3 755 80 654 +3 83 521 81 +3 521 654 81 +3 654 80 81 +3 79 755 790 +3 80 755 79 +3 78 790 794 +3 79 790 78 +3 153 160 520 +3 153 520 519 +3 1710 2892 2817 +3 2892 2896 2817 +3 1611 2892 1710 +3 1611 1710 1612 +3 95 77 895 +3 77 992 895 +3 992 993 895 +3 215 898 223 +3 898 997 223 +3 996 997 898 +3 2903 2820 2902 +3 1713 2820 2903 +3 1713 2903 1616 +3 1713 1616 1615 +3 2900 2819 1712 +3 2900 1712 1614 +3 2900 1614 2898 +3 1614 1613 2898 +3 1613 1711 2898 +3 1711 2818 2898 +3 2887 2894 2888 +3 2893 2894 2887 +3 2897 2899 2900 +3 2897 2900 2898 +3 2902 2906 2903 +3 2901 2911 2912 +3 2910 2911 2901 +3 2910 2901 2908 +3 2903 2905 2904 +3 2906 2905 2903 +3 2907 2906 2902 +3 2907 2902 2909 +3 2902 2912 2909 +3 2901 2912 2902 +3 2886 2885 2288 +3 2886 2288 2821 +3 2288 1708 2821 +3 1621 1708 2288 +3 1621 2288 1620 +3 1707 1620 2287 +3 1620 2288 2287 +3 91 92 902 +3 91 902 901 +3 902 988 901 +3 989 988 902 +3 1619 1706 1618 +3 1706 1705 1618 +3 2285 1705 1706 +3 2285 1706 2286 +3 2442 2183 2182 +3 2442 2182 2441 +3 427 52 51 +3 427 51 426 +3 49 424 425 +3 49 425 50 +3 2254 2179 2178 +3 2254 2178 2253 +3 48 47 422 +3 48 422 423 +3 2912 2911 251 +3 2911 250 251 +3 2909 251 248 +3 2912 251 2909 +3 2907 248 246 +3 2909 248 2907 +3 1307 2906 244 +3 2906 246 244 +3 2907 246 2906 +3 2904 1610 2903 +3 1610 1616 2903 +3 1607 1610 2904 +3 1607 2904 1604 +3 2904 2905 1604 +3 2905 1557 1604 +3 1521 1557 2905 +3 1521 2905 1470 +3 2905 2906 1470 +3 2906 1389 1470 +3 1307 1389 2906 +3 1210 1307 244 +3 1210 244 1132 +3 244 242 1132 +3 242 1085 1132 +3 1051 1085 242 +3 1051 242 1004 +3 242 240 1004 +3 240 1001 1004 +3 998 1001 240 +3 998 240 223 +3 998 223 997 +3 418 57 53 +3 69 999 77 +3 999 992 77 +3 1002 999 69 +3 1002 69 893 +3 69 63 893 +3 63 757 893 +3 655 757 63 +3 655 63 58 +3 655 58 524 +3 58 57 524 +3 57 420 524 +3 418 420 57 +3 421 418 53 +3 421 53 52 +3 421 52 427 +3 76 793 791 +3 76 791 70 +3 3557 3663 3657 +3 3557 3553 3496 +3 3553 3476 3496 +3 3657 3553 3557 +3 3690 3657 3663 +3 3690 3663 3693 +3 3690 3693 3796 +3 4102 4717 4573 +3 4330 4080 4438 +3 4438 3796 4582 +3 3496 4718 4831 +3 4718 3577 4574 +3 4574 3710 4430 +3 4322 4430 3833 +3 4322 3933 4243 +3 4243 4025 4314 +3 4422 4314 3926 +3 4422 3826 4566 +3 4710 4566 3703 +3 3570 4821 4710 +3 4702 4821 3488 +3 4306 4414 3919 +3 4557 4096 4701 +3 4106 4083 4330 +3 4106 4330 4251 +3 4106 4251 4329 +3 4106 4329 4105 +3 4581 4105 4437 +3 4105 4329 4437 +3 4104 4105 4581 +3 4104 4581 4725 +3 4104 4725 4103 +3 4717 4103 4830 +3 4103 4725 4830 +3 4102 4103 4717 +3 4101 4102 4573 +3 4321 4101 4429 +3 4101 4573 4429 +3 4100 4101 4321 +3 4313 4100 4242 +3 4100 4321 4242 +3 4099 4100 4313 +3 4099 4313 4421 +3 4099 4421 4565 +3 4099 4565 4098 +3 4565 4709 4098 +3 4709 4097 4098 +3 4701 4097 4820 +3 4097 4709 4820 +3 4096 4097 4701 +3 4095 4096 4557 +3 4095 4557 4413 +3 4095 4413 4305 +3 4095 4305 4094 +3 3919 4021 4094 +3 4306 4094 4237 +3 4094 4305 4237 +3 3919 4094 4306 +3 3819 3919 4414 +3 3819 4414 4558 +3 3819 4558 3696 +3 4558 4702 3696 +3 4702 3563 3696 +3 3488 3563 4702 +3 3570 3488 4821 +3 3703 3570 4710 +3 3826 3703 4566 +3 3926 3826 4422 +3 4025 3926 4314 +3 3933 4025 4243 +3 3833 3933 4322 +3 3710 3833 4430 +3 3577 3710 4574 +3 3496 3577 4718 +3 3557 3496 4831 +3 3557 4831 4726 +3 3557 4726 3663 +3 4726 4582 3663 +3 4582 3693 3663 +3 3796 3693 4582 +3 4080 3796 4438 +3 4083 4080 4330 +3 4086 4083 4106 +3 2622 2623 2517 +3 2919 2918 2991 +3 2990 3066 2991 +3 3066 3065 3113 +3 3112 3172 3113 +3 3172 3171 3235 +3 3234 3281 3235 +3 3428 3488 3489 +3 3489 3570 3571 +3 3571 3703 3704 +3 3827 3704 3826 +3 3578 3577 3497 +3 3477 3497 3476 +3 3497 3496 3476 +3 3577 3496 3497 +3 3710 3577 3578 +3 3710 3578 3711 +3 3710 3711 3833 +3 3711 3834 3833 +3 3834 3934 3833 +3 3934 3933 3833 +3 4025 3933 3934 +3 4025 3934 4026 +3 4025 4026 3926 +3 3827 3926 3927 +3 3926 4026 3927 +3 3826 3926 3827 +3 3703 3826 3704 +3 3570 3703 3571 +3 3488 3570 3489 +3 3427 3488 3428 +3 3427 3428 3356 +3 3427 3356 3355 +3 3356 3281 3355 +3 3281 3280 3355 +3 3234 3280 3281 +3 3171 3234 3235 +3 3112 3171 3172 +3 3065 3112 3113 +3 2990 3065 3066 +3 2918 2990 2991 +3 2831 2918 2919 +3 2831 2919 2832 +3 2831 2832 2809 +3 2832 2810 2809 +3 2810 2705 2809 +3 2623 2705 2706 +3 2705 2810 2706 +3 2622 2705 2623 +3 2516 2622 2517 +3 3558 3658 3664 +3 3664 3691 3694 +3 3691 3797 3694 +3 3658 3691 3664 +3 3554 3658 3558 +3 3554 3558 3497 +3 3554 3497 3477 +3 8098 8343 8347 +3 8311 7982 8303 +3 8321 7606 8329 +3 8353 7997 8362 +3 8269 7689 8265 +3 8265 7833 8261 +3 8261 7945 8257 +3 7945 8085 8257 +3 7833 7945 8261 +3 7689 7833 8265 +3 7616 7689 8269 +3 7616 8269 8287 +3 7616 8287 7709 +3 8287 8362 7709 +3 8362 7853 7709 +3 7997 7853 8362 +3 8105 7997 8353 +3 8105 8353 8198 +3 8353 8345 8198 +3 8345 8097 8198 +3 7989 8097 8345 +3 7989 8345 8337 +3 7989 8337 7845 +3 8337 8329 7845 +3 8329 7701 7845 +3 7606 7701 8329 +3 7693 7606 8321 +3 7693 8321 8313 +3 7693 8313 7837 +3 8313 8305 7837 +3 8305 7981 7837 +3 8089 7981 8305 +3 8089 8305 8303 +3 8089 8303 8193 +3 8303 8090 8193 +3 7982 8090 8303 +3 7838 7982 8311 +3 7838 8311 8319 +3 7838 8319 7694 +3 8319 8327 7694 +3 8327 7607 7694 +3 7702 7607 8327 +3 7702 8327 8335 +3 7702 8335 7846 +3 8335 8343 7846 +3 8343 7990 7846 +3 8098 7990 8343 +3 8199 8098 8347 +3 8199 8347 8106 +3 8347 8355 8106 +3 8355 7998 8106 +3 7854 7998 8355 +3 7854 8355 8363 +3 7854 8363 7710 +3 7690 8266 7834 +3 7834 8262 7946 +3 7946 8258 8086 +3 8262 8258 7946 +3 8266 8262 7834 +3 8270 8266 7690 +3 8270 7690 7617 +3 8270 7617 8288 +3 7617 7710 8288 +3 7710 8363 8288 +3 7617 7690 7686 +3 7617 7594 7546 +3 7502 7454 7546 +3 7454 7442 7362 +3 7104 7086 7006 +3 7006 6994 6912 +3 6912 6900 6831 +3 6831 6808 6724 +3 6724 6696 6584 +3 6584 6556 6440 +3 6440 6412 6328 +3 6327 6411 6439 +3 6439 6555 6583 +3 6583 6695 6723 +3 6723 6807 6830 +3 6830 6899 6911 +3 6911 6993 7005 +3 7005 7085 7103 +3 7361 7441 7453 +3 7501 7545 7453 +3 7616 7545 7593 +3 7685 7689 7616 +3 7833 7689 7829 +3 7833 7941 7945 +3 7941 8085 7945 +3 7829 7941 7833 +3 7685 7829 7689 +3 7593 7685 7616 +3 7501 7593 7545 +3 7441 7501 7453 +3 7349 7441 7361 +3 7349 7361 7305 +3 7349 7305 7226 +3 7349 7226 7203 +3 7103 7203 7155 +3 7203 7226 7155 +3 7085 7203 7103 +3 6993 7085 7005 +3 6899 6993 6911 +3 6807 6899 6830 +3 6695 6807 6723 +3 6555 6695 6583 +3 6411 6555 6439 +3 6255 6411 6327 +3 6328 6255 6251 +3 6255 6327 6251 +3 6412 6255 6328 +3 6556 6412 6440 +3 6696 6556 6584 +3 6808 6696 6724 +3 6900 6808 6831 +3 6994 6900 6912 +3 7086 6994 7006 +3 7204 7086 7104 +3 7204 7104 7156 +3 7204 7156 7227 +3 7204 7227 7350 +3 7362 7350 7306 +3 7350 7227 7306 +3 7442 7350 7362 +3 7502 7442 7454 +3 7594 7502 7546 +3 7686 7594 7617 +3 7830 7686 7690 +3 7830 7690 7834 +3 7830 7834 7942 +3 7834 7946 7942 +3 7946 8086 7942 +3 2627 2648 2710 +3 2710 2752 2814 +3 2916 2929 2988 +3 3001 3037 2988 +3 3037 3076 3063 +3 3063 3123 3159 +3 3159 3185 3233 +3 3328 3233 3245 +3 3354 3328 3291 +3 3353 3328 3354 +3 3366 3472 3354 +3 3685 3729 3818 +3 3660 3592 3480 +3 3221 3152 3060 +3 2958 2894 2893 +3 2958 2893 2985 +3 2958 2985 3030 +3 2985 3060 3030 +3 3060 3105 3030 +3 3152 3105 3060 +3 3224 3152 3221 +3 3224 3221 3274 +3 3221 3329 3274 +3 3329 3321 3274 +3 3395 3321 3329 +3 3395 3329 3405 +3 3395 3405 3467 +3 3405 3480 3467 +3 3480 3504 3467 +3 3592 3504 3480 +3 3725 3592 3660 +3 3725 3660 3795 +3 3725 3795 3848 +3 3795 4016 3848 +3 4016 3948 3848 +3 4037 3948 4016 +3 4037 4016 3952 +3 4016 3818 3952 +3 3818 3852 3952 +3 3729 3852 3818 +3 3596 3729 3685 +3 3596 3685 3556 +3 3596 3556 3509 +3 3556 3472 3509 +3 3472 3438 3509 +3 3366 3438 3472 +3 3291 3366 3354 +3 3245 3291 3328 +3 3185 3245 3233 +3 3123 3185 3159 +3 3076 3123 3063 +3 3001 3076 3037 +3 2929 3001 2988 +3 2849 2929 2916 +3 2458 2395 2436 +3 2458 2436 2541 +3 2541 2621 2646 +3 2733 2750 2646 +3 2750 2885 2842 +3 2885 2886 2842 +3 2733 2885 2750 +3 2621 2733 2646 +3 2436 2621 2541 +3 2543 2648 2523 +3 2543 2523 2460 +3 2523 2395 2460 +3 2436 2395 2523 +3 2814 2849 2848 +3 2849 2916 2848 +3 2752 2849 2814 +3 2648 2752 2710 +3 2523 2648 2627 +3 2523 2627 2522 +3 2847 2846 2812 +3 2846 2915 2914 +3 2986 2914 2987 +3 3036 3035 2986 +3 3035 3062 3061 +3 3326 3327 3351 +3 3327 3352 3351 +3 3232 3327 3326 +3 3232 3326 3231 +3 3232 3231 3158 +3 3061 3158 3157 +3 3158 3231 3157 +3 3062 3158 3061 +3 3036 3062 3035 +3 2987 3036 2986 +3 2915 2987 2914 +3 2847 2915 2846 +3 2813 2847 2812 +3 2813 2812 2708 +3 2813 2708 2709 +3 2708 2625 2709 +3 2625 2626 2709 +3 2521 2626 2625 +3 2521 2625 2520 +3 8108 8348 8356 +3 8344 7848 8336 +3 8336 7704 8328 +3 8312 7984 8304 +3 8322 7608 8330 +3 8354 7999 8364 +3 8271 7691 8267 +3 8267 7835 8263 +3 8260 8088 7948 +3 8264 7948 7836 +3 8260 7948 8264 +3 8268 7836 7692 +3 8264 7836 8268 +3 8272 7692 7619 +3 8268 7692 8272 +3 8290 7619 7712 +3 8272 7619 8290 +3 8263 7947 8259 +3 7947 8087 8259 +3 7835 7947 8263 +3 7691 7835 8267 +3 7618 7691 8271 +3 7618 8271 8289 +3 7618 8289 7711 +3 8289 8364 7711 +3 8364 7855 7711 +3 7999 7855 8364 +3 8107 7999 8354 +3 8107 8354 8200 +3 8354 8346 8200 +3 8346 8099 8200 +3 7991 8099 8346 +3 7991 8346 8338 +3 7991 8338 7847 +3 8338 8330 7847 +3 8330 7703 7847 +3 7608 7703 8330 +3 7695 7608 8322 +3 7695 8322 8314 +3 7695 8314 7839 +3 8314 8306 7839 +3 8306 7983 7839 +3 8091 7983 8306 +3 8091 8306 8304 +3 8091 8304 8194 +3 8304 8092 8194 +3 7984 8092 8304 +3 7840 7984 8312 +3 7840 8312 8320 +3 7840 8320 7696 +3 8320 8328 7696 +3 8328 7609 7696 +3 7704 7609 8328 +3 7848 7704 8336 +3 7992 7848 8344 +3 7992 8344 8100 +3 8344 8348 8100 +3 8348 8201 8100 +3 8108 8201 8348 +3 8000 8108 8356 +3 8000 8356 7856 +3 8356 8365 7856 +3 8365 7712 7856 +3 8290 7712 8365 +3 7836 7832 7692 +3 7692 7688 7619 +3 7619 7596 7548 +3 7548 7504 7456 +3 7456 7444 7364 +3 7106 7088 7008 +3 7008 6996 6914 +3 6833 6914 6902 +3 6833 6810 6726 +3 6726 6698 6586 +3 6586 6558 6442 +3 6414 6330 6442 +3 6329 6413 6441 +3 6585 6441 6557 +3 6697 6725 6585 +3 6725 6809 6832 +3 6832 6901 6913 +3 6913 6995 7007 +3 7007 7087 7105 +3 7455 7503 7547 +3 7547 7595 7618 +3 7618 7687 7691 +3 7691 7831 7835 +3 7835 7943 7947 +3 7943 8087 7947 +3 7831 7943 7835 +3 7687 7831 7691 +3 7595 7687 7618 +3 7503 7595 7547 +3 7443 7503 7455 +3 7443 7455 7363 +3 7443 7363 7351 +3 7363 7307 7351 +3 7307 7228 7351 +3 7228 7205 7351 +3 7105 7205 7157 +3 7205 7228 7157 +3 7087 7205 7105 +3 6995 7087 7007 +3 6901 6995 6913 +3 6809 6901 6832 +3 6697 6809 6725 +3 6557 6697 6585 +3 6413 6557 6441 +3 6256 6413 6329 +3 6330 6256 6252 +3 6256 6329 6252 +3 6414 6256 6330 +3 6558 6414 6442 +3 6698 6558 6586 +3 6810 6698 6726 +3 6902 6810 6833 +3 6996 6902 6914 +3 7088 6996 7008 +3 7206 7088 7106 +3 7206 7106 7158 +3 7206 7158 7229 +3 7206 7229 7352 +3 7364 7352 7308 +3 7352 7229 7308 +3 7444 7352 7364 +3 7504 7444 7456 +3 7596 7504 7548 +3 7688 7596 7619 +3 7832 7688 7692 +3 7944 7832 7836 +3 7944 7836 7948 +3 7944 7948 8088 +3 8435 8293 8443 +3 8298 8427 8436 +3 8298 8436 8294 +3 8436 8444 8294 +3 8444 8286 8294 +3 8282 8286 8444 +3 8282 8444 8278 +3 8444 8446 8278 +3 8446 8274 8278 +3 8277 8274 8446 +3 8277 8446 8443 +3 8277 8443 8281 +3 8443 8285 8281 +3 8293 8285 8443 +3 8297 8293 8435 +3 8297 8435 8426 +3 8433 8291 8441 +3 8296 8425 8434 +3 8296 8434 8292 +3 8434 8442 8292 +3 8442 8284 8292 +3 8280 8284 8442 +3 8280 8442 8276 +3 8442 8445 8276 +3 8445 8273 8276 +3 8275 8273 8445 +3 8275 8445 8441 +3 8275 8441 8279 +3 8441 8283 8279 +3 8291 8283 8441 +3 8295 8291 8433 +3 8295 8433 8424 +3 1631 2301 2299 +3 2259 2087 2192 +3 1993 2087 2259 +3 1993 2259 2267 +3 1993 2267 1860 +3 2267 2275 1860 +3 2275 1727 1860 +3 2301 1727 2283 +3 1727 2275 2283 +3 1631 1727 2301 +3 1728 1631 2299 +3 1728 2299 2298 +3 1728 2298 1861 +3 2298 2297 1861 +3 2297 1994 1861 +3 2090 1994 2297 +3 2090 2297 2296 +3 2090 2296 2197 +3 2091 2296 2443 +3 2197 2296 2091 +3 2091 2526 1995 +3 1995 2631 1862 +3 2735 1729 1862 +3 1729 2831 1632 +3 1722 2276 1854 +3 1854 2268 1960 +3 2366 2358 2809 +3 2366 2809 2370 +3 2622 2516 2370 +3 2622 2370 2705 +3 2370 2809 2705 +3 2831 2358 2353 +3 2809 2358 2831 +3 1960 2260 2178 +3 2260 2253 2178 +3 2268 2260 1960 +3 2276 2268 1854 +3 2289 2276 1722 +3 2289 1722 2341 +3 1722 1632 2341 +3 1632 2353 2341 +3 2831 2353 1632 +3 2735 2831 1729 +3 2631 2735 1862 +3 2526 2631 1995 +3 2443 2526 2091 +3 2386 2443 2296 +3 2811 2360 2833 +3 1864 2633 2737 +3 2445 2198 2387 +3 1863 2736 2632 +3 2736 1730 2832 +3 1855 2269 2277 +3 2269 1961 2261 +3 2261 2179 2254 +3 1961 2179 2261 +3 1855 1961 2269 +3 1723 1855 2277 +3 1723 2277 2290 +3 1723 2290 2342 +3 1723 2342 1633 +3 2517 2623 2371 +3 2623 2706 2371 +3 2706 2810 2371 +3 2810 2367 2371 +3 2359 2367 2810 +3 2359 2810 2832 +3 2359 2832 2354 +3 2832 1633 2354 +3 1633 2342 2354 +3 1730 1633 2832 +3 1863 1730 2736 +3 1996 1863 2632 +3 1996 2632 2527 +3 1996 2527 2092 +3 2387 2092 2444 +3 2092 2527 2444 +3 2198 2092 2387 +3 2093 2198 2445 +3 2093 2445 2528 +3 2093 2528 1997 +3 2528 2633 1997 +3 2633 1864 1997 +3 1731 2737 2833 +3 1864 2737 1731 +3 1634 2833 2355 +3 1731 2833 1634 +3 1634 2343 1724 +3 1962 2262 2180 +3 2262 2255 2180 +3 2270 2262 1962 +3 2270 1962 1856 +3 2270 1856 2278 +3 1856 1724 2278 +3 1724 2291 2278 +3 2343 2291 1724 +3 2355 2343 1634 +3 2360 2355 2833 +3 2368 2360 2811 +3 2368 2811 2372 +3 2811 2707 2372 +3 2707 2624 2372 +3 2624 2518 2372 +3 2256 2439 2440 +3 2256 2440 2181 +3 2256 2181 2180 +3 2256 2180 2255 +3 4810 5426 6232 +3 4805 4899 4806 +3 4991 4899 4805 +3 4991 4805 5135 +3 4805 5279 5135 +3 5423 5279 4805 +3 5423 4805 6231 +3 5423 6231 5515 +3 6231 5659 5515 +3 5803 5659 6231 +3 5803 6231 5947 +3 6231 6181 5947 +3 5804 5805 5660 +3 5660 5661 5516 +3 5517 5424 5516 +3 5425 5280 5424 +3 5280 5281 5136 +3 5136 5137 4992 +3 4992 4993 4900 +3 4900 4901 4807 +3 4901 4808 4807 +3 4993 4901 4900 +3 5137 4993 4992 +3 5281 5137 5136 +3 5425 5281 5280 +3 5517 5425 5424 +3 5661 5517 5516 +3 5805 5661 5660 +3 5949 5805 5804 +3 5949 5804 5948 +3 5949 5948 6182 +3 5948 6181 6182 +3 6181 6231 6182 +3 6231 6232 6182 +3 6232 5950 6182 +3 5806 5950 6232 +3 5806 6232 5662 +3 6232 5518 5662 +3 5426 5518 6232 +3 5282 5426 4810 +3 5282 4810 5138 +3 4810 4994 5138 +3 4902 4994 4810 +3 4902 4810 4809 +3 7590 7591 7682 +3 7682 7683 7794 +3 8219 8275 8081 +3 8279 7937 8081 +3 7589 7681 7291 +3 7589 7291 7497 +3 7291 7405 7497 +3 7292 7405 7291 +3 7937 8283 8423 +3 7937 8423 7793 +3 8423 7681 7793 +3 7291 7681 8423 +3 8296 8292 8293 +3 8428 8298 8294 +3 8427 8298 8428 +3 7408 7295 7296 +3 7408 7296 7500 +3 7296 7592 7500 +3 7684 7592 7296 +3 7684 7296 8428 +3 7684 8428 7796 +3 8282 7940 8286 +3 7940 8428 8286 +3 8428 8294 8286 +3 7796 8428 7940 +3 8084 8282 8278 +3 7940 8282 8084 +3 8277 8220 8274 +3 8220 8278 8274 +3 8084 8278 8220 +3 8296 8297 8425 +3 8297 8426 8425 +3 8293 8297 8296 +3 8285 8293 8292 +3 8285 8292 8284 +3 8285 8284 8281 +3 8284 8280 8281 +3 8280 8083 8281 +3 8083 8277 8281 +3 8220 8277 8083 +3 8424 8423 8295 +3 8423 8291 8295 +3 8283 8291 8423 +3 8279 8283 7937 +3 8275 8279 8081 +3 8273 8275 8219 +3 8273 8219 8276 +3 8219 8082 8276 +3 8082 8280 8276 +3 8083 8280 8082 +3 8083 8082 7939 +3 8082 7938 7939 +3 7938 7794 7939 +3 7794 7795 7939 +3 7683 7795 7794 +3 7591 7683 7682 +3 7499 7591 7590 +3 7499 7590 7498 +3 7499 7498 7406 +3 7499 7406 7407 +3 7294 7406 7293 +3 7407 7406 7294 +3 2288 2351 2287 +3 2365 2351 2288 +3 2365 2288 2523 +3 2365 2523 2522 +3 4189 4144 4190 +3 4143 4144 4189 +3 4206 4190 4207 +3 4189 4190 4206 +3 2192 2191 2258 +3 2192 2258 2259 +3 2349 2350 2363 +3 2363 2364 2520 +3 2364 2521 2520 +3 2350 2364 2363 +3 2286 2350 2349 +3 2286 2349 2285 +3 4109 4110 4143 +3 4144 4110 4045 +3 4143 4110 4144 +3 4144 3562 3354 +3 3404 3353 3354 +3 3404 3354 3475 +3 3354 3552 3475 +3 3562 3552 3354 +3 3688 3562 4144 +3 3688 4144 3794 +3 4144 3918 3794 +3 4045 3918 4144 +3 3917 4045 4110 +3 3917 4110 3793 +3 3551 3561 3560 +3 3551 3550 3474 +3 3473 3403 3474 +3 3352 3403 3351 +3 3403 3402 3351 +3 3473 3402 3403 +3 3550 3473 3474 +3 3560 3550 3551 +3 3686 3560 3561 +3 3686 3561 3687 +3 3686 3687 3792 +3 3687 3793 3792 +3 3793 4110 3792 +3 4110 3916 3792 +3 4044 3916 4110 +3 6987 6895 6988 +3 6803 6895 6987 +3 6803 6987 6551 +3 6804 6805 6896 +3 6896 6897 6989 +3 6897 6990 6989 +3 6805 6897 6896 +3 6553 6805 6804 +3 6553 6804 6552 +3 6553 6552 6408 +3 6553 6408 6409 +3 6410 5930 6554 +3 5786 6992 6554 +3 6992 6806 6554 +3 6898 6806 6992 +3 6898 6992 6991 +3 5403 5495 6987 +3 5403 6987 4206 +3 5403 4206 5231 +3 4206 5063 5231 +3 4971 5063 4206 +3 4971 4206 4851 +3 4206 4681 4851 +3 4533 4681 4206 +3 4533 4206 4267 +3 4206 4534 4267 +3 4852 4853 4972 +3 4972 4973 5064 +3 5065 5232 5064 +3 5404 5232 5233 +3 5404 5405 5496 +3 5612 5496 5497 +3 5612 5613 5784 +3 5613 5785 5784 +3 5497 5613 5612 +3 5405 5497 5496 +3 5233 5405 5404 +3 5065 5233 5232 +3 4973 5065 5064 +3 4853 4973 4972 +3 4683 4853 4852 +3 4683 4852 4682 +3 4683 4682 4535 +3 4682 4534 4535 +3 4534 4206 4535 +3 4206 4207 4535 +3 4207 4268 4535 +3 4536 4268 4207 +3 4536 4207 4684 +3 4207 4854 4684 +3 4974 4854 4207 +3 4974 4207 5066 +3 4207 5234 5066 +3 5406 5234 4207 +3 5406 4207 6992 +3 5406 6992 5498 +3 6992 5614 5498 +3 5786 5614 6992 +3 5930 5786 6554 +3 6194 5930 6410 +3 6194 6410 6409 +3 6194 6409 5929 +3 6409 6408 5929 +3 6408 5928 5929 +3 5928 5785 5929 +3 5784 5785 5928 +3 5783 6987 5611 +3 6987 5495 5611 +3 6551 6987 5783 +3 6551 5783 5927 +3 6551 5927 6407 +3 5927 6193 6407 +3 6193 6408 6407 +3 5928 6408 6193 +3 2523 2288 2436 +3 2288 2621 2436 +3 2733 2621 2288 +3 2733 2288 2885 +3 7067 6992 6969 +3 6969 5493 6845 +3 6845 5605 6677 +3 6677 5781 6533 +3 6533 5925 6259 +3 6259 6185 6531 +3 6531 5923 6675 +3 5779 6839 6675 +3 5599 6232 6839 +3 6232 6967 6839 +3 7065 6967 6232 +3 7065 6232 7235 +3 6232 7421 7235 +3 4207 5225 5401 +3 5061 5225 4207 +3 5061 4207 4969 +3 4845 3556 4679 +3 4016 4529 4259 +3 4677 4529 3795 +3 7809 7625 8366 +3 7625 7517 8366 +3 7517 7421 8366 +3 7421 6232 8366 +3 3039 2985 2984 +3 2984 2893 2887 +3 2985 2893 2984 +3 3060 2985 3039 +3 3060 3039 3161 +3 3060 3161 3221 +3 3161 3318 3221 +3 3318 3329 3221 +3 4677 3660 4839 +3 3660 3480 4839 +3 3795 3660 4677 +3 4016 3795 4529 +3 3818 4016 4259 +3 3818 4259 4531 +3 3818 4531 3685 +3 4531 4679 3685 +3 4679 3556 3685 +3 3354 3472 4144 +3 3472 3556 4144 +3 3556 4845 4144 +3 4845 4969 4144 +3 4969 4207 4144 +3 4207 4190 4144 +3 6992 5401 5493 +3 4207 5401 6992 +3 6992 7296 7094 +3 3479 4810 3401 +3 4810 3318 3401 +3 3329 3318 4810 +3 3329 4810 3405 +3 4810 3480 3405 +3 4839 3480 4810 +3 4839 4810 4967 +3 4810 5059 4967 +3 5219 5059 4810 +3 5219 4810 5399 +3 4810 6232 5399 +3 6232 5491 5399 +3 5599 5491 6232 +3 5779 5599 6839 +3 5923 5779 6675 +3 6185 5923 6531 +3 5925 6185 6259 +3 5781 5925 6533 +3 5605 5781 6677 +3 5493 5605 6845 +3 6992 5493 6969 +3 7296 6992 7067 +3 7296 7067 7241 +3 7296 7241 7423 +3 7296 7423 7519 +3 7296 7519 8428 +3 7519 7631 8428 +3 7631 7811 8428 +3 7811 7963 8428 +3 7963 8211 8428 +3 8211 7961 8428 +3 7961 7809 8428 +3 7809 8366 8428 +3 2256 2263 2439 +3 2373 2344 2362 +3 2344 2357 2362 +3 2282 2344 2373 +3 2282 2373 2273 +3 2373 2263 2273 +3 2439 2263 2373 +3 2439 2373 2519 +3 2517 2370 2516 +3 2371 2370 2517 +3 2373 2518 2519 +3 2372 2518 2373 +3 3553 3477 3476 +3 3554 3477 3553 +3 3554 3553 3657 +3 3554 3657 3658 +3 3691 3657 3690 +3 3658 3657 3691 +3 3797 3690 3796 +3 3691 3690 3797 +3 4081 3796 4080 +3 3797 3796 4081 +3 4086 4108 4083 +3 4108 4080 4083 +3 4081 4080 4108 +3 4081 4108 4084 +3 4108 4087 4084 +3 4085 4810 4082 +3 3479 3659 3692 +3 3555 3659 3479 +3 3555 3479 3478 +3 4664 4809 4810 +3 4664 4810 4556 +3 4810 4412 4556 +3 4082 3479 3798 +3 3479 3692 3798 +3 4810 3479 4082 +3 4412 4810 4085 +3 4412 4085 4256 +3 4085 4087 4256 +3 4087 4108 4256 +3 4108 4411 4256 +3 4409 4805 4553 +3 4805 4661 4553 +3 4806 4661 4805 +3 4107 4409 4255 +3 4805 4409 4107 +3 4663 4662 4808 +3 4662 4807 4808 +3 4554 4662 4663 +3 4554 4663 4555 +3 4554 4555 4410 +3 4555 4411 4410 +3 4411 4108 4410 +3 4108 4255 4410 +3 4107 4255 4108 +3 8272 7688 8268 +3 8264 8268 7832 +3 6557 6556 6697 +3 6697 6696 6809 +3 6809 6808 6901 +3 6900 6995 6901 +3 6995 6994 7087 +3 7086 7205 7087 +3 7351 7205 7204 +3 7351 7350 7443 +3 7443 7442 7503 +3 7502 7595 7503 +3 7687 7595 7594 +3 7687 7686 7831 +3 8087 7943 8259 +3 7830 8263 7831 +3 8263 7943 7831 +3 8259 7943 8263 +3 8364 8288 8363 +3 8262 7942 8258 +3 7942 8086 8258 +3 7830 7942 8262 +3 8271 8288 8289 +3 8288 8364 8289 +3 8270 8288 8271 +3 8270 8271 8267 +3 8270 8267 8266 +3 8267 8263 8266 +3 8263 8262 8266 +3 7830 8262 8263 +3 7686 7830 7831 +3 7594 7686 7687 +3 7502 7594 7595 +3 7442 7502 7503 +3 7350 7442 7443 +3 7204 7350 7351 +3 7086 7204 7205 +3 6994 7086 7087 +3 6900 6994 6995 +3 6808 6900 6901 +3 6696 6808 6809 +3 6556 6696 6697 +3 6412 6556 6557 +3 6412 6557 6413 +3 6412 6413 6255 +3 7349 8361 7441 +3 8361 7501 7441 +3 7593 7501 8361 +3 7593 8361 7685 +3 7829 8261 7941 +3 7941 8257 8085 +3 8261 8257 7941 +3 8265 8261 7829 +3 8265 7829 7685 +3 8265 7685 8269 +3 7685 8361 8269 +3 8361 8287 8269 +3 8362 8287 8361 +3 6231 6255 6256 +3 6255 6413 6256 +3 6411 6255 6231 +3 6411 6231 6555 +3 6231 6695 6555 +3 6807 6695 6231 +3 6807 6231 6899 +3 6231 6993 6899 +3 7085 6993 6231 +3 7085 6231 7203 +3 6231 7349 7203 +3 8361 7349 6231 +3 7206 7352 6232 +3 7206 6232 7088 +3 6232 6996 7088 +3 6902 6996 6232 +3 6902 6232 6810 +3 6232 6698 6810 +3 6558 6698 6232 +3 6558 6232 6414 +3 6232 6256 6414 +3 6231 6256 6232 +3 8366 7596 7688 +3 7504 7596 8366 +3 7504 8366 7444 +3 8366 7352 7444 +3 6232 7352 8366 +3 8264 7944 8260 +3 7944 8088 8260 +3 7832 7944 8264 +3 7688 7832 8268 +3 8366 7688 8272 +3 8366 8272 8290 +3 8366 8290 8365 +3 7050 7051 7090 +3 7200 7090 7091 +3 7200 7201 7293 +3 7201 7294 7293 +3 7091 7201 7200 +3 7051 7091 7090 +3 6990 7050 6989 +3 7051 7050 6990 +3 6991 6992 7052 +3 6992 7094 7052 +3 7094 7092 7052 +3 7202 7092 7094 +3 7202 7094 7296 +3 7202 7296 7295 +3 7292 7291 7199 +3 7291 7093 7199 +3 7093 7089 7199 +3 7049 7089 7093 +3 7049 7093 6987 +3 7049 6987 6988 +3 1556 1555 1476 +3 1336 1337 1342 +3 1342 1390 1391 +3 1337 1390 1342 +3 1334 1337 1336 +3 1334 1336 1335 +3 1334 1335 1338 +3 1388 1338 1341 +3 1338 1335 1341 +3 1392 1338 1388 +3 1392 1388 1438 +3 1392 1438 1473 +3 1438 1476 1473 +3 1476 1555 1473 +3 2260 2261 2253 +3 2261 2254 2253 +3 1524 1525 1391 +3 1524 1391 1390 +3 2255 2263 2256 +3 2262 2263 2255 +3 2300 2283 2281 +3 2281 2275 2272 +3 2272 2267 2258 +3 2267 2259 2258 +3 2275 2267 2272 +3 2283 2275 2281 +3 2301 2283 2300 +3 2341 2353 2354 +3 2341 2342 2289 +3 2290 2276 2289 +3 2276 2277 2268 +3 2268 2269 2260 +3 2269 2261 2260 +3 2277 2269 2268 +3 2290 2277 2276 +3 2342 2290 2289 +3 2354 2342 2341 +3 2359 2353 2358 +3 2354 2353 2359 +3 2367 2358 2366 +3 2359 2358 2367 +3 2371 2366 2370 +3 2367 2366 2371 +3 2282 2291 2344 +3 2362 2368 2373 +3 2368 2372 2373 +3 2360 2368 2362 +3 2360 2362 2357 +3 2360 2357 2355 +3 2357 2344 2355 +3 2344 2343 2355 +3 2291 2343 2344 +3 2278 2291 2282 +3 2278 2282 2273 +3 2278 2273 2270 +3 2273 2263 2270 +3 2263 2262 2270 +3 8545 7267 7073 +3 7429 7267 8545 +3 7429 8545 7525 +3 8545 7657 7525 +3 7817 7657 8545 +3 7817 8545 7969 +3 8545 8239 7969 +3 4223 5256 5412 +3 5072 5256 4223 +3 5072 4223 4980 +3 4223 4876 4980 +3 4690 4876 4223 +3 4690 4223 4542 +3 4223 4287 4542 +3 6683 5635 6871 +3 5635 6975 6871 +3 5791 5635 6683 +3 5791 6683 6539 +3 5791 6539 5935 +3 6540 5792 5936 +3 6540 5936 6213 +3 6540 6213 6285 +3 6213 6539 6285 +3 5935 6539 6213 +3 7073 5411 4222 +3 5411 5255 4222 +3 5255 5071 4222 +3 5071 4979 4222 +3 4979 4875 4222 +3 4875 4689 4222 +3 4689 4541 4222 +3 4541 4287 4222 +3 4287 4223 4222 +3 6872 5792 6684 +3 5792 6540 6684 +3 5636 5792 6872 +3 5636 6872 5504 +3 6872 6976 5504 +3 6976 7074 5504 +3 7074 5412 5504 +3 4223 5412 7074 +3 4223 7074 8546 +3 7074 7268 8546 +3 7268 7430 8546 +3 7430 7526 8546 +3 7526 7658 8546 +3 7658 7818 8546 +3 7818 7970 8546 +3 7970 8239 8546 +3 8239 8545 8546 +3 5411 6975 5503 +3 6975 5635 5503 +3 7073 6975 5411 +3 8545 7073 4222 +3 8551 4228 8550 +3 8550 4227 8549 +3 8549 4226 8548 +3 8548 4225 8547 +3 8546 8547 4223 +3 8547 4224 4223 +3 4225 4224 8547 +3 4226 4225 8548 +3 4227 4226 8549 +3 4228 4227 8550 +3 4229 4228 8551 +3 4229 8551 8552 +3 4219 4221 4212 +3 4217 4200 4216 +3 4200 4193 4202 +3 4220 4221 4229 +3 4212 4221 4220 +3 4205 4220 4218 +3 4205 4212 4220 +3 4201 4194 4192 +3 4204 4191 4200 +3 4204 4197 4191 +3 4197 4184 4191 +3 4197 4192 4184 +3 4183 4184 4192 +3 4203 4201 4215 +3 4194 4201 4203 +3 4217 4219 4204 +3 4219 4212 4204 +3 4205 4204 4212 +3 4205 4197 4204 +3 4218 4201 4205 +3 4218 4215 4201 +3 4192 4205 4201 +3 4192 4197 4205 +3 4183 4192 4194 +3 4193 4191 4182 +3 4191 4184 4182 +3 4184 4177 4182 +3 4183 4177 4184 +3 4215 4218 4229 +3 4218 4220 4229 +3 4175 4177 4180 +3 4180 4183 4187 +3 4187 4194 4198 +3 4198 4203 4213 +3 4198 4213 4210 +3 4213 4215 4229 +3 4210 4213 4229 +3 4224 4225 4216 +3 4224 4216 4214 +3 4224 4214 4223 +3 4214 4209 4223 +3 4196 4214 4202 +3 4214 4216 4202 +3 4209 4214 4196 +3 4217 4225 4226 +3 4216 4225 4217 +3 4202 4216 4200 +3 4196 4202 4193 +3 4196 4193 4186 +3 4228 4229 4221 +3 4228 4221 4227 +3 4221 4219 4227 +3 4219 4226 4227 +3 4217 4226 4219 +3 4200 4217 4204 +3 4193 4200 4191 +3 4186 4193 4182 +3 4186 4182 4179 +3 4182 4177 4179 +3 4177 4174 4179 +3 4203 4215 4213 +3 4194 4203 4198 +3 4183 4194 4187 +3 4177 4183 4180 +3 4174 4177 4175 +3 4174 4175 4146 +3 4178 4179 4174 +3 4185 4186 4179 +3 4186 4195 4196 +3 4196 4208 4209 +3 4209 4222 4223 +3 4208 4222 4209 +3 4195 4208 4196 +3 4185 4195 4186 +3 4178 4185 4179 +3 4173 4178 4174 +3 4173 4174 4146 +3 4173 4146 4145 +3 6979 5507 6881 +3 6543 6217 6289 +3 6289 5937 6541 +3 5637 6873 5793 +3 6977 6873 5637 +3 5413 6977 5505 +3 6977 5637 5505 +3 7075 6977 5413 +3 6541 5793 6685 +3 5793 6873 6685 +3 5937 5793 6541 +3 6217 5937 6289 +3 5939 6217 6543 +3 5939 6543 5795 +3 6543 6687 5795 +3 6687 6881 5795 +3 6881 5645 5795 +3 5507 5645 6881 +3 5415 5507 6979 +3 5415 6979 7077 +3 5415 7077 4230 +3 5415 4230 5265 +3 4230 5075 5265 +3 4983 5075 4230 +3 4983 4230 4885 +3 4230 4693 4885 +3 4545 4693 4230 +3 4545 4230 4291 +3 4230 4229 4291 +3 4229 4543 4291 +3 4691 4543 4229 +3 4691 4229 4877 +3 4229 4981 4877 +3 5073 4981 4229 +3 5073 4229 5257 +3 4229 5413 5257 +3 7075 5413 4229 +3 7075 4229 7269 +3 4229 8552 7269 +3 8552 7431 7269 +3 7527 7431 8552 +3 7527 8552 7659 +3 8552 7819 7659 +3 7971 7819 8552 +3 7971 8552 8243 +3 8552 8625 8243 +3 8625 7973 8243 +3 7821 7973 8625 +3 7821 8625 7667 +3 8625 7529 7667 +3 7433 7529 8625 +3 7433 8625 7277 +3 8625 7077 7277 +3 4230 7077 8625 +3 4163 4172 4165 +3 4172 4167 4165 +3 4169 4167 4172 +3 4169 4172 4170 +3 4158 4160 4171 +3 4160 4162 4171 +3 4162 4164 4171 +3 4164 4166 4171 +3 4166 4168 4171 +3 4168 4170 4171 +3 4170 4172 4171 +3 4159 4172 4161 +3 4172 4163 4161 +3 4146 4172 4159 +3 4146 4159 4157 +3 4146 4157 4155 +3 4146 4155 4153 +3 4146 4153 4151 +3 4146 4151 4149 +3 4146 4149 4147 +3 4146 4147 4145 +3 4147 4148 4145 +3 4148 4150 4145 +3 4150 4152 4145 +3 4152 4154 4145 +3 4154 4156 4145 +3 4156 4158 4145 +3 4158 4171 4145 +3 4211 4210 4229 +3 4210 4199 4198 +3 4188 4187 4198 +3 4181 4180 4187 +3 4176 4175 4180 +3 4175 4172 4146 +3 4176 4172 4175 +3 4181 4176 4180 +3 4188 4181 4187 +3 4199 4188 4198 +3 4211 4199 4210 +3 4230 4211 4229 +3 2162 2499 2352 +3 2685 1931 2581 +3 2581 2064 2498 +3 2506 2072 2588 +3 2692 2588 1939 +3 2692 1806 2796 +3 2274 2802 2698 +3 2797 2346 2693 +3 2693 2347 2589 +3 2589 2348 2507 +3 2499 2065 2582 +3 2582 1932 2686 +3 2686 1799 2790 +3 2679 1924 2575 +3 2575 2057 2492 +3 2574 2491 2056 +3 2574 1923 2678 +3 1790 2782 2678 +3 2185 2511 2080 +3 2080 2593 1951 +3 1815 2697 2801 +3 1815 2801 1694 +3 2796 1694 2878 +3 1694 2801 2878 +3 1806 1694 2796 +3 1939 1806 2692 +3 2072 1939 2588 +3 2169 2072 2506 +3 2169 2506 2240 +3 2506 2421 2240 +3 2421 2498 2240 +3 2498 2161 2240 +3 2064 2161 2498 +3 1931 2064 2581 +3 1798 1931 2685 +3 1798 2685 2789 +3 1798 2789 1684 +3 2782 1684 2870 +3 1684 2789 2870 +3 1790 1684 2782 +3 1923 1790 2678 +3 2056 1923 2574 +3 2153 2056 2491 +3 2153 2491 2416 +3 2153 2416 2233 +3 2416 2492 2233 +3 2492 2154 2233 +3 2057 2154 2492 +3 1924 2057 2575 +3 1791 1924 2679 +3 1791 2679 2783 +3 1791 2783 1685 +3 2790 1685 2871 +3 1685 2783 2871 +3 1799 1685 2790 +3 1932 1799 2686 +3 2065 1932 2582 +3 2162 2065 2499 +3 2241 2162 2352 +3 2507 2352 2422 +3 2352 2499 2422 +3 2348 2352 2507 +3 2347 2348 2589 +3 2346 2347 2693 +3 2293 2346 2797 +3 2293 2797 2879 +3 2293 2879 2284 +3 2879 2802 2284 +3 2802 2274 2284 +3 2265 2698 2594 +3 2274 2698 2265 +3 1951 2697 1859 +3 2697 1815 1859 +3 2593 2697 1951 +3 2511 2593 2080 +3 2429 2511 2185 +3 2429 2185 2188 +3 2429 2188 2512 +3 2188 2083 2512 +3 2083 2594 2512 +3 2265 2594 2083 +3 3915 4015 4014 +3 3689 3662 3791 +3 3662 3661 3549 +3 3230 3160 3111 +3 3160 3110 3111 +3 3229 3160 3230 +3 3229 3230 3279 +3 3230 3350 3279 +3 3350 3349 3279 +3 3400 3349 3350 +3 3400 3350 3426 +3 3400 3426 3425 +3 3426 3549 3425 +3 3549 3543 3425 +3 3661 3543 3549 +3 3689 3661 3662 +3 3790 3689 3791 +3 3790 3791 3913 +3 3791 4014 3913 +3 4014 4013 3913 +3 4015 4013 4014 +3 3914 4015 3915 +3 4895 3546 4894 +3 2882 2883 1701 +3 7439 7438 7535 +3 8626 7979 7978 +3 8626 7978 8255 +3 7827 7679 7678 +3 7679 7535 7678 +3 7535 7534 7678 +3 7438 7534 7535 +3 7288 7438 7439 +3 7288 7439 7289 +3 7288 7289 7082 +3 8625 7435 7285 +3 7531 7435 8625 +3 7531 8625 7675 +3 8625 7823 7675 +3 7975 7823 8625 +3 7975 8625 8254 +3 8625 7976 8254 +3 7824 7677 7676 +3 7437 7436 7533 +3 7286 7436 7437 +3 7286 7437 7287 +3 7286 7287 7080 +3 7287 7081 7080 +3 7081 6983 7080 +3 6983 6982 7080 +3 6890 6982 6983 +3 5802 6894 5658 +3 4895 4986 4987 +3 6229 6301 5944 +3 5944 6548 5800 +3 5658 6986 5514 +3 6986 5422 5514 +3 6894 6986 5658 +3 6694 6894 5802 +3 6694 5802 6550 +3 5802 5946 6550 +3 5946 6230 6550 +3 6230 6302 6550 +3 6549 6302 6230 +3 6549 6230 5945 +3 6549 5945 5801 +3 6549 5801 6693 +3 5801 5657 6693 +3 5657 6893 6693 +3 5656 6893 5657 +3 5656 5657 5513 +3 5656 5513 5512 +3 5513 5421 5512 +3 5421 5420 5512 +3 5276 5420 5421 +3 5276 5421 5277 +3 5276 5277 5080 +3 5797 5653 6689 +3 6228 6545 6300 +3 6228 6300 6546 +3 6228 6546 5942 +3 6890 5798 6690 +3 5798 6546 6690 +3 5942 6546 5798 +3 5654 6890 6891 +3 6890 6983 6891 +3 5798 6890 5654 +3 6985 7082 7083 +3 7082 7289 7083 +3 6984 7082 6985 +3 6984 6985 6892 +3 6985 6893 6892 +3 6893 5656 6892 +3 5656 5800 6892 +3 5800 6692 6892 +3 6548 6692 5800 +3 6301 6548 5944 +3 6547 6301 6229 +3 6547 6229 5943 +3 6547 5943 5799 +3 6547 5799 6691 +3 5799 5655 6691 +3 5655 6891 6691 +3 5654 6891 5655 +3 5654 5655 5511 +3 5654 5511 5510 +3 5511 5419 5510 +3 5419 5418 5510 +3 5274 5418 5419 +3 5274 5419 5275 +3 5274 5275 5078 +3 4696 4894 3682 +3 4696 3682 4548 +3 2883 2980 2981 +3 4079 4303 3817 +3 3817 4550 3684 +3 2611 1842 2728 +3 4199 3814 3681 +3 4987 5078 5079 +3 5078 5275 5079 +3 4986 5078 4987 +3 4894 4986 4895 +3 3682 4894 3546 +3 4989 5080 5081 +3 5080 5277 5081 +3 4988 5080 4989 +3 4988 4989 4897 +3 4988 4897 4896 +3 4897 3548 4896 +3 3548 3684 4896 +3 3684 4698 4896 +3 4550 4698 3684 +3 4303 4550 3817 +3 4549 4303 4079 +3 4549 4079 3816 +3 4549 3816 3683 +3 4549 3683 4697 +3 3683 3547 4697 +3 3547 4895 4697 +3 3546 4895 3547 +3 3546 3547 3423 +3 3546 3423 3422 +3 3423 3347 3422 +3 3347 3346 3422 +3 3218 3346 3347 +3 3218 3347 3219 +3 3218 3219 3057 +3 2882 1843 2729 +3 1843 2612 2729 +3 3420 4172 3344 +3 2978 3055 3056 +3 2340 1840 2339 +3 2339 1327 344 +3 1209 1330 1340 +3 1340 1466 1472 +3 1552 1560 1472 +3 1702 1560 1701 +3 1702 2883 1816 +3 1952 1816 2730 +3 1952 2613 2186 +3 2186 2432 2084 +3 3230 3348 3350 +3 3350 3424 3426 +3 3426 3548 3549 +3 3549 4897 3662 +3 3662 4699 3791 +3 4014 3791 4551 +3 4014 4304 3915 +3 7676 7533 7532 +3 7533 7436 7532 +3 7677 7533 7676 +3 7825 7677 7824 +3 7825 7824 7977 +3 7824 7976 7977 +3 7976 8625 7977 +3 8625 8255 7977 +3 8626 8255 8625 +3 4230 7285 7079 +3 8625 7285 4230 +3 5797 6545 5941 +3 6545 6228 5941 +3 6689 6545 5797 +3 6889 6689 5653 +3 6889 5653 6981 +3 5653 5509 6981 +3 5509 5417 6981 +3 5417 7079 6981 +3 4230 7079 5417 +3 4230 5417 5273 +3 4230 5273 5077 +3 4230 5077 4985 +3 4230 4985 4893 +3 4230 4893 4695 +3 4230 4695 4211 +3 4078 4548 3815 +3 4548 3682 3815 +3 4302 4548 4078 +3 4302 4078 4547 +3 4078 3814 4547 +3 3814 4211 4547 +3 4211 4695 4547 +3 4199 4211 3814 +3 4188 4199 3681 +3 4188 3681 3545 +3 4188 3545 4181 +3 4176 3545 3421 +3 4181 3545 4176 +3 2978 2979 2880 +3 2979 2881 2880 +3 3056 2979 2978 +3 3217 3056 3055 +3 3217 3055 3216 +3 3217 3216 3345 +3 3216 3344 3345 +3 3344 4172 3345 +3 4172 3421 3345 +3 4176 3421 4172 +3 4138 4171 4172 +3 4137 4171 4138 +3 3680 4172 3544 +3 4172 3420 3544 +3 4138 4172 3680 +3 4138 3680 3813 +3 4138 3813 4077 +3 345 344 639 +3 345 639 640 +3 345 640 416 +3 1465 1464 1551 +3 2728 1700 2881 +3 1842 1700 2728 +3 1989 1842 2611 +3 1989 2611 2249 +3 2611 2431 2249 +3 2431 2612 2249 +3 2612 1990 2249 +3 1843 1990 2612 +3 2981 3057 3058 +3 3057 3219 3058 +3 2980 3057 2981 +3 2882 2980 2883 +3 1843 2882 1701 +3 7978 7827 7826 +3 7827 7678 7826 +3 7979 7827 7978 +3 8256 7979 8626 +3 8256 8626 7980 +3 8626 7828 7980 +3 7680 7828 8626 +3 7680 8626 7536 +3 8626 7440 7536 +3 7290 7440 8626 +3 7290 8626 7084 +3 8626 4232 7084 +3 4232 5422 7084 +3 5422 6986 7084 +3 5278 5422 4232 +3 5278 4232 5082 +3 4232 4990 5082 +3 4898 4990 4232 +3 4898 4232 4700 +3 4232 3915 4700 +3 3915 4552 4700 +3 4304 4552 3915 +3 4551 4304 4014 +3 4699 4551 3791 +3 4897 4699 3662 +3 3548 4897 3549 +3 3424 3548 3426 +3 3348 3424 3350 +3 3220 3348 3230 +3 3220 3230 3111 +3 3220 3111 3059 +3 3111 2982 3059 +3 2884 2982 3111 +3 2884 3111 2084 +3 2884 2084 2731 +3 2084 2614 2731 +3 2432 2614 2084 +3 2613 2432 2186 +3 2730 2613 1952 +3 2883 2730 1816 +3 1701 2883 1702 +3 1552 1701 1560 +3 1466 1552 1472 +3 1330 1466 1340 +3 1161 1330 1209 +3 1161 1209 1079 +3 1209 345 1079 +3 345 985 1079 +3 786 985 345 +3 786 345 641 +3 345 416 641 +3 982 783 344 +3 982 344 1076 +3 344 1158 1076 +3 1327 1158 344 +3 1463 1327 2339 +3 1463 2339 1549 +3 2339 1698 1549 +3 1840 1698 2339 +3 1987 1840 2340 +3 1987 2340 2248 +3 2340 1988 2248 +3 1841 1988 2340 +3 2727 2340 2610 +3 2340 2430 2610 +3 1841 2340 2727 +3 1841 2727 2880 +3 1841 2880 1699 +3 2880 2881 1699 +3 2881 1700 1699 +3 1700 1551 1699 +3 1551 1550 1699 +3 1464 1550 1551 +3 1328 1464 1465 +3 1328 1465 1329 +3 1328 1329 1159 +3 1329 1160 1159 +3 1160 1078 1159 +3 1078 1077 1159 +3 983 1077 1078 +3 983 1078 984 +3 983 984 784 +3 984 785 784 +3 785 640 784 +3 640 639 784 +3 415 344 638 +3 344 783 638 +3 639 344 415 +3 347 1468 3163 +3 347 642 417 +3 346 1080 986 +3 1162 1080 346 +3 1162 346 1331 +3 346 1467 1331 +3 1553 1467 346 +3 1553 346 1703 +3 346 3163 1703 +3 3163 1844 1703 +3 1991 1844 3163 +3 1991 3163 2250 +3 3163 1992 2250 +3 1845 1992 3163 +3 1845 3163 1704 +3 3163 1554 1704 +3 1468 1554 3163 +3 1332 1468 347 +3 1332 347 1163 +3 347 1081 1163 +3 987 1081 347 +3 987 347 788 +3 347 643 788 +3 642 346 787 +3 346 986 787 +3 347 346 642 +3 643 347 417 +3 1205 1208 1253 +3 1323 1253 1257 +3 1323 1339 1383 +3 1394 1435 1383 +3 503 502 598 +3 598 597 731 +3 867 731 730 +3 866 969 867 +3 969 968 1040 +3 1040 1039 1120 +3 1119 1198 1120 +3 1197 1246 1198 +3 1510 1428 1427 +3 1798 1797 1931 +3 1930 2064 1931 +3 1939 1805 1806 +3 1806 1693 1694 +3 1601 1559 1694 +3 1435 1471 1517 +3 1394 1471 1435 +3 1339 1394 1383 +3 1257 1339 1323 +3 1208 1257 1253 +3 1130 1205 1127 +3 1208 1205 1130 +3 1082 1127 1047 +3 1130 1127 1082 +3 1000 1047 978 +3 1082 1047 1000 +3 894 978 874 +3 1000 978 894 +3 789 874 738 +3 894 874 789 +3 656 738 605 +3 789 738 656 +3 522 605 510 +3 656 605 522 +3 502 406 405 +3 406 510 405 +3 522 510 406 +3 1559 1517 1522 +3 1517 1471 1522 +3 1601 1517 1559 +3 1693 1601 1694 +3 1805 1693 1806 +3 1938 1805 1939 +3 1938 1939 2072 +3 1938 2072 2071 +3 2072 2169 2071 +3 2169 2168 2071 +3 2239 2168 2169 +3 2239 2169 2240 +3 2239 2240 2160 +3 2240 2161 2160 +3 2161 2064 2160 +3 2064 2063 2160 +3 1930 2063 2064 +3 1797 1930 1931 +3 1683 1797 1798 +3 1683 1798 1684 +3 1683 1684 1593 +3 1684 1594 1593 +3 1594 1510 1593 +3 1510 1509 1593 +3 1427 1509 1510 +3 1375 1427 1428 +3 1375 1428 1376 +3 1375 1376 1313 +3 1376 1314 1313 +3 1314 1246 1313 +3 1246 1245 1313 +3 1197 1245 1246 +3 1119 1197 1198 +3 1039 1119 1120 +3 968 1039 1040 +3 866 968 969 +3 730 866 867 +3 597 730 731 +3 502 597 598 +3 406 502 503 +3 406 503 407 +3 301 407 503 +3 301 503 292 +3 731 292 598 +3 292 503 598 +3 284 292 731 +3 284 731 867 +3 284 867 276 +3 859 276 969 +3 276 867 969 +3 268 276 859 +3 268 859 723 +3 268 723 260 +3 495 260 590 +3 260 723 590 +3 254 260 495 +3 254 495 399 +3 254 399 496 +3 254 496 261 +3 724 261 591 +3 261 496 591 +3 269 261 724 +3 269 724 860 +3 269 860 277 +3 333 348 340 +3 349 348 333 +3 349 333 326 +3 349 326 350 +3 326 319 350 +3 319 351 350 +3 352 351 319 +3 352 319 312 +3 352 312 353 +3 312 305 353 +3 305 354 353 +3 355 354 305 +3 355 305 302 +3 355 302 356 +3 868 277 970 +3 277 860 970 +3 285 277 868 +3 285 868 732 +3 285 732 293 +3 732 599 293 +3 599 504 293 +3 504 302 293 +3 356 302 504 +3 356 504 408 +3 289 282 281 +3 274 273 281 +3 264 216 272 +3 272 209 280 +3 196 197 190 +3 253 239 258 +3 186 181 179 +3 165 155 158 +3 158 151 164 +3 164 144 171 +3 178 177 184 +3 178 184 185 +3 184 190 185 +3 190 191 185 +3 197 191 190 +3 205 197 196 +3 205 196 204 +3 205 204 211 +3 198 206 202 +3 41 42 33 +3 24 31 32 +3 32 39 40 +3 6 7 1 +3 6 1 14 +3 1 22 14 +3 30 22 1 +3 30 1 38 +3 1 46 38 +3 56 46 1 +3 56 1 59 +3 62 78 66 +3 80 86 81 +3 86 83 81 +3 90 86 80 +3 90 80 79 +3 90 79 97 +3 79 78 97 +3 78 103 97 +3 183 129 123 +3 136 129 176 +3 136 169 143 +3 162 150 143 +3 150 157 156 +3 149 156 163 +3 149 170 142 +3 142 177 135 +3 122 118 114 +3 114 112 109 +3 109 106 104 +3 98 104 100 +3 125 121 127 +3 121 119 115 +3 115 113 110 +3 110 107 105 +3 101 99 105 +3 99 94 93 +3 101 94 99 +3 107 101 105 +3 113 107 110 +3 119 113 115 +3 125 119 121 +3 131 125 127 +3 131 127 133 +3 131 133 181 +3 131 181 139 +3 146 139 174 +3 146 167 153 +3 167 160 153 +3 174 167 146 +3 181 174 139 +3 251 286 248 +3 278 246 248 +3 246 270 244 +3 244 262 242 +3 242 230 240 +3 188 132 182 +3 182 138 175 +3 175 145 168 +3 168 152 161 +3 154 159 161 +3 141 134 180 +3 141 180 173 +3 141 173 147 +3 159 147 166 +3 147 173 166 +3 154 147 159 +3 152 154 161 +3 145 152 168 +3 138 145 175 +3 132 138 182 +3 126 132 188 +3 126 188 194 +3 126 194 120 +3 194 199 120 +3 199 116 120 +3 89 72 87 +3 87 74 84 +3 84 75 82 +3 82 73 77 +3 82 77 85 +3 77 88 85 +3 95 88 77 +3 77 71 69 +3 58 54 57 +3 57 44 53 +3 53 36 52 +3 51 52 43 +3 52 35 43 +3 27 52 28 +3 35 52 27 +3 27 20 19 +3 19 12 11 +3 11 2 4 +3 33 34 25 +3 42 34 33 +3 50 42 41 +3 50 41 49 +3 305 310 302 +3 302 303 293 +3 251 293 294 +3 285 293 251 +3 285 251 250 +3 285 250 277 +3 269 250 249 +3 277 250 269 +3 261 249 247 +3 269 249 261 +3 254 247 245 +3 261 247 254 +3 260 245 243 +3 254 245 260 +3 237 229 241 +3 229 221 241 +3 221 268 241 +3 268 243 241 +3 260 243 268 +3 171 137 178 +3 144 137 171 +3 151 144 164 +3 155 151 158 +3 148 155 165 +3 148 165 172 +3 148 172 140 +3 172 179 140 +3 179 133 140 +3 181 133 179 +3 187 181 186 +3 187 186 192 +3 187 192 193 +3 192 198 193 +3 198 200 193 +3 202 200 198 +3 208 202 206 +3 208 206 212 +3 208 212 214 +3 212 219 214 +3 219 276 214 +3 276 221 214 +3 268 221 276 +3 217 211 210 +3 211 204 210 +3 218 211 217 +3 218 217 274 +3 218 274 266 +3 218 266 226 +3 266 258 226 +3 258 233 226 +3 239 233 258 +3 234 239 253 +3 234 253 259 +3 234 259 227 +3 259 267 227 +3 267 275 227 +3 275 219 227 +3 276 219 275 +3 276 275 283 +3 276 283 284 +3 300 309 316 +3 299 309 300 +3 299 300 291 +3 300 284 291 +3 284 283 291 +3 292 284 300 +3 292 300 301 +3 280 203 288 +3 209 203 280 +3 216 209 272 +3 224 216 264 +3 224 264 231 +3 264 256 231 +3 256 252 231 +3 252 238 231 +3 232 238 252 +3 232 252 257 +3 232 257 265 +3 232 265 225 +3 265 273 225 +3 273 217 225 +3 274 217 273 +3 282 274 281 +3 290 282 289 +3 290 289 298 +3 289 297 298 +3 297 307 298 +3 307 308 298 +3 315 308 307 +3 315 307 314 +3 315 314 321 +3 315 321 322 +3 321 328 322 +3 328 329 322 +3 336 329 328 +3 336 328 335 +3 336 335 345 +3 336 345 342 +3 345 337 342 +3 330 337 345 +3 330 345 323 +3 345 316 323 +3 300 316 345 +3 98 92 91 +3 100 92 98 +3 106 100 104 +3 112 106 109 +3 118 112 114 +3 124 118 122 +3 124 122 128 +3 124 128 130 +3 128 135 130 +3 135 178 130 +3 178 137 130 +3 177 178 135 +3 170 177 142 +3 163 170 149 +3 157 163 156 +3 162 157 150 +3 169 162 143 +3 176 169 136 +3 183 176 129 +3 189 183 123 +3 189 123 117 +3 189 117 195 +3 117 344 195 +3 344 203 195 +3 288 203 344 +3 288 344 296 +3 344 306 296 +3 313 306 344 +3 313 344 320 +3 344 327 320 +3 334 327 344 +3 334 344 341 +3 344 335 341 +3 345 335 344 +3 66 76 70 +3 78 76 66 +3 103 78 62 +3 103 62 59 +3 103 59 111 +3 59 1 111 +3 1 117 111 +3 344 117 1 +3 40 47 48 +3 39 47 40 +3 31 39 32 +3 23 31 24 +3 23 24 16 +3 23 16 15 +3 16 8 15 +3 8 7 15 +3 1 7 8 +3 1 8 3 +3 1 3 2 +3 287 213 279 +3 279 220 271 +3 271 228 263 +3 235 255 263 +3 242 255 236 +3 262 255 242 +3 270 262 244 +3 278 270 246 +3 286 278 248 +3 294 286 251 +3 303 294 293 +3 310 303 302 +3 317 310 305 +3 317 305 312 +3 317 312 324 +3 346 333 340 +3 326 333 346 +3 326 346 319 +3 346 324 319 +3 324 312 319 +3 331 324 346 +3 331 346 338 +3 346 347 338 +3 347 343 338 +3 339 343 347 +3 339 347 332 +3 347 325 332 +3 318 325 347 +3 318 347 311 +3 304 347 295 +3 311 347 304 +3 2 45 55 +3 37 45 2 +3 37 2 29 +3 2 21 29 +3 13 21 2 +3 13 2 5 +3 2 12 5 +3 18 25 26 +3 25 34 26 +3 17 25 18 +3 17 18 10 +3 17 10 9 +3 10 4 9 +3 4 3 9 +3 2 3 4 +3 12 2 11 +3 20 12 19 +3 28 20 27 +3 36 28 52 +3 44 36 53 +3 54 44 57 +3 60 54 58 +3 60 58 63 +3 60 63 64 +3 63 69 64 +3 69 67 64 +3 71 67 69 +3 73 71 77 +3 75 73 82 +3 74 75 84 +3 72 74 87 +3 68 72 89 +3 68 89 96 +3 68 96 65 +3 96 102 65 +3 102 61 65 +3 240 222 223 +3 222 215 223 +3 230 222 240 +3 236 230 242 +3 235 236 255 +3 228 235 263 +3 220 228 271 +3 213 220 279 +3 207 213 287 +3 207 287 295 +3 207 295 201 +3 295 347 201 +3 347 199 201 +3 116 199 347 +3 116 347 2 +3 116 2 108 +3 2 61 108 +3 61 102 108 +3 55 61 2 +3 6844 6838 5598 +3 6860 6850 5610 +3 2841 1642 2845 +3 3537 4884 4874 +3 770 936 927 +3 927 1065 1063 +3 1642 2721 1827 +3 1660 2723 1831 +3 963 973 1071 +3 1980 2607 1833 +3 1540 1669 1660 +3 1669 2852 1660 +3 1542 1669 1540 +3 1542 1540 1456 +3 1290 1456 1454 +3 1456 1540 1454 +3 1298 1456 1290 +3 1298 1290 1151 +3 1290 1149 1151 +3 1149 1067 1151 +3 1067 1069 1151 +3 954 1069 1067 +3 954 1067 945 +3 954 945 776 +3 945 774 776 +3 774 629 776 +3 629 631 776 +3 347 633 393 +3 347 393 379 +3 393 629 379 +3 631 629 393 +3 2595 1986 1839 +3 1986 2426 2244 +3 1837 2874 1688 +3 3181 3184 3338 +3 2971 3048 1449 +3 2971 1449 1535 +3 2971 1535 2838 +3 1535 1639 2838 +3 1639 1826 2838 +3 1826 2720 2838 +3 2203 2603 1973 +3 2603 1826 1973 +3 2720 1826 2603 +3 2392 2203 2604 +3 2603 2203 2392 +3 3513 4680 3676 +3 3508 3414 3415 +3 3050 3181 3049 +3 3184 3181 3050 +3 2841 2973 2972 +3 2973 3049 2972 +3 3050 3049 2973 +3 1827 2604 1974 +3 2604 2203 1974 +3 2721 2604 1827 +3 2841 2721 1642 +3 2973 2841 2845 +3 1452 1278 1282 +3 1278 1147 1282 +3 1450 1278 1452 +3 1450 1452 1536 +3 1452 1538 1536 +3 1538 1651 1536 +3 1651 1642 1536 +3 2845 1642 1651 +3 2845 1651 1829 +3 2845 1829 2722 +3 2605 1829 1976 +3 2722 1829 2605 +3 2606 2397 2213 +3 2397 1976 2213 +3 2605 1976 2397 +3 3529 4874 3678 +3 3521 4850 3513 +3 3521 3513 3416 +3 3521 3416 3417 +3 3416 3340 3417 +3 3340 3341 3417 +3 3195 3341 3340 +3 3195 3340 3188 +3 3195 3188 3052 +3 2974 3052 3051 +3 3052 3188 3051 +3 2975 3052 2974 +3 2975 2974 2852 +3 2975 2852 2859 +3 1831 2606 1978 +3 2606 2213 1978 +3 2723 2606 1831 +3 2852 2723 1660 +3 2859 2852 1669 +3 2859 1669 1833 +3 2859 1833 2724 +3 1833 2607 2724 +3 2725 1835 2866 +3 1982 1835 2725 +3 1982 2725 2608 +3 1982 2608 2227 +3 2608 2409 2227 +3 2409 1980 2227 +3 2607 1980 2409 +3 4528 3674 4676 +3 5598 6674 5778 +3 625 369 2 +3 369 624 2 +3 624 769 2 +3 769 923 2 +3 923 1062 2 +3 1062 1144 2 +3 1144 1276 2 +3 1276 1449 2 +3 1449 3048 2 +3 3048 3178 2 +3 3178 5208 2 +3 5056 5208 3178 +3 5056 3178 3337 +3 5056 3337 4964 +3 3495 4964 3413 +3 4964 3337 3413 +3 4828 4964 3495 +3 4828 3495 3673 +3 4828 3673 4674 +3 4526 3673 3806 +3 4674 3673 4526 +3 4676 3503 4838 +3 3674 3503 4676 +3 3807 3674 4528 +3 3807 4528 4032 +3 4528 4250 4032 +3 4250 3806 4032 +3 4526 3806 4250 +3 5610 6678 5782 +3 5780 6844 5604 +3 5224 5218 5060 +3 4844 3503 3508 +3 4844 3508 3675 +3 4844 3675 4678 +3 4530 3675 3808 +3 4678 3675 4530 +3 4532 4264 4041 +3 4264 3808 4041 +3 4530 3808 4264 +3 4874 4982 4978 +3 5244 5230 5068 +3 4232 4892 4694 +3 4984 4892 4232 +3 4984 4232 5076 +3 4232 5272 5076 +3 5416 4232 7078 +3 5272 4232 5416 +3 6688 5796 5652 +3 5794 6880 5644 +3 5410 5264 5414 +3 7962 7960 7808 +3 7806 7958 8300 +3 7806 8300 7614 +3 8300 7514 7614 +3 7418 7514 8300 +3 7418 8300 7224 +3 8300 7062 7224 +3 6264 5924 6190 +3 6264 6190 6534 +3 7520 7646 7636 +3 7636 7814 7812 +3 8300 7962 8216 +3 7960 8300 8206 +3 8300 7958 8206 +3 7962 8300 7960 +3 7810 7962 7808 +3 7810 7808 7624 +3 7810 7624 7630 +3 7624 7516 7630 +3 7516 7518 7630 +3 7422 7518 7516 +3 7422 7516 7420 +3 7422 7420 7234 +3 7422 7234 7240 +3 6966 7066 7064 +3 7066 7234 7064 +3 7240 7234 7066 +3 6968 6966 6838 +3 7066 6966 6968 +3 5778 6530 5922 +3 6530 6176 5922 +3 6674 6530 5778 +3 6838 6674 5598 +3 6968 6838 6844 +3 3415 3338 3339 +3 3338 3184 3339 +3 3414 3338 3415 +3 3503 3414 3508 +3 4838 3503 4844 +3 4838 4844 4968 +3 4838 4968 4966 +3 4968 5060 4966 +3 5060 5058 4966 +3 5218 5058 5060 +3 5398 5218 5224 +3 5398 5224 5400 +3 5398 5400 5492 +3 5398 5492 5490 +3 5492 5604 5490 +3 5604 5598 5490 +3 6844 5598 5604 +3 6676 6844 5780 +3 6676 5780 6532 +3 5780 5924 6532 +3 5924 6264 6532 +3 7524 7666 7656 +3 7812 7966 7964 +3 7966 8216 7964 +3 7814 7966 7812 +3 7646 7814 7636 +3 7522 7646 7520 +3 7522 7520 7426 +3 7520 7424 7426 +3 7424 7246 7426 +3 7246 7256 7426 +3 6970 7070 7068 +3 7070 7246 7068 +3 7256 7246 7070 +3 6972 6970 6850 +3 7070 6970 6972 +3 5782 6534 5926 +3 6534 6190 5926 +3 6678 6534 5782 +3 6850 6678 5610 +3 6972 6850 6860 +3 4850 4864 4976 +3 4850 4976 4970 +3 4976 5068 4970 +3 5068 5062 4970 +3 5230 5062 5068 +3 5402 5230 5244 +3 5402 5244 5408 +3 5402 5408 5500 +3 5402 5500 5494 +3 5500 5624 5494 +3 5624 5610 5494 +3 6860 5610 5624 +3 6860 5624 5788 +3 6860 5788 6680 +3 6536 5788 5932 +3 6680 5788 6536 +3 6538 5790 6682 +3 5790 6870 6682 +3 5934 5790 6538 +3 5934 6538 6208 +3 6538 6280 6208 +3 6280 5932 6208 +3 6536 5932 6280 +3 6296 6224 6544 +3 5796 6544 5940 +3 6544 6224 5940 +3 6688 6544 5796 +3 6888 6688 5652 +3 6888 5652 6980 +3 7972 7968 7820 +3 7656 7820 7816 +3 7820 7968 7816 +3 7666 7820 7656 +3 7528 7666 7524 +3 7528 7524 7432 +3 7266 7432 7428 +3 7432 7524 7428 +3 7276 7432 7266 +3 7276 7266 7076 +3 6974 7076 7072 +3 7076 7266 7072 +3 6978 7076 6974 +3 6978 6974 6870 +3 6978 6870 6880 +3 5264 5254 5074 +3 5410 5254 5264 +3 5502 5410 5414 +3 5502 5414 5506 +3 5502 5506 5644 +3 5502 5644 5634 +3 5644 6870 5634 +3 6870 5790 5634 +3 6880 6870 5644 +3 6686 6880 5794 +3 6686 5794 6542 +3 5794 5938 6542 +3 5938 6224 6542 +3 6224 6296 6542 +3 1063 1147 1145 +3 1147 1278 1145 +3 1065 1147 1063 +3 936 1065 927 +3 772 936 770 +3 772 770 625 +3 772 625 627 +3 625 2 627 +3 2 379 627 +3 347 379 2 +3 6528 6176 6250 +3 6176 6530 6250 +3 5920 6176 6528 +3 5920 6528 5776 +3 6528 6672 5776 +3 6672 6828 5776 +3 6828 5588 5776 +3 5488 5588 6828 +3 5488 6828 6964 +3 5488 6964 5396 +3 6964 7062 5396 +3 7062 8300 5396 +3 8300 5208 5396 +3 2 5208 8300 +3 7078 8626 7284 +3 8626 7434 7284 +3 7530 7434 8626 +3 7530 8626 7674 +3 8626 7822 7674 +3 7974 7822 8626 +3 7974 8626 8250 +3 8626 7972 8250 +3 7968 7972 8626 +3 7968 8626 8234 +3 8626 8216 8234 +3 8216 7966 8234 +3 8300 8216 8626 +3 5416 6980 5508 +3 6980 5652 5508 +3 7078 6980 5416 +3 8626 7078 4232 +3 4298 4231 4546 +3 4231 4694 4546 +3 4232 4694 4231 +3 4073 4231 3812 +3 4692 4884 3679 +3 4692 3679 4544 +3 3679 4231 4544 +3 4231 4298 4544 +3 3812 4231 3679 +3 4978 5074 5070 +3 5074 5254 5070 +3 4982 5074 4978 +3 4884 4982 4874 +3 3679 4884 3537 +3 3676 4532 3809 +3 4532 4041 3809 +3 4680 4532 3676 +3 4850 4680 3513 +3 4864 4850 3521 +3 4864 3521 3677 +3 4864 3677 4686 +3 3677 3810 4686 +3 3810 4538 4686 +3 4282 4538 3810 +3 4282 3810 4057 +3 4282 4057 4540 +3 4057 3811 4540 +3 3811 3678 4540 +3 3678 4688 4540 +3 4874 4688 3678 +3 3537 4874 3529 +3 3537 3529 3418 +3 3537 3418 3419 +3 3418 3342 3419 +3 3342 3343 3419 +3 3210 3343 3342 +3 3210 3342 3202 +3 3210 3202 3054 +3 2976 3054 3053 +3 3054 3202 3053 +3 2977 3054 2976 +3 2977 2976 2866 +3 2977 2866 2874 +3 1544 1460 1546 +3 1544 1546 1688 +3 1544 1688 1678 +3 1688 2866 1678 +3 2866 1835 1678 +3 2874 2866 1688 +3 2726 2874 1837 +3 2726 1837 2609 +3 2244 2609 1984 +3 2609 1837 1984 +3 2426 2609 2244 +3 2595 2426 1986 +3 2712 2595 1839 +3 2712 1839 1697 +3 2712 1697 2823 +3 1306 1460 1458 +3 1460 1544 1458 +3 1318 1460 1306 +3 1318 1306 1155 +3 1306 1153 1155 +3 1153 1071 1155 +3 1071 1073 1155 +3 973 1073 1071 +3 780 973 963 +3 780 963 778 +3 780 778 633 +3 780 633 635 +3 633 347 635 +3 347 411 635 +3 637 411 347 +3 637 347 782 +3 347 981 782 +3 1075 981 347 +3 1075 347 1157 +3 347 1326 1157 +3 1462 1326 347 +3 1462 347 3163 +3 1462 3163 1548 +3 3163 1697 1548 +3 2823 1697 3163 +3 2823 3163 2963 +3 3163 3040 2963 +3 3162 3040 3163 +3 3023 2978 2951 +3 2430 2427 2508 +3 2430 2508 2610 +3 2694 2610 2590 +3 2610 2508 2590 +3 2727 2610 2694 +3 2727 2694 2798 +3 2727 2798 2880 +3 2951 2880 2875 +3 2880 2798 2875 +3 2978 2880 2951 +3 3055 2978 3023 +3 3055 3023 3098 +3 3055 3098 3145 +3 3055 3145 3216 +3 3145 3211 3216 +3 3211 3267 3216 +3 3267 3344 3216 +3 3388 3344 3313 +3 3344 3267 3313 +3 3420 3344 3388 +3 3420 3388 3460 +3 3420 3460 3544 +3 3652 3544 3538 +3 3544 3460 3538 +3 3680 3544 3652 +3 3680 3652 3785 +3 3680 3785 3813 +3 4008 3813 3908 +3 3813 3785 3908 +3 4077 3813 4008 +3 4077 4008 4074 +3 3632 3625 3758 +3 3447 3453 3375 +3 3381 3300 3375 +3 3254 3300 3306 +3 3254 3260 3196 +3 3196 3203 3132 +3 2944 2938 3010 +3 2670 2675 2565 +3 2565 2571 2482 +3 2410 2482 2414 +3 2482 2488 2414 +3 2571 2488 2482 +3 2675 2571 2565 +3 2779 2675 2670 +3 2779 2670 2774 +3 2779 2774 2867 +3 2938 2867 2860 +3 2867 2774 2860 +3 2944 2867 2938 +3 3016 2944 3010 +3 3016 3010 3085 +3 3016 3085 3091 +3 3085 3132 3091 +3 3132 3138 3091 +3 3203 3138 3132 +3 3260 3203 3196 +3 3306 3260 3254 +3 3381 3306 3300 +3 3453 3381 3375 +3 3530 3453 3447 +3 3625 3530 3522 +3 3530 3447 3522 +3 3632 3530 3625 +3 3765 3632 3758 +3 3765 3758 3881 +3 3765 3881 3888 +3 3881 3981 3888 +3 3981 3988 3888 +3 4062 3988 3981 +3 4062 3981 4058 +3 6987 5407 4206 +3 4539 4195 4273 +3 6271 5933 6199 +3 6271 6199 6535 +3 6199 5931 6535 +3 5931 5787 6535 +3 5787 6679 6535 +3 4143 4273 4109 +3 4273 4185 4109 +3 4537 4273 4143 +3 4537 4143 4189 +3 4537 4189 4685 +3 4189 4206 4685 +3 4206 4855 4685 +3 4975 4855 4206 +3 4975 4206 5067 +3 4206 5235 5067 +3 5407 5235 4206 +3 5499 5407 6987 +3 5499 6987 5615 +3 6987 5787 5615 +3 6679 5787 6987 +3 6679 6987 6851 +3 6987 6971 6851 +3 7069 6971 6987 +3 7069 6987 7093 +3 7069 7093 7247 +3 7093 7291 7247 +3 7291 7425 7247 +3 7521 7425 7291 +3 7521 7291 8423 +3 7521 8423 7637 +3 8423 7813 7637 +3 7965 7813 8423 +3 7965 8423 8225 +3 8423 8545 8225 +3 8545 7967 8225 +3 7815 7967 8545 +3 7815 8545 7647 +3 8545 7523 7647 +3 7427 7523 8545 +3 7427 8545 7257 +3 8545 7071 7257 +3 4145 4171 4137 +3 4145 4137 4109 +3 4145 4109 4173 +3 4109 4178 4173 +3 4185 4178 4109 +3 4195 4185 4273 +3 4208 4195 4539 +3 4208 4539 4687 +3 4208 4687 4222 +3 4687 4865 4222 +3 4865 4977 4222 +3 4977 5069 4222 +3 5069 5245 4222 +3 5245 5409 4222 +3 5409 7071 4222 +3 7071 8545 4222 +3 6973 7071 5409 +3 6973 5409 5501 +3 6973 5501 6861 +3 5789 6861 5625 +3 6861 5501 5625 +3 6681 6861 5789 +3 6681 5789 6537 +3 5789 5933 6537 +3 5933 6271 6537 +3 7957 8361 8197 +3 8361 7959 8197 +3 7807 7959 8361 +3 7807 8361 7615 +3 8361 7515 7615 +3 6671 5775 5579 +3 6527 6241 6167 +3 6241 6529 6167 +3 6529 5921 6167 +3 5777 6529 6673 +3 5921 6529 5777 +3 4107 4241 4527 +3 4829 4107 4675 +3 4107 4527 4675 +3 4805 4107 4829 +3 4805 4829 4965 +3 4805 4965 5057 +3 4805 5057 5209 +3 4805 5209 5397 +3 4805 5397 6231 +3 5397 5489 6231 +3 5489 5589 6231 +3 5589 5777 6231 +3 5777 6673 6231 +3 6673 6829 6231 +3 6829 6965 6231 +3 6965 7063 6231 +3 7063 7225 6231 +3 7225 7419 6231 +3 7419 7515 6231 +3 7515 8361 6231 +3 7215 7061 8299 +3 7215 8299 7417 +3 8299 7513 7417 +3 7605 7513 8299 +3 7605 8299 7805 +3 8299 7957 7805 +3 8361 7957 8299 +3 5775 6527 5919 +3 6527 6167 5919 +3 6671 6527 5775 +3 6819 6671 5579 +3 6819 5579 6963 +3 5579 5487 6963 +3 5487 5395 6963 +3 5395 7061 6963 +3 8299 7061 5395 +3 8299 5395 4092 +3 5395 5199 4092 +3 5199 5055 4092 +3 5055 4963 4092 +3 4963 4819 4092 +3 4819 4673 4092 +3 4673 4525 4092 +3 4525 4241 4092 +3 4241 4107 4092 +3 1555 1556 1617 +3 1555 1617 1814 +3 1555 1814 2302 +3 2251 2257 8628 +3 2257 2266 1948 +3 2266 1814 1948 +3 2302 1814 2266 +3 2302 2266 2280 +3 2302 2280 2303 +3 2462 2119 2545 +3 2545 2023 2650 +3 2650 1890 2754 +3 2708 1884 2625 +3 2625 2017 2520 +3 1653 1756 2309 +3 1653 2309 1750 +3 1877 2304 1744 +3 1717 2266 1849 +3 1953 1849 2257 +3 1953 2251 2085 +3 1953 0 8627 +3 2257 2251 1953 +3 2266 2257 1849 +3 2280 2266 1717 +3 2280 1717 1644 +3 2280 1644 2303 +3 1644 1744 2303 +3 1744 2304 2303 +3 2106 2305 2010 +3 2305 1877 2010 +3 2304 1877 2305 +3 2306 2106 2207 +3 2305 2106 2306 +3 2016 2306 2112 +3 2306 2207 2112 +3 2307 2306 2016 +3 2307 2016 1883 +3 2307 1883 2308 +3 1883 1750 2308 +3 1750 2309 2308 +3 2310 1756 1889 +3 2309 1756 2310 +3 2118 2311 2022 +3 2311 1889 2022 +3 2310 1889 2311 +3 2119 2312 2214 +3 2312 2118 2214 +3 2311 2118 2312 +3 2285 1645 1705 +3 1745 1645 2285 +3 1745 2285 2349 +3 1745 2349 1878 +3 2349 2363 1878 +3 2363 2011 1878 +3 2107 2011 2363 +3 2107 2363 2520 +3 2107 2520 2208 +3 2520 2113 2208 +3 2017 2113 2520 +3 1884 2017 2625 +3 1751 1884 2708 +3 1751 2708 2812 +3 1751 2812 1654 +3 2812 2846 1654 +3 2846 2754 1654 +3 2754 1757 1654 +3 1890 1757 2754 +3 2023 1890 2650 +3 2119 2023 2545 +3 2312 2119 2462 +3 2312 2462 2398 +3 4162 4133 4164 +3 4164 4134 4166 +3 4166 4135 4168 +3 4159 3995 4157 +3 4150 4126 4152 +3 4152 4127 4154 +3 4154 4128 4156 +3 4129 4158 4156 +3 4149 3888 3988 +3 3765 3888 4149 +3 3765 4149 4151 +3 3765 4151 3632 +3 4151 4153 3632 +3 4153 3530 3632 +3 3639 3530 4153 +3 3639 4153 4155 +3 3639 4155 3772 +3 4155 4157 3772 +3 4157 3895 3772 +3 3995 3895 4157 +3 4066 3995 4159 +3 4066 4159 4002 +3 4159 4161 4002 +3 4161 3902 4002 +3 3779 3902 4161 +3 3779 4161 4163 +3 3779 4163 3646 +3 4163 4165 3646 +3 4165 3538 3646 +3 3652 3538 4165 +3 3652 4165 4167 +3 3652 4167 3785 +3 4167 4169 3785 +3 4169 3908 3785 +3 4008 3908 4169 +3 4008 4169 4136 +3 4008 4136 4074 +3 4168 4136 4170 +3 4136 4169 4170 +3 4135 4136 4168 +3 4134 4135 4166 +3 4133 4134 4164 +3 4132 4133 4162 +3 4132 4162 4160 +3 4132 4160 4131 +3 4160 4158 4131 +3 4158 4130 4131 +3 4129 4130 4158 +3 4128 4129 4156 +3 4127 4128 4154 +3 4126 4127 4152 +3 4125 4126 4150 +3 4125 4150 4148 +3 4125 4148 4124 +3 4148 4147 4124 +3 4147 4149 4124 +3 4149 3988 4124 +3 3988 4062 4124 +3 2631 2713 2735 +3 3919 4017 4021 +3 3799 4017 3919 +3 3799 3919 3819 +3 3799 3819 3696 +3 3799 3696 3666 +3 3696 3563 3666 +3 3563 3481 3666 +3 3427 3481 3488 +3 3481 3563 3488 +3 3406 3481 3427 +3 3406 3427 3355 +3 3406 3355 3330 +3 3234 3330 3280 +3 3330 3355 3280 +3 3164 3330 3234 +3 3164 3234 3171 +3 3164 3171 3112 +3 3164 3112 3041 +3 2990 3041 3065 +3 3041 3112 3065 +3 2964 3041 2990 +3 2964 2990 2918 +3 2964 2918 2824 +3 2735 2824 2831 +3 2824 2918 2831 +3 2713 2824 2735 +3 2596 2713 2631 +3 2596 2631 2526 +3 2596 2526 2443 +3 2596 2443 2382 +3 2443 2386 2382 +3 1260 1 1136 +3 1 1054 1136 +3 907 1054 1 +3 907 1 761 +3 1 616 761 +3 357 1 617 +3 616 1 357 +3 358 359 619 +3 1444 1445 1530 +3 1443 1442 1262 +3 1262 1261 1138 +3 909 762 763 +3 617 618 763 +3 1 358 618 +3 912 1060 1059 +3 1446 1447 1532 +3 1823 1628 2828 +3 768 2 914 +3 2 1061 914 +3 1143 1061 2 +3 1143 2 1267 +3 2 1448 1267 +3 2829 2828 1629 +3 2828 1628 1629 +3 1628 1532 1629 +3 1532 1533 1629 +3 1447 1533 1532 +3 1266 1447 1446 +3 1266 1446 1265 +3 1266 1265 1142 +3 360 2 623 +3 2 768 623 +3 622 2 360 +3 8300 3170 2 +3 1059 1142 1141 +3 1142 1265 1141 +3 1060 1142 1059 +3 913 1060 912 +3 913 912 767 +3 912 766 767 +3 766 621 767 +3 621 622 767 +3 2 622 621 +3 2 621 359 +3 2 359 1 +3 2294 1623 1818 +3 1527 1623 2294 +3 1527 2294 1441 +3 2294 1260 1441 +3 1 1260 2294 +3 2295 1966 1819 +3 2193 1966 2295 +3 2193 2295 1965 +3 2295 1818 1965 +3 2294 1818 2295 +3 2713 1819 2824 +3 2295 1819 2713 +3 2295 2713 2596 +3 2295 2596 2382 +3 1821 2715 2598 +3 3483 4668 3668 +3 3331 3330 3165 +3 3165 3164 3042 +3 2965 3042 3041 +3 2965 2964 2825 +3 2714 2825 1625 +3 2714 1625 1820 +3 2714 1820 1967 +3 2714 1967 2597 +3 2715 1626 2826 +3 1821 1626 2715 +3 1968 1821 2598 +3 1968 2598 2194 +3 2598 2383 2194 +3 2383 1967 2194 +3 2597 1967 2383 +3 2968 2828 2969 +3 3669 4815 3484 +3 3484 4814 3483 +3 3484 3483 3408 +3 3484 3408 3409 +3 3408 3332 3409 +3 3332 3333 3409 +3 3167 3333 3332 +3 3167 3332 3166 +3 3167 3166 3044 +3 2966 3044 3043 +3 3044 3166 3043 +3 2967 3044 2966 +3 2967 2966 2826 +3 2967 2826 2827 +3 1972 2602 2196 +3 2602 2385 2196 +3 2719 2602 1972 +3 2719 1972 1825 +3 2719 1825 2830 +3 1534 2830 1630 +3 2830 1825 1630 +3 2970 2830 1534 +3 2970 1534 3047 +3 1534 1448 3047 +3 1448 2 3047 +3 2 3170 3047 +3 4962 3412 3336 +3 3485 4816 3670 +3 3486 4816 3485 +3 3486 3485 3410 +3 3486 3410 3411 +3 3410 3334 3411 +3 3334 3335 3411 +3 3169 3335 3334 +3 3169 3334 3168 +3 3169 3168 3046 +3 2968 3046 3045 +3 3046 3168 3045 +3 2969 3046 2968 +3 2829 2969 2828 +3 2718 2829 1629 +3 2718 1629 1824 +3 2718 1824 2601 +3 1824 1971 2601 +3 1971 2196 2601 +3 2196 2385 2601 +3 4233 4093 4518 +3 4093 4666 4518 +3 3666 4093 3799 +3 4093 4017 3799 +3 4666 4093 3666 +3 4666 3666 4812 +3 5572 6664 5768 +3 5767 6811 5571 +3 5574 6666 5770 +3 5769 6813 5573 +3 5573 6812 5572 +3 5573 5572 5480 +3 5573 5480 5481 +3 5480 5388 5481 +3 5388 5389 5481 +3 5193 5389 5388 +3 5193 5388 5192 +3 5193 5192 5049 +3 4956 5049 5048 +3 5049 5192 5048 +3 4957 5049 4956 +3 4957 4956 4812 +3 4957 4812 4813 +3 2600 1823 2717 +3 1823 2828 2717 +3 1970 1823 2600 +3 1970 2600 2195 +3 2600 2384 2195 +3 2384 2599 2195 +3 2599 1969 2195 +3 1822 1969 2599 +3 1822 2599 2716 +3 1822 2716 2827 +3 1822 2827 1627 +3 2827 2826 1627 +3 2826 1626 1627 +3 1626 1530 1627 +3 1530 1531 1627 +3 1445 1531 1530 +3 1264 1445 1444 +3 1264 1444 1263 +3 1264 1263 1140 +3 1263 1139 1140 +3 1139 1057 1140 +3 1057 1058 1140 +3 911 1058 1057 +3 911 1057 910 +3 911 910 765 +3 910 764 765 +3 764 619 765 +3 619 620 765 +3 359 620 619 +3 1 359 358 +3 617 1 618 +3 762 617 763 +3 908 762 909 +3 908 909 1056 +3 908 1056 1055 +3 1056 1138 1055 +3 1138 1137 1055 +3 1261 1137 1138 +3 1442 1261 1262 +3 1528 1442 1443 +3 1528 1443 1529 +3 1528 1529 1625 +3 1528 1625 1624 +3 1625 2825 1624 +3 2825 2824 1624 +3 2824 1819 1624 +3 2964 2824 2825 +3 3041 2964 2965 +3 3164 3041 3042 +3 3330 3164 3165 +3 3406 3330 3331 +3 3406 3331 3407 +3 3406 3407 3481 +3 3407 3482 3481 +3 3482 4812 3481 +3 4812 3666 3481 +3 4813 4812 3482 +3 4813 3482 3667 +3 4813 3667 4667 +3 3667 3800 4667 +3 3800 4519 4667 +3 4520 4234 4018 +3 4234 3800 4018 +3 4519 3800 4234 +3 4522 4235 4019 +3 4522 4019 3803 +3 4522 3803 3670 +3 4522 3670 4670 +3 3670 4816 4670 +3 5575 6814 5574 +3 5575 5574 5482 +3 5575 5482 5483 +3 5482 5390 5483 +3 5390 5391 5483 +3 5195 5391 5390 +3 5195 5390 5194 +3 5195 5194 5051 +3 4958 5051 5050 +3 5051 5194 5050 +3 4959 5051 4958 +3 4959 4958 4814 +3 4959 4814 4815 +3 3668 4520 3801 +3 4520 4018 3801 +3 4668 4520 3668 +3 4814 4668 3483 +3 4815 4814 3484 +3 4669 4815 3669 +3 4669 3669 4521 +3 3669 3802 4521 +3 3802 4019 4521 +3 4019 4235 4521 +3 3805 4524 4020 +3 4672 4524 3805 +3 4672 3805 3672 +3 4672 3672 4818 +3 3412 4818 3487 +3 4818 3672 3487 +3 4962 4818 3412 +3 5054 4962 3336 +3 5054 3336 5198 +3 3336 3170 5198 +3 3170 8300 5198 +3 8300 5394 5198 +3 5393 5392 5197 +3 5197 5196 5053 +3 6233 6159 6520 +3 7410 7411 7506 +3 7053 5387 6955 +3 5571 6955 5479 +3 6955 5387 5479 +3 6811 6955 5571 +3 6663 6811 5767 +3 6663 5767 6519 +3 5767 5911 6519 +3 5911 6159 6519 +3 6159 6233 6519 +3 6234 5913 6160 +3 6234 6160 6522 +3 7508 7601 7600 +3 7798 7951 7950 +3 7799 7951 7798 +3 7799 7798 7599 +3 7798 7598 7599 +3 7598 7506 7599 +3 7506 7507 7599 +3 7411 7507 7506 +3 7209 7411 7410 +3 7209 7410 7208 +3 7209 7208 7055 +3 6956 7055 7054 +3 7055 7208 7054 +3 6957 7055 6956 +3 6957 6956 6812 +3 6957 6812 6813 +3 5768 6520 5912 +3 6520 6159 5912 +3 6664 6520 5768 +3 6812 6664 5572 +3 6813 6812 5573 +3 6665 6813 5769 +3 6665 5769 5913 +3 6665 5913 6521 +3 5913 6234 6521 +3 6235 6161 6524 +3 7955 8300 7954 +3 8300 8191 7954 +3 4665 4093 4517 +3 4093 4233 4517 +3 4092 4093 4665 +3 4092 4665 4811 +3 4092 4811 4955 +3 4092 4955 5047 +3 4092 5047 5191 +3 4092 5191 5387 +3 4092 5387 8299 +3 5387 7053 8299 +3 7053 7207 8299 +3 7207 7409 8299 +3 7409 7505 8299 +3 7505 7597 8299 +3 7597 7797 8299 +3 7797 7949 8299 +3 7949 8189 8299 +3 8189 7950 8299 +3 7950 7951 8299 +3 7951 8190 8299 +3 8190 8191 8299 +3 8191 8300 8299 +3 7953 8191 8190 +3 7953 8190 7952 +3 7953 7952 7801 +3 7600 7801 7800 +3 7801 7952 7800 +3 7601 7801 7600 +3 7509 7601 7508 +3 7509 7508 7413 +3 7210 7413 7412 +3 7413 7508 7412 +3 7211 7413 7210 +3 7211 7210 7057 +3 7210 7056 7057 +3 7056 6958 7057 +3 6958 6959 7057 +3 6815 6958 6814 +3 6959 6958 6815 +3 5770 6522 5914 +3 6522 6160 5914 +3 6666 6522 5770 +3 6814 6666 5574 +3 6815 6814 5575 +3 6815 5575 5771 +3 6815 5771 6667 +3 6161 6523 5915 +3 6523 5771 5915 +3 6667 5771 6523 +3 6816 6668 5772 +3 6668 6524 5772 +3 6524 5916 5772 +3 6161 5916 6524 +3 6523 6161 6235 +3 6236 6162 6526 +3 6526 5918 6670 +3 6670 5774 6818 +3 7416 8300 7512 +3 8300 7604 7512 +3 7804 7604 8300 +3 7804 8300 7956 +3 8300 8192 7956 +3 7955 8192 8300 +3 7803 7955 7954 +3 7803 7954 7802 +3 7803 7802 7603 +3 7510 7603 7602 +3 7603 7802 7602 +3 7511 7603 7510 +3 7511 7510 7415 +3 7510 7414 7415 +3 7414 7212 7415 +3 7212 7213 7415 +3 7059 7213 7212 +3 7059 7212 7058 +3 7059 7058 6960 +3 7059 6960 6961 +3 6817 6960 6816 +3 6961 6960 6817 +3 4523 4020 4236 +3 4020 4524 4236 +3 3804 4020 4523 +3 3804 4523 4671 +3 3804 4671 3671 +3 4671 4817 3671 +3 4817 3486 3671 +3 4816 3486 4817 +3 4816 4817 4961 +3 4816 4961 4960 +3 4961 5053 4960 +3 5053 5052 4960 +3 5196 5052 5053 +3 5392 5196 5197 +3 5484 5392 5393 +3 5484 5393 5485 +3 5484 5485 5577 +3 5484 5577 5576 +3 5577 6816 5576 +3 6816 5772 5576 +3 6817 6816 5577 +3 6817 5577 5773 +3 6817 5773 6669 +3 6162 6525 5917 +3 6525 5773 5917 +3 6669 5773 6525 +3 7060 8300 7214 +3 8300 7416 7214 +3 5394 8300 7060 +3 5394 7060 6962 +3 5394 6962 5486 +3 6962 6818 5486 +3 6818 5578 5486 +3 5774 5578 6818 +3 5918 5774 6670 +3 6162 5918 6526 +3 6525 6162 6236 +3 355 525 354 +3 354 657 353 +3 353 792 352 +3 352 899 351 +3 1005 350 351 +3 350 1084 349 +3 349 1164 348 +3 2989 2374 2917 +3 2822 2917 2375 +3 2822 2376 2734 +3 2734 2377 2630 +3 2630 2378 2525 +3 2525 2379 2502 +3 2502 2380 2425 +3 2380 2381 2425 +3 2379 2380 2502 +3 2378 2379 2525 +3 2377 2378 2630 +3 2376 2377 2734 +3 2375 2376 2822 +3 2374 2375 2917 +3 2369 2989 3064 +3 2374 2989 2369 +3 3163 3064 3162 +3 2369 3064 3163 +3 2369 3163 2361 +3 1386 2356 346 +3 2356 3163 346 +3 2361 3163 2356 +3 2271 2279 1608 +3 2271 1715 2264 +3 2264 1848 2252 +3 2252 1950 2086 +3 1848 1950 2252 +3 1715 1848 2264 +3 1608 1715 2271 +3 1523 1608 2279 +3 1523 2279 2292 +3 1523 2292 1474 +3 2356 1474 2345 +3 1474 2292 2345 +3 1386 1474 2356 +3 1256 1386 346 +3 1256 346 1164 +3 348 346 340 +3 1164 346 348 +3 1084 1164 349 +3 1005 1084 350 +3 899 1005 351 +3 792 899 352 +3 657 792 353 +3 525 657 354 +3 428 525 355 +3 428 355 356 +3 428 356 408 +3 4142 4231 4072 +3 4231 4073 4072 +3 2242 2423 2424 +3 2352 2423 2242 +3 2352 2242 2241 +3 406 407 300 +3 407 301 300 +3 4139 4091 4231 +3 4139 4231 4140 +3 4231 4141 4140 +3 4142 4141 4231 +3 3915 4232 3914 +3 4232 4088 3914 +3 4089 4088 4232 +3 4089 4232 4090 +3 4232 4091 4090 +3 4231 4091 4232 +3 406 300 522 +3 300 656 522 +3 789 656 300 +3 789 300 894 +3 1209 1208 1130 +3 1209 1130 345 +3 1130 1082 345 +3 1082 1000 345 +3 1000 894 345 +3 894 300 345 +3 2913 2274 2983 +3 2265 2083 2084 +3 2265 2084 2274 +3 3110 3038 3111 +3 3038 2983 3111 +3 2983 2084 3111 +3 2274 2084 2983 +3 2284 2274 2913 +3 2284 2913 2816 +3 2284 2816 2293 +3 2816 2732 2293 +3 2732 2346 2293 +3 2347 2732 2629 +3 2346 2732 2347 +3 2348 2629 2524 +3 2347 2629 2348 +3 2352 2524 2423 +3 2348 2524 2352 +3 4108 4105 4104 +3 4106 4105 4108 +3 4093 4095 4094 +3 4096 4095 4093 +3 4096 4093 4097 +3 4093 4092 4097 +3 4092 4098 4097 +3 4099 4098 4092 +3 4099 4092 4100 +3 4092 4107 4100 +3 4107 4101 4100 +3 4102 4101 4107 +3 4102 4107 4103 +3 4107 4104 4103 +3 4108 4104 4107 +3 2301 2300 2294 +3 2301 2294 2299 +3 2294 2295 2299 +3 2295 2298 2299 +3 2297 2298 2295 +3 2297 2295 2296 +3 2339 2335 2340 +3 2338 2340 2337 +3 2340 2336 2337 +3 2335 2336 2340 +3 2334 2335 2339 +3 2334 2339 2333 +3 2339 2332 2333 +3 2321 2330 2331 +3 2328 2324 2327 +3 2327 2325 2326 +3 2324 2325 2327 +3 2323 2324 2328 +3 2323 2328 2322 +3 2308 2316 2317 +3 2316 2309 2315 +3 2314 2315 2310 +3 2314 2311 2313 +3 2311 2312 2313 +3 2310 2311 2314 +3 2309 2310 2315 +3 2308 2309 2316 +3 2307 2308 2317 +3 2307 2317 2318 +3 2307 2318 2306 +3 2330 2322 2329 +3 2322 2328 2329 +3 2321 2322 2330 +3 2320 2321 2331 +3 2320 2331 2319 +3 2331 2332 2319 +3 2332 2339 2319 +3 2339 2302 2319 +3 2302 2306 2319 +3 2306 2318 2319 +3 2305 2306 2302 +3 2305 2302 2304 +3 2302 2303 2304 +3 2386 2295 2382 +3 2296 2295 2386 +3 2313 2312 2401 +3 2312 2398 2401 +3 2325 2414 2326 +3 2410 2414 2325 +3 2340 2338 2427 +3 2340 2427 2430 +3 4074 4138 4077 +3 4136 4138 4074 +3 4123 4124 4062 +3 4123 4062 4058 +3 4046 4044 4110 +3 4046 4110 4111 +3 4086 4106 4108 +3 4093 4094 4021 +3 4093 4021 4017 +3 4127 4120 4128 +3 4133 4138 4134 +3 4138 4135 4134 +3 4136 4135 4138 +3 4137 4133 4132 +3 4138 4133 4137 +3 4117 4109 4137 +3 4109 4114 4110 +3 4111 4110 4112 +3 4110 4113 4112 +3 4114 4113 4110 +3 4115 4114 4109 +3 4115 4109 4116 +3 4109 4117 4116 +3 4130 4137 4131 +3 4137 4132 4131 +3 4117 4137 4130 +3 4117 4130 4129 +3 4117 4129 4118 +3 4129 4128 4118 +3 4128 4119 4118 +3 4120 4119 4128 +3 4121 4120 4127 +3 4121 4127 4126 +3 4121 4126 4125 +3 4121 4125 4122 +3 4123 4125 4124 +3 4122 4125 4123 +3 0 1953 2085 +3 1948 8628 2257 +3 8628 1948 8627 +3 0 2251 8628 +3 0 8628 8627 +3 2251 0 2085 diff -Nru cgal-4.4/examples/Mesh_3/debug.h cgal-4.5/examples/Mesh_3/debug.h --- cgal-4.4/examples/Mesh_3/debug.h 2012-11-13 13:13:57.000000000 +0000 +++ cgal-4.5/examples/Mesh_3/debug.h 2014-08-29 13:58:16.000000000 +0000 @@ -17,7 +17,7 @@ // #define CGAL_MESHES_DEBUG_REFINEMENT_POINTS // #define CGAL_DEBUG_OCTREE_CONSTRUCTION -#define CGAL_MESH_3_VERBOSE -#define CGAL_MESH_3_IO_VERBOSE +//#define CGAL_MESH_3_VERBOSE +//#define CGAL_MESH_3_IO_VERBOSE // #define OPTIMIZE_INTERSECTION diff -Nru cgal-4.4/examples/Mesh_3/implicit_functions.h cgal-4.5/examples/Mesh_3/implicit_functions.h --- cgal-4.4/examples/Mesh_3/implicit_functions.h 2012-11-13 13:13:57.000000000 +0000 +++ cgal-4.5/examples/Mesh_3/implicit_functions.h 2014-08-29 13:58:16.000000000 +0000 @@ -24,12 +24,13 @@ -template -class FT_to_point_function_wrapper : public std::unary_function +template +class FT_to_point_function_wrapper : public std::unary_function { typedef FT (*Implicit_function)(FT, FT, FT); Implicit_function function; public: + typedef P Point; FT_to_point_function_wrapper(Implicit_function f) : function(f) {} FT operator()(Point p) const { return function(p.x(), p.y(), p.z()); } }; diff -Nru cgal-4.4/examples/Mesh_3/mesh_3D_image.cpp cgal-4.5/examples/Mesh_3/mesh_3D_image.cpp --- cgal-4.4/examples/Mesh_3/mesh_3D_image.cpp 2012-11-13 13:13:57.000000000 +0000 +++ cgal-4.5/examples/Mesh_3/mesh_3D_image.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -13,7 +13,15 @@ typedef CGAL::Labeled_image_mesh_domain_3 Mesh_domain; // Triangulation -typedef CGAL::Mesh_triangulation_3::type Tr; +#ifdef CGAL_CONCURRENT_MESH_3 + typedef CGAL::Mesh_triangulation_3< + Mesh_domain, + CGAL::Kernel_traits::Kernel, // Same as sequential + CGAL::Parallel_tag // Tag to activate parallelism + >::type Tr; +#else + typedef CGAL::Mesh_triangulation_3::type Tr; +#endif typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Criteria diff -Nru cgal-4.4/examples/Mesh_3/mesh_3D_image_variable_size.cpp cgal-4.5/examples/Mesh_3/mesh_3D_image_variable_size.cpp --- cgal-4.4/examples/Mesh_3/mesh_3D_image_variable_size.cpp 2012-11-13 13:13:57.000000000 +0000 +++ cgal-4.5/examples/Mesh_3/mesh_3D_image_variable_size.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -1,3 +1,5 @@ +#define CGAL_MESH_3_VERBOSE + #include #include @@ -14,7 +16,15 @@ typedef CGAL::Labeled_image_mesh_domain_3 Mesh_domain; // Triangulation -typedef CGAL::Mesh_triangulation_3::type Tr; +#ifdef CGAL_CONCURRENT_MESH_3 + typedef CGAL::Mesh_triangulation_3< + Mesh_domain, + CGAL::Kernel_traits::Kernel, // Same as sequential + CGAL::Parallel_tag // Tag to activate parallelism + >::type Tr; +#else + typedef CGAL::Mesh_triangulation_3::type Tr; +#endif typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Criteria diff -Nru cgal-4.4/examples/Mesh_3/mesh_cubes_intersection.cpp cgal-4.5/examples/Mesh_3/mesh_cubes_intersection.cpp --- cgal-4.4/examples/Mesh_3/mesh_cubes_intersection.cpp 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/examples/Mesh_3/mesh_cubes_intersection.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,97 @@ + +//****************************************************************************** +// File Description : +// Outputs to out.mesh a mesh of implicit domains. +//****************************************************************************** + + + +#include + +#include +#include +#include + +#include +#include +#include + +// IO +#include + +using namespace CGAL::parameters; + +// Domain +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef K::Point_3 Point; +typedef K::FT FT; +typedef FT (*Function)(const Point&); +typedef CGAL::Implicit_multi_domain_to_labeling_function_wrapper + Function_wrapper; +typedef Function_wrapper::Function_vector Function_vector; +typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; + +// Triangulation +typedef CGAL::Mesh_triangulation_3::type Tr; +typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; + +// Mesh Criteria +typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef Mesh_criteria::Facet_criteria Facet_criteria; +typedef Mesh_criteria::Cell_criteria Cell_criteria; + + +double cube_function_1 (const Point& p) +{ + if( p.x() >= 0 && p.x() <= 2 && + p.y() >= 0 && p.y() <= 2 && + p.z() >= 0 && p.z() <= 2 ) + return -1.; + return 1.; +} + +double cube_function_2 (const Point& p) +{ + if( p.x() >= 1 && p.x() <= 3 && + p.y() >= 1 && p.y() <= 3 && + p.z() >= 1 && p.z() <= 3 ) + return -1.; + return 1.; +} + +int main() +{ + // Define functions + Function f1 = cube_function_1; + Function f2 = cube_function_2; + + Function_vector v; + v.push_back(f1); + v.push_back(f2); + + std::vector vps; + vps.push_back("--"); + + // Domain (Warning: Sphere_3 constructor uses square radius !) + Mesh_domain domain(Function_wrapper(v, vps), K::Sphere_3(CGAL::ORIGIN, 5.*5.)); + + // Set mesh criteria + Mesh_criteria criteria(edge_size = 0.15, + facet_angle = 30, facet_size = 0.2, + cell_radius_edge_ratio = 2, cell_size = 0.4); + + // Mesh generation + C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria, no_exude(), no_perturb()); + + // Perturbation (maximum cpu time: 10s, targeted dihedral angle: default) + CGAL::perturb_mesh_3(c3t3, domain, time_limit = 10); + + // Exudation + CGAL::exude_mesh_3(c3t3,12); + + // Output + std::ofstream medit_file("out_cubes_intersection.mesh"); + CGAL::output_to_medit(medit_file, c3t3); + + return 0; +} diff -Nru cgal-4.4/examples/Mesh_3/mesh_cubes_intersection_with_features.cpp cgal-4.5/examples/Mesh_3/mesh_cubes_intersection_with_features.cpp --- cgal-4.4/examples/Mesh_3/mesh_cubes_intersection_with_features.cpp 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/examples/Mesh_3/mesh_cubes_intersection_with_features.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,184 @@ + +//****************************************************************************** +// File Description : +// Outputs to out.mesh a mesh of implicit domains. +//****************************************************************************** + + + +#include + +#include +#include +#include + +#include +#include +#include +#include + +// IO +#include + +using namespace CGAL::parameters; + +// Domain +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef K::Point_3 Point; +typedef K::FT FT; +typedef FT (*Function)(const Point&); +typedef CGAL::Implicit_multi_domain_to_labeling_function_wrapper + Function_wrapper; +typedef Function_wrapper::Function_vector Function_vector; +typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; +typedef CGAL::Mesh_domain_with_polyline_features_3 Mesh_domain_with_features; + +// Triangulation +typedef CGAL::Mesh_triangulation_3::type Tr; +typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; + +// Mesh Criteria +typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef Mesh_criteria::Facet_criteria Facet_criteria; +typedef Mesh_criteria::Cell_criteria Cell_criteria; + + +double cube_function_1 (const Point& p) +{ + if( p.x() >= 0 && p.x() <= 2 && + p.y() >= 0 && p.y() <= 2 && + p.z() >= 0 && p.z() <= 2 ) + return -1.; + return 1.; +} + +double cube_function_2 (const Point& p) +{ + if( p.x() >= 1 && p.x() <= 3 && + p.y() >= 1 && p.y() <= 3 && + p.z() >= 1 && p.z() <= 3 ) + return -1.; + return 1.; +} + +// Polyline +typedef std::vector Polyline_3; +typedef std::list Polylines; + +void create_polylines (Polylines& polylines) +{ + { + Polyline_3 polyline; + polyline.push_back(Point(1,1,1)); + polyline.push_back(Point(2,1,1)); + polylines.push_back(polyline); + } + { + Polyline_3 polyline; + polyline.push_back(Point(2,1,1)); + polyline.push_back(Point(2,2,1)); + polylines.push_back(polyline); + } + { + Polyline_3 polyline; + polyline.push_back(Point(2,2,1)); + polyline.push_back(Point(1,2,1)); + polylines.push_back(polyline); + } + { + Polyline_3 polyline; + polyline.push_back(Point(1,2,1)); + polyline.push_back(Point(1,1,1)); + polylines.push_back(polyline); + } +//---------- + { + Polyline_3 polyline; + polyline.push_back(Point(1,1,2)); + polyline.push_back(Point(2,1,2)); + polylines.push_back(polyline); + } + { + Polyline_3 polyline; + polyline.push_back(Point(2,1,2)); + polyline.push_back(Point(2,2,2)); + polylines.push_back(polyline); + } + { + Polyline_3 polyline; + polyline.push_back(Point(2,2,2)); + polyline.push_back(Point(1,2,2)); + polylines.push_back(polyline); + } + { + Polyline_3 polyline; + polyline.push_back(Point(1,2,2)); + polyline.push_back(Point(1,1,2)); + polylines.push_back(polyline); + } + //---------- + { + Polyline_3 polyline; + polyline.push_back(Point(1,1,1)); + polyline.push_back(Point(1,1,2)); + polylines.push_back(polyline); + } + { + Polyline_3 polyline; + polyline.push_back(Point(2,1,1)); + polyline.push_back(Point(2,1,2)); + polylines.push_back(polyline); + } + { + Polyline_3 polyline; + polyline.push_back(Point(2,2,1)); + polyline.push_back(Point(2,2,2)); + polylines.push_back(polyline); + } + { + Polyline_3 polyline; + polyline.push_back(Point(1,2,1)); + polyline.push_back(Point(1,2,2)); + polylines.push_back(polyline); + } +} + +int main() +{ + // Define functions + Function f1 = cube_function_1; + Function f2 = cube_function_2; + + Function_vector v; + v.push_back(f1); + v.push_back(f2); + + std::vector vps; + vps.push_back("--"); + + // Domain (Warning: Sphere_3 constructor uses square radius !) + Mesh_domain_with_features domain(Function_wrapper(v, vps), K::Sphere_3(CGAL::ORIGIN, 5.*5.)); + Polylines polylines; + create_polylines(polylines); + domain.add_features(polylines.begin(),polylines.end()); + + // Set mesh criteria + Mesh_criteria criteria(edge_size = 0.15, + facet_angle = 30, facet_size = 0.2, + cell_radius_edge_ratio = 2, cell_size = 0.4); + + // Mesh generation + C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria, no_exude(), no_perturb()); + + // Perturbation (maximum cpu time: 10s, targeted dihedral angle: default) + CGAL::perturb_mesh_3(c3t3, domain, time_limit = 10); + + // Exudation + CGAL::exude_mesh_3(c3t3,12); + + // Output + std::ofstream medit_file("out_cubes_intersection_with_features.mesh"); + CGAL::output_to_medit(medit_file, c3t3); + + return 0; +} diff -Nru cgal-4.4/examples/Mesh_3/mesh_implicit_domains_2.cpp cgal-4.5/examples/Mesh_3/mesh_implicit_domains_2.cpp --- cgal-4.4/examples/Mesh_3/mesh_implicit_domains_2.cpp 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/examples/Mesh_3/mesh_implicit_domains_2.cpp 2014-10-06 19:00:05.000000000 +0000 @@ -0,0 +1,70 @@ +#include + +#include +#include +#include + +#include +#include +#include +#include "implicit_functions.h" + +// IO +#include + +using namespace CGAL::parameters; + +// Domain +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef FT_to_point_function_wrapper Function; +typedef CGAL::Implicit_multi_domain_to_labeling_function_wrapper + Function_wrapper; +typedef Function_wrapper::Function_vector Function_vector; +typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; + +// Triangulation +typedef CGAL::Mesh_triangulation_3::type Tr; +typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; + +// Mesh Criteria +typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef Mesh_criteria::Facet_criteria Facet_criteria; +typedef Mesh_criteria::Cell_criteria Cell_criteria; + + +int main() +{ + // Define functions + Function f1(&torus_function); + Function f2(&sphere_function<3>); + + Function_vector v; + v.push_back(f1); + v.push_back(f2); + + std::vector vps; + vps.push_back("+-"); + + // Domain (Warning: Sphere_3 constructor uses square radius !) + Mesh_domain domain(Function_wrapper(v, vps), K::Sphere_3(CGAL::ORIGIN, 5.*5.)); + + // Set mesh criteria + Facet_criteria facet_criteria(30, 0.2, 0.02); // angle, size, approximation + Cell_criteria cell_criteria(2., 0.4); // radius-edge ratio, size + Mesh_criteria criteria(facet_criteria, cell_criteria); + + // Mesh generation + C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria, no_exude(), no_perturb()); + + // Perturbation (maximum cpu time: 10s, targeted dihedral angle: default) + CGAL::perturb_mesh_3(c3t3, domain, time_limit = 10); + + // Exudation + CGAL::exude_mesh_3(c3t3,12); + + // Output + std::ofstream medit_file("out.mesh"); + CGAL::output_to_medit(medit_file, c3t3); + + return 0; +} diff -Nru cgal-4.4/examples/Mesh_3/mesh_implicit_domains.cpp cgal-4.5/examples/Mesh_3/mesh_implicit_domains.cpp --- cgal-4.4/examples/Mesh_3/mesh_implicit_domains.cpp 2013-07-06 19:00:27.000000000 +0000 +++ cgal-4.5/examples/Mesh_3/mesh_implicit_domains.cpp 2014-10-06 19:00:05.000000000 +0000 @@ -1,22 +1,11 @@ - -//****************************************************************************** -// File Description : -// Outputs to out.mesh a mesh of implicit domains. These domains are defined -// by a vector of functions. Each n-uplet of sign of function values defines a -// subdomain. -//****************************************************************************** - - - -#include #include #include #include #include -#include -#include +#include +#include #include #include "implicit_functions.h" @@ -28,10 +17,10 @@ // Domain typedef CGAL::Exact_predicates_inexact_constructions_kernel K; typedef FT_to_point_function_wrapper Function; -typedef CGAL::Mesh_3::Implicit_vector_to_labeled_function_wrapper +typedef CGAL::Implicit_multi_domain_to_labeling_function_wrapper Function_wrapper; typedef Function_wrapper::Function_vector Function_vector; -typedef CGAL::Mesh_3::Labeled_mesh_domain_3 Mesh_domain; +typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; // Triangulation typedef CGAL::Mesh_triangulation_3::type Tr; @@ -47,13 +36,11 @@ { // Define functions Function f1(&torus_function); - Function f2(&sphere_function<5>); - Function f3(&sphere_function<2>); + Function f2(&sphere_function<3>); Function_vector v; - v.push_back(&f1); - v.push_back(&f2); - //v.push_back(&f3); + v.push_back(f1); + v.push_back(f2); // Domain (Warning: Sphere_3 constructor uses square radius !) Mesh_domain domain(v, K::Sphere_3(CGAL::ORIGIN, 5.*5.), 1e-6); diff -Nru cgal-4.4/examples/Mesh_3/mesh_implicit_sphere.cpp cgal-4.5/examples/Mesh_3/mesh_implicit_sphere.cpp --- cgal-4.4/examples/Mesh_3/mesh_implicit_sphere.cpp 2012-11-13 13:13:57.000000000 +0000 +++ cgal-4.5/examples/Mesh_3/mesh_implicit_sphere.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -15,7 +15,15 @@ typedef CGAL::Implicit_mesh_domain_3 Mesh_domain; // Triangulation -typedef CGAL::Mesh_triangulation_3::type Tr; +#ifdef CGAL_CONCURRENT_MESH_3 + typedef CGAL::Mesh_triangulation_3< + Mesh_domain, + CGAL::Kernel_traits::Kernel, // Same as sequential + CGAL::Parallel_tag // Tag to activate parallelism + >::type Tr; +#else + typedef CGAL::Mesh_triangulation_3::type Tr; +#endif typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Criteria @@ -31,7 +39,8 @@ int main() { // Domain (Warning: Sphere_3 constructor uses squared radius !) - Mesh_domain domain(sphere_function, K::Sphere_3(CGAL::ORIGIN, 2.)); + Mesh_domain domain(sphere_function, + K::Sphere_3(CGAL::ORIGIN, 2.)); // Mesh criteria Mesh_criteria criteria(facet_angle=30, facet_size=0.1, facet_distance=0.025, diff -Nru cgal-4.4/examples/Mesh_3/mesh_implicit_sphere_variable_size.cpp cgal-4.5/examples/Mesh_3/mesh_implicit_sphere_variable_size.cpp --- cgal-4.4/examples/Mesh_3/mesh_implicit_sphere_variable_size.cpp 2012-11-13 13:13:57.000000000 +0000 +++ cgal-4.5/examples/Mesh_3/mesh_implicit_sphere_variable_size.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -15,7 +15,15 @@ typedef CGAL::Implicit_mesh_domain_3 Mesh_domain; // Triangulation -typedef CGAL::Mesh_triangulation_3::type Tr; +#ifdef CGAL_CONCURRENT_MESH_3 + typedef CGAL::Mesh_triangulation_3< + Mesh_domain, + CGAL::Kernel_traits::Kernel, // Same as sequential + CGAL::Parallel_tag // Tag to activate parallelism + >::type Tr; +#else + typedef CGAL::Mesh_triangulation_3::type Tr; +#endif typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Criteria @@ -45,7 +53,8 @@ int main() { // Domain (Warning: Sphere_3 constructor uses squared radius !) - Mesh_domain domain(sphere_function, K::Sphere_3(CGAL::ORIGIN, 2.)); + Mesh_domain domain(sphere_function, + K::Sphere_3(CGAL::ORIGIN, 2.)); // Mesh criteria Spherical_sizing_field size; diff -Nru cgal-4.4/examples/Mesh_3/mesh_optimization_example.cpp cgal-4.5/examples/Mesh_3/mesh_optimization_example.cpp --- cgal-4.4/examples/Mesh_3/mesh_optimization_example.cpp 2012-11-13 13:13:57.000000000 +0000 +++ cgal-4.5/examples/Mesh_3/mesh_optimization_example.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -13,7 +13,15 @@ typedef CGAL::Labeled_image_mesh_domain_3 Mesh_domain; // Triangulation -typedef CGAL::Mesh_triangulation_3::type Tr; +#ifdef CGAL_CONCURRENT_MESH_3 + typedef CGAL::Mesh_triangulation_3< + Mesh_domain, + CGAL::Kernel_traits::Kernel, // Same as sequential + CGAL::Parallel_tag // Tag to activate parallelism + >::type Tr; +#else + typedef CGAL::Mesh_triangulation_3::type Tr; +#endif typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Mesh Criteria diff -Nru cgal-4.4/examples/Mesh_3/mesh_optimization_lloyd_example.cpp cgal-4.5/examples/Mesh_3/mesh_optimization_lloyd_example.cpp --- cgal-4.4/examples/Mesh_3/mesh_optimization_lloyd_example.cpp 2012-11-13 13:13:57.000000000 +0000 +++ cgal-4.5/examples/Mesh_3/mesh_optimization_lloyd_example.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -13,7 +13,15 @@ typedef CGAL::Labeled_image_mesh_domain_3 Mesh_domain; // Triangulation -typedef CGAL::Mesh_triangulation_3::type Tr; +#ifdef CGAL_CONCURRENT_MESH_3 + typedef CGAL::Mesh_triangulation_3< + Mesh_domain, + CGAL::Kernel_traits::Kernel, // Same as sequential + CGAL::Parallel_tag // Tag to activate parallelism + >::type Tr; +#else + typedef CGAL::Mesh_triangulation_3::type Tr; +#endif typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Mesh Criteria diff -Nru cgal-4.4/examples/Mesh_3/mesh_polyhedral_domain.cpp cgal-4.5/examples/Mesh_3/mesh_polyhedral_domain.cpp --- cgal-4.4/examples/Mesh_3/mesh_polyhedral_domain.cpp 2012-11-13 13:13:57.000000000 +0000 +++ cgal-4.5/examples/Mesh_3/mesh_polyhedral_domain.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -17,7 +17,15 @@ typedef CGAL::Polyhedral_mesh_domain_3 Mesh_domain; // Triangulation -typedef CGAL::Mesh_triangulation_3::type Tr; +#ifdef CGAL_CONCURRENT_MESH_3 + typedef CGAL::Mesh_triangulation_3< + Mesh_domain, + CGAL::Kernel_traits::Kernel, // Same as sequential + CGAL::Parallel_tag // Tag to activate parallelism + >::type Tr; +#else + typedef CGAL::Mesh_triangulation_3::type Tr; +#endif typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Criteria diff -Nru cgal-4.4/examples/Mesh_3/mesh_polyhedral_domain_with_features.cpp cgal-4.5/examples/Mesh_3/mesh_polyhedral_domain_with_features.cpp --- cgal-4.4/examples/Mesh_3/mesh_polyhedral_domain_with_features.cpp 2012-11-13 13:13:57.000000000 +0000 +++ cgal-4.5/examples/Mesh_3/mesh_polyhedral_domain_with_features.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -12,7 +12,15 @@ typedef CGAL::Polyhedral_mesh_domain_with_features_3 Mesh_domain; // Triangulation -typedef CGAL::Mesh_triangulation_3::type Tr; +#ifdef CGAL_CONCURRENT_MESH_3 + typedef CGAL::Mesh_triangulation_3< + Mesh_domain, + CGAL::Kernel_traits::Kernel, // Same as sequential + CGAL::Parallel_tag // Tag to activate parallelism + >::type Tr; +#else + typedef CGAL::Mesh_triangulation_3::type Tr; +#endif typedef CGAL::Mesh_complex_3_in_triangulation_3< Tr,Mesh_domain::Corner_index,Mesh_domain::Curve_segment_index> C3t3; diff -Nru cgal-4.4/examples/Mesh_3/mesh_two_implicit_spheres_with_balls.cpp cgal-4.5/examples/Mesh_3/mesh_two_implicit_spheres_with_balls.cpp --- cgal-4.4/examples/Mesh_3/mesh_two_implicit_spheres_with_balls.cpp 2012-11-13 13:13:57.000000000 +0000 +++ cgal-4.5/examples/Mesh_3/mesh_two_implicit_spheres_with_balls.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -23,7 +23,15 @@ typedef std::list Polylines; // Triangulation -typedef CGAL::Mesh_triangulation_3::type Tr; +#ifdef CGAL_CONCURRENT_MESH_3 + typedef CGAL::Mesh_triangulation_3< + Mesh_domain, + CGAL::Kernel_traits::Kernel, // Same as sequential + CGAL::Parallel_tag // Tag to activate parallelism + >::type Tr; +#else + typedef CGAL::Mesh_triangulation_3::type Tr; +#endif typedef CGAL::Mesh_complex_3_in_triangulation_3< Tr,Mesh_domain::Corner_index,Mesh_domain::Curve_segment_index> C3t3; @@ -53,7 +61,8 @@ int main() { // Domain (Warning: Sphere_3 constructor uses squared radius !) - Mesh_domain domain(sphere_function, K::Sphere_3(Point(1, 0, 0), 6.)); + Mesh_domain domain(sphere_function, + K::Sphere_3(Point(1, 0, 0), 6.)); // Mesh criteria Mesh_criteria criteria(edge_size = 0.15, diff -Nru cgal-4.4/examples/Min_annulus_d/min_annulus_d_fast_exact.cpp cgal-4.5/examples/Min_annulus_d/min_annulus_d_fast_exact.cpp --- cgal-4.4/examples/Min_annulus_d/min_annulus_d_fast_exact.cpp 2012-11-13 13:13:54.000000000 +0000 +++ cgal-4.5/examples/Min_annulus_d/min_annulus_d_fast_exact.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -9,13 +9,8 @@ #include #include -#ifdef CGAL_USE_GMP -#include -typedef CGAL::Gmpzf ET; -#else -#include -typedef CGAL::MP_Float ET; -#endif +#include +typedef CGAL::Exact_integer ET; // use an inexact kernel... typedef CGAL::Homogeneous K; diff -Nru cgal-4.4/examples/Min_ellipse_2/min_ellipse_2.cpp cgal-4.5/examples/Min_ellipse_2/min_ellipse_2.cpp --- cgal-4.4/examples/Min_ellipse_2/min_ellipse_2.cpp 2012-11-13 13:13:54.000000000 +0000 +++ cgal-4.5/examples/Min_ellipse_2/min_ellipse_2.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -1,11 +1,11 @@ #include #include #include -#include +#include #include -typedef CGAL::Gmpq NT; +typedef CGAL::Exact_rational NT; typedef CGAL::Cartesian K; typedef CGAL::Point_2 Point; typedef CGAL::Min_ellipse_2_traits_2 Traits; diff -Nru cgal-4.4/examples/Min_sphere_of_spheres_d/min_sphere_of_spheres_d_2.cpp cgal-4.5/examples/Min_sphere_of_spheres_d/min_sphere_of_spheres_d_2.cpp --- cgal-4.4/examples/Min_sphere_of_spheres_d/min_sphere_of_spheres_d_2.cpp 2012-11-13 13:13:54.000000000 +0000 +++ cgal-4.5/examples/Min_sphere_of_spheres_d/min_sphere_of_spheres_d_2.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -4,14 +4,14 @@ #include #include -#include +#include #include #include const int N = 1000; // number of spheres const int LOW = 0, HIGH = 10000; // range of coordinates and radii -typedef CGAL::Gmpq FT; +typedef CGAL::Exact_rational FT; //typedef double FT; typedef CGAL::Cartesian K; typedef CGAL::Min_sphere_of_spheres_d_traits_2 Traits; diff -Nru cgal-4.4/examples/Min_sphere_of_spheres_d/min_sphere_of_spheres_d_3.cpp cgal-4.5/examples/Min_sphere_of_spheres_d/min_sphere_of_spheres_d_3.cpp --- cgal-4.4/examples/Min_sphere_of_spheres_d/min_sphere_of_spheres_d_3.cpp 2012-11-13 13:13:54.000000000 +0000 +++ cgal-4.5/examples/Min_sphere_of_spheres_d/min_sphere_of_spheres_d_3.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -4,14 +4,14 @@ #include #include -#include +#include #include #include const int N = 1000; // number of spheres const int LOW = 0, HIGH = 10000; // range of coordinates and radii -typedef CGAL::Gmpq FT; +typedef CGAL::Exact_rational FT; //typedef double FT; typedef CGAL::Cartesian K; typedef CGAL::Min_sphere_of_spheres_d_traits_3 Traits; diff -Nru cgal-4.4/examples/Min_sphere_of_spheres_d/min_sphere_of_spheres_d_d.cpp cgal-4.5/examples/Min_sphere_of_spheres_d/min_sphere_of_spheres_d_d.cpp --- cgal-4.4/examples/Min_sphere_of_spheres_d/min_sphere_of_spheres_d_d.cpp 2012-11-13 13:13:54.000000000 +0000 +++ cgal-4.5/examples/Min_sphere_of_spheres_d/min_sphere_of_spheres_d_d.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -4,7 +4,7 @@ #include #include -#include +#include #include #include @@ -12,7 +12,7 @@ const int D = 3; // dimension of points const int LOW = 0, HIGH = 10000; // range of coordinates and radii -typedef CGAL::Gmpq FT; +typedef CGAL::Exact_rational FT; //typedef double FT; typedef CGAL::Cartesian_d K; typedef CGAL::Min_sphere_of_spheres_d_traits_d Traits; diff -Nru cgal-4.4/examples/Nef_2/nef_2_construction.cpp cgal-4.5/examples/Nef_2/nef_2_construction.cpp --- cgal-4.4/examples/Nef_2/nef_2_construction.cpp 2012-11-13 13:13:58.000000000 +0000 +++ cgal-4.5/examples/Nef_2/nef_2_construction.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -1,8 +1,8 @@ -#include +#include #include #include -typedef CGAL::Gmpz RT; +typedef CGAL::Exact_integer RT; typedef CGAL::Filtered_extended_homogeneous Extended_kernel; typedef CGAL::Nef_polyhedron_2 Nef_polyhedron; typedef Nef_polyhedron::Point Point; diff -Nru cgal-4.4/examples/Nef_2/nef_2_intersection.cpp cgal-4.5/examples/Nef_2/nef_2_intersection.cpp --- cgal-4.4/examples/Nef_2/nef_2_intersection.cpp 2012-11-13 13:13:58.000000000 +0000 +++ cgal-4.5/examples/Nef_2/nef_2_intersection.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -1,8 +1,8 @@ -#include +#include #include #include -typedef CGAL::Gmpz RT; +typedef CGAL::Exact_integer RT; typedef CGAL::Filtered_extended_homogeneous Extended_kernel; typedef CGAL::Nef_polyhedron_2 Nef_polyhedron; typedef Nef_polyhedron::Line Line; diff -Nru cgal-4.4/examples/Nef_2/nef_2_polylines.cpp cgal-4.5/examples/Nef_2/nef_2_polylines.cpp --- cgal-4.4/examples/Nef_2/nef_2_polylines.cpp 2012-11-13 13:13:58.000000000 +0000 +++ cgal-4.5/examples/Nef_2/nef_2_polylines.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -1,11 +1,11 @@ -#include +#include #include #include #include #include -typedef CGAL::Lazy_exact_nt FT; +typedef CGAL::Lazy_exact_nt FT; typedef CGAL::Simple_cartesian Kernel; typedef CGAL::Bounded_kernel Extended_kernel; typedef CGAL::Nef_polyhedron_2 Nef_polyhedron; diff -Nru cgal-4.4/examples/Nef_3/comparison.cpp cgal-4.5/examples/Nef_3/comparison.cpp --- cgal-4.4/examples/Nef_3/comparison.cpp 2012-11-13 13:13:58.000000000 +0000 +++ cgal-4.5/examples/Nef_3/comparison.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -1,8 +1,8 @@ -#include +#include #include #include -typedef CGAL::Gmpz NT; +typedef CGAL::Exact_integer NT; typedef CGAL::Extended_homogeneous Kernel; typedef CGAL::Nef_polyhedron_3 Nef_polyhedron; //typedef Nef_polyhedron::Plane_3 Plane_3; diff -Nru cgal-4.4/examples/Nef_3/complex_construction.cpp cgal-4.5/examples/Nef_3/complex_construction.cpp --- cgal-4.4/examples/Nef_3/complex_construction.cpp 2012-11-13 13:13:58.000000000 +0000 +++ cgal-4.5/examples/Nef_3/complex_construction.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -1,10 +1,10 @@ -#include +#include #include #include int main() { - typedef CGAL::Homogeneous Kernel; + typedef CGAL::Homogeneous Kernel; typedef CGAL::Nef_polyhedron_3 Nef_3; Nef_3 N; diff -Nru cgal-4.4/examples/Nef_3/exploration_SM.cpp cgal-4.5/examples/Nef_3/exploration_SM.cpp --- cgal-4.4/examples/Nef_3/exploration_SM.cpp 2012-11-13 13:13:58.000000000 +0000 +++ cgal-4.5/examples/Nef_3/exploration_SM.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -1,9 +1,9 @@ -#include +#include #include #include #include -typedef CGAL::Homogeneous Kernel; +typedef CGAL::Homogeneous Kernel; typedef CGAL::Nef_polyhedron_3 Nef_polyhedron_3; diff -Nru cgal-4.4/examples/Nef_3/extended_kernel.cpp cgal-4.5/examples/Nef_3/extended_kernel.cpp --- cgal-4.4/examples/Nef_3/extended_kernel.cpp 2012-11-13 13:13:58.000000000 +0000 +++ cgal-4.5/examples/Nef_3/extended_kernel.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -1,9 +1,9 @@ -#include +#include #include #include #include -typedef CGAL::Gmpz NT; +typedef CGAL::Exact_integer NT; //instead of //typedef CGAL::Extended_homogeneous Kernel; // workaround for VC++ diff -Nru cgal-4.4/examples/Nef_3/interface_polyhedron.cpp cgal-4.5/examples/Nef_3/interface_polyhedron.cpp --- cgal-4.4/examples/Nef_3/interface_polyhedron.cpp 2012-11-13 13:13:58.000000000 +0000 +++ cgal-4.5/examples/Nef_3/interface_polyhedron.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -1,4 +1,4 @@ -#include +#include #include #include #include @@ -6,7 +6,7 @@ #include #include -typedef CGAL::Homogeneous Kernel; +typedef CGAL::Homogeneous Kernel; typedef CGAL::Polyhedron_3 Polyhedron; typedef CGAL::Nef_polyhedron_3 Nef_polyhedron; typedef Kernel::Vector_3 Vector_3; diff -Nru cgal-4.4/examples/Nef_3/nef_3_construction.cpp cgal-4.5/examples/Nef_3/nef_3_construction.cpp --- cgal-4.4/examples/Nef_3/nef_3_construction.cpp 2012-11-13 13:13:58.000000000 +0000 +++ cgal-4.5/examples/Nef_3/nef_3_construction.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -1,8 +1,8 @@ -#include +#include #include #include -typedef CGAL::Extended_homogeneous Kernel; +typedef CGAL::Extended_homogeneous Kernel; typedef CGAL::Nef_polyhedron_3 Nef_polyhedron; typedef Nef_polyhedron::Plane_3 Plane_3; diff -Nru cgal-4.4/examples/Nef_3/nef_3_point_location.cpp cgal-4.5/examples/Nef_3/nef_3_point_location.cpp --- cgal-4.4/examples/Nef_3/nef_3_point_location.cpp 2012-11-13 13:13:58.000000000 +0000 +++ cgal-4.5/examples/Nef_3/nef_3_point_location.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -1,9 +1,9 @@ -#include +#include #include #include #include -typedef CGAL::Homogeneous Kernel; +typedef CGAL::Homogeneous Kernel; typedef CGAL::Nef_polyhedron_3 Nef_polyhedron_3; typedef Kernel::Point_3 Point_3; diff -Nru cgal-4.4/examples/Nef_3/nef_3_simple.cpp cgal-4.5/examples/Nef_3/nef_3_simple.cpp --- cgal-4.4/examples/Nef_3/nef_3_simple.cpp 2012-11-13 13:13:58.000000000 +0000 +++ cgal-4.5/examples/Nef_3/nef_3_simple.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -1,8 +1,8 @@ -#include +#include #include #include -typedef CGAL::Homogeneous Kernel; +typedef CGAL::Homogeneous Kernel; typedef CGAL::Nef_polyhedron_3 Nef_polyhedron; int main() { diff -Nru cgal-4.4/examples/Nef_3/nefIO.cpp cgal-4.5/examples/Nef_3/nefIO.cpp --- cgal-4.4/examples/Nef_3/nefIO.cpp 2012-11-13 13:13:58.000000000 +0000 +++ cgal-4.5/examples/Nef_3/nefIO.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -1,11 +1,11 @@ -#include +#include #include #include #include #include #include -typedef CGAL::Gmpz NT; +typedef CGAL::Exact_integer NT; typedef CGAL::Homogeneous SK; typedef CGAL::Extended_homogeneous EK; typedef CGAL::Nef_polyhedron_3 Nef_polyhedron_S; diff -Nru cgal-4.4/examples/Nef_3/offIO.cpp cgal-4.5/examples/Nef_3/offIO.cpp --- cgal-4.4/examples/Nef_3/offIO.cpp 2012-11-13 13:13:58.000000000 +0000 +++ cgal-4.5/examples/Nef_3/offIO.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -1,4 +1,4 @@ -#include +#include #include #include #include @@ -6,7 +6,7 @@ #include #include -typedef CGAL::Gmpz NT; +typedef CGAL::Exact_integer NT; typedef CGAL::Homogeneous Kernel; typedef CGAL::Polyhedron_3 Polyhedron; typedef CGAL::Nef_polyhedron_3 Nef_polyhedron; diff -Nru cgal-4.4/examples/Nef_3/point_set_operations.cpp cgal-4.5/examples/Nef_3/point_set_operations.cpp --- cgal-4.4/examples/Nef_3/point_set_operations.cpp 2012-11-13 13:13:58.000000000 +0000 +++ cgal-4.5/examples/Nef_3/point_set_operations.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -1,8 +1,8 @@ -#include +#include #include #include -typedef CGAL::Extended_homogeneous Kernel; +typedef CGAL::Extended_homogeneous Kernel; typedef CGAL::Nef_polyhedron_3 Nef_polyhedron; typedef Kernel::Plane_3 Plane_3; diff -Nru cgal-4.4/examples/Nef_3/polyline_construction.cpp cgal-4.5/examples/Nef_3/polyline_construction.cpp --- cgal-4.4/examples/Nef_3/polyline_construction.cpp 2012-11-13 13:13:58.000000000 +0000 +++ cgal-4.5/examples/Nef_3/polyline_construction.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -1,9 +1,9 @@ -#include +#include #include #include #include -typedef CGAL::Gmpz NT; +typedef CGAL::Exact_integer NT; typedef CGAL::Homogeneous Kernel; typedef Kernel::Point_3 Point_3; typedef CGAL::Nef_polyhedron_3 Nef_polyhedron; diff -Nru cgal-4.4/examples/Nef_3/set_operations.cpp cgal-4.5/examples/Nef_3/set_operations.cpp --- cgal-4.4/examples/Nef_3/set_operations.cpp 2012-11-13 13:13:58.000000000 +0000 +++ cgal-4.5/examples/Nef_3/set_operations.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -1,8 +1,8 @@ -#include +#include #include #include -typedef CGAL::Gmpz NT; +typedef CGAL::Exact_integer NT; typedef CGAL::Extended_homogeneous Kernel; typedef CGAL::Nef_polyhedron_3 Nef_polyhedron; typedef Nef_polyhedron::Plane_3 Plane_3; diff -Nru cgal-4.4/examples/Nef_3/shell_exploration.cpp cgal-4.5/examples/Nef_3/shell_exploration.cpp --- cgal-4.4/examples/Nef_3/shell_exploration.cpp 2013-03-07 20:00:26.000000000 +0000 +++ cgal-4.5/examples/Nef_3/shell_exploration.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -1,9 +1,9 @@ -#include +#include #include #include #include -typedef CGAL::Homogeneous Kernel; +typedef CGAL::Homogeneous Kernel; typedef CGAL::Nef_polyhedron_3 Nef_polyhedron; typedef Nef_polyhedron::Vertex_const_handle Vertex_const_handle; typedef Nef_polyhedron::Halfedge_const_handle Halfedge_const_handle; diff -Nru cgal-4.4/examples/Nef_3/topological_operations.cpp cgal-4.5/examples/Nef_3/topological_operations.cpp --- cgal-4.4/examples/Nef_3/topological_operations.cpp 2012-11-13 13:13:58.000000000 +0000 +++ cgal-4.5/examples/Nef_3/topological_operations.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -1,9 +1,9 @@ -#include +#include #include #include #include -typedef CGAL::Gmpz NT; +typedef CGAL::Exact_integer NT; typedef CGAL::Homogeneous Kernel; typedef CGAL::Nef_polyhedron_3 Nef_polyhedron; diff -Nru cgal-4.4/examples/Nef_3/transformation.cpp cgal-4.5/examples/Nef_3/transformation.cpp --- cgal-4.4/examples/Nef_3/transformation.cpp 2012-11-13 13:13:58.000000000 +0000 +++ cgal-4.5/examples/Nef_3/transformation.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -1,13 +1,13 @@ -#include +#include #include #include #include //instead of -//typedef CGAL::Extended_homogeneous Kernel; +//typedef CGAL::Extended_homogeneous Kernel; // workaround for VC++ -struct Kernel : public CGAL::Extended_homogeneous {}; +struct Kernel : public CGAL::Extended_homogeneous {}; typedef CGAL::Nef_polyhedron_3 Nef_polyhedron; typedef Nef_polyhedron::Plane_3 Plane_3; diff -Nru cgal-4.4/examples/Nef_S2/nef_s2_construction.cpp cgal-4.5/examples/Nef_S2/nef_s2_construction.cpp --- cgal-4.4/examples/Nef_S2/nef_s2_construction.cpp 2012-11-13 13:13:58.000000000 +0000 +++ cgal-4.5/examples/Nef_S2/nef_s2_construction.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -1,8 +1,8 @@ -#include +#include #include #include -typedef CGAL::Gmpz RT; +typedef CGAL::Exact_integer RT; typedef CGAL::Homogeneous Kernel; typedef CGAL::Nef_polyhedron_S2 Nef_polyhedron; typedef Nef_polyhedron::Sphere_point Sphere_point; diff -Nru cgal-4.4/examples/Nef_S2/nef_s2_exploration.cpp cgal-4.5/examples/Nef_S2/nef_s2_exploration.cpp --- cgal-4.4/examples/Nef_S2/nef_s2_exploration.cpp 2012-11-13 13:13:58.000000000 +0000 +++ cgal-4.5/examples/Nef_S2/nef_s2_exploration.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -1,9 +1,9 @@ -#include +#include #include #include #include -typedef CGAL::Gmpq FT; +typedef CGAL::Exact_rational FT; typedef CGAL::Cartesian Kernel; typedef CGAL::Nef_polyhedron_S2 Nef_polyhedron_S2; typedef Nef_polyhedron_S2::SVertex_const_handle SVertex_const_handle; diff -Nru cgal-4.4/examples/Nef_S2/nef_s2_point_location.cpp cgal-4.5/examples/Nef_S2/nef_s2_point_location.cpp --- cgal-4.4/examples/Nef_S2/nef_s2_point_location.cpp 2012-11-13 13:13:58.000000000 +0000 +++ cgal-4.5/examples/Nef_S2/nef_s2_point_location.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -1,9 +1,9 @@ -#include +#include #include #include #include -typedef CGAL::Gmpq FT; +typedef CGAL::Exact_rational FT; typedef CGAL::Cartesian Kernel; typedef CGAL::Nef_polyhedron_S2 Nef_polyhedron_S2; typedef Nef_polyhedron_S2::SVertex_const_handle SVertex_const_handle; diff -Nru cgal-4.4/examples/Nef_S2/nef_s2_simple.cpp cgal-4.5/examples/Nef_S2/nef_s2_simple.cpp --- cgal-4.4/examples/Nef_S2/nef_s2_simple.cpp 2012-11-13 13:13:58.000000000 +0000 +++ cgal-4.5/examples/Nef_S2/nef_s2_simple.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -1,8 +1,8 @@ -#include +#include #include #include -typedef CGAL::Gmpz RT; +typedef CGAL::Exact_integer RT; typedef CGAL::Homogeneous Kernel; typedef CGAL::Nef_polyhedron_S2 Nef_polyhedron; typedef Nef_polyhedron::Sphere_circle Sphere_circle; diff -Nru cgal-4.4/examples/Point_set_processing_3/CMakeLists.txt cgal-4.5/examples/Point_set_processing_3/CMakeLists.txt --- cgal-4.4/examples/Point_set_processing_3/CMakeLists.txt 2012-11-13 13:13:59.000000000 +0000 +++ cgal-4.5/examples/Point_set_processing_3/CMakeLists.txt 2014-08-29 13:58:16.000000000 +0000 @@ -23,12 +23,10 @@ include( ${CGAL_USE_FILE} ) include( CGAL_CreateSingleSourceCGALProgram ) + find_package(Boost QUIET) + # VisualC++ optimization for applications dealing with large data if (MSVC) - # Use /EHa option to catch stack overflows. - # Note: TAUCS needs a stack >= 2MB. CGAL default is 10MB. - string(REGEX REPLACE "/EH[asc]*" "/EHa" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") - # Use /FR to turn on IntelliSense SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /FR") @@ -70,13 +68,22 @@ if(EIGEN3_FOUND OR LAPACK_FOUND) # Executables that require Eigen or BLAS and LAPACK create_single_source_cgal_program( "jet_smoothing_example.cpp" ) - create_single_source_cgal_program( "normal_estimation.cpp" ) + if(NOT Boost_VERSION EQUAL "105400") + create_single_source_cgal_program( "normal_estimation.cpp" ) + endif() else(EIGEN3_FOUND OR LAPACK_FOUND) message(STATUS "NOTICE: Some of the executables in this directory need either Eigen 3.1 (or greater) or LAPACK, and will not be compiled.") endif(EIGEN3_FOUND OR LAPACK_FOUND) + if(Boost_VERSION EQUAL "105400") + message(STATUS + "NOTICE: The examples \"normals_examples.cpp\" and " + "\"normal_estimation.cpp\" are incompatible with Boost 1.54," + " and will not be compiled.") + message(STATUS "See the following bug: https://svn.boost.org/trac/boost/ticket/9012") + endif() else() message(STATUS "NOTICE: This program requires the CGAL library, and will not be compiled.") diff -Nru cgal-4.4/examples/Polynomial/subresultants.cpp cgal-4.5/examples/Polynomial/subresultants.cpp --- cgal-4.4/examples/Polynomial/subresultants.cpp 2013-10-12 19:00:22.000000000 +0000 +++ cgal-4.5/examples/Polynomial/subresultants.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -2,12 +2,12 @@ #include #include -#include +#include int main(){ CGAL::set_pretty_mode(std::cout); - typedef CGAL::Gmpz Int; + typedef CGAL::Exact_integer Int; typedef CGAL::Polynomial_type_generator::Type Poly_1; typedef CGAL::Polynomial_traits_d PT_1; diff -Nru cgal-4.4/examples/Polytope_distance_d/width_simplex.cpp cgal-4.5/examples/Polytope_distance_d/width_simplex.cpp --- cgal-4.4/examples/Polytope_distance_d/width_simplex.cpp 2012-11-13 13:14:00.000000000 +0000 +++ cgal-4.5/examples/Polytope_distance_d/width_simplex.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -40,6 +40,7 @@ std::cout << "Direction: " << simplex.get_build_direction() << std::endl; Plane_3 e1, e2; + simplex.get_width_planes (e1, e2); std::cout << "Planes: E1: " << e1 << ". E2: " << e2 < + + +/* Usage + * + * This example converts arbitrary-precision arrangment into fixed-precision using Snap Rounding and by using INPUT DATA FROM A USER SPECIFIED FILE. + * (Mandatory) path to the input file containing the arrangment information. + * (Optional) path to the output file where the results of snap rounding will be stored. + * Not providing this argument will print the result on standard output. + * + * Input file format + * Line # 1: Number of line-segments present in the file. + * Line # 2 to N+1: segment_start_point_x segment_start_point_y segment_end_point_x segment_end_point_y + * + * Each line should contain information about just one segment. +*/ + +#include +#include +#include +#include +#include +#include + +typedef CGAL::Quotient Number_type; +typedef CGAL::Cartesian Kernel; +typedef CGAL::Snap_rounding_traits_2 Traits; +typedef Kernel::Segment_2 Segment_2; +typedef Kernel::Point_2 Point_2; +typedef std::list Segment_list_2; +typedef std::list Polyline_2; +typedef std::list Polyline_list_2; + +int main(int argc, char* argv[]) +{ + //if(argc > 3 || argc < 2) + if(argc > 3) + { + std::cout<< "Incorrect input. path to the INPUT file. (optional) path to the OUTPUT file. No arguments to choose the default data file" << std::endl; + return -1; + } + + Segment_list_2 seg_list; + Polyline_list_2 output_list; + + std::ifstream my_read_file; + std::ofstream my_write_file; + + if(argc > 1) + my_read_file.open(argv[1]); + else + my_read_file.open("data/snap_rounding_data"); + + if(!my_read_file.is_open()) + { + std::cout<< "Error opening the input file"<< std::endl; + return -1; + } + + if(argc==3) + { + my_write_file.open(argv[2]); + + if(!my_read_file.is_open()) + { + std::cout<< "Error opening the output file"<< std::endl; + return -1; + } + } + + unsigned int number_of_lines = 0; + my_read_file >> number_of_lines; + + for(unsigned int i=0; i> point_start_x; + my_read_file >> point_start_y; + my_read_file >> point_end_x; + my_read_file >> point_end_y; + + seg_list.push_back(Segment_2(Point_2(point_start_x, point_start_y), Point_2(point_end_x, point_end_y))); + } + + // Generate an iterated snap-rounding representation, where the centers of + // the hot pixels bear their original coordinates, using 1 kd trees: + CGAL::snap_rounding_2 + (seg_list.begin(), seg_list.end(), output_list, 1.0, true, false, 1); + + int counter = 0; + Polyline_list_2::const_iterator iter1; + + if(argc == 3) //output to the file + { + for (iter1 = output_list.begin(); iter1 != output_list.end(); ++iter1) + { + my_write_file << "Polyline number " << ++counter << ":\n"; + Polyline_2::const_iterator iter2; + + for (iter2 = iter1->begin(); iter2 != iter1->end(); ++iter2) + my_write_file << " (" << iter2->x() << ":" << iter2->y() << ")\n"; + } + + my_write_file.close(); + } + else //output to std output + { + for (iter1 = output_list.begin(); iter1 != output_list.end(); ++iter1) + { + std::cout << "Polyline number " << ++counter << ":\n"; + Polyline_2::const_iterator iter2; + + for (iter2 = iter1->begin(); iter2 != iter1->end(); ++iter2) + std::cout << " (" << iter2->x() << ":" << iter2->y() << ")\n"; + } + } + + my_read_file.close(); + + return(0); +} diff -Nru cgal-4.4/examples/Surface_mesh_parameterization/CMakeLists.txt cgal-4.5/examples/Surface_mesh_parameterization/CMakeLists.txt --- cgal-4.4/examples/Surface_mesh_parameterization/CMakeLists.txt 2012-11-13 13:14:01.000000000 +0000 +++ cgal-4.5/examples/Surface_mesh_parameterization/CMakeLists.txt 2014-08-29 13:58:17.000000000 +0000 @@ -26,10 +26,6 @@ # VisualC++ optimization for applications dealing with large data if (MSVC) - # Use /EHa option to catch stack overflows. - # Note: TAUCS needs a stack >= 2MB. CGAL default is 10MB. - string(REGEX REPLACE "/EH[asc]*" "/EHa" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") - # Use /FR to turn on IntelliSense SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /FR") @@ -70,41 +66,23 @@ list(APPEND CGAL_3RD_PARTY_LIBRARIES ${Boost_PROGRAM_OPTIONS_LIBRARY}) endif() - # Executables that do *not* use TAUCS + # Executables that do *not* require Eigen create_single_source_cgal_program( "Authalic_parameterization.cpp" ) create_single_source_cgal_program( "Mesh_cutting_parameterization.cpp" ) create_single_source_cgal_program( "Simple_parameterization.cpp" ) create_single_source_cgal_program( "Square_border_parameterization.cpp" ) - - # use either Eigen or TAUCS BLAS/LAPACK find_package(Eigen3 3.1.0) #(requires 3.1.0 or greater) - if (EIGEN3_FOUND) - include( ${EIGEN3_USE_FILE} ) - endif() - # Link with BLAS, LAPACK and TAUCS (optional) - find_package(TAUCS) - if(TAUCS_FOUND) - include( ${TAUCS_USE_FILE} ) - endif(TAUCS_FOUND) - if (EIGEN3_FOUND) # Executables that require Eigen 3.1 + include( ${EIGEN3_USE_FILE} ) create_single_source_cgal_program( "Complete_parameterization_example.cpp" ) create_single_source_cgal_program( "Eigen_parameterization.cpp" ) else(EIGEN3_FOUND) - message(STATUS "NOTICE: Example Complete_parameterization_example.cpp requires Eigen 3.1 (or greater) and will not be compiled.") + message(STATUS "NOTICE: Some examples require Eigen 3.1 (or greater) and will not be compiled.") endif(EIGEN3_FOUND) - - if (TAUCS_FOUND) - # Executables that require TAUCS (thus BLAS and LAPACK) - create_single_source_cgal_program( "Taucs_parameterization.cpp" ) - else(TAUCS_FOUND) - message(STATUS "NOTICE: Example Taucs_parameterization.cpp requires TAUCS and will not be compiled.") - endif(TAUCS_FOUND) - # Executable that can use TAUCS or not, depending on the macro CGAL_USE_TAUCS create_single_source_cgal_program( "polyhedron_ex_parameterization.cpp" ) else() diff -Nru cgal-4.4/examples/Surface_mesh_parameterization/Complete_parameterization_example.cmd cgal-4.5/examples/Surface_mesh_parameterization/Complete_parameterization_example.cmd --- cgal-4.4/examples/Surface_mesh_parameterization/Complete_parameterization_example.cmd 2012-11-13 13:14:01.000000000 +0000 +++ cgal-4.5/examples/Surface_mesh_parameterization/Complete_parameterization_example.cmd 2014-08-29 13:58:17.000000000 +0000 @@ -1 +1 @@ -data/sphere966.off sphere966_authalic_square_taucs_parameterized.eps +data/sphere966.off sphere966_authalic_square_opennl_parameterized.eps diff -Nru cgal-4.4/examples/Surface_mesh_parameterization/polyhedron_ex_parameterization.cpp cgal-4.5/examples/Surface_mesh_parameterization/polyhedron_ex_parameterization.cpp --- cgal-4.4/examples/Surface_mesh_parameterization/polyhedron_ex_parameterization.cpp 2013-09-21 19:00:24.000000000 +0000 +++ cgal-4.5/examples/Surface_mesh_parameterization/polyhedron_ex_parameterization.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -12,15 +12,6 @@ // polyhedron_ex_parameterization -t conformal -b circle mesh.off mesh.eps //---------------------------------------------------------- -// floater parameterization -// square border -// TAUCS solver -// output is a eps map -// input file is mesh.off -//---------------------------------------------------------- -// polyhedron_ex_parameterization -t floater -b square -s taucs mesh.off mesh.eps - -//---------------------------------------------------------- // Least Squares Conformal Maps parameterization // two pinned vertices (automatically picked) // OpenNL solver @@ -44,9 +35,6 @@ #include #include -#ifdef CGAL_USE_TAUCS - #include -#endif #include "Polyhedron_ex.h" #include "Mesh_cutter.h" @@ -326,7 +314,7 @@ ("border,b", po::value(&border)->default_value("circle"), "border shape: circle, square or 2pts (lscm only)") ("solver,s", po::value(&solver)->default_value("opennl"), - "solver: opennl or taucs") + "solver: opennl") ("input,i", po::value(&input)->default_value(""), "input mesh (OFF)") ("output,o", po::value(&output)->default_value("out.eps"), @@ -434,18 +422,6 @@ OpenNL::SymmetricLinearSolverTraits >(mesh_patch, type, border); } - else if (solver == std::string("taucs")) - { -#ifdef CGAL_USE_TAUCS - err = parameterize, - CGAL::Taucs_symmetric_solver_traits - >(mesh_patch, type, border); -#else - std::cerr << "Error: TAUCS is not installed" << std::endl; - err = Parameterizer::ERROR_WRONG_PARAMETER; -#endif - } else { std::cerr << "Error: invalid solver parameter " << solver << std::endl; diff -Nru cgal-4.4/examples/Surface_mesh_parameterization/Taucs_parameterization.cmd cgal-4.5/examples/Surface_mesh_parameterization/Taucs_parameterization.cmd --- cgal-4.4/examples/Surface_mesh_parameterization/Taucs_parameterization.cmd 2012-11-13 13:14:01.000000000 +0000 +++ cgal-4.5/examples/Surface_mesh_parameterization/Taucs_parameterization.cmd 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -data/mannequin-devil.off diff -Nru cgal-4.4/examples/Surface_mesh_parameterization/Taucs_parameterization.cpp cgal-4.5/examples/Surface_mesh_parameterization/Taucs_parameterization.cpp --- cgal-4.4/examples/Surface_mesh_parameterization/Taucs_parameterization.cpp 2013-09-14 19:00:19.000000000 +0000 +++ cgal-4.5/examples/Surface_mesh_parameterization/Taucs_parameterization.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,122 +0,0 @@ -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - - -// ---------------------------------------------------------------------------- -// Private types -// ---------------------------------------------------------------------------- - -typedef CGAL::Simple_cartesian Kernel; -typedef CGAL::Polyhedron_3 Polyhedron; - - -// ---------------------------------------------------------------------------- -// main() -// ---------------------------------------------------------------------------- - -int main(int argc, char * argv[]) -{ - std::cerr << "PARAMETERIZATION" << std::endl; - std::cerr << " Floater parameterization" << std::endl; - std::cerr << " Circle border" << std::endl; - std::cerr << " TAUCS solver" << std::endl; - - //*************************************** - // decode parameters - //*************************************** - - if (argc-1 != 1) - { - std::cerr << "Usage: " << argv[0] << " input_file.off" << std::endl; - return(EXIT_FAILURE); - } - - // File name is: - const char* input_filename = argv[1]; - - //*************************************** - // Read the mesh - //*************************************** - - // Read the mesh - std::ifstream stream(input_filename); - Polyhedron mesh; - stream >> mesh; - if(!stream || !mesh.is_valid() || mesh.empty()) - { - std::cerr << "Error: cannot read OFF file " << input_filename << std::endl; - return EXIT_FAILURE; - } - - //*************************************** - // Create Polyhedron adaptor - // Note: no cutting => we support only - // meshes that are topological disks - //*************************************** - - typedef CGAL::Parameterization_polyhedron_adaptor_3 - Parameterization_polyhedron_adaptor; - Parameterization_polyhedron_adaptor mesh_adaptor(mesh); - - //*************************************** - // Floater Mean Value Coordinates parameterization - // (circular border) with TAUCS solver - //*************************************** - - // Circular border parameterizer (the default) - typedef CGAL::Circular_border_arc_length_parameterizer_3 - Border_parameterizer; - // TAUCS solver - typedef CGAL::Taucs_solver_traits Solver; - - // Floater Mean Value Coordinates parameterization - // (circular border) with TAUCS solver - typedef CGAL::Mean_value_coordinates_parameterizer_3 - Parameterizer; - - Parameterizer::Error_code err = CGAL::parameterize(mesh_adaptor, Parameterizer()); - switch(err) { - case Parameterizer::OK: // Success - break; - case Parameterizer::ERROR_EMPTY_MESH: // Input mesh not supported - case Parameterizer::ERROR_NON_TRIANGULAR_MESH: - case Parameterizer::ERROR_NO_TOPOLOGICAL_DISC: - case Parameterizer::ERROR_BORDER_TOO_SHORT: - std::cerr << "Input mesh not supported: " << Parameterizer::get_error_message(err) << std::endl; - return EXIT_FAILURE; - break; - default: // Error - std::cerr << "Error: " << Parameterizer::get_error_message(err) << std::endl; - return EXIT_FAILURE; - break; - }; - - //*************************************** - // Output - //*************************************** - - // Raw output: dump (u,v) pairs - Polyhedron::Vertex_const_iterator pVertex; - for (pVertex = mesh.vertices_begin(); - pVertex != mesh.vertices_end(); - pVertex++) - { - // (u,v) pair is stored in any halfedge - double u = mesh_adaptor.info(pVertex->halfedge())->uv().x(); - double v = mesh_adaptor.info(pVertex->halfedge())->uv().y(); - std::cout << "(u,v) = (" << u << "," << v << ")" << std::endl; - } - - return EXIT_SUCCESS; -} diff -Nru cgal-4.4/examples/Surface_mesh_segmentation/CMakeLists.txt cgal-4.5/examples/Surface_mesh_segmentation/CMakeLists.txt --- cgal-4.4/examples/Surface_mesh_segmentation/CMakeLists.txt 2014-04-03 19:01:53.000000000 +0000 +++ cgal-4.5/examples/Surface_mesh_segmentation/CMakeLists.txt 2014-08-29 13:58:17.000000000 +0000 @@ -1,8 +1,8 @@ -# Created by the script cgal_create_cmake_script -# This is the CMake script for compiling a CGAL application. +# Created by the script cgal_create_cmake_script_with_options +# This is the CMake script for compiling a set of CGAL applications. +project( Surface_mesh_segmentation ) -project( Surface_mesh_segmentation_example ) cmake_minimum_required(VERSION 2.6.2) if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" VERSION_GREATER 2.6) @@ -13,24 +13,68 @@ endif() endif() -find_package(CGAL QUIET COMPONENTS Core ) +set( CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true ) + +if ( COMMAND cmake_policy ) -if ( CGAL_FOUND ) + cmake_policy( SET CMP0003 NEW ) - include( ${CGAL_USE_FILE} ) +endif() + +# CGAL and its components +find_package( CGAL QUIET COMPONENTS ) + +if ( NOT CGAL_FOUND ) + + message(STATUS "This project requires the CGAL library, and will not be compiled.") + return() + +endif() - include( CGAL_CreateSingleSourceCGALProgram ) +# include helper file +include( ${CGAL_USE_FILE} ) - include_directories (BEFORE "../../include") - create_single_source_cgal_program( "sdf_values_example.cpp" ) - create_single_source_cgal_program( "segmentation_from_sdf_values_example.cpp" ) - create_single_source_cgal_program( "segmentation_via_sdf_values_example.cpp" ) - create_single_source_cgal_program( "segmentation_with_facet_ids_example.cpp" ) +# Boost and its components +find_package( Boost REQUIRED ) + +if ( NOT Boost_FOUND ) + + message(STATUS "This project requires the Boost library, and will not be compiled.") + + return() + +endif() + +find_package( OpenMesh QUIET ) +if ( OpenMesh_FOUND ) +include( UseOpenMesh ) else() - - message(STATUS "This program requires the CGAL library, and will not be compiled.") - + message(STATUS "Examples that use OpenMesh will not be compiled.") +endif() + + +# include for local package +include_directories( BEFORE ../../include ) + + + +# Creating entries for all .cpp/.C files with "main" routine +# ########################################################## + +include( CGAL_CreateSingleSourceCGALProgram ) + +create_single_source_cgal_program( "sdf_values_example.cpp" ) + +create_single_source_cgal_program( "segmentation_from_sdf_values_example.cpp" ) + +create_single_source_cgal_program( "segmentation_via_sdf_values_example.cpp" ) + +create_single_source_cgal_program( "segmentation_with_facet_ids_example.cpp" ) + +if(OpenMesh_FOUND) + create_single_source_cgal_program( "segmentation_from_sdf_values_OpenMesh_example.cpp" ) + target_link_libraries( segmentation_from_sdf_values_OpenMesh_example ${OPENMESH_LIBRARIES} ) endif() diff -Nru cgal-4.4/examples/Surface_mesh_segmentation/sdf_values_example.cpp cgal-4.5/examples/Surface_mesh_segmentation/sdf_values_example.cpp --- cgal-4.4/examples/Surface_mesh_segmentation/sdf_values_example.cpp 2014-01-11 20:00:27.000000000 +0000 +++ cgal-4.5/examples/Surface_mesh_segmentation/sdf_values_example.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -1,5 +1,5 @@ #include -#include +#include #include #include diff -Nru cgal-4.4/examples/Surface_mesh_segmentation/segmentation_from_sdf_values_example.cpp cgal-4.5/examples/Surface_mesh_segmentation/segmentation_from_sdf_values_example.cpp --- cgal-4.4/examples/Surface_mesh_segmentation/segmentation_from_sdf_values_example.cpp 2014-01-11 20:00:27.000000000 +0000 +++ cgal-4.5/examples/Surface_mesh_segmentation/segmentation_from_sdf_values_example.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -1,5 +1,5 @@ #include -#include +#include #include #include diff -Nru cgal-4.4/examples/Surface_mesh_segmentation/segmentation_from_sdf_values_OpenMesh_example.cpp cgal-4.5/examples/Surface_mesh_segmentation/segmentation_from_sdf_values_OpenMesh_example.cpp --- cgal-4.4/examples/Surface_mesh_segmentation/segmentation_from_sdf_values_OpenMesh_example.cpp 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/examples/Surface_mesh_segmentation/segmentation_from_sdf_values_OpenMesh_example.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,69 @@ +#define CGAL_BGL_TESTSUITE +#include + +#include +#include + +#include + +#include + +#include + +#include +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; + +typedef OpenMesh::PolyMesh_ArrayKernelT Mesh; + +typedef boost::graph_traits::face_descriptor face_descriptor; +typedef boost::graph_traits::face_iterator face_iterator; + +int main(int argc, char** argv ) +{ + Mesh mesh; + if (argc==2) + OpenMesh::IO::read_mesh(mesh, argv[1]); + else + OpenMesh::IO::read_mesh(mesh, "data/cactus.off"); + + // create a property-map for SDF values + typedef std::map Facet_double_map; + Facet_double_map internal_sdf_map; + boost::associative_property_map sdf_property_map(internal_sdf_map); + + typedef boost::property_map::type Ppmap; + Ppmap ppmap(mesh); + + // compute SDF values + // We can't use default parameters for number of rays, and cone angle + // and the postprocessing + CGAL::sdf_values(mesh, sdf_property_map, 2.0 / 3.0 * CGAL_PI, 25, true, ppmap); + + // create a property-map for segment-ids + typedef std::map Facet_int_map; + Facet_int_map internal_segment_map; + boost::associative_property_map segment_property_map(internal_segment_map); + + // segment the mesh using default parameters for number of levels, and smoothing lambda + // Any other scalar values can be used instead of using SDF values computed using the CGAL function + std::size_t number_of_segments = CGAL::segmentation_from_sdf_values(mesh, sdf_property_map, segment_property_map); + + std::cout << "Number of segments: " << number_of_segments << std::endl; + // print segment-ids + face_iterator facet_it, fend; + for(boost::tie(facet_it,fend) = faces(mesh); + facet_it != fend; ++facet_it) { + // ids are between [0, number_of_segments -1] + std::cout << segment_property_map[*facet_it] << " "; + } + std::cout << std::endl; + + const std::size_t number_of_clusters = 4; // use 4 clusters in soft clustering + const double smoothing_lambda = 0.3; // importance of surface features, suggested to be in-between [0,1] + + // Note that we can use the same SDF values (sdf_property_map) over and over again for segmentation. + // This feature is relevant for segmenting the mesh several times with different parameters. + CGAL::segmentation_from_sdf_values(mesh, sdf_property_map, segment_property_map, number_of_clusters, smoothing_lambda); +} diff -Nru cgal-4.4/examples/Surface_mesh_segmentation/segmentation_via_sdf_values_example.cpp cgal-4.5/examples/Surface_mesh_segmentation/segmentation_via_sdf_values_example.cpp --- cgal-4.4/examples/Surface_mesh_segmentation/segmentation_via_sdf_values_example.cpp 2014-01-11 20:00:27.000000000 +0000 +++ cgal-4.5/examples/Surface_mesh_segmentation/segmentation_via_sdf_values_example.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -1,5 +1,5 @@ #include -#include +#include #include #include diff -Nru cgal-4.4/examples/Surface_mesh_segmentation/segmentation_with_facet_ids_example.cpp cgal-4.5/examples/Surface_mesh_segmentation/segmentation_with_facet_ids_example.cpp --- cgal-4.4/examples/Surface_mesh_segmentation/segmentation_with_facet_ids_example.cpp 2014-01-11 20:00:27.000000000 +0000 +++ cgal-4.5/examples/Surface_mesh_segmentation/segmentation_with_facet_ids_example.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -1,5 +1,5 @@ #include -#include +#include #include #include #include diff -Nru cgal-4.4/examples/Surface_mesh_simplification/CMakeLists.txt cgal-4.5/examples/Surface_mesh_simplification/CMakeLists.txt --- cgal-4.4/examples/Surface_mesh_simplification/CMakeLists.txt 2014-04-03 19:01:53.000000000 +0000 +++ cgal-4.5/examples/Surface_mesh_simplification/CMakeLists.txt 2014-08-29 13:58:17.000000000 +0000 @@ -1,8 +1,8 @@ -# Created by the script cgal_create_cmake_script -# This is the CMake script for compiling a CGAL application. +# Created by the script cgal_create_cmake_script_with_options +# This is the CMake script for compiling a set of CGAL applications. +project( Surface_mesh_simplification ) -project( Surface_mesh_simplification_example ) cmake_minimum_required(VERSION 2.6.2) if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" VERSION_GREATER 2.6) @@ -13,24 +13,72 @@ endif() endif() -find_package(CGAL QUIET COMPONENTS Core ) +set( CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true ) + +if ( COMMAND cmake_policy ) -if ( CGAL_FOUND ) + cmake_policy( SET CMP0003 NEW ) - include( ${CGAL_USE_FILE} ) +endif() + +# CGAL and its components +find_package( CGAL QUIET COMPONENTS ) + +if ( NOT CGAL_FOUND ) + + message(STATUS "This project requires the CGAL library, and will not be compiled.") + return() + +endif() + +# include helper file +include( ${CGAL_USE_FILE} ) - include( CGAL_CreateSingleSourceCGALProgram ) - include_directories (BEFORE "../../include") +# Boost and its components +find_package( Boost REQUIRED ) - create_single_source_cgal_program( "edge_collapse_constrain_sharp_edges.cpp" ) - create_single_source_cgal_program( "edge_collapse_constrained_border_polyhedron.cpp" ) - create_single_source_cgal_program( "edge_collapse_enriched_polyhedron.cpp" ) - create_single_source_cgal_program( "edge_collapse_polyhedron.cpp" ) +if ( NOT Boost_FOUND ) + message(STATUS "This project requires the Boost library, and will not be compiled.") + + return() + +endif() + + +find_package( OpenMesh QUIET ) + +if ( OpenMesh_FOUND ) +include( UseOpenMesh ) else() - - message(STATUS "This program requires the CGAL library, and will not be compiled.") - + message(STATUS "Examples that use OpenMesh will not be compiled.") endif() +# include for local directory + +# include for local package +include_directories( BEFORE ../../include ) + + + +# Creating entries for all .cpp/.C files with "main" routine +# ########################################################## + +include( CGAL_CreateSingleSourceCGALProgram ) + + +create_single_source_cgal_program( "edge_collapse_constrain_sharp_edges.cpp" ) + +create_single_source_cgal_program( "edge_collapse_constrained_border_polyhedron.cpp" ) + +create_single_source_cgal_program( "edge_collapse_enriched_polyhedron.cpp" ) + +create_single_source_cgal_program( "edge_collapse_polyhedron.cpp" ) + + +if(OpenMesh_FOUND) +create_single_source_cgal_program( "edge_collapse_OpenMesh.cpp" ) + +target_link_libraries( edge_collapse_OpenMesh ${OPENMESH_LIBRARIES} ) +endif() diff -Nru cgal-4.4/examples/Surface_mesh_simplification/edge_collapse_constrained_border_polyhedron.cpp cgal-4.5/examples/Surface_mesh_simplification/edge_collapse_constrained_border_polyhedron.cpp --- cgal-4.4/examples/Surface_mesh_simplification/edge_collapse_constrained_border_polyhedron.cpp 2014-02-15 20:00:24.000000000 +0000 +++ cgal-4.5/examples/Surface_mesh_simplification/edge_collapse_constrained_border_polyhedron.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -5,9 +5,7 @@ #include #include #include - -// Adaptor for Polyhedron_3 -#include +#include // Simplification function #include @@ -31,12 +29,21 @@ // BGL property map which indicates whether an edge is marked as non-removable // struct Border_is_constrained_edge_map{ + const Surface_mesh* sm_ptr; typedef boost::graph_traits::edge_descriptor key_type; typedef bool value_type; typedef value_type reference; typedef boost::readable_property_map_tag category; - friend bool get(Border_is_constrained_edge_map, key_type edge) { - return edge->is_border_edge(); + + Border_is_constrained_edge_map() + {} + + Border_is_constrained_edge_map(const Surface_mesh& sm) + : sm_ptr(&sm) + {} + + friend bool get(Border_is_constrained_edge_map m, const key_type& edge) { + return CGAL::is_border(edge, *m.sm_ptr); } }; @@ -89,9 +96,9 @@ int r = SMS::edge_collapse (surface_mesh ,stop - ,CGAL::vertex_index_map(boost::get(CGAL::vertex_external_index,surface_mesh)) - .edge_index_map (boost::get(CGAL::edge_external_index ,surface_mesh)) - .edge_is_constrained_map(Border_is_constrained_edge_map()) + ,CGAL::vertex_index_map(get(CGAL::vertex_external_index,surface_mesh)) + .halfedge_index_map (get(CGAL::halfedge_external_index ,surface_mesh)) + .edge_is_constrained_map(Border_is_constrained_edge_map(surface_mesh)) .get_placement(Placement()) ); diff -Nru cgal-4.4/examples/Surface_mesh_simplification/edge_collapse_constrain_sharp_edges.cpp cgal-4.5/examples/Surface_mesh_simplification/edge_collapse_constrain_sharp_edges.cpp --- cgal-4.4/examples/Surface_mesh_simplification/edge_collapse_constrain_sharp_edges.cpp 2014-02-22 20:00:27.000000000 +0000 +++ cgal-4.5/examples/Surface_mesh_simplification/edge_collapse_constrain_sharp_edges.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -1,11 +1,13 @@ #include #include + + #include #include #include +#include -#include #include #include #include @@ -18,19 +20,15 @@ typedef CGAL::Simple_cartesian Kernel; typedef Kernel::Point_3 Point_3; typedef CGAL::Polyhedron_3 Surface_mesh; -typedef boost::graph_traits::edge_descriptor edge_descriptor; +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef boost::graph_traits::halfedge_descriptor halfedge_descriptor; +typedef boost::graph_traits::edge_descriptor edge_descriptor; +typedef boost::graph_traits::edge_iterator edge_iterator; namespace SMS = CGAL::Surface_mesh_simplification ; - -typedef Surface_mesh::Facet_iterator Facet_iterator; -typedef Surface_mesh::Halfedge_handle Halfedge_handle; -typedef Surface_mesh::Halfedge_iterator Halfedge_iterator; - - // // BGL property map which indicates whether an edge is marked as non-removable -// struct Constrained_edge_map : public boost::put_get_helper { typedef boost::readable_property_map_tag category; @@ -39,25 +37,38 @@ typedef edge_descriptor key_type; Constrained_edge_map(const CGAL::Unique_hash_map& aConstraints) - : mConstraints(aConstraints) {} + : mConstraints(aConstraints) + {} reference operator[](key_type const& e) const { return is_constrained(e); } bool is_constrained( key_type const& e ) const { - return mConstraints.is_defined(e) ? mConstraints[e] : false ; } + return mConstraints.is_defined(e); + } private: const CGAL::Unique_hash_map& mConstraints; }; +bool is_border (edge_descriptor e, const Surface_mesh& sm) +{ + return (face(halfedge(e,sm),sm) == boost::graph_traits::null_face() ) + || (face(opposite(halfedge(e,sm),sm),sm) == boost::graph_traits::null_face() ); +} + +Point_3 point(vertex_descriptor vd, const Surface_mesh& sm) +{ + return get(CGAL::vertex_point, sm, vd); +} + int main( int argc, char** argv ) { CGAL::Unique_hash_map constraint_hmap(false); Surface_mesh surface_mesh; - if (argc!=2){ - std::cerr<< "Usage: " << argv[0] << " input.off\n"; + if (argc < 2){ + std::cerr<< "Usage: " << argv[0] << " input.off [out.off]\n"; return 1; } @@ -75,89 +86,92 @@ // map used to check that constrained_edges and the points of its vertices // are preserved at the end of the simplification - // Warning: the computation of the diedral angle is only an approximation and can + // Warning: the computation of the dihedral angle is only an approximation and can // be far from the real value and could influence the detection of sharp // edges after the simplification - std::map >constrained_edges; + std::map >constrained_edges; std::size_t nb_sharp_edges=0; // detect sharp edges std::ofstream cst_output("constrained_edges.cgal"); - for(Surface_mesh::Edge_iterator eb = surface_mesh.edges_begin(), ee = surface_mesh.edges_end() ; eb != ee ; ++eb ) + edge_iterator eb,ee; + for(boost::tie(eb,ee) = edges(surface_mesh); eb != ee ; ++eb ) { - if ( eb->is_border_edge() ){ + halfedge_descriptor hd = halfedge(*eb,surface_mesh); + if ( is_border(*eb,surface_mesh) ){ + std::cerr << "border" << std::endl; ++nb_sharp_edges; - constraint_hmap[eb]=true; - constraint_hmap[eb->opposite()]=true; - constrained_edges[eb]=std::make_pair( eb->opposite()->vertex()->point(), - eb->vertex()->point() ); + constraint_hmap[*eb]=true; + constrained_edges[*eb]=std::make_pair(point(source(hd,surface_mesh),surface_mesh), + point(target(hd,surface_mesh),surface_mesh)); } else{ - double angle = CGAL::Mesh_3::dihedral_angle( - eb->opposite()->vertex()->point(), - eb->vertex()->point(), - eb->next()->vertex()->point(), - eb->opposite()->next()->vertex()->point() ); - if ( std::abs(angle)<100 ){ + double angle = CGAL::Mesh_3::dihedral_angle(point(target(opposite(hd,surface_mesh),surface_mesh),surface_mesh), + point(target(hd,surface_mesh),surface_mesh), + point(target(next(hd,surface_mesh),surface_mesh),surface_mesh), + point(target(next(opposite(hd,surface_mesh),surface_mesh),surface_mesh),surface_mesh)); + if ( CGAL::abs(angle)<100 ){ ++nb_sharp_edges; - constraint_hmap[eb]=true; - constraint_hmap[eb->opposite()]=true; - constrained_edges[eb]=std::make_pair( eb->opposite()->vertex()->point(), - eb->vertex()->point() ); - cst_output << "2 " << eb->opposite()->vertex()->point() << " " - << " " << eb->vertex()->point() << "\n"; + constraint_hmap[*eb]=true; + Point_3 p = point(source(hd,surface_mesh),surface_mesh); + Point_3 q = point(target(hd,surface_mesh),surface_mesh); + constrained_edges[*eb]=std::make_pair(p,q); + cst_output << "2 " << p << " " << q << "\n"; } } } cst_output.close(); + std::cerr << "# sharp edges = " << nb_sharp_edges << std::endl; + // Contract the surface mesh as much as possible SMS::Count_stop_predicate stop(0); int r = SMS::edge_collapse(surface_mesh ,stop - ,CGAL::vertex_index_map(boost::get(CGAL::vertex_external_index,surface_mesh)) - .edge_index_map (boost::get(CGAL::edge_external_index ,surface_mesh)) + ,CGAL::vertex_index_map(get(CGAL::vertex_external_index, surface_mesh)) + .halfedge_index_map(get(CGAL::halfedge_external_index, surface_mesh)) .edge_is_constrained_map(constraints_map) .get_placement(placement) ); std::cout << "\nFinished...\n" << r << " edges removed.\n" - << (surface_mesh.size_of_halfedges()/2) << " final edges.\n" ; + << num_edges(surface_mesh) << " final edges.\n" ; std::ofstream os(argc > 2 ? argv[2] : "out.off") ; os << surface_mesh ; std::cout << "Checking sharped edges were preserved...\n"; // check sharp edges were preserved - for(Surface_mesh::Edge_iterator eb = surface_mesh.edges_begin(), ee = surface_mesh.edges_end() ; eb != ee ; ++eb ) + for(boost::tie(eb,ee) = edges(surface_mesh); eb != ee ; ++eb ) { - if ( eb->is_border_edge() ){ + halfedge_descriptor hd = halfedge(*eb,surface_mesh); + if ( is_border(*eb,surface_mesh) ){ --nb_sharp_edges; assert( - constrained_edges[eb]==std::make_pair( eb->opposite()->vertex()->point(), - eb->vertex()->point() ) ); + constrained_edges[*eb]==std::make_pair( point(source(hd,surface_mesh),surface_mesh), + point(target(hd,surface_mesh),surface_mesh))); } else{ - double angle = CGAL::Mesh_3::dihedral_angle( - eb->opposite()->vertex()->point(), - eb->vertex()->point(), - eb->next()->vertex()->point(), - eb->opposite()->next()->vertex()->point() ); - if ( std::abs(angle)<100 ){ - ++nb_sharp_edges; + double angle = CGAL::Mesh_3::dihedral_angle(point(target(opposite(hd,surface_mesh),surface_mesh),surface_mesh), + point(target(hd,surface_mesh),surface_mesh), + point(target(next(hd,surface_mesh),surface_mesh),surface_mesh), + point(target(next(opposite(hd,surface_mesh),surface_mesh),surface_mesh),surface_mesh)); + if ( CGAL::abs(angle)<100 ){ + --nb_sharp_edges; assert( - constrained_edges[eb]==std::make_pair( eb->opposite()->vertex()->point(), - eb->vertex()->point() ) ); + constrained_edges[*eb]==std::make_pair( point(source(hd,surface_mesh),surface_mesh), + point(target(hd,surface_mesh),surface_mesh))); } } } std::cout << "OK\n"; + std::cerr << "# sharp edges = " << nb_sharp_edges << std::endl; std::cout << "Check that no removable edge has been forgotten..." << std::endl; r = SMS::edge_collapse(surface_mesh ,stop - ,CGAL::vertex_index_map(boost::get(CGAL::vertex_external_index, surface_mesh)) - .edge_index_map (boost::get(CGAL::edge_external_index, surface_mesh)) + ,CGAL::vertex_index_map(get(CGAL::vertex_external_index, surface_mesh)) + .halfedge_index_map (get(CGAL::halfedge_external_index, surface_mesh)) .edge_is_constrained_map(constraints_map) .get_placement(placement) ); diff -Nru cgal-4.4/examples/Surface_mesh_simplification/edge_collapse_enriched_polyhedron.cpp cgal-4.5/examples/Surface_mesh_simplification/edge_collapse_enriched_polyhedron.cpp --- cgal-4.4/examples/Surface_mesh_simplification/edge_collapse_enriched_polyhedron.cpp 2014-02-15 20:00:24.000000000 +0000 +++ cgal-4.5/examples/Surface_mesh_simplification/edge_collapse_enriched_polyhedron.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -5,8 +5,7 @@ #include #include -// Adaptor for Polyhedron_3 -#include +#include // Simplification function #include diff -Nru cgal-4.4/examples/Surface_mesh_simplification/edge_collapse_OpenMesh.cpp cgal-4.5/examples/Surface_mesh_simplification/edge_collapse_OpenMesh.cpp --- cgal-4.4/examples/Surface_mesh_simplification/edge_collapse_OpenMesh.cpp 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/examples/Surface_mesh_simplification/edge_collapse_OpenMesh.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,97 @@ +#include +#include + +#include + +#include +#include + +#include + +// Simplification function +#include +#include +#include +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; + +typedef OpenMesh::PolyMesh_ArrayKernelT Surface_mesh; + +typedef boost::graph_traits::edge_descriptor edge_descriptor; +typedef boost::graph_traits::edge_iterator edge_iterator; + +class Constrained_edge_map +{ +public: + typedef boost::read_write_property_map_tag category; + typedef bool value_type; + typedef bool reference; + typedef edge_descriptor key_type; + + Constrained_edge_map(Surface_mesh& sm) + : sm_(sm) + { + sm_.add_property(constraint); + } + + inline friend reference get(const Constrained_edge_map& em, key_type e) + { + bool b = em.sm_.property(em.constraint,em.sm_.edge_handle(e.idx())); + return b; + } + + inline friend void put(const Constrained_edge_map& em, key_type e, value_type b) + { + em.sm_.property(em.constraint,em.sm_.edge_handle(e.idx())) = b; + } + +private: + Surface_mesh& sm_; + OpenMesh::EPropHandleT constraint; +}; + + + +namespace SMS = CGAL::Surface_mesh_simplification ; + +int main( int argc, char** argv ) +{ + Surface_mesh surface_mesh; + Constrained_edge_map constraints_map(surface_mesh); + if (argc==2) + OpenMesh::IO::read_mesh(surface_mesh, argv[1]); + else + OpenMesh::IO::read_mesh(surface_mesh, "cube.off"); + // For the pupose of the example we mark 10 edges as constrained edges + edge_iterator b,e; + int count=0; + for(boost::tie(b,e) = edges(surface_mesh); b!= e; ++b){ + put(constraints_map,*b,(count++ <100)); + } + // This is a stop predicate (defines when the algorithm terminates). + // In this example, the simplification stops when the number of undirected edges + // left in the surface mesh drops below the specified number (1000) + SMS::Count_stop_predicate stop(0); + + // This the actual call to the simplification algorithm. + // The surface mesh and stop conditions are mandatory arguments. + + int r = SMS::edge_collapse + (surface_mesh + ,stop + ,CGAL::halfedge_index_map (get(CGAL::halfedge_index ,surface_mesh)) + .vertex_point_map(get(boost::vertex_point, surface_mesh)) + .edge_is_constrained_map(constraints_map) + ); + + surface_mesh.garbage_collection(); + std::cout << "\nFinished...\n" << r << " edges removed.\n" + << num_edges(surface_mesh) << " final edges.\n" ; + + OpenMesh::IO::write_mesh(surface_mesh, "out.off"); + + return 0 ; +} + +// EOF // diff -Nru cgal-4.4/examples/Surface_mesh_simplification/edge_collapse_polyhedron.cpp cgal-4.5/examples/Surface_mesh_simplification/edge_collapse_polyhedron.cpp --- cgal-4.4/examples/Surface_mesh_simplification/edge_collapse_polyhedron.cpp 2014-02-15 20:00:24.000000000 +0000 +++ cgal-4.5/examples/Surface_mesh_simplification/edge_collapse_polyhedron.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -4,15 +4,16 @@ #include #include #include - -// Adaptor for Polyhedron_3 -#include +#include // Simplification function #include // Stop-condition policy #include +#include +#include + typedef CGAL::Simple_cartesian Kernel; typedef CGAL::Polyhedron_3 Surface_mesh; @@ -37,8 +38,10 @@ int r = SMS::edge_collapse (surface_mesh ,stop - ,CGAL::vertex_index_map(boost::get(CGAL::vertex_external_index,surface_mesh)) - .edge_index_map (boost::get(CGAL::edge_external_index ,surface_mesh)) + ,CGAL::vertex_index_map(get(CGAL::vertex_external_index,surface_mesh)) + .halfedge_index_map (get(CGAL::halfedge_external_index ,surface_mesh)) + .get_cost (SMS::Edge_length_cost ()) + .get_placement(SMS::Midpoint_placement()) ); std::cout << "\nFinished...\n" << r << " edges removed.\n" diff -Nru cgal-4.4/examples/Surface_modeling/all_roi_assign_example.cpp cgal-4.5/examples/Surface_modeling/all_roi_assign_example.cpp --- cgal-4.4/examples/Surface_modeling/all_roi_assign_example.cpp 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/examples/Surface_modeling/all_roi_assign_example.cpp 2014-10-04 19:00:10.000000000 +0000 @@ -0,0 +1,99 @@ +#include +#include +#include +#include +// HalfedgeGraph adapters for Polyhedron_3 +#include +#include + +#include + +#include + + +typedef CGAL::Simple_cartesian Kernel; +typedef CGAL::Polyhedron_3 Polyhedron; + +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef boost::graph_traits::vertex_iterator vertex_iterator; + +typedef CGAL::Surface_mesh_deformation Surface_mesh_deformation; + +int main() +{ + Polyhedron mesh; + std::ifstream input("data/plane.off"); + + if ( !input || !(input >> mesh) || mesh.empty() ) { + std::cerr<< "Cannot open data/plane.off" << std::endl; + return 1; + } + + // Init the indices of the halfedges and the vertices. + set_halfedgeds_items_id(mesh); + + // Create a deformation object + Surface_mesh_deformation deform_mesh(mesh); + + // Definition of the region of interest (use the whole mesh) + vertex_iterator vb,ve; + boost::tie(vb, ve) = vertices(mesh); + deform_mesh.insert_roi_vertices(vb, ve); + + // Select two control vertices ... + vertex_descriptor control_1 = *CGAL::cpp11::next(vb, 213); + vertex_descriptor control_2 = *CGAL::cpp11::next(vb, 157); + + // ... and insert them + deform_mesh.insert_control_vertex(control_1); + deform_mesh.insert_control_vertex(control_2); + + // The definition of the ROI and the control vertices is done, call preprocess + bool is_matrix_factorization_OK = deform_mesh.preprocess(); + if(!is_matrix_factorization_OK){ + std::cerr << "Error in preprocessing, check documentation of preprocess()" << std::endl; + return 1; + } + + // Use set_target_position() to set the constained position + // of control_1. control_2 remains at the last assigned positions + Surface_mesh_deformation::Point constrained_pos_1(-0.35, 0.40, 0.60); + deform_mesh.set_target_position(control_1, constrained_pos_1); + + // Deform the mesh, the positions of vertices of 'mesh' are updated + deform_mesh.deform(); + // The function deform() can be called several times if the convergence has not been reached yet + deform_mesh.deform(); + + // Set the constained position of control_2 + Surface_mesh_deformation::Point constrained_pos_2(0.55, -0.30, 0.70); + deform_mesh.set_target_position(control_2, constrained_pos_2); + + // Call the function deform() with one-time parameters: + // iterate 10 times and do not use energy based termination criterion + deform_mesh.deform(10, 0.0); + + // Save the deformed mesh into a file + std::ofstream output("deform_1.off"); + output << mesh; + output.close(); + + // Add another control vertex which requires another call to preprocess + vertex_descriptor control_3 = *CGAL::cpp11::next(vb, 92); + deform_mesh.insert_control_vertex(control_3); + + // The prepocessing step is again needed + if(!deform_mesh.preprocess()){ + std::cerr << "Error in preprocessing, check documentation of preprocess()" << std::endl; + return 1; + } + + // Deform the mesh + Surface_mesh_deformation::Point constrained_pos_3(0.55, 0.30, -0.70); + deform_mesh.set_target_position(control_3, constrained_pos_3); + + deform_mesh.deform(15, 0.0); + + output.open("deform_2.off"); + output << mesh; +} diff -Nru cgal-4.4/examples/Surface_modeling/all_roi_assign_example_custom_polyhedron.cpp cgal-4.5/examples/Surface_modeling/all_roi_assign_example_custom_polyhedron.cpp --- cgal-4.4/examples/Surface_modeling/all_roi_assign_example_custom_polyhedron.cpp 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/examples/Surface_modeling/all_roi_assign_example_custom_polyhedron.cpp 2014-10-04 19:00:10.000000000 +0000 @@ -0,0 +1,155 @@ +#include +#include +#include +#include + +struct Custom_point_3{ + // Required by File_scanner_OFF + struct R{ + typedef double RT; + }; + + double coords[3]; + Custom_point_3(){} + Custom_point_3(double x, double y, double z) + { coords[0]=x; coords[1]=y; coords[2]=z; } + Custom_point_3(double x, double y, double z, double w) + { coords[0]=x/w; coords[1]=y/w; coords[2]=z/w; } + + double x() const {return coords[0];} + double y() const {return coords[1];} + double z() const {return coords[2];} + + double& operator[](int i) { return coords[i]; } + double operator[](int i) const { return coords[i]; } + + friend std::ostream& operator<<(std::ostream& out, const Custom_point_3& p) + { + out << p.x() << " " << p.y() << " " << p.z(); + return out; + } + + friend std::istream& operator<<(std::istream& in, Custom_point_3& p) + { + in >> p.coords[0] >> p.coords[1] >> p.coords[2]; + return in; + } +}; + +#include +#include +#include +// Halfedge adapters for Polyhedron_3 +#include +#include + +#include + +struct Custom_traits{ + typedef Custom_point_3 Point_3; + struct Plane_3{}; +}; + +typedef CGAL::Polyhedron_3 Polyhedron; + +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef boost::graph_traits::vertex_iterator vertex_iterator; +typedef boost::graph_traits::halfedge_descriptor halfedge_descriptor; +typedef boost::graph_traits::halfedge_iterator halfedge_iterator; + +typedef std::map Internal_vertex_map; +typedef std::map Internal_hedge_map; + +typedef boost::associative_property_map Vertex_index_map; +typedef boost::associative_property_map Hedge_index_map; + +typedef CGAL::Surface_mesh_deformation Surface_mesh_deformation; + +int main() +{ + Polyhedron mesh; + std::ifstream input("data/plane.off"); + + if ( !input || !(input >> mesh) || mesh.empty() ) { + std::cerr<< "Cannot open data/plane.off" << std::endl; + return 1; + } + + // Index maps must contain an index unique per vertex starting from 0 + // to the total number of vertices + Internal_vertex_map internal_vertex_index_map; + Vertex_index_map vertex_index_map(internal_vertex_index_map); + vertex_iterator vb, ve; + std::size_t counter = 0; + for(boost::tie(vb, ve) = vertices(mesh); vb != ve; ++vb, ++counter) { + put(vertex_index_map, *vb, counter); + } + + Internal_hedge_map internal_hedge_index_map; + Hedge_index_map hedge_index_map(internal_hedge_index_map); + counter = 0; + halfedge_iterator eb, ee; + for(boost::tie(eb, ee) = halfedges(mesh); eb != ee; ++eb, ++counter) { + put(hedge_index_map, *eb, counter); + } + + Surface_mesh_deformation deform_mesh(mesh, vertex_index_map, hedge_index_map); + + // Insert the whole mesh as region of interest + boost::tie(vb, ve) = vertices(mesh); + deform_mesh.insert_roi_vertices(vb, ve); + + // Insert two control vertices + vertex_descriptor control_1 = *CGAL::cpp11::next(vb, 213); + vertex_descriptor control_2 = *CGAL::cpp11::next(vb, 157); + deform_mesh.insert_control_vertex(control_1); + deform_mesh.insert_control_vertex(control_2); + + // The definition of the ROI and the control vertices is done, call preprocess + bool is_matrix_factorization_OK = deform_mesh.preprocess(); + if(!is_matrix_factorization_OK){ + std::cerr << "Check documentation of preprocess()" << std::endl; + return 1; + } + + // Use set_target_position() to set the constained position + // of control_1. control_2 remains at the last assigned positions + Surface_mesh_deformation::Point constrained_pos_1(-0.35, 0.40, 0.60); + deform_mesh.set_target_position(control_1, constrained_pos_1); + + // Deform the mesh, the positions of vertices of 'mesh' are updated + deform_mesh.deform(); + // The function deform() can be called several times if the convergence has not been reached yet + deform_mesh.deform(); + + // Set the constained position of control_2 + Surface_mesh_deformation::Point constrained_pos_2(0.55, -0.30, 0.70); + deform_mesh.set_target_position(control_2, constrained_pos_2); + + + // Call the function deform() with one-time parameters: + // iterate 10 times and do not use energy based termination criterion + deform_mesh.deform(10, 0.0); + + std::ofstream output("deform_1.off"); + output << mesh; // save deformed mesh + output.close(); + + // Add another control vertex + vertex_descriptor control_3 = *CGAL::cpp11::next(vb, 92); + deform_mesh.insert_control_vertex(control_3); + + // The prepocessing step is again needed + if(!deform_mesh.preprocess()) { + std::cerr << "Check documentation of preprocess()" << std::endl; + return 1; + } + + Surface_mesh_deformation::Point constrained_pos_3(0.55, 0.30, -0.70); + deform_mesh.set_target_position(control_3, constrained_pos_3); + + deform_mesh.deform(15, 0.0); + + output.open("deform_2.off"); + output << mesh; +} diff -Nru cgal-4.4/examples/Surface_modeling/all_roi_assign_example_with_OpenMesh.cpp cgal-4.5/examples/Surface_modeling/all_roi_assign_example_with_OpenMesh.cpp --- cgal-4.4/examples/Surface_modeling/all_roi_assign_example_with_OpenMesh.cpp 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/examples/Surface_modeling/all_roi_assign_example_with_OpenMesh.cpp 2014-10-04 19:00:10.000000000 +0000 @@ -0,0 +1,83 @@ +#include +#include + +// HalfedgeGraph adapters +#include + +#include + +typedef OpenMesh::PolyMesh_ArrayKernelT Mesh; + +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef boost::graph_traits::vertex_iterator vertex_iterator; +typedef boost::graph_traits::halfedge_iterator halfedge_iterator; + +typedef CGAL::Surface_mesh_deformation Surface_mesh_deformation; + +int main() +{ + Mesh mesh; + OpenMesh::IO::read_mesh(mesh, "data/plane.off"); + + // Create a deformation object + Surface_mesh_deformation deform_mesh(mesh); + + // Definition of the region of interest (use the whole mesh) + vertex_iterator vb,ve; + boost::tie(vb, ve) = vertices(mesh); + deform_mesh.insert_roi_vertices(vb, ve); + + // Select two control vertices ... + vertex_descriptor control_1 = *CGAL::cpp11::next(vb, 213); + vertex_descriptor control_2 = *CGAL::cpp11::next(vb, 157); + + // ... and insert them + deform_mesh.insert_control_vertex(control_1); + deform_mesh.insert_control_vertex(control_2); + + // The definition of the ROI and the control vertices is done, call preprocess + bool is_matrix_factorization_OK = deform_mesh.preprocess(); + if(!is_matrix_factorization_OK){ + std::cerr << "Error in preprocessing, check documentation of preprocess()" << std::endl; + return 1; + } + + // Use set_target_position() to set the constained position + // of control_1. control_2 remains at the last assigned positions + Surface_mesh_deformation::Point constrained_pos_1(-0.35, 0.40, 0.60); + deform_mesh.set_target_position(control_1, constrained_pos_1); + + // Deform the mesh, the positions of vertices of 'mesh' are updated + deform_mesh.deform(); + // The function deform() can be called several times if the convergence has not been reached yet + deform_mesh.deform(); + + // Set the constained position of control_2 + Surface_mesh_deformation::Point constrained_pos_2(0.55, -0.30, 0.70); + deform_mesh.set_target_position(control_2, constrained_pos_2); + + // Call the function deform() with one-time parameters: + // iterate 10 times and do not use energy based termination criterion + deform_mesh.deform(10, 0.0); + + // Save the deformed mesh into a file + OpenMesh::IO::write_mesh(mesh,"deform_1.off"); + + // Add another control vertex which requires another call to preprocess + vertex_descriptor control_3 = *CGAL::cpp11::next(vb, 92); + deform_mesh.insert_control_vertex(control_3); + + // The prepocessing step is again needed + if(!deform_mesh.preprocess()){ + std::cerr << "Error in preprocessing, check documentation of preprocess()" << std::endl; + return 1; + } + + // Deform the mesh + Surface_mesh_deformation::Point constrained_pos_3(0.55, 0.30, -0.70); + deform_mesh.set_target_position(control_3, constrained_pos_3); + + deform_mesh.deform(15, 0.0); + + OpenMesh::IO::write_mesh(mesh,"deform_2.off"); +} diff -Nru cgal-4.4/examples/Surface_modeling/CMakeLists.txt cgal-4.5/examples/Surface_modeling/CMakeLists.txt --- cgal-4.4/examples/Surface_modeling/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/examples/Surface_modeling/CMakeLists.txt 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,52 @@ +# Created by the script cgal_create_cmake_script +# This is the CMake script for compiling a CGAL application. + + +project( Surface_modeling_ ) + +cmake_minimum_required(VERSION 2.6.2) +if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" VERSION_GREATER 2.6) + if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}" VERSION_GREATER 2.8.3) + cmake_policy(VERSION 2.8.4) + else() + cmake_policy(VERSION 2.6) + endif() +endif() + +find_package(CGAL QUIET COMPONENTS Core ) + +if ( CGAL_FOUND ) + + include( ${CGAL_USE_FILE} ) + + find_package(Eigen3 3.1.91) #(requires 3.2.0 or greater) + if (EIGEN3_FOUND) + include( ${EIGEN3_USE_FILE} ) + include( CGAL_CreateSingleSourceCGALProgram ) + + include_directories (BEFORE "../../include") + + create_single_source_cgal_program( "all_roi_assign_example.cpp" ) + create_single_source_cgal_program( "all_roi_assign_example_custom_polyhedron.cpp" ) + create_single_source_cgal_program( "custom_weight_for_edges_example.cpp" ) + create_single_source_cgal_program( "deform_polyhedron_with_custom_pmap_example.cpp" ) + create_single_source_cgal_program( "k_ring_roi_translate_rotate_example.cpp" ) + + find_package( OpenMesh QUIET ) + if ( OpenMesh_FOUND ) + include( UseOpenMesh ) + create_single_source_cgal_program( "all_roi_assign_example_with_OpenMesh.cpp" ) + target_link_libraries( all_roi_assign_example_with_OpenMesh ${OPENMESH_LIBRARIES} ) + else() + message(STATUS "Example that use OpenMesh will not be compiled.") + endif() + + else() + message(STATUS "NOTICE: These examples require the Eigen library, version 3.2 or later and will not be compiled.") + endif() +else() + + message(STATUS "NOTICE: These exmaples require the CGAL library, and will not be compiled.") + +endif() + diff -Nru cgal-4.4/examples/Surface_modeling/custom_weight_for_edges_example.cpp cgal-4.5/examples/Surface_modeling/custom_weight_for_edges_example.cpp --- cgal-4.4/examples/Surface_modeling/custom_weight_for_edges_example.cpp 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/examples/Surface_modeling/custom_weight_for_edges_example.cpp 2014-10-04 19:00:10.000000000 +0000 @@ -0,0 +1,85 @@ +#include +#include +#include +// HalfedgeGraph adapters for Polyhedron_3 +#include +#include + +#include + +#include +#include +#include + +typedef CGAL::Simple_cartesian Kernel; +typedef CGAL::Polyhedron_3 Polyhedron; + +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef boost::graph_traits::vertex_iterator vertex_iterator; +typedef boost::graph_traits::halfedge_descriptor halfedge_descriptor; +typedef boost::graph_traits::halfedge_iterator halfedge_iterator; + +typedef std::map Internal_vertex_map; +typedef std::map Internal_hedge_map; + +typedef boost::associative_property_map Vertex_index_map; +typedef boost::associative_property_map Hedge_index_map; + +// A model of SurfaceModelingWeights using a map of pre-computed weights +struct Weights_from_map +{ + typedef Polyhedron Halfedge_graph; + Weights_from_map(std::map* weight_map) : weight_map(weight_map) + { } + template + double operator()(halfedge_descriptor e, Polyhedron& /*P*/, VertexPointMap /*vpm*/) { + return (*weight_map)[e]; + } + std::map* weight_map; +}; + +typedef CGAL::Surface_mesh_deformation Surface_mesh_deformation; + +int main() +{ + Polyhedron mesh; + std::ifstream input("data/plane.off"); + + if ( !input || !(input >> mesh) || mesh.empty() ) { + std::cerr << "Cannot open data/plane.off" << std::endl; + return 1; + } + + std::map weight_map; + // Store all the weights + halfedge_iterator eb, ee; + for(boost::tie(eb, ee) = halfedges(mesh); eb != ee; ++eb) + { + weight_map[*eb] = 1.0; // store some precomputed weights + } + + // Create and initialize the vertex index map + Internal_vertex_map internal_vertex_index_map; + Vertex_index_map vertex_index_map(internal_vertex_index_map); + vertex_iterator vb, ve; + std::size_t counter = 0; + for(boost::tie(vb, ve) = vertices(mesh); vb != ve; ++vb, ++counter) { + put(vertex_index_map, *vb, counter); + } + + // Create and initialize the halfedge index map + Internal_hedge_map internal_hedge_index_map; + Hedge_index_map hedge_index_map(internal_hedge_index_map); + counter = 0; + for(boost::tie(eb, ee) = halfedges(mesh); eb != ee; ++eb, ++counter) { + put(hedge_index_map, *eb, counter); + } + Surface_mesh_deformation deform_mesh(mesh, + vertex_index_map, + hedge_index_map, + get(CGAL::vertex_point, mesh), + Weights_from_map(&weight_map)); + + // Deform mesh as desired + // ..... +} diff -Nru cgal-4.4/examples/Surface_modeling/data/plane.off cgal-4.5/examples/Surface_modeling/data/plane.off --- cgal-4.4/examples/Surface_modeling/data/plane.off 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/examples/Surface_modeling/data/plane.off 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,2443 @@ +COFF +841 1600 0 +-0.374972 0 -0.249956 192 192 192 255 +-0.249956 0 -0.249956 192 192 192 255 +-0.312464 0 -0.312464 192 192 192 255 +-0.249956 0 -0.374972 192 192 192 255 +-0.374972 0 -0.374972 192 192 192 255 +-0.124942 0 -0.249956 192 192 192 255 +-0.18745 0 -0.312464 192 192 192 255 +-0.124942 0 -0.374972 192 192 192 255 +1.49012e-008 0 -0.249956 192 192 192 255 +-0.0624345 0 -0.312464 192 192 192 255 +1.49012e-008 0 -0.374972 192 192 192 255 +-0.499986 0 -0.249956 192 192 192 255 +-0.437478 0 -0.312464 192 192 192 255 +-0.499986 0 -0.374972 192 192 192 255 +-0.625 0 -0.249956 192 192 192 255 +-0.562492 0 -0.312464 192 192 192 255 +-0.625 0 -0.374972 192 192 192 255 +-0.312464 0 -0.437478 192 192 192 255 +-0.249956 0 -0.499986 192 192 192 255 +-0.374972 0 -0.499986 192 192 192 255 +-0.18745 0 -0.437478 192 192 192 255 +-0.124942 0 -0.499986 192 192 192 255 +-0.0624345 0 -0.437478 192 192 192 255 +1.49012e-008 0 -0.499986 192 192 192 255 +-0.437478 0 -0.437478 192 192 192 255 +-0.499986 0 -0.499986 192 192 192 255 +-0.562492 0 -0.437478 192 192 192 255 +-0.625 0 -0.499986 192 192 192 255 +-0.312464 0 -0.562492 192 192 192 255 +-0.249956 0 -0.625 192 192 192 255 +-0.374972 0 -0.625 192 192 192 255 +-0.18745 0 -0.562492 192 192 192 255 +-0.124942 0 -0.625 192 192 192 255 +-0.0624345 0 -0.562492 192 192 192 255 +1.49012e-008 0 -0.625 192 192 192 255 +-0.437478 0 -0.562492 192 192 192 255 +-0.499986 0 -0.625 192 192 192 255 +-0.562492 0 -0.562492 192 192 192 255 +-0.625 0 -0.625 192 192 192 255 +-0.374972 0 8.03719e-008 192 192 192 255 +-0.249956 0 8.03719e-008 192 192 192 255 +-0.312464 0 -0.0624344 192 192 192 255 +-0.249956 0 -0.124942 192 192 192 255 +-0.374972 0 -0.124942 192 192 192 255 +-0.124942 0 -3.56804e-005 192 192 192 255 +-0.18745 0 -0.0624344 192 192 192 255 +-0.124942 0 -0.124942 192 192 192 255 +1.49012e-008 0 8.03719e-008 192 192 192 255 +-0.0624345 0 -0.0624344 192 192 192 255 +1.49012e-008 0 -0.124942 192 192 192 255 +-0.499986 -0 8.03719e-008 192 192 192 255 +-0.437478 0 -0.0624344 192 192 192 255 +-0.499986 0 -0.124942 192 192 192 255 +-0.625 0 8.03719e-008 192 192 192 255 +-0.562492 0 -0.0624344 192 192 192 255 +-0.625 0 -0.124942 192 192 192 255 +-0.312464 0 -0.18745 192 192 192 255 +-0.18745 0 -0.18745 192 192 192 255 +-0.0624345 0 -0.18745 192 192 192 255 +-0.437478 0 -0.18745 192 192 192 255 +-0.562492 0 -0.18745 192 192 192 255 +0.249956 0 -0.249956 192 192 192 255 +0.374972 0 -0.249956 192 192 192 255 +0.312464 0 -0.312464 192 192 192 255 +0.374972 0 -0.374972 192 192 192 255 +0.249956 0 -0.374972 192 192 192 255 +0.499986 0 -0.249956 192 192 192 255 +0.437478 0 -0.312464 192 192 192 255 +0.499986 0 -0.374972 192 192 192 255 +0.625 0 -0.249956 192 192 192 255 +0.562492 0 -0.312464 192 192 192 255 +0.625 0 -0.374972 192 192 192 255 +0.124942 -0 -0.249956 192 192 192 255 +0.18745 0 -0.312464 192 192 192 255 +0.124942 0 -0.374972 192 192 192 255 +0.0624345 0 -0.312464 192 192 192 255 +0.312464 0 -0.437478 192 192 192 255 +0.374972 0 -0.499986 192 192 192 255 +0.249956 0 -0.499986 192 192 192 255 +0.437478 0 -0.437478 192 192 192 255 +0.499986 0 -0.499986 192 192 192 255 +0.562492 0 -0.437478 192 192 192 255 +0.625 0 -0.499986 192 192 192 255 +0.18745 0 -0.437478 192 192 192 255 +0.124942 0 -0.499986 192 192 192 255 +0.0624345 0 -0.437478 192 192 192 255 +0.312464 0 -0.562492 192 192 192 255 +0.374972 0 -0.625 192 192 192 255 +0.249956 0 -0.625 192 192 192 255 +0.437478 0 -0.562492 192 192 192 255 +0.499986 0 -0.625 192 192 192 255 +0.562492 0 -0.562492 192 192 192 255 +0.625 0 -0.625 192 192 192 255 +0.18745 0 -0.562492 192 192 192 255 +0.124942 0 -0.625 192 192 192 255 +0.0624345 0 -0.562492 192 192 192 255 +0.249956 0 8.03719e-008 192 192 192 255 +0.374972 0 8.03719e-008 192 192 192 255 +0.312464 0 -0.0624344 192 192 192 255 +0.374972 0 -0.124942 192 192 192 255 +0.249956 0 -0.124942 192 192 192 255 +0.499986 0 8.03719e-008 192 192 192 255 +0.437478 0 -0.0624344 192 192 192 255 +0.499986 0 -0.124942 192 192 192 255 +0.625 0 8.03719e-008 192 192 192 255 +0.562492 0 -0.0624344 192 192 192 255 +0.625 0 -0.124942 192 192 192 255 +0.124942 0 8.03719e-008 192 192 192 255 +0.18745 0 -0.0624344 192 192 192 255 +0.124942 0 -0.124942 192 192 192 255 +0.0624345 0 -0.0624344 192 192 192 255 +0.312464 0 -0.18745 192 192 192 255 +0.437478 0 -0.18745 192 192 192 255 +0.562492 0 -0.18745 192 192 192 255 +0.18745 0 -0.18745 192 192 192 255 +0.0624345 0 -0.18745 192 192 192 255 +0.249956 0 0.374972 192 192 192 255 +0.374972 0 0.374972 192 192 192 255 +0.312464 0 0.312464 192 192 192 255 +0.374972 0 0.249956 192 192 192 255 +0.249956 0 0.249956 192 192 192 255 +0.499986 0 0.374972 192 192 192 255 +0.437478 0 0.312464 192 192 192 255 +0.499986 0 0.249956 192 192 192 255 +0.625 0 0.374972 192 192 192 255 +0.562492 0 0.312464 192 192 192 255 +0.625 0 0.249956 192 192 192 255 +0.124942 0 0.374972 192 192 192 255 +0.18745 0 0.312464 192 192 192 255 +0.124942 0 0.249956 192 192 192 255 +1.49012e-008 0 0.374972 192 192 192 255 +0.0624345 0 0.312464 192 192 192 255 +1.49012e-008 0 0.249956 192 192 192 255 +0.312464 0 0.18745 192 192 192 255 +0.374972 0 0.124942 192 192 192 255 +0.249956 0 0.124942 192 192 192 255 +0.437478 0 0.18745 192 192 192 255 +0.499986 0 0.124942 192 192 192 255 +0.562492 0 0.18745 192 192 192 255 +0.625 0 0.124942 192 192 192 255 +0.18745 0 0.18745 192 192 192 255 +0.124942 0 0.124942 192 192 192 255 +0.0624345 0 0.18745 192 192 192 255 +1.49012e-008 0 0.124942 192 192 192 255 +0.312464 0 0.0624346 192 192 192 255 +0.437478 0 0.0624346 192 192 192 255 +0.562492 0 0.0624346 192 192 192 255 +0.18745 0 0.0624346 192 192 192 255 +0.0624345 0 0.0624346 192 192 192 255 +0.249956 0 0.625 192 192 192 255 +0.374972 0 0.625 192 192 192 255 +0.312464 0 0.562492 192 192 192 255 +0.374972 0 0.499986 192 192 192 255 +0.249956 0 0.499986 192 192 192 255 +0.499986 0 0.625 192 192 192 255 +0.437478 0 0.562492 192 192 192 255 +0.499986 0 0.499986 192 192 192 255 +0.625 0 0.625 192 192 192 255 +0.562492 0 0.562492 192 192 192 255 +0.625 0 0.499986 192 192 192 255 +0.124942 0 0.625 192 192 192 255 +0.18745 0 0.562492 192 192 192 255 +0.124942 0 0.499986 192 192 192 255 +1.49012e-008 0 0.625 192 192 192 255 +0.0624345 0 0.562492 192 192 192 255 +1.49012e-008 0 0.499986 192 192 192 255 +0.312464 0 0.437478 192 192 192 255 +0.437478 0 0.437478 192 192 192 255 +0.562492 0 0.437478 192 192 192 255 +0.18745 0 0.437478 192 192 192 255 +0.0624345 0 0.437478 192 192 192 255 +-0.374972 0 0.374972 192 192 192 255 +-0.249956 0 0.374972 192 192 192 255 +-0.312464 0 0.312464 192 192 192 255 +-0.249956 0 0.249956 192 192 192 255 +-0.374972 0 0.249956 192 192 192 255 +-0.124942 0 0.374972 192 192 192 255 +-0.18745 0 0.312464 192 192 192 255 +-0.124942 0 0.249956 192 192 192 255 +-0.0624345 0 0.312464 192 192 192 255 +-0.499986 0 0.374972 192 192 192 255 +-0.437478 0 0.312464 192 192 192 255 +-0.499986 0 0.249956 192 192 192 255 +-0.625 0 0.374972 192 192 192 255 +-0.562492 0 0.312464 192 192 192 255 +-0.625 0 0.249956 192 192 192 255 +-0.312464 0 0.18745 192 192 192 255 +-0.249956 0 0.124942 192 192 192 255 +-0.374972 0 0.124942 192 192 192 255 +-0.18745 0 0.18745 192 192 192 255 +-0.124942 0 0.124942 192 192 192 255 +-0.0624345 0 0.18745 192 192 192 255 +-0.437478 0 0.18745 192 192 192 255 +-0.499986 0 0.124942 192 192 192 255 +-0.562492 0 0.18745 192 192 192 255 +-0.625 0 0.124942 192 192 192 255 +-0.312464 0 0.0624346 192 192 192 255 +-0.18745 0 0.0624346 192 192 192 255 +-0.0624345 0 0.0624346 192 192 192 255 +-0.437478 0 0.0624346 192 192 192 255 +-0.562492 0 0.0624346 192 192 192 255 +-0.374972 0 0.625 192 192 192 255 +-0.249956 0 0.625 192 192 192 255 +-0.312464 0 0.562492 192 192 192 255 +-0.249956 0 0.499986 192 192 192 255 +-0.374972 0 0.499986 192 192 192 255 +-0.124942 0 0.625 192 192 192 255 +-0.18745 0 0.562492 192 192 192 255 +-0.124942 0 0.499986 192 192 192 255 +-0.0624345 0 0.562492 192 192 192 255 +-0.499986 0 0.625 192 192 192 255 +-0.437478 0 0.562492 192 192 192 255 +-0.499986 0 0.499986 192 192 192 255 +-0.625 0 0.625 192 192 192 255 +-0.562492 0 0.562492 192 192 192 255 +-0.625 0 0.499986 192 192 192 255 +-0.312464 0 0.437478 192 192 192 255 +-0.18745 0 0.437478 192 192 192 255 +-0.0624345 0 0.437478 192 192 192 255 +-0.437478 0 0.437478 192 192 192 255 +-0.562492 0 0.437478 192 192 192 255 +-0.312464 0 -0.249956 192 192 192 255 +-0.343718 0 -0.28121 192 192 192 255 +-0.28121 0 -0.28121 192 192 192 255 +-0.249956 0 -0.312464 192 192 192 255 +-0.28121 0 -0.343718 192 192 192 255 +-0.312464 0 -0.374972 192 192 192 255 +-0.343718 0 -0.343718 192 192 192 255 +-0.374972 0 -0.312464 192 192 192 255 +-0.187449 0 -0.249956 192 192 192 255 +-0.218703 0 -0.28121 192 192 192 255 +-0.156196 0 -0.28121 192 192 192 255 +-0.124942 0 -0.312464 192 192 192 255 +-0.156196 0 -0.343718 192 192 192 255 +-0.187449 0 -0.374972 192 192 192 255 +-0.218703 0 -0.343718 192 192 192 255 +-0.0624712 0 -0.249956 192 192 192 255 +-0.0936884 0 -0.28121 192 192 192 255 +-0.0312172 0 -0.28121 192 192 192 255 +1.49012e-008 0 -0.312464 192 192 192 255 +-0.0312172 0 -0.343718 192 192 192 255 +-0.0624712 0 -0.374972 192 192 192 255 +-0.0936884 0 -0.343718 192 192 192 255 +-0.437479 0 -0.249956 192 192 192 255 +-0.468732 0 -0.28121 192 192 192 255 +-0.406225 0 -0.28121 192 192 192 255 +-0.406225 0 -0.343718 192 192 192 255 +-0.437479 0 -0.374972 192 192 192 255 +-0.468732 0 -0.343718 192 192 192 255 +-0.499986 0 -0.312464 192 192 192 255 +-0.562493 0 -0.249956 192 192 192 255 +-0.593746 0 -0.28121 192 192 192 255 +-0.531239 0 -0.28121 192 192 192 255 +-0.531239 0 -0.343718 192 192 192 255 +-0.562493 0 -0.374972 192 192 192 255 +-0.593746 0 -0.343718 192 192 192 255 +-0.625 0 -0.312464 192 192 192 255 +-0.343718 0 -0.406225 192 192 192 255 +-0.28121 0 -0.406225 192 192 192 255 +-0.249956 0 -0.437479 192 192 192 255 +-0.28121 0 -0.468732 192 192 192 255 +-0.312464 0 -0.499986 192 192 192 255 +-0.343718 0 -0.468732 192 192 192 255 +-0.374972 0 -0.437479 192 192 192 255 +-0.218703 0 -0.406225 192 192 192 255 +-0.156196 0 -0.406225 192 192 192 255 +-0.124942 0 -0.437479 192 192 192 255 +-0.156196 0 -0.468732 192 192 192 255 +-0.187449 0 -0.499986 192 192 192 255 +-0.218703 0 -0.468732 192 192 192 255 +-0.0936884 0 -0.406225 192 192 192 255 +-0.0312172 0 -0.406225 192 192 192 255 +1.49012e-008 0 -0.437479 192 192 192 255 +-0.0312172 0 -0.468732 192 192 192 255 +-0.0624712 0 -0.499986 192 192 192 255 +-0.0936884 0 -0.468732 192 192 192 255 +-0.468732 0 -0.406225 192 192 192 255 +-0.406225 0 -0.406225 192 192 192 255 +-0.406225 0 -0.468732 192 192 192 255 +-0.437479 0 -0.499986 192 192 192 255 +-0.468732 0 -0.468732 192 192 192 255 +-0.499986 0 -0.437479 192 192 192 255 +-0.593746 0 -0.406225 192 192 192 255 +-0.531239 0 -0.406225 192 192 192 255 +-0.531239 0 -0.468732 192 192 192 255 +-0.562493 0 -0.499986 192 192 192 255 +-0.593746 0 -0.468732 192 192 192 255 +-0.625 0 -0.437479 192 192 192 255 +-0.343718 0 -0.531239 192 192 192 255 +-0.28121 0 -0.531239 192 192 192 255 +-0.249956 0 -0.562493 192 192 192 255 +-0.28121 0 -0.593746 192 192 192 255 +-0.312464 0 -0.625 192 192 192 255 +-0.343718 0 -0.593746 192 192 192 255 +-0.374972 0 -0.562493 192 192 192 255 +-0.218703 0 -0.531239 192 192 192 255 +-0.156196 0 -0.531239 192 192 192 255 +-0.124942 0 -0.562493 192 192 192 255 +-0.156196 0 -0.593746 192 192 192 255 +-0.187449 0 -0.625 192 192 192 255 +-0.218703 0 -0.593746 192 192 192 255 +-0.0936884 0 -0.531239 192 192 192 255 +-0.0312172 0 -0.531239 192 192 192 255 +1.49012e-008 0 -0.562493 192 192 192 255 +-0.0312172 0 -0.593746 192 192 192 255 +-0.0624712 0 -0.625 192 192 192 255 +-0.0936884 0 -0.593746 192 192 192 255 +-0.468732 0 -0.531239 192 192 192 255 +-0.406225 0 -0.531239 192 192 192 255 +-0.406225 0 -0.593746 192 192 192 255 +-0.437479 0 -0.625 192 192 192 255 +-0.468732 0 -0.593746 192 192 192 255 +-0.499986 0 -0.562493 192 192 192 255 +-0.593746 0 -0.531239 192 192 192 255 +-0.531239 0 -0.531239 192 192 192 255 +-0.531239 0 -0.593746 192 192 192 255 +-0.562493 0 -0.625 192 192 192 255 +-0.593746 0 -0.593746 192 192 192 255 +-0.625 0 -0.562493 192 192 192 255 +-0.312464 0 8.03719e-008 192 192 192 255 +-0.343718 0 -0.0312172 192 192 192 255 +-0.28121 0 -0.0312172 192 192 192 255 +-0.249956 0 -0.0624711 192 192 192 255 +-0.28121 0 -0.0936884 192 192 192 255 +-0.312464 0 -0.124942 192 192 192 255 +-0.343718 0 -0.0936884 192 192 192 255 +-0.374972 0 -0.0624711 192 192 192 255 +-0.187449 0 -1.78e-005 192 192 192 255 +-0.218703 0 -0.0312172 192 192 192 255 +-0.156196 0 -0.0312351 192 192 192 255 +-0.124942 0 -0.062489 192 192 192 255 +-0.156196 0 -0.0936884 192 192 192 255 +-0.187449 0 -0.124942 192 192 192 255 +-0.218703 0 -0.0936884 192 192 192 255 +-0.0624712 0 -1.78e-005 192 192 192 255 +-0.0936884 0 -0.0312351 192 192 192 255 +-0.0312172 0 -0.0312172 192 192 192 255 +1.49012e-008 0 -0.0624711 192 192 192 255 +-0.0312172 0 -0.0936884 192 192 192 255 +-0.0624712 0 -0.124942 192 192 192 255 +-0.0936884 0 -0.0936884 192 192 192 255 +-0.437479 0 8.03719e-008 192 192 192 255 +-0.468732 0 -0.0312172 192 192 192 255 +-0.406225 0 -0.0312172 192 192 192 255 +-0.406225 0 -0.0936884 192 192 192 255 +-0.437479 0 -0.124942 192 192 192 255 +-0.468732 0 -0.0936884 192 192 192 255 +-0.499986 0 -0.0624711 192 192 192 255 +-0.562493 0 8.03719e-008 192 192 192 255 +-0.593746 0 -0.0312172 192 192 192 255 +-0.531239 0 -0.0312172 192 192 192 255 +-0.531239 0 -0.0936884 192 192 192 255 +-0.562493 0 -0.124942 192 192 192 255 +-0.593746 0 -0.0936884 192 192 192 255 +-0.625 0 -0.0624711 192 192 192 255 +-0.343718 0 -0.156196 192 192 192 255 +-0.28121 0 -0.156196 192 192 192 255 +-0.249956 0 -0.187449 192 192 192 255 +-0.28121 0 -0.218703 192 192 192 255 +-0.343718 0 -0.218703 192 192 192 255 +-0.374972 0 -0.187449 192 192 192 255 +-0.218703 0 -0.156196 192 192 192 255 +-0.156196 0 -0.156196 192 192 192 255 +-0.124942 0 -0.187449 192 192 192 255 +-0.156196 0 -0.218703 192 192 192 255 +-0.218703 0 -0.218703 192 192 192 255 +-0.0936884 0 -0.156196 192 192 192 255 +-0.0312172 0 -0.156196 192 192 192 255 +1.49012e-008 0 -0.187449 192 192 192 255 +-0.0312172 0 -0.218703 192 192 192 255 +-0.0936884 0 -0.218703 192 192 192 255 +-0.468732 0 -0.156196 192 192 192 255 +-0.406225 0 -0.156196 192 192 192 255 +-0.406225 0 -0.218703 192 192 192 255 +-0.468732 0 -0.218703 192 192 192 255 +-0.499986 0 -0.187449 192 192 192 255 +-0.593746 0 -0.156196 192 192 192 255 +-0.531239 0 -0.156196 192 192 192 255 +-0.531239 0 -0.218703 192 192 192 255 +-0.593746 0 -0.218703 192 192 192 255 +-0.625 0 -0.187449 192 192 192 255 +0.312464 0 -0.249956 192 192 192 255 +0.28121 0 -0.28121 192 192 192 255 +0.343718 0 -0.28121 192 192 192 255 +0.374972 0 -0.312464 192 192 192 255 +0.343718 0 -0.343718 192 192 192 255 +0.312464 0 -0.374972 192 192 192 255 +0.28121 0 -0.343718 192 192 192 255 +0.249956 0 -0.312464 192 192 192 255 +0.437479 0 -0.249956 192 192 192 255 +0.406225 0 -0.28121 192 192 192 255 +0.468732 0 -0.28121 192 192 192 255 +0.499986 0 -0.312464 192 192 192 255 +0.468732 0 -0.343718 192 192 192 255 +0.437479 0 -0.374972 192 192 192 255 +0.406225 0 -0.343718 192 192 192 255 +0.562493 0 -0.249956 192 192 192 255 +0.531239 0 -0.28121 192 192 192 255 +0.593746 0 -0.28121 192 192 192 255 +0.625 0 -0.312464 192 192 192 255 +0.593746 0 -0.343718 192 192 192 255 +0.562493 0 -0.374972 192 192 192 255 +0.531239 0 -0.343718 192 192 192 255 +0.187449 0 -0.249956 192 192 192 255 +0.156196 0 -0.28121 192 192 192 255 +0.218703 0 -0.28121 192 192 192 255 +0.218703 0 -0.343718 192 192 192 255 +0.187449 0 -0.374972 192 192 192 255 +0.156196 0 -0.343718 192 192 192 255 +0.124942 0 -0.312464 192 192 192 255 +0.0624712 0 -0.249956 192 192 192 255 +0.0312173 0 -0.28121 192 192 192 255 +0.0936885 0 -0.28121 192 192 192 255 +0.0936885 0 -0.343718 192 192 192 255 +0.0624712 0 -0.374972 192 192 192 255 +0.0312173 0 -0.343718 192 192 192 255 +0.28121 0 -0.406225 192 192 192 255 +0.343718 0 -0.406225 192 192 192 255 +0.374972 0 -0.437479 192 192 192 255 +0.343718 0 -0.468732 192 192 192 255 +0.312464 0 -0.499986 192 192 192 255 +0.28121 0 -0.468732 192 192 192 255 +0.249956 0 -0.437479 192 192 192 255 +0.406225 0 -0.406225 192 192 192 255 +0.468732 0 -0.406225 192 192 192 255 +0.499986 0 -0.437479 192 192 192 255 +0.468732 0 -0.468732 192 192 192 255 +0.437479 0 -0.499986 192 192 192 255 +0.406225 0 -0.468732 192 192 192 255 +0.531239 0 -0.406225 192 192 192 255 +0.593746 0 -0.406225 192 192 192 255 +0.625 0 -0.437479 192 192 192 255 +0.593746 0 -0.468732 192 192 192 255 +0.562493 0 -0.499986 192 192 192 255 +0.531239 0 -0.468732 192 192 192 255 +0.156196 0 -0.406225 192 192 192 255 +0.218703 0 -0.406225 192 192 192 255 +0.218703 0 -0.468732 192 192 192 255 +0.187449 0 -0.499986 192 192 192 255 +0.156196 0 -0.468732 192 192 192 255 +0.124942 0 -0.437479 192 192 192 255 +0.0312173 0 -0.406225 192 192 192 255 +0.0936885 0 -0.406225 192 192 192 255 +0.0936885 0 -0.468732 192 192 192 255 +0.0624712 0 -0.499986 192 192 192 255 +0.0312173 0 -0.468732 192 192 192 255 +0.28121 0 -0.531239 192 192 192 255 +0.343718 0 -0.531239 192 192 192 255 +0.374972 0 -0.562493 192 192 192 255 +0.343718 0 -0.593746 192 192 192 255 +0.312464 0 -0.625 192 192 192 255 +0.28121 0 -0.593746 192 192 192 255 +0.249956 0 -0.562493 192 192 192 255 +0.406225 0 -0.531239 192 192 192 255 +0.468732 0 -0.531239 192 192 192 255 +0.499986 0 -0.562493 192 192 192 255 +0.468732 0 -0.593746 192 192 192 255 +0.437479 0 -0.625 192 192 192 255 +0.406225 0 -0.593746 192 192 192 255 +0.531239 0 -0.531239 192 192 192 255 +0.593746 0 -0.531239 192 192 192 255 +0.625 0 -0.562493 192 192 192 255 +0.593746 0 -0.593746 192 192 192 255 +0.562493 0 -0.625 192 192 192 255 +0.531239 0 -0.593746 192 192 192 255 +0.156196 0 -0.531239 192 192 192 255 +0.218703 0 -0.531239 192 192 192 255 +0.218703 0 -0.593746 192 192 192 255 +0.187449 0 -0.625 192 192 192 255 +0.156196 0 -0.593746 192 192 192 255 +0.124942 0 -0.562493 192 192 192 255 +0.0312173 0 -0.531239 192 192 192 255 +0.0936885 0 -0.531239 192 192 192 255 +0.0936885 0 -0.593746 192 192 192 255 +0.0624712 0 -0.625 192 192 192 255 +0.0312173 0 -0.593746 192 192 192 255 +0.312464 0 8.03719e-008 192 192 192 255 +0.28121 0 -0.0312172 192 192 192 255 +0.343718 0 -0.0312172 192 192 192 255 +0.374972 0 -0.0624711 192 192 192 255 +0.343718 0 -0.0936884 192 192 192 255 +0.312464 0 -0.124942 192 192 192 255 +0.28121 0 -0.0936884 192 192 192 255 +0.249956 0 -0.0624711 192 192 192 255 +0.437479 0 8.03719e-008 192 192 192 255 +0.406225 0 -0.0312172 192 192 192 255 +0.468732 0 -0.0312172 192 192 192 255 +0.499986 0 -0.0624711 192 192 192 255 +0.468732 0 -0.0936884 192 192 192 255 +0.437479 0 -0.124942 192 192 192 255 +0.406225 0 -0.0936884 192 192 192 255 +0.562493 0 8.03719e-008 192 192 192 255 +0.531239 0 -0.0312172 192 192 192 255 +0.593746 0 -0.0312172 192 192 192 255 +0.625 0 -0.0624711 192 192 192 255 +0.593746 0 -0.0936884 192 192 192 255 +0.562493 0 -0.124942 192 192 192 255 +0.531239 0 -0.0936884 192 192 192 255 +0.187449 0 8.03719e-008 192 192 192 255 +0.156196 0 -0.0312172 192 192 192 255 +0.218703 0 -0.0312172 192 192 192 255 +0.218703 0 -0.0936884 192 192 192 255 +0.187449 0 -0.124942 192 192 192 255 +0.156196 0 -0.0936884 192 192 192 255 +0.124942 0 -0.0624711 192 192 192 255 +0.0624712 0 8.03719e-008 192 192 192 255 +0.0312173 0 -0.0312172 192 192 192 255 +0.0936885 0 -0.0312172 192 192 192 255 +0.0936885 0 -0.0936884 192 192 192 255 +0.0624712 0 -0.124942 192 192 192 255 +0.0312173 0 -0.0936884 192 192 192 255 +0.28121 0 -0.156196 192 192 192 255 +0.343718 0 -0.156196 192 192 192 255 +0.374972 0 -0.187449 192 192 192 255 +0.343718 0 -0.218703 192 192 192 255 +0.28121 0 -0.218703 192 192 192 255 +0.249956 0 -0.187449 192 192 192 255 +0.406225 0 -0.156196 192 192 192 255 +0.468732 0 -0.156196 192 192 192 255 +0.499986 0 -0.187449 192 192 192 255 +0.468732 0 -0.218703 192 192 192 255 +0.406225 0 -0.218703 192 192 192 255 +0.531239 0 -0.156196 192 192 192 255 +0.593746 0 -0.156196 192 192 192 255 +0.625 0 -0.187449 192 192 192 255 +0.593746 0 -0.218703 192 192 192 255 +0.531239 0 -0.218703 192 192 192 255 +0.156196 0 -0.156196 192 192 192 255 +0.218703 0 -0.156196 192 192 192 255 +0.218703 0 -0.218703 192 192 192 255 +0.156196 0 -0.218703 192 192 192 255 +0.124942 0 -0.187449 192 192 192 255 +0.0312173 0 -0.156196 192 192 192 255 +0.0936885 0 -0.156196 192 192 192 255 +0.0936885 0 -0.218703 192 192 192 255 +0.0312173 0 -0.218703 192 192 192 255 +0.312464 0 0.374972 192 192 192 255 +0.28121 0 0.343718 192 192 192 255 +0.343718 0 0.343718 192 192 192 255 +0.374972 0 0.312464 192 192 192 255 +0.343718 0 0.28121 192 192 192 255 +0.312464 0 0.249956 192 192 192 255 +0.28121 0 0.28121 192 192 192 255 +0.249956 0 0.312464 192 192 192 255 +0.437479 0 0.374972 192 192 192 255 +0.406225 0 0.343718 192 192 192 255 +0.468732 0 0.343718 192 192 192 255 +0.499986 0 0.312464 192 192 192 255 +0.468732 0 0.28121 192 192 192 255 +0.437479 0 0.249956 192 192 192 255 +0.406225 0 0.28121 192 192 192 255 +0.562493 0 0.374972 192 192 192 255 +0.531239 0 0.343718 192 192 192 255 +0.593746 0 0.343718 192 192 192 255 +0.625 0 0.312464 192 192 192 255 +0.593746 0 0.28121 192 192 192 255 +0.562493 0 0.249956 192 192 192 255 +0.531239 0 0.28121 192 192 192 255 +0.187449 0 0.374972 192 192 192 255 +0.156196 0 0.343718 192 192 192 255 +0.218703 0 0.343718 192 192 192 255 +0.218703 0 0.28121 192 192 192 255 +0.187449 0 0.249956 192 192 192 255 +0.156196 0 0.28121 192 192 192 255 +0.124942 0 0.312464 192 192 192 255 +0.0624712 0 0.374972 192 192 192 255 +0.0312173 0 0.343718 192 192 192 255 +0.0936885 0 0.343718 192 192 192 255 +0.0936885 0 0.28121 192 192 192 255 +0.0624712 0 0.249956 192 192 192 255 +0.0312173 0 0.28121 192 192 192 255 +1.49012e-008 0 0.312464 192 192 192 255 +0.28121 0 0.218703 192 192 192 255 +0.343718 0 0.218703 192 192 192 255 +0.374972 0 0.187449 192 192 192 255 +0.343718 0 0.156196 192 192 192 255 +0.312464 0 0.124942 192 192 192 255 +0.28121 0 0.156196 192 192 192 255 +0.249956 0 0.187449 192 192 192 255 +0.406225 0 0.218703 192 192 192 255 +0.468732 0 0.218703 192 192 192 255 +0.499986 0 0.187449 192 192 192 255 +0.468732 0 0.156196 192 192 192 255 +0.437479 0 0.124942 192 192 192 255 +0.406225 0 0.156196 192 192 192 255 +0.531239 0 0.218703 192 192 192 255 +0.593746 0 0.218703 192 192 192 255 +0.625 0 0.187449 192 192 192 255 +0.593746 0 0.156196 192 192 192 255 +0.562493 0 0.124942 192 192 192 255 +0.531239 0 0.156196 192 192 192 255 +0.156196 0 0.218703 192 192 192 255 +0.218703 0 0.218703 192 192 192 255 +0.218703 0 0.156196 192 192 192 255 +0.187449 0 0.124942 192 192 192 255 +0.156196 0 0.156196 192 192 192 255 +0.124942 0 0.187449 192 192 192 255 +0.0312173 0 0.218703 192 192 192 255 +0.0936885 0 0.218703 192 192 192 255 +0.0936885 0 0.156196 192 192 192 255 +0.0624712 0 0.124942 192 192 192 255 +0.0312173 0 0.156196 192 192 192 255 +1.49012e-008 0 0.187449 192 192 192 255 +0.28121 0 0.0936885 192 192 192 255 +0.343718 0 0.0936885 192 192 192 255 +0.374972 0 0.0624713 192 192 192 255 +0.343718 0 0.0312173 192 192 192 255 +0.28121 0 0.0312173 192 192 192 255 +0.249956 0 0.0624713 192 192 192 255 +0.406225 0 0.0936885 192 192 192 255 +0.468732 0 0.0936885 192 192 192 255 +0.499986 0 0.0624713 192 192 192 255 +0.468732 0 0.0312173 192 192 192 255 +0.406225 0 0.0312173 192 192 192 255 +0.531239 0 0.0936885 192 192 192 255 +0.593746 0 0.0936885 192 192 192 255 +0.625 0 0.0624713 192 192 192 255 +0.593746 0 0.0312173 192 192 192 255 +0.531239 0 0.0312173 192 192 192 255 +0.156196 0 0.0936885 192 192 192 255 +0.218703 0 0.0936885 192 192 192 255 +0.218703 0 0.0312173 192 192 192 255 +0.156196 0 0.0312173 192 192 192 255 +0.124942 0 0.0624713 192 192 192 255 +0.0312173 0 0.0936885 192 192 192 255 +0.0936885 0 0.0936885 192 192 192 255 +0.0936885 0 0.0312173 192 192 192 255 +0.0312173 0 0.0312173 192 192 192 255 +1.49012e-008 0 0.0624713 192 192 192 255 +0.312464 0 0.625 192 192 192 255 +0.28121 0 0.593746 192 192 192 255 +0.343718 0 0.593746 192 192 192 255 +0.374972 0 0.562493 192 192 192 255 +0.343718 0 0.531239 192 192 192 255 +0.312464 0 0.499986 192 192 192 255 +0.28121 0 0.531239 192 192 192 255 +0.249956 0 0.562493 192 192 192 255 +0.437479 0 0.625 192 192 192 255 +0.406225 0 0.593746 192 192 192 255 +0.468732 0 0.593746 192 192 192 255 +0.499986 0 0.562493 192 192 192 255 +0.468732 0 0.531239 192 192 192 255 +0.437479 0 0.499986 192 192 192 255 +0.406225 0 0.531239 192 192 192 255 +0.562493 0 0.625 192 192 192 255 +0.531239 0 0.593746 192 192 192 255 +0.593746 0 0.593746 192 192 192 255 +0.625 0 0.562493 192 192 192 255 +0.593746 0 0.531239 192 192 192 255 +0.562493 0 0.499986 192 192 192 255 +0.531239 0 0.531239 192 192 192 255 +0.187449 0 0.625 192 192 192 255 +0.156196 0 0.593746 192 192 192 255 +0.218703 0 0.593746 192 192 192 255 +0.218703 0 0.531239 192 192 192 255 +0.187449 0 0.499986 192 192 192 255 +0.156196 0 0.531239 192 192 192 255 +0.124942 0 0.562493 192 192 192 255 +0.0624712 0 0.625 192 192 192 255 +0.0312173 0 0.593746 192 192 192 255 +0.0936885 0 0.593746 192 192 192 255 +0.0936885 0 0.531239 192 192 192 255 +0.0624712 0 0.499986 192 192 192 255 +0.0312173 0 0.531239 192 192 192 255 +1.49012e-008 0 0.562493 192 192 192 255 +0.28121 0 0.468732 192 192 192 255 +0.343718 0 0.468732 192 192 192 255 +0.374972 0 0.437479 192 192 192 255 +0.343718 0 0.406225 192 192 192 255 +0.28121 0 0.406225 192 192 192 255 +0.249956 0 0.437479 192 192 192 255 +0.406225 0 0.468732 192 192 192 255 +0.468732 0 0.468732 192 192 192 255 +0.499986 0 0.437479 192 192 192 255 +0.468732 0 0.406225 192 192 192 255 +0.406225 0 0.406225 192 192 192 255 +0.531239 0 0.468732 192 192 192 255 +0.593746 0 0.468732 192 192 192 255 +0.625 0 0.437479 192 192 192 255 +0.593746 0 0.406225 192 192 192 255 +0.531239 0 0.406225 192 192 192 255 +0.156196 0 0.468732 192 192 192 255 +0.218703 0 0.468732 192 192 192 255 +0.218703 0 0.406225 192 192 192 255 +0.156196 0 0.406225 192 192 192 255 +0.124942 0 0.437479 192 192 192 255 +0.0312173 0 0.468732 192 192 192 255 +0.0936885 0 0.468732 192 192 192 255 +0.0936885 0 0.406225 192 192 192 255 +0.0312173 0 0.406225 192 192 192 255 +1.49012e-008 0 0.437479 192 192 192 255 +-0.312464 0 0.374972 192 192 192 255 +-0.343718 0 0.343718 192 192 192 255 +-0.28121 0 0.343718 192 192 192 255 +-0.249956 0 0.312464 192 192 192 255 +-0.28121 0 0.28121 192 192 192 255 +-0.312464 0 0.249956 192 192 192 255 +-0.343718 0 0.28121 192 192 192 255 +-0.374972 0 0.312464 192 192 192 255 +-0.187449 0 0.374972 192 192 192 255 +-0.218703 0 0.343718 192 192 192 255 +-0.156196 0 0.343718 192 192 192 255 +-0.124942 0 0.312464 192 192 192 255 +-0.156196 0 0.28121 192 192 192 255 +-0.187449 0 0.249956 192 192 192 255 +-0.218703 0 0.28121 192 192 192 255 +-0.0624712 0 0.374972 192 192 192 255 +-0.0936884 0 0.343718 192 192 192 255 +-0.0312172 0 0.343718 192 192 192 255 +-0.0312172 0 0.28121 192 192 192 255 +-0.0624712 0 0.249956 192 192 192 255 +-0.0936884 0 0.28121 192 192 192 255 +-0.437479 0 0.374972 192 192 192 255 +-0.468732 0 0.343718 192 192 192 255 +-0.406225 0 0.343718 192 192 192 255 +-0.406225 0 0.28121 192 192 192 255 +-0.437479 0 0.249956 192 192 192 255 +-0.468732 0 0.28121 192 192 192 255 +-0.499986 0 0.312464 192 192 192 255 +-0.562493 0 0.374972 192 192 192 255 +-0.593746 0 0.343718 192 192 192 255 +-0.531239 0 0.343718 192 192 192 255 +-0.531239 0 0.28121 192 192 192 255 +-0.562493 0 0.249956 192 192 192 255 +-0.593746 0 0.28121 192 192 192 255 +-0.625 0 0.312464 192 192 192 255 +-0.343718 0 0.218703 192 192 192 255 +-0.28121 0 0.218703 192 192 192 255 +-0.249956 0 0.187449 192 192 192 255 +-0.28121 0 0.156196 192 192 192 255 +-0.312464 0 0.124942 192 192 192 255 +-0.343718 0 0.156196 192 192 192 255 +-0.374972 0 0.187449 192 192 192 255 +-0.218703 0 0.218703 192 192 192 255 +-0.156196 0 0.218703 192 192 192 255 +-0.124942 0 0.187449 192 192 192 255 +-0.156196 0 0.156196 192 192 192 255 +-0.187449 0 0.124942 192 192 192 255 +-0.218703 0 0.156196 192 192 192 255 +-0.0936884 0 0.218703 192 192 192 255 +-0.0312172 0 0.218703 192 192 192 255 +-0.0312172 0 0.156196 192 192 192 255 +-0.0624712 0 0.124942 192 192 192 255 +-0.0936884 0 0.156196 192 192 192 255 +-0.468732 0 0.218703 192 192 192 255 +-0.406225 0 0.218703 192 192 192 255 +-0.406225 0 0.156196 192 192 192 255 +-0.437479 0 0.124942 192 192 192 255 +-0.468732 0 0.156196 192 192 192 255 +-0.499986 0 0.187449 192 192 192 255 +-0.593746 0 0.218703 192 192 192 255 +-0.531239 0 0.218703 192 192 192 255 +-0.531239 0 0.156196 192 192 192 255 +-0.562493 0 0.124942 192 192 192 255 +-0.593746 0 0.156196 192 192 192 255 +-0.625 0 0.187449 192 192 192 255 +-0.343718 0 0.0936885 192 192 192 255 +-0.28121 0 0.0936885 192 192 192 255 +-0.249956 0 0.0624713 192 192 192 255 +-0.28121 0 0.0312173 192 192 192 255 +-0.343718 0 0.0312173 192 192 192 255 +-0.374972 0 0.0624713 192 192 192 255 +-0.218703 0 0.0936885 192 192 192 255 +-0.156196 0 0.0936885 192 192 192 255 +-0.124942 0 0.0624534 192 192 192 255 +-0.156196 0 0.0311995 192 192 192 255 +-0.218703 0 0.0312173 192 192 192 255 +-0.0936884 0 0.0936885 192 192 192 255 +-0.0312172 0 0.0936885 192 192 192 255 +-0.0312172 0 0.0312173 192 192 192 255 +-0.0936884 0 0.0311995 192 192 192 255 +-0.468732 0 0.0936885 192 192 192 255 +-0.406225 0 0.0936885 192 192 192 255 +-0.406225 0 0.0312173 192 192 192 255 +-0.468732 0 0.0312173 192 192 192 255 +-0.499986 0 0.0624713 192 192 192 255 +-0.593746 0 0.0936885 192 192 192 255 +-0.531239 0 0.0936885 192 192 192 255 +-0.531239 0 0.0312173 192 192 192 255 +-0.593746 0 0.0312173 192 192 192 255 +-0.625 0 0.0624713 192 192 192 255 +-0.312464 0 0.625 192 192 192 255 +-0.343718 0 0.593746 192 192 192 255 +-0.28121 0 0.593746 192 192 192 255 +-0.249956 0 0.562493 192 192 192 255 +-0.28121 0 0.531239 192 192 192 255 +-0.312464 0 0.499986 192 192 192 255 +-0.343718 0 0.531239 192 192 192 255 +-0.374972 0 0.562493 192 192 192 255 +-0.187449 0 0.625 192 192 192 255 +-0.218703 0 0.593746 192 192 192 255 +-0.156196 0 0.593746 192 192 192 255 +-0.124942 0 0.562493 192 192 192 255 +-0.156196 0 0.531239 192 192 192 255 +-0.187449 0 0.499986 192 192 192 255 +-0.218703 0 0.531239 192 192 192 255 +-0.0624712 0 0.625 192 192 192 255 +-0.0936884 0 0.593746 192 192 192 255 +-0.0312172 0 0.593746 192 192 192 255 +-0.0312172 0 0.531239 192 192 192 255 +-0.0624712 0 0.499986 192 192 192 255 +-0.0936884 0 0.531239 192 192 192 255 +-0.437479 0 0.625 192 192 192 255 +-0.468732 0 0.593746 192 192 192 255 +-0.406225 0 0.593746 192 192 192 255 +-0.406225 0 0.531239 192 192 192 255 +-0.437479 0 0.499986 192 192 192 255 +-0.468732 0 0.531239 192 192 192 255 +-0.499986 0 0.562493 192 192 192 255 +-0.562493 0 0.625 192 192 192 255 +-0.593746 0 0.593746 192 192 192 255 +-0.531239 0 0.593746 192 192 192 255 +-0.531239 0 0.531239 192 192 192 255 +-0.562493 0 0.499986 192 192 192 255 +-0.593746 0 0.531239 192 192 192 255 +-0.625 0 0.562493 192 192 192 255 +-0.343718 0 0.468732 192 192 192 255 +-0.28121 0 0.468732 192 192 192 255 +-0.249956 0 0.437479 192 192 192 255 +-0.28121 0 0.406225 192 192 192 255 +-0.343718 0 0.406225 192 192 192 255 +-0.374972 0 0.437479 192 192 192 255 +-0.218703 0 0.468732 192 192 192 255 +-0.156196 0 0.468732 192 192 192 255 +-0.124942 0 0.437479 192 192 192 255 +-0.156196 0 0.406225 192 192 192 255 +-0.218703 0 0.406225 192 192 192 255 +-0.0936884 0 0.468732 192 192 192 255 +-0.0312172 0 0.468732 192 192 192 255 +-0.0312172 0 0.406225 192 192 192 255 +-0.0936884 0 0.406225 192 192 192 255 +-0.468732 0 0.468732 192 192 192 255 +-0.406225 0 0.468732 192 192 192 255 +-0.406225 0 0.406225 192 192 192 255 +-0.468732 0 0.406225 192 192 192 255 +-0.499986 0 0.437479 192 192 192 255 +-0.593746 0 0.468732 192 192 192 255 +-0.531239 0 0.468732 192 192 192 255 +-0.531239 0 0.406225 192 192 192 255 +-0.593746 0 0.406225 192 192 192 255 +-0.625 0 0.437479 192 192 192 255 +3 0 221 222 +3 221 1 223 +3 221 223 222 +3 222 223 2 +3 1 224 223 +3 224 3 225 +3 224 225 223 +3 223 225 2 +3 3 226 225 +3 226 4 227 +3 226 227 225 +3 225 227 2 +3 4 228 227 +3 228 0 222 +3 228 222 227 +3 227 222 2 +3 1 229 230 +3 229 5 231 +3 229 231 230 +3 230 231 6 +3 5 232 231 +3 232 7 233 +3 232 233 231 +3 231 233 6 +3 7 234 233 +3 234 3 235 +3 234 235 233 +3 233 235 6 +3 3 224 235 +3 224 1 230 +3 224 230 235 +3 235 230 6 +3 5 236 237 +3 236 8 238 +3 236 238 237 +3 237 238 9 +3 8 239 238 +3 239 10 240 +3 239 240 238 +3 238 240 9 +3 10 241 240 +3 241 7 242 +3 241 242 240 +3 240 242 9 +3 7 232 242 +3 232 5 237 +3 232 237 242 +3 242 237 9 +3 11 243 244 +3 243 0 245 +3 243 245 244 +3 244 245 12 +3 0 228 245 +3 228 4 246 +3 228 246 245 +3 245 246 12 +3 4 247 246 +3 247 13 248 +3 247 248 246 +3 246 248 12 +3 13 249 248 +3 249 11 244 +3 249 244 248 +3 248 244 12 +3 14 250 251 +3 250 11 252 +3 250 252 251 +3 251 252 15 +3 11 249 252 +3 249 13 253 +3 249 253 252 +3 252 253 15 +3 13 254 253 +3 254 16 255 +3 254 255 253 +3 253 255 15 +3 16 256 255 +3 256 14 251 +3 256 251 255 +3 255 251 15 +3 4 226 257 +3 226 3 258 +3 226 258 257 +3 257 258 17 +3 3 259 258 +3 259 18 260 +3 259 260 258 +3 258 260 17 +3 18 261 260 +3 261 19 262 +3 261 262 260 +3 260 262 17 +3 19 263 262 +3 263 4 257 +3 263 257 262 +3 262 257 17 +3 3 234 264 +3 234 7 265 +3 234 265 264 +3 264 265 20 +3 7 266 265 +3 266 21 267 +3 266 267 265 +3 265 267 20 +3 21 268 267 +3 268 18 269 +3 268 269 267 +3 267 269 20 +3 18 259 269 +3 259 3 264 +3 259 264 269 +3 269 264 20 +3 7 241 270 +3 241 10 271 +3 241 271 270 +3 270 271 22 +3 10 272 271 +3 272 23 273 +3 272 273 271 +3 271 273 22 +3 23 274 273 +3 274 21 275 +3 274 275 273 +3 273 275 22 +3 21 266 275 +3 266 7 270 +3 266 270 275 +3 275 270 22 +3 13 247 276 +3 247 4 277 +3 247 277 276 +3 276 277 24 +3 4 263 277 +3 263 19 278 +3 263 278 277 +3 277 278 24 +3 19 279 278 +3 279 25 280 +3 279 280 278 +3 278 280 24 +3 25 281 280 +3 281 13 276 +3 281 276 280 +3 280 276 24 +3 16 254 282 +3 254 13 283 +3 254 283 282 +3 282 283 26 +3 13 281 283 +3 281 25 284 +3 281 284 283 +3 283 284 26 +3 25 285 284 +3 285 27 286 +3 285 286 284 +3 284 286 26 +3 27 287 286 +3 287 16 282 +3 287 282 286 +3 286 282 26 +3 19 261 288 +3 261 18 289 +3 261 289 288 +3 288 289 28 +3 18 290 289 +3 290 29 291 +3 290 291 289 +3 289 291 28 +3 29 292 291 +3 292 30 293 +3 292 293 291 +3 291 293 28 +3 30 294 293 +3 294 19 288 +3 294 288 293 +3 293 288 28 +3 18 268 295 +3 268 21 296 +3 268 296 295 +3 295 296 31 +3 21 297 296 +3 297 32 298 +3 297 298 296 +3 296 298 31 +3 32 299 298 +3 299 29 300 +3 299 300 298 +3 298 300 31 +3 29 290 300 +3 290 18 295 +3 290 295 300 +3 300 295 31 +3 21 274 301 +3 274 23 302 +3 274 302 301 +3 301 302 33 +3 23 303 302 +3 303 34 304 +3 303 304 302 +3 302 304 33 +3 34 305 304 +3 305 32 306 +3 305 306 304 +3 304 306 33 +3 32 297 306 +3 297 21 301 +3 297 301 306 +3 306 301 33 +3 25 279 307 +3 279 19 308 +3 279 308 307 +3 307 308 35 +3 19 294 308 +3 294 30 309 +3 294 309 308 +3 308 309 35 +3 30 310 309 +3 310 36 311 +3 310 311 309 +3 309 311 35 +3 36 312 311 +3 312 25 307 +3 312 307 311 +3 311 307 35 +3 27 285 313 +3 285 25 314 +3 285 314 313 +3 313 314 37 +3 25 312 314 +3 312 36 315 +3 312 315 314 +3 314 315 37 +3 36 316 315 +3 316 38 317 +3 316 317 315 +3 315 317 37 +3 38 318 317 +3 318 27 313 +3 318 313 317 +3 317 313 37 +3 39 319 320 +3 319 40 321 +3 319 321 320 +3 320 321 41 +3 40 322 321 +3 322 42 323 +3 322 323 321 +3 321 323 41 +3 42 324 323 +3 324 43 325 +3 324 325 323 +3 323 325 41 +3 43 326 325 +3 326 39 320 +3 326 320 325 +3 325 320 41 +3 40 327 328 +3 327 44 329 +3 327 329 328 +3 328 329 45 +3 44 330 329 +3 330 46 331 +3 330 331 329 +3 329 331 45 +3 46 332 331 +3 332 42 333 +3 332 333 331 +3 331 333 45 +3 42 322 333 +3 322 40 328 +3 322 328 333 +3 333 328 45 +3 44 334 335 +3 334 47 336 +3 334 336 335 +3 335 336 48 +3 47 337 336 +3 337 49 338 +3 337 338 336 +3 336 338 48 +3 49 339 338 +3 339 46 340 +3 339 340 338 +3 338 340 48 +3 46 330 340 +3 330 44 335 +3 330 335 340 +3 340 335 48 +3 50 341 342 +3 341 39 343 +3 341 343 342 +3 342 343 51 +3 39 326 343 +3 326 43 344 +3 326 344 343 +3 343 344 51 +3 43 345 344 +3 345 52 346 +3 345 346 344 +3 344 346 51 +3 52 347 346 +3 347 50 342 +3 347 342 346 +3 346 342 51 +3 53 348 349 +3 348 50 350 +3 348 350 349 +3 349 350 54 +3 50 347 350 +3 347 52 351 +3 347 351 350 +3 350 351 54 +3 52 352 351 +3 352 55 353 +3 352 353 351 +3 351 353 54 +3 55 354 353 +3 354 53 349 +3 354 349 353 +3 353 349 54 +3 43 324 355 +3 324 42 356 +3 324 356 355 +3 355 356 56 +3 42 357 356 +3 357 1 358 +3 357 358 356 +3 356 358 56 +3 1 221 358 +3 221 0 359 +3 221 359 358 +3 358 359 56 +3 0 360 359 +3 360 43 355 +3 360 355 359 +3 359 355 56 +3 42 332 361 +3 332 46 362 +3 332 362 361 +3 361 362 57 +3 46 363 362 +3 363 5 364 +3 363 364 362 +3 362 364 57 +3 5 229 364 +3 229 1 365 +3 229 365 364 +3 364 365 57 +3 1 357 365 +3 357 42 361 +3 357 361 365 +3 365 361 57 +3 46 339 366 +3 339 49 367 +3 339 367 366 +3 366 367 58 +3 49 368 367 +3 368 8 369 +3 368 369 367 +3 367 369 58 +3 8 236 369 +3 236 5 370 +3 236 370 369 +3 369 370 58 +3 5 363 370 +3 363 46 366 +3 363 366 370 +3 370 366 58 +3 52 345 371 +3 345 43 372 +3 345 372 371 +3 371 372 59 +3 43 360 372 +3 360 0 373 +3 360 373 372 +3 372 373 59 +3 0 243 373 +3 243 11 374 +3 243 374 373 +3 373 374 59 +3 11 375 374 +3 375 52 371 +3 375 371 374 +3 374 371 59 +3 55 352 376 +3 352 52 377 +3 352 377 376 +3 376 377 60 +3 52 375 377 +3 375 11 378 +3 375 378 377 +3 377 378 60 +3 11 250 378 +3 250 14 379 +3 250 379 378 +3 378 379 60 +3 14 380 379 +3 380 55 376 +3 380 376 379 +3 379 376 60 +3 61 381 382 +3 381 62 383 +3 381 383 382 +3 382 383 63 +3 62 384 383 +3 384 64 385 +3 384 385 383 +3 383 385 63 +3 64 386 385 +3 386 65 387 +3 386 387 385 +3 385 387 63 +3 65 388 387 +3 388 61 382 +3 388 382 387 +3 387 382 63 +3 62 389 390 +3 389 66 391 +3 389 391 390 +3 390 391 67 +3 66 392 391 +3 392 68 393 +3 392 393 391 +3 391 393 67 +3 68 394 393 +3 394 64 395 +3 394 395 393 +3 393 395 67 +3 64 384 395 +3 384 62 390 +3 384 390 395 +3 395 390 67 +3 66 396 397 +3 396 69 398 +3 396 398 397 +3 397 398 70 +3 69 399 398 +3 399 71 400 +3 399 400 398 +3 398 400 70 +3 71 401 400 +3 401 68 402 +3 401 402 400 +3 400 402 70 +3 68 392 402 +3 392 66 397 +3 392 397 402 +3 402 397 70 +3 72 403 404 +3 403 61 405 +3 403 405 404 +3 404 405 73 +3 61 388 405 +3 388 65 406 +3 388 406 405 +3 405 406 73 +3 65 407 406 +3 407 74 408 +3 407 408 406 +3 406 408 73 +3 74 409 408 +3 409 72 404 +3 409 404 408 +3 408 404 73 +3 8 410 411 +3 410 72 412 +3 410 412 411 +3 411 412 75 +3 72 409 412 +3 409 74 413 +3 409 413 412 +3 412 413 75 +3 74 414 413 +3 414 10 415 +3 414 415 413 +3 413 415 75 +3 10 239 415 +3 239 8 411 +3 239 411 415 +3 415 411 75 +3 65 386 416 +3 386 64 417 +3 386 417 416 +3 416 417 76 +3 64 418 417 +3 418 77 419 +3 418 419 417 +3 417 419 76 +3 77 420 419 +3 420 78 421 +3 420 421 419 +3 419 421 76 +3 78 422 421 +3 422 65 416 +3 422 416 421 +3 421 416 76 +3 64 394 423 +3 394 68 424 +3 394 424 423 +3 423 424 79 +3 68 425 424 +3 425 80 426 +3 425 426 424 +3 424 426 79 +3 80 427 426 +3 427 77 428 +3 427 428 426 +3 426 428 79 +3 77 418 428 +3 418 64 423 +3 418 423 428 +3 428 423 79 +3 68 401 429 +3 401 71 430 +3 401 430 429 +3 429 430 81 +3 71 431 430 +3 431 82 432 +3 431 432 430 +3 430 432 81 +3 82 433 432 +3 433 80 434 +3 433 434 432 +3 432 434 81 +3 80 425 434 +3 425 68 429 +3 425 429 434 +3 434 429 81 +3 74 407 435 +3 407 65 436 +3 407 436 435 +3 435 436 83 +3 65 422 436 +3 422 78 437 +3 422 437 436 +3 436 437 83 +3 78 438 437 +3 438 84 439 +3 438 439 437 +3 437 439 83 +3 84 440 439 +3 440 74 435 +3 440 435 439 +3 439 435 83 +3 10 414 441 +3 414 74 442 +3 414 442 441 +3 441 442 85 +3 74 440 442 +3 440 84 443 +3 440 443 442 +3 442 443 85 +3 84 444 443 +3 444 23 445 +3 444 445 443 +3 443 445 85 +3 23 272 445 +3 272 10 441 +3 272 441 445 +3 445 441 85 +3 78 420 446 +3 420 77 447 +3 420 447 446 +3 446 447 86 +3 77 448 447 +3 448 87 449 +3 448 449 447 +3 447 449 86 +3 87 450 449 +3 450 88 451 +3 450 451 449 +3 449 451 86 +3 88 452 451 +3 452 78 446 +3 452 446 451 +3 451 446 86 +3 77 427 453 +3 427 80 454 +3 427 454 453 +3 453 454 89 +3 80 455 454 +3 455 90 456 +3 455 456 454 +3 454 456 89 +3 90 457 456 +3 457 87 458 +3 457 458 456 +3 456 458 89 +3 87 448 458 +3 448 77 453 +3 448 453 458 +3 458 453 89 +3 80 433 459 +3 433 82 460 +3 433 460 459 +3 459 460 91 +3 82 461 460 +3 461 92 462 +3 461 462 460 +3 460 462 91 +3 92 463 462 +3 463 90 464 +3 463 464 462 +3 462 464 91 +3 90 455 464 +3 455 80 459 +3 455 459 464 +3 464 459 91 +3 84 438 465 +3 438 78 466 +3 438 466 465 +3 465 466 93 +3 78 452 466 +3 452 88 467 +3 452 467 466 +3 466 467 93 +3 88 468 467 +3 468 94 469 +3 468 469 467 +3 467 469 93 +3 94 470 469 +3 470 84 465 +3 470 465 469 +3 469 465 93 +3 23 444 471 +3 444 84 472 +3 444 472 471 +3 471 472 95 +3 84 470 472 +3 470 94 473 +3 470 473 472 +3 472 473 95 +3 94 474 473 +3 474 34 475 +3 474 475 473 +3 473 475 95 +3 34 303 475 +3 303 23 471 +3 303 471 475 +3 475 471 95 +3 96 476 477 +3 476 97 478 +3 476 478 477 +3 477 478 98 +3 97 479 478 +3 479 99 480 +3 479 480 478 +3 478 480 98 +3 99 481 480 +3 481 100 482 +3 481 482 480 +3 480 482 98 +3 100 483 482 +3 483 96 477 +3 483 477 482 +3 482 477 98 +3 97 484 485 +3 484 101 486 +3 484 486 485 +3 485 486 102 +3 101 487 486 +3 487 103 488 +3 487 488 486 +3 486 488 102 +3 103 489 488 +3 489 99 490 +3 489 490 488 +3 488 490 102 +3 99 479 490 +3 479 97 485 +3 479 485 490 +3 490 485 102 +3 101 491 492 +3 491 104 493 +3 491 493 492 +3 492 493 105 +3 104 494 493 +3 494 106 495 +3 494 495 493 +3 493 495 105 +3 106 496 495 +3 496 103 497 +3 496 497 495 +3 495 497 105 +3 103 487 497 +3 487 101 492 +3 487 492 497 +3 497 492 105 +3 107 498 499 +3 498 96 500 +3 498 500 499 +3 499 500 108 +3 96 483 500 +3 483 100 501 +3 483 501 500 +3 500 501 108 +3 100 502 501 +3 502 109 503 +3 502 503 501 +3 501 503 108 +3 109 504 503 +3 504 107 499 +3 504 499 503 +3 503 499 108 +3 47 505 506 +3 505 107 507 +3 505 507 506 +3 506 507 110 +3 107 504 507 +3 504 109 508 +3 504 508 507 +3 507 508 110 +3 109 509 508 +3 509 49 510 +3 509 510 508 +3 508 510 110 +3 49 337 510 +3 337 47 506 +3 337 506 510 +3 510 506 110 +3 100 481 511 +3 481 99 512 +3 481 512 511 +3 511 512 111 +3 99 513 512 +3 513 62 514 +3 513 514 512 +3 512 514 111 +3 62 381 514 +3 381 61 515 +3 381 515 514 +3 514 515 111 +3 61 516 515 +3 516 100 511 +3 516 511 515 +3 515 511 111 +3 99 489 517 +3 489 103 518 +3 489 518 517 +3 517 518 112 +3 103 519 518 +3 519 66 520 +3 519 520 518 +3 518 520 112 +3 66 389 520 +3 389 62 521 +3 389 521 520 +3 520 521 112 +3 62 513 521 +3 513 99 517 +3 513 517 521 +3 521 517 112 +3 103 496 522 +3 496 106 523 +3 496 523 522 +3 522 523 113 +3 106 524 523 +3 524 69 525 +3 524 525 523 +3 523 525 113 +3 69 396 525 +3 396 66 526 +3 396 526 525 +3 525 526 113 +3 66 519 526 +3 519 103 522 +3 519 522 526 +3 526 522 113 +3 109 502 527 +3 502 100 528 +3 502 528 527 +3 527 528 114 +3 100 516 528 +3 516 61 529 +3 516 529 528 +3 528 529 114 +3 61 403 529 +3 403 72 530 +3 403 530 529 +3 529 530 114 +3 72 531 530 +3 531 109 527 +3 531 527 530 +3 530 527 114 +3 49 509 532 +3 509 109 533 +3 509 533 532 +3 532 533 115 +3 109 531 533 +3 531 72 534 +3 531 534 533 +3 533 534 115 +3 72 410 534 +3 410 8 535 +3 410 535 534 +3 534 535 115 +3 8 368 535 +3 368 49 532 +3 368 532 535 +3 535 532 115 +3 116 536 537 +3 536 117 538 +3 536 538 537 +3 537 538 118 +3 117 539 538 +3 539 119 540 +3 539 540 538 +3 538 540 118 +3 119 541 540 +3 541 120 542 +3 541 542 540 +3 540 542 118 +3 120 543 542 +3 543 116 537 +3 543 537 542 +3 542 537 118 +3 117 544 545 +3 544 121 546 +3 544 546 545 +3 545 546 122 +3 121 547 546 +3 547 123 548 +3 547 548 546 +3 546 548 122 +3 123 549 548 +3 549 119 550 +3 549 550 548 +3 548 550 122 +3 119 539 550 +3 539 117 545 +3 539 545 550 +3 550 545 122 +3 121 551 552 +3 551 124 553 +3 551 553 552 +3 552 553 125 +3 124 554 553 +3 554 126 555 +3 554 555 553 +3 553 555 125 +3 126 556 555 +3 556 123 557 +3 556 557 555 +3 555 557 125 +3 123 547 557 +3 547 121 552 +3 547 552 557 +3 557 552 125 +3 127 558 559 +3 558 116 560 +3 558 560 559 +3 559 560 128 +3 116 543 560 +3 543 120 561 +3 543 561 560 +3 560 561 128 +3 120 562 561 +3 562 129 563 +3 562 563 561 +3 561 563 128 +3 129 564 563 +3 564 127 559 +3 564 559 563 +3 563 559 128 +3 130 565 566 +3 565 127 567 +3 565 567 566 +3 566 567 131 +3 127 564 567 +3 564 129 568 +3 564 568 567 +3 567 568 131 +3 129 569 568 +3 569 132 570 +3 569 570 568 +3 568 570 131 +3 132 571 570 +3 571 130 566 +3 571 566 570 +3 570 566 131 +3 120 541 572 +3 541 119 573 +3 541 573 572 +3 572 573 133 +3 119 574 573 +3 574 134 575 +3 574 575 573 +3 573 575 133 +3 134 576 575 +3 576 135 577 +3 576 577 575 +3 575 577 133 +3 135 578 577 +3 578 120 572 +3 578 572 577 +3 577 572 133 +3 119 549 579 +3 549 123 580 +3 549 580 579 +3 579 580 136 +3 123 581 580 +3 581 137 582 +3 581 582 580 +3 580 582 136 +3 137 583 582 +3 583 134 584 +3 583 584 582 +3 582 584 136 +3 134 574 584 +3 574 119 579 +3 574 579 584 +3 584 579 136 +3 123 556 585 +3 556 126 586 +3 556 586 585 +3 585 586 138 +3 126 587 586 +3 587 139 588 +3 587 588 586 +3 586 588 138 +3 139 589 588 +3 589 137 590 +3 589 590 588 +3 588 590 138 +3 137 581 590 +3 581 123 585 +3 581 585 590 +3 590 585 138 +3 129 562 591 +3 562 120 592 +3 562 592 591 +3 591 592 140 +3 120 578 592 +3 578 135 593 +3 578 593 592 +3 592 593 140 +3 135 594 593 +3 594 141 595 +3 594 595 593 +3 593 595 140 +3 141 596 595 +3 596 129 591 +3 596 591 595 +3 595 591 140 +3 132 569 597 +3 569 129 598 +3 569 598 597 +3 597 598 142 +3 129 596 598 +3 596 141 599 +3 596 599 598 +3 598 599 142 +3 141 600 599 +3 600 143 601 +3 600 601 599 +3 599 601 142 +3 143 602 601 +3 602 132 597 +3 602 597 601 +3 601 597 142 +3 135 576 603 +3 576 134 604 +3 576 604 603 +3 603 604 144 +3 134 605 604 +3 605 97 606 +3 605 606 604 +3 604 606 144 +3 97 476 606 +3 476 96 607 +3 476 607 606 +3 606 607 144 +3 96 608 607 +3 608 135 603 +3 608 603 607 +3 607 603 144 +3 134 583 609 +3 583 137 610 +3 583 610 609 +3 609 610 145 +3 137 611 610 +3 611 101 612 +3 611 612 610 +3 610 612 145 +3 101 484 612 +3 484 97 613 +3 484 613 612 +3 612 613 145 +3 97 605 613 +3 605 134 609 +3 605 609 613 +3 613 609 145 +3 137 589 614 +3 589 139 615 +3 589 615 614 +3 614 615 146 +3 139 616 615 +3 616 104 617 +3 616 617 615 +3 615 617 146 +3 104 491 617 +3 491 101 618 +3 491 618 617 +3 617 618 146 +3 101 611 618 +3 611 137 614 +3 611 614 618 +3 618 614 146 +3 141 594 619 +3 594 135 620 +3 594 620 619 +3 619 620 147 +3 135 608 620 +3 608 96 621 +3 608 621 620 +3 620 621 147 +3 96 498 621 +3 498 107 622 +3 498 622 621 +3 621 622 147 +3 107 623 622 +3 623 141 619 +3 623 619 622 +3 622 619 147 +3 143 600 624 +3 600 141 625 +3 600 625 624 +3 624 625 148 +3 141 623 625 +3 623 107 626 +3 623 626 625 +3 625 626 148 +3 107 505 626 +3 505 47 627 +3 505 627 626 +3 626 627 148 +3 47 628 627 +3 628 143 624 +3 628 624 627 +3 627 624 148 +3 149 629 630 +3 629 150 631 +3 629 631 630 +3 630 631 151 +3 150 632 631 +3 632 152 633 +3 632 633 631 +3 631 633 151 +3 152 634 633 +3 634 153 635 +3 634 635 633 +3 633 635 151 +3 153 636 635 +3 636 149 630 +3 636 630 635 +3 635 630 151 +3 150 637 638 +3 637 154 639 +3 637 639 638 +3 638 639 155 +3 154 640 639 +3 640 156 641 +3 640 641 639 +3 639 641 155 +3 156 642 641 +3 642 152 643 +3 642 643 641 +3 641 643 155 +3 152 632 643 +3 632 150 638 +3 632 638 643 +3 643 638 155 +3 154 644 645 +3 644 157 646 +3 644 646 645 +3 645 646 158 +3 157 647 646 +3 647 159 648 +3 647 648 646 +3 646 648 158 +3 159 649 648 +3 649 156 650 +3 649 650 648 +3 648 650 158 +3 156 640 650 +3 640 154 645 +3 640 645 650 +3 650 645 158 +3 160 651 652 +3 651 149 653 +3 651 653 652 +3 652 653 161 +3 149 636 653 +3 636 153 654 +3 636 654 653 +3 653 654 161 +3 153 655 654 +3 655 162 656 +3 655 656 654 +3 654 656 161 +3 162 657 656 +3 657 160 652 +3 657 652 656 +3 656 652 161 +3 163 658 659 +3 658 160 660 +3 658 660 659 +3 659 660 164 +3 160 657 660 +3 657 162 661 +3 657 661 660 +3 660 661 164 +3 162 662 661 +3 662 165 663 +3 662 663 661 +3 661 663 164 +3 165 664 663 +3 664 163 659 +3 664 659 663 +3 663 659 164 +3 153 634 665 +3 634 152 666 +3 634 666 665 +3 665 666 166 +3 152 667 666 +3 667 117 668 +3 667 668 666 +3 666 668 166 +3 117 536 668 +3 536 116 669 +3 536 669 668 +3 668 669 166 +3 116 670 669 +3 670 153 665 +3 670 665 669 +3 669 665 166 +3 152 642 671 +3 642 156 672 +3 642 672 671 +3 671 672 167 +3 156 673 672 +3 673 121 674 +3 673 674 672 +3 672 674 167 +3 121 544 674 +3 544 117 675 +3 544 675 674 +3 674 675 167 +3 117 667 675 +3 667 152 671 +3 667 671 675 +3 675 671 167 +3 156 649 676 +3 649 159 677 +3 649 677 676 +3 676 677 168 +3 159 678 677 +3 678 124 679 +3 678 679 677 +3 677 679 168 +3 124 551 679 +3 551 121 680 +3 551 680 679 +3 679 680 168 +3 121 673 680 +3 673 156 676 +3 673 676 680 +3 680 676 168 +3 162 655 681 +3 655 153 682 +3 655 682 681 +3 681 682 169 +3 153 670 682 +3 670 116 683 +3 670 683 682 +3 682 683 169 +3 116 558 683 +3 558 127 684 +3 558 684 683 +3 683 684 169 +3 127 685 684 +3 685 162 681 +3 685 681 684 +3 684 681 169 +3 165 662 686 +3 662 162 687 +3 662 687 686 +3 686 687 170 +3 162 685 687 +3 685 127 688 +3 685 688 687 +3 687 688 170 +3 127 565 688 +3 565 130 689 +3 565 689 688 +3 688 689 170 +3 130 690 689 +3 690 165 686 +3 690 686 689 +3 689 686 170 +3 171 691 692 +3 691 172 693 +3 691 693 692 +3 692 693 173 +3 172 694 693 +3 694 174 695 +3 694 695 693 +3 693 695 173 +3 174 696 695 +3 696 175 697 +3 696 697 695 +3 695 697 173 +3 175 698 697 +3 698 171 692 +3 698 692 697 +3 697 692 173 +3 172 699 700 +3 699 176 701 +3 699 701 700 +3 700 701 177 +3 176 702 701 +3 702 178 703 +3 702 703 701 +3 701 703 177 +3 178 704 703 +3 704 174 705 +3 704 705 703 +3 703 705 177 +3 174 694 705 +3 694 172 700 +3 694 700 705 +3 705 700 177 +3 176 706 707 +3 706 130 708 +3 706 708 707 +3 707 708 179 +3 130 571 708 +3 571 132 709 +3 571 709 708 +3 708 709 179 +3 132 710 709 +3 710 178 711 +3 710 711 709 +3 709 711 179 +3 178 702 711 +3 702 176 707 +3 702 707 711 +3 711 707 179 +3 180 712 713 +3 712 171 714 +3 712 714 713 +3 713 714 181 +3 171 698 714 +3 698 175 715 +3 698 715 714 +3 714 715 181 +3 175 716 715 +3 716 182 717 +3 716 717 715 +3 715 717 181 +3 182 718 717 +3 718 180 713 +3 718 713 717 +3 717 713 181 +3 183 719 720 +3 719 180 721 +3 719 721 720 +3 720 721 184 +3 180 718 721 +3 718 182 722 +3 718 722 721 +3 721 722 184 +3 182 723 722 +3 723 185 724 +3 723 724 722 +3 722 724 184 +3 185 725 724 +3 725 183 720 +3 725 720 724 +3 724 720 184 +3 175 696 726 +3 696 174 727 +3 696 727 726 +3 726 727 186 +3 174 728 727 +3 728 187 729 +3 728 729 727 +3 727 729 186 +3 187 730 729 +3 730 188 731 +3 730 731 729 +3 729 731 186 +3 188 732 731 +3 732 175 726 +3 732 726 731 +3 731 726 186 +3 174 704 733 +3 704 178 734 +3 704 734 733 +3 733 734 189 +3 178 735 734 +3 735 190 736 +3 735 736 734 +3 734 736 189 +3 190 737 736 +3 737 187 738 +3 737 738 736 +3 736 738 189 +3 187 728 738 +3 728 174 733 +3 728 733 738 +3 738 733 189 +3 178 710 739 +3 710 132 740 +3 710 740 739 +3 739 740 191 +3 132 602 740 +3 602 143 741 +3 602 741 740 +3 740 741 191 +3 143 742 741 +3 742 190 743 +3 742 743 741 +3 741 743 191 +3 190 735 743 +3 735 178 739 +3 735 739 743 +3 743 739 191 +3 182 716 744 +3 716 175 745 +3 716 745 744 +3 744 745 192 +3 175 732 745 +3 732 188 746 +3 732 746 745 +3 745 746 192 +3 188 747 746 +3 747 193 748 +3 747 748 746 +3 746 748 192 +3 193 749 748 +3 749 182 744 +3 749 744 748 +3 748 744 192 +3 185 723 750 +3 723 182 751 +3 723 751 750 +3 750 751 194 +3 182 749 751 +3 749 193 752 +3 749 752 751 +3 751 752 194 +3 193 753 752 +3 753 195 754 +3 753 754 752 +3 752 754 194 +3 195 755 754 +3 755 185 750 +3 755 750 754 +3 754 750 194 +3 188 730 756 +3 730 187 757 +3 730 757 756 +3 756 757 196 +3 187 758 757 +3 758 40 759 +3 758 759 757 +3 757 759 196 +3 40 319 759 +3 319 39 760 +3 319 760 759 +3 759 760 196 +3 39 761 760 +3 761 188 756 +3 761 756 760 +3 760 756 196 +3 187 737 762 +3 737 190 763 +3 737 763 762 +3 762 763 197 +3 190 764 763 +3 764 44 765 +3 764 765 763 +3 763 765 197 +3 44 327 765 +3 327 40 766 +3 327 766 765 +3 765 766 197 +3 40 758 766 +3 758 187 762 +3 758 762 766 +3 766 762 197 +3 190 742 767 +3 742 143 768 +3 742 768 767 +3 767 768 198 +3 143 628 768 +3 628 47 769 +3 628 769 768 +3 768 769 198 +3 47 334 769 +3 334 44 770 +3 334 770 769 +3 769 770 198 +3 44 764 770 +3 764 190 767 +3 764 767 770 +3 770 767 198 +3 193 747 771 +3 747 188 772 +3 747 772 771 +3 771 772 199 +3 188 761 772 +3 761 39 773 +3 761 773 772 +3 772 773 199 +3 39 341 773 +3 341 50 774 +3 341 774 773 +3 773 774 199 +3 50 775 774 +3 775 193 771 +3 775 771 774 +3 774 771 199 +3 195 753 776 +3 753 193 777 +3 753 777 776 +3 776 777 200 +3 193 775 777 +3 775 50 778 +3 775 778 777 +3 777 778 200 +3 50 348 778 +3 348 53 779 +3 348 779 778 +3 778 779 200 +3 53 780 779 +3 780 195 776 +3 780 776 779 +3 779 776 200 +3 201 781 782 +3 781 202 783 +3 781 783 782 +3 782 783 203 +3 202 784 783 +3 784 204 785 +3 784 785 783 +3 783 785 203 +3 204 786 785 +3 786 205 787 +3 786 787 785 +3 785 787 203 +3 205 788 787 +3 788 201 782 +3 788 782 787 +3 787 782 203 +3 202 789 790 +3 789 206 791 +3 789 791 790 +3 790 791 207 +3 206 792 791 +3 792 208 793 +3 792 793 791 +3 791 793 207 +3 208 794 793 +3 794 204 795 +3 794 795 793 +3 793 795 207 +3 204 784 795 +3 784 202 790 +3 784 790 795 +3 795 790 207 +3 206 796 797 +3 796 163 798 +3 796 798 797 +3 797 798 209 +3 163 664 798 +3 664 165 799 +3 664 799 798 +3 798 799 209 +3 165 800 799 +3 800 208 801 +3 800 801 799 +3 799 801 209 +3 208 792 801 +3 792 206 797 +3 792 797 801 +3 801 797 209 +3 210 802 803 +3 802 201 804 +3 802 804 803 +3 803 804 211 +3 201 788 804 +3 788 205 805 +3 788 805 804 +3 804 805 211 +3 205 806 805 +3 806 212 807 +3 806 807 805 +3 805 807 211 +3 212 808 807 +3 808 210 803 +3 808 803 807 +3 807 803 211 +3 213 809 810 +3 809 210 811 +3 809 811 810 +3 810 811 214 +3 210 808 811 +3 808 212 812 +3 808 812 811 +3 811 812 214 +3 212 813 812 +3 813 215 814 +3 813 814 812 +3 812 814 214 +3 215 815 814 +3 815 213 810 +3 815 810 814 +3 814 810 214 +3 205 786 816 +3 786 204 817 +3 786 817 816 +3 816 817 216 +3 204 818 817 +3 818 172 819 +3 818 819 817 +3 817 819 216 +3 172 691 819 +3 691 171 820 +3 691 820 819 +3 819 820 216 +3 171 821 820 +3 821 205 816 +3 821 816 820 +3 820 816 216 +3 204 794 822 +3 794 208 823 +3 794 823 822 +3 822 823 217 +3 208 824 823 +3 824 176 825 +3 824 825 823 +3 823 825 217 +3 176 699 825 +3 699 172 826 +3 699 826 825 +3 825 826 217 +3 172 818 826 +3 818 204 822 +3 818 822 826 +3 826 822 217 +3 208 800 827 +3 800 165 828 +3 800 828 827 +3 827 828 218 +3 165 690 828 +3 690 130 829 +3 690 829 828 +3 828 829 218 +3 130 706 829 +3 706 176 830 +3 706 830 829 +3 829 830 218 +3 176 824 830 +3 824 208 827 +3 824 827 830 +3 830 827 218 +3 212 806 831 +3 806 205 832 +3 806 832 831 +3 831 832 219 +3 205 821 832 +3 821 171 833 +3 821 833 832 +3 832 833 219 +3 171 712 833 +3 712 180 834 +3 712 834 833 +3 833 834 219 +3 180 835 834 +3 835 212 831 +3 835 831 834 +3 834 831 219 +3 215 813 836 +3 813 212 837 +3 813 837 836 +3 836 837 220 +3 212 835 837 +3 835 180 838 +3 835 838 837 +3 837 838 220 +3 180 719 838 +3 719 183 839 +3 719 839 838 +3 838 839 220 +3 183 840 839 +3 840 215 836 +3 840 836 839 +3 839 836 220 diff -Nru cgal-4.4/examples/Surface_modeling/deform_polyhedron_with_custom_pmap_example.cpp cgal-4.5/examples/Surface_modeling/deform_polyhedron_with_custom_pmap_example.cpp --- cgal-4.4/examples/Surface_modeling/deform_polyhedron_with_custom_pmap_example.cpp 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/examples/Surface_modeling/deform_polyhedron_with_custom_pmap_example.cpp 2014-10-04 19:00:10.000000000 +0000 @@ -0,0 +1,60 @@ +#include +#include +#include +// Halfedge adaptors for Polyhedron_3 +#include +#include +#include +#include + +#include + + +typedef CGAL::Simple_cartesian Kernel; +typedef CGAL::Polyhedron_3 Polyhedron; + +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef boost::graph_traits::vertex_iterator vertex_iterator; +typedef boost::graph_traits::halfedge_descriptor halfedge_descriptor; +typedef boost::graph_traits::halfedge_iterator halfedge_iterator; + +// Define the maps +typedef std::map Vertex_id_map; +typedef std::map Hedge_id_map; +typedef boost::associative_property_map Vertex_id_pmap; +typedef boost::associative_property_map Hedge_id_pmap; + + +typedef CGAL::Surface_mesh_deformation Surface_mesh_deformation; + +int main() +{ + Polyhedron mesh; + std::ifstream input("data/plane.off"); + + if ( !input || !(input >> mesh) || mesh.empty() ) { + std::cerr<< "Cannot open data/plane.off"; + return 1; + } + + // Init the indices of the vertices from 0 to num_vertices(mesh)-1 + Vertex_id_map vertex_index_map; + vertex_iterator vb, ve; + std::size_t counter = 0; + for(boost::tie(vb, ve) = vertices(mesh); vb != ve; ++vb, ++counter) + vertex_index_map[*vb]=counter; + + // Init the indices of the halfedges from 0 to 2*num_edges(mesh)-1 + Hedge_id_map hedge_index_map; + counter = 0; + halfedge_iterator eb, ee; + for(boost::tie(eb, ee) = halfedges(mesh); eb != ee; ++eb, ++counter) + hedge_index_map[*eb]=counter; + + Surface_mesh_deformation deform_mesh( mesh, + Vertex_id_pmap(vertex_index_map), + Hedge_id_pmap(hedge_index_map) ); + + // Now deform mesh as desired + // ..... +} diff -Nru cgal-4.4/examples/Surface_modeling/k_ring_roi_translate_rotate_example.cpp cgal-4.5/examples/Surface_modeling/k_ring_roi_translate_rotate_example.cpp --- cgal-4.4/examples/Surface_modeling/k_ring_roi_translate_rotate_example.cpp 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/examples/Surface_modeling/k_ring_roi_translate_rotate_example.cpp 2014-10-04 19:00:10.000000000 +0000 @@ -0,0 +1,111 @@ +#include +#include +#include +#include +// HalfedgeGraph adaptors for Polyhedron_3 +#include +#include + +#include + +#include +#include +#include + + +typedef CGAL::Simple_cartesian Kernel; +typedef CGAL::Polyhedron_3 Polyhedron; + +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef boost::graph_traits::vertex_iterator vertex_iterator; +typedef boost::graph_traits::halfedge_descriptor halfedge_descriptor; +typedef boost::graph_traits::out_edge_iterator out_edge_iterator; + +typedef Eigen::Vector3d Vector3d; + +typedef CGAL::Surface_mesh_deformation Surface_mesh_deformation; + +// Collect the vertices which are at distance less or equal to k +// from the vertex v in the graph of vertices connected by the edges of P +std::vector extract_k_ring(const Polyhedron &P, vertex_descriptor v, int k) +{ + std::map D; + std::vector Q; + Q.push_back(v); D[v] = 0; + std::size_t current_index = 0; + + int dist_v; + while( current_index < Q.size() && (dist_v = D[ Q[current_index] ]) < k ) { + v = Q[current_index++]; + + out_edge_iterator e, e_end; + for(boost::tie(e, e_end) = out_edges(v, P); e != e_end; e++) + { + halfedge_descriptor he = halfedge(*e, P); + vertex_descriptor new_v = target(he, P); + if(D.insert(std::make_pair(new_v, dist_v + 1)).second) { + Q.push_back(new_v); + } + } + } + return Q; +} + +int main() +{ + Polyhedron mesh; + std::ifstream input("data/plane.off"); + + if ( !input || !(input >> mesh) || mesh.empty() ) { + std::cerr<< "Cannot open data/plane.off"; + return 1; + } + + // Init the indices of the halfedges and the vertices. + set_halfedgeds_items_id(mesh); + + // Create the deformation object + Surface_mesh_deformation deform_mesh(mesh); + + // Select and insert the vertices of the region of interest + vertex_iterator vb, ve; + boost::tie(vb,ve) = vertices(mesh); + std::vector roi = extract_k_ring(mesh, *CGAL::cpp11::next(vb, 47), 9); + deform_mesh.insert_roi_vertices(roi.begin(), roi.end()); + + // Select and insert the control vertices + std::vector cvertices_1 = extract_k_ring(mesh, *CGAL::cpp11::next(vb, 39), 1); + std::vector cvertices_2 = extract_k_ring(mesh, *CGAL::cpp11::next(vb, 97), 1); + deform_mesh.insert_control_vertices(cvertices_1.begin(), cvertices_1.end()); + deform_mesh.insert_control_vertices(cvertices_2.begin(), cvertices_2.end()); + + // Apply a rotation to the control vertices + Eigen::Quaternion quad(0.92, 0, 0, -0.38); + deform_mesh.rotate(cvertices_1.begin(), cvertices_1.end(), Vector3d(0,0,0), quad); + deform_mesh.rotate(cvertices_2.begin(), cvertices_2.end(), Vector3d(0,0,0), quad); + + deform_mesh.deform(); + + // Save the deformed mesh + std::ofstream output("deform_1.off"); + output << mesh; + output.close(); + + // Restore the positions of the vertices + deform_mesh.reset(); + + // Apply a translation on the original positions of the vertices (reset() was called before) + deform_mesh.translate(cvertices_1.begin(), cvertices_1.end(), Vector3d(0,0.3,0)); + deform_mesh.translate(cvertices_2.begin(), cvertices_2.end(), Vector3d(0,0.3,0)); + + // Call the function deform() with one-time parameters: + // iterate 10 times and do not use energy based termination criterion + deform_mesh.set_iterations(10); + deform_mesh.set_tolerance(0.0); + deform_mesh.deform(); + + // Save the deformed mesh + output.open("deform_2.off"); + output << mesh; +} + diff -Nru cgal-4.4/examples/Surface_reconstruction_points_3/CMakeLists.txt cgal-4.5/examples/Surface_reconstruction_points_3/CMakeLists.txt --- cgal-4.4/examples/Surface_reconstruction_points_3/CMakeLists.txt 2013-03-30 20:00:26.000000000 +0000 +++ cgal-4.5/examples/Surface_reconstruction_points_3/CMakeLists.txt 2014-08-29 13:58:17.000000000 +0000 @@ -28,10 +28,6 @@ # VisualC++ optimization for applications dealing with large data if (MSVC) - # Use /EHa option to catch stack overflows. - # Note: TAUCS needs a stack >= 2MB. CGAL default is 10MB. - string(REGEX REPLACE "/EH[asc]*" "/EHa" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") - # Use /FR to turn on IntelliSense SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /FR") @@ -55,19 +51,14 @@ find_package(Eigen3 3.1.0) if (EIGEN3_FOUND) include( ${EIGEN3_USE_FILE} ) - else() - find_package(TAUCS) - if(TAUCS_FOUND) - include( ${TAUCS_USE_FILE} ) - endif(TAUCS_FOUND) endif() - if (EIGEN3_FOUND OR TAUCS_FOUND) - # Executables that require Eigen 3 or TAUCS + if (EIGEN3_FOUND) + # Executables that require Eigen 3 create_single_source_cgal_program( "poisson_reconstruction_example.cpp" ) create_single_source_cgal_program( "poisson_reconstruction.cpp" ) else() - message(STATUS "NOTICE: The examples needs Eigen 3.1 (or greater) or the TAUCS library and will not be compiled.") + message(STATUS "NOTICE: The examples need Eigen 3.1 (or greater) will not be compiled.") endif() diff -Nru cgal-4.4/examples/Surface_reconstruction_points_3/poisson_reconstruction.cpp cgal-4.5/examples/Surface_reconstruction_points_3/poisson_reconstruction.cpp --- cgal-4.4/examples/Surface_reconstruction_points_3/poisson_reconstruction.cpp 2013-07-27 19:00:34.000000000 +0000 +++ cgal-4.5/examples/Surface_reconstruction_points_3/poisson_reconstruction.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include #include @@ -25,9 +25,6 @@ #include #include #include -#ifdef CGAL_TAUCS_ENABLED -#include -#endif #include "compute_normal.h" @@ -124,9 +121,6 @@ std::cerr << "Options:\n"; std::cerr << " -sm_radius Radius upper bound (default=100 * average spacing)\n"; std::cerr << " -sm_distance Distance upper bound (default=0.25 * average spacing)\n"; - #if defined(CGAL_EIGEN3_ENABLED) && defined(CGAL_TAUCS_ENABLED) - std::cerr << " -solver eigen|taucs Sparse linear solver (default=eigen)\n"; - #endif return EXIT_FAILURE; } @@ -135,15 +129,7 @@ FT sm_angle = 20.0; // Min triangle angle (degrees). FT sm_radius = 100; // Max triangle size w.r.t. point set average spacing. FT sm_distance = 0.25; // Approximation error w.r.t. point set average spacing. - #ifdef CGAL_EIGEN3_ENABLED std::string solver_name = "eigen"; // Sparse linear solver name. - #else - #ifdef CGAL_TAUCS_ENABLED - std::string solver_name = "taucs"; // Sparse linear solver name. - #else - std::string solver_name = "no_solver_available"; - #endif - #endif double approximation_ratio = 0.02; double average_spacing_ratio = 5; @@ -273,37 +259,6 @@ CGAL::make_normal_of_point_with_normal_pmap(PointList::value_type()), visitor); - #ifdef CGAL_TAUCS_ENABLED - if (solver_name == "taucs") - { - std::cerr << "Use TAUCS out-of-core Multifrontal Supernodal Cholesky Factorization\n"; - - // Creates sparse linear solver: - // TAUCS out-of-core Multifrontal Supernodal Cholesky Factorization - const char* OOC_SUPERNODAL_CHOLESKY_FACTORIZATION[] = - { - "taucs.factor.LLT=true", - "taucs.factor.mf=true", - "taucs.factor.ordering=metis", - "taucs.ooc=true", "taucs.ooc.basename=taucs-ooc", - NULL - }; - unlink("taucs-ooc.0"); // make sure TAUCS ooc file does not exist - CGAL::Taucs_symmetric_solver_traits solver(OOC_SUPERNODAL_CHOLESKY_FACTORIZATION); - - // Computes the Poisson indicator function f() - // at each vertex of the triangulation. - - if ( ! function.compute_implicit_function(solver, visitor, - approximation_ratio, - average_spacing_ratio) ) - { - std::cerr << "Error: cannot compute implicit function" << std::endl; - return EXIT_FAILURE; - } - } - else - #endif #ifdef CGAL_EIGEN3_ENABLED { if (solver_name == "eigen") @@ -410,7 +365,7 @@ // Constructs AABB tree and computes internal KD-tree // data structure to accelerate distance queries - AABB_tree tree(output_mesh.facets_begin(), output_mesh.facets_end(), output_mesh); + AABB_tree tree(faces(output_mesh).first, faces(output_mesh).second, output_mesh); tree.accelerate_distance_queries(); // Computes distance from each input point to reconstructed mesh diff -Nru cgal-4.4/examples/Triangulation_3/CMakeLists.txt cgal-4.5/examples/Triangulation_3/CMakeLists.txt --- cgal-4.4/examples/Triangulation_3/CMakeLists.txt 2014-04-03 19:01:53.000000000 +0000 +++ cgal-4.5/examples/Triangulation_3/CMakeLists.txt 2014-08-29 13:58:17.000000000 +0000 @@ -18,6 +18,13 @@ if ( CGAL_FOUND ) include( ${CGAL_USE_FILE} ) + + find_package( TBB QUIET ) + + if( TBB_FOUND ) + include(${TBB_USE_FILE}) + list(APPEND CGAL_3RD_PARTY_LIBRARIES ${TBB_LIBRARIES}) + endif() include( CGAL_CreateSingleSourceCGALProgram ) @@ -25,7 +32,6 @@ create_single_source_cgal_program( "adding_handles_3.cpp" ) create_single_source_cgal_program( "color.cpp" ) - create_single_source_cgal_program( "copy_triangulation_3.cpp" ) create_single_source_cgal_program( "fast_location_3.cpp" ) create_single_source_cgal_program( "find_conflicts_3.cpp" ) create_single_source_cgal_program( "info_insert_with_pair_iterator.cpp" ) @@ -33,6 +39,9 @@ create_single_source_cgal_program( "info_insert_with_transform_iterator.cpp" ) create_single_source_cgal_program( "info_insert_with_zip_iterator.cpp" ) create_single_source_cgal_program( "linking_2d_and_3d.cpp" ) + create_single_source_cgal_program( "sequential_parallel.cpp" ) + create_single_source_cgal_program( "parallel_insertion_in_delaunay_3.cpp" ) + create_single_source_cgal_program( "parallel_insertion_and_removal_in_regular_3.cpp" ) create_single_source_cgal_program( "regular_3.cpp" ) create_single_source_cgal_program( "simple_triangulation_3.cpp" ) create_single_source_cgal_program( "simplex.cpp" ) diff -Nru cgal-4.4/examples/Triangulation_3/parallel_insertion_and_removal_in_regular_3.cpp cgal-4.5/examples/Triangulation_3/parallel_insertion_and_removal_in_regular_3.cpp --- cgal-4.4/examples/Triangulation_3/parallel_insertion_and_removal_in_regular_3.cpp 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/examples/Triangulation_3/parallel_insertion_and_removal_in_regular_3.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,59 @@ +#include +#include +#include +#include + +#include +#include +#include + +int main() +{ +#ifdef CGAL_LINKED_WITH_TBB + typedef CGAL::Exact_predicates_inexact_constructions_kernel K; + typedef CGAL::Regular_triangulation_euclidean_traits_3 Traits; + typedef Traits::Bare_point Point; + + // Regular T3 + typedef CGAL::Triangulation_data_structure_3< + CGAL::Triangulation_vertex_base_3, + CGAL::Regular_triangulation_cell_base_3, + CGAL::Parallel_tag> Tds; + + typedef CGAL::Regular_triangulation_3 Rt; + typedef Rt::Vertex_handle Vertex_handle; + + const int NUM_INSERTED_POINTS = 5000; + + CGAL::Random_points_in_cube_3 rnd(1.); + + // Construction from a vector of 1,000,000 points + std::vector V; + V.reserve(NUM_INSERTED_POINTS); + for (int i = 0; i != NUM_INSERTED_POINTS; ++i) + V.push_back(*rnd++); + + // Construct the locking data-structure, using the bounding-box of the points + Rt::Lock_data_structure locking_ds( + CGAL::Bbox_3(-1., -1., -1., 1., 1., 1.), 50); + // Contruct the triangulation in parallel + std::cerr << "Construction and insertion" << std::endl; + Rt rtr(V.begin(), V.end(), &locking_ds); + + assert(rtr.is_valid()); + + std::cerr << "Remove" << std::endl; + // Remove the first 1/10 vertices + std::vector vertices_to_remove; + Rt::Finite_vertices_iterator vit = rtr.finite_vertices_begin(); + for (int i = 0 ; i < NUM_INSERTED_POINTS/10 ; ++i) + vertices_to_remove.push_back(vit++); + // Parallel remove + rtr.remove(vertices_to_remove.begin(), vertices_to_remove.end()); + + assert(rtr.is_valid()); + +#endif //CGAL_LINKED_WITH_TBB + + return 0; +} diff -Nru cgal-4.4/examples/Triangulation_3/parallel_insertion_in_delaunay_3.cpp cgal-4.5/examples/Triangulation_3/parallel_insertion_in_delaunay_3.cpp --- cgal-4.4/examples/Triangulation_3/parallel_insertion_in_delaunay_3.cpp 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/examples/Triangulation_3/parallel_insertion_in_delaunay_3.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,44 @@ +#include +#include +#include + +#include +#include +#include + +int main() +{ +#ifdef CGAL_LINKED_WITH_TBB + typedef CGAL::Exact_predicates_inexact_constructions_kernel K; + + // Delaunay T3 + typedef CGAL::Triangulation_data_structure_3< + CGAL::Triangulation_vertex_base_3, + CGAL::Triangulation_cell_base_3, + CGAL::Parallel_tag> Tds; + typedef CGAL::Delaunay_triangulation_3 Triangulation; + + typedef Triangulation::Point Point; + + const int NUM_INSERTED_POINTS = 5000; + + CGAL::Random_points_in_cube_3 rnd(1.); + + // Construction from a vector of 1,000,000 points + std::vector V; + V.reserve(NUM_INSERTED_POINTS); + for (int i = 0; i != NUM_INSERTED_POINTS; ++i) + V.push_back(*rnd++); + + // Construct the locking data-structure, using the bounding-box of the points + Triangulation::Lock_data_structure locking_ds( + CGAL::Bbox_3(-1., -1., -1., 1., 1., 1.), 50); + // Construct the triangulation in parallel + Triangulation T(V.begin(), V.end(), &locking_ds); + + assert(T.is_valid()); + +#endif //CGAL_LINKED_WITH_TBB + + return 0; +} diff -Nru cgal-4.4/examples/Triangulation_3/sequential_parallel.cpp cgal-4.5/examples/Triangulation_3/sequential_parallel.cpp --- cgal-4.4/examples/Triangulation_3/sequential_parallel.cpp 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/examples/Triangulation_3/sequential_parallel.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,57 @@ +#include +#include +#include +#include + +#include +#include +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef K::Point_3 Point; +typedef CGAL::Timer Timer; + +const int NUM_INSERTED_POINTS = 10000; + +int main() +{ + CGAL::Random_points_in_cube_3 rnd(1.); + + std::cerr << "Construction of a 3D Delaunay triangulation from a vector of " + << NUM_INSERTED_POINTS << " random points in a cube" << std::endl; + std::vector V; + V.reserve(NUM_INSERTED_POINTS); + for (int i = 0; i != NUM_INSERTED_POINTS; ++i) + V.push_back(*rnd++); + + // Sequential Delaunay T3 + typedef CGAL::Delaunay_triangulation_3 SequentialTriangulation; + + Timer t; + t.start(); + SequentialTriangulation S(V.begin(), V.end()); + t.stop(); + std::cerr << "Sequential construction takes " << t.time() << " sec." << std::endl; + +// Parallel Delaunay T3 +#ifdef CGAL_LINKED_WITH_TBB + typedef CGAL::Triangulation_data_structure_3< + CGAL::Triangulation_vertex_base_3, + CGAL::Triangulation_cell_base_3, + CGAL::Parallel_tag> ParallelTds; + typedef CGAL::Delaunay_triangulation_3 ParallelTriangulation; + + t.reset(); + t.start(); + // Construct the locking data-structure, using the bounding-box of the points + ParallelTriangulation::Lock_data_structure locking_ds( + CGAL::Bbox_3(-1., -1., -1., 1., 1., 1.), 50); + // Construct the triangulation in parallel + ParallelTriangulation T(V.begin(), V.end(), &locking_ds); + t.stop(); + std::cerr << "Parallel construction takes " << t.time() << " sec. with " + << tbb::task_scheduler_init::default_num_threads() << " threads" << std::endl; +#endif + + return 0; +} diff -Nru cgal-4.4/include/CGAL/AABB_face_graph_triangle_primitive.h cgal-4.5/include/CGAL/AABB_face_graph_triangle_primitive.h --- cgal-4.4/include/CGAL/AABB_face_graph_triangle_primitive.h 2013-08-03 19:00:28.000000000 +0000 +++ cgal-4.5/include/CGAL/AABB_face_graph_triangle_primitive.h 2014-08-29 13:58:15.000000000 +0000 @@ -23,12 +23,29 @@ #define CGAL_AABB_FACE_GRAPH_TRIANGLE_PRIMITIVE_H #include -#include -#include +#include #include +#include namespace CGAL { + +#ifndef CGAL_NO_DEPRECATED_CODE +namespace internal_aabb_tree{ + BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_facet_const_handle,Facet_const_handle,false) + template ::value> + struct Get_facet_const_handle{ + typedef typename FaceGraph::Facet_const_handle type; + }; + + template + struct Get_facet_const_handle{ + typedef void* type; + }; +} +#endif + /*! * \ingroup PkgAABB_tree * Primitive type for a facet of a polyhedral surface. @@ -38,10 +55,10 @@ * * \cgalModels `AABBPrimitiveWithSharedData` * - *\tparam FaceGraph is a \cgal polyhedron. - *\tparam VertexPointPMap must be set to `CGAL::Default` - * This parameter is useless for the moment and will be useful in an upcoming release of \cgal. - *\tparam OneFaceGraphPerTree is either `CGAL::Tag_true or `CGAL::Tag_false`. + *\tparam FaceGraph is a model of the face graph concept. + *\tparam VertexPointPMap is a property map with `boost::graph_traits::%vertex_descriptor` + * as key type and a \cgal Kernel `Point_3` as value type. + *\tparam OneFaceGraphPerTree is either `CGAL::Tag_true` or `CGAL::Tag_false`. * In the former case, we guarantee that all the primitives will be from a * common polyhedron and some data will be factorized so that the size of * the primitive is reduced. In the latter case, the primitives can be from @@ -60,23 +77,26 @@ class CacheDatum=Tag_false > class AABB_face_graph_triangle_primitive #ifndef DOXYGEN_RUNNING -: public AABB_primitive< typename boost::mpl::if_< - typename boost::is_const::type, - typename FaceGraph::Facet_const_handle, - typename FaceGraph::Facet_handle - >::type, - Triangle_from_facet_handle_property_map, - One_point_from_facet_handle_property_map, - OneFaceGraphPerTree, - CacheDatum > + : public AABB_primitive::face_descriptor, + Triangle_from_face_descriptor_property_map< + FaceGraph, + typename Default::Get::type >::type>, + One_point_from_face_descriptor_property_map< + FaceGraph, + typename Default::Get::type >::type>, + OneFaceGraphPerTree, + CacheDatum > #endif { - typedef typename boost::mpl::if_< - typename boost::is_const::type, - typename FaceGraph::Facet_const_handle, - typename FaceGraph::Facet_handle >::type Id_; - typedef Triangle_from_facet_handle_property_map Triangle_property_map; - typedef One_point_from_facet_handle_property_map Point_property_map; + typedef typename Default::Get::type >::type VertexPointPMap_; + + typedef typename boost::graph_traits::face_descriptor Id_; + typedef Triangle_from_face_descriptor_property_map Triangle_property_map; + typedef One_point_from_face_descriptor_property_map Point_property_map; typedef AABB_primitive< Id_, Triangle_property_map, @@ -91,7 +111,7 @@ /*! The point type. */ - typedef boost::property_traits< boost::property_map< FaceGraph, vertex_point_t>::type >::value_type Point; + typedef boost::property_traits::value_type Point; /*! Geometric data type. */ @@ -114,19 +134,52 @@ Constructs a primitive. */ template - AABB_face_graph_triangle_primitive(Iterator it, FaceGraph& graph) - : Base( Id_(it), + AABB_face_graph_triangle_primitive(Iterator it, const FaceGraph& graph, VertexPointPMap vppm) + : Base( Id_(*it), + Triangle_property_map(const_cast(&graph),vppm), + Point_property_map(const_cast(&graph),vppm) ) + {} + +#ifndef DOXYGEN_RUNNING + template + AABB_face_graph_triangle_primitive(Iterator it, const FaceGraph& graph) + : Base( Id_(*it), + Triangle_property_map(const_cast(&graph)), + Point_property_map(const_cast(&graph)) ) + {} +#ifndef CGAL_NO_DEPRECATED_CODE + // for backward compatibility with Polyhedron::facets_begin() + AABB_face_graph_triangle_primitive(typename boost::graph_traits::face_descriptor fd, FaceGraph& graph) + : Base( Id_(fd), Triangle_property_map(&graph), - Point_property_map(&graph) ){} + Point_property_map(&graph) ) + {} + + AABB_face_graph_triangle_primitive( + typename internal_aabb_tree::Get_facet_const_handle::type fd, + FaceGraph& graph + ) : Base( Id_(fd.remove_const()), + Triangle_property_map(&graph), + Point_property_map(&graph) ) + {} +#endif +#endif /// \internal typedef internal::Cstr_shared_data Cstr_shared_data; /// \internal static typename Cstr_shared_data::Shared_data - construct_shared_data(FaceGraph& graph) + construct_shared_data(const FaceGraph& graph) + { + return Cstr_shared_data::construct_shared_data(const_cast(graph)); + } + + static + typename Cstr_shared_data::Shared_data + construct_shared_data(const FaceGraph& graph, const VertexPointPMap& vpm) { - return Cstr_shared_data::construct_shared_data(graph); + return Cstr_shared_data::construct_shared_data(const_cast(graph), vpm); } }; diff -Nru cgal-4.4/include/CGAL/AABB_halfedge_graph_segment_primitive.h cgal-4.5/include/CGAL/AABB_halfedge_graph_segment_primitive.h --- cgal-4.4/include/CGAL/AABB_halfedge_graph_segment_primitive.h 2013-12-07 20:01:08.000000000 +0000 +++ cgal-4.5/include/CGAL/AABB_halfedge_graph_segment_primitive.h 2014-08-29 13:58:15.000000000 +0000 @@ -23,8 +23,7 @@ #define CGAL_AABB_HALFEDGE_GRAPH_SEGMENT_PRIMITIVE_H #include -#include -#include +#include #include #include @@ -121,18 +120,18 @@ is available with `vppm` set to `boost::get(vertex_point, graph)`. */ template - AABB_halfedge_graph_segment_primitive(Iterator it, HalfedgeGraph& graph, VertexPointPMap vppm) + AABB_halfedge_graph_segment_primitive(Iterator it, const HalfedgeGraph& graph, VertexPointPMap vppm) : Base( Id_(*it), - Segment_property_map(&graph, vppm), - Point_property_map(&graph, vppm) ) + Segment_property_map(const_cast(&graph), vppm), + Point_property_map(const_cast(&graph), vppm) ) {} #ifndef DOXYGEN_RUNNING template - AABB_halfedge_graph_segment_primitive(Iterator it, HalfedgeGraph& graph) + AABB_halfedge_graph_segment_primitive(Iterator it, const HalfedgeGraph& graph) : Base( Id_(*it), - Segment_property_map(&graph), - Point_property_map(&graph) ){} + Segment_property_map(const_cast(&graph)), + Point_property_map(const_cast(&graph)) ){} #endif /// \internal @@ -140,9 +139,16 @@ /// \internal static typename Cstr_shared_data::Shared_data - construct_shared_data(HalfedgeGraph& graph) + construct_shared_data(const HalfedgeGraph& graph) { - return Cstr_shared_data::construct_shared_data(graph); + return Cstr_shared_data::construct_shared_data(const_cast(graph)); + } + + static + typename Cstr_shared_data::Shared_data + construct_shared_data(const HalfedgeGraph& graph, const VertexPointPMap& vpm) + { + return Cstr_shared_data::construct_shared_data(const_cast(graph), vpm); } }; diff -Nru cgal-4.4/include/CGAL/AABB_polyhedral_oracle.h cgal-4.5/include/CGAL/AABB_polyhedral_oracle.h --- cgal-4.4/include/CGAL/AABB_polyhedral_oracle.h 2013-07-27 19:00:33.000000000 +0000 +++ cgal-4.5/include/CGAL/AABB_polyhedral_oracle.h 2014-08-29 13:58:16.000000000 +0000 @@ -50,7 +50,7 @@ typedef Self Surface_3; // AABB tree - typedef AABB_face_graph_triangle_primitive AABB_primitive; + typedef AABB_face_graph_triangle_primitive AABB_primitive; typedef class AABB_traits AABB_traits; typedef AABB_tree Tree; typedef typename AABB_traits::Bounding_box Bounding_box; @@ -65,8 +65,8 @@ // Surface constructor AABB_polyhedral_oracle(const Polyhedron& poly) { - m_pTree = Tree_shared_ptr(new Tree(poly.facets_begin(), - poly.facets_end(), + m_pTree = Tree_shared_ptr(new Tree(faces(poly).first, + faces(poly).second, poly )); } diff -Nru cgal-4.4/include/CGAL/AABB_traits.h cgal-4.5/include/CGAL/AABB_traits.h --- cgal-4.4/include/CGAL/AABB_traits.h 2014-01-25 20:00:23.000000000 +0000 +++ cgal-4.5/include/CGAL/AABB_traits.h 2014-08-29 13:58:15.000000000 +0000 @@ -53,10 +53,10 @@ struct AABB_traits_base{ typename Primitive::Shared_data m_primitive_data; - #ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES + #if !defined(CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES) && !defined(CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE) template - void set_shared_data(T ... t){ - m_primitive_data=Primitive::construct_shared_data(t...); + void set_shared_data(T&& ... t){ + m_primitive_data=Primitive::construct_shared_data(std::forward(t)...); } #else void set_shared_data(){ @@ -64,22 +64,27 @@ } template - void set_shared_data(T1 t1){ + void set_shared_data(T1& t1){ m_primitive_data=Primitive::construct_shared_data(t1); } + template + void set_shared_data(T1& t1, T2& t2){ + m_primitive_data=Primitive::construct_shared_data(t1,t2); + } + template - void set_shared_data(T1 t1,T2 t2,T3 t3){ + void set_shared_data(T1& t1,T2& t2,T3& t3){ m_primitive_data=Primitive::construct_shared_data(t1,t2,t3); } template - void set_shared_data(T1 t1,T2 t2,T3 t3,T4 t4){ + void set_shared_data(T1& t1,T2& t2,T3& t3,T4& t4){ m_primitive_data=Primitive::construct_shared_data(t1,t2,t3,t4); } template - void set_shared_data(T1 t1,T2 t2,T3 t3,T4 t4,T5 t5){ + void set_shared_data(T1& t1,T2& t2,T3& t3,T4& t4,T5& t5){ m_primitive_data=Primitive::construct_shared_data(t1,t2,t3,t4,t5); } #endif diff -Nru cgal-4.4/include/CGAL/AABB_tree.h cgal-4.5/include/CGAL/AABB_tree.h --- cgal-4.4/include/CGAL/AABB_tree.h 2014-01-25 20:00:23.000000000 +0000 +++ cgal-4.5/include/CGAL/AABB_tree.h 2014-08-29 13:58:15.000000000 +0000 @@ -124,22 +124,22 @@ * 5 template arguments are provided. * The tree stays empty if the memory allocation is not successful. */ - #ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES + #if !defined(CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES) && !defined(CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE) template - AABB_tree(InputIterator first, InputIterator beyond,T...); + AABB_tree(InputIterator first, InputIterator beyond,T&& ...); #else template AABB_tree(InputIterator first, InputIterator beyond); template - AABB_tree(InputIterator first, InputIterator beyond,T1); + AABB_tree(InputIterator first, InputIterator beyond, T1&); template - AABB_tree(InputIterator first, InputIterator beyond,T1,T2); + AABB_tree(InputIterator first, InputIterator beyond,T1&,T2&); template - AABB_tree(InputIterator first, InputIterator beyond,T1,T2,T3); + AABB_tree(InputIterator first, InputIterator beyond,T1&,T2&,T3&); template - AABB_tree(InputIterator first, InputIterator beyond,T1,T2,T3,T4); + AABB_tree(InputIterator first, InputIterator beyond,T1&,T2&,T3&,T4&); template - AABB_tree(InputIterator first, InputIterator beyond,T1,T2,T3,T4,T5); + AABB_tree(InputIterator first, InputIterator beyond,T1&,T2&,T3&,T4&,T5&); #endif ///@} @@ -150,22 +150,22 @@ /// Equivalent to calling `clear()` and then `insert(first,last,t...)`. /// For compilers that do not support variadic templates, overloads up /// to 5 template arguments are provided. - #ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES + #if !defined(CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES) && !defined(CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE) template - void rebuild(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond,T...); + void rebuild(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond,T&& ...); #else template void rebuild(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond); template - void rebuild(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond,T1); + void rebuild(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond, T1&); template - void rebuild(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond,T1,T2); + void rebuild(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond,T1&,T2&); template - void rebuild(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond,T1,T2,T3); + void rebuild(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond,T1&,T2&,T3&); template - void rebuild(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond,T1,T2,T3,T4); + void rebuild(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond,T1&,T2&,T3&,T4&); template - void rebuild(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond,T1,T2,T3,T4,T5); + void rebuild(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond,T1&,T2&,T3&,T4&,T5&); #endif @@ -177,22 +177,22 @@ /// is made using the internally stored traits. /// For compilers that do not support variadic templates, /// overloads up to 5 template arguments are provided. - #ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES + #if !defined(CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES) && !defined(CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE) template - void insert(InputIterator first, InputIterator beyond,T...); + void insert(InputIterator first, InputIterator beyond,T&& ...); #else template void insert(InputIterator first, InputIterator beyond); template - void insert(InputIterator first, InputIterator beyond,T1); + void insert(InputIterator first, InputIterator beyond,T1&); template - void insert(InputIterator first, InputIterator beyond,T1,T2); + void insert(InputIterator first, InputIterator beyond,T1&, T2&); template - void insert(InputIterator first, InputIterator beyond,T1,T2,T3); + void insert(InputIterator first, InputIterator beyond,T1&,T2&,T3&); template - void insert(InputIterator first, InputIterator beyond,T1,T2,T3,T4); + void insert(InputIterator first, InputIterator beyond,T1&,T2&,T3&,T4&); template - void insert(InputIterator first, InputIterator beyond,T1,T2,T3,T4,T5); + void insert(InputIterator first, InputIterator beyond,T1&,T2&,T3&,T4&,T5&); #endif /// Adds a primitive to the set of primitives of the tree. @@ -251,16 +251,16 @@ ///@} private: - #ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES + #if !defined(CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES) && !defined(CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE) template void set_primitive_data_impl(CGAL::Boolean_tag,T ... ){} template - void set_primitive_data_impl(CGAL::Boolean_tag,T ... t) - {m_traits.set_shared_data(t...);} + void set_primitive_data_impl(CGAL::Boolean_tag,T&& ... t) + {m_traits.set_shared_data(std::forward(t)...);} template - void set_shared_data(T...t){ - set_primitive_data_impl(CGAL::Boolean_tag::value>(),t...); + void set_shared_data(T&& ...t){ + set_primitive_data_impl(CGAL::Boolean_tag::value>(),std::forward(t)...); } #else void set_primitive_data_impl(CGAL::Boolean_tag){} @@ -273,50 +273,50 @@ template void set_primitive_data_impl(CGAL::Boolean_tag,T1){} template - void set_primitive_data_impl(CGAL::Boolean_tag,T1 t1) + void set_primitive_data_impl(CGAL::Boolean_tag,T1& t1) {m_traits.set_shared_data(t1);} template - void set_shared_data(T1 t1){ + void set_shared_data(T1& t1){ set_primitive_data_impl(Boolean_tag::value>(),t1); } template void set_primitive_data_impl(CGAL::Boolean_tag,T1,T2){} template - void set_primitive_data_impl(CGAL::Boolean_tag,T1 t1,T2 t2) + void set_primitive_data_impl(CGAL::Boolean_tag,T1& t1,T2& t2) {m_traits.set_shared_data(t1,t2);} template - void set_shared_data(T1 t1,T2 t2){ + void set_shared_data(const T1& t1,const T2& t2){ set_primitive_data_impl(Boolean_tag::value>(),t1,t2); } template void set_primitive_data_impl(CGAL::Boolean_tag,T1,T2,T3){} template - void set_primitive_data_impl(CGAL::Boolean_tag,T1 t1,T2 t2,T3 t3) + void set_primitive_data_impl(CGAL::Boolean_tag,T1& t1,T2& t2,T3& t3) {m_traits.set_shared_data(t1,t2,t3);} template - void set_shared_data(T1 t1,T2 t2,T3 t3){ + void set_shared_data(T1& t1,T2& t2,T3& t3){ set_primitive_data_impl(Boolean_tag::value>(),t1,t2,t3); } template void set_primitive_data_impl(CGAL::Boolean_tag,T1,T2,T3,T4){} template - void set_primitive_data_impl(CGAL::Boolean_tag,T1 t1,T2 t2,T3 t3,T4 t4) + void set_primitive_data_impl(CGAL::Boolean_tag,T1& t1,T2& t2,T3& t3,T4& t4) {m_traits.set_shared_data(t1,t2,t3,t4);} template - void set_shared_data(T1 t1,T2 t2,T3 t3,T4 t4){ + void set_shared_data(T1& t1,T2& t2,T3& t3,T4& t4){ set_primitive_data_impl(Boolean_tag::value>(),t1,t2,t3,t4); } template void set_primitive_data_impl(CGAL::Boolean_tag,T1,T2,T3,T4,T5){} template - void set_primitive_data_impl(CGAL::Boolean_tag,T1 t1,T2 t2,T3 t3,T4 t4,T5 t5) + void set_primitive_data_impl(CGAL::Boolean_tag,T1& t1,T2& t2,T3& t3,T4& t4,T5& t5) {m_traits.set_shared_data(t1,t2,t3,t4,t5);} template - void set_shared_data(T1 t1,T2 t2,T3 t3,T4 t4,T5 t5){ + void set_shared_data(T1& t1,T2& t2,T3& t3,T4& t4,T5& t5){ set_primitive_data_impl(Boolean_tag::value>(),t1,t2,t3,t4,t5); } #endif @@ -648,12 +648,12 @@ , m_need_build(false) {} - #ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES + #if !defined(CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES) && !defined(CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE) template template AABB_tree::AABB_tree(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond, - T ... t) + T&& ... t) : m_traits() , m_primitives() , m_p_root_node(NULL) @@ -663,19 +663,19 @@ , m_need_build(false) { // Insert each primitive into tree - insert(first, beyond,t...); + insert(first, beyond,std::forward(t)...); } template template void AABB_tree::insert(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond, - T ... t) + T&& ... t) { - set_shared_data(t...); + set_shared_data(std::forward(t)...); while(first != beyond) { - m_primitives.push_back(Primitive(first,t...)); + m_primitives.push_back(Primitive(first,std::forward(t)...)); ++first; } m_need_build = true; @@ -686,13 +686,13 @@ template void AABB_tree::rebuild(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond, - T ... t) + T&& ... t) { // cleanup current tree and internal KD tree clear(); // inserts primitives - insert(first, beyond,t...); + insert(first, beyond,std::forward(t)...); build(); } @@ -718,7 +718,7 @@ template AABB_tree::AABB_tree(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond, - T1 t1) + T1& t1) : m_traits() , m_primitives() , m_p_root_node(NULL) @@ -735,7 +735,7 @@ template AABB_tree::AABB_tree(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond, - T1 t1,T2 t2) + T1& t1,T2& t2) : m_traits() , m_primitives() , m_p_root_node(NULL) @@ -752,7 +752,7 @@ template AABB_tree::AABB_tree(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond, - T1 t1,T2 t2,T3 t3) + T1& t1,T2& t2,T3& t3) : m_traits() , m_primitives() , m_p_root_node(NULL) @@ -769,7 +769,7 @@ template AABB_tree::AABB_tree(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond, - T1 t1,T2 t2,T3 t3,T4 t4) + T1& t1,T2& t2,T3& t3,T4& t4) : m_traits() , m_primitives() , m_p_root_node(NULL) @@ -786,7 +786,7 @@ template AABB_tree::AABB_tree(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond, - T1 t1,T2 t2,T3 t3,T4 t4,T5 t5) + T1& t1,T2& t2,T3& t3,T4& t4,T5& t5) : m_traits() , m_primitives() , m_p_root_node(NULL) @@ -817,7 +817,7 @@ template void AABB_tree::insert(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond, - T1 t1) + T1& t1) { set_shared_data(t1); while(first != beyond) @@ -832,7 +832,7 @@ template void AABB_tree::insert(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond, - T1 t1,T2 t2) + T1& t1, T2& t2) { set_shared_data(t1,t2); while(first != beyond) @@ -847,7 +847,7 @@ template void AABB_tree::insert(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond, - T1 t1,T2 t2,T3 t3) + T1& t1,T2& t2,T3& t3) { set_shared_data(t1,t2,t3); while(first != beyond) @@ -862,7 +862,7 @@ template void AABB_tree::insert(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond, - T1 t1,T2 t2,T3 t3,T4 t4) + T1& t1,T2& t2,T3& t3,T4& t4) { set_shared_data(t1,t2,t3,t4); while(first != beyond) @@ -877,7 +877,7 @@ template void AABB_tree::insert(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond, - T1 t1,T2 t2,T3 t3,T4 t4,T5 t5) + T1& t1,T2& t2,T3& t3,T4& t4,T5& t5) { set_shared_data(t1,t2,t3,t4,t5); while(first != beyond) @@ -888,7 +888,7 @@ m_need_build = true; } - //=============insert====================== + //=============rebuild====================== template template void AABB_tree::rebuild(ConstPrimitiveIterator first, @@ -907,7 +907,7 @@ template void AABB_tree::rebuild(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond, - T1 t1) + T1& t1) { // cleanup current tree and internal KD tree clear(); @@ -922,7 +922,7 @@ template void AABB_tree::rebuild(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond, - T1 t1,T2 t2) + T1& t1, T2& t2) { // cleanup current tree and internal KD tree clear(); @@ -937,7 +937,7 @@ template void AABB_tree::rebuild(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond, - T1 t1,T2 t2,T3 t3) + T1& t1,T2& t2,T3& t3) { // cleanup current tree and internal KD tree clear(); @@ -952,7 +952,7 @@ template void AABB_tree::rebuild(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond, - T1 t1,T2 t2,T3 t3,T4 t4) + T1& t1,T2& t2,T3& t3,T4& t4) { // cleanup current tree and internal KD tree clear(); @@ -967,7 +967,7 @@ template void AABB_tree::rebuild(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond, - T1 t1,T2 t2,T3 t3,T4 t4,T5 t5) + T1& t1,T2& t2,T3& t3,T4& t4,T5& t5) { // cleanup current tree and internal KD tree clear(); diff -Nru cgal-4.4/include/CGAL/argument_swaps.h cgal-4.5/include/CGAL/argument_swaps.h --- cgal-4.4/include/CGAL/argument_swaps.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/argument_swaps.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,88 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_ARGUMENT_SWAPS_H +#define CGAL_ARGUMENT_SWAPS_H + +#include +#include + +#ifndef CGAL_CXX11 +#include +#include +#endif + +namespace CGAL { + +#ifdef CGAL_CXX11 + +namespace internal { + +template struct Apply_to_last_then_rest_; + +template +struct Apply_to_last_then_rest_ { + typedef typename Apply_to_last_then_rest_::result_type result_type; + inline result_type operator()(F&&f,T&&t,U&&...u)const{ + return Apply_to_last_then_rest_()( + std::forward(f), + std::forward(u)..., + std::forward(t)); + } +}; + +template +struct Apply_to_last_then_rest_<0,F,T,U...> { + typedef decltype(std::declval()(std::declval(), std::declval()...)) result_type; + inline result_type operator()(F&&f,T&&t,U&&...u)const{ + return std::forward(f)(std::forward(t), std::forward(u)...); + } +}; + +} // namespace internal + + +struct Apply_to_last_then_rest { + template inline + typename internal::Apply_to_last_then_rest_::result_type + operator()(F&&f,T&&t,U&&...u)const{ + return internal::Apply_to_last_then_rest_()( + std::forward(f), + std::forward(t), + std::forward(u)...); + } +}; + +#else // CGAL_CXX11 + +struct Apply_to_last_then_rest { +#define CGAL_CODE(Z,N,_) template \ + typename boost::result_of::type \ + operator()(F const&f, BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t), T const&t) const { \ + return f(t,BOOST_PP_ENUM_PARAMS(N,t)); \ + } + BOOST_PP_REPEAT_FROM_TO(1,11,CGAL_CODE,_) +#undef CGAL_CODE +}; + +#endif // CGAL_CXX11 + +} // namespace CGAL + +#endif // CGAL_ARGUMENT_SWAPS_H diff -Nru cgal-4.4/include/CGAL/Arithmetic_kernel/Arithmetic_kernel_base.h cgal-4.5/include/CGAL/Arithmetic_kernel/Arithmetic_kernel_base.h --- cgal-4.4/include/CGAL/Arithmetic_kernel/Arithmetic_kernel_base.h 2012-11-13 13:13:52.000000000 +0000 +++ cgal-4.5/include/CGAL/Arithmetic_kernel/Arithmetic_kernel_base.h 2014-08-29 13:58:16.000000000 +0000 @@ -27,6 +27,8 @@ #ifndef CGAL_ARITHMETIC_KERNEL_ARITHMETIC_KERNEL_BASE_H #define CGAL_ARITHMETIC_KERNEL_ARITHMETIC_KERNEL_BASE_H +#include + namespace CGAL { namespace internal{ diff -Nru cgal-4.4/include/CGAL/Arrangement_2/Arrangement_on_surface_2_global.h cgal-4.5/include/CGAL/Arrangement_2/Arrangement_on_surface_2_global.h --- cgal-4.4/include/CGAL/Arrangement_2/Arrangement_on_surface_2_global.h 2013-08-13 19:00:22.000000000 +0000 +++ cgal-4.5/include/CGAL/Arrangement_2/Arrangement_on_surface_2_global.h 2014-08-29 13:58:16.000000000 +0000 @@ -14,7 +14,7 @@ // // $URL$ // $Id$ -// +// // // Author(s) : Ron Wein // Baruch Zukerman @@ -55,21 +55,21 @@ // Insert a curve into the arrangement (incremental insertion). // The inserted curve may intersect the existing arrangement. // -// The last parameter is used to resolve ambiguity between this function and -// do_intersect of X_monotone_curve_2 in case that X_monotone_curve_2 and -// Curve_2 are the same class. -// The last parameter should be boost::false_type but we used a +// The last parameter is used to resolve ambiguity between this function and +// do_intersect of X_monotone_curve_2 in case that X_monotone_curve_2 and +// Curve_2 are the same class. +// The last parameter should be boost::false_type but we used a // workaround since it didn't compile in FC3_g++-3.4.4 with the error of: // -// error: no matching function for call to `do_intersect(Arrangement_2<>&, -// const Arr_segment_2&, const Arr_walk_along_line_point_location<>&, +// error: no matching function for call to `do_intersect(Arrangement_2<>&, +// const Arr_segment_2&, const Arr_walk_along_line_point_location<>&, // mpl_::bool_< true>)' // -template -void insert (Arrangement_on_surface_2& arr, +void insert (Arrangement_on_surface_2& arr, const typename GeomTraits::Curve_2& c, - const PointLocation& pl, ZoneVisitor &visitor, + const PointLocation& pl, ZoneVisitor &visitor, boost::is_same::type) { typedef Arrangement_on_surface_2 Arr; @@ -104,7 +104,7 @@ // Initialize the zone-computation object with the given curve. arr_zone.init (*x_curve, pl); - // Notify the arrangement observers that a global operation is about to + // Notify the arrangement observers that a global operation is about to // take place. arr_access.notify_before_global_change(); @@ -130,21 +130,21 @@ // Insert an x-monotone curve into the arrangement (incremental insertion). // The inserted x-monotone curve may intersect the existing arrangement. // -// The last parameter is used to resolve ambiguity between this function and -// do_intersect of Curve_2 in case that X_monotone_curve_2 and Curve_2 are the -// same class. The last parameter should be boost::true_type but we used a +// The last parameter is used to resolve ambiguity between this function and +// do_intersect of Curve_2 in case that X_monotone_curve_2 and Curve_2 are the +// same class. The last parameter should be boost::true_type but we used a // workaround since it didn't compile in FC3_g++-3.4.4 with the error of: // -// error: no matching function for call to `do_intersect(Arrangement_2<>&, -// const Arr_segment_2&, const Arr_walk_along_line_point_location<>&, +// error: no matching function for call to `do_intersect(Arrangement_2<>&, +// const Arr_segment_2&, const Arr_walk_along_line_point_location<>&, // mpl_::bool_< true>)' // // -template void insert(Arrangement_on_surface_2& arr, const typename GeomTraits::X_monotone_curve_2& c, - const PointLocation& pl, ZoneVisitor &visitor, + const PointLocation& pl, ZoneVisitor &visitor, boost::is_same::type) { typedef Arrangement_on_surface_2 Arr; @@ -177,11 +177,11 @@ } std::cout << std::endl; std::cout << "xxxxxxxxxxxx" << std::endl; - } + } */ arr_zone.init (c, pl); - // Notify the arrangement observers that a global operation is about to + // Notify the arrangement observers that a global operation is about to // take place. arr_access.notify_before_global_change(); @@ -195,16 +195,16 @@ //----------------------------------------------------------------------------- // Common interface for the insert of the Curve_2 and X_monotone_curve_2 -template void insert (Arrangement_on_surface_2& arr, const Curve& c, const PointLocation& pl, ZoneVisitor &visitor) { typedef typename GeomTraits::X_monotone_curve_2 X_monotone_curve_2; - + typedef typename boost::is_same::type Is_x_monotone; - + insert(arr, c, pl, visitor, Is_x_monotone()); } @@ -219,13 +219,13 @@ typename PointLocation::Point_2*) { typedef typename TopTraits::Zone_insertion_visitor Zone_visitor; - + Zone_visitor visitor; insert (arr, c, pl, visitor); } //----------------------------------------------------------------------------- -// Insert a curve/x-monotone curve into the arrangement (incremental +// Insert a curve/x-monotone curve into the arrangement (incremental // insertion). // The inserted x-monotone curve may intersect the existing arrangement. // Overloaded version with no point location object - using the default point @@ -265,7 +265,7 @@ * GeomTraits, use a reference to GeomTraits to avoid constructing a new one. * Otherwise, instantiate a local variable of the former and provide * the later as a single parameter to the constructor. - * + * * Use the form 'A a(*b);' and not ''A a = b;' to handle the case where A has * only an implicit constructor, (which takes *b as a parameter). */ @@ -298,7 +298,7 @@ typedef typename TopTraits::Sweep_line_construction_visitor Construct_visitor; typedef typename Construct_visitor::Traits_2 Construct_traits; - + const GeomTraits * geom_traits = arr.geometry_traits(); Construct_visitor visitor(&arr); @@ -310,14 +310,14 @@ * GeomTraits, use a reference to GeomTraits to avoid constructing a new one. * Otherwise, instantiate a local variable of the former and provide * the later as a single parameter to the constructor. - * + * * Use the form 'A a(*b);' and not ''A a = b;' to handle the case where A has * only an implicit constructor, (which takes *b as a parameter). */ typename boost::mpl::if_, const Construct_traits&, Construct_traits>::type traits(*geom_traits); - + // Define a sweep-line instance and perform the sweep. Sweep_line_2 ex_cvs; std::list ex_pts; - + prepare_for_sweep(arr, begin_xcurves, end_xcurves, // the x-monotone curves begin_points, end_points, // the points (if any) @@ -384,18 +384,18 @@ } //----------------------------------------------------------------------------- -// Insert a range of curves into the arrangement (aggregated insertion). -// The inserted curves may intersect one another and may also intersect the +// Insert a range of curves into the arrangement (aggregated insertion). +// The inserted curves may intersect one another and may also intersect the // existing arrangement. // -// The last parameter is used to resolve ambiguity between this function and -// do_intersect of X_monotone_curve_2 in case that X_monotone_curve_2 and -// Curve_2 are the same class. -// The last parameter should be boost::false_type but we used a +// The last parameter is used to resolve ambiguity between this function and +// do_intersect of X_monotone_curve_2 in case that X_monotone_curve_2 and +// Curve_2 are the same class. +// The last parameter should be boost::false_type but we used a // workaround since it didn't compile in FC3_g++-3.4.4 with the error of: // -// error: no matching function for call to `do_intersect(Arrangement_2<>&, -// const Arr_segment_2&, const Arr_walk_along_line_point_location<>&, +// error: no matching function for call to `do_intersect(Arrangement_2<>&, +// const Arr_segment_2&, const Arr_walk_along_line_point_location<>&, // mpl_::bool_< true>)' // template @@ -410,7 +410,7 @@ // Obtain an arrangement accessor. Arr_accessor arr_access (arr); - // Notify the arrangement observers that a global operation is about to + // Notify the arrangement observers that a global operation is about to // take place. arr_access.notify_before_global_change(); @@ -440,18 +440,18 @@ // insertion). The inserted x-monotone curves may intersect one another and // may also intersect the existing arrangement. // -// The last parameter is used to resolve ambiguity between this function and -// insert of Curve_2 in case that X_monotone_curve_2 and Curve_2 are the -// same class. The last parameter should be boost::true_type but we used a +// The last parameter is used to resolve ambiguity between this function and +// insert of Curve_2 in case that X_monotone_curve_2 and Curve_2 are the +// same class. The last parameter should be boost::true_type but we used a // workaround since it didn't compile in FC3_g++-3.4.4 with the error of: // -// error: no matching function for call to `do_intersect(Arrangement_2<>&, -// const Arr_segment_2&, const Arr_walk_along_line_point_location<>&, +// error: no matching function for call to `do_intersect(Arrangement_2<>&, +// const Arr_segment_2&, const Arr_walk_along_line_point_location<>&, // mpl_::bool_< true>)' // template void insert(Arrangement_on_surface_2& arr, - InputIterator begin, InputIterator end, + InputIterator begin, InputIterator end, boost::is_same::type) { typedef Arrangement_on_surface_2 Arr; @@ -459,7 +459,7 @@ // Obtain an arrangement accessor. Arr_accessor arr_access (arr); - // Notify the arrangement observers that a global operation is about to + // Notify the arrangement observers that a global operation is about to // take place. arr_access.notify_before_global_change(); @@ -486,12 +486,12 @@ InputIterator begin, InputIterator end) { typedef typename GeomTraits::X_monotone_curve_2 X_monotone_curve_2; - typedef typename std::iterator_traits::value_type + typedef typename std::iterator_traits::value_type Iterator_value_type; typedef typename boost::is_same::type Is_x_monotone; - + return insert (arr, begin, end, Is_x_monotone()); } @@ -520,7 +520,7 @@ // Initialize the zone-computation object with the given curve. arr_zone.init_with_hint (c, obj); - // Notify the arrangement observers that a global operation is about to + // Notify the arrangement observers that a global operation is about to // take place. arr_access.notify_before_global_change(); @@ -555,7 +555,7 @@ /* DEPRECATED use insert() instead */ template -CGAL_DEPRECATED void insert_x_monotone_curves +CGAL_DEPRECATED void insert_x_monotone_curves (Arrangement_on_surface_2& arr, InputIterator begin, InputIterator end) { @@ -696,8 +696,8 @@ vh2 = object_cast(&obj2); } - // Notify the arrangement observers that a global operation is about to - // take place. + // Notify the arrangement observers that a global operation is about to + // take place. arr_access.notify_before_global_change(); // Check whether the located features containing the curve endpoints @@ -746,8 +746,8 @@ // << (*fh1)->number_of_outer_ccbs() << std::endl; // std::cout << "(*fh2)->number_of_outer_ccbs(): " // << (*fh2)->number_of_outer_ccbs() << std::endl; - - CGAL_assertion_msg + + CGAL_assertion_msg ((fh1 != NULL) && (fh2 != NULL) && ((*fh1) == (*fh2)), "The curve intersects the interior of existing edges."); @@ -799,7 +799,7 @@ Construct_visitor; Construct_visitor visitor(&arr); typename Construct_visitor::Traits_2 traits(*geom_traits); - + // Define a basic sweep-line instance (which is not supposed to handle // insersections) and perform the sweep. Basic_sweep_line_2, const Insert_traits&, Insert_traits>::type traits(*geom_traits); - + // Create a set of existing as well as new curves and points. std::list ex_cvs; std::list ex_pts; - + prepare_for_sweep(arr, begin_xcurves, end_xcurves, // the x-monotone curves begin_points, end_points, // the points (if any) @@ -929,7 +929,7 @@ // Obtain an arrangement accessor. Arr_accessor arr_access (arr); - // Notify the arrangement observers that a global operation is about to + // Notify the arrangement observers that a global operation is about to // take place. arr_access.notify_before_global_change(); @@ -963,7 +963,7 @@ typedef Arrangement_on_surface_2 Arr; typedef Arr_traits_adaptor_2 Traits_adaptor_2; - // Notify the arrangement observers that a global operation is about to + // Notify the arrangement observers that a global operation is about to // take place. Arr_accessor arr_access (arr); @@ -974,10 +974,10 @@ bool is_removed[2]; v_ends[0] = e->source(); - is_removed[0] = + is_removed[0] = (v_ends[0]->is_at_open_boundary() || v_ends[0]->degree() == 1); v_ends[1] = e->target(); - is_removed[1] = + is_removed[1] = (v_ends[1]->is_at_open_boundary() || v_ends[1]->degree() == 1); // Remove the edge from the arrangement. @@ -987,7 +987,7 @@ // curves associated with these edges can be merged, merge the two edges and // remove the vertex. - const Traits_adaptor_2 * traits = + const Traits_adaptor_2 * traits = static_cast (arr.geometry_traits()); typename Arr::Halfedge_around_vertex_circulator circ; @@ -1021,7 +1021,7 @@ // Notify the arrangement observers that the global operation has been // completed. arr_access.notify_after_global_change(); - + // Return the face remaining after the removal of the edge. return (face); } @@ -1047,27 +1047,27 @@ // Locate the given point in the arrangement. CGAL::Object obj = pl.locate (p); - // Notify the arrangement observers that a global operation is about to + // Notify the arrangement observers that a global operation is about to // take place. Arr_accessor arr_access (arr); arr_access.notify_before_global_change(); - if ((fh = object_cast(&obj)) != NULL) + if ((fh = object_cast(&obj)) != NULL) { // p lies inside a face: Insert it as an isolated vertex it the interior of // this face. vh_for_p = arr.insert_in_face_interior (p, arr.non_const_handle (*fh)); } - else if ((hh = - object_cast(&obj)) != NULL) + else if ((hh = + object_cast(&obj)) != NULL) { // p lies in the interior of an edge: Split this edge to create a new // vertex associated with p. typename GeomTraits::X_monotone_curve_2 sub_cv1, sub_cv2; typename Arr::Halfedge_handle split_he; - + arr.geometry_traits()->split_2_object() ((*hh)->curve(), p, sub_cv1, sub_cv2); @@ -1083,7 +1083,7 @@ // vertex. vh = object_cast(&obj); CGAL_assertion (vh != NULL); - + vh_for_p = arr.modify_vertex (arr.non_const_handle (*vh), p); } @@ -1091,7 +1091,7 @@ // completed. arr_access.notify_after_global_change(); - // Return a handle for the vertex associated with p. + // Return a handle for the vertex associated with p. return (vh_for_p); } @@ -1106,7 +1106,7 @@ { // Create a default point-location object and use it to insert the point. typename TopTraits::Default_point_location_strategy def_pl (arr); - + return (insert_point (arr, p, def_pl)); } @@ -1121,7 +1121,7 @@ typedef Arrangement_on_surface_2 Arr; typedef Arr_traits_adaptor_2 Traits_adaptor_2; - // Notify the arrangement observers that a global operation is about to + // Notify the arrangement observers that a global operation is about to // take place. Arr_accessor arr_access (arr); @@ -1187,7 +1187,7 @@ typedef Arrangement_on_surface_2 Arr; typedef GeomTraits Geometry_traits_2; typedef typename Geometry_traits_2::X_monotone_curve_2 X_monotone_curve_2; - + // Define the sweep-line types: typedef Sweep_line_do_curves_x_visitor Visitor; typedef Sweep_line_2 Sweep_line_2; @@ -1201,14 +1201,14 @@ typedef typename Arr::Vertex_const_handle Vertex_const_handle; typedef typename Arr::Isolated_vertex_const_iterator Isolated_vertex_const_iterator; - typedef typename Arr::Halfedge_around_vertex_const_circulator + typedef typename Arr::Halfedge_around_vertex_const_circulator Halfedge_around_vertex_const_circulator; - + // Perform a sweep over all subcurves associated with arrangement edges. std::vector curves_vec (arr.number_of_edges()); Edge_const_iterator eit; unsigned int i = 0; - + for (eit = arr.edges_begin(); eit != arr.edges_end(); ++eit, i++) curves_vec[i] = eit->curve(); @@ -1217,7 +1217,7 @@ Sweep_line_2 sweep_line (traits, &visitor); visitor.sweep_xcurves (curves_vec.begin(), curves_vec.end()); - + bool are_edges_disjoint = (! visitor.found_intersection()); if (!are_edges_disjoint) @@ -1229,10 +1229,10 @@ // Check that the holes and isolated vertices are located where they should. // At the same time, we prepare a vector that consists of all isolated - // vertices and all leftmost vertices from every hole. + // vertices and all leftmost vertices from every hole. std::list > vf_list; - typename Geometry_traits_2::Compare_xy_2 compare_xy = + typename Geometry_traits_2::Compare_xy_2 compare_xy = traits->compare_xy_2_object(); Face_const_iterator fit; Face_const_handle fh; @@ -1313,7 +1313,7 @@ // right. if (he_below->direction() == ARR_RIGHT_TO_LEFT) he_below = he_below->twin(); - + in_face = he_below->face(); } else if (CGAL::assign(v_below, obj)) @@ -1324,7 +1324,7 @@ in_face = v_below->face(); } else - { + { // Get the first halfedge aroung v_below that is directed from left to // right and the first halfedge that is directed from right to left. first = circ = v_below->incident_halfedges(); @@ -1344,16 +1344,16 @@ break; } ++circ; - + } while(circ != first); - CGAL_assertion (he_left != invalid_he || he_right != invalid_he); + CGAL_assertion (he_left != invalid_he || he_right != invalid_he); if (he_left != invalid_he && he_right != invalid_he) { while (he_left->direction() == ARR_LEFT_TO_RIGHT) he_left = he_left->next()->twin(); - + he_left = he_left->twin()->prev(); CGAL_assertion (he_left->direction() == ARR_LEFT_TO_RIGHT); in_face = he_left->face(); @@ -1362,7 +1362,7 @@ { Comparison_result res; Halfedge_const_handle he_curr = he_left; - + do // as long as we have next he_left halfedge which is above { he_left = he_curr; @@ -1371,13 +1371,13 @@ he_left->curve(), v_below->point()); } while(res == LARGER); - in_face = he_left->face(); + in_face = he_left->face(); } else { Comparison_result res; Halfedge_const_handle he_curr = he_right; - + do // as long as we have he_right halfedge which is below { he_right = he_curr; @@ -1386,8 +1386,8 @@ he_right->curve(), v_below->point()); } while(res == SMALLER); - in_face = he_right->face(); - } + in_face = he_right->face(); + } } } else @@ -1415,26 +1415,26 @@ //----------------------------------------------------------------------------- // Compute the zone of the given x-monotone curve in the existing arrangement. -// Meaning, it output the arrangment's vertices, edges and faces that the +// Meaning, it output the arrangment's vertices, edges and faces that the // x-monotone curve intersects. -template -OutputIterator zone (Arrangement_on_surface_2& arr, +OutputIterator zone (Arrangement_on_surface_2& arr, const typename GeomTraits::X_monotone_curve_2& c, OutputIterator oi, const PointLocation& pl) { // Obtain an arrangement accessor. - typedef Arrangement_on_surface_2 + typedef Arrangement_on_surface_2 Arrangement_on_surface_2; // Define a zone-computation object an a visitor that performs the // intersection check. - typedef Arr_compute_zone_visitor + typedef Arr_compute_zone_visitor Zone_visitor; - + Zone_visitor visitor (oi); - Arrangement_zone_2 + Arrangement_zone_2 arr_zone (arr, &visitor); arr_zone.init (c, pl); @@ -1449,7 +1449,7 @@ // strategy is used as default. // template -OutputIterator zone (Arrangement_on_surface_2& arr, +OutputIterator zone (Arrangement_on_surface_2& arr, const typename GeomTraits::X_monotone_curve_2& c, OutputIterator oi) { @@ -1464,16 +1464,16 @@ //----------------------------------------------------------------------------- // Checks if the given x-monotone curve intersects the existing arrangement. -// The last parameter is used to resolve ambiguity between this function and -// do_intersect of Curve_2 in case that X_monotone_curve_2 and Curve_2 are the -// same class. The last parameter should be boost::true_type but we used a +// The last parameter is used to resolve ambiguity between this function and +// do_intersect of Curve_2 in case that X_monotone_curve_2 and Curve_2 are the +// same class. The last parameter should be boost::true_type but we used a // workaround since it didn't compile in FC3_g++-3.4.4 with the error of: // -// error: no matching function for call to `do_intersect(Arrangement_on_surface_2<>&, +// error: no matching function for call to `do_intersect(Arrangement_on_surface_2<>&, // const Arr_segment_2&, const Arr_walk_along_line_point_location<>&, mpl_::bool_< true>)' // template -bool do_intersect (Arrangement_on_surface_2& arr, +bool do_intersect (Arrangement_on_surface_2& arr, const typename GeomTraits::X_monotone_curve_2& c, const PointLocation& pl, boost::is_same::type) { @@ -1484,9 +1484,9 @@ // Define a zone-computation object an a visitor that performs the // intersection check. typedef Arr_do_intersect_zone_visitor Zone_visitor; - + Zone_visitor visitor; - Arrangement_zone_2 + Arrangement_zone_2 arr_zone (arr, &visitor); arr_zone.init (c, pl); @@ -1497,17 +1497,17 @@ //----------------------------------------------------------------------------- // Checks if the given curve intersects the existing arrangement. -// The last parameter is used to resolve ambiguity between this function and -// do_intersect of X_monotone_curve_2 in case that X_monotone_curve_2 and -// Curve_2 are the same class. -// The last parameter should be boost::false_type but we used a +// The last parameter is used to resolve ambiguity between this function and +// do_intersect of X_monotone_curve_2 in case that X_monotone_curve_2 and +// Curve_2 are the same class. +// The last parameter should be boost::false_type but we used a // workaround since it didn't compile in FC3_g++-3.4.4 with the error of: // -// error: no matching function for call to `do_intersect(Arrangement_on_surface_2<>&, +// error: no matching function for call to `do_intersect(Arrangement_on_surface_2<>&, // const Arr_segment_2&, const Arr_walk_along_line_point_location<>&, mpl_::bool_< true>)' // template -bool do_intersect (Arrangement_on_surface_2& arr, +bool do_intersect (Arrangement_on_surface_2& arr, const typename GeomTraits::X_monotone_curve_2& c, const PointLocation& pl, boost::is_same::type) { @@ -1519,7 +1519,7 @@ typedef Arr_traits_adaptor_2 Traits_adaptor_2; const Traits_adaptor_2 * traits = - static_cast (arr.traits()); + static_cast (arr.geometry_traits()); std::list x_objects; std::list::const_iterator obj_iter; @@ -1533,7 +1533,7 @@ for (obj_iter = x_objects.begin(); obj_iter != x_objects.end(); ++obj_iter) { // Act according to the type of the current object. - x_curve = object_cast + x_curve = object_cast (&(*obj_iter)); if (x_curve != NULL) { @@ -1545,12 +1545,12 @@ { iso_p = object_cast (&(*obj_iter)); CGAL_assertion (iso_p != NULL); - + // Check whether the isolated point lies inside a face (otherwise, // it conincides with a vertex or an edge). CGAL::Object obj = pl.locate (*iso_p); - - return (object_cast(&obj) != NULL); } } @@ -1562,14 +1562,14 @@ //----------------------------------------------------------------------------- // Common interface for the do_intersect of the Curve_2 and X_monotone_curve_2 template -bool do_intersect (Arrangement_on_surface_2& arr, +bool do_intersect (Arrangement_on_surface_2& arr, const Curve& c, const PointLocation& pl) { typedef typename GeomTraits::X_monotone_curve_2 X_monotone_curve_2; - + typedef typename boost::is_same::type Is_x_monotone; - + return do_intersect(arr, c, pl, Is_x_monotone()); } @@ -1578,13 +1578,13 @@ // Overloaded version with no point location object - the walk point-location // strategy is used as default. template -bool do_intersect (Arrangement_on_surface_2& arr, +bool do_intersect (Arrangement_on_surface_2& arr, const Curve& c) { // Create a default point-location object and use it to insert the curve. typename TopTraits::Default_point_location_strategy def_pl (arr); - - // check if the curve intersects the arrangement using the walk point + + // check if the curve intersects the arrangement using the walk point // location. return do_intersect (arr, c, def_pl); } diff -Nru cgal-4.4/include/CGAL/Arrangement_2/Arrangement_on_surface_2_impl.h cgal-4.5/include/CGAL/Arrangement_2/Arrangement_on_surface_2_impl.h --- cgal-4.4/include/CGAL/Arrangement_2/Arrangement_on_surface_2_impl.h 2013-12-14 20:00:35.000000000 +0000 +++ cgal-4.5/include/CGAL/Arrangement_2/Arrangement_on_surface_2_impl.h 2014-08-29 13:58:16.000000000 +0000 @@ -40,6 +40,7 @@ */ #include +#include namespace CGAL { @@ -909,6 +910,8 @@ Vertex_handle v1, Vertex_handle v2, Face_handle f) { + CGAL_USE(f); + // Determine which one of the given vertices matches the left end of the // given curve. const bool at_obnd1 = !m_geom_traits->is_closed_2_object()(cv, ARR_MIN_END); @@ -3672,7 +3675,6 @@ // init with edges at first link. // assuming that he_anchor has been removed const DHalfedge* he_curr = he_anchor->opposite()->prev(); - CGAL_assertion(! he_curr->has_null_curve()); const DHalfedge* he_next = he_anchor->next(); // init edge where loop should end const DHalfedge* he_end = he_anchor->opposite(); @@ -3681,12 +3683,17 @@ int y_index = 0; // obtain the parameter space pair of he_curr - Arr_curve_end he_curr_tgt_end = - (he_curr->direction() == ARR_LEFT_TO_RIGHT) ? ARR_MAX_END : ARR_MIN_END; - Arr_parameter_space ps_x_save = - parameter_space_in_x(he_curr->curve(), he_curr_tgt_end); - Arr_parameter_space ps_y_save = - parameter_space_in_y(he_curr->curve(), he_curr_tgt_end); + Arr_parameter_space ps_x_save, ps_y_save; + if (he_curr->has_null_curve()) { + ps_x_save = he_curr->vertex()->parameter_space_in_x(); + ps_y_save = he_curr->vertex()->parameter_space_in_y(); + } + else { + Arr_curve_end he_curr_tgt_end = + (he_curr->direction() == ARR_LEFT_TO_RIGHT) ? ARR_MAX_END : ARR_MIN_END; + ps_x_save = parameter_space_in_x(he_curr->curve(), he_curr_tgt_end); + ps_y_save = parameter_space_in_y(he_curr->curve(), he_curr_tgt_end); + } // TODO EBEB 2012-09-20 check whether this fix is correct // EBEB 2012-08-22 the 'start' of one (out of two) loops might @@ -3700,22 +3707,28 @@ Arr_parameter_space ps_x_curr, ps_y_curr; Arr_parameter_space ps_x_next, ps_y_next; - // start loop + // Start loop do { ps_x_curr = ps_x_save; ps_y_curr = ps_y_save; - CGAL_assertion(!is_open(ps_x_curr, ps_y_curr)); - Arr_curve_end he_next_src_end = - (he_next->direction() == ARR_LEFT_TO_RIGHT) ? ARR_MIN_END : ARR_MAX_END; - ps_x_next = parameter_space_in_x(he_next->curve(), he_next_src_end); - ps_y_next = parameter_space_in_y(he_next->curve(), he_next_src_end); - CGAL_assertion(!is_open(ps_x_next, ps_y_next)); - - Arr_curve_end he_next_tgt_end = - (he_next->direction() == ARR_LEFT_TO_RIGHT) ? ARR_MAX_END : ARR_MIN_END; - ps_x_save = parameter_space_in_x(he_next->curve(), he_next_tgt_end); - ps_y_save = parameter_space_in_y(he_next->curve(), he_next_tgt_end); + if (he_next->has_null_curve()) { + ps_x_next = he_next->opposite()->vertex()->parameter_space_in_x(); + ps_y_next = he_next->opposite()->vertex()->parameter_space_in_y(); + ps_x_save = he_next->vertex()->parameter_space_in_x(); + ps_y_save = he_next->vertex()->parameter_space_in_y(); + } + else { + Arr_curve_end he_next_src_end = + (he_next->direction() == ARR_LEFT_TO_RIGHT) ? ARR_MIN_END : ARR_MAX_END; + ps_x_next = parameter_space_in_x(he_next->curve(), he_next_src_end); + ps_y_next = parameter_space_in_y(he_next->curve(), he_next_src_end); + + Arr_curve_end he_next_tgt_end = + (he_next->direction() == ARR_LEFT_TO_RIGHT) ? ARR_MAX_END : ARR_MIN_END; + ps_x_save = parameter_space_in_x(he_next->curve(), he_next_tgt_end); + ps_y_save = parameter_space_in_y(he_next->curve(), he_next_tgt_end); + } // If the halfedge is directed from right to left and its successor is // directed from left to right, the target vertex might be the smallest: @@ -3790,6 +3803,19 @@ CGAL_precondition(he1->direction() == ARR_RIGHT_TO_LEFT); CGAL_precondition(he2->direction() == ARR_RIGHT_TO_LEFT); CGAL_precondition(he1->vertex() != he2->vertex()); + + /* If he1 points to a vertex on the left or the bottom boundary, then it + * is the smaller. + */ + if ((ps_x1 == ARR_LEFT_BOUNDARY) || (ps_y1 == ARR_BOTTOM_BOUNDARY)) + return true; + + /* If he2 points to a vertex on the left or the bottom boundary, then it + * is the smaller. + */ + if ((ps_x2 == ARR_LEFT_BOUNDARY) || (ps_y2 == ARR_BOTTOM_BOUNDARY)) + return false; + return _is_smaller(he1->curve(), he1->vertex()->point(), ps_x1, ps_y1, he2->curve(), he2->vertex()->point(), ps_x2, ps_y2, tag); } @@ -3875,7 +3901,8 @@ _is_smaller_near_right(const X_monotone_curve_2& cv1, const X_monotone_curve_2& cv2, const Point_2& p, - Arr_parameter_space /* ps_x */, Arr_parameter_space /* ps_y */, + Arr_parameter_space /* ps_x */, + Arr_parameter_space /* ps_y */, Arr_all_sides_oblivious_tag) const { return @@ -4153,12 +4180,12 @@ // is neither a need to compute signs and nor swapping of the halfedges if ((he1->next() != he2) && (he2->next() != he1)) { - // If f1 == f2 (same_face-case), then we consider two loops that occur - // when he1 and he2 get removedl; - // if f1 != f2, then he1 and he2 seperated the two faces that will be merged - // upon their removal - here each he1 and he2 belongs to a full cycle - // THAT IS WHY we give the f1 == f2 test to determine whether end of loop - // should be he1->opposite() and he2->opposite(), respectively. + // If f1 == f2 (same_face-case), then we consider two loops that occur when + // he1 and he2 get removed; if f1 != f2, then he1 and he2 seperates the two + // faces that will be merged upon their removal---here both he1 and he2 + // belong to a full cycle, and THAT IS WHY we give the f1 == f2 test to + // determine whether end of loop should be he1->opposite() and + // he2->opposite(), respectively. // If f1 != f2, the removal of he1 (and its twin halfedge) will cause // the two incident faces to merge. Thus, swapping is not needed. @@ -4189,7 +4216,9 @@ #if CGAL_ARRANGEMENT_ON_SURFACE_INSERT_VERBOSE std::cout << "signs1.x: " << signs1.first << std::endl; std::cout << "signs1.y: " << signs1.second << std::endl; - std::cout << "he_min1: " << he_min1->curve() << std::endl; + if (! he_min1->is_fictitious()) + std::cout << "he_min1: " << he_min1->curve() << std::endl; + else std::cout << "he_min1 fictitious" << std::endl; #endif // Compute the signs and minimum along ccb of he2: @@ -4203,7 +4232,9 @@ #if CGAL_ARRANGEMENT_ON_SURFACE_INSERT_VERBOSE std::cout << "signs2.x: " << signs2.first << std::endl; std::cout << "signs2.y: " << signs2.second << std::endl; - std::cout << "he_min2: " << he_min2->curve() << std::endl; + if (! he_min2->is_fictitious()) + std::cout << "he_min2: " << he_min2->curve() << std::endl; + else std::cout << "he_min2 fictitious" << std::endl; #endif // TODO EBEB 2012-07-29 @@ -4241,17 +4272,14 @@ #endif } else { - CGAL_assertion(he_min1 != NULL); - CGAL_assertion(he_min2 != NULL); - - // const DVertex* v_min1 = he_min1->vertex(); - // const DVertex* v_min2 = he_min2->vertex(); - // Both paths from he1 to he2 and back from he2 to he1 are not - // perimetric, so we are in case (a). As we want to determine which - // halfedge points to the new hole to be created (he1 or he2), - // we have to compare the two leftmost vertices lexicographically, - // first by the indices then by x and y. v_min2 lies to the left of - // v_min1 if and only if he1 points at the hole we are about to create. + // const DVertex* v_min1 = he_min1->vertex(); const DVertex* v_min2 = + // he_min2->vertex(); Both paths from he1 to he2 and back from he2 to + // he1 are not perimetric, so we are in case (a). As we want to + // determine which halfedge points to the new hole to be created (he1 + // or he2), we have to compare the two leftmost vertices + // lexicographically, first by the indices then by x and y. v_min2 + // lies to the left of v_min1 if and only if he1 points at the hole we + // are about to create. // // +---------------------+ // | | @@ -4272,7 +4300,8 @@ // on different sides of the identification, which is only // problematic when either he1 or he2 points to the // identification. In these cases, we have to adapt the indices: - typename Traits_adaptor_2::Parameter_space_in_x_2 parameter_space_in_x = + typename Traits_adaptor_2::Parameter_space_in_x_2 + parameter_space_in_x = m_geom_traits->parameter_space_in_x_2_object(); Arr_curve_end he1_tgt_end = diff -Nru cgal-4.4/include/CGAL/Arr_bounded_planar_topology_traits_2.h cgal-4.5/include/CGAL/Arr_bounded_planar_topology_traits_2.h --- cgal-4.4/include/CGAL/Arr_bounded_planar_topology_traits_2.h 2013-12-14 20:00:35.000000000 +0000 +++ cgal-4.5/include/CGAL/Arr_bounded_planar_topology_traits_2.h 2014-08-29 13:58:16.000000000 +0000 @@ -35,7 +35,7 @@ #include #include #include - +#include namespace CGAL { // Forward declaration: @@ -382,6 +382,9 @@ const X_monotone_curve_2& cv, Arr_curve_end ind, Arr_parameter_space ps_x, Arr_parameter_space ps_y) const { + CGAL_USE(ps_x); + CGAL_USE(ps_y); + CGAL_assertion((ps_x == ARR_INTERIOR) && (ps_y == ARR_INTERIOR)); if (ind == ARR_MIN_END) { diff -Nru cgal-4.4/include/CGAL/Arr_geodesic_arc_on_sphere_traits_2.h cgal-4.5/include/CGAL/Arr_geodesic_arc_on_sphere_traits_2.h --- cgal-4.4/include/CGAL/Arr_geodesic_arc_on_sphere_traits_2.h 2014-01-18 20:00:25.000000000 +0000 +++ cgal-4.5/include/CGAL/Arr_geodesic_arc_on_sphere_traits_2.h 2014-08-29 13:58:16.000000000 +0000 @@ -282,8 +282,8 @@ FT norm2 = v2 * v2; return (s1 == POSITIVE) ? - compare(dot_p1 * dot_p1 * norm2, dot_p2 * dot_p2 * norm1) : - compare(dot_p2 * dot_p2 * norm1, dot_p1 * dot_p1 * norm2); + CGAL::compare(dot_p1 * dot_p1 * norm2, dot_p2 * dot_p2 * norm1) : + CGAL::compare(dot_p2 * dot_p2 * norm1, dot_p1 * dot_p1 * norm2); } /*! Compare two directions contained in the xy plane by u. diff -Nru cgal-4.4/include/CGAL/Arr_polyline_traits_2.h cgal-4.5/include/CGAL/Arr_polyline_traits_2.h --- cgal-4.4/include/CGAL/Arr_polyline_traits_2.h 2013-12-14 20:00:35.000000000 +0000 +++ cgal-4.5/include/CGAL/Arr_polyline_traits_2.h 2014-08-29 13:58:16.000000000 +0000 @@ -2742,8 +2742,7 @@ * If q is not in the x-range of cv, returns INVALID_INDEX. */ template - std::size_t locate_gen(const X_monotone_curve_2& cv, - Compare compare) const + std::size_t locate_gen(const X_monotone_curve_2& cv, Compare compare) const { // The direction of cv. SMALLER means left-to-right and // otherwise right-to-left @@ -2766,7 +2765,14 @@ Comparison_result res_to = compare(cv[to], ARR_MAX_END); if (res_to == EQUAL) return to; - if (res_to == res_from) return INVALID_INDEX; + // Check whether the point is either lexicographically to the left of + // the curve or lexicographically to the right of the curve. + if (res_to == res_from) + // If the x-monotone polyline is vertical, return the index of the + // segment that is closest to the point. Otherwise, the point is not + // in the x-range of the polyline. + return (is_vertical_2_object()(cv)) ? + ((res_to == SMALLER) ? from : to) : INVALID_INDEX; // Perform a binary search to locate the segment that contains q in its // range: diff -Nru cgal-4.4/include/CGAL/boost/graph/backward_compatibility_functions.h cgal-4.5/include/CGAL/boost/graph/backward_compatibility_functions.h --- cgal-4.4/include/CGAL/boost/graph/backward_compatibility_functions.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/boost/graph/backward_compatibility_functions.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,77 @@ +// Copyright (c) 2013 GeometryFactory (France). All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Andreas Fabri + +#ifndef CGAL_BOOST_GRAPH_BACKWARD_COMPATIBILITY_FUNCTIONS_H +#define CGAL_BOOST_GRAPH_BACKWARD_COMPATIBILITY_FUNCTIONS_H + +namespace CGAL { + + template + typename boost::graph_traits::edge_descriptor + opposite_edge(typename boost::graph_traits::edge_descriptor e + , const Graph& g) + { + typename boost::graph_traits::halfedge_descriptor h = halfedge(e, g); + return edge(opposite(h,g), g); + } + + + template + typename boost::graph_traits::edge_descriptor + next_edge(typename boost::graph_traits::edge_descriptor e + , const Graph& g) + { + typename boost::graph_traits::halfedge_descriptor h = halfedge(e, g); + return edge(next(h, g), g); +} + + + template + typename boost::graph_traits::edge_descriptor + next_edge_cw(typename boost::graph_traits::edge_descriptor e + , const Graph& g) + { + typename boost::graph_traits::halfedge_descriptor h = halfedge(e, g); + return edge(opposite(next(h, g), g), g); + } + + + template + typename boost::graph_traits::edge_descriptor + next_edge_ccw(typename boost::graph_traits::edge_descriptor e + , const Graph& g) + { + typename boost::graph_traits::halfedge_descriptor h = halfedge(e, g); + + return edge(prev(opposite(h, g), g), g); + } + + template + struct halfedge_graph_traits; + + template + std::pair::undirected_edge_iterator, typename CGAL::halfedge_graph_traits::undirected_edge_iterator> + undirected_edges(const Graph& g) + { + return edges(g); + } + +} //end of namespace CGAL + +#endif //CGAL_BOOST_GRAPH_BACKWARD_COMPATIBILITY_FUNCTIONS_H diff -Nru cgal-4.4/include/CGAL/boost/graph/dijkstra_shortest_paths.h cgal-4.5/include/CGAL/boost/graph/dijkstra_shortest_paths.h --- cgal-4.4/include/CGAL/boost/graph/dijkstra_shortest_paths.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/boost/graph/dijkstra_shortest_paths.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,40 @@ +// Copyright (c) 2014 GeometryFactory (France). All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Sebastien Loriot + + +#ifndef CGAL_BOOST_GRAPH_DIJKSTRA_SHORTEST_PATHS_H +#define CGAL_BOOST_GRAPH_DIJKSTRA_SHORTEST_PATHS_H + +#include +#include + +#if BOOST_VERSION == 105400 + #ifdef BOOST_GRAPH_DIJKSTRA_HPP + # pragma message \ + "Warning: the header file boost/graph/dijkstra_shortest_paths.hpp " \ + "of boost 1.54 contains a bug that may impact some functions in CGAL. " \ + "Please consider including CGAL/boost/graph/dijkstra_shortest_paths.hpp " \ + "before boost header" + #endif + #include +#else + #include +#endif + +#endif // CGAL_BOOST_GRAPH_DIJKSTRA_SHORTEST_PATHS_H diff -Nru cgal-4.4/include/CGAL/boost/graph/dijkstra_shortest_paths.hpp cgal-4.5/include/CGAL/boost/graph/dijkstra_shortest_paths.hpp --- cgal-4.4/include/CGAL/boost/graph/dijkstra_shortest_paths.hpp 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/boost/graph/dijkstra_shortest_paths.hpp 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,629 @@ +// This file is a copy of the file distributed with boost 1.55 +// It is distributed with CGAL to work around a bug in boost 1.54 +// and must be used only with boost 1.54 by including +// CGAL/boost/graph/dijkstra_shortest_paths.hpp + + +//======================================================================= +// Copyright 1997, 1998, 1999, 2000 University of Notre Dame. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// 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) +//======================================================================= +// +// +// Revision History: +// 04 April 2001: Added named parameter variant. (Jeremy Siek) +// 01 April 2001: Modified to use new header. (JMaddock) +// +#ifndef BOOST_GRAPH_DIJKSTRA_HPP +#define BOOST_GRAPH_DIJKSTRA_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_GRAPH_DIJKSTRA_TESTING +# include +#endif // BOOST_GRAPH_DIJKSTRA_TESTING + +namespace boost { + + /** + * @brief Updates a particular value in a queue used by Dijkstra's + * algorithm. + * + * This routine is called by Dijkstra's algorithm after it has + * decreased the distance from the source vertex to the given @p + * vertex. By default, this routine will just call @c + * Q.update(vertex). However, other queues may provide more + * specialized versions of this routine. + * + * @param Q the queue that will be updated. + * @param vertex the vertex whose distance has been updated + * @param old_distance the previous distance to @p vertex + */ + template + inline void + dijkstra_queue_update(Buffer& Q, Vertex vertex, DistanceType old_distance) + { + (void)old_distance; + Q.update(vertex); + } + +#ifdef BOOST_GRAPH_DIJKSTRA_TESTING + // This is a misnomer now: it now just refers to the "default heap", which is + // currently d-ary (d=4) but can be changed by a #define. + static bool dijkstra_relaxed_heap = true; +#endif + + template + struct DijkstraVisitorConcept { + void constraints() { + BOOST_CONCEPT_ASSERT(( CopyConstructibleConcept )); + vis.initialize_vertex(u, g); + vis.discover_vertex(u, g); + vis.examine_vertex(u, g); + vis.examine_edge(e, g); + vis.edge_relaxed(e, g); + vis.edge_not_relaxed(e, g); + vis.finish_vertex(u, g); + } + Visitor vis; + Graph g; + typename graph_traits::vertex_descriptor u; + typename graph_traits::edge_descriptor e; + }; + + template + class dijkstra_visitor : public bfs_visitor { + public: + dijkstra_visitor() { } + dijkstra_visitor(Visitors vis) + : bfs_visitor(vis) { } + + template + void edge_relaxed(Edge e, Graph& g) { + invoke_visitors(this->m_vis, e, g, on_edge_relaxed()); + } + template + void edge_not_relaxed(Edge e, Graph& g) { + invoke_visitors(this->m_vis, e, g, on_edge_not_relaxed()); + } + private: + template + void tree_edge(Edge /* u */, Graph& /* g */) { } + }; + template + dijkstra_visitor + make_dijkstra_visitor(Visitors vis) { + return dijkstra_visitor(vis); + } + typedef dijkstra_visitor<> default_dijkstra_visitor; + + namespace detail { + + template + struct dijkstra_bfs_visitor + { + typedef typename property_traits::value_type D; + typedef typename property_traits::value_type W; + + dijkstra_bfs_visitor(UniformCostVisitor vis, UpdatableQueue& Q, + WeightMap w, PredecessorMap p, DistanceMap d, + BinaryFunction combine, BinaryPredicate compare, + D zero) + : m_vis(vis), m_Q(Q), m_weight(w), m_predecessor(p), m_distance(d), + m_combine(combine), m_compare(compare), m_zero(zero) { } + + template + void tree_edge(Edge e, Graph& g) { + bool decreased = relax(e, g, m_weight, m_predecessor, m_distance, + m_combine, m_compare); + if (decreased) + m_vis.edge_relaxed(e, g); + else + m_vis.edge_not_relaxed(e, g); + } + template + void gray_target(Edge e, Graph& g) { + D old_distance = get(m_distance, target(e, g)); + + bool decreased = relax(e, g, m_weight, m_predecessor, m_distance, + m_combine, m_compare); + if (decreased) { + dijkstra_queue_update(m_Q, target(e, g), old_distance); + m_vis.edge_relaxed(e, g); + } else + m_vis.edge_not_relaxed(e, g); + } + + template + void initialize_vertex(Vertex u, Graph& g) + { m_vis.initialize_vertex(u, g); } + template + void non_tree_edge(Edge, Graph&) { } + template + void discover_vertex(Vertex u, Graph& g) { m_vis.discover_vertex(u, g); } + template + void examine_vertex(Vertex u, Graph& g) { m_vis.examine_vertex(u, g); } + template + void examine_edge(Edge e, Graph& g) { + // Test for negative-weight edges: + // + // Reasons that other comparisons do not work: + // + // m_compare(e_weight, D(0)): + // m_compare only needs to work on distances, not weights, and those + // types do not need to be the same (bug 8398, + // https://svn.boost.org/trac/boost/ticket/8398). + // m_compare(m_combine(source_dist, e_weight), source_dist): + // if m_combine is project2nd (as in prim_minimum_spanning_tree), + // this test will claim that the edge weight is negative whenever + // the edge weight is less than source_dist, even if both of those + // are positive (bug 9012, + // https://svn.boost.org/trac/boost/ticket/9012). + // m_compare(m_combine(e_weight, source_dist), source_dist): + // would fix project2nd issue, but documentation only requires that + // m_combine be able to take a distance and a weight (in that order) + // and return a distance. + + // W e_weight = get(m_weight, e); + // sd_plus_ew = source_dist + e_weight. + // D sd_plus_ew = m_combine(source_dist, e_weight); + // sd_plus_2ew = source_dist + 2 * e_weight. + // D sd_plus_2ew = m_combine(sd_plus_ew, e_weight); + // The test here is equivalent to e_weight < 0 if m_combine has a + // cancellation law, but always returns false when m_combine is a + // projection operator. + if (m_compare(m_combine(m_zero, get(m_weight, e)), m_zero)) + boost::throw_exception(negative_edge()); + // End of test for negative-weight edges. + + m_vis.examine_edge(e, g); + + } + template + void black_target(Edge, Graph&) { } + template + void finish_vertex(Vertex u, Graph& g) { m_vis.finish_vertex(u, g); } + + UniformCostVisitor m_vis; + UpdatableQueue& m_Q; + WeightMap m_weight; + PredecessorMap m_predecessor; + DistanceMap m_distance; + BinaryFunction m_combine; + BinaryPredicate m_compare; + D m_zero; + }; + + } // namespace detail + + namespace detail { + template + struct vertex_property_map_generator_helper {}; + + template + struct vertex_property_map_generator_helper { + typedef boost::iterator_property_map type; + static type build(const Graph& g, const IndexMap& index, boost::scoped_array& array_holder) { + array_holder.reset(new Value[num_vertices(g)]); + std::fill(array_holder.get(), array_holder.get() + num_vertices(g), Value()); + return make_iterator_property_map(array_holder.get(), index); + } + }; + + template + struct vertex_property_map_generator_helper { + typedef boost::vector_property_map type; + static type build(const Graph& /* g */, const IndexMap& index, boost::scoped_array& /* array_holder */) { + return boost::make_vector_property_map(index); + } + }; + + template + struct vertex_property_map_generator { + typedef boost::is_base_and_derived< + boost::vertex_list_graph_tag, + typename boost::graph_traits::traversal_category> + known_num_vertices; + typedef vertex_property_map_generator_helper helper; + typedef typename helper::type type; + static type build(const Graph& g, const IndexMap& index, boost::scoped_array& array_holder) { + return helper::build(g, index, array_holder); + } + }; + } + + namespace detail { + template + struct default_color_map_generator_helper {}; + + template + struct default_color_map_generator_helper { + typedef boost::two_bit_color_map type; + static type build(const Graph& g, const IndexMap& index) { + size_t nv = num_vertices(g); + return boost::two_bit_color_map(nv, index); + } + }; + + template + struct default_color_map_generator_helper { + typedef boost::vector_property_map type; + static type build(const Graph& /* g */, const IndexMap& index) { + return boost::make_vector_property_map(index); + } + }; + + template + struct default_color_map_generator { + typedef boost::is_base_and_derived< + boost::vertex_list_graph_tag, + typename boost::graph_traits::traversal_category> + known_num_vertices; + typedef default_color_map_generator_helper helper; + typedef typename helper::type type; + static type build(const Graph& g, const IndexMap& index) { + return helper::build(g, index); + } + }; + } + + // Call breadth first search with default color map. + template + inline void + dijkstra_shortest_paths_no_init + (const Graph& g, + SourceInputIter s_begin, SourceInputIter s_end, + PredecessorMap predecessor, DistanceMap distance, WeightMap weight, + IndexMap index_map, + Compare compare, Combine combine, DistZero zero, + DijkstraVisitor vis) + { + typedef + detail::default_color_map_generator + ColorMapHelper; + typedef typename ColorMapHelper::type ColorMap; + ColorMap color = + ColorMapHelper::build(g, index_map); + dijkstra_shortest_paths_no_init( g, s_begin, s_end, predecessor, distance, weight, + index_map, compare, combine, zero, vis, + color); + } + + // Call breadth first search with default color map. + template + inline void + dijkstra_shortest_paths_no_init + (const Graph& g, + typename graph_traits::vertex_descriptor s, + PredecessorMap predecessor, DistanceMap distance, WeightMap weight, + IndexMap index_map, + Compare compare, Combine combine, DistZero zero, + DijkstraVisitor vis) + { + dijkstra_shortest_paths_no_init(g, &s, &s + 1, predecessor, distance, + weight, index_map, compare, combine, zero, + vis); + } + + // Call breadth first search + template + inline void + dijkstra_shortest_paths_no_init + (const Graph& g, + SourceInputIter s_begin, SourceInputIter s_end, + PredecessorMap predecessor, DistanceMap distance, WeightMap weight, + IndexMap index_map, + Compare compare, Combine combine, DistZero zero, + DijkstraVisitor vis, ColorMap color) + { + typedef indirect_cmp IndirectCmp; + IndirectCmp icmp(distance, compare); + + typedef typename graph_traits::vertex_descriptor Vertex; + +#ifdef BOOST_GRAPH_DIJKSTRA_TESTING + if (!dijkstra_relaxed_heap) { + typedef mutable_queue, IndirectCmp, IndexMap> + MutableQueue; + + MutableQueue Q(num_vertices(g), icmp, index_map); + detail::dijkstra_bfs_visitor + bfs_vis(vis, Q, weight, predecessor, distance, combine, compare, zero); + + breadth_first_visit(g, s_begin, s_end, Q, bfs_vis, color); + return; + } +#endif // BOOST_GRAPH_DIJKSTRA_TESTING + +#ifdef BOOST_GRAPH_DIJKSTRA_USE_RELAXED_HEAP + typedef relaxed_heap MutableQueue; + MutableQueue Q(num_vertices(g), icmp, index_map); +#else // Now the default: use a d-ary heap + boost::scoped_array index_in_heap_map_holder; + typedef + detail::vertex_property_map_generator + IndexInHeapMapHelper; + typedef typename IndexInHeapMapHelper::type IndexInHeapMap; + IndexInHeapMap index_in_heap = + IndexInHeapMapHelper::build(g, index_map, index_in_heap_map_holder); + typedef d_ary_heap_indirect + MutableQueue; + MutableQueue Q(distance, index_in_heap, compare); +#endif // Relaxed heap + + detail::dijkstra_bfs_visitor + bfs_vis(vis, Q, weight, predecessor, distance, combine, compare, zero); + + breadth_first_visit(g, s_begin, s_end, Q, bfs_vis, color); + } + + // Call breadth first search + template + inline void + dijkstra_shortest_paths_no_init + (const Graph& g, + typename graph_traits::vertex_descriptor s, + PredecessorMap predecessor, DistanceMap distance, WeightMap weight, + IndexMap index_map, + Compare compare, Combine combine, DistZero zero, + DijkstraVisitor vis, ColorMap color) + { + dijkstra_shortest_paths_no_init(g, &s, &s + 1, predecessor, distance, + weight, index_map, compare, combine, + zero, vis, color); + } + + // Initialize distances and call breadth first search with default color map + template + inline void + dijkstra_shortest_paths + (const VertexListGraph& g, + SourceInputIter s_begin, SourceInputIter s_end, + PredecessorMap predecessor, DistanceMap distance, WeightMap weight, + IndexMap index_map, + Compare compare, Combine combine, DistInf inf, DistZero zero, + DijkstraVisitor vis, + const bgl_named_params& + BOOST_GRAPH_ENABLE_IF_MODELS_PARM(VertexListGraph,vertex_list_graph_tag)) + { + boost::two_bit_color_map color(num_vertices(g), index_map); + dijkstra_shortest_paths(g, s_begin, s_end, predecessor, distance, weight, + index_map, compare, combine, inf, zero, vis, + color); + } + + // Initialize distances and call breadth first search with default color map + template + inline void + dijkstra_shortest_paths + (const VertexListGraph& g, + typename graph_traits::vertex_descriptor s, + PredecessorMap predecessor, DistanceMap distance, WeightMap weight, + IndexMap index_map, + Compare compare, Combine combine, DistInf inf, DistZero zero, + DijkstraVisitor vis, + const bgl_named_params& + BOOST_GRAPH_ENABLE_IF_MODELS_PARM(VertexListGraph,vertex_list_graph_tag)) + { + dijkstra_shortest_paths(g, &s, &s + 1, predecessor, distance, weight, + index_map, compare, combine, inf, zero, vis); + } + + // Initialize distances and call breadth first search + template + inline void + dijkstra_shortest_paths + (const VertexListGraph& g, + SourceInputIter s_begin, SourceInputIter s_end, + PredecessorMap predecessor, DistanceMap distance, WeightMap weight, + IndexMap index_map, + Compare compare, Combine combine, DistInf inf, DistZero zero, + DijkstraVisitor vis, ColorMap color) + { + typedef typename property_traits::value_type ColorValue; + typedef color_traits Color; + typename graph_traits::vertex_iterator ui, ui_end; + for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) { + vis.initialize_vertex(*ui, g); + put(distance, *ui, inf); + put(predecessor, *ui, *ui); + put(color, *ui, Color::white()); + } + for (SourceInputIter it = s_begin; it != s_end; ++it) { + put(distance, *it, zero); + } + + dijkstra_shortest_paths_no_init(g, s_begin, s_end, predecessor, distance, + weight, index_map, compare, combine, zero, vis, + color); + } + + // Initialize distances and call breadth first search + template + inline void + dijkstra_shortest_paths + (const VertexListGraph& g, + typename graph_traits::vertex_descriptor s, + PredecessorMap predecessor, DistanceMap distance, WeightMap weight, + IndexMap index_map, + Compare compare, Combine combine, DistInf inf, DistZero zero, + DijkstraVisitor vis, ColorMap color) + { + dijkstra_shortest_paths(g, &s, &s + 1, predecessor, distance, weight, + index_map, compare, combine, inf, zero, + vis, color); + } + + // Initialize distances and call breadth first search + template + inline void + dijkstra_shortest_paths + (const VertexListGraph& g, + SourceInputIter s_begin, SourceInputIter s_end, + PredecessorMap predecessor, DistanceMap distance, WeightMap weight, + IndexMap index_map, + Compare compare, Combine combine, DistInf inf, DistZero zero, + DijkstraVisitor vis) + { + dijkstra_shortest_paths(g, s_begin, s_end, predecessor, distance, + weight, index_map, + compare, combine, inf, zero, vis, + no_named_parameters()); + } + + // Initialize distances and call breadth first search + template + inline void + dijkstra_shortest_paths + (const VertexListGraph& g, + typename graph_traits::vertex_descriptor s, + PredecessorMap predecessor, DistanceMap distance, WeightMap weight, + IndexMap index_map, + Compare compare, Combine combine, DistInf inf, DistZero zero, + DijkstraVisitor vis) + { + dijkstra_shortest_paths(g, &s, &s + 1, predecessor, distance, + weight, index_map, + compare, combine, inf, zero, vis); + } + + namespace detail { + + // Handle defaults for PredecessorMap and + // Distance Compare, Combine, Inf and Zero + template + inline void + dijkstra_dispatch2 + (const VertexListGraph& g, + typename graph_traits::vertex_descriptor s, + DistanceMap distance, WeightMap weight, IndexMap index_map, + const Params& params) + { + // Default for predecessor map + dummy_property_map p_map; + + typedef typename property_traits::value_type D; + D inf = choose_param(get_param(params, distance_inf_t()), + (std::numeric_limits::max)()); + + dijkstra_shortest_paths + (g, s, + choose_param(get_param(params, vertex_predecessor), p_map), + distance, weight, index_map, + choose_param(get_param(params, distance_compare_t()), + std::less()), + choose_param(get_param(params, distance_combine_t()), + closed_plus(inf)), + inf, + choose_param(get_param(params, distance_zero_t()), + D()), + choose_param(get_param(params, graph_visitor), + make_dijkstra_visitor(null_visitor())), + params); + } + + template + inline void + dijkstra_dispatch1 + (const VertexListGraph& g, + typename graph_traits::vertex_descriptor s, + DistanceMap distance, WeightMap weight, IndexMap index_map, + const Params& params) + { + // Default for distance map + typedef typename property_traits::value_type D; + typename std::vector::size_type + n = is_default_param(distance) ? num_vertices(g) : 1; + std::vector distance_map(n); + + detail::dijkstra_dispatch2 + (g, s, choose_param(distance, make_iterator_property_map + (distance_map.begin(), index_map, + distance_map[0])), + weight, index_map, params); + } + } // namespace detail + + // Named Parameter Variant + template + inline void + dijkstra_shortest_paths + (const VertexListGraph& g, + typename graph_traits::vertex_descriptor s, + const bgl_named_params& params) + { + // Default for edge weight and vertex index map is to ask for them + // from the graph. Default for the visitor is null_visitor. + detail::dijkstra_dispatch1 + (g, s, + get_param(params, vertex_distance), + choose_const_pmap(get_param(params, edge_weight), g, edge_weight), + choose_const_pmap(get_param(params, vertex_index), g, vertex_index), + params); + } + +} // namespace boost + +#ifdef BOOST_GRAPH_USE_MPI +# include +#endif + +#endif // BOOST_GRAPH_DIJKSTRA_HPP diff -Nru cgal-4.4/include/CGAL/boost/graph/Euler_operations.h cgal-4.5/include/CGAL/boost/graph/Euler_operations.h --- cgal-4.4/include/CGAL/boost/graph/Euler_operations.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/boost/graph/Euler_operations.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,1257 @@ +// Copyright (c) 2014 GeometryFactory (France). All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Philipp Moeller + +#ifndef CGAL_EULER_OPERATIONS_H +#define CGAL_EULER_OPERATIONS_H + +#include + +#include + +#include +#include +#include + +namespace CGAL { + +namespace EulerImpl { + +template +typename boost::graph_traits::halfedge_descriptor +join_face(typename boost::graph_traits::halfedge_descriptor h, + Graph& g) +{ + typedef typename boost::graph_traits Traits; + typedef typename Traits::halfedge_descriptor halfedge_descriptor; + + typedef typename Traits::face_descriptor face_descriptor; + + + halfedge_descriptor hop = opposite(h,g); + halfedge_descriptor hprev = prev(h, g), gprev = prev(hop, g); + face_descriptor f = face(h, g), f2 = face(hop, g); + + internal::remove_tip(hprev, g); + + internal::remove_tip(gprev, g); + + if(! is_border(hop,g)){ + remove_face(f2, g); + } + bool fnull = is_border(h,g); + + + halfedge_descriptor hprev2 = hprev; + while(hprev2 != gprev) { + hprev2 = next(hprev2, g); + set_face(hprev2, f, g); + } + + if (! fnull) + set_halfedge(f, hprev, g); + set_halfedge(target(hprev,g), hprev, g); + set_halfedge(target(gprev,g), gprev, g); + // internal::set_constant_vertex_is_border(g, target(h, g)); + // internal::set_constant_vertex_is_border(g, target(opposite(h, g), g)); + + remove_edge(edge(h, g), g); + return hprev; + +} +} // namespace EulerImpl + + + namespace Euler { +/// \ingroup PkgBGLEulerOperations +/// @{ + +/** + * joins the two vertices incident to `h`, (that is `source(h, g)` and + * `target(h, g)`) and removes `source(h,g)`. Returns the predecessor + * of `h` around the vertex, i.e., `prev(opposite(h,g))`. The + * invariant `join_vertex(split_vertex(h,g),g)` returns `h`. The + * time complexity is linear in the degree of the vertex removed. + * + * \image html join_vertex.svg + * + * \tparam Graph must be a model of `MutableFaceGraph` + * + * \param g the graph + * \param h the halfedge which incident vertices are joint + * + * \returns `prev(opposite(h,g))` + * + * \pre The size of the faces incident to `h` and `opposite(h,g)` is at least 4. + * + * \post `source(h, g)` is invalidated + * \post `h` is invalidated + * + * \sa `split_vertex()` + */ +template +typename boost::graph_traits::halfedge_descriptor +join_vertex(typename boost::graph_traits::halfedge_descriptor h, + Graph& g) +{ + typedef typename boost::graph_traits Traits; + typedef typename Traits::halfedge_descriptor halfedge_descriptor; + typedef typename Traits::vertex_descriptor vertex_descriptor; + typedef Halfedge_around_target_iterator halfedge_around_vertex_iterator; + + halfedge_descriptor hop = opposite(h, g) + , hprev = prev(hop, g) + , gprev = prev(h, g) + , hnext = next(hop, g) + , gnext = next(h, g); + vertex_descriptor v_to_remove = target(hop, g) + , v = target(h, g); + + // this assertion fires needlessly + // CGAL_precondition(std::distance( + // halfedges_around_face(e, g).first, + // halfedges_around_face(e, g).second) >= 4); + + CGAL_assertion( halfedge(v_to_remove, v, g).first == h ); + + halfedge_around_vertex_iterator ieb, iee; + for(boost::tie(ieb, iee) = halfedges_around_target(hop, g); ieb != iee; ++ieb) { + CGAL_assertion( target(*ieb,g) == v_to_remove); + set_target(*ieb ,v , g); + } + + set_next(hprev, hnext, g); + set_next(gprev, gnext, g); + set_halfedge(v, gprev, g); + // internal::set_constant_vertex_is_border(g, v); + + remove_edge(edge(h, g), g); + remove_vertex(v_to_remove, g); + + return hprev; +} + + + +/** + * splits the target vertex `v` of `h1` and `h2`, and connects the new vertex + * and `v` with a new edge. Let `hnew` be `opposite(next(h1, g), g)` after the + * split. The split regroups the halfedges around the two vertices. The + * edge sequence `hnew`, `opposite(next(h2, g), g)`, ..., `h1` + * remains around the old vertex, while the halfedge sequence + * `opposite(hnew, g)`, `opposite(next(h1, g), g)` (before the + * split), ..., `h2` is regrouped around the new vertex. The split + * returns `hnew`, i.e., the new edge incident to vertex `v`. The + * time is proportional to the distance from `h1` to `h2` around the + * vertex. + * + * \image html split_vertex.svg + * + * \tparam Graph must be a model of `MutableFaceGraph` + * + * \param g the graph + * \param h1 halfedge descriptor + * \param h2 halfedge descriptor + * + * \returns `hnew` + * + * \pre `target(h1, g) == target(h2, g)`, that is `h1` and `h2` are incident to the same vertex + * \pre `h1 != h2`, that is no antennas + * + * \sa `join_vertex()` + * + */ +template +typename boost::graph_traits::halfedge_descriptor +split_vertex(typename boost::graph_traits::halfedge_descriptor h1, + typename boost::graph_traits::halfedge_descriptor h2, + Graph& g) +{ + CGAL_assertion(h1 != h2); + CGAL_assertion(target(h1, g) == target(h2, g)); + + typename boost::graph_traits::halfedge_descriptor + hnew = halfedge(add_edge(g), g), + hnewopp = opposite(hnew, g); + typename boost::graph_traits::vertex_descriptor + vnew = add_vertex(g); + internal::insert_halfedge(hnew, h2, g); + internal::insert_halfedge(hnewopp, h1, g); + set_target(hnew, target(h1, g), g); + + typename boost::graph_traits::halfedge_descriptor + end = hnewopp; + do + { + set_target(hnewopp, vnew, g); + hnewopp = opposite(next(hnewopp, g), g); + } while (hnewopp != end); + + internal::set_vertex_halfedge(hnew, g); + // internal::set_constant_vertex_is_border(g, target(hnew, g)); + internal::set_vertex_halfedge(hnewopp, g); + // internal::set_constant_vertex_is_border(g, target(hnewopp, g)); + return hnew; +} + +/** + * splits the halfedge `h` into two halfedges inserting a new vertex that is a copy of `vertex(opposite(h,g),g)`. + * Is equivalent to `opposite(split_vertex( prev(h,g), opposite(h,g),g), g)`. + * \returns the new halfedge `hnew` pointing to the inserted vertex. The new halfedge is followed by the old halfedge, i.e., `next(hnew,g) == h`. + */ +template +typename boost::graph_traits::halfedge_descriptor +split_edge(typename boost::graph_traits::halfedge_descriptor h, Graph& g) +{ return opposite(split_vertex(prev(h,g), opposite(h,g),g), g); } + + +/** + * joins the two faces incident to `h` and `opposite(h,g)`. + * The faces may be holes. + * + * If `Graph` is a model of `MutableFaceGraph` + * the face incident to `opposite(h,g)` is removed. + * + * `join_face()` and `split_face()` are inverse operations, that is + * `join_face(split_face(h,g),g)` returns `h`. + * + * \image html join_face.svg + * + * \tparam Graph must be a model of `MutableFaceGraph`. + * \param g the graph + * \param h the halfedge incident to one of the faces to be joined. + * + * \returns `prev(h,g)` + * + * \pre `out_degree(source(h,g)), g)) >= 3` + * \pre `out_degree(target(h,g)) >= 3` + * + * \sa `split_face()` + */ +template +typename boost::graph_traits::halfedge_descriptor +join_face(typename boost::graph_traits::halfedge_descriptor h, + Graph& g) +{ + return EulerImpl::join_face(h,g); +} + + + +/** + * splits the face incident to `h1` and `h2`. Creates the opposite + * halfedges `h3` and `h4`, such that `next(h1,g) == h3` and `next(h2,g) == h4`. + * Performs the inverse operation to `join_face()`. + * + * If `Graph` is a model of `MutableFaceGraph` and if the update of faces is not disabled + * a new face incident to `h4` is added. + * + * \image html split_face.svg + * + * \tparam Graph must be a model of `MutableFaceGraph` + * + * \param g the graph + * \param h1 + * \param h2 + * + * \returns `h3` + * + * \pre `h1` and `h2` are incident to the same face + * \pre `h1 != h2` + * \pre `next(h1,g) != h2` and `next(h2,g) != h1` (no loop) + */ +template +typename boost::graph_traits::halfedge_descriptor +split_face(typename boost::graph_traits::halfedge_descriptor h1, + typename boost::graph_traits::halfedge_descriptor h2, + Graph& g) +{ + typedef typename boost::graph_traits Traits; + typedef typename Traits::halfedge_descriptor halfedge_descriptor; + typedef typename Traits::face_descriptor face_descriptor; + halfedge_descriptor hnew = halfedge(add_edge(g), g); + face_descriptor fnew = add_face(g); + internal::insert_tip( hnew, h2, g); + internal::insert_tip( opposite(hnew, g), h1, g); + set_face( hnew, face(h1,g), g); + internal::set_face_in_face_loop(opposite(hnew,g), fnew, g); + set_halfedge(face(hnew,g), hnew, g); + set_halfedge(face(opposite(hnew,g),g), opposite(hnew,g), g); + return hnew; +} + + +/** + * glues the cycle of halfedges of `h1` and `h2` together. + * The vertices in the cycle of `h2` get removed. + * If `h1` or `h2` are not border halfedges their faces get removed. + * The vertices on the face cycle of `h1` get removed. + * The invariant `join_loop(h1, split_loop(h1,h2,h3,g), g)` returns `h1` and keeps + * the graph unchanged. + * + * \image html join_loop.svg + * + * \tparam Graph must be a `MutableFaceGraph` + * + * \returns `h1`. + * + * \pre The faces incident to `h` and `g` are different and have equal number of edges. + */ +template +typename boost::graph_traits::halfedge_descriptor +join_loop(typename boost::graph_traits::halfedge_descriptor h1, + typename boost::graph_traits::halfedge_descriptor h2, + Graph& g) +{ + typedef typename boost::graph_traits Traits; + typedef typename Traits::halfedge_descriptor halfedge_descriptor; + + CGAL_precondition( is_border(h1,g) || face(h1, g) != face(h2, g)); + if (! is_border(h1,g)) + remove_face(face(h1, g), g); + if (! is_border(h2,g)) + remove_face(face(h2,g), g); + halfedge_descriptor hi = h1; + halfedge_descriptor gi = h2; + CGAL_assertion_code( std::size_t termination_count = 0;) + do { + CGAL_assertion( ++termination_count != 0); + halfedge_descriptor hii = hi; + halfedge_descriptor gii = gi; + hi = next(hi, g); + // gi = find_prev(gi); // Replaced by search around vertex. + set_face( hii, face( opposite(gii, g), g), g); + set_halfedge(face(hii, g), hii, g); + remove_vertex(target(opposite(gii, g), g), g); + if ( next(opposite(next(opposite(gii,g), g), g), g) == gii) { + gi = opposite(next(opposite(gii,g),g), g); + } else { + set_next(hii, next(opposite(gii,g), g), g); + gii = opposite(next(opposite(gii, g), g), g); + set_target( gii, target(hii, g), g); + while ( next(opposite(next(gii, g), g), g) != gi) { + CGAL_assertion( ++termination_count != 0); + gii = opposite(next(gii,g), g); + set_target( gii, target(hii, g), g); + } + gi = opposite(next(gii,g), g); + set_next(gii, hi, g); + } + } while ( hi != h1); + CGAL_assertion( gi == h2); + do { + halfedge_descriptor gii = gi; + gi = next(gi, g); + remove_edge(edge(gii,g), g); + } while ( gi != h2); + return h1; +} + + +/** + * cuts the graph along the cycle `(h1,h2,h3)` changing the genus + * (halfedge `h3` runs on the backside of the three dimensional figure below). + * Three new vertices, three new pairs of halfedges, + * and two new triangular faces are created. + * + * `h1`, `h2`, and `h3` will be incident to the first new face. + * + * Note that `split_loop()` does not deal with properties of new vertices, halfedges, and faces. + * + * \image html split_loop.svg + * + * \tparam Graph must be a `MutableFaceGraph` + * + * \returns the halfedge incident to the second new face. + * + * \pre `h1`, `h2`, and `h3` denote distinct, consecutive halfedges of the graph + * and form a cycle: i.e., `target(h1) == target(opposite(h2,g),g)`, … , + * `target(h3,g) == target(opposite(h1,g),g)`. + * \pre The six faces incident to `h1`, `h2`, and `h3` are all distinct. + */ + template +typename boost::graph_traits::halfedge_descriptor +split_loop(typename boost::graph_traits::halfedge_descriptor h1, + typename boost::graph_traits::halfedge_descriptor h2, + typename boost::graph_traits::halfedge_descriptor h3, + Graph& g) +{ + typedef typename boost::graph_traits Traits; + typedef typename Traits::halfedge_descriptor halfedge_descriptor; + typedef typename Traits::face_descriptor face_descriptor; + + halfedge_descriptor h = h1, i = h2, j = h3; + CGAL_precondition( h != i); + CGAL_precondition( h != j); + CGAL_precondition( i != j); + CGAL_precondition( target(h,g) == target(opposite(i,g),g)); + CGAL_precondition( target(i,g) == target(opposite(j,g),g)); + CGAL_precondition( target(j,g) == target(opposite(h,g),g)); + // Create a copy of the triangle. + halfedge_descriptor hnew = internal::copy(h,g); + halfedge_descriptor inew = internal::copy(i,g); + halfedge_descriptor jnew = internal::copy(j,g); + internal::close_tip( hnew, add_vertex(g), g); + internal::close_tip( inew, add_vertex(g), g); + internal::close_tip( jnew, add_vertex(g), g); + internal::insert_tip( opposite(inew, g), hnew, g); + internal::insert_tip( opposite(jnew, g), inew, g); + internal::insert_tip( opposite(hnew, g), jnew, g); + // Make the new incidences with the old stucture. + CGAL_assertion_code( std::size_t termination_count = 0;) + if ( next(h,g) != i) { + halfedge_descriptor nh = next(h, g); + set_next(h, i, g); + set_next(hnew, nh, g); + nh = opposite(nh, g); + while ( next(nh, g) != i) { + CGAL_assertion( ++termination_count != 0); + set_target( nh, target(hnew,g), g); + nh = opposite(next(nh, g), g); + } + set_target( nh, target(hnew,g), g); + set_next(nh, inew, g); + } + if ( next(i, g) != j) { + halfedge_descriptor nh = next(i, g); + set_next(i, j, g); + set_next(inew, nh, g); + nh = opposite(nh,g); + while ( next(nh,g) != j) { + CGAL_assertion( ++termination_count != 0); + set_target( nh, target(inew, g), g); + nh = opposite(next(nh, g), g); + } + set_target( nh, target(inew, g), g); + set_next(nh, jnew, g); + + } + if ( next(j,g) != h) { + halfedge_descriptor nh = next(j, g); + set_next(j, h, g); + set_next(jnew, nh, g); + nh = opposite(nh, g); + while ( next(nh,g) != h) { + CGAL_assertion( ++termination_count != 0); + set_target( nh, target(jnew, g), g); + nh = opposite(next(nh, g), g); + } + set_target(nh, target(jnew, g), g); + set_next(nh, hnew, g); + } + // Fill the holes with two new faces. + face_descriptor f = add_face(g); + set_face( h, f, g); + set_face( i, f, g); + set_face( j, f, g); + set_halfedge(face(h,g), h, g); + f = add_face(g); + set_face( opposite(hnew, g), f, g); + set_face( opposite(inew, g), f, g); + set_face( opposite(jnew, g), f, g); + set_halfedge(face(opposite(hnew,g),g), opposite(hnew,g), g); + // Take care of maybe changed halfedge pointers. + set_halfedge(face(hnew, g), hnew, g); + set_halfedge(face(inew, g), inew, g); + set_halfedge(face(jnew, g), jnew, g); + set_halfedge(target(hnew, g), hnew, g); + set_halfedge(target(inew, g), inew, g); + set_halfedge(target(jnew, g), jnew, g); + return opposite(hnew, g); +} + + +/** + * removes the incident face of `h` and changes all halfedges incident to the face into border halfedges + * or removes them from the graph if they were already border halfedges. + * + * If this creates isolated vertices they get removed as well. + * + * \image html remove_face.svg + * \image html remove_face_and_vertex.svg + * + * \tparam Graph must be a model of `MutableFaceGraph` + * + * \pre `h` is not a border halfedge + * + * \sa `make_hole()` for a more specialized variant. + */ +template< typename Graph > +void remove_face(typename boost::graph_traits::halfedge_descriptor h, + Graph& g) +{ + typedef typename boost::graph_traits Traits; + typedef typename Traits::halfedge_descriptor halfedge_descriptor; + typedef typename Traits::face_descriptor face_descriptor; + + CGAL_precondition(! is_border(h,g)); + face_descriptor f = face(h, g); + + halfedge_descriptor end = h; + do { + internal::set_border(h,g); + halfedge_descriptor nh = next(h, g); + bool h_border = is_border(opposite(h, g),g); + bool nh_bborder = is_border(opposite(nh, g),g); + + if(h_border && nh_bborder && next(opposite(nh, g), g) == opposite(h, g)) { + remove_vertex(target(h, g), g); + if(h != end) + remove_edge(edge(h, g), g); + } else { + if(nh_bborder) { + internal::set_vertex_halfedge(opposite(next(opposite(nh, g), g), g), g); + internal::remove_tip(h, g); + //internal::set_constant_vertex_is_border(g, target(h, g)); + } + if(h_border) { + internal::set_vertex_halfedge(opposite(next(h, g), g), g); + internal::remove_tip(prev(opposite(h, g), g), g); + //internal::set_constant_vertex_is_border(g, target(prev(opposite(h, g), g), g)); + if(h != end) + remove_edge(edge(h, g), g); + } + } + h = nh; + } while(h != end); + remove_face(f, g); + if(is_border(opposite(h, g),g)) + remove_edge(edge(h, g), g); +} + + /** + * removes the incident face of `h` and changes all halfedges incident to the face into border halfedges. See `remove_face(g,h)` for a more generalized variant. + * \returns `h`. + * + * \pre None of the incident halfedges of the face is a border halfedge. + */ +template< typename Graph> +void make_hole(typename boost::graph_traits::halfedge_descriptor h, + Graph& g) +{ + typedef typename boost::graph_traits Traits; + typedef typename Traits::face_descriptor face_descriptor; + typedef Halfedge_around_face_iterator halfedge_around_face_iterator; + + CGAL_precondition(! is_border(h,g)); + face_descriptor fd = face(h, g); + halfedge_around_face_iterator hafib, hafie; + for(boost::tie(hafib, hafie) = halfedges_around_face(h, g); + hafib != hafie; + ++hafib){ + CGAL_assertion(! is_border(opposite(*hafib,g),g)); + internal::set_border(*hafib, g); + } + remove_face(fd,g); +} + + + +/** + * creates a barycentric triangulation of the face incident to `h`. Creates a new + * vertex and connects it to each vertex incident to `h` and splits `face(h, g)` + * into triangular faces. + * `h` remains incident to + * the original face. The time complexity is linear in the size of the face. + * + * \image html add_center_vertex.svg + * + * \returns the halfedge `next(h, g)` after the + * operation, i.e., a halfedge pointing to the new vertex. + * + * Note that `add_center_vertex()` does not deal with properties of new vertices, + * halfedges, and faces. + * \pre `h` is not a border halfedge. + * + * \param g the graph + * \param h halfedge descriptor + * \tparam Graph must be a model of `MutableFaceGraph` + * \sa `remove_center_vertex()` + * + */ +template +typename boost::graph_traits::halfedge_descriptor +add_center_vertex(typename boost::graph_traits::halfedge_descriptor h, + Graph& g) +{ + typedef typename boost::graph_traits Traits; + typedef typename Traits::vertex_descriptor vertex_descriptor; + typedef typename Traits::halfedge_descriptor halfedge_descriptor; + typedef typename Traits::face_descriptor face_descriptor; + + halfedge_descriptor hnew = halfedge(add_edge(g),g); + vertex_descriptor vnew = add_vertex(g); + internal::close_tip(hnew, vnew, g); + internal::insert_tip(opposite(hnew, g), h, g); + set_face(hnew, face(h, g), g); + set_halfedge(face(h,g), h, g); + halfedge_descriptor h2 = next(opposite(hnew, g), g); + while ( next(h2, g) != hnew) { + halfedge_descriptor gnew = halfedge(add_edge(g),g); + internal::insert_tip( gnew, hnew, g); + internal::insert_tip( opposite(gnew,g), h2, g); + face_descriptor fnew = add_face(g); + set_face( h2, fnew, g); + set_face( gnew, fnew, g); + set_face( next(gnew,g), fnew, g); + set_halfedge(face(h2, g), h2, g); + h2 = next(opposite(gnew, g), g); + } + set_face(next(hnew,g), face(hnew,g), g); + internal::set_vertex_halfedge(hnew, g); + return hnew; +} + +/** + * removes the vertex `target(h, g)` and all incident halfedges thereby merging all + * incident faces. The resulting face may not be triangulated. + * This function is the inverse operation of `add_center_vertex()`. + * The invariant `h == remove_center_vertex(add_center_vertex(h,g),g)` + * holds, if `h` is not a border halfedge. + * + * \image html remove_center_vertex.svg + * + * \tparam Graph must be a model of `MutableFaceGraph` + * + * \param g the graph + * \param h halfedge descriptor + * + * \returns `prev(h, g)` + * + * \pre None of the incident faces of `target(h,g)` is a + * hole. There are at least two distinct faces incident to the faces + * that are incident to `target(h,g)`. (This prevents the + * operation from collapsing a volume into two faces glued together + * with opposite orientations, such as would happen with any vertex of + * a tetrahedron.) + * + * \sa `add_center_vertex()` + * + */ +template +typename boost::graph_traits::halfedge_descriptor +remove_center_vertex(typename boost::graph_traits::halfedge_descriptor h, + Graph& g) +{ + typedef typename boost::graph_traits Traits; + typedef typename Traits::halfedge_descriptor halfedge_descriptor; + + // h points to the vertex that gets removed + halfedge_descriptor h2 = opposite(next(h, g), g); + halfedge_descriptor hret = prev(h, g); + while (h2 != h) { + halfedge_descriptor gprev = prev(h2, g); + internal::set_vertex_halfedge(gprev, g); + internal::remove_tip(gprev, g); + + remove_face(face(h2, g), g); + + halfedge_descriptor gnext = opposite(next(h2, g), g); + remove_edge(edge(h2,g), g); + h2 = gnext; + } + internal::set_vertex_halfedge(hret, g); + internal::remove_tip(hret, g); + remove_vertex(target(h, g), g); + remove_edge(edge(h, g), g); + internal::set_face_in_face_loop(hret, face(hret, g), g); + set_halfedge(face(hret, g), hret, g); + return hret; +} + +/** + * appends a new face to the border halfedge `h2` by connecting + * the tip of `h2` with the tip of `h1` with two new halfedges and a new vertex + * and creating a new face that is incident to `h2`. + * Note that `add_vertex_and_face_to_border()` does not deal with properties of new + * vertices, halfedges, and faces. + * + * \image html add_vertex_and_face_to_border.svg + * + * \tparam Graph must be a model of `MutableFaceGraph` + * + * \returns the halfedge of the new edge that is incident to the new face + * and the new vertex. + * + * \pre `h1` and `h2` are border halfedges + * \pre `h1 != h2`, + * \pre `h1` and `h2` are on the same border. + */ +template +typename boost::graph_traits::halfedge_descriptor +add_vertex_and_face_to_border(typename boost::graph_traits::halfedge_descriptor h1, + typename boost::graph_traits::halfedge_descriptor h2, + Graph& g) +{ + typename boost::graph_traits::vertex_descriptor v = add_vertex(g); + typename boost::graph_traits::face_descriptor f = add_face(g); + typename boost::graph_traits::edge_descriptor e1 = add_edge(g); + typename boost::graph_traits::edge_descriptor e2 = add_edge(g); + typename boost::graph_traits::halfedge_descriptor he1= halfedge(e1, g); + typename boost::graph_traits::halfedge_descriptor he2= halfedge(e2, g); + typename boost::graph_traits::halfedge_descriptor ohe1= opposite(he1, g); + typename boost::graph_traits::halfedge_descriptor ohe2= opposite(he2, g); + + set_next(he1, next(h1,g),g); + set_next(h1,ohe1,g); + set_target(he1,target(h1,g),g); + set_target(ohe1,v,g); + + set_next(he2,he1,g); + set_next(ohe1,ohe2,g); + set_target(he2,v,g); + set_halfedge(v,ohe1,g); + set_next(ohe2,next(h2,g),g); + set_target(ohe2,target(h2,g),g); + set_next(h2,he2,g); + internal::set_border(ohe1,g); + internal::set_border(ohe2,g); + + CGAL::Halfedge_around_face_iterator hafib,hafie; + for(boost::tie(hafib, hafie) = halfedges_around_face(he1, g); + hafib != hafie; + ++hafib){ + set_face(*hafib, f, g); + } + set_halfedge(f, he1, g); + return ohe2; +} + + +/** + * appends a new face incident to the border halfedge `h1` and `h2` by connecting the vertex `target(h2,g)` + * and the vertex `target(h1,g)` with a new halfedge, and filling this separated part of the hole + * with a new face, such that the new face is incident to `h2`. + * + * \image html add_face_to_border.svg + * + * \tparam Graph must be a model of `MutableFaceGraph` + * + * \returns the halfedge of the new edge that is incident to the new face. + * + * \pre `h1` and `h2` are border halfedges, + * \pre `h1 != h2`, + * \pre `next(h1,g) != h2`, + * \pre `h1` and `h2` are on the same border. + */ +template +typename boost::graph_traits::halfedge_descriptor +add_face_to_border(typename boost::graph_traits::halfedge_descriptor h1, + typename boost::graph_traits::halfedge_descriptor h2, + Graph& g) +{ + CGAL_precondition(is_border(h1,g) == true); + CGAL_precondition(is_border(h2,g) == true); + CGAL_precondition(h1 != h2); + CGAL_precondition(next(h1, g) != h2); + + typename boost::graph_traits::face_descriptor f = add_face(g); + typename boost::graph_traits::edge_descriptor e = add_edge(g); + typename boost::graph_traits::halfedge_descriptor + newh= halfedge(e, g) + , newhop = opposite(newh, g); + + set_next(newhop, next(h2, g), g); + + set_next(h2, newh, g); + + set_next(newh, next(h1, g), g); + + set_next(h1, newhop, g); + + set_target(newh, target(h1, g), g); + set_target(newhop, target(h2, g), g); + + // make the vertices point to the border halfedge + set_halfedge(target(h2,g), newhop, g); + internal::set_border(newhop, g); + + CGAL::Halfedge_around_face_iterator hafib,hafie; + for(boost::tie(hafib, hafie) = halfedges_around_face(newh, g); + hafib != hafie; + ++hafib){ + set_face(*hafib, f, g); + } + + set_halfedge(f, newh, g); + + return newh; +} + + +/** + * collapses an edge in a graph. + * + * \tparam Graph must be a model of `MutableFaceGraph` + * Let `v0` and `v1` be the source and target vertices, and let `e` and `e'` be the halfedges of edge `v0v1`. + * + * For `e`, let `en` and `ep` be the next and previous + * halfedges, that is `en = next(e, g)`, `ep = prev(e, g)`, and let + * `eno` and `epo` be their opposite halfedges, that is + * `eno = opposite(en, g)` and `epo = opposite(ep, g)`. + * Analoguously, for `e'` define `en'`, `ep'`, `eno'`, and `epo'`. + * + * Then, after the collapse of edge `v0v1` the following holds for `e` (and analoguously for `e'`) + * + *
    + *
  • The edge `v0v1` is no longer in `g`. + *
  • The faces incident to edge `v0v1` are no longer in `g`. + *
  • Either `v0`, or `v1` is no longer in `g` while the other remains. + * Let `vgone` be the removed vertex and `vkept` be the remaining vertex. + *
  • If `e` was a border halfedge, that is `is_border(e, g) == true`, then `next(ep,g) == en`, and `prev(en,g) == ep`. + *
  • If `e` was not a border halfedge, that is `is_border(e, g) == false`, then `ep` and `epo` are no longer in `g` while `en` and `eno` are kept in `g`. + *
  • For all halfedges `hv` in `halfedges_around_target(vgone, g)`, `target(*hv, g) == vkept` and `source(opposite(*hv, g), g) == vkept`. + *
  • No other incidence information has changed in `g`. + *
+ * \returns vertex `vkept` (which can be either `v0` or `v1`). + * \pre g must be a triangulated graph + * \pre `safisfies_link_condition(v0v1,g) == true`. + */ +template +typename boost::graph_traits::vertex_descriptor +collapse_edge(typename boost::graph_traits::edge_descriptor v0v1, + Graph& g) +{ + typedef boost::graph_traits< Graph > Traits; + typedef typename Traits::vertex_descriptor vertex_descriptor; + typedef typename Traits::halfedge_descriptor halfedge_descriptor; + + halfedge_descriptor pq = halfedge(v0v1,g); + halfedge_descriptor qp = opposite(pq, g); + halfedge_descriptor pt = opposite(prev(pq, g), g); + halfedge_descriptor qb = opposite(prev(qp, g), g); + + bool lTopFaceExists = ! is_border(pq,g); + bool lBottomFaceExists = ! is_border(qp,g); + bool lTopLeftFaceExists = lTopFaceExists && ! is_border(pt,g); + bool lBottomRightFaceExists = lBottomFaceExists && ! is_border(qb,g); + + CGAL_precondition( !lTopFaceExists || (lTopFaceExists && ( degree(target(pt, g), g) > 2 ) ) ) ; + CGAL_precondition( !lBottomFaceExists || (lBottomFaceExists && ( degree(target(qb, g), g) > 2 ) ) ) ; + + vertex_descriptor q = target(pq, g); + vertex_descriptor p = source(pq, g); +#if 0 + if(lTopLeftFaceExists && lBottomRightFaceExists){ + std::cerr << " // do it low level" << std::endl; + halfedge_descriptor qt = next(pq,g); + halfedge_descriptor pb = next(qp,g); + halfedge_descriptor ppt = prev(pt,g); + halfedge_descriptor pqb = prev(qb,g); + if(halfedge(q,g) == pq){ + set_halfedge(q, pqb,g); + } + vertex_descriptor t = target(qt,g); + if(halfedge(t,g) == pt){ + set_halfedge(t, qt,g); + } + vertex_descriptor b = target(pb,g); + if(halfedge(b,g) == qb){ + set_halfedge(t, pb,g); + } + set_face(qt, face(pt,g),g); + set_halfedge(face(qt,g),qt,g); + set_face(pb, face(qb,g),g); + set_halfedge(face(pb,g),pb,g); + set_next(qt, next(pt,g),g); + set_next(pb, next(qb,g),g); + set_next(ppt, qt,g); + set_next(pqb,pb,g); + remove_face(face(pq,g),g); + remove_face(face(qp,g),g); + remove_edge(v0v1,g); + remove_edge(edge(pt,g),g); + remove_edge(edge(qb,g),g); + remove_vertex(p,g); + Halfedge_around_target_circulator beg(ppt,g), end(pqb,g); + while(beg != end){ + assert(target(*beg,g) == p); + set_target(*beg,q,g); + --beg; + } + + return q; + // return the vertex kept + } +#endif + + bool lP_Erased = false, lQ_Erased = false ; + + if ( lTopFaceExists ) + { + CGAL_precondition( ! is_border(opposite(pt, g),g) ) ; // p-q-t is a face of the mesh + if ( lTopLeftFaceExists ) + { + //CGAL_ECMS_TRACE(3, "Removing p-t E" << pt.idx() << " (V" + // << p.idx() << "->V" << target(pt, g).idx() + // << ") by joining top-left face" ) ; + + join_face(pt,g); + } + else + { + //CGAL_ECMS_TRACE(3, "Removing p-t E" << pt.idx() << " (V" << p.idx() + // << "->V" << target(pt, g).idx() << ") by erasing top face" ) ; + + remove_face(opposite(pt, g),g); + + if ( !lBottomFaceExists ) + { + //CGAL_ECMS_TRACE(3, "Bottom face doesn't exist so vertex P already removed" ) ; + + lP_Erased = true ; + } + } + } + + if ( lBottomFaceExists ) + { + CGAL_precondition( ! is_border(opposite(qb, g),g) ) ; // p-q-b is a face of the mesh + if ( lBottomRightFaceExists ) + { + //CGAL_ECMS_TRACE(3, "Removing q-b E" << qb.idx() << " (V" + // << q.idx() << "->V" << target(qb, g).idx() + // << ") by joining bottom-right face" ) ; + + join_face(qb,g); + } + else + { + //CGAL_ECMS_TRACE(3, "Removing q-b E" << qb.idx() << " (V" + // << q.idx() << "->V" << target(qb, g).idx() + // << ") by erasing bottom face" ) ; + + remove_face(opposite(qb, g),g); + + if ( !lTopFaceExists ) + { + //CGAL_ECMS_TRACE(3, "Top face doesn't exist so vertex Q already removed" ) ; + lQ_Erased = true ; + } + } + } + + CGAL_assertion( !lP_Erased || !lQ_Erased ) ; + + if ( !lP_Erased && !lQ_Erased ) + { + //CGAL_ECMS_TRACE(3, "Removing vertex P by joining pQ" ) ; + + join_vertex(pq,g); + lP_Erased = true ; + } + + CGAL_assertion(is_valid(g)); + + return lP_Erased ? q : p ; +} + + +template +typename boost::graph_traits::vertex_descriptor +collapse_edge(typename boost::graph_traits::edge_descriptor v0v1, + Graph& g + , EdgeIsConstrainedMap Edge_is_constrained_map) +{ + typedef boost::graph_traits< Graph > Traits; + typedef typename Traits::vertex_descriptor vertex_descriptor; + typedef typename Traits::halfedge_descriptor halfedge_descriptor; + + halfedge_descriptor pq = halfedge(v0v1,g); + CGAL_assertion( !get(Edge_is_constrained_map,v0v1) ); + + halfedge_descriptor qp = opposite(pq,g); + halfedge_descriptor pt = opposite(prev(pq,g),g); + halfedge_descriptor qb = opposite(prev(qp,g),g); + halfedge_descriptor tq = opposite(next(pq,g),g); + halfedge_descriptor bp = opposite(next(qp,g),g); + + bool lTopFaceExists = ! is_border(pq,g) ; + bool lBottomFaceExists = ! is_border(qp,g) ; + + vertex_descriptor q = target(pq,g); + vertex_descriptor p = source(pq,g); + + //used to collect edges to remove from the surface + halfedge_descriptor edges_to_erase[2]; + halfedge_descriptor* edges_to_erase_ptr=edges_to_erase; + + // If the top facet exists, we need to choose one out of the two edges which one disappears: + // p-t if it is not constrained and t-q otherwise + if ( lTopFaceExists ) + { + if ( !get(Edge_is_constrained_map,edge(pt,g)) ) + { + *edges_to_erase_ptr++=pt; + } + else + { + *edges_to_erase_ptr++=tq; + } + } + + // If the bottom facet exists, we need to choose one out of the two edges which one disappears: + // q-b if it is not constrained and b-p otherwise + if ( lBottomFaceExists ) + { + if ( !get(Edge_is_constrained_map,edge(qb,g)) ) + { + *edges_to_erase_ptr++=qb; + } + else{ + *edges_to_erase_ptr++=bp; + } + } + + if (lTopFaceExists && lBottomFaceExists) + { + if ( face(edges_to_erase[0],g) == face(edges_to_erase[1],g) + && (! is_border(edges_to_erase[0],g)) ) + { + // the vertex is of valence 3 and we simply need to remove the vertex + // and its indicent edges + bool lP_Erased = false; + halfedge_descriptor edge = + next(edges_to_erase[0],g) == edges_to_erase[1]? + edges_to_erase[0]:edges_to_erase[1]; + if (target(edge,g) == p) + lP_Erased = true; + remove_center_vertex(edge,g); + return lP_Erased? q : p; + } + else + { + if (!(is_border(edges_to_erase[0],g))) + join_face(edges_to_erase[0],g); + else + remove_face(opposite(edges_to_erase[0],g),g); + if (!is_border(edges_to_erase[1],g)) + join_face(edges_to_erase[1],g); + else + remove_face(opposite(edges_to_erase[1],g),g); + join_vertex(pq,g); + return q; + } + } + else + { + if (lTopFaceExists) + { + if (!(is_border(edges_to_erase[0],g))){ + join_face(edges_to_erase[0],g); + join_vertex(pq,g); + return q; + } + bool lQ_Erased = is_border(opposite(next(pq,g),g),g); + remove_face(opposite(edges_to_erase[0],g),g); + return lQ_Erased?p:q; + } + + if (! (is_border(edges_to_erase[0],g))){ + join_face(edges_to_erase[0],g); + join_vertex(qp,g); + return p; + } + bool lP_Erased= is_border(opposite(next(qp,g),g),g); + remove_face(opposite(edges_to_erase[0],g),g); + return lP_Erased?q:p; + }; +} + + +template +void +flip_edge(typename boost::graph_traits::halfedge_descriptor h, + Graph& g) +{ + typedef boost::graph_traits Traits; + typedef typename Traits::vertex_descriptor vertex_descriptor; + typedef typename Traits::halfedge_descriptor halfedge_descriptor; + typedef typename Traits::face_descriptor face_descriptor; + + vertex_descriptor s = source(h,g); + vertex_descriptor t = target(h,g); + halfedge_descriptor nh = next(h,g), nnh = next(nh,g), oh = opposite(h,g), noh = next(oh,g), nnoh = next(noh,g); + vertex_descriptor s2 = target(nh,g), t2 = target(noh,g); + face_descriptor fh = face(h,g), foh = face(oh,g); + + assert(fh != Traits::null_face() && foh != Traits::null_face()); + + if(halfedge(s,g) == oh){ + set_halfedge(s,nnh,g); + } + if(halfedge(t,g) == h){ + set_halfedge(t,nnoh,g); + } + set_next(h,nnoh,g); + set_next(oh,nnh,g); + set_target(h,t2,g); + set_target(oh,s2,g); + set_next(nh,h,g); + set_next(noh,oh,g); + set_next(nnoh,nh,g); + set_next(nnh,noh,g); + set_face(nnoh,fh,g); + set_face(nnh,foh,g); + set_halfedge(fh,h,g); + set_halfedge(foh,oh,g); +} + + + ///\cond DO_NOT_INCLUDE_IN_SUBMISSION + + /** collapses `edge(coll,g)` and removes the edges `edge(rm0,g)` and `edge(rm1,g)` + * \todo implement + * \todo finish doc + */ +#if 0 + +template +typename boost::graph_traits::vertex_descriptor +collapse_edge(typename boost::graph_traits::halfedge_descriptor coll, + typename boost::graph_traits::halfedge_descriptor rm0, + typename boost::graph_traits::halfedge_descriptor rm1, + Graph& g) +{} + +#endif + + ///\endcond + + + + +/** + * \returns `true` if `e` satisfies the *link condition* \cgalCite{degn-tpec-98}, which guarantees that the surface is also 2-manifold after the edge collapse. + */ + template +bool + safisfies_link_condition(typename boost::graph_traits::edge_descriptor e, + Graph& g) +{ + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef CGAL::Halfedge_around_source_iterator out_edge_iterator; + + halfedge_descriptor v0_v1 = halfedge(e,g); + halfedge_descriptor v1_v0 = opposite(v0_v1,g); + + vertex_descriptor v0 = target(v1_v0,g), v1 = target(v0_v1,g); + + vertex_descriptor vL = target(next(v0_v1,g),g); + vertex_descriptor vR = target(next(v1_v0,g),g); + + out_edge_iterator eb1, ee1 ; + out_edge_iterator eb2, ee2 ; + + + // The following loop checks the link condition for v0_v1. + // Specifically, that for every vertex 'k' adjacent to both 'p and 'q', 'pkq' is a face of the mesh. + // + for ( boost::tie(eb1,ee1) = halfedges_around_source(v0,g) ; eb1 != ee1 ; ++ eb1 ) + { + halfedge_descriptor v0_k = *eb1; + + if ( v0_k != v0_v1 ) + { + vertex_descriptor k = target(v0_k,g); + + for ( boost::tie(eb2,ee2) = halfedges_around_source(k,g) ; eb2 != ee2 ; ++ eb2 ) + { + halfedge_descriptor k_v1 = *eb2; + + if ( target(k_v1,g) == v1 ) + { + // At this point we know p-q-k are connected and we need to determine if this triangle is a face of the mesh. + // + // Since the mesh is known to be triangular there are at most two faces sharing the edge p-q. + // + // If p->q is NOT a border edge, the top face is p->q->t where t is target(next(p->q)) + // If q->p is NOT a border edge, the bottom face is q->p->b where b is target(next(q->p)) + // + // If k is either t or b then p-q-k *might* be a face of the mesh. It won't be if k==t but p->q is border + // or k==b but q->b is a border (because in that case even though there exists triangles p->q->t (or q->p->b) + // they are holes, not faces) + // + + bool lIsFace = ( vL == k && (! is_border(v0_v1,g)) ) + || ( vR == k && (! is_border(v1_v0,g)) ) ; + + + + if ( !lIsFace ) + { + // CGAL_ECMS_TRACE(3," k=V" << get(Vertex_index_map,k) << " IS NOT in a face with p-q. NON-COLLAPSABLE edge." ) ; + return false ; + } + else + { + //CGAL_ECMS_TRACE(4," k=V" << get(Vertex_index_map,k) << " is in a face with p-q") ; + } + } + } + } + } + + + if ( is_border(v0_v1,g) ) + { + if ( next(next(next(v0_v1,g),g),g) == v0_v1 ) + { + //CGAL_ECMS_TRACE(3," p-q belongs to an open triangle. NON-COLLAPSABLE edge." ) ; + return false ; + } + } + else if ( is_border(v1_v0,g) ) + { + if ( next(next(next(v1_v0,g),g),g) == v1_v0 ) + { + //CGAL_ECMS_TRACE(3," p-q belongs to an open triangle. NON-COLLAPSABLE edge." ) ; + return false ; + } + } + else + { + if ( is_border(v0,g) && is_border(v1,g) ) + { + //CGAL_ECMS_TRACE(3," both p and q are boundary vertices but p-q is not. NON-COLLAPSABLE edge." ) ; + return false ; + } + else + { + if ( is_tetrahedron(v0_v1,g) ) + { + //CGAL_ECMS_TRACE(3," p-q belongs to a tetrahedron. NON-COLLAPSABLE edge." ) ; + return false ; + } + } + } + + + return true ; +} + + +/// @} + +} // CGAL + +} // CGAL + + +#endif /* CGAL_EULER_OPERATIONS_H */ diff -Nru cgal-4.4/include/CGAL/boost/graph/graph_concepts.h cgal-4.5/include/CGAL/boost/graph/graph_concepts.h --- cgal-4.4/include/CGAL/boost/graph/graph_concepts.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/boost/graph/graph_concepts.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,203 @@ +// Copyright (c) 2014 GeometryFactory (France). All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Philipp Moeller + +#ifndef CGAL_GRAPH_CONCEPTS_H +#define CGAL_GRAPH_CONCEPTS_H + +#include +#include + +namespace CGAL { +namespace concepts { + +BOOST_concept(HalfedgeGraph,(G)) + : boost::concepts::Graph +{ + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + + BOOST_CONCEPT_USAGE(HalfedgeGraph) + { + BOOST_CONCEPT_ASSERT((boost::DefaultConstructible)); + BOOST_CONCEPT_ASSERT((boost::EqualityComparable)); + BOOST_CONCEPT_ASSERT((boost::Assignable)); + + + e = edge(h, g); + h = halfedge(e, g); + h = halfedge(v, g); + hp = halfedge(u, v, g); + h = opposite(h, g); + v = source(h, g); + v = target(h, g); + h = next(h, g); + h = prev(h, g); + const_constraints(g); + } + + void const_constraints(const G& cg) + { + e = edge(h, cg); + h = halfedge(e, cg); + h = halfedge(v, cg); + hp = halfedge(u, v, cg); + h = opposite(h, cg); + v = source(h, cg); + v = target(h, cg); + h = next(h, cg); + h = prev(h, cg); + } + + G g; + + typename boost::graph_traits::vertex_descriptor v, u; + typename boost::graph_traits::edge_descriptor e; + typename boost::graph_traits::halfedge_descriptor h; + std::pair hp; +}; + +BOOST_concept(HalfedgeListGraph,(G)) + : HalfedgeGraph +{ + typedef typename boost::graph_traits::halfedge_iterator halfedge_iterator; + typedef typename boost::graph_traits::halfedges_size_type halfedges_size_type; + + BOOST_CONCEPT_USAGE(HalfedgeListGraph) + { + // BOOST_CONCEPT_ASSERT((boost::BidirectionalIterator)); + h_num = num_halfedges(g); + p = halfedges(g); + this->h = *p.first; + const_constraints(g); + } + + void const_constraints(const G& cg) + { + h_num = num_halfedges(cg); + p = halfedges(cg); + this->h = *p.first; + } + + G g; + halfedges_size_type h_num; + std::pair p; +}; + +BOOST_concept(FaceGraph,(G)) + : HalfedgeGraph +{ + typedef typename boost::graph_traits::face_descriptor face_descriptor; + + BOOST_CONCEPT_USAGE(FaceGraph) + { + BOOST_CONCEPT_ASSERT((boost::DefaultConstructible)); + BOOST_CONCEPT_ASSERT((boost::EqualityComparable)); + BOOST_CONCEPT_ASSERT((boost::Assignable)); + + f = face(h, g); + h = halfedge(f, g); + boost::graph_traits::null_face(); + const_constraints(g); + } + + void const_constraints(const G& cg) + { + f = face(h, cg); + h = halfedge(f, cg); + } + + G g; + face_descriptor f; + typename boost::graph_traits::halfedge_descriptor h; +}; + +BOOST_concept(FaceListGraph,(G)) + : FaceGraph +{ + typedef typename boost::graph_traits::face_iterator face_iterator; + typedef typename boost::graph_traits::faces_size_type faces_size_type; + + BOOST_CONCEPT_USAGE(FaceListGraph) + { + // BOOST_CONCEPT_ASSERT((boost::BidirectionalIterator)); + p = faces(g); + nf = num_faces(g); + this->f = *p.first; + const_constraints(g); + } + + void const_constraints(const G& cg) + { + p = faces(cg); + nf = num_faces(cg); + this->f = *p.first; + } + + G g; + std::pair p; + typename boost::graph_traits::faces_size_type nf; +}; + +BOOST_concept(MutableFaceGraph,(G)) + : FaceGraph +{ + BOOST_CONCEPT_USAGE(MutableFaceGraph) + { + f = add_face(g); + remove_face(f, g); + set_face(h, f, g); + set_halfedge(f, h, g); + } + G g; + typename boost::graph_traits::face_descriptor f; + typename boost::graph_traits::halfedge_descriptor h; +}; + +BOOST_concept(MutableHalfedgeGraph,(G)) + : HalfedgeGraph +{ + BOOST_CONCEPT_USAGE(MutableHalfedgeGraph) + { + v = add_vertex(g); + remove_vertex(v, g); + e = add_edge(g); + remove_edge(e, g); + set_target(h1, v, g); + set_next(h1, h2, g); + set_halfedge(v, h1, g); + } + + G g; + typename boost::graph_traits::edge_descriptor e; + typename boost::graph_traits::vertex_descriptor v; + typename boost::graph_traits::halfedge_descriptor h1, h2; +}; + +} // concepts + +using CGAL::concepts::HalfedgeGraphConcept; +using CGAL::concepts::HalfedgeListGraphConcept; +using CGAL::concepts::FaceGraphConcept; +using CGAL::concepts::FaceListGraphConcept; +using CGAL::concepts::MutableFaceGraphConcept; +using CGAL::concepts::MutableHalfedgeGraphConcept; +} // CGAL + +#include + +#endif /* CGAL_GRAPH_CONCEPTS_H */ diff -Nru cgal-4.4/include/CGAL/boost/graph/Graph_geometry.h cgal-4.5/include/CGAL/boost/graph/Graph_geometry.h --- cgal-4.4/include/CGAL/boost/graph/Graph_geometry.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/boost/graph/Graph_geometry.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,233 @@ +// Copyright (c) 2014 GeometryFactory (France). All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Andreas Fabri + +#ifndef CGAL_GRAPH_GEOMETRY_H +#define CGAL_GRAPH_GEOMETRY_H + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace CGAL { + +/// \ingroup PkgBGLGraphGeometry +/// @{ + +template +void calculate_face_normals(const HalfedgeGraph& g, + PositionMap pm, + NormalMap nm) +{ + typedef boost::graph_traits GraphTraits; + typedef typename GraphTraits::face_iterator face_iterator; + typedef typename GraphTraits::edge_descriptor edge_descriptor; + typedef typename GraphTraits::enclosure_iterator enc_iterator; + typedef typename boost::property_traits::value_type position; + typedef typename boost::property_traits::value_type normal; + + face_iterator fb, fe; + for(boost::tie(fb, fe) = faces(g); fb != fe; ++fb) + { + edge_descriptor edg = edge(*fb, g); + edge_descriptor edgb = edg; + enc_iterator eb, ee; + boost::tie(eb, ee) = enclosure(*fb, g); + + position p0 = pm[target(edg, g)]; + edg = next(edg, g); + position p1 = pm[target(edg, g)]; + edg = next(edg, g); + position p2 = pm[target(edg, g)]; + edg = next(edg, g); + + if(edg == edgb) { + // triangle + nm[*fb] = CGAL::unit_normal(p1, p2, p0); + } else { + normal n(CGAL::NULL_VECTOR); + do { + n = n + CGAL::normal(p1, p2, p0); + p0 = p1; + p1 = p2; + + edg = next(edg, g); + p2 = pm[target(edg, g)]; + } while(edg != edgb); + + nm[*fb] = n / CGAL::sqrt(n.squared_length()); + } + } +} + +namespace internal { +template +typename Kernel_traits::Kernel::FT +dot(const T& t1, const T& t2) +{ + return t1[0]*t2[0] + + t1[1]*t2[1] + + t1[2]*t2[2]; +} + +} // internal + +template +void calculate_vertex_normals(const HalfedgeGraph& g, + Position position_map, + Normal normal_map, + Boundary boundary_map) +{ + typedef boost::graph_traits GraphTraits; + typedef typename GraphTraits::vertex_iterator vertex_iterator; + typedef typename GraphTraits::out_edge_iterator out_edge_iterator; + + typedef typename boost::property_traits::value_type normal; + typedef typename boost::property_traits::value_type position; + typedef typename Kernel_traits::Kernel::FT FT; + + vertex_iterator vb, ve; + for(boost::tie(vb, ve) = vertices(g); vb != ve; ++vb) + { + normal nn(CGAL::NULL_VECTOR); + + position p0 = position_map[*vb]; + out_edge_iterator oeb, oee; + + for(boost::tie(oeb, oee) = out_edges(*vb, g); oeb != oee; ++oeb) + { + if(!boundary_map[target(*oeb, g)]) + { + position p1 = position_map[target(*oeb, g)]; + p1 = p1 - (p0 - CGAL::ORIGIN); + FT length = CGAL::sqrt((p1 - CGAL::ORIGIN).squared_length()); + if(length > (std::numeric_limits::min)()) + p1 = CGAL::ORIGIN + ((p1 - CGAL::ORIGIN) * 1.0 / length); + + position p2 = position_map[source(prev(halfedge(*oeb, g), g), g)]; + p2 = p2 - (p0 - CGAL::ORIGIN); + length = CGAL::sqrt((p2 - CGAL::ORIGIN).squared_length()); + if(length > (std::numeric_limits::min)()) + p2 = CGAL::ORIGIN + ((p2 - CGAL::ORIGIN) * 1.0 / length); + + FT cosine + = internal::dot(p1, p2) / CGAL::sqrt(internal::dot(p1, p1) * internal::dot(p2, p2)); + if(cosine < -1.0) cosine = -1.0; + else if(cosine > 1.0) cosine = 1.0; + + FT angle = std::acos(cosine); + + normal n = CGAL::unit_normal(position(CGAL::ORIGIN), p1, p2); + n = n * angle; + nn = nn + n; + } + } + + FT length = CGAL::sqrt(nn.squared_length()); + if(length > (std::numeric_limits::min)()) + nn = nn * (1.0 / length); + normal_map[*vb] = nn; + } +} + + +/// Convenience function that calls `triangle()` with the property map +/// obtained by `get(CGAL::vertex_point, g)`. +template +typename Kernel_traits< + typename boost::property_traits< + typename boost::property_map< HalfedgeGraph, CGAL::vertex_point_t>::const_type + >::value_type + >::Kernel::Triangle_3 +triangle(const HalfedgeGraph& g, + typename boost::graph_traits::halfedge_descriptor h) { + return triangle(g, h, get(CGAL::vertex_point, g)); +} + + +/// `triangle()` returns a `Triangle_3` constructed +/// from the positions of the `vertex_descriptors` around the face +/// incident to `h` in counter-clockwise direction. +/// +/// The Kernel of the returned `Triangle_3` is the same as the +/// Kernel of the `value_type` of the. +/// +/// \pre The face incident to h is triangular. +/// +/// \tparam PositionMap must be a model of \ref ReadablePropertyMap. +/// Its value_type must be a model of `Kernel::Point_3` +/// \tparam HalfedgeGraph must be a model of \ref HalfedgeGraph. +/// \param g The graph +/// \param h The halfedge +/// \param pm The map used to find the vertices of the triangle. +template +typename Kernel_traits::value_type>::Kernel::Triangle_3 +triangle(const HalfedgeGraph& g, + typename boost::graph_traits::halfedge_descriptor h, + const PositionMap& pm) +{ + BOOST_CONCEPT_ASSERT((HalfedgeGraphConcept)); + + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + + typedef typename Kernel_traits< + typename boost::property_traits::value_type + >::Kernel::Triangle_3 Triangle_3; + + CGAL_assertion_code( + typename boost::graph_traits::halfedge_descriptor h2 = h; + ) + vertex_descriptor u = target(h,g); + h = next(h,g); + vertex_descriptor v = target(h,g); + h = next(h,g); + vertex_descriptor w = target(h,g); + h = next(h,g); + + // are we really looking at a triangle? + CGAL_assertion(h == h2); + + return Triangle_3(get(pm, u), + get(pm,v), + get(pm,w)); +} + + + + +/// @} + +} // CGAL + +#endif /* CGAL_GRAPH_GEOMETRY_H */ diff -Nru cgal-4.4/include/CGAL/boost/graph/graph_traits_CombinatorialMap.h cgal-4.5/include/CGAL/boost/graph/graph_traits_CombinatorialMap.h --- cgal-4.4/include/CGAL/boost/graph/graph_traits_CombinatorialMap.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/boost/graph/graph_traits_CombinatorialMap.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,331 @@ +// Copyright (c) 2013 CNRS and LIRIS' Establishments (France). All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Pierre Talbot + +#ifndef CGAL_BOOST_GRAPH_GRAPH_TRAITS_CMAP_H +#define CGAL_BOOST_GRAPH_GRAPH_TRAITS_CMAP_H + +#include +#include + +#include +#include +#include + +#include +#include + +#define CGAL_CMAP_BASE_TEMPLATE_ARGS template +#define CGAL_CMAP_BASE_TYPE CGAL::Combinatorial_map_base + +#define CGAL_CMAP_TEMPLATE_ARGS template +#define CGAL_CMAP_TYPE CGAL::Combinatorial_map + +#define CGAL_LCC_TEMPLATE_ARGS template < unsigned int d_, unsigned int ambient_dim, \ + class Traits_, \ + class Items_, \ + class Alloc_, \ + template\ + class CMap> + +#define CGAL_LCC_TYPE CGAL::Linear_cell_complex + +namespace CGAL { + + +template +class CMap_dart_handle_iterator +{ +public: + typedef Dart_Iterator Iterator; + + typedef typename CMap::Dart_handle Dart_handle; + + typedef CMap_dart_handle_iterator Self; + + typedef typename std::iterator_traits::iterator_category iterator_category; + typedef typename std::iterator_traits::difference_type difference_type; + typedef Dart_handle value_type; + typedef value_type reference; + typedef value_type pointer; + +public: + +// OPERATIONS Forward Category +// --------------------------- + + bool operator==( const Self& i) const { return ( nt == i.nt); } + bool operator!=( const Self& i) const { return !(nt == i.nt );} + value_type operator*() const { return nt; } + value_type operator->() { return nt; } + + Self& operator++() { + ++nt; + return *this; + } + + Self operator++(int) { + Self tmp = *this; + ++*this; + return tmp; + } + + CMap_dart_handle_iterator(Iterator iter): + nt(iter) + {} + + // Default constructor + CMap_dart_handle_iterator(): + nt(get_default(), Dart_handle()) + {} + + CMap_dart_handle_iterator(const CMap_dart_handle_iterator& it) + : nt(it.nt) + {} + + CMap_dart_handle_iterator& operator=(const CMap_dart_handle_iterator& it) + { + nt = const_cast(it).nt; + } + +private: + Iterator nt; + static CMap& get_default() + { + static CMap* m = new CMap(); + return *m; + } +}; + +template +struct EdgeHandle : Dart_handle +{ + EdgeHandle() : Dart_handle(NULL){} + EdgeHandle(const Dart_handle& h): Dart_handle(h) + {} +}; + +template +struct CMap_Base_graph_traits +{ + +public : + struct CMap_graph_traversal_category : public virtual boost::bidirectional_graph_tag, + public virtual boost::vertex_list_graph_tag, + public virtual boost::edge_list_graph_tag + {}; + + // Expose types required by the boost::Graph concept. + typedef typename CMap::Dart_handle vertex_descriptor; + typedef EdgeHandle edge_descriptor; + typedef boost::directed_tag directed_category; + typedef boost::allow_parallel_edge_tag edge_parallel_category; + typedef CMap_graph_traversal_category traversal_category; + + // Expose types required by the boost::IncidenceGraph concept. + typedef CMap_dart_handle_iterator > out_edge_iterator; + typedef typename CMap::size_type degree_size_type; + + // Expose types required by the boost::BidirectionalGraph concept. + typedef CMap_dart_handle_iterator > in_edge_iterator; + typedef typename CMap::size_type edges_size_type; + + // Expose types required by the boost::EdgeListGraph concept. + typedef CMap_dart_handle_iterator edge_iterator; + + // Expose types required by the boost::VertexListGraph concept. + typedef typename CMap::size_type vertices_size_type; + typedef CMap_dart_handle_iterator::iterator> vertex_iterator; +}; + +} //namespace CGAL + +namespace boost{ + +// Specialization of graph_traits for Combinatorial map. +CGAL_CMAP_TEMPLATE_ARGS +struct graph_traits +: CGAL::CMap_Base_graph_traits +{}; + +CGAL_CMAP_TEMPLATE_ARGS +struct graph_traits +: CGAL::CMap_Base_graph_traits +{}; + +// Specialization of graph_traits for Combinatorial map base. +CGAL_CMAP_BASE_TEMPLATE_ARGS +struct graph_traits +: CGAL::CMap_Base_graph_traits +{}; + +CGAL_CMAP_BASE_TEMPLATE_ARGS +struct graph_traits +: CGAL::CMap_Base_graph_traits +{}; + +// Specialization of graph_traits for Linear Cell Complex. +CGAL_LCC_TEMPLATE_ARGS +struct graph_traits +: CGAL::CMap_Base_graph_traits +{}; + +CGAL_LCC_TEMPLATE_ARGS +struct graph_traits +: CGAL::CMap_Base_graph_traits +{}; + +// Expression required by the boost::IncidenceGraph concept. + +CGAL_CMAP_BASE_TEMPLATE_ARGS +typename boost::graph_traits::vertex_descriptor +source(typename boost::graph_traits::edge_descriptor e, const CGAL_CMAP_BASE_TYPE&) +{ + return e; +} + +CGAL_CMAP_BASE_TEMPLATE_ARGS +typename boost::graph_traits::vertex_descriptor +target(typename boost::graph_traits::edge_descriptor e, const CGAL_CMAP_BASE_TYPE&) +{ + return e->opposite(); +} + +CGAL_CMAP_BASE_TEMPLATE_ARGS +std::pair::out_edge_iterator, + typename boost::graph_traits::out_edge_iterator> +out_edges(typename boost::graph_traits::vertex_descriptor u, const CGAL_CMAP_BASE_TYPE& cm) +{ + typedef typename boost::graph_traits::out_edge_iterator iter_type; + + CGAL_CMAP_BASE_TYPE& cmap = const_cast(cm); + + return std::make_pair( + cmap.template darts_of_cell<0>(u).begin(), + cmap.template darts_of_cell<0>(u).end()); +} + +CGAL_CMAP_BASE_TEMPLATE_ARGS +typename boost::graph_traits::degree_size_type +out_degree(typename boost::graph_traits::vertex_descriptor u, const CGAL_CMAP_BASE_TYPE& cm) +{ + typedef typename boost::graph_traits::out_edge_iterator iter_type; + std::pair iter = out_edges(u, cm); + + typename boost::graph_traits::degree_size_type degree=0; + for(;iter.first != iter.second; ++(iter.first)) + ++degree; + return degree; +} + +// Expression required by the boost::BidirectionalGraph concept. + +CGAL_CMAP_BASE_TEMPLATE_ARGS +std::pair::in_edge_iterator, typename boost::graph_traits::in_edge_iterator> +in_edges(typename boost::graph_traits::vertex_descriptor v, const CGAL_CMAP_BASE_TYPE& cm) +{ + typedef typename boost::graph_traits::in_edge_iterator iter_type; + + CGAL_CMAP_BASE_TYPE& cmap = const_cast(cm); + + return std::make_pair + (cmap.darts_of_second_vertex(v).begin(), cmap.darts_of_second_vertex(v).end()); +} + +CGAL_CMAP_BASE_TEMPLATE_ARGS +typename boost::graph_traits::degree_size_type +in_degree(typename boost::graph_traits::vertex_descriptor v, const CGAL_CMAP_BASE_TYPE& cm) +{ + typedef typename boost::graph_traits::in_edge_iterator iter_type; + std::pair iter = in_edges(v, cm); + + typename boost::graph_traits::degree_size_type degree=0; + for(;iter.first != iter.second; ++(iter.first)) + ++degree; + return degree; +} + +// We suppose there are no loops. +CGAL_CMAP_BASE_TEMPLATE_ARGS +typename boost::graph_traits::degree_size_type +degree(typename boost::graph_traits::vertex_descriptor v, const CGAL_CMAP_BASE_TYPE& cm) +{ + return in_degree(v, cm) + out_degree(v, cm); +} + +// Expression required by the boost::VertexListGraph concept. + +CGAL_CMAP_BASE_TEMPLATE_ARGS +std::pair::vertex_iterator, typename boost::graph_traits::vertex_iterator> +vertices(const CGAL_CMAP_BASE_TYPE& cm) +{ + typedef typename boost::graph_traits::vertex_iterator iter_type; + + CGAL_CMAP_BASE_TYPE& cmap = const_cast(cm); + + return std::make_pair + (iter_type(cmap.template one_dart_per_cell<0>().begin()), + iter_type(cmap.template one_dart_per_cell<0>().end())); +} + +CGAL_CMAP_BASE_TEMPLATE_ARGS +typename boost::graph_traits::vertices_size_type +num_vertices(const CGAL_CMAP_BASE_TYPE& cm) +{ + CGAL_CMAP_BASE_TYPE& cmap = const_cast(cm); + return cmap.template one_dart_per_cell<0>().size(); +} + +// Expression required by the boost::EdgeListGraph concept. + +CGAL_CMAP_BASE_TEMPLATE_ARGS +std::pair::edge_iterator, typename boost::graph_traits::edge_iterator> +edges(const CGAL_CMAP_BASE_TYPE& cm) +{ + typedef typename boost::graph_traits::edge_iterator iter_type; + + CGAL_CMAP_BASE_TYPE& cmap = const_cast(cm); + + return std::make_pair + (iter_type(cmap.darts().begin()), + iter_type(cmap.darts().end())); +} + +CGAL_CMAP_BASE_TEMPLATE_ARGS +typename boost::graph_traits::edges_size_type +num_edges(const CGAL_CMAP_BASE_TYPE& cm) +{ + typedef typename boost::graph_traits::edge_iterator iter_type; + std::pair iter = edges(cm); + + typename boost::graph_traits::edges_size_type degree=0; + for(;iter.first != iter.second; ++(iter.first)) + ++degree; + return degree; +} + + +}// namespace boost + +#undef CGAL_CMAP_BASE_TEMPLATE_ARGS +#undef CGAL_CMAP_TEMPLATE_ARGS +#undef CGAL_CMAP_TYPE +#undef CGAL_CMAP_BASE_TYPE +#undef CGAL_LCC_TEMPLATE_ARGS +#undef CGAL_LCC_TYPE + +#endif // CGAL_BOOST_GRAPH_GRAPH_TRAITS_CMAP_H diff -Nru cgal-4.4/include/CGAL/boost/graph/graph_traits_HalfedgeDS.h cgal-4.5/include/CGAL/boost/graph/graph_traits_HalfedgeDS.h --- cgal-4.4/include/CGAL/boost/graph/graph_traits_HalfedgeDS.h 2013-07-06 19:00:27.000000000 +0000 +++ cgal-4.5/include/CGAL/boost/graph/graph_traits_HalfedgeDS.h 2014-08-29 13:58:16.000000000 +0000 @@ -13,7 +13,7 @@ // // $URL$ // $Id$ -// +// // // Author(s) : Andreas Fabri, Fernando Cacciola @@ -21,271 +21,197 @@ #define CGAL_BOOST_GRAPH_GRAPH_TRAITS_HALFEDGEDS_H #include -#include +#include +#include +#include + #include #include #include -#include +#include -namespace CGAL { +#include -template -class HDS_in_halfedge_circulator : public Circ -{ -private: - mutable E e; +#ifndef CGAL_NO_DEPRECATED_CODE +#include +#endif -public: +namespace CGAL { - typedef E value_type; - typedef E* pointer; - typedef E& reference; - - HDS_in_halfedge_circulator() - : Circ() - {} - - HDS_in_halfedge_circulator(Circ c) - : Circ(c) - {} +namespace internal { - const E& operator*() const - { - e = *this; - return e; - } -}; - -template -class HDS_out_halfedge_circulator : public Circ -{ +template +class Prevent_deref + : public boost::iterator_adaptor< + Prevent_deref + , I // base + , I // value + > +{ +public: + typedef boost::iterator_adaptor< + Prevent_deref + , I // base + , I // value + > Base; + // typedef typename Prevent_deref::iterator_adaptor_::reference reference; + typedef typename Base::reference reference; + Prevent_deref() : Base() {}; + Prevent_deref(const I& i) : Base(i) {}; private: - mutable E e; - -public: - - typedef E value_type; - typedef E* pointer; - typedef E& reference; - - HDS_out_halfedge_circulator() - : Circ() - {} - - HDS_out_halfedge_circulator(Circ c) - : Circ(c) - {} - - const E& operator*() const - { - e = *this; - e = e->opposite(); - return e; - } + friend class boost::iterator_core_access; + reference dereference() const { return const_cast::type&>(this->base_reference()); } }; - - -// The vertex iterator of the bgl must evaluate to a vertex handle, not to a vertex -template < class HDS, class Vertex_iterator, class Vertex_handle> -class HDS_all_vertices_iterator_base { -protected: - Vertex_iterator nt; -public: - typedef Vertex_iterator Iterator; - typedef HDS_all_vertices_iterator_base Self; - - typedef typename std::iterator_traits::iterator_category iterator_category; - typedef typename std::iterator_traits::difference_type difference_type; - typedef Vertex_handle value_type; - typedef value_type reference; - typedef value_type pointer; - -protected: - - HDS_all_vertices_iterator_base() {} - HDS_all_vertices_iterator_base( Iterator j) : nt(j) {} - -public: - - // OPERATIONS Forward Category - // --------------------------- - bool operator==( const Self& i) const { return ( nt == i.nt); } - bool operator!=( const Self& i) const { return !(nt == i.nt ); } - value_type operator*() const { return nt; } - value_type operator->() { return nt; } - - Self& operator++() { - ++nt; - return *this; +// a HDS_halfedge pretending to be an Edge +template +struct HDS_edge { + HDS_edge() : halfedge_() { } + + explicit HDS_edge(const Halfedge_handle& h) : halfedge_(h) {} + + bool operator==(const HDS_edge& other) const { + // equality is tricky, we are equal when both halfedges are the + // same or when the opposite halfedge of this is the same as + // halfedge_.other but we need to be careful not to apply this + // should this be the invalid halfedge or opposite is going to + // blow up + if(halfedge_ == other.halfedge_) { + return true; + } else if(halfedge_ != Halfedge_handle()) { // not default constructed + return halfedge_->opposite() == other.halfedge_; + } else { + // this is the invalid halfedge, it can only be equal to the + // invalid halfedge and this is covered by the first case + return false; + } } - Self operator++(int) { - Self tmp = *this; - ++*this; - return tmp; + bool operator!=(const HDS_edge& other) const { + return !(*this == other); } - Self& operator--() { - --nt; - return *this; - } - - Self operator--(int) { - Self tmp = *this; - --*this; - return tmp; + friend bool operator<(const HDS_edge& a,const HDS_edge& b) + { + if(a==b) return false; + return a.halfedge_ < b.halfedge_; } -}; - -template < class HDS > -class HDS_all_vertices_const_iterator - : public HDS_all_vertices_iterator_base -{ - typedef HDS_all_vertices_iterator_base Base ; - -public: - - typedef typename HDS::Vertex_const_iterator Iterator; - HDS_all_vertices_const_iterator() {} - HDS_all_vertices_const_iterator( Iterator j) : Base(j) {} -}; + // forward some function to avoid boilerplate and typedefs inside + // the free functions + HDS_edge next() { return HDS_edge(halfedge_->next()); } -template < class HDS > -class HDS_all_vertices_iterator - : public HDS_all_vertices_iterator_base -{ - typedef HDS_all_vertices_iterator_base Base ; - -public: + // this is potentially broken as it does not use the decorator to + // find prev, but we cannot instantiate the entire decorator + // without the full polyhedron type and taking all necessary + // template parameters seems overkill + HDS_edge prev() { return HDS_edge(halfedge_->prev()); } - typedef typename HDS::Vertex_iterator Iterator; + HDS_edge opposite() { return HDS_edge(halfedge_->opposite()); } - HDS_all_vertices_iterator() {} - HDS_all_vertices_iterator( Iterator j) : Base(j) {} -}; + // this is hacky, we don't know the actual type of the id and if we + // start adding decltype special cases we have to do it consistently + // up to the property map and maybe back down to Polyhedron. + std::size_t id() const { return halfedge_->id() / 2; } -template < class HDS, class Iterator_, class Value_type> -class HDS_all_edges_iterator_base { -protected: - Iterator_ nt; -public: - typedef Iterator_ Iterator; - typedef HDS_all_edges_iterator_base Self; + Halfedge_handle halfedge() const { return halfedge_; } - typedef typename std::iterator_traits::iterator_category iterator_category; - typedef typename std::iterator_traits::difference_type difference_type; - typedef Value_type value_type; - typedef value_type reference; - typedef value_type pointer; - -protected: + // save us some work to do function chaining + HDS_edge + opposite_next() { return HDS_edge(halfedge_->opposite()->next()); } - HDS_all_edges_iterator_base() {} - HDS_all_edges_iterator_base( Iterator j) : nt(j) {} + HDS_edge + next_opposite() { return HDS_edge(halfedge_->next()->opposite()); } -public: - - // OPERATIONS Forward Category - // --------------------------- + HDS_edge + prev_opposite() { return HDS_edge(halfedge_->prev()->opposite()); } + HDS_edge + opposite_prev() { return HDS_edge(halfedge_->opposite()->prev()); } - bool operator==( const Self& i) const { return ( nt == i.nt); } - bool operator!=( const Self& i) const { return !(nt == i.nt ); } - value_type operator*() const { return nt; } - value_type operator->() { return nt; } - - Self& operator++() { - ++nt; - return *this; - } - Self operator++(int) { - Self tmp = *this; - ++*this; - return tmp; - } - - Self& operator--() { - --nt; - return *this; - } - - Self operator--(int) { - Self tmp = *this; - --*this; - return tmp; - } +private: + Halfedge_handle halfedge_; }; -template < class HDS > -class HDS_all_halfedges_const_iterator - : public HDS_all_edges_iterator_base -{ - typedef HDS_all_edges_iterator_base Base ; - -public: - - typedef typename HDS::Halfedge_const_iterator Iterator; - - HDS_all_halfedges_const_iterator() {} - HDS_all_halfedges_const_iterator( Iterator j) : Base(j) {} +// make edge_descriptor hashable by default in Unique_hash_map +namespace handle{ + template + struct Hash_functor< HDS_edge > + { + std::size_t + operator()(const HDS_edge& edge) + { + Halfedge_handle he = edge.halfedge(); + if ( he < he->opposite() ) + return Hash_functor()(he); + return Hash_functor()(he->opposite()); + } + }; +} //end of namespace handle + +template +struct Construct_edge { + typedef HDS_edge result_type; + HDS_edge operator()(const Halfedge_handle& he) const + { return HDS_edge(he); } +}; + +template +struct Construct_edge_opposite { + typedef HDS_edge result_type; + HDS_edge operator()(const Halfedge_handle& he) const + { return HDS_edge(he->opposite()); } }; -template < class HDS > -class HDS_all_halfedges_iterator - : public HDS_all_edges_iterator_base -{ - typedef HDS_all_edges_iterator_base Base ; - -public: - - typedef typename HDS::Halfedge_iterator Iterator; +} // internal - HDS_all_halfedges_iterator() {} - HDS_all_halfedges_iterator( Iterator j) : Base(j) {} -}; - -template +template struct HDS_graph_traits { -public : - +private: struct HDS_graph_traversal_category : public virtual boost::bidirectional_graph_tag, public virtual boost::vertex_list_graph_tag, public virtual boost::edge_list_graph_tag {}; - typedef HDS_ HDS; +public: + typedef typename HDS::Vertex_handle vertex_descriptor; + typedef typename internal::HDS_edge edge_descriptor; + typedef typename HDS::Face_handle face_descriptor; + typedef typename HDS::Halfedge_handle halfedge_descriptor; - typedef typename HDS::Vertex_handle vertex_descriptor; - typedef typename HDS::Halfedge_handle edge_descriptor; - - typedef HDS_all_vertices_iterator vertex_iterator; - typedef HDS_all_halfedges_iterator edge_iterator; - -private: + typedef internal::Prevent_deref vertex_iterator; + typedef internal::Prevent_deref face_iterator; + typedef internal::Prevent_deref edge_iterator_i; + typedef internal::Prevent_deref halfedge_iterator; + + + + typedef boost::transform_iterator< + internal::Construct_edge, + edge_iterator_i, + edge_descriptor> edge_iterator; - typedef typename HDS::Halfedge_around_vertex_circulator Halfedge_around_vertex_circulator ; - - typedef HDS_out_halfedge_circulator out_edge_circulator ; - typedef HDS_in_halfedge_circulator in_edge_circulator ; - -public : - - typedef Counting_iterator out_edge_iterator; - typedef Counting_iterator in_edge_iterator; - - typedef boost::directed_tag directed_category; - typedef boost::disallow_parallel_edge_tag edge_parallel_category; + typedef Out_edge_iterator out_edge_iterator; + + typedef In_edge_iterator in_edge_iterator; + + typedef boost::undirected_tag directed_category; + typedef boost::disallow_parallel_edge_tag edge_parallel_category; typedef HDS_graph_traversal_category traversal_category; - + typedef typename HDS::size_type vertices_size_type; typedef vertices_size_type edges_size_type; + typedef vertices_size_type halfedges_size_type; typedef vertices_size_type degree_size_type; + typedef vertices_size_type faces_size_type; + + static vertex_descriptor null_vertex() { return vertex_descriptor(); } + static halfedge_descriptor null_halfedge() { return halfedge_descriptor(); } + static face_descriptor null_face() { return face_descriptor(); } }; diff -Nru cgal-4.4/include/CGAL/boost/graph/graph_traits_Polyhedron_3.h cgal-4.5/include/CGAL/boost/graph/graph_traits_Polyhedron_3.h --- cgal-4.4/include/CGAL/boost/graph/graph_traits_Polyhedron_3.h 2012-11-13 13:13:53.000000000 +0000 +++ cgal-4.5/include/CGAL/boost/graph/graph_traits_Polyhedron_3.h 2014-08-29 13:58:16.000000000 +0000 @@ -13,7 +13,7 @@ // // $URL$ // $Id$ -// +// // // Author(s) : Andreas Fabri, Fernando Cacciola @@ -27,7 +27,7 @@ #define CGAL_HDS_PARAM_ template < class Traits, class Items, class Alloc> class HDS // -// NOTE: The BGL algorithms are NOT const-correct: i.e., they take a "G const&" +// NOTE: The BGL algorithms are NOT const-correct: i.e., they take a "G const&" // but instantiate "graph_traits" instead of "graph_traits" // This is known Boost bug which will eventually be fixed, but in the meantime we need // to coerce both const and non-const specializations. @@ -39,118 +39,468 @@ // namespace boost -{ +{ template struct graph_traits< CGAL::Polyhedron_3 > : CGAL::HDS_graph_traits< CGAL::Polyhedron_3 > -{}; - +{ + typedef typename Gt::Point_3 vertex_property_type; +}; template struct graph_traits< CGAL::Polyhedron_3 const > : CGAL::HDS_graph_traits< CGAL::Polyhedron_3 > // See NOTE above! {}; - +} // namespace boost + +namespace CGAL { + template -typename graph_traits< CGAL::Polyhedron_3 const>::vertices_size_type +typename boost::graph_traits< CGAL::Polyhedron_3 const>::vertices_size_type num_vertices(const CGAL::Polyhedron_3& p) { return p.size_of_vertices(); } template -typename graph_traits< CGAL::Polyhedron_3 const>::edges_size_type +typename boost::graph_traits< CGAL::Polyhedron_3 const>::edges_size_type num_edges(const CGAL::Polyhedron_3& p) { - return p.size_of_halfedges() ; + return p.size_of_halfedges() / 2; } template -typename graph_traits< CGAL::Polyhedron_3 const>::degree_size_type -degree(typename graph_traits< CGAL::Polyhedron_3 const>::vertex_descriptor v, const CGAL::Polyhedron_3&) +typename boost::graph_traits< CGAL::Polyhedron_3 const>::degree_size_type +degree(typename boost::graph_traits< CGAL::Polyhedron_3 const>::vertex_descriptor v + , const CGAL::Polyhedron_3&) { - return v->vertex_degree() * 2 ; + return v->vertex_degree(); } template -typename graph_traits< CGAL::Polyhedron_3 const>::degree_size_type -out_degree(typename graph_traits< CGAL::Polyhedron_3 const>::vertex_descriptor v, const CGAL::Polyhedron_3&) +typename boost::graph_traits< CGAL::Polyhedron_3 const>::degree_size_type +out_degree(typename boost::graph_traits< CGAL::Polyhedron_3 const>::vertex_descriptor v + , const CGAL::Polyhedron_3&) { return v->vertex_degree(); } template -typename graph_traits< CGAL::Polyhedron_3 const>::degree_size_type -in_degree(typename graph_traits< CGAL::Polyhedron_3 const>::vertex_descriptor v, const CGAL::Polyhedron_3&) +typename boost::graph_traits< CGAL::Polyhedron_3 const>::degree_size_type +in_degree(typename boost::graph_traits< CGAL::Polyhedron_3 const>::vertex_descriptor v + , const CGAL::Polyhedron_3&) { return v->vertex_degree(); } +template +typename boost::graph_traits< CGAL::Polyhedron_3 const>::vertex_descriptor +source(typename boost::graph_traits< CGAL::Polyhedron_3 const>::edge_descriptor e + , const CGAL::Polyhedron_3 & ) +{ + return e.halfedge()->opposite()->vertex(); +} template -typename graph_traits< CGAL::Polyhedron_3 const>::vertex_descriptor -source(typename graph_traits< CGAL::Polyhedron_3 const>::edge_descriptor e, const CGAL::Polyhedron_3 & ) +typename boost::graph_traits< CGAL::Polyhedron_3 const>::vertex_descriptor +target(typename boost::graph_traits< CGAL::Polyhedron_3 const>::edge_descriptor e + , const CGAL::Polyhedron_3 & ) { - return e->opposite()->vertex(); + return e.halfedge()->vertex(); } template -typename graph_traits< CGAL::Polyhedron_3 const>::vertex_descriptor -target(typename graph_traits< CGAL::Polyhedron_3 const>::edge_descriptor e, const CGAL::Polyhedron_3 & ) +std::pair< + typename boost::graph_traits< CGAL::Polyhedron_3 const>::edge_descriptor + , bool> +edge(typename boost::graph_traits< CGAL::Polyhedron_3 const>::vertex_descriptor u + , typename boost::graph_traits< CGAL::Polyhedron_3 const>::vertex_descriptor v + , const CGAL::Polyhedron_3 &) { - return e->vertex(); + typedef CGAL::Polyhedron_3 P; + typedef typename P::Halfedge_around_vertex_circulator Circ; + typedef boost::graph_traits< P > Traits; + typedef typename Traits::edge_descriptor edge; + + // circulate around the inedges of u + Circ c(u->halfedge()), d(u->halfedge()); + if(c != 0) { + do { + if(c->opposite()->vertex() == v) { + return std::make_pair(edge(c->opposite()), true); + } + } while (++c != d); + } + + return std::make_pair(edge(), false); } template -inline std::pair const>::vertex_iterator - ,typename graph_traits< CGAL::Polyhedron_3 const>::vertex_iterator - > +inline std::pair const>::vertex_iterator + ,typename boost::graph_traits< CGAL::Polyhedron_3 const>::vertex_iterator + > vertices( const CGAL::Polyhedron_3& p) { - typedef typename graph_traits< CGAL::Polyhedron_3 const>::vertex_iterator Iter; + typedef typename boost::graph_traits< CGAL::Polyhedron_3 const>::vertex_iterator Iter; CGAL::Polyhedron_3& ncp = const_cast&>(p); return std::make_pair( Iter(ncp.vertices_begin()), Iter(ncp.vertices_end()) ); } template -inline std::pair const>::edge_iterator - ,typename graph_traits< CGAL::Polyhedron_3 const>::edge_iterator - > +inline std::pair const>::edge_iterator + ,typename boost::graph_traits< CGAL::Polyhedron_3 const>::edge_iterator + > edges( const CGAL::Polyhedron_3& p) { - typedef typename graph_traits< CGAL::Polyhedron_3 const>::edge_iterator Iter; + typedef typename boost::graph_traits< CGAL::Polyhedron_3 const>::edge_iterator_i Iter_i; + typedef typename boost::graph_traits< CGAL::Polyhedron_3 const>::edge_iterator Iter; CGAL::Polyhedron_3& ncp = const_cast&>(p); - return std::make_pair( Iter(ncp.halfedges_begin()), Iter(ncp.halfedges_end()) ); + return std::make_pair( Iter(Iter_i(ncp.halfedges_begin())), + Iter(Iter_i(ncp.halfedges_end()) )); } template -inline std::pair const>::in_edge_iterator - ,typename graph_traits< CGAL::Polyhedron_3 const>::in_edge_iterator - > -in_edges( typename graph_traits< CGAL::Polyhedron_3 const>::vertex_descriptor u, const CGAL::Polyhedron_3& g) +inline std::pair const>::in_edge_iterator + ,typename boost::graph_traits< CGAL::Polyhedron_3 const>::in_edge_iterator + > +in_edges( typename boost::graph_traits< CGAL::Polyhedron_3 const>::vertex_descriptor u + , const CGAL::Polyhedron_3& p) { - typename CGAL::Polyhedron_3::Halfedge_around_vertex_circulator ec = u->vertex_begin(); - typename graph_traits< CGAL::Polyhedron_3 const>::edges_size_type in_deg = in_degree(u,g); - typedef typename graph_traits< CGAL::Polyhedron_3 const>::in_edge_iterator Iter; - return std::make_pair( Iter(ec), Iter(ec,in_deg) ); + typedef typename boost::graph_traits< CGAL::Polyhedron_3 const>::in_edge_iterator Iter; + return std::make_pair(Iter(halfedge(u,p),p), Iter(halfedge(u,p),p,1)); } template -inline std::pair const>::out_edge_iterator - ,typename graph_traits< CGAL::Polyhedron_3 const>::out_edge_iterator - > -out_edges( typename graph_traits< CGAL::Polyhedron_3 const>::vertex_descriptor u, const CGAL::Polyhedron_3& g) +inline std::pair const>::out_edge_iterator + ,typename boost::graph_traits< CGAL::Polyhedron_3 const>::out_edge_iterator + > +out_edges( typename boost::graph_traits< CGAL::Polyhedron_3 const>::vertex_descriptor u + , const CGAL::Polyhedron_3& p) { - typename CGAL::Polyhedron_3::Halfedge_around_vertex_circulator ec = u->vertex_begin(); - typename graph_traits< CGAL::Polyhedron_3 const>::edges_size_type out_deg = out_degree(u,g); - typedef typename graph_traits< CGAL::Polyhedron_3 const>::out_edge_iterator Iter; - return std::make_pair( Iter(ec), Iter(ec,out_deg) ); + typedef typename boost::graph_traits< CGAL::Polyhedron_3 const>::out_edge_iterator Iter; + return std::make_pair(Iter(halfedge(u,p),p), Iter(halfedge(u,p),p,1)); } - + +// +// MutableHalfedgeGraph +// + +template +typename boost::graph_traits< CGAL::Polyhedron_3 >::vertex_descriptor +add_vertex(CGAL::Polyhedron_3& g) +{ + return g.hds().vertices_push_back(typename CGAL::Polyhedron_3::Vertex()); +} + + +template +typename boost::graph_traits< CGAL::Polyhedron_3 >::vertex_descriptor +add_vertex(const typename boost::graph_traits >::vertex_property_type& p + , CGAL::Polyhedron_3& g) +{ + return g.hds().vertices_push_back(typename CGAL::Polyhedron_3::Vertex(p)); +} + +template +void +remove_vertex(typename boost::graph_traits< CGAL::Polyhedron_3 >::vertex_descriptor v + , CGAL::Polyhedron_3& g) +{ + g.hds().vertices_erase(v); +} + +template +typename boost::graph_traits< CGAL::Polyhedron_3 >::edge_descriptor +add_edge(CGAL::Polyhedron_3& g) +{ + return typename boost::graph_traits< CGAL::Polyhedron_3 >::edge_descriptor( + g.hds().edges_push_back(typename CGAL::Polyhedron_3::Halfedge(), + typename CGAL::Polyhedron_3::Halfedge())); +} + +template +typename boost::graph_traits< CGAL::Polyhedron_3 >::edge_descriptor +add_edge(typename boost::graph_traits< CGAL::Polyhedron_3 >::vertex_descriptor u + , typename boost::graph_traits< CGAL::Polyhedron_3 >::vertex_descriptor v + , CGAL::Polyhedron_3& g) +{ + typename boost::graph_traits< CGAL::Polyhedron_3 >::edge_descriptor + e = add_edge(g); + set_target(halfedge(e, g), u, g); + set_target(opposite(halfedge(e, g), g), v, g); + return e; +} + +template +void +remove_edge(typename boost::graph_traits< CGAL::Polyhedron_3 >::edge_descriptor e + , CGAL::Polyhedron_3& g) +{ + g.hds().edges_erase(e.halfedge()); +} + + +template +void +set_target(typename boost::graph_traits< CGAL::Polyhedron_3 >::halfedge_descriptor h1 + , typename boost::graph_traits< CGAL::Polyhedron_3 >::vertex_descriptor v + , CGAL::Polyhedron_3&) +{ + // set_face has become private in the halfedge provided by + // polyhedron for unknown reasons, although it used to be public + // once. + + // We sneak in anyway. Inheritance can't keep us out. + typedef typename CGAL::Polyhedron_3::Halfedge::Base Sneak; + static_cast(*h1).set_vertex(v); +} + +template +void +set_next(typename boost::graph_traits< CGAL::Polyhedron_3 >::halfedge_descriptor h1 + , typename boost::graph_traits< CGAL::Polyhedron_3 >::halfedge_descriptor h2 + , CGAL::Polyhedron_3&) +{ + typedef typename CGAL::Polyhedron_3::Halfedge::Base Sneak; + static_cast(*h1).set_next(h2); + static_cast(*h2).set_prev(h1); +} + +// +// MutableFaceGraph +// + +template +typename boost::graph_traits< CGAL::Polyhedron_3 >::face_descriptor +add_face(CGAL::Polyhedron_3& g) +{ + return g.hds().faces_push_back(typename CGAL::Polyhedron_3::HalfedgeDS::Face()); +} + +template +void +remove_face(typename boost::graph_traits< CGAL::Polyhedron_3 >::face_descriptor f + , CGAL::Polyhedron_3& g) +{ + g.hds().faces_erase(f); +} + +template +void +set_face(typename boost::graph_traits< CGAL::Polyhedron_3 >::halfedge_descriptor h + , typename boost::graph_traits< CGAL::Polyhedron_3 >::face_descriptor f + , const CGAL::Polyhedron_3&) +{ + // set_face has become private in the halfedge provided by + // polyhedron for unknown reasons, although it used to be public + // once. + + // We sneak in anyway. Inheritance can't keep us out. + typedef typename CGAL::Polyhedron_3::Halfedge::Base Sneak; + static_cast(*h).set_face(f); +} + +template +void +set_halfedge(typename boost::graph_traits< CGAL::Polyhedron_3 >::face_descriptor f + , typename boost::graph_traits< CGAL::Polyhedron_3 >::halfedge_descriptor h + , const CGAL::Polyhedron_3&) +{ + f->set_halfedge(h); +} + +template +void +set_halfedge(typename boost::graph_traits< CGAL::Polyhedron_3 >::vertex_descriptor v + , typename boost::graph_traits< CGAL::Polyhedron_3 >::halfedge_descriptor h + , const CGAL::Polyhedron_3&) +{ + typedef typename CGAL::Polyhedron_3::Vertex::Base Sneak; + static_cast(*v).set_halfedge(h); +} + + +// +// HalfedgeGraph +// +template +typename boost::graph_traits< CGAL::Polyhedron_3 >::edge_descriptor +edge(typename boost::graph_traits< CGAL::Polyhedron_3 >::halfedge_descriptor h + , const CGAL::Polyhedron_3&) +{ + return typename boost::graph_traits< CGAL::Polyhedron_3 >::edge_descriptor(h); +} + +template +typename boost::graph_traits< CGAL::Polyhedron_3 >::halfedge_descriptor +halfedge(typename boost::graph_traits< CGAL::Polyhedron_3 >::edge_descriptor e + , const CGAL::Polyhedron_3&) +{ + return e.halfedge(); +} + +template +typename boost::graph_traits< CGAL::Polyhedron_3 >::halfedge_descriptor +halfedge(typename boost::graph_traits< CGAL::Polyhedron_3 >::vertex_descriptor v + , const CGAL::Polyhedron_3&) +{ + CGAL_assertion(v->halfedge()->vertex() == v); + return v->halfedge(); +} + +template +std::pair< typename boost::graph_traits< CGAL::Polyhedron_3 >::halfedge_descriptor + , bool> +halfedge(typename boost::graph_traits< CGAL::Polyhedron_3 >::vertex_descriptor u + , typename boost::graph_traits< CGAL::Polyhedron_3 >::vertex_descriptor v + , const CGAL::Polyhedron_3& g) +{ + std::pair< typename boost::graph_traits< CGAL::Polyhedron_3 >::edge_descriptor + , bool> e = edge(u, v, g); + return std::make_pair(e.first.halfedge(), e.second); +} + +template +typename boost::graph_traits< CGAL::Polyhedron_3 >::halfedge_descriptor +opposite(typename boost::graph_traits< CGAL::Polyhedron_3 >::halfedge_descriptor h + , const CGAL::Polyhedron_3&) +{ + return h->opposite(); +} + +template +typename boost::graph_traits< CGAL::Polyhedron_3 >::vertex_descriptor +source(typename boost::graph_traits< CGAL::Polyhedron_3 >::halfedge_descriptor h + , const CGAL::Polyhedron_3& g) +{ + return target(opposite(h, g), g); +} + +template +typename boost::graph_traits< CGAL::Polyhedron_3 >::vertex_descriptor +target(typename boost::graph_traits< CGAL::Polyhedron_3 >::halfedge_descriptor h + , const CGAL::Polyhedron_3&) +{ + return h->vertex(); +} + +template +typename boost::graph_traits< CGAL::Polyhedron_3 >::halfedge_descriptor +next(typename boost::graph_traits< CGAL::Polyhedron_3 >::halfedge_descriptor outedge + , const CGAL::Polyhedron_3&) +{ + return outedge->next(); +} + +template +typename boost::graph_traits< CGAL::Polyhedron_3 >::halfedge_descriptor +prev(typename boost::graph_traits< CGAL::Polyhedron_3 >::halfedge_descriptor outedge + , const CGAL::Polyhedron_3&) +{ + return outedge->prev(); +} + + +// +// HalfedgeListGraph +// + +template +std::pair< + typename boost::graph_traits< CGAL::Polyhedron_3 >::halfedge_iterator + , typename boost::graph_traits< CGAL::Polyhedron_3 >::halfedge_iterator> +halfedges(const CGAL::Polyhedron_3& p) +{ + typedef typename boost::graph_traits< CGAL::Polyhedron_3 >::halfedge_iterator Iter; + CGAL::Polyhedron_3& ncp = const_cast&>(p); + return std::make_pair(Iter(ncp.halfedges_begin()), Iter(ncp.halfedges_end())); +} + +template +typename boost::graph_traits< CGAL::Polyhedron_3 >::halfedges_size_type +num_halfedges(const CGAL::Polyhedron_3& p) +{ + return p.size_of_halfedges(); +} + +// FaceGraph +template +typename boost::graph_traits< CGAL::Polyhedron_3 >::face_descriptor +face(typename boost::graph_traits< CGAL::Polyhedron_3 >::halfedge_descriptor h + , const CGAL::Polyhedron_3&) +{ + return h->face(); +} + +template +typename boost::graph_traits< CGAL::Polyhedron_3 >::halfedge_descriptor +halfedge(typename boost::graph_traits< CGAL::Polyhedron_3 >::face_descriptor f + , const CGAL::Polyhedron_3&) +{ + return f->halfedge(); +} + +template +inline std::pair const>::face_iterator + ,typename boost::graph_traits< CGAL::Polyhedron_3 const>::face_iterator + > +faces(const CGAL::Polyhedron_3& p) +{ + typedef typename boost::graph_traits< CGAL::Polyhedron_3 const>::face_iterator face_iterator; + CGAL::Polyhedron_3& ncp = const_cast&>(p); + return std::make_pair( face_iterator(ncp.facets_begin()), + face_iterator(ncp.facets_end())); +} + +template +typename boost::graph_traits< CGAL::Polyhedron_3 const>::faces_size_type +num_faces(const CGAL::Polyhedron_3& p) +{ + return p.size_of_facets(); +} + + + +template +bool is_valid(const CGAL::Polyhedron_3& p, bool verbose = false) +{ + return p.is_valid(verbose); +} +} // namespace CGAL + + +#ifndef CGAL_NO_DEPRECATED_CODE + +namespace CGAL { +template +struct halfedge_graph_traits< CGAL::Polyhedron_3 > + : CGAL::HDS_graph_traits< CGAL::Polyhedron_3 > +{ + typedef CGAL::HDS_graph_traits< CGAL::Polyhedron_3 > Base; + typedef typename Gt::Point_3 Point; + typedef typename Base::edge_iterator undirected_edge_iterator; +}; +} // namespace CGAL +#include + +namespace boost { + // The following functions were defined in the namespace boost + using CGAL::vertices; + using CGAL::edges; + using CGAL::num_vertices; + using CGAL::num_edges; + using CGAL::out_edges; + using CGAL::in_edges; + using CGAL::target; + using CGAL::source; } // namespace boost +#endif //CGAL_NO_DEPRECATED_CODE + #undef CGAL_HDS_PARAM_ +#include + #endif // CGAL_BOOST_GRAPH_GRAPH_TRAITS_POLYHEDRON_3_H diff -Nru cgal-4.4/include/CGAL/boost/graph/graph_traits_PolyMesh_ArrayKernelT.h cgal-4.5/include/CGAL/boost/graph/graph_traits_PolyMesh_ArrayKernelT.h --- cgal-4.4/include/CGAL/boost/graph/graph_traits_PolyMesh_ArrayKernelT.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/boost/graph/graph_traits_PolyMesh_ArrayKernelT.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,667 @@ +// Copyright (c) 2007 GeometryFactory (France). All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Andreas Fabri, Philipp Moeller + +#ifndef CGAL_BOOST_GRAPH_GRAPH_TRAITS_POLYMESH_ARRAYKERNELT_H +#define CGAL_BOOST_GRAPH_GRAPH_TRAITS_POLYMESH_ARRAYKERNELT_H + +#include +#include + +#include + +#include +#include +#include + +#include + +// http://openmesh.org/Documentation/OpenMesh-Doc-Latest/classOpenMesh_1_1Concepts_1_1KernelT.html + +#if defined(BOOST_MSVC) +# pragma warning(push) +# pragma warning(disable:4267) +#endif +namespace CGAL { namespace internal { + + +template +class OMesh_edge { +public: + OMesh_edge() : halfedge_() {} + explicit OMesh_edge(const Halfedge_handle& h) : halfedge_(h) {} + Halfedge_handle halfedge() const { return halfedge_; } + bool is_valid() const { return halfedge_.is_valid(); } + + bool + operator==(const OMesh_edge& other) { + if(halfedge_ == other.halfedge_) { + return true; + } else if(halfedge_ != Halfedge_handle()) { + return opposite() == other.halfedge_; + } else { + return false; + } + } + + bool + operator!=(const OMesh_edge& other) { return !(*this == other); } + + Halfedge_handle + opposite() const { return Halfedge_handle((halfedge_.idx() & 1) ? halfedge_.idx()-1 : halfedge_.idx()+1); } + + OMesh_edge + opposite_edge() const { return OMesh_edge(Halfedge_handle((halfedge_.idx() & 1) ? halfedge_.idx()-1 : halfedge_.idx()+1)); } + + std::size_t idx() const { return halfedge_.idx() / 2; } +private: + Halfedge_handle halfedge_; +}; + +template +struct Convert_omesh_edge +{ + typedef OMesh_edge result_type; + result_type operator()(const OMeshEdge& h) const { + return result_type(Halfedge_handle(h.idx() * 2)); + } +}; + +template +struct Construct_omesh_edge +{ + typedef OMesh_edge result_type; + template + result_type operator()(const T& h) const { return result_type(h); } +}; + +template +struct Construct_omesh_edge_opposite +{ + typedef OMesh_edge result_type; + template + result_type operator()(const T& h) const { return result_type(h).opposite_edge(); } +}; + + +} // internal +} // CGAL + + +namespace boost { + +template +struct graph_traits< OpenMesh::PolyMesh_ArrayKernelT > +{ +private: + typedef OpenMesh::PolyMesh_ArrayKernelT SM; + + struct SM_graph_traversal_category : public virtual boost::bidirectional_graph_tag, + public virtual boost::vertex_list_graph_tag, + public virtual boost::edge_list_graph_tag + {}; + +public: + // Graph + typedef typename SM::VertexHandle vertex_descriptor; + typedef typename SM::Point vertex_property_type; + typedef typename CGAL::internal::OMesh_edge edge_descriptor; + typedef boost::undirected_tag directed_category; + typedef boost::disallow_parallel_edge_tag edge_parallel_category; + typedef SM_graph_traversal_category traversal_category; + + // HalfedgeGraph + typedef typename SM::HalfedgeHandle halfedge_descriptor; + + // FaceGraph + typedef typename SM::FaceHandle face_descriptor; + + // VertexListGraph + typedef typename SM::VertexIter vertex_iterator; + typedef unsigned int vertices_size_type; + // EdgeListGraph + typedef boost::transform_iterator< + CGAL::internal::Convert_omesh_edge, + typename SM::EdgeIter, + edge_descriptor> edge_iterator; + + typedef unsigned int edges_size_type; + // HalfEdgeListGraph + typedef typename SM::HalfedgeIter halfedge_iterator; + typedef unsigned int halfedges_size_type; + // FaceListGraph + typedef typename SM::FaceIter face_iterator; + typedef unsigned int faces_size_type; + + // IncidenceGraph + typedef unsigned int degree_size_type; + + + typedef CGAL::In_edge_iterator in_edge_iterator; + + typedef CGAL::Out_edge_iterator out_edge_iterator; + + // nulls + static vertex_descriptor null_vertex() { return vertex_descriptor(); } + static face_descriptor null_face() { return face_descriptor(); } + static halfedge_descriptor null_halfedge() { return halfedge_descriptor(); } +}; + +template +struct graph_traits< const OpenMesh::PolyMesh_ArrayKernelT > + : public graph_traits< OpenMesh::PolyMesh_ArrayKernelT > +{ }; + +} // namespace boost + +namespace OpenMesh { + +template +typename boost::graph_traits >::vertices_size_type +num_vertices(const OpenMesh::PolyMesh_ArrayKernelT& sm) +{ + return sm.n_vertices(); +} + + +template +typename boost::graph_traits >::edges_size_type +num_edges(const OpenMesh::PolyMesh_ArrayKernelT& sm) +{ + return sm.n_edges(); +} + + +template +typename boost::graph_traits >::degree_size_type +degree(typename boost::graph_traits >::vertex_descriptor v, + const OpenMesh::PolyMesh_ArrayKernelT& sm) +{ + return sm.valence(v); +} + + +template +typename boost::graph_traits >::degree_size_type +out_degree(typename boost::graph_traits >::vertex_descriptor v, + const OpenMesh::PolyMesh_ArrayKernelT& sm) +{ + return sm.valence(v); +} + + +template +typename boost::graph_traits >::degree_size_type +in_degree(typename boost::graph_traits >::vertex_descriptor v, + const OpenMesh::PolyMesh_ArrayKernelT& sm) +{ + return sm.valence(v); +} + + +template +typename boost::graph_traits >::vertex_descriptor +source(typename boost::graph_traits >::edge_descriptor e, + const OpenMesh::PolyMesh_ArrayKernelT& sm) +{ + return sm.from_vertex_handle(e.halfedge()); +} + +template +typename boost::graph_traits >::vertex_descriptor +source(typename boost::graph_traits >::halfedge_descriptor h, + const OpenMesh::PolyMesh_ArrayKernelT& sm) +{ + return sm.from_vertex_handle(h); +} + + +template +typename boost::graph_traits >::vertex_descriptor +target(typename boost::graph_traits >::edge_descriptor e, + const OpenMesh::PolyMesh_ArrayKernelT& sm) +{ + return sm.to_vertex_handle(e.halfedge()); +} + +template +typename boost::graph_traits >::vertex_descriptor +target(typename boost::graph_traits >::halfedge_descriptor h, + const OpenMesh::PolyMesh_ArrayKernelT& sm) +{ + return sm.to_vertex_handle(h); +} + +template +std::pair >::vertex_iterator, + typename boost::graph_traits >::vertex_iterator> +vertices(const OpenMesh::PolyMesh_ArrayKernelT& sm) +{ + return std::make_pair(sm.vertices_sbegin(), sm.vertices_end()); +} + + +template +std::pair >::edge_iterator, + typename boost::graph_traits >::edge_iterator> +edges(const OpenMesh::PolyMesh_ArrayKernelT& sm) +{ + typedef typename boost::graph_traits >::edge_iterator iterator; + iterator beg(sm.edges_sbegin()); + iterator end(sm.edges_end()); + return std::make_pair(beg,end); +} + + +template +std::pair >::in_edge_iterator, + typename boost::graph_traits >::in_edge_iterator> +in_edges(typename boost::graph_traits >::vertex_descriptor v, + const OpenMesh::PolyMesh_ArrayKernelT& sm) +{ + typedef typename boost::graph_traits >::in_edge_iterator Iter; + + return std::make_pair(Iter(halfedge(v,sm),sm), Iter(halfedge(v,sm),sm,1)); +} + +template +std::pair >::out_edge_iterator, + typename boost::graph_traits >::out_edge_iterator> +out_edges(typename boost::graph_traits >::vertex_descriptor v, + const OpenMesh::PolyMesh_ArrayKernelT& sm) +{ + typedef typename boost::graph_traits >::out_edge_iterator Iter; + return std::make_pair(Iter(halfedge(v,sm),sm), Iter(halfedge(v,sm),sm,1)); +} + + +template +std::pair >::edge_descriptor, + bool> +edge(typename boost::graph_traits >::vertex_descriptor u, + typename boost::graph_traits >::vertex_descriptor v, + const OpenMesh::PolyMesh_ArrayKernelT& sm) { + typename boost::graph_traits >::edge_descriptor + he(sm.find_halfedge(u, v)); + return std::make_pair(he, he.is_valid()); +} + + +// +// HalfedgeGraph +// +template +typename boost::graph_traits >::halfedge_descriptor +next(typename boost::graph_traits >::halfedge_descriptor h, + const OpenMesh::PolyMesh_ArrayKernelT& sm) +{ + return sm.next_halfedge_handle(h); +} + +template +typename boost::graph_traits >::halfedge_descriptor +prev(typename boost::graph_traits >::halfedge_descriptor h, + const OpenMesh::PolyMesh_ArrayKernelT& sm) +{ + return sm.prev_halfedge_handle(h); +} + +template +typename boost::graph_traits >::halfedge_descriptor +opposite(typename boost::graph_traits >::halfedge_descriptor h, + const OpenMesh::PolyMesh_ArrayKernelT& sm) +{ + return sm.opposite_halfedge_handle(h); +} + +template +typename boost::graph_traits >::edge_descriptor +edge(typename boost::graph_traits >::halfedge_descriptor h, + const OpenMesh::PolyMesh_ArrayKernelT& /*sm*/) +{ + return typename boost::graph_traits >::edge_descriptor(h); +} + +template +typename boost::graph_traits >::halfedge_descriptor +halfedge(typename boost::graph_traits >::edge_descriptor e, + const OpenMesh::PolyMesh_ArrayKernelT&) +{ + return e.halfedge(); +} + +template +typename boost::graph_traits >::halfedge_descriptor +halfedge(typename boost::graph_traits >::vertex_descriptor v, + const OpenMesh::PolyMesh_ArrayKernelT& sm) +{ + // prev because OpenMesh stores out-going halfedges + return sm.prev_halfedge_handle(sm.halfedge_handle(v)); +} + + +template +std::pair< + typename boost::graph_traits >::halfedge_descriptor, + bool +> +halfedge(typename boost::graph_traits >::vertex_descriptor u, + typename boost::graph_traits >::vertex_descriptor v, + const OpenMesh::PolyMesh_ArrayKernelT& sm) +{ + typename boost::graph_traits >::halfedge_descriptor h = sm.find_halfedge(u, v); + return std::make_pair(h, h.is_valid()); +} + + + +// +// HalfedgeListGraph +// +template +std::pair >::halfedge_iterator, + typename boost::graph_traits >::halfedge_iterator> +halfedges(const OpenMesh::PolyMesh_ArrayKernelT& sm) +{ + return std::make_pair(sm.halfedges_sbegin(), sm.halfedges_end()); +} + +template +typename boost::graph_traits >::halfedges_size_type +num_halfedges(const OpenMesh::PolyMesh_ArrayKernelT& sm) +{ + return sm.n_halfedges(); +} + + + +// +// MutableHalfedgeGraph +// +template +void +set_next(typename boost::graph_traits >::halfedge_descriptor h1, + typename boost::graph_traits >::halfedge_descriptor h2, + OpenMesh::PolyMesh_ArrayKernelT& sm) +{ + sm.set_next_halfedge_handle(h1, h2); +} + + + +template +void +set_target(typename boost::graph_traits >::halfedge_descriptor h, + typename boost::graph_traits >::vertex_descriptor v, + OpenMesh::PolyMesh_ArrayKernelT& sm) +{ + sm.set_vertex_handle(h, v); +} + + +template +void +set_halfedge(typename boost::graph_traits >::vertex_descriptor v, + typename boost::graph_traits >::halfedge_descriptor h, + OpenMesh::PolyMesh_ArrayKernelT& sm) +{ + sm.set_halfedge_handle(v, sm.opposite_halfedge_handle(h)); +} + + +template +void +adjust_border_halfedge(typename boost::graph_traits >::vertex_descriptor v, + OpenMesh::PolyMesh_ArrayKernelT& sm) +{ + sm.adjust_outgoing_halfedge(v); +} + +template +void +garbage_collection(OpenMesh::PolyMesh_ArrayKernelT& sm) +{ + sm.garbage_collection(); +} + +template +typename boost::graph_traits >::edge_descriptor +add_edge(OpenMesh::PolyMesh_ArrayKernelT& sm) +{ + return edge(sm.new_edge(boost::graph_traits >::null_vertex(), + boost::graph_traits >::null_vertex() ), sm); +} + + +// +// FaceGraph +// +template +typename boost::graph_traits >::halfedge_descriptor +halfedge(typename boost::graph_traits >::face_descriptor f, + const OpenMesh::PolyMesh_ArrayKernelT& sm) +{ + return sm.halfedge_handle(f); +} + +template +typename boost::graph_traits >::face_descriptor +face(typename boost::graph_traits >::halfedge_descriptor h, + const OpenMesh::PolyMesh_ArrayKernelT& sm) +{ + return sm.face_handle(h); +} + + + +// +// MutableFaceGraph +// +template +void +set_face(typename boost::graph_traits >::halfedge_descriptor h, + typename boost::graph_traits >::face_descriptor f, + OpenMesh::PolyMesh_ArrayKernelT& sm) +{ + sm.set_face_handle(h, f); +} + + +template +void +set_halfedge(typename boost::graph_traits >::face_descriptor f, + typename boost::graph_traits >::halfedge_descriptor h, + OpenMesh::PolyMesh_ArrayKernelT& sm) +{ + sm.set_halfedge_handle(f, h); +} + + +// +// FaceListGraph +// +template +typename boost::graph_traits >::faces_size_type +num_faces(const OpenMesh::PolyMesh_ArrayKernelT& sm) +{ + return sm.n_faces(); +} + +template +std::pair >::face_iterator, + typename boost::graph_traits >::face_iterator> +faces(const OpenMesh::PolyMesh_ArrayKernelT& sm) +{ + return std::make_pair(sm.faces_sbegin(), sm.faces_end()); +} + + +template +typename boost::graph_traits >::vertex_descriptor +add_vertex(OpenMesh::PolyMesh_ArrayKernelT& sm) { + return sm.new_vertex(); +} + + /* + +// MutableGraph +// add a vertex with a default constructed property +template +typename boost::graph_traits >::vertex_descriptor +add_vertex(OpenMesh::PolyMesh_ArrayKernelT& sm) { + return sm.add_vertex(typename boost::graph_traits >::vertex_property_type()); +} + +template +typename boost::graph_traits >::vertex_descriptor +add_vertex(const typename boost::graph_traits >::vertex_property_type& p, OpenMesh::PolyMesh_ArrayKernelT& sm) { + return sm.add_vertex(p); +} + +template +void +clear_vertex(typename boost::graph_traits >::vertex_descriptor, + OpenMesh::PolyMesh_ArrayKernelT&) { + assert(false); +} + + */ + +template +void +remove_vertex(typename boost::graph_traits >::vertex_descriptor v, + OpenMesh::PolyMesh_ArrayKernelT& sm) { + + sm.request_face_status(); + sm.request_vertex_status(); + sm.request_halfedge_status(); + sm.set_halfedge_handle(v, typename boost::graph_traits >::halfedge_descriptor()); + sm.status(v).set_deleted(true); +} + + +template +void +remove_edge(typename boost::graph_traits >::vertex_descriptor u, + typename boost::graph_traits >::vertex_descriptor v, + OpenMesh::PolyMesh_ArrayKernelT& sm) +{ + typename boost::graph_traits >::edge_descriptor e = edge(u, v, sm); + remove_edge(e,sm); +} + +template +void +remove_edge(typename boost::graph_traits >::edge_descriptor e, + OpenMesh::PolyMesh_ArrayKernelT& sm) +{ + sm.request_face_status(); + sm.request_vertex_status(); + sm.request_halfedge_status(); + sm.request_edge_status(); + + typedef typename boost::graph_traits >::halfedge_descriptor halfedge_descriptor; + + halfedge_descriptor h1 = halfedge(e,sm); + halfedge_descriptor h2 = opposite(halfedge(e,sm),sm); + sm.status(sm.edge_handle(h1)).set_deleted(true); + sm.status(h1).set_deleted(true); + sm.status(h2).set_deleted(true); + +} + + +template +void +remove_edge(typename boost::graph_traits >::edge_iterator eiter, + OpenMesh::PolyMesh_ArrayKernelT& sm) +{ + remove_edge(*eiter, sm); +} + +template +void +remove_face(typename boost::graph_traits >::face_descriptor f, + OpenMesh::PolyMesh_ArrayKernelT& sm) +{ + + sm.request_face_status(); + sm.request_vertex_status(); + sm.request_halfedge_status(); + set_halfedge(f, typename boost::graph_traits >::halfedge_descriptor(), sm); + set_halfedge(f, typename boost::graph_traits >::halfedge_descriptor(), sm); + sm.status(f).set_deleted(true); +} + + +template +std::pair >::edge_descriptor, + bool> +add_edge(typename boost::graph_traits >::vertex_descriptor v1, + typename boost::graph_traits >::vertex_descriptor v2, + OpenMesh::PolyMesh_ArrayKernelT& sm) { + + return sm.new_edge(v1, v2); +} + +template +typename boost::graph_traits >::face_descriptor +add_face(OpenMesh::PolyMesh_ArrayKernelT& sm) +{ + return sm.new_face(); +} + +template +typename boost::graph_traits >::face_descriptor +add_face(InputIterator begin, InputIterator end, OpenMesh::PolyMesh_ArrayKernelT& sm) +{ + std::vector >::vertex_descriptor> + v(begin, end); + return sm.add_face(v); +} + +template +bool is_valid(OpenMesh::PolyMesh_ArrayKernelT& sm, bool verbose = false) +{ + return true; +} + +} // namespace OpenMesh + + +#ifndef CGAL_NO_DEPRECATED_CODE +#include + +namespace boost { + // The following functions were defined in the namespace boost + using OpenMesh::vertices; + using OpenMesh::edges; + using OpenMesh::num_vertices; + using OpenMesh::num_edges; + using OpenMesh::out_edges; + using OpenMesh::in_edges; + using OpenMesh::target; + using OpenMesh::source; +} // namespace boost +#endif //CGAL_NO_DEPRECATED_CODE + +#if defined(BOOST_MSVC) +# pragma warning(pop) +#endif + +#endif // CGAL_BOOST_GRAPH_TRAITS_POLYMESH_ARRAYKERNELT_H diff -Nru cgal-4.4/include/CGAL/boost/graph/graph_traits_Triangulation_2.h cgal-4.5/include/CGAL/boost/graph/graph_traits_Triangulation_2.h --- cgal-4.4/include/CGAL/boost/graph/graph_traits_Triangulation_2.h 2013-07-06 19:00:27.000000000 +0000 +++ cgal-4.5/include/CGAL/boost/graph/graph_traits_Triangulation_2.h 2014-08-29 13:58:16.000000000 +0000 @@ -25,6 +25,8 @@ #include #include +#include + // The functions and classes in this file allows the user to // treat a CGAL Triangulation_2 object as a boost graph "as is". No // wrapper is needed for the Triangulation_2 object. diff -Nru cgal-4.4/include/CGAL/boost/graph/halfedge_graph_traits_Polyhedron_3.h cgal-4.5/include/CGAL/boost/graph/halfedge_graph_traits_Polyhedron_3.h --- cgal-4.4/include/CGAL/boost/graph/halfedge_graph_traits_Polyhedron_3.h 2012-11-13 13:13:53.000000000 +0000 +++ cgal-4.5/include/CGAL/boost/graph/halfedge_graph_traits_Polyhedron_3.h 2014-08-29 13:58:16.000000000 +0000 @@ -21,170 +21,10 @@ #ifndef CGAL_BOOST_GRAPH_HALFEDGE_GRAPH_TRAITS_POLYHEDRON_3_H #define CGAL_BOOST_GRAPH_HALFEDGE_GRAPH_TRAITS_POLYHEDRON_3_H -#include -#include -#include -#include - -#define CGAL_HDS_PARAM_ template < class Traits, class Items, class Alloc> class HDS - -// -// NOTE: The BGL algorithms are NOT const-correct: i.e., they take a "G const&" -// but instantiate "graph_traits" instead of "graph_traits" -// This is known Boost bug which will eventually be fixed, but in the meantime we need -// to coerce both const and non-const specializations. -// That is, HDS_graph_traits is really the same as HDS_graph_traits -// so graph_traits is also the same as graph_traits. -// Therefore, while, for instance, "graph_traits::vertex_descriptor" -// is conceptually const-correct, it actually corresponds to the non-const handle, -// hence the const_cast<> used below in the functions implementation. -// - -namespace CGAL { - -// -// Const versions -// -template -struct halfedge_graph_traits< CGAL::Polyhedron_3 const > - : CGAL::HDS_halfedge_graph_traits< CGAL::Polyhedron_3 > // See NOTE above! -{ -}; - -template -inline std::pair const>::undirected_edge_iterator - ,typename halfedge_graph_traits< Polyhedron_3 const>::undirected_edge_iterator - > -undirected_edges( Polyhedron_3 const& p ) -{ - typedef typename halfedge_graph_traits< Polyhedron_3 const>::undirected_edge_iterator Iter; - CGAL::Polyhedron_3& ncp = const_cast&>(p); - return std::make_pair( Iter(ncp.edges_begin()), Iter(ncp.edges_end()) ); -} - -template -typename boost::graph_traits< Polyhedron_3 const>::edge_descriptor -next_edge( typename boost::graph_traits< Polyhedron_3 const>::edge_descriptor outedge - , Polyhedron_3 const& - ) -{ - return outedge->next(); -} - -template -typename boost::graph_traits< Polyhedron_3 const>::edge_descriptor -prev_edge( typename boost::graph_traits< Polyhedron_3 const>::edge_descriptor outedge - , Polyhedron_3 const& - ) -{ - HalfedgeDS_items_decorator< Polyhedron_3 > D ; - return D.get_prev(outedge); -} - -template -typename boost::graph_traits< Polyhedron_3 const>::edge_descriptor -opposite_edge( typename boost::graph_traits< Polyhedron_3 const>::edge_descriptor e - , Polyhedron_3 const& - ) -{ - return e->opposite(); -} - -template -typename boost::graph_traits< Polyhedron_3 const>::edge_descriptor -next_edge_ccw( typename boost::graph_traits< Polyhedron_3 const>::edge_descriptor inedge - , Polyhedron_3 const& - ) -{ - HalfedgeDS_items_decorator< Polyhedron_3 > D ; - return D.get_prev(inedge->opposite()); -} - -template -typename boost::graph_traits< Polyhedron_3 const>::edge_descriptor -next_edge_cw( typename boost::graph_traits< Polyhedron_3 const>::edge_descriptor inedge - , Polyhedron_3 const& - ) -{ - return inedge->next()->opposite(); -} - - -// -// Non-const versions -// - -template -struct halfedge_graph_traits< CGAL::Polyhedron_3 > - : CGAL::HDS_halfedge_graph_traits< CGAL::Polyhedron_3 > -{ -}; +#define CGAL_DEPRECATED_HEADER "" +#define CGAL_REPLACEMENT_HEADER "" +#include -template -inline std::pair >::undirected_edge_iterator - ,typename halfedge_graph_traits< Polyhedron_3 >::undirected_edge_iterator - > -undirected_edges( Polyhedron_3& p ) -{ - typedef typename halfedge_graph_traits< Polyhedron_3 >::undirected_edge_iterator Iter; - CGAL::Polyhedron_3& ncp = const_cast&>(p); - return std::make_pair( Iter(ncp.edges_begin()), Iter(ncp.edges_end()) ); -} - -template -typename boost::graph_traits< Polyhedron_3 >::edge_descriptor -next_edge( typename boost::graph_traits< Polyhedron_3 >::edge_descriptor outedge - , Polyhedron_3& - ) -{ - return outedge->next(); -} - - -template -typename boost::graph_traits< Polyhedron_3 >::edge_descriptor -prev_edge( typename boost::graph_traits< Polyhedron_3 >::edge_descriptor outedge - , Polyhedron_3& - ) -{ - CGAL::HalfedgeDS_items_decorator< Polyhedron_3 > D ; - return D.get_prev(outedge); -} - - -template -typename boost::graph_traits< Polyhedron_3 >::edge_descriptor -opposite_edge( typename boost::graph_traits< Polyhedron_3 >::edge_descriptor e - , Polyhedron_3& - ) -{ - return e->opposite(); -} - - -template -typename boost::graph_traits< Polyhedron_3 >::edge_descriptor -next_edge_ccw( typename boost::graph_traits< Polyhedron_3 >::edge_descriptor inedge - , Polyhedron_3& - ) -{ - HalfedgeDS_items_decorator< Polyhedron_3 > D ; - return D.get_prev(inedge->opposite()); -} - - -template -typename boost::graph_traits< Polyhedron_3 >::edge_descriptor -next_edge_cw( typename boost::graph_traits< Polyhedron_3 >::edge_descriptor inedge - , Polyhedron_3& - ) -{ - return inedge->next()->opposite(); -} - - -} //namespace CGAL - -#undef CGAL_HDS_ +#include #endif // CGAL_BOOST_GRAPH_HALFEDGE_GRAPH_TRAITS_POLYHEDRON_3_H diff -Nru cgal-4.4/include/CGAL/boost/graph/helpers.h cgal-4.5/include/CGAL/boost/graph/helpers.h --- cgal-4.4/include/CGAL/boost/graph/helpers.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/boost/graph/helpers.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,261 @@ +// Copyright (c) 2014 GeometryFactory (France). All rights reserved. +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Andreas Fabri + +#ifndef CGAL_BOOST_GRAPH_HELPERS_H +#define CGAL_BOOST_GRAPH_HELPERS_H + + +#include + +namespace CGAL { + + + +template +bool is_border(typename boost::graph_traits::halfedge_descriptor hd, const FaceGraph& g) +{ + return face(hd,g) == boost::graph_traits::null_face(); +} + +template +bool is_border_edge(typename boost::graph_traits::halfedge_descriptor hd, const FaceGraph& g) +{ + return is_border(hd, g) || is_border(opposite(hd,g), g); +} + +template +bool is_border(typename boost::graph_traits::edge_descriptor ed, const FaceGraph& g) +{ + return is_border_edge(halfedge(ed,g), g); +} + +template +boost::optional::halfedge_descriptor> +is_border(typename boost::graph_traits::vertex_descriptor v, + const Graph& g) +{ + CGAL::Halfedge_around_target_iterator havib, havie; + for(boost::tie(havib, havie) = halfedges_around_target(halfedge(v, g), g); havib != havie; ++havib) { + if(is_border(*havib,g)) { + typename boost::graph_traits::halfedge_descriptor h = *havib; + return h; + } + } + // empty + return boost::optional::halfedge_descriptor>(); +} + + + /*! + returns `true` if there are no + border edges. + */ +template +bool is_closed(const FaceGraph& g) +{ + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + BOOST_FOREACH(halfedge_descriptor hd, halfedges(g)){ + if(is_border(hd,g)){ + return false; + } + } + return true; +} + + +template +bool is_bivalent(typename boost::graph_traits::halfedge_descriptor hd, const FaceGraph& g) +{ + return hd == opposite(next(opposite(next(hd,g),g),g),g); +} + + /*! + returns `true` if all + vertices have exactly two incident edges. + */ +template + bool is_pure_bivalent(const FaceGraph& g) +{ + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + BOOST_FOREACH(vertex_descriptor vd, vertices(g)){ + halfedge_descriptor hd = halfedge(vd,g); + if((hd == boost::graph_traits::null_halfedge()) || + (! is_bivalent(hd,g))){ + return false; + } + } + return true; +} + +template +bool is_trivalent(typename boost::graph_traits::halfedge_descriptor hd, const FaceGraph& g) +{ + return hd == opposite(next(opposite(next(opposite(next(hd,g),g),g),g),g),g); +} + + /*! + returns `true` if all + vertices have exactly three incident edges. + */ +template + bool is_pure_trivalent(const FaceGraph& g) +{ + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + BOOST_FOREACH(vertex_descriptor vd, vertices(g)){ + halfedge_descriptor hd = halfedge(vd,g); + if((hd == boost::graph_traits::null_halfedge()) || + (! is_trivalent(hd,g))){ + return false; + } + } + return true; +} + + /*! + returns `true` iff the connected component denoted by `h` is a triangle. + \pre `g` must be valid. + */ +template + bool is_triangle(typename boost::graph_traits::halfedge_descriptor hd, const FaceGraph& g) +{ + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + halfedge_descriptor beg = hd; + if(is_border(hd,g)) return false; + for(int i=0; i<3;i++){ + if(! is_border(opposite(hd,g),g)) return false; + hd = next(hd,g); + } + return next(hd,g)== beg; +} + + /*! + returns `true` iff the face is a triangle, that is it has three incident halfedges. + */ +template +bool is_triangle(typename boost::graph_traits::face_descriptor fd, const FaceGraph& g) +{ + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + halfedge_descriptor hd = halfedge(fd,g); + return hd == next(next(next(hd,g),g),g); +} + + /*! + returns `true` if all faces are triangles. + */ +template + bool is_pure_triangle(const FaceGraph& g) +{ + typedef typename boost::graph_traits::face_descriptor face_descriptor; + BOOST_FOREACH(face_descriptor fd, faces(g)){ + if(! is_triangle(fd,g)){ + return false; + } + } + return true; +} + + +/*! + returns `true` iff the connected component denoted by `h` is a quadrilateral. + */ +template +bool is_quad(typename boost::graph_traits::halfedge_descriptor hd, const FaceGraph& g) +{ + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + halfedge_descriptor beg = hd; + if(is_border(hd,g)) return false; + for(int i=0; i<4;i++){ + if(! is_border(opposite(hd,g),g)) return false; + hd = next(hd,g); + } + return next(hd,g)== beg; +} + + + /*! + returns `true` iff the face is a quad, that is it has four incident halfedges. + */ +template +bool is_quad(typename boost::graph_traits::face_descriptor fd, const FaceGraph& g) +{ + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + halfedge_descriptor hd = halfedge(fd,g); + return hd == next(next(next(next(hd,g),g),g),g); +} + + /*! + returns `true` if all faces are quadrilaterals. + */ +template + bool is_pure_quad(const FaceGraph& g) +{ + typedef typename boost::graph_traits::face_descriptor face_descriptor; + BOOST_FOREACH(face_descriptor fd, faces(g)){ + if(! is_quad(fd,g)){ + return false; + } + } + return true; +} + + /*! + returns `true` iff the connected component denoted by `h` is a tetrahedron. + */ +template +bool is_tetrahedron( typename boost::graph_traits::halfedge_descriptor h1, const FaceGraph& g) +{ + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + halfedge_descriptor h2 = next(h1,g); + halfedge_descriptor h3 = next(h2,g); + halfedge_descriptor h4 = next(opposite(h1,g),g ); + halfedge_descriptor h5 = next(opposite(h2,g),g ); + halfedge_descriptor h6 = next(opposite(h3,g),g ); + // check halfedge combinatorics. + // at least three edges at vertices 1, 2, 3. + if ( h4 == opposite(h3,g) ) return false; + if ( h5 == opposite(h1,g) ) return false; + if ( h6 == opposite(h2,g) ) return false; + // exact three edges at vertices 1, 2, 3. + if ( next(opposite(h4,g),g) != opposite(h3,g) ) return false; + if ( next(opposite(h5,g),g) != opposite(h1,g) ) return false; + if ( next(opposite(h6,g),g) != opposite(h2,g) ) return false; + // three edges at v4. + if ( opposite(next(h4,g),g) != h5 ) return false; + if ( opposite(next(h5,g),g) != h6 ) return false; + if ( opposite(next(h6,g),g) != h4 ) return false; + // All facets are triangles. + if ( next(next(next(h1,g),g),g) != h1 ) return false; + if ( next(next(next(h4,g),g),g) != h4 ) return false; + if ( next(next(next(h5,g),g),g) != h5 ) return false; + if ( next(next(next(h6,g),g),g) != h6 ) return false; + // all edges are non-border edges. + if ( is_border(h1,g) ) return false; // implies h2 and h3 + if ( is_border(h4,g) ) return false; + if ( is_border(h5,g) ) return false; + if ( is_border(h6,g) ) return false; + return true; + } + + + +} // namespace CGAL + +#endif // CGAL_BOOST_GRAPH_HELPERS_H diff -Nru cgal-4.4/include/CGAL/boost/graph/internal/helpers.h cgal-4.5/include/CGAL/boost/graph/internal/helpers.h --- cgal-4.4/include/CGAL/boost/graph/internal/helpers.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/boost/graph/internal/helpers.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,178 @@ +// Copyright (c) 2014 GeometryFactory (France). All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Andread Fabri + +#ifndef CGAL_BOOST_GRAPH_INTERNAL_HELPERS_H +#define CGAL_BOOST_GRAPH_INTERNAL_HELPERS_H + +#include +#include +#include + +namespace CGAL { + +// breaks a dependency loop between +// and +template class Halfedge_around_target_iterator; + +namespace internal { + +template +void +set_border(typename boost::graph_traits::halfedge_descriptor const& h + , Graph& g) +{ + set_face(h, boost::graph_traits::null_face(), g); +} + +template +typename boost::graph_traits::halfedge_descriptor +copy(typename boost::graph_traits::halfedge_descriptor const& h + , Graph& g) +{ + typename boost::graph_traits::edge_descriptor e = add_edge(g); + typename boost::graph_traits::halfedge_descriptor res = halfedge(e,g); + typename boost::graph_traits::halfedge_descriptor ropp = opposite(res, g); + typename boost::graph_traits::halfedge_descriptor hopp = opposite(h, g); + set_target(res, target(h, g), g); + set_target(hopp, target(hopp, g), g); + set_face(res, face(h, g), g); + set_face(ropp, face(hopp, g), g); + // note that we cannot call set_next as it then would call set_prev on the original + return res; + } + + +template +void +set_vertex_halfedge(typename boost::graph_traits::halfedge_descriptor const& h + , Graph& g) +{ set_halfedge(target(h, g), h, g); } + + +template +void +close_tip(typename boost::graph_traits::halfedge_descriptor const& h + , Graph& g) +{ + // makes `opposite(h,g)' the successor of h. + set_next( h, opposite(h, g), g); +} + + +template +void +close_tip(typename boost::graph_traits::halfedge_descriptor const& h + , typename boost::graph_traits::vertex_descriptor const& v + , Graph& g) +{ + // makes `h->opposite()' the successor of h and sets the incident + // vertex of h to v. + set_next(h, opposite(h, g), g); + set_target(h, v, g); + set_halfedge(v, h, g); +} + +template +void +insert_tip(typename boost::graph_traits::halfedge_descriptor const& h + , typename boost::graph_traits::halfedge_descriptor const& h2 + , Graph& g) +{ + set_next(h, next(h2,g), g); + set_next(h2, opposite(h, g), g); + set_target(h, target(h2, g), g); +} + + +template +void +remove_tip(typename boost::graph_traits::halfedge_descriptor const& h + , Graph& g) +{ + set_next(h, next(opposite(next(h, g), g), g), g); +} + + +template +void +set_face_in_face_loop(typename boost::graph_traits::halfedge_descriptor h, + typename boost::graph_traits::face_descriptor f, + Graph& g) +{ + typename boost::graph_traits::halfedge_descriptor end = h; + do { + set_face(h, f, g); + h = next(h, g); + } while ( h != end); +} + + +template +void insert_halfedge(typename boost::graph_traits::halfedge_descriptor const& h + , typename boost::graph_traits::halfedge_descriptor const& f + , Graph& g) +{ + set_next(h, next(f, g), g); + set_next(f, h, g); + set_face(h, face(f, g), g); +} + +template +std::size_t +exact_num_vertices(const Graph& g) +{ + typename boost::graph_traits::vertex_iterator beg, end; + boost::tie(beg,end) = vertices(g); + return std::distance(beg,end); + } + +template +std::size_t +exact_num_halfedges(const Graph& g) +{ + typename boost::graph_traits::halfedge_iterator beg, end; + boost::tie(beg,end) = halfedges(g); + return std::distance(beg,end); + } + +template +std::size_t +exact_num_edges(const Graph& g) +{ + typename boost::graph_traits::edge_iterator beg, end; + boost::tie(beg,end) = edges(g); + return std::distance(beg,end); + } + +template +std::size_t +exact_num_faces(const Graph& g) +{ + typename boost::graph_traits::face_iterator beg, end; + boost::tie(beg,end) = faces(g); + return std::distance(beg,end); + } + + + + +} // internal +} // CGAL + + +#endif // CGAL_BOOST_GRAPH_INTERNAL_HELPERS_H diff -Nru cgal-4.4/include/CGAL/boost/graph/internal/OM_iterator_from_circulator.h cgal-4.5/include/CGAL/boost/graph/internal/OM_iterator_from_circulator.h --- cgal-4.4/include/CGAL/boost/graph/internal/OM_iterator_from_circulator.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/boost/graph/internal/OM_iterator_from_circulator.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,182 @@ +// Copyright (c) 2014 GeometryFactory (France). All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Philipp Moeller + +#ifndef CGAL_OM_ITERATOR_FROM_CICULATOR_H +#define CGAL_OM_ITERATOR_FROM_CICULATOR_H + +#include +#include + +#include + +#include +#include + +#include +#include + +namespace CGAL { + +// adapted from circulator.h, does not support +// random_access_circulators and returns the underlying circulator +// instead of dereferencing it +template +class OM_iterator_from_circulator { +private: + // The m_anchor is normalized to be a minimal circulator. + C m_anchor; + C current; + bool past_the_end; + + typedef std::iterator_traits I_traits; + typedef typename I_traits::iterator_category I_Iter_cat; + typedef I_Iterator_from_circulator_traits I__traits; + +public: + typedef C Circulator; + typedef OM_iterator_from_circulator Self; + + typedef typename I__traits::iterator_category iterator_category; + + typedef typename + boost::mpl::if_c< Prevent_deref + , C + , typename C::value_type + >::type value_type; + + typedef typename C::difference_type difference_type; + typedef typename + boost::mpl::if_c< Prevent_deref + , C& + , typename C::reference + >::type reference; + typedef typename + boost::mpl::if_c< Prevent_deref + , C* + , typename C::reference + >::type pointer; + + OM_iterator_from_circulator(){} + + OM_iterator_from_circulator(const C circ, int n) + : m_anchor(circ), current(circ), past_the_end(n == 1) {} + + + bool done() const + { + return past_the_end || (! current); + } + + + bool operator==( const Self& i) const { + CGAL_assertion( m_anchor == i.m_anchor); // same anchor? + return (done() && i.done()) || (((!done()) && (!i.done())) && ( current == i.current)); + } + + bool operator!=( const Self& i) const { + return !(*this == i); + } + + +// we cannot enable_if on operator* and operator-> because they do not +// depend on template parameters directly and default template +// arguments for functions are C++11. we redirect on helper member +// templates as a work-around. +private: + template + typename boost::enable_if_c::type + indirection() const { + return const_cast(this)->current; + } + template + typename boost::disable_if_c::type + indirection() const { + return *current; + } +public: + reference operator*() const { + return indirection(); + } + +private: + template + typename boost::disable_if_c::type + structure_dereference() { + return &(*current); + } + template + typename boost::enable_if_c::type + structure_dereference() { + return ¤t; + } +public: + pointer operator->() const { + return structure_dereference(); + } + + Self& operator++() { + ++current; + return *this; + } + Self operator++(int) { + std::cerr << "operator++(int)" << std::endl; + Self tmp = *this; + ++*this; + return tmp; + } + Self& operator--() { + --current; + return *this; + } + Self operator--(int) { + Self tmp = *this; + --*this; + return tmp; + } + /* + Self& operator+=( difference_type n) { + if ( n < 0 && current == m_anchor) // We are leaving the anchor. + --m_winding; + current += n; + if ( n > 0 && current == m_anchor) // Back again at the anchor. + ++m_winding; + return *this; + } + + bool operator<( const Self& i) const { + CGAL_assertion( m_anchor != NULL); + CGAL_assertion( m_anchor == i.m_anchor); + return ( (m_winding < i.m_winding) + || ( (m_winding == i.m_winding) + && (current - m_anchor) < (i.current - m_anchor) + ) + ); + } + bool operator> ( const Self& i) const { return i < *this; } + bool operator<=( const Self& i) const { return !(i < *this); } + bool operator>=( const Self& i) const { return !(*this < i); } + */ + const C* anchor() const { return m_anchor;} + + Circulator current_circulator() const { return current;} +}; + +} // CGAL + +#endif /* CGAL_OM_ITERATOR_FROM_CICULATOR_H */ diff -Nru cgal-4.4/include/CGAL/boost/graph/iterator.h cgal-4.5/include/CGAL/boost/graph/iterator.h --- cgal-4.4/include/CGAL/boost/graph/iterator.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/boost/graph/iterator.h 2014-10-04 19:00:10.000000000 +0000 @@ -0,0 +1,1189 @@ +// Copyright (c) 2014 GeometryFactory (France). All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Andreas Fabri + +#ifndef CGAL_BGL_ITERATORS_H +#define CGAL_BGL_ITERATORS_H + +#include + +#include +#include + +#include +#include +#include + +namespace CGAL { + + +namespace internal { + +template +struct Edge { + const G* g; + + Edge() + : g(NULL) + {} + + Edge(const G& g) + : g(&g) + {} + + typedef typename boost::graph_traits::edge_descriptor result_type; + typedef typename boost::graph_traits::halfedge_descriptor argument_type; + + result_type operator()(argument_type h) const + { + return edge(h, *g); + } +}; + +template +struct OppositeEdge { + const G* g; + + OppositeEdge() + : g(NULL) + {} + + OppositeEdge(const G& g) + : g(&g) + {} + + typedef typename boost::graph_traits::edge_descriptor result_type; + typedef typename boost::graph_traits::halfedge_descriptor argument_type; + + result_type operator()(argument_type h) const + { + return edge(opposite(h,*g), *g); + } +}; + +template +struct OppositeHalfedge { + const G* g; + + OppositeHalfedge() + : g(NULL) + {} + + OppositeHalfedge(const G& g) + : g(&g) + {} + + typedef typename boost::graph_traits::halfedge_descriptor result_type; + typedef typename boost::graph_traits::halfedge_descriptor argument_type; + + result_type operator()(argument_type h) const + { + return opposite(h,*g); + } +}; + +template +struct Target { + const G* g; + + Target() + : g(NULL) + {} + + Target(const G& g) + : g(&g) + {} + + typedef typename boost::graph_traits::vertex_descriptor result_type; + typedef typename boost::graph_traits::halfedge_descriptor argument_type; + + result_type operator()(argument_type h) const + { + return target(h,*g); + } +}; + +template +struct Source { + const G* g; + + Source() + : g(NULL) + {} + + Source(const G& g) + : g(&g) + {} + + typedef typename boost::graph_traits::vertex_descriptor result_type; + typedef typename boost::graph_traits::halfedge_descriptor argument_type; + + result_type operator()(argument_type h) const + { + return source(h,*g); + } +}; + +template +struct Face { + const G* g; + + Face() + : g(NULL) + {} + + Face(const G& g) + : g(&g) + {} + + typedef typename boost::graph_traits::face_descriptor result_type; + typedef typename boost::graph_traits::halfedge_descriptor argument_type; + + result_type operator()(argument_type h) const + { + return face(h,*g); + } +}; + + } // namespace internal + + +/** + * \ingroup PkgBGLIterators + * A bidirectional iterator with value type `boost::graph_traits::%halfedge_descriptor` over all halfedges having the same vertex as source. + * Let `h` be a halfedge of graph `g`. For a `Halfedge_around_source_iterator` `havi` with `h = *havi;` + * the following holds: Either `++havi` is the past the end iterator, or `next(opposite(h,g),g) == *++havi`. + * \tparam Graph must be a model of the concept `HalfedgeGraph` + * \cgalModels `BidirectionalIterator` + */ +template +class Halfedge_around_source_iterator { + typedef Halfedge_around_source_iterator Self; +public: +#ifndef DOXYGEN_RUNNING + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::halfedge_descriptor vertex_descriptor; + typedef std::bidirectional_iterator_tag iterator_category; + typedef halfedge_descriptor value_type; + typedef value_type* pointer; + typedef const value_type& reference; + typedef std::ptrdiff_t difference_type; + +private: + halfedge_descriptor anchor, pos; + const Graph* g; + int winding; +#endif + +public: + Halfedge_around_source_iterator() + : anchor(), pos(), g(0) + {} + + Halfedge_around_source_iterator(halfedge_descriptor hd, const Graph& g, int n=0) + : anchor(hd), pos(hd), g(&g), winding((hd==halfedge_descriptor())?1:n) + {} + +#ifndef DOXYGEN_RUNNING + // design patter: "safe bool" + // will be replaced by explicit operator bool with C++11 + typedef void (Halfedge_around_source_iterator::*bool_type)() const; + + void this_type_does_not_support_comparisons() const {} + + operator bool_type() const + { + return (! (this->base() == NULL)) ? + &Halfedge_around_source_iterator::this_type_does_not_support_comparisons : 0; + } + + bool operator==( const Self& i) const { + CGAL_assertion( anchor == anchor); + return ( g == i.g) && ( pos == i.pos) && ( winding == i.winding); + } + + bool operator!=( const Self& i) const { + return !(*this == i); + } + + bool operator== (void* ) const + { + return g == NULL; + } + + reference operator*() const + { + return pos; + } + + pointer operator->() const + { + return &pos; + } + + Self& operator++() { + pos = next(opposite(pos,*g),*g); + if ( pos == anchor) + ++winding; + return *this; + } + Self operator++(int) { + Self tmp = *this; + ++*this; + return tmp; + } + Self& operator--() { + if ( pos == anchor) + --winding; + pos = opposite(prev(pos,*g),*g); + return *this; + } + Self operator--(int) { + Self tmp = *this; + --*this; + return tmp; + } +#endif +}; + +/** + * \ingroup PkgBGLIterators + * A bidirectional iterator with value type `boost::graph_traits::%halfedge_descriptor` over all halfedges having the same vertex as target. + * Let `h` be a halfedge of graph `g`. For a `Halfedge_around_target_iterator` `havi` with `h = *havi;` + * the following holds: Either `++havi` is the past the end iterator, or `opposite(next(h,g),g) == *++havi`. + * \tparam Graph must be a model of the concept `HalfedgeGraph` + * \cgalModels `BidirectionalIterator` + */ + +template +class Halfedge_around_target_iterator { + typedef Halfedge_around_target_iterator Self; + +public: +#ifndef DOXYGEN_RUNNING + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::halfedge_descriptor vertex_descriptor; + typedef std::bidirectional_iterator_tag iterator_category; + typedef halfedge_descriptor value_type; + typedef value_type* pointer; + typedef const value_type& reference; + typedef std::ptrdiff_t difference_type; + +private: + halfedge_descriptor anchor, pos; + const Graph* g; + int winding; +#endif + +public: + Halfedge_around_target_iterator() + : anchor(), pos(), g(0) + {} + + Halfedge_around_target_iterator(halfedge_descriptor hd, const Graph& g, int n=0) + : anchor(hd), pos(hd), g(&g), winding((hd==halfedge_descriptor())?1:n) + {} + +#ifndef DOXYGEN_RUNNING + // design patter: "safe bool" + // will be replaced by explicit operator bool with C++11 + typedef void (Halfedge_around_target_iterator::*bool_type)() const; + + void this_type_does_not_support_comparisons() const {} + + operator bool_type() const + { + return (! (this->base() == NULL)) ? + &Halfedge_around_target_iterator::this_type_does_not_support_comparisons : 0; + } + + bool operator==( const Self& i) const { + CGAL_assertion( anchor == anchor); + return ( g == i.g) && ( pos == i.pos) && ( winding == i.winding); + } + + bool operator!=( const Self& i) const { + return !(*this == i); + } + + bool operator== (void* ) const + { + return g == NULL; + } + + reference operator*() const + { + return pos; + } + + pointer operator->() const + { + return &pos; + } + + Self& operator++() { + pos = opposite(next(pos,*g),*g); + if ( pos == anchor) + ++winding; + return *this; + } + Self operator++(int) { + Self tmp = *this; + ++*this; + return tmp; + } + Self& operator--() { + if ( pos == anchor) + --winding; + pos = prev(opposite(pos,*g),*g); + return *this; + } + Self operator--(int) { + Self tmp = *this; + --*this; + return tmp; + } +#endif +}; + + +/** + * \ingroup PkgBGLIterators + * A bidirectional iterator with value type `boost::graph_traits::%halfedge_descriptor` over all halfedges incident to the same face. + * Let `h` be a halfedge of graph `g`. For a `Halfedge_around_face_iterator` `hafi` with `h = *hafi` + * the following holds: Either `++hafi` is the past the end iterator, or `next(h,g) == *++hafi`. + * \tparam Graph must be a model of the concept `HalfedgeGraph` + * \cgalModels `BidirectionalIterator` + */ + +template +class Halfedge_around_face_iterator { +#ifndef DOXYGEN_RUNNING + typedef Halfedge_around_face_iterator Self; + +public: + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef std::bidirectional_iterator_tag iterator_category; + typedef halfedge_descriptor value_type; + typedef value_type* pointer; + typedef value_type& reference; + typedef std::ptrdiff_t difference_type; + +#endif + + Halfedge_around_face_iterator() + : pos(), g(0) + {} + + Halfedge_around_face_iterator(halfedge_descriptor hd, const Graph& g, int n=0) + : anchor(hd), pos(hd), g(&g), winding((hd == halfedge_descriptor())?1:n) + {} +#ifndef DOXYGEN_RUNNING + reference operator * ( ) { return pos; } + const value_type& operator * ( ) const { return pos; } + pointer operator -> ( ) { return &pos; } + const value_type* operator -> ( ) const { return &pos; } + + // design patter: "safe bool" + // will be replaced by explicit operator bool with C++11 + typedef void (Halfedge_around_face_iterator::*bool_type)() const; + + void this_type_does_not_support_comparisons() const {} + + operator bool_type() const + { + return (! (this->base() == NULL)) ? + &Halfedge_around_face_iterator::this_type_does_not_support_comparisons : 0; + } + + bool operator==( const Self& i) const { + CGAL_assertion( anchor == anchor); + return ( g == i.g) && ( pos == i.pos) && ( winding == i.winding); + } + + bool operator!=( const Self& i) const { + return !(*this == i); + } + + Self& operator++() + { + CGAL_assertion(g != NULL); + pos = next(pos,*g); + if ( pos == anchor) + ++winding; + return *this; + } + + Self operator++(int) + { + CGAL_assertion(g != NULL); + Self tmp = *this; + ++*this; + return tmp; + } + + Self& operator--() + { + CGAL_assertion(g != NULL); + if ( pos == anchor) + --winding; + + pos = prev(pos,*g); + return *this; + } + + Self operator--(int) + { + CGAL_assertion(g != NULL); + Self tmp = *this; + --*this; + return tmp; + } +#endif +private: + halfedge_descriptor anchor, pos; + const Graph* g; + int winding; +}; + + +template +class Halfedge_around_target_circulator; + +/** + * \ingroup PkgBGLIterators + * A bidirectional circulator with value type `boost::graph_traits::%halfedge_descriptor` over all halfedges having the same vertex as source. + * Let `h` be a halfedge of graph `g`. For a `Halfedge_around_source_circulator` `havc` with `h = *havc;` + * the following holds: `next(opposite(h,g),g) == *++havc`. + * \tparam Graph must be a model of the concept `HalfedgeGraph` + * \cgalModels `BidirectionalCirculator` + */ +template +class Halfedge_around_source_circulator +#ifndef DOXYGEN_RUNNING + : public boost::transform_iterator, Halfedge_around_target_circulator > +#endif +{ +#ifndef DOXYGEN_RUNNING + typedef boost::transform_iterator, Halfedge_around_target_circulator > Base; + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; +#endif + +public: + +#ifndef DOXYGEN_RUNNING + typedef Bidirectional_circulator_tag iterator_category; + typedef std::size_t size_type; +#endif + + Halfedge_around_source_circulator() + {} + + Halfedge_around_source_circulator(halfedge_descriptor hd, const Graph& g) + : Base(Halfedge_around_target_circulator(hd,g), internal::OppositeHalfedge(g)) + {} + + Halfedge_around_source_circulator(vertex_descriptor vd, const Graph& g) + : Base(Halfedge_around_target_circulator(halfedge(vd,g),g), internal::OppositeHalfedge(g)) + {} +}; + + +/** + * \ingroup PkgBGLIterators + * A bidirectional circulator with value type `boost::graph_traits::%face_descriptor` over all faces incident to the same vertex. + * It circulates over the same halfedges as the `Halfedge_around_target_circulator`. + * + * \tparam Graph must be a model of the concept `HalfedgeGraph` + * \cgalModels `BidirectionalCirculator` + */ + +template +class Face_around_target_circulator +#ifndef DOXYGEN_RUNNING + : public boost::transform_iterator, Halfedge_around_target_circulator > +#endif +{ + typedef boost::transform_iterator, Halfedge_around_target_circulator > Base; + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + +public: + + Face_around_target_circulator() + {} + + Face_around_target_circulator(halfedge_descriptor hd, const Graph& g) + : Base(Halfedge_around_target_circulator(hd,g), internal::Face(g)) + {} +#ifndef DOXYGEN_RUNNING + typedef Bidirectional_circulator_tag iterator_category; + typedef std::size_t size_type; + + // design patter: "safe bool" + // will be replaced by explicit operator bool with C++11 + typedef void (Face_around_target_circulator::*bool_type)() const; + + void this_type_does_not_support_comparisons() const {} + + operator bool_type() const + { + return (! (this->base() == NULL)) ? + &Face_around_target_circulator::this_type_does_not_support_comparisons : 0; + } + + bool operator== (void*) const + { + return this->base() == NULL; + } +#endif + +}; + + +/** + * \ingroup PkgBGLIterators + * A bidirectional circulator with value type `boost::graph_traits::%halfedge_descriptor` over all halfedges having the same vertex as target. + * Let `h` be a halfedge of graph `g`. For a `Halfedge_around_target_circulator` `havc` with `h = *havc;` + * the following holds: `opposite(next(h,g),g) == *++havc`. + * \tparam Graph must be a model of the concept `HalfedgeGraph` + * \cgalModels `BidirectionalCirculator` + */ + + + +template +class Halfedge_around_target_circulator { + typedef Halfedge_around_target_circulator Self; + +public: +#ifndef DOXYGEN_RUNNING + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef Bidirectional_circulator_tag iterator_category; + typedef halfedge_descriptor value_type; + typedef value_type* pointer; + typedef value_type& reference; + typedef std::ptrdiff_t difference_type; + typedef std::size_t size_type; +#endif + + Halfedge_around_target_circulator() + : g(0) + {} + + Halfedge_around_target_circulator(halfedge_descriptor pos, const Graph& g) + : pos(pos), g(&g) + {} + + Halfedge_around_target_circulator(vertex_descriptor vd, const Graph& g) + : pos(halfedge(vd,g)), g(&g) + {} + +#ifndef DOXYGEN_RUNNING + reference operator * ( ) { return pos; } + const value_type& operator * ( ) const { return pos; } + pointer operator -> ( ) { return &pos; } + const value_type* operator -> ( ) const { return &pos; } + + bool operator == ( const Self& other) const { return g == other.g && pos == other.pos; } + bool operator != ( const Self& other) const { return g != other.g || pos != other.pos; } + + + // design patter: "safe bool" + // will be replaced by explicit operator bool with C++11 + typedef void (Halfedge_around_target_circulator::*bool_type)() const; + + void this_type_does_not_support_comparisons() const {} + + operator bool_type() const + { + return (! (g == NULL)) ? + &Halfedge_around_target_circulator::this_type_does_not_support_comparisons : 0; + } + + + bool operator== (void* ) const + { + return g == NULL; + } + + + Self& operator++() + { + CGAL_assertion(g != NULL); + pos = opposite(next(pos,*g),*g); + return *this; + } + + Self operator++(int) + { + CGAL_assertion(g != NULL); + Self tmp = *this; + ++*this; + return tmp; + } + + Self& operator--() + { + CGAL_assertion(g != NULL); + pos = prev(opposite(pos,*g),*g); + return *this; + } + + Self operator--(int) + { + CGAL_assertion(g != NULL); + Self tmp = *this; + --*this; + return tmp; + } +#endif + +private: + halfedge_descriptor pos; + const Graph* g; +}; + + +/** + * \ingroup PkgBGLIterators + * A bidirectional circulator with value type `boost::graph_traits::%halfedge_descriptor` over all halfedges incident to the same face. + * Let `h` be a halfedge of graph `g`. For a `Halfedge_around_face_circulator` `hafc` with `h = *hafc` + * the following holds: `next(h,g) == *++hafc`. + * \tparam Graph must be a model of the concept `HalfedgeGraph` + * \cgalModels `BidirectionalCirculator` + */ + +template +class Halfedge_around_face_circulator { + typedef Halfedge_around_face_circulator Self; + +public: +#ifndef DOXYGEN_RUNNING + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef Bidirectional_circulator_tag iterator_category; + typedef halfedge_descriptor value_type; + typedef value_type* pointer; + typedef value_type& reference; + typedef std::ptrdiff_t difference_type; + typedef std::size_t size_type; +#endif + + Halfedge_around_face_circulator() + : pos(), g(0) + {} + + Halfedge_around_face_circulator(halfedge_descriptor pos, const Graph& g) + : pos(pos), g(&g) + {} +#ifndef DOXYGEN_RUNNING + reference operator * ( ) { return pos; } + const value_type& operator * ( ) const { return pos; } + pointer operator -> ( ) { return &pos; } + const value_type* operator -> ( ) const { return &pos; } + + bool operator == ( const Self& other) const { return g == other.g && pos == other.pos; } + bool operator != ( const Self& other) const { return g != other.g || pos != other.pos; } + + + // design patter: "safe bool" + // will be replaced by explicit operator bool with C++11 + typedef void (Halfedge_around_face_circulator::*bool_type)() const; + + void this_type_does_not_support_comparisons() const {} + + operator bool_type() const + { + return (! (this->base() == NULL)) ? + &Halfedge_around_face_circulator::this_type_does_not_support_comparisons : 0; + } + + bool operator== (void* ) const + { + return g == NULL; + } + + Self& operator++() + { + CGAL_assertion(g != NULL); + pos = next(pos,*g); + return *this; + } + + Self operator++(int) + { + CGAL_assertion(g != NULL); + Self tmp = *this; + ++*this; + return tmp; + } + + Self& operator--() + { + CGAL_assertion(g != NULL); + pos = prev(pos,*g); + return *this; + } + + Self operator--(int) + { + CGAL_assertion(g != NULL); + Self tmp = *this; + --*this; + return tmp; + } +#endif + +private: + halfedge_descriptor pos; + const Graph* g; +}; + + +/** + * \ingroup PkgBGLIterators + * returns an iterator range over all halfedges with vertex `source(h,g)` as source. + */ +template +std::pair,Halfedge_around_source_iterator > +halfedges_around_source(typename boost::graph_traits::halfedge_descriptor h, Graph& g) +{ + typedef Halfedge_around_source_iterator I; + return std::make_pair(I(h,g), I(h,g,1)); +} + +/** + * \ingroup PkgBGLIterators + * returns an iterator range over all halfedges with vertex `v` as source. + */ +template +std::pair,Halfedge_around_source_iterator > +halfedges_around_source(typename boost::graph_traits::vertex_descriptor v, Graph& g) +{ + return halfedges_around_source(opposite(halfedge(v,g),g),g); +} + +/** + * \ingroup PkgBGLIterators + * returns an iterator range over all halfedges with vertex `target(h,g)` as target. + */ +template +std::pair,Halfedge_around_target_iterator > +halfedges_around_target(typename boost::graph_traits::halfedge_descriptor h, const Graph& g) +{ + typedef Halfedge_around_target_iterator I; + return std::make_pair(I(h,g), I(h,g,1)); +} + +/** + * \ingroup PkgBGLIterators + * returns an iterator range over all halfedges with vertex `v` as target. + */ +template +std::pair,Halfedge_around_target_iterator > +halfedges_around_target(typename boost::graph_traits::vertex_descriptor v, Graph& g) +{ + return halfedges_around_target(halfedge(v,g),g); +} + +/** + * \ingroup PkgBGLIterators + * returns an iterator range over all halfedges incident to the same face as `h`. + */ +template +std::pair,Halfedge_around_face_iterator > +halfedges_around_face(typename boost::graph_traits::halfedge_descriptor h, const Graph& g) +{ + typedef Halfedge_around_face_iterator I; + return std::make_pair(I(h,g), I(h,g,1)); +} + + +template +class Face_around_face_iterator +#ifndef DOXYGEN_RUNNING + : public boost::transform_iterator, Halfedge_around_face_iterator > +#endif +{ + typedef boost::transform_iterator, Halfedge_around_face_iterator > Base; + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + +public: +#ifndef DOXYGEN_RUNNING + typedef std::bidirectional_iterator_tag iterator_category; +#endif + + Face_around_face_iterator() + {} + + Face_around_face_iterator(halfedge_descriptor h, const Graph& g, int n = 0) + : Base(Halfedge_around_face_iterator(h,g,(h==halfedge_descriptor())?1:n), internal::Face(g)) + {} +}; + + +/** + * \ingroup PkgBGLIterators + * A bidirectional circulator with value type `boost::graph_traits::%face_descriptor` over all faces adjacent to the same face. + * It circulates over the same halfedges as the `Halfedge_around_face_circulator`. + * + * \tparam Graph must be a model of the concept `HalfedgeGraph` + * \cgalModels `BidirectionalCirculator` + */ + + + +template +class Face_around_face_circulator +{}; + + +template +class Face_around_target_iterator +#ifndef DOXYGEN_RUNNING + : public boost::transform_iterator, Halfedge_around_target_iterator > +#endif +{ + typedef boost::transform_iterator, Halfedge_around_target_iterator > Base; + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + +public: +#ifndef DOXYGEN_RUNNING + typedef std::bidirectional_iterator_tag iterator_category; +#endif + + Face_around_target_iterator() + {} + + Face_around_target_iterator(halfedge_descriptor h, const Graph& g, int n = 0) + : Base(Halfedge_around_target_iterator(h,g,(h==halfedge_descriptor())?1:n), internal::Face(g)) + {} +}; + +/** + * \ingroup PkgBGLIterators + * returns an iterator range over all faces around vertex `target(h,g)`. + */ +template +std::pair,Face_around_target_iterator > +faces_around_target(typename boost::graph_traits::halfedge_descriptor h, const Graph& g) +{ + typedef Face_around_target_iterator I; + return std::make_pair(I(h,g), I(h,g,1)); +} + +/** + * \ingroup PkgBGLIterators + * returns an iterator range over all faces adjacent to the same face `face(h,g)`. + */ +template +std::pair,Face_around_face_iterator > +faces_around_face(typename boost::graph_traits::halfedge_descriptor h, const Graph& g) +{ + typedef Face_around_face_iterator I; + return std::make_pair(I(h,g), I(h,g,1)); +} + +template +class Vertex_around_face_circulator +#ifndef DOXYGEN_RUNNING + : public boost::transform_iterator, Halfedge_around_face_circulator > +#endif +{ + typedef boost::transform_iterator, Halfedge_around_face_circulator > Base; + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + +public: +#ifndef DOXYGEN_RUNNING + typedef Bidirectional_circulator_tag iterator_category; + typedef std::size_t size_type; +#endif + + Vertex_around_face_circulator() + {} + + Vertex_around_face_circulator(halfedge_descriptor h, const Graph& g) + : Base(Halfedge_around_face_circulator(h,g), internal::Target(g)) + {} + +#ifndef DOXYGEN_RUNNING + // design patter: "safe bool" + // will be replaced by explicit operator bool with C++11 + typedef void (Vertex_around_face_circulator::*bool_type)() const; + + void this_type_does_not_support_comparisons() const {} + + operator bool_type() const + { + return (! (this->base() == NULL)) ? + &Vertex_around_face_circulator::this_type_does_not_support_comparisons : 0; + } + + bool operator== (void*) const + { + return this->base()== NULL; + } +#endif +}; + +template +class Vertex_around_face_iterator +#ifndef DOXYGEN_RUNNING + : public boost::transform_iterator, Halfedge_around_face_iterator > +#endif +{ + typedef boost::transform_iterator, Halfedge_around_face_iterator > Base; + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + +public: +#ifndef DOXYGEN_RUNNING + typedef std::bidirectional_iterator_tag iterator_category; +#endif + + Vertex_around_face_iterator() + {} + + Vertex_around_face_iterator(halfedge_descriptor h, const Graph& g, int n = 0) + : Base(Halfedge_around_face_iterator(h,g,(h==halfedge_descriptor())?1:n), internal::Target(g)) + {} + +#ifndef DOXYGEN_RUNNING + // design patter: "safe bool" + // will be replaced by explicit operator bool with C++11 + typedef void (Vertex_around_face_iterator::*bool_type)() const; + + void this_type_does_not_support_comparisons() const {} + + operator bool_type() const + { + return (! (this->base() == NULL)) ? + &Vertex_around_face_iterator::this_type_does_not_support_comparisons : 0; + } + + bool operator== (void*) const + { + return this->base()== NULL; + } +#endif +}; + + +/** + * \ingroup PkgBGLIterators + * A bidirectional circulator with value type `boost::graph_traits::%vertex_descriptor` over all vertices adjacent to the same vertex. + * It circulates over the same halfedges as the `Halfedge_around_target_circulator`. + * + * \tparam Graph must be a model of the concept `HalfedgeGraph` + * \cgalModels `BidirectionalCirculator` + */ + +template +class Vertex_around_target_circulator +#ifndef DOXYGEN_RUNNING + : public boost::transform_iterator, Halfedge_around_target_circulator > +#endif +{ + typedef boost::transform_iterator, Halfedge_around_target_circulator > Base; + +public: +#ifndef DOXYGEN_RUNNING + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef Bidirectional_circulator_tag iterator_category; + typedef std::size_t size_type; +#endif + + Vertex_around_target_circulator() + {} + + Vertex_around_target_circulator(halfedge_descriptor h, const Graph& g) + : Base(Halfedge_around_target_circulator(h,g), internal::Source(g)) + {} + +#ifndef DOXYGEN_RUNNING + // design patter: "safe bool" + // will be replaced by explicit operator bool with C++11 + typedef void (Vertex_around_target_circulator::*bool_type)() const; + + void this_type_does_not_support_comparisons() const {} + + operator bool_type() const + { + return (! (this->base() == NULL)) ? + &Vertex_around_target_circulator::this_type_does_not_support_comparisons : 0; + } +#endif +}; + + + + +template +class Vertex_around_target_iterator +#ifndef DOXYGEN_RUNNING + : public boost::transform_iterator, Halfedge_around_target_iterator > +#endif +{ + typedef boost::transform_iterator, Halfedge_around_target_iterator > Base; + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + +public: + typedef std::bidirectional_iterator_tag iterator_category; + + Vertex_around_target_iterator() + {} + + Vertex_around_target_iterator(halfedge_descriptor h, const Graph& g, int n = 0) + : Base(Halfedge_around_target_iterator(h,g,(h==halfedge_descriptor())?1:n), internal::Source(g)) + {} + +#ifndef DOXYGEN_RUNNING + // design patter: "safe bool" + // will be replaced by explicit operator bool with C++11 + typedef void (Vertex_around_target_iterator::*bool_type)() const; + + void this_type_does_not_support_comparisons() const {} + + operator bool_type() const + { + return (! (this->base() == NULL)) ? + &Vertex_around_target_iterator::this_type_does_not_support_comparisons : 0; + } +#endif +}; + + +template +std::pair, Vertex_around_target_iterator > +adjacent_vertices(typename boost::graph_traits::halfedge_descriptor h, const Graph& g) +{ + typedef Vertex_around_face_iterator I; + return std::make_pair(I(h,g), I(h,g,1)); +} + + +template +std::pair, Vertex_around_target_iterator > +adjacent_vertices(typename boost::graph_traits::vertex_descriptor v, const Graph& g) +{ + typedef Vertex_around_face_iterator I; + return std::make_pair(I(halfedge(v,g),g), I(halfedge(v,g),g,1)); +} + +/** + * \ingroup PkgBGLIterators + * returns an iterator range over all vertices adjacent to the vertex `target(h,g)`. + */ +template +std::pair, Vertex_around_target_iterator > +vertices_around_target(typename boost::graph_traits::halfedge_descriptor h, const Graph& g) +{ + typedef Vertex_around_target_iterator I; + return std::make_pair(I(h,g), I(h,g,1)); +} + +template +std::pair, Vertex_around_target_iterator > +vertices_around_target(typename boost::graph_traits::vertex_descriptor v, const Graph& g) +{ + typedef Vertex_around_target_iterator I; + return std::make_pair(I(halfedge(v,g),g), I(halfedge(v,g),g,1)); +} +/** + * \ingroup PkgBGLIterators + * returns an iterator range over all vertices adjacent to the face `face(h,g)`. + */ +template +std::pair, Vertex_around_face_iterator > +vertices_around_face(typename boost::graph_traits::halfedge_descriptor h, const Graph& g) +{ + typedef Vertex_around_face_iterator I; + return std::make_pair(I(h,g), I(h,g,1)); +} + +template +class Out_edge_iterator + : public boost::transform_iterator, Halfedge_around_target_iterator > +{ + typedef boost::transform_iterator, Halfedge_around_target_iterator > Base; + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + +public: + typedef std::bidirectional_iterator_tag iterator_category; + + Out_edge_iterator() + {} + + Out_edge_iterator(halfedge_descriptor h, const Graph& g, int n = 0) + : Base(Halfedge_around_target_iterator(h,g,(h==halfedge_descriptor())?1:n), internal::OppositeEdge(g)) + {} + + + // design patter: "safe bool" + // will be replaced by explicit operator bool with C++11 + typedef void (Out_edge_iterator::*bool_type)() const; + + void this_type_does_not_support_comparisons() const {} + + operator bool_type() const + { + return (! (this->base() == NULL)) ? + &Out_edge_iterator::this_type_does_not_support_comparisons : 0; + } + +}; + + +template +class In_edge_iterator + : public boost::transform_iterator, Halfedge_around_target_iterator > +{ + typedef boost::transform_iterator, Halfedge_around_target_iterator > Base; + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + +public: + typedef std::bidirectional_iterator_tag iterator_category; + + In_edge_iterator() + {} + + In_edge_iterator(halfedge_descriptor h, const Graph& g, int n = 0) + : Base(Halfedge_around_target_iterator(h,g,(h==halfedge_descriptor())?1:n), internal::Edge(g)) + {} + + + // design patter: "safe bool" + // will be replaced by explicit operator bool with C++11 + typedef void (In_edge_iterator::*bool_type)() const; + + void this_type_does_not_support_comparisons() const {} + + operator bool_type() const + { + return (! (this->base() == NULL)) ? + &In_edge_iterator::this_type_does_not_support_comparisons : 0; + } + +}; + + + +} // CGAL + + +#endif /* CGAL_BGL_ITERATORS_H */ diff -Nru cgal-4.4/include/CGAL/boost/graph/named_function_params.h cgal-4.5/include/CGAL/boost/graph/named_function_params.h --- cgal-4.4/include/CGAL/boost/graph/named_function_params.h 2014-02-15 20:00:23.000000000 +0000 +++ cgal-4.5/include/CGAL/boost/graph/named_function_params.h 2014-08-29 13:58:16.000000000 +0000 @@ -72,6 +72,7 @@ enum edge_is_constrained_params_t { edge_is_constrained_params } ; #if BOOST_VERSION >= 105100 + template struct cgal_bgl_named_params : boost::bgl_named_params { @@ -112,15 +113,15 @@ typedef cgal_bgl_named_params Params; return Params(p, *this); } - - template - cgal_bgl_named_params - edge_is_border_map(const IsBorderMap& p) const + + template + cgal_bgl_named_params + halfedge_index_map(const IndexMap& p) const { - typedef cgal_bgl_named_params Params; + typedef cgal_bgl_named_params Params; return Params(p, *this); } - + template cgal_bgl_named_params visitor(const Visitor& p) const @@ -232,12 +233,12 @@ typedef cgal_bgl_named_params Params; return Params(p, *this); } - - template - cgal_bgl_named_params - edge_is_border_map(const IsBorderMap& p) const + + template + cgal_bgl_named_params + halfedge_index_map(const IndexMap& p) const { - typedef cgal_bgl_named_params Params; + typedef cgal_bgl_named_params Params; return Params(p, *this); } @@ -328,6 +329,14 @@ return Params(p); } + template + cgal_bgl_named_params + halfedge_index_map(IndexMap const& p) + { + typedef cgal_bgl_named_params Params; + return Params(p); + } + template cgal_bgl_named_params vertex_point_map(PointMap const& p) @@ -351,15 +360,7 @@ typedef cgal_bgl_named_params Params; return Params(pmap); } - - template - cgal_bgl_named_params - edge_is_border_map(IsBorderMap const& p) - { - typedef cgal_bgl_named_params Params; - return Params(p); - } - + template cgal_bgl_named_params visitor(const Visitor& p) diff -Nru cgal-4.4/include/CGAL/boost/graph/properties_CombinatorialMap.h cgal-4.5/include/CGAL/boost/graph/properties_CombinatorialMap.h --- cgal-4.4/include/CGAL/boost/graph/properties_CombinatorialMap.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/boost/graph/properties_CombinatorialMap.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,276 @@ +// Copyright (c) 2013 CNRS and LIRIS' Establishments (France). +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL: +// +// +// Author(s) : Pierre Talbot + +#ifndef CGAL_BOOST_GRAPH_PROPERTIES_COMBINATORIAL_MAP_H +#define CGAL_BOOST_GRAPH_PROPERTIES_COMBINATORIAL_MAP_H + +#include +#include +#include + +#define CGAL_LCC_ARGS unsigned int d_, unsigned int ambient_dim, \ + class Traits_, \ + class Items_, \ + class Alloc_, \ + template \ + class CMap + +#define CGAL_LCC_TYPE CGAL::Linear_cell_complex + +namespace CGAL { + +template +class LCC_edge_weight_map : public boost::put_get_helper +{ +public: + + typedef boost::readable_property_map_tag category; + typedef double value_type; + typedef double reference; + typedef typename boost::graph_traits::edge_descriptor key_type; + + LCC_edge_weight_map(LCC const& ) {} + + reference operator[](key_type const& e) const + { + return CGAL::squared_distance(LCC::point(e), LCC::point(e->opposite())); + } +}; + +template +class CMap_dart_index_map_external + : public boost::put_get_helper > +{ + +public: + + typedef boost::readable_property_map_tag category; + typedef std::size_t value_type; + typedef std::size_t reference; + typedef typename boost::graph_traits::edge_descriptor key_type; + + CMap_dart_index_map_external() : map() + {} + + CMap_dart_index_map_external(CMap const& cm) + : map() + { + CMap &cmap = const_cast(cm); + typedef typename CMap::template One_dart_per_cell_range<1>::iterator Iter; + Iter b=cmap.template one_dart_per_cell<1>().begin(); + Iter e=cmap.template one_dart_per_cell<1>().end(); + for(value_type i=0; b != e; ++b, ++i) + { + map[b] = i; + ++i; + map[b->opposite()] = i; + } + typedef typename CMap::Dart_range::iterator DIter; + DIter bi = cmap.darts().begin(); + DIter ei = cmap.darts().end(); + for(; bi != ei; ++bi) + { + value_type v1 = map[bi]; + value_type v2 = map[opposite_edge(bi, cm)]; + CGAL_assertion(v1 - v2 == 1 || v1 - v2 == -1); + } + } + + reference operator[](key_type const& e) const { return map[e]; } + +private: + + CGAL::Unique_hash_map map ; +}; + +template +class LCC_vertex_point_map : public boost::put_get_helper< typename LCC::Point&, LCC_vertex_point_map > +{ +public: + + typedef typename LCC::Point Point; + + typedef boost::lvalue_property_map_tag category; + typedef Point value_type; + typedef Point& reference; + typedef typename boost::graph_traits::vertex_descriptor key_type; + + LCC_vertex_point_map(LCC& ) {} + + reference operator[](key_type const& v) const { return LCC::point(v); } +}; + +template +class LCC_vertex_point_const_map : public boost::put_get_helper< typename LCC::Point const&, LCC_vertex_point_const_map > +{ +public: + + typedef typename LCC::Point Point; + + typedef boost::readable_property_map_tag category; + typedef Point value_type; + typedef Point const& reference; + typedef typename boost::graph_traits::vertex_descriptor key_type; + + LCC_vertex_point_const_map(LCC const&) {} + + reference operator[](key_type const& v) const { return LCC::point(v); } +}; + + +template +struct CMap_property_map +{}; + +template +struct CMap_property_map +{ + typedef CMap_dart_index_map_external type; + typedef CMap_dart_index_map_external const_type; +}; + +template +struct CMap_property_map +{ + typedef CMap_dart_index_map_external type; + typedef CMap_dart_index_map_external const_type; +}; + +template +struct CMap_property_map +{ + typedef CMap_dart_index_map_external type; + typedef CMap_dart_index_map_external const_type; +}; + +template +struct CMap_property_map +{ + typedef CMap_dart_index_map_external type; + typedef CMap_dart_index_map_external const_type; +}; + +// For LCC +template +struct CMap_property_map +{ + typedef LCC_edge_weight_map type; + typedef LCC_edge_weight_map const_type; +}; + +template +struct CMap_property_map +{ + typedef LCC_vertex_point_map type; + typedef LCC_vertex_point_const_map const_type; +}; + +template +struct CMap_property_map_helper +{ + typedef typename CGAL::CMap_property_map map_gen; + typedef typename map_gen::type type; + typedef typename map_gen::const_type const_type; +}; + +} // namespace CGAL + +namespace boost{ + +// LCC. +template +struct property_map : CGAL::CMap_property_map_helper +{}; + +// This partial specialization shouldn't be needed but is due to a bug in Boost 1.51. +template +struct property_map : CGAL::CMap_property_map_helper +{}; + +template +CGAL::CMap_dart_index_map_external get(CGAL::edge_external_index_t, CGAL_LCC_TYPE const& cmap) +{ + return CGAL::CMap_dart_index_map_external(cmap); +} + +template +CGAL::CMap_dart_index_map_external get(CGAL::vertex_external_index_t, CGAL_LCC_TYPE const& cmap) +{ + return CGAL::CMap_dart_index_map_external(cmap); +} + +// LCC get. +template +CGAL::LCC_edge_weight_map get(edge_weight_t, CGAL_LCC_TYPE const& lcc) +{ + return CGAL::LCC_edge_weight_map(lcc); +} + +template +CGAL::CMap_dart_index_map_external get(edge_index_t, CGAL_LCC_TYPE const& lcc) +{ + return CGAL::CMap_dart_index_map_external(lcc); +} + +template +CGAL::CMap_dart_index_map_external get(vertex_index_t, CGAL_LCC_TYPE const& lcc) +{ + return CGAL::CMap_dart_index_map_external(lcc); +} + +template +CGAL::LCC_vertex_point_map get(CGAL::vertex_point_t, CGAL_LCC_TYPE& lcc) +{ + return CGAL::LCC_vertex_point_map(lcc); +} + +template +CGAL::LCC_vertex_point_const_map get(CGAL::vertex_point_t, CGAL_LCC_TYPE const& lcc) +{ + return CGAL::LCC_vertex_point_const_map(lcc); +} + +template +typename property_traits::type>::reference +get(PropertyTag p, CGAL_LCC_TYPE& g, const Key& key) +{ + return get(get(p, g), key); +} + +template +typename property_traits::const_type>::reference +get(PropertyTag p, CGAL_LCC_TYPE const& g, const Key& key) +{ + return get(get(p, g), key); +} + +template +void put(PropertyTag p, CGAL_LCC_TYPE& g, const Key& key, const Value& value) +{ + typedef typename property_map::type Map; + Map pmap = get(p, g); + put(pmap, key, value); +} + +} // namespace boost + +#undef CGAL_LCC_ARGS +#undef CGAL_LCC_TYPE + + +#endif // CGAL_BOOST_GRAPH_PROPERTIES_COMBINATORIAL_MAP_H diff -Nru cgal-4.4/include/CGAL/boost/graph/properties.h cgal-4.5/include/CGAL/boost/graph/properties.h --- cgal-4.4/include/CGAL/boost/graph/properties.h 2012-11-13 13:13:53.000000000 +0000 +++ cgal-4.5/include/CGAL/boost/graph/properties.h 2014-08-29 13:58:16.000000000 +0000 @@ -25,15 +25,76 @@ #include #include +#include -namespace CGAL { +/// Boost Namespace +namespace boost { + +/// \ingroup PkgBGLProperties +/// @{ -enum vertex_is_border_t { vertex_is_border } ; -enum vertex_point_t { vertex_point } ; +/// A property tag which refers to the geometric embedding property +/// of a vertex of a \ref HalfedgeGraph. +enum vertex_point_t { vertex_point }; enum vertex_external_index_t { vertex_external_index } ; -enum edge_is_border_t { edge_is_border } ; -enum edge_external_index_t { edge_external_index } ; -} //namespace CGAL +/// A property tag which refers to the property +/// of a halfedge of being a border halfedge. +enum edge_external_index_t { edge_external_index } ; + +/// A property tag which identifies the *index* property of +/// a halfedge of a \ref HalfedgeGraph. +enum halfedge_index_t { halfedge_index }; +enum halfedge_external_index_t { halfedge_external_index } ; + +/// A property tag which identifies the *index* property of +/// a face of a \ref FaceGraph. +enum face_index_t { face_index }; +enum face_external_index_t { face_external_index } ; + + template + struct vertex_property_t + { + vertex_property_t(const std::string s, const T& t = T()) + : s(s), t(t) + {} + std::string s; + T t; + + }; + +/// @} + +// Introduce those two tags so we can use BOOST_INSTALL_PROPERTY +// macro. This is dangerous because we now rely on implementation +// details. +struct halfedge_property_tag { }; +struct face_property_tag { }; + +BOOST_INSTALL_PROPERTY(vertex, point); +BOOST_INSTALL_PROPERTY(vertex, external_index); +BOOST_INSTALL_PROPERTY(halfedge, external_index); +BOOST_INSTALL_PROPERTY(edge, external_index); +BOOST_INSTALL_PROPERTY(face, index); +BOOST_INSTALL_PROPERTY(face, external_index); +} // boost + +namespace CGAL { +using boost::vertex_point_t; +using boost::vertex_point; +using boost::vertex_external_index_t; +using boost::vertex_external_index; +using boost::halfedge_index_t; +using boost::halfedge_index; +using boost::halfedge_external_index_t; +using boost::halfedge_external_index; +using boost::edge_external_index_t; +using boost::edge_external_index; +using boost::face_index_t; +using boost::face_index; +using boost::face_external_index_t; +using boost::face_external_index; +using boost::vertex_property_t; +} // CGAL #endif // CGAL_BOOST_GRAPH_BGL_PROPERTIES_H diff -Nru cgal-4.4/include/CGAL/boost/graph/properties_Polyhedron_3.h cgal-4.5/include/CGAL/boost/graph/properties_Polyhedron_3.h --- cgal-4.4/include/CGAL/boost/graph/properties_Polyhedron_3.h 2013-09-28 19:00:44.000000000 +0000 +++ cgal-4.5/include/CGAL/boost/graph/properties_Polyhedron_3.h 2014-08-29 13:58:16.000000000 +0000 @@ -13,7 +13,7 @@ // // $URL$ // $Id$ -// +// // // Author(s) : Andreas Fabri, Fernando Cacciola @@ -29,348 +29,370 @@ namespace CGAL { -template -class Polyhedron_edge_weight_map : public boost::put_get_helper > -{ -private: - - typedef CGAL::Polyhedron_3 Polyhedron ; - -public: - - typedef boost::readable_property_map_tag category; - typedef double value_type; - typedef double reference; - typedef typename boost::graph_traits::edge_descriptor key_type; - - Polyhedron_edge_weight_map( Polyhedron const& ) {} +namespace internal { - reference operator[](key_type const& e) const - { - return CGAL::squared_distance(e->vertex()->point(), e->opposite()->vertex()->point()); - } -}; - -template -class Polyhedron_edge_is_border_map : public boost::put_get_helper > +template +class Polyhedron_index_map_external + : public boost::put_get_helper > { -private: - - typedef CGAL::Polyhedron_3 Polyhedron ; - public: + typedef boost::readable_property_map_tag category; + typedef std::size_t value_type; + typedef std::size_t reference; + typedef Handle key_type; + + template + Polyhedron_index_map_external(InputIterator begin, InputIterator end, std::size_t max) + : map_(begin, end, 0, std::size_t(-1), max) {} - typedef boost::readable_property_map_tag category; - typedef bool value_type; - typedef bool reference; - typedef typename boost::graph_traits::edge_descriptor key_type; - - Polyhedron_edge_is_border_map( Polyhedron const& ) {} - - reference operator[](key_type const& e) const { return e->is_border(); } -}; - -template -class Polyhedron_edge_index_map_stored : public boost::put_get_helper > -{ + reference operator[](const key_type& k) const { return map_[k]; } private: - - typedef CGAL::Polyhedron_3 Polyhedron ; - -public: - - typedef boost::readable_property_map_tag category; - typedef std::size_t value_type; - typedef std::size_t reference; - typedef typename boost::graph_traits::edge_descriptor key_type; - - Polyhedron_edge_index_map_stored( Polyhedron const& ) {} - - reference operator[](key_type const& e) const { return e->id(); } + CGAL::Unique_hash_map map_; }; -template -class Polyhedron_edge_index_map_external : public boost::put_get_helper > +// Special case for edges. +template +class Polyhedron_edge_index_map_external + : public boost::put_get_helper > { -private: - - typedef CGAL::Polyhedron_3 Polyhedron ; - public: + typedef boost::readable_property_map_tag category; + typedef std::size_t value_type; + typedef std::size_t reference; + typedef typename boost::graph_traits::edge_descriptor key_type; - typedef boost::readable_property_map_tag category; - typedef std::size_t value_type; - typedef std::size_t reference; - typedef typename boost::graph_traits::edge_descriptor key_type; - - Polyhedron_edge_index_map_external( Polyhedron const& p) - : map( remove_const(p).halfedges_begin() - , remove_const(p).halfedges_end() - , 0 - , std::size_t(-1) - , p.size_of_halfedges() - ) - {} + Polyhedron_edge_index_map_external(Polyhedron& p) + : map_(std::size_t(-1), num_halfedges(p)) + { + unsigned int data = 0; + typename boost::graph_traits::edge_iterator it, end; + for(boost::tie(it, end) = edges(p); it != end; ++it, ++data) + map_[*it] = data; + } - reference operator[](key_type const& e) const { return map[e]; } - + reference operator[](const key_type& k) const { return map_[k]; } private: - - static Polyhedron& remove_const ( Polyhedron const& p ) { return const_cast(p) ; } - - CGAL::Unique_hash_map map ; + CGAL::Unique_hash_map map_; }; +template +struct Wrap_squared + : boost::put_get_helper< double, Wrap_squared > +{ + typedef double value_type; + typedef double reference; + typedef Handle key_type; + typedef boost::readable_property_map_tag category; + + template + double + // TODO Kernel::FT, this is as bad as the old code, we need to + // forward the halfedge type in HDS_edge to extract the kernel here. + // Technically, there is also a general implementation for + // HalfedgeGraph to prevent duplication in Surface_mesh. + operator[](const E& e) const { + return CGAL::squared_distance(e.halfedge()->vertex()->point(), e.halfedge()->opposite()->vertex()->point()); + } +}; -template -class Polyhedron_vertex_point_map : public boost::put_get_helper< typename Gt::Point_3&, Polyhedron_vertex_point_map > + template +struct Index_accessor + : boost::put_get_helper< std::size_t&, Index_accessor > { -private: + typedef boost::lvalue_property_map_tag category; + typedef std::size_t& reference; + typedef std::size_t value_type; + typedef Handle key_type; - typedef CGAL::Polyhedron_3 Polyhedron ; - -public: - - typedef typename Gt::Point_3 Point_3 ; - - typedef boost::lvalue_property_map_tag category; - typedef Point_3 value_type; - typedef Point_3& reference; - typedef typename boost::graph_traits::vertex_descriptor key_type; - - Polyhedron_vertex_point_map( Polyhedron& ) {} - - reference operator[](key_type const& v) const { return v->point(); } + reference operator[](Handle h) const { return h->id(); } }; -template -class Polyhedron_vertex_point_const_map : public boost::put_get_helper< typename Gt::Point_3 const& - , Polyhedron_vertex_point_const_map - > +template +struct Edge_index_accessor + : boost::put_get_helper< std::size_t, Edge_index_accessor > { -private: + typedef boost::readable_property_map_tag category; + typedef std::size_t reference; + typedef std::size_t value_type; + typedef Handle key_type; - typedef CGAL::Polyhedron_3 Polyhedron ; - -public: - - typedef typename Gt::Point_3 Point_3 ; - - typedef boost::readable_property_map_tag category; - typedef Point_3 value_type; - typedef Point_3 const& reference; - typedef typename boost::graph_traits::vertex_descriptor key_type; - - Polyhedron_vertex_point_const_map( Polyhedron const& ) {} - - reference operator[](key_type const& v) const { return v->point(); } + reference operator[](Handle h) const { return h.id(); } }; -template -class Polyhedron_vertex_index_map_stored : public boost::put_get_helper > +template +struct Point_accessor + : boost::put_get_helper< Reference, Point_accessor > { -private: + typedef boost::lvalue_property_map_tag category; + typedef Reference reference; + typedef ValueType value_type; + typedef Handle key_type; - typedef CGAL::Polyhedron_3 Polyhedron ; + reference operator[](Handle h) const { return h->point(); } +}; -public: +} // internal - typedef boost::readable_property_map_tag category; - typedef std::size_t value_type; - typedef std::size_t reference; - typedef typename boost::graph_traits::vertex_descriptor key_type; +// the tag we dispatch on from property_map +template +struct Polyhedron_property_map {}; - Polyhedron_vertex_index_map_stored( Polyhedron const& ) {} +} // namespace CGAL - reference operator[](key_type const& v) const { return v->id(); } -}; +namespace CGAL { -template -class Polyhedron_vertex_index_map_external : public boost::put_get_helper > -{ -private: +// generalized 2-ary get functions +template +typename boost::property_map< CGAL::Polyhedron_3, PropertyTag >::const_type +get(PropertyTag, CGAL::Polyhedron_3 const&) +{ return typename boost::property_map< CGAL::Polyhedron_3, PropertyTag >::const_type(); } + +template +typename boost::property_map< CGAL::Polyhedron_3, PropertyTag >::type +get(PropertyTag, CGAL::Polyhedron_3&) +{ return typename boost::property_map< CGAL::Polyhedron_3, PropertyTag >::type(); } - typedef CGAL::Polyhedron_3 Polyhedron ; - -public: +// generalized 3-ary get functions +template +typename boost::property_traits< typename boost::property_map< CGAL::Polyhedron_3, PropertyTag >::type >::reference +get(PropertyTag p, CGAL::Polyhedron_3& g, const Key& key) +{ return get(get(p, g), key); } - typedef boost::readable_property_map_tag category; - typedef std::size_t value_type; - typedef std::size_t reference; - typedef typename boost::graph_traits::vertex_descriptor key_type; - - Polyhedron_vertex_index_map_external( Polyhedron const& p) - : map( remove_const(p).vertices_begin() - , remove_const(p).vertices_end() - , 0 - , std::size_t(-1) - , p.size_of_vertices() - ) - {} +template +typename boost::property_traits< typename boost::property_map, PropertyTag >::const_type >::reference +get(PropertyTag p, CGAL::Polyhedron_3 const& g, const Key& key) +{ return get(get(p, g), key); } - reference operator[](key_type const& v) const { return map[v]; } - -private: +// generalized put +template +void put(PropertyTag p, CGAL::Polyhedron_3& g, const Key& key, const Value& value) +{ + typedef typename boost::property_map, PropertyTag>::type Map; + Map pmap = get(p, g); + put(pmap, key, value); +} - static Polyhedron& remove_const ( Polyhedron const& p ) { return const_cast(p) ; } - - CGAL::Unique_hash_map map ; -}; +} // boost +// specialization needs to be repeated for halfedge, vertex, face +#define CGAL_POLYHEDRON_INDEX_PM(ENTITY, TAG, ACCESSOR) \ + namespace CGAL { \ + template<> struct Polyhedron_property_map { \ + template \ + struct bind_ { \ + typedef internal::ACCESSOR##_accessor< \ + CGAL::Polyhedron_3, \ + typename boost::graph_traits< CGAL::Polyhedron_3 \ + >::ENTITY##_descriptor > type; \ + typedef type const_type; \ + }; \ + }; \ + } -template -struct Polyhedron_property_map {}; +CGAL_POLYHEDRON_INDEX_PM(halfedge, _index_t, Index) +CGAL_POLYHEDRON_INDEX_PM(vertex, _index_t, Index) +CGAL_POLYHEDRON_INDEX_PM(face, _index_t, Index) + +#undef CGAL_POLYHEDRON_INDEX_PM +namespace CGAL { +// not done with macros, because HDS_edge::id does not return a +// reference template <> -struct Polyhedron_property_map +struct Polyhedron_property_map { template - struct bind_ + struct bind_ { - typedef Polyhedron_edge_weight_map type; - typedef Polyhedron_edge_weight_map const_type; + typedef internal::Edge_index_accessor< + typename boost::graph_traits< + CGAL::Polyhedron_3 + >::edge_descriptor > type; + typedef type const_type; }; }; - template <> -struct Polyhedron_property_map +struct Polyhedron_property_map { template - struct bind_ + struct bind_ { - typedef Polyhedron_edge_index_map_stored type; - typedef Polyhedron_edge_index_map_stored const_type; + typedef internal::Wrap_squared< + typename boost::graph_traits< + CGAL::Polyhedron_3 + >::edge_descriptor > type; + typedef type const_type; }; }; template <> -struct Polyhedron_property_map +struct Polyhedron_property_map { template - struct bind_ + struct bind_ { - typedef Polyhedron_edge_index_map_external type; - typedef Polyhedron_edge_index_map_external const_type; + typedef internal::Point_accessor< + typename boost::graph_traits< + CGAL::Polyhedron_3 + >::vertex_descriptor, + typename Gt::Point_3, typename Gt::Point_3&> type; + + typedef internal::Point_accessor< + typename boost::graph_traits< + CGAL::Polyhedron_3 + >::vertex_descriptor, + typename Gt::Point_3, const typename Gt::Point_3&> const_type; }; }; +// +// external indices +// + template <> -struct Polyhedron_property_map +struct Polyhedron_property_map { template - struct bind_ + struct bind_ { - typedef Polyhedron_edge_is_border_map type; - typedef Polyhedron_edge_is_border_map const_type; + typedef internal::Polyhedron_edge_index_map_external< + CGAL::Polyhedron_3 + > type; + typedef type const_type; }; }; template <> -struct Polyhedron_property_map +struct Polyhedron_property_map { template - struct bind_ + struct bind_ { - typedef Polyhedron_vertex_point_map type; - typedef Polyhedron_vertex_point_const_map const_type; + typedef internal::Polyhedron_index_map_external< + typename boost::graph_traits< + CGAL::Polyhedron_3 + >::halfedge_descriptor > type; + typedef type const_type; }; }; + template <> -struct Polyhedron_property_map +struct Polyhedron_property_map { template - struct bind_ + struct bind_ { - typedef Polyhedron_vertex_index_map_stored type; - typedef Polyhedron_vertex_index_map_stored const_type; + typedef internal::Polyhedron_index_map_external< + typename boost::graph_traits< + CGAL::Polyhedron_3 + >::vertex_descriptor > type; + typedef type const_type; }; }; template <> -struct Polyhedron_property_map +struct Polyhedron_property_map { template - struct bind_ + struct bind_ { - typedef Polyhedron_vertex_index_map_external type; - typedef Polyhedron_vertex_index_map_external const_type; + typedef internal::Polyhedron_index_map_external< + typename boost::graph_traits< + CGAL::Polyhedron_3 + >::face_descriptor > type; + typedef type const_type; }; }; -} //namespace CGAL +} // CGAL -namespace boost -{ +namespace CGAL { template -inline -CGAL::Polyhedron_edge_weight_map get( edge_weight_t, CGAL::Polyhedron_3 const& p) +typename boost::property_map< CGAL::Polyhedron_3, boost::edge_external_index_t >::const_type +get(boost::edge_external_index_t, CGAL::Polyhedron_3 const& p) { - CGAL::Polyhedron_edge_weight_map m(p); - return m; + return typename boost::property_map< CGAL::Polyhedron_3, boost::edge_external_index_t >::const_type( + const_cast& >(p)); } template -inline -CGAL::Polyhedron_edge_is_border_map get( CGAL::edge_is_border_t, CGAL::Polyhedron_3 const& p) +typename boost::property_map< CGAL::Polyhedron_3, boost::halfedge_external_index_t >::const_type +get(boost::halfedge_external_index_t, CGAL::Polyhedron_3 const& p) { - CGAL::Polyhedron_edge_is_border_map m(p); - return m; + CGAL::Polyhedron_3& ncp = const_cast&>(p); + + return typename boost::property_map< CGAL::Polyhedron_3, boost::halfedge_external_index_t >::const_type( + ncp.halfedges_begin(), ncp.halfedges_end(), ncp.size_of_halfedges()); } template -inline -CGAL::Polyhedron_edge_index_map_stored get( edge_index_t, CGAL::Polyhedron_3 const& p) +typename boost::property_map< CGAL::Polyhedron_3, boost::vertex_external_index_t >::const_type +get(boost::vertex_external_index_t, CGAL::Polyhedron_3 const& p) { - CGAL::Polyhedron_edge_index_map_stored m(p); - return m; + CGAL::Polyhedron_3& ncp = const_cast&>(p); + + return typename boost::property_map< CGAL::Polyhedron_3, boost::vertex_external_index_t >::const_type( + ncp.vertices_begin(), ncp.vertices_end(), ncp.size_of_vertices()); } template -inline -CGAL::Polyhedron_edge_index_map_external get( CGAL::edge_external_index_t, CGAL::Polyhedron_3 const& p) +typename boost::property_map< CGAL::Polyhedron_3, boost::face_external_index_t >::const_type +get(boost::face_external_index_t, CGAL::Polyhedron_3 const& p) { - CGAL::Polyhedron_edge_index_map_external m(p); - return m; + CGAL::Polyhedron_3& ncp = const_cast&>(p); + + return typename boost::property_map< CGAL::Polyhedron_3, boost::face_external_index_t >::const_type( + ncp.facets_begin(), ncp.facets_end(), ncp.size_of_facets()); } +// the same blurb for non-const + template -inline -CGAL::Polyhedron_vertex_point_map get(CGAL::vertex_point_t, CGAL::Polyhedron_3& p) +typename boost::property_map< CGAL::Polyhedron_3, boost::edge_external_index_t >::type +get(boost::edge_external_index_t, CGAL::Polyhedron_3& p) { - CGAL::Polyhedron_vertex_point_map m(p); - return m; + return typename boost::property_map< CGAL::Polyhedron_3, boost::edge_external_index_t >::type( + p); } template -inline -CGAL::Polyhedron_vertex_point_const_map get(CGAL::vertex_point_t, CGAL::Polyhedron_3 const& p) +typename boost::property_map< CGAL::Polyhedron_3, boost::halfedge_external_index_t >::type +get(boost::halfedge_external_index_t, CGAL::Polyhedron_3 & ncp) { - CGAL::Polyhedron_vertex_point_const_map m(p); - return m; + return typename boost::property_map< CGAL::Polyhedron_3, boost::halfedge_external_index_t >::type( + ncp.halfedges_begin(), ncp.halfedges_end(), ncp.size_of_halfedges()); } template -inline -CGAL::Polyhedron_vertex_index_map_stored get(vertex_index_t, CGAL::Polyhedron_3 const& p) +typename boost::property_map< CGAL::Polyhedron_3, boost::vertex_external_index_t >::type +get(boost::vertex_external_index_t, CGAL::Polyhedron_3 & ncp) { - CGAL::Polyhedron_vertex_index_map_stored m(p); - return m; + return typename boost::property_map< CGAL::Polyhedron_3, boost::vertex_external_index_t >::type( + ncp.vertices_begin(), ncp.vertices_end(), ncp.size_of_vertices()); } + template -inline -CGAL::Polyhedron_vertex_index_map_external get(CGAL::vertex_external_index_t, CGAL::Polyhedron_3 const& p) +typename boost::property_map< CGAL::Polyhedron_3, boost::face_external_index_t >::type +get(boost::face_external_index_t, CGAL::Polyhedron_3 & ncp) { - CGAL::Polyhedron_vertex_index_map_external m(p); - return m; + return typename boost::property_map< CGAL::Polyhedron_3, boost::face_external_index_t >::type( + ncp.facets_begin(), ncp.facets_end(), ncp.size_of_facets()); } + +} // namespace CGAL + + +namespace boost { + +// property_map dispatcher into Polyhedron template -struct property_map, Tag> +struct property_map, Tag> { typedef typename CGAL::Polyhedron_property_map:: template bind_ map_gen; @@ -378,9 +400,9 @@ typedef typename map_gen::const_type const_type; }; -// This partial specialization shouldn't be needed but is due to a bug in Boost 1.51. +// property_map dispatcher into const Polyhedron template -struct property_map, Tag> +struct property_map, Tag> { typedef typename CGAL::Polyhedron_property_map:: template bind_ map_gen; @@ -388,47 +410,27 @@ typedef typename map_gen::const_type const_type; }; -template -inline -typename property_traits,PropertyTag>::type>::reference -get(PropertyTag p, CGAL::Polyhedron_3& g, const Key& key) -{ - return get(get(p, g), key); -} - -template -inline -typename property_traits,PropertyTag>::const_type>::reference -get(PropertyTag p, CGAL::Polyhedron_3 const& g, const Key& key) -{ - return get(get(p, g), key); -} - -template -inline -void put(PropertyTag p, CGAL::Polyhedron_3& g, const Key& key, const Value& value) -{ - typedef typename property_map, PropertyTag>::type Map; - Map pmap = get(p, g); - put(pmap, key, value); -} - - // What are those needed for ??? template -struct edge_property_type > +struct edge_property_type > { typedef edge_weight_t type; -}; +}; template -struct vertex_property_type > +struct vertex_property_type > +{ + typedef CGAL::vertex_point_t type; +}; + +template +struct vertex_property_type > { typedef CGAL::vertex_point_t type; }; - } // namespace boost + #undef CGAL_HDS_PARAM_ #endif // CGAL_BOOST_GRAPH_PROPERTIES_POLYHEDRON_3_H diff -Nru cgal-4.4/include/CGAL/boost/graph/properties_PolyMesh_ArrayKernelT.h cgal-4.5/include/CGAL/boost/graph/properties_PolyMesh_ArrayKernelT.h --- cgal-4.4/include/CGAL/boost/graph/properties_PolyMesh_ArrayKernelT.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/boost/graph/properties_PolyMesh_ArrayKernelT.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,288 @@ +// Copyright (c) 2014 GeometryFactory (France). All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Philipp Möller + + +#ifndef CGAL_PROPERTIES_POLYMESH_ARRAYKERNELT_H +#define CGAL_PROPERTIES_POLYMESH_ARRAYKERNELT_H + +#include +#include +#include +#include + +namespace CGAL { + + +template +class OM_edge_weight_pmap + : public boost::put_get_helper::Scalar , OM_edge_weight_pmap > +{ +public: + typedef boost::readable_property_map_tag category; + typedef typename OpenMesh::PolyMesh_ArrayKernelT::Scalar value_type; + typedef value_type reference; + typedef typename boost::graph_traits >::edge_descriptor key_type; + + OM_edge_weight_pmap(const OpenMesh::PolyMesh_ArrayKernelT& sm) + : sm_(sm) + {} + + value_type operator[](const key_type& e) const + { + return sm_.calc_edge_length(e.halfedge()); + } + +private: + const OpenMesh::PolyMesh_ArrayKernelT& sm_; +}; + +template +class OM_index_pmap : public boost::put_get_helper > +{ +public: + typedef boost::readable_property_map_tag category; + typedef std::size_t value_type; + typedef std::size_t reference; + typedef VEF key_type; + + value_type operator[](const key_type& vd) const + { + return vd.idx(); + } +}; + + + template +class OM_point_pmap //: public boost::put_get_helper > +{ +public: + typedef boost::read_write_property_map_tag category; +#if defined(CGAL_USE_OM_POINTS) + typedef typename OpenMesh::PolyMesh_ArrayKernelT::Point value_type; + typedef const typename OpenMesh::PolyMesh_ArrayKernelT::Point& reference; +#else + typedef P value_type; + typedef P reference; +#endif + typedef typename boost::graph_traits< OpenMesh::PolyMesh_ArrayKernelT >::vertex_descriptor key_type; + + OM_point_pmap() + : sm_(NULL) + {} + + OM_point_pmap(const OpenMesh::PolyMesh_ArrayKernelT& sm) + : sm_(&sm) + {} + + OM_point_pmap(const OM_point_pmap& pm) + : sm_(pm.sm_) + {} + + inline friend reference get(const OM_point_pmap& pm, key_type v) + { + CGAL_precondition(pm.sm_!=NULL); +#if defined(CGAL_USE_OM_POINTS) + return pm.sm_->point(v); +#else + typename OpenMesh::PolyMesh_ArrayKernelT::Point const& omp = pm.sm_->point(v); + return value_type(omp[0], omp[1], omp[2]); +#endif + } + + inline friend void put(const OM_point_pmap& pm, key_type v, const value_type& p) + { + CGAL_precondition(pm.sm_!=NULL); +#if defined(CGAL_USE_OM_POINTS) + const_cast&>(*pm.sm_).set_point(v,p); +#else + const_cast&>(*pm.sm_).set_point + (v, typename OpenMesh::PolyMesh_ArrayKernelT::Point(p[0], p[1], p[2])); +#endif + } + + private: + const OpenMesh::PolyMesh_ArrayKernelT* sm_; +}; + + +} // CGAL + +// overloads and specializations in the boost namespace +namespace boost { + +// +// edge_weight +// + + +template +struct property_map, boost::edge_weight_t > +{ + typedef CGAL::OM_edge_weight_pmap type; + typedef CGAL::OM_edge_weight_pmap const_type; +}; + + + +// +// vertex_index +// + +template +struct property_map, boost::vertex_index_t > +{ + typedef CGAL::OM_index_pmap >::vertex_descriptor> type; + typedef CGAL::OM_index_pmap >::vertex_descriptor> const_type; +}; + + +// +// face_index +// + +template +struct property_map, boost::face_index_t > +{ + typedef CGAL::OM_index_pmap >::face_descriptor> type; + typedef CGAL::OM_index_pmap >::face_descriptor> const_type; +}; + +// +// edge_index +// + +template +struct property_map, boost::edge_index_t > +{ + typedef CGAL::OM_index_pmap >::edge_descriptor> type; + typedef CGAL::OM_index_pmap >::edge_descriptor> const_type; +}; + +// +// halfedge_index +// + +template +struct property_map, boost::halfedge_index_t > +{ + typedef CGAL::OM_index_pmap >::halfedge_descriptor> type; + typedef CGAL::OM_index_pmap >::halfedge_descriptor> const_type; +}; + + +template +struct property_map, boost::vertex_point_t > +{ + typedef CGAL::Exact_predicates_inexact_constructions_kernel::Point_3 P; + typedef CGAL::OM_point_pmap type; + typedef type const_type; +}; + +} // namespace boost + +namespace boost { + + +template +typename boost::property_map, boost::edge_weight_t>::const_type +get(boost::edge_weight_t, const OpenMesh::PolyMesh_ArrayKernelT& sm) +{ + return CGAL::OM_edge_weight_pmap(sm); +} + +template +typename OpenMesh::PolyMesh_ArrayKernelT::Scalar +get(boost::edge_weight_t, const OpenMesh::PolyMesh_ArrayKernelT& sm, + const typename boost::graph_traits >::edge_descriptor& e) +{ + return CGAL::OM_edge_weight_pmap(sm)[e]; +} + + +template +CGAL::OM_index_pmap >::vertex_descriptor> +get(const boost::vertex_index_t&, const OpenMesh::PolyMesh_ArrayKernelT&) +{ + return CGAL::OM_index_pmap >::vertex_descriptor>(); +} + +template +typename boost::property_map, boost::face_index_t>::const_type +get(const boost::face_index_t&, const OpenMesh::PolyMesh_ArrayKernelT&) +{ + return CGAL::OM_index_pmap >::face_descriptor>(); +} + +template +CGAL::OM_index_pmap >::edge_descriptor> +get(const boost::edge_index_t&, const OpenMesh::PolyMesh_ArrayKernelT&) +{ + return CGAL::OM_index_pmap >::edge_descriptor>(); +} + +template +CGAL::OM_index_pmap >::halfedge_descriptor> +get(const boost::halfedge_index_t&, const OpenMesh::PolyMesh_ArrayKernelT&) +{ + return CGAL::OM_index_pmap >::halfedge_descriptor>(); +} + +template +CGAL::OM_point_pmap +get(boost::vertex_point_t, const OpenMesh::PolyMesh_ArrayKernelT& g) +{ + typedef typename CGAL::Exact_predicates_inexact_constructions_kernel::Point_3 P; + return CGAL::OM_point_pmap(g); +} + +// get for intrinsic properties +#define CGAL_OM_INTRINSIC_PROPERTY(RET, PROP, TYPE) \ + template \ + RET \ + get(PROP p, const OpenMesh::PolyMesh_ArrayKernelT& sm, \ + typename boost::graph_traits< OpenMesh::PolyMesh_ArrayKernelT >::TYPE x) \ + { return get(get(p, sm), x); } \ + + CGAL_OM_INTRINSIC_PROPERTY(std::size_t, boost::vertex_index_t, vertex_descriptor) + CGAL_OM_INTRINSIC_PROPERTY(std::size_t, boost::edge_index_t, edge_descriptor) + CGAL_OM_INTRINSIC_PROPERTY(int, boost::halfedge_index_t, halfedge_descriptor) + CGAL_OM_INTRINSIC_PROPERTY(std::size_t, boost::face_index_t, face_descriptor) + // CGAL_OM_INTRINSIC_PROPERTY(std::size_t, boost::halfedge_index_t, face_descriptor) + CGAL_OM_INTRINSIC_PROPERTY(typename CGAL::Exact_predicates_inexact_constructions_kernel::Point_3, boost::vertex_point_t, vertex_descriptor) + +#undef CGAL_OM_INTRINSIC_PROPERTY + +// put for intrinsic properties +// only available for vertex_point + +template +void +put(boost::vertex_point_t p, OpenMesh::PolyMesh_ArrayKernelT& g, + typename boost::graph_traits< OpenMesh::PolyMesh_ArrayKernelT >::vertex_descriptor vd, + const typename K::Point& point) +{ + put(get(p,g), vd, point); +} + + +} // namespace boost + + + +#endif /* CGAL_PROPERTIES_POLYMESH_ARRAYKERNELT_H */ diff -Nru cgal-4.4/include/CGAL/Cartesian/function_objects.h cgal-4.5/include/CGAL/Cartesian/function_objects.h --- cgal-4.4/include/CGAL/Cartesian/function_objects.h 2012-11-13 13:13:54.000000000 +0000 +++ cgal-4.5/include/CGAL/Cartesian/function_objects.h 2014-08-29 13:58:16.000000000 +0000 @@ -68,17 +68,34 @@ template class Angle_3 { - typedef typename K::Point_3 Point_3; + typedef typename K::Point_3 Point_3; + typedef typename K::Vector_3 Vector_3; public: - typedef typename K::Angle result_type; + typedef typename K::Angle result_type; result_type + operator()(const Vector_3& u, const Vector_3& v) const + { + return angleC3(u.x(), u.y(), u.z(), + v.x(), v.y(), v.z()); + } + result_type operator()(const Point_3& p, const Point_3& q, const Point_3& r) const { return angleC3(p.x(), p.y(), p.z(), q.x(), q.y(), q.z(), r.x(), r.y(), r.z()); } + + result_type + operator()(const Point_3& p, const Point_3& q, + const Point_3& r, const Point_3& s) const + { + return angleC3(p.x(), p.y(), p.z(), + q.x(), q.y(), q.z(), + r.x(), r.y(), r.z(), + s.x(), s.y(), s.z()); + } }; template @@ -167,8 +184,8 @@ operator()( const Circle_2& c, const Point_2& p) const { typename K::Compute_squared_distance_2 squared_distance; - return enum_cast(CGAL_NTS compare(c.squared_radius(), - squared_distance(c.center(),p))); + return enum_cast(CGAL::compare(c.squared_radius(), + squared_distance(c.center(),p))); } result_type @@ -430,14 +447,14 @@ result_type operator()(const T1& p, const T2& q, const T3& r) const { - return CGAL_NTS compare(squared_distance(p, q), squared_distance(p, r)); + return CGAL::compare(squared_distance(p, q), squared_distance(p, r)); } template result_type operator()(const T1& p, const T2& q, const T3& r, const T4& s) const { - return CGAL_NTS compare(squared_distance(p, q), squared_distance(r, s)); + return CGAL::compare(squared_distance(p, q), squared_distance(r, s)); } }; @@ -460,14 +477,14 @@ result_type operator()(const T1& p, const T2& q, const T3& r) const { - return CGAL_NTS compare(squared_distance(p, q), squared_distance(p, r)); + return CGAL::compare(squared_distance(p, q), squared_distance(p, r)); } template result_type operator()(const T1& p, const T2& q, const T3& r, const T4& s) const { - return CGAL_NTS compare(squared_distance(p, q), squared_distance(r, s)); + return CGAL::compare(squared_distance(p, q), squared_distance(r, s)); } }; @@ -482,28 +499,28 @@ result_type operator()(const Point_3& p, const Point_3& q, const Point_3& r, const Point_3& s, const FT& ft) const { - return CGAL_NTS compare(squared_radiusC3(p.x(), p.y(), p.z(), - q.x(), q.y(), q.z(), - r.x(), r.y(), r.z(), - s.x(), s.y(), s.z() ), - ft); + return CGAL::compare(squared_radiusC3(p.x(), p.y(), p.z(), + q.x(), q.y(), q.z(), + r.x(), r.y(), r.z(), + s.x(), s.y(), s.z() ), + ft); } result_type operator()(const Point_3& p, const Point_3& q, const Point_3& r, const FT& ft) const { - return CGAL_NTS compare(squared_radiusC3(p.x(), p.y(), p.z(), - q.x(), q.y(), q.z(), - r.x(), r.y(), r.z()), - ft); + return CGAL::compare(squared_radiusC3(p.x(), p.y(), p.z(), + q.x(), q.y(), q.z(), + r.x(), r.y(), r.z()), + ft); } result_type operator()(const Point_3& p, const Point_3& q, const FT& ft) const { - return CGAL_NTS compare(squared_radiusC3(p.x(), p.y(), p.z(), - q.x(), q.y(), q.z() ), - ft); + return CGAL::compare(squared_radiusC3(p.x(), p.y(), p.z(), + q.x(), q.y(), q.z() ), + ft); } result_type @@ -623,7 +640,7 @@ result_type operator()( const Point_2& p, const Point_2& q) const - { return CGAL_NTS compare(p.x(), q.x()); } + { return CGAL::compare(p.x(), q.x()); } result_type operator()( const Point_2& p, const Line_2& l, const Line_2& h) const @@ -654,7 +671,7 @@ result_type operator()( const Point_3& p, const Point_3& q) const - { return CGAL_NTS compare(p.x(), q.x()); } + { return CGAL::compare(p.x(), q.x()); } }; template @@ -734,7 +751,7 @@ result_type operator()( const Point_2& p, const Point_2& q) const - { return CGAL_NTS compare(p.y(), q.y()); } + { return CGAL::compare(p.y(), q.y()); } result_type operator()( const Point_2& p, const Line_2& l1, const Line_2& l2) const @@ -769,7 +786,7 @@ result_type operator()( const Point_3& p, const Point_3& q) const - { return CGAL_NTS compare(p.y(), q.y()); } + { return CGAL::compare(p.y(), q.y()); } }; template @@ -781,7 +798,7 @@ result_type operator()( const Point_3& p, const Point_3& q) const - { return CGAL_NTS compare(p.z(), q.z()); } + { return CGAL::compare(p.z(), q.z()); } }; template diff -Nru cgal-4.4/include/CGAL/Cartesian/MatrixC33.h cgal-4.5/include/CGAL/Cartesian/MatrixC33.h --- cgal-4.4/include/CGAL/Cartesian/MatrixC33.h 2012-11-13 13:14:01.000000000 +0000 +++ cgal-4.5/include/CGAL/Cartesian/MatrixC33.h 2014-08-29 13:58:17.000000000 +0000 @@ -35,7 +35,7 @@ typedef R_ R ; - typedef typename R::RT RT ; + typedef typename R::FT RT ; typedef typename R::Vector_3 Vector_3; MatrixC33 ( Null_matrix ) diff -Nru cgal-4.4/include/CGAL/CC_safe_handle.h cgal-4.5/include/CGAL/CC_safe_handle.h --- cgal-4.4/include/CGAL/CC_safe_handle.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/CC_safe_handle.h 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,61 @@ +// Copyright (c) 2012 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL: $ +// $Id: $ +// +// Author(s) : Clement Jamin + +#ifndef CGAL_CC_SAFE_HANDLE_H +#define CGAL_CC_SAFE_HANDLE_H + +namespace CGAL { + +// CC_safe_handle is a helper that store a CC handle and its erase +// counter value (value when the CC_safe_handle instance was created). +// The is_zombie() function allows to know if the pointee was erased since. +template +class CC_safe_handle +{ +public: + CC_safe_handle(CC_iterator iterator) + : m_handle(iterator) + , m_erase_counter_value(iterator->erase_counter()) + { + } + + bool is_zombie() const + { + return m_handle->erase_counter() != m_erase_counter_value; + } + + CC_iterator cc_iterator() const + { + return m_handle; + } + +protected: + CC_iterator m_handle; + unsigned int m_erase_counter_value; +}; + +template +CC_safe_handle make_cc_safe_handle(CC_iterator iterator) +{ + return CC_safe_handle(iterator); +} + +} //namespace CGAL + +#endif // CGAL_CC_SAFE_HANDLE_H diff -Nru cgal-4.4/include/CGAL/Cell_attribute.h cgal-4.5/include/CGAL/Cell_attribute.h --- cgal-4.4/include/CGAL/Cell_attribute.h 2013-11-30 20:00:26.000000000 +0000 +++ cgal-4.5/include/CGAL/Cell_attribute.h 2014-08-29 13:58:16.000000000 +0000 @@ -70,16 +70,16 @@ template < unsigned int, class, class, class, class > friend class Combinatorial_map_base; + template < unsigned int, class, class, class, class > + friend class Generalized_map_base; + template friend struct Dart; - template < unsigned int, class, class, class > - friend class Generalized_map_base; - - template + template friend struct GMap_dart; - template + template friend class Compact_container; template @@ -182,16 +182,16 @@ template < unsigned int, class, class, class, class > friend class Combinatorial_map_base; + template < unsigned int, class, class, class, class > + friend class Generalized_map_base; + template friend struct Dart; - template < unsigned int, class, class, class > - friend class Generalized_map_base; - - template + template friend struct GMap_dart; - template + template friend class Compact_container; template @@ -300,7 +300,10 @@ template < unsigned int, class, class, class, class > friend class Combinatorial_map_base; - template + template < unsigned int, class, class, class, class > + friend class Generalized_map_base; + + template friend class Compact_container; public: @@ -329,7 +332,10 @@ template < unsigned int, class, class, class, class > friend class Combinatorial_map_base; - template + template < unsigned int, class, class, class, class > + friend class Generalized_map_base; + + template friend class Compact_container; public: diff -Nru cgal-4.4/include/CGAL/Cell_attribute_with_point.h cgal-4.5/include/CGAL/Cell_attribute_with_point.h --- cgal-4.4/include/CGAL/Cell_attribute_with_point.h 2013-11-30 20:00:27.000000000 +0000 +++ cgal-4.5/include/CGAL/Cell_attribute_with_point.h 2014-08-29 13:58:16.000000000 +0000 @@ -66,7 +66,7 @@ template < unsigned int, class, class, class, class > friend class Combinatorial_map_base; - template + template friend class Compact_container; public: @@ -121,7 +121,7 @@ template < unsigned int, class, class, class, class > friend class Combinatorial_map_base; - template + template friend class Compact_container; public: diff -Nru cgal-4.4/include/CGAL/Combinatorial_map.h cgal-4.5/include/CGAL/Combinatorial_map.h --- cgal-4.4/include/CGAL/Combinatorial_map.h 2013-11-30 20:00:27.000000000 +0000 +++ cgal-4.5/include/CGAL/Combinatorial_map.h 2014-08-29 13:58:16.000000000 +0000 @@ -475,12 +475,12 @@ */ Dart_handle first_dart() { - if (darts().begin() == darts().end()) return null_dart_handle; + if (darts().begin() == darts().end()) return null_handle; return mdarts.begin(); } Dart_const_handle first_dart() const { - if (darts().begin() == darts().end()) return null_dart_handle; + if (darts().begin() == darts().end()) return null_handle; return mdarts.begin(); } @@ -1272,18 +1272,8 @@ typename Attribute_handle::type res= CGAL::cpp11::get::value> (mattribute_containers).emplace(args...); - return res; - } - // If one attribute, could be a copy constructor => need to reinitialize - // ref counting - template - typename Attribute_handle::type create_attribute(const T1& t1) - { - CGAL_static_assertion_msg(Helper::template Dimension_index::value>=0, - "create_attribute but i-attributes are disabled"); - typename Attribute_handle::type res= - CGAL::cpp11::get::value> - (mattribute_containers).emplace(t1); + // Reinitialize the ref counting of the new attribute. This is normally + // not required except if create_attribute is used as "copy contructor". this->template get_attribute(res).mrefcounting = 0; return res; } diff -Nru cgal-4.4/include/CGAL/Compact_container.h cgal-4.5/include/CGAL/Compact_container.h --- cgal-4.4/include/CGAL/Compact_container.h 2013-12-14 20:00:35.000000000 +0000 +++ cgal-4.5/include/CGAL/Compact_container.h 2014-08-29 13:58:17.000000000 +0000 @@ -1,4 +1,5 @@ // Copyright (c) 2003,2004,2007-2010 INRIA Sophia-Antipolis (France). +// Copyright (c) 2014 GeometryFactory Sarl (France) // All rights reserved. // // This file is part of CGAL (www.cgal.org); you can redistribute it and/or @@ -30,6 +31,8 @@ #include #include +#include +#include #include @@ -82,9 +85,78 @@ namespace CGAL { +#define CGAL_GENERATE_MEMBER_DETECTOR(X) \ +template class has_##X { \ + struct Fallback { int X; }; \ + struct Derived : T, Fallback { }; \ + \ + template struct Check; \ + \ + typedef char ArrayOfOne[1]; \ + typedef char ArrayOfTwo[2]; \ + \ + template static ArrayOfOne & func( \ + Check *); \ + template static ArrayOfTwo & func(...); \ + public: \ + typedef has_##X type; \ + enum { value = sizeof(func(0)) == 2 }; \ +} // semicolon is after the macro call + #define CGAL_INIT_COMPACT_CONTAINER_BLOCK_SIZE 14 -#define CGAL_INCREMENT_COMPACT_CONTAINER_BLOCK_SIZE 16 - +#define CGAL_INCREMENT_COMPACT_CONTAINER_BLOCK_SIZE 16 + +template +struct Addition_size_policy +{ + static const unsigned int first_block_size = first_block_size_; + + template + static void increase_size(Compact_container& cc) + { cc.block_size += block_size_increment; } + + template + static void get_index_and_block(typename Compact_container::size_type i, + typename Compact_container::size_type& index, + typename Compact_container::size_type& block) + { + typedef typename Compact_container::size_type ST; + const ST TWO_M_N = 2*first_block_size_ - block_size_increment; + ST delta = TWO_M_N*TWO_M_N + 8*block_size_increment*i; + block= (static_cast(std::sqrt(static_cast(delta))) - TWO_M_N) + / (2*block_size_increment); + + if ( block==0 ) + { index = i + 1; } + else + { + const typename Compact_container::size_type first_element_in_block = + block*(first_block_size_+ (block_size_increment*(block - 1))/2); + + index=i - first_element_in_block + 1; + } + } +}; + +template +struct Constant_size_policy +{ + static const unsigned int first_block_size = k; + + template + static void increase_size(Compact_container& /*cc*/) + {} + + template + static void get_index_and_block(typename Compact_container::size_type i, + typename Compact_container::size_type& index, + typename Compact_container::size_type& block) + { + block=i/k; + index=(i%k)+1; + } +}; + // The following base class can be used to easily add a squattable pointer // to a class (maybe you loose a bit of compactness though). // TODO : Shouldn't adding these bits be done automatically and transparently, @@ -110,16 +182,69 @@ namespace internal { template < class DSC, bool Const > class CC_iterator; + + CGAL_GENERATE_MEMBER_DETECTOR(increment_erase_counter); + + // A basic "no erase counter" strategy + template + class Erase_counter_strategy { + public: + // Do nothing + template + static unsigned int erase_counter(const Element &) { return 0; } + template + static void set_erase_counter(Element &, unsigned int) {} + template + static void increment_erase_counter(Element &) {} + }; + + + // A strategy managing an internal counter + template <> + class Erase_counter_strategy + { + public: + template + static unsigned int erase_counter(const Element &e) + { + return e.erase_counter(); + } + + template + static void set_erase_counter(Element &e, unsigned int c) + { + e.set_erase_counter(c); + } + + template + static void increment_erase_counter(Element &e) + { + e.increment_erase_counter(); + } + }; } -template < class T, class Allocator_ = Default > +template < class T, + class Allocator_ = Default, + class Increment_policy_ = Default, + class TimeStamper_ = Default > class Compact_container { typedef Allocator_ Al; typedef typename Default::Get< Al, CGAL_ALLOCATOR(T) >::type Allocator; - typedef Compact_container Self; + typedef Increment_policy_ Ip; + typedef typename Default::Get< Ip, + Addition_size_policy + >::type Increment_policy; + typedef TimeStamper_ Ts; + typedef Compact_container Self; typedef Compact_container_traits Traits; public: + typedef typename Default::Get< TimeStamper_, + CGAL::Time_stamper_impl >::type + Time_stamper_impl; + typedef T value_type; typedef Allocator allocator_type; typedef typename Allocator::reference reference; @@ -128,24 +253,30 @@ typedef typename Allocator::const_pointer const_pointer; typedef typename Allocator::size_type size_type; typedef typename Allocator::difference_type difference_type; - typedef internal::CC_iterator iterator; - typedef internal::CC_iterator const_iterator; + typedef internal::CC_iterator iterator; + typedef internal::CC_iterator const_iterator; typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; friend class internal::CC_iterator; friend class internal::CC_iterator; + template + friend struct Addition_size_policy; + template friend struct Constant_size_policy; + explicit Compact_container(const Allocator &a = Allocator()) : alloc(a) + , time_stamper(new Time_stamper_impl()) { - init(); + init (); } template < class InputIterator > Compact_container(InputIterator first, InputIterator last, const Allocator & a = Allocator()) : alloc(a) + , time_stamper(new Time_stamper_impl()) { init(); std::copy(first, last, CGAL::inserter(*this)); @@ -154,9 +285,11 @@ // The copy constructor and assignment operator preserve the iterator order Compact_container(const Compact_container &c) : alloc(c.get_allocator()) + , time_stamper(new Time_stamper_impl()) { init(); block_size = c.block_size; + *time_stamper = *c.time_stamper; std::copy(c.begin(), c.end(), CGAL::inserter(*this)); } @@ -172,6 +305,39 @@ ~Compact_container() { clear(); + delete time_stamper; + } + + bool is_used(size_type i) const + { + typename Self::size_type block_number, index_in_block; + Increment_policy::template get_index_and_block(i, + index_in_block, + block_number); + return (type(&all_items[block_number].first[index_in_block]) + == USED); + } + + const T& operator[] (size_type i) const + { + CGAL_assertion( is_used(i) ); + + typename Self::size_type block_number, index_in_block; + Increment_policy::template get_index_and_block(i, + index_in_block, + block_number); + return all_items[block_number].first[index_in_block]; + } + + T& operator[] (size_type i) + { + CGAL_assertion( is_used(i) ); + + typename Self::size_type block_number, index_in_block; + Increment_policy::template get_index_and_block(i, + index_in_block, + block_number); + return all_items[block_number].first[index_in_block]; } void swap(Self &c) @@ -184,6 +350,7 @@ std::swap(last_item, c.last_item); std::swap(free_list, c.free_list); all_items.swap(c.all_items); + std::swap(time_stamper, c.time_stamper); } iterator begin() { return iterator(first_item, 0, 0); } @@ -229,6 +396,7 @@ new (ret) value_type(args...); CGAL_assertion(type(ret) == USED); ++size_; + time_stamper->set_time_stamp(ret); return iterator(ret, 0); } #else @@ -243,6 +411,7 @@ new (ret) value_type(); CGAL_assertion(type(ret) == USED); ++size_; + time_stamper->set_time_stamp(ret); return iterator(ret, 0); } @@ -258,6 +427,7 @@ new (ret) value_type(t1); CGAL_assertion(type(ret) == USED); ++size_; + time_stamper->set_time_stamp(ret); return iterator(ret, 0); } @@ -273,6 +443,7 @@ new (ret) value_type(t1, t2); CGAL_assertion(type(ret) == USED); ++size_; + time_stamper->set_time_stamp(ret); return iterator(ret, 0); } @@ -288,6 +459,7 @@ new (ret) value_type(t1, t2, t3); CGAL_assertion(type(ret) == USED); ++size_; + time_stamper->set_time_stamp(ret); return iterator(ret, 0); } @@ -303,13 +475,14 @@ new (ret) value_type(t1, t2, t3, t4); CGAL_assertion(type(ret) == USED); ++size_; + time_stamper->set_time_stamp(ret); return iterator(ret, 0); } template < typename T1, typename T2, typename T3, typename T4, typename T5 > iterator emplace(const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4, - const T5 &t5) + const T5 &t5) { if (free_list == NULL) allocate_new_block(); @@ -319,6 +492,7 @@ new (ret) value_type(t1, t2, t3, t4, t5); CGAL_assertion(type(ret) == USED); ++size_; + time_stamper->set_time_stamp(ret); return iterator(ret, 0); } @@ -336,6 +510,7 @@ new (ret) value_type(t1, t2, t3, t4, t5, t6); CGAL_assertion(type(ret) == USED); ++size_; + time_stamper->set_time_stamp(ret); return iterator(ret, 0); } @@ -353,6 +528,7 @@ new (ret) value_type(t1, t2, t3, t4, t5, t6, t7); CGAL_assertion(type(ret) == USED); ++size_; + time_stamper->set_time_stamp(ret); return iterator(ret, 0); } @@ -370,6 +546,7 @@ new (ret) value_type(t1, t2, t3, t4, t5, t6, t7, t8); CGAL_assertion(type(ret) == USED); ++size_; + time_stamper->set_time_stamp(ret); return iterator(ret, 0); } #endif // CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES @@ -384,6 +561,7 @@ alloc.construct(ret, t); CGAL_assertion(type(ret) == USED); ++size_; + time_stamper->set_time_stamp(ret); return iterator(ret, 0); } @@ -403,11 +581,15 @@ void erase(iterator x) { + typedef internal::Erase_counter_strategy< + internal::has_increment_erase_counter::value> EraseCounterStrategy; + CGAL_precondition(type(&*x) == USED); + EraseCounterStrategy::increment_erase_counter(*x); alloc.destroy(&*x); -#ifndef CGAL_NO_ASSERTIONS +/*#ifndef CGAL_NO_ASSERTIONS std::memset(&*x, 0, sizeof(T)); -#endif +#endif*/ put_on_free_list(&*x); --size_; } @@ -491,16 +673,52 @@ /** Reserve method to ensure that the capacity of the Compact_container be * greater or equal than a given value n. - */ + */ void reserve(size_type n) { if ( capacity_>=n ) return; - size_type tmp = block_size; - block_size = (std::max)( n - capacity_, block_size ); - allocate_new_block(); - block_size = tmp+CGAL_INCREMENT_COMPACT_CONTAINER_BLOCK_SIZE; + + size_type lastblock = all_items.size(); + + while ( capacity_= 1; --i) + put_on_free_list(new_block + i); + } + while ( curblock>lastblock ); } - + private: void allocate_new_block(); @@ -552,7 +770,7 @@ { // This out of range compare is always true and causes lots of // unnecessary warnings. - // CGAL_precondition(0 <= t && t < 4); + // CGAL_precondition(0 <= t && t < 4); Traits::pointer(*ptr) = (void *) ((clean_pointer((char *) p)) + (int) t); } @@ -567,13 +785,14 @@ void init() { - block_size = CGAL_INIT_COMPACT_CONTAINER_BLOCK_SIZE; + block_size = Increment_policy::first_block_size; capacity_ = 0; size_ = 0; free_list = NULL; first_item = NULL; last_item = NULL; all_items = All_items(); + time_stamper->reset(); } allocator_type alloc; @@ -584,10 +803,14 @@ pointer first_item; pointer last_item; All_items all_items; + + // This is a pointer, so that the definition of Compact_container does + // not require a complete type `T`. + Time_stamper_impl* time_stamper; }; -template < class T, class Allocator > -void Compact_container::merge(Self &d) +template < class T, class Allocator, class Increment_policy, class TimeStamper > +void Compact_container::merge(Self &d) { CGAL_precondition(&d != this); @@ -623,8 +846,8 @@ d.init(); } -template < class T, class Allocator > -void Compact_container::clear() +template < class T, class Allocator, class Increment_policy, class TimeStamper > +void Compact_container::clear() { for (typename All_items::iterator it = all_items.begin(), itend = all_items.end(); it != itend; ++it) { @@ -639,9 +862,12 @@ init(); } -template < class T, class Allocator > -void Compact_container::allocate_new_block() +template < class T, class Allocator, class Increment_policy, class TimeStamper > +void Compact_container::allocate_new_block() { + typedef internal::Erase_counter_strategy< + internal::has_increment_erase_counter::value> EraseCounterStrategy; + pointer new_block = alloc.allocate(block_size + 2); all_items.push_back(std::make_pair(new_block, block_size + 2)); capacity_ += block_size; @@ -649,7 +875,10 @@ // We mark them free in reverse order, so that the insertion order // will correspond to the iterator order... for (size_type i = block_size; i >= 1; --i) + { + EraseCounterStrategy::set_erase_counter(*(new_block + i), 0); put_on_free_list(new_block + i); + } // We insert this new block at the end. if (last_item == NULL) // First time { @@ -665,55 +894,55 @@ } set_type(last_item, NULL, START_END); // Increase the block_size for the next time. - block_size += CGAL_INCREMENT_COMPACT_CONTAINER_BLOCK_SIZE; + Increment_policy::increase_size(*this); } -template < class T, class Allocator > +template < class T, class Allocator, class Increment_policy, class TimeStamper > inline -bool operator==(const Compact_container &lhs, - const Compact_container &rhs) +bool operator==(const Compact_container &lhs, + const Compact_container &rhs) { return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin()); } -template < class T, class Allocator > +template < class T, class Allocator, class Increment_policy, class TimeStamper > inline -bool operator!=(const Compact_container &lhs, - const Compact_container &rhs) +bool operator!=(const Compact_container &lhs, + const Compact_container &rhs) { return ! (lhs == rhs); } -template < class T, class Allocator > +template < class T, class Allocator, class Increment_policy, class TimeStamper > inline -bool operator< (const Compact_container &lhs, - const Compact_container &rhs) +bool operator< (const Compact_container &lhs, + const Compact_container &rhs) { return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end()); } -template < class T, class Allocator > +template < class T, class Allocator, class Increment_policy, class TimeStamper > inline -bool operator> (const Compact_container &lhs, - const Compact_container &rhs) +bool operator> (const Compact_container &lhs, + const Compact_container &rhs) { return rhs < lhs; } -template < class T, class Allocator > +template < class T, class Allocator, class Increment_policy, class TimeStamper > inline -bool operator<=(const Compact_container &lhs, - const Compact_container &rhs) +bool operator<=(const Compact_container &lhs, + const Compact_container &rhs) { return ! (lhs > rhs); } -template < class T, class Allocator > +template < class T, class Allocator, class Increment_policy, class TimeStamper > inline -bool operator>=(const Compact_container &lhs, - const Compact_container &rhs) +bool operator>=(const Compact_container &lhs, + const Compact_container &rhs) { return ! (lhs < rhs); } @@ -764,13 +993,19 @@ private: + typedef typename DSC::Time_stamper_impl Time_stamper_impl; + union { pointer p; void *vp; } m_ptr; // Only Compact_container should access these constructors. - friend class Compact_container; + friend class Compact_container; + // For begin() CC_iterator(pointer ptr, int, int) @@ -795,9 +1030,9 @@ { // It's either pointing to end(), or valid. CGAL_assertion_msg(m_ptr.p != NULL, - "Incrementing a singular iterator or an empty container iterator ?"); + "Incrementing a singular iterator or an empty container iterator ?"); CGAL_assertion_msg(DSC::type(m_ptr.p) != DSC::START_END, - "Incrementing end() ?"); + "Incrementing end() ?"); // If it's not end(), then it's valid, we can do ++. do { @@ -815,9 +1050,9 @@ { // It's either pointing to end(), or valid. CGAL_assertion_msg(m_ptr.p != NULL, - "Decrementing a singular iterator or an empty container iterator ?"); + "Decrementing a singular iterator or an empty container iterator ?"); CGAL_assertion_msg(DSC::type(m_ptr.p - 1) != DSC::START_END, - "Decrementing begin() ?"); + "Decrementing begin() ?"); // If it's not begin(), then it's valid, we can do --. do { @@ -836,7 +1071,7 @@ Self & operator++() { CGAL_assertion_msg(m_ptr.p != NULL, - "Incrementing a singular iterator or an empty container iterator ?"); + "Incrementing a singular iterator or an empty container iterator ?"); CGAL_assertion_msg(DSC::type(m_ptr.p) == DSC::USED, "Incrementing an invalid iterator."); increment(); @@ -846,9 +1081,9 @@ Self & operator--() { CGAL_assertion_msg(m_ptr.p != NULL, - "Decrementing a singular iterator or an empty container iterator ?"); + "Decrementing a singular iterator or an empty container iterator ?"); CGAL_assertion_msg(DSC::type(m_ptr.p) == DSC::USED - || DSC::type(m_ptr.p) == DSC::START_END, + || DSC::type(m_ptr.p) == DSC::START_END, "Decrementing an invalid iterator."); decrement(); return *this; @@ -864,22 +1099,24 @@ // For std::less... bool operator<(const CC_iterator& other) const { - return (m_ptr.p < other.m_ptr.p); + return Time_stamper_impl::less(m_ptr.p, other.m_ptr.p); } bool operator>(const CC_iterator& other) const { - return (m_ptr.p > other.m_ptr.p); + return Time_stamper_impl::less(other.m_ptr.p, m_ptr.p); } bool operator<=(const CC_iterator& other) const { - return (m_ptr.p <= other.m_ptr.p); + return Time_stamper_impl::less(m_ptr.p, other.m_ptr.p) + || (*this == other); } bool operator>=(const CC_iterator& other) const { - return (m_ptr.p >= other.m_ptr.p); + return Time_stamper_impl::less(other.m_ptr.p, m_ptr.p) + || (*this == other); } // Can itself be used for bit-squatting. @@ -916,7 +1153,7 @@ template < class DSC, bool Const > inline bool operator!=(const CC_iterator &rhs, - Nullptr_t CGAL_assertion_code(n)) + Nullptr_t CGAL_assertion_code(n)) { CGAL_assertion( n == NULL); return &*rhs != NULL; diff -Nru cgal-4.4/include/CGAL/Compact_mesh_cell_base_3.h cgal-4.5/include/CGAL/Compact_mesh_cell_base_3.h --- cgal-4.4/include/CGAL/Compact_mesh_cell_base_3.h 2013-12-21 20:00:22.000000000 +0000 +++ cgal-4.5/include/CGAL/Compact_mesh_cell_base_3.h 2014-08-29 13:58:16.000000000 +0000 @@ -26,24 +26,191 @@ #include #include +#include #include #include +#include +#include #include #include +#ifdef CGAL_LINKED_WITH_TBB +# include +#endif + namespace CGAL { - + +// Class Compact_mesh_cell_base_3_base +// Base for Compact_mesh_cell_base_3, with specializations +// for different values of Concurrency_tag +// Sequential +template +class Compact_mesh_cell_base_3_base +{ + typedef typename GT::Point_3 Point; + +protected: + Compact_mesh_cell_base_3_base() + : bits_(0) + , circumcenter_(NULL) + {} + +public: +#if defined(CGAL_MESH_3_USE_LAZY_SORTED_REFINEMENT_QUEUE) \ + || defined(CGAL_MESH_3_USE_LAZY_UNSORTED_REFINEMENT_QUEUE) + + // Erase counter (cf. Compact_container) + unsigned int erase_counter() const + { + return this->m_erase_counter; + } + void set_erase_counter(unsigned int c) + { + this->m_erase_counter = c; + } + void increment_erase_counter() + { + ++this->m_erase_counter; + } +#endif + + /// Marks \c facet as visited + void set_facet_visited (const int facet) + { + CGAL_precondition(facet>=0 && facet <4); + bits_ |= (1 << facet); + } + + /// Marks \c facet as not visited + void reset_visited (const int facet) + { + CGAL_precondition(facet>=0 && facet<4); + bits_ &= (15 & ~(1 << facet)); + } + + /// Returns \c true if \c facet is marked as visited + bool is_facet_visited (const int facet) const + { + CGAL_precondition(facet>=0 && facet<4); + return ( (bits_ & (1 << facet)) != 0 ); + } + + /// Precondition circumcenter_ == NULL + void try_to_set_circumcenter(Point *cc) const + { + CGAL_precondition(circumcenter_ == NULL); + circumcenter_ = cc; + } + +private: + char bits_; + +#if defined(CGAL_MESH_3_USE_LAZY_SORTED_REFINEMENT_QUEUE) \ + || defined(CGAL_MESH_3_USE_LAZY_UNSORTED_REFINEMENT_QUEUE) + + typedef unsigned int Erase_counter_type; + Erase_counter_type m_erase_counter; +#endif + +protected: + mutable Point * circumcenter_; +}; + + +#ifdef CGAL_LINKED_WITH_TBB +// Class Compact_mesh_cell_base_3_base +// Specialization for parallel +template +class Compact_mesh_cell_base_3_base +{ + typedef typename GT::Point_3 Point; + +protected: + Compact_mesh_cell_base_3_base() + { + bits_ = 0; + circumcenter_ = NULL; + } + +public: + // Erase counter (cf. Compact_container) + unsigned int erase_counter() const + { + return this->m_erase_counter; + } + void set_erase_counter(unsigned int c) + { + this->m_erase_counter = c; + } + void increment_erase_counter() + { + ++this->m_erase_counter; + } + + /// Marks \c facet as visited + void set_facet_visited (const int facet) + { + CGAL_precondition(facet>=0 && facet<4); + char current_bits = bits_; + while (bits_.compare_and_swap(current_bits | (1 << facet), current_bits) != current_bits) + { + current_bits = bits_; + } + } + + /// Marks \c facet as not visited + void reset_visited (const int facet) + { + CGAL_precondition(facet>=0 && facet<4); + char current_bits = bits_; + while (bits_.compare_and_swap(current_bits & (15 & ~(1 << facet)), current_bits) != current_bits) + { + current_bits = bits_; + } + } + + /// Returns \c true if \c facet is marked as visited + bool is_facet_visited (const int facet) const + { + CGAL_precondition(facet>=0 && facet<4); + return ( (bits_ & (1 << facet)) != 0 ); + } + + /// If the circumcenter is already set (circumcenter_ != NULL), + /// this function "deletes" cc + void try_to_set_circumcenter(Point *cc) const + { + if (circumcenter_.compare_and_swap(cc, NULL) != NULL) + delete cc; + } + +private: + typedef tbb::atomic Erase_counter_type; + Erase_counter_type m_erase_counter; + /// Stores visited facets (4 first bits) + tbb::atomic bits_; + +protected: + mutable tbb::atomic circumcenter_; +}; + +#endif // CGAL_LINKED_WITH_TBB + + // Class Compact_mesh_cell_base_3 // Cell base class used in 3D meshing process. // Adds information to Cb about the cell of the input complex containing it template< class GT, class MD, - class TDS = void > + class TDS = void > class Compact_mesh_cell_base_3 + : public Compact_mesh_cell_base_3_base { typedef typename GT::FT FT; - + typedef Compact_mesh_cell_base_3_base Base; + using Base::circumcenter_; + public: typedef TDS Triangulation_data_structure; typedef typename TDS::Vertex_handle Vertex_handle; @@ -63,10 +230,10 @@ typedef typename MD::Subdomain_index Subdomain_index; typedef typename MD::Surface_patch_index Surface_patch_index; typedef typename MD::Index Index; - + typedef GT Geom_traits; typedef typename GT::Point_3 Point; - + typedef Point* Point_container; typedef Point* Point_iterator; typedef const Point* Point_const_iterator; @@ -79,33 +246,33 @@ circumcenter_ = NULL; } } + public: // Constructors Compact_mesh_cell_base_3() : surface_index_table_() , surface_center_table_() - , circumcenter_(NULL) #ifdef CGAL_INTRUSIVE_LIST , next_intrusive_() , previous_intrusive_() #endif + , time_stamp_(-1) , surface_center_index_table_() , sliver_value_(FT(0.)) - , subdomain_index_() - , bits_(0) + , subdomain_index_() , sliver_cache_validity_(false) - { - } + {} - Compact_mesh_cell_base_3(const Compact_mesh_cell_base_3& rhs) - : circumcenter_(NULL) + Compact_mesh_cell_base_3(const Compact_mesh_cell_base_3& rhs) + : N(rhs.N) + , V(rhs.V) #ifdef CGAL_INTRUSIVE_LIST , next_intrusive_(rhs.next_intrusive_) , previous_intrusive_(rhs.previous_intrusive_) #endif + , time_stamp_(rhs.time_stamp_) , sliver_value_(rhs.sliver_value_) , subdomain_index_(rhs.subdomain_index_) - , bits_(0) , sliver_cache_validity_(false) { for(int i=0; i <4; i++){ @@ -114,25 +281,24 @@ surface_center_index_table_[i] = rhs.surface_center_index_table_[i]; } } - + Compact_mesh_cell_base_3 (Vertex_handle v0, Vertex_handle v1, Vertex_handle v2, Vertex_handle v3) : surface_index_table_() , surface_center_table_() - , circumcenter_(NULL) + , V(CGAL::make_array(v0, v1, v2, v3)) #ifdef CGAL_INTRUSIVE_LIST , next_intrusive_() , previous_intrusive_() #endif + , time_stamp_(-1) , surface_center_index_table_() , sliver_value_(FT(0.)) - , subdomain_index_() - , bits_(0) + , subdomain_index_() , sliver_cache_validity_(false) { - set_vertices(v0, v1, v2, v3); } @@ -146,19 +312,18 @@ Cell_handle n3) : surface_index_table_() , surface_center_table_() - , circumcenter_(NULL) + , N(CGAL::make_array(n0, n1, n2, n3)) + , V(CGAL::make_array(v0, v1, v2, v3)) #ifdef CGAL_INTRUSIVE_LIST , next_intrusive_() , previous_intrusive_() #endif + , time_stamp_(-1) , surface_center_index_table_() , sliver_value_(FT(0.)) , subdomain_index_() - , bits_(0) , sliver_cache_validity_(false) { - set_neighbors(n0, n1, n2, n3); - set_vertices(v0, v1, v2, v3); } ~Compact_mesh_cell_base_3() @@ -306,28 +471,21 @@ } const Point & - circumcenter(const Geom_traits& gt = Geom_traits()) const + weighted_circumcenter(const Geom_traits& gt = Geom_traits()) const { if (circumcenter_ == NULL) { -#ifndef CGAL_REGULAR_TRIANGULATION_3_USE_CIRCUMCENTER_CACHE - circumcenter_ = new Point(gt.construct_circumcenter_3_object() - (this->vertex(0)->point(), - this->vertex(1)->point(), - this->vertex(2)->point(), - this->vertex(3)->point())); -#else // CGAL_REGULAR_TRIANGULATION_3_USE_CIRCUMCENTER_CACHE - circumcenter_ = new Point(gt.construct_weighted_circumcenter_3_object() - (this->vertex(0)->point(), - this->vertex(1)->point(), - this->vertex(2)->point(), - this->vertex(3)->point())); -#endif // CGAL_REGULAR_TRIANGULATION_3_USE_CIRCUMCENTER_CACHE + this->try_to_set_circumcenter( + new Point(gt.construct_weighted_circumcenter_3_object() + (this->vertex(0)->point(), + this->vertex(1)->point(), + this->vertex(2)->point(), + this->vertex(3)->point()))); } else { - CGAL_expensive_assertion(gt.construct_circumcenter_3_object() + CGAL_expensive_assertion(gt.construct_weighted_circumcenter_3_object() (this->vertex(0)->point(), this->vertex(1)->point(), this->vertex(2)->point(), - this->vertex(3)->point()) == *circumcenter); + this->vertex(3)->point()) == *circumcenter_); } return *circumcenter_; } @@ -335,11 +493,11 @@ // Returns the index of the cell of the input complex that contains the cell Subdomain_index subdomain_index() const { return subdomain_index_; } - + // Sets the index of the cell of the input complex that contains the cell void set_subdomain_index(const Subdomain_index& index) - { subdomain_index_ = index; } - + { subdomain_index_ = index; } + void set_sliver_value(const FT& value) { sliver_cache_validity_ = true; @@ -369,27 +527,6 @@ return surface_index_table_[facet]; } - /// Marks \c facet as visited - void set_facet_visited (const int facet) - { - CGAL_precondition(facet>=0 && facet <4); - bits_ |= (1 << facet); - } - - /// Marks \c facet as not visited - void reset_visited (const int facet) - { - CGAL_precondition(facet>=0 && facet<4); - bits_ &= (15 & ~(1 << facet)); - } - - /// Returns \c true if \c facet is marked as visited - bool is_facet_visited (const int facet) const - { - CGAL_precondition(facet>=0 && facet<4); - return ( (bits_ & (1 << facet)) != 0 ); - } - /// Sets surface center of \c facet to \c point void set_facet_surface_center(const int facet, const Point& point) { @@ -424,16 +561,16 @@ CGAL_precondition(facet>=0 && facet<4); return ( Surface_patch_index() != surface_index_table_[facet]); } - + // ----------------------------------- // Backward Compatibility // ----------------------------------- #ifndef CGAL_MESH_3_NO_DEPRECATED_SURFACE_INDEX typedef Surface_patch_index Surface_index; - + void set_surface_index(const int facet, const Surface_index& index) { set_surface_patch_index(facet,index); } - + /// Returns surface index of facet \c facet Surface_index surface_index(const int facet) const { return surface_patch_index(facet); } @@ -445,7 +582,7 @@ static std::string io_signature() { - return + return Get_io_signature()() + "+" + Get_io_signature >()() + "+(" + Get_io_signature()() + ")[4]"; @@ -458,7 +595,7 @@ { next_intrusive_ = c; } - + Cell_handle previous_intrusive() const { return previous_intrusive_; } void set_previous_intrusive(Cell_handle c) { @@ -466,6 +603,17 @@ } #endif // CGAL_INTRUSIVE_LIST + /// For the determinism of Compact_container iterators + ///@{ + typedef Tag_true Has_timestamp; + + std::size_t time_stamp() const { + return time_stamp_; + } + void set_time_stamp(const std::size_t& ts) { + time_stamp_ = ts; + } + ///@} private: @@ -479,11 +627,10 @@ CGAL::cpp11::array N; CGAL::cpp11::array V; - mutable Point * circumcenter_; - #ifdef CGAL_INTRUSIVE_LIST Cell_handle next_intrusive_, previous_intrusive_; #endif + std::size_t time_stamp_; CGAL::cpp11::array surface_center_index_table_; /// Stores visited facets (4 first bits) @@ -496,14 +643,11 @@ Subdomain_index subdomain_index_; TDS_data _tds_data; - char bits_; mutable bool sliver_cache_validity_; }; // end class Compact_mesh_cell_base_3 - - template < class GT, class MT, class Cb > std::istream& operator>>(std::istream &is, diff -Nru cgal-4.4/include/CGAL/Concurrent_compact_container.h cgal-4.5/include/CGAL/Concurrent_compact_container.h --- cgal-4.4/include/CGAL/Concurrent_compact_container.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/Concurrent_compact_container.h 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,1026 @@ +// Copyright (c) 2012 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL: $ +// $Id: $ +// +// Author(s) : Clement Jamin + +#ifdef CGAL_LINKED_WITH_TBB + +#ifndef CGAL_CONCURRENT_COMPACT_CONTAINER_H +#define CGAL_CONCURRENT_COMPACT_CONTAINER_H + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include + +namespace CGAL { + +#define CGAL_GENERATE_MEMBER_DETECTOR(X) \ +template class has_##X { \ + struct Fallback { int X; }; \ + struct Derived : T, Fallback { }; \ + \ + template struct Check; \ + \ + typedef char ArrayOfOne[1]; \ + typedef char ArrayOfTwo[2]; \ + \ + template static ArrayOfOne & func( \ + Check *); \ + template static ArrayOfTwo & func(...); \ + public: \ + typedef has_##X type; \ + enum { value = sizeof(func(0)) == 2 }; \ +} // semicolon is after the macro call + +#define CGAL_INIT_CONCURRENT_COMPACT_CONTAINER_BLOCK_SIZE 14 +#define CGAL_INCREMENT_CONCURRENT_COMPACT_CONTAINER_BLOCK_SIZE 16 + +// The traits class describes the way to access the pointer. +// It can be specialized. +template < class T > +struct Concurrent_compact_container_traits { + static void * pointer(const T &t) { return t.for_compact_container(); } + static void * & pointer(T &t) { return t.for_compact_container(); } +}; + +namespace CCC_internal { + template < class CCC, bool Const > + class CCC_iterator; + + CGAL_GENERATE_MEMBER_DETECTOR(increment_erase_counter); + + // A basic "no erase counter" strategy + template + class Erase_counter_strategy { + public: + // Do nothing + template + static unsigned int erase_counter(const Element &) { return 0; } + template + static void set_erase_counter(Element &, unsigned int) {} + template + static void increment_erase_counter(Element &) {} + }; + + + // A strategy managing an internal counter + template <> + class Erase_counter_strategy + { + public: + template + static unsigned int erase_counter(const Element &e) + { + return e.erase_counter(); + } + + template + static void set_erase_counter(Element &e, unsigned int c) + { + e.set_erase_counter(c); + } + + template + static void increment_erase_counter(Element &e) + { + e.increment_erase_counter(); + } + }; +} + +// Free list (head and size) +template< typename pointer, typename size_type, typename CCC > +class Free_list { +public: + Free_list() : m_head(NULL), m_size(0) {} + + void init() { m_head = NULL; m_size = 0; } + pointer head() const { return m_head; } + void set_head(pointer p) { m_head = p; } + size_type size() const { return m_size; } + void set_size(size_type s) { m_size = s; } + void inc_size() { ++m_size; } + void dec_size() { --m_size; } + bool empty() { return size() == 0; } + // Warning: copy the pointer, not the data! + Free_list& operator= (const Free_list& other) + { + m_head = other.m_head; + m_size = other.m_size; + return *this; + } + + void merge(Free_list &other) + { + if (m_head == NULL) { + *this = other; + } + else if (!other.empty()) + { + pointer p = m_head; + while (CCC::clean_pointee(p) != NULL) + p = CCC::clean_pointee(p); + CCC::set_type(p, other.m_head, CCC::FREE); + m_size += other.m_size; + } + other.init(); // clear other + } + +protected: + pointer m_head; // the free list head pointer + size_type m_size; // the free list size +}; + +// Class Concurrent_compact_container +// +// Safe concurrent "insert" and "erase". +// Do not parse the container while others are modifying it. +// +template < class T, class Allocator_ = Default > +class Concurrent_compact_container +{ + typedef Allocator_ Al; + typedef typename Default::Get::type Allocator; + typedef Concurrent_compact_container Self; + typedef Concurrent_compact_container_traits Traits; + +public: + typedef T value_type; + typedef Allocator allocator_type; + typedef typename Allocator::reference reference; + typedef typename Allocator::const_reference const_reference; + typedef typename Allocator::pointer pointer; + typedef typename Allocator::const_pointer const_pointer; + typedef typename Allocator::size_type size_type; + typedef typename Allocator::difference_type difference_type; + typedef CCC_internal::CCC_iterator iterator; + typedef CCC_internal::CCC_iterator const_iterator; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + +private: + typedef Free_list FreeList; + typedef tbb::enumerable_thread_specific Free_lists; + + // FreeList can access our private function (clean_pointee...) + friend class Free_list; + +public: + friend class CCC_internal::CCC_iterator; + friend class CCC_internal::CCC_iterator; + + explicit Concurrent_compact_container(const Allocator &a = Allocator()) + : m_alloc(a) + { + init (); + } + + template < class InputIterator > + Concurrent_compact_container(InputIterator first, InputIterator last, + const Allocator & a = Allocator()) + : m_alloc(a) + { + init(); + std::copy(first, last, CGAL::inserter(*this)); + } + + // The copy constructor and assignment operator preserve the iterator order + Concurrent_compact_container(const Concurrent_compact_container &c) + : m_alloc(c.get_allocator()) + { + init(); + m_block_size = c.m_block_size; + std::copy(c.begin(), c.end(), CGAL::inserter(*this)); + } + + Concurrent_compact_container & operator=(const Concurrent_compact_container &c) + { + if (&c != this) { + Self tmp(c); + swap(tmp); + } + return *this; + } + + ~Concurrent_compact_container() + { + clear(); + } + + void swap(Self &c) + { + std::swap(m_alloc, c.m_alloc); + std::swap(m_capacity, c.m_capacity); + std::swap(m_block_size, c.m_block_size); + std::swap(m_first_item, c.m_first_item); + std::swap(m_last_item, c.m_last_item); + std::swap(m_free_lists, c.m_free_lists); + m_all_items.swap(c.m_all_items); + } + + iterator begin() { return iterator(m_first_item, 0, 0); } + iterator end() { return iterator(m_last_item, 0); } + + const_iterator begin() const { return const_iterator(m_first_item, 0, 0); } + const_iterator end() const { return const_iterator(m_last_item, 0); } + + reverse_iterator rbegin() { return reverse_iterator(end()); } + reverse_iterator rend() { return reverse_iterator(begin()); } + + const_reverse_iterator + rbegin() const { return const_reverse_iterator(end()); } + const_reverse_iterator + rend() const { return const_reverse_iterator(begin()); } + + // Boost.Intrusive interface + iterator iterator_to(reference value) const { + return iterator(&value, 0); + } + const_iterator iterator_to(const_reference value) const { + return const_iterator(&value, 0); + } + static iterator s_iterator_to(reference value) { + return iterator(&value, 0); + } + static const_iterator s_iterator_to(const_reference value) { + return const_iterator(&value, 0); + } + + // Special insert methods that construct the objects in place + // (just forward the arguments to the constructor, to optimize a copy). +#ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES + template < typename... Args > + iterator + emplace(const Args&... args) + { + FreeList * fl = get_free_list(); + pointer ret = init_insert(fl); + new (ret) value_type(args...); + return finalize_insert(ret, fl); + } +#else + // inserts a default constructed item. + iterator emplace() + { + FreeList * fl = get_free_list(); + pointer ret = init_insert(fl); + new (ret) value_type(); + return finalize_insert(ret, fl); + } + + template < typename T1 > + iterator + emplace(const T1 &t1) + { + FreeList * fl = get_free_list(); + pointer ret = init_insert(fl); + new (ret) value_type(t1); + return finalize_insert(ret, fl); + } + + template < typename T1, typename T2 > + iterator + emplace(const T1 &t1, const T2 &t2) + { + FreeList * fl = get_free_list(); + pointer ret = init_insert(fl); + new (ret) value_type(t1, t2); + return finalize_insert(ret, fl); + } + + template < typename T1, typename T2, typename T3 > + iterator + emplace(const T1 &t1, const T2 &t2, const T3 &t3) + { + FreeList * fl = get_free_list(); + pointer ret = init_insert(fl); + new (ret) value_type(t1, t2, t3); + return finalize_insert(ret, fl); + } + + template < typename T1, typename T2, typename T3, typename T4 > + iterator + emplace(const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4) + { + FreeList * fl = get_free_list(); + pointer ret = init_insert(fl); + new (ret) value_type(t1, t2, t3, t4); + return finalize_insert(ret, fl); + } + + template < typename T1, typename T2, typename T3, typename T4, typename T5 > + iterator + emplace(const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4, + const T5 &t5) + { + FreeList * fl = get_free_list(); + pointer ret = init_insert(fl); + new (ret) value_type(t1, t2, t3, t4, t5); + return finalize_insert(ret, fl); + } + + template < typename T1, typename T2, typename T3, typename T4, + typename T5, typename T6 > + iterator + emplace(const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4, + const T5 &t5, const T6 &t6) + { + FreeList * fl = get_free_list(); + pointer ret = init_insert(fl); + new (ret) value_type(t1, t2, t3, t4, t5, t6); + return finalize_insert(ret, fl); + } + + template < typename T1, typename T2, typename T3, typename T4, + typename T5, typename T6, typename T7 > + iterator + emplace(const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4, + const T5 &t5, const T6 &t6, const T7 &t7) + { + FreeList * fl = get_free_list(); + pointer ret = init_insert(fl); + new (ret) value_type(t1, t2, t3, t4, t5, t6, t7); + return finalize_insert(ret, fl); + } + + template < typename T1, typename T2, typename T3, typename T4, + typename T5, typename T6, typename T7, typename T8 > + iterator + emplace(const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4, + const T5 &t5, const T6 &t6, const T7 &t7, const T8 &t8) + { + FreeList * fl = get_free_list(); + pointer ret = init_insert(fl); + new (ret) value_type(t1, t2, t3, t4, t5, t6, t7, t8); + return finalize_insert(ret, fl); + } +#endif // CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES + + iterator insert(const T &t) + { + FreeList * fl = get_free_list(); + pointer ret = init_insert(fl); + m_alloc.construct(ret, t); + return finalize_insert(ret, fl); + } + + template < class InputIterator > + void insert(InputIterator first, InputIterator last) + { + for (; first != last; ++first) + insert(*first); + } + + template < class InputIterator > + void assign(InputIterator first, InputIterator last) + { + clear(); // erase(begin(), end()); // ? + insert(first, last); + } + +private: + void erase(iterator x, FreeList * fl) + { + typedef CCC_internal::Erase_counter_strategy< + CCC_internal::has_increment_erase_counter::value> EraseCounterStrategy; + + CGAL_precondition(type(x) == USED); + EraseCounterStrategy::increment_erase_counter(*x); + m_alloc.destroy(&*x); +/* WE DON'T DO THAT BECAUSE OF THE ERASE COUNTER +#ifndef CGAL_NO_ASSERTIONS + std::memset(&*x, 0, sizeof(T)); +#endif*/ + put_on_free_list(&*x, fl); + } +public: + + void erase(iterator x) + { + erase(x, get_free_list()); + } + + void erase(iterator first, iterator last) { + while (first != last) + erase(first++); + } + + void clear(); + + // Merge the content of d into *this. d gets cleared. + // The complexity is O(size(free list = capacity-size)). + void merge(Self &d); + + // Do not call this function while others are inserting/erasing elements + size_type size() const + { + size_type size = m_capacity; + for( typename Free_lists::iterator it_free_list = m_free_lists.begin() ; + it_free_list != m_free_lists.end() ; + ++it_free_list ) + { + size -= it_free_list->size(); + } + return size; + } + + size_type max_size() const + { + return m_alloc.max_size(); + } + + size_type capacity() const + { + return m_capacity; + } + + // void resize(size_type sz, T c = T()); // TODO makes sense ??? + + bool empty() const + { + return size() == 0; + } + + allocator_type get_allocator() const + { + return m_alloc; + } + + // Returns whether the iterator "cit" is in the range [begin(), end()]. + // Complexity : O(#blocks) = O(sqrt(capacity())). + // This function is mostly useful for purposes of efficient debugging at + // higher levels. + bool owns(const_iterator cit) const + { + // We use the block structure to provide an efficient version : + // we check if the address is in the range of each block, + // and then test whether it is valid (not a free element). + + if (cit == end()) + return true; + + const_pointer c = &*cit; + + Mutex::scoped_lock lock(m_mutex); + + for (typename All_items::const_iterator it = m_all_items.begin(), itend = m_all_items.end(); + it != itend; ++it) { + const_pointer p = it->first; + size_type s = it->second; + + // Are we in the address range of this block (excluding first and last + // elements) ? + if (c <= p || (p+s-1) <= c) + continue; + + CGAL_assertion_msg( (c-p)+p == c, "wrong alignment of iterator"); + + return type(c) == USED; + } + return false; + } + + bool owns_dereferencable(const_iterator cit) const + { + return cit != end() && owns(cit); + } + + /** Reserve method to ensure that the capacity of the Concurrent_compact_container be + * greater or equal than a given value n. + */ + // TODO? + //void reserve(size_type n) + //{ + // Does it really make sense: it will reserve size for the current + // thread only! + /*Mutex::scoped_lock lock; + if ( m_capacity >= n ) return; + size_type tmp = m_block_size; + // TODO: use a tmpBlockSize instead of m_block_size + m_block_size = (std::max)( n - m_capacity, m_block_size ); + allocate_new_block(free_list()); + m_block_size = tmp + CGAL_INCREMENT_CONCURRENT_COMPACT_CONTAINER_BLOCK_SIZE;*/ + //} + +private: + + FreeList* get_free_list() { return & m_free_lists.local(); } + const FreeList* get_free_list() const { return & m_free_lists.local(); } + + // Two helper functions for the emplace() methods + + // allocate new space if needed get the pointer from + // the free list and then clean it + pointer init_insert(FreeList * fl) + { + pointer fl2 = fl->head(); + if (fl2 == NULL) { + allocate_new_block(fl); + fl2 = fl->head(); + } + pointer ret = fl2; + fl->set_head(clean_pointee(ret)); + return ret; + } + + // get verify the return pointer increment size and + // return as iterator + iterator finalize_insert(pointer ret, FreeList * fl) + { + CGAL_assertion(type(ret) == USED); + fl->dec_size(); + return iterator(ret, 0); + } + + void allocate_new_block(FreeList *fl); + + void put_on_free_list(pointer x, FreeList * fl) + { + set_type(x, fl->head(), FREE); + fl->set_head(x); + fl->inc_size(); + } + + // Definition of the bit squatting : + // ================================= + // ptr is composed of a pointer part and the last 2 bits. + // Here is the meaning of each of the 8 cases. + // + // value of the last 2 bits as "Type" + // pointer part 0 1 2 3 + // NULL user elt unused free_list end start/end + // != NULL user elt block boundary free elt unused + // + // meaning of ptr : user stuff next/prev block free_list unused + + enum Type { USED = 0, BLOCK_BOUNDARY = 1, FREE = 2, START_END = 3 }; + + // The bit squatting is implemented by casting pointers to (char *), then + // subtracting to NULL, doing bit manipulations on the resulting integer, + // and converting back. + + static char * clean_pointer(char * p) + { + return ((p - (char *) NULL) & ~ (std::ptrdiff_t) START_END) + (char *) NULL; + } + + // Returns the pointee, cleaned up from the squatted bits. + static pointer clean_pointee(const_pointer ptr) + { + return (pointer) clean_pointer((char *) Traits::pointer(*ptr)); + } + + // Get the type of the pointee. + static Type type(const_pointer ptr) + { + char * p = (char *) Traits::pointer(*ptr); + return (Type) (p - clean_pointer(p)); + } + + static Type type(const_iterator ptr) + { + return type(&*ptr); + } + + // Sets the pointer part and the type of the pointee. + static void set_type(pointer p_element, void * pointer, Type t) + { + CGAL_precondition(0 <= t && t < 4); + Traits::pointer(*p_element) = + (void *) ((clean_pointer((char *) pointer)) + (int) t); + } + + typedef tbb::queuing_mutex Mutex; + + // We store a vector of pointers to all allocated blocks and their sizes. + // Knowing all pointers, we don't have to walk to the end of a block to reach + // the pointer to the next block. + // Knowing the sizes allows to deallocate() without having to compute the size + // by walking through the block till its end. + // This opens up the possibility for the compiler to optimize the clear() + // function considerably when has_trivial_destructor. + typedef std::vector > All_items; + + + void init() + { + m_block_size = CGAL_INIT_CONCURRENT_COMPACT_CONTAINER_BLOCK_SIZE; + m_capacity = 0; + for( typename Free_lists::iterator it_free_list = m_free_lists.begin() ; + it_free_list != m_free_lists.end() ; + ++it_free_list ) + { + it_free_list->set_head(0); + it_free_list->set_size(0); + } + m_first_item = NULL; + m_last_item = NULL; + m_all_items = All_items(); + } + + allocator_type m_alloc; + size_type m_capacity; + size_type m_block_size; + Free_lists m_free_lists; + pointer m_first_item; + pointer m_last_item; + All_items m_all_items; + mutable Mutex m_mutex; +}; + +template < class T, class Allocator > +void Concurrent_compact_container::merge(Self &d) +{ + CGAL_precondition(&d != this); + + // Allocators must be "compatible" : + CGAL_precondition(get_allocator() == d.get_allocator()); + + // Concatenate the free_lists. + // Iterates over TLS free lists of "d". Note that the number of TLS freelists + // may be different. + typename Free_lists::iterator it_free_list = m_free_lists.begin(); + if (it_free_list == m_free_lists.end()) + { + // No free list at all? Create our local one... empty. + get_free_list()->set_head(0); + get_free_list()->set_size(0); + // Now there is one TLS free list: ours! + it_free_list = m_free_lists.begin(); + } + for( typename Free_lists::iterator it_free_list_d = d.m_free_lists.begin() ; + it_free_list_d != d.m_free_lists.end() ; + ++it_free_list_d, ++it_free_list ) + { + // If we run out of TLS free lists in *this, let's start again from "begin" + if (it_free_list == m_free_lists.end()) + it_free_list = m_free_lists.begin(); + + it_free_list->merge(*it_free_list_d); + } + // Concatenate the blocks. + if (m_last_item == NULL) { // empty... + m_first_item = d.m_first_item; + m_last_item = d.m_last_item; + } else if (d.m_last_item != NULL) { + set_type(m_last_item, d.m_first_item, BLOCK_BOUNDARY); + set_type(d.m_first_item, m_last_item, BLOCK_BOUNDARY); + m_last_item = d.m_last_item; + } + m_all_items.insert(m_all_items.end(), d.m_all_items.begin(), d.m_all_items.end()); + // Add the capacities. + m_capacity += d.m_capacity; + // It seems reasonnable to take the max of the block sizes. + m_block_size = (std::max)(m_block_size, d.m_block_size); + // Clear d. + d.init(); +} + +template < class T, class Allocator > +void Concurrent_compact_container::clear() +{ + for (typename All_items::iterator it = m_all_items.begin(), itend = m_all_items.end(); + it != itend; ++it) { + pointer p = it->first; + size_type s = it->second; + for (pointer pp = p + 1; pp != p + s - 1; ++pp) { + if (type(pp) == USED) + m_alloc.destroy(pp); + } + m_alloc.deallocate(p, s); + } + init(); +} + +template < class T, class Allocator > +void Concurrent_compact_container:: + allocate_new_block(FreeList * fl) +{ + typedef CCC_internal::Erase_counter_strategy< + CCC_internal::has_increment_erase_counter::value> EraseCounterStrategy; + + size_type old_block_size; + pointer new_block; + + { + Mutex::scoped_lock lock(m_mutex); + old_block_size = m_block_size; + new_block = m_alloc.allocate(old_block_size + 2); + m_all_items.push_back(std::make_pair(new_block, old_block_size + 2)); + m_capacity += old_block_size; + + // We insert this new block at the end. + if (m_last_item == NULL) // First time + { + m_first_item = new_block; + m_last_item = new_block + old_block_size + 1; + set_type(m_first_item, NULL, START_END); + } + else + { + set_type(m_last_item, new_block, BLOCK_BOUNDARY); + set_type(new_block, m_last_item, BLOCK_BOUNDARY); + m_last_item = new_block + old_block_size + 1; + } + set_type(m_last_item, NULL, START_END); + // Increase the m_block_size for the next time. + m_block_size += CGAL_INCREMENT_CONCURRENT_COMPACT_CONTAINER_BLOCK_SIZE; + } + + // We don't touch the first and the last one. + // We mark them free in reverse order, so that the insertion order + // will correspond to the iterator order... + for (size_type i = old_block_size; i >= 1; --i) + { + EraseCounterStrategy::set_erase_counter(*(new_block + i), 0); + put_on_free_list(new_block + i, fl); + } +} + +template < class T, class Allocator > +inline +bool operator==(const Concurrent_compact_container &lhs, + const Concurrent_compact_container &rhs) +{ + return lhs.size() == rhs.size() && + std::equal(lhs.begin(), lhs.end(), rhs.begin()); +} + +template < class T, class Allocator > +inline +bool operator!=(const Concurrent_compact_container &lhs, + const Concurrent_compact_container &rhs) +{ + return ! (lhs == rhs); +} + +template < class T, class Allocator > +inline +bool operator< (const Concurrent_compact_container &lhs, + const Concurrent_compact_container &rhs) +{ + return std::lexicographical_compare(lhs.begin(), lhs.end(), + rhs.begin(), rhs.end()); +} + +template < class T, class Allocator > +inline +bool operator> (const Concurrent_compact_container &lhs, + const Concurrent_compact_container &rhs) +{ + return rhs < lhs; +} + +template < class T, class Allocator > +inline +bool operator<=(const Concurrent_compact_container &lhs, + const Concurrent_compact_container &rhs) +{ + return ! (lhs > rhs); +} + +template < class T, class Allocator > +inline +bool operator>=(const Concurrent_compact_container &lhs, + const Concurrent_compact_container &rhs) +{ + return ! (lhs < rhs); +} + +namespace CCC_internal { + + template < class CCC, bool Const > + class CCC_iterator + { + typedef typename CCC::iterator iterator; + typedef CCC_iterator Self; + public: + typedef typename CCC::value_type value_type; + typedef typename CCC::size_type size_type; + typedef typename CCC::difference_type difference_type; + typedef typename boost::mpl::if_c< Const, const value_type*, + value_type*>::type pointer; + typedef typename boost::mpl::if_c< Const, const value_type&, + value_type&>::type reference; + typedef std::bidirectional_iterator_tag iterator_category; + + // the initialization with NULL is required by our Handle concept. + CCC_iterator() + { + m_ptr.p = NULL; + } + + // Either a harmless copy-ctor, + // or a conversion from iterator to const_iterator. + CCC_iterator (const iterator &it) + { + m_ptr.p = &(*it); + } + + // Same for assignment operator (otherwise MipsPro warns) + CCC_iterator & operator= (const iterator &it) + { + m_ptr.p = &(*it); + return *this; + } + + // Construction from NULL + CCC_iterator (Nullptr_t CGAL_assertion_code(n)) + { + CGAL_assertion (n == NULL); + m_ptr.p = NULL; + } + + private: + + union { + pointer p; + void *vp; + } m_ptr; + + // Only Concurrent_compact_container should access these constructors. + friend class Concurrent_compact_container; + + // For begin() + CCC_iterator(pointer ptr, int, int) + { + m_ptr.p = ptr; + if (m_ptr.p == NULL) // empty container. + return; + + ++(m_ptr.p); // if not empty, p = start + if (CCC::type(m_ptr.p) == CCC::FREE) + increment(); + } + + // Construction from raw pointer and for end(). + CCC_iterator(pointer ptr, int) + { + m_ptr.p = ptr; + } + + // NB : in case empty container, begin == end == NULL. + void increment() + { + // It's either pointing to end(), or valid. + CGAL_assertion_msg(m_ptr.p != NULL, + "Incrementing a singular iterator or an empty container iterator ?"); + CGAL_assertion_msg(CCC::type(m_ptr.p) != CCC::START_END, + "Incrementing end() ?"); + + // If it's not end(), then it's valid, we can do ++. + do { + ++(m_ptr.p); + if (CCC::type(m_ptr.p) == CCC::USED || + CCC::type(m_ptr.p) == CCC::START_END) + return; + + if (CCC::type(m_ptr.p) == CCC::BLOCK_BOUNDARY) + m_ptr.p = CCC::clean_pointee(m_ptr.p); + } while (true); + } + + void decrement() + { + // It's either pointing to end(), or valid. + CGAL_assertion_msg(m_ptr.p != NULL, + "Decrementing a singular iterator or an empty container iterator ?"); + CGAL_assertion_msg(CCC::type(m_ptr.p - 1) != CCC::START_END, + "Decrementing begin() ?"); + + // If it's not begin(), then it's valid, we can do --. + do { + --m_ptr.p; + if (CCC::type(m_ptr.p) == CCC::USED || + CCC::type(m_ptr.p) == CCC::START_END) + return; + + if (CCC::type(m_ptr.p) == CCC::BLOCK_BOUNDARY) + m_ptr.p = CCC::clean_pointee(m_ptr.p); + } while (true); + } + + public: + + Self & operator++() + { + CGAL_assertion_msg(m_ptr.p != NULL, + "Incrementing a singular iterator or an empty container iterator ?"); + CGAL_assertion_msg(CCC::type(m_ptr.p) == CCC::USED, + "Incrementing an invalid iterator."); + increment(); + return *this; + } + + Self & operator--() + { + CGAL_assertion_msg(m_ptr.p != NULL, + "Decrementing a singular iterator or an empty container iterator ?"); + CGAL_assertion_msg(CCC::type(m_ptr.p) == CCC::USED + || CCC::type(m_ptr.p) == CCC::START_END, + "Decrementing an invalid iterator."); + decrement(); + return *this; + } + + Self operator++(int) { Self tmp(*this); ++(*this); return tmp; } + Self operator--(int) { Self tmp(*this); --(*this); return tmp; } + + reference operator*() const { return *(m_ptr.p); } + + pointer operator->() const { return (m_ptr.p); } + + // For std::less... + bool operator<(const CCC_iterator& other) const + { + return (m_ptr.p < other.m_ptr.p); + } + + bool operator>(const CCC_iterator& other) const + { + return (m_ptr.p > other.m_ptr.p); + } + + bool operator<=(const CCC_iterator& other) const + { + return (m_ptr.p <= other.m_ptr.p); + } + + bool operator>=(const CCC_iterator& other) const + { + return (m_ptr.p >= other.m_ptr.p); + } + + // Can itself be used for bit-squatting. + void * for_compact_container() const { return (m_ptr.vp); } + void * & for_compact_container() { return (m_ptr.vp); } + }; + + template < class CCC, bool Const1, bool Const2 > + inline + bool operator==(const CCC_iterator &rhs, + const CCC_iterator &lhs) + { + return &*rhs == &*lhs; + } + + template < class CCC, bool Const1, bool Const2 > + inline + bool operator!=(const CCC_iterator &rhs, + const CCC_iterator &lhs) + { + return &*rhs != &*lhs; + } + + // Comparisons with NULL are part of CGAL's Handle concept... + template < class CCC, bool Const > + inline + bool operator==(const CCC_iterator &rhs, + Nullptr_t CGAL_assertion_code(n)) + { + CGAL_assertion( n == NULL); + return &*rhs == NULL; + } + + template < class CCC, bool Const > + inline + bool operator!=(const CCC_iterator &rhs, + Nullptr_t CGAL_assertion_code(n)) + { + CGAL_assertion( n == NULL); + return &*rhs != NULL; + } + +} // namespace CCC_internal + +} //namespace CGAL + +#endif // CGAL_CONCURRENT_COMPACT_CONTAINER_H + +#endif // CGAL_LINKED_WITH_TBB diff -Nru cgal-4.4/include/CGAL/config.h cgal-4.5/include/CGAL/config.h --- cgal-4.4/include/CGAL/config.h 2014-02-18 15:00:15.000000000 +0000 +++ cgal-4.5/include/CGAL/config.h 2014-08-29 13:58:16.000000000 +0000 @@ -83,6 +83,9 @@ // feature is not available, even if that is wrong. // ----------------------------------------------------------------------// +#if defined(BOOST_NO_CXX11_RANGE_BASED_FOR) || BOOST_VERSION < 105000 +#define CGAL_NO_CPP0X_RANGE_BASED_FOR 1 +#endif #if defined(BOOST_NO_0X_HDR_ARRAY) || BOOST_VERSION < 104000 #define CGAL_CFG_NO_CPP0X_ARRAY 1 #endif @@ -140,6 +143,20 @@ #define CGAL_CFG_NO_CPP0X_EXPLICIT_CONVERSION_OPERATORS 1 #endif +// Some random list to let us write C++11 without thinking about +// each feature we are using. +#if __cplusplus >= 201103L && \ + !defined CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES && \ + !defined CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE && \ + !defined CGAL_CFG_NO_CPP0X_EXPLICIT_CONVERSION_OPERATORS && \ + !defined CGAL_CFG_NO_CPP0X_TUPLE && \ + !defined CGAL_CFG_NO_CPP0X_UNIFIED_INITIALIZATION_SYNTAX && \ + !defined CGAL_CFG_NO_CPP0X_STATIC_ASSERT && \ + !defined CGAL_CFG_NO_CPP0X_DECLTYPE && \ + !defined CGAL_CFG_NO_CPP0X_DELETED_AND_DEFAULT_FUNCTIONS && \ + !defined CGAL_CFG_NO_CPP0X_DEFAULT_TEMPLATE_ARGUMENTS_FOR_FUNCTION_TEMPLATES +#define CGAL_CXX11 +#endif //----------------------------------------------------------------------// // auto-link the CGAL library on platforms that support it @@ -313,11 +330,17 @@ #ifndef __has_builtin #define __has_builtin(x) 0 // Compatibility with non-clang compilers. #endif +#ifndef __has_attribute + #define __has_attribute(x) 0 // Compatibility with non-clang compilers. +#endif +#ifndef __has_warning + #define __has_warning(x) 0 // Compatibility with non-clang compilers. +#endif // Macro to trigger deprecation warnings #ifdef CGAL_NO_DEPRECATION_WARNINGS # define CGAL_DEPRECATED -#elif defined(__GNUC__) +#elif defined(__GNUC__) || __has_attribute(__deprecated__) # define CGAL_DEPRECATED __attribute__((__deprecated__)) #elif defined (_MSC_VER) && (_MSC_VER > 1300) # define CGAL_DEPRECATED __declspec(deprecated) @@ -327,14 +350,14 @@ // Macro to specify a 'noreturn' attribute. -#ifdef __GNUG__ +#if defined(__GNUG__) || __has_attribute(__noreturn__) # define CGAL_NORETURN __attribute__ ((__noreturn__)) #else # define CGAL_NORETURN #endif // Macro to specify a 'unused' attribute. -#ifdef __GNUG__ +#if defined(__GNUG__) || __has_attribute(__unused__) # define CGAL_UNUSED __attribute__ ((__unused__)) #else # define CGAL_UNUSED @@ -361,6 +384,23 @@ # endif #endif +// Support for LEDA with threads +// Not that, if CGAL_HAS_THREADS is defined, and you want to use LEDA, +// you must link with a version of LEDA libraries that support threads. +#if defined(CGAL_HAS_THREADS) && CGAL_USE_LEDA +# define LEDA_MULTI_THREAD 1 +#endif +// Support for LEDA_numbers on Windows +#define LEDA_NUMBERS_DLL 1 + +// Helper macros to disable macros +#if defined(__clang__) || (BOOST_GCC >= 40600) +# define CGAL_PRAGMA_DIAG_PUSH _Pragma("GCC diagnostic push") +# define CGAL_PRAGMA_DIAG_POP _Pragma("GCC diagnostic pop") +#else +# define CGAL_PRAGMA_DIAG_PUSH +# define CGAL_PRAGMA_DIAG_POP +#endif namespace CGAL { diff -Nru cgal-4.4/include/CGAL/convex_hull_3.h cgal-4.5/include/CGAL/convex_hull_3.h --- cgal-4.4/include/CGAL/convex_hull_3.h 2013-05-25 19:00:28.000000000 +0000 +++ cgal-4.5/include/CGAL/convex_hull_3.h 2014-08-29 13:58:16.000000000 +0000 @@ -44,6 +44,8 @@ #include #include #include +#include +#include #include @@ -85,13 +87,18 @@ class Is_floating_point= typename boost::is_floating_point::Kernel::FT>::type, class Has_filtered_predicates_tag=typename Kernel_traits::Kernel::Has_filtered_predicates_tag, - class Has_cartesian_tag=typename Kernel_traits::Kernel::Kernel_tag > + class Has_cartesian_tag=typename Kernel_traits::Kernel::Kernel_tag, + class Has_classical_point_type = + typename boost::is_same< + typename Kernel_traits::Kernel::Point_3, + typename Traits::Point_3 >::type + > struct Use_advanced_filtering{ typedef CGAL::Tag_false type; }; template -struct Use_advanced_filtering{ +struct Use_advanced_filtering{ typedef typename Kernel_traits::Kernel K; typedef CGAL::Boolean_tag type; }; @@ -274,50 +281,80 @@ ForwardIterator end; }; -template + +namespace internal { namespace Convex_hull_3{ + +BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Traits_has_typedef_Traits_xy_3,Traits_xy_3,false) +BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Traits_has_typedef_Traits_yz_3,Traits_xy_3,false) +BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Traits_has_typedef_Traits_xz_3,Traits_xy_3,false) + +template ::value && + Traits_has_typedef_Traits_yz_3::value && + Traits_has_typedef_Traits_xz_3::value +> +struct Projection_traits{ + typedef typename Kernel_traits::Kernel K; + typedef CGAL::Projection_traits_xy_3 Traits_xy_3; + typedef CGAL::Projection_traits_yz_3 Traits_yz_3; + typedef CGAL::Projection_traits_xz_3 Traits_xz_3; +}; + +template +struct Projection_traits{ + typedef typename T::Traits_xy_3 Traits_xy_3; + typedef typename T::Traits_yz_3 Traits_yz_3; + typedef typename T::Traits_xz_3 Traits_xz_3; +}; + +} } //end of namespace internal::Convex_hull_3 + +template void coplanar_3_hull(InputIterator first, InputIterator beyond, - Plane_3 plane, Polyhedron_3& P, const Traits& traits) + const Point_3& p1, const Point_3& p2, const Point_3& p3, + Polyhedron_3& P, const Traits& traits) { - typedef typename Traits::Point_3 Point_3; - typedef typename Kernel_traits::Kernel R; typedef typename Traits::Vector_3 Vector_3; - typedef Max_coordinate_3 Max_coordinate_3; - typedef Polyhedron_3 Polyhedron; - + typedef typename Traits::Construct_vector_3 Construct_vector_3; + typedef typename Traits::Orientation_3 Orientation_3; + + typedef typename internal::Convex_hull_3::Projection_traits PTraits; + typedef typename PTraits::Traits_xy_3 Traits_xy_3; + typedef typename PTraits::Traits_yz_3 Traits_yz_3; + typedef typename PTraits::Traits_xz_3 Traits_xz_3; + std::list CH_2; typedef typename std::list::iterator CH_2_iterator; - typedef typename Traits::Construct_orthogonal_vector_3 - Construct_normal_vec; - Max_coordinate_3 max_coordinate; - - Construct_normal_vec c_normal = - traits.construct_orthogonal_vector_3_object(); - Vector_3 normal = c_normal(plane); - int max_coord = max_coordinate(normal); - switch (max_coord) - { - case 0: - { - convex_hull_points_2(first, beyond, std::back_inserter(CH_2), - Projection_traits_yz_3()); - break; - } - case 1: - { - convex_hull_points_2(first, beyond, std::back_inserter(CH_2), - Projection_traits_xz_3()); - break; - } - case 2: - { - convex_hull_points_2(first, beyond, std::back_inserter(CH_2), - Projection_traits_xy_3()); - break; - } - default: - break; + + Construct_vector_3 vector_3 = traits.construct_vector_3_object(); + Orientation_3 orientation = traits.orientation_3_object(); + Vector_3 v1 = vector_3(p1,p2); + Vector_3 v2 = vector_3(p1,p3); + + Vector_3 vx = vector_3(1,0,0); + + + + if ( orientation(v1, v2, vx) != COPLANAR ) + convex_hull_points_2( first, beyond, + std::back_inserter(CH_2), + Traits_yz_3() ); + else{ + Vector_3 vy = vector_3(0,1,0); + if ( orientation(v1,v2,vy) != COPLANAR ) + convex_hull_points_2( first, beyond, + std::back_inserter(CH_2), + Traits_xz_3() ); + else{ + CGAL_assertion_code( Vector_3 vz = vector_3(0,0,1); ) + CGAL_assertion( orientation(v1,v2,vz) != COPLANAR ); + convex_hull_points_2( first, beyond, + std::back_inserter(CH_2), + Traits_xy_3() ); + } } - typedef typename Polyhedron::Halfedge_data_structure HDS; + + typedef typename Polyhedron_3::Halfedge_data_structure HDS; Build_coplanar_poly poly(CH_2.begin(),CH_2.end()); P.delegate(poly); @@ -670,10 +707,9 @@ typedef typename Traits::Plane_3 Plane_3; typedef typename std::list::iterator P3_iterator; - typedef typename Kernel_traits::Kernel R; typedef Triangulation_data_structure_2< - Triangulation_vertex_base_with_info_2 >, - Convex_hull_face_base_2 > Tds; + Triangulation_vertex_base_with_info_2 >, + Convex_hull_face_base_2 > Tds; typedef typename Tds::Vertex_handle Vertex_handle; typedef typename Tds::Face_handle Face_handle; @@ -708,7 +744,7 @@ // if the maximum distance point is on the plane then all are coplanar if (coplanar(*point1_it, *point2_it, *point3_it, *max_it)) { - coplanar_3_hull(points.begin(), points.end(), plane, P, traits); + coplanar_3_hull(points.begin(), points.end(), *point1_it, *point2_it, *point3_it, P, traits); } else { Tds tds; Vertex_handle v0 = tds.create_vertex(); v0->set_point(*point1_it); diff -Nru cgal-4.4/include/CGAL/Convex_hull_traits_3.h cgal-4.5/include/CGAL/Convex_hull_traits_3.h --- cgal-4.4/include/CGAL/Convex_hull_traits_3.h 2012-11-13 13:13:55.000000000 +0000 +++ cgal-4.5/include/CGAL/Convex_hull_traits_3.h 2014-08-29 13:58:16.000000000 +0000 @@ -130,29 +130,6 @@ } }; - - -template -class Max_coordinate_3 -{ -public: - - int operator()(const T& v) - { - if (CGAL_NTS abs(v.x()) >= CGAL_NTS abs(v.y())) - { - if (CGAL_NTS abs(v.x()) >= CGAL_NTS abs(v.z())) return 0; - return 2; - } - else - { - if (CGAL_NTS abs(v.y()) >= CGAL_NTS abs(v.z())) return 1; - return 2; - } - } -}; - - template struct GT3_for_CH3 { typedef typename GT::Point_3 Point_2; @@ -185,7 +162,6 @@ } }; - typedef typename R::Construct_vector_3 Construct_vector_3; typedef typename R::Construct_triangle_3 Construct_triangle_3; typedef typename R::Construct_centroid_3 Construct_centroid_3; typedef Point_triple_construct_orthogonal_vector_3 @@ -199,17 +175,18 @@ typedef Point_triple_has_on_positive_side_3 Has_on_positive_side_3; typedef Point_triple_less_signed_distance_to_plane_3 - Less_signed_distance_to_plane_3; + Less_signed_distance_to_plane_3; // required for degenerate case of all points coplanar - typedef CGAL::Max_coordinate_3 Max_coordinate_3; - + typedef CGAL::Projection_traits_xy_3 Traits_xy_3; + typedef CGAL::Projection_traits_yz_3 Traits_yz_3; + typedef CGAL::Projection_traits_xz_3 Traits_xz_3; + typedef typename R::Construct_vector_3 Construct_vector_3; // for postcondition checking typedef typename R::Ray_3 Ray_3; typedef typename R::Has_on_3 Has_on_3; typedef Point_triple_oriented_side_3 Oriented_side_3; - typedef typename R::Intersect_3 Intersect_3; typedef typename R::Do_intersect_3 Do_intersect_3; Construct_segment_3 @@ -228,10 +205,6 @@ construct_triangle_3_object() const { return Construct_triangle_3(); } - Construct_vector_3 - construct_vector_3_object() const - { return Construct_vector_3(); } - Construct_centroid_3 construct_centroid_3_object() const { return Construct_centroid_3(); } @@ -268,10 +241,6 @@ equal_3_object() const { return Equal_3(); } - Intersect_3 - intersect_3_object() const - { return Intersect_3(); } - Do_intersect_3 do_intersect_3_object() const { return Do_intersect_3(); } @@ -280,9 +249,14 @@ less_signed_distance_to_plane_3_object() const { return Less_signed_distance_to_plane_3(); } - Max_coordinate_3 - max_coordinate_3_object() const - { return Max_coordinate_3(); } + Orientation_3 + orientation_3_object() const + { return Orientation_3(); } + + Construct_vector_3 + construct_vector_3_object() const + { return Construct_vector_3(); } + }; } // namespace CGAL diff -Nru cgal-4.4/include/CGAL/CORE_BigFloat.h cgal-4.5/include/CGAL/CORE_BigFloat.h --- cgal-4.4/include/CGAL/CORE_BigFloat.h 2012-11-13 13:13:59.000000000 +0000 +++ cgal-4.5/include/CGAL/CORE_BigFloat.h 2014-08-29 13:58:16.000000000 +0000 @@ -531,6 +531,7 @@ typedef CORE::BigFloat Nested; static inline Real epsilon() { return 0; } + static inline Real dummy_precision() { return 0; } enum { IsInteger = 0, diff -Nru cgal-4.4/include/CGAL/CORE_BigInt.h cgal-4.5/include/CGAL/CORE_BigInt.h --- cgal-4.4/include/CGAL/CORE_BigInt.h 2012-11-13 13:13:59.000000000 +0000 +++ cgal-4.5/include/CGAL/CORE_BigInt.h 2014-08-29 13:58:16.000000000 +0000 @@ -209,6 +209,7 @@ typedef CORE::BigInt Nested; static inline Real epsilon() { return 0; } + static inline Real dummy_precision() { return 0; } enum { IsInteger = 1, diff -Nru cgal-4.4/include/CGAL/CORE_BigRat.h cgal-4.5/include/CGAL/CORE_BigRat.h --- cgal-4.4/include/CGAL/CORE_BigRat.h 2012-11-13 13:13:59.000000000 +0000 +++ cgal-4.5/include/CGAL/CORE_BigRat.h 2014-08-29 13:58:16.000000000 +0000 @@ -243,6 +243,7 @@ typedef CORE::BigRat Nested; static inline Real epsilon() { return 0; } + static inline Real dummy_precision() { return 0; } enum { IsInteger = 0, diff -Nru cgal-4.4/include/CGAL/CORE_Expr.h cgal-4.5/include/CGAL/CORE_Expr.h --- cgal-4.4/include/CGAL/CORE_Expr.h 2012-11-13 13:13:59.000000000 +0000 +++ cgal-4.5/include/CGAL/CORE_Expr.h 2014-08-29 13:58:16.000000000 +0000 @@ -198,6 +198,7 @@ typedef CORE::Expr Nested; static inline Real epsilon() { return 0; } + static inline Real dummy_precision() { return 0; } enum { IsInteger = 0, diff -Nru cgal-4.4/include/CGAL/create_offset_polygons_2.h cgal-4.5/include/CGAL/create_offset_polygons_2.h --- cgal-4.4/include/CGAL/create_offset_polygons_2.h 2013-10-12 19:00:22.000000000 +0000 +++ cgal-4.5/include/CGAL/create_offset_polygons_2.h 2014-08-29 13:58:17.000000000 +0000 @@ -171,7 +171,7 @@ template Skeleton const& dereference ( boost::shared_ptr const& ss ) { - CGAL_precondition(ss!= NULL); + CGAL_precondition(ss.get() != 0); return *ss; } diff -Nru cgal-4.4/include/CGAL/Dart.h cgal-4.5/include/CGAL/Dart.h --- cgal-4.4/include/CGAL/Dart.h 2013-11-30 20:00:27.000000000 +0000 +++ cgal-4.5/include/CGAL/Dart.h 2014-08-29 13:58:16.000000000 +0000 @@ -65,7 +65,7 @@ template friend class Linear_cell_complex_storage_2; - template + template friend class Compact_container; template diff -Nru cgal-4.4/include/CGAL/Dart_iterators.h cgal-4.5/include/CGAL/Dart_iterators.h --- cgal-4.4/include/CGAL/Dart_iterators.h 2013-11-30 20:00:27.000000000 +0000 +++ cgal-4.5/include/CGAL/Dart_iterators.h 2014-08-29 13:58:16.000000000 +0000 @@ -1246,7 +1246,6 @@ else { this->mprev_op = OP_END; - this->set_current_dart(this->mmap->null_handle); } } @@ -1343,7 +1342,6 @@ else { this->mprev_op = OP_END; - this->set_current_dart(this->mmap->null_handle); } } @@ -1484,7 +1482,6 @@ else { this->mprev_op = OP_END; - this->set_current_dart(this->mmap->null_handle); } } @@ -1977,7 +1974,6 @@ else { this->mprev_op = OP_END; - this->set_current_dart(this->mmap->null_handle); } } @@ -2098,7 +2094,6 @@ else { this->mprev_op = OP_END; - this->set_current_dart(this->mmap->null_handle); } } @@ -2197,7 +2192,6 @@ else { this->mprev_op = OP_END; - this->set_current_dart(this->mmap->null_handle); } } @@ -2323,7 +2317,6 @@ else { this->mprev_op = OP_END; - this->set_current_dart(this->mmap->null_handle); } } diff -Nru cgal-4.4/include/CGAL/Deformation_Eigen_closest_rotation_traits_3.h cgal-4.5/include/CGAL/Deformation_Eigen_closest_rotation_traits_3.h --- cgal-4.4/include/CGAL/Deformation_Eigen_closest_rotation_traits_3.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/Deformation_Eigen_closest_rotation_traits_3.h 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,109 @@ +// Copyright (c) 2013 INRIA Bordeaux Sud-Ouest (France), All rights reserved. +// Copyright (c) 2013 GeometryFactory +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Gael Guennebaud and Ilker O. Yaz + + +#ifndef CGAL_DEFORMATION_EIGEN_CLOSEST_ROTATION_TRAITS_3_H +#define CGAL_DEFORMATION_EIGEN_CLOSEST_ROTATION_TRAITS_3_H + +#include +#include + +namespace CGAL { +/// \ingroup PkgSurfaceModeling +/// A class to compute the closest rotation in Frobenius norm to a 3x3 Matrix using the \link thirdpartyEigen `Eigen` library \endlink. +/// The internal computation relies on `Eigen::JacobiSVD<>` solver. +/// +/// \cgalModels `DeformationClosestRotationTraits_3` +class Deformation_Eigen_closest_rotation_traits_3{ +public: + + /// \cond SKIP_FROM_MANUAL + typedef Eigen::Matrix3d Matrix; + typedef Eigen::Vector3d Vector; + + /// Equivalent to `result += w * (v1*v2^t)` + void add_scalar_t_vector_t_vector_transpose(Matrix& result, double w, const Vector& v1, const Vector& v2) + { + result += w * (v1*v2.transpose()); + } + + /// Equivalent to `result += (w1*m1 + w2*m2) * v` + void add__scalar_t_matrix_p_scalar_t_matrix__t_vector(Vector& result, double w1, const Matrix& m1, double w2, const Matrix& m2, const Vector& v) + { + result += (w1*m1 + w2*m2) * v; + } + + /// Equivalent to `result += w * (m1 + m2 + m3) * v` + void add_scalar_t_matrix_sum_t_vector(Vector& result, double w, const Matrix& m1, const Matrix& m2, const Matrix& m3, const Vector& v) + { + result += w * (m1 + m2 + m3) * v; + } + + /// Returns the squared norm of `v1 - m*v2` + double squared_norm_vector_scalar_vector_subs(const Vector& v1, const Matrix& m, const Vector& v2) + { + return (v1 - m*v2).squaredNorm(); + } + + /// Returns an identity matrix + Matrix identity_matrix() + { + return Matrix().setIdentity(); + } + + /// Returns a zero initialized matrix + Matrix zero_matrix() + { + return Matrix().setZero(); + } + + /// Returns vector initialized with parameters + Vector vector(double x, double y, double z) + { + return Vector(x, y, z); + } + + /// Returns a coefficient of a vector + double vector_coordinate(const Vector& v, int i) + { + return v(i); + } + + /// Computes the closest rotation to `m` and places it into `R` + void compute_close_rotation(const Matrix& m, Matrix& R) + { + Eigen::JacobiSVD solver; + solver.compute( m, Eigen::ComputeFullU | Eigen::ComputeFullV ); + + const Matrix& u = solver.matrixU(); const Matrix& v = solver.matrixV(); + R = v * u.transpose(); + + if( R.determinant() < 0 ) { + Matrix u_copy = u; + u_copy.col(2) *= -1; // singular values sorted ascendingly + R = v * u_copy.transpose(); // re-extract rotation matrix + } + } + + /// \endcond + +}; + +}//namespace CGAL +#endif // CGAL_DEFORMATION_EIGEN_CLOSEST_ROTATION_TRAITS_3_H diff -Nru cgal-4.4/include/CGAL/Deformation_Eigen_polar_closest_rotation_traits_3.h cgal-4.5/include/CGAL/Deformation_Eigen_polar_closest_rotation_traits_3.h --- cgal-4.4/include/CGAL/Deformation_Eigen_polar_closest_rotation_traits_3.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/Deformation_Eigen_polar_closest_rotation_traits_3.h 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,84 @@ +// Copyright (c) 2013 INRIA Bordeaux Sud-Ouest (France), All rights reserved. +// Copyright (c) 2013 GeometryFactory +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Gael Guennebaud Ilker O. Yaz + + +#ifndef CGAL_DEFORMATION_EIGEN_POLAR_CLOSEST_ROTATION_TRAITS_3_H +#define CGAL_DEFORMATION_EIGEN_POLAR_CLOSEST_ROTATION_TRAITS_3_H + +#include +#include +#include + +namespace CGAL { + /// \ingroup PkgSurfaceModeling + /// A class to compute the closest rotation in Frobenius norm to a 3x3 Matrix using the \link thirdpartyEigen `Eigen` library \endlink. + /// The internal computation relies on a hybrid system using the solvers `Eigen::SelfAdjointEigenSolver<>` + /// and `Eigen::JacobiSVD<>` (polar decomposition). + /// + /// \cgalModels `DeformationClosestRotationTraits_3` + class Deformation_Eigen_polar_closest_rotation_traits_3 : + public Deformation_Eigen_closest_rotation_traits_3{ + public: + + /// \cond SKIP_FROM_MANUAL + + /// Computes closest rotation to `m` and places it into `R` + void compute_close_rotation(const Matrix& m, Matrix& R) + { + CGAL_PROFILER(" times closest rotation is computed"); + bool solved = polar_eigen(m, R); + + if(!solved) { + CGAL_PROFILER(" times polar_eigen failed and SVD is called"); + Deformation_Eigen_closest_rotation_traits_3::compute_close_rotation(m, R); + } + } + + private: + // polar decomposition using Eigen, 5 times faster than SVD + bool polar_eigen(const Matrix& A, Matrix& R) + { + if(A.determinant() < 0) + { return false; } + + typedef Matrix::Scalar Scalar; + + const Scalar th = std::sqrt(Eigen::NumTraits::dummy_precision()); + + Eigen::SelfAdjointEigenSolver eig; + CGAL::feclearexcept(FE_UNDERFLOW); + eig.computeDirect(A.transpose()*A); + if(CGAL::fetestexcept(FE_UNDERFLOW) || eig.eigenvalues()(0)/eig.eigenvalues()(2) th || R.determinant() < 0) + { return false; } + + R.transposeInPlace(); // the optimal rotation matrix should be transpose of decomposition result + return true; + } + /// \endcond + + }; +}//namespace CGAL +#endif // CGAL_DEFORMATION_EIGEN_POLAR_CLOSEST_ROTATION_TRAITS_3_H diff -Nru cgal-4.4/include/CGAL/Deform_mesh.h cgal-4.5/include/CGAL/Deform_mesh.h --- cgal-4.4/include/CGAL/Deform_mesh.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/Deform_mesh.h 2014-10-04 19:00:10.000000000 +0000 @@ -0,0 +1,112 @@ +// Copyright (c) 2014 GeometryFactory +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Yin Xu, Andreas Fabri and Ilker O. Yaz + +#ifndef CGAL_DEFORM_MESH_H +#define CGAL_DEFORM_MESH_H + +#ifdef DOXYGEN_RUNNING +template < + class HG, + class VIM=Default, + class HIM=Default, + Deformation_algorithm_tag TAG = SPOKES_AND_RIMS, + class WC = Default, + class ST = Default, + class CR = Default, + class VPM = Default + > +class Surface_mesh_deformation; +#endif + +#ifndef CGAL_NO_DEPRECATED_CODE + +#define CGAL_DEPRECATED_HEADER "" +#define CGAL_REPLACEMENT_HEADER "" +#include + +#include + +namespace CGAL { + + /// + /// \ingroup PkgSurfaceModeling + /// Class renamed to `Surface_mesh_deformation`. + /// \deprecated This class name is deprecated and has been renamed to `Surface_mesh_deformation`. +template < + class HG, + class VIM=Default, + class HIM=Default, + Deformation_algorithm_tag TAG = SPOKES_AND_RIMS, + class WC = Default, + class ST = Default, + class CR = Default, + class VPM = Default + > +class Deform_mesh : public Surface_mesh_deformation +{ + typedef Deform_mesh Self; + typedef Surface_mesh_deformation Base; +#ifndef CGAL_CFG_NO_CPP0X_DELETED_AND_DEFAULT_FUNCTIONS +public: + Deform_mesh(const Self&) = delete; // no copy +#else +private: + Deform_mesh(const Self&); // no copy +#endif + +public: + typedef typename Base::Halfedge_graph Halfedge_graph; + typedef typename Base::Vertex_index_map Vertex_index_map; + typedef typename Base::Hedge_index_map Hedge_index_map; + typedef typename Base::Weight_calculator Weight_calculator; + typedef typename Base::Vertex_point_map Vertex_point_map; + + //vertex_point_map set by default + Deform_mesh(Halfedge_graph& halfedge_graph, + Vertex_index_map vertex_index_map, + Hedge_index_map hedge_index_map + ) + : Base(halfedge_graph, vertex_index_map, hedge_index_map) + {} + + //vertex_point_map and hedge_index_map set by default + Deform_mesh(Halfedge_graph& halfedge_graph, + Vertex_index_map vertex_index_map) + : Base(halfedge_graph, vertex_index_map) + {} + //vertex_point_map, hedge_index_map and vertex_index_map set by default + Deform_mesh(Halfedge_graph& halfedge_graph) + : Base(halfedge_graph) + {} + + // Constructor with all the parameters provided + Deform_mesh(Halfedge_graph& halfedge_graph, + Vertex_index_map vertex_index_map, + Hedge_index_map hedge_index_map, + Vertex_point_map vertex_point_map, + Weight_calculator weight_calculator = Weight_calculator() + ) + : Base(halfedge_graph, vertex_index_map, hedge_index_map, vertex_point_map, weight_calculator) + {} +}; +} //namespace CGAL + +#endif //CGAL_NO_DEPRECATED_CODE + +#endif // CGAL_DEFORM_MESH_H diff -Nru cgal-4.4/include/CGAL/Delaunay_triangulation_3.h cgal-4.5/include/CGAL/Delaunay_triangulation_3.h --- cgal-4.4/include/CGAL/Delaunay_triangulation_3.h 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/include/CGAL/Delaunay_triangulation_3.h 2014-08-29 13:58:17.000000000 +0000 @@ -19,18 +19,27 @@ // Author(s) : Monique Teillaud // Sylvain Pion // Andreas Fabri +// Clement Jamin #ifndef CGAL_DELAUNAY_TRIANGULATION_3_H #define CGAL_DELAUNAY_TRIANGULATION_3_H #include +#ifdef CGAL_CONCURRENT_TRIANGULATION_3_PROFILING +# define CGAL_PROFILE +# include +#endif + #include #include #include #include #include +#ifdef CGAL_TRIANGULATION_3_PROFILING +# include +#endif #ifndef CGAL_TRIANGULATION_3_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO #include @@ -41,6 +50,13 @@ #include #endif //CGAL_TRIANGULATION_3_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO +#ifdef CGAL_LINKED_WITH_TBB +# include +# include +# include +# include +#endif + #ifdef CGAL_DELAUNAY_3_OLD_REMOVE # error "The old remove() code has been removed. Please report any issue you may have with the current one." #endif @@ -51,7 +67,8 @@ // having a default value. There is no definition of that class template. template < class Gt, class Tds_ = Default, - class Location_policy = Default > + class Location_policy = Default, + class Lock_data_structure_ = Default > class Delaunay_triangulation_3; // There is a specialization Delaunay_triangulation_3 @@ -59,12 +76,14 @@ // Here is the specialization Delaunay_triangulation_3, with two // arguments, that is if Location_policy being the default value 'Default'. -template < class Gt, class Tds_ > -class Delaunay_triangulation_3 - : public Triangulation_3 -{ - typedef Delaunay_triangulation_3 Self; - typedef Triangulation_3 Tr_Base; +template < class Gt, class Tds_, + class Lock_data_structure_ > +class Delaunay_triangulation_3 + : public Triangulation_3 +{ + typedef Delaunay_triangulation_3 Self; + typedef Triangulation_3 Tr_Base; public: @@ -73,6 +92,8 @@ typedef Gt Geom_traits; typedef Compact_location Location_policy; + typedef typename Tr_Base::Lock_data_structure Lock_data_structure; + typedef typename Gt::Point_3 Point; typedef typename Gt::Segment_3 Segment; typedef typename Gt::Triangle_3 Triangle; @@ -148,11 +169,11 @@ Oriented_side side_of_oriented_sphere(const Point &p0, const Point &p1, const Point &p2, - const Point &p3, const Point &t, bool perturb = false) const; + const Point &p3, const Point &t, bool perturb = false) const; Bounded_side coplanar_side_of_bounded_circle(const Point &p, const Point &q, - const Point &r, const Point &s, bool perturb = false) const; + const Point &r, const Point &s, bool perturb = false) const; // for dual: Point @@ -200,10 +221,24 @@ public: - Delaunay_triangulation_3(const Gt& gt = Gt()) - : Tr_Base(gt) + Delaunay_triangulation_3(const Gt& gt = Gt(), Lock_data_structure *lock_ds = NULL) + : Tr_Base(gt, lock_ds) {} + Delaunay_triangulation_3(Lock_data_structure *lock_ds, const Gt& gt = Gt()) + : Tr_Base(lock_ds, gt) + {} + + // Create a 3D triangulation from 4 points which must be well-oriented + // AND non-coplanar + Delaunay_triangulation_3(const Point &p0, const Point &p1, + const Point &p2, const Point &p3, + const Gt& gt = Gt(), + Lock_data_structure *lock_ds = NULL) + : Tr_Base(p0, p1, p2, p3, gt, lock_ds) + {} + + // copy constructor duplicates vertices and cells Delaunay_triangulation_3(const Delaunay_triangulation_3 & tr) : Tr_Base(tr) @@ -213,8 +248,17 @@ template < typename InputIterator > Delaunay_triangulation_3(InputIterator first, InputIterator last, + const Gt& gt = Gt(), Lock_data_structure *lock_ds = NULL) + : Tr_Base(gt, lock_ds) + { + insert(first, last); + } + + template < typename InputIterator > + Delaunay_triangulation_3(InputIterator first, InputIterator last, + Lock_data_structure *lock_ds, const Gt& gt = Gt()) - : Tr_Base(gt) + : Tr_Base(gt, lock_ds) { insert(first, last); } @@ -236,21 +280,110 @@ insert( InputIterator first, InputIterator last) #endif //CGAL_TRIANGULATION_3_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO { +#ifdef CGAL_TRIANGULATION_3_PROFILING + WallClockTimer t; +#endif + size_type n = number_of_vertices(); std::vector points (first, last); spatial_sort (points.begin(), points.end(), geom_traits()); - Vertex_handle hint; - for (typename std::vector::const_iterator p = points.begin(), end = points.end(); - p != end; ++p) - hint = insert(*p, hint); + // Parallel +#ifdef CGAL_LINKED_WITH_TBB + if (this->is_parallel()) + { + size_t num_points = points.size(); + + Vertex_handle hint; + std::vector far_sphere_vertices; + +#ifdef CGAL_CONCURRENT_TRIANGULATION_3_ADD_TEMPORARY_POINTS_ON_FAR_SPHERE + const size_t MIN_NUM_POINTS_FOR_FAR_SPHERE_POINTS = 1000000; + if (num_points >= MIN_NUM_POINTS_FOR_FAR_SPHERE_POINTS) + { + // Add temporary vertices on a "far sphere" to reduce contention on + // the infinite vertex + + // Get bbox + const Bbox_3 &bbox = *this->get_bbox(); + // Compute radius for far sphere + const double& xdelta = bbox.xmax() - bbox.xmin(); + const double& ydelta = bbox.ymax() - bbox.ymin(); + const double& zdelta = bbox.zmax() - bbox.zmin(); + const double radius = 1.3 * 0.5 * std::sqrt(xdelta*xdelta + + ydelta*ydelta + + zdelta*zdelta); + // WARNING - TODO: this code has to be fixed because Vector_3 is not + // required by the traits concept + const typename Gt::Vector_3 center( + bbox.xmin() + 0.5*xdelta, + bbox.ymin() + 0.5*ydelta, + bbox.zmin() + 0.5*zdelta); + Random_points_on_sphere_3 random_point(radius); + const int NUM_PSEUDO_INFINITE_VERTICES = static_cast( + tbb::task_scheduler_init::default_num_threads() * 3.5); + std::vector points_on_far_sphere; + for (int i = 0 ; i < NUM_PSEUDO_INFINITE_VERTICES ; ++i, ++random_point) + points_on_far_sphere.push_back(*random_point + center); + + spatial_sort(points_on_far_sphere.begin(), + points_on_far_sphere.end(), + geom_traits()); + + std::vector::const_iterator it_p = points_on_far_sphere.begin(); + std::vector::const_iterator it_p_end = points_on_far_sphere.end(); + for ( ; it_p != it_p_end ; ++it_p) + { + hint = insert(*it_p, hint); + far_sphere_vertices.push_back(hint); + } + } +#endif // CGAL_CONCURRENT_TRIANGULATION_3_ADD_TEMPORARY_POINTS_ON_FAR_SPHERE + + int i = 0; + // Insert "num_points_seq" points sequentially + // (or more if dim < 3 after that) + size_t num_points_seq = (std::min)(num_points, (size_t)100); + while (dimension() < 3 || i < num_points_seq) + { + hint = insert(points[i], hint); + ++i; + } + + tbb::enumerable_thread_specific tls_hint(hint); + tbb::parallel_for( + tbb::blocked_range( i, num_points ), + Insert_point(*this, points, tls_hint) + ); + +#ifdef CGAL_CONCURRENT_TRIANGULATION_3_ADD_TEMPORARY_POINTS_ON_FAR_SPHERE + if (num_points >= MIN_NUM_POINTS_FOR_FAR_SPHERE_POINTS) + { + // Remove the temporary vertices on far sphere + remove(far_sphere_vertices.begin(), far_sphere_vertices.end()); + } +#endif // CGAL_CONCURRENT_TRIANGULATION_3_ADD_TEMPORARY_POINTS_ON_FAR_SPHERE + } + // Sequential + else +#endif // CGAL_LINKED_WITH_TBB + { + Vertex_handle hint; + for (typename std::vector::const_iterator p = points.begin(), end = points.end(); + p != end; ++p) + hint = insert(*p, hint); + } + +#ifdef CGAL_TRIANGULATION_3_PROFILING + std::cerr << "Triangulation computed in " << t.elapsed() << " seconds." << std::endl; +#endif return number_of_vertices() - n; } - - + + #ifndef CGAL_TRIANGULATION_3_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO -private: +private: //top stands for tuple-or-pair template const Point& top_get_first(const std::pair& pair) const { return pair.first; } @@ -277,7 +410,7 @@ } typedef Spatial_sort_traits_adapter_3 Search_traits; - + spatial_sort(indices.begin(),indices.end(),Search_traits(&(points[0]),geom_traits())); Vertex_handle hint; @@ -290,7 +423,7 @@ return number_of_vertices() - n; } - + public: template < class InputIterator > @@ -322,24 +455,28 @@ return insert_with_info< boost::tuple::type> >(first,last); } #endif //CGAL_TRIANGULATION_3_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO - - Vertex_handle insert(const Point & p, Vertex_handle hint) + + Vertex_handle insert(const Point & p, Vertex_handle hint, + bool *could_lock_zone = NULL) { - return insert(p, hint == Vertex_handle() ? this->infinite_cell() : hint->cell()); + return insert(p, hint == Vertex_handle() ? this->infinite_cell() : hint->cell(), + could_lock_zone); } - Vertex_handle insert(const Point & p, Cell_handle start = Cell_handle()); + Vertex_handle insert(const Point & p, Cell_handle start = Cell_handle(), + bool *could_lock_zone = NULL); Vertex_handle insert(const Point & p, Locate_type lt, - Cell_handle c, int li, int); - + Cell_handle c, int li, int, + bool *could_lock_zone = NULL); + public: // internal methods - + template - Vertex_handle insert_and_give_new_cells(const Point &p, + Vertex_handle insert_and_give_new_cells(const Point &p, OutputItCells fit, Cell_handle start = Cell_handle() ); - + template Vertex_handle insert_and_give_new_cells(const Point& p, OutputItCells fit, @@ -348,14 +485,14 @@ template Vertex_handle insert_and_give_new_cells(const Point& p, Locate_type lt, - Cell_handle c, int li, int lj, - OutputItCells fit); + Cell_handle c, int li, int lj, + OutputItCells fit); + +public: -public: - #ifndef CGAL_NO_DEPRECATED_CODE CGAL_DEPRECATED Vertex_handle move_point(Vertex_handle v, const Point & p); -#endif +#endif template find_conflicts(const Point &p, Cell_handle c, - OutputIteratorBoundaryFacets bfit, + OutputIteratorBoundaryFacets bfit, OutputIteratorCells cit, - OutputIteratorInternalFacets ifit) const + OutputIteratorInternalFacets ifit, + bool *could_lock_zone = NULL) const { CGAL_triangulation_precondition(dimension() >= 2); @@ -377,33 +515,33 @@ if (dimension() == 2) { Conflict_tester_2 tester(p, this); - ifit = Tr_Base::find_conflicts - (c, tester, - make_triple(std::back_inserter(facets), - std::back_inserter(cells), - ifit)).third; + ifit = Tr_Base::find_conflicts + (c, tester, + make_triple(std::back_inserter(facets), + std::back_inserter(cells), + ifit), could_lock_zone).third; } else { Conflict_tester_3 tester(p, this); - ifit = Tr_Base::find_conflicts - (c, tester, - make_triple(std::back_inserter(facets), - std::back_inserter(cells), - ifit)).third; + ifit = Tr_Base::find_conflicts + (c, tester, + make_triple(std::back_inserter(facets), + std::back_inserter(cells), + ifit), could_lock_zone).third; } // Reset the conflict flag on the boundary. for(typename std::vector::iterator fit=facets.begin(); fit != facets.end(); ++fit) { fit->first->neighbor(fit->second)->tds_data().clear(); - *bfit++ = *fit; + *bfit++ = *fit; } // Reset the conflict flag in the conflict cells. for(typename std::vector::iterator ccit=cells.begin(); ccit != cells.end(); ++ccit) { (*ccit)->tds_data().clear(); - *cit++ = *ccit; + *cit++ = *ccit; } return make_triple(bfit, cit, ifit); } @@ -411,13 +549,15 @@ template std::pair find_conflicts(const Point &p, Cell_handle c, - OutputIteratorBoundaryFacets bfit, - OutputIteratorCells cit) const + OutputIteratorBoundaryFacets bfit, + OutputIteratorCells cit, + bool *could_lock_zone = NULL) const { Triple t = find_conflicts(p, c, bfit, cit, - Emptyset_iterator()); + Emptyset_iterator> t = find_conflicts(p, c, bfit, cit, + Emptyset_iterator(), + could_lock_zone); return std::make_pair(t.first, t.second); } @@ -442,22 +582,22 @@ // Get the facets on the boundary of the hole. std::vector facets; find_conflicts(p, c, std::back_inserter(facets), - Emptyset_iterator(), Emptyset_iterator()); + Emptyset_iterator(), Emptyset_iterator()); // Then extract uniquely the vertices. std::set vertices; if (dimension() == 3) { for (typename std::vector::const_iterator i = facets.begin(); - i != facets.end(); ++i) { - vertices.insert(i->first->vertex((i->second+1)&3)); - vertices.insert(i->first->vertex((i->second+2)&3)); - vertices.insert(i->first->vertex((i->second+3)&3)); + i != facets.end(); ++i) { + vertices.insert(i->first->vertex((i->second+1)&3)); + vertices.insert(i->first->vertex((i->second+2)&3)); + vertices.insert(i->first->vertex((i->second+3)&3)); } } else { for (typename std::vector::const_iterator i = facets.begin(); - i != facets.end(); ++i) { - vertices.insert(i->first->vertex(cw(i->second))); - vertices.insert(i->first->vertex(ccw(i->second))); + i != facets.end(); ++i) { + vertices.insert(i->first->vertex(cw(i->second))); + vertices.insert(i->first->vertex(ccw(i->second))); } } @@ -466,10 +606,13 @@ // REMOVE void remove(Vertex_handle v); + // Concurrency-safe + // See Triangulation_3::remove for more information + bool remove(Vertex_handle v, bool *could_lock_zone); // return new cells (internal) template - void remove_and_give_new_cells(Vertex_handle v, + void remove_and_give_new_cells(Vertex_handle v, OutputItCells fit); template < typename InputIterator > @@ -477,13 +620,51 @@ { CGAL_triangulation_precondition(!this->does_repeat_in_range(first, beyond)); size_type n = number_of_vertices(); - while (first != beyond) { - remove(*first); - ++first; + +#ifdef CGAL_TRIANGULATION_3_PROFILING + WallClockTimer t; +#endif + + // Parallel +#ifdef CGAL_LINKED_WITH_TBB + if (this->is_parallel()) + { + // TODO: avoid that by asking for random-access iterators? + std::vector vertices(first, beyond); + tbb::concurrent_vector vertices_to_remove_sequentially; + + tbb::parallel_for( + tbb::blocked_range( 0, vertices.size()), + Remove_point(*this, vertices, vertices_to_remove_sequentially) + ); + + // Do the rest sequentially + for ( typename tbb::concurrent_vector::const_iterator + it = vertices_to_remove_sequentially.begin(), + it_end = vertices_to_remove_sequentially.end() + ; it != it_end + ; ++it) + { + remove(*it); + } } + // Sequential + else +#endif // CGAL_LINKED_WITH_TBB + { + while (first != beyond) { + remove(*first); + ++first; + } + } + +#ifdef CGAL_TRIANGULATION_3_PROFILING + double elapsed = t.elapsed(); + std::cerr << "Points removed in " << elapsed << " seconds." << std::endl; +#endif return n - number_of_vertices(); } - + template < typename InputIterator > size_type remove_cluster(InputIterator first, InputIterator beyond) { @@ -499,22 +680,22 @@ // return new cells (internal) template - Vertex_handle move_if_no_collision_and_give_new_cells(Vertex_handle v, - const Point &p, + Vertex_handle move_if_no_collision_and_give_new_cells(Vertex_handle v, + const Point &p, OutputItCells fit); private: Bounded_side side_of_sphere(Vertex_handle v0, Vertex_handle v1, - Vertex_handle v2, Vertex_handle v3, - const Point &p, bool perturb) const; + Vertex_handle v2, Vertex_handle v3, + const Point &p, bool perturb) const; public: // Queries Bounded_side side_of_sphere(Cell_handle c, const Point & p, - bool perturb = false) const + bool perturb = false) const { return side_of_sphere(c->vertex(0), c->vertex(1), c->vertex(2), c->vertex(3), p, perturb); @@ -528,7 +709,7 @@ Bounded_side side_of_circle( Cell_handle c, int i, const Point & p, - bool perturb = false) const; + bool perturb = false) const; Vertex_handle nearest_vertex_in_cell(const Point& p, Cell_handle c) const; @@ -541,7 +722,7 @@ bool is_Gabriel(const Facet& f)const ; bool is_Gabriel(const Edge& e) const; - bool is_delaunay_after_displacement(Vertex_handle v, + bool is_delaunay_after_displacement(Vertex_handle v, const Point &p) const; // Dual functions @@ -558,16 +739,16 @@ bool is_valid(Cell_handle c, bool verbose = false, int level = 0) const; - template < class Stream> + template < class Stream> Stream& draw_dual(Stream & os) { for (Finite_facets_iterator fit = finite_facets_begin(), end = finite_facets_end(); fit != end; ++fit) { - Object o = dual(*fit); - if (const Segment *s = object_cast(&o)) os << *s; - else if (const Ray *r = object_cast(&o)) os << *r; - else if (const Point *p = object_cast(&o)) os << *p; + Object o = dual(*fit); + if (const Segment *s = object_cast(&o)) os << *s; + else if (const Ray *r = object_cast(&o)) os << *r; + else if (const Point *p = object_cast(&o)) os << *p; } return os; } @@ -581,9 +762,9 @@ CGAL_triangulation_precondition(v != w); if (is_infinite(v)) - return w; + return w; if (is_infinite(w)) - return v; + return v; return less_distance(p, w->point(), v->point()) ? w : v; } @@ -644,7 +825,7 @@ void process_cells_in_conflict(InputIterator, InputIterator) const {} void reinsert_vertices(Vertex_handle ) {} Vertex_handle replace_vertex(Cell_handle c, int index, - const Point &) { + const Point &) { return c->vertex(index); } void hide_point(Cell_handle, const Point &) {} @@ -655,13 +836,137 @@ public: Perturbation_order(const Self *tr) - : t(tr) {} + : t(tr) {} bool operator()(const Point *p, const Point *q) const { - return t->compare_xyz(*p, *q) == SMALLER; + return t->compare_xyz(*p, *q) == SMALLER; } }; +#ifdef CGAL_LINKED_WITH_TBB + // Functor for parallel insert(begin, end) function + template + class Insert_point + { + typedef typename DT::Point Point; + typedef typename DT::Vertex_handle Vertex_handle; + + DT & m_dt; + const std::vector & m_points; + tbb::enumerable_thread_specific & m_tls_hint; + + public: + // Constructor + Insert_point(DT & dt, + const std::vector & points, + tbb::enumerable_thread_specific & tls_hint) + : m_dt(dt), m_points(points), m_tls_hint(tls_hint) + {} + + // Constructor + Insert_point(const Insert_point &ip) + : m_dt(ip.m_dt), m_points(ip.m_points), m_tls_hint(ip.m_tls_hint) + {} + + // operator() + void operator()( const tbb::blocked_range& r ) const + { +#ifdef CGAL_CONCURRENT_TRIANGULATION_3_PROFILING + static Profile_branch_counter_3 bcounter( + "early withdrawals / late withdrawals / successes [Delaunay_tri_3::insert]"); +#endif + + Vertex_handle &hint = m_tls_hint.local(); + for( std::size_t i_point = r.begin() ; i_point != r.end() ; ++i_point) + { + bool success = false; + while(!success) + { + if (m_dt.try_lock_vertex(hint) && m_dt.try_lock_point(m_points[i_point])) + { + bool could_lock_zone; + Vertex_handle new_hint = m_dt.insert( + m_points[i_point], hint, &could_lock_zone); + + m_dt.unlock_all_elements(); + + if (could_lock_zone) + { + hint = new_hint; + success = true; +#ifdef CGAL_CONCURRENT_TRIANGULATION_3_PROFILING + ++bcounter; +#endif + } +#ifdef CGAL_CONCURRENT_TRIANGULATION_3_PROFILING + else + { + bcounter.increment_branch_1(); // THIS is a late withdrawal! + } +#endif + } + else + { + m_dt.unlock_all_elements(); + +#ifdef CGAL_CONCURRENT_TRIANGULATION_3_PROFILING + bcounter.increment_branch_2(); // THIS is an early withdrawal! +#endif + } + } + + } + } + }; + + // Functor for parallel remove(begin, end) function + template + class Remove_point + { + typedef typename DT::Point Point; + typedef typename DT::Vertex_handle Vertex_handle; + + DT & m_dt; + const std::vector & m_vertices; + tbb::concurrent_vector & m_vertices_to_remove_sequentially; + + public: + // Constructor + Remove_point(DT & dt, + const std::vector & vertices, + tbb::concurrent_vector & + vertices_to_remove_sequentially) + : m_dt(dt), m_vertices(vertices), + m_vertices_to_remove_sequentially(vertices_to_remove_sequentially) + {} + + // Constructor + Remove_point(const Remove_point &rp) + : m_dt(rp.m_dt), m_vertices(rp.m_vertices), + m_vertices_to_remove_sequentially(rp.m_vertices_to_remove_sequentially) + {} + + // operator() + void operator()( const tbb::blocked_range& r ) const + { + for( size_t i_vertex = r.begin() ; i_vertex != r.end() ; ++i_vertex) + { + Vertex_handle v = m_vertices[i_vertex]; + bool could_lock_zone, needs_to_be_done_sequentially; + do + { + needs_to_be_done_sequentially = + !m_dt.remove(v, &could_lock_zone); + m_dt.unlock_all_elements(); + } while (!could_lock_zone); + + if (needs_to_be_done_sequentially) + m_vertices_to_remove_sequentially.push_back(v); + } + } + }; +#endif // CGAL_LINKED_WITH_TBB + template < class DelaunayTriangulation_3 > class Vertex_remover; @@ -675,35 +980,51 @@ Hidden_point_visitor hidden_point_visitor; }; -template < class Gt, class Tds > -typename Delaunay_triangulation_3::Vertex_handle -Delaunay_triangulation_3:: -insert(const Point & p, Cell_handle start) +template < class Gt, class Tds, class Lds > +typename Delaunay_triangulation_3::Vertex_handle +Delaunay_triangulation_3:: +insert(const Point & p, Cell_handle start, bool *could_lock_zone) { - Locate_type lt; - int li, lj; + Locate_type lt; + int li, lj; + + // Parallel + if (could_lock_zone) + { + Cell_handle c = locate(p, lt, li, lj, start, could_lock_zone); + if (*could_lock_zone) + return insert(p, lt, c, li, lj, could_lock_zone); + else + return Vertex_handle(); + } + // Sequential + else + { Cell_handle c = locate(p, lt, li, lj, start); return insert(p, lt, c, li, lj); + } + } -template < class Gt, class Tds > -typename Delaunay_triangulation_3::Vertex_handle -Delaunay_triangulation_3:: -insert(const Point & p, Locate_type lt, Cell_handle c, int li, int lj) +template < class Gt, class Tds, class Lds > +typename Delaunay_triangulation_3::Vertex_handle +Delaunay_triangulation_3:: +insert(const Point & p, Locate_type lt, Cell_handle c, int li, int lj, + bool *could_lock_zone) { switch (dimension()) { case 3: { Conflict_tester_3 tester(p, this); Vertex_handle v = insert_in_conflict(p, lt, c, li, lj, - tester, hidden_point_visitor); + tester, hidden_point_visitor, could_lock_zone); return v; }// dim 3 case 2: { Conflict_tester_2 tester(p, this); return insert_in_conflict(p, lt, c, li, lj, - tester, hidden_point_visitor); + tester, hidden_point_visitor, could_lock_zone); }//dim 2 default : // dimension <= 1 @@ -712,11 +1033,11 @@ } } -template < class Gt, class Tds > +template < class Gt, class Tds, class Lds > template -typename Delaunay_triangulation_3::Vertex_handle -Delaunay_triangulation_3:: -insert_and_give_new_cells(const Point &p, +typename Delaunay_triangulation_3::Vertex_handle +Delaunay_triangulation_3:: +insert_and_give_new_cells(const Point &p, OutputItCells fit, Cell_handle start) { @@ -730,8 +1051,8 @@ *fit++ = c; int i = c->index(v); c = c->neighbor((i+1)%3); - } while(c != end); - } + } while(c != end); + } else if(dimension == 1) { Cell_handle c = v->cell(); @@ -739,13 +1060,13 @@ *fit++ = c->neighbor((~(c->index(v)))&1); } else *fit++ = v->cell(); // dimension = 0 - return v; + return v; } -template < class Gt, class Tds > +template < class Gt, class Tds, class Lds > template -typename Delaunay_triangulation_3::Vertex_handle -Delaunay_triangulation_3:: +typename Delaunay_triangulation_3::Vertex_handle +Delaunay_triangulation_3:: insert_and_give_new_cells(const Point& p, OutputItCells fit, Vertex_handle hint) @@ -760,8 +1081,8 @@ *fit++ = c; int i = c->index(v); c = c->neighbor((i+1)%3); - } while(c != end); - } + } while(c != end); + } else if(dimension == 1) { Cell_handle c = v->cell(); @@ -772,13 +1093,13 @@ return v; } -template < class Gt, class Tds > +template < class Gt, class Tds, class Lds > template -typename Delaunay_triangulation_3::Vertex_handle -Delaunay_triangulation_3:: +typename Delaunay_triangulation_3::Vertex_handle +Delaunay_triangulation_3:: insert_and_give_new_cells(const Point& p, Locate_type lt, - Cell_handle c, int li, int lj, + Cell_handle c, int li, int lj, OutputItCells fit) { Vertex_handle v = insert(p, lt, c, li, lj); @@ -791,22 +1112,22 @@ *fit++ = c; int i = c->index(v); c = c->neighbor((i+1)%3); - } while(c != end); - } + } while(c != end); + } else if(dimension == 1) { Cell_handle c = v->cell(); *fit++ = c; *fit++ = c->neighbor((~(c->index(v)))&1); } - else *fit++ = v->cell(); // dimension = 0 + else *fit++ = v->cell(); // dimension = 0 return v; } #ifndef CGAL_NO_DEPRECATED_CODE -template < class Gt, class Tds > -typename Delaunay_triangulation_3::Vertex_handle -Delaunay_triangulation_3:: +template < class Gt, class Tds, class Lds > +typename Delaunay_triangulation_3::Vertex_handle +Delaunay_triangulation_3:: move_point(Vertex_handle v, const Point & p) { CGAL_triangulation_precondition(! is_infinite(v)); @@ -823,14 +1144,14 @@ remove(v); if (dimension() <= 0) - return insert(p); + return insert(p); return insert(p, old_neighbor->cell()); } #endif -template +template template -class Delaunay_triangulation_3::Vertex_remover { +class Delaunay_triangulation_3::Vertex_remover { typedef DelaunayTriangulation_3 Delaunay; public: typedef Nullptr_t Hidden_points_iterator; @@ -849,9 +1170,9 @@ } }; -template +template template -class Delaunay_triangulation_3::Vertex_inserter { +class Delaunay_triangulation_3::Vertex_inserter { typedef DelaunayTriangulation_3 Delaunay; public: typedef Nullptr_t Hidden_points_iterator; @@ -865,7 +1186,7 @@ Hidden_points_iterator hidden_points_end() { return NULL; } Vertex_handle insert(const Point& p, - Locate_type lt, Cell_handle c, int li, int lj) { + Locate_type lt, Cell_handle c, int li, int lj) { return tmp.insert(p, lt, c, li, lj); } @@ -878,21 +1199,34 @@ } }; -template < class Gt, class Tds > +template < class Gt, class Tds, class Lds > void -Delaunay_triangulation_3:: +Delaunay_triangulation_3:: remove(Vertex_handle v) { Self tmp; Vertex_remover remover (tmp); - Tr_Base::remove(v,remover); + Tr_Base::remove(v, remover); + + CGAL_triangulation_expensive_postcondition(is_valid()); +} + +template < class Gt, class Tds, class Lds > +bool +Delaunay_triangulation_3:: +remove(Vertex_handle v, bool *could_lock_zone) +{ + Self tmp; + Vertex_remover remover (tmp); + bool ret = Tr_Base::remove(v, remover, could_lock_zone); CGAL_triangulation_expensive_postcondition(is_valid()); + return ret; } -template < class Gt, class Tds > -typename Delaunay_triangulation_3::Vertex_handle -Delaunay_triangulation_3:: +template < class Gt, class Tds, class Lds > +typename Delaunay_triangulation_3::Vertex_handle +Delaunay_triangulation_3:: move_if_no_collision(Vertex_handle v, const Point &p) { Self tmp; @@ -900,26 +1234,26 @@ Vertex_inserter inserter (*this); Vertex_handle res = Tr_Base::move_if_no_collision(v,p,remover,inserter); - CGAL_triangulation_expensive_postcondition(is_valid()); - return res; + CGAL_triangulation_expensive_postcondition(is_valid()); + return res; } -template -typename Delaunay_triangulation_3::Vertex_handle -Delaunay_triangulation_3:: +template +typename Delaunay_triangulation_3::Vertex_handle +Delaunay_triangulation_3:: move(Vertex_handle v, const Point &p) { CGAL_triangulation_precondition(!is_infinite(v)); if(v->point() == p) return v; Self tmp; Vertex_remover remover (tmp); Vertex_inserter inserter (*this); - return Tr_Base::move(v,p,remover,inserter); + return Tr_Base::move(v,p,remover,inserter); } -template < class Gt, class Tds > +template < class Gt, class Tds, class Lds > template void -Delaunay_triangulation_3:: +Delaunay_triangulation_3:: remove_and_give_new_cells(Vertex_handle v, OutputItCells fit) { Self tmp; @@ -929,37 +1263,37 @@ CGAL_triangulation_expensive_postcondition(is_valid()); } -template < class Gt, class Tds > +template < class Gt, class Tds, class Lds > template -typename Delaunay_triangulation_3::Vertex_handle -Delaunay_triangulation_3:: +typename Delaunay_triangulation_3::Vertex_handle +Delaunay_triangulation_3:: move_if_no_collision_and_give_new_cells(Vertex_handle v, const Point &p, OutputItCells fit) { Self tmp; Vertex_remover remover (tmp); Vertex_inserter inserter (*this); - Vertex_handle res = + Vertex_handle res = Tr_Base::move_if_no_collision_and_give_new_cells(v,p, remover,inserter,fit); - CGAL_triangulation_expensive_postcondition(is_valid()); - return res; + CGAL_triangulation_expensive_postcondition(is_valid()); + return res; } -template < class Gt, class Tds > +template < class Gt, class Tds, class Lds > Oriented_side -Delaunay_triangulation_3:: +Delaunay_triangulation_3:: side_of_oriented_sphere(const Point &p0, const Point &p1, const Point &p2, - const Point &p3, const Point &p, bool perturb) const + const Point &p3, const Point &p, bool perturb) const { CGAL_triangulation_precondition( orientation(p0, p1, p2, p3) == POSITIVE ); Oriented_side os = - geom_traits().side_of_oriented_sphere_3_object()(p0, p1, p2, p3, p); + geom_traits().side_of_oriented_sphere_3_object()(p0, p1, p2, p3, p); if (os != ON_ORIENTED_BOUNDARY || !perturb) - return os; + return os; // We are now in a degenerate case => we do a symbolic perturbation. @@ -973,7 +1307,7 @@ for (int i=4; i>2; --i) { if (points[i] == &p) return ON_NEGATIVE_SIDE; // since p0 p1 p2 p3 are non coplanar - // and positively oriented + // and positively oriented Orientation o; if (points[i] == &p3 && (o = orientation(p0,p1,p2,p)) != COPLANAR ) return o; @@ -989,21 +1323,21 @@ return ON_NEGATIVE_SIDE; } -template < class Gt, class Tds > +template < class Gt, class Tds, class Lds > Bounded_side -Delaunay_triangulation_3:: +Delaunay_triangulation_3:: coplanar_side_of_bounded_circle(const Point &p0, const Point &p1, - const Point &p2, const Point &p, bool perturb) const + const Point &p2, const Point &p, bool perturb) const { // In dim==2, we should even be able to assert orient == POSITIVE. CGAL_triangulation_precondition( coplanar_orientation(p0, p1, p2) - != COLLINEAR ); + != COLLINEAR ); Bounded_side bs = geom_traits().coplanar_side_of_bounded_circle_3_object()(p0, p1, p2, p); if (bs != ON_BOUNDARY || !perturb) - return bs; + return bs; // We are now in a degenerate case => we do a symbolic perturbation. @@ -1019,17 +1353,17 @@ for (int i=3; i>0; --i) { if (points[i] == &p) return Bounded_side(NEGATIVE); // since p0 p1 p2 are non collinear - // but not necessarily positively oriented + // but not necessarily positively oriented Orientation o; if (points[i] == &p2 - && (o = coplanar_orientation(p0,p1,p)) != COLLINEAR ) - // [syl] : TODO : I'm not sure of the signs here (nor the rest :) + && (o = coplanar_orientation(p0,p1,p)) != COLLINEAR ) + // [syl] : TODO : I'm not sure of the signs here (nor the rest :) return Bounded_side(o*local); if (points[i] == &p1 - && (o = coplanar_orientation(p0,p,p2)) != COLLINEAR ) + && (o = coplanar_orientation(p0,p,p2)) != COLLINEAR ) return Bounded_side(o*local); if (points[i] == &p0 - && (o = coplanar_orientation(p,p1,p2)) != COLLINEAR ) + && (o = coplanar_orientation(p,p1,p2)) != COLLINEAR ) return Bounded_side(o*local); } @@ -1042,51 +1376,51 @@ return Bounded_side(-local); //ON_UNBOUNDED_SIDE; } -template < class Gt, class Tds > +template < class Gt, class Tds, class Lds > Bounded_side -Delaunay_triangulation_3:: +Delaunay_triangulation_3:: side_of_sphere(Vertex_handle v0, Vertex_handle v1, - Vertex_handle v2, Vertex_handle v3, - const Point &p, bool perturb) const + Vertex_handle v2, Vertex_handle v3, + const Point &p, bool perturb) const { CGAL_triangulation_precondition( dimension() == 3 ); if (is_infinite(v0)) { - Orientation o = orientation(v2->point(), v1->point(), v3->point(), p); - if (o != COPLANAR) - return Bounded_side(o); - return coplanar_side_of_bounded_circle(v2->point(), v1->point(), v3->point(), p, perturb); + Orientation o = orientation(v2->point(), v1->point(), v3->point(), p); + if (o != COPLANAR) + return Bounded_side(o); + return coplanar_side_of_bounded_circle(v2->point(), v1->point(), v3->point(), p, perturb); } if (is_infinite(v1)) { - Orientation o = orientation(v2->point(), v3->point(), v0->point(), p); - if (o != COPLANAR) - return Bounded_side(o); - return coplanar_side_of_bounded_circle(v2->point(), v3->point(), v0->point(), p, perturb); + Orientation o = orientation(v2->point(), v3->point(), v0->point(), p); + if (o != COPLANAR) + return Bounded_side(o); + return coplanar_side_of_bounded_circle(v2->point(), v3->point(), v0->point(), p, perturb); } if (is_infinite(v2)) { - Orientation o = orientation(v1->point(), v0->point(), v3->point(), p); - if (o != COPLANAR) - return Bounded_side(o); - return coplanar_side_of_bounded_circle(v1->point(), v0->point(), v3->point(), p, perturb); + Orientation o = orientation(v1->point(), v0->point(), v3->point(), p); + if (o != COPLANAR) + return Bounded_side(o); + return coplanar_side_of_bounded_circle(v1->point(), v0->point(), v3->point(), p, perturb); } if (is_infinite(v3)) { - Orientation o = orientation(v0->point(), v1->point(), v2->point(), p); - if (o != COPLANAR) - return Bounded_side(o); - return coplanar_side_of_bounded_circle(v0->point(), v1->point(), v2->point(), p, perturb); + Orientation o = orientation(v0->point(), v1->point(), v2->point(), p); + if (o != COPLANAR) + return Bounded_side(o); + return coplanar_side_of_bounded_circle(v0->point(), v1->point(), v2->point(), p, perturb); } return (Bounded_side) side_of_oriented_sphere(v0->point(), v1->point(), v2->point(), v3->point(), p, perturb); } -template < class Gt, class Tds > +template < class Gt, class Tds, class Lds > Bounded_side -Delaunay_triangulation_3:: +Delaunay_triangulation_3:: side_of_circle(Cell_handle c, int i, - const Point & p, bool perturb) const + const Point & p, bool perturb) const // precondition : dimension >=2 // in dimension 3, - for a finite facet // returns ON_BOUNDARY if the point lies on the circle, @@ -1110,27 +1444,27 @@ // with vertices 0 1 2 in this order is positively oriented if ( ! c->has_vertex( infinite_vertex(), i3 ) ) return coplanar_side_of_bounded_circle( c->vertex(0)->point(), - c->vertex(1)->point(), - c->vertex(2)->point(), - p, perturb); + c->vertex(1)->point(), + c->vertex(2)->point(), + p, perturb); // else infinite facet // v1, v2 finite vertices of the facet such that v1,v2,infinite // is positively oriented Vertex_handle v1 = c->vertex( ccw(i3) ), v2 = c->vertex( cw(i3) ); CGAL_triangulation_assertion(coplanar_orientation(v1->point(), v2->point(), - mirror_vertex(c, i3)->point()) == NEGATIVE); + mirror_vertex(c, i3)->point()) == NEGATIVE); Orientation o = coplanar_orientation(v1->point(), v2->point(), p); if ( o != COLLINEAR ) - return Bounded_side( o ); + return Bounded_side( o ); // because p is in f iff // it does not lie on the same side of v1v2 as vn int i_e; Locate_type lt; // case when p collinear with v1v2 return side_of_segment( p, - v1->point(), v2->point(), - lt, i_e ); + v1->point(), v2->point(), + lt, i_e ); } // else dimension == 3 @@ -1143,13 +1477,13 @@ int i1 = (i>1) ? 1 : 2; int i2 = (i>2) ? 2 : 3; CGAL_triangulation_precondition( coplanar( c->vertex(i0)->point(), - c->vertex(i1)->point(), - c->vertex(i2)->point(), - p ) ); + c->vertex(i1)->point(), + c->vertex(i2)->point(), + p ) ); return coplanar_side_of_bounded_circle( c->vertex(i0)->point(), - c->vertex(i1)->point(), - c->vertex(i2)->point(), - p, perturb); + c->vertex(i1)->point(), + c->vertex(i2)->point(), + p, perturb); } //else infinite facet @@ -1159,7 +1493,7 @@ v2 = c->vertex( next_around_edge(i,i3) ); Orientation o = (Orientation) (coplanar_orientation( v1->point(), v2->point(), - c->vertex(i)->point()) * + c->vertex(i)->point()) * coplanar_orientation( v1->point(), v2->point(), p )); // then the code is duplicated from 2d case if ( o != COLLINEAR ) @@ -1170,13 +1504,13 @@ Locate_type lt; // case when p collinear with v1v2 return side_of_segment( p, - v1->point(), v2->point(), - lt, i_e ); + v1->point(), v2->point(), + lt, i_e ); } -template < class Gt, class Tds > -typename Delaunay_triangulation_3::Vertex_handle -Delaunay_triangulation_3:: +template < class Gt, class Tds, class Lds > +typename Delaunay_triangulation_3::Vertex_handle +Delaunay_triangulation_3:: nearest_vertex_in_cell(const Point& p, Cell_handle c) const // Returns the finite vertex of the cell c which is the closest to p. { @@ -1184,36 +1518,36 @@ Vertex_handle nearest = nearest_vertex(p, c->vertex(0), c->vertex(1)); if (dimension() >= 2) { - nearest = nearest_vertex(p, nearest, c->vertex(2)); + nearest = nearest_vertex(p, nearest, c->vertex(2)); if (dimension() == 3) - nearest = nearest_vertex(p, nearest, c->vertex(3)); + nearest = nearest_vertex(p, nearest, c->vertex(3)); } return nearest; } -template < class Gt, class Tds > -typename Delaunay_triangulation_3::Vertex_handle -Delaunay_triangulation_3:: +template < class Gt, class Tds, class Lds > +typename Delaunay_triangulation_3::Vertex_handle +Delaunay_triangulation_3:: nearest_vertex(const Point& p, Cell_handle start) const { if (number_of_vertices() == 0) - return Vertex_handle(); + return Vertex_handle(); // Use a brute-force algorithm if dimension < 3. if (dimension() < 3) { - Finite_vertices_iterator vit = finite_vertices_begin(); - Vertex_handle res = vit; - ++vit; - for (Finite_vertices_iterator end = finite_vertices_end(); vit != end; ++vit) - res = nearest_vertex(p, res, vit); - return res; + Finite_vertices_iterator vit = finite_vertices_begin(); + Vertex_handle res = vit; + ++vit; + for (Finite_vertices_iterator end = finite_vertices_end(); vit != end; ++vit) + res = nearest_vertex(p, res, vit); + return res; } Locate_type lt; int li, lj; Cell_handle c = locate(p, lt, li, lj, start); if (lt == Tr_Base::VERTEX) - return c->vertex(li); + return c->vertex(li); // - start with the closest vertex from the located cell. // - repeatedly take the nearest of its incident vertices if any @@ -1222,36 +1556,36 @@ std::vector vs; vs.reserve(32); while (true) { - Vertex_handle tmp = nearest; + Vertex_handle tmp = nearest; adjacent_vertices(nearest, std::back_inserter(vs)); for (typename std::vector::const_iterator - vsit = vs.begin(); vsit != vs.end(); ++vsit) - tmp = nearest_vertex(p, tmp, *vsit); - if (tmp == nearest) - break; - vs.clear(); - nearest = tmp; + vsit = vs.begin(); vsit != vs.end(); ++vsit) + tmp = nearest_vertex(p, tmp, *vsit); + if (tmp == nearest) + break; + vs.clear(); + nearest = tmp; } return nearest; } // This is not a fast version. -// The optimized version needs an int for book-keeping in +// The optimized version needs an int for book-keeping in // tds() so as to avoiding the need to clear // the tds marker in each cell (which is an unsigned char) // Also the visitor in TDS could be more clever. // The Delaunay triangulation which filters displacements -// will do these optimizations. -template -bool -Delaunay_triangulation_3:: +// will do these optimizations. +template +bool +Delaunay_triangulation_3:: is_delaunay_after_displacement(Vertex_handle v, const Point &p) const { - CGAL_triangulation_precondition(!this->is_infinite(v)); - CGAL_triangulation_precondition(this->dimension() == 2); + CGAL_triangulation_precondition(!this->is_infinite(v)); + CGAL_triangulation_precondition(this->dimension() == 2); CGAL_triangulation_precondition(!this->test_dim_down(v)); - if(v->point() == p) return true; + if(v->point() == p) return true; Point ant = v->point(); v->set_point(p); @@ -1266,18 +1600,18 @@ { Cell_handle c = cells[i]; if(this->is_infinite(c)) continue; - if(this->orientation(c->vertex(0)->point(), c->vertex(1)->point(), - c->vertex(2)->point(), c->vertex(3)->point()) + if(this->orientation(c->vertex(0)->point(), c->vertex(1)->point(), + c->vertex(2)->point(), c->vertex(3)->point()) != POSITIVE) { v->set_point(ant); return false; - } + } } - // are incident bi-cells Delaunay? + // are incident bi-cells Delaunay? std::vector facets; - facets.reserve(128); + facets.reserve(128); this->incident_facets(v, std::back_inserter(facets)); size = facets.size(); for(std::size_t i=0; imirror_index(c, j); Vertex_handle h1 = c->vertex(j); if(this->is_infinite(h1)) { - if(this->side_of_sphere(c, cj->vertex(mj)->point(), true) + if(this->side_of_sphere(c, cj->vertex(mj)->point(), true) != ON_UNBOUNDED_SIDE) { v->set_point(ant); return false; @@ -1301,22 +1635,22 @@ } } } - + v->set_point(ant); return true; } -template < class Gt, class Tds > +template < class Gt, class Tds, class Lds > bool -Delaunay_triangulation_3:: +Delaunay_triangulation_3:: is_Gabriel(const Facet& f) const { return is_Gabriel(f.first, f.second); } -template < class Gt, class Tds > +template < class Gt, class Tds, class Lds > bool -Delaunay_triangulation_3:: +Delaunay_triangulation_3:: is_Gabriel(Cell_handle c, int i) const { CGAL_triangulation_precondition(dimension() == 3 && !is_infinite(c,i)); @@ -1326,34 +1660,34 @@ if ((!is_infinite(c->vertex(i))) && side_of_bounded_sphere ( - c->vertex(vertex_triple_index(i,0))->point(), - c->vertex(vertex_triple_index(i,1))->point(), - c->vertex(vertex_triple_index(i,2))->point(), - c->vertex(i)->point()) == ON_BOUNDED_SIDE ) return false; + c->vertex(vertex_triple_index(i,0))->point(), + c->vertex(vertex_triple_index(i,1))->point(), + c->vertex(vertex_triple_index(i,2))->point(), + c->vertex(i)->point()) == ON_BOUNDED_SIDE ) return false; Cell_handle neighbor = c->neighbor(i); int in = neighbor->index(c); if ((!is_infinite(neighbor->vertex(in))) && side_of_bounded_sphere( - c->vertex(vertex_triple_index(i,0))->point(), - c->vertex(vertex_triple_index(i,1))->point(), - c->vertex(vertex_triple_index(i,2))->point(), - neighbor->vertex(in)->point()) == ON_BOUNDED_SIDE ) return false; + c->vertex(vertex_triple_index(i,0))->point(), + c->vertex(vertex_triple_index(i,1))->point(), + c->vertex(vertex_triple_index(i,2))->point(), + neighbor->vertex(in)->point()) == ON_BOUNDED_SIDE ) return false; return true; } -template < class Gt, class Tds > +template < class Gt, class Tds, class Lds > bool -Delaunay_triangulation_3:: +Delaunay_triangulation_3:: is_Gabriel(const Edge& e) const { return is_Gabriel(e.first, e.second, e.third); } -template < class Gt, class Tds > +template < class Gt, class Tds, class Lds > bool -Delaunay_triangulation_3:: +Delaunay_triangulation_3:: is_Gabriel(Cell_handle c, int i, int j) const { CGAL_triangulation_precondition(dimension() == 3 && !is_infinite(c,i,j)); @@ -1371,17 +1705,17 @@ Cell_handle cc = (*fcirc).first; int ii = (*fcirc).second; if (!is_infinite(cc->vertex(ii)) && - side_of_bounded_sphere( v1->point(), - v2->point(), - cc->vertex(ii)->point()) - == ON_BOUNDED_SIDE ) return false; + side_of_bounded_sphere( v1->point(), + v2->point(), + cc->vertex(ii)->point()) + == ON_BOUNDED_SIDE ) return false; } while(++fcirc != fdone); return true; } -template < class Gt, class Tds > -typename Delaunay_triangulation_3::Point -Delaunay_triangulation_3:: +template < class Gt, class Tds, class Lds > +typename Delaunay_triangulation_3::Point +Delaunay_triangulation_3:: dual(Cell_handle c) const { CGAL_triangulation_precondition(dimension()==3); @@ -1390,9 +1724,9 @@ } -template < class Gt, class Tds > -typename Delaunay_triangulation_3::Object -Delaunay_triangulation_3:: +template < class Gt, class Tds, class Lds > +typename Delaunay_triangulation_3::Object +Delaunay_triangulation_3:: dual(Cell_handle c, int i) const { CGAL_triangulation_precondition(dimension()>=2); @@ -1401,8 +1735,8 @@ if ( dimension() == 2 ) { CGAL_triangulation_precondition( i == 3 ); return construct_object( construct_circumcenter(c->vertex(0)->point(), - c->vertex(1)->point(), - c->vertex(2)->point()) ); + c->vertex(1)->point(), + c->vertex(2)->point()) ); } // dimension() == 3 @@ -1436,9 +1770,9 @@ -template < class Gt, class Tds > -typename Delaunay_triangulation_3::Line -Delaunay_triangulation_3:: +template < class Gt, class Tds, class Lds > +typename Delaunay_triangulation_3::Line +Delaunay_triangulation_3:: dual_support(Cell_handle c, int i) const { CGAL_triangulation_precondition(dimension()>=2); @@ -1447,31 +1781,31 @@ if ( dimension() == 2 ) { CGAL_triangulation_precondition( i == 3 ); return construct_equidistant_line( c->vertex(0)->point(), - c->vertex(1)->point(), - c->vertex(2)->point() ); + c->vertex(1)->point(), + c->vertex(2)->point() ); } return construct_equidistant_line( c->vertex((i+1)&3)->point(), - c->vertex((i+2)&3)->point(), - c->vertex((i+3)&3)->point() ); + c->vertex((i+2)&3)->point(), + c->vertex((i+3)&3)->point() ); } -template < class Gt, class Tds > +template < class Gt, class Tds, class Lds > bool -Delaunay_triangulation_3:: +Delaunay_triangulation_3:: is_valid(bool verbose, int level) const { if ( ! tds().is_valid(verbose,level) ) { if (verbose) - std::cerr << "invalid data structure" << std::endl; + std::cerr << "invalid data structure" << std::endl; CGAL_triangulation_assertion(false); return false; } if ( infinite_vertex() == Vertex_handle() ) { if (verbose) - std::cerr << "no infinite vertex" << std::endl; + std::cerr << "no infinite vertex" << std::endl; CGAL_triangulation_assertion(false); return false; } @@ -1480,51 +1814,51 @@ case 3: { for(Finite_cells_iterator it = finite_cells_begin(), end = finite_cells_end(); it != end; ++it) { - is_valid_finite(it); - for(int i=0; i<4; i++ ) { - if ( !is_infinite - (it->neighbor(i)->vertex(it->neighbor(i)->index(it))) ) { - if ( side_of_sphere - (it, - it->neighbor(i)->vertex(it->neighbor(i)->index(it))->point()) - == ON_BOUNDED_SIDE ) { - if (verbose) - std::cerr << "non-empty sphere " << std::endl; - CGAL_triangulation_assertion(false); - return false; - } - } - } + is_valid_finite(it); + for(int i=0; i<4; i++ ) { + if ( !is_infinite + (it->neighbor(i)->vertex(it->neighbor(i)->index(it))) ) { + if ( side_of_sphere + (it, + it->neighbor(i)->vertex(it->neighbor(i)->index(it))->point()) + == ON_BOUNDED_SIDE ) { + if (verbose) + std::cerr << "non-empty sphere " << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + } + } } break; } case 2: { for(Finite_facets_iterator it = finite_facets_begin(), end = finite_facets_end(); it != end; ++it) { - is_valid_finite((*it).first); - for(int i=0; i<3; i++ ) { - if( !is_infinite - ((*it).first->neighbor(i)->vertex( (((*it).first)->neighbor(i)) - ->index((*it).first))) ) { - if ( side_of_circle ( (*it).first, 3, - (*it).first->neighbor(i)-> - vertex( (((*it).first)->neighbor(i)) - ->index((*it).first) )->point() ) - == ON_BOUNDED_SIDE ) { - if (verbose) - std::cerr << "non-empty circle " << std::endl; - CGAL_triangulation_assertion(false); - return false; - } - } - } + is_valid_finite((*it).first); + for(int i=0; i<3; i++ ) { + if( !is_infinite + ((*it).first->neighbor(i)->vertex( (((*it).first)->neighbor(i)) + ->index((*it).first))) ) { + if ( side_of_circle ( (*it).first, 3, + (*it).first->neighbor(i)-> + vertex( (((*it).first)->neighbor(i)) + ->index((*it).first) )->point() ) + == ON_BOUNDED_SIDE ) { + if (verbose) + std::cerr << "non-empty circle " << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + } + } } break; } case 1: { for(Finite_edges_iterator it = finite_edges_begin(), end = finite_edges_end(); it != end; ++it) - is_valid_finite((*it).first); + is_valid_finite((*it).first); break; } } @@ -1533,16 +1867,16 @@ return true; } -template < class Gt, class Tds > +template < class Gt, class Tds, class Lds > bool -Delaunay_triangulation_3:: +Delaunay_triangulation_3:: is_valid(Cell_handle c, bool verbose, int level) const { if ( ! Tr_Base::is_valid(c,verbose,level) ) { if (verbose) { std::cerr << "combinatorically invalid cell" ; for (int i=0; i <= dimension(); i++ ) - std::cerr << c->vertex(i)->point() << ", " ; + std::cerr << c->vertex(i)->point() << ", " ; std::cerr << std::endl; } CGAL_triangulation_assertion(false); @@ -1552,31 +1886,31 @@ case 3: { if ( ! is_infinite(c) ) { - is_valid_finite(c,verbose,level); - for (int i=0; i<4; i++ ) { - if (side_of_sphere(c, c->vertex((c->neighbor(i))->index(c))->point()) - == ON_BOUNDED_SIDE ) { - if (verbose) - std::cerr << "non-empty sphere " << std::endl; - CGAL_triangulation_assertion(false); - return false; - } - } + is_valid_finite(c,verbose,level); + for (int i=0; i<4; i++ ) { + if (side_of_sphere(c, c->vertex((c->neighbor(i))->index(c))->point()) + == ON_BOUNDED_SIDE ) { + if (verbose) + std::cerr << "non-empty sphere " << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + } } break; } case 2: { if ( ! is_infinite(c,3) ) { - for (int i=0; i<2; i++ ) { - if (side_of_circle(c, 3, c->vertex(c->neighbor(i)->index(c))->point()) - == ON_BOUNDED_SIDE ) { - if (verbose) - std::cerr << "non-empty circle " << std::endl; - CGAL_triangulation_assertion(false); - return false; - } - } + for (int i=0; i<2; i++ ) { + if (side_of_circle(c, 3, c->vertex(c->neighbor(i)->index(c))->point()) + == ON_BOUNDED_SIDE ) { + if (verbose) + std::cerr << "non-empty circle " << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + } } break; } diff -Nru cgal-4.4/include/CGAL/Delaunay_triangulation_cell_base_3.h cgal-4.5/include/CGAL/Delaunay_triangulation_cell_base_3.h --- cgal-4.4/include/CGAL/Delaunay_triangulation_cell_base_3.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/Delaunay_triangulation_cell_base_3.h 2014-10-06 19:00:05.000000000 +0000 @@ -0,0 +1,55 @@ +// Copyright (c) 2014 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Monique Teillaud +// Sylvain Pion +// Jane Tournois + +// cell of a Delaunay triangulation of any dimension <=3 + +#ifndef CGAL_DELAUNAY_TRIANGULATION_CELL_BASE_3_H +#define CGAL_DELAUNAY_TRIANGULATION_CELL_BASE_3_H + +#include +#include +#include +#include + +namespace CGAL { + +template < typename GT, typename Cb = Triangulation_ds_cell_base_3<> > +class Delaunay_triangulation_cell_base_3 + : public Triangulation_cell_base_3 +{ +public: + typedef GT Geom_traits; + typedef typename Geom_traits::Point_3 Point_3; + + Point_3 + circumcenter(const Geom_traits& gt = Geom_traits()) const + { + return gt.construct_circumcenter_3_object()(this->vertex(0)->point(), + this->vertex(1)->point(), + this->vertex(2)->point(), + this->vertex(3)->point()); + } + +}; + +} //namespace CGAL + +#endif // CGAL_DELAUNAY_TRIANGULATION_CELL_BASE_3_H diff -Nru cgal-4.4/include/CGAL/Delaunay_triangulation_cell_base_with_circumcenter_3.h cgal-4.5/include/CGAL/Delaunay_triangulation_cell_base_with_circumcenter_3.h --- cgal-4.4/include/CGAL/Delaunay_triangulation_cell_base_with_circumcenter_3.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/Delaunay_triangulation_cell_base_with_circumcenter_3.h 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,134 @@ +// Copyright (c) 1999-2006 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Monique Teillaud +// Sylvain Pion + +// cell of a triangulation of any dimension <=3, +// storing its circumcenter lazily. + +#ifndef CGAL_DELAUNAY_TRIANGULATION_CELL_BASE_WITH_CIRCUMCENTER_3_H +#define CGAL_DELAUNAY_TRIANGULATION_CELL_BASE_WITH_CIRCUMCENTER_3_H + + +#include +#include +#include + +namespace CGAL { + +template < typename GT, typename Cb = Triangulation_cell_base_3 > +class Delaunay_triangulation_cell_base_with_circumcenter_3 + : public Cb +{ + typedef typename GT::Point_3 Point_3; + + mutable Point_3 * circumcenter_; + +public: + void invalidate_circumcenter() + { + if (circumcenter_) { + delete circumcenter_; + circumcenter_ = NULL; + } + } + +public: + typedef typename Cb::Vertex_handle Vertex_handle; + typedef typename Cb::Cell_handle Cell_handle; + + typedef GT Geom_traits; + + template < typename TDS2 > + struct Rebind_TDS { + typedef typename Cb::template Rebind_TDS::Other Cb2; + typedef Delaunay_triangulation_cell_base_with_circumcenter_3 Other; + }; + + Delaunay_triangulation_cell_base_with_circumcenter_3() + : Cb(), circumcenter_(NULL) {} + + Delaunay_triangulation_cell_base_with_circumcenter_3 + (const Delaunay_triangulation_cell_base_with_circumcenter_3 &c) + : Cb(c), circumcenter_(c.circumcenter_ != NULL ? new Point_3(*(c.circumcenter_)) : NULL) + {} + + Delaunay_triangulation_cell_base_with_circumcenter_3& + operator=(const Delaunay_triangulation_cell_base_with_circumcenter_3 &c) + { + Delaunay_triangulation_cell_base_with_circumcenter_3 tmp=c; + std::swap(tmp, *this); + return *this; + } + + Delaunay_triangulation_cell_base_with_circumcenter_3( + Vertex_handle v0, Vertex_handle v1, + Vertex_handle v2, Vertex_handle v3) + : Cb(v0, v1, v2, v3), circumcenter_(NULL) {} + + Delaunay_triangulation_cell_base_with_circumcenter_3( + Vertex_handle v0, Vertex_handle v1, + Vertex_handle v2, Vertex_handle v3, + Cell_handle n0, Cell_handle n1, + Cell_handle n2, Cell_handle n3) + : Cb(v0, v1, v2, v3, n0, n1, n2, n3), circumcenter_(NULL) {} + + ~Delaunay_triangulation_cell_base_with_circumcenter_3() + { + delete circumcenter_; + } + + // We must override the functions that modify the vertices. + // And if the point inside a vertex is modified, we fail, + // but there's not much we can do for this now. + void set_vertex(int i, Vertex_handle v) + { + invalidate_circumcenter(); + Cb::set_vertex(i, v); + } + + void set_vertices() + { + invalidate_circumcenter(); + Cb::set_vertices(); + } + + void set_vertices(Vertex_handle v0, Vertex_handle v1, + Vertex_handle v2, Vertex_handle v3) + { + invalidate_circumcenter(); + Cb::set_vertices(v0, v1, v2, v3); + } + + const Point_3 & + circumcenter(const Geom_traits& gt = Geom_traits()) const + { + if (circumcenter_ == NULL) { + circumcenter_ = new Point_3(this->Cb::circumcenter(gt)); + } else { + CGAL_expensive_assertion( + this->Cb::circumcenter(gt) == *circumcenter); + } + + return *circumcenter_; + } +}; + +} //namespace CGAL + +#endif // CGAL_DELAUNAY_TRIANGULATION_CELL_BASE_WITH_CIRCUMCENTER_3_H diff -Nru cgal-4.4/include/CGAL/determinant_of_vectors.h cgal-4.5/include/CGAL/determinant_of_vectors.h --- cgal-4.4/include/CGAL/determinant_of_vectors.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/determinant_of_vectors.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,117 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_DETVEC_H +#define CGAL_DETVEC_H +#include +#include + +namespace CGAL { + // TODO: determine whether it is better to pass them by lines or columns. + + template inline + NT determinant_of_vectors(Vector const&a, Vector const&b){ + return determinant(a[0],a[1],b[0],b[1]); + } + template inline + typename Sgn::result_type + sign_of_determinant_of_vectors(Vector const&a, Vector const&b){ + return sign_of_determinant(a[0],a[1],b[0],b[1]); + } + + template + NT determinant_of_vectors(Vector const&a, Vector const&b, + Vector const&c){ + return determinant(a[0],a[1],a[2],b[0],b[1],b[2],c[0],c[1],c[2]); + } + template + typename Sgn::result_type + sign_of_determinant_of_vectors(Vector const&a, Vector const&b, + Vector const&c){ + return sign_of_determinant(a[0],a[1],a[2],b[0],b[1],b[2],c[0],c[1],c[2]); + } + + template + NT determinant_of_vectors(Vector const&a, Vector const&b, + Vector const&c, Vector const&d){ + return determinant( + a[0],a[1],a[2],a[3], + b[0],b[1],b[2],b[3], + c[0],c[1],c[2],c[3], + d[0],d[1],d[2],d[3]); + } + template + typename Sgn::result_type + sign_of_determinant_of_vectors(Vector const&a, Vector const&b, + Vector const&c, Vector const&d){ + return sign_of_determinant( + a[0],a[1],a[2],a[3], + b[0],b[1],b[2],b[3], + c[0],c[1],c[2],c[3], + d[0],d[1],d[2],d[3]); + } + + template + NT determinant_of_vectors(Vector const&a, Vector const&b, + Vector const&c, Vector const&d, Vector const&e){ + return determinant( + a[0],a[1],a[2],a[3],a[4], + b[0],b[1],b[2],b[3],b[4], + c[0],c[1],c[2],c[3],c[4], + d[0],d[1],d[2],d[3],d[4], + e[0],e[1],e[2],e[3],e[4]); + } + template + typename Sgn::result_type + sign_of_determinant_of_vectors(Vector const&a, Vector const&b, + Vector const&c, Vector const&d, Vector const&e){ + return sign_of_determinant( + a[0],a[1],a[2],a[3],a[4], + b[0],b[1],b[2],b[3],b[4], + c[0],c[1],c[2],c[3],c[4], + d[0],d[1],d[2],d[3],d[4], + e[0],e[1],e[2],e[3],e[4]); + } + + template + NT determinant_of_vectors(Vector const&a, Vector const&b, + Vector const&c, Vector const&d, Vector const&e, Vector const&f){ + return determinant( + a[0],a[1],a[2],a[3],a[4],a[5], + b[0],b[1],b[2],b[3],b[4],b[5], + c[0],c[1],c[2],c[3],c[4],c[5], + d[0],d[1],d[2],d[3],d[4],d[5], + e[0],e[1],e[2],e[3],e[4],e[5], + f[0],f[1],f[2],f[3],f[4],f[5]); + } + template + typename Sgn::result_type + sign_of_determinant_of_vectors(Vector const&a, Vector const&b, + Vector const&c, Vector const&d, Vector const&e, Vector const&f){ + return sign_of_determinant( + a[0],a[1],a[2],a[3],a[4],a[5], + b[0],b[1],b[2],b[3],b[4],b[5], + c[0],c[1],c[2],c[3],c[4],c[5], + d[0],d[1],d[2],d[3],d[4],d[5], + e[0],e[1],e[2],e[3],e[4],e[5], + f[0],f[1],f[2],f[3],f[4],f[5]); + } + +} +#endif diff -Nru cgal-4.4/include/CGAL/Dimension.h cgal-4.5/include/CGAL/Dimension.h --- cgal-4.4/include/CGAL/Dimension.h 2012-11-13 13:13:56.000000000 +0000 +++ cgal-4.5/include/CGAL/Dimension.h 2014-08-29 13:58:16.000000000 +0000 @@ -23,9 +23,27 @@ #include #include #include +#include +#ifdef CGAL_EIGEN3_ENABLED +#include +#endif namespace CGAL { +#ifdef CGAL_EIGEN3_ENABLED +const int UNKNOWN_DIMENSION=Eigen::Dynamic; +#elif defined CGAL_CXX11 +const int UNKNOWN_DIMENSION=std::numeric_limits::max(); +#else +const int UNKNOWN_DIMENSION=(unsigned)-1/2; +#endif + +// Check that dimension d1 is fine for a kernel of dimension d2. +// If d2 is unknown, any d1 is fine. +inline bool check_dimension_eq(int d1, int d2){ + return d2==UNKNOWN_DIMENSION || d1==d2; +} + // These tag classes help dispatching functions based on a geometric dimension. template < int dim > @@ -69,6 +87,39 @@ typedef typename K::template Feature_dimension::type type; }; +// Change the dimension +templatestruct Increment_dimension { + typedef Dynamic_dimension_tag type; +}; +templatestruct Increment_dimension,i> { + typedef Dimension_tag type; +}; + +templatestruct Product_dimension { + typedef Dynamic_dimension_tag type; +}; +templatestruct Product_dimension,Dimension_tag > { + typedef Dimension_tag type; +}; + +#ifdef CGAL_EIGEN3_ENABLED +// Convert to Eigen's notion of dimension +template struct Eigen_dimension { + enum { value=Eigen::Dynamic }; +}; +template struct Eigen_dimension > { + enum { value=d }; +}; + +// and convert back +template struct Dimension_eigen { + typedef Dimension_tag type; +}; +template <> struct Dimension_eigen { + typedef Dynamic_dimension_tag type; +}; +#endif + } //namespace CGAL #endif // CGAL_DIMENSION_H diff -Nru cgal-4.4/include/CGAL/Eigen_matrix.h cgal-4.5/include/CGAL/Eigen_matrix.h --- cgal-4.4/include/CGAL/Eigen_matrix.h 2013-07-20 19:00:36.000000000 +0000 +++ cgal-4.5/include/CGAL/Eigen_matrix.h 2014-08-29 13:58:17.000000000 +0000 @@ -44,13 +44,25 @@ // Public types public: - typedef Eigen::SparseMatrix EigenType; + typedef Eigen::SparseMatrix EigenType; typedef T NT; // Public operations public: /// Create a square matrix initialized with zeros. + Eigen_sparse_matrix(std::size_t dim, ///< Matrix dimension. + bool is_symmetric = false) ///< Symmetric/hermitian? + : m_is_already_built(false), m_matrix(static_cast(dim),static_cast(dim)) + { + CGAL_precondition(dim > 0); + + m_is_symmetric = is_symmetric; + // reserve memory for a regular 3D grid + m_triplets.reserve(dim); + } + + /// Create a square matrix initialized with zeros. Eigen_sparse_matrix(int dim, ///< Matrix dimension. bool is_symmetric = false) ///< Symmetric/hermitian? : m_is_already_built(false), m_matrix(dim,dim) @@ -65,10 +77,10 @@ /// Create a rectangular matrix initialized with zeros. /// /// @commentheading Precondition: rows == columns if is_symmetric is true. - Eigen_sparse_matrix(int rows, ///< Number of rows. - int columns, ///< Number of columns. + Eigen_sparse_matrix(std::size_t rows, ///< Number of rows. + std::size_t columns, ///< Number of columns. bool is_symmetric = false) ///< Symmetric/hermitian? - : m_is_already_built(false), m_matrix(rows,columns) + : m_is_already_built(false), m_matrix(static_cast(rows),static_cast(columns)) { CGAL_precondition(rows > 0); CGAL_precondition(columns > 0); @@ -81,11 +93,30 @@ m_triplets.reserve(rows); } - /// Delete this object and the wrapped TAUCS matrix. + /// Delete this object and the wrapped matrix. ~Eigen_sparse_matrix() { } + /// Create a rectangular matrix initialized with zeros. + /// + /// @commentheading Precondition: rows == columns if is_symmetric is true. + Eigen_sparse_matrix(int rows, ///< Number of rows. + int columns, ///< Number of columns. + bool is_symmetric = false) ///< Symmetric/hermitian? + : m_is_already_built(false), m_matrix(rows,columns) + { + CGAL_precondition(rows > 0); + CGAL_precondition(columns > 0); + if (is_symmetric) { + CGAL_precondition(rows == columns); + } + + m_is_symmetric = is_symmetric; + // reserve memory for a regular 3D grid + m_triplets.reserve(rows); + } + /// Return the matrix number of rows int row_dimension() const { return m_matrix.rows(); } /// Return the matrix number of columns @@ -103,8 +134,10 @@ /// @commentheading Preconditions: /// - 0 <= i < row_dimension(). /// - 0 <= j < column_dimension(). - void set_coef(int i, int j, T val, bool new_coef = false) + void set_coef(std::size_t i_, std::size_t j_, T val, bool new_coef = false) { + int i = static_cast(i_); + int j = static_cast(j_); CGAL_precondition(i < row_dimension()); CGAL_precondition(j < column_dimension()); diff -Nru cgal-4.4/include/CGAL/Eigen_solver_traits.h cgal-4.5/include/CGAL/Eigen_solver_traits.h --- cgal-4.4/include/CGAL/Eigen_solver_traits.h 2012-11-13 13:14:00.000000000 +0000 +++ cgal-4.5/include/CGAL/Eigen_solver_traits.h 2014-08-29 13:58:17.000000000 +0000 @@ -19,9 +19,22 @@ #ifndef CGAL_EIGEN_SOLVER_TRAITS_H #define CGAL_EIGEN_SOLVER_TRAITS_H -#include // include basic.h before testing #defines - +#include // include basic.h before testing #defines +#if defined(BOOST_MSVC) +# pragma warning(push) +# pragma warning(disable:4244) +#endif #include +#if EIGEN_VERSION_AT_LEAST(3, 1, 91) + +#include +#endif + + +#if defined(BOOST_MSVC) +# pragma warning(pop) +#endif + #include #include #include @@ -44,6 +57,12 @@ struct Get_eigen_matrix< ::Eigen::SimplicialCholesky,FT>{ typedef Eigen_sparse_symmetric_matrix type; }; +#if EIGEN_VERSION_AT_LEAST(3, 1, 91) + template + struct Get_eigen_matrix< ::Eigen::SparseLU, FT> { + typedef Eigen_sparse_matrix type; + }; +#endif } //internal /// The class Eigen_solver_traits @@ -52,7 +71,7 @@ /// The default solver is the iterative bi-congugate gradient stabilized solver /// Eigen::BiCGSTAB for double. /// -/// @heading Is Model for the Concepts: Model of the SparseLinearAlgebraTraits_d concept. +/// \cgalModels `SparseLinearAlgebraTraitsWithFactor_d`. template::EigenType> > class Eigen_solver_traits @@ -68,7 +87,7 @@ // Public operations public: - Eigen_solver_traits(): m_solver_sptr(new EigenSolverT) + Eigen_solver_traits():m_mat(NULL), m_solver_sptr(new EigenSolverT) { } @@ -93,7 +112,24 @@ return m_solver_sptr->info() == Eigen::Success; } + + bool factor (const Matrix& A, NT& D) + { + D = 1; + + m_mat = &A.eigen_object(); + solver().compute(*m_mat); + return solver().info() == Eigen::Success; + } + + bool linear_solver(const Vector& B, Vector& X) + { + CGAL_precondition(m_mat!=NULL); //factor should have been called first + X = solver().solve(B); + return solver().info() == Eigen::Success; + } protected: + const typename Matrix::EigenType* m_mat; boost::shared_ptr m_solver_sptr; }; diff -Nru cgal-4.4/include/CGAL/Eigen_vector.h cgal-4.5/include/CGAL/Eigen_vector.h --- cgal-4.4/include/CGAL/Eigen_vector.h 2012-11-13 13:14:00.000000000 +0000 +++ cgal-4.5/include/CGAL/Eigen_vector.h 2014-08-29 13:58:17.000000000 +0000 @@ -54,8 +54,8 @@ } /// Create a vector initialized with zeros. - Eigen_vector(int dimension) - : EigenType(dimension) + Eigen_vector(std::size_t dimension) + : EigenType(static_cast(dimension)) { this->setZero(); } @@ -75,7 +75,7 @@ return this->size(); } - /// Get TAUCS vector wrapped by this object. + /// Get vector wrapped by this object. const EigenType& eigen_object() const { return *this; } @@ -83,8 +83,8 @@ return *this; } - void set(int i,NT value) { - this->operator[](i)=value; + void set(std::size_t i,NT value) { + this->operator[](static_cast(i))=value; } NT* vector() {return this->data();} diff -Nru cgal-4.4/include/CGAL/Envelope_3/Envelope_divide_and_conquer_3.h cgal-4.5/include/CGAL/Envelope_3/Envelope_divide_and_conquer_3.h --- cgal-4.4/include/CGAL/Envelope_3/Envelope_divide_and_conquer_3.h 2013-03-07 20:00:26.000000000 +0000 +++ cgal-4.5/include/CGAL/Envelope_3/Envelope_divide_and_conquer_3.h 2014-08-29 13:58:16.000000000 +0000 @@ -43,8 +43,7 @@ #ifdef CGAL_ENVELOPE_USE_BFS_FACE_ORDER #include #include -#include // Needed because BGL forgot it. -#include +#include #endif // this base divide & conquer algorithm splits the input into 2 groups, diff -Nru cgal-4.4/include/CGAL/Epick_d.h cgal-4.5/include/CGAL/Epick_d.h --- cgal-4.4/include/CGAL/Epick_d.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/Epick_d.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,70 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_EPICK_D_H +#define CGAL_EPICK_D_H +#include +#include +#include +#include +#include +#include +#include + + +namespace CGAL { +#define CGAL_BASE \ + Cartesian_filter_K< \ + Cartesian_base_d, \ + Cartesian_base_d, \ + Cartesian_base_d::Type, Dim> \ + > +template +struct Epick_d_help1 +: CGAL_BASE +{ + CGAL_CONSTEXPR Epick_d_help1(){} + CGAL_CONSTEXPR Epick_d_help1(int d):CGAL_BASE(d){} +}; +#undef CGAL_BASE +#define CGAL_BASE \ + Cartesian_static_filters,Epick_d_help2 > +template +struct Epick_d_help2 +: CGAL_BASE +{ + CGAL_CONSTEXPR Epick_d_help2(){} + CGAL_CONSTEXPR Epick_d_help2(int d):CGAL_BASE(d){} +}; +#undef CGAL_BASE +#define CGAL_BASE \ + Kernel_d_interface< \ + Cartesian_wrap< \ + Epick_d_help2, \ + Epick_d > > +template +struct Epick_d +: CGAL_BASE +{ + CGAL_CONSTEXPR Epick_d(){} + CGAL_CONSTEXPR Epick_d(int d):CGAL_BASE(d){} +}; +#undef CGAL_BASE +} +#endif diff -Nru cgal-4.4/include/CGAL/Exact_integer.h cgal-4.5/include/CGAL/Exact_integer.h --- cgal-4.4/include/CGAL/Exact_integer.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/Exact_integer.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,72 @@ +// Copyright (c) 2014 +// 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); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Laurent Rineau + +#include +#if CGAL_USE_GMP +# include +#elif CGAL_USE_LEDA +# include +#elif CGAL_USE_CORE +# include +#else +# error CGAL is configured with none of GMP, LEDA and CORE. cannot be used. +#endif + +namespace CGAL { + +/*! +\ingroup nt_cgal + +`Exact_integer` is an exact integer number type. + +It is a typedef of another number type. Its exact definition depends on +the availability the third-party libraries %GMP, %CORE, and %LEDA. %CGAL must +be configured with at least one of those libraries. + +\cgalModels `EuclideanRing` +\cgalModels `RealEmbeddable` + +*/ +#if DOXYGEN_RUNNING + +typedef unspecified_type Exact_integer; + +#else // not DOXYGEN_RUNNING + +#if CGAL_USE_GMP + +typedef Gmpz Exact_integer; + +#elif CGAL_USE_LEDA + +typedef leda_integer Exact_integer; + +#elif CGAL_USE_CORE + +typedef CORE::BigInt Exact_integer; + +#endif // CGAL_USE_CORE +#endif // not DOXYGEN_RUNNING + +} /* end namespace CGAL */ diff -Nru cgal-4.4/include/CGAL/Exact_predicates_exact_constructions_kernel.h cgal-4.5/include/CGAL/Exact_predicates_exact_constructions_kernel.h --- cgal-4.4/include/CGAL/Exact_predicates_exact_constructions_kernel.h 2013-06-15 19:00:25.000000000 +0000 +++ cgal-4.5/include/CGAL/Exact_predicates_exact_constructions_kernel.h 2014-08-29 13:58:16.000000000 +0000 @@ -37,7 +37,7 @@ namespace CGAL { -// Epeck_ft is either Gmpq or Quotient +// Epeck_ft is either Gmpq, or leda_rational, or Quotient typedef internal::Exact_field_selector::Type Epeck_ft; // The following are redefined kernels instead of simple typedefs in order to shorten diff -Nru cgal-4.4/include/CGAL/Exact_rational.h cgal-4.5/include/CGAL/Exact_rational.h --- cgal-4.4/include/CGAL/Exact_rational.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/Exact_rational.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,54 @@ +// Copyright (c) 2014 +// 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); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Laurent Rineau + +#include + +namespace CGAL { + +/*! +\ingroup nt_cgal + +`Exact_rational` is an exact rational number type, constructible from `double`. + +It is a typedef of another number type. Its exact definition depends on +the availability the third-party libraries %GMP, %CORE, and %LEDA. %CGAL must +be configured with at least one of those libraries. + +\cgalModels `Field` +\cgalModels `RealEmbeddable` +\cgalModels `Fraction` +\cgalModels `FromDoubleConstructible` + +*/ +#if DOXYGEN_RUNNING + +typedef unspecified_type Exact_rational; + +#else // not DOXYGEN_RUNNING + +typedef internal::Exact_field_selector::Type Exact_rational; + +#endif + +} /* end namespace CGAL */ diff -Nru cgal-4.4/include/CGAL/exude_mesh_3.h cgal-4.5/include/CGAL/exude_mesh_3.h --- cgal-4.4/include/CGAL/exude_mesh_3.h 2013-12-21 20:00:22.000000000 +0000 +++ cgal-4.5/include/CGAL/exude_mesh_3.h 2014-08-29 13:58:16.000000000 +0000 @@ -50,7 +50,7 @@ -template +template Mesh_optimization_return_code exude_mesh_3_impl(C3T3& c3t3, const double time_limit, diff -Nru cgal-4.4/include/CGAL/Fixed_border_parameterizer_3.h cgal-4.5/include/CGAL/Fixed_border_parameterizer_3.h --- cgal-4.4/include/CGAL/Fixed_border_parameterizer_3.h 2012-12-08 20:00:21.000000000 +0000 +++ cgal-4.5/include/CGAL/Fixed_border_parameterizer_3.h 2014-08-29 13:58:17.000000000 +0000 @@ -574,7 +574,7 @@ const Vector& , const Vector& ) { - Vector_3 first_triangle_normal; + Vector_3 first_triangle_normal = NULL_VECTOR; // initialize to avoid warning for (Facet_const_iterator facetIt = mesh.mesh_facets_begin(); facetIt != mesh.mesh_facets_end(); diff -Nru cgal-4.4/include/CGAL/FPU_extension.h cgal-4.5/include/CGAL/FPU_extension.h --- cgal-4.4/include/CGAL/FPU_extension.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/FPU_extension.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,65 @@ +// Copyright (c) 2010-2011 GeometryFactory Sarl (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Laurent Rineau + + +// The main goal of FPU.h is to define functions or macros to modify the +// control word of the FPU, to: +// - set the precision to 53 bits of mantissa, +// - get/set the rounding mode. +// +// The goal of FPU_extension.h is to define inline functions similar to +// feclearexcept and fetestexcept of C99. +// +// For the moment, only i386 and x64 processors are supported, with MSVC, +// gcc, or the Intel compiler suite. Otherwise, the non-inline functions of +// C99 are used. + +#ifndef CGAL_FPU_EXTENSION_H +#define CGAL_FPU_EXTENSION_H + +#if __i386__ && !defined __PGI && !defined __SUNPRO_CC +# ifdef CGAL_SAFE_SSE2 +# include +# else +# include +# endif +#elif defined _MSC_VER +# include +#else + +// generic functions, using C99 + +extern "C" { +# include +} + +namespace CGAL { + +inline int +feclearexcept(int exceptions) { + return ::feclearexcept(exceptions); +} + +inline int +fetestexcept(int exceptions) { + return ::fetestexcept(exceptions); +} + +} // end namespace CGAL + +#endif // use fenv + +#endif // CGAL_FPU_EXTENSION_H diff -Nru cgal-4.4/include/CGAL/FPU_gcc_i386.h cgal-4.5/include/CGAL/FPU_gcc_i386.h --- cgal-4.4/include/CGAL/FPU_gcc_i386.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/FPU_gcc_i386.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,38 @@ +// Copyright (c) 2010-2011 GeometryFactory Sarl (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Laurent Rineau + +extern "C" { +#include +} + +namespace CGAL { + +// brute-force replacement for C99 (which does not require an inline-function) +inline int +feclearexcept(int exceptions) { + // TODO: clear only given exceptions + asm volatile("fnclex"); + return 0; +} + +inline int +fetestexcept(int exceptions) { + int status; + asm volatile("fnstsw %0" : "=m" (status)); + return status & exceptions; +} + +} // end namespace CGAL diff -Nru cgal-4.4/include/CGAL/FPU_gcc_i386_sse2.h cgal-4.5/include/CGAL/FPU_gcc_i386_sse2.h --- cgal-4.4/include/CGAL/FPU_gcc_i386_sse2.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/FPU_gcc_i386_sse2.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,41 @@ +// Copyright (c) 2010-2011 GeometryFactory Sarl (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Laurent Rineau + +extern "C" { +#include +} + +namespace CGAL { + +// replacement for C99 + +inline int +feclearexcept(int exceptions) { + int mxcsr; + asm volatile("stmxcsr %0" : "=m" (mxcsr) ); + mxcsr &= ~exceptions; + asm volatile("ldmxcsr %0" : : "m" (mxcsr) ); + return 0; +} + +inline int +fetestexcept(int exceptions) { + int status; + asm volatile("stmxcsr %0" : "=m" (status) ); + return status & exceptions; +} + +} // end namespace CGAL diff -Nru cgal-4.4/include/CGAL/FPU.h cgal-4.5/include/CGAL/FPU.h --- cgal-4.4/include/CGAL/FPU.h 2013-12-21 20:00:22.000000000 +0000 +++ cgal-4.5/include/CGAL/FPU.h 2014-08-29 13:58:16.000000000 +0000 @@ -153,6 +153,11 @@ asm volatile ("" : "+m"(x) ); # endif return x; +#elif defined __xlC__ + // PowerPC - XL C++ (the z/OS version supposedly does not define this macro) + // If we give it an alternative "+fm", it gets confused and generates worse code. + asm volatile ("" : "+f"(x) ); + return x; #elif defined __GNUG__ // Intel used not to emulate this perfectly, we'll see. // If we create a version of IA_opacify for vectors, note that gcc < 4.8 diff -Nru cgal-4.4/include/CGAL/FPU_msvc.h cgal-4.5/include/CGAL/FPU_msvc.h --- cgal-4.4/include/CGAL/FPU_msvc.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/FPU_msvc.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,52 @@ +// Copyright (c) 2010-2011 GeometryFactory Sarl (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Laurent Rineau + +#include + +#ifndef FE_INVALID +# define FE_INEXACT _EM_INEXACT +# define FE_UNDERFLOW _EM_UNDERFLOW +# define FE_OVERFLOW _EM_OVERFLOW +# define FE_DIVBYZERO _EM_ZERODIVIDE +# define FE_INVALID _EM_INVALID +#endif + +namespace CGAL { + +// replacement for C99 functions + +inline int +feclearexcept(int exceptions) { + _clearfp(); + return 0; +} + +inline int +fetestexcept(int exceptions) +{ +#if defined(_M_IX86) && _M_IX86_FP > 0 + // On x86/x64 processors, when SSE is used. + unsigned int i1; + unsigned int i2; + _statusfp2(&i1, &i2); + return (i1 & exceptions) | (i2 & exceptions); +#else + // On x86 processors without SSE, or on other processors supported by MSVC + return _statusfp() & exceptions; +#endif +} + +} // end namespace CGAL diff -Nru cgal-4.4/include/CGAL/Fuzzy_iso_box.h cgal-4.5/include/CGAL/Fuzzy_iso_box.h --- cgal-4.4/include/CGAL/Fuzzy_iso_box.h 2013-09-28 19:00:44.000000000 +0000 +++ cgal-4.5/include/CGAL/Fuzzy_iso_box.h 2014-08-29 13:58:17.000000000 +0000 @@ -116,7 +116,7 @@ Cartesian_const_iterator_d pit = construct_it(p); Cartesian_const_iterator_d minit= min_begin, maxit = max_begin; for (unsigned int i = 0; i < dim; ++i, ++pit, ++minit, ++maxit) { - if ( ((*pit) < (*minit)) || ((*pit) >= (*maxit)) ) return false; + if ( ((*pit) < (*minit)) || ((*pit) > (*maxit)) ) return false; } return true; } @@ -125,7 +125,7 @@ Cartesian_const_iterator_d minit= min_begin, maxit = max_begin; for (unsigned int i = 0; i < dim; ++i, ++minit, ++maxit) { if ( ((*maxit)-eps < rectangle.min_coord(i)) - || ((*minit)+eps >= rectangle.max_coord(i)) ) return false; + || ((*minit)+eps > rectangle.max_coord(i)) ) return false; } return true; } @@ -135,7 +135,7 @@ Cartesian_const_iterator_d minit= min_begin, maxit = max_begin; for (unsigned int i = 0; i < dim; ++i, ++minit, ++maxit) { if ( ((*maxit)+eps < rectangle.max_coord(i) ) - || ((*minit)-eps >= rectangle.min_coord(i)) ) return false; + || ((*minit)-eps > rectangle.min_coord(i)) ) return false; } return true; } diff -Nru cgal-4.4/include/CGAL/Fuzzy_sphere.h cgal-4.5/include/CGAL/Fuzzy_sphere.h --- cgal-4.4/include/CGAL/Fuzzy_sphere.h 2012-11-13 13:14:00.000000000 +0000 +++ cgal-4.5/include/CGAL/Fuzzy_sphere.h 2014-08-29 13:58:17.000000000 +0000 @@ -71,7 +71,7 @@ ((*cit)-(*pit))*((*cit)-(*pit)); } - return (distance < squared_radius); + return (distance <= squared_radius); } @@ -94,7 +94,7 @@ ((*cit)-rectangle.max_coord(i))*((*cit)-rectangle.max_coord(i)); } - return (distance < squared_radius); + return (distance <= squared_radius); } @@ -117,7 +117,7 @@ distance += ((*cit)-rectangle.min_coord(i))*((*cit)-rectangle.min_coord(i)); } - return (distance < squared_radius); + return (distance <= squared_radius); } }; // class Fuzzy_sphere_impl diff -Nru cgal-4.4/include/CGAL/Get_arithmetic_kernel.h cgal-4.5/include/CGAL/Get_arithmetic_kernel.h --- cgal-4.4/include/CGAL/Get_arithmetic_kernel.h 2012-11-13 13:13:52.000000000 +0000 +++ cgal-4.5/include/CGAL/Get_arithmetic_kernel.h 2014-08-29 13:58:16.000000000 +0000 @@ -25,8 +25,6 @@ #ifndef CGAL_GET_ARITHMETIC_KERNEL_H #define CGAL_GET_ARITHMETIC_KERNEL_H -#include - namespace CGAL { template< class NT > struct Get_arithmetic_kernel{}; } //namespace CGAL diff -Nru cgal-4.4/include/CGAL/GMP/Gmpfi_type.h cgal-4.5/include/CGAL/GMP/Gmpfi_type.h --- cgal-4.4/include/CGAL/GMP/Gmpfi_type.h 2013-11-16 20:00:24.000000000 +0000 +++ cgal-4.5/include/CGAL/GMP/Gmpfi_type.h 2014-08-29 13:58:16.000000000 +0000 @@ -14,7 +14,7 @@ // $URL$ // $Id$ // -// Author: Luis Peñaranda +// Author: Luis Peñaranda #ifndef CGAL_GMPFI_TYPE_H #define CGAL_GMPFI_TYPE_H diff -Nru cgal-4.4/include/CGAL/GMP/Gmpfi_type_static.h cgal-4.5/include/CGAL/GMP/Gmpfi_type_static.h --- cgal-4.4/include/CGAL/GMP/Gmpfi_type_static.h 2013-11-16 20:00:24.000000000 +0000 +++ cgal-4.5/include/CGAL/GMP/Gmpfi_type_static.h 2014-08-29 13:58:16.000000000 +0000 @@ -14,7 +14,7 @@ // $URL$ // $Id$ // -// Author: Luis Peñaranda +// Author: Luis Peñaranda // This file contains the arithmetic functions not members of the Gmpfi // class. diff -Nru cgal-4.4/include/CGAL/GMP/Gmpfr_type_static.h cgal-4.5/include/CGAL/GMP/Gmpfr_type_static.h --- cgal-4.4/include/CGAL/GMP/Gmpfr_type_static.h 2012-11-13 13:13:59.000000000 +0000 +++ cgal-4.5/include/CGAL/GMP/Gmpfr_type_static.h 2014-08-29 13:58:16.000000000 +0000 @@ -14,7 +14,7 @@ // $URL$ // $Id$ // -// Author: Luis Peñaranda +// Author: Luis Peñaranda // This file contains the arithmetic functions not members of the Gmpfr // class. diff -Nru cgal-4.4/include/CGAL/GMP/Gmpq_type.h cgal-4.5/include/CGAL/GMP/Gmpq_type.h --- cgal-4.4/include/CGAL/GMP/Gmpq_type.h 2013-10-15 19:00:17.000000000 +0000 +++ cgal-4.5/include/CGAL/GMP/Gmpq_type.h 2014-08-29 13:58:16.000000000 +0000 @@ -39,6 +39,12 @@ #include #include +#if defined(BOOST_MSVC) +# pragma warning(push) +# pragma warning(disable:4146) + // warning on - applied on unsigned number +#endif + namespace CGAL { // Wrapper around mpq_t to get the destructor call mpq_clear. @@ -60,13 +66,14 @@ class Gmpq : Handle_for, - boost::ordered_field_operators1< Gmpq + boost::totally_ordered1< Gmpq , boost::ordered_field_operators2< Gmpq, int , boost::ordered_field_operators2< Gmpq, long + , boost::ordered_field_operators2< Gmpq, long long , boost::ordered_field_operators2< Gmpq, double , boost::ordered_field_operators2< Gmpq, Gmpz , boost::ordered_field_operators2< Gmpq, Gmpfr - > > > > > > + > > > > > > > { typedef Handle_for Base; public: @@ -95,6 +102,35 @@ Gmpq(unsigned long n) { mpq_set_ui(mpq(), n, 1); } +private: + void init_ull(unsigned long long n){ + CGAL_assertion(sizeof(long)==4 && sizeof(long long)==8); + mpq_set_ui(mpq(), (unsigned long)(n>>32), 1); + mpz_ptr z = mpq_numref(mpq()); + mpz_mul_2exp (z, z, 32); + mpz_add_ui (z, z, (unsigned long)n); + } +public: + Gmpq(unsigned long long n) + { + if (n <= std::numeric_limits::max BOOST_PREVENT_MACRO_SUBSTITUTION ()) + mpq_set_ui(mpq(), (unsigned long)n, 1); + else + init_ull(n); + } + + Gmpq(long long n) + { + if (sizeof(long)==sizeof(long long)) + mpq_set_si(mpq(), (long)n, 1); + else if (n>=0) + init_ull(n); + else { + init_ull(-(unsigned long long)n); + mpq_neg(mpq(), mpq()); + } + } + Gmpq(const Gmpz& n) { mpq_set_z(mpq(), n.mpz()); } @@ -223,6 +259,15 @@ bool operator< (long z) const {return mpq_cmp_si(mpq(),z,1)<0;} bool operator> (long z) const {return mpq_cmp_si(mpq(),z,1)>0;} + // Interoperability with long long + Gmpq& operator+=(long long z){return (*this)+= Gmpq(z);} + Gmpq& operator-=(long long z){return (*this)-= Gmpq(z);} + Gmpq& operator*=(long long z){return (*this)*= Gmpq(z);} + Gmpq& operator/=(long long z){return (*this)/= Gmpq(z);} + bool operator==(long long z) const {return (*this)== Gmpq(z);} + bool operator< (long long z) const {return (*this)< Gmpq(z);} + bool operator> (long long z) const {return (*this)> Gmpq(z);} + // Interoperability with double Gmpq& operator+=(double d){return (*this)+= Gmpq(d);} Gmpq& operator-=(double d){return (*this)-= Gmpq(d);} @@ -269,43 +314,71 @@ } inline +Gmpq +operator+(const Gmpq &x, const Gmpq &y) +{ + Gmpq Res; + mpq_add(Res.mpq(), x.mpq(), y.mpq()); + return Res; +} + +inline Gmpq& Gmpq::operator+=(const Gmpq &z) { - Gmpq Res; - mpq_add(Res.mpq(), mpq(), z.mpq()); - swap(Res); + (*this + z).swap(*this); return *this; } inline +Gmpq +operator-(const Gmpq &x, const Gmpq &y) +{ + Gmpq Res; + mpq_sub(Res.mpq(), x.mpq(), y.mpq()); + return Res; +} + +inline Gmpq& Gmpq::operator-=(const Gmpq &z) { - Gmpq Res; - mpq_sub(Res.mpq(), mpq(), z.mpq()); - swap(Res); + (*this - z).swap(*this); return *this; } inline +Gmpq +operator*(const Gmpq &x, const Gmpq &y) +{ + Gmpq Res; + mpq_mul(Res.mpq(), x.mpq(), y.mpq()); + return Res; +} + +inline Gmpq& Gmpq::operator*=(const Gmpq &z) { - Gmpq Res; - mpq_mul(Res.mpq(), mpq(), z.mpq()); - swap(Res); + (*this * z).swap(*this); return *this; } inline +Gmpq +operator/(const Gmpq &x, const Gmpq &y) +{ + CGAL_precondition(y != 0); + Gmpq Res; + mpq_div(Res.mpq(), x.mpq(), y.mpq()); + return Res; +} + +inline Gmpq& Gmpq::operator/=(const Gmpq &z) { - CGAL_precondition(z != 0); - Gmpq Res; - mpq_div(Res.mpq(), mpq(), z.mpq()); - swap(Res); + (*this / z).swap(*this); return *this; } @@ -553,4 +626,8 @@ } //namespace CGAL +#if defined(BOOST_MSVC) +# pragma warning(pop) +#endif + #endif // CGAL_GMPQ_TYPE_H diff -Nru cgal-4.4/include/CGAL/GMP_arithmetic_kernel.h cgal-4.5/include/CGAL/GMP_arithmetic_kernel.h --- cgal-4.4/include/CGAL/GMP_arithmetic_kernel.h 2012-11-13 13:13:52.000000000 +0000 +++ cgal-4.5/include/CGAL/GMP_arithmetic_kernel.h 2014-08-29 13:58:16.000000000 +0000 @@ -25,9 +25,10 @@ #ifndef CGAL_GMP_ARITHMETIC_KERNEL_H #define CGAL_GMP_ARITHMETIC_KERNEL_H +#include + #ifdef CGAL_USE_GMP -#include #include #include diff -Nru cgal-4.4/include/CGAL/Gmpfi.h cgal-4.5/include/CGAL/Gmpfi.h --- cgal-4.4/include/CGAL/Gmpfi.h 2013-09-28 19:00:44.000000000 +0000 +++ cgal-4.5/include/CGAL/Gmpfi.h 2014-08-29 13:58:16.000000000 +0000 @@ -14,7 +14,7 @@ // $URL$ // $Id$ // -// Author: Luis Peñaranda +// Author: Luis Peñaranda // Michael Hemmer #ifndef CGAL_GMPFI_H @@ -344,6 +344,7 @@ typedef CGAL::Gmpfi Nested; static inline Real epsilon() { return 0; } + static inline Real dummy_precision() { return 0; } enum { IsInteger = 0, diff -Nru cgal-4.4/include/CGAL/Gmpfr.h cgal-4.5/include/CGAL/Gmpfr.h --- cgal-4.4/include/CGAL/Gmpfr.h 2012-11-13 13:13:59.000000000 +0000 +++ cgal-4.5/include/CGAL/Gmpfr.h 2014-08-29 13:58:16.000000000 +0000 @@ -14,7 +14,7 @@ // $URL$ // $Id$ // -// Author: Luis Peñaranda +// Author: Luis Peñaranda #ifndef CGAL_GMPFR_H #define CGAL_GMPFR_H @@ -164,6 +164,7 @@ typedef CGAL::Gmpfr Nested; static inline Real epsilon() { return 0; } + static inline Real dummy_precision() { return 0; } enum { IsInteger = 0, diff -Nru cgal-4.4/include/CGAL/Gmpq.h cgal-4.5/include/CGAL/Gmpq.h --- cgal-4.4/include/CGAL/Gmpq.h 2012-11-13 13:13:59.000000000 +0000 +++ cgal-4.5/include/CGAL/Gmpq.h 2014-08-29 13:58:16.000000000 +0000 @@ -143,6 +143,7 @@ typedef CGAL::Gmpq Nested; static inline Real epsilon() { return 0; } + static inline Real dummy_precision() { return 0; } enum { IsInteger = 0, diff -Nru cgal-4.4/include/CGAL/Gmpz.h cgal-4.5/include/CGAL/Gmpz.h --- cgal-4.4/include/CGAL/Gmpz.h 2012-11-13 13:13:59.000000000 +0000 +++ cgal-4.5/include/CGAL/Gmpz.h 2014-08-29 13:58:16.000000000 +0000 @@ -217,6 +217,7 @@ typedef CGAL::Gmpz Nested; static inline Real epsilon() { return 0; } + static inline Real dummy_precision() { return 0; } enum { IsInteger = 1, diff -Nru cgal-4.4/include/CGAL/Handle_for.h cgal-4.5/include/CGAL/Handle_for.h --- cgal-4.4/include/CGAL/Handle_for.h 2013-11-30 20:00:27.000000000 +0000 +++ cgal-4.5/include/CGAL/Handle_for.h 2014-08-29 13:58:17.000000000 +0000 @@ -60,25 +60,28 @@ typedef std::ptrdiff_t Id_type ; Handle_for() - : ptr_(allocator.allocate(1)) { - new (&(ptr_->t)) element_type(); // we get the warning here - ptr_->count = 1; + pointer p = allocator.allocate(1); + new (&(p->t)) element_type(); // we get the warning here + p->count = 1; + ptr_ = p; } Handle_for(const element_type& t) - : ptr_(allocator.allocate(1)) { - new (&(ptr_->t)) element_type(t); - ptr_->count = 1; + pointer p = allocator.allocate(1); + new (&(p->t)) element_type(t); + p->count = 1; + ptr_ = p; } #ifndef CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE Handle_for(element_type && t) - : ptr_(allocator.allocate(1)) { - new (&(ptr_->t)) element_type(std::move(t)); - ptr_->count = 1; + pointer p = allocator.allocate(1); + new (&(p->t)) element_type(std::move(t)); + p->count = 1; + ptr_ = p; } #endif @@ -86,44 +89,49 @@ to take place. We'll see if it's a problem later. template < typename T1 > Handle_for(const T1& t1) - : ptr_(allocator.allocate(1)) { - new (&(ptr_->t)) T(t1); - ptr_->count = 1; + pointer p = allocator.allocate(1); + new (&(p->t)) T(t1); + p->count = 1; + ptr_ = p; } */ #if !defined CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES && !defined CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE template < typename T1, typename T2, typename... Args > Handle_for(T1 && t1, T2 && t2, Args && ... args) - : ptr_(allocator.allocate(1)) { - new (&(ptr_->t)) element_type(std::forward(t1), std::forward(t2), std::forward(args)...); - ptr_->count = 1; + pointer p = allocator.allocate(1); + new (&(p->t)) element_type(std::forward(t1), std::forward(t2), std::forward(args)...); + p->count = 1; + ptr_ = p; } #else template < typename T1, typename T2 > Handle_for(const T1& t1, const T2& t2) - : ptr_(allocator.allocate(1)) { - new (&(ptr_->t)) element_type(t1, t2); - ptr_->count = 1; + pointer p = allocator.allocate(1); + new (&(p->t)) element_type(t1, t2); + p->count = 1; + ptr_ = p; } template < typename T1, typename T2, typename T3 > Handle_for(const T1& t1, const T2& t2, const T3& t3) - : ptr_(allocator.allocate(1)) { - new (&(ptr_->t)) element_type(t1, t2, t3); - ptr_->count = 1; + pointer p = allocator.allocate(1); + new (&(p->t)) element_type(t1, t2, t3); + p->count = 1; + ptr_ = p; } template < typename T1, typename T2, typename T3, typename T4 > Handle_for(const T1& t1, const T2& t2, const T3& t3, const T4& t4) - : ptr_(allocator.allocate(1)) { - new (&(ptr_->t)) element_type(t1, t2, t3, t4); - ptr_->count = 1; + pointer p = allocator.allocate(1); + new (&(p->t)) element_type(t1, t2, t3, t4); + p->count = 1; + ptr_ = p; } #endif // CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES diff -Nru cgal-4.4/include/CGAL/Handle_hash_function.h cgal-4.5/include/CGAL/Handle_hash_function.h --- cgal-4.4/include/CGAL/Handle_hash_function.h 2012-11-13 13:13:55.000000000 +0000 +++ cgal-4.5/include/CGAL/Handle_hash_function.h 2014-08-29 13:58:16.000000000 +0000 @@ -31,13 +31,28 @@ namespace CGAL { +//mechanism to abuse Handle_hash_function which is the default +//template parameter of Unique_hash_map +namespace internal{ + namespace handle { + template + struct Hash_functor{ + std::size_t + operator()(const H& h) + { + return std::size_t(&*h) / + sizeof( typename std::iterator_traits::value_type); + } + }; + } +} + struct Handle_hash_function { typedef std::size_t result_type; template - std::size_t operator() (const H& h) const { - return std::size_t(&*h) / - sizeof( typename std::iterator_traits::value_type); - } + std::size_t operator() (const H& h) const { + return ::CGAL::internal::handle::Hash_functor()(h); + } }; } //namespace CGAL diff -Nru cgal-4.4/include/CGAL/Has_timestamp.h cgal-4.5/include/CGAL/Has_timestamp.h --- cgal-4.4/include/CGAL/Has_timestamp.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/Has_timestamp.h 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,49 @@ +// Copyright (c) 2014 GeometryFactory Sarl (France) +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// +// +// Author(s) : Jane Tournois + +#ifndef CGAL_HAS_TIMESTAMP_H +#define CGAL_HAS_TIMESTAMP_H + +#include +#include + +namespace CGAL { + +namespace internal { + + BOOST_MPL_HAS_XXX_TRAIT_DEF(Has_timestamp) + + // Used by Compact container to make the comparison of iterator + // depending on the insertion order rather than the object address + // when the object class defines a Has_timestamp tag + // This is for example used in to make Mesh_3 deterministic, see + // classes implementing concepts MeshCellBase_3 and MeshVertexBase_3 + template ::value> + struct Has_timestamp : public T::Has_timestamp + // when T has a Has_timestamp tag + {}; + + template + struct Has_timestamp : public Tag_false + // when T does not have a Has_timestamp tag + {}; + +} // end namespace internal +} // end namespace CGAL + +#endif // CGAL_HAS_TIMESTAMP_H diff -Nru cgal-4.4/include/CGAL/Homogeneous/function_objects.h cgal-4.5/include/CGAL/Homogeneous/function_objects.h --- cgal-4.4/include/CGAL/Homogeneous/function_objects.h 2012-11-13 13:13:55.000000000 +0000 +++ cgal-4.5/include/CGAL/Homogeneous/function_objects.h 2014-08-29 13:58:16.000000000 +0000 @@ -86,6 +86,7 @@ class Angle_3 { typedef typename K::Point_3 Point_3; + typedef typename K::Vector_3 Vector_3; typedef typename K::Construct_vector_3 Construct_vector_3; Construct_vector_3 c; public: @@ -95,9 +96,20 @@ Angle_3(const Construct_vector_3& c_) : c(c_) {} result_type + operator()(const Vector_3& u, const Vector_3& v) const + { return enum_cast(CGAL_NTS sign(u * v)); } + // FIXME: scalar product + + result_type operator()(const Point_3& p, const Point_3& q, const Point_3& r) const { return enum_cast(CGAL_NTS sign(c(q,p) * c(q,r))); } // FIXME: scalar product + + result_type + operator()(const Point_3& p, const Point_3& q, + const Point_3& r, const Point_3& s) const + { return enum_cast(CGAL_NTS sign(c(q,p) * c(s,r))); } + // FIXME: scalar product }; @@ -115,8 +127,8 @@ operator()( const Circle_2& c, const Point_2& p) const { typename K::Compute_squared_distance_2 squared_distance; - return enum_cast(CGAL_NTS compare(c.squared_radius(), - squared_distance(c.center(),p))); + return enum_cast(CGAL::compare(c.squared_radius(), + squared_distance(c.center(),p))); } result_type @@ -664,14 +676,14 @@ result_type operator()(const T1& p, const T2& q, const T3& r) const { - return CGAL_NTS compare(squared_distance(p, q), squared_distance(p, r)); + return CGAL::compare(squared_distance(p, q), squared_distance(p, r)); } template result_type operator()(const T1& p, const T2& q, const T3& r, const T4& s) const { - return CGAL_NTS compare(squared_distance(p, q), squared_distance(r, s)); + return CGAL::compare(squared_distance(p, q), squared_distance(r, s)); } }; @@ -717,14 +729,14 @@ result_type operator()(const T1& p, const T2& q, const T3& r) const { - return CGAL_NTS compare(squared_distance(p, q), squared_distance(p, r)); + return CGAL::compare(squared_distance(p, q), squared_distance(p, r)); } template result_type operator()(const T1& p, const T2& q, const T3& r, const T4& s) const { - return CGAL_NTS compare(squared_distance(p, q), squared_distance(r, s)); + return CGAL::compare(squared_distance(p, q), squared_distance(r, s)); } }; @@ -754,11 +766,11 @@ if (l1_sign > l2_sign) return LARGER; if (l1_sign > 0) - return CGAL_NTS compare( CGAL_NTS abs(l1.a() * l2.b()), - CGAL_NTS abs(l2.a() * l1.b()) ); + return CGAL::compare( CGAL::abs(l1.a() * l2.b()), + CGAL::abs(l2.a() * l1.b()) ); - return CGAL_NTS compare( CGAL_NTS abs(l2.a() * l1.b()), - CGAL_NTS abs(l1.a() * l2.b()) ); + return CGAL::compare( CGAL::abs(l2.a() * l1.b()), + CGAL::abs(l1.a() * l2.b()) ); } // FIXME result_type @@ -843,7 +855,7 @@ result_type operator()( const Point_2& p, const Line_2& h1, const Line_2& h2) const - { return CGAL_NTS compare(h1.x_at_y( p.y() ), h2.x_at_y( p.y() )); } + { return CGAL::compare(h1.x_at_y( p.y() ), h2.x_at_y( p.y() )); } // FIXME result_type @@ -893,7 +905,7 @@ // same x and y pV = p.hz()*q.hw(); qV = q.hz()*p.hw(); - return CGAL_NTS compare(pV, qV); + return CGAL::compare(pV, qV); } }; @@ -923,7 +935,7 @@ pV = phy*qhw; qV = qhy*phw; } - return CGAL_NTS compare(pV, qV); + return CGAL::compare(pV, qV); } }; @@ -953,7 +965,7 @@ pV = phx*qhw; qV = qhx*phw; } - return CGAL_NTS compare(pV, qV); + return CGAL::compare(pV, qV); } }; @@ -981,7 +993,7 @@ // same x pV = p.hy()*q.hw(); qV = q.hy()*p.hw(); - return CGAL_NTS compare(pV, qV); + return CGAL::compare(pV, qV); } }; @@ -996,7 +1008,7 @@ result_type operator()( const Point_2& p, const Point_2& q) const { - return CGAL_NTS compare(p.hx()*q.hw(), q.hx()*p.hw()); + return CGAL::compare(p.hx()*q.hw(), q.hx()*p.hw()); } result_type @@ -1031,7 +1043,7 @@ result_type operator()( const Point_3& p, const Point_3& q) const - { return CGAL_NTS compare(p.hx() * q.hw(), q.hx() * p.hw() ); } + { return CGAL::compare(p.hx() * q.hw(), q.hx() * p.hw() ); } }; template @@ -1055,7 +1067,7 @@ result_type operator()( const Point_2& p, const Line_2& h1, const Line_2& h2) const - { return CGAL_NTS compare(h1.y_at_x( p.x() ), h2.y_at_x( p.x() )); } + { return CGAL::compare(h1.y_at_x( p.x() ), h2.y_at_x( p.x() )); } // FIXME result_type @@ -1128,11 +1140,11 @@ FT s1stx = s1sx-s1tx; FT s2stx = s2sx-s2tx; - return CGAL_NTS compare(s1sx, s1tx) * - CGAL_NTS compare(s2sx, s2tx) * - CGAL_NTS compare(-(s1sx-px)*(s1sy-s1ty)*s2stx, - (s2sy-s1sy)*s2stx*s1stx - -(s2sx-px)*(s2sy-s2ty)*s1stx); + return CGAL::compare(s1sx, s1tx) * + CGAL::compare(s2sx, s2tx) * + CGAL::compare(-(s1sx-px)*(s1sy-s1ty)*s2stx, + (s2sy-s1sy)*s2stx*s1stx + -(s2sx-px)*(s2sy-s2ty)*s1stx); } else { if (s1sx == s1tx) { // s1 is vertical @@ -1171,7 +1183,7 @@ const RT& phw = p.hw(); const RT& qhy = q.hy(); const RT& qhw = q.hw(); - return CGAL_NTS compare(phy * qhw, qhy * phw); + return CGAL::compare(phy * qhw, qhy * phw); } result_type @@ -1206,7 +1218,7 @@ result_type operator()( const Point_3& p, const Point_3& q) const - { return CGAL_NTS compare(p.hy() * q.hw(), q.hy() * p.hw() ); } + { return CGAL::compare(p.hy() * q.hw(), q.hy() * p.hw() ); } }; template @@ -1218,7 +1230,7 @@ result_type operator()( const Point_3& p, const Point_3& q) const - { return CGAL_NTS compare(p.hz() * q.hw(), q.hz() * p.hw() ); } + { return CGAL::compare(p.hz() * q.hw(), q.hz() * p.hw() ); } }; template @@ -4185,7 +4197,7 @@ RT C = qhx*rhw - qhw*rhx; RT D = qhy*rhw - qhw*rhy; - return CGAL_NTS compare(A*D, B*C); + return CGAL::compare(A*D, B*C); } result_type @@ -4318,8 +4330,8 @@ const RT& thw = t.hw(); return enum_cast( - CGAL_NTS compare((thx*phw-phx*thw)*(qhx*thw-thx*qhw), - (thy*phw-phy*thw)*(thy*qhw-qhy*thw)) ); + CGAL::compare((thx*phw-phx*thw)*(qhx*thw-thx*qhw), + (thy*phw-phy*thw)*(thy*qhw-qhy*thw)) ); } result_type diff -Nru cgal-4.4/include/CGAL/Image_3.h cgal-4.5/include/CGAL/Image_3.h --- cgal-4.4/include/CGAL/Image_3.h 2013-03-23 20:00:23.000000000 +0000 +++ cgal-4.5/include/CGAL/Image_3.h 2014-08-29 13:58:16.000000000 +0000 @@ -457,7 +457,9 @@ labels.insert(((Image_word_type*)image()->data)[(i2 * dimy + j2) * dimx + k1]); labels.insert(((Image_word_type*)image()->data)[(i2 * dimy + j2) * dimx + k2]); - CGAL_HISTOGRAM_PROFILER("Number of labels around a vertex, Image_3::labellized_trilinear_interpolation()", labels.size()); + CGAL_HISTOGRAM_PROFILER( + "Number of labels around a vertex, Image_3::labellized_trilinear_interpolation()", + static_cast(labels.size())); if(labels.size() == 1) { return *(labels.begin()); diff -Nru cgal-4.4/include/CGAL/Implicit_mesh_domain_3.h cgal-4.5/include/CGAL/Implicit_mesh_domain_3.h --- cgal-4.4/include/CGAL/Implicit_mesh_domain_3.h 2013-09-21 19:00:24.000000000 +0000 +++ cgal-4.5/include/CGAL/Implicit_mesh_domain_3.h 2014-08-29 13:58:16.000000000 +0000 @@ -31,8 +31,9 @@ # pragma warning(disable:4180) // qualifier applied to function type has no meaning; ignored #endif -#include -#include +#include +#include +#include namespace CGAL { @@ -45,13 +46,13 @@ */ template > + class Wrapper = Implicit_to_labeling_function_wrapper > class Implicit_mesh_domain_3 - : public Mesh_3::Labeled_mesh_domain_3 + : public Labeled_mesh_domain_3 { public: /// Base type - typedef Mesh_3::Labeled_mesh_domain_3 Base; + typedef Labeled_mesh_domain_3 Base; /// Public types typedef typename Base::Sphere_3 Sphere_3; @@ -66,8 +67,9 @@ */ Implicit_mesh_domain_3(const Function& f, const Sphere_3& bounding_sphere, - const FT& error_bound = FT(1e-3)) - : Base(Wrapper(f), bounding_sphere, error_bound) {} + const FT& error_bound = FT(1e-3), + CGAL::Random* p_rng = NULL) + : Base(Wrapper(f), bounding_sphere, error_bound, p_rng) {} /// Destructor virtual ~Implicit_mesh_domain_3() {} diff -Nru cgal-4.4/include/CGAL/Implicit_to_labeling_function_wrapper.h cgal-4.5/include/CGAL/Implicit_to_labeling_function_wrapper.h --- cgal-4.4/include/CGAL/Implicit_to_labeling_function_wrapper.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/Implicit_to_labeling_function_wrapper.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,286 @@ +// Copyright (c) 2009 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Stéphane Tayeb, Aymeric PELLE +// +//****************************************************************************** +// File Description : +// Implicit_to_labeling_function_wrapper and +// Implicit_vector_to_labeling_function_wrapper class declaration +// and implementation. +// +// See classes description to have more information. +//****************************************************************************** + +#ifndef CGAL_IMPLICIT_TO_LABELING_FUNCTION_WRAPPER_H +#define CGAL_IMPLICIT_TO_LABELING_FUNCTION_WRAPPER_H + + +#if defined(BOOST_MSVC) +# pragma warning(push) +# pragma warning(disable:4180) // qualifier applied to function type has no meaning; ignored +#endif + +#include + +namespace CGAL { + +#include + +/** + * @class Implicit_to_labeling_function_wrapper + * + * This class is designed to wrap an implicit function which describes a domain + * by [p is inside if f(p)<0] to a function which takes its values into {0,1}. + * f(p)=0 means that p is outside the domain. + */ +template +class Implicit_to_labeling_function_wrapper +{ +public: + // Types + typedef int return_type; + typedef typename BGT::Point_3 Point_3; + + /// Constructor + Implicit_to_labeling_function_wrapper(const Function_& f) + : r_f_(f) {} + + // Default copy constructor and assignment operator are ok + + /// Destructor + ~Implicit_to_labeling_function_wrapper() {} + + /// Operator () + return_type operator()(const Point_3& p, const bool = true) const + { + return ( (r_f_(p)<0) ? 1 : 0 ); + } + +private: + /// Function to wrap + const Function_& r_f_; + +}; // end class Implicit_to_labeling_function_wrapper + + + +/** + * \deprecated + * + * @class Implicit_vector_to_labeling_function_wrapper + * + * Wraps a set of implicit function [f1,f2,...] to one function F which + * takes its values into N. + * + * Let p be a point. + * F(p) = 0b000000(f2(p)<0)(f1(p)<0) + * + * It can handle at most 8 functions. + */ +template +class Implicit_vector_to_labeling_function_wrapper +{ +public: + // Types + typedef int return_type; + typedef std::vector Function_vector; + typedef typename BGT::Point_3 Point_3; + + /// Constructor + Implicit_vector_to_labeling_function_wrapper(const std::vector& v) + : function_vector_(v) {} + + // Default copy constructor and assignment operator are ok + + /// Destructor + ~Implicit_vector_to_labeling_function_wrapper() {} + + /// Operator () + return_type operator()(const Point_3& p, const bool = true) const + { + int nb_func = function_vector_.size(); + if ( nb_func > 8 ) + { + CGAL_error_msg("We support at most 8 functions !"); + } + + char bits = 0; + for ( int i = 0 ; i < nb_func ; ++i ) + { + // Insert value into bits : we compute fi(p) and insert result at + // bit i of bits + bits |= ( ((*function_vector_[i])(p) < 0) << i ); + } + + return ( static_cast(bits) ); + } + +private: + /// Functions to wrap + const Function_vector function_vector_; + +}; // end class Implicit_to_labeling_function_wrapper + +template +class Implicit_multi_domain_to_labeling_function_wrapper +{ + template + class Implicit_function_traits + { + public: + typedef typename T_::Point Point; + }; + + template + class Implicit_function_traits + { + public: + typedef typename boost::remove_reference< + typename boost::remove_cv< Point_ >::type>::type Point; + }; + +public: + typedef int return_type; + typedef ImplicitFunction Function; + typedef typename Implicit_function_traits::Point Point_3; + typedef std::vector Function_vector; + +private: + std::vector funcs; + std::vector > bmasks; + +public: + Implicit_multi_domain_to_labeling_function_wrapper (const Function_vector& vf, const std::vector >& vps) + : funcs(vf), bmasks(vps.size(), boost::dynamic_bitset<>(funcs.size() * 2, false)) + { + assert(funcs.size()); + + std::size_t mask_index = 0; + for (std::vector >::const_iterator mask_iter = vps.begin(), mask_end_iter = vps.end(); + mask_iter != mask_end_iter; + ++mask_iter) + { + const std::vector& mask = *mask_iter; + assert(funcs.size() == mask.size()); + boost::dynamic_bitset<>& bmask = bmasks[mask_index++]; + + std::size_t bit_index = 0; + for (std::vector::const_iterator iter = mask.begin(), endIter = mask.end(); iter != endIter; ++iter) + { + std::string::value_type character = *iter; + assert(character == POSITIVE || character == NEGATIVE); + + bmask[bit_index] = character == POSITIVE; + ++bit_index; + bmask[bit_index] = character == NEGATIVE; + ++bit_index; + } + } + std::sort(bmasks.begin(), bmasks.end()); + } + + Implicit_multi_domain_to_labeling_function_wrapper (const Function_vector& vf) + : funcs(vf) + { + assert(funcs.size()); + + bmasks.reserve((1 << funcs.size()) - 1); + bmasks.push_back(boost::dynamic_bitset<>(std::string("10"))); + bmasks.push_back(boost::dynamic_bitset<>(std::string("01"))); + + for (std::size_t i = 0; i < funcs.size()-1; ++i) + { + std::size_t c_size = bmasks.size(); + for (std::size_t index = 0; index < c_size; ++index) + { + boost::dynamic_bitset<> aux = bmasks[index]; + aux.push_back(true); + aux.push_back(false); + bmasks.push_back(aux); + bmasks[index].push_back(false); + bmasks[index].push_back(true); + } + } + bmasks.pop_back(); + std::sort(bmasks.begin(), bmasks.end()); + } + + Implicit_multi_domain_to_labeling_function_wrapper (const Function_vector& vf, const std::vector& vps) + : funcs(vf), bmasks(vps.size(), boost::dynamic_bitset<>(funcs.size() * 2, false)) + { + assert(funcs.size()); + + std::size_t mask_index = 0; + for (std::vector::const_iterator mask_iter = vps.begin(), mask_end_iter = vps.end(); + mask_iter != mask_end_iter; + ++mask_iter) + { + const std::string& mask_str = *mask_iter; + assert(funcs.size() == mask_str.length()); + boost::dynamic_bitset<>& bmask = bmasks[mask_index++]; + + std::size_t bit_index = 0; + for (std::string::const_iterator iter = mask_str.begin(), endIter = mask_str.end(); iter != endIter; ++iter) + { + std::string::value_type character = *iter; + assert(character == '+' || character == '-'); + + bmask[bit_index] = character == '+'; + ++bit_index; + bmask[bit_index] = character == '-'; + ++bit_index; + } + } + std::sort(bmasks.begin(), bmasks.end()); + } + + return_type operator() (const Point_3& p, const bool = true) const + { + boost::dynamic_bitset<> bmask(funcs.size() * 2, false); + + std::size_t i = 0; + for (typename std::vector::const_iterator iter = funcs.begin(), endIter = funcs.end(); + iter != endIter; + ++iter) + { + const Function& function = *iter; + + double fres = function(p); + bmask[i] = fres > 0; + ++i; + bmask[i] = fres < 0; + ++i; + } + + std::vector >::const_iterator iter = std::lower_bound(bmasks.begin(), bmasks.end(), bmask); + if (iter != bmasks.end() && *iter == bmask) + return static_cast(1 + (iter - bmasks.begin())); + return 0; + } +}; + +} // end namespace CGAL + + + +#if defined(BOOST_MSVC) +# pragma warning(pop) +#endif + +#endif // CGAL_IMPLICIT_TO_LABELING_FUNCTION_WRAPPER_H diff -Nru cgal-4.4/include/CGAL/In_place_list.h cgal-4.5/include/CGAL/In_place_list.h --- cgal-4.4/include/CGAL/In_place_list.h 2012-11-24 20:00:52.000000000 +0000 +++ cgal-4.5/include/CGAL/In_place_list.h 2014-08-29 13:58:17.000000000 +0000 @@ -164,6 +164,11 @@ --*this; return tmp; } + In_place_list_iterator + remove_const() const + { + return In_place_list_iterator(const_cast(node)); + } }; } diff -Nru cgal-4.4/include/CGAL/internal/AABB_tree/Halfedge_and_face_graph_property_maps.h cgal-4.5/include/CGAL/internal/AABB_tree/Halfedge_and_face_graph_property_maps.h --- cgal-4.4/include/CGAL/internal/AABB_tree/Halfedge_and_face_graph_property_maps.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/internal/AABB_tree/Halfedge_and_face_graph_property_maps.h 2014-08-29 13:58:15.000000000 +0000 @@ -0,0 +1,198 @@ +// Copyright (c) 2012 GeometryFactory (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Sebastien Loriot +// + +#ifndef HALFEDGE_AND_FACE_GRAPH_PROPERTY_MAPS_H +#define HALFEDGE_AND_FACE_GRAPH_PROPERTY_MAPS_H + +#include +#include +#include +#include +#include + +namespace CGAL{ + +//property map +template +struct Triangle_from_face_descriptor_property_map{ + typename boost::remove_const::type* m_graph; + VertexPointPMap m_vppm; + + Triangle_from_face_descriptor_property_map() : m_graph(NULL) + {} + + Triangle_from_face_descriptor_property_map(FaceGraph* g) + : m_graph( const_cast::type*>(g) ), + m_vppm( get(vertex_point, *m_graph) ) + {} + + Triangle_from_face_descriptor_property_map(FaceGraph* g, + VertexPointPMap vppm ) + : m_graph(const_cast::type*>(g)), + m_vppm(vppm) + {} + + typedef typename boost::property_traits< VertexPointPMap >::value_type Point_3; + typedef typename Kernel_traits::Kernel::Triangle_3 Triangle_3; + + //classical typedefs + typedef typename boost::graph_traits::face_descriptor key_type; + typedef Triangle_3 value_type; + typedef value_type reference; + typedef boost::readable_property_map_tag category; + + //get function for property map + inline friend + Triangle_3 + get(const Triangle_from_face_descriptor_property_map& pmap, + typename Triangle_from_face_descriptor_property_map::key_type f) + { + typedef typename boost::property_traits< VertexPointPMap >::value_type Point_3; + typedef typename Kernel_traits::Kernel::Triangle_3 Triangle_3; + typename boost::remove_const::type & g = *(pmap.m_graph); + + CGAL_precondition(halfedge(f,g) == next(next(next(halfedge(f,g),g),g),g)); + const Point_3& a = get(pmap.m_vppm, target(halfedge(f,g),g)); + const Point_3& b = get(pmap.m_vppm, target(next(halfedge(f,g),g),g)); + const Point_3& c = get(pmap.m_vppm,target(next(next(halfedge(f,g),g),g),g)); + + return Triangle_3(a,b,c); + } +}; + + +template < class HalfedgeGraph, + class VertexPointPMap > +struct Segment_from_edge_descriptor_property_map{ + + Segment_from_edge_descriptor_property_map() + {} + +Segment_from_edge_descriptor_property_map(HalfedgeGraph* g) + : m_graph( const_cast::type*>(g) ), + m_vppm( get(vertex_point, *m_graph) ) + {} + + Segment_from_edge_descriptor_property_map(HalfedgeGraph* g, + VertexPointPMap vppm ) + : m_graph( const_cast::type*>(g) ), + m_vppm(vppm) + {} + + //classical typedefs + typedef typename boost::property_traits< VertexPointPMap >::value_type Point; + typedef typename boost::graph_traits::edge_descriptor key_type; + typedef typename Kernel_traits::Kernel::Segment_3 value_type; + typedef value_type reference; + typedef boost::readable_property_map_tag category; + //data + typename boost::remove_const::type* m_graph; + VertexPointPMap m_vppm; + + //get function for property map + inline friend + value_type + get(Segment_from_edge_descriptor_property_map pmap, + key_type h) + { + typedef typename boost::property_traits< VertexPointPMap >::value_type Point; + typedef typename Kernel_traits::Kernel::Segment_3 Segment_3; + + return Segment_3(get(pmap.m_vppm, source(h, *pmap.m_graph) ), + get(pmap.m_vppm, target(h, *pmap.m_graph) ) ); + } +}; + +//property map to access a point from a facet handle +template +struct One_point_from_face_descriptor_property_map{ + + One_point_from_face_descriptor_property_map(FaceGraph* g = NULL) + : m_graph( const_cast::type*>(g) ) + {} + + One_point_from_face_descriptor_property_map(FaceGraph* g, VertexPointPMap vppm ) + : m_graph( const_cast::type*>(g) ), + m_vppm(vppm) + {} + + typename boost::remove_const::type* m_graph; + VertexPointPMap m_vppm; + + //classical typedefs + typedef typename boost::graph_traits::face_descriptor key_type; + typedef typename boost::property_traits< VertexPointPMap >::value_type value_type; + typedef typename boost::property_traits< VertexPointPMap >::reference reference; + typedef boost::lvalue_property_map_tag category; + + //get function for property map + inline friend + reference + get(const One_point_from_face_descriptor_property_map& m, + key_type f) + { + return get(m.m_vppm, target(halfedge(f, *m.m_graph), *m.m_graph)); + } +}; + +//property map to access a point from an edge +template < class HalfedgeGraph, + class VertexPointPMap > +struct Source_point_from_edge_descriptor{ + Source_point_from_edge_descriptor( + HalfedgeGraph* g = NULL ) : + m_graph( const_cast::type*>(g) ), + m_vppm( get(vertex_point, *m_graph) ) + {} + + Source_point_from_edge_descriptor( + HalfedgeGraph* g, + VertexPointPMap vppm ) : + m_graph( const_cast::type*>(g) ), + m_vppm(vppm) + {} + + //classical typedefs + typedef typename boost::property_traits< VertexPointPMap >::value_type value_type; + typedef typename boost::property_traits< VertexPointPMap >::reference reference; + typedef typename boost::graph_traits::edge_descriptor key_type; + typedef boost::readable_property_map_tag category; + //data + typename boost::remove_const::type* m_graph; + VertexPointPMap m_vppm; + + //get function for property map + inline friend + reference + get(Source_point_from_edge_descriptor pmap, + key_type h) + { + return get(vertex_point, + *pmap.m_graph, + source(h, *pmap.m_graph) ); + } +}; + +} //namespace CGAL + +#endif //HALFEDGE_AND_FACE_GRAPH_PROPERTY_MAPS_H diff -Nru cgal-4.4/include/CGAL/internal/AABB_tree/Has_nested_type_Shared_data.h cgal-4.5/include/CGAL/internal/AABB_tree/Has_nested_type_Shared_data.h --- cgal-4.4/include/CGAL/internal/AABB_tree/Has_nested_type_Shared_data.h 2013-09-28 19:00:44.000000000 +0000 +++ cgal-4.5/include/CGAL/internal/AABB_tree/Has_nested_type_Shared_data.h 2014-08-29 13:58:15.000000000 +0000 @@ -36,7 +36,7 @@ BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_nested_type_Shared_data,Shared_data,false) // Utility class used by AABB_face_graph_triangle_primitive and AABB_halfedge_graph_segment_primitive -// to implement the Consruct_shared_data static function. +// to implement the Construct_shared_data static function. template struct Cstr_shared_data; @@ -48,6 +48,12 @@ { return Base::construct_shared_data(ObjectPropertyMap(&graph), PointPropertyMap(&graph)); } + + template + static Shared_data construct_shared_data(Graph& graph, const VertexPmap& vpm) + { + return Base::construct_shared_data(ObjectPropertyMap(&graph, vpm), PointPropertyMap(&graph, vpm)); + } }; template @@ -58,6 +64,12 @@ { return NULL; } + + template + static Shared_data construct_shared_data(Graph&, VertexPmap) + { + return NULL; + } }; } } //namespace CGAL diff -Nru cgal-4.4/include/CGAL/internal/Combinatorial_map_internal_functors.h cgal-4.5/include/CGAL/internal/Combinatorial_map_internal_functors.h --- cgal-4.4/include/CGAL/internal/Combinatorial_map_internal_functors.h 2013-11-30 20:00:27.000000000 +0000 +++ cgal-4.5/include/CGAL/internal/Combinatorial_map_internal_functors.h 2014-08-29 13:58:16.000000000 +0000 @@ -208,8 +208,10 @@ a=amap->template attribute(adart); unsigned int nb = 0; - for ( CGAL::CMap_dart_const_iterator_basic_of_cell - it(*amap, adart, amark); it.cont(); ++it ) + for ( typename + CMap::template Dart_of_cell_basic_const_range::const_iterator + it=amap->template darts_of_cell_basic(adart, amark).begin(); + it.cont(); ++it ) { if ( amap->template attribute(it) != a ) { diff -Nru cgal-4.4/include/CGAL/internal/Combinatorial_map_utility.h cgal-4.5/include/CGAL/internal/Combinatorial_map_utility.h --- cgal-4.4/include/CGAL/internal/Combinatorial_map_utility.h 2013-11-30 20:00:27.000000000 +0000 +++ cgal-4.5/include/CGAL/internal/Combinatorial_map_utility.h 2014-08-29 13:58:16.000000000 +0000 @@ -48,7 +48,8 @@ struct Convert_void { typedef CGAL::Void type; }; -#ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES +#if ! defined(CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES) && \ + ! defined(CGAL_CFG_NO_CPP0X_TUPLE) // Convert a tuple in a same tuple where each void type was replaced into // CGAL::Void. template diff -Nru cgal-4.4/include/CGAL/internal/Combinatorial_map_utility_novariadic.h cgal-4.5/include/CGAL/internal/Combinatorial_map_utility_novariadic.h --- cgal-4.4/include/CGAL/internal/Combinatorial_map_utility_novariadic.h 2013-11-30 20:00:27.000000000 +0000 +++ cgal-4.5/include/CGAL/internal/Combinatorial_map_utility_novariadic.h 2014-08-29 13:58:16.000000000 +0000 @@ -20,7 +20,7 @@ #ifndef CGAL_INTERNAL_COMBINATORIAL_MAP_UTILITY_NOVARIADIC_H #define CGAL_INTERNAL_COMBINATORIAL_MAP_UTILITY_NOVARIADIC_H 1 -#ifdef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES +#if defined(CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES) || defined(CGAL_CFG_NO_CPP0X_TUPLE) #include #include diff -Nru cgal-4.4/include/CGAL/internal/Dummy_tds_3.h cgal-4.5/include/CGAL/internal/Dummy_tds_3.h --- cgal-4.4/include/CGAL/internal/Dummy_tds_3.h 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/include/CGAL/internal/Dummy_tds_3.h 2014-08-29 13:58:17.000000000 +0000 @@ -25,6 +25,8 @@ // Dummy TDS which provides all types that a vertex_base or cell_base can use. struct Dummy_tds_3 { + struct Concurrency_tag {}; + struct Vertex {}; struct Cell {}; struct Facet {}; diff -Nru cgal-4.4/include/CGAL/internal/Exact_type_selector.h cgal-4.5/include/CGAL/internal/Exact_type_selector.h --- cgal-4.4/include/CGAL/internal/Exact_type_selector.h 2013-11-16 20:00:24.000000000 +0000 +++ cgal-4.5/include/CGAL/internal/Exact_type_selector.h 2014-08-29 13:58:16.000000000 +0000 @@ -57,12 +57,14 @@ // Two classes which tell the prefered "exact number types" corresponding to a type. -// The default template chooses Gmpq or Quotient. +// The default template chooses Gmpq, or leda_rational, or Quotient. // It should support the built-in types. template < typename > struct Exact_field_selector #ifdef CGAL_USE_GMP { typedef Gmpq Type; }; +#elif defined(CGAL_USE_LEDA) +{ typedef leda_rational Type; }; #else { typedef Quotient Type; }; #endif diff -Nru cgal-4.4/include/CGAL/internal/Intersections_3/Bbox_3_Triangle_3_do_intersect.h cgal-4.5/include/CGAL/internal/Intersections_3/Bbox_3_Triangle_3_do_intersect.h --- cgal-4.4/include/CGAL/internal/Intersections_3/Bbox_3_Triangle_3_do_intersect.h 2013-06-15 19:00:25.000000000 +0000 +++ cgal-4.5/include/CGAL/internal/Intersections_3/Bbox_3_Triangle_3_do_intersect.h 2014-08-29 13:58:16.000000000 +0000 @@ -1,4 +1,5 @@ // Copyright (c) 2008 INRIA Sophia-Antipolis (France), ETH Zurich (Switzerland). +// Copyright (c) 2010, 2014 GeometryFactory Sarl (France). // All rights reserved. // // This file is part of CGAL (www.cgal.org); you can redistribute it and/or @@ -28,8 +29,7 @@ // The code looks slightly different from his code because we avoid the translation at // a minimal cost (and we use C++ ;). -#include -// ST: is this include really needed ? +#include #include namespace CGAL { @@ -203,7 +203,7 @@ if (is_indeterminate(b)) return b; if(b) std::swap(j,k); - return CGAL_OR( (do_axis_intersect_aux(p_min.y()-j->y(), p_min.z()-j->z(), sides) <= 0), + return CGAL_AND((do_axis_intersect_aux(p_min.y()-j->y(), p_min.z()-j->z(), sides) <= 0), (do_axis_intersect_aux(p_max.y()-k->y(), p_max.z()-k->z(), sides) >= 0) ); } case 1: { @@ -212,7 +212,7 @@ if (is_indeterminate(b)) return b; if(b) std::swap(j,k); - return CGAL_OR( (do_axis_intersect_aux(p_min.x()-j->x(), p_min.z()-j->z(), sides) <= 0), + return CGAL_AND((do_axis_intersect_aux(p_min.x()-j->x(), p_min.z()-j->z(), sides) <= 0), (do_axis_intersect_aux(p_max.x()-k->x(), p_max.z()-k->z(), sides) >= 0) ); } @@ -222,7 +222,7 @@ if ( is_indeterminate(b)) return b; if(b) std::swap(j,k); - return CGAL_OR( (do_axis_intersect_aux(p_min.x()-j->x(), p_min.y()-j->y(), sides) <= 0), + return CGAL_AND((do_axis_intersect_aux(p_min.x()-j->x(), p_min.y()-j->y(), sides) <= 0), (do_axis_intersect_aux(p_max.x()-k->x(), p_max.y()-k->y(), sides) >= 0) ); } default: @@ -287,30 +287,30 @@ const Bbox_3& bbox = a_bbox; #endif - Uncertain ind = make_uncertain(true); + // Create a "certainly true" + Uncertain ind_or_true = make_uncertain(true); - Uncertain b = make_uncertain(true); if (forbidden_axis!=0){ if (forbidden_size!=0){ - b = do_axis_intersect(triangle, sides, bbox); + Uncertain b = do_axis_intersect(triangle, sides, bbox); if(is_indeterminate(b)){ - ind = b; + ind_or_true = b; } else if(! b){ return false; } } if (forbidden_size!=1){ - b = do_axis_intersect(triangle, sides, bbox); + Uncertain b = do_axis_intersect(triangle, sides, bbox); if(is_indeterminate(b)){ - ind = b; + ind_or_true = b; } else if(! b){ return false; } } if (forbidden_size!=2){ - b = do_axis_intersect(triangle, sides, bbox); + Uncertain b = do_axis_intersect(triangle, sides, bbox); if(is_indeterminate(b)){ - ind = b; + ind_or_true = b; } else if(! b){ return false; } @@ -319,25 +319,25 @@ if (forbidden_axis!=1){ if (forbidden_size!=0){ - b = do_axis_intersect(triangle, sides, bbox); + Uncertain b = do_axis_intersect(triangle, sides, bbox); if(is_indeterminate(b)){ - ind = b; + ind_or_true = b; } else if(! b){ return false; } } if (forbidden_size!=1){ - b = do_axis_intersect(triangle, sides, bbox); + Uncertain b = do_axis_intersect(triangle, sides, bbox); if(is_indeterminate(b)){ - ind = b; + ind_or_true = b; } else if(! b){ return false; } } if (forbidden_size!=2){ - b = do_axis_intersect(triangle, sides, bbox); + Uncertain b = do_axis_intersect(triangle, sides, bbox); if(is_indeterminate(b)){ - ind = b; + ind_or_true = b; } else if(! b){ return false; } @@ -346,31 +346,31 @@ if (forbidden_axis!=2){ if (forbidden_size!=0){ - b = do_axis_intersect(triangle, sides, bbox); + Uncertain b = do_axis_intersect(triangle, sides, bbox); if(is_indeterminate(b)){ - ind = b; + ind_or_true = b; } else if(! b){ return false; } } if (forbidden_size!=1){ - b = do_axis_intersect(triangle, sides, bbox); + Uncertain b = do_axis_intersect(triangle, sides, bbox); if(is_indeterminate(b)){ - ind = b; + ind_or_true = b; } else if(! b){ return false; } } if (forbidden_size!=2){ - b = do_axis_intersect(triangle, sides, bbox); + Uncertain b = do_axis_intersect(triangle, sides, bbox); if(is_indeterminate(b)){ - ind = b; + ind_or_true = b; } else if(! b){ return false; } } } - return ind; // throws exception in case it is indeterminate + return ind_or_true; // throws exception in case it is indeterminate } template diff -Nru cgal-4.4/include/CGAL/internal/Projection_traits_3.h cgal-4.5/include/CGAL/internal/Projection_traits_3.h --- cgal-4.4/include/CGAL/internal/Projection_traits_3.h 2012-12-01 20:00:21.000000000 +0000 +++ cgal-4.5/include/CGAL/internal/Projection_traits_3.h 2014-10-09 19:00:09.000000000 +0000 @@ -408,6 +408,25 @@ } }; +template +struct Angle_projected_3{ + typedef typename R::Point_3 Point_3; + typedef typename R::Point_2 Point_2; + + typename R::FT x(const Point_3 &p) const { return Projector::x(p); } + typename R::FT y(const Point_3 &p) const { return Projector::y(p); } + + Point_2 project(const Point_3& p) const + { + return Point_2(x(p),y(p)); + } + + CGAL::Angle operator()(const Point_3& p, const Point_3& q, const Point_3& r) const + { + return CGAL::angle(project(p), project(q), project(r)); + } +}; + template < class R, int dim > class Projection_traits_3 { public: @@ -425,7 +444,7 @@ typedef typename Projector::Compare_x_2 Compare_x_2; typedef typename Projector::Compare_y_2 Compare_y_2; typedef Orientation_projected_3 Orientation_2; - typedef typename Rp::Angle_3 Angle_2; + typedef Angle_projected_3 Angle_2; typedef Side_of_oriented_circle_projected_3 Side_of_oriented_circle_2; typedef Less_signed_distance_to_line_projected_3 Less_signed_distance_to_line_2; typedef Side_of_bounded_circle_projected_3 Side_of_bounded_circle_2; diff -Nru cgal-4.4/include/CGAL/internal/Static_filters/Angle_3.h cgal-4.5/include/CGAL/internal/Static_filters/Angle_3.h --- cgal-4.4/include/CGAL/internal/Static_filters/Angle_3.h 2012-11-13 13:13:55.000000000 +0000 +++ cgal-4.5/include/CGAL/internal/Static_filters/Angle_3.h 2014-08-29 13:58:16.000000000 +0000 @@ -59,6 +59,13 @@ { return Base()(t1,t2); } + + template + result_type + operator()(const T1& t1, const T2& t2, const T3& t3, const T4& t4) const + { + return Base()(t1,t2,t3,t4); + } #endif // CGAL_CFG_MATCHING_BUG_6 diff -Nru cgal-4.4/include/CGAL/internal/Surface_mesh_segmentation/AABB_traversal_traits.h cgal-4.5/include/CGAL/internal/Surface_mesh_segmentation/AABB_traversal_traits.h --- cgal-4.4/include/CGAL/internal/Surface_mesh_segmentation/AABB_traversal_traits.h 2014-02-08 20:00:27.000000000 +0000 +++ cgal-4.5/include/CGAL/internal/Surface_mesh_segmentation/AABB_traversal_traits.h 2014-08-29 13:58:17.000000000 +0000 @@ -54,7 +54,7 @@ if ( GeomTraits().do_intersect_3_object()(query, primitive.datum(m_traits.shared_data())) ) { boost::optional intersection; - intersection = AABBTraits().intersection_object()(query, primitive); + intersection = m_traits.intersection_object()(query, primitive); if(intersection) { *m_out_it++ = *intersection; } diff -Nru cgal-4.4/include/CGAL/internal/Surface_mesh_segmentation/Filters.h cgal-4.5/include/CGAL/internal/Surface_mesh_segmentation/Filters.h --- cgal-4.4/include/CGAL/internal/Surface_mesh_segmentation/Filters.h 2014-02-08 20:00:27.000000000 +0000 +++ cgal-4.5/include/CGAL/internal/Surface_mesh_segmentation/Filters.h 2014-08-29 13:58:17.000000000 +0000 @@ -30,7 +30,7 @@ #include #include - +#include namespace CGAL { @@ -56,7 +56,7 @@ * - domain : over value distances * @param mesh `CGAL Polyhedron` on which @a values are defined * @param window_size range of effective neighbors - * @param[in, out] values `ReadWritePropertyMap` with `Polyhedron::Facet_const_handle` as key and `double` as value type + * @param[in, out] values `ReadWritePropertyMap` with `boost::graph_traits::face_handle` as key and `double` as value type */ template void operator()(const Polyhedron& mesh, @@ -65,8 +65,8 @@ boost::optional spatial_parameter = boost::optional(), boost::optional range_parameter = boost::optional() ) const { - typedef typename Polyhedron::Facet_const_handle Facet_const_handle; - typedef typename Polyhedron::Facet_const_iterator Facet_const_iterator; + typedef typename boost::graph_traits::face_descriptor face_descriptor; + typedef typename boost::graph_traits::face_iterator face_iterator; double spatial_parameter_actual; if(!spatial_parameter) { @@ -76,20 +76,21 @@ } std::vector smoothed_values; // holds smoothed values - smoothed_values.reserve(mesh.size_of_facets()); + smoothed_values.reserve(num_faces(mesh)); - for(Facet_const_iterator facet_it = mesh.facets_begin(); - facet_it != mesh.facets_end(); ++facet_it) { - std::map neighbors; - NeighborSelector()(facet_it, window_size, + face_iterator facet_it, fend; + for(boost::tie(facet_it,fend) = faces(mesh); + facet_it != fend; ++facet_it) { + std::map neighbors; + NeighborSelector()(mesh,*facet_it, window_size, neighbors); // gather neighbors in the window - double current_sdf_value = values[facet_it]; + double current_sdf_value = values[*facet_it]; double range_parameter_actual; if(!range_parameter) { // calculate deviation for range weighting. double deviation = 0.0; - for(typename std::map::iterator it = + for(typename std::map::iterator it = neighbors.begin(); it != neighbors.end(); ++it) { deviation += std::pow(values[it->first] - current_sdf_value, 2); } @@ -107,7 +108,7 @@ // smooth double total_sdf_value = 0.0, total_weight = 0.0; - for(typename std::map::iterator it = + for(typename std::map::iterator it = neighbors.begin(); it != neighbors.end(); ++it) { double spatial_weight = gaussian_function(static_cast(it->second), spatial_parameter_actual); @@ -123,10 +124,10 @@ } // put smoothed values back again to values pmap. std::vector::iterator smoothed_value_it = smoothed_values.begin(); - for(Facet_const_iterator facet_it = mesh.facets_begin(); - facet_it != mesh.facets_end(); + for(boost::tie(facet_it,fend) = faces(mesh); + facet_it != fend; ++facet_it, ++smoothed_value_it) { - values[facet_it] = *smoothed_value_it; + values[*facet_it] = *smoothed_value_it; } } private: @@ -147,26 +148,27 @@ * * @param mesh `CGAL Polyhedron` on which @a values are defined * @param window_size range of effective neighbors - * @param[in, out] values `ReadWritePropertyMap` with `Polyhedron::Facet_const_handle` as key and `double` as value type + * @param[in, out] values `ReadWritePropertyMap` with `boost::graph_traits::face_handle` as key and `double` as value type */ template void operator()(const Polyhedron& mesh, std::size_t window_size, ValuePropertyMap values) const { - typedef typename Polyhedron::Facet_const_handle Facet_const_handle; - typedef typename Polyhedron::Facet_const_iterator Facet_const_iterator; + typedef typename boost::graph_traits::face_descriptor face_descriptor; + typedef typename boost::graph_traits::face_iterator face_iterator; std::vector smoothed_values; - smoothed_values.reserve(mesh.size_of_facets()); - for(Facet_const_iterator facet_it = mesh.facets_begin(); - facet_it != mesh.facets_end(); ++facet_it) { - std::map neighbors; - NeighborSelector()(facet_it, window_size, + smoothed_values.reserve(num_faces(mesh)); + face_iterator facet_it, fend; + for(boost::tie(facet_it,fend) = faces(mesh); + facet_it != fend; ++facet_it) { + std::map neighbors; + NeighborSelector()(mesh, *facet_it, window_size, neighbors); // gather neighbors in the window std::vector neighbor_values; neighbor_values.reserve(neighbors.size()); - for(typename std::map::iterator it = + for(typename std::map::iterator it = neighbors.begin(); it != neighbors.end(); ++it) { neighbor_values.push_back(values[it->first]); } @@ -184,10 +186,9 @@ } // put smoothed values back again to values pmap. std::vector::iterator smoothed_value_it = smoothed_values.begin(); - for(Facet_const_iterator facet_it = mesh.facets_begin(); - facet_it != mesh.facets_end(); - ++facet_it) { - values[facet_it] = *smoothed_value_it; + for(boost::tie(facet_it,fend) = faces(mesh); + facet_it != fend; ++facet_it) { + values[*facet_it] = *smoothed_value_it; } } }; @@ -224,20 +225,20 @@ class Neighbor_selector_by_edge { private: - typedef typename Polyhedron::Facet::Halfedge_around_facet_const_circulator - Halfedge_around_facet_const_circulator; + typedef ::CGAL::Halfedge_around_face_circulator Halfedge_around_face_circulator; public: - typedef typename Polyhedron::Facet_const_handle Facet_const_handle; + typedef typename boost::graph_traits::face_descriptor face_descriptor; /** * Breadth-first traversal on facets by treating facets, which share a common edge, are 1-level neighbors. * @param facet root facet * @param max_level maximum allowed distance (number of levels) between root facet and visited facet * @param[out] neighbors visited facets and their distances to root facet */ - void operator()(Facet_const_handle facet, + void operator()(const Polyhedron& polyhedron, + face_descriptor facet, std::size_t max_level, - std::map& neighbors) const { - typedef std::pair Facet_level_pair; + std::map& neighbors) const { + typedef std::pair Facet_level_pair; std::queue facet_queue; facet_queue.push(Facet_level_pair(facet, 0)); @@ -250,11 +251,10 @@ while(!facet_queue.empty()) { const Facet_level_pair& pair = facet_queue.front(); - Halfedge_around_facet_const_circulator facet_circulator = - pair.first->facet_begin(); + Halfedge_around_face_circulator facet_circulator(halfedge(pair.first,polyhedron),polyhedron), done(facet_circulator); do { - if(!facet_circulator->opposite()->is_border()) { - Facet_level_pair new_pair(facet_circulator->opposite()->facet(), + if(!(face(opposite(*facet_circulator,polyhedron),polyhedron) == boost::graph_traits::null_face())) { + Facet_level_pair new_pair(face(opposite(*facet_circulator,polyhedron),polyhedron), pair.second + 1); if(neighbors.insert(new_pair).second && new_pair.second < max_level) { // first insert new_pair to map @@ -263,7 +263,7 @@ new_pair); // if its level is equal to max_level do not put it in } // queue since we do not want to traverse its neighbors } - } while(++facet_circulator != pair.first->facet_begin()); + } while(++facet_circulator != done); facet_queue.pop(); } @@ -275,22 +275,22 @@ class Neighbor_selector_by_vertex { private: - typedef typename Polyhedron::Facet::Halfedge_around_vertex_const_circulator - Halfedge_around_vertex_const_circulator; - typedef typename Polyhedron::Halfedge_const_iterator Halfedge_const_iterator; - typedef typename Polyhedron::Vertex_const_iterator Vertex_const_iterator; + typedef ::CGAL::Halfedge_around_target_circulator Halfedge_around_target_circulator; + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::vertex_iterator vertex_iterator; public: - typedef typename Polyhedron::Facet_const_handle Facet_const_handle; + typedef typename boost::graph_traits::face_descriptor face_descriptor; /** * Breadth-first traversal on facets by treating facets, which share a common vertex, are 1-level neighbors. * @param facet root facet * @param max_level maximum allowed distance (number of levels) between root facet and visited facet * @param[out] neighbors visited facets and their distances to root facet */ - void operator()(Facet_const_handle facet, + void operator()(const Polyhedron& polyhedron, + face_descriptor facet, std::size_t max_level, - std::map& neighbors) const { - typedef std::pair Facet_level_pair; + std::map& neighbors) const { + typedef std::pair Facet_level_pair; std::queue facet_queue; facet_queue.push(Facet_level_pair(facet, 0)); @@ -303,15 +303,14 @@ while(!facet_queue.empty()) { const Facet_level_pair& pair = facet_queue.front(); - Facet_const_handle facet_front = pair.first; - Halfedge_const_iterator edge = facet_front->halfedge(); + face_descriptor facet_front = pair.first; + halfedge_descriptor edge = halfedge(facet_front,polyhedron); do { // loop on three vertices of the facet - Vertex_const_iterator vertex = edge->vertex(); - Halfedge_around_vertex_const_circulator vertex_circulator = - vertex->vertex_begin(); + Halfedge_around_target_circulator vertex_circulator(edge,polyhedron), done(vertex_circulator); + do { // for each vertex loop on incoming edges (through those edges loop on neighbor facets which includes the vertex) - if(!vertex_circulator->is_border()) { - Facet_level_pair new_pair(vertex_circulator->opposite()->facet(), + if(!(face(*vertex_circulator,polyhedron) == boost::graph_traits::null_face())) { + Facet_level_pair new_pair(face(opposite(*vertex_circulator,polyhedron),polyhedron), pair.second + 1); if(neighbors.insert(new_pair).second && new_pair.second < max_level) { // first insert new_pair to map @@ -320,8 +319,8 @@ new_pair); // if its level is equal to max_level do not put it in } // queue since we do not want to traverse its childs } - } while(++vertex_circulator != vertex->vertex_begin()); - } while((edge = edge->next()) != facet_front->halfedge()); + } while(++vertex_circulator != done); + } while((edge = next(edge,polyhedron)) != halfedge(facet_front,polyhedron)); facet_queue.pop(); } diff -Nru cgal-4.4/include/CGAL/internal/Surface_mesh_segmentation/K_means_clustering.h cgal-4.5/include/CGAL/internal/Surface_mesh_segmentation/K_means_clustering.h --- cgal-4.4/include/CGAL/internal/Surface_mesh_segmentation/K_means_clustering.h 2014-02-08 20:00:27.000000000 +0000 +++ cgal-4.5/include/CGAL/internal/Surface_mesh_segmentation/K_means_clustering.h 2014-08-29 13:58:17.000000000 +0000 @@ -76,7 +76,7 @@ } } - // To future reference, I also left prev implementation which is a variant of Fisher–Yates shuffle, however to keep `points` intact I use another vector to + // To future reference, I also left prev implementation which is a variant of Fisher–Yates shuffle, however to keep `points` intact I use another vector to // store and swap indices. // where n = number of points; complexity = O(n), memory overhead = O(n) /* diff -Nru cgal-4.4/include/CGAL/internal/Surface_mesh_segmentation/SDF_calculation.h cgal-4.5/include/CGAL/internal/Surface_mesh_segmentation/SDF_calculation.h --- cgal-4.4/include/CGAL/internal/Surface_mesh_segmentation/SDF_calculation.h 2014-02-08 20:00:27.000000000 +0000 +++ cgal-4.5/include/CGAL/internal/Surface_mesh_segmentation/SDF_calculation.h 2014-08-29 13:58:17.000000000 +0000 @@ -62,7 +62,8 @@ * @tparam GeomTraits a model of SegmentationGeomTraits */ template < -class Polyhedron, + class Polyhedron, + class VertexPointPmap, class GeomTraits = typename Polyhedron::Traits, bool fast_bbox_intersection = true > @@ -78,12 +79,10 @@ typedef typename GeomTraits::Segment_3 Segment; typedef typename GeomTraits::FT FT; - typedef typename Polyhedron::Facet Facet; + typedef typename boost::graph_traits::face_iterator face_iterator; + typedef typename boost::graph_traits::face_descriptor face_handle; - typedef typename Polyhedron::Facet_const_iterator Facet_const_iterator; - typedef typename Polyhedron::Facet_const_handle Facet_const_handle; - - typedef AABB_face_graph_triangle_primitive Primitive; + typedef AABB_face_graph_triangle_primitive Primitive; typedef AABB_traits_SDF AABB_traits_internal; typedef typename CGAL::AABB_tree Tree; @@ -104,6 +103,8 @@ // member variables private: GeomTraits traits; + const Polyhedron& mesh; + VertexPointPmap vertex_point_map; typename GeomTraits::Angle_3 angle_functor; typename GeomTraits::Construct_scaled_vector_3 scale_functor; @@ -124,18 +125,23 @@ * @param use_diagonal if true: calculates diagonal of AABB tree and cast segments instead of rays using diagonal length * @param traits trait object */ - SDF_calculation(const Polyhedron& mesh, bool build_kd_tree = false, + SDF_calculation(const Polyhedron& mesh, + VertexPointPmap vertex_point_map, + bool build_kd_tree = false, bool use_diagonal = true, GeomTraits traits = GeomTraits()) : traits(traits), + mesh(mesh), + vertex_point_map(vertex_point_map), angle_functor(traits.angle_3_object()), scale_functor(traits.construct_scaled_vector_3_object()), sum_functor(traits.construct_sum_of_vectors_3_object()), normal_functor(traits.construct_normal_3_object()), translated_point_functor(traits.construct_translated_point_3_object()), centroid_functor(traits.construct_centroid_3_object()), - use_diagonal(use_diagonal) { - tree.insert(mesh.facets_begin(), mesh.facets_end(), mesh); + use_diagonal(use_diagonal) + { + tree.insert(faces(mesh).first, faces(mesh).second, mesh, vertex_point_map); tree.build(); if(build_kd_tree) { @@ -153,38 +159,8 @@ } /** - * Construct AABB tree with meshes inside interval. - * @tparam InputIterator Iterator over polyhedrons. Its value type is `pointer to polyhedron`. - * @param polyhedron_begin range begin - * @param polyhedron_end range past-the-end - * @param build_kd_tree requirement on internal kd-tree (it is only required if find_closest_with_AABB_distance is planned to use) - * @param traits trait object - */ - template - SDF_calculation(InputIterator polyhedron_begin, InputIterator polyhedron_end, - bool build_kd_tree = false, GeomTraits traits = GeomTraits()) - : traits(traits), - angle_functor(traits.angle_3_object()), - scale_functor(traits.construct_scaled_vector_3_object()), - sum_functor(traits.construct_sum_of_vectors_3_object()), - normal_functor(traits.construct_normal_3_object()), - translated_point_functor(traits.construct_translated_point_3_object()), - centroid_functor(traits.construct_centroid_3_object()), - use_diagonal(false) { - for( ; polyhedron_begin != polyhedron_end; ++polyhedron_begin) { - tree.insert((*polyhedron_begin)->facets_begin(), - (*polyhedron_begin)->facets_end()); - } - tree.build(); - - if(build_kd_tree) { - tree.accelerate_distance_queries(); - } - } - - /** * Calculates SDF values for each facet in a range, and stores them in @a sdf_values. Note that sdf values are neither smoothed nor normalized. - * @tparam FacetValueMap `WritablePropertyMap` with `Polyhedron::Facet_const_handle` as key and `double` as value type + * @tparam FacetValueMap `WritablePropertyMap` with `boost::graph_traits::face_handle` as key and `double` as value type * @tparam InputIterator Iterator over polyhedrons. Its value type is `pointer to polyhedron`. * @param facet_begin range begin * @param facet_end range past-the-end @@ -204,13 +180,13 @@ disk_sampler(number_of_rays, std::back_inserter(disk_samples)); for( ; facet_begin != facet_end; ++facet_begin) { - boost::optional sdf_value = calculate_sdf_value_of_facet(facet_begin, + boost::optional sdf_value = calculate_sdf_value_of_facet(*facet_begin, cone_angle, true, disk_samples); if(sdf_value) { - sdf_values[facet_begin] = *sdf_value; + sdf_values[*facet_begin] = *sdf_value; } else { - sdf_values[facet_begin] = -1.0; + sdf_values[*facet_begin] = -1.0; } } } @@ -374,21 +350,22 @@ * @return calculated SDF value */ boost::optional calculate_sdf_value_of_facet( - Facet_const_handle facet, + face_handle facet, double cone_angle, bool accept_if_acute, const Disk_samples_list& disk_samples) const { - const Point& p1 = facet->halfedge()->vertex()->point(); - const Point& p2 = facet->halfedge()->next()->vertex()->point(); - const Point& p3 = facet->halfedge()->prev()->vertex()->point(); + + const Point p1 = get(vertex_point_map,target(halfedge(facet,mesh),mesh)); + const Point p2 = get(vertex_point_map,target(next(halfedge(facet,mesh),mesh),mesh)); + const Point p3 = get(vertex_point_map,target(prev(halfedge(facet,mesh),mesh),mesh)); const Point center = centroid_functor(p1, p2, p3); Vector normal = normal_functor(p2, p1, p3); normal=scale_functor(normal, FT(1.0/std::sqrt(to_double(normal.squared_length())))); - CGAL::internal::SkipPrimitiveFunctor + CGAL::internal::SkipPrimitiveFunctor skip(facet); - CGAL::internal::FirstIntersectionVisitor + CGAL::internal::FirstIntersectionVisitor visitor; return calculate_sdf_value_of_point(center, normal, skip, visitor, cone_angle, @@ -454,9 +431,9 @@ if(accept_if_acute) { // check whether the ray makes acute angle with intersected facet - const Point& min_v1 = min_id->halfedge()->vertex()->point(); - const Point& min_v2 = min_id->halfedge()->next()->vertex()->point(); - const Point& min_v3 = min_id->halfedge()->prev()->vertex()->point(); + const Point& min_v1 = get(vertex_point_map,target(halfedge(min_id,mesh),mesh)); + const Point& min_v2 = get(vertex_point_map,target(next(halfedge(min_id,mesh),mesh),mesh)); + const Point& min_v3 = get(vertex_point_map,target(prev(halfedge(min_id,mesh),mesh),mesh)); Vector min_normal = scale_functor(normal_functor(min_v1, min_v2, min_v3), -1.0); if(angle_functor(translated_point_functor(Point(ORIGIN), min_i_ray), diff -Nru cgal-4.4/include/CGAL/internal/Surface_mesh_segmentation/Surface_mesh_segmentation.h cgal-4.5/include/CGAL/internal/Surface_mesh_segmentation/Surface_mesh_segmentation.h --- cgal-4.4/include/CGAL/internal/Surface_mesh_segmentation/Surface_mesh_segmentation.h 2014-02-08 20:00:27.000000000 +0000 +++ cgal-4.5/include/CGAL/internal/Surface_mesh_segmentation/Surface_mesh_segmentation.h 2014-08-29 13:58:17.000000000 +0000 @@ -45,10 +45,8 @@ template class Postprocess_sdf_values { - - typedef typename Polyhedron::Facet Facet; - typedef typename Polyhedron::Facet_const_handle Facet_const_handle; - typedef typename Polyhedron::Facet_const_iterator Facet_const_iterator; + typedef typename boost::graph_traits::face_descriptor face_descriptor; + typedef typename boost::graph_traits::face_iterator face_iterator; typedef Bilateral_filtering Default_filter; @@ -73,48 +71,49 @@ * Sdf values on these facets are assigned to average sdf value of its neighbors. * If still there is any facet which has no sdf value, assigns minimum sdf value to it. * This is meaningful since (being an outlier) zero sdf values might effect normalization & log extremely. - * @param[in, out] sdf_values `ReadWritePropertyMap` with `Polyhedron::Facet_const_handle` as key and `double` as value type + * @param[in, out] sdf_values `ReadWritePropertyMap` with `Polyhedron::face_descriptor` as key and `double` as value type */ template void check_missing_sdf_values(const Polyhedron& mesh, SDFPropertyMap sdf_values) { - std::vector still_missing_facets; + std::vector still_missing_facets; double min_sdf = (std::numeric_limits::max)(); // If there is any facet which has no sdf value, assign average sdf value of its neighbors - for(Facet_const_iterator facet_it = mesh.facets_begin(); - facet_it != mesh.facets_end(); ++facet_it) { - double sdf_value = sdf_values[facet_it]; + face_iterator facet_it, fend; + for(boost::tie(facet_it,fend) = faces(mesh); + facet_it != fend; ++facet_it) { + double sdf_value = sdf_values[*facet_it]; CGAL_assertion(sdf_value == -1 || sdf_value >= 0); // validity check if(sdf_value != -1.0) { min_sdf = (std::min)(sdf_value, min_sdf); continue; } - typename Facet::Halfedge_around_facet_const_circulator facet_circulator = - facet_it->facet_begin(); + Halfedge_around_face_circulator facet_circulator(halfedge(*facet_it,mesh),mesh), done(facet_circulator); + double total_neighbor_sdf = 0.0; std::size_t nb_valid_neighbors = 0; do { - if(!facet_circulator->opposite()->is_border()) { - double neighbor_sdf = sdf_values[facet_circulator->opposite()->facet()]; + if(!(face(opposite(*facet_circulator,mesh),mesh) == boost::graph_traits::null_face())) { + double neighbor_sdf = sdf_values[face(opposite(*facet_circulator,mesh),mesh)]; if(neighbor_sdf != -1) { total_neighbor_sdf += neighbor_sdf; ++nb_valid_neighbors; } } - } while( ++facet_circulator != facet_it->facet_begin()); + } while( ++facet_circulator != done); if(nb_valid_neighbors == 0) { - still_missing_facets.push_back(facet_it); + still_missing_facets.push_back(*facet_it); } else { sdf_value = total_neighbor_sdf / nb_valid_neighbors; - sdf_values[facet_it] = sdf_value; + sdf_values[*facet_it] = sdf_value; // trying to update min_sdf is pointless, since it is interpolated one of the neighbors sdf will be smaller than it } } // If still there is any facet which has no sdf value, assign minimum sdf value. // This is meaningful since (being an outlier) 0 sdf values might effect normalization & log extremely. - for(typename std::vector::iterator it = + for(typename std::vector::iterator it = still_missing_facets.begin(); it != still_missing_facets.end(); ++it) { sdf_values[*it] = min_sdf; @@ -126,9 +125,10 @@ SDFPropertyMap sdf_values) { double min_sdf = (std::numeric_limits::max)(); double max_sdf = -min_sdf; - for(Facet_const_iterator facet_it = mesh.facets_begin(); - facet_it != mesh.facets_end(); ++facet_it) { - double sdf_value = sdf_values[facet_it]; + face_iterator facet_it, fend; + for(boost::tie(facet_it,fend) = faces(mesh); + facet_it != fend; ++facet_it) { + double sdf_value = sdf_values[*facet_it]; max_sdf = (std::max)(sdf_value, max_sdf); min_sdf = (std::min)(sdf_value, min_sdf); } @@ -136,7 +136,7 @@ } /** * Normalize sdf values between [0-1]. - * @param sdf_values `ReadWritePropertyMap` with `Polyhedron::Facet_const_handle` as key and `double` as value type + * @param sdf_values `ReadWritePropertyMap` with `Polyhedron::face_descriptor` as key and `double` as value type * @return minimum and maximum SDF values before normalization */ template @@ -151,9 +151,10 @@ } const double max_min_dif = max_sdf - min_sdf; - for(Facet_const_iterator facet_it = mesh.facets_begin(); - facet_it != mesh.facets_end(); ++facet_it) { - sdf_values[facet_it] = (sdf_values[facet_it] - min_sdf) / max_min_dif; + face_iterator facet_it, fend; + for(boost::tie(facet_it,fend) = faces(mesh); + facet_it != fend; ++facet_it) { + sdf_values[*facet_it] = (sdf_values[*facet_it] - min_sdf) / max_min_dif; } return std::make_pair(min_sdf, max_sdf); } @@ -168,7 +169,7 @@ * - ... */ std::size_t get_window_size(const Polyhedron& mesh) { - double facet_sqrt = std::sqrt(mesh.size_of_facets() / 2000.0); + double facet_sqrt = std::sqrt(num_faces(mesh) / 2000.0); return static_cast(facet_sqrt) + 1; } }; @@ -195,6 +196,7 @@ template < class Polyhedron, class GeomTraits, + class VertexPointPmap, bool fast_bbox_intersection = true, #ifndef CGAL_DO_NOT_USE_BOYKOV_KOLMOGOROV_MAXFLOW_SOFTWARE class GraphCut = Alpha_expansion_graph_cut_boykov_kolmogorov, @@ -207,36 +209,35 @@ { //type definitions public: - typedef typename Polyhedron::Facet_const_handle Facet_const_handle; + typedef typename boost::graph_traits::face_descriptor face_descriptor; private: //typedef typename Polyhedron::Traits Kernel; typedef typename GeomTraits::Point_3 Point; - typedef typename Polyhedron::Facet Facet; - - typedef typename Polyhedron::Edge_const_iterator Edge_const_iterator; - typedef typename Polyhedron::Halfedge_const_handle Halfedge_const_handle; - typedef typename Polyhedron::Halfedge_const_iterator Halfedge_const_iterator; - typedef typename Polyhedron::Facet_const_iterator Facet_const_iterator; - typedef typename Polyhedron::Vertex_const_iterator Vertex_const_iterator; + typedef typename boost::graph_traits::edge_iterator edge_iterator; + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::halfedge_iterator halfedge_iterator; + typedef typename boost::graph_traits::face_iterator face_iterator; + typedef typename boost::graph_traits::vertex_iterator vertex_iterator; - typedef SDF_calculation + typedef SDF_calculation SDF_calculation_class; // member variables private: const Polyhedron& mesh; GeomTraits traits; + VertexPointPmap vertex_point_pmap; // member functions public: /** * @pre @a polyhedron.is_pure_triangle() * @param mesh `CGAL Polyhedron` on which other functions operate. */ - Surface_mesh_segmentation(const Polyhedron& mesh, GeomTraits traits) - : mesh(mesh), traits(traits) { - CGAL_precondition(mesh.is_pure_triangle()); + Surface_mesh_segmentation(const Polyhedron& mesh, GeomTraits traits, VertexPointPmap vertex_point_pmap) + : mesh(mesh), traits(traits), vertex_point_pmap(vertex_point_pmap) { + // CGAL_precondition(is_pure_triangle(mesh)); } // Use these two functions together @@ -245,8 +246,8 @@ calculate_sdf_values(double cone_angle, std::size_t number_of_rays, SDFPropertyMap sdf_pmap, bool postprocess_req) { // calculate sdf values - SDF_calculation_class sdf_calculator(mesh, false, true, traits); - sdf_calculator.calculate_sdf_values(mesh.facets_begin(), mesh.facets_end(), + SDF_calculation_class sdf_calculator(mesh, vertex_point_pmap, false, true, traits); + sdf_calculator.calculate_sdf_values(faces(mesh).first, faces(mesh).second, cone_angle, number_of_rays, sdf_pmap); Postprocess_sdf_values p; @@ -287,10 +288,11 @@ // apply graph cut GraphCut()(edges, edge_weights, probability_matrix, labels); std::vector::iterator label_it = labels.begin(); - for(Facet_const_iterator facet_it = mesh.facets_begin(); - facet_it != mesh.facets_end(); + face_iterator facet_it, fend; + for(boost::tie(facet_it,fend) = faces(mesh); + facet_it != fend; ++facet_it, ++label_it) { - segment_pmap[facet_it] = *label_it; // fill with cluster-ids + segment_pmap[*facet_it] = *label_it; // fill with cluster-ids } if(clusters_to_segments) { // assign a segment id for each facet @@ -310,16 +312,18 @@ * @param edge whose dihedral angle is computed using incident facets * @return computed dihedral angle */ - double calculate_dihedral_angle_of_edge(Halfedge_const_handle edge) const { - CGAL_precondition(!edge->is_border_edge()); - const Point& a = edge->vertex()->point(); - const Point& b = edge->prev()->vertex()->point(); - const Point& c = edge->next()->vertex()->point(); - const Point& d = edge->opposite()->next()->vertex()->point(); + double calculate_dihedral_angle_of_edge(halfedge_descriptor edge) const { + + CGAL_precondition( (! (face(edge,mesh)==boost::graph_traits::null_face())) + && (! (face(opposite(edge,mesh),mesh)==boost::graph_traits::null_face())) ); + const Point a = get(vertex_point_pmap,target(edge,mesh)); + const Point b = get(vertex_point_pmap,target(prev(edge,mesh),mesh)); + const Point c = get(vertex_point_pmap,target(next(edge,mesh),mesh)); + const Point d = get(vertex_point_pmap,target(next(opposite(edge,mesh),mesh),mesh)); // As far as I check: if, say, dihedral angle is 5, this returns 175, // if dihedral angle is -5, this returns -175. // Another words this function returns angle between planes. - double n_angle = to_double( Mesh_3::dihedral_angle(a, b, c, d) ); + double n_angle = to_double( ::CGAL::Mesh_3::dihedral_angle(a, b, c, d) ); n_angle /= 180.0; bool concave = n_angle > 0; double angle = 1 + ((concave ? -1 : +1) * n_angle); @@ -333,17 +337,18 @@ /** * Normalize sdf values using function: * normalized_sdf = log( alpha * ( current_sdf - min_sdf ) / ( max_sdf - min_sdf ) + 1 ) / log( alpha + 1 ) - * @param sdf_values `ReadablePropertyMap` with `Polyhedron::Facet_const_handle` as key and `double` as value type + * @param sdf_values `ReadablePropertyMap` with `Polyhedron::face_descriptor` as key and `double` as value type * @param[out] normalized_sdf_values normalized values stored in facet iteration order * Important note: @a sdf_values parameter should contain linearly normalized values between [0-1] */ template void log_normalize_sdf_values(SDFPropertyMap sdf_values, std::vector& normalized_sdf_values) { - normalized_sdf_values.reserve(mesh.size_of_facets()); - for(Facet_const_iterator facet_it = mesh.facets_begin(); - facet_it != mesh.facets_end(); ++facet_it) { - double log_normalized = log(sdf_values[facet_it] * CGAL_NORMALIZATION_ALPHA + + normalized_sdf_values.reserve(num_faces(mesh)); + face_iterator facet_it, fend; + for(boost::tie(facet_it,fend) = faces(mesh); + facet_it != fend; ++facet_it) { + double log_normalized = log(sdf_values[*facet_it] * CGAL_NORMALIZATION_ALPHA + 1) / log(CGAL_NORMALIZATION_ALPHA + 1); normalized_sdf_values.push_back(log_normalized); } @@ -376,32 +381,37 @@ * @param[out] edge_weights calculated weight for each edge in @a edges */ void calculate_and_log_normalize_dihedral_angles(double smoothing_lambda, - std::vector >& edges, + std::vector >& a_edges, std::vector& edge_weights) const { // associate each facet with an id // important note: ids should be compatible with iteration order of facets: // [0 <- facet_begin(),...., size_of_facets() -1 <- facet_end()] // Why ? it is send to graph cut algorithm where other data associated with facets are also sorted according to iteration order. - std::map facet_index_map; + std::map facet_index_map; std::size_t facet_index = 0; - for(Facet_const_iterator facet_it = mesh.facets_begin(); - facet_it != mesh.facets_end(); + face_iterator facet_it, fend; + for(boost::tie(facet_it,fend) = faces(mesh); + facet_it != fend; ++facet_it, ++facet_index) { - facet_index_map[facet_it] = facet_index; + facet_index_map[*facet_it] = facet_index; } const double epsilon = 5e-6; // edges and their weights. pair stores facet-id pairs (see above) (may be using boost::tuple can be more suitable) - for(Edge_const_iterator edge_it = mesh.edges_begin(); - edge_it != mesh.edges_end(); ++edge_it) { - if(edge_it->is_border_edge()) { + edge_iterator edge_it, eend; + for(boost::tie(edge_it,eend) = edges(mesh); + edge_it != eend; ++edge_it) { + halfedge_descriptor hd = halfedge(*edge_it,mesh); + halfedge_descriptor ohd = opposite(hd,mesh); + if((face(hd,mesh)==boost::graph_traits::null_face()) + || (face(ohd,mesh)==boost::graph_traits::null_face())) { continue; // if edge does not contain two neighbor facets then do not include it in graph-cut } - const std::size_t index_f1 = facet_index_map[edge_it->facet()]; - const std::size_t index_f2 = facet_index_map[edge_it->opposite()->facet()]; - edges.push_back(std::make_pair(index_f1, index_f2)); + const std::size_t index_f1 = facet_index_map[face(hd,mesh)]; + const std::size_t index_f2 = facet_index_map[face(ohd,mesh)]; + a_edges.push_back(std::make_pair(index_f1, index_f2)); - double angle = calculate_dihedral_angle_of_edge(edge_it); + double angle = calculate_dihedral_angle_of_edge(hd); angle = (std::max)(angle, epsilon); angle = -log(angle); @@ -432,8 +442,8 @@ * set of connected facets which are placed under same cluster. Note that returned segment-ids are ordered by average sdf value of segment ascen. * * @param number_of_clusters cluster-ids in @a segments should be between [0, number_of_clusters -1] - * @param sdf_values `ReadablePropertyMap` with `Polyhedron::Facet_const_handle` as key and `double` as value type - * @param[in, out] segments `ReadWritePropertyMap` with `Polyhedron::Facet_const_handle` as key and `std::size_t` as value type. + * @param sdf_values `ReadablePropertyMap` with `Polyhedron::face_descriptor` as key and `double` as value type + * @param[in, out] segments `ReadWritePropertyMap` with `Polyhedron::face_descriptor` as key and `std::size_t` as value type. * @return number of segments */ template @@ -442,12 +452,12 @@ // assign a segment-id to each facet std::size_t segment_id = number_of_clusters; std::vector > segments_with_average_sdf_values; - - for(Facet_const_iterator facet_it = mesh.facets_begin(); - facet_it != mesh.facets_end(); ++facet_it) { - if(segments[facet_it] < + face_iterator facet_it, fend; + for(boost::tie(facet_it,fend) = faces(mesh); + facet_it != fend; ++facet_it) { + if(segments[*facet_it] < number_of_clusters) { // not visited by depth_first_traversal - double average_sdf_value = breadth_first_traversal(facet_it, segment_id, + double average_sdf_value = breadth_first_traversal(*facet_it, segment_id, sdf_values, segments); segments_with_average_sdf_values.push_back(std::make_pair(segment_id, @@ -470,10 +480,10 @@ } // make one-pass on facets. First make segment-id zero based by subtracting number_of_clusters // . Then place its sorted index to pmap - for(Facet_const_iterator facet_it = mesh.facets_begin(); - facet_it != mesh.facets_end(); ++facet_it) { - std::size_t segment_id = segments[facet_it] - number_of_clusters; - segments[facet_it] = segment_id_to_sorted_id_map[segment_id]; + for(boost::tie(facet_it,fend) = faces(mesh); + facet_it != fend; ++facet_it) { + std::size_t segment_id = segments[*facet_it] - number_of_clusters; + segments[*facet_it] = segment_id_to_sorted_id_map[segment_id]; } return segment_id - number_of_clusters; } @@ -483,15 +493,15 @@ * Each visited facet assigned to @a segment_id. * @param facet root facet * @param segment_id segment-id of root facet - * @param sdf_values `ReadablePropertyMap` with `Polyhedron::Facet_const_handle` as key and `double` as value type - * @param[in, out] segments `ReadWritePropertyMap` with `Polyhedron::Facet_const_handle` as key and `std::size_t` as value type. + * @param sdf_values `ReadablePropertyMap` with `Polyhedron::face_descriptor` as key and `double` as value type + * @param[in, out] segments `ReadWritePropertyMap` with `Polyhedron::face_descriptor` as key and `std::size_t` as value type. * @return average sdf value for segment */ template double - breadth_first_traversal(Facet_const_handle root, std::size_t segment_id, + breadth_first_traversal(face_descriptor root, std::size_t segment_id, SDFProperyMap sdf_values, SegmentPropertyMap segments) { - std::queue facet_queue; + std::queue facet_queue; facet_queue.push(root); std::size_t prev_segment_id = segments[root]; @@ -501,15 +511,14 @@ std::size_t visited_facet_count = 1; while(!facet_queue.empty()) { - Facet_const_handle facet = facet_queue.front(); + face_descriptor facet = facet_queue.front(); - typename Facet::Halfedge_around_facet_const_circulator facet_circulator = - facet->facet_begin(); + Halfedge_around_face_circulator facet_circulator(halfedge(facet,mesh),mesh), done(facet_circulator); do { - if(facet_circulator->opposite()->is_border()) { + if(face(opposite(*facet_circulator,mesh),mesh)==boost::graph_traits::null_face()) { continue; // no facet to traversal } - Facet_const_handle neighbor = facet_circulator->opposite()->facet(); + face_descriptor neighbor = face(opposite(*facet_circulator,mesh),mesh); if(prev_segment_id == segments[neighbor]) { segments[neighbor] = segment_id; facet_queue.push(neighbor); @@ -517,7 +526,7 @@ total_sdf_value += sdf_values[neighbor]; ++visited_facet_count; } - } while( ++facet_circulator != facet->facet_begin()); + } while( ++facet_circulator != done); facet_queue.pop(); } diff -Nru cgal-4.4/include/CGAL/internal/Surface_modeling/Spokes_and_rims_iterator.h cgal-4.5/include/CGAL/internal/Surface_modeling/Spokes_and_rims_iterator.h --- cgal-4.4/include/CGAL/internal/Surface_modeling/Spokes_and_rims_iterator.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/internal/Surface_modeling/Spokes_and_rims_iterator.h 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,81 @@ +// Copyright (c) 2014 GeometryFactory +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// $URL:$ +// $Id:$ +// +// Author(s) : Ilker O. Yaz + +#ifndef CGAL_SURFACE_MODELING_SPOKES_AND_RIMS_ITERATOR_H +#define CGAL_SURFACE_MODELING_SPOKES_AND_RIMS_ITERATOR_H +/// @cond CGAL_DOCUMENT_INTERNAL + +namespace CGAL { +namespace internal { +/** + * Currently this class is not used by surface modeling package, just leave it for possible future need. + * Provide simple functionality for iterating over spoke and rim edges + * - use get_descriptor() to obtain active edge + * - get_iterator() always holds spoke edges */ + /// \code + /// // how to use Spokes_and_rims_iterator + /// boost::tie(e_begin, e_end) = out_edges(vertex, halfedge_graph); + /// Spokes_and_rims_iterator rims_it(e_begin, halfedge_graph); + /// + /// for ( ; rims_it.get_iterator() != e_end; ++rims_it ) + /// { + /// halfedge_descriptor active_hedge = rims_it.get_descriptor(); + /// // use active_edge as you like + /// } + /// \endcode +template +class Spokes_and_rims_iterator +{ +public: + typedef typename boost::graph_traits::out_edge_iterator out_edge_iterator; + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + + Spokes_and_rims_iterator(out_edge_iterator edge_iterator, HalfedgeGraph& halfedge_graph) + : is_current_rim(false), iterator(edge_iterator), descriptor(halfedge(*edge_iterator)), halfedge_graph(halfedge_graph) + { } + + /// descriptor will be assigned to next valid edge, note that iterator might not change + Spokes_and_rims_iterator& + operator++() + { + // loop through one spoke then one rim edge + if(!is_current_rim && !is_border(descriptor, halfedge_graph)) // it is rim edge's turn + { + is_current_rim = true; + descriptor = next(descriptor, halfedge_graph); + } + else // if current edge is rim OR there is no rim edge (current spoke edge is boudary) + { // then iterate to next spoke edge + is_current_rim = false; + descriptor = halfedge(*(++iterator)); + } + return *this; + } + + out_edge_iterator get_iterator() { return iterator; } + edge_descriptor get_descriptor() { return descriptor; } + +private: + bool is_current_rim; ///< current descriptor is rim or spoke + out_edge_iterator iterator; ///< holds spoke edges (i.e. descriptor is not always = *iterator) + halfedge_descriptor descriptor; ///< current active halfedge descriptor for looping + HalfedgeGraph& halfedge_graph; +}; + +}//namespace internal +/// @endcond +}//namespace CGAL +#endif //CGAL_SURFACE_MODELING_SPOKES_AND_RIMS_ITERATOR_H diff -Nru cgal-4.4/include/CGAL/internal/Surface_modeling/Weights.h cgal-4.5/include/CGAL/internal/Surface_modeling/Weights.h --- cgal-4.4/include/CGAL/internal/Surface_modeling/Weights.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/internal/Surface_modeling/Weights.h 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,309 @@ +// Copyright (c) 2014 GeometryFactory +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Ilker O. Yaz + +#ifndef CGAL_SURFACE_MODELING_WEIGHTS_H +#define CGAL_SURFACE_MODELING_WEIGHTS_H +/// @cond CGAL_DOCUMENT_INTERNAL + +#include +#include +typedef CGAL::Simple_cartesian::Vector_3 Vector; + +namespace CGAL { +namespace internal { + +template +Vector to_vector(const Point& b, const Point& a) { + return Vector(a[0] - b[0], a[1] - b[1], a[2] - b[2]); +} + +// Returns the cotangent value of half angle v0 v1 v2 +// using formula in -[Meyer02] Discrete Differential-Geometry Operators for- page 19 +// The potential problem with previous one (Cotangent_value) is that it does not produce symmetric results +// (i.e. for v0, v1, v2 and v2, v1, v0 returned cot weights can be slightly different) +// This one provides stable results. +template +class Cotangent_value_Meyer +{ +public: + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + + typedef HalfedgeGraph Halfedge_graph; + + template + double operator()(vertex_descriptor v0, vertex_descriptor v1, vertex_descriptor v2, VertexPointMap vpm) + { + const Vector& a = to_vector(get(vpm, v1), get(vpm, v0)); + const Vector& b = to_vector(get(vpm, v1), get(vpm, v2)); + + double dot_ab = a*b; + Vector cross_ab = CGAL::cross_product(a, b); + double divider = std::sqrt(cross_ab*cross_ab); + + if(divider == 0 /*|| divider != divider*/) + { + this->collinear(get(vpm, v0), get(vpm, v1), get(vpm, v2)) ? + CGAL_warning(!"Infinite Cotangent value with degenerate triangle!") : + CGAL_warning(!"Infinite Cotangent value due to floating point arithmetic!"); + + return dot_ab > 0 ? (std::numeric_limits::max)() : + -(std::numeric_limits::max)(); + } + + return dot_ab / divider; + } + + /////////////////////////////////////////////////////////////////////////////////////// + // WARNING: this two functions are just used when cotangent weight turns out to be +-inf, + // just for raising a proper warning message (i.e nothing functional) + template + bool collinear(const Point&, const Point&, const Point&) { + return true; + } + template + bool collinear(const CGAL::Point_3& a, const CGAL::Point_3& b, const CGAL::Point_3& c) { + return CGAL::collinear(a, b, c); + } + /////////////////////////////////////////////////////////////////////////////////////// + +}; + +// Returns the cotangent value of half angle v0 v1 v2 by clamping between [1, 89] degrees +// as suggested by -[Friedel] Unconstrained Spherical Parameterization- +template > +class Cotangent_value_clamped : CotangentValue +{ +public: + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + + typedef HalfedgeGraph Halfedge_graph; + + template + double operator()(vertex_descriptor v0, vertex_descriptor v1, vertex_descriptor v2, VertexPointMap vpm) + { + const double cot_1 = 57.289962; + const double cot_89 = 0.017455; + double value = CotangentValue::operator()(v0, v1, v2, vpm); + return (std::max)(cot_89, (std::min)(value, cot_1)); + } +}; + +template > +class Cotangent_value_minimum_zero : CotangentValue +{ +public: + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + + template + double operator()(vertex_descriptor v0, vertex_descriptor v1, vertex_descriptor v2, VertexPointMap vpm) + { + double value = CotangentValue::operator()(v0, v1, v2, vpm); + return (std::max)(0.0, value); + } +}; + + +///////////////////////////// Halfedge Weight Calculators /////////////////////////////////// +// Cotangent weight calculator +// Cotangent_value: as suggested by -[Sorkine07] ARAP Surface Modeling- +// Cotangent_value_area_weighted: as suggested by -[Mullen08] Spectral Conformal Parameterization- +template > +class Cotangent_weight : CotangentValue +{ +public: + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef HalfedgeGraph Halfedge_graph; + // Returns the cotangent weight of specified halfedge_descriptor + // Edge orientation is trivial + template + double operator()(halfedge_descriptor he, HalfedgeGraph& halfedge_graph, VertexPointMap vpm) + { + vertex_descriptor v0 = target(he, halfedge_graph); + vertex_descriptor v1 = source(he, halfedge_graph); + // Only one triangle for border edges + if ( is_border(he, halfedge_graph) || + is_border(opposite(he, halfedge_graph), halfedge_graph) ) + { + halfedge_descriptor he_cw = opposite( next(he, halfedge_graph), halfedge_graph ); + vertex_descriptor v2 = source(he_cw, halfedge_graph); + if ( is_border(he_cw, halfedge_graph) || + is_border(opposite(he_cw, halfedge_graph), halfedge_graph) ) + { + halfedge_descriptor he_ccw = prev( opposite(he, halfedge_graph), halfedge_graph ); + v2 = source(he_ccw, halfedge_graph); + } + return ( CotangentValue::operator()(v0, v2, v1, vpm)/2.0 ); + } + else + { + halfedge_descriptor he_cw = opposite( next(he, halfedge_graph), halfedge_graph ); + vertex_descriptor v2 = source(he_cw, halfedge_graph); + halfedge_descriptor he_ccw = prev( opposite(he, halfedge_graph), halfedge_graph ); + vertex_descriptor v3 = source(he_ccw, halfedge_graph); + + return ( CotangentValue::operator()(v0, v2, v1, vpm)/2.0 + CotangentValue::operator()(v0, v3, v1, vpm)/2.0 ); + } + } +}; + +// Single cotangent from -[Chao10] Simple Geometric Model for Elastic Deformation +template > +class Single_cotangent_weight : CotangentValue +{ +public: + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef HalfedgeGraph Halfedge_graph; + + // Returns the cotangent of the opposite angle of the halfedge + // 0 for border edges (which does not have an opposite angle) + template + double operator()(halfedge_descriptor he, HalfedgeGraph& halfedge_graph, VertexPointMap vpm) + { + if(is_border(he, halfedge_graph)) { return 0.0;} + + vertex_descriptor v0 = target(he, halfedge_graph); + vertex_descriptor v1 = source(he, halfedge_graph); + + vertex_descriptor v_op = target(next(he, halfedge_graph), halfedge_graph); + return CotangentValue::operator()(v0, v_op, v1, vpm); + } +}; + +// Mean value calculator described in -[Floater04] Mean Value Coordinates- +// WARNING: Need to be updated to use point pmap +template +class Mean_value_weight +{ +public: + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef HalfedgeGraph Halfedge_graph; + + // Returns the mean-value coordinate of specified halfedge_descriptor + // Returns different value for different halfedge orientation (which is a normal behaviour according to formula) + double operator()(halfedge_descriptor he, HalfedgeGraph& halfedge_graph) + { + vertex_descriptor v0 = target(he, halfedge_graph); + vertex_descriptor v1 = source(he, halfedge_graph); + Vector vec(v1->point(), v0->point()); + double norm = std::sqrt( vec.squared_length() ); + + // Only one triangle for border edges + if ( is_border(he, halfedge_graph) || + is_border( opposite(he, halfedge_graph), halfedge_graph) ) + { + halfedge_descriptor he_cw = opposite( next(he, halfedge_graph), halfedge_graph ); + vertex_descriptor v2 = source(he_cw, halfedge_graph); + if ( is_border(he_cw, halfedge_graph) || + is_border(opposite(he_cw, halfedge_graph), halfedge_graph) ) + { + halfedge_descriptor he_ccw = prev( opposite(he, halfedge_graph), halfedge_graph ); + v2 = source(he_ccw, halfedge_graph); + } + + return ( half_tan_value_2(v1, v0, v2)/norm); + } + else + { + halfedge_descriptor he_cw = opposite( next(he, halfedge_graph), halfedge_graph ); + vertex_descriptor v2 = source(he_cw, halfedge_graph); + halfedge_descriptor he_ccw = prev( opposite(he, halfedge_graph), halfedge_graph ); + vertex_descriptor v3 = source(he_ccw, halfedge_graph); + + return ( half_tan_value_2(v1, v0, v2)/norm + half_tan_value_2(v1, v0, v3)/norm); + } + } + +private: + // Returns the tangent value of half angle v0_v1_v2/2 + double half_tan_value(vertex_descriptor v0, vertex_descriptor v1, vertex_descriptor v2) + { + Vector vec0(v2->point(), v1->point()); + Vector vec1(v0->point(), v2->point()); + Vector vec2(v1->point(), v0->point()); + double e0_square = vec0.squared_length(); + double e1_square = vec1.squared_length(); + double e2_square = vec2.squared_length(); + double e0 = std::sqrt(e0_square); + double e2 = std::sqrt(e2_square); + double cos_angle = ( e0_square + e2_square - e1_square ) / 2.0 / e0 / e2; + cos_angle = (std::max)(-1.0, (std::min)(1.0, cos_angle)); // clamp into [-1, 1] + double angle = acos(cos_angle); + + return ( tan(angle/2.0) ); + } + + // My deviation built on Meyer_02 + double half_tan_value_2(vertex_descriptor v0, vertex_descriptor v1, vertex_descriptor v2) + { + Vector a(v1->point(), v0->point()); + Vector b(v1->point(), v2->point()); + double dot_ab = a[0]*b[0] + a[1]*b[1] + a[2]*b[2]; + double dot_aa = a.squared_length(); + double dot_bb = b.squared_length(); + double dot_aa_bb = dot_aa * dot_bb; + + double cos_rep = dot_ab; + double sin_rep = std::sqrt(dot_aa_bb - dot_ab * dot_ab); + double normalizer = std::sqrt(dot_aa_bb); // |a|*|b| + + return (normalizer - cos_rep) / sin_rep; // formula from [Floater04] page 4 + // tan(Q/2) = (1 - cos(Q)) / sin(Q) + } +}; + +template< class HalfedgeGraph, + class PrimaryWeight = Cotangent_weight, + class SecondaryWeight = Mean_value_weight > +class Hybrid_weight : public PrimaryWeight, SecondaryWeight +{ +public: + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef HalfedgeGraph Halfedge_graph; + + double operator()(halfedge_descriptor he, HalfedgeGraph& halfedge_graph) + { + double weight = PrimaryWeight::operator()(he, halfedge_graph); + //if(weight < 0) { std::cout << "Negative weight" << std::endl; } + return (weight >= 0) ? weight : SecondaryWeight::operator()(he, halfedge_graph); + } +}; + +// Trivial uniform weights (created for test purposes) +template +class Uniform_weight +{ +public: + typedef HalfedgeGraph Halfedge_graph; + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + + double operator()(halfedge_descriptor /*he*/, HalfedgeGraph& /*halfedge_graph*/) + { return 1.0; } +}; + + + +}//namespace internal +/// @endcond +}//namespace CGAL +#endif //CGAL_SURFACE_MODELING_WEIGHTS_H diff -Nru cgal-4.4/include/CGAL/intersection_of_Polyhedra_3.h cgal-4.5/include/CGAL/intersection_of_Polyhedra_3.h --- cgal-4.4/include/CGAL/intersection_of_Polyhedra_3.h 2013-11-30 20:00:27.000000000 +0000 +++ cgal-4.5/include/CGAL/intersection_of_Polyhedra_3.h 2014-08-29 13:58:16.000000000 +0000 @@ -186,8 +186,8 @@ Order_along_a_halfedge(Halfedge_handle hedge_,const Nodes_vector& nodes_):nodes(nodes_),hedge(hedge_){} bool operator()(int i,int j) const { //returns true, iff q lies strictly between p and r. + typename Nodes_vector::Protector p; try{ - typename Nodes_vector::Protector p; CGAL::internal::use(p); return CGAL::collinear_are_strictly_ordered_along_line(nodes.to_interval(hedge->vertex()->point()), diff -Nru cgal-4.4/include/CGAL/Interval_nt.h cgal-4.5/include/CGAL/Interval_nt.h --- cgal-4.4/include/CGAL/Interval_nt.h 2013-03-07 20:00:26.000000000 +0000 +++ cgal-4.5/include/CGAL/Interval_nt.h 2014-08-29 13:58:16.000000000 +0000 @@ -272,105 +272,6 @@ { return ! (a == b); } -// Mixed operators with int. - -template -inline -Uncertain -operator<(int a, const Interval_nt &b) -{ - if (a < b.inf()) return true; - if (a >= b.sup()) return false; - return Uncertain::indeterminate(); -} - -template -inline -Uncertain -operator>(int a, const Interval_nt &b) -{ return b < a; } - -template -inline -Uncertain -operator<=(int a, const Interval_nt &b) -{ - if (a <= b.inf()) return true; - if (a > b.sup()) return false; - return Uncertain::indeterminate(); -} - -template -inline -Uncertain -operator>=(int a, const Interval_nt &b) -{ return b <= a; } - -template -inline -Uncertain -operator==(int a, const Interval_nt &b) -{ - if (b.inf() > a || b.sup() < a) return false; - if (b.inf() == a && b.sup() == a) return true; - return Uncertain::indeterminate(); -} - -template -inline -Uncertain -operator!=(int a, const Interval_nt &b) -{ return ! (a == b); } - -template -inline -Uncertain -operator<(const Interval_nt &a, int b) -{ - if (a.sup() < b) return true; - if (a.inf() >= b) return false; - return Uncertain::indeterminate(); -} - -template -inline -Uncertain -operator>(const Interval_nt &a, int b) -{ return b < a; } - -template -inline -Uncertain -operator<=(const Interval_nt &a, int b) -{ - if (a.sup() <= b) return true; - if (a.inf() > b) return false; - return Uncertain::indeterminate(); -} - -template -inline -Uncertain -operator>=(const Interval_nt &a, int b) -{ return b <= a; } - -template -inline -Uncertain -operator==(const Interval_nt &a, int b) -{ - if (b > a.sup() || b < a.inf()) return false; - if (b == a.sup() && b == a.inf()) return true; - return Uncertain::indeterminate(); -} - -template -inline -Uncertain -operator!=(const Interval_nt &a, int b) -{ return ! (a == b); } - - // Mixed operators with double. template @@ -620,22 +521,6 @@ return a+Interval_nt(b); } -template -inline -Interval_nt -operator+ (int a, const Interval_nt & b) -{ - return Interval_nt(a)+b; -} - -template -inline -Interval_nt -operator+ (const Interval_nt & a, int b) -{ - return a+Interval_nt(b); -} - template< bool Protected > inline Interval_nt @@ -672,22 +557,6 @@ template inline Interval_nt -operator- (int a, const Interval_nt & b) -{ - return Interval_nt(a)-b; -} - -template -inline -Interval_nt -operator- (const Interval_nt & a, int b) -{ - return a-Interval_nt(b); -} - -template -inline -Interval_nt operator* (const Interval_nt &a, const Interval_nt & b) { typedef Interval_nt IA; @@ -756,22 +625,6 @@ template inline Interval_nt -operator* (int a, const Interval_nt & b) -{ - return Interval_nt(a)*b; -} - -template -inline -Interval_nt -operator* (const Interval_nt & a, int b) -{ - return a*Interval_nt(b); -} - -template -inline -Interval_nt operator/ (const Interval_nt &a, const Interval_nt & b) { typedef Interval_nt IA; @@ -826,22 +679,6 @@ return a/Interval_nt(b); } -template -inline -Interval_nt -operator/ (int a, const Interval_nt & b) -{ - return Interval_nt(a)/b; -} - -template -inline -Interval_nt -operator/ (const Interval_nt & a, int b) -{ - return a/Interval_nt(b); -} - // TODO: What about these two guys? Where do they belong to? template struct Min > @@ -1433,6 +1270,7 @@ typedef CGAL::Interval_nt Nested; static inline Real epsilon() { return 0; } + static inline Real dummy_precision() { return 0; } // Costs could depend on b. enum { diff -Nru cgal-4.4/include/CGAL/IO/File_maya.h cgal-4.5/include/CGAL/IO/File_maya.h --- cgal-4.4/include/CGAL/IO/File_maya.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/IO/File_maya.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,323 @@ +// Copyright (c) 2012 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL: $ +// $Id: $ +// +// +// Author(s) : Clement Jamin + +#ifndef CGAL_IO_FILE_MAYA_H +#define CGAL_IO_FILE_MAYA_H + +#include +#include +#include +#include +#include +#include +#include + +namespace CGAL { + +//------------------------------------------------------- +// IO functions +//------------------------------------------------------- + +template +void +output_to_maya(std::ostream& os, + const C3T3& c3t3, + bool surfaceOnly = true) +{ + typedef typename C3T3::Triangulation Tr; + typedef typename C3T3::Facets_in_complex_iterator Facet_iterator; + typedef typename C3T3::Cells_in_complex_iterator Cell_iterator; + + typedef typename Tr::Finite_vertices_iterator Finite_vertices_iterator; + typedef typename Tr::Vertex_handle Vertex_handle; + typedef typename Tr::Point Point_3; + +#ifdef CGAL_MESH_3_IO_VERBOSE + std::cerr << "Output to maya:\n"; +#endif + + const Tr& tr = c3t3.triangulation(); + + //------------------------------------------------------- + // File output + //------------------------------------------------------- + + //------------------------------------------------------- + // Header + //------------------------------------------------------- + os << std::setprecision(20); + + os << "//Maya ASCII 2011 scene" << std::endl; + os << "//Name: testMaya3.ma" << std::endl; + os << "//Last modified: Wed, Jan 25, 2012 05:54:26 PM" << std::endl; + os << "//Codeset: 1252" << std::endl; + os << "requires maya \"2011\";" << std::endl; + os << "currentUnit -l centimeter -a degree -t film;" << std::endl; + os << "fileInfo \"application\" \"maya\";" << std::endl; + os << "fileInfo \"product\" \"Maya 2011\";" << std::endl; + os << "fileInfo \"version\" \"2011\";" << std::endl; + os << "fileInfo \"cutIdentifier\" \"201003190014-771504\";" << std::endl; + os << "fileInfo \"license\" \"education\";" << std::endl; + + std::string name = "Mesh_3"; + os << "createNode mesh -n \"" << name << "Shape\" -p \"" << name << "\";" << std::endl; + os << " setAttr -k off \".v\";" << std::endl; + os << " setAttr \".uvst[0].uvsn\" -type \"string\" \"map1\";" << std::endl; + os << " setAttr \".cuvs\" -type \"string\" \"map1\";" << std::endl; + os << " setAttr \".dcol\" yes;" << std::endl; + os << " setAttr \".dcc\" -type \"string\" \"Ambient+Diffuse\";" << std::endl; + + os << " connectAttr \"" << name << "Shape.iog\" \":initialShadingGroup.dsm\" -na;\n\n"; + + //------------------------------------------------------- + // Colors + //------------------------------------------------------ + + /*os << " setAttr \".ccls\" -type \"string\" \"colorSet\";\n"; + os << " setAttr \".clst[0].clsn\" -type \"string\" \"colorSet\";\n"; + os << " setAttr \".clst[0].rprt\" 3;\n"; + os << " setAttr -s " << 3 << " \".clst[0].clsp[0:" << 3-1 << "]\"" << std::endl; + os << " 10 50 250" << std::endl; + os << " 100 250 50" << std::endl; + os << " 0 200 200" << std::endl; + os << " ;\n";*/ + + //------------------------------------------------------- + // Vertices + //------------------------------------------------------ + + std::map V; + std::stringstream vertices_sstr; + int num_vertices = 0; + for( Finite_vertices_iterator vit = tr.finite_vertices_begin(); + vit != tr.finite_vertices_end(); + ++vit) + { + if ( (surfaceOnly && c3t3.in_dimension(vit) <= 2) + || !surfaceOnly) + { + V[vit] = num_vertices++; + Point_3 p = vit->point(); + vertices_sstr << " " << CGAL::to_double(p.x()) << " " << CGAL::to_double(p.y()) << " " << CGAL::to_double(p.z()) << std::endl; + } + } + + os << " setAttr -s " << num_vertices << " \".vt[0:" << num_vertices-1 << "]\"" << std::endl; + os << vertices_sstr.str(); + os << ";\n"; + + /* + // Triangles + os << "setAttr -s " << QString().setNum(number_of_triangles) << " \".fc[0:" << QString().setNum(number_of_triangles-1) << "]\" -type \"polyFaces\" \n"; + for (int i=0;i > EdgeList; + EdgeList edges; + + // Surface only + if (surfaceOnly) + { + facets_sstr << " setAttr -s " << number_of_triangles + << " \".fc[0:" << number_of_triangles-1 << "]\" -type \"polyFaces\" \n"; + int c = 0; + for( Facet_iterator fit = c3t3.facets_in_complex_begin(); + fit != c3t3.facets_in_complex_end(); + ++fit, ++c) + { + int indices[3]; + //Point_3 points[3]; + facets_sstr << " f 3 "; + for (int j = 0, i = (fit->second + 1) % 4 ; j < 3 ; i = (i+1)%4, ++j) + { + const Vertex_handle& vh = fit->first->vertex(i); + indices[j] = V[vh]; + //points[j] = vh->point(); + } + + // Reverse triangle orientation? + bool reverse_triangle = + (fit->second % 2 == 0 && !c3t3.is_in_complex(fit->first)) + || (fit->second % 2 != 0 && c3t3.is_in_complex(fit->first)); + if (reverse_triangle) + { + std::swap(indices[1], indices[2]); + //std::swap(points[1], points[2]); + } + //Kernel::Vector_3 n = cross_product(points[1] - points[0], points[2] - points[0]); + //n = n / CGAL::sqrt(n*n); + // Add the normal 3 times + //normals_sstr << " " << n.x() << " " << n.y() << " " << n.z() << std::endl; + //normals_sstr << " " << n.x() << " " << n.y() << " " << n.z() << std::endl; + //normals_sstr << " " << n.x() << " " << n.y() << " " << n.z() << std::endl; + + // 3 edges + for (int i = 0 ; i < 3 ; ++i) + { + std::pair edge = std::make_pair( + (std::min)(indices[i], indices[(i+1)%3]), + (std::max)(indices[i], indices[(i+1)%3])); + size_t pos = std::find(edges.begin(), edges.end(), edge) - edges.begin(); + if (pos == edges.size()) // Not found? + { + edges.push_back(edge); + } + // ith edge of triangle + facets_sstr << pos << " "; + } + + // 1 triangles + facets_sstr << std::endl; + // Colors + //facets_sstr << " mc 0 3 " << rand()%3 << " " << rand()%3 << " " << rand()%3 << std::endl; + } + } + // Tetrahedra = 4 facets for each + else + { + facets_sstr << " setAttr -s " << 4*c3t3.number_of_cells_in_complex() + << " \".fc[0:" << 4*c3t3.number_of_cells_in_complex()-1 << "]\" -type \"polyFaces\" \n"; + int c = 0; + for( Cell_iterator cit = c3t3.cells_in_complex_begin(); + cit != c3t3.cells_in_complex_end(); + ++cit, ++c) + { + for (int facet_i = 0 ; facet_i < 4 ; ++facet_i) + { + int indices[3]; + //Point_3 points[3]; + facets_sstr << " f 3 "; + for (int j = 0, i = (facet_i + 1) % 4 ; j < 3 ; i = (i+1)%4, ++j) + { + const Vertex_handle& vh = cit->vertex(i); + indices[j] = V[vh]; + //points[j] = vh->point(); + } + + // Reverse triangle orientation? + bool reverse_triangle = (facet_i % 2 != 0 && c3t3.is_in_complex(cit, facet_i)); + if (reverse_triangle) + { + std::swap(indices[1], indices[2]); + //std::swap(points[1], points[2]); + } + //Kernel::Vector_3 n = cross_product(points[1] - points[0], points[2] - points[0]); + //n = n / CGAL::sqrt(n*n); + // Add the normal 3 times + //normals_sstr << " " << n.x() << " " << n.y() << " " << n.z() << std::endl; + //normals_sstr << " " << n.x() << " " << n.y() << " " << n.z() << std::endl; + //normals_sstr << " " << n.x() << " " << n.y() << " " << n.z() << std::endl; + + // 3 edges + for (int i = 0 ; i < 3 ; ++i) + { + std::pair edge = std::make_pair( + (std::min)(indices[i], indices[(i+1)%3]), + (std::max)(indices[i], indices[(i+1)%3])); + size_t pos = std::find(edges.begin(), edges.end(), edge) - edges.begin(); + if (pos == edges.size()) // Not found? + { + edges.push_back(edge); + } + // ith edge of triangle + facets_sstr << pos << " "; + } + + // 1 triangles + facets_sstr << std::endl; + // Colors + //facets_sstr << " mc 0 3 " << rand()%3 << " " << rand()%3 << " " << rand()%3 << std::endl; + } + } + } + facets_sstr << ";\n\n"; + //normals_sstr << ";\n\n"; + + //------------------------------------------------------- + // Edges + //------------------------------------------------------- + os << " setAttr -s " << edges.size() << " \".ed[0:" + << edges.size() - 1 << "]\"" << std::endl; + + for (EdgeList::const_iterator it = edges.begin(), it_end = edges.end() ; it != it_end ; ++it) + os << " " << it->first << " " << it->second << " " << 0 << std::endl; + + os << ";\n"; + + //------------------------------------------------------- + // Normals + //------------------------------------------------------- + + //os << normals_sstr.str(); + + //------------------------------------------------------- + // Facets + //------------------------------------------------------- + + os << facets_sstr.str(); + + //------------------------------------------------------- + // Tetrahedra + //------------------------------------------------------- + /*os << "Tetrahedra" << std::endl + << c3t3.number_of_cells_in_complex() << std::endl; + + for( Cell_iterator cit = c3t3.cells_in_complex_begin() ; + cit != c3t3.cells_in_complex_end() ; + ++cit ) + { + for (int i=0; i<4; i++) + os << V[cit->vertex(i)] << " "; + + os << get(cell_pmap, cit) << std::endl; + }*/ + + //------------------------------------------------------- + // End + //------------------------------------------------------- + +#ifdef CGAL_MESH_3_IO_VERBOSE + std::cerr << "done.\n"; +#endif +} // end output_to_maya(...) + +} // end namespace CGAL + +#endif // CGAL_IO_FILE_MAYA_H diff -Nru cgal-4.4/include/CGAL/IO/File_scanner_OFF.h cgal-4.5/include/CGAL/IO/File_scanner_OFF.h --- cgal-4.4/include/CGAL/IO/File_scanner_OFF.h 2012-11-13 13:14:01.000000000 +0000 +++ cgal-4.5/include/CGAL/IO/File_scanner_OFF.h 2014-08-29 13:58:17.000000000 +0000 @@ -172,9 +172,11 @@ } } else { skip_comment(); - m_in >> x >> y >> z; + extract(m_in, x); + extract(m_in, y); + extract(m_in, z); if ( is_homogeneous()) - m_in >> w; + extract(m_in, w); } } void scan_vertex( int& x, int& y, int& z, int& w) { diff -Nru cgal-4.4/include/CGAL/IO/io.h cgal-4.5/include/CGAL/IO/io.h --- cgal-4.4/include/CGAL/IO/io.h 2012-11-13 13:14:01.000000000 +0000 +++ cgal-4.5/include/CGAL/IO/io.h 2014-08-29 13:58:17.000000000 +0000 @@ -26,6 +26,9 @@ #ifndef CGAL_IO_H #define CGAL_IO_H + +#include +#include #include #include #include @@ -164,6 +167,19 @@ bool is_binary(std::ios& i); + + inline std::istream& extract(std::istream& is, double &d) +{ +#if defined( _MSC_VER ) && ( _MSC_VER > 1600 ) + std::string s; + is >> s; + sscanf(s.c_str(), "%lf", &d); +#else + is >> d; +#endif + return is; +} + template < class T > inline void diff -Nru cgal-4.4/include/CGAL/is_iterator.h cgal-4.5/include/CGAL/is_iterator.h --- cgal-4.4/include/CGAL/is_iterator.h 2013-09-28 19:00:44.000000000 +0000 +++ cgal-4.5/include/CGAL/is_iterator.h 2014-08-29 13:58:17.000000000 +0000 @@ -68,6 +68,13 @@ template struct is_iterator_type : internal::is_iterator_type_::type>::type,Tag> {}; +template ::value> struct is_iterator_to { + enum { value=false }; +}; +template struct is_iterator_to : + boost::is_convertible::value_type,U> +{ }; + } #endif // CGAL_IS_ITERATOR_H diff -Nru cgal-4.4/include/CGAL/iterator_from_indices.h cgal-4.5/include/CGAL/iterator_from_indices.h --- cgal-4.4/include/CGAL/iterator_from_indices.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/iterator_from_indices.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,75 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_ITERATOR_FROM_INDICES_H +#define CGAL_ITERATOR_FROM_INDICES_H +#include +#include +namespace CGAL { +template +struct Default_coordinate_access { + typedef Ref_ result_type; + template Ref_ operator()(T const& t, std::ptrdiff_t i)const{ + return t[i]; + } +}; + +//TODO: default type for Value_: typename same_cv::type::value_type>::type +template ()[0]) +#else + Value_& +#endif + , class Coord_access = Default_coordinate_access + > +class Iterator_from_indices +: public boost::iterator_facade, + Value_, std::bidirectional_iterator_tag, Ref_> +{ + friend class boost::iterator_core_access; + //FIXME: use int to save space + //TODO: use a tuple to save space when Coord_access is empty + typedef std::ptrdiff_t index_t; + Container_* cont; + index_t index; + Coord_access ca; + void increment(){ ++index; } + void decrement(){ --index; } + void advance(std::ptrdiff_t n){ index+=n; } + ptrdiff_t distance_to(Iterator_from_indices const& other)const{ + return other.index-index; + } + bool equal(Iterator_from_indices const& other)const{ + return index==other.index; + } + Ref_ dereference()const{ + //FIXME: use the functor properly + //Uh, and what did I mean by that? + return ca(*cont,index); + } + public: + Iterator_from_indices(Container_& cont_,std::size_t n) + : cont(&cont_), index(n) {} + template + Iterator_from_indices(Container_& cont_,std::size_t n,T const&t) + : cont(&cont_), index(n), ca(t) {} +}; +} +#endif // CGAL_ITERATOR_FROM_INDICES_H diff -Nru cgal-4.4/include/CGAL/iterator.h cgal-4.5/include/CGAL/iterator.h --- cgal-4.4/include/CGAL/iterator.h 2014-03-29 20:00:20.000000000 +0000 +++ cgal-4.5/include/CGAL/iterator.h 2014-08-29 13:58:17.000000000 +0000 @@ -495,6 +495,8 @@ template < class I, class P > bool operator==(const Filter_iterator&, const Filter_iterator&); +template < class I, class P > +bool operator<(const Filter_iterator&, const Filter_iterator&); template < class I, class P > struct Filter_iterator { @@ -552,15 +554,17 @@ --(*this); return tmp; } - + reference operator*() const { return *c_; } pointer operator->() const { return &*c_; } const Predicate& predicate() const { return p_; } Iterator base() const { return c_; } + Iterator end() const { return e_; } bool is_end() const { return (c_ == e_); } friend bool operator== <>(const Self&, const Self&); + friend bool operator< <>(const Self&, const Self&); }; template < class I, class P > @@ -583,6 +587,14 @@ } template < class I, class P > +inline +bool operator<(const Filter_iterator& it1, + const Filter_iterator& it2) +{ + return it1.base() < it2.base(); +} + +template < class I, class P > inline bool operator!=(const Filter_iterator& it1, const Filter_iterator& it2) diff -Nru cgal-4.4/include/CGAL/iterator_range.h cgal-4.5/include/CGAL/iterator_range.h --- cgal-4.4/include/CGAL/iterator_range.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/iterator_range.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,60 @@ +// Copyright (c) 2014 GeometryFactory (France). All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Andreas Fabri + +#ifndef CGAL_ITERATOR_RANGE_H +#define CGAL_ITERATOR_RANGE_H + +#include +#include + +namespace CGAL { + + template + class iterator_range + : public std::pair{ + + typedef std::pair Base; + + public: + + typedef I iterator; + typedef const I const_iterator; + + iterator_range(I b, I e) + : Base(b,e) + {} + + iterator_range(const std::pair& ip) + : Base(ip) + {} + + const I& begin() const + { + return this->first; + } + + const I& end() const + { + return this->second; + } +}; + +} // namespace CGAL + +#endif // CGAL_ITERATOR_RANGE_H diff -Nru cgal-4.4/include/CGAL/kdtree_d.h cgal-4.5/include/CGAL/kdtree_d.h --- cgal-4.4/include/CGAL/kdtree_d.h 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/include/CGAL/kdtree_d.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,1060 +0,0 @@ -// Copyright (c) 1997 Tel-Aviv University (Israel). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org). -// You can redistribute it and/or modify it under the terms of the GNU -// General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -// -// $URL$ -// $Id$ -// -// -// Author(s) : Sariel Har-Peled (sariel@math.tau.ac.il) -// Eyal Flato (flato@math.tau.ac.il) - -#ifndef CGAL_KDTREE_D_H -#define CGAL_KDTREE_D_H - -#include -#include -#include -#include -using std::list; // to avoid compiler crash on MSVC++ - -namespace CGAL { - -/*======================================================================= - * Kdtree_interface - - * This is the default interface of point. It assume that PT (the - * point type have the following properties: - * default constructor - * int dimension() - * const coord_type & operator[]( int ) const - * ... operator=( const Pt & ) - copy operator -\*=======================================================================*/ - -template -class Kdtree_interface -{ -public: - typedef PT Point; - - static int dimension( const PT & pnt ) - { - // return pnt.dimensions(); - return pnt.dimension(); - } - - static int compare( int d, const PT & a, const PT & b ) - { - if ( a[ d ] < b[ d ] ) - return -1; - if ( a[ d ] > b[ d ] ) - return 1; - - return 0; - } - static void copy_coord( int d, PT & a, const PT & b ) - { - a[ d ] = b[ d ]; - } -}; - - - -template -class Kdtree_interface_2d -{ -public: - typedef PT Point; - - static int dimension( const PT & pnt ) - { - // return pnt.dimensions(); - return pnt.dimension(); - } - - static int compare( int d, const PT & a, const PT & b ) - { - if ( a[ d ] < b[ d ] ) - return -1; - if ( a[ d ] > b[ d ] ) - return 1; - - return 0; - } - static void copy_coord( int d, PT & a, const PT & b ) - { - if ( d == 0 ) - a = PT( b[ 0 ], a[1] ); - else - if ( d == 1 ) - a = PT( a[ 0 ], b[1] ); - else { - CGAL_error(); - } - } -}; - - -template -class Kdtree_interface_3d -{ -public: - typedef PT Point; - - static int dimension( const PT & pnt ) - { - // return pnt.dimensions(); - return pnt.dimension(); - } - - static int compare( int d, const PT & a, const PT & b ) - { - if ( a[ d ] < b[ d ] ) - return -1; - if ( a[ d ] > b[ d ] ) - return 1; - - return 0; - } - static void copy_coord( int d, PT & a, const PT & b ) - { - if ( d == 0 ) - a = PT( b[ 0 ], a[1], a[ 2 ] ); - else - if ( d == 1 ) - a = PT( a[ 0 ], b[1], a[ 2 ] ); - else - if ( d == 2 ) - a = PT( a[ 0 ], a[1], b[ 2 ] ); - else { - CGAL_error(); - } - } -}; - - -/*========================================================================= - * kdtree_d - - * A the kdtree class. - * - * Remark: The kd-trees allocates all the memory it needs in advance, - * This results in a rather efficient memory management, and a fast - * iplementation. -\*=========================================================================*/ -template -class Kdtree_d -{ - class Plane; - -public: - typedef typename Traits::Point Point; - typedef list List_points; - - - //------------------------------------------------------------------------- - // Extended_Point_d - - // A class for representing an extended d-dimal point: with - // ability to support +/- infinity. Templated by the kd-treee interface - // type. - //------------------------------------------------------------------------- - class ExtPoint - { - private: - class coordinate_type - { - public: - const Point * p_pnt; - int type; - //signed char type; - }; - - coordinate_type * p_arr; - int dim; - Point def_pnt; - - void init( int _dim ) - { - CGAL_precondition( _dim > 0 ); - dim = _dim; - - p_arr = (coordinate_type *)std::malloc( sizeof( coordinate_type ) - * dim ); - //printf( "p_arr(new): %p\n", (void *)p_arr ); - CGAL_assertion( p_arr != NULL ); - - std::memset( p_arr, 0, sizeof( coordinate_type ) * dim ); - } - - public: - enum { MINUS_INFINITY = -1, FINITE = 0, PLUS_INFINITY = 1 }; - - ExtPoint( int _type, int _dim ) - { - CGAL_precondition( _type == MINUS_INFINITY || _type == PLUS_INFINITY ); - init( _dim ); - - for ( int ind = 0; ind < dim; ind++ ) - p_arr[ ind ].type = _type; - } - - ExtPoint() - { - p_arr = NULL; - dim = -1; - } - - ExtPoint( const ExtPoint & p ) - { - init( p.dim ); - - def_pnt = p.def_pnt; - for ( int ind = 0; ind < dim; ind++ ) { - p_arr[ ind ] = p.p_arr[ ind ]; - if ( p.p_arr[ ind ].p_pnt == &p.def_pnt ) - p_arr[ ind ].p_pnt = &def_pnt; - } - } - - ExtPoint & operator=( const ExtPoint & p ) - { - term(); - - init( p.dim ); - - def_pnt = p.def_pnt; - for ( int ind = 0; ind < dim; ind++ ) { - p_arr[ ind ] = p.p_arr[ ind ]; - if ( p.p_arr[ ind ].p_pnt == &p.def_pnt ) - p_arr[ ind ].p_pnt = &def_pnt; - } - - return *this; - } - - ExtPoint( const Point & point, int _dim ) - { - init( _dim ); - - def_pnt = point; - for ( int ind = 0; ind < _dim; ind++ ) { - p_arr[ ind ].p_pnt = &def_pnt; - p_arr[ ind ].type = FINITE; - } - } - - void term() - { - if ( p_arr != NULL ) { - //printf( "a: %p\n", p_arr ); - std::free( p_arr ); - //printf( "_a\n" ); - p_arr = NULL; - } - dim = 0; - } - - ~ExtPoint() - { - term(); - } - - void set_coord( int k, Point & point ) - { - CGAL_precondition( 0 <= k && k < dim ); - - p_arr[ k ].type = FINITE; - //p_arr[ k ].p_pnt = &point; - - Traits::copy_coord( k, def_pnt, point ); - p_arr[ k ].p_pnt = &def_pnt; - } - - void set_coord( int k, const ExtPoint & point ) - { - CGAL_precondition( 0 <= k && k < dim ); - CGAL_precondition( 0 <= k && k < point.dim ); - - p_arr[ k ] = point.p_arr[ k ]; - if ( p_arr[ k ].type == FINITE ) { - Traits::copy_coord( k, def_pnt, *(p_arr[ k ].p_pnt) ); - p_arr[ k ].p_pnt = &def_pnt; - } - } - - int compare( int k, const ExtPoint & point ) const - { - CGAL_precondition( 0 <= k && k < dim ); - // the following does not compile on msvc++... - // coordinate_type & a( p_arr[ k ] ), - // & b( point.p_arr[ k ] ); - coordinate_type & a = p_arr[ k ]; - coordinate_type & b = point.p_arr[ k ]; - - if ( a.type != FINITE ) { - if ( b.type != FINITE ) { - return a.type - b.type; - } else { - return a.type; - } - } else { - if ( b.type != FINITE ) - return -b.type; - else - return Traits::compare( k, *a.p_pnt, *b.p_pnt ); - } - } - - - int compare_vector( const ExtPoint & point ) const - { - int ind, res; - - for ( ind = 0; ind < dim; ind++ ) { - res = compare( ind, point ); - if ( res != 0 ) - return res; - } - - return 0; - } - - int compare( int k, const Point & point ) const - { - CGAL_precondition( 0 <= k && k < dim ); - - // coordinate_type & a( p_arr[ k ] ); - coordinate_type & a = p_arr[ k ]; - - if ( a.type != FINITE ) - return a.type; - else - return Traits::compare( k, *a.p_pnt, point ); - } - - int dimension() const - { - return dim; - } - - int get_coord_status( int d ) const - { - CGAL_precondition( 0 <= d && d < dim ); - - return p_arr[ d ].type; - } - - - const Point * get_coord_point( int d ) const - { - CGAL_precondition( 0 <= d && d < dim ); - - return p_arr[ d ].p_pnt; - } - }; - - - // Box - represents an axis parallel box. - class Box - { - public: - int dim; - ExtPoint left, right; - - private: - friend class Plane; - - ExtPoint & get_vertex( bool f_left ) - { - return f_left? left : right; - } - - public: - // constructors - - //CHECK - Box() - { - } - - Box( const Box & box ) - { - dim = box.dim; - left = box.left; - right = box.right; - } - - - Box( const Point &l, const Point &r, int _dim ) - { - dim = _dim; - left = ExtPoint( l, dim ); - right = ExtPoint( r, dim ); - } - - Box( int _dim ) : left( ExtPoint::MINUS_INFINITY, _dim ), - right( ExtPoint::PLUS_INFINITY, _dim ) - { - dim = _dim; - } - - - // data access - void set_left( Point &l) - { - left = ExtPoint( l, dim ); - }; - - void set_right( Point &r) - { - right = ExtPoint( r, dim ); - } - - const ExtPoint &get_left() const - { - return left; - } - - const ExtPoint &get_right() const - { - return right; - } - - - void set_coord_left( int k, Point & p ) - { - left.set_coord( k, p ); - } - - - void set_coord_right( int k, Point & p ) - { - right.set_coord( k, p ); - } - - - // operations - bool is_in( const Box &o) const - // checks if o is completely inside - { - int dim = left.dimension(); - - for (int i = 0; i < dim; i++) - { - if ( (left.compare(i, o.get_left()) > 0 ) - || (right.compare(i, o.get_right()) < 0 ) ) - return false; - } - - return true; - } - - - bool is_in( const Point & o ) const - // checks if o is completely inside - { - int _dim = left.dimension(); - for (int i = 0; i < _dim; i++) - { - if ( (left.compare( i, o ) > 0 ) || - (right.compare( i, o ) <= 0 ) ) - return false; - } - return true; - } - - - bool is_coord_in_range( int k, const Point & o ) const - // checks if o is completely inside - { - return ( ! ( (left.compare( k, o ) > 0 ) - || (right.compare( k, o ) <= 0 ) ) ); - } - - - bool is_intersect( const Box &o) const - // checks if there is an intersection between o and this - { - int dim = left.dimension(); - for (int i = 0; i < dim; i++) - { - if ( (left.compare(i, o.get_right()) >= 0) || - (right.compare(i, o.get_left()) <= 0) ) - return false; - } - return true; - } - - - // checks if there is an intersection between o and this box - // only in a specific coordinate... - bool is_intersect_in_dim( int d, const Box & o ) const - { - return (! ( (left.compare( d, o.get_right() ) >= 0 ) - || (right.compare( d, o.get_left() ) <= 0) )); - } - - - // checks if there is an intersection between o and this box - // only in a specific coordinate... - bool is_intersect_in_dim_closed( int d, const Box & o ) const - { - return (! ( (left.compare( d, o.get_right() ) > 0 ) - || (right.compare( d, o.get_left() ) < 0) )); - } - - - bool intersect(Box &o) - // intersects this with o. the intersection will be in this - // returns false if intersection is empty - { - int dim = left.dimension(); - for (int i = 0; i < dim; i++) - { - // left is the maximal of the lefts - if (left.compare(i, o.get_left()) == -1) - left.set_coord(i, o.get_left()); - - // right is the minimal of the rights - if (right.compare(i, o.get_right()) == 1) - right.set_coord(i, o.get_right()); - } - return !(is_empty()); - } - - bool is_empty() const - // return true if this is not an interval (left[k] > right[k]) - { - int dim = left.dimension(); - for (int i = 0; i < dim; i++) - { - if (left.compare(i, right) == 1) - return true; - } - return false; - } - - bool is_empty_open() const - // return true if this is not an interval (left[k] > right[k]) - { - int dim = left.dimension(); - for (int i = 0; i < dim; i++) - { - if ( left.compare(i, right) >= 0 ) - return true; - } - return false; - } - - int comp( const Box & o ) const - { - int res; - - res = left.compare_vector( o.left ); - if ( res != 0 ) - return res; - - return right.compare_vector( o.right ); - } - // destructor - needed in ...recursive ... DVP - - ~Box() - { - left.term(); - right.term(); - dim = 0; - } - - }; - - -private: - class Plane - { - private: - int coord; - Point * normal; - bool f_plus; // orientation of half space - // is (0, 0, ... , +inifinity, 0, ..., 0) inside plane - - public: - Plane() - { - normal = NULL; - coord = 0; - } - - Plane( int k, Point & p ) - { - normal = &p; - coord = k; - } - - Plane( const Plane & p ) - { - coord = p.coord; - normal = p.normal; - } - - void dump( void ) - { - std::cout << "(" << coord << ": " << *normal << ")"; - } - - bool is_in( const Point & p ) const - { - int cmp; - - cmp = Traits::compare( coord, p, *normal ); - - if ( ! f_plus ) - cmp = -cmp; - - return cmp >= 0; - } - - void set_plane(int k, Point &p) - { - coord = k; - normal = &p; - //normal->copy( coord, p ); - } - - void split( Box & region, bool f_neg ) - { - ExtPoint * p_p = &(region.get_vertex( ! f_neg )); - - if ( f_neg ) { - if ( p_p->compare( coord, *normal ) > 0 ) - p_p->set_coord( coord, *normal ); - } else - if ( p_p->compare( coord, *normal ) < 0 ) - p_p->set_coord( coord, *normal ); - } - - void orient_half_space( bool f_neg_side ) - { - f_plus = ! f_neg_side; - } - - int get_coord() const - { - return coord; - } - }; - -private: - class Node - { - public: - Plane plane; - Point * pnt; - - Node * left, * right; - - enum { LEFT, RIGHT }; - - const Plane & get_hs( int side ) const - { - - ((Plane *)&plane)->orient_half_space( side == LEFT ); - - return plane; - } - - - bool is_points_in_hs( const Plane & pl ) const - { - if ( is_point() ) - return pl.is_in( *pnt ); - - if ( left != NULL && ( ! left->is_points_in_hs( pl ) ) ) - return false; - if ( right != NULL && ( ! right->is_points_in_hs( pl ) ) ) - return false; - - return true; - } - - - bool is_valid() const - { - if ( is_point() ) - return true; - - if ( left != NULL ) - if ( ! left->is_points_in_hs( get_hs( LEFT ) ) ) - return false; - if ( right != NULL ) - if ( ! right->is_points_in_hs( get_hs( RIGHT ) ) ) - return false; - - return true; - } - - - void dump( int depth ) - { - int ind; - - for ( ind = 0; ind < depth; ind++ ) - std::cout << " "; - - if ( is_point() ) { - std::cout << *pnt << "\n"; - return; - } - - plane.dump(); - std::cout << "\n"; - left->dump( depth + 1 ); - for ( ind = 0; ind < depth; ind++ ) - std::cout << " "; - - std::cout << "!!!!!!!!!!!!\n"; - right->dump( depth + 1 ); - } - - bool is_point() const - { - return ((left == NULL) && (right == NULL)); - } - - typedef std::back_insert_iterator back_iter; - - Node() : plane() - { - left = right = NULL; - } - - void copy_subtree_points( back_iter & result, - const Box & rect ) - { - if ( is_point() ) { - if ( rect.is_in( *pnt ) ) - (*result++) = *pnt; - return; - } - if ( left != NULL ) - left->copy_subtree_points( result, rect ); - if ( right != NULL ) - right->copy_subtree_points( result, rect ); - } - - static void search_recursive( back_iter & result, - Node * node, - const Box & rect, - Box & _region, - Plane & plane, - bool f_split_plus ) - { - //printf( "search_recusrive\n" ); - Box * p_r = new Box( _region ); - - //printf( "z" ); - //fflush( stdout ); - - plane.split( *p_r, f_split_plus ); - - //printf( "c" ); - //fflush( stdout ); - CGAL_precondition( node != NULL ); - - //printf( "b" ); - //fflush( stdout ); - if ( rect.is_in( *p_r ) ) - { - //printf( "5" ); - //fflush( stdout ); - node->copy_subtree_points( result, rect ); - //printf( "\tsearch_recursive done...\n" ); - //printf( "6" ); - //fflush( stdout ); - delete p_r; - return; - } - - //printf( "v" ); - //fflush( stdout ); - - if ( rect.is_intersect_in_dim_closed( plane.get_coord(), *p_r ) ) - node->search( result, rect, *p_r ); - //printf( "x" ); - //fflush( stdout ); - delete p_r; - } - - void search( std::back_insert_iterator result, - const Box &rect, Box ®ion ) - { - if (is_point()) { - if ( rect.is_in( *pnt ) ) - (*result++) = *pnt; - return; - } - - //this is not a point so it is a hypeplane - if ( left != NULL ) - search_recursive( result, left, rect, - region, plane, true ); - if ( right != NULL ) - search_recursive( result, right, rect, - region, plane, false ); - } - }; - - typedef Point * Point_ptr; - - int size; - Point * p_arr_pt; - Node *root; - int dim; - - Node * p_node_arr; - int node_count; - - Node * malloc_node( void ) - { - Node * p_ret; - - p_ret = &(p_node_arr[ node_count ]); - node_count++; - - CGAL_assertion( node_count <= ( 2 * size )); - - *p_ret = Node(); - - return p_ret; - } - - static int comp( const Point & a, const Point & b, int dim ) - { - return Traits::compare( dim, a, b ); - } - - static int partition( Point_ptr * arr, int left, int right, - Point * p_pivot, int dim ) - { - int i, j; - Point_ptr tmp; - - if ( left >= right ) - return left; - - i = left; - j = right; - - while ( i < j ) { - if ( comp( *(arr[ i ]), *(arr[ j ]), dim ) > 0 ) { - tmp = arr[ i ]; - arr[ i ] = arr[ j ]; - arr[ j ] = tmp; - } - if ( comp( *(arr[ i ]), *p_pivot, dim ) < 0 ) { - i++; - } else - if ( comp( *p_pivot, *(arr[ j ]), dim ) <= 0 ) - j--; - } - - return (i > left)? i - 1 : left; - } - - - /* split the array into two sub-arrays, such that all the elements - * from left to pos_mid are smaller than the elements from pos+1 to - * right. - */ - static void split_arr( Point_ptr * arr, - int left, - int right, - int pos_mid, - int dim ) - { - int pos; - - if ( left >= right ) - return; - - pos = partition( arr, left, right, arr[ (left + right ) / 2 ], - dim ); - if ( pos == pos_mid ) - return; - - if ( pos < pos_mid ) - split_arr( arr, pos+1, right, pos_mid, dim ); - else - split_arr( arr, left, pos, pos_mid, dim ); - } - - - static Point_ptr get_max_element( Point_ptr * arr, - int left, int right, int d ) - { - int max_pos = left; - Point mx = *(arr[ max_pos ]); - - for ( int ind = left + 1; ind <= right; ind++ ) - if ( comp( mx, *(arr[ ind ]), d ) < 0 ) { - mx = *(arr[ ind ]); - max_pos = ind; - } - - return arr[ max_pos ]; - } - - Node *build_r( Point_ptr * arr, int left, int right, - int d ) - { - int num, pos, next_d; - Node * n; - - num = right - left + 1; - - if ( num < 1) - return NULL; - - // if the list contains only one point, - // construct a leaf for this node - if ( num == 1) { - //n = new node; - n = malloc_node(); - n->pnt = arr[ left ]; - - return n; - } - - // else divide space into two regions in - // dim-dim and cotinue recursively - pos = (left + right) / 2; - split_arr( arr, left, right, pos, d ); - - Point * p_median = get_max_element( arr, left, pos, d ); - - // create division plane; - Plane plane( d, *p_median ); - //n = new node; - // CGAL_assertion( n != NULL ); - n = malloc_node(); - - n->plane = plane; - - next_d = d + 1; - if ( next_d >= dim ) - next_d = 0; - - // build left sub-tree - n->left = build_r( arr, left, pos, next_d ); - - // build right sub-tree - n->right = build_r( arr, pos + 1, right, next_d ); - - return n; - } - -public: - typedef list list_points; - - Kdtree_d(int k = 2) - { - dim = k; - root = NULL; - p_arr_pt = NULL; - p_node_arr = NULL; - } - - ~Kdtree_d() - { - delete_all(); - } - - - bool is_valid( bool verbose = false, int level = 0 ) const - { - (void)verbose; - (void)level; - - if ( root == NULL ) - return true; - - return root->is_valid(); - } - - - void dump() - { - root->dump( 0); - } - - void delete_all() - { - root = NULL; - - if ( p_arr_pt != NULL ) - delete[] p_arr_pt; - p_arr_pt = NULL; - if ( p_node_arr != NULL ) - delete[] p_node_arr; - p_node_arr = NULL; - } - - void search( std::back_insert_iterator result, - Box & rect ) - { - if (root == NULL) - return; // it is an empty tree - nothing to search in - - Box region = Box( dim ); - - root->search( result, rect, region ); - } - - void build(list &l) - { - int i; - Point_ptr * p_arr; - - size = l.size(); - p_arr_pt = new Point[ size ]; - CGAL_assertion( p_arr_pt != NULL ); - - p_arr = new Point_ptr[ size ]; - CGAL_assertion( p_arr != NULL ); - - p_node_arr = new Node[ 2 * size ]; - CGAL_assertion( p_node_arr != NULL ); - - node_count = 0; - - /* fill the array */ - i = 0; - for ( typename std::list::iterator j = l.begin(); - j != l.end(); - j++ ) - { - p_arr_pt[ i ] = (*j); - p_arr[ i ] = p_arr_pt + i; - i++; - } - - // recursively build the tree from the sorted list - // starting to divide it in coordinate 0 - root = build_r( p_arr, 0, size - 1, 0 ); - - //printf( "b\n" ); - delete[] p_arr; - } -}; - - -} //namespace CGAL - -#endif /* CGAL_KDTREE_D_H */ diff -Nru cgal-4.4/include/CGAL/Kd_tree.h cgal-4.5/include/CGAL/Kd_tree.h --- cgal-4.4/include/CGAL/Kd_tree.h 2012-11-13 13:14:00.000000000 +0000 +++ cgal-4.5/include/CGAL/Kd_tree.h 2014-08-29 13:58:17.000000000 +0000 @@ -1,4 +1,4 @@ -// Copyright (c) 2002,2011 Utrecht University (The Netherlands). +// Copyright (c) 2002,2011,2014 Utrecht University (The Netherlands), Max-Planck-Institute Saarbruecken (Germany). // All rights reserved. // // This file is part of CGAL (www.cgal.org). @@ -14,9 +14,9 @@ // // $URL$ // $Id$ -// // -// Author(s) : Hans Tangelder () +// Author(s) : Hans Tangelder (), +// : Waqar Khan #ifndef CGAL_KD_TREE_H #define CGAL_KD_TREE_H @@ -45,7 +45,7 @@ typedef Splitter_ Splitter; typedef typename SearchTraits::Point_d Point_d; typedef typename Splitter::Container Point_container; - + typedef typename SearchTraits::FT FT; typedef Kd_tree_node Node; typedef Kd_tree Tree; @@ -58,7 +58,7 @@ typedef typename Splitter::Separator Separator; typedef typename std::vector::const_iterator iterator; typedef typename std::vector::const_iterator const_iterator; - + typedef typename std::vector::size_type size_type; private: @@ -74,7 +74,7 @@ // Instead of storing the points in arrays in the Kd_tree_node // we put all the data in a vector in the Kd_tree. // and we only store an iterator range in the Kd_tree_node. - // + // std::vector data; @@ -94,7 +94,7 @@ // the allocation of the nodes. // The leaf node - Node_handle + Node_handle create_leaf_node(Point_container& c) { Node_handle nh = nodes.emplace(static_cast(c.size()), Node::LEAF); @@ -103,40 +103,40 @@ return nh; } - + // The internal node - Node_handle + Node_handle create_internal_node(Point_container& c, const Tag_true&) { return create_internal_node_use_extension(c); } - Node_handle + Node_handle create_internal_node(Point_container& c, const Tag_false&) { return create_internal_node(c); } - - + + // TODO: Similiar to the leaf_init function above, a part of the code should be // moved to a the class Kd_tree_node. // It is not proper yet, but the goal was to see if there is // a potential performance gain through the Compact_container - Node_handle + Node_handle create_internal_node_use_extension(Point_container& c) { Node_handle nh = nodes.emplace(Node::EXTENDED_INTERNAL); - + Point_container c_low(c.dimension(),traits_); split(nh->separator(), c, c_low); - + int cd = nh->separator().cutting_dimension(); - + nh->low_val = c_low.bounding_box().min_coord(cd); nh->high_val = c.bounding_box().max_coord(cd); - + CGAL_assertion(nh->separator().cutting_value() >= nh->low_val); CGAL_assertion(nh->separator().cutting_value() <= nh->high_val); @@ -150,21 +150,21 @@ }else{ nh->upper_ch = create_leaf_node(c); } - + return nh; } - + // Note also that I duplicated the code to get rid if the if's for // the boolean use_extension which was constant over the construction - Node_handle + Node_handle create_internal_node(Point_container& c) { Node_handle nh = nodes.emplace(Node::INTERNAL); - + Point_container c_low(c.dimension(),traits_); split(nh->separator(), c, c_low); - + if (c_low.size() > split.bucket_size()){ nh->lower_ch = create_internal_node(c_low); }else{ @@ -185,11 +185,11 @@ Kd_tree(Splitter s = Splitter(),const SearchTraits traits=SearchTraits()) : traits_(traits),split(s), built_(false) {} - + template Kd_tree(InputIterator first, InputIterator beyond, - Splitter s = Splitter(),const SearchTraits traits=SearchTraits()) - : traits_(traits),split(s), built_(false) + Splitter s = Splitter(),const SearchTraits traits=SearchTraits()) + : traits_(traits),split(s), built_(false) { pts.insert(pts.end(), first, beyond); } @@ -197,13 +197,13 @@ bool empty() const { return pts.empty(); } - - void + + void build() { const Point_d& p = *pts.begin(); typename SearchTraits::Construct_cartesian_const_iterator_d ccci=traits_.construct_cartesian_const_iterator_d_object(); - int dim = static_cast(std::distance(ccci(p), ccci(p,0))); + int dim = static_cast(std::distance(ccci(p), ccci(p,0))); data.reserve(pts.size()); for(unsigned int i = 0; i < pts.size(); i++){ @@ -214,12 +214,12 @@ if (c.size() <= split.bucket_size()){ tree_root = create_leaf_node(c); }else { - tree_root = create_internal_node(c, UseExtendedNode()); + tree_root = create_internal_node(c, UseExtendedNode()); } built_ = true; } -private: +private: //any call to this function is for the moment not threadsafe void const_build() const { #ifdef CGAL_HAS_THREADS @@ -230,7 +230,7 @@ const_cast(this)->build(); //THIS IS NOT THREADSAFE } public: - + bool is_built() const { return built_; @@ -245,35 +245,47 @@ built_ = false; } } - + void clear() { invalidate_built(); pts.clear(); } - + void insert(const Point_d& p) { invalidate_built(); pts.push_back(p); - } - + } + template - void + void insert(InputIterator first, InputIterator beyond) { invalidate_built(); pts.insert(pts.end(),first, beyond); } + //For efficiency; reserve the size of the points vectors in advance (if the number of points is already known). + void reserve(size_t size) + { + pts.reserve(size); + } + + //Get the capacity of the underlying points vector. + size_t capacity() + { + return pts.capacity(); + } + template - OutputIterator + OutputIterator search(OutputIterator it, const FuzzyQueryItem& q) const { if(! pts.empty()){ - + if(! is_built()){ const_build(); } @@ -291,27 +303,27 @@ const SearchTraits& - traits() const + traits() const { return traits_; } - Node_const_handle - root() const - { + Node_const_handle + root() const + { if(! is_built()){ const_build(); } - return tree_root; + return tree_root; } - Node_handle + Node_handle root() { if(! is_built()){ build(); } - return tree_root; + return tree_root; } void @@ -324,12 +336,12 @@ } const Kd_tree_rectangle& - bounding_box() const + bounding_box() const { if(! is_built()){ const_build(); } - return *bbox; + return *bbox; } const_iterator @@ -344,23 +356,23 @@ return pts.end(); } - size_type - size() const + size_type + size() const { return pts.size(); } // Print statistics of the tree. - std::ostream& + std::ostream& statistics(std::ostream& s) const { if(! is_built()){ const_build(); } s << "Tree statistics:" << std::endl; - s << "Number of items stored: " + s << "Number of items stored: " << root()->num_items() << std::endl; - s << "Number of nodes: " + s << "Number of nodes: " << root()->num_nodes() << std::endl; s << " Tree depth: " << root()->depth() << std::endl; return s; diff -Nru cgal-4.4/include/CGAL/Kernel/function_objects.h cgal-4.5/include/CGAL/Kernel/function_objects.h --- cgal-4.4/include/CGAL/Kernel/function_objects.h 2013-10-05 19:00:24.000000000 +0000 +++ cgal-4.5/include/CGAL/Kernel/function_objects.h 2014-08-29 13:58:16.000000000 +0000 @@ -223,9 +223,9 @@ if(sc_prod_1 >= 0 ) { if(cosine >= 0) { // the two cosine are >= 0, cosine is decreasing on [0,1] - return compare(CGAL::square(cosine)* - abac1.squared_length()*abad1.squared_length(), - CGAL::square(sc_prod_1)); + return CGAL::compare(CGAL::square(cosine)* + abac1.squared_length()*abad1.squared_length(), + CGAL::square(sc_prod_1)); } else { return SMALLER; @@ -234,9 +234,9 @@ else { if(cosine < 0) { // the two cosine are < 0, cosine is increasing on [-1,0] - return compare(CGAL::square(sc_prod_1), - CGAL::square(cosine)* - abac1.squared_length()*abad1.squared_length()); + return CGAL::compare(CGAL::square(sc_prod_1), + CGAL::square(cosine)* + abac1.squared_length()*abad1.squared_length()); } else return LARGER; @@ -272,10 +272,10 @@ if(sc_prod_1 >= 0 ) { if(sc_prod_2 >= 0) { // the two cosine are >= 0, cosine is decreasing on [0,1] - return compare(CGAL::square(sc_prod_2)* - abac1.squared_length()*abad1.squared_length(), - CGAL::square(sc_prod_1)* - abac2.squared_length()*abad2.squared_length()); + return CGAL::compare(CGAL::square(sc_prod_2)* + abac1.squared_length()*abad1.squared_length(), + CGAL::square(sc_prod_1)* + abac2.squared_length()*abad2.squared_length()); } else { return SMALLER; @@ -284,10 +284,10 @@ else { if(sc_prod_2 < 0) { // the two cosine are < 0, cosine is increasing on [-1,0] - return compare(CGAL::square(sc_prod_1)* - abac2.squared_length()*abad2.squared_length(), - CGAL::square(sc_prod_2)* - abac1.squared_length()*abad1.squared_length()); + return CGAL::compare(CGAL::square(sc_prod_1)* + abac2.squared_length()*abad2.squared_length(), + CGAL::square(sc_prod_2)* + abac1.squared_length()*abad1.squared_length()); } else return LARGER; @@ -306,14 +306,14 @@ result_type operator()(const T1& p, const T2& q, const FT& d2) const { - return CGAL_NTS compare(squared_distance(p, q), d2); + return CGAL::compare(squared_distance(p, q), d2); } template result_type operator()(const T1& p, const T2& q, const T3& r, const T4& s) const { - return CGAL_NTS compare(squared_distance(p, q), squared_distance(r, s)); + return CGAL::compare(squared_distance(p, q), squared_distance(r, s)); } }; @@ -328,14 +328,14 @@ result_type operator()(const T1& p, const T2& q, const FT& d2) const { - return CGAL_NTS compare(squared_distance(p, q), d2); + return CGAL::compare(squared_distance(p, q), d2); } template result_type operator()(const T1& p, const T2& q, const T3& r, const T4& s) const { - return CGAL_NTS compare(squared_distance(p, q), squared_distance(r, s)); + return CGAL::compare(squared_distance(p, q), squared_distance(r, s)); } }; diff -Nru cgal-4.4/include/CGAL/Kernel/global_functions_3.h cgal-4.5/include/CGAL/Kernel/global_functions_3.h --- cgal-4.4/include/CGAL/Kernel/global_functions_3.h 2012-11-13 13:13:56.000000000 +0000 +++ cgal-4.5/include/CGAL/Kernel/global_functions_3.h 2014-08-29 13:58:16.000000000 +0000 @@ -37,11 +37,28 @@ template inline Angle +angle(const Vector_3 &u, const Vector_3 &v) +{ + return internal::angle(u, v, K()); +} + +template +inline +Angle angle(const Point_3 &p, const Point_3 &q, const Point_3 &r) { return internal::angle(p, q, r, K()); } +template +inline +Angle +angle(const Point_3 &p, const Point_3 &q, + const Point_3 &r, const Point_3 &s) +{ + return internal::angle(p, q, r, s, K()); +} + template < typename K > inline typename K::Boolean diff -Nru cgal-4.4/include/CGAL/Kernel/global_functions_internal_3.h cgal-4.5/include/CGAL/Kernel/global_functions_internal_3.h --- cgal-4.4/include/CGAL/Kernel/global_functions_internal_3.h 2012-12-22 20:00:18.000000000 +0000 +++ cgal-4.5/include/CGAL/Kernel/global_functions_internal_3.h 2014-08-29 13:58:16.000000000 +0000 @@ -41,6 +41,16 @@ template inline typename K::Angle +angle(const typename K::Vector_3 &u, + const typename K::Vector_3 &v, + const K &k) +{ + return k.angle_3_object()(u, v); +} + +template +inline +typename K::Angle angle(const typename K::Point_3 &p, const typename K::Point_3 &q, const typename K::Point_3 &r, const K &k) @@ -48,6 +58,18 @@ return k.angle_3_object()(p, q, r); } +template +inline +typename K::Angle +angle(const typename K::Point_3 &p, + const typename K::Point_3 &q, + const typename K::Point_3 &r, + const typename K::Point_3 &s, + const K &k) +{ + return k.angle_3_object()(p, q, r, s); +} + template < class K > inline typename K::Boolean diff -Nru cgal-4.4/include/CGAL/Kinetic/Active_objects_vector.h cgal-4.5/include/CGAL/Kinetic/Active_objects_vector.h --- cgal-4.4/include/CGAL/Kinetic/Active_objects_vector.h 2014-01-11 20:00:27.000000000 +0000 +++ cgal-4.5/include/CGAL/Kinetic/Active_objects_vector.h 2014-08-29 13:58:16.000000000 +0000 @@ -35,6 +35,11 @@ #include #include +#if defined(BOOST_MSVC) +# pragma warning(push) +# pragma warning(disable:4267) // warning C4267: 'argument' : conversion from 'size_t' to 'int', possible loss of data +#endif + namespace CGAL { namespace Kinetic { //! Holds a set of moving points and creates notifications when changes occur. @@ -365,4 +370,9 @@ } } } //namespace CGAL::Kinetic + +#if defined(BOOST_MSVC) +# pragma warning(pop) +#endif + #endif diff -Nru cgal-4.4/include/CGAL/Kinetic/basic.h cgal-4.5/include/CGAL/Kinetic/basic.h --- cgal-4.4/include/CGAL/Kinetic/basic.h 2012-11-13 13:13:56.000000000 +0000 +++ cgal-4.5/include/CGAL/Kinetic/basic.h 2014-08-29 13:58:16.000000000 +0000 @@ -56,8 +56,9 @@ } } //namespace CGAL::Kinetic #else #include +#include namespace CGAL { namespace Kinetic { -typedef CGAL::MP_Float Default_field_nt; +typedef CGAL::Quotient Default_field_nt; } } //namespace CGAL::Kinetic #endif diff -Nru cgal-4.4/include/CGAL/Kinetic/Delaunay_triangulation_3.h cgal-4.5/include/CGAL/Kinetic/Delaunay_triangulation_3.h --- cgal-4.4/include/CGAL/Kinetic/Delaunay_triangulation_3.h 2012-11-13 13:13:56.000000000 +0000 +++ cgal-4.5/include/CGAL/Kinetic/Delaunay_triangulation_3.h 2014-08-29 13:58:16.000000000 +0000 @@ -87,9 +87,14 @@ typedef TriangulationT Triangulation; typedef typename TraitsT::Kinetic_kernel::Side_of_oriented_sphere_3 Side_of_oriented_sphere_3; typedef typename TraitsT::Kinetic_kernel::Orientation_3 Orientation_3; + + // The next typedef is needed for VC++ as it does not pick the definition from ten lines above + typedef typename TraitsT::Kinetic_kernel::Side_of_oriented_sphere_3::result_type Root_stack; + typedef internal::Delaunay_3_edge_flip_event Edge_flip; typedef typename internal::Delaunay_3_facet_flip_event Facet_flip; + Side_of_oriented_sphere_3 side_of_oriented_sphere_3_object() const { return TraitsT::kinetic_kernel_object().side_of_oriented_sphere_3_object(); diff -Nru cgal-4.4/include/CGAL/Kinetic/Exact_simulation_traits.h cgal-4.5/include/CGAL/Kinetic/Exact_simulation_traits.h --- cgal-4.4/include/CGAL/Kinetic/Exact_simulation_traits.h 2012-11-13 13:13:56.000000000 +0000 +++ cgal-4.5/include/CGAL/Kinetic/Exact_simulation_traits.h 2014-08-29 13:58:16.000000000 +0000 @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include //#include @@ -41,7 +41,7 @@ struct Exact_simulation_traits { typedef Exact_simulation_traits This; #ifdef CGAL_KINETIC_DO_NOT_USE_LAZY_EXACT - typedef CGAL::Cartesian Static_kernel; + typedef CGAL::Cartesian Static_kernel; #else typedef CGAL::Exact_predicates_exact_constructions_kernel Static_kernel; #endif diff -Nru cgal-4.4/include/CGAL/Kinetic/internal/Instantaneous_adaptor.h cgal-4.5/include/CGAL/Kinetic/internal/Instantaneous_adaptor.h --- cgal-4.4/include/CGAL/Kinetic/internal/Instantaneous_adaptor.h 2012-11-13 13:13:56.000000000 +0000 +++ cgal-4.5/include/CGAL/Kinetic/internal/Instantaneous_adaptor.h 2014-08-29 13:58:16.000000000 +0000 @@ -23,6 +23,12 @@ #include #include + +#if defined(BOOST_MSVC) +# pragma warning(push) +# pragma warning(disable:4800) // conversion to bool performance warning +#endif + namespace CGAL { namespace Kinetic { //! An object to help convert between moving objects and their static representations to wrap a predicate. @@ -166,4 +172,11 @@ }; } } //namespace CGAL::Kinetic + + +#if defined(BOOST_MSVC) +# pragma warning(pop) +#endif + + #endif diff -Nru cgal-4.4/include/CGAL/Kinetic/Regular_triangulation_exact_simulation_traits.h cgal-4.5/include/CGAL/Kinetic/Regular_triangulation_exact_simulation_traits.h --- cgal-4.4/include/CGAL/Kinetic/Regular_triangulation_exact_simulation_traits.h 2012-11-13 13:13:56.000000000 +0000 +++ cgal-4.5/include/CGAL/Kinetic/Regular_triangulation_exact_simulation_traits.h 2014-08-29 13:58:16.000000000 +0000 @@ -40,7 +40,7 @@ struct Regular_triangulation_exact_simulation_traits { typedef Regular_triangulation_exact_simulation_traits This; #ifdef CGAL_KINETIC_DO_NOT_USE_LAZY_EXACT - typedef CGAL::Cartesian Static_kernel_base; + typedef CGAL::Cartesian::Type> Static_kernel_base; #else typedef CGAL::Exact_predicates_exact_constructions_kernel Static_kernel_base; #endif diff -Nru cgal-4.4/include/CGAL/Labeled_image_mesh_domain_3.h cgal-4.5/include/CGAL/Labeled_image_mesh_domain_3.h --- cgal-4.4/include/CGAL/Labeled_image_mesh_domain_3.h 2012-11-13 13:13:57.000000000 +0000 +++ cgal-4.5/include/CGAL/Labeled_image_mesh_domain_3.h 2014-08-29 13:58:16.000000000 +0000 @@ -28,7 +28,8 @@ #define CGAL_LABELED_IMAGE_MESH_DOMAIN_3_H -#include +#include +#include #include @@ -43,10 +44,10 @@ class BGT, class Wrapper = Mesh_3::Image_to_labeled_function_wrapper > class Labeled_image_mesh_domain_3 -: public Mesh_3::Labeled_mesh_domain_3 +: public Labeled_mesh_domain_3 { public: - typedef Mesh_3::Labeled_mesh_domain_3 Base; + typedef Labeled_mesh_domain_3 Base; typedef typename Base::Sphere_3 Sphere_3; typedef typename Base::FT FT; @@ -55,10 +56,12 @@ /// Constructor Labeled_image_mesh_domain_3(const Image& image, - const FT& error_bound = FT(1e-3)) + const FT& error_bound = FT(1e-3), + CGAL::Random* p_rng = NULL) : Base(Wrapper(image), compute_bounding_box(image), - error_bound) + error_bound, + p_rng) {} /// Destructor diff -Nru cgal-4.4/include/CGAL/Labeled_mesh_domain_3.h cgal-4.5/include/CGAL/Labeled_mesh_domain_3.h --- cgal-4.4/include/CGAL/Labeled_mesh_domain_3.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/Labeled_mesh_domain_3.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,641 @@ +// Copyright (c) 2009 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Stéphane Tayeb, Aymeric PELLE +// +//****************************************************************************** +// File Description : +// class Labeled_mesh_domain_3. See class description. +//****************************************************************************** + +#ifndef CGAL_LABELED_MESH_DOMAIN_3_H +#define CGAL_LABELED_MESH_DOMAIN_3_H + +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include + +namespace CGAL { + +/** + * \class Labeled_mesh_domain_3 + * + * Function f must take his values into N. + * Let p be a Point. + * - f(p)=0 means that p is outside domain. + * - f(p)=a, a!=0 means that p is inside subdomain a. + * + * Any boundary facet is labelled , a, where b!=0. + */ +template +class Labeled_mesh_domain_3 +{ +public: + /// Geometric object types + typedef typename BGT::Point_3 Point_3; + typedef typename BGT::Segment_3 Segment_3; + typedef typename BGT::Ray_3 Ray_3; + typedef typename BGT::Line_3 Line_3; + typedef typename BGT::Vector_3 Vector_3; + typedef typename BGT::Sphere_3 Sphere_3; + typedef CGAL::Bbox_3 Bbox_3; + +protected: + typedef typename BGT::Iso_cuboid_3 Iso_cuboid_3; + +public: + // Kernel_traits compatibility + typedef BGT R; + + //------------------------------------------------------- + // Index Types + //------------------------------------------------------- + /// Type of indexes for cells of the input complex + typedef typename Function::return_type Subdomain_index; + typedef boost::optional Subdomain; + /// Type of indexes for surface patch of the input complex + typedef std::pair Surface_patch_index; + typedef boost::optional Surface_patch; + /// Type of indexes to characterize the lowest dimensional face of the input + /// complex on which a vertex lie + typedef boost::variant Index; + typedef CGAL::cpp11::tuple Intersection; + + + typedef typename BGT::FT FT; + typedef BGT Geom_traits; + + /** + * @brief Constructor + */ + Labeled_mesh_domain_3(const Function& f, + const Sphere_3& bounding_sphere, + const FT& error_bound = FT(1e-3), + CGAL::Random* p_rng = NULL); + + Labeled_mesh_domain_3(const Function& f, + const Bbox_3& bbox, + const FT& error_bound = FT(1e-3), + CGAL::Random* p_rng = NULL); + + Labeled_mesh_domain_3(const Function& f, + const Iso_cuboid_3& bbox, + const FT& error_bound = FT(1e-3), + CGAL::Random* p_rng = NULL); + + /// Destructor + virtual ~Labeled_mesh_domain_3() + { + if(delete_rng_) + delete p_rng_; + } + + + /** + * Constructs a set of \ccc{n} points on the surface, and output them to + * the output iterator \ccc{pts} whose value type is required to be + * \ccc{std::pair}. + */ + struct Construct_initial_points + { + Construct_initial_points(const Labeled_mesh_domain_3& domain) + : r_domain_(domain) {} + + template + OutputIterator operator()(OutputIterator pts, const int n = 12) const; + + private: + const Labeled_mesh_domain_3& r_domain_; + }; + + /// Returns Construct_initial_points object + Construct_initial_points construct_initial_points_object() const + { + return Construct_initial_points(*this); + } + + /** + * Returns true if point~\ccc{p} is in the domain. If \ccc{p} is in the + * domain, the parameter index is set to the index of the subdomain + * including $p$. It is set to the default value otherwise. + */ + struct Is_in_domain + { + Is_in_domain(const Labeled_mesh_domain_3& domain) : r_domain_(domain) {} + + Subdomain operator()(const Point_3& p) const + { + // f(p)==0 means p is outside the domain + Subdomain_index index = (r_domain_.function_)(p); + if ( Subdomain_index() == index ) + return Subdomain(); + else + return Subdomain(index); + } + private: + const Labeled_mesh_domain_3& r_domain_; + }; + + /// Returns Is_in_domain object + Is_in_domain is_in_domain_object() const { return Is_in_domain(*this); } + + /** + * Returns true is the element \ccc{type} intersect properly any of the + * surface patches describing the either the domain boundary or some + * subdomain boundary. + * \ccc{Type} is either \ccc{Segment_3}, \ccc{Ray_3} or \ccc{Line_3}. + * Parameter index is set to the index of the intersected surface patch + * if \ccc{true} is returned and to the default \ccc{Surface_patch_index} + * value otherwise. + */ + struct Do_intersect_surface + { + Do_intersect_surface(const Labeled_mesh_domain_3& domain) + : r_domain_(domain) {} + + Surface_patch operator()(const Segment_3& s) const + { + return this->operator()(s.source(), s.target()); + } + + Surface_patch operator()(const Ray_3& r) const + { + return clip_to_segment(r); + } + + Surface_patch operator()(const Line_3& l) const + { + return clip_to_segment(l); + } + + private: + /// Returns true if points \c a & \c b do not belong to the same subdomain + /// \c index is set to the surface index of subdomains f(a), f(b) + Surface_patch operator()(const Point_3& a, const Point_3& b) const + { + // If f(a) != f(b), then [a,b] intersects some surface. Here we consider + // [a,b] intersects surface_patch labelled (or ). + // It may be false, further rafinement will improve precision + const Subdomain_index value_a = r_domain_.function_(a); + const Subdomain_index value_b = r_domain_.function_(b); + + if ( value_a != value_b ) + return Surface_patch(r_domain_.make_surface_index(value_a, value_b)); + else + return Surface_patch(); + } + + /** + * Clips \c query to a segment \c s, and call operator()(s) + */ + template + Surface_patch clip_to_segment(const Query& query) const + { + typename cpp11::result_of::type + clipped = CGAL::intersection(query, r_domain_.bbox_); + + if(clipped) +#if CGAL_INTERSECTION_VERSION > 1 + if(const Segment_3* s = boost::get(&*clipped)) + return this->operator()(*s); +#else + if(const Segment_3* s = object_cast(&clipped)) + return this->operator()(*s); +#endif + + return Surface_patch(); + } + + private: + const Labeled_mesh_domain_3& r_domain_; + }; + + /// Returns Do_intersect_surface object + Do_intersect_surface do_intersect_surface_object() const + { + return Do_intersect_surface(*this); + } + + /** + * Returns a point in the intersection of the primitive \ccc{type} + * with some boundary surface. + * \ccc{Type1} is either \ccc{Segment_3}, \ccc{Ray_3} or \ccc{Line_3}. + * The integer \ccc{dimension} is set to the dimension of the lowest + * dimensional face in the input complex containing the returned point, and + * \ccc{index} is set to the index to be stored at a mesh vertex lying + * on this face. + */ + struct Construct_intersection + { + Construct_intersection(const Labeled_mesh_domain_3& domain) + : r_domain_(domain) {} + + Intersection operator()(const Segment_3& s) const + { +#ifndef CGAL_MESH_3_NO_LONGER_CALLS_DO_INTERSECT_3 + CGAL_precondition(r_domain_.do_intersect_surface_object()(s)); +#endif // NOT CGAL_MESH_3_NO_LONGER_CALLS_DO_INTERSECT_3 + return this->operator()(s.source(),s.target()); + } + + Intersection operator()(const Ray_3& r) const + { + return clip_to_segment(r); + } + + Intersection operator()(const Line_3& l) const + { + return clip_to_segment(l); + } + + private: + /** + * Returns a point in the intersection of [a,b] with the surface + * \c a must be the source point, and \c b the out point. It's important + * because it drives bisection cuts. + * Indeed, the returned point is the first intersection from \c [a,b] + * with a subdomain surface. + */ + Intersection operator()(const Point_3& a, const Point_3& b) const + { + // Functors + typename BGT::Compute_squared_distance_3 squared_distance = + BGT().compute_squared_distance_3_object(); + typename BGT::Construct_midpoint_3 midpoint = + BGT().construct_midpoint_3_object(); + + // Non const points + Point_3 p1 = a; + Point_3 p2 = b; + Point_3 mid = midpoint(p1, p2); + + // Cannot be const: those values are modified below. + Subdomain_index value_at_p1 = r_domain_.function_(p1); + Subdomain_index value_at_p2 = r_domain_.function_(p2); + Subdomain_index value_at_mid = r_domain_.function_(mid,true); + + // If both extremities are in the same subdomain, + // there is no intersection. + // This should not happen... + if( value_at_p1 == value_at_p2 ) + { + return Intersection(); + } + + // Construct the surface patch index and index from the values at 'a' + // and 'b'. Even if the bissection find out a different pair of + // values, the reported index will be constructed from the initial + // values. + const Surface_patch_index sp_index = + r_domain_.make_surface_index(value_at_p1, value_at_p2); + const Index index = r_domain_.index_from_surface_patch_index(sp_index); + + // Else lets find a point (by bisection) + // Bisection ends when the point is near than error bound from surface + while(true) + { + // If the two points are enough close, then we return midpoint + if ( squared_distance(p1, p2) < r_domain_.squared_error_bound_ ) + { + CGAL_assertion(value_at_p1 != value_at_p2); + return Intersection(mid, index, 2); + } + + // Else we must go on + // Here we consider that p1(a) is the source point. Thus, we keep p1 and + // change p2 if f(p1)!=f(p2). + // That allows us to find the first intersection from a of [a,b] with + // a surface. + if ( value_at_p1 != value_at_mid ) + { + p2 = mid; + value_at_p2 = value_at_mid; + } + else + { + p1 = mid; + value_at_p1 = value_at_mid; + } + + mid = midpoint(p1, p2); + value_at_mid = r_domain_.function_(mid,true); + } + } + + /// Clips \c query to a segment \c s, and call operator()(s) + template + Intersection clip_to_segment(const Query& query) const + { + typename cpp11::result_of::type + clipped = CGAL::intersection(query, r_domain_.bbox_); + + if(clipped) +#if CGAL_INTERSECTION_VERSION > 1 + if(const Segment_3* s = boost::get(&*clipped)) + return this->operator()(*s); +#else + if(const Segment_3* s = object_cast(&clipped)) + return this->operator()(*s); +#endif + + return Intersection(); + } + + private: + const Labeled_mesh_domain_3& r_domain_; + }; + + /// Returns Construct_intersection object + Construct_intersection construct_intersection_object() const + { + return Construct_intersection(*this); + } + + /** + * Returns the index to be stored in a vertex lying on the surface identified + * by \c index. + */ + Index index_from_surface_patch_index(const Surface_patch_index& index) const + { return Index(index); } + + /** + * Returns the index to be stored in a vertex lying in the subdomain + * identified by \c index. + */ + Index index_from_subdomain_index(const Subdomain_index& index) const + { return Index(index); } + + /** + * Returns the \c Surface_patch_index of the surface patch + * where lies a vertex with dimension 2 and index \c index. + */ + Surface_patch_index surface_patch_index(const Index& index) const + { return boost::get(index); } + + /** + * Returns the index of the subdomain containing a vertex + * with dimension 3 and index \c index. + */ + Subdomain_index subdomain_index(const Index& index) const + { return boost::get(index); } + + // ----------------------------------- + // Backward Compatibility + // ----------------------------------- +#ifndef CGAL_MESH_3_NO_DEPRECATED_SURFACE_INDEX + typedef Surface_patch_index Surface_index; + + Index index_from_surface_index(const Surface_index& index) const + { return index_from_surface_patch_index(index); } + + Surface_index surface_index(const Index& index) const + { return surface_patch_index(index); } +#endif // CGAL_MESH_3_NO_DEPRECATED_SURFACE_INDEX + // ----------------------------------- + // End backward Compatibility + // ----------------------------------- + + +private: + /// Returns Surface_patch_index from \c i and \c j + Surface_patch_index make_surface_index(const Subdomain_index i, + const Subdomain_index j) const + { + if ( i < j ) return Surface_patch_index(i,j); + else return Surface_patch_index(j,i); + } + + /// Returns squared error bound from \c bbox and \c error + FT squared_error_bound(const Iso_cuboid_3& bbox, const FT& error) const + { + typename BGT::Compute_squared_distance_3 squared_distance = + BGT().compute_squared_distance_3_object(); + return squared_distance((bbox.min)(), (bbox.max)())*error*error/4; + } + + /// Returns squared error bound from \c sphere and \c error + FT squared_error_bound(const Sphere_3& sphere, const FT& error) const + { + typename BGT::Compute_squared_radius_3 squared_radius = + BGT().compute_squared_radius_3_object(); + return squared_radius(sphere)*error*error; + } + + /// Returns the bounding sphere of an Iso_cuboid_3 + Sphere_3 bounding_sphere(const Iso_cuboid_3& bbox) const + { + typename BGT::Construct_sphere_3 sphere = BGT().construct_sphere_3_object(); + return sphere((bbox.min)(), (bbox.max)()); + } + + /// Returns and Iso_cuboid_3 from a Bbox_3 + Iso_cuboid_3 iso_cuboid(const Bbox_3& bbox) + { + const Point_3 p_min(bbox.xmin(), bbox.ymin(), bbox.zmin()); + const Point_3 p_max(bbox.xmax(), bbox.ymax(), bbox.zmax()); + + return Iso_cuboid_3(p_min,p_max); + } + +protected: + /// Returns bounding box + const Iso_cuboid_3& bounding_box() const { return bbox_; } + +private: + /// The function which answers subdomain queries + const Function function_; + /// The bounding box + const Iso_cuboid_3 bbox_; + /// The random number generator used by Construct_initial_points + CGAL::Random* p_rng_; + bool delete_rng_; + /// Error bound relative to sphere radius + FT squared_error_bound_; + + +private: + // Disabled copy constructor & assignment operator + typedef Labeled_mesh_domain_3 Self; + Labeled_mesh_domain_3(const Self& src); + Self& operator=(const Self& src); + +}; // end class Labeled_mesh_domain_3 + + + + +//------------------------------------------------------- +// Method implementation +//------------------------------------------------------- +template +Labeled_mesh_domain_3::Labeled_mesh_domain_3( + const F& f, + const Sphere_3& bounding_sphere, + const FT& error_bound, + CGAL::Random* p_rng) +: function_(f) +, bbox_(iso_cuboid(bounding_sphere.bbox())) +, p_rng_(p_rng) +, delete_rng_(false) +, squared_error_bound_(squared_error_bound(bounding_sphere,error_bound)) +{ + // TODO : CGAL_ASSERT(0 < f(bounding_sphere.get_center()) ) ? + if(!p_rng_) + { + p_rng_ = new CGAL::Random(0); + delete_rng_ = true; + } +} + +template +Labeled_mesh_domain_3::Labeled_mesh_domain_3( + const F& f, + const Bbox_3& bbox, + const FT& error_bound, + CGAL::Random* p_rng) +: function_(f) +, bbox_(iso_cuboid(bbox)) +, p_rng_(p_rng) +, delete_rng_(false) +, squared_error_bound_(squared_error_bound(bbox_,error_bound)) +{ + // TODO : CGAL_ASSERT(0 < f(bounding_sphere.get_center()) ) ? + if(!p_rng_) + { + p_rng_ = new CGAL::Random(0); + delete_rng_ = true; + } +} + +template +Labeled_mesh_domain_3::Labeled_mesh_domain_3( + const F& f, + const Iso_cuboid_3& bbox, + const FT& error_bound, + CGAL::Random* p_rng) +: function_(f) +, bbox_(bbox) +, p_rng_(p_rng) +, delete_rng_(false) +, squared_error_bound_(squared_error_bound(bbox_,error_bound)) +{ + // TODO : CGAL_ASSERT(0 < f( bbox.get_center()) ) ? + if(!p_rng_) + { + p_rng_ = new CGAL::Random(0); + delete_rng_ = true; + } +} + + + +template +template +OutputIterator +Labeled_mesh_domain_3::Construct_initial_points::operator()( + OutputIterator pts, + const int nb_points) const +{ + // Create point_iterator on and in bounding_sphere + typedef Random_points_on_sphere_3 Random_points_on_sphere_3; + typedef Random_points_in_sphere_3 Random_points_in_sphere_3; + + + const FT squared_radius = BGT().compute_squared_radius_3_object()( + r_domain_.bounding_sphere(r_domain_.bbox_)); + + const double radius = std::sqrt(CGAL::to_double(squared_radius)); + + CGAL::Random& rng = *(r_domain_.p_rng_); + Random_points_on_sphere_3 random_point_on_sphere(radius, rng); + Random_points_in_sphere_3 random_point_in_sphere(radius, rng); + + // Get some functors + typename BGT::Construct_segment_3 segment_3 = + BGT().construct_segment_3_object(); + typename BGT::Construct_vector_3 vector_3 = + BGT().construct_vector_3_object(); + typename BGT::Construct_translated_point_3 translate = + BGT().construct_translated_point_3_object(); + typename BGT::Construct_center_3 center = BGT().construct_center_3_object(); + + // Get translation from origin to sphere center + Point_3 center_pt = center(r_domain_.bounding_sphere(r_domain_.bbox_)); + const Vector_3 sphere_translation = vector_3(CGAL::ORIGIN, center_pt); + + // Create nb_point points + int n = nb_points; +#ifdef CGAL_MESH_3_VERBOSE + std::cerr << "construct initial points:\n"; +#endif + while ( 0 != n ) + { + // Get a random segment + const Point_3 random_point = translate(*random_point_on_sphere, + sphere_translation); + const Segment_3 random_seg = segment_3(center_pt, random_point); + + // Add the intersection to the output if it exists + Surface_patch surface = r_domain_.do_intersect_surface_object()(random_seg); + if ( surface ) + { + const Point_3 intersect_pt = CGAL::cpp11::get<0>( + r_domain_.construct_intersection_object()(random_seg)); + *pts++ = std::make_pair(intersect_pt, + r_domain_.index_from_surface_patch_index(*surface)); + --n; + +#ifdef CGAL_MESH_3_VERBOSE + std::cerr << boost::format("\r \r" + "%1%/%2% initial point(s) found...") + % (nb_points - n) + % nb_points; +#endif + } + else + { + // Get a new random point into sphere as center of object + // It may be necessary if the center of the domain is empty, e.g. torus + // In general case, it is good for input point dispersion + ++random_point_in_sphere; + center_pt = translate(*random_point_in_sphere, sphere_translation); + } + ++random_point_on_sphere; + } + +#ifdef CGAL_MESH_3_VERBOSE + std::cerr << "\n"; +#endif + return pts; +} + + +} // end namespace CGAL + +#endif // LABELLED_MESH_TRAITS_3_H_ diff -Nru cgal-4.4/include/CGAL/Lapack/Linear_algebra_lapack.h cgal-4.5/include/CGAL/Lapack/Linear_algebra_lapack.h --- cgal-4.4/include/CGAL/Lapack/Linear_algebra_lapack.h 2012-11-13 13:13:56.000000000 +0000 +++ cgal-4.5/include/CGAL/Lapack/Linear_algebra_lapack.h 2014-08-29 13:58:16.000000000 +0000 @@ -15,7 +15,7 @@ // $URL$ // $Id$ // -// Author(s) : Marc Pouget and Frédéric Cazals +// Author(s) : Marc Pouget and Frédéric Cazals #ifndef CGAL_LAPACK_H #define CGAL_LAPACK_H diff -Nru cgal-4.4/include/CGAL/Lazy_exact_nt.h cgal-4.5/include/CGAL/Lazy_exact_nt.h --- cgal-4.4/include/CGAL/Lazy_exact_nt.h 2013-05-25 19:00:28.000000000 +0000 +++ cgal-4.5/include/CGAL/Lazy_exact_nt.h 2014-08-29 13:58:16.000000000 +0000 @@ -1427,6 +1427,7 @@ typedef CGAL::Lazy_exact_nt Nested; static inline Real epsilon() { return 0; } + static inline Real dummy_precision() { return 0; } enum { IsInteger = NumTraits::IsInteger, diff -Nru cgal-4.4/include/CGAL/Lazy.h cgal-4.5/include/CGAL/Lazy.h --- cgal-4.4/include/CGAL/Lazy.h 2013-06-15 19:00:25.000000000 +0000 +++ cgal-4.5/include/CGAL/Lazy.h 2014-08-29 13:58:16.000000000 +0000 @@ -1596,6 +1596,7 @@ typename Type_mapper::type)>::type ET; CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); + Protect_FPU_rounding P; try { Lazy lazy(new Lazy_rep_3(AC(), EC(), l1, l2, l3)); diff -Nru cgal-4.4/include/CGAL/leda_bigfloat.h cgal-4.5/include/CGAL/leda_bigfloat.h --- cgal-4.4/include/CGAL/leda_bigfloat.h 2012-11-13 13:13:59.000000000 +0000 +++ cgal-4.5/include/CGAL/leda_bigfloat.h 2014-08-29 13:58:16.000000000 +0000 @@ -27,8 +27,6 @@ #include -#ifdef CGAL_USE_LEDA - #include #include #include @@ -154,13 +152,10 @@ inline bigfloat operator+( const bigfloat& i) { return i; } } // namespace leda -//since types are included by leda_coercion_traits.h: +//since types are included by LEDA_coercion_traits.h: #include #include -#include #include #include -#endif // CGAL_USE_LEDA - #endif // CGAL_LEDA_BIGFLOAT_H diff -Nru cgal-4.4/include/CGAL/leda_bigfloat_interval.h cgal-4.5/include/CGAL/leda_bigfloat_interval.h --- cgal-4.4/include/CGAL/leda_bigfloat_interval.h 2012-11-13 13:13:59.000000000 +0000 +++ cgal-4.5/include/CGAL/leda_bigfloat_interval.h 2014-08-29 13:58:16.000000000 +0000 @@ -25,10 +25,6 @@ #include -#ifndef CGAL_USE_LEDA -#warning This header file needs LEDA installed in order to work properly. -#else // CGAL_USE_LEDA - #include #if CGAL_LEDA_VERSION < 500 #include @@ -38,10 +34,6 @@ #include -#include -#include -#include -#include #include #include #include @@ -170,6 +162,15 @@ internal::Checking_for_leda_bigfloat > > leda_bigfloat_interval; +} //end of namespace CGAL + +#include +#include +#include +#include + +namespace CGAL { + template <> class Algebraic_structure_traits< leda_bigfloat_interval > : public Algebraic_structure_traits_base< leda_bigfloat_interval, Field_with_sqrt_tag > { @@ -487,5 +488,5 @@ } //namespace CGAL -#endif // CGAL_USE_LEDA + #endif // CGAL_LEDA_BIGFLOAT_INTERVAL_H diff -Nru cgal-4.4/include/CGAL/leda_integer.h cgal-4.5/include/CGAL/leda_integer.h --- cgal-4.4/include/CGAL/leda_integer.h 2012-11-13 13:13:59.000000000 +0000 +++ cgal-4.5/include/CGAL/leda_integer.h 2014-08-29 13:58:16.000000000 +0000 @@ -27,8 +27,6 @@ #include -#ifdef CGAL_USE_LEDA - #include #include @@ -275,13 +273,10 @@ inline integer operator+( const integer& i) { return i; } } // namespace leda -//since types are included by leda_coercion_traits.h: -#include +//since types are included by LEDA_coercion_traits.h: #include #include #include #include -#endif // CGAL_USE_LEDA - #endif // CGAL_LEDA_INTEGER_H diff -Nru cgal-4.4/include/CGAL/leda_rational.h cgal-4.5/include/CGAL/leda_rational.h --- cgal-4.4/include/CGAL/leda_rational.h 2012-11-13 13:13:59.000000000 +0000 +++ cgal-4.5/include/CGAL/leda_rational.h 2014-08-29 13:58:16.000000000 +0000 @@ -27,8 +27,6 @@ #include -#ifdef CGAL_USE_LEDA - #include #include @@ -287,13 +285,10 @@ inline rational operator+( const rational& i) { return i; } } -//since types are included by leda_coercion_traits.h: +//since types are included by LEDA_coercion_traits.h: #include -#include #include #include #include -#endif // CGAL_USE_LEDA - #endif // CGAL_LEDA_RATIONAL_H diff -Nru cgal-4.4/include/CGAL/leda_real.h cgal-4.5/include/CGAL/leda_real.h --- cgal-4.4/include/CGAL/leda_real.h 2012-11-13 13:13:59.000000000 +0000 +++ cgal-4.5/include/CGAL/leda_real.h 2014-08-29 13:58:16.000000000 +0000 @@ -27,8 +27,6 @@ #include -#ifdef CGAL_USE_LEDA - #include #include @@ -251,13 +249,11 @@ inline real operator+( const real& i) { return i; } } // namespace leda -//since types are included by leda_coercion_traits.h: + +//since types are included by LEDA_coercion_traits.h: #include #include #include -#include #include -#endif // CGAL_USE_LEDA - #endif // CGAL_LEDA_REAL_H diff -Nru cgal-4.4/include/CGAL/long_long.h cgal-4.5/include/CGAL/long_long.h --- cgal-4.4/include/CGAL/long_long.h 2012-11-13 13:13:59.000000000 +0000 +++ cgal-4.5/include/CGAL/long_long.h 2014-08-29 13:58:16.000000000 +0000 @@ -88,6 +88,50 @@ }; }; +#ifdef BOOST_HAS_INT128 +// __int128 +template<> class Algebraic_structure_traits< boost::int128_type > + : public Algebraic_structure_traits_base< boost::int128_type, + Euclidean_ring_tag > { + + public: + typedef Tag_true Is_exact; + typedef Tag_false Is_numerical_sensitive; + + typedef INTERN_AST::Div_per_operator< Type > Div; + typedef INTERN_AST::Mod_per_operator< Type > Mod; + +}; + +template <> class Real_embeddable_traits< boost::int128_type > + : public INTERN_RET::Real_embeddable_traits_base< boost::int128_type , CGAL::Tag_true > { + public: + + class To_interval + : public std::unary_function< Type, std::pair< double, double > > { + public: + std::pair operator()( const Type& x ) const { + return (Interval_nt<>((double)x)+Interval_nt<>::smallest()).pair(); + } + }; +}; + +// unsigned __int128 +template <> class Real_embeddable_traits< boost::uint128_type > + : public INTERN_RET::Real_embeddable_traits_base< boost::uint128_type , CGAL::Tag_true > { + public: + + class To_interval + : public std::unary_function< Type, std::pair< double, double > > { + public: + std::pair operator()( const Type& x ) const { + return (Interval_nt<>((double)x)+Interval_nt<>::smallest()).pair(); + } + }; +}; +#endif + + } //namespace CGAL #include diff -Nru cgal-4.4/include/CGAL/make_mesh_3.h cgal-4.5/include/CGAL/make_mesh_3.h --- cgal-4.4/include/CGAL/make_mesh_3.h 2013-07-06 19:00:27.000000000 +0000 +++ cgal-4.5/include/CGAL/make_mesh_3.h 2014-08-29 13:58:16.000000000 +0000 @@ -25,6 +25,7 @@ #ifndef CGAL_MAKE_MESH_3_H #define CGAL_MAKE_MESH_3_H +#include #include #include #include @@ -113,7 +114,15 @@ // ----------------------------------- // Parameters // ----------------------------------- + +// see +CGAL_PRAGMA_DIAG_PUSH +// see +CGAL_MESH_3_IGNORE_BOOST_PARAMETER_NAME_WARNINGS + BOOST_PARAMETER_NAME( features_param ) + +CGAL_PRAGMA_DIAG_POP } // end namespace parameters::internal @@ -178,7 +187,7 @@ { typedef typename MeshCriteria::Edge_criteria Edge_criteria; typedef Edge_criteria_sizing_field_wrapper Sizing_field; - + CGAL::Mesh_3::Protect_edges_sizing_field protect_edges(c3t3, domain, Sizing_field(criteria.edge_criteria_object())); @@ -393,6 +402,10 @@ const parameters::internal::Mesh_3_options& mesh_options = parameters::internal::Mesh_3_options()) { +#ifdef CGAL_MESH_3_INITIAL_POINTS_NO_RANDOM_SHOOTING + CGAL::default_random = CGAL::Random(0); +#endif + // Initialize c3t3 internal::Mesh_3::C3t3_initializer< C3T3, diff -Nru cgal-4.4/include/CGAL/Mesh_3/C3T3_helpers.h cgal-4.5/include/CGAL/Mesh_3/C3T3_helpers.h --- cgal-4.4/include/CGAL/Mesh_3/C3T3_helpers.h 2014-03-29 20:00:20.000000000 +0000 +++ cgal-4.5/include/CGAL/Mesh_3/C3T3_helpers.h 2014-10-06 19:00:05.000000000 +0000 @@ -33,6 +33,11 @@ #include #include #include +#include + +#ifdef CGAL_MESH_3_PROFILING + #include +#endif #include #include @@ -42,6 +47,12 @@ #include #include #include +#include +#include + +#ifdef CGAL_LINKED_WITH_TBB +# include +#endif #include #include @@ -50,12 +61,11 @@ namespace CGAL { namespace Mesh_3 { - #ifdef CGAL_INTRUSIVE_LIST template class Intrusive_list { public: - + typedef Type Type_handle; typedef Type_handle& reference; typedef const Type_handle& const_reference; @@ -79,17 +89,17 @@ #ifdef CGAL_CONSTRUCT_INTRUSIVE_LIST_RANGE_CONSTRUCTOR template Intrusive_list(IT first, IT last) - : f(), b(), n(0) + : f(), b(), n(0) { if(first == last){ return; } - + f = *first; Type_handle ch = f; ++n; ++first; - while(first != last){ + while(first != last){ if((ch != Type(*first)) && ((*first)->next_intrusive()==Type_handle())){ // not yet inserted ch->set_next_intrusive(*first); @@ -98,7 +108,7 @@ ++n; } ++first; - } + } b = ch; b->set_next_intrusive(f); f->set_previous_intrusive(b); @@ -148,8 +158,8 @@ return true; } - - void clear() + + void clear() { if(!empty()){ while( f!= b ){ @@ -194,9 +204,9 @@ if(pos != Type_handle()){ if(pos == b){ pos = Type_handle(); // past the end - }else { + }else { pos = pos->next_intrusive(); - } + } } return *this; } @@ -209,10 +219,10 @@ } bool operator==(const iterator& i) const - { + { return pos == i.pos; } - + bool operator!=(const iterator& i) const { return !(*this == i); @@ -265,10 +275,10 @@ iterator insert(iterator /* position */, const Type_handle& ch) { - CGAL_assertion( (ch->next_intrusive() == Type_handle() && ch->previous_intrusive() == Type_handle()) || + CGAL_assertion( (ch->next_intrusive() == Type_handle() && ch->previous_intrusive() == Type_handle()) || (ch->next_intrusive() != Type_handle() && ch->previous_intrusive() != Type_handle()) ); CGAL_expensive_assertion(is_valid()); - + if(ch->next_intrusive() != Type_handle()){ return iterator(ch->next_intrusive()/*first*/, ch/*last*/); } @@ -280,10 +290,10 @@ void insert(Type_handle ch) { - CGAL_assertion( (ch->next_intrusive() == Type_handle() && ch->previous_intrusive() == Type_handle()) || + CGAL_assertion( (ch->next_intrusive() == Type_handle() && ch->previous_intrusive() == Type_handle()) || (ch->next_intrusive() != Type_handle() && ch->previous_intrusive() != Type_handle()) ); CGAL_expensive_assertion(is_valid()); - + if(ch->next_intrusive() != Type_handle()){ return; } @@ -303,7 +313,7 @@ void erase(Type_handle ch) { - CGAL_assertion( (ch->next_intrusive() == Type_handle() && ch->previous_intrusive() == Type_handle()) || + CGAL_assertion( (ch->next_intrusive() == Type_handle() && ch->previous_intrusive() == Type_handle()) || (ch->next_intrusive() != Type_handle() && ch->previous_intrusive() != Type_handle()) ); CGAL_expensive_assertion(is_valid()); if(ch->next_intrusive() == Type_handle()){ @@ -312,7 +322,7 @@ if(f == b){ // only 1 element in the list CGAL_assertion(f == ch); CGAL_assertion(n == 1); - + f = b = Type_handle(); } else { if(f == ch){ @@ -350,46 +360,293 @@ } else return false; } - + void push_back(Type_handle ch) { insert(ch); } private: - Type_handle f,b; + Type_handle f,b; std::size_t n; }; #endif // #ifdef CGAL_INTRUSIVE_LIST -template + +/************************************************ +// Class C3T3_helpers_base +// Two versions: sequential / parallel +************************************************/ + +// Sequential +template +class C3T3_helpers_base +{ +protected: + typedef typename Tr::Geom_traits Gt; + typedef typename Gt::Point_3 Point_3; + typedef typename Tr::Vertex_handle Vertex_handle; + typedef typename Tr::Cell_handle Cell_handle; + typedef typename Tr::Facet Facet; + typedef typename Tr::Lock_data_structure Lock_data_structure; + + C3T3_helpers_base(Lock_data_structure *) {} + + Lock_data_structure *get_lock_data_structure() const + { + return 0; + } + +public: + // Dummy locks/unlocks + bool try_lock_point(const Point_3 &, int = 0) const + { + return true; + } + + bool try_lock_vertex(Vertex_handle, int = 0) const + { + return true; + } + + bool try_lock_point_no_spin(const Point_3 &, int = 0) const + { + return true; + } + + bool try_lock_vertex_no_spin(Vertex_handle, int = 0) const + { + return true; + } + + bool try_lock_element(Cell_handle, int = 0) const + { + return true; + } + + bool try_lock_element(const Facet &, int = 0) const + { + return true; + } + + + bool is_point_locked_by_this_thread(const Point_3 &) const + { return false; } + + bool is_cell_locked_by_this_thread(const Cell_handle &) const + { return false; } + + void unlock_all_elements() const {} + + // Dummy locks/unlocks + void lock_outdated_cells() const {} + void unlock_outdated_cells() const {} + void lock_moving_vertices() const {} + void unlock_moving_vertices() const {} + void lock_vertex_to_proj() const {} + void unlock_vertex_to_proj() const {} +}; + +#ifdef CGAL_LINKED_WITH_TBB +// Parallel +template +class C3T3_helpers_base +{ +protected: + typedef typename Tr::Geom_traits Gt; + typedef typename Gt::Point_3 Point_3; + typedef typename Tr::Vertex_handle Vertex_handle; + typedef typename Tr::Cell_handle Cell_handle; + typedef typename Tr::Facet Facet; + typedef typename Tr::Lock_data_structure Lock_data_structure; + + C3T3_helpers_base(Lock_data_structure *lock_ds) + : m_lock_ds(lock_ds) {} + + +public: + // LOCKS (CONCURRENCY) + + /*Lock_data_structure *get_lock_data_structure() const + { + return m_lock_ds; + }*/ + + bool try_lock_point(const Point_3 &p, int lock_radius = 0) const + { + if (m_lock_ds) + { + return m_lock_ds->try_lock(p, lock_radius); + } + return true; + } + + bool try_lock_vertex(Vertex_handle vh, int lock_radius = 0) const + { + if (m_lock_ds) + { + return m_lock_ds->try_lock(vh->point(), lock_radius); + } + return true; + } + + bool try_lock_point_no_spin(const Point_3 &p, int lock_radius = 0) const + { + if (m_lock_ds) + { + return m_lock_ds->template try_lock(p, lock_radius); + } + return true; + } + + bool try_lock_vertex_no_spin(Vertex_handle vh, int lock_radius = 0) const + { + return try_lock_point_no_spin(vh->point(), lock_radius); + } + + bool try_lock_element(Cell_handle cell_handle, int lock_radius = 0) const + { + bool success = true; + + // Lock the element area on the grid + for (int iVertex = 0 ; success && iVertex < 4 ; ++iVertex) + { + Vertex_handle vh = cell_handle->vertex(iVertex); + success = try_lock_vertex(vh, lock_radius); + } + + return success; + } + + bool try_lock_element(const Facet &facet, int lock_radius = 0) const + { + bool success = true; + + // Lock the element area on the grid + Cell_handle cell = facet.first; + for (int iVertex = (facet.second+1)&3 ; + success && iVertex != facet.second ; iVertex = (iVertex+1)&3) + { + Vertex_handle vh = cell->vertex(iVertex); + success = try_lock_vertex(vh, lock_radius); + } + + return success; + } + + bool is_point_locked_by_this_thread(const Point_3 &p) const + { + bool locked = true; + if (m_lock_ds) + { + locked = m_lock_ds->is_locked_by_this_thread(p); + } + return locked; + } + + bool is_cell_locked_by_this_thread(const Cell_handle &cell_handle) const + { + bool locked = true; + if (m_lock_ds) + { + for (int iVertex = 0 ; locked && iVertex < 4 ; ++iVertex) + { + locked = m_lock_ds->is_locked_by_this_thread( + cell_handle->vertex(iVertex)->point()); + } + } + return locked; + } + + void unlock_all_elements() const + { + if (m_lock_ds) + { + m_lock_ds->unlock_all_points_locked_by_this_thread(); + } + } + + void lock_outdated_cells() const + { + m_mut_outdated_cells.lock(); + } + void unlock_outdated_cells() const + { + m_mut_outdated_cells.unlock(); + } + + void lock_moving_vertices() const + { + m_mut_moving_vertices.lock(); + } + void unlock_moving_vertices() const + { + m_mut_moving_vertices.unlock(); + } + + void lock_vertex_to_proj() const + { + m_mut_vertex_to_proj.lock(); + } + void unlock_vertex_to_proj() const + { + m_mut_vertex_to_proj.unlock(); + } + +protected: + Lock_data_structure *m_lock_ds; + + typedef tbb::mutex Mutex_type; + mutable Mutex_type m_mut_outdated_cells; + mutable Mutex_type m_mut_moving_vertices; + mutable Mutex_type m_mut_vertex_to_proj; +}; +#endif // CGAL_LINKED_WITH_TBB + + +/************************************************ + * + * C3T3_helpers class + * + ************************************************/ + +template class C3T3_helpers +: public C3T3_helpers_base { // ----------------------------------- // Private types // ----------------------------------- - typedef typename C3T3::Triangulation Tr; - typedef Tr Triangulation; - typedef typename Tr::Geom_traits Gt; - + typedef C3T3_helpers Self; + typedef C3T3_helpers_base Base; + typedef typename C3T3::Concurrency_tag Concurrency_tag; + + typedef typename Base::Lock_data_structure Lock_data_structure; + typedef typename C3T3::Triangulation Tr; + typedef Tr Triangulation; + typedef typename Tr::Geom_traits Gt; + typedef typename Gt::Vector_3 Vector_3; typedef typename Gt::Point_3 Point_3; typedef typename Gt::Plane_3 Plane_3; typedef typename Gt::FT FT; typedef typename Gt::Tetrahedron_3 Tetrahedron; - + typedef typename Tr::Vertex_handle Vertex_handle; typedef typename Tr::Cell_handle Cell_handle; typedef typename Tr::Cell Cell; typedef typename Tr::Facet Facet; - + typedef typename C3T3::Surface_patch_index Surface_patch_index; typedef typename C3T3::Subdomain_index Subdomain_index; typedef typename C3T3::Index Index; typedef boost::optional Surface_patch; typedef boost::optional Subdomain; - + typedef std::vector Cell_vector; typedef std::set Cell_set; typedef std::vector Tet_vector; @@ -397,10 +654,10 @@ typedef std::vector Facet_vector; typedef std::vector Vertex_vector; typedef std::set Vertex_set; - + #ifdef CGAL_INTRUSIVE_LIST typedef Intrusive_list Outdated_cell_set; -#else +#else typedef Cell_set Outdated_cell_set; #endif //CGAL_INTRUSIVE_LIST @@ -410,7 +667,6 @@ typedef Vertex_set Moving_vertices_set; #endif //CGAL_INTRUSIVE_LIST - private: // Facet_boundary stores the edges, of the boundary of surface facets, // with meta-data. @@ -420,30 +676,47 @@ // facet. typedef std::pair Facet_topology_description; typedef std::map Facet_boundary; - + typedef Triangulation_helpers Th; - + public: // ----------------------------------- // Public interface // ----------------------------------- typedef boost::optional Update_mesh; - + + using Base::try_lock_point; + using Base::try_lock_vertex; + using Base::try_lock_point_no_spin; + using Base::try_lock_vertex_no_spin; + using Base::try_lock_element; + using Base::is_point_locked_by_this_thread; + using Base::is_cell_locked_by_this_thread; + using Base::unlock_all_elements; + using Base::lock_outdated_cells; + using Base::unlock_outdated_cells; + using Base::lock_moving_vertices; + using Base::unlock_moving_vertices; + using Base::lock_vertex_to_proj; + using Base::unlock_vertex_to_proj; + /** * Constructor */ - C3T3_helpers(C3T3& c3t3, const MeshDomain& domain) - : c3t3_(c3t3) + C3T3_helpers(C3T3& c3t3, const MeshDomain& domain, + Lock_data_structure *lock_ds = NULL) + : Base(lock_ds) + , c3t3_(c3t3) , tr_(c3t3.triangulation()) , domain_(domain) { } - + /** * @brief tries to move \c old_vertex to \c new_position in the mesh * @param new_position the new position of \c old_vertex * @param old_vertex the old vertex - * @param criterion the criterion which will be used to verify the new + * @param criterion the criterion which will be used to verify the new * position is ok. c3t3 minimal value of new criterion shall not decrease. - * @param modified_vertices contains the vertices incident to cells which + * @param modified_vertices contains the vertices incident to cells which * may have been impacted by relocation * @return a pair which contains: * - a bool which is \c true if the move has been done. @@ -456,21 +729,23 @@ update_mesh(const Point_3& new_position, const Vertex_handle& old_vertex, const SliverCriterion& criterion, - OutputIterator modified_vertices); + OutputIterator modified_vertices, + bool *could_lock_zone = NULL); /** @brief tries to move \c old_vertex to \c new_position in the mesh * - * Same as update_mesh, but with the precondition that + * Same as update_mesh, but with the precondition that * Th().no_topological_change(tr_, old_vertex, new_position, - * incident_cells) return false. + * incident_cells_) return false. */ template std::pair update_mesh_topo_change(const Point_3& new_position, const Vertex_handle& old_vertex, const SliverCriterion& criterion, - OutputIterator modified_vertices); - + OutputIterator modified_vertices, + bool *could_lock_zone = NULL); + /** * Updates mesh moving vertex \c old_vertex to \c new_position. Returns the * new vertex of the triangulation. @@ -482,7 +757,7 @@ const Vertex_handle& old_vertex, OutputIterator modified_vertices, bool fill_modified_vertices = true); - + /** * Updates mesh moving vertex \c old_vertex to \c new_position. Returns the * new vertex of the triangulation. @@ -492,7 +767,7 @@ { return update_mesh(new_position, old_vertex, Emptyset_iterator(), false); } - + /** * Rebuilds restricted Delaunay */ @@ -500,7 +775,7 @@ void rebuild_restricted_delaunay(ForwardIterator first_cell, ForwardIterator last_cell, Moving_vertices_set& moving_vertices); - + #ifdef CGAL_INTRUSIVE_LIST template void rebuild_restricted_delaunay(OutdatedCells& outdated_cells, @@ -520,25 +795,74 @@ * the fitting plane. */ Point_3 - project_on_surface(const Point_3& p, const Vertex_handle& v, + project_on_surface(const Point_3& p, const Vertex_handle& v, Surface_patch_index index = Surface_patch_index()) const; /** - * Returns the minimum value for criterion for incident cells of \c vh + * Returns the minimum value for criterion for incident cells of \c vh */ - template + template FT min_incident_value(const Vertex_handle& vh, const SliverCriterion& criterion) const; - + /** * Moves \c old_vertex to \c new_position * Stores the cells which have to be updated in \c outdated_cells * Updates the Vertex_handle old_vertex to its new value in \c moving_vertices + * The second one (with the could_lock_zone param) is for the parallel version */ Vertex_handle move_point(const Vertex_handle& old_vertex, const Point_3& new_position, Outdated_cell_set& outdated_cells_set, - Moving_vertices_set& moving_vertices); + Moving_vertices_set& moving_vertices) const; + Vertex_handle move_point(const Vertex_handle& old_vertex, + const Point_3& new_position, + Outdated_cell_set& outdated_cells_set, + Moving_vertices_set& moving_vertices, + bool *could_lock_zone) const; + + /** + * Try to lock the incident cells and return them in \c cells + * Return value: + * - false: everything is unlocked and \c cells is empty + * - true: incident cells are locked and \c cells contains all of them + */ + bool + try_lock_and_get_incident_cells(const Vertex_handle& v, + Cell_vector &cells) const; + + /** + * Try to lock ALL the incident cells and return in \c cells the ones + * whose \c filter says "true". + * Return value: + * - false: everything is unlocked and \c cells is empty + * - true: ALL incident cells are locked and \c cells is filled + */ + template + bool + try_lock_and_get_incident_cells(const Vertex_handle& v, + Cell_vector &cells, + const Filter &filter) const; + + /** + * Try to lock ALL the incident cells and return in \c cells the slivers + * Return value: + * - false: everything is unlocked and \c cells is empty + * - true: incident cells are locked and \c cells contains all slivers + */ + template + bool + try_lock_and_get_incident_slivers(const Vertex_handle& v, + const SliverCriterion& criterion, + const FT& sliver_bound, + Cell_vector &cells) const; + + template + void + get_incident_slivers_without_using_tds_data(const Vertex_handle& v, + const SliverCriterion& criterion, + const FT& sliver_bound, + Cell_vector &slivers) const; /** * Outputs to out the sliver (wrt \c criterion and \c sliver_bound) incident @@ -561,8 +885,8 @@ /** * Returns the sliver (wrt \c criterion and \c sliver_bound) incident to \c v - */ - template + */ + template Cell_vector incident_slivers(const Vertex_handle& v, const SliverCriterion& criterion, @@ -573,7 +897,7 @@ return slivers; } - template + template Cell_vector new_incident_slivers(const Vertex_handle& v, const SliverCriterion& criterion, @@ -588,13 +912,13 @@ /** * Returns the number of slivers incident to \c v */ - template + template std::size_t number_of_incident_slivers(const Vertex_handle& v, const SliverCriterion& criterion, const FT& sliver_bound) const; - - template + + template bool is_sliver(const Cell_handle& ch, const SliverCriterion& criterion, @@ -608,8 +932,8 @@ template FT min_sliver_value(const Cell_vector& cells, const SliverCriterion& criterion, - const bool use_cache = true) const; - + const bool use_cache = true) const; + /** * Reset cache validity of all cells of c3t3_ */ @@ -619,8 +943,8 @@ std::for_each(c3t3_.cells_in_complex_begin(),c3t3_.cells_in_complex_end(), bl::bind(&Cell::reset_cache_validity, bl::_1) ); } - -private: + +private: // ----------------------------------- // Usefull Functors // ----------------------------------- @@ -636,7 +960,7 @@ Get_all_facets(const Triangulation& tr, OutputIterator out) : tr_(tr) , out_(out) {} - + void operator()(const Cell_handle& cell) { #ifndef CGAL_MESH_3_NEW_GET_FACETS @@ -650,7 +974,7 @@ // This approach makes less tests if vertices are infinite int i=0; for ( ; i<4 ; ++i ){ - if ( tr_.is_infinite(cell->vertex(i)) ){ + if ( tr_.is_infinite(cell->vertex(i)) ){ *out_++ = canonical_facet(cell,i); return; } @@ -660,7 +984,7 @@ } #endif } - + private: Facet canonical_facet(const Cell_handle& c, const int i) const { @@ -669,7 +993,7 @@ Facet mirror = tr_.mirror_facet(facet); return ( (mirrorneighbor(i); + Cell_handle n = c->neighbor(i); if(c < n){ return Facet(c,i); }else{ @@ -677,13 +1001,13 @@ } #endif } - + private: const Triangulation& tr_; OutputIterator out_; }; - - + + /** * @class Is_in_c3t3 * @@ -695,11 +1019,11 @@ public: Is_in_c3t3(const C3T3& c3t3) : c3t3_(c3t3) { } bool operator()(const Handle& h) const { return c3t3_.is_in_complex(h); } - + private: const C3T3& c3t3_; }; - + /** * @class Is_sliver @@ -715,13 +1039,13 @@ : c3t3_(c3t3) , criterion_(criterion) , bound_(bound) { } - + bool operator()(const Cell_handle& c) const { if ( c3t3_.is_in_complex(c) ) { CGAL_assertion(!c3t3_.triangulation().is_infinite(c)); - + if ( ! c->is_cache_valid() ) { Sliver_criterion_value sc_value(c3t3_.triangulation(), @@ -740,14 +1064,14 @@ else return false; } - + private: const C3T3& c3t3_; const SliverCriterion& criterion_; const FT bound_; }; - - + + /** * @class Update_c3t3 * @@ -759,7 +1083,7 @@ Update_c3t3(const MeshDomain& domain, C3T3& c3t3) : domain_(domain) , c3t3_(c3t3) {} - + /** * @brief Updates facet \c facet in c3t3 * @param facet the facet to update @@ -790,24 +1114,24 @@ typedef typename Gt::Segment_3 Segment_3; typedef typename Gt::Ray_3 Ray_3; typedef typename Gt::Line_3 Line_3; - + // Nothing to do for infinite facets if ( c3t3_.triangulation().is_infinite(facet) ) return Surface_patch(); - + // Functors - typename Gt::Is_degenerate_3 is_degenerate = + typename Gt::Is_degenerate_3 is_degenerate = Gt().is_degenerate_3_object(); - + // Get dual of facet Object dual = c3t3_.triangulation().dual(facet); // The dual is a segment, a ray or a line if ( const Segment_3* p_segment = object_cast(&dual) ) { - if (is_degenerate(*p_segment)) + if (is_degenerate(*p_segment)) return Surface_patch(); - + return dual_intersect(*p_segment,facet, update_c3t3, update_surface_center); @@ -816,7 +1140,7 @@ { if (is_degenerate(*p_ray)) return Surface_patch(); - + return dual_intersect(*p_ray,facet,update_c3t3, update_surface_center); } @@ -825,11 +1149,11 @@ return dual_intersect(*p_line,facet,update_c3t3, update_surface_center); } - + CGAL_error_msg("This should not happen"); return Surface_patch(); } - + /** * @brief Updates cell \c ch in c3t3 * @param ch the cell to update @@ -840,12 +1164,12 @@ { if ( c3t3_.triangulation().is_infinite(ch) ) return false; - + // treat cell const Subdomain subdomain = domain_.is_in_domain_object()(c3t3_.triangulation().dual(ch)); // function dual(cell) updates the circumcenter cache if there is one - + if ( subdomain && update ) { c3t3_.add_to_complex(ch,*subdomain); @@ -857,9 +1181,9 @@ return subdomain; } - + private: - + // Returns true if query intersects the surface. template Surface_patch dual_intersect(const Query& dual, @@ -868,12 +1192,12 @@ const bool update_surface_center) const { typedef typename MeshDomain::Intersection Intersection; - + typename MeshDomain::Construct_intersection construct_intersection = domain_.construct_intersection_object(); -#ifndef CGAL_MESH_3_NO_LONGER_CALLS_DO_INTERSECT_3 - +#ifndef CGAL_MESH_3_NO_LONGER_CALLS_DO_INTERSECT_3 + typename MeshDomain::Do_intersect_surface do_intersect_surface = domain_.do_intersect_surface_object(); Surface_patch surface = do_intersect_surface(dual); @@ -881,16 +1205,16 @@ #else // CGAL_MESH_3_NO_LONGER_CALLS_DO_INTERSECT_3 Intersection intersection = construct_intersection(dual); - Surface_patch surface = - (CGAL::cpp0x::get<2>(intersection) == 0) ? Surface_patch() : + Surface_patch surface = + (CGAL::cpp0x::get<2>(intersection) == 0) ? Surface_patch() : domain_.surface_patch_index(CGAL::cpp0x::get<1>(intersection)); #endif // CGAL_MESH_3_NO_LONGER_CALLS_DO_INTERSECT_3 - + // Update if needed - if(update_c3t3) + if(update_c3t3) { - // Update status in c3t3 + // Update status in c3t3 if(surface) c3t3_.add_to_complex(facet,*surface); else @@ -917,11 +1241,11 @@ facet_m.first->set_facet_surface_center(facet_m.second,Point_3()); } } - + return surface; } - - + + private: const MeshDomain& domain_; C3T3& c3t3_; @@ -959,16 +1283,18 @@ { const Vertex_handle& v = f.first->vertex((k+i)&3); if ( c3t3_.in_dimension(v) > 2 ) - { + { + //lock_vertex_to_proj(); vertex_to_proj.insert(v); + //unlock_vertex_to_proj(); } } } } }; // end class Facet_updater - - + + /** * @class Sliver_criterion_value * @@ -984,11 +1310,11 @@ const SliverCriterion& criterion) : p_tr_(&tr) , criterion_(criterion) {} - + FT operator()(const Cell_handle& ch) const { CGAL_precondition(!p_tr_->is_infinite(ch)); - + if ( ! ch->is_cache_valid() ) { double sliver_value = criterion_(ch); @@ -1000,7 +1326,7 @@ } return ch->sliver_value(); } - + private: // '=' is used, so p_tr_ must be a pointer ... const Tr* p_tr_; @@ -1053,7 +1379,7 @@ const bool do_backup = true) : cell_ids_(c) { - //backup is not done when constructor is called to + //backup is not done when constructor is called to //convert a newly created cell (has nothing to backup) //to a Cell_data_backup if(do_backup) @@ -1077,7 +1403,7 @@ surface_center_index_table_[i] = c->get_facet_surface_center_index(ii); } //note c->next_intrusive() and c->previous_intrusive() - //are lost by 'backup' and 'restore', + //are lost by 'backup' and 'restore', //because all cells are changing during the move //they are not used in update_mesh functions involving a Sliver_criterion } @@ -1089,7 +1415,7 @@ } /** - * new_cell has the same vertices as cell_ids_ + * new_cell has the same vertices as cell_ids_ * (checked before function is called) * resets new_cell's meta-data to its back-uped values */ @@ -1099,7 +1425,7 @@ CGAL_assertion_code(unsigned int nbv_found = 0); for(int i = 0; i < 4; ++i) { - std::size_t new_vi_index = + std::size_t new_vi_index = static_cast(new_cell->vertex(i)->meshing_info()); for(std::size_t j = 0; j < 4; ++j) { @@ -1118,7 +1444,7 @@ private: typedef CGAL::cpp11::array IndexMap; - + void restore(Cell_handle c, const IndexMap& index_map,//new_to_old_indices C3T3& c3t3) @@ -1143,7 +1469,7 @@ { std::size_t old_i = index_map.at(static_cast(i)); Surface_patch_index index = surface_index_table_[old_i]; - //add_to_complex sets the index, and updates the facet counter + //add_to_complex sets the index, and updates the facet counter if(Surface_patch_index() != index) c3t3.add_to_complex(Facet(c, i), index); else @@ -1151,8 +1477,16 @@ c->set_facet_surface_center(i, facet_surface_center_[old_i]); c->set_facet_surface_center_index(i, surface_center_index_table_[old_i]); - //here we don't need to update mirror_facet because it's been either - //backuped, or unchanged + + //we need to update mirror_facet when the i-th neighbor is + // an infinite cell + Cell_handle c2 = c->neighbor(i); + if(c3t3.triangulation().is_infinite(c2)) + { + const int i2 = c2->index(c); + c2->set_facet_surface_center(i2, facet_surface_center_[old_i]); + c2->set_facet_surface_center_index(i2, surface_center_index_table_[old_i]); + } } } @@ -1165,7 +1499,7 @@ FT sliver_value_; Subdomain_index subdomain_index_; CGAL::cpp11::array surface_index_table_; - CGAL::cpp11::array facet_surface_center_; + CGAL::cpp11::array facet_surface_center_; CGAL::cpp11::array surface_center_index_table_; }; @@ -1185,7 +1519,7 @@ Cell_vector c3t3_cells_ = c3t3_cells(cells); return min_sliver_value(c3t3_cells_, criterion, use_cache); } - + Cell_vector c3t3_cells(const Cell_vector& cells) const { Cell_vector c3t3_cells; @@ -1200,24 +1534,24 @@ * Removes objects of [begin,end[ range from \c c3t3_ */ template - void remove_from_c3t3(ForwardIterator begin, ForwardIterator end) + void remove_from_c3t3(ForwardIterator begin, ForwardIterator end) const { while ( begin != end ) c3t3_.remove_from_complex(*begin++); } - + /** * Remove cells and facets of \c cells from c3t3 */ template < typename ForwardIterator > void remove_cells_and_facets_from_c3t3(ForwardIterator cells_begin, - ForwardIterator cells_end) + ForwardIterator cells_end) const { Facet_vector facets = get_facets_not_inplace(cells_begin,cells_end); remove_from_c3t3(facets.begin(), facets.end()); - remove_from_c3t3(cells_begin, cells_end); + remove_from_c3t3(cells_begin, cells_end); } - + /** * Insert into \c out the vertices of range [cells_begin,cells_end[ */ @@ -1231,14 +1565,14 @@ * Backup cells meta-data to a vector of Cell_data_backup */ template - void fill_cells_backup(const CellsVector& cells, + void fill_cells_backup(const CellsVector& cells, CellDataSet& cells_backup) const; template void restore_from_cells_backup(const CellsVector& cells, CellDataSet& cells_backup) const; - - + + /** * Update mesh iff sliver criterion value does not decrease. */ @@ -1249,7 +1583,7 @@ const SliverCriterion& criterion, OutputIterator modified_vertices, const Cell_vector& conflict_cells); - + /** * Move point and returns the set of cells that are not valid anymore, and * the set of cells which have been deleted by the move process. @@ -1259,12 +1593,13 @@ Vertex_handle move_point(const Vertex_handle& old_vertex, const Point_3& new_position, OutdatedCellsOutputIterator outdated_cells, - DeletedCellsOutputIterator deleted_cells); + DeletedCellsOutputIterator deleted_cells) const; - Vertex_handle + Vertex_handle move_point_topo_change(const Vertex_handle& old_vertex, const Point_3& new_position, - Outdated_cell_set& outdated_cells_set); + Outdated_cell_set& outdated_cells_set, + bool *could_lock_zone = NULL) const; template < typename OutdatedCellsOutputIterator, typename DeletedCellsOutputIterator > @@ -1272,37 +1607,37 @@ move_point_topo_change(const Vertex_handle& old_vertex, const Point_3& new_position, OutdatedCellsOutputIterator outdated_cells, - DeletedCellsOutputIterator deleted_cells); - + DeletedCellsOutputIterator deleted_cells) const; + Vertex_handle move_point_topo_change(const Vertex_handle& old_vertex, - const Point_3& new_position); - + const Point_3& new_position) const; + template < typename OutdatedCellsOutputIterator > Vertex_handle move_point_no_topo_change(const Vertex_handle& old_vertex, const Point_3& new_position, - OutdatedCellsOutputIterator outdated_cells); + OutdatedCellsOutputIterator outdated_cells) const; Vertex_handle move_point_no_topo_change(const Vertex_handle& old_vertex, - const Point_3& new_position); - + const Point_3& new_position) const; + /** * Returns the least square plane from v, using adjacent surface points */ Plane_3 get_least_square_surface_plane(const Vertex_handle& v, Point_3& ref_point, Surface_patch_index index = Surface_patch_index()) const; - + /** - * @brief Returns the projection of \c p, using direction of + * @brief Returns the projection of \c p, using direction of * \c projection_vector */ Point_3 project_on_surface_aux(const Point_3& p, const Point_3& ref_point, const Vector_3& projection_vector) const; - + /** * Reverts the move from \c old_point to \c new_vertex. Returns the inserted * vertex located at \c old_point @@ -1314,16 +1649,16 @@ OutputIterator outdated_cells) { // Move vertex - Vertex_handle revert_vertex = + Vertex_handle revert_vertex = move_point_topo_change(new_vertex, old_point, outdated_cells, CGAL::Emptyset_iterator()); //deleted cells CGAL_assertion(Vertex_handle() != revert_vertex); - + return revert_vertex; } - + /** * Returns the boundary of restricted facets of \c facets, and the list of vertices of all restricted facets, @@ -1333,7 +1668,7 @@ get_surface_boundary(const Vertex_handle& moving_vertex, const Facet_vector& facets, Vertex_set& incident_surface_vertices) const; - + /** * Returns the boundary of restricted facets of \c cells and the list of vertices of all restricted facets. @@ -1347,13 +1682,13 @@ get_facets(cells), incident_surface_vertices); } - + /** - * Returns false if there is a vertex belonging to one facet of \c facets + * Returns false if there is a vertex belonging to one facet of \c facets * which has not his dimension < 3 */ bool check_no_inside_vertices(const Facet_vector& facets) const; - + /** * Returns the impacted cells when moving \c vertex to \c conflict_point */ @@ -1361,36 +1696,37 @@ OutputIterator get_conflict_zone_no_topo_change(const Vertex_handle& vertex, OutputIterator conflict_cells) const; - + template OutputIterator get_conflict_zone_topo_change(const Vertex_handle& vertex, const Point_3& conflict_point, OutputIterator conflict_cells) const; - - template void get_conflict_zone_topo_change(const Vertex_handle& v, const Point_3& conflict_point, CellsOutputIterator insertion_conflict_cells, FacetsOutputIterator insertion_conflict_boundary, - CellsOutputIterator removal_conflict_cells) const; + CellsOutputIterator removal_conflict_cells, + bool *could_lock_zone = NULL) const; + - template < typename ConflictCellsInputIterator, typename OutdatedCellsOutputIterator, typename DeletedCellsOutputIterator > - Vertex_handle + Vertex_handle move_point_topo_change_conflict_zone_known(const Vertex_handle& old_vertex, const Point_3& new_position, const Facet& insertion_boundary_facet, ConflictCellsInputIterator insertion_conflict_cells_begin, ConflictCellsInputIterator insertion_conflict_cells_end, ConflictCellsInputIterator removal_conflict_cells_begin, - ConflictCellsInputIterator removal_conflict_cells_end, + ConflictCellsInputIterator removal_conflict_cells_end, OutdatedCellsOutputIterator outdated_cells, - DeletedCellsOutputIterator deleted_cells); + DeletedCellsOutputIterator deleted_cells) const; /** * Updates \c boundary wrt \c edge: if edge is already in boundary we remove @@ -1401,7 +1737,7 @@ const Vertex_handle third_vertex, const Surface_patch_index& surface_index) const { - const typename Facet_boundary::value_type x = + const typename Facet_boundary::value_type x = std::make_pair(edge, std::make_pair(surface_index, std::make_pair(c3t3_.in_dimension(third_vertex), @@ -1411,13 +1747,13 @@ ); typename Facet_boundary::iterator boundary_it = boundary.find(edge); - + if ( boundary_it != boundary.end() ) boundary.erase(boundary_it); else boundary.insert(x); } - + /** * Returns the facets of \c cells (returns each facet only once i.e. use * canonical facet) @@ -1426,7 +1762,7 @@ { return get_facets(cells.begin(),cells.end()); } - + // TODO: write get_facets so that it uses update_facets with a FacetUpdater that calls push_back #if defined(CGAL_MESH_3_GET_FACETS_USING_INTRUSIVE_LIST) && defined(CGAL_INTRUSIVE_LIST) @@ -1437,13 +1773,13 @@ Facet_vector result; // AF: todo: resize? #ifdef CGAL_CONSTRUCT_INTRUSIVE_LIST_RANGE_CONSTRUCTOR Intrusive_list outdated_cells(first_cell, last_cell); -#else +#else Intrusive_list outdated_cells; for( ;first_cell!= last_cell; ++first_cell){ - outdated_cells.insert(*first_cell); + outdated_cells.insert(*first_cell); } #endif - + for(typename Intrusive_list::iterator it = outdated_cells.begin(); it != outdated_cells.end(); ++it){ @@ -1459,7 +1795,7 @@ result.push_back(Facet(cell,i)); } } else { // report it now or never - if(cell < n){ + if(cell < n){ result.push_back(Facet(cell,i)); }else { result.push_back(Facet(n,n->index(cell))); @@ -1475,7 +1811,7 @@ result.push_back(Facet(cell,i)); } } else { // report it now or never - if(cell < n){ + if(cell < n){ result.push_back(Facet(cell,i)); }else { result.push_back(Facet(n,n->index(cell))); @@ -1497,15 +1833,15 @@ { // Get all facets typedef Get_all_facets > Get_facets; - + Facet_vector all_facets; all_facets.reserve(64); std::for_each(first_cell, last_cell, Get_facets(tr_,std::back_inserter(all_facets))); - + std::sort(all_facets.begin(), all_facets.end()); - + // Keep one copy of each facet (maybe copy could be avoided) // typename Facet_vector::iterator all_facets_end = // std::unique(all_facets.begin(), all_facets.end()); @@ -1514,7 +1850,7 @@ std::unique_copy(all_facets.begin(), all_facets.end(), std::back_inserter(facets)); - + return facets; } #endif @@ -1523,52 +1859,60 @@ template void update_facets(Intrusive_list& outdated_cells, FacetUpdater updater) { - typename Intrusive_list::iterator it; - for(it = outdated_cells.begin(); - it != outdated_cells.end(); - ++it) +# ifdef CGAL_LINKED_WITH_TBB + // Parallel + if (boost::is_convertible::value) + { + tbb::parallel_do( + outdated_cells.begin(), outdated_cells.end(), + Update_cell_facets(tr_, updater)); + } + // Sequential + else +# endif // CGAL_LINKED_WITH_TBB { - Cell_handle cell = *it; - - int i=0; - bool inf = false; - for ( ; i<4 && (!inf) ; ++i ){ - if ( tr_.is_infinite(cell->vertex(i)) ){ - inf = true; - Cell_handle n = cell->neighbor(i); - if(n->next_intrusive() != Cell_handle()){// the neighbor is also outdated - if(cell < n){ // otherwise n will report it later - updater(Facet(cell,i)); - } - } else { // report it now or never - if(cell < n){ - updater(Facet(cell,i)); - }else { - updater(Facet(n,n->index(cell))); - } - } - } - } - if(! inf){ - for ( i=0 ; i<4 ; ++i ){ - Cell_handle n = cell->neighbor(i); - if(n->next_intrusive() != Cell_handle()){// the neighbor is also outdated - if(cell < n){ // otherwise n will report it later - updater(Facet(cell,i)); - } - } else { // report it now or never - if(cell < n){ - updater(Facet(cell,i)); - }else { - updater(Facet(n,n->index(cell))); - } - } - } + typename Intrusive_list::iterator it; + for(it = outdated_cells.begin(); + it != outdated_cells.end(); + ++it) + { + Update_cell_facets ucf(tr_, updater); + ucf(*it); } } } #endif //CGAL_INTRUSIVE_LIST + // Used by the parallel version + template + void update_facets(std::vector& outdated_cells_vector, FacetUpdater updater) + { +# ifdef CGAL_LINKED_WITH_TBB + // Parallel + if (boost::is_convertible::value) + { + tbb::parallel_for + ( + tbb::blocked_range(0, outdated_cells_vector.size()), + Update_cell_facets_for_parallel_for( + tr_, updater, outdated_cells_vector) + ); + } + // Sequential + else +# endif // CGAL_LINKED_WITH_TBB + { + typename std::vector::iterator it; + for(it = outdated_cells_vector.begin(); + it != outdated_cells_vector.end(); + ++it) + { + Update_cell_facets ucf(tr_, updater); + ucf(*it); + } + } + } + /** * Returns the facets of \c cells (returns each facet only once i.e. use @@ -1579,15 +1923,15 @@ ForwardIterator last_cell) const { typedef Get_all_facets > Get_facets; - + Facet_vector all_facets; all_facets.reserve(64); std::for_each(first_cell, last_cell, Get_facets(tr_,std::back_inserter(all_facets))); - + std::sort(all_facets.begin(), all_facets.end()); - + // Keep one copy of each facet (maybe copy could be avoided) // typename Facet_vector::iterator all_facets_end = // std::unique(all_facets.begin(), all_facets.end()); @@ -1596,10 +1940,11 @@ std::unique_copy(all_facets.begin(), all_facets.end(), std::back_inserter(facets)); - CGAL_HISTOGRAM_PROFILER("|facets|", facets.size()); + CGAL_HISTOGRAM_PROFILER("|facets|", + static_cast(facets.size())); return facets; } - + /** * Returns false iff a surface facet of `cells` has entered or left the @@ -1615,7 +1960,7 @@ // Todo: improve this (maybe we don't have to check if no facet is on surface) Facet_vector facets = get_facets(cells); Facet_vector surface_facets; - + // Check that nothing changed Update_c3t3 checker(domain_,c3t3_); for ( typename Facet_vector::iterator fit = facets.begin() ; @@ -1634,20 +1979,20 @@ ((bool)sp && c3t3_.surface_patch_index(*fit) != sp.get()) ) return false; } - + return true; } /** * Restore mesh for cells and facets of \c cells, using domain_ - */ + */ template void restore_mesh(ForwardIterator first_cell, ForwardIterator last_cell) { Facet_vector facets = get_facets(first_cell, last_cell); restore_mesh(first_cell, last_cell, facets.begin(), facets.end()); } - + /** * Restore mesh for cells of \c cells and facets of \c facets, using domain_ */ @@ -1662,9 +2007,9 @@ std::for_each(first_facet, last_facet, updater); std::for_each(first_cell, last_cell, updater); } - + /** - * Returns true if facets of \c facets have the same boundary as + * Returns true if facets of \c facets have the same boundary as * \c old_boundary, and if the list of vertices has not changed. */ bool check_surface_mesh(const Vertex_handle& moving_vertex, @@ -1682,17 +2027,18 @@ new_boundary.end(), old_boundary.begin()) ); } - + + void set_facet_visited(const Facet& facet) { facet.first->set_facet_visited(facet.second); const Facet mirror_facet = tr_.mirror_facet(facet); - mirror_facet.first->set_facet_visited(mirror_facet.second); + mirror_facet.first->set_facet_visited(mirror_facet.second); } - + /** * Orders handles \c h1, \c h2 & \c h3 - */ + */ template void order_handles(Handle& h1, Handle& h2, Handle& h3) const { @@ -1700,11 +2046,11 @@ if ( h2 < h1 ) std::swap(h1,h2); - + if ( h3 < h2 ) { std::swap(h2,h3); - + if ( h2 < h1 ) // don't need to compare h2 & h1 if h2 didn't change std::swap(h1,h2); } @@ -1733,7 +2079,7 @@ reset_circumcenter_cache(boost::begin(cell_range), boost::end(cell_range)); } - + template void reset_circumcenter_cache(CellForwardIterator cells_begin, CellForwardIterator cells_end) const @@ -1743,53 +2089,306 @@ bl::bind(&Cell::invalidate_circumcenter, *bl::_1) ); } + private: + + // Functor for update_facets function (base) + template + class Update_cell_facets + { + Tr & m_tr; + FacetUpdater_ & m_facet_updater; + + protected: + + void update(const Cell_handle& cell) const + { + Cell_handle null_cell; + bool inf = false; + for (int i=0 ; i<4 && (!inf) ; ++i ){ + if ( m_tr.is_infinite(cell->vertex(i)) ){ + inf = true; + Cell_handle n = cell->neighbor(i); + if(n->next_intrusive() != null_cell){// the neighbor is also outdated + if(cell < n){ // otherwise n will report it later + Facet f(cell,i); + m_facet_updater(f); + } + } else { // report it now or never + if(cell < n){ + Facet f(cell,i); + m_facet_updater(f); + }else { + Facet f(n,n->index(cell)); + m_facet_updater(f); + } + } + } + } + if(! inf){ + for ( int i=0 ; i<4 ; ++i ){ + Cell_handle n = cell->neighbor(i); + if(n->next_intrusive() != null_cell){// the neighbor is also outdated + if(cell < n){ // otherwise n will report it later + Facet f(cell,i); + m_facet_updater(f); + } + } else { // report it now or never + if(cell < n){ + Facet f(cell,i); + m_facet_updater(f); + }else { + Facet f(n,n->index(cell)); + m_facet_updater(f); + } + } + } + } + } + + public: + // Constructor + Update_cell_facets(Tr &tr, + FacetUpdater_& fu) + : m_tr(tr), m_facet_updater(fu) + {} + + // Constructor + Update_cell_facets(const Update_cell_facets &uf) + : m_tr(uf.m_tr), m_facet_updater(uf.m_facet_updater) + {} + + // operator() + void operator()(const Cell_handle& cell) const + { + update(cell); + } + }; + +#ifdef CGAL_LINKED_WITH_TBB + // Same functor: special version for tbb:parallel_for + template + class Update_cell_facets_for_parallel_for + : Update_cell_facets + { + typedef Update_cell_facets Base; + using Base::update; + + const std::vector & m_outdated_cells; + + public: + // Constructor + Update_cell_facets_for_parallel_for( + Tr &tr, + FacetUpdater_& fu, + const std::vector &oc) + : Base(tr, fu), m_outdated_cells(oc) + {} + + // Constructor + Update_cell_facets_for_parallel_for( + const Update_cell_facets_for_parallel_for &uf) + : Base(uf), m_outdated_cells(uf.m_outdated_cells) + {} + + // operator() + void operator()(const tbb::blocked_range& r) const + { + for( size_t i = r.begin() ; i != r.end() ; ++i) + update(m_outdated_cells[i]); + } + }; +#endif //CGAL_LINKED_WITH_TBB + + // ----------------------------------- + // ----------------------------------- + // ----------------------------------- + + // Functor for rebuild_restricted_delaunay function + template + class Update_cell + { + C3T3 & m_c3t3; + Update_c3t3_ & m_updater; + + protected: + typedef typename C3T3_::Cell_handle Cell_handle; + + void update(const Cell_handle& cell) const + { + m_c3t3.remove_from_complex(cell); + m_updater(cell); + } + + public: + // Constructor + Update_cell(C3T3_ &c3t3, Update_c3t3_& updater) + : m_c3t3(c3t3), m_updater(updater) + {} + + // Constructor + Update_cell(const Update_cell &uc) + : m_c3t3(uc.m_c3t3), m_updater(uc.m_updater) + {} + + // operator() + void operator()(const Cell_handle& cell) const + { + update(cell); + } + }; + +#ifdef CGAL_LINKED_WITH_TBB + // Same functor: special version for tbb:parallel_for + template + class Update_cell_for_parallel_for + : Update_cell + { + typedef Update_cell Base; + using Base::update; + + const std::vector & m_outdated_cells; + + public: + // Constructor + Update_cell_for_parallel_for( + C3T3_ &c3t3, + Update_c3t3_& updater, + const std::vector &oc) + : Base(c3t3, updater), m_outdated_cells(oc) + {} + + // Constructor + Update_cell_for_parallel_for( + const Update_cell_for_parallel_for &uc) + : Base(uc), m_outdated_cells(uc.m_outdated_cells) + {} + + // operator() + void operator()(const tbb::blocked_range& r) const + { + for( size_t i = r.begin() ; i != r.end() ; ++i) + update(m_outdated_cells[i]); + } + }; +#endif //CGAL_LINKED_WITH_TBB + + // ----------------------------------- + // ----------------------------------- + // ----------------------------------- + + // Functor for rebuild_restricted_delaunay function +#ifdef CGAL_LINKED_WITH_TBB + template + class Update_facet + { + const C3T3_helpers_ & m_c3t3_helpers; + C3T3_ & m_c3t3; + Update_c3t3_ & m_updater; + Vertex_to_proj_set_ & m_vertex_to_proj; + + typedef typename C3T3_::Vertex_handle Vertex_handle; + typedef typename C3T3_::Cell_handle Cell_handle; + typedef typename C3T3_::Facet Facet; + typedef typename C3T3::Surface_patch_index Surface_patch_index; + + public: + // Constructor + Update_facet(const C3T3_helpers_ & c3t3_helpers, + C3T3_ &c3t3, Update_c3t3_& updater, + Vertex_to_proj_set_ &vertex_to_proj) + : m_c3t3_helpers(c3t3_helpers), m_c3t3(c3t3), m_updater(updater), + m_vertex_to_proj(vertex_to_proj) + {} + + // Constructor + Update_facet(const Update_facet &uc) + : m_c3t3_helpers(uc.m_c3t3_helpers), m_c3t3(uc.m_c3t3), + m_updater(uc.m_updater), m_vertex_to_proj(uc.m_vertex_to_proj) + {} + + // operator() + void operator()( const Facet& facet ) const + { + // Update facet + m_c3t3.remove_from_complex(facet); + m_updater(facet); + + // Update m_vertex_to_proj + if ( m_c3t3.is_in_complex(facet) ) + { + // Iterate on vertices + int k = facet.second; + for ( int i=1 ; i<4 ; ++i ) + { + const Vertex_handle& v = facet.first->vertex((k+i)&3); + if ( m_c3t3.in_dimension(v) > 2 ) + { + std::pair p + = std::make_pair(v, m_c3t3.surface_patch_index(facet)); + m_c3t3_helpers.lock_vertex_to_proj(); + m_vertex_to_proj.insert(p); + m_c3t3_helpers.unlock_vertex_to_proj(); + } + } + } + } + }; +#endif + // ----------------------------------- // Private data // ----------------------------------- C3T3& c3t3_; Tr& tr_; const MeshDomain& domain_; -}; - - +}; // class C3T3_helpers + + template template std::pair::Vertex_handle> -C3T3_helpers:: +C3T3_helpers:: update_mesh(const Point_3& new_position, const Vertex_handle& old_vertex, const SliverCriterion& criterion, - OutputIterator modified_vertices) + OutputIterator modified_vertices, + bool *could_lock_zone) { // std::cerr << "\nupdate_mesh[v1](" << new_position << ",\n" // << " " << (void*)(&*old_vertex) << "=" << old_vertex->point() // << ")\n"; - Cell_vector incident_cells; - incident_cells.reserve(64); - tr_.incident_cells(old_vertex, std::back_inserter(incident_cells)); - if ( Th().no_topological_change(tr_, old_vertex, new_position, incident_cells) ) + if (could_lock_zone) + *could_lock_zone = true; + + Cell_vector incident_cells_; + incident_cells_.reserve(64); + tr_.incident_cells(old_vertex, std::back_inserter(incident_cells_)); + if ( Th().no_topological_change(tr_, old_vertex, new_position, incident_cells_) ) { + return update_mesh_no_topo_change(new_position, old_vertex, criterion, modified_vertices, - incident_cells); + incident_cells_); } else { return update_mesh_topo_change(new_position, old_vertex, criterion, - modified_vertices); + modified_vertices, + could_lock_zone); } } template template std::pair::Vertex_handle> -C3T3_helpers:: +C3T3_helpers:: update_mesh_no_topo_change(const Point_3& new_position, const Vertex_handle& old_vertex, const SliverCriterion& criterion, @@ -1814,11 +2413,11 @@ reset_circumcenter_cache(conflict_cells); reset_sliver_cache(conflict_cells); move_point_no_topo_change(old_vertex,new_position); - + // Check that surface mesh is still valid - // and Get new criterion value (conflict_zone did not change) + // and Get new criterion value (conflict_zone did not change) // warnings : valid_move updates caches - // verify_surface does not change c3t3 when returns false, + // verify_surface does not change c3t3 when returns false, // but it does change circumcenters if( verify_surface(conflict_cells) && criterion.valid_move(c3t3_cells(conflict_cells))) @@ -1849,11 +2448,12 @@ template template std::pair::Vertex_handle> -C3T3_helpers:: +C3T3_helpers:: update_mesh_topo_change(const Point_3& new_position, const Vertex_handle& old_vertex, const SliverCriterion& criterion, - OutputIterator modified_vertices) + OutputIterator modified_vertices, + bool *could_lock_zone) { // std::cerr << "update_mesh_topo_change(\n" // << new_position << ",\n" @@ -1867,7 +2467,11 @@ get_conflict_zone_topo_change(old_vertex, new_position, std::inserter(insertion_conflict_cells,insertion_conflict_cells.end()), std::back_inserter(insertion_conflict_boundary), - std::inserter(removal_conflict_cells, removal_conflict_cells.end())); + std::inserter(removal_conflict_cells, removal_conflict_cells.end()), + could_lock_zone); + + if (could_lock_zone && *could_lock_zone == false) + return std::make_pair(false, Vertex_handle()); if(insertion_conflict_boundary.empty()) return std::make_pair(false,old_vertex); //new_location is a vertex already @@ -1876,7 +2480,7 @@ conflict_cells.reserve(insertion_conflict_cells.size()+removal_conflict_cells.size()); std::set_union(insertion_conflict_cells.begin(), insertion_conflict_cells.end(), removal_conflict_cells.begin(), removal_conflict_cells.end(), - std::back_inserter(conflict_cells)); + std::back_inserter(conflict_cells)); //backup metadata std::set cells_backup; @@ -1890,13 +2494,13 @@ Vertex_set old_incident_surface_vertices; Facet_boundary old_surface_boundary = get_surface_boundary(old_vertex, conflict_cells, old_incident_surface_vertices); - + reset_circumcenter_cache(conflict_cells); reset_sliver_cache(conflict_cells); Cell_vector outdated_cells; outdated_cells.reserve(64); - Vertex_handle new_vertex = + Vertex_handle new_vertex = move_point_topo_change_conflict_zone_known(old_vertex, new_position, insertion_conflict_boundary[0], insertion_conflict_cells.begin(), @@ -1907,18 +2511,18 @@ CGAL::Emptyset_iterator()); // If nothing changed, return - if ( old_position == new_vertex->point() ) + if ( old_position == new_vertex->point() ) { // std::cerr << "update_mesh_topo_change: no move!\n"; // check_c3t3(c3t3_); return std::make_pair(false,old_vertex); } - + restore_mesh(outdated_cells.begin(),outdated_cells.end()); // std::cerr << "new_sliver_value=" << new_sliver_value << std::endl; // Check that surface boundary does not change. - // This check ensures that vertices which are inside c3t3 stay inside. + // This check ensures that vertices which are inside c3t3 stay inside. if (criterion.valid_move(c3t3_cells(outdated_cells)) && check_surface_mesh(new_vertex, get_facets(outdated_cells), @@ -1956,11 +2560,11 @@ return std::make_pair(false,revert_vertex); } } - + template -template +template typename C3T3_helpers::Vertex_handle -C3T3_helpers:: +C3T3_helpers:: update_mesh(const Point_3& new_position, const Vertex_handle& old_vertex, OutputIterator modified_vertices, @@ -1975,51 +2579,118 @@ std::back_inserter(outdated_cells), CGAL::Emptyset_iterator()); // move_point has invalidated caches - + restore_mesh(outdated_cells.begin(),outdated_cells.end()); - + // Fill modified vertices - if ( fill_vertices + if ( fill_vertices && !(boost::is_same::value)) { fill_modified_vertices(outdated_cells.begin(), outdated_cells.end(), - new_vertex, modified_vertices); + new_vertex, modified_vertices); } - - return new_vertex; + + return new_vertex; } - + #ifdef CGAL_INTRUSIVE_LIST template template void -C3T3_helpers:: +C3T3_helpers:: rebuild_restricted_delaunay(OutdatedCells& outdated_cells, Moving_vertices_set& moving_vertices) { typename OutdatedCells::iterator first_cell = outdated_cells.begin(); typename OutdatedCells::iterator last_cell = outdated_cells.end(); Update_c3t3 updater(domain_,c3t3_); - + +# ifdef CGAL_MESH_3_PROFILING + std::cerr << std::endl << " Updating cells..."; + WallClockTimer t; + size_t num_cells = c3t3_.number_of_cells_in_complex(); +# endif + // Updates cells - while ( first_cell != last_cell ) + // Note: ~58% of rebuild_restricted_delaunay time + + std::set vertex_to_proj; + +# ifdef CGAL_LINKED_WITH_TBB + // Parallel + if (boost::is_convertible::value) + { + std::vector outdated_cells_vector; + outdated_cells_vector.reserve(outdated_cells.size()); + for ( ; first_cell != last_cell ; ++first_cell) + { + outdated_cells_vector.push_back(*first_cell); + } + + tbb::parallel_for( + tbb::blocked_range(0, outdated_cells_vector.size()), + Update_cell_for_parallel_for( + c3t3_, updater, outdated_cells_vector)); + +# ifdef CGAL_MESH_3_PROFILING + std::cerr << " done in " << t.elapsed() << " seconds (#cells from " + << num_cells << " to " << c3t3_.number_of_cells_in_complex() << ")." + << std::endl; + std::cerr << " Updating facets..."; + t.reset(); +# endif + + // Get facets (returns each canonical facet only once) + // Note: ~42% of rebuild_restricted_delaunay time + // Facet_vector facets; + lock_vertex_to_proj(); + Facet_updater facet_updater(c3t3_,vertex_to_proj, updater); + unlock_vertex_to_proj(); + update_facets(outdated_cells_vector, facet_updater); + + // now we can clear + outdated_cells.clear(); + } + // Sequential + else +# endif // CGAL_LINKED_WITH_TBB { - const Cell_handle cell = *first_cell++; - c3t3_.remove_from_complex(cell); - updater(cell); + while ( first_cell != last_cell ) + { + Cell_handle cell = *first_cell++; + c3t3_.remove_from_complex(cell); + updater(cell); + } + +# ifdef CGAL_MESH_3_PROFILING + std::cerr << " done in " << t.elapsed() << " seconds (#cells from " + << num_cells << " to " << c3t3_.number_of_cells_in_complex() << ")." + << std::endl; + std::cerr << " Updating facets..."; + t.reset(); +# endif + + // Get facets (returns each canonical facet only once) + // Note: ~42% of rebuild_restricted_delaunay time + // Facet_vector facets; + Facet_updater facet_updater(c3t3_,vertex_to_proj, updater); + update_facets(outdated_cells, facet_updater); + + // now we can clear + outdated_cells.clear(); } - // Get facets (returns each canonical facet only once) - // Facet_vector facets; - std::set vertex_to_proj; - Facet_updater facet_updater(c3t3_,vertex_to_proj, updater); - update_facets(outdated_cells, facet_updater); - - // now we can clear - outdated_cells.clear(); +# ifdef CGAL_MESH_3_PROFILING + std::cerr << " done in " << t.elapsed() << " seconds (" + << vertex_to_proj.size() << " vertices to project)." << std::endl; + std::cerr << " Projecting interior vertices..."; + t.reset(); +# endif - CGAL_HISTOGRAM_PROFILER("|vertex_to_proj|=", vertex_to_proj.size()); + CGAL_HISTOGRAM_PROFILER("|vertex_to_proj|=", + static_cast(vertex_to_proj.size())); // Project interior vertices + // Note: ~0% of rebuild_restricted_delaunay time // TODO : iterate to be sure no interior vertice become on the surface // because of move ? for ( typename std::set::iterator it = vertex_to_proj.begin() ; @@ -2029,68 +2700,101 @@ Point_3 new_pos = project_on_surface((*it)->point(),*it); if ( new_pos != Point_3() ) - { + { //freezing needs 'erase' to be done before the vertex is actually destroyed // Update moving vertices (it becomes new_vertex) moving_vertices.erase(*it); - + Vertex_handle new_vertex = update_mesh(new_pos,*it); c3t3_.set_dimension(new_vertex,2); moving_vertices.insert(new_vertex); } } + +# ifdef CGAL_MESH_3_PROFILING + std::cerr << " done in " << t.elapsed() << " seconds." << std::endl; +# endif } #endif //CGAL_INTRUSIVE_LIST template template void -C3T3_helpers:: +C3T3_helpers:: rebuild_restricted_delaunay(ForwardIterator first_cell, ForwardIterator last_cell, Moving_vertices_set& moving_vertices) { Update_c3t3 updater(domain_,c3t3_); - + // Get facets (returns each canonical facet only once) Facet_vector facets = get_facets(first_cell, last_cell); - + // Updates cells - while ( first_cell != last_cell ) + // Note: ~58% of rebuild_restricted_delaunay time +#ifdef CGAL_LINKED_WITH_TBB + // Parallel + if (boost::is_convertible::value) { - const Cell_handle& cell = *first_cell++; - c3t3_.remove_from_complex(cell); - updater(cell); + tbb::parallel_do(first_cell, last_cell, + Update_cell(c3t3_, updater)); } - - // Updates facets - std::set > vertex_to_proj; - for ( typename Facet_vector::iterator fit = facets.begin() ; - fit != facets.end() ; - ++fit ) + // Sequential + else +#endif // CGAL_LINKED_WITH_TBB { - // Update facet - c3t3_.remove_from_complex(*fit); - updater(*fit); + while ( first_cell != last_cell ) + { + Update_cell uc(c3t3_, updater); + uc(*first_cell++); + } + } - // Update vertex_to_proj - if ( c3t3_.is_in_complex(*fit) ) + // Updates facets + typedef std::set > + Vertex_to_proj_set; + Vertex_to_proj_set vertex_to_proj; +#ifdef CGAL_LINKED_WITH_TBB + // Parallel + if (boost::is_convertible::value) + { + tbb::parallel_do( + facets.begin(), facets.end(), + Update_facet( + *this, c3t3_, updater, vertex_to_proj) + ); + } + // Sequential + else +#endif // CGAL_LINKED_WITH_TBB + { + for ( typename Facet_vector::iterator fit = facets.begin() ; + fit != facets.end() ; + ++fit ) { - // Iterate on vertices - int k = fit->second; - for ( int i=1 ; i<4 ; ++i ) - { - const Vertex_handle& v = fit->first->vertex((k+i)&3); - if ( c3t3_.in_dimension(v) > 2 ) - { - vertex_to_proj.insert - (std::make_pair(v, c3t3_.surface_patch_index(*fit))); + // Update facet + c3t3_.remove_from_complex(*fit); + updater(*fit); + + // Update vertex_to_proj + if ( c3t3_.is_in_complex(*fit) ) + { + // Iterate on vertices + int k = fit->second; + for ( int i=1 ; i<4 ; ++i ) + { + const Vertex_handle& v = fit->first->vertex((k+i)&3); + if ( c3t3_.in_dimension(v) > 2 ) + { + vertex_to_proj.insert + (std::make_pair(v, c3t3_.surface_patch_index(*fit))); + } } } } } - + // Project interior vertices // TODO : iterate to be sure no interior vertice become on the surface // because of move ? @@ -2109,7 +2813,7 @@ Vertex_handle new_vertex = update_mesh(new_pos,it->first); c3t3_.set_dimension(new_vertex,2); - + moving_vertices.insert(new_vertex); } } @@ -2119,24 +2823,24 @@ template template -typename C3T3_helpers::Vertex_handle -C3T3_helpers:: +typename C3T3_helpers::Vertex_handle +C3T3_helpers:: move_point(const Vertex_handle& old_vertex, const Point_3& new_position, OutdatedCellsOutputIterator outdated_cells, - DeletedCellsOutputIterator deleted_cells) + DeletedCellsOutputIterator deleted_cells) const { - // std::cerr << "C3T3_helpers::move_point[v2](" + // std::cerr << "C3T3_helpers::move_point[v2](" // << (void*)(&*old_vertex) << " = " << old_vertex->point() // << " , " << new_position << ")\n"; - Cell_vector incident_cells; - incident_cells.reserve(64); - tr_.incident_cells(old_vertex, std::back_inserter(incident_cells)); - if ( Th().no_topological_change(tr_, old_vertex, new_position, incident_cells) ) - { - reset_circumcenter_cache(incident_cells); - reset_sliver_cache(incident_cells); - std::copy(incident_cells.begin(),incident_cells.end(), outdated_cells); + Cell_vector incident_cells_; + incident_cells_.reserve(64); + tr_.incident_cells(old_vertex, std::back_inserter(incident_cells_)); + if ( Th().no_topological_change(tr_, old_vertex, new_position, incident_cells_) ) + { + reset_circumcenter_cache(incident_cells_); + reset_sliver_cache(incident_cells_); + std::copy(incident_cells_.begin(),incident_cells_.end(), outdated_cells); return move_point_no_topo_change(old_vertex, new_position); } @@ -2149,22 +2853,23 @@ } } +// Sequential template -typename C3T3_helpers::Vertex_handle -C3T3_helpers:: +typename C3T3_helpers::Vertex_handle +C3T3_helpers:: move_point(const Vertex_handle& old_vertex, const Point_3& new_position, - Outdated_cell_set& outdated_cells_set, - Moving_vertices_set& moving_vertices) + Outdated_cell_set& outdated_cells_set, + Moving_vertices_set& moving_vertices) const { - Cell_vector incident_cells; - incident_cells.reserve(64); - tr_.incident_cells(old_vertex, std::back_inserter(incident_cells)); - if ( Th().no_topological_change(tr_, old_vertex, new_position, incident_cells) ) - { - reset_circumcenter_cache(incident_cells); - reset_sliver_cache(incident_cells); - std::copy(incident_cells.begin(),incident_cells.end(), + Cell_vector incident_cells_; + incident_cells_.reserve(64); + tr_.incident_cells(old_vertex, std::back_inserter(incident_cells_)); + if ( Th().no_topological_change(tr_, old_vertex, new_position, incident_cells_) ) + { + reset_circumcenter_cache(incident_cells_); + reset_sliver_cache(incident_cells_); + std::copy(incident_cells_.begin(),incident_cells_.end(), std::inserter(outdated_cells_set, outdated_cells_set.end())); return move_point_no_topo_change(old_vertex, new_position); } @@ -2176,36 +2881,123 @@ moving_vertices.insert(new_vertex); return new_vertex; - } -} + } +} +// Parallel +// In case of success (could_lock_zone = true), the zone is locked after the call +// ==> the caller needs to call "unlock_all_elements" by itself +// In case of failure (could_lock_zone = false), the zone is unlocked by this function template -typename C3T3_helpers::Vertex_handle -C3T3_helpers:: +typename C3T3_helpers::Vertex_handle +C3T3_helpers:: +move_point(const Vertex_handle& old_vertex, + const Point_3& new_position, + Outdated_cell_set& outdated_cells_set, + Moving_vertices_set& moving_vertices, + bool *could_lock_zone) const +{ + CGAL_assertion(could_lock_zone != NULL); + *could_lock_zone = true; + + if (!try_lock_vertex(old_vertex)) // LOCK + { + *could_lock_zone = false; + unlock_all_elements(); + return Vertex_handle(); + } + + //======= Get incident cells ========== + Cell_vector incident_cells_; + incident_cells_.reserve(64); + if (try_lock_and_get_incident_cells(old_vertex, incident_cells_) == false) + { + *could_lock_zone = false; + return Vertex_handle(); + } + //======= /Get incident cells ========== + + if (!try_lock_point(new_position)) // LOCK + { + *could_lock_zone = false; + unlock_all_elements(); + return Vertex_handle(); + } + if ( Th().no_topological_change(tr_, old_vertex, new_position, incident_cells_) ) + { + reset_circumcenter_cache(incident_cells_); + reset_sliver_cache(incident_cells_); + + lock_outdated_cells(); + std::copy(incident_cells_.begin(),incident_cells_.end(), + std::inserter(outdated_cells_set, outdated_cells_set.end())); + unlock_outdated_cells(); + + Vertex_handle new_vertex = + move_point_no_topo_change(old_vertex, new_position); + + // Don't "unlock_all_elements" here, the caller may need it to do it himself + return new_vertex; + } + else + { + //moving_vertices.erase(old_vertex); MOVED BELOW + + Vertex_handle new_vertex = + move_point_topo_change(old_vertex, new_position, outdated_cells_set, + could_lock_zone); + + if (*could_lock_zone == false) + { + unlock_all_elements(); + return Vertex_handle(); + } + + + lock_moving_vertices(); + moving_vertices.erase(old_vertex); + moving_vertices.insert(new_vertex); + unlock_moving_vertices(); + + // Don't "unlock_all_elements" here, the caller may need it to do it himself + return new_vertex; + } +} + +template +typename C3T3_helpers::Vertex_handle +C3T3_helpers:: move_point_topo_change(const Vertex_handle& old_vertex, const Point_3& new_position, - Outdated_cell_set& outdated_cells_set) + Outdated_cell_set& outdated_cells_set, + bool *could_lock_zone) const { Cell_set insertion_conflict_cells; Cell_set removal_conflict_cells; Facet_vector insertion_conflict_boundary; insertion_conflict_boundary.reserve(64); - + get_conflict_zone_topo_change(old_vertex, new_position, std::inserter(insertion_conflict_cells,insertion_conflict_cells.end()), std::back_inserter(insertion_conflict_boundary), - std::inserter(removal_conflict_cells, removal_conflict_cells.end())); + std::inserter(removal_conflict_cells, removal_conflict_cells.end()), + could_lock_zone); reset_circumcenter_cache(removal_conflict_cells); reset_sliver_cache(removal_conflict_cells); reset_circumcenter_cache(insertion_conflict_cells); reset_sliver_cache(insertion_conflict_cells); + if (could_lock_zone && *could_lock_zone == false) + return Vertex_handle(); + + lock_outdated_cells(); for(typename Cell_set::iterator it = insertion_conflict_cells.begin(); it != insertion_conflict_cells.end(); ++it) outdated_cells_set.erase(*it); for(typename Cell_set::iterator it = removal_conflict_cells.begin(); it != removal_conflict_cells.end(); ++it) outdated_cells_set.erase(*it); + unlock_outdated_cells(); Cell_vector outdated_cells; Vertex_handle nv = move_point_topo_change_conflict_zone_known(old_vertex, new_position, @@ -2217,28 +3009,30 @@ std::back_inserter(outdated_cells), CGAL::Emptyset_iterator()); // deleted_cells + lock_outdated_cells(); for(typename Cell_vector::iterator it = outdated_cells.begin(); it != outdated_cells.end(); ++it) outdated_cells_set.insert(*it); - + unlock_outdated_cells(); + return nv; } template template -typename C3T3_helpers::Vertex_handle -C3T3_helpers:: +typename C3T3_helpers::Vertex_handle +C3T3_helpers:: move_point_topo_change(const Vertex_handle& old_vertex, const Point_3& new_position, OutdatedCellsOutputIterator outdated_cells, - DeletedCellsOutputIterator deleted_cells) + DeletedCellsOutputIterator deleted_cells) const { Cell_set insertion_conflict_cells; Cell_set removal_conflict_cells; Facet_vector insertion_conflict_boundary; insertion_conflict_boundary.reserve(64); - + get_conflict_zone_topo_change(old_vertex, new_position, std::inserter(insertion_conflict_cells,insertion_conflict_cells.end()), std::back_inserter(insertion_conflict_boundary), @@ -2256,6 +3050,7 @@ removal_conflict_cells.end(), outdated_cells, deleted_cells); + return nv; } @@ -2264,8 +3059,8 @@ template < typename ConflictCellsInputIterator, typename OutdatedCellsOutputIterator, typename DeletedCellsOutputIterator > -typename C3T3_helpers::Vertex_handle -C3T3_helpers:: +typename C3T3_helpers::Vertex_handle +C3T3_helpers:: move_point_topo_change_conflict_zone_known( const Vertex_handle& old_vertex, const Point_3& new_position, @@ -2273,13 +3068,14 @@ ConflictCellsInputIterator insertion_conflict_cells_begin,//ordered ConflictCellsInputIterator insertion_conflict_cells_end, ConflictCellsInputIterator removal_conflict_cells_begin,//ordered - ConflictCellsInputIterator removal_conflict_cells_end, + ConflictCellsInputIterator removal_conflict_cells_end, OutdatedCellsOutputIterator outdated_cells, DeletedCellsOutputIterator deleted_cells)//warning : this should not be an iterator to Intrusive_list //o.w. deleted_cells will point to null pointer or so and crash + const { Point_3 old_position = old_vertex->point(); - // make one set with conflict zone + // make one set with conflict zone Cell_set conflict_zone; std::set_union(insertion_conflict_cells_begin, insertion_conflict_cells_end, removal_conflict_cells_begin, removal_conflict_cells_end, @@ -2287,28 +3083,28 @@ // Remove conflict zone cells from c3t3 (they will be deleted by insert/remove) remove_cells_and_facets_from_c3t3(conflict_zone.begin(), conflict_zone.end()); - + // Start Move point // Insert new_vertex, remove old_vertex int dimension = c3t3_.in_dimension(old_vertex); Index vertex_index = c3t3_.index(old_vertex); FT meshing_info = old_vertex->meshing_info(); // insert new point - Vertex_handle new_vertex = tr_.insert_in_hole(new_position, + Vertex_handle new_vertex = tr_.insert_in_hole(new_position, insertion_conflict_cells_begin, insertion_conflict_cells_end, - insertion_boundary_facet.first, + insertion_boundary_facet.first, insertion_boundary_facet.second); // If new_position is hidden, update what should be and return default constructed handle - if ( Vertex_handle() == new_vertex ) - { + if ( Vertex_handle() == new_vertex ) + { std::copy(conflict_zone.begin(), conflict_zone.end(), outdated_cells); - return old_vertex; + return old_vertex; } // remove old point tr_.remove(old_vertex); - + c3t3_.set_dimension(new_vertex,dimension); c3t3_.set_index(new_vertex,vertex_index); new_vertex->set_meshing_info(meshing_info); @@ -2319,7 +3115,7 @@ Cell_vector new_conflict_cells; new_conflict_cells.reserve(64); get_conflict_zone_topo_change(new_vertex, old_position, - std::back_inserter(new_conflict_cells)); + std::back_inserter(new_conflict_cells)); std::copy(new_conflict_cells.begin(),new_conflict_cells.end(),outdated_cells); // Fill deleted_cells @@ -2330,10 +3126,10 @@ } template -typename C3T3_helpers::Vertex_handle +typename C3T3_helpers::Vertex_handle C3T3_helpers:: move_point_topo_change(const Vertex_handle& old_vertex, - const Point_3& new_position) + const Point_3& new_position) const { // Insert new_vertex, remove old_vertex int dimension = c3t3_.in_dimension(old_vertex); @@ -2346,47 +3142,51 @@ if ( Vertex_handle() == new_vertex ) { return Vertex_handle(); } // remove old point tr_.remove(old_vertex); - + c3t3_.set_dimension(new_vertex,dimension); c3t3_.set_index(new_vertex,vertex_index); new_vertex->set_meshing_info(meshing_info); return new_vertex; } - + template template -typename C3T3_helpers::Vertex_handle -C3T3_helpers:: +typename C3T3_helpers::Vertex_handle +C3T3_helpers:: move_point_no_topo_change(const Vertex_handle& old_vertex, const Point_3& new_position, - OutdatedCellsOutputIterator outdated_cells) + OutdatedCellsOutputIterator outdated_cells) const { + + lock_outdated_cells(); get_conflict_zone_no_topo_change(old_vertex, outdated_cells); + unlock_outdated_cells(); + return move_point_no_topo_change(old_vertex, new_position); } template -typename C3T3_helpers::Vertex_handle -C3T3_helpers:: +typename C3T3_helpers::Vertex_handle +C3T3_helpers:: move_point_no_topo_change(const Vertex_handle& old_vertex, - const Point_3& new_position) -{ + const Point_3& new_position) const +{ // Change vertex position old_vertex->set_point(new_position); - return old_vertex; + return old_vertex; } /** - * @brief Returns the projection of \c p, using direction of + * @brief Returns the projection of \c p, using direction of * \c projection_vector */ template typename C3T3_helpers::Point_3 -C3T3_helpers:: +C3T3_helpers:: project_on_surface_aux(const Point_3& p, const Point_3& ref_point, const Vector_3& projection_vector) const @@ -2396,33 +3196,33 @@ // Build a segment directed as projection_direction, typename Gt::Compute_squared_distance_3 sq_distance = Gt().compute_squared_distance_3_object(); - + typename Gt::Compute_squared_length_3 sq_length = Gt().compute_squared_length_3_object(); - + typename Gt::Construct_scaled_vector_3 scale = Gt().construct_scaled_vector_3_object(); - + typename Gt::Is_degenerate_3 is_degenerate = Gt().is_degenerate_3_object(); typename MD::Construct_intersection construct_intersection = domain_.construct_intersection_object(); - + const FT sq_dist = sq_distance(p,ref_point); const FT sq_proj_length = sq_length(projection_vector); - + if ( CGAL_NTS is_zero(sq_proj_length) ) return ref_point; - + const Vector_3 projection_scaled_vector = scale(projection_vector, CGAL::sqrt(sq_dist/sq_proj_length)); - + const Point_3 source = p + projection_scaled_vector; const Point_3 target = p - projection_scaled_vector; - + const Segment_3 proj_segment(source,target); - + if ( is_degenerate(proj_segment) ) return ref_point; @@ -2434,7 +3234,7 @@ if ( do_intersect(proj_segment) ) return CGAL::cpp0x::get<0>(construct_intersection(proj_segment)); else - return ref_point; + return ref_point; #else // CGAL_MESH_3_NO_LONGER_CALLS_DO_INTERSECT_3 @@ -2442,23 +3242,34 @@ Intersection intersection = construct_intersection(proj_segment); if(CGAL::cpp0x::get<2>(intersection) == 2) return CGAL::cpp0x::get<0>(intersection); - else + else return ref_point; #endif // CGAL_MESH_3_NO_LONGER_CALLS_DO_INTERSECT_3 } - + template typename C3T3_helpers::Plane_3 -C3T3_helpers:: +C3T3_helpers:: get_least_square_surface_plane(const Vertex_handle& v, Point_3& reference_point, Surface_patch_index patch_index) const { // Get incident facets Facet_vector facets; - tr_.finite_incident_facets(v,std::back_inserter(facets)); +# ifdef CGAL_LINKED_WITH_TBB + // Parallel + if (boost::is_convertible::value) + { + tr_.finite_incident_facets_threadsafe(v, std::back_inserter(facets)); + } + // Sequential + else +# endif // CGAL_LINKED_WITH_TBB + { + tr_.finite_incident_facets(v,std::back_inserter(facets)); + } // Get adjacent surface points std::vector surface_point_vector; @@ -2466,13 +3277,13 @@ fit != facets.end() ; ++fit ) { - if ( c3t3_.is_in_complex(*fit) && - (patch_index == Surface_patch_index() || + if ( c3t3_.is_in_complex(*fit) && + (patch_index == Surface_patch_index() || c3t3_.surface_patch_index(*fit) == patch_index) ) { const Cell_handle& cell = fit->first; const int& i = fit->second; - + surface_point_vector.push_back(cell->get_facet_surface_center(i)); } } @@ -2480,24 +3291,24 @@ // In some cases point is not a real surface point if ( surface_point_vector.empty() ) return Plane_3(); - + // Compute least square fitting plane Plane_3 plane; CGAL::linear_least_squares_fitting_3(surface_point_vector.begin(), surface_point_vector.end(), plane, Dimension_tag<0>()); - + reference_point = surface_point_vector.front(); return plane; } - - - + + + template typename C3T3_helpers::Point_3 -C3T3_helpers:: +C3T3_helpers:: project_on_surface(const Point_3& p, const Vertex_handle& v, Surface_patch_index index) const @@ -2506,10 +3317,10 @@ // Get plane Point_3 reference_point(CGAL::ORIGIN); Plane_3 plane = get_least_square_surface_plane(v,reference_point, index); - + if ( reference_point == CGAL::ORIGIN ) return p; - + // Project if ( p != v->point() ) return project_on_surface_aux(p, @@ -2521,19 +3332,19 @@ plane.orthogonal_vector()); } - - + + template -template +template typename C3T3_helpers::FT C3T3_helpers:: min_incident_value(const Vertex_handle& vh, const SliverCriterion& criterion) const { - Cell_vector incident_cells; - tr_.finite_incident_cells(vh,std::back_inserter(incident_cells)); - - return min_sliver_in_c3t3_value(incident_cells, criterion); + Cell_vector incident_cells_; + tr_.finite_incident_cells(vh,std::back_inserter(incident_cells_)); + + return min_sliver_in_c3t3_value(incident_cells_, criterion); } template @@ -2542,7 +3353,7 @@ mutable OutputIterator out; const Fct& fct; - Filter(OutputIterator out, const Fct& fct) + Filter(OutputIterator out, const Fct& fct) : out(out), fct(fct) {} @@ -2554,14 +3365,14 @@ } }; - + template struct Counter { const Fct& fct; std::size_t& count; - Counter(const Fct& fct, std::size_t& count) + Counter(const Fct& fct, std::size_t& count) : fct(fct), count(count) {} @@ -2574,6 +3385,115 @@ }; +template +template +void +C3T3_helpers:: +get_incident_slivers_without_using_tds_data(const Vertex_handle& v, + const SliverCriterion& criterion, + const FT& sliver_bound, + Cell_vector &slivers) const +{ + typedef SliverCriterion Sc; + typedef std::back_insert_iterator OutputIt; + typedef Filter > F; + OutputIt slivers_it = std::back_inserter(slivers); + Is_sliver i_s(c3t3_, criterion, sliver_bound); + F f(slivers_it, i_s); + tr_.incident_cells_threadsafe(v, boost::make_function_output_iterator(f)); +} + +// CJTODO: call tr_.try_lock_and_get_incident_cells instead? +template +bool +C3T3_helpers:: +try_lock_and_get_incident_cells(const Vertex_handle& v, + Cell_vector &cells) const + { + // We need to lock v individually first, to be sure v->cell() is valid + if (!try_lock_vertex(v)) + return false; + + Cell_handle d = v->cell(); + if (!try_lock_element(d)) // LOCK + { + unlock_all_elements(); + return false; + } + cells.push_back(d); + d->tds_data().mark_in_conflict(); + int head=0; + int tail=1; + do { + Cell_handle c = cells[head]; + + for (int i=0; i<4; ++i) { + if (c->vertex(i) == v) + continue; + Cell_handle next = c->neighbor(i); + + if (!try_lock_element(next)) // LOCK + { + BOOST_FOREACH(Cell_handle& ch, + std::make_pair(cells.begin(), cells.end())) + { + ch->tds_data().clear(); + } + cells.clear(); + unlock_all_elements(); + return false; + } + if (! next->tds_data().is_clear()) + continue; + cells.push_back(next); + ++tail; + next->tds_data().mark_in_conflict(); + } + ++head; + } while(head != tail); + BOOST_FOREACH(Cell_handle& ch, std::make_pair(cells.begin(), cells.end())) + { + ch->tds_data().clear(); + } + return true; + } + +template +template +bool +C3T3_helpers:: +try_lock_and_get_incident_cells(const Vertex_handle& v, + Cell_vector &cells, + const Filter &filter) const +{ + std::vector tmp_cells; + tmp_cells.reserve(64); + bool ret = try_lock_and_get_incident_cells(v, tmp_cells); + if (ret) + { + BOOST_FOREACH(Cell_handle& ch, + std::make_pair(tmp_cells.begin(), tmp_cells.end())) + { + if (filter(ch)) + cells.push_back(ch); + } + } + return ret; +} + +template +template +bool +C3T3_helpers:: +try_lock_and_get_incident_slivers(const Vertex_handle& v, + const SliverCriterion& criterion, + const FT& sliver_bound, + Cell_vector &slivers) const +{ + Is_sliver i_s(c3t3_, criterion, sliver_bound); + return try_lock_and_get_incident_cells(v, slivers, i_s); +} + template template @@ -2585,15 +3505,15 @@ OutputIterator out) const { typedef SliverCriterion Sc; - - std::vector incident_cells; - tr_.incident_cells(v, std::back_inserter(incident_cells)); - - std::remove_copy_if(incident_cells.begin(), - incident_cells.end(), + + std::vector incident_cells_; + tr_.incident_cells(v, std::back_inserter(incident_cells_)); + + std::remove_copy_if(incident_cells_.begin(), + incident_cells_.end(), out, std::not1(Is_sliver(c3t3_,criterion,sliver_bound))); - + return out; } @@ -2608,7 +3528,7 @@ { typedef SliverCriterion Sc; typedef Filter > F; - + Is_sliver i_s(c3t3_, criterion, sliver_bound); F f(out, i_s); tr_.incident_cells(v,boost::make_function_output_iterator(f)); @@ -2647,7 +3567,7 @@ return count; } - + template template typename C3T3_helpers::FT @@ -2657,31 +3577,31 @@ const bool use_cache) const { using boost::make_transform_iterator; - + if ( cells.empty() ) return criterion.get_max_value(); - + if ( ! use_cache ) - { + { reset_sliver_cache(cells.begin(),cells.end()); } - + // Return min dihedral angle //Sliver_criterion_value sc_value(tr_,criterion); // //return *(std::min_element(make_transform_iterator(cells.begin(),sc_value), // make_transform_iterator(cells.end(),sc_value))); FT min_value = criterion.get_max_value(); - for(typename Cell_vector::const_iterator it = cells.begin(); - it != cells.end(); + for(typename Cell_vector::const_iterator it = cells.begin(); + it != cells.end(); ++it) { min_value = (std::min)(criterion(*it), min_value); - } + } return min_value; } - - + + template template void @@ -2694,12 +3614,12 @@ std::set already_inserted_vertices; // Dont insert vertex in out already_inserted_vertices.insert(vertex); - + for ( InputIterator it = cells_begin ; it != cells_end ; ++it ) { for ( int i=0 ; i<4 ; ++i ) { - // Insert vertices if not already inserted + // Insert vertices if not already inserted const Vertex_handle& current_vertex = (*it)->vertex(i); if ( !tr_.is_infinite(current_vertex) && already_inserted_vertices.insert(current_vertex).second ) @@ -2709,8 +3629,8 @@ } } } - - + + template template void @@ -2742,7 +3662,7 @@ if(tr_.is_infinite(*cit)) continue;//don't restore infinite cells, they have not been backed-up - typename CellDataSet::const_iterator cd_it + typename CellDataSet::const_iterator cd_it = cells_backup.find(Cell_data_backup(*cit, false/*don't backup*/)); if(cd_it != cells_backup.end()) { @@ -2761,7 +3681,7 @@ C3T3_helpers:: get_conflict_zone_no_topo_change(const Vertex_handle& vertex, OutputIterator conflict_cells) const -{ +{ return tr_.incident_cells(vertex,conflict_cells); } @@ -2774,27 +3694,35 @@ const Point_3& conflict_point, CellsOutputIterator insertion_conflict_cells, FacetsOutputIterator insertion_conflict_boundary, - CellsOutputIterator removal_conflict_cells) const + CellsOutputIterator removal_conflict_cells, + bool *could_lock_zone) const { // Get triangulation_vertex incident cells : removal conflict zone + // TODO: hasn't it already been computed in "perturb_vertex" (when getting the slivers)? + // We don't try to lock the incident cells since they've already been locked tr_.incident_cells(v, removal_conflict_cells); - // Get conflict_point conflict zone + // Get conflict_point conflict zone int li=0; int lj=0; typename Tr::Locate_type lt; - Cell_handle cell = tr_.locate(conflict_point, lt, li, lj, v->cell()); - - if ( lt == Tr::VERTEX ) // Vertex removal is forbidden + Cell_handle cell = tr_.locate( + conflict_point, lt, li, lj, v->cell(), could_lock_zone); + + if (could_lock_zone && *could_lock_zone == false) + return; + + if ( lt == Tr::VERTEX ) // Vertex removal is forbidden return; - + // Find conflict zone tr_.find_conflicts(conflict_point, cell, insertion_conflict_boundary, - insertion_conflict_cells); + insertion_conflict_cells, + could_lock_zone); } - + template template OutputIterator @@ -2804,15 +3732,15 @@ OutputIterator conflict_cells) const { // Get triangulation_vertex incident cells - Cell_vector incident_cells; - incident_cells.reserve(64); - tr_.incident_cells(vertex, std::back_inserter(incident_cells)); - + Cell_vector incident_cells_; + incident_cells_.reserve(64); + tr_.incident_cells(vertex, std::back_inserter(incident_cells_)); + // Get conflict_point conflict zone Cell_vector deleted_cells; deleted_cells.reserve(64); - - // Vertex removal is forbidden + + // Vertex removal is forbidden int li=0; int lj=0; typename Tr::Locate_type locate_type; @@ -2821,30 +3749,30 @@ li, lj, vertex->cell()); - + if ( Tr::VERTEX == locate_type ) return conflict_cells; - + // Find conflict zone tr_.find_conflicts(conflict_point, cell, CGAL::Emptyset_iterator(), std::back_inserter(deleted_cells), CGAL::Emptyset_iterator()); - + // Compute union of conflict_point conflict zone and triangulation_vertex // incident cells std::sort(deleted_cells.begin(),deleted_cells.end()); - std::sort(incident_cells.begin(),incident_cells.end()); - + std::sort(incident_cells_.begin(),incident_cells_.end()); + std::set_union(deleted_cells.begin(), deleted_cells.end(), - incident_cells.begin(), incident_cells.end(), + incident_cells_.begin(), incident_cells_.end(), conflict_cells); - + return conflict_cells; } - - + + template typename C3T3_helpers::Facet_boundary C3T3_helpers:: @@ -2866,7 +3794,7 @@ incident_surface_vertices.insert(v1); incident_surface_vertices.insert(v2); incident_surface_vertices.insert(v3); - + // Check that each vertex is a surface one // This is a trick to ensure that in_domain vertices stay inside if ( c3t3_.in_dimension(v1) > 2 @@ -2877,12 +3805,12 @@ return boundary; // return an empty boundary, that cannot be equal // to a real boundary } - + order_handles(v1,v2,v3); - + CGAL_assertion(v1 bool C3T3_helpers:: @@ -2916,7 +3844,7 @@ const Vertex_handle& v1 = fit->first->vertex((k+1)&3); const Vertex_handle& v2 = fit->first->vertex((k+2)&3); const Vertex_handle& v3 = fit->first->vertex((k+3)&3); - + // Check that each vertex is a surface one if ( c3t3_.in_dimension(v1) > 2 || c3t3_.in_dimension(v2) > 2 @@ -2926,7 +3854,7 @@ } } } - + return true; } diff -Nru cgal-4.4/include/CGAL/Mesh_3/Concurrent_mesher_config.h cgal-4.5/include/CGAL/Mesh_3/Concurrent_mesher_config.h --- cgal-4.4/include/CGAL/Mesh_3/Concurrent_mesher_config.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/Mesh_3/Concurrent_mesher_config.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,179 @@ +// Copyright (c) 2012 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Clement Jamin +// +//****************************************************************************** +// File Description : +//****************************************************************************** + +#ifndef CGAL_MESH_3_CONCURRENT_MESHER_CONFIG_H +#define CGAL_MESH_3_CONCURRENT_MESHER_CONFIG_H + +#ifdef CGAL_USE_BOOST_PROGRAM_OPTIONS +# include + namespace po = boost::program_options; +#endif + +#include +#include +#include + +// class Concurrent_mesher_config +/// Singleton containing config +class Concurrent_mesher_config +{ + // Private constructor (singleton) + Concurrent_mesher_config() + : locking_grid_num_cells_per_axis(50), + first_grid_lock_radius(0), + work_stats_grid_num_cells_per_axis(5), + num_work_items_per_batch(50), + refinement_grainsize(10), + refinement_batch_size(10000), + min_num_vertices_of_coarse_mesh(100), + num_vertices_of_coarse_mesh_per_core(3.5f), + num_pseudo_infinite_vertices_per_core(5.0f), + m_config_file_loaded(false) + {} + +public: + static Concurrent_mesher_config &get() + { + static Concurrent_mesher_config singleton; + return singleton; + } + + static bool load_config_file(const char *filename, + bool reload_if_already_loaded = false) + { + return get().load_file(filename, reload_if_already_loaded); + } + + + //=============== PUBLIC PARAMETERS ============== + + // From config file (or default) + int locking_grid_num_cells_per_axis; + int first_grid_lock_radius; + int work_stats_grid_num_cells_per_axis; + int num_work_items_per_batch; + int refinement_grainsize; + int refinement_batch_size; + int min_num_vertices_of_coarse_mesh; + float num_vertices_of_coarse_mesh_per_core; + float num_pseudo_infinite_vertices_per_core; + + // Others + + + //================================================ + +protected: + + bool load_file( + const char *filename, + bool reload_if_already_loaded = false) + { + CGAL_USE(reload_if_already_loaded); +#ifdef CGAL_USE_BOOST_PROGRAM_OPTIONS + if (m_config_file_loaded && reload_if_already_loaded == false) + return true; + + try + { + std::ifstream in(filename); + if (in.fail()) + { + std::string err = "could not open file '"; + err += filename; + err += "'. Using default values."; + throw std::runtime_error(err); + } + + // Declare the supported options. + po::options_description desc("Allowed options"); + desc.add_options() + ("locking_grid_num_cells_per_axis", po::value(), "") + ("first_grid_lock_radius", po::value(), "") + ("work_stats_grid_num_cells_per_axis", po::value(), "") + ("num_work_items_per_batch", po::value(), "") + ("refinement_grainsize", po::value(), "") + ("refinement_batch_size", po::value(), "") + ("min_num_vertices_of_coarse_mesh", po::value(), "") + ("num_vertices_of_coarse_mesh_per_core", po::value(), "") + ("num_pseudo_infinite_vertices_per_core", po::value(), ""); + + + po::store(po::parse_config_file(in, desc), m_variables_map); + po::notify(m_variables_map); + } + catch (std::exception &e) + { + std::cerr << "Concurrency configuration file error: " + << e.what() << std::endl; + return false; + } + + locking_grid_num_cells_per_axis = + get_config_file_option_value("locking_grid_num_cells_per_axis"); + first_grid_lock_radius = + get_config_file_option_value("first_grid_lock_radius"); + work_stats_grid_num_cells_per_axis = + get_config_file_option_value("work_stats_grid_num_cells_per_axis"); + num_work_items_per_batch = + get_config_file_option_value("num_work_items_per_batch"); + refinement_grainsize = + get_config_file_option_value("refinement_grainsize"); + refinement_batch_size = + get_config_file_option_value("refinement_batch_size"); + min_num_vertices_of_coarse_mesh = + get_config_file_option_value("min_num_vertices_of_coarse_mesh"); + num_vertices_of_coarse_mesh_per_core = + get_config_file_option_value("num_vertices_of_coarse_mesh_per_core"); + num_pseudo_infinite_vertices_per_core = + get_config_file_option_value("num_pseudo_infinite_vertices_per_core"); + + m_config_file_loaded = true; + +#else // CGAL_USE_BOOST_PROGRAM_OPTIONS not defined + std::cerr << "Warning: could not load concurrency configuration file '" + << filename << "'. Default values will be used." + << std::endl; +#endif // CGAL_USE_BOOST_PROGRAM_OPTIONS + return true; + } + +#ifdef CGAL_USE_BOOST_PROGRAM_OPTIONS + template + OptionType get_config_file_option_value(const char *option_name) + { + if (m_variables_map.count(option_name)) + return m_variables_map[option_name].as(); + else + return OptionType(); + } +#endif + +#ifdef CGAL_USE_BOOST_PROGRAM_OPTIONS + po::variables_map m_variables_map; +#endif + bool m_config_file_loaded; +}; + +#endif // CGAL_MESH_3_CONCURRENT_MESHER_CONFIG_H diff -Nru cgal-4.4/include/CGAL/Mesh_3/config.h cgal-4.5/include/CGAL/Mesh_3/config.h --- cgal-4.4/include/CGAL/Mesh_3/config.h 2014-02-08 20:00:27.000000000 +0000 +++ cgal-4.5/include/CGAL/Mesh_3/config.h 2014-08-29 13:58:16.000000000 +0000 @@ -20,14 +20,11 @@ #ifndef CGAL_MESH_3_CONFIG_H #define CGAL_MESH_3_CONFIG_H 1 -#include - #include //#define CGAL_MESH_3_VERBOSE 1 // Use optimisations of Mesh_3 -# define CGAL_REGULAR_TRIANGULATION_3_USE_CIRCUMCENTER_CACHE 1 # define CGAL_INTRUSIVE_LIST 1 # define CGAL_CONSTRUCT_INTRUSIVE_LIST_RANGE_CONSTRUCTOR 1 # define CGAL_MESH_3_NEW_GET_FACETS 1 @@ -38,12 +35,14 @@ //experimental # define CGAL_FASTER_BUILD_QUEUE 1 +//# define CGAL_SEQUENTIAL_MESH_3_ADD_OUTSIDE_POINTS_ON_A_FAR_SPHERE +//# define CGAL_PARALLEL_MESH_3_DO_NOT_ADD_OUTSIDE_POINTS_ON_A_FAR_SPHERE // slower / not recommended //should not be used //#define CGAL_MESH_3_OLD_MINIMUM_DIHEDRAL_ANGLE 1 //experimental -//#define CGAL_MESH_3_PROTECTION_NON_LINEAR 1 +#define CGAL_MESH_3_NO_PROTECTION_NON_LINEAR 1 #define CGAL_MESH_3_NEW_ROBUST_INTERSECTION_TRAITS 1 @@ -64,4 +63,21 @@ # endif #endif +#if defined(__clang__) || (BOOST_GCC >= 40600) +# define CGAL_MESH_3_IGNORE_UNUSED_VARIABLES \ + _Pragma("GCC diagnostic ignored \"-Wunused-variable\"") +#else +# define CGAL_MESH_3_IGNORE_UNUSED_VARIABLES +#endif +#if __has_warning("-Wunneeded-internal-declaration") +# define CGAL_MESH_3_IGNORE_UNUSED_INTERNAL_DECLARATION \ + _Pragma("clang diagnostic ignored \"-Wunneeded-internal-declaration\"") +#else +# define CGAL_MESH_3_IGNORE_UNUSED_INTERNAL_DECLARATION +#endif + +#define CGAL_MESH_3_IGNORE_BOOST_PARAMETER_NAME_WARNINGS \ + CGAL_MESH_3_IGNORE_UNUSED_VARIABLES \ + CGAL_MESH_3_IGNORE_UNUSED_INTERNAL_DECLARATION + #endif // CGAL_MESH_3_CONFIG_H diff -Nru cgal-4.4/include/CGAL/Mesh_3/Detect_features_in_polyhedra.h cgal-4.5/include/CGAL/Mesh_3/Detect_features_in_polyhedra.h --- cgal-4.4/include/CGAL/Mesh_3/Detect_features_in_polyhedra.h 2013-07-06 19:00:27.000000000 +0000 +++ cgal-4.5/include/CGAL/Mesh_3/Detect_features_in_polyhedra.h 2014-08-29 13:58:16.000000000 +0000 @@ -53,9 +53,10 @@ typedef typename Polyhedron::Facet_handle Facet_handle; typedef typename Polyhedron::Halfedge Halfedge; typedef typename Polyhedron::Facet Facet; + typedef typename Facet::Patch_id Patch_id; - typedef std::set Facet_handle_set; - typedef std::set He_handle_set; + typedef std::set Facet_handle_set; + typedef std::set He_handle_set; public: Detect_features_in_polyhedra() : current_surface_index_(1) {} @@ -68,8 +69,14 @@ private: Vector_3 facet_normal(const Facet_handle& f) const; bool is_sharp(const Halfedge_handle& he, FT cos_angle) const; - void flood(Facet& f, const int index, + void flood(Facet_handle f, const Patch_id id, Facet_handle_set& unsorted_faces) const; + + template + Int generate_patch_id(Int, int); + + template + std::pair generate_patch_id(std::pair, int); private: // Stores the current surface index (usefull to detect different patches @@ -109,6 +116,24 @@ template +template +Int +Detect_features_in_polyhedra:: +generate_patch_id(Int, int i) +{ + return Int(i); +} + +template +template +std::pair +Detect_features_in_polyhedra:: +generate_patch_id(std::pair, int i) +{ + return std::pair(i, 0); +} + +template void Detect_features_in_polyhedra:: detect_surface_patches(Polyhedron& polyhedron) @@ -118,22 +143,25 @@ for ( typename Polyhedron::Facet_iterator fit = polyhedron.facets_begin(), end = polyhedron.facets_end() ; fit != end ; ++fit ) { - unsorted_faces.insert(&*fit); + Facet_handle fh = fit; + unsorted_faces.insert(fh); } // Flood while ( ! unsorted_faces.empty() ) { - Facet& f = **(unsorted_faces.begin()); + Facet_handle f = *(unsorted_faces.begin()); unsorted_faces.erase(unsorted_faces.begin()); - f.set_patch_id(current_surface_index_); - flood(f,current_surface_index_,unsorted_faces); + const Patch_id patch_id = generate_patch_id(Patch_id(), + current_surface_index_); + f->set_patch_id(patch_id); + flood(f,patch_id,unsorted_faces); ++current_surface_index_; } } - - + + template void Detect_features_in_polyhedra:: @@ -218,52 +246,52 @@ template void Detect_features_in_polyhedra:: -flood(Facet& f, const int index, Facet_handle_set& unsorted_faces) const +flood(Facet_handle f, const Patch_id patch_id, Facet_handle_set& unsorted_faces) const { typedef typename Facet::Halfedge_around_facet_circulator Facet_he_circ; - Facet_he_circ begin = f.facet_begin(); + Facet_he_circ begin = f->facet_begin(); Facet_he_circ done = begin; // Initialize he_to_explore with halfedges of the starting facet He_handle_set he_to_explore; CGAL_For_all(begin,done) { - he_to_explore.insert(&*(begin->opposite())); + he_to_explore.insert(begin->opposite()); } // While there is something to explore while ( ! he_to_explore.empty() ) { // Get next halfedge to explore - Halfedge& he = **(he_to_explore.begin()); + Halfedge_handle he = *(he_to_explore.begin()); he_to_explore.erase(he_to_explore.begin()); // If we don't go through a border of the patch - if ( ! he.is_feature_edge() && ! he.is_border() ) + if ( ! he->is_feature_edge() && ! he->is_border() ) { - Facet& explored_facet = *(he.facet()); + Facet_handle explored_facet = he->facet(); // Mark facet and delete it from unsorted - explored_facet.set_patch_id(index); - unsorted_faces.erase(&explored_facet); + explored_facet->set_patch_id(patch_id); + unsorted_faces.erase(explored_facet); // Add/Remove facet's halfedge to/from explore list - Facet_he_circ he_begin = explored_facet.facet_begin(); + Facet_he_circ he_begin = explored_facet->facet_begin(); Facet_he_circ he_done = he_begin; CGAL_For_all(he_begin,he_done) { - Halfedge& current_he = *he_begin; + Halfedge_handle current_he = he_begin; // do not explore heh again - if ( ¤t_he == &he ) { continue; } + if ( current_he == he ) { continue; } // if current_he is not in to_explore set, add it, otherwise remove it // (because we just explore the facet he_begin is pointing to) - if ( he_to_explore.erase(¤t_he) == 0 ) + if ( he_to_explore.erase(current_he) == 0 ) { - he_to_explore.insert(&*(current_he.opposite())); + he_to_explore.insert(current_he->opposite()); } } } diff -Nru cgal-4.4/include/CGAL/Mesh_3/Detect_polylines_in_polyhedra.h cgal-4.5/include/CGAL/Mesh_3/Detect_polylines_in_polyhedra.h --- cgal-4.4/include/CGAL/Mesh_3/Detect_polylines_in_polyhedra.h 2013-07-06 19:00:27.000000000 +0000 +++ cgal-4.5/include/CGAL/Mesh_3/Detect_polylines_in_polyhedra.h 2014-08-29 13:58:16.000000000 +0000 @@ -23,15 +23,46 @@ #define CGAL_MESH_3_DETECT_POLYLINES_IN_POLYHEDRA_H #include +#include +#include + #include #include +#include namespace CGAL { namespace Mesh_3 { -struct Detect_polyline_less { - template - bool operator()(const Handle& va, const Handle& vb) const { - return &*va < &*vb; +template +struct CGAL_with_time_stamp +{ +public: + static bool less(Handle h1, Handle h2) + { + return h1->time_stamp() < h2->time_stamp(); + } +}; + +template +struct CGAL_no_time_stamp +{ +public: + static bool less(Handle h1, Handle h2) + { + return &*h1 < &*h2; + } +}; + +struct Detect_polyline_less +{ + template + bool operator()(const Handle& h1, const Handle& h2) const + { + typedef typename std::iterator_traits::value_type Type; + typedef typename boost::mpl::if_c< + CGAL::internal::Has_timestamp::value, + CGAL_with_time_stamp, + CGAL_no_time_stamp >::type Comparator; + return Comparator::less(h1, h2); } }; diff -Nru cgal-4.4/include/CGAL/Mesh_3/global_parameters.h cgal-4.5/include/CGAL/Mesh_3/global_parameters.h --- cgal-4.4/include/CGAL/Mesh_3/global_parameters.h 2013-12-21 20:00:22.000000000 +0000 +++ cgal-4.5/include/CGAL/Mesh_3/global_parameters.h 2014-08-29 13:58:16.000000000 +0000 @@ -55,6 +55,11 @@ { Class(double d) : Base(d) { precondition(d); } }; \ inline Class function(double d) { return Class(d); } +// see +CGAL_PRAGMA_DIAG_PUSH +// see +CGAL_MESH_3_IGNORE_BOOST_PARAMETER_NAME_WARNINGS + BOOST_PARAMETER_NAME( c3t3 ) BOOST_PARAMETER_NAME( domain ) BOOST_PARAMETER_NAME( criteria ) @@ -75,6 +80,7 @@ BOOST_PARAMETER_NAME( (dump_after_perturb_prefix, tag ) dump_after_perturb_prefix_) BOOST_PARAMETER_NAME( (dump_after_exude_prefix, tag ) dump_after_exude_prefix_) +CGAL_PRAGMA_DIAG_POP } // end namespace parameters diff -Nru cgal-4.4/include/CGAL/Mesh_3/Implicit_to_labeled_function_wrapper.h cgal-4.5/include/CGAL/Mesh_3/Implicit_to_labeled_function_wrapper.h --- cgal-4.4/include/CGAL/Mesh_3/Implicit_to_labeled_function_wrapper.h 2013-09-21 19:00:24.000000000 +0000 +++ cgal-4.5/include/CGAL/Mesh_3/Implicit_to_labeled_function_wrapper.h 2014-08-29 13:58:16.000000000 +0000 @@ -20,8 +20,8 @@ // //****************************************************************************** // File Description : -// Implicit_to_labeled_function_wrapper and -// Implicit_vector_to_labeled_function_wrapper class declaration +// Implicit_to_labeling_function_wrapper and +// Implicit_vector_to_labeling_function_wrapper class declaration // and implementation. // // See classes description to have more information. @@ -30,12 +30,17 @@ #ifndef CGAL_MESH_3_IMPLICIT_TO_LABELED_FUNCTION_WRAPPER_H #define CGAL_MESH_3_IMPLICIT_TO_LABELED_FUNCTION_WRAPPER_H - #if defined(BOOST_MSVC) # pragma warning(push) # pragma warning(disable:4180) // qualifier applied to function type has no meaning; ignored #endif +#define CGAL_DEPRECATED_HEADER "" +#define CGAL_REPLACEMENT_HEADER "" +#include + +#include + namespace CGAL { namespace Mesh_3 { @@ -81,6 +86,8 @@ /** + * \deprecated + * * @class Implicit_vector_to_labeled_function_wrapper * * Wraps a set of implicit function [f1,f2,...] to one function F which @@ -112,7 +119,7 @@ /// Operator () return_type operator()(const Point_3& p, const bool = true) const { - int nb_func = function_vector_.size(); + int nb_func = static_cast(function_vector_.size()); if ( nb_func > 8 ) { CGAL_error_msg("We support at most 8 functions !"); @@ -135,7 +142,6 @@ }; // end class Implicit_to_labeled_function_wrapper - } // end namespace Mesh_3 } // end namespace CGAL diff -Nru cgal-4.4/include/CGAL/Mesh_3/Labeled_mesh_domain_3.h cgal-4.5/include/CGAL/Mesh_3/Labeled_mesh_domain_3.h --- cgal-4.4/include/CGAL/Mesh_3/Labeled_mesh_domain_3.h 2014-02-08 20:00:27.000000000 +0000 +++ cgal-4.5/include/CGAL/Mesh_3/Labeled_mesh_domain_3.h 2014-08-29 13:58:16.000000000 +0000 @@ -26,6 +26,10 @@ #ifndef CGAL_MESH_3_LABELED_MESH_DOMAIN_3_H #define CGAL_MESH_3_LABELED_MESH_DOMAIN_3_H +#define CGAL_DEPRECATED_HEADER "" +#define CGAL_REPLACEMENT_HEADER "" +#include + #include #include @@ -38,6 +42,7 @@ #include #include #include +#include namespace CGAL { @@ -55,7 +60,8 @@ * tags of it's incident subdomain. * Thus, a boundary facet of the domain is labelled <0,b>, where b!=0. */ -template +template class Labeled_mesh_domain_3 { public: @@ -68,6 +74,9 @@ typedef typename BGT::Sphere_3 Sphere_3; typedef CGAL::Bbox_3 Bbox_3; + typedef typename BGT::Iso_cuboid_3 Iso_cuboid_3; + +public: // Kernel_traits compatibility typedef BGT R; @@ -94,14 +103,20 @@ */ Labeled_mesh_domain_3(const Function& f, const Sphere_3& bounding_sphere, - const FT& error_bound = FT(1e-3)); + const FT& error_bound = FT(1e-3), + CGAL::Random* p_rng = NULL); Labeled_mesh_domain_3(const Function& f, const Bbox_3& bbox, - const FT& error_bound = FT(1e-3)); + const FT& error_bound = FT(1e-3), + CGAL::Random* p_rng = NULL); /// Destructor - virtual ~Labeled_mesh_domain_3() {} + virtual ~Labeled_mesh_domain_3() + { + if(delete_rng_) + delete p_rng_; + } /** * Constructs a set of \ccc{n} points on the surface, and output them to @@ -409,9 +424,6 @@ private: - typedef typename BGT::Iso_cuboid_3 Iso_cuboid_3; - -private: /// Returns Surface_patch_index from \c i and \c j Surface_patch_index make_surface_index(const Subdomain_index i, const Subdomain_index j) const @@ -461,6 +473,9 @@ const Function function_; /// The bounding box const Iso_cuboid_3 bbox_; + /// The random number generator used by Construct_initial_points + CGAL::Random* p_rng_; + bool delete_rng_; /// Error bound relative to sphere radius FT squared_error_bound_; @@ -483,28 +498,43 @@ Labeled_mesh_domain_3::Labeled_mesh_domain_3( const F& f, const Sphere_3& bounding_sphere, - const FT& error_bound ) + const FT& error_bound, + CGAL::Random* p_rng) : function_(f) , bbox_(iso_cuboid(bounding_sphere.bbox())) +, p_rng_(p_rng) +, delete_rng_(false) , squared_error_bound_(squared_error_bound(bounding_sphere,error_bound)) { // TODO : CGAL_ASSERT(0 < f(bounding_sphere.get_center()) ) ? + if(!p_rng_) + { + p_rng_ = new CGAL::Random(0); + delete_rng_ = true; + } } template Labeled_mesh_domain_3::Labeled_mesh_domain_3( const F& f, const Bbox_3& bbox, - const FT& error_bound ) + const FT& error_bound, + CGAL::Random* p_rng) : function_(f) , bbox_(iso_cuboid(bbox)) +, p_rng_(p_rng) +, delete_rng_(false) , squared_error_bound_(squared_error_bound(bbox_,error_bound)) { // TODO : CGAL_ASSERT(0 < f(bounding_sphere.get_center()) ) ? + if(!p_rng_) + { + p_rng_ = new CGAL::Random(0); + delete_rng_ = true; + } } - template template OutputIterator @@ -522,8 +552,9 @@ const double radius = std::sqrt(CGAL::to_double(squared_radius)); - Random_points_on_sphere_3 random_point_on_sphere(radius); - Random_points_in_sphere_3 random_point_in_sphere(radius); + CGAL::Random& rng = *(r_domain_.p_rng_); + Random_points_on_sphere_3 random_point_on_sphere(radius, rng); + Random_points_in_sphere_3 random_point_in_sphere(radius, rng); // Get some functors typename BGT::Construct_segment_3 segment_3 = diff -Nru cgal-4.4/include/CGAL/Mesh_3/Lloyd_move.h cgal-4.5/include/CGAL/Mesh_3/Lloyd_move.h --- cgal-4.4/include/CGAL/Mesh_3/Lloyd_move.h 2013-07-06 19:00:27.000000000 +0000 +++ cgal-4.5/include/CGAL/Mesh_3/Lloyd_move.h 2014-08-29 13:58:16.000000000 +0000 @@ -86,7 +86,10 @@ break; case 1: case 0: + case -1: // Don't move edge or corner vertices + // N.B.: dimension = -1 is possible if we added points on a far sphere + // during initialization return CGAL::NULL_VECTOR; break; default: @@ -99,7 +102,8 @@ return CGAL::NULL_VECTOR; } -#ifdef CGAL_MESH_3_OPTIMIZER_VERBOSE +#if defined(CGAL_MESH_3_OPTIMIZER_VERBOSE) \ + || defined (CGAL_MESH_3_EXPORT_PERFORMANCE_DATA) static std::string name() { return std::string("Lloyd"); } #endif diff -Nru cgal-4.4/include/CGAL/Mesh_3/Mesh_complex_3_in_triangulation_3_base.h cgal-4.5/include/CGAL/Mesh_3/Mesh_complex_3_in_triangulation_3_base.h --- cgal-4.4/include/CGAL/Mesh_3/Mesh_complex_3_in_triangulation_3_base.h 2013-12-14 20:00:35.000000000 +0000 +++ cgal-4.5/include/CGAL/Mesh_3/Mesh_complex_3_in_triangulation_3_base.h 2014-08-29 13:58:16.000000000 +0000 @@ -30,11 +30,16 @@ #include #include #include +#include #include #include #include #include +#ifdef CGAL_LINKED_WITH_TBB + #include +#endif + namespace CGAL { namespace Mesh_3 { @@ -43,10 +48,10 @@ * @brief A data-structure to represent and maintain a 3D complex embedded * in a 3D triangulation. */ -template +template class Mesh_complex_3_in_triangulation_3_base { - typedef Mesh_complex_3_in_triangulation_3_base Self; + typedef Mesh_complex_3_in_triangulation_3_base Self; public: // Triangulation types @@ -70,15 +75,21 @@ * Builds an empty 3D complex. */ Mesh_complex_3_in_triangulation_3_base() - : number_of_facets_(0) - , tr_() - , number_of_cells_(0) {} - + : tr_() + { + // We don't put it in the initialization list because + // tbb::atomic has no contructors + number_of_facets_ = 0; + number_of_cells_ = 0; + } + /// Copy constructor Mesh_complex_3_in_triangulation_3_base(const Self& rhs) - : number_of_facets_(rhs.number_of_facets_) - , tr_(rhs.tr_) - , number_of_cells_(rhs.number_of_cells_) {} + : tr_(rhs.tr_) + { + number_of_facets_ = rhs.number_of_facets_; + number_of_cells_ = rhs.number_of_cells_; + } /// Destructor ~Mesh_complex_3_in_triangulation_3_base() {} @@ -88,7 +99,7 @@ number_of_facets_ = 0; tr_.clear(); } - + /// Assignment operator Self& operator=(Self rhs) { @@ -130,7 +141,7 @@ /// Sets surface index of facet(\c cell, \c i) to \c index void set_surface_patch_index(const Cell_handle& cell, const int i, - const Surface_patch_index& index) + const Surface_patch_index& index) const { cell->set_surface_patch_index(i, index); } @@ -188,19 +199,19 @@ /// Sets subdomain index of cell \c cell to \c index void set_subdomain_index(const Cell_handle& cell, - const Subdomain_index& index) + const Subdomain_index& index) const { cell->set_subdomain_index(index); } /// Sets index of vertex \c vertex to \c index - void set_index(const Vertex_handle& vertex, const Index& index) + void set_index(const Vertex_handle& vertex, const Index& index) const { vertex->set_index(index); } - + /// Sets dimension of vertex \c vertex to \c dimension - void set_dimension(const Vertex_handle& vertex, int dimension) + void set_dimension(const Vertex_handle& vertex, int dimension) const { vertex->set_dimension(dimension); } @@ -229,15 +240,23 @@ /// Returns the index of vertex \c v Index index(const Vertex_handle& v) const { return v->index(); } - + /// Outputs the mesh to medit - void output_to_medit(std::ofstream& os, + void output_to_medit(std::ostream& os, bool rebind = true, bool show_patches = false) const { // Call global function CGAL::output_to_medit(os,*this,rebind,show_patches); } + + /// Outputs the mesh to medit + void output_to_maya(std::ofstream& os, + bool surfaceOnly = true) const + { + // Call global function + CGAL::output_to_maya(os,*this,surfaceOnly); + } //------------------------------------------------------- // Undocumented features @@ -283,7 +302,7 @@ ++first; } } - + /// Swaps this & rhs void swap(Self& rhs) { @@ -291,16 +310,16 @@ tr_.swap(rhs.tr_); std::swap(rhs.number_of_cells_, number_of_cells_); } - + /// Returns bbox Bbox_3 bbox() const; - + //------------------------------------------------------- // Traversal //------------------------------------------------------- private: typedef Mesh_3::internal::Iterator_not_in_complex Iterator_not_in_complex; - + class Facet_iterator_not_in_complex { const Self* c3t3_; @@ -311,15 +330,15 @@ const Surface_patch_index& index = Surface_patch_index()) : c3t3_(&c3t3) , index_(index) { } - + template bool operator()(Iterator it) const - { + { if ( index_ == Surface_patch_index() ) { return ! c3t3_->is_in_complex(*it); } else { return c3t3_->surface_patch_index(*it) != index_; } } }; - + /** * @class Cell_not_in_complex * @brief A class to filter cells which do not belong to the complex @@ -336,12 +355,12 @@ , index_(index) { } bool operator()(Cell_handle ch) const - { + { if ( index_ == Subdomain_index() ) { return !r_self_->is_in_complex(ch); } else { return r_self_->subdomain_index(ch) != index_; } } }; // end class Cell_not_in_complex - + public: /// Iterator type to visit the facets of the 2D complex. typedef Filter_iterator< @@ -355,7 +374,7 @@ Facet_iterator_not_in_complex(*this), tr_.finite_facets_begin()); } - + /// Returns a Facets_in_complex_iterator to the first facet of the 2D complex Facets_in_complex_iterator facets_in_complex_begin(const Surface_patch_index& index) const @@ -410,7 +429,7 @@ Cell_not_in_complex(*this), tr_.finite_cells_begin()); } - + /// Returns a \c Cells_in_complex_iterator to the first cell of the 3D complex Cells_in_complex_iterator cells_in_complex_begin(const Subdomain_index& index) const @@ -426,7 +445,7 @@ return CGAL::filter_iterator(tr_.finite_cells_end(), Cell_not_in_complex(*this)); } - + // ----------------------------------- // Backward Compatibility // ----------------------------------- @@ -435,30 +454,30 @@ void set_surface_index(const Facet& f, const Surface_index& index) { set_surface_patch_index(f, index); } - + void set_surface_index(const Cell_handle& c, const int i, const Surface_index& index) { set_surface_patch_index(c,i,index); } - + Surface_index surface_index(const Facet& f) const { return surface_patch_index(f); } - + Surface_index surface_index(const Cell_handle& c, const int i) const { return surface_patch_index(c,i); } #endif // CGAL_MESH_3_NO_DEPRECATED_SURFACE_INDEX - + #ifndef CGAL_MESH_3_NO_DEPRECATED_C3T3_ITERATORS typedef Facets_in_complex_iterator Facet_iterator; typedef Cells_in_complex_iterator Cell_iterator; - + Facet_iterator facets_begin() const { return facets_in_complex_begin(); } - + Facet_iterator facets_end() const { return facets_in_complex_end(); } - + Cell_iterator cells_begin() const { return cells_in_complex_begin(); } - + Cell_iterator cells_end() const { return cells_in_complex_end(); } #endif // CGAL_MESH_3_NO_DEPRECATED_C3T3_ITERATORS @@ -473,11 +492,11 @@ { return number_of_cells_in_complex(); } public: - template + template friend - std::istream & - operator>> (std::istream& is, - Mesh_complex_3_in_triangulation_3_base &c3t3); + std::istream & + operator>> (std::istream& is, + Mesh_complex_3_in_triangulation_3_base &c3t3); static std::string io_signature() @@ -486,17 +505,34 @@ Get_io_signature()(); } private: + + // Sequential: non-atomic + // "dummy" is here to allow the specialization (see below) + // See http://groups.google.com/group/comp.lang.c++.moderated/browse_thread/thread/285ab1eec49e1cb6 + template + struct Number_of_elements + { + typedef size_type type; + }; +#ifdef CGAL_LINKED_WITH_TBB + // Parallel: atomic + template + struct Number_of_elements + { + typedef tbb::atomic type; + }; +#endif // CGAL_LINKED_WITH_TBB + // Private date members - size_type number_of_facets_; Triangulation tr_; - size_type number_of_cells_; - + typename Number_of_elements::type number_of_facets_; + typename Number_of_elements::type number_of_cells_; }; // end class Mesh_complex_3_in_triangulation_3_base -template +template void -Mesh_complex_3_in_triangulation_3_base::add_to_complex( +Mesh_complex_3_in_triangulation_3_base::add_to_complex( const Cell_handle& cell, const int i, const Surface_patch_index& index) @@ -513,9 +549,9 @@ } -template +template void -Mesh_complex_3_in_triangulation_3_base::remove_from_complex(const Facet& facet) +Mesh_complex_3_in_triangulation_3_base::remove_from_complex(const Facet& facet) { if ( is_in_complex(facet) ) { @@ -525,46 +561,46 @@ --number_of_facets_; } } - + // ----------------------------------- // Undocumented // ----------------------------------- -template +template Bbox_3 -Mesh_complex_3_in_triangulation_3_base:: +Mesh_complex_3_in_triangulation_3_base:: bbox() const { if ( 0 == triangulation().number_of_vertices() ) { return Bbox_3(); } - + typename Tr::Finite_vertices_iterator vit = tr_.finite_vertices_begin(); Bbox_3 result = (vit++)->point().bbox(); - + for(typename Tr::Finite_vertices_iterator end = tr_.finite_vertices_end(); vit != end ; ++vit) { result = result + vit->point().bbox(); } - + return result; } -template < class Tr> -std::ostream & -operator<< (std::ostream& os, - const Mesh_complex_3_in_triangulation_3_base &c3t3) +template +std::ostream & +operator<< (std::ostream& os, + const Mesh_complex_3_in_triangulation_3_base &c3t3) { return os << c3t3.triangulation(); } -template < class Tr> -std::istream & -operator>> (std::istream& is, - Mesh_complex_3_in_triangulation_3_base &c3t3) +template +std::istream & +operator>> (std::istream& is, + Mesh_complex_3_in_triangulation_3_base &c3t3) { c3t3.clear(); is >> c3t3.triangulation(); @@ -574,20 +610,20 @@ return is; } - for(typename Tr::Finite_facets_iterator + for(typename Tr::Finite_facets_iterator fit = c3t3.triangulation().finite_facets_begin(), end = c3t3.triangulation().finite_facets_end(); - fit != end; ++fit) + fit != end; ++fit) { if ( c3t3.is_in_complex(*fit) ) { ++c3t3.number_of_facets_; } } - for(typename Tr::Finite_cells_iterator + for(typename Tr::Finite_cells_iterator cit = c3t3.triangulation().finite_cells_begin(), end = c3t3.triangulation().finite_cells_end(); - cit != end; ++cit) + cit != end; ++cit) { if ( c3t3.is_in_complex(cit) ) { ++c3t3.number_of_cells_; diff -Nru cgal-4.4/include/CGAL/Mesh_3/Mesher_3.h cgal-4.5/include/CGAL/Mesh_3/Mesher_3.h --- cgal-4.4/include/CGAL/Mesh_3/Mesher_3.h 2013-07-06 19:00:27.000000000 +0000 +++ cgal-4.5/include/CGAL/Mesh_3/Mesher_3.h 2014-08-29 13:58:16.000000000 +0000 @@ -1,4 +1,4 @@ -// Copyright (c) 2009 INRIA Sophia-Antipolis (France). +// Copyright (c) 2009-2014 INRIA Sophia-Antipolis (France). // All rights reserved. // // This file is part of CGAL (www.cgal.org). @@ -16,7 +16,7 @@ // $Id$ // // -// Author(s) : Laurent Rineau, Stephane Tayeb +// Author(s) : Laurent Rineau, Stephane Tayeb, Clement Jamin // //****************************************************************************** // File Description : @@ -35,51 +35,149 @@ #include #include #include +#include #ifdef CGAL_MESH_3_USE_OLD_SURFACE_RESTRICTED_DELAUNAY_UPDATE #include #endif +#include #include +#ifdef CGAL_MESH_3_PROFILING + #include +#endif + +#ifdef CGAL_LINKED_WITH_TBB +# if TBB_IMPLEMENT_CPP0X +# include +# else +# include +# endif +#endif + #include +#include #include namespace CGAL { - namespace Mesh_3 { - - -// Class Mesher_3 -// + +/************************************************ +// Class Mesher_3_base +// Two versions: sequential / parallel +************************************************/ + +// Sequential +template +class Mesher_3_base +{ +protected: + typedef typename Tr::Lock_data_structure Lock_data_structure; + + Mesher_3_base(const Bbox_3 &, int) {} + + Lock_data_structure *get_lock_data_structure() { return 0; } + WorksharingDataStructureType *get_worksharing_data_structure() { return 0; } + void set_bbox(const Bbox_3 &) {} +}; + +#ifdef CGAL_LINKED_WITH_TBB +// Parallel +template +class Mesher_3_base +{ +protected: + typedef typename Tr::Lock_data_structure Lock_data_structure; + + Mesher_3_base(const Bbox_3 &bbox, int num_grid_cells_per_axis) + : m_lock_ds(bbox, num_grid_cells_per_axis), + m_worksharing_ds(bbox) + {} + + Lock_data_structure *get_lock_data_structure() + { + return &m_lock_ds; + } + WorksharingDataStructureType *get_worksharing_data_structure() + { + return &m_worksharing_ds; + } + + void set_bbox(const Bbox_3 &bbox) + { + m_lock_ds.set_bbox(bbox); + m_worksharing_ds.set_bbox(bbox); + } + + /// Lock data structure + Lock_data_structure m_lock_ds; + /// Worksharing data structure + WorksharingDataStructureType m_worksharing_ds; +}; +#endif // CGAL_LINKED_WITH_TBB + + +/************************************************ + * + * Mesher_3 class + * + ************************************************/ + template class Mesher_3 +: public Mesher_3_base< + typename C3T3::Triangulation, +#ifdef CGAL_DEBUG_FORCE_SEQUENTIAL_MESH_REFINEMENT + Sequential_tag +#else + typename C3T3::Concurrency_tag +#endif + > { public: +#ifdef CGAL_DEBUG_FORCE_SEQUENTIAL_MESH_REFINEMENT + typedef Sequential_tag Concurrency_tag; +#else + typedef typename C3T3::Concurrency_tag Concurrency_tag; +#endif + typedef typename C3T3::Triangulation Triangulation; + typedef typename Triangulation::Point Point; + typedef typename Kernel_traits::Kernel Kernel; + typedef typename Kernel::Vector_3 Vector; + typedef typename MeshDomain::Index Index; + // Self - typedef Mesher_3 Self; - - typedef typename C3T3::Triangulation Triangulation; - + typedef Mesher_3 Self; +#ifdef CGAL_DEBUG_FORCE_SEQUENTIAL_MESH_REFINEMENT + typedef Mesher_3_base Base; +#else + typedef Mesher_3_base Base; +#endif + + using Base::get_lock_data_structure; + //------------------------------------------------------- // Mesher_levels //------------------------------------------------------- /// Facets mesher level - typedef Mesh_3::Refine_facets_3< + typedef Refine_facets_3< Triangulation, typename MeshCriteria::Facet_criteria, MeshDomain, C3T3, - Null_mesher_level> Facets_level; - + Null_mesher_level, + Concurrency_tag> Facets_level; + /// Cells mesher level - typedef Mesh_3::Refine_cells_3< + typedef Refine_cells_3< Triangulation, typename MeshCriteria::Cell_criteria, MeshDomain, C3T3, - Facets_level> Cells_level; - + Facets_level, + Concurrency_tag> Cells_level; + //------------------------------------------------------- // Visitors //------------------------------------------------------- @@ -88,7 +186,7 @@ Triangulation, Cells_level, Null_mesh_visitor> Facets_visitor; - + #ifndef CGAL_MESH_3_USE_OLD_SURFACE_RESTRICTED_DELAUNAY_UPDATE /// Cells visitor : it just need to know previous level typedef Null_mesh_visitor_level Cells_visitor; @@ -105,67 +203,78 @@ Mesher_3(C3T3& c3t3, const MeshDomain& domain, const MeshCriteria& criteria); - + /// Destructor - ~Mesher_3() { } - + ~Mesher_3() + { + // The lock data structure is going to be destroyed + r_c3t3_.triangulation().set_lock_data_structure(NULL); + } + /// Launch mesh refinement double refine_mesh(std::string dump_after_refine_surface_prefix = ""); /// Debug std::string debug_info() const; std::string debug_info_header() const; - + // Step-by-step methods void initialize(); void fix_c3t3(); + void display_number_of_bad_elements(); void one_step(); bool is_algorithm_done(); - + #ifdef CGAL_MESH_3_MESHER_STATUS_ACTIVATED struct Mesher_status - { + { std::size_t vertices, facet_queue, cells_queue; - + Mesher_status(std::size_t v, std::size_t f, std::size_t c) : vertices(v), facet_queue(f), cells_queue(c) {} }; - + Mesher_status status() const; #endif - + private: void remove_cells_from_c3t3(); - + private: + /// The oracle + const MeshDomain& r_oracle_; + /// Meshers Null_mesher_level null_mesher_; Facets_level facets_mesher_; Cells_level cells_mesher_; - + /// Visitors Null_mesh_visitor null_visitor_; Facets_visitor facets_visitor_; Cells_visitor cells_visitor_; - + /// The container of the resulting mesh C3T3& r_c3t3_; - + private: // Disabled copy constructor Mesher_3(const Self& src); // Disabled assignment operator Self& operator=(const Self& src); - + }; // end class Mesher_3 - - - + + + template Mesher_3::Mesher_3(C3T3& c3t3, const MD& domain, const MC& criteria) -: null_mesher_() +: Base(c3t3.bbox(), + Concurrent_mesher_config::get().locking_grid_num_cells_per_axis) +, r_oracle_(domain) +, null_mesher_() , facets_mesher_(c3t3.triangulation(), criteria.facet_criteria_object(), domain, @@ -185,6 +294,10 @@ #endif , r_c3t3_(c3t3) { + facets_mesher_.set_lock_ds(this->get_lock_data_structure()); + facets_mesher_.set_worksharing_ds(this->get_worksharing_data_structure()); + cells_mesher_.set_lock_ds(this->get_lock_data_structure()); + cells_mesher_.set_worksharing_ds(this->get_worksharing_data_structure()); } @@ -196,15 +309,42 @@ CGAL::Timer timer; timer.start(); double elapsed_time = 0.; - + // First surface mesh could modify c3t3 without notifying cells_mesher // So we have to ensure that no old cell will be left in c3t3 remove_cells_from_c3t3(); - + #ifndef CGAL_MESH_3_VERBOSE // Scan surface and refine it - facets_mesher_.scan_triangulation(); + initialize(); + +#ifdef CGAL_MESH_3_PROFILING + std::cerr << "Refining facets..." << std::endl; + WallClockTimer t; +#endif facets_mesher_.refine(facets_visitor_); +#ifdef CGAL_MESH_3_PROFILING + double facet_ref_time = t.elapsed(); + std::cerr << "==== Facet refinement: " << facet_ref_time << " seconds ====" + << std::endl << std::endl; +# ifdef CGAL_MESH_3_EXPORT_PERFORMANCE_DATA + // If it's parallel but the refinement is forced to sequential, we don't + // output the value +# ifndef CGAL_DEBUG_FORCE_SEQUENTIAL_MESH_REFINEMENT + CGAL_MESH_3_SET_PERFORMANCE_DATA("Facets_time", facet_ref_time); +# endif +# endif +#endif + +#if defined(CHECK_AND_DISPLAY_THE_NUMBER_OF_BAD_ELEMENTS_IN_THE_END) + std::cerr << std::endl + << "===============================================================" << std::endl + << "=== CHECK_AND_DISPLAY_THE_NUMBER_OF_BAD_ELEMENTS_IN_THE_END ===" << std::endl; + display_number_of_bad_elements(); + std::cerr + << "===============================================================" + << std::endl << std::endl; +#endif // Then activate facet to surface visitor (surface could be // refined again if it is encroached) @@ -214,26 +354,50 @@ // Then scan volume and refine it cells_mesher_.scan_triangulation(); +#ifdef CGAL_MESH_3_PROFILING + std::cerr << "Refining cells..." << std::endl; + t.reset(); +#endif cells_mesher_.refine(cells_visitor_); -#else // if defined(CGAL_MESH_3_VERBOSE) +#ifdef CGAL_MESH_3_PROFILING + double cell_ref_time = t.elapsed(); + std::cerr << "==== Cell refinement: " << cell_ref_time << " seconds ====" + << std::endl << std::endl; +# ifdef CGAL_MESH_3_EXPORT_PERFORMANCE_DATA + // If it's parallel but the refinement is forced to sequential, we don't + // output the value +# ifndef CGAL_DEBUG_FORCE_SEQUENTIAL_MESH_REFINEMENT + CGAL_MESH_3_SET_PERFORMANCE_DATA("Cells_refin_time", cell_ref_time); +# endif +# endif +#endif + +#if defined(CGAL_MESH_3_VERBOSE) || defined(CGAL_MESH_3_PROFILING) + std::cerr + << "Vertices: " << r_c3t3_.triangulation().number_of_vertices() << std::endl + << "Facets : " << r_c3t3_.number_of_facets_in_complex() << std::endl + << "Tets : " << r_c3t3_.number_of_cells_in_complex() << std::endl; +#endif + +#else // ifdef CGAL_MESH_3_VERBOSE std::cerr << "Start surface scan..."; - facets_mesher_.scan_triangulation(); + initialize(); std::cerr << "end scan. [Bad facets:" << facets_mesher_.size() << "]"; std::cerr << std::endl << std::endl; elapsed_time += timer.time(); timer.stop(); timer.reset(); timer.start(); - + const Triangulation& r_tr = r_c3t3_.triangulation(); int nbsteps = 0; - + std::cerr << "Refining Surface...\n"; - std::cerr << "Legende of the following line: " + std::cerr << "Legend of the following line: " << "(#vertices,#steps," << cells_mesher_.debug_info_header() << ")\n"; - + std::cerr << "(" << r_tr.number_of_vertices() << "," << nbsteps << "," << cells_mesher_.debug_info() << ")"; - + while ( ! facets_mesher_.is_algorithm_done() ) { facets_mesher_.one_step(facets_visitor_); @@ -252,7 +416,7 @@ elapsed_time += timer.time(); timer.stop(); timer.reset(); timer.start(); nbsteps = 0; - + facets_visitor_.activate(); dump_c3t3(r_c3t3_, dump_after_refine_surface_prefix); std::cerr << "Start volume scan..."; @@ -261,9 +425,9 @@ std::cerr << std::endl << std::endl; elapsed_time += timer.time(); timer.stop(); timer.reset(); timer.start(); - + std::cerr << "Refining...\n"; - std::cerr << "Legende of the following line: " + std::cerr << "Legend of the following line: " << "(#vertices,#steps," << cells_mesher_.debug_info_header() << ")\n"; std::cerr << "(" << r_tr.number_of_vertices() << "," @@ -286,9 +450,21 @@ std::cerr << "Total refining time: " << timer.time()+elapsed_time << "s" << std::endl; std::cerr << std::endl; #endif - + timer.stop(); elapsed_time += timer.time(); + +#if defined(CHECK_AND_DISPLAY_THE_NUMBER_OF_BAD_ELEMENTS_IN_THE_END) \ + || defined(SHOW_REMAINING_BAD_ELEMENT_IN_RED) + std::cerr << std::endl + << "===============================================================" << std::endl + << "=== CHECK_AND_DISPLAY_THE_NUMBER_OF_BAD_ELEMENTS_IN_THE_END ===" << std::endl; + display_number_of_bad_elements(); + std::cerr + << "===============================================================" + << std::endl << std::endl; +#endif + return elapsed_time; } @@ -298,7 +474,138 @@ Mesher_3:: initialize() { - facets_mesher_.scan_triangulation(); +#ifdef CGAL_MESH_3_PROFILING + std::cerr << "Initializing... "; + WallClockTimer t; +#endif + //===================================== + // Bounding box estimation + //===================================== + typedef std::vector > Points_vector; + Points_vector random_points_on_surface; + r_oracle_.construct_initial_points_object()( + std::back_inserter(random_points_on_surface), 1000); + typename Points_vector::const_iterator + it = random_points_on_surface.begin(), + it_end = random_points_on_surface.end(); + Bbox_3 estimated_bbox = it->first.bbox(); + ++it; + for( ; it != it_end ; ++it) + estimated_bbox = estimated_bbox + it->first.bbox(); + + Base::set_bbox(estimated_bbox); + + //======================================== + // Initialization: parallel or sequential + //======================================== + +#ifdef CGAL_LINKED_WITH_TBB + // Parallel + if (boost::is_convertible::value) + { + // we're not multi-thread, yet + r_c3t3_.triangulation().set_lock_data_structure(0); + +# ifndef CGAL_PARALLEL_MESH_3_DO_NOT_ADD_OUTSIDE_POINTS_ON_A_FAR_SPHERE + + if (r_c3t3_.number_of_far_points() == 0 && r_c3t3_.number_of_facets() == 0) + { + const Bbox_3 &bbox = estimated_bbox; + + // Compute radius for far sphere + const double xdelta = bbox.xmax()-bbox.xmin(); + const double ydelta = bbox.ymax()-bbox.ymin(); + const double zdelta = bbox.zmax()-bbox.zmin(); + const double radius = 5. * std::sqrt(xdelta*xdelta + + ydelta*ydelta + + zdelta*zdelta); + const Vector center( + bbox.xmin() + 0.5*xdelta, + bbox.ymin() + 0.5*ydelta, + bbox.zmin() + 0.5*zdelta); +# ifdef CGAL_CONCURRENT_MESH_3_VERBOSE + std::cerr << "Adding points on a far sphere (radius = " << radius <<")..."; +# endif + Random_points_on_sphere_3 random_point(radius); + const int NUM_PSEUDO_INFINITE_VERTICES = static_cast( + tbb::task_scheduler_init::default_num_threads() + * Concurrent_mesher_config::get().num_pseudo_infinite_vertices_per_core); + for (int i = 0 ; i < NUM_PSEUDO_INFINITE_VERTICES ; ++i, ++random_point) + r_c3t3_.add_far_point(*random_point + center); + +# ifdef CGAL_CONCURRENT_MESH_3_VERBOSE + std::cerr << "done." << std::endl; +# endif + } +# endif // CGAL_PARALLEL_MESH_3_DO_NOT_ADD_OUTSIDE_POINTS_ON_A_FAR_SPHERE + +#ifdef CGAL_MESH_3_PROFILING + double init_time = t.elapsed(); + std::cerr << "done in " << init_time << " seconds." << std::endl; +#endif + + // Scan triangulation + facets_mesher_.scan_triangulation(); + + // From now on, we're multi-thread + r_c3t3_.triangulation().set_lock_data_structure(get_lock_data_structure()); + } + // Sequential + else +#endif // CGAL_LINKED_WITH_TBB + { +#ifdef CGAL_SEQUENTIAL_MESH_3_ADD_OUTSIDE_POINTS_ON_A_FAR_SPHERE + if (r_c3t3_.number_of_far_points() == 0 && r_c3t3_.number_of_facets() == 0) + { + /*std::cerr << "A little bit of refinement... "; + + // Start by a little bit of refinement to get a coarse mesh + // => Good approx of bounding box + const int NUM_VERTICES_OF_COARSE_MESH = 40; + facets_mesher_.refine_sequentially_up_to_N_vertices( + facets_visitor_, NUM_VERTICES_OF_COARSE_MESH); + + std::cerr << "done." << std::endl; + std::cerr + << "Vertices: " << r_c3t3_.triangulation().number_of_vertices() << std::endl + << "Facets : " << r_c3t3_.number_of_facets_in_complex() << std::endl + << "Tets : " << r_c3t3_.number_of_cells_in_complex() << std::endl;*/ + + // Compute radius for far sphere + //const Bbox_3 &bbox = r_c3t3_.bbox(); + const Bbox_3 &bbox = estimated_bbox; + const double xdelta = bbox.xmax()-bbox.xmin(); + const double ydelta = bbox.ymax()-bbox.ymin(); + const double zdelta = bbox.zmax()-bbox.zmin(); + const double radius = 5. * std::sqrt(xdelta*xdelta + + ydelta*ydelta + + zdelta*zdelta); + const Vector center( + bbox.xmin() + 0.5*xdelta, + bbox.ymin() + 0.5*ydelta, + bbox.zmin() + 0.5*zdelta); +# ifdef CGAL_MESH_3_VERBOSE + std::cerr << "Adding points on a far sphere (radius = " << radius << ")..."; +# endif + Random_points_on_sphere_3 random_point(radius); + const int NUM_PSEUDO_INFINITE_VERTICES = 12*2; + for (int i = 0 ; i < NUM_PSEUDO_INFINITE_VERTICES ; ++i, ++random_point) + r_c3t3_.add_far_point(*random_point + center); +# ifdef CGAL_MESH_3_VERBOSE + std::cerr << "done." << std::endl; +# endif + } +#endif // CGAL_SEQUENTIAL_MESH_3_ADD_OUTSIDE_POINTS_ON_A_FAR_SPHERE + +#ifdef CGAL_MESH_3_PROFILING + double init_time = t.elapsed(); + std::cerr << "done in " << init_time << " seconds." << std::endl; +#endif + + // Scan triangulation + facets_mesher_.scan_triangulation(); + + } } @@ -309,7 +616,7 @@ { if ( ! facets_visitor_.is_active() ) { - cells_mesher_.scan_triangulation(); + cells_mesher_.scan_triangulation(); } } @@ -317,12 +624,22 @@ template void Mesher_3:: +display_number_of_bad_elements() +{ + int nf = facets_mesher_.number_of_bad_elements(); + int nc = cells_mesher_.number_of_bad_elements(); + std::cerr << "Bad facets: " << nf << " - Bad cells: " << nc << std::endl; +} + +template +void +Mesher_3:: one_step() { if ( ! facets_visitor_.is_active() ) { facets_mesher_.one_step(facets_visitor_); - + if ( facets_mesher_.is_algorithm_done() ) { facets_visitor_.activate(); @@ -331,10 +648,10 @@ } else { - cells_mesher_.one_step(cells_visitor_); + cells_mesher_.one_step(cells_visitor_); } } - + template bool Mesher_3:: @@ -353,7 +670,7 @@ return Mesher_status(r_c3t3_.triangulation().number_of_vertices(), facets_mesher_.queue_size(), cells_mesher_.queue_size()); -} +} #endif @@ -362,7 +679,7 @@ Mesher_3:: remove_cells_from_c3t3() { - for ( typename C3T3::Triangulation::Finite_cells_iterator + for ( typename C3T3::Triangulation::Finite_cells_iterator cit = r_c3t3_.triangulation().finite_cells_begin(), end = r_c3t3_.triangulation().finite_cells_end() ; cit != end ; ++cit ) { @@ -372,22 +689,22 @@ template inline -std::string +std::string Mesher_3::debug_info() const { return cells_mesher_.debug_info(); } - + template inline -std::string +std::string Mesher_3::debug_info_header() const { return cells_mesher_.debug_info_header(); } } // end namespace Mesh_3 - + } // end namespace CGAL diff -Nru cgal-4.4/include/CGAL/Mesh_3/Mesher_level_default_implementations.h cgal-4.5/include/CGAL/Mesh_3/Mesher_level_default_implementations.h --- cgal-4.4/include/CGAL/Mesh_3/Mesher_level_default_implementations.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/Mesh_3/Mesher_level_default_implementations.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,148 @@ +// Copyright (c) 2005 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Laurent RINEAU, Clement JAMIN + +#ifndef CGAL_MESH_3_MESHER_LEVEL_DEFAULT_IMPLEMENTATIONS_H +#define CGAL_MESH_3_MESHER_LEVEL_DEFAULT_IMPLEMENTATIONS_H + +#include + +namespace CGAL { namespace Mesh_3 { + +/** This class implements the two get_triangulation_ref() functions. + \param Tr The triangulation type */ +template +class Triangulation_ref_impl +{ + Tr& tr; +public: + Triangulation_ref_impl(Tr& t) : tr(t) + { + } + + Tr& triangulation_ref_impl() + { + return tr; + } + const Tr& triangulation_ref_impl() const + { + return tr; + } + +}; // end class Triangulation_ref_impl + +/** This struct implements an empty private_test_point_conflict_impl() + function. */ +struct No_private_test_point_conflict +{ + template + Mesher_level_conflict_status + private_test_point_conflict_impl(const Point&, const Zone&) const + { + return NO_CONFLICT; + } +}; // end No_private_test_point_conflict + +/** This struct implements an empty test_point_conflict_from_superior_impl() + function. */ +struct No_test_point_conflict_from_superior +{ + // For sequential + template + Mesher_level_conflict_status + test_point_conflict_from_superior_impl(const Point&, const Zone&) const + { + return NO_CONFLICT; + } + + // For parallel + template + Mesher_level_conflict_status + test_point_conflict_from_superior_impl(const Point&, const Zone&, + Mesh_visitor &) const + { + return NO_CONFLICT; + } +}; // end No_test_point_conflict_from_superior + +/** This struct implements empty functions: + - private_test_point_conflict_impl() and + - test_point_conflict_from_superior_impl(). +*/ +struct No_test_point_conflict : + public No_private_test_point_conflict, + public No_test_point_conflict_from_superior +{ +}; + +/** This struct implements an empty before_insertion_impl() + function. */ +struct No_before_insertion +{ + template + void before_insertion_impl(const Cell_handle&, const Point&, + Zone& ) + { + } +}; // end No_before_insertion + +/** This struct implements an empty after_insertion_impl() + function. */ +struct No_after_insertion +{ + template + void after_insertion_impl(const Vertex_handle&) + { + } +}; // end No_after_insertion + +/** This struct implements an empty after_insertion_impl() + function. */ +struct No_after_no_insertion +{ + template + void after_no_insertion_impl(const Cell_handle&, const Point&, + const Zone& ) + { + } +}; // end No_after_no_insertion + +/** This struct implements empty functions: + - before_insertion_impl(), + - after_insertion_impl(), + - after_no_insertion_impl() +*/ +struct No_before_after_insertion : + public No_after_insertion, + public No_before_insertion, + public No_after_no_insertion +{ +}; + +/** This struct implements an empty before_conflicts_impl() function. */ +struct No_before_conflicts { + template + void before_conflicts_impl(const Face_handle&, const Point&) + { + } +}; + +} } // end namespace CGAL::Mesh_3 + +#endif // CGAL_MESH_3_MESHER_LEVEL_DEFAULT_IMPLEMENTATIONS_H diff -Nru cgal-4.4/include/CGAL/Mesh_3/Mesher_level.h cgal-4.5/include/CGAL/Mesh_3/Mesher_level.h --- cgal-4.4/include/CGAL/Mesh_3/Mesher_level.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/Mesh_3/Mesher_level.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,1214 @@ +// Copyright (c) 2004-2005 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Laurent RINEAU, Clement JAMIN + +#ifndef CGAL_MESH_3_MESHER_LEVEL_H +#define CGAL_MESH_3_MESHER_LEVEL_H + +#include + +#ifdef CGAL_MESH_3_PROFILING + #include +#endif + +#include + +#ifdef CGAL_CONCURRENT_MESH_3_PROFILING +# define CGAL_PROFILE +# include +#endif + +#include + +#ifdef CGAL_LINKED_WITH_TBB +# include +# include +#endif + +#include + +namespace CGAL { namespace Mesh_3 { + +enum Mesher_level_conflict_status { + NO_CONFLICT = 0 + , CONFLICT_BUT_ELEMENT_CAN_BE_RECONSIDERED + , CONFLICT_AND_ELEMENT_SHOULD_BE_DROPPED + , THE_FACET_TO_REFINE_IS_NOT_IN_ITS_CONFLICT_ZONE + , ELEMENT_WAS_A_ZOMBIE + , COULD_NOT_LOCK_ZONE + , COULD_NOT_LOCK_ELEMENT +}; + +/************************************************ + * + * Null_mesher_level class + * + ************************************************/ + +struct Null_mesher_level { + + template + void refine(Visitor) {} + + // For sequential version + template + Mesher_level_conflict_status test_point_conflict_from_superior(P, Z) + { + return NO_CONFLICT; + } + // For parallel version + template + Mesher_level_conflict_status test_point_conflict_from_superior(P, Z, MV &) + { + return NO_CONFLICT; + } + + bool is_algorithm_done() const + { + return true; + } + + template + bool try_to_insert_one_point(Visitor) + { + return false; + } + + template + bool one_step(Visitor) + { + return false; + } + + //============================================== + // For parallel version + void add_to_TLS_lists(bool) {} + void splice_local_lists() {} + template + void before_next_element_refinement_in_superior(Mesh_visitor) {} + void before_next_element_refinement() {} + //============================================== + + std::string debug_info_class_name_impl() const + { + return "Null_mesher_level"; + } + + std::string debug_info() const + { + return ""; + } + std::string debug_info_header() const + { + return ""; + } + +}; // end Null_mesher_level + + +/************************************************ + * + * Mesher_level_base class + * + ************************************************/ + +template < + class Tr, /**< The triangulation type. */ + class Derived, /**< Derived class, that implements methods. */ + class Element, /**< Type of elements that this level refines. */ + class Previous, /* = Null_mesher_level, */ + /**< Previous level type, defaults to + \c Null_mesher_level. */ + class Triangulation_traits /** Traits class that defines types for the + triangulation. */ +> +class Mesher_level_base +{ +public: + /** Type of triangulation that is meshed. */ + typedef Tr Triangulation; + /** Type of point that are inserted into the triangulation. */ + typedef typename Triangulation::Point Point; + /** Type of vertex handles that are returns by insertions into the + triangulation. */ + typedef typename Triangulation::Vertex_handle Vertex_handle; + /** Type of lock data structure for concurrency */ + typedef typename Triangulation::Lock_data_structure Lock_data_structure; + /** Type of facet & cell handles */ + typedef typename Triangulation::Cell_handle Cell_handle; + typedef typename Cell_handle::value_type Cell; + typedef typename Triangulation::Facet Facet; + /** Type of the conflict zone for a point that can be inserted. */ + typedef typename Triangulation_traits::Zone Zone; + + typedef Element Element_type; + typedef Previous Previous_level; + +protected: + /** \name Private member functions */ + + /** Curiously recurring template pattern. */ + //@{ + Derived& derived() + { + return static_cast(*this); + } + + const Derived& derived() const + { + return static_cast(*this); + } + //@} + + /// debug info: class name + std::string debug_info_class_name() const + { + return derived().debug_info_class_name_impl(); + } + + std::string debug_info_element(const Element &e) const + { + return derived().debug_info_element_impl(e); + } + + /** \name Private member datas */ + + Previous_level& previous_level; /**< The previous level of the refinement + process. */ + +#ifdef CGAL_MESH_3_PROFILING +protected: + WallClockTimer m_timer; +#endif + +public: + typedef Mesher_level_base Self; + + /** \name CONSTRUCTORS */ + Mesher_level_base(Previous_level& previous) + : previous_level(previous) + { + } + + /** \name FUNCTIONS IMPLEMENTED IN THE CLASS \c Derived */ + + /** Access to the triangulation */ + Triangulation& triangulation() + { + return derived().triangulation_ref_impl(); + } + + /** Access to the triangulation */ + const Triangulation& triangulation() const + { + return derived().triangulation_ref_impl(); + } + + const Previous_level& previous() const + { + return previous_level; + } + + Vertex_handle insert(Point p, Zone& z) + { + return derived().insert_impl(p, z); + } + + void clear_refinement_queue() + { + derived().clear(); // Clear refinement queue + } + + /** Called before the first refinement, to initialized the queue of + elements that should be refined. */ + void scan_triangulation() + { + //derived().clear(); // Clear refinement queue + derived().scan_triangulation_impl(); + +#if defined(CGAL_MESH_3_USE_LAZY_UNSORTED_REFINEMENT_QUEUE)\ + && defined(CGAL_MESH_3_IF_UNSORTED_QUEUE_JUST_SORT_AFTER_SCAN) + std::cerr << "Sorting..."; + derived().sort(); + std::cerr << " done." << std::endl; +#endif + } + + /** For diagnostics. */ + int number_of_bad_elements() + { + return derived().number_of_bad_elements_impl(); + } + + /** Tells if, as regards the elements of type \c Element, the refinement is + done. */ + bool no_longer_element_to_refine() + { + return derived().no_longer_element_to_refine_impl(); + } + + /** It includes zombie elements */ + int number_of_elements_in_queue() + { + return derived().size(); + } + + /** Retrieves the next element that could be refined. */ + Element get_next_element() + { + return derived().get_next_element_impl(); + } + + /** Remove from the list the next element that could be refined. */ + void pop_next_element() + { + derived().pop_next_element_impl(); + } + + Point circumcenter_of_element(const Element& e) + { + return derived().circumcenter_impl(e); + } + + template + void before_next_element_refinement_in_superior(Mesh_visitor visitor) + { + derived().before_next_element_refinement_in_superior_impl(visitor); + } + + template + void before_next_element_refinement(Mesh_visitor visitor) + { + derived().before_next_element_refinement_impl(); + previous_level.before_next_element_refinement_in_superior( + visitor.previous_level()); + } + + /** Gives the point that should be inserted to refine the element \c e */ + Point refinement_point(const Element& e) + { + return derived().refinement_point_impl(e); + } + + /** Actions before testing conflicts for point \c p and element \c e */ + template + void before_conflicts(const Element& e, const Point& p, + Mesh_visitor visitor) + { + visitor.before_conflicts(e, p); + derived().before_conflicts_impl(e, p); + } + + /** Tells if, as regards this level of the refinement process, if the + point conflicts with something, and do what is needed. The return + type is made of two booleans: + - the first one tells if the point can be inserted, + - in case of, the first one is \c false, the second one tells if + the tested element should be reconsidered latter. + */ + Mesher_level_conflict_status private_test_point_conflict(const Point& p, + Zone& zone) + { + return derived().private_test_point_conflict_impl(p, zone); + } + + /** + * Actions before inserting the point \c p in order to refine the + * element \c e. The zone of conflicts is \c zone. + */ + template + void before_insertion(Element& e, const Point& p, Zone& zone, + Mesh_visitor visitor) + { + visitor.before_insertion(e, p, zone); + derived().before_insertion_impl(e, p, zone); + } + + /** Actions after having inserted the point. + * \param vh is the vertex handle of the inserted point, + * \param visitor is the visitor. + */ + template + void after_insertion(Vertex_handle vh, Mesh_visitor visitor) + { + derived().after_insertion_impl(vh); + visitor.after_insertion(vh); + } + + /** Actions after testing conflicts for point \c p and element \c e + * if no point is inserted. */ + template + void after_no_insertion(const Element& e, const Point& p, Zone& zone, + Mesh_visitor visitor) + { + derived().after_no_insertion_impl(e, p, zone); + visitor.after_no_insertion(e, p, zone); + } + + /** \name MESHING PROCESS + * + * The following functions use the functions that are implemented in the + * derived classes. + * + */ + + /** + * Tells it the algorithm is done, regarding elements of type \c Element + * or elements of previous levels. + */ + bool is_algorithm_done() + { +#ifdef CGAL_MESH_3_PROFILING + bool done = ( previous_level.is_algorithm_done() && + no_longer_element_to_refine() ); + /*if (done) + { + std::cerr << "done in " << m_timer.elapsed() << " seconds." << std::endl; + m_timer.reset(); + }*/ + return done; +#else + return ( previous_level.is_algorithm_done() && + no_longer_element_to_refine() ); +#endif + } + + /** + * This function takes one element from the queue, and try to refine + * it. It returns \c true if one point has been inserted. + * @todo Merge with try_to_refine_element(). + */ + template + bool process_one_element(Mesh_visitor visitor) + { + Element e = get_next_element(); + + const Mesher_level_conflict_status result + = derived().try_to_refine_element(e, visitor); + + if(result == CONFLICT_AND_ELEMENT_SHOULD_BE_DROPPED) + { + pop_next_element(); + } + + return result == NO_CONFLICT; + } + + void get_valid_vertices_of_element(const Cell_handle &e, Vertex_handle vertices[4]) const + { + for (int i = 0 ; i < 4 ; ++i) + vertices[i] = e->vertex(i); + } + // Among the 4 values, one of them will be Vertex_handle() (~= NULL) + void get_valid_vertices_of_element(const Facet &e, Vertex_handle vertices[4]) const + { + for (int i = 0 ; i < 4 ; ++i) + vertices[i] = (i != e.second ? e.first->vertex(i) : Vertex_handle()); + } + + Cell_handle get_cell_from_element(const Cell_handle &e) const + { + return e; + } + Cell_handle get_cell_from_element(const Facet &e) const + { + return e.first; + } + + /** \name STEP BY STEP FUNCTIONS */ + + /** + * Inserts exactly one point, if possible, and returns \c false if no + * point has been inserted because the algorithm is done. + */ + template + bool try_to_insert_one_point(Mesh_visitor visitor) + { + while(! is_algorithm_done() ) + { + if( previous_level.try_to_insert_one_point(visitor.previous_level()) ) + return true; + if(! no_longer_element_to_refine() ) + if( process_one_element(visitor) ) + return true; + } + return false; + } + +}; // end Mesher_level_base + + +/************************************************ +// Class Mesher_level +// Two versions: sequential / parallel +************************************************/ +// Sequential +template < + class Tr, /**< The triangulation type. */ + class Derived, /**< Derived class, that implements methods. */ + class Element, /**< Type of elements that this level refines. */ + class Previous, /* = Null_mesher_level, */ + /**< Previous level type, defaults to + \c Null_mesher_level. */ + class Triangulation_traits, /** Traits class that defines types for the + triangulation. */ + typename Concurrency_tag> +class Mesher_level + : public Mesher_level_base +{ +public: + + typedef Mesher_level Self; + + typedef Mesher_level_base Base; + + typedef typename Base::Lock_data_structure Lock_data_structure; + typedef typename Base::Zone Zone; + typedef typename Base::Point Point; + typedef typename Base::Vertex_handle Vertex_handle; + using Base::derived; + using Base::is_algorithm_done; + using Base::triangulation; + using Base::insert; + using Base::before_conflicts; + using Base::previous_level; + using Base::no_longer_element_to_refine; + using Base::pop_next_element; + using Base::debug_info_class_name; + using Base::debug_info_element; + + /** \name CONSTRUCTORS */ + + Mesher_level(Previous& previous) + : Base(previous) + { + } + + void add_to_TLS_lists(bool) {} + void splice_local_lists() {} + bool no_longer_local_element_to_refine() { return true; } + Element get_next_local_element() {return Element(); } + void pop_next_local_element() {} + + Zone conflicts_zone(const Point& p + , Element e + , bool &facet_is_in_its_cz) + { + return derived().conflicts_zone_impl(p, e, facet_is_in_its_cz); + } + + /** Tells if, as regards this level of the refinement process, if the + point conflicts with something, and do what is needed. The return + type is made of two booleans: + - the first one tells if the point can be inserted, + - in case of, the first one is \c false, the second one tells if + the tested element should be reconsidered latter. + This function is called by the superior level, if any. + */ + Mesher_level_conflict_status + test_point_conflict_from_superior(const Point& p, Zone& zone) + { + return derived().test_point_conflict_from_superior_impl(p, zone); + } + + /** Refines elements of this level and previous levels (SEQUENTIAL VERSION). */ + template + void refine(Mesh_visitor visitor) + { + while(! is_algorithm_done() ) + { + previous_level.refine(visitor.previous_level()); + if(! no_longer_element_to_refine() ) + { + this->process_one_element(visitor); + } + } + } + + template + Mesher_level_conflict_status + try_to_refine_element(Element e, Mesh_visitor visitor) + { + const Point& p = this->refinement_point(e); + +#ifdef CGAL_MESH_3_VERY_VERBOSE + std::cerr << "Trying to insert point: " << p << + " inside element " << debug_info_element(e) << std::endl; +#endif + + Mesher_level_conflict_status result; + Zone zone; + + before_conflicts(e, p, visitor); + + bool facet_is_in_its_cz = true; + zone = conflicts_zone(p, e, facet_is_in_its_cz); + if (!facet_is_in_its_cz) + result = THE_FACET_TO_REFINE_IS_NOT_IN_ITS_CONFLICT_ZONE; + else + result = test_point_conflict(p, zone); + +#ifdef CGAL_MESHES_DEBUG_REFINEMENT_POINTS + std::cerr << "(" << p << ") "; + switch( result ) + { + case NO_CONFLICT: + std::cerr << "accepted\n"; + break; + case CONFLICT_BUT_ELEMENT_CAN_BE_RECONSIDERED: + std::cerr << "rejected (temporarily)\n"; + break; + case CONFLICT_AND_ELEMENT_SHOULD_BE_DROPPED: + std::cerr << "rejected (permanent)\n"; + break; + case THE_FACET_TO_REFINE_IS_NOT_IN_ITS_CONFLICT_ZONE: + std::cerr << "the facet to refine was not in the conflict zone " + "(switching to exact)\n"; + break; + case ELEMENT_WAS_A_ZOMBIE: + std::cerr << "element was a zombie\n"; + break; + case COULD_NOT_LOCK_ELEMENT: + std::cerr << "could not lock element\n"; + break; + case COULD_NOT_LOCK_ZONE: + std::cerr << "could not lock zone\n"; + break; + } +#endif + + if(result == NO_CONFLICT) + { + this->before_insertion(e, p, zone, visitor); + + Vertex_handle vh = insert(p, zone); + + this->after_insertion(vh, visitor); + } + else + { + this->after_no_insertion(e, p, zone, visitor); + } + + return result; + } + + /** Refines elements of this level and previous levels. + * Stops when algorithm is done + * or when num vertices > approx_max_num_mesh_vertices + */ + template + void + refine_sequentially_up_to_N_vertices(Mesh_visitor visitor, + int approx_max_num_mesh_vertices) + { + while(! is_algorithm_done() + && triangulation().number_of_vertices() < approx_max_num_mesh_vertices) + { + previous_level.refine(visitor.previous_level()); + if(! no_longer_element_to_refine() ) + { + this->process_one_element(visitor); + } + } + } + + /** Return (can_split_the_element, drop_element). */ + Mesher_level_conflict_status + test_point_conflict(const Point& p, Zone& zone) + { + const Mesher_level_conflict_status result = + previous_level.test_point_conflict_from_superior(p, zone); + + if( result != NO_CONFLICT ) + return result; + + return this->private_test_point_conflict(p, zone); + } + + /** + * Applies one step of the algorithm: tries to refine one element of + * previous level or one element of this level. Return \c false iff + * is_algorithm_done()==true . + */ + template + bool one_step(Mesh_visitor visitor) + { + if( ! previous_level.is_algorithm_done() ) + previous_level.one_step(visitor.previous_level()); + else if( ! no_longer_element_to_refine() ) + { + this->process_one_element(visitor); + } + return ! is_algorithm_done(); + } + + // Useless here + void set_lock_ds(Lock_data_structure *) {} + void set_worksharing_ds(WorksharingDataStructureType *) {} + +protected: +}; + +// Parallel +#ifdef CGAL_LINKED_WITH_TBB +template < + class Tr, /**< The triangulation type. */ + class Derived, /**< Derived class, that implements methods. */ + class Element, /**< Type of elements that this level refines. */ + class Previous, /* = Null_mesher_level, */ + /**< Previous level type, defaults to + \c Null_mesher_level. */ + class Triangulation_traits> /** Traits class that defines types for the + triangulation. */ +class Mesher_level + : public Mesher_level_base +{ +private: + typedef Derived Derived_; + template class Enqueue_element; +public: + + typedef Mesher_level Self; + + typedef Mesher_level_base Base; + + + typedef typename Base::Lock_data_structure Lock_data_structure; + typedef typename Base::Zone Zone; + typedef typename Base::Point Point; + typedef typename Base::Vertex_handle Vertex_handle; + using Base::derived; + using Base::is_algorithm_done; + using Base::triangulation; + using Base::insert; + using Base::before_conflicts; + using Base::before_insertion; + using Base::after_insertion; + using Base::previous_level; + using Base::no_longer_element_to_refine; + using Base::pop_next_element; + using Base::debug_info_class_name; + using Base::debug_info_element; + + /** \name CONSTRUCTORS */ + + Mesher_level(Previous& previous) + : Base(previous), + FIRST_GRID_LOCK_RADIUS( + Concurrent_mesher_config::get().first_grid_lock_radius) + , MESH_3_REFINEMENT_GRAINSIZE( + Concurrent_mesher_config::get().first_grid_lock_radius) + , REFINEMENT_BATCH_SIZE( + Concurrent_mesher_config::get().refinement_batch_size) + , m_lock_ds(0) + , m_worksharing_ds(0) + , m_empty_root_task(0) + { + } + + void add_to_TLS_lists(bool add) + { + derived().add_to_TLS_lists_impl(add); + } + void splice_local_lists() + { + derived().splice_local_lists_impl(); + } + + bool no_longer_local_element_to_refine() + { + return derived().no_longer_local_element_to_refine_impl(); + } + + Element get_next_local_element() + { + return derived().get_next_local_element_impl(); + } + + void pop_next_local_element() + { + derived().pop_next_local_element_impl(); + } + + Zone conflicts_zone(const Point& p + , Element e + , bool &facet_is_in_its_cz + , bool &could_lock_zone) + { + return derived().conflicts_zone_impl(p, e, facet_is_in_its_cz, + could_lock_zone); + } + + template + void treat_local_refinement_queue(Mesh_visitor visitor) + { + // We treat the elements of the local (TLS) refinement queue + while (no_longer_local_element_to_refine() == false) + { + typedef typename Derived::Container::Element Container_element; + Container_element ce = derived().get_next_local_raw_element_impl().second; + + Mesher_level_conflict_status status; + do + { + status = try_lock_and_refine_element(ce, visitor); + } + while (status != NO_CONFLICT + && status != CONFLICT_AND_ELEMENT_SHOULD_BE_DROPPED + && status != ELEMENT_WAS_A_ZOMBIE); + + pop_next_local_element(); + } + } + + /** Tells if, as regards this level of the refinement process, if the + point conflicts with something, and do what is needed. The return + type is made of two booleans: + - the first one tells if the point can be inserted, + - in case of, the first one is \c false, the second one tells if + the tested element should be reconsidered latter. + This function is called by the superior level, if any. + */ + template + Mesher_level_conflict_status test_point_conflict_from_superior( + const Point& p, Zone& zone, Mesh_visitor &visitor) + { + return derived().test_point_conflict_from_superior_impl(p, zone, visitor); + } + + /** Refines elements of this level and previous levels (SEQUENTIAL VERSION). */ + template + void refine(Mesh_visitor visitor) + { + while(! is_algorithm_done() ) + { + previous_level.refine(visitor.previous_level()); + if(! no_longer_element_to_refine() ) + { + process_a_batch_of_elements(visitor); + } + } + } + + /** Refines elements of this level and previous levels. + * Stops when algorithm is done + * or when num vertices > approx_max_num_mesh_vertices + */ + template + void + refine_sequentially_up_to_N_vertices(Mesh_visitor visitor, + int approx_max_num_mesh_vertices) + { + + CGAL_assertion_msg(triangulation().get_lock_data_structure() == 0, + "In refine_sequentially_up_to_N_vertices, the triangulation's locking data structure should be NULL"); + + while(! is_algorithm_done() + && triangulation().number_of_vertices() < approx_max_num_mesh_vertices) + { + previous_level.refine(visitor.previous_level()); + if(! no_longer_element_to_refine() ) + { + this->process_one_element(visitor); + } + } + } + + void unlock_all_thread_local_elements() + { + if (m_lock_ds) + { + m_lock_ds->unlock_all_points_locked_by_this_thread(); + } + } + + template + void enqueue_task( + const Container_element &ce, const Quality &quality, Mesh_visitor visitor) + { + CGAL_assertion(m_empty_root_task != 0); + + m_worksharing_ds->enqueue_work( + Enqueue_element( + *this, ce, quality, visitor), + quality, + *m_empty_root_task + // NOTE: if you uncomment this line (Load_based_worksharing_ds), the element may + // be a zombie at this point => thus, it may be "infinite" and cause an assertion error + // in debug mode when computing the circumcenter + //, circumcenter_of_element(derived().extract_element_from_container_value(ce)) + ); + } + + /** + * This function takes N elements from the queue, and try to refine + * it in parallel. + */ + template + void process_a_batch_of_elements(Mesh_visitor visitor) + { + typedef typename Derived::Container::value_type Container_quality_and_element; + +#ifdef CGAL_CONCURRENT_MESH_3_VERBOSE + std::cerr << "Refining elements..."; +#endif + + previous_level.add_to_TLS_lists(true); + add_to_TLS_lists(true); + + m_empty_root_task = new( tbb::task::allocate_root() ) tbb::empty_task; + m_empty_root_task->set_ref_count(1); + + while (!no_longer_element_to_refine()) + { + Container_quality_and_element qe = derived().get_next_raw_element_impl(); + pop_next_element(); + enqueue_task(qe.second, qe.first, visitor); + } + + m_empty_root_task->wait_for_all(); + +#if defined(CGAL_MESH_3_VERBOSE) || defined(CGAL_MESH_3_PROFILING) + std::cerr << " Flushing"; +#endif + bool keep_flushing = true; + while (keep_flushing) + { + m_empty_root_task->set_ref_count(1); + keep_flushing = m_worksharing_ds->flush_work_buffers(*m_empty_root_task); + m_empty_root_task->wait_for_all(); +#if defined(CGAL_MESH_3_VERBOSE) || defined(CGAL_MESH_3_PROFILING) + std::cerr << "."; +#endif + } + + tbb::task::destroy(*m_empty_root_task); + m_empty_root_task = 0; + + splice_local_lists(); + //previous_level.splice_local_lists(); // useless + previous_level.add_to_TLS_lists(false); + add_to_TLS_lists(false); + +#ifdef CGAL_CONCURRENT_MESH_3_VERBOSE + std::cerr << " done." << std::endl; +#endif + + } + + template + Mesher_level_conflict_status + try_to_refine_element(Element e, Mesh_visitor visitor) + { + const Point& p = this->refinement_point(e); + +#ifdef CGAL_MESH_3_VERY_VERBOSE + std::cerr << "Trying to insert point: " << p << + " inside element " << debug_info_element(e) << std::endl; +#endif + + before_conflicts(e, p, visitor); + + bool could_lock_zone; + bool facet_is_in_its_cz = true; + Zone zone = conflicts_zone(p, e, facet_is_in_its_cz, could_lock_zone); + Mesher_level_conflict_status result; + if (!could_lock_zone) + result = COULD_NOT_LOCK_ZONE; + else if (!facet_is_in_its_cz) + result = THE_FACET_TO_REFINE_IS_NOT_IN_ITS_CONFLICT_ZONE; + else + result = test_point_conflict(p, zone, visitor); + +#ifdef CGAL_MESHES_DEBUG_REFINEMENT_POINTS + std::cerr << "(" << p << ") "; + switch( result ) + { + case NO_CONFLICT: + std::cerr << "accepted\n"; + break; + case CONFLICT_BUT_ELEMENT_CAN_BE_RECONSIDERED: + std::cerr << "rejected (temporarily)\n"; + break; + case CONFLICT_AND_ELEMENT_SHOULD_BE_DROPPED: + std::cerr << "rejected (permanent)\n"; + break; + case THE_FACET_TO_REFINE_IS_NOT_IN_ITS_CONFLICT_ZONE: + std::cerr << "the facet to refine was not in the conflict zone " + "(switching to exact)\n"; + break; + case ELEMENT_WAS_A_ZOMBIE: + std::cerr << "element was a zombie\n"; + break; + case COULD_NOT_LOCK_ELEMENT: + std::cerr << "could not lock element\n"; + break; + case COULD_NOT_LOCK_ZONE: + std::cerr << "could not lock zone\n"; + break; + } +#endif + + if(result == NO_CONFLICT) + { + this->before_insertion(e, p, zone, visitor); + + Vertex_handle vh = insert(p, zone); + + if (vh == Vertex_handle()) + { + this->after_no_insertion(e, p, zone, visitor); + result = COULD_NOT_LOCK_ZONE; + } + else + { + this->after_insertion(vh, visitor); + } + } + else + { + this->after_no_insertion(e, p, zone, visitor); + } + + return result; + } + + template + Mesher_level_conflict_status + try_lock_and_refine_element(const Container_element &ce, Mesh_visitor visitor) + { +#ifdef CGAL_CONCURRENT_MESH_3_PROFILING + static Profile_branch_counter_3 bcounter( + std::string("early withdrawals / late withdrawals / successes [") + debug_info_class_name() + "]"); +#endif + + Mesher_level_conflict_status result; + Derived &derivd = derived(); + if( !derivd.is_zombie(ce) ) + { + // Lock the element area on the grid + Element element = derivd.extract_element_from_container_value(ce); + bool locked = derivd.try_lock_element(element, FIRST_GRID_LOCK_RADIUS); + + if( locked ) + { + // Test it again as it may have changed in the meantime + if( !derivd.is_zombie(ce) ) + { + result = try_to_refine_element(element, visitor); + + //lock.release(); + + if (result == CONFLICT_BUT_ELEMENT_CAN_BE_RECONSIDERED + || result == THE_FACET_TO_REFINE_IS_NOT_IN_ITS_CONFLICT_ZONE) + { +#ifdef CGAL_CONCURRENT_MESH_3_PROFILING + ++bcounter; // It's not a withdrawal +#endif + } + else if (result == COULD_NOT_LOCK_ZONE) + { +#ifdef CGAL_CONCURRENT_MESH_3_PROFILING + bcounter.increment_branch_1(); // THIS is a late withdrawal! +#endif + } + else + { +#ifdef CGAL_CONCURRENT_MESH_3_PROFILING + ++bcounter; +#endif + } + } + else + { + result = ELEMENT_WAS_A_ZOMBIE; + } + + // Unlock + unlock_all_thread_local_elements(); + } + // else, we will try it again + else + { +#ifdef CGAL_CONCURRENT_MESH_3_PROFILING + bcounter.increment_branch_2(); // THIS is an early withdrawal! +#endif + // Unlock + unlock_all_thread_local_elements(); + + std::this_thread::yield(); + result = COULD_NOT_LOCK_ELEMENT; + } + } + else + { + result = ELEMENT_WAS_A_ZOMBIE; + } + + return result; + } + + /** Return (can_split_the_element, drop_element). */ + template + Mesher_level_conflict_status + test_point_conflict(const Point& p, Zone& zone, Mesh_visitor &visitor) + { + const Mesher_level_conflict_status result = + previous_level.test_point_conflict_from_superior( + p, zone, visitor.previous_level()); + + if( result != NO_CONFLICT ) + return result; + + return this->private_test_point_conflict(p, zone); + } + + /** + * Applies one step of the algorithm: tries to refine one element of + * previous level or one element of this level. Return \c false iff + * is_algorithm_done()==true . + */ + template + bool one_step(Mesh_visitor visitor) + { + if( ! previous_level.is_algorithm_done() ) + previous_level.one_step(visitor.previous_level()); + else if( ! no_longer_element_to_refine() ) + { + process_a_batch_of_elements(visitor); + } + return ! is_algorithm_done(); + } + + void set_lock_ds(Lock_data_structure *p) + { + m_lock_ds = p; + } + + void set_worksharing_ds(WorksharingDataStructureType *p) + { + m_worksharing_ds = p; + } + +protected: + + // Member variables + const int FIRST_GRID_LOCK_RADIUS; + const int MESH_3_REFINEMENT_GRAINSIZE; + const int REFINEMENT_BATCH_SIZE; + Lock_data_structure *m_lock_ds; + WorksharingDataStructureType *m_worksharing_ds; + + tbb::task *m_empty_root_task; + +private: + + // Functor for enqueue_task function + template + class Enqueue_element + { + ML & m_mesher_level; + Container_element m_container_element; + Quality m_quality; + Mesh_visitor m_visitor; + + public: + // Constructor + Enqueue_element(ML &ml, + const Container_element &ce, + const Quality &quality, + Mesh_visitor visitor) + : m_mesher_level(ml), + m_container_element(ce), + m_quality(quality), + m_visitor(visitor) + { + } + + // operator() + void operator()() const + { + typedef typename ML::Derived_::Container::value_type + Container_quality_and_element; + + Mesher_level_conflict_status status; + do + { + status = m_mesher_level.try_lock_and_refine_element(m_container_element, + m_visitor); + } + while (status != NO_CONFLICT + && status != CONFLICT_AND_ELEMENT_SHOULD_BE_DROPPED + && status != CONFLICT_BUT_ELEMENT_CAN_BE_RECONSIDERED + && status != ELEMENT_WAS_A_ZOMBIE); + + // Refine the new bad facets + m_mesher_level.before_next_element_refinement(m_visitor); + + // We can now reconsider the element if requested + if (status == CONFLICT_BUT_ELEMENT_CAN_BE_RECONSIDERED) + m_mesher_level.enqueue_task(m_container_element, m_quality, m_visitor); + + // Finally we add the new local bad_elements to the feeder + while (m_mesher_level.no_longer_local_element_to_refine() == false) + { + Container_quality_and_element qe = + m_mesher_level.derived().get_next_local_raw_element_impl(); + m_mesher_level.pop_next_local_element(); + m_mesher_level.enqueue_task(qe.second, qe.first, m_visitor); + } + } + }; + +}; +#endif // CGAL_LINKED_WITH_TBB + +} } // end namespace CGAL::Mesh_3 + +#include +#include + +#endif // CGAL_MESH_3_MESHER_LEVEL_H diff -Nru cgal-4.4/include/CGAL/Mesh_3/Mesh_global_optimizer.h cgal-4.5/include/CGAL/Mesh_3/Mesh_global_optimizer.h --- cgal-4.4/include/CGAL/Mesh_3/Mesh_global_optimizer.h 2013-12-21 20:00:22.000000000 +0000 +++ cgal-4.5/include/CGAL/Mesh_3/Mesh_global_optimizer.h 2014-08-29 13:58:16.000000000 +0000 @@ -19,7 +19,7 @@ // Author(s) : Stephane Tayeb // //****************************************************************************** -// File Description : +// File Description : //****************************************************************************** #ifndef CGAL_MESH_3_MESH_GLOBAL_OPTIMIZER_H @@ -34,45 +34,213 @@ #include #include #include +#include + +#include + +#ifdef CGAL_MESH_3_PROFILING + #include +#endif #include #include +#include #include #include +#include + +#ifdef CGAL_LINKED_WITH_TBB +# include +# include +# include +#endif namespace CGAL { namespace Mesh_3 { - - + + +/************************************************ +// Class Mesh_global_optimizer_base +// Two versions: sequential / parallel +************************************************/ + +// Sequential +template +class Mesh_global_optimizer_base +{ +protected: + typedef typename Tr::Geom_traits Gt; + typedef typename Gt::FT FT; + typedef typename Tr::Lock_data_structure Lock_data_structure; + + typedef std::vector > Moves_vector; + typedef unsigned int Nb_frozen_points_type ; + + Mesh_global_optimizer_base(const Bbox_3 &, int) + : big_moves_size_(0) {} + + void update_big_moves(const FT& new_sq_move) + { + if (big_moves_.size() < big_moves_size_ ) + big_moves_.insert(new_sq_move); + else + { + FT smallest = *(big_moves_.begin()); + if( new_sq_move > smallest ) + { + big_moves_.erase(big_moves_.begin()); + big_moves_.insert(new_sq_move); + } + } + } + + void clear_big_moves() + { + big_moves_.clear(); + } + + Lock_data_structure *get_lock_data_structure() { return 0; } + void unlock_all_elements() {} + +protected: + std::size_t big_moves_size_; + std::multiset big_moves_; +}; + +#ifdef CGAL_LINKED_WITH_TBB +// Parallel +template +class Mesh_global_optimizer_base +{ +protected: + typedef typename Tr::Geom_traits Gt; + typedef typename Gt::FT FT; + typedef typename Tr::Lock_data_structure Lock_data_structure; + typedef tbb::concurrent_vector > Moves_vector; + typedef tbb::atomic Nb_frozen_points_type ; + + Mesh_global_optimizer_base(const Bbox_3 &bbox, int num_grid_cells_per_axis) + : big_moves_size_(0) + , m_lock_ds(bbox, num_grid_cells_per_axis) + { + big_moves_current_size_ = 0; + big_moves_smallest_ = std::numeric_limits::max(); + } + + void update_big_moves(const FT& new_sq_move) + { + if (++big_moves_current_size_ <= big_moves_size_ ) + { + tbb::mutex::scoped_lock lock(m_big_moves_mutex); + typename std::multiset::const_iterator it = big_moves_.insert(new_sq_move); + + // New smallest move of all big moves? + if (it == big_moves_.begin()) + big_moves_smallest_ = new_sq_move; + } + else + { + --big_moves_current_size_; + + if( new_sq_move > big_moves_smallest_ ) + { + tbb::mutex::scoped_lock lock(m_big_moves_mutex); + // Test it again since it may have been modified by another + // thread in the meantime + if( new_sq_move > big_moves_smallest_ ) + { + big_moves_.erase(big_moves_.begin()); + typename std::multiset::const_iterator it = big_moves_.insert(new_sq_move); + + // New smallest move of all big moves? + if (it == big_moves_.begin()) + big_moves_smallest_ = new_sq_move; + } + } + } + } + + void clear_big_moves() + { + big_moves_current_size_ = 0; + big_moves_smallest_ = std::numeric_limits::max(); + big_moves_.clear(); + } + + Lock_data_structure *get_lock_data_structure() + { + return &m_lock_ds; + } + + void unlock_all_elements() + { + m_lock_ds.unlock_all_points_locked_by_this_thread(); + } + +public: + +protected: + tbb::atomic big_moves_current_size_; + tbb::atomic big_moves_smallest_; + std::size_t big_moves_size_; + std::multiset big_moves_; + tbb::mutex m_big_moves_mutex; + + /// Lock data structure + Lock_data_structure m_lock_ds; +}; +#endif // CGAL_LINKED_WITH_TBB + + + + +/************************************************ +// Class Mesh_global_optimizer +************************************************/ + template > class Mesh_global_optimizer -{ +: public Mesh_global_optimizer_base +{ // Types + typedef typename C3T3::Concurrency_tag Concurrency_tag; + + typedef Mesh_global_optimizer Self; + typedef Mesh_global_optimizer_base< + typename C3T3::Triangulation, typename C3T3::Concurrency_tag> Base; + + using Base::get_lock_data_structure; + using Base::big_moves_; + using Base::big_moves_size_; + typedef typename C3T3::Triangulation Tr; typedef typename Tr::Geom_traits Gt; - + typedef typename Tr::Point Point_3; typedef typename Tr::Cell_handle Cell_handle; typedef typename Tr::Vertex_handle Vertex_handle; typedef typename Tr::Edge Edge; typedef typename Tr::Vertex Vertex; - + typedef typename Gt::FT FT; typedef typename Gt::Vector_3 Vector_3; - + typedef typename std::vector Cell_vector; typedef typename std::vector Vertex_vector; typedef typename std::set Vertex_set; - typedef std::vector > Moves_vector; - + typedef typename Base::Moves_vector Moves_vector; + typedef typename Base::Nb_frozen_points_type Nb_frozen_points_type; + #ifdef CGAL_INTRUSIVE_LIST typedef Intrusive_list Outdated_cell_set; -#else +#else typedef std::set Outdated_cell_set; #endif //CGAL_INTRUSIVE_LIST @@ -83,9 +251,9 @@ #endif typedef typename MoveFunction::Sizing_field Sizing_field; - + typedef class C3T3_helpers C3T3_helpers; - + // Visitor class // Should define: // - after_compute_moves() @@ -93,7 +261,7 @@ // - after_rebuild_restricted_delaunay() // - end_of_iteration(int iteration_number) typedef Visitor_ Visitor; - + public: /** * Constructor @@ -104,7 +272,7 @@ const bool do_freeze, const FT& convergence_ratio, const MoveFunction move_function = MoveFunction()); - + /** * Launch optimization process * @@ -122,25 +290,103 @@ /// Time accessors void set_time_limit(double time) { time_limit_ = time; } double time_limit() const { return time_limit_; } - + private: /** * Returns moves for vertices of set \c moving_vertices */ - Moves_vector compute_moves(Moving_vertices_set& moving_vertices); - + Moves_vector compute_moves(Moving_vertices_set& moving_vertices) +{ + typename Gt::Construct_translated_point_3 translate = + Gt().construct_translated_point_3_object(); + + // Store new position of points which have to move + Moves_vector moves; + + + moves.reserve(moving_vertices.size()); + + // reset worst_move list + this->clear_big_moves(); + +#ifdef CGAL_MESH_3_PROFILING + std::cerr << "Computing moves..."; + WallClockTimer t; +#endif + + +#ifdef CGAL_LINKED_WITH_TBB + // Parallel + if (boost::is_convertible::value) + { + tbb::concurrent_vector vertices_not_moving_any_more; + + // Get move for each moving vertex + tbb::parallel_do( + moving_vertices.begin(), moving_vertices.end(), + Compute_move( + *this, sizing_field_, moves, do_freeze_, vertices_not_moving_any_more, + translate) + ); + + typename tbb::concurrent_vector::const_iterator it + = vertices_not_moving_any_more.begin(); + typename tbb::concurrent_vector::const_iterator it_end + = vertices_not_moving_any_more.end(); + for ( ; it != it_end ; ++it) + { + moving_vertices.erase(*it); + } + } + // Sequential + else +#endif // CGAL_LINKED_WITH_TBB + { + // Get move for each moving vertex + typename Moving_vertices_set::iterator vit = moving_vertices.begin(); + for ( ; vit != moving_vertices.end() ; ) + { + Vertex_handle oldv = *vit; + ++vit; + Vector_3 move = compute_move(oldv); + + if ( CGAL::NULL_VECTOR != move ) + { + Point_3 new_position = translate(oldv->point(),move); + FT size = (Sizing_field::is_vertex_update_needed ? + sizing_field_(new_position, oldv) : 0); + moves.push_back(cpp11::make_tuple(oldv,new_position,size)); + } + else // CGAL::NULL_VECTOR == move + { + if(do_freeze_) + moving_vertices.erase(oldv); // TODO: if non-intrusive, + // we can optimize since we have the iterator, + // don't forget to do "vit = mv.erase(vit)" instead ++vit + } + + // Stop if time_limit_ is reached + if ( is_time_limit_reached() ) + break; + } + } + +#ifdef CGAL_MESH_3_PROFILING + std::cerr << "done in " << t.elapsed() << " seconds." << std::endl; +#endif + + return moves; +} + + /** * Returns the move for vertex \c v * warning : this function should be called only on moving vertices * even for frozen vertices, it could return a non-zero vector */ Vector_3 compute_move(const Vertex_handle& v); - - /** - * update big_moves_ vector with new_sq_move value - */ - void update_big_moves(const FT& new_sq_move); - + /** * Updates mesh using moves of \c moves vector. Updates moving_vertices with * the new set of moving vertices after the move. @@ -148,42 +394,223 @@ void update_mesh(const Moves_vector& moves, Moving_vertices_set& moving_vertices, Visitor& visitor); - + /** * Fill sizing field using sizes (avg circumradius) contained in tr_ */ void fill_sizing_field(); - + /** * Returns true if convergence is reached */ bool check_convergence() const; - + /** * Returns the average circumradius length of cells incident to \c v */ FT average_circumradius_length(const Vertex_handle& v) const; - + /** * Returns the minimum cicumradius length of cells incident to \c v */ - FT min_circumradius_sq_length(const Vertex_handle& v, const Cell_vector& incident_cells) const; - + FT min_circumradius_sq_length(const Vertex_handle& v, const Cell_vector& incident_cells) const; + /** * Returns the squared circumradius length of cell \c cell */ FT sq_circumradius_length(const Cell_handle& cell, const Vertex_handle& v) const; - + /** * Returns true if time_limit is reached */ bool is_time_limit_reached() const { - return ( (time_limit() > 0) && (running_time_.time() > time_limit()) ); + return ( (time_limit() > 0) && (running_time_.time() > time_limit()) ); } - + private: + +#ifdef CGAL_LINKED_WITH_TBB + // Functor for compute_moves function + template + class Compute_move + { + typedef tbb::concurrent_vector Vertex_conc_vector; + + MGO & m_mgo; + const Sizing_field_ & m_sizing_field; + Moves_vector_ & m_moves; + bool m_do_freeze; + Vertex_conc_vector & m_vertices_not_moving_any_more; + const CTOP3 & m_translate; + + public: + // Constructor + Compute_move(MGO &mgo, + const Sizing_field_ &sizing_field, + Moves_vector_ &moves, + bool do_freeze, + Vertex_conc_vector & vertices_not_moving_any_more, + const CTOP3 & translate) + : m_mgo(mgo), + m_sizing_field(sizing_field), + m_moves(moves), + m_do_freeze(do_freeze), + m_vertices_not_moving_any_more(vertices_not_moving_any_more), + m_translate(translate) + {} + + // Constructor + Compute_move(const Compute_move &cm) + : m_mgo(cm.m_mgo), + m_sizing_field(cm.m_sizing_field), + m_moves(cm.m_moves), + m_do_freeze(cm.m_do_freeze), + m_vertices_not_moving_any_more(cm.m_vertices_not_moving_any_more), + m_translate(cm.m_translate) + {} + + // operator() + void operator()(const Vertex_handle& oldv) const + { + Vector_3 move = m_mgo.compute_move(oldv); + + if ( CGAL::NULL_VECTOR != move ) + { + Point_3 new_position = m_translate(oldv->point(), move); + FT size = (MGO::Sizing_field::is_vertex_update_needed ? + m_sizing_field(new_position, oldv) : 0); + // typedef Triangulation_helpers Th; + //if( !Th().inside_protecting_balls(tr_, oldv, new_position)) + //note : this is not happening for Lloyd and ODT so it's commented + // maybe for a new global optimizer it should be de-commented + m_moves.push_back(cpp11::make_tuple(oldv, new_position, size)); + } + else // CGAL::NULL_VECTOR == move + { + if(m_do_freeze) + { + m_vertices_not_moving_any_more.push_back(oldv); + } + } + + if ( m_mgo.is_time_limit_reached() ) + tbb::task::self().cancel_group_execution(); + } + }; + + // Functor for fill_sizing_field function + template + class Compute_sizing_field_value + { + MGO & m_mgo; + Local_list_ & m_local_lists; + + public: + // Constructor + Compute_sizing_field_value(MGO &mgo, + Local_list_ & local_lists) + : m_mgo(mgo), + m_local_lists(local_lists) + {} + + // Constructor + Compute_sizing_field_value(const Compute_sizing_field_value &csfv) + : m_mgo(csfv.m_mgo), + m_local_lists(csfv.m_local_lists) + {} + + // operator() + void operator()(Vertex& v) const + { + Vertex_handle vh + = Tr_::Triangulation_data_structure::Vertex_range::s_iterator_to(v); + m_local_lists.local().push_back( + std::make_pair(v.point(), m_mgo.average_circumradius_length(vh))); + } + }; + + // Functor for update_mesh function + template + class Move_vertex + { + MGO & m_mgo; + const Helper & m_helper; + const Moves_vector_ & m_moves; + Moving_vertices_set_ & m_moving_vertices; + Outdated_cell_set_ & m_outdated_cells; + + typedef typename Tr_::Point Point_3; + typedef typename Tr_::Vertex_handle Vertex_handle; + + public: + // Constructor + Move_vertex(MGO &mgo, const Helper &helper, const Moves_vector_ &moves, + Moving_vertices_set_ &moving_vertices, + Outdated_cell_set_ &outdated_cells) + : m_mgo(mgo), m_helper(helper), m_moves(moves), + m_moving_vertices(moving_vertices), m_outdated_cells(outdated_cells) + {} + + // Constructor + Move_vertex(const Move_vertex &mv) + : m_mgo(mv.m_mgo), m_helper(mv.m_helper), m_moves(mv.m_moves), + m_moving_vertices(mv.m_moving_vertices), + m_outdated_cells(mv.m_outdated_cells) + {} + + // operator() + void operator()( const tbb::blocked_range& r ) const + { + for( size_t i = r.begin() ; i != r.end() ; ++i) + { + const Vertex_handle& v = cpp11::get<0>(m_moves[i]); + const Point_3& new_position = cpp11::get<1>(m_moves[i]); + // Get size at new position + if ( MGO::Sizing_field::is_vertex_update_needed ) + { + //FT size = sizing_field_(new_position,v); + FT size = cpp11::get<2>(m_moves[i]); + + // Move point + bool could_lock_zone; + Vertex_handle new_v = m_helper.move_point( + v, new_position, m_outdated_cells, m_moving_vertices, &could_lock_zone); + while (could_lock_zone == false) + { + new_v = m_helper.move_point( + v, new_position, m_outdated_cells, m_moving_vertices, &could_lock_zone); + } + + // Restore size in meshing_info data + new_v->set_meshing_info(size); + } + else // Move point + { + bool could_lock_zone; + do { + m_helper.move_point( + v, new_position, m_outdated_cells, m_moving_vertices, &could_lock_zone); + } while (!could_lock_zone); + } + + m_mgo.unlock_all_elements(); + + // Stop if time_limit_ is reached, here we can't return without rebuilding + // restricted delaunay + if ( m_mgo.is_time_limit_reached() ) + { + tbb::task::self().cancel_group_execution(); + break; + } + } + } + }; +#endif // CGAL_LINKED_WITH_TBB + // ----------------------------------- // Private data // ----------------------------------- @@ -197,19 +624,16 @@ Sizing_field sizing_field_; double time_limit_; CGAL::Timer running_time_; - - std::size_t big_moves_size_; - std::set big_moves_; bool do_freeze_; - mutable unsigned int nb_frozen_points_; + mutable Nb_frozen_points_type nb_frozen_points_; #ifdef CGAL_MESH_3_OPTIMIZER_VERBOSE mutable FT sum_moves_; #endif }; - - + + template Mesh_global_optimizer:: Mesh_global_optimizer(C3T3& c3t3, @@ -218,42 +642,45 @@ const bool do_freeze, const FT& convergence_ratio, const Mf move_function) -: c3t3_(c3t3) +: Base(c3t3.bbox(), + Concurrent_mesher_config::get().locking_grid_num_cells_per_axis) +, c3t3_(c3t3) , tr_(c3t3_.triangulation()) , domain_(domain) , sq_freeze_ratio_(freeze_ratio*freeze_ratio) , convergence_ratio_(convergence_ratio) -, helper_(c3t3_,domain_) +, helper_(c3t3_,domain_, get_lock_data_structure()) , move_function_(move_function) , sizing_field_(c3t3.triangulation()) , time_limit_(-1) , running_time_() -, big_moves_size_(0) -, big_moves_() - , do_freeze_(do_freeze) -, nb_frozen_points_(0) #ifdef CGAL_MESH_3_OPTIMIZER_VERBOSE , sum_moves_(0) #endif // CGAL_MESH_3_OPTIMIZER_VERBOSE { + nb_frozen_points_ = 0; // We put it here in case it's an "atomic" + + // If we're multi-thread + tr_.set_lock_data_structure(get_lock_data_structure()); + #ifdef CGAL_MESH_3_OPTIMIZER_VERBOSE std::cerr << "Fill sizing field..."; CGAL::Timer timer; timer.start(); #endif - + fill_sizing_field(); - + #ifdef CGAL_MESH_3_OPTIMIZER_VERBOSE std::cerr << "done (" << timer.time() << "s)\n"; #endif } - + template Mesh_optimization_return_code Mesh_global_optimizer:: @@ -262,6 +689,10 @@ running_time_.reset(); running_time_.start(); +#ifdef CGAL_MESH_3_PROFILING + WallClockTimer t; +#endif + // Fill set containing moving vertices // first, take them all #ifdef CGAL_CONSTRUCT_INTRUSIVE_LIST_RANGE_CONSTRUCTOR @@ -276,15 +707,15 @@ std::size_t initial_vertices_nb = moving_vertices.size(); #ifdef CGAL_MESH_3_OPTIMIZER_VERBOSE double step_begin = running_time_.time(); - std::cerr << "Running " << Mf::name() << "-smoothing (" + std::cerr << "Running " << Mf::name() << "-smoothing (" << initial_vertices_nb << " vertices)" << std::endl; #endif //CGAL_MESH_3_OPTIMIZER_VERBOSE // Initialize big moves (stores the largest moves) - big_moves_.clear(); - big_moves_size_ = + this->clear_big_moves(); + big_moves_size_ = (std::max)(std::size_t(1), std::size_t(moving_vertices.size()/500)); - + std::size_t nb_vertices_moved = -1; bool convergence_stop = false; @@ -292,7 +723,7 @@ int i = -1; while ( ++i < nb_iterations && ! is_time_limit_reached() ) { - if(!do_freeze_) + if(!do_freeze_) nb_frozen_points_ = 0; else nb_vertices_moved = moving_vertices.size(); @@ -303,11 +734,11 @@ //Pb with Freeze : sometimes a few vertices continue moving indefinitely //if the nb of moving vertices is < 1% of total nb AND does not decrease - if(do_freeze_ + if(do_freeze_ && nb_vertices_moved < 0.005 * initial_vertices_nb && nb_vertices_moved == moving_vertices.size()) - { - // we should stop because we are + { + // we should stop because we are // probably entering an infinite instable loop convergence_stop = true; break; @@ -316,13 +747,13 @@ // Stop if time_limit is reached if ( is_time_limit_reached() ) break; - + // Update mesh with those moves update_mesh(moves, moving_vertices, visitor); visitor.end_of_iteration(i); #ifdef CGAL_MESH_3_OPTIMIZER_VERBOSE - std::size_t moving_vertices_size = moving_vertices.size(); + std::size_t moving_vertices_size = moving_vertices.size(); std::cerr << boost::format("\r \r" "end iter.%1%, %2% / %3%, last step:%4$.2fs, step avg:%5$.2fs, avg big moves:%6$.3f ") % (i+1) @@ -340,9 +771,16 @@ if(check_convergence()) break; - } + } running_time_.stop(); - + +#ifdef CGAL_MESH_3_PROFILING + double optim_time = t.elapsed(); +# ifdef CGAL_MESH_3_EXPORT_PERFORMANCE_DATA + CGAL_MESH_3_SET_PERFORMANCE_DATA(std::string(Mf::name()) + "_optim_time", optim_time); +# endif +#endif + #ifdef CGAL_MESH_3_OPTIMIZER_VERBOSE if ( do_freeze_ && nb_frozen_points_ == initial_vertices_nb ) std::cerr << "All vertices frozen" << std::endl; @@ -354,195 +792,179 @@ std::cerr << "Convergence reached" << std::endl; else if( i >= nb_iterations ) std::cerr << "Max iteration number reached" << std::endl; - + std::cerr << "Total optimization time: " << running_time_.time() << "s" << std::endl << std::endl; #endif +#ifdef CGAL_MESH_3_PROFILING + std::cerr << std::endl << "Total optimization 'wall-clock' time: " + << optim_time << "s" << std::endl; +#endif + if ( do_freeze_ && nb_frozen_points_ == initial_vertices_nb ) return ALL_VERTICES_FROZEN; - + else if ( do_freeze_ && convergence_stop ) return CANT_IMPROVE_ANYMORE; - + else if ( is_time_limit_reached() ) return TIME_LIMIT_REACHED; - + else if ( check_convergence() ) return CONVERGENCE_REACHED; - + return MAX_ITERATION_NUMBER_REACHED; } template -void +void Mesh_global_optimizer:: collect_all_vertices(Moving_vertices_set& moving_vertices) { typename Tr::Finite_vertices_iterator vit = tr_.finite_vertices_begin(); for(; vit != tr_.finite_vertices_end(); ++vit ) - moving_vertices.insert(vit); + moving_vertices.insert(vit); } -template -typename Mesh_global_optimizer::Moves_vector -Mesh_global_optimizer:: -compute_moves(Moving_vertices_set& moving_vertices) -{ - typename Gt::Construct_translated_point_3 translate = - Gt().construct_translated_point_3_object(); - - // Store new position of points which have to move - Moves_vector moves; - moves.reserve(moving_vertices.size()); - - // reset worst_move list - big_moves_.clear(); - - // Get move for each moving vertex - typename Moving_vertices_set::iterator vit = moving_vertices.begin(); - for ( ; vit != moving_vertices.end() ; ) - { - Vertex_handle oldv = *vit; - Vector_3 move = compute_move(oldv); - ++vit; - - if ( CGAL::NULL_VECTOR != move ) - { - Point_3 new_position = translate(oldv->point(),move); - // typedef Triangulation_helpers Th; - //if( !Th().inside_protecting_balls(tr_, oldv, new_position)) - //note : this is not happening for Lloyd and ODT so it's commented - // maybe for a new global optimizer it should be de-commented - moves.push_back(std::make_pair(oldv,new_position)); - } - else // CGAL::NULL_VECTOR == move - { - if(do_freeze_) - moving_vertices.erase(oldv); - } - // Stop if time_limit_ is reached - if ( is_time_limit_reached() ) - break; - } - - return moves; -} - - - template typename Mesh_global_optimizer::Vector_3 Mesh_global_optimizer:: compute_move(const Vertex_handle& v) -{ +{ typename Gt::Compute_squared_length_3 sq_length = Gt().compute_squared_length_3_object(); - + typename Gt::Construct_vector_3 vector = Gt().construct_vector_3_object(); - + typename Gt::Construct_translated_point_3 translate = Gt().construct_translated_point_3_object(); Cell_vector incident_cells; incident_cells.reserve(64); - tr_.incident_cells(v, std::back_inserter(incident_cells)); +#ifdef CGAL_LINKED_WITH_TBB + // Parallel + if (boost::is_convertible::value) + { + tr_.incident_cells_threadsafe(v, std::back_inserter(incident_cells)); + } + else +#endif //CGAL_LINKED_WITH_TBB + { + tr_.incident_cells(v, std::back_inserter(incident_cells)); + } // Get move from move function Vector_3 move = move_function_(v, incident_cells, c3t3_, sizing_field_); - + // Project surface vertex if ( c3t3_.in_dimension(v) == 2 ) { Point_3 new_position = translate(v->point(),move); move = vector(v->point(), helper_.project_on_surface(new_position,v)); } - + FT local_sq_size = min_circumradius_sq_length(v, incident_cells); if ( FT(0) == local_sq_size ) return CGAL::NULL_VECTOR; - + FT local_move_sq_ratio = sq_length(move) / local_sq_size; - + // Move point only if displacement is big enough w.r.t local size if ( local_move_sq_ratio < sq_freeze_ratio_ ) { nb_frozen_points_++; return CGAL::NULL_VECTOR; } - + // Update big moves - update_big_moves(local_move_sq_ratio); - + this->update_big_moves(local_move_sq_ratio); + return move; } - - -template -void -Mesh_global_optimizer:: -update_big_moves(const FT& new_sq_move) -{ - if (big_moves_.size() < big_moves_size_ ) - big_moves_.insert(new_sq_move); - else - { - FT smallest = *(big_moves_.begin()); - if( new_sq_move > smallest ) - { - big_moves_.erase(big_moves_.begin()); - big_moves_.insert(new_sq_move); - } - } -} - - + + template void Mesh_global_optimizer:: update_mesh(const Moves_vector& moves, Moving_vertices_set& moving_vertices, Visitor& visitor) -{ +{ // Cells which have to be updated Outdated_cell_set outdated_cells; - - // Apply moves in triangulation - for ( typename Moves_vector::const_iterator it = moves.begin() ; - it != moves.end() ; - ++it ) - { - const Vertex_handle& v = it->first; - const Point_3& new_position = it->second; - // Get size at new position - if ( Sizing_field::is_vertex_update_needed ) - { - FT size = sizing_field_(new_position,v); - - // Move point - Vertex_handle new_v = helper_.move_point(v, new_position, outdated_cells, moving_vertices); - - // Restore size in meshing_info data - new_v->set_meshing_info(size); - } - else // Move point - { - helper_.move_point(v, new_position, outdated_cells, moving_vertices); - } - - // Stop if time_limit_ is reached, here we can't return without rebuilding - // restricted delaunay - if ( is_time_limit_reached() ) - break; + +#ifdef CGAL_MESH_3_PROFILING + std::cerr << "Moving vertices..."; + WallClockTimer t; +#endif + +#ifdef CGAL_LINKED_WITH_TBB + // Parallel + if (boost::is_convertible::value) + { + // Apply moves in triangulation + tbb::parallel_for(tbb::blocked_range(0, moves.size()), + Move_vertex< + Self, C3T3_helpers, Tr, Moves_vector, + Moving_vertices_set, Outdated_cell_set>( + *this, helper_, moves, moving_vertices, outdated_cells) + ); + } + // Sequential + else +#endif // CGAL_LINKED_WITH_TBB + { + // Apply moves in triangulation + for ( typename Moves_vector::const_iterator it = moves.begin() ; + it != moves.end() ; + ++it ) + { + const Vertex_handle& v = cpp11::get<0>(*it); + const Point_3& new_position = cpp11::get<1>(*it); + // Get size at new position + if ( Sizing_field::is_vertex_update_needed ) + { + //FT size = sizing_field_(new_position,v); + FT size = cpp11::get<2>(*it); + + // Move point + Vertex_handle new_v = helper_.move_point(v, new_position, outdated_cells, moving_vertices); + + // Restore size in meshing_info data + new_v->set_meshing_info(size); + } + else // Move point + { + helper_.move_point(v, new_position, outdated_cells, moving_vertices); + } + + // Stop if time_limit_ is reached, here we can't return without rebuilding + // restricted delaunay + if ( is_time_limit_reached() ) + break; + } } + + visitor.after_move_points(); - + +#ifdef CGAL_MESH_3_PROFILING + std::cerr << "done in " << t.elapsed() << " seconds." << std::endl; +#endif + + +#ifdef CGAL_MESH_3_PROFILING + std::cerr << "Updating C3T3 (rebuilding restricted Delaunay)..."; + t.reset(); +#endif + // Update c3t3 #ifdef CGAL_INTRUSIVE_LIST // AF: rebuild_restricted_delaunay does more cell insertion/removal - // which clashes with our inplace list + // which clashes with our inplace list // That's why we hand it in, and call clear() when we no longer need it helper_.rebuild_restricted_delaunay(outdated_cells, moving_vertices); @@ -550,9 +972,14 @@ helper_.rebuild_restricted_delaunay(outdated_cells.begin(), outdated_cells.end(), moving_vertices); -#endif - +#endif + visitor.after_rebuild_restricted_delaunay(); + +#ifdef CGAL_MESH_3_PROFILING + std::cerr << "Updating C3T3 done in " << t.elapsed() << " seconds." << std::endl; +#endif + } @@ -562,45 +989,69 @@ fill_sizing_field() { std::map value_map; - - // Fill map with local size - for(typename Tr::Finite_vertices_iterator vit = tr_.finite_vertices_begin(); - vit != tr_.finite_vertices_end(); - ++vit) + +#ifdef CGAL_LINKED_WITH_TBB + // Parallel + if (boost::is_convertible::value) { - value_map.insert(std::make_pair(vit->point(), - average_circumradius_length(vit))); + typedef tbb::enumerable_thread_specific< + std::vector< std::pair > > Local_list; + Local_list local_lists; + + tbb::parallel_do( + tr_.finite_vertices_begin(), tr_.finite_vertices_end(), + Compute_sizing_field_value(*this, local_lists) + ); + + for(typename Local_list::iterator it_list = local_lists.begin() ; + it_list != local_lists.end() ; + ++it_list ) + { + value_map.insert(it_list->begin(), it_list->end()); + } } - + else +#endif //CGAL_LINKED_WITH_TBB + { + // Fill map with local size + for(typename Tr::Finite_vertices_iterator vit = tr_.finite_vertices_begin(); + vit != tr_.finite_vertices_end(); + ++vit) + { + value_map.insert(std::make_pair(vit->point(), + average_circumradius_length(vit))); + } + } + // fill sizing field sizing_field_.fill(value_map); } - + template bool Mesh_global_optimizer:: check_convergence() const { namespace bl = boost::lambda; - + FT sum(0); - for( typename std::set::const_iterator + for( typename std::multiset::const_iterator it = big_moves_.begin(), end = big_moves_.end() ; it != end ; ++it ) { sum += CGAL::sqrt(*it); } - + FT average_move = sum/big_moves_size_;/*even if set is not full, divide*/ /*by max size so that if only 1 point moves, it goes to 0*/ #ifdef CGAL_MESH_3_OPTIMIZER_VERBOSE sum_moves_ = average_move; #endif - + return ( average_move < convergence_ratio_ ); } - - + + template typename Mesh_global_optimizer::FT Mesh_global_optimizer:: @@ -608,11 +1059,21 @@ { Cell_vector incident_cells; incident_cells.reserve(64); - tr_.incident_cells(v, std::back_inserter(incident_cells)); - +#ifdef CGAL_LINKED_WITH_TBB + // Parallel + if (boost::is_convertible::value) + { + tr_.incident_cells_threadsafe(v, std::back_inserter(incident_cells)); + } + else +#endif //CGAL_LINKED_WITH_TBB + { + tr_.incident_cells(v, std::back_inserter(incident_cells)); + } + FT sum_len (0); unsigned int nb = 0; - + for ( typename Cell_vector::iterator cit = incident_cells.begin() ; cit != incident_cells.end() ; ++cit) @@ -623,7 +1084,7 @@ ++nb; } } - + // nb == 0 could happen if there is an isolated point. if ( 0 != nb ) { @@ -649,32 +1110,32 @@ } } - + template typename Mesh_global_optimizer::FT Mesh_global_optimizer:: min_circumradius_sq_length(const Vertex_handle& v, const Cell_vector& incident_cells) const { - // Get first cell sq_circumradius_length + // Get first cell sq_circumradius_length typename Cell_vector::const_iterator cit = incident_cells.begin(); while ( incident_cells.end() != cit && !c3t3_.is_in_complex(*cit) ) { ++cit; } - + // if vertex is isolated ... if ( incident_cells.end() == cit ) return FT(0); - + // Initialize min FT min_sq_len = sq_circumradius_length(*cit++,v); - + // Find the minimum value for ( ; cit != incident_cells.end() ; ++cit ) { if ( !c3t3_.is_in_complex(*cit) ) continue; - + min_sq_len = (std::min)(min_sq_len,sq_circumradius_length(*cit,v)); } - + return min_sq_len; } @@ -686,11 +1147,11 @@ { typename Gt::Compute_squared_distance_3 sq_distance = Gt().compute_squared_distance_3_object(); - + const Point_3 circumcenter = tr_.dual(cell); return ( sq_distance(v->point(), circumcenter) ); } - + } // end namespace Mesh_3 } //namespace CGAL diff -Nru cgal-4.4/include/CGAL/Mesh_3/Mesh_sizing_field.h cgal-4.5/include/CGAL/Mesh_3/Mesh_sizing_field.h --- cgal-4.4/include/CGAL/Mesh_3/Mesh_sizing_field.h 2013-07-06 19:00:27.000000000 +0000 +++ cgal-4.5/include/CGAL/Mesh_3/Mesh_sizing_field.h 2014-08-29 13:58:16.000000000 +0000 @@ -26,16 +26,70 @@ #ifndef CGAL_MESH_3_MESH_SIZING_FIELD_H #define CGAL_MESH_3_MESH_SIZING_FIELD_H +#ifdef CGAL_LINKED_WITH_TBB +# include +#endif + namespace CGAL { namespace Mesh_3 { - + +/** + * @class Mesh_sizing_field_base + */ +// Sequential +template +class Mesh_sizing_field_base +{ +protected: + Cell_handle get_last_cell() const + { + return last_cell_; + } + + void set_last_cell(Cell_handle c) const + { + last_cell_ = c; + } + +private: + /// A cell that is used to accelerate location queries + mutable Cell_handle last_cell_; +}; + +#ifdef CGAL_LINKED_WITH_TBB +/** + * @class Mesh_sizing_field_base specialization + */ +// Parallel +template +class Mesh_sizing_field_base +{ +protected: + Cell_handle get_last_cell() const + { + return last_cell_.local(); + } + + void set_last_cell(Cell_handle c) const + { + last_cell_.local() = c; + } + +private: + /// A cell that is used to accelerate location queries + mutable tbb::enumerable_thread_specific last_cell_; +}; +#endif // CGAL_LINKED_WITH_TBB + /** * @class Mesh_sizing_field */ template class Mesh_sizing_field + : public Mesh_sizing_field_base { // Types typedef typename Tr::Geom_traits Gt; @@ -44,91 +98,88 @@ typedef typename Tr::Vertex_handle Vertex_handle; typedef typename Tr::Cell_handle Cell_handle; - + public: - // update vertices of mesh triangulation ? + // update vertices of mesh triangulation ? static const bool is_vertex_update_needed = Need_vertex_update; - + public: /** * Constructor */ Mesh_sizing_field(Tr& tr); - + /** * Fill sizing field, using size associated to point in \c value_map */ void fill(const std::map& value_map); - + /** * Returns size at point \c p. */ FT operator()(const Point_3& p) const - { return this->operator()(p,last_cell_); } - + { return this->operator()(p, this->get_last_cell()); } + /** * Returns size at point \c p, using \c v to accelerate \c p location * in triangulation */ FT operator()(const Point_3& p, const Vertex_handle& v) const { return this->operator()(p,v->cell()); } - + /** * Returns size at point \c p. */ FT operator()(const Point_3& p, const Cell_handle& c) const; - + /** * Returns size at point \c p. Assumes that p is the centroid of c. */ FT operator()(const Point_3& p, const std::pair& c) const; - + private: /** * Returns size at point \c p, by interpolation into tetrahedron. */ FT interpolate_on_cell_vertices(const Point_3& p, const Cell_handle& cell) const; - + /** * Returns size at point \c p, by interpolation into facet (\c cell is assumed * to be an infinite cell). */ FT interpolate_on_facet_vertices(const Point_3& p, const Cell_handle& cell) const; - + private: /// The triangulation Tr& tr_; - /// A cell that is used to accelerate location queries - mutable Cell_handle last_cell_; }; - - - + + + template Mesh_sizing_field:: Mesh_sizing_field(Tr& tr) : tr_(tr) - , last_cell_() { -} - - +} + + template void Mesh_sizing_field:: fill(const std::map& value_map) { typedef typename Tr::Finite_vertices_iterator Fvi; - + for ( Fvi vit = tr_.finite_vertices_begin() ; vit != tr_.finite_vertices_end() ; ++ vit ) { - typename std::map::const_iterator find_result = + typename std::map::const_iterator find_result = value_map.find(vit->point()); - + if ( find_result != value_map.end() ) { vit->set_meshing_info(find_result->second); @@ -139,14 +190,14 @@ vit->set_meshing_info(FT(0)); } } -} +} template typename Mesh_sizing_field::FT Mesh_sizing_field:: -operator()(const Point_3& p, const Cell_handle& c) const -{ -#ifdef CGAL_MESH_3_SIZING_FIELD_INEXACT_LOCATE +operator()(const Point_3& p, const Cell_handle& c) const +{ +#ifdef CGAL_MESH_3_SIZING_FIELD_INEXACT_LOCATE //use the inexact locate (much faster than locate) to get a hint //and then use locate to check whether p is really inside hint // if not, an exact locate will be performed @@ -155,8 +206,8 @@ #else const Cell_handle cell = tr_.locate(p,c); #endif - last_cell_ = cell; - + this->set_last_cell(cell); + if ( !tr_.is_infinite(cell) ) return interpolate_on_cell_vertices(p,cell); else @@ -171,17 +222,17 @@ { // Assumes that p is the centroid of c const Cell_handle& cell = c.first; - + // Interpolate value using tet vertices values const FT& va = cell->vertex(0)->meshing_info(); const FT& vb = cell->vertex(1)->meshing_info(); const FT& vc = cell->vertex(2)->meshing_info(); const FT& vd = cell->vertex(3)->meshing_info(); - + return ( (va+vb+vc+vd)/4 ); } - + template typename Mesh_sizing_field::FT Mesh_sizing_field:: @@ -189,32 +240,32 @@ { typename Gt::Compute_volume_3 volume = Gt().compute_volume_3_object(); - + // Interpolate value using tet vertices values const FT& va = cell->vertex(0)->meshing_info(); const FT& vb = cell->vertex(1)->meshing_info(); const FT& vc = cell->vertex(2)->meshing_info(); const FT& vd = cell->vertex(3)->meshing_info(); - + const Point_3& a = cell->vertex(0)->point(); const Point_3& b = cell->vertex(1)->point(); const Point_3& c = cell->vertex(2)->point(); const Point_3& d = cell->vertex(3)->point(); - + const FT abcp = CGAL::abs(volume(a,b,c,p)); const FT abdp = CGAL::abs(volume(a,d,b,p)); const FT acdp = CGAL::abs(volume(a,c,d,p)); const FT bcdp = CGAL::abs(volume(b,d,c,p)); - + // If volume is 0, then compute the average value if ( is_zero(abcp+abdp+acdp+bcdp) ) return (va+vb+vc+vd)/4.; - + return ( (abcp*vd + abdp*vc + acdp*vb + bcdp*va) / (abcp+abdp+acdp+bcdp) ); } - - - + + + template typename Mesh_sizing_field::FT Mesh_sizing_field:: @@ -222,44 +273,44 @@ { typename Gt::Compute_area_3 area = Gt().compute_area_3_object(); - + // Find infinite vertex and put it in k0 int k0 = 0; int k1 = 1; int k2 = 2; int k3 = 3; - + if ( tr_.is_infinite(cell->vertex(1)) ) std::swap(k0,k1); if ( tr_.is_infinite(cell->vertex(2)) ) std::swap(k0,k2); if ( tr_.is_infinite(cell->vertex(3)) ) std::swap(k0,k3); - + // Interpolate value using tet vertices values const FT& va = cell->vertex(k1)->meshing_info(); const FT& vb = cell->vertex(k2)->meshing_info(); const FT& vc = cell->vertex(k3)->meshing_info(); - + const Point_3& a = cell->vertex(k1)->point(); const Point_3& b = cell->vertex(k2)->point(); const Point_3& c = cell->vertex(k3)->point(); - + const FT abp = area(a,b,p); const FT acp = area(a,c,p); const FT bcp = area(b,c,p); - + CGAL_assertion(abp >= 0); CGAL_assertion(acp >= 0); CGAL_assertion(bcp >= 0); - + // If area is 0, then compute the average value if ( is_zero(abp+acp+bcp) ) return (va+vb+vc)/3.; - + return ( (abp*vc + acp*vb + bcp*va ) / (abp+acp+bcp) ); } - + } // end namespace Mesh_3 diff -Nru cgal-4.4/include/CGAL/Mesh_3/mesh_standard_cell_criteria.h cgal-4.5/include/CGAL/Mesh_3/mesh_standard_cell_criteria.h --- cgal-4.4/include/CGAL/Mesh_3/mesh_standard_cell_criteria.h 2013-07-06 19:00:27.000000000 +0000 +++ cgal-4.5/include/CGAL/Mesh_3/mesh_standard_cell_criteria.h 2014-08-29 13:58:16.000000000 +0000 @@ -239,7 +239,7 @@ Radius sq_radius = Geom_traits().compute_squared_radius_3_object(); const FT size = sq_radius(p, q, r, s); - const FT sq_bound = CGAL::square( size_(ch->circumcenter(), + const FT sq_bound = CGAL::square( size_(ch->weighted_circumcenter(), 3, Index(ch->subdomain_index())) ); diff -Nru cgal-4.4/include/CGAL/Mesh_3/Mesh_surface_cell_base_3.h cgal-4.5/include/CGAL/Mesh_3/Mesh_surface_cell_base_3.h --- cgal-4.4/include/CGAL/Mesh_3/Mesh_surface_cell_base_3.h 2013-07-06 19:00:27.000000000 +0000 +++ cgal-4.5/include/CGAL/Mesh_3/Mesh_surface_cell_base_3.h 2014-08-29 13:58:16.000000000 +0000 @@ -31,6 +31,10 @@ #include #include +#ifdef CGAL_LINKED_WITH_TBB +# include +#endif + #ifdef _MSC_VER // Kill warning "C4351: new behavior: elements of array // 'CGAL::Mesh_3::Mesh_surface_cell_base_3::surface_index_table_' @@ -42,15 +46,103 @@ namespace Mesh_3 { + +/************************************************ +// Class Mesh_surface_cell_base_3_base +// Two versions: sequential / parallel +************************************************/ + +// Sequential +template +class Mesh_surface_cell_base_3_base +{ +public: + Mesh_surface_cell_base_3_base() + : bits_(0) {} + + /// Marks \c facet as visited + void set_facet_visited (const int facet) + { + CGAL_precondition(facet>=0 && facet <4); + bits_ |= (1 << facet); + } + + /// Marks \c facet as not visited + void reset_visited (const int facet) + { + CGAL_precondition(facet>=0 && facet<4); + bits_ &= (15 & ~(1 << facet)); + } + + /// Returns \c true if \c facet is marked as visited + bool is_facet_visited (const int facet) const + { + CGAL_precondition(facet>=0 && facet<4); + return ( (bits_ & (1 << facet)) != 0 ); + } + +protected: + /// Stores visited facets (4 first bits) + char bits_; +}; + +#ifdef CGAL_LINKED_WITH_TBB +// Parallel +template<> +class Mesh_surface_cell_base_3_base +{ +public: + Mesh_surface_cell_base_3_base() + { + bits_ = 0; + } + + /// Marks \c facet as visited + void set_facet_visited (const int facet) + { + CGAL_precondition(facet>=0 && facet<4); + char current_bits = bits_; + while (bits_.compare_and_swap(current_bits | (1 << facet), current_bits) != current_bits) + { + current_bits = bits_; + } + } + + /// Marks \c facet as not visited + void reset_visited (const int facet) + { + CGAL_precondition(facet>=0 && facet<4); + char current_bits = bits_; + while (bits_.compare_and_swap(current_bits & (15 & ~(1 << facet)), current_bits) != current_bits) + { + current_bits = bits_; + } + } + + /// Returns \c true if \c facet is marked as visited + bool is_facet_visited (const int facet) const + { + CGAL_precondition(facet>=0 && facet<4); + return ( (bits_ & (1 << facet)) != 0 ); + } + +protected: + /// Stores visited facets (4 first bits) + tbb::atomic bits_; +}; +#endif // CGAL_LINKED_WITH_TBB + /** * @class Mesh_surface_cell_base_3 */ template > + class Cb> class Mesh_surface_cell_base_3 -: public Cb +: public Mesh_surface_cell_base_3_base< + typename Cb::Triangulation_data_structure::Concurrency_tag> +, public Cb { public: // Indices @@ -62,7 +154,7 @@ typedef typename Tds::Vertex_handle Vertex_handle; typedef typename Tds::Cell_handle Cell_handle; typedef typename GT::Point_3 Point; - + // To get correct cell type in TDS template < class TDS3 > struct Rebind_TDS @@ -76,14 +168,14 @@ : Cb() , surface_index_table_() , surface_center_table_() - , bits_(0) { } + { } Mesh_surface_cell_base_3(Vertex_handle v0, Vertex_handle v1, Vertex_handle v2, Vertex_handle v3) : Cb (v0, v1, v2, v3) , surface_index_table_() , surface_center_table_() - , bits_(0) { } + { } Mesh_surface_cell_base_3(Vertex_handle v0, Vertex_handle v1, Vertex_handle v2, Vertex_handle v3, @@ -92,7 +184,7 @@ : Cb (v0, v1, v2, v3, n0, n1, n2, n3) , surface_index_table_() , surface_center_table_() - , bits_(0) { } + { } /// Destructor @@ -114,27 +206,6 @@ return surface_index_table_[facet]; } - /// Marks \c facet as visited - void set_facet_visited (const int facet) - { - CGAL_precondition(facet>=0 && facet <4); - bits_ |= (1 << facet); - } - - /// Marks \c facet as not visited - void reset_visited (const int facet) - { - CGAL_precondition(facet>=0 && facet<4); - bits_ &= (15 & ~(1 << facet)); - } - - /// Returns \c true if \c facet is marked as visited - bool is_facet_visited (const int facet) const - { - CGAL_precondition(facet>=0 && facet<4); - return ( (bits_ & (1 << facet)) != 0 ); - } - /// Sets surface center of \c facet to \c point void set_facet_surface_center(const int facet, const Point& point) { @@ -201,8 +272,6 @@ Point surface_center_table_[4]; /// Stores surface center index of each facet of the cell Index surface_center_index_table_[4]; - /// Stores visited facets (4 first bits) - char bits_; }; // end class Mesh_surface_cell_base_3 diff -Nru cgal-4.4/include/CGAL/Mesh_3/Odt_move.h cgal-4.5/include/CGAL/Mesh_3/Odt_move.h --- cgal-4.4/include/CGAL/Mesh_3/Odt_move.h 2013-07-06 19:00:27.000000000 +0000 +++ cgal-4.5/include/CGAL/Mesh_3/Odt_move.h 2014-08-29 13:58:16.000000000 +0000 @@ -113,8 +113,8 @@ return CGAL::NULL_VECTOR; } - -#ifdef CGAL_MESH_3_OPTIMIZER_VERBOSE +#if defined(CGAL_MESH_3_OPTIMIZER_VERBOSE) \ + || defined (CGAL_MESH_3_EXPORT_PERFORMANCE_DATA) static std::string name() { return std::string("Odt"); } #endif diff -Nru cgal-4.4/include/CGAL/Mesh_3/Profiling_tools.h cgal-4.5/include/CGAL/Mesh_3/Profiling_tools.h --- cgal-4.4/include/CGAL/Mesh_3/Profiling_tools.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/Mesh_3/Profiling_tools.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,69 @@ +// Copyright (c) 2012 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Clement Jamin +// +//****************************************************************************** +// File Description : +//****************************************************************************** + +#ifndef CGAL_MESH_3_PROFILING_TOOLS_H +#define CGAL_MESH_3_PROFILING_TOOLS_H + +// TBB timers +#ifdef CGAL_LINKED_WITH_TBB + #include + struct WallClockTimer + { + tbb::tick_count t; + WallClockTimer() + { + t = tbb::tick_count::now(); + } + void reset() + { + t = tbb::tick_count::now(); + } + double elapsed() const + { + return (tbb::tick_count::now() - t).seconds(); + } + }; + +#else + #include + + struct WallClockTimer + { + CGAL::Real_timer t; + WallClockTimer() + { + t.start(); + } + void reset() + { + t.reset(); + } + double elapsed() const + { + return t.time(); + } + }; +#endif + +#endif // CGAL_MESH_3_PROFILING_TOOLS_H diff -Nru cgal-4.4/include/CGAL/Mesh_3/Protect_edges_sizing_field.h cgal-4.5/include/CGAL/Mesh_3/Protect_edges_sizing_field.h --- cgal-4.4/include/CGAL/Mesh_3/Protect_edges_sizing_field.h 2013-09-21 19:00:24.000000000 +0000 +++ cgal-4.5/include/CGAL/Mesh_3/Protect_edges_sizing_field.h 2014-10-06 19:00:05.000000000 +0000 @@ -33,6 +33,7 @@ #ifndef CGAL_NO_ASSERTIONS # include // for float_prior #endif +#include namespace CGAL { namespace Mesh_3 { @@ -918,6 +919,9 @@ std::cerr << "Number of to-be-inserted balls is: " << n << "\n between points (" << vp->point() << ") and (" << vq->point() + << ") (geodesic distance: " + << domain_.geodesic_distance(vp->point(), vq->point(), + curve_index) << ")\n"; #endif const Bare_point new_point = @@ -1191,13 +1195,15 @@ c3t3_.remove_from_complex(v); } + unchecked_vertices_.erase(v); // Change v size c3t3_.triangulation().remove(v); CGAL_assertion_code(Tr& tr = c3t3_.triangulation()); CGAL_assertion_code(Cell_handle ch = tr.locate(p)); CGAL_assertion_code(std::vector hidden_vertices); - CGAL_assertion_code(tr.vertices_inside_conflict_zone(Weighted_point(p, w), + CGAL_assertion_code(if(tr.dimension() > 1) + tr.vertices_inside_conflict_zone(Weighted_point(p, w), ch, std::back_inserter(hidden_vertices))); @@ -1231,11 +1237,25 @@ } // Update unchecked vertices - unchecked_vertices_.erase(v); unchecked_vertices_.insert(new_v); return new_v; } +namespace details { + + // Functor used by Protect_edges_sizing_field::check_and_repopulate_edges, below + template + class Erase_element_from_set { + Set* set_ptr; + public: + Erase_element_from_set(Set& set) : set_ptr(&set) {} + + void operator()(const typename Set::key_type& x) + { + set_ptr->erase(x); + } + }; // end class Erase_element_from_set +} // end namespace details template void @@ -1245,7 +1265,8 @@ #ifdef CGAL_MESH_3_PROTECTION_DEBUG std::cerr << "check_and_repopulate_edges()\n"; #endif - std::set vertices; + typedef std::set Vertices; + Vertices vertices; std::copy( unchecked_vertices_.begin(), unchecked_vertices_.end(), std::inserter(vertices,vertices.begin()) ); @@ -1256,15 +1277,11 @@ { Vertex_handle v = *vertices.begin(); vertices.erase(vertices.begin()); - - Vertex_vector erased_vertices; - check_and_fix_vertex_along_edge(v, std::back_inserter(erased_vertices)); - - for ( typename Vertex_vector::iterator vit = erased_vertices.begin(), - vend = erased_vertices.end() ; vit != vend ; ++vit ) - { - vertices.erase(*vit); - } + + details::Erase_element_from_set erase_from_vertices(vertices); + + check_and_fix_vertex_along_edge(v, + boost::make_function_output_iterator(erase_from_vertices)); } } diff -Nru cgal-4.4/include/CGAL/Mesh_3/Refine_cells_3.h cgal-4.5/include/CGAL/Mesh_3/Refine_cells_3.h --- cgal-4.4/include/CGAL/Mesh_3/Refine_cells_3.h 2013-07-06 19:00:27.000000000 +0000 +++ cgal-4.5/include/CGAL/Mesh_3/Refine_cells_3.h 2014-08-29 13:58:16.000000000 +0000 @@ -14,9 +14,8 @@ // // $URL$ // $Id$ -// // -// Author(s) : Laurent Rineau, Stéphane Tayeb +// Author(s) : Laurent Rineau, Stéphane Tayeb #ifndef CGAL_MESH_3_REFINE_CELLS_3_H #define CGAL_MESH_3_REFINE_CELLS_3_H @@ -24,18 +23,30 @@ #include #include -#include -#include +#include +#include #include +#ifdef CGAL_LINKED_WITH_TBB + #include +#endif + +#include +#include #include +#ifdef CGAL_MESH_3_PROFILING + #include +#endif + #include #include +#include +#include #include namespace CGAL { - + namespace Mesh_3 { // Helper meta-programming functions, to allow backward compatibility. @@ -52,7 +63,7 @@ BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_Cell_badness, Cell_badness, false) // template class, used when use_cell_badness = false -template ::value) && Has_Cell_badness::value > struct Get_Is_cell_bad { @@ -67,8 +78,116 @@ typedef Type type; }; +// Predicate to know if a cell in a refinement queue is a zombie +template +class Cell_to_refine_is_not_zombie +{ +public: + Cell_to_refine_is_not_zombie() {} + + bool operator()(const CC_safe_handle &c) const + { + return !c.is_zombie(); + } +}; + +/************************************************ +// Class Refine_cells_3_base +// Two versions: sequential / parallel +************************************************/ + +// Sequential +template +class Refine_cells_3_base +{ +protected: + Refine_cells_3_base() : m_last_vertex_index() {} + + Index get_last_vertex_index() const + { + return m_last_vertex_index; + } + + void set_last_vertex_index(Index i) const + { + m_last_vertex_index = i; + } + +#if defined(CGAL_MESH_3_USE_LAZY_SORTED_REFINEMENT_QUEUE) \ + || defined(CGAL_MESH_3_USE_LAZY_UNSORTED_REFINEMENT_QUEUE) + CC_safe_handle + from_cell_to_refinement_queue_element(Cell_handle ch) const + { + return make_cc_safe_handle(ch); + } + +public: + template + Cell_handle extract_element_from_container_value(const Container_element &e) const + { + // We get the Cell_handle from the safe handle + return e.cc_iterator(); + } + +#else + Cell_handle + from_cell_to_refinement_queue_element(Cell_handle ch) const + { + return ch; + } +public: + template + Cell_handle extract_element_from_container_value(const Container_element &e) const + { + return e; + } +#endif +protected: + /// Stores index of vertex that may be inserted into triangulation + mutable Index m_last_vertex_index; +}; + +#ifdef CGAL_LINKED_WITH_TBB +// Parallel +template +class Refine_cells_3_base +{ +protected: + Refine_cells_3_base() : m_last_vertex_index(Index()) {} + + Index get_last_vertex_index() const + { + return m_last_vertex_index.local(); + } + + void set_last_vertex_index(Index i) const + { + m_last_vertex_index.local() = i; + } + + CC_safe_handle + from_cell_to_refinement_queue_element(Cell_handle ch) const + { + return make_cc_safe_handle(ch); + } + +public: + template + Cell_handle extract_element_from_container_value(const Container_element &e) const + { + // We get the Cell_handle from the safe handle + return e.cc_iterator(); + } + +protected: + /// Stores index of vertex that may be inserted into triangulation + mutable tbb::enumerable_thread_specific m_last_vertex_index; +}; +#endif // CGAL_LINKED_WITH_TBB + +/************************************************ // Class Refine_cells_3 // // Template parameters should be models of @@ -77,46 +196,141 @@ // MeshDomain : MeshTraits_3 // // Implements a Mesher_level for cells +************************************************/ + template > + class Concurrency_tag, +#ifdef CGAL_LINKED_WITH_TBB + class Container_ = typename boost::mpl::if_c // (parallel/sequential?) + < + boost::is_convertible::value, + + // Parallel +# ifdef CGAL_MESH_3_USE_LAZY_UNSORTED_REFINEMENT_QUEUE + Meshes::Filtered_deque_container +# else + Meshes::Filtered_multimap_container +# endif + < + CC_safe_handle, + typename Criteria::Cell_quality, + Cell_to_refine_is_not_zombie, + Concurrency_tag + >, + // Sequential +# ifdef CGAL_MESH_3_USE_LAZY_UNSORTED_REFINEMENT_QUEUE + Meshes::Filtered_deque_container + < + CC_safe_handle, + typename Criteria::Cell_quality, + Cell_to_refine_is_not_zombie, + Concurrency_tag + > +# elif defined(CGAL_MESH_3_USE_LAZY_SORTED_REFINEMENT_QUEUE) + Meshes::Filtered_multimap_container + < + CC_safe_handle, + typename Criteria::Cell_quality, + Cell_to_refine_is_not_zombie, + Concurrency_tag + > +# else + Meshes::Double_map_container +# endif + >::type // boost::if (parallel/sequential) + +#else // !CGAL_LINKED_WITH_TBB + + // Sequential + class Container_ = +# ifdef CGAL_MESH_3_USE_LAZY_UNSORTED_REFINEMENT_QUEUE + Meshes::Filtered_deque_container + < + CC_safe_handle, + typename Criteria::Cell_quality, + Cell_to_refine_is_not_zombie, + Concurrency_tag + > +# elif defined(CGAL_MESH_3_USE_LAZY_SORTED_REFINEMENT_QUEUE) + Meshes::Filtered_multimap_container + < + CC_safe_handle, + typename Criteria::Cell_quality, + Cell_to_refine_is_not_zombie, + Concurrency_tag + > +# else + Meshes::Double_map_container +# endif + +#endif // CGAL_LINKED_WITH_TBB +> class Refine_cells_3 - : public Mesher_level, - typename Tr::Cell_handle, - Previous_, - Triangulation_mesher_level_traits_3 > - , public Container_ - , public No_test_point_conflict - , public No_after_no_insertion - , public No_before_conflicts +: public Refine_cells_3_base +, public Mesher_level, + typename Tr::Cell_handle, + Previous_, + Triangulation_mesher_level_traits_3, + Concurrency_tag> +, public Container_ +, public No_test_point_conflict +, public No_after_no_insertion +, public No_before_conflicts { private: // Internal types typedef typename Tr::Facet Facet; + typedef typename Tr::Lock_data_structure Lock_data_structure; typedef typename MeshDomain::Subdomain_index Subdomain_index; typedef typename MeshDomain::Index Index; typedef typename Get_Is_cell_bad::Type Is_cell_bad; - + // Self typedef Refine_cells_3 Self; - -public: + Criteria, + MeshDomain, + Complex3InTriangulation3, + Previous_, + Concurrency_tag, + Container_> Self; + + typedef Refine_cells_3_base Base; + + typedef Mesher_level, + typename Tr::Cell_handle, + Previous_, + Triangulation_mesher_level_traits_3, + Concurrency_tag> Base_ML; + +public: + using Base_ML::add_to_TLS_lists; + using Base_ML::splice_local_lists; + + typedef Container_ Container; // Because we need it in Mesher_level + typedef typename Container::Element Container_element; typedef typename Tr::Point Point; typedef typename Tr::Cell Cell; typedef typename Tr::Cell_handle Cell_handle; @@ -124,44 +338,81 @@ typedef typename Criteria::Cell_quality Cell_quality; typedef typename Triangulation_mesher_level_traits_3::Zone Zone; typedef Complex3InTriangulation3 C3T3; - - + + // Constructor + // For sequential Refine_cells_3(Tr& triangulation, const Criteria& criteria, const MeshDomain& oracle, Previous_& previous, - C3T3& c3t3) ; - + C3T3& c3t3); + // For parallel + Refine_cells_3(Tr& triangulation, + const Criteria& criteria, + const MeshDomain& oracle, + Previous_& previous, + C3T3& c3t3, + Lock_data_structure *lock_ds, + WorksharingDataStructureType *worksharing_ds); + // Destructor virtual ~Refine_cells_3() { } - + // Get a reference on triangulation Tr& triangulation_ref_impl() { return r_tr_; } const Tr& triangulation_ref_impl() const { return r_tr_; } - + // Initialization function void scan_triangulation_impl(); - + + int number_of_bad_elements_impl(); + + Point circumcenter_impl(const Cell_handle& cell) const + { + return r_tr_.dual(cell); + } + + template + void before_next_element_refinement_in_superior_impl(Mesh_visitor) + { + } + + void before_next_element_refinement_impl() + { + } + + Cell_handle get_next_element_impl() + { + return this->extract_element_from_container_value(Container_::get_next_element_impl()); + } + // Gets the point to insert from the element to refine Point refinement_point_impl(const Cell_handle& cell) const { - last_vertex_index_ = r_oracle_.index_from_subdomain_index( - cell->subdomain_index()); + this->set_last_vertex_index( + r_oracle_.index_from_subdomain_index(cell->subdomain_index()) ); + // last_vertex_index_ = Index(cell->subdomain_index()); // NB : dual() is optimized when the cell base class has circumcenter() return r_tr_.dual(cell); } - + // Returns the conflicts zone - Zone conflicts_zone_impl(const Point& point, const Cell_handle& cell) const; - + Zone conflicts_zone_impl(const Point& point + , const Cell_handle& cell + , bool &facet_is_in_its_cz) const; + Zone conflicts_zone_impl(const Point& point + , const Cell_handle& cell + , bool &facet_is_in_its_cz + , bool &could_lock_zone) const; + // Job to do before insertion void before_insertion_impl(const Cell_handle&, const Point&, Zone& zone) { before_insertion_handle_cells_in_conflict_zone(zone); } - + // Job to do after insertion void after_insertion_impl(const Vertex_handle& v) #ifndef CGAL_MESH_3_USE_OLD_SURFACE_RESTRICTED_DELAUNAY_UPDATE @@ -172,54 +423,128 @@ // Insertion implementation ; returns the inserted vertex Vertex_handle insert_impl(const Point& p, const Zone& zone); - + // Updates cells incident to vertex, and add them to queue if needed void update_star(const Vertex_handle& vertex); - + + // Sequential + void remove_element_from_refinement_queue(Cell_handle c, Sequential_tag) + { + // If sequential AND NOT lazy, remove cell from refinement queue + #if !defined(CGAL_MESH_3_USE_LAZY_SORTED_REFINEMENT_QUEUE) \ + && !defined(CGAL_MESH_3_USE_LAZY_UNSORTED_REFINEMENT_QUEUE) + this->remove_element(c); + #endif + } + // Parallel: it's always lazy, so do nothing + void remove_element_from_refinement_queue(Cell_handle, Parallel_tag) {} + /// Handle cells contained in \c zone (before their destruction by insertion) void before_insertion_handle_cells_in_conflict_zone(Zone& zone); - + + bool try_lock_element(const Cell_handle &ch, int lock_radius = 0) const + { + return this->triangulation().try_lock_cell(ch, lock_radius); + } + + /// debug info: class name + std::string debug_info_class_name_impl() const + { + return "Refine_cells_3"; + } + std::string debug_info() const { std::stringstream s; s << this->previous().debug_info() << "," << this->size(); return s.str(); } - + std::string debug_info_header() const { std::stringstream s; s << this->previous().debug_info_header() << "," << "#tets to refine"; return s.str(); } + + std::string debug_info_element_impl(const Cell_handle &ch) const + { + std::stringstream sstr; + sstr << "Cell { " << std::endl + << " - " << *ch->vertex(0) << std::endl + << " - " << *ch->vertex(1) << std::endl + << " - " << *ch->vertex(2) << std::endl + << " - " << *ch->vertex(3) << std::endl + << "}" << std::endl; + + return sstr.str(); + } + /// Adds \c cell to the refinement queue if needed + void treat_new_cell(const Cell_handle& cell); + #ifdef CGAL_MESH_3_MESHER_STATUS_ACTIVATED std::size_t queue_size() const { return this->size(); } #endif - + private: - /// Adds \c cell to the refinement queue if needed - void treat_new_cell(const Cell_handle& cell); + +#ifdef CGAL_LINKED_WITH_TBB + // Functor for scan_triangulation_impl function + template + class Scan_cell + { + Refine_cells_ & m_refine_cells; + const std::vector & m_cells; + + public: + // Constructor + Scan_cell(Refine_cells_ & rc, + const std::vector & cells) + : m_refine_cells(rc), m_cells(cells) + {} + + // Constructor + Scan_cell(const Scan_cell &sc) + : m_refine_cells(sc.m_refine_cells), m_cells(sc.m_cells) + {} + + // operator() + void operator()( const tbb::blocked_range& r ) const + { + for( size_t i = r.begin() ; i != r.end() ; ++i) + { + Cell_handle c = m_cells[i]; + if (!m_refine_cells.triangulation().is_infinite(c)) + m_refine_cells.treat_new_cell(c); + } + } + }; +#endif // CGAL_LINKED_WITH_TBB + // ----------------------------------- + // ----------------------------------- + // ----------------------------------- + /// Computes badness and add to queue if needed void compute_badness(const Cell_handle& cell); - + // Updates cells incident to vertex, and add them to queue if needed void update_star_self(const Vertex_handle& vertex); - + /// Set \c cell to domain, with subdomain index \c index void set_cell_in_domain(const Cell_handle& cell, const Subdomain_index& index) { r_c3t3_.add_to_complex(cell, index); } - + /// Removes \c cell from domain void remove_cell_from_domain(const Cell_handle& cell) { r_c3t3_.remove_from_complex(cell); } - + /// Sets index and dimension of vertex \c v void set_vertex_properties(Vertex_handle& v, const Index& index) { @@ -227,12 +552,12 @@ // Set dimension of v: v is inside volume by construction, so dimension=3 v->set_dimension(3); } - + /// Get mirror facet Facet mirror_facet(const Facet& f) const { return r_tr_.mirror_facet(f); }; Facet mirror_facet(const Cell_handle& c, const int i) const { return mirror_facet(std::make_pair(c,i)); } - + private: /// The triangulation Tr& r_tr_; @@ -242,35 +567,27 @@ const MeshDomain& r_oracle_; /// The mesh result C3T3& r_c3t3_; - - //------------------------------------------------------- - // Cache objects - //------------------------------------------------------- - /// Stores index of vertex that may be inserted into triangulation - mutable Index last_vertex_index_; - + private: // Disabled copy constructor Refine_cells_3(const Self& src); // Disabled assignment operator Self& operator=(const Self& src); - -}; // end class Refine_cells_3 - - +}; // end class Refine_cells_3 -template -Refine_cells_3:: +// For sequential +template +Refine_cells_3:: Refine_cells_3(Tr& triangulation, const Cr& criteria, const MD& oracle, P_& previous, C3T3& c3t3) : Mesher_level >(previous) + Triangulation_mesher_level_traits_3, Ct >(previous) , C_() , No_test_point_conflict() , No_after_no_insertion() @@ -279,78 +596,240 @@ , r_criteria_(criteria) , r_oracle_(oracle) , r_c3t3_(c3t3) - , last_vertex_index_() { } +// For parallel +template +Refine_cells_3:: +Refine_cells_3(Tr& triangulation, + const Cr& criteria, + const MD& oracle, + P_& previous, + C3T3& c3t3, + Lock_data_structure *lock_ds, + WorksharingDataStructureType *worksharing_ds) + : Mesher_level, Ct >(previous, lock_ds, worksharing_ds) + , C_() + , No_test_point_conflict() + , No_after_no_insertion() + , No_before_conflicts() + , r_tr_(triangulation) + , r_criteria_(criteria) + , r_oracle_(oracle) + , r_c3t3_(c3t3) +{ +} -template +template void -Refine_cells_3:: +Refine_cells_3:: scan_triangulation_impl() { typedef typename Tr::Finite_cells_iterator Finite_cell_iterator; - + +#ifdef CGAL_MESH_3_PROFILING + WallClockTimer t; +#endif + + +#ifdef CGAL_LINKED_WITH_TBB + // Parallel + if (boost::is_convertible::value) + { +# if defined(CGAL_MESH_3_VERBOSE) || defined(CGAL_MESH_3_PROFILING) + std::cerr << "Scanning triangulation for bad cells (in parallel)"; +# endif + add_to_TLS_lists(true); + + typedef typename Tr::All_cells_iterator All_cells_iterator; + + // WITH PARALLEL_FOR + // Copy cells into an std::vector to allow the use of tbb::parallel_for + // which requires random-access. + // Note that we're using all_cells_begin() instead of finite_cells_begin() + // because it's faster to do the is_infinite() test in parallel. + std::vector cells; + cells.reserve(r_tr_.number_of_cells()); + for(All_cells_iterator cell_it = r_tr_.all_cells_begin(); + cell_it != r_tr_.all_cells_end(); + ++cell_it) + { + cells.push_back(cell_it); + } + +# if defined(CGAL_MESH_3_VERBOSE) || defined(CGAL_MESH_3_PROFILING) + std::cerr << " - Num cells to scan = " << cells.size() << "..." << std::endl; +# endif + tbb::parallel_for( + tbb::blocked_range(0, cells.size(), 1000), + Scan_cell(*this, cells) + ); + + splice_local_lists(); + add_to_TLS_lists(false); + } + // Sequential + else +#endif // CGAL_LINKED_WITH_TBB + { +#if defined(CGAL_MESH_3_VERBOSE) || defined(CGAL_MESH_3_PROFILING) + std::cerr << "Scanning triangulation for bad cells (sequential)... "; +#endif + + int count = 0; + for(Finite_cell_iterator cell_it = r_tr_.finite_cells_begin(); + cell_it != r_tr_.finite_cells_end(); + ++cell_it) + { + treat_new_cell(cell_it); + ++count; + } +#if defined(CGAL_MESH_3_VERBOSE) || defined(CGAL_MESH_3_PROFILING) + std::cerr << count << " cells scanned, "; +#endif + } + +#if defined(CGAL_MESH_3_VERBOSE) || defined(CGAL_MESH_3_PROFILING) + std::cerr << "done." << std::endl; +#endif + +#ifdef CGAL_MESH_3_PROFILING + double cell_scan_time = t.elapsed(); + std::cerr << "==== Cell scan: " << cell_scan_time << " seconds ====" + << std::endl << std::endl; +# ifdef CGAL_MESH_3_EXPORT_PERFORMANCE_DATA + // If it's parallel but the refinement is forced to sequential, we don't + // output the value +# ifndef CGAL_DEBUG_FORCE_SEQUENTIAL_MESH_REFINEMENT + CGAL_MESH_3_SET_PERFORMANCE_DATA("Cells_scan_time", cell_scan_time); +# endif +# endif + std::cerr << "Refining... "; +#endif + +#if defined(CGAL_MESH_3_VERBOSE) || defined(CGAL_MESH_3_PROFILING) + std::cerr << "Number of bad cells: " << C_::size() << std::endl; +#endif +} + + +template +int +Refine_cells_3:: +number_of_bad_elements_impl() +{ + typedef typename MD::Subdomain Subdomain; + typedef typename Tr::Finite_cells_iterator Finite_cell_iterator; + + int count = 0; +#if defined(CGAL_MESH_3_VERBOSE) || defined(CGAL_MESH_3_PROFILING) + std::cerr << "Scanning triangulation for bad cells - " + "number of finite cells = " + << r_c3t3_.triangulation().number_of_finite_cells() << "..."; +#endif for(Finite_cell_iterator cell_it = r_tr_.finite_cells_begin(); cell_it != r_tr_.finite_cells_end(); ++cell_it) { - treat_new_cell(cell_it); + // treat cell + const Subdomain subdomain = r_oracle_.is_in_domain_object()(r_tr_.dual(cell_it)); + if ( subdomain ) + { + const Is_cell_bad is_cell_bad = r_criteria_(cell_it); + if( is_cell_bad ) + ++count; + } } -} +# if defined(CGAL_MESH_3_VERBOSE) || defined(CGAL_MESH_3_PROFILING) + std::cerr << "done." << std::endl; +# endif + return count; +} -template -typename Refine_cells_3::Zone -Refine_cells_3:: -conflicts_zone_impl(const Point& point, - const Cell_handle& cell) const +template +typename Refine_cells_3::Zone +Refine_cells_3:: +conflicts_zone_impl(const Point& point + , const Cell_handle& cell + , bool &facet_is_in_its_cz) const { Zone zone; zone.cell = cell; zone.locate_type = Tr::CELL; - + r_tr_.find_conflicts(point, zone.cell, std::back_inserter(zone.boundary_facets), std::back_inserter(zone.cells), std::back_inserter(zone.internal_facets)); - CGAL_HISTOGRAM_PROFILER("Mesh_3::Refine_cells::conflict zone", zone.cells.size()); + + facet_is_in_its_cz = true; // Always true + + CGAL_HISTOGRAM_PROFILER("Mesh_3::Refine_cells::conflict zone", + static_cast(zone.cells.size())); return zone; } +template +typename Refine_cells_3::Zone +Refine_cells_3:: +conflicts_zone_impl(const Point& point + , const Cell_handle& cell + , bool &facet_is_in_its_cz + , bool &could_lock_zone + ) const +{ + Zone zone; + zone.cell = cell; + zone.locate_type = Tr::CELL; + + r_tr_.find_conflicts(point, + zone.cell, + std::back_inserter(zone.boundary_facets), + std::back_inserter(zone.cells), + std::back_inserter(zone.internal_facets), + &could_lock_zone); + + facet_is_in_its_cz = true; // Always true + + return zone; +} -template +template void -Refine_cells_3:: +Refine_cells_3:: before_insertion_handle_cells_in_conflict_zone(Zone& zone) { typename Zone::Cells_iterator cit = zone.cells.begin(); for ( ; cit != zone.cells.end() ; ++cit ) { - // Remove cell from refinement queue - this->remove_element(*cit); - + // Remove element (if needed - see + // remove_element_from_refinement_queue implementation) + this->remove_element_from_refinement_queue(*cit, Ct()); + // Remove cell from complex remove_cell_from_domain(*cit); } } -template +template void -Refine_cells_3:: +Refine_cells_3:: update_star(const Vertex_handle& vertex) { typedef std::vector Cells; typedef typename Cells::iterator Cell_iterator; - + // Get the star of v Cells incident_cells; r_tr_.incident_cells(vertex, std::back_inserter(incident_cells)); - + // Scan tets of the star of v for( Cell_iterator cell_it = incident_cells.begin(); cell_it != incident_cells.end(); @@ -364,35 +843,35 @@ } } - -template + +template void -Refine_cells_3:: +Refine_cells_3:: update_star_self(const Vertex_handle& vertex) { typedef std::vector Cells; typedef typename Cells::iterator Cell_iterator; - + // Get the star of v Cells incident_cells; r_tr_.incident_cells(vertex, std::back_inserter(incident_cells)); - + // Get subdomain index Subdomain_index cells_subdomain = r_oracle_.subdomain_index(vertex->index()); - + // Restore surface & domain for( Cell_iterator cell_it = incident_cells.begin(); cell_it != incident_cells.end(); ++cell_it ) { CGAL_assertion(!r_tr_.is_infinite(*cell_it)); - + // Restore surface const int& k = (*cell_it)->index(vertex); const Facet mirror_f = mirror_facet(*cell_it,k); const Cell_handle& neighbor_cell = mirror_f.first; const int& neighb_k = mirror_f.second; - + if ( neighbor_cell->is_facet_on_surface(neighb_k) ) { // Facet(*cell_it,k) is on surface @@ -405,29 +884,29 @@ (*cell_it)->set_facet_surface_center_index( k,neighbor_cell->get_facet_surface_center_index(neighb_k)); } - + // Set subdomain index set_cell_in_domain(*cell_it, cells_subdomain); - + // Add to queue compute_badness(*cell_it); } } -template +template void -Refine_cells_3:: +Refine_cells_3:: treat_new_cell(const Cell_handle& cell) { typedef boost::optional Subdomain; - + // treat cell const Subdomain subdomain = r_oracle_.is_in_domain_object()(r_tr_.dual(cell)); if ( subdomain ) { set_cell_in_domain(cell, *subdomain); - + // Add to refinement queue if needed compute_badness(cell); } @@ -436,23 +915,22 @@ remove_cell_from_domain(cell); } } - -template +template void -Refine_cells_3:: +Refine_cells_3:: compute_badness(const Cell_handle& cell) { const Is_cell_bad is_cell_bad = r_criteria_(cell); if( is_cell_bad ) { - this->add_bad_element(cell, *is_cell_bad); + this->add_bad_element(this->from_cell_to_refinement_queue_element(cell), *is_cell_bad); } } -template -typename Refine_cells_3::Vertex_handle -Refine_cells_3:: +template +typename Refine_cells_3::Vertex_handle +Refine_cells_3:: insert_impl(const Point& point, const Zone& zone) { @@ -461,18 +939,17 @@ { return zone.cell->vertex(zone.i); } - + const Facet& facet = *(zone.boundary_facets.begin()); - + Vertex_handle v = r_tr_.insert_in_hole(point, zone.cells.begin(), zone.cells.end(), facet.first, facet.second); - + // Set index and dimension of v - set_vertex_properties(v, last_vertex_index_); - + set_vertex_properties(v, Base::get_last_vertex_index()); return v; } diff -Nru cgal-4.4/include/CGAL/Mesh_3/Refine_facets_3.h cgal-4.5/include/CGAL/Mesh_3/Refine_facets_3.h --- cgal-4.4/include/CGAL/Mesh_3/Refine_facets_3.h 2014-03-29 20:00:20.000000000 +0000 +++ cgal-4.5/include/CGAL/Mesh_3/Refine_facets_3.h 2014-08-29 13:58:16.000000000 +0000 @@ -26,17 +26,30 @@ #ifndef CGAL_MESH_3_REFINE_FACETS_3_H #define CGAL_MESH_3_REFINE_FACETS_3_H -#include -#include +#include +#include +#ifdef CGAL_LINKED_WITH_TBB + #include +#endif + +#include +#include #include + #include +#ifdef CGAL_MESH_3_PROFILING + #include +#endif + #include #include #include #include +#include #include +#include #include namespace CGAL { @@ -57,7 +70,7 @@ BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_Facet_badness, Facet_badness, false) // template class, used when use_facet_badness = false -template ::value) && Has_Facet_badness::value > struct Get_Is_facet_bad { @@ -72,7 +85,172 @@ typedef Type type; }; + // Predicate to know if a facet in a refinement queue is a zombie + // A facet is a pair . + // A facet is a "zombie" if at least one of its two adjacent cells + // has been erased. We test it thanks to the "erase counter" which + // is inside each cell (incremented by the compact container). + // In the refinement queue, we store a tuple + // + // where facet2 = mirror_facet(facet1) and facetx_erase_counter is + // the erase_counter of facetx's cell when added to the queue> + template + class Facet_to_refine_is_not_zombie + { + public: + Facet_to_refine_is_not_zombie() {} + + bool operator()(const CGAL::cpp11::tuple< + Facet, unsigned int, Facet, unsigned int> &f) const + { +#ifdef _DEBUG + int f1_current_erase_counter = CGAL::cpp11::get<0>(f).first->erase_counter(); + int f1_saved_erase_counter = CGAL::cpp11::get<1>(f); + int f2_current_erase_counter = CGAL::cpp11::get<2>(f).first->erase_counter(); + int f2_saved_erase_counter = CGAL::cpp11::get<3>(f); + //f1_current_erase_counter - f1_saved_erase_counter + f2_current_erase_counter - f2_saved_erase_counter == 1 + + /*if (f1_current_erase_counter - f1_saved_erase_counter + f2_current_erase_counter - f2_saved_erase_counter == 1) + { +#ifdef CGAL_LINKED_WITH_TBB + tbb::queuing_mutex mut; + tbb::queuing_mutex::scoped_lock l(mut); +#endif + + std::stringstream sstr; + Facet facet = CGAL::cpp11::get<0>(f); + sstr << "Facet 1 { " << std::endl + << " - " << *facet.first->vertex((facet.second+1)%4) << std::endl + << " - " << *facet.first->vertex((facet.second+2)%4) << std::endl + << " - " << *facet.first->vertex((facet.second+3)%4) << std::endl + << " - 4th vertex in cell: " << *facet.first->vertex(facet.second) << std::endl + << "}" << std::endl; + + facet = CGAL::cpp11::get<2>(f); + sstr << "Facet 2 { " << std::endl + << " - " << *facet.first->vertex((facet.second+1)%4) << std::endl + << " - " << *facet.first->vertex((facet.second+2)%4) << std::endl + << " - " << *facet.first->vertex((facet.second+3)%4) << std::endl + << " - 4th vertex in cell: " << *facet.first->vertex(facet.second) << std::endl + << "}" << std::endl; + + std::string s = sstr.str(); + //std::cerr << s << std::endl; + }*/ +#endif + return (CGAL::cpp11::get<0>(f).first->erase_counter() == CGAL::cpp11::get<1>(f) + && CGAL::cpp11::get<2>(f).first->erase_counter() == CGAL::cpp11::get<3>(f) ); + } + }; + +/************************************************ +// Class Refine_facets_3_base +// Two versions: sequential / parallel +************************************************/ + +// Sequential +template +class Refine_facets_3_base +{ +protected: + Refine_facets_3_base() : m_last_vertex_index() {} + + Index get_last_vertex_index() const + { + return m_last_vertex_index; + } + + void set_last_vertex_index(Index i) const + { + m_last_vertex_index = i; + } + +#if defined(CGAL_MESH_3_USE_LAZY_SORTED_REFINEMENT_QUEUE) \ + || defined(CGAL_MESH_3_USE_LAZY_UNSORTED_REFINEMENT_QUEUE) + + CGAL::cpp11::tuple + from_facet_to_refinement_queue_element(const Facet &facet, + const Facet &mirror) const + { + return CGAL::cpp11::make_tuple( + facet, facet.first->erase_counter(), + mirror, mirror.first->erase_counter()); + } + +public: + template + Facet extract_element_from_container_value(const Container_element &e) const + { + // We get the first Facet inside the tuple + return CGAL::cpp11::get<0>(e); + } + +#else + + Facet + from_facet_to_refinement_queue_element(const Facet &facet, + const Facet &mirror) const + { + // Returns canonical facet + return (facet < mirror) ? facet : mirror; + } + +public: + template + Facet extract_element_from_container_value(const Container_element &e) const + { + return e; + } + +#endif + +protected: + /// Stores index of vertex that may be inserted into triangulation + mutable Index m_last_vertex_index; +}; + +#ifdef CGAL_LINKED_WITH_TBB +// Parallel +template +class Refine_facets_3_base +{ +protected: + Refine_facets_3_base() : m_last_vertex_index(Index()) {} + + Index get_last_vertex_index() const + { + return m_last_vertex_index.local(); + } + + void set_last_vertex_index(Index i) const + { + m_last_vertex_index.local() = i; + } + + CGAL::cpp11::tuple + from_facet_to_refinement_queue_element(const Facet &facet, + const Facet &mirror) const + { + return CGAL::cpp11::make_tuple( + facet, facet.first->erase_counter(), + mirror, mirror.first->erase_counter()); + } + +public: + template + Facet extract_element_from_container_value(const Container_element &e) const + { + // We get the first Facet inside the tuple + return CGAL::cpp11::get<0>(e); + } +protected: + /// Stores index of vertex that may be inserted into triangulation + mutable tbb::enumerable_thread_specific m_last_vertex_index; +}; +#endif // CGAL_LINKED_WITH_TBB + +/************************************************ // Class Refine_facets_3 // // Template parameters should be models of @@ -81,6 +259,7 @@ // MeshDomain : MeshTraits_3 // // Implements a Mesher_level for facets +************************************************/ // TODO document Container_ requirements template > + class Concurrency_tag, +#ifdef CGAL_LINKED_WITH_TBB + class Container_ = typename boost::mpl::if_c // (parallel/sequential?) + < + boost::is_convertible::value, + // Parallel +# ifdef CGAL_MESH_3_USE_LAZY_UNSORTED_REFINEMENT_QUEUE + Meshes::Filtered_deque_container +# else + Meshes::Filtered_multimap_container +# endif + < + CGAL::cpp11::tuple, + typename Criteria::Facet_quality, + Facet_to_refine_is_not_zombie, + Concurrency_tag + >, + // Sequential +# ifdef CGAL_MESH_3_USE_LAZY_UNSORTED_REFINEMENT_QUEUE + Meshes::Filtered_deque_container + < + CGAL::cpp11::tuple, + typename Criteria::Facet_quality, + Facet_to_refine_is_not_zombie, + Concurrency_tag + > +# elif defined(CGAL_MESH_3_USE_LAZY_SORTED_REFINEMENT_QUEUE) + Meshes::Filtered_multimap_container + < + CGAL::cpp11::tuple, + typename Criteria::Facet_quality, + Facet_to_refine_is_not_zombie, + Concurrency_tag + > +# else + Meshes::Double_map_container +# endif + >::type // boost::if (parallel/sequential) + +#else // !CGAL_LINKED_WITH_TBB + + // Sequential + class Container_ = +# ifdef CGAL_MESH_3_USE_LAZY_UNSORTED_REFINEMENT_QUEUE + Meshes::Filtered_deque_container + < + CGAL::cpp11::tuple, + typename Criteria::Facet_quality, + Facet_to_refine_is_not_zombie, + Concurrency_tag + > +# elif defined(CGAL_MESH_3_USE_LAZY_SORTED_REFINEMENT_QUEUE) + Meshes::Filtered_multimap_container + < + CGAL::cpp11::tuple, + typename Criteria::Facet_quality, + Facet_to_refine_is_not_zombie, + Concurrency_tag + > +# else + Meshes::Double_map_container +# endif +#endif // CGAL_LINKED_WITH_TBB +> class Refine_facets_3 -: public Mesher_level +, public Mesh_3::Mesher_level, + Previous_level_, + Concurrency_tag, + Container_>, typename Tr::Facet, Previous_level_, - Triangulation_mesher_level_traits_3 > + Triangulation_mesher_level_traits_3, + Concurrency_tag > , public Container_ , public No_after_no_insertion , public No_before_conflicts @@ -110,9 +362,35 @@ Criteria, MeshDomain, Complex3InTriangulation3, - Previous_level_> Self; + Previous_level_, + Concurrency_tag, + Container_> Self; + + typedef Refine_facets_3_base Base; + + typedef Mesher_level, + typename Tr::Facet, + Previous_level_, + Triangulation_mesher_level_traits_3, + Concurrency_tag > Base_ML; + + typedef typename Tr::Lock_data_structure Lock_data_structure; public: + using Base_ML::add_to_TLS_lists; + using Base_ML::splice_local_lists; + + typedef Container_ Container; // Because we need it in Mesher_level + typedef typename Container::Element Container_element; typedef typename Tr::Point Point; typedef typename Tr::Facet Facet; typedef typename Tr::Vertex_handle Vertex_handle; @@ -120,11 +398,20 @@ typedef Complex3InTriangulation3 C3T3; /// Constructor + // For sequential Refine_facets_3(Tr& triangulation, const Criteria& criteria, const MeshDomain& oracle, Previous_level_& previous, C3T3& c3t3); + // For parallel + Refine_facets_3(Tr& triangulation, + const Criteria& criteria, + const MeshDomain& oracle, + Previous_level_& previous, + C3T3& c3t3, + Lock_data_structure *lock_ds, + WorksharingDataStructureType *worksharing_ds); /// Destructor virtual ~Refine_facets_3() { } @@ -136,27 +423,66 @@ /// Initialization function void scan_triangulation_impl(); + int number_of_bad_elements_impl(); + + Point circumcenter_impl(const Facet& facet) const + { + return get_facet_surface_center(facet); + } + + template + void before_next_element_refinement_in_superior_impl(Mesh_visitor visitor) + { + // Before refining any cell, we refine the facets in the local refinement + // queue + this->treat_local_refinement_queue(visitor); + } + + void before_next_element_refinement_impl() + { + } + + Facet get_next_element_impl() + { + return this->extract_element_from_container_value( + Container_::get_next_element_impl()); + } + + Facet get_next_local_element_impl() + { + return extract_element_from_container_value( + Container_::get_next_local_element_impl()); + } + /// Gets the point to insert from the element to refine Point refinement_point_impl(const Facet& facet) const { #ifdef CGAL_MESHES_DEBUG_REFINEMENT_POINTS const Cell_handle c = facet.first; const int i = facet.second; - std::cerr << "Facet (" + std::cerr << "Facet (" << c->vertex((i+1)&3)->point() << " , " << c->vertex((i+2)&3)->point() << " , " << c->vertex((i+3)&3)->point() << ") : refinement point is " << get_facet_surface_center(facet) << std::endl; #endif CGAL_assertion (is_facet_on_surface(facet)); - last_vertex_index_ = get_facet_surface_center_index(facet); + this->set_last_vertex_index(get_facet_surface_center_index(facet)); return get_facet_surface_center(facet); }; /// Tests if p encroaches facet from zone + // For sequential Mesher_level_conflict_status test_point_conflict_from_superior_impl(const Point& p, Zone& zone); + /// Tests if p encroaches facet from zone + // For parallel + template + Mesher_level_conflict_status + test_point_conflict_from_superior_impl(const Point& p, Zone& zone, + Mesh_visitor &visitor); + /// Useless here Mesher_level_conflict_status private_test_point_conflict_impl( const Point& p, @@ -174,7 +500,13 @@ } /// Returns the conflicts zone - Zone conflicts_zone_impl(const Point& point, const Facet& facet) const; + Zone conflicts_zone_impl(const Point& point + , const Facet& facet + , bool &facet_is_in_its_cz); + Zone conflicts_zone_impl(const Point& point + , const Facet& facet + , bool &facet_is_in_its_cz + , bool &could_lock_zone); /// Job to do before insertion void before_insertion_impl(const Facet& facet, @@ -183,7 +515,9 @@ /// Job to do after insertion void after_insertion_impl(const Vertex_handle& v) - { restore_restricted_Delaunay(v); } + { + restore_restricted_Delaunay(v); + } /// Insert p into triangulation Vertex_handle insert_impl(const Point& p, const Zone& zone); @@ -191,6 +525,17 @@ /// Restore restricted Delaunay ; may be call by Cells_mesher visitor void restore_restricted_Delaunay(const Vertex_handle& v); + bool try_lock_element(const Facet &f, int lock_radius = 0) const + { + return this->triangulation().try_lock_facet(f, lock_radius); + } + + /// debug info: class name + std::string debug_info_class_name_impl() const + { + return "Refine_facets_3"; + } + /// debug info std::string debug_info() const { @@ -204,9 +549,22 @@ { return "#facets to refine"; } - + + std::string debug_info_element_impl(const Facet &facet) const + { + std::stringstream sstr; + sstr << "Facet { " << std::endl + << " - " << *facet.first->vertex((facet.second+1)%4) << std::endl + << " - " << *facet.first->vertex((facet.second+2)%4) << std::endl + << " - " << *facet.first->vertex((facet.second+3)%4) << std::endl + << " - 4th vertex in cell: " << *facet.first->vertex(facet.second) << std::endl + << "}" << std::endl; + + return sstr.str(); + } + /// for debugging - std::string display_dual(Facet f) const + std::string display_dual(Facet f) const { std::stringstream stream; stream.precision(17); @@ -218,7 +576,7 @@ } else if ( const Ray_3* p_ray = object_cast(&dual) ) { stream << "Ray(" << p_ray->point(0) - << " , " << p_ray->point(1) + << " , " << p_ray->point(1) << "), with vector (" << p_ray->to_vector() << ")"; } else if ( const Line_3* p_line = object_cast(&dual) ) { @@ -234,6 +592,35 @@ private: + + // Functor for scan_triangulation_impl function + template + class Scan_facet + { + Refine_facets_ & m_refine_facets; + + typedef typename Refine_facets_::Facet Facet; + + public: + // Constructor + Scan_facet(Refine_facets_ & rf) + : m_refine_facets(rf) + {} + + // Constructor + Scan_facet(const Scan_facet &sf) + : m_refine_facets(sf.m_refine_facets) + {} + + // operator() + // f cannot be const, see treat_new_facet signature + void operator()( Facet f ) const + { + m_refine_facets.treat_new_facet(f); + } + }; + + //------------------------------------------------------- // Private types //------------------------------------------------------- @@ -247,8 +634,9 @@ typedef typename Gt::Ray_3 Ray_3; typedef typename Gt::Line_3 Line_3; - typedef typename boost::optional > - Facet_properties; + typedef typename boost::optional< + CGAL::cpp11::tuple > + Facet_properties; private: /// Get mirror facet @@ -341,12 +729,16 @@ /// Computes facet properties and add facet to the refinement queue if needed void treat_new_facet(Facet& facet); + /// Compute the exact dual of a facet + Object dual_exact(const Facet & f) const; + /** * Computes at once is_facet_on_surface and facet_surface_center. * @param facet The input facet * @return \c true if \c facet is on surface, \c false otherwise */ - void compute_facet_properties(const Facet& facet, Facet_properties& fp ) const; + void compute_facet_properties(const Facet& facet, Facet_properties& fp, + bool force_exact = false ) const; /// Returns true if point encroaches facet bool is_facet_encroached(const Facet& facet, const Point& point) const; @@ -357,10 +749,12 @@ /// Insert facet into refinement queue void insert_bad_facet(Facet& facet, const Quality& quality) { - // Insert canonical facet - this->add_bad_element(this->canonical_facet(facet), quality); + // Insert the facet and its mirror + this->add_bad_element( + this->from_facet_to_refinement_queue_element(facet, mirror_facet(facet)), + quality); } - + /// Insert encroached facet into refinement queue void insert_encroached_facet_in_queue(Facet& facet) { @@ -368,12 +762,22 @@ } /// Removes facet from refinement queue - void remove_bad_facet(Facet& facet) + // Sequential + void remove_bad_facet(Facet& facet, Sequential_tag) { + // If sequential AND NOT lazy, remove cell from refinement queue +#if !defined(CGAL_MESH_3_USE_LAZY_SORTED_REFINEMENT_QUEUE) \ + && !defined(CGAL_MESH_3_USE_LAZY_UNSORTED_REFINEMENT_QUEUE) // Remove canonical facet Facet canonical_facet = this->canonical_facet(facet); this->remove_element(canonical_facet); +#endif } +#ifdef CGAL_LINKED_WITH_TBB + /// Removes facet from refinement queue + // Parallel: it's always lazy, so do nothing + void remove_bad_facet(Facet&, Parallel_tag) {} +#endif // CGAL_LINKED_WITH_TBB /** * Action to perform on a facet inside the conflict zone before insertion @@ -414,12 +818,6 @@ /// The mesh result C3T3& r_c3t3_; - //------------------------------------------------------- - // Cache objects - //------------------------------------------------------- - /// Stores index of vertex that may be inserted into triangulation - mutable Index last_vertex_index_; - private: // Disabled copy constructor Refine_facets_3(const Self& src); @@ -430,16 +828,16 @@ - -template -Refine_facets_3:: +// For sequential +template +Refine_facets_3:: Refine_facets_3(Tr& triangulation, const Cr& criteria, const MD& oracle, P_& previous, C3T3& c3t3) : Mesher_level >(previous) + Triangulation_mesher_level_traits_3, Ct>(previous) , C_() , No_after_no_insertion() , No_before_conflicts() @@ -447,37 +845,278 @@ , r_criteria_(criteria) , r_oracle_(oracle) , r_c3t3_(c3t3) - , last_vertex_index_() { } +// For parallel +template +Refine_facets_3:: +Refine_facets_3(Tr& triangulation, + const Cr& criteria, + const MD& oracle, + P_& previous, + C3T3& c3t3, + Lock_data_structure *lock_ds, + WorksharingDataStructureType *worksharing_ds) + : Mesher_level, Ct>(previous) + , C_() + , No_after_no_insertion() + , No_before_conflicts() + , r_tr_(triangulation) + , r_criteria_(criteria) + , r_oracle_(oracle) + , r_c3t3_(c3t3) +{ + Base::set_lock_ds(lock_ds); + Base::set_worksharing_ds(worksharing_ds); +} -template + +template void -Refine_facets_3:: +Refine_facets_3:: scan_triangulation_impl() { typedef typename Tr::Finite_facets_iterator Finite_facet_iterator; +#ifdef CGAL_MESH_3_PROFILING + WallClockTimer t; +#endif + +#ifdef CGAL_MESH_3_VERY_VERBOSE + std::cerr + << "Vertices: " << r_c3t3_.triangulation().number_of_vertices() << std::endl + << "Facets : " << r_c3t3_.number_of_facets_in_complex() << std::endl + << "Tets : " << r_c3t3_.number_of_cells_in_complex() << std::endl; +#endif + +#ifdef CGAL_LINKED_WITH_TBB + // Parallel + if (boost::is_convertible::value) + { +# if defined(CGAL_MESH_3_VERBOSE) || defined(CGAL_MESH_3_PROFILING) + std::cerr << "Scanning triangulation for bad facets (in parallel) - " + "number of finite facets = " + << r_c3t3_.triangulation().number_of_finite_facets() << "..." + << std::endl; +# endif + add_to_TLS_lists(true); + + // PARALLEL_DO + tbb::parallel_do( + r_tr_.finite_facets_begin(), r_tr_.finite_facets_end(), + Scan_facet(*this) + ); + + splice_local_lists(); + add_to_TLS_lists(false); + } + // Sequential + else +#endif // CGAL_LINKED_WITH_TBB + { +#if defined(CGAL_MESH_3_VERBOSE) || defined(CGAL_MESH_3_PROFILING) + std::cerr << "Scanning triangulation for bad facets (sequential) - " + "number of finite facets = " + << r_c3t3_.triangulation().number_of_finite_facets() << "..." + << std::endl; +#endif + for(Finite_facet_iterator facet_it = r_tr_.finite_facets_begin(); + facet_it != r_tr_.finite_facets_end(); + ++facet_it) + { + // Cannot be const, see treat_new_facet signature + Facet facet = *facet_it; + /*std::cerr << "*" << *facet.first->vertex((facet.second+1)%4) << std::endl + << " " << *facet.first->vertex((facet.second+2)%4) << std::endl + << " " << *facet.first->vertex((facet.second+3)%4) << std::endl;*/ + treat_new_facet(facet); + } + } + +#ifdef CGAL_MESH_3_PROFILING + std::cerr << "==== Facet scan: " << t.elapsed() << " seconds ====" + << std::endl << std::endl; +#endif + +#if defined(CGAL_MESH_3_VERBOSE) || defined(CGAL_MESH_3_PROFILING) + std::cerr << "Number of bad facets: " << C_::size() << std::endl; +#endif + +#ifdef CGAL_MESH_3_PROFILING + std::cerr << "Refining... "; + Base_ML::m_timer.reset(); +#endif +} + + + +template +int +Refine_facets_3:: +number_of_bad_elements_impl() +{ + typedef typename Tr::Finite_facets_iterator Finite_facet_iterator; + + int count = 0, count_num_bad_surface_facets = 0; + int num_internal_facets_that_should_be_on_surface = 0; +#if defined(CGAL_MESH_3_VERBOSE) || defined(CGAL_MESH_3_PROFILING) + std::cerr << "Scanning triangulation for bad facets - " + "number of finite facets = " + << r_c3t3_.triangulation().number_of_finite_facets() << "..."; +#endif + int num_tested_facets = 0; for(Finite_facet_iterator facet_it = r_tr_.finite_facets_begin(); facet_it != r_tr_.finite_facets_end(); ++facet_it) { - // Cannot be const, see treat_new_facet signature Facet facet = *facet_it; - treat_new_facet(facet); - } -} + Facet_properties properties; + compute_facet_properties(facet, properties); + +#ifdef SHOW_REMAINING_BAD_ELEMENT_IN_RED + //facet.first->mark = 0; +#endif + + // On surface? + if ( properties ) + { + // This facet should be on surface... + if (!is_facet_on_surface(facet)) + { + std::cerr << "\n\n*** The facet f is on surface but is NOT MARKED ON SURFACE. " << std::endl; + + Cell_handle c = facet.first; + int ind = facet.second; + Cell_handle mc = mirror_facet(facet).first; + int mind = mirror_facet(facet).second; + +#ifdef SHOW_REMAINING_BAD_ELEMENT_IN_RED + c->mark2 = ind; +#endif + + // c and mc are the cells adjacent to f + // browse each facet ff of c and mc, and mark it if it is "on surface" + int num_erroneous_surface_facets_in_c = 0; + int num_erroneous_surface_facets_in_mc = 0; + int num_real_surface_facets_in_c = 0; + int num_real_surface_facets_in_mc = 0; + for (int i = 0 ; i < 4 ; ++i) + { + if (i != ind) + { + const Facet f1(c, i); + if (is_facet_on_surface(f1)) + { + std::cerr << "*** f1 is " << (r_criteria_(f1) ? "bad" : "good") << std::endl; + +#ifdef SHOW_REMAINING_BAD_ELEMENT_IN_RED + c->mark = i; +#endif + Facet_properties properties; + compute_facet_properties(f1, properties); + if (properties) + ++num_real_surface_facets_in_c; + else + ++num_erroneous_surface_facets_in_c; + } + } + if (i != mind) + { + const Facet f2(c, i); + if (is_facet_on_surface(f2)) + { + std::cerr << "*** f2 is " << (r_criteria_(f2) ? "bad" : "good") << std::endl; + +#ifdef SHOW_REMAINING_BAD_ELEMENT_IN_RED + mc->mark = i; +#endif + Facet_properties properties; + compute_facet_properties(f2, properties); + if (properties) + ++num_real_surface_facets_in_mc; + else + ++num_erroneous_surface_facets_in_mc; + } + } + } + + std::cerr + << "*** Num of erroneous surface facets in c: " << num_erroneous_surface_facets_in_c << std::endl + << "*** Num of erroneous surface facets in mc: " << num_erroneous_surface_facets_in_mc << std::endl + << "*** Num of real surface facets in c: " << num_real_surface_facets_in_c << std::endl + << "*** Num of real surface facets in mc: " << num_real_surface_facets_in_mc << std::endl; + + const bool is_c_in_domain = r_oracle_.is_in_domain_object()(r_tr_.dual(c)); + const bool is_mc_in_domain = r_oracle_.is_in_domain_object()(r_tr_.dual(mc)); + + std::cerr << "*** Is in complex? c is marked in domain: " << r_c3t3_.is_in_complex(c) + << " / c is really in domain: " << is_c_in_domain + << " / mc is marked in domain: " << r_c3t3_.is_in_complex(mc) + << " / mc is really in domain: " << is_mc_in_domain + << std::endl; + + + // ... if it's not, count it + ++num_internal_facets_that_should_be_on_surface; + + } + + const Surface_patch_index& surface_index = CGAL::cpp11::get<0>(*properties); + const Index& surface_center_index = CGAL::cpp11::get<1>(*properties); + const Point& surface_center = CGAL::cpp11::get<2>(*properties); + + // Facet is on surface: set facet properties + //set_facet_surface_center(facet, surface_center, surface_center_index); + //set_facet_on_surface(facet, surface_index); + + const Is_facet_bad is_facet_bad = r_criteria_(facet); + if ( is_facet_bad ) + { + ++count; + if (is_facet_on_surface(facet)) + ++count_num_bad_surface_facets; + +#ifdef SHOW_REMAINING_BAD_ELEMENT_IN_RED + //facet.first->mark = facet.second; +#endif + } + ++ num_tested_facets; + } + // Not on surface? + else + { + // Facet is not on surface + //remove_facet_from_surface(facet); + // Marked on surface? + if (is_facet_on_surface(facet)) + { + std::cerr << "************** The facet is marked on surface whereas it's not! **************" << std::endl; +#ifdef SHOW_REMAINING_BAD_ELEMENT_IN_RED + facet.first->mark = facet.second; +#endif + } + } + } + /*std::cerr << "done (" << num_internal_facets_that_should_be_on_surface + << " facets which were internal facets were added to the surface)." << std::endl;*/ + std::cerr << "done (" << num_internal_facets_that_should_be_on_surface + << " facets that should be on surface are actually internal facets)." << std::endl; + std::cerr << std::endl << "Num_tested_facets = " << num_tested_facets << std::endl; + std::cerr << std::endl << "Num bad surface-marked facets = " << count_num_bad_surface_facets << std::endl; + return count; +} -template +// For sequential +template Mesher_level_conflict_status -Refine_facets_3:: -test_point_conflict_from_superior_impl(const Point& point, - Zone& zone) +Refine_facets_3:: +test_point_conflict_from_superior_impl(const Point& point, Zone& zone) { typedef typename Zone::Facets_iterator Facet_iterator; @@ -519,12 +1158,63 @@ return NO_CONFLICT; } +// For parallel +template +template +Mesher_level_conflict_status +Refine_facets_3:: +test_point_conflict_from_superior_impl(const Point& point, Zone& zone, + Mesh_visitor &visitor) +{ + typedef typename Zone::Facets_iterator Facet_iterator; -template -typename Refine_facets_3::Zone -Refine_facets_3:: -conflicts_zone_impl(const Point& point, - const Facet& facet) const + for (Facet_iterator facet_it = zone.internal_facets.begin(); + facet_it != zone.internal_facets.end(); + ++facet_it) + { + // surface facets which are internal facets of the conflict zone are + // encroached + if( is_facet_on_surface(*facet_it) ) + { + if ( is_encroached_facet_refinable(*facet_it) ) + { + // Even if it doesn't succeed, it will be tried again + this->try_to_refine_element(*facet_it, visitor); + return CONFLICT_BUT_ELEMENT_CAN_BE_RECONSIDERED; + } + else + return CONFLICT_AND_ELEMENT_SHOULD_BE_DROPPED; + } + } + + for (Facet_iterator facet_it = zone.boundary_facets.begin(); + facet_it != zone.boundary_facets.end(); + ++facet_it) + { + if( is_facet_encroached(*facet_it, point) ) + { + // Insert already existing surface facet into refinement queue + if ( is_encroached_facet_refinable(*facet_it) ) + { + // Even if it doesn't succeed, it will be tried again + this->try_to_refine_element(*facet_it, visitor); + return CONFLICT_BUT_ELEMENT_CAN_BE_RECONSIDERED; + } + else + return CONFLICT_AND_ELEMENT_SHOULD_BE_DROPPED; + } + } + + return NO_CONFLICT; +} + + +template +typename Refine_facets_3::Zone +Refine_facets_3:: +conflicts_zone_impl(const Point& point + , const Facet& facet + , bool &facet_is_in_its_cz) { Zone zone; @@ -537,22 +1227,113 @@ if(zone.locate_type != Tr::VERTEX) { + const Facet *p_facet = (facet == Facet() ? 0 : &facet); + r_tr_.find_conflicts(point, zone.cell, std::back_inserter(zone.boundary_facets), std::back_inserter(zone.cells), - std::back_inserter(zone.internal_facets)); + std::back_inserter(zone.internal_facets) + , 0 + , p_facet + , &facet_is_in_its_cz); + + if (p_facet != 0 && !facet_is_in_its_cz) + { +# ifdef CGAL_MESH_3_VERBOSE + std::cerr << "Info: the facet is not in its conflict zone. " + "Switching to exact computation." << std::endl; +# endif + + Facet_properties properties; + compute_facet_properties(facet, properties, /*force_exact=*/true); + if ( properties ) + { + const Surface_patch_index& surface_index = CGAL::cpp11::get<0>(*properties); + const Index& surface_center_index = CGAL::cpp11::get<1>(*properties); + const Point& surface_center = CGAL::cpp11::get<2>(*properties); + + // Facet is on surface: set facet properties + set_facet_surface_center(facet, surface_center, surface_center_index); + set_facet_on_surface(facet, surface_index); + } + else + { + // Facet is not on surface + remove_facet_from_surface(facet); + } + } } return zone; } +template +typename Refine_facets_3::Zone +Refine_facets_3:: +conflicts_zone_impl(const Point& point + , const Facet& facet + , bool &facet_is_in_its_cz + , bool &could_lock_zone) +{ + Zone zone; + // TODO may be avoid the locate here + zone.cell = r_tr_.locate(point, + zone.locate_type, + zone.i, + zone.j, + facet.first, + &could_lock_zone); + + if(could_lock_zone && zone.locate_type != Tr::VERTEX) + { + const Facet *p_facet = (facet == Facet() ? 0 : &facet); + r_tr_.find_conflicts(point, + zone.cell, + std::back_inserter(zone.boundary_facets), + std::back_inserter(zone.cells), + std::back_inserter(zone.internal_facets) + , &could_lock_zone + , p_facet + , &facet_is_in_its_cz); -template + if (could_lock_zone && p_facet != 0 && !facet_is_in_its_cz) + { +#ifdef CGAL_MESH_3_VERBOSE + std::cerr << "Info: the facet is not in its conflict zone. " + "Switching to exact computation." << std::endl; +#endif + + Facet_properties properties; + compute_facet_properties(facet, properties, /*force_exact=*/true); + if ( properties ) + { + const Surface_patch_index& surface_index = CGAL::cpp11::get<0>(*properties); + const Index& surface_center_index = CGAL::cpp11::get<1>(*properties); + const Point& surface_center = CGAL::cpp11::get<2>(*properties); + + // Facet is on surface: set facet properties + set_facet_surface_center(facet, surface_center, surface_center_index); + set_facet_on_surface(facet, surface_index); + } + else + { + // Facet is not on surface + remove_facet_from_surface(facet); + } + } + } + + return zone; +} + + + +template void -Refine_facets_3:: +Refine_facets_3:: before_insertion_impl(const Facet& facet, const Point& point, Zone& zone) @@ -561,6 +1342,11 @@ bool source_facet_is_in_conflict = false; + /*std::cerr << "before_insertion_impl:" << std::endl + << "* " << *facet.first->vertex((facet.second+1)%4) << std::endl + << " " << *facet.first->vertex((facet.second+2)%4) << std::endl + << " " << *facet.first->vertex((facet.second+3)%4) << std::endl;*/ + // Iterate on conflict zone facets for (Facets_iterator facet_it = zone.internal_facets.begin(); facet_it != zone.internal_facets.end(); @@ -586,6 +1372,8 @@ // called from a Mesh_3 visitor. if ( !source_facet_is_in_conflict && facet != Facet() ) { + const Facet source_other_side = mirror_facet(facet); + using boost::io::group; using std::setprecision; @@ -596,7 +1384,10 @@ "Debugging informations:\n" " Facet: (%1%, %2%) = (%6%, %7%, %8%)\n" " Dual: %3%\n" - " Refinement point: %5%\n") + " Refinement point: %5%\n" + " Cells adjacent to facet:\n" + " ( %9% , %10% , %11% , %12% )\n" + " ( %13% , %14% , %15% , %16% )\n") % group(setprecision(17), (&*facet.first)) % group(setprecision(17), facet.second) % display_dual(facet) @@ -604,7 +1395,15 @@ % group(setprecision(17), point) % group(setprecision(17), facet.first->vertex((facet.second + 1)&3)->point()) % group(setprecision(17), facet.first->vertex((facet.second + 2)&3)->point()) - % group(setprecision(17), facet.first->vertex((facet.second + 3)&3)->point()); + % group(setprecision(17), facet.first->vertex((facet.second + 3)&3)->point()) + % facet.first->vertex(0)->point() + % facet.first->vertex(1)->point() + % facet.first->vertex(2)->point() + % facet.first->vertex(3)->point() + % source_other_side.first->vertex(0)->point() + % source_other_side.first->vertex(1)->point() + % source_other_side.first->vertex(2)->point() + % source_other_side.first->vertex(3)->point(); CGAL_error_msg(error_msg.str().c_str()); } @@ -612,9 +1411,9 @@ -template -typename Refine_facets_3::Vertex_handle -Refine_facets_3:: +template +typename Refine_facets_3::Vertex_handle +Refine_facets_3:: insert_impl(const Point& point, const Zone& zone) { @@ -634,16 +1433,16 @@ facet.second); // Set index and dimension of v - set_vertex_properties(v, last_vertex_index_); + set_vertex_properties(v, Base::get_last_vertex_index()); return v; } -template +template void -Refine_facets_3:: +Refine_facets_3:: restore_restricted_Delaunay(const Vertex_handle& vertex) { typedef std::vector Cell_handle_vector; @@ -675,9 +1474,9 @@ //------------------------------------------------------- // Private methods //------------------------------------------------------- -template +template void -Refine_facets_3:: +Refine_facets_3:: treat_new_facet(Facet& facet) { // Treat facet @@ -695,9 +1494,16 @@ // Insert facet into refinement queue if needed const Is_facet_bad is_facet_bad = r_criteria_(facet); + if ( is_facet_bad ) { insert_bad_facet(facet, *is_facet_bad); + + /*std::cerr << "INSERT BAD FACET : " << std::endl + << "* " << *facet.first->vertex((facet.second+1)%4) << std::endl + << " " << *facet.first->vertex((facet.second+2)%4) << std::endl + << " " << *facet.first->vertex((facet.second+3)%4) << std::endl + << " Quality=" << is_facet_bad->second << std::endl;*/ } } else @@ -712,12 +1518,70 @@ set_facet_visited(mirror); } +template +Object +Refine_facets_3:: +dual_exact(const Facet& facet) const +{ + typedef typename Gt::Bare_point Bare_point; -template + Cell_handle c = facet.first; + int i = facet.second; + Cell_handle n = c->neighbor(i); + if ( ! r_tr_.is_infinite(c) && ! r_tr_.is_infinite(n) ) + { + Bare_point p1 = Gt().construct_weighted_circumcenter_3_object()( + c->vertex(0)->point(), + c->vertex(1)->point(), + c->vertex(2)->point(), + c->vertex(3)->point(), + true); + Bare_point p2 = Gt().construct_weighted_circumcenter_3_object()( + n->vertex(0)->point(), + n->vertex(1)->point(), + n->vertex(2)->point(), + n->vertex(3)->point(), + true); + return Gt().construct_object_3_object()( + Gt().construct_segment_3_object()(p1, p2)); + } + + // either n or c is infinite + int in; + if ( r_tr_.is_infinite(c) ) + in = n->index(c); + else { + n = c; + in = i; + } + // n now denotes a finite cell, either c or c->neighbor(i) + int ind[3] = {(in+1)&3,(in+2)&3,(in+3)&3}; + if ( (in&1) == 1 ) + std::swap(ind[0], ind[1]); + const Point& p = n->vertex(ind[0])->point(); + const Point& q = n->vertex(ind[1])->point(); + const Point& r = n->vertex(ind[2])->point(); + + typename Gt::Line_3 l = Gt().construct_perpendicular_line_3_object() + ( Gt().construct_plane_3_object()(p,q,r), + Gt().construct_weighted_circumcenter_3_object()(p,q,r) ); + return Gt().construct_object_3_object()( + Gt().construct_ray_3_object()( + Gt().construct_weighted_circumcenter_3_object()( + n->vertex(0)->point(), + n->vertex(1)->point(), + n->vertex(2)->point(), + n->vertex(3)->point(), + true), + l)); +} + +template void -Refine_facets_3:: +Refine_facets_3:: compute_facet_properties(const Facet& facet, - Facet_properties& fp) const + Facet_properties& fp, + bool force_exact) const { //------------------------------------------------------- // Facet must be finite @@ -736,7 +1600,7 @@ // Get dual of facet - Object dual = r_tr_.dual(facet); + Object dual = (force_exact ? dual_exact(facet) : r_tr_.dual(facet)); // If the dual is a segment if ( const Segment_3* p_segment = object_cast(&dual) ) @@ -766,17 +1630,17 @@ Intersection intersect = construct_intersection(segment); #ifdef CGAL_MESH_3_NO_LONGER_CALLS_DO_INTERSECT_3 - // In the following, CGAL::cpp0x::get<2>(intersect) == 0 is a way to + // In the following, CGAL::cpp11::get<2>(intersect) == 0 is a way to // test "intersect == Intersection()" (aka empty intersection), but // the later does not work. - Surface_patch surface = - (CGAL::cpp0x::get<2>(intersect) == 0) ? Surface_patch() : - r_oracle_.surface_patch_index(CGAL::cpp0x::get<1>(intersect)); + Surface_patch surface = + (CGAL::cpp11::get<2>(intersect) == 0) ? Surface_patch() : + r_oracle_.surface_patch_index(CGAL::cpp11::get<1>(intersect)); if(surface) #endif // CGAL_MESH_3_NO_LONGER_CALLS_DO_INTERSECT_3 - fp = Facet_properties(CGAL::cpp0x::make_tuple(*surface, - CGAL::cpp0x::get<1>(intersect), - CGAL::cpp0x::get<0>(intersect))); + fp = Facet_properties(CGAL::cpp11::make_tuple(*surface, + CGAL::cpp11::get<1>(intersect), + CGAL::cpp11::get<0>(intersect))); return; } } @@ -784,7 +1648,7 @@ else if ( const Ray_3* p_ray = object_cast(&dual) ) { // If a facet is on the convex hull, and if its finite incident - // cell has a very bid Delaunay ball, then the dual of the facet is + // cell has a very big Delaunay ball, then the dual of the facet is // a ray constructed with a point with very big coordinates, and a // vector with small coordinates. Its can happen than the // constructed ray is degenerate (the point(1) of the ray is @@ -801,15 +1665,15 @@ Intersection intersect = construct_intersection(*p_ray); #ifdef CGAL_MESH_3_NO_LONGER_CALLS_DO_INTERSECT_3 - Surface_patch surface = - (CGAL::cpp0x::get<2>(intersect) == 0) ? Surface_patch() : - r_oracle_.surface_patch_index(CGAL::cpp0x::get<1>(intersect)); + Surface_patch surface = + (CGAL::cpp11::get<2>(intersect) == 0) ? Surface_patch() : + r_oracle_.surface_patch_index(CGAL::cpp11::get<1>(intersect)); if(surface) #endif // CGAL_MESH_3_NO_LONGER_CALLS_DO_INTERSECT_3 { - fp = Facet_properties(CGAL::cpp0x::make_tuple(*surface, - CGAL::cpp0x::get<1>(intersect), - CGAL::cpp0x::get<0>(intersect))); + fp = Facet_properties(CGAL::cpp11::make_tuple(*surface, + CGAL::cpp11::get<1>(intersect), + CGAL::cpp11::get<0>(intersect))); return; } @@ -839,8 +1703,8 @@ Intersection intersect = construct_intersection(line); fp = Facet_properties(CGAL::cpp11::make_tuple(*surface, - CGAL::cpp11::get<1>(intersect), - CGAL::cpp11::get<0>(intersect))); + CGAL::cpp11::get<1>(intersect), + CGAL::cpp11::get<0>(intersect))); return; } } @@ -857,9 +1721,9 @@ } -template +template bool -Refine_facets_3:: +Refine_facets_3:: is_facet_encroached(const Facet& facet, const Point& point) const { @@ -867,68 +1731,68 @@ { return false; } - + typename Gt::Compare_power_distance_3 compare_distance = r_tr_.geom_traits().compare_power_distance_3_object(); - + const Cell_handle& cell = facet.first; const int& facet_index = facet.second; const Point& center = get_facet_surface_center(facet); const Point& reference_point = cell->vertex((facet_index+1)&3)->point(); - + // facet is encroached if the new point is near from center than // one vertex of the facet return ( compare_distance(center, reference_point, point) != CGAL::SMALLER ); } -template +template bool -Refine_facets_3:: +Refine_facets_3:: is_encroached_facet_refinable(Facet& facet) const { typedef typename Gt::Point_3 Point_3; typedef typename Gt::FT FT; - + typename Gt::Compute_squared_radius_smallest_orthogonal_sphere_3 sq_radius = Gt().compute_squared_radius_smallest_orthogonal_sphere_3_object(); - + typename Gt::Compare_weighted_squared_radius_3 compare = Gt().compare_weighted_squared_radius_3_object(); - + const Cell_handle& c = facet.first; const int& k = facet.second; - + int k1 = (k+1)&3; int k2 = (k+2)&3; int k3 = (k+3)&3; - + // Get number of weighted points, and ensure that they will be accessible // using k1...ki, if i is the number of weighted points. int wp_nb = 0; if(c->vertex(k1)->point().weight() > FT(0)) - { + { ++wp_nb; } - + if(c->vertex(k2)->point().weight() > FT(0)) - { + { if ( 0 == wp_nb ) { std::swap(k1,k2); } ++wp_nb; } - + if(c->vertex(k3)->point().weight() > FT(0)) - { + { if ( 0 == wp_nb ) { std::swap(k1,k3); } if ( 1 == wp_nb ) { std::swap(k2,k3); } ++wp_nb; } - + const Point_3& p1 = c->vertex(k1)->point(); const Point_3& p2 = c->vertex(k2)->point(); const Point_3& p3 = c->vertex(k3)->point(); - + const FT min_ratio (0.16); // (0.2*2)^2 - + // Check ratio switch ( wp_nb ) { @@ -938,7 +1802,7 @@ if ( r < min_ratio*p1.weight() ) { return false; } break; } - + case 2: { bool do_spheres_intersect = (compare(p1,p2,FT(0)) != CGAL::LARGER); @@ -947,38 +1811,42 @@ FT r13 = sq_radius(p1,p3) / p1.weight(); FT r23 = sq_radius(p2,p3) / p2.weight(); FT r = (std::max)(r13,r23); - + if ( r < min_ratio ) { return false; } } break; } - + case 3: { bool do_spheres_intersect = (compare(p1,p2,p3,FT(0)) != CGAL::LARGER); if ( do_spheres_intersect ) { return false; } break; - } - + } + default: break; } return true; } - -template +/** + * \c facet is an internal facet we are going to remove + * \c source_facet is the facet we want to refine by inserting a new point + */ +template bool -Refine_facets_3:: +Refine_facets_3:: before_insertion_handle_facet_in_conflict_zone(Facet& facet, const Facet& source_facet) { Facet other_side = mirror_facet(facet); + // Is the facet on the surface of the complex if ( is_facet_on_surface(facet) ) { - // Remove facet from refinement queue - remove_bad_facet(facet); + // Remove element (if needed - see remove_bad_facet implementation) + remove_bad_facet(facet, Ct()); // Remove facet from complex remove_facet_from_surface(facet); @@ -993,9 +1861,9 @@ -template +template void -Refine_facets_3:: +Refine_facets_3:: after_insertion_handle_incident_facet(Facet& facet) { // If the facet is infinite or has been already visited, diff -Nru cgal-4.4/include/CGAL/Mesh_3/Robust_weighted_circumcenter_filtered_traits_3.h cgal-4.5/include/CGAL/Mesh_3/Robust_weighted_circumcenter_filtered_traits_3.h --- cgal-4.4/include/CGAL/Mesh_3/Robust_weighted_circumcenter_filtered_traits_3.h 2014-04-03 19:00:30.000000000 +0000 +++ cgal-4.5/include/CGAL/Mesh_3/Robust_weighted_circumcenter_filtered_traits_3.h 2014-08-29 13:58:16.000000000 +0000 @@ -165,7 +165,8 @@ Bare_point operator() ( const Weighted_point_3 & p, const Weighted_point_3 & q, const Weighted_point_3 & r, - const Weighted_point_3 & s ) const + const Weighted_point_3 & s, + bool force_exact = false) const { CGAL_precondition(Rt().orientation_3_object()(p,q,r,s) == CGAL::POSITIVE); @@ -181,7 +182,7 @@ s.x(), s.y(), s.z(), s.weight(), num_x, num_y, num_z, den); - if ( ! CGAL_NTS is_zero(den) ) + if ( ! force_exact && ! CGAL_NTS is_zero(den) ) { FT inv = FT(1)/(FT(2) * den); Bare_point res(p.x() + num_x*inv, p.y() - num_y*inv, p.z() + num_z*inv); diff -Nru cgal-4.4/include/CGAL/Mesh_3/sliver_criteria.h cgal-4.5/include/CGAL/Mesh_3/sliver_criteria.h --- cgal-4.4/include/CGAL/Mesh_3/sliver_criteria.h 2014-03-29 20:00:20.000000000 +0000 +++ cgal-4.5/include/CGAL/Mesh_3/sliver_criteria.h 2014-08-29 13:58:16.000000000 +0000 @@ -154,7 +154,7 @@ public: Min_dihedral_angle_criterion(const double& sliver_bound, const Tr& tr) - : Base(sliver_bound, tr) + : Base(sliver_bound, tr), min_value_before_move_(0.) {} private: diff -Nru cgal-4.4/include/CGAL/Mesh_3/Sliver_perturber.h cgal-4.5/include/CGAL/Mesh_3/Sliver_perturber.h --- cgal-4.4/include/CGAL/Mesh_3/Sliver_perturber.h 2014-02-08 20:00:27.000000000 +0000 +++ cgal-4.5/include/CGAL/Mesh_3/Sliver_perturber.h 2014-08-29 13:58:16.000000000 +0000 @@ -19,7 +19,7 @@ // Author(s) : Stephane Tayeb // //****************************************************************************** -// File Description : +// File Description : //****************************************************************************** #ifndef CGAL_MESH_3_SLIVER_PERTURBER_H @@ -46,6 +46,19 @@ #include #include #include +#include + +#include +#include + +#ifdef CGAL_CONCURRENT_MESH_3_PROFILING +# define CGAL_PROFILE +# include +#endif + +#ifdef CGAL_LINKED_WITH_TBB +# include +#endif #include #ifdef CGAL_MESH_3_USE_RELAXED_HEAP @@ -56,35 +69,424 @@ #include #include #include +#include + +#include -#include +#include namespace CGAL { +namespace internal { namespace Mesh_3 { + + // Hash function for boost::unordered_map + template + struct VHash + { + typedef typename Tr::Vertex_handle Vertex_handle; + std::size_t operator()(Vertex_handle vh) const + { + return vh->time_stamp(); + } + }; + template + struct VHash + { + typedef typename Tr::Vertex_handle Vertex_handle; + std::size_t operator()(Vertex_handle vh) const + { + return boost::hash_value(&*vh); + } + }; +}} // end internal::Mesh_3 + namespace Mesh_3 { - + + +/** +* @class PVertex +* Vertex with associated perturbation datas +*/ +// Sequential +template< typename FT + , typename Vertex_handle + , typename Point_3 + , typename SliverCriterion + , typename Perturbation + , typename Concurrency_tag> +class PVertex_ +{ +public: +typedef PVertex_ Self; +typedef std::size_t id_type; + +/// Constructor +PVertex_() +: vertex_handle_() +, incident_sliver_nb_(0) +, min_value_((std::numeric_limits::max)()) +, try_nb_(0) +, p_perturbation_(NULL) +, id_() +{ } + +PVertex_(const Vertex_handle& vh, id_type id) +: vertex_handle_(vh) +, incident_sliver_nb_(0) +, min_value_((std::numeric_limits::max)()) +, try_nb_(0) +, p_perturbation_(NULL) +, id_(id) +{ } + +/// Associated vertex +const Vertex_handle& vertex() const { return vertex_handle_; } +void set_vertex(const Vertex_handle& vh) { vertex_handle_ = vh; } + +/// Incident slivers number +unsigned int sliver_nb() const { return incident_sliver_nb_; } +void set_sliver_nb(const unsigned int n) { incident_sliver_nb_ = n; } + +/// Current perturbation +const Perturbation* perturbation() const { return p_perturbation_; } +void set_perturbation(const Perturbation* p) { p_perturbation_ = p; } + +/// Is perturbable +bool is_perturbable() const +{ + return ( (vertex_handle_->in_dimension() > 1) + && (NULL != perturbation()) + && (sliver_nb() != 0) ); +} + +/// Min sliver value +const FT& min_value() const { return min_value_; } +void set_min_value(const FT& min_value){ min_value_ = min_value; } + +/// Try nb +const unsigned int& try_nb() const { return try_nb_; } +void set_try_nb(const unsigned int& try_nb) { try_nb_ = try_nb; } +void increment_try_nb() { ++try_nb_; } + +/// Id +void set_id(const id_type& id) { id_ = id; } +id_type id() const { return id_; } + +/// Operators +bool operator==(const Self& pv) const { return ( id() == pv.id() ); } + +bool operator<(const Self& pv) const +{ + // vertex type (smallest-interior first) + if ( vertex()->in_dimension() != pv.vertex()->in_dimension() ) + return vertex()->in_dimension() > pv.vertex()->in_dimension(); + // nb incident slivers (smallest first) + else if ( sliver_nb() != pv.sliver_nb() ) + return sliver_nb() < pv.sliver_nb(); + // min angle (smallest first) + else if ( min_value() != pv.min_value() ) + return min_value() < pv.min_value(); + // try nb (smallest first) + else if ( try_nb() != pv.try_nb() ) + return try_nb() < pv.try_nb(); + // perturbation type (smallest first) + else if ( perturbation() != pv.perturbation() ) + return *perturbation() < *pv.perturbation(); + return ( id() < pv.id() ); // all characteristics are the same! +} + +/// Dummy functions +void update_saved_erase_counter() {} +bool is_zombie() { return false; } + +private: +/// Private datas +Vertex_handle vertex_handle_; +unsigned int incident_sliver_nb_; +FT min_value_; +unsigned int try_nb_; +const Perturbation* p_perturbation_; +id_type id_; +}; + +#ifdef CGAL_LINKED_WITH_TBB +// Parallel +template< typename FT + , typename Vertex_handle + , typename Point_3 + , typename SliverCriterion + , typename Perturbation> +class PVertex_ +{ +public: +typedef PVertex_ Self; +typedef std::size_t id_type; + +/// Constructor +PVertex_() +: vertex_handle_() +, in_dimension_(-1) +, incident_sliver_nb_(0) +, min_value_((std::numeric_limits::max)()) +, try_nb_(0) +, p_perturbation_(NULL) +, id_() +{ } + +PVertex_(const Vertex_handle& vh, id_type id) +: vertex_handle_(vh) +, vh_erase_counter_when_added_(vh->erase_counter()) +, in_dimension_(vh->in_dimension()) +, incident_sliver_nb_(0) +, min_value_((std::numeric_limits::max)()) +, try_nb_(0) +, p_perturbation_(NULL) +, id_(id) +{ } + +/// Associated vertex +const Vertex_handle& vertex() const { return vertex_handle_; } +void set_vertex(const Vertex_handle& vh) +{ + vertex_handle_ = vh; + update_saved_erase_counter(); +} +void update_saved_erase_counter() +{ + vh_erase_counter_when_added_ = vertex_handle_->erase_counter(); +} + +int in_dimension() const { return in_dimension_; } + +/// Incident slivers number +unsigned int sliver_nb() const { return incident_sliver_nb_; } +void set_sliver_nb(const unsigned int n) { incident_sliver_nb_ = n; } + +/// Current perturbation +const Perturbation* perturbation() const { return p_perturbation_; } +void set_perturbation(const Perturbation* p) { p_perturbation_ = p; } + +/// Is perturbable +bool is_perturbable() const +{ + return ( (vertex_handle_->in_dimension() > 1) + && (NULL != perturbation()) + && (sliver_nb() != 0) ); +} + +/// Min sliver value +const FT& min_value() const { return min_value_; } +void set_min_value(const FT& min_value){ min_value_ = min_value; } + +/// Try nb +const unsigned int& try_nb() const { return try_nb_; } +void set_try_nb(const unsigned int& try_nb) { try_nb_ = try_nb; } +void increment_try_nb() { ++try_nb_; } + +/// Id +void set_id(const id_type& id) { id_ = id; } +id_type id() const { return id_; } + +/// Zombie +bool is_zombie() const +{ + return vertex_handle_->erase_counter() != vh_erase_counter_when_added_; +} + +/// Operators +bool operator==(const Self& pv) const { return ( id() == pv.id() ); } + +bool operator<(const Self& pv) const +{ + // vertex type (smallest-interior first) + if ( in_dimension() != pv.in_dimension() ) + return in_dimension() > pv.in_dimension(); + // nb incident slivers (smallest first) + else if ( sliver_nb() != pv.sliver_nb() ) + return sliver_nb() < pv.sliver_nb(); + // min angle (smallest first) + else if ( min_value() != pv.min_value() ) + return min_value() < pv.min_value(); + // try nb (smallest first) + else if ( try_nb() != pv.try_nb() ) + return try_nb() < pv.try_nb(); + // perturbation type (smallest first) + else if ( perturbation() != pv.perturbation() ) + return *perturbation() < *pv.perturbation(); + return ( id() < pv.id() ); // all characteristics are the same! +} + +private: +/// Private datas +Vertex_handle vertex_handle_; +unsigned int vh_erase_counter_when_added_; +int in_dimension_; +unsigned int incident_sliver_nb_; +FT min_value_; +unsigned int try_nb_; +const Perturbation* p_perturbation_; +id_type id_; +}; +#endif + +/************************************************ +// Class Sliver_perturber_base +// Two versions: sequential / parallel +************************************************/ + +// Sequential +template +class Sliver_perturber_base +{ +protected: + typedef typename Tr::Vertex_handle Vertex_handle; + typedef typename Tr::Geom_traits Gt; + typedef typename Gt::FT FT; + typedef typename std::vector Bad_vertices_vector; + typedef typename Tr::Lock_data_structure Lock_data_structure; + + + Sliver_perturber_base(const Bbox_3 &, int) {} + + Lock_data_structure * + get_lock_data_structure() const { return 0; } + void unlock_all_elements() const {} + void create_root_task() const {} + bool flush_work_buffers() const { return true; } + void wait_for_all() const {} + void destroy_root_task() const {} + template + void enqueue_work(Func, const PVertex &) const {} + + void increment_erase_counter(const Vertex_handle &) const {} +}; + +#ifdef CGAL_LINKED_WITH_TBB +// Parallel +template +class Sliver_perturber_base +{ +protected: + typedef typename Tr::Vertex_handle Vertex_handle; + typedef typename Tr::Geom_traits Gt; + typedef typename Gt::FT FT; + typedef typename tbb::concurrent_vector Bad_vertices_vector; + typedef typename Tr::Lock_data_structure Lock_data_structure; + + Sliver_perturber_base(const Bbox_3 &bbox, int num_grid_cells_per_axis) + : m_lock_ds(bbox, num_grid_cells_per_axis) + , m_worksharing_ds(bbox) + { + } + + Lock_data_structure *get_lock_data_structure() const + { + return &m_lock_ds; + } + + void unlock_all_elements() const + { + m_lock_ds.unlock_all_points_locked_by_this_thread(); + } + + void create_root_task() const + { + m_empty_root_task = new( tbb::task::allocate_root() ) tbb::empty_task; + m_empty_root_task->set_ref_count(1); + } + + bool flush_work_buffers() const + { + m_empty_root_task->set_ref_count(1); + bool keep_flushing = m_worksharing_ds.flush_work_buffers(*m_empty_root_task); + wait_for_all(); + return keep_flushing; + } + + void wait_for_all() const + { + m_empty_root_task->wait_for_all(); + } + + void destroy_root_task() const + { + tbb::task::destroy(*m_empty_root_task); + m_empty_root_task = 0; + } + + template + void enqueue_work(Func f, const PVertex &pv) const + { + CGAL_assertion(m_empty_root_task != 0); + m_worksharing_ds.enqueue_work(f, pv, *m_empty_root_task); + } + + void increment_erase_counter(const Vertex_handle &vh) const + { + vh->increment_erase_counter(); + } + +public: + +protected: + mutable Lock_data_structure m_lock_ds; + mutable Mesh_3::Auto_worksharing_ds m_worksharing_ds; + mutable tbb::task *m_empty_root_task; +}; +#endif // CGAL_LINKED_WITH_TBB + + + +/************************************************ +// Class Sliver_perturber +************************************************/ + template < typename C3T3, typename MeshDomain, typename SliverCriterion = Mesh_3::Min_dihedral_angle_criterion , typename Visitor_ = Null_perturber_visitor > class Sliver_perturber +: public Sliver_perturber_base { + // Types + typedef typename C3T3::Concurrency_tag Concurrency_tag; + + typedef Sliver_perturber Self; + typedef Sliver_perturber_base< + typename C3T3::Triangulation, Concurrency_tag> Base; + typedef typename C3T3::Triangulation Tr; typedef typename Tr::Geom_traits Gt; - + typedef typename Tr::Cell_handle Cell_handle; - typedef typename Tr::Vertex_handle Vertex_handle; + typedef typename Base::Vertex_handle Vertex_handle; typedef typename Tr::Vertex Vertex; - + typedef typename MeshDomain::Point_3 Point_3; + typedef typename std::vector Cell_vector; typedef typename std::vector Vertex_vector; - + typedef typename Base::Bad_vertices_vector Bad_vertices_vector; + typedef typename Gt::FT FT; - + // Helper typedef class C3T3_helpers C3T3_helpers; - + + using Base::get_lock_data_structure; + // Visitor // Should define // - bound_reached(FT bound) @@ -95,112 +497,22 @@ public: typedef Abstract_perturbation Perturbation; typedef boost::ptr_vector Perturbation_vector; - + private: // Relaxed heap - // ----------------------------------- - // Private classes - // ----------------------------------- - /** - * @class PVertex - * Vertex with associated perturbation datas - */ - class PVertex - { - public: - typedef std::size_t id_type; - - /// Constructor - PVertex() - : vertex_handle_() - , incident_sliver_nb_(0) - , min_value_((std::numeric_limits::max)()) - , try_nb_(0) - , p_perturbation_(NULL) - , id_() - { } - - PVertex(const Vertex_handle& vh, id_type id) - : vertex_handle_(vh) - , incident_sliver_nb_(0) - , min_value_((std::numeric_limits::max)()) - , try_nb_(0) - , p_perturbation_(NULL) - , id_(id) - { } - - /// Associated vertex - const Vertex_handle& vertex() const { return vertex_handle_; } - void set_vertex(const Vertex_handle& vh) { vertex_handle_ = vh; } - - /// Incident slivers number - unsigned int sliver_nb() const { return incident_sliver_nb_; } - void set_sliver_nb(const unsigned int n) { incident_sliver_nb_ = n; } - - /// Current perturbation - const Perturbation* perturbation() const { return p_perturbation_; } - void set_perturbation(const Perturbation* p) { p_perturbation_ = p; } - - /// Is perturbable - bool is_perturbable() const - { - return ( (vertex_handle_->in_dimension() > 1) - && (NULL != perturbation()) - && (sliver_nb() != 0) ); - } - - /// Min sliver value - const FT& min_value() const { return min_value_; } - void set_min_value(const FT& min_value){ min_value_ = min_value; } - - /// Try nb - const unsigned int& try_nb() const { return try_nb_; } - void set_try_nb(const unsigned int& try_nb) { try_nb_ = try_nb; } - void increment_try_nb() { ++try_nb_; } - - /// Id - void set_id(const id_type& id) { id_ = id; } - id_type id() const { return id_; } - - /// Operators - bool operator==(const PVertex& pv) const { return ( id() == pv.id() ); } - - bool operator<(const PVertex& pv) const - { - // vertex type (smallest-interior first) - if ( vertex()->in_dimension() != pv.vertex()->in_dimension() ) - return vertex()->in_dimension() > pv.vertex()->in_dimension(); - // nb incident slivers (smallest first) - else if ( sliver_nb() != pv.sliver_nb() ) - return sliver_nb() < pv.sliver_nb(); - // min angle (smallest first) - else if ( min_value() != pv.min_value() ) - return min_value() < pv.min_value(); - // try nb (smallest first) - else if ( try_nb() != pv.try_nb() ) - return try_nb() < pv.try_nb(); - // perturbation type (smallest first) - else if ( perturbation() != pv.perturbation() ) - return *perturbation() < *pv.perturbation(); - return ( id() < pv.id() ); // all characteristics are the same! - } - - private: - /// Private datas - Vertex_handle vertex_handle_; - unsigned int incident_sliver_nb_; - FT min_value_; - unsigned int try_nb_; - const Perturbation* p_perturbation_; - id_type id_; - }; - - + + typedef PVertex_ PVertex; + /** * @class PVertex_id * relaxed heap */ - class PVertex_id : + class PVertex_id : public boost::put_get_helper { public: @@ -208,17 +520,17 @@ typedef typename PVertex::id_type value_type; typedef typename PVertex::id_type reference; typedef PVertex key_type; - + value_type operator[] (const key_type& pv) const { return pv.id(); } }; - + typedef std::less less_PVertex; #ifdef CGAL_MESH_3_USE_RELAXED_HEAP - typedef boost::relaxed_heap PQueue; + typedef boost::relaxed_heap PQueue; #else - typedef ::CGAL::internal::mutable_queue_with_remove, less_PVertex, PVertex_id> PQueue; + typedef ::CGAL::internal::mutable_queue_with_remove, less_PVertex, PVertex_id> PQueue; #endif //CGAL_MESH_3_USE_RELAXED_HEAP - + public: /** * Constructor @@ -226,7 +538,7 @@ Sliver_perturber(C3T3& c3t3, const MeshDomain& domain, const SliverCriterion& criterion); - + /** * @brief Launch perturbation * @param sliver_bound the bound the perturber will try to achieve @@ -234,39 +546,31 @@ * * Runs explicit perturbation. The goal is that for each tet of the mesh, * SliverCriterion(tet) > sliver_bound. - * The perturber runs step by step, using delta as step size. + * The perturber runs step by step, using delta as step size. */ Mesh_optimization_return_code operator()(Visitor visitor = Visitor()); - + /** * Adds a perturbation at the end of the perturbation queue - */ + */ void add_perturbation(Perturbation* perturbation); - + /// Time accessors void set_time_limit(double time) { time_limit_ = time; } double time_limit() const { return time_limit_; } - -private: - struct VHash - { - std::size_t operator()(Vertex_handle vh) const - { - return boost::hash_value(&*vh); - } - }; +private: // ----------------------------------- // Private methods // ----------------------------------- - + /** * One step perturbation: tries to achieve sliver_bound quality in the mesh */ - bool perturb(const FT& sliver_bound, PQueue& pqueue, Visitor& v) const; - + bool perturb(const FT& sliver_bound, PQueue& pqueue, Visitor& v) const; + /** * Builds priority queue. It will contain all vertices that have quality below * sliver_bound. @@ -275,19 +579,36 @@ * precondition: pqueue.empty() */ int build_priority_queue(const FT& sliver_bound, PQueue& pqueue) const; - + /** * Updates priority queue for all vertices of \c vertices */ + // Sequential int update_priority_queue(const Vertex_vector& vertices, const FT& sliver_bound, PQueue& pqueue) const; - +#ifdef CGAL_LINKED_WITH_TBB + // Parallel + int update_priority_queue( const Vertex_vector& vertices + , const FT& sliver_bound + , Visitor& visitor + , Bad_vertices_vector &bad_vertices) const; +#endif + /** * Updates \c pv in priority queue */ int update_priority_queue(const PVertex& pv, PQueue& pqueue) const; - + + // For parallel version + void + perturb_vertex( PVertex pv + , const FT& sliver_bound + , Visitor& visitor + , Bad_vertices_vector &bad_vertices + , bool *could_lock_zone + ) const; + /** * Returns a pvertex from a vertex handle \c vh, using id \c pv_id */ @@ -295,12 +616,18 @@ make_pvertex(const Vertex_handle& vh, const FT& sliver_bound, const typename PVertex::id_type& pv_id) const; - + PVertex + make_pvertex__concurrent( + const Vertex_handle& vh, + const FT& sliver_bound, + const typename PVertex::id_type& pv_id) const; + /** * Updates a pvertex \c pv */ void update_pvertex(PVertex& pv, const FT& sliver_bound) const; - + void update_pvertex__concurrent(PVertex& pv, const FT& sliver_bound) const; + /** * Returns \c vh pvertex id */ @@ -308,35 +635,105 @@ { return static_cast(vh->meshing_info()); } - + /** * Update bad vertices vector, wrt \c sliver_bound */ - void update_bad_vertices(Vertex_vector& bad_vertices, + // Sequential + void update_bad_vertices(std::vector &bad_vertices, const FT& sliver_bound) const; - +#ifdef CGAL_LINKED_WITH_TBB + // Parallel + void update_bad_vertices(tbb::concurrent_vector &bad_vertices, + const FT& sliver_bound) const; +#endif + /** * Initializes vertices ids */ void initialize_vertices_id() const; - + /** * Returns true if time_limit is reached */ bool is_time_limit_reached() const { - return ( (time_limit() > 0) && (running_time_.time() > time_limit()) ); + return ( (time_limit() > 0) && (running_time_.time() > time_limit()) ); } - - + + #ifdef CGAL_MESH_3_PERTURBER_VERBOSE /// Verbose mode methods void print_perturbations_statistics() const; void print_final_perturbations_statistics() const; void reset_perturbation_counters(); #endif - + +#ifdef CGAL_LINKED_WITH_TBB + // For parallel version + void + enqueue_task(const PVertex &pv, + const FT& sliver_bound, + Visitor& visitor, + Bad_vertices_vector &bad_vertices + ) const; +#endif + private: + +#ifdef CGAL_LINKED_WITH_TBB + + // Functor for enqueue_task function + template + class Perturb_vertex + { + const SP & m_sliver_perturber; + PVertex m_pv; + FT m_sliver_bound; + Visitor & m_visitor; + Bad_vertices_vector_ & m_bad_vertices; + + public: + // Constructor + Perturb_vertex(const SP &sp, + const PVertex &pv, + FT sliver_bound, + Visitor& visitor, + Bad_vertices_vector_ &bad_vertices) + : m_sliver_perturber(sp), + m_pv(pv), + m_sliver_bound(sliver_bound), + m_visitor(visitor), + m_bad_vertices(bad_vertices) + { + } + + // Constructor + Perturb_vertex(const Perturb_vertex &pvx) + : m_sliver_perturber(pvx.m_sliver_perturber), + m_pv(pvx.m_pv), + m_sliver_bound(pvx.m_sliver_bound), + m_visitor(pvx.m_visitor), + m_bad_vertices(pvx.m_bad_vertices) + {} + + // operator() + void operator()() const + { + bool could_lock_zone; + do + { + m_sliver_perturber.perturb_vertex( + m_pv, m_sliver_bound, m_visitor, m_bad_vertices, &could_lock_zone); + m_sliver_perturber.unlock_all_elements(); + } while (!could_lock_zone); + + if ( m_sliver_perturber.is_time_limit_reached() ) + tbb::task::self().cancel_group_execution(); + } + }; +#endif + // ----------------------------------- // Private data // ----------------------------------- @@ -346,38 +743,43 @@ SliverCriterion sliver_criterion_; Perturbation_vector perturbation_vector_; C3T3_helpers helper_; - + // Internal perturbation ordering int next_perturbation_order_; - + // Timer double time_limit_; CGAL::Timer running_time_; }; - - - - - - - + + + + + + + template Sliver_perturber:: Sliver_perturber(C3T3& c3t3, const Md& domain, const Sc& criterion) - : c3t3_(c3t3) + : Base(c3t3.bbox(), + Concurrent_mesher_config::get().locking_grid_num_cells_per_axis) + , c3t3_(c3t3) , tr_(c3t3_.triangulation()) , domain_(domain) , sliver_criterion_(criterion) - , helper_(c3t3_,domain_) + , helper_(c3t3_,domain_,get_lock_data_structure()) , next_perturbation_order_(0) , time_limit_(-1) - , running_time_() -{} - - - + , running_time_() +{ + // If we're multi-thread + tr_.set_lock_data_structure(get_lock_data_structure()); +} + + + template Mesh_optimization_return_code Sliver_perturber:: @@ -385,31 +787,38 @@ { //check criterion bound if ( sliver_criterion_.sliver_bound() == 0 ) - sliver_criterion_.set_sliver_bound(Sc::default_value); + sliver_criterion_.set_sliver_bound(Sc::default_value); // Reset sliver value cache helper_.reset_cache(); - + // Init time counter + if (running_time_.is_running()) + running_time_.stop(); running_time_.reset(); running_time_.start(); - + +#ifdef CGAL_MESH_3_PROFILING + WallClockTimer t; +#endif + // Build priority queue (we use one queue for all steps) PQueue pqueue(tr_.number_of_vertices()); // Initialize vertices ids initialize_vertices_id(); - - -#ifdef CGAL_MESH_3_PERTURBER_VERBOSE + + +#if defined(CGAL_MESH_3_PERTURBER_VERBOSE) \ + || defined(CGAL_MESH_3_PROFILING) std::cerr << "Running sliver perturbation..." << std::endl; #endif - + #ifdef CGAL_MESH_3_PERTURBER_LOW_VERBOSITY std::cerr << "Legend of the following line: " << "(#vertices in pqueue, #iterations, #fails)" << std::endl; #endif - + const FT& delta = sliver_criterion_.get_perturbation_unit(); FT current_bound = delta; bool perturbation_ok = true; @@ -418,51 +827,78 @@ #ifdef CGAL_MESH_3_PERTURBER_HIGH_VERBOSITY // reset_perturbation_counters is not const reset_perturbation_counters(); -#endif +#endif perturbation_ok = perturb(current_bound, pqueue, visitor); - + visitor.bound_reached(current_bound); - + current_bound += delta; if ( (current_bound >= sliver_criterion_.sliver_bound()) && (current_bound < sliver_criterion_.sliver_bound() + delta) ) - { + { current_bound = sliver_criterion_.sliver_bound(); } } - + +#ifdef CGAL_MESH_3_PROFILING + double perturbation_time = t.elapsed(); +#endif + running_time_.stop(); helper_.reset_cache();//in case we re-use caches in another operation // after this perturbation - + #ifdef CGAL_MESH_3_PERTURBER_VERBOSE std::cerr << std::endl << "Total perturbation time: " << running_time_.time() << "s"; std::cerr << std::endl << "Perturbation statistics:" << std::endl; print_final_perturbations_statistics(); #endif - + +#ifdef CGAL_MESH_3_PROFILING + std::cerr << std::endl << "Total perturbation 'wall-clock' time: " + << perturbation_time << "s" << std::endl; +#endif + + Mesh_optimization_return_code ret; + if ( is_time_limit_reached() ) { -#ifdef CGAL_MESH_3_PERTURBER_VERBOSE +#if defined(CGAL_MESH_3_PERTURBER_VERBOSE) || defined(CGAL_MESH_3_PROFILING) std::cerr << "Perturbation return code: TIME_LIMIT_REACHED\n\n"; #endif // CGAL_MESH_3_PERTURBER_VERBOSE - return TIME_LIMIT_REACHED; + ret = TIME_LIMIT_REACHED; } - - if ( !perturbation_ok ) { -#ifdef CGAL_MESH_3_PERTURBER_VERBOSE + else if ( !perturbation_ok ) { +#if defined(CGAL_MESH_3_PERTURBER_VERBOSE) || defined(CGAL_MESH_3_PROFILING) std::cerr << "Perturbation return code: CANT_IMPROVE_ANYMORE\n\n"; #endif // CGAL_MESH_3_PERTURBER_VERBOSE - return CANT_IMPROVE_ANYMORE; + ret = CANT_IMPROVE_ANYMORE; } -#ifdef CGAL_MESH_3_PERTURBER_VERBOSE - std::cerr << "Perturbation return code: BOUND_REACHED\n\n"; + else + { +#if defined(CGAL_MESH_3_PERTURBER_VERBOSE) || defined(CGAL_MESH_3_PROFILING) + std::cerr << "Perturbation return code: BOUND_REACHED\n\n"; #endif // CGAL_MESH_3_PERTURBER_VERBOSE - return BOUND_REACHED; + ret = BOUND_REACHED; + } + +#if defined(CGAL_MESH_3_EXPORT_PERFORMANCE_DATA) \ + && defined(CGAL_MESH_3_PROFILING) + if (ret == BOUND_REACHED) + { + CGAL_MESH_3_SET_PERFORMANCE_DATA("Perturber_optim_time", perturbation_time); + } + else + { + CGAL_MESH_3_SET_PERFORMANCE_DATA("Perturber_optim_time", + (ret == CANT_IMPROVE_ANYMORE ? + "CANT_IMPROVE_ANYMORE" : "TIME_LIMIT_REACHED")); + } +#endif + + return ret; } - - template void Sliver_perturber:: @@ -470,25 +906,25 @@ { if ( !perturbation_vector_.empty() ) perturbation_vector_.back().set_next(perturbation); - + if ( NULL != perturbation ) { // Set order perturbation->set_order(next_perturbation_order_++); - + // Add perturbation perturbation_vector_.push_back(perturbation); } -} - - - - +} + + + + // ----------------------------------- // Private methods -// ----------------------------------- +// ----------------------------------- template -bool +bool Sliver_perturber:: perturb(const FT& sliver_bound, PQueue& pqueue, Visitor& visitor) const { @@ -496,18 +932,18 @@ CGAL::Timer timer; timer.start(); std::streamsize prec = std::cerr.precision(4); - std::cerr << "Perturb sliver vertices (bound: " << sliver_bound + std::cerr << "Perturb sliver vertices (bound: " << sliver_bound << ") ..." << std::endl; std::cerr.precision(prec); #endif - + // build priority queue int pqueue_size = build_priority_queue(sliver_bound, pqueue); - + #ifdef CGAL_MESH_3_PERTURBER_HIGH_VERBOSITY std::cerr << "Legend of the following line: " << "(#vertices in pqueue, #iterations, #fails)" << std::endl; - + // Store construction time timer.stop(); double construction_time = timer.time(); @@ -515,125 +951,160 @@ timer.start(); #endif -#ifdef CGAL_MESH_3_PERTURBER_VERBOSE - int iteration_nb = 0; -#endif - // Stores the vertices for which perturbation has failed - Vertex_vector bad_vertices; - - while ( !is_time_limit_reached() && !pqueue.empty() ) - { - // Get pqueue head - PVertex pv = pqueue.top(); - pqueue.pop(); - --pqueue_size; - - CGAL_assertion(pv.is_perturbable()); - - // Get pvertex slivers list -#ifdef CGAL_NEW_INCIDENT_SLIVERS - Cell_vector slivers; - helper_.new_incident_slivers(pv.vertex(), sliver_criterion_, sliver_bound, - std::back_inserter(slivers)); -#else - Cell_vector slivers = - helper_.incident_slivers(pv.vertex(), sliver_criterion_, sliver_bound); -#endif + Bad_vertices_vector bad_vertices; - CGAL_assertion(slivers.size() == pv.sliver_nb()); - - // Perturb vertex - Vertex_vector modified_vertices; - - // pv.perturbation() should not be NULL if pv is in pqueue - CGAL_assertion(pv.perturbation() != NULL); - - std::pair perturbation_ok = - pv.perturbation()->operator()(pv.vertex(), - slivers, - c3t3_, - domain_, - sliver_criterion_, - sliver_bound, - modified_vertices); - - // If vertex has changed - may happen in two cases: vertex has been moved - // or vertex has been reverted to the same location - - if ( perturbation_ok.second != pv.vertex() ) - { - // Update pvertex vertex - pv.set_vertex(perturbation_ok.second); - } - - // If v has been moved - if ( perturbation_ok.first ) - { - // Update pvertex - update_pvertex(pv,sliver_bound); - - // If pv needs to be modified again, try first perturbation - pv.set_perturbation(&perturbation_vector_.front()); - pv.increment_try_nb(); - - // update modified vertices - pqueue_size += update_priority_queue(modified_vertices, - sliver_bound, - pqueue); +#ifdef CGAL_LINKED_WITH_TBB + // Parallel + if (boost::is_convertible::value) + { + this->create_root_task(); + + while (pqueue.size() > 0) + { + PVertex pv = pqueue.top(); + pqueue.pop(); + enqueue_task(pv, sliver_bound, + visitor, bad_vertices); } - else + + this->wait_for_all(); + +# if defined(CGAL_MESH_3_PERTURBER_VERBOSE) || defined(CGAL_MESH_3_PROFILING) + std::cerr << " Flushing"; +# endif + bool keep_flushing = true; + while (keep_flushing) { - // If perturbation fails, try next one - pv.set_perturbation(pv.perturbation()->next()); - - if ( NULL == pv.perturbation() ) + keep_flushing = this->flush_work_buffers(); +# if defined(CGAL_MESH_3_PERTURBER_VERBOSE) || defined(CGAL_MESH_3_PROFILING) + std::cerr << "."; +# endif + } + + this->destroy_root_task(); + } + // Sequential + else +#endif // CGAL_LINKED_WITH_TBB + { +# ifdef CGAL_MESH_3_PERTURBER_VERBOSE + int iteration_nb = 0; +# endif + + while ( !is_time_limit_reached() && !pqueue.empty() ) + { + // Get pqueue head + PVertex pv = pqueue.top(); + pqueue.pop(); + --pqueue_size; + + CGAL_assertion(pv.is_perturbable()); + + // Get pvertex slivers list +# ifdef CGAL_NEW_INCIDENT_SLIVERS + Cell_vector slivers; + helper_.new_incident_slivers(pv.vertex(), sliver_criterion_, sliver_bound, + std::back_inserter(slivers)); +# else + Cell_vector slivers = + helper_.incident_slivers(pv.vertex(), sliver_criterion_, sliver_bound); +# endif + + CGAL_assertion(slivers.size() == pv.sliver_nb()); + + // Perturb vertex + Vertex_vector modified_vertices; + + // pv.perturbation() should not be NULL if pv is in pqueue + CGAL_assertion(pv.perturbation() != NULL); + + std::pair perturbation_ok = + pv.perturbation()->operator()(pv.vertex(), + slivers, + c3t3_, + domain_, + sliver_criterion_, + sliver_bound, + modified_vertices); + + // If vertex has changed - may happen in two cases: vertex has been moved + // or vertex has been reverted to the same location - + if ( perturbation_ok.second != pv.vertex() ) + { + // Update pvertex vertex + pv.set_vertex(perturbation_ok.second); + } + + // If v has been moved + if ( perturbation_ok.first ) + { + // Update pvertex + update_pvertex(pv,sliver_bound); + + // If pv needs to be modified again, try first perturbation + pv.set_perturbation(&perturbation_vector_.front()); + pv.increment_try_nb(); + + // update modified vertices + pqueue_size += update_priority_queue(modified_vertices, + sliver_bound, + pqueue); + } + else { - bad_vertices.push_back(pv.vertex()); + // If perturbation fails, try next one + pv.set_perturbation(pv.perturbation()->next()); + + if ( NULL == pv.perturbation() ) + { + bad_vertices.push_back(pv.vertex()); + } } + + // Update pqueue in every cases, because pv was poped + pqueue_size += update_priority_queue(pv, pqueue); + visitor.end_of_perturbation_iteration(pqueue_size); + +# ifdef CGAL_MESH_3_PERTURBER_HIGH_VERBOSITY + ++iteration_nb; + std::cerr << boost::format("\r \r" + "(%1%,%2%,%4%) (%|3$.1f| iteration/s)") + % pqueue_size + % iteration_nb + % (iteration_nb / timer.time()) + % bad_vertices.size(); +# endif + +# ifdef CGAL_MESH_3_PERTURBER_LOW_VERBOSITY + ++iteration_nb; + std::cerr << boost::format("\r \r" + "bound %5%: (%1%,%2%,%4%) (%|3$.1f| iteration/s)") + % pqueue_size + % iteration_nb + % (iteration_nb / running_time_.time()) + % bad_vertices.size() + % sliver_bound; +# endif } - - // Update pqueue in every cases, because pv was poped - pqueue_size += update_priority_queue(pv, pqueue); - visitor.end_of_perturbation_iteration(pqueue_size); - -#ifdef CGAL_MESH_3_PERTURBER_HIGH_VERBOSITY - ++iteration_nb; - std::cerr << boost::format("\r \r" - "(%1%,%2%,%4%) (%|3$.1f| iteration/s)") - % pqueue_size - % iteration_nb - % (iteration_nb / timer.time()) - % bad_vertices.size(); -#endif - -#ifdef CGAL_MESH_3_PERTURBER_LOW_VERBOSITY - ++iteration_nb; - std::cerr << boost::format("\r \r" - "bound %5%: (%1%,%2%,%4%) (%|3$.1f| iteration/s)") - % pqueue_size - % iteration_nb - % (iteration_nb / running_time_.time()) - % bad_vertices.size() - % sliver_bound; -#endif } - + #ifdef CGAL_MESH_3_PERTURBER_HIGH_VERBOSITY std::cerr << std::endl; print_perturbations_statistics(); std::cerr << "Step perturbation time: " << timer.time() + construction_time - << "s" << std::endl << std::endl; + << "s" << std::endl << std::endl; #endif - + if ( is_time_limit_reached() ) return false; - + // update bad vertices list (remove those which are not bad anymore) update_bad_vertices(bad_vertices,sliver_bound); return bad_vertices.empty(); } - - + + #ifdef CGAL_FASTER_BUILD_QUEUE template @@ -642,7 +1113,7 @@ build_priority_queue(const FT& sliver_bound, PQueue& pqueue) const { CGAL_precondition(pqueue.empty()); - + #ifdef CGAL_MESH_3_PERTURBER_HIGH_VERBOSITY CGAL::Timer timer; timer.start(); @@ -651,7 +1122,12 @@ int pqueue_size = 0; - typedef boost::unordered_map M; + typedef typename std::iterator_traits::value_type Vertex; + typedef CGAL::internal::Has_timestamp Vertex_has_timestamp; + using CGAL::internal::Mesh_3::VHash; + typedef VHash Hash_fct; + typedef boost::unordered_map M; + M vpm; for ( typename Tr::Finite_cells_iterator cit = tr_.finite_cells_begin(); cit != tr_.finite_cells_end() ; @@ -670,8 +1146,8 @@ pv.set_sliver_nb(1); pv.set_min_value(d); pv.set_perturbation(&perturbation_vector_.front()); - } - else + } + else { pv.set_sliver_nb(pv.sliver_nb()+1); if(d < pv.min_value()) @@ -684,25 +1160,25 @@ for( typename M::iterator vit = vpm.begin(); vit != vpm.end() ; ++vit ) - pqueue_size += update_priority_queue(vit->second, pqueue); - + pqueue_size += update_priority_queue(vit->second, pqueue); + #ifdef CGAL_MESH_3_PERTURBER_HIGH_VERBOSITY std::cerr << "done (" << pqueue_size << " vertices inserted in " << timer.time() << "s)\n"; #endif - + return pqueue_size; } - + #else // not CGAL_FASTER_BUILD_QUEUE - + template int Sliver_perturber:: build_priority_queue(const FT& sliver_bound, PQueue& pqueue) const { CGAL_precondition(pqueue.empty()); - + #ifdef CGAL_MESH_3_PERTURBER_HIGH_VERBOSITY CGAL::Timer timer; timer.start(); @@ -710,25 +1186,25 @@ #endif int pqueue_size = 0; - + for ( typename Tr::Finite_vertices_iterator vit = tr_.finite_vertices_begin(); vit != tr_.finite_vertices_end() ; ++vit ) { PVertex pv = make_pvertex(vit, sliver_bound, get_pvertex_id(vit)); - pqueue_size += update_priority_queue(pv, pqueue); + pqueue_size += update_priority_queue(pv, pqueue); } - + #ifdef CGAL_MESH_3_PERTURBER_HIGH_VERBOSITY std::cerr << "done (" << pqueue_size << " vertices inserted in " << timer.time() << "s)\n"; #endif - + return pqueue_size; } -#endif // not CGAL_FASTER_BUILD_QUEUE +#endif // not CGAL_FASTER_BUILD_QUEUE + - template int Sliver_perturber:: @@ -744,11 +1220,37 @@ PVertex pv = make_pvertex(*vit,sliver_bound,get_pvertex_id(*vit)); modified_pv_nb += update_priority_queue(pv, pqueue); } - + return modified_pv_nb; } +#ifdef CGAL_LINKED_WITH_TBB +// For parallel version +template +int +Sliver_perturber:: +update_priority_queue( const Vertex_vector& vertices + , const FT& sliver_bound + , Visitor& visitor + , Bad_vertices_vector &bad_vertices) const +{ + int modified_pv_nb = 0; + for ( typename Vertex_vector::const_iterator vit = vertices.begin() ; + vit != vertices.end() ; + ++vit ) + { + PVertex pv = make_pvertex__concurrent(*vit,sliver_bound,get_pvertex_id(*vit)); + if (pv.is_perturbable()) + { + enqueue_task(pv, sliver_bound, visitor, bad_vertices); + ++modified_pv_nb; + } + } + + return modified_pv_nb; +} +#endif template int @@ -776,11 +1278,157 @@ return 1; } } - + return 0; } +#ifdef CGAL_LINKED_WITH_TBB +// For parallel version +template +void +Sliver_perturber:: +perturb_vertex( PVertex pv + , const FT& sliver_bound + , Visitor& visitor + , Bad_vertices_vector &bad_vertices + , bool *could_lock_zone + ) const +{ +#ifdef CGAL_CONCURRENT_MESH_3_PROFILING + static Profile_branch_counter_3 bcounter( + "early withdrawals / late withdrawals / successes [Perturber]"); +#endif + + *could_lock_zone = true; + + // Zombie? + if (pv.is_zombie()) + { + return; + } + + Point_3 p = pv.vertex()->point(); + if (!helper_.try_lock_point_no_spin(p) || p != pv.vertex()->point()) + { +#ifdef CGAL_CONCURRENT_MESH_3_PROFILING + bcounter.increment_branch_2(); // THIS is an early withdrawal! +#endif + *could_lock_zone = false; + return; + } + + // Zombie? (in case the vertex has changed in the meantime) + if (pv.is_zombie()) + { + return; + } + + CGAL_assertion(pv.is_perturbable()); + + int num_new_vertices_to_treat = 0; + + Cell_vector slivers; + slivers.reserve(8); + if (!helper_.try_lock_and_get_incident_slivers( + pv.vertex(), sliver_criterion_, sliver_bound, slivers)) + { + *could_lock_zone = false; +#ifdef CGAL_CONCURRENT_MESH_3_PROFILING + bcounter.increment_branch_1(); // THIS is a late withdrawal! +#endif + } + else + { + // Slivers may be empty if the vertex has been modified by another thread in the meatime + if (slivers.empty()) + { + return; + } + + // Perturb vertex + Vertex_vector modified_vertices; + + // pv.perturbation() should not be NULL if pv is in pqueue + CGAL_assertion(pv.perturbation() != NULL); + + std::pair perturbation_ok = + pv.perturbation()->operator()(pv.vertex(), + slivers, + c3t3_, + domain_, + sliver_criterion_, + sliver_bound, + modified_vertices, + could_lock_zone); + + if (*could_lock_zone) + { + // If vertex has changed - may happen in two cases: vertex has been moved + // or vertex has been reverted to the same location - + if ( perturbation_ok.second != pv.vertex() ) + { + // Update pvertex vertex + pv.set_vertex(perturbation_ok.second); + } + // If the vertex hasn't changed, we still need to "virtually" increment + // the erase counter, because we need to invalidate the PVertex that + // may be in other threads' queues + else + { + this->increment_erase_counter(pv.vertex()); + } + + // If v has been moved + if ( perturbation_ok.first ) + { + // Update pvertex + update_pvertex__concurrent(pv,sliver_bound); + + // If pv needs to be modified again, try first perturbation + pv.set_perturbation(&perturbation_vector_.front()); + pv.increment_try_nb(); + + // update modified vertices + num_new_vertices_to_treat += + update_priority_queue(modified_vertices, sliver_bound, visitor, bad_vertices); + } + else + { + // If perturbation fails, try next one + pv.set_perturbation(pv.perturbation()->next()); + pv.update_saved_erase_counter(); + + if ( NULL == pv.perturbation() ) + { + bad_vertices.push_back(pv.vertex()); + } + } + +#ifdef CGAL_CONCURRENT_MESH_3_PROFILING + ++bcounter; +#endif + + // Update pqueue in every cases, because pv was poped + if (pv.is_perturbable()) + { + enqueue_task(pv, sliver_bound, visitor, bad_vertices); + ++num_new_vertices_to_treat; + } + } + else + { +#ifdef CGAL_CONCURRENT_MESH_3_PROFILING + bcounter.increment_branch_1(); // THIS is a late withdrawal! +#endif + } + } + + visitor.end_of_perturbation_iteration(0); +} +#endif + +// Sequential template typename Sliver_perturber::PVertex Sliver_perturber:: @@ -794,12 +1442,29 @@ PVertex pv(vh,pv_id); pv.set_perturbation(&perturbation_vector_.front()); update_pvertex(pv, sliver_bound); - + + return pv; +} + +// Parallel +template +typename Sliver_perturber::PVertex +Sliver_perturber:: +make_pvertex__concurrent( + const Vertex_handle& vh, + const FT& sliver_bound, + const typename PVertex::id_type& pv_id) const +{ + // Make pvertex in all cases + PVertex pv(vh,pv_id); + pv.set_perturbation(&perturbation_vector_.front()); + update_pvertex__concurrent(pv, sliver_bound); + return pv; } - - + +// Sequential template void Sliver_perturber:: @@ -812,19 +1477,35 @@ Cell_vector slivers = helper_.incident_slivers(pv.vertex(), sliver_criterion_, sliver_bound); #endif - + + pv.set_sliver_nb(static_cast(slivers.size())); + pv.set_min_value(helper_.min_sliver_value(slivers, sliver_criterion_)); +} + +#ifdef CGAL_LINKED_WITH_TBB +// Parallel +template +void +Sliver_perturber:: +update_pvertex__concurrent(PVertex& pv, const FT& sliver_bound) const +{ + Cell_vector slivers; + helper_.get_incident_slivers_without_using_tds_data( + pv.vertex(), sliver_criterion_, sliver_bound, slivers); + pv.set_sliver_nb(static_cast(slivers.size())); pv.set_min_value(helper_.min_sliver_value(slivers, sliver_criterion_)); } - - +#endif + +// Sequential template void Sliver_perturber:: -update_bad_vertices(Vertex_vector& bad_vertices, +update_bad_vertices(std::vector &bad_vertices, const FT& sliver_bound) const { - typename Vertex_vector::iterator vit = bad_vertices.begin(); + typename std::vector::iterator vit = bad_vertices.begin(); while ( vit != bad_vertices.end() ) { if ( tr_.is_vertex(*vit) @@ -833,26 +1514,51 @@ ++vit; } else - { + { vit = bad_vertices.erase(vit); } - } + } } - - + +#ifdef CGAL_LINKED_WITH_TBB +// Parallel +template +void +Sliver_perturber:: +update_bad_vertices(tbb::concurrent_vector &bad_vertices, + const FT& sliver_bound) const +{ + tbb::concurrent_vector tmpv; + + typename tbb::concurrent_vector::iterator vit + = bad_vertices.begin(); + while ( vit != bad_vertices.end() ) + { + if ( tr_.is_vertex(*vit) + && helper_.min_incident_value(*vit,sliver_criterion_) <= sliver_bound ) + { + tmpv.push_back(*vit); + } + ++vit; + } + bad_vertices.swap(tmpv); +} +#endif // CGAL_LINKED_WITH_TBB + + template void Sliver_perturber:: initialize_vertices_id() const { namespace bl = boost::lambda; - int cur_id = 0; - + int cur_id = 0; + std::for_each(tr_.finite_vertices_begin(), tr_.finite_vertices_end(), bl::bind(&Vertex::set_meshing_info, &bl::_1, bl::var(cur_id)++)); } - - + + #ifdef CGAL_MESH_3_PERTURBER_VERBOSE template void @@ -865,25 +1571,25 @@ { total_perturbation_nb += it->counter(); } - + if ( 0 == total_perturbation_nb ) { std::cerr << "No perturbation done at this step" << std::endl; - return; + return; } - + for ( it = perturbation_vector_.begin() ; it != perturbation_vector_.end() ; ++it ) { - std::cerr << it->perturbation_name() << ": " + std::cerr << it->perturbation_name() << ": " << (double)it->counter() / (double)total_perturbation_nb * 100. << "% (" << it->counter() << " in " << it->time() << "s)" << std::endl; } } - - + + template void @@ -896,25 +1602,25 @@ { total_perturbation_nb += it->total_counter(); } - + if ( 0 == total_perturbation_nb ) { std::cerr << "No perturbation done" << std::endl; - return; + return; } - + for ( it = perturbation_vector_.begin() ; it != perturbation_vector_.end() ; ++it ) { - std::cerr << it->perturbation_name() << ": " + std::cerr << it->perturbation_name() << ": " << (double)it->total_counter() / (double)total_perturbation_nb * 100. - << "% (" << it->total_counter() << " in " << it->total_time() << "s)" + << "% (" << it->total_counter() << " in " << it->total_time() << "ms)" << std::endl; } } - - + + template void @@ -926,12 +1632,29 @@ { it->reset_counter(); it->reset_timer(); - } + } } #endif - - - + + +#ifdef CGAL_LINKED_WITH_TBB +// For parallel version +template +void +Sliver_perturber:: +enqueue_task(const PVertex &pv, + const FT& sliver_bound, + Visitor& visitor, + Bad_vertices_vector &bad_vertices + ) const +{ + this->enqueue_work( + Perturb_vertex( + *this, pv, sliver_bound, visitor, bad_vertices), + pv); +} +#endif + } // end namespace Mesh_3 diff -Nru cgal-4.4/include/CGAL/Mesh_3/Slivers_exuder.h cgal-4.5/include/CGAL/Mesh_3/Slivers_exuder.h --- cgal-4.4/include/CGAL/Mesh_3/Slivers_exuder.h 2013-12-21 20:00:22.000000000 +0000 +++ cgal-4.5/include/CGAL/Mesh_3/Slivers_exuder.h 2014-08-29 13:58:16.000000000 +0000 @@ -37,6 +37,7 @@ #include #include #include +#include #include @@ -44,6 +45,15 @@ #include #include +#ifdef CGAL_CONCURRENT_MESH_3_PROFILING +# define CGAL_PROFILE +# include +#endif + +#ifdef CGAL_LINKED_WITH_TBB +# include +#endif + #ifdef CGAL_MESH_3_VERBOSE #define CGAL_MESH_3_EXUDER_VERBOSE @@ -51,15 +61,15 @@ namespace CGAL { - + namespace Mesh_3 { - + namespace details { // various function objects - + // That functor Second_of takes a pair as input (the value type of a // map), and returns the ".second" member of that pair. It is used in - // Sliver_exuder, to constructor a transform iterator. - + // Slivers_exuder, to constructor a transform iterator. + // It should be doable using STL bind operators, but i am not sure how // to use them. -- Laurent Rineau, 2007/07/27 template @@ -71,18 +81,18 @@ const typename Map::mapped_type&> Base; typedef typename Base::result_type result_type; typedef typename Base::argument_type argument_type; - + const typename Map::mapped_type& operator()(const typename Map::value_type& p) const { return p.second; } }; // end class Second_of - + // That function is constructed with a vertex handle v1. // Then, its operator() takes an other vertex handle v2 as input, and // returns the distance d(v1, v2). - // It is used in Sliver_exuder, to constructor a transform iterator. + // It is used in Slivers_exuder, to constructor a transform iterator. template class Min_distance_from_v : public std::unary_function @@ -98,7 +108,7 @@ : v(&vh), gt(geom_traits), dist(dist) { } - + void operator()(const Vertex_handle& vh) const { @@ -106,18 +116,248 @@ Compute_squared_distance_3; Compute_squared_distance_3 distance = gt.compute_squared_distance_3_object(); - + const double d = CGAL::to_double(distance((*v)->point(), vh->point())); if(d < dist){ dist = d; } } }; // end class Min_distance_from_v - + } // end namespace details - - - + + + +/************************************************ +// Class Slivers_exuder_base +// Two versions: sequential / parallel +************************************************/ + +// Sequential +template +class Slivers_exuder_base +{ +protected: + typedef typename Tr::Vertex_handle Vertex_handle; + typedef typename Tr::Cell_handle Cell_handle; + typedef std::vector Cell_vector; + typedef typename Tr::Geom_traits Gt; + typedef typename Gt::FT FT; + typedef typename std::vector Bad_vertices_vector; + typedef typename Tr::Lock_data_structure Lock_data_structure; + + // A priority queue ordered on Tet quality (SliverCriteria) + typedef CGAL::Double_map Tet_priority_queue; + typedef typename Tet_priority_queue::reverse_iterator Queue_iterator; + typedef typename Tet_priority_queue::Reverse_entry Queue_value_type; + + Slivers_exuder_base(const Bbox_3 &, int) {} + + Lock_data_structure * get_lock_data_structure() const { return 0; } + void unlock_all_elements() const {} + void create_root_task() const {} + bool flush_work_buffers() const { return true; } + void wait_for_all() const {} + void destroy_root_task() const {} + template + void enqueue_work(Func, double) const {} + +protected: + Cell_handle extract_cell_handle_from_queue_value(const Queue_value_type &qv) const + { + return qv.second; + } + double extract_cell_quality_from_queue_value(const Queue_value_type &qv) const + { + return qv.first; + } + unsigned int extract_erase_counter_from_queue_value(const Queue_value_type &) const + { + return 0; + } + + // Dummy + unsigned int erase_counter(const Cell_handle &) const { return 0;} + + std::size_t cells_queue_size() const { return cells_queue_.size(); } + bool cells_queue_empty() const { return cells_queue_.empty(); } + Queue_iterator + cells_queue_front() { return cells_queue_.front(); } + void cells_queue_pop_front() { cells_queue_.pop_front(); } + void cells_queue_clear() { cells_queue_.clear(); } + void cells_queue_insert(const Cell_handle &ch, double quality_value) + { + cells_queue_.insert(ch, quality_value); + } + + /** + * A functor to remove one \c Cell_handle from a priority queue + */ + class Erase_from_queue + { + public: + Erase_from_queue(Tet_priority_queue& queue) + : r_queue_(queue) { } + + void operator()(const Cell_handle& cell) + { r_queue_.erase(cell); } + + private: + Tet_priority_queue& r_queue_; + }; + + /** + * Delete cells of \c cells from \c cells_queue + */ + void delete_cells_from_queue(const Cell_vector& cells) + { + std::for_each(cells.begin(), cells.end(), + Erase_from_queue(cells_queue_)); + } + +private: + + Tet_priority_queue cells_queue_; +}; + +#ifdef CGAL_LINKED_WITH_TBB +// Parallel +template +class Slivers_exuder_base +{ +protected: + typedef typename Tr::Vertex_handle Vertex_handle; + typedef typename Tr::Cell_handle Cell_handle; + typedef std::vector Cell_vector; + typedef typename Tr::Geom_traits Gt; + typedef typename Gt::FT FT; + typedef typename tbb::concurrent_vector Bad_vertices_vector; + typedef typename Tr::Lock_data_structure Lock_data_structure; + + // A priority queue ordered on Tet quality (SliverCriteria) + typedef std::multimap< + double, std::pair > Tet_priority_queue; + typedef typename Tet_priority_queue::iterator Queue_iterator; + typedef typename Tet_priority_queue::value_type Queue_value_type; + + Slivers_exuder_base(const Bbox_3 &bbox, int num_grid_cells_per_axis) + : m_lock_ds(bbox, num_grid_cells_per_axis) + , m_worksharing_ds(bbox) + { + } + + Lock_data_structure *get_lock_data_structure() const + { + return &m_lock_ds; + } + + void unlock_all_elements() const + { + m_lock_ds.unlock_all_points_locked_by_this_thread(); + } + + void create_root_task() const + { + m_empty_root_task = new( tbb::task::allocate_root() ) tbb::empty_task; + m_empty_root_task->set_ref_count(1); + } + + bool flush_work_buffers() const + { + m_empty_root_task->set_ref_count(1); + bool keep_flushing = m_worksharing_ds.flush_work_buffers(*m_empty_root_task); + wait_for_all(); + return keep_flushing; + } + + void wait_for_all() const + { + m_empty_root_task->wait_for_all(); + } + + void destroy_root_task() const + { + tbb::task::destroy(*m_empty_root_task); + m_empty_root_task = 0; + } + + template + void enqueue_work(Func f, double value) const + { + CGAL_assertion(m_empty_root_task != 0); + m_worksharing_ds.enqueue_work(f, value, *m_empty_root_task); + } + +public: + +protected: + Cell_handle extract_cell_handle_from_queue_value(const Queue_value_type &qv) const + { + return qv.second.first; + } + double extract_cell_quality_from_queue_value(const Queue_value_type &qv) const + { + return qv.first; + } + unsigned int extract_erase_counter_from_queue_value(const Queue_value_type &qv) const + { + return qv.second.second; + } + + unsigned int erase_counter(const Cell_handle &ch) const + { + return ch->erase_counter(); + } + + std::size_t cells_queue_size() const { return cells_queue_.size(); } + bool cells_queue_empty() const { return cells_queue_.empty(); } + Queue_iterator + cells_queue_front() { return cells_queue_.begin(); } + void cells_queue_pop_front() { cells_queue_.erase(cells_queue_front()); } + void cells_queue_clear() { cells_queue_.clear(); } + void cells_queue_insert(const Cell_handle &ch, double quality_value) + { + cells_queue_.insert(std::make_pair( + quality_value, + std::make_pair(ch, ch->erase_counter()))); + } + + /** + * A functor to remove one \c Cell_handle from a priority queue + */ + class Erase_from_queue + { + public: + Erase_from_queue(Tet_priority_queue&) {} + + void operator()(const Cell_handle& cell) + { cell->increment_erase_counter(); } + }; + + /** + * Delete cells of \c cells from \c cells_queue + */ + void delete_cells_from_queue(const Cell_vector& cells) + { + std::for_each(cells.begin(), cells.end(), + Erase_from_queue(cells_queue_)); + } + + mutable Lock_data_structure m_lock_ds; + mutable Mesh_3::Auto_worksharing_ds m_worksharing_ds; + mutable tbb::task *m_empty_root_task; + +private: + + Tet_priority_queue cells_queue_; +}; +#endif // CGAL_LINKED_WITH_TBB + + +/************************************************ +// Class Slivers_exuder +************************************************/ + template < typename C3T3, typename SliverCriteria, @@ -125,8 +365,20 @@ typename FT = typename C3T3::Triangulation::Geom_traits::FT > class Slivers_exuder +: public Slivers_exuder_base { - // Types + +public: // Types + + typedef typename C3T3::Concurrency_tag Concurrency_tag; + typedef Slivers_exuder_base< + typename C3T3::Triangulation, Concurrency_tag> Base; + +private: // Types + + typedef Slivers_exuder Self; + typedef typename C3T3::Triangulation Tr; typedef typename Tr::Weighted_point Weighted_point; typedef typename Tr::Bare_point Bare_point; @@ -134,50 +386,49 @@ typedef typename Tr::Facet Facet; typedef typename Tr::Vertex_handle Vertex_handle; typedef typename Weighted_point::Weight Weight; - + typedef typename Base::Queue_value_type Queue_value_type; + typedef typename Base::Cell_vector Cell_vector; + typedef typename Tr::Geom_traits Geom_traits; typedef typename Geom_traits::Tetrahedron_3 Tetrahedron_3; - + typedef typename C3T3::Cells_in_complex_iterator Cell_iterator; - typedef std::vector Cell_vector; typedef std::vector Facet_vector; - + typedef typename C3T3::Surface_patch_index Surface_patch_index; typedef typename C3T3::Subdomain_index Subdomain_index; typedef typename C3T3::Index Index; - + // Umbrella will store the surface_index of internal facets of a new // weighted point conflict zone. Such facets are represented by their edge // which do not contain the pumped vertex typedef std::pair Ordered_edge; typedef std::map Umbrella; - + // Boundary_facets_from_outside represents the facet of the conflict zone // seen from outside of it. It stores Surface_patch_index of the facet, and - // Subdomain_index of the cell which is inside the conflict zone. + // Subdomain_index of the cell which is inside the conflict zone. typedef std::map > Boundary_facets_from_outside; - + /** Pre_star will represent the pre-star of a point. It is a (double)-map * of Facet (viewed from cells inside the star), ordered by the * critial_radius of the point with the cell that lies on the facet, at * the exterior of the pre-star. */ typedef CGAL::Double_map Pre_star; - + // Stores the value of facet for the sliver criterion functor typedef std::map Sliver_values; - - // A priority queue ordered on Tet quality (SliverCriteria) - typedef CGAL::Double_map Tet_priority_queue; - + // Visitor class // Should define // - after_cell_pumped(std::size_t cells_left_number) typedef Visitor_ Visitor; - + using Base::get_lock_data_structure; + public: // methods - + /** * @brief Constructor * @param c3t3 The mesh to exude @@ -188,7 +439,7 @@ Slivers_exuder(C3T3& c3t3, const SliverCriteria& criterion, double d = 0.45); - + /** * @brief pumps vertices * @param criterion_value_limit All vertices of tetrahedra that have a @@ -197,13 +448,39 @@ Mesh_optimization_return_code operator()(Visitor visitor = Visitor()) { - return pump_vertices(sliver_criteria_.sliver_bound(), visitor); +#ifdef CGAL_MESH_3_PROFILING + WallClockTimer t; +#endif + + Mesh_optimization_return_code ret = + pump_vertices(sliver_criteria_.sliver_bound(), visitor); + +#ifdef CGAL_MESH_3_PROFILING + double exudation_time = t.elapsed(); + std::cerr << std::endl << "==== Total exudation 'wall-clock' time: " + << exudation_time << "s ====" << std::endl; +#endif + +#ifdef CGAL_MESH_3_EXPORT_PERFORMANCE_DATA + if (ret == BOUND_REACHED) + { + CGAL_MESH_3_SET_PERFORMANCE_DATA("Exuder_optim_time", exudation_time); + } + else + { + CGAL_MESH_3_SET_PERFORMANCE_DATA("Exuder_optim_time", + (ret == CANT_IMPROVE_ANYMORE ? + "CANT_IMPROVE_ANYMORE" : "TIME_LIMIT_REACHED")); + } +#endif + + return ret; } - + /// Time accessors void set_time_limit(double time) { time_limit_ = time; } double time_limit() const { return time_limit_; } - + private: // ----------------------------------- // Private Methods @@ -214,25 +491,29 @@ template Mesh_optimization_return_code pump_vertices(double criterion_value_limit, Visitor& v); - + /** * Pump one vertex */ - bool pump_vertex(const Vertex_handle& v); - + template + bool pump_vertex(const Vertex_handle& v, + bool *could_lock_zone = NULL); + /** * Returns the best_weight of v */ - double get_best_weight(const Vertex_handle& v) const; - + double get_best_weight(const Vertex_handle& v, + bool *could_lock_zone = NULL) const; + /** * Initializes pre_star and criterion_values */ void initialize_prestar_and_criterion_values(const Vertex_handle& v, Pre_star& pre_star, - Sliver_values& criterion_values) const; - + Sliver_values& criterion_values, + bool *could_lock_zone = NULL) const; + /** * Expand pre_star with cell_to_add */ @@ -240,41 +521,44 @@ const Vertex_handle& pumped_vertex, Pre_star& pre_star, Sliver_values& criterion_values) const; - + /** * Returns Ordered_edge of facet which do not contains vertex */ Ordered_edge get_opposite_ordered_edge(const Facet& facet, const Vertex_handle& vertex) const; - + /** * Returns the umbrella of internal_facets vector */ Umbrella get_umbrella(const Facet_vector& internal_facets, const Vertex_handle& v) const; - + /** * Updates the mesh with new_point */ + template void update_mesh(const Weighted_point& new_point, - const Vertex_handle& old_vertex); - + const Vertex_handle& old_vertex, + bool *could_lock_zone = NULL); + /** * Restores cells and boundary facets of conflict zone of new_vertex in c3t3_ */ + template void restore_cells_and_boundary_facets( const Boundary_facets_from_outside& boundary_facets_from_outside, const Vertex_handle& new_vertex); - + /** * Restore internal facets of conflict zone of new_vertex in c3t3_ */ void restore_internal_facets(const Umbrella& umbrella, const Vertex_handle& new_vertex); - + /** * Orders handles \c h1 & \c h2 - */ + */ template static void order_two_handles(Handle& h1, Handle& h2) @@ -282,7 +566,7 @@ if( h2 < h1 ) std::swap(h1, h2); } - + /** * Initialization */ @@ -292,12 +576,12 @@ sliver_criteria_.set_sliver_bound(limit_value); else sliver_criteria_.set_sliver_bound(SliverCriteria::max_value); - - cells_queue_.clear(); + + this->cells_queue_clear(); initialize_cells_priority_queue(); initialized_ = true; } - + /** * Initialize cells_queue w.r.t sliver_bound_ */ @@ -307,14 +591,14 @@ cit != c3t3_.cells_in_complex_end() ; ++cit) { - const double value + const double value = sliver_criteria_(cit); if( value < sliver_criteria_.sliver_bound() ) - cells_queue_.insert(cit, value); + this->cells_queue_insert(cit, value); } } - + /** * Returns critical radius of (v,c) */ @@ -323,17 +607,17 @@ { typedef typename Geom_traits::Compute_critical_squared_radius_3 Critical_radius; - + Critical_radius critical_radius = tr_.geom_traits().compute_critical_squared_radius_3_object(); - + return CGAL::to_double(critical_radius(c->vertex(0)->point(), c->vertex(1)->point(), c->vertex(2)->point(), c->vertex(3)->point(), v->point())); } - + /** * Returns the squared distance from vh to its closest vertice */ @@ -345,23 +629,23 @@ min_distance_from_v(vh, dist); tr_.adjacent_vertices(vh, boost::make_function_output_iterator(min_distance_from_v)); - + return dist; } - - /** + + /** * Returns the min value of second element of Ratio */ double get_min_value(const Sliver_values& criterion_values) const { using boost::make_transform_iterator; typedef details::Second_of Second_of; - + return *(std::min_element( make_transform_iterator(criterion_values.begin(), Second_of()), make_transform_iterator(criterion_values.end(), Second_of()))); } - + /** * Returns the \c Boundary_facets_from_outside object containing mirror facets * of \c facets @@ -370,7 +654,7 @@ get_boundary_facets_from_outside(const Facet_vector& facets) const { Boundary_facets_from_outside boundary_facets_from_outside; - + for(typename Facet_vector::const_iterator fit = facets.begin(); fit != facets.end(); ++fit) @@ -380,34 +664,28 @@ std::make_pair(c3t3_.surface_patch_index(*fit), c3t3_.subdomain_index(fit->first)))); } - + return boundary_facets_from_outside; } - - /** - * A functor to remove one \c Cell_handle from a priority queue - */ - class Erase_from_queue - { - public: - Erase_from_queue(Tet_priority_queue& queue) - : r_queue_(queue) { } - - void operator()(const Cell_handle& cell) - { r_queue_.erase(cell); } - - private: - Tet_priority_queue& r_queue_; - }; - + /** - * Delete cells of \c cells from \c cells_queue + * Add a cell \c ch to \c cells_queue */ - void delete_cells_from_queue(const Cell_vector& cells) + template + void add_cell_to_queue(Cell_handle ch, double criterion_value) { - std::for_each(cells.begin(), cells.end(), Erase_from_queue(cells_queue_)); +#ifdef CGAL_LINKED_WITH_TBB + // Parallel + if (boost::is_convertible::value) + enqueue_task( + ch, this->erase_counter(ch), criterion_value); + // Sequential + else +#endif + this->cells_queue_insert(ch, criterion_value); + } - + /** * A functor to remove one handle (Cell_handle/Facet_handle) from complex */ @@ -416,15 +694,15 @@ public: Remove_from_complex(C3T3& c3t3) : c3t3_(c3t3) { } - + template void operator()(const Handle_& handle) { c3t3_.remove_from_complex(handle); } - + private: C3T3& c3t3_; }; - + /** * Removes objects of [begin,end[ range from \c c3t3_ */ @@ -433,15 +711,15 @@ { std::for_each(begin, end, Remove_from_complex(c3t3_)); } - + /** * Returns true if time_limit is reached */ bool is_time_limit_reached() const { - return ( (time_limit() > 0) && (running_time_.time() > time_limit()) ); + return ( (time_limit() > 0) && (running_time_.time() > time_limit()) ); } - + /** * Returns true if all cells of mesh have a sliver_criteria_ value greater * than sliver_bound_ @@ -452,36 +730,138 @@ cit != c3t3_.cells_in_complex_end() ; ++cit) { - const double value = + const double value = sliver_criteria_(cit); if( value < sliver_criteria_.sliver_bound() ) return false; } - + return true; } - + +#ifdef CGAL_LINKED_WITH_TBB + // For parallel version + template + void + enqueue_task(Cell_handle ch, unsigned int erase_counter, double value); +#endif + private: + + +#ifdef CGAL_LINKED_WITH_TBB + + // Functor for enqueue_task function + template + class Pump_vertex + { + SE & m_sliver_exuder; + const C3T3 & m_c3t3; + Cell_handle m_cell_handle; + unsigned int m_erase_counter; + + + public: + // Constructor + Pump_vertex(SE &sliver_exuder, + const C3T3 &c3t3, + Cell_handle cell_handle, + unsigned int erase_counter) + : m_sliver_exuder(sliver_exuder), + m_c3t3(c3t3), + m_cell_handle(cell_handle), + m_erase_counter(erase_counter) + { + } + + // Constructor + Pump_vertex(const Pump_vertex &pvx) + : m_sliver_exuder(pvx.m_sliver_exuder), + m_c3t3(pvx.m_c3t3), + m_cell_handle(pvx.m_cell_handle), + m_erase_counter(pvx.m_erase_counter) + {} + + // operator() + void operator()() const + { +#ifdef CGAL_CONCURRENT_MESH_3_PROFILING + static Profile_branch_counter_3 bcounter( + "early withdrawals / late withdrawals / successes [Exuder]"); +#endif + + for( int i = 0; i < 4; ++i ) + { + bool could_lock_zone; + do + { + could_lock_zone = true; + + if (m_sliver_exuder.erase_counter(m_cell_handle) != m_erase_counter) + break; + + if (!m_c3t3.triangulation().try_lock_cell(m_cell_handle)) + { +#ifdef CGAL_CONCURRENT_MESH_3_PROFILING + bcounter.increment_branch_2(); // THIS is an early withdrawal! +#endif + could_lock_zone = false; + m_sliver_exuder.unlock_all_elements(); + continue; + } + + if (m_sliver_exuder.erase_counter(m_cell_handle) != m_erase_counter) + { + m_sliver_exuder.unlock_all_elements(); + break; + } + + // pump_vertices_on_surfaces is a boolean template parameter. The + // following condition is pruned at compiled time, if + // pump_vertices_on_surfaces==false. + if (pump_vertices_on_surfaces + || m_c3t3.in_dimension(m_cell_handle->vertex(i)) > 2) + { + m_sliver_exuder.template pump_vertex( + m_cell_handle->vertex(i), &could_lock_zone); + +#ifdef CGAL_CONCURRENT_MESH_3_PROFILING + if (!could_lock_zone) + bcounter.increment_branch_1(); // THIS is a late withdrawal! + else + ++bcounter; // Success! +#endif + } + + m_sliver_exuder.unlock_all_elements(); + } while (!could_lock_zone); + } + + if ( m_sliver_exuder.is_time_limit_reached() ) + tbb::task::self().cancel_group_execution(); + } + }; +#endif + // ----------------------------------- // Private data // ----------------------------------- C3T3& c3t3_; Tr& tr_; double sq_delta_; - + int num_of_pumped_vertices_; int num_of_ignored_vertices_; int num_of_treated_vertices_; - + bool initialized_; SliverCriteria sliver_criteria_; - Tet_priority_queue cells_queue_; - + // Timer double time_limit_; CGAL::Timer running_time_; - + #ifdef CGAL_MESH_3_DEBUG_SLIVERS_EXUDER // ----------------------------------- // Debug Helpers @@ -493,9 +873,9 @@ static bool near_equal(const double& d1, const double& d2) { const double epsilon = 1e-8; - return ( ((d1-d2) >= -1*epsilon) && ((d1-d2) <= epsilon) ); + return ( ((d1-d2) >= -1*epsilon) && ((d1-d2) <= epsilon) ); } - + /** * Prints a double */ @@ -503,10 +883,10 @@ { std::cerr << d << " ; "; } - + /** This function verifies that the pre_star contains exactly the set of facets given by the sequence [begin, end[. - + If v!=0, it also fills another Pre_star object, from the sequence [begin, end[, and checks that is in the same order as pre_star. */ @@ -515,18 +895,18 @@ Input_facet_it begin, Input_facet_it end, const Vertex_handle v = Vertex_handle()) const; - + /** This function verifies that the pre_star contains exactly the set of facets on the boundary of the conflict zone of the weighted point wp. The vertex handle vh is an hint for the location of wp. - + It also fills another Pre_star object, and checks that is in the same order as pre_star. */ bool check_pre_star(const Pre_star& pre_star, const Weighted_point& wp, const Vertex_handle& vh) const; - + /** * Checks if the sliver criterion values from \c criterion_values are the same as * those that will be found if wp is inserted in the triangulation @@ -536,15 +916,17 @@ const Vertex_handle& vh) const; #endif // CGAL_MESH_3_DEBUG_SLIVERS_EXUDER - + }; // end class Slivers_exuder - - -template + + +template Slivers_exuder:: Slivers_exuder(C3T3& c3t3, const SC& criteria, double d) - : c3t3_(c3t3) + : Base(c3t3.bbox(), + Concurrent_mesher_config::get().locking_grid_num_cells_per_axis) + , c3t3_(c3t3) , tr_(c3t3_.triangulation()) , sq_delta_(d*d) , num_of_pumped_vertices_(0) @@ -555,133 +937,213 @@ , time_limit_(-1) , running_time_() { -} - + // If we're multi-thread + tr_.set_lock_data_structure(get_lock_data_structure()); +} + -template +template template Mesh_optimization_return_code -Slivers_exuder:: +Slivers_exuder:: pump_vertices(double sliver_criterion_limit, Visitor& visitor) { +#ifdef CGAL_MESH_3_PROFILING + WallClockTimer t; +#endif + init(sliver_criterion_limit); - + +#ifdef CGAL_MESH_3_PROFILING + std::cerr << std::endl << "==== Init time: " + << t.elapsed() << "s ====" << std::endl; +#endif + #ifdef CGAL_MESH_3_EXUDER_VERBOSE std::cerr << "Exuding...\n"; std::cerr << "Legend of the following line: " << "(#cells left,#vertices pumped,#vertices ignored)" << std::endl; - std::cerr << "(" << cells_queue_.size() << ",0,0)"; + std::cerr << "(" << this->cells_queue_size() << ",0,0)"; #endif // CGAL_MESH_3_EXUDER_VERBOSE - + running_time_.reset(); running_time_.start(); - - while( !cells_queue_.empty() && !is_time_limit_reached() ) + +#ifdef CGAL_MESH_3_PROFILING + t.reset(); +#endif + + +#ifdef CGAL_LINKED_WITH_TBB + // Parallel + if (boost::is_convertible::value) + { + this->create_root_task(); + + while (!this->cells_queue_empty()) + { + Queue_value_type front = *(this->cells_queue_front()); + this->cells_queue_pop_front(); + Cell_handle c = this->extract_cell_handle_from_queue_value(front); + double q = this->extract_cell_quality_from_queue_value(front); + unsigned int ec = this->extract_erase_counter_from_queue_value(front); + // Low quality first (i.e. low value of q) + enqueue_task(c, ec, q); + } + + this->wait_for_all(); + +# if defined(CGAL_MESH_3_EXUDER_VERBOSE) || defined(CGAL_MESH_3_PROFILING) + std::cerr << " Flushing"; +# endif + bool keep_flushing = true; + while (keep_flushing) + { + keep_flushing = this->flush_work_buffers(); +# if defined(CGAL_MESH_3_EXUDER_VERBOSE) || defined(CGAL_MESH_3_PROFILING) + std::cerr << "."; +# endif + } + + this->destroy_root_task(); + } + // Sequential + else +#endif // CGAL_LINKED_WITH_TBB { - typename Tet_priority_queue::Reverse_entry front = *(cells_queue_.front()); - Cell_handle c = front.second; - - bool vertex_pumped = false; - for( int i = 0; i < 4; ++i ) - { - // pump_vertices_on_surfaces is a boolean template parameter. The - // following condition is pruned at compiled time, if - // pump_vertices_on_surfaces==false. - if( pump_vertices_on_surfaces || c3t3_.in_dimension(c->vertex(i)) > 2 ) + while( !this->cells_queue_empty() && !is_time_limit_reached() ) + { + Queue_value_type front = *(this->cells_queue_front()); + Cell_handle c = this->extract_cell_handle_from_queue_value(front); + + // Low quality first (i.e. low value of cell quality) + bool vertex_pumped = false; + for( int i = 0; i < 4; ++i ) { - if( pump_vertex(c->vertex(i)) ) + // pump_vertices_on_surfaces is a boolean template parameter. The + // following condition is pruned at compiled time, if + // pump_vertices_on_surfaces==false. + if( pump_vertices_on_surfaces || c3t3_.in_dimension(c->vertex(i)) > 2 ) { - vertex_pumped = true; - ++num_of_pumped_vertices_; - break; + if( pump_vertex(c->vertex(i)) ) + { + vertex_pumped = true; + ++num_of_pumped_vertices_; + break; + } + else + ++num_of_ignored_vertices_; + + ++num_of_treated_vertices_; } - else - ++num_of_ignored_vertices_; - - ++num_of_treated_vertices_; } + + // if the tet could not be deleted + if ( ! vertex_pumped ) + this->cells_queue_pop_front(); + + visitor.after_cell_pumped(this->cells_queue_size()); + #ifdef CGAL_MESH_3_EXUDER_VERBOSE + std::cerr << boost::format("\r \r" + "(%1%,%2%,%3%) (%|4$.1f| vertices/s)") + % this->cells_queue_size() + % num_of_pumped_vertices_ + % num_of_ignored_vertices_ + % (num_of_treated_vertices_ / running_time_.time()); + #endif // CGAL_MESH_3_EXUDER_VERBOSE } - - // if the tet could not be deleted - if ( ! vertex_pumped ) - cells_queue_.pop_front(); - - visitor.after_cell_pumped(cells_queue_.size()); -#ifdef CGAL_MESH_3_EXUDER_VERBOSE - std::cerr << boost::format("\r \r" - "(%1%,%2%,%3%) (%|4$.1f| vertices/s)") - % cells_queue_.size() - % num_of_pumped_vertices_ - % num_of_ignored_vertices_ - % (num_of_treated_vertices_ / running_time_.time()); -#endif // CGAL_MESH_3_EXUDER_VERBOSE } - + running_time_.stop(); - -#ifdef CGAL_MESH_3_EXUDER_VERBOSE + +#ifdef CGAL_MESH_3_PROFILING + std::cerr << std::endl << "==== Iterations time: " + << t.elapsed() << "s ====" << std::endl; +#endif + + +#ifdef CGAL_MESH_3_EXUDER_VERBOSE std::cerr << std::endl; std::cerr << "Total exuding time: " << running_time_.time() << "s"; std::cerr << std::endl; -#endif // CGAL_MESH_3_EXUDER_VERBOSE - +#endif // CGAL_MESH_3_EXUDER_VERBOSE + if ( is_time_limit_reached() ) { #ifdef CGAL_MESH_3_EXUDER_VERBOSE std::cerr << "Exuding return code: TIME_LIMIT_REACHED\n\n"; #endif // CGAL_MESH_3_EXUDER_VERBOSE return TIME_LIMIT_REACHED; } - + if ( check_sliver_bound() ) { #ifdef CGAL_MESH_3_EXUDER_VERBOSE std::cerr << "Exuding return code: BOUND_REACHED\n\n"; #endif // CGAL_MESH_3_EXUDER_VERBOSE return BOUND_REACHED; } - + #ifdef CGAL_MESH_3_EXUDER_VERBOSE std::cerr << "Exuding return code: CANT_IMPROVE_ANYMORE\n\n"; #endif // CGAL_MESH_3_EXUDER_VERBOSE return CANT_IMPROVE_ANYMORE; - + } // end function pump_vertices -template +template +template bool Slivers_exuder:: -pump_vertex(const Vertex_handle& pumped_vertex) +pump_vertex(const Vertex_handle& pumped_vertex, + bool *could_lock_zone) { // Get best_weight - double best_weight = get_best_weight(pumped_vertex); - + double best_weight = get_best_weight(pumped_vertex, could_lock_zone); + if (could_lock_zone && *could_lock_zone == false) + return false; + // If best_weight < pumped_vertex weight, nothing to do if ( best_weight > pumped_vertex->point().weight() ) { Weighted_point wp(pumped_vertex->point(), best_weight); - + // Insert weighted point into mesh - update_mesh(wp, pumped_vertex); - + update_mesh(wp, pumped_vertex, could_lock_zone); + return true; } - + return false; } - - -template + + +template void Slivers_exuder:: initialize_prestar_and_criterion_values(const Vertex_handle& v, Pre_star& pre_star, - Sliver_values& criterion_values) const + Sliver_values& criterion_values, + bool *could_lock_zone) const { std::vector incident_cells; incident_cells.reserve(64); - tr_.incident_cells(v, std::back_inserter(incident_cells)); + // Parallel + if (could_lock_zone) + { + if (!tr_.try_lock_and_get_incident_cells(v, incident_cells)) + { + this->unlock_all_elements(); + *could_lock_zone = false; + return; + } + } + // Sequential + else + { + tr_.incident_cells(v, std::back_inserter(incident_cells)); + } for ( typename Cell_vector::const_iterator cit = incident_cells.begin() ; cit != incident_cells.end() ; @@ -690,28 +1152,28 @@ const int index = (*cit)->index(v); const Facet f = Facet(*cit, index); const Facet opposite_facet = tr_.mirror_facet(f); - + // Sliver criterion values initialization if( c3t3_.is_in_complex(*cit) ) { criterion_values[f] = sliver_criteria_(*cit); } - + // Pre_star initialization // If facet is adjacent to and infinite cell, no need to put it in prestar // (infinite critical radius) if ( tr_.is_infinite(opposite_facet.first) ) continue; - + // Insert facet in prestar (even if it is not in complex) double critical_radius = compute_critical_radius(v, opposite_facet.first); - pre_star.insert(f, critical_radius); + pre_star.insert(f, critical_radius); } } - - -template + + +template bool Slivers_exuder:: expand_prestar(const Cell_handle& cell_to_add, @@ -728,21 +1190,21 @@ pre_star.pop_front(); if ( c3t3_.is_in_complex(cell_to_add) ) { - criterion_values.erase(start_facet); + criterion_values.erase(start_facet); } - + int start_mirror_facet_index = tr_.mirror_facet(start_facet).second; - + // For each facet of cell_to_add for(int i = 0; i<4 ; ++i) { // We have already treated start_facet if ( i == start_mirror_facet_index ) continue; - + const Facet current_facet(cell_to_add, i); const Facet current_mirror_facet(tr_.mirror_facet(current_facet)); - + // If current_facet_mirror is in prestar, delete it // (it may happen than pre_star contains two facets of the same cell) if ( pre_star.erase(current_mirror_facet) ) @@ -752,84 +1214,89 @@ { return false; } - + // Update criterion_values if ( c3t3_.is_in_complex(cell_to_add) ) - { + { criterion_values.erase(current_mirror_facet); } } // If current_mirror_facet is not in prestar: - // expand prestar & update criterion_values - else + // expand prestar & update criterion_values + else { const Cell_handle& current_mirror_cell = current_mirror_facet.first; - + CGAL_assertion(current_mirror_cell != start_facet.first); CGAL_assertion(pumped_vertex != current_mirror_facet.first->vertex(0)); CGAL_assertion(pumped_vertex != current_mirror_facet.first->vertex(1)); CGAL_assertion(pumped_vertex != current_mirror_facet.first->vertex(2)); CGAL_assertion(pumped_vertex != current_mirror_facet.first->vertex(3)); - + // Update pre_star (we do not insert facets with infinite critical radius) - // We do insert facet of cells which are outside the complex (we just + // We do insert facet of cells which are outside the complex (we just // don't use their sliver criterion value to get best weight) if ( ! tr_.is_infinite(current_mirror_cell) ) { - double new_critical_radius = + double new_critical_radius = compute_critical_radius(pumped_vertex, current_mirror_cell); pre_star.insert(current_facet, new_critical_radius); -#ifdef CGAL_MESH_3_DEBUG_SLIVERS_EXUDER +#ifdef CGAL_MESH_3_DEBUG_SLIVERS_EXUDER if ( new_critical_radius < critical_radius ) std::cerr << "new critical radius:" << new_critical_radius << " / current critical radius:" << critical_radius - << std::endl; + << std::endl; #endif // CGAL_MESH_3_DEBUG_SLIVERS_EXUDER } - + // Update ratio (ratio is needed for cells of complex only) if ( c3t3_.is_in_complex(cell_to_add) ) - { + { Tetrahedron_3 tet(pumped_vertex->point(), cell_to_add->vertex((i+1)&3)->point(), cell_to_add->vertex((i+2)&3)->point(), cell_to_add->vertex((i+3)&3)->point()); - + double new_value = sliver_criteria_(tet); criterion_values.insert(std::make_pair(current_facet,new_value)); } } - } - + } + return true; } - -template + +template double Slivers_exuder:: -get_best_weight(const Vertex_handle& v) const +get_best_weight(const Vertex_handle& v, bool *could_lock_zone) const { // Get pre_star and criterion_values Pre_star pre_star; Sliver_values criterion_values; - initialize_prestar_and_criterion_values(v, pre_star, criterion_values); + initialize_prestar_and_criterion_values( + v, pre_star, criterion_values, could_lock_zone); -#ifdef CGAL_MESH_3_DEBUG_SLIVERS_EXUDER + if (could_lock_zone && *could_lock_zone == false) + return 0.; + +#ifdef CGAL_MESH_3_DEBUG_SLIVERS_EXUDER Pre_star pre_star_copy; Sliver_values ratios_copy; #endif - + double worst_criterion_value = get_min_value(criterion_values); double best_weight = 0; + // TODO: it seems that this computes the incident cells again double sq_d_v = get_closest_vertice_squared_distance(v); - + // If that boolean is set to false, it means that a facet in the complex // is about to be flipped. In that case, the pumping is stopped. bool can_flip = true; - + // Main loop: find the weight which maximizes the minimum value of ratio while( can_flip && ! pre_star.empty() @@ -838,57 +1305,63 @@ { // Store critial radius (pre_star will be modified in expand_prestar) double critical_r = pre_star.front()->first; - - // expand prestar (insert opposite_cell facets in pre_star) + + // expand prestar (insert opposite_cell facets in pre_star) Facet link = pre_star.front()->second; const Cell_handle& opposite_cell = tr_.mirror_facet(link).first; + + if (could_lock_zone && !tr_.try_lock_cell(opposite_cell)) + { + *could_lock_zone = false; + return 0.; + } can_flip = expand_prestar(opposite_cell, v, pre_star, criterion_values); - + // Update best_weight if needed if(can_flip) { double min_of_pre_star = get_min_value(criterion_values); - + if( min_of_pre_star > worst_criterion_value ) { // Update worst_criterion_value worst_criterion_value = min_of_pre_star; - + // Update best_weight CGAL_assertion(!pre_star.empty()); double next_r = pre_star.front()->first; best_weight = (critical_r + next_r) / 2; - -#ifdef CGAL_MESH_3_DEBUG_SLIVERS_EXUDER + +#ifdef CGAL_MESH_3_DEBUG_SLIVERS_EXUDER pre_star_copy = pre_star; ratios_copy = criterion_values; -#endif // CGAL_MESH_3_DEBUG_SLIVERS_EXUDER +#endif // CGAL_MESH_3_DEBUG_SLIVERS_EXUDER } } } // end while(... can pump...) - - -#ifdef CGAL_MESH_3_DEBUG_SLIVERS_EXUDER + + +#ifdef CGAL_MESH_3_DEBUG_SLIVERS_EXUDER if ( best_weight > v->point().weight() ) { Weighted_point wp(v->point(), best_weight); check_pre_star(pre_star_copy, wp, v); check_ratios(ratios_copy, wp, v); } -#endif // CGAL_MESH_3_DEBUG_SLIVERS_EXUDER - +#endif // CGAL_MESH_3_DEBUG_SLIVERS_EXUDER + return best_weight; } - -template + +template typename Slivers_exuder::Umbrella Slivers_exuder:: get_umbrella(const Facet_vector& facets, const Vertex_handle& v) const { Umbrella umbrella; - + // Insert into umbrella surface_index of facets which are on the surface typename Facet_vector::const_iterator fit = facets.begin(); for ( ; fit != facets.end() ; ++fit ) @@ -899,14 +1372,15 @@ umbrella.insert(std::make_pair(edge, c3t3_.surface_patch_index(*fit))); } } - + return umbrella; } - -template + +template +template void -Slivers_exuder:: +Slivers_exuder:: restore_cells_and_boundary_facets( const Boundary_facets_from_outside& boundary_facets_from_outside, const Vertex_handle& new_vertex) @@ -914,10 +1388,10 @@ Cell_vector new_cells; new_cells.reserve(64); tr_.incident_cells(new_vertex, std::back_inserter(new_cells)); - + // Each cell must have a facet on the boundary of the conflict zone CGAL_assertion(boundary_facets_from_outside.size() == new_cells.size()); - + // Restore attributes of each cell for(typename Cell_vector::iterator cit = new_cells.begin(); cit != new_cells.end(); @@ -927,38 +1401,38 @@ const int index = (*cit)->index(new_vertex); const Facet new_facet = std::make_pair(*cit, index); const Facet new_facet_from_outside = tr_.mirror_facet(new_facet); - + // Search new_facet_from_outside in boundary_facets_from_outside. // That search cannot fail. typename Boundary_facets_from_outside::const_iterator it = boundary_facets_from_outside.find(new_facet_from_outside); - + CGAL_assertion(it != boundary_facets_from_outside.end()); - + // Restore facet attributes if ( it->second.first != Surface_patch_index() ) c3t3_.add_to_complex(new_facet, it->second.first); - + // Restore cell attributes if ( it->second.second != Subdomain_index() ) c3t3_.add_to_complex(*cit, it->second.second); - + // if the new cell is in the domain, and it criterion value is less that // the maximum, push it in the cells queue. if( c3t3_.is_in_complex(*cit) ) { - double criterion_value + double criterion_value = sliver_criteria_(*cit); - + if( criterion_value < sliver_criteria_.sliver_bound() ) - cells_queue_.insert(*cit, criterion_value); + add_cell_to_queue(*cit, criterion_value); } - } + } } - - -template + + +template typename Slivers_exuder::Ordered_edge Slivers_exuder::get_opposite_ordered_edge( const Facet& facet, @@ -966,12 +1440,12 @@ { Vertex_handle v1; Vertex_handle v2; - + // Get the two vertex of *fit which are not new_vertex for ( int i = 0 ; i < 4 ; ++i ) { const Vertex_handle current_vertex = facet.first->vertex(i); - + if ( current_vertex != vertex && tr_.has_vertex(facet, current_vertex) ) { if ( v1 == Vertex_handle() ) @@ -980,24 +1454,24 @@ v2 = current_vertex; } } - + CGAL_assertion(v1 != Vertex_handle() && v2 != Vertex_handle()); - + order_two_handles(v1,v2); return Ordered_edge(v1,v2); } - - -template + + +template void -Slivers_exuder:: +Slivers_exuder:: restore_internal_facets(const Umbrella& umbrella, const Vertex_handle& new_vertex) { Facet_vector new_internal_facets; new_internal_facets.reserve(64); tr_.incident_facets(new_vertex, std::back_inserter(new_internal_facets)); - + // Restore attributes of each facet for(typename Facet_vector::iterator fit = new_internal_facets.begin(); fit != new_internal_facets.end(); @@ -1015,62 +1489,88 @@ } } - -template + +template +template void -Slivers_exuder:: +Slivers_exuder:: update_mesh(const Weighted_point& new_point, - const Vertex_handle& old_vertex) + const Vertex_handle& old_vertex, + bool *could_lock_zone) { - CGAL_assertion_code(std::size_t nb_vert = + CGAL_assertion_code(std::size_t nb_vert = tr_.number_of_vertices()); Cell_vector deleted_cells; Facet_vector internal_facets; Facet_vector boundary_facets; - + deleted_cells.reserve(64); internal_facets.reserve(64); boundary_facets.reserve(64); - + tr_.find_conflicts(new_point, old_vertex->cell(), std::back_inserter(boundary_facets), std::back_inserter(deleted_cells), - std::back_inserter(internal_facets)); - + std::back_inserter(internal_facets), + could_lock_zone); + + if (could_lock_zone && *could_lock_zone == false) + return; + // Get some datas to restore mesh Boundary_facets_from_outside boundary_facets_from_outside = get_boundary_facets_from_outside(boundary_facets); - + Umbrella umbrella = get_umbrella(internal_facets, old_vertex); // Delete old cells from queue (they aren't in the triangulation anymore) - delete_cells_from_queue(deleted_cells); - + this->delete_cells_from_queue(deleted_cells); + // Delete old cells & facets from c3t3 remove_from_c3t3(deleted_cells.begin(),deleted_cells.end()); remove_from_c3t3(boundary_facets.begin(),boundary_facets.end()); remove_from_c3t3(internal_facets.begin(),internal_facets.end()); - + // Insert new point (v will be updated using a wp) int dimension = c3t3_.in_dimension(old_vertex); Index vertice_index = c3t3_.index(old_vertex); - - Vertex_handle new_vertex = tr_.insert(new_point); + + Vertex_handle new_vertex = tr_.insert(new_point, old_vertex->cell()); c3t3_.set_dimension(new_vertex,dimension); c3t3_.set_index(new_vertex,vertice_index); - CGAL_assertion(nb_vert == tr_.number_of_vertices()); - + // Only true for sequential version + CGAL_assertion(could_lock_zone || nb_vert == tr_.number_of_vertices()); + // Restore mesh - restore_cells_and_boundary_facets(boundary_facets_from_outside, new_vertex); + restore_cells_and_boundary_facets( + boundary_facets_from_outside, new_vertex); restore_internal_facets(umbrella, new_vertex); - CGAL_assertion(nb_vert == tr_.number_of_vertices()); + + // Only true for sequential version + CGAL_assertion(could_lock_zone || nb_vert == tr_.number_of_vertices()); } - -#ifdef CGAL_MESH_3_DEBUG_SLIVERS_EXUDER -template + +#ifdef CGAL_LINKED_WITH_TBB +// For parallel version +template +template +void +Slivers_exuder:: +enqueue_task(Cell_handle ch, unsigned int erase_counter, double value) +{ + this->enqueue_work( + Pump_vertex( + *this, c3t3_, ch, erase_counter), + value); +} +#endif + + +#ifdef CGAL_MESH_3_DEBUG_SLIVERS_EXUDER +template template bool Slivers_exuder:: @@ -1083,7 +1583,7 @@ if(v != Vertex_handle()) { Pre_star pre_star2; - + // fill pre_star2 for(Input_facet_it fit = begin; fit != end; @@ -1096,7 +1596,7 @@ opposite_facet.first)); } } - + while(!pre_star_copy.empty() && !pre_star2.empty()) { if(pre_star_copy.front()->first != pre_star2.front()->first) { @@ -1105,7 +1605,7 @@ % pre_star_copy.front()->first % pre_star2.front()->first; return false; } - if ( pre_star_copy.front()->second != pre_star2.front()->second ) + if ( pre_star_copy.front()->second != pre_star2.front()->second ) { Facet f1 = pre_star_copy.front()->second; Facet f2 = pre_star2.front()->second; @@ -1131,7 +1631,7 @@ pre_star_copy.pop_front(); } } - + if(pre_star2.empty() && ! pre_star_copy.empty()) { std::cerr << "pre_star is too big!\n"; while(!pre_star_copy.empty()) @@ -1145,7 +1645,7 @@ } return false; } - + if( pre_star_copy.empty() && ! pre_star2.empty() ) { std::cerr << "pre_star is too small!\n"; while(!pre_star2.empty()) @@ -1158,9 +1658,9 @@ return false; } } - + pre_star_copy = pre_star; - + for(Input_facet_it fit = begin; fit != end; ++fit) @@ -1171,13 +1671,13 @@ } if( !pre_star_copy.empty() ) return false; - + return true; } - -template + +template bool Slivers_exuder:: check_pre_star(const Pre_star& pre_star, @@ -1186,13 +1686,13 @@ { std::vector boundary_facets; boundary_facets.reserve(64); - + tr_.find_conflicts(wp, vh->cell(), std::back_inserter(boundary_facets), CGAL::Emptyset_iterator(), CGAL::Emptyset_iterator()); - + const bool result = check_pre_star(pre_star, boundary_facets.begin(), boundary_facets.end(), @@ -1205,8 +1705,8 @@ return result; } - -template + +template bool Slivers_exuder:: check_ratios(const Sliver_values& criterion_values, @@ -1216,40 +1716,40 @@ Cell_vector deleted_cells; Facet_vector internal_facets; Facet_vector boundary_facets; - + tr_.find_conflicts(wp, vh->cell(), std::back_inserter(boundary_facets), std::back_inserter(deleted_cells), std::back_inserter(internal_facets)); - + bool result = true; std::vector expected_ratios; std::vector ratio_vector; - + for ( typename Sliver_values::const_iterator rit = criterion_values.begin() ; rit != criterion_values.end() ; ++rit ) { ratio_vector.push_back(rit->second); } - + for ( typename Facet_vector::const_iterator it = boundary_facets.begin() ; it != boundary_facets.end() ; ++ it ) { if ( !c3t3_.is_in_complex((it->first)) ) continue; - + int k = it->second; Tetrahedron_3 tet(vh->point(), it->first->vertex((k+1)&3)->point(), it->first->vertex((k+2)&3)->point(), it->first->vertex((k+3)&3)->point()); - + double ratio = sliver_criteria_(tet); - expected_ratios.push_back(ratio); - + expected_ratios.push_back(ratio); + bool found = false; for ( typename Sliver_values::const_iterator rit = criterion_values.begin() ; rit != criterion_values.end() ; @@ -1262,14 +1762,14 @@ } } if ( ! found ) - { + { result = false; } } - + if (expected_ratios.size() != criterion_values.size()) result = false; - + if ( !result ) { std::sort(expected_ratios.begin(),expected_ratios.end()); @@ -1278,8 +1778,8 @@ std::set_difference(expected_ratios.begin(),expected_ratios.end(), ratio_vector.begin(),ratio_vector.end(), std::back_inserter(diff)); - - + + std::cerr << "\nExpected criterion_values:["; std::for_each(expected_ratios.begin(), expected_ratios.end(), print_double); std::cerr << "]\nRatios:["; @@ -1288,11 +1788,11 @@ std::for_each(diff.begin(),diff.end(), print_double); std::cerr << "]\n"; } - + return result; } #endif // CGAL_MESH_3_DEBUG_SLIVERS_EXUDER - + } // end namespace Mesh_3 diff -Nru cgal-4.4/include/CGAL/Mesh_3/Triangulation_helpers.h cgal-4.5/include/CGAL/Mesh_3/Triangulation_helpers.h --- cgal-4.4/include/CGAL/Mesh_3/Triangulation_helpers.h 2013-12-21 20:00:22.000000000 +0000 +++ cgal-4.5/include/CGAL/Mesh_3/Triangulation_helpers.h 2014-08-29 13:58:16.000000000 +0000 @@ -19,7 +19,7 @@ // Author(s) : Stephane Tayeb // //****************************************************************************** -// File Description : +// File Description : //****************************************************************************** #ifndef CGAL_MESH_3_TRIANGULATION_HELPERS_H @@ -31,8 +31,8 @@ namespace CGAL { namespace Mesh_3 { - - + + template class Triangulation_helpers { @@ -41,7 +41,7 @@ typedef typename Tr::Vertex_handle Vertex_handle; typedef typename Tr::Cell_handle Cell_handle; typedef std::vector Cell_vector; - + /** * A functor to reset visited flag of each facet of a cell */ @@ -53,19 +53,41 @@ c->reset_visited(i); } }; - + + /** + * A functor to get the point of a vertex vh, but replacing + * it by m_p when vh == m_vh + */ + struct Point_getter + { + /// When the requested will be about vh, the returned point will be p + /// instead of vh->point() + Point_getter(const Vertex_handle &vh, const Point_3&p) + : m_vh(vh), m_p(p) + {} + + const Point_3& operator()(const Vertex_handle &vh) const + { + return (vh == m_vh ? m_p : vh->point()); + } + + private: + const Vertex_handle m_vh; + const Point_3 &m_p; + }; + public: /// Constructor / Destructor Triangulation_helpers() {} ~Triangulation_helpers() {} - + /** * Moves point from \c v to \c p. */ void move_point(Tr& tr, const Vertex_handle& v, const Point_3& p) const; - + /** * Returns true if moving \c v to \c p makes no topological * change in \c tr @@ -74,11 +96,20 @@ const Vertex_handle& v, const Point_3& p, Cell_vector& cells_tos) const; - + bool no_topological_change__without_set_point( + const Tr& tr, + const Vertex_handle& v, + const Point_3& p, + Cell_vector& cells_tos) const; bool no_topological_change(const Tr& tr, const Vertex_handle& v, const Point_3& p) const; + bool no_topological_change__without_set_point( + const Tr& tr, + const Vertex_handle& v, + const Point_3& p) const; + bool inside_protecting_balls(const Tr& tr, const Vertex_handle& v, @@ -88,11 +119,16 @@ /** * Returns true if \c v is well_oriented on each cell of \c cell_tos */ + // For sequential version bool well_oriented(const Tr& tr, const Cell_vector& cell_tos) const; + // For parallel version + bool well_oriented(const Tr& tr, + const Cell_vector& cell_tos, + const Point_getter& pg) const; }; - - + + template void Triangulation_helpers:: @@ -108,7 +144,7 @@ tr.remove(v); } } - + template bool Triangulation_helpers:: @@ -120,66 +156,151 @@ bool np = true; Point_3 fp = v0->point(); v0->set_point(p); - -/// @TODO: One can do the same checks without the set_point. -/// In the following orientation or side_of_power_sphere tests, just -/// replace v0->point() by p. - if(!well_oriented(tr, cells_tos)) + if(!well_oriented(tr, cells_tos)) { // Reset (restore) v0 v0->set_point(fp); return false; } - + // Reset visited tags of facets std::for_each(cells_tos.begin(), cells_tos.end(), Reset_facet_visited()); - + for ( typename Cell_vector::iterator cit = cells_tos.begin() ; cit != cells_tos.end() ; ++cit ) { Cell_handle c = *cit; - for(int j=0; j<4; j++) + for(int j=0; j<4; j++) { // Treat each facet only once if(c->is_facet_visited(j)) continue; - + // Set facet and it's mirror's one visited Cell_handle cj = c->neighbor(j); int mj = tr.mirror_index(c, j); c->set_facet_visited(j); - cj->set_facet_visited(mj); - + cj->set_facet_visited(mj); + Vertex_handle v1 = c->vertex(j); - if(tr.is_infinite(v1)) + if(tr.is_infinite(v1)) { - if(tr.side_of_power_sphere(c, cj->vertex(mj)->point(), false) - != CGAL::ON_UNBOUNDED_SIDE) + if(tr.side_of_power_sphere(c, cj->vertex(mj)->point(), false) + != CGAL::ON_UNBOUNDED_SIDE) { - np = false; + np = false; break; } } else { - if(tr.side_of_power_sphere(cj, v1->point(), false) - != CGAL::ON_UNBOUNDED_SIDE) + if(tr.side_of_power_sphere(cj, v1->point(), false) + != CGAL::ON_UNBOUNDED_SIDE) { - np = false; + np = false; break; } } } } - + // Reset (restore) v0 v0->set_point(fp); return np; } - + +template +bool +Triangulation_helpers:: +no_topological_change__without_set_point( + const Tr& tr, + const Vertex_handle& v0, + const Point_3& p, + Cell_vector& cells_tos) const +{ + bool np = true; + + Point_getter pg(v0, p); + + if(!well_oriented(tr, cells_tos, pg)) + { + return false; + } + + // Reset visited tags of facets + std::for_each(cells_tos.begin(), cells_tos.end(), Reset_facet_visited()); + + for ( typename Cell_vector::iterator cit = cells_tos.begin() ; + cit != cells_tos.end() ; + ++cit ) + { + Cell_handle c = *cit; + for(int j=0; j<4; j++) + { + // Treat each facet only once + if(c->is_facet_visited(j)) + continue; + + // Set facet and it's mirror's one visited + Cell_handle cj = c->neighbor(j); + int mj = tr.mirror_index(c, j); + c->set_facet_visited(j); + cj->set_facet_visited(mj); + + Vertex_handle v1 = c->vertex(j); + if(tr.is_infinite(v1)) + { + // Build a copy of c, and replace V0 by a temporary vertex (position "p") + typename Cell_handle::value_type c_copy (*c); + int i_v0; + typename Vertex_handle::value_type v; + if (c_copy.has_vertex(v0, i_v0)) + { + v.set_point(p); + c_copy.set_vertex(i_v0, + Tr::Triangulation_data_structure::Vertex_range::s_iterator_to(v)); + } + + Cell_handle c_copy_h = + Tr::Triangulation_data_structure::Cell_range::s_iterator_to(c_copy); + if(tr.side_of_power_sphere(c_copy_h, pg(cj->vertex(mj)), false) + != CGAL::ON_UNBOUNDED_SIDE) + { + np = false; + break; + } + } + else + { + // Build a copy of cj, and replace V0 by a temporary vertex (position "p") + typename Cell_handle::value_type cj_copy (*cj); + int i_v0; + typename Vertex_handle::value_type v; + if (cj_copy.has_vertex(v0, i_v0)) + { + v.set_point(p); + cj_copy.set_vertex(i_v0, + Tr::Triangulation_data_structure::Vertex_range::s_iterator_to(v)); + } + + Cell_handle cj_copy_h = + Tr::Triangulation_data_structure::Cell_range::s_iterator_to(cj_copy); + if(tr.side_of_power_sphere(cj_copy_h, pg(v1), false) + != CGAL::ON_UNBOUNDED_SIDE) + { + np = false; + break; + } + } + } + } + + return np; +} + template bool @@ -197,6 +318,21 @@ template bool Triangulation_helpers:: +no_topological_change__without_set_point( + const Tr& tr, + const Vertex_handle& v0, + const Point_3& p) const +{ + Cell_vector cells_tos; + cells_tos.reserve(64); + tr.incident_cells(v0, std::back_inserter(cells_tos)); + return no_topological_change__without_set_point(tr, v0, p, cells_tos); +} + + +template +bool +Triangulation_helpers:: inside_protecting_balls(const Tr& tr, const Vertex_handle& v, const Point_3& p) const @@ -211,7 +347,6 @@ /// This function well_oriented is called by no_topological_change after a /// v->set_point(p) -/// @TODO: One can do the same checks without the set_point. template bool Triangulation_helpers:: @@ -222,7 +357,7 @@ for( ; it != cells_tos.end() ; ++it) { Cell_handle c = *it; - if( tr.is_infinite(c) ) + if( tr.is_infinite(c) ) { int iv = c->index(tr.infinite_vertex()); Cell_handle cj = c->neighbor(iv); @@ -240,12 +375,46 @@ return false; } return true; -} +} +/// Another version for the parallel version +/// Here, the set_point is not done before, but we use a Point_getter instance +/// to get the point of a vertex. +template +bool +Triangulation_helpers:: +well_oriented(const Tr& tr, + const Cell_vector& cells_tos, + const Point_getter& pg) const +{ + typename Cell_vector::const_iterator it = cells_tos.begin(); + for( ; it != cells_tos.end() ; ++it) + { + Cell_handle c = *it; + if( tr.is_infinite(c) ) + { + int iv = c->index(tr.infinite_vertex()); + Cell_handle cj = c->neighbor(iv); + int mj = tr.mirror_index(c, iv); + if(CGAL::orientation(pg(cj->vertex(mj)), + pg(c->vertex((iv+1)&3)), + pg(c->vertex((iv+2)&3)), + pg(c->vertex((iv+3)&3))) != CGAL::NEGATIVE) + return false; + } + else if(CGAL::orientation(pg(c->vertex(0)), + pg(c->vertex(1)), + pg(c->vertex(2)), + pg(c->vertex(3))) != CGAL::POSITIVE) + return false; + } + return true; +} -} // end namespace Mesh_3 - + +} // end namespace Mesh_3 + } //namespace CGAL #endif // CGAL_MESH_3_TRIANGULATION_HELPERS_H diff -Nru cgal-4.4/include/CGAL/Mesh_3/vertex_perturbation.h cgal-4.5/include/CGAL/Mesh_3/vertex_perturbation.h --- cgal-4.4/include/CGAL/Mesh_3/vertex_perturbation.h 2013-12-21 20:00:22.000000000 +0000 +++ cgal-4.5/include/CGAL/Mesh_3/vertex_perturbation.h 2014-08-29 13:58:16.000000000 +0000 @@ -27,10 +27,17 @@ #include -#include #include #include +#ifdef CGAL_MESH_3_PERTURBER_VERBOSE + #include + #ifdef CGAL_LINKED_WITH_TBB + #include + #include + #endif +#endif + #include #include #include @@ -184,10 +191,14 @@ #ifdef CGAL_MESH_3_PERTURBER_VERBOSE , counter_(0) , timer_() - , total_counter_(0) - , total_time_(0.) #endif - {} + { +#ifdef CGAL_MESH_3_PERTURBER_VERBOSE + // Initialized here in case it's some tbb::atomic + total_counter_ = 0; + total_time_ = 0; +#endif + } /** * @brief destructor @@ -224,23 +235,24 @@ const MeshDomain& domain, const SliverCriterion& criterion, const FT& sliver_bound, - std::vector& modified_vertices) const + std::vector& modified_vertices, + bool *could_lock_zone = NULL) const { #ifndef CGAL_MESH_3_PERTURBER_VERBOSE return do_perturb(v, slivers, c3t3, domain, criterion, - sliver_bound, modified_vertices); + sliver_bound, modified_vertices, could_lock_zone); #else - timer_.start(); + timer().start(); // Virtual call std::pair perturb = do_perturb(v, slivers, c3t3, domain, criterion, - sliver_bound, modified_vertices); + sliver_bound, modified_vertices, could_lock_zone); if ( perturb.first ) ++counter_; - timer_.stop(); + timer().stop(); return perturb; #endif @@ -300,7 +312,8 @@ const MeshDomain& domain, const SliverCriterion& criterion, const FT& sliver_bound, - std::vector& modified_vertices) const = 0; + std::vector& modified_vertices, + bool *could_lock_zone = NULL) const = 0; /** @@ -323,18 +336,33 @@ #ifdef CGAL_MESH_3_PERTURBER_VERBOSE public: - void reset_timer() { total_time_+= time(); timer_.reset(); } + void reset_timer() { total_time_+= 1000*time(); timer().reset(); } void reset_counter() { total_counter_ += counter_; counter_ = 0; } int counter() const { return counter_; } - double time() const { return timer_.time(); } + double time() const { return timer().time(); } int total_counter() const { return total_counter_ + counter(); } - double total_time() const { return total_time_ + time(); } + std::size_t total_time() const + { return static_cast(total_time_ + 1000*time()); } virtual std::string perturbation_name() const = 0; private: + CGAL::Timer &timer() const + { +#ifdef CGAL_LINKED_WITH_TBB + return timer_.local(); +#else + return timer_; +#endif + } mutable int counter_; +#ifdef CGAL_LINKED_WITH_TBB + mutable tbb::enumerable_thread_specific timer_; + tbb::atomic total_counter_; + tbb::atomic total_time_; +#else mutable CGAL::Timer timer_; int total_counter_; - double total_time_; + std::size_t total_time_; +#endif #endif }; @@ -390,7 +418,8 @@ const MeshDomain& domain, const SliverCriterion& criterion, const FT& sliver_bound, - std::vector& modified_vertices) const = 0; + std::vector& modified_vertices, + bool *could_lock_zone = NULL) const = 0; protected: // ----------------------------------- @@ -407,7 +436,8 @@ C3T3& c3t3, const MeshDomain& domain, const SliverCriterion& criterion, - std::vector& modified_vertices) const + std::vector& modified_vertices, + bool *could_lock_zone = NULL) const { typedef typename C3T3::Triangulation::Geom_traits Gt; typedef typename Gt::FT FT; @@ -434,27 +464,46 @@ // as long as no topological change takes place unsigned int i = 0; - while( Th().no_topological_change(c3t3.triangulation(), v, final_loc) - && (++i <= max_step_nb_) ) + // Concurrent-safe version + if (could_lock_zone) + { + while(Th().no_topological_change__without_set_point(c3t3.triangulation(), + v, final_loc) + && (++i <= max_step_nb_) ) + { + new_loc = new_loc + step_length * gradient_vector; + + if ( c3t3.in_dimension(v) == 3 ) + final_loc = new_loc; + else + final_loc = helper.project_on_surface(new_loc, v); + } + } + else { - new_loc = new_loc + step_length * gradient_vector; + while( Th().no_topological_change(c3t3.triangulation(), v, final_loc) + && (++i <= max_step_nb_) ) + { + new_loc = new_loc + step_length * gradient_vector; - if ( c3t3.in_dimension(v) == 3 ) - final_loc = new_loc; - else - final_loc = helper.project_on_surface(new_loc, v); + if ( c3t3.in_dimension(v) == 3 ) + final_loc = new_loc; + else + final_loc = helper.project_on_surface(new_loc, v); + } } // Topology could not change moving this vertex if ( i > max_step_nb_ || Th().inside_protecting_balls(c3t3.triangulation(), v, final_loc)) return std::make_pair(false,v); - + // we know that there will be a combinatorial change return helper.update_mesh_topo_change(final_loc, v, criterion, - std::back_inserter(modified_vertices)); + std::back_inserter(modified_vertices), + could_lock_zone); } @@ -515,7 +564,8 @@ const MeshDomain& domain, const SliverCriterion& criterion, const FT&, - std::vector& modified_vertices) const + std::vector& modified_vertices, + bool *could_lock_zone = NULL) const { CGAL_precondition(!slivers.empty()); @@ -530,7 +580,8 @@ c3t3, domain, criterion, - modified_vertices); + modified_vertices, + could_lock_zone); } private: @@ -671,7 +722,8 @@ const MeshDomain& domain, const SliverCriterion& criterion, const FT&, - std::vector& modified_vertices) const + std::vector& modified_vertices, + bool *could_lock_zone = NULL) const { CGAL_precondition(!slivers.empty()); @@ -686,7 +738,8 @@ c3t3, domain, criterion, - modified_vertices); + modified_vertices, + could_lock_zone); } private: @@ -810,7 +863,8 @@ const MeshDomain& domain, const SliverCriterion& criterion, const FT&, - std::vector& modified_vertices) const + std::vector& modified_vertices, + bool *could_lock_zone = NULL) const { CGAL_precondition(!slivers.empty()); @@ -825,7 +879,8 @@ c3t3, domain, criterion, - modified_vertices); + modified_vertices, + could_lock_zone); } private: @@ -1009,7 +1064,8 @@ const MeshDomain& domain, const SliverCriterion& criterion, const FT& sliver_bound, - std::vector& modified_vertices) const = 0; + std::vector& modified_vertices, + bool *could_lock_zone = NULL) const = 0; protected: // ----------------------------------- @@ -1140,12 +1196,14 @@ const MeshDomain& domain, const SliverCriterion& criterion, const FT& sliver_bound, - std::vector& modified_vertices) const + std::vector& modified_vertices, + bool *could_lock_zone = NULL) const { CGAL_precondition(!slivers.empty()); return apply_perturbation(v, slivers, c3t3, domain, criterion, - sliver_bound, modified_vertices); + sliver_bound, modified_vertices, + could_lock_zone); } private: @@ -1163,7 +1221,8 @@ const MeshDomain& domain, const SliverCriterion& criterion, const FT& sliver_bound, - std::vector& modified_vertices) const + std::vector& modified_vertices, + bool *could_lock_zone = NULL) const { typedef Triangulation_helpers Th; @@ -1206,8 +1265,12 @@ helper.update_mesh(new_location, moving_vertex, criterion, - std::back_inserter(tmp_mod_vertices)); + std::back_inserter(tmp_mod_vertices), + could_lock_zone); + if (could_lock_zone && *could_lock_zone == false) + return std::make_pair(false, Vertex_handle()); + // get new vertex moving_vertex = update.second; diff -Nru cgal-4.4/include/CGAL/Mesh_3/Worksharing_data_structures.h cgal-4.5/include/CGAL/Mesh_3/Worksharing_data_structures.h --- cgal-4.4/include/CGAL/Mesh_3/Worksharing_data_structures.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/Mesh_3/Worksharing_data_structures.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,882 @@ +// Copyright (c) 2012 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL: $ +// $Id: $ +// +// Author(s) : Clement Jamin + +#ifndef CGAL_MESH_3_WORKSHARING_DATA_STRUCTURES_H +#define CGAL_MESH_3_WORKSHARING_DATA_STRUCTURES_H + +#ifdef CGAL_LINKED_WITH_TBB + +#include + +#include + +#include +#include +#include +#include +#include + + +#include +#ifdef CGAL_MESH_3_TASK_SCHEDULER_SORTED_BATCHES_WITH_MULTISET +# include +#endif + +namespace CGAL { namespace Mesh_3 { + +// Forward declarations +class Load_based_worksharing_ds; +class Auto_worksharing_ds; + +// Typedef + +// Load-based +#ifdef CGAL_MESH_3_LOAD_BASED_WORKSHARING + typedef Load_based_worksharing_ds WorksharingDataStructureType; +// Task-scheduler with TLS work buffers +// => 1 work-buffer / thread +#else + typedef Auto_worksharing_ds WorksharingDataStructureType; +#endif + + + +class Work_statistics +{ +public: + // Constructors + + Work_statistics(const Bbox_3 &bbox, + int num_grid_cells_per_axis) + : m_num_grid_cells_per_axis(num_grid_cells_per_axis) + { + m_laziest_cell_index = 0; + m_laziest_cell_occupation = 1000; + + m_num_cells = + num_grid_cells_per_axis*num_grid_cells_per_axis*num_grid_cells_per_axis; + m_occupation_grid = new tbb::atomic[m_num_cells]; + m_num_batches_grid = new tbb::atomic[m_num_cells]; + // Initialize grid + for (int i = 0 ; i < m_num_cells ; ++i) + { + m_occupation_grid[i] = 0; + m_num_batches_grid[i] = 0; + } + + set_bbox(bbox); + } + + /// Destructor + virtual ~Work_statistics() + { + delete [] m_occupation_grid; + delete [] m_num_batches_grid; + } + + void set_bbox(const Bbox_3 &bbox) + { + // Keep mins and resolutions + m_xmin = bbox.xmin(); + m_ymin = bbox.ymin(); + m_zmin = bbox.zmin(); + double n = static_cast(m_num_grid_cells_per_axis); + m_resolution_x = n / (bbox.xmax() - m_xmin); + m_resolution_y = n / (bbox.ymax() - m_ymin); + m_resolution_z = n / (bbox.zmax() - m_zmin); + +#ifdef CGAL_CONCURRENT_MESH_3_VERBOSE + std::cerr << "Worksharing data structure Bounding Box = [" + << bbox.xmin() << ", " << bbox.xmax() << "], " + << bbox.ymin() << ", " << bbox.ymax() << "], " + << bbox.zmin() << ", " << bbox.zmax() << "]" + << std::endl; +#endif + } + + void add_batch(int cell_index, int to_add) + { + m_num_batches_grid[cell_index].fetch_and_add(to_add); + } + + void add_occupation(int cell_index, int to_add, int) + { + m_occupation_grid[cell_index].fetch_and_add(to_add); + + /*int new_occupation = + (m_occupation_grid[cell_index].fetch_and_add(to_add)) + + to_add; + //m_num_batches_grid[cell_index] = num_items_in_work_queue; + + // If this cell is the current most lazy, update the value + if (cell_index == m_laziest_cell_index) + { + if (num_items_in_work_queue == 0) + // So that it won't stay long the laziest + m_laziest_cell_occupation = 999999; + else + m_laziest_cell_occupation = new_occupation; + } + else if (num_items_in_work_queue > 0 + && new_occupation <= m_laziest_cell_occupation) + { + m_laziest_cell_index = cell_index; + m_laziest_cell_occupation = new_occupation; + }*/ + } + + void add_occupation(int index_x, int index_y, int index_z, + int to_add, int num_items_in_work_queue) + { + int index = + index_z*m_num_grid_cells_per_axis*m_num_grid_cells_per_axis + + index_y*m_num_grid_cells_per_axis + + index_x; + return add_occupation(index, to_add, num_items_in_work_queue); + } + + /// P3 must provide .x(), .y(), .z() + template + int compute_index(const P3 &point) const + { + // Compute indices on grid + int index_x = static_cast( (to_double(point.x()) - m_xmin) * m_resolution_x); + index_x = std::max( 0, std::min(index_x, m_num_grid_cells_per_axis - 1) ); + int index_y = static_cast( (to_double(point.y()) - m_ymin) * m_resolution_y); + index_y = std::max( 0, std::min(index_y, m_num_grid_cells_per_axis - 1) ); + int index_z = static_cast( (to_double(point.z()) - m_zmin) * m_resolution_z); + index_z = std::max( 0, std::min(index_z, m_num_grid_cells_per_axis - 1) ); + + int index = + index_z*m_num_grid_cells_per_axis*m_num_grid_cells_per_axis + + index_y*m_num_grid_cells_per_axis + + index_x; + + return index; + } + + /// P3 must provide .x(), .y(), .z() + // Returns index in grid + template + int add_occupation(const P3 &point, int to_add, int num_items_in_work_queue) + { + int index = compute_index(point); + add_occupation(index, to_add, num_items_in_work_queue); + return index; + } + + int get_laziest_cell_index() const + { + //return m_laziest_cell_index; + + + /* + // Look for best occupation/work ratio + int laziest_index = 0; + float laziest_ratio = 200000.f; + for (int i = 0 ; i < m_num_cells ; ++i) + { + if (m_num_batches_grid[i] > 0) + { + float ratio = + static_cast(m_occupation_grid[i]) + / m_num_batches_grid[i]; + if (ratio < laziest_ratio) + { + laziest_index = i; + laziest_ratio = ratio; + } + } + } + return laziest_index;*/ + + // Look for the least occupied + /*int laziest_index = 0; + int smallest_occupation = 99999; + for (int i = 0 ; i < m_num_cells ; ++i) + { + if (m_num_batches_grid[i] > 1) + { + if (m_occupation_grid[i] < smallest_occupation) + { + laziest_index = i; + smallest_occupation = m_occupation_grid[i]; + } + } + } + //std::cerr << "Occ=" << m_occupation_grid[laziest_index] + // << " / Bat=" << m_num_batches_grid[laziest_index] + // << std::endl; + return laziest_index;*/ + + + // Rotate + static tbb::atomic last_cell_index; + //std::cerr << "last=" << last_cell_index << std::endl; + int i = (last_cell_index + 1) % m_num_cells; + for ( ; i != last_cell_index ; i = (i + 1) % m_num_cells) + { + //std::cerr << "#" << i << "=" << m_num_batches_grid[i] << std::endl; + if (m_num_batches_grid[i] > 0) + { + break; + } + } + last_cell_index = i; + return i; + } + +protected: + double m_xmin; + double m_ymin; + double m_zmin; + double m_resolution_x; + double m_resolution_y; + double m_resolution_z; + + int m_num_grid_cells_per_axis; + int m_num_cells; + tbb::atomic * m_occupation_grid; + tbb::atomic * m_num_batches_grid; + + tbb::atomic m_laziest_cell_index; + tbb::atomic m_laziest_cell_occupation; +}; + + +/* + * ============== + * class WorkItem + * Abstract base class for a piece of work. + * ============== + */ +class WorkItem +{ +public: + WorkItem() {} + // Derived class defines the actual work. + virtual void run() = 0; + virtual bool less_than(const WorkItem &) const = 0; +}; + +struct CompareTwoWorkItems +{ + bool operator()(const WorkItem *p1, const WorkItem *p2) const + { + return p1->less_than(*p2); + } +}; + +/* + * ============== + * class MeshRefinementWorkItem + * Concrete class for a piece of work in the refinement process. + * ============== + */ +template +class MeshRefinementWorkItem + : public WorkItem +{ +public: + MeshRefinementWorkItem(const Func& func, const Quality &quality) + : m_func(func), m_quality(quality) + {} + + void run() + { + m_func(); + tbb::scalable_allocator >().deallocate(this, 1); + } + + bool less_than (const WorkItem &other) const + { + /*try + { + const MeshRefinementWorkItem& other_cwi = dynamic_cast&>(other); + return m_quality < other_cwi.m_quality; + } + catch (const std::bad_cast&) + { + return false; + }*/ + const MeshRefinementWorkItem& other_cwi = static_cast&>(other); + return m_quality < other_cwi.m_quality; + } + +private: + Func m_func; + Quality m_quality; +}; + + + + +/* + * ============== + * class SimpleFunctorWorkItem + * Concrete class for a work item embedding a simple functor + * ============== + */ +template +class SimpleFunctorWorkItem + : public WorkItem +{ +public: + SimpleFunctorWorkItem(const Func& func) + : m_func(func) + {} + + void run() + { + m_func(); + tbb::scalable_allocator >().deallocate(this, 1); + } + + // Irrelevant here + bool less_than (const WorkItem &other) const + { + // Just compare addresses + return this < &other; + } + +private: + Func m_func; +}; + + +/* + * =============== + * class WorkBatch + * =============== + */ +class WorkBatch +{ +public: + +#ifdef CGAL_MESH_3_TASK_SCHEDULER_SORTED_BATCHES_WITH_MULTISET + typedef std::multiset Batch; +#else + typedef std::vector Batch; +#endif + typedef Batch::const_iterator BatchConstIterator; + typedef Batch::iterator BatchIterator; + + WorkBatch() {} + + void add_work_item(WorkItem *p_item) + { +#ifdef CGAL_MESH_3_TASK_SCHEDULER_SORTED_BATCHES_WITH_MULTISET + m_batch.insert(p_item); +#else + m_batch.push_back(p_item); +#endif + } + + void move_first_elements(WorkBatch &dest, int num_elements) + { + BatchIterator it = m_batch.begin(); + BatchIterator it_end = m_batch.end(); + for (int i = 0 ; i < num_elements && it != it_end ; ++it) + { + dest.add_work_item(*it); + } + m_batch.erase(m_batch.begin(), it); + } + + void run() + { +#ifdef CGAL_MESH_3_TASK_SCHEDULER_SORTED_BATCHES_WITH_SORT + std::sort(m_batch.begin(), m_batch.end(), CompareTwoWorkItems()); +#endif + BatchIterator it = m_batch.begin(); + BatchIterator it_end = m_batch.end(); + for ( ; it != it_end ; ++it) + (*it)->run(); + } + + size_t size() const + { + return m_batch.size(); + } + + void clear() + { + m_batch.clear(); + } + +protected: + Batch m_batch; +}; + + + + +/* + * =================== + * class WorkItemTask + * =================== + */ +class WorkItemTask + : public tbb::task +{ +public: + WorkItemTask(WorkItem *pwi) + : m_pwi(pwi) + { + } + +private: + /*override*/inline tbb::task* execute(); + + WorkItem *m_pwi; +}; + + +/* + * ======================================= + * class Simple_worksharing_ds + * ======================================= + */ +class Simple_worksharing_ds +{ +public: + // Constructors + Simple_worksharing_ds() + { + } + + /// Destructor + virtual ~Simple_worksharing_ds() + { + } + + template + void enqueue_work(Func f, tbb::task &parent_task) const + { + //WorkItem *p_item = new SimpleFunctorWorkItem(f); + WorkItem *p_item = + tbb::scalable_allocator >().allocate(1); + new (p_item) SimpleFunctorWorkItem(f); + enqueue_task(create_task(p_item, parent_task)); + } + +protected: + + WorkItemTask *create_task(WorkItem *pwi, tbb::task &parent_task) const + { + return new(tbb::task::allocate_additional_child_of(parent_task)) WorkItemTask(pwi); + } + + void enqueue_task(WorkItemTask *t) const + { + tbb::task::spawn(*t); + } +}; + + + +/* + * ================== + * class TokenTask + * ================== + */ +class TokenTask + : public tbb::task +{ +public: + TokenTask(Load_based_worksharing_ds *p_wsds) + : m_worksharing_ds(p_wsds) {} + +private: + /*override*/inline tbb::task* execute(); + + Load_based_worksharing_ds *m_worksharing_ds; +}; + +/* + * ======================================= + * class Load_based_worksharing_ds + * ======================================= + */ +class Load_based_worksharing_ds +{ +public: + // Constructors + Load_based_worksharing_ds(const Bbox_3 &bbox) + : NUM_WORK_ITEMS_PER_BATCH( + Concurrent_mesher_config::get().num_work_items_per_batch), + m_num_cells_per_axis( + Concurrent_mesher_config::get().work_stats_grid_num_cells_per_axis), + m_num_cells(m_num_cells_per_axis*m_num_cells_per_axis*m_num_cells_per_axis), + m_stats(bbox, m_num_cells_per_axis) + { + m_tls_work_buffers = new TLS_WorkBuffer[m_num_cells]; + m_work_batches = new tbb::concurrent_queue[m_num_cells]; + m_num_batches = new tbb::atomic[m_num_cells]; + + for (int i = 0 ; i < m_num_cells ; ++i) + m_num_batches[i] = 0; + + set_bbox(bbox); + } + + /// Destructor + virtual ~Load_based_worksharing_ds() + { + delete [] m_tls_work_buffers; + delete [] m_work_batches; + delete [] m_num_batches; + } + + void set_bbox(const Bbox_3 &bbox) + { + m_stats.set_bbox(bbox); + } + + template + void enqueue_work(Func f, const Quality &quality, tbb::task &parent_task, const P3 &point) + { + WorkItem *p_item = new MeshRefinementWorkItem(f, quality); + int index = m_stats.compute_index(point); + WorkBatch &wb = m_tls_work_buffers[index].local(); + wb.add_work_item(p_item); + if (wb.size() >= NUM_WORK_ITEMS_PER_BATCH) + { + add_batch_and_enqueue_task(wb, index, parent_task); + wb.clear(); + } + } + + // Returns true if some items were flushed + bool flush_work_buffers(tbb::task &parent_task) + { + int num_flushed_items = 0; + + for (int i = 0 ; i < m_num_cells ; ++i) + { + for (TLS_WorkBuffer::iterator it_buffer = m_tls_work_buffers[i].begin() ; + it_buffer != m_tls_work_buffers[i].end() ; + ++it_buffer ) + { + if (it_buffer->size() > 0) + { + add_batch(*it_buffer, i); + it_buffer->clear(); + ++num_flushed_items; + } + } + } + + for (int i = 0 ; i < num_flushed_items ; ++i) + enqueue_task(parent_task); + + return (num_flushed_items > 0); + } + + void run_next_work_item() + { + WorkBuffer wb; + int index = m_stats.get_laziest_cell_index(); + bool popped = m_work_batches[index].try_pop(wb); + + if (!popped) + { + // Look for an non-empty queue + for (index = 0 ; !popped ; ++index) + { + CGAL_assertion(index < m_num_cells); + popped = m_work_batches[index].try_pop(wb); + } + + --index; + } + + CGAL_assertion(index < m_num_cells); + + --m_num_batches[index]; + m_stats.add_batch(index, -1); + add_occupation(index, 1); + +#ifdef CGAL_CONCURRENT_MESH_3_VERY_VERBOSE + std::cerr << "Running a batch of " << wb.size() << + " elements on cell #" << index << std::endl; +#endif + wb.run(); + add_occupation(index, -1); + } + +protected: + + // TLS + typedef WorkBatch WorkBuffer; + typedef tbb::enumerable_thread_specific TLS_WorkBuffer; + + void add_batch(const WorkBuffer &wb, int index) + { + m_work_batches[index].push(wb); + ++m_num_batches[index]; + m_stats.add_batch(index, 1); + } + + void enqueue_task(tbb::task &parent_task) + { + parent_task.increment_ref_count(); + // Warning: when using "enqueue", the system will use up to two threads + // even if you told task_scheduler_init to use only one + // (see http://software.intel.com/en-us/forums/showthread.php?t=101669) + tbb::task::spawn(*new(parent_task.allocate_child()) TokenTask(this)); + } + + void add_batch_and_enqueue_task(const WorkBuffer &wb, int index, tbb::task &parent_task) + { + add_batch(wb, index); + enqueue_task(parent_task); + } + + void add_occupation(int cell_index, int to_add, int occupation_radius = 1) + { + int index_z = cell_index/(m_num_cells_per_axis* + m_num_cells_per_axis); + cell_index -= index_z* + m_num_cells_per_axis* + m_num_cells_per_axis; + int index_y = cell_index/m_num_cells_per_axis; + cell_index -= index_y*m_num_cells_per_axis; + int index_x = cell_index; + + // For each cell inside the square + for (int i = std::max(0, index_x-occupation_radius) ; + i <= std::min(m_num_cells_per_axis - 1, index_x+occupation_radius) ; + ++i) + { + for (int j = std::max(0, index_y-occupation_radius) ; + j <= std::min(m_num_cells_per_axis - 1, index_y+occupation_radius) ; + ++j) + { + for (int k = std::max(0, index_z-occupation_radius) ; + k <= std::min(m_num_cells_per_axis - 1, index_z+occupation_radius) ; + ++k) + { + int index = + k*m_num_cells_per_axis*m_num_cells_per_axis + + j*m_num_cells_per_axis + + i; + + int weight = + (occupation_radius + 1 - std::abs(i - index_x)) + *(occupation_radius + 1 - std::abs(j - index_y)) + *(occupation_radius + 1 - std::abs(k - index_z)); + + m_stats.add_occupation(index, to_add*weight, m_num_batches[index]); + } + } + } + + } + + const int NUM_WORK_ITEMS_PER_BATCH; + + int m_num_cells_per_axis; + int m_num_cells; + Work_statistics m_stats; + TLS_WorkBuffer *m_tls_work_buffers; + tbb::concurrent_queue *m_work_batches; + tbb::atomic *m_num_batches; +}; + + + + + + + + +/* + * =================== + * class WorkBatchTask + * =================== + */ +class WorkBatchTask + : public tbb::task +{ +public: + WorkBatchTask(const WorkBatch &wb) + : m_wb(wb) + { + //set_affinity(tbb::task::self().affinity()); + } + +private: + /*override*/inline tbb::task* execute(); + + WorkBatch m_wb; +}; + +/* + * ======================================= + * class Auto_worksharing_ds + * ======================================= + */ +class Auto_worksharing_ds +{ +public: + // Constructors + Auto_worksharing_ds(const Bbox_3 &bbox) + : NUM_WORK_ITEMS_PER_BATCH( + Concurrent_mesher_config::get().num_work_items_per_batch) + { + set_bbox(bbox); + } + + /// Destructor + virtual ~Auto_worksharing_ds() + { + } + + void set_bbox(const Bbox_3 &/*bbox*/) + { + // We don't need it. + } + + template + void enqueue_work(Func f, tbb::task &parent_task) + { + //WorkItem *p_item = new SimpleFunctorWorkItem(f); + WorkItem *p_item = + tbb::scalable_allocator >().allocate(1); + new (p_item) SimpleFunctorWorkItem(f); + WorkBatch &workbuffer = m_tls_work_buffers.local(); + workbuffer.add_work_item(p_item); + if (workbuffer.size() >= NUM_WORK_ITEMS_PER_BATCH) + { + /*WorkBatch wb; + workbuffer.move_first_elements(wb, NUM_WORK_ITEMS_PER_BATCH); + add_batch_and_enqueue_task(wb, parent_task);*/ + add_batch_and_enqueue_task(workbuffer, parent_task); + workbuffer.clear(); + } + } + + template + void enqueue_work(Func f, const Quality &quality, tbb::task &parent_task) + { + //WorkItem *p_item = new MeshRefinementWorkItem(f, quality); + WorkItem *p_item = + tbb::scalable_allocator >() + .allocate(1); + new (p_item) MeshRefinementWorkItem(f, quality); + WorkBatch &workbuffer = m_tls_work_buffers.local(); + workbuffer.add_work_item(p_item); + if (workbuffer.size() >= NUM_WORK_ITEMS_PER_BATCH) + { + /*WorkBatch wb; + workbuffer.move_first_elements(wb, NUM_WORK_ITEMS_PER_BATCH); + add_batch_and_enqueue_task(wb, parent_task);*/ + add_batch_and_enqueue_task(workbuffer, parent_task); + workbuffer.clear(); + } + } + + // Returns true if some items were flushed + bool flush_work_buffers(tbb::task &parent_task) + { + int num_flushed_items = 0; + + std::vector tasks; + + for (TLS_WorkBuffer::iterator it_buffer = m_tls_work_buffers.begin() ; + it_buffer != m_tls_work_buffers.end() ; + ++it_buffer ) + { + if (it_buffer->size() > 0) + { + tasks.push_back(create_task(*it_buffer, parent_task)); + it_buffer->clear(); + ++num_flushed_items; + } + } + + for (std::vector::const_iterator it = tasks.begin() ; + it != tasks.end() ; ++it) + { + enqueue_task(*it, parent_task); + } + + return (num_flushed_items > 0); + } + +protected: + + // TLS + typedef WorkBatch WorkBuffer; + typedef tbb::enumerable_thread_specific TLS_WorkBuffer; + + WorkBatchTask *create_task(const WorkBuffer &wb, tbb::task &parent_task) const + { + return new(tbb::task::allocate_additional_child_of(parent_task)) WorkBatchTask(wb); + } + + void enqueue_task(WorkBatchTask *task, + tbb::task &) const + { + tbb::task::spawn(*task); + } + + void add_batch_and_enqueue_task(const WorkBuffer &wb, + tbb::task &parent_task) const + { + enqueue_task(create_task(wb, parent_task), parent_task); + } + + const int NUM_WORK_ITEMS_PER_BATCH; + TLS_WorkBuffer m_tls_work_buffers; +}; + + + + +inline tbb::task* TokenTask::execute() +{ + m_worksharing_ds->run_next_work_item(); + return NULL; +} + +inline tbb::task* WorkItemTask::execute() +{ + m_pwi->run(); + return NULL; +} + +inline tbb::task* WorkBatchTask::execute() +{ + m_wb.run(); + return NULL; +} + +} } //namespace CGAL::Mesh_3 + +#else // !CGAL_LINKED_WITH_TBB + +namespace CGAL { namespace Mesh_3 { + typedef void WorksharingDataStructureType; +} } //namespace CGAL::Mesh_3 + +#endif // CGAL_LINKED_WITH_TBB + +#endif // CGAL_MESH_3_WORKSHARING_DATA_STRUCTURES_H diff -Nru cgal-4.4/include/CGAL/Mesh_cell_base_3.h cgal-4.5/include/CGAL/Mesh_cell_base_3.h --- cgal-4.4/include/CGAL/Mesh_cell_base_3.h 2013-10-16 19:00:17.000000000 +0000 +++ cgal-4.5/include/CGAL/Mesh_cell_base_3.h 2014-08-29 13:58:16.000000000 +0000 @@ -30,21 +30,84 @@ #include #include -#include +#include #include #include +#include + +#include + +#ifdef CGAL_LINKED_WITH_TBB +# include +#endif namespace CGAL { + +// Sequential +template +class Mesh_cell_base_3_base +{ +public: +#if defined(CGAL_MESH_3_USE_LAZY_SORTED_REFINEMENT_QUEUE) \ + || defined(CGAL_MESH_3_USE_LAZY_UNSORTED_REFINEMENT_QUEUE) + + // Erase counter (cf. Compact_container) + unsigned int erase_counter() const + { + return this->m_erase_counter; + } + void set_erase_counter(unsigned int c) + { + this->m_erase_counter = c; + } + void increment_erase_counter() + { + ++this->m_erase_counter; + } + +private: + typedef unsigned int Erase_counter_type; + Erase_counter_type m_erase_counter; +#endif +}; + +#ifdef CGAL_LINKED_WITH_TBB +// Specialized version (parallel) +template <> +class Mesh_cell_base_3_base +{ +public: + // Erase counter (cf. Compact_container) + unsigned int erase_counter() const + { + return this->m_erase_counter; + } + void set_erase_counter(unsigned int c) + { + this->m_erase_counter = c; + } + void increment_erase_counter() + { + ++this->m_erase_counter; + } +protected: + typedef tbb::atomic Erase_counter_type; + Erase_counter_type m_erase_counter; +}; +#endif // CGAL_LINKED_WITH_TBB + // Class Mesh_cell_base_3 // Cell base class used in 3D meshing process. // Adds information to Cb about the cell of the input complex containing it template< class GT, - class MD, - class Cb = CGAL::Regular_triangulation_cell_base_3< - GT, CGAL::Triangulation_cell_base_with_circumcenter_3 > > + class MD, + class Cb= CGAL::Regular_triangulation_cell_base_with_weighted_circumcenter_3< + GT, CGAL::Regular_triangulation_cell_base_3 > > class Mesh_cell_base_3 -: public Mesh_3::Mesh_surface_cell_base_3 +: public Mesh_3::Mesh_surface_cell_base_3, + public Mesh_cell_base_3_base< + typename Mesh_3::Mesh_surface_cell_base_3::Tds::Concurrency_tag> { typedef typename GT::FT FT; @@ -83,6 +146,7 @@ , next_intrusive_() , previous_intrusive_() #endif + , time_stamp_(-1) {} Mesh_cell_base_3 (Vertex_handle v0, @@ -97,6 +161,7 @@ , next_intrusive_() , previous_intrusive_() #endif + , time_stamp_(-1) {} Mesh_cell_base_3 (Vertex_handle v0, @@ -115,6 +180,7 @@ , next_intrusive_() , previous_intrusive_() #endif + , time_stamp_(-1) {} // Default copy constructor and assignment operator are ok @@ -157,7 +223,19 @@ previous_intrusive_ = c; } #endif // CGAL_INTRUSIVE_LIST - + + /// For the determinism of Compact_container iterators + ///@{ + typedef Tag_true Has_timestamp; + + std::size_t time_stamp() const { + return time_stamp_; + } + void set_time_stamp(const std::size_t& ts) { + time_stamp_ = ts; + } + ///@} + private: // The index of the cell of the input complex that contains me Subdomain_index subdomain_index_; @@ -168,11 +246,10 @@ #ifdef CGAL_INTRUSIVE_LIST Cell_handle next_intrusive_, previous_intrusive_; #endif + std::size_t time_stamp_; }; // end class Mesh_cell_base_3 - - template < class GT, class MT, class Cb > std::istream& operator>>(std::istream &is, diff -Nru cgal-4.4/include/CGAL/Mesh_complex_3_in_triangulation_3.h cgal-4.5/include/CGAL/Mesh_complex_3_in_triangulation_3.h --- cgal-4.4/include/CGAL/Mesh_complex_3_in_triangulation_3.h 2013-07-06 19:00:27.000000000 +0000 +++ cgal-4.5/include/CGAL/Mesh_complex_3_in_triangulation_3.h 2014-10-09 19:00:09.000000000 +0000 @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2010 INRIA Sophia-Antipolis (France). +// Copyright (c) 2009-2014 INRIA Sophia-Antipolis (France). // Copyright (c) 2010-2013 GeometryFactory Sarl (France). // All rights reserved. // @@ -17,26 +17,27 @@ // $Id$ // // -// Author(s) : Stephane Tayeb +// Author(s) : Stephane Tayeb, Clement Jamin // //****************************************************************************** -// File Description : +// File Description : //****************************************************************************** #ifndef CGAL_MESH_COMPLEX_3_IN_TRIANGULATION_3_H #define CGAL_MESH_COMPLEX_3_IN_TRIANGULATION_3_H -#include -#include -#include -#include -#include #include #include #include +#include +#include +#include +#include +#include +#include namespace CGAL { @@ -45,57 +46,70 @@ typename CornerIndex = int, typename CurveSegmentIndex = int> class Mesh_complex_3_in_triangulation_3 : - public Mesh_3::Mesh_complex_3_in_triangulation_3_base + public Mesh_3::Mesh_complex_3_in_triangulation_3_base< + Tr, typename Tr::Concurrency_tag> { +public: + typedef typename Tr::Concurrency_tag Concurrency_tag; + +private: typedef Mesh_complex_3_in_triangulation_3< Tr,CornerIndex,CurveSegmentIndex> Self; - typedef Mesh_3::Mesh_complex_3_in_triangulation_3_base Base; - + typedef Mesh_3::Mesh_complex_3_in_triangulation_3_base< + Tr,Concurrency_tag> Base; + public: typedef typename Base::size_type size_type; + typedef typename Tr::Point Point; typedef typename Base::Edge Edge; + typedef typename Base::Facet Facet; typedef typename Base::Vertex_handle Vertex_handle; + typedef typename Base::Cell_handle Cell_handle; typedef CornerIndex Corner_index; typedef CurveSegmentIndex Curve_segment_index; - + typedef typename Base::Triangulation Triangulation; - + + using Base::surface_patch_index; + private: // Type to store the edges: // - a set of std::pair (ordered at insertion) // - which allows fast lookup from one Vertex_handle // - each element of the set has an associated info (Curve_segment_index) value - typedef boost::bimaps::bimap< + typedef boost::bimaps::bimap< boost::bimaps::multiset_of, boost::bimaps::multiset_of, boost::bimaps::set_of_relation<>, boost::bimaps::with_info > Edge_map; typedef typename Edge_map::value_type Internal_edge; - + // Type to store the corners typedef std::map Corner_map; - + // Type to store far vertices + typedef std::vector Far_vertices_vec; + public: /** * Constructor */ - Mesh_complex_3_in_triangulation_3() + Mesh_complex_3_in_triangulation_3() : Base() , edges_() , corners_() {} - + /** * Copy constructor */ Mesh_complex_3_in_triangulation_3(const Self& rhs); - + /** * Destructor */ virtual ~Mesh_complex_3_in_triangulation_3() {} - + /** * Assignement operator */ @@ -104,7 +118,7 @@ swap(rhs); return *this; } - + /** * Swaps this & rhs */ @@ -113,8 +127,9 @@ Base::swap(rhs); edges_.swap(rhs.edges_); corners_.swap(rhs.corners_); + far_vertices_.swap(rhs.far_vertices_); } - + /** * Clears data of c3t3 */ @@ -124,16 +139,19 @@ edges_.clear(); corners_.clear(); } - + /// Import Base functions using Base::is_in_complex; using Base::add_to_complex; using Base::remove_from_complex; - + using Base::triangulation; + using Base::set_surface_patch_index; + + /** * Add edge e to complex, with Curve_segment_index index - */ + */ void add_to_complex(const Edge& e, const Curve_segment_index& index) { @@ -141,7 +159,7 @@ e.first->vertex(e.third), index); } - + /** * Add edge (v1,v2) to complex, with Curve_segment_index index */ @@ -151,7 +169,7 @@ { add_to_complex(make_internal_edge(v1,v2), index); } - + /** * Mark vertex \c v as a corner of the complex */ @@ -163,12 +181,12 @@ /** * Remove edge \c e from complex - */ + */ void remove_from_complex(const Edge& e) { remove_from_complex(e.first->vertex(e.second), e.first->vertex(e.third)); } - + /** * Remove edge (v1,v2) from complex */ @@ -176,7 +194,7 @@ { remove_from_complex(make_internal_edge(v1,v2)); } - + /** * Remove vertex \c v from complex */ @@ -185,7 +203,65 @@ corners_.erase(v); v->set_dimension(-1); } + + std::size_t number_of_far_points() const + { + return far_vertices_.size(); + } + + void add_far_point(const Point &p) + { + far_vertices_.push_back(triangulation().insert(p)); + } + void add_far_point(Vertex_handle vh) + { + far_vertices_.push_back(vh); + } + + void remove_far_points() + { + Triangulation &tr = triangulation(); + //triangulation().remove(far_vertices_.begin(), far_vertices_.end()); + typename Far_vertices_vec::const_iterator it = far_vertices_.begin(); + typename Far_vertices_vec::const_iterator it_end = far_vertices_.end(); + for ( ; it != it_end ; ++it) + { + std::vector new_cells; + new_cells.reserve(32); + tr.remove_and_give_new_cells(*it, std::back_inserter(new_cells)); + + typename std::vector::iterator nc_it = new_cells.begin(); + typename std::vector::iterator nc_it_end = new_cells.end(); + for ( ; nc_it != nc_it_end ; ++nc_it) + { + Cell_handle c = *nc_it; + for (int i = 0 ; i < 4 ; ++i) + { + Facet mirror_facet = tr.mirror_facet(std::make_pair(c, i)); + if (is_in_complex(mirror_facet)) + { + set_surface_patch_index(c, i, + surface_patch_index(mirror_facet)); + c->set_facet_surface_center(i, + mirror_facet.first->get_facet_surface_center(mirror_facet.second)); + } + } + /*int i_inf; + if (c->has_vertex(tr.infinite_vertex(), i_inf)) + { + Facet mirror_facet = tr.mirror_facet(std::make_pair(c, i_inf)); + if (is_in_complex(mirror_facet)) + { + set_surface_patch_index(c, i_inf, + surface_patch_index(mirror_facet)); + } + }*/ + } + } + far_vertices_.clear(); + } + /** * Returns the number of edges of c3t3 */ @@ -205,7 +281,7 @@ { return corners_.size(); } - + /** * Returns true if edge \c e is in complex */ @@ -213,7 +289,7 @@ { return is_in_complex(e.first->vertex(e.second), e.first->vertex(e.third)); } - + /** * Returns true if edge (v1,v2) is in C3T3 */ @@ -229,7 +305,7 @@ { return (corners_.find(v) != corners_.end()); } - + /** * Returns Curve_segment_index of edge \c e */ @@ -238,7 +314,7 @@ return curve_segment_index(e.first->vertex(e.second), e.first->vertex(e.third)); } - + /** * Returns Curve_segment_index of edge \c (v1,v2) */ @@ -247,7 +323,7 @@ { return curve_index(make_internal_edge(v1,v2)); } - + /** * Returns Corner_index of vertex \c v */ @@ -257,25 +333,25 @@ if ( corners_.end() != it ) { return it->second; } return Corner_index(); } - + /** * Fills \c out with incident edges (1-dimensional features of \c v. * OutputIterator value type is std::pair - * \pre v->in_dimension() < 2 + * \pre v->in_dimension() < 2 */ template OutputIterator adjacent_vertices_in_complex(const Vertex_handle& v, OutputIterator out) const; - + // ----------------------------------- // Undocumented // ----------------------------------- - + /** * Returns true if c3t3 is valid */ bool is_valid(bool verbose = false) const; - + // ----------------------------------- // Complex traversal // ----------------------------------- @@ -289,15 +365,15 @@ const Curve_segment_index& index = Curve_segment_index()) : c3t3_(c3t3) , index_(index) { } - + template bool operator()(Iterator it) const - { + { if ( index_ == Curve_segment_index() ) { return ! c3t3_.is_in_complex(*it); } else { return c3t3_.curve_segment_index(*it) != index_; } } }; - + class Vertex_iterator_not_in_complex { const Self& c3t3_; @@ -307,15 +383,15 @@ const Corner_index& index = Corner_index()) : c3t3_(c3t3) , index_(index) { } - + template bool operator()(const ItMap it) const - { + { if ( index_ == Corner_index() ) { return false; } else { return it->second != index_; } } }; - + // Filtered iterator typedef Filter_iterator< typename Corner_map::const_iterator, @@ -325,7 +401,7 @@ typedef boost::transform_iterator < Mesh_3::internal::First_of, Vertex_map_filter_iterator > Vertex_map_iterator_first; - + // Iterator type to remove a level of referencing class Vertex_map_iterator_first_dereference : public boost::iterator_adaptor < @@ -345,26 +421,26 @@ public: typedef typename Vertex_map_iterator_first::reference pointer; typedef typename iterator_adaptor_::reference reference; - + Vertex_map_iterator_first_dereference() : Self::iterator_adaptor_() { } - + template < typename Iterator > Vertex_map_iterator_first_dereference(Iterator i) : Self::iterator_adaptor_(typename Self::iterator_adaptor_::base_type(i)) { } - + pointer operator->() const { return *(this->base()); } reference operator*() const { return **(this->base()); } operator Vertex_handle() { return Vertex_handle(*(this->base())); } }; - + public: /// Iterator type to visit the edges of the 1D complex. typedef Filter_iterator< typename Triangulation::Finite_edges_iterator, Edge_iterator_not_in_complex > Edges_in_complex_iterator; - + /// Returns a Facets_in_complex_iterator to the first facet of the 1D complex Edges_in_complex_iterator edges_in_complex_begin() const { @@ -372,7 +448,7 @@ Edge_iterator_not_in_complex(*this), this->triangulation().finite_edges_begin()); } - + /// Returns a Facets_in_complex_iterator to the first facet of the 1D complex Edges_in_complex_iterator edges_in_complex_begin(const Curve_segment_index& index) const @@ -381,17 +457,17 @@ Edge_iterator_not_in_complex(*this,index), this->triangulation().finite_edges_begin()); } - + /// Returns past-the-end iterator on facet of the 1D complex Edges_in_complex_iterator edges_in_complex_end(const Curve_segment_index& = Curve_segment_index()) const { return CGAL::filter_iterator(this->triangulation().finite_edges_end(), Edge_iterator_not_in_complex(*this)); } - + /// Iterator type to visit the edges of the 0D complex. typedef Vertex_map_iterator_first_dereference Vertices_in_complex_iterator; - + /// Returns a Vertices_in_complex_iterator to the first vertex of the 0D complex Vertices_in_complex_iterator vertices_in_complex_begin() const { @@ -407,20 +483,20 @@ return CGAL::filter_iterator(corners_.end(), Vertex_iterator_not_in_complex(*this,index), corners_.begin()); - } - + } + /// Returns past-the-end iterator on facet of the 0D complex Vertices_in_complex_iterator vertices_in_complex_end() const { return CGAL::filter_iterator(corners_.end(), Vertex_iterator_not_in_complex(*this)); - } - - + } + + private: /** * Creates an Internal_edge object (i.e a pair of ordered Vertex_handle) - */ + */ Internal_edge make_internal_edge(const Vertex_handle& v1, const Vertex_handle& v2) const { @@ -435,7 +511,7 @@ { return (curve_index(edge) != Curve_segment_index() ); } - + /** * Add edge \c edge to complex, with Curve_segment_index index */ @@ -450,7 +526,7 @@ std::pair it = edges_.insert(edge); it.first->info = index; } - + /** * Remove edge \c edge from complex */ @@ -468,10 +544,11 @@ if ( edges_.end() != it ) { return it->info; } return Curve_segment_index(); } - + private: Edge_map edges_; Corner_map corners_; + Far_vertices_vec far_vertices_; }; @@ -483,29 +560,43 @@ , corners_() { // Copy edges - for ( typename Edge_map::const_iterator it = rhs.edges_.begin(), + for ( typename Edge_map::const_iterator it = rhs.edges_.begin(), end = rhs.edges_.end() ; it != end ; ++it ) { const Vertex_handle& va = it->right; const Vertex_handle& vb = it->left; - + Vertex_handle new_va; this->triangulation().is_vertex(va->point(), new_va); - + Vertex_handle new_vb; this->triangulation().is_vertex(vb->point(), new_vb); - + this->add_to_complex(make_internal_edge(new_va,new_vb), it->info); } - + // Copy corners - for ( typename Corner_map::const_iterator it = rhs.corners_.begin(), + for ( typename Corner_map::const_iterator it = rhs.corners_.begin(), end = rhs.corners_.end() ; it != end ; ++it ) { Vertex_handle new_v; this->triangulation().is_vertex(it->first->point(), new_v); this->add_to_complex(new_v, it->second); } + + // Parse vertices to identify far vertices + if (rhs.far_vertices_.size() > 0) + { + Triangulation &tr = triangulation(); + typename Tr::Finite_vertices_iterator vit = tr.finite_vertices_begin(); + for(typename Tr::Finite_vertices_iterator end = tr.finite_vertices_end(); + vit != end ; ++vit) + { + if (vit->in_dimension() == -1) + far_vertices_.push_back(vit); + } + CGAL_assertion(far_vertices_.size() == rhs.far_vertices_.size()); + } } @@ -516,7 +607,7 @@ adjacent_vertices_in_complex(const Vertex_handle& v, OutputIterator out) const { CGAL_precondition(v->in_dimension() < 2); - + typedef typename Edge_map::right_const_iterator Rcit; typedef typename Edge_map::left_const_iterator Lcit; @@ -526,14 +617,14 @@ { *out++ = std::make_pair(rit->second, rit->info); } - + // Add edges containing v on the right std::pair range_left = edges_.left.equal_range(v); for ( Lcit lit = range_left.first ; lit != range_left.second ; ++lit ) { *out++ = std::make_pair(lit->second, lit->info); } - + return out; } @@ -548,7 +639,7 @@ typedef Weight FT; std::map vertex_map; - + // Fill map counting neighbor number for each vertex of an edge for ( typename Edge_map::const_iterator it = edges_.begin(), end = edges_.end() ; it != end ; ++it ) @@ -556,12 +647,12 @@ const Vertex_handle& v1 = it->right; if ( vertex_map.find(v1) == vertex_map.end() ) { vertex_map[v1] = 1; } else { vertex_map[v1] += 1; } - + const Vertex_handle& v2 = it->left; if ( vertex_map.find(v2) == vertex_map.end() ) { vertex_map[v2] = 1; } else { vertex_map[v2] += 1; } } - + // Verify that each vertex has 2 neighbors if it's not a corner for ( typename std::map::iterator vit = vertex_map.begin(), vend = vertex_map.end() ; vit != vend ; ++vit ) @@ -576,53 +667,57 @@ return false; } } - + // Verify that balls of each edge intersect for ( typename Edge_map::const_iterator it = edges_.begin(), end = edges_.end() ; it != end ; ++it ) { const Bare_point& p = it->right->point().point(); const Bare_point& q = it->left->point().point(); - - typename Tr::Geom_traits::Construct_sphere_3 sphere = + + typename Tr::Geom_traits::Construct_sphere_3 sphere = this->triangulation().geom_traits().construct_sphere_3_object(); - typename Tr::Geom_traits::Do_intersect_3 do_intersect = + typename Tr::Geom_traits::Do_intersect_3 do_intersect = this->triangulation().geom_traits().do_intersect_3_object(); const FT& sq_rp = it->right->point().weight(); const FT& sq_rq = it->left->point().weight(); - + if ( ! do_intersect(sphere(p, sq_rp), sphere(q, sq_rq)) ) { - std::cerr << "Point p[" << p << "], dim=" << it->right->in_dimension() - << " and q[" << q << "], dim=" << it->left->in_dimension() + std::cerr << "Point p[" << p << "], dim=" << it->right->in_dimension() + << " and q[" << q << "], dim=" << it->left->in_dimension() << " form an edge but do not intersect !\n"; return false; } } - + return true; } -template < class Tr, class CI_, class CSI_> -std::ostream & -operator<< (std::ostream& os, +template +std::ostream & +operator<< (std::ostream& os, const Mesh_complex_3_in_triangulation_3 &c3t3) { // TODO: implement edge saving - return os << static_cast&>(c3t3); + typedef typename Mesh_complex_3_in_triangulation_3::Concurrency_tag Concurrency_tag; + return os << static_cast< + const Mesh_3::Mesh_complex_3_in_triangulation_3_base&>(c3t3); } -template < class Tr, class CI_, class CSI_> -std::istream & -operator>> (std::istream& is, +template +std::istream & +operator>> (std::istream& is, Mesh_complex_3_in_triangulation_3 &c3t3) { // TODO: implement edge loading - is >> static_cast&>(c3t3); + typedef typename Mesh_complex_3_in_triangulation_3::Concurrency_tag Concurrency_tag; + is >> static_cast< + Mesh_3::Mesh_complex_3_in_triangulation_3_base&>(c3t3); return is; } diff -Nru cgal-4.4/include/CGAL/Mesh_criteria_3.h cgal-4.5/include/CGAL/Mesh_criteria_3.h --- cgal-4.4/include/CGAL/Mesh_criteria_3.h 2012-11-13 13:13:57.000000000 +0000 +++ cgal-4.5/include/CGAL/Mesh_criteria_3.h 2014-08-29 13:58:16.000000000 +0000 @@ -27,6 +27,7 @@ #ifndef CGAL_MESH_CRITERIA_3_H #define CGAL_MESH_CRITERIA_3_H +#include #include #include #include @@ -35,6 +36,12 @@ namespace CGAL { namespace parameters { + +// see +CGAL_PRAGMA_DIAG_PUSH +// see +CGAL_MESH_3_IGNORE_BOOST_PARAMETER_NAME_WARNINGS + BOOST_PARAMETER_NAME( (edge_size, tag) edge_size_ ) BOOST_PARAMETER_NAME( (edge_sizing_field, tag) edge_sizing_field_ ) BOOST_PARAMETER_NAME( (facet_angle, tag) facet_angle_ ) @@ -47,6 +54,9 @@ BOOST_PARAMETER_NAME( (cell_size, tag) cell_size_ ) BOOST_PARAMETER_NAME( (cell_sizing_field, tag) cell_sizing_field_ ) BOOST_PARAMETER_NAME( (sizing_field, tag) sizing_field_ ) + +CGAL_PRAGMA_DIAG_POP + } // end namespace parameters namespace internal { diff -Nru cgal-4.4/include/CGAL/Mesh_domain_with_polyline_features_3.h cgal-4.5/include/CGAL/Mesh_domain_with_polyline_features_3.h --- cgal-4.4/include/CGAL/Mesh_domain_with_polyline_features_3.h 2014-03-29 20:00:20.000000000 +0000 +++ cgal-4.5/include/CGAL/Mesh_domain_with_polyline_features_3.h 2014-08-29 13:58:16.000000000 +0000 @@ -54,13 +54,13 @@ typedef typename Kernel::FT FT; typedef std::vector Data; - + public: typedef typename Data::const_iterator const_iterator; - + Polyline() {} ~Polyline() {} - + /// Add a point at the end of the polyline void add_point(const Point_3& p) { @@ -68,33 +68,33 @@ points_.push_back(p); } } - + /// Returns the starting point of the polyline const Point_3& start_point() const { CGAL_assertion( ! points_.empty() ); return points_.front(); } - + /// Returns the ending point of the polyline const Point_3& end_point() const { CGAL_assertion( ! points_.empty() ); - return points_.back(); + return points_.back(); } - + /// Returns true if the polyline is not degenerated bool is_valid() const { return points_.size() > 1; } - + /// Returns true if polyline is a cycle bool is_cycle() const { return start_point() == end_point(); } - + /// Returns the length of the polyline FT length() const { @@ -102,29 +102,29 @@ FT result (0); const_iterator it = points_.begin(); const_iterator previous = it++; - + for ( const_iterator end = points_.end() ; it != end ; ++it, ++previous ) { result += distance(*previous,*it); } - + return result; } - + /// Returns signed geodesic distance between \c p and \c q FT geodesic_distance(const Point_3& p, const Point_3& q, bool /*treat_cycle*/=true) const { CGAL_precondition(is_valid()); - + // Locate p & q on polyline const_iterator pit = locate(p); const_iterator qit = locate(q,false); - + // Compute geodesic distance FT result = (pit <= qit) ? geodesic_distance(p,q,pit,qit) : -geodesic_distance(q,p,qit,pit); - + // Treat cycles: return a positive value if ( is_cycle() && (p==q || result < FT(0)) ) { @@ -133,8 +133,8 @@ return result; } - - + + /// Returns a point at geodesic distance \c distance from p along the /// polyline. The polyline is oriented from starting point to end point. /// The distance could be negative. @@ -142,108 +142,108 @@ { // use first point of the polyline instead of p distance += geodesic_distance(start_point(),p,false); - + // If polyline is a cycle, ensure that distance is given from start_point() if ( is_cycle() ) { if ( distance < FT(0) ) { distance += length(); } else if ( distance > length() ) { distance -= length(); } } - - CGAL_assertion( distance > FT(0) ); - CGAL_assertion( distance < length() ); - + + CGAL_assertion( distance >= FT(0) ); + CGAL_assertion( distance <= length() ); + // Initialize iterators const_iterator pit = points_.begin(); const_iterator previous = pit++; - + // Iterate to find which segment contains the point we want to construct FT segment_length = this->distance(*previous,*pit); while ( distance > segment_length ) { distance -= segment_length; - + // Increment iterators and update length ++previous; ++pit; CGAL_assertion(pit != points_.end()); - + segment_length = this->distance(*previous,*pit); } - + // return point at distance from current segment source typedef typename Kernel::Vector_3 Vector_3; Vector_3 v (*previous, *pit); - + return (*previous) + (distance / CGAL::sqrt(v.squared_length())) * v; } - + bool are_ordered_along(const Point_3& p, const Point_3& q) const { CGAL_precondition(!is_cycle()); - + // Locate p & q on polyline const_iterator pit = locate(p); const_iterator qit = locate(q,true); - + // Points are not located on the same segment if ( pit != qit ) { return (pit <= qit); } - + // pit == qit, then we have to sort p&q along (pit,pit+1) return ( compare_distance(*pit,p,q) != CGAL::LARGER ); } - + private: const_iterator first_segment_source() const { CGAL_precondition(is_valid()); return points_.begin(); } - + const_iterator last_segment_source() const { CGAL_precondition(is_valid()); return (points_.end() - 2); } - + FT geodesic_distance(const Point_3& p, const Point_3& q, const_iterator pit, const_iterator qit) const { CGAL_precondition(std::distance(pit,qit) >= 0); - + // If p and q are in the same segment of the polyline if ( pit == qit ) { FT result = distance(p,q); - + // Find the closest point to *pit if ( compare_distance(*pit,p,q) != CGAL::LARGER ) { return result; } else { return -result; } } - + // p is inside [pit,pit+1], pit+1 != qit, q is inside [qit,qit+1] FT result = distance(p,*(pit+1)); result += distance(*qit,q); - + // Add segments between pit+1 and qit to result for ( const_iterator it = (pit+1) ; it != qit ; ++it ) { result += distance(*it,*(it+1)); } - + return result; } - /// Returns an iterator on the starting point of the segment of the + /// Returns an iterator on the starting point of the segment of the /// polyline which contains p /// if end_point_first is true, then --end is returned instead of begin /// if p is the starting point of a cycle. const_iterator locate(const Point_3& p, bool end_point_first=false) const { CGAL_precondition(is_valid()); - + // First look if p is one of the points of the polyline const_iterator result = std::find(points_.begin(), points_.end(), p); if ( result != points_.end() ) @@ -251,7 +251,7 @@ if ( result != points_.begin() ) { return --result; } else - { + { // Treat cycles if ( end_point_first && p == end_point() ) { return last_segment_source(); } @@ -269,7 +269,7 @@ const_iterator nearest_vertex = it; result = nearest_vertex; bool nearest_is_a_segment = false; - + while ( ++it != points_.end() ) { Segment_3 seg (*previous, *it); @@ -311,27 +311,27 @@ return result; } } - + // FT squared_distance(const Point_3& p, const Point_3& q) const // { // typename Kernel::Compute_squared_distance_3 sq_distance = // Kernel().compute_squared_distance_3_object(); // return sq_distance(p,q); // } - + FT distance(const Point_3& p, const Point_3& q) const { return CGAL::sqrt(squared_distance(p, q)); } - Angle angle(const Point_3& p, + Angle angle(const Point_3& p, const Point_3& angle_vertex_point, - const Point_3& q) const + const Point_3& q) const { typename Kernel::Angle_3 compute_angle = Kernel().angle_3_object(); return compute_angle(p,angle_vertex_point,q); } - + template CGAL::Sign compare_distance(const Point_3& p, const T1& obj1, @@ -345,7 +345,7 @@ public: Data points_; }; // end class Polyline - + template struct Mesh_domain_segment_of_curve_primitive{ @@ -353,7 +353,7 @@ typedef typename Map_value_type::first_type Curve_id; typedef typename Map_value_type::second_type Polyline; - typedef std::pair Id; typedef typename std::iterator_traits< @@ -362,7 +362,7 @@ typedef typename Gt::Segment_3 Datum; Id id_; - + Mesh_domain_segment_of_curve_primitive(Id id) : id_(id) {} const Id& id() const { return id_; } @@ -427,7 +427,7 @@ // Index types typedef typename Base::Index Index; - typedef typename Base::Surface_patch_index + typedef typename Base::Surface_patch_index Surface_patch_index; typedef int Curve_segment_index; @@ -437,10 +437,10 @@ typedef Gt R; typedef typename Base::Point_3 Point_3; typedef typename Gt::FT FT; - + typedef CGAL::Tag_true Has_features; - + #ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES template Mesh_domain_with_polyline_features_3(const T& ...t) @@ -472,11 +472,11 @@ , curves_aabb_tree_is_built(false) {} template - Mesh_domain_with_polyline_features_3(const T1& o1, const T2& o2, + Mesh_domain_with_polyline_features_3(const T1& o1, const T2& o2, const T3& o3) : Base(o1, o2, o3) , current_corner_index_(1) - , current_curve_index_(1) + , current_curve_index_(1) , curves_aabb_tree_is_built(false) {} #endif @@ -486,13 +486,13 @@ /// OutputIterator value type is std::pair template OutputIterator get_corners(OutputIterator out) const; - + /// OutputIterator value type is CGAL::cpp11::tuple, std::pair > template OutputIterator get_curve_segments(OutputIterator out) const; - /// Returns the geodesic distance between points p and q of curve + /// Returns the geodesic distance between points p and q of curve /// \c curve_index FT geodesic_distance(const Point_3& p, const Point_3& q, const Curve_segment_index& curve_index) const; @@ -503,17 +503,17 @@ construct_point_on_curve_segment(const Point_3& starting_point, const Curve_segment_index& curve_index, FT distance) const; - + /// Returns the sign of the orientation of p,q,r along curve segment /// of index \c index CGAL::Sign distance_sign_along_cycle(const Point_3& p, const Point_3& q, const Point_3& r, const Curve_segment_index& index) const; - + /// Returns true if curve \c curve_index is a cycle bool is_cycle(const Point_3&, const Curve_segment_index& index) const; - + /// Returns an Index from a Curve_segment_index Index index_from_curve_segment_index(const Curve_segment_index& index) const { return Index(index); } @@ -521,11 +521,11 @@ /// Returns an Curve_segment_index from an Index Curve_segment_index curve_segment_index(const Index& index) const { return boost::get(index); } - + /// Returns an Index from a Corner_index Index index_from_corner_index(const Corner_index& index) const { return Index(index); } - + /// Returns an Corner_index from an Index Corner_index corner_index(const Index& index) const { return boost::get(index); } @@ -549,20 +549,20 @@ template IndicesOutputIterator get_incidences(Curve_segment_index id, IndicesOutputIterator out) const; - + template IndicesOutputIterator get_corner_incidences(Curve_segment_index id, IndicesOutputIterator out) const; typedef std::set Surface_patch_index_set; - const Surface_patch_index_set& + const Surface_patch_index_set& get_incidences(Curve_segment_index id) const; void display_corner_incidences(std::ostream& os, Corner_index id); template - void + void add_features(InputIterator first, InputIterator last) { add_features(first, last, CGAL::Emptyset_iterator()); } @@ -578,8 +578,8 @@ /// Returns the sign of the geodesic distance between \c p and \c q /// Precondition: index is not a cycle CGAL::Sign distance_sign(const Point_3& p, const Point_3& q, - const Curve_segment_index& index) const; - + const Curve_segment_index& index) const; + /// Returns Index associated to p (p must be the coordinates of a corner /// point) Index point_corner_index(const Point_3& p) const; @@ -597,7 +597,7 @@ Gt, typename Edges::const_iterator> Curves_primitives; - typedef CGAL::AABB_traits AABB_curves_traits; Corners corners_; @@ -621,17 +621,17 @@ if(!curves_aabb_tree_is_built) build_curves_aabb_tree(); return curves_aabb_tree_; } - + void build_curves_aabb_tree() const { std::cerr << "Building curves AABB tree...\n"; curves_aabb_tree_.clear(); - for(typename Edges::const_iterator + for(typename Edges::const_iterator edges_it = edges_.begin(), edges_end = edges_.end(); edges_it != edges_end; ++edges_it) { const Polyline& polyline = edges_it->second; - for(typename Polyline::const_iterator + for(typename Polyline::const_iterator pit = polyline.points_.begin(), end = polyline.points_.end() - 1; pit != end; ++pit) @@ -664,7 +664,7 @@ { *out++ = std::make_pair(cit->second,cit->first); } - + return out; } @@ -678,10 +678,10 @@ eit = edges_.begin(), end = edges_.end() ; eit != end ; ++eit ) { CGAL_assertion( eit->second.is_valid() ); - + const Point_3& p = eit->second.start_point(); const Point_3& q = eit->second.end_point(); - + Index p_index, q_index; if ( ! eit->second.is_cycle() ) { @@ -693,15 +693,15 @@ p_index = index_from_curve_segment_index(eit->first); q_index = p_index; } - + *out++ = CGAL::cpp11::make_tuple(eit->first, std::make_pair(p,p_index), std::make_pair(q,q_index)); } - + return out; } - + template typename Mesh_domain_with_polyline_features_3::Index @@ -714,7 +714,7 @@ CGAL_assertion(false); return Index(); } - + return p_index_it->second; } @@ -728,7 +728,7 @@ // Get corresponding polyline typename Edges::const_iterator eit = edges_.find(curve_index); CGAL_assertion(eit != edges_.end()); - + // Compute geodesic_distance return eit->second.geodesic_distance(p,q); } @@ -744,7 +744,7 @@ // Get corresponding polyline typename Edges::const_iterator eit = edges_.find(curve_index); CGAL_assertion(eit != edges_.end()); - + // Return point at geodesic_distance distance from starting_point return eit->second.point_at(starting_point,distance); } @@ -778,7 +778,7 @@ // Insert one edge for each element for( ; first != last ; ++first ) { - Curve_segment_index curve_id = + Curve_segment_index curve_id = insert_edge(first->polyline_content.begin(), first->polyline_content.end()); edges_incidences_[curve_id] = first->context.adjacent_patches_ids; *indices_out++ = curve_id; @@ -900,7 +900,7 @@ Mesh_domain_with_polyline_features_3:: compute_corners_incidences() { - for(typename Corners::iterator + for(typename Corners::iterator cit = corners_.begin(), end = corners_.end(); cit != end; /* the loop variable is incremented in the body */) { @@ -925,7 +925,7 @@ BOOST_FOREACH(Curve_segment_index curve_index, corner_tmp_incidences) { - get_incidences(curve_index, + get_incidences(curve_index, std::inserter(incidences, incidences.begin())); } @@ -939,7 +939,7 @@ } template -const typename Mesh_domain_with_polyline_features_3::Surface_patch_index_set& +const typename Mesh_domain_with_polyline_features_3::Surface_patch_index_set& Mesh_domain_with_polyline_features_3:: get_incidences(Curve_segment_index id) const { @@ -952,7 +952,7 @@ Mesh_domain_with_polyline_features_3:: register_corner(const Point_3& p, const Curve_segment_index& curve_index) { - + typename Corners::iterator cit = corners_.lower_bound(p); // If the corner already exists, returns... @@ -977,9 +977,9 @@ insert_edge(InputIterator first, InputIterator last) { CGAL_assertion(std::distance(first,last) > 1); - + const Curve_segment_index curve_index = current_curve_index_++; - + // Fill corners // // For a cycle, the "first" point of the cycle is registered as a @@ -991,11 +991,11 @@ { register_corner(*boost::prior(last), curve_index); } - + // Create a new polyline std::pair insertion = edges_.insert(std::make_pair(curve_index,Polyline())); - + // Fill polyline with data while ( first != last ) { @@ -1014,7 +1014,7 @@ typename Edges::const_iterator eit = edges_.find(index); CGAL_assertion(eit != edges_.end()); CGAL_precondition( ! eit->second.is_cycle() ); - + if ( p == q ) return CGAL::ZERO; else if ( eit->second.are_ordered_along(p,q) ) @@ -1034,17 +1034,17 @@ // Find edge typename Edges::const_iterator eit = edges_.find(index); CGAL_assertion(eit != edges_.end()); - + // If eit is not a cycle, then the orientation corresponds to the sign // of the distance if ( ! eit->second.is_cycle() ) { return distance_sign(p,r,index); } - + // If p and r are the same point, it correspond to a complete loop on a cycle if ( p == r ) { return CGAL::POSITIVE; } - + // We are on a cycle without any clue (p==q). Return the shortest path as // orientation. if ( p == q ) @@ -1054,15 +1054,15 @@ if ( pr < rp ) { return CGAL::POSITIVE; } else { return CGAL::NEGATIVE; } } - + // If pq or pr is negative, edge is not a cycle, thus geodesic_distance // gives the answer. FT pq = eit->second.geodesic_distance(p,q); FT pr = eit->second.geodesic_distance(p,r); CGAL_assertion(pq > FT(0)); CGAL_assertion(pr > FT(0)); - - // Compare pq and pr + + // Compare pq and pr if ( pq <= pr ) { return CGAL::POSITIVE; } else { return CGAL::NEGATIVE; } } @@ -1075,7 +1075,7 @@ // Find edge typename Edges::const_iterator eit = edges_.find(index); CGAL_assertion(eit != edges_.end()); - + return eit->second.is_cycle(); } diff -Nru cgal-4.4/include/CGAL/Mesher_level.h cgal-4.5/include/CGAL/Mesher_level.h --- cgal-4.4/include/CGAL/Mesher_level.h 2012-11-13 13:13:57.000000000 +0000 +++ cgal-4.5/include/CGAL/Mesher_level.h 2014-08-29 13:58:16.000000000 +0000 @@ -78,7 +78,7 @@ /**< Previous level type, defaults to \c Null_mesher_level. */ class Triangulation_traits /** Traits class that defines types for the - triangulation. */ + triangulation. */ > class Mesher_level { @@ -121,7 +121,7 @@ Derived, Element, Previous_level, - Triangulation_traits> Self; + Triangulation_traits> Self; /** \name CONSTRUCTORS */ Mesher_level(Previous_level& previous) @@ -193,7 +193,7 @@ /** Actions before testing conflicts for point \c p and element \c e */ template void before_conflicts(const Element& e, const Point& p, - Mesh_visitor visitor) + Mesh_visitor visitor) { visitor.before_conflicts(e, p); derived().before_conflicts_impl(e, p); @@ -207,7 +207,7 @@ the tested element should be reconsidered latter. */ Mesher_level_conflict_status private_test_point_conflict(const Point& p, - Zone& zone) + Zone& zone) { return derived().private_test_point_conflict_impl(p, zone); } @@ -222,7 +222,7 @@ */ Mesher_level_conflict_status test_point_conflict_from_superior(const Point& p, - Zone& zone) + Zone& zone) { return derived().test_point_conflict_from_superior_impl(p, zone); } @@ -254,7 +254,7 @@ * if no point is inserted. */ template void after_no_insertion(const Element& e, const Point& p, Zone& zone, - Mesh_visitor visitor) + Mesh_visitor visitor) { derived().after_no_insertion_impl(e, p, zone); visitor.after_no_insertion(e, p, zone); diff -Nru cgal-4.4/include/CGAL/Meshes/Filtered_deque_container.h cgal-4.5/include/CGAL/Meshes/Filtered_deque_container.h --- cgal-4.4/include/CGAL/Meshes/Filtered_deque_container.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/Meshes/Filtered_deque_container.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,318 @@ +// Copyright (c) 2012 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL: $ +// $Id: $ +// +// +// Author(s) : Clement JAMIN + +#ifndef CGAL_MESHES_FILTERED_DEQUE_CONTAINER_H +#define CGAL_MESHES_FILTERED_DEQUE_CONTAINER_H + +#include +#include +#include +#ifdef CGAL_LINKED_WITH_TBB + #include +#endif + +namespace CGAL { + +namespace Meshes { + + /************************************************ + // Class Filtered_deque_container_base + // Two versions: sequential / parallel + ************************************************/ + + // Sequential + template + class Filtered_deque_container_base + { + public: + typedef std::deque > Container; + typedef typename Container::size_type size_type; + typedef typename Container::value_type value_type; + + void add_to_TLS_lists_impl(bool) {} + Element get_next_local_element_impl() + { return Element(); } + value_type get_next_local_raw_element_impl() + { return value_type(); } + void pop_next_local_element_impl() {} + + protected: + Filtered_deque_container_base() {} + Filtered_deque_container_base(bool) {} + + template + void splice_local_lists_impl(Container &) + {} + + template + bool no_longer_local_element_to_refine_impl(const Predicate &) + { + return true; + } + + template + void insert_raw_element(const value_type &re, Container &container) + { + container.push_back(re); + } + }; + +#ifdef CGAL_LINKED_WITH_TBB + // Parallel + template + class Filtered_deque_container_base + { + public: + typedef std::deque > Container; + typedef typename Container::size_type size_type; + typedef typename Container::value_type value_type; + + void add_to_TLS_lists_impl(bool add) + { + m_add_to_TLS_lists = add; + } + + // Warning: no_longer_local_element_to_refine_impl must have been called + // just before calling get_next_local_element_impl + // (successive calls to "get_next_local_element_impl" are not allowed) + Element get_next_local_element_impl() + { + CGAL_assertion(!m_local_lists.local().empty()); + // Add this? It shouldn't be necessary as user + // is supposed to call "no_longer_element_to_refine_impl" first + /*while( !test(container.front()) ) + { + container.pop_front(); + }*/ + return m_local_lists.local().front().second; + } + + // Warning: no_longer_local_element_to_refine_impl must have been called + // just before calling get_next_local_raw_element_impl + // (successive calls to "get_next_local_raw_element_impl" are not allowed) + value_type get_next_local_raw_element_impl() + { + CGAL_assertion(!m_local_lists.local().empty()); + return m_local_lists.local().front(); + } + + void pop_next_local_element_impl() + { + // Erase last element + m_local_lists.local().pop_front(); + } + + protected: + Filtered_deque_container_base(bool add_to_TLS_lists = false) + : m_add_to_TLS_lists(add_to_TLS_lists) {} + + + template + void splice_local_lists_impl(Container &container) + { + for(typename LocalList::iterator it_list = m_local_lists.begin() ; + it_list != m_local_lists.end() ; + ++it_list ) + { +#ifdef _DEBUG + size_t deque_size = container.size(); + size_t local_list_size = it_list->size(); +#endif + container.insert(container.end(), it_list->begin(), it_list->end()); + it_list->clear(); + } + } + + template + bool no_longer_local_element_to_refine_impl(const Predicate &test) + { + bool is_empty = m_local_lists.local().empty(); + while( !is_empty && !test(m_local_lists.local().front().second) ) + { + pop_next_local_element_impl(); + is_empty = m_local_lists.local().empty(); + } + return is_empty; + } + + template + void insert_raw_element(const value_type &re, Container &container) + { + if (m_add_to_TLS_lists) + m_local_lists.local().push_back(re); + else + container.push_back(re); + } + + + // === Member variables === + + typedef tbb::enumerable_thread_specific< + std::deque > > LocalList; + LocalList m_local_lists; + bool m_add_to_TLS_lists; + }; +#endif // CGAL_LINKED_WITH_TBB + + /************************************************ + // Class Filtered_deque_container + // + // This container is a filtered deque: + // front() and empty() use an object predicate + // to test if the element is ok. + ************************************************/ + + template + class Filtered_deque_container + : public Filtered_deque_container_base + { + public: + typedef Filtered_deque_container_base Base; + typedef typename Base::Container Container; + typedef typename Base::value_type value_type; + typedef typename Base::size_type size_type; + typedef Quality_ Quality; + typedef Element_ Element; + + protected: + // --- protected datas --- + Container container; + Predicate test; + + static bool CompareTwoElements(std::pair e1, + std::pair e2) + { + return (e1.first < e2.first); + } + + public: + + // Constructors - For sequential + Filtered_deque_container() {} + explicit Filtered_deque_container(const Predicate &p) + : test(p) {} + + // Constructors - For parallel + explicit Filtered_deque_container(bool add_to_TLS_lists) + : Base(add_to_TLS_lists) {} + explicit Filtered_deque_container(const Predicate &p, bool add_to_TLS_lists) + : test(p), Base(add_to_TLS_lists) {} + + void splice_local_lists_impl() + { + Base::splice_local_lists_impl(container); + } + + bool no_longer_local_element_to_refine_impl() + { + return Base::no_longer_local_element_to_refine_impl(test); + } + + void insert_raw_element(const value_type &re) + { + Base::insert_raw_element(re, container); + } + + bool no_longer_element_to_refine_impl() + { +#ifdef _DEBUG + size_t deque_size = container.size(); +#endif + bool is_empty = container.empty(); + while( !is_empty && !test(container.front().second) ) + { + pop_next_element_impl(); + is_empty = container.empty(); + } + return is_empty; + } + + // Warning: no_longer_element_to_refine_impl must have been called + // just before calling get_next_element_impl + // (successive calls to "get_next_element_impl" are not allowed) + Element get_next_element_impl() const + { + CGAL_assertion(!container.empty()); + // Add this? It shouldn't be necessary as user + // is supposed to call "no_longer_element_to_refine_impl" first + /*while( !test(container.front()) ) + { + container.pop_front(); + }*/ + return container.front().second; + } + + void add_bad_element(const Element& e, const Quality& q) + { + insert_raw_element(std::make_pair(q, e)); + } + + void pop_next_element_impl() + { + // Erase last element + container.pop_front(); + } + + // Sort + // Worst (smallest) quality first + void sort () + { + std::sort(container.begin(), container.end(), CompareTwoElements); + } + + // Clear + void clear () + { + container.clear(); + } + + // Random shuffle + void random_shuffle () + { + std::random_shuffle(container.begin(), container.end()); + } + + size_type size() const + { + return container.size(); + } + + // Warning: no_longer_element_to_refine_impl must have been called + // just before calling get_next_raw_element_impl + // (successive calls to "get_next_raw_element_impl" are not allowed) + value_type get_next_raw_element_impl() + { + CGAL_assertion(!container.empty()); + return container.front(); + } + + bool is_zombie(const Element &e) const + { + return !test(e); + } + + }; // end Filtered_deque_container + +} // end namespace Mesh_3 +} // end namespace CGAL + +#endif // CGAL_MESHES_FILTERED_DEQUE_CONTAINER_H diff -Nru cgal-4.4/include/CGAL/Meshes/Filtered_multimap_container.h cgal-4.5/include/CGAL/Meshes/Filtered_multimap_container.h --- cgal-4.4/include/CGAL/Meshes/Filtered_multimap_container.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/Meshes/Filtered_multimap_container.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,309 @@ +// Copyright (c) 2012 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL: $ +// $Id: $ +// +// +// Author(s) : Clement JAMIN + +#ifndef CGAL_MESHES_FILTERED_MULTIMAP_CONTAINER_H +#define CGAL_MESHES_FILTERED_MULTIMAP_CONTAINER_H + +#include +#include +#ifdef CGAL_LINKED_WITH_TBB + #include +#endif + +namespace CGAL { + + namespace Meshes { + + /************************************************ + // Class Filtered_multimap_container_base + // Two versions: sequential / parallel + ************************************************/ + + // Sequential + template + class Filtered_multimap_container_base + { + public: + typedef std::multimap Map; + typedef typename Map::size_type size_type; + typedef typename Map::value_type value_type; + + void add_to_TLS_lists_impl(bool) {} + Element get_next_local_element_impl() + { return Element(); } + value_type get_next_local_raw_element_impl() + { return value_type(); } + void pop_next_local_element_impl() {} + + protected: + Filtered_multimap_container_base() {} + Filtered_multimap_container_base(bool) {} + + template + void splice_local_lists_impl(Container &) + {} + + template + bool no_longer_local_element_to_refine_impl(const Predicate &) + { + return true; + } + + template + void insert_raw_element(const value_type &re, Container &container) + { + container.insert(re); + } + }; + +#ifdef CGAL_LINKED_WITH_TBB + // Parallel + template + class Filtered_multimap_container_base + { + public: + typedef std::multimap Map; + typedef typename Map::size_type size_type; + typedef typename Map::value_type value_type; + + void add_to_TLS_lists_impl(bool add) + { + m_add_to_TLS_lists = add; + } + + // Warning: no_longer_local_element_to_refine_impl must have been called + // just before calling get_next_local_element_impl + // (successive calls to "get_next_local_element_impl" are not allowed) + Element get_next_local_element_impl() + { + CGAL_assertion(!m_local_lists.local().empty()); + // Add this? It shouldn't be necessary as user + // is supposed to call "no_longer_element_to_refine_impl" first + /*while( !test(container.front()) ) + { + container.pop_front(); + }*/ + return m_local_lists.local().front().second; + } + + // Warning: no_longer_local_element_to_refine_impl must have been called + // just before calling get_next_local_raw_element_impl + // (successive calls to "get_next_local_raw_element_impl" are not allowed) + value_type get_next_local_raw_element_impl() + { + CGAL_assertion(!m_local_lists.local().empty()); + return m_local_lists.local().front(); + } + + void pop_next_local_element_impl() + { + // Erase last element + m_local_lists.local().pop_front(); + } + + protected: + Filtered_multimap_container_base(bool add_to_TLS_lists = false) + : m_add_to_TLS_lists(add_to_TLS_lists) {} + + template + void splice_local_lists_impl(Container &container) + { + for(typename LocalList::iterator it_list = m_local_lists.begin() ; + it_list != m_local_lists.end() ; + ++it_list ) + { +#ifdef _DEBUG + size_t multimap_size = container.size(); + size_t local_list_size = it_list->size(); +#endif + container.insert(it_list->begin(), it_list->end()); + it_list->clear(); + } + } + + template + bool no_longer_local_element_to_refine_impl(const Predicate &test) + { + bool is_empty = m_local_lists.local().empty(); + while( !is_empty && !test(m_local_lists.local().front().second) ) + { + pop_next_local_element_impl(); + is_empty = m_local_lists.local().empty(); + } + return is_empty; + } + + template + void insert_raw_element(const value_type &re, Container &container) + { + if (m_add_to_TLS_lists) + m_local_lists.local().push_back(re); + else + container.insert(re); + } + + // === Member variables === + + typedef tbb::enumerable_thread_specific< + std::deque > > LocalList; + LocalList m_local_lists; + bool m_add_to_TLS_lists; + }; +#endif // CGAL_LINKED_WITH_TBB + + /************************************************ + // Class Filtered_multimap_container + // + // This container is a filtered multimap: + // front() and empty() use an object predicate + // to test if the element is ok. + ************************************************/ + + template + class Filtered_multimap_container + : public Filtered_multimap_container_base + { + public: + typedef Quality_ Quality; + typedef Element_ Element; + typedef Filtered_multimap_container_base Base; + typedef typename Base::Map Map; + typedef typename Base::value_type value_type; + typedef typename Base::size_type size_type; + + protected: + // --- protected datas --- + Map container; + Predicate test; + + public: + + // Constructors - For sequential + Filtered_multimap_container() {} + explicit Filtered_multimap_container(const Predicate &p) + : test(p) {} + + // Constructors - For parallel + explicit Filtered_multimap_container(bool add_to_TLS_lists) + : Base(add_to_TLS_lists) {} + explicit Filtered_multimap_container(const Predicate &p, bool add_to_TLS_lists) + : test(p), Base(add_to_TLS_lists) {} + + void splice_local_lists_impl() + { +#ifdef _DEBUG + size_t s = size(); +#endif + Base::splice_local_lists_impl(container); + } + + bool no_longer_local_element_to_refine_impl() + { + return Base::no_longer_local_element_to_refine_impl(test); + } + + void insert_raw_element(const value_type &re) + { + Base::insert_raw_element(re, container); + } + + bool no_longer_element_to_refine_impl() + { +#ifdef _DEBUG + size_t multimap_size = container.size(); +#endif + bool is_empty = container.empty(); + while( !is_empty && !test(container.begin()->second) ) + { + pop_next_element_impl(); + is_empty = container.empty(); + } + return is_empty; + } + + // Warning: no_longer_element_to_refine_impl must have been called + // just before calling get_next_element_impl + // (successive calls to "get_next_element_impl" are not allowed) + Element get_next_element_impl() const + { + CGAL_assertion(!container.empty()); + // Add this? It shouldn't be necessary as user + // is supposed to call "no_longer_element_to_refine_impl" first + /*while( !test(container.front()) ) + { + container.pop_front(); + }*/ + return container.begin()->second; + } + + void add_bad_element(const Element& e, const Quality& q) + { + insert_raw_element(std::make_pair(q, e)); + } + + void pop_next_element_impl() + { + // Erase last element + container.erase( container.begin() ); + } + + /*void remove_element(const Element& e) + { + container.erase(container.find(e)); + } + + const Quality& quality(const Element& e) + { + return container[e]; + }*/ + + size_type size() const + { + return container.size(); + } + + // Clear + void clear () + { + container.clear(); + } + + // Warning: no_longer_element_to_refine_impl must have been called + // just before calling get_next_raw_element_impl + // (successive calls to "get_next_raw_element_impl" are not allowed) + value_type get_next_raw_element_impl() + { + CGAL_assertion(!container.empty()); + return *container.begin(); + } + + bool is_zombie(const Element &e) const + { + return !test(e); + } + + }; // end Filtered_multimap_container + +} // end namespace Mesh_3 +} // end namespace CGAL + +#endif // CGAL_MESHES_FILTERED_MULTIMAP_CONTAINER_H diff -Nru cgal-4.4/include/CGAL/Mesh_polyhedron_3.h cgal-4.5/include/CGAL/Mesh_polyhedron_3.h --- cgal-4.4/include/CGAL/Mesh_polyhedron_3.h 2013-07-06 19:00:27.000000000 +0000 +++ cgal-4.5/include/CGAL/Mesh_polyhedron_3.h 2014-08-29 13:58:16.000000000 +0000 @@ -27,6 +27,8 @@ #include #include +#include +#include #include @@ -44,6 +46,8 @@ typedef CGAL::HalfedgeDS_vertex_base Pdv_base; Set_of_indices indices; + std::size_t time_stamp_; + public: int nb_of_feature_edges; @@ -58,6 +62,18 @@ void add_incident_patch(const Patch_id i) { indices.insert(i); } + + /// For the determinism of Compact_container iterators + ///@{ + typedef Tag_true Has_timestamp; + + std::size_t time_stamp() const { + return time_stamp_; + } + void set_time_stamp(const std::size_t& ts) { + time_stamp_ = ts; + } + ///@} const Set_of_indices& incident_patches_ids_set() const { @@ -74,6 +90,8 @@ { private: bool feature_edge; + std::size_t time_stamp_; + public: Mesh_polyhedron_halfedge() @@ -87,20 +105,47 @@ feature_edge = b; this->opposite()->feature_edge = b; } + + /// For the determinism of Compact_container iterators + ///@{ + typedef Tag_true Has_timestamp; + + std::size_t time_stamp() const { + return time_stamp_; + } + void set_time_stamp(const std::size_t& ts) { + time_stamp_ = ts; + } + ///@} }; +template +inline std::pair +patch_id_default_value(std::pair) +{ + return std::pair(1, 0); +} + +template +inline Integral patch_id_default_value(Integral) +{ + return Integral(1); +} + template class Mesh_polyhedron_face : public CGAL::HalfedgeDS_face_base { private: Patch_id_ patch_id_; + std::size_t time_stamp_; + public: typedef Patch_id_ Patch_id; Mesh_polyhedron_face() - : patch_id_(1) {} + : patch_id_(patch_id_default_value(Patch_id())) {} const Patch_id& patch_id() const { return patch_id_; @@ -109,8 +154,22 @@ void set_patch_id(const Patch_id& i) { patch_id_ = i; } + + /// For the determinism of Compact_container iterators + ///@{ + typedef Tag_true Has_timestamp; + + std::size_t time_stamp() const { + return time_stamp_; + } + void set_time_stamp(const std::size_t& ts) { + time_stamp_ = ts; + } + ///@} }; + + template class Mesh_polyhedron_items : public CGAL::Polyhedron_items_3 { public: @@ -153,7 +212,6 @@ typedef type Type; }; - } // end namespace CGAL #endif // CGAL_MESH_POLYHEDRON_3_H diff -Nru cgal-4.4/include/CGAL/mesh_segmentation.h cgal-4.5/include/CGAL/mesh_segmentation.h --- cgal-4.4/include/CGAL/mesh_segmentation.h 2014-02-08 20:00:27.000000000 +0000 +++ cgal-4.5/include/CGAL/mesh_segmentation.h 2014-08-29 13:58:17.000000000 +0000 @@ -29,9 +29,14 @@ /// @cond SKIP_IN_MANUAL template ::type +#endif + , class GeomTraits + #ifndef CGAL_CFG_NO_CPP0X_DEFAULT_TEMPLATE_ARGUMENTS_FOR_FUNCTION_TEMPLATES + = typename Kernel_traits::value_type>::Kernel #endif > std::pair @@ -40,10 +45,12 @@ double cone_angle = 2.0 / 3.0 * CGAL_PI, std::size_t number_of_rays = 25, bool postprocess = true, + PointPropertyMap ppmap = PointPropertyMap(), GeomTraits traits = GeomTraits()) { - internal::Surface_mesh_segmentation - algorithm(polyhedron, traits); + typedef PointPropertyMap VPMap; + internal::Surface_mesh_segmentation + algorithm(polyhedron, traits, ppmap); return algorithm.calculate_sdf_values(cone_angle, number_of_rays, sdf_values_map, postprocess); } @@ -59,9 +66,10 @@ * * @pre @a polyhedron.is_pure_triangle() * - * @tparam Polyhedron a %CGAL polyhedron - * @tparam SDFPropertyMap a `ReadWritePropertyMap` with `Polyhedron::Facet_const_handle` as key and `double` as value type - * @tparam GeomTraits a model of SegmentationGeomTraits + * @tparam Polyhedron a model of `FaceListGraph` + * @tparam SDFPropertyMap a `ReadWritePropertyMap` with `boost::graph_traits::%face_descriptor` as key and `double` as value type + * @tparam GeomTraits a model of `SegmentationGeomTraits` + * @tparam PointPropertyMap a `ReadablePropertyMap` with `boost::graph_traits::%vertex_descriptor` as key and `GeomTraits::Point_3` as value type. * * @param polyhedron surface mesh on which SDF values are computed * @param[out] sdf_values_map the SDF value of each facet @@ -69,12 +77,17 @@ * @param number_of_rays number of rays picked in the cone of each facet. In our experiments, we observe that increasing the number of rays beyond the default has little effect on the quality of the segmentation result * @param postprocess if `true`, `CGAL::sdf_values_postprocessing` is called on raw SDF value computed. * @param traits traits class + * @param ppmap point property map. An overload is provided with `get(boost::vertex_point,polyhedron)` as default. * * @return minimum and maximum raw SDF values if @a postprocess is `true`, otherwise minimum and maximum SDF values (before linear normalization) */ -template ::type +#endif +, class GeomTraits #ifndef CGAL_CFG_NO_CPP0X_DEFAULT_TEMPLATE_ARGUMENTS_FOR_FUNCTION_TEMPLATES -= typename Polyhedron::Traits += typename Kernel_traits::value_type>::Kernel #endif > std::pair @@ -83,10 +96,11 @@ double cone_angle = 2.0 / 3.0 * CGAL_PI, std::size_t number_of_rays = 25, bool postprocess = true, + PointPropertyMap ppmap = PointPropertyMap(), GeomTraits traits = GeomTraits()) { - return sdf_values - (polyhedron, sdf_values_map, cone_angle, number_of_rays, postprocess, traits); + return sdf_values + (polyhedron, sdf_values_map, cone_angle, number_of_rays, postprocess, ppmap, traits); } @@ -106,8 +120,8 @@ * @pre @a polyhedron.is_pure_triangle() * @pre Raw values should be greater or equal to 0. -1 indicates when no value could be computed * - * @tparam Polyhedron a %CGAL polyhedron - * @tparam SDFPropertyMap a `ReadWritePropertyMap` with `Polyhedron::Facet_const_handle` as key and `double` as value type + * @tparam Polyhedron a model of `FaceListGraph` + * @tparam SDFPropertyMap a `ReadWritePropertyMap` with `boost::graph_traits::%face_descriptor` as key and `double` as value type * * @param polyhedron surface mesh on which SDF values are computed * @param[in, out] sdf_values_map the SDF value of each facet @@ -144,10 +158,11 @@ * @pre @a polyhedron.is_pure_triangle() * @pre @a number_of_clusters > 0 * - * @tparam Polyhedron a %CGAL polyhedron - * @tparam SDFPropertyMap a `ReadablePropertyMap` with `Polyhedron::Facet_const_handle` as key and `double` as value type - * @tparam SegmentPropertyMap a `ReadWritePropertyMap` with `Polyhedron::Facet_const_handle` as key and `std::size_t` as value type - * @tparam GeomTraits a model of SegmentationGeomTraits + * @tparam Polyhedron a model of `FaceListGraph` + * @tparam SDFPropertyMap a `ReadablePropertyMap` with `boost::graph_traits::%face_descriptor` as key and `double` as value type + * @tparam SegmentPropertyMap a `ReadWritePropertyMap` with `boost::graph_traits::%face_descriptor` as key and `std::size_t` as value type + * @tparam GeomTraits a model of `SegmentationGeomTraits` + * @tparam PointPropertyMap a `ReadablePropertyMap` with `boost::graph_traits::%vertex_descriptor` as key and `GeomTraits::Point_3` as value type. * * @param polyhedron surface mesh corresponding to the SDF values * @param sdf_values_map the SDF value of each facet between [0-1] @@ -156,13 +171,18 @@ * @param smoothing_lambda factor which indicates the importance of the surface features for the energy minimization. It is recommended to choose a value in the interval [0,1]. See the section \ref Surface_mesh_segmentationGraphCut for more details. * @param output_cluster_ids if `false` fill `segment_ids` with segment-ids, and with cluster-ids otherwise (see \cgalFigureRef{Cluster_vs_segment}) * @param traits traits class + * @param ppmap point property map. An overload is provided with `get(boost::vertex_point,polyhedron)` as default. * * @return number of segments if `output_cluster_ids` is set to `false` and `number_of_clusters` otherwise */ template ::type +#endif + , class GeomTraits #ifndef CGAL_CFG_NO_CPP0X_DEFAULT_TEMPLATE_ARGUMENTS_FOR_FUNCTION_TEMPLATES - = typename Polyhedron::Traits + = typename Kernel_traits::value_type>::Kernel #endif > std::size_t @@ -172,21 +192,26 @@ std::size_t number_of_clusters = 5, double smoothing_lambda = 0.26, bool output_cluster_ids = false, - GeomTraits traits = GeomTraits()) + PointPropertyMap ppmap=PointPropertyMap(), + GeomTraits traits=GeomTraits()) { - internal::Surface_mesh_segmentation algorithm( - polyhedron, traits); + typedef typename boost::property_map::type VPMap; + internal::Surface_mesh_segmentation algorithm(polyhedron, traits, ppmap); return algorithm.partition(number_of_clusters, smoothing_lambda, sdf_values_map, segment_ids, !output_cluster_ids); } ///\cond SKIP_IN_MANUAL template < bool Fast_sdf_calculation_mode, class Polyhedron, - class SegmentPropertyMap, class GeomTraits + class SegmentPropertyMap, class PointPropertyMap #ifndef CGAL_CFG_NO_CPP0X_DEFAULT_TEMPLATE_ARGUMENTS_FOR_FUNCTION_TEMPLATES - = typename Polyhedron::Traits + = typename boost::property_map::type #endif - > + , class GeomTraits +#ifndef CGAL_CFG_NO_CPP0X_DEFAULT_TEMPLATE_ARGUMENTS_FOR_FUNCTION_TEMPLATES + = typename Kernel_traits::value_type>::Kernel +#endif + > std::size_t segmentation_via_sdf_values(const Polyhedron& polyhedron, SegmentPropertyMap segment_ids, @@ -195,19 +220,21 @@ std::size_t number_of_clusters = 5, double smoothing_lambda = 0.26, bool output_cluster_ids = false, - GeomTraits traits = GeomTraits()) + PointPropertyMap ppmap=PointPropertyMap(), + GeomTraits traits=GeomTraits() ) { - typedef std::map< typename Polyhedron::Facet_const_handle, double> + typedef typename boost::graph_traits::face_descriptor face_descriptor; + typedef std::map Facet_double_map; Facet_double_map internal_sdf_map; boost::associative_property_map sdf_property_map( internal_sdf_map); - sdf_values, GeomTraits> - (polyhedron, sdf_property_map, cone_angle, number_of_rays, true, traits); - return segmentation_from_sdf_values, SegmentPropertyMap, GeomTraits> + sdf_values, PointPropertyMap, GeomTraits> + (polyhedron, sdf_property_map, cone_angle, number_of_rays, true, ppmap, traits); + return segmentation_from_sdf_values, SegmentPropertyMap, PointPropertyMap, GeomTraits> (polyhedron, sdf_property_map, segment_ids, number_of_clusters, - smoothing_lambda, output_cluster_ids, traits); + smoothing_lambda, output_cluster_ids, ppmap, traits); } /// \endcond @@ -228,9 +255,10 @@ * @pre @a polyhedron.is_pure_triangle() * @pre @a number_of_clusters > 0 * - * @tparam Polyhedron a %CGAL polyhedron - * @tparam SegmentPropertyMap a `ReadWritePropertyMap` with `Polyhedron::Facet_const_handle` as key and `std::size_t` as value type - * @tparam GeomTraits a model of SegmentationGeomTraits + * @tparam Polyhedron a model of `FaceListGraph` + * @tparam SegmentPropertyMap a `ReadWritePropertyMap` with `boost::graph_traits::%face_descriptor` as key and `std::size_t` as value type + * @tparam GeomTraits a model of `SegmentationGeomTraits` + * @tparam PointPropertyMap a `ReadablePropertyMap` with `boost::graph_traits::%vertex_descriptor` as key and `GeomTraits::Point_3` as value type. * * @param polyhedron surface mesh on which SDF values are computed * @param[out] segment_ids the segment or cluster id of each facet @@ -240,12 +268,17 @@ * @param smoothing_lambda factor which indicates the importance of the surface features for the energy minimization. It is recommended to choose a value in the interval [0,1]. See the section \ref Surface_mesh_segmentationGraphCut for more details. * @param output_cluster_ids if `false` fill `segment_ids` with segment-ids, and with cluster-ids otherwise (see \cgalFigureRef{Cluster_vs_segment}) * @param traits traits class + * @param ppmap point property map. An overload is provided with `get(boost::vertex_point,polyhedron)` as default. * * @return number of segments if `output_cluster_ids` is set to `false` and `number_of_clusters` otherwise */ -template < class Polyhedron, class SegmentPropertyMap, class GeomTraits +template < class Polyhedron, class SegmentPropertyMap, class PointPropertyMap +#ifndef CGAL_CFG_NO_CPP0X_DEFAULT_TEMPLATE_ARGUMENTS_FOR_FUNCTION_TEMPLATES + = typename boost::property_map::type +#endif +, class GeomTraits #ifndef CGAL_CFG_NO_CPP0X_DEFAULT_TEMPLATE_ARGUMENTS_FOR_FUNCTION_TEMPLATES -= typename Polyhedron::Traits += typename Kernel_traits::value_type>::Kernel #endif > std::size_t @@ -256,42 +289,86 @@ std::size_t number_of_clusters = 5, double smoothing_lambda = 0.26, bool output_cluster_ids = false, - GeomTraits traits = GeomTraits()) + PointPropertyMap ppmap=PointPropertyMap(), + GeomTraits traits=GeomTraits()) { - return segmentation_via_sdf_values + return segmentation_via_sdf_values (polyhedron, segment_ids, cone_angle, number_of_rays, number_of_clusters, - smoothing_lambda, output_cluster_ids, traits); + smoothing_lambda, output_cluster_ids, ppmap, traits); } +#ifdef CGAL_CFG_NO_CPP0X_DEFAULT_TEMPLATE_ARGUMENTS_FOR_FUNCTION_TEMPLATES +// we need these overloads for the default of the point property map -#ifdef CGAL_CFG_NO_CPP0X_DEFAULT_TEMPLATE_ARGUMENTS_FOR_FUNCTION_TEMPLATES -template +/// sdf_values /// +template < bool Fast_sdf_calculation_mode, class Polyhedron, class SDFPropertyMap, class PointPropertyMap> std::pair -sdf_values(const Polyhedron& polyhedron, - SDFPropertyMap sdf_values_map, - double cone_angle = 2.0 / 3.0 * CGAL_PI, - std::size_t number_of_rays = 25, - bool postprocess = true, - typename Polyhedron::Traits traits = typename Polyhedron::Traits()) +sdf_values( const Polyhedron& polyhedron, + SDFPropertyMap sdf_values_map, + double cone_angle = 2.0 / 3.0 * CGAL_PI, + std::size_t number_of_rays = 25, + bool postprocess = true, + PointPropertyMap ppmap = PointPropertyMap()) { - return sdf_values - (polyhedron, sdf_values_map, cone_angle, number_of_rays, postprocess, traits); + typedef typename boost::property_traits::value_type Point_3; + typedef typename Kernel_traits::Kernel GeomTraits; + GeomTraits traits; + return sdf_values + (polyhedron, sdf_values_map, cone_angle, number_of_rays, postprocess, ppmap, traits); } -template < class Polyhedron, class SDFPropertyMap> +template < bool Fast_sdf_calculation_mode, class Polyhedron, class SDFPropertyMap> +std::pair +sdf_values( const Polyhedron& polyhedron, + SDFPropertyMap sdf_values_map, + double cone_angle = 2.0 / 3.0 * CGAL_PI, + std::size_t number_of_rays = 25, + bool postprocess = true) +{ + typedef typename boost::property_map::type PointPropertyMap; + PointPropertyMap ppmap = get(boost::vertex_point, const_cast(polyhedron)); + typedef typename boost::property_traits::value_type Point_3; + typedef typename Kernel_traits::Kernel GeomTraits; + GeomTraits traits; + return sdf_values + (polyhedron, sdf_values_map, cone_angle, number_of_rays, postprocess, ppmap, traits); +} + +template < class Polyhedron, class SDFPropertyMap, class PointPropertyMap> std::pair sdf_values( const Polyhedron& polyhedron, SDFPropertyMap sdf_values_map, double cone_angle = 2.0 / 3.0 * CGAL_PI, std::size_t number_of_rays = 25, bool postprocess = true, - typename Polyhedron::Traits traits = typename Polyhedron::Traits()) + PointPropertyMap ppmap = PointPropertyMap()) { - return sdf_values - (polyhedron, sdf_values_map, cone_angle, number_of_rays, postprocess, traits); + typedef typename boost::property_traits::value_type Point_3; + typedef typename Kernel_traits::Kernel GeomTraits; + GeomTraits traits; + return sdf_values + (polyhedron, sdf_values_map, cone_angle, number_of_rays, postprocess, ppmap, traits); } -template +template < class Polyhedron, class SDFPropertyMap> +std::pair +sdf_values( const Polyhedron& polyhedron, + SDFPropertyMap sdf_values_map, + double cone_angle = 2.0 / 3.0 * CGAL_PI, + std::size_t number_of_rays = 25, + bool postprocess = true) +{ + typedef typename boost::property_map::type PointPropertyMap; + PointPropertyMap ppmap = get(boost::vertex_point, const_cast(polyhedron)); + typedef typename boost::property_traits::value_type Point_3; + typedef typename Kernel_traits::Kernel GeomTraits; + GeomTraits traits; + return sdf_values + (polyhedron, sdf_values_map, cone_angle, number_of_rays, postprocess, ppmap, traits); +} + +/// segmentation_from_sdf_values /// +template std::size_t segmentation_from_sdf_values(const Polyhedron& polyhedron, SDFPropertyMap sdf_values_map, @@ -299,14 +376,37 @@ std::size_t number_of_clusters = 5, double smoothing_lambda = 0.26, bool output_cluster_ids = false, - typename Polyhedron::Traits traits = typename Polyhedron::Traits()) + PointPropertyMap ppmap = PointPropertyMap() ) { - return segmentation_from_sdf_values + typedef typename boost::property_traits::value_type Point_3; + typedef typename Kernel_traits::Kernel GeomTraits; + GeomTraits traits; + return segmentation_from_sdf_values (polyhedron, sdf_values_map, segment_ids, number_of_clusters, smoothing_lambda, - output_cluster_ids, traits); + output_cluster_ids, ppmap, traits); } -template +template +std::size_t +segmentation_from_sdf_values(const Polyhedron& polyhedron, + SDFPropertyMap sdf_values_map, + SegmentPropertyMap segment_ids, + std::size_t number_of_clusters = 5, + double smoothing_lambda = 0.26, + bool output_cluster_ids = false) +{ + typedef typename boost::property_map::type PointPropertyMap; + PointPropertyMap ppmap = get(boost::vertex_point, const_cast(polyhedron)); + typedef typename boost::property_traits::value_type Point_3; + typedef typename Kernel_traits::Kernel GeomTraits; + GeomTraits traits; + return segmentation_from_sdf_values + (polyhedron, sdf_values_map, segment_ids, number_of_clusters, smoothing_lambda, + output_cluster_ids, ppmap, traits); +} + +/// segmentation_via_sdf_values /// +template std::size_t segmentation_via_sdf_values(const Polyhedron& polyhedron, SegmentPropertyMap segment_ids, @@ -315,14 +415,17 @@ std::size_t number_of_clusters = 5, double smoothing_lambda = 0.26, bool output_cluster_ids = false, - typename Polyhedron::Traits traits = typename Polyhedron::Traits()) + PointPropertyMap ppmap = PointPropertyMap() ) { - return segmentation_via_sdf_values< Fast_sdf_calculation_mode, Polyhedron, SegmentPropertyMap, typename Polyhedron::Traits> + typedef typename boost::property_traits::value_type Point_3; + typedef typename Kernel_traits::Kernel GeomTraits; + GeomTraits traits; + return segmentation_via_sdf_values (polyhedron, segment_ids, cone_angle, number_of_rays, number_of_clusters, - smoothing_lambda, output_cluster_ids, traits); + smoothing_lambda, output_cluster_ids, ppmap, traits); } -template +template std::size_t segmentation_via_sdf_values(const Polyhedron& polyhedron, SegmentPropertyMap segment_ids, @@ -330,17 +433,59 @@ std::size_t number_of_rays = 25, std::size_t number_of_clusters = 5, double smoothing_lambda = 0.26, - bool output_cluster_ids = false, - typename Polyhedron::Traits traits = typename Polyhedron::Traits()) + bool output_cluster_ids = false) { - return segmentation_via_sdf_values + typedef typename boost::property_map::type PointPropertyMap; + PointPropertyMap ppmap = get(boost::vertex_point, const_cast(polyhedron)); + typedef typename boost::property_traits::value_type Point_3; + typedef typename Kernel_traits::Kernel GeomTraits; + GeomTraits traits; + return segmentation_via_sdf_values (polyhedron, segment_ids, cone_angle, number_of_rays, number_of_clusters, - smoothing_lambda, output_cluster_ids, traits); + smoothing_lambda, output_cluster_ids, ppmap, traits); } +template +std::size_t +segmentation_via_sdf_values(const Polyhedron& polyhedron, + SegmentPropertyMap segment_ids, + double cone_angle = 2.0 / 3.0 * CGAL_PI, + std::size_t number_of_rays = 25, + std::size_t number_of_clusters = 5, + double smoothing_lambda = 0.26, + bool output_cluster_ids = false, + PointPropertyMap ppmap = PointPropertyMap() ) +{ + typedef typename boost::property_traits::value_type Point_3; + typedef typename Kernel_traits::Kernel GeomTraits; + GeomTraits traits; + return segmentation_via_sdf_values + (polyhedron, segment_ids, cone_angle, number_of_rays, number_of_clusters, + smoothing_lambda, output_cluster_ids, ppmap, traits); +} +template +std::size_t +segmentation_via_sdf_values(const Polyhedron& polyhedron, + SegmentPropertyMap segment_ids, + double cone_angle = 2.0 / 3.0 * CGAL_PI, + std::size_t number_of_rays = 25, + std::size_t number_of_clusters = 5, + double smoothing_lambda = 0.26, + bool output_cluster_ids = false) +{ + typedef typename boost::property_map::type PointPropertyMap; + PointPropertyMap ppmap = get(boost::vertex_point, const_cast(polyhedron)); + typedef typename boost::property_traits::value_type Point_3; + typedef typename Kernel_traits::Kernel GeomTraits; + GeomTraits traits; + return segmentation_via_sdf_values + (polyhedron, segment_ids, cone_angle, number_of_rays, number_of_clusters, + smoothing_lambda, output_cluster_ids, ppmap, traits); +} #endif + }//namespace CGAL #endif // CGAL_SURFACE_MESH_SEGMENTATION_MESH_SEGMENTATION_H // diff -Nru cgal-4.4/include/CGAL/Mesh_triangulation_3.h cgal-4.5/include/CGAL/Mesh_triangulation_3.h --- cgal-4.4/include/CGAL/Mesh_triangulation_3.h 2013-07-13 19:00:30.000000000 +0000 +++ cgal-4.5/include/CGAL/Mesh_triangulation_3.h 2014-08-29 13:58:16.000000000 +0000 @@ -35,41 +35,46 @@ #include namespace CGAL { - + namespace details { - + template struct Mesh_geom_traits_generator { private: typedef Robust_weighted_circumcenter_filtered_traits_3 Geom_traits; - + public: typedef Geom_traits type; typedef type Type; }; // end struct Mesh_geom_traits_generator - + } // end namespace details - - + + // Struct Mesh_triangulation_3 // template::Kernel, - class Concurrency_tag = Default, + class Concurrency_tag = Sequential_tag, class Vertex_base_ = Default, class Cell_base_ = Default> +struct Mesh_triangulation_3; + +// Sequential version (default) +template struct Mesh_triangulation_3 - { +{ private: typedef typename details::Mesh_geom_traits_generator::type Geom_traits; typedef typename Default::Get< - Vertex_base_, + Vertex_base_, Mesh_vertex_base_3 >::type Vertex_base; typedef typename Default::Get< - Cell_base_, + Cell_base_, Compact_mesh_cell_base_3 >::type Cell_base; typedef Triangulation_data_structure_3 Tds; @@ -80,6 +85,33 @@ typedef type Type; }; // end struct Mesh_triangulation_3 +#ifdef CGAL_LINKED_WITH_TBB +// Parallel version (specialization) +// +template +struct Mesh_triangulation_3 +{ +private: + typedef typename details::Mesh_geom_traits_generator::type Geom_traits; + + typedef typename Default::Get< + Vertex_base_, + Mesh_vertex_base_3 >::type Vertex_base; + typedef typename Default::Get< + Cell_base_, + Compact_mesh_cell_base_3 >::type Cell_base; + + typedef Triangulation_data_structure_3< + Vertex_base, Cell_base, Parallel_tag> Tds; + typedef Regular_triangulation_3 Triangulation; + +public: + typedef Triangulation type; + typedef type Type; +}; // end struct Mesh_triangulation_3 +#endif // CGAL_LINKED_WITH_TBB + } // end namespace CGAL #endif // CGAL_MESH_TRIANGULATION_3_H diff -Nru cgal-4.4/include/CGAL/Mesh_vertex_base_3.h cgal-4.5/include/CGAL/Mesh_vertex_base_3.h --- cgal-4.4/include/CGAL/Mesh_vertex_base_3.h 2013-07-06 19:00:27.000000000 +0000 +++ cgal-4.5/include/CGAL/Mesh_vertex_base_3.h 2014-08-29 13:58:16.000000000 +0000 @@ -30,11 +30,68 @@ #define CGAL_COMPACT_MESH_VERTEX_BASE_3_H #include -#include #include #include +#include +#include namespace CGAL { + +// Without erase counter +template +class Mesh_vertex_base_3_base +{ +#if defined(CGAL_MESH_3_USE_LAZY_SORTED_REFINEMENT_QUEUE) \ + || defined(CGAL_MESH_3_USE_LAZY_UNSORTED_REFINEMENT_QUEUE) + +public: + // Erase counter (cf. Compact_container) + unsigned int erase_counter() const + { + return this->m_erase_counter; + } + void set_erase_counter(unsigned int c) + { + this->m_erase_counter = c; + } + void increment_erase_counter() + { + ++this->m_erase_counter; + } + +protected: + typedef unsigned int Erase_counter_type; + Erase_counter_type m_erase_counter; +#endif +}; + +#ifdef CGAL_LINKED_WITH_TBB +// Specialized version (parallel) +template <> +class Mesh_vertex_base_3_base +{ +public: + + // Erase counter (cf. Compact_container) + unsigned int erase_counter() const + { + return this->m_erase_counter; + } + void set_erase_counter(unsigned int c) + { + this->m_erase_counter = c; + } + void increment_erase_counter() + { + ++this->m_erase_counter; + } + +protected: + typedef tbb::atomic Erase_counter_type; + Erase_counter_type m_erase_counter; + +}; +#endif // CGAL_LINKED_WITH_TBB // Class Mesh_vertex_base_3 // Vertex base class used in 3D meshing process. @@ -44,7 +101,9 @@ class MD, class Vb = Triangulation_vertex_base_3 > class Mesh_vertex_base_3 -: public Vb +: public Vb, + public Mesh_vertex_base_3_base< + typename Vb::Triangulation_data_structure::Concurrency_tag> { public: typedef Vb Cmvb3_base; @@ -74,6 +133,7 @@ , next_intrusive_() , previous_intrusive_() #endif //CGAL_INTRUSIVE_LIST + , time_stamp_(-1) {} // Default copy constructor and assignment operator are ok @@ -124,6 +184,18 @@ } #endif + /// For the determinism of Compact_container iterators + ///@{ + typedef Tag_true Has_timestamp; + + std::size_t time_stamp() const { + return time_stamp_; + } + void set_time_stamp(const std::size_t& ts) { + time_stamp_ = ts; + } + ///@} + bool is_c2t3_cache_valid() const { return cache_validity; } @@ -179,12 +251,9 @@ Vertex_handle next_intrusive_; Vertex_handle previous_intrusive_; #endif -}; // end class Mesh_vertex_base_3 + std::size_t time_stamp_; -namespace internal { -namespace Mesh_3 { -} // end namespace internal::Mesh_3 -} // end namespace internal +}; // end class Mesh_vertex_base_3 template0; --i) { gamma[i] = beta[i]; + // the next for won't do anything fori=m-1 + // which triggers a warning with g++-4.8 + // but it makes no sense to add an if(i!=m-1) for (int j=i+1; j +// Author: Luis Peñaranda diff -Nru cgal-4.4/include/CGAL/MP_Float.h cgal-4.5/include/CGAL/MP_Float.h --- cgal-4.4/include/CGAL/MP_Float.h 2012-11-13 13:13:59.000000000 +0000 +++ cgal-4.5/include/CGAL/MP_Float.h 2014-08-29 13:58:16.000000000 +0000 @@ -887,6 +887,7 @@ typedef CGAL::MP_Float Nested; static inline Real epsilon() { return 0; } + static inline Real dummy_precision() { return 0; } enum { IsInteger = 1, // Is this lie right? diff -Nru cgal-4.4/include/CGAL/mpfr_coercion_traits.h cgal-4.5/include/CGAL/mpfr_coercion_traits.h --- cgal-4.4/include/CGAL/mpfr_coercion_traits.h 2012-11-13 13:13:59.000000000 +0000 +++ cgal-4.5/include/CGAL/mpfr_coercion_traits.h 2014-08-29 13:58:16.000000000 +0000 @@ -14,7 +14,7 @@ // $URL$ // $Id$ // -// Author: Luis Peñaranda +// Author: Luis Peñaranda #ifndef CGAL_MPFR_COERCION_TRAITS_H #define CGAL_MPFR_COERCION_TRAITS_H diff -Nru cgal-4.4/include/CGAL/Mpzf.h cgal-4.5/include/CGAL/Mpzf.h --- cgal-4.4/include/CGAL/Mpzf.h 2014-02-15 20:00:24.000000000 +0000 +++ cgal-4.5/include/CGAL/Mpzf.h 2014-08-29 13:58:16.000000000 +0000 @@ -67,6 +67,10 @@ #pragma intrinsic(_BitScanReverse64) #endif +#ifdef __xlC__ +#include +#endif + #if defined(BOOST_MSVC) # pragma warning(push) # pragma warning(disable:4146 4244 4267 4800) @@ -189,20 +193,25 @@ // Only used with an argument known not to be 0. inline int ctz (boost::uint64_t x) { -#ifdef _MSC_VER +#if defined(_MSC_VER) unsigned long ret; _BitScanForward64(&ret, x); return (int)ret; +#elif defined(__xlC__) + return __cnttz8 (x); #else // Assume long long is 64 bits return __builtin_ctzll (x); #endif } inline int clz (boost::uint64_t x) { -#ifdef _MSC_VER +#if defined(_MSC_VER) unsigned long ret; _BitScanReverse64(&ret, x); return 63 - (int)ret; +#elif defined(__xlC__) + // Macro supposedly not defined on z/OS. + return __cntlz8 (x); #else return __builtin_clzll (x); #endif diff -Nru cgal-4.4/include/CGAL/mst_orient_normals.h cgal-4.5/include/CGAL/mst_orient_normals.h --- cgal-4.4/include/CGAL/mst_orient_normals.h 2013-10-12 19:00:22.000000000 +0000 +++ cgal-4.5/include/CGAL/mst_orient_normals.h 2014-08-29 13:58:16.000000000 +0000 @@ -35,13 +35,9 @@ #include #include -#include -#if BOOST_VERSION >= 104000 - #include -#else - #include -#endif +#include #include +#include // work around a bug in boost 1.54 #include namespace CGAL { diff -Nru cgal-4.4/include/CGAL/Nef_2/PM_overlayer.h cgal-4.5/include/CGAL/Nef_2/PM_overlayer.h --- cgal-4.4/include/CGAL/Nef_2/PM_overlayer.h 2013-03-07 20:00:26.000000000 +0000 +++ cgal-4.5/include/CGAL/Nef_2/PM_overlayer.h 2014-08-29 13:58:16.000000000 +0000 @@ -40,7 +40,9 @@ #include #ifndef CGAL_USE_LEDA -#define LEDA_MEMORY(t) +#define LEDA_MEMORY(t) +#else +#include #endif namespace CGAL { diff -Nru cgal-4.4/include/CGAL/Nef_2/PM_point_locator.h cgal-4.5/include/CGAL/Nef_2/PM_point_locator.h --- cgal-4.4/include/CGAL/Nef_2/PM_point_locator.h 2012-12-01 20:00:22.000000000 +0000 +++ cgal-4.5/include/CGAL/Nef_2/PM_point_locator.h 2014-08-29 13:58:16.000000000 +0000 @@ -35,7 +35,7 @@ #include #endif -#ifdef CGAL_USE_LEDA +#ifdef CGAL_USE_LEDA_LIBRARY #include # if __LEDA__ > 410 && __LEDA__ < 441 # define CGAL_USING_PPL diff -Nru cgal-4.4/include/CGAL/Nef_2/Segment_overlay_traits.h cgal-4.5/include/CGAL/Nef_2/Segment_overlay_traits.h --- cgal-4.4/include/CGAL/Nef_2/Segment_overlay_traits.h 2013-02-23 20:00:17.000000000 +0000 +++ cgal-4.5/include/CGAL/Nef_2/Segment_overlay_traits.h 2014-08-29 13:58:16.000000000 +0000 @@ -24,22 +24,9 @@ #define CGAL_NEF_DEBUG 23 #include -#if defined(CGAL_USE_LEDA) +#if defined(CGAL_USE_LEDA_LIBRARY) #include -#if CGAL_LEDA_VERSION < 500 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#else + #include #include #include @@ -52,7 +39,7 @@ #include #include #include -#endif + #include #include @@ -444,8 +431,8 @@ } // namespace CGAL -#endif // defined(CGAL_USE_LEDA) -#if !defined(CGAL_USE_LEDA) +#endif // defined(CGAL_USE_LEDA_LIBRARY) +#if !defined(CGAL_USE_LEDA_LIBRARY) #include #include #include @@ -1123,10 +1110,10 @@ } // namespace CGAL -#endif // !defined(CGAL_USE_LEDA) +#endif // !defined(CGAL_USE_LEDA_LIBRARY) namespace CGAL { -#if defined(CGAL_USE_LEDA) +#if defined(CGAL_USE_LEDA_LIBRARY) #define Segment_overlay_traits leda_seg_overlay_traits static const char* const sweepversion = "LEDA segment overlay sweep"; #else diff -Nru cgal-4.4/include/CGAL/Nef_S2/SM_overlayer.h cgal-4.5/include/CGAL/Nef_S2/SM_overlayer.h --- cgal-4.4/include/CGAL/Nef_S2/SM_overlayer.h 2012-12-01 20:00:22.000000000 +0000 +++ cgal-4.5/include/CGAL/Nef_S2/SM_overlayer.h 2014-08-29 13:58:16.000000000 +0000 @@ -41,7 +41,9 @@ #include #ifndef CGAL_USE_LEDA -#define LEDA_MEMORY(t) +#define LEDA_MEMORY(t) +#else +#include #endif namespace CGAL { diff -Nru cgal-4.4/include/CGAL/Nef_S2/Sphere_map.h cgal-4.5/include/CGAL/Nef_S2/Sphere_map.h --- cgal-4.4/include/CGAL/Nef_S2/Sphere_map.h 2012-11-13 13:13:58.000000000 +0000 +++ cgal-4.5/include/CGAL/Nef_S2/Sphere_map.h 2014-08-29 13:58:16.000000000 +0000 @@ -158,7 +158,7 @@ operator SHalfedge_handle() const { SHalfedge_handle e; CGAL::assign(e,Ibase::operator*()); return e; } operator SHalfloop_handle() const - { SHalfloop_handle l; CGAL::assign(l,Ibase::operator*()); return l; } + { SHalfloop_handle l=0; CGAL::assign(l,Ibase::operator*()); return l; } operator Object_handle() const { return Ibase::operator*(); } Object_handle& operator*() const { return Ibase::operator*(); } @@ -188,7 +188,7 @@ { SHalfedge_handle e; CGAL::assign(e,Ibase::operator*()); return SHalfedge_const_handle(e); } operator SHalfloop_const_handle() const - { SHalfloop_handle l; CGAL::assign(l,Ibase::operator*()); + { SHalfloop_handle l=0; CGAL::assign(l,Ibase::operator*()); return SHalfloop_const_handle(l); } operator Object_handle() const { return Ibase::operator*(); } diff -Nru cgal-4.4/include/CGAL/NewKernel_d/Cartesian_base.h cgal-4.5/include/CGAL/NewKernel_d/Cartesian_base.h --- cgal-4.4/include/CGAL/NewKernel_d/Cartesian_base.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/Cartesian_base.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,40 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_KERNEL_D_CARTESIAN_BASE_H +#define CGAL_KERNEL_D_CARTESIAN_BASE_H + +#include +#include +#include + +namespace CGAL { +#define CGAL_BASE \ + Cartesian_LA_base_d< FT_, Dim_ > +template < typename FT_, typename Dim_, typename Derived_=Default> +struct Cartesian_base_d : public CGAL_BASE +{ + CGAL_CONSTEXPR Cartesian_base_d(){} + CGAL_CONSTEXPR Cartesian_base_d(int d):CGAL_BASE(d){} +}; +#undef CGAL_BASE + +} //namespace CGAL + +#endif // CGAL_KERNEL_D_CARTESIAN_BASE_H diff -Nru cgal-4.4/include/CGAL/NewKernel_d/Cartesian_change_FT.h cgal-4.5/include/CGAL/NewKernel_d/Cartesian_change_FT.h --- cgal-4.4/include/CGAL/NewKernel_d/Cartesian_change_FT.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/Cartesian_change_FT.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,117 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_KERNEL_D_CARTESIAN_CHANGE_FT_H +#define CGAL_KERNEL_D_CARTESIAN_CHANGE_FT_H + +#include +#include +#include +#include + +namespace CGAL { + +template < typename Base_, typename FT_, typename LA_=CGAL::LA_eigen > +struct Cartesian_change_FT_base : public + Base_ +{ + CGAL_CONSTEXPR Cartesian_change_FT_base(){} + CGAL_CONSTEXPR Cartesian_change_FT_base(int d):Base_(d){} + + typedef Cartesian_change_FT_base Self; + typedef Base_ Kernel_base; + typedef LA_ LA; + + template struct Type : Inherit_type {}; + template struct Type { typedef FT_ type; }; + template struct Type { typedef FT_ type; }; + + typedef NT_converter::type,FT_> FT_converter; + typedef transforming_iterator Point_cartesian_const_iterator; + typedef transforming_iterator Vector_cartesian_const_iterator; + //FIXME: use Iterator_list! + /* + template::value_tag,FT_tag>::value> + struct Iterator : Get_type {}; + template struct Iterator { + typedef transforming_iterator::type> type; + }; + */ + + template + struct Construct_cartesian_const_iterator_ { + typedef typename Get_functor::type Functor_base; + Construct_cartesian_const_iterator_(){} + Construct_cartesian_const_iterator_(Self const&r):f(r){} + Functor_base f; + typedef Type_ result_type; + template + result_type operator()(T const& v, Begin_tag)const{ + return make_transforming_iterator(f(v,Begin_tag()),FT_converter()); + } + template + result_type operator()(T const& v, End_tag)const{ + return make_transforming_iterator(f(v,End_tag()),FT_converter()); + } + }; + typedef Construct_cartesian_const_iterator_,Point_cartesian_const_iterator> Construct_point_cartesian_const_iterator; + typedef Construct_cartesian_const_iterator_,Vector_cartesian_const_iterator> Construct_vector_cartesian_const_iterator; + + template + struct Compute_cartesian_coordinate { + typedef typename Get_functor::type Functor_base; + Compute_cartesian_coordinate(){} + Compute_cartesian_coordinate(Self const&r):f(r){} + Functor_base f; + typedef FT_ result_type; + template + result_type operator()(Obj_ const& v,int i)const{ + return FT_converter()(f(v,i)); + } + }; + + template::type> struct Functor : + Inherit_functor { }; + template struct Functor { }; + template struct Functor { }; + template struct Functor { + typedef Compute_cartesian_coordinate type; + }; + template struct Functor { + typedef Compute_cartesian_coordinate type; + }; + template struct Functor,D,Construct_iterator_tag> { + typedef Construct_point_cartesian_const_iterator type; + }; + template struct Functor,D,Construct_iterator_tag> { + typedef Construct_vector_cartesian_const_iterator type; + }; +}; + +template < typename Base_, typename FT_> +struct Cartesian_change_FT : public + Cartesian_change_FT_base +{ + CGAL_CONSTEXPR Cartesian_change_FT(){} + CGAL_CONSTEXPR Cartesian_change_FT(int d):Cartesian_change_FT_base(d){} +}; + +} //namespace CGAL + +#endif // CGAL_KERNEL_D_CARTESIAN_CHANGE_FT_H diff -Nru cgal-4.4/include/CGAL/NewKernel_d/Cartesian_complete.h cgal-4.5/include/CGAL/NewKernel_d/Cartesian_complete.h --- cgal-4.4/include/CGAL/NewKernel_d/Cartesian_complete.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/Cartesian_complete.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,33 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_KERNEL_D_CARTESIAN_COMPLETE_H +#define CGAL_KERNEL_D_CARTESIAN_COMPLETE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif // CGAL_KERNEL_D_CARTESIAN_COMPLETE_H diff -Nru cgal-4.4/include/CGAL/NewKernel_d/Cartesian_filter_K.h cgal-4.5/include/CGAL/NewKernel_d/Cartesian_filter_K.h --- cgal-4.4/include/CGAL/NewKernel_d/Cartesian_filter_K.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/Cartesian_filter_K.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,79 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_KERNEL_D_CARTESIAN_FILTER_K_H +#define CGAL_KERNEL_D_CARTESIAN_FILTER_K_H + +#include +#include +#include +#include +#include + +namespace CGAL { + +template < typename Base_, typename AK_, typename EK_ > +struct Cartesian_filter_K : public Base_, + private Store_kernel, private Store_kernel2 +{ + CGAL_CONSTEXPR Cartesian_filter_K(){} + CGAL_CONSTEXPR Cartesian_filter_K(int d):Base_(d){} + //FIXME: or do we want an instance of AK and EK belonging to this kernel, + //instead of a reference to external ones? + CGAL_CONSTEXPR Cartesian_filter_K(AK_ const&a,EK_ const&b):Base_(),Store_kernel(a),Store_kernel2(b){} + CGAL_CONSTEXPR Cartesian_filter_K(int d,AK_ const&a,EK_ const&b):Base_(d),Store_kernel(a),Store_kernel2(b){} + typedef Base_ Kernel_base; + typedef AK_ AK; + typedef EK_ EK; + typedef typename Store_kernel::reference_type AK_rt; + AK_rt approximate_kernel()const{return this->kernel();} + typedef typename Store_kernel2::reference2_type EK_rt; + EK_rt exact_kernel()const{return this->kernel2();} + + // MSVC is too dumb to perform the empty base optimization. + typedef boost::mpl::and_< + internal::Do_not_store_kernel, + internal::Do_not_store_kernel, + internal::Do_not_store_kernel > Do_not_store_kernel; + + //TODO: C2A/C2E could be able to convert *this into this->kernel() or this->kernel2(). + typedef KernelD_converter C2A; + typedef KernelD_converter C2E; + + // fix the types + // TODO: only fix some types, based on some criterion? + template struct Type : Get_type {}; + + template::type> struct Functor : + Inherit_functor {}; + template struct Functor { + typedef typename Get_functor::type AP; + typedef typename Get_functor::type EP; + typedef Filtered_predicate2 type; + }; +// TODO: +// template struct Functor : +// Kernel_base::template Functor {}; +// TODO: +// detect when Less_cartesian_coordinate doesn't need filtering +}; + +} //namespace CGAL + +#endif // CGAL_KERNEL_D_CARTESIAN_FILTER_K_H diff -Nru cgal-4.4/include/CGAL/NewKernel_d/Cartesian_filter_NT.h cgal-4.5/include/CGAL/NewKernel_d/Cartesian_filter_NT.h --- cgal-4.4/include/CGAL/NewKernel_d/Cartesian_filter_NT.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/Cartesian_filter_NT.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,93 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_KERNEL_D_CARTESIAN_FILTER_NT_H +#define CGAL_KERNEL_D_CARTESIAN_FILTER_NT_H + +#include +#include +#include + +namespace CGAL { + +template < typename Base_ > +struct Cartesian_filter_NT : public Base_ +{ + CGAL_CONSTEXPR Cartesian_filter_NT(){} + CGAL_CONSTEXPR Cartesian_filter_NT(int d):Base_(d){} + typedef Base_ Kernel_base; + typedef Cartesian_change_FT K1; + typedef typename internal::Exact_field_selector::type>::Type Exact_nt; + typedef Cartesian_change_FT K2; + + template::type> struct Functor : + Inherit_functor {}; + template struct Functor { + struct type { + //TODO: use compression (derive from a compressed_pair?) + typedef typename Get_functor::type P1; P1 p1; + typedef typename Get_functor::type P2; P2 p2; + typedef typename P2::result_type result_type; + type(){} + type(Cartesian_filter_NT const&k):p1(reinterpret_cast(k)),p2(reinterpret_cast(k)){} + //FIXME: if predicate's constructor takes a kernel as argument, how do we translate that? reinterpret_cast is really ugly and possibly unsafe. + +#ifdef CGAL_CXX11 + template result_type operator()(U&&...u)const{ + { + Protect_FPU_rounding p; + try { + typename P1::result_type res=p1(u...); // don't forward as u may be reused + if(is_certain(res)) return get_certain(res); + } catch (Uncertain_conversion_exception) {} + } + return p2(std::forward(u)...); + } +#else + result_type operator()()const{ // does it make sense to have 0 argument? + { + Protect_FPU_rounding p; + try { + typename P1::result_type res=p1(); + if(is_certain(res)) return get_certain(res); + } catch (Uncertain_conversion_exception) {} + } + return p2(); + } +#define CGAL_CODE(Z,N,_) template result_type operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t))const{ \ + { \ + Protect_FPU_rounding p; \ + try { \ + typename P1::result_type res=p1(BOOST_PP_ENUM_PARAMS(N,t)); \ + if(is_certain(res)) return get_certain(res); \ + } catch (Uncertain_conversion_exception) {} \ + } \ + return p2(BOOST_PP_ENUM_PARAMS(N,t)); \ + } + BOOST_PP_REPEAT_FROM_TO(1,11,CGAL_CODE,_) +#undef CGAL_CODE + +#endif + }; + }; +}; + +} //namespace CGAL + +#endif // CGAL_KERNEL_D_CARTESIAN_FILTER_NT_H diff -Nru cgal-4.4/include/CGAL/NewKernel_d/Cartesian_LA_base.h cgal-4.5/include/CGAL/NewKernel_d/Cartesian_LA_base.h --- cgal-4.4/include/CGAL/NewKernel_d/Cartesian_LA_base.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/Cartesian_LA_base.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,177 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_KERNEL_D_CARTESIAN_LA_BASE_H +#define CGAL_KERNEL_D_CARTESIAN_LA_BASE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CGAL_EIGEN3_ENABLED +#include +#else +#error Eigen3 is required +#include +#endif + +namespace CGAL { + +template < typename FT_, typename Dim_, +#if 1 + typename Vec_=Mix_vector, + Vector_vector, + FT_, Dim_>, +#elif 0 + typename Vec_=Array_vector, +#elif 0 + typename Vec_=Vector_vector, +#else + // Dangerous because of alignment. Ok on x86_64 without AVX. + typename Vec_=LA_eigen, +#endif + typename LA_=LA_eigen > + /* Default LA to Vec or to LA_eigen? */ +struct Cartesian_LA_base_d : public Dimension_base +{ + typedef Cartesian_LA_base_d Self; + typedef Cartesian_tag Rep_tag; + typedef Cartesian_tag Kernel_tag; + typedef Dim_ Default_ambient_dimension; + typedef Dim_ Max_ambient_dimension; + typedef Dim_ Dimension; + typedef LA_ LA; + template struct Ambient_dimension { typedef Dim_ type; }; + + typedef Vec_ LA_vector; + typedef typename LA_vector::Vector Point; + typedef typename LA_vector::Vector Vector; + typedef typename LA_vector::Vector Vector_; + typedef typename LA_vector::Construct_vector Constructor; + typedef typename LA_vector::Vector_const_iterator Point_cartesian_const_iterator; + typedef typename LA_vector::Vector_const_iterator Vector_cartesian_const_iterator; + + template struct Type {}; + template struct Type< Point_tag, D> { typedef Vector_ type; }; + template struct Type { typedef Vector_ type; }; + template struct Type< FT_tag, D> { typedef FT_ type; }; + template struct Type< RT_tag, D> { typedef FT_ type; }; + + typedef typeset + ::add::type + // FIXME: These have nothing to do here. + ::add::type + ::add::type + ::add::type + Object_list; + + typedef typeset< Point_cartesian_const_iterator_tag>::type + ::add::type + Iterator_list; + + template > struct Functor { + typedef Null_functor type; + }; + template struct Functor,D> { + typedef CartesianDVectorBase::Construct_LA_vector type; + }; + template struct Functor,D> { + typedef CartesianDVectorBase::Construct_LA_vector type; + }; + template struct Functor,D> { + typedef CartesianDVectorBase::Construct_cartesian_const_iterator type; + }; + template struct Functor,D> { + typedef CartesianDVectorBase::Construct_cartesian_const_iterator type; + }; + template struct Functor::value> > { + typedef CartesianDVectorBase::Sum_of_vectors type; + }; + template struct Functor::value> > { + typedef CartesianDVectorBase::Difference_of_vectors type; + }; + template struct Functor::value> > { + typedef CartesianDVectorBase::Opposite_vector type; + }; + template struct Functor::value + || !LA_vector::template Property::value> > { + typedef CartesianDVectorBase::Midpoint type; + }; + template struct Functor { + typedef CartesianDVectorBase::Compute_cartesian_coordinate type; + }; + template struct Functor { + typedef CartesianDVectorBase::Compute_cartesian_coordinate type; + }; + template struct Functor { + typedef CartesianDVectorBase::PV_dimension type; + }; + template struct Functor { + typedef CartesianDVectorBase::PV_dimension type; + }; + template struct Functor::value> > { + typedef CartesianDVectorBase::Orientation_of_vectors type; + }; + template struct Functor::value> > { + typedef CartesianDVectorBase::Orientation_of_points type; + }; + template struct Functor::value> > { + typedef CartesianDVectorBase::Scalar_product type; + }; + template struct Functor::value> > { + typedef CartesianDVectorBase::Squared_distance_to_origin_stored type; + }; + // Use integral_constant in case of failure, to distinguish from the previous one. + template struct Functor::value + || !LA_vector::template Property::value)*2> > { + typedef CartesianDVectorBase::Squared_distance_to_origin_via_dotprod type; + }; + template struct Functor { + typedef CartesianDVectorBase::Identity_functor type; + }; + template struct Functor { + typedef CartesianDVectorBase::Identity_functor type; + }; + + CGAL_CONSTEXPR Cartesian_LA_base_d(){} + CGAL_CONSTEXPR Cartesian_LA_base_d(int d):Dimension_base(d){} +}; + +} //namespace CGAL + +#endif // CGAL_KERNEL_D_CARTESIAN_LA_BASE_H diff -Nru cgal-4.4/include/CGAL/NewKernel_d/Cartesian_LA_functors.h cgal-4.5/include/CGAL/NewKernel_d/Cartesian_LA_functors.h --- cgal-4.4/include/CGAL/NewKernel_d/Cartesian_LA_functors.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/Cartesian_LA_functors.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,344 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_CARTESIAN_LA_FUNCTORS_H +#define CGAL_CARTESIAN_LA_FUNCTORS_H + +#include +#include +#include +#include +#include +#include +#include + +namespace CGAL { +namespace CartesianDVectorBase { +#ifndef CGAL_CXX11 +namespace internal { +template struct Construct_LA_vector_ { + struct Never_use {}; + void operator()(Never_use)const; +}; +#define CGAL_CODE(Z,N,_) template struct Construct_LA_vector_ > { \ + typedef typename R::Constructor Constructor; \ + typedef typename Get_type::type RT; \ + typedef typename R::Vector_ result_type; \ + result_type operator() \ + (BOOST_PP_ENUM_PARAMS(N,RT const& t)) const { \ + return typename Constructor::Values()(BOOST_PP_ENUM_PARAMS(N,t)); \ + } \ + result_type operator() \ + (BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(N),RT const& t)) const { \ + return typename Constructor::Values_divide()(t##N,BOOST_PP_ENUM_PARAMS(N,t)); \ + } \ + }; +BOOST_PP_REPEAT_FROM_TO(2, 11, CGAL_CODE, _ ) +#undef CGAL_CODE +} +#endif + +template struct Construct_LA_vector +: private Store_kernel +#ifndef CGAL_CXX11 +, public internal::Construct_LA_vector_ +#endif +{ + //CGAL_FUNCTOR_INIT_IGNORE(Construct_LA_vector) + CGAL_FUNCTOR_INIT_STORE(Construct_LA_vector) + typedef R_ R; + typedef typename R::Constructor Constructor; + typedef typename Get_type::type RT; + typedef typename Get_type::type FT; + typedef typename R::Vector_ result_type; + typedef typename R_::Default_ambient_dimension Dimension; + result_type operator()(int d)const{ + CGAL_assertion(check_dimension_eq(d,this->kernel().dimension())); + return typename Constructor::Dimension()(d); + } + result_type operator()()const{ + return typename Constructor::Dimension()((std::max)(0,this->kernel().dimension())); + } + result_type operator()(int d, Zero_ const&)const{ + CGAL_assertion(check_dimension_eq(d,this->kernel().dimension())); + return typename Constructor::Dimension()(d); + } + result_type operator()(Zero_ const&)const{ + // Makes no sense for an unknown dimension. + return typename Constructor::Dimension()(this->kernel().dimension()); + } + result_type operator()(result_type const& v)const{ + return v; + } +#ifdef CGAL_CXX11 + result_type operator()(result_type&& v)const{ + return std::move(v); + } +#endif +#ifdef CGAL_CXX11 + template + typename std::enable_if::value && + boost::is_same, Dimension>::value, + result_type>::type + operator()(U&&...u)const{ + return typename Constructor::Values()(std::forward(u)...); + } + //template::value>::type,class=typename std::enable_if<(sizeof...(U)==static_dim+1)>::type,class=void> + template + typename std::enable_if::value && + boost::is_same, Dimension>::value, + result_type>::type + operator()(U&&...u)const{ + return Apply_to_last_then_rest()(typename Constructor::Values_divide(),std::forward(u)...); + } +#else + using internal::Construct_LA_vector_::operator(); +#endif + template inline + typename boost::enable_if,result_type>::type operator() + (Iter f,Iter g,Cartesian_tag t)const + { + return this->operator()((int)std::distance(f,g),f,g,t); + } + template inline + typename boost::enable_if,result_type>::type operator() + (int d,Iter f,Iter g,Cartesian_tag)const + { + CGAL_assertion(d==std::distance(f,g)); + CGAL_assertion(check_dimension_eq(d,this->kernel().dimension())); + return typename Constructor::Iterator()(d,f,g); + } + template inline + typename boost::enable_if,result_type>::type operator() + (Iter f,Iter g,Homogeneous_tag)const + { + --g; + return this->operator()((int)std::distance(f,g),f,g,*g); + } + template inline + typename boost::enable_if,result_type>::type operator() + (int d,Iter f,Iter g,Homogeneous_tag)const + { + --g; + return this->operator()(d,f,g,*g); + } + template inline + typename boost::enable_if,result_type>::type operator() + (Iter f,Iter g)const + { + // Shouldn't it try comparing dist(f,g) to the dimension if it is known? + return this->operator()(f,g,typename R::Rep_tag()); + } + template inline + typename boost::enable_if,result_type>::type operator() + (int d,Iter f,Iter g)const + { + return this->operator()(d,f,g,typename R::Rep_tag()); + } + + // Last homogeneous coordinate given separately + template inline + typename boost::enable_if,result_type>::type operator() + (int d,Iter f,Iter g,NT const&l)const + { + CGAL_assertion(d==std::distance(f,g)); + CGAL_assertion(check_dimension_eq(d,this->kernel().dimension())); + // RT? better be safe for now + return typename Constructor::Iterator()(d,CGAL::make_transforming_iterator(f,Divide(l)),CGAL::make_transforming_iterator(g,Divide(l))); + } + template inline + typename boost::enable_if,result_type>::type operator() + (Iter f,Iter g,NT const&l)const + { + return this->operator()((int)std::distance(f,g),f,g,l); + } +}; + +template struct Compute_cartesian_coordinate { + CGAL_FUNCTOR_INIT_IGNORE(Compute_cartesian_coordinate) + typedef R_ R; + typedef typename Get_type::type RT; + typedef typename R::Vector_ first_argument_type; + typedef int second_argument_type; + typedef Tag_true Is_exact; +#ifdef CGAL_CXX11 + typedef decltype(std::declval()[0]) result_type; +#else + typedef RT const& result_type; + // RT const& doesn't work with some LA (Eigen2 for instance) so we + // should use plain RT or find a way to detect this. +#endif + + result_type operator()(first_argument_type const& v,int i)const{ + return v[i]; + } +}; + +template struct Construct_cartesian_const_iterator { + CGAL_FUNCTOR_INIT_IGNORE(Construct_cartesian_const_iterator) + typedef R_ R; + typedef typename R::Vector_ argument_type; + typedef typename R::LA_vector S_; + typedef typename R::Point_cartesian_const_iterator result_type; + // same as Vector + typedef Tag_true Is_exact; + + result_type operator()(argument_type const& v,Begin_tag)const{ + return S_::vector_begin(v); + } + result_type operator()(argument_type const& v,End_tag)const{ + return S_::vector_end(v); + } +}; + +template struct Midpoint { + CGAL_FUNCTOR_INIT_IGNORE(Midpoint) + typedef R_ R; + typedef typename Get_type::type first_argument_type; + typedef typename Get_type::type second_argument_type; + typedef typename Get_type::type result_type; + + result_type operator()(result_type const& a, result_type const& b)const{ + return (a+b)/2; + } +}; + +template struct Sum_of_vectors { + CGAL_FUNCTOR_INIT_IGNORE(Sum_of_vectors) + typedef R_ R; + typedef typename Get_type::type first_argument_type; + typedef typename Get_type::type second_argument_type; + typedef typename Get_type::type result_type; + + result_type operator()(result_type const& a, result_type const& b)const{ + return a+b; + } +}; + +template struct Difference_of_vectors { + CGAL_FUNCTOR_INIT_IGNORE(Difference_of_vectors) + typedef R_ R; + typedef typename Get_type::type first_argument_type; + typedef typename Get_type::type second_argument_type; + typedef typename Get_type::type result_type; + + result_type operator()(result_type const& a, result_type const& b)const{ + return a-b; + } +}; + +template struct Opposite_vector { + CGAL_FUNCTOR_INIT_IGNORE(Opposite_vector) + typedef R_ R; + typedef typename Get_type::type result_type; + typedef typename Get_type::type argument_type; + + result_type operator()(result_type const& v)const{ + return -v; + } +}; + +template struct Scalar_product { + CGAL_FUNCTOR_INIT_IGNORE(Scalar_product) + typedef R_ R; + typedef typename R::LA_vector LA; + typedef typename Get_type::type result_type; + typedef typename Get_type::type first_argument_type; + typedef typename Get_type::type second_argument_type; + + result_type operator()(first_argument_type const& a, second_argument_type const& b)const{ + return LA::dot_product(a,b); + } +}; + +template struct Squared_distance_to_origin_stored { + CGAL_FUNCTOR_INIT_IGNORE(Squared_distance_to_origin_stored) + typedef R_ R; + typedef typename R::LA_vector LA; + typedef typename Get_type::type result_type; + typedef typename Get_type::type argument_type; + + result_type operator()(argument_type const& a)const{ + return LA::squared_norm(a); + } +}; + +template struct Squared_distance_to_origin_via_dotprod { + CGAL_FUNCTOR_INIT_IGNORE(Squared_distance_to_origin_via_dotprod) + typedef R_ R; + typedef typename R::LA_vector LA; + typedef typename Get_type::type result_type; + typedef typename Get_type::type argument_type; + + result_type operator()(argument_type const& a)const{ + return LA::dot_product(a,a); + } +}; + +template struct Orientation_of_vectors { + CGAL_FUNCTOR_INIT_IGNORE(Orientation_of_vectors) + typedef R_ R; + typedef typename R::Vector_cartesian_const_iterator first_argument_type; + typedef typename R::Vector_cartesian_const_iterator second_argument_type; + typedef typename Get_type::type result_type; + typedef typename R::LA_vector LA; + + template + result_type operator()(Iter const& f, Iter const& e) const { + return LA::determinant_of_iterators_to_vectors(f,e); + } +}; + +template struct Orientation_of_points { + CGAL_FUNCTOR_INIT_IGNORE(Orientation_of_points) + typedef R_ R; + typedef typename R::Point_cartesian_const_iterator first_argument_type; + typedef typename R::Point_cartesian_const_iterator second_argument_type; + typedef typename Get_type::type result_type; + typedef typename R::LA_vector LA; + + template + result_type operator()(Iter const& f, Iter const& e) const { + return LA::determinant_of_iterators_to_points(f,e); + } +}; + +template struct PV_dimension { + CGAL_FUNCTOR_INIT_IGNORE(PV_dimension) + typedef R_ R; + typedef typename R::Vector_ argument_type; + typedef int result_type; + typedef typename R::LA_vector LA; + typedef Tag_true Is_exact; + + template + result_type operator()(T const& v) const { + return LA::size_of_vector(v); + } +}; + +template struct Identity_functor { + CGAL_FUNCTOR_INIT_IGNORE(Identity_functor) + template + T const& operator()(T const&t) const { return t; } +}; + +} +} // namespace CGAL +#endif // CGAL_CARTESIAN_LA_FUNCTORS_H diff -Nru cgal-4.4/include/CGAL/NewKernel_d/Cartesian_per_dimension.h cgal-4.5/include/CGAL/NewKernel_d/Cartesian_per_dimension.h --- cgal-4.4/include/CGAL/NewKernel_d/Cartesian_per_dimension.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/Cartesian_per_dimension.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,33 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_KD_CARTESIAN_PER_DIM_H +#define CGAL_KD_CARTESIAN_PER_DIM_H +#include +#include +#include + +// Should probably disappear. + +namespace CGAL { +template +struct Cartesian_per_dimension : public R_ {}; +} + +#endif diff -Nru cgal-4.4/include/CGAL/NewKernel_d/Cartesian_static_filters.h cgal-4.5/include/CGAL/NewKernel_d/Cartesian_static_filters.h --- cgal-4.4/include/CGAL/NewKernel_d/Cartesian_static_filters.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/Cartesian_static_filters.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,95 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_KD_CARTESIAN_STATIC_FILTERS_H +#define CGAL_KD_CARTESIAN_STATIC_FILTERS_H +#include +#include +#include // bug, should be included by the next one +#include +#include + +namespace CGAL { +namespace SFA { // static filter adapter +// Note that this would be quite a bit simpler without stateful kernels +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)); + } + }; + }; + template result_type operator()(Iter f, Iter CGAL_assertion_code(e))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::Orientation_2()(P(this->kernel(),c,A),P(this->kernel(),c,B),P(this->kernel(),c,C)); + } +}; +} + +template +struct Cartesian_static_filters : public R_ { + CGAL_CONSTEXPR Cartesian_static_filters(){} + CGAL_CONSTEXPR Cartesian_static_filters(int d):R_(d){} +}; + +template +struct Cartesian_static_filters, R_, Derived_> : public R_ { + CGAL_CONSTEXPR Cartesian_static_filters(){} + CGAL_CONSTEXPR Cartesian_static_filters(int d):R_(d){} + typedef Cartesian_static_filters, R_, Derived_> Self; + typedef typename Default::Get::type Derived; + template struct Functor : Inherit_functor {}; + template struct Functor { + typedef + //typename boost::mpl::if_ < + //boost::is_same, + //typename Get_functor::type, + SFA::Orientation_of_points_2 + // >::type + type; + }; +}; + +} + +#endif diff -Nru cgal-4.4/include/CGAL/NewKernel_d/Coaffine.h cgal-4.5/include/CGAL/NewKernel_d/Coaffine.h --- cgal-4.4/include/CGAL/NewKernel_d/Coaffine.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/Coaffine.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,279 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_KD_COAFFINE_H +#define CGAL_KD_COAFFINE_H +#include +#include +#include +#include +#include + +namespace CGAL { +namespace CartesianDKernelFunctors { +struct Flat_orientation { + std::vector proj; + std::vector rest; + bool reverse; +}; + +// For debugging purposes +inline std::ostream& operator<< (std::ostream& o, Flat_orientation const& f) { + o << "Proj: "; + for(std::vector::const_iterator i=f.proj.begin(); + i!=f.proj.end(); ++i) + o << *i << ' '; + o << "\nRest: "; + for(std::vector::const_iterator i=f.rest.begin(); + i!=f.rest.end(); ++i) + o << *i << ' '; + o << "\nInv: " << f.reverse; + return o << '\n'; +} + +namespace internal { +namespace coaffine { +template +inline void debug_matrix(std::ostream& o, Mat const&mat) { + for(int i=0;i struct Construct_flat_orientation : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Construct_flat_orientation) + typedef R_ R; + typedef typename Get_type::type FT; + typedef typename Get_type::type Point; + typedef typename Increment_dimension::type Dplusone; + typedef typename R::LA::template Rebind_dimension::Other LA; + typedef typename LA::Square_matrix Matrix; + typedef typename Get_functor::type CCC; + typedef typename Get_functor::type PD; + typedef Flat_orientation result_type; + + // This implementation is going to suck. Maybe we should push the + // functionality into LA. And we should check (in debug mode) that + // the points are affinely independent. + template + result_type operator()(Iter f, Iter e)const{ + Iter f_save = f; + PD pd (this->kernel()); + CCC ccc (this->kernel()); + int dim = pd(*f); + Matrix coord (dim+1, dim+1); // use distance(f,e)? This matrix doesn't need to be square. + int col = 0; + Flat_orientation o; + std::vector& proj=o.proj; + std::vector& rest=o.rest; rest.reserve(dim+1); + for(int i=0; i::iterator it=rest.begin();;++it) { + CGAL_assertion(it!=rest.end()); + for(int i=0; i::type ifo(this->kernel()); + o.reverse = false; + o.reverse = ifo(o, f_save, e) != CGAL::POSITIVE; + return o; + } +}; + +template struct Contained_in_affine_hull : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Contained_in_affine_hull) + typedef R_ R; + typedef typename Get_type::type FT; + typedef typename Get_type::type Point; + typedef typename Get_type::type result_type; + typedef typename Get_functor::type CCC; + typedef typename Get_functor::type PD; + //typedef typename Increment_dimension::type D1; + //typedef typename Increment_dimension::type D2; + //typedef typename R::LA::template Rebind_dimension::Other LA; + typedef typename Increment_dimension::type Dplusone; + typedef typename R::LA::template Rebind_dimension::Other LA; + typedef typename LA::Square_matrix Matrix; + + // mostly copied from Construct_flat_orientation. TODO: dedup this code or use LA. + template + result_type operator()(Iter f, Iter e, Point const&x) const { + // FIXME: are the points in (f,e) required to be affinely independent? + PD pd (this->kernel()); + CCC ccc (this->kernel()); + int dim=pd(*f); + Matrix coord (dim+1, dim+1); // use distance + int col = 0; + std::vector proj; + std::vector rest; rest.reserve(dim+1); + for(int i=0; i::iterator it=rest.begin();it!=rest.end();++it) { + for(int i=0; i::iterator it=rest.begin();it!=rest.end();++it) { + for(int i=0; i struct In_flat_orientation : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(In_flat_orientation) + typedef R_ R; + typedef typename Get_type::type FT; + typedef typename Get_type::type Point; + typedef typename Get_type::type result_type; + typedef typename Increment_dimension::type D1; + typedef typename Increment_dimension::type D2; + typedef typename R::LA::template Rebind_dimension::Other LA; + typedef typename LA::Square_matrix Matrix; + + template + result_type operator()(Flat_orientation const&o, Iter f, Iter e) const { + // TODO: work in the projection instead of the ambient space. + typename Get_functor::type c(this->kernel()); + typename Get_functor::type pd(this->kernel()); + int d=pd(*f); + Matrix m(d+1,d+1); + int i=0; + for(;f!=e;++f,++i) { + Point const& p=*f; + m(i,0)=1; + for(int j=0;j::const_iterator it = o.rest.begin(); it != o.rest.end() /* i struct In_flat_side_of_oriented_sphere : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(In_flat_side_of_oriented_sphere) + typedef R_ R; + typedef typename Get_type::type FT; + typedef typename Get_type::type Point; + typedef typename Get_type::type result_type; + typedef typename Increment_dimension::type D1; + typedef typename Increment_dimension::type D2; + typedef typename R::LA::template Rebind_dimension::Other LA; + typedef typename LA::Square_matrix Matrix; + + template + result_type operator()(Flat_orientation const&o, Iter f, Iter e, Point const&x) const { + // TODO: can't work in the projection, but we should at least remove the row of 1s. + typename Get_functor::type c(this->kernel()); + typename Get_functor::type pd(this->kernel()); + int d=pd(*f); + Matrix m(d+2,d+2); + int i=0; + for(;f!=e;++f,++i) { + Point const& p=*f; + m(i,0)=1; + m(i,d+1)=0; + for(int j=0;j::const_iterator it = o.rest.begin(); it != o.rest.end() /* i),(Point_tag),(Compute_point_cartesian_coordinate_tag,Point_dimension_tag)); +CGAL_KD_DEFAULT_FUNCTOR(In_flat_side_of_oriented_sphere_tag,(CartesianDKernelFunctors::In_flat_side_of_oriented_sphere),(Point_tag),(Compute_point_cartesian_coordinate_tag,Point_dimension_tag)); +CGAL_KD_DEFAULT_FUNCTOR(Construct_flat_orientation_tag,(CartesianDKernelFunctors::Construct_flat_orientation),(Point_tag),(Compute_point_cartesian_coordinate_tag,Point_dimension_tag,In_flat_orientation_tag)); +CGAL_KD_DEFAULT_FUNCTOR(Contained_in_affine_hull_tag,(CartesianDKernelFunctors::Contained_in_affine_hull),(Point_tag),(Compute_point_cartesian_coordinate_tag,Point_dimension_tag)); +} +#endif diff -Nru cgal-4.4/include/CGAL/NewKernel_d/Define_kernel_types.h cgal-4.5/include/CGAL/NewKernel_d/Define_kernel_types.h --- cgal-4.4/include/CGAL/NewKernel_d/Define_kernel_types.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/Define_kernel_types.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,50 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_DEFINE_KERNEL_TYPES_H +#define CGAL_DEFINE_KERNEL_TYPES_H +#include +#include +#include +#ifdef CGAL_CXX11 +#include +#else +#include +#endif + +namespace CGAL { + namespace internal { + template::is_iterator> + struct Type_or_iter : K::template Type {}; + template + struct Type_or_iter : K::template Iterator {}; + } + template::type> struct Define_kernel_types; + template + struct Define_kernel_types > : Base {}; + template + struct Define_kernel_types > {}; + template + struct Define_kernel_types : + Typedef_tag_type::type, + Define_kernel_types + > {}; +} +#endif diff -Nru cgal-4.4/include/CGAL/NewKernel_d/Dimension_base.h cgal-4.5/include/CGAL/NewKernel_d/Dimension_base.h --- cgal-4.4/include/CGAL/NewKernel_d/Dimension_base.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/Dimension_base.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,49 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_KD_DIMENSION_BASE_h +#define CGAL_KD_DIMENSION_BASE_h +#include +#include +#include +namespace CGAL { +struct Store_dimension_base { + //TODO: add some assertions + Store_dimension_base(int dim=UNKNOWN_DIMENSION):dim_(dim){} + int dimension()const{return dim_;} + void set_dimension(int dim){dim_=dim;} + private: + int dim_; +}; +template +struct Dimension_base { + Dimension_base(int = UNKNOWN_DIMENSION){} + int dimension() const { return UNKNOWN_DIMENSION; } + void set_dimension(int) {} +}; +template +struct Dimension_base > { + Dimension_base(){} + Dimension_base(int CGAL_assertion_code(dim)){CGAL_assertion(dim_==dim);} + int dimension()const{return dim_;} + void set_dimension(int dim){CGAL_assertion(dim_==dim);} +}; +} +#endif + diff -Nru cgal-4.4/include/CGAL/NewKernel_d/Filtered_predicate2.h cgal-4.5/include/CGAL/NewKernel_d/Filtered_predicate2.h --- cgal-4.4/include/CGAL/NewKernel_d/Filtered_predicate2.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/Filtered_predicate2.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,137 @@ +// Copyright (c) 2001-2005 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Sylvain Pion + +#ifndef CGAL_FILTERED_PREDICATE_H +#define CGAL_FILTERED_PREDICATE_H + +#include +#include +#include +#include +#include +#include +#include + +namespace CGAL { + +// This template class is a wrapper that implements the filtering for any +// predicate (dynamic filters with IA). + +// TODO : +// - each predicate in the default kernel should define a tag that says if it +// wants to be filtered or not (=> all homogeneous predicate define this +// tag). We could even test-suite that automatically. It makes a strong +// new requirement on the kernel though... +// Could be done with a traits mechanism ? +// A default template could use the current IA, but other tags or whatever +// could specify no filtering at all, or static filtering... +// - same thing for constructions => virtual operator() ? +// - similarly, constructions should have a tag saying if they can throw or +// not, or we let all this up to the compiler optimizer to figure out ? +// - Some caching could be done at the Point_2 level. + + +template +class Filtered_predicate2 +{ +//TODO: pack (at least use a tuple) +//FIXME: is it better to store those, or just store enough to recreate them +//(i.e. possibly references to the kernels)? + EP ep; + AP ap; + C2E c2e; + C2A c2a; + + typedef typename AP::result_type Ares; + +public: + + typedef AP Approximate_predicate; + typedef EP Exact_predicate; + typedef C2E To_exact_converter; + typedef C2A To_approximate_converter; + + // FIXME: should use result_of, see emails by Nico + typedef typename EP::result_type result_type; + // AP::result_type must be convertible to EP::result_type. + + Filtered_predicate2() + {} + + template + Filtered_predicate2(const K& k) + : ep(k.exact_kernel()), ap(k.approximate_kernel()), c2e(k,k.exact_kernel()), c2a(k,k.approximate_kernel()) + {} + +#ifdef CGAL_CXX11 + template + result_type + operator()(Args&&... args) const + { + CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); + // Protection is outside the try block as VC8 has the CGAL_CFG_FPU_ROUNDING_MODE_UNWINDING_VC_BUG + { + Protect_FPU_rounding p; + try + { + // No forward here, the arguments may still be needed + Ares res = ap(c2a(args)...); + if (is_certain(res)) + return get_certain(res); + } + catch (Uncertain_conversion_exception) {} + } + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding p(CGAL_FE_TONEAREST); + return ep(c2e(std::forward(args))...); + } +#else + +#define CGAL_VAR(Z,N,C) C(a##N) +#define CGAL_CODE(Z,N,_) \ + template \ + result_type \ + operator()(BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& a)) const \ + { \ + CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); \ + { \ + Protect_FPU_rounding p; \ + try \ + { \ + Ares res = ap(BOOST_PP_ENUM(N,CGAL_VAR,c2a)); \ + if (is_certain(res)) \ + return get_certain(res); \ + } \ + catch (Uncertain_conversion_exception) {} \ + } \ + CGAL_BRANCH_PROFILER_BRANCH(tmp); \ + Protect_FPU_rounding p(CGAL_FE_TONEAREST); \ + return ep(BOOST_PP_ENUM(N,CGAL_VAR,c2e)); \ + } + BOOST_PP_REPEAT_FROM_TO(1, 10, CGAL_CODE, _ ) +#undef CGAL_CODE +#undef CGAL_VAR + +#endif +}; + +} //namespace CGAL + +#endif // CGAL_FILTERED_PREDICATE_H diff -Nru cgal-4.4/include/CGAL/NewKernel_d/function_objects_cartesian.h cgal-4.5/include/CGAL/NewKernel_d/function_objects_cartesian.h --- cgal-4.4/include/CGAL/NewKernel_d/function_objects_cartesian.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/function_objects_cartesian.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,1139 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_KERNEL_D_FUNCTION_OBJECTS_CARTESIAN_H +#define CGAL_KERNEL_D_FUNCTION_OBJECTS_CARTESIAN_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CGAL_CXX11 +#include +#endif + +namespace CGAL { +namespace CartesianDKernelFunctors { +namespace internal { +template struct Dimension_at_most { enum { value = false }; }; +template struct Dimension_at_most,b> { + enum { value = (a <= b) }; +}; +} + +template::value> struct Orientation_of_points : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Orientation_of_points) + typedef R_ R; + typedef typename Get_type::type Point; + typedef typename Get_type::type result_type; + typedef typename R::LA::Square_matrix Matrix; + + template + result_type operator()(Iter f, Iter e)const{ + typename Get_functor::type c(this->kernel()); + typename Get_functor::type pd(this->kernel()); + Point const& p0=*f++; + int d=pd(p0); + Matrix m(d,d); + // FIXME: this writes the vector coordinates in lines ? check all the other uses in this file, this may be wrong for some. + for(int i=0;f!=e;++f,++i) { + Point const& p=*f; + for(int j=0;j,typename R::Default_ambient_dimension>::value>::type> + template =3)>::type> + result_type operator()(U&&...u) const { + return operator()({std::forward(u)...}); + } + + template + result_type operator()(std::initializer_list

l) const { + return operator()(l.begin(),l.end()); + } +#else + //should we make it template to avoid instantiation for wrong dim? + //or iterate outside the class? +#define CGAL_VAR(Z,J,I) m(I,J)=c(p##I,J)-c(x,J); +#define CGAL_VAR2(Z,I,N) BOOST_PP_REPEAT(N,CGAL_VAR,I) +#define CGAL_CODE(Z,N,_) \ + result_type operator()(Point const&x, BOOST_PP_ENUM_PARAMS(N,Point const&p)) const { \ + typename Get_functor::type c(this->kernel()); \ + Matrix m(N,N); \ + BOOST_PP_REPEAT(N,CGAL_VAR2,N) \ + return R::LA::sign_of_determinant(CGAL_MOVE(m)); \ + } + +BOOST_PP_REPEAT_FROM_TO(7, 10, CGAL_CODE, _ ) + // No need to do it for <=6, since that uses a different code path +#undef CGAL_CODE +#undef CGAL_VAR2 +#undef CGAL_VAR +#endif +}; + +#ifdef CGAL_CXX11 +template struct Orientation_of_points,true> : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Orientation_of_points) + typedef R_ R; + typedef typename Get_type::type Point; + typedef typename Get_type::type result_type; + templatestruct Help; + templatestruct Help > { + template result_type operator()(C const&c,P const&x,T&&t)const{ + return sign_of_determinant(c(std::get(t),I%d)-c(x,I%d)...); + } + }; + template result_type operator()(P0 const&x,P&&...p)const{ + static_assert(d==sizeof...(P),"Wrong number of arguments"); + typename Get_functor::type c(this->kernel()); + return Help::type>()(c,x,std::forward_as_tuple(std::forward

(p)...)); + } + + + template result_type help2(Dimension_tag, Iter f, Iter const&e, U&&...u)const{ + auto const&p=*f; + return help2(Dimension_tag(),++f,e,std::forward(u)...,p); + } + template result_type help2(Dimension_tag<0>, Iter CGAL_assertion_code(f), Iter const& CGAL_assertion_code(e), U&&...u)const{ + CGAL_assertion(f==e); + return operator()(std::forward(u)...); + } + template + result_type operator()(Iter f, Iter e)const{ + return help2(Dimension_tag(),f,e); + } +}; +#else +#define CGAL_VAR(Z,J,I) c(p##I,J)-x##J +#define CGAL_VAR2(Z,I,N) BOOST_PP_ENUM(N,CGAL_VAR,I) +#define CGAL_VAR3(Z,N,_) Point const&p##N=*++f; +#define CGAL_VAR4(Z,N,_) RT const&x##N=c(x,N); +#define CGAL_CODE(Z,N,_) \ +template struct Orientation_of_points,true> : private Store_kernel { \ + CGAL_FUNCTOR_INIT_STORE(Orientation_of_points) \ + typedef R_ R; \ + typedef typename Get_type::type RT; \ + typedef typename Get_type::type Point; \ + typedef typename Get_type::type result_type; \ + result_type operator()(Point const&x, BOOST_PP_ENUM_PARAMS(N,Point const&p)) const { \ + typename Get_functor::type c(this->kernel()); \ + BOOST_PP_REPEAT(N,CGAL_VAR4,) \ + return sign_of_determinant(BOOST_PP_ENUM(N,CGAL_VAR2,N)); \ + } \ + template \ + result_type operator()(Iter f, Iter CGAL_assertion_code(e))const{ \ + Point const&x=*f; \ + BOOST_PP_REPEAT(N,CGAL_VAR3,) \ + CGAL_assertion(++f==e); \ + return operator()(x,BOOST_PP_ENUM_PARAMS(N,p)); \ + } \ +}; + + BOOST_PP_REPEAT_FROM_TO(2, 7, CGAL_CODE, _ ) +#undef CGAL_CODE +#undef CGAL_VAR4 +#undef CGAL_VAR3 +#undef CGAL_VAR2 +#undef CGAL_VAR + +#endif +} + +CGAL_KD_DEFAULT_FUNCTOR(Orientation_of_points_tag,(CartesianDKernelFunctors::Orientation_of_points),(Point_tag),(Point_dimension_tag,Compute_point_cartesian_coordinate_tag)); + +namespace CartesianDKernelFunctors { +template struct Orientation_of_vectors : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Orientation_of_vectors) + typedef R_ R; + typedef typename Get_type::type Vector; + typedef typename Get_type::type result_type; + typedef typename R::LA::Square_matrix Matrix; + + template + result_type operator()(Iter f, Iter e)const{ + typename Get_functor::type c(this->kernel()); + typename Get_functor::type vd(this->kernel()); + // FIXME: Uh? Using it on a vector ?! + Vector const& v0=*f; + int d=vd(v0); + Matrix m(d,d); + for(int j=0;j=3)>::type> + result_type operator()(U&&...u) const { + return operator()({std::forward(u)...}); + } + + template + result_type operator()(std::initializer_list l) const { + return operator()(l.begin(),l.end()); + } +#else + //TODO +#endif +}; +} + +CGAL_KD_DEFAULT_FUNCTOR(Orientation_of_vectors_tag,(CartesianDKernelFunctors::Orientation_of_vectors),(Vector_tag),(Point_dimension_tag,Compute_vector_cartesian_coordinate_tag)); + +namespace CartesianDKernelFunctors { +template struct Linear_rank : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Linear_rank) + typedef R_ R; + typedef typename Get_type::type Vector; + // Computing a sensible Uncertain is not worth it + typedef int result_type; + typedef typename R::LA::Dynamic_matrix Matrix; + + template + result_type operator()(Iter f, Iter e)const{ + typename Get_functor::type c(this->kernel()); + typename Get_functor::type vd(this->kernel()); + std::ptrdiff_t n=std::distance(f,e); + if (n==0) return 0; + Vector const& v0 = *f; + // FIXME: Uh? Using it on a vector ?! + int d=vd(v0); + Matrix m(d,n); + for(int j=0;j),(Vector_tag),(Point_dimension_tag,Compute_vector_cartesian_coordinate_tag)); + +namespace CartesianDKernelFunctors { +template struct Linearly_independent : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Linearly_independent) + typedef R_ R; + typedef typename Get_type::type result_type; + + template + result_type operator()(Iter f, Iter e)const{ + typename Get_functor::type vd(this->kernel()); + std::ptrdiff_t n=std::distance(f,e); + // FIXME: Uh? Using it on a vector ?! + int d=vd(*f); + if (n>d) return false; + typename Get_functor::type lr(this->kernel()); + return lr(f,e) == n; + } +}; +} + +CGAL_KD_DEFAULT_FUNCTOR(Linearly_independent_tag,(CartesianDKernelFunctors::Linearly_independent),(Vector_tag),(Point_dimension_tag,Linear_rank_tag)); + +namespace CartesianDKernelFunctors { +template struct Contained_in_linear_hull : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Contained_in_linear_hull) + typedef R_ R; + typedef typename Get_type::type Vector; + // Computing a sensible Uncertain is not worth it + typedef bool result_type; + typedef typename R::LA::Dynamic_matrix Matrix; + + template + result_type operator()(Iter f, Iter e,V const&w)const{ + typename Get_functor::type c(this->kernel()); + typename Get_functor::type vd(this->kernel()); + std::ptrdiff_t n=std::distance(f,e); + if (n==0) return false; + // FIXME: Uh? Using it on a vector ?! + int d=vd(w); + Matrix m(d,n+1); + for(int i=0; f!=e; ++f,++i){ + Vector const& v = *f; + for(int j=0;j),(Vector_tag),(Point_dimension_tag,Compute_vector_cartesian_coordinate_tag)); + +namespace CartesianDKernelFunctors { +template struct Affine_rank : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Affine_rank) + typedef R_ R; + typedef typename Get_type::type Point; + // Computing a sensible Uncertain is not worth it + typedef int result_type; + typedef typename R::LA::Dynamic_matrix Matrix; + + template + result_type operator()(Iter f, Iter e)const{ + typename Get_functor::type c(this->kernel()); + typename Get_functor::type pd(this->kernel()); + int n=(int)std::distance(f,e); + if (--n<=0) return n; + Point const& p0 = *f; + int d=pd(p0); + Matrix m(d,n); + for(int i=0; ++f!=e; ++i){ + Point const& p = *f; + for(int j=0;j),(Point_tag),(Point_dimension_tag,Compute_point_cartesian_coordinate_tag)); + +namespace CartesianDKernelFunctors { +template struct Affinely_independent : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Affinely_independent) + typedef R_ R; + typedef typename Get_type::type result_type; + + template + result_type operator()(Iter f, Iter e)const{ + typename Get_functor::type pd(this->kernel()); + std::ptrdiff_t n=std::distance(f,e); + int d=pd(*f); + if (--n>d) return false; + typename Get_functor::type ar(this->kernel()); + return ar(f,e) == n; + } +}; +} + +CGAL_KD_DEFAULT_FUNCTOR(Affinely_independent_tag,(CartesianDKernelFunctors::Affinely_independent),(Point_tag),(Point_dimension_tag,Affine_rank_tag)); + +namespace CartesianDKernelFunctors { +template struct Contained_in_simplex : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Contained_in_simplex) + typedef R_ R; + typedef typename Get_type::type Point; + // Computing a sensible Uncertain<*> is not worth it + // typedef typename Get_type::type result_type; + typedef bool result_type; + typedef typename Increment_dimension::type D1; + typedef typename Increment_dimension::type D2; + typedef typename R::LA::template Rebind_dimension::Other LA; + typedef typename LA::Dynamic_matrix Matrix; + typedef typename LA::Dynamic_vector DynVec; + typedef typename LA::Vector Vec; + + template + result_type operator()(Iter f, Iter e, P const&q)const{ + typename Get_functor::type c(this->kernel()); + typename Get_functor::type pd(this->kernel()); + std::ptrdiff_t n=std::distance(f,e); + if (n==0) return false; + int d=pd(q); + Matrix m(d+1,n); + DynVec a(n); + // FIXME: Should use the proper vector constructor (Iterator_and_last) + Vec b(d+1); + for(int j=0;j),(Point_tag),(Point_dimension_tag,Compute_point_cartesian_coordinate_tag)); + +namespace CartesianDKernelFunctors { + namespace internal { + template + struct Matrix_col_access { + typedef Ref_ result_type; + int col; + Matrix_col_access(int r):col(r){} + template Ref_ operator()(Mat const& m, std::ptrdiff_t row)const{ + return m(row,col); + } + }; + } +template struct Linear_base : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Linear_base) + typedef R_ R; + typedef typename Get_type::type Vector; + typedef typename Get_type::type FT; + typedef void result_type; + typedef typename R::LA::Dynamic_matrix Matrix; + + template + result_type operator()(Iter f, Iter e, Oter&o)const{ + typename Get_functor::type c(this->kernel()); + typename Get_functor::type vd(this->kernel()); + typename Get_functor >::type cv(this->kernel()); + std::ptrdiff_t n=std::distance(f,e); + if (n==0) return; + Vector const& v0 = *f; + // FIXME: Uh? Using it on a vector ?! + int d=vd(v0); + Matrix m(d,n); + for(int j=0;j()(0,0)) +#else + FT +#endif + Ref; + typedef Iterator_from_indices > IFI; + *o++ = cv(IFI(b,0,i),IFI(b,d,i)); + } + } +}; +} + +CGAL_KD_DEFAULT_FUNCTOR(Linear_base_tag,(CartesianDKernelFunctors::Linear_base),(Vector_tag),(Point_dimension_tag,Compute_vector_cartesian_coordinate_tag)); + +#if 0 +namespace CartesianDKernelFunctors { +template::value> struct Orientation : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Orientation) + typedef R_ R; + typedef typename Get_type::type Vector; + typedef typename Get_type::type Point; + typedef typename Get_type::type result_type; + typedef typename Get_functor::type OP; + typedef typename Get_functor::type OV; + + //FIXME!!! + //when Point and Vector are distinct types, the dispatch should be made + //in a way that doesn't instantiate a conversion from Point to Vector + template + result_type operator()(Iter const&f, Iter const& e)const{ + typename Get_functor::type pd(this->kernel()); + typename std::iterator_traits::difference_type d=std::distance(f,e); + int dim=pd(*f); // BAD + if(d==dim) return OV(this->kernel())(f,e); + CGAL_assertion(d==dim+1); + return OP(this->kernel())(f,e); + } + //TODO: version that takes objects directly instead of iterators +}; + +template struct Orientation : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Orientation) + typedef R_ R; + typedef typename Get_type::type Vector; + typedef typename Get_type::type Point; + typedef typename Get_type::type result_type; + typedef typename Get_functor::type OP; + typedef typename Get_functor::type OV; + typedef typename R::LA::Square_matrix Matrix; + + //FIXME!!! + //when Point and Vector are distinct types, the dispatch should be made + //in a way that doesn't instantiate a conversion from Point to Vector + template + typename boost::enable_if,result_type>::type + operator()(Iter const&f, Iter const& e)const{ + return OP(this->kernel())(f,e); + } + template + typename boost::enable_if,result_type>::type + operator()(Iter const&f, Iter const& e)const{ + return OV(this->kernel())(f,e); + } + //TODO: version that takes objects directly instead of iterators +}; +} +#endif + +namespace CartesianDKernelFunctors { +template struct Side_of_oriented_sphere : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Side_of_oriented_sphere) + typedef R_ R; + typedef typename Get_type::type RT; + typedef typename Get_type::type Point; + typedef typename Get_type::type result_type; + typedef typename Increment_dimension::type D1; + typedef typename Increment_dimension::type D2; + typedef typename R::LA::template Rebind_dimension::Other LA; + typedef typename LA::Square_matrix Matrix; + + template + result_type operator()(Iter f, Iter const& e)const{ + Point const& p0=*f++; // *--e ? + return this->operator()(f,e,p0); + } + + template + result_type operator()(Iter f, Iter const& e, Point const& p0) const { + typedef typename Get_functor::type Sqdo; + typename Get_functor::type c(this->kernel()); + typename Get_functor::type pd(this->kernel()); + + int d=pd(p0); + Matrix m(d+1,d+1); + if(CGAL::Is_stored::value) { + Sqdo sqdo(this->kernel()); + for(int i=0;f!=e;++f,++i) { + Point const& p=*f; + for(int j=0;j=4)>::type> + result_type operator()(U&&...u) const { + return operator()({std::forward(u)...}); + } + + template + result_type operator()(std::initializer_list

l) const { + return operator()(l.begin(),l.end()); + } +#else + //TODO +#endif +}; +} + +CGAL_KD_DEFAULT_FUNCTOR(Side_of_oriented_sphere_tag,(CartesianDKernelFunctors::Side_of_oriented_sphere),(Point_tag),(Point_dimension_tag,Squared_distance_to_origin_tag,Compute_point_cartesian_coordinate_tag)); + +namespace CartesianDKernelFunctors { +// TODO: implement it directly, it should be at least as fast as Side_of_oriented_sphere. +template struct Side_of_bounded_sphere : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Side_of_bounded_sphere) + typedef R_ R; + typedef typename Get_type::type Point; + typedef typename Get_type::type result_type; + + template + result_type operator()(Iter f, Iter const& e) const { + Point const& p0 = *f++; // *--e ? + return operator() (f, e, p0); + } + + template + result_type operator()(Iter const& f, Iter const& e, Point const& p0) const { + typename Get_functor::type sos (this->kernel()); + typename Get_functor::type op (this->kernel()); + // enum_cast is not very generic, but since this function isn't supposed to remain like this... + return enum_cast (sos (f, e, p0) * op (f, e)); + } + +#ifdef CGAL_CXX11 + template =4)>::type> + result_type operator()(U&&...u) const { + return operator()({std::forward(u)...}); + } + + template + result_type operator()(std::initializer_list

l) const { + return operator()(l.begin(),l.end()); + } +#else + //TODO +#endif +}; +} + +CGAL_KD_DEFAULT_FUNCTOR(Side_of_bounded_sphere_tag,(CartesianDKernelFunctors::Side_of_bounded_sphere),(Point_tag),(Side_of_oriented_sphere_tag,Orientation_of_points_tag)); + +namespace CartesianDKernelFunctors { +template struct Point_to_vector : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Point_to_vector) + typedef R_ R; + typedef typename Get_type::type RT; + typedef typename Get_type::type Vector; + typedef typename Get_type::type Point; + typedef typename Get_functor >::type CV; + typedef typename Get_functor >::type CI; + typedef Vector result_type; + typedef Point argument_type; + result_type operator()(argument_type const&v)const{ + CI ci(this->kernel()); + return CV(this->kernel())(ci(v,Begin_tag()),ci(v,End_tag())); + } +}; +} + +CGAL_KD_DEFAULT_FUNCTOR(Point_to_vector_tag,(CartesianDKernelFunctors::Point_to_vector),(Point_tag,Vector_tag),(Construct_ttag, Construct_ttag)); + +namespace CartesianDKernelFunctors { +template struct Vector_to_point : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Vector_to_point) + typedef R_ R; + typedef typename Get_type::type RT; + typedef typename Get_type::type Vector; + typedef typename Get_type::type Point; + typedef typename Get_functor >::type CV; + typedef typename Get_functor >::type CI; + typedef Point result_type; + typedef Vector argument_type; + result_type operator()(argument_type const&v)const{ + CI ci(this->kernel()); + return CV(this->kernel())(ci(v,Begin_tag()),ci(v,End_tag())); + } +}; +} + +CGAL_KD_DEFAULT_FUNCTOR(Vector_to_point_tag,(CartesianDKernelFunctors::Vector_to_point),(Point_tag,Vector_tag),(Construct_ttag, Construct_ttag)); + +namespace CartesianDKernelFunctors { +template struct Opposite_vector : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Opposite_vector) + typedef R_ R; + typedef typename Get_type::type RT; + typedef typename Get_type::type Vector; + typedef typename Get_functor >::type CV; + typedef typename Get_functor >::type CI; + typedef Vector result_type; + typedef Vector argument_type; + result_type operator()(Vector const&v)const{ + CI ci(this->kernel()); + return CV(this->kernel())(make_transforming_iterator(ci(v,Begin_tag()),std::negate()),make_transforming_iterator(ci(v,End_tag()),std::negate())); + } +}; +} + +CGAL_KD_DEFAULT_FUNCTOR(Opposite_vector_tag,(CartesianDKernelFunctors::Opposite_vector),(Vector_tag),(Construct_ttag, Construct_ttag)); + +namespace CartesianDKernelFunctors { +template struct Scaled_vector : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Scaled_vector) + typedef R_ R; + typedef typename Get_type::type FT; + typedef typename Get_type::type Vector; + typedef typename Get_functor >::type CV; + typedef typename Get_functor >::type CI; + typedef Vector result_type; + typedef Vector first_argument_type; + typedef FT second_argument_type; + result_type operator()(Vector const&v,FT const& s)const{ + CI ci(this->kernel()); + return CV(this->kernel())(make_transforming_iterator(ci(v,Begin_tag()),Scale(s)),make_transforming_iterator(ci(v,End_tag()),Scale(s))); + } +}; +} + +CGAL_KD_DEFAULT_FUNCTOR(Scaled_vector_tag,(CartesianDKernelFunctors::Scaled_vector),(Vector_tag),(Construct_ttag, Construct_ttag)); + +namespace CartesianDKernelFunctors { +template struct Sum_of_vectors : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Sum_of_vectors) + typedef R_ R; + typedef typename Get_type::type RT; + typedef typename Get_type::type Vector; + typedef typename Get_functor >::type CV; + typedef typename Get_functor >::type CI; + typedef Vector result_type; + typedef Vector first_argument_type; + typedef Vector second_argument_type; + result_type operator()(Vector const&a, Vector const&b)const{ + CI ci(this->kernel()); + return CV(this->kernel())(make_transforming_pair_iterator(ci(a,Begin_tag()),ci(b,Begin_tag()),std::plus()),make_transforming_pair_iterator(ci(a,End_tag()),ci(b,End_tag()),std::plus())); + } +}; +} + +CGAL_KD_DEFAULT_FUNCTOR(Sum_of_vectors_tag,(CartesianDKernelFunctors::Sum_of_vectors),(Vector_tag),(Construct_ttag, Construct_ttag)); + +namespace CartesianDKernelFunctors { +template struct Difference_of_vectors : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Difference_of_vectors) + typedef R_ R; + typedef typename Get_type::type RT; + typedef typename Get_type::type Vector; + typedef typename Get_functor >::type CV; + typedef typename Get_functor >::type CI; + typedef Vector result_type; + typedef Vector first_argument_type; + typedef Vector second_argument_type; + result_type operator()(Vector const&a, Vector const&b)const{ + CI ci(this->kernel()); + return CV(this->kernel())(make_transforming_pair_iterator(ci(a,Begin_tag()),ci(b,Begin_tag()),std::minus()),make_transforming_pair_iterator(ci(a,End_tag()),ci(b,End_tag()),std::minus())); + } +}; +} + +CGAL_KD_DEFAULT_FUNCTOR(Difference_of_vectors_tag,(CartesianDKernelFunctors::Difference_of_vectors),(Vector_tag),(Construct_ttag, Construct_ttag)); + +namespace CartesianDKernelFunctors { +template struct Translated_point : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Translated_point) + typedef R_ R; + typedef typename Get_type::type RT; + typedef typename Get_type::type Vector; + typedef typename Get_type::type Point; + typedef typename Get_functor >::type CP; + typedef typename Get_functor >::type CVI; + typedef typename Get_functor >::type CPI; + typedef Point result_type; + typedef Point first_argument_type; + typedef Vector second_argument_type; + result_type operator()(Point const&a, Vector const&b)const{ + CVI cvi(this->kernel()); + CPI cpi(this->kernel()); + return CP(this->kernel())(make_transforming_pair_iterator(cpi(a,Begin_tag()),cvi(b,Begin_tag()),std::plus()),make_transforming_pair_iterator(cpi(a,End_tag()),cvi(b,End_tag()),std::plus())); + } +}; +} + +CGAL_KD_DEFAULT_FUNCTOR(Translated_point_tag,(CartesianDKernelFunctors::Translated_point),(Point_tag, Vector_tag),(Construct_ttag, Construct_ttag, Construct_ttag)); + +namespace CartesianDKernelFunctors { +template struct Difference_of_points : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Difference_of_points) + typedef R_ R; + typedef typename Get_type::type RT; + typedef typename Get_type::type Point; + typedef typename Get_type::type Vector; + typedef typename Get_functor >::type CV; + typedef typename Get_functor >::type CI; + typedef Vector result_type; + typedef Point first_argument_type; + typedef Point second_argument_type; + result_type operator()(Point const&a, Point const&b)const{ + CI ci(this->kernel()); + return CV(this->kernel())(make_transforming_pair_iterator(ci(a,Begin_tag()),ci(b,Begin_tag()),std::minus()),make_transforming_pair_iterator(ci(a,End_tag()),ci(b,End_tag()),std::minus())); + } +}; +} + +CGAL_KD_DEFAULT_FUNCTOR(Difference_of_points_tag,(CartesianDKernelFunctors::Difference_of_points),(Point_tag, Vector_tag),(Construct_ttag, Construct_ttag)); + +namespace CartesianDKernelFunctors { +template struct Midpoint : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Midpoint) + typedef R_ R; + typedef typename Get_type::type FT; + typedef typename Get_type::type RT; + typedef typename Get_type::type Point; + typedef typename Get_functor >::type CP; + typedef typename Get_functor >::type CI; + typedef Point result_type; + typedef Point first_argument_type; + typedef Point second_argument_type; + // There is a division, but it will be cast to RT afterwards anyway, so maybe we could use RT. + struct Average : std::binary_function { + FT operator()(FT const&a, RT const&b)const{ + return (a+b)/2; + } + }; + result_type operator()(Point const&a, Point const&b)const{ + CI ci(this->kernel()); + //Divide half(2); + //return CP(this->kernel())(make_transforming_iterator(make_transforming_pair_iterator(ci.begin(a),ci.begin(b),std::plus()),half),make_transforming_iterator(make_transforming_pair_iterator(ci.end(a),ci.end(b),std::plus()),half)); + return CP(this->kernel())(make_transforming_pair_iterator(ci(a,Begin_tag()),ci(b,Begin_tag()),Average()),make_transforming_pair_iterator(ci(a,End_tag()),ci(b,End_tag()),Average())); + } +}; +} + +CGAL_KD_DEFAULT_FUNCTOR(Midpoint_tag,(CartesianDKernelFunctors::Midpoint),(Point_tag),(Construct_ttag, Construct_ttag)); + +namespace CartesianDKernelFunctors { +template struct Squared_length : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Squared_length) + typedef R_ R; + typedef typename Get_type::type RT; + typedef typename Get_type::type Vector; + typedef typename Get_functor >::type CI; + typedef RT result_type; + typedef Vector argument_type; + result_type operator()(Vector const&a)const{ + CI ci(this->kernel()); + typename Algebraic_structure_traits::Square f; + // TODO: avoid this RT(0)+... + return std::accumulate(make_transforming_iterator(ci(a,Begin_tag()),f),make_transforming_iterator(ci(a,End_tag()),f),RT(0)); + } +}; +} + +CGAL_KD_DEFAULT_FUNCTOR(Squared_length_tag,(CartesianDKernelFunctors::Squared_length),(Vector_tag),(Construct_ttag)); + +namespace CartesianDKernelFunctors { +template struct Squared_distance_to_origin : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Squared_distance_to_origin) + typedef R_ R; + typedef typename Get_type::type RT; + typedef typename Get_type::type Point; + typedef typename Get_functor >::type CI; + typedef RT result_type; + typedef Point argument_type; + result_type operator()(Point const&a)const{ + CI ci(this->kernel()); + typename Algebraic_structure_traits::Square f; + // TODO: avoid this RT(0)+... + return std::accumulate(make_transforming_iterator(ci(a,Begin_tag()),f),make_transforming_iterator(ci(a,End_tag()),f),RT(0)); + } +}; +} + +CGAL_KD_DEFAULT_FUNCTOR(Squared_distance_to_origin_tag,(CartesianDKernelFunctors::Squared_distance_to_origin),(Point_tag),(Construct_ttag)); + +namespace CartesianDKernelFunctors { +template struct Squared_distance : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Squared_distance) + typedef R_ R; + typedef typename Get_type::type RT; + typedef typename Get_type::type Point; + typedef typename Get_functor >::type CI; + typedef RT result_type; + typedef Point first_argument_type; + typedef Point second_argument_type; + struct Sq_diff : std::binary_function { + RT operator()(RT const&a, RT const&b)const{ + return CGAL::square(a-b); + } + }; + result_type operator()(Point const&a, Point const&b)const{ + CI ci(this->kernel()); + Sq_diff f; + // TODO: avoid this RT(0)+... + return std::accumulate(make_transforming_pair_iterator(ci(a,Begin_tag()),ci(b,Begin_tag()),f),make_transforming_pair_iterator(ci(a,End_tag()),ci(b,End_tag()),f),RT(0)); + } +}; +} + +CGAL_KD_DEFAULT_FUNCTOR(Squared_distance_tag,(CartesianDKernelFunctors::Squared_distance),(Point_tag),(Construct_ttag)); + +namespace CartesianDKernelFunctors { +template struct Scalar_product : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Scalar_product) + typedef R_ R; + typedef typename Get_type::type RT; + typedef typename Get_type::type Vector; + typedef typename Get_functor >::type CI; + typedef RT result_type; + typedef Vector first_argument_type; + typedef Vector second_argument_type; + result_type operator()(Vector const&a, Vector const&b)const{ + CI ci(this->kernel()); + std::multiplies f; + // TODO: avoid this RT(0)+... + return std::accumulate( + make_transforming_pair_iterator(ci(a,Begin_tag()),ci(b,Begin_tag()),f), + make_transforming_pair_iterator(ci(a, End_tag()),ci(b, End_tag()),f), + RT(0)); + } +}; +} + +CGAL_KD_DEFAULT_FUNCTOR(Scalar_product_tag,(CartesianDKernelFunctors::Scalar_product),(Vector_tag),(Construct_ttag)); + +namespace CartesianDKernelFunctors { +template struct Compare_distance : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Compare_distance) + typedef R_ R; + typedef typename Get_type::type Point; + typedef typename Get_functor::type CSD; + typedef typename Get_type::type result_type; + typedef Point first_argument_type; + typedef Point second_argument_type; + typedef Point third_argument_type; // why am I doing this already? + typedef Point fourth_argument_type; + result_type operator()(Point const&a, Point const&b, Point const&c)const{ + CSD csd(this->kernel()); + return CGAL_NTS compare(csd(a,b),csd(a,c)); + } + result_type operator()(Point const&a, Point const&b, Point const&c, Point const&d)const{ + CSD csd(this->kernel()); + return CGAL_NTS compare(csd(a,b),csd(c,d)); + } +}; +} + +CGAL_KD_DEFAULT_FUNCTOR(Compare_distance_tag,(CartesianDKernelFunctors::Compare_distance),(Point_tag),(Squared_distance_tag)); + +namespace CartesianDKernelFunctors { +template struct Less_point_cartesian_coordinate : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Less_point_cartesian_coordinate) + typedef R_ R; + typedef typename Get_type::type result_type; + 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; + + template + result_type operator()(V const&a, W const&b, I i)const{ + Cc c(this->kernel()); + return c(a,i)),(),(Compute_point_cartesian_coordinate_tag)); + +namespace CartesianDKernelFunctors { +template struct Compare_point_cartesian_coordinate : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Compare_point_cartesian_coordinate) + typedef R_ R; + typedef typename Get_type::type result_type; + 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; + + template + result_type operator()(V const&a, W const&b, I i)const{ + Cc c(this->kernel()); + return CGAL_NTS compare(c(a,i),c(b,i)); + } +}; +} + +CGAL_KD_DEFAULT_FUNCTOR(Compare_point_cartesian_coordinate_tag,(CartesianDKernelFunctors::Compare_point_cartesian_coordinate),(),(Compute_point_cartesian_coordinate_tag)); + +namespace CartesianDKernelFunctors { +template struct Compare_lexicographically : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Compare_lexicographically) + typedef R_ R; + typedef typename Get_type::type result_type; + 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; + + template + result_type operator()(V const&a, W const&b)const{ + CI c(this->kernel()); +#ifdef CGAL_CXX11 + auto +#else + typename CI::result_type +#endif + a_begin=c(a,Begin_tag()), + b_begin=c(b,Begin_tag()), + a_end=c(a,End_tag()); + result_type res; + // can't we do slightly better for Uncertain<*> ? + // after res=...; if(is_uncertain(res))return indeterminate(); + do res=CGAL_NTS compare(*a_begin++,*b_begin++); + while(a_begin!=a_end && res==EQUAL); + return res; + } +}; +} + +CGAL_KD_DEFAULT_FUNCTOR(Compare_lexicographically_tag,(CartesianDKernelFunctors::Compare_lexicographically),(),(Construct_ttag)); + +namespace CartesianDKernelFunctors { +template struct Less_lexicographically : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Less_lexicographically) + typedef R_ R; + typedef typename Get_type::type result_type; + typedef typename Get_functor::type CL; + typedef typename CGAL::Is_exact Is_exact; + + template + result_type operator() (V const&a, W const&b) const { + CL c (this->kernel()); + return c(a,b) < 0; + } +}; +} + +CGAL_KD_DEFAULT_FUNCTOR(Less_lexicographically_tag,(CartesianDKernelFunctors::Less_lexicographically),(),(Compare_lexicographically_tag)); + +namespace CartesianDKernelFunctors { +template struct Less_or_equal_lexicographically : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Less_or_equal_lexicographically) + typedef R_ R; + typedef typename Get_type::type result_type; + typedef typename Get_functor::type CL; + typedef typename CGAL::Is_exact Is_exact; + + template + result_type operator() (V const&a, W const&b) const { + CL c (this->kernel()); + return c(a,b) <= 0; + } +}; +} + +CGAL_KD_DEFAULT_FUNCTOR(Less_or_equal_lexicographically_tag,(CartesianDKernelFunctors::Less_or_equal_lexicographically),(),(Compare_lexicographically_tag)); + +namespace CartesianDKernelFunctors { +template struct Equal_points : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Equal_points) + typedef R_ R; + typedef typename Get_type::type result_type; + 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; + + template + result_type operator()(V const&a, W const&b)const{ + CI c(this->kernel()); +#ifdef CGAL_CXX11 + auto +#else + typename CI::result_type +#endif + a_begin=c(a,Begin_tag()), + b_begin=c(b,Begin_tag()), + a_end=c(a,End_tag()); + result_type res = true; + // Is using CGAL::possibly for Uncertain really an optimization? + do res = res & (*a_begin++ == *b_begin++); + while(a_begin!=a_end && possibly(res)); + return res; + } +}; +} + +CGAL_KD_DEFAULT_FUNCTOR(Equal_points_tag,(CartesianDKernelFunctors::Equal_points),(),(Construct_ttag)); + +namespace CartesianDKernelFunctors { +template struct Oriented_side : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Oriented_side) + typedef R_ R; + typedef typename Get_type::type result_type; + typedef typename Get_type::type Point; + typedef typename Get_type::type Hyperplane; + typedef typename Get_type::type Sphere; + typedef typename Get_functor::type VA; + typedef typename Get_functor::type HT; + typedef typename Get_functor::type SD; + typedef typename Get_functor::type SR; + typedef typename Get_functor::type CS; + + result_type operator()(Hyperplane const&h, Point const&p)const{ + HT ht(this->kernel()); + VA va(this->kernel()); + return CGAL::compare(va(h,p),ht(h)); + } + result_type operator()(Sphere const&s, Point const&p)const{ + SD sd(this->kernel()); + SR sr(this->kernel()); + CS cs(this->kernel()); + return CGAL::compare(sd(cs(s),p),sr(s)); + } +}; +} + +CGAL_KD_DEFAULT_FUNCTOR(Oriented_side_tag,(CartesianDKernelFunctors::Oriented_side),(Point_tag,Sphere_tag,Hyperplane_tag),(Value_at_tag,Hyperplane_translation_tag,Squared_distance_tag,Squared_radius_tag,Center_of_sphere_tag)); + +namespace CartesianDKernelFunctors { +template struct Has_on_positive_side : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Has_on_positive_side) + typedef R_ R; + typedef typename Get_type::type result_type; + typedef typename Get_functor::type OS; + + template + result_type operator()(Obj const&o, Pt const&p)const{ + OS os(this->kernel()); + return os(o,p) == ON_POSITIVE_SIDE; + } +}; +} + +CGAL_KD_DEFAULT_FUNCTOR(Has_on_positive_side_tag,(CartesianDKernelFunctors::Has_on_positive_side),(),(Oriented_side_tag)); + +} +#include +#endif // CGAL_KERNEL_D_FUNCTION_OBJECTS_CARTESIAN_H diff -Nru cgal-4.4/include/CGAL/NewKernel_d/functor_properties.h cgal-4.5/include/CGAL/NewKernel_d/functor_properties.h --- cgal-4.4/include/CGAL/NewKernel_d/functor_properties.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/functor_properties.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,40 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_EXACTNESS_H +#define CGAL_EXACTNESS_H +#include +#include +namespace CGAL { + +#define CGAL_STRAWBERRY(Is_pretty) \ + namespace internal { \ + BOOST_MPL_HAS_XXX_TRAIT_DEF(Is_pretty) \ + } \ + template::value> \ + struct Is_pretty : boost::false_type {}; \ + template \ + struct Is_pretty : T::Is_pretty {} + +CGAL_STRAWBERRY(Is_exact); +CGAL_STRAWBERRY(Is_fast); +CGAL_STRAWBERRY(Is_stored); +#undef CGAL_STRAWBERRY +} +#endif // CGAL_EXACTNESS_H diff -Nru cgal-4.4/include/CGAL/NewKernel_d/functor_tags.h cgal-4.5/include/CGAL/NewKernel_d/functor_tags.h --- cgal-4.4/include/CGAL/NewKernel_d/functor_tags.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/functor_tags.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,351 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_FUNCTOR_TAGS_H +#define CGAL_FUNCTOR_TAGS_H +#include // for Null_tag +#include +#ifdef CGAL_CXX11 +#include +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +namespace CGAL { + + // Find a better place for this later + + template struct Get_type + : K::template Type {}; + template struct Get_functor + : K::template Functor {}; +#ifdef CGAL_CXX11 + template using Type = typename Get_type::type; + template using Functor = typename Get_functor::type; +#endif + + class Null_type {~Null_type();}; // no such object should be created + + // To construct iterators + struct Begin_tag {}; + struct End_tag {}; + + // Functor category + struct Predicate_tag {}; + struct Construct_tag {}; + struct Construct_iterator_tag {}; + struct Compute_tag {}; + struct Misc_tag {}; + + struct No_filter_tag {}; + + templatestruct Construct_ttag {}; + templatestruct Convert_ttag {}; + + template struct Get_functor_category { typedef Misc_tag type; }; + template struct Typedef_tag_type; + //template struct Read_tag_type {}; + + template + struct Provides_type + : Has_type_different_from, Null_type> {}; + + template + struct Provides_functor + : Has_type_different_from, Null_functor> {}; + + template::type::value> + struct Provides_functors : boost::mpl::and_ < + Provides_functor::type>, + Provides_functors::type> > {}; + template + struct Provides_functors : boost::true_type {}; + + template::type::value> + struct Provides_types : boost::mpl::and_ < + Provides_type::type>, + Provides_types::type> > {}; + template + struct Provides_types : boost::true_type {}; + + namespace internal { BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_Type,template Type,false) } + template::value /* false */> + struct Provides_type_i : boost::false_type {}; + template + struct Provides_type_i + : Has_type_different_from, Null_type> {}; + + namespace internal { BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_Functor,template Functor,false) } + template::value /* false */> + struct Provides_functor_i : boost::false_type {}; + template + struct Provides_functor_i + : Has_type_different_from, Null_functor> {}; + + // TODO: Refine this a bit. + template ::value, + //bool=Provides_functor_i::value, + bool = +#ifdef __INTEL_COMPILER +// FIXME: this is obviously wrong, but Intel's compiler evaluates it to false +// and Epick_d doesn't seem to use the other case currently. + true +#else + internal::has_Functor::value +#endif + > + struct Inherit_functor : K::template Functor {}; + template + struct Inherit_functor {}; + + template ::value> + struct Inherit_type : K::template Type {}; + template + struct Inherit_type {}; + + struct Number_tag {}; + struct Discrete_tag {}; + struct Object_tag {}; + template struct Get_type_category { + // The lazy kernel uses it too eagerly, + // so it currently needs a default. + typedef Null_tag type; + }; + +#define CGAL_DECL_OBJ_(X,Y) \ + template \ + struct Typedef_tag_type : Base { typedef Obj X; }; \ + template \ + struct Get_type_category { typedef Y##_tag type; } +#define CGAL_DECL_OBJ(X,Y) struct X##_tag {}; \ + CGAL_DECL_OBJ_(X,Y) + + //namespace has_object { BOOST_MPL_HAS_XXX_TRAIT_DEF(X) } + //template + //struct Provides_tag_type : has_object::has_##X {}; + //template + //struct Read_tag_type { typedef typename Kernel::X type; } + + // Not exactly objects, but the extras can't hurt. + CGAL_DECL_OBJ(FT, Number); + CGAL_DECL_OBJ(RT, Number); + + CGAL_DECL_OBJ(Bool, Discrete); // Boolean_tag is already taken, and is a template :-( + CGAL_DECL_OBJ(Comparison_result, Discrete); + CGAL_DECL_OBJ(Sign, Discrete); + CGAL_DECL_OBJ(Orientation, Discrete); // Note: duplicate with the functor tag! + CGAL_DECL_OBJ(Oriented_side, Discrete); + CGAL_DECL_OBJ(Bounded_side, Discrete); + CGAL_DECL_OBJ(Angle, Discrete); + CGAL_DECL_OBJ(Flat_orientation, Discrete); + + CGAL_DECL_OBJ(Vector, Object); + CGAL_DECL_OBJ(Point, Object); + CGAL_DECL_OBJ(Segment, Object); + CGAL_DECL_OBJ(Sphere, Object); + CGAL_DECL_OBJ(Line, Object); + CGAL_DECL_OBJ(Direction, Object); + CGAL_DECL_OBJ(Hyperplane, Object); + CGAL_DECL_OBJ(Ray, Object); + CGAL_DECL_OBJ(Iso_box, Object); + CGAL_DECL_OBJ(Bbox, Object); + CGAL_DECL_OBJ(Aff_transformation, Object); +#undef CGAL_DECL_OBJ_ +#undef CGAL_DECL_OBJ + +// Intel fails with those, and they are not so useful. +// CGAL_KD_DEFAULT_TYPE(RT_tag,(typename Get_type::type),(),()); +// CGAL_KD_DEFAULT_TYPE(FT_tag,(CGAL::Quotient::type>),(),()); + +#define CGAL_SMURF2(A,B) CGAL_KD_DEFAULT_TYPE(A##_tag,(typename Same_uncertainty_nt::type>::type),(RT_tag),()) +#define CGAL_SMURF1(A) CGAL_SMURF2(A,CGAL::A) + CGAL_SMURF2(Bool, bool); + CGAL_SMURF1(Sign); + CGAL_SMURF1(Comparison_result); + CGAL_SMURF1(Orientation); + CGAL_SMURF1(Oriented_side); + CGAL_SMURF1(Bounded_side); + CGAL_SMURF1(Angle); +#undef CGAL_SMURF1 +#undef CGAL_SMURF2 + + // TODO: replace with Get_type_category + template struct is_NT_tag { enum { value = false }; }; + template<> struct is_NT_tag { enum { value = true }; }; + template<> struct is_NT_tag { enum { value = true }; }; + + template struct iterator_tag_traits { + enum { is_iterator = false, has_nth_element = false }; + typedef Null_tag value_tag; + }; + +#define CGAL_DECL_COMPUTE(X) struct X##_tag {}; \ + templatestruct Get_functor_category{typedef Compute_tag type;} + CGAL_DECL_COMPUTE(Compute_point_cartesian_coordinate); + CGAL_DECL_COMPUTE(Compute_vector_cartesian_coordinate); + CGAL_DECL_COMPUTE(Compute_homogeneous_coordinate); + CGAL_DECL_COMPUTE(Squared_distance); + CGAL_DECL_COMPUTE(Squared_distance_to_origin); + CGAL_DECL_COMPUTE(Squared_length); + CGAL_DECL_COMPUTE(Squared_radius); + CGAL_DECL_COMPUTE(Scalar_product); + CGAL_DECL_COMPUTE(Hyperplane_translation); + CGAL_DECL_COMPUTE(Value_at); +#undef CGAL_DECL_COMPUTE + +#define CGAL_DECL_ITER_OBJ(X,Y,Z,C) struct X##_tag {}; \ + template<>struct iterator_tag_traits { \ + enum { is_iterator = true, has_nth_element = true }; \ + typedef Y##_tag value_tag; \ + typedef Z##_tag nth_element; \ + typedef C##_tag container; \ + }; \ + template \ + struct Typedef_tag_type : Base { typedef Obj X; } + + //namespace has_object { BOOST_MPL_HAS_XXX_TRAIT_DEF(X) } + //template + //struct Provides_tag_type : has_object::has_##X {}; + //template + //struct Read_tag_type { typedef typename Kernel::X type; } + + CGAL_DECL_ITER_OBJ(Vector_cartesian_const_iterator, FT, Compute_vector_cartesian_coordinate, Vector); + CGAL_DECL_ITER_OBJ(Point_cartesian_const_iterator, FT, Compute_point_cartesian_coordinate, Point); +#undef CGAL_DECL_ITER_OBJ + + templatestruct map_result_tag{typedef Null_type type;}; + templatestruct map_result_tag >{typedef T type;}; + + templatestruct Get_functor_category,B,C> : + boost::mpl::if_c::is_iterator, + Construct_iterator_tag, + Construct_tag> {}; + + // Really? + templatestruct Get_functor_category,B,C>{typedef Misc_tag type;}; + +#define CGAL_DECL_CONSTRUCT(X,Y) struct X##_tag {}; \ + template<>struct map_result_tag{typedef Y##_tag type;}; \ + templatestruct Get_functor_category{typedef Construct_tag type;} + CGAL_DECL_CONSTRUCT(Midpoint,Point); + CGAL_DECL_CONSTRUCT(Center_of_sphere,Point); + CGAL_DECL_CONSTRUCT(Point_of_sphere,Point); + CGAL_DECL_CONSTRUCT(Segment_extremity,Point); + CGAL_DECL_CONSTRUCT(Sum_of_vectors,Vector); + CGAL_DECL_CONSTRUCT(Difference_of_vectors,Vector); + CGAL_DECL_CONSTRUCT(Opposite_vector,Vector); + CGAL_DECL_CONSTRUCT(Scaled_vector,Vector); + CGAL_DECL_CONSTRUCT(Orthogonal_vector,Vector); + CGAL_DECL_CONSTRUCT(Difference_of_points,Vector); + CGAL_DECL_CONSTRUCT(Translated_point,Point); + CGAL_DECL_CONSTRUCT(Point_to_vector,Vector); + CGAL_DECL_CONSTRUCT(Vector_to_point,Point); +#undef CGAL_DECL_CONSTRUCT +#if 0 +#define CGAL_DECL_ITER_CONSTRUCT(X,Y) struct X##_tag {}; \ + template<>struct map_result_tag{typedef Y##_tag type;}; \ + template<>struct map_functor_type{typedef Construct_iterator_tag type;} + CGAL_DECL_ITER_CONSTRUCT(Construct_point_cartesian_const_iterator,Point_cartesian_const_iterator); + CGAL_DECL_ITER_CONSTRUCT(Construct_vector_cartesian_const_iterator,Vector_cartesian_const_iterator); +#undef CGAL_DECL_ITER_CONSTRUCT +#endif + + //FIXME: choose a convention: prefix with Predicate_ ? +#define CGAL_DECL_PREDICATE_(X) \ + templatestruct Get_functor_category{typedef Predicate_tag type;} +#define CGAL_DECL_PREDICATE(X) struct X##_tag {}; \ + CGAL_DECL_PREDICATE_(X) + CGAL_DECL_PREDICATE(Less_point_cartesian_coordinate); + CGAL_DECL_PREDICATE(Compare_point_cartesian_coordinate); + CGAL_DECL_PREDICATE(Compare_distance); + CGAL_DECL_PREDICATE(Compare_lexicographically); + CGAL_DECL_PREDICATE(Less_lexicographically); + CGAL_DECL_PREDICATE(Less_or_equal_lexicographically); + CGAL_DECL_PREDICATE(Equal_points); + CGAL_DECL_PREDICATE(Has_on_positive_side); + CGAL_DECL_PREDICATE_(Orientation); // duplicate with the type + CGAL_DECL_PREDICATE_(Oriented_side); // duplicate with the type + CGAL_DECL_PREDICATE(Orientation_of_points); + CGAL_DECL_PREDICATE(Orientation_of_vectors); + CGAL_DECL_PREDICATE(Side_of_oriented_sphere); + CGAL_DECL_PREDICATE(Side_of_bounded_sphere); + CGAL_DECL_PREDICATE(Contained_in_affine_hull); + CGAL_DECL_PREDICATE(In_flat_orientation); + CGAL_DECL_PREDICATE(In_flat_side_of_oriented_sphere); + CGAL_DECL_PREDICATE(Construct_flat_orientation); // Making it a predicate is a questionable choice, it should be possible to let it be a construction for some implementations. Not sure how to do that... TODO + CGAL_DECL_PREDICATE(Linear_rank); + CGAL_DECL_PREDICATE(Affine_rank); + CGAL_DECL_PREDICATE(Linearly_independent); + CGAL_DECL_PREDICATE(Affinely_independent); + CGAL_DECL_PREDICATE(Contained_in_linear_hull); + CGAL_DECL_PREDICATE(Contained_in_simplex); +#undef CGAL_DECL_PREDICATE + +#define CGAL_DECL_MISC(X) struct X##_tag {}; \ + templatestruct Get_functor_category{typedef Misc_tag type;} + //TODO: split into _begin and _end ? + //CGAL_DECL_MISC(Construct_point_cartesian_const_iterator); + //CGAL_DECL_MISC(Construct_vector_cartesian_const_iterator); + CGAL_DECL_MISC(Point_dimension); + CGAL_DECL_MISC(Vector_dimension); + CGAL_DECL_MISC(Linear_base); // Find a more appropriate category? +#undef CGAL_DECL_MISC + + + // Properties for LA + struct Has_extra_dimension_tag {}; + struct Has_vector_plus_minus_tag {}; + struct Has_vector_scalar_ops_tag {}; + struct Has_dot_product_tag {}; + struct Has_determinant_of_vectors_tag {}; + struct Has_determinant_of_points_tag {}; + struct Has_determinant_of_iterator_to_vectors_tag {}; + struct Has_determinant_of_iterator_to_points_tag {}; + struct Has_determinant_of_vectors_omit_last_tag {}; + struct Stores_squared_norm_tag {}; + + template struct Preserved_by_non_linear_extra_coordinate + : boost::false_type {}; + template<> struct Preserved_by_non_linear_extra_coordinate + : boost::true_type {}; + template<> struct Preserved_by_non_linear_extra_coordinate + : boost::true_type {}; + template<> struct Preserved_by_non_linear_extra_coordinate + : boost::true_type {}; + template<> struct Preserved_by_non_linear_extra_coordinate + : boost::true_type {}; + template<> struct Preserved_by_non_linear_extra_coordinate + : boost::true_type {}; + template<> struct Preserved_by_non_linear_extra_coordinate + : boost::true_type {}; + + // Kernel properties + struct Point_stores_squared_distance_to_origin_tag {}; + +} +#endif // CGAL_FUNCTOR_TAGS_H diff -Nru cgal-4.4/include/CGAL/NewKernel_d/Kernel_2_interface.h cgal-4.5/include/CGAL/NewKernel_d/Kernel_2_interface.h --- cgal-4.4/include/CGAL/NewKernel_d/Kernel_2_interface.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/Kernel_2_interface.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,104 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_KD_KERNEL_2_INTERFACE_H +#define CGAL_KD_KERNEL_2_INTERFACE_H + +#include +#include +#include +#include + + +namespace CGAL { +template struct Kernel_2_interface : public Base_ { + typedef Base_ Base; + typedef Kernel_2_interface Kernel; + typedef typename Get_type::type RT; + typedef typename Get_type::type FT; + typedef typename Get_type::type Boolean; + typedef typename Get_type::type Sign; + typedef typename Get_type::type Comparison_result; + typedef typename Get_type::type Orientation; + typedef typename Get_type::type Oriented_side; + typedef typename Get_type::type Bounded_side; + typedef typename Get_type::type Angle; + typedef typename Get_type::type Point_2; + typedef typename Get_type::type Vector_2; + typedef typename Get_type::type Segment_2; + typedef cpp0x::tuple Triangle_2; // triangulation insists... + template struct Help_2p_i { + typedef typename Get_functor::type LT; + typedef typename LT::result_type result_type; + LT lt; + Help_2p_i(Kernel const&k):lt(k){} + result_type operator()(Point_2 const&a, Point_2 const&b) { + return lt(a,b,i); + } + }; + typedef Help_2p_i Less_x_2; + typedef Help_2p_i Less_y_2; + typedef Help_2p_i Compare_x_2; + typedef Help_2p_i Compare_y_2; + struct Compare_distance_2 { + typedef typename Get_functor::type CD; + typedef typename CD::result_type result_type; + CD cd; + Compare_distance_2(Kernel const&k):cd(k){} + result_type operator()(Point_2 const&a, Point_2 const&b, Point_2 const&c) { + return cd(a,b,c); + } + result_type operator()(Point_2 const&a, Point_2 const&b, Point_2 const&c, Point_2 const&d) { + return cd(a,b,c,d); + } + }; + struct Orientation_2 { + typedef typename Get_functor::type O; + typedef typename O::result_type result_type; + O o; + Orientation_2(Kernel const&k):o(k){} + result_type operator()(Point_2 const&a, Point_2 const&b, Point_2 const&c) { + //return o(a,b,c); + Point_2 const* t[3]={&a,&b,&c}; + return o(make_transforming_iterator(t+0),make_transforming_iterator(t+3)); + + } + }; + struct Side_of_oriented_circle_2 { + typedef typename Get_functor::type SOS; + typedef typename SOS::result_type result_type; + SOS sos; + 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)); + } + }; + 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); } + Compare_y_2 compare_y_2_object()const{ return Compare_y_2(*this); } + 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); } +}; +} + +#endif diff -Nru cgal-4.4/include/CGAL/NewKernel_d/Kernel_3_interface.h cgal-4.5/include/CGAL/NewKernel_d/Kernel_3_interface.h --- cgal-4.4/include/CGAL/NewKernel_d/Kernel_3_interface.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/Kernel_3_interface.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,102 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_KD_KERNEL_3_INTERFACE_H +#define CGAL_KD_KERNEL_3_INTERFACE_H + +#include +#include +#include +#include + + +namespace CGAL { +template struct Kernel_3_interface : public Base_ { + typedef Base_ Base; + typedef Kernel_3_interface Kernel; + typedef typename Get_type::type RT; + typedef typename Get_type::type FT; + typedef typename Get_type::type Boolean; + typedef typename Get_type::type Sign; + typedef typename Get_type::type Comparison_result; + typedef typename Get_type::type Orientation; + typedef typename Get_type::type Oriented_side; + typedef typename Get_type::type Bounded_side; + typedef typename Get_type::type Angle; + typedef typename Get_type::type Point_3; + typedef typename Get_type::type Vector_3; + typedef typename Get_type::type Segment_3; + typedef cpp0x::tuple Triangle_3; // placeholder + typedef cpp0x::tuple Tetrahedron_3; // placeholder + struct Compare_xyz_3 { + typedef typename Get_functor::type CL; + typedef typename CL::result_type result_type; + CL cl; + Compare_xyz_3(Kernel const&k):cl(k){} + result_type operator()(Point_3 const&a, Point_3 const&b) { + return cl(a,b); + } + }; + struct Compare_distance_3 { + typedef typename Get_functor::type CD; + typedef typename CD::result_type result_type; + CD cd; + Compare_distance_3(Kernel const&k):cd(k){} + result_type operator()(Point_3 const&a, Point_3 const&b, Point_3 const&c) { + return cd(a,b,c); + } + result_type operator()(Point_3 const&a, Point_3 const&b, Point_3 const&c, Point_3 const&d) { + return cd(a,b,c,d); + } + }; + struct Orientation_3 { + typedef typename Get_functor::type O; + typedef typename O::result_type result_type; + O o; + Orientation_3(Kernel const&k):o(k){} + result_type operator()(Point_3 const&a, Point_3 const&b, Point_3 const&c, Point_3 const&d) { + //return o(a,b,c,d); + Point_3 const* t[4]={&a,&b,&c,&d}; + return o(make_transforming_iterator(t+0),make_transforming_iterator(t+4)); + + } + }; + struct Side_of_oriented_sphere_3 { + typedef typename Get_functor::type SOS; + typedef typename SOS::result_type result_type; + SOS sos; + 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)); + } + }; + + // I don't have the Coplanar predicates (yet) + + + Compare_xyz_3 compare_xyz_3_object()const{ return Compare_xyz_3(*this); } + 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); } +}; +} + +#endif diff -Nru cgal-4.4/include/CGAL/NewKernel_d/KernelD_converter.h cgal-4.5/include/CGAL/NewKernel_d/KernelD_converter.h --- cgal-4.4/include/CGAL/NewKernel_d/KernelD_converter.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/KernelD_converter.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,195 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_KERNEL_D_CARTESIAN_CONVERTER_H +#define CGAL_KERNEL_D_CARTESIAN_CONVERTER_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace CGAL { +namespace internal { +// Reverses order, but that shouldn't matter. +template struct Map_taglist_to_typelist : + Map_taglist_to_typelist::type + ::template add::type> +{}; +template struct Map_taglist_to_typelist > : typeset<> {}; +} + +template > +struct Object_converter { + typedef Object result_type; + template + result_type operator()(Object const& o, F const& f) const { + typedef typename List::head H; + if (H const* ptr = object_cast(&o)) + return make_object(f(*ptr)); + else + return Object_converter()(o,f); + } +}; +template<> +struct Object_converter > { + typedef Object result_type; + template + result_type operator()(Object const&,F const&)const { + CGAL_error_msg("Cartesiand_converter is unable to determine what is wrapped in the Object"); + return Object(); + } +}; + + + //TODO: special case when K1==K2 (or they are very close?) +template +class KernelD_converter_ +: public KernelD_converter_ +{ + typedef typename List::head Tag_; + typedef typename List::tail Rest; + typedef KernelD_converter_ Base; + typedef typename Get_type::type K1_Obj; + typedef typename Get_type::type K2_Obj; + typedef typename Get_functor >::type K1_Conv; + typedef KO_converter KOC; + typedef CGAL_BOOSTD is_same no_converter; + typedef typename internal::Map_taglist_to_typelist::type::template contains duplicate; + + // Disable the conversion in some cases: + struct Do_not_use{}; + typedef typename boost::mpl::if_c < + // If Point==Vector, keep only one conversion + duplicate::value || + // For iterator objects, the default is make_transforming_iterator + (iterator_tag_traits::is_iterator && no_converter::value), + Do_not_use,K1_Obj>::type argument_type; + //typedef typename KOC::argument_type K1_Obj; + //typedef typename KOC::result_type K2_Obj; + public: + using Base::operator(); // don't use directly, just make it accessible to the next level + K2_Obj helper(K1_Obj const& o,CGAL_BOOSTD true_type)const{ + return KOC()(this->myself().kernel(),this->myself().kernel2(),this->myself(),o); + } + K2_Obj helper(K1_Obj const& o,CGAL_BOOSTD false_type)const{ + return K1_Conv(this->myself().kernel())(this->myself().kernel2(),this->myself(),o); + } + K2_Obj operator()(argument_type const& o)const{ + return helper(o,no_converter()); + } + template struct result:Base::template result{}; + template struct result {typedef K2_Obj type;}; +}; + +template +class KernelD_converter_ > { + public: + struct Do_not_use2{}; + void operator()(Do_not_use2)const{} + template struct result; + Final_& myself(){return *static_cast(this);} + Final_ const& myself()const{return *static_cast(this);} +}; + + +// TODO: use the intersection of Kn::Object_list. +template::type +//typeset::add::type/*::add::type*/ +> class KernelD_converter + : public Store_kernel, public Store_kernel2, + public KernelD_converter_,K1,K2,List_> +{ + typedef KernelD_converter Self; + typedef Self Final_; + typedef KernelD_converter_ Base; + typedef typename Get_type::type FT1; + typedef typename Get_type::type FT2; + typedef NT_converter NTc; + NTc c; // TODO: compressed storage as this is likely empty and the converter gets passed around (and stored in iterators) + + public: + KernelD_converter(){} + KernelD_converter(K1 const&a,K2 const&b):Store_kernel(a),Store_kernel2(b){} + + // For boost::result_of, used in transforming_iterator + template::value?42:0> struct result:Base::template result{}; + template struct result { + typedef transforming_iterator type; + }; + template struct result{typedef K2 type;}; + template struct result{typedef int type;}; + // Ideally the next 2 would come with Point_tag and Vector_tag, but that's hard... + template struct result{typedef Origin type;}; + template struct result{typedef Null_vector type;}; + template struct result{typedef Object type;}; + template struct result{typedef FT2 type;}; + + using Base::operator(); + typename Store_kernel2::reference2_type operator()(K1 const&)const{return this->kernel2();} + int operator()(int i)const{return i;} + Origin operator()(Origin const&o)const{return o;} + Null_vector operator()(Null_vector const&v)const{return v;} + FT2 operator()(FT1 const&x)const{return c(x);} + //RT2 operator()(typename First_if_different::Type const&x)const{return cr(x);} + + typename Get_type::type const& + operator()(typename Get_type::type const&o)const + { return o; } // Both kernels should have the same, returning a reference should warn if not. + + template + transforming_iterator,It>::type> + operator()(It const& it) const { + return make_transforming_iterator(it,*this); + } + + template + //TODO: use decltype in C++11 instead of result + std::vector::type> + operator()(const std::vector& v) const { + return std::vector::type>(operator()(v.begin()),operator()(v.begin())); + } + + //TODO: convert std::list and other containers? + + Object + operator()(const Object &obj) const + { + typedef typename internal::Map_taglist_to_typelist::type Possibilities; + //TODO: add Empty, vector, etc to the list. + return Object_converter()(obj,*this); + } + + //TODO: convert boost::variant + +}; + +} //namespace CGAL + +#endif // CGAL_KERNEL_D_CARTESIAN_CONVERTER_H diff -Nru cgal-4.4/include/CGAL/NewKernel_d/Kernel_d_interface.h cgal-4.5/include/CGAL/NewKernel_d/Kernel_d_interface.h --- cgal-4.4/include/CGAL/NewKernel_d/Kernel_d_interface.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/Kernel_d_interface.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,210 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_KD_KERNEL_D_INTERFACE_H +#define CGAL_KD_KERNEL_D_INTERFACE_H + +#include +#include +#include +#include + + +namespace CGAL { +template struct Kernel_d_interface : public Base_ { + CGAL_CONSTEXPR Kernel_d_interface(){} + CGAL_CONSTEXPR Kernel_d_interface(int d):Base_(d){} + + typedef Base_ Base; + typedef Kernel_d_interface Kernel; + typedef Base_ R_; // for the macros + typedef typename Get_type::type RT; + typedef typename Get_type::type FT; + typedef typename Get_type::type Boolean; + typedef typename Get_type::type Sign; + typedef typename Get_type::type Comparison_result; + typedef typename Get_type::type Orientation; + typedef typename Get_type::type Oriented_side; + typedef typename Get_type::type Bounded_side; + typedef typename Get_type::type Angle; + typedef typename Get_type::type Flat_orientation_d; + typedef typename Get_type::type Point_d; + typedef typename Get_type::type Vector_d; + typedef typename Get_type::type Segment_d; + typedef typename Get_type::type Sphere_d; + typedef typename Get_type::type Hyperplane_d; + typedef Vector_d Direction_d; + typedef typename Get_type::type Line_d; + typedef typename Get_type::type Ray_d; + typedef typename Get_type::type Iso_box_d; + typedef typename Get_type::type Aff_transformation_d; + typedef typename Get_functor::type Compute_coordinate_d; + typedef typename Get_functor::type Compare_lexicographically_d; + typedef typename Get_functor::type Equal_d; + typedef typename Get_functor::type Less_lexicographically_d; + typedef typename Get_functor::type Less_or_equal_lexicographically_d; + // FIXME: and vectors? + typedef typename Get_functor::type Orientation_d; + typedef typename Get_functor::type Less_coordinate_d; + typedef typename Get_functor::type Point_dimension_d; + typedef typename Get_functor::type Side_of_oriented_sphere_d; + typedef typename Get_functor::type Contained_in_affine_hull_d; + typedef typename Get_functor::type Construct_flat_orientation_d; + typedef typename Get_functor::type In_flat_orientation_d; + typedef typename Get_functor::type In_flat_side_of_oriented_sphere_d; + typedef typename Get_functor::type Point_to_vector_d; + typedef typename Get_functor::type Vector_to_point_d; + typedef typename Get_functor >::type Construct_point_d; + typedef typename Get_functor >::type Construct_vector_d; + typedef typename Get_functor >::type Construct_segment_d; + typedef typename Get_functor >::type Construct_sphere_d; + typedef typename Get_functor >::type Construct_hyperplane_d; + typedef Construct_vector_d Construct_direction_d; + typedef typename Get_functor >::type Construct_line_d; + typedef typename Get_functor >::type Construct_ray_d; + typedef typename Get_functor >::type Construct_iso_box_d; + typedef typename Get_functor >::type Construct_aff_transformation_d; + typedef typename Get_functor::type Midpoint_d; + struct Component_accessor_d : private Store_kernel { + typedef Kernel R_; // for the macro + CGAL_FUNCTOR_INIT_STORE(Component_accessor_d) + int dimension(Point_d const&p){ + return this->kernel().point_dimension_d_object()(p); + } + FT cartesian(Point_d const&p, int i){ + return this->kernel().compute_coordinate_d_object()(p,i); + } + RT homogeneous(Point_d const&p, int i){ + if (i == dimension(p)) + return 1; + return cartesian(p, i); + } + }; + struct Construct_cartesian_const_iterator_d : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Construct_cartesian_const_iterator_d) + typedef typename Get_functor >::type CPI; + typedef typename Get_functor >::type CVI; + // FIXME: The following sometimes breaks compilation. The typedef below forces instantiation of this, which forces Point_d, which itself (in the wrapper) needs the derived kernel to tell it what the base kernel is, and that's a cycle. The exact circumstances are not clear, g++ and clang++ are ok in both C++03 and C++11, it is only clang in C++11 without CGAL_CXX11 that breaks. For now, rely on result_type. + //typedef typename CGAL::decay::type>::type result_type; + typedef typename CGAL::decay::type result_type; + // Kernel_d requires a common iterator type for points and vectors + // TODO: provide this mixed functor in preKernel? + //CGAL_static_assertion((boost::is_same::type>::type, result_type>::value)); + CGAL_static_assertion((boost::is_same::type, result_type>::value)); + template + result_type operator()(Point_d const&p, Tag_ t)const{ + return CPI(this->kernel())(p,t); + } + template + result_type operator()(typename First_if_different::Type const&v, Tag_ t)const{ + return CVI(this->kernel())(v,t); + } + + template + result_type operator()(Obj const&o)const{ + return operator()(o, Begin_tag()); + } + result_type operator()(Point_d const&p, int)const{ + return operator()(p, End_tag()); + } + result_type operator()(typename First_if_different::Type const&v, int)const{ + return operator()(v, End_tag()); + } + }; + typedef typename Construct_cartesian_const_iterator_d::result_type Cartesian_const_iterator_d; + typedef typename Get_functor::type Squared_distance_d; + typedef typename Get_functor::type Affine_rank_d; + typedef typename Get_functor::type Affinely_independent_d; + typedef typename Get_functor::type Contained_in_linear_hull_d; + typedef typename Get_functor::type Contained_in_simplex_d; + typedef typename Get_functor::type Has_on_positive_side_d; + typedef typename Get_functor::type Linear_rank_d; + typedef typename Get_functor::type Linearly_independent_d; + typedef typename Get_functor::type Oriented_side_d; + typedef typename Get_functor::type Side_of_bounded_sphere_d; + + typedef typename Get_functor::type Center_of_sphere_d; + typedef typename Get_functor::type Value_at_d; + typedef typename Get_functor::type Point_of_sphere_d; + typedef typename Get_functor::type Orthogonal_vector_d; + typedef typename Get_functor::type Linear_base_d; + + //TODO: + //typedef ??? Intersect_d; + + + Compute_coordinate_d compute_coordinate_d_object()const{ return Compute_coordinate_d(*this); } + Has_on_positive_side_d has_on_positive_side_d_object()const{ return Has_on_positive_side_d(*this); } + Compare_lexicographically_d compare_lexicographically_d_object()const{ return Compare_lexicographically_d(*this); } + Equal_d equal_d_object()const{ return Equal_d(*this); } + Less_lexicographically_d less_lexicographically_d_object()const{ return Less_lexicographically_d(*this); } + Less_or_equal_lexicographically_d less_or_equal_lexicographically_d_object()const{ return Less_or_equal_lexicographically_d(*this); } + Less_coordinate_d less_coordinate_d_object()const{ return Less_coordinate_d(*this); } + Orientation_d orientation_d_object()const{ return Orientation_d(*this); } + Oriented_side_d oriented_side_d_object()const{ return Oriented_side_d(*this); } + Point_dimension_d point_dimension_d_object()const{ return Point_dimension_d(*this); } + Point_of_sphere_d point_of_sphere_d_object()const{ return Point_of_sphere_d(*this); } + Side_of_oriented_sphere_d side_of_oriented_sphere_d_object()const{ return Side_of_oriented_sphere_d(*this); } + Side_of_bounded_sphere_d side_of_bounded_sphere_d_object()const{ return Side_of_bounded_sphere_d(*this); } + Contained_in_affine_hull_d contained_in_affine_hull_d_object()const{ return Contained_in_affine_hull_d(*this); } + Contained_in_linear_hull_d contained_in_linear_hull_d_object()const{ return Contained_in_linear_hull_d(*this); } + Contained_in_simplex_d contained_in_simplex_d_object()const{ return Contained_in_simplex_d(*this); } + Construct_flat_orientation_d construct_flat_orientation_d_object()const{ return Construct_flat_orientation_d(*this); } + In_flat_orientation_d in_flat_orientation_d_object()const{ return In_flat_orientation_d(*this); } + In_flat_side_of_oriented_sphere_d in_flat_side_of_oriented_sphere_d_object()const{ return In_flat_side_of_oriented_sphere_d(*this); } + Point_to_vector_d point_to_vector_d_object()const{ return Point_to_vector_d(*this); } + Vector_to_point_d vector_to_point_d_object()const{ return Vector_to_point_d(*this); } + Affine_rank_d affine_rank_d_object()const{ return Affine_rank_d(*this); } + Affinely_independent_d affinely_independent_d_object()const{ return Affinely_independent_d(*this); } + Linear_base_d linear_base_d_object()const{ return Linear_base_d(*this); } + Linear_rank_d linear_rank_d_object()const{ return Linear_rank_d(*this); } + Linearly_independent_d linearly_independent_d_object()const{ return Linearly_independent_d(*this); } + Midpoint_d midpoint_d_object()const{ return Midpoint_d(*this); } + Value_at_d value_at_d_object()const{ return Value_at_d(*this); } + /// Intersect_d intersect_d_object()const{ return Intersect_d(*this); } + Component_accessor_d component_accessor_d_object()const{ return Component_accessor_d(*this); } + Orthogonal_vector_d orthogonal_vector_d_object()const{ return Orthogonal_vector_d(*this); } + Construct_cartesian_const_iterator_d construct_cartesian_const_iterator_d_object()const{ return Construct_cartesian_const_iterator_d(*this); } + Construct_point_d construct_point_d_object()const{ return Construct_point_d(*this); } + Construct_vector_d construct_vector_d_object()const{ return Construct_vector_d(*this); } + Construct_segment_d construct_segment_d_object()const{ return Construct_segment_d(*this); } + Construct_sphere_d construct_sphere_d_object()const{ return Construct_sphere_d(*this); } + Construct_hyperplane_d construct_hyperplane_d_object()const{ return Construct_hyperplane_d(*this); } + Squared_distance_d squared_distance_d_object()const{ return Squared_distance_d(*this); } + Center_of_sphere_d center_of_sphere_d_object()const{ return Center_of_sphere_d(*this); } + Construct_direction_d construct_direction_d_object()const{ return Construct_direction_d(*this); } + Construct_line_d construct_line_d_object()const{ return Construct_line_d(*this); } + Construct_ray_d construct_ray_d_object()const{ return Construct_ray_d(*this); } + Construct_iso_box_d construct_iso_box_d_object()const{ return Construct_iso_box_d(*this); } + Construct_aff_transformation_d construct_aff_transformation_d_object()const{ return Construct_aff_transformation_d(*this); } + + // Dummies for those required functors missing a concept. + typedef Null_functor Position_on_line_d; + Position_on_line_d position_on_line_d_object()const{return Null_functor();} + typedef Null_functor Barycentric_coordinates_d; + Barycentric_coordinates_d barycentric_coordinates_d_object()const{return Null_functor();} + + /* Not provided because they don't make sense here: + Lift_to_paraboloid_d + Project_along_d_axis_d + */ +}; +} + +#endif // CGAL_KD_KERNEL_D_INTERFACE_H diff -Nru cgal-4.4/include/CGAL/NewKernel_d/Kernel_object_converter.h cgal-4.5/include/CGAL/NewKernel_d/Kernel_object_converter.h --- cgal-4.4/include/CGAL/NewKernel_d/Kernel_object_converter.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/Kernel_object_converter.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,121 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_KD_KO_CONVERTER_H +#define CGAL_KD_KO_CONVERTER_H +#include +#include +#include // First_if_different +namespace CGAL { +template struct KO_converter; +//TODO: It would probably be better if this was a Misc Functor in K1. +// This way K1 could chose how it wants to present its points (sparse +// iterator?) and derived classes would inherit it. + +namespace internal { +template +struct Point_converter_help { + typedef typename Get_type::type argument_type; + typedef typename Get_type::type result_type; + template + result_type operator()(K1 const& k1, K2 const& k2, C const& conv, argument_type const& p) const { + typename Get_functor >::type i(k1); + typename Get_functor >::type cp(k2); + return cp(conv(i(p,Begin_tag())),conv(i(p,End_tag()))); + } +}; +#ifdef CGAL_CXX11 +// This doesn't seem so useful, the compiler should be able to handle +// the iterators just as efficiently. +template +struct Point_converter_help,K1,K2> { + typedef typename Get_type::type argument_type; + typedef typename Get_type::type result_type; + template + result_type help(Indices, K1 const& k1, K2 const& k2, C const& conv, argument_type const& p) const { + typename Get_functor::type cc(k1); + typename Get_functor >::type cp(k2); + return cp(conv(cc(p,I))...); + } + template + result_type operator()(K1 const& k1, K2 const& k2, C const& conv, argument_type const& p) const { + return help(typename N_increasing_indices::type(),k1,k2,conv,p); + } +}; +#endif +} +template struct KO_converter +: internal::Point_converter_help +{}; + +template struct KO_converter{ + typedef typename Get_type::type K1_Vector; + + // Disabling is now done in KernelD_converter + // // can't use vector without at least a placeholder point because of this + // typedef typename K1:: Point K1_Point; + // typedef typename First_if_different::Type argument_type; + + typedef K1_Vector argument_type; + typedef typename Get_type::type result_type; + template + result_type operator()(K1 const& k1, K2 const& k2, C const& conv, argument_type const& v) const { + typename Get_functor >::type i(k1); + typename Get_functor >::type cp(k2); + return cp(conv(i(v,Begin_tag())),conv(i(v,End_tag()))); + } +}; + +template struct KO_converter{ + typedef typename Get_type::type argument_type; + typedef typename Get_type::type result_type; + template + result_type operator()(K1 const& k1, K2 const& k2, C const& conv, argument_type const& s) const { + typename Get_functor::type f(k1); + typename Get_functor >::type cs(k2); + return cs(conv(f(s,0)),conv(f(s,1))); + } +}; + +template struct KO_converter{ + typedef typename Get_type::type argument_type; + typedef typename Get_type::type result_type; + template + result_type operator()(K1 const& k1, K2 const& k2, C const& conv, argument_type const& h) const { + typename Get_functor::type ov(k1); + typename Get_functor::type ht(k1); + typename Get_functor >::type ch(k2); + return ch(conv(ov(h)),conv(ht(h))); + } +}; + +template struct KO_converter{ + typedef typename Get_type::type argument_type; + typedef typename Get_type::type result_type; + template + result_type operator()(K1 const& k1, K2 const& k2, C const& conv, argument_type const& s) const { + typename Get_functor::type cos(k1); + typename Get_functor::type sr(k1); + typename Get_functor >::type cs(k2); + return cs(conv(cos(s)),conv(sr(s))); + } +}; + +} +#endif diff -Nru cgal-4.4/include/CGAL/NewKernel_d/LA_eigen/constructors.h cgal-4.5/include/CGAL/NewKernel_d/LA_eigen/constructors.h --- cgal-4.4/include/CGAL/NewKernel_d/LA_eigen/constructors.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/LA_eigen/constructors.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,151 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_LA_EIGEN_CONSTRUCTORS_H +#define CGAL_LA_EIGEN_CONSTRUCTORS_H +#include +#ifndef CGAL_EIGEN3_ENABLED +#error Requires Eigen +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace CGAL { + template struct Construct_eigen { + typedef Vector_ result_type; + typedef typename Vector_::Scalar NT; + + private: + static void check_dim(int CGAL_assertion_code(d)){ + CGAL_assertion_code(int m = result_type::MaxSizeAtCompileTime;) + CGAL_assertion((m == Eigen::Dynamic) || (d <= m)); + } + public: + + struct Dimension { + // Initialize with NaN if possible? + result_type operator()(int d) const { + check_dim(d); + return result_type(d); + } + }; + + struct Iterator { + template + result_type operator()(int d,Iter const& f,Iter const& e) const { + check_dim(d); + CGAL_assertion(d==std::distance(f,e)); + result_type a(d); + // TODO: check the right way to do this + std::copy(f,e,&a[0]); + return a; + } + }; + +#if 0 + struct Iterator_add_one { + template + result_type operator()(int d,Iter const& f,Iter const& e) const { + check_dim(d); + CGAL_assertion(d==std::distance(f,e)+1); + result_type a(d); + std::copy(f,e,&a[0]); + a[d-1]=1; + return a; + } + }; +#endif + + struct Iterator_and_last { + template + result_type operator()(int d,Iter const& f,Iter const& e,CGAL_FORWARDABLE(T) t) const { + check_dim(d); + CGAL_assertion(d==std::distance(f,e)+1); + result_type a(d); + std::copy(f,e,&a[0]); + a[d-1]=CGAL_FORWARD(T,t); + return a; + } + }; + +#ifdef CGAL_CXX11 + struct Initializer_list { + // Fix T==NT? + template + result_type operator()(std::initializer_list l) const { + return Iterator()(l.size(),l.begin(),l.end()); + } + }; +#endif + + struct Values { +#ifdef CGAL_CXX11 + // TODO avoid going through Initializer_list which may cause extra copies. Possibly use forward_as_tuple. + template + result_type operator()(U&&...u) const { + check_dim(sizeof...(U)); // TODO: use static_assert + return Initializer_list()({forward_safe(u)...}); + } +#else + +#define CGAL_CODE(Z,N,_) result_type operator()(BOOST_PP_ENUM_PARAMS(N,NT const& t)) const { \ + check_dim(N); \ + result_type a(N); \ + a << BOOST_PP_ENUM_PARAMS(N,t); \ + return a; \ +} +BOOST_PP_REPEAT_FROM_TO(1, 11, CGAL_CODE, _ ) +#undef CGAL_CODE + +#endif + }; + + struct Values_divide { +#ifdef CGAL_CXX11 + template + result_type operator()(H const&h,U&&...u) const { + check_dim(sizeof...(U)); // TODO: use static_assert + return Initializer_list()({Rational_traits().make_rational(std::forward(u),h)...}); + } +#else + +#define CGAL_VAR(Z,N,_) ( Rational_traits().make_rational( t##N ,h) ) +#define CGAL_CODE(Z,N,_) template result_type \ + operator()(H const&h, BOOST_PP_ENUM_PARAMS(N,NT const& t)) const { \ + check_dim(N); \ + result_type a(N); \ + a << BOOST_PP_ENUM(N,CGAL_VAR,); \ + return a; \ + } + BOOST_PP_REPEAT_FROM_TO(1, 11, CGAL_CODE, _ ) +#undef CGAL_CODE +#undef CGAL_VAR + +#endif + }; + }; +} +#endif diff -Nru cgal-4.4/include/CGAL/NewKernel_d/LA_eigen/LA.h cgal-4.5/include/CGAL/NewKernel_d/LA_eigen/LA.h --- cgal-4.4/include/CGAL/NewKernel_d/LA_eigen/LA.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/LA_eigen/LA.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,170 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_LA_EIGEN_H +#define CGAL_LA_EIGEN_H +#include +#ifndef CGAL_EIGEN3_ENABLED +#error Requires Eigen +#endif +#include +#include +#include +#include +#include +#include + +namespace CGAL { + +//FIXME: where could we use Matrix_base instead of Matrix? +// Dim_ real dimension +// Max_dim_ upper bound on the dimension +template struct LA_eigen { + typedef NT_ NT; + typedef Dim_ Dimension; + typedef Max_dim_ Max_dimension; + enum { dimension = Eigen_dimension::value }; + enum { max_dimension = Eigen_dimension::value }; + template< class D2, class D3=D2 > + struct Rebind_dimension { + typedef LA_eigen< NT, D2, D3 > Other; + }; + template struct Property : boost::false_type {}; + template struct Property : boost::true_type {}; + template struct Property : boost::true_type {}; + template struct Property : boost::true_type {}; + + typedef Eigen::Matrix::value,1,Eigen::ColMajor|Eigen::AutoAlign,Eigen_dimension::value,1> Vector; + typedef Eigen::Matrix Dynamic_vector; + typedef Construct_eigen Construct_vector; + +#if (EIGEN_WORLD_VERSION>=3) + typedef NT const* Vector_const_iterator; +#else + typedef Iterator_from_indices Vector_const_iterator; +#endif + + templatestatic Vector_const_iterator vector_begin(Vec_ const&a){ +#if (EIGEN_WORLD_VERSION>=3) + return &a[0]; +#else + return Vector_const_iterator(a,0); +#endif + } + + templatestatic Vector_const_iterator vector_end(Vec_ const&a){ +#if (EIGEN_WORLD_VERSION>=3) + // FIXME: Isn't that dangerous if a is an expression and not a concrete vector? + return &a[0]+a.size(); +#else + return Vector_const_iterator(a,a.size()); +#endif + } + + typedef Eigen::Matrix Square_matrix; + typedef Eigen::Matrix Dynamic_matrix; + //TODO: don't pass on the values of Max_* for an expensive NT + // typedef ... Constructor + // typedef ... Accessor +#if 0 + private: + template class Canonicalize_vector { + typedef typename Dimension_eigen::type S1; + typedef typename Dimension_eigen::type S2; + public: + typedef typename Vector::type type; + }; + public: +#endif + + templatestatic int size_of_vector(Vec_ const&v){ + return (int)v.size(); + } + + templatestatic NT dot_product(Vec_ const&a,Vec_ const&b){ + return a.dot(b); + } + + template static int rows(Vec_ const&v) { + return (int)v.rows(); + } + template static int columns(Vec_ const&v) { + return (int)v.cols(); + } + + template static NT determinant(Mat_ const&m,bool=false){ + return m.determinant(); + } + + template static typename + Same_uncertainty_nt::type + sign_of_determinant(Mat_ const&m,bool=false) + { + return CGAL::sign(m.determinant()); + } + + template static int rank(Mat_ const&m){ + // return m.rank(); + // This one uses sqrt so cannot be used with Gmpq + // TODO: use different algo for different NT? + // Eigen::ColPivHouseholderQR decomp(m); + Eigen::FullPivLU decomp(m); + // decomp.setThreshold(0); + return static_cast(decomp.rank()); + } + + // m*a==b + template + static bool solve(DV&a, DM const&m, V const& b){ + //a = m.colPivHouseholderQr().solve(b); + a = m.fullPivLu().solve(b); + return b.isApprox(m*a); + } + + static Dynamic_matrix basis(Dynamic_matrix const&m){ + return m.fullPivLu().image(m); + } + + template static Vector homogeneous_add(Vec1 const&a,Vec2 const&b){ + //TODO: use compile-time size when available + int d=a.size(); + Vector v(d); + v << b[d-1]*a.topRows(d-1)+a[d-1]*b.topRows(d-1), a[d-1]*b[d-1]; + return v; + } + + template static Vector homogeneous_sub(Vec1 const&a,Vec2 const&b){ + int d=a.size(); + Vector v(d); + v << b[d-1]*a.topRows(d-1)-a[d-1]*b.topRows(d-1), a[d-1]*b[d-1]; + return v; + } + + template static std::pair homogeneous_dot_product(Vec1 const&a,Vec2 const&b){ + int d=a.size(); + return make_pair(a.topRows(d-1).dot(b.topRows(d-1)), a[d-1]*b[d-1]); + } + +}; +} +#endif diff -Nru cgal-4.4/include/CGAL/NewKernel_d/Lazy_cartesian.h cgal-4.5/include/CGAL/NewKernel_d/Lazy_cartesian.h --- cgal-4.4/include/CGAL/NewKernel_d/Lazy_cartesian.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/Lazy_cartesian.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,188 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_KERNEL_D_LAZY_CARTESIAN_H +#define CGAL_KERNEL_D_LAZY_CARTESIAN_H + +#include +#include +#include +#include +#include +#include +#include + +namespace CGAL { + +template +struct Nth_iterator_element : private Store_kernel { + Nth_iterator_element(){} + Nth_iterator_element(K const&k):Store_kernel(k){} + typedef typename Get_type::value_tag>::type result_type; + template result_type operator()(CGAL_FORWARDABLE(U) u, int i) const { + typename Get_functor >::type ci(this->kernel()); + return *cpp0x::next(ci(CGAL_FORWARD(U,u),Begin_tag()),i); + } +}; + //typedef typename Functor::nth_element>::type nth_elem; +template::has_nth_element> +struct Select_nth_element_functor { + typedef Nth_iterator_element type; +}; +template +struct Select_nth_element_functor : + Get_functor::nth_element> {}; + +namespace internal { + template + struct Lazy_construction_maybe_nt { + typedef Lazy_construction type; + }; + template + struct Lazy_construction_maybe_nt { + typedef Lazy_construction_nt type; + }; +} + +template +struct Lazy_cartesian_types +{ + typedef typename typeset_intersection< + typename AK_::Object_list, + typename EK_::Object_list + >::type Object_list; + + typedef typename typeset_intersection< + typename AK_::Iterator_list, + typename EK_::Iterator_list + >::type Iterator_list; + + template ::type> struct Type {}; + template struct Type { + typedef Lazy< + typename Get_type::type, + typename Get_type::type, + typename Get_type::type, + E2A_> type; + }; + template struct Type { + typedef CGAL::Lazy_exact_nt::type> type; + }; + + template struct Iterator { + typedef typename iterator_tag_traits::value_tag Vt; + typedef typename Type::type V; + typedef typename Select_nth_element_functor::type AF; + typedef typename Select_nth_element_functor::type EF; + + typedef typename internal::Lazy_construction_maybe_nt< + Kernel_, AF, EF, is_NT_tag::value + >::type nth_elem; + + typedef Iterator_from_indices< + const typename Type::container>::type, + const V, V, nth_elem + > type; + }; +}; + +template +struct Lazy_cartesian : Dimension_base, + Lazy_cartesian_types > +{ + //CGAL_CONSTEXPR Lazy_cartesian(){} + //CGAL_CONSTEXPR Lazy_cartesian(int d):Base_(d){} + + //TODO: Do we want to store an AK and an EK? Or just references? + //FIXME: references would be better I guess. + //TODO: In any case, make sure that we don't end up storing this kernel for + //nothing (it is not empty but references empty kernels or something) + AK_ ak; EK_ ek; + AK_ const& approximate_kernel()const{return ak;} + EK_ const& exact_kernel()const{return ek;} + + typedef Lazy_cartesian Self; + typedef Lazy_cartesian_types Base; + //typedef typename Default::Get::type Kernel; + typedef Self Kernel; + typedef AK_ Approximate_kernel; + typedef EK_ Exact_kernel; + typedef E2A_ E2A; + typedef Approx_converter C2A; + typedef Exact_converter C2E; + + typedef typename Exact_kernel::Rep_tag Rep_tag; + typedef typename Exact_kernel::Kernel_tag Kernel_tag; + typedef typename Exact_kernel::Default_ambient_dimension Default_ambient_dimension; + typedef typename Exact_kernel::Max_ambient_dimension Max_ambient_dimension; + //typedef typename Exact_kernel::Flat_orientation Flat_orientation; + // Check that Approximate_kernel agrees with all that... + + template::type> struct Functor { + typedef Null_functor type; + }; + //FIXME: what do we do with D here? + template struct Functor { + typedef typename Get_functor::type FA; + typedef typename Get_functor::type FE; + typedef Filtered_predicate2 type; + }; + template struct Functor { + typedef typename Get_functor::type FA; + typedef typename Get_functor::type FE; + typedef Lazy_construction_nt type; + }; + template struct Functor { + typedef typename Get_functor::type FA; + typedef typename Get_functor::type FE; + typedef Lazy_construction type; + }; + + //typedef typename Iterator::type Point_cartesian_const_iterator; + //typedef typename Iterator::type Vector_cartesian_const_iterator; + + template + struct Construct_iter : private Store_kernel { + Construct_iter(){} + Construct_iter(Kernel const&k):Store_kernel(k){} + //FIXME: pass the kernel to the functor in the iterator + typedef U result_type; + template + result_type operator()(T const& t,Begin_tag)const{ + return result_type(t,0,this->kernel()); + } + template + result_type operator()(T const& t,End_tag)const{ + return result_type(t,Self().dimension(),this->kernel()); + } + }; + template struct Functor { + typedef Construct_iter::type>::type> type; + }; + + + //TODO: what about other functors of the Misc category? + // for Point_dimension, we should apply it to the approximate point + // for printing, we should??? just not do printing this way? +}; + + +} //namespace CGAL + +#endif // CGAL_KERNEL_D_LAZY_CARTESIAN_H diff -Nru cgal-4.4/include/CGAL/NewKernel_d/static_int.h cgal-4.5/include/CGAL/NewKernel_d/static_int.h --- cgal-4.4/include/CGAL/NewKernel_d/static_int.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/static_int.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,61 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_STATIC_INT_H +#define CGAL_STATIC_INT_H +#include + +namespace CGAL { +template struct static_zero { + operator NT() const { return constant(); } +}; +template struct static_one { + operator NT() const { return constant(); } +}; + +template static_zero operator-(static_zero) { return static_zero(); } + +template NT operator+(NT const& x, static_zero) { return x; } +template NT operator+(static_zero, NT const& x) { return x; } +template static_zero operator+(static_zero, static_zero) { return static_zero(); } +template static_one operator+(static_zero, static_one) { return static_one(); } +template static_one operator+(static_one, static_zero) { return static_one(); } + +template NT operator-(NT const& x, static_zero) { return x; } +template NT operator-(static_zero, NT const& x) { return -x; } +template static_zero operator-(static_zero, static_zero) { return static_zero(); } +template static_zero operator-(static_one, static_one) { return static_zero(); } +template static_one operator-(static_one, static_zero) { return static_one(); } + +template NT operator*(NT const& x, static_one) { return x; } +template NT operator*(static_one, NT const& x) { return x; } +template static_zero operator*(NT const&, static_zero) { return static_zero(); } +template static_zero operator*(static_zero, NT const&) { return static_zero(); } +template static_zero operator*(static_zero, static_zero) { return static_zero(); } +template static_one operator*(static_one, static_one) { return static_one(); } +template static_zero operator*(static_zero, static_one) { return static_zero(); } +template static_zero operator*(static_one, static_zero) { return static_zero(); } + +template NT operator/(NT const& x, static_one) { return x; } +template static_zero operator/(static_zero, NT const&) { return static_zero(); } +template static_zero operator/(static_zero, static_one) { return static_zero(); } +template static_one operator/(static_one, static_one) { return static_one(); } + +} +#endif // CGAL_STATIC_INT_H diff -Nru cgal-4.4/include/CGAL/NewKernel_d/store_kernel.h cgal-4.5/include/CGAL/NewKernel_d/store_kernel.h --- cgal-4.4/include/CGAL/NewKernel_d/store_kernel.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/store_kernel.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,104 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_STORE_KERNEL_H +#define CGAL_STORE_KERNEL_H + +#include +#include + +namespace CGAL { +namespace internal { +BOOST_MPL_HAS_XXX_TRAIT_DEF(Do_not_store_kernel) +template::value,bool=has_Do_not_store_kernel::value> struct Do_not_store_kernel { + enum { value=false }; + typedef Tag_false type; +}; +template struct Do_not_store_kernel { + enum { value=true }; + typedef Tag_true type; +}; +template struct Do_not_store_kernel { + typedef typename T::Do_not_store_kernel type; + enum { value=type::value }; +}; +} + +template::value> +struct Store_kernel { + Store_kernel(){} + Store_kernel(R_ const&){} + enum { kernel_is_stored = false }; + R_ kernel()const{return R_();} + typedef R_ reference_type; + void set_kernel(R_ const&){} +}; +template +struct Store_kernel { + Store_kernel():rp(0){ + CGAL_warning_msg(true,"I should know my kernel"); + } + Store_kernel(R_ const& r):rp(&r){} + enum { kernel_is_stored = true }; + R_ const& kernel()const{ + CGAL_warning_msg(rp!=0,"I should know my kernel"); + return *rp; + } + typedef R_ const& reference_type; + void set_kernel(R_ const&r){rp=&r;} + private: + R_ const* rp; +}; + +//For a second kernel. TODO: find something more elegant +template::value> +struct Store_kernel2 { + Store_kernel2(){} + Store_kernel2(R_ const&){} + enum { kernel2_is_stored = false }; + R_ kernel2()const{return R_();} + typedef R_ reference2_type; + void set_kernel2(R_ const&){} +}; +template +struct Store_kernel2 { + Store_kernel2(){ + //CGAL_warning_msg(true,"I should know my kernel"); + } + Store_kernel2(R_ const& r):rp(&r){} + enum { kernel2_is_stored = true }; + R_ const& kernel2()const{ + CGAL_warning_msg(rp==0,"I should know my kernel"); + return *rp; + } + typedef R_ const& reference2_type; + void set_kernel2(R_ const&r){rp=&r;} + private: + R_ const* rp; +}; +} +#define CGAL_BASE_INIT(X,Y) \ + X():Y(){} \ + X(R_ const&r):Y(r){} +#define CGAL_FUNCTOR_INIT_STORE(X) CGAL_BASE_INIT(X,Store_kernel) +#define CGAL_FUNCTOR_INIT_IGNORE(X) \ + X(){} \ + X(R_ const&){} + +#endif // CGAL_STORE_KERNEL_H diff -Nru cgal-4.4/include/CGAL/NewKernel_d/Types/Aff_transformation.h cgal-4.5/include/CGAL/NewKernel_d/Types/Aff_transformation.h --- cgal-4.4/include/CGAL/NewKernel_d/Types/Aff_transformation.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/Types/Aff_transformation.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,59 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_KD_TYPE_AFF_TRANSFORMATION_H +#define CGAL_KD_TYPE_AFF_TRANSFORMATION_H +#include +#include +#include + +// Dummy, that's all the Kernel_d concept requires, so a useful class will wait. + +namespace CGAL { +template +struct Aff_transformation { + typedef R_ R; +}; +namespace CartesianDKernelFunctors { +template struct Construct_aff_transformation { + CGAL_FUNCTOR_INIT_IGNORE(Construct_aff_transformation) + typedef R_ R; + typedef typename Get_type::type result_type; +#ifdef CGAL_CXX11 + template + result_type operator()(T&&...)const{return result_type();} +#else + result_type operator()()const{ + return result_type(); + } +#define CGAL_CODE(Z,N,_) template \ + result_type operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,U,const& BOOST_PP_INTERCEPT))const{ \ + return result_type(); \ + } + BOOST_PP_REPEAT_FROM_TO(1, 9, CGAL_CODE, _ ) +#undef CGAL_CODE + +#endif +}; +} +CGAL_KD_DEFAULT_TYPE(Aff_transformation_tag,(CGAL::Aff_transformation),(),()); +CGAL_KD_DEFAULT_FUNCTOR(Construct_ttag,(CartesianDKernelFunctors::Construct_aff_transformation),(Aff_transformation_tag),()); + +} +#endif diff -Nru cgal-4.4/include/CGAL/NewKernel_d/Types/Hyperplane.h cgal-4.5/include/CGAL/NewKernel_d/Types/Hyperplane.h --- cgal-4.4/include/CGAL/NewKernel_d/Types/Hyperplane.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/Types/Hyperplane.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,154 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_KD_TYPE_HYPERPLANE_H +#define CGAL_KD_TYPE_HYPERPLANE_H +#include +#include +#include +#include +#include +namespace CGAL { +template class Hyperplane { + typedef typename Get_type::type FT_; + typedef typename Get_type::type Vector_; + Vector_ v_; + FT_ s_; + + public: + Hyperplane(Vector_ const&v, FT_ const&s): v_(v), s_(s) {} + // TODO: Add a piecewise constructor? + + Vector_ const& orthogonal_vector()const{return v_;} + FT_ translation()const{return s_;} +}; +namespace CartesianDKernelFunctors { +template struct Construct_hyperplane : Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Construct_hyperplane) + typedef typename Get_type::type result_type; + typedef typename Get_type::type Point; + typedef typename Get_type::type Vector; + typedef typename Get_type::type FT; + typedef typename R_::LA::Square_matrix Matrix; + private: + struct One { + typedef int result_type; + templateint const& operator()(T const&)const{ + static const int one = 1; + return one; + } + }; + public: + + result_type operator()(Vector const&a, FT const&b)const{ + return result_type(a,b); + } + // Not really needed + result_type operator()()const{ + typename Get_functor >::type cv(this->kernel()); + return result_type(cv(),0); + } + + template + result_type operator()(Iter f, Iter e)const{ + typedef typename R_::LA LA; + typedef typename LA::Vector Vec; + typedef typename LA::Construct_vector CVec; + typename Get_functor::type c(this->kernel()); + typename Get_functor >::type cv(this->kernel()); + typename Get_functor::type pd(this->kernel()); + + Point const& p0=*f; + int d = pd(p0); + Matrix m(d,d); + for(int j=0;j(0),One()), + boost::make_transform_iterator(boost::counting_iterator(d),One())); + Vec res = typename CVec::Dimension()(d); + LA::solve(res, CGAL_MOVE(m), CGAL_MOVE(one)); + return this->operator()(cv(d,LA::vector_begin(res),LA::vector_end(res)),1); + } + template + result_type operator()(Iter f, Iter e, Point const&p, CGAL::Oriented_side s)const{ + result_type ret = this->operator()(f, e); + if (s == ON_ORIENTED_BOUNDARY) + return ret; + // TODO: I doubt this does the right thing wrt filtering... + typename Get_functor::type va(this->kernel()); + CGAL::Oriented_side o = CGAL::compare(va(ret,p),ret.translation()); + if (o == ON_ORIENTED_BOUNDARY || o == s) + return ret; + typename Get_functor::type ov(this->kernel()); + typename Get_functor >::type cv(this->kernel()); + return this->operator()(ov(ret.orthogonal_vector()), -ret.translation()); + } +}; +template struct Orthogonal_vector { + CGAL_FUNCTOR_INIT_IGNORE(Orthogonal_vector) + typedef typename Get_type::type Hyperplane; + typedef typename Get_type::type const& result_type; + result_type operator()(Hyperplane const&s)const{ + return s.orthogonal_vector(); + } +}; +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? + result_type operator()(Hyperplane const&s)const{ + return s.translation(); + } +}; +template struct Value_at : Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Value_at) + typedef typename Get_type::type Hyperplane; + typedef typename Get_type::type Vector; + typedef typename Get_type::type Point; + typedef typename Get_type::type FT; + typedef FT result_type; + typedef typename Get_functor::type Dot; + typedef typename Get_functor::type P2V; + result_type operator()(Hyperplane const&h, Point const&p)const{ + Dot dot(this->kernel()); + P2V p2v(this->kernel()); + return dot(h.orthogonal_vector(),p2v(p)); + // Use Orthogonal_vector to make it generic? + // Copy the code from Scalar_product to avoid p2v? + } +}; +} +//TODO: Add a condition that the hyperplane type is the one from this file. +CGAL_KD_DEFAULT_TYPE(Hyperplane_tag,(CGAL::Hyperplane),(Vector_tag),()); +CGAL_KD_DEFAULT_FUNCTOR(Construct_ttag,(CartesianDKernelFunctors::Construct_hyperplane),(Vector_tag,Hyperplane_tag),(Value_at_tag)); +CGAL_KD_DEFAULT_FUNCTOR(Orthogonal_vector_tag,(CartesianDKernelFunctors::Orthogonal_vector),(Vector_tag,Hyperplane_tag),()); +CGAL_KD_DEFAULT_FUNCTOR(Hyperplane_translation_tag,(CartesianDKernelFunctors::Hyperplane_translation),(Hyperplane_tag),()); +CGAL_KD_DEFAULT_FUNCTOR(Value_at_tag,(CartesianDKernelFunctors::Value_at),(Point_tag,Vector_tag,Hyperplane_tag),(Scalar_product_tag,Point_to_vector_tag)); +} // namespace CGAL +#endif diff -Nru cgal-4.4/include/CGAL/NewKernel_d/Types/Iso_box.h cgal-4.5/include/CGAL/NewKernel_d/Types/Iso_box.h --- cgal-4.4/include/CGAL/NewKernel_d/Types/Iso_box.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/Types/Iso_box.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,68 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_KERNELD_TYPES_ISO_BOX_H +#define CGAL_KERNELD_TYPES_ISO_BOX_H +#include +#include +#include +#include +#include +namespace CGAL { +template class Iso_box { + typedef typename Get_type::type FT_; + typedef typename Get_type::type Point_; + typedef std::pair Data_; + Data_ data; + public: + Iso_box(){} + Iso_box(Point_ const&a, Point_ const&b): data(a,b) {} + Point_ min BOOST_PREVENT_MACRO_SUBSTITUTION ()const{ + return data.first; + } + Point_ max BOOST_PREVENT_MACRO_SUBSTITUTION ()const{ + return data.second; + } +}; +namespace CartesianDKernelFunctors { + template struct Construct_iso_box : Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Construct_iso_box) + typedef typename Get_type::type result_type; + typedef typename Get_type::type RT; + typedef typename Get_type::type Point; + typedef typename Get_functor >::type Cp_; + typedef typename Get_functor >::type Ci_; + result_type operator()(Point const&a, Point const&b)const{ + Cp_ cp(this->kernel()); + Ci_ ci(this->kernel()); + return result_type(cp( + make_transforming_pair_iterator(ci(a,Begin_tag()), ci(b,Begin_tag()), Min()), + make_transforming_pair_iterator(ci(a,End_tag()), ci(b,End_tag()), Min())), + cp( + make_transforming_pair_iterator(ci(a,Begin_tag()), ci(b,Begin_tag()), Max()), + make_transforming_pair_iterator(ci(a,End_tag()), ci(b,End_tag()), Max()))); + } + }; +} +CGAL_KD_DEFAULT_TYPE(Iso_box_tag,(CGAL::Iso_box),(Point_tag),()); +CGAL_KD_DEFAULT_FUNCTOR(Construct_ttag,(CartesianDKernelFunctors::Construct_iso_box),(Iso_box_tag,Point_tag),(Construct_ttag,Construct_ttag)); + +} // namespace CGAL + +#endif // CGAL_KERNELD_TYPES_ISO_BOX_H diff -Nru cgal-4.4/include/CGAL/NewKernel_d/Types/Line.h cgal-4.5/include/CGAL/NewKernel_d/Types/Line.h --- cgal-4.4/include/CGAL/NewKernel_d/Types/Line.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/Types/Line.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,66 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_KERNELD_TYPES_LINE_H +#define CGAL_KERNELD_TYPES_LINE_H +#include +#include +#include +namespace CGAL { +template class Line { + typedef typename Get_type::type FT_; + typedef typename Get_type::type Point_; + typedef std::pair Data_; + Data_ data; + public: + Line(){} + Line(Point_ const&a, Point_ const&b): data(a,b) {} + Point_ point(int i)const{ + if(i==0) return data.first; + if(i==1) return data.second; + throw "not implemented"; + } + Line opposite()const{ + return Line(data.second,data.first); + } +}; +namespace CartesianDKernelFunctors { + template struct Construct_line : Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Construct_line) + typedef typename Get_type::type result_type; + typedef typename Get_type::type Point; + typedef typename Get_type::type Vector; + typedef typename Get_functor::type Tp_; + //typedef typename Get_functor::type Dp_; + //typedef typename Get_functor::type Sv_; + result_type operator()(Point const&a, Point const&b)const{ + return result_type(a,b); + } + result_type operator()(Point const&a, typename First_if_different::Type const&b)const{ + Tp_ tp(this->kernel()); + return result_type(a,tp(a,b)); + } + }; +} +CGAL_KD_DEFAULT_TYPE(Line_tag,(CGAL::Line),(Point_tag),()); +CGAL_KD_DEFAULT_FUNCTOR(Construct_ttag,(CartesianDKernelFunctors::Construct_line),(Line_tag,Point_tag,Vector_tag),(Translated_point_tag)); + +} // namespace CGAL + +#endif // CGAL_KERNELD_TYPES_LINE_H diff -Nru cgal-4.4/include/CGAL/NewKernel_d/Types/Ray.h cgal-4.5/include/CGAL/NewKernel_d/Types/Ray.h --- cgal-4.4/include/CGAL/NewKernel_d/Types/Ray.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/Types/Ray.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,66 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_KERNELD_TYPES_RAY_H +#define CGAL_KERNELD_TYPES_RAY_H +#include +#include +#include +namespace CGAL { +template class Ray { + typedef typename Get_type::type FT_; + typedef typename Get_type::type Point_; + typedef typename Get_type::type Vector_; + typedef std::pair Data_; + Data_ data; + public: + Ray(){} + Ray(Point_ const&a, Vector_ const&b): data(a,b) {} + Point_ source()const{ + return data.first; + } + // FIXME: return a R_::Direction? + Vector_ direction()const{ + return data.second; + } +}; +namespace CartesianDKernelFunctors { + template struct Construct_ray : Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Construct_ray) + typedef typename Get_type::type result_type; + typedef typename Get_type::type Point; + typedef typename Get_type::type Vector; + typedef typename Get_functor::type Dp_; + //typedef typename Get_functor::type Tp_; + //typedef typename Get_functor::type Sv_; + result_type operator()(Point const&a, Vector const&b)const{ + return result_type(a,b); + } + result_type operator()(Point const&a, typename First_if_different::Type const&b)const{ + Dp_ dp(this->kernel()); + return result_type(a,dp(b,a)); + } + }; +} +CGAL_KD_DEFAULT_TYPE(Ray_tag,(CGAL::Ray),(Point_tag,Vector_tag),()); +CGAL_KD_DEFAULT_FUNCTOR(Construct_ttag,(CartesianDKernelFunctors::Construct_ray),(Point_tag,Ray_tag,Vector_tag),(Difference_of_points_tag)); + +} // namespace CGAL + +#endif // CGAL_KERNELD_TYPES_RAY_H diff -Nru cgal-4.4/include/CGAL/NewKernel_d/Types/Segment.h cgal-4.5/include/CGAL/NewKernel_d/Types/Segment.h --- cgal-4.4/include/CGAL/NewKernel_d/Types/Segment.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/Types/Segment.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,121 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_KERNELD_SEGMENTD_H +#define CGAL_KERNELD_SEGMENTD_H +#include +#include +#include +namespace CGAL { +template class Segment { + typedef typename Get_type::type FT_; + typedef typename Get_type::type Point_; + //typedef typename R_::Vector Vector_; + //typedef typename Get_functor >::type Cv_; +// typedef typename R_::Squared_distance Csd_; + typedef std::pair Data_; + Data_ data; + public: + //typedef Segmentd Segment; +#ifdef CGAL_CXX11 + //FIXME: don't forward directly, piecewise_constuct should call the point construction functor (I guess? or is it unnecessary?) + template::type...>,std::tuple>::value>::type> + Segment(U&&...u):data(std::forward(u)...){} +#else + Segment(){} + Segment(Point_ const&a, Point_ const&b): data(a,b) {} + //template + //Segment(A const&,T1 const&t1,T2 const&t2) +#endif + Point_ source()const{return data.first;} + Point_ target()const{return data.second;} + Point_ operator[](int i)const{ + if((i%2)==0) + return source(); + else + return target(); + } + Segment opposite()const{ + return Segment(target(),source()); + } + //Vector_ vector()const{ + // return Cv_()(data.first,data.second); + //} +// FT_ squared_length()const{ +// return Csd_()(data.first,data.second); +// } +}; + +namespace CartesianDKernelFunctors { + +template struct Construct_segment : Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Construct_segment) + typedef R_ R; + typedef typename Get_type::type Point; + typedef typename Get_type::type Segment; + typedef typename Get_functor >::type CP; + typedef Segment result_type; + result_type operator()(Point const&a, Point const&b)const{ + return result_type(a,b); + } + // Not really needed, especially since it forces us to store the kernel + result_type operator()()const{ + Point p = typename Get_functor >::type (this->kernel()) (); + return result_type (p, p); + } + // T should only be std::piecewise_construct_t, but we shouldn't fail if it doesn't exist. + template + result_type operator()(CGAL_FORWARDABLE(T),CGAL_FORWARDABLE(U) u,CGAL_FORWARDABLE(V) v)const{ + CP cp(this->kernel()); + result_type r = {{ + call_on_tuple_elements(cp, CGAL_FORWARD(U,u)), + call_on_tuple_elements(cp, CGAL_FORWARD(V,v)) }}; + return r; + } +}; + +// This should be part of Construct_point, according to Kernel_23 conventions +template struct Segment_extremity { + CGAL_FUNCTOR_INIT_IGNORE(Segment_extremity) + typedef R_ R; + typedef typename Get_type::type Point; + typedef typename Get_type::type Segment; + typedef Point result_type; + result_type operator()(Segment const&s, int i)const{ + if(i==0) return s.source(); + CGAL_assertion(i==1); + return s.target(); + } +#ifdef CGAL_CXX11 + result_type operator()(Segment &&s, int i)const{ + if(i==0) return std::move(s.source()); + CGAL_assertion(i==1); + return std::move(s.target()); + } +#endif +}; +} // CartesianDKernelFunctors + +CGAL_KD_DEFAULT_TYPE(Segment_tag,(CGAL::Segment),(Point_tag),()); +CGAL_KD_DEFAULT_FUNCTOR(Construct_ttag,(CartesianDKernelFunctors::Construct_segment),(Segment_tag,Point_tag),(Construct_ttag)); +CGAL_KD_DEFAULT_FUNCTOR(Segment_extremity_tag,(CartesianDKernelFunctors::Segment_extremity),(Segment_tag,Point_tag),()); + +} // namespace CGAL + +#endif // CGAL_KERNELD_SEGMENTD_H diff -Nru cgal-4.4/include/CGAL/NewKernel_d/Types/Sphere.h cgal-4.5/include/CGAL/NewKernel_d/Types/Sphere.h --- cgal-4.4/include/CGAL/NewKernel_d/Types/Sphere.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/Types/Sphere.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,159 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_KD_TYPE_SPHERE_H +#define CGAL_KD_TYPE_SPHERE_H +#include +#include +namespace CGAL { +template class Sphere { + typedef typename Get_type::type FT_; + typedef typename Get_type::type Point_; + Point_ c_; + FT_ r2_; + + public: + Sphere(Point_ const&p, FT_ const&r2): c_(p), r2_(r2) {} + // TODO: Add a piecewise constructor? + + Point_ const& center()const{return c_;} + FT_ const& squared_radius()const{return r2_;} +}; + +namespace CartesianDKernelFunctors { +template struct Construct_sphere : Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Construct_sphere) + typedef typename Get_type::type result_type; + typedef typename Get_type::type Point; + typedef typename Get_type::type FT; + result_type operator()(Point const&a, FT const&b)const{ + return result_type(a,b); + } + // Not really needed + result_type operator()()const{ + typename Get_functor >::type cp(this->kernel()); + return result_type(cp(),0); + } + template + result_type operator()(Iter f, Iter e)const{ + // 2*(x-y).c == x^2-y^2 + typedef typename R_::LA LA; + typedef typename LA::Square_matrix Matrix; + typedef typename LA::Vector Vec; + typedef typename LA::Construct_vector CVec; + typedef typename Get_type::type Point; + typename Get_functor::type c(this->kernel()); + typename Get_functor >::type cp(this->kernel()); + typename Get_functor::type pd(this->kernel()); + typename Get_functor::type sdo(this->kernel()); + typename Get_functor::type sd(this->kernel()); + + Point const& p0=*f; + int d = pd(p0); + FT const& n0 = sdo(p0); + Matrix m(d,d); + Vec b = typename CVec::Dimension()(d); + // Write the point coordinates in lines. + int i; + for(i=0; ++f!=e; ++i) { + Point const& p=*f; + for(int j=0;joperator()(CGAL_MOVE(center), r2); + } +}; + +template struct Center_of_sphere : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Center_of_sphere) + typedef typename Get_type::type Sphere; + // No reference because of the second overload + typedef typename Get_type::type result_type; + + result_type const& operator()(Sphere const&s)const{ + return s.center(); + } + + template + result_type operator()(Iter b, Iter e)const{ + typename Get_functor >::type cs(this->kernel()); + return operator()(cs(b,e)); // computes the radius needlessly + } +}; + +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? + result_type operator()(Sphere const&s)const{ + return s.squared_radius(); + } +}; + +// FIXME: Move it to the generic functors, using the two above and conditional to the existence of sqrt(FT) +template struct Point_of_sphere : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Point_of_sphere) + typedef R_ R; + typedef typename Get_type::type FT; + typedef typename Get_type::type RT; + typedef typename Get_type::type Point; + typedef typename Get_type::type Sphere; + typedef typename Get_functor >::type CP; + typedef typename Get_functor >::type CI; + typedef typename Get_functor::type PD; + typedef Point result_type; + typedef Sphere first_argument_type; + typedef int second_argument_type; + struct Trans : std::binary_function { + FT const& r_; int idx; bool sgn; + Trans (int n, FT const& r, bool b) : r_(r), idx(n), sgn(b) {} + FT operator()(FT const&x, int i)const{ + return (i == idx) ? sgn ? x + r_ : x - r_ : x; + } + }; + result_type operator()(Sphere const&s, int i)const{ + CI ci(this->kernel()); + PD pd(this->kernel()); + typedef boost::counting_iterator Count; + Point const&c = s.center(); + int d=pd(c); + bool last = (i == d); + FT r = sqrt(s.squared_radius()); + Trans t(last ? 0 : i, r, !last); + return CP(this->kernel())(make_transforming_pair_iterator(ci(c,Begin_tag()),Count(0),t),make_transforming_pair_iterator(ci(c,End_tag()),Count(d),t)); + } +}; +} +CGAL_KD_DEFAULT_TYPE(Sphere_tag,(CGAL::Sphere),(Point_tag),()); +CGAL_KD_DEFAULT_FUNCTOR(Construct_ttag,(CartesianDKernelFunctors::Construct_sphere),(Sphere_tag,Point_tag),(Construct_ttag,Compute_point_cartesian_coordinate_tag,Squared_distance_tag,Squared_distance_to_origin_tag,Point_dimension_tag)); +CGAL_KD_DEFAULT_FUNCTOR(Center_of_sphere_tag,(CartesianDKernelFunctors::Center_of_sphere),(Sphere_tag,Point_tag),(Construct_ttag)); +CGAL_KD_DEFAULT_FUNCTOR(Squared_radius_tag,(CartesianDKernelFunctors::Squared_radius),(Sphere_tag),()); +CGAL_KD_DEFAULT_FUNCTOR(Point_of_sphere_tag,(CartesianDKernelFunctors::Point_of_sphere),(Sphere_tag,Point_tag),(Construct_ttag, Construct_ttag)); +} // namespace CGAL +#endif diff -Nru cgal-4.4/include/CGAL/NewKernel_d/utils.h cgal-4.5/include/CGAL/NewKernel_d/utils.h --- cgal-4.4/include/CGAL/NewKernel_d/utils.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/utils.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,290 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_MARCUTILS +#define CGAL_MARCUTILS + +#include +#ifdef CGAL_CXX11 +#include +#include +#define CGAL_FORWARDABLE(T) T&& +#define CGAL_FORWARD(T,t) std::forward(t) +#define CGAL_MOVE(t) std::move(t) +#define CGAL_CONSTEXPR constexpr +#else +#define CGAL_FORWARDABLE(T) T const& +#define CGAL_FORWARD(T,t) t +#define CGAL_MOVE(t) t +#define CGAL_CONSTEXPR +#endif +#include +#include +#include +#include +#include +#include +#include + +#ifdef CGAL_CXX11 +#define CGAL_BOOSTD std:: +#else +#define CGAL_BOOSTD boost:: +#endif + +namespace CGAL { +namespace internal { + BOOST_MPL_HAS_XXX_TRAIT_DEF(type) +} + +template ::value /*false*/> +struct Has_type_different_from : boost::false_type {}; +template +struct Has_type_different_from +: boost::mpl::not_ > {}; + + + template struct Wrap_type { typedef T type; }; + + // tell a function f(a,b,c) that its real argument is a(b,c) + struct Eval_functor {}; + + // forget the first argument. Useful to make something dependant + // (and thus usable in SFINAE), although that's not a great design. + template struct Second_arg { + typedef B type; + }; + + // like std::forward, except for basic types where it does a cast, to + // avoid issues with narrowing conversions +#ifdef CGAL_CXX11 + template inline + typename std::conditional::value&&std::is_arithmetic::type>::value,T,U&&>::type + forward_safe(V&& u) { return std::forward(u); } +#else + template inline U const& forward_safe(U const& u) { + return u; + } +#endif + +#ifdef CGAL_CXX11 + template struct Constructible_from_each; + template struct Constructible_from_each{ + enum { value=std::is_convertible::value&&Constructible_from_each::value }; + }; + template struct Constructible_from_each{ + enum { value=true }; + }; +#else +// currently only used in C++0X code +#endif + + template struct Scale { + T const& scale; + Scale(T const& t):scale(t){} + template +#ifdef CGAL_CXX11 + auto operator()(FT&& x)const->decltype(scale*std::forward(x)) +#else + FT operator()(FT const& x)const +#endif + { + return scale*CGAL_FORWARD(FT,x); + } + }; + template struct Divide { +#if !defined(CGAL_CXX11) || !defined(BOOST_RESULT_OF_USE_DECLTYPE) + // requires boost > 1.44 + // shouldn't be needed with C++0X + //template struct result; + //template struct result { + // typedef FT type; + //}; + typedef NT result_type; +#endif + T const& scale; + Divide(T const& t):scale(t){} + template +#ifdef CGAL_CXX11 + //FIXME: gcc complains for Gmpq + //auto operator()(FT&& x)const->decltype(Rational_traits().make_rational(std::forward(x),scale)) + NT operator()(FT&& x)const +#else + NT operator()(FT const& x)const +#endif + { + return Rational_traits(). + make_rational(CGAL_FORWARD(FT,x),scale); + } + }; + + template struct has_cheap_constructor : boost::is_arithmetic{}; + template struct has_cheap_constructor > { + enum { value=true }; + }; + + // like std::multiplies but allows mixing types + // in C++11 in doesn't need to be a template + template < class Ret > + struct multiplies { + template +#ifdef CGAL_CXX11 + auto operator()(A&&a,B&&b)const->decltype(std::forward(a)*std::forward(b)) +#else + Ret operator()(A const& a, B const& b)const +#endif + { + return CGAL_FORWARD(A,a)*CGAL_FORWARD(B,b); + } + }; + template < class Ret > + struct division { + template +#ifdef CGAL_CXX11 + auto operator()(A&&a,B&&b)const->decltype(std::forward(a)/std::forward(b)) +#else + Ret operator()(A const& a, B const& b)const +#endif + { + return CGAL_FORWARD(A,a)/CGAL_FORWARD(B,b); + } + }; + +#ifdef CGAL_CXX11 + using std::decay; +#else + template struct decay : boost::remove_cv::type> {}; +#endif + + template struct Type_copy_ref { typedef U type; }; + template struct Type_copy_ref { typedef U& type; }; +#ifdef CGAL_CXX11 + template struct Type_copy_ref { typedef U&& type; }; +#endif + template struct Type_copy_cv { typedef U type; }; + template struct Type_copy_cv { typedef U const type; }; + template struct Type_copy_cv { typedef U volatile type; }; + template struct Type_copy_cv { typedef U const volatile type; }; + + template struct Type_copy_cvref : + Type_copy_ref::type,U>::type> {}; + + struct Dereference_functor { + template struct result{}; + template struct result { + typedef typename std::iterator_traits::reference type; + }; + template typename result::type + operator()(It const&i)const{ + return *i; + } + }; + +#ifdef CGAL_CXX11 + template struct Indices{}; + template struct Next_increasing_indices; + template struct Next_increasing_indices > { + typedef Indices type; + }; + template struct N_increasing_indices { + typedef typename Next_increasing_indices::type>::type type; + }; + template<> struct N_increasing_indices<0> { typedef Indices<> type; }; + namespace internal { + template inline typename std::result_of::type + do_call_on_tuple_elements(F&&f, std::tuple&&t, Indices&&) { + return f(std::get(std::move(t))...); + } + } // internal + template + inline typename std::result_of::type + call_on_tuple_elements(F&&f, std::tuple&&t) { + return internal::do_call_on_tuple_elements(std::forward(f),std::move(t), + typename N_increasing_indices::type()); + } +#else +#define CGAL_VAR(Z,N,_) cpp0x::get(t) +#define CGAL_CODE(Z,N,_) template \ + inline Res call_on_tuple_elements(F const&f, \ + cpp0x::tuple const&t) { \ + return f(BOOST_PP_ENUM(N,CGAL_VAR,)); \ + } + template + inline Res call_on_tuple_elements(F const&f, cpp0x::tuple<>) { + return f(); + } +BOOST_PP_REPEAT_FROM_TO(1, 8, CGAL_CODE, _ ) +#undef CGAL_CODE +#undef CGAL_VAR +#endif + + template struct Factory { + typedef A result_type; +#ifdef CGAL_CXX11 + template result_type operator()(U&&...u)const{ + return A(std::forward(u)...); + } +#else + result_type operator()()const{ + return A(); + } +#define CGAL_CODE(Z,N,_) template \ + result_type operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,U,const&u))const{ \ + return A(BOOST_PP_ENUM_PARAMS(N,u)); \ + } +BOOST_PP_REPEAT_FROM_TO(1, 8, CGAL_CODE, _ ) +#undef CGAL_CODE +#endif + }; +} + +// TODO: make a Cartesian-only variant +// WARNING: do not use the Req* parameters too much, they can cause circular instanciations and are only useful for dispatching. +#define CGAL_STRIP_PAREN_(...) __VA_ARGS__ +#define CGAL_STRIP_PAREN(...) CGAL_STRIP_PAREN_ __VA_ARGS__ +// What to do with O? pass it down to other functors or drop it? +#define CGAL_KD_DEFAULT_FUNCTOR(Tg,Name,ReqTyp,ReqFun) \ + template \ + struct Get_functor::value \ + || !Provides_types >::value \ + || !Provides_functors >::value \ + , int, void>::type> \ + { \ + typedef CGAL_STRIP_PAREN_ Name type; \ + typedef K Bound_kernel; \ + } + +// Not used yet, may need some changes. +#define CGAL_KD_DEFAULT_TYPE(Tg,Name,ReqTyp,ReqFun) \ + template \ + struct Get_type::value \ + || !Provides_types >::value \ + || !Provides_functors >::value \ + , int, void>::type> \ + { \ + typedef CGAL_STRIP_PAREN_ Name type; \ + typedef K Bound_kernel; \ + } + + +#endif diff -Nru cgal-4.4/include/CGAL/NewKernel_d/Vector/array.h cgal-4.5/include/CGAL/NewKernel_d/Vector/array.h --- cgal-4.4/include/CGAL/NewKernel_d/Vector/array.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/Vector/array.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,165 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_VECTOR_ARRAY_H +#define CGAL_VECTOR_ARRAY_H +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + + + +namespace CGAL { + +// May not be safe to use with dim!=max_dim. +// In that case, we should store the real dim next to the array. +template struct Array_vector { + typedef NT_ NT; + typedef Dim_ Dimension; + typedef Max_dim_ Max_dimension; + template< class D2, class D3=D2 > + struct Rebind_dimension { + typedef Array_vector< NT, D2, D3 > Other; + }; + template struct Property : boost::false_type {}; + + static const unsigned d_=Max_dim_::value; + CGAL_static_assertion(d_ != (unsigned)UNKNOWN_DIMENSION); + + typedef cpp0x::array Vector; + struct Construct_vector { + struct Dimension { + // Initialize with NaN if possible? + Vector operator()(unsigned d) const { + CGAL_assertion(d<=d_); + return Vector(); + } + }; + + struct Iterator { + template + Vector operator()(unsigned CGAL_assertion_code(d),Iter const& f,Iter const& e) const { + CGAL_assertion(d==std::distance(f,e)); + CGAL_assertion(d<=d_); + //TODO: optimize for forward iterators + Vector a; + std::copy(f,e,a.begin()); + return a; + } + }; + +#if 0 + struct Iterator_add_one { + template + Vector operator()(unsigned d,Iter const& f,Iter const& e) const { + CGAL_assertion(d==std::distance(f,e)+1); + CGAL_assertion(d<=d_); + //TODO: optimize + Vector a; + std::copy(f,e,a.begin()); + a.back()=1; + return a; + } + }; +#endif + + struct Iterator_and_last { + template + Vector operator()(unsigned d,Iter const& f,Iter const& e,CGAL_FORWARDABLE(T) t) const { + CGAL_assertion(d==std::distance(f,e)+1); + CGAL_assertion(d<=d_); + //TODO: optimize for forward iterators + Vector a; + std::copy(f,e,a.begin()); + a.back()=CGAL_FORWARD(T,t); + return a; + } + }; + + struct Values { +#ifdef CGAL_CXX11 + template + Vector operator()(U&&...u) const { + static_assert(sizeof...(U)<=d_,"too many arguments"); + Vector a={{forward_safe(u)...}}; + return a; + } +#else + +#define CGAL_CODE(Z,N,_) Vector operator()(BOOST_PP_ENUM_PARAMS(N,NT const& t)) const { \ + CGAL_assertion(N<=d_); \ + Vector a={{BOOST_PP_ENUM_PARAMS(N,t)}}; \ + return a; \ +} +BOOST_PP_REPEAT_FROM_TO(1, 11, CGAL_CODE, _ ) +#undef CGAL_CODE + +#endif + }; + + struct Values_divide { +#ifdef CGAL_CXX11 + template + Vector operator()(H const& h,U&&...u) const { + static_assert(sizeof...(U)<=d_,"too many arguments"); + Vector a={{Rational_traits().make_rational(std::forward(u),h)...}}; + return a; + } +#else + +#define CGAL_VAR(Z,N,_) Rational_traits().make_rational( t##N , h) +#define CGAL_CODE(Z,N,_) template Vector \ + operator()(H const&h, BOOST_PP_ENUM_PARAMS(N,NT const& t)) const { \ + CGAL_assertion(N<=d_); \ + Vector a={{BOOST_PP_ENUM(N,CGAL_VAR,_)}}; \ + return a; \ + } + BOOST_PP_REPEAT_FROM_TO(1, 11, CGAL_CODE, _ ) +#undef CGAL_CODE +#undef CGAL_VAR + +#endif + }; + }; + + typedef NT const* Vector_const_iterator; + static Vector_const_iterator vector_begin(Vector const&a){ + return &a[0]; + } + static Vector_const_iterator vector_end(Vector const&a){ + return &a[0]+d_; // Don't know the real size + } + static unsigned size_of_vector(Vector const&){ + return d_; // Don't know the real size + } + +}; + +} +#endif diff -Nru cgal-4.4/include/CGAL/NewKernel_d/Vector/avx4.h cgal-4.5/include/CGAL/NewKernel_d/Vector/avx4.h --- cgal-4.4/include/CGAL/NewKernel_d/Vector/avx4.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/Vector/avx4.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,213 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_VECTOR_AVX4_H +#define CGAL_VECTOR_AVX4_H + +#if !defined __AVX__ || (__GNUC__ * 100 + __GNUC_MINOR__ < 408) +#error Requires AVX and gcc 4.8+ +#endif +#include + +#include +#include +#include // CGAL::Sign +#include // CGAL::sign + + + +namespace CGAL { + + struct Avx_vector_4 { + typedef double NT; + typedef Dimension_tag<4> Dimension; + typedef Dimension_tag<4> Max_dimension; + // No Rebind_dimension, this is a building block + template struct Property : boost::false_type {}; + template struct Property + : boost::true_type {}; + /* MAYBE? + template struct Property + : boost::true_type {}; + */ + template struct Property + : boost::true_type {}; + template struct Property + : boost::true_type {}; + template struct Property + : boost::true_type {}; + + typedef __m256d Vector; + struct Construct_vector { + struct Dimension { + // Initialize with NaN? + Vector operator()(unsigned d) const { + CGAL_assertion(d==4); + return Vector(); + } + }; + + struct Iterator { + template + Vector operator()(unsigned d,Iter const& f,Iter const& e) const { + CGAL_assertion(d==4); + double x0 = *f; + double x1 = *++f; + double x2 = *++f; + double x3 = *++f; + CGAL_assertion(++f==e); + Vector a = { x0, x1, x2, x3 }; + return a; + } + }; + + struct Iterator_and_last { + template + Vector operator()(unsigned d,Iter const& f,Iter const& e,double t) const { + CGAL_assertion(d==4); + double x0 = *f; + double x1 = *++f; + double x2 = *++f; + CGAL_assertion(++f==e); + Vector a = { x0, x1, x2, t }; + return a; + } + }; + + struct Values { + Vector operator()(double a,double b,double c,double d) const { + Vector r = { a, b, c, d }; + return r; + } + }; + + struct Values_divide { + Vector operator()(double h,double a,double b,double c,double d) const { + // {a,b,c,d}/{h,h,h,h} should be roughly the same + Vector r = { a/h, b/h, c/h, d/h }; + return r; + } + }; + }; + + public: + typedef double const* Vector_const_iterator; + static inline Vector_const_iterator vector_begin(Vector const&a){ + return (Vector_const_iterator)(&a); + } + static inline Vector_const_iterator vector_end(Vector const&a){ + return (Vector_const_iterator)(&a)+4; + } + static inline unsigned size_of_vector(Vector){ + return 4; + } + static inline double dot_product(__m256d x, __m256d y){ + __m256d p=x*y; + __m256d z=_mm256_hadd_pd(p,p); + return z[0]+z[2]; + } + private: + static inline __m256d avx_sym(__m256d x){ +#if 0 + return __builtin_shuffle(x,(__m256i){2,3,0,1}); +#else + return _mm256_permute2f128_pd(x,x,1); +#endif + } + static inline __m256d avx_left(__m256d x){ +#if 0 + return __builtin_shuffle(x,(__m256i){1,2,3,0}); +#else +#ifdef __AVX2__ + return _mm256_permute4x64_pd(x,1+2*4+3*16+0*64); +#else + __m256d s = _mm256_permute2f128_pd(x,x,1); + return _mm256_shuffle_pd(x,s,5); +#endif +#endif + } + static inline __m256d avx_right(__m256d x){ +#if 0 + return __builtin_shuffle(x,(__m256i){3,0,1,2}); +#else +#ifdef __AVX2__ + return _mm256_permute4x64_pd(x,3+0*4+1*16+2*64); +#else + __m256d s = _mm256_permute2f128_pd(x,x,1); + return _mm256_shuffle_pd(s,x,5); +#endif +#endif + } + static inline double avx_altprod(__m256d x, __m256d y){ + __m256d p=x*y; + __m256d z=_mm256_hsub_pd(p,p); + return z[0]+z[2]; + } + public: + static double + determinant_of_vectors(Vector a, Vector b, Vector c, Vector d) { + __m256d x=a*avx_left(b)-avx_left(a)*b; + __m256d yy=a*avx_sym(b); + __m256d y=yy-avx_sym(yy); + __m256d z0=x*avx_sym(c); + __m256d z1=avx_left(x)*c; + __m256d z2=y*avx_left(c); + __m256d z=z0+z1-z2; + return avx_altprod(z,avx_right(d)); + } + static CGAL::Sign + sign_of_determinant_of_vectors(Vector a, Vector b, Vector c, Vector d) { + return CGAL::sign(determinant_of_vectors(a,b,c,d)); + } + + private: + static inline __m256d avx3_right(__m256d x){ +#if 0 + return __builtin_shuffle(x,(__m256i){2,0,1,3}); // can replace 3 with anything +#else +#ifdef __AVX2__ + return _mm256_permute4x64_pd(x,2+0*4+1*16+3*64); +#else + __m256d s = _mm256_permute2f128_pd(x,x,1); + return _mm256_shuffle_pd(s,x,12); +#endif +#endif + } + public: + static inline double dot_product_omit_last(__m256d x, __m256d y){ + __m256d p=x*y; + __m128d q=_mm256_extractf128_pd(p,0); + double z=_mm_hadd_pd(q,q)[0]; + return z+p[2]; + } + // Note: without AVX2, is it faster than the scalar computation? + static double + determinant_of_vectors_omit_last(Vector a, Vector b, Vector c) { + __m256d x=a*avx3_right(b)-avx3_right(a)*b; + return dot_product_omit_last(c,avx3_right(x)); + } + static CGAL::Sign + sign_of_determinant_of_vectors_omit_last(Vector a, Vector b, Vector c) { + return CGAL::sign(determinant_of_vectors_omit_last(a,b,c)); + } + + }; + +} +#endif diff -Nru cgal-4.4/include/CGAL/NewKernel_d/Vector/determinant_of_iterator_to_points_from_iterator_to_vectors.h cgal-4.5/include/CGAL/NewKernel_d/Vector/determinant_of_iterator_to_points_from_iterator_to_vectors.h --- cgal-4.4/include/CGAL/NewKernel_d/Vector/determinant_of_iterator_to_points_from_iterator_to_vectors.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/Vector/determinant_of_iterator_to_points_from_iterator_to_vectors.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,76 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_VECTOR_DET_ITER_PTS_ITER_VEC_H +#define CGAL_VECTOR_DET_ITER_PTS_ITER_VEC_H +#include +#include +#include +#include + +namespace CGAL { + +template ::value, + bool = LA::template Property::value> +struct Add_determinant_of_iterator_to_points_from_iterator_to_vectors : LA { + template< class D2, class D3=D2 > + struct Rebind_dimension { + typedef typename LA::template Rebind_dimension LA2; + typedef Add_determinant_of_iterator_to_points_from_iterator_to_vectors Other; + }; +}; + +template +struct Add_determinant_of_iterator_to_points_from_iterator_to_vectors + : LA { + typedef typename LA::NT NT; + typedef typename LA::Vector Vector; + template< class D2, class D3=D2 > + struct Rebind_dimension { + typedef typename LA::template Rebind_dimension LA2; + typedef Add_determinant_of_iterator_to_points_from_iterator_to_vectors Other; + }; + template struct Property : LA::template Property

{}; + template struct Property : + boost::true_type {}; + + // TODO: use std::minus, std::bind, etc + template struct Minus_fixed { + T const& a; + Minus_fixed(T const&a_):a(a_){} + T operator()(T const&b)const{return b-a;} + }; + template + static NT determinant_of_iterator_to_points(Iter const&first, Iter const&end){ + Vector const&a=*first; ++first; + Minus_fixed f(a); + return LA::determinant_of_iterator_to_vectors(make_transforming_iterator(first,f),make_transforming_iterator(end,f)); + } + template + static Sign sign_of_determinant_of_iterator_to_points(Iter const&first, Iter const&end){ + Vector const&a=*first; ++first; + Minus_fixed f(a); + return LA::sign_of_determinant_of_iterator_to_vectors(make_transforming_iterator(first,f),make_transforming_iterator(end,f)); + } +}; + +} +#endif diff -Nru cgal-4.4/include/CGAL/NewKernel_d/Vector/determinant_of_iterator_to_points_from_points.h cgal-4.5/include/CGAL/NewKernel_d/Vector/determinant_of_iterator_to_points_from_points.h --- cgal-4.4/include/CGAL/NewKernel_d/Vector/determinant_of_iterator_to_points_from_points.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/Vector/determinant_of_iterator_to_points_from_points.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,211 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_VECTOR_DET_ITER_PTS_PTS_H +#define CGAL_VECTOR_DET_ITER_PTS_PTS_H +#include +#include + +namespace CGAL { + +template ::value, + bool = LA::template Property::value> +struct Add_determinant_of_iterator_to_points_from_points : LA { + template< class D2, class D3=D2 > + struct Rebind_dimension { + typedef typename LA::template Rebind_dimension LA2; + typedef Add_determinant_of_iterator_to_points_from_points Other; + }; +}; + +//FIXME: Use variadics and boost so it works in any dimension. +template +struct Add_determinant_of_iterator_to_points_from_points +, Max_dim_, false, true> : LA { + typedef typename LA::NT NT; + typedef typename LA::Vector Vector; + template< class D2, class D3=D2 > + struct Rebind_dimension { + typedef typename LA::template Rebind_dimension LA2; + typedef Add_determinant_of_iterator_to_points_from_points Other; + }; + template struct Property : LA::template Property

{}; + template struct Property : + boost::true_type {}; + + template + static NT determinant_of_iterator_to_points(Iter const&first, Iter const&end){ + Vector const&a=*first; ++first; + Vector const&b=*first; ++first; + Vector const&c=*first; CGAL_assertion(++first==end); + return LA::determinant_of_points(a,b,c); + } + template + static Sign sign_of_determinant_of_iterator_to_points(Iter const&first, Iter const&end){ + Vector const&a=*first; ++first; + Vector const&b=*first; ++first; + Vector const&c=*first; CGAL_assertion(++first==end); + return LA::sign_of_determinant_of_points(a,b,c); + } +}; + +template +struct Add_determinant_of_iterator_to_points_from_points +, Max_dim_, false, true> : LA { + typedef typename LA::NT NT; + typedef typename LA::Vector Vector; + template< class D2, class D3=D2 > + struct Rebind_dimension { + typedef typename LA::template Rebind_dimension LA2; + typedef Add_determinant_of_iterator_to_points_from_points Other; + }; + template struct Property : LA::template Property

{}; + template struct Property : + boost::true_type {}; + + template + static NT determinant_of_iterator_to_points(Iter const&first, Iter const&end){ + Vector const&a=*first; ++first; + Vector const&b=*first; ++first; + Vector const&c=*first; ++first; + Vector const&d=*first; CGAL_assertion(++first==end); + return LA::determinant_of_points(a,b,c,d); + } + template + static Sign sign_of_determinant_of_iterator_to_points(Iter const&first, Iter const&end){ + Vector const&a=*first; ++first; + Vector const&b=*first; ++first; + Vector const&c=*first; ++first; + Vector const&d=*first; CGAL_assertion(++first==end); + return LA::sign_of_determinant_of_points(a,b,c,d); + } +}; + +template +struct Add_determinant_of_iterator_to_points_from_points +, Max_dim_, false, true> : LA { + typedef typename LA::NT NT; + typedef typename LA::Vector Vector; + template< class D2, class D3=D2 > + struct Rebind_dimension { + typedef typename LA::template Rebind_dimension LA2; + typedef Add_determinant_of_iterator_to_points_from_points Other; + }; + template struct Property : LA::template Property

{}; + template struct Property : + boost::true_type {}; + + template + static NT determinant_of_iterator_to_points(Iter const&first, Iter const&end){ + Vector const&a=*first; ++first; + Vector const&b=*first; ++first; + Vector const&c=*first; ++first; + Vector const&d=*first; ++first; + Vector const&e=*first; CGAL_assertion(++first==end); + return LA::determinant_of_points(a,b,c,d,e); + } + template + static Sign sign_of_determinant_of_iterator_to_points(Iter const&first, Iter const&end){ + Vector const&a=*first; ++first; + Vector const&b=*first; ++first; + Vector const&c=*first; ++first; + Vector const&d=*first; ++first; + Vector const&e=*first; CGAL_assertion(++first==end); + return LA::sign_of_determinant_of_points(a,b,c,d,e); + } +}; + +template +struct Add_determinant_of_iterator_to_points_from_points +, Max_dim_, false, true> : LA { + typedef typename LA::NT NT; + typedef typename LA::Vector Vector; + template< class D2, class D3=D2 > + struct Rebind_dimension { + typedef typename LA::template Rebind_dimension LA2; + typedef Add_determinant_of_iterator_to_points_from_points Other; + }; + template struct Property : LA::template Property

{}; + template struct Property : + boost::true_type {}; + + template + static NT determinant_of_iterator_to_points(Iter const&first, Iter const&end){ + Vector const&a=*first; ++first; + Vector const&b=*first; ++first; + Vector const&c=*first; ++first; + Vector const&d=*first; ++first; + Vector const&e=*first; ++first; + Vector const&f=*first; CGAL_assertion(++first==end); + return LA::determinant_of_points(a,b,c,d,e,f); + } + template + static Sign sign_of_determinant_of_iterator_to_points(Iter const&first, Iter const&end){ + Vector const&a=*first; ++first; + Vector const&b=*first; ++first; + Vector const&c=*first; ++first; + Vector const&d=*first; ++first; + Vector const&e=*first; ++first; + Vector const&f=*first; CGAL_assertion(++first==end); + return LA::sign_of_determinant_of_points(a,b,c,d,e,f); + } +}; + +template +struct Add_determinant_of_iterator_to_points_from_points +, Max_dim_, false, true> : LA { + typedef typename LA::NT NT; + typedef typename LA::Vector Vector; + template< class D2, class D3=D2 > + struct Rebind_dimension { + typedef typename LA::template Rebind_dimension LA2; + typedef Add_determinant_of_iterator_to_points_from_points Other; + }; + template struct Property : LA::template Property

{}; + template struct Property : + boost::true_type {}; + + template + static NT determinant_of_iterator_to_points(Iter const&first, Iter const&end){ + Vector const&a=*first; ++first; + Vector const&b=*first; ++first; + Vector const&c=*first; ++first; + Vector const&d=*first; ++first; + Vector const&e=*first; ++first; + Vector const&f=*first; ++first; + Vector const&g=*first; CGAL_assertion(++first==end); + return LA::determinant_of_points(a,b,c,d,e,f,g); + } + template + static Sign sign_of_determinant_of_iterator_to_points(Iter const&first, Iter const&end){ + Vector const&a=*first; ++first; + Vector const&b=*first; ++first; + Vector const&c=*first; ++first; + Vector const&d=*first; ++first; + Vector const&e=*first; ++first; + Vector const&f=*first; ++first; + Vector const&g=*first; CGAL_assertion(++first==end); + return LA::sign_of_determinant_of_points(a,b,c,d,e,f,g); + } +}; + +} +#endif diff -Nru cgal-4.4/include/CGAL/NewKernel_d/Vector/determinant_of_iterator_to_vectors_from_vectors.h cgal-4.5/include/CGAL/NewKernel_d/Vector/determinant_of_iterator_to_vectors_from_vectors.h --- cgal-4.4/include/CGAL/NewKernel_d/Vector/determinant_of_iterator_to_vectors_from_vectors.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/Vector/determinant_of_iterator_to_vectors_from_vectors.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,201 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_VECTOR_DET_ITER_VEC_VEC_H +#define CGAL_VECTOR_DET_ITER_VEC_VEC_H +#include +#include + +namespace CGAL { + +template ::value, + bool = LA::template Property::value> +struct Add_determinant_of_iterator_to_vectors_from_vectors : LA { + template< class D2, class D3=D2 > + struct Rebind_dimension { + typedef typename LA::template Rebind_dimension LA2; + typedef Add_determinant_of_iterator_to_vectors_from_vectors Other; + }; +}; + +//FIXME: Use variadics and boost so it works in any dimension. +template +struct Add_determinant_of_iterator_to_vectors_from_vectors +, Max_dim_, false, true> : LA { + typedef typename LA::NT NT; + typedef typename LA::Vector Vector; + template< class D2, class D3=D2 > + struct Rebind_dimension { + typedef typename LA::template Rebind_dimension LA2; + typedef Add_determinant_of_iterator_to_vectors_from_vectors Other; + }; + template struct Property : LA::template Property

{}; + template struct Property : + boost::true_type {}; + + template + static NT determinant_of_iterator_to_vectors(Iter const&first, Iter const&end){ + Vector const&a=*first; ++first; + Vector const&b=*first; CGAL_assertion(++first==end); + return LA::determinant_of_vectors(a,b); + } + template + static Sign sign_of_determinant_of_iterator_to_vectors(Iter const&first, Iter const&end){ + Vector const&a=*first; ++first; + Vector const&b=*first; CGAL_assertion(++first==end); + return LA::sign_of_determinant_of_vectors(a,b); + } +}; + +template +struct Add_determinant_of_iterator_to_vectors_from_vectors +, Max_dim_, false, true> : LA { + typedef typename LA::NT NT; + typedef typename LA::Vector Vector; + template< class D2, class D3=D2 > + struct Rebind_dimension { + typedef typename LA::template Rebind_dimension LA2; + typedef Add_determinant_of_iterator_to_vectors_from_vectors Other; + }; + template struct Property : LA::template Property

{}; + template struct Property : + boost::true_type {}; + + template + static NT determinant_of_iterator_to_vectors(Iter const&first, Iter const&end){ + Vector const&a=*first; ++first; + Vector const&b=*first; ++first; + Vector const&c=*first; CGAL_assertion(++first==end); + return LA::determinant_of_vectors(a,b,c); + } + template + static Sign sign_of_determinant_of_iterator_to_vectors(Iter const&first, Iter const&end){ + Vector const&a=*first; ++first; + Vector const&b=*first; ++first; + Vector const&c=*first; CGAL_assertion(++first==end); + return LA::sign_of_determinant_of_vectors(a,b,c); + } +}; + +template +struct Add_determinant_of_iterator_to_vectors_from_vectors +, Max_dim_, false, true> : LA { + typedef typename LA::NT NT; + typedef typename LA::Vector Vector; + template< class D2, class D3=D2 > + struct Rebind_dimension { + typedef typename LA::template Rebind_dimension LA2; + typedef Add_determinant_of_iterator_to_vectors_from_vectors Other; + }; + template struct Property : LA::template Property

{}; + template struct Property : + boost::true_type {}; + + template + static NT determinant_of_iterator_to_vectors(Iter const&first, Iter const&end){ + Vector const&a=*first; ++first; + Vector const&b=*first; ++first; + Vector const&c=*first; ++first; + Vector const&d=*first; CGAL_assertion(++first==end); + return LA::determinant_of_vectors(a,b,c,d); + } + template + static Sign sign_of_determinant_of_iterator_to_vectors(Iter const&first, Iter const&end){ + Vector const&a=*first; ++first; + Vector const&b=*first; ++first; + Vector const&c=*first; ++first; + Vector const&d=*first; CGAL_assertion(++first==end); + return LA::sign_of_determinant_of_vectors(a,b,c,d); + } +}; + +template +struct Add_determinant_of_iterator_to_vectors_from_vectors +, Max_dim_, false, true> : LA { + typedef typename LA::NT NT; + typedef typename LA::Vector Vector; + template< class D2, class D3=D2 > + struct Rebind_dimension { + typedef typename LA::template Rebind_dimension LA2; + typedef Add_determinant_of_iterator_to_vectors_from_vectors Other; + }; + template struct Property : LA::template Property

{}; + template struct Property : + boost::true_type {}; + + template + static NT determinant_of_iterator_to_vectors(Iter const&first, Iter const&end){ + Vector const&a=*first; ++first; + Vector const&b=*first; ++first; + Vector const&c=*first; ++first; + Vector const&d=*first; ++first; + Vector const&e=*first; CGAL_assertion(++first==end); + return LA::determinant_of_vectors(a,b,c,d,e); + } + template + static Sign sign_of_determinant_of_iterator_to_vectors(Iter const&first, Iter const&end){ + Vector const&a=*first; ++first; + Vector const&b=*first; ++first; + Vector const&c=*first; ++first; + Vector const&d=*first; ++first; + Vector const&e=*first; CGAL_assertion(++first==end); + return LA::sign_of_determinant_of_vectors(a,b,c,d,e); + } +}; + +template +struct Add_determinant_of_iterator_to_vectors_from_vectors +, Max_dim_, false, true> : LA { + typedef typename LA::NT NT; + typedef typename LA::Vector Vector; + template< class D2, class D3=D2 > + struct Rebind_dimension { + typedef typename LA::template Rebind_dimension LA2; + typedef Add_determinant_of_iterator_to_vectors_from_vectors Other; + }; + template struct Property : LA::template Property

{}; + template struct Property : + boost::true_type {}; + + template + static NT determinant_of_iterator_to_vectors(Iter const&first, Iter const&end){ + Vector const&a=*first; ++first; + Vector const&b=*first; ++first; + Vector const&c=*first; ++first; + Vector const&d=*first; ++first; + Vector const&e=*first; ++first; + Vector const&f=*first; CGAL_assertion(++first==end); + return LA::determinant_of_vectors(a,b,c,d,e,f); + } + template + static Sign sign_of_determinant_of_iterator_to_vectors(Iter const&first, Iter const&end){ + Vector const&a=*first; ++first; + Vector const&b=*first; ++first; + Vector const&c=*first; ++first; + Vector const&d=*first; ++first; + Vector const&e=*first; ++first; + Vector const&f=*first; CGAL_assertion(++first==end); + return LA::sign_of_determinant_of_vectors(a,b,c,d,e,f); + } +}; + +} +#endif diff -Nru cgal-4.4/include/CGAL/NewKernel_d/Vector/determinant_of_points_from_vectors.h cgal-4.5/include/CGAL/NewKernel_d/Vector/determinant_of_points_from_vectors.h --- cgal-4.4/include/CGAL/NewKernel_d/Vector/determinant_of_points_from_vectors.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/Vector/determinant_of_points_from_vectors.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,164 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_VECTOR_DETPTS_H +#define CGAL_VECTOR_DETPTS_H +#include +#include + +namespace CGAL { + +template ::value, + bool = LA::template Property::value + && LA::template Property::value> +struct Add_determinant_of_points_from_vectors_and_minus : LA { + template< class D2, class D3=D2 > + struct Rebind_dimension { + typedef typename LA::template Rebind_dimension LA2; + typedef Add_determinant_of_points_from_vectors_and_minus Other; + }; +}; + +//FIXME: Use variadics and boost so it works in any dimension. +template +struct Add_determinant_of_points_from_vectors_and_minus +, Max_dim_, false, true> : LA { + typedef typename LA::NT NT; + typedef typename LA::Vector Vector; + template< class D2, class D3=D2 > + struct Rebind_dimension { + typedef typename LA::template Rebind_dimension LA2; + typedef Add_determinant_of_points_from_vectors_and_minus Other; + }; + template struct Property : LA::template Property

{}; + template struct Property : + boost::true_type {}; + + static NT determinant_of_points(Vector const&a, Vector const&b, + Vector const&c){ + return LA::determinant_of_vectors(b-a,c-a); + } + static Sign sign_of_determinant_of_points(Vector const&a, Vector const&b, + Vector const&c){ + return LA::sign_of_determinant_of_vectors(b-a,c-a); + } +}; + +template +struct Add_determinant_of_points_from_vectors_and_minus +, Max_dim_, false, true> : LA { + typedef typename LA::NT NT; + typedef typename LA::Vector Vector; + template< class D2, class D3=D2 > + struct Rebind_dimension { + typedef typename LA::template Rebind_dimension LA2; + typedef Add_determinant_of_points_from_vectors_and_minus Other; + }; + template struct Property : LA::template Property

{}; + template struct Property : + boost::true_type {}; + + static NT determinant_of_points(Vector const&a, Vector const&b, + Vector const&c, Vector const&d){ + return LA::determinant_of_vectors(b-a,c-a,d-a); + } + static Sign sign_of_determinant_of_points(Vector const&a, Vector const&b, + Vector const&c, Vector const&d){ + return LA::sign_of_determinant_of_vectors(b-a,c-a,d-a); + } +}; + +template +struct Add_determinant_of_points_from_vectors_and_minus +, Max_dim_, false, true> : LA { + typedef typename LA::NT NT; + typedef typename LA::Vector Vector; + template< class D2, class D3=D2 > + struct Rebind_dimension { + typedef typename LA::template Rebind_dimension LA2; + typedef Add_determinant_of_points_from_vectors_and_minus Other; + }; + template struct Property : LA::template Property

{}; + template struct Property : + boost::true_type {}; + + static NT determinant_of_points(Vector const&a, Vector const&b, + Vector const&c, Vector const&d, Vector const&e){ + return LA::determinant_of_vectors(b-a,c-a,d-a,e-a); + } + static Sign sign_of_determinant_of_points(Vector const&a, Vector const&b, + Vector const&c, Vector const&d, Vector const&e){ + return LA::sign_of_determinant_of_vectors(b-a,c-a,d-a,e-a); + } +}; + +template +struct Add_determinant_of_points_from_vectors_and_minus +, Max_dim_, false, true> : LA { + typedef typename LA::NT NT; + typedef typename LA::Vector Vector; + template< class D2, class D3=D2 > + struct Rebind_dimension { + typedef typename LA::template Rebind_dimension LA2; + typedef Add_determinant_of_points_from_vectors_and_minus Other; + }; + template struct Property : LA::template Property

{}; + template struct Property : + boost::true_type {}; + + static NT determinant_of_points(Vector const&a, Vector const&b, + Vector const&c, Vector const&d, Vector const&e, Vector const&f){ + return LA::determinant_of_vectors(b-a,c-a,d-a,e-a,f-a); + } + static Sign sign_of_determinant_of_points(Vector const&a, Vector const&b, + Vector const&c, Vector const&d, Vector const&e, Vector const&f){ + return LA::sign_of_determinant_of_vectors(b-a,c-a,d-a,e-a,f-a); + } +}; + +template +struct Add_determinant_of_points_from_vectors_and_minus +, Max_dim_, false, true> : LA { + typedef typename LA::NT NT; + typedef typename LA::Vector Vector; + template< class D2, class D3=D2 > + struct Rebind_dimension { + typedef typename LA::template Rebind_dimension LA2; + typedef Add_determinant_of_points_from_vectors_and_minus Other; + }; + template struct Property : LA::template Property

{}; + template struct Property : + boost::true_type {}; + + static NT determinant_of_points(Vector const&a, Vector const&b, + Vector const&c, Vector const&d, Vector const&e, Vector const&f, + Vector const&g){ + return LA::determinant_of_vectors(b-a,c-a,d-a,e-a,f-a,g-a); + } + static Sign sign_of_determinant_of_points(Vector const&a, Vector const&b, + Vector const&c, Vector const&d, Vector const&e, Vector const&f, + Vector const&g){ + return LA::sign_of_determinant_of_vectors(b-a,c-a,d-a,e-a,f-a,g-a); + } +}; + +} +#endif diff -Nru cgal-4.4/include/CGAL/NewKernel_d/Vector/determinant_of_vectors_small_dim.h cgal-4.5/include/CGAL/NewKernel_d/Vector/determinant_of_vectors_small_dim.h --- cgal-4.4/include/CGAL/NewKernel_d/Vector/determinant_of_vectors_small_dim.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/Vector/determinant_of_vectors_small_dim.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,58 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_VECTOR_DETVEC_SMALL_H +#define CGAL_VECTOR_DETVEC_SMALL_H +#include +#include +#include + +#define CGAL_ALLOWED_INCLUSION 1 + +#define CGAL_CLASS Add_determinant_of_vectors_small_dim +#define CGAL_TAG Has_determinant_of_vectors_tag +#define CGAL_FUNC determinant_of_vectors +#define CGAL_SIGN_FUNC sign_of_determinant_of_vectors +#define CGAL_SHIFT 0 + +#include + +#undef CGAL_CLASS +#undef CGAL_TAG +#undef CGAL_FUNC +#undef CGAL_SIGN_FUNC +#undef CGAL_SHIFT + +#define CGAL_CLASS Add_determinant_of_vectors_omit_last_small_dim +#define CGAL_TAG Has_determinant_of_vectors_omit_last_tag +#define CGAL_FUNC determinant_of_vectors_omit_last +#define CGAL_SIGN_FUNC sign_of_determinant_of_vectors_omit_last +#define CGAL_SHIFT 1 + +#include + +#undef CGAL_CLASS +#undef CGAL_TAG +#undef CGAL_FUNC +#undef CGAL_SIGN_FUNC +#undef CGAL_SHIFT + +#undef CGAL_ALLOWED_INCLUSION + +#endif diff -Nru cgal-4.4/include/CGAL/NewKernel_d/Vector/determinant_of_vectors_small_dim_internal.h cgal-4.5/include/CGAL/NewKernel_d/Vector/determinant_of_vectors_small_dim_internal.h --- cgal-4.4/include/CGAL/NewKernel_d/Vector/determinant_of_vectors_small_dim_internal.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/Vector/determinant_of_vectors_small_dim_internal.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,164 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_ALLOWED_INCLUSION +#error Must not include this header directly +#endif +#if !defined(CGAL_TAG) \ + || ! defined(CGAL_CLASS) \ + || ! defined(CGAL_FUNC) \ + || ! defined(CGAL_SIGN_FUNC) \ + || ! defined(CGAL_SHIFT) + +#error Forgot one macro +#endif + +namespace CGAL { + +template ::value> +struct CGAL_CLASS : LA { + template< class D2, class D3=D2 > + struct Rebind_dimension { + typedef typename LA::template Rebind_dimension LA2; + typedef CGAL_CLASS Other; + }; +}; + +template +struct CGAL_CLASS +, Max_dim_, false> : LA { + typedef typename LA::NT NT; + typedef typename LA::Vector Vector; + template< class D2, class D3=D2 > + struct Rebind_dimension { + typedef typename LA::template Rebind_dimension LA2; + typedef CGAL_CLASS Other; + }; + template struct Property : LA::template Property

{}; + template struct Property : + boost::true_type {}; + + static NT CGAL_FUNC(Vector const&a, Vector const&b){ + return CGAL::determinant_of_vectors(a,b); + } + template + static Sign CGAL_SIGN_FUNC(V1 const&a, V2 const&b){ + return CGAL::sign_of_determinant_of_vectors(a,b); + } +}; + +template +struct CGAL_CLASS +, Max_dim_, false> : LA { + typedef typename LA::NT NT; + typedef typename LA::Vector Vector; + template< class D2, class D3=D2 > + struct Rebind_dimension { + typedef typename LA::template Rebind_dimension LA2; + typedef CGAL_CLASS Other; + }; + template struct Property : LA::template Property

{}; + template struct Property : + boost::true_type {}; + + static NT CGAL_FUNC(Vector const&a, Vector const&b, + Vector const&c){ + return CGAL::determinant_of_vectors(a,b,c); + } + static Sign CGAL_SIGN_FUNC(Vector const&a, Vector const&b, + Vector const&c){ + return CGAL::sign_of_determinant_of_vectors(a,b,c); + } +}; + +template +struct CGAL_CLASS +, Max_dim_, false> : LA { + typedef typename LA::NT NT; + typedef typename LA::Vector Vector; + template< class D2, class D3=D2 > + struct Rebind_dimension { + typedef typename LA::template Rebind_dimension LA2; + typedef CGAL_CLASS Other; + }; + template struct Property : LA::template Property

{}; + template struct Property : + boost::true_type {}; + + static NT CGAL_FUNC(Vector const&a, Vector const&b, + Vector const&c, Vector const&d){ + return CGAL::determinant_of_vectors(a,b,c,d); + } + static Sign CGAL_SIGN_FUNC(Vector const&a, Vector const&b, + Vector const&c, Vector const&d){ + return CGAL::sign_of_determinant_of_vectors(a,b,c,d); + } +}; + +template +struct CGAL_CLASS +, Max_dim_, false> : LA { + typedef typename LA::NT NT; + typedef typename LA::Vector Vector; + template< class D2, class D3=D2 > + struct Rebind_dimension { + typedef typename LA::template Rebind_dimension LA2; + typedef CGAL_CLASS Other; + }; + template struct Property : LA::template Property

{}; + template struct Property : + boost::true_type {}; + + static NT CGAL_FUNC(Vector const&a, Vector const&b, + Vector const&c, Vector const&d, Vector const&e){ + return CGAL::determinant_of_vectors(a,b,c,d,e); + } + static Sign CGAL_SIGN_FUNC(Vector const&a, Vector const&b, + Vector const&c, Vector const&d, Vector const&e){ + return CGAL::sign_of_determinant_of_vectors(a,b,c,d,e); + } +}; + +template +struct CGAL_CLASS +, Max_dim_, false> : LA { + typedef typename LA::NT NT; + typedef typename LA::Vector Vector; + template< class D2, class D3=D2 > + struct Rebind_dimension { + typedef typename LA::template Rebind_dimension LA2; + typedef CGAL_CLASS Other; + }; + template struct Property : LA::template Property

{}; + template struct Property : + boost::true_type {}; + + static NT CGAL_FUNC(Vector const&a, Vector const&b, + Vector const&c, Vector const&d, Vector const&e, Vector const&f){ + return CGAL::determinant_of_vectors(a,b,c,d,e,f); + } + static Sign CGAL_SIGN_FUNC(Vector const&a, Vector const&b, + Vector const&c, Vector const&d, Vector const&e, Vector const&f){ + return CGAL::sign_of_determinant_of_vectors(a,b,c,d,e,f); + } +}; + +} diff -Nru cgal-4.4/include/CGAL/NewKernel_d/Vector/mix.h cgal-4.5/include/CGAL/NewKernel_d/Vector/mix.h --- cgal-4.4/include/CGAL/NewKernel_d/Vector/mix.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/Vector/mix.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,46 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_KD_MIX_VECTOR_H +#define CGAL_KD_MIX_VECTOR_H +#include +namespace CGAL { + +template +struct Mix_vector +: Dynamic_::template Rebind_dimension::Other +{ + template + struct Rebind_dimension { + typedef Mix_vector Other; + }; +}; + +template +struct Mix_vector, Max_dim_> +: Static_::template Rebind_dimension, Max_dim_>::Other +{ + template + struct Rebind_dimension { + typedef Mix_vector Other; + }; +}; +} +#endif + diff -Nru cgal-4.4/include/CGAL/NewKernel_d/Vector/sse2.h cgal-4.5/include/CGAL/NewKernel_d/Vector/sse2.h --- cgal-4.4/include/CGAL/NewKernel_d/Vector/sse2.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/Vector/sse2.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,145 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_VECTOR_SSE2_H +#define CGAL_VECTOR_SSE2_H + +// Check what needs adapting for clang, intel and microsoft +#if !defined __SSE2__ || (__GNUC__ * 100 + __GNUC_MINOR__ < 408) +#error Requires SSE2 and gcc 4.8+ +#endif +#include // FIXME: other platforms call it differently + +#include +#include +#include // CGAL::Sign +#include // CGAL::sign + + + +namespace CGAL { + + struct Sse_vector_2 { + typedef double NT; + typedef Dimension_tag<2> Dimension; + typedef Dimension_tag<2> Max_dimension; + // No Rebind_dimension, this is a building block + template struct Property : boost::false_type {}; + template struct Property + : boost::true_type {}; + /* MAYBE? + template struct Property + : boost::true_type {}; + */ + template struct Property + : boost::true_type {}; + template struct Property + : boost::true_type {}; + + typedef __m128d Vector; + struct Construct_vector { + struct Dimension { + // Initialize with NaN? + Vector operator()(unsigned d) const { + CGAL_assertion(d==2); + return Vector(); + } + }; + + struct Iterator { + template + Vector operator()(unsigned d,Iter const& f,Iter const& e) const { + CGAL_assertion(d==2); + double x0 = *f; + double x1 = *++f; + CGAL_assertion(++f==e); + Vector a = { x0, x1 }; + return a; + } + }; + + struct Iterator_and_last { + template + Vector operator()(unsigned d,Iter const& f,Iter const& e,double t) const { + CGAL_assertion(d==2); + Vector a = { *f, t }; + CGAL_assertion(++f==e); + return a; + } + }; + + struct Values { + Vector operator()(double a,double b) const { + Vector r = { a, b }; + return r; + } + }; + + struct Values_divide { + Vector operator()(double h,double a,double b) const { + // {a,b}/{h,h} is probably slower + Vector r = { a/h, b/h }; + return r; + } + }; + }; + + typedef double const* Vector_const_iterator; + static inline Vector_const_iterator vector_begin(Vector const&a){ + return (Vector_const_iterator)(&a); + } + static inline Vector_const_iterator vector_end(Vector const&a){ + return (Vector_const_iterator)(&a)+2; + } + static inline unsigned size_of_vector(Vector){ + return 2; + } + public: + + static double determinant_of_vectors(Vector a, Vector b) { + __m128d c = _mm_shuffle_pd (b, b, 1); // b1, b0 + __m128d d = a * c; // a0*b1, a1*b0 +#ifdef __SSE3__ + __m128d e = _mm_hsub_pd (d, d); + return e[0]; +#else + return d[0]-d[1]; +#endif + } + static CGAL::Sign sign_of_determinant_of_vectors(Vector a, Vector b) { + return CGAL::sign(determinant_of_vectors(a,b)); + } + + static double dot_product(Vector a,Vector b){ +#ifdef __SSE4_1__ + return _mm_dp_pd (a, b, 1+16+32)[0]; +#else + __m128d p = a * b; +#if defined __SSE3__ + __m128d s = _mm_hadd_pd (p, p); + return s[0]; +#else + return p[0]+p[1]; +#endif +#endif + }; + }; + +} +#endif diff -Nru cgal-4.4/include/CGAL/NewKernel_d/Vector/v2int.h cgal-4.5/include/CGAL/NewKernel_d/Vector/v2int.h --- cgal-4.4/include/CGAL/NewKernel_d/Vector/v2int.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/Vector/v2int.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,181 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_VECTOR_2INT_H +#define CGAL_VECTOR_2INT_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +// What are the pros and cons of having NT be int vs double? + +namespace CGAL { + struct Vector_2_int_prop1 { + typedef double NT; // try lying a bit + typedef int32_t NT1; // what is really stored + typedef int32_t NT1b; // slightly longer + typedef int_fast64_t NT2; // longer type for computations + typedef int_fast64_t NT2b; // slightly longer + bool check_limits(int32_t x){return std::abs(x)<(1<<30);} + // TODO: find nice bounds + }; +#ifdef __SIZEOF_INT128__ + struct Vector_2_int_prop2 { + typedef double NT; + typedef int32_t NT1; + typedef int_fast64_t NT1b; + typedef int_fast64_t NT2; + typedef __int128 NT2b; + bool check_limits(int32_t){return true;} + // take a template/int64_t input and still check the limits? + }; + struct Vector_2_int_prop3 { + typedef long double NT; + typedef int64_t NT1; + typedef int64_t NT1b; + typedef __int128 NT2; + typedef __int128 NT2b; + enum { has_limit=true }; + bool check_limits(int32_t x){return std::abs(x)<(1L<<62);} + // TODO: find nice bounds + }; +#endif + + template + struct Vector_2_int : Prop { + using typename Prop::NT; + using typename Prop::NT1; + using typename Prop::NT1b; + using typename Prop::NT2; + using typename Prop::NT2b; + using Prop::check_limits; + + typedef Dimension_tag<2> Dimension; + typedef Dimension_tag<2> Max_dimension; + // No Rebind_dimension, this is a building block + template struct Property : boost::false_type {}; + //template struct Property + // : boost::true_type {}; + template struct Property + : boost::true_type {}; + //template struct Property + // : boost::true_type {}; + // Advertise somehow that the sign_of_determinant* are exact? + + typedef cpp0x::array Vector; + struct Construct_vector { + struct Dimension { + Vector operator()(unsigned d) const { + CGAL_assertion(d==2); + return Vector(); + } + }; + + // TODO (for all constructors): check that input fits in NT1... + struct Iterator { + template + Vector operator()(unsigned d,Iter const& f,Iter const& e) const { + CGAL_assertion(d==2); + NT1 x0 = *f; + NT1 x1 = *++f; + CGAL_assertion (++f == e); + CGAL_assertion (check_limits(x0) && check_limits(x1)); + Vector a = { x0, x1 }; + return a; + } + }; + + struct Iterator_and_last { + template + Vector operator()(unsigned d,Iter const& f,Iter const& e,double t) const { + CGAL_assertion(d==2); + NT1 x = *f; + CGAL_assertion (++f == e); + CGAL_assertion (check_limits(x) && check_limits(t)); + Vector a = { x, t }; + return a; + } + }; + + struct Values { + Vector operator()(NT1 a,NT1 b) const { + CGAL_assertion (check_limits(a) && check_limits(b)); + Vector r = { a, b }; + return r; + } + }; + + /* + // Maybe safer not to provide it + struct Values_divide { + Vector operator()(double h,double a,double b) const { + Vector r = { a/h, b/h }; + return r; + } + }; + */ + }; + + // Since we lie about NT, be consistent about it + typedef transforming_iterator,NT1 const*> Vector_const_iterator; + static inline Vector_const_iterator vector_begin(Vector const&a){ + return Vector_const_iterator(a.begin()); + } + static inline Vector_const_iterator vector_end(Vector const&a){ + return Vector_const_iterator(a.end()); + } + static inline unsigned size_of_vector(Vector){ + return 2; + } + + // for unsigned NT1, check what changes to do. + // return NT or NT2? + static NT determinant_of_vectors(Vector a, Vector b) { + return CGAL::determinant_of_vectors(a,b); + } + static CGAL::Sign sign_of_determinant_of_vectors(Vector a, Vector b) { + return CGAL::sign_of_determinant_of_vectors(a,b); + } + + static NT determinant_of_points(Vector a, Vector b, Vector c) { + // could be faster to convert to NT directly + NT1b a0=a[0]; NT1b a1=a[1]; + NT1b x0=b[0]-a0; NT1b x1=b[1]-a1; + NT1b y0=c[0]-a0; NT1b y1=c[1]-a1; + return CGAL::determinant(x0,x1,y0,y1); + } + static CGAL::Sign sign_of_determinant_of_points(Vector a, Vector b, Vector c) { + NT1b a0=a[0]; NT1b a1=a[1]; + NT1b x0=b[0]-a0; NT1b x1=b[1]-a1; + NT2b y0=c[0]-a0; NT2b y1=c[1]-a1; + return CGAL::compare(x0*y1,x1*y0); + } + }; + +} +#endif diff -Nru cgal-4.4/include/CGAL/NewKernel_d/Vector/vector.h cgal-4.5/include/CGAL/NewKernel_d/Vector/vector.h --- cgal-4.4/include/CGAL/NewKernel_d/Vector/vector.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/Vector/vector.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,167 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_VECTOR_VECTOR_H +#define CGAL_VECTOR_VECTOR_H +#include +#include +#include +#include +#include +#include +#include +namespace CGAL { + +//Derive from a class that doesn't depend on Dim, or still use Dim for checking? +template struct Vector_vector { + typedef NT_ NT; + typedef Dim_ Dimension; + typedef Max_dim_ Max_dimension; + typedef std::vector Vector; + template< class D2, class D3=D2 > + struct Rebind_dimension { + typedef Vector_vector< NT, D2, D3 > Other; + }; + template struct Property : boost::false_type {}; + + struct Construct_vector { + struct Dimension { + Vector operator()(int d) const { + return Vector(d); + } + }; + + struct Iterator { + template + Vector operator()(int d,Iter const& f,Iter const& e) const { + CGAL_assertion(d==std::distance(f,e)); + return Vector(f,e); + } + }; + + // unneeded thanks to Iterator_and_last? +#if 0 + struct Iterator_add_one { + template + Vector operator()(int d,Iter const& f,Iter const& e) const { + CGAL_assertion(d==std::distance(f,e)+1); + Vector a; + a.reserve(d+1); + a.insert(a.end(),f,e); + a.push_back(1); + return a; + } + }; +#endif + + struct Iterator_and_last { + template + Vector operator()(int d,Iter const& f,Iter const& e,CGAL_FORWARDABLE(T) t) const { + CGAL_assertion(d==std::distance(f,e)+1); + Vector a; + a.reserve(d+1); + a.insert(a.end(),f,e); + a.push_back(CGAL_FORWARD(T,t)); + return a; + } + }; + + // useless, use a transform_iterator? +#if 0 + struct Iterator_and_last_divide { + template + Vector operator()(int d,Iter f,Iter const& e,T const&t) const { + CGAL_assertion(d==std::distance(f,e)+1); + Vector a; + a.reserve(d+1); + for(;f!=e;++f){ + a.push_back(*f/t); + } + return a; + } + }; +#endif + + struct Values { +#ifdef CGAL_CXX11 + template + Vector operator()(U&&...u) const { + //TODO: check the right number of {}, g++ accepts one and two + Vector a={forward_safe(u)...}; + return a; + } +#else + +#define CGAL_VAR(Z,N,_) a.push_back(t##N); +#define CGAL_CODE(Z,N,_) Vector operator()(BOOST_PP_ENUM_PARAMS(N,NT const& t)) const { \ + Vector a; \ + a.reserve(N); \ + BOOST_PP_REPEAT(N,CGAL_VAR,) \ + return a; \ +} +BOOST_PP_REPEAT_FROM_TO(1, 11, CGAL_CODE, _ ) +#undef CGAL_CODE +#undef CGAL_VAR + +#endif + }; + + struct Values_divide { +#ifdef CGAL_CXX11 + template + Vector operator()(H const&h,U&&...u) const { + //TODO: do we want to cast at some point? + //e.g. to avoid 1/2 in integers + // ==> use Rational_traits().make_rational(x,y) ? + Vector a={Rational_traits().make_rational(std::forward(u),h)...}; + return a; + } +#else + +#define CGAL_VAR(Z,N,_) a.push_back(Rational_traits().make_rational( t##N ,h)); +#define CGAL_CODE(Z,N,_) template Vector \ + operator()(H const&h, BOOST_PP_ENUM_PARAMS(N,NT const& t)) const { \ + Vector a; \ + a.reserve(N); \ + BOOST_PP_REPEAT(N,CGAL_VAR,) \ + return a; \ + } + BOOST_PP_REPEAT_FROM_TO(1, 11, CGAL_CODE, _ ) +#undef CGAL_CODE +#undef CGAL_VAR + +#endif + }; + }; + typedef typename Vector::const_iterator Vector_const_iterator; + static Vector_const_iterator vector_begin(Vector const&a){ + return a.begin(); + } + static Vector_const_iterator vector_end(Vector const&a){ + return a.end(); + } + static int size_of_vector(Vector const&a){ + return (int)a.size(); + } +}; + + +} +#endif + diff -Nru cgal-4.4/include/CGAL/NewKernel_d/Wrapper/Cartesian_wrap.h cgal-4.5/include/CGAL/NewKernel_d/Wrapper/Cartesian_wrap.h --- cgal-4.4/include/CGAL/NewKernel_d/Wrapper/Cartesian_wrap.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/Wrapper/Cartesian_wrap.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,294 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_KERNEL_D_CARTESIAN_WRAP_H +#define CGAL_KERNEL_D_CARTESIAN_WRAP_H + +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +//TODO: do we want to store the kernel ref in the Object wrappers? It would allow for additions and operator[] and things like that to work, but objects would still need to be created by functors. + +namespace CGAL { +namespace internal { +BOOST_MPL_HAS_XXX_TRAIT_DEF(Is_wrapper) +template::value> struct Is_wrapper { + enum { value=false }; + typedef Tag_false type; +}; +template struct Is_wrapper { + typedef typename T::Is_wrapper type; + enum { value=type::value }; +}; + +template::value> struct Is_wrapper_iterator { + enum { value=false }; + typedef Tag_false type; +}; +template struct Is_wrapper_iterator : + Is_wrapper::type>::value_type> +{ }; + +struct Forward_rep { +//TODO: make a good C++0X version with perfect forwarding +//#ifdef CGAL_CXX11 +//template ::type>::value&&!Is_wrapper_iterator::type>::value>::type> +//T&& operator()(typename std::remove_reference::type&& t) const {return static_cast(t);}; +//template ::type>::value&&!Is_wrapper_iterator::type>::value>::type> +//T&& operator()(typename std::remove_reference::type& t) const {return static_cast(t);}; +// +//template ::type>::value>::type> +//typename Type_copy_cvref::type::Rep>::type&& +//operator()(T&& t) const { +// return static_cast::type::Rep>::type&&>(t.rep()); +//}; +// +//template ::type>::value>::type> +//transforming_iterator::type> +//operator()(T&& t) const { +// return make_transforming_iterator(std::forward(t),Forward_rep()); +//}; +//#else +template ::value,bool=Is_wrapper_iterator::value> struct result_; +template struct result_{typedef T const& type;}; +template struct result_{typedef typename decay::type::Rep const& type;}; +template struct result_{typedef transforming_iterator::type> type;}; +template struct result; +template struct result : result_ {}; + +template typename boost::disable_if,Is_wrapper_iterator >,T>::type const& operator()(T const& t) const {return t;} +template typename boost::disable_if,Is_wrapper_iterator >,T>::type& operator()(T& t) const {return t;} + +template typename T::Rep const& operator()(T const& t, typename boost::enable_if >::type* = 0) const {return t.rep();} + +template transforming_iterator,T>::type> operator()(T const& t) const {return make_transforming_iterator(t,Forward_rep());} +//#endif +}; +} + +template ::value> +struct Map_wrapping_type : Get_type {}; +#define CGAL_REGISTER_OBJECT_WRAPPER(X) \ + template \ + struct Map_wrapping_type { \ + typedef Wrap::X##_d type; \ + } +CGAL_REGISTER_OBJECT_WRAPPER(Point); +CGAL_REGISTER_OBJECT_WRAPPER(Vector); +CGAL_REGISTER_OBJECT_WRAPPER(Segment); +CGAL_REGISTER_OBJECT_WRAPPER(Sphere); +CGAL_REGISTER_OBJECT_WRAPPER(Hyperplane); +#undef CGAL_REGISTER_OBJECT_WRAPPER + +// Note: this tends to be an all or nothing thing currently, wrapping +// only some types breaks, probably because we don't check whether the +// return type is indeed wrapped. +template < typename Base_ , typename Derived_ = Default > +struct Cartesian_wrap : public Base_ +{ + CGAL_CONSTEXPR Cartesian_wrap(){} + CGAL_CONSTEXPR Cartesian_wrap(int d):Base_(d){} + typedef Base_ Kernel_base; + typedef Cartesian_wrap Self; + // TODO: pass the 2 types Self and Derived to the wrappers, they can use Self for most purposes and Derived only for Kernel_traits' typedef R. + typedef typename Default::Get::type Derived; + // FIXME: The list doesn't belong here. + typedef boost::mpl::vector Wrapped_list; + + template + struct Type : Map_wrapping_type {}; + + //Translate the arguments + template ::type, + bool=Provides_functor::value, + bool=boost::mpl::contains::type>::type::value> + struct Functor { + typedef typename Get_functor::type B; + struct type { + B b; + type(){} + type(Self const&k):b(k){} + typedef typename B::result_type result_type; +#ifdef CGAL_CXX11 + template result_type operator()(U&&...u)const{ + return b(internal::Forward_rep()(u)...); + } +#else +#define CGAL_VAR(Z,N,_) internal::Forward_rep()(u##N) +#define CGAL_CODE(Z,N,_) template result_type \ + operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,U,const&u))const{ \ + return b(BOOST_PP_ENUM(N,CGAL_VAR,)); \ + } + BOOST_PP_REPEAT_FROM_TO(1,11,CGAL_CODE,_) +#undef CGAL_CODE +#undef CGAL_VAR +// In case the last argument needs to be non-const. Fragile... +#define CGAL_VAR(Z,N,_) internal::Forward_rep()(u##N) +#define CGAL_CODE(Z,N,_) template result_type \ + operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,U,const&u),V&v)const{ \ + return b(BOOST_PP_ENUM(N,CGAL_VAR,),internal::Forward_rep()(v)); \ + } + BOOST_PP_REPEAT_FROM_TO(1,8,CGAL_CODE,_) +#undef CGAL_CODE +#undef CGAL_VAR +#endif + }; + }; + + // Preserve the difference between Null_functor and nothing. + template + struct Functor + : Get_functor {}; + + //Translate both the arguments and the result + //TODO: Check Is_wrapper instead of relying on map_result_tag? + template struct Functor { + typedef typename Get_functor::type B; + struct type { + B b; + type(){} + type(Self const&k):b(k){} + typedef typename map_result_tag::type result_tag; + // FIXME: Self or Derived? + typedef typename Get_type::type result_type; +#ifdef CGAL_CXX11 + template result_type operator()(U&&...u)const{ + return result_type(Eval_functor(),b,internal::Forward_rep()(u)...); + } +#else +#define CGAL_VAR(Z,N,_) internal::Forward_rep()(u##N) +#define CGAL_CODE(Z,N,_) template result_type \ + operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,U,const&u))const{ \ + return result_type(Eval_functor(),b,BOOST_PP_ENUM(N,CGAL_VAR,)); \ + } + BOOST_PP_REPEAT_FROM_TO(1,11,CGAL_CODE,_) +#undef CGAL_CODE +#undef CGAL_VAR +#endif + }; + }; + +}; + +template < typename Base_ > +struct Cartesian_refcount : public Base_ +{ + CGAL_CONSTEXPR Cartesian_refcount(){} + CGAL_CONSTEXPR Cartesian_refcount(int d):Base_(d){} + typedef Base_ Kernel_base; + typedef Cartesian_refcount Self; + + // FIXME: Use object_list, or a list passed as argument, or anything + // automatic. + template struct Type : Get_type {}; +#define CGAL_Kernel_obj(X,Y) \ + template struct Type { typedef Ref_count_obj type; }; + + CGAL_Kernel_obj(Point,point) + CGAL_Kernel_obj(Vector,vector) +#undef CGAL_Kernel_obj + + template struct Dispatch { + //typedef typename map_functor_type::type f_t; + typedef typename map_result_tag::type r_t; + enum { + is_nul = boost::is_same::type,Null_functor>::value, + ret_rcobj = boost::is_same::value || boost::is_same::value + }; + }; + + //Translate the arguments + template::is_nul,bool=Dispatch::ret_rcobj> struct Functor { + typedef typename Get_functor::type B; + struct type { + B b; + type(){} + type(Self const&k):b(k){} + typedef typename B::result_type result_type; +#ifdef CGAL_CXX11 + template result_type operator()(U&&...u)const{ + return b(internal::Forward_rep()(u)...); + } +#else + result_type operator()()const{ + return b(); + } +#define CGAL_VAR(Z,N,_) internal::Forward_rep()(u##N) +#define CGAL_CODE(Z,N,_) template result_type \ + operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,U,const&u))const{ \ + return b(BOOST_PP_ENUM(N,CGAL_VAR,)); \ + } + BOOST_PP_REPEAT_FROM_TO(1,11,CGAL_CODE,_) +#undef CGAL_CODE +#undef CGAL_VAR +#endif + }; + }; + + //Translate both the arguments and the result + template struct Functor { + typedef Null_functor type; + }; + + template struct Functor { + typedef typename Get_functor::type B; + struct type { + B b; + type(){} + type(Self const&k):b(k){} + typedef typename map_result_tag::type result_tag; + typedef typename Get_type::type result_type; +#ifdef CGAL_CXX11 + template result_type operator()(U&&...u)const{ + return result_type(Eval_functor(),b,internal::Forward_rep()(u)...); + } +#else + result_type operator()()const{ + return result_type(Eval_functor(),b); + } +#define CGAL_VAR(Z,N,_) internal::Forward_rep()(u##N) +#define CGAL_CODE(Z,N,_) template result_type \ + operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,U,const&u))const{ \ + return result_type(Eval_functor(),b,BOOST_PP_ENUM(N,CGAL_VAR,)); \ + } + BOOST_PP_REPEAT_FROM_TO(1,11,CGAL_CODE,_) +#undef CGAL_CODE +#undef CGAL_VAR +#endif + }; + }; + +}; + +} //namespace CGAL + +#endif // CGAL_KERNEL_D_CARTESIAN_WRAP_H diff -Nru cgal-4.4/include/CGAL/NewKernel_d/Wrapper/Hyperplane_d.h cgal-4.5/include/CGAL/NewKernel_d/Wrapper/Hyperplane_d.h --- cgal-4.4/include/CGAL/NewKernel_d/Wrapper/Hyperplane_d.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/Wrapper/Hyperplane_d.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,131 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_WRAPPER_HYPERPLANE_D_H +#define CGAL_WRAPPER_HYPERPLANE_D_H + +#include +#include +#include +#include +#include +#ifndef CGAL_CXX11 +#include +#endif +#include + +namespace CGAL { +namespace Wrap { + +template +class Hyperplane_d : public Get_type::type +{ + typedef typename Get_type::type FT_; + typedef typename R_::Kernel_base Kbase; + typedef typename Get_type::type Vector_; + typedef typename Get_functor >::type CHBase; + typedef typename Get_functor::type OVBase; + typedef typename Get_functor::type HTBase; + + typedef Hyperplane_d Self; + BOOST_STATIC_ASSERT((boost::is_same::type>::value)); + +public: + + typedef Tag_true Is_wrapper; + typedef typename R_::Default_ambient_dimension Ambient_dimension; + typedef typename Increment_dimension::type Feature_dimension; + + typedef typename Get_type::type Rep; + + const Rep& rep() const + { + return *this; + } + + Rep& rep() + { + return *this; + } + + typedef R_ R; + +#ifdef CGAL_CXX11 + template::type...>,std::tuple >::value>::type> explicit Hyperplane_d(U&&...u) + : Rep(CHBase()(std::forward(u)...)){} + +// // called from Construct_point_d +// template explicit Point_d(Eval_functor&&,U&&...u) +// : Rep(Eval_functor(), std::forward(u)...){} + template explicit Hyperplane_d(Eval_functor&&,F&&f,U&&...u) + : Rep(std::forward(f)(std::forward(u)...)){} + +#if 0 + // the new standard may make this necessary + Point_d(Point_d const&)=default; + Point_d(Point_d &);//=default; + Point_d(Point_d &&)=default; +#endif + + // try not to use these + Hyperplane_d(Rep const& v) : Rep(v) {} + Hyperplane_d(Rep& v) : Rep(static_cast(v)) {} + Hyperplane_d(Rep&& v) : Rep(std::move(v)) {} + +#else + + Hyperplane_d() : Rep(CHBase()()) {} + + Hyperplane_d(Rep const& v) : Rep(v) {} // try not to use it + +#define CGAL_CODE(Z,N,_) template \ + explicit Hyperplane_d(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \ + : Rep(CHBase()( \ + BOOST_PP_ENUM_PARAMS(N,t))) {} \ + \ + template \ + Hyperplane_d(Eval_functor,F const& f,BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \ + : Rep(f(BOOST_PP_ENUM_PARAMS(N,t))) {} + /* + template \ + Point_d(Eval_functor,BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \ + : Rep(Eval_functor(), BOOST_PP_ENUM_PARAMS(N,t)) {} + */ + + BOOST_PP_REPEAT_FROM_TO(1,11,CGAL_CODE,_) +#undef CGAL_CODE + +#endif + + //TODO: if OVBase returns a reference to a base vector, cast it to a + //reference to a wrapper vector. Ugly but should be safe. + Vector_ orthogonal_vector()const{ + return Vector_(Eval_functor(),OVBase(),rep()); + } + FT_ translation()const{ + return HTBase()(rep()); + } + + +}; + +} //namespace Wrap +} //namespace CGAL + +#endif // CGAL_WRAPPER_SPHERE_D_H diff -Nru cgal-4.4/include/CGAL/NewKernel_d/Wrapper/Point_d.h cgal-4.5/include/CGAL/NewKernel_d/Wrapper/Point_d.h --- cgal-4.4/include/CGAL/NewKernel_d/Wrapper/Point_d.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/Wrapper/Point_d.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,281 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_WRAPPER_POINT_D_H +#define CGAL_WRAPPER_POINT_D_H + +#include +#include +#include +#include +#include +#include +#include +#ifndef CGAL_CXX11 +#include +#endif +#include + +namespace CGAL { +namespace Wrap { + +template +class Point_d : public Get_type::type + // Deriving won't work if the point is just a __m256d. + // Test boost/std::is_class for instance +{ + typedef typename Get_type::type RT_; + typedef typename Get_type::type FT_; + typedef typename R_::Kernel_base Kbase; + typedef typename Get_type::type Vector_; + typedef typename Get_functor >::type CPBase; + typedef typename Get_functor::type CCBase; + typedef typename Get_functor >::type CPI; + + + typedef Point_d Self; + BOOST_STATIC_ASSERT((boost::is_same::type>::value)); + +public: + + typedef Tag_true Is_wrapper; + typedef typename R_::Default_ambient_dimension Ambient_dimension; + typedef Dimension_tag<0> Feature_dimension; + + typedef typename Get_type::type Rep; + //typedef typename CGAL::decay::type>::type Cartesian_const_iterator; + + const Rep& rep() const + { + return *this; + } + + Rep& rep() + { + return *this; + } + + typedef R_ R; + +#ifdef CGAL_CXX11 + template::type...>,std::tuple >::value>::type> explicit Point_d(U&&...u) + : Rep(CPBase()(std::forward(u)...)){} + +// // called from Construct_point_d +// template explicit Point_d(Eval_functor&&,U&&...u) +// : Rep(Eval_functor(), std::forward(u)...){} + template explicit Point_d(Eval_functor&&,F&&f,U&&...u) + : Rep(std::forward(f)(std::forward(u)...)){} + +#if 0 + // the new standard may make this necessary + Point_d(Point_d const&)=default; + Point_d(Point_d &);//=default; + Point_d(Point_d &&)=default; +#endif + + // try not to use these + Point_d(Rep const& v) : Rep(v) {} + Point_d(Rep& v) : Rep(static_cast(v)) {} + Point_d(Rep&& v) : Rep(std::move(v)) {} + + // this one should be implicit + Point_d(Origin const& v) + : Rep(CPBase()(v)) {} + Point_d(Origin& v) + : Rep(CPBase()(v)) {} + Point_d(Origin&& v) + : Rep(CPBase()(std::move(v))) {} + +#else + + Point_d() : Rep(CPBase()()) {} + + Point_d(Rep const& v) : Rep(v) {} // try not to use it + +#define CGAL_CODE(Z,N,_) template \ + explicit Point_d(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \ + : Rep(CPBase()( \ + BOOST_PP_ENUM_PARAMS(N,t))) {} \ + \ + template \ + Point_d(Eval_functor,F const& f,BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \ + : Rep(f(BOOST_PP_ENUM_PARAMS(N,t))) {} + /* + template \ + Point_d(Eval_functor,BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \ + : Rep(Eval_functor(), BOOST_PP_ENUM_PARAMS(N,t)) {} + */ + + BOOST_PP_REPEAT_FROM_TO(1,11,CGAL_CODE,_) +#undef CGAL_CODE + + // this one should be implicit + Point_d(Origin const& o) + : Rep(CPBase()(o)) {} + +#endif + + typename boost::result_of::type cartesian(int i)const{ + return CCBase()(rep(),i); + } + typename boost::result_of::type operator[](int i)const{ + return CCBase()(rep(),i); + } + + typename boost::result_of::type cartesian_begin()const{ + return CPI()(rep(),Begin_tag()); + } + + typename boost::result_of::type cartesian_end()const{ + return CPI()(rep(),End_tag()); + } + + /* + Direction_d direction() const + { + return R().construct_direction_d_object()(*this); + } + + Vector_d transform(const Aff_transformation_d &t) const + { + return t.transform(*this); + } + + Vector_d operator/(const RT& c) const + { + return R().construct_divided_vector_d_object()(*this,c); + } + + Vector_d operator/(const typename First_if_different::Type & c) const + { + return R().construct_divided_vector_d_object()(*this,c); + } + + typename Qualified_result_of::type + x() const + { + return R().compute_x_3_object()(*this); + } + + typename Qualified_result_of::type + y() const + { + return R().compute_y_3_object()(*this); + } + + typename Qualified_result_of::type + z() const + { + return R().compute_z_3_object()(*this); + } + + typename Qualified_result_of::type + hx() const + { + return R().compute_hx_3_object()(*this); + } + + typename Qualified_result_of::type + hy() const + { + return R().compute_hy_3_object()(*this); + } + + typename Qualified_result_of::type + hz() const + { + return R().compute_hz_3_object()(*this); + } + + typename Qualified_result_of::type + hw() const + { + return R().compute_hw_3_object()(*this); + } + + typename Qualified_result_of::type + cartesian(int i) const + { + CGAL_kernel_precondition( (i == 0) || (i == 1) || (i == 2) ); + if (i==0) return x(); + if (i==1) return y(); + return z(); + } + + typename Qualified_result_of::type + homogeneous(int i) const + { + CGAL_kernel_precondition( (i >= 0) || (i <= 3) ); + if (i==0) return hx(); + if (i==1) return hy(); + if (i==2) return hz(); + return hw(); + } + + int dimension() const // bad idea? + { + return rep.dimension(); + } + + typename Qualified_result_of::type + operator[](int i) const + { + return cartesian(i); + } + + Cartesian_const_iterator cartesian_begin() const + { + return typename R::Construct_cartesian_const_iterator_3()(*this); + } + + Cartesian_const_iterator cartesian_end() const + { + return typename R::Construct_cartesian_const_iterator_3()(*this,3); + } + + typename Qualified_result_of::type + squared_length() const + { + return R().compute_squared_length_3_object()(*this); + } +*/ +}; +#if 0 +template Point_d::Point_d(Point_d &)=default; +#endif + +//TODO: IO + +//template +//Vector_d operator+(const Vector_d& v,const Vector_d& w) const +//{ +// return typename R::template Construct::type()(v,w); +//} +// +//template +//Vector_d operator-(const Vector_d& v,const Vector_d& w) const +//{ +// return typename R::template Construct::type()(v,w); +//} + +} //namespace Wrap +} //namespace CGAL + +#endif // CGAL_WRAPPER_POINT_D_H diff -Nru cgal-4.4/include/CGAL/NewKernel_d/Wrapper/Ref_count_obj.h cgal-4.5/include/CGAL/NewKernel_d/Wrapper/Ref_count_obj.h --- cgal-4.4/include/CGAL/NewKernel_d/Wrapper/Ref_count_obj.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/Wrapper/Ref_count_obj.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,120 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_WRAPPER_REF_COUNT_OBJ_H +#define CGAL_WRAPPER_REF_COUNT_OBJ_H + +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef CGAL_CXX11 +#include +#endif +#include + +// no need for a fancy interface here, people can use the Point_d wrapper on +// top. + +namespace CGAL { + +template +class Ref_count_obj +{ + typedef typename R_::Kernel_base Kbase; + typedef typename Get_functor >::type CBase; + + typedef Ref_count_obj Self; + BOOST_STATIC_ASSERT((boost::is_same::type>::value)); + +public: + typedef R_ R; + + typedef Tag_true Is_wrapper; + typedef typename R_::Default_ambient_dimension Ambient_dimension; + //typedef Dimension_tag<0> Feature_dimension; + + typedef typename Get_type::type Rep; + typedef Handle_for Data; + +private: + Data data; +public: + + const Rep& rep() const + { + return CGAL::get(data); + } + +#ifdef CGAL_CXX11 + template::type...>,std::tuple >::value>::type> explicit Ref_count_obj(U&&...u) + : data(Eval_functor(),CBase(),std::forward(u)...){} + + template explicit Ref_count_obj(Eval_functor&&,F&&f,U&&...u) + : data(Eval_functor(),std::forward(f),std::forward(u)...){} + + // try not to use these + Ref_count_obj(Rep const& v) : data(v) {} + Ref_count_obj(Rep& v) : data(static_cast(v)) {} + Ref_count_obj(Rep&& v) : data(std::move(v)) {} + + // Do we really need this for point? +// // this one should be implicit +// Ref_count_obj(Origin const& v) +// : data(Eval_functor(),CBase(),v) {} +// Ref_count_obj(Origin& v) +// : data(Eval_functor(),CBase(),v) {} +// Ref_count_obj(Origin&& v) +// : data(Eval_functor(),CBase(),std::move(v)) {} + +#else + + Ref_count_obj() : data(Eval_functor(),CBase()) {} + + Ref_count_obj(Rep const& v) : data(v) {} // try not to use it + +#define CGAL_CODE(Z,N,_) template \ + explicit Ref_count_obj(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \ + : data(Eval_functor(),CBase(),BOOST_PP_ENUM_PARAMS(N,t)) {} \ + \ + template \ + Ref_count_obj(Eval_functor,F const& f,BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \ + : data(Eval_functor(),f,BOOST_PP_ENUM_PARAMS(N,t)) {} + + BOOST_PP_REPEAT_FROM_TO(1,11,CGAL_CODE,_) +#undef CGAL_CODE + template + Ref_count_obj(Eval_functor,F const& f) + : data(Eval_functor(),f) {} + +// // this one should be implicit +// Ref_count_obj(Origin const& o) +// : data(Eval_functor(),CBase(),o) {} + +#endif + +}; + +} //namespace CGAL + +#endif diff -Nru cgal-4.4/include/CGAL/NewKernel_d/Wrapper/Segment_d.h cgal-4.5/include/CGAL/NewKernel_d/Wrapper/Segment_d.h --- cgal-4.4/include/CGAL/NewKernel_d/Wrapper/Segment_d.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/Wrapper/Segment_d.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,133 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_WRAPPER_SEGMENT_D_H +#define CGAL_WRAPPER_SEGMENT_D_H + +#include +#include +#include +#include +#include +#include +#include +#ifndef CGAL_CXX11 +#include +#endif +#include + +namespace CGAL { +namespace Wrap { + +template +class Segment_d : public Get_type::type +{ + typedef typename Get_type::type RT_; + typedef typename Get_type::type FT_; + typedef typename R_::Kernel_base Kbase; + typedef typename Get_type::type Point_; + typedef typename Get_functor >::type CPBase; + typedef typename Get_functor >::type CSBase; + typedef typename Get_functor::type CSEBase; + + typedef Segment_d Self; + BOOST_STATIC_ASSERT((boost::is_same::type>::value)); + +public: + + typedef Tag_true Is_wrapper; + typedef typename R_::Default_ambient_dimension Ambient_dimension; + typedef Dimension_tag<1> Feature_dimension; + + typedef typename Get_type::type Rep; + + const Rep& rep() const + { + return *this; + } + + Rep& rep() + { + return *this; + } + + typedef R_ R; + +#ifdef CGAL_CXX11 + template::type...>,std::tuple >::value>::type> explicit Segment_d(U&&...u) + : Rep(CSBase()(std::forward(u)...)){} + +// // called from Construct_point_d +// template explicit Point_d(Eval_functor&&,U&&...u) +// : Rep(Eval_functor(), std::forward(u)...){} + template explicit Segment_d(Eval_functor&&,F&&f,U&&...u) + : Rep(std::forward(f)(std::forward(u)...)){} + +#if 0 + // the new standard may make this necessary + Point_d(Point_d const&)=default; + Point_d(Point_d &);//=default; + Point_d(Point_d &&)=default; +#endif + + // try not to use these + Segment_d(Rep const& v) : Rep(v) {} + Segment_d(Rep& v) : Rep(static_cast(v)) {} + Segment_d(Rep&& v) : Rep(std::move(v)) {} + +#else + + Segment_d() : Rep(CSBase()()) {} + + Segment_d(Rep const& v) : Rep(v) {} // try not to use it + +#define CGAL_CODE(Z,N,_) template \ + explicit Segment_d(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \ + : Rep(CSBase()( \ + BOOST_PP_ENUM_PARAMS(N,t))) {} \ + \ + template \ + Segment_d(Eval_functor,F const& f,BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \ + : Rep(f(BOOST_PP_ENUM_PARAMS(N,t))) {} + /* + template \ + Point_d(Eval_functor,BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \ + : Rep(Eval_functor(), BOOST_PP_ENUM_PARAMS(N,t)) {} + */ + + BOOST_PP_REPEAT_FROM_TO(1,11,CGAL_CODE,_) +#undef CGAL_CODE + +#endif + + //TODO: if CSEBase returns a reference to a base point, cast it to a + //reference to a wrapper point. Ugly but should be safe. + Point_ source()const{ + return Point_(Eval_functor(),CSEBase(),rep(),0); + } + Point_ target()const{ + return Point_(Eval_functor(),CSEBase(),rep(),1); + } + +}; + +} //namespace Wrap +} //namespace CGAL + +#endif // CGAL_WRAPPER_SEGMENT_D_H diff -Nru cgal-4.4/include/CGAL/NewKernel_d/Wrapper/Sphere_d.h cgal-4.5/include/CGAL/NewKernel_d/Wrapper/Sphere_d.h --- cgal-4.4/include/CGAL/NewKernel_d/Wrapper/Sphere_d.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/Wrapper/Sphere_d.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,130 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_WRAPPER_SPHERE_D_H +#define CGAL_WRAPPER_SPHERE_D_H + +#include +#include +#include +#include +#include +#ifndef CGAL_CXX11 +#include +#endif +#include + +namespace CGAL { +namespace Wrap { + +template +class Sphere_d : public Get_type::type +{ + typedef typename Get_type::type FT_; + typedef typename R_::Kernel_base Kbase; + typedef typename Get_type::type Point_; + typedef typename Get_functor >::type CSBase; + typedef typename Get_functor::type COSBase; + typedef typename Get_functor::type SRBase; + + typedef Sphere_d Self; + BOOST_STATIC_ASSERT((boost::is_same::type>::value)); + +public: + + typedef Tag_true Is_wrapper; + typedef typename R_::Default_ambient_dimension Ambient_dimension; + typedef typename Increment_dimension::type Feature_dimension; + + typedef typename Get_type::type Rep; + + const Rep& rep() const + { + return *this; + } + + Rep& rep() + { + return *this; + } + + typedef R_ R; + +#ifdef CGAL_CXX11 + template::type...>,std::tuple >::value>::type> explicit Sphere_d(U&&...u) + : Rep(CSBase()(std::forward(u)...)){} + +// // called from Construct_point_d +// template explicit Point_d(Eval_functor&&,U&&...u) +// : Rep(Eval_functor(), std::forward(u)...){} + template explicit Sphere_d(Eval_functor&&,F&&f,U&&...u) + : Rep(std::forward(f)(std::forward(u)...)){} + +#if 0 + // the new standard may make this necessary + Point_d(Point_d const&)=default; + Point_d(Point_d &);//=default; + Point_d(Point_d &&)=default; +#endif + + // try not to use these + Sphere_d(Rep const& v) : Rep(v) {} + Sphere_d(Rep& v) : Rep(static_cast(v)) {} + Sphere_d(Rep&& v) : Rep(std::move(v)) {} + +#else + + Sphere_d() : Rep(CSBase()()) {} + + Sphere_d(Rep const& v) : Rep(v) {} // try not to use it + +#define CGAL_CODE(Z,N,_) template \ + explicit Sphere_d(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \ + : Rep(CSBase()( \ + BOOST_PP_ENUM_PARAMS(N,t))) {} \ + \ + template \ + Sphere_d(Eval_functor,F const& f,BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \ + : Rep(f(BOOST_PP_ENUM_PARAMS(N,t))) {} + /* + template \ + Point_d(Eval_functor,BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \ + : Rep(Eval_functor(), BOOST_PP_ENUM_PARAMS(N,t)) {} + */ + + BOOST_PP_REPEAT_FROM_TO(1,11,CGAL_CODE,_) +#undef CGAL_CODE + +#endif + + //TODO: if COSBase returns a reference to a base point, cast it to a + //reference to a wrapper point. Ugly but should be safe. + Point_ center()const{ + return Point_(Eval_functor(),COSBase(),rep()); + } + FT_ squared_radius()const{ + return SRBase()(rep()); + } + +}; + +} //namespace Wrap +} //namespace CGAL + +#endif // CGAL_WRAPPER_SPHERE_D_H diff -Nru cgal-4.4/include/CGAL/NewKernel_d/Wrapper/Vector_d.h cgal-4.5/include/CGAL/NewKernel_d/Wrapper/Vector_d.h --- cgal-4.4/include/CGAL/NewKernel_d/Wrapper/Vector_d.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/NewKernel_d/Wrapper/Vector_d.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,268 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_WRAPPER_VECTOR_D_H +#define CGAL_WRAPPER_VECTOR_D_H + +#include +#include +#include +#include +#include +#include +#include +#ifndef CGAL_CXX11 +#include +#endif +#include + +namespace CGAL { +namespace Wrap { + +template +class Vector_d : public Get_type::type +{ + typedef typename Get_type::type RT_; + typedef typename Get_type::type FT_; + typedef typename R_::Kernel_base Kbase; + typedef typename Get_type::type Point_; + typedef typename Get_functor >::type CVBase; + typedef typename Get_functor::type CCBase; + typedef typename Get_functor >::type CVI; + + typedef Vector_d Self; + BOOST_STATIC_ASSERT((boost::is_same::type>::value)); + +public: + + typedef Tag_true Is_wrapper; + typedef typename R_::Default_ambient_dimension Ambient_dimension; + typedef Dimension_tag<0> Feature_dimension; + + //typedef typename R_::Vector_cartesian_const_iterator Cartesian_const_iterator; + typedef typename Get_type::type Rep; + + const Rep& rep() const + { + return *this; + } + + Rep& rep() + { + return *this; + } + + typedef R_ R; + +#ifdef CGAL_CXX11 + template::type...>,std::tuple >::value>::type> explicit Vector_d(U&&...u) + : Rep(CVBase()(std::forward(u)...)){} + +// // called from Construct_vector_d +// template explicit Vector_d(Eval_functor&&,U&&...u) +// : Rep(Eval_functor(), std::forward(u)...){} + template explicit Vector_d(Eval_functor&&,F&&f,U&&...u) + : Rep(std::forward(f)(std::forward(u)...)){} + +#if 0 + // the new standard may make this necessary + Vector_d(Vector_d const&)=default; + Vector_d(Vector_d &);//=default; + Vector_d(Vector_d &&)=default; +#endif + + // try not to use these + Vector_d(Rep const& v) : Rep(v) {} + Vector_d(Rep& v) : Rep(static_cast(v)) {} + Vector_d(Rep&& v) : Rep(std::move(v)) {} + + // this one should be implicit + Vector_d(Null_vector const& v) + : Rep(CVBase()(v)) {} + Vector_d(Null_vector& v) + : Rep(CVBase()(v)) {} + Vector_d(Null_vector&& v) + : Rep(CVBase()(std::move(v))) {} + +#else + + Vector_d() : Rep(CVBase()()) {} + + Vector_d(Rep const& v) : Rep(v) {} // try not to use it + +#define CGAL_CODE(Z,N,_) template \ + explicit Vector_d(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \ + : Rep(CVBase()( \ + BOOST_PP_ENUM_PARAMS(N,t))) {} \ + \ + template \ + Vector_d(Eval_functor,F const& f,BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \ + : Rep(f(BOOST_PP_ENUM_PARAMS(N,t))) {} + /* + template \ + Vector_d(Eval_functor,BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \ + : Rep(Eval_functor(), BOOST_PP_ENUM_PARAMS(N,t)) {} + */ + + BOOST_PP_REPEAT_FROM_TO(1,11,CGAL_CODE,_) +#undef CGAL_CODE + + // this one should be implicit + Vector_d(Null_vector const& v) + : Rep(CVBase()(v)) {} + +#endif + + typename boost::result_of::type cartesian(int i)const{ + return CCBase()(rep(),i); + } + + typename boost::result_of::type operator[](int i)const{ + return CCBase()(rep(),i); + } + + typename boost::result_of::type cartesian_begin()const{ + return CVI()(rep(),Begin_tag()); + } + + typename boost::result_of::type cartesian_end()const{ + return CVI()(rep(),End_tag()); + } + + Vector_d operator-() const + { + return typename Get_functor::type()(*this); + } + + /* + Direction_d direction() const + { + return R().construct_direction_d_object()(*this); + } + + Vector_d transform(const Aff_transformation_d &t) const + { + return t.transform(*this); + } + + Vector_d operator/(const RT& c) const + { + return R().construct_divided_vector_d_object()(*this,c); + } + + Vector_d operator/(const typename First_if_different::Type & c) const + { + return R().construct_divided_vector_d_object()(*this,c); + } + + typename Qualified_result_of::type + x() const + { + return R().compute_x_3_object()(*this); + } + + typename Qualified_result_of::type + y() const + { + return R().compute_y_3_object()(*this); + } + + typename Qualified_result_of::type + z() const + { + return R().compute_z_3_object()(*this); + } + + typename Qualified_result_of::type + hx() const + { + return R().compute_hx_3_object()(*this); + } + + typename Qualified_result_of::type + hy() const + { + return R().compute_hy_3_object()(*this); + } + + typename Qualified_result_of::type + hz() const + { + return R().compute_hz_3_object()(*this); + } + + typename Qualified_result_of::type + hw() const + { + return R().compute_hw_3_object()(*this); + } + + typename Qualified_result_of::type + cartesian(int i) const + { + CGAL_kernel_precondition( (i == 0) || (i == 1) || (i == 2) ); + if (i==0) return x(); + if (i==1) return y(); + return z(); + } + + typename Qualified_result_of::type + homogeneous(int i) const + { + CGAL_kernel_precondition( (i >= 0) || (i <= 3) ); + if (i==0) return hx(); + if (i==1) return hy(); + if (i==2) return hz(); + return hw(); + } + + int dimension() const // bad idea? + { + return rep.dimension(); + } + + typename Qualified_result_of::type + squared_length() const + { + return R().compute_squared_length_3_object()(*this); + } +*/ +}; +#if 0 +template Vector_d::Vector_d(Vector_d &)=default; +#endif + +//TODO: IO + +template +Vector_d operator+(const Vector_d& v,const Vector_d& w) +{ + return typename Get_functor::type()(v,w); +} + +template +Vector_d operator-(const Vector_d& v,const Vector_d& w) +{ + return typename Get_functor::type()(v,w); +} + +} //namespace Wrap +} //namespace CGAL + +#endif // CGAL_WRAPPER_VECTOR_D_H diff -Nru cgal-4.4/include/CGAL/Number_type_checker.h cgal-4.5/include/CGAL/Number_type_checker.h --- cgal-4.4/include/CGAL/Number_type_checker.h 2012-11-13 13:13:59.000000000 +0000 +++ cgal-4.5/include/CGAL/Number_type_checker.h 2014-08-29 13:58:16.000000000 +0000 @@ -26,6 +26,7 @@ #define CGAL_NUMBER_TYPE_CHECKER_H #include +#include // A number type class, parameterized by 2 number types NT1 and NT2. // It runs all operations on parallel over NT1 and NT2. @@ -926,7 +927,9 @@ operator>> (std::istream & is, Number_type_checker &b) { is >> b.n1(); - b.n2() = b.n1(); // We hope that there is a conversion. + std::stringstream ss; + ss << b.n1(); + ss >> b.n2(); return is; } diff -Nru cgal-4.4/include/CGAL/OFF_to_nef_3.h cgal-4.5/include/CGAL/OFF_to_nef_3.h --- cgal-4.4/include/CGAL/OFF_to_nef_3.h 2012-11-13 13:13:58.000000000 +0000 +++ cgal-4.5/include/CGAL/OFF_to_nef_3.h 2014-08-29 13:58:16.000000000 +0000 @@ -23,26 +23,28 @@ #include + + // --- begin preliminary number type converter ----------------- #ifndef CGAL_NUMBER_TYPE_CONVERTER_NEF_3_H #define CGAL_NUMBER_TYPE_CONVERTER_NEF_3_H #include -#include -#include +#include +#include +#include #include #include #include #include -#ifdef CGAL_USE_LEDA -#include -#include -#endif // CGAL_USE_LEDA - namespace CGAL { + +typedef CGAL::Exact_integer Integer; +typedef CGAL::Exact_rational Rational; + class Homogeneous_tag; class Cartesian_tag; template class number_type_converter_nef_3; @@ -55,15 +57,21 @@ { typedef typename Kernel::Point_3 Point_3; typedef typename Kernel::RT RT; - - CGAL::Gmpq x(d.x()), y(d.y()), z(d.z()); - - CGAL::Homogeneous::Point_3 b = - normalized ( CGAL::Homogeneous::Point_3 ( - x.numerator() * y.denominator() * z.denominator(), - x.denominator() * y.numerator() * z.denominator(), - x.denominator() * y.denominator() * z.numerator(), - x.denominator() * y.denominator() * z.denominator() ) ); + + typedef Fraction_traits F_traits; + + Rational x(d.x()), y(d.y()), z(d.z()); + Integer xn, xd, yn, yd, zn, zd; + typename F_traits::Decompose decompose; + decompose(x, xn, xd); + decompose(y, yn, yd); + decompose(z, zn, zd); + CGAL::Homogeneous::Point_3 b = + normalized ( CGAL::Homogeneous::Point_3 ( + xn * yd * zd, + xd * yn * zd, + xd * yd * zn, + xd * yd * zd ) ); std::ostringstream outx, outy, outz, outw; outx << b.hx(); diff -Nru cgal-4.4/include/CGAL/orient_polygon_soup.h cgal-4.5/include/CGAL/orient_polygon_soup.h --- cgal-4.4/include/CGAL/orient_polygon_soup.h 2013-06-29 19:00:35.000000000 +0000 +++ cgal-4.5/include/CGAL/orient_polygon_soup.h 2014-08-29 13:58:16.000000000 +0000 @@ -19,8 +19,8 @@ // Author(s) : Laurent Rineau and Ilker O. Yaz -#ifndef CGAL_ORIENT_POLYHEDRON_3 -#define CGAL_ORIENT_POLYHEDRON_3 +#ifndef CGAL_ORIENT_POLYGON_SOUP +#define CGAL_ORIENT_POLYGON_SOUP #include #include #include @@ -171,7 +171,8 @@ const std::size_t& i0 = polygons[index][j]; const std::size_t& i1 = polygons[index][ j+1 < size ? j+1: 0]; CGAL_assertion_code(const bool r = ) - edges[std::make_pair(i0, i1)].erase(index); + edges[std::make_pair(i0, i1)].erase(index) + CGAL_assertion_code(!= 0); CGAL_assertion(r); } inverse_orientation(index); @@ -279,4 +280,4 @@ }// namespace CGAL -#endif // CGAL_ORIENT_POLYHEDRON_3 +#endif // CGAL_ORIENT_POLYGON_SOUP diff -Nru cgal-4.4/include/CGAL/orient_polyhedron_3.h cgal-4.5/include/CGAL/orient_polyhedron_3.h --- cgal-4.4/include/CGAL/orient_polyhedron_3.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/orient_polyhedron_3.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,77 @@ +// Copyright (c) 2013 GeometryFactory (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Ilker O. Yaz + + +#ifndef CGAL_ORIENT_POLYHEDRON_3 +#define CGAL_ORIENT_POLYHEDRON_3 + +#include +#include + +namespace CGAL { +namespace internal { + +template +struct Axis_compare { + template + bool operator()(const Vertex& v0, const Vertex& v1) const + { return v0.point()[axis] < v1.point()[axis]; } +}; + +} // namespace internal + +/** + * Tests whether a closed polyhedron has a positive orientation. + * A polyhedron is considered to have positive orientation if the normal vectors + * of the facets point outside of the polyhedron. For each facet, its normal vector + * is considered to point on the side of the facet where the sequence of vertices of + * the facet is seen counterclockwise. + * @pre @a `polyhedron`.is_closed() + * @pre @a `polyhedron` is consistently oriented + * + * @tparam Polyhedron a %CGAL polyhedron + * + * @param polyhedron a closed polyhedron to be tested + * + * \todo The following only handle polyhedron with one connected component + * the code, the sample example and the plugin must be updated. + * @code + * // use inside out to fix orientation + * if(!is_oriented(polyhedron)) { + * polyhedron.inside_out(); + * } + * @endcode + */ +template +bool is_oriented(const Polyhedron& polyhedron) { + CGAL_precondition(polyhedron.is_closed()); + const unsigned int axis = 0; + + typename Polyhedron::Vertex_const_iterator v_min + = std::min_element(polyhedron.vertices_begin(), polyhedron.vertices_end(), internal::Axis_compare()); + + typedef typename Polyhedron::Traits K; + const typename K::Vector_3& normal_v_min = compute_vertex_normal(*v_min); + + CGAL_warning(normal_v_min[axis] != 0); + return normal_v_min[axis] < 0; +} +} // namespace CGAL +#endif // CGAL_ORIENT_POLYHEDRON_3 diff -Nru cgal-4.4/include/CGAL/Periodic_3_triangulation_3.h cgal-4.5/include/CGAL/Periodic_3_triangulation_3.h --- cgal-4.4/include/CGAL/Periodic_3_triangulation_3.h 2013-05-25 19:00:28.000000000 +0000 +++ cgal-4.5/include/CGAL/Periodic_3_triangulation_3.h 2014-08-29 13:58:16.000000000 +0000 @@ -53,6 +53,11 @@ #include #include +#ifndef CGAL_NO_STRUCTURAL_FILTERING +#include +#include +#endif // no CGAL_NO_STRUCTURAL_FILTERING + namespace CGAL { template < class GT, class TDS > class Periodic_3_triangulation_3; @@ -62,6 +67,28 @@ template < class GT, class TDS > std::ostream& operator<< (std::ostream& os, const Periodic_3_triangulation_3 &tr); +#ifndef CGAL_NO_STRUCTURAL_FILTERING +namespace internal { +// structural filtering is performed only for EPIC +struct Periodic_structural_filtering_3_tag {}; +struct No_periodic_structural_filtering_3_tag {}; + +template +struct Periodic_structural_filtering_selector_3 { +#ifdef FORCE_STRUCTURAL_FILTERING + typedef Periodic_structural_filtering_3_tag Tag; +#else + typedef No_periodic_structural_filtering_3_tag Tag; +#endif +}; + +template <> +struct Periodic_structural_filtering_selector_3 { + typedef Periodic_structural_filtering_3_tag Tag; +}; +} +#endif // no CGAL_NO_STRUCTURAL_FILTERING + /**\class Periodic_3_triangulation_3 * * \brief Implements functionality for computing in periodic space. @@ -766,11 +793,121 @@ return _tds.are_equal(f.first, f.second, n, j); } //@} - + +#ifdef CGAL_NO_STRUCTURAL_FILTERING + Cell_handle + periodic_locate(const Point & p, const Offset &o_p, + Locate_type & lt, int & li, int & lj, + Cell_handle start = Cell_handle()) const; +#else // no CGAL_NO_STRUCTURAL_FILTERING +# ifndef CGAL_PT3_STRUCTURAL_FILTERING_MAX_VISITED_CELLS +# define CGAL_PT3_STRUCTURAL_FILTERING_MAX_VISITED_CELLS 2500 +# endif // no CGAL_PT3_STRUCTURAL_FILTERING_MAX_VISITED_CELLS + +public: + Cell_handle + inexact_periodic_locate(const Point& p, const Offset &o_p, + Cell_handle start = Cell_handle(), + int max_num_cells = CGAL_PT3_STRUCTURAL_FILTERING_MAX_VISITED_CELLS) const; +protected: + Cell_handle + exact_periodic_locate(const Point& p, const Offset &o_p, + Locate_type& lt, + int& li, int & lj, + Cell_handle start) const; + + Cell_handle + generic_periodic_locate(const Point& p, const Offset &o_p, + Locate_type& lt, + int& li, int & lj, + Cell_handle start, + internal::Periodic_structural_filtering_3_tag) const { + return exact_periodic_locate(p, o_p, lt, li, lj, inexact_periodic_locate(p, o_p, start)); + } + + Cell_handle + generic_periodic_locate(const Point& p, const Offset &o_p, + Locate_type& lt, + int& li, int & lj, + Cell_handle start, + internal::No_periodic_structural_filtering_3_tag) const { + return exact_periodic_locate(p, o_p, lt, li, lj, start); + } + + Orientation + inexact_orientation(const Point &p, const Point &q, + const Point &r, const Point &s) const + { + const double px = to_double(p.x()); + const double py = to_double(p.y()); + const double pz = to_double(p.z()); + const double qx = to_double(q.x()); + const double qy = to_double(q.y()); + const double qz = to_double(q.z()); + const double rx = to_double(r.x()); + const double ry = to_double(r.y()); + const double rz = to_double(r.z()); + const double sx = to_double(s.x()); + const double sy = to_double(s.y()); + const double sz = to_double(s.z()); + + const double pqx = qx - px; + const double pqy = qy - py; + const double pqz = qz - pz; + const double prx = rx - px; + const double pry = ry - py; + const double prz = rz - pz; + const double psx = sx - px; + const double psy = sy - py; + const double psz = sz - pz; + + const double det = determinant(pqx, pqy, pqz, + prx, pry, prz, + psx, psy, psz); + if (det > 0) return POSITIVE; + if (det < 0) return NEGATIVE; + return ZERO; + } + + Orientation + inexact_orientation(const Point &p, const Point &q, + const Point &r, const Point &s, + const Offset& o_p, const Offset& o_q, + const Offset& o_r, const Offset& o_s) const + { + return inexact_orientation(construct_point(p, o_p), + construct_point(q, o_q), + construct_point(r, o_r), + construct_point(s, o_s)); + } + +public: + + Cell_handle + periodic_locate(const Point & p, const Offset &o_p, + Locate_type & lt, int & li, int & lj, + Cell_handle start = Cell_handle()) const + { + typedef Triangulation_structural_filtering_traits TSFT; + typedef typename internal::Periodic_structural_filtering_selector_3< + TSFT::Use_structural_filtering_tag::value >::Tag Should_filter_tag; + + return generic_periodic_locate(p, o_p, lt, li, lj, start, Should_filter_tag()); + } + + Cell_handle + inexact_locate(const Point& p, + Cell_handle start = Cell_handle(), + int max_num_cells = CGAL_PT3_STRUCTURAL_FILTERING_MAX_VISITED_CELLS) const + { + return inexact_periodic_locate(p, Offset(), start, max_num_cells); + } +#endif // no CGAL_NO_STRUCTURAL_FILTERING + protected: /** @name Location helpers */ //@{ - Cell_handle periodic_locate(const Point & p, const Offset &o_p, - Locate_type & lt, int & li, int & lj, Cell_handle start) const; +// Cell_handle periodic_locate(const Point & p, const Offset &o_p, +// Locate_type & lt, int & li, int & lj, Cell_handle start) const; Bounded_side side_of_cell(const Point & p, const Offset &off, Cell_handle c, Locate_type & lt, int & i, int & j) const; @@ -1500,9 +1637,14 @@ * returns a vertex (Cell_handle,li) if lt == VERTEX */ template < class GT, class TDS > -typename Periodic_3_triangulation_3::Cell_handle -Periodic_3_triangulation_3::periodic_locate( - const Point & p, const Offset &o_p, +inline typename Periodic_3_triangulation_3::Cell_handle +Periodic_3_triangulation_3:: +#ifdef CGAL_NO_STRUCTURAL_FILTERING +periodic_locate +#else +exact_periodic_locate +#endif +(const Point & p, const Offset &o_p, Locate_type & lt, int & li, int & lj, Cell_handle start) const { int cumm_off = 0; Offset off_query = o_p; @@ -1672,6 +1814,130 @@ return c; } + +#ifndef CGAL_NO_STRUCTURAL_FILTERING +template < class GT, class TDS > +typename Periodic_3_triangulation_3::Cell_handle +Periodic_3_triangulation_3:: +inexact_periodic_locate(const Point& p, const Offset& o_p, + Cell_handle start, + int n_of_turns) const +{ + int cumm_off = 0; + Offset off_query = o_p; + if (number_of_vertices() == 0) { + return Cell_handle(); + } + CGAL_triangulation_assertion(number_of_vertices() != 0); + + if (start == Cell_handle()) { + start = cells_begin(); + } + + cumm_off = start->offset(0) | start->offset(1) + | start->offset(2) | start->offset(3); + if (is_1_cover() && cumm_off != 0) { + if (((cumm_off & 4) == 4) && (FT(2)*p.x()<(_domain.xmax()+_domain.xmin()))) + off_query += Offset(1,0,0); + if (((cumm_off & 2) == 2) && (FT(2)*p.y()<(_domain.ymax()+_domain.ymin()))) + off_query += Offset(0,1,0); + if (((cumm_off & 1) == 1) && (FT(2)*p.z()<(_domain.zmax()+_domain.zmin()))) + off_query += Offset(0,0,1); + } + + CGAL_triangulation_postcondition(start!=Cell_handle()); + CGAL_triangulation_assertion(start->neighbor(0)->neighbor( + start->neighbor(0)->index(start))==start); + CGAL_triangulation_assertion(start->neighbor(1)->neighbor( + start->neighbor(1)->index(start))==start); + CGAL_triangulation_assertion(start->neighbor(2)->neighbor( + start->neighbor(2)->index(start))==start); + CGAL_triangulation_assertion(start->neighbor(3)->neighbor( + start->neighbor(3)->index(start))==start); + + // We implement the remembering visibility/stochastic walk. + + // Remembers the previous cell to avoid useless orientation tests. + Cell_handle previous = Cell_handle(); + Cell_handle c = start; + + // Now treat the cell c. +try_next_cell: + --n_of_turns; + cumm_off = + c->offset(0) | c->offset(1) | c->offset(2) | c->offset(3); + + bool simplicity_criterion = (cumm_off == 0) && (off_query.is_null()); + + // We know that the 4 vertices of c are positively oriented. + // So, in order to test if p is seen outside from one of c's facets, + // we just replace the corresponding point by p in the orientation + // test. We do this using the arrays below. + + Offset off[4]; + const Point* pts[4] = { &(c->vertex(0)->point()), + &(c->vertex(1)->point()), + &(c->vertex(2)->point()), + &(c->vertex(3)->point()) }; + + if (!simplicity_criterion && is_1_cover() ) { + for (int i=0; i<4; i++) { + off[i] = int_to_off(c->offset(i)); + } + } + + if (!is_1_cover()) { + // Just fetch the vertices of c as points with offsets + for (int i=0; i<4; i++) { + pts[i] = &(c->vertex(i)->point()); + off[i] = get_offset(c,i); + } + } + + for (int i=0; i != 4; ++i) { + Cell_handle next = c->neighbor(i); + if (previous == next) { + continue; + } + + // We temporarily put p at i's place in pts. + const Point* backup = pts[i]; + pts[i] = &p; + + if (simplicity_criterion && is_1_cover() ) { + if ( inexact_orientation(*pts[0], *pts[1], *pts[2], *pts[3]) != NEGATIVE ) { + pts[i] = backup; + continue; + } + } + else { + Offset backup_off; + + backup_off = off[i]; + off[i] = off_query; + + if ( inexact_orientation(*pts[0], *pts[1], *pts[2], *pts[3], + off[0], off[1], off[2], off[3]) != NEGATIVE ) { + pts[i] = backup; + off[i] = backup_off; + continue; + } + } + + // Test whether we need to adapt the offset of the query point. + // This means, if we get out of the current cover. + off_query = combine_offsets(off_query, get_neighbor_offset(c,i,next)); + previous = c; + c = next; + if (n_of_turns) + goto try_next_cell; + } + + return c; +} +#endif + + /** * returns * ON_BOUNDED_SIDE if p inside the cell diff -Nru cgal-4.4/include/CGAL/Poisson_reconstruction_function.h cgal-4.5/include/CGAL/Poisson_reconstruction_function.h --- cgal-4.4/include/CGAL/Poisson_reconstruction_function.h 2014-02-08 20:00:27.000000000 +0000 +++ cgal-4.5/include/CGAL/Poisson_reconstruction_function.h 2014-08-29 13:58:17.000000000 +0000 @@ -38,9 +38,6 @@ #ifdef CGAL_EIGEN3_ENABLED #include #else -#ifdef CGAL_TAUCS_ENABLED -#include -#endif #endif #include #include @@ -532,26 +529,15 @@ else return compute_implicit_function(solver,Poisson_visitor()); } - + /// \cond SKIP_IN_MANUAL -#ifdef CGAL_EIGEN3_ENABLED // This variant provides the default sparse linear traits class = Eigen_solver_traits. bool compute_implicit_function(bool smoother_hole_filling = false) { typedef Eigen_solver_traits::EigenType> > Solver; return compute_implicit_function(Solver(), smoother_hole_filling); } -#else - #ifdef CGAL_TAUCS_ENABLED - // This variant provides the default sparse linear traits class = Taucs_symmetric_solver_traits. - bool compute_implicit_function(bool smoother_hole_filling = false) - { - typedef Taucs_symmetric_solver_traits Solver; - return compute_implicit_function(Solver(), smoother_hole_filling); - } - #endif -#endif - + boost::tuple special_func(const Point& p) const { m_hint = m_tr->locate(p ,m_hint ); // no hint when we use hierarchy diff -Nru cgal-4.4/include/CGAL/Polyhedral_mesh_domain_3.h cgal-4.5/include/CGAL/Polyhedral_mesh_domain_3.h --- cgal-4.4/include/CGAL/Polyhedral_mesh_domain_3.h 2014-02-08 20:00:27.000000000 +0000 +++ cgal-4.5/include/CGAL/Polyhedral_mesh_domain_3.h 2014-08-29 13:58:16.000000000 +0000 @@ -36,6 +36,7 @@ #include #include +#include #include #include #include @@ -50,6 +51,10 @@ #include #include +#ifdef CGAL_LINKED_WITH_TBB +# include +#endif + namespace CGAL { namespace Mesh_3 { @@ -63,8 +68,8 @@ return (std::max)(b.xmax()-b.xmin(), (std::max)(b.ymax()-b.ymin(),b.zmax()-b.zmin()) ); } - - + + // ----------------------------------- // Surface_patch_index_generator // To use patch_id enclosed in AABB_primitives or not @@ -74,12 +79,12 @@ { typedef std::pair Surface_patch_index; typedef Surface_patch_index type; - + template < typename Primitive_id > Surface_patch_index operator()(const Primitive_id&) { return Surface_patch_index(0,1); } }; - + template < typename Subdomain_index, typename Polyhedron > struct Surface_patch_index_generator { @@ -113,10 +118,10 @@ // ----------------------------------- // Geometric traits generator // ----------------------------------- -template < typename Gt, +template < typename Gt, typename Use_exact_intersection_construction_tag > struct IGT_generator {}; - + template < typename Gt > struct IGT_generator { @@ -127,14 +132,14 @@ #endif // NOT CGAL_MESH_3_NEW_ROBUST_INTERSECTION_TRAITS typedef type Type; }; - + template < typename Gt > struct IGT_generator { typedef Gt type; typedef type Type; }; - + } // end namespace details } // end namespace Mesh_3 @@ -154,7 +159,7 @@ { typedef typename Mesh_3::details::IGT_generator< IGT_,Use_exact_intersection_construction_tag>::type IGT; - + public: /// Geometric object types typedef typename IGT::Point_3 Point_3; @@ -196,46 +201,64 @@ typedef typename AABB_tree_::Primitive_id AABB_primitive_id; typedef typename AABB_tree_::Primitive Primitive; typedef typename AABB_traits::Bounding_box Bounding_box; - + public: /// Default constructor Polyhedral_mesh_domain_3() : tree_() - , bounding_tree_(&tree_) - , has_cache(false) {} - + , bounding_tree_(&tree_) + , p_rng_(NULL) + , delete_rng_(true) + { + p_rng_ = new CGAL::Random(0); + } + /** * @brief Constructor. Contruction from a polyhedral surface * @param polyhedron the polyhedron describing the polyhedral surface */ - Polyhedral_mesh_domain_3(const Polyhedron& p) + Polyhedral_mesh_domain_3(const Polyhedron& p, + CGAL::Random* p_rng = NULL) : tree_(TriangleAccessor().triangles_begin(p), - TriangleAccessor().triangles_end(p)), - bounding_tree_(&tree_) // the bounding tree is tree_ - , has_cache(false) - { + TriangleAccessor().triangles_end(p)) + , bounding_tree_(&tree_) // the bounding tree is tree_ + , p_rng_(p_rng) + , delete_rng_(false) + { if(!p.is_pure_triangle()) { std::cerr << "Your input polyhedron must be triangulated!\n"; CGAL_error_msg("Your input polyhedron must be triangulated!"); } + if(!p_rng_) + { + p_rng_ = new CGAL::Random(0); + delete_rng_ = true; + } } Polyhedral_mesh_domain_3(const Polyhedron& p, - const Polyhedron& bounding_polyhedron) + const Polyhedron& bounding_polyhedron, + CGAL::Random* p_rng = NULL) : tree_(TriangleAccessor().triangles_begin(p), TriangleAccessor().triangles_end(p)) , bounding_tree_(new AABB_tree_(TriangleAccessor().triangles_begin(bounding_polyhedron), TriangleAccessor().triangles_end(bounding_polyhedron))) - , has_cache(false) - { + , p_rng_(p_rng) + , delete_rng_(false) + { tree_.insert(TriangleAccessor().triangles_begin(bounding_polyhedron), TriangleAccessor().triangles_end(bounding_polyhedron)); tree_.build(); bounding_tree_->build(); + if(!p_rng_) + { + p_rng_ = new CGAL::Random(0); + delete_rng_ = true; + } } - - /** + + /** * Constructor. * * Constructor from a sequence of polyhedral surfaces, and a bounding @@ -249,10 +272,12 @@ template Polyhedral_mesh_domain_3(InputPolyhedraPtrIterator begin, InputPolyhedraPtrIterator end, - const Polyhedron& bounding_polyhedron) - : has_cache(false) + const Polyhedron& bounding_polyhedron, + CGAL::Random* p_rng = NULL) + : p_rng_(p_rng) + , delete_rng_(false) { - if(begin != end) { + if(begin != end) { for(; begin != end; ++begin) { tree_.insert(TriangleAccessor().triangles_begin(**begin), TriangleAccessor().triangles_end(**begin)); @@ -260,7 +285,7 @@ tree_.insert(TriangleAccessor().triangles_begin(bounding_polyhedron), TriangleAccessor().triangles_end(bounding_polyhedron)); tree_.build(); - bounding_tree_ = + bounding_tree_ = new AABB_tree_(TriangleAccessor().triangles_begin(bounding_polyhedron), TriangleAccessor().triangles_end(bounding_polyhedron)); bounding_tree_->build(); @@ -270,9 +295,14 @@ TriangleAccessor().triangles_end(bounding_polyhedron)); bounding_tree_ = &tree_; } + if(!p_rng_) + { + p_rng_ = new CGAL::Random(0); + delete_rng_ = true; + } } - /** + /** * Constructor. * * Constructor from a sequence of polyhedral surfaces, without bounding @@ -284,8 +314,10 @@ */ template Polyhedral_mesh_domain_3(InputPolyhedraPtrIterator begin, - InputPolyhedraPtrIterator end) - : has_cache(false) + InputPolyhedraPtrIterator end, + CGAL::Random* p_rng = NULL) + : p_rng_(p_rng) + , delete_rng_(false) { if(begin != end) { for(; begin != end; ++begin) { @@ -295,13 +327,20 @@ tree_.build(); } bounding_tree_ = 0; + if(!p_rng_) + { + p_rng_ = new CGAL::Random(0); + delete_rng_ = true; + } } /// Destructor - ~Polyhedral_mesh_domain_3() { + ~Polyhedral_mesh_domain_3() { if(bounding_tree_ != 0 && bounding_tree_ != &tree_) { - delete bounding_tree_; + delete bounding_tree_; } + if(delete_rng_) + delete p_rng_; } /** @@ -348,7 +387,7 @@ { return tree_.closest_point(p); } - + /// Allowed query types typedef boost::mpl::vector Allowed_query_types; @@ -376,10 +415,10 @@ boost::optional primitive_id = r_domain_.tree_.any_intersected_primitive(q); if ( primitive_id ) - { + { r_domain_.cache_primitive(q, *primitive_id); return Surface_patch(r_domain_.make_surface_index(*primitive_id)); - } else { + } else { return Surface_patch(); } } @@ -423,14 +462,14 @@ #ifndef CGAL_MESH_3_NO_LONGER_CALLS_DO_INTERSECT_3 if(r_domain_.query_is_cached(q)) { - const AABB_primitive_id primitive_id = r_domain_.cached_primitive_id; + const AABB_primitive_id primitive_id = r_domain_.cached_primitive_id(); typename cpp11::result_of< typename IGT::Intersect_3(typename Primitive::Datum, Query)>::type o = IGT().intersect_3_object()(Primitive(primitive_id).datum(),q); intersection = o ? Intersection_and_primitive_id(*o, primitive_id) : AABB_intersection(); - } else + } else #endif // not CGAL_MESH_3_NO_LONGER_CALLS_DO_INTERSECT_3 { #ifndef CGAL_MESH_3_NO_LONGER_CALLS_DO_INTERSECT_3 @@ -443,7 +482,7 @@ { // Get primitive AABB_primitive_id primitive_id = intersection->second; - + // intersection may be either a point or a segment #if CGAL_INTERSECTION_VERSION > 1 if ( const Bare_point* p_intersect_pt = @@ -478,10 +517,10 @@ std::stringstream stream; stream.precision(17); set_pretty_mode(stream); - stream << + stream << "Mesh_3 error : AABB_tree any_intersection result is " "not a point nor a segment\n"; - if(intersection->first.empty()) { + if(intersection->first.empty()) { stream << "The intersection is empty!"; } else { stream << "The intersection typeinfo name is "; @@ -492,7 +531,7 @@ stream << "The intersecting primitive in the AABB tree was: " << AABB_primitive(intersection->second).datum() << std::endl; CGAL_error_msg(stream.str().c_str()); -#endif // not CGAL_MESH_3_NO_LONGER_CALLS_DO_INTERSECT_3 +#endif // not CGAL_MESH_3_NO_LONGER_CALLS_DO_INTERSECT_3 } } @@ -509,8 +548,8 @@ { return Construct_intersection(*this); } - - + + /** * Returns the index to be stored in a vertex lying on the surface identified * by \c index. @@ -538,16 +577,16 @@ */ Subdomain_index subdomain_index(const Index& index) const { return boost::get(index); } - + // ----------------------------------- // Backward Compatibility // ----------------------------------- #ifndef CGAL_MESH_3_NO_DEPRECATED_SURFACE_INDEX typedef Surface_patch_index Surface_index; - + Index index_from_surface_index(const Surface_index& index) const { return index_from_surface_patch_index(index); } - + Surface_index surface_index(const Index& index) const { return surface_patch_index(index); } #endif // CGAL_MESH_3_NO_DEPRECATED_SURFACE_INDEX @@ -579,36 +618,84 @@ { tree_.insert(TriangleAccessor().triangles_begin(p), TriangleAccessor().triangles_end(p)); - + tree_.build(); } - + private: /// The AABB tree: intersection detection and more AABB_tree_ tree_; AABB_tree_* bounding_tree_; - // cache queries and intersected primitive + // cache queries and intersected primitive typedef typename boost::make_variant_over::type Cached_query; - mutable bool has_cache; - mutable Cached_query cached_query; - mutable AABB_primitive_id cached_primitive_id; + struct Query_cache + { + Query_cache() : has_cache(false) {} + bool has_cache; + Cached_query cached_query; + AABB_primitive_id cached_primitive_id; + }; +#ifdef CGAL_LINKED_WITH_TBB + mutable tbb::enumerable_thread_specific query_cache; +#else + mutable Query_cache query_cache; +#endif + + //random number generator for Construct_initial_points + CGAL::Random* p_rng_; + bool delete_rng_; public: template - void cache_primitive(const Query& q, + void cache_primitive(const Query& q, const AABB_primitive_id id) const { - cached_query = Cached_query(q); - has_cache = true; - cached_primitive_id = id; +#ifdef CGAL_LINKED_WITH_TBB + Query_cache &qc = query_cache.local(); + qc.cached_query = Cached_query(q); + qc.has_cache = true; + qc.cached_primitive_id = id; +#else + query_cache.cached_query = Cached_query(q); + query_cache.has_cache = true; + query_cache.cached_primitive_id = id; +#endif } template bool query_is_cached(const Query& q) const { - return has_cache && (cached_query == Cached_query(q)); +#ifdef CGAL_LINKED_WITH_TBB + Query_cache &qc = query_cache.local(); + return qc.has_cache && (qc.cached_query == Cached_query(q)); +#else + return query_cache.has_cache + && (query_cache.cached_query == Cached_query(q)); +#endif + } + + AABB_primitive_id cached_primitive_id() const { +#ifdef CGAL_LINKED_WITH_TBB + return query_cache.local().cached_primitive_id; +#else + return query_cache.cached_primitive_id; +#endif + } + + void set_random_generator(CGAL::Random* p_rng) + { + if(delete_rng_) delete p_rng_; + if(!p_rng) + { + p_rng_ = new CGAL::Random(0); + delete_rng_ = true; + } + else { + p_rng_ = p_rng; + delete_rng_ = false; + } } private: @@ -623,7 +710,8 @@ -template +template template OutputIterator Polyhedral_mesh_domain_3:: @@ -632,18 +720,19 @@ { typename IGT::Construct_ray_3 ray = IGT().construct_ray_3_object(); typename IGT::Construct_vector_3 vector = IGT().construct_vector_3_object(); - + const Bounding_box bbox = r_domain_.tree_.bbox(); const Point_3 center( FT( (bbox.xmin() + bbox.xmax()) / 2), FT( (bbox.ymin() + bbox.ymax()) / 2), FT( (bbox.zmin() + bbox.zmax()) / 2) ); - - Random_points_on_sphere_3 random_point(1.); + + CGAL::Random& rng = *(r_domain_.p_rng_); + Random_points_on_sphere_3 random_point(1., rng); int i = n; -#ifdef CGAL_MESH_3_VERBOSE +# ifdef CGAL_MESH_3_VERBOSE std::cerr << "construct initial points:" << std::endl; -#endif +# endif // Point construction by ray shooting from the center of the enclosing bbox while ( i > 0 ) { @@ -658,19 +747,19 @@ #endif *pts++ = std::make_pair(CGAL::cpp0x::get<0>(intersection), CGAL::cpp0x::get<1>(intersection)); - + --i; - + #ifdef CGAL_MESH_3_VERBOSE std::cerr << boost::format("\r \r" "%1%/%2% initial point(s) found...") % (n - i) % n; -#endif +# endif } ++random_point; } - + #ifdef CGAL_MESH_3_VERBOSE std::cerr << std::endl; #endif @@ -678,7 +767,8 @@ } -template +template typename Polyhedral_mesh_domain_3::Subdomain Polyhedral_mesh_domain_3:: Is_in_domain::operator()(const Point_3& p) const diff -Nru cgal-4.4/include/CGAL/Polyhedral_mesh_domain_with_features_3.h cgal-4.5/include/CGAL/Polyhedral_mesh_domain_with_features_3.h --- cgal-4.4/include/CGAL/Polyhedral_mesh_domain_with_features_3.h 2013-07-06 19:00:27.000000000 +0000 +++ cgal-4.5/include/CGAL/Polyhedral_mesh_domain_with_features_3.h 2014-08-29 13:58:16.000000000 +0000 @@ -28,11 +28,11 @@ #include +#include #include #include #include -#include #include #include #include @@ -58,7 +58,7 @@ class Polyhedron_ = typename Mesh_polyhedron_3::type, class TriangleAccessor=Triangle_accessor_3, class Use_patch_id_tag = Tag_true, - class Use_exact_intersection_construction_tag = CGAL::Tag_true > + class Use_exact_intersection_construction_tag = Tag_true > class Polyhedral_mesh_domain_with_features_3 : public Mesh_domain_with_polyline_features_3< Polyhedral_mesh_domain_3< Polyhedron_, @@ -94,20 +94,36 @@ typedef CGAL::Tag_true Has_features; /// Constructors - Polyhedral_mesh_domain_with_features_3(const Polyhedron& p); - Polyhedral_mesh_domain_with_features_3(const std::string& filename); + Polyhedral_mesh_domain_with_features_3(const Polyhedron& p, + CGAL::Random* p_rng = NULL); + Polyhedral_mesh_domain_with_features_3(const std::string& filename, + CGAL::Random* p_rng = NULL); + + // The following is needed, because otherwise, when a "const char*" is + // passed, the constructors templates are a better match, than the + // constructor with `std::string`. + Polyhedral_mesh_domain_with_features_3(const char* filename, + CGAL::Random* p_rng = NULL); template - Polyhedral_mesh_domain_with_features_3(const T1& a, const T2& b) : Base(a, b) {} + Polyhedral_mesh_domain_with_features_3(const T1& a, const T2& b, + CGAL::Random* p_rng = NULL) + : Base(a, b) + { this->set_random_generator(p_rng); } + template - Polyhedral_mesh_domain_with_features_3(const T1& a, const T2& b, const T3& c) - : Base(a, b, c) {} + Polyhedral_mesh_domain_with_features_3(const T1& a, const T2& b, const T3& c, + CGAL::Random* p_rng = NULL) + : Base(a, b, c) + { this->set_random_generator(p_rng); } /// Destructor ~Polyhedral_mesh_domain_with_features_3() {} /// Detect features + void initialize_ts(Polyhedron& p); + void detect_features(FT angle_in_degree, Polyhedron& p); void detect_features(FT angle_in_degree = FT(60)) { detect_features(angle_in_degree, polyhedron_); } @@ -126,17 +142,35 @@ template < typename GT_, typename P_, typename TA_, typename Tag_, typename E_tag_> Polyhedral_mesh_domain_with_features_3:: -Polyhedral_mesh_domain_with_features_3(const Polyhedron& p) +Polyhedral_mesh_domain_with_features_3(const Polyhedron& p, + CGAL::Random* p_rng) : Base() , polyhedron_(p) { this->add_primitives(polyhedron_); + this->set_random_generator(p_rng); +} + +template < typename GT_, typename P_, typename TA_, + typename Tag_, typename E_tag_> +Polyhedral_mesh_domain_with_features_3:: +Polyhedral_mesh_domain_with_features_3(const char* filename, + CGAL::Random* p_rng) + : Base() + , polyhedron_() +{ + // Create input polyhedron + std::ifstream input(filename); + input >> polyhedron_; + this->add_primitives(polyhedron_); + this->set_random_generator(p_rng); } template < typename GT_, typename P_, typename TA_, typename Tag_, typename E_tag_> Polyhedral_mesh_domain_with_features_3:: -Polyhedral_mesh_domain_with_features_3(const std::string& filename) +Polyhedral_mesh_domain_with_features_3(const std::string& filename, + CGAL::Random* p_rng) : Base() , polyhedron_() { @@ -144,6 +178,32 @@ std::ifstream input(filename.c_str()); input >> polyhedron_; this->add_primitives(polyhedron_); + this->set_random_generator(p_rng); +} + + +template < typename GT_, typename P_, typename TA_, + typename Tag_, typename E_tag_> +void +Polyhedral_mesh_domain_with_features_3:: +initialize_ts(Polyhedron& p) +{ + std::size_t ts = 0; + for(typename Polyhedron::Vertex_iterator v = p.vertices_begin(), + end = p.vertices_end() ; v != end ; ++v) + { + v->set_time_stamp(ts++); + } + for(typename Polyhedron::Facet_iterator fit = p.facets_begin(), + end = p.facets_end() ; fit != end ; ++fit ) + { + fit->set_time_stamp(ts++); + } + for(typename Polyhedron::Halfedge_iterator hit = p.halfedges_begin(), + end = p.halfedges_end() ; hit != end ; ++hit ) + { + hit->set_time_stamp(ts++); + } } @@ -153,6 +213,7 @@ Polyhedral_mesh_domain_with_features_3:: detect_features(FT angle_in_degree, Polyhedron& p) { + initialize_ts(p); // Get sharp features Mesh_3::detect_features(p,angle_in_degree); diff -Nru cgal-4.4/include/CGAL/PolyhedralSurf_neighbors.h cgal-4.5/include/CGAL/PolyhedralSurf_neighbors.h --- cgal-4.4/include/CGAL/PolyhedralSurf_neighbors.h 2013-09-28 19:00:44.000000000 +0000 +++ cgal-4.5/include/CGAL/PolyhedralSurf_neighbors.h 2014-08-29 13:58:17.000000000 +0000 @@ -15,7 +15,7 @@ // $URL$ // $Id$ // -// Author(s) : Marc Pouget and Frédéric Cazals +// Author(s) : Marc Pouget and Frédéric Cazals #ifndef CGAL_POLYHEDRALSURF_NEIGHBORS_H_ #define CGAL_POLYHEDRALSURF_NEIGHBORS_H_ diff -Nru cgal-4.4/include/CGAL/Polyhedron_3.h cgal-4.5/include/CGAL/Polyhedron_3.h --- cgal-4.4/include/CGAL/Polyhedron_3.h 2012-11-13 13:14:00.000000000 +0000 +++ cgal-4.5/include/CGAL/Polyhedron_3.h 2014-08-29 13:58:17.000000000 +0000 @@ -606,9 +606,13 @@ protected: - HDS hds; // the boundary representation. + HDS hds_; // the boundary representation. Traits m_traits; +public: + HDS& hds() { return hds_; } + const HDS& hds() const { return hds_; } + // CREATION public: @@ -617,7 +621,7 @@ Polyhedron_3( size_type v, size_type h, size_type f, const Traits& traits = Traits()) - : hds(v,h,f), m_traits(traits) {} + : hds_(v,h,f), m_traits(traits) {} // a polyhedron `P' with storage reserved for v vertices, h // halfedges, and f facets. The reservation sizes are a hint for // optimizing storage allocation. @@ -628,16 +632,16 @@ // If the `capacity' is already greater than the requested size // nothing happens. If the `capacity' changes all iterators and // circulators invalidates. - hds.reserve(v,h,f); + hds_.reserve(v,h,f); } protected: Halfedge_handle make_triangle( Vertex_handle v1, Vertex_handle v2, Vertex_handle v3) { - HalfedgeDS_decorator decorator(hds); - Halfedge_handle h = hds.edges_push_back( Halfedge(), Halfedge()); - h->HBase::set_next( hds.edges_push_back( Halfedge(), Halfedge())); - h->next()->HBase::set_next( hds.edges_push_back( Halfedge(), + HalfedgeDS_decorator decorator(hds_); + Halfedge_handle h = hds_.edges_push_back( Halfedge(), Halfedge()); + h->HBase::set_next( hds_.edges_push_back( Halfedge(), Halfedge())); + h->next()->HBase::set_next( hds_.edges_push_back( Halfedge(), Halfedge())); h->next()->next()->HBase::set_next( h); decorator.set_prev( h, h->next()->next()); @@ -675,15 +679,15 @@ Vertex_handle v2, Vertex_handle v3, Vertex_handle v4) { - HalfedgeDS_decorator decorator(hds); + HalfedgeDS_decorator decorator(hds_); Halfedge_handle h = make_triangle(v1,v2,v3); // The remaining tip. - Halfedge_handle g = hds.edges_push_back( Halfedge(), Halfedge()); + Halfedge_handle g = hds_.edges_push_back( Halfedge(), Halfedge()); decorator.insert_tip( g->opposite(), h->opposite()); decorator.close_tip( g); decorator.set_vertex( g, v4); - Halfedge_handle e = hds.edges_push_back( Halfedge(), Halfedge()); - Halfedge_handle d = hds.edges_push_back( Halfedge(), Halfedge()); + Halfedge_handle e = hds_.edges_push_back( Halfedge(), Halfedge()); + Halfedge_handle d = hds_.edges_push_back( Halfedge(), Halfedge()); decorator.insert_tip( e->opposite(), h->next()->opposite()); decorator.insert_tip( e, g); decorator.insert_tip( d->opposite(),h->next()->next()->opposite()); @@ -716,7 +720,7 @@ reserve( 4 + size_of_vertices(), 12 + size_of_halfedges(), 4 + size_of_facets()); - HalfedgeDS_decorator decorator(hds); + HalfedgeDS_decorator decorator(hds_); return make_tetrahedron( decorator.vertices_push_back( Vertex()), decorator.vertices_push_back( Vertex()), decorator.vertices_push_back( Vertex()), @@ -730,7 +734,7 @@ reserve( 4 + size_of_vertices(), 12 + size_of_halfedges(), 4 + size_of_facets()); - HalfedgeDS_decorator decorator(hds); + HalfedgeDS_decorator decorator(hds_); return make_tetrahedron( decorator.vertices_push_back( Vertex(p1)), decorator.vertices_push_back( Vertex(p2)), decorator.vertices_push_back( Vertex(p3)), @@ -745,7 +749,7 @@ reserve( 3 + size_of_vertices(), 6 + size_of_halfedges(), 1 + size_of_facets()); - HalfedgeDS_decorator decorator(hds); + HalfedgeDS_decorator decorator(hds_); return make_triangle( decorator.vertices_push_back( Vertex()), decorator.vertices_push_back( Vertex()), decorator.vertices_push_back( Vertex())); @@ -760,7 +764,7 @@ reserve( 3 + size_of_vertices(), 6 + size_of_halfedges(), 1 + size_of_facets()); - HalfedgeDS_decorator decorator(hds); + HalfedgeDS_decorator decorator(hds_); return make_triangle( decorator.vertices_push_back( Vertex(p1)), decorator.vertices_push_back( Vertex(p2)), decorator.vertices_push_back( Vertex(p3))); @@ -768,76 +772,76 @@ // Access Member Functions - allocator_type get_allocator() const { return hds.get_allocator(); } + allocator_type get_allocator() const { return hds_.get_allocator(); } - size_type size_of_vertices() const { return hds.size_of_vertices();} + size_type size_of_vertices() const { return hds_.size_of_vertices();} // number of vertices. - size_type size_of_halfedges() const { return hds.size_of_halfedges();} + size_type size_of_halfedges() const { return hds_.size_of_halfedges();} // number of all halfedges (including border halfedges). - size_type size_of_facets() const { return hds.size_of_faces();} + size_type size_of_facets() const { return hds_.size_of_faces();} // number of facets. bool empty() const { return size_of_halfedges() == 0; } size_type capacity_of_vertices() const { // space reserved for vertices. - return hds.capacity_of_vertices(); + return hds_.capacity_of_vertices(); } size_type capacity_of_halfedges() const { // space reserved for halfedges. - return hds.capacity_of_halfedges(); + return hds_.capacity_of_halfedges(); } size_type capacity_of_facets() const { // space reserved for facets. - return hds.capacity_of_faces(); + return hds_.capacity_of_faces(); } std::size_t bytes() const { // bytes used for the polyhedron. - return sizeof(Self) - sizeof(HDS) + hds.bytes(); + return sizeof(Self) - sizeof(HDS) + hds_.bytes(); } std::size_t bytes_reserved() const { // bytes reserved for the polyhedron. - return sizeof(Self) - sizeof(HDS) + hds.bytes_reserved(); + return sizeof(Self) - sizeof(HDS) + hds_.bytes_reserved(); } - Vertex_iterator vertices_begin() { return hds.vertices_begin();} + Vertex_iterator vertices_begin() { return hds_.vertices_begin();} // iterator over all vertices. - Vertex_iterator vertices_end() { return hds.vertices_end();} + Vertex_iterator vertices_end() { return hds_.vertices_end();} - Halfedge_iterator halfedges_begin() { return hds.halfedges_begin();} + Halfedge_iterator halfedges_begin() { return hds_.halfedges_begin();} // iterator over all halfedges - Halfedge_iterator halfedges_end() { return hds.halfedges_end();} + Halfedge_iterator halfedges_end() { return hds_.halfedges_end();} - Facet_iterator facets_begin() { return hds.faces_begin();} + Facet_iterator facets_begin() { return hds_.faces_begin();} // iterator over all facets - Facet_iterator facets_end() { return hds.faces_end();} + Facet_iterator facets_end() { return hds_.faces_end();} // The constant iterators and circulators. Vertex_const_iterator vertices_begin() const { - return hds.vertices_begin(); + return hds_.vertices_begin(); } Vertex_const_iterator vertices_end() const { - return hds.vertices_end(); + return hds_.vertices_end(); } Halfedge_const_iterator halfedges_begin() const { - return hds.halfedges_begin(); + return hds_.halfedges_begin(); } Halfedge_const_iterator halfedges_end() const { - return hds.halfedges_end(); + return hds_.halfedges_end(); } - Facet_const_iterator facets_begin() const { return hds.faces_begin();} - Facet_const_iterator facets_end() const { return hds.faces_end();} + Facet_const_iterator facets_begin() const { return hds_.faces_begin();} + Facet_const_iterator facets_end() const { return hds_.faces_end();} // Auxiliary iterators for convinience Point_iterator points_begin() { return vertices_begin();} @@ -1139,7 +1143,7 @@ reserve( size_of_vertices(), 2 + size_of_halfedges(), 1 + size_of_facets()); - HalfedgeDS_decorator D(hds); + HalfedgeDS_decorator D(hds_); CGAL_precondition( D.get_face(h) == D.get_face(g)); CGAL_precondition( h != g); CGAL_precondition( h != g->next()); @@ -1156,7 +1160,7 @@ // removed and the time to compute `h.prev()'. Precondition: // `HDS' supports removal of facets. The degree of both // vertices incident to h is at least three (no antennas). - HalfedgeDS_decorator D(hds); + HalfedgeDS_decorator D(hds_); CGAL_precondition( circulator_size(h->vertex_begin()) >= size_type(3)); CGAL_precondition( circulator_size(h->opposite()->vertex_begin()) @@ -1174,7 +1178,7 @@ reserve( 1 + size_of_vertices(), 2 + size_of_halfedges(), size_of_facets()); - HalfedgeDS_decorator D(hds); + HalfedgeDS_decorator D(hds_); CGAL_precondition( D.get_vertex(h) == D.get_vertex(g)); CGAL_precondition( h != g); return D.split_vertex( h, g); @@ -1189,7 +1193,7 @@ // `h.prev()'. // Precondition: `HDS' supports removal of vertices. The size of // both facets incident to h is at least four (no multi-edges) - HalfedgeDS_decorator D(hds); + HalfedgeDS_decorator D(hds_); CGAL_precondition( circulator_size( h->facet_begin()) >= size_type(4)); CGAL_precondition( circulator_size( h->opposite()->facet_begin()) @@ -1207,14 +1211,14 @@ } Halfedge_handle create_center_vertex( Halfedge_handle h) { - HalfedgeDS_decorator D(hds); + HalfedgeDS_decorator D(hds_); CGAL_assertion( circulator_size( h->facet_begin()) >= size_type(3)); return D.create_center_vertex(h); } Halfedge_handle erase_center_vertex( Halfedge_handle h) { - HalfedgeDS_decorator D(hds); + HalfedgeDS_decorator D(hds_); return D.erase_center_vertex(h); } @@ -1235,7 +1239,7 @@ reserve( 3 + size_of_vertices(), 6 + size_of_halfedges(), 2 + size_of_facets()); - HalfedgeDS_decorator D(hds); + HalfedgeDS_decorator D(hds_); CGAL_precondition( h != i); CGAL_precondition( h != j); CGAL_precondition( i != j); @@ -1282,7 +1286,7 @@ // and keeps the polyhedron unchanged. Precondition: `HDS' // supports removal of vertices and facets. The facets denoted by // h and g have equal size. - HalfedgeDS_decorator D(hds); + HalfedgeDS_decorator D(hds_); CGAL_precondition( D.get_face(h) == Facet_handle() || D.get_face(h) != D.get_face(g)); CGAL_precondition( circulator_size( h->facet_begin()) @@ -1298,7 +1302,7 @@ // removes incident facet and makes all halfedges incident to the // facet to border edges. Returns h. Precondition: `HDS' // supports removal of facets. `! h.is_border()'. - HalfedgeDS_decorator D(hds); + HalfedgeDS_decorator D(hds_); return D.make_hole(h); } @@ -1309,7 +1313,7 @@ reserve( size_of_vertices(), size_of_halfedges(), 1 + size_of_facets()); - HalfedgeDS_decorator D(hds); + HalfedgeDS_decorator D(hds_); return D.fill_hole(h); } @@ -1326,7 +1330,7 @@ reserve( 1 + size_of_vertices(), 4 + size_of_halfedges(), 1 + size_of_facets()); - HalfedgeDS_decorator D(hds); + HalfedgeDS_decorator D(hds_); Halfedge_handle hh = D.add_face_to_border( h, g); CGAL_assertion( hh == g->next()); D.split_vertex( g, hh->opposite()); @@ -1347,7 +1351,7 @@ reserve( size_of_vertices(), 2 + size_of_halfedges(), 1 + size_of_facets()); - HalfedgeDS_decorator D(hds); + HalfedgeDS_decorator D(hds_); return D.add_face_to_border( h, g); } @@ -1359,7 +1363,7 @@ // the polyhedral surface if they were already border edges. See // `make_hole(h)' for a more specialized variant. Precondition: // `Traits' supports removal. - HalfedgeDS_decorator D(hds); + HalfedgeDS_decorator D(hds_); D.erase_face(h); } @@ -1367,7 +1371,7 @@ // removes the vertices, halfedges, and facets that belong to the // connected component of h. Precondition: `Traits' supports // removal. - HalfedgeDS_decorator D(hds); + HalfedgeDS_decorator D(hds_); D.erase_connected_component(h); } @@ -1382,11 +1386,11 @@ /// @return the number of connected components erased (ignoring isolated vertices). unsigned int keep_largest_connected_components(unsigned int nb_components_to_keep) { - HalfedgeDS_decorator D(hds); + HalfedgeDS_decorator D(hds_); return D.keep_largest_connected_components(nb_components_to_keep); } - void clear() { hds.clear(); } + void clear() { hds_.clear(); } // removes all vertices, halfedges, and facets. void erase_all() { clear(); } @@ -1397,7 +1401,7 @@ void delegate( Modifier_base& modifier) { // calls the `operator()' of the `modifier'. Precondition: The // `modifier' returns a consistent representation. - modifier( hds); + modifier( hds_); CGAL_expensive_postcondition( is_valid()); } @@ -1409,7 +1413,7 @@ // ()' has been called and no halfedge insertion or removal and no // change in border status of the halfedges have occured since // then. - return hds.size_of_border_halfedges(); + return hds_.size_of_border_halfedges(); } size_type size_of_border_edges() const { @@ -1419,7 +1423,7 @@ // Precondition: `normalize_border()' has been called and no // halfedge insertion or removal and no change in border status of // the halfedges have occured since then. - return hds.size_of_border_edges(); + return hds_.size_of_border_edges(); } Halfedge_iterator border_halfedges_begin() { @@ -1430,10 +1434,10 @@ // `normalize_border()' has been called and no halfedge insertion // or removal and no change in border status of the halfedges have // occured since then. - return hds.border_halfedges_begin(); + return hds_.border_halfedges_begin(); } Halfedge_const_iterator border_halfedges_begin() const { - return hds.border_halfedges_begin(); + return hds_.border_halfedges_begin(); } // Convenient edge iterator @@ -1444,7 +1448,7 @@ bool normalized_border_is_valid( bool verbose = false) const { // checks whether all non-border edges precedes the border edges. - HalfedgeDS_const_decorator decorator(hds); + HalfedgeDS_const_decorator decorator(hds_); bool valid = decorator.normalized_border_is_valid( verbose); for ( Halfedge_const_iterator i = border_halfedges_begin(); valid && (i != halfedges_end()); (++i, ++i)) { @@ -1461,7 +1465,7 @@ void normalize_border() { // sorts halfedges such that the non-border edges precedes the // border edges. - hds.normalize_border(); + hds_.normalize_border(); CGAL_postcondition( normalized_border_is_valid()); } @@ -1476,7 +1480,7 @@ public: void inside_out() { // reverse facet orientation. - HalfedgeDS_decorator decorator(hds); + HalfedgeDS_decorator decorator(hds_); decorator.inside_out(); inside_out_geometry( Supports_face_plane()); } @@ -1486,7 +1490,7 @@ Verbose_ostream verr(verb); verr << "begin CGAL::Polyhedron_3<...>::is_valid( verb=true, " "level = " << level << "):" << std::endl; - HalfedgeDS_const_decorator D(hds); + HalfedgeDS_const_decorator D(hds_); bool valid = D.is_valid( verb, level + 3); // All halfedges. Halfedge_const_iterator i = halfedges_begin(); @@ -1529,4 +1533,8 @@ } //namespace CGAL +#ifndef CGAL_NO_DEPRECATED_CODE +#include +#endif + #endif // CGAL_POLYHEDRON_3_H // diff -Nru cgal-4.4/include/CGAL/Polyhedron_3_property_map.h cgal-4.5/include/CGAL/Polyhedron_3_property_map.h --- cgal-4.4/include/CGAL/Polyhedron_3_property_map.h 2013-07-06 19:00:27.000000000 +0000 +++ cgal-4.5/include/CGAL/Polyhedron_3_property_map.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,170 +0,0 @@ -// Copyright (c) 2012 GeometryFactory (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org). -// You can redistribute it and/or modify it under the terms of the GNU -// General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -// -// $URL$ -// $Id$ -// -// -// Author(s) : Sebastien Loriot -// - -#ifndef CGAL_POLYHEDRON_SIMPLEX_PROPERTY_MAP_H -#define CGAL_POLYHEDRON_SIMPLEX_PROPERTY_MAP_H - -#include -#include -#include -#include -#include -#include - -namespace CGAL{ - -//property map -template -struct Triangle_from_facet_handle_property_map{ - Triangle_from_facet_handle_property_map(Polyhedron* = NULL){} - typedef typename Kernel_traits< - typename Polyhedron::Vertex::Point>::Kernel::Triangle_3 Triangle_3; - //classical typedefs - typedef typename boost::mpl::if_< - typename boost::is_const::type, - typename Polyhedron::Facet_const_handle, - typename Polyhedron::Facet_handle >::type key_type; - typedef Triangle_3 value_type; - typedef value_type reference; - typedef boost::readable_property_map_tag category; - - //get function for property map - inline friend - Triangle_3 - get(Triangle_from_facet_handle_property_map, - typename Triangle_from_facet_handle_property_map::key_type f) - { - typedef typename Polyhedron::Traits Kernel; - CGAL_precondition(f->halfedge() == f->halfedge()->next()->next()->next()); - const typename Kernel::Point_3& a = f->halfedge()->vertex()->point(); - const typename Kernel::Point_3& b = f->halfedge()->next()->vertex()->point(); - const typename Kernel::Point_3& c = f->halfedge()->next()->next()->vertex()->point(); - return typename Kernel::Triangle_3(a,b,c); - } -}; - - -template < class HalfedgeGraph, - class VertexPointPMap > -struct Segment_from_edge_descriptor_property_map{ - Segment_from_edge_descriptor_property_map( - HalfedgeGraph* g = NULL ) : - m_graph( const_cast::type*>(g) ), - m_vppm( boost::get(vertex_point, *m_graph) ) - {} - - Segment_from_edge_descriptor_property_map( - HalfedgeGraph* g, - VertexPointPMap vppm ) : - m_graph( const_cast::type*>(g) ), - m_vppm(vppm) - {} - - //classical typedefs - typedef typename boost::property_traits< VertexPointPMap >::value_type Point; - typedef typename boost::graph_traits::edge_descriptor key_type; - typedef typename Kernel_traits::Kernel::Segment_3 value_type; - typedef value_type reference; - typedef boost::readable_property_map_tag category; - //data - typename boost::remove_const::type* m_graph; - VertexPointPMap m_vppm; - - //get function for property map - inline friend - value_type - get(Segment_from_edge_descriptor_property_map pmap, - key_type h) - { - typedef typename boost::property_map< HalfedgeGraph, vertex_point_t>::type Point_pmap; - typedef typename boost::property_traits< Point_pmap >::value_type Point; - typedef typename Kernel_traits::Kernel Kernel; - - return typename Kernel::Segment_3( - get(pmap.m_vppm, boost::source(h, *pmap.m_graph) ), - get(pmap.m_vppm, boost::target(h, *pmap.m_graph) ) ); - } -}; - -//property map to access a point from a facet handle -template -struct One_point_from_facet_handle_property_map{ - One_point_from_facet_handle_property_map(Polyhedron* = NULL){} - //classical typedefs - typedef typename boost::mpl::if_< - typename boost::is_const::type, - typename Polyhedron::Facet_const_handle, - typename Polyhedron::Facet_handle >::type key_type; - typedef typename Polyhedron::Vertex::Point_3 value_type; - typedef const value_type& reference; - typedef boost::lvalue_property_map_tag category; - - //get function for property map - inline friend - reference - get(One_point_from_facet_handle_property_map, - key_type f) - { - return f->halfedge()->vertex()->point(); - } -}; - -//property map to access a point from an edge -template < class HalfedgeGraph, - class VertexPointPMap > -struct Source_point_from_edge_descriptor{ - Source_point_from_edge_descriptor( - HalfedgeGraph* g = NULL ) : - m_graph( const_cast::type*>(g) ), - m_vppm( boost::get(vertex_point, *m_graph) ) - {} - - Source_point_from_edge_descriptor( - HalfedgeGraph* g, - VertexPointPMap vppm ) : - m_graph( const_cast::type*>(g) ), - m_vppm(vppm) - {} - - //classical typedefs - typedef typename boost::property_traits< VertexPointPMap >::value_type value_type; - typedef typename boost::property_traits< VertexPointPMap >::reference reference; - typedef typename boost::graph_traits::edge_descriptor key_type; - typedef boost::readable_property_map_tag category; - //data - typename boost::remove_const::type* m_graph; - VertexPointPMap m_vppm; - - //get function for property map - inline friend - reference - get(Source_point_from_edge_descriptor pmap, - key_type h) - { - return boost::get(vertex_point, - *pmap.m_graph, - boost::source(h, *pmap.m_graph) ); - } -}; - -} //namespace CGAL - -#endif //CGAL_POLYHEDRON_SIMPLEX_PROPERTY_MAP_H diff -Nru cgal-4.4/include/CGAL/Polyhedron_slicer_3.h cgal-4.5/include/CGAL/Polyhedron_slicer_3.h --- cgal-4.4/include/CGAL/Polyhedron_slicer_3.h 2013-10-05 19:00:24.000000000 +0000 +++ cgal-4.5/include/CGAL/Polyhedron_slicer_3.h 2014-08-29 13:58:16.000000000 +0000 @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include @@ -48,7 +48,7 @@ class Polyhedron_slicer_3 { private: - typedef AABB_halfedge_graph_segment_primitive AABB_primitive; + typedef AABB_halfedge_graph_segment_primitive AABB_primitive; typedef AABB_traits AABB_traits_; typedef AABB_tree AABB_tree_; @@ -59,12 +59,13 @@ typedef typename Kernel::Segment_3 Segment; typedef typename Kernel::Point_3 Point; - typedef typename Polyhedron::Edge_const_iterator Edge_const_iterator; - typedef typename Polyhedron::Halfedge_const_handle Halfedge_const_handle; - typedef typename Polyhedron::Facet_const_handle Facet_const_handle; - typedef typename Polyhedron::Vertex_const_handle Vertex_const_handle; - typedef typename Polyhedron::Halfedge_around_vertex_const_circulator Halfedge_around_vertex_const_circulator; - typedef typename Polyhedron::Halfedge_around_facet_const_circulator Halfedge_around_facet_const_circulator; + typedef typename boost::graph_traits::edge_descriptor Edge_const_handle; + typedef typename boost::graph_traits::edge_iterator Edge_const_iterator; + typedef typename boost::graph_traits::halfedge_descriptor Halfedge_const_handle; + typedef typename boost::graph_traits::face_descriptor Facet_const_handle; + typedef typename boost::graph_traits::vertex_descriptor Vertex_const_handle; + typedef Halfedge_around_target_circulator Halfedge_around_vertex_const_circulator; + typedef Halfedge_around_face_circulator Halfedge_around_facet_const_circulator; // to unite halfedges under an "edge" struct Edge_comparator { @@ -127,6 +128,7 @@ typename Kernel::Intersect_3 intersect_3_functor; AABB_tree_ tree; mutable Node_graph node_graph; + Polyhedron& polyhedron; boost::tuple halfedge_intersection(Halfedge_const_handle hf, const Plane& plane) const @@ -177,11 +179,11 @@ Vertex_g v_g = boost::add_vertex(node_graph); node_graph[v_g].point = v->point(); - Halfedge_around_vertex_const_circulator around_vertex_c = v->vertex_begin(); + Halfedge_around_vertex_const_circulator around_vertex_c(v,polyhedron), done(around_vertex_c); do { - edge_node_map[around_vertex_c].put(v_g); + edge_node_map[*around_vertex_c].put(v_g); } - while(++around_vertex_c != v->vertex_begin()); + while(++around_vertex_c != done); } void add_intersection_edge_to_facet_neighbors(Halfedge_const_handle hf, Edge_node_map& edge_node_map) const { @@ -212,11 +214,11 @@ Node_pair& hf_node_pair = edge_node_map.find(hf)->second; Vertex_g v_g = node_graph[hf_node_pair.v1].point == v->point() ? hf_node_pair.v1 : hf_node_pair.v2;// find node containing v - Halfedge_around_vertex_const_circulator around_vertex_c = v->vertex_begin(); + Halfedge_around_vertex_const_circulator around_vertex_c(v, polyhedron), done(around_vertex_c); do { - if(around_vertex_c->is_border()) { continue;} - Node_pair& around_vertex_node_pair = edge_node_map.find(around_vertex_c)->second; - Halfedge_around_facet_const_circulator around_facet_c = around_vertex_c->facet_begin(); + if((*around_vertex_c)->is_border()) { continue;} + Node_pair& around_vertex_node_pair = edge_node_map.find(*around_vertex_c)->second; + Halfedge_around_facet_const_circulator around_facet_c(*around_vertex_c,polyhedron), done2(around_facet_c); do { CGAL_assertion(around_vertex_node_pair.vertex_count != 0); if(around_vertex_node_pair.v1 != v_g) { @@ -226,9 +228,9 @@ boost::add_edge(around_vertex_node_pair.v2, v_g, node_graph); } } - while(++around_facet_c != around_vertex_c->facet_begin()); + while(++around_facet_c != done2); } - while(++around_vertex_c != v->vertex_begin()); + while(++around_vertex_c != done); } template @@ -237,17 +239,17 @@ node_graph.clear(); // find out intersecting halfedges (note that tree contains edges only with custom comparator) - std::vector intersected_edges; + std::vector intersected_edges; tree.all_intersected_primitives(plane, std::back_inserter(intersected_edges)); // create node graph from segments // each node is associated with multiple edges Edge_node_map edge_node_map; Edge_intersection_map edge_intersection_map; - for(typename std::vector::iterator it = intersected_edges.begin(); + for(typename std::vector::iterator it = intersected_edges.begin(); it != intersected_edges.end(); ++it) { - Halfedge_const_handle hf = *it; + Halfedge_const_handle hf = halfedge(*it,polyhedron); Node_pair& assoc_nodes = edge_node_map[hf]; CGAL_assertion(assoc_nodes.vertex_count < 3); // every Node_pair can at most contain 2 nodes @@ -297,10 +299,10 @@ } // for(typename std::vector::iterator it = intersected_edges.begin()... // introduce node connectivity - for(typename std::vector::iterator it = intersected_edges.begin(); + for(typename std::vector::iterator it = intersected_edges.begin(); it != intersected_edges.end(); ++it) { - Halfedge_const_handle hf = *it; + Halfedge_const_handle hf = halfedge(*it,polyhedron); Edge_intersection_map_iterator intersection_it = edge_intersection_map.find(hf); CGAL_assertion(intersection_it != edge_intersection_map.end()); @@ -419,9 +421,10 @@ */ Polyhedron_slicer_3(const Polyhedron& polyhedron, const Kernel& kernel = Kernel()) : intersect_3_functor(kernel.intersect_3_object()), - tree( undirected_edges(polyhedron).first, - undirected_edges(polyhedron).second, - polyhedron) + tree( edges(polyhedron).first, + edges(polyhedron).second, + polyhedron), + polyhedron(const_cast(polyhedron)) { } /** diff -Nru cgal-4.4/include/CGAL/Polynomial/basic.h cgal-4.5/include/CGAL/Polynomial/basic.h --- cgal-4.4/include/CGAL/Polynomial/basic.h 2012-11-13 13:13:56.000000000 +0000 +++ cgal-4.5/include/CGAL/Polynomial/basic.h 2014-08-29 13:58:16.000000000 +0000 @@ -53,8 +53,9 @@ } } //namespace CGAL::POLYNOMIAL #else #include +#include namespace CGAL { namespace POLYNOMIAL { -typedef CGAL::MP_Float Default_field_nt; +typedef CGAL::Quotient Default_field_nt; } } //namespace CGAL::POLYNOMIAL #endif diff -Nru cgal-4.4/include/CGAL/Polynomial/internal/Kernel/Sign_above.h cgal-4.5/include/CGAL/Polynomial/internal/Kernel/Sign_above.h --- cgal-4.4/include/CGAL/Polynomial/internal/Kernel/Sign_above.h 2012-11-13 13:13:56.000000000 +0000 +++ cgal-4.5/include/CGAL/Polynomial/internal/Kernel/Sign_above.h 2014-08-29 13:58:16.000000000 +0000 @@ -42,13 +42,23 @@ } Sign_above(){} +#if defined(_MSC_VER) && ( _MSC_VER >= 1800 ) + // == VC12 == Visual Studio 2013 + template + auto operator()(Args&&... args) -> + decltype(P::operator()(std::forward(args)...)) + { + return P::operator()(std::forward(args)...); + } +#else using P::operator(); +#endif typedef CGAL::Sign result_type; typedef Poly first_argument_type; typedef typename K::Root second_argument_type; - typename P::result_type operator()(const first_argument_type &f, - const second_argument_type &v) const + typename P::result_type operator()(const first_argument_type &f, + const second_argument_type &v) const { CGAL_Polynomial_expensive_precondition(k_.sign_at_root_object(p_)(v)==CGAL::ZERO); return eval(f, v); diff -Nru cgal-4.4/include/CGAL/Polynomial/internal/Rational/Sturm_sequence_base.h cgal-4.5/include/CGAL/Polynomial/internal/Rational/Sturm_sequence_base.h --- cgal-4.4/include/CGAL/Polynomial/internal/Rational/Sturm_sequence_base.h 2012-11-13 13:13:56.000000000 +0000 +++ cgal-4.5/include/CGAL/Polynomial/internal/Rational/Sturm_sequence_base.h 2014-08-29 13:58:16.000000000 +0000 @@ -29,6 +29,7 @@ #ifndef POLYNOMIAL_NO_CGAL #include +#include #endif namespace CGAL { namespace POLYNOMIAL { namespace internal { @@ -81,7 +82,7 @@ } #ifdef POLYNOMIAL_USE_CGAL - void normalize(Polynomial& r, const CGAL::MP_Float&) { + void normalize(Polynomial& r, const CGAL::Quotient&) { // THE FOLLOWING HACK HAS BEEN DONE SO THAT MP_Float HOPEFULLY // DOES NOT RUN OUT OF EXPONENT BITS WHEN THE STURM SEQUENCE IS // COMPUTED diff -Nru cgal-4.4/include/CGAL/Polytope_distance_d.h cgal-4.5/include/CGAL/Polytope_distance_d.h --- cgal-4.4/include/CGAL/Polytope_distance_d.h 2013-03-07 20:00:26.000000000 +0000 +++ cgal-4.5/include/CGAL/Polytope_distance_d.h 2014-08-29 13:58:17.000000000 +0000 @@ -574,8 +574,8 @@ insert( InputIterator1 p_first, InputIterator1 p_last, InputIterator2 q_first, InputIterator2 q_last) { - int old_r = static_cast(p_points.size()); - int old_s = static_cast(q_points.size()); + CGAL_optimisation_precondition_code(int old_r = static_cast(p_points.size())); + CGAL_optimisation_precondition_code(int old_s = static_cast(q_points.size())); p_points.insert( p_points.end(), p_first, p_last); q_points.insert( q_points.end(), q_first, q_last); set_dimension(); @@ -590,7 +590,7 @@ void insert_p( InputIterator p_first, InputIterator p_last) { - int old_r = static_cast(p_points.size()); + CGAL_optimisation_precondition_code(int old_r = static_cast(p_points.size())); p_points.insert( p_points.end(), p_first, p_last); set_dimension(); CGAL_optimisation_precondition_msg @@ -603,7 +603,7 @@ void insert_q( InputIterator q_first, InputIterator q_last) { - int old_s = static_cast(q_points.size()); + CGAL_optimisation_precondition_code( int old_s = static_cast(q_points.size())); q_points.insert( q_points.end(), q_first, q_last); set_dimension(); CGAL_optimisation_precondition_msg diff -Nru cgal-4.4/include/CGAL/predicates/kernel_ftC3.h cgal-4.5/include/CGAL/predicates/kernel_ftC3.h --- cgal-4.4/include/CGAL/predicates/kernel_ftC3.h 2012-11-13 13:13:54.000000000 +0000 +++ cgal-4.5/include/CGAL/predicates/kernel_ftC3.h 2014-08-29 13:58:16.000000000 +0000 @@ -141,7 +141,16 @@ } template < class FT > -inline +CGAL_KERNEL_MEDIUM_INLINE +typename Same_uncertainty_nt::type +angleC3(const FT &ux, const FT &uy, const FT &uz, + const FT &vx, const FT &vy, const FT &vz) +{ + return enum_cast(CGAL_NTS sign(ux*vx + uy*vy + uz*vz)); +} + +template < class FT > +CGAL_KERNEL_MEDIUM_INLINE typename Same_uncertainty_nt::type angleC3(const FT &px, const FT &py, const FT &pz, const FT &qx, const FT &qy, const FT &qz, @@ -153,6 +162,19 @@ } template < class FT > +CGAL_KERNEL_MEDIUM_INLINE +typename Same_uncertainty_nt::type +angleC3(const FT &px, const FT &py, const FT &pz, + const FT &qx, const FT &qy, const FT &qz, + const FT &rx, const FT &ry, const FT &rz, + const FT &sx, const FT &sy, const FT &sz) +{ + return enum_cast(CGAL_NTS sign((px-qx)*(rx-sx)+ + (py-qy)*(ry-sy)+ + (pz-qz)*(rz-sz))); +} + +template < class FT > CGAL_KERNEL_MEDIUM_INLINE typename Same_uncertainty_nt::type coplanar_orientationC3(const FT &px, const FT &py, const FT &pz, diff -Nru cgal-4.4/include/CGAL/predicates/Regular_triangulation_ftC3.h cgal-4.5/include/CGAL/predicates/Regular_triangulation_ftC3.h --- cgal-4.4/include/CGAL/predicates/Regular_triangulation_ftC3.h 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/include/CGAL/predicates/Regular_triangulation_ftC3.h 2014-08-29 13:58:17.000000000 +0000 @@ -21,6 +21,9 @@ #ifndef CGAL_REGULAR_TRIANGULATION_FTC3_H #define CGAL_REGULAR_TRIANGULATION_FTC3_H +#include +#include + // This file contains the low level cartesian predicates // used by the 3D regular triangulation. diff -Nru cgal-4.4/include/CGAL/Profile_counter.h cgal-4.5/include/CGAL/Profile_counter.h --- cgal-4.4/include/CGAL/Profile_counter.h 2012-11-13 13:14:00.000000000 +0000 +++ cgal-4.5/include/CGAL/Profile_counter.h 2014-08-29 13:58:17.000000000 +0000 @@ -1,4 +1,4 @@ -// Copyright (c) 2005,2006,2008 INRIA Sophia-Antipolis (France). +//r Copyright (c) 2005,2006,2008 INRIA Sophia-Antipolis (France). // All rights reserved. // // This file is part of CGAL (www.cgal.org); you can redistribute it and/or @@ -38,6 +38,8 @@ // - Profile_branch_counter_3 which keeps track of 3 counters, aiming at measuring // the ratios corresponding to the number of times 2 branches are taken. // +// If CGAL_CONCURRENT_PROFILE is defined, the counters can be concurrently updated +// // See also CGAL/Profile_timer.h // TODO : @@ -54,12 +56,31 @@ #include #include +// Automatically define CGAL_CONCURRENT_PROFILE if we're linked with TBB +#ifdef CGAL_LINKED_WITH_TBB +# ifndef CGAL_CONCURRENT_PROFILE +# define CGAL_CONCURRENT_PROFILE +# endif +#else +// Automatically UNdefine CGAL_CONCURRENT_PROFILE if we're NOT linked with TBB +# ifdef CGAL_CONCURRENT_PROFILE +# undef CGAL_CONCURRENT_PROFILE +# endif +#endif + +#ifdef CGAL_CONCURRENT_PROFILE +# include "tbb/concurrent_hash_map.h" +#endif + namespace CGAL { struct Profile_counter { Profile_counter(const std::string & ss) - : i(0), s(ss) {} + : s(ss) + { + i = 0; // needed here because of tbb::atomic + } void operator++() { ++i; } @@ -70,7 +91,11 @@ } private: +#ifdef CGAL_CONCURRENT_PROFILE + tbb::atomic i; +#else unsigned int i; +#endif const std::string s; }; @@ -78,10 +103,27 @@ struct Profile_histogram_counter { +private: +#ifdef CGAL_CONCURRENT_PROFILE + typedef tbb::concurrent_hash_map Counters; +#else + typedef std::map Counters; +#endif + +public: Profile_histogram_counter(const std::string & ss) : s(ss) {} - void operator()(unsigned i) { ++counters[i]; } + void operator()(unsigned i) + { +#ifdef CGAL_CONCURRENT_PROFILE + Counters::accessor a; + counters.insert(a, i); + ++a->second; +#else + ++counters[i]; +#endif + } ~Profile_histogram_counter() { @@ -100,7 +142,6 @@ } private: - typedef std::map Counters; Counters counters; const std::string s; }; @@ -109,7 +150,10 @@ struct Profile_branch_counter { Profile_branch_counter(const std::string & ss) - : i(0), j(0), s(ss) {} + : s(ss) + { + i = j = 0; // needed here because of tbb::atomic + } void operator++() { ++i; } @@ -123,7 +167,11 @@ } private: +#ifdef CGAL_CONCURRENT_PROFILE + tbb::atomic i, j; +#else unsigned int i, j; +#endif const std::string s; }; @@ -131,7 +179,10 @@ struct Profile_branch_counter_3 { Profile_branch_counter_3(const std::string & ss) - : i(0), j(0), k(0), s(ss) {} + : s(ss) + { + i = j = k = 0; // needed here because of tbb::atomic + } void operator++() { ++i; } @@ -147,7 +198,11 @@ } private: +#ifdef CGAL_CONCURRENT_PROFILE + tbb::atomic i, j, k; +#else unsigned int i, j, k; +#endif const std::string s; }; diff -Nru cgal-4.4/include/CGAL/property_map.h cgal-4.5/include/CGAL/property_map.h --- cgal-4.4/include/CGAL/property_map.h 2013-06-29 19:00:35.000000000 +0000 +++ cgal-4.5/include/CGAL/property_map.h 2014-08-29 13:58:16.000000000 +0000 @@ -27,6 +27,8 @@ #include #else #include + #include + #endif #include diff -Nru cgal-4.4/include/CGAL/Quotient.h cgal-4.5/include/CGAL/Quotient.h --- cgal-4.4/include/CGAL/Quotient.h 2013-10-12 19:00:22.000000000 +0000 +++ cgal-4.5/include/CGAL/Quotient.h 2014-08-29 13:58:16.000000000 +0000 @@ -861,6 +861,7 @@ typedef CGAL::Quotient Nested; static inline Real epsilon() { return NumTraits::epsilon(); } + static inline Real dummy_precision() { return NumTraits::dummy_precision(); } enum { IsInteger = 0, diff -Nru cgal-4.4/include/CGAL/refine_mesh_3.h cgal-4.5/include/CGAL/refine_mesh_3.h --- cgal-4.4/include/CGAL/refine_mesh_3.h 2013-07-06 19:00:27.000000000 +0000 +++ cgal-4.5/include/CGAL/refine_mesh_3.h 2014-08-29 13:58:16.000000000 +0000 @@ -26,6 +26,7 @@ #define CGAL_REFINE_MESH_3_H #include +#include #include #include #include @@ -69,6 +70,22 @@ Vertex_handle new_vertex = r_c3t3_.triangulation().insert(point); r_c3t3_.set_index(new_vertex, index); r_c3t3_.set_dimension(new_vertex, dimension); + +#if defined(CGAL_LINKED_WITH_TBB)\ + && !defined(CGAL_PARALLEL_MESH_3_DO_NOT_ADD_OUTSIDE_POINTS_ON_A_FAR_SPHERE) + if (boost::is_convertible::value) + { + if (dimension == -1) + r_c3t3_.add_far_point(new_vertex); + } +#endif +#ifdef CGAL_SEQUENTIAL_MESH_3_ADD_OUTSIDE_POINTS_ON_A_FAR_SPHERE + if (boost::is_convertible::value) + { + if (dimension == -1) + r_c3t3_.add_far_point(new_vertex); + } +#endif } private: @@ -314,6 +331,11 @@ CGAL_MESH_BOOLEAN_PARAMETER(Reset,reset_c3t3,no_reset_c3t3) // CGAL_MESH_BOOLEAN_PARAMETER defined in +// see +CGAL_PRAGMA_DIAG_PUSH +// see +CGAL_MESH_3_IGNORE_BOOST_PARAMETER_NAME_WARNINGS + // ----------------------------------- // Parameters // ----------------------------------- @@ -323,7 +345,8 @@ BOOST_PARAMETER_NAME( lloyd_param ) BOOST_PARAMETER_NAME( reset_param ) BOOST_PARAMETER_NAME( mesh_options_param ) - + +CGAL_PRAGMA_DIAG_POP } // end namespace parameters diff -Nru cgal-4.4/include/CGAL/Regular_triangulation_3.h cgal-4.5/include/CGAL/Regular_triangulation_3.h --- cgal-4.4/include/CGAL/Regular_triangulation_3.h 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/include/CGAL/Regular_triangulation_3.h 2014-08-29 13:58:17.000000000 +0000 @@ -19,6 +19,7 @@ // Author(s) : Monique Teillaud // Sylvain Pion // Christophe Delage +// Clement Jamin #ifndef CGAL_REGULAR_TRIANGULATION_3_H #define CGAL_REGULAR_TRIANGULATION_3_H @@ -26,6 +27,9 @@ #include #include +#ifdef CGAL_LINKED_WITH_TBB +# include +#endif #include #include @@ -38,6 +42,9 @@ #include #include #endif //CGAL_TRIANGULATION_3_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO +#ifdef CGAL_TRIANGULATION_3_PROFILING +# include +#endif #if defined(BOOST_MSVC) # pragma warning(push) @@ -46,269 +53,405 @@ namespace CGAL { -template < class Gt, class Tds_ = Default > -class Regular_triangulation_3 - : public Triangulation_3, - Regular_triangulation_cell_base_3 > >::type> -{ - typedef Regular_triangulation_3 Self; + /************************************************ + * + * Regular_triangulation_3 class + * + ************************************************/ + + template < class Gt, class Tds_ = Default, class Lock_data_structure_ = Default > + class Regular_triangulation_3 + : public Triangulation_3< + Gt, + typename Default::Get, + Regular_triangulation_cell_base_3 > >::type, + Lock_data_structure_> + { + typedef Regular_triangulation_3 Self; + + typedef typename Default::Get, + Regular_triangulation_cell_base_3 > >::type Tds; + + typedef Triangulation_3 Tr_Base; + + public: + + typedef Tds Triangulation_data_structure; + typedef Gt Geom_traits; + + typedef typename Tr_Base::Concurrency_tag Concurrency_tag; + typedef typename Tr_Base::Lock_data_structure Lock_data_structure; - typedef typename Default::Get, - Regular_triangulation_cell_base_3 > >::type Tds; - - typedef Triangulation_3 Tr_Base; - -public: - - typedef Tds Triangulation_data_structure; - typedef Gt Geom_traits; - - typedef typename Tr_Base::Vertex_handle Vertex_handle; - typedef typename Tr_Base::Cell_handle Cell_handle; - typedef typename Tr_Base::Vertex Vertex; - typedef typename Tr_Base::Cell Cell; - typedef typename Tr_Base::Facet Facet; - typedef typename Tr_Base::Edge Edge; - - typedef typename Tr_Base::size_type size_type; - typedef typename Tr_Base::Locate_type Locate_type; - typedef typename Tr_Base::Cell_iterator Cell_iterator; - typedef typename Tr_Base::Facet_iterator Facet_iterator; - typedef typename Tr_Base::Edge_iterator Edge_iterator; - typedef typename Tr_Base::Facet_circulator Facet_circulator; - - typedef typename Tr_Base::Finite_vertices_iterator Finite_vertices_iterator; - typedef typename Tr_Base::Finite_cells_iterator Finite_cells_iterator; - typedef typename Tr_Base::Finite_facets_iterator Finite_facets_iterator; - typedef typename Tr_Base::Finite_edges_iterator Finite_edges_iterator; - typedef typename Tr_Base::All_cells_iterator All_cells_iterator; - - typedef typename Gt::Weighted_point_3 Weighted_point; - typedef typename Gt::Bare_point Bare_point; - typedef typename Gt::Segment_3 Segment; - typedef typename Gt::Triangle_3 Triangle; - typedef typename Gt::Tetrahedron_3 Tetrahedron; - - // types for dual: - typedef typename Gt::Line_3 Line; - typedef typename Gt::Ray_3 Ray; - typedef typename Gt::Plane_3 Plane; - typedef typename Gt::Object_3 Object; + typedef typename Tr_Base::Vertex_handle Vertex_handle; + typedef typename Tr_Base::Cell_handle Cell_handle; + typedef typename Tr_Base::Vertex Vertex; + typedef typename Tr_Base::Cell Cell; + typedef typename Tr_Base::Facet Facet; + typedef typename Tr_Base::Edge Edge; + + typedef typename Tr_Base::size_type size_type; + typedef typename Tr_Base::Locate_type Locate_type; + typedef typename Tr_Base::Cell_iterator Cell_iterator; + typedef typename Tr_Base::Facet_iterator Facet_iterator; + typedef typename Tr_Base::Edge_iterator Edge_iterator; + typedef typename Tr_Base::Facet_circulator Facet_circulator; + + typedef typename Tr_Base::Finite_vertices_iterator Finite_vertices_iterator; + typedef typename Tr_Base::Finite_cells_iterator Finite_cells_iterator; + typedef typename Tr_Base::Finite_facets_iterator Finite_facets_iterator; + typedef typename Tr_Base::Finite_edges_iterator Finite_edges_iterator; + typedef typename Tr_Base::All_cells_iterator All_cells_iterator; + + typedef typename Gt::Weighted_point_3 Weighted_point; + typedef typename Gt::Bare_point Bare_point; + typedef typename Gt::Segment_3 Segment; + typedef typename Gt::Triangle_3 Triangle; + typedef typename Gt::Tetrahedron_3 Tetrahedron; + + // types for dual: + typedef typename Gt::Line_3 Line; + typedef typename Gt::Ray_3 Ray; + typedef typename Gt::Plane_3 Plane; + typedef typename Gt::Object_3 Object; - //Tag to distinguish Delaunay from Regular triangulations - typedef Tag_true Weighted_tag; + //Tag to distinguish Delaunay from Regular triangulations + typedef Tag_true Weighted_tag; - using Tr_Base::cw; - using Tr_Base::ccw; + using Tr_Base::cw; + using Tr_Base::ccw; #ifndef CGAL_CFG_USING_BASE_MEMBER_BUG_2 - using Tr_Base::geom_traits; + using Tr_Base::geom_traits; #endif - using Tr_Base::number_of_vertices; - using Tr_Base::dimension; - using Tr_Base::finite_facets_begin; - using Tr_Base::finite_facets_end; - using Tr_Base::finite_vertices_begin; - using Tr_Base::finite_vertices_end; - using Tr_Base::finite_cells_begin; - using Tr_Base::finite_cells_end; - using Tr_Base::finite_edges_begin; - using Tr_Base::finite_edges_end; - using Tr_Base::tds; - using Tr_Base::infinite_vertex; - using Tr_Base::next_around_edge; - using Tr_Base::vertex_triple_index; - using Tr_Base::mirror_vertex; - using Tr_Base::mirror_index; - using Tr_Base::orientation; - using Tr_Base::coplanar_orientation; - using Tr_Base::adjacent_vertices; - using Tr_Base::construct_segment; - using Tr_Base::incident_facets; - using Tr_Base::insert_in_conflict; - using Tr_Base::is_infinite; - using Tr_Base::is_valid_finite; - using Tr_Base::locate; - using Tr_Base::side_of_segment; - using Tr_Base::side_of_edge; - using Tr_Base::find_conflicts; - using Tr_Base::is_valid; - - Regular_triangulation_3(const Gt & gt = Gt()) - : Tr_Base(gt), hidden_point_visitor(this) - {} + using Tr_Base::number_of_vertices; + using Tr_Base::dimension; + using Tr_Base::finite_facets_begin; + using Tr_Base::finite_facets_end; + using Tr_Base::finite_vertices_begin; + using Tr_Base::finite_vertices_end; + using Tr_Base::finite_cells_begin; + using Tr_Base::finite_cells_end; + using Tr_Base::finite_edges_begin; + using Tr_Base::finite_edges_end; + using Tr_Base::tds; + using Tr_Base::infinite_vertex; + using Tr_Base::next_around_edge; + using Tr_Base::vertex_triple_index; + using Tr_Base::mirror_vertex; + using Tr_Base::mirror_index; + using Tr_Base::orientation; + using Tr_Base::coplanar_orientation; + using Tr_Base::adjacent_vertices; + using Tr_Base::construct_segment; + using Tr_Base::incident_facets; + using Tr_Base::insert_in_conflict; + using Tr_Base::is_infinite; + using Tr_Base::is_valid_finite; + using Tr_Base::locate; + using Tr_Base::side_of_segment; + using Tr_Base::side_of_edge; + using Tr_Base::find_conflicts; + using Tr_Base::is_valid; + + Regular_triangulation_3(const Gt & gt = Gt(), Lock_data_structure *lock_ds = NULL) + : Tr_Base(gt, lock_ds), hidden_point_visitor(this) + {} + + Regular_triangulation_3(Lock_data_structure *lock_ds, const Gt & gt = Gt()) + : Tr_Base(lock_ds, gt), hidden_point_visitor(this) + {} - Regular_triangulation_3(const Regular_triangulation_3 & rt) - : Tr_Base(rt), hidden_point_visitor(this) - { + Regular_triangulation_3(const Regular_triangulation_3 & rt) + : Tr_Base(rt), hidden_point_visitor(this) + { CGAL_triangulation_postcondition( is_valid() ); - } + } - //insertion - template < typename InputIterator > - Regular_triangulation_3(InputIterator first, InputIterator last, - const Gt & gt = Gt()) - : Tr_Base(gt), hidden_point_visitor(this) - { + //insertion + template < typename InputIterator > + Regular_triangulation_3(InputIterator first, InputIterator last, + const Gt & gt = Gt(), Lock_data_structure *lock_ds = NULL) + : Tr_Base(gt, lock_ds), hidden_point_visitor(this) + { insert(first, last); - } + } + + template < typename InputIterator > + Regular_triangulation_3(InputIterator first, InputIterator last, + Lock_data_structure *lock_ds, const Gt & gt = Gt()) + : Tr_Base(gt, lock_ds), hidden_point_visitor(this) + { + insert(first, last); + } #ifndef CGAL_TRIANGULATION_3_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO - template < class InputIterator > - std::ptrdiff_t - insert( InputIterator first, InputIterator last, - typename boost::enable_if< - boost::is_convertible< - typename std::iterator_traits::value_type, - Weighted_point - > - >::type* = NULL - ) + template < class InputIterator > + std::ptrdiff_t + insert( InputIterator first, InputIterator last, + typename boost::enable_if< + boost::is_convertible< + typename std::iterator_traits::value_type, + Weighted_point + > + >::type* = NULL + ) #else - template < class InputIterator > - std::ptrdiff_t - insert( InputIterator first, InputIterator last) + template < class InputIterator > + std::ptrdiff_t + insert( InputIterator first, InputIterator last) #endif //CGAL_TRIANGULATION_3_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO - { - size_type n = number_of_vertices(); + { +#ifdef CGAL_CONCURRENT_TRIANGULATION_3_PROFILING + static Profile_branch_counter_3 bcounter( + "early withdrawals / late withdrawals / successes [Regular_tri_3::insert]"); +#endif + +#ifdef CGAL_TRIANGULATION_3_PROFILING + WallClockTimer t; +#endif - std::vector points(first, last); - spatial_sort (points.begin(), points.end(), geom_traits()); + size_type n = number_of_vertices(); + std::vector points(first, last); + spatial_sort (points.begin(), points.end(), geom_traits()); + + // Parallel +#ifdef CGAL_LINKED_WITH_TBB + if (this->is_parallel()) + { + size_t num_points = points.size(); + Cell_handle hint; + std::vector far_sphere_vertices; + +#ifdef CGAL_CONCURRENT_TRIANGULATION_3_ADD_TEMPORARY_POINTS_ON_FAR_SPHERE + const size_t MIN_NUM_POINTS_FOR_FAR_SPHERE_POINTS = 1000000; + if (num_points >= MIN_NUM_POINTS_FOR_FAR_SPHERE_POINTS) + { + // Add temporary vertices on a "far sphere" to reduce contention on + // the infinite vertex + + // Get bbox + const Bbox_3 &bbox = *this->get_bbox(); + // Compute radius for far sphere + const double& xdelta = bbox.xmax() - bbox.xmin(); + const double& ydelta = bbox.ymax() - bbox.ymin(); + const double& zdelta = bbox.zmax() - bbox.zmin(); + const double radius = 1.3 * 0.5 * std::sqrt(xdelta*xdelta + + ydelta*ydelta + + zdelta*zdelta); + + // WARNING - TODO: this code has to be fixed because Vector_3 is not + // required by the traits concept + const typename Gt::Vector_3 center( + bbox.xmin() + 0.5*xdelta, + bbox.ymin() + 0.5*ydelta, + bbox.zmin() + 0.5*zdelta); + Random_points_on_sphere_3 random_point(radius); + const int NUM_PSEUDO_INFINITE_VERTICES = static_cast( + tbb::task_scheduler_init::default_num_threads() * 3.5); + std::vector points_on_far_sphere; + for (int i = 0 ; i < NUM_PSEUDO_INFINITE_VERTICES ; ++i, ++random_point) + points_on_far_sphere.push_back(*random_point + center); + + spatial_sort(points_on_far_sphere.begin(), + points_on_far_sphere.end(), + geom_traits()); + + std::vector::const_iterator it_p = points_on_far_sphere.begin(); + std::vector::const_iterator it_p_end = points_on_far_sphere.end(); + for ( ; it_p != it_p_end ; ++it_p) + { + Locate_type lt; + Cell_handle c; + int li, lj; + + c = locate (*it_p, lt, li, lj, hint); + Vertex_handle v = insert (*it_p, lt, c, li, lj); + hint = (v == Vertex_handle() ? c : v->cell()); - Cell_handle hint; - for (typename std::vector::const_iterator p = points.begin(), - end = points.end(); p != end; ++p) - { - Locate_type lt; - Cell_handle c; - int li, lj; - c = locate (*p, lt, li, lj, hint); + far_sphere_vertices.push_back(v); + } + } +#endif // CGAL_CONCURRENT_TRIANGULATION_3_ADD_TEMPORARY_POINTS_ON_FAR_SPHERE + + int i = 0; + // Insert "num_points_seq" points sequentially + // (or more if dim < 3 after that) + size_t num_points_seq = (std::min)(num_points, (size_t)500); + while (dimension() < 3 || i < num_points_seq) + { + Locate_type lt; + Cell_handle c; + int li, lj; - Vertex_handle v = insert (*p, lt, c, li, lj); + c = locate (points[i], lt, li, lj, hint); + Vertex_handle v = insert (points[i], lt, c, li, lj); - hint = v == Vertex_handle() ? c : v->cell(); + hint = (v == Vertex_handle() ? c : v->cell()); + ++i; + } + + tbb::enumerable_thread_specific tls_hint(hint->vertex(0)); + tbb::parallel_for( + tbb::blocked_range( i, num_points ), + Insert_point(*this, points, tls_hint) + ); + +#ifdef CGAL_CONCURRENT_TRIANGULATION_3_ADD_TEMPORARY_POINTS_ON_FAR_SPHERE + if (num_points >= MIN_NUM_POINTS_FOR_FAR_SPHERE_POINTS) + { + // Remove the temporary vertices on far sphere + remove(far_sphere_vertices.begin(), far_sphere_vertices.end()); + } +#endif // CGAL_CONCURRENT_TRIANGULATION_3_ADD_TEMPORARY_POINTS_ON_FAR_SPHERE + } + // Sequential + else +#endif // CGAL_LINKED_WITH_TBB + { + Cell_handle hint; + for (typename std::vector::const_iterator p = points.begin(), + end = points.end(); p != end; ++p) + { + Locate_type lt; + Cell_handle c; + int li, lj; + c = locate (*p, lt, li, lj, hint); + + Vertex_handle v = insert (*p, lt, c, li, lj); + + hint = v == Vertex_handle() ? c : v->cell(); + } + } +#ifdef CGAL_TRIANGULATION_3_PROFILING + std::cerr << "Points inserted in " << t.elapsed() << " seconds." << std::endl; +#endif + return number_of_vertices() - n; } - return number_of_vertices() - n; - } - + #ifndef CGAL_TRIANGULATION_3_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO -private: - //top stands for tuple-or-pair - template - const Weighted_point& top_get_first(const std::pair& pair) const { return pair.first; } - template - const Info& top_get_second(const std::pair& pair) const { return pair.second; } - template - const Weighted_point& top_get_first(const boost::tuple& tuple) const { return boost::get<0>(tuple); } - template - const Info& top_get_second(const boost::tuple& tuple) const { return boost::get<1>(tuple); } - - template - std::ptrdiff_t insert_with_info(InputIterator first,InputIterator last) - { - size_type n = number_of_vertices(); - std::vector indices; - std::vector points; - std::vector infos; - std::ptrdiff_t index=0; - for (InputIterator it=first;it!=last;++it){ - Tuple_or_pair pair = *it; - points.push_back( top_get_first(pair) ); - infos.push_back ( top_get_second(pair) ); - indices.push_back(index++); - } + private: + //top stands for tuple-or-pair + template + const Weighted_point& top_get_first(const std::pair& pair) const { return pair.first; } + template + const Info& top_get_second(const std::pair& pair) const { return pair.second; } + template + const Weighted_point& top_get_first(const boost::tuple& tuple) const { return boost::get<0>(tuple); } + template + const Info& top_get_second(const boost::tuple& tuple) const { return boost::get<1>(tuple); } - typedef Spatial_sort_traits_adapter_3 Search_traits; - - spatial_sort( indices.begin(),indices.end(),Search_traits(&(points[0]),geom_traits()) ); + template + std::ptrdiff_t insert_with_info(InputIterator first,InputIterator last) + { + size_type n = number_of_vertices(); + std::vector indices; + std::vector points; + std::vector infos; + std::ptrdiff_t index=0; + for (InputIterator it=first;it!=last;++it){ + Tuple_or_pair pair = *it; + points.push_back( top_get_first(pair) ); + infos.push_back ( top_get_second(pair) ); + indices.push_back(index++); + } + + typedef Spatial_sort_traits_adapter_3 Search_traits; + + spatial_sort( indices.begin(),indices.end(),Search_traits(&(points[0]),geom_traits()) ); + + Cell_handle hint; + for (typename std::vector::const_iterator + it = indices.begin(), end = indices.end(); + it != end; ++it) + { + Locate_type lt; + Cell_handle c; + int li, lj; + c = locate (points[*it], lt, li, lj, hint); - Cell_handle hint; - for (typename std::vector::const_iterator - it = indices.begin(), end = indices.end(); - it != end; ++it) - { - Locate_type lt; - Cell_handle c; - int li, lj; - c = locate (points[*it], lt, li, lj, hint); - - Vertex_handle v = insert (points[*it], lt, c, li, lj); - if (v!=Vertex_handle()){ - v->info()=infos[*it]; - hint=v->cell(); + Vertex_handle v = insert (points[*it], lt, c, li, lj); + if (v!=Vertex_handle()){ + v->info()=infos[*it]; + hint=v->cell(); + } + else + hint=c; } - else - hint=c; + + return number_of_vertices() - n; } - return number_of_vertices() - n; - } - -public: + public: - template < class InputIterator > - std::ptrdiff_t - insert( InputIterator first, - InputIterator last, - typename boost::enable_if< - boost::is_convertible< - typename std::iterator_traits::value_type, - std::pair::type> - > - >::type* = NULL - ) - {return insert_with_info< std::pair::type> >(first,last);} - - template - std::ptrdiff_t - insert( boost::zip_iterator< boost::tuple > first, - boost::zip_iterator< boost::tuple > last, - typename boost::enable_if< - boost::mpl::and_< - typename boost::is_convertible< typename std::iterator_traits::value_type, Weighted_point >, - typename boost::is_convertible< typename std::iterator_traits::value_type, typename internal::Info_check::type > - > - >::type* =NULL - ) - {return insert_with_info< boost::tuple::type> >(first,last);} + template < class InputIterator > + std::ptrdiff_t + insert( InputIterator first, + InputIterator last, + typename boost::enable_if< + boost::is_convertible< + typename std::iterator_traits::value_type, + std::pair::type> + > + >::type* = NULL + ) + {return insert_with_info< std::pair::type> >(first,last);} + + template + std::ptrdiff_t + insert( boost::zip_iterator< boost::tuple > first, + boost::zip_iterator< boost::tuple > last, + typename boost::enable_if< + boost::mpl::and_< + typename boost::is_convertible< typename std::iterator_traits::value_type, Weighted_point >, + typename boost::is_convertible< typename std::iterator_traits::value_type, typename internal::Info_check::type > + > + >::type* =NULL + ) + {return insert_with_info< boost::tuple::type> >(first,last);} #endif //CGAL_TRIANGULATION_3_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO - - Vertex_handle insert(const Weighted_point & p, Vertex_handle hint) - { - return insert(p, hint == Vertex_handle() ? this->infinite_cell() : hint->cell()); - } - - Vertex_handle insert(const Weighted_point & p, - Cell_handle start = Cell_handle()); - Vertex_handle insert(const Weighted_point & p, Locate_type lt, - Cell_handle c, int li, int); - - template - Vertex_handle - insert_in_hole(const Weighted_point & p, CellIt cell_begin, CellIt cell_end, - Cell_handle begin, int i); - - template - Vertex_handle - insert_in_hole(const Weighted_point & p, CellIt cell_begin, CellIt cell_end, - Cell_handle begin, int i, Vertex_handle newv); - - template - Triple - find_conflicts(const Weighted_point &p, Cell_handle c, - OutputIteratorBoundaryFacets bfit, - OutputIteratorCells cit, - OutputIteratorInternalFacets ifit) const - { + Vertex_handle insert(const Weighted_point & p, Vertex_handle hint, + bool *could_lock_zone = NULL) + { + return insert(p, + hint == Vertex_handle() ? this->infinite_cell() : hint->cell(), + could_lock_zone); + } + + Vertex_handle insert(const Weighted_point & p, + Cell_handle start = Cell_handle(), bool *could_lock_zone = NULL); + + Vertex_handle insert(const Weighted_point & p, Locate_type lt, + Cell_handle c, int li, int, bool *could_lock_zone = NULL); + + template + Vertex_handle + insert_in_hole(const Weighted_point & p, CellIt cell_begin, CellIt cell_end, + Cell_handle begin, int i); + + template + Vertex_handle + insert_in_hole(const Weighted_point & p, CellIt cell_begin, CellIt cell_end, + Cell_handle begin, int i, Vertex_handle newv); + + template + Triple + find_conflicts(const Weighted_point &p, Cell_handle c, + OutputIteratorBoundaryFacets bfit, + OutputIteratorCells cit, + OutputIteratorInternalFacets ifit + , bool *could_lock_zone = NULL + , const Facet *this_facet_must_be_in_the_cz = NULL + , bool *the_facet_is_in_its_cz = NULL + ) const + { CGAL_triangulation_precondition(dimension() >= 2); std::vector cells; @@ -317,73 +460,84 @@ facets.reserve(64); if (dimension() == 2) { - Conflict_tester_2 tester(p, this); - if (! tester (c)) return make_triple (bfit, cit, ifit); - ifit = Tr_Base::find_conflicts - (c, tester, - make_triple(std::back_inserter(facets), - std::back_inserter(cells), - ifit)).third; + Conflict_tester_2 tester(p, this); + if (! tester (c)) return make_triple (bfit, cit, ifit); + ifit = Tr_Base::find_conflicts + (c, tester, + make_triple(std::back_inserter(facets), + std::back_inserter(cells), + ifit) + , could_lock_zone + , this_facet_must_be_in_the_cz + , the_facet_is_in_its_cz + ).third; } else { - Conflict_tester_3 tester(p, this); - if (! tester (c)) return make_triple (bfit, cit, ifit); - ifit = Tr_Base::find_conflicts - (c, tester, - make_triple(std::back_inserter(facets), - std::back_inserter(cells), - ifit)).third; + Conflict_tester_3 tester(p, this); + if (! tester (c)) return make_triple (bfit, cit, ifit); + ifit = Tr_Base::find_conflicts + (c, tester, + make_triple(std::back_inserter(facets), + std::back_inserter(cells), + ifit) + , could_lock_zone + , this_facet_must_be_in_the_cz + , the_facet_is_in_its_cz + ).third; } // Reset the conflict flag on the boundary. for(typename std::vector::iterator fit=facets.begin(); - fit != facets.end(); ++fit) { - fit->first->neighbor(fit->second)->tds_data().clear(); - *bfit++ = *fit; + fit != facets.end(); ++fit) { + fit->first->neighbor(fit->second)->tds_data().clear(); + *bfit++ = *fit; } // Reset the conflict flag in the conflict cells. for(typename std::vector::iterator ccit=cells.begin(); ccit != cells.end(); ++ccit) { - (*ccit)->tds_data().clear(); - *cit++ = *ccit; + (*ccit)->tds_data().clear(); + *cit++ = *ccit; } return make_triple(bfit, cit, ifit); - } + } - template - std::pair - find_conflicts(const Weighted_point &p, Cell_handle c, - OutputIteratorBoundaryFacets bfit, - OutputIteratorCells cit) const - { + template + std::pair + find_conflicts(const Weighted_point &p, Cell_handle c, + OutputIteratorBoundaryFacets bfit, + OutputIteratorCells cit + , bool *could_lock_zone = NULL + ) const + { Triple t = find_conflicts(p, c, bfit, cit, - Emptyset_iterator()); + OutputIteratorCells, + Emptyset_iterator> t = find_conflicts(p, c, bfit, cit, + Emptyset_iterator(), + could_lock_zone); return std::make_pair(t.first, t.second); - } + } - // Returns the vertices on the interior of the conflict hole. - template - OutputIterator - vertices_inside_conflict_zone(const Weighted_point&p, Cell_handle c, - OutputIterator res) const - { + // Returns the vertices on the interior of the conflict hole. + template + OutputIterator + vertices_inside_conflict_zone(const Weighted_point&p, Cell_handle c, + OutputIterator res) const + { CGAL_triangulation_precondition(dimension() >= 2); // Get the facets on the boundary of the hole, and the cells of the hole std::vector cells; std::vector facets; find_conflicts(p, c, std::back_inserter(facets), - std::back_inserter(cells), Emptyset_iterator()); + std::back_inserter(cells), Emptyset_iterator()); // Put all vertices on the hole in 'vertices' const int d = dimension(); std::set vertices; - for (typename std::vector::const_iterator - it = cells.begin(), - end = cells.end(); it != end; ++it) + for (typename std::vector::const_iterator + it = cells.begin(), + end = cells.end(); it != end; ++it) { for(int i = 0; i <= d; ++i) { vertices.insert((*it)->vertex(i)); @@ -392,527 +546,779 @@ // Then extract the vertices of the boundary and remove them from // 'vertices' if (dimension() == 3) { - for (typename std::vector::const_iterator i = facets.begin(); - i != facets.end(); ++i) { - vertices.erase(i->first->vertex((i->second+1)&3)); - vertices.erase(i->first->vertex((i->second+2)&3)); - vertices.erase(i->first->vertex((i->second+3)&3)); - } + for (typename std::vector::const_iterator i = facets.begin(); + i != facets.end(); ++i) { + vertices.erase(i->first->vertex((i->second+1)&3)); + vertices.erase(i->first->vertex((i->second+2)&3)); + vertices.erase(i->first->vertex((i->second+3)&3)); + } } else { - for (typename std::vector::const_iterator i = facets.begin(); - i != facets.end(); ++i) { - vertices.erase(i->first->vertex(cw(i->second))); - vertices.erase(i->first->vertex(ccw(i->second))); - } + for (typename std::vector::const_iterator i = facets.begin(); + i != facets.end(); ++i) { + vertices.erase(i->first->vertex(cw(i->second))); + vertices.erase(i->first->vertex(ccw(i->second))); + } } return std::copy(vertices.begin(), vertices.end(), res); - } + } #ifndef CGAL_NO_DEPRECATED_CODE - // Returns the vertices on the boundary of the conflict hole. - template - OutputIterator - vertices_in_conflict(const Weighted_point&p, Cell_handle c, OutputIterator res) const - { - return vertices_on_conflict_zone_boundary(p, c, res); - } + // Returns the vertices on the boundary of the conflict hole. + template + OutputIterator + vertices_in_conflict(const Weighted_point&p, Cell_handle c, OutputIterator res) const + { + return vertices_on_conflict_zone_boundary(p, c, res); + } #endif // CGAL_NO_DEPRECATED_CODE - // Returns the vertices on the boundary of the conflict hole. - template - OutputIterator - vertices_on_conflict_zone_boundary(const Weighted_point&p, Cell_handle c, - OutputIterator res) const - { + // Returns the vertices on the boundary of the conflict hole. + template + OutputIterator + vertices_on_conflict_zone_boundary(const Weighted_point&p, Cell_handle c, + OutputIterator res) const + { CGAL_triangulation_precondition(dimension() >= 2); // Get the facets on the boundary of the hole. std::vector facets; find_conflicts(p, c, std::back_inserter(facets), - Emptyset_iterator(), Emptyset_iterator()); + Emptyset_iterator(), Emptyset_iterator()); // Then extract uniquely the vertices. std::set vertices; if (dimension() == 3) { - for (typename std::vector::const_iterator i = facets.begin(); - i != facets.end(); ++i) { - vertices.insert(i->first->vertex((i->second+1)&3)); - vertices.insert(i->first->vertex((i->second+2)&3)); - vertices.insert(i->first->vertex((i->second+3)&3)); - } + for (typename std::vector::const_iterator i = facets.begin(); + i != facets.end(); ++i) { + vertices.insert(i->first->vertex((i->second+1)&3)); + vertices.insert(i->first->vertex((i->second+2)&3)); + vertices.insert(i->first->vertex((i->second+3)&3)); + } } else { - for (typename std::vector::const_iterator i = facets.begin(); - i != facets.end(); ++i) { - vertices.insert(i->first->vertex(cw(i->second))); - vertices.insert(i->first->vertex(ccw(i->second))); - } + for (typename std::vector::const_iterator i = facets.begin(); + i != facets.end(); ++i) { + vertices.insert(i->first->vertex(cw(i->second))); + vertices.insert(i->first->vertex(ccw(i->second))); + } } return std::copy(vertices.begin(), vertices.end(), res); - } + } - void remove (Vertex_handle v); + void remove (Vertex_handle v); + // Concurrency-safe + // See Triangulation_3::remove for more information + bool remove (Vertex_handle v, bool *could_lock_zone); - template < typename InputIterator > - size_type remove(InputIterator first, InputIterator beyond) - { - CGAL_triangulation_precondition(!this->does_repeat_in_range(first, beyond)); - size_type n = number_of_vertices(); - while (first != beyond) { - remove (*first); - ++first; - } - return n - number_of_vertices(); - } + template < typename InputIterator > + size_type remove(InputIterator first, InputIterator beyond) + { + CGAL_triangulation_precondition(!this->does_repeat_in_range(first, beyond)); + size_type n = number_of_vertices(); - // DISPLACEMENT - Vertex_handle move_point(Vertex_handle v, const Weighted_point & p); +#ifdef CGAL_TRIANGULATION_3_PROFILING + WallClockTimer t; +#endif - // Displacement works only for Regular triangulation - // without hidden points at any time - Vertex_handle move_if_no_collision(Vertex_handle v, const Weighted_point & p); - Vertex_handle move(Vertex_handle v, const Weighted_point & p); + // Parallel +#ifdef CGAL_LINKED_WITH_TBB + if (this->is_parallel()) + { + // TODO: avoid that by asking for ramdom-access iterators? + std::vector vertices(first, beyond); + tbb::concurrent_vector vertices_to_remove_sequentially; + + tbb::parallel_for( + tbb::blocked_range( 0, vertices.size()), + Remove_point(*this, vertices, vertices_to_remove_sequentially) + ); + + // Do the rest sequentially + for ( typename tbb::concurrent_vector::const_iterator + it = vertices_to_remove_sequentially.begin(), + it_end = vertices_to_remove_sequentially.end() + ; it != it_end + ; ++it) + { + remove(*it); + } + } + // Sequential + else +#endif // CGAL_LINKED_WITH_TBB + { + while (first != beyond) { + remove(*first); + ++first; + } + } - // REMOVE CLUSTER - works only when Regular has no hidden point at all - // "regular as Delaunay" - template < typename InputIterator > - size_type remove_cluster(InputIterator first, InputIterator beyond) - { - Self tmp; - Vertex_remover remover (tmp); - return Tr_Base::remove(first, beyond, remover); - } +#ifdef CGAL_TRIANGULATION_3_PROFILING + std::cerr << "Points removed in " << t.elapsed() << " seconds." << std::endl; +#endif + return n - number_of_vertices(); + } -protected: + + template + void remove_and_give_new_cells(Vertex_handle v, OutputItCells cit) + { + Self tmp; + Vertex_remover remover (tmp); + Tr_Base::remove_and_give_new_cells(v, remover, cit); - Oriented_side - side_of_oriented_power_sphere(const Weighted_point &p0, - const Weighted_point &p1, - const Weighted_point &p2, - const Weighted_point &p3, - const Weighted_point &p, - bool perturb = false) const; + CGAL_triangulation_expensive_postcondition(is_valid()); + } - Oriented_side - side_of_oriented_power_circle(const Weighted_point &p0, - const Weighted_point &p1, - const Weighted_point &p2, - const Weighted_point &p, - bool perturb = false) const; - Bounded_side - side_of_bounded_power_circle(const Weighted_point &p0, - const Weighted_point &p1, - const Weighted_point &p2, - const Weighted_point &p, - bool perturb = false) const; + // DISPLACEMENT + Vertex_handle move_point(Vertex_handle v, const Weighted_point & p); - Bounded_side - side_of_bounded_power_segment(const Weighted_point &p0, - const Weighted_point &p1, - const Weighted_point &p, - bool perturb = false) const; + // Displacement works only for Regular triangulation + // without hidden points at any time + Vertex_handle move_if_no_collision(Vertex_handle v, const Weighted_point & p); + Vertex_handle move(Vertex_handle v, const Weighted_point & p); + // REMOVE CLUSTER - works only when Regular has no hidden point at all + // "regular as Delaunay" + template < typename InputIterator > + size_type remove_cluster(InputIterator first, InputIterator beyond) + { + Self tmp; + Vertex_remover remover (tmp); + return Tr_Base::remove(first, beyond, remover); + } + + protected: + + Oriented_side + side_of_oriented_power_sphere(const Weighted_point &p0, + const Weighted_point &p1, + const Weighted_point &p2, + const Weighted_point &p3, + const Weighted_point &p, + bool perturb = false) const; + + Oriented_side + side_of_oriented_power_circle(const Weighted_point &p0, + const Weighted_point &p1, + const Weighted_point &p2, + const Weighted_point &p, + bool perturb = false) const; + + Bounded_side + side_of_bounded_power_circle(const Weighted_point &p0, + const Weighted_point &p1, + const Weighted_point &p2, + const Weighted_point &p, + bool perturb = false) const; + + Bounded_side + side_of_bounded_power_segment(const Weighted_point &p0, + const Weighted_point &p1, + const Weighted_point &p, + bool perturb = false) const; -public: - // Queries - Bounded_side - side_of_power_sphere(Cell_handle c, const Weighted_point &p, - bool perturb = false) const; + public: - Bounded_side - side_of_power_circle(const Facet & f, const Weighted_point & p, - bool /* perturb */ = false) const - { + // Queries + Bounded_side + side_of_power_sphere(Cell_handle c, const Weighted_point &p, + bool perturb = false) const; + + Bounded_side + side_of_power_circle(const Facet & f, const Weighted_point & p, + bool /* perturb */ = false) const + { return side_of_power_circle(f.first, f.second, p); - } + } - Bounded_side - side_of_power_circle(Cell_handle c, int i, const Weighted_point &p, - bool perturb = false) const; + Bounded_side + side_of_power_circle(Cell_handle c, int i, const Weighted_point &p, + bool perturb = false) const; - Bounded_side - side_of_power_segment(Cell_handle c, const Weighted_point &p, - bool perturb = false) const; + Bounded_side + side_of_power_segment(Cell_handle c, const Weighted_point &p, + bool perturb = false) const; - Vertex_handle - nearest_power_vertex_in_cell(const Bare_point& p, - Cell_handle c) const; + Vertex_handle + nearest_power_vertex_in_cell(const Bare_point& p, + Cell_handle c) const; - Vertex_handle - nearest_power_vertex(const Bare_point& p, Cell_handle c = - Cell_handle()) const; + Vertex_handle + nearest_power_vertex(const Bare_point& p, Cell_handle c = + Cell_handle()) const; - bool is_Gabriel(Cell_handle c, int i) const; - bool is_Gabriel(Cell_handle c, int i, int j) const; - bool is_Gabriel(const Facet& f)const ; - bool is_Gabriel(const Edge& e) const; - bool is_Gabriel(Vertex_handle v) const; + bool is_Gabriel(Cell_handle c, int i) const; + bool is_Gabriel(Cell_handle c, int i, int j) const; + bool is_Gabriel(const Facet& f)const ; + bool is_Gabriel(const Edge& e) const; + bool is_Gabriel(Vertex_handle v) const; - // Dual functions - Bare_point dual(Cell_handle c) const; + // Dual functions + Bare_point dual(Cell_handle c) const; - Object dual(const Facet & f) const + Object dual(const Facet & f) const { return dual( f.first, f.second ); } - Object dual(Cell_handle c, int i) const; + Object dual(Cell_handle c, int i) const; - template < class Stream> - Stream& draw_dual(Stream & os) + template < class Stream> + Stream& draw_dual(Stream & os) { for (Finite_facets_iterator fit = finite_facets_begin(), - end = finite_facets_end(); - fit != end; ++fit) { - Object o = dual(*fit); - if (const Segment *s = object_cast(&o)) os << *s; - else if (const Ray *r = object_cast(&o)) os << *r; - else if (const Bare_point *p = object_cast(&o)) os << *p; + end = finite_facets_end(); + fit != end; ++fit) { + Object o = dual(*fit); + if (const Segment *s = object_cast(&o)) os << *s; + else if (const Ray *r = object_cast(&o)) os << *r; + else if (const Bare_point *p = object_cast(&o)) os << *p; } return os; } - bool is_valid(bool verbose = false, int level = 0) const; + bool is_valid(bool verbose = false, int level = 0) const; -protected: - bool - less_power_distance(const Bare_point &p, - const Weighted_point &q, - const Weighted_point &r) const - { - return - geom_traits().compare_power_distance_3_object()(p, q, r) == SMALLER; - } + protected: + bool + less_power_distance(const Bare_point &p, + const Weighted_point &q, + const Weighted_point &r) const + { + return + geom_traits().compare_power_distance_3_object()(p, q, r) == SMALLER; + } - Bare_point - construct_weighted_circumcenter(const Weighted_point &p, - const Weighted_point &q, - const Weighted_point &r, - const Weighted_point &s) const - { - return geom_traits().construct_weighted_circumcenter_3_object()(p,q,r,s); - } + Bare_point + construct_weighted_circumcenter(const Weighted_point &p, + const Weighted_point &q, + const Weighted_point &r, + const Weighted_point &s) const + { + return geom_traits().construct_weighted_circumcenter_3_object()(p,q,r,s); + } - Bare_point - construct_weighted_circumcenter(const Weighted_point &p, - const Weighted_point &q, - const Weighted_point &r) const - { - return geom_traits().construct_weighted_circumcenter_3_object()(p,q,r); - } + Bare_point + construct_weighted_circumcenter(const Weighted_point &p, + const Weighted_point &q, + const Weighted_point &r) const + { + return geom_traits().construct_weighted_circumcenter_3_object()(p,q,r); + } - Line - construct_perpendicular_line(const Plane &pl, const Bare_point &p) const - { + Line + construct_perpendicular_line(const Plane &pl, const Bare_point &p) const + { return geom_traits().construct_perpendicular_line_3_object()(pl, p); - } + } - Plane - construct_plane(const Bare_point &p, const Bare_point &q, const Bare_point &r) const - { + Plane + construct_plane(const Bare_point &p, const Bare_point &q, const Bare_point &r) const + { return geom_traits().construct_plane_3_object()(p, q, r); - } + } - Ray - construct_ray(const Bare_point &p, const Line &l) const - { + Ray + construct_ray(const Bare_point &p, const Line &l) const + { return geom_traits().construct_ray_3_object()(p, l); - } + } - Object - construct_object(const Bare_point &p) const - { + Object + construct_object(const Bare_point &p) const + { return geom_traits().construct_object_3_object()(p); - } + } - Object - construct_object(const Segment &s) const - { + Object + construct_object(const Segment &s) const + { return geom_traits().construct_object_3_object()(s); - } + } - Object - construct_object(const Ray &r) const - { + Object + construct_object(const Ray &r) const + { return geom_traits().construct_object_3_object()(r); - } + } - Vertex_handle - nearest_power_vertex(const Bare_point &p, - Vertex_handle v, - Vertex_handle w) const - { + Vertex_handle + nearest_power_vertex(const Bare_point &p, + Vertex_handle v, + Vertex_handle w) const + { // In case of equality, v is returned. CGAL_triangulation_precondition(v != w); if (is_infinite(v)) return w; if (is_infinite(w)) return v; return less_power_distance(p, w->point(), v->point()) ? w : v; - } + } - Oriented_side - power_test(const Weighted_point &p, const Weighted_point &q) const - { + Oriented_side + power_test(const Weighted_point &p, const Weighted_point &q) const + { CGAL_triangulation_precondition(this->equal(p, q)); return geom_traits().power_test_3_object()(p, q); - } + } - Oriented_side - power_test(const Weighted_point &p, const Weighted_point &q, - const Weighted_point &r) const - { + Oriented_side + power_test(const Weighted_point &p, const Weighted_point &q, + const Weighted_point &r) const + { CGAL_triangulation_precondition(this->collinear(p, q, r)); return geom_traits().power_test_3_object()(p, q, r); - } + } - Oriented_side - power_test(const Weighted_point &p, const Weighted_point &q, - const Weighted_point &r, const Weighted_point &s) const - { + Oriented_side + power_test(const Weighted_point &p, const Weighted_point &q, + const Weighted_point &r, const Weighted_point &s) const + { CGAL_triangulation_precondition(this->coplanar(p, q, r, s)); return geom_traits().power_test_3_object()(p, q, r, s); - } + } - Oriented_side - power_test(const Weighted_point &p, const Weighted_point &q, - const Weighted_point &r, const Weighted_point &s, - const Weighted_point &t) const - { + Oriented_side + power_test(const Weighted_point &p, const Weighted_point &q, + const Weighted_point &r, const Weighted_point &s, + const Weighted_point &t) const + { return geom_traits().power_test_3_object()(p, q, r, s, t); - } + } - bool in_conflict_3(const Weighted_point &p, const Cell_handle c) const - { + bool in_conflict_3(const Weighted_point &p, const Cell_handle c) const + { return side_of_power_sphere(c, p, true) == ON_BOUNDED_SIDE; - } + } - bool in_conflict_2(const Weighted_point &p, const Cell_handle c, int i) const - { + bool in_conflict_2(const Weighted_point &p, const Cell_handle c, int i) const + { return side_of_power_circle(c, i, p, true) == ON_BOUNDED_SIDE; - } + } - bool in_conflict_1(const Weighted_point &p, const Cell_handle c) const - { + bool in_conflict_1(const Weighted_point &p, const Cell_handle c) const + { return side_of_power_segment(c, p, true) == ON_BOUNDED_SIDE; - } + } - bool in_conflict_0(const Weighted_point &p, const Cell_handle c) const - { + bool in_conflict_0(const Weighted_point &p, const Cell_handle c) const + { return power_test(c->vertex(0)->point(), p) == ON_POSITIVE_SIDE; - } + } - bool in_conflict(const Weighted_point &p, const Cell_handle c) const - { + bool in_conflict(const Weighted_point &p, const Cell_handle c) const + { switch (dimension()) { - case 0: return in_conflict_0(p, c); - case 1: return in_conflict_1(p, c); - case 2: return in_conflict_2(p, c, 3); - case 3: return in_conflict_3(p, c); + case 0: return in_conflict_0(p, c); + case 1: return in_conflict_1(p, c); + case 2: return in_conflict_2(p, c, 3); + case 3: return in_conflict_3(p, c); } return true; - } + } - class Conflict_tester_3 - { - const Weighted_point &p; - const Self *t; + class Conflict_tester_3 + { + const Weighted_point &p; + const Self *t; - public: + public: - Conflict_tester_3(const Weighted_point &pt, const Self *tr) - : p(pt), t(tr) {} + Conflict_tester_3(const Weighted_point &pt, const Self *tr) + : p(pt), t(tr) {} - bool operator()(const Cell_handle c) const { - return t->in_conflict_3(p, c); - } + bool operator()(const Cell_handle c) const { + return t->in_conflict_3(p, c); + } - bool test_initial_cell(const Cell_handle c) const { - return operator()(c); - } - Oriented_side compare_weight(const Weighted_point &wp1, - const Weighted_point &wp2) const - { - return t->power_test (wp1, wp2); - } - }; + bool test_initial_cell(const Cell_handle c) const { + return operator()(c); + } + Oriented_side compare_weight(const Weighted_point &wp1, + const Weighted_point &wp2) const + { + return t->power_test (wp1, wp2); + } + }; - class Conflict_tester_2 - { + class Conflict_tester_2 + { const Weighted_point &p; const Self *t; - public: + public: - Conflict_tester_2(const Weighted_point &pt, const Self *tr) - : p(pt), t(tr) {} + Conflict_tester_2(const Weighted_point &pt, const Self *tr) + : p(pt), t(tr) {} - bool operator()(const Cell_handle c) const - { - return t->in_conflict_2(p, c, 3); - } - bool test_initial_cell(const Cell_handle c) const { - return operator()(c); - } - Oriented_side compare_weight(const Weighted_point &wp1, - const Weighted_point &wp2) const - { - return t->power_test (wp1, wp2); - } - }; + bool operator()(const Cell_handle c) const + { + return t->in_conflict_2(p, c, 3); + } + bool test_initial_cell(const Cell_handle c) const { + return operator()(c); + } + Oriented_side compare_weight(const Weighted_point &wp1, + const Weighted_point &wp2) const + { + return t->power_test (wp1, wp2); + } + }; - class Conflict_tester_1 - { + class Conflict_tester_1 + { const Weighted_point &p; const Self *t; - public: + public: - Conflict_tester_1(const Weighted_point &pt, const Self *tr) - : p(pt), t(tr) {} + Conflict_tester_1(const Weighted_point &pt, const Self *tr) + : p(pt), t(tr) {} - bool operator()(const Cell_handle c) const - { - return t->in_conflict_1(p, c); - } - bool test_initial_cell(const Cell_handle c) const { - return operator()(c); - } - Oriented_side compare_weight(const Weighted_point &wp1, - const Weighted_point &wp2) const - { - return t->power_test (wp1, wp2); - } - }; + bool operator()(const Cell_handle c) const + { + return t->in_conflict_1(p, c); + } + bool test_initial_cell(const Cell_handle c) const { + return operator()(c); + } + Oriented_side compare_weight(const Weighted_point &wp1, + const Weighted_point &wp2) const + { + return t->power_test (wp1, wp2); + } + }; - class Conflict_tester_0 - { + class Conflict_tester_0 + { const Weighted_point &p; const Self *t; - public: + public: - Conflict_tester_0(const Weighted_point &pt, const Self *tr) - : p(pt), t(tr) {} + Conflict_tester_0(const Weighted_point &pt, const Self *tr) + : p(pt), t(tr) {} - bool operator()(const Cell_handle c) const + bool operator()(const Cell_handle c) const + { + return t->in_conflict_0(p, c); + } + bool test_initial_cell(const Cell_handle c) const { + return operator()(c); + } + int compare_weight(const Weighted_point &wp1, + const Weighted_point &wp2) const + { + return t->power_test (wp1, wp2); + } + }; + + // Sequential version + // "dummy" is here to allow the specialization (see below) + // See http://groups.google.com/group/comp.lang.c++.moderated/browse_thread/thread/285ab1eec49e1cb6 + template + class Hidden_point_visitor { - return t->in_conflict_0(p, c); - } - bool test_initial_cell(const Cell_handle c) const { - return operator()(c); - } - int compare_weight(const Weighted_point &wp1, - const Weighted_point &wp2) const + Self *t; + mutable std::vector vertices; + mutable std::vector hidden_points; + + public: + + Hidden_point_visitor(Self *tr) : t(tr) {} + + template + void process_cells_in_conflict(InputIterator start, InputIterator end) const + { + int dim = t->dimension(); + while (start != end) { + std::copy((*start)->hidden_points_begin(), + (*start)->hidden_points_end(), + std::back_inserter(hidden_points)); + + for (int i=0; i<=dim; i++) { + Vertex_handle v = (*start)->vertex(i); + if (v->cell() != Cell_handle()) { + vertices.push_back(v); + v->set_cell(Cell_handle()); + } + } + start ++; + } + } + void reinsert_vertices(Vertex_handle v) { + Cell_handle hc = v->cell(); + for (typename std::vector::iterator + vi = vertices.begin(); vi != vertices.end(); ++vi) { + if ((*vi)->cell() != Cell_handle()) continue; + hc = t->locate ((*vi)->point(), hc); + hide_point(hc, (*vi)->point()); + t->tds().delete_vertex(*vi); + } + vertices.clear(); + for (typename std::vector::iterator + hp = hidden_points.begin(); hp != hidden_points.end(); ++hp) { + hc = t->locate (*hp, hc); + hide_point (hc, *hp); + } + hidden_points.clear(); + } + Vertex_handle replace_vertex(Cell_handle c, int index, + const Weighted_point &p) { + Vertex_handle v = c->vertex(index); + hide_point(c, v->point()); + v->set_point(p); + return v; + } + void hide_point(Cell_handle c, const Weighted_point &p) { + c->hide_point(p); + } + }; + +#ifdef CGAL_LINKED_WITH_TBB + // Parallel version specialization + template + class Hidden_point_visitor { - return t->power_test (wp1, wp2); + typedef Hidden_point_visitor HPV; + + Self *t; + mutable tbb::enumerable_thread_specific > vertices; + mutable tbb::enumerable_thread_specific > hidden_points; + + public: + + Hidden_point_visitor(Self *tr) : t(tr) {} + + template + void process_cells_in_conflict(InputIterator start, InputIterator end) const + { + int dim = t->dimension(); + while (start != end) { + std::copy((*start)->hidden_points_begin(), + (*start)->hidden_points_end(), + std::back_inserter(hidden_points.local())); + + for (int i=0; i<=dim; i++) { + Vertex_handle v = (*start)->vertex(i); + if (v->cell() != Cell_handle()) { + vertices.local().push_back(v); + v->set_cell(Cell_handle()); + } + } + start ++; + } + } + void reinsert_vertices(Vertex_handle v) { + Cell_handle hc = v->cell(); + for (typename std::vector::iterator + vi = vertices.local().begin(); vi != vertices.local().end(); ++vi) { + if ((*vi)->cell() != Cell_handle()) continue; + hc = t->locate ((*vi)->point(), hc); + hide_point(hc, (*vi)->point()); + t->tds().delete_vertex(*vi); + } + vertices.local().clear(); + for (typename std::vector::iterator + hp = hidden_points.local().begin(); hp != hidden_points.local().end(); ++hp) { + hc = t->locate (*hp, hc); + hide_point (hc, *hp); + } + hidden_points.local().clear(); + } + Vertex_handle replace_vertex(Cell_handle c, int index, + const Weighted_point &p) { + Vertex_handle v = c->vertex(index); + hide_point(c, v->point()); + v->set_point(p); + return v; + } + void hide_point(Cell_handle c, const Weighted_point &p) { + c->hide_point(p); + } + }; + + // Functor for parallel insert(begin, end) function + template + class Insert_point + { + typedef typename RT::Weighted_point Weighted_point; + typedef typename RT::Vertex_handle Vertex_handle; + + RT & m_rt; + const std::vector & m_points; + tbb::enumerable_thread_specific & m_tls_hint; + + public: + // Constructor + Insert_point(RT & rt, + const std::vector & points, + tbb::enumerable_thread_specific & tls_hint) + : m_rt(rt), m_points(points), m_tls_hint(tls_hint) + {} + + // Constructor + Insert_point(const Insert_point &ip) + : m_rt(ip.m_rt), m_points(ip.m_points), m_tls_hint(ip.m_tls_hint) + {} + + // operator() + void operator()( const tbb::blocked_range& r ) const + { +#ifdef CGAL_CONCURRENT_TRIANGULATION_3_PROFILING + static Profile_branch_counter_3 bcounter( + "early withdrawals / late withdrawals / successes [Delaunay_tri_3::insert]"); +#endif + + Vertex_handle &hint = m_tls_hint.local(); + for( size_t i_point = r.begin() ; i_point != r.end() ; ++i_point) + { + bool success = false; + const Weighted_point &p = m_points[i_point]; + while(!success) + { + if (m_rt.try_lock_vertex(hint) && m_rt.try_lock_point(p)) + { + bool could_lock_zone; + Locate_type lt; + int li, lj; + + Cell_handle c = m_rt.locate (p, lt, li, lj, hint->cell(), + &could_lock_zone); + Vertex_handle v; + if (could_lock_zone) + v = m_rt.insert (p, lt, c, li, lj, &could_lock_zone); + + if (could_lock_zone) + { + hint = (v == Vertex_handle() ? c->vertex(0) : v); + m_rt.unlock_all_elements(); + success = true; +#ifdef CGAL_CONCURRENT_TRIANGULATION_3_PROFILING + ++bcounter; +#endif + } + else + { + m_rt.unlock_all_elements(); +#ifdef CGAL_CONCURRENT_TRIANGULATION_3_PROFILING + bcounter.increment_branch_1(); // THIS is a late withdrawal! +#endif + } + } + else + { + m_rt.unlock_all_elements(); +#ifdef CGAL_CONCURRENT_TRIANGULATION_3_PROFILING + bcounter.increment_branch_2(); // THIS is an early withdrawal! +#endif + } + } + } } }; - class Hidden_point_visitor - { - Self *t; - mutable std::vector vertices; - mutable std::vector hidden_points; + // Functor for parallel remove(begin, end) function + template + class Remove_point + { + typedef typename RT::Weighted_point Weighted_point; + typedef typename RT::Vertex_handle Vertex_handle; + + RT & m_rt; + const std::vector & m_vertices; + tbb::concurrent_vector & m_vertices_to_remove_sequentially; public: + // Constructor + Remove_point(RT & rt, + const std::vector & vertices, + tbb::concurrent_vector & + vertices_to_remove_sequentially) + : m_rt(rt), m_vertices(vertices), + m_vertices_to_remove_sequentially(vertices_to_remove_sequentially) + {} + + // Constructor + Remove_point(const Remove_point &rp) + : m_rt(rp.m_rt), m_vertices(rp.m_vertices), + m_vertices_to_remove_sequentially(rp.m_vertices_to_remove_sequentially) + {} - Hidden_point_visitor(Self *tr) : t(tr) {} - - template - void process_cells_in_conflict(InputIterator start, InputIterator end) const + // operator() + void operator()( const tbb::blocked_range& r ) const { - int dim = t->dimension(); - while (start != end) { - std::copy((*start)->hidden_points_begin(), - (*start)->hidden_points_end(), - std::back_inserter(hidden_points)); - - for (int i=0; i<=dim; i++) { - Vertex_handle v = (*start)->vertex(i); - if (v->cell() != Cell_handle()) { - vertices.push_back(v); - v->set_cell(Cell_handle()); - } - } - start ++; - } - } - void reinsert_vertices(Vertex_handle v) { - Cell_handle hc = v->cell(); - for (typename std::vector::iterator - vi = vertices.begin(); vi != vertices.end(); ++vi) { - if ((*vi)->cell() != Cell_handle()) continue; - hc = t->locate ((*vi)->point(), hc); - hide_point(hc, (*vi)->point()); - t->tds().delete_vertex(*vi); - } - vertices.clear(); - for (typename std::vector::iterator - hp = hidden_points.begin(); hp != hidden_points.end(); ++hp) { - hc = t->locate (*hp, hc); - hide_point (hc, *hp); - } - hidden_points.clear(); - } - Vertex_handle replace_vertex(Cell_handle c, int index, - const Weighted_point &p) { - Vertex_handle v = c->vertex(index); - hide_point(c, v->point()); - v->set_point(p); - return v; - } - void hide_point(Cell_handle c, const Weighted_point &p) { - c->hide_point(p); + for( size_t i_vertex = r.begin() ; i_vertex != r.end() ; ++i_vertex) + { + Vertex_handle v = m_vertices[i_vertex]; + bool could_lock_zone, needs_to_be_done_sequentially; + do + { + needs_to_be_done_sequentially = + !m_rt.remove(v, &could_lock_zone); + m_rt.unlock_all_elements(); + } while (!could_lock_zone); + + if (needs_to_be_done_sequentially) + m_vertices_to_remove_sequentially.push_back(v); + } } }; +#endif // CGAL_LINKED_WITH_TBB - template < class RegularTriangulation_3 > - class Vertex_remover; + Hidden_point_visitor &get_hidden_point_visitor() + { + return hidden_point_visitor; + } - template < class RegularTriangulation_3 > - class Vertex_inserter; + template < class RegularTriangulation_3 > + class Vertex_remover; - Hidden_point_visitor hidden_point_visitor; -}; + template < class RegularTriangulation_3 > + class Vertex_inserter; + Hidden_point_visitor hidden_point_visitor; + }; -template < class Gt, class Tds > -typename Regular_triangulation_3::Vertex_handle -Regular_triangulation_3:: -nearest_power_vertex_in_cell(const Bare_point& p, - Cell_handle c) const -// Returns the finite vertex of the cell c with smaller -// power distance to p. -{ + + template < class Gt, class Tds, class Lds > + typename Regular_triangulation_3::Vertex_handle + Regular_triangulation_3:: + nearest_power_vertex_in_cell(const Bare_point& p, + Cell_handle c) const + // Returns the finite vertex of the cell c with smaller + // power distance to p. + { CGAL_triangulation_precondition(dimension() >= 1); Vertex_handle nearest = nearest_power_vertex(p, - c->vertex(0), - c->vertex(1)); + c->vertex(0), + c->vertex(1)); if (dimension() >= 2) { - nearest = nearest_power_vertex(p, nearest, c->vertex(2)); - if (dimension() == 3) - nearest = nearest_power_vertex(p, nearest, c->vertex(3)); + nearest = nearest_power_vertex(p, nearest, c->vertex(2)); + if (dimension() == 3) + nearest = nearest_power_vertex(p, nearest, c->vertex(3)); } return nearest; -} + } -template < class Gt, class Tds > -typename Regular_triangulation_3::Vertex_handle -Regular_triangulation_3:: -nearest_power_vertex(const Bare_point& p, Cell_handle start) const -{ + template < class Gt, class Tds, class Lds > + typename Regular_triangulation_3::Vertex_handle + Regular_triangulation_3:: + nearest_power_vertex(const Bare_point& p, Cell_handle start) const + { if (number_of_vertices() == 0) return Vertex_handle(); // Use a brute-force algorithm if dimension < 3. if (dimension() < 3) { - Finite_vertices_iterator vit = finite_vertices_begin(); - Vertex_handle res = vit; - ++vit; - for (Finite_vertices_iterator end = finite_vertices_end(); vit != end; ++vit) - res = nearest_power_vertex(p, res, vit); - return res; + Finite_vertices_iterator vit = finite_vertices_begin(); + Vertex_handle res = vit; + ++vit; + for (Finite_vertices_iterator end = finite_vertices_end(); vit != end; ++vit) + res = nearest_power_vertex(p, res, vit); + return res; } Locate_type lt; @@ -928,85 +1334,83 @@ std::vector vs; vs.reserve(32); while (true) { - Vertex_handle tmp = nearest; - adjacent_vertices(nearest, std::back_inserter(vs)); - for (typename std::vector::const_iterator - vsit = vs.begin(); vsit != vs.end(); ++vsit) - tmp = nearest_power_vertex(p, tmp, *vsit); - if (tmp == nearest) - break; - vs.clear(); - nearest = tmp; + Vertex_handle tmp = nearest; + adjacent_vertices(nearest, std::back_inserter(vs)); + for (typename std::vector::const_iterator + vsit = vs.begin(); vsit != vs.end(); ++vsit) + tmp = nearest_power_vertex(p, tmp, *vsit); + if (tmp == nearest) + break; + vs.clear(); + nearest = tmp; } return nearest; -} + } -template < class Gt, class Tds > -typename Regular_triangulation_3::Bare_point -Regular_triangulation_3:: +template < class Gt, class Tds, class Lds > +typename Regular_triangulation_3::Bare_point +Regular_triangulation_3:: dual(Cell_handle c) const { CGAL_triangulation_precondition(dimension()==3); CGAL_triangulation_precondition( ! is_infinite(c) ); - return construct_weighted_circumcenter( c->vertex(0)->point(), - c->vertex(1)->point(), - c->vertex(2)->point(), - c->vertex(3)->point() ); -} -template < class Gt, class Tds > -typename Regular_triangulation_3::Object -Regular_triangulation_3:: -dual(Cell_handle c, int i) const -{ - CGAL_triangulation_precondition(dimension()>=2); - CGAL_triangulation_precondition( ! is_infinite(c,i) ); + return c->weighted_circumcenter(geom_traits()); +} - if ( dimension() == 2 ) { - CGAL_triangulation_precondition( i == 3 ); - return construct_object( - construct_weighted_circumcenter(c->vertex(0)->point(), - c->vertex(1)->point(), - c->vertex(2)->point()) ); - } - - // dimension() == 3 - Cell_handle n = c->neighbor(i); - if ( ! is_infinite(c) && ! is_infinite(n) ) - return construct_object(construct_segment( dual(c), dual(n) )); - - // either n or c is infinite - int in; - if ( is_infinite(c) ) - in = n->index(c); - else { - n = c; - in = i; - } - // n now denotes a finite cell, either c or c->neighbor(i) - int ind[3] = {(in+1)&3,(in+2)&3,(in+3)&3}; - if ( (in&1) == 1 ) + template < class Gt, class Tds, class Lds > + typename Regular_triangulation_3::Object + Regular_triangulation_3:: + dual(Cell_handle c, int i) const + { + CGAL_triangulation_precondition(dimension()>=2); + CGAL_triangulation_precondition( ! is_infinite(c,i) ); + + if ( dimension() == 2 ) { + CGAL_triangulation_precondition( i == 3 ); + return construct_object( + construct_weighted_circumcenter(c->vertex(0)->point(), + c->vertex(1)->point(), + c->vertex(2)->point()) ); + } + + // dimension() == 3 + Cell_handle n = c->neighbor(i); + if ( ! is_infinite(c) && ! is_infinite(n) ) + return construct_object(construct_segment( dual(c), dual(n) )); + + // either n or c is infinite + int in; + if ( is_infinite(c) ) + in = n->index(c); + else { + n = c; + in = i; + } + // n now denotes a finite cell, either c or c->neighbor(i) + int ind[3] = {(in+1)&3,(in+2)&3,(in+3)&3}; + if ( (in&1) == 1 ) std::swap(ind[0], ind[1]); - const Weighted_point& p = n->vertex(ind[0])->point(); - const Weighted_point& q = n->vertex(ind[1])->point(); - const Weighted_point& r = n->vertex(ind[2])->point(); - - Line l = - construct_perpendicular_line( construct_plane(p,q,r), - construct_weighted_circumcenter(p,q,r) ); - return construct_object(construct_ray( dual(n), l)); -} + const Weighted_point& p = n->vertex(ind[0])->point(); + const Weighted_point& q = n->vertex(ind[1])->point(); + const Weighted_point& r = n->vertex(ind[2])->point(); + Line l = + construct_perpendicular_line( construct_plane(p,q,r), + construct_weighted_circumcenter(p,q,r) ); + return construct_object(construct_ray( dual(n), l)); + } -template < class Gt, class Tds > -Oriented_side -Regular_triangulation_3:: -side_of_oriented_power_sphere(const Weighted_point &p0, - const Weighted_point &p1, - const Weighted_point &p2, - const Weighted_point &p3, - const Weighted_point &p, bool perturb) const -{ + + template < class Gt, class Tds, class Lds > + Oriented_side + Regular_triangulation_3:: + side_of_oriented_power_sphere(const Weighted_point &p0, + const Weighted_point &p1, + const Weighted_point &p2, + const Weighted_point &p3, + const Weighted_point &p, bool perturb) const + { CGAL_triangulation_precondition( orientation(p0, p1, p2, p3) == POSITIVE ); using namespace boost; @@ -1014,109 +1418,109 @@ Oriented_side os = power_test(p0, p1, p2, p3, p); if (os != ON_ORIENTED_BOUNDARY || !perturb) - return os; + return os; // We are now in a degenerate case => we do a symbolic perturbation. // We sort the points lexicographically. const Weighted_point * points[5] = {&p0, &p1, &p2, &p3, &p}; std::sort(points, points + 5, - boost::bind(geom_traits().compare_xyz_3_object(), - boost::bind(Dereference(), _1), - boost::bind(Dereference(), _2)) == SMALLER); + boost::bind(geom_traits().compare_xyz_3_object(), + boost::bind(Dereference(), _1), + boost::bind(Dereference(), _2)) == SMALLER); // We successively look whether the leading monomial, then 2nd monomial // of the determinant has non null coefficient. for (int i=4; i>1; --i) { - if (points[i] == &p) - return ON_NEGATIVE_SIDE; // since p0 p1 p2 p3 are non coplanar - // and positively oriented - Orientation o; - if (points[i] == &p3 && (o = orientation(p0,p1,p2,p)) != COPLANAR ) - return o; - if (points[i] == &p2 && (o = orientation(p0,p1,p,p3)) != COPLANAR ) - return o; - if (points[i] == &p1 && (o = orientation(p0,p,p2,p3)) != COPLANAR ) - return o; - if (points[i] == &p0 && (o = orientation(p,p1,p2,p3)) != COPLANAR ) - return o; + if (points[i] == &p) + return ON_NEGATIVE_SIDE; // since p0 p1 p2 p3 are non coplanar + // and positively oriented + Orientation o; + if (points[i] == &p3 && (o = orientation(p0,p1,p2,p)) != COPLANAR ) + return o; + if (points[i] == &p2 && (o = orientation(p0,p1,p,p3)) != COPLANAR ) + return o; + if (points[i] == &p1 && (o = orientation(p0,p,p2,p3)) != COPLANAR ) + return o; + if (points[i] == &p0 && (o = orientation(p,p1,p2,p3)) != COPLANAR ) + return o; } CGAL_triangulation_assertion(false); return ON_NEGATIVE_SIDE; -} + } -template < class Gt, class Tds > -Bounded_side -Regular_triangulation_3:: -side_of_power_sphere(Cell_handle c, const Weighted_point &p, - bool perturb) const -{ - CGAL_triangulation_precondition( dimension() == 3 ); - int i3; - if ( ! c->has_vertex( infinite_vertex(), i3 ) ) { - return Bounded_side( side_of_oriented_power_sphere(c->vertex(0)->point(), - c->vertex(1)->point(), - c->vertex(2)->point(), - c->vertex(3)->point(), - p, perturb) ); - } - // else infinite cell : - int i0,i1,i2; - if ( (i3%2) == 1 ) { - i0 = (i3+1)&3; - i1 = (i3+2)&3; - i2 = (i3+3)&3; - } - else { - i0 = (i3+2)&3; - i1 = (i3+1)&3; - i2 = (i3+3)&3; - } - - // general case - Orientation o = orientation(c->vertex(i0)->point(), - c->vertex(i1)->point(), - c->vertex(i2)->point(), p); - if (o != ZERO) - return Bounded_side(o); - - // else p coplanar with i0,i1,i2 - return side_of_bounded_power_circle(c->vertex(i0)->point(), - c->vertex(i1)->point(), - c->vertex(i2)->point(), - p, perturb); -} + template < class Gt, class Tds, class Lds > + Bounded_side + Regular_triangulation_3:: + side_of_power_sphere(Cell_handle c, const Weighted_point &p, + bool perturb) const + { + CGAL_triangulation_precondition( dimension() == 3 ); + int i3; + if ( ! c->has_vertex( infinite_vertex(), i3 ) ) { + return Bounded_side( side_of_oriented_power_sphere(c->vertex(0)->point(), + c->vertex(1)->point(), + c->vertex(2)->point(), + c->vertex(3)->point(), + p, perturb) ); + } + // else infinite cell : + int i0,i1,i2; + if ( (i3%2) == 1 ) { + i0 = (i3+1)&3; + i1 = (i3+2)&3; + i2 = (i3+3)&3; + } + else { + i0 = (i3+2)&3; + i1 = (i3+1)&3; + i2 = (i3+3)&3; + } + + // general case + Orientation o = orientation(c->vertex(i0)->point(), + c->vertex(i1)->point(), + c->vertex(i2)->point(), p); + if (o != ZERO) + return Bounded_side(o); + // else p coplanar with i0,i1,i2 + return side_of_bounded_power_circle(c->vertex(i0)->point(), + c->vertex(i1)->point(), + c->vertex(i2)->point(), + p, perturb); + } -template < class Gt, class Tds > -Bounded_side -Regular_triangulation_3:: -side_of_bounded_power_circle(const Weighted_point &p0, - const Weighted_point &p1, - const Weighted_point &p2, - const Weighted_point &p, bool perturb) const -{ + + template < class Gt, class Tds, class Lds > + Bounded_side + Regular_triangulation_3:: + side_of_bounded_power_circle(const Weighted_point &p0, + const Weighted_point &p1, + const Weighted_point &p2, + const Weighted_point &p, bool perturb) const + { CGAL_triangulation_precondition(coplanar_orientation(p0, p1, p2) != 0); if (coplanar_orientation(p0, p1, p2) == POSITIVE) - return Bounded_side (side_of_oriented_power_circle(p0, p1, p2, p, perturb)); + return Bounded_side (side_of_oriented_power_circle(p0, p1, p2, p, perturb)); // Wrong because the low level power test already does a coplanar orientation // test. // return Bounded_side (- side_of_oriented_power_circle (p0, p2, p1, p, // perturb)); return Bounded_side (side_of_oriented_power_circle(p0, p2, p1, p, perturb)); -} + } -template < class Gt, class Tds > -Oriented_side -Regular_triangulation_3:: -side_of_oriented_power_circle(const Weighted_point &p0, - const Weighted_point &p1, - const Weighted_point &p2, - const Weighted_point &p, bool perturb) const -{ + template < class Gt, class Tds, class Lds > + Oriented_side + Regular_triangulation_3:: + side_of_oriented_power_circle(const Weighted_point &p0, + const Weighted_point &p1, + const Weighted_point &p2, + const Weighted_point &p, bool perturb) const + { CGAL_triangulation_precondition( coplanar_orientation(p0, p1, p2) == POSITIVE ); using namespace boost; @@ -1124,398 +1528,422 @@ Oriented_side os = power_test(p0, p1, p2, p); if (os != ON_ORIENTED_BOUNDARY || !perturb) - return os; + return os; // We are now in a degenerate case => we do a symbolic perturbation. // We sort the points lexicographically. const Weighted_point * points[4] = {&p0, &p1, &p2, &p}; std::sort(points, points + 4, - boost::bind(geom_traits().compare_xyz_3_object(), - boost::bind(Dereference(), _1), - boost::bind(Dereference(), _2)) == SMALLER); + boost::bind(geom_traits().compare_xyz_3_object(), + boost::bind(Dereference(), _1), + boost::bind(Dereference(), _2)) == SMALLER); // We successively look whether the leading monomial, then 2nd monomial // of the determinant has non null coefficient. // 2 iterations are enough (cf paper) for (int i=3; i>1; --i) { - if (points[i] == &p) - return ON_NEGATIVE_SIDE; // since p0 p1 p2 are non collinear - // and positively oriented - Orientation o; - if (points[i] == &p2 && (o = coplanar_orientation(p0,p1,p)) != COPLANAR ) - return o; - if (points[i] == &p1 && (o = coplanar_orientation(p0,p,p2)) != COPLANAR ) - return o; - if (points[i] == &p0 && (o = coplanar_orientation(p,p1,p2)) != COPLANAR ) - return o; + if (points[i] == &p) + return ON_NEGATIVE_SIDE; // since p0 p1 p2 are non collinear + // and positively oriented + Orientation o; + if (points[i] == &p2 && (o = coplanar_orientation(p0,p1,p)) != COPLANAR ) + return o; + if (points[i] == &p1 && (o = coplanar_orientation(p0,p,p2)) != COPLANAR ) + return o; + if (points[i] == &p0 && (o = coplanar_orientation(p,p1,p2)) != COPLANAR ) + return o; } CGAL_triangulation_assertion(false); return ON_NEGATIVE_SIDE; -} + } -template < class Gt, class Tds > -Bounded_side -Regular_triangulation_3:: -side_of_power_circle(Cell_handle c, int i, const Weighted_point &p, - bool perturb) const -{ - CGAL_triangulation_precondition( dimension() >= 2 ); - int i3 = 5; - if ( dimension() == 2 ) { - CGAL_triangulation_precondition( i == 3 ); - // the triangulation is supposed to be valid, ie the facet - // with vertices 0 1 2 in this order is positively oriented - if ( ! c->has_vertex( infinite_vertex(), i3 ) ) - return Bounded_side( side_of_oriented_power_circle(c->vertex(0)->point(), - c->vertex(1)->point(), - c->vertex(2)->point(), - p, perturb) ); - // else infinite facet + template < class Gt, class Tds, class Lds > + Bounded_side + Regular_triangulation_3:: + side_of_power_circle(Cell_handle c, int i, const Weighted_point &p, + bool perturb) const + { + CGAL_triangulation_precondition( dimension() >= 2 ); + int i3 = 5; + if ( dimension() == 2 ) { + CGAL_triangulation_precondition( i == 3 ); + // the triangulation is supposed to be valid, ie the facet + // with vertices 0 1 2 in this order is positively oriented + if ( ! c->has_vertex( infinite_vertex(), i3 ) ) + return Bounded_side( side_of_oriented_power_circle(c->vertex(0)->point(), + c->vertex(1)->point(), + c->vertex(2)->point(), + p, perturb) ); + // else infinite facet + // v1, v2 finite vertices of the facet such that v1,v2,infinite + // is positively oriented + Vertex_handle v1 = c->vertex( ccw(i3) ), + v2 = c->vertex( cw(i3) ); + CGAL_triangulation_assertion(coplanar_orientation(v1->point(), v2->point(), + mirror_vertex(c, i3)->point()) == NEGATIVE); + Orientation o = coplanar_orientation(v1->point(), v2->point(), p); + if ( o != ZERO ) + return Bounded_side( o ); + // case when p collinear with v1v2 + return side_of_bounded_power_segment(v1->point(), + v2->point(), + p, perturb); + }// dim 2 + + // else dimension == 3 + CGAL_triangulation_precondition( (i >= 0) && (i < 4) ); + if ( ( ! c->has_vertex(infinite_vertex(),i3) ) || ( i3 != i ) ) { + // finite facet + // initialization of i0 i1 i2, vertices of the facet positively + // oriented (if the triangulation is valid) + int i0 = (i>0) ? 0 : 1; + int i1 = (i>1) ? 1 : 2; + int i2 = (i>2) ? 2 : 3; + CGAL_triangulation_precondition(this->coplanar(c->vertex(i0)->point(), + c->vertex(i1)->point(), + c->vertex(i2)->point(), p)); + return side_of_bounded_power_circle(c->vertex(i0)->point(), + c->vertex(i1)->point(), + c->vertex(i2)->point(), + p, perturb); + } + //else infinite facet // v1, v2 finite vertices of the facet such that v1,v2,infinite // is positively oriented - Vertex_handle v1 = c->vertex( ccw(i3) ), - v2 = c->vertex( cw(i3) ); - CGAL_triangulation_assertion(coplanar_orientation(v1->point(), v2->point(), - mirror_vertex(c, i3)->point()) == NEGATIVE); - Orientation o = coplanar_orientation(v1->point(), v2->point(), p); + Vertex_handle v1 = c->vertex( next_around_edge(i3,i) ), + v2 = c->vertex( next_around_edge(i,i3) ); + Orientation o = (Orientation) + (coplanar_orientation( v1->point(), v2->point(), + c->vertex(i)->point()) * + coplanar_orientation( v1->point(), v2->point(), p)); + // then the code is duplicated from 2d case if ( o != ZERO ) - return Bounded_side( o ); - // case when p collinear with v1v2 - return side_of_bounded_power_segment(v1->point(), - v2->point(), - p, perturb); - }// dim 2 - - // else dimension == 3 - CGAL_triangulation_precondition( (i >= 0) && (i < 4) ); - if ( ( ! c->has_vertex(infinite_vertex(),i3) ) || ( i3 != i ) ) { - // finite facet - // initialization of i0 i1 i2, vertices of the facet positively - // oriented (if the triangulation is valid) - int i0 = (i>0) ? 0 : 1; - int i1 = (i>1) ? 1 : 2; - int i2 = (i>2) ? 2 : 3; - CGAL_triangulation_precondition(this->coplanar(c->vertex(i0)->point(), - c->vertex(i1)->point(), - c->vertex(i2)->point(), p)); - return side_of_bounded_power_circle(c->vertex(i0)->point(), - c->vertex(i1)->point(), - c->vertex(i2)->point(), - p, perturb); - } - //else infinite facet - // v1, v2 finite vertices of the facet such that v1,v2,infinite - // is positively oriented - Vertex_handle v1 = c->vertex( next_around_edge(i3,i) ), - v2 = c->vertex( next_around_edge(i,i3) ); - Orientation o = (Orientation) - (coplanar_orientation( v1->point(), v2->point(), - c->vertex(i)->point()) * - coplanar_orientation( v1->point(), v2->point(), p)); - // then the code is duplicated from 2d case - if ( o != ZERO ) return Bounded_side( -o ); - // because p is in f iff - // it is not on the same side of v1v2 as c->vertex(i) - // case when p collinear with v1v2 : - return side_of_bounded_power_segment(v1->point(), - v2->point(), - p, perturb); -} + // because p is in f iff + // it is not on the same side of v1v2 as c->vertex(i) + // case when p collinear with v1v2 : + return side_of_bounded_power_segment(v1->point(), + v2->point(), + p, perturb); + } -template < class Gt, class Tds > -Bounded_side -Regular_triangulation_3:: -side_of_bounded_power_segment(const Weighted_point &p0, - const Weighted_point &p1, - const Weighted_point &p, bool perturb) const -{ + template < class Gt, class Tds, class Lds > + Bounded_side + Regular_triangulation_3:: + side_of_bounded_power_segment(const Weighted_point &p0, + const Weighted_point &p1, + const Weighted_point &p, bool perturb) const + { Oriented_side os = power_test(p0, p1, p); if (os != ON_ORIENTED_BOUNDARY || !perturb) - return Bounded_side(os); + return Bounded_side(os); // We are now in a degenerate case => we do a symbolic perturbation. switch (this->collinear_position(p0, p, p1)) { - case Tr_Base::BEFORE: case Tr_Base::AFTER: - return ON_UNBOUNDED_SIDE; - case Tr_Base::MIDDLE: - return ON_BOUNDED_SIDE; - default: - ; + case Tr_Base::BEFORE: case Tr_Base::AFTER: + return ON_UNBOUNDED_SIDE; + case Tr_Base::MIDDLE: + return ON_BOUNDED_SIDE; + default: + ; } CGAL_triangulation_assertion(false); return ON_UNBOUNDED_SIDE; -} + } -template < class Gt, class Tds > -Bounded_side -Regular_triangulation_3:: -side_of_power_segment(Cell_handle c, const Weighted_point &p, - bool perturb) const -{ - CGAL_triangulation_precondition( dimension() == 1 ); - if ( ! is_infinite(c,0,1) ) - return side_of_bounded_power_segment(c->vertex(0)->point(), - c->vertex(1)->point(), - p, perturb); - Locate_type lt; int i; - Bounded_side soe = side_of_edge( p, c, lt, i ); - if (soe != ON_BOUNDARY) - return soe; - // Either we compare weights, or we use the finite neighboring edge - Cell_handle finite_neighbor = c->neighbor(c->index(infinite_vertex())); - CGAL_triangulation_assertion(!is_infinite(finite_neighbor,0,1)); - return side_of_bounded_power_segment(finite_neighbor->vertex(0)->point(), - finite_neighbor->vertex(1)->point(), - p, perturb); -} + template < class Gt, class Tds, class Lds > + Bounded_side + Regular_triangulation_3:: + side_of_power_segment(Cell_handle c, const Weighted_point &p, + bool perturb) const + { + CGAL_triangulation_precondition( dimension() == 1 ); + if ( ! is_infinite(c,0,1) ) + return side_of_bounded_power_segment(c->vertex(0)->point(), + c->vertex(1)->point(), + p, perturb); + Locate_type lt; int i; + Bounded_side soe = side_of_edge( p, c, lt, i ); + if (soe != ON_BOUNDARY) + return soe; + // Either we compare weights, or we use the finite neighboring edge + Cell_handle finite_neighbor = c->neighbor(c->index(infinite_vertex())); + CGAL_triangulation_assertion(!is_infinite(finite_neighbor,0,1)); + return side_of_bounded_power_segment(finite_neighbor->vertex(0)->point(), + finite_neighbor->vertex(1)->point(), + p, perturb); + } -template < class Gt, class Tds > -bool -Regular_triangulation_3:: -is_Gabriel(const Facet& f) const -{ - return is_Gabriel(f.first, f.second); -} + template < class Gt, class Tds, class Lds > + bool + Regular_triangulation_3:: + is_Gabriel(const Facet& f) const + { + return is_Gabriel(f.first, f.second); + } -template < class Gt, class Tds > -bool -Regular_triangulation_3:: -is_Gabriel(Cell_handle c, int i) const -{ - CGAL_triangulation_precondition(dimension() == 3 && !is_infinite(c,i)); - typename Geom_traits::Side_of_bounded_orthogonal_sphere_3 - side_of_bounded_orthogonal_sphere = - geom_traits().side_of_bounded_orthogonal_sphere_3_object(); + template < class Gt, class Tds, class Lds > + bool + Regular_triangulation_3:: + is_Gabriel(Cell_handle c, int i) const + { + CGAL_triangulation_precondition(dimension() == 3 && !is_infinite(c,i)); + typename Geom_traits::Side_of_bounded_orthogonal_sphere_3 + side_of_bounded_orthogonal_sphere = + geom_traits().side_of_bounded_orthogonal_sphere_3_object(); - if ((!is_infinite(c->vertex(i))) && + if ((!is_infinite(c->vertex(i))) && side_of_bounded_orthogonal_sphere( - c->vertex(vertex_triple_index(i,0))->point(), - c->vertex(vertex_triple_index(i,1))->point(), - c->vertex(vertex_triple_index(i,2))->point(), - c->vertex(i)->point()) == ON_BOUNDED_SIDE ) return false; + c->vertex(vertex_triple_index(i,0))->point(), + c->vertex(vertex_triple_index(i,1))->point(), + c->vertex(vertex_triple_index(i,2))->point(), + c->vertex(i)->point()) == ON_BOUNDED_SIDE ) return false; - Cell_handle neighbor = c->neighbor(i); - int in = neighbor->index(c); + Cell_handle neighbor = c->neighbor(i); + int in = neighbor->index(c); - if ((!is_infinite(neighbor->vertex(in))) && + if ((!is_infinite(neighbor->vertex(in))) && side_of_bounded_orthogonal_sphere( - c->vertex(vertex_triple_index(i,0))->point(), - c->vertex(vertex_triple_index(i,1))->point(), - c->vertex(vertex_triple_index(i,2))->point(), - neighbor->vertex(in)->point()) == ON_BOUNDED_SIDE ) return false; + c->vertex(vertex_triple_index(i,0))->point(), + c->vertex(vertex_triple_index(i,1))->point(), + c->vertex(vertex_triple_index(i,2))->point(), + neighbor->vertex(in)->point()) == ON_BOUNDED_SIDE ) return false; - return true; -} + return true; + } -template < class Gt, class Tds > -bool -Regular_triangulation_3:: -is_Gabriel(const Edge& e) const -{ - return is_Gabriel(e.first, e.second, e.third); -} + template < class Gt, class Tds, class Lds > + bool + Regular_triangulation_3:: + is_Gabriel(const Edge& e) const + { + return is_Gabriel(e.first, e.second, e.third); + } -template < class Gt, class Tds > -bool -Regular_triangulation_3:: -is_Gabriel(Cell_handle c, int i, int j) const -{ - CGAL_triangulation_precondition(dimension() == 3 && !is_infinite(c,i,j)); - typename Geom_traits::Side_of_bounded_orthogonal_sphere_3 - side_of_bounded_orthogonal_sphere = - geom_traits().side_of_bounded_orthogonal_sphere_3_object(); - - Facet_circulator fcirc = incident_facets(c,i,j), - fdone(fcirc); - Vertex_handle v1 = c->vertex(i); - Vertex_handle v2 = c->vertex(j); - do { + template < class Gt, class Tds, class Lds > + bool + Regular_triangulation_3:: + is_Gabriel(Cell_handle c, int i, int j) const + { + CGAL_triangulation_precondition(dimension() == 3 && !is_infinite(c,i,j)); + typename Geom_traits::Side_of_bounded_orthogonal_sphere_3 + side_of_bounded_orthogonal_sphere = + geom_traits().side_of_bounded_orthogonal_sphere_3_object(); + + Facet_circulator fcirc = incident_facets(c,i,j), + fdone(fcirc); + Vertex_handle v1 = c->vertex(i); + Vertex_handle v2 = c->vertex(j); + do { // test whether the vertex of cc opposite to *fcirc // is inside the sphere defined by the edge e = (s, i,j) Cell_handle cc = (*fcirc).first; int ii = (*fcirc).second; if (!is_infinite(cc->vertex(ii)) && - side_of_bounded_orthogonal_sphere( v1->point(), - v2->point(), - cc->vertex(ii)->point()) - == ON_BOUNDED_SIDE ) return false; - } while(++fcirc != fdone); - return true; -} + side_of_bounded_orthogonal_sphere( v1->point(), + v2->point(), + cc->vertex(ii)->point()) + == ON_BOUNDED_SIDE ) return false; + } while(++fcirc != fdone); + return true; + } -template < class Gt, class Tds > -bool -Regular_triangulation_3:: -is_Gabriel(Vertex_handle v) const -{ - return nearest_power_vertex( v->point().point(), v->cell()) == v; -} + template < class Gt, class Tds, class Lds > + bool + Regular_triangulation_3:: + is_Gabriel(Vertex_handle v) const + { + return nearest_power_vertex( v->point().point(), v->cell()) == v; + } -template < class Gt, class Tds > -typename Regular_triangulation_3::Vertex_handle -Regular_triangulation_3:: -insert(const Weighted_point & p, Cell_handle start) -{ + // Returns + template < class Gt, class Tds, class Lds > + typename Regular_triangulation_3::Vertex_handle + Regular_triangulation_3:: + insert(const Weighted_point & p, Cell_handle start, bool *could_lock_zone) + { Locate_type lt; int li, lj; - Cell_handle c = locate(p, lt, li, lj, start); - return insert(p, lt, c, li, lj); -} -template < class Gt, class Tds > -typename Regular_triangulation_3::Vertex_handle -Regular_triangulation_3:: -insert(const Weighted_point & p, Locate_type lt, Cell_handle c, int li, int lj) -{ - switch (dimension()) { - case 3: + // Parallel + if (could_lock_zone) { - Conflict_tester_3 tester (p, this); - return insert_in_conflict(p, lt,c,li,lj, tester, hidden_point_visitor); + Cell_handle c = locate(p, lt, li, lj, start, could_lock_zone); + if (*could_lock_zone) + return insert(p, lt, c, li, lj, could_lock_zone); + else + return Vertex_handle(); } - case 2: + // Sequential + else { - Conflict_tester_2 tester (p, this); - return insert_in_conflict(p, lt,c,li,lj, tester, hidden_point_visitor); + Cell_handle c = locate(p, lt, li, lj, start); + return insert(p, lt, c, li, lj); } - case 1: - { - Conflict_tester_1 tester (p, this); - return insert_in_conflict(p, lt,c,li,lj, tester, hidden_point_visitor); + } + + template < class Gt, class Tds, class Lds > + typename Regular_triangulation_3::Vertex_handle + Regular_triangulation_3:: + insert(const Weighted_point & p, Locate_type lt, Cell_handle c, + int li, int lj, bool *could_lock_zone) + { + switch (dimension()) { + case 3: + { + Conflict_tester_3 tester (p, this); + return insert_in_conflict(p, lt,c,li,lj, tester, + get_hidden_point_visitor(), + could_lock_zone); + } + case 2: + { + Conflict_tester_2 tester (p, this); + return insert_in_conflict(p, lt,c,li,lj, tester, + get_hidden_point_visitor(), + could_lock_zone); + } + case 1: + { + Conflict_tester_1 tester (p, this); + return insert_in_conflict(p, lt,c,li,lj, tester, + get_hidden_point_visitor(), + could_lock_zone); + } } + + Conflict_tester_0 tester (p, this); + return insert_in_conflict(p, lt,c,li,lj, tester, + get_hidden_point_visitor(), + could_lock_zone); } - Conflict_tester_0 tester (p, this); - return insert_in_conflict(p, lt,c,li,lj, tester, hidden_point_visitor); -} + template < class Gt, class Tds, class Lds > + template + typename Regular_triangulation_3::Vertex_handle + Regular_triangulation_3:: + insert_in_hole(const Weighted_point & p, CellIt cell_begin, CellIt cell_end, + Cell_handle begin, int i) + { + CGAL_triangulation_precondition(cell_begin != cell_end); + + get_hidden_point_visitor().process_cells_in_conflict(cell_begin,cell_end); -template < class Gt, class Tds > -template -typename Regular_triangulation_3::Vertex_handle -Regular_triangulation_3:: -insert_in_hole(const Weighted_point & p, CellIt cell_begin, CellIt cell_end, - Cell_handle begin, int i) -{ - CGAL_triangulation_precondition(cell_begin != cell_end); - - hidden_point_visitor.process_cells_in_conflict(cell_begin,cell_end); - - Vertex_handle v = - Tr_Base::insert_in_hole(p, cell_begin, cell_end, begin, i); - - // Store the hidden points in their new cells and hide vertices that - // have to be hidden - hidden_point_visitor.reinsert_vertices(v); - return v; -} + Vertex_handle v = + Tr_Base::insert_in_hole(p, cell_begin, cell_end, begin, i); + // Store the hidden points in their new cells and hide vertices that + // have to be hidden + get_hidden_point_visitor().reinsert_vertices(v); + return v; + } -template < class Gt, class Tds > -template -typename Regular_triangulation_3::Vertex_handle -Regular_triangulation_3:: -insert_in_hole(const Weighted_point & p, CellIt cell_begin, CellIt cell_end, - Cell_handle begin, int i, Vertex_handle newv) -{ - CGAL_triangulation_precondition(cell_begin != cell_end); - hidden_point_visitor.process_cells_in_conflict(cell_begin,cell_end); + template < class Gt, class Tds, class Lds > + template + typename Regular_triangulation_3::Vertex_handle + Regular_triangulation_3:: + insert_in_hole(const Weighted_point & p, CellIt cell_begin, CellIt cell_end, + Cell_handle begin, int i, Vertex_handle newv) + { + CGAL_triangulation_precondition(cell_begin != cell_end); - Vertex_handle v = - Tr_Base::insert_in_hole(p, cell_begin, cell_end, begin, i, newv); + get_hidden_point_visitor().process_cells_in_conflict(cell_begin,cell_end); - // Store the hidden points in their new cells and hide vertices that - // have to be hidden - hidden_point_visitor.reinsert_vertices(v); - return v; -} + Vertex_handle v = + Tr_Base::insert_in_hole(p, cell_begin, cell_end, begin, i, newv); -template -template -class Regular_triangulation_3::Vertex_remover { - typedef RegularTriangulation_3 Regular; - typedef typename Gt::Point_3 Point; -public: - typedef typename std::vector::iterator + // Store the hidden points in their new cells and hide vertices that + // have to be hidden + get_hidden_point_visitor().reinsert_vertices(v); + return v; + } + + template + template + class Regular_triangulation_3::Vertex_remover { + typedef RegularTriangulation_3 Regular; + typedef typename Gt::Point_3 Point; + public: + typedef typename std::vector::iterator Hidden_points_iterator; - Vertex_remover(Regular &tmp_) : tmp(tmp_) {} + Vertex_remover(Regular &tmp_) : tmp(tmp_) {} - Regular &tmp; + Regular &tmp; - void add_hidden_points(Cell_handle ch) { - std::copy (ch->hidden_points_begin(), ch->hidden_points_end(), - std::back_inserter(hidden)); - } + void add_hidden_points(Cell_handle ch) { + std::copy (ch->hidden_points_begin(), ch->hidden_points_end(), + std::back_inserter(hidden)); + } - Hidden_points_iterator hidden_points_begin() { - return hidden.begin(); - } - Hidden_points_iterator hidden_points_end() { - return hidden.end(); - } + Hidden_points_iterator hidden_points_begin() { + return hidden.begin(); + } + Hidden_points_iterator hidden_points_end() { + return hidden.end(); + } - Bounded_side side_of_bounded_circle(const Point &p, const Point &q, - const Point &r, const Point &s, bool perturb = false) const { - return tmp.side_of_bounded_power_circle(p,q,r,s,perturb); - } + Bounded_side side_of_bounded_circle(const Point &p, const Point &q, + const Point &r, const Point &s, bool perturb = false) const { + return tmp.side_of_bounded_power_circle(p,q,r,s,perturb); + } -private: - // The removal of v may un-hide some points, - // Space functions output them. - std::vector hidden; -}; + private: + // The removal of v may un-hide some points, + // Space functions output them. + std::vector hidden; + }; -// The displacement method works only -// on regular triangulation without hidden points at any time -// the vertex inserter is used only -// for the purpose of displacements -template -template -class Regular_triangulation_3::Vertex_inserter { - typedef RegularTriangulation_3 Regular; -public: - typedef Nullptr_t Hidden_points_iterator; + // The displacement method works only + // on regular triangulation without hidden points at any time + // the vertex inserter is used only + // for the purpose of displacements + template + template + class Regular_triangulation_3::Vertex_inserter { + typedef RegularTriangulation_3 Regular; + public: + typedef Nullptr_t Hidden_points_iterator; - Vertex_inserter(Regular &tmp_) : tmp(tmp_) {} + Vertex_inserter(Regular &tmp_) : tmp(tmp_) {} - Regular &tmp; + Regular &tmp; - void add_hidden_points(Cell_handle) {} - Hidden_points_iterator hidden_points_begin() { return NULL; } - Hidden_points_iterator hidden_points_end() { return NULL; } + void add_hidden_points(Cell_handle) {} + Hidden_points_iterator hidden_points_begin() { return NULL; } + Hidden_points_iterator hidden_points_end() { return NULL; } - Vertex_handle insert(const Weighted_point& p, - Locate_type lt, Cell_handle c, int li, int lj) { - return tmp.insert(p, lt, c, li, lj); - } + Vertex_handle insert(const Weighted_point& p, + Locate_type lt, Cell_handle c, int li, int lj) { + return tmp.insert(p, lt, c, li, lj); + } - Vertex_handle insert(const Weighted_point& p, Cell_handle c) { - return tmp.insert(p, c); - } + Vertex_handle insert(const Weighted_point& p, Cell_handle c) { + return tmp.insert(p, c); + } - Vertex_handle insert(const Weighted_point& p) { - return tmp.insert(p); - } -}; + Vertex_handle insert(const Weighted_point& p) { + return tmp.insert(p); + } + }; -template < class Gt, class Tds > -void -Regular_triangulation_3:: -remove(Vertex_handle v) -{ + template < class Gt, class Tds, class Lds > + void + Regular_triangulation_3:: + remove(Vertex_handle v) + { Cell_handle c; if (dimension() > 0) - c = v->cell()->neighbor(v->cell()->index(v)); + c = v->cell()->neighbor(v->cell()->index(v)); Self tmp; Vertex_remover remover(tmp); @@ -1523,20 +1951,64 @@ // Re-insert the points that v was hiding. for (typename Vertex_remover::Hidden_points_iterator - hi = remover.hidden_points_begin(); - hi != remover.hidden_points_end(); ++hi) { - Vertex_handle hv = insert (*hi, c); - if (hv != Vertex_handle()) c = hv->cell(); + hi = remover.hidden_points_begin(); + hi != remover.hidden_points_end(); ++hi) { + Vertex_handle hv = insert (*hi, c); + if (hv != Vertex_handle()) c = hv->cell(); } CGAL_triangulation_expensive_postcondition (is_valid()); -} + } -// Again, verbatim copy from Delaunay. -template < class Gt, class Tds > -typename Regular_triangulation_3::Vertex_handle -Regular_triangulation_3:: -move_point(Vertex_handle v, const Weighted_point & p) -{ + template < class Gt, class Tds, class Lds > + bool + Regular_triangulation_3:: + remove(Vertex_handle v, bool *could_lock_zone) + { + bool removed = true; + + // Locking vertex v... + if (!this->try_lock_vertex(v)) + { + *could_lock_zone = false; + } + else + { + Vertex_handle hint = (v->cell()->vertex(0) == v ? + v->cell()->vertex(1) : v->cell()->vertex(0)); + + Self tmp; + Vertex_remover remover(tmp); + removed = Tr_Base::remove(v, remover, could_lock_zone); + + if (*could_lock_zone && removed) + { + // Re-insert the points that v was hiding. + for (typename Vertex_remover::Hidden_points_iterator + hi = remover.hidden_points_begin(); + hi != remover.hidden_points_end(); ++hi) + { + bool could_lock_zone = false; + Vertex_handle hv; + while (!could_lock_zone) + { + hv = insert (*hi, hint, &could_lock_zone); + } + if (hv != Vertex_handle()) + hint = hv; + } + CGAL_triangulation_expensive_postcondition (is_valid()); + } + } + + return removed; + } + + // Again, verbatim copy from Delaunay. + template < class Gt, class Tds, class Lds > + typename Regular_triangulation_3::Vertex_handle + Regular_triangulation_3:: + move_point(Vertex_handle v, const Weighted_point & p) + { CGAL_triangulation_precondition(! is_infinite(v)); CGAL_triangulation_expensive_precondition(is_vertex(v)); @@ -1551,125 +2023,125 @@ remove(v); if (dimension() <= 0) - return insert(p); + return insert(p); return insert(p, old_neighbor->cell()); -} - -// Displacement works only for Regular triangulation -// without hidden points at any time -template < class Gt, class Tds > -typename Regular_triangulation_3::Vertex_handle -Regular_triangulation_3:: -move_if_no_collision(Vertex_handle v, const Weighted_point &p) -{ - Self tmp; - Vertex_remover remover (tmp); - Vertex_inserter inserter (*this); - Vertex_handle res = Tr_Base::move_if_no_collision(v,p,remover,inserter); + } - CGAL_triangulation_expensive_postcondition(is_valid()); - return res; -} + // Displacement works only for Regular triangulation + // without hidden points at any time + template < class Gt, class Tds, class Lds > + typename Regular_triangulation_3::Vertex_handle + Regular_triangulation_3:: + move_if_no_collision(Vertex_handle v, const Weighted_point &p) + { + Self tmp; + Vertex_remover remover (tmp); + Vertex_inserter inserter (*this); + Vertex_handle res = Tr_Base::move_if_no_collision(v,p,remover,inserter); -template -typename Regular_triangulation_3::Vertex_handle -Regular_triangulation_3:: -move(Vertex_handle v, const Weighted_point &p) { - CGAL_triangulation_precondition(!is_infinite(v)); - if(v->point() == p) return v; - Self tmp; - Vertex_remover remover (tmp); - Vertex_inserter inserter (*this); - return Tr_Base::move(v,p,remover,inserter); -} + CGAL_triangulation_expensive_postcondition(is_valid()); + return res; + } -template < class Gt, class Tds > -bool -Regular_triangulation_3:: -is_valid(bool verbose, int level) const -{ - if ( ! Tr_Base::is_valid(verbose,level) ) { - if (verbose) - std::cerr << "invalid base triangulation" << std::endl; - CGAL_triangulation_assertion(false); - return false; + template + typename Regular_triangulation_3::Vertex_handle + Regular_triangulation_3:: + move(Vertex_handle v, const Weighted_point &p) { + CGAL_triangulation_precondition(!is_infinite(v)); + if(v->point() == p) return v; + Self tmp; + Vertex_remover remover (tmp); + Vertex_inserter inserter (*this); + return Tr_Base::move(v,p,remover,inserter); } - switch ( dimension() ) { - case 3: - { - for(Finite_cells_iterator it = finite_cells_begin(), end = finite_cells_end(); it != end; ++it) { - is_valid_finite(it, verbose, level); - for(int i=0; i<4; i++) { - if ( !is_infinite - (it->neighbor(i)->vertex(it->neighbor(i)->index(it))) ) { - if ( side_of_power_sphere - (it, - it->neighbor(i)->vertex(it->neighbor(i)->index(it))->point()) - == ON_BOUNDED_SIDE ) { - if (verbose) - std::cerr << "non-empty sphere " << std::endl; - CGAL_triangulation_assertion(false); - return false; - } - } - } - } - break; - } - case 2: - { - for(Finite_facets_iterator it = finite_facets_begin(), end = finite_facets_end(); it!= end; ++it) { - is_valid_finite((*it).first, verbose, level); - for(int i=0; i<3; i++) { - if( !is_infinite - ((*it).first->neighbor(i)->vertex( (((*it).first)->neighbor(i)) - ->index((*it).first))) ) { - if ( side_of_power_circle - ( (*it).first, 3, - (*it).first->neighbor(i)-> - vertex( (((*it).first)->neighbor(i)) - ->index((*it).first) )->point() ) - == ON_BOUNDED_SIDE ) { - if (verbose) - std::cerr << "non-empty circle " << std::endl; - CGAL_triangulation_assertion(false); - return false; - } - } - } - } - break; - } - case 1: - { - for(Finite_edges_iterator it = finite_edges_begin(), end = finite_edges_end(); it != end; ++it) { - is_valid_finite((*it).first, verbose, level); - for(int i=0; i<2; i++) { - if( !is_infinite - ((*it).first->neighbor(i)->vertex( (((*it).first)->neighbor(i)) - ->index((*it).first))) ) { - if ( side_of_power_segment - ( (*it).first, - (*it).first->neighbor(i)-> - vertex( (((*it).first)->neighbor(i)) - ->index((*it).first) )->point() ) - == ON_BOUNDED_SIDE ) { - if (verbose) - std::cerr << "non-empty edge " << std::endl; - CGAL_triangulation_assertion(false); - return false; - } - } - } + template < class Gt, class Tds, class Lds > + bool + Regular_triangulation_3:: + is_valid(bool verbose, int level) const + { + if ( ! Tr_Base::is_valid(verbose,level) ) { + if (verbose) + std::cerr << "invalid base triangulation" << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + + switch ( dimension() ) { + case 3: + { + for(Finite_cells_iterator it = finite_cells_begin(), end = finite_cells_end(); it != end; ++it) { + is_valid_finite(it, verbose, level); + for(int i=0; i<4; i++) { + if ( !is_infinite + (it->neighbor(i)->vertex(it->neighbor(i)->index(it))) ) { + if ( side_of_power_sphere + (it, + it->neighbor(i)->vertex(it->neighbor(i)->index(it))->point()) + == ON_BOUNDED_SIDE ) { + if (verbose) + std::cerr << "non-empty sphere " << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + } + } + } + break; + } + case 2: + { + for(Finite_facets_iterator it = finite_facets_begin(), end = finite_facets_end(); it!= end; ++it) { + is_valid_finite((*it).first, verbose, level); + for(int i=0; i<3; i++) { + if( !is_infinite + ((*it).first->neighbor(i)->vertex( (((*it).first)->neighbor(i)) + ->index((*it).first))) ) { + if ( side_of_power_circle + ( (*it).first, 3, + (*it).first->neighbor(i)-> + vertex( (((*it).first)->neighbor(i)) + ->index((*it).first) )->point() ) + == ON_BOUNDED_SIDE ) { + if (verbose) + std::cerr << "non-empty circle " << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + } + } + } + break; + } + case 1: + { + for(Finite_edges_iterator it = finite_edges_begin(), end = finite_edges_end(); it != end; ++it) { + is_valid_finite((*it).first, verbose, level); + for(int i=0; i<2; i++) { + if( !is_infinite + ((*it).first->neighbor(i)->vertex( (((*it).first)->neighbor(i)) + ->index((*it).first))) ) { + if ( side_of_power_segment + ( (*it).first, + (*it).first->neighbor(i)-> + vertex( (((*it).first)->neighbor(i)) + ->index((*it).first) )->point() ) + == ON_BOUNDED_SIDE ) { + if (verbose) + std::cerr << "non-empty edge " << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + } + } + } + break; } - break; } - } - if (verbose) + if (verbose) std::cerr << "valid Regular triangulation" << std::endl; - return true; -} + return true; + } } //namespace CGAL diff -Nru cgal-4.4/include/CGAL/Regular_triangulation_cell_base_3.h cgal-4.5/include/CGAL/Regular_triangulation_cell_base_3.h --- cgal-4.4/include/CGAL/Regular_triangulation_cell_base_3.h 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/include/CGAL/Regular_triangulation_cell_base_3.h 2014-08-29 13:58:17.000000000 +0000 @@ -80,6 +80,29 @@ void hide_point (const Point &p) { _hidden.push_back(p); } // void unhide_point (Point_iterator i) { _hidden.delete(i); } + //note this function is not requested by the RegularTriangulationCellBase_3 + //it should be replaced everywhere by weighted_circumcenter() + // but remains here for backward compatibility + typename Geom_traits::Point_3 + circumcenter(const Geom_traits& gt = Geom_traits()) const + { + return gt.construct_weighted_circumcenter_3_object() + (this->vertex(0)->point(), + this->vertex(1)->point(), + this->vertex(2)->point(), + this->vertex(3)->point()); + } + + typename Geom_traits::Bare_point + weighted_circumcenter(const Geom_traits& gt = Geom_traits()) const + { + return gt.construct_weighted_circumcenter_3_object() + (this->vertex(0)->point(), + this->vertex(1)->point(), + this->vertex(2)->point(), + this->vertex(3)->point()); + } + private: Point_container _hidden; }; diff -Nru cgal-4.4/include/CGAL/Regular_triangulation_cell_base_with_weighted_circumcenter_3.h cgal-4.5/include/CGAL/Regular_triangulation_cell_base_with_weighted_circumcenter_3.h --- cgal-4.4/include/CGAL/Regular_triangulation_cell_base_with_weighted_circumcenter_3.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/Regular_triangulation_cell_base_with_weighted_circumcenter_3.h 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,147 @@ +// Copyright (c) 1999-2006 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Monique Teillaud +// Sylvain Pion + +// cell of a triangulation of any dimension <=3, +// storing its circumcenter lazily. + +#ifndef CGAL_REGULAR_TRIANGULATION_CELL_BASE_WITH_CIRCUMCENTER_3_H +#define CGAL_REGULAR_TRIANGULATION_CELL_BASE_WITH_CIRCUMCENTER_3_H + +#include +#include +#include + +namespace CGAL { + +template < typename GT, typename Cb = Regular_triangulation_cell_base_3 > +class Regular_triangulation_cell_base_with_weighted_circumcenter_3 + : public Cb +{ + typedef typename GT::Point_3 Point_3; + typedef typename GT::Bare_point Bare_point; + + mutable Bare_point * weighted_circumcenter_; + +public: + void invalidate_circumcenter() + { + if (weighted_circumcenter_) { + delete weighted_circumcenter_; + weighted_circumcenter_ = NULL; + } + } + +public: + typedef typename Cb::Vertex_handle Vertex_handle; + typedef typename Cb::Cell_handle Cell_handle; + + typedef GT Geom_traits; + + template < typename TDS2 > + struct Rebind_TDS { + typedef typename Cb::template Rebind_TDS::Other Cb2; + typedef + Regular_triangulation_cell_base_with_weighted_circumcenter_3 + Other; + }; + + Regular_triangulation_cell_base_with_weighted_circumcenter_3() + : Cb(), weighted_circumcenter_(NULL) {} + + Regular_triangulation_cell_base_with_weighted_circumcenter_3 + (const Regular_triangulation_cell_base_with_weighted_circumcenter_3 &c) + : Cb(c), + weighted_circumcenter_(c.weighted_circumcenter_ != NULL ? + new Bare_point(*(c.weighted_circumcenter_)) : + NULL) + {} + + Regular_triangulation_cell_base_with_weighted_circumcenter_3& + operator= + (const Regular_triangulation_cell_base_with_weighted_circumcenter_3 &c) + { + Regular_triangulation_cell_base_with_weighted_circumcenter_3 tmp=c; + tmp.swap(*this); + return *this; + } + + Regular_triangulation_cell_base_with_weighted_circumcenter_3( + Vertex_handle v0, Vertex_handle v1, + Vertex_handle v2, Vertex_handle v3) + : Cb(v0, v1, v2, v3), weighted_circumcenter_(NULL) {} + + Regular_triangulation_cell_base_with_weighted_circumcenter_3( + Vertex_handle v0, Vertex_handle v1, + Vertex_handle v2, Vertex_handle v3, + Cell_handle n0, Cell_handle n1, + Cell_handle n2, Cell_handle n3) + : Cb(v0, v1, v2, v3, n0, n1, n2, n3), weighted_circumcenter_(NULL) {} + + ~Regular_triangulation_cell_base_with_weighted_circumcenter_3() + { + delete weighted_circumcenter_; + } + + // We must override the functions that modify the vertices. + // And if the point inside a vertex is modified, we fail, + // but there's not much we can do for this now. + void set_vertex(int i, Vertex_handle v) + { + invalidate_circumcenter(); + Cb::set_vertex(i, v); + } + + void set_vertices() + { + invalidate_circumcenter(); + Cb::set_vertices(); + } + + void set_vertices(Vertex_handle v0, Vertex_handle v1, + Vertex_handle v2, Vertex_handle v3) + { + invalidate_circumcenter(); + Cb::set_vertices(v0, v1, v2, v3); + } + + const Bare_point & + weighted_circumcenter(const Geom_traits& gt = Geom_traits()) const + { + if (weighted_circumcenter_ == NULL) { + weighted_circumcenter_ + = new Bare_point(this->Cb::weighted_circumcenter(gt)); + } else { + CGAL_expensive_assertion( + this->Cb::weighted_circumcenter(gt) == *weighted_circumcenter_); + } + + return *weighted_circumcenter_; + } + + void swap (Regular_triangulation_cell_base_with_weighted_circumcenter_3& other) throw() + { + std::swap(static_cast(*this), static_cast(other)); + std::swap(weighted_circumcenter_, other.weighted_circumcenter_); + } +}; + +} //namespace CGAL + +#endif // CGAL_REGULAR_TRIANGULATION_CELL_BASE_WITH_CIRCUMCENTER_3_H diff -Nru cgal-4.4/include/CGAL/Regular_triangulation_euclidean_traits_2.h cgal-4.5/include/CGAL/Regular_triangulation_euclidean_traits_2.h --- cgal-4.4/include/CGAL/Regular_triangulation_euclidean_traits_2.h 2013-09-28 19:00:45.000000000 +0000 +++ cgal-4.5/include/CGAL/Regular_triangulation_euclidean_traits_2.h 2014-08-29 13:58:17.000000000 +0000 @@ -308,7 +308,7 @@ power_test_2(const Weighted_point &p, const Weighted_point &t) { - Comparison_result r = compare(p.weight(), t.weight()); + Comparison_result r = CGAL::compare(p.weight(), t.weight()); if(r == LARGER) return ON_NEGATIVE_SIDE; else if (r == SMALLER) return ON_POSITIVE_SIDE; return ON_ORIENTED_BOUNDARY; diff -Nru cgal-4.4/include/CGAL/Regular_triangulation_euclidean_traits_3.h cgal-4.5/include/CGAL/Regular_triangulation_euclidean_traits_3.h --- cgal-4.4/include/CGAL/Regular_triangulation_euclidean_traits_3.h 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/include/CGAL/Regular_triangulation_euclidean_traits_3.h 2014-08-29 13:58:17.000000000 +0000 @@ -398,7 +398,7 @@ const Weighted_point_3 & s, const FT& w) const { - return compare( + return CGAL::compare( squared_radius_orthogonal_sphereC3( p.x(),p.y(),p.z(),p.weight(), q.x(),q.y(),q.z(),q.weight(), @@ -413,7 +413,7 @@ const Weighted_point_3 & r, const FT& w) const { - return compare( + return CGAL::compare( squared_radius_smallest_orthogonal_sphereC3( p.x(),p.y(),p.z(),p.weight(), q.x(),q.y(),q.z(),q.weight(), @@ -426,7 +426,7 @@ const Weighted_point_3 & q, const FT& w) const { - return compare( + return CGAL::compare( squared_radius_smallest_orthogonal_sphereC3( p.x(),p.y(),p.z(),p.weight(), q.x(),q.y(),q.z(),q.weight() ), @@ -437,7 +437,7 @@ const Weighted_point_3 & p, const FT& w) const { - return compare(-p.weight(),w); + return CGAL::compare(-p.weight(),w); } }; diff -Nru cgal-4.4/include/CGAL/remove_far_points_in_mesh_3.h cgal-4.5/include/CGAL/remove_far_points_in_mesh_3.h --- cgal-4.4/include/CGAL/remove_far_points_in_mesh_3.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/remove_far_points_in_mesh_3.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,90 @@ +// Copyright (c) 2014 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Clement Jamin +// +//****************************************************************************** +// File Description : remove_far_points_in_mesh_3 function definition. +//****************************************************************************** + +#ifndef CGAL_REMOVE_FAR_POINTS_IN_MESH_3_H +#define CGAL_REMOVE_FAR_POINTS_IN_MESH_3_H + +namespace CGAL { + +namespace Mesh_3 { + +/************************************************ +// Class Mesher_3_base +// Two versions: sequential / parallel +************************************************/ + +// Sequential +template +class Remove_far_points +{ +#ifdef CGAL_SEQUENTIAL_MESH_3_ADD_OUTSIDE_POINTS_ON_A_FAR_SPHERE + +public: + Remove_far_points(C3T3 &c3t3) : m_c3t3(c3t3) {} + void remove_far_points() { m_c3t3.remove_far_points(); } +private: + C3T3 &m_c3t3; + +#else // !CGAL_SEQUENTIAL_MESH_3_ADD_OUTSIDE_POINTS_ON_A_FAR_SPHERE + +public: + Remove_far_points(C3T3 &) {} + void remove_far_points() {} + +#endif +}; + +#ifdef CGAL_LINKED_WITH_TBB +// Parallel +template +class Remove_far_points +{ +public: + Remove_far_points(C3T3 &c3t3) : m_c3t3(c3t3) {} + + void remove_far_points() + { + m_c3t3.remove_far_points(); + } + +private: + C3T3 &m_c3t3; +}; +#endif // CGAL_LINKED_WITH_TBB + +} // namespace Mesh_3 + +template +void +remove_far_points_in_mesh_3(C3T3& c3t3) +{ + typedef typename Mesh_3::Remove_far_points Remove_far_points; + Remove_far_points cu(c3t3); + cu.remove_far_points(); +} + + +} //namespace CGAL + +#endif // CGAL_REMOVE_FAR_POINTS_IN_MESH_3_H diff -Nru cgal-4.4/include/CGAL/Ridges.h cgal-4.5/include/CGAL/Ridges.h --- cgal-4.4/include/CGAL/Ridges.h 2013-09-28 19:00:44.000000000 +0000 +++ cgal-4.5/include/CGAL/Ridges.h 2014-08-29 13:58:17.000000000 +0000 @@ -15,7 +15,7 @@ // $URL$ // $Id$ // -// Author(s) : Marc Pouget and Frédéric Cazals +// Author(s) : Marc Pouget and Frédéric Cazals #ifndef CGAL_RIDGE_3_H_ #define CGAL_RIDGE_3_H_ diff -Nru cgal-4.4/include/CGAL/Snap_rounding_kd_2.h cgal-4.5/include/CGAL/Snap_rounding_kd_2.h --- cgal-4.4/include/CGAL/Snap_rounding_kd_2.h 2013-11-02 20:00:21.000000000 +0000 +++ cgal-4.5/include/CGAL/Snap_rounding_kd_2.h 2014-08-29 13:58:17.000000000 +0000 @@ -1,4 +1,4 @@ -// Copyright (c) 2001 Tel-Aviv University (Israel). +// Copyright (c) 2001, 2009, 2014 Tel-Aviv University (Israel), Max-Planck-Institute Saarbruecken (Germany). // All rights reserved. // // This file is part of CGAL (www.cgal.org). @@ -16,13 +16,14 @@ // $Id$ // // -// author(s) : Eli Packer +// author(s) : Eli Packer , +// Waqar Khan + #ifndef CGAL_SNAP_ROUNDING_KD_2_H #define CGAL_SNAP_ROUNDING_KD_2_H #include #include -#include #include #include #include @@ -31,23 +32,81 @@ #include +#include +#include +#include + namespace CGAL { +namespace internal { + +////////////////////// +////////////////////// +//Point_with_hot_pixel_history +////////////////////// + template -class My_point : public Traits::Point_2 { +class Point_with_hot_pixel_history : public Traits::Point_2 { + private: - typedef typename Traits::Point_2 Point_2; - typedef typename Traits::FT NT; + + typedef typename Traits::Point_2 Base; + typedef typename Traits::Point_2 Point_2; + typedef typename Traits::FT NT; public: + Point_2 orig; SAVED_OBJECT object; - My_point(const Point_2& p, const Point_2& inp_orig, SAVED_OBJECT obj) : - Point_2(p), orig(inp_orig), object(obj) {} - My_point(const Point_2& p) : Point_2(p), orig(Point_2(0, 0)) {} - My_point() : Point_2(),orig() {} - My_point(NT x, NT y) : Point_2(x, y), orig(Point_2(0, 0)) {} -}; + + Point_with_hot_pixel_history(const Base& p, const Point_2& inp_orig, SAVED_OBJECT obj) : Base(p), orig(inp_orig), object(obj) {} + + Point_with_hot_pixel_history(const Base& p) : Base(p), orig(Point_2(0, 0)) {} + + Point_with_hot_pixel_history() : Base(), orig() {} + + Point_with_hot_pixel_history(NT x, NT y) : Base(x, y), orig(Point_2(0, 0)) {} + +}; // Point_with_hot_pixel_history + + +////////////////////// +////////////////////// +//Search_traits_kd_tree_2 +// +//(Search traits modified to be used by the Spacial Searching kd_trees for Snap rounding) +////////////////////// + +template < class Traits_, class Point_ = typename Traits_::Point_2 > +class Search_traits_kd_tree_2 { + +public: + typedef Traits_ Traits; + typedef Point_ Point_d; + + typedef typename Traits::Iso_rectangle_2 Iso_box_d; + typedef typename Traits::Cartesian_const_iterator_2 Cartesian_const_iterator_d; + typedef typename Traits::Construct_cartesian_const_iterator_2 Construct_cartesian_const_iterator_d; + + typedef typename Traits::Construct_min_vertex_2 Construct_min_vertex_d; + typedef typename Traits::Construct_max_vertex_2 Construct_max_vertex_d; + + typedef typename Traits::Construct_iso_rectangle_2 Construct_iso_box_d; + typedef typename Traits::FT FT; + + Construct_cartesian_const_iterator_d construct_cartesian_const_iterator_d_object() const + { + return Construct_cartesian_const_iterator_d(); + } + +}; // Search_traits_kd_tree_2 + +} // namespace internal + +///////////////////// +///////////////////// +//Multiple_kd_tree +///////////////////// template class Multiple_kd_tree { @@ -62,22 +121,25 @@ typedef typename Traits::Direction_2 Direction_2; typedef typename Traits::Line_2 Line_2; typedef typename Traits::Aff_transformation_2 Transformation_2; - typedef My_point My_point_saved; - typedef CGAL::Kdtree_interface_2d Kd_interface; - typedef CGAL::Kdtree_d Kd_tree; - typedef typename Kd_tree::Box Box; - typedef std::list Points_List; - typedef std::pair Direction_nt_pair; - typedef std::pair Kd_triple; - typedef std::pair Kd_direction_nt_pair; - typedef std::list Kd_triple_list; + + typedef CGAL::internal::Point_with_hot_pixel_history Point_with_hot_pixel_history_saved; + typedef CGAL::internal::Search_traits_kd_tree_2 + Search_traits; + typedef CGAL::Kd_tree Kd_tree; + typedef CGAL::Fuzzy_iso_box Box; + + typedef std::list Points_List; + typedef std::pair Direction_nt_pair; + typedef std::pair Kd_triple; + typedef std::pair Kd_direction_nt_pair; + typedef std::list Kd_triple_list; typedef std::pair Point_saved_pair; typedef std::list Point_saved_pair_list; typedef typename Point_saved_pair_list::iterator Point_saved_pair_iter; - typedef typename std::list My_point_saved_list; - typedef typename My_point_saved_list::iterator My_point_saved_iter; + typedef typename std::list Point_with_hot_pixel_history_saved_list; + typedef typename Point_with_hot_pixel_history_saved_list::iterator Point_with_hot_pixel_history_saved_iter; typedef std::list Point_list; typedef typename Point_list::iterator Point_iter; @@ -88,11 +150,14 @@ typedef std::list Direction_list; typedef typename Direction_list::const_iterator Direction_const_iter; + private: Traits m_gt; const double pi, half_pi; int number_of_trees; - Kd_triple_list kd_trees_list; + + Kd_triple_list kd_trees_list; + Point_saved_pair_list input_points_list; std::map angle_to_sines_appr; // was const int @@ -115,35 +180,38 @@ /*! */ Kd_triple create_kd_tree(NT angle) { - Points_List l; - Kd_tree *tree = new Kd_tree(2); - for (Point_saved_pair_iter iter = input_points_list.begin(); - iter != input_points_list.end(); ++iter) + Kd_tree *tree = new Kd_tree(); + + tree->reserve(input_points_list.size()); + + for (Point_saved_pair_iter iter = input_points_list.begin(); iter != input_points_list.end(); ++iter) { Point_2 p(iter->first); rotate(p,angle); - My_point_saved rotated_point(p,iter->first,iter->second); - l.push_back(rotated_point); + Point_with_hot_pixel_history_saved rotated_point(p,iter->first,iter->second); + + tree->insert(rotated_point); } - tree->build(l); + tree->build(); - //checking validity - if (!tree->is_valid()) tree->dump(); - CGAL_assertion(tree->is_valid()); typename Traits::To_double to_dbl; double buffer_angle(to_dbl(angle) - half_pi / (2 * number_of_trees)); - if (buffer_angle < 0) buffer_angle = 0; + if (buffer_angle < 0) + buffer_angle = 0; + Line_2 li(std::tan(buffer_angle), -1, 0); Direction_2 d(li); + // rotate_by 180 degrees Transformation_2 t(ROTATION, 0, -1); d = d.transform(t); Direction_nt_pair kp(d, angle); - Kd_triple kt(tree,kp); + + Kd_triple kt(tree, kp); return(kt); } @@ -155,10 +223,12 @@ inline NT min BOOST_PREVENT_MACRO_SUBSTITUTION (NT x1, NT x2, NT x3, NT x4, NT x5, NT x6) - {return(min BOOST_PREVENT_MACRO_SUBSTITUTION (min BOOST_PREVENT_MACRO_SUBSTITUTION (min BOOST_PREVENT_MACRO_SUBSTITUTION (x1, x2), min BOOST_PREVENT_MACRO_SUBSTITUTION (x3, x4)),min BOOST_PREVENT_MACRO_SUBSTITUTION (x5, x6)));} + {return(min BOOST_PREVENT_MACRO_SUBSTITUTION (min BOOST_PREVENT_MACRO_SUBSTITUTION (min BOOST_PREVENT_MACRO_SUBSTITUTION (x1, x2), + min BOOST_PREVENT_MACRO_SUBSTITUTION (x3, x4)),min BOOST_PREVENT_MACRO_SUBSTITUTION (x5, x6)));} inline NT max BOOST_PREVENT_MACRO_SUBSTITUTION (NT x1, NT x2, NT x3, NT x4, NT x5, NT x6) - {return(max BOOST_PREVENT_MACRO_SUBSTITUTION (max BOOST_PREVENT_MACRO_SUBSTITUTION (max BOOST_PREVENT_MACRO_SUBSTITUTION (x1, x2), max BOOST_PREVENT_MACRO_SUBSTITUTION (x3, x4)),max BOOST_PREVENT_MACRO_SUBSTITUTION (x5, x6)));} + {return(max BOOST_PREVENT_MACRO_SUBSTITUTION (max BOOST_PREVENT_MACRO_SUBSTITUTION (max BOOST_PREVENT_MACRO_SUBSTITUTION (x1, x2), + max BOOST_PREVENT_MACRO_SUBSTITUTION (x3, x4)),max BOOST_PREVENT_MACRO_SUBSTITUTION (x5, x6)));} /*! */ Direction_2 get_direction(Segment_2 seg) @@ -330,6 +400,7 @@ pi(3.1415), half_pi(1.57075), number_of_trees(inp_number_of_trees), input_points_list(inp_points_list) { + Kd_triple kd; // check that there are at least two trees @@ -353,9 +424,13 @@ angle += half_pi / number_of_trees,++i) { buffer_angle = angle - half_pi / (2 * number_of_trees); - if (buffer_angle < 0) buffer_angle = 0; + + if (buffer_angle < 0) + buffer_angle = 0; + li = Line_2(std::tan(buffer_angle), -1, 0); d = Direction_2(li); + // rotate_by 180 degrees Transformation_2 t(ROTATION, 0, -1); d = d.transform(t); @@ -369,7 +444,9 @@ #ifdef CGAL_SR_DEBUG int number_of_actual_kd_trees = 0; #endif + i = 0; + for (NT angle = 0; i < number_of_trees; angle += NT(half_pi / number_of_trees),++i) { @@ -377,6 +454,7 @@ (double)number_of_segments / (double)number_of_trees / 2.0) { kd = create_kd_tree(angle); + kd_trees_list.push_back(kd); #ifdef CGAL_SR_DEBUG @@ -397,14 +475,15 @@ } - ~Multiple_kd_tree() { - for(typename Kd_triple_list::iterator it = kd_trees_list.begin(); - it != kd_trees_list.end(); ++it) { + ~Multiple_kd_tree() + { + //delete all the kd_trees. + for(typename Kd_triple_list::iterator it = kd_trees_list.begin(); it != kd_trees_list.end(); ++it) delete (it->first); - } - for(typename Point_saved_pair_list::iterator it = input_points_list.begin(); - it != input_points_list.end(); ++it) { + //delete all the points. + for(typename Point_saved_pair_list::iterator it = input_points_list.begin(); + it != input_points_list.end(); ++it) { delete (it->second); } @@ -444,63 +523,71 @@ { // determine right kd-tree to work on, depending on the segment's slope Direction_2 d = get_direction(s); + int i = 0; int n = kd_trees_list.size(); bool found = false; typename Kd_triple_list::const_iterator iter = kd_trees_list.begin(); - while(i < n && !found) { - if (iter->second.first > d) found = true; + while(i < n && !found) + { + if (iter->second.first > d) + found = true; + ++i; ++iter; } - if (!found) iter = kd_trees_list.begin(); - else --iter; + if (!found) + iter = kd_trees_list.begin(); + + else + --iter; Point_list points_list; m_gt.minkowski_sum_with_pixel_2_object()(points_list, s, unit_square); Point_iter points_iter; - for (points_iter = points_list.begin(); points_iter != points_list.end(); - ++points_iter) + for (points_iter = points_list.begin(); points_iter != points_list.end(); ++points_iter) rotate(*points_iter, iter->second.second); // query points_iter = points_list.begin(); - Point_2 point_left,point_right,point_bot,point_top; + Point_2 point_left, point_right, point_bot, point_top; point_left = point_right = point_bot = point_top = *points_iter; - for (++points_iter; points_iter != points_list.end(); ++points_iter) { + + for (++points_iter; points_iter != points_list.end(); ++points_iter) + { point_left = small_x_point(point_left,*points_iter); point_right = big_x_point(point_right,*points_iter); point_bot = small_y_point(point_bot,*points_iter); point_top = big_y_point(point_top,*points_iter); } - typedef typename Traits::Construct_iso_rectangle_2 - Construct_iso_rectangle_2; - Construct_iso_rectangle_2 construct_rec = - m_gt.construct_iso_rectangle_2_object(); - Iso_rectangle_2 rec = - construct_rec(point_left, point_right, point_bot, point_top); + typedef typename Traits::Construct_iso_rectangle_2 Construct_iso_rectangle_2; + + Construct_iso_rectangle_2 construct_rec = m_gt.construct_iso_rectangle_2_object(); + + Iso_rectangle_2 rec = construct_rec(point_left, point_right, point_bot, point_top); Point_2 p1 = rec.vertex(0); Point_2 p2 = rec.vertex(2); - My_point_saved point1(p1); - My_point_saved point2(p2); + Point_with_hot_pixel_history_saved point1(p1); + Point_with_hot_pixel_history_saved point2(p2); - Box b(point1, point2, 2); + Box b(point1, point2); // the kd-tree query - My_point_saved_list res; - iter->first->search(std::back_inserter(res), b); + Point_with_hot_pixel_history_saved_list result; + + iter->first->search(std::back_inserter(result), b); // create result result_list.empty(); - for (My_point_saved_iter my_point_iter = res.begin(); - my_point_iter != res.end(); ++my_point_iter) + + for( Point_with_hot_pixel_history_saved_iter my_point_iter = result.begin(); my_point_iter != result.end(); ++my_point_iter ) result_list.push_back(my_point_iter->object); } }; diff -Nru cgal-4.4/include/CGAL/Snap_rounding_traits_2.h cgal-4.5/include/CGAL/Snap_rounding_traits_2.h --- cgal-4.4/include/CGAL/Snap_rounding_traits_2.h 2012-11-13 13:14:00.000000000 +0000 +++ cgal-4.5/include/CGAL/Snap_rounding_traits_2.h 2014-08-29 13:58:17.000000000 +0000 @@ -1,4 +1,4 @@ -// Copyright (c) 2001 Tel-Aviv University (Israel). +// Copyright (c) 2001,2009,2014 Tel-Aviv University (Israel), Max-Planck-Institute Saarbruecken (Germany). // All rights reserved. // // This file is part of CGAL (www.cgal.org). @@ -14,9 +14,11 @@ // // $URL$ // $Id$ -// // -// author(s) : Eli Packer +// +// author(s) : Eli Packer , +// Waqar Khan + #ifndef CGAL_SNAP_ROUNDING_2_TRAITS_H #define CGAL_SNAP_ROUNDING_2_TRAITS_H @@ -33,28 +35,29 @@ public CGAL::Arr_segment_traits_2 { public: // otherwise Segment_data cannot access the types - typedef typename Base_kernel::FT NT; - typedef typename Base_kernel::FT FT; - typedef typename Base_kernel::Point_2 Point_2; - typedef typename Base_kernel::Segment_2 Segment_2; - typedef typename Base_kernel::Iso_rectangle_2 Iso_rectangle_2; - typedef typename Base_kernel::Vector_2 Vector_2; - typedef typename Base_kernel::Line_2 Line_2; - typedef typename Base_kernel::Aff_transformation_2 Aff_transformation_2; - typedef typename Base_kernel::Direction_2 Direction_2; - typedef typename Base_kernel::Construct_vertex_2 Construct_vertex_2 ; - typedef typename Base_kernel::Construct_segment_2 Construct_segment_2 ; - typedef typename Base_kernel::Construct_iso_rectangle_2 - Construct_iso_rectangle_2; - typedef typename Base_kernel::Compare_y_2 Compare_y_2; - - typedef CGAL::Arr_segment_traits_2 Base_traits; + typedef typename Base_kernel::FT NT; + typedef typename Base_kernel::FT FT; + typedef typename Base_kernel::Point_2 Point_2; + typedef typename Base_kernel::Segment_2 Segment_2; + typedef typename Base_kernel::Iso_rectangle_2 Iso_rectangle_2; + typedef typename Base_kernel::Vector_2 Vector_2; + typedef typename Base_kernel::Line_2 Line_2; + typedef typename Base_kernel::Aff_transformation_2 Aff_transformation_2; + typedef typename Base_kernel::Direction_2 Direction_2; + typedef typename Base_kernel::Construct_vertex_2 Construct_vertex_2 ; + typedef typename Base_kernel::Construct_segment_2 Construct_segment_2 ; + typedef typename Base_kernel::Construct_iso_rectangle_2 Construct_iso_rectangle_2; + typedef typename Base_kernel::Compare_y_2 Compare_y_2; + + typedef typename Base_kernel::Construct_min_vertex_2 Construct_min_vertex_2; + typedef typename Base_kernel::Construct_max_vertex_2 Construct_max_vertex_2; + typedef typename Base_kernel::Cartesian_const_iterator_2 Cartesian_const_iterator_2; + typedef typename Base_kernel::Construct_cartesian_const_iterator_2 Construct_cartesian_const_iterator_2; + + typedef CGAL::Arr_segment_traits_2 Base_traits; + typedef typename Base_traits::Compare_x_2 Compare_x_2; + typedef CGAL::To_double To_double; - typedef typename Base_traits::Compare_x_2 Compare_x_2; - - - typedef CGAL::To_double To_double; - public: /*! Functor */ class Snap_2 { @@ -198,7 +201,6 @@ return k.construct_iso_rectangle_2_object(); } - }; } //namespace CGAL diff -Nru cgal-4.4/include/CGAL/Spatial_lock_grid_3.h cgal-4.5/include/CGAL/Spatial_lock_grid_3.h --- cgal-4.4/include/CGAL/Spatial_lock_grid_3.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/Spatial_lock_grid_3.h 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,682 @@ +// Copyright (c) 2012 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Clement Jamin + +#ifndef CGAL_STL_EXTENSION_SPATIAL_LOCK_GRID_3_H +#define CGAL_STL_EXTENSION_SPATIAL_LOCK_GRID_3_H + +#ifdef CGAL_LINKED_WITH_TBB + +#include + +#include + +#include +#if TBB_IMPLEMENT_CPP0X +# include +#else +# include +#endif +#include +#include + +#include +#include + +namespace CGAL { + +struct Tag_no_lock {}; +struct Tag_non_blocking {}; +struct Tag_non_blocking_with_mutexes {}; +struct Tag_priority_blocking {}; + +//***************************************************************************** +// class Spatial_lock_grid_base_3 +// (Uses Curiously recurring template pattern) +//***************************************************************************** + +template +class Spatial_lock_grid_base_3 +{ +private: + static bool *init_TLS_grid(int num_cells_per_axis) + { + int num_cells = num_cells_per_axis* + num_cells_per_axis*num_cells_per_axis; + bool *local_grid = new bool[num_cells]; + for (int i = 0 ; i < num_cells ; ++i) + local_grid[i] = false; + return local_grid; + } + +public: + bool *get_thread_local_grid() + { + return m_tls_grids.local(); + } + + void set_bbox(const Bbox_3 &bbox) + { + // Compute resolutions + m_bbox = bbox; + double n = static_cast(m_num_grid_cells_per_axis); + m_resolution_x = n / (bbox.xmax() - bbox.xmin()); + m_resolution_y = n / (bbox.ymax() - bbox.ymin()); + m_resolution_z = n / (bbox.zmax() - bbox.zmin()); + +#ifdef CGAL_CONCURRENT_MESH_3_VERBOSE + std::cerr << "Locking data structure Bounding Box = " + << "[" << bbox.xmin() << ", " << bbox.xmax() << "], " + << "[" << bbox.ymin() << ", " << bbox.ymax() << "], " + << "[" << bbox.zmin() << ", " << bbox.zmax() << "]" + << std::endl; +#endif + } + + const Bbox_3 &get_bbox() const + { + return m_bbox; + } + + bool is_locked_by_this_thread(int cell_index) + { + return get_thread_local_grid()[cell_index]; + } + + template + bool is_locked(const P3 &point) + { + return is_cell_locked(get_grid_index(point)); + } + + template + bool is_locked_by_this_thread(const P3 &point) + { + return get_thread_local_grid()[get_grid_index(point)]; + } + + bool try_lock(int cell_index) + { + return try_lock(cell_index); + } + + template + bool try_lock(int cell_index) + { + return get_thread_local_grid()[cell_index] + || try_lock_cell(cell_index); + } + + + bool try_lock(int index_x, int index_y, int index_z, int lock_radius) + { + return try_lock(index_x, index_y, index_z, lock_radius); + } + + template + bool try_lock(int index_x, int index_y, int index_z, int lock_radius) + { + if (lock_radius == 0) + { + int index_to_lock = + index_z*m_num_grid_cells_per_axis*m_num_grid_cells_per_axis + + index_y*m_num_grid_cells_per_axis + + index_x; + return try_lock(index_to_lock); + } + else + { + // We have to lock the square + std::vector locked_cells_tmp; + + // For each cell inside the square + for (int i = std::max(0, index_x-lock_radius) ; + i <= std::min(m_num_grid_cells_per_axis - 1, index_x+lock_radius) ; + ++i) + { + for (int j = std::max(0, index_y-lock_radius) ; + j <= std::min(m_num_grid_cells_per_axis - 1, index_y+lock_radius) ; + ++j) + { + for (int k = std::max(0, index_z-lock_radius) ; + k <= std::min(m_num_grid_cells_per_axis - 1, index_z+lock_radius) ; + ++k) + { + int index_to_lock = + k*m_num_grid_cells_per_axis*m_num_grid_cells_per_axis + + j*m_num_grid_cells_per_axis + + i; + // Try to lock it + if (try_lock(index_to_lock)) + { + locked_cells_tmp.push_back(index_to_lock); + } + else + { + // failed => we unlock already locked cells and return false + std::vector::const_iterator it = locked_cells_tmp.begin(); + std::vector::const_iterator it_end = locked_cells_tmp.end(); + for( ; it != it_end ; ++it) + { + unlock(*it); + } + return false; + } + } + } + } + + return true; + } + } + + + bool try_lock(int cell_index, int lock_radius) + { + return try_lock(cell_index, lock_radius); + } + + template + bool try_lock(int cell_index, int lock_radius) + { + if (lock_radius == 0) + { + return try_lock(cell_index); + } + else + { + int index_z = cell_index/(m_num_grid_cells_per_axis*m_num_grid_cells_per_axis); + cell_index -= index_z*m_num_grid_cells_per_axis*m_num_grid_cells_per_axis; + int index_y = cell_index/m_num_grid_cells_per_axis; + cell_index -= index_y*m_num_grid_cells_per_axis; + int index_x = cell_index; + + return try_lock(index_x, index_y, index_z, lock_radius); + } + } + + // P3 must provide .x(), .y(), .z() + template + bool try_lock(const P3 &point, int lock_radius = 0) + { + return try_lock(point, lock_radius); + } + + // P3 must provide .x(), .y(), .z() + template + bool try_lock(const P3 &point, int lock_radius = 0) + { + // Compute index on grid + int index_x = static_cast( (CGAL::to_double(point.x()) - m_bbox.xmin()) * m_resolution_x); + //index_x = std::max( 0, std::min(index_x, m_num_grid_cells_per_axis - 1) ); + index_x = + (index_x < 0 ? + 0 + : (index_x >= m_num_grid_cells_per_axis ? + m_num_grid_cells_per_axis - 1 + : index_x + ) + ); + int index_y = static_cast( (CGAL::to_double(point.y()) - m_bbox.ymin()) * m_resolution_y); + //index_y = std::max( 0, std::min(index_y, m_num_grid_cells_per_axis - 1) ); + index_y = + (index_y < 0 ? + 0 + : (index_y >= m_num_grid_cells_per_axis ? + m_num_grid_cells_per_axis - 1 + : index_y + ) + ); + int index_z = static_cast( (CGAL::to_double(point.z()) - m_bbox.zmin()) * m_resolution_z); + //index_z = std::max( 0, std::min(index_z, m_num_grid_cells_per_axis - 1) ); + index_z = + (index_z < 0 ? + 0 + : (index_z >= m_num_grid_cells_per_axis ? + m_num_grid_cells_per_axis - 1 + : index_z + ) + ); + + if (lock_radius == 0) + { + int index = + index_z*m_num_grid_cells_per_axis*m_num_grid_cells_per_axis + + index_y*m_num_grid_cells_per_axis + + index_x; + return try_lock(index); + } + else + { + return try_lock(index_x, index_y, index_z, lock_radius); + } + } + + void unlock(int cell_index) + { + // Unlock lock and shared grid + unlock_cell(cell_index); + get_thread_local_grid()[cell_index] = false; + } + + void unlock_all_points_locked_by_this_thread() + { + std::vector &tls_locked_cells = m_tls_locked_cells.local(); + std::vector::const_iterator it = tls_locked_cells.begin(); + std::vector::const_iterator it_end = tls_locked_cells.end(); + for( ; it != it_end ; ++it) + { + // If we still own the lock + int cell_index = *it; + if (get_thread_local_grid()[cell_index] == true) + unlock(cell_index); + } + tls_locked_cells.clear(); + } + + void unlock_all_tls_locked_cells_but_one(int cell_index_to_keep_locked) + { + std::vector &tls_locked_cells = m_tls_locked_cells.local(); + std::vector::const_iterator it = tls_locked_cells.begin(); + std::vector::const_iterator it_end = tls_locked_cells.end(); + bool cell_to_keep_found = false; + for( ; it != it_end ; ++it) + { + // If we still own the lock + int cell_index = *it; + if (get_thread_local_grid()[cell_index] == true) + { + if (cell_index == cell_index_to_keep_locked) + cell_to_keep_found = true; + else + unlock(cell_index); + } + } + tls_locked_cells.clear(); + if (cell_to_keep_found) + tls_locked_cells.push_back(cell_index_to_keep_locked); + } + + template + void unlock_all_tls_locked_locations_but_one_point(const P3 &point) + { + unlock_all_tls_locked_cells_but_one(get_grid_index(point)); + } + + bool check_if_all_cells_are_unlocked() + { + int num_cells = m_num_grid_cells_per_axis* + m_num_grid_cells_per_axis*m_num_grid_cells_per_axis; + bool unlocked = true; + for (int i = 0 ; unlocked && i < num_cells ; ++i) + unlocked = !is_cell_locked(i); + return unlocked; + } + + bool check_if_all_tls_cells_are_unlocked() + { + int num_cells = m_num_grid_cells_per_axis* + m_num_grid_cells_per_axis*m_num_grid_cells_per_axis; + bool unlocked = true; + for (int i = 0 ; unlocked && i < num_cells ; ++i) + unlocked = (get_thread_local_grid()[i] == false); + return unlocked; + } + +protected: + + // Constructor + Spatial_lock_grid_base_3(const Bbox_3 &bbox, + int num_grid_cells_per_axis) + : m_num_grid_cells_per_axis(num_grid_cells_per_axis), + m_tls_grids(boost::bind(init_TLS_grid, num_grid_cells_per_axis)) + { + set_bbox(bbox); + } + + /// Destructor + ~Spatial_lock_grid_base_3() + { + for( TLS_grid::iterator it_grid = m_tls_grids.begin() ; + it_grid != m_tls_grids.end() ; + ++it_grid ) + { + delete [] *it_grid; + } + } + + template + int get_grid_index(const P3& point) const + { + // Compute indices on grid + int index_x = static_cast( (CGAL::to_double(point.x()) - m_bbox.xmin()) * m_resolution_x); + //index_x = std::max( 0, std::min(index_x, m_num_grid_cells_per_axis - 1) ); + index_x = + (index_x < 0 ? + 0 + : (index_x >= m_num_grid_cells_per_axis ? + m_num_grid_cells_per_axis - 1 + : index_x + ) + ); + int index_y = static_cast( (CGAL::to_double(point.y()) - m_bbox.ymin()) * m_resolution_y); + //index_y = std::max( 0, std::min(index_y, m_num_grid_cells_per_axis - 1) ); + index_y = + (index_y < 0 ? + 0 + : (index_y >= m_num_grid_cells_per_axis ? + m_num_grid_cells_per_axis - 1 + : index_y + ) + ); + int index_z = static_cast( (CGAL::to_double(point.z()) - m_bbox.zmin()) * m_resolution_z); + //index_z = std::max( 0, std::min(index_z, m_num_grid_cells_per_axis - 1) ); + index_z = + (index_z < 0 ? + 0 + : (index_z >= m_num_grid_cells_per_axis ? + m_num_grid_cells_per_axis - 1 + : index_z + ) + ); + + return + index_z*m_num_grid_cells_per_axis*m_num_grid_cells_per_axis + + index_y*m_num_grid_cells_per_axis + + index_x; + } + + bool is_cell_locked(int cell_index) + { + return static_cast(this)->is_cell_locked_impl(cell_index); + } + + bool try_lock_cell(int cell_index) + { + return try_lock_cell(cell_index); + } + + template + bool try_lock_cell(int cell_index) + { + return static_cast(this) + ->template try_lock_cell_impl(cell_index); + } + void unlock_cell(int cell_index) + { + static_cast(this)->unlock_cell_impl(cell_index); + } + + int m_num_grid_cells_per_axis; + Bbox_3 m_bbox; + double m_resolution_x; + double m_resolution_y; + double m_resolution_z; + + // TLS + typedef tbb::enumerable_thread_specific< + bool*, + tbb::cache_aligned_allocator, + tbb::ets_key_per_instance> TLS_grid; + typedef tbb::enumerable_thread_specific > TLS_locked_cells; + + TLS_grid m_tls_grids; + TLS_locked_cells m_tls_locked_cells; +}; + + + +//***************************************************************************** +// class Spatial_lock_grid_3 +//***************************************************************************** +template +class Spatial_lock_grid_3; + + +//***************************************************************************** +// class Spatial_lock_grid_3 +//***************************************************************************** +template <> +class Spatial_lock_grid_3 + : public Spatial_lock_grid_base_3< + Spatial_lock_grid_3 > +{ + typedef Spatial_lock_grid_base_3< + Spatial_lock_grid_3 > Base; + +public: + // Constructors + Spatial_lock_grid_3(const Bbox_3 &bbox, int num_grid_cells_per_axis) + : Base(bbox, num_grid_cells_per_axis) + { + int num_cells = + num_grid_cells_per_axis*num_grid_cells_per_axis*num_grid_cells_per_axis; + + m_grid.resize(num_cells); + // Initialize grid (useless?) + for (int i = 0 ; i < num_cells ; ++i) + m_grid[i] = false; + } + + ~Spatial_lock_grid_3() + { + } + + bool is_cell_locked_impl(int cell_index) + { + return (m_grid[cell_index] == true); + } + + template + bool try_lock_cell_impl(int cell_index) + { + bool old_value = m_grid[cell_index].compare_and_swap(true, false); + if (old_value == false) + { + get_thread_local_grid()[cell_index] = true; + m_tls_locked_cells.local().push_back(cell_index); + return true; + } + return false; + } + + void unlock_cell_impl(int cell_index) + { + m_grid[cell_index] = false; + } + +protected: + + std::vector > m_grid; +}; + + +//***************************************************************************** +// class Spatial_lock_grid_3 +//***************************************************************************** + +template <> +class Spatial_lock_grid_3 + : public Spatial_lock_grid_base_3 > +{ + typedef Spatial_lock_grid_base_3< + Spatial_lock_grid_3 > Base; + +public: + // Constructors + + Spatial_lock_grid_3(const Bbox_3 &bbox, int num_grid_cells_per_axis) + : Base(bbox, num_grid_cells_per_axis), + m_tls_thread_ids(init_TLS_thread_ids) + { + int num_cells = + num_grid_cells_per_axis*num_grid_cells_per_axis*num_grid_cells_per_axis; + m_grid.resize(num_cells); + } + + /// Destructor + ~Spatial_lock_grid_3() + { + } + + bool is_cell_locked_impl(int cell_index) + { + return (m_grid[cell_index] != 0); + } + + template + bool try_lock_cell_impl(int cell_index) + { + unsigned int this_thread_id = m_tls_thread_ids.local(); + + // NO SPIN + if (no_spin) + { + unsigned int old_value = + m_grid[cell_index].compare_and_swap(this_thread_id, 0); + if (old_value == 0) + { + get_thread_local_grid()[cell_index] = true; + m_tls_locked_cells.local().push_back(cell_index); + return true; + } + } + // SPIN + else + { + for(;;) + { + unsigned int old_value = + m_grid[cell_index].compare_and_swap(this_thread_id, 0); + if (old_value == 0) + { + get_thread_local_grid()[cell_index] = true; + m_tls_locked_cells.local().push_back(cell_index); + return true; + } + else if (old_value > this_thread_id) + { + // Another "more prioritary" thread owns the lock, we back off + return false; + } + else + { + std::this_thread::yield(); + } + } + } + + return false; + } + + void unlock_cell_impl(int cell_index) + { + m_grid[cell_index] = 0; + } + +private: + static unsigned int init_TLS_thread_ids() + { + static tbb::atomic last_id; + unsigned int id = ++last_id; + // Ensure it is > 0 + return (1 + id%(std::numeric_limits::max())); + } + +protected: + + std::vector > m_grid; + + typedef tbb::enumerable_thread_specific TLS_thread_uint_ids; + TLS_thread_uint_ids m_tls_thread_ids; +}; + +//***************************************************************************** +// class Spatial_lock_grid_3 +// Note: undocumented, for testing only... +//***************************************************************************** + +template <> +class Spatial_lock_grid_3 + : public Spatial_lock_grid_base_3< + Spatial_lock_grid_3 > +{ + typedef Spatial_lock_grid_base_3< + Spatial_lock_grid_3 > Base; + +public: + // Constructors + Spatial_lock_grid_3(const Bbox_3 &bbox, int num_grid_cells_per_axis) + : Base(bbox, num_grid_cells_per_axis) + { + int num_cells = + num_grid_cells_per_axis*num_grid_cells_per_axis*num_grid_cells_per_axis; + m_grid.resize(num_cells); + } + + /// Destructor + ~Spatial_lock_grid_3() + { + } + + bool is_cell_locked_impl(int cell_index) + { + bool locked = m_grid[cell_index].try_lock(); + if (locked) + m_grid[cell_index].unlock(); + return !locked; + } + + template + bool try_lock_cell_impl(int cell_index) + { + bool success = m_grid[cell_index].try_lock(); + if (success) + { + get_thread_local_grid()[cell_index] = true; + m_tls_locked_cells.local().push_back(cell_index); + } + return success; + } + + void unlock_cell_impl(int cell_index) + { + m_grid[cell_index].unlock(); + } + +protected: + + std::vector m_grid; +}; + +} //namespace CGAL + +#else // !CGAL_LINKED_WITH_TBB + +namespace CGAL { + +template +class Spatial_lock_grid_3 +{ +}; + +} + +#endif // CGAL_LINKED_WITH_TBB + +#endif // CGAL_STL_EXTENSION_SPATIAL_LOCK_GRID_3_H diff -Nru cgal-4.4/include/CGAL/Subdivision_mask_3.h cgal-4.5/include/CGAL/Subdivision_mask_3.h --- cgal-4.4/include/CGAL/Subdivision_mask_3.h 2012-11-13 13:14:01.000000000 +0000 +++ cgal-4.5/include/CGAL/Subdivision_mask_3.h 2014-08-29 13:58:17.000000000 +0000 @@ -237,7 +237,7 @@ if (n == 6) { pt = Point((10*S[0]+R[0])/16, (10*S[1]+R[1])/16, (10*S[2]+R[2])/16); } else { - FT Cn = (FT) (5.0/8.0 - std::sqrt(3+2*std::cos(6.283/(double)n))/64.0); + FT Cn = (FT) (5.0/8.0 - CGAL::square(3+2*std::cos(2 * CGAL_PI/(double) n))/64.0); FT Sw = (double)n*(1-Cn)/Cn; FT W = (double)n/Cn; pt = Point((Sw*S[0]+R[0])/W, (Sw*S[1]+R[1])/W, (Sw*S[2]+R[2])/W); diff -Nru cgal-4.4/include/CGAL/Surface_mesh_default_triangulation_3.h cgal-4.5/include/CGAL/Surface_mesh_default_triangulation_3.h --- cgal-4.4/include/CGAL/Surface_mesh_default_triangulation_3.h 2012-11-24 20:00:52.000000000 +0000 +++ cgal-4.5/include/CGAL/Surface_mesh_default_triangulation_3.h 2014-08-29 13:58:17.000000000 +0000 @@ -31,7 +31,7 @@ // vertex and cell bases #include #include -#include +#include namespace CGAL { namespace Surface_mesher { @@ -45,7 +45,8 @@ // vertex and cell types typedef Surface_mesh_vertex_base_3 Vb; typedef Surface_mesh_cell_base_3 Cb; - typedef Triangulation_cell_base_with_circumcenter_3 Cb_with_circumcenter; + typedef Delaunay_triangulation_cell_base_with_circumcenter_3 + Cb_with_circumcenter; // triangulation typedef Triangulation_data_structure_3 Tds; diff -Nru cgal-4.4/include/CGAL/Surface_mesh_deformation.h cgal-4.5/include/CGAL/Surface_mesh_deformation.h --- cgal-4.4/include/CGAL/Surface_mesh_deformation.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/Surface_mesh_deformation.h 2014-10-04 19:00:10.000000000 +0000 @@ -0,0 +1,1509 @@ +// Copyright (c) 2014 GeometryFactory +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Yin Xu, Andreas Fabri and Ilker O. Yaz + +#ifndef CGAL_SURFACE_MESH_DEFORMATION_H +#define CGAL_SURFACE_MESH_DEFORMATION_H + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/* +#define CGAL_DEFORM_MESH_USE_EXPERIMENTAL_SCALE // define it to activate optimal scale calculation, +// then you can define below to just scale, if not both rotate and scale will be activated +#define CGAL_DEFORM_MESH_JUST_EXPERIMENTAL_SCALE // to not to rotate but just scale +*/ + +// for default parameters +#if defined(CGAL_EIGEN3_ENABLED) +#include // for sparse linear system solver +#include // for 3x3 closest rotation computer +#endif + +namespace CGAL { + +/// \ingroup PkgSurfaceModeling +///@brief Deformation algorithm type +enum Deformation_algorithm_tag +{ + ORIGINAL_ARAP, /**< use original as-rigid-as possible algorithm */ + SPOKES_AND_RIMS /**< use spokes and rims version of as-rigid-as possible algorithm */ +}; + +/// @cond CGAL_DOCUMENT_INTERNAL +namespace internal { +template +struct Weight_calculator_selector { + typedef Uniform_weight weight_calculator; +}; + +template +struct Weight_calculator_selector { + typedef Single_cotangent_weight weight_calculator; +}; + +template +struct Weight_calculator_selector { + typedef Cotangent_weight weight_calculator; +}; +}//namespace internal +/// @endcond + + /// + /// \ingroup PkgSurfaceModeling + /// @brief Class providing the functionalities for deforming a triangulated surface mesh + /// + /// @tparam HG a model of HalfedgeGraph + /// @tparam VIM a model of `ReadablePropertyMap` with Surface_mesh_deformation::vertex_descriptor as key and `unsigned int` as value type. + /// The default is `boost::property_map::%type`. + /// @tparam HIM a model of `ReadablePropertyMap` with Surface_mesh_deformation::halfedge_descriptor as key and `unsigned int` as value type. + /// The default is `boost::property_map::%type`. + /// @tparam TAG tag for selecting the deformation algorithm + /// @tparam WC a model of SurfaceModelingWeights, with `WC::Halfedge_graph` being `HG`. + /// If `TAG` is `ORIGINAL_ARAP`, the weights must be positive to guarantee a correct energy minimization. + /// The default is the cotangent weighting scheme. In case `TAG` is `ORIGINAL_ARAP`, negative weights are clamped to zero. + /// @tparam ST a model of SparseLinearAlgebraTraitsWithFactor_d. If \ref thirdpartyEigen "Eigen" 3.2 (or greater) is available + /// and `CGAL_EIGEN3_ENABLED` is defined, then an overload of `Eigen_solver_traits` is provided as default parameter.\n + /// \code + /// CGAL::Eigen_solver_traits< + /// Eigen::SparseLU< + /// CGAL::Eigen_sparse_matrix::EigenType, + /// Eigen::COLAMDOrdering > > + /// \endcode + /// @tparam CR a model of DeformationClosestRotationTraits_3. If \ref thirdpartyEigen "Eigen" 3.1 (or greater) is available and `CGAL_EIGEN3_ENABLED` is defined, + /// `Deformation_Eigen_polar_closest_rotation_traits_3` is provided as default parameter. + /// @tparam VPM a model of `ReadWritePropertyMap` with Surface_mesh_deformation::vertex_descriptor as key and a point as value type. The point type must be a model of `::RawPoint_3`. + /// The default is `boost::property_map::%type`. +template < + class HG, + class VIM=Default, + class HIM=Default, + Deformation_algorithm_tag TAG = SPOKES_AND_RIMS, + class WC = Default, + class ST = Default, + class CR = Default, + class VPM = Default + > +class Surface_mesh_deformation +{ +//Typedefs +public: + + /// \name Types + /// @{ + // typedefed template parameters, main reason is doxygen creates autolink to typedefs but not template parameters + /// + typedef HG Halfedge_graph; + +// Index maps +#ifndef DOXYGEN_RUNNING + typedef typename Default::Get< + VIM, + typename boost::property_map::type + >::type Vertex_index_map; + typedef typename Default::Get< + HIM, + typename boost::property_map::type + >::type Hedge_index_map; +#else + /// + typedef VIM Vertex_index_map; + /// + typedef HIM Hedge_index_map; +#endif + +// weight calculator +#ifndef DOXYGEN_RUNNING + typedef typename Default::Get< + WC, + typename internal::Weight_calculator_selector::weight_calculator + >::type Weight_calculator; +#else + /// + typedef WC Weight_calculator; +#endif + +// sparse linear solver +#ifndef DOXYGEN_RUNNING + typedef typename Default::Get< + ST, + #if defined(CGAL_EIGEN3_ENABLED) + CGAL::Eigen_solver_traits< + Eigen::SparseLU< + CGAL::Eigen_sparse_matrix::EigenType, + Eigen::COLAMDOrdering > > + #else + ST // no parameter provided, and Eigen is not enabled: so don't compile! + #endif + >::type Sparse_linear_solver; +#else + /// + typedef ST Sparse_linear_solver; +#endif + +// CR helper +#ifndef DOXYGEN_RUNNING + typedef typename Default::Get< + CR, + #if defined(CGAL_EIGEN3_ENABLED) + Deformation_Eigen_polar_closest_rotation_traits_3 + #else + CR // no parameter provided, and Eigen is not enabled: so don't compile! + #endif + >::type Closest_rotation_traits; +#else + /// + typedef CR Closest_rotation_traits; +#endif + +// vertex point pmap +#ifndef DOXYGEN_RUNNING + typedef typename Default::Get< + VPM, + typename boost::property_map::type + >::type Vertex_point_map; +#else + /// + typedef VPM Vertex_point_map; +#endif + + /// The type for vertex descriptor + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + /// The type for halfedge descriptor + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + /// The 3D point type, model of `::RawPoint_3` + typedef typename boost::property_traits::value_type Point; + /// A constant iterator range over the vertices of the region-of-interest. + /// It is a model of `ConstRange` with `vertex_descriptor` as iterator value type. + typedef std::vector Roi_vertex_range; +/// @} + +private: + typedef Surface_mesh_deformation Self; + // Repeat Halfedge_graph types + typedef typename boost::graph_traits::vertex_iterator vertex_iterator; + typedef typename boost::graph_traits::halfedge_iterator halfedge_iterator; + typedef typename boost::graph_traits::in_edge_iterator in_edge_iterator; + typedef typename boost::graph_traits::out_edge_iterator out_edge_iterator; + + typedef typename Closest_rotation_traits::Matrix CR_matrix; + typedef typename Closest_rotation_traits::Vector CR_vector; + +// Data members. + Halfedge_graph& m_halfedge_graph; /**< Source triangulated surface mesh for modeling */ + + std::vector original; ///< original positions of roi (size: ros + boundary_of_ros) + std::vector solution; ///< storing position of ros vertices during iterations (size: ros + boundary_of_ros) + + Vertex_index_map vertex_index_map; ///< storing indices of all vertices + Hedge_index_map hedge_index_map; ///< storing indices of all halfedges + + std::vector roi; ///< region of interest + std::vector ros; ///< region of solution, including roi and hard constraints on boundary of roi + + std::vector ros_id_map; ///< (size: num vertices) + std::vector is_roi_map; ///< (size: num vertices) + std::vector is_ctrl_map; ///< (size: num vertices) + + std::vector hedge_weight; ///< all halfedge weights + std::vector rot_mtr; ///< rotation matrices of ros vertices (size: ros) + + Sparse_linear_solver m_solver; ///< linear sparse solver + unsigned int m_iterations; ///< number of maximal iterations + double m_tolerance; ///< tolerance of convergence + + bool need_preprocess_factorization; ///< is there any need to compute L and factorize + bool need_preprocess_region_of_solution; ///< is there any need to compute region of solution + + bool last_preprocess_successful; ///< stores the result of last call to preprocess() + + Weight_calculator weight_calculator; + + Vertex_point_map vertex_point_map; + +#ifdef CGAL_DEFORM_MESH_USE_EXPERIMENTAL_SR_ARAP +public: +// SR-ARAP [Zohar13] + double m_sr_arap_alpha; +private: +#endif +#ifdef CGAL_DEFORM_MESH_USE_EXPERIMENTAL_SCALE + std::vector scales; +#endif + +#ifndef CGAL_CFG_NO_CPP0X_DELETED_AND_DEFAULT_FUNCTIONS +public: + Surface_mesh_deformation(const Self&) = delete; // no copy +#else +private: + Surface_mesh_deformation(const Self&); // no copy +#endif + + +// Public methods +public: + + /// \cond SKIP_FROM_MANUAL + //vertex_point_map set by default + Surface_mesh_deformation(Halfedge_graph& halfedge_graph, + Vertex_index_map vertex_index_map, + Hedge_index_map hedge_index_map + ) + : m_halfedge_graph(halfedge_graph), vertex_index_map(vertex_index_map), hedge_index_map(hedge_index_map), + ros_id_map(std::vector(num_vertices(halfedge_graph), (std::numeric_limits::max)() )), + is_roi_map(std::vector(num_vertices(halfedge_graph), false)), + is_ctrl_map(std::vector(num_vertices(halfedge_graph), false)), + m_iterations(5), m_tolerance(1e-4), + need_preprocess_factorization(true), + need_preprocess_region_of_solution(true), + last_preprocess_successful(false), + weight_calculator(Weight_calculator()), + vertex_point_map(get(vertex_point, halfedge_graph)) + { + init(); + } + + //vertex_point_map and hedge_index_map set by default + Surface_mesh_deformation(Halfedge_graph& halfedge_graph, + Vertex_index_map vertex_index_map + ) + : m_halfedge_graph(halfedge_graph), vertex_index_map(vertex_index_map), + hedge_index_map(get(boost::halfedge_index, halfedge_graph)), + ros_id_map(std::vector(num_vertices(halfedge_graph), (std::numeric_limits::max)() )), + is_roi_map(std::vector(num_vertices(halfedge_graph), false)), + is_ctrl_map(std::vector(num_vertices(halfedge_graph), false)), + m_iterations(5), m_tolerance(1e-4), + need_preprocess_factorization(true), + need_preprocess_region_of_solution(true), + last_preprocess_successful(false), + weight_calculator(Weight_calculator()), + vertex_point_map(get(vertex_point, halfedge_graph)) + { + init(); + } + //vertex_point_map, hedge_index_map and vertex_index_map set by default + Surface_mesh_deformation(Halfedge_graph& halfedge_graph) + : m_halfedge_graph(halfedge_graph), + vertex_index_map(get(boost::vertex_index, halfedge_graph)), + hedge_index_map(get(boost::halfedge_index, halfedge_graph)), + ros_id_map(std::vector(num_vertices(halfedge_graph), (std::numeric_limits::max)() )), + is_roi_map(std::vector(num_vertices(halfedge_graph), false)), + is_ctrl_map(std::vector(num_vertices(halfedge_graph), false)), + m_iterations(5), m_tolerance(1e-4), + need_preprocess_factorization(true), + need_preprocess_region_of_solution(true), + last_preprocess_successful(false), + weight_calculator(Weight_calculator()), + vertex_point_map(get(vertex_point, halfedge_graph)) + { + init(); + } + + // Constructor with all the parameters provided + Surface_mesh_deformation(Halfedge_graph& halfedge_graph, + Vertex_index_map vertex_index_map, + Hedge_index_map hedge_index_map, + Vertex_point_map vertex_point_map, + Weight_calculator weight_calculator = Weight_calculator() + ) + : m_halfedge_graph(halfedge_graph), vertex_index_map(vertex_index_map), hedge_index_map(hedge_index_map), + ros_id_map(std::vector(num_vertices(halfedge_graph), (std::numeric_limits::max)() )), + is_roi_map(std::vector(num_vertices(halfedge_graph), false)), + is_ctrl_map(std::vector(num_vertices(halfedge_graph), false)), + m_iterations(5), m_tolerance(1e-4), + need_preprocess_factorization(true), + need_preprocess_region_of_solution(true), + last_preprocess_successful(false), + weight_calculator(weight_calculator), + vertex_point_map(vertex_point_map) + { + init(); + } + /// \endcond + #if DOXYGEN_RUNNING +/// \name Construction +/// @{ + /** + * The constructor of a deformation object + * + * @pre the halfedge_graph consists of only triangular facets + * @param halfedge_graph triangulated surface mesh to deform + * @param vertex_index_map property map for associating an id to each vertex, from `0` to `num_vertices(halfedge_graph)-1`. + * @param hedge_index_map property map for associating an id to each halfedge, from `0` to `2*num_edges(halfedge_graph)-1`. + * @param vertex_point_map property map used to access the points associated to each vertex of the graph. + * @param weight_calculator function object or pointer for weight calculation + */ + Surface_mesh_deformation(Halfedge_graph& halfedge_graph, + Vertex_index_map vertex_index_map=get(boost::vertex_index, halfedge_graph), + Hedge_index_map hedge_index_map=get(boost::halfedge_index, halfedge_graph), + Vertex_point_map vertex_point_map=get(vertex_point, halfedge_graph), + Weight_calculator weight_calculator = Weight_calculator() + ); +/// @} + #endif + +private: + void init() { + // compute halfedge weights + halfedge_iterator eb, ee; + hedge_weight.reserve(2*num_edges(m_halfedge_graph)); + for(cpp11::tie(eb, ee) = halfedges(m_halfedge_graph); eb != ee; ++eb) + { + hedge_weight.push_back( + this->weight_calculator(*eb, m_halfedge_graph, vertex_point_map)); + } +#ifdef CGAL_DEFORM_MESH_USE_EXPERIMENTAL_SR_ARAP + m_sr_arap_alpha=2; +#endif + } + +public: + +/// \name Preprocessing +/// @{ + /** + * Erases all the vertices from the region-of-interest (control vertices included). + */ + void clear_roi_vertices(){ + need_preprocess_both(); + // clear roi vertices + roi.clear(); + //set to false all bits + is_roi_map.assign(num_vertices(m_halfedge_graph), false); + is_ctrl_map.assign(num_vertices(m_halfedge_graph), false); + } + + /** + * Erases all the vertices from the set of control vertices. + */ + void clear_control_vertices(){ + need_preprocess_factorization=true; + //set to false all bits + is_ctrl_map.assign(num_vertices(m_halfedge_graph), false); + } + + /** + * Inserts a vertex in the set of control vertices. The vertex is also inserted in the region-of-interest if it is not already in it. + * @param vd the vertex to be inserted + * @return `true` if `vd` is not already a control vertex. + */ + bool insert_control_vertex(vertex_descriptor vd) + { + if(is_control_vertex(vd)) { return false; } + need_preprocess_factorization=true; + + insert_roi_vertex(vd); // also insert it as roi + + is_ctrl_map[id(vd)] = true; + return true; + } + + /** + * Inserts a range of vertices in the set of control vertices. The vertices are also inserted in the region-of-interest if they are not already in it. + * @tparam InputIterator input iterator type with `vertex_descriptor` as value type + * @param begin first iterator of the range of vertices + * @param end past-the-end iterator of the range of vertices + */ + template + void insert_control_vertices(InputIterator begin, InputIterator end) + { + for( ;begin != end; ++begin) + { + insert_control_vertex(*begin); + } + } + + /** + * Erases a vertex from the set of control vertices. + * @param vd the vertex to be erased + * @return `true` if `vd` was a control vertex. + */ + bool erase_control_vertex(vertex_descriptor vd) + { + if(!is_control_vertex(vd)) { return false; } + + need_preprocess_factorization=true; + is_ctrl_map[id(vd)] = false; + return true; + } + + /** + * Inserts a range of vertices in the region-of-interest + * @tparam InputIterator input iterator with `vertex_descriptor` as value type + * @param begin first iterator of the range of vertices + * @param end past-the-end iterator of the range of vertices + */ + template + void insert_roi_vertices(InputIterator begin, InputIterator end) + { + for( ;begin != end; ++begin) + { + insert_roi_vertex(*begin); + } + } + + /** + * Inserts a vertex in the region-of-interest + * @param vd the vertex to be inserted + * @return `true` if `vd` is not already in the region-of-interest. + */ + bool insert_roi_vertex(vertex_descriptor vd) + { + if(is_roi_vertex(vd)) { return false; } + need_preprocess_both(); + + is_roi_map[id(vd)] = true; + roi.push_back(vd); + return true; + } + + /** + * Erases a vertex from the region-of-interest and the set of control vertices. + * \note At the next call to `preprocess()`, any vertex that is no longer in the region-of-interest will be assigned to its original position + * (that is the position of the vertex at the time of construction or after the last call to `overwrite_initial_geometry()`). + * @param vd the vertex to be erased + * @return `true` `vd` was a vertex from the region-of-interest. + */ + bool erase_roi_vertex(vertex_descriptor vd) + { + if(!is_roi_vertex(vd)) { return false; } + + erase_control_vertex(vd); // also erase from being control + + typename std::vector::iterator it = std::find(roi.begin(), roi.end(), vd); + if(it != roi.end()) + { + is_roi_map[id(vd)] = false; + roi.erase(it); + + need_preprocess_both(); + return true; + } + + CGAL_assertion(false); // inconsistency between is_roi_map, and roi vector! + return false; + } + + /** + * Preprocessing function that need to be called each time the region-of-interest or the set + * of control vertices are changed before calling `deform()`. + * If not already done, `deform()` first calls this function. + * \cgalAdvancedBegin + * Collects the vertices not in the region-of-interest that are adjacent to a vertex from the + * region-of-interest (these vertices are internally considered as fixed control vertices). + * Then assembles and factorizes the Laplacian matrix used in the function `deform()`. + * \cgalAdvancedEnd + * \note A modification of the set of control vertices or the region-of-interest invalidates the + * preprocessing data. + * @return `true` if successful. + * A common reason for failure is that the system is rank deficient, + * which happens for example when all the vertices are in the region-of-interest and no control vertices are set, or + * if the weighting scheme used features too many zero and breaks the connectivity information. + */ + bool preprocess() + { + region_of_solution(); + assemble_laplacian_and_factorize(); + return last_preprocess_successful; // which is set by assemble_laplacian_and_factorize() + } +/// @} Preprocessing + +/// \name Deformation +/// @{ + + /** + * Sets the target position of a control vertex. + * @param vd the control vertex the target position is set + * @param target_position the new target position + */ + void set_target_position(vertex_descriptor vd, const Point& target_position) + { + region_of_solution(); // we require ros ids, so if there is any need to preprocess of region of solution -do it. + + if(!is_control_vertex(vd)) { return; } + solution[ros_id(vd)] = target_position; + } + + /** + * Updates the target position of `vd` by applying a translation of vector `t`. + * + * @tparam Vect is a 3D vector class, with `Vect(double x,double y, double z)` being a constructor from its %Cartesian coordinates + * and `double Vect::operator[](int i)` with i=0,1 or 2 returning its %Cartesian coordinates. + * + * @param vd a control vertex + * @param t translation vector + * \pre `is_control_vertex(vd)` + */ + template + void translate(vertex_descriptor vd, const Vect& t) + { + region_of_solution(); // we require ros ids, so if there is any need to preprocess of region of solution -do it. + + std::size_t v_id = ros_id(vd); + solution[v_id] = add_to_point(solution[v_id], t); + } + + /** + * Equivalent to calling the overload taking only one control vertex, for each vertex in the range `[begin,end[`. + * + * @tparam InputIterator input iterator type with `vertex_descriptor` as value type + * @tparam Vect is a 3D vector class, with `Vect(double x,double y, double z)` being a constructor from its %Cartesian coordinates + * and `double Vect::operator[](int i)` with i=0,1 or 2 returning its %Cartesian coordinates. + * + * @param begin first iterator of the range of vertices + * @param end past-the-end iterator of the range of vertices + * @param t translation vector + */ + template + void translate(InputIterator begin, InputIterator end, const Vect& t) + { + region_of_solution(); // we require ros ids, so if there is any need to preprocess of region of solution -do it. + + for(; begin != end; ++begin) { + std::size_t v_id = ros_id(*begin); + solution[v_id] = add_to_point(solution[v_id], t); + } + } + + /** + * Updates the target position of `vd` by applying to its last target position + * a rotation defined by the quaternion `quat`, the center of the rotation being + * the origin translated by `to_rotation_center` . + * + * @tparam Quaternion is a quaternion class with `Vect operator*(Quaternion, Vect)` returning the product of a quaternion with a vector + * @tparam Vect is a 3D vector class, with `Vect(double x,double y, double z)` being a constructor from its %Cartesian coordinates + * and `double Vect::operator[](int i)` with i=0,1 or 2 returning its %Cartesian coordinates. + * + * @param vd a control vertex + * @param to_rotation_center the vector to translate the origin to the center of the rotation + * @param quat quaternion of the rotation + * \pre `is_control_vertex(vd)` + * \pre `quad` represents a rotation + */ + template + void rotate(vertex_descriptor vd, const Vect& to_rotation_center, const Quaternion& quat) + { + CGAL_precondition( is_control_vertex(vd) ); + region_of_solution(); // we require ros ids, so if there is any need to preprocess of region of solution -do it. + + std::size_t v_id = ros_id(vd); + Vect v = quat * sub_to_vect(solution[v_id], to_rotation_center); + solution[v_id] = Point( to_rotation_center[0]+v[0], + to_rotation_center[1]+v[1], + to_rotation_center[2]+v[2] ); + } + + /** + * Equivalent to calling the overload taking only one control vertex, for each vertex in the range `[begin,end[`. + * + * @tparam InputIterator input iterator type with `vertex_descriptor` as value type + * @tparam Quaternion is a quaternion class with `Vect operator*(Quaternion, Vect)` returning the product of a quaternion with a vector + * @tparam Vect is a 3D vector class, with `Vect(double x,double y, double z)` being a constructor from its %Cartesian coordinates + * and `double Vect::operator[](int i)` with i=0,1 or 2 returning its %Cartesian coordinates. + * + * @param begin first iterator of the range of vertices + * @param end past-the-end iterator of the range of vertices + * @param to_rotation_center the vector to translate the origin to the center of the rotation + * @param quat quaternion of the rotation + * \pre `quad` represents a rotation + */ + template + void rotate(InputIterator begin, InputIterator end, const Vect& to_rotation_center, const Quaternion& quat) + { + region_of_solution(); // we require ros ids, so if there is any need to preprocess of region of solution -do it. + + for(; begin != end; ++begin) { + std::size_t v_id = ros_id(*begin); + Vect v = quat * sub_to_vect(solution[v_id], to_rotation_center); + solution[v_id] = Point( to_rotation_center[0]+v[0], + to_rotation_center[1]+v[1], + to_rotation_center[2]+v[2] ); + } + } + + /** + * Returns the target position of a control vertex. + * \param vd a control vertex + * \pre `is_control_vertex(vd)` + */ + const Point& target_position(vertex_descriptor vd) + { + region_of_solution(); + + CGAL_precondition( is_control_vertex(vd) ); + return solution[ ros_id(vd) ]; + } + + /** + * Deforms the region-of-interest according to the deformation algorithm, using the target positions of each control vertex set by using `rotate()`, `translate()`, or `set_target_position()`. + * The points associated to each vertex of the input graph that are inside the region-of-interest are updated. + * \note Nothing happens if `preprocess()` returns `false`. + * @see set_iterations(unsigned int iterations), set_tolerance(double tolerance), deform(unsigned int iterations, double tolerance) + */ + void deform() + { + deform(m_iterations, m_tolerance); + } + + /** + * Same as `deform()` but the number of iterations and the tolerance are one-time parameters. + * @param iterations number of iterations for optimization procedure + * @param tolerance tolerance of convergence (see explanations set_tolerance(double tolerance)) + */ + void deform(unsigned int iterations, double tolerance) + { + preprocess(); + + if(!last_preprocess_successful) { + CGAL_warning(false); + return; + } + // Note: no energy based termination occurs at first iteration + // because comparing energy of original model (before deformation) and deformed model (deformed_1_iteration) + // simply does not make sense, comparison is meaningful between deformed_(i)_iteration & deformed_(i+1)_iteration + + double energy_this = 0; // initial value is not important, because we skip first iteration + double energy_last; + + // iterations + for ( unsigned int ite = 0; ite < iterations; ++ite) + { + // main steps of optimization + update_solution(); +#ifndef CGAL_DEFORM_MESH_JUST_EXPERIMENTAL_SCALE + optimal_rotations(); +#endif +#ifdef CGAL_DEFORM_MESH_USE_EXPERIMENTAL_SCALE + optimal_scales(); +#endif + // energy based termination + if(tolerance > 0.0 && (ite + 1) < iterations) // if tolerance <= 0 then don't compute energy + { // also no need compute energy if this iteration is the last iteration + energy_last = energy_this; + energy_this = energy(); + CGAL_warning(energy_this >= 0); + + if(ite != 0) // skip first iteration + { + double energy_dif = std::abs((energy_last - energy_this) / energy_this); + if ( energy_dif < tolerance ) { break; } + } + } + } + // copy solution to the target surface mesh + assign_solution(); + } + + /** + * Resets the points associated to the vertices of the region-of-interest at their + * initial positions at time of the functor construction or after + * the last call to `overwrite_initial_geometry()`. + * \note if the region-of-interest or the set of control vertices have been + * modified since the last call to `preprocess()`, it will be called prior + * to the reset. + */ + void reset() + { + if(roi.empty()) { return; } // no ROI to reset + + region_of_solution(); // since we are using original vector + + //restore the current positions to be the original positions + BOOST_FOREACH(vertex_descriptor vd, roi_vertices()) + { + put(vertex_point_map, vd, original[ros_id(vd)]); + solution[ros_id(vd)]=original[ros_id(vd)]; + } + + // also set rotation matrix to identity + std::fill(rot_mtr.begin(), rot_mtr.end(), + Closest_rotation_traits().identity_matrix()); + } + + /** + * Sets the initial positions of the vertices from the region-of-interest to the current positions. Calling this function has the same effect as creating + * a new deformation object with the current deformed halfedge-graph, keeping the region-of-interest and the set of control vertices. + * \note if the region-of-interest or the set of control vertices have been modified since the last call to `preprocess()`, + * it will be called prior to the overwrite. + * + * \cgalAdvancedBegin + * This function might have a non-negligible effect on the result. + * The Laplacian matrix of the free vertices and the optimal rotations + * are computed using the original positions of the points + * associated to the vertices. Thus, if a deformed version of the surface mesh + * is used as reference, the surface mesh properties the algorithm + * tries to preserve are those of an altered version (which are already + * degraded). + * \cgalAdvancedEnd + */ + void overwrite_initial_geometry() + { + if(roi.empty()) { return; } // no ROI to overwrite + + region_of_solution(); // the roi should be preprocessed since we are using original_position vec + + BOOST_FOREACH(vertex_descriptor vd, roi_vertices()) + { + original[ros_id(vd)] = get(vertex_point_map, vd); + } + + // now I need to compute weights for halfedges incident to roi vertices + std::vector is_weight_computed(2*num_edges(m_halfedge_graph), false); + BOOST_FOREACH(vertex_descriptor vd, roi_vertices()) + { + in_edge_iterator e, e_end; + for (cpp11::tie(e,e_end) = in_edges(vd, m_halfedge_graph); e != e_end; e++) + { + halfedge_descriptor he = halfedge(*e, m_halfedge_graph); + std::size_t id_e = id(he); + if(is_weight_computed[id_e]) { continue; } + + hedge_weight[id_e] = weight_calculator(he, m_halfedge_graph, vertex_point_map); + is_weight_computed[id_e] = true; + + halfedge_descriptor e_opp = opposite(he, m_halfedge_graph); + std::size_t id_e_opp = id(e_opp); + + hedge_weight[id_e_opp] = weight_calculator(e_opp, m_halfedge_graph, vertex_point_map); + is_weight_computed[id_e_opp] = true; + } + } + + // also set rotation matrix to identity + std::fill(rot_mtr.begin(), rot_mtr.end(), Closest_rotation_traits().identity_matrix()); + + need_preprocess_both(); // now we need reprocess + } + +/// @} Deformation + +/// \name Utilities +/// @{ + + /** + * Gets the default number of iterations (5) or the value passed to the function `set_iterations()` + */ + unsigned int iterations() + { return m_iterations; } + + /** + * Gets the default tolerance parameter (1e-4) or the value passed to the function `set_tolerance()` + */ + double tolerance() + { return m_tolerance; } + + /** + * Sets the maximum number of iterations ran by `deform()` + */ + void set_iterations(unsigned int iterations) + { this->m_iterations = iterations; } + + /// @brief Sets the tolerance of the convergence used in `deform()`. + /// If `tolerance==0`, no energy based termination criteria is used (preventing to do the energy computation at each iteration step) + /// + /// `tolerance >` \f$|\mathrm{energy}(m_i) - \mathrm{energy}(m_{i-1})| / \mathrm{energy}(m_i)\f$ will be used as a termination criterium. + void set_tolerance(double tolerance) + { this->m_tolerance = tolerance; } + + /** + * Returns the range of vertices in the region-of-interest. + */ + Roi_vertex_range roi_vertices() const + { + return roi; + } + + /** + * Tests whether a vertex is inside the region-of-interest. + * @param vd the query vertex + * @return `true` if `vd` has been inserted to (and not erased from) the region-of-interest. + */ + bool is_roi_vertex(vertex_descriptor vd) const + { return is_roi_map[id(vd)]; } + + /** + * Tests whether a vertex is a control vertex. + * @param vd the query vertex + * @return `true` if `vd` has been inserted to (and not erased from) the set of control vertices. + */ + bool is_control_vertex(vertex_descriptor vd) const + { return is_ctrl_map[id(vd)]; } + + /** + * Provides access to the halfedge graph being deformed + */ + const Halfedge_graph& halfedge_graph() const + { return m_halfedge_graph; } + +/// @} Utilities + + +private: + + /// Assigns id to one ring neighbor of vd, and also push them into push_vector + void assign_ros_id_to_one_ring(vertex_descriptor vd, + std::size_t& next_id, + std::vector& push_vector) + { + in_edge_iterator e, e_end; + for (cpp11::tie(e,e_end) = in_edges(vd, m_halfedge_graph); e != e_end; e++) + { + vertex_descriptor vt = source(*e, m_halfedge_graph); + if(ros_id(vt) == (std::numeric_limits::max)()) // neighboring vertex which is outside of roi and not visited previously (i.e. need an id) + { + ros_id(vt) = next_id++; + push_vector.push_back(vt); + } + } + } + + /// Find region of solution, including roi and hard constraints, which is the 1-ring vertices out roi + /// Contains four parts: + /// - if there is any vertex which is no longer roi, set its position back to original position + /// - assign a ros id to vertices inside ros + ros-boundary + /// - reinitialize rotation matrices, if a vertex is previously ros, use its previous matrix, otherwise set zero + /// - reinitialize original, and solution, + /// + if a vertex is previously roi, then use its original position in old_origional, else use point(). + /// In both case we are using "original position" of the vertex. + /// + same for solution (it is required to prevent jumping effects) + void region_of_solution() + { + if(!need_preprocess_region_of_solution) { return; } + need_preprocess_region_of_solution = false; + + std::vector old_ros_id_map = ros_id_map; + std::vector old_rot_mtr = rot_mtr; + std::vector old_solution = solution; + std::vector old_original = original; + + // any vertices which are no longer ROI, should be assigned to their original position, so that: + // IF a vertex is ROI (actually if its ros + boundary) previously (when previous region_of_solution() is called) + // we have its original position in old_original + // ELSE + // we have its original position in vertex->point() + // (current ros is actually old ros - we did not change it yet) + for(typename std::vector::iterator it = ros.begin(); it != ros.end(); ++it) + { + if(!is_roi_vertex(*it)) { + put(vertex_point_map, *it, old_original[ old_ros_id_map[id(*it)] ]); + } + } + + //////////////////////////////////////////////////////////////// + // assign id to vertices inside: roi, boundary of roi (roi + boundary of roi = ros), + // and boundary of ros + // keep in mind that id order does not have to be compatible with ros order + ros.clear(); // clear ros + ros.insert(ros.end(), roi.begin(), roi.end()); + + ros_id_map.assign(num_vertices(m_halfedge_graph), (std::numeric_limits::max)()); // use max as not assigned mark + + for(std::size_t i = 0; i < roi.size(); i++) // assign id to all roi vertices + { ros_id(roi[i]) = i; } + + // now assign an id to vertices on boundary of roi + std::size_t next_ros_index = roi.size(); + for(std::size_t i = 0; i < roi.size(); i++) + { assign_ros_id_to_one_ring(roi[i], next_ros_index, ros); } + + std::vector outside_ros; + // boundary of ros also must have ids because in CR calculation, + // one-ring neighbor of ROS vertices are reached. + for(std::size_t i = roi.size(); i < ros.size(); i++) + { assign_ros_id_to_one_ring(ros[i], next_ros_index, outside_ros); } + //////////////////////////////////////////////////////////////// + + // initialize the rotation matrices (size: ros) + rot_mtr.resize(ros.size()); + for(std::size_t i = 0; i < rot_mtr.size(); i++) + { + std::size_t v_ros_id = ros_id(ros[i]); + std::size_t v_id = id(ros[i]); + + // any vertex which is previously ROS has a rotation matrix + // use that matrix to prevent jumping effects + if(old_ros_id_map[v_id] != (std::numeric_limits::max)() + && old_ros_id_map[v_id] < old_rot_mtr.size()) { + // && boundary of ros vertices also have ids so check whether it is ros + rot_mtr[v_ros_id] = old_rot_mtr[ old_ros_id_map[v_id] ]; + } + else { + rot_mtr[v_ros_id] = Closest_rotation_traits().identity_matrix(); + } + } + + // initialize solution and original (size: ros + boundary_of_ros) + + // for simplifying coding effort, I also put boundary of ros into solution and original + // because boundary of ros vertices are reached in optimal_rotations() and energy() + solution.resize(ros.size() + outside_ros.size()); + original.resize(ros.size() + outside_ros.size()); + + for(std::size_t i = 0; i < ros.size(); i++) + { + std::size_t v_ros_id = ros_id(ros[i]); + std::size_t v_id = id(ros[i]); + + if(is_roi_vertex(ros[i]) && old_ros_id_map[v_id] != (std::numeric_limits::max)()) { + // if it is currently roi and previously ros + boundary + // (actually I just need to assign old's to new's if a vertex is currently and previously ROI + // but no harm on assigning if its also previously ros + boundary because + // those(old_original & old_solution) will be equal to original position) + original[v_ros_id] = old_original[old_ros_id_map[v_id]]; + solution[v_ros_id] = old_solution[old_ros_id_map[v_id]]; + } + else { + solution[v_ros_id] = get(vertex_point_map, ros[i]); + original[v_ros_id] = get(vertex_point_map, ros[i]); + } + } + + for(std::size_t i = 0; i < outside_ros.size(); ++i) + { + std::size_t v_ros_id = ros_id(outside_ros[i]); + original[v_ros_id] = get(vertex_point_map, outside_ros[i]); + solution[v_ros_id] = get(vertex_point_map, outside_ros[i]); + } + +#ifdef CGAL_DEFORM_MESH_USE_EXPERIMENTAL_SCALE + scales.resize(ros.size()); + std::fill(scales.begin(), scales.end(), 1.0); +#endif + } + + /// Assemble Laplacian matrix A of linear system A*X=B + void assemble_laplacian_and_factorize() + { + if(TAG == SPOKES_AND_RIMS) + { + assemble_laplacian_and_factorize_spokes_and_rims(); + } + else + { + assemble_laplacian_and_factorize_arap(); + } + } + /// Construct matrix that corresponds to left-hand side of eq:lap_ber in user manual + /// Also constraints are integrated as eq:lap_energy_system in user manual + void assemble_laplacian_and_factorize_arap() + { + if(!need_preprocess_factorization) { return; } + need_preprocess_factorization = false; + + typename Sparse_linear_solver::Matrix A(ros.size()); + + /// assign cotangent Laplacian to ros vertices + for(std::size_t k = 0; k < ros.size(); k++) + { + vertex_descriptor vi = ros[k]; + std::size_t vi_id = ros_id(vi); + if ( is_roi_vertex(vi) && !is_control_vertex(vi) ) // vertices of ( roi - ctrl ) + { + double diagonal = 0; + in_edge_iterator e, e_end; + for (cpp11::tie(e,e_end) = in_edges(vi, m_halfedge_graph); e != e_end; e++) + { + halfedge_descriptor he = halfedge(*e, m_halfedge_graph); + vertex_descriptor vj = source(he, m_halfedge_graph); + double wij = hedge_weight[id(he)]; // edge(pi - pj) + double wji = hedge_weight[id(opposite(he, m_halfedge_graph))]; // edge(pi - pj) + double total_weight = wij + wji; + + A.set_coef(vi_id, ros_id(vj), -total_weight, true); // off-diagonal coefficient + diagonal += total_weight; + } + // diagonal coefficient + A.set_coef(vi_id, vi_id, diagonal, true); + } + else + { + A.set_coef(vi_id, vi_id, 1.0, true); + } + } + + // now factorize + double D; + last_preprocess_successful = m_solver.factor(A, D); + CGAL_warning(last_preprocess_successful); + } + /// Construct matrix that corresponds to left-hand side of eq:lap_ber_rims in user manual + /// Also constraints are integrated as eq:lap_energy_system in user manual + void assemble_laplacian_and_factorize_spokes_and_rims() + { + if(!need_preprocess_factorization) { return; } + need_preprocess_factorization = false; + + typename Sparse_linear_solver::Matrix A(ros.size()); + + /// assign cotangent Laplacian to ros vertices + for(std::size_t k = 0; k < ros.size(); k++) + { + vertex_descriptor vi = ros[k]; + std::size_t vi_id = ros_id(vi); + if ( is_roi_vertex(vi) && !is_control_vertex(vi) ) // vertices of ( roi - ctrl ): free vertices + { + double diagonal = 0; + out_edge_iterator e, e_end; + for (cpp11::tie(e,e_end) = out_edges(vi, m_halfedge_graph); e != e_end; e++) + { + halfedge_descriptor he = halfedge(*e, m_halfedge_graph); + double total_weight = 0; + // an edge contribute to energy only if it is part of an incident triangle + // (i.e it should not be a border edge) + if(!is_border(he, m_halfedge_graph)) + { + double wji = hedge_weight[id(he)]; // edge(pj - pi) + total_weight += wji; + } + + halfedge_descriptor opp = opposite(he, m_halfedge_graph); + if(!is_border(opp, m_halfedge_graph)) + { + double wij = hedge_weight[id(opp)]; // edge(pi - pj) + total_weight += wij; + } + + // place coefficient to matrix + vertex_descriptor vj = target(he, m_halfedge_graph); + A.set_coef(vi_id, ros_id(vj), -total_weight, true); // off-diagonal coefficient + diagonal += total_weight; + } + // diagonal coefficient + A.set_coef(vi_id, vi_id, diagonal, true); + } + else // constrained vertex + { + A.set_coef(vi_id, vi_id, 1.0, true); + } + } + + // now factorize + double D; + last_preprocess_successful = m_solver.factor(A, D); + CGAL_warning(last_preprocess_successful); + } + + /// Local step of iterations, computing optimal rotation matrices + void optimal_rotations() + { + if(TAG == SPOKES_AND_RIMS) + { + optimal_rotations_spokes_and_rims(); + } + else + { + optimal_rotations_arap(); + } + } + void optimal_rotations_arap() + { + Closest_rotation_traits cr_traits; + CR_matrix cov = cr_traits.zero_matrix(); + + // only accumulate ros vertices + for ( std::size_t k = 0; k < ros.size(); k++ ) + { + vertex_descriptor vi = ros[k]; + std::size_t vi_id = ros_id(vi); + // compute covariance matrix (user manual eq:cov_matrix) + cov = cr_traits.zero_matrix(); + + in_edge_iterator e, e_end; + +#ifdef CGAL_DEFORM_MESH_USE_EXPERIMENTAL_SR_ARAP + cpp11::tie(e,e_end) = in_edges(vi, m_halfedge_graph); + double ne_i=std::distance(e,e_end); +#endif + for (cpp11::tie(e,e_end) = in_edges(vi, m_halfedge_graph); e != e_end; e++) + { + halfedge_descriptor he=halfedge(*e, m_halfedge_graph); + vertex_descriptor vj = source(he, m_halfedge_graph); + std::size_t vj_id = ros_id(vj); + + const CR_vector& pij = sub_to_CR_vector(original[vi_id], original[vj_id]); + const CR_vector& qij = sub_to_CR_vector(solution[vi_id], solution[vj_id]); + double wij = hedge_weight[id(he)]; + + cr_traits.add_scalar_t_vector_t_vector_transpose(cov, wij, pij, qij); // cov += wij * (pij * qij) +#ifdef CGAL_DEFORM_MESH_USE_EXPERIMENTAL_SR_ARAP + // add neighbor rotation + cov += m_sr_arap_alpha * rot_mtr[vj_id].transpose() / ne_i; +#endif + + } + + cr_traits.compute_close_rotation(cov, rot_mtr[vi_id]); + } + } + void optimal_rotations_spokes_and_rims() + { + Closest_rotation_traits cr_traits; + CR_matrix cov =cr_traits.zero_matrix(); + + // only accumulate ros vertices + for ( std::size_t k = 0; k < ros.size(); k++ ) + { + vertex_descriptor vi = ros[k]; + std::size_t vi_id = ros_id(vi); + // compute covariance matrix + cov = cr_traits.zero_matrix(); + + //iterate through all triangles + out_edge_iterator e, e_end; + for (cpp11::tie(e,e_end) = out_edges(vi, m_halfedge_graph); e != e_end; e++) + { + halfedge_descriptor he = halfedge(*e, m_halfedge_graph); + if(is_border(he, m_halfedge_graph)) { continue; } // no facet + // iterate edges around facet + halfedge_descriptor hedge_around_facet = he; + do + { + vertex_descriptor v1 = target(hedge_around_facet, m_halfedge_graph); + vertex_descriptor v2 = source(hedge_around_facet, m_halfedge_graph); + + std::size_t v1_id = ros_id(v1); std::size_t v2_id = ros_id(v2); + + const CR_vector& p12 = sub_to_CR_vector(original[v1_id], original[v2_id]); + const CR_vector& q12 = sub_to_CR_vector(solution[v1_id], solution[v2_id]); + double w12 = hedge_weight[id(hedge_around_facet)]; + + cr_traits.add_scalar_t_vector_t_vector_transpose(cov, w12, p12, q12); // cov += w12 * (p12 * q12); + + } while( (hedge_around_facet = next(hedge_around_facet, m_halfedge_graph)) != he); + } + + cr_traits.compute_close_rotation(cov, rot_mtr[vi_id]); + } + } + +#ifdef CGAL_DEFORM_MESH_USE_EXPERIMENTAL_SCALE + void optimal_scales() + { + for ( std::size_t k = 0; k < ros.size(); k++ ) + { + vertex_descriptor vi = ros[k]; + std::size_t vi_id = ros_id(vi); + // compute covariance matrix (user manual eq:cov_matrix) + double eT_eR = 0, eRT_eR = 0; + + in_edge_iterator e, e_end; + for (cpp11::tie(e,e_end) = in_edges(vi, m_halfedge_graph); e != e_end; e++) + { + halfedge_descriptor he = *e; + vertex_descriptor vj = source(he, m_halfedge_graph); + std::size_t vj_id = ros_id(vj); + + const CR_vector& pij = sub_to_CR_vector(original[vi_id], original[vj_id]); + const CR_vector& qij = sub_to_CR_vector(solution[vi_id], solution[vj_id]); + + double wij = hedge_weight[id(he)]; + + const CR_vector& pRij = rot_mtr[vi_id] * pij; + eRT_eR += pRij[0]*pRij[0] + pRij[1]*pRij[1] + pRij[2]*pRij[2]; + eT_eR += qij[0]*pRij[0] + qij[1]*pRij[1] + qij[2]*pRij[2]; + } + + scales[vi_id] = eT_eR / eRT_eR; + } + } +#endif + + /// Global step of iterations, updating solution + void update_solution() + { + if(TAG == SPOKES_AND_RIMS) + { + update_solution_spokes_and_rims(); + } + else + { + update_solution_arap(); + } + } + /// calculate right-hand side of eq:lap_ber in user manual and solve the system + void update_solution_arap() + { + typename Sparse_linear_solver::Vector X(ros.size()), Bx(ros.size()); + typename Sparse_linear_solver::Vector Y(ros.size()), By(ros.size()); + typename Sparse_linear_solver::Vector Z(ros.size()), Bz(ros.size()); + + Closest_rotation_traits cr_traits; + + // assemble right columns of linear system + for ( std::size_t k = 0; k < ros.size(); k++ ) + { + vertex_descriptor vi = ros[k]; + std::size_t vi_id = ros_id(vi); + + if ( is_roi_vertex(vi) && !is_control_vertex(vi) ) + {// free vertices + // sum of right-hand side of eq:lap_ber in user manual + CR_vector xyz = cr_traits.vector(0, 0, 0); + + in_edge_iterator e, e_end; + for (cpp11::tie(e,e_end) = in_edges(vi, m_halfedge_graph); e != e_end; e++) + { + halfedge_descriptor he = halfedge(*e, m_halfedge_graph); + vertex_descriptor vj = source(he, m_halfedge_graph); + std::size_t vj_id = ros_id(vj); + + const CR_vector& pij = sub_to_CR_vector(original[vi_id], original[vj_id]); + + double wij = hedge_weight[id(he)]; + double wji = hedge_weight[id(opposite(he, m_halfedge_graph))]; +#ifndef CGAL_DEFORM_MESH_USE_EXPERIMENTAL_SCALE + cr_traits.add__scalar_t_matrix_p_scalar_t_matrix__t_vector(xyz, wij, rot_mtr[vi_id], wji, rot_mtr[vj_id], pij); +#else + cr_traits.add__scalar_t_matrix_p_scalar_t_matrix__t_vector(xyz, wij * scales[vi_id], rot_mtr[vi_id], + wji * scales[vj_id], rot_mtr[vj_id], pij); +#endif + // corresponds xyz += (wij*rot_mtr[vi_id] + wji*rot_mtr[vj_id]) * pij + } + Bx[vi_id] = cr_traits.vector_coordinate(xyz, 0); + By[vi_id] = cr_traits.vector_coordinate(xyz, 1); + Bz[vi_id] = cr_traits.vector_coordinate(xyz, 2); + } + else + {// constrained vertex + Bx[vi_id] = solution[vi_id][0]; By[vi_id] = solution[vi_id][1]; Bz[vi_id] = solution[vi_id][2]; + } + } + + // solve "A*X = B". + bool is_all_solved = m_solver.linear_solver(Bx, X) && m_solver.linear_solver(By, Y) && m_solver.linear_solver(Bz, Z); + if(!is_all_solved) { + CGAL_warning(false); + return; + } + // copy to solution + for (std::size_t i = 0; i < ros.size(); i++) + { + std::size_t v_id = ros_id(ros[i]); + Point p(X[v_id], Y[v_id], Z[v_id]); + solution[v_id] = p; + } + } + /// calculate right-hand side of eq:lap_ber_rims in user manual and solve the system + void update_solution_spokes_and_rims() + { + typename Sparse_linear_solver::Vector X(ros.size()), Bx(ros.size()); + typename Sparse_linear_solver::Vector Y(ros.size()), By(ros.size()); + typename Sparse_linear_solver::Vector Z(ros.size()), Bz(ros.size()); + + Closest_rotation_traits cr_traits; + + // assemble right columns of linear system + for ( std::size_t k = 0; k < ros.size(); k++ ) + { + vertex_descriptor vi = ros[k]; + std::size_t vi_id = ros_id(vi); + + if ( is_roi_vertex(vi) && !is_control_vertex(vi) ) + {// free vertices + // sum of right-hand side of eq:lap_ber_rims in user manual + CR_vector xyz = cr_traits.vector(0, 0, 0); + + out_edge_iterator e, e_end; + for (cpp11::tie(e,e_end) = out_edges(vi, m_halfedge_graph); e != e_end; e++) + { + halfedge_descriptor he = halfedge(*e, m_halfedge_graph); + vertex_descriptor vj = target(he, m_halfedge_graph); + std::size_t vj_id = ros_id(vj); + + const CR_vector& pij = sub_to_CR_vector(original[vi_id], original[vj_id]); + + if(!is_border(he, m_halfedge_graph)) + { + vertex_descriptor vn = target(next(he, m_halfedge_graph), m_halfedge_graph); // opp vertex of e_ij + double wji = hedge_weight[id(he)] / 3.0; // edge(pj - pi) + cr_traits.add_scalar_t_matrix_sum_t_vector(xyz, wji, rot_mtr[vi_id], rot_mtr[vj_id], rot_mtr[ros_id(vn)], pij); + // corresponds xyz += wji*(rot_mtr[vi_id] + rot_mtr[vj_id] + rot_mtr[ros_id(vn)])*pij; + } + + halfedge_descriptor opp = opposite(he, m_halfedge_graph); + if(!is_border(opp, m_halfedge_graph)) + { + vertex_descriptor vm = target(next(opp, m_halfedge_graph), m_halfedge_graph); // other opp vertex of e_ij + double wij = hedge_weight[id(opp)] / 3.0; // edge(pi - pj) + cr_traits.add_scalar_t_matrix_sum_t_vector(xyz, wij, rot_mtr[vi_id], rot_mtr[vj_id], rot_mtr[ros_id(vm)], pij); + // corresponds xyz += wij * ( rot_mtr[vi_id] + rot_mtr[vj_id] + rot_mtr[ros_id(vm)] ) * pij + } + } + Bx[vi_id] = cr_traits.vector_coordinate(xyz, 0); + By[vi_id] = cr_traits.vector_coordinate(xyz, 1); + Bz[vi_id] = cr_traits.vector_coordinate(xyz, 2); + } + else + {// constrained vertices + Bx[vi_id] = solution[vi_id][0]; By[vi_id] = solution[vi_id][1]; Bz[vi_id] = solution[vi_id][2]; + } + } + // solve "A*X = B". + bool is_all_solved = m_solver.linear_solver(Bx, X) && m_solver.linear_solver(By, Y) && m_solver.linear_solver(Bz, Z); + if(!is_all_solved) { + CGAL_warning(false); + return; + } + + // copy to solution + for (std::size_t i = 0; i < ros.size(); i++) + { + std::size_t v_id = ros_id(ros[i]); + Point p(X[v_id], Y[v_id], Z[v_id]); + solution[v_id] = p; + } + } + + /// Assign solution to target surface mesh + void assign_solution() + { + for(std::size_t i = 0; i < ros.size(); ++i){ + std::size_t v_id = ros_id(ros[i]); + if(is_roi_vertex(ros[i])) + { + put(vertex_point_map, ros[i], solution[v_id]); + } + } + } + + /// Compute modeling energy + double energy() const + { + if(TAG == SPOKES_AND_RIMS) + { + return energy_spokes_and_rims(); + } + else + { + return energy_arap(); + return 0; + } + } + double energy_arap() const + { + Closest_rotation_traits cr_traits; + + double sum_of_energy = 0; + // only accumulate ros vertices + for( std::size_t k = 0; k < ros.size(); k++ ) + { + vertex_descriptor vi = ros[k]; + std::size_t vi_id = ros_id(vi); + + in_edge_iterator e, e_end; + for (cpp11::tie(e,e_end) = in_edges(vi, m_halfedge_graph); e != e_end; e++) + { + halfedge_descriptor he = halfedge(*e, m_halfedge_graph); + vertex_descriptor vj = source(he, m_halfedge_graph); + std::size_t vj_id = ros_id(vj); + + const CR_vector& pij = sub_to_CR_vector(original[vi_id], original[vj_id]); + const CR_vector& qij = sub_to_CR_vector(solution[vi_id], solution[vj_id]); + + double wij = hedge_weight[id(he)]; + + sum_of_energy += wij * cr_traits.squared_norm_vector_scalar_vector_subs(qij, rot_mtr[vi_id], pij); + // sum_of_energy += wij * ( qij - rot_mtr[vi_id]*pij )^2 + } + } + return sum_of_energy; + } + double energy_spokes_and_rims() const + { + Closest_rotation_traits cr_traits; + + double sum_of_energy = 0; + // only accumulate ros vertices + for( std::size_t k = 0; k < ros.size(); k++ ) + { + vertex_descriptor vi = ros[k]; + std::size_t vi_id = ros_id(vi); + //iterate through all triangles + out_edge_iterator e, e_end; + for (cpp11::tie(e,e_end) = out_edges(vi, m_halfedge_graph); e != e_end; e++) + { + halfedge_descriptor he = halfedge(*e, m_halfedge_graph); + if(is_border(he, m_halfedge_graph)) { continue; } // no facet + // iterate edges around facet + halfedge_descriptor hedge_around_facet = he; + do + { + vertex_descriptor v1 = target(hedge_around_facet, m_halfedge_graph); + vertex_descriptor v2 = source(hedge_around_facet, m_halfedge_graph); + std::size_t v1_id = ros_id(v1); std::size_t v2_id = ros_id(v2); + + const CR_vector& p12 = sub_to_CR_vector(original[v1_id], original[v2_id]); + const CR_vector& q12 = sub_to_CR_vector(solution[v1_id], solution[v2_id]); + double w12 = hedge_weight[id(hedge_around_facet)]; + + sum_of_energy += w12 * cr_traits.squared_norm_vector_scalar_vector_subs(q12, rot_mtr[vi_id], p12); + // sum_of_energy += w12 * ( q12 - rot_mtr[vi_id]*p12 )^2 + + } while( (hedge_around_facet = next(hedge_around_facet, m_halfedge_graph)) != he); + } + } + return sum_of_energy; + } + + void need_preprocess_both() + { + need_preprocess_factorization = true; + need_preprocess_region_of_solution = true; + } + + /// p1 - p2, return CR_vector + CR_vector sub_to_CR_vector(const Point& p1, const Point& p2) const + { + return Closest_rotation_traits().vector(p1[0] - p2[0], p1[1] - p2[1], p1[2] - p2[2]); + } + + template + Point add_to_point(const Point& p, const Vect& v) { + return Point(p[0] + v[0], p[1] + v[1], p[2] + v[2]); + } + + template + Vect sub_to_vect(const Point& p, const Vect& v) { + return Vect(p[0] - v[0], p[1] - v[1], p[2] - v[2]); + } + + /// shorthand of get(vertex_index_map, v) + std::size_t id(vertex_descriptor vd) const + { return get(vertex_index_map, vd); } + + std::size_t& ros_id(vertex_descriptor vd) + { return ros_id_map[id(vd)]; } + std::size_t ros_id(vertex_descriptor vd) const + { return ros_id_map[id(vd)]; } + + /// shorthand of get(hedge_index_map, e) + std::size_t id(halfedge_descriptor e) const + { + return get(hedge_index_map, e); + } +}; +} //namespace CGAL +#endif // CGAL_SURFACE_MESH_DEFORMATION_H diff -Nru cgal-4.4/include/CGAL/Surface_mesh_simplification/Detail/Common.h cgal-4.5/include/CGAL/Surface_mesh_simplification/Detail/Common.h --- cgal-4.4/include/CGAL/Surface_mesh_simplification/Detail/Common.h 2014-02-15 20:00:24.000000000 +0000 +++ cgal-4.5/include/CGAL/Surface_mesh_simplification/Detail/Common.h 2014-08-29 13:58:17.000000000 +0000 @@ -40,7 +40,6 @@ #include #include -#include namespace CGAL { diff -Nru cgal-4.4/include/CGAL/Surface_mesh_simplification/Detail/Edge_collapse.h cgal-4.5/include/CGAL/Surface_mesh_simplification/Detail/Edge_collapse.h --- cgal-4.4/include/CGAL/Surface_mesh_simplification/Detail/Edge_collapse.h 2014-02-15 20:00:24.000000000 +0000 +++ cgal-4.5/include/CGAL/Surface_mesh_simplification/Detail/Edge_collapse.h 2014-08-29 13:58:17.000000000 +0000 @@ -21,6 +21,7 @@ #include #include +#include namespace CGAL { @@ -33,8 +34,8 @@ template Profile ; + typedef Edge_profile Profile ; typedef boost::graph_traits GraphTraits ; typedef boost::graph_traits ConstGraphTraits ; - typedef halfedge_graph_traits HalfedgeGraphTraits ; typedef typename GraphTraits::vertex_descriptor vertex_descriptor ; typedef typename GraphTraits::vertex_iterator vertex_iterator ; - typedef typename GraphTraits::edge_descriptor edge_descriptor ; - typedef typename GraphTraits::edge_iterator edge_iterator ; - typedef typename GraphTraits::out_edge_iterator out_edge_iterator ; - typedef typename GraphTraits::in_edge_iterator in_edge_iterator ; + typedef typename GraphTraits::halfedge_descriptor halfedge_descriptor ; + typedef typename GraphTraits::halfedge_iterator halfedge_iterator ; + typedef CGAL::Halfedge_around_source_iterator out_edge_iterator ; + typedef CGAL::Halfedge_around_target_iterator in_edge_iterator ; typedef typename GraphTraits::traversal_category traversal_category ; typedef typename GraphTraits::edges_size_type size_type ; - typedef typename ConstGraphTraits::vertex_descriptor const_vertex_descriptor ; - typedef typename ConstGraphTraits::edge_descriptor const_edge_descriptor ; - typedef typename ConstGraphTraits::in_edge_iterator const_in_edge_iterator ; + typedef typename GraphTraits::edge_iterator edge_iterator ; + typedef VertexPointMap Vertex_point_pmap; + typedef typename boost::property_traits::value_type Point; + typedef typename Kernel_traits::Kernel Traits; - typedef typename HalfedgeGraphTraits::undirected_edge_iterator undirected_edge_iterator ; - typedef typename HalfedgeGraphTraits::Point Point ; - - typedef typename GetCost ::result_type Cost_type ; - typedef typename GetPlacement::result_type Placement_type ; - - typedef typename Kernel_traits::Kernel Kernel ; - - typedef typename Kernel::Equal_3 Equal_3 ; + typedef typename Traits::Equal_3 Equal_3 ; - typedef typename Kernel::Vector_3 Vector ; - typedef typename Kernel::FT FT ; + typedef typename Traits::Vector_3 Vector ; + typedef typename Traits::FT FT ; + + typedef optional Cost_type ; + typedef optional Placement_type ; struct Compare_id { @@ -94,9 +90,9 @@ Compare_id( Self const* aAlgorithm ) : mAlgorithm(aAlgorithm) {} - bool operator() ( edge_descriptor const& a, edge_descriptor const& b ) const + bool operator() ( halfedge_descriptor const& a, halfedge_descriptor const& b ) const { - return mAlgorithm->get_directed_edge_id(a) < mAlgorithm->get_directed_edge_id(b); + return mAlgorithm->get_halfedge_id(a) < mAlgorithm->get_halfedge_id(b); } Self const* mAlgorithm ; @@ -108,7 +104,7 @@ Compare_cost( Self const* aAlgorithm ) : mAlgorithm(aAlgorithm) {} - bool operator() ( edge_descriptor const& a, edge_descriptor const& b ) const + bool operator() ( halfedge_descriptor const& a, halfedge_descriptor const& b ) const { // NOTE: A cost is an optional<> value. // Absent optionals are ordered first; that is, "none < T" and "T > none" for any defined T != none. @@ -119,27 +115,27 @@ Self const* mAlgorithm ; } ; - struct Undirected_edge_id : boost::put_get_helper + struct edge_id : boost::put_get_helper { typedef boost::readable_property_map_tag category; typedef size_type value_type; typedef size_type reference; - typedef edge_descriptor key_type; + typedef halfedge_descriptor key_type; - Undirected_edge_id() : mAlgorithm(0) {} + edge_id() : mAlgorithm(0) {} - Undirected_edge_id( Self const* aAlgorithm ) : mAlgorithm(aAlgorithm) {} + edge_id( Self const* aAlgorithm ) : mAlgorithm(aAlgorithm) {} - size_type operator[] ( edge_descriptor const& e ) const { return mAlgorithm->get_undirected_edge_id(e); } + size_type operator[] ( halfedge_descriptor const& e ) const { return mAlgorithm->get_edge_id(e); } Self const* mAlgorithm ; } ; - typedef Modifiable_priority_queue PQ ; + typedef Modifiable_priority_queue PQ ; typedef typename PQ::handle pq_handle ; - // An Edge_data is associated with EVERY _undirected_ edge in the mesh (collapsable or not). + // An Edge_data is associated with EVERY _ edge in the mesh (collapsable or not). // It relates the edge with the PQ-handle needed to update the priority queue // It also relates the edge with a policy-based cache class Edge_data @@ -173,8 +169,8 @@ EdgeCollapse( ECM& aSurface , ShouldStop const& aShouldStop , VertexIndexMap const& aVertex_index_map + , VertexPointMap const& aVertex_point_map , EdgeIndexMap const& aEdge_index_map - , EdgeIsBorderMap const& aEdge_is_border_map , EdgeIsConstrainedMap const& aEdge_is_constrained_map , GetCost const& aGetCost , GetPlacement const& aGetPlacement @@ -188,70 +184,70 @@ void Collect(); void Loop(); bool Is_collapse_topologically_valid( Profile const& aProfile ) ; - bool Is_tetrahedron( edge_descriptor const& h1 ) ; - bool Is_open_triangle( edge_descriptor const& h1 ) ; + bool Is_tetrahedron( halfedge_descriptor const& h1 ) ; + bool Is_open_triangle( halfedge_descriptor const& h1 ) ; bool Is_collapse_geometrically_valid( Profile const& aProfile, Placement_type aPlacement ) ; void Collapse( Profile const& aProfile, Placement_type aPlacement ) ; void Update_neighbors( vertex_descriptor const& aKeptV ) ; - Profile create_profile ( edge_descriptor const& aEdge ) + Profile create_profile ( halfedge_descriptor const& aEdge ) { - return Profile(aEdge,mSurface,Vertex_index_map,Edge_index_map,Edge_is_border_map); + return Profile(aEdge,mSurface,Vertex_index_map,Vertex_point_map,Edge_index_map, m_has_border); } - size_type get_directed_edge_id ( const_edge_descriptor const& aEdge ) const { return Edge_index_map[aEdge]; } - size_type get_undirected_edge_id ( const_edge_descriptor const& aEdge ) const { return get_directed_edge_id(aEdge) / 2 ; } + size_type get_halfedge_id ( halfedge_descriptor const& aEdge ) const { return Edge_index_map[aEdge]; } + size_type get_edge_id ( halfedge_descriptor const& aEdge ) const { return get_halfedge_id(aEdge) / 2 ; } - bool is_primary_edge ( const_edge_descriptor const& aEdge ) const { return ( get_directed_edge_id(aEdge) % 2 ) == 0 ; } + bool is_primary_edge ( halfedge_descriptor const& aEdge ) const { return ( get_halfedge_id(aEdge) % 2 ) == 0 ; } - edge_descriptor primary_edge ( edge_descriptor const& aEdge ) + halfedge_descriptor primary_edge ( halfedge_descriptor const& aEdge ) { - return is_primary_edge(aEdge) ? aEdge : opposite_edge(aEdge,mSurface) ; + return is_primary_edge(aEdge) ? aEdge : opposite(aEdge,mSurface) ; } - bool is_border ( const_edge_descriptor const& aEdge ) const { return Edge_is_border_map[aEdge] ; } + bool is_border ( halfedge_descriptor const& aEdge ) const { return face(aEdge,mSurface) == boost::graph_traits::null_face() ; } - bool is_constrained( const_edge_descriptor const& aEdge ) const { return get(Edge_is_constrained_map,aEdge); } - bool is_constrained( const_vertex_descriptor const& aVertex ) const; + bool is_constrained( halfedge_descriptor const& aEdge ) const { return get(Edge_is_constrained_map,edge(aEdge,mSurface)); } + bool is_constrained( vertex_descriptor const& aVertex ) const; - bool is_border_or_constrained( const_edge_descriptor const& aEdge ) const { return Edge_is_border_map[aEdge] || - Edge_is_constrained_map[aEdge];} + bool is_border_or_constrained( halfedge_descriptor const& aEdge ) const { return is_border(aEdge) || is_constrained(aEdge); } - bool is_undirected_edge_a_border ( const_edge_descriptor const& aEdge ) const + bool is_edge_a_border ( halfedge_descriptor const& aEdge ) const { - return is_border(aEdge) || is_border(opposite_edge(aEdge,mSurface)) ; + return is_border(aEdge) || is_border(opposite(aEdge,mSurface)) ; } - bool is_border ( const_vertex_descriptor const& aV ) const ; + bool is_border ( vertex_descriptor const& aV ) const ; - bool is_border_or_constrained ( const_vertex_descriptor const& aV ) const ; + bool is_border_or_constrained ( vertex_descriptor const& aV ) const ; bool are_shared_triangles_valid( Point const& p0, Point const& p1, Point const& p2, Point const& p3 ) const ; - edge_descriptor find_connection ( const_vertex_descriptor const& v0, const_vertex_descriptor const& v1 ) const ; + halfedge_descriptor find_connection ( vertex_descriptor const& v0, vertex_descriptor const& v1 ) const ; - vertex_descriptor find_exterior_link_triangle_3rd_vertex ( const_edge_descriptor const& e, const_vertex_descriptor const& v0, const_vertex_descriptor const& v1 ) const ; + vertex_descriptor find_exterior_link_triangle_3rd_vertex ( halfedge_descriptor const& e, vertex_descriptor const& v0, vertex_descriptor const& v1 ) const ; - Edge_data& get_data ( edge_descriptor const& aEdge ) const + Edge_data& get_data ( halfedge_descriptor const& aEdge ) const { CGAL_assertion( is_primary_edge(aEdge) ) ; - return mEdgeDataArray[get_undirected_edge_id(aEdge)]; + return mEdgeDataArray[get_edge_id(aEdge)]; } - Point const& get_point ( const_vertex_descriptor const& aV ) const + typename boost::property_traits::reference + get_point ( vertex_descriptor const& aV ) const { - return get(vertex_point,mSurface,aV); + return get(Vertex_point_map,aV); } - boost::tuple get_vertices( const_edge_descriptor const& aEdge ) const + boost::tuple get_vertices( halfedge_descriptor const& aEdge ) const { - const_vertex_descriptor p,q ; + vertex_descriptor p,q ; p = boost::source(aEdge,mSurface); q = boost::target(aEdge,mSurface); return boost::make_tuple(p,q); } - boost::tuple get_vertices( edge_descriptor const& aEdge ) + boost::tuple get_vertices( halfedge_descriptor const& aEdge ) { vertex_descriptor p,q ; p = boost::source(aEdge,mSurface); @@ -259,15 +255,15 @@ return boost::make_tuple(p,q); } - std::string vertex_to_string( const_vertex_descriptor const& v ) const + std::string vertex_to_string( vertex_descriptor const& v ) const { Point const& p = get_point(v); return boost::str( boost::format("[V%1%:%2%]") % get(Vertex_index_map,v) % xyz_to_string(p) ) ; } - std::string edge_to_string ( const_edge_descriptor const& aEdge ) const + std::string edge_to_string ( halfedge_descriptor const& aEdge ) const { - const_vertex_descriptor p,q ; boost::tie(p,q) = get_vertices(aEdge); + vertex_descriptor p,q ; boost::tie(p,q) = get_vertices(aEdge); return boost::str( boost::format("{E%1% %2%->%3%}%4%") % get(Edge_index_map,aEdge) % vertex_to_string(p) % vertex_to_string(q) % ( is_border(aEdge) ? " (BORDER)" : ( is_border(aEdge->opposite()) ? " (~BORDER)": "" ) ) ) ; } @@ -281,7 +277,7 @@ return Get_placement(aProfile); } - void insert_in_PQ( edge_descriptor const& aEdge, Edge_data& aData ) + void insert_in_PQ( halfedge_descriptor const& aEdge, Edge_data& aData ) { CGAL_SURF_SIMPL_TEST_assertion(is_primary_edge(aEdge)) ; CGAL_SURF_SIMPL_TEST_assertion(!aData.is_in_PQ()); @@ -293,7 +289,7 @@ CGAL_SURF_SIMPL_TEST_assertion(mPQ->contains(aEdge) ) ; } - void update_in_PQ( edge_descriptor const& aEdge, Edge_data& aData ) + void update_in_PQ( halfedge_descriptor const& aEdge, Edge_data& aData ) { CGAL_SURF_SIMPL_TEST_assertion(is_primary_edge(aEdge)) ; CGAL_SURF_SIMPL_TEST_assertion(aData.is_in_PQ()); @@ -305,7 +301,7 @@ CGAL_SURF_SIMPL_TEST_assertion(mPQ->contains(aEdge) ) ; } - void remove_from_PQ( edge_descriptor const& aEdge, Edge_data& aData ) + void remove_from_PQ( halfedge_descriptor const& aEdge, Edge_data& aData ) { CGAL_SURF_SIMPL_TEST_assertion(is_primary_edge(aEdge)) ; CGAL_SURF_SIMPL_TEST_assertion(aData.is_in_PQ()); @@ -317,9 +313,9 @@ CGAL_SURF_SIMPL_TEST_assertion(!mPQ->contains(aEdge) ) ; } - optional pop_from_PQ() + optional pop_from_PQ() { - optional rEdge = mPQ->extract_top(); + optional rEdge = mPQ->extract_top(); if ( rEdge ) { CGAL_SURF_SIMPL_TEST_assertion(is_primary_edge(*rEdge) ) ; @@ -337,20 +333,22 @@ template vertex_descriptor halfedge_collapse_bk_compatibility( - edge_descriptor const& pq, AEdgeIsConstrainedMap aEdge_is_constrained_map) + halfedge_descriptor const& pq, AEdgeIsConstrainedMap aEdge_is_constrained_map) { - return halfedge_collapse(pq, mSurface, aEdge_is_constrained_map); + return CGAL::Euler::collapse_edge(edge(pq,mSurface), mSurface, aEdge_is_constrained_map); } + template vertex_descriptor halfedge_collapse_bk_compatibility( - edge_descriptor const& pq, No_constrained_edge_map ) + halfedge_descriptor const& pq, No_constrained_edge_map ) { - return halfedge_collapse(pq, mSurface); + vertex_descriptor vd = CGAL::Euler::collapse_edge(edge(pq,mSurface), mSurface); + return vd; } - /// + /// We wrap this test to avoid penalizing runtime when no constraints are present template bool @@ -363,7 +361,7 @@ template bool is_edge_adjacent_to_a_constrained_edge( - edge_descriptor const&, No_constrained_edge_map ) + halfedge_descriptor const&, No_constrained_edge_map ) { return false; } @@ -375,13 +373,13 @@ ShouldStop const& Should_stop ; VertexIndexMap const& Vertex_index_map ; + VertexPointMap const& Vertex_point_map ; EdgeIndexMap const& Edge_index_map ; - EdgeIsBorderMap const& Edge_is_border_map; EdgeIsConstrainedMap const& Edge_is_constrained_map; GetCost const& Get_cost ; GetPlacement const& Get_placement ; VisitorT Visitor ; - + bool m_has_border ; private: diff -Nru cgal-4.4/include/CGAL/Surface_mesh_simplification/Detail/Edge_collapse_impl.h cgal-4.5/include/CGAL/Surface_mesh_simplification/Detail/Edge_collapse_impl.h --- cgal-4.4/include/CGAL/Surface_mesh_simplification/Detail/Edge_collapse_impl.h 2014-02-15 20:00:24.000000000 +0000 +++ cgal-4.5/include/CGAL/Surface_mesh_simplification/Detail/Edge_collapse_impl.h 2014-08-29 13:58:17.000000000 +0000 @@ -24,12 +24,12 @@ namespace Surface_mesh_simplification { -template -EdgeCollapse::EdgeCollapse( ECM& aSurface + template + EdgeCollapse::EdgeCollapse( ECM& aSurface , ShouldStop const& aShould_stop , VertexIndexMap const& aVertex_index_map + , VertexPointMap const& aVertex_point_map , EdgeIndexMap const& aEdge_index_map - , EdgeIsBorderMap const& aEdge_is_border_map , EdgeIsConstrainedMap const& aEdge_is_constrained_map , GetCost const& aGet_cost , GetPlacement const& aGet_placement @@ -39,16 +39,27 @@ mSurface (aSurface) ,Should_stop (aShould_stop) ,Vertex_index_map (aVertex_index_map) + ,Vertex_point_map (aVertex_point_map) ,Edge_index_map (aEdge_index_map) - ,Edge_is_border_map (aEdge_is_border_map) ,Edge_is_constrained_map (aEdge_is_constrained_map) ,Get_cost (aGet_cost) ,Get_placement (aGet_placement) ,Visitor (aVisitor) + ,m_has_border (false) { const FT cMaxDihedralAngleCos = std::cos( 1.0 * CGAL_PI / 180.0 ) ; mcMaxDihedralAngleCos2 = cMaxDihedralAngleCos * cMaxDihedralAngleCos ; + + halfedge_iterator eb, ee ; + for ( boost::tie(eb,ee) = halfedges(mSurface); eb!=ee; ++eb ) + { + halfedge_descriptor ed = *eb; + if(is_border(ed)){ + m_has_border = true; + break; + } + } CGAL_ECMS_TRACE(0,"EdgeCollapse of ECM with " << (num_edges(aSurface)/2) << " edges" ); @@ -59,14 +70,13 @@ for ( boost::tie(vb,ve) = boost::vertices(mSurface) ; vb != ve ; ++ vb ) CGAL_ECMS_TRACE(1, vertex_to_string(*vb) ) ; - undirected_edge_iterator eb, ee ; - for ( boost::tie(eb,ee) = undirected_edges(mSurface); eb!=ee; ++eb ) + for ( boost::tie(eb,ee) = edges(mSurface); eb!=ee; ++eb ) CGAL_ECMS_TRACE(1, edge_to_string(*eb) ) ; #endif } -template -int EdgeCollapse::run() + template + int EdgeCollapse::run() { CGAL_SURF_SIMPL_TEST_assertion( mSurface.is_valid() && mSurface.is_pure_triangle() ) ; @@ -87,8 +97,8 @@ return r ; } -template -void EdgeCollapse::Collect() + template + void EdgeCollapse::Collect() { CGAL_ECMS_TRACE(0,"Collecting edges..."); @@ -96,34 +106,32 @@ // Loop over all the _undirected_ edges in the surface putting them in the PQ // - Equal_3 equal_points = Kernel().equal_3_object(); + Equal_3 equal_points = Traits().equal_3_object(); - size_type lSize = num_edges(mSurface) / 2 ; + size_type lSize = num_edges(mSurface); - CGAL_SURF_SIMPL_TEST_assertion( ( lSize * 2 ) == mSurface.size_of_halfedges() ) ; - mInitialEdgeCount = mCurrentEdgeCount = lSize; mEdgeDataArray.reset( new Edge_data[lSize] ) ; - mPQ.reset( new PQ (lSize, Compare_cost(this), Undirected_edge_id(this) ) ) ; + mPQ.reset( new PQ (lSize, Compare_cost(this), edge_id(this) ) ) ; std::size_t id = 0 ; CGAL_SURF_SIMPL_TEST_assertion_code ( size_type lInserted = 0 ) ; CGAL_SURF_SIMPL_TEST_assertion_code ( size_type lNotInserted = 0 ) ; - std::set zero_length_edges; + std::set zero_length_edges; - undirected_edge_iterator eb, ee ; - for ( boost::tie(eb,ee) = undirected_edges(mSurface); eb!=ee; ++eb, id+=2 ) + edge_iterator eb, ee ; + for ( boost::tie(eb,ee) = edges(mSurface); eb!=ee; ++eb, id+=2 ) { - edge_descriptor lEdge = *eb ; + halfedge_descriptor lEdge = halfedge(*eb,mSurface) ; if ( is_constrained(lEdge) ) continue;//no not insert constrainted edges - CGAL_assertion( get_directed_edge_id(lEdge) == id ) ; - CGAL_assertion( get_directed_edge_id(opposite_edge(lEdge,mSurface)) == id+1 ) ; + CGAL_assertion( get_halfedge_id(lEdge) == id ) ; + CGAL_assertion( get_halfedge_id(opposite(lEdge,mSurface)) == id+1 ) ; Profile const& lProfile = create_profile(lEdge); if ( !equal_points(lProfile.p0(),lProfile.p1()) ) @@ -149,7 +157,7 @@ CGAL_SURF_SIMPL_TEST_assertion ( lInserted + lNotInserted == mInitialEdgeCount ) ; - for (typename std::set::iterator it=zero_length_edges.begin(), + for (typename std::set::iterator it=zero_length_edges.begin(), it_end=zero_length_edges.end();it!=it_end;++it) { Profile const& lProfile = create_profile(*it); @@ -159,7 +167,7 @@ // edges of length 0 removed no longer need to be treated if ( lProfile.left_face_exists() ) { - edge_descriptor lEdge_to_remove = is_constrained(lProfile.vL_v0()) ? + halfedge_descriptor lEdge_to_remove = is_constrained(lProfile.vL_v0()) ? primary_edge(lProfile.v1_vL()) : primary_edge(lProfile.vL_v0()) ; zero_length_edges.erase( lEdge_to_remove ); @@ -173,7 +181,7 @@ if ( lProfile.right_face_exists() ) { - edge_descriptor lEdge_to_remove = is_constrained(lProfile.vR_v1()) ? + halfedge_descriptor lEdge_to_remove = is_constrained(lProfile.vR_v1()) ? primary_edge(lProfile.v0_vR()) : primary_edge(lProfile.vR_v1()) ; zero_length_edges.erase( lEdge_to_remove ); @@ -191,15 +199,15 @@ Placement_type lPlacement = lProfile.p0(); vertex_descriptor rResult = halfedge_collapse_bk_compatibility(lProfile.v0_v1(), Edge_is_constrained_map); - put(vertex_point,mSurface,rResult,*lPlacement); + put(Vertex_point_map,rResult,*lPlacement); Visitor.OnCollapsed(lProfile,rResult); } CGAL_ECMS_TRACE(0,"Initial edge count: " << mInitialEdgeCount ) ; } -template -void EdgeCollapse::Loop() + template + void EdgeCollapse::Loop() { CGAL_ECMS_TRACE(0,"Collapsing edges...") ; @@ -209,7 +217,7 @@ // // Pops and processes each edge from the PQ // - optional lEdge ; + optional lEdge ; #ifdef CGAL_SURF_SIMPL_INTERMEDIATE_STEPS_PRINTING int i_rm=0; #endif @@ -217,7 +225,7 @@ { CGAL_SURF_SIMPL_TEST_assertion ( lLoop_watchdog ++ < mInitialEdgeCount ) ; - CGAL_ECMS_TRACE(1,"Poped " << edge_to_string(*lEdge) ) ; + CGAL_ECMS_TRACE(1,"Popped " << edge_to_string(*lEdge) ) ; CGAL_assertion( !is_constrained(*lEdge) ); @@ -243,7 +251,7 @@ if ( Is_collapse_topologically_valid(lProfile) ) { // The external function Get_new_vertex_point() is allowed to return an absent point if there is no way to place the vertex - // satisfying its constrians. In that case the remaining vertex is simply left unmoved. + // satisfying its constraints. In that case the remaining vertex is simply left unmoved. Placement_type lPlacement = get_placement(lProfile); if ( Is_collapse_geometrically_valid(lProfile,lPlacement) ) @@ -280,16 +288,16 @@ } } -template -bool EdgeCollapse::is_border( const_vertex_descriptor const& aV ) const +template +bool EdgeCollapse::is_border( vertex_descriptor const& aV ) const { bool rR = false ; - const_in_edge_iterator eb, ee ; - for ( boost::tie(eb,ee) = in_edges(aV,mSurface) ; eb != ee ; ++ eb ) + in_edge_iterator eb, ee ; + for ( boost::tie(eb,ee) = halfedges_around_target(aV,mSurface) ; eb != ee ; ++ eb ) { - const_edge_descriptor lEdge = *eb ; - if ( is_undirected_edge_a_border(lEdge) ) + halfedge_descriptor lEdge = *eb ; + if ( is_edge_a_border(lEdge) ) { rR = true ; break ; @@ -299,24 +307,24 @@ return rR ; } -template -bool EdgeCollapse::is_border_or_constrained( const_vertex_descriptor const& aV ) const +template +bool EdgeCollapse::is_border_or_constrained( vertex_descriptor const& aV ) const { - const_in_edge_iterator eb, ee ; - for ( boost::tie(eb,ee) = in_edges(aV,mSurface) ; eb != ee ; ++ eb ) + in_edge_iterator eb, ee ; + for ( boost::tie(eb,ee) = halfedges_around_target(aV,mSurface) ; eb != ee ; ++ eb ) { - const_edge_descriptor lEdge = *eb ; - if ( is_undirected_edge_a_border(lEdge) || is_constrained(lEdge) ) + halfedge_descriptor lEdge = *eb ; + if ( is_edge_a_border(lEdge) || is_constrained(lEdge) ) return true; } return false; } -template -bool EdgeCollapse::is_constrained( const_vertex_descriptor const& aV ) const +template +bool EdgeCollapse::is_constrained( vertex_descriptor const& aV ) const { - const_in_edge_iterator eb, ee ; - for ( boost::tie(eb,ee) = in_edges(aV,mSurface) ; eb != ee ; ++ eb ) + in_edge_iterator eb, ee ; + for ( boost::tie(eb,ee) = halfedges_around_target(aV,mSurface) ; eb != ee ; ++ eb ) if ( is_constrained(*eb) ) return true; return false; } @@ -330,8 +338,8 @@ // The link condition is as follows: for every vertex 'k' adjacent to both 'p and 'q', // "p,k,q" is a facet of the mesh. // -template -bool EdgeCollapse::Is_collapse_topologically_valid( Profile const& aProfile ) +template +bool EdgeCollapse::Is_collapse_topologically_valid( Profile const& aProfile ) { bool rR = true ; @@ -358,20 +366,44 @@ << ")" ); + // Simple tests handling the case of non-manifold situations at a vertex or edge (pinching) + // (even if we advertise one should not use a surface mesh with such features) + if ( aProfile.left_face_exists () ) + { + if ( CGAL::is_border( opposite(aProfile.v1_vL(), mSurface), mSurface ) && + CGAL::is_border( opposite(aProfile.vL_v0(), mSurface), mSurface ) + ) return false; + + if ( aProfile.right_face_exists () && + CGAL::is_border( opposite(aProfile.vR_v1(), mSurface), mSurface ) && + CGAL::is_border( opposite(aProfile.v0_vR(), mSurface), mSurface ) + ) return false; + } + else{ + if ( aProfile.right_face_exists () ) + { + if ( CGAL::is_border( opposite(aProfile.vR_v1(), mSurface), mSurface ) && + CGAL::is_border( opposite(aProfile.v0_vR(), mSurface), mSurface ) + ) return false; + } + else + return false; + } + // The following loop checks the link condition for v0_v1. // Specifically, that for every vertex 'k' adjacent to both 'p and 'q', 'pkq' is a face of the mesh. // - for ( boost::tie(eb1,ee1) = out_edges(aProfile.v0(),mSurface) ; rR && eb1 != ee1 ; ++ eb1 ) + for ( boost::tie(eb1,ee1) = halfedges_around_source(aProfile.v0(),mSurface) ; rR && eb1 != ee1 ; ++ eb1 ) { - edge_descriptor v0_k = *eb1 ; + halfedge_descriptor v0_k = *eb1 ; if ( v0_k != aProfile.v0_v1() ) { vertex_descriptor k = target(v0_k,mSurface); - for ( boost::tie(eb2,ee2) = out_edges(k,mSurface) ; rR && eb2 != ee2 ; ++ eb2 ) + for ( boost::tie(eb2,ee2) = halfedges_around_source(k,mSurface) ; rR && eb2 != ee2 ; ++ eb2 ) { - edge_descriptor k_v1 = *eb2 ; + halfedge_descriptor k_v1 = *eb2 ; if ( target(k_v1,mSurface) == aProfile.v1() ) { @@ -395,20 +427,20 @@ if ( lIsFace ) { // Is k_v1 the halfedge bounding the face 'k-v1-v0'? - if ( !k_v1->is_border() && k_v1->next()->vertex() == aProfile.v0() ) + if ( ! is_border(k_v1) && target(next(k_v1,mSurface),mSurface) == aProfile.v0() ) { - CGAL_SURF_SIMPL_TEST_assertion( !k_v1->is_border() ) ; - CGAL_SURF_SIMPL_TEST_assertion( k_v1 ->vertex() == aProfile.v1() ) ; - CGAL_SURF_SIMPL_TEST_assertion( k_v1->next() ->vertex() == aProfile.v0() ) ; - CGAL_SURF_SIMPL_TEST_assertion( k_v1->next()->next()->vertex() == k ) ; + CGAL_SURF_SIMPL_TEST_assertion( ! is_border(k_v1) ) ; + CGAL_SURF_SIMPL_TEST_assertion( target(k_v1,mSurface) == aProfile.v1() ) ; + CGAL_SURF_SIMPL_TEST_assertion( target(next(k_v1,mSurface),mSurface) == aProfile.v0() ) ; + CGAL_SURF_SIMPL_TEST_assertion( target(next(next(k_v1,mSurface),mSurface),mSurface) == k ) ; } else // or is it the opposite? { - edge_descriptor v1_k = k_v1->opposite(); - CGAL_SURF_SIMPL_TEST_assertion( !v1_k->is_border() ) ; - CGAL_SURF_SIMPL_TEST_assertion( v1_k ->vertex() == k ) ; - CGAL_SURF_SIMPL_TEST_assertion( v1_k->next() ->vertex() == aProfile.v0() ) ; - CGAL_SURF_SIMPL_TEST_assertion( v1_k->next()->next()->vertex() == aProfile.v1() ) ; + halfedge_descriptor v1_k = opposite(k_v1,mSurface); + CGAL_SURF_SIMPL_TEST_assertion( ! is_border(v1_k) ) ; + CGAL_SURF_SIMPL_TEST_assertion( target(v1_k,mSurface) == k ) ; + CGAL_SURF_SIMPL_TEST_assertion( target(next(v1_k, mSurface),mSurface) == aProfile.v0() ) ; + CGAL_SURF_SIMPL_TEST_assertion( target(next(next(v1_k, mSurface),mSurface),mSurface) == aProfile.v1() ) ; } } ); @@ -461,7 +493,7 @@ { bool lTetra = Is_tetrahedron(aProfile.v0_v1()); - CGAL_SURF_SIMPL_TEST_assertion( lTetra == mSurface.is_tetrahedron(aProfile.v0_v1()) ) ; + //CGAL_SURF_SIMPL_TEST_assertion( lTetra == mSurface.is_tetrahedron(aProfile.v0_v1()) ) ; if ( lTetra ) { @@ -475,77 +507,31 @@ return rR ; } -template -bool EdgeCollapse::Is_tetrahedron( edge_descriptor const& h1 ) +template +bool EdgeCollapse::Is_tetrahedron( halfedge_descriptor const& h1 ) { - // - // Code copied from Polyhedron_3::is_tetrahedron() - // - edge_descriptor h2 = next_edge(h1,mSurface); - edge_descriptor h3 = next_edge(h2,mSurface); - - edge_descriptor h1o = opposite_edge(h1,mSurface) ; - edge_descriptor h2o = opposite_edge(h2,mSurface) ; - edge_descriptor h3o = opposite_edge(h3,mSurface) ; - - edge_descriptor h4 = next_edge(h1o,mSurface); - edge_descriptor h5 = next_edge(h2o,mSurface); - edge_descriptor h6 = next_edge(h3o,mSurface); - - edge_descriptor h4o = opposite_edge(h4,mSurface) ; - edge_descriptor h5o = opposite_edge(h5,mSurface) ; - edge_descriptor h6o = opposite_edge(h6,mSurface) ; - - // check halfedge combinatorics. - // at least three edges at vertices 1, 2, 3. - if ( h4 == h3o ) return false; - if ( h5 == h1o ) return false; - if ( h6 == h2o ) return false; - - // exact three edges at vertices 1, 2, 3. - if ( next_edge(h4o,mSurface) != h3o ) return false; - if ( next_edge(h5o,mSurface) != h1o ) return false; - if ( next_edge(h6o,mSurface) != h2o ) return false; - - // three edges at v4. - if ( opposite_edge(next_edge(h4,mSurface),mSurface) != h5) return false; - if ( opposite_edge(next_edge(h5,mSurface),mSurface) != h6) return false; - if ( opposite_edge(next_edge(h6,mSurface),mSurface) != h4) return false; - - // All facets are triangles. - if ( next_edge(next_edge(next_edge(h1,mSurface),mSurface),mSurface) != h1) return false; - if ( next_edge(next_edge(next_edge(h4,mSurface),mSurface),mSurface) != h4) return false; - if ( next_edge(next_edge(next_edge(h5,mSurface),mSurface),mSurface) != h5) return false; - if ( next_edge(next_edge(next_edge(h6,mSurface),mSurface),mSurface) != h6) return false; - - // all edges are non-border edges. - if ( is_border(h1)) return false; // implies h2 and h3 - if ( is_border(h4)) return false; - if ( is_border(h5)) return false; - if ( is_border(h6)) return false; - - return true; + return is_tetrahedron(h1,mSurface); } -template -bool EdgeCollapse::Is_open_triangle( edge_descriptor const& h1 ) +template +bool EdgeCollapse::Is_open_triangle( halfedge_descriptor const& h1 ) { bool rR = false ; - edge_descriptor h2 = next_edge(h1,mSurface); - edge_descriptor h3 = next_edge(h2,mSurface); + halfedge_descriptor h2 = next(h1,mSurface); + halfedge_descriptor h3 = next(h2,mSurface); // First check if it is a triangle - if ( next_edge(h3,mSurface) == h1 ) + if ( next(h3,mSurface) == h1 ) { // Now check if it is open CGAL_ECMS_TRACE(4," p-q is a border edge... checking E" << get(Edge_index_map,h2) << " and E" << get(Edge_index_map,h3) ) ; rR = is_border(h2) && is_border(h3); - CGAL_SURF_SIMPL_TEST_assertion( rR == ( h1->is_border() - && h1->next()->is_border() - && h1->next()->next()->is_border() + CGAL_SURF_SIMPL_TEST_assertion( rR == ( is_border(h1) + && is_border(next(h1,mSurface)) + && is_border(next(next(h1,mSurface),mSurface)) ) ) ; } @@ -558,20 +544,20 @@ // respective areas is no greater than a max value and the internal // dihedral angle formed by their supporting planes is no greater than // a given threshold -template -bool EdgeCollapse::are_shared_triangles_valid( Point const& p0, Point const& p1, Point const& p2, Point const& p3 ) const +template +bool EdgeCollapse::are_shared_triangles_valid( Point const& p0, Point const& p1, Point const& p2, Point const& p3 ) const { bool rR = false ; - Vector e01 = p1 - p0 ; - Vector e02 = p2 - p0 ; - Vector e03 = p3 - p0 ; + Vector e01 = Traits().construct_vector_3_object()(p0,p1) ; + Vector e02 = Traits().construct_vector_3_object()(p0,p2) ; + Vector e03 = Traits().construct_vector_3_object()(p0,p3) ; - Vector n012 = cross_product(e01,e02); - Vector n023 = cross_product(e02,e03); + Vector n012 = Traits().construct_cross_product_vector_3_object()(e01,e02); + Vector n023 = Traits().construct_cross_product_vector_3_object()(e02,e03); - FT l012 = n012 * n012 ; - FT l023 = n023 * n023 ; + FT l012 = Traits().compute_scalar_product_3_object()(n012, n012) ; + FT l023 = Traits().compute_scalar_product_3_object()(n023, n023) ; FT larger = (std::max)(l012,l023); FT smaller = (std::min)(l012,l023); @@ -587,7 +573,7 @@ if ( larger < cMaxAreaRatio * smaller ) { - FT l0123 = n012 * n023 ; + FT l0123 = Traits().compute_scalar_product_3_object()(n012, n023) ; CGAL_ECMS_TRACE(4,"\n l0123=" << n_to_string(l0123) ); if ( CGAL_NTS is_positive(l0123) ) @@ -609,33 +595,33 @@ } // Returns the directed halfedge connecting v0 to v1, if exists. -template -typename EdgeCollapse::edge_descriptor -EdgeCollapse::find_connection ( const_vertex_descriptor const& v0, const_vertex_descriptor const& v1 ) const +template +typename EdgeCollapse::halfedge_descriptor +EdgeCollapse::find_connection ( vertex_descriptor const& v0, vertex_descriptor const& v1 ) const { out_edge_iterator eb, ee ; - for ( boost::tie(eb,ee) = out_edges(v0,mSurface) ; eb != ee ; ++ eb ) + for ( boost::tie(eb,ee) = halfedges_around_source(v0,mSurface) ; eb != ee ; ++ eb ) { - edge_descriptor out = *eb ; + halfedge_descriptor out = *eb ; if ( target(out,mSurface) == v1 ) return out ; } - return edge_descriptor() ; + return halfedge_descriptor() ; } // Given the edge 'e' around the link for the collapsinge edge "v0-v1", finds the vertex that makes a triangle adjacent to 'e' but exterior to the link (i.e not containing v0 nor v1) // If 'e' is a null handle OR 'e' is a border edge, there is no such triangle and a null handle is returned. -template -typename EdgeCollapse::vertex_descriptor -EdgeCollapse::find_exterior_link_triangle_3rd_vertex ( const_edge_descriptor const& e, const_vertex_descriptor const& v0, const_vertex_descriptor const& v1 ) const +template +typename EdgeCollapse::vertex_descriptor +EdgeCollapse::find_exterior_link_triangle_3rd_vertex ( halfedge_descriptor const& e, vertex_descriptor const& v0, vertex_descriptor const& v1 ) const { vertex_descriptor r ; if ( handle_assigned(e) ) { - vertex_descriptor ra = target(next_edge(e, mSurface), mSurface); - vertex_descriptor rb = source(prev_edge(e, mSurface), mSurface); + vertex_descriptor ra = target(next(e, mSurface), mSurface); + vertex_descriptor rb = source(prev(e, mSurface), mSurface); if ( ra == rb && ra != v0 && ra != v1 ) { @@ -643,8 +629,8 @@ } else { - ra = target(next_edge(opposite_edge(e,mSurface), mSurface), mSurface); - rb = source(prev_edge(opposite_edge(e,mSurface), mSurface), mSurface); + ra = target(next(opposite(e,mSurface), mSurface), mSurface); + rb = source(prev(opposite(e,mSurface), mSurface), mSurface); if ( ra == rb && ra != v0 && ra != v1 ) { @@ -660,8 +646,8 @@ // A collapse is geometrically valid if, in the resulting local mesh no two adjacent triangles form an internal dihedral angle // greater than a fixed threshold (i.e. triangles do not "fold" into each other) // -template -bool EdgeCollapse::Is_collapse_geometrically_valid( Profile const& aProfile, Placement_type k0) +template +bool EdgeCollapse::Is_collapse_geometrically_valid( Profile const& aProfile, Placement_type k0) { bool rR = true ; @@ -671,15 +657,15 @@ // // Use the current link to extract all local triangles incident to 'vx' in the collapsed mesh (which at this point doesn't exist yet) // - typedef typename Profile::vertex_descriptor_vector::const_iterator const_link_iterator ; - const_link_iterator linkb = aProfile.link().begin(); - const_link_iterator linke = aProfile.link().end (); - const_link_iterator linkl = cpp11::prev(linke) ; + typedef typename Profile::vertex_descriptor_vector::const_iterator link_iterator ; + link_iterator linkb = aProfile.link().begin(); + link_iterator linke = aProfile.link().end (); + link_iterator linkl = cpp11::prev(linke) ; - for ( const_link_iterator l = linkb ; l != linke && rR ; ++ l ) + for ( link_iterator l = linkb ; l != linke && rR ; ++ l ) { - const_link_iterator pv = ( l == linkb ? linkl : cpp11::prev (l) ); - const_link_iterator nx = ( l == linkl ? linkb : cpp11::next (l) ) ; + link_iterator pv = ( l == linkb ? linkl : cpp11::prev (l) ); + link_iterator nx = ( l == linkl ? linkb : cpp11::next (l) ) ; // k0,k1 and k3 are three consecutive vertices along the link. vertex_descriptor k1 = *pv ; @@ -688,8 +674,8 @@ CGAL_ECMS_TRACE(4," Screening link vertices k1=V" << get(Vertex_index_map,k1) << " k2=V" << get(Vertex_index_map,k2) << " k3=V" << get(Vertex_index_map,k3) ) ; - edge_descriptor e12 = find_connection(k1,k2); - edge_descriptor e23 = k3 != k1 ? find_connection(k2,k3) : edge_descriptor() ; + halfedge_descriptor e12 = find_connection(k1,k2); + halfedge_descriptor e23 = k3 != k1 ? find_connection(k2,k3) : halfedge_descriptor() ; // If 'k1-k2-k3' are connected there will be two adjacent triangles 'k0,k1,k2' and 'k0,k2,k3' after the collapse. if ( handle_assigned(e12) && handle_assigned(e23) ) @@ -745,11 +731,11 @@ return rR ; } -template -void EdgeCollapse::Collapse( Profile const& aProfile, Placement_type aPlacement ) +template +void EdgeCollapse::Collapse( Profile const& aProfile, Placement_type aPlacement ) { - CGAL_ECMS_TRACE(1,"S" << mStep << ". Collapsig " << edge_to_string(aProfile.v0_v1()) ) ; + CGAL_ECMS_TRACE(1,"S" << mStep << ". Collapsing " << edge_to_string(aProfile.v0_v1()) ) ; vertex_descriptor rResult ; @@ -766,7 +752,7 @@ if ( aProfile.left_face_exists() ) { - edge_descriptor lV0VL = primary_edge(aProfile.vL_v0()); + halfedge_descriptor lV0VL = primary_edge(aProfile.vL_v0()); if ( is_constrained(lV0VL) ) //make sure a constrained edge will not disappear lV0VL=primary_edge(aProfile.v1_vL()); @@ -787,7 +773,7 @@ if ( aProfile.right_face_exists() ) { - edge_descriptor lVRV1 = primary_edge(aProfile.vR_v1()); + halfedge_descriptor lVRV1 = primary_edge(aProfile.vR_v1()); if ( is_constrained(lVRV1) ) //make sure a constrained edge will not disappear lVRV1=primary_edge(aProfile.v0_vR()); @@ -837,7 +823,7 @@ if ( aPlacement ) { CGAL_ECMS_TRACE(1,"New vertex point: " << xyz_to_string(*aPlacement) ) ; - put(vertex_point,mSurface,rResult,*aPlacement) ; + put(Vertex_point_map,rResult,*aPlacement) ; } Visitor.OnCollapsed(aProfile,rResult); @@ -847,33 +833,33 @@ CGAL_ECMS_DEBUG_CODE ( ++mStep ; ) } -template -void EdgeCollapse::Update_neighbors( vertex_descriptor const& aKeptV ) +template +void EdgeCollapse::Update_neighbors( vertex_descriptor const& aKeptV ) { CGAL_ECMS_TRACE(3,"Updating cost of neighboring edges..." ) ; // - // (A) Collect all edges to update its cost: all those around each vertex adjacent to the vertex kept + // (A) Collect all edges to update their cost: all those around each vertex adjacent to the vertex kept // - typedef std::set edges ; + typedef std::set edges ; edges lToUpdate(Compare_id(this)) ; edges lToInsert(Compare_id(this)) ; // (A.1) Loop around all vertices adjacent to the vertex kept in_edge_iterator eb1, ee1 ; - for ( boost::tie(eb1,ee1) = in_edges(aKeptV,mSurface) ; eb1 != ee1 ; ++ eb1 ) + for ( boost::tie(eb1,ee1) = halfedges_around_target(aKeptV,mSurface) ; eb1 != ee1 ; ++ eb1 ) { - edge_descriptor lEdge1 = *eb1 ; + halfedge_descriptor lEdge1 = *eb1 ; vertex_descriptor lAdj_k = source(lEdge1,mSurface); // (A.2) Loop around all edges incident on each adjacent vertex in_edge_iterator eb2, ee2 ; - for ( boost::tie(eb2,ee2) = in_edges(lAdj_k,mSurface) ; eb2 != ee2 ; ++ eb2 ) + for ( boost::tie(eb2,ee2) = halfedges_around_target(lAdj_k,mSurface) ; eb2 != ee2 ; ++ eb2 ) { - edge_descriptor lEdge2 = primary_edge(*eb2) ; + halfedge_descriptor lEdge2 = primary_edge(*eb2) ; Edge_data& lData2 = get_data(lEdge2); CGAL_ECMS_TRACE(4,"Inedge around V" << get(Vertex_index_map,lAdj_k) << edge_to_string(lEdge2) ) ; @@ -892,7 +878,7 @@ for ( typename edges::iterator it = lToUpdate.begin(), eit = lToUpdate.end() ; it != eit ; ++ it ) { - edge_descriptor lEdge = *it; + halfedge_descriptor lEdge = *it; Edge_data& lData = get_data(lEdge); @@ -914,7 +900,7 @@ for ( typename edges::iterator it = lToInsert.begin(), eit = lToInsert.end() ; it != eit ; ++ it ) { - edge_descriptor lEdge = *it; + halfedge_descriptor lEdge = *it; if ( is_constrained(lEdge) ) continue; //do not insert constrained edges Edge_data& lData = get_data(lEdge); diff -Nru cgal-4.4/include/CGAL/Surface_mesh_simplification/edge_collapse.h cgal-4.5/include/CGAL/Surface_mesh_simplification/edge_collapse.h --- cgal-4.4/include/CGAL/Surface_mesh_simplification/edge_collapse.h 2014-02-15 20:00:24.000000000 +0000 +++ cgal-4.5/include/CGAL/Surface_mesh_simplification/edge_collapse.h 2014-08-29 13:58:17.000000000 +0000 @@ -34,20 +34,19 @@ template int edge_collapse ( ECM& aSurface - , ShouldStop const& aShould_stop - + , ShouldStop const& aShould_stop // optional mesh information policies , VertexIndexMap const& aVertex_index_map // defaults to get(vertex_index,aSurface) + , VertexPointMap const& aVertex_point_map // defaults to get(vertex_point,aSurface) , EdgeIndexMap const& aEdge_index_map // defaults to get(edge_index,aSurface) - , EdgeIsBorderMap const& aEdge_is_border_map // defaults to get(edge_is_border,aSurface) , EdgeIsConstrainedMap const& aEdge_is_constrained_map // defaults to No_constrained_edge_map() // optional strategy policies - defaults to LindstomTurk @@ -60,8 +59,8 @@ typedef EdgeCollapse< ECM , ShouldStop , VertexIndexMap + , VertexPointMap , EdgeIndexMap - , EdgeIsBorderMap , EdgeIsConstrainedMap , GetCost , GetPlacement @@ -72,8 +71,8 @@ Algorithm algorithm( aSurface , aShould_stop , aVertex_index_map + , aVertex_point_map , aEdge_index_map - , aEdge_is_border_map , aEdge_is_constrained_map , aGet_cost , aGet_placement @@ -109,12 +108,38 @@ LindstromTurk_params lPolicyParams ; boost::graph_visitor_t vis = boost::graph_visitor_t() ; + + return edge_collapse(aSurface + ,aShould_stop + ,choose_const_pmap(get_param(aParams,boost::vertex_index),aSurface,boost::vertex_index) + ,choose_pmap(get_param(aParams,boost::vertex_point),aSurface,boost::vertex_point) + ,choose_const_pmap(get_param(aParams,boost::halfedge_index),aSurface,boost::halfedge_index) + ,choose_param (get_param(aParams,edge_is_constrained),No_constrained_edge_map()) + ,choose_param (get_param(aParams,get_cost_policy), LindstromTurk_cost()) + ,choose_param (get_param(aParams,get_placement_policy), LindstromTurk_placement()) + ,choose_param (get_param(aParams,vis), Dummy_visitor()) + ); + +} + template +int edge_collapse ( ECM& aSurface + , ShouldStop const& aShould_stop + , cgal_bgl_named_params const& aParams + ) +{ + using boost::choose_param ; + using boost::choose_const_pmap ; + using boost::get_param ; + + LindstromTurk_params lPolicyParams ; + + boost::graph_visitor_t vis = boost::graph_visitor_t() ; return edge_collapse(aSurface ,aShould_stop ,choose_const_pmap(get_param(aParams,boost::vertex_index),aSurface,boost::vertex_index) - ,choose_const_pmap(get_param(aParams,boost::edge_index),aSurface,boost::edge_index) - ,choose_const_pmap(get_param(aParams,edge_is_border),aSurface,edge_is_border) + ,choose_const_pmap(get_param(aParams,boost::vertex_point),aSurface,boost::vertex_point) + ,choose_const_pmap(get_param(aParams,boost::halfedge_index),aSurface,boost::halfedge_index) ,choose_param (get_param(aParams,edge_is_constrained),No_constrained_edge_map()) ,choose_param (get_param(aParams,get_cost_policy), LindstromTurk_cost()) ,choose_param (get_param(aParams,get_placement_policy), LindstromTurk_placement()) @@ -126,7 +151,13 @@ template int edge_collapse ( ECM& aSurface, ShouldStop const& aShould_stop ) { - return edge_collapse(aSurface,aShould_stop, edge_index_map(get(boost::edge_index,aSurface))); + return edge_collapse(aSurface,aShould_stop, halfedge_index_map(get(boost::halfedge_index,aSurface))); // AF why the halfedge_index_map? +} + + template + int edge_collapse ( ECM& aSurface, ShouldStop const& aShould_stop) +{ + return edge_collapse(aSurface,aShould_stop, CGAL::halfedge_index_map(get(boost::halfedge_index,aSurface))); } } // namespace Surface_mesh_simplification diff -Nru cgal-4.4/include/CGAL/Surface_mesh_simplification/Edge_collapse_visitor_base.h cgal-4.5/include/CGAL/Surface_mesh_simplification/Edge_collapse_visitor_base.h --- cgal-4.4/include/CGAL/Surface_mesh_simplification/Edge_collapse_visitor_base.h 2012-11-13 13:14:01.000000000 +0000 +++ cgal-4.5/include/CGAL/Surface_mesh_simplification/Edge_collapse_visitor_base.h 2014-08-29 13:58:17.000000000 +0000 @@ -35,11 +35,11 @@ typedef Edge_profile Profile ; typedef boost::graph_traits GraphTraits ; - typedef halfedge_graph_traits HalfedgeGraphTraits ; typedef typename GraphTraits::edges_size_type size_type ; typedef typename GraphTraits::vertex_descriptor vertex_descriptor ; - typedef typename HalfedgeGraphTraits::Point Point ; + typedef typename boost::property_map::type Vertex_point_pmap; + typedef typename boost::property_traits::value_type Point; typedef typename Kernel_traits::Kernel Kernel ; typedef typename Kernel::FT FT ; diff -Nru cgal-4.4/include/CGAL/Surface_mesh_simplification/halfedge_collapse_Polyhedron_3.h cgal-4.5/include/CGAL/Surface_mesh_simplification/halfedge_collapse_Polyhedron_3.h --- cgal-4.4/include/CGAL/Surface_mesh_simplification/halfedge_collapse_Polyhedron_3.h 2014-02-15 20:00:24.000000000 +0000 +++ cgal-4.5/include/CGAL/Surface_mesh_simplification/halfedge_collapse_Polyhedron_3.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,196 +0,0 @@ -// Copyright (c) 2006 GeometryFactory (France). All rights reserved. -// -// This file is part of CGAL (www.cgal.org). -// You can redistribute it and/or modify it under the terms of the GNU -// General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -// -// $URL$ -// $Id$ -// -// Author(s) : Fernando Cacciola -// -#ifndef CGAL_SURFACE_MESH_SIMPLIFICATION_COLLAPSE_TRIANGULATION_EDGE_POLYHEDRON_3_H -#define CGAL_SURFACE_MESH_SIMPLIFICATION_COLLAPSE_TRIANGULATION_EDGE_POLYHEDRON_3_H - -#include -#include - -# define CGAL_HDS_PARAM_ template < class Traits, class Items, class Alloc> class HDS - -namespace CGAL { - -namespace Surface_mesh_simplification -{ -/* -Function responsible for contracting an edge while respecting constrained edges - -Notations used in the following function: -Top=TopFace -Btm=BottomFace - - t - / \ - / \ - / Top \ - p -------- q - \ Btm / - \ / - \ / - b - -Prerequisites: -If Top exists, amongst p-t and t-q only one is constrained -If Btm exists, amongst p-b and q-b only one is constrained -p-q is not constrained -*/ -template -typename boost::graph_traits< Polyhedron_3 >::vertex_descriptor -halfedge_collapse( typename boost::graph_traits< Polyhedron_3 >::edge_descriptor const& pq - , Polyhedron_3& aSurface - , EdgeIsConstrainedMap Edge_is_constrained_map - ) -{ - CGAL_assertion( !get(Edge_is_constrained_map,pq) ); - typedef Polyhedron_3 Surface ; - - typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor ; - typedef typename boost::graph_traits::edge_descriptor edge_descriptor ; - - edge_descriptor qp = opposite_edge(pq,aSurface); - edge_descriptor pt = opposite_edge(prev_edge(pq,aSurface),aSurface); - edge_descriptor qb = opposite_edge(prev_edge(qp,aSurface),aSurface); - edge_descriptor tq = pq->next()->opposite(); - edge_descriptor bp = qp->next()->opposite(); - - bool lTopFaceExists = !pq->is_border() ; - bool lBottomFaceExists = !qp->is_border() ; - - CGAL_precondition( !lTopFaceExists || (lTopFaceExists && ( pt->vertex()->vertex_degree() > 2 ) ) ) ; - CGAL_precondition( !lBottomFaceExists || (lBottomFaceExists && ( qb->vertex()->vertex_degree() > 2 ) ) ) ; - - vertex_descriptor q = pq->vertex(); - vertex_descriptor p = pq->opposite()->vertex(); - - CGAL_ECMS_TRACE(3, "Collapsing p-q E" << pq->id() << " (V" << p->id() << "->V" << q->id() << ")" ) ; - - //used to collect edges to remove from the surface - edge_descriptor edges_to_erase[2]; - edge_descriptor* edges_to_erase_ptr=edges_to_erase; - - // If the top facet exists, we need to choose one out of the two edges which one disappears: - // p-t if it is not constrained and t-q otherwise - if ( lTopFaceExists ) - { - CGAL_precondition( !pt->opposite()->is_border() ) ; // p-q-t is a face of the mesh - if ( !get(Edge_is_constrained_map,pt) ) - { - CGAL_ECMS_TRACE(3, "Removing p-t E" << pt->id() << " (V" << p->id() << "->V" << pt->vertex()->id()) ; - *edges_to_erase_ptr++=pt; - } - else - { - CGAL_ECMS_TRACE(3, "Removing t-q E" << pt->id() << " (V" << pt->vertex()->id() << "->V" << q->id() ) ; - CGAL_assertion( !get(Edge_is_constrained_map,tq) ); - *edges_to_erase_ptr++=tq; - } - } - - // If the bottom facet exists, we need to choose one out of the two edges which one disappears: - // q-b if it is not constrained and b-p otherwise - if ( lBottomFaceExists ) - { - if ( !get(Edge_is_constrained_map,qb) ) - { - CGAL_ECMS_TRACE(3, "Removing q-b E" << qb->id() << " (V" << q->id() << "->V" << qb->vertex()->id() ) ; - *edges_to_erase_ptr++=qb; - } - else{ - CGAL_ECMS_TRACE(3, "Removing b-p E" << qb->id() << " (V" << qb->vertex()->id() << "->V" << p->id() ) ; - CGAL_assertion( !get(Edge_is_constrained_map,bp) ); - *edges_to_erase_ptr++=bp; - } - } - - if (lTopFaceExists && lBottomFaceExists) - { - if ( edges_to_erase[0]->facet()==edges_to_erase[1]->facet() - && !edges_to_erase[0]->is_border() ) - { - // the vertex is of valence 3 and we simply need to remove the vertex - // and its indicent edges - bool lP_Erased=false; - edge_descriptor edge = - edges_to_erase[0]->next()==edges_to_erase[1]? - edges_to_erase[0]:edges_to_erase[1]; - if (edge->vertex()==p) - lP_Erased=true; - aSurface.erase_center_vertex(edge); - return lP_Erased? q : p; - } - else - { - if (!edges_to_erase[0]->is_border()) - aSurface.join_facet(edges_to_erase[0]); - else - aSurface.erase_facet(edges_to_erase[0]->opposite()); - if (!edges_to_erase[1]->is_border()) - aSurface.join_facet(edges_to_erase[1]); - else - aSurface.erase_facet(edges_to_erase[1]->opposite()); - aSurface.join_vertex(pq); - return q; - } - } - else - { - if (lTopFaceExists) - { - if (!edges_to_erase[0]->is_border()){ - aSurface.join_facet(edges_to_erase[0]); - aSurface.join_vertex(pq); - return q; - } - bool lQ_Erased=pq->next()->opposite()->is_border(); - aSurface.erase_facet(edges_to_erase[0]->opposite()); - return lQ_Erased?p:q; - } - - CGAL_assertion(lBottomFaceExists); - if (!edges_to_erase[0]->is_border()){ - aSurface.join_facet(edges_to_erase[0]); - aSurface.join_vertex(qp); - return p; - } - bool lP_Erased=qp->next()->opposite()->is_border(); - aSurface.erase_facet(edges_to_erase[0]->opposite()); - return lP_Erased?q:p; - }; -} - -template -typename boost::graph_traits< Polyhedron_3 >::vertex_descriptor -halfedge_collapse( typename boost::graph_traits< Polyhedron_3 >::edge_descriptor const& pq - , Polyhedron_3& aSurface - ) -{ - return halfedge_collapse( pq, - aSurface, - No_constrained_edge_map >() ); -} - -} // namespace Surface_mesh_simplification - -} //namespace CGAL - -#undef CGAL_HDS_PARAM - -#endif // CGAL_SURFACE_MESH_SIMPLIFICATION_COLLAPSE_TRIANGULATION_EDGE_POLYHEDRON_3_H -// EOF // - diff -Nru cgal-4.4/include/CGAL/Surface_mesh_simplification/HalfedgeGraph_Polyhedron_3.h cgal-4.5/include/CGAL/Surface_mesh_simplification/HalfedgeGraph_Polyhedron_3.h --- cgal-4.4/include/CGAL/Surface_mesh_simplification/HalfedgeGraph_Polyhedron_3.h 2012-11-13 13:14:01.000000000 +0000 +++ cgal-4.5/include/CGAL/Surface_mesh_simplification/HalfedgeGraph_Polyhedron_3.h 2014-08-29 13:58:17.000000000 +0000 @@ -21,9 +21,6 @@ #include #include -#include -#include -#include #endif // CGAL_SURFACE_MESH_SIMPLIFICATION_HALFEDGEGRAPH_POLYHEDRON_3_H // EOF // diff -Nru cgal-4.4/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Constrained_placement.h cgal-4.5/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Constrained_placement.h --- cgal-4.4/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Constrained_placement.h 2014-02-15 20:00:24.000000000 +0000 +++ cgal-4.5/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Constrained_placement.h 2014-08-29 13:58:17.000000000 +0000 @@ -32,9 +32,6 @@ { public: - typedef typename BasePlacement::Profile Profile; - typedef typename BasePlacement::Point Point; - typedef optional result_type ; EdgeIsConstrainedMap Edge_is_constrained_map; public: @@ -45,27 +42,25 @@ , Edge_is_constrained_map(map) {} - result_type operator()( Profile const& aProfile ) const + template + optional operator()( Profile const& aProfile ) const { typedef typename Profile::ECM ECM; - typedef typename boost::graph_traits GraphTraits; - typedef typename GraphTraits::in_edge_iterator in_edge_iterator; + typedef typename CGAL::Halfedge_around_target_iterator in_edge_iterator; in_edge_iterator eb, ee ; - for ( boost::tie(eb,ee) = in_edges(aProfile.v0(),aProfile.surface_mesh()); + for ( boost::tie(eb,ee) = halfedges_around_target(aProfile.v0(),aProfile.surface_mesh()); eb != ee ; ++ eb ) { - if( get(Edge_is_constrained_map, *eb) ) - return get(vertex_point, - aProfile.surface_mesh(), + if( get(Edge_is_constrained_map, edge(*eb,aProfile.surface_mesh())) ) + return get(aProfile.vertex_point_map(), aProfile.v0()); } - for ( boost::tie(eb,ee) = in_edges(aProfile.v1(),aProfile.surface_mesh()); + for ( boost::tie(eb,ee) = halfedges_around_target(aProfile.v1(),aProfile.surface_mesh()); eb != ee ; ++ eb ) { - if( get(Edge_is_constrained_map, *eb) ) - return get(vertex_point, - aProfile.surface_mesh(), + if( get(Edge_is_constrained_map, edge(*eb,aProfile.surface_mesh())) ) + return get(aProfile.vertex_point_map(), aProfile.v1()); } diff -Nru cgal-4.4/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Count_ratio_stop_predicate.h cgal-4.5/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Count_ratio_stop_predicate.h --- cgal-4.4/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Count_ratio_stop_predicate.h 2012-11-13 13:14:01.000000000 +0000 +++ cgal-4.5/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Count_ratio_stop_predicate.h 2014-08-29 13:58:17.000000000 +0000 @@ -49,16 +49,11 @@ typedef typename boost::graph_traits::edge_descriptor edge_descriptor ; typedef typename boost::graph_traits::edges_size_type size_type ; - - typedef typename halfedge_graph_traits::Point Point ; - typedef typename Kernel_traits::Kernel Kernel ; - typedef typename Kernel::FT FT ; - -public : - + Count_ratio_stop_predicate( double aRatio ) : mRatio(aRatio) {} - bool operator()( FT const& // aCurrentCost + template + bool operator()( F const& // aCurrentCost , Profile const& //aEdgeProfile , size_type aInitialCount , size_type aCurrentCount diff -Nru cgal-4.4/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Count_stop_predicate.h cgal-4.5/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Count_stop_predicate.h --- cgal-4.4/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Count_stop_predicate.h 2012-11-13 13:14:01.000000000 +0000 +++ cgal-4.5/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Count_stop_predicate.h 2014-08-29 13:58:17.000000000 +0000 @@ -45,28 +45,21 @@ typedef ECM_ ECM ; - typedef Edge_profile Profile ; + // typedef Edge_profile Profile ; -private : - - typedef typename halfedge_graph_traits::Point Point ; - typedef typename Kernel_traits::Kernel Kernel ; - -public : - - typedef typename boost::graph_traits::edge_descriptor edge_descriptor ; typedef typename boost::graph_traits::edges_size_type size_type ; - typedef typename Kernel::FT FT ; + // typedef typename Kernel::FT FT ; public : - Count_stop_predicate( size_type aThres ) : mThres(aThres) {} + Count_stop_predicate( std::size_t aThres ) : mThres(aThres) {} - bool operator()( FT const& // aCurrentCost + template + bool operator()( F const& // aCurrentCost , Profile const& //aEdgeProfile - , size_type //aInitialCount - , size_type aCurrentCount + , std::size_t //aInitialCount + , std::size_t aCurrentCount ) const { return aCurrentCount < mThres ; @@ -74,7 +67,7 @@ private: - size_type mThres ; + std::size_t mThres ; }; } // namespace Surface_mesh_simplification diff -Nru cgal-4.4/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Detail/Lindstrom_Turk_core.h cgal-4.5/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Detail/Lindstrom_Turk_core.h --- cgal-4.4/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Detail/Lindstrom_Turk_core.h 2012-11-13 13:14:01.000000000 +0000 +++ cgal-4.5/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Detail/Lindstrom_Turk_core.h 2014-08-29 13:58:17.000000000 +0000 @@ -41,30 +41,30 @@ namespace Surface_mesh_simplification { -template::Point>::Kernel > + template class LindstromTurkCore { public: typedef ECM_ ECM ; - typedef Kernel_ Kernel ; - - typedef Edge_profile Profile ; + typedef Profile_ Profile ; typedef boost::graph_traits GraphTraits ; typedef typename GraphTraits::vertex_descriptor vertex_descriptor ; - typedef typename GraphTraits::edge_descriptor edge_descriptor ; + typedef typename GraphTraits::halfedge_descriptor halfedge_descriptor ; typedef typename GraphTraits::in_edge_iterator in_edge_iterator ; typedef LindstromTurk_params Params ; - typedef typename Kernel::Point_3 Point ; + typedef typename Profile::Point Point ; - typedef typename halfedge_graph_traits::Point ECM_Point ; + typedef typename Profile::VertexPointMap Vertex_point_pmap; + typedef typename boost::property_traits::value_type ECM_Point; typedef typename Kernel_traits::Kernel ECM_Kernel ; + typedef typename Kernel_traits::Kernel Kernel; typedef typename Kernel::Vector_3 Vector ; typedef typename Kernel::FT FT ; @@ -78,7 +78,7 @@ typedef typename Profile::vertex_descriptor_vector vertex_descriptor_vector ; typedef typename Profile::Triangle_vector ::const_iterator const_triangle_iterator ; - typedef typename Profile::edge_descriptor_vector::const_iterator const_border_edge_iterator ; + typedef typename Profile::halfedge_descriptor_vector::const_iterator const_border_edge_iterator ; public: @@ -120,9 +120,9 @@ FT Compute_volume_cost ( Vector const& v, Triangle_data_vector const& aTriangles ) ; FT Compute_shape_cost ( Point const& p, vertex_descriptor_vector const& aLink ) ; - Point get_point ( vertex_descriptor const& v ) const + Point get_point ( vertex_descriptor const& v ) const { - return convert(get(vertex_point,surface(),v)); + return convert(get(mProfile.vertex_point_map(),v)); } static Vector Point_cross_product ( Point const& a, Point const& b ) diff -Nru cgal-4.4/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Detail/Lindstrom_Turk_core_impl.h cgal-4.5/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Detail/Lindstrom_Turk_core_impl.h --- cgal-4.4/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Detail/Lindstrom_Turk_core_impl.h 2012-11-13 13:14:01.000000000 +0000 +++ cgal-4.5/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Detail/Lindstrom_Turk_core_impl.h 2014-08-29 13:58:17.000000000 +0000 @@ -56,11 +56,12 @@ template void LindstromTurkCore::Extract_boundary_data() { + mBdry_data.reserve(mProfile.border_edges().size()); for ( const_border_edge_iterator it = mProfile.border_edges().begin(), eit = mProfile.border_edges().end() ; it != eit ; ++ it ) { - edge_descriptor border_edge = *it ; + halfedge_descriptor border_edge = *it ; - edge_descriptor face_edge = opposite_edge(border_edge,surface()) ; + halfedge_descriptor face_edge = opposite(border_edge,surface()) ; vertex_descriptor sv = source(face_edge,surface()); vertex_descriptor tv = target(face_edge,surface()); @@ -82,6 +83,7 @@ template void LindstromTurkCore::Extract_triangle_data() { + mTriangle_data.reserve(mProfile.triangles().size()); for ( const_triangle_iterator it = mProfile.triangles().begin(), eit = mProfile.triangles().end() ; it != eit ; ++ it ) { Triangle const& tri = *it ; @@ -548,9 +550,9 @@ CGAL_assertion( A0 != NULL_VECTOR ) ; - Vector AbsA0( CGAL_NTS abs(A0.x()) - , CGAL_NTS abs(A0.y()) - , CGAL_NTS abs(A0.z()) + Vector AbsA0( CGAL::abs(A0.x()) + , CGAL::abs(A0.y()) + , CGAL::abs(A0.z()) ); Vector Q0; diff -Nru cgal-4.4/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Edge_length_cost.h cgal-4.5/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Edge_length_cost.h --- cgal-4.4/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Edge_length_cost.h 2012-11-13 13:14:01.000000000 +0000 +++ cgal-4.5/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Edge_length_cost.h 2014-08-29 13:58:17.000000000 +0000 @@ -30,30 +30,28 @@ // // Edge-length cost: the squared length of the collapsing edge // -template + template class Edge_length_cost { - public: - + /* typedef ECM_ ECM ; typedef Edge_profile Profile ; - - typedef typename halfedge_graph_traits::Point Point ; - + typedef typename Profile::Point Point; typedef typename Kernel_traits::Kernel Kernel ; - typedef typename Kernel::FT FT ; - typedef optional result_type ; - + */ public: - Edge_length_cost() {} - - result_type operator()( Profile const& aProfile, optional const& /*aPlacement*/ ) const + Edge_length_cost() + {} + + template + optional operator()( Profile const& aProfile, T const& /*aPlacement*/ ) const { + typedef optional result_type; return result_type(squared_distance(aProfile.p0(),aProfile.p1())); } diff -Nru cgal-4.4/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Edge_profile.h cgal-4.5/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Edge_profile.h --- cgal-4.4/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Edge_profile.h 2014-02-15 20:00:24.000000000 +0000 +++ cgal-4.5/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Edge_profile.h 2014-08-29 13:58:17.000000000 +0000 @@ -29,24 +29,25 @@ namespace Surface_mesh_simplification { -template + template::type> class Edge_profile { public: typedef ECM_ ECM ; - - typedef boost::graph_traits ConstGraphTraits ; + typedef VertexPointMap_ VertexPointMap; typedef boost::graph_traits GraphTraits ; - typedef typename ConstGraphTraits::vertex_descriptor const_vertex_descriptor ; - typedef typename ConstGraphTraits::edge_descriptor const_edge_descriptor ; - typedef typename GraphTraits::vertex_descriptor vertex_descriptor ; - typedef typename GraphTraits::edge_descriptor edge_descriptor ; + typedef typename GraphTraits::face_descriptor face_descriptor ; + typedef typename GraphTraits::halfedge_descriptor halfedge_descriptor ; + + + //typedef typename boost::property_map::type Vertex_point_pmap; + typedef typename boost::property_traits::value_type Point; + typedef typename Kernel_traits::Kernel Kernel; + typedef typename Kernel::FT FT; - typedef typename halfedge_graph_traits::Point Point ; - public: struct Triangle @@ -69,7 +70,7 @@ } ; typedef std::vector vertex_descriptor_vector ; - typedef std::vector edge_descriptor_vector ; + typedef std::vector halfedge_descriptor_vector ; typedef std::vector Triangle_vector ; @@ -77,43 +78,57 @@ template - Edge_profile ( edge_descriptor const& aV0V1 + Edge_profile ( halfedge_descriptor const& aV0V1 , ECM& aSurface , VertexIdxMap const& aVertex_index_map + , VertexPointMap const& aVertex_point_map , EdgeIdxMap const& aEdge_index_map - , EdgeIsBorderMap const& aEdge_is_border_map + , bool has_border ) ; public : - edge_descriptor const& v0_v1() const { return mV0V1; } - edge_descriptor const& v1_v0() const { return mV1V0; } + halfedge_descriptor const& v0_v1() const { return mV0V1; } + halfedge_descriptor const& v1_v0() const { return mV1V0; } vertex_descriptor const& v0() const { return mV0; } vertex_descriptor const& v1() const { return mV1; } // These are null if v0v1 is a border (thius there is no face to its left) vertex_descriptor const& vL() const { return mVL; } - edge_descriptor const& v1_vL() const { return mV1VL; } - edge_descriptor const& vL_v0() const { return mVLV0; } + halfedge_descriptor const& v1_vL() const { return mV1VL; } + halfedge_descriptor const& vL_v0() const { return mVLV0; } // These are null if v1v0 is a border (thius there is no face to its left) vertex_descriptor const& vR() const { return mVR; } - edge_descriptor const& v0_vR() const { return mV0VR; } - edge_descriptor const& vR_v1() const { return mVRV1; } + halfedge_descriptor const& v0_vR() const { return mV0VR; } + halfedge_descriptor const& vR_v1() const { return mVRV1; } - Triangle_vector const& triangles() const { return mTriangles ; } + Triangle_vector const& triangles() const { + + if(mTriangles.empty()){ + const_cast(this)->Extract_triangles_and_link(); + } + CGAL_HISTOGRAM_PROFILER("triangles.size()", mTriangles.size()); + return mTriangles ; } // The cycle of vertices around the edge - vertex_descriptor_vector const& link() const { return mLink ; } - - edge_descriptor_vector const& border_edges() const { return mBorderEdges ; } + vertex_descriptor_vector const& link() const { + CGAL_PROFILER("link calls"); + if(mLink.empty()){ + const_cast(this)->Extract_triangles_and_link(); + } + return mLink ; } + + halfedge_descriptor_vector const& border_edges() const { + return mBorderEdges ; + } ECM& surface() const { return *mSurface ; } ECM& surface_mesh() const { return *mSurface ; } + VertexPointMap vertex_point_map() const { return mvpm ; } public : @@ -130,35 +145,20 @@ typedef typename GraphTraits::in_edge_iterator in_edge_iterator ; - typedef std::set IdxSet; - -private: - - template - void Extract_borders( vertex_descriptor const& v - , IdxSet& rCollected - , EdgeIdxMap const& edge_idx - , EdgeIsBorderMap const& is_border - ) ; + bool is_border(halfedge_descriptor e) const + { + return face(e,*mSurface) == boost::graph_traits::null_face(); + } - template - void Extract_borders( EdgeIdxMap const& edge_idx, EdgeIsBorderMap const& is_border) ; + + void Extract_borders() ; - template - void Extract_triangle( vertex_descriptor const& v0 - , vertex_descriptor const& v1 - , vertex_descriptor const& v2 - , edge_descriptor const& e02 - , EdgeIsBorderMap const& is_border - ) ; - - template - void Extract_triangles_and_link( VertexIdxMap const& vertex_idx, EdgeIsBorderMap const& is_border ) ; + void Extract_triangles_and_link() ; private: - - edge_descriptor mV0V1; - edge_descriptor mV1V0; + + halfedge_descriptor mV0V1; + halfedge_descriptor mV1V0; bool mIsBorderV0V1 ; bool mIsBorderV1V0 ; @@ -172,17 +172,17 @@ vertex_descriptor mVL; vertex_descriptor mVR; - edge_descriptor mV1VL; - edge_descriptor mVLV0; - edge_descriptor mV0VR; - edge_descriptor mVRV1; + halfedge_descriptor mV1VL; + halfedge_descriptor mVLV0; + halfedge_descriptor mV0VR; + halfedge_descriptor mVRV1; vertex_descriptor_vector mLink ; - edge_descriptor_vector mBorderEdges ; + halfedge_descriptor_vector mBorderEdges ; Triangle_vector mTriangles ; ECM* mSurface ; - + VertexPointMap mvpm; } ; } // namespace Surface_mesh_simplification diff -Nru cgal-4.4/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Edge_profile_impl.h cgal-4.5/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Edge_profile_impl.h --- cgal-4.4/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Edge_profile_impl.h 2014-02-15 20:00:24.000000000 +0000 +++ cgal-4.5/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Edge_profile_impl.h 2014-08-29 13:58:17.000000000 +0000 @@ -24,42 +24,48 @@ namespace Surface_mesh_simplification { -template + template template -Edge_profile::Edge_profile ( edge_descriptor const& aV0V1 + Edge_profile::Edge_profile ( halfedge_descriptor const& aV0V1 , ECM& aSurface - , VertexIdxMap const& vertex_idx - , EdgeIdxMap const& edge_idx - , EdgeIsBorderMap const& is_border + , VertexIdxMap const& + , VertexPointMap const& aVertex_point_map + , EdgeIdxMap const& + , bool has_border + ) : mV0V1(aV0V1) ,mSurface(boost::addressof(aSurface)) + , mvpm(aVertex_point_map) { - mV1V0 = opposite_edge(v0_v1(),surface_mesh()); + CGAL_PROFILER("Edge_profile constructor calls"); + + mLink.reserve(12); + mTriangles.reserve(16); + mV1V0 = opposite(v0_v1(),surface_mesh()); mV0 = source(v0_v1(),surface_mesh()); mV1 = target(v0_v1(),surface_mesh()); CGAL_assertion( mV0 != mV1 ); - mP0 = get(vertex_point,surface_mesh(),mV0); - mP1 = get(vertex_point,surface_mesh(),mV1); + mP0 = get(vertex_point_map(),mV0); + mP1 = get(vertex_point_map(),mV1); - mIsBorderV0V1 = is_border[v0_v1()]; - mIsBorderV1V0 = is_border[v1_v0()]; + mIsBorderV0V1 = is_border(v0_v1()); + mIsBorderV1V0 = is_border(v1_v0()); if ( left_face_exists() ) { - CGAL_SURF_SIMPL_TEST_assertion( !mV0V1->is_border() ) ; + CGAL_SURF_SIMPL_TEST_assertion( ! is_border(mV0V1) ) ; - mVLV0 = prev_edge(v0_v1(),surface_mesh()); - mV1VL = next_edge(v0_v1(),surface_mesh()); + mVLV0 = prev(v0_v1(),surface_mesh()); + mV1VL = next(v0_v1(),surface_mesh()); mVL = target(v1_vL(),surface_mesh()); CGAL_SURF_SIMPL_TEST_assertion( mV0 != mVL ); @@ -67,15 +73,15 @@ } else { - CGAL_SURF_SIMPL_TEST_assertion( mV0V1->is_border() ) ; + CGAL_SURF_SIMPL_TEST_assertion( is_border(mV0V1) ) ; } if ( right_face_exists() ) { - CGAL_SURF_SIMPL_TEST_assertion( !mV1V0->is_border() ) ; + CGAL_SURF_SIMPL_TEST_assertion( ! is_border(mV1V0) ) ; - mV0VR = next_edge(v1_v0(),surface_mesh()); - mVRV1 = prev_edge(v1_v0(),surface_mesh()); + mV0VR = next(v1_v0(),surface_mesh()); + mVRV1 = prev(v1_v0(),surface_mesh()); mVR = target(v0_vR(),surface_mesh()); CGAL_SURF_SIMPL_TEST_assertion( mV0 != mVR ); @@ -83,161 +89,110 @@ } else { - CGAL_SURF_SIMPL_TEST_assertion( mV1V0->is_border() ) ; + CGAL_SURF_SIMPL_TEST_assertion( is_border(mV1V0) ) ; } - - Extract_triangles_and_link(vertex_idx,is_border); - Extract_borders(edge_idx,is_border); -} - -template -template -void Edge_profile::Extract_borders( vertex_descriptor const& v - , IdxSet& rCollected - , EdgeIdxMap const& edge_idx - , EdgeIsBorderMap const& is_border - ) -{ - in_edge_iterator eb, ee ; - for ( boost::tie(eb,ee) = in_edges(v,surface_mesh()) ; eb != ee ; ++ eb ) - { - edge_descriptor edge = *eb ; - edge_descriptor opp_edge = opposite_edge(edge,surface_mesh()) ; - - bool is_edge_border = is_border[edge] ; - bool is_opp_edge_border = is_border[opp_edge] ; - - if ( is_edge_border || is_opp_edge_border ) - { - std::size_t eidx = edge_idx[edge]; - bool lNotCollected = rCollected.find(eidx) == rCollected.end() ; - if ( lNotCollected ) - { - rCollected.insert(eidx); - rCollected.insert(edge_idx[opp_edge]); - - edge_descriptor border_edge = is_edge_border ? edge : opp_edge ; - - mBorderEdges.push_back(border_edge) ; - } - } + + if(has_border){ + Extract_borders(); } } -template -template -void Edge_profile::Extract_borders( EdgeIdxMap const& edge_idx, EdgeIsBorderMap const& is_border) -{ - IdxSet lCollected ; - Extract_borders(mV0,lCollected,edge_idx,is_border); - Extract_borders(mV1,lCollected,edge_idx,is_border); -} -// -// If (v0,v1,v2) is a finite triangular facet of the mesh, that is, NONE of these vertices are boundary vertices, -// the triangle, properly oriented, is added to mTriangles. -// -template -template -void Edge_profile::Extract_triangle( vertex_descriptor const& v0 - , vertex_descriptor const& v1 - , vertex_descriptor const& v2 - , edge_descriptor const& e02 - , EdgeIsBorderMap const& is_border - ) + template + void Edge_profile::Extract_borders() { - // The 3 vertices are obtained by circulating ccw around v0, that is, e02 = next_ccw(e01). - // Since these vertices are NOT obtained by circulating the face, the actual triangle orientation is unspecified. - - // The triangle is oriented v0->v2->v1 if the next edge that follows e02 (which is the edge v0->v2) is v2->v1. - if ( target(next_edge(e02,surface_mesh()),surface_mesh()) == v1 ) - { - // The triangle is oriented v0->v2->v1. - // In this case e02 is an edge of the facet. - // If this facet edge is a border edge then this triangle is not in the mesh . - if ( !is_border[e02] ) - mTriangles.push_back(Triangle(v0,v2,v1) ) ; - } - else - { - // The triangle is oriented v0->v1->v2. - // In this case, e20 and not e02, is an edge of the facet. - // If this facet edge is a border edge then this triangle is not in the mesh . - if ( !is_border[opposite_edge(e02,surface_mesh())] ) - mTriangles.push_back(Triangle(v0,v1,v2) ) ; + halfedge_descriptor e = mV0V1; + halfedge_descriptor oe = opposite(e, surface_mesh()); + bool b; + if((b = is_border(e)) || is_border(oe)){ + mBorderEdges.push_back(b?e:oe); + } + e = next(oe,surface_mesh()); + oe = opposite(e,surface_mesh()); + while(e != mV0V1){ + if((b = is_border(e)) || is_border(oe)){ + mBorderEdges.push_back(b?e:oe); + } + e = next(oe,surface_mesh()); + oe = opposite(e,surface_mesh()); } + e = opposite(next(e,surface_mesh()),surface_mesh()); + oe = opposite(e,surface_mesh()); + while(e != mV0V1){ + if((b = is_border(e)) || is_border(oe)){ + mBorderEdges.push_back(b?e:oe); + } + e = opposite(next(e,surface_mesh()),surface_mesh()); + oe = opposite(e,surface_mesh()); + } } + + +// Extract all triangles (its normals) and vertices (the link) around the collapsing edge p_q // -// Extract all triangles (its normals) and vertices (the link) around the collpasing edge p_q -// -template -template -void Edge_profile::Extract_triangles_and_link( VertexIdxMap const& vertex_idx - , EdgeIsBorderMap const& is_border - ) + template + void Edge_profile::Extract_triangles_and_link() { - - IdxSet lCollected ; - - // - // Extract around mV0, CCW - // - vertex_descriptor v0 = mV0; - vertex_descriptor v1 = mV1; - - edge_descriptor e02 = mV0V1; - - do - { - e02 = opposite_edge(prev_edge(e02,surface_mesh()), surface_mesh()); - vertex_descriptor v2 = target(e02,surface_mesh()); - - if ( v2 != mV1 ) - { - mLink.push_back(v2) ; - CGAL_assertion_code( bool lInserted = ) lCollected.insert(vertex_idx[v2]).second ; - CGAL_assertion(lInserted); + #ifdef CGAL_SMS_EDGE_PROFILE_ALWAYS_NEED_UNIQUE_VERTEX_IN_LINK + std::set vertex_already_inserted; + #endif + // look at the two faces or holes adjacent to edge (v0,v1) + // and at the opposite vertex if it exists + halfedge_descriptor endleft = next(v1_v0(), surface_mesh()); + halfedge_descriptor endright = next(v0_v1(), surface_mesh()); + + if( left_face_exists() ) + mTriangles.push_back(Triangle(v0(),v1(),vL()) ) ; + if( right_face_exists() ) + mTriangles.push_back(Triangle(v1(),v0(),vR()) ) ; + + // counterclockwise around v0 + halfedge_descriptor e02 = opposite(prev(v0_v1(),surface_mesh()), surface_mesh()); + vertex_descriptor v, v2 =target(e02,surface_mesh()); + while(e02 != endleft) { + #ifdef CGAL_SMS_EDGE_PROFILE_ALWAYS_NEED_UNIQUE_VERTEX_IN_LINK + if (vertex_already_inserted.insert(v2).second) + #endif + mLink.push_back(v2); + bool is_b = is_border(e02); + e02 = opposite(prev(e02,surface_mesh()), surface_mesh()); + v = target(e02,surface_mesh()); + if(! is_b){ + mTriangles.push_back(Triangle(v,v0(),v2) ) ; } - - Extract_triangle(v0,v1,v2,e02,is_border); - - v1 = v2 ; + v2 = v; } - while ( e02 != mV0V1 ) ; - - // - // Extract around mV1, CCW - // - - v0 = mV1; - - e02 = opposite_edge(prev_edge(mV1V0,surface_mesh()), surface_mesh()); - - v1 = target(e02,surface_mesh()); - - - // This could have been added to the link while circulating around mP - if ( v1 != mV0 && lCollected.find(vertex_idx[v1]) == lCollected.end() ) - mLink.push_back(v1) ; - - e02 = opposite_edge(prev_edge(e02,surface_mesh()), surface_mesh()); - - do - { - vertex_descriptor v2 = target(e02,surface_mesh()); - - // Any of the vertices found around mP can be reached again around mQ, but we can't duplicate them here. - if ( v2 != mV0 && lCollected.find(vertex_idx[v2]) == lCollected.end() ) - mLink.push_back(v2) ; - - Extract_triangle(v0,v1,v2,e02,is_border); - - v1 = v2 ; - - e02 = opposite_edge(prev_edge(e02,surface_mesh()), surface_mesh()); + if(v != vR() && (v!= vertex_descriptor())){ + #ifdef CGAL_SMS_EDGE_PROFILE_ALWAYS_NEED_UNIQUE_VERTEX_IN_LINK + if (vertex_already_inserted.insert(v).second) + #endif + mLink.push_back(v); + } + + // counterclockwise around v1 + e02 = opposite(prev(v1_v0(),surface_mesh()), surface_mesh()); + v2 = target(e02,surface_mesh()); + while(e02 != endright) { + #ifdef CGAL_SMS_EDGE_PROFILE_ALWAYS_NEED_UNIQUE_VERTEX_IN_LINK + if (vertex_already_inserted.insert(v2).second) + #endif + mLink.push_back(v2); + bool is_b = is_border(e02); + e02 = opposite(prev(e02,surface_mesh()), surface_mesh()); + v = target(e02,surface_mesh()); + if(! is_b){ + mTriangles.push_back(Triangle(v,v1(),v2) ) ; + } + v2 = v; } - while ( e02 != mV1V0 ) ; + if(v != vL() && (v!= vertex_descriptor())){ + #ifdef CGAL_SMS_EDGE_PROFILE_ALWAYS_NEED_UNIQUE_VERTEX_IN_LINK + if (vertex_already_inserted.insert(v).second) + #endif + mLink.push_back(v); + } + } } // namespace Surface_mesh_simplification diff -Nru cgal-4.4/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/LindstromTurk_cost.h cgal-4.5/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/LindstromTurk_cost.h --- cgal-4.4/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/LindstromTurk_cost.h 2012-11-13 13:14:01.000000000 +0000 +++ cgal-4.5/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/LindstromTurk_cost.h 2014-08-29 13:58:17.000000000 +0000 @@ -27,28 +27,29 @@ namespace Surface_mesh_simplification { -template + template class LindstromTurk_cost { public: typedef ECM_ ECM ; + /* typedef Edge_profile Profile ; - - typedef typename halfedge_graph_traits::Point Point ; - typedef typename Kernel_traits::Kernel Kernel ; - typedef typename Kernel::FT FT ; + typedef typename Traits::Point_3 Point; + typedef typename Traits::FT FT ; typedef optional result_type ; - + */ public: LindstromTurk_cost( LindstromTurk_params const& aParams = LindstromTurk_params() ) : mParams(aParams) {} - result_type operator()( Profile const& aProfile, optional const& aPlacement ) const + template + optional + operator()( Profile const& aProfile, optional const& aPlacement ) const { - return LindstromTurkCore(mParams,aProfile).compute_cost(aPlacement) ; + return LindstromTurkCore(mParams,aProfile).compute_cost(aPlacement) ; } private: diff -Nru cgal-4.4/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/LindstromTurk_placement.h cgal-4.5/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/LindstromTurk_placement.h --- cgal-4.4/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/LindstromTurk_placement.h 2012-11-13 13:14:01.000000000 +0000 +++ cgal-4.5/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/LindstromTurk_placement.h 2014-08-29 13:58:17.000000000 +0000 @@ -27,26 +27,22 @@ namespace Surface_mesh_simplification { -template + template class LindstromTurk_placement { public: typedef ECM_ ECM ; - typedef Edge_profile Profile ; - - typedef typename halfedge_graph_traits::Point Point ; - - typedef optional result_type ; - public: LindstromTurk_placement( LindstromTurk_params const& aParams = LindstromTurk_params() ) : mParams(aParams) {} - result_type operator()( Profile const& aProfile) const + template + optional + operator()( Profile const& aProfile) const { - return LindstromTurkCore(mParams,aProfile).compute_placement() ; + return LindstromTurkCore(mParams,aProfile).compute_placement() ; } private: diff -Nru cgal-4.4/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Midpoint_placement.h cgal-4.5/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Midpoint_placement.h --- cgal-4.4/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Midpoint_placement.h 2012-11-13 13:14:01.000000000 +0000 +++ cgal-4.5/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Midpoint_placement.h 2014-08-29 13:58:17.000000000 +0000 @@ -27,26 +27,18 @@ namespace Surface_mesh_simplification { -template + template class Midpoint_placement { public: - typedef ECM_ ECM ; + Midpoint_placement() + {} - typedef Edge_profile Profile ; - - typedef typename halfedge_graph_traits::Point Point ; - - typedef optional result_type ; - -public: - - Midpoint_placement() {} - - result_type operator()( Profile const& aProfile ) const + template + optional operator()( Profile const& aProfile ) const { - return result_type(midpoint(aProfile.p0(),aProfile.p1())); + return optional (midpoint(aProfile.p0(),aProfile.p1())); } }; diff -Nru cgal-4.4/include/CGAL/tags.h cgal-4.5/include/CGAL/tags.h --- cgal-4.4/include/CGAL/tags.h 2014-01-11 20:00:27.000000000 +0000 +++ cgal-4.5/include/CGAL/tags.h 2014-08-29 13:58:17.000000000 +0000 @@ -43,6 +43,10 @@ typedef Boolean_tag type; operator bool() const { return this->value; } }; +/* In C++11, try: +template +using Boolean_tag = std::integral_constant; +*/ typedef Boolean_tag Tag_true; typedef Boolean_tag Tag_false; diff -Nru cgal-4.4/include/CGAL/Taucs_solver_traits.h cgal-4.5/include/CGAL/Taucs_solver_traits.h --- cgal-4.4/include/CGAL/Taucs_solver_traits.h 2013-09-28 19:00:44.000000000 +0000 +++ cgal-4.5/include/CGAL/Taucs_solver_traits.h 2014-08-29 13:58:17.000000000 +0000 @@ -66,6 +66,10 @@ // May also work with T = taucs_dcomplex and taucs_scomplex class Taucs_symmetric_solver_traits { + +private: + boost::shared_ptr mtr; + // Public types public: @@ -176,6 +180,104 @@ } } + + bool factor (const Matrix& A, NT& D) + { + D = 1; // TAUCS does not support homogeneous coordinates + +#ifdef DEBUG_TRACE + // Turn on TAUCS trace to stderr or to a log file +#if DEBUG_TRACE >= 2 + std::cerr.flush(); + taucs_logfile((char*)"stderr"); +#else + taucs_logfile((char*)"taucs.log"); +#endif + +#endif + +#ifdef WIN32 + Win32_exception_handler eh; // catch Win32 structured exceptions +#endif + + try + { + int success; + + // ordering + int* perm_raw = NULL; + int* invperm_raw = NULL; + taucs_ccs_order((taucs_ccs_matrix*) A.get_taucs_matrix(), + &perm_raw, + &invperm_raw, + (char*)"colamd"); + boost::shared_ptr perm(perm_raw, free); + boost::shared_ptr invperm(invperm_raw, free); + if ( perm == NULL || invperm == NULL) + throw std::runtime_error("Ordering Failed"); + + // Create multi-file for out-of-core swapping. + // Note: g++ complains that tempnam() is deprecated. You may safely ignore the warning. +#ifdef _MSC_VER + char template_name[13] = {'t', 'a', 'u', 'c', 's','.','X','X','X','X','X','X', '\0' }; + char* matrixfile = _mktemp(template_name); + if (matrixfile == NULL) + throw std::runtime_error("Cannot Create Multifile"); + boost::shared_ptr oocL(taucs_io_create_multifile(matrixfile), taucs_io_delete); + mtr = oocL; +#else + boost::shared_ptr matrixfile(tempnam(NULL, "taucs.L"), free); + if (matrixfile == NULL) + throw std::runtime_error("Cannot Create Multifile"); + boost::shared_ptr oocL(taucs_io_create_multifile(matrixfile.get()), taucs_io_delete); + mtr = oocL; +#endif + if (mtr == NULL) + throw std::runtime_error("Cannot Create Multifile"); + + // factor + int memory_mb = int(taucs_available_memory_size()/1048576.0); + success = taucs_ooc_factor_llt((taucs_ccs_matrix*) A.get_taucs_matrix(), + mtr.get(), + memory_mb*1048576.0); + if (success != TAUCS_SUCCESS) + throw std::runtime_error("Factorization Failed"); + + return true; + } + catch (std::exception& e) + { + taucs_printf((char*)"\t"); + taucs_printf((char*)(e.what() != NULL ? e.what() : "Incorrect Matrix")); + taucs_printf((char*)"\n"); + return false; + } + catch (...) + { + taucs_printf((char*)"\tIncorrect Matrix\n"); + return false; + } + } + + + + + bool solve (const Vector& B, Vector& X) + { + int success; + success = taucs_ooc_solve_llt(mtr.get(), + X.get_taucs_vector(), + (T*) B.get_taucs_vector()); + if (success != TAUCS_SUCCESS) + throw std::runtime_error("Solving Failed"); + + return true; + + } + + + + private: // Test if a floating point number is (close to) 0.0. @@ -204,6 +306,11 @@ class Taucs_solver_traits { // Public types + +private: + + boost::shared_ptr mtr; + public: typedef Taucs_matrix Matrix; @@ -338,6 +445,105 @@ } } + + + bool factor (const Matrix& A, NT& D) + { + D = 1; // TAUCS does not support homogeneous coordinates + +#ifdef DEBUG_TRACE + // Turn on TAUCS trace to stderr or to a log file +#if DEBUG_TRACE >= 2 + std::cerr.flush(); + taucs_logfile((char*)"stderr"); +#else + taucs_logfile((char*)"taucs.log"); +#endif + +#endif + +#ifdef WIN32 + Win32_exception_handler eh; // catch Win32 structured exceptions +#endif + + try + { + int success; + + // ordering + int* perm_raw = NULL; + int* invperm_raw = NULL; + taucs_ccs_order((taucs_ccs_matrix*) A.get_taucs_matrix(), + &perm_raw, + &invperm_raw, + (char*)"colamd"); + boost::shared_ptr perm(perm_raw, free); + boost::shared_ptr invperm(invperm_raw, free); + if ( perm == NULL || invperm == NULL) + throw std::runtime_error("Ordering Failed"); + + // Create multi-file for out-of-core swapping. + // Note: g++ complains that tempnam() is deprecated. You may safely ignore the warning. +#ifdef _MSC_VER + char template_name[13] = {'t', 'a', 'u', 'c', 's','.','X','X','X','X','X','X', '\0' }; + char* matrixfile = _mktemp(template_name); + if (matrixfile == NULL) + throw std::runtime_error("Cannot Create Multifile"); + boost::shared_ptr oocL(taucs_io_create_multifile(matrixfile), taucs_io_delete); + mtr = oocL; +#else + boost::shared_ptr matrixfile(tempnam(NULL, "taucs.L"), free); + if (matrixfile == NULL) + throw std::runtime_error("Cannot Create Multifile"); + boost::shared_ptr oocL(taucs_io_create_multifile(matrixfile.get()), taucs_io_delete); + mtr = oocL; +#endif + if (mtr == NULL) + throw std::runtime_error("Cannot Create Multifile"); + + // factor + int memory_mb = int(taucs_available_memory_size()/1048576.0); + success = taucs_ooc_factor_lu((taucs_ccs_matrix*) A.get_taucs_matrix(), + perm.get(), + mtr.get(), + memory_mb*1048576.0); + if (success != TAUCS_SUCCESS) + throw std::runtime_error("Factorization Failed"); + + return true; + } + catch (std::exception& e) + { + taucs_printf((char*)"\t"); + taucs_printf((char*)(e.what() != NULL ? e.what() : "Incorrect Matrix")); + taucs_printf((char*)"\n"); + return false; + } + catch (...) + { + taucs_printf((char*)"\tIncorrect Matrix\n"); + return false; + } + } + + + + + bool solve (const Vector& B, Vector& X) + { + int success; + success = taucs_ooc_solve_lu(mtr.get(), + X.get_taucs_vector(), + (T*) B.get_taucs_vector()); + if (success != TAUCS_SUCCESS) + throw std::runtime_error("Solving Failed"); + + return true; + + } + + + private: // Test if a floating point number is (close to) 0.0. diff -Nru cgal-4.4/include/CGAL/Time_stamper.h cgal-4.5/include/CGAL/Time_stamper.h --- cgal-4.4/include/CGAL/Time_stamper.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/Time_stamper.h 2014-08-29 13:58:17.000000000 +0000 @@ -0,0 +1,90 @@ +// Copyright (c) 2014 GeometryFactory Sarl (France) +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// +// +// Author(s) : Jane Tournois + +#include + +#ifndef CGAL_TIME_STAMPER_H +#define CGAL_TIME_STAMPER_H + +namespace CGAL { + +template +struct Time_stamper +{ + Time_stamper() + : time_stamp_(0) {} + + Time_stamper(const Time_stamper& ts) + : time_stamp_(ts.time_stamp_) {} + + void set_time_stamp(T* pt) { + pt->set_time_stamp(time_stamp_++); + } + + static bool less(const T* p_t1, const T* p_t2) { + if(p_t1 == NULL) return (p_t2 != NULL); + else if(p_t2 == NULL) return false; + else return p_t1->time_stamp() < p_t2->time_stamp(); + } + + void reset() { + time_stamp_ = 0; + } +private: + std::size_t time_stamp_; +}; // end class template Time_stamper + +template +struct No_time_stamp +{ +public: + void set_time_stamp(T*) {} + static bool less(const T* p_t1,const T* p_t2) { + return p_t1 < p_t2; + } + void reset() {} +}; // end class template No_time_stamp + +// That class template is an auxiliary class. It has a +// specialization for the case where `T::Has_timestamp` does not exists. +// The non-specialized template, when `T::Has_timestamp` exists, derives +// from `Time_stamper` or `No_time_stamp` depending on the +// value of the Boolean constant `T::Has_timestamp`. +// The declaration of that class template requires `T` to be a complete type. +template ::value> +struct Get_time_stamper{ + typedef Time_stamper type; +}; + +// Specialization when `T::Has_timestamp` does not exist, derives from +// `TimeStamper_`, or from `No_time_stamp`. +template +struct Get_time_stamper{ + typedef No_time_stamp type; +}; + +// Implementation of the timestamp policy. It is very important that the +// declaration of that class template does not require `T` to be a complete +// type. That way, the declaration of a pointer of type `Time_stamper_impl +// in `Compact_container` for example is possible with an incomplete type. +template +struct Time_stamper_impl : public Get_time_stamper::type {}; + +} //end of namespace CGAL + +#endif // CGAL_TIME_STAMPER_H diff -Nru cgal-4.4/include/CGAL/Tools/chained_map.h cgal-4.5/include/CGAL/Tools/chained_map.h --- cgal-4.4/include/CGAL/Tools/chained_map.h 2012-11-13 13:13:55.000000000 +0000 +++ cgal-4.5/include/CGAL/Tools/chained_map.h 2014-08-29 13:58:16.000000000 +0000 @@ -24,22 +24,24 @@ #ifndef CGAL_CHAINED_MAP_H #define CGAL_CHAINED_MAP_H +#include + namespace CGAL { namespace internal { -template class chained_map; +template class chained_map; template class chained_map_elem; template class chained_map_elem { - friend class chained_map; + template friend class chained_map; std::size_t k; T i; chained_map_elem* succ; }; -template +template class chained_map { const std::size_t NULLKEY; @@ -50,8 +52,8 @@ chained_map_elem* table; chained_map_elem* table_end; chained_map_elem* free; - std::size_t table_size; - std::size_t table_size_1; + std::size_t table_size; + std::size_t table_size_1; chained_map_elem* old_table; chained_map_elem* old_table_end; @@ -61,6 +63,9 @@ std::size_t old_index; + typedef typename Allocator::template rebind >::other allocator_type; + allocator_type alloc; + public: T& xdef() { return STOP.i; } const T& cxdef() const { return STOP.i; } @@ -84,14 +89,25 @@ std::size_t index(chained_map_item it) const { return it->k; } T& inf(chained_map_item it) const { return it->i; } - chained_map(std::size_t n = 1); - chained_map(const chained_map& D); - chained_map& operator=(const chained_map& D); + chained_map(std::size_t n = 1); + chained_map(const chained_map& D); + chained_map& operator=(const chained_map& D); void clear_entries(); void clear(); - ~chained_map() { if (old_table) delete[] old_table; delete[] table; } + ~chained_map() + { + if (old_table) + { + for (chained_map_item item = old_table ; item != old_table_end ; ++item) + alloc.destroy(item); + alloc.deallocate(old_table, old_table_end - old_table); + } + for (chained_map_item item = table ; item != table_end ; ++item) + alloc.destroy(item); + alloc.deallocate(table, table_end - table); + } T& access(chained_map_item p, std::size_t x); T& access(std::size_t x); @@ -101,8 +117,8 @@ void statistics() const; }; -template -inline T& chained_map::access(std::size_t x) +template +inline T& chained_map::access(std::size_t x) { chained_map_item p = HASH(x); if (old_table) del_old_table(); @@ -121,12 +137,15 @@ } } -template -void chained_map::init_table(std::size_t t) +template +void chained_map::init_table(std::size_t t) { table_size = t; table_size_1 = t-1; - table = new chained_map_elem[t + t/2]; + table = alloc.allocate(t + t/2); + for (std::size_t i = 0 ; i < t + t/2 ; ++i) + alloc.construct(table + i, chained_map_elem()); + free = table + t; table_end = table + t + t/2; @@ -138,8 +157,8 @@ } -template -inline void chained_map::insert(std::size_t x, T y) +template +inline void chained_map::insert(std::size_t x, T y) { chained_map_item q = HASH(x); if ( q->k == NULLKEY ) { q->k = x; @@ -153,8 +172,8 @@ } -template -void chained_map::rehash() +template +void chained_map::rehash() { old_table = table; old_table_end = table_end; @@ -185,8 +204,8 @@ } -template -void chained_map::del_old_table() +template +void chained_map::del_old_table() { chained_map_item save_table = table; chained_map_item save_table_end = table_end; @@ -204,7 +223,9 @@ T p = access(old_index); - delete[] table; + for (chained_map_item item = table ; item != table_end ; ++item) + alloc.destroy(item); + alloc.deallocate(table, table_end - table); table = save_table; table_end = save_table_end; @@ -214,8 +235,8 @@ access(old_index) = p; } -template -T& chained_map::access(chained_map_item p, std::size_t x) +template +T& chained_map::access(chained_map_item p, std::size_t x) { STOP.k = x; chained_map_item q = p->succ; @@ -247,8 +268,8 @@ } -template -chained_map::chained_map(std::size_t n) : +template +chained_map::chained_map(std::size_t n) : NULLKEY(0), NONNULLKEY(1), old_table(0) { if (n < 512) @@ -261,8 +282,8 @@ } -template -chained_map::chained_map(const chained_map& D) : +template +chained_map::chained_map(const chained_map& D) : NULLKEY(0), NONNULLKEY(1), old_table(0) { init_table(D.table_size); @@ -276,11 +297,15 @@ } } -template -chained_map& chained_map::operator=(const chained_map& D) +template +chained_map& chained_map::operator=(const chained_map& D) { clear_entries(); - delete[] table; + + for (chained_map_item item = table ; item != table_end ; ++item) + alloc.destroy(item); + alloc.deallocate(table, table_end - table); + init_table(D.table_size); STOP.i = D.STOP.i; // xdef @@ -293,23 +318,28 @@ return *this; } -template -void chained_map::clear_entries() +template +void chained_map::clear_entries() { for(chained_map_item p = table + 1; p < free; p++) if (p->k != NULLKEY || p >= table + table_size) p->i = T(); } -template -void chained_map::clear() -{ clear_entries(); - delete[] table; +template +void chained_map::clear() +{ + clear_entries(); + + for (chained_map_item item = table ; item != table_end ; ++item) + alloc.destroy(item); + alloc.deallocate(table, table_end - table); + init_table(512); } -template -typename chained_map::chained_map_item -chained_map::lookup(std::size_t x) const +template +typename chained_map::chained_map_item +chained_map::lookup(std::size_t x) const { chained_map_item p = HASH(x); ((std::size_t &)STOP.k) = x; // cast away const while (p->k != x) @@ -318,21 +348,21 @@ } -template -typename chained_map::chained_map_item -chained_map::first_item() const +template +typename chained_map::chained_map_item +chained_map::first_item() const { return next_item(table); } -template -typename chained_map::chained_map_item -chained_map::next_item(chained_map_item it) const +template +typename chained_map::chained_map_item +chained_map::next_item(chained_map_item it) const { if (it == 0) return 0; do it++; while (it < table + table_size && it->k == NULLKEY); return (it < free ? it : 0); } -template -void chained_map::statistics() const +template +void chained_map::statistics() const { std::cout << "table_size: " << table_size <<"\n"; std::size_t n = 0; for (chained_map_item p = table + 1; p < table + table_size; p++) diff -Nru cgal-4.4/include/CGAL/transforming_iterator.h cgal-4.5/include/CGAL/transforming_iterator.h --- cgal-4.4/include/CGAL/transforming_iterator.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/transforming_iterator.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,111 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_TRANSFORMING_ITERATOR_H +#define CGAL_TRANSFORMING_ITERATOR_H +#include +#include +#include +#include +#include + +// Inspired by the boost version, but more compact and +// without any iterator_category games. + +namespace CGAL { +namespace internal { + +// non-empty case +template::value> struct Functor_as_base { + Functor_as_base(){} + Functor_as_base(T const& t):f(t){} + //template Functor_as_base(Functor_as_base const&g):f(g.functor()){} + T const& functor()const{return f;} + T & functor() {return f;} + private: + T f; +}; + +// empty case +template struct Functor_as_base : public T { + Functor_as_base(){} + Functor_as_base(T const& t):T(t){} + //template Functor_as_base(Functor_as_base const&g):T(g.functor()){} + T const& functor()const{return *this;} + T & functor() {return *this;} +}; + +template +class transforming_iterator_helper +{ + typedef typename Default::Get()(std::declval::reference>())) +#else + typename boost::result_of::value_type)>::type + // should be reference instead of value_type +#endif + >::type reference; + + typedef typename Default::Get::type>::type>::type value_type; + + public: + typedef boost::iterator_adaptor< + Derived, + Iter, + value_type, + typename std::iterator_traits::iterator_category, + reference + > type; +}; +} + +template +class transforming_iterator +: public internal::transforming_iterator_helper,F,Iter,Ref,Val>::type, +private internal::Functor_as_base +{ + friend class boost::iterator_core_access; + typedef typename internal::transforming_iterator_helper::type Base; + typedef internal::Functor_as_base Functor_base; + typename Base::reference dereference()const{ + return functor()(*this->base_reference()); + } + public: + using Functor_base::functor; + transforming_iterator(){} + explicit transforming_iterator(Iter i,F const& f=F()) + :Base(i),Functor_base(f){} + template + transforming_iterator( + transforming_iterator const&i, + typename boost::enable_if_convertible::type* = 0, + typename boost::enable_if_convertible::type* = 0) + : Base(i.base()),Functor_base(i.functor()) {} + +}; + +template inline +transforming_iterator make_transforming_iterator(Iter i, F const&f=F()) { + return transforming_iterator(i,f); +} + +} + +#endif // CGAL_TRANSFORMING_ITERATOR_H diff -Nru cgal-4.4/include/CGAL/transforming_pair_iterator.h cgal-4.5/include/CGAL/transforming_pair_iterator.h --- cgal-4.4/include/CGAL/transforming_pair_iterator.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/transforming_pair_iterator.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,126 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_TRANSFORMING_PAIR_ITERATOR_H +#define CGAL_TRANSFORMING_PAIR_ITERATOR_H +// Should be a combination of transform_iterator and zip_iterator, +// but boost's iterator_category games are a pain. + +#include +#include +#include + + + +namespace CGAL { +namespace internal { +template ::value> +struct Min_category { + BOOST_STATIC_ASSERT((boost::is_convertible::value)); + typedef Cat1 type; +}; + +template +struct Min_category { + typedef Cat2 type; +}; + + +template +class transforming_pair_iterator_helper +{ + typedef typename Min_category< + typename std::iterator_traits::iterator_category, + typename std::iterator_traits::iterator_category> + ::type iterator_category; + + typedef typename Default::Get()(std::declval::reference>(),std::declval::reference>())) +#else + typename boost::result_of::value_type,typename std::iterator_traits::value_type)>::type + // should be reference instead of value_type +#endif + >::type reference; + + typedef typename Default::Get::type>::type>::type value_type; + + public: + typedef boost::iterator_facade< + Derived, + value_type, + iterator_category, + reference + // expect ptrdiff_t is good enough for difference + > type; +}; +} + +template +class transforming_pair_iterator +: public internal::transforming_pair_iterator_helper,F,It1,It2,Ref,Val>::type, +private internal::Functor_as_base +{ + It1 iter1; It2 iter2; + friend class boost::iterator_core_access; + typedef typename internal::transforming_pair_iterator_helper::type Base; + typedef internal::Functor_as_base Functor_base; + typename Base::reference dereference()const{ + return functor()(*iter1,*iter2); + } + bool equal(transforming_pair_iterator const&i)const{ + bool b=(iter1==i.iter1); + CGAL_assertion(b==(iter2==i.iter2)); + //FIXME: or do we want only one driving iterator + return b; + } + void increment(){ ++iter1; ++iter2; } + void decrement(){ --iter1; --iter2; } + void advance(std::ptrdiff_t n){ + std::advance(iter1,n); + std::advance(iter2,n); + } + std::ptrdiff_t distance_to(transforming_pair_iterator const&i)const{ + std::ptrdiff_t dist=std::distance(iter1,i.iter1); + CGAL_assertion(dist==std::distance(iter2,i.iter2)); + return dist; + } + public: + using Functor_base::functor; + transforming_pair_iterator(){} + explicit transforming_pair_iterator(It1 i1,It2 i2,F const& f=F()) + :Functor_base(f),iter1(i1),iter2(i2){} + template + transforming_pair_iterator( + transforming_pair_iterator const&i, + typename boost::enable_if_convertible::type* = 0, + typename boost::enable_if_convertible::type* = 0, + typename boost::enable_if_convertible::type* = 0) + : Functor_base(i.functor()),iter1(i.iter1),iter2(i.iter2) {} + +}; + +template inline +transforming_pair_iterator make_transforming_pair_iterator(It1 i1, It2 i2, F const&f=F()) { + return transforming_pair_iterator(i1,i2,f); +} + +} + +#endif // CGAL_TRANSFORMING_PAIR_ITERATOR_H diff -Nru cgal-4.4/include/CGAL/Triangulation_3.h cgal-4.5/include/CGAL/Triangulation_3.h --- cgal-4.4/include/CGAL/Triangulation_3.h 2014-03-29 20:00:20.000000000 +0000 +++ cgal-4.5/include/CGAL/Triangulation_3.h 2014-08-29 13:58:17.000000000 +0000 @@ -17,12 +17,18 @@ // // Author(s) : Monique Teillaud // Sylvain Pion +// Clement Jamin #ifndef CGAL_TRIANGULATION_3_H #define CGAL_TRIANGULATION_3_H #include +#ifdef CGAL_CONCURRENT_TRIANGULATION_3_PROFILING +# define CGAL_PROFILE +# include +#endif + #include #include #include @@ -43,25 +49,36 @@ #include #include #include -#include #include +#include +#include + #include #include #include #include +#include #ifndef CGAL_NO_STRUCTURAL_FILTERING #include #include #endif // no CGAL_NO_STRUCTURAL_FILTERING +#ifdef CGAL_LINKED_WITH_TBB +# include +#endif + +#define CGAL_TRIANGULATION_3_USE_THE_4_POINTS_CONSTRUCTOR + namespace CGAL { -template < class GT, class Tds = Default > class Triangulation_3; +template < class GT, class Tds = Default, + class Lock_data_structure = Default > +class Triangulation_3; -template < class GT, class Tds > std::istream& operator>> -(std::istream& is, Triangulation_3 &tr); +template < class GT, class Tds, class Lds > std::istream& operator>> +(std::istream& is, Triangulation_3 &tr); #ifndef CGAL_NO_STRUCTURAL_FILTERING namespace internal { @@ -85,21 +102,285 @@ } #endif // no CGAL_NO_STRUCTURAL_FILTERING -template < class GT, class Tds_ > +/************************************************ +// Class Triangulation_3_base +// Two versions: Sequential (no locking) / Parallel (with locking) +************************************************/ + +// Sequential (without locking) +template +class Triangulation_3_base +{ +public: + // If Lock_data_structure_ = Default => void + typedef typename Default::Get< + Lock_data_structure_, void>::type Lock_data_structure; + +protected: + Triangulation_3_base() {} + + Triangulation_3_base(Lock_data_structure *) {} + + void swap(Triangulation_3_base &){} + + template + struct Vertex_triple_Facet_map_generator + { + typedef std::map type; + }; + + template + struct Vertex_handle_unique_hash_map_generator + { + typedef Unique_hash_map type; + }; + +public: + bool is_parallel() const + { + return false; + } + + // LOCKS (no-op functions) + + template + bool try_lock_point(const Point_3 &, int = 0) const + { return true; } + + template + bool try_lock_vertex(const Vertex_handle &, int = 0) const + { return true; } + + template + bool try_lock_cell(const Cell_handle &, int = 0) const + { return true; } + + template + bool try_lock_facet(const Facet &, int = 0) const + { return true; } + + template + bool is_point_locked_by_this_thread(const P3 &) const + { return false; } + + template + bool is_cell_locked_by_this_thread(const Cell_handle &) const + { return false; } + + void *get_lock_data_structure() const + { + return 0; + } + + void set_lock_data_structure(void *) const + { + } + + void unlock_all_elements() const {} + template void unlock_all_elements_but_one_point(const P3 &) const {} + + const Bbox_3 *get_bbox() const + { + return NULL; + } +}; + +#ifdef CGAL_LINKED_WITH_TBB +// Parallel (with locking) +template +class Triangulation_3_base +{ +public: + // If Lock_data_structure_ = Default => use Spatial_lock_grid_3 + typedef typename Default::Get< + Lock_data_structure_, Spatial_lock_grid_3 > + ::type Lock_data_structure; + +protected: + Triangulation_3_base() + : m_lock_ds(0) {} + + Triangulation_3_base(Lock_data_structure *lock_ds) + : m_lock_ds(lock_ds) {} + + void swap(Triangulation_3_base &tr) + { + std::swap(tr.m_lock_ds, m_lock_ds); + } + + template + struct Vertex_triple_Facet_map_generator + { + typedef std::map + < + Vertex_triple, + Facet, + std::less, + tbb::scalable_allocator > + > type; + }; + + template + struct Vertex_handle_unique_hash_map_generator + { + typedef Unique_hash_map > type; + }; + +public: + + bool is_parallel() const + { + return m_lock_ds != 0; + } + + // LOCKS + template + bool try_lock_point(const Point_3 &p, int lock_radius = 0) const + { + bool locked = true; + if (m_lock_ds) + { + locked = m_lock_ds->try_lock(p, lock_radius); + } + return locked; + } + + template + bool try_lock_vertex(const Vertex_handle &vh, int lock_radius = 0) const + { + bool locked = true; + if (m_lock_ds) + { + locked = m_lock_ds->try_lock(vh->point(), lock_radius); + } + return locked; + } + + template + bool try_lock_cell(const Cell_handle &cell_handle, int lock_radius = 0) const + { + bool success = true; + // Lock the element area on the grid + for (int iVertex = 0 ; success && iVertex < 4 ; ++iVertex) + { + success = try_lock_vertex(cell_handle->vertex(iVertex), lock_radius); + } + return success; + } + + template + bool try_lock_facet(const Facet &facet, int lock_radius = 0) const + { + bool success = true; + + // Lock the element area on the grid + for (int iVertex = (facet.second+1)&3 ; + success && iVertex != facet.second ; iVertex = (iVertex+1)&3) + { + success = try_lock_vertex(facet.first->vertex(iVertex), lock_radius); + } + + return success; + } + + template + bool is_point_locked_by_this_thread(const P3 &p) const + { + bool locked = true; + if (m_lock_ds) + { + locked = m_lock_ds->is_locked_by_this_thread(p); + } + return locked; + } + + template + bool is_cell_locked_by_this_thread(const Cell_handle &cell_handle) const + { + bool locked = true; + if (m_lock_ds) + { + for (int iVertex = 0 ; locked && iVertex < 4 ; ++iVertex) + { + locked = m_lock_ds->is_locked_by_this_thread( + cell_handle->vertex(iVertex)->point()); + } + } + return locked; + } + + Lock_data_structure *get_lock_data_structure() const + { + return m_lock_ds; + } + + void set_lock_data_structure(Lock_data_structure *lock_ds) const + { + m_lock_ds = lock_ds; + } + + void unlock_all_elements() const + { + if (m_lock_ds) + m_lock_ds->unlock_all_points_locked_by_this_thread(); + } + + template + void unlock_all_elements_but_one_point(const P3 &point) const + { + if (m_lock_ds) + m_lock_ds->unlock_all_tls_locked_locations_but_one_point(point); + } + + const Bbox_3 *get_bbox() const + { + return &m_lock_ds->get_bbox(); + } + +protected: + mutable Lock_data_structure *m_lock_ds; +}; +#endif // CGAL_LINKED_WITH_TBB + +/************************************************ + * + * Triangulation_3 class + * + ************************************************/ + +template < class GT, class Tds_, class Lock_data_structure_ > class Triangulation_3 - : public Triangulation_utils_3 + : public Triangulation_3_base< + // Get Concurrency_tag from TDS + typename Default::Get< Tds_, + Triangulation_data_structure_3 + < + Triangulation_vertex_base_3, + Triangulation_cell_base_3 + > + >::type::Concurrency_tag, + Lock_data_structure_> + , public Triangulation_utils_3 { friend std::istream& operator>> <> - (std::istream& is, Triangulation_3 &tr); - - typedef Triangulation_3 Self; + (std::istream& is, Triangulation_3 &tr); typedef typename Default::Get, - Triangulation_cell_base_3 > >::type Tds; + Triangulation_cell_base_3 > >::type Tds; + + typedef Triangulation_3 Self; + typedef Triangulation_3_base< + typename Tds::Concurrency_tag, Lock_data_structure_> Base; public: + typedef typename Base::Lock_data_structure Lock_data_structure; typedef Tds Triangulation_data_structure; typedef GT Geom_traits; @@ -108,6 +389,8 @@ typedef typename GT::Triangle_3 Triangle; typedef typename GT::Tetrahedron_3 Tetrahedron; + typedef typename Tds::Concurrency_tag Concurrency_tag; + typedef typename Tds::Vertex Vertex; typedef typename Tds::Cell Cell; typedef typename Tds::Facet Facet; @@ -147,26 +430,31 @@ Infinite_tester() {} Infinite_tester(const Self *tr) - : t(tr) {} + : t(tr) {} bool operator()(const Vertex_iterator & v) const { - return t->is_infinite(v); + return t->is_infinite(v); + } + + bool operator()(typename std::vector::const_iterator v) const + { + return t->is_infinite(*v); } bool operator()(const Cell_iterator & c) const { - return t->is_infinite(c); + return t->is_infinite(c); } bool operator()(const Edge_iterator & e) const { - return t->is_infinite(*e); + return t->is_infinite(*e); } bool operator()(const Facet_iterator & f) const { - return t->is_infinite(*f); + return t->is_infinite(*f); } }; @@ -220,7 +508,7 @@ public: typedef Iterator_project Point_iterator; @@ -260,14 +548,14 @@ Orientation orientation(const Point &p, const Point &q, - const Point &r, const Point &s) const + const Point &r, const Point &s) const { return geom_traits().orientation_3_object()(p, q, r, s); } bool coplanar(const Point &p, const Point &q, - const Point &r, const Point &s) const + const Point &r, const Point &s) const { return orientation(p, q, r, s) == COPLANAR; } @@ -298,7 +586,7 @@ Tetrahedron construct_tetrahedron(const Point &p, const Point &q, - const Point &r, const Point &s) const + const Point &r, const Point &s) const { return geom_traits().construct_tetrahedron_3_object()(p, q, r, s); } @@ -317,15 +605,15 @@ Comparison_result ps = compare_xyz(p, s); if (ps == EQUAL) - return SOURCE; + return SOURCE; Comparison_result st = compare_xyz(s, t); if (ps == st) - return BEFORE; + return BEFORE; Comparison_result pt = compare_xyz(p, t); if (pt == EQUAL) - return TARGET; + return TARGET; if (pt == st) - return MIDDLE; + return MIDDLE; return AFTER; } @@ -334,18 +622,47 @@ infinite = _tds.insert_increase_dimension(); } + void init_tds(const Point &p0, const Point &p1, + const Point &p2, const Point &p3) + { + Vertex_handle v0, v1, v2, v3; + infinite = _tds.insert_first_finite_cell(v0, v1, v2, v3, infinite); + v0->set_point(p0); + v1->set_point(p1); + v2->set_point(p2); + v3->set_point(p3); + } + + void init_tds(const Point &p0, const Point &p1, + const Point &p2, const Point &p3, + Vertex_handle &vh0, Vertex_handle &vh1, + Vertex_handle &vh2, Vertex_handle &vh3) + { + infinite = _tds.insert_first_finite_cell(vh0, vh1, vh2, vh3, infinite); + vh0->set_point(p0); + vh1->set_point(p1); + vh2->set_point(p2); + vh3->set_point(p3); + } + public: // CONSTRUCTORS - Triangulation_3(const GT & gt = GT()) - : _tds(), _gt(gt) + Triangulation_3(const GT & gt = GT(), Lock_data_structure *lock_ds = NULL) + : Base(lock_ds), _tds(), _gt(gt) + { + init_tds(); + } + + Triangulation_3(Lock_data_structure *lock_ds, const GT & gt = GT()) + : Base(lock_ds), _tds(), _gt(gt) { init_tds(); } // copy constructor duplicates vertices and cells Triangulation_3(const Triangulation_3 & tr) - : _gt(tr._gt) + : Base(tr.get_lock_data_structure()), _gt(tr._gt) { infinite = _tds.copy_tds(tr._tds, tr.infinite); CGAL_triangulation_expensive_postcondition(*this == tr); @@ -353,12 +670,23 @@ template < typename InputIterator > Triangulation_3(InputIterator first, InputIterator last, - const GT & gt = GT()) - : _gt(gt) - { + const GT & gt = GT(), Lock_data_structure *lock_ds = NULL) + : Base(lock_ds), _gt(gt) + { init_tds(); insert(first, last); - } + } + + // Create the 3D triangulation of p0, p1, p3 and p4 + // Precondition: p0, p1, p3 and p4 MUST BE positively oriented + Triangulation_3(const Point &p0, const Point &p1, + const Point &p3, const Point &p4, + const GT & gt = GT(), Lock_data_structure *lock_ds = NULL) + : Base(lock_ds), _gt(gt) + { + CGAL_triangulation_precondition(orientation(p0, p1, p3, p4) == POSITIVE); + init_tds(p0, p1, p3, p4); + } void clear() { @@ -368,7 +696,7 @@ Triangulation_3 & operator=(Triangulation_3 tr) { - // The triangulation passed as argument has been copied, + // The triangulation passed as argument has been copied, // because the parameter tr is passed by value. Then the following // swap consumes the *copy*. The original triangulation is left // untouched. @@ -383,6 +711,7 @@ std::swap(tr._gt, _gt); std::swap(tr.infinite, infinite); _tds.swap(tr._tds); + Base::swap(tr); } //ACCESS FUNCTIONS @@ -415,14 +744,14 @@ Vertex_handle infinite_vertex() const { return infinite; } - + void set_infinite_vertex(Vertex_handle v) { infinite=v;} Cell_handle infinite_cell() const { CGAL_triangulation_assertion(infinite_vertex()->cell()-> - has_vertex(infinite_vertex())); + has_vertex(infinite_vertex())); return infinite_vertex()->cell(); } @@ -433,9 +762,9 @@ CGAL_triangulation_precondition( dimension() == 3 ); CGAL_triangulation_precondition( ! is_infinite(c) ); return construct_tetrahedron(c->vertex(0)->point(), - c->vertex(1)->point(), - c->vertex(2)->point(), - c->vertex(3)->point()); + c->vertex(1)->point(), + c->vertex(2)->point(), + c->vertex(3)->point()); } Triangle triangle(const Cell_handle c, int i) const; @@ -481,23 +810,22 @@ bool is_infinite(const Edge & e) const { return is_infinite(e.first,e.second,e.third); } - //QUERIES bool is_vertex(const Point & p, Vertex_handle & v) const; bool is_vertex(Vertex_handle v) const; bool is_edge(Vertex_handle u, Vertex_handle v, - Cell_handle & c, int & i, int & j) const; + Cell_handle & c, int & i, int & j) const; bool is_facet(Vertex_handle u, Vertex_handle v, Vertex_handle w, - Cell_handle & c, int & i, int & j, int & k) const; + Cell_handle & c, int & i, int & j, int & k) const; bool is_cell(Cell_handle c) const; bool is_cell(Vertex_handle u, Vertex_handle v, - Vertex_handle w, Vertex_handle t, - Cell_handle & c, int & i, int & j, int & k, int & l) const; + Vertex_handle w, Vertex_handle t, + Cell_handle & c, int & i, int & j, int & k, int & l) const; bool is_cell(Vertex_handle u, Vertex_handle v, - Vertex_handle w, Vertex_handle t, - Cell_handle & c) const; + Vertex_handle w, Vertex_handle t, + Cell_handle & c) const; bool has_vertex(const Facet & f, Vertex_handle v, int & j) const; bool has_vertex(Cell_handle c, int i, Vertex_handle v, int & j) const; @@ -511,8 +839,9 @@ #ifdef CGAL_NO_STRUCTURAL_FILTERING Cell_handle locate(const Point & p, - Locate_type & lt, int & li, int & lj, - Cell_handle start = Cell_handle()) const; + Locate_type & lt, int & li, int & lj, + Cell_handle start = Cell_handle(), + bool *could_lock_zone = NULL) const; #else // no CGAL_NO_STRUCTURAL_FILTERING # ifndef CGAL_T3_STRUCTURAL_FILTERING_MAX_VISITED_CELLS # define CGAL_T3_STRUCTURAL_FILTERING_MAX_VISITED_CELLS 2500 @@ -522,32 +851,44 @@ public: Cell_handle inexact_locate(const Point& p, - Cell_handle start = Cell_handle(), - int max_num_cells = CGAL_T3_STRUCTURAL_FILTERING_MAX_VISITED_CELLS) const; + Cell_handle start = Cell_handle(), + int max_num_cells = CGAL_T3_STRUCTURAL_FILTERING_MAX_VISITED_CELLS, + bool *could_lock_zone = NULL) const; protected: Cell_handle exact_locate(const Point& p, Locate_type& lt, int& li, int & lj, - Cell_handle start) const; + Cell_handle start, + bool *could_lock_zone = NULL + ) const; Cell_handle generic_locate(const Point& p, Locate_type& lt, int& li, int & lj, Cell_handle start, - internal::Structural_filtering_3_tag) const { - return exact_locate(p, lt, li, lj, inexact_locate(p, start)); - } + internal::Structural_filtering_3_tag, + bool *could_lock_zone = NULL) const + { + Cell_handle ch = inexact_locate( + p, start, CGAL_T3_STRUCTURAL_FILTERING_MAX_VISITED_CELLS, could_lock_zone); + if (could_lock_zone && *could_lock_zone == false) + return ch; // = Cell_handle() here + else + return exact_locate(p, lt, li, lj, ch, could_lock_zone); + } Cell_handle generic_locate(const Point& p, Locate_type& lt, int& li, int & lj, Cell_handle start, - internal::No_structural_filtering_3_tag) const { - return exact_locate(p, lt, li, lj, start); - } + internal::No_structural_filtering_3_tag + , bool *could_lock_zone = NULL) const + { + return exact_locate(p, lt, li, lj, start, could_lock_zone); + } public: Orientation @@ -586,82 +927,90 @@ } public: - + Cell_handle locate(const Point & p, Locate_type & lt, int & li, int & lj, - Cell_handle start = Cell_handle()) const + Cell_handle start = Cell_handle() + , bool *could_lock_zone = NULL + ) const { typedef Triangulation_structural_filtering_traits TSFT; - typedef typename internal::Structural_filtering_selector_3< + typedef typename internal::Structural_filtering_selector_3< TSFT::Use_structural_filtering_tag::value >::Tag Should_filter_tag; - return generic_locate(p, lt, li, lj, start, Should_filter_tag()); + return generic_locate(p, lt, li, lj, start, Should_filter_tag(), could_lock_zone); } #endif // no CGAL_NO_STRUCTURAL_FILTERING Cell_handle - locate(const Point & p, Cell_handle start = Cell_handle()) const + locate(const Point & p, Cell_handle start = Cell_handle(), + bool *could_lock_zone = NULL) const { Locate_type lt; int li, lj; - return locate( p, lt, li, lj, start); + return locate( p, lt, li, lj, start, could_lock_zone); } Cell_handle locate(const Point & p, - Locate_type & lt, int & li, int & lj, Vertex_handle hint) const + Locate_type & lt, int & li, int & lj, Vertex_handle hint, + bool *could_lock_zone = NULL) const { - return locate(p, lt, li, lj, hint == Vertex_handle() ? infinite_cell() : hint->cell()); + return locate(p, lt, li, lj, + hint == Vertex_handle() ? infinite_cell() : hint->cell(), + could_lock_zone); } Cell_handle - locate(const Point & p, Vertex_handle hint) const - { - return locate(p, hint == Vertex_handle() ? infinite_cell() : hint->cell()); + locate(const Point & p, Vertex_handle hint, + bool *could_lock_zone = NULL) const + { + return locate(p, hint == Vertex_handle() ? infinite_cell() : hint->cell(), + could_lock_zone); } // PREDICATES ON POINTS ``TEMPLATED'' by the geom traits Bounded_side side_of_tetrahedron(const Point & p, - const Point & p0, - const Point & p1, - const Point & p2, - const Point & p3, - Locate_type & lt, int & i, int & j ) const; + const Point & p0, + const Point & p1, + const Point & p2, + const Point & p3, + Locate_type & lt, int & i, int & j ) const; Bounded_side side_of_cell(const Point & p, - Cell_handle c, - Locate_type & lt, int & i, int & j) const; + Cell_handle c, + Locate_type & lt, int & i, int & j) const; Bounded_side side_of_triangle(const Point & p, - const Point & p0, const Point & p1, const Point & p2, - Locate_type & lt, int & i, int & j ) const; + const Point & p0, const Point & p1, const Point & p2, + Locate_type & lt, int & i, int & j ) const; Bounded_side side_of_facet(const Point & p, - Cell_handle c, - Locate_type & lt, int & li, int & lj) const; + Cell_handle c, + Locate_type & lt, int & li, int & lj) const; Bounded_side side_of_facet(const Point & p, - const Facet & f, - Locate_type & lt, int & li, int & lj) const + const Facet & f, + Locate_type & lt, int & li, int & lj) const { CGAL_triangulation_precondition( f.second == 3 ); return side_of_facet(p, f.first, lt, li, lj); } Bounded_side side_of_segment(const Point & p, - const Point & p0, const Point & p1, - Locate_type & lt, int & i ) const; + const Point & p0, const Point & p1, + Locate_type & lt, int & i ) const; Bounded_side side_of_edge(const Point & p, - Cell_handle c, - Locate_type & lt, int & li) const; + Cell_handle c, + Locate_type & lt, int & li) const; Bounded_side side_of_edge(const Point & p, - const Edge & e, - Locate_type & lt, int & li) const + const Edge & e, + Locate_type & lt, int & li) const { CGAL_triangulation_precondition( e.second == 0 ); CGAL_triangulation_precondition( e.third == 1 ); @@ -716,15 +1065,15 @@ } Vertex_handle insert(const Point & p, Cell_handle start = Cell_handle()); Vertex_handle insert(const Point & p, Locate_type lt, Cell_handle c, - int li, int lj); - + int li, int lj); + //protected: // internal methods - + template - Vertex_handle insert_and_give_new_cells(const Point &p, + Vertex_handle insert_and_give_new_cells(const Point &p, OutputItCells fit, Cell_handle start = Cell_handle() ); - + template Vertex_handle insert_and_give_new_cells(const Point& p, OutputItCells fit, @@ -733,15 +1082,16 @@ template Vertex_handle insert_and_give_new_cells(const Point& p, Locate_type lt, - Cell_handle c, int li, int lj, - OutputItCells fit); + Cell_handle c, int li, int lj, + OutputItCells fit); template < class Conflict_tester, class Hidden_points_visitor > inline Vertex_handle insert_in_conflict(const Point & p, - Locate_type lt, - Cell_handle c, int li, int lj, - const Conflict_tester &tester, - Hidden_points_visitor &hider); + Locate_type lt, + Cell_handle c, int li, int lj, + const Conflict_tester &tester, + Hidden_points_visitor &hider, + bool *could_lock_zone = NULL); template < class InputIterator > std::ptrdiff_t insert(InputIterator first, InputIterator last) @@ -789,7 +1139,7 @@ template Vertex_handle insert_in_hole(const Point & p, CellIt cell_begin, CellIt cell_end, - Cell_handle begin, int i) + Cell_handle begin, int i) { // Some geometric preconditions should be tested... Vertex_handle v = _tds.insert_in_hole(cell_begin, cell_end, begin, i); @@ -800,7 +1150,7 @@ template Vertex_handle insert_in_hole(const Point & p, CellIt cell_begin, CellIt cell_end, - Cell_handle begin, int i, Vertex_handle newv) + Cell_handle begin, int i, Vertex_handle newv) { // Some geometric preconditions should be tested... newv->set_point(p); @@ -811,7 +1161,7 @@ template Vertex_handle _insert_in_hole(const Point & p, CellIt cell_begin, CellIt cell_end, - Cell_handle begin, int i) + Cell_handle begin, int i) { // Some geometric preconditions should be tested... Vertex_handle v = _tds._insert_in_hole(cell_begin, cell_end, begin, i); @@ -823,7 +1173,7 @@ template Vertex_handle _insert_in_hole(const Point & p, CellIt cell_begin, CellIt cell_end, - Cell_handle begin, int i, Vertex_handle newv) + Cell_handle begin, int i, Vertex_handle newv) { // Some geometric preconditions should be tested... newv->set_point(p); @@ -831,61 +1181,136 @@ } protected: - + template < class InputIterator > bool does_repeat_in_range(InputIterator first, InputIterator beyond) const; template < class InputIterator > bool infinite_vertex_in_range(InputIterator first, InputIterator beyond) const; - + + // - c is the current cell, which must be in conflict. // - tester is the function object that tests if a cell is in conflict. - template < - class Conflict_test, + template Triple - find_conflicts(Cell_handle d, const Conflict_test &tester, - Triple it) const + find_conflicts( + Cell_handle d, + const Conflict_test &tester, + Triple it + , bool *could_lock_zone = NULL + , const Facet *this_facet_must_be_in_the_cz = NULL + , bool *the_facet_is_in_its_cz = NULL + ) const { CGAL_triangulation_precondition( dimension()>=2 ); + + if (the_facet_is_in_its_cz) + *the_facet_is_in_its_cz = false; + + if (could_lock_zone) + *could_lock_zone = true; + + if (could_lock_zone) + { + if (!this->try_lock_cell(d)) + { + *could_lock_zone = false; + return it; + } + } + CGAL_triangulation_precondition( tester(d) ); + // To store the boundary cells, in case we need to rollback std::stack cell_stack; cell_stack.push(d); d->tds_data().mark_in_conflict(); + *it.second++ = d; do { - Cell_handle c = cell_stack.top(); - cell_stack.pop(); + Cell_handle c = cell_stack.top(); + cell_stack.pop(); + + // For each neighbor cell + for (int i=0; ineighbor(i); + + // "test" is either in the conflict zone, + // either facet-adjacent to the CZ + + if (test->tds_data().is_in_conflict()) { + + Facet f(c, i); // Internal facet. + // Is it the facet where're looking for? + if (this_facet_must_be_in_the_cz && the_facet_is_in_its_cz + && f == *this_facet_must_be_in_the_cz) + { + *the_facet_is_in_its_cz = true; + } + if (c < test) + { + *it.third++ = f; + } + continue; // test was already in conflict. + } + if (test->tds_data().is_clear()) { + if (tester(test)) { - for (int i=0; ineighbor(i); - if (test->tds_data().is_in_conflict()) { - if (c < test) - *it.third++ = Facet(c, i); // Internal facet. - continue; // test was already in conflict. + // "test" is in the conflict zone + if (could_lock_zone) + { + if (!this->try_lock_cell(test)) + { + *could_lock_zone = false; + // Unlock + return it; + } } - if (test->tds_data().is_clear()) { - if (tester(test)) { - if (c < test) - *it.third++ = Facet(c, i); // Internal facet. - - cell_stack.push(test); - test->tds_data().mark_in_conflict(); - *it.second++ = test; - continue; - } - test->tds_data().mark_on_boundary(); + + + Facet f(c, i); // Internal facet. + // Is it the facet where're looking for? + if (this_facet_must_be_in_the_cz && the_facet_is_in_its_cz + && f == *this_facet_must_be_in_the_cz) + { + *the_facet_is_in_its_cz = true; } - *it.first++ = Facet(c, i); + + if (c < test) + { + *it.third++ = f; + } + + cell_stack.push(test); + test->tds_data().mark_in_conflict(); + *it.second++ = test; + continue; + } + + test->tds_data().mark_on_boundary(); + } + + Facet f(c, i); // Boundary facet. + // Is it the facet where're looking for? + if (this_facet_must_be_in_the_cz + && the_facet_is_in_its_cz + && + (mirror_facet(f) == *this_facet_must_be_in_the_cz + || f == *this_facet_must_be_in_the_cz) ) + { + *the_facet_is_in_its_cz = true; } + + *it.first++ = f; + } } while (!cell_stack.empty()); return it; } @@ -909,17 +1334,17 @@ switch (dimension()) { case 3: find_conflicts(c, tester, make_triple(Oneset_iterator(facet), - std::back_inserter(cells), - Emptyset_iterator())); + std::back_inserter(cells), + Emptyset_iterator())); break; case 2: find_conflicts(c, tester, make_triple(Oneset_iterator(facet), - std::back_inserter(cells), - Emptyset_iterator())); + std::back_inserter(cells), + Emptyset_iterator())); } // Create the new cells and delete the old. return _tds._insert_in_hole(cells.begin(), cells.end(), - facet.first, facet.second); + facet.first, facet.second); } private: @@ -933,13 +1358,13 @@ public: Conflict_tester_outside_convex_hull_3(const Point &pt, const Self *tr) - : p(pt), t(tr) {} + : p(pt), t(tr) {} bool operator()(const Cell_handle c) const { - Locate_type loc; + Locate_type loc; int i, j; - return t->side_of_cell( p, c, loc, i, j ) == ON_BOUNDED_SIDE; + return t->side_of_cell( p, c, loc, i, j ) == ON_BOUNDED_SIDE; } }; @@ -951,13 +1376,13 @@ public: Conflict_tester_outside_convex_hull_2(const Point &pt, const Self *tr) - : p(pt), t(tr) {} + : p(pt), t(tr) {} bool operator()(const Cell_handle c) const { - Locate_type loc; + Locate_type loc; int i, j; - return t->side_of_facet( p, c, loc, i, j ) == ON_BOUNDED_SIDE; + return t->side_of_facet( p, c, loc, i, j ) == ON_BOUNDED_SIDE; } }; @@ -968,9 +1393,23 @@ // others inherited triangulations bool test_dim_down(Vertex_handle v) const; + bool test_dim_down_using_incident_cells_3( + Vertex_handle v, std::vector &incident_cells, + std::vector &adj_vertices, + bool *could_lock_zone = NULL) const; + // REMOVAL template < class VertexRemover > void remove(Vertex_handle v, VertexRemover &remover); + template < class VertexRemover > + // Concurrency-safe version + // Pre-condition: dimension = 3 + // The return value is only meaningful if *could_lock_zone = true: + // * returns true if the vertex was removed + // * returns false if the vertex wasn't removed since it would decrease + // the dimension => needs to be done sequentially + bool remove(Vertex_handle v, VertexRemover &remover, + bool *could_lock_zone); template < class VertexRemover, class OutputItCells > void remove_and_give_new_cells(Vertex_handle v, VertexRemover &remover, @@ -983,15 +1422,15 @@ // By doing these kind of remove followed by inserting the cluster, // we achieve fast relocations for a batch of points (in a Delaunay triangulation). template < class InputIterator, class VertexRemover > - size_type remove(InputIterator first, InputIterator beyond, + size_type remove(InputIterator first, InputIterator beyond, VertexRemover &remover); enum REMOVE_VERTEX_STATE {CLEAR, TO_REMOVE, PROCESSED, EXTREMITY}; - + // MOVE template < class VertexRemover, class VertexInserter > Vertex_handle move_if_no_collision(Vertex_handle v, const Point &p, VertexRemover &remover, - VertexInserter &inserter); + VertexInserter &inserter); template < class VertexRemover, class VertexInserter > Vertex_handle move(Vertex_handle v, const Point &p, @@ -1014,17 +1453,17 @@ int cwi = (i+2)%3; int ccwi = (i+1)%3; - int cwni = (ni+2)%3; - int ccwni = (ni+1)%3; + int cwni = (ni+2)%3; + int ccwni = (ni+1)%3; Vertex_handle v_cw = f->vertex(cwi); Vertex_handle v_ccw = f->vertex(ccwi); // bl == bottom left, tr == top right Cell_handle tr = f->neighbor(ccwi); - int tri = this->_tds.mirror_index(f,ccwi); + int tri = this->_tds.mirror_index(f,ccwi); Cell_handle bl = n->neighbor(ccwni); - int bli = this->_tds.mirror_index(n,ccwni); + int bli = this->_tds.mirror_index(n,ccwni); f->set_vertex(cwi, n->vertex(ni)); n->set_vertex(cwni, f->vertex(i)); @@ -1044,13 +1483,13 @@ } template < class VertexRemover, class VertexInserter > - void restore_edges_after_decrease_dimension(Vertex_handle v, + void restore_edges_after_decrease_dimension(Vertex_handle v, VertexRemover &remover, VertexInserter &inserter) { - + Cell_handle fkstart = v->cell(); Cell_handle start = fkstart->neighbor(fkstart->index(v)); - + std::list hole; make_hole_2D(v, hole, remover); fill_hole_2D(hole, remover); @@ -1058,18 +1497,18 @@ // the aim here is Delaunay triangulations // to make it more general one could have an internal function here // to remove v without touching its handle - + // This insert must be from Delaunay (or the particular trian.) - // not the basic Triangulation_3. + // not the basic Triangulation_3. // Here we correct the recent triangulation (with decreased dimension) formed // in particular here a 2D (from 3D to 2D displacement) Vertex_handle inserted = inserter.insert(v->point(), start); - + // fixing pointer Cell_handle fc = inserted->cell(), done(fc); std::vector faces_pt; faces_pt.reserve(16); - do { + do { faces_pt.push_back(fc); fc = fc->neighbor((fc->index(inserted) + 1)%3); } while(fc != done); @@ -1088,6 +1527,10 @@ private: typedef Facet Edge_2D; typedef Triple Vertex_triple; + typedef typename Base::template Vertex_triple_Facet_map_generator< + Vertex_triple, Facet>::type Vertex_triple_Facet_map; + typedef typename Base::template Vertex_handle_unique_hash_map_generator< + Vertex_handle>::type Vertex_handle_unique_hash_map; Vertex_triple make_vertex_triple(const Facet& f) const; void make_canonical(Vertex_triple& t) const; @@ -1097,14 +1540,19 @@ VertexRemover &remover); template < class VertexRemover > VertexRemover& make_hole_2D(Vertex_handle v, std::list & hole, - VertexRemover &remover, + VertexRemover &remover, std::set &cells_set); template < class VertexRemover > void fill_hole_2D(std::list & hole, VertexRemover &remover); - void make_hole_3D( Vertex_handle v, std::map& outer_map, + void make_hole_3D( Vertex_handle v, Vertex_triple_Facet_map& outer_map, std::vector & hole); + // When the incident cells are already known + void make_hole_3D( + Vertex_handle v, + const std::vector & incident_cells, + Vertex_triple_Facet_map& outer_map); template < class VertexRemover > VertexRemover& remove_dim_down(Vertex_handle v, VertexRemover &remover); @@ -1114,6 +1562,12 @@ VertexRemover& remove_2D(Vertex_handle v, VertexRemover &remover); template < class VertexRemover > VertexRemover& remove_3D(Vertex_handle v, VertexRemover &remover); + // Version of remove_3D if the incident cells and the adjacent vertices + // are already known + template < class VertexRemover > + VertexRemover& remove_3D(Vertex_handle v, VertexRemover &remover, + const std::vector &inc_cells, + std::vector &adj_vertices); template < class VertexRemover, class OutputItCells > VertexRemover& remove_dim_down(Vertex_handle v, VertexRemover &remover, @@ -1130,7 +1584,7 @@ template < class VertexRemover, class OutputItCells > VertexRemover& remove_3D(Vertex_handle v, VertexRemover &remover, OutputItCells fit); - + template < class VertexRemover, class OutputItCells > void fill_hole_2D(std::list & hole, VertexRemover &remover, OutputItCells fit); @@ -1144,7 +1598,7 @@ // remove cluster template < class InputIterator > - void _mark_vertices_to_remove(InputIterator first, InputIterator beyond, + void _mark_vertices_to_remove(InputIterator first, InputIterator beyond, std::map &vstates) const { while (first != beyond) vstates[*first++] = TO_REMOVE; @@ -1158,20 +1612,20 @@ CGAL_triangulation_precondition( dimension() == 3 ); int k=0; Vertex_handle v[4]; - for (Finite_vertices_iterator fit = finite_vertices_begin(); + for (Finite_vertices_iterator fit = finite_vertices_begin(); fit != finite_vertices_end(); ++fit ) { if(vstates[fit] == TO_REMOVE) continue; v[k++] = fit; if(k == 4) { - if (!coplanar(v[0]->point(), v[1]->point(), + if (!coplanar(v[0]->point(), v[1]->point(), v[2]->point(), v[3]->point())) return false; k--; } } return k < 4; } - + template < class InputIterator, class VertexRemover > bool _remove_cluster_3D(InputIterator first, InputIterator beyond, VertexRemover &remover, @@ -1189,9 +1643,9 @@ Finite_cells_iterator finite_cells_begin() const { if ( dimension() < 3 ) - return finite_cells_end(); + return finite_cells_end(); return CGAL::filter_iterator(cells_end(), Infinite_tester(this), - cells_begin()); + cells_begin()); } Finite_cells_iterator finite_cells_end() const { @@ -1219,9 +1673,9 @@ Finite_vertices_iterator finite_vertices_begin() const { if ( number_of_vertices() <= 0 ) - return finite_vertices_end(); + return finite_vertices_end(); return CGAL::filter_iterator(vertices_end(), Infinite_tester(this), - vertices_begin()); + vertices_begin()); } Finite_vertices_iterator finite_vertices_end() const { @@ -1249,9 +1703,9 @@ Finite_edges_iterator finite_edges_begin() const { if ( dimension() < 1 ) - return finite_edges_end(); + return finite_edges_end(); return CGAL::filter_iterator(edges_end(), Infinite_tester(this), - edges_begin()); + edges_begin()); } Finite_edges_iterator finite_edges_end() const { @@ -1279,9 +1733,9 @@ Finite_facets_iterator finite_facets_begin() const { if ( dimension() < 2 ) - return finite_facets_end(); + return finite_facets_end(); return CGAL::filter_iterator(facets_end(), Infinite_tester(this), - facets_begin()); + facets_begin()); } Finite_facets_iterator finite_facets_end() const { @@ -1329,7 +1783,7 @@ return _tds.incident_cells(e, start); } Cell_circulator incident_cells(Cell_handle c, int i, int j, - Cell_handle start) const + Cell_handle start) const { return _tds.incident_cells(c, i, j, start); } @@ -1348,17 +1802,17 @@ return _tds.incident_facets(e, start); } Facet_circulator incident_facets(Cell_handle c, int i, int j, - const Facet & start) const + const Facet & start) const { return _tds.incident_facets(c, i, j, start); } Facet_circulator incident_facets(const Edge & e, - Cell_handle start, int f) const + Cell_handle start, int f) const { return _tds.incident_facets(e, start, f); } Facet_circulator incident_facets(Cell_handle c, int i, int j, - Cell_handle start, int f) const + Cell_handle start, int f) const { return _tds.incident_facets(c, i, j, start, f); } @@ -1389,19 +1843,148 @@ } }; - template + template OutputIterator incident_cells(Vertex_handle v, OutputIterator cells) const { return _tds.incident_cells(v, cells); } + + template + void incident_cells_threadsafe(Vertex_handle v, + OutputIterator cells) const + { + _tds.incident_cells_threadsafe(v, cells); + } + + template + void incident_cells_threadsafe(Vertex_handle v, + OutputIterator cells, + const Filter &filter) const + { + _tds.incident_cells_threadsafe(v, cells, filter); + } + + bool + try_lock_and_get_incident_cells(Vertex_handle v, + std::vector& cells) const + { + // We need to lock v individually first, to be sure v->cell() is valid + if (!this->try_lock_vertex(v)) + return false; + + Cell_handle d = v->cell(); + if (!this->try_lock_cell(d)) // LOCK + { + return false; + } + cells.push_back(d); + d->tds_data().mark_in_conflict(); + int head=0; + int tail=1; + do { + Cell_handle c = cells[head]; + + for (int i=0; i<4; ++i) { + if (c->vertex(i) == v) + continue; + Cell_handle next = c->neighbor(i); + + if (!this->try_lock_cell(next)) // LOCK + { + BOOST_FOREACH(Cell_handle& ch, + std::make_pair(cells.begin(), cells.end())) + { + ch->tds_data().clear(); + } + cells.clear(); + return false; + } + if (! next->tds_data().is_clear()) + continue; + cells.push_back(next); + ++tail; + next->tds_data().mark_in_conflict(); + } + ++head; + } while(head != tail); + BOOST_FOREACH(Cell_handle& ch, std::make_pair(cells.begin(), cells.end())) + { + ch->tds_data().clear(); + } + return true; + } + + template + bool + try_lock_and_get_adjacent_vertices_and_cells_3( + Vertex_handle v, OutputIterator vertices, + std::vector &cells) const + { + + // We need to lock v individually first, to be sure v->cell() is valid + if (!this->try_lock_vertex(v)) + return false; + + Cell_handle d = v->cell(); + if (!this->try_lock_cell(d)) // LOCK + { + return false; + } + cells.push_back(d); + d->tds_data().mark_in_conflict(); + int head=0; + int tail=1; + do { + Cell_handle c = cells[head]; + + for (int i=0; i<4; ++i) { + if (c->vertex(i) == v) + continue; + Cell_handle next = c->neighbor(i); + + if (!this->try_lock_cell(next)) // LOCK + { + BOOST_FOREACH(Cell_handle& ch, + std::make_pair(cells.begin(), cells.end())) + { + ch->tds_data().clear(); + } + cells.clear(); + return false; + } + if (! next->tds_data().is_clear()) + continue; + cells.push_back(next); + ++tail; + next->tds_data().mark_in_conflict(); + } + ++head; + } while(head != tail); + + std::set tmp_vertices; + BOOST_FOREACH(Cell_handle& ch, std::make_pair(cells.begin(), cells.end())) + { + ch->tds_data().clear(); + for (int i = 0; i < 4; ++i) + { + Vertex_handle w = ch->vertex(i); + if (w != v && tmp_vertices.insert(w).second) + { + *vertices = w; + + } + } + } + return true; + } template OutputIterator finite_incident_cells(Vertex_handle v, OutputIterator cells) const { - if(dimension() == 2) - return _tds.incident_cells(v, cells, Finite_filter_2D(this)); + if(dimension() == 2) + return _tds.incident_cells(v, cells, Finite_filter_2D(this)); return _tds.incident_cells(v, cells, Finite_filter(this)); } @@ -1419,6 +2002,20 @@ return _tds.incident_facets(v, facets, Finite_filter(this)); } + template + OutputIterator + incident_facets_threadsafe(Vertex_handle v, OutputIterator facets) const + { + return _tds.incident_facets_threadsafe(v, facets); + } + + template + OutputIterator + finite_incident_facets_threadsafe(Vertex_handle v, OutputIterator facets) const + { + return _tds.incident_facets_threadsafe(v, facets, Finite_filter(this)); + } + // old name (up to CGAL 3.4) // kept for backwards compatibility but not documented template @@ -1436,6 +2033,14 @@ return _tds.adjacent_vertices(v, vertices); } + template + OutputIterator + adjacent_vertices_and_cells_3(Vertex_handle v, OutputIterator vertices, + std::vector &cells) const + { + return _tds.adjacent_vertices_and_cells_3(v, vertices, cells); + } + // old name (up to CGAL 3.4) // kept for backwards compatibility but not documented template @@ -1482,9 +2087,9 @@ bool is_valid_finite(Cell_handle c, bool verbose = false, int level=0) const; }; -template < class GT, class Tds > +template < class GT, class Tds, class Lds > std::istream & -operator>> (std::istream& is, Triangulation_3 &tr) +operator>> (std::istream& is, Triangulation_3 &tr) // reads // the dimension // the number of finite vertices @@ -1534,9 +2139,9 @@ return is; } -template < class GT, class Tds > +template < class GT, class Tds, class Lds > std::ostream & -operator<< (std::ostream& os, const Triangulation_3 &tr) +operator<< (std::ostream& os, const Triangulation_3 &tr) // writes : // the dimension // the number of finite vertices @@ -1554,7 +2159,7 @@ typedef typename Triangulation::Cell_iterator Cell_iterator; typedef typename Triangulation::Edge_iterator Edge_iterator; typedef typename Triangulation::Facet_iterator Facet_iterator; - + // outputs dimension and number of vertices size_type n = tr.number_of_vertices(); if (is_ascii(os)) @@ -1574,7 +2179,7 @@ // write the vertices for (Vertex_iterator it = tr.vertices_begin(), end = tr.vertices_end(); - it != end; ++it) + it != end; ++it) TV[i++] = it; CGAL_triangulation_assertion( i == n+1 ); @@ -1587,7 +2192,7 @@ os << *TV[i]; V[TV[i]] = i; if (is_ascii(os)) - os << std::endl; + os << std::endl; } // asks the tds for the combinatorial information @@ -1602,7 +2207,7 @@ case 3: { for(Cell_iterator it = tr.cells_begin(), end = tr.cells_end(); it != end; ++it) { - os << *it; // other information + os << *it; // other information if(is_ascii(os)) os << std::endl; } @@ -1611,7 +2216,7 @@ case 2: { for(Facet_iterator it = tr.facets_begin(), end = tr.facets_end(); it != end; ++it) { - os << *((*it).first); // other information + os << *((*it).first); // other information if(is_ascii(os)) os << std::endl; } @@ -1620,7 +2225,7 @@ case 1: { for(Edge_iterator it = tr.edges_begin(), end = tr.edges_end(); it != end; ++it) { - os << *((*it).first); // other information + os << *((*it).first); // other information if(is_ascii(os)) os << std::endl; } @@ -1632,118 +2237,118 @@ return os ; } -template < class GT, class Tds > -typename Triangulation_3::size_type -Triangulation_3:: +template < class GT, class Tds, class Lds > +typename Triangulation_3::size_type +Triangulation_3:: number_of_finite_cells() const { if ( dimension() < 3 ) return 0; return std::distance(finite_cells_begin(), finite_cells_end()); } -template < class GT, class Tds > -typename Triangulation_3::size_type -Triangulation_3:: +template < class GT, class Tds, class Lds > +typename Triangulation_3::size_type +Triangulation_3:: number_of_cells() const { return _tds.number_of_cells(); } -template < class GT, class Tds > -typename Triangulation_3::size_type -Triangulation_3:: +template < class GT, class Tds, class Lds > +typename Triangulation_3::size_type +Triangulation_3:: number_of_finite_facets() const { if ( dimension() < 2 ) return 0; return std::distance(finite_facets_begin(), finite_facets_end()); } -template < class GT, class Tds > -typename Triangulation_3::size_type -Triangulation_3:: +template < class GT, class Tds, class Lds > +typename Triangulation_3::size_type +Triangulation_3:: number_of_facets() const { return _tds.number_of_facets(); } -template < class GT, class Tds > -typename Triangulation_3::size_type -Triangulation_3:: +template < class GT, class Tds, class Lds > +typename Triangulation_3::size_type +Triangulation_3:: number_of_finite_edges() const { if ( dimension() < 1 ) return 0; return std::distance(finite_edges_begin(), finite_edges_end()); } -template < class GT, class Tds > -typename Triangulation_3::size_type -Triangulation_3:: +template < class GT, class Tds, class Lds > +typename Triangulation_3::size_type +Triangulation_3:: number_of_edges() const { return _tds.number_of_edges(); } -template < class GT, class Tds > -typename Triangulation_3::Triangle -Triangulation_3:: +template < class GT, class Tds, class Lds > +typename Triangulation_3::Triangle +Triangulation_3:: triangle(const Cell_handle c, int i) const { CGAL_triangulation_precondition( dimension() == 2 || dimension() == 3 ); CGAL_triangulation_precondition( (dimension() == 2 && i == 3) - || (dimension() == 3 && i >= 0 && i <= 3) ); + || (dimension() == 3 && i >= 0 && i <= 3) ); CGAL_triangulation_precondition( ! is_infinite(Facet(c, i)) ); if ( (i&1)==0 ) return construct_triangle(c->vertex( (i+2)&3 )->point(), - c->vertex( (i+1)&3 )->point(), - c->vertex( (i+3)&3 )->point()); + c->vertex( (i+1)&3 )->point(), + c->vertex( (i+3)&3 )->point()); return construct_triangle(c->vertex( (i+1)&3 )->point(), - c->vertex( (i+2)&3 )->point(), - c->vertex( (i+3)&3 )->point()); + c->vertex( (i+2)&3 )->point(), + c->vertex( (i+3)&3 )->point()); } -template < class GT, class Tds > -typename Triangulation_3::Segment -Triangulation_3:: +template < class GT, class Tds, class Lds > +typename Triangulation_3::Segment +Triangulation_3:: segment(const Cell_handle c, int i, int j) const { CGAL_triangulation_precondition( i != j ); CGAL_triangulation_precondition( dimension() >= 1 && dimension() <= 3 ); CGAL_triangulation_precondition( i >= 0 && i <= dimension() - && j >= 0 && j <= dimension() ); + && j >= 0 && j <= dimension() ); CGAL_triangulation_precondition( ! is_infinite(Edge(c, i, j)) ); return construct_segment( c->vertex(i)->point(), c->vertex(j)->point() ); } -template < class GT, class Tds > +template < class GT, class Tds, class Lds > inline bool -Triangulation_3:: +Triangulation_3:: is_infinite(const Cell_handle c, int i) const { CGAL_triangulation_precondition( dimension() == 2 || dimension() == 3 ); CGAL_triangulation_precondition( (dimension() == 2 && i == 3) - || (dimension() == 3 && i >= 0 && i <= 3) ); + || (dimension() == 3 && i >= 0 && i <= 3) ); return is_infinite(c->vertex(i<=0 ? 1 : 0)) || - is_infinite(c->vertex(i<=1 ? 2 : 1)) || - is_infinite(c->vertex(i<=2 ? 3 : 2)); + is_infinite(c->vertex(i<=1 ? 2 : 1)) || + is_infinite(c->vertex(i<=2 ? 3 : 2)); } -template < class GT, class Tds > +template < class GT, class Tds, class Lds > inline bool -Triangulation_3:: +Triangulation_3:: is_infinite(const Cell_handle c, int i, int j) const { CGAL_triangulation_precondition( i != j ); CGAL_triangulation_precondition( dimension() >= 1 && dimension() <= 3 ); CGAL_triangulation_precondition( - i >= 0 && i <= dimension() && j >= 0 && j <= dimension() ); + i >= 0 && i <= dimension() && j >= 0 && j <= dimension() ); return is_infinite( c->vertex(i) ) || is_infinite( c->vertex(j) ); } -template < class GT, class Tds > +template < class GT, class Tds, class Lds > bool -Triangulation_3:: +Triangulation_3:: is_vertex(const Point & p, Vertex_handle & v) const { Locate_type lt; @@ -1755,135 +2360,135 @@ return true; } -template < class GT, class Tds > +template < class GT, class Tds, class Lds > inline bool -Triangulation_3:: +Triangulation_3:: is_vertex(Vertex_handle v) const { return _tds.is_vertex(v); } -template < class GT, class Tds > +template < class GT, class Tds, class Lds > bool -Triangulation_3:: +Triangulation_3:: is_edge(Vertex_handle u, Vertex_handle v, - Cell_handle & c, int & i, int & j) const + Cell_handle & c, int & i, int & j) const { return _tds.is_edge(u, v, c, i, j); } -template < class GT, class Tds > +template < class GT, class Tds, class Lds > bool -Triangulation_3:: +Triangulation_3:: is_facet(Vertex_handle u, Vertex_handle v, Vertex_handle w, - Cell_handle & c, int & i, int & j, int & k) const + Cell_handle & c, int & i, int & j, int & k) const { return _tds.is_facet(u, v, w, c, i, j, k); } -template < class GT, class Tds > +template < class GT, class Tds, class Lds > inline bool -Triangulation_3:: +Triangulation_3:: is_cell(Cell_handle c) const { return _tds.is_cell(c); } -template < class GT, class Tds > +template < class GT, class Tds, class Lds > bool -Triangulation_3:: +Triangulation_3:: is_cell(Vertex_handle u, Vertex_handle v, - Vertex_handle w, Vertex_handle t, - Cell_handle & c, int & i, int & j, int & k, int & l) const + Vertex_handle w, Vertex_handle t, + Cell_handle & c, int & i, int & j, int & k, int & l) const { return _tds.is_cell(u, v, w, t, c, i, j, k, l); } -template < class GT, class Tds > +template < class GT, class Tds, class Lds > bool -Triangulation_3:: +Triangulation_3:: is_cell(Vertex_handle u, Vertex_handle v, - Vertex_handle w, Vertex_handle t, - Cell_handle & c) const + Vertex_handle w, Vertex_handle t, + Cell_handle & c) const { int i,j,k,l; return _tds.is_cell(u, v, w, t, c, i, j, k, l); } -template < class GT, class Tds > +template < class GT, class Tds, class Lds > inline bool -Triangulation_3:: +Triangulation_3:: has_vertex(const Facet & f, Vertex_handle v, int & j) const { return _tds.has_vertex(f.first, f.second, v, j); } -template < class GT, class Tds > +template < class GT, class Tds, class Lds > inline bool -Triangulation_3:: +Triangulation_3:: has_vertex(Cell_handle c, int i, Vertex_handle v, int & j) const { return _tds.has_vertex(c, i, v, j); } -template < class GT, class Tds > +template < class GT, class Tds, class Lds > inline bool -Triangulation_3:: +Triangulation_3:: has_vertex(const Facet & f, Vertex_handle v) const { return _tds.has_vertex(f.first, f.second, v); } -template < class GT, class Tds > +template < class GT, class Tds, class Lds > inline bool -Triangulation_3:: +Triangulation_3:: has_vertex(Cell_handle c, int i, Vertex_handle v) const { return _tds.has_vertex(c, i, v); } -template < class GT, class Tds > +template < class GT, class Tds, class Lds > inline bool -Triangulation_3:: +Triangulation_3:: are_equal(Cell_handle c, int i, Cell_handle n, int j) const { return _tds.are_equal(c, i, n, j); } -template < class GT, class Tds > +template < class GT, class Tds, class Lds > inline bool -Triangulation_3:: +Triangulation_3:: are_equal(const Facet & f, const Facet & g) const { return _tds.are_equal(f.first, f.second, g.first, g.second); } -template < class GT, class Tds > +template < class GT, class Tds, class Lds > inline bool -Triangulation_3:: +Triangulation_3:: are_equal(const Facet & f, Cell_handle n, int j) const { return _tds.are_equal(f.first, f.second, n, j); } -template < class GT, class Tds > -typename Triangulation_3::Cell_handle -Triangulation_3:: +template < class GT, class Tds, class Lds > +typename Triangulation_3::Cell_handle +Triangulation_3:: #ifdef CGAL_NO_STRUCTURAL_FILTERING locate(const Point & p, Locate_type & lt, int & li, int & lj, - Cell_handle start ) const + Cell_handle start, bool *could_lock_zone) const #else exact_locate(const Point & p, Locate_type & lt, int & li, int & lj, - Cell_handle start ) const + Cell_handle start, bool *could_lock_zone) const #endif // returns the (finite or infinite) cell p lies in // starts at cell "start" @@ -1899,6 +2504,9 @@ { CGAL_triangulation_expensive_assertion(start == Cell_handle() || tds().is_simplex(start) ); + if (could_lock_zone) + *could_lock_zone = true; + if ( dimension() >= 1 ) { // Make sure we continue from here with a finite cell. if ( start == Cell_handle() ) @@ -1909,111 +2517,144 @@ start = start->neighbor(ind_inf); } - boost::rand48 rng; + boost::rand48 rng; switch (dimension()) { case 3: + { + CGAL_triangulation_precondition( start != Cell_handle() ); + CGAL_triangulation_precondition( ! start->has_vertex(infinite) ); + + // We implement the remembering visibility/stochastic walk. + + // Remembers the previous cell to avoid useless orientation tests. + Cell_handle previous = Cell_handle(); + Cell_handle c = start; + + if (could_lock_zone) { - CGAL_triangulation_precondition( start != Cell_handle() ); - CGAL_triangulation_precondition( ! start->has_vertex(infinite) ); + if (!this->try_lock_cell(c)) + { + *could_lock_zone = false; + return Cell_handle(); + } + } - // We implement the remembering visibility/stochastic walk. + // Stores the results of the 4 orientation tests. It will be used + // at the end to decide if p lies on a face/edge/vertex/interior. + Orientation o[4]; + + boost::uniform_smallint<> four(0, 3); + boost::variate_generator > die4(rng, four); + + // Now treat the cell c. + bool try_next_cell = true; + while(try_next_cell) + { + try_next_cell = false; + // We know that the 4 vertices of c are positively oriented. + // So, in order to test if p is seen outside from one of c's facets, + // we just replace the corresponding point by p in the orientation + // test. We do this using the array below. + const Point* pts[4] = { &(c->vertex(0)->point()), + &(c->vertex(1)->point()), + &(c->vertex(2)->point()), + &(c->vertex(3)->point()) }; + + // For the remembering stochastic walk, + // we need to start trying with a random index : + int i = die4(); + // For the remembering visibility walk (Delaunay and Regular only), we don't : + // int i = 0; - // Remembers the previous cell to avoid useless orientation tests. - Cell_handle previous = Cell_handle(); - Cell_handle c = start; + // for each vertex + for (int j=0; !try_next_cell && j != 4; ++j, i = (i+1)&3) + { + Cell_handle next = c->neighbor(i); - // Stores the results of the 4 orientation tests. It will be used - // at the end to decide if p lies on a face/edge/vertex/interior. - Orientation o[4]; - - boost::uniform_smallint<> four(0, 3); - boost::variate_generator > die4(rng, four); - - // Now treat the cell c. - try_next_cell: - - // We know that the 4 vertices of c are positively oriented. - // So, in order to test if p is seen outside from one of c's facets, - // we just replace the corresponding point by p in the orientation - // test. We do this using the array below. - const Point* pts[4] = { &(c->vertex(0)->point()), - &(c->vertex(1)->point()), - &(c->vertex(2)->point()), - &(c->vertex(3)->point()) }; - - // For the remembering stochastic walk, - // we need to start trying with a random index : - int i = die4(); - // For the remembering visibility walk (Delaunay and Regular only), we don't : - // int i = 0; - - for (int j=0; j != 4; ++j, i = (i+1)&3) { - Cell_handle next = c->neighbor(i); - if (previous == next) { - o[i] = POSITIVE; - continue; + if (previous == next) + { + o[i] = POSITIVE; + } + else + { + // We temporarily put p at i's place in pts. + const Point* backup = pts[i]; + pts[i] = &p; + o[i] = orientation(*pts[0], *pts[1], *pts[2], *pts[3]); + if ( o[i] != NEGATIVE ) + { + pts[i] = backup; + } + else + { + if ( next->has_vertex(infinite, li) ) + { + // We are outside the convex hull. + lt = OUTSIDE_CONVEX_HULL; + return next; + } + previous = c; + c = next; + if (could_lock_zone) + { + //previous->unlock(); // DON'T do that, "c" may be in + // the same locking cell as "previous" + if (!this->try_lock_cell(c)) + { + *could_lock_zone = false; + return Cell_handle(); + } } - // We temporarily put p at i's place in pts. - const Point* backup = pts[i]; - pts[i] = &p; - o[i] = orientation(*pts[0], *pts[1], *pts[2], *pts[3]); - if ( o[i] != NEGATIVE ) { - pts[i] = backup; - continue; + try_next_cell = true; + } + } + } // next vertex + } // next cell + + // now p is in c or on its boundary + int sum = ( o[0] == COPLANAR ) + + ( o[1] == COPLANAR ) + + ( o[2] == COPLANAR ) + + ( o[3] == COPLANAR ); + switch (sum) { + case 0: + { + lt = CELL; + break; } - if ( next->has_vertex(infinite, li) ) { - // We are outside the convex hull. - lt = OUTSIDE_CONVEX_HULL; - return next; - } - previous = c; - c = next; - goto try_next_cell; - } - - // now p is in c or on its boundary - int sum = ( o[0] == COPLANAR ) - + ( o[1] == COPLANAR ) - + ( o[2] == COPLANAR ) - + ( o[3] == COPLANAR ); - switch (sum) { - case 0: - { - lt = CELL; - break; - } - case 1: - { - lt = FACET; - li = ( o[0] == COPLANAR ) ? 0 : - ( o[1] == COPLANAR ) ? 1 : - ( o[2] == COPLANAR ) ? 2 : 3; - break; - } - case 2: - { - lt = EDGE; - li = ( o[0] != COPLANAR ) ? 0 : - ( o[1] != COPLANAR ) ? 1 : 2; - lj = ( o[li+1] != COPLANAR ) ? li+1 : - ( o[li+2] != COPLANAR ) ? li+2 : li+3; - CGAL_triangulation_assertion(collinear( p, - c->vertex( li )->point(), - c->vertex( lj )->point())); - break; - } - case 3: - { - lt = VERTEX; - li = ( o[0] != COPLANAR ) ? 0 : - ( o[1] != COPLANAR ) ? 1 : - ( o[2] != COPLANAR ) ? 2 : 3; - break; - } - } - return c; - } + case 1: + { + lt = FACET; + li = ( o[0] == COPLANAR ) ? 0 : + ( o[1] == COPLANAR ) ? 1 : + ( o[2] == COPLANAR ) ? 2 : 3; + break; + } + case 2: + { + lt = EDGE; + li = ( o[0] != COPLANAR ) ? 0 : + ( o[1] != COPLANAR ) ? 1 : 2; + lj = ( o[li+1] != COPLANAR ) ? li+1 : + ( o[li+2] != COPLANAR ) ? li+2 : li+3; + CGAL_triangulation_assertion(collinear( p, + c->vertex( li )->point(), + c->vertex( lj )->point())); + break; + } + case 3: + { + lt = VERTEX; + li = ( o[0] != COPLANAR ) ? 0 : + ( o[1] != COPLANAR ) ? 1 : + ( o[2] != COPLANAR ) ? 2 : 3; + break; + } + } + return c; + } + case 2: { CGAL_triangulation_precondition( start != Cell_handle() ); @@ -2025,80 +2666,80 @@ //first tests whether p is coplanar with the current triangulation if ( orientation( c->vertex(0)->point(), - c->vertex(1)->point(), - c->vertex(2)->point(), - p ) != DEGENERATE ) { - lt = OUTSIDE_AFFINE_HULL; - li = 3; // only one facet in dimension 2 - return c; + c->vertex(1)->point(), + c->vertex(2)->point(), + p ) != DEGENERATE ) { + lt = OUTSIDE_AFFINE_HULL; + li = 3; // only one facet in dimension 2 + return c; } // if p is coplanar, location in the triangulation // only the facet numbered 3 exists in each cell while (1) { - int inf; - if ( c->has_vertex(infinite,inf) ) { - // c must contain p in its interior - lt = OUTSIDE_CONVEX_HULL; - li = cw(inf); - lj = ccw(inf); - return c; - } - - // else c is finite - // we test its edges in a random order until we find a - // neighbor to go further - int i = die3(); - const Point & p0 = c->vertex( i )->point(); - const Point & p1 = c->vertex( ccw(i) )->point(); - const Point & p2 = c->vertex( cw(i) )->point(); + int inf; + if ( c->has_vertex(infinite,inf) ) { + // c must contain p in its interior + lt = OUTSIDE_CONVEX_HULL; + li = cw(inf); + lj = ccw(inf); + return c; + } + + // else c is finite + // we test its edges in a random order until we find a + // neighbor to go further + int i = die3(); + const Point & p0 = c->vertex( i )->point(); + const Point & p1 = c->vertex( ccw(i) )->point(); + const Point & p2 = c->vertex( cw(i) )->point(); Orientation o[3]; - CGAL_triangulation_assertion(coplanar_orientation(p0,p1,p2)==POSITIVE); - o[0] = coplanar_orientation(p0,p1,p); - if ( o[0] == NEGATIVE ) { - c = c->neighbor( cw(i) ); - continue; - } - o[1] = coplanar_orientation(p1,p2,p); - if ( o[1] == NEGATIVE ) { - c = c->neighbor( i ); - continue; - } - o[2] = coplanar_orientation(p2,p0,p); - if ( o[2] == NEGATIVE ) { - c = c->neighbor( ccw(i) ); - continue; - } - - // now p is in c or on its boundary - int sum = ( o[0] == COLLINEAR ) - + ( o[1] == COLLINEAR ) - + ( o[2] == COLLINEAR ); - switch (sum) { - case 0: - { - lt = FACET; - li = 3; // useless ? - break; - } - case 1: - { - lt = EDGE; - li = ( o[0] == COLLINEAR ) ? i : - ( o[1] == COLLINEAR ) ? ccw(i) : - cw(i); - lj = ccw(li); - break; - } - case 2: - { - lt = VERTEX; - li = ( o[0] != COLLINEAR ) ? cw(i) : - ( o[1] != COLLINEAR ) ? i : - ccw(i); - break; - } - } - return c; + CGAL_triangulation_assertion(coplanar_orientation(p0,p1,p2)==POSITIVE); + o[0] = coplanar_orientation(p0,p1,p); + if ( o[0] == NEGATIVE ) { + c = c->neighbor( cw(i) ); + continue; + } + o[1] = coplanar_orientation(p1,p2,p); + if ( o[1] == NEGATIVE ) { + c = c->neighbor( i ); + continue; + } + o[2] = coplanar_orientation(p2,p0,p); + if ( o[2] == NEGATIVE ) { + c = c->neighbor( ccw(i) ); + continue; + } + + // now p is in c or on its boundary + int sum = ( o[0] == COLLINEAR ) + + ( o[1] == COLLINEAR ) + + ( o[2] == COLLINEAR ); + switch (sum) { + case 0: + { + lt = FACET; + li = 3; // useless ? + break; + } + case 1: + { + lt = EDGE; + li = ( o[0] == COLLINEAR ) ? i : + ( o[1] == COLLINEAR ) ? ccw(i) : + cw(i); + lj = ccw(li); + break; + } + case 2: + { + lt = VERTEX; + li = ( o[0] != COLLINEAR ) ? cw(i) : + ( o[1] != COLLINEAR ) ? i : + ccw(i); + break; + } + } + return c; } } case 1: @@ -2109,55 +2750,55 @@ //first tests whether p is collinear with the current triangulation if ( ! collinear( p, - c->vertex(0)->point(), - c->vertex(1)->point()) ) { - lt = OUTSIDE_AFFINE_HULL; - return c; + c->vertex(0)->point(), + c->vertex(1)->point()) ) { + lt = OUTSIDE_AFFINE_HULL; + return c; } // if p is collinear, location : while (1) { - if ( c->has_vertex(infinite) ) { - // c must contain p in its interior - lt = OUTSIDE_CONVEX_HULL; - return c; - } - - // else c is finite - // we test on which direction to continue the traversal - switch (collinear_position(c->vertex(0)->point(), - p, - c->vertex(1)->point()) ) { - case AFTER: - c = c->neighbor(0); - continue; - case BEFORE: - c = c->neighbor(1); - continue; - case MIDDLE: - lt = EDGE; - li = 0; - lj = 1; - return c; - case SOURCE: - lt = VERTEX; - li = 0; - return c; - case TARGET: - lt = VERTEX; - li = 1; - return c; - } + if ( c->has_vertex(infinite) ) { + // c must contain p in its interior + lt = OUTSIDE_CONVEX_HULL; + return c; + } + + // else c is finite + // we test on which direction to continue the traversal + switch (collinear_position(c->vertex(0)->point(), + p, + c->vertex(1)->point()) ) { + case AFTER: + c = c->neighbor(0); + continue; + case BEFORE: + c = c->neighbor(1); + continue; + case MIDDLE: + lt = EDGE; + li = 0; + lj = 1; + return c; + case SOURCE: + lt = VERTEX; + li = 0; + return c; + case TARGET: + lt = VERTEX; + li = 1; + return c; + } } } case 0: { Finite_vertices_iterator vit = finite_vertices_begin(); if ( ! equal( p, vit->point() ) ) { - lt = OUTSIDE_AFFINE_HULL; + lt = OUTSIDE_AFFINE_HULL; } else { - lt = VERTEX; - li = 0; + lt = VERTEX; + li = 0; } return vit->cell(); } @@ -2175,20 +2816,34 @@ } #ifndef CGAL_NO_STRUCTURAL_FILTERING -template -inline -typename Triangulation_3::Cell_handle -Triangulation_3:: -inexact_locate(const Point & t, Cell_handle start, int n_of_turns) const +template +inline +typename Triangulation_3::Cell_handle +Triangulation_3:: +inexact_locate(const Point & t, Cell_handle start, int n_of_turns, + bool *could_lock_zone) const { CGAL_triangulation_expensive_assertion(start == Cell_handle() || tds().is_simplex(start) ); + if (could_lock_zone) + *could_lock_zone = true; + if(dimension() < 3) return start; // Make sure we continue from here with a finite cell. if ( start == Cell_handle() ) start = infinite_cell(); + // CJTODO: useless? + if (could_lock_zone) + { + if (!this->try_lock_cell(start)) + { + *could_lock_zone = false; + return Cell_handle(); + } + } + int ind_inf; if( start->has_vertex(infinite, ind_inf) ) start = start->neighbor(ind_inf); @@ -2203,6 +2858,15 @@ Cell_handle previous = Cell_handle(); Cell_handle c = start; + if (could_lock_zone) + { + if (!this->try_lock_cell(c)) + { + *could_lock_zone = false; + return Cell_handle(); + } + } + // Now treat the cell c. try_next_cell: @@ -2235,6 +2899,16 @@ } previous = c; c = next; + if (could_lock_zone) + { + //previous->unlock(); // DON'T do that, "c" may be in + // the same locking cell as "previous" + if (!this->try_lock_cell(c)) + { + *could_lock_zone = false; + return Cell_handle(); + } + } if(n_of_turns) goto try_next_cell; } @@ -2242,15 +2916,15 @@ } #endif // no CGAL_NO_STRUCTURAL_FILTERING -template < class GT, class Tds > +template < class GT, class Tds, class Lds > Bounded_side -Triangulation_3:: +Triangulation_3:: side_of_tetrahedron(const Point & p, - const Point & p0, - const Point & p1, - const Point & p2, - const Point & p3, - Locate_type & lt, int & i, int & j ) const + const Point & p0, + const Point & p1, + const Point & p2, + const Point & p3, + Locate_type & lt, int & i, int & j ) const // p0,p1,p2,p3 supposed to be non coplanar // tetrahedron p0,p1,p2,p3 is supposed to be well oriented // returns : @@ -2288,9 +2962,9 @@ lt = FACET; // i = index such that p lies on facet(i) i = ( o0 == ZERO ) ? 0 : - ( o1 == ZERO ) ? 1 : - ( o2 == ZERO ) ? 2 : - 3; + ( o1 == ZERO ) ? 1 : + ( o2 == ZERO ) ? 2 : + 3; return ON_BOUNDARY; } case 2: @@ -2299,13 +2973,13 @@ // i = smallest index such that p does not lie on facet(i) // i must be < 3 since p lies on 2 facets i = ( o0 == POSITIVE ) ? 0 : - ( o1 == POSITIVE ) ? 1 : - 2; + ( o1 == POSITIVE ) ? 1 : + 2; // j = larger index such that p not on facet(j) // j must be > 0 since p lies on 2 facets j = ( o3 == POSITIVE ) ? 3 : - ( o2 == POSITIVE ) ? 2 : - 1; + ( o2 == POSITIVE ) ? 2 : + 1; return ON_BOUNDARY; } case 3: @@ -2313,9 +2987,9 @@ lt = VERTEX; // i = index such that p does not lie on facet(i) i = ( o0 == POSITIVE ) ? 0 : - ( o1 == POSITIVE ) ? 1 : - ( o2 == POSITIVE ) ? 2 : - 3; + ( o1 == POSITIVE ) ? 1 : + ( o2 == POSITIVE ) ? 2 : + 3; return ON_BOUNDARY; } default: @@ -2327,12 +3001,12 @@ } } -template < class GT, class Tds > +template < class GT, class Tds, class Lds > Bounded_side -Triangulation_3:: +Triangulation_3:: side_of_cell(const Point & p, - Cell_handle c, - Locate_type & lt, int & i, int & j) const + Cell_handle c, + Locate_type & lt, int & i, int & j) const // returns // ON_BOUNDED_SIDE if p inside the cell // (for an infinite cell this means that p lies strictly in the half space @@ -2347,11 +3021,11 @@ CGAL_triangulation_precondition( dimension() == 3 ); if ( ! is_infinite(c) ) { return side_of_tetrahedron(p, - c->vertex(0)->point(), - c->vertex(1)->point(), - c->vertex(2)->point(), - c->vertex(3)->point(), - lt, i, j); + c->vertex(0)->point(), + c->vertex(1)->point(), + c->vertex(2)->point(), + c->vertex(3)->point(), + lt, i, j); } else { int inf = c->index(infinite); @@ -2368,69 +3042,69 @@ switch (o) { case POSITIVE: { - lt = CELL; - return ON_BOUNDED_SIDE; + lt = CELL; + return ON_BOUNDED_SIDE; } case NEGATIVE: return ON_UNBOUNDED_SIDE; case ZERO: { - // location in the finite facet - int i_f, j_f; - Bounded_side side = - side_of_triangle(p, v1->point(), v2->point(), v3->point(), - lt, i_f, j_f); - // lt need not be modified in most cases : - switch (side) { - case ON_BOUNDED_SIDE: - { - // lt == FACET ok - i = inf; - return ON_BOUNDARY; - } - case ON_BOUNDARY: - { - // lt == VERTEX OR EDGE ok - i = ( i_f == 0 ) ? ((inf+1)&3) : - ( i_f == 1 ) ? ((inf+2)&3) : - ((inf+3)&3); - if ( lt == EDGE ) { - j = (j_f == 0 ) ? ((inf+1)&3) : - ( j_f == 1 ) ? ((inf+2)&3) : - ((inf+3)&3); - } - return ON_BOUNDARY; - } - case ON_UNBOUNDED_SIDE: - { - // p lies on the plane defined by the finite facet - // lt must be initialized - return ON_UNBOUNDED_SIDE; - } - default: - { - CGAL_triangulation_assertion(false); - return ON_BOUNDARY; - } - } // switch side + // location in the finite facet + int i_f, j_f; + Bounded_side side = + side_of_triangle(p, v1->point(), v2->point(), v3->point(), + lt, i_f, j_f); + // lt need not be modified in most cases : + switch (side) { + case ON_BOUNDED_SIDE: + { + // lt == FACET ok + i = inf; + return ON_BOUNDARY; + } + case ON_BOUNDARY: + { + // lt == VERTEX OR EDGE ok + i = ( i_f == 0 ) ? ((inf+1)&3) : + ( i_f == 1 ) ? ((inf+2)&3) : + ((inf+3)&3); + if ( lt == EDGE ) { + j = (j_f == 0 ) ? ((inf+1)&3) : + ( j_f == 1 ) ? ((inf+2)&3) : + ((inf+3)&3); + } + return ON_BOUNDARY; + } + case ON_UNBOUNDED_SIDE: + { + // p lies on the plane defined by the finite facet + // lt must be initialized + return ON_UNBOUNDED_SIDE; + } + default: + { + CGAL_triangulation_assertion(false); + return ON_BOUNDARY; + } + } // switch side }// case ZERO default: { - CGAL_triangulation_assertion(false); - return ON_BOUNDARY; + CGAL_triangulation_assertion(false); + return ON_BOUNDARY; } } // switch o } // else infinite cell } // side_of_cell -template < class GT, class Tds > +template < class GT, class Tds, class Lds > Bounded_side -Triangulation_3:: +Triangulation_3:: side_of_triangle(const Point & p, - const Point & p0, - const Point & p1, - const Point & p2, - Locate_type & lt, int & i, int & j ) const + const Point & p0, + const Point & p1, + const Point & p2, + Locate_type & lt, int & i, int & j ) const // p0,p1,p2 supposed to define a plane // p supposed to lie on plane p0,p1,p2 // triangle p0,p1,p2 defines the orientation of the plane @@ -2471,20 +3145,20 @@ { lt = EDGE; i = ( o0 == ZERO ) ? 0 : - ( o1 == ZERO ) ? 1 : - 2; + ( o1 == ZERO ) ? 1 : + 2; if ( i == 2 ) - j=0; + j=0; else - j = i+1; + j = i+1; return ON_BOUNDARY; } case 2: { lt = VERTEX; i = ( o0 == o012 ) ? 2 : - ( o1 == o012 ) ? 0 : - 1; + ( o1 == o012 ) ? 0 : + 1; return ON_BOUNDARY; } default: @@ -2496,12 +3170,12 @@ } } -template < class GT, class Tds > +template < class GT, class Tds, class Lds > Bounded_side -Triangulation_3:: +Triangulation_3:: side_of_facet(const Point & p, - Cell_handle c, - Locate_type & lt, int & li, int & lj) const + Cell_handle c, + Locate_type & lt, int & li, int & lj) const // supposes dimension 2 otherwise does not work for infinite facets // returns : // ON_BOUNDED_SIDE if p inside the facet @@ -2526,10 +3200,10 @@ // c->vertex(2)->point) ); int i_t, j_t; Bounded_side side = side_of_triangle(p, - c->vertex(0)->point(), - c->vertex(1)->point(), - c->vertex(2)->point(), - lt, i_t, j_t); + c->vertex(0)->point(), + c->vertex(1)->point(), + c->vertex(2)->point(), + lt, i_t, j_t); // We protect the following code by this test to avoid valgrind messages. if (side == ON_BOUNDARY) { // indices in the original cell : @@ -2554,7 +3228,7 @@ v2 = c->vertex(i2); CGAL_triangulation_assertion(coplanar_orientation(v1->point(), v2->point(), - mirror_vertex(c, inf)->point()) == POSITIVE); + mirror_vertex(c, inf)->point()) == POSITIVE); switch (coplanar_orientation(v1->point(), v2->point(), p)) { case POSITIVE: @@ -2569,30 +3243,30 @@ // p collinear with v1v2 int i_e; switch (side_of_segment(p, v1->point(), v2->point(), lt, i_e)) { - // computation of the indices in the original cell + // computation of the indices in the original cell case ON_BOUNDED_SIDE: - // lt == EDGE ok - li = i1; - lj = i2; - return ON_BOUNDARY; + // lt == EDGE ok + li = i1; + lj = i2; + return ON_BOUNDARY; case ON_BOUNDARY: - // lt == VERTEX ok - li = ( i_e == 0 ) ? i1 : i2; - return ON_BOUNDARY; + // lt == VERTEX ok + li = ( i_e == 0 ) ? i1 : i2; + return ON_BOUNDARY; default: // case ON_UNBOUNDED_SIDE: - // p lies on the line defined by the finite edge - return ON_UNBOUNDED_SIDE; + // p lies on the line defined by the finite edge + return ON_UNBOUNDED_SIDE; } } } -template < class GT, class Tds > +template < class GT, class Tds, class Lds > Bounded_side -Triangulation_3:: +Triangulation_3:: side_of_segment(const Point & p, - const Point & p0, - const Point & p1, - Locate_type & lt, int & i ) const + const Point & p0, + const Point & p1, + Locate_type & lt, int & i ) const // p0, p1 supposed to be different // p supposed to be collinear to p0, p1 // returns : @@ -2621,12 +3295,12 @@ } } -template < class GT, class Tds > +template < class GT, class Tds, class Lds > Bounded_side -Triangulation_3:: +Triangulation_3:: side_of_edge(const Point & p, - Cell_handle c, - Locate_type & lt, int & li) const + Cell_handle c, + Locate_type & lt, int & li) const // supposes dimension 1 otherwise does not work for infinite edges // returns : // ON_BOUNDED_SIDE if p inside the edge @@ -2641,15 +3315,15 @@ CGAL_triangulation_precondition( dimension() == 1 ); if ( ! is_infinite(c,0,1) ) return side_of_segment(p, c->vertex(0)->point(), c->vertex(1)->point(), - lt, li); + lt, li); // else infinite edge int inf = c->index(infinite); switch (collinear_position(c->vertex(1-inf)->point(), p, - mirror_vertex(c, inf)->point())) { + mirror_vertex(c, inf)->point())) { case SOURCE: - lt = VERTEX; - li = 1-inf; - return ON_BOUNDARY; + lt = VERTEX; + li = 1-inf; + return ON_BOUNDARY; case BEFORE: lt = EDGE; return ON_BOUNDED_SIDE; @@ -2658,13 +3332,13 @@ } } -template < class GT, class Tds > +template < class GT, class Tds, class Lds > bool -Triangulation_3:: +Triangulation_3:: flip( Cell_handle c, int i ) { CGAL_triangulation_precondition( (dimension() == 3) && (0<=i) && (i<4) - && (number_of_vertices() >= 5) ); + && (number_of_vertices() >= 5) ); Cell_handle n = c->neighbor(i); int in = n->index(c); @@ -2672,104 +3346,104 @@ if ( i%2 == 1 ) { if ( orientation( c->vertex((i+1)&3)->point(), - c->vertex((i+2)&3)->point(), - n->vertex(in)->point(), - c->vertex(i)->point() ) - != POSITIVE ) return false; + c->vertex((i+2)&3)->point(), + n->vertex(in)->point(), + c->vertex(i)->point() ) + != POSITIVE ) return false; if ( orientation( c->vertex((i+2)&3)->point(), - c->vertex((i+3)&3)->point(), - n->vertex(in)->point(), - c->vertex(i)->point() ) - != POSITIVE ) return false; + c->vertex((i+3)&3)->point(), + n->vertex(in)->point(), + c->vertex(i)->point() ) + != POSITIVE ) return false; if ( orientation( c->vertex((i+3)&3)->point(), - c->vertex((i+1)&3)->point(), - n->vertex(in)->point(), - c->vertex(i)->point() ) - != POSITIVE ) return false; + c->vertex((i+1)&3)->point(), + n->vertex(in)->point(), + c->vertex(i)->point() ) + != POSITIVE ) return false; } else { if ( orientation( c->vertex((i+2)&3)->point(), - c->vertex((i+1)&3)->point(), - n->vertex(in)->point(), - c->vertex(i)->point() ) - != POSITIVE ) return false; + c->vertex((i+1)&3)->point(), + n->vertex(in)->point(), + c->vertex(i)->point() ) + != POSITIVE ) return false; if ( orientation( c->vertex((i+3)&3)->point(), - c->vertex((i+2)&3)->point(), - n->vertex(in)->point(), - c->vertex(i)->point() ) - != POSITIVE ) return false; + c->vertex((i+2)&3)->point(), + n->vertex(in)->point(), + c->vertex(i)->point() ) + != POSITIVE ) return false; if ( orientation( c->vertex((i+1)&3)->point(), - c->vertex((i+3)&3)->point(), - n->vertex(in)->point(), - c->vertex(i)->point() ) - != POSITIVE ) return false; + c->vertex((i+3)&3)->point(), + n->vertex(in)->point(), + c->vertex(i)->point() ) + != POSITIVE ) return false; } _tds.flip_flippable(c, i); return true; } -template < class GT, class Tds > +template < class GT, class Tds, class Lds > void -Triangulation_3:: +Triangulation_3:: flip_flippable( Cell_handle c, int i ) { CGAL_triangulation_precondition( (dimension() == 3) && (0<=i) && (i<4) - && (number_of_vertices() >= 5) ); + && (number_of_vertices() >= 5) ); CGAL_triangulation_precondition_code( Cell_handle n = c->neighbor(i); ); CGAL_triangulation_precondition_code( int in = n->index(c); ); CGAL_triangulation_precondition( ( ! is_infinite( c ) ) && - ( ! is_infinite( n ) ) ); + ( ! is_infinite( n ) ) ); if ( i%2 == 1 ) { CGAL_triangulation_precondition( orientation( c->vertex((i+1)&3)->point(), - c->vertex((i+2)&3)->point(), - n->vertex(in)->point(), - c->vertex(i)->point() ) - == POSITIVE ); + c->vertex((i+2)&3)->point(), + n->vertex(in)->point(), + c->vertex(i)->point() ) + == POSITIVE ); CGAL_triangulation_precondition( orientation( c->vertex((i+2)&3)->point(), - c->vertex((i+3)&3)->point(), - n->vertex(in)->point(), - c->vertex(i)->point() ) - == POSITIVE ); + c->vertex((i+3)&3)->point(), + n->vertex(in)->point(), + c->vertex(i)->point() ) + == POSITIVE ); CGAL_triangulation_precondition( orientation( c->vertex((i+3)&3)->point(), - c->vertex((i+1)&3)->point(), - n->vertex(in)->point(), - c->vertex(i)->point() ) - == POSITIVE ); + c->vertex((i+1)&3)->point(), + n->vertex(in)->point(), + c->vertex(i)->point() ) + == POSITIVE ); } else { CGAL_triangulation_precondition( orientation( c->vertex((i+2)&3)->point(), - c->vertex((i+1)&3)->point(), - n->vertex(in)->point(), - c->vertex(i)->point() ) - == POSITIVE ); + c->vertex((i+1)&3)->point(), + n->vertex(in)->point(), + c->vertex(i)->point() ) + == POSITIVE ); CGAL_triangulation_precondition( orientation( c->vertex((i+3)&3)->point(), - c->vertex((i+2)&3)->point(), - n->vertex(in)->point(), - c->vertex(i)->point() ) - == POSITIVE ); + c->vertex((i+2)&3)->point(), + n->vertex(in)->point(), + c->vertex(i)->point() ) + == POSITIVE ); CGAL_triangulation_precondition( orientation( c->vertex((i+1)&3)->point(), - c->vertex((i+3)&3)->point(), - n->vertex(in)->point(), - c->vertex(i)->point() ) - == POSITIVE ); + c->vertex((i+3)&3)->point(), + n->vertex(in)->point(), + c->vertex(i)->point() ) + == POSITIVE ); } _tds.flip_flippable(c, i); } -template < class GT, class Tds > +template < class GT, class Tds, class Lds > bool -Triangulation_3:: +Triangulation_3:: flip( Cell_handle c, int i, int j ) // flips edge i,j of cell c { CGAL_triangulation_precondition( (dimension() == 3) - && (0<=i) && (i<4) - && (0<=j) && (j<4) - && ( i != j ) - && (number_of_vertices() >= 5) ); + && (0<=i) && (i<4) + && (0<=j) && (j<4) + && ( i != j ) + && (number_of_vertices() >= 5) ); // checks that degree 3 and not on the convex hull int degree = 0; @@ -2788,33 +3462,33 @@ int in = n->index( c->vertex(i) ); int jn = n->index( c->vertex(j) ); if ( orientation( c->vertex(next_around_edge(i,j))->point(), - c->vertex(next_around_edge(j,i))->point(), - n->vertex(next_around_edge(jn,in))->point(), - c->vertex(j)->point() ) + c->vertex(next_around_edge(j,i))->point(), + n->vertex(next_around_edge(jn,in))->point(), + c->vertex(j)->point() ) != POSITIVE ) return false; if ( orientation( c->vertex(i)->point(), - c->vertex(next_around_edge(j,i))->point(), - n->vertex(next_around_edge(jn,in))->point(), - c->vertex(next_around_edge(i,j))->point() ) + c->vertex(next_around_edge(j,i))->point(), + n->vertex(next_around_edge(jn,in))->point(), + c->vertex(next_around_edge(i,j))->point() ) != POSITIVE ) return false; _tds.flip_flippable(c, i, j); return true; } -template < class GT, class Tds > +template < class GT, class Tds, class Lds > void -Triangulation_3:: +Triangulation_3:: flip_flippable( Cell_handle c, int i, int j ) // flips edge i,j of cell c { #if !defined CGAL_TRIANGULATION_NO_PRECONDITIONS && \ !defined CGAL_NO_PRECONDITIONS && !defined NDEBUG CGAL_triangulation_precondition( (dimension() == 3) - && (0<=i) && (i<4) - && (0<=j) && (j<4) - && ( i != j ) - && (number_of_vertices() >= 5) ); + && (0<=i) && (i<4) + && (0<=j) && (j<4) + && ( i != j ) + && (number_of_vertices() >= 5) ); int degree = 0; Cell_circulator ccir = incident_cells(c,i,j); Cell_circulator cdone = ccir; @@ -2830,21 +3504,21 @@ int jn = n->index( c->vertex(j) ); CGAL_triangulation_precondition ( orientation( c->vertex(next_around_edge(i,j))->point(), - c->vertex(next_around_edge(j,i))->point(), - n->vertex(next_around_edge(jn,in))->point(), - c->vertex(j)->point() ) == POSITIVE ); + c->vertex(next_around_edge(j,i))->point(), + n->vertex(next_around_edge(jn,in))->point(), + c->vertex(j)->point() ) == POSITIVE ); CGAL_triangulation_precondition ( orientation( c->vertex(i)->point(), - c->vertex(next_around_edge(j,i))->point(), - n->vertex(next_around_edge(jn,in))->point(), - c->vertex(next_around_edge(i,j))->point() ) == POSITIVE ); + c->vertex(next_around_edge(j,i))->point(), + n->vertex(next_around_edge(jn,in))->point(), + c->vertex(next_around_edge(i,j))->point() ) == POSITIVE ); #endif _tds.flip_flippable(c, i, j); } -template < class GT, class Tds > -typename Triangulation_3::Vertex_handle -Triangulation_3:: +template < class GT, class Tds, class Lds > +typename Triangulation_3::Vertex_handle +Triangulation_3:: insert(const Point & p, Cell_handle start) { Locate_type lt; @@ -2853,9 +3527,9 @@ return insert(p, lt, c, li, lj); } -template < class GT, class Tds > -typename Triangulation_3::Vertex_handle -Triangulation_3:: +template < class GT, class Tds, class Lds > +typename Triangulation_3::Vertex_handle +Triangulation_3:: insert(const Point & p, Locate_type lt, Cell_handle c, int li, int lj) { switch (lt) { @@ -2877,26 +3551,30 @@ -template < class GT, class Tds > +template < class GT, class Tds, class Lds > template < class Conflict_tester, class Hidden_points_visitor > -typename Triangulation_3::Vertex_handle -Triangulation_3:: +typename Triangulation_3::Vertex_handle +Triangulation_3:: insert_in_conflict(const Point & p, - Locate_type lt, Cell_handle c, int li, int /*lj*/, - const Conflict_tester &tester, - Hidden_points_visitor &hider) + Locate_type lt, Cell_handle c, int li, int /*lj*/, + const Conflict_tester &tester, + Hidden_points_visitor &hider, + bool *could_lock_zone) { + if (could_lock_zone) + *could_lock_zone = true; + switch (dimension()) { case 3: { if ((lt == VERTEX) && - (tester.compare_weight(c->vertex(li)->point(), p)==0) ) { - return c->vertex(li); + (tester.compare_weight(c->vertex(li)->point(), p)==0) ) { + return c->vertex(li); } // If the new point is not in conflict with its cell, it is hidden. if (!tester.test_initial_cell(c)) { - hider.hide_point(c,p); - return Vertex_handle(); + hider.hide_point(c,p); + return Vertex_handle(); } // Ok, we really insert the point now. @@ -2905,17 +3583,60 @@ Facet facet; cells.reserve(32); - find_conflicts - (c, tester, make_triple(Oneset_iterator(facet), - std::back_inserter(cells), - Emptyset_iterator())); + + // Parallel + if (could_lock_zone) + { + std::vector facets; + facets.reserve(32); + + find_conflicts( + c, + tester, + make_triple( + std::back_inserter(facets), + std::back_inserter(cells), + Emptyset_iterator()), + could_lock_zone); + + if (*could_lock_zone == false) + { + BOOST_FOREACH(Cell_handle& ch, + std::make_pair(cells.begin(), cells.end())) + { + ch->tds_data().clear(); + } + + BOOST_FOREACH(Facet& f, + std::make_pair(facets.begin(), facets.end())) + { + f.first->neighbor(f.second)->tds_data().clear(); + } + return Vertex_handle(); + } + + facet = facets.back(); + } + // Sequential + else + { + cells.reserve(32); + find_conflicts( + c, + tester, + make_triple( + Oneset_iterator(facet), + std::back_inserter(cells), + Emptyset_iterator())); + } + // Remember the points that are hidden by the conflicting cells, // as they will be deleted during the insertion. hider.process_cells_in_conflict(cells.begin(), cells.end()); Vertex_handle v = _insert_in_hole(p, cells.begin(), cells.end(), - facet.first, facet.second); + facet.first, facet.second); // Store the hidden points in their new cells. hider.reinsert_vertices(v); @@ -2925,16 +3646,16 @@ { // This check is added compared to the 3D case if (lt == OUTSIDE_AFFINE_HULL) - return insert_outside_affine_hull (p); + return insert_outside_affine_hull (p); if ((lt == VERTEX) && - (tester.compare_weight(c->vertex(li)->point(), p)==0) ) { - return c->vertex(li); + (tester.compare_weight(c->vertex(li)->point(), p)==0) ) { + return c->vertex(li); } // If the new point is not in conflict with its cell, it is hidden. if (!tester.test_initial_cell(c)) { - hider.hide_point(c,p); - return Vertex_handle(); + hider.hide_point(c,p); + return Vertex_handle(); } // Ok, we really insert the point now. @@ -2944,16 +3665,16 @@ cells.reserve(32); find_conflicts - (c, tester, make_triple(Oneset_iterator(facet), - std::back_inserter(cells), - Emptyset_iterator())); + (c, tester, make_triple(Oneset_iterator(facet), + std::back_inserter(cells), + Emptyset_iterator())); // Remember the points that are hidden by the conflicting cells, // as they will be deleted during the insertion. hider.process_cells_in_conflict(cells.begin(), cells.end()); Vertex_handle v = _insert_in_hole(p, cells.begin(), cells.end(), - facet.first, facet.second); + facet.first, facet.second); // Store the hidden points in their new cells. hider.reinsert_vertices(v); @@ -2963,21 +3684,21 @@ { // dimension() <= 1 if (lt == OUTSIDE_AFFINE_HULL) - return insert_outside_affine_hull (p); + return insert_outside_affine_hull (p); if (lt == VERTEX && - tester.compare_weight(c->vertex(li)->point(), p) == 0) { - return c->vertex(li); + tester.compare_weight(c->vertex(li)->point(), p) == 0) { + return c->vertex(li); } // If the new point is not in conflict with its cell, it is hidden. if (! tester.test_initial_cell(c)) { - hider.hide_point(c,p); - return Vertex_handle(); + hider.hide_point(c,p); + return Vertex_handle(); } if (dimension() == 0) { - return hider.replace_vertex(c, li, p); + return hider.replace_vertex(c, li, p); } @@ -2995,12 +3716,12 @@ cells.push_back(c); for (int j = 0; j<2; ++j) { - Cell_handle n = c->neighbor(j); - while ( tester(n) ) { - cells.push_back(n); - n = n->neighbor(j); - } - bound[j] = n; + Cell_handle n = c->neighbor(j); + while ( tester(n) ) { + cells.push_back(n); + n = n->neighbor(j); + } + bound[j] = n; } // Insertion. @@ -3027,9 +3748,9 @@ } } -template < class GT, class Tds > -typename Triangulation_3::Vertex_handle -Triangulation_3:: +template < class GT, class Tds, class Lds > +typename Triangulation_3::Vertex_handle +Triangulation_3:: insert_in_cell(const Point & p, Cell_handle c) { CGAL_triangulation_precondition( dimension() == 3 ); @@ -3038,54 +3759,54 @@ int i; int j; ); CGAL_triangulation_precondition ( side_of_tetrahedron( p, - c->vertex(0)->point(), - c->vertex(1)->point(), - c->vertex(2)->point(), - c->vertex(3)->point(), - lt,i,j ) == ON_BOUNDED_SIDE ); + c->vertex(0)->point(), + c->vertex(1)->point(), + c->vertex(2)->point(), + c->vertex(3)->point(), + lt,i,j ) == ON_BOUNDED_SIDE ); Vertex_handle v = _tds.insert_in_cell(c); v->set_point(p); return v; } -template < class GT, class Tds > +template < class GT, class Tds, class Lds > inline -typename Triangulation_3::Vertex_handle -Triangulation_3:: +typename Triangulation_3::Vertex_handle +Triangulation_3:: insert_in_facet(const Point & p, Cell_handle c, int i) { CGAL_triangulation_precondition( dimension() == 2 || dimension() == 3); CGAL_triangulation_precondition( (dimension() == 2 && i == 3) - || (dimension() == 3 && i >= 0 && i <= 3) ); + || (dimension() == 3 && i >= 0 && i <= 3) ); CGAL_triangulation_exactness_precondition_code ( Locate_type lt; int li; int lj; ); CGAL_triangulation_exactness_precondition ( coplanar( p, c->vertex((i+1)&3)->point(), - c->vertex((i+2)&3)->point(), - c->vertex((i+3)&3)->point() ) + c->vertex((i+2)&3)->point(), + c->vertex((i+3)&3)->point() ) && side_of_triangle( p, - c->vertex((i+1)&3)->point(), - c->vertex((i+2)&3)->point(), - c->vertex((i+3)&3)->point(), - lt, li, lj) == ON_BOUNDED_SIDE ); + c->vertex((i+1)&3)->point(), + c->vertex((i+2)&3)->point(), + c->vertex((i+3)&3)->point(), + lt, li, lj) == ON_BOUNDED_SIDE ); Vertex_handle v = _tds.insert_in_facet(c, i); v->set_point(p); return v; } -template < class GT, class Tds > -typename Triangulation_3::Vertex_handle -Triangulation_3:: +template < class GT, class Tds, class Lds > +typename Triangulation_3::Vertex_handle +Triangulation_3:: insert_in_edge(const Point & p, Cell_handle c, int i, int j) { CGAL_triangulation_precondition( i != j ); CGAL_triangulation_precondition( dimension() >= 1 && dimension() <= 3 ); CGAL_triangulation_precondition( i >= 0 && i <= dimension() - && j >= 0 && j <= dimension() ); + && j >= 0 && j <= dimension() ); CGAL_triangulation_exactness_precondition_code( Locate_type lt; int li; ); switch ( dimension() ) { case 3: @@ -3094,18 +3815,18 @@ CGAL_triangulation_precondition( ! is_infinite(c, i, j) ); CGAL_triangulation_exactness_precondition( collinear( c->vertex(i)->point(), - p, - c->vertex(j)->point() ) - && side_of_segment( p, - c->vertex(i)->point(), - c->vertex(j)->point(), - lt, li ) == ON_BOUNDED_SIDE ); + p, + c->vertex(j)->point() ) + && side_of_segment( p, + c->vertex(i)->point(), + c->vertex(j)->point(), + lt, li ) == ON_BOUNDED_SIDE ); break; } case 1: { CGAL_triangulation_exactness_precondition( side_of_edge(p, c, lt, li) - == ON_BOUNDED_SIDE ); + == ON_BOUNDED_SIDE ); break; } } @@ -3115,9 +3836,9 @@ return v; } -template < class GT, class Tds > -typename Triangulation_3::Vertex_handle -Triangulation_3:: +template < class GT, class Tds, class Lds > +typename Triangulation_3::Vertex_handle +Triangulation_3:: insert_outside_convex_hull(const Point & p, Cell_handle c) // c is an infinite cell containing p // p is strictly outside the convex hull @@ -3152,9 +3873,9 @@ } } -template < class GT, class Tds > -typename Triangulation_3::Vertex_handle -Triangulation_3:: +template < class GT, class Tds, class Lds > +typename Triangulation_3::Vertex_handle +Triangulation_3:: insert_outside_affine_hull(const Point & p) { CGAL_triangulation_precondition( dimension() < 3 ); @@ -3165,7 +3886,7 @@ Cell_handle c = infinite_cell(); Cell_handle n = c->neighbor(c->index(infinite_vertex())); Orientation o = coplanar_orientation(n->vertex(0)->point(), - n->vertex(1)->point(), p); + n->vertex(1)->point(), p); CGAL_triangulation_precondition ( o != COLLINEAR ); reorient = o == NEGATIVE; break; @@ -3175,8 +3896,8 @@ Cell_handle c = infinite_cell(); Cell_handle n = c->neighbor(c->index(infinite_vertex())); Orientation o = orientation( n->vertex(0)->point(), - n->vertex(1)->point(), - n->vertex(2)->point(), p ); + n->vertex(1)->point(), + n->vertex(2)->point(), p ); CGAL_triangulation_precondition ( o != COPLANAR ); reorient = o == NEGATIVE; break; @@ -3194,10 +3915,10 @@ return v; } -template < class GT, class Tds > +template < class GT, class Tds, class Lds > template < class OutputItCells > -typename Triangulation_3::Vertex_handle -Triangulation_3::insert_and_give_new_cells(const Point &p, +typename Triangulation_3::Vertex_handle +Triangulation_3::insert_and_give_new_cells(const Point &p, OutputItCells fit, Cell_handle start) { @@ -3211,8 +3932,8 @@ *fit++ = c; int i = c->index(v); c = c->neighbor((i+1)%3); - } while(c != end); - } + } while(c != end); + } else if(dimension == 1) { Cell_handle c = v->cell(); @@ -3220,13 +3941,13 @@ *fit++ = c->neighbor((~(c->index(v)))&1); } else *fit++ = v->cell(); // dimension = 0 - return v; + return v; } -template < class GT, class Tds > +template < class GT, class Tds, class Lds > template < class OutputItCells > -typename Triangulation_3::Vertex_handle -Triangulation_3::insert_and_give_new_cells(const Point& p, +typename Triangulation_3::Vertex_handle +Triangulation_3::insert_and_give_new_cells(const Point& p, OutputItCells fit, Vertex_handle hint) { @@ -3240,8 +3961,8 @@ *fit++ = c; int i = c->index(v); c = c->neighbor((i+1)%3); - } while(c != end); - } + } while(c != end); + } else if(dimension == 1) { Cell_handle c = v->cell(); @@ -3252,12 +3973,12 @@ return v; } -template < class GT, class Tds > +template < class GT, class Tds, class Lds > template < class OutputItCells > -typename Triangulation_3::Vertex_handle -Triangulation_3::insert_and_give_new_cells(const Point& p, +typename Triangulation_3::Vertex_handle +Triangulation_3::insert_and_give_new_cells(const Point& p, Locate_type lt, - Cell_handle c, int li, int lj, + Cell_handle c, int li, int lj, OutputItCells fit) { Vertex_handle v = insert(p, lt, c, li, lj); @@ -3270,21 +3991,21 @@ *fit++ = c; int i = c->index(v); c = c->neighbor((i+1)%3); - } while(c != end); - } + } while(c != end); + } else if(dimension == 1) { Cell_handle c = v->cell(); *fit++ = c; *fit++ = c->neighbor((~(c->index(v)))&1); } - else *fit++ = v->cell(); // dimension = 0 + else *fit++ = v->cell(); // dimension = 0 return v; } -template < class Gt, class Tds > -typename Triangulation_3::Vertex_triple -Triangulation_3:: +template +typename Triangulation_3::Vertex_triple +Triangulation_3:: make_vertex_triple(const Facet& f) const { Cell_handle ch = f.first; @@ -3295,16 +4016,16 @@ ch->vertex(vertex_triple_index(i,2))); } -template < class Gt, class Tds > +template void -Triangulation_3:: +Triangulation_3:: make_canonical(Vertex_triple& t) const { - int i = (&*(t.first) < &*(t.second))? 0 : 1; + int i = (t.first < t.second) ? 0 : 1; if(i==0) { - i = (&*(t.first) < &*(t.third))? 0 : 2; + i = (t.first < t.third) ? 0 : 2; } else { - i = (&*(t.second) < &*(t.third))? 1 : 2; + i = (t.second < t.third) ? 1 : 2; } Vertex_handle tmp; switch(i){ @@ -3323,9 +4044,9 @@ } } -template < class GT, class Tds > +template < class GT, class Tds, class Lds > bool -Triangulation_3:: +Triangulation_3:: test_dim_down(Vertex_handle v) const // tests whether removing v decreases the dimension of the triangulation // true iff @@ -3350,8 +4071,8 @@ if ( ! cit->has_vertex(v,iv) ) return false; for (int i=1; i<4; i++ ) - if ( !coplanar(p1,p2,p3,cit->vertex((iv+i)&3)->point()) ) - return false; + if ( !coplanar(p1,p2,p3,cit->vertex((iv+i)&3)->point()) ) + return false; } } else if (dimension() == 2) @@ -3369,25 +4090,81 @@ if ( ! cit->first->has_vertex(v,iv) ) return false; if ( !collinear(p1, p2, cit->first->vertex(cw(iv))->point()) || - !collinear(p1, p2, cit->first->vertex(ccw(iv))->point()) ) - return false; + !collinear(p1, p2, cit->first->vertex(ccw(iv))->point()) ) + return false; } } - else // dimension() == 1 or 0 - return number_of_vertices() == (size_type) dimension() + 1; + else // dimension() == 1 or 0 + return number_of_vertices() == (size_type) dimension() + 1; + + return true; +} + +template < class GT, class Tds, class Lds > +bool +Triangulation_3:: +test_dim_down_using_incident_cells_3( + Vertex_handle v, std::vector &incident_cells, + std::vector &adj_vertices, + bool *could_lock_zone) const +{ + CGAL_triangulation_precondition(dimension() == 3); + CGAL_triangulation_precondition(! is_infinite(v) ); + + // Collect all vertices on the boundary + // and all incident cells + if (could_lock_zone) + { + *could_lock_zone = try_lock_and_get_adjacent_vertices_and_cells_3( + v, std::back_inserter(adj_vertices), incident_cells); + if (*could_lock_zone == false) + return false; + } + else + { + adjacent_vertices_and_cells_3( + v, std::back_inserter(adj_vertices), incident_cells); + } + + typedef Filter_iterator< typename std::vector::const_iterator, + Infinite_tester + > Finite_vertex_iterator; + Finite_vertex_iterator vit( + adj_vertices.end(), Infinite_tester(this), adj_vertices.begin()); + Finite_vertex_iterator vit_end( + adj_vertices.end(), Infinite_tester(this)); + const Point &p1 = (*vit++)->point(); + const Point &p2 = (*vit++)->point(); + const Point &p3 = (*vit++)->point(); + + for ( ; vit != vit_end ; ++vit ) + { + if (!coplanar(p1, p2, p3, (*vit)->point())) + return false; + } + + for (typename std::vector::const_iterator it_inc_cell + = incident_cells.begin() ; + it_inc_cell != incident_cells.end() ; + ++it_inc_cell) + { + if (!is_infinite(*it_inc_cell)) + return is_infinite(mirror_vertex( + *it_inc_cell, (*it_inc_cell)->index(v))); + } return true; } -template +template template < class VertexRemover > VertexRemover& -Triangulation_3:: +Triangulation_3:: make_hole_2D(Vertex_handle v, std::list &hole, VertexRemover &remover) { std::vector to_delete; to_delete.reserve(32); - + Face_circulator fc = tds().incident_faces(v); Face_circulator done(fc); @@ -3417,10 +4194,10 @@ // this one also erases a set of cells // which is useful to the move method // outputting newly created cells -template +template template < class VertexRemover > VertexRemover& -Triangulation_3:: +Triangulation_3:: make_hole_2D(Vertex_handle v, std::list &hole, VertexRemover &remover, std::set &cells_set) { @@ -3456,10 +4233,10 @@ return remover; } -template +template template < class VertexRemover > void -Triangulation_3:: +Triangulation_3:: fill_hole_2D(std::list & first_hole, VertexRemover &remover) { typedef std::list Hole; @@ -3478,12 +4255,12 @@ // if the hole has only three edges, create the triangle if (hole.size() == 3) { - typename Hole::iterator hit = hole.begin(); - f = (*hit).first; i = (*hit).second; - ff = (* ++hit).first; ii = (*hit).second; - fn = (* ++hit).first; in = (*hit).second; - tds().create_face(f, i, ff, ii, fn, in); - continue; + typename Hole::iterator hit = hole.begin(); + f = (*hit).first; i = (*hit).second; + ff = (* ++hit).first; ii = (*hit).second; + fn = (* ++hit).first; in = (*hit).second; + tds().create_face(f, i, ff, ii, fn, in); + continue; } // else find an edge with two finite vertices @@ -3495,15 +4272,15 @@ // whose vertices on the hole boundary are finite // is the first of the hole while (1) { - ff = (hole.front()).first; - ii = (hole.front()).second; - if ( is_infinite(ff->vertex(cw(ii))) || - is_infinite(ff->vertex(ccw(ii)))) { + ff = (hole.front()).first; + ii = (hole.front()).second; + if ( is_infinite(ff->vertex(cw(ii))) || + is_infinite(ff->vertex(ccw(ii)))) { hole.push_back(hole.front()); hole.pop_front(); - } - else - break; + } + else + break; } // take the first neighboring face and pop it; @@ -3527,25 +4304,25 @@ // stop at the before last face; hdone--; for (; hit != hdone; ++hit) { - fn = hit->first; - in = hit->second; + fn = hit->first; + in = hit->second; Vertex_handle vv = fn->vertex(ccw(in)); - if (is_infinite(vv)) { - if (is_infinite(v2)) - cut_after = hit; - } - else { // vv is a finite vertex - const Point &p = vv->point(); - if (coplanar_orientation(p0, p1, p) == COUNTERCLOCKWISE) { - if (is_infinite(v2) || - remover.side_of_bounded_circle(p0, p1, *p2, p, true) - == ON_BOUNDED_SIDE) { - v2 = vv; - p2 = &p; - cut_after = hit; - } - } - } + if (is_infinite(vv)) { + if (is_infinite(v2)) + cut_after = hit; + } + else { // vv is a finite vertex + const Point &p = vv->point(); + if (coplanar_orientation(p0, p1, p) == COUNTERCLOCKWISE) { + if (is_infinite(v2) || + remover.side_of_bounded_circle(p0, p1, *p2, p, true) + == ON_BOUNDED_SIDE) { + v2 = vv; + p2 = &p; + cut_after = hit; + } + } + } } // create new triangle and update adjacency relations @@ -3559,44 +4336,44 @@ fn = (hole.front()).first; in = (hole.front()).second; if (fn->has_vertex(v2, i) && i == ccw(in)) { - newf = tds().create_face(ff, ii, fn, in); - hole.pop_front(); - hole.push_front(Edge_2D(newf, 1)); - hole_list.push_back(hole); + newf = tds().create_face(ff, ii, fn, in); + hole.pop_front(); + hole.push_front(Edge_2D(newf, 1)); + hole_list.push_back(hole); } else{ - fn = (hole.back()).first; - in = (hole.back()).second; - if (fn->has_vertex(v2, i) && i == cw(in)) { - newf = tds().create_face(fn, in, ff, ii); - hole.pop_back(); - hole.push_back(Edge_2D(newf, 1)); - hole_list.push_back(hole); - } - else{ - // split the hole in two holes - newf = tds().create_face(ff, ii, v2); - Hole new_hole; - ++cut_after; - while( hole.begin() != cut_after ) + fn = (hole.back()).first; + in = (hole.back()).second; + if (fn->has_vertex(v2, i) && i == cw(in)) { + newf = tds().create_face(fn, in, ff, ii); + hole.pop_back(); + hole.push_back(Edge_2D(newf, 1)); + hole_list.push_back(hole); + } + else{ + // split the hole in two holes + newf = tds().create_face(ff, ii, v2); + Hole new_hole; + ++cut_after; + while( hole.begin() != cut_after ) { new_hole.push_back(hole.front()); hole.pop_front(); } - hole.push_front(Edge_2D(newf, 1)); - new_hole.push_front(Edge_2D(newf, 0)); - hole_list.push_back(hole); - hole_list.push_back(new_hole); - } + hole.push_front(Edge_2D(newf, 1)); + new_hole.push_front(Edge_2D(newf, 0)); + hole_list.push_back(hole); + hole_list.push_back(new_hole); + } } } } -template +template template < class VertexRemover, class OutputItCells > void -Triangulation_3:: +Triangulation_3:: fill_hole_2D(std::list & first_hole, VertexRemover &remover, OutputItCells fit) { @@ -3731,12 +4508,12 @@ } } -template < class Gt, class Tds > +template void -Triangulation_3:: +Triangulation_3:: make_hole_3D( Vertex_handle v, - std::map& outer_map, - std::vector & hole) + Vertex_triple_Facet_map& outer_map, + std::vector & hole) { CGAL_triangulation_expensive_precondition( ! test_dim_down(v) ); @@ -3752,14 +4529,38 @@ outer_map[vt] = f; for (int i=0; i<4; i++) if ( i != indv ) - (*cit)->vertex(i)->set_cell(opp_cit); + (*cit)->vertex(i)->set_cell(opp_cit); + } +} + +// When the incident cells are already known +template +void +Triangulation_3:: +make_hole_3D( Vertex_handle v, + const std::vector & incident_cells, + Vertex_triple_Facet_map& outer_map) +{ + CGAL_triangulation_expensive_precondition( ! test_dim_down(v) ); + + for (typename std::vector::const_iterator cit = incident_cells.begin(), + end = incident_cells.end(); cit != end; ++cit) { + int indv = (*cit)->index(v); + Cell_handle opp_cit = (*cit)->neighbor( indv ); + Facet f(opp_cit, opp_cit->index(*cit)); + Vertex_triple vt = make_vertex_triple(f); + make_canonical(vt); + outer_map[vt] = f; + for (int i=0; i<4; i++) + if ( i != indv ) + (*cit)->vertex(i)->set_cell(opp_cit); } } -template < class Gt, class Tds > +template template < class VertexRemover > VertexRemover& -Triangulation_3:: +Triangulation_3:: remove_dim_down(Vertex_handle v, VertexRemover &remover) { CGAL_triangulation_precondition (dimension() >= 0); @@ -3783,10 +4584,10 @@ return remover; } -template < class Gt, class Tds > +template template < class VertexRemover > VertexRemover& -Triangulation_3:: +Triangulation_3:: remove_1D(Vertex_handle v, VertexRemover &remover) { CGAL_triangulation_precondition (dimension() == 1); @@ -3801,10 +4602,10 @@ return remover; } -template < class Gt, class Tds > +template template < class VertexRemover > VertexRemover& -Triangulation_3:: +Triangulation_3:: remove_2D(Vertex_handle v, VertexRemover &remover) { CGAL_triangulation_precondition(dimension() == 2); @@ -3815,10 +4616,10 @@ return remover; } -template < class Gt, class Tds > +template template < class VertexRemover > VertexRemover& -Triangulation_3:: +Triangulation_3:: remove_3D(Vertex_handle v, VertexRemover &remover) { std::vector hole; @@ -3826,7 +4627,6 @@ // Construct the set of vertex triples on the boundary // with the facet just behind - typedef std::map Vertex_triple_Facet_map; Vertex_triple_Facet_map outer_map; Vertex_triple_Facet_map inner_map; @@ -3840,7 +4640,6 @@ remover.add_hidden_points(*hi); bool inf = false; - unsigned int i; // collect all vertices on the boundary std::vector vertices; vertices.reserve(64); @@ -3851,9 +4650,49 @@ // and make a map from the vertices in remover.tmp towards the vertices // in *this - Unique_hash_map vmap; + unsigned int i = 0; + Vertex_handle_unique_hash_map vmap; Cell_handle ch = Cell_handle(); - for(i=0; i < vertices.size(); i++){ +#ifdef CGAL_TRIANGULATION_3_USE_THE_4_POINTS_CONSTRUCTOR + size_t num_vertices = vertices.size(); + if (num_vertices >= 5) + { + //std::random_shuffle(vertices.begin(), vertices.end()); + for (int j = 0 ; j < 4 ; ++j) + { + if (is_infinite(vertices[j])) + { + std::swap(vertices[j], vertices[4]); + break; + } + } + Orientation o = orientation( + vertices[0]->point(), + vertices[1]->point(), + vertices[2]->point(), + vertices[3]->point()); + + if (o == NEGATIVE) + std::swap(vertices[0], vertices[1]); + + if (o != ZERO) + { + Vertex_handle vh1, vh2, vh3, vh4; + remover.tmp.init_tds( + vertices[0]->point(), vertices[1]->point(), + vertices[2]->point(), vertices[3]->point(), + vh1, vh2, vh3, vh4); + ch = vh1->cell(); + vmap[vh1] = vertices[0]; + vmap[vh2] = vertices[1]; + vmap[vh3] = vertices[2]; + vmap[vh4] = vertices[3]; + i = 4; + } + } +#endif + + for(; i < vertices.size(); i++){ if(! is_infinite(vertices[i])){ Vertex_handle vh = remover.tmp.insert(vertices[i]->point(), ch); ch = vh->cell(); @@ -3878,24 +4717,24 @@ if(inf){ for(All_cells_iterator it = remover.tmp.all_cells_begin(), - end = remover.tmp.all_cells_end(); it != end; ++it){ + end = remover.tmp.all_cells_end(); it != end; ++it){ for(i=0; i < 4; i++){ - Facet f = std::pair(it,i); - Vertex_triple vt_aux = make_vertex_triple(f); - Vertex_triple vt(vmap[vt_aux.first],vmap[vt_aux.third],vmap[vt_aux.second]); - make_canonical(vt); - inner_map[vt]= f; + Facet f = std::pair(it,i); + Vertex_triple vt_aux = make_vertex_triple(f); + Vertex_triple vt(vmap[vt_aux.first],vmap[vt_aux.third],vmap[vt_aux.second]); + make_canonical(vt); + inner_map[vt]= f; } } } else { for(Finite_cells_iterator it = remover.tmp.finite_cells_begin(), - end = remover.tmp.finite_cells_end(); it != end; ++it){ + end = remover.tmp.finite_cells_end(); it != end; ++it){ for(i=0; i < 4; i++){ - Facet f = std::pair(it,i); - Vertex_triple vt_aux = make_vertex_triple(f); - Vertex_triple vt(vmap[vt_aux.first],vmap[vt_aux.third],vmap[vt_aux.second]); - make_canonical(vt); - inner_map[vt]= f; + Facet f = std::pair(it,i); + Vertex_triple vt_aux = make_vertex_triple(f); + Vertex_triple vt(vmap[vt_aux.first],vmap[vt_aux.third],vmap[vt_aux.second]); + make_canonical(vt); + inner_map[vt]= f; } } } @@ -3903,8 +4742,8 @@ while(! outer_map.empty()){ typename Vertex_triple_Facet_map::iterator oit = outer_map.begin(); while(is_infinite(oit->first.first) || - is_infinite(oit->first.second) || - is_infinite(oit->first.third)){ + is_infinite(oit->first.second) || + is_infinite(oit->first.third)){ ++oit; // otherwise the lookup in the inner_map fails // because the infinite vertices are different @@ -3923,7 +4762,7 @@ // create a new cell and glue it to the outer surface Cell_handle new_ch = tds().create_cell(); new_ch->set_vertices(vmap[i_ch->vertex(0)], vmap[i_ch->vertex(1)], - vmap[i_ch->vertex(2)], vmap[i_ch->vertex(3)]); + vmap[i_ch->vertex(2)], vmap[i_ch->vertex(3)]); o_ch->set_neighbor(o_i,new_ch); new_ch->set_neighbor(i_i, o_ch); @@ -3931,23 +4770,23 @@ // for the other faces check, if they can also be glued for(i = 0; i < 4; i++){ if(i != i_i){ - Facet f = std::pair(new_ch,i); - Vertex_triple vt = make_vertex_triple(f); - make_canonical(vt); - std::swap(vt.second,vt.third); - typename Vertex_triple_Facet_map::iterator oit2 = outer_map.find(vt); - if(oit2 == outer_map.end()){ - std::swap(vt.second,vt.third); - outer_map[vt]= f; - } else { - // glue the faces - typename Vertex_triple_Facet_map::value_type o_vt_f_pair2 = *oit2; - Cell_handle o_ch2 = o_vt_f_pair2.second.first; - int o_i2 = o_vt_f_pair2.second.second; - o_ch2->set_neighbor(o_i2,new_ch); - new_ch->set_neighbor(i, o_ch2); - outer_map.erase(oit2); - } + Facet f = std::pair(new_ch,i); + Vertex_triple vt = make_vertex_triple(f); + make_canonical(vt); + std::swap(vt.second,vt.third); + typename Vertex_triple_Facet_map::iterator oit2 = outer_map.find(vt); + if(oit2 == outer_map.end()){ + std::swap(vt.second,vt.third); + outer_map[vt]= f; + } else { + // glue the faces + typename Vertex_triple_Facet_map::value_type o_vt_f_pair2 = *oit2; + Cell_handle o_ch2 = o_vt_f_pair2.second.first; + int o_i2 = o_vt_f_pair2.second.second; + o_ch2->set_neighbor(o_i2,new_ch); + new_ch->set_neighbor(i, o_ch2); + outer_map.erase(oit2); + } } } outer_map.erase(oit); @@ -3958,10 +4797,186 @@ return remover; } -template < class Gt, class Tds > +template +template < class VertexRemover > +VertexRemover& +Triangulation_3:: +remove_3D(Vertex_handle v, VertexRemover &remover, + const std::vector &inc_cells, + std::vector &adj_vertices) +{ + // Construct the set of vertex triples on the boundary + // with the facet just behind + Vertex_triple_Facet_map outer_map; + Vertex_triple_Facet_map inner_map; + + make_hole_3D(v, inc_cells, outer_map); + + CGAL_assertion(remover.hidden_points_begin() == + remover.hidden_points_end() ); + + // Output the hidden points. + for (typename std::vector::const_iterator + hi = inc_cells.begin(), hend = inc_cells.end(); hi != hend; ++hi) + remover.add_hidden_points(*hi); + + bool inf = false; + + // create a Delaunay triangulation of the points on the boundary + // and make a map from the vertices in remover.tmp towards the vertices + // in *this + + unsigned int i = 0; + Vertex_handle_unique_hash_map vmap; + Cell_handle ch = Cell_handle(); +#ifdef CGAL_TRIANGULATION_3_USE_THE_4_POINTS_CONSTRUCTOR + size_t num_vertices = adj_vertices.size(); + if (num_vertices >= 5) + { + //std::random_shuffle(adj_vertices.begin(), adj_vertices.end()); + for (int j = 0 ; j < 4 ; ++j) + { + if (is_infinite(adj_vertices[j])) + { + std::swap(adj_vertices[j], adj_vertices[4]); + break; + } + } + Orientation o = orientation( + adj_vertices[0]->point(), + adj_vertices[1]->point(), + adj_vertices[2]->point(), + adj_vertices[3]->point()); + + if (o == NEGATIVE) + std::swap(adj_vertices[0], adj_vertices[1]); + + if (o != ZERO) + { + Vertex_handle vh1, vh2, vh3, vh4; + remover.tmp.init_tds( + adj_vertices[0]->point(), adj_vertices[1]->point(), + adj_vertices[2]->point(), adj_vertices[3]->point(), + vh1, vh2, vh3, vh4); + ch = vh1->cell(); + vmap[vh1] = adj_vertices[0]; + vmap[vh2] = adj_vertices[1]; + vmap[vh3] = adj_vertices[2]; + vmap[vh4] = adj_vertices[3]; + i = 4; + } + } +#endif + + for(; i < adj_vertices.size(); i++){ + if(! is_infinite(adj_vertices[i])){ + Vertex_handle vh = remover.tmp.insert(adj_vertices[i]->point(), ch); + ch = vh->cell(); + vmap[vh] = adj_vertices[i]; + }else { + inf = true; + } + } + + if(remover.tmp.dimension()==2){ + Vertex_handle fake_inf = remover.tmp.insert(v->point()); + vmap[fake_inf] = infinite_vertex(); + } else { + vmap[remover.tmp.infinite_vertex()] = infinite_vertex(); + } + + CGAL_triangulation_assertion(remover.tmp.dimension() == 3); + + // Construct the set of vertex triples of remover.tmp + // We reorient the vertex triple so that it matches those from outer_map + // Also note that we use the vertices of *this, not of remover.tmp + + if(inf){ + for(All_cells_iterator it = remover.tmp.all_cells_begin(), + end = remover.tmp.all_cells_end(); it != end; ++it){ + for(i=0; i < 4; i++){ + Facet f = std::pair(it,i); + Vertex_triple vt_aux = make_vertex_triple(f); + Vertex_triple vt(vmap[vt_aux.first],vmap[vt_aux.third],vmap[vt_aux.second]); + make_canonical(vt); + inner_map[vt]= f; + } + } + } else { + for(Finite_cells_iterator it = remover.tmp.finite_cells_begin(), + end = remover.tmp.finite_cells_end(); it != end; ++it){ + for(i=0; i < 4; i++){ + Facet f = std::pair(it,i); + Vertex_triple vt_aux = make_vertex_triple(f); + Vertex_triple vt(vmap[vt_aux.first],vmap[vt_aux.third],vmap[vt_aux.second]); + make_canonical(vt); + inner_map[vt]= f; + } + } + } + // Grow inside the hole, by extending the surface + while(! outer_map.empty()){ + typename Vertex_triple_Facet_map::iterator oit = outer_map.begin(); + while(is_infinite(oit->first.first) || + is_infinite(oit->first.second) || + is_infinite(oit->first.third)){ + ++oit; + // otherwise the lookup in the inner_map fails + // because the infinite vertices are different + } + typename Vertex_triple_Facet_map::value_type o_vt_f_pair = *oit; + Cell_handle o_ch = o_vt_f_pair.second.first; + unsigned int o_i = o_vt_f_pair.second.second; + + typename Vertex_triple_Facet_map::iterator iit = + inner_map.find(o_vt_f_pair.first); + CGAL_triangulation_assertion(iit != inner_map.end()); + typename Vertex_triple_Facet_map::value_type i_vt_f_pair = *iit; + Cell_handle i_ch = i_vt_f_pair.second.first; + unsigned int i_i = i_vt_f_pair.second.second; + + // create a new cell and glue it to the outer surface + Cell_handle new_ch = tds().create_cell(); + new_ch->set_vertices(vmap[i_ch->vertex(0)], vmap[i_ch->vertex(1)], + vmap[i_ch->vertex(2)], vmap[i_ch->vertex(3)]); + + o_ch->set_neighbor(o_i,new_ch); + new_ch->set_neighbor(i_i, o_ch); + + // for the other faces check, if they can also be glued + for(i = 0; i < 4; i++){ + if(i != i_i){ + Facet f = std::pair(new_ch,i); + Vertex_triple vt = make_vertex_triple(f); + make_canonical(vt); + std::swap(vt.second,vt.third); + typename Vertex_triple_Facet_map::iterator oit2 = outer_map.find(vt); + if(oit2 == outer_map.end()){ + std::swap(vt.second,vt.third); + outer_map[vt]= f; + } else { + // glue the faces + typename Vertex_triple_Facet_map::value_type o_vt_f_pair2 = *oit2; + Cell_handle o_ch2 = o_vt_f_pair2.second.first; + int o_i2 = o_vt_f_pair2.second.second; + o_ch2->set_neighbor(o_i2,new_ch); + new_ch->set_neighbor(i, o_ch2); + outer_map.erase(oit2); + } + } + } + outer_map.erase(oit); + } + tds().delete_vertex(v); + tds().delete_cells(inc_cells.begin(), inc_cells.end()); + + return remover; +} + +template template < class VertexRemover > void -Triangulation_3:: +Triangulation_3:: remove(Vertex_handle v, VertexRemover &remover) { CGAL_triangulation_precondition( v != Vertex_handle()); CGAL_triangulation_precondition( !is_infinite(v)); @@ -3981,25 +4996,85 @@ } } +template +template < class VertexRemover > +bool +Triangulation_3:: +remove(Vertex_handle v, VertexRemover &remover, bool *could_lock_zone) +{ + // N.B.: dimension doesn't need to be atomic since the parallel removal + // will never decrease the dimension (the last few removes are done + // sequentially) + CGAL_triangulation_precondition( v != Vertex_handle()); + CGAL_triangulation_precondition( !is_infinite(v)); + CGAL_triangulation_precondition( dimension() == 3); + CGAL_triangulation_expensive_precondition( tds().is_vertex(v) ); + +#ifdef CGAL_CONCURRENT_TRIANGULATION_3_PROFILING + static Profile_branch_counter_3 bcounter( + "early withdrawals / late withdrawals / successes [Delaunay_tri_3::remove]"); +#endif + + bool removed = true; + + // Locking vertex v is a good start + if (!this->try_lock_vertex(v)) + { + *could_lock_zone = false; +#ifdef CGAL_CONCURRENT_TRIANGULATION_3_PROFILING + bcounter.increment_branch_2(); // THIS is an early withdrawal! +#endif + } + else + { + std::vector incident_cells; + incident_cells.reserve(64); + std::vector adj_vertices; + adj_vertices.reserve(64); + bool dim_down = test_dim_down_using_incident_cells_3( + v, incident_cells, adj_vertices, could_lock_zone); + + if (*could_lock_zone) + { + if (dim_down) + removed = false; + else + remove_3D (v, remover, incident_cells, adj_vertices); + } + } + +#ifdef CGAL_CONCURRENT_TRIANGULATION_3_PROFILING + if (could_lock_zone) + { + if (*could_lock_zone) + ++bcounter; + else + bcounter.increment_branch_1(); // THIS is a late withdrawal! + } +#endif + + return removed; +} + // The remove here uses the remover, but // no function envolving hidden points // will be used in this internal version -template < class Gt, class Tds > +template template < class VertexRemover, class OutputItCells > VertexRemover& -Triangulation_3:: +Triangulation_3:: remove_dim_down(Vertex_handle v, VertexRemover &remover, OutputItCells fit) { remove_dim_down(v, remover); - for(All_cells_iterator afi = tds().raw_cells_begin(); - afi != tds().raw_cells_end(); + for(All_cells_iterator afi = tds().raw_cells_begin(); + afi != tds().raw_cells_end(); afi++) *fit++ = afi; return remover; } -template < class Gt, class Tds > +template template < class VertexRemover, class OutputItCells > VertexRemover& -Triangulation_3:: +Triangulation_3:: remove_1D(Vertex_handle v, VertexRemover &remover, OutputItCells fit) { Point p = v->point(); remove_1D(v, remover); @@ -4007,10 +5082,10 @@ return remover; } -template < class Gt, class Tds > +template template < class VertexRemover, class OutputItCells > VertexRemover& -Triangulation_3:: +Triangulation_3:: remove_2D(Vertex_handle v, VertexRemover &remover, OutputItCells fit) { CGAL_triangulation_precondition(dimension() == 2); std::list hole; @@ -4020,10 +5095,10 @@ return remover; } -template < class Gt, class Tds > +template template < class VertexRemover, class OutputItCells > VertexRemover& -Triangulation_3:: +Triangulation_3:: remove_3D(Vertex_handle v, VertexRemover &remover, OutputItCells fit) { CGAL_triangulation_precondition(dimension() == 3); @@ -4032,7 +5107,6 @@ // Construct the set of vertex triples on the boundary // with the facet just behind - typedef std::map Vertex_triple_Facet_map; Vertex_triple_Facet_map outer_map; Vertex_triple_Facet_map inner_map; @@ -4058,7 +5132,7 @@ // and make a map from the vertices in remover.tmp towards the vertices // in *this - Unique_hash_map vmap; + Vertex_handle_unique_hash_map vmap; Cell_handle ch = Cell_handle(); for(i=0; i < vertices.size(); i++){ if(! is_infinite(vertices[i])){ @@ -4088,23 +5162,23 @@ end = remover.tmp.all_cells_end(); it != end; ++it) { for(i=0; i < 4; i++){ - Facet f = std::pair(it,i); - Vertex_triple vt_aux = make_vertex_triple(f); - Vertex_triple vt(vmap[vt_aux.first],vmap[vt_aux.third],vmap[vt_aux.second]); - make_canonical(vt); - inner_map[vt]= f; + Facet f = std::pair(it,i); + Vertex_triple vt_aux = make_vertex_triple(f); + Vertex_triple vt(vmap[vt_aux.first],vmap[vt_aux.third],vmap[vt_aux.second]); + make_canonical(vt); + inner_map[vt]= f; } } } else { for(Finite_cells_iterator it = remover.tmp.finite_cells_begin(), - end = remover.tmp.finite_cells_end(); it != end; ++it) + end = remover.tmp.finite_cells_end(); it != end; ++it) { for(i=0; i < 4; i++){ - Facet f = std::pair(it,i); - Vertex_triple vt_aux = make_vertex_triple(f); - Vertex_triple vt(vmap[vt_aux.first],vmap[vt_aux.third],vmap[vt_aux.second]); - make_canonical(vt); - inner_map[vt]= f; + Facet f = std::pair(it,i); + Vertex_triple vt_aux = make_vertex_triple(f); + Vertex_triple vt(vmap[vt_aux.first],vmap[vt_aux.third],vmap[vt_aux.second]); + make_canonical(vt); + inner_map[vt]= f; } } } @@ -4112,8 +5186,8 @@ while(! outer_map.empty()){ typename Vertex_triple_Facet_map::iterator oit = outer_map.begin(); while(is_infinite(oit->first.first) || - is_infinite(oit->first.second) || - is_infinite(oit->first.third)){ + is_infinite(oit->first.second) || + is_infinite(oit->first.third)){ ++oit; // otherwise the lookup in the inner_map fails // because the infinite vertices are different @@ -4131,10 +5205,10 @@ // create a new cell and glue it to the outer surface Cell_handle new_ch = tds().create_cell(); - *fit++ = new_ch; + *fit++ = new_ch; new_ch->set_vertices(vmap[i_ch->vertex(0)], vmap[i_ch->vertex(1)], - vmap[i_ch->vertex(2)], vmap[i_ch->vertex(3)]); + vmap[i_ch->vertex(2)], vmap[i_ch->vertex(3)]); o_ch->set_neighbor(o_i,new_ch); new_ch->set_neighbor(i_i, o_ch); @@ -4142,23 +5216,23 @@ // for the other faces check, if they can also be glued for(i = 0; i < 4; i++){ if(i != i_i){ - Facet f = std::pair(new_ch,i); - Vertex_triple vt = make_vertex_triple(f); - make_canonical(vt); - std::swap(vt.second,vt.third); - typename Vertex_triple_Facet_map::iterator oit2 = outer_map.find(vt); - if(oit2 == outer_map.end()){ - std::swap(vt.second,vt.third); - outer_map[vt]= f; - } else { - // glue the faces - typename Vertex_triple_Facet_map::value_type o_vt_f_pair2 = *oit2; - Cell_handle o_ch2 = o_vt_f_pair2.second.first; - int o_i2 = o_vt_f_pair2.second.second; - o_ch2->set_neighbor(o_i2,new_ch); - new_ch->set_neighbor(i, o_ch2); - outer_map.erase(oit2); - } + Facet f = std::pair(new_ch,i); + Vertex_triple vt = make_vertex_triple(f); + make_canonical(vt); + std::swap(vt.second,vt.third); + typename Vertex_triple_Facet_map::iterator oit2 = outer_map.find(vt); + if(oit2 == outer_map.end()){ + std::swap(vt.second,vt.third); + outer_map[vt]= f; + } else { + // glue the faces + typename Vertex_triple_Facet_map::value_type o_vt_f_pair2 = *oit2; + Cell_handle o_ch2 = o_vt_f_pair2.second.first; + int o_i2 = o_vt_f_pair2.second.second; + o_ch2->set_neighbor(o_i2,new_ch); + new_ch->set_neighbor(i, o_ch2); + outer_map.erase(oit2); + } } } outer_map.erase(oit); @@ -4170,10 +5244,10 @@ } -template < class Gt, class Tds > +template template < class VertexRemover, class OutputItCells > void -Triangulation_3:: +Triangulation_3:: remove_and_give_new_cells(Vertex_handle v, VertexRemover &remover, OutputItCells fit) { CGAL_triangulation_precondition( v != Vertex_handle()); @@ -4194,21 +5268,21 @@ } } -// The VertexInserter is needed so as to +// The VertexInserter is needed so as to // allow us the usage of the insertion method // from the particular triangulation -template +template template < class VertexRemover, class VertexInserter > -typename Triangulation_3::Vertex_handle -Triangulation_3:: -move_if_no_collision(Vertex_handle v, const Point &p, +typename Triangulation_3::Vertex_handle +Triangulation_3:: +move_if_no_collision(Vertex_handle v, const Point &p, VertexRemover &remover, VertexInserter &inserter) { CGAL_assertion(remover.hidden_points_begin() == remover.hidden_points_end() ); CGAL_triangulation_precondition(!is_infinite(v)); if(v->point() == p) return v; const int dim = dimension(); - + // If displacements are known to be small // we might want to optimize by checking // whether there is a topological change @@ -4246,7 +5320,7 @@ } if((lt != OUTSIDE_AFFINE_HULL) && (dim == 1)) { - + if(loc->has_vertex(v)) { v->set_point(p); } else { @@ -4282,7 +5356,7 @@ int iinf; Cell_handle finf = infinite_vertex()->cell(), fdone; fdone = finf; - do { + do { iinf = finf->index(infinite_vertex()); if(!finf->has_vertex(v)) break; finf = finf->neighbor((iinf+1)%3); @@ -4298,23 +5372,23 @@ } } - if(((dim == 2) && (lt != OUTSIDE_AFFINE_HULL)) || + if(((dim == 2) && (lt != OUTSIDE_AFFINE_HULL)) || ((lt == OUTSIDE_AFFINE_HULL) && (dim == 1))) { - + // This is insert must be from Delaunay (or the particular trian.) // not Triangulation_3 ! Vertex_handle inserted = inserter.insert(p, lt, loc, li, lj); - + std::list hole; - make_hole_2D(v, hole, remover); + make_hole_2D(v, hole, remover); fill_hole_2D(hole, remover); - + // fixing pointer Cell_handle fc = inserted->cell(), done(fc); std::vector faces_pt; faces_pt.reserve(16); - do { + do { faces_pt.push_back(fc); fc = fc->neighbor((fc->index(inserted) + 1)%3); } while(fc != done); @@ -4345,9 +5419,9 @@ } int iinf = finf->index(infinite_vertex()); if(remover.tmp.coplanar(finf->vertex((iinf+1)&3)->point(), - finf->vertex((iinf+2)&3)->point(), - finf->vertex((iinf+3)&3)->point(), - p)) + finf->vertex((iinf+2)&3)->point(), + finf->vertex((iinf+3)&3)->point(), + p)) { v->set_point(p); _tds.decrease_dimension(loc, loc->index(v)); @@ -4362,7 +5436,7 @@ } // This is insert must be from Delaunay (or the particular trian.) - // not Triangulation_3 ! + // not Triangulation_3 ! Vertex_handle inserted = inserter.insert(p, lt, loc, li, lj); std::vector hole; @@ -4370,7 +5444,6 @@ // Construct the set of vertex triples on the boundary // with the facet just behind - typedef std::map Vertex_triple_Facet_map; Vertex_triple_Facet_map outer_map; Vertex_triple_Facet_map inner_map; @@ -4396,7 +5469,7 @@ // and make a map from the vertices in remover.tmp towards the vertices // in *this - Unique_hash_map vmap; + Vertex_handle_unique_hash_map vmap; Cell_handle ch = Cell_handle(); for(i=0; i < vertices.size(); i++){ if(! is_infinite(vertices[i])){ @@ -4425,22 +5498,22 @@ for(All_cells_iterator it = remover.tmp.all_cells_begin(), end = remover.tmp.all_cells_end(); it != end; ++it){ for(i=0; i < 4; i++){ - Facet f = std::pair(it,i); - Vertex_triple vt_aux = make_vertex_triple(f); - Vertex_triple vt(vmap[vt_aux.first],vmap[vt_aux.third],vmap[vt_aux.second]); - make_canonical(vt); - inner_map[vt]= f; + Facet f = std::pair(it,i); + Vertex_triple vt_aux = make_vertex_triple(f); + Vertex_triple vt(vmap[vt_aux.first],vmap[vt_aux.third],vmap[vt_aux.second]); + make_canonical(vt); + inner_map[vt]= f; } } } else { for(Finite_cells_iterator it = remover.tmp.finite_cells_begin(), end = remover.tmp.finite_cells_end(); it != end; ++it){ for(i=0; i < 4; i++){ - Facet f = std::pair(it,i); - Vertex_triple vt_aux = make_vertex_triple(f); - Vertex_triple vt(vmap[vt_aux.first],vmap[vt_aux.third],vmap[vt_aux.second]); - make_canonical(vt); - inner_map[vt]= f; + Facet f = std::pair(it,i); + Vertex_triple vt_aux = make_vertex_triple(f); + Vertex_triple vt(vmap[vt_aux.first],vmap[vt_aux.third],vmap[vt_aux.second]); + make_canonical(vt); + inner_map[vt]= f; } } } @@ -4448,8 +5521,8 @@ while(! outer_map.empty()){ typename Vertex_triple_Facet_map::iterator oit = outer_map.begin(); while(is_infinite(oit->first.first) || - is_infinite(oit->first.second) || - is_infinite(oit->first.third)){ + is_infinite(oit->first.second) || + is_infinite(oit->first.third)){ ++oit; // otherwise the lookup in the inner_map fails // because the infinite vertices are different @@ -4469,7 +5542,7 @@ Cell_handle new_ch = tds().create_cell(); new_ch->set_vertices(vmap[i_ch->vertex(0)], vmap[i_ch->vertex(1)], - vmap[i_ch->vertex(2)], vmap[i_ch->vertex(3)]); + vmap[i_ch->vertex(2)], vmap[i_ch->vertex(3)]); o_ch->set_neighbor(o_i,new_ch); new_ch->set_neighbor(i_i, o_ch); @@ -4477,23 +5550,23 @@ // for the other faces check, if they can also be glued for(i = 0; i < 4; i++){ if(i != i_i){ - Facet f = std::pair(new_ch,i); - Vertex_triple vt = make_vertex_triple(f); - make_canonical(vt); - std::swap(vt.second,vt.third); - typename Vertex_triple_Facet_map::iterator oit2 = outer_map.find(vt); - if(oit2 == outer_map.end()){ - std::swap(vt.second,vt.third); - outer_map[vt]= f; - } else { - // glue the faces - typename Vertex_triple_Facet_map::value_type o_vt_f_pair2 = *oit2; - Cell_handle o_ch2 = o_vt_f_pair2.second.first; - int o_i2 = o_vt_f_pair2.second.second; - o_ch2->set_neighbor(o_i2,new_ch); - new_ch->set_neighbor(i, o_ch2); - outer_map.erase(oit2); - } + Facet f = std::pair(new_ch,i); + Vertex_triple vt = make_vertex_triple(f); + make_canonical(vt); + std::swap(vt.second,vt.third); + typename Vertex_triple_Facet_map::iterator oit2 = outer_map.find(vt); + if(oit2 == outer_map.end()){ + std::swap(vt.second,vt.third); + outer_map[vt]= f; + } else { + // glue the faces + typename Vertex_triple_Facet_map::value_type o_vt_f_pair2 = *oit2; + Cell_handle o_ch2 = o_vt_f_pair2.second.first; + int o_i2 = o_vt_f_pair2.second.second; + o_ch2->set_neighbor(o_i2,new_ch); + new_ch->set_neighbor(i, o_ch2); + outer_map.erase(oit2); + } } } outer_map.erase(oit); @@ -4513,14 +5586,14 @@ tds().delete_vertex(inserted); tds().delete_cells(hole.begin(), hole.end()); return v; -} // end of Vertex_handle - // Triangulation_3:: +} // end of Vertex_handle + // Triangulation_3:: // move_if_no_collision(Vertex_handle,Point, VertexRemover, VertexInserter) -template +template template < class VertexRemover, class VertexInserter > -typename Triangulation_3::Vertex_handle -Triangulation_3:: +typename Triangulation_3::Vertex_handle +Triangulation_3:: move(Vertex_handle v, const Point &p, VertexRemover &remover, VertexInserter &inserter) { CGAL_assertion(remover.hidden_points_begin() == @@ -4535,21 +5608,21 @@ return v; } -// The VertexInserter is needed so as to +// The VertexInserter is needed so as to // allow us the usage of the insertion method // from the particular triangulation -template +template template < class VertexRemover, class VertexInserter, class OutputItCells > -typename Triangulation_3::Vertex_handle -Triangulation_3:: -move_if_no_collision_and_give_new_cells(Vertex_handle v, const Point &p, +typename Triangulation_3::Vertex_handle +Triangulation_3:: +move_if_no_collision_and_give_new_cells(Vertex_handle v, const Point &p, VertexRemover &remover, VertexInserter &inserter, OutputItCells fit) { CGAL_assertion(remover.hidden_points_begin() == remover.hidden_points_end() ); CGAL_triangulation_precondition(!is_infinite(v)); if(v->point() == p) return v; const int dim = dimension(); - + // If displacements are known to be small // we might want to optimize by checking // whether there is a topological change @@ -4562,7 +5635,7 @@ // However, a non-fully optimized but good version of // is_delaunay_after_displacement is provided as an internal method of // Delaunay_triangulation_3 (see the class for more details). - + Locate_type lt; int li, lj; Cell_handle loc = locate(p, lt, li, lj, v->cell()); @@ -4578,16 +5651,16 @@ if((lt == OUTSIDE_AFFINE_HULL) && (dim == 1) && (n_vertices == 3)) { v->set_point(p); - for(All_cells_iterator afi = tds().raw_cells_begin(); - afi != tds().raw_cells_end(); + for(All_cells_iterator afi = tds().raw_cells_begin(); + afi != tds().raw_cells_end(); afi++) *fit++ = afi; return v; } if((lt == OUTSIDE_AFFINE_HULL) && (dim == 2) && (n_vertices == 4)) { v->set_point(p); - for(All_cells_iterator afi = tds().raw_cells_begin(); - afi != tds().raw_cells_end(); + for(All_cells_iterator afi = tds().raw_cells_begin(); + afi != tds().raw_cells_end(); afi++) *fit++ = afi; return v; } @@ -4620,9 +5693,9 @@ tds().delete_vertex(inserted); } *fit++ = v->cell(); - if(v->cell()->neighbor(0)->has_vertex(v)) + if(v->cell()->neighbor(0)->has_vertex(v)) *fit++ = v->cell()->neighbor(0); - if(v->cell()->neighbor(1)->has_vertex(v)) + if(v->cell()->neighbor(1)->has_vertex(v)) *fit++ = v->cell()->neighbor(1); return v; } @@ -4634,7 +5707,7 @@ int iinf; Cell_handle finf = infinite_vertex()->cell(), fdone; fdone = finf; - do { + do { iinf = finf->index(infinite_vertex()); if(!finf->has_vertex(v)) break; finf = finf->neighbor((iinf+1)%3); @@ -4646,37 +5719,37 @@ { v->set_point(p); _tds.decrease_dimension(loc, loc->index(v)); - for(All_cells_iterator afi = tds().raw_cells_begin(); - afi != tds().raw_cells_end(); + for(All_cells_iterator afi = tds().raw_cells_begin(); + afi != tds().raw_cells_end(); afi++) *fit++ = afi; return v; } } - if(((dim == 2) && (lt != OUTSIDE_AFFINE_HULL)) || + if(((dim == 2) && (lt != OUTSIDE_AFFINE_HULL)) || ((lt == OUTSIDE_AFFINE_HULL) && (dim == 1))) { - + std::set cells_set; // This is insert must be from Delaunay (or the particular trian.) // not Triangulation_3 ! Vertex_handle inserted = inserter.insert(p, lt, loc, li, lj); Cell_handle c = inserted->cell(), end = c; - do { - cells_set.insert(c); - int i = c->index(inserted); - c = c->neighbor((i+1)%3); + do { + cells_set.insert(c); + int i = c->index(inserted); + c = c->neighbor((i+1)%3); } while(c != end); - + std::list hole; make_hole_2D(v, hole, remover, cells_set); fill_hole_2D(hole, remover, fit); - + // fixing pointer Cell_handle fc = inserted->cell(), done(fc); std::vector faces_pt; faces_pt.reserve(16); - do { + do { faces_pt.push_back(fc); fc = fc->neighbor((fc->index(inserted) + 1)%3); } while(fc != done); @@ -4691,9 +5764,9 @@ v->set_cell(inserted->cell()); tds().delete_vertex(inserted); - + for(typename std::set::const_iterator ib = cells_set.begin(), - iend = cells_set.end(); ib != iend; ib++) *fit++ = *ib; + iend = cells_set.end(); ib != iend; ib++) *fit++ = *ib; return v; } @@ -4710,9 +5783,9 @@ } int iinf = finf->index(infinite_vertex()); if(remover.tmp.coplanar(finf->vertex((iinf+1)&3)->point(), - finf->vertex((iinf+2)&3)->point(), - finf->vertex((iinf+3)&3)->point(), - p)) + finf->vertex((iinf+2)&3)->point(), + finf->vertex((iinf+3)&3)->point(), + p)) { v->set_point(p); _tds.decrease_dimension(loc, loc->index(v)); @@ -4722,8 +5795,8 @@ f.first->vertex(2)->point()) == NEGATIVE) tds().reorient(); restore_edges_after_decrease_dimension(v, remover,inserter); - for(All_cells_iterator afi = tds().raw_cells_begin(); - afi != tds().raw_cells_end(); + for(All_cells_iterator afi = tds().raw_cells_begin(); + afi != tds().raw_cells_end(); afi++) *fit++ = afi; return v; } @@ -4732,7 +5805,7 @@ std::set cells_set; // This is insert must be from Delaunay (or the particular trian.) - // not Triangulation_3 ! + // not Triangulation_3 ! Vertex_handle inserted = inserter.insert(p, lt, loc, li, lj); std::vector cells_tmp; @@ -4748,14 +5821,13 @@ // Construct the set of vertex triples on the boundary // with the facet just behind - typedef std::map Vertex_triple_Facet_map; Vertex_triple_Facet_map outer_map; Vertex_triple_Facet_map inner_map; make_hole_3D(v, outer_map, hole); - + for(typename std::vector::const_iterator ib = hole.begin(), - iend = hole.end(); ib != iend; ib++) cells_set.erase(*ib); + iend = hole.end(); ib != iend; ib++) cells_set.erase(*ib); CGAL_assertion(remover.hidden_points_begin() == remover.hidden_points_end() ); @@ -4777,7 +5849,7 @@ // and make a map from the vertices in remover.tmp towards the vertices // in *this - Unique_hash_map vmap; + Vertex_handle_unique_hash_map vmap; Cell_handle ch = Cell_handle(); for(i=0; i < vertices.size(); i++){ if(! is_infinite(vertices[i])){ @@ -4806,22 +5878,22 @@ for(All_cells_iterator it = remover.tmp.all_cells_begin(), end = remover.tmp.all_cells_end(); it != end; ++it){ for(i=0; i < 4; i++){ - Facet f = std::pair(it,i); - Vertex_triple vt_aux = make_vertex_triple(f); - Vertex_triple vt(vmap[vt_aux.first],vmap[vt_aux.third],vmap[vt_aux.second]); - make_canonical(vt); - inner_map[vt]= f; + Facet f = std::pair(it,i); + Vertex_triple vt_aux = make_vertex_triple(f); + Vertex_triple vt(vmap[vt_aux.first],vmap[vt_aux.third],vmap[vt_aux.second]); + make_canonical(vt); + inner_map[vt]= f; } } } else { for(Finite_cells_iterator it = remover.tmp.finite_cells_begin(), end = remover.tmp.finite_cells_end(); it != end; ++it){ for(i=0; i < 4; i++){ - Facet f = std::pair(it,i); - Vertex_triple vt_aux = make_vertex_triple(f); - Vertex_triple vt(vmap[vt_aux.first],vmap[vt_aux.third],vmap[vt_aux.second]); - make_canonical(vt); - inner_map[vt]= f; + Facet f = std::pair(it,i); + Vertex_triple vt_aux = make_vertex_triple(f); + Vertex_triple vt(vmap[vt_aux.first],vmap[vt_aux.third],vmap[vt_aux.second]); + make_canonical(vt); + inner_map[vt]= f; } } } @@ -4829,8 +5901,8 @@ while(! outer_map.empty()){ typename Vertex_triple_Facet_map::iterator oit = outer_map.begin(); while(is_infinite(oit->first.first) || - is_infinite(oit->first.second) || - is_infinite(oit->first.third)){ + is_infinite(oit->first.second) || + is_infinite(oit->first.third)){ ++oit; // otherwise the lookup in the inner_map fails // because the infinite vertices are different @@ -4849,9 +5921,9 @@ // create a new cell and glue it to the outer surface Cell_handle new_ch = tds().create_cell(); *fit++ = new_ch; - + new_ch->set_vertices(vmap[i_ch->vertex(0)], vmap[i_ch->vertex(1)], - vmap[i_ch->vertex(2)], vmap[i_ch->vertex(3)]); + vmap[i_ch->vertex(2)], vmap[i_ch->vertex(3)]); o_ch->set_neighbor(o_i,new_ch); new_ch->set_neighbor(i_i, o_ch); @@ -4859,23 +5931,23 @@ // for the other faces check, if they can also be glued for(i = 0; i < 4; i++){ if(i != i_i){ - Facet f = std::pair(new_ch,i); - Vertex_triple vt = make_vertex_triple(f); - make_canonical(vt); - std::swap(vt.second,vt.third); - typename Vertex_triple_Facet_map::iterator oit2 = outer_map.find(vt); - if(oit2 == outer_map.end()){ - std::swap(vt.second,vt.third); - outer_map[vt]= f; - } else { - // glue the faces - typename Vertex_triple_Facet_map::value_type o_vt_f_pair2 = *oit2; - Cell_handle o_ch2 = o_vt_f_pair2.second.first; - int o_i2 = o_vt_f_pair2.second.second; - o_ch2->set_neighbor(o_i2,new_ch); - new_ch->set_neighbor(i, o_ch2); - outer_map.erase(oit2); - } + Facet f = std::pair(new_ch,i); + Vertex_triple vt = make_vertex_triple(f); + make_canonical(vt); + std::swap(vt.second,vt.third); + typename Vertex_triple_Facet_map::iterator oit2 = outer_map.find(vt); + if(oit2 == outer_map.end()){ + std::swap(vt.second,vt.third); + outer_map[vt]= f; + } else { + // glue the faces + typename Vertex_triple_Facet_map::value_type o_vt_f_pair2 = *oit2; + Cell_handle o_ch2 = o_vt_f_pair2.second.first; + int o_i2 = o_vt_f_pair2.second.second; + o_ch2->set_neighbor(o_i2,new_ch); + new_ch->set_neighbor(i, o_ch2); + outer_map.erase(oit2); + } } } outer_map.erase(oit); @@ -4894,37 +5966,37 @@ v->set_cell(inserted->cell()); tds().delete_vertex(inserted); tds().delete_cells(hole.begin(), hole.end()); - + for(typename std::set::const_iterator ib = cells_set.begin(), iend = cells_set.end(); ib != iend; ib++) *fit++ = *ib; return v; } -template < class Gt, class Tds > +template void -Triangulation_3:: +Triangulation_3:: _make_big_hole_3D( Vertex_handle v, std::map& outer_map, std::vector & hole, std::vector & vertices, std::map &vstates) { - + Cell_handle start = v->cell(); start->tds_data().mark_processed(); hole.push_back(start); std::size_t i=0, n=1; while(i < n) { - + Cell_handle c = hole[i++]; - + for(int k=0; k<4; k++) { Vertex_handle v0 = c->vertex(k); - + const REMOVE_VERTEX_STATE vst = vstates[v0]; - + if(vst == CLEAR) { vstates[v0] = EXTREMITY; @@ -4932,46 +6004,46 @@ } else if(vst == TO_REMOVE) { // we mark the vertices, so all the vertices // from the same cluster will be skipped - // in the remove_cluster_3D function + // in the remove_cluster_3D function vstates[v0] = PROCESSED; } - + int i1 = vertex_triple_index(k, 0); int i2 = vertex_triple_index(k, 1); int i3 = vertex_triple_index(k, 2); - + Vertex_handle v1 = c->vertex(i1); Vertex_handle v2 = c->vertex(i2); Vertex_handle v3 = c->vertex(i3); - + Cell_handle opp_cit = c->neighbor(k); int opp_i = tds().mirror_index(c,k); Vertex_handle vm = opp_cit->vertex(opp_i); - + bool pb1 = false, pb2 = false, pb3 = false, pbm = false; - + const REMOVE_VERTEX_STATE vst1 = vstates[v1]; pb1 = vst1 == TO_REMOVE || vst1 == PROCESSED; - + if(!pb1) { const REMOVE_VERTEX_STATE vst2 = vstates[v2]; pb2 = vst2 == TO_REMOVE || vst2 == PROCESSED; - + if(!pb2) { const REMOVE_VERTEX_STATE vst3 = vstates[v3]; pb3 = vst3 == TO_REMOVE || vst3 == PROCESSED; - + if(!pb3) { const REMOVE_VERTEX_STATE vstm = vstates[vm]; pbm = vstm == TO_REMOVE || vstm == PROCESSED; } - + } - + } bool bad_opposite_cell = pb1 || pb2 || pb3 || pbm; - + // update the hole if needed // when the vertex is not to be removed if(bad_opposite_cell) @@ -4993,32 +6065,32 @@ v2->set_cell(opp_cit); v3->set_cell(opp_cit); vm->set_cell(opp_cit); - + } } - + std::size_t vsize = vertices.size(); for(std::size_t i=0; i +template template < class InputIterator, class VertexRemover > bool -Triangulation_3:: +Triangulation_3:: _remove_cluster_3D(InputIterator first, InputIterator beyond, VertexRemover &remover, std::map &vstates) { InputIterator init = first; while(first != beyond) { Vertex_handle v = *first++; - + if(vstates[v] == PROCESSED) continue; - + // _make_big_hole_3D and we fill the hole for each cluster vstates[v] = PROCESSED; - + // here, we make the hole for the cluster with v inside typedef std::map Vertex_triple_Facet_map; std::vector hole; @@ -5027,7 +6099,7 @@ vertices.reserve(32); Vertex_triple_Facet_map outer_map; _make_big_hole_3D(v, outer_map, hole, vertices, vstates); - + // the connectivity is totally lost, we need to rebuild if(!outer_map.size()) { @@ -5035,14 +6107,14 @@ for(std::size_t i=0; itds_data().clear(); return false; } - + std::size_t vsi = vertices.size(); - + bool inf = false; std::size_t i; - Unique_hash_map vmap; + Vertex_handle_unique_hash_map vmap; Cell_handle ch = Cell_handle(); - + if(vsi > 100) { // spatial sort if too many points @@ -5057,14 +6129,14 @@ } else inf = true; } spatial_sort(vps.begin(), vps.end()); - + std::size_t svps = vps.size(); - + for(i=0; i < svps; i++){ Vertex_handle vv = mp_vps[vps[i]]; Vertex_handle vh = remover.tmp.insert(vv->point(), ch); ch = vh->cell(); - vmap[vh] = vv; + vmap[vh] = vv; } if(remover.tmp.dimension()==2){ @@ -5074,14 +6146,14 @@ vmap[remover.tmp.infinite_vertex()] = this->infinite_vertex(); } } else { - + for(i=0; i < vsi; i++){ if(!this->is_infinite(vertices[i])){ Vertex_handle vh = remover.tmp.insert(vertices[i]->point(), ch); ch = vh->cell(); - vmap[vh] = vertices[i]; + vmap[vh] = vertices[i]; } else { - inf = true; + inf = true; } } @@ -5092,9 +6164,9 @@ vmap[remover.tmp.infinite_vertex()] = this->infinite_vertex(); } } - + Vertex_triple_Facet_map inner_map; - + if(inf){ for(All_cells_iterator it = remover.tmp.all_cells_begin(), end = remover.tmp.all_cells_end(); it != end; ++it){ @@ -5122,7 +6194,7 @@ // Grow inside the hole, by extending the surface while(! outer_map.empty()){ typename Vertex_triple_Facet_map::iterator oit = outer_map.begin(); - + while(this->is_infinite(oit->first.first) || this->is_infinite(oit->first.second) || this->is_infinite(oit->first.third)){ @@ -5148,9 +6220,9 @@ o_ch->set_neighbor(o_i,new_ch); new_ch->set_neighbor(i_i, o_ch); - + for(int j=0;j<4;j++) new_ch->vertex(j)->set_cell(new_ch); - + // for the other faces check, if they can also be glued for(unsigned int index = 0; index < 4; index++){ if(index != i_i){ @@ -5176,40 +6248,40 @@ outer_map.erase(oit); } - + this->tds().delete_cells(hole.begin(), hole.end()); remover.tmp.clear(); } - + this->tds().delete_vertices(init, beyond); - + return true; } -template < class Gt, class Tds > +template template < class InputIterator > -bool -Triangulation_3:: +bool +Triangulation_3:: does_repeat_in_range(InputIterator first, InputIterator beyond) const { std::set s; while (first!=beyond) if (! s.insert(*first++).second ) return true; return false; } -template < class Gt, class Tds > +template template < class InputIterator > -bool -Triangulation_3:: +bool +Triangulation_3:: infinite_vertex_in_range(InputIterator first, InputIterator beyond) const { while(first != beyond) if(is_infinite(*first++)) return true; return false; } -template < class Gt, class Tds > +template template < class InputIterator, class VertexRemover > -typename Triangulation_3::size_type -Triangulation_3:: +typename Triangulation_3::size_type +Triangulation_3:: remove(InputIterator first, InputIterator beyond, VertexRemover &remover) { CGAL_triangulation_precondition(!does_repeat_in_range(first, beyond)); CGAL_triangulation_precondition(!infinite_vertex_in_range(first, beyond)); @@ -5239,21 +6311,21 @@ return n - number_of_vertices(); } -template < class GT, class Tds > +template < class GT, class Tds, class Lds > bool -Triangulation_3:: +Triangulation_3:: is_valid(bool verbose, int level) const { if ( ! _tds.is_valid(verbose,level) ) { if (verbose) - std::cerr << "invalid data structure" << std::endl; + std::cerr << "invalid data structure" << std::endl; CGAL_triangulation_assertion(false); return false; } if ( infinite_vertex() == Vertex_handle() ) { if (verbose) - std::cerr << "no infinite vertex" << std::endl; + std::cerr << "no infinite vertex" << std::endl; CGAL_triangulation_assertion(false); return false; } @@ -5262,22 +6334,22 @@ case 3: { for(Finite_cells_iterator it = finite_cells_begin(), end = finite_cells_end(); - it != end; ++it) - is_valid_finite(it, verbose, level); + it != end; ++it) + is_valid_finite(it, verbose, level); break; } case 2: { for(Finite_facets_iterator it = finite_facets_begin(), end = finite_facets_end(); - it != end; ++it) - is_valid_finite(it->first,verbose,level); + it != end; ++it) + is_valid_finite(it->first,verbose,level); break; } case 1: { for(Finite_edges_iterator it = finite_edges_begin(), end = finite_edges_end(); - it != end; ++it) - is_valid_finite(it->first,verbose,level); + it != end; ++it) + is_valid_finite(it->first,verbose,level); break; } } @@ -5286,16 +6358,16 @@ return true; } -template < class GT, class Tds > +template < class GT, class Tds, class Lds > bool -Triangulation_3:: +Triangulation_3:: is_valid(Cell_handle c, bool verbose, int level) const { if ( ! _tds.is_valid(c,verbose,level) ) { if (verbose) { std::cerr << "combinatorially invalid cell"; for (int i=0; i <= dimension(); i++ ) - std::cerr << c->vertex(i)->point() << ", "; + std::cerr << c->vertex(i)->point() << ", "; std::cerr << std::endl; } CGAL_triangulation_assertion(false); @@ -5309,42 +6381,42 @@ } -template < class GT, class Tds > +template < class GT, class Tds, class Lds > bool -Triangulation_3:: +Triangulation_3:: is_valid_finite(Cell_handle c, bool verbose, int) const { switch ( dimension() ) { case 3: { if ( orientation(c->vertex(0)->point(), - c->vertex(1)->point(), - c->vertex(2)->point(), - c->vertex(3)->point()) != POSITIVE ) { - if (verbose) - std::cerr << "badly oriented cell " - << c->vertex(0)->point() << ", " - << c->vertex(1)->point() << ", " - << c->vertex(2)->point() << ", " - << c->vertex(3)->point() << std::endl; - CGAL_triangulation_assertion(false); - return false; + c->vertex(1)->point(), + c->vertex(2)->point(), + c->vertex(3)->point()) != POSITIVE ) { + if (verbose) + std::cerr << "badly oriented cell " + << c->vertex(0)->point() << ", " + << c->vertex(1)->point() << ", " + << c->vertex(2)->point() << ", " + << c->vertex(3)->point() << std::endl; + CGAL_triangulation_assertion(false); + return false; } break; } case 2: { - if (coplanar_orientation(c->vertex(0)->point(), - c->vertex(1)->point(), - c->vertex(2)->point()) != POSITIVE) { - if (verbose) - std::cerr << "badly oriented face " - << c->vertex(0)->point() << ", " - << c->vertex(1)->point() << ", " - << c->vertex(2)->point() << std::endl; - CGAL_triangulation_assertion(false); - return false; - } + if (coplanar_orientation(c->vertex(0)->point(), + c->vertex(1)->point(), + c->vertex(2)->point()) != POSITIVE) { + if (verbose) + std::cerr << "badly oriented face " + << c->vertex(0)->point() << ", " + << c->vertex(1)->point() << ", " + << c->vertex(2)->point() << std::endl; + CGAL_triangulation_assertion(false); + return false; + } break; } case 1: @@ -5355,33 +6427,33 @@ Vertex_handle v = c->neighbor(0)->vertex(c->neighbor(0)->index(c)); if ( ! is_infinite(v) ) { - if ( collinear_position(p0, p1, v->point()) != MIDDLE ) { - if (verbose) - std::cerr << "badly oriented edge " - << p0 << ", " << p1 << std::endl - << "with neighbor 0" - << c->neighbor(0)->vertex(1-c->neighbor(0)->index(c)) - ->point() - << ", " << v->point() << std::endl; - CGAL_triangulation_assertion(false); - return false; - } + if ( collinear_position(p0, p1, v->point()) != MIDDLE ) { + if (verbose) + std::cerr << "badly oriented edge " + << p0 << ", " << p1 << std::endl + << "with neighbor 0" + << c->neighbor(0)->vertex(1-c->neighbor(0)->index(c)) + ->point() + << ", " << v->point() << std::endl; + CGAL_triangulation_assertion(false); + return false; + } } v = c->neighbor(1)->vertex(c->neighbor(1)->index(c)); if ( ! is_infinite(v) ) { - if ( collinear_position(p1, p0, v->point()) != MIDDLE ) { - if (verbose) - std::cerr << "badly oriented edge " - << p0 << ", " << p1 << std::endl - << "with neighbor 1" - << c->neighbor(1)->vertex(1-c->neighbor(1)->index(c)) - ->point() - << ", " << v->point() << std::endl; - CGAL_triangulation_assertion(false); - return false; - } + if ( collinear_position(p1, p0, v->point()) != MIDDLE ) { + if (verbose) + std::cerr << "badly oriented edge " + << p0 << ", " << p1 << std::endl + << "with neighbor 1" + << c->neighbor(1)->vertex(1-c->neighbor(1)->index(c)) + ->point() + << ", " << v->point() << std::endl; + CGAL_triangulation_assertion(false); + return false; + } } break; } @@ -5393,16 +6465,16 @@ namespace internal { // Internal function used by operator==. -template < class GT, class Tds1, class Tds2 > +template < class GT, class Tds1, class Tds2, class Lds > bool -test_next(const Triangulation_3 &t1, - const Triangulation_3 &t2, - typename Triangulation_3::Cell_handle c1, - typename Triangulation_3::Cell_handle c2, - std::map::Cell_handle, - typename Triangulation_3::Cell_handle> &Cmap, - std::map::Vertex_handle, - typename Triangulation_3::Vertex_handle> &Vmap) +test_next(const Triangulation_3 &t1, + const Triangulation_3 &t2, + typename Triangulation_3::Cell_handle c1, + typename Triangulation_3::Cell_handle c2, + std::map::Cell_handle, + typename Triangulation_3::Cell_handle> &Cmap, + std::map::Vertex_handle, + typename Triangulation_3::Vertex_handle> &Vmap) { // This function tests and registers the 4 neighbors of c1/c2, @@ -5419,8 +6491,8 @@ CGAL_triangulation_precondition(t1.dimension() == 2 || Vmap.find(c1->vertex(3)) != Vmap.end()); - typedef Triangulation_3 Tr1; - typedef Triangulation_3 Tr2; + typedef Triangulation_3 Tr1; + typedef Triangulation_3 Tr2; typedef typename Tr1::Vertex_handle Vertex_handle1; typedef typename Tr1::Cell_handle Cell_handle1; typedef typename Tr2::Vertex_handle Vertex_handle2; @@ -5439,17 +6511,17 @@ cell_stack.pop_back(); for (int i=0; i <= t1.dimension(); ++i) { - Cell_handle1 n1 = c1->neighbor(i); - Cit cit = Cmap.find(n1); - Vertex_handle1 v1 = c1->vertex(i); - Vertex_handle2 v2 = Vmap[v1]; - Cell_handle2 n2 = c2->neighbor(c2->index(v2)); - if (cit != Cmap.end()) { + Cell_handle1 n1 = c1->neighbor(i); + Cit cit = Cmap.find(n1); + Vertex_handle1 v1 = c1->vertex(i); + Vertex_handle2 v2 = Vmap[v1]; + Cell_handle2 n2 = c2->neighbor(c2->index(v2)); + if (cit != Cmap.end()) { // n1 was already registered. if (cit->second != n2) - return false; + return false; continue; - } + } // n1 has not yet been registered. // We check that the new vertices match geometrically. // And we register them. @@ -5484,10 +6556,10 @@ } // namespace internal -template < class GT, class Tds1, class Tds2 > +template < class GT, class Tds1, class Tds2, class Lds > bool -operator==(const Triangulation_3 &t1, - const Triangulation_3 &t2) +operator==(const Triangulation_3 &t1, + const Triangulation_3 &t2) { typedef typename Triangulation_3::Vertex_handle Vertex_handle1; typedef typename Triangulation_3::Cell_handle Cell_handle1; @@ -5506,7 +6578,7 @@ if (t1.dimension() != t2.dimension() || t1.number_of_vertices() != t2.number_of_vertices() || t1.number_of_cells() != t2.number_of_cells()) - return false; + return false; int dim = t1.dimension(); // Special case for dimension < 1. @@ -5549,60 +6621,60 @@ std::vector ics; t2.incident_cells(iv2, std::back_inserter(ics)); for (typename std::vector::const_iterator cit = ics.begin(); - cit != ics.end(); ++cit) { - int inf = (*cit)->index(iv2); + cit != ics.end(); ++cit) { + int inf = (*cit)->index(iv2); - if (equal(p2, (*cit)->vertex((inf+1)%(dim+1))->point())) - Vmap.insert(std::make_pair(v2, (*cit)->vertex((inf+1)%(dim+1)))); - else if (equal(p2, (*cit)->vertex((inf+2)%(dim+1))->point())) - Vmap.insert(std::make_pair(v2, (*cit)->vertex((inf+2)%(dim+1)))); - else if (dim == 3 && + if (equal(p2, (*cit)->vertex((inf+1)%(dim+1))->point())) + Vmap.insert(std::make_pair(v2, (*cit)->vertex((inf+1)%(dim+1)))); + else if (equal(p2, (*cit)->vertex((inf+2)%(dim+1))->point())) + Vmap.insert(std::make_pair(v2, (*cit)->vertex((inf+2)%(dim+1)))); + else if (dim == 3 && equal(p2, (*cit)->vertex((inf+3)%(dim+1))->point())) - Vmap.insert(std::make_pair(v2, (*cit)->vertex((inf+3)%(dim+1)))); - else - continue; // None matched v2. - - if (equal(p3, (*cit)->vertex((inf+1)%(dim+1))->point())) - Vmap.insert(std::make_pair(v3, (*cit)->vertex((inf+1)%(dim+1)))); - else if (equal(p3, (*cit)->vertex((inf+2)%(dim+1))->point())) - Vmap.insert(std::make_pair(v3, (*cit)->vertex((inf+2)%(dim+1)))); - else if (dim == 3 && + Vmap.insert(std::make_pair(v2, (*cit)->vertex((inf+3)%(dim+1)))); + else + continue; // None matched v2. + + if (equal(p3, (*cit)->vertex((inf+1)%(dim+1))->point())) + Vmap.insert(std::make_pair(v3, (*cit)->vertex((inf+1)%(dim+1)))); + else if (equal(p3, (*cit)->vertex((inf+2)%(dim+1))->point())) + Vmap.insert(std::make_pair(v3, (*cit)->vertex((inf+2)%(dim+1)))); + else if (dim == 3 && equal(p3, (*cit)->vertex((inf+3)%(dim+1))->point())) - Vmap.insert(std::make_pair(v3, (*cit)->vertex((inf+3)%(dim+1)))); - else - continue; // None matched v3. + Vmap.insert(std::make_pair(v3, (*cit)->vertex((inf+3)%(dim+1)))); + else + continue; // None matched v3. if (dim == 3) { - if (equal(p4, (*cit)->vertex((inf+1)%(dim+1))->point())) - Vmap.insert(std::make_pair(v4, + if (equal(p4, (*cit)->vertex((inf+1)%(dim+1))->point())) + Vmap.insert(std::make_pair(v4, (*cit)->vertex((inf+1)%(dim+1)))); - else if (equal(p4, (*cit)->vertex((inf+2)%(dim+1))->point())) - Vmap.insert(std::make_pair(v4, + else if (equal(p4, (*cit)->vertex((inf+2)%(dim+1))->point())) + Vmap.insert(std::make_pair(v4, (*cit)->vertex((inf+2)%(dim+1)))); - else if (equal(p4, (*cit)->vertex((inf+3)%(dim+1))->point())) - Vmap.insert(std::make_pair(v4, + else if (equal(p4, (*cit)->vertex((inf+3)%(dim+1))->point())) + Vmap.insert(std::make_pair(v4, (*cit)->vertex((inf+3)%(dim+1)))); - else - continue; // None matched v4. + else + continue; // None matched v4. } - // Found it ! - Cmap.insert(std::make_pair(c, *cit)); - break; + // Found it ! + Cmap.insert(std::make_pair(c, *cit)); + break; } if (Cmap.size() == 0) - return false; + return false; // We now have one cell, we need to propagate recursively. return internal::test_next(t1, t2, - Cmap.begin()->first, Cmap.begin()->second, Cmap, Vmap); + Cmap.begin()->first, Cmap.begin()->second, Cmap, Vmap); } template < class GT, class Tds1, class Tds2 > inline bool operator!=(const Triangulation_3 &t1, - const Triangulation_3 &t2) + const Triangulation_3 &t2) { return ! (t1 == t2); } diff -Nru cgal-4.4/include/CGAL/Triangulation_cell_base_3.h cgal-4.5/include/CGAL/Triangulation_cell_base_3.h --- cgal-4.4/include/CGAL/Triangulation_cell_base_3.h 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/include/CGAL/Triangulation_cell_base_3.h 2014-08-29 13:58:17.000000000 +0000 @@ -67,6 +67,9 @@ Point_iterator hidden_points_end() const { return NULL; } void hide_point (const Point &) const { } + // note the circumcenter() function is not part of the concept TriangulationCellBase_3 + // it is requested only by DelaunayTriangulartionCellBase_3 + // we keep it here for backward compatibility typename Geom_traits::Point_3 circumcenter(const Geom_traits& gt = Geom_traits()) const { diff -Nru cgal-4.4/include/CGAL/Triangulation_cell_base_with_circumcenter_3.h cgal-4.5/include/CGAL/Triangulation_cell_base_with_circumcenter_3.h --- cgal-4.4/include/CGAL/Triangulation_cell_base_with_circumcenter_3.h 2013-12-21 20:00:22.000000000 +0000 +++ cgal-4.5/include/CGAL/Triangulation_cell_base_with_circumcenter_3.h 2014-08-29 13:58:17.000000000 +0000 @@ -24,13 +24,19 @@ #ifndef CGAL_TRIANGULATION_CELL_BASE_WITH_CIRCUMCENTER_3_H #define CGAL_TRIANGULATION_CELL_BASE_WITH_CIRCUMCENTER_3_H +#define CGAL_DEPRECATED_HEADER \ + "" +#define CGAL_REPLACEMENT_HEADER \ + "" +#include + #include #include -#include +#include namespace CGAL { -template < typename GT, typename Cb = Triangulation_ds_cell_base_3<> > +template < typename GT, typename Cb = Triangulation_cell_base_3 > class Triangulation_cell_base_with_circumcenter_3 : public Cb { @@ -76,12 +82,12 @@ } Triangulation_cell_base_with_circumcenter_3( - Vertex_handle v0, Vertex_handle v1, + Vertex_handle v0, Vertex_handle v1, Vertex_handle v2, Vertex_handle v3) : Cb(v0, v1, v2, v3), circumcenter_(NULL) {} Triangulation_cell_base_with_circumcenter_3( - Vertex_handle v0, Vertex_handle v1, + Vertex_handle v0, Vertex_handle v1, Vertex_handle v2, Vertex_handle v3, Cell_handle n0, Cell_handle n1, Cell_handle n2, Cell_handle n3) @@ -118,17 +124,10 @@ circumcenter(const Geom_traits& gt = Geom_traits()) const { if (circumcenter_ == NULL) { - circumcenter_ = new Point_3( - gt.construct_circumcenter_3_object()(this->vertex(0)->point(), - this->vertex(1)->point(), - this->vertex(2)->point(), - this->vertex(3)->point())); + circumcenter_ = new Point_3(this->Cb::circumcenter(gt)); } else { - CGAL_expensive_assertion(gt.construct_circumcenter_3_object() - (this->vertex(0)->point(), - this->vertex(1)->point(), - this->vertex(2)->point(), - this->vertex(3)->point()) == *circumcenter); + CGAL_expensive_assertion( + this->Cb::circumcenter(gt) == *circumcenter); } return *circumcenter_; diff -Nru cgal-4.4/include/CGAL/Triangulation_data_structure_3.h cgal-4.5/include/CGAL/Triangulation_data_structure_3.h --- cgal-4.4/include/CGAL/Triangulation_data_structure_3.h 2013-07-06 19:00:27.000000000 +0000 +++ cgal-4.5/include/CGAL/Triangulation_data_structure_3.h 2014-08-29 13:58:17.000000000 +0000 @@ -33,6 +33,7 @@ #include #include +#include #include #include @@ -40,6 +41,7 @@ #include #include +#include #include #include @@ -50,32 +52,46 @@ #include #ifdef CGAL_HAS_THREADS -# include +# ifdef CGAL_LINKED_WITH_TBB +# include +# else +# include +# endif #endif +#ifdef CGAL_LINKED_WITH_TBB +# include +#endif + +#include +#include namespace CGAL { // TODO : noms : Vb != Vertex_base : clarifier. template < class Vb = Triangulation_ds_vertex_base_3<>, - class Cb = Triangulation_ds_cell_base_3<> > + class Cb = Triangulation_ds_cell_base_3<>, + class Concurrency_tag_ = Sequential_tag +> class Triangulation_data_structure_3 : public Triangulation_utils_3 { - typedef Triangulation_data_structure_3 Tds; + typedef Triangulation_data_structure_3 Tds; public: + typedef Concurrency_tag_ Concurrency_tag; + // Tools to change the Vertex and Cell types of the TDS. template < typename Vb2 > struct Rebind_vertex { - typedef Triangulation_data_structure_3 Other; + typedef Triangulation_data_structure_3 Other; }; template < typename Cb2 > struct Rebind_cell { - typedef Triangulation_data_structure_3 Other; + typedef Triangulation_data_structure_3 Other; }; // Put this TDS inside the Vertex and Cell types. @@ -107,10 +123,36 @@ friend class internal::Triangulation_ds_facet_circulator_3; public: + + // Cells + // N.B.: Concurrent_compact_container requires TBB +#ifdef CGAL_LINKED_WITH_TBB + typedef typename boost::mpl::if_c + < + boost::is_convertible::value, + Concurrent_compact_container >, + Compact_container + >::type Cell_range; + +# else + typedef Compact_container Cell_range; +#endif - typedef Compact_container Cell_range; - typedef Compact_container Vertex_range; + // Vertices + // N.B.: Concurrent_compact_container requires TBB +#ifdef CGAL_LINKED_WITH_TBB + typedef typename boost::mpl::if_c + < + boost::is_convertible::value, + Concurrent_compact_container >, + Compact_container + >::type Vertex_range; +# else + typedef Compact_container Vertex_range; +#endif + + typedef typename Cell_range::size_type size_type; typedef typename Cell_range::difference_type difference_type; @@ -236,15 +278,15 @@ } Cell_handle create_cell(Vertex_handle v0, Vertex_handle v1, - Vertex_handle v2, Vertex_handle v3) + Vertex_handle v2, Vertex_handle v3) { return cells().emplace(v0, v1, v2, v3); } Cell_handle create_cell(Vertex_handle v0, Vertex_handle v1, - Vertex_handle v2, Vertex_handle v3, - Cell_handle n0, Cell_handle n1, - Cell_handle n2, Cell_handle n3) + Vertex_handle v2, Vertex_handle v3, + Cell_handle n0, Cell_handle n1, + Cell_handle n2, Cell_handle n3) { return cells().emplace(v0, v1, v2, v3, n0, n1, n2, n3); } @@ -256,7 +298,7 @@ } Cell_handle create_face(Vertex_handle v0, Vertex_handle v1, - Vertex_handle v2) + Vertex_handle v2) { CGAL_triangulation_precondition(dimension()<3); return cells().emplace(v0, v1, v2, Vertex_handle()); @@ -264,13 +306,13 @@ // The following functions come from TDS_2. Cell_handle create_face(Cell_handle f0, int i0, - Cell_handle f1, int i1, - Cell_handle f2, int i2) + Cell_handle f1, int i1, + Cell_handle f2, int i2) { CGAL_triangulation_precondition(dimension() <= 2); Cell_handle newf = create_face(f0->vertex(cw(i0)), - f1->vertex(cw(i1)), - f2->vertex(cw(i2))); + f1->vertex(cw(i1)), + f2->vertex(cw(i2))); set_adjacency(newf, 2, f0, i0); set_adjacency(newf, 0, f1, i1); set_adjacency(newf, 1, f2, i2); @@ -278,12 +320,12 @@ } Cell_handle create_face(Cell_handle f0, int i0, - Cell_handle f1, int i1) + Cell_handle f1, int i1) { CGAL_triangulation_precondition(dimension() <= 2); Cell_handle newf = create_face(f0->vertex(cw(i0)), - f1->vertex(cw(i1)), - f1->vertex(ccw(i1))); + f1->vertex(cw(i1)), + f1->vertex(ccw(i1))); set_adjacency(newf, 2, f0, i0); set_adjacency(newf, 0, f1, i1); return newf; @@ -293,8 +335,8 @@ { CGAL_triangulation_precondition(dimension() <= 2); Cell_handle newf = create_face(f->vertex(cw(i)), - f->vertex(ccw(i)), - v); + f->vertex(ccw(i)), + v); set_adjacency(newf, 2, f, i); return newf; } @@ -324,14 +366,14 @@ void delete_vertices(InputIterator begin, InputIterator end) { for(; begin != end; ++begin) - delete_vertex(*begin); + delete_vertex(*begin); } template void delete_cells(InputIterator begin, InputIterator end) { for(; begin != end; ++begin) - delete_cell(*begin); + delete_cell(*begin); } // QUERIES @@ -340,27 +382,27 @@ bool is_vertex(Vertex_handle v) const; bool is_edge(Cell_handle c, int i, int j) const; bool is_edge(Vertex_handle u, Vertex_handle v, Cell_handle & c, - int & i, int & j) const; + int & i, int & j) const; bool is_edge(Vertex_handle u, Vertex_handle v) const; bool is_facet(Cell_handle c, int i) const; bool is_facet(Vertex_handle u, Vertex_handle v, - Vertex_handle w, - Cell_handle & c, int & i, int & j, int & k) const; + Vertex_handle w, + Cell_handle & c, int & i, int & j, int & k) const; bool is_cell(Cell_handle c) const; bool is_cell(Vertex_handle u, Vertex_handle v, - Vertex_handle w, Vertex_handle t, - Cell_handle & c, int & i, int & j, int & k, int & l) const; + Vertex_handle w, Vertex_handle t, + Cell_handle & c, int & i, int & j, int & k, int & l) const; bool is_cell(Vertex_handle u, Vertex_handle v, - Vertex_handle w, Vertex_handle t) const; + Vertex_handle w, Vertex_handle t) const; bool has_vertex(const Facet & f, Vertex_handle v, int & j) const; bool has_vertex(Cell_handle c, int i, - Vertex_handle v, int & j) const; + Vertex_handle v, int & j) const; bool has_vertex(const Facet & f, Vertex_handle v) const; bool has_vertex(Cell_handle c, int i, Vertex_handle v) const; bool are_equal(Cell_handle c, int i, - Cell_handle n, int j) const; + Cell_handle n, int j) const; bool are_equal(const Facet & f, const Facet & g) const; bool are_equal(const Facet & f, Cell_handle n, int j) const; @@ -386,36 +428,36 @@ // common to flip and flip_flippable void flip_really(Cell_handle c, int i, Cell_handle n, int in); void flip_really(Cell_handle c, int i, int j, - Cell_handle c1, Vertex_handle v1, - int i1, int j1, int next1, - Cell_handle c2, Vertex_handle v2, - int i2, int j2, int next2, - Vertex_handle v3); + Cell_handle c1, Vertex_handle v1, + int i1, int j1, int next1, + Cell_handle c2, Vertex_handle v2, + int i2, int j2, int next2, + Vertex_handle v3); #ifdef CGAL_TDS_USE_RECURSIVE_CREATE_STAR_3 Cell_handle create_star_3(Vertex_handle v, Cell_handle c, - int li, int prev_ind2 = -1); + int li, int prev_ind2 = -1); #else Cell_handle recursive_create_star_3(Vertex_handle v, Cell_handle c, int li, int prev_ind2,int depth); Cell_handle non_recursive_create_star_3(Vertex_handle v, Cell_handle c, int li, int prev_ind2); Cell_handle create_star_3(Vertex_handle v, Cell_handle c, - int li, int prev_ind2 = -1) + int li, int prev_ind2 = -1) { return recursive_create_star_3(v,c,li,prev_ind2,0); } #endif Cell_handle create_star_2(Vertex_handle v, - Cell_handle c, int li); + Cell_handle c, int li); public: // Internal function : assumes the conflict cells are marked. template Vertex_handle _insert_in_hole(CellIt cell_begin, CellIt cell_end, - Cell_handle begin, int i, - Vertex_handle newv) + Cell_handle begin, int i, + Vertex_handle newv) { CGAL_triangulation_precondition(begin != Cell_handle()); // if begin == NULL (default arg), we could compute one by walking in @@ -424,9 +466,9 @@ Cell_handle cnew; if (dimension() == 3) - cnew = create_star_3(newv, begin, i); + cnew = create_star_3(newv, begin, i); else - cnew = create_star_2(newv, begin, i); + cnew = create_star_2(newv, begin, i); newv->set_cell(cnew); delete_cells(cell_begin, cell_end); @@ -436,7 +478,7 @@ // Internal function : assumes the conflict cells are marked. template Vertex_handle _insert_in_hole(CellIt cell_begin, CellIt cell_end, - Cell_handle begin, int i) + Cell_handle begin, int i) { return _insert_in_hole(cell_begin, cell_end, begin, i, create_vertex()); } @@ -444,11 +486,11 @@ // Mark the cells in conflict, then calls the internal function. template Vertex_handle insert_in_hole(CellIt cell_begin, CellIt cell_end, - Cell_handle begin, int i, - Vertex_handle newv) + Cell_handle begin, int i, + Vertex_handle newv) { for (CellIt cit = cell_begin; cit != cell_end; ++cit) - (*cit)->tds_data().mark_in_conflict(); + (*cit)->tds_data().mark_in_conflict(); return _insert_in_hole(cell_begin, cell_end, begin, i, newv); } @@ -456,12 +498,18 @@ // Mark the cells in conflict, then calls the internal function. template Vertex_handle insert_in_hole(CellIt cell_begin, CellIt cell_end, - Cell_handle begin, int i) + Cell_handle begin, int i) { return insert_in_hole(cell_begin, cell_end, begin, i, create_vertex()); } //INSERTION + + // Create a finite cell with v1, v2, v3 and v4 + // Precondition: v1, v2, v3 and v4 MUST BE positively oriented + Vertex_handle insert_first_finite_cell( + Vertex_handle &v1, Vertex_handle &v2, Vertex_handle &v3, Vertex_handle &v4, + Vertex_handle v_infinite = Vertex_handle()); Vertex_handle insert_in_cell(Cell_handle c); @@ -497,8 +545,8 @@ { CGAL_triangulation_precondition(dimension() >= 1); for (Cell_iterator i = cells().begin(); - i != cells().end(); ++i) - change_orientation(i); + i != cells().end(); ++i) + change_orientation(i); } // ITERATOR METHODS @@ -506,7 +554,7 @@ Cell_iterator cells_begin() const { if ( dimension() < 3 ) - return cells_end(); + return cells_end(); return cells().begin(); } @@ -528,7 +576,7 @@ Facet_iterator facets_begin() const { if ( dimension() < 2 ) - return facets_end(); + return facets_end(); return Facet_iterator(this); } @@ -540,7 +588,7 @@ Edge_iterator edges_begin() const { if ( dimension() < 1 ) - return edges_end(); + return edges_end(); return Edge_iterator(this); } @@ -579,7 +627,7 @@ return Cell_circulator(e, start); } Cell_circulator incident_cells(Cell_handle ce, int i, int j, - Cell_handle start) const + Cell_handle start) const { CGAL_triangulation_precondition( dimension() == 3 ); return Cell_circulator(ce, i, j, start); @@ -602,19 +650,19 @@ return Facet_circulator(e, start); } Facet_circulator incident_facets(Cell_handle ce, int i, int j, - const Facet & start) const + const Facet & start) const { CGAL_triangulation_precondition( dimension() == 3 ); return Facet_circulator(ce, i, j, start); } Facet_circulator incident_facets(const Edge & e, - Cell_handle start, int f) const + Cell_handle start, int f) const { CGAL_triangulation_precondition( dimension() == 3 ); return Facet_circulator(e, start, f); } Facet_circulator incident_facets(Cell_handle ce, int i, int j, - Cell_handle start, int f) const + Cell_handle start, int f) const { CGAL_triangulation_precondition( dimension() == 3 ); return Facet_circulator(ce, i, j, start, f); @@ -633,35 +681,65 @@ template std::pair incident_cells_3(Vertex_handle v, Cell_handle d, - std::pair it) const + std::pair it) const { - CGAL_triangulation_precondition(dimension() == 3); - - std::stack cell_stack; - cell_stack.push(d); - d->tds_data().mark_in_conflict(); - *it.first++ = d; - - do { - Cell_handle c = cell_stack.top(); - cell_stack.pop(); - - for (int i=0; i<4; ++i) { - if (c->vertex(i) == v) - continue; - Cell_handle next = c->neighbor(i); - if (c < next) - *it.second++ = Facet(c, i); // Incident facet. - if (! next->tds_data().is_clear()) - continue; - cell_stack.push(next); - next->tds_data().mark_in_conflict(); - *it.first++ = next; - } - } while(!cell_stack.empty()); + CGAL_triangulation_precondition(dimension() == 3); + + std::stack cell_stack; + cell_stack.push(d); + d->tds_data().mark_in_conflict(); + *it.first++ = d; + + do { + Cell_handle c = cell_stack.top(); + cell_stack.pop(); + + for (int i=0; i<4; ++i) { + if (c->vertex(i) == v) + continue; + Cell_handle next = c->neighbor(i); + if (c < next) + *it.second++ = Facet(c, i); // Incident facet. + if (! next->tds_data().is_clear()) + continue; + cell_stack.push(next); + next->tds_data().mark_in_conflict(); + *it.first++ = next; + } + } while(!cell_stack.empty()); - return it; + return it; + } + + template + void + incident_cells_3_threadsafe(Vertex_handle v, Cell_handle d, + std::vector &cells, + IncidentFacetIterator facet_it) const + { + boost::unordered_set found_cells; + + cells.push_back(d); + found_cells.insert(d); + int head=0; + int tail=1; + do { + Cell_handle c = cells[head]; + + for (int i=0; i<4; ++i) { + if (c->vertex(i) == v) + continue; + Cell_handle next = c->neighbor(i); + if (c < next) + *facet_it++ = Facet(c, i); // Incident facet + if (! found_cells.insert(next).second ) + continue; + cells.push_back(next); + ++tail; + } + ++head; + } while(head != tail); } void just_incident_cells_3(Vertex_handle v, @@ -682,7 +760,7 @@ continue; Cell_handle next = c->neighbor(i); if (! next->tds_data().is_clear()) - continue; + continue; cells.push_back(next); ++tail; next->tds_data().mark_in_conflict(); @@ -693,29 +771,17 @@ template void - incident_cells_2(Vertex_handle v, Cell_handle c, - OutputIterator cells) const + incident_cells_2(Vertex_handle v, Cell_handle, + OutputIterator cells) const { CGAL_triangulation_precondition(dimension() == 2); - // TODO : in 2D, there's no real need for tds_data, we could use - // a smarter algorithm. We could use the 2D Face_circulator. - // Should we just have this Face_circulator ? - - // Flag values : - // 1 : incident cell already visited - // 0 : unknown - c->tds_data().mark_in_conflict(); - *cells++ = c; - - for (int i=0; i<3; ++i) { - if (c->vertex(i) == v) - continue; - Cell_handle next = c->neighbor(i); - if (! next->tds_data().is_clear()) - continue; - incident_cells_2(v, next, cells); - } + Face_circulator fc = incident_faces(v); + Face_circulator done(fc); + do { + *cells++ = fc; + ++fc; + } while (fc != done); } public: @@ -729,8 +795,8 @@ } }; - // Visitor for visit_incident_cells: - // outputs the facets + // Visitor for visit_incident_cells: + // outputs the facets template class Facet_extractor { OutputIterator output; @@ -754,15 +820,15 @@ Facet_it operator++(int) {return *this;}; template Facet_it& operator=(const T& e) { - if(filter(e)) - return *this; - *output++ = e; - return *this; + if(filter(e)) + return *this; + *output++ = e; + return *this; } Facet_it& operator=(const Facet_it& f) { - output = f.output; - filter = f.filter; - return *this; + output = f.output; + filter = f.filter; + return *this; } }; Facet_it facet_it() { @@ -770,8 +836,8 @@ } }; - // Visitor for visit_incident_cells: - // outputs the cells + // Visitor for visit_incident_cells: + // outputs the cells template class Cell_extractor { OutputIterator output; @@ -782,7 +848,7 @@ void operator()(Cell_handle c) { if(filter(c)) - return; + return; *output++ = c; } CGAL::Emptyset_iterator facet_it() {return CGAL::Emptyset_iterator();} @@ -805,7 +871,7 @@ void operator()(Cell_handle c) { Facet f = Facet(c,3); if(filter(f)) - return; + return; *output++ = f; } CGAL::Emptyset_iterator facet_it() {return CGAL::Emptyset_iterator();} @@ -814,37 +880,96 @@ } }; + template + class Vertex_extractor; - // Visitor for visit_incident_cells: - // outputs the result of Treatment applied to the vertices + // Visitor for visit_incident_cells: + // outputs the result of Treatment applied to the vertices template - class Vertex_extractor { + class Vertex_extractor { Vertex_handle v; - std::set tmp_vertices; + + boost::unordered_set tmp_vertices; + Treatment treat; const Tds* t; Filter filter; public: Vertex_extractor(Vertex_handle _v, OutputIterator _output, const Tds* _t, Filter _filter): - v(_v), treat(_output), t(_t), filter(_filter) {} + v(_v), treat(_output), t(_t), filter(_filter) + { +#if ( BOOST_VERSION >= 105000 ) + tmp_vertices.reserve(64); +#endif + } + + void operator()(Cell_handle c) { + for (int j=0; j<= t->dimension(); ++j) { + Vertex_handle w = c->vertex(j); + if(filter(w)) + continue; + if (w != v) { + if(tmp_vertices.insert(w).second) { + treat(c, v, j); + } + + } + } + } + + + CGAL::Emptyset_iterator facet_it() {return CGAL::Emptyset_iterator();} + OutputIterator result() { + return treat.result(); + } + }; + + template + class Vertex_extractor { + Vertex_handle v; + std::vector tmp_vertices; + + Treatment treat; + const Tds* t; + Filter filter; + public: + Vertex_extractor(Vertex_handle _v, OutputIterator _output, const Tds* _t, Filter _filter): + v(_v), treat(_output), t(_t), filter(_filter) { + tmp_vertices.reserve(64); + } + void operator()(Cell_handle c) { for (int j=0; j<= t->dimension(); ++j) { Vertex_handle w = c->vertex(j); if(filter(w)) continue; - if (w != v) - if(tmp_vertices.insert(w).second) { + if (w != v){ + + if(! w->visited_for_vertex_extractor){ + w->visited_for_vertex_extractor = true; + tmp_vertices.push_back(w); treat(c, v, j); - } + } + } + } + } + + ~Vertex_extractor() + { + for(std::size_t i=0; i < tmp_vertices.size(); ++i){ + tmp_vertices[i]->visited_for_vertex_extractor = false; } } + CGAL::Emptyset_iterator facet_it() {return CGAL::Emptyset_iterator();} OutputIterator result() { return treat.result(); } }; + + // Treatment for Vertex_extractor: // outputs the vertices template @@ -897,12 +1022,27 @@ just_incident_cells_3(v, cells); typename std::vector::iterator cit,end; for(cit = cells.begin(), end = cells.end(); - cit != end; - ++cit) + cit != end; + ++cit) { (*cit)->tds_data().clear(); } } + + template + OutputIterator + incident_cells_threadsafe(Vertex_handle v, OutputIterator cells, Filter f = Filter()) const + { + return visit_incident_cells_threadsafe, + OutputIterator>(v, cells, f); + } + + template + OutputIterator + incident_cells_threadsafe(Vertex_handle v, OutputIterator cells) const + { + return incident_cells_threadsafe(v, cells); + } template OutputIterator @@ -910,9 +1050,9 @@ { CGAL_triangulation_precondition( dimension() > 1 ); if(dimension() == 3) - return visit_incident_cells, OutputIterator>(v, facets, f); + return visit_incident_cells, OutputIterator>(v, facets, f); else - return visit_incident_cells, OutputIterator>(v, facets, f); + return visit_incident_cells, OutputIterator>(v, facets, f); } template @@ -921,6 +1061,26 @@ { return incident_facets(v, facets); } + + template + OutputIterator + incident_facets_threadsafe(Vertex_handle v, OutputIterator facets, Filter f = Filter()) const + { + CGAL_triangulation_precondition( dimension() > 1 ); + if(dimension() == 3) + return visit_incident_cells_threadsafe, OutputIterator>(v, facets, f); + else + return visit_incident_cells_threadsafe, OutputIterator>(v, facets, f); + } + + template + OutputIterator + incident_facets_threadsafe(Vertex_handle v, OutputIterator facets) const + { + return incident_facets(v, facets); + } + + BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_member_visited,Has_visited_for_vertex_extractor,false) template OutputIterator @@ -944,7 +1104,7 @@ return edges; } return visit_incident_cells, - OutputIterator, Filter>, + OutputIterator, Filter, Has_member_visited::value>, OutputIterator>(v, edges, f); } @@ -968,7 +1128,8 @@ return vertices; if (dimension() == 0) { - *vertices++ = v->cell()->neighbor(0)->vertex(0); + Vertex_handle v1 = v->cell()->neighbor(0)->vertex(0); + if(!f(v1)) *vertices++ = v1; return vertices; } @@ -987,7 +1148,7 @@ return vertices; } return visit_incident_cells, - OutputIterator, Filter>, + OutputIterator, Filter, Has_member_visited::value>, OutputIterator>(v, vertices, f); } @@ -1028,14 +1189,139 @@ typename std::vector::iterator cit; for(cit = tmp_cells.begin(); - cit != tmp_cells.end(); - ++cit) + cit != tmp_cells.end(); + ++cit) + { + (*cit)->tds_data().clear(); + visit(*cit); + } + + return visit.result(); + } + + template + OutputIterator + visit_incident_cells_threadsafe( + Vertex_handle v, OutputIterator output, Filter f) const + { + CGAL_triangulation_precondition( v != Vertex_handle() ); + CGAL_triangulation_expensive_precondition( is_vertex(v) ); + + if ( dimension() < 2 ) + return output; + + Visitor visit(v, output, this, f); + + std::vector tmp_cells; + tmp_cells.reserve(64); + if ( dimension() == 3 ) + incident_cells_3_threadsafe( + v, v->cell(), tmp_cells, visit.facet_it()); + else + incident_cells_2(v, v->cell(), std::back_inserter(tmp_cells)); + + typename std::vector::iterator cit; + for(cit = tmp_cells.begin(); + cit != tmp_cells.end(); + ++cit) + { + visit(*cit); + } + + return visit.result(); + } + + template + OutputIterator + visit_incident_cells(Vertex_handle v, OutputIterator output, + std::vector &cells, Filter f) const + { + CGAL_triangulation_precondition( v != Vertex_handle() ); + CGAL_triangulation_expensive_precondition( is_vertex(v) ); + + if ( dimension() < 2 ) + return output; + + Visitor visit(v, output, this, f); + + if ( dimension() == 3 ) + incident_cells_3(v, v->cell(), std::make_pair(std::back_inserter(cells), visit.facet_it())); + else + incident_cells_2(v, v->cell(), std::back_inserter(cells)); + + typename std::vector::iterator cit; + for(cit = cells.begin(); + cit != cells.end(); + ++cit) + { + (*cit)->tds_data().clear(); + visit(*cit); + } + return visit.result(); + } + + template + OutputIterator + visit_just_incident_cells(Vertex_handle v, OutputIterator output, Filter f) const + { + CGAL_triangulation_precondition( v != Vertex_handle() ); + CGAL_triangulation_expensive_precondition( is_vertex(v) ); + + if ( dimension() < 2 ) + return output; + + Visitor visit(v, output, this, f); + + std::vector tmp_cells; + tmp_cells.reserve(64); + + if ( dimension() == 3 ) + just_incident_cells_3(v, tmp_cells); + else + incident_cells_2(v, v->cell(), std::back_inserter(tmp_cells)); + + typename std::vector::iterator cit; + for(cit = tmp_cells.begin(); + cit != tmp_cells.end(); + ++cit) { (*cit)->tds_data().clear(); visit(*cit); } return visit.result(); } + + // For dimension 3 only + template + OutputVertexIterator + adjacent_vertices_and_cells_3(Vertex_handle v, OutputVertexIterator vertices, + std::vector &cells, + VertexFilter f = VertexFilter()) const + { + CGAL_triangulation_precondition( v != Vertex_handle() ); + CGAL_triangulation_precondition( dimension() == 3 ); + CGAL_triangulation_expensive_precondition( is_vertex(v) ); + CGAL_triangulation_expensive_precondition( is_valid() ); + + return + visit_incident_cells + < + Vertex_extractor, + OutputVertexIterator, + VertexFilter, + Has_member_visited::value>, + OutputVertexIterator + >(v, vertices, cells, f); + } + + // For dimension 3 only + template + OutputVertexIterator + adjacent_vertices_and_cells_3(Vertex_handle v, OutputVertexIterator vertices, + std::vector &cells) const + { + return adjacent_vertices_and_cells_3(v, vertices, cells); + } size_type degree(Vertex_handle v) const; @@ -1047,7 +1333,7 @@ // Helping functions template Vertex_handle copy_tds(const TDS_src & tds, - typename TDS_src::Vertex_handle vert); + typename TDS_src::Vertex_handle vert); template Vertex_handle copy_tds(const TDS_src & tds) @@ -1065,7 +1351,7 @@ void clear(); void set_adjacency(Cell_handle c0, int i0, - Cell_handle c1, int i1) const + Cell_handle c1, int i1) const { CGAL_triangulation_assertion(i0 >= 0 && i0 <= dimension()); CGAL_triangulation_assertion(i1 >= 0 && i1 <= dimension()); @@ -1133,9 +1419,9 @@ }; #ifdef CGAL_TDS_USE_RECURSIVE_CREATE_STAR_3 -template -typename Triangulation_data_structure_3::Cell_handle -Triangulation_data_structure_3:: +template +typename Triangulation_data_structure_3::Cell_handle +Triangulation_data_structure_3:: create_star_3(Vertex_handle v, Cell_handle c, int li, int prev_ind2) { CGAL_triangulation_precondition( dimension() == 3); @@ -1143,9 +1429,9 @@ CGAL_triangulation_precondition( ! c->neighbor(li)->tds_data().is_in_conflict() ); Cell_handle cnew = create_cell(c->vertex(0), - c->vertex(1), - c->vertex(2), - c->vertex(3)); + c->vertex(1), + c->vertex(2), + c->vertex(3)); cnew->set_vertex(li, v); Cell_handle c_li = c->neighbor(li); set_adjacency(cnew, li, c_li, c_li->index(c)); @@ -1153,7 +1439,7 @@ // Look for the other neighbors of cnew. for (int ii=0; ii<4; ++ii) { if (ii == prev_ind2 || cnew->neighbor(ii) != Cell_handle()) - continue; + continue; cnew->vertex(ii)->set_cell(cnew); // Indices of the vertices of cnew such that ii,vj1,vj2,li positive. @@ -1164,13 +1450,12 @@ Cell_handle n = cur->neighbor(zz); // turn around the oriented edge vj1 vj2 while ( n->tds_data().is_in_conflict() ) { - CGAL_triangulation_assertion( n != c ); - cur = n; - zz = next_around_edge(n->index(vj1), n->index(vj2)); - n = cur->neighbor(zz); + CGAL_triangulation_assertion( n != c ); + cur = n; + zz = next_around_edge(n->index(vj1), n->index(vj2)); + n = cur->neighbor(zz); } // Now n is outside region, cur is inside. - n->tds_data().clear(); // Reset the flag for boundary cells. int jj1 = n->index(vj1); @@ -1179,9 +1464,9 @@ Cell_handle nnn = n->neighbor(next_around_edge(jj2, jj1)); int zzz = nnn->index(vvv); if (nnn == cur) { - // Neighbor relation is reciprocal, ie - // the cell we are looking for is not yet created. - nnn = create_star_3(v, nnn, zz, zzz); + // Neighbor relation is reciprocal, ie + // the cell we are looking for is not yet created. + nnn = create_star_3(v, nnn, zz, zzz); } set_adjacency(nnn, zzz, cnew, ii); @@ -1190,9 +1475,9 @@ return cnew; } #else -template -typename Triangulation_data_structure_3::Cell_handle -Triangulation_data_structure_3:: +template +typename Triangulation_data_structure_3::Cell_handle +Triangulation_data_structure_3:: recursive_create_star_3(Vertex_handle v, Cell_handle c, int li, int prev_ind2, int depth) { @@ -1202,9 +1487,9 @@ CGAL_triangulation_precondition( ! c->neighbor(li)->tds_data().is_in_conflict() ); Cell_handle cnew = create_cell(c->vertex(0), - c->vertex(1), - c->vertex(2), - c->vertex(3)); + c->vertex(1), + c->vertex(2), + c->vertex(3)); cnew->set_vertex(li, v); Cell_handle c_li = c->neighbor(li); set_adjacency(cnew, li, c_li, c_li->index(c)); @@ -1212,7 +1497,7 @@ // Look for the other neighbors of cnew. for (int ii=0; ii<4; ++ii) { if (ii == prev_ind2 || cnew->neighbor(ii) != Cell_handle()) - continue; + continue; cnew->vertex(ii)->set_cell(cnew); // Indices of the vertices of cnew such that ii,vj1,vj2,li positive. @@ -1223,13 +1508,12 @@ Cell_handle n = cur->neighbor(zz); // turn around the oriented edge vj1 vj2 while ( n->tds_data().is_in_conflict() ) { - CGAL_triangulation_assertion( n != c ); - cur = n; - zz = next_around_edge(n->index(vj1), n->index(vj2)); - n = cur->neighbor(zz); + CGAL_triangulation_assertion( n != c ); + cur = n; + zz = next_around_edge(n->index(vj1), n->index(vj2)); + n = cur->neighbor(zz); } // Now n is outside region, cur is inside. - n->tds_data().clear(); // Reset the flag for boundary cells. int jj1 = n->index(vj1); @@ -1238,9 +1522,9 @@ Cell_handle nnn = n->neighbor(next_around_edge(jj2, jj1)); int zzz = nnn->index(vvv); if (nnn == cur) { - // Neighbor relation is reciprocal, ie - // the cell we are looking for is not yet created. - nnn = recursive_create_star_3(v, nnn, zz, zzz,depth+1); + // Neighbor relation is reciprocal, ie + // the cell we are looking for is not yet created. + nnn = recursive_create_star_3(v, nnn, zz, zzz,depth+1); } set_adjacency(nnn, zzz, cnew, ii); @@ -1251,9 +1535,9 @@ //We use the class iAdjacency_info instead of a tuple because //at the moment we made the change it was faster like this. -template -typename Triangulation_data_structure_3::Cell_handle -Triangulation_data_structure_3:: +template +typename Triangulation_data_structure_3::Cell_handle +Triangulation_data_structure_3:: non_recursive_create_star_3(Vertex_handle v, Cell_handle c, int li, int prev_ind2) { CGAL_triangulation_precondition( dimension() == 3); @@ -1261,9 +1545,9 @@ CGAL_triangulation_precondition( ! c->neighbor(li)->tds_data().is_in_conflict() ); Cell_handle cnew = create_cell(c->vertex(0), - c->vertex(1), - c->vertex(2), - c->vertex(3)); + c->vertex(1), + c->vertex(2), + c->vertex(3)); cnew->set_vertex(li, v); Cell_handle c_li = c->neighbor(li); set_adjacency(cnew, li, c_li, c_li->index(c)); @@ -1291,7 +1575,6 @@ n = cur->neighbor(zz); } // Now n is outside region, cur is inside. - n->tds_data().clear(); // Reset the flag for boundary cells. int jj1 = n->index(vj1); @@ -1329,9 +1612,9 @@ } #endif -template -typename Triangulation_data_structure_3::Cell_handle -Triangulation_data_structure_3:: +template +typename Triangulation_data_structure_3::Cell_handle +Triangulation_data_structure_3:: create_star_2(Vertex_handle v, Cell_handle c, int li ) { CGAL_triangulation_assertion( dimension() == 2 ); @@ -1359,7 +1642,7 @@ // here cur has an edge on the boundary of region cnew = create_face( v, v1, cur->vertex( ccw(i1) ) ); set_adjacency(cnew, 0, cur->neighbor(cw(i1)), - cur->neighbor(cw(i1))->index(cur)); + cur->neighbor(cw(i1))->index(cur)); cnew->set_neighbor(1, Cell_handle()); cnew->set_neighbor(2, pnew); // pnew is null at the first iteration @@ -1379,9 +1662,9 @@ return cnew; } -template < class Vb, class Cb> +template std::istream& -operator>>(std::istream& is, Triangulation_data_structure_3& tds) +operator>>(std::istream& is, Triangulation_data_structure_3& tds) // reads : // the dimension // the number of vertices @@ -1390,7 +1673,7 @@ // the neighbors of each cell by their index in the preceding list of cells // when dimension < 3 : the same with faces of maximal dimension { - typedef Triangulation_data_structure_3 Tds; + typedef Triangulation_data_structure_3 Tds; typedef typename Tds::Vertex_handle Vertex_handle; typedef typename Tds::Cell_handle Cell_handle; @@ -1427,9 +1710,9 @@ return is; } -template < class Vb, class Cb> +template std::ostream& -operator<<(std::ostream& os, const Triangulation_data_structure_3 &tds) +operator<<(std::ostream& os, const Triangulation_data_structure_3 &tds) // writes : // the dimension // the number of vertices @@ -1438,7 +1721,7 @@ // the neighbors of each cell by their index in the preceding list of cells // when dimension < 3 : the same with faces of maximal dimension { - typedef Triangulation_data_structure_3 Tds; + typedef Triangulation_data_structure_3 Tds; typedef typename Tds::size_type size_type; typedef typename Tds::Vertex_handle Vertex_handle; typedef typename Tds::Vertex_iterator Vertex_iterator; @@ -1472,9 +1755,9 @@ return os; } -template < class Vb, class Cb> +template bool -Triangulation_data_structure_3:: +Triangulation_data_structure_3:: is_simplex( Cell_handle c ) const { switch(dimension()) { @@ -1487,19 +1770,19 @@ return false; } -template < class Vb, class Cb> +template bool -Triangulation_data_structure_3:: +Triangulation_data_structure_3:: is_vertex(Vertex_handle v) const { return vertices().owns_dereferencable(v); } -template < class Vb, class Cb> +template bool -Triangulation_data_structure_3:: +Triangulation_data_structure_3:: is_edge(Vertex_handle u, Vertex_handle v, - Cell_handle &c, int &i, int &j) const + Cell_handle &c, int &i, int &j) const // returns false when dimension <1 or when indices wrong { CGAL_triangulation_expensive_precondition( is_vertex(u) && is_vertex(v) ); @@ -1512,18 +1795,18 @@ incident_cells(u, std::back_inserter(cells)); for (typename std::vector::iterator cit = cells.begin(); - cit != cells.end(); ++cit) + cit != cells.end(); ++cit) if ((*cit)->has_vertex(v, j)) { - c = *cit; - i = c->index(u); - return true; - } + c = *cit; + i = c->index(u); + return true; + } return false; } -template < class Vb, class Cb> +template bool -Triangulation_data_structure_3:: +Triangulation_data_structure_3:: is_edge(Vertex_handle u, Vertex_handle v) const { Cell_handle c; @@ -1531,9 +1814,9 @@ return is_edge(u, v, c, i, j); } -template < class Vb, class Cb> +template bool -Triangulation_data_structure_3:: +Triangulation_data_structure_3:: is_edge(Cell_handle c, int i, int j) const { if (dimension() < 1) @@ -1548,40 +1831,40 @@ return cells().owns_dereferencable(c); } -template < class Vb, class Cb> +template bool -Triangulation_data_structure_3:: +Triangulation_data_structure_3:: is_facet(Vertex_handle u, Vertex_handle v, - Vertex_handle w, - Cell_handle & c, int & i, int & j, int & k) const + Vertex_handle w, + Cell_handle & c, int & i, int & j, int & k) const // returns false when dimension <2 or when indices wrong { CGAL_triangulation_expensive_precondition( is_vertex(u) && - is_vertex(v) && - is_vertex(w) ); + is_vertex(v) && + is_vertex(w) ); if ( u==v || u==w || v==w ) - return false; + return false; if (dimension() < 2) - return false; + return false; std::vector cells; cells.reserve(64); incident_cells(u, std::back_inserter(cells)); for (typename std::vector::iterator cit = cells.begin(); - cit != cells.end(); ++cit) + cit != cells.end(); ++cit) if ((*cit)->has_vertex(v, j) && (*cit)->has_vertex(w, k)) { - c = *cit; - i = c->index(u); - return true; - } + c = *cit; + i = c->index(u); + return true; + } return false; } -template < class Vb, class Cb> +template bool -Triangulation_data_structure_3:: +Triangulation_data_structure_3:: is_facet(Cell_handle c, int i) const { CGAL_triangulation_precondition(i>=0 && i<4); @@ -1595,9 +1878,9 @@ return cells().owns_dereferencable(c); } -template < class Vb, class Cb> +template bool -Triangulation_data_structure_3:: +Triangulation_data_structure_3:: is_cell( Cell_handle c ) const // returns false when dimension <3 { @@ -1607,18 +1890,18 @@ return cells().owns_dereferencable(c); } -template < class Vb, class Cb> +template bool -Triangulation_data_structure_3:: +Triangulation_data_structure_3:: is_cell(Vertex_handle u, Vertex_handle v, - Vertex_handle w, Vertex_handle t, - Cell_handle & c, int & i, int & j, int & k, int & l) const + Vertex_handle w, Vertex_handle t, + Cell_handle & c, int & i, int & j, int & k, int & l) const // returns false when dimension <3 { CGAL_triangulation_expensive_precondition( is_vertex(u) && - is_vertex(v) && - is_vertex(w) && - is_vertex(t) ); + is_vertex(v) && + is_vertex(w) && + is_vertex(t) ); if ( u==v || u==w || u==t || v==w || v==t || w==t ) return false; @@ -1628,21 +1911,21 @@ incident_cells(u, std::back_inserter(cells)); for (typename std::vector::iterator cit = cells.begin(); - cit != cells.end(); ++cit) + cit != cells.end(); ++cit) if ((*cit)->has_vertex(v, j) && (*cit)->has_vertex(w, k) && - (*cit)->has_vertex(t, l)) { - c = *cit; - i = c->index(u); - return true; - } + (*cit)->has_vertex(t, l)) { + c = *cit; + i = c->index(u); + return true; + } return false; } -template < class Vb, class Cb> +template bool -Triangulation_data_structure_3:: +Triangulation_data_structure_3:: is_cell(Vertex_handle u, Vertex_handle v, - Vertex_handle w, Vertex_handle t) + Vertex_handle w, Vertex_handle t) const // returns false when dimension <3 { @@ -1651,10 +1934,10 @@ return is_cell(u, v, w, t, c, i, j, k, l); } -template < class Vb, class Cb> +template inline bool -Triangulation_data_structure_3:: +Triangulation_data_structure_3:: has_vertex(Cell_handle c, int i, Vertex_handle v, int & j) const // computes the index j of the vertex in the cell c giving the query // facet (c,i) @@ -1664,10 +1947,10 @@ return ( c->has_vertex(v,j) && (j != i) ); } -template < class Vb, class Cb> +template inline bool -Triangulation_data_structure_3:: +Triangulation_data_structure_3:: has_vertex(Cell_handle c, int i, Vertex_handle v) const // checks whether the query facet (c,i) has vertex v { @@ -1676,27 +1959,27 @@ return ( c->has_vertex(v,j) && (j != i) ); } -template < class Vb, class Cb> +template inline bool -Triangulation_data_structure_3:: +Triangulation_data_structure_3:: has_vertex(const Facet & f, Vertex_handle v, int & j) const { return has_vertex(f.first, f.second, v, j); } -template < class Vb, class Cb> +template inline bool -Triangulation_data_structure_3:: +Triangulation_data_structure_3:: has_vertex(const Facet & f, Vertex_handle v) const { return has_vertex(f.first, f.second, v); } -template < class Vb, class Cb> +template bool -Triangulation_data_structure_3:: +Triangulation_data_structure_3:: are_equal(Cell_handle c, int i, Cell_handle n, int j) const // tests whether facets c,i and n,j, have the same 3 vertices // the triangulation is supposed to be valid, the orientation of the @@ -1713,30 +1996,30 @@ int j1,j2,j3; return( n->has_vertex( c->vertex((i+1)&3), j1 ) && - n->has_vertex( c->vertex((i+2)&3), j2 ) && - n->has_vertex( c->vertex((i+3)&3), j3 ) && - ( j1+j2+j3+j == 6 ) ); + n->has_vertex( c->vertex((i+2)&3), j2 ) && + n->has_vertex( c->vertex((i+3)&3), j3 ) && + ( j1+j2+j3+j == 6 ) ); } -template < class Vb, class Cb> +template bool -Triangulation_data_structure_3:: +Triangulation_data_structure_3:: are_equal(const Facet & f, const Facet & g) const { return are_equal(f.first, f.second, g.first, g.second); } -template < class Vb, class Cb> +template bool -Triangulation_data_structure_3:: +Triangulation_data_structure_3:: are_equal(const Facet & f, Cell_handle n, int j) const { return are_equal(f.first, f.second, n, j); } -template < class Vb, class Cb> +template bool -Triangulation_data_structure_3:: +Triangulation_data_structure_3:: flip( Cell_handle c, int i ) // returns false if the facet is not flippable // true other wise and @@ -1744,7 +2027,7 @@ // c will be replaced by one of the new cells { CGAL_triangulation_precondition( (dimension() == 3) && (0<=i) && (i<4) - && (number_of_vertices() >= 6) ); + && (number_of_vertices() >= 6) ); CGAL_triangulation_expensive_precondition( is_cell(c) ); Cell_handle n = c->neighbor(i); @@ -1759,15 +2042,15 @@ return true; } -template < class Vb, class Cb> +template void -Triangulation_data_structure_3:: +Triangulation_data_structure_3:: flip_flippable(Cell_handle c, int i ) // flips facet i of cell c // c will be replaced by one of the new cells { CGAL_triangulation_precondition( (dimension() == 3) && (0<=i) && (i<4) - && (number_of_vertices() >= 6) ); + && (number_of_vertices() >= 6) ); CGAL_triangulation_expensive_precondition( is_cell(c) ); Cell_handle n = c->neighbor(i); @@ -1776,14 +2059,14 @@ // checks that the facet is flippable, // ie the future edge does not already exist CGAL_triangulation_expensive_precondition( !is_edge(c->vertex(i), - n->vertex(in))); + n->vertex(in))); flip_really(c,i,n,in); } -template < class Vb, class Cb> +template inline void -Triangulation_data_structure_3:: +Triangulation_data_structure_3:: flip_really( Cell_handle c, int i, Cell_handle n, int in ) // private - used by flip and flip_flippable { @@ -1802,7 +2085,7 @@ n->set_vertex( in1, c->vertex(i) ); Cell_handle cnew = create_cell(c->vertex(i), c->vertex(i1), - n->vertex(in), n->vertex(in3)); + n->vertex(in), n->vertex(in3)); set_adjacency(cnew, 0, n->neighbor(in2), n->neighbor(in2)->index(n)); set_adjacency(cnew, 1, n, in2); @@ -1820,9 +2103,9 @@ // CGAL_triangulation_precondition( (0<=i) && (i<3) ); } -template < class Vb, class Cb> +template bool -Triangulation_data_structure_3:: +Triangulation_data_structure_3:: flip( Cell_handle c, int i, int j ) // returns false if the edge is not flippable // true otherwise and @@ -1830,10 +2113,10 @@ // c will be deleted { CGAL_triangulation_precondition( (dimension() == 3) - && (0<=i) && (i<4) - && (0<=j) && (j<4) - && ( i != j ) - && (number_of_vertices() >= 6) ); + && (0<=i) && (i<4) + && (0<=j) && (j<4) + && ( i != j ) + && (number_of_vertices() >= 6) ); CGAL_triangulation_expensive_precondition( is_cell(c) ); // checks that the edge is flippable ie degree 3 @@ -1872,18 +2155,18 @@ return true; } -template < class Vb, class Cb> +template void -Triangulation_data_structure_3:: +Triangulation_data_structure_3:: flip_flippable( Cell_handle c, int i, int j ) // flips edge i,j of cell c // c will be deleted { CGAL_triangulation_precondition( (dimension() == 3) - && (0<=i) && (i<4) - && (0<=j) && (j<4) - && ( i != j ) - && (number_of_vertices() >= 6) ); + && (0<=i) && (i<4) + && (0<=j) && (j<4) + && ( i != j ) + && (number_of_vertices() >= 6) ); CGAL_triangulation_expensive_precondition( is_cell(c) ); // checks that the edge is flippable ie degree 3 @@ -1893,7 +2176,7 @@ CGAL_triangulation_precondition_code( Cell_circulator cdone = ccir; ); CGAL_triangulation_precondition_code( do { ++degree; - ++ccir; + ++ccir; } while ( ccir != cdone ); ); CGAL_triangulation_precondition( degree == 3 ); @@ -1921,16 +2204,16 @@ flip_really(c,i,j,c1,v1,i1,j1,next1,c2,v2,i2,j2,next2,v3); } -template < class Vb, class Cb> +template inline void -Triangulation_data_structure_3:: +Triangulation_data_structure_3:: flip_really( Cell_handle c, int i, int j, - Cell_handle c1, Vertex_handle v1, - int i1, int j1, int next1, - Cell_handle c2, Vertex_handle v2, - int i2, int j2, int next2, - Vertex_handle v3 ) + Cell_handle c1, Vertex_handle v1, + int i1, int j1, int next1, + Cell_handle c2, Vertex_handle v2, + int i2, int j2, int next2, + Vertex_handle v3 ) { c->vertex(i)->set_cell(c1); c->vertex(j)->set_cell(c2); @@ -1953,11 +2236,11 @@ delete_cell( c ); } -template < class Vb, class Cb > +template void -Triangulation_data_structure_3:: +Triangulation_data_structure_3:: read_cells(std::istream& is, std::map< std::size_t, Vertex_handle > &V, - std::size_t & m, std::map< std::size_t, Cell_handle > &C) + std::size_t & m, std::map< std::size_t, Cell_handle > &C) { // creation of the cells and neighbors switch (dimension()) { @@ -1971,28 +2254,28 @@ read(is, m); for(std::size_t i = 0; i < m; i++) { - Cell_handle c = create_cell(); - for (int k=0; k<=dimension(); ++k) { + Cell_handle c = create_cell(); + for (int k=0; k<=dimension(); ++k) { std::size_t ik; if(is_ascii(is)) is >> ik; else read(is, ik); - c->set_vertex(k, V[ik]); - V[ik]->set_cell(c); - } - C[i] = c; + c->set_vertex(k, V[ik]); + V[ik]->set_cell(c); + } + C[i] = c; } for(std::size_t j = 0; j < m; j++) { Cell_handle c = C[j]; - for (int k=0; k<=dimension(); ++k) { + for (int k=0; k<=dimension(); ++k) { std::size_t ik; if(is_ascii(is)) is >> ik; else read(is, ik); - c->set_neighbor(k, C[ik]); - } + c->set_neighbor(k, C[ik]); + } } break; } @@ -2002,12 +2285,12 @@ // CGAL_triangulation_assertion( n == 2 ); for (int i=0; i < 2; i++) { - Cell_handle c = create_face(V[i], Vertex_handle(), Vertex_handle()); - C[i] = c; - V[i]->set_cell(c); + Cell_handle c = create_face(V[i], Vertex_handle(), Vertex_handle()); + C[i] = c; + V[i]->set_cell(c); } for (int j=0; j < 2; j++) { - Cell_handle c = C[j]; + Cell_handle c = C[j]; c->set_neighbor(0, C[1-j]); } break; @@ -2024,9 +2307,9 @@ } } -template < class Vb, class Cb> +template void -Triangulation_data_structure_3:: +Triangulation_data_structure_3:: print_cells(std::ostream& os, const Unique_hash_map &V ) const { std::map C; @@ -2044,34 +2327,34 @@ // write the cells Cell_iterator it; for(it = cells_begin(); it != cells_end(); ++it) { - C[it] = i++; - for(int j = 0; j < 4; j++){ - if(is_ascii(os)) { + C[it] = i++; + for(int j = 0; j < 4; j++){ + if(is_ascii(os)) { os << V[it->vertex(j)]; - if ( j==3 ) - os << std::endl; - else - os << ' '; - } + if ( j==3 ) + os << std::endl; + else + os << ' '; + } else write(os, V[it->vertex(j)]); - } + } } CGAL_triangulation_assertion( i == m ); // write the neighbors for(it = cells_begin(); it != cells_end(); ++it) { - for (int j = 0; j < 4; j++) { - if(is_ascii(os)){ + for (int j = 0; j < 4; j++) { + if(is_ascii(os)){ os << C[it->neighbor(j)]; - if(j==3) - os << std::endl; - else - os << ' '; + if(j==3) + os << std::endl; + else + os << ' '; } else write(os, C[it->neighbor(j)]); - } + } } break; } @@ -2086,36 +2369,36 @@ // write the facets Facet_iterator it; for(it = facets_begin(); it != facets_end(); ++it) { - C[(*it).first] = i++; - for(int j = 0; j < 3; j++){ - if(is_ascii(os)) { - os << V[(*it).first->vertex(j)]; - if ( j==2 ) - os << std::endl; - else - os << ' '; - } - else { - write(os, V[(*it).first->vertex(j)]); - } - } + C[(*it).first] = i++; + for(int j = 0; j < 3; j++){ + if(is_ascii(os)) { + os << V[(*it).first->vertex(j)]; + if ( j==2 ) + os << std::endl; + else + os << ' '; + } + else { + write(os, V[(*it).first->vertex(j)]); + } + } } CGAL_triangulation_assertion( i == m ); // write the neighbors for(it = facets_begin(); it != facets_end(); ++it) { - for (int j = 0; j < 3; j++) { - if(is_ascii(os)){ - os << C[(*it).first->neighbor(j)]; - if(j==2) - os << std::endl; - else - os << ' '; - } - else { - write(os, C[(*it).first->neighbor(j)]); - } - } + for (int j = 0; j < 3; j++) { + if(is_ascii(os)){ + os << C[(*it).first->neighbor(j)]; + if(j==2) + os << std::endl; + else + os << ' '; + } + else { + write(os, C[(*it).first->neighbor(j)]); + } + } } break; } @@ -2129,45 +2412,93 @@ // write the edges Edge_iterator it; for(it = edges_begin(); it != edges_end(); ++it) { - C[(*it).first] = i++; - for(int j = 0; j < 2; j++){ - if(is_ascii(os)) { - os << V[(*it).first->vertex(j)]; - if ( j==1 ) - os << std::endl; - else - os << ' '; - } - else { - write(os, V[(*it).first->vertex(j)]); - } - } + C[(*it).first] = i++; + for(int j = 0; j < 2; j++){ + if(is_ascii(os)) { + os << V[(*it).first->vertex(j)]; + if ( j==1 ) + os << std::endl; + else + os << ' '; + } + else { + write(os, V[(*it).first->vertex(j)]); + } + } } CGAL_triangulation_assertion( i == m ); // write the neighbors for(it = edges_begin(); it != edges_end(); ++it) { - for (int j = 0; j < 2; j++) { - if(is_ascii(os)){ - os << C[(*it).first->neighbor(j)]; - if(j==1) - os << std::endl; - else - os << ' '; - } - else { - write(os, C[(*it).first->neighbor(j)]); - } - } + for (int j = 0; j < 2; j++) { + if(is_ascii(os)){ + os << C[(*it).first->neighbor(j)]; + if(j==1) + os << std::endl; + else + os << ' '; + } + else { + write(os, C[(*it).first->neighbor(j)]); + } + } } break; } } } -template -typename Triangulation_data_structure_3::Vertex_handle -Triangulation_data_structure_3:: + +template +typename Triangulation_data_structure_3::Vertex_handle +Triangulation_data_structure_3::insert_first_finite_cell( + Vertex_handle &v0, Vertex_handle &v1, Vertex_handle &v2, Vertex_handle &v3, + Vertex_handle v_infinite) +{ + CGAL_triangulation_precondition( + (v_infinite == Vertex_handle() && dimension() == -2) + || (v_infinite != Vertex_handle() && dimension() == -1)); + + if (v_infinite == Vertex_handle()) + v_infinite = create_vertex(); + + set_dimension(3); + + v0 = create_vertex(); + v1 = create_vertex(); + v2 = create_vertex(); + v3 = create_vertex(); + + Cell_handle c0123 = create_cell(v0, v1, v2, v3); + Cell_handle ci012 = create_cell(v_infinite, v0, v1, v2); + Cell_handle ci103 = create_cell(v_infinite, v1, v0, v3); + Cell_handle ci023 = create_cell(v_infinite, v0, v2, v3); + Cell_handle ci132 = create_cell(v_infinite, v1, v3, v2); + + v_infinite->set_cell(ci012); + v0->set_cell(c0123); + v1->set_cell(c0123); + v2->set_cell(c0123); + v3->set_cell(c0123); + + set_adjacency(c0123, 0, ci132, 0); + set_adjacency(c0123, 1, ci023, 0); + set_adjacency(c0123, 2, ci103, 0); + set_adjacency(c0123, 3, ci012, 0); + + set_adjacency(ci012, 3, ci103, 3); + set_adjacency(ci012, 2, ci023, 3); + set_adjacency(ci012, 1, ci132, 2); + set_adjacency(ci103, 1, ci023, 2); + set_adjacency(ci023, 1, ci132, 1); + set_adjacency(ci103, 2, ci132, 3); + + return v_infinite; +} + +template +typename Triangulation_data_structure_3::Vertex_handle +Triangulation_data_structure_3:: insert_in_cell(Cell_handle c) { CGAL_triangulation_precondition( dimension() == 3 ); @@ -2210,9 +2541,9 @@ return v; } -template -typename Triangulation_data_structure_3::Vertex_handle -Triangulation_data_structure_3:: +template +typename Triangulation_data_structure_3::Vertex_handle +Triangulation_data_structure_3:: insert_in_facet(Cell_handle c, int i) { // inserts v in the facet opposite to vertex i of cell c @@ -2227,15 +2558,15 @@ { CGAL_triangulation_expensive_precondition( is_cell(c) ); CGAL_triangulation_precondition( i == 0 || i == 1 || - i == 2 || i == 3 ); + i == 2 || i == 3 ); // c will be modified to have v replacing vertex(i+3) int i1,i2,i3; if ( (i&1) == 0 ) { - i1=(i+1)&3; i2=(i+2)&3; i3=6-i-i1-i2; + i1=(i+1)&3; i2=(i+2)&3; i3=6-i-i1-i2; } else { - i1=(i+1)&3; i2=(i+3)&3; i3=6-i-i1-i2; + i1=(i+1)&3; i2=(i+3)&3; i3=6-i-i1-i2; } // i,i1,i2,i3 is well oriented // so v will "replace" the vertices in this order @@ -2319,9 +2650,9 @@ return v; } -template -typename Triangulation_data_structure_3::Vertex_handle -Triangulation_data_structure_3:: +template +typename Triangulation_data_structure_3::Vertex_handle +Triangulation_data_structure_3:: insert_in_edge(Cell_handle c, int i, int j) // inserts a vertex in the edge of cell c with vertices i and j { @@ -2339,10 +2670,10 @@ cells.reserve(32); Cell_circulator ccir = incident_cells(c, i, j); do { - Cell_handle cc = ccir; - cells.push_back(cc); - cc->tds_data().mark_in_conflict(); - ++ccir; + Cell_handle cc = ccir; + cells.push_back(cc); + cc->tds_data().mark_in_conflict(); + ++ccir; } while (c != ccir); return _insert_in_hole(cells.begin(), cells.end(), c, i); @@ -2401,9 +2732,9 @@ } } -template -typename Triangulation_data_structure_3::Vertex_handle -Triangulation_data_structure_3:: +template +typename Triangulation_data_structure_3::Vertex_handle +Triangulation_data_structure_3:: insert_increase_dimension(Vertex_handle star) // star = vertex from which we triangulate the facet of the // incremented dimension @@ -2474,32 +2805,32 @@ CGAL_assertion(i==0 || i==1); int j = (i == 0) ? 1 : 0; Cell_handle d = c->neighbor(j); - + c->set_vertex(2,v); Cell_handle e = c->neighbor(i); Cell_handle cnew = c; Cell_handle enew = Cell_handle(); - + while( e != d ){ - enew = create_cell(); - enew->set_vertex(i,e->vertex(j)); - enew->set_vertex(j,e->vertex(i)); - enew->set_vertex(2,star); - - set_adjacency(enew, i, cnew, j); - // false at the first iteration of the loop where it should - // be neighbor 2 - // it is corrected after the loop - set_adjacency(enew, 2, e, 2); - // neighbor j will be set during next iteration of the loop - - e->set_vertex(2,v); + enew = create_cell(); + enew->set_vertex(i,e->vertex(j)); + enew->set_vertex(j,e->vertex(i)); + enew->set_vertex(2,star); + + set_adjacency(enew, i, cnew, j); + // false at the first iteration of the loop where it should + // be neighbor 2 + // it is corrected after the loop + set_adjacency(enew, 2, e, 2); + // neighbor j will be set during next iteration of the loop + + e->set_vertex(2,v); - e = e->neighbor(i); - cnew = enew; + e = e->neighbor(i); + cnew = enew; } - + d->set_vertex(2,v); set_adjacency(enew, j, d, 2); @@ -2527,47 +2858,47 @@ v->set_cell(it); // ok since there is at least one ``cell'' for(; it != cells_end(); ++it) { - // Here we must be careful since we create_cells in a loop controlled - // by an iterator. So we first take care of the cells newly created - // by the following test : - if (it->neighbor(0) == Cell_handle()) - continue; - it->set_neighbor(3, Cell_handle()); - it->set_vertex(3, v); - if ( ! it->has_vertex(star) ) { - Cell_handle cnew = create_cell( it->vertex(0), it->vertex(2), - it->vertex(1), star); - // The Intel compiler has a problem with passing "it" directly to - // function "set_adjacency": the adjacency is not changed. - Cell_handle ch_it = it; - set_adjacency(cnew, 3, ch_it, 3); - cnew->set_neighbor(0, Cell_handle()); - new_cells.push_back(cnew); - } + // Here we must be careful since we create_cells in a loop controlled + // by an iterator. So we first take care of the cells newly created + // by the following test : + if (it->neighbor(0) == Cell_handle()) + continue; + it->set_neighbor(3, Cell_handle()); + it->set_vertex(3, v); + if ( ! it->has_vertex(star) ) { + Cell_handle cnew = create_cell( it->vertex(0), it->vertex(2), + it->vertex(1), star); + // The Intel compiler has a problem with passing "it" directly to + // function "set_adjacency": the adjacency is not changed. + Cell_handle ch_it = it; + set_adjacency(cnew, 3, ch_it, 3); + cnew->set_neighbor(0, Cell_handle()); + new_cells.push_back(cnew); + } } // traversal of the new cells only, to add missing neighbors for(typename std::vector::iterator ncit = new_cells.begin(); ncit != new_cells.end(); ++ncit) { - Cell_handle n = (*ncit)->neighbor(3); // opposite to star - for ( int i=0; i<3; i++ ) { - int j; - if ( i==0 ) j=0; - else j=3-i; // vertex 1 and vertex 2 are always switched when - // creating a new cell (see above) + Cell_handle n = (*ncit)->neighbor(3); // opposite to star + for ( int i=0; i<3; i++ ) { + int j; + if ( i==0 ) j=0; + else j=3-i; // vertex 1 and vertex 2 are always switched when + // creating a new cell (see above) Cell_handle c = n->neighbor(i)->neighbor(3); - if ( c != Cell_handle() ) { - // i.e. star is not a vertex of n->neighbor(i) - (*ncit)->set_neighbor(j, c); - // opposite relation will be set when ncit arrives on c - // this avoids to look for the correct index - // and to test whether *ncit already has neighbor i - } - else { - // star is a vertex of n->neighbor(i) - set_adjacency(*ncit, j, n->neighbor(i), 3);//neighbor opposite to v - } - } + if ( c != Cell_handle() ) { + // i.e. star is not a vertex of n->neighbor(i) + (*ncit)->set_neighbor(j, c); + // opposite relation will be set when ncit arrives on c + // this avoids to look for the correct index + // and to test whether *ncit already has neighbor i + } + else { + // star is a vertex of n->neighbor(i) + set_adjacency(*ncit, j, n->neighbor(i), 3);//neighbor opposite to v + } + } } } }// end switch @@ -2575,21 +2906,21 @@ return v; } -template +template void -Triangulation_data_structure_3:: +Triangulation_data_structure_3:: remove_decrease_dimension(Vertex_handle v, Vertex_handle w) { CGAL_triangulation_expensive_precondition( is_valid() ); CGAL_triangulation_precondition( dimension() >= -1 ); CGAL_triangulation_precondition( dimension() != 1 || - number_of_vertices() == 3); + number_of_vertices() == 3); CGAL_triangulation_precondition( number_of_vertices() > - (size_type) dimension() + 1 ); + (size_type) dimension() + 1 ); CGAL_triangulation_precondition( degree(v) == number_of_vertices()-1 ); if (dimension() <= 0) { - delete_cell(v->cell()); + delete_cell(v->cell()); } else { // the cells incident to w are down graded one dimension @@ -2599,28 +2930,28 @@ for (Cell_iterator ib = cells().begin(); ib != cells().end(); ++ib) { if ( ib->has_vertex(w) ) - to_downgrade.push_back(ib); + to_downgrade.push_back(ib); else - to_delete.push_back(ib); + to_delete.push_back(ib); } typename std::vector::iterator lfit=to_downgrade.begin(); for( ; lfit != to_downgrade.end(); ++lfit) { - Cell_handle f = *lfit; - int j = f->index(w); - int k; if (f->has_vertex(v, k)) f->set_vertex(k, w); + Cell_handle f = *lfit; + int j = f->index(w); + int k; if (f->has_vertex(v, k)) f->set_vertex(k, w); if (j != dimension()) { - f->set_vertex(j, f->vertex(dimension())); - f->set_neighbor(j, f->neighbor(dimension())); - if (dimension() >= 1) - change_orientation(f); - } - f->set_vertex(dimension(), Vertex_handle()); - f->set_neighbor(dimension(), Cell_handle()); - - // Update vertex->cell() pointers. - for (int i = 0; i < dimension(); ++i) - f->vertex(i)->set_cell(f); + f->set_vertex(j, f->vertex(dimension())); + f->set_neighbor(j, f->neighbor(dimension())); + if (dimension() >= 1) + change_orientation(f); + } + f->set_vertex(dimension(), Vertex_handle()); + f->set_neighbor(dimension(), Cell_handle()); + + // Update vertex->cell() pointers. + for (int i = 0; i < dimension(); ++i) + f->vertex(i)->set_cell(f); } delete_cells(to_delete.begin(), to_delete.end()); @@ -2630,33 +2961,33 @@ CGAL_triangulation_postcondition(is_valid()); } -template -typename Triangulation_data_structure_3::Cell_handle -Triangulation_data_structure_3:: +template +typename Triangulation_data_structure_3::Cell_handle +Triangulation_data_structure_3:: remove_from_maximal_dimension_simplex(Vertex_handle v) { CGAL_triangulation_precondition(dimension() >= 1); CGAL_triangulation_precondition(degree(v) == (size_type) dimension() + 1); CGAL_triangulation_precondition(number_of_vertices() > - (size_type) dimension() + 1); + (size_type) dimension() + 1); if (number_of_vertices() == (size_type) dimension() + 2) { - remove_decrease_dimension(v); - return Cell_handle(); + remove_decrease_dimension(v); + return Cell_handle(); } if (dimension() == 3) - return remove_degree_4(v); + return remove_degree_4(v); if (dimension() == 2) - return remove_degree_3(v); + return remove_degree_3(v); // dimension() == 1 return remove_degree_2(v); } -template -typename Triangulation_data_structure_3::Cell_handle -Triangulation_data_structure_3:: +template +typename Triangulation_data_structure_3::Cell_handle +Triangulation_data_structure_3:: remove_degree_2(Vertex_handle v) { CGAL_triangulation_precondition(dimension() == 1); @@ -2676,7 +3007,7 @@ // New cell : we copy the content of c0, so we keep the orientation. Cell_handle newc = create_face(c0->vertex(0), c0->vertex(1), - Vertex_handle()); + Vertex_handle()); newc->set_vertex(i0, c1->vertex(c1->index(c0))); @@ -2693,9 +3024,9 @@ return newc; } -template -typename Triangulation_data_structure_3::Cell_handle -Triangulation_data_structure_3:: +template +typename Triangulation_data_structure_3::Cell_handle +Triangulation_data_structure_3:: remove_degree_3(Vertex_handle v) { CGAL_triangulation_precondition(dimension() == 2); @@ -2737,9 +3068,9 @@ return newc; } -template -typename Triangulation_data_structure_3::Cell_handle -Triangulation_data_structure_3:: +template +typename Triangulation_data_structure_3::Cell_handle +Triangulation_data_structure_3:: remove_degree_4(Vertex_handle v) { CGAL_triangulation_precondition(dimension() == 3); @@ -2787,9 +3118,9 @@ return newc; } -template +template void -Triangulation_data_structure_3:: +Triangulation_data_structure_3:: decrease_dimension(Cell_handle c, int i) { CGAL_triangulation_expensive_precondition( is_valid() );; @@ -2846,13 +3177,13 @@ Vertex_handle v0 = c->vertex(0); Vertex_handle v1 = c->vertex(1); Vertex_handle v2 = c->vertex(2); - + int i0 = 0, i1 = 0, i2 = 0; - + for(int i=0; i<3; i++) if(n0->neighbor(i) == c) { i0 = i; break; } for(int i=0; i<3; i++) if(n1->neighbor(i) == c) { i1 = i; break; } - for(int i=0; i<3; i++) if(n2->neighbor(i) == c) { i2 = i; break; } - + for(int i=0; i<3; i++) if(n2->neighbor(i) == c) { i2 = i; break; } + Cell_handle c1 = create_cell(v, v0, v1, Vertex_handle()); Cell_handle c2 = create_cell(v, v1, v2, Vertex_handle()); @@ -2861,74 +3192,74 @@ c->set_vertex(2, v0); c->set_vertex(3, Vertex_handle()); - //Cell_handle c3 = create_cell(v, v2, v0, Vertex_handle()); + //Cell_handle c3 = create_cell(v, v2, v0, Vertex_handle()); Cell_handle c3 = c; - + c1->set_neighbor(0, n2); n2->set_neighbor(i2, c1); c1->set_neighbor(1, c2); c1->set_neighbor(2, c3); c1->set_neighbor(3, Cell_handle()); - + c2->set_neighbor(0, n0); n0->set_neighbor(i0, c2); c2->set_neighbor(1, c3); c2->set_neighbor(2, c1); - c2->set_neighbor(3, Cell_handle()); - + c2->set_neighbor(3, Cell_handle()); + c3->set_neighbor(0, n1); n1->set_neighbor(i1, c3); c3->set_neighbor(1, c1); c3->set_neighbor(2, c2); c3->set_neighbor(3, Cell_handle()); - + v->set_cell(c1); v0->set_cell(c1); v1->set_cell(c1); - v2->set_cell(c2); + v2->set_cell(c2); } - + if(dimension() == 1) { Cell_handle n0 = c->neighbor(0); Cell_handle n1 = c->neighbor(1); Vertex_handle v0 = c->vertex(0); Vertex_handle v1 = c->vertex(1); - + int i0 = 0 , i1 = 0; - + for(int i=0; i<2; i++) if(n0->neighbor(i) == c) { i0 = i; break; } for(int i=0; i<2; i++) if(n1->neighbor(i) == c) { i1 = i; break; } - + Cell_handle c1 = create_cell(v0, v, Vertex_handle(), Vertex_handle()); - + c->set_vertex(0, v); c->set_vertex(1, v1); c->set_vertex(2, Vertex_handle()); c->set_vertex(3, Vertex_handle()); - //Cell_handle c2 = create_cell(v, v1, Vertex_handle(), Vertex_handle()); + //Cell_handle c2 = create_cell(v, v1, Vertex_handle(), Vertex_handle()); Cell_handle c2 = c; - + c1->set_neighbor(0, c2); c1->set_neighbor(1, n1); n1->set_neighbor(i1, c1); c1->set_neighbor(2, Cell_handle()); c1->set_neighbor(3, Cell_handle()); - + c2->set_neighbor(0, n0); n0->set_neighbor(i0, c2); c2->set_neighbor(1, c1); c2->set_neighbor(2, Cell_handle()); c2->set_neighbor(3, Cell_handle()); - + v->set_cell(c1); v0->set_cell(c1); v1->set_cell(c2); } - + CGAL_triangulation_postcondition(is_valid()); } -template -typename Triangulation_data_structure_3::size_type -Triangulation_data_structure_3:: +template +typename Triangulation_data_structure_3::size_type +Triangulation_data_structure_3:: degree(Vertex_handle v) const { std::size_t res; @@ -2936,30 +3267,30 @@ return res; } -template +template bool -Triangulation_data_structure_3:: +Triangulation_data_structure_3:: is_valid(bool verbose, int level ) const { switch ( dimension() ) { case 3: { - + if(number_of_vertices() <= 4) { if (verbose) std::cerr << "wrong number of vertices" << std::endl; CGAL_triangulation_assertion(false); return false; } - + size_type vertex_count; if ( ! count_vertices(vertex_count,verbose,level) ) return false; if ( number_of_vertices() != vertex_count ) { - if (verbose) + if (verbose) std::cerr << "wrong number of vertices" << std::endl; - CGAL_triangulation_assertion(false); - return false; + CGAL_triangulation_assertion(false); + return false; } size_type cell_count; @@ -2967,125 +3298,125 @@ return false; size_type edge_count; if ( ! count_edges(edge_count,verbose,level) ) - return false; + return false; size_type facet_count; if ( ! count_facets(facet_count,verbose,level) ) - return false; + return false; // Euler relation if ( cell_count - facet_count + edge_count - vertex_count != 0 ) { - if (verbose) - std::cerr << "Euler relation unsatisfied" << std::endl; - CGAL_triangulation_assertion(false); - return false; + if (verbose) + std::cerr << "Euler relation unsatisfied" << std::endl; + CGAL_triangulation_assertion(false); + return false; } break; } case 2: { - + if(number_of_vertices() <= 3) { if (verbose) std::cerr << "wrong number of vertices" << std::endl; CGAL_triangulation_assertion(false); return false; } - + size_type vertex_count; if ( ! count_vertices(vertex_count,verbose,level) ) return false; if ( number_of_vertices() != vertex_count ) { - if (verbose) - std::cerr << "false number of vertices" << std::endl; - CGAL_triangulation_assertion(false); - return false; + if (verbose) + std::cerr << "false number of vertices" << std::endl; + CGAL_triangulation_assertion(false); + return false; } size_type edge_count; if ( ! count_edges(edge_count,verbose,level) ) - return false; + return false; // Euler for edges if ( edge_count != 3 * vertex_count - 6 ) { - if (verbose) - std::cerr << "Euler relation unsatisfied - edges/vertices" - << std::endl; - CGAL_triangulation_assertion(false); - return false; + if (verbose) + std::cerr << "Euler relation unsatisfied - edges/vertices" + << std::endl; + CGAL_triangulation_assertion(false); + return false; } size_type facet_count; if ( ! count_facets(facet_count,verbose,level) ) - return false; + return false; // Euler for facets if ( facet_count != 2 * vertex_count - 4 ) { - if (verbose) - std::cerr << "Euler relation unsatisfied - facets/vertices" - << std::endl; - CGAL_triangulation_assertion(false); - return false; + if (verbose) + std::cerr << "Euler relation unsatisfied - facets/vertices" + << std::endl; + CGAL_triangulation_assertion(false); + return false; } break; } case 1: { - + if(number_of_vertices() <= 1) { if (verbose) std::cerr << "wrong number of vertices" << std::endl; CGAL_triangulation_assertion(false); return false; } - + size_type vertex_count; if ( ! count_vertices(vertex_count,verbose,level) ) - return false; + return false; if ( number_of_vertices() != vertex_count ) { - if (verbose) - std::cerr << "false number of vertices" << std::endl; - CGAL_triangulation_assertion(false); - return false; + if (verbose) + std::cerr << "false number of vertices" << std::endl; + CGAL_triangulation_assertion(false); + return false; } size_type edge_count; if ( ! count_edges(edge_count,verbose,level) ) - return false; + return false; // Euler for edges if ( edge_count != vertex_count ) { - if (verbose) - std::cerr << "false number of edges" << std::endl; - CGAL_triangulation_assertion(false); - return false; + if (verbose) + std::cerr << "false number of edges" << std::endl; + CGAL_triangulation_assertion(false); + return false; } break; } case 0: { if ( number_of_vertices() < 2 ) { - if (verbose) - std::cerr << "less than 2 vertices but dimension 0" << std::endl; - CGAL_triangulation_assertion(false); - return false; + if (verbose) + std::cerr << "less than 2 vertices but dimension 0" << std::endl; + CGAL_triangulation_assertion(false); + return false; } // no break; continue } case -1: { if ( number_of_vertices() < 1 ) { - if (verbose) - std::cerr << "no vertex but dimension -1" << std::endl; - CGAL_triangulation_assertion(false); - return false; + if (verbose) + std::cerr << "no vertex but dimension -1" << std::endl; + CGAL_triangulation_assertion(false); + return false; } // vertex count size_type vertex_count; if ( ! count_vertices(vertex_count,verbose,level) ) - return false; + return false; if ( number_of_vertices() != vertex_count ) { - if (verbose) - std::cerr << "false number of vertices" << std::endl; - CGAL_triangulation_assertion(false); - return false; + if (verbose) + std::cerr << "false number of vertices" << std::endl; + CGAL_triangulation_assertion(false); + return false; } } } // end switch @@ -3094,9 +3425,9 @@ return true; } -template +template bool -Triangulation_data_structure_3:: +Triangulation_data_structure_3:: is_valid(Vertex_handle v, bool verbose, int level) const { bool result = v->is_valid(verbose,level); @@ -3109,38 +3440,38 @@ return result; } -template +template bool -Triangulation_data_structure_3:: +Triangulation_data_structure_3:: is_valid(Cell_handle c, bool verbose, int level) const { if ( ! c->is_valid(verbose, level) ) - return false; + return false; switch (dimension()) { case -2: case -1: { if ( c->vertex(0) == Vertex_handle() ) { - if (verbose) - std::cerr << "vertex 0 NULL" << std::endl; - CGAL_triangulation_assertion(false); - return false; + if (verbose) + std::cerr << "vertex 0 NULL" << std::endl; + CGAL_triangulation_assertion(false); + return false; } is_valid(c->vertex(0),verbose,level); if ( c->vertex(1) != Vertex_handle() || c->vertex(2) != Vertex_handle()) { - if (verbose) - std::cerr << "vertex 1 or 2 != NULL" << std::endl; - CGAL_triangulation_assertion(false); - return false; + if (verbose) + std::cerr << "vertex 1 or 2 != NULL" << std::endl; + CGAL_triangulation_assertion(false); + return false; } if ( c->neighbor(0) != Cell_handle() || - c->neighbor(1) != Cell_handle() || - c->neighbor(2) != Cell_handle()) { - if (verbose) - std::cerr << "one neighbor != NULL" << std::endl; - CGAL_triangulation_assertion(false); - return false; + c->neighbor(1) != Cell_handle() || + c->neighbor(2) != Cell_handle()) { + if (verbose) + std::cerr << "one neighbor != NULL" << std::endl; + CGAL_triangulation_assertion(false); + return false; } break; } @@ -3148,38 +3479,38 @@ case 0: { if ( c->vertex(0) == Vertex_handle() ) { - if (verbose) - std::cerr << "vertex 0 NULL" << std::endl; - CGAL_triangulation_assertion(false); - return false; + if (verbose) + std::cerr << "vertex 0 NULL" << std::endl; + CGAL_triangulation_assertion(false); + return false; } is_valid(c->vertex(0),verbose,level); if ( c->neighbor (0) == Cell_handle() ) { - if (verbose) - std::cerr << "neighbor 0 NULL" << std::endl; - CGAL_triangulation_assertion(false); - return false; + if (verbose) + std::cerr << "neighbor 0 NULL" << std::endl; + CGAL_triangulation_assertion(false); + return false; } if ( c->vertex(1) != Vertex_handle() || c->vertex(2) != Vertex_handle() ) { - if (verbose) - std::cerr << "vertex 1 or 2 != NULL" << std::endl; - CGAL_triangulation_assertion(false); - return false; + if (verbose) + std::cerr << "vertex 1 or 2 != NULL" << std::endl; + CGAL_triangulation_assertion(false); + return false; } if ( c->neighbor(1) != Cell_handle() || c->neighbor(2) != Cell_handle() ) { - if (verbose) - std::cerr << "neighbor 1 or 2 != NULL" << std::endl; - CGAL_triangulation_assertion(false); - return false; + if (verbose) + std::cerr << "neighbor 1 or 2 != NULL" << std::endl; + CGAL_triangulation_assertion(false); + return false; } if ( ! c->neighbor(0)->has_vertex(c->vertex(0)) ) { - if (verbose) - std::cerr << "neighbor 0 does not have vertex 0" << std::endl; - CGAL_triangulation_assertion(false); - return false; + if (verbose) + std::cerr << "neighbor 0 does not have vertex 0" << std::endl; + CGAL_triangulation_assertion(false); + return false; } break; } @@ -3192,48 +3523,48 @@ Cell_handle n1 = c->neighbor(1); if ( v0 == Vertex_handle() || v1 == Vertex_handle() ) { - if (verbose) - std::cerr << "vertex 0 or 1 NULL" << std::endl; - CGAL_triangulation_assertion(false); - return false; + if (verbose) + std::cerr << "vertex 0 or 1 NULL" << std::endl; + CGAL_triangulation_assertion(false); + return false; } is_valid(c->vertex(0),verbose,level); is_valid(c->vertex(1),verbose,level); if ( n0 == Cell_handle() || n1 == Cell_handle() ) { - if (verbose) - std::cerr << "neighbor 0 or 1 NULL" << std::endl; - CGAL_triangulation_assertion(false); - return false; + if (verbose) + std::cerr << "neighbor 0 or 1 NULL" << std::endl; + CGAL_triangulation_assertion(false); + return false; } if ( v0 != n1->vertex(1) ) { - if (verbose) - std::cerr << "neighbor 1 does not have vertex 0 as vertex 1" - << std::endl; - CGAL_triangulation_assertion(false); - return false; + if (verbose) + std::cerr << "neighbor 1 does not have vertex 0 as vertex 1" + << std::endl; + CGAL_triangulation_assertion(false); + return false; } if ( v1 != n0->vertex(0) ) { - if (verbose) - std::cerr << "neighbor 0 does not have vertex 1 as vertex 0" - << std::endl; - CGAL_triangulation_assertion(false); - return false; + if (verbose) + std::cerr << "neighbor 0 does not have vertex 1 as vertex 0" + << std::endl; + CGAL_triangulation_assertion(false); + return false; } if ( n0->neighbor(1) != c ) { - if (verbose) - std::cerr << "neighbor 0 does not have this as neighbor 1" - << std::endl; - CGAL_triangulation_assertion(false); - return false; + if (verbose) + std::cerr << "neighbor 0 does not have this as neighbor 1" + << std::endl; + CGAL_triangulation_assertion(false); + return false; } if ( n1->neighbor(0) != c ) { - if (verbose) - std::cerr << "neighbor 1 does not have this as neighbor 0" - << std::endl; - CGAL_triangulation_assertion(false); - return false; + if (verbose) + std::cerr << "neighbor 1 does not have this as neighbor 0" + << std::endl; + CGAL_triangulation_assertion(false); + return false; } break; @@ -3242,12 +3573,12 @@ case 2: { if ( c->vertex(0) == Vertex_handle() || - c->vertex(1) == Vertex_handle() || - c->vertex(2) == Vertex_handle() ) { - if (verbose) - std::cerr << "vertex 0, 1, or 2 NULL" << std::endl; - CGAL_triangulation_assertion(false); - return false; + c->vertex(1) == Vertex_handle() || + c->vertex(2) == Vertex_handle() ) { + if (verbose) + std::cerr << "vertex 0, 1, or 2 NULL" << std::endl; + CGAL_triangulation_assertion(false); + return false; } is_valid(c->vertex(0),verbose,level); is_valid(c->vertex(1),verbose,level); @@ -3255,181 +3586,182 @@ int in; Cell_handle n; for(int i = 0; i < 3; i++) { - n = c->neighbor(i); - if ( n == Cell_handle() ) { - if (verbose) - std::cerr << "neighbor " << i << " NULL" << std::endl; - CGAL_triangulation_assertion(false); - return false; - } - if ( ! n->has_vertex(c->vertex(cw(i)),in ) ) { - if (verbose) - std::cerr << "vertex " << cw(i) - << " not vertex of neighbor " << i << std::endl; - CGAL_triangulation_assertion(false); - return false; - } - in = cw(in); - if ( n->neighbor(in) != c ) { - if (verbose) - std::cerr << "neighbor " << i - << " does not have this as neighbor " - << in << std::endl; - CGAL_triangulation_assertion(false); - return false; - } - if ( c->vertex(ccw(i)) != n->vertex(cw(in)) ) { - if (verbose) - std::cerr << "vertex " << ccw(i) - << " is not vertex " << cw(in) - << " of neighbor " << i << std::endl; - CGAL_triangulation_assertion(false); - return false; - } + n = c->neighbor(i); + if ( n == Cell_handle() ) { + if (verbose) + std::cerr << "neighbor " << i << " NULL" << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + if ( ! n->has_vertex(c->vertex(cw(i)),in ) ) { + if (verbose) + std::cerr << "vertex " << cw(i) + << " not vertex of neighbor " << i << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + in = cw(in); + if ( n->neighbor(in) != c ) { + if (verbose) + std::cerr << "neighbor " << i + << " does not have this as neighbor " + << in << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + if ( c->vertex(ccw(i)) != n->vertex(cw(in)) ) { + if (verbose) + std::cerr << "vertex " << ccw(i) + << " is not vertex " << cw(in) + << " of neighbor " << i << std::endl; + CGAL_triangulation_assertion(false); + return false; + } } break; } case 3: { - int i; - for(i = 0; i < 4; i++) { - if ( c->vertex(i) == Vertex_handle() ) { - if (verbose) - std::cerr << "vertex " << i << " NULL" << std::endl; - CGAL_triangulation_assertion(false); - return false; - } - is_valid(c->vertex(i),verbose,level); - } - - for(i = 0; i < 4; i++) { - Cell_handle n = c->neighbor(i); - if ( n == Cell_handle() ) { - if (verbose) - std::cerr << "neighbor " << i << " NULL" << std::endl; - CGAL_triangulation_assertion(false); - return false; - } + int i; + for(i = 0; i < 4; i++) { + if ( c->vertex(i) == Vertex_handle() ) { + if (verbose) + std::cerr << "vertex " << i << " NULL" << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + is_valid(c->vertex(i),verbose,level); + } - int in = 5; - // if ( ! n->has_neighbor(handle(), in) ) { + for(i = 0; i < 4; i++) { + Cell_handle n = c->neighbor(i); + if ( n == Cell_handle() ) { + if (verbose) + std::cerr << "neighbor " << i << " NULL" << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + + int in = 5; + // if ( ! n->has_neighbor(handle(), in) ) { if ( n->neighbor(0) == c) in = 0; if ( n->neighbor(1) == c) in = 1; if ( n->neighbor(2) == c) in = 2; if ( n->neighbor(3) == c) in = 3; if (in == 5) { - if (verbose) + if (verbose) std::cerr << "neighbor of c has not c as neighbor" << std::endl; - CGAL_triangulation_assertion(false); - return false; - } - - int j1n,j2n,j3n; - if ( ! n->has_vertex(c->vertex((i+1)&3),j1n) ) { - if (verbose) { std::cerr << "vertex " << ((i+1)&3) - << " not vertex of neighbor " - << i << std::endl; } - CGAL_triangulation_assertion(false); - return false; - } - if ( ! n->has_vertex(c->vertex((i+2)&3),j2n) ) { - if (verbose) { std::cerr << "vertex " << ((i+2)&3) - << " not vertex of neighbor " - << i << std::endl; } - CGAL_triangulation_assertion(false); - return false; - } - if ( ! n->has_vertex(c->vertex((i+3)&3),j3n) ) { - if (verbose) { std::cerr << "vertex " << ((i+3)&3) - << " not vertex of neighbor " - << i << std::endl; } - CGAL_triangulation_assertion(false); - return false; - } - - if ( in+j1n+j2n+j3n != 6) { - if (verbose) { std::cerr << "sum of the indices != 6 " - << std::endl; } - CGAL_triangulation_assertion(false); - return false; - } - - // tests whether the orientations of this and n are consistent - if ( ((i+in)&1) == 0 ) { // i and in have the same parity - if ( j1n == ((in+1)&3) ) { - if ( ( j2n != ((in+3)&3) ) || ( j3n != ((in+2)&3) ) ) { - if (verbose) + CGAL_triangulation_assertion(false); + return false; + } + + int j1n,j2n,j3n; + if ( ! n->has_vertex(c->vertex((i+1)&3),j1n) ) { + if (verbose) { std::cerr << "vertex " << ((i+1)&3) + << " not vertex of neighbor " + << i << std::endl; } + CGAL_triangulation_assertion(false); + return false; + } + if ( ! n->has_vertex(c->vertex((i+2)&3),j2n) ) { + if (verbose) { std::cerr << "vertex " << ((i+2)&3) + << " not vertex of neighbor " + << i << std::endl; } + CGAL_triangulation_assertion(false); + return false; + } + if ( ! n->has_vertex(c->vertex((i+3)&3),j3n) ) { + if (verbose) { std::cerr << "vertex " << ((i+3)&3) + << " not vertex of neighbor " + << i << std::endl; } + CGAL_triangulation_assertion(false); + return false; + } + + if ( in+j1n+j2n+j3n != 6) { + if (verbose) { std::cerr << "sum of the indices != 6 " + << std::endl; } + CGAL_triangulation_assertion(false); + return false; + } + + // tests whether the orientations of this and n are consistent + if ( ((i+in)&1) == 0 ) { // i and in have the same parity + if ( j1n == ((in+1)&3) ) { + if ( ( j2n != ((in+3)&3) ) || ( j3n != ((in+2)&3) ) ) { + if (verbose) std::cerr << " pb orientation with neighbor " << i << std::endl; - CGAL_triangulation_assertion(false); - return false; - } - } - if ( j1n == ((in+2)&3) ) { - if ( ( j2n != ((in+1)&3) ) || ( j3n != ((in+3)&3) ) ) { - if (verbose) + CGAL_triangulation_assertion(false); + return false; + } + } + if ( j1n == ((in+2)&3) ) { + if ( ( j2n != ((in+1)&3) ) || ( j3n != ((in+3)&3) ) ) { + if (verbose) std::cerr << " pb orientation with neighbor " << i << std::endl; - CGAL_triangulation_assertion(false); - return false; - } - } - if ( j1n == ((in+3)&3) ) { - if ( ( j2n != ((in+2)&3) ) || ( j3n != ((in+1)&3) ) ) { - if (verbose) + CGAL_triangulation_assertion(false); + return false; + } + } + if ( j1n == ((in+3)&3) ) { + if ( ( j2n != ((in+2)&3) ) || ( j3n != ((in+1)&3) ) ) { + if (verbose) std::cerr << " pb orientation with neighbor " << i << std::endl; - CGAL_triangulation_assertion(false); - return false; - } - } - } - else { // i and in do not have the same parity - if ( j1n == ((in+1)&3) ) { - if ( ( j2n != ((in+2)&3) ) || ( j3n != ((in+3)&3) ) ) { - if (verbose) + CGAL_triangulation_assertion(false); + return false; + } + } + } + else { // i and in do not have the same parity + if ( j1n == ((in+1)&3) ) { + if ( ( j2n != ((in+2)&3) ) || ( j3n != ((in+3)&3) ) ) { + if (verbose) std::cerr << " pb orientation with neighbor " << i << std::endl; - CGAL_triangulation_assertion(false); - return false; - } - } - if ( j1n == ((in+2)&3) ) { - if ( ( j2n != ((in+3)&3) ) || ( j3n != ((in+1)&3) ) ) { - if (verbose) + CGAL_triangulation_assertion(false); + return false; + } + } + if ( j1n == ((in+2)&3) ) { + if ( ( j2n != ((in+3)&3) ) || ( j3n != ((in+1)&3) ) ) { + if (verbose) std::cerr << " pb orientation with neighbor " << i << std::endl; - CGAL_triangulation_assertion(false); - return false; - } - } - if ( j1n == ((in+3)&3) ) { - if ( ( j2n != ((in+1)&3) ) || ( j3n != ((in+2)&3) ) ) { - if (verbose) + CGAL_triangulation_assertion(false); + return false; + } + } + if ( j1n == ((in+3)&3) ) { + if ( ( j2n != ((in+1)&3) ) || ( j3n != ((in+2)&3) ) ) { + if (verbose) std::cerr << " pb orientation with neighbor " << i << std::endl; - CGAL_triangulation_assertion(false); - return false; - } - } - } - } // end looking at neighbors + CGAL_triangulation_assertion(false); + return false; + } + } + } + } // end looking at neighbors }// end case dim 3 } // end switch return true; } -template + +template template -typename Triangulation_data_structure_3::Vertex_handle -Triangulation_data_structure_3:: +typename Triangulation_data_structure_3::Vertex_handle +Triangulation_data_structure_3:: copy_tds(const TDS_src& tds, typename TDS_src::Vertex_handle vert, const ConvertVertex& convert_vertex, const ConvertCell& convert_cell) { CGAL_triangulation_expensive_precondition( vert == Vertex_handle() - || tds.is_vertex(vert) ); + || tds.is_vertex(vert) ); clear(); @@ -3462,7 +3794,7 @@ // Create the cells. for (typename TDS_src::Cell_iterator cit = tds.cells().begin(); - cit != tds.cells_end(); ++cit) { + cit != tds.cells_end(); ++cit) { Cell_handle ch=create_cell(convert_cell(*cit)); F[cit]=ch; for (int j = 0; j < dim; j++) @@ -3477,7 +3809,7 @@ // Hook neighbor pointers of the cells. for (typename TDS_src::Cell_iterator cit2 = tds.cells().begin(); - cit2 != tds.cells_end(); ++cit2) { + cit2 != tds.cells_end(); ++cit2) { for (int j = 0; j < dim; j++) F[cit2]->set_neighbor(j, F[cit2->neighbor(j)] ); } @@ -3529,10 +3861,10 @@ }; } } //namespace internal::TDS_3 -template +template template -typename Triangulation_data_structure_3::Vertex_handle -Triangulation_data_structure_3:: +typename Triangulation_data_structure_3::Vertex_handle +Triangulation_data_structure_3:: copy_tds(const TDS_src& src,typename TDS_src::Vertex_handle vert) { internal::TDS_3::Default_vertex_converter setv; @@ -3540,9 +3872,9 @@ return copy_tds(src,vert,setv,setc); } -template +template void -Triangulation_data_structure_3:: +Triangulation_data_structure_3:: swap(Tds & tds) { CGAL_triangulation_expensive_precondition(tds.is_valid() && is_valid()); @@ -3552,9 +3884,9 @@ vertices().swap(tds.vertices()); } -template +template void -Triangulation_data_structure_3:: +Triangulation_data_structure_3:: clear() { cells().clear(); @@ -3562,9 +3894,9 @@ set_dimension(-2); } -template +template bool -Triangulation_data_structure_3:: +Triangulation_data_structure_3:: count_vertices(size_type & i, bool verbose, int level) const // counts AND checks the validity { @@ -3573,7 +3905,7 @@ for (Vertex_iterator it = vertices_begin(); it != vertices_end(); ++it) { if ( ! is_valid(it,verbose,level) ) { if (verbose) - std::cerr << "invalid vertex" << std::endl; + std::cerr << "invalid vertex" << std::endl; CGAL_triangulation_assertion(false); return false; } @@ -3582,9 +3914,9 @@ return true; } -template +template bool -Triangulation_data_structure_3:: +Triangulation_data_structure_3:: count_facets(size_type & i, bool verbose, int level) const // counts but does not check { @@ -3593,7 +3925,7 @@ for (Facet_iterator it = facets_begin(); it != facets_end(); ++it) { if ( ! is_valid((*it).first,verbose, level) ) { if (verbose) - std::cerr << "invalid facet" << std::endl; + std::cerr << "invalid facet" << std::endl; CGAL_triangulation_assertion(false); return false; } @@ -3602,9 +3934,9 @@ return true; } -template +template bool -Triangulation_data_structure_3:: +Triangulation_data_structure_3:: count_edges(size_type & i, bool verbose, int level) const // counts but does not check { @@ -3613,7 +3945,7 @@ for (Edge_iterator it = edges_begin(); it != edges_end(); ++it) { if ( ! is_valid((*it).first,verbose, level) ) { if (verbose) - std::cerr << "invalid edge" << std::endl; + std::cerr << "invalid edge" << std::endl; CGAL_triangulation_assertion(false); return false; } @@ -3622,9 +3954,9 @@ return true; } -template +template bool -Triangulation_data_structure_3:: +Triangulation_data_structure_3:: count_cells(size_type & i, bool verbose, int level) const // counts AND checks the validity { @@ -3633,7 +3965,7 @@ for (Cell_iterator it = cells_begin(); it != cells_end(); ++it) { if ( ! is_valid(it,verbose, level) ) { if (verbose) - std::cerr << "invalid cell" << std::endl; + std::cerr << "invalid cell" << std::endl; CGAL_triangulation_assertion(false); return false; } diff -Nru cgal-4.4/include/CGAL/Triangulation_ds_cell_base_3.h cgal-4.5/include/CGAL/Triangulation_ds_cell_base_3.h --- cgal-4.4/include/CGAL/Triangulation_ds_cell_base_3.h 2013-08-03 19:00:28.000000000 +0000 +++ cgal-4.5/include/CGAL/Triangulation_ds_cell_base_3.h 2014-08-29 13:58:17.000000000 +0000 @@ -33,24 +33,42 @@ class Triangulation_ds_cell_base_3 { public: - typedef TDS Triangulation_data_structure; - typedef typename TDS::Vertex_handle Vertex_handle; - typedef typename TDS::Cell_handle Cell_handle; - typedef typename TDS::Vertex Vertex; - typedef typename TDS::Cell Cell; - typedef typename TDS::Cell_data TDS_data; + typedef TDS Triangulation_data_structure; + typedef typename TDS::Vertex_handle Vertex_handle; + typedef typename TDS::Cell_handle Cell_handle; + typedef typename TDS::Vertex Vertex; + typedef typename TDS::Cell Cell; + typedef typename TDS::Cell_data TDS_data; template struct Rebind_TDS { typedef Triangulation_ds_cell_base_3 Other; }; - Triangulation_ds_cell_base_3() {} + Triangulation_ds_cell_base_3() + { +#ifdef SHOW_REMAINING_BAD_ELEMENT_IN_RED + mark = -1; + mark2 = -1; +#endif + } Triangulation_ds_cell_base_3(Vertex_handle v0, Vertex_handle v1, Vertex_handle v2, Vertex_handle v3) #ifndef CGAL_CFG_NO_CPP0X_UNIFIED_INITIALIZATION_SYNTAX - : V{v0, v1, v2, v3} {} + : V{v0, v1, v2, v3} + { +#ifdef SHOW_REMAINING_BAD_ELEMENT_IN_RED + mark = -1; + mark2 = -1; +#endif + } #else - { set_vertices(v0, v1, v2, v3); } + { + set_vertices(v0, v1, v2, v3); +#ifdef SHOW_REMAINING_BAD_ELEMENT_IN_RED + mark = -1; + mark2 = -1; +#endif + } #endif Triangulation_ds_cell_base_3(Vertex_handle v0, Vertex_handle v1, @@ -63,6 +81,10 @@ { set_neighbors(n0, n1, n2, n3); set_vertices(v0, v1, v2, v3); +#ifdef SHOW_REMAINING_BAD_ELEMENT_IN_RED + mark = -1; + mark2 = -1; +#endif } #endif @@ -201,6 +223,11 @@ // TDS internal data access functions. TDS_data& tds_data() { return _tds_data; } const TDS_data& tds_data() const { return _tds_data; } + +#ifdef SHOW_REMAINING_BAD_ELEMENT_IN_RED + int mark; + int mark2; +#endif private: diff -Nru cgal-4.4/include/CGAL/Triangulation_ds_vertex_base_3.h cgal-4.5/include/CGAL/Triangulation_ds_vertex_base_3.h --- cgal-4.4/include/CGAL/Triangulation_ds_vertex_base_3.h 2012-11-13 13:14:02.000000000 +0000 +++ cgal-4.5/include/CGAL/Triangulation_ds_vertex_base_3.h 2014-08-29 13:58:17.000000000 +0000 @@ -36,17 +36,22 @@ template struct Rebind_TDS { typedef Triangulation_ds_vertex_base_3 Other; }; + Triangulation_ds_vertex_base_3() - : _c() {} + : _c(), visited_for_vertex_extractor(false) + {} Triangulation_ds_vertex_base_3(Cell_handle c) - : _c(c) {} + : _c(c), visited_for_vertex_extractor(false) + {} - Cell_handle cell() const - { return _c; } + Cell_handle cell() const + { return _c; } void set_cell(Cell_handle c) - { _c = c; } + { + _c = c; + } // the following trivial is_valid allows // the user of derived cell base classes @@ -64,6 +69,13 @@ private: Cell_handle _c; + + // The typedef and the bool are used by Triangulation_data_structure::Vertex_extractor + // The names are chooses complicated so that we do not have to document them + // (privacy by obfuscation) + public: + typedef bool Has_visited_for_vertex_extractor; + bool visited_for_vertex_extractor; }; template < class TDS > diff -Nru cgal-4.4/include/CGAL/typeset.h cgal-4.5/include/CGAL/typeset.h --- cgal-4.4/include/CGAL/typeset.h 1970-01-01 00:00:00.000000000 +0000 +++ cgal-4.5/include/CGAL/typeset.h 2014-08-29 13:58:16.000000000 +0000 @@ -0,0 +1,117 @@ +// Copyright (c) 2014 +// INRIA Saclay-Ile de France (France) +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Marc Glisse + +#ifndef CGAL_TYPESET_H +#define CGAL_TYPESET_H +#include +#ifdef CGAL_CXX11 +#include +#else +#include +#endif + +// Sometimes using tuple just to list types is overkill (takes forever to +// instantiate). + +namespace CGAL { +#ifdef CGAL_CXX11 + template struct typeset; + template struct typeset { + typedef H head; + typedef typeset tail; + typedef typeset type; + template using contains = typename + std::conditional< + std::is_same::value, + std::true_type, + typename tail::template contains + >::type; + template using add = typename + std::conditional< + contains::value, + typeset, + typeset + >::type; + }; + template<> struct typeset<> { + typedef typeset type; + template using contains = std::false_type; + template using add = typeset; + }; +#else + template struct typeset; + template, void, typeset >::type > + struct typeset { + typedef typeset type; + typedef H head; + typedef T tail; + template struct contains : + boost::mpl::if_,boost::true_type,typename tail::template contains >::type + {}; + template struct add; + //boost::mpl::if_,typeset,typeset >::type + }; + template<> struct typeset<> { + typedef typeset type; + template struct contains : boost::false_type {}; + template struct add : CGAL::typeset {}; + }; + + template + template + struct typeset::add : typeset::type> {}; + template + template + struct typeset::add : typeset {}; +#endif + + template struct typeset_union_ : + typeset_union_::type, typename T2::tail> + {}; + template struct typeset_union_ > : T {}; + + template + struct typeset_intersection_ { + typedef typename T1::head H; + typedef typename typeset_intersection_::type U; + typedef typename +#ifdef CGAL_CXX11 + std::conditional::value, +#else + boost::mpl::if_, +#endif + typename U::template add::type, U>::type type; + }; + template + struct typeset_intersection_,T> : typeset<> {}; + +#ifdef CGAL_CXX11 + template + using typeset_union = typename typeset_union_::type; + template + using typeset_intersection = typename typeset_intersection_::type; +#else + template + struct typeset_union : typeset_union_::type {}; + template + struct typeset_intersection : typeset_intersection_::type {}; +#endif +} +#endif diff -Nru cgal-4.4/include/CGAL/Umbilics.h cgal-4.5/include/CGAL/Umbilics.h --- cgal-4.4/include/CGAL/Umbilics.h 2013-11-16 20:00:24.000000000 +0000 +++ cgal-4.5/include/CGAL/Umbilics.h 2014-08-29 13:58:17.000000000 +0000 @@ -15,7 +15,7 @@ // $URL$ // $Id$ // -// Author(s) : Marc Pouget and Frédéric Cazals +// Author(s) : Marc Pouget and Frédéric Cazals #ifndef CGAL_UMBILIC_H_ #define CGAL_UMBILIC_H_ diff -Nru cgal-4.4/include/CGAL/Unique_hash_map.h cgal-4.5/include/CGAL/Unique_hash_map.h --- cgal-4.4/include/CGAL/Unique_hash_map.h 2012-11-13 13:13:55.000000000 +0000 +++ cgal-4.5/include/CGAL/Unique_hash_map.h 2014-08-29 13:58:16.000000000 +0000 @@ -27,6 +27,7 @@ #define CGAL_UNIQUE_HASH_MAP_H #include +#include #include #include #include @@ -34,22 +35,24 @@ namespace CGAL { template + class UniqueHashFunction = Handle_hash_function, + class Allocator_ = CGAL_ALLOCATOR(Data_) > class Unique_hash_map { public: typedef Key_ Key; typedef Data_ Data; typedef UniqueHashFunction Hash_function; + typedef Allocator_ Allocator; // STL compliance typedef Key_ key_type; typedef Data_ data_type; typedef UniqueHashFunction hasher; - typedef Unique_hash_map Self; + typedef Unique_hash_map Self; private: - typedef internal::chained_map Map; + typedef internal::chained_map Map; typedef typename Map::item Item; private: diff -Nru cgal-4.4/include/CGAL/vector.h cgal-4.5/include/CGAL/vector.h --- cgal-4.4/include/CGAL/vector.h 2012-11-13 13:14:00.000000000 +0000 +++ cgal-4.5/include/CGAL/vector.h 2014-08-29 13:58:17.000000000 +0000 @@ -32,6 +32,9 @@ #include #include #include +#include +#include +#include namespace CGAL { @@ -118,6 +121,24 @@ bool operator> ( const Self& i) const { return i < *this; } bool operator<=( const Self& i) const { return !(i < *this); } bool operator>=( const Self& i) const { return !(*this < i); } + + vector_iterator< T, + typename boost::remove_const< + typename boost::remove_reference::type + >::type&, + typename boost::remove_const< + typename boost::remove_pointer::type + >::type* > + remove_const() const + { + typedef typename boost::remove_const< + typename boost::remove_pointer::type + >::type* Ptr_no_c; + return vector_iterator< T, + typename boost::remove_const::type>::type&, + Ptr_no_c> + ( const_cast(ptr) ); + } }; template < class T, class Ref, class Ptr> inline diff -Nru cgal-4.4/include/CGAL/version.h cgal-4.5/include/CGAL/version.h --- cgal-4.4/include/CGAL/version.h 2014-04-03 19:02:08.000000000 +0000 +++ cgal-4.5/include/CGAL/version.h 2014-10-09 19:00:35.000000000 +0000 @@ -26,10 +26,10 @@ #define CGAL_xstr(s) #s #define CGAL_str(s) CGAL_xstr(s) -#define CGAL_VERSION 4.4 -#define CGAL_VERSION_NR 1040401000 +#define CGAL_VERSION 4.5 +#define CGAL_VERSION_NR 1040501000 #define CGAL_SVN_REVISION 99999 -#define CGAL_GIT_HASH 611cccf68c5eca6318f4055be6f12d43ce9ef627 +#define CGAL_GIT_HASH 86ae58ef9f4ef15b328a4d61ef4c826f48c1f1c5 #define CGAL_VERSION_STR CGAL_str(CGAL_VERSION) #endif diff -Nru cgal-4.4/INSTALL cgal-4.5/INSTALL --- cgal-4.4/INSTALL 2012-11-13 13:13:55.000000000 +0000 +++ cgal-4.5/INSTALL 2014-08-29 13:58:16.000000000 +0000 @@ -95,16 +95,6 @@ http://www.netlib.org/blas/, http://www.netlib.org/lapack/ or precompiled version that can be downloaded with CGAL-x.y-Setup.exe - - TAUCS (sparse matrix solver) - Required by the package (if EIGEN is not available): - o Surface Reconstruction from Point Sets - Accelerates the package: - o Planar Parameterization of Triangulated Surface Meshes - http://www.tau.ac.il/~stoledo/taucs/ - The version to used is available at - https://gforge.inria.fr/frs/download.php/24628/taucs_full.tgz - or automatically downloaded with CGAL-x.y-Setup.exe on Windows. - - MPFI Required by the package: o Algebraic Kernel diff -Nru cgal-4.4/scripts/cgal_create_CMakeLists cgal-4.5/scripts/cgal_create_CMakeLists --- cgal-4.4/scripts/cgal_create_CMakeLists 2012-11-13 13:14:00.000000000 +0000 +++ cgal-4.5/scripts/cgal_create_CMakeLists 2014-08-29 13:58:17.000000000 +0000 @@ -33,7 +33,6 @@ #MPFR #MPFI #RS -#TAUCS #BLAS #LAPACK #OPENNL @@ -97,7 +96,7 @@ # print makefile header #vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv cat << 'EOF' -# Created by the script cgal_create_cmake_script_with_options +# Created by the script cgal_create_CMakeLists # This is the CMake script for compiling a set of CGAL applications. EOF @@ -157,7 +156,6 @@ CGAL_COMPONENTS=${CGAL_COMPONENTS//[r|R][s|S]/RS} CGAL_COMPONENTS=${CGAL_COMPONENTS//[o|O][p|P][e|E][n|N][n|N][l|L]/OpenNL} - CGAL_COMPONENTS=${CGAL_COMPONENTS//[t|T][a|A][u|U][c|C][s|S]/TAUCS} CGAL_COMPONENTS=${CGAL_COMPONENTS//[b|B][l|L][a|A][s|S]/BLAS} CGAL_COMPONENTS=${CGAL_COMPONENTS//[l|L][a|A][p|P][a|A][c|C][k|K]/LAPACK} diff -Nru cgal-4.4/src/CGAL/assertions.cpp cgal-4.5/src/CGAL/assertions.cpp --- cgal-4.4/src/CGAL/assertions.cpp 2012-11-13 13:14:00.000000000 +0000 +++ cgal-4.5/src/CGAL/assertions.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -20,7 +20,7 @@ // $Id$ // // -// Author(s) : Geert-Jan Giezeman and Sven Schönherr +// Author(s) : Geert-Jan Giezeman and Sven Schönherr #include #include diff -Nru cgal-4.4/src/CGAL/Color.cpp cgal-4.5/src/CGAL/Color.cpp --- cgal-4.4/src/CGAL/Color.cpp 2012-11-13 13:14:01.000000000 +0000 +++ cgal-4.5/src/CGAL/Color.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -20,7 +20,7 @@ // $Id$ // // -// Author(s) : Andreas Fabri, Hervé Brönnimann +// Author(s) : Andreas Fabri, Hervé Brönnimann #include diff -Nru cgal-4.4/src/CGAL/Random.cpp cgal-4.5/src/CGAL/Random.cpp --- cgal-4.4/src/CGAL/Random.cpp 2012-11-13 13:14:00.000000000 +0000 +++ cgal-4.5/src/CGAL/Random.cpp 2014-08-29 13:58:17.000000000 +0000 @@ -20,7 +20,7 @@ // $Id$ // // -// Author(s) : Sven Schönherr +// Author(s) : Sven Schönherr #include #include diff -Nru cgal-4.4/src/CGAL_ImageIO/CMakeLists.txt cgal-4.5/src/CGAL_ImageIO/CMakeLists.txt --- cgal-4.4/src/CGAL_ImageIO/CMakeLists.txt 2012-11-13 13:13:54.000000000 +0000 +++ cgal-4.5/src/CGAL_ImageIO/CMakeLists.txt 2014-08-29 13:58:16.000000000 +0000 @@ -34,7 +34,7 @@ cache_set(CGAL_ImageIO_3RD_PARTY_DEFINITIONS ${CGAL_ImageIO_3RD_PARTY_DEFINITIONS} -DCGAL_USE_VTK ${VTK_REQUIRED_CXX_FLAGS}) cache_set(CGAL_ImageIO_3RD_PARTY_INCLUDE_DIRS ${CGAL_ImageIO_3RD_PARTY_INCLUDE_DIRS} ${VTK_INCLUDE_DIRS} ) cache_set(CGAL_ImageIO_3RD_PARTY_LIBRARIES_DIRS ${CGAL_ImageIO_3RD_PARTY_LIBRARIES_DIRS} ${VTK_LIBRARY_DIRS} ) - cache_set(CGAL_ImageIO_3RD_PARTY_LIBRARIES ${CGAL_ImageIO_3RD_PARTY_LIBRARIES} vtkImaging vtkIO ) + cache_set(CGAL_ImageIO_3RD_PARTY_LIBRARIES ${CGAL_ImageIO_3RD_PARTY_LIBRARIES} ${VTK_LIBRARIES} ) else() message(STATUS "VTK not found.") diff -Nru cgal-4.4/src/CGAL_ImageIO/convert.cpp cgal-4.5/src/CGAL_ImageIO/convert.cpp --- cgal-4.4/src/CGAL_ImageIO/convert.cpp 2012-11-13 13:13:54.000000000 +0000 +++ cgal-4.5/src/CGAL_ImageIO/convert.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -24,7 +24,7 @@ * * $Id$ * - * Copyright©INRIA 1999 + * Copyright©INRIA 1999 * * AUTHOR: * Gregoire Malandain (greg@sophia.inria.fr) diff -Nru cgal-4.4/src/CGAL_ImageIO/convert.h cgal-4.5/src/CGAL_ImageIO/convert.h --- cgal-4.4/src/CGAL_ImageIO/convert.h 2012-11-13 13:13:54.000000000 +0000 +++ cgal-4.5/src/CGAL_ImageIO/convert.h 2014-08-29 13:58:16.000000000 +0000 @@ -24,7 +24,7 @@ * * $Id$ * - * Copyright©INRIA 1998 + * Copyright©INRIA 1998 * * AUTHOR: * Gregoire Malandain (greg@sophia.inria.fr) diff -Nru cgal-4.4/src/CGAL_ImageIO/gis.h cgal-4.5/src/CGAL_ImageIO/gis.h --- cgal-4.4/src/CGAL_ImageIO/gis.h 2012-11-13 13:13:54.000000000 +0000 +++ cgal-4.5/src/CGAL_ImageIO/gis.h 2014-08-29 13:58:16.000000000 +0000 @@ -44,20 +44,20 @@ -txt image acquise sur SIGNA 1.5T au CHRU de Caen donnees brutes sans traitement -endtxt -- la première ligne comporte les dimensions de l'image, respectivement, le nombre de colonnes, de lignes, de coupes et de temps; ces deux, trois ou quatre entiers doivent être strictement positifs et rester inférieurs à 4096. +- la première ligne comporte les dimensions de l'image, respectivement, le nombre de colonnes, de lignes, de coupes et de temps; ces deux, trois ou quatre entiers doivent être strictement positifs et rester inférieurs à 4096. - les lignes suivantes comportent des champs indiques par des mots clefs: -type typespecifier - U8 entier non signé codé sur 8 bit (unsigned char) - S8 entier signé codé sur 8 bit (signed char) - U16 entier non signé codé sur 16 bit (unsigned short) - S16 entier signé codé sur 16 bit (signed short) - U32 entier non signé codé sur 32 bit (unsigned int) - S32 entier signé codé sur 32 bit (signed int) - FLOAT flottant simple précision (float) - DOUBLE flottant double précision (double) + U8 entier non signé codé sur 8 bit (unsigned char) + S8 entier signé codé sur 8 bit (signed char) + U16 entier non signé codé sur 16 bit (unsigned short) + S16 entier signé codé sur 16 bit (signed short) + U32 entier non signé codé sur 32 bit (unsigned int) + S32 entier signé codé sur 32 bit (signed int) + FLOAT flottant simple précision (float) + DOUBLE flottant double précision (double) -dx double (taille du voxel en x) -dy double (taille du voxel en y) @@ -66,7 +66,7 @@ -dt double (taille du voxel en t) (taille donnee en secondes) - (spécification d'un sous-volume) + (spécification d'un sous-volume) -x1 entier -x2 entier -y1 entier diff -Nru cgal-4.4/src/CGAL_ImageIO/inr.cpp cgal-4.5/src/CGAL_ImageIO/inr.cpp --- cgal-4.4/src/CGAL_ImageIO/inr.cpp 2013-05-04 19:00:25.000000000 +0000 +++ cgal-4.5/src/CGAL_ImageIO/inr.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -277,13 +277,13 @@ was used. However the man said ... - n Nothing is expected; instead, the number of charac­ + n Nothing is expected; instead, the number of charac­ ters consumed thus far from the input is stored through the next pointer, which must be a pointer to int. This is not a conversion, although it can be suppressed with the * flag. The C standard - says: `Execution of a %n directive does not incre­ - ment the assignment count returned at the comple­ + says: `Execution of a %n directive does not incre­ + ment the assignment count returned at the comple­ tion of execution' but the Corrigendum seems to contradict this. Probably it is wise not to make any assumptions on the effect of %n conversions on diff -Nru cgal-4.4/src/CGAL_ImageIO/recbuffer.cpp cgal-4.5/src/CGAL_ImageIO/recbuffer.cpp --- cgal-4.4/src/CGAL_ImageIO/recbuffer.cpp 2012-11-13 13:13:54.000000000 +0000 +++ cgal-4.5/src/CGAL_ImageIO/recbuffer.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -24,7 +24,7 @@ * * $Id$ * - * Copyright©INRIA 1999 + * Copyright©INRIA 1999 * * DESCRIPTION: * diff -Nru cgal-4.4/src/CGAL_ImageIO/recbuffer.h cgal-4.5/src/CGAL_ImageIO/recbuffer.h --- cgal-4.4/src/CGAL_ImageIO/recbuffer.h 2012-11-13 13:13:54.000000000 +0000 +++ cgal-4.5/src/CGAL_ImageIO/recbuffer.h 2014-08-29 13:58:16.000000000 +0000 @@ -24,7 +24,7 @@ * * $Id$ * - * Copyright©INRIA 1999 + * Copyright©INRIA 1999 * * DESCRIPTION: * diff -Nru cgal-4.4/src/CGAL_ImageIO/recline.cpp cgal-4.5/src/CGAL_ImageIO/recline.cpp --- cgal-4.4/src/CGAL_ImageIO/recline.cpp 2012-11-13 13:13:54.000000000 +0000 +++ cgal-4.5/src/CGAL_ImageIO/recline.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -24,7 +24,7 @@ * * $Id$ * - * Copyright©INRIA 1999 + * Copyright©INRIA 1999 * * DESCRIPTION: * diff -Nru cgal-4.4/src/CGAL_ImageIO/recline.h cgal-4.5/src/CGAL_ImageIO/recline.h --- cgal-4.4/src/CGAL_ImageIO/recline.h 2012-11-13 13:13:54.000000000 +0000 +++ cgal-4.5/src/CGAL_ImageIO/recline.h 2014-08-29 13:58:16.000000000 +0000 @@ -24,7 +24,7 @@ * * $Id$ * - * Copyright©INRIA 1998 + * Copyright©INRIA 1998 * * DESCRIPTION: * diff -Nru cgal-4.4/src/CGAL_ImageIO/reech4x4.cpp cgal-4.5/src/CGAL_ImageIO/reech4x4.cpp --- cgal-4.4/src/CGAL_ImageIO/reech4x4.cpp 2012-11-13 13:13:54.000000000 +0000 +++ cgal-4.5/src/CGAL_ImageIO/reech4x4.cpp 2014-08-29 13:58:16.000000000 +0000 @@ -24,7 +24,7 @@ * * $Id$ * - * Copyright©INRIA 1999 + * Copyright©INRIA 1999 * * AUTHOR: * Gregoire Malandain (greg@sophia.inria.fr) diff -Nru cgal-4.4/src/CGAL_ImageIO/reech4x4.h cgal-4.5/src/CGAL_ImageIO/reech4x4.h --- cgal-4.4/src/CGAL_ImageIO/reech4x4.h 2012-11-13 13:13:54.000000000 +0000 +++ cgal-4.5/src/CGAL_ImageIO/reech4x4.h 2014-08-29 13:58:16.000000000 +0000 @@ -24,7 +24,7 @@ * * $Id$ * - * Copyright©INRIA 1999 + * Copyright©INRIA 1999 * * AUTHOR: * Gregoire Malandain (greg@sophia.inria.fr) diff -Nru cgal-4.4/src/CGAL_ImageIO/typedefs.h cgal-4.5/src/CGAL_ImageIO/typedefs.h --- cgal-4.4/src/CGAL_ImageIO/typedefs.h 2012-11-13 13:13:54.000000000 +0000 +++ cgal-4.5/src/CGAL_ImageIO/typedefs.h 2014-08-29 13:58:16.000000000 +0000 @@ -24,7 +24,7 @@ * * $Id$ * - * Copyright©INRIA 1998 + * Copyright©INRIA 1998 * * AUTHOR: * Gregoire Malandain (greg@sophia.inria.fr) diff -Nru cgal-4.4/src/CMakeLists.txt cgal-4.5/src/CMakeLists.txt --- cgal-4.4/src/CMakeLists.txt 2012-11-13 13:13:55.000000000 +0000 +++ cgal-4.5/src/CMakeLists.txt 2014-08-29 13:58:16.000000000 +0000 @@ -103,6 +103,8 @@ # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${CONF_TYPE} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) #endforeach() +# TODO: Seems useless, because it is called again in ../CMakeLists.txt +# Should probably be removed. -- Laurent Rineau, 2014/07/22 create_CGALconfig_files() set(CGAL_DIR ${CMAKE_BINARY_DIR}) @@ -110,7 +112,7 @@ add_subdirectory(CGAL) # search libs -set(CGAL_CONFIGURED_LIBRARIES "" PARENT_SCOPE) +set(CGAL_CONFIGURED_LIBRARIES "") foreach(package ${CGAL_CONFIGURED_PACKAGES}) file(GLOB CONFIGURED_LIBS_IN_PACKAGE ${package}/src/CGAL_*/CMakeLists.txt) @@ -128,8 +130,7 @@ cache_set(${CGAL_CONFIGURED_LIBRARY_NAME}_3RD_PARTY_INCLUDE_DIRS "" ) cache_set(${CGAL_CONFIGURED_LIBRARY_NAME}_3RD_PARTY_LIBRARIES "" ) cache_set(${CGAL_CONFIGURED_LIBRARY_NAME}_3RD_PARTY_LIBRARIES_DIRS "" ) - - if (${CGAL_CONFIGURED_LIBRARY_NAME} STREQUAL "Core") + if (${CGAL_CONFIGURED_LIBRARY_NAME} STREQUAL "CGAL_Core") if (NOT CGAL_NO_CORE) configure_component( ${package}/src/${CGAL_CONFIGURED_LIBRARY_NAME} ${CGAL_CONFIGURED_LIBRARY_NAME}) else(NOT CGAL_NO_CORE) diff -Nru cgal-4.4/VERSION cgal-4.5/VERSION --- cgal-4.4/VERSION 2014-04-03 19:02:08.000000000 +0000 +++ cgal-4.5/VERSION 2014-10-09 19:00:35.000000000 +0000 @@ -1 +1 @@ -4.4 \ No newline at end of file +4.5 \ No newline at end of file