diff --git a/.travis.yml b/.travis.yml index 3761737a3d6..398df77da8b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -53,7 +53,7 @@ env: compiler: clang-3.6 install: - echo "$PWD" - - if [ -n "$TRAVIS_PULL_REQUEST" ] && [ "$PACKAGE" != CHECK ]; then DO_IGNORE=FALSE; for ARG in $(echo "$PACKAGE");do . $PWD/.travis/test_package.sh "$PWD" "$ARG"; echo "DO_IGNORE is $DO_IGNORE"; if [ "$DO_IGNORE" = "FALSE" ]; then break; fi; done; if [ "$DO_IGNORE" = "TRUE" ]; then travis_terminate 0; fi;fi + - if [ -n "$TRAVIS_PULL_REQUEST" ] && [ "$PACKAGE" != CHECK ]; then DO_IGNORE=FALSE; for ARG in $(echo "$PACKAGE");do if [ "$ARG" = "Maintenance" ]; then continue; fi; . $PWD/.travis/test_package.sh "$PWD" "$ARG"; echo "DO_IGNORE is $DO_IGNORE"; if [ "$DO_IGNORE" = "FALSE" ]; then break; fi; done; if [ "$DO_IGNORE" = "TRUE" ]; then travis_terminate 0; fi;fi - bash .travis/install.sh - export CXX=clang++-3.6 CC=clang-3.6; before_script: diff --git a/.travis/build_package.sh b/.travis/build_package.sh index af24f4e13e1..f1faf434ddd 100755 --- a/.travis/build_package.sh +++ b/.travis/build_package.sh @@ -77,7 +77,8 @@ cd $ROOT zsh $ROOT/Scripts/developer_scripts/test_merge_of_branch HEAD #test dependencies cd $ROOT - bash Scripts/developer_scripts/cgal_check_dependencies.sh /usr/bin/doxygen + bash Scripts/developer_scripts/cgal_check_dependencies.sh --check_headers /usr/bin/doxygen + cd .travis #parse current matrix and check that no package has been forgotten diff --git a/.travis/template.txt b/.travis/template.txt index 7deb9f4b73c..c023fe68f3e 100644 --- a/.travis/template.txt +++ b/.travis/template.txt @@ -10,7 +10,7 @@ env: compiler: clang-3.6 install: - echo "$PWD" - - if [ -n "$TRAVIS_PULL_REQUEST" ] && [ "$PACKAGE" != CHECK ]; then DO_IGNORE=FALSE; for ARG in $(echo "$PACKAGE");do . $PWD/.travis/test_package.sh "$PWD" "$ARG"; echo "DO_IGNORE is $DO_IGNORE"; if [ "$DO_IGNORE" = "FALSE" ]; then break; fi; done; if [ "$DO_IGNORE" = "TRUE" ]; then travis_terminate 0; fi;fi + - if [ -n "$TRAVIS_PULL_REQUEST" ] && [ "$PACKAGE" != CHECK ]; then DO_IGNORE=FALSE; for ARG in $(echo "$PACKAGE");do if [ "$ARG" = "Maintenance" ]; then continue; fi; . $PWD/.travis/test_package.sh "$PWD" "$ARG"; echo "DO_IGNORE is $DO_IGNORE"; if [ "$DO_IGNORE" = "FALSE" ]; then break; fi; done; if [ "$DO_IGNORE" = "TRUE" ]; then travis_terminate 0; fi;fi - bash .travis/install.sh - export CXX=clang++-3.6 CC=clang-3.6; before_script: diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/NewTabDialog.cpp b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/NewTabDialog.cpp index 54072193c53..18bff61b342 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/NewTabDialog.cpp +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/NewTabDialog.cpp @@ -21,6 +21,7 @@ #include "NewTabDialog.h" #include "ArrangementDemoWindow.h" #include "ui_NewTabDialog.h" +#include NewTabDialog::NewTabDialog( QWidget* parent, Qt::WindowFlags f ) : QDialog( parent, f ), diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_Bezier_curve_traits_2.h b/Arrangement_on_surface_2/include/CGAL/Arr_Bezier_curve_traits_2.h index b52e4299e47..8372ecb4e6c 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_Bezier_curve_traits_2.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_Bezier_curve_traits_2.h @@ -784,7 +784,7 @@ public: * \return SMALLER if the curve is directed right; * LARGER if the curve is directed left. */ - Comparison_result operator() (const X_monotone_curve_2& cv) + Comparison_result operator() (const X_monotone_curve_2& cv) const { if (cv.is_directed_right()) return (SMALLER); diff --git a/BGL/include/CGAL/boost/graph/Euler_operations.h b/BGL/include/CGAL/boost/graph/Euler_operations.h index 2472d30f220..109de182736 100644 --- a/BGL/include/CGAL/boost/graph/Euler_operations.h +++ b/BGL/include/CGAL/boost/graph/Euler_operations.h @@ -1020,40 +1020,33 @@ add_face_to_border(typename boost::graph_traits::halfedge_descriptor h1, * collapses an edge in a graph. * * \tparam Graph must be a model of `MutableFaceGraph` - * Let `v0` and `v1` be the source and target vertices, and let `e` and `e'` be the halfedges of edge `v0v1`. + * Let `h` be the halfedge of `e`, and let `v0` and `v1` be the source and target vertices of `h`. + * Let `p_h` and `p_o_h` be respectively the edges of `prev(h,g)` and `prev(opposite(h, g), g)`. + * Let `o_n_h` and `o_n_o_h` be respectively the edges of `opposite(next(h,g))` and `opposite(next(opposite(h, g), g))`. * - * For `e`, let `en` and `ep` be the next and previous - * halfedges, that is `en = next(e, g)`, `ep = prev(e, g)`, and let - * `eno` and `epo` be their opposite halfedges, that is - * `eno = opposite(en, g)` and `epo = opposite(ep, g)`. - * Analoguously, for `e'` define `en'`, `ep'`, `eno'`, and `epo'`. + * After the collapse of edge `e` the following holds: + * - The edge `e` is no longer in `g`. + * - The faces incident to edge `e` are no longer in `g`. + * - `v0` is no longer in `g`. + * - If `h` is not a border halfedge, `p_h` is no longer in `g` and is replaced by `o_n_h`. + * - If the opposite of `h` is not a border halfedge, `p_o_h` is no longer in `g` and is replaced by `o_n_o_h`. + * - The halfedges kept in `g` that had `v0` as target and source now have `v1` as target and source, respectively. + * - No other incidence information is changed in `g`. * - * Then, after the collapse of edge `v0v1` the following holds for `e` (and analoguously for `e'`) - * - * - * \returns vertex `vkept` (which can be either `v0` or `v1`). + * \returns vertex `v1`. * \pre g must be a triangulated graph - * \pre `does_satisfy_link_condition(v0v1,g) == true`. + * \pre `does_satisfy_link_condition(e,g) == true`. */ template typename boost::graph_traits::vertex_descriptor -collapse_edge(typename boost::graph_traits::edge_descriptor v0v1, +collapse_edge(typename boost::graph_traits::edge_descriptor e, Graph& g) { typedef boost::graph_traits< Graph > Traits; typedef typename Traits::vertex_descriptor vertex_descriptor; typedef typename Traits::halfedge_descriptor halfedge_descriptor; - halfedge_descriptor pq = halfedge(v0v1,g); + halfedge_descriptor pq = halfedge(e,g); halfedge_descriptor qp = opposite(pq, g); halfedge_descriptor pt = opposite(prev(pq, g), g); halfedge_descriptor qb = opposite(prev(qp, g), g); @@ -1068,51 +1061,9 @@ collapse_edge(typename boost::graph_traits::edge_descriptor v0v1, vertex_descriptor q = target(pq, g); vertex_descriptor p = source(pq, g); -#if 0 - if(lTopLeftFaceExists && lBottomRightFaceExists){ - std::cerr << " // do it low level" << std::endl; - halfedge_descriptor qt = next(pq,g); - halfedge_descriptor pb = next(qp,g); - halfedge_descriptor ppt = prev(pt,g); - halfedge_descriptor pqb = prev(qb,g); - if(halfedge(q,g) == pq){ - set_halfedge(q, pqb,g); - } - vertex_descriptor t = target(qt,g); - if(halfedge(t,g) == pt){ - set_halfedge(t, qt,g); - } - vertex_descriptor b = target(pb,g); - if(halfedge(b,g) == qb){ - set_halfedge(t, pb,g); - } - set_face(qt, face(pt,g),g); - set_halfedge(face(qt,g),qt,g); - set_face(pb, face(qb,g),g); - set_halfedge(face(pb,g),pb,g); - set_next(qt, next(pt,g),g); - set_next(pb, next(qb,g),g); - set_next(ppt, qt,g); - set_next(pqb,pb,g); - remove_face(face(pq,g),g); - remove_face(face(qp,g),g); - remove_edge(v0v1,g); - remove_edge(edge(pt,g),g); - remove_edge(edge(qb,g),g); - remove_vertex(p,g); - Halfedge_around_target_circulator beg(ppt,g), end(pqb,g); - while(beg != end){ - CGAL_assertion(target(*beg,g) == p); - set_target(*beg,q,g); - --beg; - } - return q; - // return the vertex kept - } -#endif - bool lP_Erased = false, lQ_Erased = false ; + bool lP_Erased = false; if ( lTopFaceExists ) { @@ -1137,7 +1088,7 @@ collapse_edge(typename boost::graph_traits::edge_descriptor v0v1, //CGAL_ECMS_TRACE(3, "Bottom face doesn't exist so vertex P already removed" ) ; lP_Erased = true ; - } + } } } @@ -1158,19 +1109,20 @@ collapse_edge(typename boost::graph_traits::edge_descriptor v0v1, // << q.idx() << "->V" << target(qb, g).idx() // << ") by erasing bottom face" ) ; - remove_face(opposite(qb, g),g); - if ( !lTopFaceExists ) { //CGAL_ECMS_TRACE(3, "Top face doesn't exist so vertex Q already removed" ) ; - lQ_Erased = true ; - } + lP_Erased = true ; + + // q will be removed, swap p and q + internal::swap_vertices(p, q, g); + } + + remove_face(opposite(qb, g),g); } } - CGAL_assertion( !lP_Erased || !lQ_Erased ) ; - - if ( !lP_Erased && !lQ_Erased ) + if ( !lP_Erased ) { //CGAL_ECMS_TRACE(3, "Removing vertex P by joining pQ" ) ; @@ -1180,19 +1132,22 @@ collapse_edge(typename boost::graph_traits::edge_descriptor v0v1, CGAL_expensive_assertion(is_valid_polygon_mesh(g)); - return lP_Erased ? q : p ; + return q; } /** - * Collapses the edge `v0v1` replacing it with v0 or v1, as described in the paragraph above + * collapses an edge in a graph having non-collapsable edges. + * + * Let `h` be the halfedge of `e`, and let `v0` and `v1` be the source and target vertices of `h`. + * Collapses the edge `e` replacing it with `v1`, as described in the paragraph above * and guarantees that an edge `e2`, for which `get(edge_is_constrained_map, e2)==true`, * is not removed after the collapse. * - * * \tparam Graph must be a model of `MutableFaceGraph` * \tparam EdgeIsConstrainedMap mut be a model of `ReadablePropertyMap` with the edge descriptor of `Graph` * as key type and a Boolean as value type. It indicates if an edge is constrained or not. * + * \returns vertex `v1`. * \pre This function requires `g` to be an oriented 2-manifold with or without boundaries. * Furthermore, the edge `v0v1` must satisfy the link condition, which guarantees that the surface mesh is also 2-manifold after the edge collapse. * \pre `get(edge_is_constrained_map, v0v1)==false`. @@ -1262,14 +1217,16 @@ collapse_edge(typename boost::graph_traits::edge_descriptor v0v1, { // the vertex is of valence 3 and we simply need to remove the vertex // and its indicent edges - bool lP_Erased = false; halfedge_descriptor edge = next(edges_to_erase[0],g) == edges_to_erase[1]? edges_to_erase[0]:edges_to_erase[1]; - if (target(edge,g) == p) - lP_Erased = true; + if (target(edge,g) != p) + { + // q will be removed, swap it with p + internal::swap_vertices(p, q, g); + } remove_center_vertex(edge,g); - return lP_Erased? q : p; + return q; } else { @@ -1294,19 +1251,29 @@ collapse_edge(typename boost::graph_traits::edge_descriptor v0v1, join_vertex(pq,g); return q; } - bool lQ_Erased = is_border(opposite(next(pq,g),g),g); + if( is_border(opposite(next(pq,g),g),g) ) + { + // q will be removed, swap it with p + internal::swap_vertices(p, q, g); + } remove_face(opposite(edges_to_erase[0],g),g); - return lQ_Erased?p:q; + return q; } if (! (is_border(edges_to_erase[0],g))){ + // q will be removed, swap it with p + internal::swap_vertices(p, q, g); join_face(edges_to_erase[0],g); join_vertex(qp,g); - return p; + return q; + } + if(!is_border(opposite(next(qp,g),g),g)) + { + // q will be removed, swap it with p + internal::swap_vertices(p, q, g); } - bool lP_Erased= is_border(opposite(next(qp,g),g),g); remove_face(opposite(edges_to_erase[0],g),g); - return lP_Erased?q:p; + return q; }; } diff --git a/BGL/include/CGAL/boost/graph/helpers.h b/BGL/include/CGAL/boost/graph/helpers.h index 5e2c03e95e9..f34e24b7687 100644 --- a/BGL/include/CGAL/boost/graph/helpers.h +++ b/BGL/include/CGAL/boost/graph/helpers.h @@ -1397,6 +1397,101 @@ clear_impl(FaceGraph& g) } } +template +void swap_vertices( + typename boost::graph_traits::vertex_descriptor& p, + typename boost::graph_traits::vertex_descriptor& q, + FaceGraph& g) +{ + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + + halfedge_descriptor hq=halfedge(q, g); + halfedge_descriptor hp=halfedge(p, g); + BOOST_FOREACH(halfedge_descriptor h, halfedges_around_target(hq, g)) + set_target(h, p, g); + BOOST_FOREACH(halfedge_descriptor h, halfedges_around_target(hp, g)) + set_target(h, q, g); + set_halfedge(p, hq, g); + set_halfedge(q, hp, g); +} + +template +void swap_edges( + const typename boost::graph_traits::halfedge_descriptor& h1, + const typename boost::graph_traits::halfedge_descriptor& h2, + FaceGraph& g) +{ + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::face_descriptor face_descriptor; + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + const halfedge_descriptor oh1 = opposite(h1, g), oh2 = opposite(h2, g); + + // backup vertex pointers + vertex_descriptor s1 = target(oh1, g), s2 = target(oh2, g); + vertex_descriptor t1 = target(h1, g), t2 = target(h2, g); + + // backup face pointers + face_descriptor f1 = face(h1, g), f2 = face(h2, g); + face_descriptor fo1 = face(oh1, g), fo2 = face(oh2, g); + + // backup next prev pointers + halfedge_descriptor nh1 = next(h1, g), nh2 = next(h2, g); + halfedge_descriptor ph1 = prev(h1, g), ph2 = prev(h2, g); + halfedge_descriptor noh1 = next(oh1, g), noh2 = next(oh2, g); + halfedge_descriptor poh1 = prev(oh1, g), poh2 = prev(oh2, g); + + // handle particular cases where next/prev are halfedges to be swapt + if (nh1 == oh2) nh1 = oh1; + if (nh1 == h2) nh1 = h1; + if (nh2 == oh1) nh2 = oh2; + if (nh2 == h1) nh2 = h2; + if (ph1 == oh2) ph1 = oh1; + if (ph1 == h2) ph1 = h1; + if (ph2 == oh1) ph2 = oh2; + if (ph2 == h1) ph2 = h2; + if (noh1 == oh2) noh1 = oh1; + if (noh1 == h2) noh1 = h1; + if (noh2 == oh1) noh2 = oh2; + if (noh2 == h1) noh2 = h2; + if (poh1 == oh2) poh1 = oh1; + if (poh1 == h2) poh1 = h1; + if (poh2 == oh1) poh2 = oh2; + if (poh2 == h1) poh2 = h2; + + // (1) exchange next pointers + set_next(h1, nh2, g); + set_next(h2, nh1, g); + set_next(ph1, h2, g); + set_next(ph2, h1, g); + set_next(oh1, noh2, g); + set_next(oh2, noh1, g); + set_next(poh1, oh2, g); + set_next(poh2, oh1, g); + + // (2) exchange vertex-halfedge pointers + set_target(h1, t2, g); + set_target(h2, t1, g); + set_target(oh1, s2, g); + set_target(oh2, s1, g); + if (halfedge(t1, g)==h1) set_halfedge(t1, h2, g); + if (halfedge(t2, g)==h2) set_halfedge(t2, h1, g); + if (halfedge(s1, g)==oh1) set_halfedge(s1, oh2, g); + if (halfedge(s2, g)==oh2) set_halfedge(s2, oh1, g); + + // (3) exchange face-halfedge pointers + set_face(h1, f2, g); + set_face(h2, f1, g); + set_face(oh1, fo2, g); + set_face(oh2, fo1, g); + + face_descriptor nf = boost::graph_traits::null_face(); + if (f1 != nf && halfedge(f1, g)==h1) set_halfedge(f1, h2, g); + if (f2 != nf && halfedge(f2, g)==h2) set_halfedge(f2, h1, g); + if (fo1 != nf && halfedge(fo1, g)==oh1) set_halfedge(fo1, oh2, g); + if (fo2 != nf && halfedge(fo2, g)==oh2) set_halfedge(fo2, oh1, g); +} + + } //end of internal namespace /** diff --git a/BGL/include/CGAL/boost/parameter.h b/BGL/include/CGAL/boost/parameter.h index 1c5c1b8e979..6413902f63e 100644 --- a/BGL/include/CGAL/boost/parameter.h +++ b/BGL/include/CGAL/boost/parameter.h @@ -31,9 +31,8 @@ #else # define BOOST_PARAMETER_MAX_ARITY 12 #endif -#include -#include +#include #if defined(__clang__) || (BOOST_GCC >= 40600) # define CGAL_IGNORE_UNUSED_VARIABLES \ @@ -58,7 +57,7 @@ namespace CGAL { namespace parameters { - + template struct Base { @@ -114,6 +113,20 @@ BOOST_PARAMETER_NAME( (number_of_initial_points, tag) number_of_initial_points_) BOOST_PARAMETER_NAME( (maximal_number_of_vertices, tag ) maximal_number_of_vertices_) BOOST_PARAMETER_NAME( (pointer_to_error_code, tag ) pointer_to_error_code_) +// First used in +BOOST_PARAMETER_NAME( (function, tag ) function_) +BOOST_PARAMETER_NAME( (bounding_object, tag ) bounding_object_) +BOOST_PARAMETER_NAME( (relative_error_bound, tag ) relative_error_bound_) +BOOST_PARAMETER_NAME( (p_rng, tag ) p_rng_) +BOOST_PARAMETER_NAME( (null_subdomain_index, tag ) null_subdomain_index_) +BOOST_PARAMETER_NAME( (construct_surface_patch_index, tag ) construct_surface_patch_index_) + +// First used in +BOOST_PARAMETER_NAME( (image, tag ) image_) +BOOST_PARAMETER_NAME( (iso_value, tag) iso_value_) +BOOST_PARAMETER_NAME( (value_outside, tag) value_outside_) +BOOST_PARAMETER_NAME( (image_values_to_subdomain_indices, tag ) image_values_to_subdomain_indices_) + CGAL_PRAGMA_DIAG_POP } // parameters } // CGAL diff --git a/BGL/test/BGL/CMakeLists.txt b/BGL/test/BGL/CMakeLists.txt index e3938cdd9c6..74efdb21fc3 100644 --- a/BGL/test/BGL/CMakeLists.txt +++ b/BGL/test/BGL/CMakeLists.txt @@ -98,6 +98,8 @@ create_single_source_cgal_program( "test_Face_filtered_graph.cpp" ) create_single_source_cgal_program( "test_Euler_operations.cpp" ) +create_single_source_cgal_program( "test_Collapse_edge.cpp" ) + create_single_source_cgal_program( "test_graph_traits.cpp" ) create_single_source_cgal_program( "test_Properties.cpp" ) @@ -105,6 +107,7 @@ create_single_source_cgal_program( "test_Properties.cpp" ) if(OpenMesh_FOUND) target_link_libraries( test_clear PRIVATE ${OPENMESH_LIBRARIES}) target_link_libraries( test_Euler_operations PRIVATE ${OPENMESH_LIBRARIES}) + target_link_libraries( test_Collapse_edge PRIVATE ${OPENMESH_LIBRARIES}) target_link_libraries( test_Face_filtered_graph PRIVATE ${OPENMESH_LIBRARIES}) target_link_libraries( test_graph_traits PRIVATE ${OPENMESH_LIBRARIES} ) target_link_libraries( test_Properties PRIVATE ${OPENMESH_LIBRARIES}) diff --git a/BGL/test/BGL/data/flat_hexahedron.off b/BGL/test/BGL/data/flat_hexahedron.off new file mode 100644 index 00000000000..b7c3562356d --- /dev/null +++ b/BGL/test/BGL/data/flat_hexahedron.off @@ -0,0 +1,24 @@ +OFF +10 10 0 +-1.5 0 0 +-0.5 0 0 +0.5 0 0 +1.5 0 0 +-0.75 -0.5 0 +0 -0.5 0 +0.75 -0.5 0 +-0.75 0.5 0 +0 0.5 0 +0.75 0.5 0 + +3 0 1 7 +3 7 1 8 +3 8 1 2 +3 2 9 8 +3 9 2 3 + +3 0 4 1 +3 1 4 5 +3 1 5 2 +3 2 5 6 +3 2 6 3 diff --git a/BGL/test/BGL/test_Collapse_edge.cpp b/BGL/test/BGL/test_Collapse_edge.cpp new file mode 100644 index 00000000000..d1f9e0e22d8 --- /dev/null +++ b/BGL/test/BGL/test_Collapse_edge.cpp @@ -0,0 +1,226 @@ +#include "test_Prefix.h" +#include +#include + +template < typename Mesh> +typename boost::graph_traits:: +halfedge_descriptor find_halfedge(double x1, double y1, + double x2, double y2, + Mesh& m, + bool is_border = false) +{ + typedef typename boost::property_map::type VPMAP; + typedef typename boost::property_traits::value_type Point; + + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + VPMAP vpmap = get(CGAL::vertex_point, m); + BOOST_FOREACH(halfedge_descriptor h, halfedges(m)) + { + if(get(vpmap, source(h, m)) == Point(x1,y1,0) + && get(vpmap, target(h, m)) == Point(x2,y2,0)) + { + if(is_border == CGAL::is_border(h, m)) + return h; + else + return opposite(h, m); + } + } + return boost::graph_traits::null_halfedge(); +} + +template +void +collapse_edge_test() +{ + CGAL_GRAPH_TRAITS_MEMBERS(Mesh); + typedef typename boost::graph_traits:: vertex_descriptor vertex_descriptor; + typedef typename boost::graph_traits:: halfedge_descriptor halfedge_descriptor; + + const std::string fname = "data/flat_hexahedron.off"; + Mesh m; + if(!CGAL::read_off(fname, m)) { + std::cout << "Error reading file: " << fname << std::endl; + } + bool m_is_valid = CGAL::is_valid(m); + assert(m_is_valid); + + Mesh test_mesh; + CGAL::copy_face_graph(m, test_mesh); + m_is_valid = CGAL::is_valid(m); + assert(m_is_valid); + + //case 1: General Case. + { + halfedge_descriptor he = find_halfedge(-0.5,0, + 0.5,0, + test_mesh); + halfedge_descriptor en = next(he, test_mesh); + halfedge_descriptor eno = opposite(en, test_mesh); + halfedge_descriptor eno_prime = opposite(next(opposite(he, test_mesh), test_mesh), test_mesh); + vertex_descriptor v1 = target(he, test_mesh); + bool ok = CGAL::Euler::collapse_edge(edge(he, test_mesh), test_mesh) == v1; + assert(ok); + char found = 0; + BOOST_FOREACH(halfedge_descriptor it, CGAL::halfedges_around_target(v1,test_mesh)) + { + if(it == eno + || it == eno_prime){ + ++found; + } + } + assert(found == 2); + CGAL::clear(test_mesh); + + } + //case 2: collapsing edge is not itself a border, but is incident upon a border edge that is removed. + { + CGAL::copy_face_graph(m, test_mesh); + halfedge_descriptor he = find_halfedge(0,0.5, + -0.75,0.5, + test_mesh); + CGAL::Euler::remove_face(he, test_mesh); + + he = find_halfedge(-0.5,0, + 0.5,0, + test_mesh); + halfedge_descriptor en = next(he, test_mesh); + halfedge_descriptor eno = opposite(en, test_mesh); + halfedge_descriptor eno_prime = opposite(next(opposite(he, test_mesh), test_mesh), test_mesh); + vertex_descriptor v1 = target(he, test_mesh); + bool ok = CGAL::Euler::collapse_edge(edge(he, test_mesh), test_mesh) == v1; + assert(ok); + char found = 0; + BOOST_FOREACH(halfedge_descriptor it, CGAL::halfedges_around_target(v1,test_mesh)) + { + if(it == eno + || it == eno_prime){ + ++found; + } + } + assert(found == 2); + CGAL::clear(test_mesh); + } + //case 3: collapsing edge is not itself a border, but is incident upon a border edge that is not removed + { + CGAL::copy_face_graph(m, test_mesh); + halfedge_descriptor he = find_halfedge(1.5,0, + 0.75,0.5, + test_mesh); + CGAL::Euler::remove_face(he, test_mesh); + + he = find_halfedge(-0.5,0, + 0.5,0, + test_mesh); + halfedge_descriptor en = next(he, test_mesh); + halfedge_descriptor eno = opposite(en, test_mesh); + halfedge_descriptor eno_prime = opposite(next(opposite(he, test_mesh), test_mesh), test_mesh); + vertex_descriptor v1 = target(he, test_mesh); + bool ok = CGAL::Euler::collapse_edge(edge(he, test_mesh), test_mesh) == v1; + assert(ok); + char found = 0; + BOOST_FOREACH(halfedge_descriptor it, CGAL::halfedges_around_target(v1,test_mesh)) + { + if(it == eno + || it == eno_prime){ + ++found; + } + } + assert(found == 2); + CGAL::clear(test_mesh); + } + //case 4: collapsing edge is itself a border + { + CGAL::copy_face_graph(m, test_mesh); + halfedge_descriptor he = find_halfedge(-0.5, 0, + 0, -0.5, + test_mesh); + CGAL::Euler::remove_face(he, test_mesh); + he = find_halfedge(0, -0.5, + -0.5, 0, + test_mesh); + CGAL::Euler::remove_face(he, test_mesh); + he = find_halfedge(0, -0.5, + 0.75, -0.5, + test_mesh); + CGAL::Euler::remove_face(he, test_mesh); + + + he = find_halfedge(-0.5,0, + 0.5,0, + test_mesh); + halfedge_descriptor en = next(he, test_mesh); + halfedge_descriptor eno = opposite(en, test_mesh); + halfedge_descriptor ep_prime = prev(opposite(he, test_mesh), test_mesh); + halfedge_descriptor eno_prime = opposite(next(opposite(he, test_mesh), test_mesh), test_mesh); + vertex_descriptor v1 = target(he, test_mesh); + bool ok = CGAL::Euler::collapse_edge(edge(he, test_mesh), test_mesh) == v1; + assert(ok); + char found = 0; + BOOST_FOREACH(halfedge_descriptor it, CGAL::halfedges_around_target(v1,test_mesh)) + { + if(it == eno + || it == eno_prime + || it == ep_prime){ + ++found; + } + } + assert(found == 3); + CGAL::clear(test_mesh); + } + //case 5 singular case. + { + CGAL::copy_face_graph(m, test_mesh); + halfedge_descriptor he = find_halfedge(0.75,0.5, + 1.5,0, + test_mesh); + CGAL::Euler::remove_face(he, test_mesh); + he = find_halfedge(0.75,-0.5, + 1.5,0, + test_mesh); + CGAL::Euler::remove_face(he, test_mesh); + he = find_halfedge(0,0.5, + 0.5,0, + test_mesh); + CGAL::Euler::remove_face(he, test_mesh); + he = find_halfedge(0.5,0, + 0,-0.5, + test_mesh); + CGAL::Euler::remove_face(he, test_mesh); + + he = find_halfedge(-0.5,0, + 0.5,0, + test_mesh); + CGAL::Euler::remove_face(he, test_mesh); + halfedge_descriptor ep = prev(he, test_mesh); + halfedge_descriptor eno_prime = opposite(next(opposite(he, test_mesh), test_mesh), test_mesh); + vertex_descriptor v1 = target(he, test_mesh); + bool ok = CGAL::Euler::collapse_edge(edge(he, test_mesh), test_mesh) == v1; + assert(ok); + char found = 0; + BOOST_FOREACH(halfedge_descriptor it, CGAL::halfedges_around_target(v1,test_mesh)) + { + if(it == ep) + ++found; + else if( it == eno_prime){ + ++found; + } + } + assert(found == 2); + CGAL::clear(test_mesh); + } +} + + +int main() +{ + + collapse_edge_test(); + collapse_edge_test(); + +#ifdef CGAL_USE_OPENMESH + collapse_edge_test(); +#endif + + std::cerr << "done\n"; + return 0; +} diff --git a/BGL/test/BGL/test_Euler_operations.cpp b/BGL/test/BGL/test_Euler_operations.cpp index cdf53ec5f4c..3ae73d6c38d 100644 --- a/BGL/test/BGL/test_Euler_operations.cpp +++ b/BGL/test/BGL/test_Euler_operations.cpp @@ -380,7 +380,27 @@ does_satisfy_link_condition() assert(CGAL::Euler::does_satisfy_link_condition(*edges(f.m).first,f.m)); } - +template +void +test_swap_edges() +{ + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + std::size_t nbh=12; + Kernel::Point_3 pt(0,0,0); + // test all possible pairs of halfedges + for (std::size_t i=0; i void @@ -400,6 +420,7 @@ test_Euler_operations() remove_center_vertex_test(); join_split_inverse(); does_satisfy_link_condition(); + test_swap_edges(); } int main() diff --git a/CGAL_Core/include/CGAL/CORE/BigFloat.h b/CGAL_Core/include/CGAL/CORE/BigFloat.h index 4dc7263dfb1..f010ee7696c 100644 --- a/CGAL_Core/include/CGAL/CORE/BigFloat.h +++ b/CGAL_Core/include/CGAL/CORE/BigFloat.h @@ -61,6 +61,8 @@ public: BigFloat(float i) : RCBigFloat(new BigFloatRep(i)) {} /// constructor for int BigFloat(int i) : RCBigFloat(new BigFloatRep(i)) {} + /// constructor for unsigned int + BigFloat(unsigned int i) : RCBigFloat(new BigFloatRep(i)) {} /// constructor for long BigFloat(long l) : RCBigFloat(new BigFloatRep(l)) {} /// constructor for double diff --git a/CGAL_Core/include/CGAL/CORE/BigFloatRep.h b/CGAL_Core/include/CGAL/CORE/BigFloatRep.h index 000ea42deac..74f0de011ae 100644 --- a/CGAL_Core/include/CGAL/CORE/BigFloatRep.h +++ b/CGAL_Core/include/CGAL/CORE/BigFloatRep.h @@ -71,6 +71,7 @@ public: public: // constructors BigFloatRep(int=0); //inline + BigFloatRep(unsigned int); //inline BigFloatRep(short); //inline BigFloatRep(float); //inline BigFloatRep(long); //inline @@ -249,6 +250,9 @@ inline BigFloatRep::BigFloatRep(float n) inline BigFloatRep::BigFloatRep(int n) : m(n), err(0), exp(0) {} +inline BigFloatRep::BigFloatRep(unsigned int n) + : m(n), err(0), exp(0) {} + // Chee (8/8/04) -- introduced constructor from long inline BigFloatRep::BigFloatRep(long n) : m(n), err(0), exp(0) {} diff --git a/CGAL_Core/include/CGAL/CORE/CoreDefs.h b/CGAL_Core/include/CGAL/CORE/CoreDefs.h index 0d53c442bcc..1d136ab43d1 100644 --- a/CGAL_Core/include/CGAL/CORE/CoreDefs.h +++ b/CGAL_Core/include/CGAL/CORE/CoreDefs.h @@ -55,7 +55,7 @@ #else // CGAL_HEADER_ONLY #define CGAL_GLOBAL_STATE_VAR(TYPE, NAME, VALUE) \ - CGAL_EXPORT extern TYPE NAME; \ + CGAL_CORE_EXPORT extern TYPE NAME; \ inline TYPE& get_static_##NAME() \ { \ return NAME; \ diff --git a/CGAL_ImageIO/include/CGAL/ImageIO/bmpendian_impl.h b/CGAL_ImageIO/include/CGAL/ImageIO/bmpendian_impl.h index 581164c0d3f..3a2b7d56b50 100644 --- a/CGAL_ImageIO/include/CGAL/ImageIO/bmpendian_impl.h +++ b/CGAL_ImageIO/include/CGAL/ImageIO/bmpendian_impl.h @@ -56,7 +56,7 @@ int readINT8little(FILE *f, CGAL_INT8 *i) rc = fgetc(f); if (rc == EOF) - return rc; + return EOF; *i = CGAL_INT8(rc & 0xff); return 0; @@ -69,7 +69,7 @@ int readUINT8little(FILE *f, CGAL_UINT8 *i) rc = fgetc(f); if (rc == EOF) - return rc; + return EOF; *i = CGAL_UINT8(rc & 0xff); return 0; @@ -91,7 +91,7 @@ int readINT16little(FILE *f, CGAL_INT16 *i) rc = fgetc(f); if (rc == EOF) - return rc; + return EOF; temp = temp | CGAL_INT16((rc & 0xff) << 8); *i = temp; @@ -108,7 +108,7 @@ int readUINT16little(FILE *f, CGAL_UINT16 *i) rc = fgetc(f); if (rc == EOF) - return rc; + return EOF; temp = CGAL_INT16(temp | ((rc & 0xff) << 8)); *i = temp; @@ -132,7 +132,7 @@ int readINT32little(FILE *f, CGAL_INT32 *i) rc = fgetc(f); if (rc == EOF) - return rc; + return EOF; temp = CGAL_INT32(temp | (((long)rc & 0xff) << 24)); *i = temp; @@ -151,7 +151,7 @@ int readUINT32little(FILE *f, CGAL_UINT32 *i) rc = fgetc(f); if (rc == EOF) - return rc; + return EOF; temp = CGAL_UINT32(temp | (((long)rc & 0xff) << 24)); *i = temp; @@ -185,7 +185,7 @@ int writeINT16little(FILE *f, CGAL_INT16 i) rc = fputc((i & 0xff), f); if (rc == EOF) - return rc; + return EOF; return fputc(((i >> 8) & 0xff), f); } @@ -197,7 +197,7 @@ int writeUINT16little(FILE *f, CGAL_UINT16 i) rc = fputc((i & 0xff), f); if (rc == EOF) - return rc; + return EOF; return fputc(((i >> 8) & 0xff), f); } @@ -209,15 +209,15 @@ int writeINT32little(FILE *f, CGAL_INT32 i) rc = fputc((i & 0xff), f); if (rc == EOF) - return rc; + return EOF; rc = fputc(((i >> 8) & 0xff), f); if (rc == EOF) - return rc; + return EOF; rc = fputc(((i >> 16) & 0xff), f); if (rc == EOF) - return rc; + return EOF; return fputc(((i >> 24) & 0xff), f); } @@ -230,15 +230,15 @@ int writeUINT32little(FILE *f, CGAL_UINT32 i) rc = fputc((i & 0xff), f); if (rc == EOF) - return rc; + return EOF; rc = fputc(((i >> 8) & 0xff), f); if (rc == EOF) - return rc; + return EOF; rc = fputc(((i >> 16) & 0xff), f); if (rc == EOF) - return rc; + return EOF; return fputc(((i >> 24) & 0xff), f); } diff --git a/CGAL_ImageIO/include/CGAL/Image_3.h b/CGAL_ImageIO/include/CGAL/Image_3.h index e13a7e81e08..e344d0ccc19 100644 --- a/CGAL_ImageIO/include/CGAL/Image_3.h +++ b/CGAL_ImageIO/include/CGAL/Image_3.h @@ -503,7 +503,7 @@ Image_3::labellized_trilinear_interpolation static_cast(lc)); if(lc == 1) { - return labels[0]; + return static_cast(labels[0]); } double best_value = 0.; @@ -521,7 +521,7 @@ Image_3::labellized_trilinear_interpolation } } // CGAL_assertion(best_value > 0.5); - return best; + return static_cast(best); } } // end namespace CGAL diff --git a/CMakeLists.txt b/CMakeLists.txt index 88cfc9acacc..4c884132d3e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,13 +3,33 @@ message( "== CMake setup ==" ) project(CGAL CXX C) # Minimal version of CMake: -cmake_minimum_required(VERSION 2.8.11) +cmake_minimum_required(VERSION 3.1) set( CGAL_BRANCH_BUILD ON CACHE INTERNAL "Create CGAL from a Git branch" FORCE) include(${CMAKE_SOURCE_DIR}/Installation/cmake/modules/CGAL_SCM.cmake) CGAL_detect_git(${CMAKE_SOURCE_DIR}) +function(CGAL_error_if_detect_in_source_build) + # If in a Git repository, forbid in-source builds + get_filename_component(srcdir "${CMAKE_SOURCE_DIR}" REALPATH) + get_filename_component(bindir "${CMAKE_BINARY_DIR}" REALPATH) + if("${srcdir}" STREQUAL "${bindir}") + message(FATAL_ERROR [=[ +############ +Since CGAL-4.12.1, you can no longer configure an in-source build in a Git +repository. See this StackOverlow question and answers for a way to create +a separate build directory: + https://stackoverflow.com/q/45518317/1728537 +############ +]=]) + endif() +endfunction() + +if ( "${CGAL_SCM_NAME}" STREQUAL "git" ) + CGAL_error_if_detect_in_source_build() +endif() + # add option for duplicate file detection option( CGAL_REPORT_DUPLICATE_FILES "Switch on to start (naive) detection of duplicate source- and headerfiles in packages" OFF) diff --git a/Cartesian_kernel/include/CGAL/Cartesian_converter.h b/Cartesian_kernel/include/CGAL/Cartesian_converter.h index d77689adca9..fb25953c85f 100644 --- a/Cartesian_kernel/include/CGAL/Cartesian_converter.h +++ b/Cartesian_kernel/include/CGAL/Cartesian_converter.h @@ -32,6 +32,7 @@ // provided you give a NT converter from A to B. // There's a Homogeneous counterpart. +#include #include #include #include @@ -91,7 +92,7 @@ struct Converting_visitor : boost::static_visitor<> { template < class K1, class K2, // class Converter = NT_converter > - class Converter = typename internal::Default_converter::Type > + class Converter> class Cartesian_converter : public Enum_converter { typedef Enum_converter Base; diff --git a/Combinatorial_map/include/CGAL/Combinatorial_map.h b/Combinatorial_map/include/CGAL/Combinatorial_map.h index d6da5650c85..4c2bb810685 100644 --- a/Combinatorial_map/include/CGAL/Combinatorial_map.h +++ b/Combinatorial_map/include/CGAL/Combinatorial_map.h @@ -1250,7 +1250,7 @@ namespace CGAL { /** Test if the map is valid. * @return true iff the map is valid. */ - bool is_valid() const + bool is_valid(bool show_errors=true) const { bool valid = true; unsigned int i = 0, j = 0; @@ -1276,9 +1276,11 @@ namespace CGAL { if ((!is_free(it, 0) && beta(it, 0, 1)!=it) || (!is_free(it, 1) && beta(it, 1, 0)!=it )) { - std::cerr << "Map not valid: beta(0) " - "is not the inverse of beta(1) for dart " - < + for ( typename CMap::template Dart_of_cell_basic_range::iterator it(amap, adart, amark); it.cont(); ++it, ++nb ) { if ( a!=amap.template attribute(it) ) diff --git a/Documentation/doc/Documentation/General.txt b/Documentation/doc/Documentation/General.txt index 1afb38e746c..0941991e41c 100644 --- a/Documentation/doc/Documentation/General.txt +++ b/Documentation/doc/Documentation/General.txt @@ -15,6 +15,11 @@ class DefaultConstructible {}; /// See http://en.cppreference.com/w/cpp/concept/CopyConstructible class CopyConstructible {}; +/// \cgalConcept +/// Concept from the \cpp standard. +/// See http://en.cppreference.com/w/cpp/concept/Callable +class Callable {}; + /// \cgalConcept /// Concept from the \cpp standard. /// See http://en.cppreference.com/w/cpp/concept/EqualityComparable diff --git a/Documentation/doc/Documentation/Installation.txt b/Documentation/doc/Documentation/Installation.txt index ac67f2cac42..9516d1779c8 100644 --- a/Documentation/doc/Documentation/Installation.txt +++ b/Documentation/doc/Documentation/Installation.txt @@ -18,13 +18,13 @@ make # build the \cgal libraries Compiling an example or a demo shipped with \cgal is similarly simple:
-cd examples/Straight_skeleton_2 # go to an example directory
+cd examples/Triangulation_2 # go to an example directory
 cmake -DCGAL_DIR=$HOME/CGAL-\cgalReleaseNumber . # configure the examples
 make # build the examples 
 
-cd demo/Straight_skeleton_2 # go to a demo directory
+cd demo/Triangulation_2 # go to a demo directory
 cmake -DCGAL_DIR=$HOME/CGAL-\cgalReleaseNumber . # configure the demos
 make # build the demos 
 
@@ -551,14 +551,6 @@ and the \ref PkgRidges_3 packages. The \sc{Eigen} web site is `http://eigen.tuxfamily.org`. -\subsection thirdpartylibQGLViewer libQGLViewer - -libQGLViewer is a 3D widget based on \sc{Qt} 4's `QGLWidget`. In case of \sc{Qt}5 used, libQGLViewer needs to be recompiled with the proper \sc{Qt}5 version. - -In \cgal some 3D demos are based on libQGLViewer. - -It can be downloaded from `http://www.libqglviewer.com/`. - \subsection thirdpartyESBTL ESBTL The \sc{Esbtl} (Easy Structural Biology Template Library) is a library that allows @@ -673,9 +665,6 @@ make examples # build all demos at once make demos -# build only the Straight Skeleton demo -make Straight_skeleton_2_demo - \cgalAdvancedBegin @@ -757,7 +746,7 @@ Ideally, configuring and compiling a demo/example/program amounts to
 
-cd CGAL-\cgalReleaseNumber/examples/Straight_skeleton_2
+cd CGAL-\cgalReleaseNumber/examples/Triangulation_2
 cmake -DCGAL_DIR=$HOME/CGAL-\cgalReleaseNumber .
 make
 
@@ -893,7 +882,7 @@ controlling variable right up front:
 
 cd CGAL-\cgalReleaseNumber
 cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS=-g .
-cd CGAL-\cgalReleaseNumber/examples/Straight_skeleton_2
+cd CGAL-\cgalReleaseNumber/examples/Triangulation_2
 cmake -DCGAL_DIR=CGAL-\cgalReleaseNumber -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS=-O2 -DCGAL_DONT_OVERRIDE_CMAKE_FLAGS=TRUE . 
 
\cgalAdvancedEnd @@ -1172,22 +1161,6 @@ Only the directory containing the header files of \sc{Eigen} 3.1 (or grea | `EIGEN3_INCLUDE_DIR` | Directory containing the file `signature_of_eigen3_matrix_library` | CMake | | `EIGEN3_INC_DIR` | Idem | Environment | -\subsection installation_qgl QGLViewer Library - -Some demos require the GLViewer library. - -In most cases, if QGLViewer is not automatically found, setting the `QGLVIEWERROOT` -environment variable is sufficient. If it is not, you can specify the directory containing -the header files and the full pathnames of the release and debug libraries - -| Variable | Description | Type | -| :- | :- | :- | -| `QGLVIEWERROOT` | Root directory of the QGLViewer library | Environment | -| `QGLVIEWER_INCLUDE_DIR` | Directory containing the `QGLViewer/qglviewer.h` file | CMake | -| `QGLVIEWER_LIBRARY_RELEASE` | Full pathname to a release build of the QGLViewer library | CMake | -| `QGLVIEWER_LIBRARY_DEBUG` | Full pathname to a debug build of the QGLViewer library | CMake | - - \subsection installation_esbtl ESBTL Library One skin surface example requires the \sc{Esbtl} library in order to read \sc{Pdb} files. diff --git a/Documentation/doc/resources/1.8.13/BaseDoxyfile.in b/Documentation/doc/resources/1.8.13/BaseDoxyfile.in index a6bc2bbb17e..49b2e2c11b3 100644 --- a/Documentation/doc/resources/1.8.13/BaseDoxyfile.in +++ b/Documentation/doc/resources/1.8.13/BaseDoxyfile.in @@ -1571,7 +1571,7 @@ MATHJAX_FORMAT = HTML-CSS # The default value is: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2. # This tag requires that the tag USE_MATHJAX is set to YES. -${CGAL_DOC_MATHJAX_LOCATION_FULL_OPTION_LINE} +MATHJAX_RELPATH = ${CGAL_DOC_MATHJAX_LOCATION} # The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax # extension names that should be enabled during MathJax rendering. For example diff --git a/Filtered_kernel/include/CGAL/Epic_converter.h b/Filtered_kernel/include/CGAL/Epic_converter.h index 6dc96801973..bd4650c4c2a 100644 --- a/Filtered_kernel/include/CGAL/Epic_converter.h +++ b/Filtered_kernel/include/CGAL/Epic_converter.h @@ -23,7 +23,7 @@ #define CGAL_EPIC_CONVERTER_H -#include +#include #include namespace CGAL { @@ -54,6 +54,8 @@ class Epic_converter { typedef typename Exact_predicates_inexact_constructions_kernel::Sphere_3 Sphere_3; typedef typename Exact_predicates_inexact_constructions_kernel::Circle_3 Circle_3; typedef typename Exact_predicates_inexact_constructions_kernel::Iso_cuboid_3 Iso_cuboid_3; + + typedef typename IK::FT IK_FT; public: @@ -61,6 +63,7 @@ public: std::pair operator()(const typename IK::FT n) const { double d; + internal::init_double(d, (IK_FT*)(0)); if(fit_in_double(n,d)){ return std::make_pair(d,true); } @@ -80,6 +83,7 @@ public: std::pair operator()(const typename IK::Point_2& p) const { double x, y; + internal::init_double(x, y, (IK_FT*)(0)); if(fit_in_double(p.x(),x) && fit_in_double(p.y(),y)){ return std::make_pair(Point_2(x,y),true); } @@ -89,6 +93,7 @@ public: std::pair operator()(const typename IK::Vector_2& v) const { double x, y; + internal::init_double(x, y, (IK_FT*)(0)); if(fit_in_double(v.x(),x) && fit_in_double(v.y(),y)){ return std::make_pair(Vector_2(x,y),true); } @@ -98,6 +103,7 @@ public: std::pair operator()(const typename IK::Direction_2& d) const { double x, y; + internal::init_double(x, y, (IK_FT*)(0)); if(fit_in_double(d.dx(),x) && fit_in_double(d.dy(),y)){ return std::make_pair(Direction_2(x,y),true); } @@ -266,6 +272,7 @@ public: std::pair operator()(const typename IK::Point_3& p) const { double x, y, z; + internal::init_double(x, y, z, (IK_FT*)(0)); if(fit_in_double(p.x(),x) && fit_in_double(p.y(),y) && fit_in_double(p.z(),z)){ return std::make_pair(Point_3(x,y,z),true); } @@ -275,6 +282,7 @@ public: std::pair operator()(const typename IK::Vector_3& v) const { double x, y, z; + internal::init_double(x, y, z, (IK_FT*)(0)); if(fit_in_double(v.x(),x) && fit_in_double(v.y(),y) && fit_in_double(v.z(),z)){ return std::make_pair(Vector_3(x,y,z),true); } @@ -284,6 +292,7 @@ public: std::pair operator()(const typename IK::Direction_3& d) const { double x, y, z; + internal::init_double(x, y, z, (IK_FT*)(0)); if(fit_in_double(d.dx(),x) && fit_in_double(d.dy(),y) && fit_in_double(d.dz(),z)){ return std::make_pair(Direction_3(x,y,z),true); } diff --git a/Filtered_kernel/include/CGAL/Lazy.h b/Filtered_kernel/include/CGAL/Lazy.h index 1cfb6838fe5..c54296e8767 100644 --- a/Filtered_kernel/include/CGAL/Lazy.h +++ b/Filtered_kernel/include/CGAL/Lazy.h @@ -55,6 +55,12 @@ namespace CGAL { +template +class Lazy_kernel_base; + template class Lazy; template @@ -425,13 +431,19 @@ class Lazy_rep_##n :public Lazy_rep< AT, \ E2A >, \ private EC \ { \ + \ + template \ + friend class Lazy_kernel_base; \ BOOST_PP_REPEAT(n, CGAL_MLIST, _) \ const EC& ec() const { return *this; } \ public: \ void update_exact() const { \ - this->et = new ET(ec()( BOOST_PP_ENUM(n, CGAL_LEXACT, _) ) ); \ - this->at = E2A()(*(this->et)); \ - BOOST_PP_REPEAT(n, CGAL_PRUNE_TREE, _) \ + this->et = new ET(ec()( BOOST_PP_ENUM(n, CGAL_LEXACT, _) ) ); \ + this->at = E2A()(*(this->et)); \ + BOOST_PP_REPEAT(n, CGAL_PRUNE_TREE, _) \ } \ Lazy_rep_##n(const AC& ac, const EC&, BOOST_PP_ENUM(n, CGAL_LARGS, _)) \ : Lazy_rep(ac( BOOST_PP_ENUM(n, CGAL_LN, CGAL::approx) )), BOOST_PP_ENUM(n, CGAL_LINIT, _) \ @@ -714,6 +726,17 @@ public: template class Lazy : public Handle { + template + friend struct Lazy_kernel; + + template + friend class Lazy_kernel_base; + public : typedef Lazy Self; @@ -784,7 +807,7 @@ public : ptr()->print_dag(os, level); } -private: + private: // We have a static variable for optimizing the default constructor, // which is in particular heavily used for pruning DAGs. diff --git a/Filtered_kernel/include/CGAL/Lazy_kernel.h b/Filtered_kernel/include/CGAL/Lazy_kernel.h index 521215d6576..2639a9f7027 100644 --- a/Filtered_kernel/include/CGAL/Lazy_kernel.h +++ b/Filtered_kernel/include/CGAL/Lazy_kernel.h @@ -304,6 +304,7 @@ public: typedef EK_ Exact_kernel; typedef E2A_ E2A; + typedef Lazy_kernel_generic_base BaseClass; template < typename Kernel2 > struct Base { typedef Lazy_kernel_base Type; }; @@ -320,6 +321,213 @@ public: // typedef void Compute_z_3; // to detect where .z() is called // typedef void Construct_point_3; // to detect where the ctor is called + struct Compute_weight_2 : public BaseClass::Compute_weight_2 + { + typedef typename Kernel_::FT FT; + typedef typename Kernel_::Point_2 Point_2; + typedef typename Kernel_::Weighted_point_2 Weighted_point_2; + + FT operator()(const Weighted_point_2& p) const + { + + typedef Lazy_rep_3 LR; + + + LR * lr = dynamic_cast(p.ptr()); + if(lr && (! lr->et)){ + return lr->l2; + } + return BaseClass().compute_weight_2_object()(p); + } + + }; + + + struct Compute_weight_3 : public BaseClass::Compute_weight_3 + { + typedef typename Kernel_::FT FT; + typedef typename Kernel_::Point_3 Point_3; + typedef typename Kernel_::Weighted_point_3 Weighted_point_3; + + FT operator()(const Weighted_point_3& p) const + { + + typedef Lazy_rep_3 LR; + + + LR * lr = dynamic_cast(p.ptr()); + if(lr && (! lr->et)){ + return lr->l2; + } + return BaseClass().compute_weight_3_object()(p); + } + + }; + + + struct Construct_point_2 : public BaseClass::Construct_point_2 + { + typedef typename Kernel_::FT FT; + typedef typename Kernel_::Point_2 Point_2; + typedef typename Kernel_::Weighted_point_2 Weighted_point_2; + +#ifndef CGAL_CFG_MATCHING_BUG_6 + using BaseClass::Construct_point_2::operator(); +#else // CGAL_CFG_MATCHING_BUG_6 + + + template + Point_2 operator()(const T& ...t) const + { + return BaseClass().construct_point_2_object()(t...); + } + +#endif // CGAL_CFG_MATCHING_BUG_6 + + const Point_2& operator()(const Point_2& p) const + { + return p; + } + + + Point_2 operator()(const Weighted_point_2& p) const + { + typedef Lazy_rep_3 LR; + + typedef Lazy_rep_3 LRint; + + LR * lr = dynamic_cast(p.ptr()); + if(lr && (! lr->et)){ + return lr->l1; + } else { + LRint* lrint = dynamic_cast(p.ptr()); + if(lrint && (! lrint->et)){ + return lrint->l1; + } + } + + return BaseClass().construct_point_2_object()(p); + } + + }; + + + + struct Construct_point_3 : public BaseClass::Construct_point_3 + { + typedef typename Kernel_::FT FT; + typedef typename Kernel_::Point_3 Point_3; + typedef typename Kernel_::Weighted_point_3 Weighted_point_3; + +#ifndef CGAL_CFG_MATCHING_BUG_6 + using BaseClass::Construct_point_3::operator(); +#else // CGAL_CFG_MATCHING_BUG_6 + + template + Point_3 operator()(const T& ...t) const + { + return BaseClass().construct_point_3_object()(t...); + } + +#endif // CGAL_CFG_MATCHING_BUG_6 + + const Point_3& operator()(const Point_3& p) const + { + return p; + } + + Point_3 operator()(const Weighted_point_3& p) const + { + typedef Lazy_rep_3 LR; + + typedef Lazy_rep_3 LRint; + + + LR * lr = dynamic_cast(p.ptr()); + if(lr && (! lr->et)){ + return lr->l1; + }else{ + LRint* lrint = dynamic_cast(p.ptr()); + if(lrint && (! lrint->et)){ + return lrint->l1; + } + } + return BaseClass().construct_point_3_object()(p); + } + + }; + + + Construct_point_2 construct_point_2_object() const + { + return Construct_point_2(); + } + + Construct_point_3 construct_point_3_object() const + { + return Construct_point_3(); + } + + + Compute_weight_2 compute_weight_2_object() const + { + return Compute_weight_2(); + } + + Compute_weight_3 compute_weight_3_object() const + { + return Compute_weight_3(); + } + + Assign_2 assign_2_object() const { return Assign_2(); } diff --git a/Filtered_kernel/include/CGAL/internal/Static_filters/tools.h b/Filtered_kernel/include/CGAL/internal/Static_filters/tools.h index 44a69734f5b..59d60fe902e 100644 --- a/Filtered_kernel/include/CGAL/internal/Static_filters/tools.h +++ b/Filtered_kernel/include/CGAL/internal/Static_filters/tools.h @@ -31,6 +31,9 @@ namespace CGAL { template < typename ET > class Lazy_exact_nt; +template +class Interval_nt; + namespace internal { // Utility function to check a posteriori that a subtraction was performed @@ -152,6 +155,66 @@ template < typename ET > inline void init_double(double& d0, double& d1, double& d2, double& d3, double& d4, double& d5, double& d6, double& d7, double&d8, double& d9, double& d10, double& d11, double& d12, double& d13, double& d14, Lazy_exact_nt* ) {d0 = d1 = d2 = d3 = d4 = d5 = d6 = d7 = d8 = d9 = d10 = d11 = d12 = d13 = d14 = 0;} +template < bool P > +inline void init_double(double& d0, Interval_nt

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

"; + text += "Press Escape to exit the viewer."; + return text; + } + +private: + bool m_draw_vertices; + bool m_draw_edges; + bool m_draw_faces; + bool m_flatShading; + bool m_use_mono_color; + bool m_inverse_normal; + + double m_size_points; + double m_size_edges; + + CGAL::Color m_vertices_mono_color; + CGAL::Color m_edges_mono_color; + CGAL::Color m_faces_mono_color; + QVector4D m_ambient_color; + + bool m_are_buffers_initialized; + CGAL::Bbox_3 m_bounding_box; + + // The following enum gives the indices of different elements of arrays vectors. + enum + { + BEGIN_POS=0, + POS_MONO_POINTS=BEGIN_POS, + POS_COLORED_POINTS, + POS_MONO_SEGMENTS, + POS_COLORED_SEGMENTS, + POS_MONO_FACES, + POS_COLORED_FACES, + END_POS, + BEGIN_COLOR=END_POS, + COLOR_POINTS=BEGIN_COLOR, + COLOR_SEGMENTS, + COLOR_FACES, + END_COLOR, + BEGIN_NORMAL=END_COLOR, + SMOOTH_NORMAL_MONO_FACES=BEGIN_NORMAL, + FLAT_NORMAL_MONO_FACES, + SMOOTH_NORMAL_COLORED_FACES, + FLAT_NORMAL_COLORED_FACES, + END_NORMAL, + LAST_INDEX=END_NORMAL + }; + std::vector arrays[LAST_INDEX]; + + Buffer_for_vao m_buffer_for_mono_points; + Buffer_for_vao m_buffer_for_colored_points; + Buffer_for_vao m_buffer_for_mono_segments; + Buffer_for_vao m_buffer_for_colored_segments; + Buffer_for_vao m_buffer_for_mono_faces; + Buffer_for_vao m_buffer_for_colored_faces; + + static const unsigned int NB_VBO_BUFFERS=(END_POS-BEGIN_POS)+ + (END_COLOR-BEGIN_COLOR)+2; // +2 for 2 vectors of normals + + QGLBuffer buffers[NB_VBO_BUFFERS]; + + // The following enum gives the indices of the differents vao. + enum + { VAO_MONO_POINTS=0, + VAO_COLORED_POINTS, + VAO_MONO_SEGMENTS, + VAO_COLORED_SEGMENTS, + VAO_MONO_FACES, + VAO_COLORED_FACES, + NB_VAO_BUFFERS + }; + QOpenGLVertexArrayObject vao[NB_VAO_BUFFERS]; + + QOpenGLShaderProgram rendering_program_face; + QOpenGLShaderProgram rendering_program_p_l; +}; + +} // End namespace CGAL + +#else // CGAL_USE_BASIC_VIEWER + +namespace CGAL +{ + +template +void draw(const T&, const char*, bool, const ColorFunctor&) +{ + std::cerr<<"Impossible to draw because CGAL_USE_BASIC_VIEWER is not defined." + < +void draw(const T&, const char*, bool) +{ + std::cerr<<"Impossible to draw because CGAL_USE_BASIC_VIEWER is not defined." + < +void draw(const T&, const char*) +{ + std::cerr<<"Impossible to draw because CGAL_USE_BASIC_VIEWER is not defined." + < +void draw(const T&) +{ + std::cerr<<"Impossible to draw because CGAL_USE_BASIC_VIEWER is not defined." + < #include -using namespace std; -using namespace CGAL::qglviewer; +namespace CGAL{ +namespace qglviewer{ /*! Default constructor. @@ -1602,12 +1598,10 @@ int project(qreal objx, qreal objy, qreal objz, GLdouble *modelview, fTempo[1]=modelview[1]*objx+modelview[5]*objy+modelview[9]*objz+modelview[13]; fTempo[2]=modelview[2]*objx+modelview[6]*objy+modelview[10]*objz+modelview[14]; fTempo[3]=modelview[3]*objx+modelview[7]*objy+modelview[11]*objz+modelview[15]; - //Projection transform, the final row of projection matrix is always [0 0 -1 0] - //so we optimize for that. fTempo[4]=projection[0]*fTempo[0]+projection[4]*fTempo[1]+projection[8]*fTempo[2]+projection[12]*fTempo[3]; fTempo[5]=projection[1]*fTempo[0]+projection[5]*fTempo[1]+projection[9]*fTempo[2]+projection[13]*fTempo[3]; fTempo[6]=projection[2]*fTempo[0]+projection[6]*fTempo[1]+projection[10]*fTempo[2]+projection[14]*fTempo[3]; - fTempo[7]=-fTempo[2]; + fTempo[7]=projection[3]*fTempo[0]+projection[7]*fTempo[1]+projection[11]*fTempo[2]+projection[15]*fTempo[3]; //The result normalizes between -1 and 1 if(fTempo[7]==0.0) //The w value return 0; @@ -1948,7 +1942,7 @@ int unProject(GLdouble winx, GLdouble winy, GLdouble winz, GLdouble *modelview, CGAL_INLINE_FUNCTION Vec Camera::projectedCoordinatesOf(const Vec& src, const Frame* frame) const { - GLdouble x,y,z; + GLdouble x = 0.f, y = 0.f, z = 0.f; static GLint viewport[4]; getViewport(viewport); @@ -1990,7 +1984,7 @@ Vec Camera::projectedCoordinatesOf(const Vec& src, const Frame* frame) const CGAL_INLINE_FUNCTION Vec Camera::unprojectedCoordinatesOf(const Vec& src, const Frame* frame) const { - GLdouble x,y,z; + GLdouble x = 0.f, y = 0.f, z = 0.f; static GLint viewport[4]; getViewport(viewport); unProject(src.x,src.y,src.z, modelViewMatrix_, projectionMatrix_, viewport, &x,&y,&z); @@ -2480,8 +2474,8 @@ void Camera::setFrustum(double frustum[6]) double B = (r+l)/(r-l); double C = 2*n/(t-b); double D = (t+b)/(t-b); - float E = -(f+n)/(f-n); - float F = -2*(f*n)/(f-n); + double E = -(f+n)/(f-n); + double F = -2*(f*n)/(f-n); projectionMatrix_[0] = A; projectionMatrix_[4] = 0; projectionMatrix_[8] = B ; projectionMatrix_[12] = 0; projectionMatrix_[1] = 0; projectionMatrix_[5] = C; projectionMatrix_[9] = D ; projectionMatrix_[13] = 0; projectionMatrix_[2] = 0; projectionMatrix_[6] = 0; projectionMatrix_[10] = E ; projectionMatrix_[14] = F; @@ -2493,8 +2487,8 @@ void Camera::setFrustum(double frustum[6]) double B = -(r+l)/(r-l); double C = 2/(t-b); double D = -(t+b)/(t-b); - float E = -(f+n)/(f-n); - float F = -2/(f-n); + double E = -(f+n)/(f-n); + double F = -2/(f-n); projectionMatrix_[0] = A; projectionMatrix_[1] = 0; projectionMatrix_[2] = 0 ; projectionMatrix_[3] = 0; projectionMatrix_[4] = 0; projectionMatrix_[5] = C; projectionMatrix_[6] = 0 ; projectionMatrix_[7] = 0; projectionMatrix_[8] = 0; projectionMatrix_[9] = 0; projectionMatrix_[10] = F ; projectionMatrix_[11] = 0; @@ -2539,4 +2533,4 @@ void Camera::getFrustum(double frustum[6]) frustum[4] = n; frustum[5] = f; } - +}}//end of namespace diff --git a/GraphicsView/include/CGAL/Qt/constraint.h b/GraphicsView/include/CGAL/Qt/constraint.h index 65beca0e189..842ea58efb7 100644 --- a/GraphicsView/include/CGAL/Qt/constraint.h +++ b/GraphicsView/include/CGAL/Qt/constraint.h @@ -3,17 +3,13 @@ Copyright (c) 2018 GeometryFactory Sarl (France). Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. - This file is part of a fork of the CGAL::QGLViewer library version 2.7.0. - + This file is part of a fork of the QGLViewer library version 2.7.0. http://www.libqglviewer.com - contact@libqglviewer.com This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the LICENSE file included in the packaging of this file. - libCGAL::QGLViewer uses dual licensing. Commercial/proprietary software must - purchase a libCGAL::QGLViewer Commercial License. - This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. diff --git a/GraphicsView/include/CGAL/Qt/constraint_impl.h b/GraphicsView/include/CGAL/Qt/constraint_impl.h index 7094f0c9eb5..c37fca4a729 100644 --- a/GraphicsView/include/CGAL/Qt/constraint_impl.h +++ b/GraphicsView/include/CGAL/Qt/constraint_impl.h @@ -3,17 +3,13 @@ Copyright (c) 2018 GeometryFactory Sarl (France). Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. - This file is part of a fork of the CGAL::QGLViewer library version 2.7.0. - + This file is part of a fork of the QGLViewer library version 2.7.0. http://www.libqglviewer.com - contact@libqglviewer.com This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the LICENSE file included in the packaging of this file. - libCGAL::QGLViewer uses dual licensing. Commercial/proprietary software must - purchase a libCGAL::QGLViewer Commercial License. - This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. @@ -35,8 +31,9 @@ #include #include -using namespace CGAL::qglviewer; -using namespace std; +namespace CGAL{ +namespace qglviewer{ + //////////////////////////////////////////////////////////////////////////////// // Constraint // @@ -301,3 +298,5 @@ void CameraConstraint::constrainRotation(Quaternion &rotation, break; } } + +}}//end namespace diff --git a/GraphicsView/include/CGAL/Qt/domUtils.h b/GraphicsView/include/CGAL/Qt/domUtils.h index 61e7caa4afe..466e6509bbe 100644 --- a/GraphicsView/include/CGAL/Qt/domUtils.h +++ b/GraphicsView/include/CGAL/Qt/domUtils.h @@ -3,17 +3,13 @@ Copyright (c) 2018 GeometryFactory Sarl (France). Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. - This file is part of a fork of the CGAL::QGLViewer library version 2.7.0. - + This file is part of a fork of the QGLViewer library version 2.7.0. http://www.libqglviewer.com - contact@libqglviewer.com This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the LICENSE file included in the packaging of this file. - libCGAL::QGLViewer uses dual licensing. Commercial/proprietary software must - purchase a libCGAL::QGLViewer Commercial License. - This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. diff --git a/GraphicsView/include/CGAL/Qt/frame.h b/GraphicsView/include/CGAL/Qt/frame.h index 3832c14101c..bfc4e28538f 100644 --- a/GraphicsView/include/CGAL/Qt/frame.h +++ b/GraphicsView/include/CGAL/Qt/frame.h @@ -3,17 +3,13 @@ Copyright (c) 2018 GeometryFactory Sarl (France). Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. - This file is part of a fork of the CGAL::QGLViewer library version 2.7.0. - + This file is part of a fork of the QGLViewer library version 2.7.0. http://www.libqglviewer.com - contact@libqglviewer.com This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the LICENSE file included in the packaging of this file. - libCGAL::QGLViewer uses dual licensing. Commercial/proprietary software must - purchase a libCGAL::QGLViewer Commercial License. - This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. diff --git a/GraphicsView/include/CGAL/Qt/frame_impl.h b/GraphicsView/include/CGAL/Qt/frame_impl.h index a8433867b5a..acacb62c9b4 100644 --- a/GraphicsView/include/CGAL/Qt/frame_impl.h +++ b/GraphicsView/include/CGAL/Qt/frame_impl.h @@ -3,17 +3,13 @@ Copyright (c) 2018 GeometryFactory Sarl (France). Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. - This file is part of a fork of the CGAL::QGLViewer library version 2.7.0. - + This file is part of a fork of the QGLViewer library version 2.7.0. http://www.libqglviewer.com - contact@libqglviewer.com This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the LICENSE file included in the packaging of this file. - libCGAL::QGLViewer uses dual licensing. Commercial/proprietary software must - purchase a libCGAL::QGLViewer Commercial License. - This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. @@ -36,8 +32,9 @@ #include #include -using namespace CGAL::qglviewer; -using namespace std; +namespace CGAL{ +namespace qglviewer{ + /*! Creates a default Frame. @@ -1137,7 +1134,7 @@ void Frame::alignWithFrame(const Frame *const frame, bool move, rotate(rotation().inverse() * Quaternion(axis, angle) * orientation()); // Try to align an other axis direction - unsigned short d = (index[1] + 1) % 3; + unsigned short d = (unsigned short)((index[1] + 1) % 3); Vec dir((d == 0) ? 1.0 : 0.0, (d == 1) ? 1.0 : 0.0, (d == 2) ? 1.0 : 0.0); dir = inverseTransformOf(dir); @@ -1186,3 +1183,4 @@ void Frame::projectOnLine(const Vec &origin, const Vec &direction) { proj.projectOnAxis(direction); translate(shift - proj); } +}} diff --git a/GraphicsView/include/CGAL/Qt/image_interface.h b/GraphicsView/include/CGAL/Qt/image_interface.h index d76fd993efe..aa423eb5587 100644 --- a/GraphicsView/include/CGAL/Qt/image_interface.h +++ b/GraphicsView/include/CGAL/Qt/image_interface.h @@ -3,17 +3,13 @@ Copyright (c) 2018 GeometryFactory Sarl (France). Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. - This file is part of a fork of the CGAL::QGLViewer library version 2.7.0. - + This file is part of a fork of the QGLViewer library version 2.7.0. http://www.libqglviewer.com - contact@libqglviewer.com This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the LICENSE file included in the packaging of this file. - libCGAL::QGLViewer uses dual licensing. Commercial/proprietary software must - purchase a libCGAL::QGLViewer Commercial License. - This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. @@ -56,14 +52,14 @@ private Q_SLOTS: { if(currentlyFocused == imgHeight && ratioCheckBox->isChecked()) - {imgWidth->setValue(i*ratio);} + {imgWidth->setValue(int(i*ratio));} } void imgWidthValueChanged(int i) { if(currentlyFocused == imgWidth && ratioCheckBox->isChecked()) - {imgHeight->setValue(i/ratio);} + {imgHeight->setValue(int(i/ratio));} } void onFocusChanged(QWidget*, QWidget* now) diff --git a/GraphicsView/include/CGAL/Qt/keyFrameInterpolator.h b/GraphicsView/include/CGAL/Qt/keyFrameInterpolator.h index 2fc38c84873..2090b3f6de8 100644 --- a/GraphicsView/include/CGAL/Qt/keyFrameInterpolator.h +++ b/GraphicsView/include/CGAL/Qt/keyFrameInterpolator.h @@ -3,17 +3,13 @@ Copyright (c) 2018 GeometryFactory Sarl (France). Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. - This file is part of a fork of the CGAL::QGLViewer library version 2.7.0. - + This file is part of a fork of the QGLViewer library version 2.7.0. http://www.libqglviewer.com - contact@libqglviewer.com This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the LICENSE file included in the packaging of this file. - libCGAL::QGLViewer uses dual licensing. Commercial/proprietary software must - purchase a libCGAL::QGLViewer Commercial License. - This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. diff --git a/GraphicsView/include/CGAL/Qt/keyFrameInterpolator_impl.h b/GraphicsView/include/CGAL/Qt/keyFrameInterpolator_impl.h index 6070f37164d..a591734c161 100644 --- a/GraphicsView/include/CGAL/Qt/keyFrameInterpolator_impl.h +++ b/GraphicsView/include/CGAL/Qt/keyFrameInterpolator_impl.h @@ -3,17 +3,13 @@ Copyright (c) 2018 GeometryFactory Sarl (France). Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. - This file is part of a fork of the CGAL::QGLViewer library version 2.7.0. - + This file is part of a fork of the QGLViewer library version 2.7.0. http://www.libqglviewer.com - contact@libqglviewer.com This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the LICENSE file included in the packaging of this file. - libCGAL::QGLViewer uses dual licensing. Commercial/proprietary software must - purchase a libCGAL::QGLViewer Commercial License. - This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. @@ -33,8 +29,9 @@ #include #include -using namespace CGAL::qglviewer; -using namespace std; +namespace CGAL{ +namespace qglviewer{ + /*! Creates a KeyFrameInterpolator, with \p frame as associated frame(). @@ -584,5 +581,6 @@ void KeyFrameInterpolator::KeyFrame::flipOrientationIfNeeded( if (Quaternion::dot(prev, q_) < 0.0) q_.negate(); } - #endif // DOXYGEN + +}} diff --git a/GraphicsView/include/CGAL/Qt/manipulatedCameraFrame.h b/GraphicsView/include/CGAL/Qt/manipulatedCameraFrame.h index 93343682346..77116b23788 100644 --- a/GraphicsView/include/CGAL/Qt/manipulatedCameraFrame.h +++ b/GraphicsView/include/CGAL/Qt/manipulatedCameraFrame.h @@ -3,17 +3,13 @@ Copyright (c) 2018 GeometryFactory Sarl (France). Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. - This file is part of a fork of the CGAL::QGLViewer library version 2.7.0. - + This file is part of a fork of the QGLViewer library version 2.7.0. http://www.libqglviewer.com - contact@libqglviewer.com This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the LICENSE file included in the packaging of this file. - libCGAL::QGLViewer uses dual licensing. Commercial/proprietary software must - purchase a libCGAL::QGLViewer Commercial License. - This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. diff --git a/GraphicsView/include/CGAL/Qt/manipulatedCameraFrame_impl.h b/GraphicsView/include/CGAL/Qt/manipulatedCameraFrame_impl.h index cfff7d57d14..0f9c76e0d58 100644 --- a/GraphicsView/include/CGAL/Qt/manipulatedCameraFrame_impl.h +++ b/GraphicsView/include/CGAL/Qt/manipulatedCameraFrame_impl.h @@ -3,17 +3,13 @@ Copyright (c) 2018 GeometryFactory Sarl (France). Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. - This file is part of a fork of the CGAL::QGLViewer library version 2.7.0. - + This file is part of a fork of the QGLViewer library version 2.7.0. http://www.libqglviewer.com - contact@libqglviewer.com This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the LICENSE file included in the packaging of this file. - libCGAL::QGLViewer uses dual licensing. Commercial/proprietary software must - purchase a libCGAL::QGLViewer Commercial License. - This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. @@ -38,8 +34,8 @@ #include -using namespace CGAL::qglviewer; -using namespace std; +namespace CGAL{ +namespace qglviewer{ /*! Default constructor. @@ -488,3 +484,5 @@ ManipulatedCameraFrame::pitchYawQuaternion(int x, int y, camera->screenWidth()); return rotY * rotX; } + +}} diff --git a/GraphicsView/include/CGAL/Qt/manipulatedFrame.h b/GraphicsView/include/CGAL/Qt/manipulatedFrame.h index 4821a643d1d..ca3102713ee 100644 --- a/GraphicsView/include/CGAL/Qt/manipulatedFrame.h +++ b/GraphicsView/include/CGAL/Qt/manipulatedFrame.h @@ -3,17 +3,13 @@ Copyright (c) 2018 GeometryFactory Sarl (France). Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. - This file is part of a fork of the CGAL::QGLViewer library version 2.7.0. - + This file is part of a fork of the QGLViewer library version 2.7.0. http://www.libqglviewer.com - contact@libqglviewer.com This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the LICENSE file included in the packaging of this file. - libCGAL::QGLViewer uses dual licensing. Commercial/proprietary software must - purchase a libCGAL::QGLViewer Commercial License. - This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. diff --git a/GraphicsView/include/CGAL/Qt/manipulatedFrame_impl.h b/GraphicsView/include/CGAL/Qt/manipulatedFrame_impl.h index a31a57d6b2a..e8ded238fa0 100644 --- a/GraphicsView/include/CGAL/Qt/manipulatedFrame_impl.h +++ b/GraphicsView/include/CGAL/Qt/manipulatedFrame_impl.h @@ -3,17 +3,13 @@ Copyright (c) 2018 GeometryFactory Sarl (France). Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. - This file is part of a fork of the CGAL::QGLViewer library version 2.7.0. - + This file is part of a fork of the QGLViewer library version 2.7.0. http://www.libqglviewer.com - contact@libqglviewer.com This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the LICENSE file included in the packaging of this file. - libCGAL::QGLViewer uses dual licensing. Commercial/proprietary software must - purchase a libCGAL::QGLViewer Commercial License. - This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. @@ -40,8 +36,9 @@ #include -using namespace CGAL::qglviewer; -using namespace std; +namespace CGAL{ +namespace qglviewer{ + /*! Default constructor. @@ -592,3 +589,4 @@ ManipulatedFrame::deformedBallQuaternion(int x, int y, qreal cx, qreal cy, return Quaternion(axis, angle); } #endif // DOXYGEN +}} diff --git a/GraphicsView/include/CGAL/Qt/mouseGrabber.h b/GraphicsView/include/CGAL/Qt/mouseGrabber.h index e0a71aeec2e..02d78f52750 100644 --- a/GraphicsView/include/CGAL/Qt/mouseGrabber.h +++ b/GraphicsView/include/CGAL/Qt/mouseGrabber.h @@ -3,17 +3,13 @@ Copyright (c) 2018 GeometryFactory Sarl (France). Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. - This file is part of a fork of the CGAL::QGLViewer library version 2.7.0. - + This file is part of a fork of the QGLViewer library version 2.7.0. http://www.libqglviewer.com - contact@libqglviewer.com This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the LICENSE file included in the packaging of this file. - libCGAL::QGLViewer uses dual licensing. Commercial/proprietary software must - purchase a libCGAL::QGLViewer Commercial License. - This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. diff --git a/GraphicsView/include/CGAL/Qt/mouseGrabber_impl.h b/GraphicsView/include/CGAL/Qt/mouseGrabber_impl.h index 9641f62dde7..1550214ddb8 100644 --- a/GraphicsView/include/CGAL/Qt/mouseGrabber_impl.h +++ b/GraphicsView/include/CGAL/Qt/mouseGrabber_impl.h @@ -3,17 +3,13 @@ Copyright (c) 2018 GeometryFactory Sarl (France). Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. - This file is part of a fork of the CGAL::QGLViewer library version 2.7.0. - + This file is part of a fork of the QGLViewer library version 2.7.0. http://www.libqglviewer.com - contact@libqglviewer.com This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the LICENSE file included in the packaging of this file. - libCGAL::QGLViewer uses dual licensing. Commercial/proprietary software must - purchase a libCGAL::QGLViewer Commercial License. - This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. @@ -33,7 +29,9 @@ #include -using namespace CGAL::qglviewer; +namespace CGAL{ +namespace qglviewer{ + // Static private variable CGAL_INLINE_FUNCTION @@ -95,3 +93,4 @@ void MouseGrabber::clearMouseGrabberPool(bool autoDelete) { qDeleteAll(MouseGrabber::MouseGrabberPool()); MouseGrabber::MouseGrabberPool().clear(); } +}} diff --git a/GraphicsView/include/CGAL/Qt/qglviewer.h b/GraphicsView/include/CGAL/Qt/qglviewer.h index c076fcbb102..77cc5a354f3 100644 --- a/GraphicsView/include/CGAL/Qt/qglviewer.h +++ b/GraphicsView/include/CGAL/Qt/qglviewer.h @@ -4,16 +4,12 @@ Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. This file is part of a fork of the QGLViewer library version 2.7.0. - http://www.libqglviewer.com - contact@libqglviewer.com This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the LICENSE file included in the packaging of this file. - libQGLViewer uses dual licensing. Commercial/proprietary software must - purchase a libQGLViewer Commercial License. - This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. @@ -218,7 +214,10 @@ public Q_SLOTS: also setForegroundColor(). */ void setBackgroundColor(const QColor &color) { backgroundColor_ = color; - glClearColor(color.redF(), color.greenF(), color.blueF(), color.alphaF()); + glClearColor(GLclampf(color.redF()), + GLclampf(color.greenF()), + GLclampf(color.blueF()), + GLclampf(color.alphaF())); } /*! Sets the foregroundColor() of the viewer, used to draw visual hints. See * also setBackgroundColor(). */ diff --git a/GraphicsView/include/CGAL/Qt/qglviewer_impl.h b/GraphicsView/include/CGAL/Qt/qglviewer_impl.h index 2d78bd719fb..e6a530dd845 100644 --- a/GraphicsView/include/CGAL/Qt/qglviewer_impl.h +++ b/GraphicsView/include/CGAL/Qt/qglviewer_impl.h @@ -3,17 +3,13 @@ Copyright (c) 2018 GeometryFactory Sarl (France). Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. - This file is part of a fork of the CGAL::QGLViewer library version 2.7.0. - + This file is part of a fork of the QGLViewer library version 2.7.0. http://www.libqglviewer.com - contact@libqglviewer.com This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the LICENSE file included in the packaging of this file. - libCGAL::QGLViewer uses dual licensing. Commercial/proprietary software must - purchase a libCGAL::QGLViewer Commercial License. - This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. @@ -59,9 +55,7 @@ #include #include -using namespace std; -using namespace CGAL::qglviewer; - +namespace CGAL{ // Static private variable CGAL_INLINE_FUNCTION QList &CGAL::QGLViewer::QGLViewerPool() { @@ -105,7 +99,7 @@ void CGAL::QGLViewer::defaultConstructor() { CGAL::QGLViewer::QGLViewerPool().replace(poolIndex, this); else CGAL::QGLViewer::QGLViewerPool().append(this); - camera_ = new Camera(this); + camera_ = new qglviewer::Camera(this); setCamera(camera()); setDefaultShortcuts(); @@ -221,6 +215,7 @@ void CGAL::QGLViewer::initializeGL() { format.setVersion(4,3); format.setProfile(QSurfaceFormat::CompatibilityProfile); format.setSamples(0); + format.setOption(QSurfaceFormat::DebugContext); context()->setFormat(format); bool created = context()->create(); if(!created || context()->format().profile() != QSurfaceFormat::CompatibilityProfile) { @@ -493,10 +488,10 @@ void CGAL::QGLViewer::postDraw() { } // Restore foregroundColor - float color[4]; - color[0] = foregroundColor().red() / 255.0f; - color[1] = foregroundColor().green() / 255.0f; - color[2] = foregroundColor().blue() / 255.0f; + GLfloat color[4]; + color[0] = GLfloat(foregroundColor().red()) / 255.0f; + color[1] = GLfloat(foregroundColor().green()) / 255.0f; + color[2] = GLfloat(foregroundColor().blue()) / 255.0f; color[3] = 1.0f; glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color); glDisable(GL_LIGHTING); @@ -507,9 +502,6 @@ void CGAL::QGLViewer::postDraw() { if (displayMessage_) drawText(10, height() - 10, message_); - // Restore GL state - glPopAttrib(); - glPopMatrix(); } /*! Called before draw() (instead of preDraw()) when viewer displaysInStereo(). @@ -580,58 +572,58 @@ void CGAL::QGLViewer::setCameraIsEdited(bool edit) { CGAL_INLINE_FUNCTION void CGAL::QGLViewer::setDefaultShortcuts() { // D e f a u l t a c c e l e r a t o r s - setShortcut(DRAW_AXIS, ::Qt::Key_A); - setShortcut(DRAW_GRID, ::Qt::Key_G); - setShortcut(DISPLAY_FPS, ::Qt::Key_F); - setShortcut(ENABLE_TEXT, ::Qt::SHIFT + ::Qt::Key_Question); - setShortcut(EXIT_VIEWER, ::Qt::Key_Escape); - setShortcut(CAMERA_MODE, ::Qt::Key_Space); - setShortcut(FULL_SCREEN, ::Qt::ALT + ::Qt::Key_Return); - setShortcut(STEREO, ::Qt::Key_S); - setShortcut(ANIMATION, ::Qt::Key_Return); - setShortcut(HELP, ::Qt::Key_H); - setShortcut(EDIT_CAMERA, ::Qt::Key_C); - setShortcut(MOVE_CAMERA_LEFT, ::Qt::Key_Left); - setShortcut(MOVE_CAMERA_RIGHT, ::Qt::Key_Right); - setShortcut(MOVE_CAMERA_UP, ::Qt::Key_Up); - setShortcut(MOVE_CAMERA_DOWN, ::Qt::Key_Down); - setShortcut(INCREASE_FLYSPEED, ::Qt::Key_Plus); - setShortcut(DECREASE_FLYSPEED, ::Qt::Key_Minus); + setShortcut(qglviewer::DRAW_AXIS, ::Qt::Key_A); + setShortcut(qglviewer::DRAW_GRID, ::Qt::Key_G); + setShortcut(qglviewer::DISPLAY_FPS, ::Qt::Key_F); + setShortcut(qglviewer::ENABLE_TEXT, ::Qt::SHIFT + ::Qt::Key_Question); + setShortcut(qglviewer::EXIT_VIEWER, ::Qt::Key_Escape); + setShortcut(qglviewer::CAMERA_MODE, ::Qt::Key_Space); + setShortcut(qglviewer::FULL_SCREEN, ::Qt::ALT + ::Qt::Key_Return); + setShortcut(qglviewer::STEREO, ::Qt::Key_S); + setShortcut(qglviewer::ANIMATION, ::Qt::Key_Return); + setShortcut(qglviewer::HELP, ::Qt::Key_H); + setShortcut(qglviewer::EDIT_CAMERA, ::Qt::Key_C); + setShortcut(qglviewer::MOVE_CAMERA_LEFT, ::Qt::Key_Left); + setShortcut(qglviewer::MOVE_CAMERA_RIGHT, ::Qt::Key_Right); + setShortcut(qglviewer::MOVE_CAMERA_UP, ::Qt::Key_Up); + setShortcut(qglviewer::MOVE_CAMERA_DOWN, ::Qt::Key_Down); + setShortcut(qglviewer::INCREASE_FLYSPEED, ::Qt::Key_Plus); + setShortcut(qglviewer::DECREASE_FLYSPEED, ::Qt::Key_Minus); - keyboardActionDescription_[DISPLAY_FPS] = + keyboardActionDescription_[qglviewer::DISPLAY_FPS] = tr("Toggles the display of the FPS", "DISPLAY_FPS action description"); - keyboardActionDescription_[FULL_SCREEN] = + keyboardActionDescription_[qglviewer::FULL_SCREEN] = tr("Toggles full screen display", "FULL_SCREEN action description"); - keyboardActionDescription_[DRAW_AXIS] = tr( + keyboardActionDescription_[qglviewer::DRAW_AXIS] = tr( "Toggles the display of the world axis", "DRAW_AXIS action description"); - keyboardActionDescription_[DRAW_GRID] = + keyboardActionDescription_[qglviewer::DRAW_GRID] = tr("Toggles the display of the XY grid", "DRAW_GRID action description"); - keyboardActionDescription_[CAMERA_MODE] = tr( + keyboardActionDescription_[qglviewer::CAMERA_MODE] = tr( "Changes camera mode (observe or fly)", "CAMERA_MODE action description"); - keyboardActionDescription_[STEREO] = + keyboardActionDescription_[qglviewer::STEREO] = tr("Toggles stereo display", "STEREO action description"); - keyboardActionDescription_[HELP] = + keyboardActionDescription_[qglviewer::HELP] = tr("Opens this help window", "HELP action description"); - keyboardActionDescription_[ANIMATION] = + keyboardActionDescription_[qglviewer::ANIMATION] = tr("Starts/stops the animation", "ANIMATION action description"); - keyboardActionDescription_[EDIT_CAMERA] = + keyboardActionDescription_[qglviewer::EDIT_CAMERA] = tr("Toggles camera paths display", "EDIT_CAMERA action description"); // TODO change - keyboardActionDescription_[ENABLE_TEXT] = + keyboardActionDescription_[qglviewer::ENABLE_TEXT] = tr("Toggles the display of the text", "ENABLE_TEXT action description"); - keyboardActionDescription_[EXIT_VIEWER] = + keyboardActionDescription_[qglviewer::EXIT_VIEWER] = tr("Exits program", "EXIT_VIEWER action description"); - keyboardActionDescription_[MOVE_CAMERA_LEFT] = + keyboardActionDescription_[qglviewer::MOVE_CAMERA_LEFT] = tr("Moves camera left", "MOVE_CAMERA_LEFT action description"); - keyboardActionDescription_[MOVE_CAMERA_RIGHT] = + keyboardActionDescription_[qglviewer::MOVE_CAMERA_RIGHT] = tr("Moves camera right", "MOVE_CAMERA_RIGHT action description"); - keyboardActionDescription_[MOVE_CAMERA_UP] = + keyboardActionDescription_[qglviewer::MOVE_CAMERA_UP] = tr("Moves camera up", "MOVE_CAMERA_UP action description"); - keyboardActionDescription_[MOVE_CAMERA_DOWN] = + keyboardActionDescription_[qglviewer::MOVE_CAMERA_DOWN] = tr("Moves camera down", "MOVE_CAMERA_DOWN action description"); - keyboardActionDescription_[INCREASE_FLYSPEED] = + keyboardActionDescription_[qglviewer::INCREASE_FLYSPEED] = tr("Increases fly speed", "INCREASE_FLYSPEED action description"); - keyboardActionDescription_[DECREASE_FLYSPEED] = + keyboardActionDescription_[qglviewer::DECREASE_FLYSPEED] = tr("Decreases fly speed", "DECREASE_FLYSPEED action description"); // K e y f r a m e s s h o r t c u t k e y s @@ -660,38 +652,38 @@ void CGAL::QGLViewer::setDefaultMouseBindings() { //#CONNECTION# toggleCameraMode() for (int handler = 0; handler < 2; ++handler) { - MouseHandler mh = (MouseHandler)(handler); + qglviewer::MouseHandler mh = (qglviewer::MouseHandler)(handler); ::Qt::KeyboardModifiers modifiers = - (mh == FRAME) ? frameKeyboardModifiers : cameraKeyboardModifiers; + (mh == qglviewer::FRAME) ? frameKeyboardModifiers : cameraKeyboardModifiers; - setMouseBinding(modifiers, ::Qt::LeftButton, mh, ROTATE); - setMouseBinding(modifiers, ::Qt::MidButton, mh, ZOOM); - setMouseBinding(modifiers, ::Qt::RightButton, mh, TRANSLATE); + setMouseBinding(modifiers, ::Qt::LeftButton, mh, qglviewer::ROTATE); + setMouseBinding(modifiers, ::Qt::MidButton, mh, qglviewer::ZOOM); + setMouseBinding(modifiers, ::Qt::RightButton, mh, qglviewer::TRANSLATE); - setMouseBinding(::Qt::Key_R, modifiers, ::Qt::LeftButton, mh, SCREEN_ROTATE); + setMouseBinding(::Qt::Key_R, modifiers, ::Qt::LeftButton, mh, qglviewer::SCREEN_ROTATE); - setWheelBinding(modifiers, mh, ZOOM); + setWheelBinding(modifiers, mh, qglviewer::ZOOM); } // Z o o m o n r e g i o n - setMouseBinding(::Qt::ShiftModifier, ::Qt::MidButton, CAMERA, ZOOM_ON_REGION); + setMouseBinding(::Qt::ShiftModifier, ::Qt::MidButton, qglviewer::CAMERA, qglviewer::ZOOM_ON_REGION); // S e l e c t - setMouseBinding(::Qt::ShiftModifier, ::Qt::LeftButton, SELECT); + setMouseBinding(::Qt::ShiftModifier, ::Qt::LeftButton, qglviewer::SELECT); - setMouseBinding(::Qt::ShiftModifier, ::Qt::RightButton, RAP_FROM_PIXEL); + setMouseBinding(::Qt::ShiftModifier, ::Qt::RightButton, qglviewer::RAP_FROM_PIXEL); // D o u b l e c l i c k - setMouseBinding(::Qt::NoModifier, ::Qt::LeftButton, ALIGN_CAMERA, true); - setMouseBinding(::Qt::NoModifier, ::Qt::MidButton, SHOW_ENTIRE_SCENE, true); - setMouseBinding(::Qt::NoModifier, ::Qt::RightButton, CENTER_SCENE, true); + setMouseBinding(::Qt::NoModifier, ::Qt::LeftButton, qglviewer::ALIGN_CAMERA, true); + setMouseBinding(::Qt::NoModifier, ::Qt::MidButton, qglviewer::SHOW_ENTIRE_SCENE, true); + setMouseBinding(::Qt::NoModifier, ::Qt::RightButton, qglviewer::CENTER_SCENE, true); - setMouseBinding(frameKeyboardModifiers, ::Qt::LeftButton, ALIGN_FRAME, true); + setMouseBinding(frameKeyboardModifiers, ::Qt::LeftButton, qglviewer::ALIGN_FRAME, true); // middle double click makes no sense for manipulated frame - setMouseBinding(frameKeyboardModifiers, ::Qt::RightButton, CENTER_FRAME, true); + setMouseBinding(frameKeyboardModifiers, ::Qt::RightButton, qglviewer::CENTER_FRAME, true); // A c t i o n s w i t h k e y m o d i f i e r s - setMouseBinding(::Qt::Key_Z, ::Qt::NoModifier, ::Qt::LeftButton, ZOOM_ON_PIXEL); - setMouseBinding(::Qt::Key_Z, ::Qt::NoModifier, ::Qt::RightButton, ZOOM_TO_FIT); + setMouseBinding(::Qt::Key_Z, ::Qt::NoModifier, ::Qt::LeftButton, qglviewer::ZOOM_ON_PIXEL); + setMouseBinding(::Qt::Key_Z, ::Qt::NoModifier, ::Qt::RightButton, qglviewer::ZOOM_TO_FIT); #ifdef Q_OS_MAC // Specific Mac bindings for touchpads. Two fingers emulate a wheelEvent which @@ -701,12 +693,12 @@ void CGAL::QGLViewer::setDefaultMouseBindings() { // override previous settings. const ::Qt::KeyboardModifiers macKeyboardModifiers = ::Qt::AltModifier; - setMouseBinding(macKeyboardModifiers, ::Qt::LeftButton, CAMERA, TRANSLATE); - setMouseBinding(macKeyboardModifiers, ::Qt::LeftButton, CENTER_SCENE, true); + setMouseBinding(macKeyboardModifiers, ::Qt::LeftButton, qglviewer::CAMERA, qglviewer::TRANSLATE); + setMouseBinding(macKeyboardModifiers, ::Qt::LeftButton, qglviewer::CENTER_SCENE, true); setMouseBinding(frameKeyboardModifiers | macKeyboardModifiers, ::Qt::LeftButton, - CENTER_FRAME, true); + qglviewer::CENTER_FRAME, true); setMouseBinding(frameKeyboardModifiers | macKeyboardModifiers, ::Qt::LeftButton, - FRAME, TRANSLATE); + qglviewer::FRAME, qglviewer::TRANSLATE); #endif } @@ -732,7 +724,7 @@ CGAL::qglviewer::KeyFrameInterpolator::interpolated() signals are connected to t viewer update() slot. The connections with the previous viewer's camera are removed. */ CGAL_INLINE_FUNCTION -void CGAL::QGLViewer::setCamera(Camera *const camera) { +void CGAL::QGLViewer::setCamera(qglviewer::Camera *const camera) { if (!camera) return; @@ -758,7 +750,7 @@ void CGAL::QGLViewer::setCamera(Camera *const camera) { CGAL_INLINE_FUNCTION void CGAL::QGLViewer::connectAllCameraKFIInterpolatedSignals(bool connection) { - for (QMap::ConstIterator + for (QMap::ConstIterator it = camera()->kfi_.begin(), end = camera()->kfi_.end(); it != end; ++it) { @@ -817,8 +809,9 @@ void CGAL::QGLViewer::renderText(int x, int y, const QString &str, CGAL_INLINE_FUNCTION void CGAL::QGLViewer::renderText(double x, double y, double z, const QString &str, const QFont &font) { + using CGAL::qglviewer::Vec; const Vec proj = camera_->projectedCoordinatesOf(Vec(x, y, z)); - renderText(proj.x, proj.y, str, font); + renderText(int(proj.x), int(proj.y), str, font); } #endif @@ -1162,52 +1155,52 @@ static QString mouseButtonsString(::Qt::MouseButtons b) { } CGAL_INLINE_FUNCTION -void CGAL::QGLViewer::performClickAction(ClickAction ca, const QMouseEvent *const e) { +void CGAL::QGLViewer::performClickAction(qglviewer::ClickAction ca, const QMouseEvent *const e) { // Note: action that need it should call update(). switch (ca) { // # CONNECTION setMouseBinding prevents adding NO_CLICK_ACTION in // clickBinding_ This case should hence not be possible. Prevents unused case // warning. - case NO_CLICK_ACTION: + case qglviewer::NO_CLICK_ACTION: break; - case ZOOM_ON_PIXEL: + case qglviewer::ZOOM_ON_PIXEL: camera()->interpolateToZoomOnPixel(e->pos()); break; - case ZOOM_TO_FIT: + case qglviewer::ZOOM_TO_FIT: camera()->interpolateToFitScene(); break; - case SELECT: + case qglviewer::SELECT: select(e); update(); break; - case RAP_FROM_PIXEL: + case qglviewer::RAP_FROM_PIXEL: if (!camera()->setPivotPointFromPixel(e->pos())) camera()->setPivotPoint(sceneCenter()); setVisualHintsMask(1); update(); break; - case RAP_IS_CENTER: + case qglviewer::RAP_IS_CENTER: camera()->setPivotPoint(sceneCenter()); setVisualHintsMask(1); update(); break; - case CENTER_FRAME: + case qglviewer::CENTER_FRAME: if (manipulatedFrame()) manipulatedFrame()->projectOnLine(camera()->position(), camera()->viewDirection()); break; - case CENTER_SCENE: + case qglviewer::CENTER_SCENE: camera()->centerScene(); break; - case SHOW_ENTIRE_SCENE: + case qglviewer::SHOW_ENTIRE_SCENE: camera()->showEntireScene(); break; - case ALIGN_FRAME: + case qglviewer::ALIGN_FRAME: if (manipulatedFrame()) manipulatedFrame()->alignWithFrame(camera()->frame()); break; - case ALIGN_CAMERA: - Frame *frame = new Frame(); + case qglviewer::ALIGN_CAMERA: + qglviewer::Frame *frame = new qglviewer::Frame(); frame->setTranslation(camera()->pivotPoint()); camera()->frame()->alignWithFrame(frame, true); delete frame; @@ -1249,13 +1242,13 @@ void CGAL::QGLViewer::mousePressEvent(QMouseEvent *e) { it = mouseBinding_.begin(), end = mouseBinding_.end(); it != end; ++it) - if ((it.value().handler == FRAME) && (it.key().button == e->button())) { - ManipulatedFrame *mf = - dynamic_cast(mouseGrabber()); + if ((it.value().handler == qglviewer::FRAME) && (it.key().button == e->button())) { + qglviewer::ManipulatedFrame *mf = + dynamic_cast(mouseGrabber()); if (mouseGrabberIsAManipulatedCameraFrame_) { - mf->ManipulatedFrame::startAction(it.value().action, + mf->qglviewer::ManipulatedFrame::startAction(it.value().action, it.value().withConstraint); - mf->ManipulatedFrame::mousePressEvent(e, camera()); + mf->qglviewer::ManipulatedFrame::mousePressEvent(e, camera()); } else { mf->startAction(it.value().action, it.value().withConstraint); mf->mousePressEvent(e, camera()); @@ -1273,11 +1266,11 @@ void CGAL::QGLViewer::mousePressEvent(QMouseEvent *e) { if (mouseBinding_.contains(mbp)) { MouseActionPrivate map = mouseBinding_[mbp]; switch (map.handler) { - case CAMERA: + case qglviewer::CAMERA: camera()->frame()->startAction(map.action, map.withConstraint); camera()->frame()->mousePressEvent(e, camera()); break; - case FRAME: + case qglviewer::FRAME: if (manipulatedFrame()) { if (manipulatedFrameIsACamera_) { manipulatedFrame()->ManipulatedFrame::startAction( @@ -1290,7 +1283,7 @@ void CGAL::QGLViewer::mousePressEvent(QMouseEvent *e) { } break; } - if (map.action == SCREEN_ROTATE) + if (map.action == qglviewer::SCREEN_ROTATE) // Display visual hint line update(); } else @@ -1339,8 +1332,8 @@ void CGAL::QGLViewer::mouseMoveEvent(QMouseEvent *e) { mouseGrabber()->checkIfGrabsMouse(e->x(), e->y(), camera()); if (mouseGrabber()->grabsMouse()) if (mouseGrabberIsAManipulatedCameraFrame_) - (dynamic_cast(mouseGrabber())) - ->ManipulatedFrame::mouseMoveEvent(e, camera()); + (dynamic_cast(mouseGrabber())) + ->qglviewer::ManipulatedFrame::mouseMoveEvent(e, camera()); else mouseGrabber()->mouseMoveEvent(e, camera()); else @@ -1354,7 +1347,7 @@ void CGAL::QGLViewer::mouseMoveEvent(QMouseEvent *e) { camera()->frame()->mouseMoveEvent(e, camera()); // #CONNECTION# manipulatedCameraFrame::mouseMoveEvent specific if at the // beginning - if (camera()->frame()->action_ == ZOOM_ON_REGION) + if (camera()->frame()->action_ == qglviewer::ZOOM_ON_REGION) update(); } else // ! if ((manipulatedFrame()) && (manipulatedFrame()->isManipulated())) @@ -1363,7 +1356,7 @@ void CGAL::QGLViewer::mouseMoveEvent(QMouseEvent *e) { else manipulatedFrame()->mouseMoveEvent(e, camera()); else if (hasMouseTracking()) { - Q_FOREACH (MouseGrabber *mg, MouseGrabber::MouseGrabberPool()) { + Q_FOREACH (qglviewer::MouseGrabber *mg, qglviewer::MouseGrabber::MouseGrabberPool()) { mg->checkIfGrabsMouse(e->x(), e->y(), camera()); if (mg->grabsMouse()) { setMouseGrabber(mg); @@ -1389,8 +1382,8 @@ CGAL_INLINE_FUNCTION void CGAL::QGLViewer::mouseReleaseEvent(QMouseEvent *e) { if (mouseGrabber()) { if (mouseGrabberIsAManipulatedCameraFrame_) - (dynamic_cast(mouseGrabber())) - ->ManipulatedFrame::mouseReleaseEvent(e, camera()); + (dynamic_cast(mouseGrabber())) + ->qglviewer::ManipulatedFrame::mouseReleaseEvent(e, camera()); else mouseGrabber()->mouseReleaseEvent(e, camera()); mouseGrabber()->checkIfGrabsMouse(e->x(), e->y(), camera()); @@ -1426,13 +1419,13 @@ void CGAL::QGLViewer::wheelEvent(QWheelEvent *e) { it = wheelBinding_.begin(), end = wheelBinding_.end(); it != end; ++it) - if (it.value().handler == FRAME) { - ManipulatedFrame *mf = - dynamic_cast(mouseGrabber()); + if (it.value().handler == qglviewer::FRAME) { + qglviewer::ManipulatedFrame *mf = + dynamic_cast(mouseGrabber()); if (mouseGrabberIsAManipulatedCameraFrame_) { - mf->ManipulatedFrame::startAction(it.value().action, + mf->qglviewer::ManipulatedFrame::startAction(it.value().action, it.value().withConstraint); - mf->ManipulatedFrame::wheelEvent(e, camera()); + mf->qglviewer::ManipulatedFrame::wheelEvent(e, camera()); } else { mf->startAction(it.value().action, it.value().withConstraint); mf->wheelEvent(e, camera()); @@ -1449,11 +1442,11 @@ void CGAL::QGLViewer::wheelEvent(QWheelEvent *e) { if (wheelBinding_.contains(wbp)) { MouseActionPrivate map = wheelBinding_[wbp]; switch (map.handler) { - case CAMERA: + case qglviewer::CAMERA: camera()->frame()->startAction(map.action, map.withConstraint); camera()->frame()->wheelEvent(e, camera()); break; - case FRAME: + case qglviewer::FRAME: if (manipulatedFrame()) { if (manipulatedFrameIsACamera_) { manipulatedFrame()->ManipulatedFrame::startAction( @@ -1549,16 +1542,16 @@ CGAL::qglviewer::MouseGrabber::checkIfGrabsMouse() test performed by mouseMoveEv If the MouseGrabber is disabled (see mouseGrabberIsEnabled()), this method silently does nothing. */ CGAL_INLINE_FUNCTION -void CGAL::QGLViewer::setMouseGrabber(MouseGrabber *mouseGrabber) { +void CGAL::QGLViewer::setMouseGrabber(qglviewer::MouseGrabber *mouseGrabber) { if (!mouseGrabberIsEnabled(mouseGrabber)) return; mouseGrabber_ = mouseGrabber; mouseGrabberIsAManipulatedFrame_ = - (dynamic_cast(mouseGrabber) != NULL); + (dynamic_cast(mouseGrabber) != NULL); mouseGrabberIsAManipulatedCameraFrame_ = - ((dynamic_cast(mouseGrabber) != NULL) && + ((dynamic_cast(mouseGrabber) != NULL) && (mouseGrabber != camera()->frame())); Q_EMIT mouseGrabberChanged(mouseGrabber); } @@ -1574,7 +1567,7 @@ void CGAL::QGLViewer::setMouseGrabberIsEnabled( } CGAL_INLINE_FUNCTION -QString CGAL::QGLViewer::mouseActionString(MouseAction ma) { +QString CGAL::QGLViewer::mouseActionString(qglviewer::MouseAction ma) { switch (ma) { case CGAL::qglviewer::NO_MOUSE_ACTION: return QString::null; @@ -1833,10 +1826,10 @@ QString CGAL::QGLViewer::mouseString() const { if (!text.isNull()) { switch (itmb.value().handler) { - case CAMERA: + case qglviewer::CAMERA: text += " " + tr("camera", "Suffix after action"); break; - case FRAME: + case qglviewer::FRAME: text += " " + tr("manipulated frame", "Suffix after action"); break; } @@ -1857,10 +1850,10 @@ QString CGAL::QGLViewer::mouseString() const { if (!text.isNull()) { switch (itw.value().handler) { - case CAMERA: + case qglviewer::CAMERA: text += " " + tr("camera", "Suffix after action"); break; - case FRAME: + case qglviewer::FRAME: text += " " + tr("manipulated frame", "Suffix after action"); break; } @@ -1871,7 +1864,7 @@ QString CGAL::QGLViewer::mouseString() const { mouseBinding[cbp] = text; } - for (QMap::ConstIterator + for (QMap::ConstIterator itcb = clickBinding_.begin(), endcb = clickBinding_.end(); itcb != endcb; ++itcb) @@ -2022,13 +2015,13 @@ QString CGAL::QGLViewer::keyboardString() const { } // 3 - KeyboardAction bindings description - for (QMap::ConstIterator + for (QMap::ConstIterator it = keyboardBinding_.begin(), end = keyboardBinding_.end(); it != end; ++it) if ((it.value() != 0) && ((!cameraIsInRotateMode()) || - ((it.key() != INCREASE_FLYSPEED) && (it.key() != DECREASE_FLYSPEED)))) + ((it.key() != qglviewer::INCREASE_FLYSPEED) && (it.key() != qglviewer::DECREASE_FLYSPEED)))) keyDescription[it.value()] = keyboardActionDescription_[it.key()]; // Add to text in sorted order @@ -2196,7 +2189,7 @@ void CGAL::QGLViewer::keyPressEvent(QKeyEvent *e) { const ::Qt::KeyboardModifiers modifiers = e->modifiers(); - QMap::ConstIterator it = keyboardBinding_ + QMap::ConstIterator it = keyboardBinding_ .begin(), end = keyboardBinding_.end(); @@ -2220,7 +2213,7 @@ void CGAL::QGLViewer::keyPressEvent(QKeyEvent *e) { else { // Stop previous interpolation before starting a new one. if (index != previousPathId_) { - KeyFrameInterpolator *previous = + qglviewer::KeyFrameInterpolator *previous = camera()->keyFrameInterpolator(previousPathId_); if ((previous) && (previous->interpolationIsStarted())) previous->resetInterpolation(); @@ -2274,71 +2267,71 @@ void CGAL::QGLViewer::keyReleaseEvent(QKeyEvent *e) { } CGAL_INLINE_FUNCTION -void CGAL::QGLViewer::handleKeyboardAction(KeyboardAction id) { +void CGAL::QGLViewer::handleKeyboardAction(qglviewer::KeyboardAction id) { switch (id) { - case DRAW_AXIS: + case qglviewer::DRAW_AXIS: toggleAxisIsDrawn(); break; - case DRAW_GRID: + case qglviewer::DRAW_GRID: toggleGridIsDrawn(); break; - case DISPLAY_FPS: + case qglviewer::DISPLAY_FPS: toggleFPSIsDisplayed(); break; - case ENABLE_TEXT: + case qglviewer::ENABLE_TEXT: toggleTextIsEnabled(); break; - case EXIT_VIEWER: + case qglviewer::EXIT_VIEWER: saveStateToFileForAllViewers(); qApp->closeAllWindows(); break; - case FULL_SCREEN: + case qglviewer::FULL_SCREEN: toggleFullScreen(); break; - case STEREO: + case qglviewer::STEREO: toggleStereoDisplay(); break; - case ANIMATION: + case qglviewer::ANIMATION: toggleAnimation(); break; - case HELP: + case qglviewer::HELP: help(); break; - case EDIT_CAMERA: + case qglviewer::EDIT_CAMERA: toggleCameraIsEdited(); break; - case CAMERA_MODE: + case qglviewer::CAMERA_MODE: toggleCameraMode(); displayMessage(cameraIsInRotateMode() ? tr("Camera in observer mode", "Feedback message") : tr("Camera in fly mode", "Feedback message")); break; - case MOVE_CAMERA_LEFT: + case qglviewer::MOVE_CAMERA_LEFT: camera()->frame()->translate(camera()->frame()->inverseTransformOf( - Vec(-10.0 * camera()->flySpeed(), 0.0, 0.0))); + qglviewer::Vec(-10.0 * camera()->flySpeed(), 0.0, 0.0))); update(); break; - case MOVE_CAMERA_RIGHT: + case qglviewer::MOVE_CAMERA_RIGHT: camera()->frame()->translate(camera()->frame()->inverseTransformOf( - Vec(10.0 * camera()->flySpeed(), 0.0, 0.0))); + qglviewer::Vec(10.0 * camera()->flySpeed(), 0.0, 0.0))); update(); break; - case MOVE_CAMERA_UP: + case qglviewer::MOVE_CAMERA_UP: camera()->frame()->translate(camera()->frame()->inverseTransformOf( - Vec(0.0, 10.0 * camera()->flySpeed(), 0.0))); + qglviewer::Vec(0.0, 10.0 * camera()->flySpeed(), 0.0))); update(); break; - case MOVE_CAMERA_DOWN: + case qglviewer::MOVE_CAMERA_DOWN: camera()->frame()->translate(camera()->frame()->inverseTransformOf( - Vec(0.0, -10.0 * camera()->flySpeed(), 0.0))); + qglviewer::Vec(0.0, -10.0 * camera()->flySpeed(), 0.0))); update(); break; - case INCREASE_FLYSPEED: + case qglviewer::INCREASE_FLYSPEED: camera()->setFlySpeed(camera()->flySpeed() * 1.5); break; - case DECREASE_FLYSPEED: + case qglviewer::DECREASE_FLYSPEED: camera()->setFlySpeed(camera()->flySpeed() / 1.5); break; } @@ -2377,7 +2370,7 @@ Only one shortcut can be assigned to a given CGAL::QGLViewer::KeyboardAction (ne bindings replace previous ones). If several KeyboardAction are binded to the same shortcut, only one of them is active. */ CGAL_INLINE_FUNCTION -void CGAL::QGLViewer::setShortcut(KeyboardAction action, unsigned int key) { +void CGAL::QGLViewer::setShortcut(qglviewer::KeyboardAction action, unsigned int key) { keyboardBinding_[action] = key; } @@ -2399,7 +2392,7 @@ See the keyboard page for details and default values and the keyboardAndMouse example for a practical illustration. */ CGAL_INLINE_FUNCTION -unsigned int CGAL::QGLViewer::shortcut(KeyboardAction action) const { +unsigned int CGAL::QGLViewer::shortcut(qglviewer::KeyboardAction action) const { if (keyboardBinding_.contains(action)) return keyboardBinding_[action]; else @@ -2511,8 +2504,8 @@ CGAL_INLINE_FUNCTION action). */ CGAL_INLINE_FUNCTION void CGAL::QGLViewer::setMouseBinding(::Qt::KeyboardModifiers modifiers, - ::Qt::MouseButton button, MouseHandler handler, - MouseAction action, bool withConstraint) { + ::Qt::MouseButton button, qglviewer::MouseHandler handler, + qglviewer::MouseAction action, bool withConstraint) { setMouseBinding(::Qt::Key(0), modifiers, button, handler, action, withConstraint); } @@ -2558,12 +2551,12 @@ See also setMouseBinding(::Qt::KeyboardModifiers, ::Qt::MouseButtons, ClickActio bool, int), setWheelBinding() and clearMouseBindings(). */ CGAL_INLINE_FUNCTION void CGAL::QGLViewer::setMouseBinding(::Qt::Key key, ::Qt::KeyboardModifiers modifiers, - ::Qt::MouseButton button, MouseHandler handler, - MouseAction action, bool withConstraint) { - if ((handler == FRAME) && - ((action == MOVE_FORWARD) || (action == MOVE_BACKWARD) || - (action == ROLL) || (action == LOOK_AROUND) || - (action == ZOOM_ON_REGION))) { + ::Qt::MouseButton button, qglviewer::MouseHandler handler, + qglviewer::MouseAction action, bool withConstraint) { + if ((handler == qglviewer::FRAME) && + ((action == qglviewer::MOVE_FORWARD) || (action == qglviewer::MOVE_BACKWARD) || + (action == qglviewer::ROLL) || (action == qglviewer::LOOK_AROUND) || + (action == qglviewer::ZOOM_ON_REGION))) { qWarning("Cannot bind %s to FRAME", mouseActionString(action).toLatin1().constData()); return; @@ -2580,7 +2573,7 @@ void CGAL::QGLViewer::setMouseBinding(::Qt::Key key, ::Qt::KeyboardModifiers mod map.withConstraint = withConstraint; MouseBindingPrivate mbp(modifiers, button, key); - if (action == NO_MOUSE_ACTION) + if (action == qglviewer::NO_MOUSE_ACTION) mouseBinding_.remove(mbp); else mouseBinding_.insert(mbp, map); @@ -2598,7 +2591,7 @@ void CGAL::QGLViewer::setMouseBinding(::Qt::Key key, ::Qt::KeyboardModifiers mod */ CGAL_INLINE_FUNCTION void CGAL::QGLViewer::setMouseBinding(::Qt::KeyboardModifiers modifiers, - ::Qt::MouseButton button, ClickAction action, + ::Qt::MouseButton button, qglviewer::ClickAction action, bool doubleClick, ::Qt::MouseButtons buttonsBefore) { setMouseBinding(::Qt::Key(0), modifiers, button, action, doubleClick, @@ -2633,7 +2626,7 @@ MouseAction, bool), setWheelBinding() and clearMouseBindings(). */ CGAL_INLINE_FUNCTION void CGAL::QGLViewer::setMouseBinding(::Qt::Key key, ::Qt::KeyboardModifiers modifiers, - ::Qt::MouseButton button, ClickAction action, + ::Qt::MouseButton button, qglviewer::ClickAction action, bool doubleClick, ::Qt::MouseButtons buttonsBefore) { if ((buttonsBefore != ::Qt::NoButton) && !doubleClick) { @@ -2650,7 +2643,7 @@ void CGAL::QGLViewer::setMouseBinding(::Qt::Key key, ::Qt::KeyboardModifiers mod ClickBindingPrivate cbp(modifiers, button, doubleClick, buttonsBefore, key); // #CONNECTION performClickAction comment on NO_CLICK_ACTION - if (action == NO_CLICK_ACTION) + if (action == qglviewer::NO_CLICK_ACTION) clickBinding_.remove(cbp); else clickBinding_.insert(cbp, action); @@ -2668,7 +2661,7 @@ void CGAL::QGLViewer::setMouseBinding(::Qt::Key key, ::Qt::KeyboardModifiers mod to be pressed to activate this action). */ CGAL_INLINE_FUNCTION void CGAL::QGLViewer::setWheelBinding(::Qt::KeyboardModifiers modifiers, - MouseHandler handler, MouseAction action, + qglviewer::MouseHandler handler, qglviewer::MouseAction action, bool withConstraint) { setWheelBinding(::Qt::Key(0), modifiers, handler, action, withConstraint); } @@ -2687,18 +2680,18 @@ CGAL::QGLViewer::MOVE_FORWARD moves at a constant speed defined by CGAL::qglviewer::Camera::flySpeed(). */ CGAL_INLINE_FUNCTION void CGAL::QGLViewer::setWheelBinding(::Qt::Key key, ::Qt::KeyboardModifiers modifiers, - MouseHandler handler, MouseAction action, + qglviewer::MouseHandler handler, qglviewer::MouseAction action, bool withConstraint) { //#CONNECTION# ManipulatedFrame::wheelEvent and // ManipulatedCameraFrame::wheelEvent switches - if ((action != ZOOM) && (action != MOVE_FORWARD) && - (action != MOVE_BACKWARD) && (action != NO_MOUSE_ACTION)) { + if ((action != qglviewer::ZOOM) && (action != qglviewer::MOVE_FORWARD) && + (action != qglviewer::MOVE_BACKWARD) && (action != qglviewer::NO_MOUSE_ACTION)) { qWarning("Cannot bind %s to wheel", mouseActionString(action).toLatin1().constData()); return; } - if ((handler == FRAME) && (action != ZOOM) && (action != NO_MOUSE_ACTION)) { + if ((handler == qglviewer::FRAME) && (action != qglviewer::ZOOM) && (action != qglviewer::NO_MOUSE_ACTION)) { qWarning("Cannot bind %s to FRAME wheel", mouseActionString(action).toLatin1().constData()); return; @@ -2710,7 +2703,7 @@ void CGAL::QGLViewer::setWheelBinding(::Qt::Key key, ::Qt::KeyboardModifiers mod map.withConstraint = withConstraint; WheelBindingPrivate wbp(modifiers, key); - if (action == NO_MOUSE_ACTION) + if (action == qglviewer::NO_MOUSE_ACTION) wheelBinding_.remove(wbp); else wheelBinding_[wbp] = map; @@ -2755,14 +2748,14 @@ if (ma != CGAL::QGLViewer::NO_MOUSE_ACTION) ... Use mouseHandler() to know which object (CGAL::QGLViewer::CAMERA or CGAL::QGLViewer::FRAME) will execute this action. */ CGAL_INLINE_FUNCTION -MouseAction CGAL::QGLViewer::mouseAction(::Qt::Key key, +qglviewer::MouseAction CGAL::QGLViewer::mouseAction(::Qt::Key key, ::Qt::KeyboardModifiers modifiers, ::Qt::MouseButton button) const { MouseBindingPrivate mbp(modifiers, button, key); if (mouseBinding_.contains(mbp)) return mouseBinding_[mbp].action; else - return NO_MOUSE_ACTION; + return qglviewer::NO_MOUSE_ACTION; } @@ -2803,7 +2796,7 @@ them is returned. See also setMouseBinding(), getClickActionBinding() and getMouseActionBinding(). */ CGAL_INLINE_FUNCTION -void CGAL::QGLViewer::getWheelActionBinding(MouseHandler handler, MouseAction action, +void CGAL::QGLViewer::getWheelActionBinding(qglviewer::MouseHandler handler, qglviewer::MouseAction action, bool withConstraint, ::Qt::Key &key, ::Qt::KeyboardModifiers &modifiers) const { for (QMap::ConstIterator @@ -2817,7 +2810,7 @@ void CGAL::QGLViewer::getWheelActionBinding(MouseHandler handler, MouseAction ac return; } - key = ::Qt::Key(-1); + key = ::Qt::Key_unknown; modifiers = ::Qt::NoModifier; } @@ -2832,7 +2825,7 @@ MouseAction, one of them is returned. See also setMouseBinding(), getClickActionBinding() and getWheelActionBinding(). */ CGAL_INLINE_FUNCTION -void CGAL::QGLViewer::getMouseActionBinding(MouseHandler handler, MouseAction action, +void CGAL::QGLViewer::getMouseActionBinding(qglviewer::MouseHandler handler, qglviewer::MouseAction action, bool withConstraint, ::Qt::Key &key, ::Qt::KeyboardModifiers &modifiers, ::Qt::MouseButton &button) const { @@ -2862,14 +2855,14 @@ setWheelBinding(). Same as mouseAction(), but for the wheel action. See also wheelHandler(). */ -MouseAction +qglviewer::MouseAction CGAL_INLINE_FUNCTION CGAL::QGLViewer::wheelAction(::Qt::Key key, ::Qt::KeyboardModifiers modifiers) const { WheelBindingPrivate wbp(modifiers, key); if (wheelBinding_.contains(wbp)) return wheelBinding_[wbp].action; else - return NO_MOUSE_ACTION; + return qglviewer::NO_MOUSE_ACTION; } /*! Returns the MouseHandler (if any) that receives wheel events when the \p @@ -2901,7 +2894,7 @@ CGAL::QGLViewer::clickAction(::Qt::Key key, ::Qt::KeyboardModifiers modifiers, if (clickBinding_.contains(cbp)) return clickBinding_[cbp]; else - return NO_CLICK_ACTION; + return qglviewer::NO_CLICK_ACTION; } /*! Returns the mouse and keyboard state that triggers \p action. @@ -2914,12 +2907,12 @@ buttons trigger in the ClickAction, one of them is returned. See also setMouseBinding(), getMouseActionBinding() and getWheelActionBinding(). */ CGAL_INLINE_FUNCTION -void CGAL::QGLViewer::getClickActionBinding(ClickAction action, ::Qt::Key &key, +void CGAL::QGLViewer::getClickActionBinding(qglviewer::ClickAction action, ::Qt::Key &key, ::Qt::KeyboardModifiers &modifiers, ::Qt::MouseButton &button, bool &doubleClick, ::Qt::MouseButtons &buttonsBefore) const { - for (QMap::ConstIterator + for (QMap::ConstIterator it = clickBinding_.begin(), end = clickBinding_.end(); it != end; ++it) @@ -2948,7 +2941,7 @@ bool CGAL::QGLViewer::cameraIsInRotateMode() const { ::Qt::Key key; ::Qt::KeyboardModifiers modifiers; ::Qt::MouseButton button; - getMouseActionBinding(CAMERA, ROTATE, true /*constraint*/, key, modifiers, + getMouseActionBinding(qglviewer::CAMERA, qglviewer::ROTATE, true /*constraint*/, key, modifiers, button); return button != ::Qt::NoButton; } @@ -2972,12 +2965,12 @@ void CGAL::QGLViewer::toggleCameraMode() { ::Qt::Key key; ::Qt::KeyboardModifiers modifiers; ::Qt::MouseButton button; - getMouseActionBinding(CAMERA, ROTATE, true /*constraint*/, key, modifiers, + getMouseActionBinding(qglviewer::CAMERA, qglviewer::ROTATE, true /*constraint*/, key, modifiers, button); bool rotateMode = button != ::Qt::NoButton; if (!rotateMode) { - getMouseActionBinding(CAMERA, MOVE_FORWARD, true /*constraint*/, key, + getMouseActionBinding(qglviewer::CAMERA, qglviewer::MOVE_FORWARD, true /*constraint*/, key, modifiers, button); } @@ -2986,31 +2979,31 @@ void CGAL::QGLViewer::toggleCameraMode() { camera()->frame()->updateSceneUpVector(); camera()->frame()->stopSpinning(); - setMouseBinding(modifiers, ::Qt::LeftButton, CAMERA, MOVE_FORWARD); - setMouseBinding(modifiers, ::Qt::MidButton, CAMERA, LOOK_AROUND); - setMouseBinding(modifiers, ::Qt::RightButton, CAMERA, MOVE_BACKWARD); + setMouseBinding(modifiers, ::Qt::LeftButton, qglviewer::CAMERA, qglviewer::MOVE_FORWARD); + setMouseBinding(modifiers, ::Qt::MidButton, qglviewer::CAMERA, qglviewer::LOOK_AROUND); + setMouseBinding(modifiers, ::Qt::RightButton, qglviewer::CAMERA, qglviewer::MOVE_BACKWARD); - setMouseBinding(::Qt::Key_R, modifiers, ::Qt::LeftButton, CAMERA, ROLL); + setMouseBinding(::Qt::Key_R, modifiers, ::Qt::LeftButton, qglviewer::CAMERA, qglviewer::ROLL); - setMouseBinding(::Qt::NoModifier, ::Qt::LeftButton, NO_CLICK_ACTION, true); - setMouseBinding(::Qt::NoModifier, ::Qt::MidButton, NO_CLICK_ACTION, true); - setMouseBinding(::Qt::NoModifier, ::Qt::RightButton, NO_CLICK_ACTION, true); + setMouseBinding(::Qt::NoModifier, ::Qt::LeftButton, qglviewer::NO_CLICK_ACTION, true); + setMouseBinding(::Qt::NoModifier, ::Qt::MidButton, qglviewer::NO_CLICK_ACTION, true); + setMouseBinding(::Qt::NoModifier, ::Qt::RightButton, qglviewer::NO_CLICK_ACTION, true); - setWheelBinding(modifiers, CAMERA, MOVE_FORWARD); + setWheelBinding(modifiers, qglviewer::CAMERA, qglviewer::MOVE_FORWARD); } else { // Should stop flyTimer. But unlikely and not easy. - setMouseBinding(modifiers, ::Qt::LeftButton, CAMERA, ROTATE); - setMouseBinding(modifiers, ::Qt::MidButton, CAMERA, ZOOM); - setMouseBinding(modifiers, ::Qt::RightButton, CAMERA, TRANSLATE); + setMouseBinding(modifiers, ::Qt::LeftButton, qglviewer::CAMERA, qglviewer::ROTATE); + setMouseBinding(modifiers, ::Qt::MidButton, qglviewer::CAMERA, qglviewer::ZOOM); + setMouseBinding(modifiers, ::Qt::RightButton, qglviewer::CAMERA, qglviewer::TRANSLATE); - setMouseBinding(::Qt::Key_R, modifiers, ::Qt::LeftButton, CAMERA, - SCREEN_ROTATE); + setMouseBinding(::Qt::Key_R, modifiers, ::Qt::LeftButton, qglviewer::CAMERA, + qglviewer::SCREEN_ROTATE); - setMouseBinding(::Qt::NoModifier, ::Qt::LeftButton, ALIGN_CAMERA, true); - setMouseBinding(::Qt::NoModifier, ::Qt::MidButton, SHOW_ENTIRE_SCENE, true); - setMouseBinding(::Qt::NoModifier, ::Qt::RightButton, CENTER_SCENE, true); + setMouseBinding(::Qt::NoModifier, ::Qt::LeftButton, qglviewer::ALIGN_CAMERA, true); + setMouseBinding(::Qt::NoModifier, ::Qt::MidButton, qglviewer::SHOW_ENTIRE_SCENE, true); + setMouseBinding(::Qt::NoModifier, ::Qt::RightButton, qglviewer::CENTER_SCENE, true); - setWheelBinding(modifiers, CAMERA, ZOOM); + setWheelBinding(modifiers, qglviewer::CAMERA, qglviewer::ZOOM); } } @@ -3031,7 +3024,7 @@ Note that a CGAL::qglviewer::ManipulatedCameraFrame can be set as the manipulatedFrame(): it is possible to manipulate the camera of a first viewer in a second viewer. */ CGAL_INLINE_FUNCTION -void CGAL::QGLViewer::setManipulatedFrame(ManipulatedFrame *frame) { +void CGAL::QGLViewer::setManipulatedFrame(qglviewer::ManipulatedFrame *frame) { if (manipulatedFrame()) { manipulatedFrame()->stopSpinning(); @@ -3046,7 +3039,7 @@ void CGAL::QGLViewer::setManipulatedFrame(ManipulatedFrame *frame) { manipulatedFrameIsACamera_ = ((manipulatedFrame() != camera()->frame()) && - (dynamic_cast(manipulatedFrame()) != NULL)); + (dynamic_cast(manipulatedFrame()) != NULL)); if (manipulatedFrame()) { // Prevent multiple connections, that would result in useless display @@ -3094,7 +3087,7 @@ void CGAL::QGLViewer::drawVisualHints() { QMatrix4x4 mvMatrix; for(int i=0; i < 16; i++) { - mvMatrix.data()[i] = camera()->orientation().inverse().matrix()[i]; + mvMatrix.data()[i] = float(camera()->orientation().inverse().matrix()[i]); } rendering_program.setUniformValue("mvp_matrix", mvpMatrix); rendering_program.setUniformValue("color", QColor(::Qt::lightGray)); @@ -3117,7 +3110,7 @@ void CGAL::QGLViewer::drawVisualHints() { camera()->setType(CGAL::qglviewer::Camera::ORTHOGRAPHIC); for(int i=0; i < 16; i++) { - mvMatrix.data()[i] = camera()->orientation().inverse().matrix()[i]; + mvMatrix.data()[i] = float(camera()->orientation().inverse().matrix()[i]); } mvpMatrix.setToIdentity(); mvpMatrix.ortho(-1,1,-1,1,-1,1); @@ -3151,8 +3144,8 @@ void CGAL::QGLViewer::drawVisualHints() { std::vector vertices; for(int i=0; i< 4; ++i) { - float x = (pow(-1, i)*(1-i/2)); - float y = (pow(-1, i)*(i/2)); + float x = float(std::pow(-1, i)*(1-i/2)); + float y = float(std::pow(-1, i)*(i/2)); vertices.push_back(x); vertices.push_back(y); vertices.push_back(0); @@ -3167,9 +3160,11 @@ void CGAL::QGLViewer::drawVisualHints() { mvpMatrix.setToIdentity(); mvpMatrix.ortho(-1,1,-1,1,-1,1); size=30*devicePixelRatio(); - rendering_program.setUniformValue("mvp_matrix", mvpMatrix); - glViewport((camera()->projectedCoordinatesOf(camera()->pivotPoint()).x-size/2)*devicePixelRatio(), (height() - camera()->projectedCoordinatesOf(camera()->pivotPoint()).y-size/2)*devicePixelRatio(), size, size); - glScissor ((camera()->projectedCoordinatesOf(camera()->pivotPoint()).x-size/2)*devicePixelRatio(), (height() - camera()->projectedCoordinatesOf(camera()->pivotPoint()).y-size/2)*devicePixelRatio(), size, size); + rendering_program.setUniformValue("mvp_matrix", mvpMatrix); + glViewport(GLint((camera()->projectedCoordinatesOf(camera()->pivotPoint()).x-size/2)*devicePixelRatio()), + GLint((height() - camera()->projectedCoordinatesOf(camera()->pivotPoint()).y-size/2)*devicePixelRatio()), size, size); + glScissor (GLint((camera()->projectedCoordinatesOf(camera()->pivotPoint()).x-size/2)*devicePixelRatio()), + GLint((height() - camera()->projectedCoordinatesOf(camera()->pivotPoint()).y-size/2)*devicePixelRatio()), size, size); rendering_program.setUniformValue("color", QColor(::Qt::black)); glLineWidth(3.0); glDrawArrays(GL_LINES, 0, static_cast(4)); @@ -3214,18 +3209,21 @@ CGAL_INLINE_FUNCTION void CGAL::QGLViewer::drawArrow(double r,double R, int prec, CGAL::qglviewer::Vec from, CGAL::qglviewer::Vec to, CGAL::qglviewer::Vec color, std::vector &data) { + using std::cos; + using std::sin; + using std::acos; CGAL::qglviewer::Vec temp = to-from; - QVector3D dir = QVector3D(temp.x, temp.y, temp.z); + QVector3D dir = QVector3D(float(temp.x), float(temp.y), float(temp.z)); QMatrix4x4 mat; mat.setToIdentity(); - mat.translate(from.x, from.y, from.z); + mat.translate(float(from.x), float(from.y), float(from.z)); mat.scale(dir.length()); dir.normalize(); float angle = 0.0; if(std::sqrt((dir.x()*dir.x()+dir.y()*dir.y())) > 1) angle = 90.0f; else - angle =acos(dir.y()/std::sqrt(dir.x()*dir.x()+dir.y()*dir.y()+dir.z()*dir.z()))*180.0/CGAL_PI; + angle = float(acos(dir.y()/std::sqrt(dir.lengthSquared()))*180.0/CGAL_PI); QVector3D axis; axis = QVector3D(dir.z(), 0, -dir.x()); @@ -3268,7 +3266,7 @@ void CGAL::QGLViewer::drawArrow(double r,double R, int prec, CGAL::qglviewer::Ve data.push_back((float)color.y); data.push_back((float)color.z); //point C1 - D = (d+360/prec)*CGAL_PI/180.0; + D = float((d+360/prec)*CGAL_PI/180.0); p = QVector4D(Rf* sin(D), 0.66f, Rf* cos(D), 1.f); n = QVector4D(sin(D), sin(a), cos(D), 1.0); pR = mat*p; @@ -3292,7 +3290,7 @@ void CGAL::QGLViewer::drawArrow(double r,double R, int prec, CGAL::qglviewer::Ve for(int d = 0; d<360; d+= 360/prec) { //point A1 - double D = d*CGAL_PI/180.0; + float D = float(d*CGAL_PI/180.0); QVector4D p(rf*sin(D), 0.66f, rf*cos(D), 1.f); QVector4D n(sin(D), 0.f, cos(D), 1.f); QVector4D pR = mat*p; @@ -3304,9 +3302,9 @@ void CGAL::QGLViewer::drawArrow(double r,double R, int prec, CGAL::qglviewer::Ve data.push_back(nR.x()); data.push_back(nR.y()); data.push_back(nR.z()); - data.push_back(color.x); - data.push_back(color.y); - data.push_back(color.z); + data.push_back(float(color.x)); + data.push_back(float(color.y)); + data.push_back(float(color.z)); //point B1 p = QVector4D(rf * sin(D),0,rf*cos(D), 1.0); n = QVector4D(sin(D), 0, cos(D), 1.0); @@ -3320,11 +3318,11 @@ void CGAL::QGLViewer::drawArrow(double r,double R, int prec, CGAL::qglviewer::Ve data.push_back(nR.x()); data.push_back(nR.y()); data.push_back(nR.z()); - data.push_back(color.x); - data.push_back(color.y); - data.push_back(color.z); + data.push_back(float(color.x)); + data.push_back(float(color.y)); + data.push_back(float(color.z)); //point C1 - D = (d+360/prec)*CGAL_PI/180.0; + D = float((d+360/prec)*CGAL_PI/180.0); p = QVector4D(rf * sin(D),0,rf*cos(D), 1.0); n = QVector4D(sin(D), 0, cos(D), 1.0); pR = mat*p; @@ -3335,11 +3333,11 @@ void CGAL::QGLViewer::drawArrow(double r,double R, int prec, CGAL::qglviewer::Ve data.push_back(nR.x()); data.push_back(nR.y()); data.push_back(nR.z()); - data.push_back(color.x); - data.push_back(color.y); - data.push_back(color.z); + data.push_back(float(color.x)); + data.push_back(float(color.y)); + data.push_back(float(color.z)); //point A2 - D = (d+360/prec)*CGAL_PI/180.0; + D = float((d+360/prec)*CGAL_PI/180.0); p = QVector4D(rf * sin(D),0,rf*cos(D), 1.0); n = QVector4D(sin(D), 0, cos(D), 1.0); @@ -3351,9 +3349,9 @@ void CGAL::QGLViewer::drawArrow(double r,double R, int prec, CGAL::qglviewer::Ve data.push_back(nR.x()); data.push_back(nR.y()); data.push_back(nR.z()); - data.push_back((float)color.x); - data.push_back((float)color.y); - data.push_back((float)color.z); + data.push_back(float(color.x)); + data.push_back(float(color.y)); + data.push_back(float(color.z)); //point B2 p = QVector4D(rf * sin(D), 0.66f, rf*cos(D), 1.f); n = QVector4D(sin(D), 0, cos(D), 1.0); @@ -3365,11 +3363,11 @@ void CGAL::QGLViewer::drawArrow(double r,double R, int prec, CGAL::qglviewer::Ve data.push_back(nR.x()); data.push_back(nR.y()); data.push_back(nR.z()); - data.push_back((float)color.x); - data.push_back((float)color.y); - data.push_back((float)color.z); + data.push_back(float(color.x)); + data.push_back(float(color.y)); + data.push_back(float(color.z)); //point C2 - D = d*CGAL_PI/180.0; + D = float(d*CGAL_PI/180.0); p = QVector4D(rf * sin(D), 0.66f, rf*cos(D), 1.f); n = QVector4D(sin(D), 0.f, cos(D), 1.f); pR = mat*p; @@ -3380,9 +3378,9 @@ void CGAL::QGLViewer::drawArrow(double r,double R, int prec, CGAL::qglviewer::Ve data.push_back(nR.x()); data.push_back(nR.y()); data.push_back(nR.z()); - data.push_back(color.x); - data.push_back(color.y); - data.push_back(color.z); + data.push_back(float(color.x)); + data.push_back(float(color.y)); + data.push_back(float(color.z)); } } @@ -3403,7 +3401,7 @@ void CGAL::QGLViewer::drawAxis(qreal length) { rendering_program_light.bind(); vaos[AXIS].bind(); vbos[Axis].bind(); - vbos[Axis].allocate(data.data(), static_cast(data.size()) * sizeof(float)); + vbos[Axis].allocate(data.data(), static_cast(data.size() * sizeof(float))); rendering_program_light.enableAttributeArray("vertex"); rendering_program_light.setAttributeBuffer("vertex",GL_FLOAT,0,3, static_cast(9*sizeof(float))); @@ -3432,22 +3430,22 @@ void CGAL::QGLViewer::drawGrid(qreal size, int nbSubdivisions) { std::vector v_Grid; for (int i=0; i<=nbSubdivisions; ++i) { - const float pos = size*(2.0*i/nbSubdivisions-1.0); + const float pos = float(size*(2.0*i/nbSubdivisions-1.0)); v_Grid.push_back(pos); - v_Grid.push_back(-size); - v_Grid.push_back(0.0); + v_Grid.push_back(float(-size)); + v_Grid.push_back(0.f); v_Grid.push_back(pos); - v_Grid.push_back(+size); - v_Grid.push_back(0.0); + v_Grid.push_back(float(+size)); + v_Grid.push_back(0.f); - v_Grid.push_back(-size); + v_Grid.push_back(float(-size)); v_Grid.push_back(pos); - v_Grid.push_back(0.0); + v_Grid.push_back(0.f); - v_Grid.push_back( size); + v_Grid.push_back( float(size)); v_Grid.push_back( pos); - v_Grid.push_back( 0.0); + v_Grid.push_back( 0.f); } rendering_program.bind(); vaos[GRID].bind(); @@ -3471,7 +3469,7 @@ void CGAL::QGLViewer::drawGrid(qreal size, int nbSubdivisions) { rendering_program_light.bind(); vaos[GRID_AXIS].bind(); vbos[Grid_axis].bind(); - vbos[Grid_axis].allocate(d_axis.data(), static_cast(d_axis.size()) * sizeof(float)); + vbos[Grid_axis].allocate(d_axis.data(), static_cast(d_axis.size() * sizeof(float))); rendering_program_light.enableAttributeArray("vertex"); rendering_program_light.setAttributeBuffer("vertex",GL_FLOAT,0,3, static_cast(9*sizeof(float))); @@ -4013,7 +4011,10 @@ QImage* CGAL::QGLViewer::takeSnapshot( CGAL::qglviewer::SnapShotBackground back for (int j=0; j // RAND_MAX // All the methods are declared inline in Quaternion.h -using namespace CGAL::qglviewer; -using namespace std; +namespace CGAL{ +namespace qglviewer{ + /*! Constructs a Quaternion that will rotate from the \p from direction to the \p to direction. @@ -533,7 +530,7 @@ Quaternion Quaternion::squadTangent(const Quaternion &before, } CGAL_INLINE_FUNCTION -ostream &operator<<(ostream &o, const Quaternion &Q) { +std::ostream &operator<<(std::ostream &o, const Quaternion &Q) { return o << Q[0] << '\t' << Q[1] << '\t' << Q[2] << '\t' << Q[3]; } @@ -559,3 +556,4 @@ Quaternion Quaternion::randomQuaternion() { qreal t2 = 2.0 * CGAL_PI * (rand() / (qreal)RAND_MAX); return Quaternion(sin(t1) * r1, cos(t1) * r1, sin(t2) * r2, cos(t2) * r2); } +}} diff --git a/GraphicsView/include/CGAL/Qt/vec.h b/GraphicsView/include/CGAL/Qt/vec.h index 33aa7e919e9..0a6e2e2e95b 100644 --- a/GraphicsView/include/CGAL/Qt/vec.h +++ b/GraphicsView/include/CGAL/Qt/vec.h @@ -3,17 +3,13 @@ Copyright (c) 2018 GeometryFactory Sarl (France). Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. - This file is part of a fork of the CGAL::QGLViewer library version 2.7.0. - + This file is part of a fork of the QGLViewer library version 2.7.0. http://www.libqglviewer.com - contact@libqglviewer.com This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the LICENSE file included in the packaging of this file. - libCGAL::QGLViewer uses dual licensing. Commercial/proprietary software must - purchase a libCGAL::QGLViewer Commercial License. - This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. diff --git a/GraphicsView/include/CGAL/Qt/vec_impl.h b/GraphicsView/include/CGAL/Qt/vec_impl.h index 2c3bfa37b0f..340c6cbf62c 100644 --- a/GraphicsView/include/CGAL/Qt/vec_impl.h +++ b/GraphicsView/include/CGAL/Qt/vec_impl.h @@ -3,17 +3,13 @@ Copyright (c) 2018 GeometryFactory Sarl (France). Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. - This file is part of a fork of the CGAL::QGLViewer library version 2.7.0. - + This file is part of a fork of the QGLViewer library version 2.7.0. http://www.libqglviewer.com - contact@libqglviewer.com This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the LICENSE file included in the packaging of this file. - libCGAL::QGLViewer uses dual licensing. Commercial/proprietary software must - purchase a libCGAL::QGLViewer Commercial License. - This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. @@ -36,8 +32,9 @@ // Most of the methods are declared inline in vec.h -using namespace CGAL::qglviewer; -using namespace std; +namespace CGAL{ +namespace qglviewer{ + /*! Projects the Vec on the axis of direction \p direction that passes through the origin. @@ -178,6 +175,7 @@ void Vec::initFromDOMElement(const QDomElement &element) { } CGAL_INLINE_FUNCTION -ostream &operator<<(ostream &o, const Vec &v) { +std::ostream &operator<<(std::ostream &o, const Vec &v) { return o << v.x << '\t' << v.y << '\t' << v.z; } +}} diff --git a/GraphicsView/include/CGAL/Qt/viewer_actions.h b/GraphicsView/include/CGAL/Qt/viewer_actions.h index 413d4b60213..e07f2227796 100644 --- a/GraphicsView/include/CGAL/Qt/viewer_actions.h +++ b/GraphicsView/include/CGAL/Qt/viewer_actions.h @@ -3,17 +3,13 @@ Copyright (c) 2018 GeometryFactory Sarl (France). Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. - This file is part of a fork of the CGAL::QGLViewer library version 2.7.0. - + This file is part of a fork of the QGLViewer library version 2.7.0. http://www.libqglviewer.com - contact@libqglviewer.com This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the LICENSE file included in the packaging of this file. - libCGAL::QGLViewer uses dual licensing. Commercial/proprietary software must - purchase a libCGAL::QGLViewer Commercial License. - This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. diff --git a/Installation/CHANGES.md b/Installation/CHANGES.md index d1a7dc8f22d..8384b3cbe57 100644 --- a/Installation/CHANGES.md +++ b/Installation/CHANGES.md @@ -1,20 +1,34 @@ Release History =============== + Release 4.13 ------------ Release date: September 2018 -### Polygon Mesh Processing -- Added a function in Polygon Mesh Processing to perform an extrusion of an open polygon mesh: - - `CGAL::Polygon_mesh_processing::extrude_mesh()` +### Installation + +- The library CGAL_Qt5 now contains a fork of the version 2.7.0 of libQGLViewer. + The corresponding code is in the package GraphicsView. + The dependency for the external library libQGLViewer is therefore dropped for all demos. + +### General + + - A new function `CGAL::draw()` is added in the packages Polyhedral + Surface, Surface Mesh, Linear Cell Complex, 2D Triangulations, and 3D + Triangulations, enabling to draw the corresponding data structures. ### 2D and 3D Linear Geometry Kernel - An operator() that takes a Ray_3 has been added to the concept ConstructProjectedPoint 3. +### CGAL and Boost Property Maps + +- Addition of a read-write property map to convert on-the-fly geometric + object from Cartesian kernels + ### 2D Triangulations - Added a new type of intersection to deal with insertion of a constraints @@ -37,9 +51,47 @@ Release date: September 2018 in the code but did not appear in the concepts). ### Polygon Mesh Processing -- Added a function to apply a transformation to a mesh : +- Added a function to apply a transformation to a mesh: - `CGAL::Polygon_mesh_processing::transform()` +- Fix a bug in `isotropic_remeshing()` making constrained vertices missing in the output +- Guarantee that constrained vertices are kept in the mesh after calling `isotropic_remeshing()` + (and not only the points associated to constrained vertices as it was before). +- Added a function in Polygon Mesh Processing to perform an extrusion of an open polygon mesh: + - `CGAL::Polygon_mesh_processing::extrude_mesh()` + +### 3D Mesh Generation + +- **Breaking change:** The template parameters of the class template + `Labeled_mesh_domain_3` have been simplified. The three constructors of + that class template have been replaced by a new unique constructor + using Boost named parameters. Three new static template member + functions that act as named constructors have been added: + - `create_gray_image_mesh_domain()`, to create a domain from a 3D + gray image, + - `create_labeled_image_mesh_domain()`, to create a domain from a 3D + labeled image, and + - `create_implicit_mesh_domain()`, to create a domain from an + implicit function. + +- The class templates `Implicit_mesh_domain_3`, + `Gray_image_mesh_domain_3`, and `Labeled_image_mesh_domain_3` are now + deprecated. + +- **Breaking change:** The headers + `` and + ``, that were deprecated since + CGAL 4.5, are now removed. + +### CGAL and the Boost Graph Library (BGL) + +- Add helper function `CGAL::is_valid_polygon_mesh` that checks the + validity of a polygon mesh using BGL functions. + +- Improve the function `CGAL::Euler::collapse_edge` so that the target + vertex of the collapsed edge is always kept after the collapse. + + Release 4.12 ------------ @@ -214,9 +266,6 @@ Release date: April 2018 ### CGAL and the Boost Graph Library (BGL) -- Add helper function `CGAL::is_valid_polygon_mesh` that checks the - validity of a polygon mesh using BGL functions. - - Add helper function `CGAL::expand_face_selection_for_removal` that expands a face selection to avoid creating a non manifold mesh when removing the selected faces. diff --git a/Installation/CMakeLists.txt b/Installation/CMakeLists.txt index 728e16f2ec5..4a45bf89485 100644 --- a/Installation/CMakeLists.txt +++ b/Installation/CMakeLists.txt @@ -863,10 +863,8 @@ endif() if(NOT CGAL_HEADER_ONLY) create_CGALconfig_files() else() - if(NOT EXISTS "${CMAKE_BINARY_DIR}/CGALConfig.cmake") - configure_file("${CGAL_MODULES_DIR}/CGALConfig_binary_header_only.cmake.in" - "${CMAKE_BINARY_DIR}/CGALConfig.cmake" @ONLY) - endif() + configure_file("${CGAL_MODULES_DIR}/CGALConfig_binary_header_only.cmake.in" + "${CMAKE_BINARY_DIR}/CGALConfig.cmake" @ONLY) endif() #-------------------------------------------------------------------------------------------------- diff --git a/Installation/INSTALL.md b/Installation/INSTALL.md index 043e7643757..17abb7c05ab 100644 --- a/Installation/INSTALL.md +++ b/Installation/INSTALL.md @@ -63,9 +63,6 @@ CGAL packages, some are only needed for demos. - Qt5 (>= 5.3) http://qt-project.org/ - - libQGLViewer - http://www.libqglviewer.com/ - - Geomview http://www.geomview.org/ Not supported with Visual C++ diff --git a/Installation/cmake/modules/FindQGLViewer.cmake b/Installation/cmake/modules/FindQGLViewer.cmake deleted file mode 100644 index aadfa505689..00000000000 --- a/Installation/cmake/modules/FindQGLViewer.cmake +++ /dev/null @@ -1,81 +0,0 @@ -# - Try to find QGLViewer -# Once done this will define -# -# QGLVIEWER_FOUND - system has QGLViewer -# QGLVIEWER_INCLUDE_DIR - the QGLViewer include directory -# QGLVIEWER_LIBRARIES - Link these to use QGLViewer -# QGLVIEWER_DEFINITIONS - Compiler switches required for using QGLViewer -# -if(POLICY CMP0072) - # About the use of OpenGL - cmake_policy(SET CMP0072 NEW) -endif() -find_package(OpenGL QUIET) -find_package(Qt5 QUIET COMPONENTS OpenGL Xml) - -# first look in user defined locations -find_path(QGLVIEWER_INCLUDE_DIR - NAMES QGLViewer/qglviewer.h - NO_DEFAULT_PATH - PATHS ENV QGLVIEWERROOT - /usr/local/include - ) - -find_library(QGLVIEWER_LIBRARY_RELEASE - NAMES qglviewer-qt5 qglviewer QGLViewer-qt5 QGLViewer QGLViewer2-qt5 QGLViewer2 - NO_DEFAULT_PATH - PATHS ENV QGLVIEWERROOT - ENV LD_LIBRARY_PATH - ENV LIBRARY_PATH - /usr/local/lib - PATH_SUFFIXES QGLViewer QGLViewer/release - ) - -find_library(QGLVIEWER_LIBRARY_DEBUG - NAMES dqglviewer dQGLViewer-qt5 dQGLViewer dQGLViewer2-qt5 dQGLViewer2 QGLViewerd2-qt5 QGLViewerd2 - NO_DEFAULT_PATH - PATHS /usr/local/lib - ENV QGLVIEWERROOT - ENV LD_LIBRARY_PATH - ENV LIBRARY_PATH - PATH_SUFFIXES QGLViewer QGLViewer/debug - ) - -#now try the standard paths -if (NOT QGLVIEWER_INCLUDE_DIR OR NOT QGLVIEWER_LIBRARY_RELEASE OR NOT QGLVIEWER_LIBRARY_DEBUG) -find_path(QGLVIEWER_INCLUDE_DIR - NAMES QGLViewer/qglviewer.h) - -find_library(QGLVIEWER_LIBRARY_RELEASE - NAMES qglviewer-qt5 qglviewer QGLViewer-qt5 QGLViewer QGLViewer2-qt5 QGLViewer2) - -find_library(QGLVIEWER_LIBRARY_DEBUG - NAMES dqglviewer dQGLViewer-qt5 dQGLViewer dQGLViewer2-qt5 dQGLViewer2 QGLViewerd2-qt5 QGLViewerd2) - -endif() - -if(QGLVIEWER_LIBRARY_RELEASE) - if(QGLVIEWER_LIBRARY_DEBUG) - set(QGLVIEWER_LIBRARIES_ Qt5::Xml Qt5::OpenGL ${OPENGL_LIBRARIES} optimized ${QGLVIEWER_LIBRARY_RELEASE} debug ${QGLVIEWER_LIBRARY_DEBUG}) - else() - set(QGLVIEWER_LIBRARIES_ Qt5::Xml Qt5::OpenGL ${OPENGL_LIBRARIES} ${QGLVIEWER_LIBRARY_RELEASE}) - endif() - - set(QGLVIEWER_LIBRARIES ${QGLVIEWER_LIBRARIES_} CACHE FILEPATH "The QGLViewer library") - -endif() - -IF(QGLVIEWER_INCLUDE_DIR AND QGLVIEWER_LIBRARIES) - SET(QGLVIEWER_FOUND TRUE) -ENDIF(QGLVIEWER_INCLUDE_DIR AND QGLVIEWER_LIBRARIES) - -IF(QGLVIEWER_FOUND) - IF(NOT QGLViewer_FIND_QUIETLY) - MESSAGE(STATUS "Found QGLViewer: ${QGLVIEWER_LIBRARIES}") - ENDIF(NOT QGLViewer_FIND_QUIETLY) -ELSE(QGLVIEWER_FOUND) - IF(QGLViewer_FIND_REQUIRED) - MESSAGE(FATAL_ERROR "Could not find QGLViewer") - ENDIF(QGLViewer_FIND_REQUIRED) -ENDIF(QGLVIEWER_FOUND) - diff --git a/Installation/cmake/modules/UseCGAL.cmake b/Installation/cmake/modules/UseCGAL.cmake index a11c5470c87..5128023cc5d 100644 --- a/Installation/cmake/modules/UseCGAL.cmake +++ b/Installation/cmake/modules/UseCGAL.cmake @@ -26,20 +26,6 @@ if(NOT USE_CGAL_FILE_INCLUDED) include(${CMAKE_CURRENT_LIST_DIR}/CGAL_GeneratorSpecificSettings.cmake) include(${CMAKE_CURRENT_LIST_DIR}/CGAL_TweakFindBoost.cmake) - set(CGAL_INSTALLED_SCM_BRANCH_NAME ${CGAL_SCM_BRANCH_NAME}) - set(CGAL_SCM_BRANCH_NAME "") - - if( NOT "${CGAL_INSTALLED_SCM_BRANCH_NAME}" STREQUAL "" ) - include(${CMAKE_CURRENT_LIST_DIR}/CGAL_SCM.cmake) - CGAL_detect_git(${CMAKE_SOURCE_DIR}) - if ( NOT "${CGAL_SCM_BRANCH_NAME}" STREQUAL "" ) - message ( STATUS "Code taken from Git branch: ${CGAL_SCM_BRANCH_NAME}" ) - if ( NOT "${CGAL_SCM_BRANCH_NAME}" STREQUAL "${CGAL_INSTALLED_SCM_BRANCH_NAME}") - message (AUTHOR_WARNING "Branch '${CGAL_SCM_BRANCH_NAME}' does not match branch '${CGAL_INSTALLED_SCM_BRANCH_NAME}' from which CGAL has been installed. Please consider rebuilding CGAL from this branch.") - endif() - endif() - endif() - set( CGAL_LIBRARIES ) foreach ( component ${CGAL_REQUESTED_COMPONENTS} ) diff --git a/Installation/include/CGAL/Cartesian_converter_fwd.h b/Installation/include/CGAL/Cartesian_converter_fwd.h new file mode 100644 index 00000000000..2e265bc205c --- /dev/null +++ b/Installation/include/CGAL/Cartesian_converter_fwd.h @@ -0,0 +1,42 @@ +// Copyright (C) 2018 GeometryFactory Sarl +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0+ +// + +#ifndef CGAL_CARTESIAN_CONVERTER_FWD_H +#define CGAL_CARTESIAN_CONVERTER_FWD_H + +/// \file Cartesian_converter_fwd.h +/// Forward declarations of the `Cartesian_converter` class. + +#ifndef DOXYGEN_RUNNING +namespace CGAL { + +namespace internal { +template < typename K1, typename K2 > +struct Default_converter; +}//internal + +template < class K1, class K2, + class Converter = typename internal::Default_converter::Type > +class Cartesian_converter; + +} // CGAL +#endif + +#endif /* CGAL_CARTESIAN_CONVERTER_FWD_H */ + + diff --git a/Installation/include/CGAL/Kernel_traits_fwd.h b/Installation/include/CGAL/Kernel_traits_fwd.h new file mode 100644 index 00000000000..0f7359e7b72 --- /dev/null +++ b/Installation/include/CGAL/Kernel_traits_fwd.h @@ -0,0 +1,33 @@ +// Copyright (C) 2018 GeometryFactory Sarl +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0+ +// + +#ifndef CGAL_KERNEL_TRAITS_FWD_H +#define CGAL_KERNEL_TRAITS_FWD_H + +/// \file Kernel_traits_fwd.h +/// Forward declarations of the `Kernel_traits` class. + +#ifndef DOXYGEN_RUNNING +namespace CGAL { + +template struct Kernel_traits; + +} // CGAL +#endif + +#endif // CGAL_KERNEL_TRAITS_FWD_H diff --git a/Installation/include/CGAL/config.h b/Installation/include/CGAL/config.h index 70cb2a2281f..7c3cde37f53 100644 --- a/Installation/include/CGAL/config.h +++ b/Installation/include/CGAL/config.h @@ -107,6 +107,17 @@ # define BOOST_TT_HAS_POST_INCREMENT_HPP_INCLUDED #endif +// Macro used by Boost Parameter. Mesh_3 needs at least 12, before the +// Boost Parameter headers are included: +// defines the value to 8, if it is not yet defined. +// The CGAL BGL properties mechanism includes +// , that includes +// , and maybe other Boost libraries may use +// Boost Parameter as well. +// That is why that is important to define that macro as early as possible, +// in +#define BOOST_PARAMETER_MAX_ARITY 12 + // The following header file defines among other things BOOST_PREVENT_MACRO_SUBSTITUTION #include #include diff --git a/Kernel_23/doc/Kernel_23/CGAL/Bbox_2.h b/Kernel_23/doc/Kernel_23/CGAL/Bbox_2.h index 284cc4178fa..3f70437c5b5 100644 --- a/Kernel_23/doc/Kernel_23/CGAL/Bbox_2.h +++ b/Kernel_23/doc/Kernel_23/CGAL/Bbox_2.h @@ -95,6 +95,11 @@ updates `b` to be the bounding box of `b` and `c` and returns itself. */ Bbox_2& operator+=(const Bbox_2 &c); +/*! +dilates the bounding box by a specified number of ULP. +*/ +void dilate(int dist); + /// @} }; /* end Bbox_2 */ diff --git a/Kernel_23/doc/Kernel_23/CGAL/Bbox_3.h b/Kernel_23/doc/Kernel_23/CGAL/Bbox_3.h index 66d54449ae3..88d9f4dd426 100644 --- a/Kernel_23/doc/Kernel_23/CGAL/Bbox_3.h +++ b/Kernel_23/doc/Kernel_23/CGAL/Bbox_3.h @@ -109,6 +109,10 @@ updates `b` to be the bounding box of `b` and `c` and returns itself. */ Bbox_3& operator+=(const Bbox_3 &c); +/*! +dilates the bounding box by a specified number of ULP. +*/ +void dilate(int dist); /// @} }; /* end Bbox_3 */ diff --git a/Kernel_23/doc/Kernel_23/CGAL/Weighted_point_3.h b/Kernel_23/doc/Kernel_23/CGAL/Weighted_point_3.h index 299f8c6bbc8..cef4445a0a3 100644 --- a/Kernel_23/doc/Kernel_23/CGAL/Weighted_point_3.h +++ b/Kernel_23/doc/Kernel_23/CGAL/Weighted_point_3.h @@ -61,7 +61,7 @@ public: /*! introduces a weighted point with coordinates `x`, `y`, `z` and weight `0`. */ - Weighted_point_3(const Kernel::FT& x, const Kernel::FT& y, const Kernel::FT& Z); + Weighted_point_3(const Kernel::FT& x, const Kernel::FT& y, const Kernel::FT& z); /// @} diff --git a/Kernel_23/include/CGAL/Bbox_2.h b/Kernel_23/include/CGAL/Bbox_2.h index fbcdef4760f..02292f28d32 100644 --- a/Kernel_23/include/CGAL/Bbox_2.h +++ b/Kernel_23/include/CGAL/Bbox_2.h @@ -30,6 +30,7 @@ #include #include #include +#include namespace CGAL { @@ -76,6 +77,7 @@ public: inline Bbox_2 operator+(const Bbox_2 &b) const; inline Bbox_2& operator+=(const Bbox_2 &b); + inline void dilate(int dist); }; inline @@ -156,7 +158,17 @@ Bbox_2::operator+=(const Bbox_2& b) rep[3] = (std::max)(ymax(), b.ymax()); return *this; } - +inline +void +Bbox_2::dilate(int dist) +{ + using boost::math::float_advance; + float_advance(rep[0],-dist); + float_advance(rep[1],-dist); + float_advance(rep[2],dist); + float_advance(rep[3],dist); +} + inline bool do_overlap(const Bbox_2 &bb1, const Bbox_2 &bb2) diff --git a/Kernel_23/include/CGAL/Bbox_3.h b/Kernel_23/include/CGAL/Bbox_3.h index a0d2ee29ac5..c58538095ee 100644 --- a/Kernel_23/include/CGAL/Bbox_3.h +++ b/Kernel_23/include/CGAL/Bbox_3.h @@ -31,6 +31,7 @@ #include #include #include +#include namespace CGAL { @@ -78,6 +79,8 @@ public: Bbox_3 operator+(const Bbox_3& b) const; Bbox_3& operator+=(const Bbox_3& b); + + void dilate(int dist); }; inline @@ -176,6 +179,20 @@ Bbox_3::operator+=(const Bbox_3& b) return *this; } +inline +void +Bbox_3::dilate(int dist) +{ + using boost::math::float_advance; + float_advance(rep[0],-dist); + float_advance(rep[1],-dist); + float_advance(rep[2],-dist); + float_advance(rep[3],dist); + float_advance(rep[4],dist); + float_advance(rep[5],dist); +} + + inline bool do_overlap(const Bbox_3& bb1, const Bbox_3& bb2) diff --git a/Kernel_23/include/CGAL/Kernel_traits.h b/Kernel_23/include/CGAL/Kernel_traits.h index e52020fcb47..dc5d38257c0 100644 --- a/Kernel_23/include/CGAL/Kernel_traits.h +++ b/Kernel_23/include/CGAL/Kernel_traits.h @@ -26,6 +26,7 @@ #ifndef CGAL_KERNEL_TRAITS_H #define CGAL_KERNEL_TRAITS_H +#include #include #include diff --git a/Kernel_23/include/CGAL/internal/Projection_traits_3.h b/Kernel_23/include/CGAL/internal/Projection_traits_3.h index a66158b9301..67e2760cfe2 100644 --- a/Kernel_23/include/CGAL/internal/Projection_traits_3.h +++ b/Kernel_23/include/CGAL/internal/Projection_traits_3.h @@ -805,6 +805,7 @@ public: typedef typename Rp::Construct_scaled_vector_3 Construct_scaled_vector_2; typedef typename Rp::Construct_triangle_3 Construct_triangle_2; typedef typename Rp::Construct_line_3 Construct_line_2; + typedef typename Rp::Construct_bbox_3 Construct_bbox_2; struct Less_xy_2 { typedef bool result_type; @@ -989,6 +990,9 @@ public: Construct_line_2 construct_line_2_object() const {return Construct_line_2();} + Construct_bbox_2 construct_bbox_2_object() const + {return Construct_bbox_2();} + Compute_scalar_product_2 compute_scalar_product_2_object() const {return Compute_scalar_product_2();} diff --git a/Kernel_23/test/Kernel_23/include/CGAL/_test_2.h b/Kernel_23/test/Kernel_23/include/CGAL/_test_2.h index 6aad5a2786c..f9e69b8c284 100644 --- a/Kernel_23/test/Kernel_23/include/CGAL/_test_2.h +++ b/Kernel_23/test/Kernel_23/include/CGAL/_test_2.h @@ -51,7 +51,7 @@ template bool _test_2(const R& r) { - return + return _test_cls_vector_2(r) && _test_fct_vector_2(r) && _test_cls_point_2(r) diff --git a/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_weighted_point_2.h b/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_weighted_point_2.h index bbdc904fab7..f7d41190673 100644 --- a/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_weighted_point_2.h +++ b/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_weighted_point_2.h @@ -45,7 +45,7 @@ bool _test_cls_weighted_point_2(const R& ) RT n2( 50 ); RT n4( 5); FT iw = -1; - + int int_w = 1; CGAL::Point_2 p0(n1, n2, n4); // constructions @@ -57,6 +57,7 @@ bool _test_cls_weighted_point_2(const R& ) CGAL::Weighted_point_2 wp4(iwp); // with R::Weighted_point_2 CGAL::Weighted_point_2 wp5(wp3); // with CGAL::Weighted_point_2< R > CGAL::Weighted_point_2 wp6(n1, n2); // with coordinates + CGAL::Weighted_point_2 wp7(p0, int_w); use(wp0); use(wp4); use(wp5); // assignement @@ -65,12 +66,18 @@ bool _test_cls_weighted_point_2(const R& ) std::cout << "."; // accessors - CGAL::Point_2 p1 = wp2.point(); + CGAL::Point_2 p1; + p1 = wp1.point(); + + p1 = wp2.point(); assert(p1 == p0); + + p1 = wp3.point(); FT w = wp3.weight(); assert(w == iw); - + w = wp7.weight(); + // no need to test the other operations as they use Point_2 operations (which // are tested in _test_cls_point_2.h) diff --git a/Linear_cell_complex/benchmark/Linear_cell_complex_2/CMakeLists.txt b/Linear_cell_complex/benchmark/Linear_cell_complex_2/CMakeLists.txt index 3baf4250adc..6eae9b0b136 100644 --- a/Linear_cell_complex/benchmark/Linear_cell_complex_2/CMakeLists.txt +++ b/Linear_cell_complex/benchmark/Linear_cell_complex_2/CMakeLists.txt @@ -48,11 +48,11 @@ SET(QT_USE_QTSVG TRUE) SET(QT_USE_QTXML TRUE ) INCLUDE(${QT_USE_FILE}) ADD_DEFINITIONS(${QT_DEFINITIONS}) -SET (CGoGN_EXT_INCLUDES ${CGoGN_EXT_INCLUDES} ${QT_INCLUDE_DIR} ${QGLVIEWER_INCLUDE_DIR} ) -SET (CGoGN_EXT_LIBS ${CGoGN_EXT_LIBS} ${QT_LIBRARIES} ${QGLVIEWER_LIBRARIES} ) +SET (CGoGN_EXT_INCLUDES ${CGoGN_EXT_INCLUDES} ${QT_INCLUDE_DIR} ) +SET (CGoGN_EXT_LIBS ${CGoGN_EXT_LIBS} ${QT_LIBRARIES} ) add_executable(cgogn_performance_2 performance_2.h cgogn_performance_2.h cgogn_performance_2.cpp) -target_link_libraries(cgogn_performance_2 algo assimp container nl topology utils Zinri z ${QT_LIBRARIES} ${QGLVIEWER_LIBRARIES} ) +target_link_libraries(cgogn_performance_2 algo assimp container nl topology utils Zinri z ${QT_LIBRARIES} ) # Performance_2 add_executable(performance_2 @@ -68,6 +68,6 @@ add_executable(performance_2 target_link_libraries(performance_2 ${CGAL_LIBRARIES} surface_mesh - algo assimp container nl topology utils Zinri z ${QT_LIBRARIES} ${QGLVIEWER_LIBRARIES} + algo assimp container nl topology utils Zinri z ${QT_LIBRARIES} ${OPENMESH_LIBRARIES} ) diff --git a/Linear_cell_complex/benchmark/Linear_cell_complex_3/CMakeLists.txt b/Linear_cell_complex/benchmark/Linear_cell_complex_3/CMakeLists.txt index e1a2e344722..9faf17e58ac 100644 --- a/Linear_cell_complex/benchmark/Linear_cell_complex_3/CMakeLists.txt +++ b/Linear_cell_complex/benchmark/Linear_cell_complex_3/CMakeLists.txt @@ -37,11 +37,11 @@ add_definitions(-DINCLUDE_TEMPLATES) # Performance_3 add_executable(performance_3 performance_3.cpp) add_dependencies(performance_3 OpenVolumeMesh) -target_link_libraries(performance_3 OpenVolumeMesh boost_timer boost_system ${CGAL_LIBRARIES} algo assimp container nl topology utils Zinri z xml2 ${QT_LIBRARIES} ${QGLVIEWER_LIBRARIES} ${MAP_VIEWER_LIBRARIES}) +target_link_libraries(performance_3 OpenVolumeMesh boost_timer boost_system ${CGAL_LIBRARIES} algo assimp container nl topology utils Zinri z xml2 ${QT_LIBRARIES} ${MAP_VIEWER_LIBRARIES}) # CGoGN add_executable(cgogn_performance_3 performance_3.h cgogn_performance_3.h cgogn_performance_3.cpp) -target_link_libraries(cgogn_performance_3 algo assimp container nl topology utils Zinri z xml2 ${QT_LIBRARIES} ${QGLVIEWER_LIBRARIES} ) +target_link_libraries(cgogn_performance_3 algo assimp container nl topology utils Zinri z xml2 ${QT_LIBRARIES} ) # LCC_3 add_executable(lcc_performance_3 performance_3.h lcc_performance_3.h lcc_performance_3.cpp) diff --git a/Linear_cell_complex/demo/Linear_cell_complex/CMakeLists.txt b/Linear_cell_complex/demo/Linear_cell_complex/CMakeLists.txt index cf875857d47..d774c81cc65 100644 --- a/Linear_cell_complex/demo/Linear_cell_complex/CMakeLists.txt +++ b/Linear_cell_complex/demo/Linear_cell_complex/CMakeLists.txt @@ -58,7 +58,6 @@ qt5_wrap_ui(uis MainWindow.ui CreateMesh.ui CreateMenger.ui # qrc files (resources files, that contain icons, at least) qt5_add_resources (CGAL_Qt5_RESOURCE_FILES ./Linear_cell_complex_3.qrc) - add_executable(Linear_cell_complex_3_demo Linear_cell_complex_3_demo.cpp MainWindow.cpp Viewer.cpp Linear_cell_complex_3_subdivision.cpp diff --git a/Linear_cell_complex/demo/Linear_cell_complex/MainWindow.cpp b/Linear_cell_complex/demo/Linear_cell_complex/MainWindow.cpp index d1831d39149..a78780d3e78 100644 --- a/Linear_cell_complex/demo/Linear_cell_complex/MainWindow.cpp +++ b/Linear_cell_complex/demo/Linear_cell_complex/MainWindow.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include "import_moka.h" diff --git a/Linear_cell_complex/doc/Linear_cell_complex/CGAL/draw_linear_cell_complex.h b/Linear_cell_complex/doc/Linear_cell_complex/CGAL/draw_linear_cell_complex.h new file mode 100644 index 00000000000..7fd78b6695f --- /dev/null +++ b/Linear_cell_complex/doc/Linear_cell_complex/CGAL/draw_linear_cell_complex.h @@ -0,0 +1,15 @@ +namespace CGAL { + +/*! +\ingroup PkgDrawLinearCellComplex + +Open a new window and draw `alcc`, a model of the `LinearCellComplex` concept. The function is blocking, that is the program continues as soon as the user closes the window. This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time. +\tparam LCC a model of the `LinearCellComplex` concept. +\param alcc the linear cell complex to draw. + +*/ +template +void draw(const LCC& alcc); + +} /* namespace CGAL */ + diff --git a/Linear_cell_complex/doc/Linear_cell_complex/Linear_cell_complex.txt b/Linear_cell_complex/doc/Linear_cell_complex/Linear_cell_complex.txt index 0f00181c9a7..30e3be293e6 100644 --- a/Linear_cell_complex/doc/Linear_cell_complex/Linear_cell_complex.txt +++ b/Linear_cell_complex/doc/Linear_cell_complex/Linear_cell_complex.txt @@ -241,7 +241,7 @@ point: 1 0 0, color: 19 Before applying the sew operation, the eight vertices of the first cube are colored by `1`, and the eight vertices of the second cube by `19`. After the sew operation, there are eight vertices which are merged two by two, and due to the average functor, the color of the four resulting vertices is now 10. Then we insert a vertex in the center of the common 2-cell between the two cubes. The coordinates of this vertex are initialized with the barycenter of the 2-cell (-1,0.5,0.5), and its color is not initialized by the method, thus we set its color manually by using the result of \link LinearCellComplex::insert_barycenter_in_cell `insert_barycenter_in_cell<2>`\endlink which is a dart incident to the new vertex. -\subsection Linear_cell_complexAutomaticAttributesManagement Automatic attributes management +\subsection Linear_cell_complexAutomaticAttributesManagement Automatic Attribute Management \anchor ssecAttributesManagement The following example illustrates the use of the automatic attributes management for a linear cell complex. An off file is loaded into a 2D linear cell complex embedded in 3D. Then, a certain percentage of edges is removed from the linear cell complex. The same method is applied twice: the first time by using the automatic attributes management (which is the default behaviour) and the second time by calling first \link GenericMap::set_automatic_attributes_management `set_automatic_attributes_management(false)`\endlink to disable the automatic updating of attributes. @@ -250,6 +250,19 @@ We can observe that the second run is faster than the first one. Indeed, updatin \cgalExample{Linear_cell_complex/linear_cell_complex_3_attributes_management.cpp} +\subsection Linear_cell_complexDraw Draw a Linear Cell Complex +\anchor ssecDrawLCC + +A linear cell complex can be visualized by calling the `CGAL::draw()` function as shown in the following example. This function opens a new window showing the given linear cell complex. The function is blocking, that is the program continues as soon as the user closes the window. + +\cgalExample{Linear_cell_complex/draw_linear_cell_complex.cpp} + +This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time. + +\cgalFigureBegin{fig_draw_lcc,draw_lcc.png} +Result of the run of the draw_linear_cell_complex program. A window shows two 3D cubes and allows to navigate through the 3D scene. +\cgalFigureEnd + \section Linear_cell_complexDesign Design and Implementation History This package was developed by Guillaume Damiand, with the help of Andreas Fabri, Sébastien Loriot and Laurent Rineau. Monique Teillaud and Bernd Gärtner contributed to the manual. diff --git a/Linear_cell_complex/doc/Linear_cell_complex/PackageDescription.txt b/Linear_cell_complex/doc/Linear_cell_complex/PackageDescription.txt index 4d9a112c79a..8eb6f42e7dc 100644 --- a/Linear_cell_complex/doc/Linear_cell_complex/PackageDescription.txt +++ b/Linear_cell_complex/doc/Linear_cell_complex/PackageDescription.txt @@ -19,6 +19,14 @@ /// \defgroup PkgLinearCellComplexOperations Operations for Linear Cell Complex /// \ingroup PkgLinearCellComplex +/*! Draw. + \code + #include + \endcode +*/ +/// \defgroup PkgDrawLinearCellComplex Draw a Linear Cell Complex +/// \ingroup PkgLinearCellComplex + /*! \addtogroup PkgLinearCellComplex @@ -57,14 +65,17 @@ - `CGAL::Linear_cell_complex` ## Global Functions ## -### Constructions for Linear cell complex ### +### Constructions for Linear Cell Complex ### - `CGAL::import_from_plane_graph` - `CGAL::import_from_triangulation_3` - `CGAL::import_from_polyhedron_3` -### Operations for Linear cell complex ### +### Operations for Linear Cell Complex ### - `CGAL::compute_normal_of_cell_0` - `CGAL::compute_normal_of_cell_2` +### Draw a Linear cell complex ### +- `CGAL::draw` + */ diff --git a/Linear_cell_complex/doc/Linear_cell_complex/examples.txt b/Linear_cell_complex/doc/Linear_cell_complex/examples.txt index 081c08d5da3..f41e9b41af0 100644 --- a/Linear_cell_complex/doc/Linear_cell_complex/examples.txt +++ b/Linear_cell_complex/doc/Linear_cell_complex/examples.txt @@ -3,4 +3,5 @@ \example Linear_cell_complex/linear_cell_complex_3.cpp \example Linear_cell_complex/linear_cell_complex_4.cpp \example Linear_cell_complex/linear_cell_complex_3_attributes_management.cpp +\example Linear_cell_complex/draw_linear_cell_complex.cpp */ diff --git a/Linear_cell_complex/doc/Linear_cell_complex/fig/draw_lcc.png b/Linear_cell_complex/doc/Linear_cell_complex/fig/draw_lcc.png new file mode 100644 index 00000000000..5ae0ccbb570 Binary files /dev/null and b/Linear_cell_complex/doc/Linear_cell_complex/fig/draw_lcc.png differ diff --git a/Linear_cell_complex/examples/Linear_cell_complex/CMakeBasicViewerQt.inc b/Linear_cell_complex/examples/Linear_cell_complex/CMakeBasicViewerQt.inc deleted file mode 100644 index 5dd94c1e7f9..00000000000 --- a/Linear_cell_complex/examples/Linear_cell_complex/CMakeBasicViewerQt.inc +++ /dev/null @@ -1,33 +0,0 @@ -# This file must be included in your CMakeLists.txt to use the basic viewer -# You need to link the libraries in your executable by using -# TARGET_LINK_LIBRARIES( myexec ${BASIC_VIEWER_LIBRARIES}) - -if ( NOT CGAL_FOUND OR NOT CGAL_Qt5_FOUND) - message(STATUS "NOTICE: Libraries for basic viewer not found " - "(CGAL, Qt5, QGLViewer).") -endif( NOT CGAL_FOUND OR NOT CGAL_Qt5_FOUND) - -include( ${CGAL_USE_FILE} ) -set(CMAKE_INCLUDE_CURRENT_DIR ON) - -FIND_PACKAGE(Qt5 REQUIRED COMPONENTS OpenGL Xml) -find_package(QGLViewer REQUIRED) -find_package(OpenGL REQUIRED) - -add_definitions(${QT_DEFINITIONS}) -add_definitions(-DQT_NO_KEYWORDS) - -include_directories( ${QGLVIEWER_INCLUDE_DIR} ) -add_definitions(${QGLVIEWER_DEFINITIONS}) - -set (BASIC_VIEWER_LIBRARIES ${QT_LIBRARIES} ${QGLVIEWER_LIBRARIES} - ${OPENGL_gl_LIBRARY}) # ${OPENGL_glu_LIBRARY} - -set(BASIC_VIEWER_MODULES Xml OpenGL) - -ADD_DEFINITIONS("-DCGAL_USE_BASIC_VIEWER") -message(STATUS "Libraries for lcc_viewer found. You need to link them " - "in your executable by using " - "TARGET_LINK_LIBRARIES( myexec \${BASIC_VIEWER_LIBRARIES})") - -set(USE_BASIC_VIEWER true) diff --git a/Linear_cell_complex/examples/Linear_cell_complex/CMakeLists.txt b/Linear_cell_complex/examples/Linear_cell_complex/CMakeLists.txt index 0d26a50dbff..9c0372c277d 100644 --- a/Linear_cell_complex/examples/Linear_cell_complex/CMakeLists.txt +++ b/Linear_cell_complex/examples/Linear_cell_complex/CMakeLists.txt @@ -9,14 +9,11 @@ if(NOT POLICY CMP0070 AND POLICY CMP0053) cmake_policy(SET CMP0053 OLD) endif() -# If you want to visualize a linear cell complex, you can use the following viewer -# based on qt. Just uncomment the following two lines, plus the lines qt5_use_modules below +find_package(CGAL COMPONENTS Qt5) -# find_package(CGAL COMPONENTS Qt5) -# include("CMakeBasicViewerQt.inc") - -# If you don't want to visualize, use the following line (otherwise comment it) -find_package(CGAL QUIET) +if(CGAL_Qt5_FOUND) + add_definitions(-DCGAL_USE_BASIC_VIEWER -DQT_NO_KEYWORDS) +endif() # For Gprof. # ADD_DEFINITIONS("-pg") @@ -25,50 +22,31 @@ find_package(CGAL QUIET) # To use valgrind, we must disable rounding math ckeck. # add_definition(-DCGAL_DISABLE_ROUNDING_MATH_CHECK) -if ( CGAL_FOUND ) +if (CGAL_FOUND) include( ${CGAL_USE_FILE} ) - include( CGAL_CreateSingleSourceCGALProgram ) + include(CGAL_CreateSingleSourceCGALProgram) include_directories(BEFORE ../../include) - create_single_source_cgal_program( "linear_cell_complex_3.cpp" ) - create_single_source_cgal_program( "linear_cell_complex_4.cpp" ) - create_single_source_cgal_program( - "linear_cell_complex_3_with_colored_vertices.cpp" ) - create_single_source_cgal_program( - "linear_cell_complex_3_with_mypoint.cpp" ) - - create_single_source_cgal_program("plane_graph_to_lcc_2.cpp") + create_single_source_cgal_program("gmap_linear_cell_complex_3.cpp") + create_single_source_cgal_program("linear_cell_complex_3.cpp") create_single_source_cgal_program("linear_cell_complex_3_attributes_management.cpp") + create_single_source_cgal_program("linear_cell_complex_3_operations.cpp") + create_single_source_cgal_program("linear_cell_complex_3_with_colored_vertices.cpp") + create_single_source_cgal_program("linear_cell_complex_3_with_mypoint.cpp") + create_single_source_cgal_program("linear_cell_complex_4.cpp") + create_single_source_cgal_program("plane_graph_to_lcc_2.cpp") + create_single_source_cgal_program("voronoi_2.cpp") + create_single_source_cgal_program("voronoi_3.cpp") - add_executable(voronoi_2 voronoi_2.cpp) - target_link_libraries(voronoi_2 ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES} - ${BASIC_VIEWER_LIBRARIES}) - if (USE_BASIC_VIEWER) - qt5_use_modules(voronoi_2 ${BASIC_VIEWER_MODULES}) - endif(USE_BASIC_VIEWER) + create_single_source_cgal_program("draw_linear_cell_complex.cpp") + if(CGAL_Qt5_FOUND) + target_link_libraries(draw_linear_cell_complex PUBLIC CGAL::CGAL_Qt5) + endif() - add_executable(voronoi_3 voronoi_3.cpp) - target_link_libraries(voronoi_3 ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES} - ${BASIC_VIEWER_LIBRARIES}) - - if (USE_BASIC_VIEWER) - qt5_use_modules(voronoi_3 ${BASIC_VIEWER_MODULES}) - endif(USE_BASIC_VIEWER) - - create_single_source_cgal_program( "gmap_linear_cell_complex_3.cpp" ) - - add_executable(linear_cell_complex_3_operations linear_cell_complex_3_operations.cpp) - target_link_libraries(linear_cell_complex_3_operations ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES} - ${BASIC_VIEWER_LIBRARIES}) - if (USE_BASIC_VIEWER) - qt5_use_modules(linear_cell_complex_3_operations ${BASIC_VIEWER_MODULES}) - endif(USE_BASIC_VIEWER) - else() - message(STATUS "This program requires the CGAL library, " - "and will not be compiled.") + message(STATUS "This program requires the CGAL library, and will not be compiled.") endif() diff --git a/Linear_cell_complex/examples/Linear_cell_complex/draw_linear_cell_complex.cpp b/Linear_cell_complex/examples/Linear_cell_complex/draw_linear_cell_complex.cpp new file mode 100644 index 00000000000..7888bba129d --- /dev/null +++ b/Linear_cell_complex/examples/Linear_cell_complex/draw_linear_cell_complex.cpp @@ -0,0 +1,29 @@ +#include +#include + +typedef CGAL::Linear_cell_complex_for_combinatorial_map<3> LCC; +typedef LCC::Dart_handle Dart_handle; +typedef LCC::Point Point; + +int main() +{ + LCC lcc; + Dart_handle dh1= + lcc.make_hexahedron(Point(0,0,0), Point(5,0,0), + Point(5,5,0), Point(0,5,0), + Point(0,5,4), Point(0,0,4), + Point(5,0,4), Point(5,5,4)); + Dart_handle dh2= + lcc.make_hexahedron(Point(5,0,0), Point(10,0,0), + Point(10,5,0), Point(5,5,0), + Point(5,5,4), Point(5,0,4), + Point(10,0,4), Point(10,5,4)); + + lcc.sew<3>(lcc.beta(dh1, 1, 1, 2), lcc.beta(dh2, 2)); + + lcc.display_characteristics(std::cout)<<", valid=" + < #include -/* If you want to use a viewer, you can use qglviewer. */ -#ifdef CGAL_USE_BASIC_VIEWER -#include "linear_cell_complex_3_viewer_qt.h" -#endif - typedef CGAL::Linear_cell_complex_for_combinatorial_map<3> LCC_3_cmap; typedef CGAL::Linear_cell_complex_for_generalized_map<3> LCC_3_gmap; @@ -54,10 +49,6 @@ void run_test() lcc.template sew<3>(lcc.template opposite<2>(lcc.next(dh1)), lcc.other_orientation(lcc.template opposite<2>(lcc.previous(dh3)))); -#ifdef CGAL_USE_BASIC_VIEWER - display_lcc(lcc); -#endif // CGAL_USE_BASIC_VIEWER - lcc.insert_cell_1_in_cell_2(lcc.next(dh1), Alpha1::run(lcc, lcc.previous(dh1))); dh2=lcc.template opposite<2>(lcc.next(lcc.next @@ -73,14 +64,9 @@ void run_test() lcc.insert_cell_2_in_cell_3(path.begin(),path.end()); lcc.display_characteristics(std::cout) << ", valid=" - << lcc.is_valid() << std::endl; - -#ifdef CGAL_USE_BASIC_VIEWER - display_lcc(lcc); -#endif // CGAL_USE_BASIC_VIEWER + << lcc.is_valid() << std::endl; } - int main() { run_test(); diff --git a/Linear_cell_complex/examples/Linear_cell_complex/linear_cell_complex_3_viewer_qt.h b/Linear_cell_complex/examples/Linear_cell_complex/linear_cell_complex_3_viewer_qt.h deleted file mode 100644 index 4e6d5e37077..00000000000 --- a/Linear_cell_complex/examples/Linear_cell_complex/linear_cell_complex_3_viewer_qt.h +++ /dev/null @@ -1,242 +0,0 @@ -// Copyright (c) 2011 CNRS and LIRIS' Establishments (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org); you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public License as -// published by the Free Software Foundation; either version 3 of the License, -// or (at your option) any later version. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: LGPL-3.0+ -// -// Author(s) : Guillaume Damiand - -#ifndef CGAL_LCC_3_VIEWER_QT_H -#define CGAL_LCC_3_VIEWER_QT_H - -#include "basic_viewer.h" -#include -#include -#include - -typedef CGAL::Exact_predicates_inexact_constructions_kernel Local_kernel; -typedef Local_kernel::Point_3 Local_point; -typedef Local_kernel::Vector_3 Local_vector; - -// Default color functor; user can change it to have its own face color -struct DefaultColorFunctor -{ - template - static CGAL::Color run(const LCC& alcc, - typename LCC::Dart_const_handle dh) - { - if (dh==alcc.null_handle) // use to get the mono color - return CGAL::Color(100, 125, 200); // R G B between 0-255 - - // Here dh is the smaller dart of its face - CGAL::Random random(alcc.darts().index(dh)); - CGAL::Color res; - do - { - res=CGAL::Color(random.get_int(0,256), - random.get_int(0,256), - random.get_int(0,256)); - } - while(res.red()==255 && res.green()==255 && res.blue()==255); - return res; - } -}; - -template -struct Geom_utils; - -template -struct Geom_utils -{ - Local_point get_point(const LCC& lcc, - typename LCC::Vertex_attribute_const_handle vh) - { return converter(lcc.point_of_vertex_attribute(vh)); } - - Local_point get_point(const LCC& lcc, typename LCC::Dart_const_handle dh) - { return converter(lcc.point(dh)); } - - Local_vector get_vertex_normal(const LCC& lcc, - typename LCC::Dart_const_handle dh) - { - Local_vector n = converter(CGAL::compute_normal_of_cell_0(lcc,dh)); - n = n/(CGAL::sqrt(n*n)); - return n; - } -protected: - CGAL::Cartesian_converter converter; -}; - -template -struct Geom_utils -{ - Local_point get_point(const LCC& lcc, - typename LCC::Vertex_attribute_const_handle vh) - { - Local_point p(converter(lcc.point_of_vertex_attribute(vh).x()),0, - converter(lcc.point_of_vertex_attribute(vh).y())); - return p; - } - - Local_point get_point(const LCC& lcc, typename LCC::Dart_const_handle dh) - { return get_point(lcc, lcc.vertex_attribute(dh)); } - - Local_vector get_vertex_normal(const LCC&, typename LCC::Dart_const_handle) - { - Local_vector n(0,-1,0); - return n; - } -protected: - CGAL::Cartesian_converter converter; -}; - -// Viewer class for LCC -template -class SimpleLCCViewerQt : public Basic_viewer -{ - typedef Basic_viewer Base; - typedef typename LCC::Dart_const_handle Dart_const_handle; - -public: - /// Construct the viewer. - /// @param alcc the lcc to view - /// @param title the title of the window - /// @param anofaces if true, do not draw faces (faces are not computed; this can be - /// usefull for very big LCC where this time could be long) - SimpleLCCViewerQt(const LCC& alcc, const char* title="", bool anofaces=false) : - Base(title), - lcc(alcc), - m_nofaces(anofaces) - { - compute_elements(); - } - -protected: - - void compute_face(Dart_const_handle dh) - { - // We fill only closed faces. - Dart_const_handle cur=dh; - Dart_const_handle min=dh; - do - { - if (!lcc.is_next_exist(cur)) return; // open face=>not filled - if (cur(lcc, it, markfaces); - } - - if ( !lcc.is_marked(it, markedges) ) - { - compute_edge(it); - CGAL::mark_cell(lcc, it, markedges); - } - - if ( !lcc.is_marked(it, markvertices) ) - { - compute_vertex(it, empty); - CGAL::mark_cell(lcc, it, markvertices); - } - } - - lcc.free_mark(markfaces); - lcc.free_mark(markedges); - lcc.free_mark(markvertices); - } - - virtual void keyPressEvent(QKeyEvent *e) - { - const Qt::KeyboardModifiers modifiers = e->modifiers(); - Base::keyPressEvent(e); - } - -protected: - const LCC& lcc; - bool m_nofaces; - Geom_utils geomutils; -}; - - -template -void display_lcc(const LCC& alcc, - const char* title="", - bool nofill=false) -{ - int argc=1; - - const char* argv[2]={"lccviewer","\0"}; - QApplication app(argc,const_cast(argv)); - - SimpleLCCViewerQt mainwindow(alcc, title, nofill); - mainwindow.show(); - - app.exec(); -} - -#endif // CGAL_LCC_3_VIEWER_QT_H diff --git a/Linear_cell_complex/examples/Linear_cell_complex/voronoi_2.cpp b/Linear_cell_complex/examples/Linear_cell_complex/voronoi_2.cpp index 43ac93a3327..64fe08e3b42 100644 --- a/Linear_cell_complex/examples/Linear_cell_complex/voronoi_2.cpp +++ b/Linear_cell_complex/examples/Linear_cell_complex/voronoi_2.cpp @@ -6,10 +6,6 @@ #include #include -/* If you want to use a viewer, you can use qglviewer. */ -#ifdef CGAL_USE_BASIC_VIEWER -#include "linear_cell_complex_3_viewer_qt.h" -#endif // This example works both with cmap and gmap as combinatorial data structure. //typedef CGAL::Linear_cell_complex_for_combinatorial_map<2> LCC_2; @@ -56,10 +52,6 @@ void display_voronoi(LCC_2& alcc, Dart_handle adart) alcc.display_characteristics(std::cout) << ", valid=" << alcc.is_valid() << std::endl; - -#ifdef CGAL_USE_BASIC_VIEWER - display_lcc(alcc); -#endif // CGAL_USE_BASIC_VIEWER } template diff --git a/Linear_cell_complex/examples/Linear_cell_complex/voronoi_3.cpp b/Linear_cell_complex/examples/Linear_cell_complex/voronoi_3.cpp index 28bf93b0f12..30f94107b00 100644 --- a/Linear_cell_complex/examples/Linear_cell_complex/voronoi_3.cpp +++ b/Linear_cell_complex/examples/Linear_cell_complex/voronoi_3.cpp @@ -5,11 +5,6 @@ #include #include -/* If you want to use a viewer, you can use one qglviewer. */ -#ifdef CGAL_USE_BASIC_VIEWER -#include "linear_cell_complex_3_viewer_qt.h" -#endif - /* // If you want to use exact constructions. #include typedef CGAL::Linear_cell_complex<3,3, @@ -59,10 +54,6 @@ void display_voronoi(LCC_3& alcc, Dart_handle adart) alcc.display_characteristics(std::cout) << ", valid=" << alcc.is_valid() << std::endl; - -#ifdef CGAL_USE_BASIC_VIEWER - display_lcc(alcc); -#endif // CGAL_USE_BASIC_VIEWER } template diff --git a/Linear_cell_complex/include/CGAL/draw_linear_cell_complex.h b/Linear_cell_complex/include/CGAL/draw_linear_cell_complex.h new file mode 100644 index 00000000000..e792b745282 --- /dev/null +++ b/Linear_cell_complex/include/CGAL/draw_linear_cell_complex.h @@ -0,0 +1,247 @@ +// Copyright (c) 2018 CNRS and LIRIS' Establishments (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0+ +// +// Author(s) : Guillaume Damiand + +#ifndef CGAL_DRAW_LCC_H +#define CGAL_DRAW_LCC_H + +#include + +#ifdef CGAL_USE_BASIC_VIEWER + +#include + +namespace CGAL +{ + +// Default color functor; user can change it to have its own face color +struct DefaultColorFunctorLCC +{ + template + static CGAL::Color run(const LCC& alcc, + typename LCC::Dart_const_handle dh) + { + if (dh==alcc.null_handle) // use to get the mono color + return CGAL::Color(100, 125, 200); // R G B between 0-255 + + CGAL::Random random((unsigned int)(alcc.darts().index(dh))); + return get_random_color(random); + } +}; + +template +struct Geom_utils; + +template +struct Geom_utils +{ + static typename LCC::Vector get_vertex_normal(const LCC& lcc, + typename LCC::Dart_const_handle dh) + { + typename LCC::Vector n = CGAL::compute_normal_of_cell_0(lcc,dh); + n = n/(CGAL::sqrt(n*n)); + return n; + } +}; + +template +struct Geom_utils +{ + static typename LCC::Vector get_vertex_normal(const LCC&, + typename LCC::Dart_const_handle) + { + typename LCC::Vector res=CGAL::NULL_VECTOR; + return res; + } +}; + +// Viewer class for LCC +template +class SimpleLCCViewerQt : public Basic_viewer_qt +{ + typedef Basic_viewer_qt Base; + typedef typename LCC::Dart_const_handle Dart_const_handle; + typedef typename LCC::Traits Kernel; + typedef typename Kernel::Point Point; + typedef typename Kernel::Vector Vector; + +public: + /// Construct the viewer. + /// @param alcc the lcc to view + /// @param title the title of the window + /// @param anofaces if true, do not draw faces (faces are not computed; this can be + /// usefull for very big object where this time could be long) + SimpleLCCViewerQt(QWidget* parent, + const LCC& alcc, + const char* title="Basic LCC Viewer", + bool anofaces=false, + const ColorFunctor& fcolor=ColorFunctor()) : + // First draw: vertices; edges, faces; multi-color; inverse normal + Base(parent, title, true, true, true, false, true), + lcc(alcc), + m_nofaces(anofaces), + m_fcolor(fcolor) + { + compute_elements(); + } + +protected: + void compute_face(Dart_const_handle dh) + { + // We fill only closed faces. + Dart_const_handle cur=dh; + Dart_const_handle min=dh; + do + { + if (!lcc.is_next_exist(cur)) return; // open face=>not filled + if (cur::get_vertex_normal(lcc, cur)); + cur=lcc.next(cur); + } + while(cur!=dh); + + face_end(); + } + + void compute_edge(Dart_const_handle dh) + { + Point p1 = lcc.point(dh); + Dart_const_handle d2 = lcc.other_extremity(dh); + if (d2!=NULL) + { add_segment(p1, lcc.point(d2)); } + } + + void compute_vertex(Dart_const_handle dh) + { add_point(lcc.point(dh)); } + + void compute_elements() + { + clear(); + + typename LCC::size_type markfaces = lcc.get_new_mark(); + typename LCC::size_type markedges = lcc.get_new_mark(); + typename LCC::size_type markvertices = lcc.get_new_mark(); + + for (typename LCC::Dart_range::const_iterator it=lcc.darts().begin(), + itend=lcc.darts().end(); it!=itend; ++it ) + { + if ( !m_nofaces && !lcc.is_marked(it, markfaces) ) + { + compute_face(it); + CGAL::mark_cell(lcc, it, markfaces); + } + + if ( !lcc.is_marked(it, markedges) ) + { + compute_edge(it); + CGAL::mark_cell(lcc, it, markedges); + } + + if ( !lcc.is_marked(it, markvertices) ) + { + compute_vertex(it); + CGAL::mark_cell(lcc, it, markvertices); + } + } + + lcc.free_mark(markfaces); + lcc.free_mark(markedges); + lcc.free_mark(markvertices); + } + + virtual void keyPressEvent(QKeyEvent *e) + { + // Test key pressed: + // const ::Qt::KeyboardModifiers modifiers = e->modifiers(); + // if ((e->key()==Qt::Key_PageUp) && (modifiers==Qt::NoButton)) { ... } + + // Call: * compute_elements() if the model changed, followed by + // * redraw() if some viewing parameters changed that implies some + // modifications of the buffers + // (eg. type of normal, color/mono) + // * update() just to update the drawing + + // Call the base method to process others/classicals key + Base::keyPressEvent(e); + } + +protected: + const LCC& lcc; + bool m_nofaces; + const ColorFunctor& m_fcolor; +}; + +template +void draw(const LCC& alcc, + const char* title, + bool nofill, + const ColorFunctor& fcolor) +{ +#if defined(CGAL_TEST_SUITE) + bool cgal_test_suite=true; +#else + bool cgal_test_suite=false; +#endif + + if (!cgal_test_suite) + { + int argc=1; + const char* argv[2]={"lccviewer","\0"}; + QApplication app(argc,const_cast(argv)); + SimpleLCCViewerQt mainwindow(app.activeWindow(), + alcc, + title, + nofill, + fcolor); + mainwindow.show(); + app.exec(); + } +} + +template +void draw(const LCC& alcc, const char* title, bool nofill) +{ + DefaultColorFunctorLCC c; + draw(alcc, title, nofill, c); +} + +template +void draw(const LCC& alcc, const char* title) +{ draw(alcc, title, false); } + +template +void draw(const LCC& alcc) +{ draw(alcc, "Basic LCC Viewer"); } + +} // End namespace CGAL + +#endif // CGAL_USE_BASIC_VIEWER + +#endif // CGAL_DRAW_LCC_H diff --git a/Linear_cell_complex/package_info/Linear_cell_complex/dependencies b/Linear_cell_complex/package_info/Linear_cell_complex/dependencies index d3c90923a14..4a46d8312a8 100644 --- a/Linear_cell_complex/package_info/Linear_cell_complex/dependencies +++ b/Linear_cell_complex/package_info/Linear_cell_complex/dependencies @@ -8,6 +8,7 @@ Distance_2 Distance_3 Filtered_kernel Generalized_map +GraphicsView HalfedgeDS Hash_map Homogeneous_kernel diff --git a/Mesh_2/include/CGAL/lloyd_optimize_mesh_2.h b/Mesh_2/include/CGAL/lloyd_optimize_mesh_2.h index ee2f6e42d48..a5563bffc87 100644 --- a/Mesh_2/include/CGAL/lloyd_optimize_mesh_2.h +++ b/Mesh_2/include/CGAL/lloyd_optimize_mesh_2.h @@ -32,6 +32,7 @@ #include #include #include +#include #include diff --git a/Mesh_3/doc/Mesh_3/CGAL/Gray_image_mesh_domain_3.h b/Mesh_3/doc/Mesh_3/CGAL/Gray_image_mesh_domain_3.h index ea5e789f463..34808a821d2 100644 --- a/Mesh_3/doc/Mesh_3/CGAL/Gray_image_mesh_domain_3.h +++ b/Mesh_3/doc/Mesh_3/CGAL/Gray_image_mesh_domain_3.h @@ -3,6 +3,11 @@ namespace CGAL { /*! \ingroup PkgMesh_3Domains +\deprecated The class template `Gray_image_mesh_domain_3` is deprecated +since CGAL-4.13, in favor of the class template `Labeled_mesh_domain_3` and +its static function +`Labeled_mesh_domain_3::create_gray_image_mesh_domain()`. + The class `Gray_image_mesh_domain_3` implements a domain described by a 3D gray image. A 3D gray image is a grid of voxels, where each voxel is associated with a gray level value. @@ -24,8 +29,7 @@ length of the diagonal of the bounding box (in world coordinates) and \tparam Image is the type of the input image. -This parameter must be a model of the concept -`LabeledImage_3`. +This parameter must be `CGAL::Image_3`. \tparam BGT is a geometric traits class which provides the basic operations to implement diff --git a/Mesh_3/doc/Mesh_3/CGAL/Image_3.h b/Mesh_3/doc/Mesh_3/CGAL/Image_3.h new file mode 100644 index 00000000000..b973c7d2632 --- /dev/null +++ b/Mesh_3/doc/Mesh_3/CGAL/Image_3.h @@ -0,0 +1,23 @@ +namespace CGAL { + +/*! +\ingroup PkgMesh_3Domains + +The class `Image_3` is a C++ wrapper around the InrImage library. It holds a +shared pointer to a 3D image buffer. + +*/ +class Image_3 { +public: + + /// The default-constructor. The object is invalid until a call to `read()`. + Image_3(); + + /// Open an 3D image file. + /// + /// Returns `true` if the file was sucessfully loaded. + bool read(const char* file); + +}; +} /* end namespace CGAL */ diff --git a/Mesh_3/doc/Mesh_3/CGAL/Implicit_mesh_domain_3.h b/Mesh_3/doc/Mesh_3/CGAL/Implicit_mesh_domain_3.h index 500dd2736e3..d0cf46482b9 100644 --- a/Mesh_3/doc/Mesh_3/CGAL/Implicit_mesh_domain_3.h +++ b/Mesh_3/doc/Mesh_3/CGAL/Implicit_mesh_domain_3.h @@ -3,6 +3,11 @@ namespace CGAL { /*! \ingroup PkgMesh_3Domains +\deprecated The class template `Implicit_mesh_domain_3` is deprecated +since CGAL-4.13, in favor of the class template `Labeled_mesh_domain_3` and +its static function +`Labeled_mesh_domain_3::create_implicit_mesh_domain()`. + The class `Implicit_mesh_domain_3` implements a domain whose bounding surface is described implicitly as the zero level set of a function. diff --git a/Mesh_3/doc/Mesh_3/CGAL/Implicit_to_labeling_function_wrapper.h b/Mesh_3/doc/Mesh_3/CGAL/Implicit_to_labeling_function_wrapper.h index 728883d04e2..f43c2f3a857 100644 --- a/Mesh_3/doc/Mesh_3/CGAL/Implicit_to_labeling_function_wrapper.h +++ b/Mesh_3/doc/Mesh_3/CGAL/Implicit_to_labeling_function_wrapper.h @@ -18,7 +18,7 @@ The second one matches the locus of points satisfying f1(p)>0 and f2(p)<0 and f3 This parameter stands for a model of the concept ImplicitFunction described in the surface mesh generation package. The number types Function::FT and BGT::FT are required to match. -\sa `Implicit_mesh_domain_3`. +\sa `Labeled_mesh_domain_3`. */ template diff --git a/Mesh_3/doc/Mesh_3/CGAL/Labeled_image_mesh_domain_3.h b/Mesh_3/doc/Mesh_3/CGAL/Labeled_image_mesh_domain_3.h index 960db2cbf8c..fddfbf0dfe6 100644 --- a/Mesh_3/doc/Mesh_3/CGAL/Labeled_image_mesh_domain_3.h +++ b/Mesh_3/doc/Mesh_3/CGAL/Labeled_image_mesh_domain_3.h @@ -3,6 +3,11 @@ namespace CGAL { /*! \ingroup PkgMesh_3Domains +\deprecated The class template `Labeled_image_mesh_domain_3` is deprecated +since CGAL-4.13, in favor of the class template `Labeled_mesh_domain_3` and +its static function +`Labeled_mesh_domain_3::create_labeled_image_mesh_domain()`. + The class `Labeled_image_mesh_domain_3` implements a domain described by a 3D labeled image. A 3D labeled image is a grid of voxels, where each voxel is associated with an index (a subdomain index) characterizing the subdomain in which the voxel lies. This @@ -21,8 +26,7 @@ length of the diagonal of the bounding box (in world coordinates) and \tparam Image is the type of the input image. -This parameter must be a model of the concept -`LabeledImage_3`. +This parameter must be `CGAL::Image_3`. \tparam BGT is a geometric traits class which provides the basic operations to implement diff --git a/Mesh_3/doc/Mesh_3/CGAL/Labeled_mesh_domain_3.h b/Mesh_3/doc/Mesh_3/CGAL/Labeled_mesh_domain_3.h index 8755edeeb8c..2e76323ba42 100644 --- a/Mesh_3/doc/Mesh_3/CGAL/Labeled_mesh_domain_3.h +++ b/Mesh_3/doc/Mesh_3/CGAL/Labeled_mesh_domain_3.h @@ -11,7 +11,7 @@ Any boundary facet is labeled , a, where b!=0. -This class includes a function that provides, the subdomain index of any +This class includes a labeling function that provides, the subdomain index of any query point. An intersection between a segment and bounding surfaces is detected when both segment endpoints are associated with different values of subdomain indices. The intersection is then constructed by bisection. @@ -20,18 +20,13 @@ The bisection stops when the query segment is shorter than an error bound length of the diagonal of the bounding box (in world coordinates), or the radius of the bounding sphere, and a relative error bound passed as argument to the constructor of `Labeled_mesh_domain_3`. -Implicit_mesh_domain_3 is a heir of Labeled_mesh_domain_3. It uses a satisfying labeling function if there is only one component to mesh. - -\tparam LabelingFunction is the type of the input function.
-This parameter stands for a model of the concept ImplicitFunction described in the surface mesh generation package.
-Labeling function f must return 0 if the point isn't located in any subdomain. Usually, the return type of labeling functions are integer.
-Let p be a Point. +This class has a constructor taking a labeling function. It has also three +static template member functions that act as named constructors:
    -
  • f(p)=0 means that p is outside domain.
  • -
  • f(p)=a, a!=0 means that p is inside subdomain a.
  • +
  • `create_gray_image_mesh_domain()`, to create a domain from a 3D gray image, +
  • `create_labeled_image_mesh_domain()`, to create a domain from a 3D labeled image, and +
  • `create_implicit_mesh_domain()`, to create a domain from an implicit function.
-Implicit_multi_domain_to_labeling_function_wrapper is a good candidate for this template parameter -if there are several components to mesh. \tparam BGT is a geometric traits class that provides the basic operations to implement @@ -39,19 +34,229 @@ intersection tests and intersection computations through a bisection method. This parameter must be instantiated with a model of the concept `BisectionGeometricTraits_3`. +\cgalHeading{Labeling function} + +A labeling function `f` must return `0` if the point isn't located in any subdomain. The return type of labeling functions is an integer. + +Let `p` be a Point. +
    +
  • `f(p)=0` means that `p` is outside domain.
  • +
  • `f(p)=a`, `a!=0` means that `p` is inside subdomain `a`.
  • +
+`CGAL::Implicit_multi_domain_to_labeling_function_wrapper` is a good candidate for this template parameter +if there are several components to mesh. + +The function type can be any model of the concept `Callable` compatible with the signature `Subdomain_index(const Point_3&)`: it can be a function, a function object, a lambda expression... that takes a `%Point_3` as argument, and returns a type convertible to `Subdomain_index`. + \cgalModels MeshDomain_3 -\sa `Implicit_mesh_domain_3` \sa `Implicit_multi_domain_to_labeling_function_wrapper` \sa `CGAL::make_mesh_3()`. */ -template +template class Labeled_mesh_domain_3 { public: -/// \name Creation +/// \name Types +///@{ + +/// The subdomain index of this model of `MeshDomain_3`. +typedef int Subdomain_index; + +/// The type of object that stores the function using type-erasure +typedef CGAL::cpp11::function Labeling_function; + +///@} +/// \name Types imported from the geometric traits class +///@{ + +/// The point type of the geometric traits class +typedef typename Geom_traits::Point_3 Point_3; +/// The sphere type of the geometric traits class +typedef typename Geom_traits::Sphere_3 Sphere_3; +/// The iso-cuboid type of the geometric traits class +typedef typename Geom_traits::Iso_cuboid_3 Iso_cuboid_3; +/// The number type (a field type) of the geometric traits class +typedef typename Geom_traits::FT FT; +///@} + +/// \name Creation +/// @{ +/*! \brief Construction from a function, a bounding +object and a relative error bound. + +This constructor uses named parameters (from the Boost Parameter +Library). They can be specified in any order. + +\cgalHeading{Named Parameters} +- `parameters::function` (mandatory) the labeling function, compatible with `Labeling_function`. +- `parameters::bounding_object` (mandatory) the bounding object is either a bounding sphere (of type `Sphere_3`), a bounding box (type `Bbox_3`), or a bounding `Iso_cuboid_3`. It bounds the meshable space. +- `parameters::relative_error_bound` (optional) the relative error bound used to compute intersection points between the implicit surface and query segments. The +bisection is stopped when the length of the intersected segment is less than the product of `relative_error_bound` by the diameter of the bounding object. Its default value is `FT(1e-3)`. + +\cgalHeading{Example} +From the example (\ref Mesh_3/mesh_implicit_domains_2.cpp): +\snippet Mesh_3/mesh_implicit_domains_2.cpp Domain creation + + */ +template +Labeled_mesh_domain_3(const A_i&...); + +///@} + +/// \name Creation of domains from implicit functions + +/*! +\brief Construction from an implicit function + +This static method is a named constructor. It constructs a domain +whose bounding surface is described implicitly as the zero level set of a +function. The domain to be discretized is assumed to be the domain where +the function has negative values. + +The method takes as argument a bounding sphere which is required to +circumscribe the surface and to have its center inside the domain. + +This constructor uses named parameters (from the Boost Parameter +Library). They can be specified in any order. + +\cgalHeading{Named Parameters} +
    +
  • `parameters::function` (mandatory) the implicit function, +compatible with the signature `FT(Point_3)`: it takes a point as argument, +and returns a scalar value. That object must be model of `CopyConstructible`. +
  • `parameters::bounding_object` (mandatory) the bounding object is +either a bounding sphere (of type `Sphere_3`), a bounding box (type +`Bbox_3`), or a bounding `Iso_cuboid_3`. It must bounds the surface, and +its center must be inside the domain. +
+ +\cgalHeading{Examples} + +From the example (\ref Mesh_3/mesh_implicit_sphere.cpp), where the name of +the parameters is not specified, as they are given is the same order as the +parameters definition: + +\snippet Mesh_3/mesh_implicit_sphere.cpp Domain creation + +From the example (\ref Mesh_3/mesh_implicit_sphere_variable_size.cpp): + +\snippet Mesh_3/mesh_implicit_sphere_variable_size.cpp Domain creation + + */ +template +static +Labeled_mesh_domain_3 +create_implicit_mesh_domain(A_i&...); + +/// \name Creation of domains from 3D images + + +/*! +\brief Construction from a 3D gray image + +This static method is a named constructor. It constructs a domain +described by a 3D gray image. A 3D gray image is a grid of voxels, +where each voxel is associated with a gray level value. Unless otherwise specified by the parameter `image_values_to_subdom_indices`, the domain to +be discretized is the union of voxels that lie inside a surface +described by an isolevel value, called \a isovalue. The voxels lying +inside the domain have gray level values that are larger than the +isovalue. + +The value of voxels is interpolated to a gray level value at any query point. + +This constructor uses named parameters (from the Boost Parameter +Library). They can be specified in any order. + +\cgalHeading{Named Parameters} +The parameters are optional unless otherwise specified. +
    + +
  • `parameters::image` (mandatory) the input 3D image. Must +be a `CGAL::Image_3` object. + +
  • `parameters::iso_value` the isovalue, inside + `image`, of the surface describing the boundary of the object to be + meshed. Its default value is `0`. + +
  • `parameters::image_values_to_subdom_indices` a function or + a function object, compatible with the signature + `Subdomain_index(double)`. This function returns the subdomain index + corresponding to a pixel value. If this parameter is used, then the + parameter `iso_value` is ignored. + +
  • `parameter::value_outside` the value attached to voxels + outside of the domain to be meshed. It should be lower than + `iso_value`. Its default value is `0`. + +
  • `parameter::relative_error_bound` is the relative error + bound, relative to the diameter of the box of the image. Its default + value is `FT(1e-3)`.
+ +\cgalHeading{Examples} + +From the example (\ref Mesh_3/mesh_3D_gray_image.cpp), where the name +of the parameters is not specified, as they are given is the same +order as the parameters definition: + +\snippet Mesh_3/mesh_3D_gray_image.cpp Domain creation + +From the example (\ref Mesh_3/mesh_3D_gray_vtk_image.cpp): + +\snippet Mesh_3/mesh_3D_gray_vtk_image.cpp Domain creation + + */ +template +static +Labeled_mesh_domain_3 +create_gray_image_mesh_domain(A_i&...); + +/*! +\brief Construction from a 3D labeled image + +This static method is a named constructor. It constructs a +domain described by a 3D labeled image. A 3D labeled image is a grid +of voxels, where each voxel is associated with an index (a subdomain +index) characterizing the subdomain in which the voxel lies. The +domain to be discretized is the union of voxels that have non-zero +values. + +This constructor uses named parameters (from the Boost Parameter +Library). They can be specified in any order. + +\cgalHeading{Named Parameters} +The parameters are optional unless otherwise specified. +
    + +
  • `parameters::image` (mandatory) the input 3D image. Must +be a `CGAL::Image_3` object. + +
  • `parameter::value_outside` the value attached to voxels + outside of the domain to be meshed. Its default value is `0`. + +
  • `parameter::relative_error_bound` is the relative error + bound, relative to the diameter of the box of the image. Its default + value is `FT(1e-3)`.
+ +\cgalHeading{Example} + +From the example (\ref Mesh_3/mesh_3D_image.cpp): + +\snippet Mesh_3/mesh_3D_image.cpp Domain creation + + */ +template +static +Labeled_mesh_domain_3 +create_labeled_image_mesh_domain(A_i&...); + +/// \name Deprecated constructors +/// +/// Those three constructors have been deprecated since CGAL-4.13, and +/// replaced by the constructor using the Boost Parameter Library. +/// /// @{ /*! @@ -61,8 +266,10 @@ public: \param relative_error_bound is the relative error bound used to compute intersection points between the implicit surface and query segments. The bisection is stopped when the length of the intersected segment is less than the product of `relative_error_bound` by the radius of `bounding_sphere`. +\deprecated This constructor is deprecated since CGAL-4.13, and +replaced by the constructor using the Boost Parameter Library. */ -Labeled_mesh_domain_3(const LabelingFunction& f, +Labeled_mesh_domain_3(Labeling_function f, const Sphere_3& bounding_sphere, const FT& relative_error_bound = FT(1e-3)); @@ -73,8 +280,10 @@ Labeled_mesh_domain_3(const LabelingFunction& f, \param relative_error_bound is the relative error bound used to compute intersection points between the implicit surface and query segments. The bisection is stopped when the length of the intersected segment is less than the product of `relative_error_bound` by the diagonal of `bounding_box`. +\deprecated This constructor is deprecated since CGAL-4.13, and +replaced by the constructor using the Boost Parameter Library. */ -Labeled_mesh_domain_3(const LabelingFunction& f, +Labeled_mesh_domain_3(Labeling_function f, const Bbox_3& bbox, const FT& relative_error_bound = FT(1e-3)); @@ -85,8 +294,10 @@ Labeled_mesh_domain_3(const LabelingFunction& f, \param relative_error_bound is the relative error bound used to compute intersection points between the implicit surface and query segments. The bisection is stopped when the length of the intersected segment is less than the product of `relative_error_bound` by the diagonal of `bounding_box`. +\deprecated This constructor is deprecated since CGAL-4.13, and +replaced by the constructor using the Boost Parameter Library. */ -Labeled_mesh_domain_3(const LabelingFunction& f, +Labeled_mesh_domain_3(Labeling_function f, const Iso_cuboid_3& bbox, const FT& relative_error_bound = FT(1e-3)); diff --git a/Mesh_3/doc/Mesh_3/Concepts/BisectionGeometricTraits_3.h b/Mesh_3/doc/Mesh_3/Concepts/BisectionGeometricTraits_3.h index 4c55a49fe2d..af8ade1a8f0 100644 --- a/Mesh_3/doc/Mesh_3/Concepts/BisectionGeometricTraits_3.h +++ b/Mesh_3/doc/Mesh_3/Concepts/BisectionGeometricTraits_3.h @@ -20,8 +20,7 @@ of the segment. \sa `ImplicitSurfaceTraits_3` \sa `IntersectionGeometricTraits_3` -\sa `CGAL::Implicit_mesh_domain_3` -\sa `CGAL::Labeled_image_mesh_domain_3` +\sa `CGAL::Labeled_mesh_domain_3` */ diff --git a/Mesh_3/doc/Mesh_3/Concepts/LabeledImage_3.h b/Mesh_3/doc/Mesh_3/Concepts/LabeledImage_3.h deleted file mode 100644 index 627cefdc5ad..00000000000 --- a/Mesh_3/doc/Mesh_3/Concepts/LabeledImage_3.h +++ /dev/null @@ -1,80 +0,0 @@ -/*! -\ingroup PkgMesh_3SecondaryConcepts -\cgalConcept - -The concept `LabeledImage_3` describes the requirements for the second template -parameter of the class `CGAL::Labeled_image_mesh_domain_3` -which represents mesh domains defined by 3D labeled images. A 3D labeled -image is a 3D array of elements of an integral -type `Type`. `Type` can be `bool`, `char`, `short`, -`int`, or `long` (signed or not). Such an array is -associated to a 3D axis-aligned regular grid, in -\f$ \mathbb{R}^3\f$. A cell of this grid is denoted by voxel. A voxel is -an iso-cuboid of size `vx()`, `vy()`, and `vz()`. - -\cgalHasModel `CGAL::Image_3`, for any \cgal kernel `K` and any integral type `T` - -*/ - -class LabeledImage_3 { -public: - -/// \name Types -/// @{ - -/*! -Type of voxel data. Must be an -integral type. -*/ -typedef unspecified_type Type; - -/*! -Ring number type. -*/ -typedef unspecified_type RT; - -/// @} - -/// \name Operations -/// @{ - -/*! -First dimension of the 3D array, -i.e., the number of voxels along the x coordinate axis. -*/ -int xdim(); - -/*! -Second dimension of the 3D array. -*/ -int ydim(); - -/*! -Third dimension of the 3D array. -*/ -int zdim(); - -/*! -Size of each voxel along x coordinate axis. -*/ -RT vx(); - -/*! -Size of each voxel along y coordinate axis. -*/ -RT vy(); - -/*! -Size of each voxel along z coordinate axis. -*/ -RT vz(); - -/*! -Pointer to the first element of the 3D -image. The size of the array must be `xdim()`\f$ \times\f$`ydim()`\f$ \times\f$`zdim()`. -*/ -const Type* data(); - -/// @} - -}; /* end LabeledImage_3 */ diff --git a/Mesh_3/doc/Mesh_3/Concepts/MeshDomain_3.h b/Mesh_3/doc/Mesh_3/Concepts/MeshDomain_3.h index 23923535102..60205e189bc 100644 --- a/Mesh_3/doc/Mesh_3/Concepts/MeshDomain_3.h +++ b/Mesh_3/doc/Mesh_3/Concepts/MeshDomain_3.h @@ -30,9 +30,7 @@ if it includes points which are strictly inside and strictly outside the domain (resp. the subdomain). \cgalHasModel `CGAL::Polyhedral_mesh_domain_3` -\cgalHasModel `CGAL::Implicit_mesh_domain_3` -\cgalHasModel `CGAL::Labeled_image_mesh_domain_3` -\cgalHasModel `CGAL::Labeled_mesh_domain_3` +\cgalHasModel `CGAL::Labeled_mesh_domain_3` \sa `MeshVertexBase_3` \sa `MeshCellBase_3` diff --git a/Mesh_3/doc/Mesh_3/Mesh_3.txt b/Mesh_3/doc/Mesh_3/Mesh_3.txt index d682deb13eb..07fc6d487ea 100644 --- a/Mesh_3/doc/Mesh_3/Mesh_3.txt +++ b/Mesh_3/doc/Mesh_3/Mesh_3.txt @@ -881,9 +881,9 @@ image is composed of 1D curves, and must be defined as 1D-features in the domain. The first modification is the type of the mesh domain. Instead of being -`Labeled_image_mesh_domain_3`, it is a +`Labeled_mesh_domain_3`, it is a `Mesh_domain_with_polyline_features_3` templated by a -`Labeled_image_mesh_domain_3`. +`Labeled_mesh_domain_3`. \snippet Mesh_3/mesh_3D_image_with_features.cpp Domain definition diff --git a/Mesh_3/doc/Mesh_3/PackageDescription.txt b/Mesh_3/doc/Mesh_3/PackageDescription.txt index aecb0b2b3ba..a823b21cffc 100644 --- a/Mesh_3/doc/Mesh_3/PackageDescription.txt +++ b/Mesh_3/doc/Mesh_3/PackageDescription.txt @@ -70,7 +70,6 @@ related to the template parameters of some models of the main concepts: - `BisectionGeometricTraits_3` - `IntersectionGeometricTraits_3` -- `LabeledImage_3` - `MeshCellBase_3` - `MeshVertexBase_3` - `MeshDomainField_3` @@ -93,17 +92,17 @@ related to the template parameters of some models of the main concepts: The following classes are models of domain concepts and their associated classes: -- `CGAL::Implicit_mesh_domain_3` - `CGAL::Labeled_mesh_domain_3` - `CGAL::Polyhedral_mesh_domain_3` - `CGAL::Polyhedral_mesh_domain_with_features_3` - `CGAL::Polyhedral_complex_mesh_domain_3` -- `CGAL::Labeled_image_mesh_domain_3` -- `CGAL::Gray_image_mesh_domain_3` - `CGAL::Mesh_domain_with_polyline_features_3` - `CGAL::Mesh_polyhedron_3` - `CGAL::Triangle_accessor_3,K>` - `CGAL::Implicit_multi_domain_to_labeling_function_wrapper` +- `CGAL::Implicit_mesh_domain_3` (deprecated) +- `CGAL::Labeled_image_mesh_domain_3` (deprecated) +- `CGAL::Gray_image_mesh_domain_3` (deprecated) ## Function Templates ## diff --git a/Mesh_3/examples/Mesh_3/CMakeLists.txt b/Mesh_3/examples/Mesh_3/CMakeLists.txt index 30762fed754..480956dbaf0 100644 --- a/Mesh_3/examples/Mesh_3/CMakeLists.txt +++ b/Mesh_3/examples/Mesh_3/CMakeLists.txt @@ -81,6 +81,7 @@ if ( CGAL_FOUND ) endif() create_single_source_cgal_program( "mesh_3D_gray_image.cpp" ) + create_single_source_cgal_program( "mesh_3D_gray_image_multiple_values.cpp" ) create_single_source_cgal_program( "mesh_3D_image_with_features.cpp" ) if( CGAL_ImageIO_USE_ZLIB ) create_single_source_cgal_program( "mesh_optimization_example.cpp" ) diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_gray_image.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_gray_image.cpp index d9cce646941..222fe1cf4c3 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_gray_image.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_gray_image.cpp @@ -5,7 +5,7 @@ #include #include -#include +#include #include #include #include @@ -14,8 +14,7 @@ typedef float Image_word_type; // Domain typedef CGAL::Exact_predicates_inexact_constructions_kernel K; -typedef CGAL::Gray_image_mesh_domain_3 Mesh_domain; +typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; // Triangulation typedef CGAL::Mesh_triangulation_3::type Tr; @@ -36,8 +35,10 @@ int main(int argc, char*argv[]) std::cerr << "Error: Cannot read file " << fname << std::endl; return EXIT_FAILURE; } - // Domain - Mesh_domain domain(image, 2.9f, 0.f); + /// [Domain creation] + Mesh_domain domain = + Mesh_domain::create_gray_image_mesh_domain(image, 2.9f, 0.f); + /// [Domain creation] // Mesh criteria Mesh_criteria criteria(facet_angle=30, facet_size=6, facet_distance=2, diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_gray_image_multiple_values.cmd b/Mesh_3/examples/Mesh_3/mesh_3D_gray_image_multiple_values.cmd new file mode 100644 index 00000000000..d70c103fded --- /dev/null +++ b/Mesh_3/examples/Mesh_3/mesh_3D_gray_image_multiple_values.cmd @@ -0,0 +1 @@ +data/skull_2.9.inr 1.5 2.9 3.5 diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_gray_image_multiple_values.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_gray_image_multiple_values.cpp new file mode 100644 index 00000000000..bb476fea566 --- /dev/null +++ b/Mesh_3/examples/Mesh_3/mesh_3D_gray_image_multiple_values.cpp @@ -0,0 +1,85 @@ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +typedef float Image_word_type; + +// Domain +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; + +// Triangulation +typedef CGAL::Mesh_triangulation_3::type Tr; +typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; + +// Criteria +typedef CGAL::Mesh_criteria_3 Mesh_criteria; + +// To avoid verbose function and named parameters call +using namespace CGAL::parameters; + +template +struct Image_to_multiple_iso_level_sets { + const Set& set; + Image_to_multiple_iso_level_sets(const Set& set) : set(set) {} + + int operator()(double v) const { + return int(std::distance(set.begin(), + set.lower_bound(float(v)))); + } +}; + +int main(int argc, char*argv[]) +{ + const char* fname = (argc>1)?argv[1]:"data/skull_2.9.inr"; + // Load image + CGAL::Image_3 image; + if(!image.read(fname)){ + std::cerr << "Error: Cannot read file " << fname << std::endl; + return EXIT_FAILURE; + } + + typedef boost::container::flat_set Flat_set; + Flat_set iso_values; + if(argc < 3) { + iso_values.insert(2.9f); + } else { + for(int i = 2; i < argc; ++i) { + iso_values.insert(static_cast(std::atof(argv[i]))); + } + } + + // Domain + namespace p = CGAL::parameters; + Mesh_domain domain = + Mesh_domain::create_gray_image_mesh_domain + (p::image = image, + p::image_values_to_subdomain_indices = + Image_to_multiple_iso_level_sets(iso_values), + p::value_outside = 0.f + ); + + // Mesh criteria + Mesh_criteria criteria(facet_angle=30, facet_size=6, facet_distance=2, + cell_radius_edge_ratio=3, cell_size=8); + + // Meshing + C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria); + + // Output + std::ofstream medit_file("out.mesh"); + c3t3.output_to_medit(medit_file); + + return 0; +} diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_gray_vtk_image.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_gray_vtk_image.cpp index 55c6487817f..45c6124cce0 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_gray_vtk_image.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_gray_vtk_image.cpp @@ -11,7 +11,7 @@ #include #include -#include +#include #include #include #include @@ -23,9 +23,7 @@ typedef short Image_word_type; // Domain typedef CGAL::Exact_predicates_inexact_constructions_kernel K; -typedef CGAL::Gray_image_mesh_domain_3 > > Mesh_domain; +typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; // Triangulation typedef CGAL::Mesh_triangulation_3::type Tr; @@ -34,8 +32,16 @@ typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Criteria typedef CGAL::Mesh_criteria_3 Mesh_criteria; -// To avoid verbose function and named parameters call -using namespace CGAL::parameters; +class Less { + double iso; +public: + Less(double iso): iso(iso) {} + + template + int operator()(T v) const { + return int(v < iso); + } +}; int main(int argc, char* argv[]) { @@ -72,9 +78,16 @@ int main(int argc, char* argv[]) std::cerr << "could not create a CGAL::Image_3 from the vtk image\n"; return 0; } - // Domain - Mesh_domain domain(image, boost::bind1st(std::less(), iso), 0); - + /// [Domain creation] + // To avoid verbose function and named parameters call + using namespace CGAL::parameters; + + Mesh_domain domain = Mesh_domain::create_gray_image_mesh_domain + (image, + image_values_to_subdomain_indices = Less(iso), + value_outside = 0); + /// [Domain creation] + // Mesh criteria Mesh_criteria criteria(facet_angle=30, facet_size=fs, facet_distance=fd, cell_radius_edge_ratio=3, cell_size=cs); diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_image.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_image.cpp index 8fa9d544102..c7dad626119 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_image.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_image.cpp @@ -4,13 +4,13 @@ #include #include -#include +#include #include #include // Domain typedef CGAL::Exact_predicates_inexact_constructions_kernel K; -typedef CGAL::Labeled_image_mesh_domain_3 Mesh_domain; +typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; #ifdef CGAL_CONCURRENT_MESH_3 typedef CGAL::Parallel_tag Concurrency_tag; @@ -40,8 +40,9 @@ int main(int argc, char* argv[]) } /// [Loads image] - // Domain - Mesh_domain domain(image); + /// [Domain creation] + Mesh_domain domain = Mesh_domain::create_labeled_image_mesh_domain(image); + /// [Domain creation] // Mesh criteria Mesh_criteria criteria(facet_angle=30, facet_size=6, facet_distance=4, diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_image_variable_size.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_image_variable_size.cpp index b5b975ee879..be26a22b3a5 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_image_variable_size.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_image_variable_size.cpp @@ -7,13 +7,13 @@ #include #include -#include +#include #include #include // Domain typedef CGAL::Exact_predicates_inexact_constructions_kernel K; -typedef CGAL::Labeled_image_mesh_domain_3 Mesh_domain; +typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; #ifdef CGAL_CONCURRENT_MESH_3 typedef CGAL::Parallel_tag Concurrency_tag; @@ -45,7 +45,7 @@ int main(int argc, char* argv[]) } // Domain - Mesh_domain domain(image); + Mesh_domain domain = Mesh_domain::create_labeled_image_mesh_domain(image); // Sizing field: set global size to 8 and kidney size (label 127) to 3 double kidney_size = 3.; diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp index 9197c4239bf..9bd06e32ae4 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp @@ -7,7 +7,7 @@ #include -#include +#include #include #include @@ -15,7 +15,7 @@ // Domain typedef CGAL::Exact_predicates_inexact_constructions_kernel K; -typedef CGAL::Labeled_image_mesh_domain_3 Mesh_domain; +typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; #ifdef CGAL_CONCURRENT_MESH_3 typedef CGAL::Parallel_tag Concurrency_tag; @@ -41,7 +41,7 @@ int main() /// [Create the image] // Domain - Mesh_domain domain(image); + Mesh_domain domain = Mesh_domain::create_labeled_image_mesh_domain(image); // Mesh criteria Mesh_criteria criteria(facet_angle=30, facet_size=3, facet_distance=1, diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_features.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_features.cpp index 4292d2a257a..e2334150529 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_features.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_features.cpp @@ -11,10 +11,10 @@ /// [Domain definition] #include #include -#include +#include typedef CGAL::Exact_predicates_inexact_constructions_kernel K; -typedef CGAL::Labeled_image_mesh_domain_3 Image_domain; +typedef CGAL::Labeled_mesh_domain_3 Image_domain; typedef CGAL::Mesh_domain_with_polyline_features_3 Mesh_domain; /// [Domain definition] @@ -47,7 +47,7 @@ bool add_1D_features(const CGAL::Image_3& image, const char* lines_fname) { typedef K::Point_3 Point_3; - typedef Mesh_domain::Image_word_type Word_type; // that is `unsigned char` + typedef unsigned char Word_type; std::vector > features_inside; if(!read_polylines(lines_fname, features_inside)) // see file "read_polylines.h" @@ -81,7 +81,7 @@ int main(int argc, char* argv[]) } // Domain - Mesh_domain domain(image); + Mesh_domain domain = Mesh_domain::create_labeled_image_mesh_domain(image); /// Declare 1D-features, see above [Call add_1D_features] const char* lines_fname = (argc>2)?argv[2]:"data/420.polylines.txt"; diff --git a/Mesh_3/examples/Mesh_3/mesh_cubes_intersection.cpp b/Mesh_3/examples/Mesh_3/mesh_cubes_intersection.cpp index 3b9da29830e..f0d8e94348e 100644 --- a/Mesh_3/examples/Mesh_3/mesh_cubes_intersection.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_cubes_intersection.cpp @@ -29,7 +29,7 @@ typedef FT (*Function)(const Point&); typedef CGAL::Implicit_multi_domain_to_labeling_function_wrapper Function_wrapper; typedef Function_wrapper::Function_vector Function_vector; -typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; +typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; // Triangulation typedef CGAL::Mesh_triangulation_3::type Tr; diff --git a/Mesh_3/examples/Mesh_3/mesh_cubes_intersection_with_features.cpp b/Mesh_3/examples/Mesh_3/mesh_cubes_intersection_with_features.cpp index 0ab5d0d7ffc..60bd95f7815 100644 --- a/Mesh_3/examples/Mesh_3/mesh_cubes_intersection_with_features.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_cubes_intersection_with_features.cpp @@ -30,7 +30,7 @@ typedef FT (*Function)(const Point&); typedef CGAL::Implicit_multi_domain_to_labeling_function_wrapper Function_wrapper; typedef Function_wrapper::Function_vector Function_vector; -typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; +typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; typedef CGAL::Mesh_domain_with_polyline_features_3 Mesh_domain_with_features; // Triangulation diff --git a/Mesh_3/examples/Mesh_3/mesh_hybrid_mesh_domain.cpp b/Mesh_3/examples/Mesh_3/mesh_hybrid_mesh_domain.cpp index 8316a6f5335..eb6cec632ac 100644 --- a/Mesh_3/examples/Mesh_3/mesh_hybrid_mesh_domain.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_hybrid_mesh_domain.cpp @@ -6,7 +6,7 @@ #include #include -#include +#include #include #include #include @@ -20,10 +20,8 @@ // Sphere Domain typedef CGAL::Exact_predicates_inexact_constructions_kernel K; -typedef K::FT FT; -typedef K::Point_3 Point; -typedef FT (Function)(const Point&); -typedef CGAL::Implicit_mesh_domain_3 Implicit_domain; + +typedef CGAL::Labeled_mesh_domain_3 Implicit_domain; // Polyhedral Domain typedef CGAL::Polyhedron_3 Polyhedron; @@ -180,6 +178,9 @@ typedef Mesh_criteria::Facet_criteria Facet_criteria; typedef Mesh_criteria::Cell_criteria Cell_criteria; // Function +typedef K::FT FT; +typedef K::Point_3 Point; + FT sphere_centered_at_111 (const Point& p) { const FT dx=p.x()-1; @@ -212,8 +213,10 @@ int main() // - the first argument is the function pointer // - the second argument is a bounding sphere of the domain // (Warning: Sphere_3 constructor uses square radius !) - Implicit_domain sphere_domain(sphere_centered_at_111, - K::Sphere_3(K::Point_3(1, 1, 1), 2.)); + Implicit_domain sphere_domain = + Implicit_domain::create_implicit_mesh_domain(sphere_centered_at_111, + K::Sphere_3(K::Point_3(1, 1, 1), + 2.)); Domain domain(sphere_domain, polyhedron_domain); diff --git a/Mesh_3/examples/Mesh_3/mesh_implicit_domains.cpp b/Mesh_3/examples/Mesh_3/mesh_implicit_domains.cpp index 073fb09082e..ba9c950f610 100644 --- a/Mesh_3/examples/Mesh_3/mesh_implicit_domains.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_implicit_domains.cpp @@ -20,7 +20,7 @@ typedef FT_to_point_function_wrapper Function; typedef CGAL::Implicit_multi_domain_to_labeling_function_wrapper Function_wrapper; typedef Function_wrapper::Function_vector Function_vector; -typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; +typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; // Triangulation typedef CGAL::Mesh_triangulation_3::type Tr; @@ -43,7 +43,7 @@ int main() v.push_back(f2); // Domain (Warning: Sphere_3 constructor uses square radius !) - Mesh_domain domain(v, K::Sphere_3(CGAL::ORIGIN, 5.*5.), 1e-6); + Mesh_domain domain(Function_wrapper(v), K::Sphere_3(CGAL::ORIGIN, 5.*5.), 1e-6); // Set mesh criteria Facet_criteria facet_criteria(30, 0.2, 0.02); // angle, size, approximation diff --git a/Mesh_3/examples/Mesh_3/mesh_implicit_domains_2.cpp b/Mesh_3/examples/Mesh_3/mesh_implicit_domains_2.cpp index 41daf9fd6dd..1db89900160 100644 --- a/Mesh_3/examples/Mesh_3/mesh_implicit_domains_2.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_implicit_domains_2.cpp @@ -20,7 +20,7 @@ typedef FT_to_point_function_wrapper Function; typedef CGAL::Implicit_multi_domain_to_labeling_function_wrapper Function_wrapper; typedef Function_wrapper::Function_vector Function_vector; -typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; +typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; // Triangulation typedef CGAL::Mesh_triangulation_3::type Tr; @@ -45,8 +45,13 @@ int main() std::vector vps; vps.push_back("+-"); - // Domain (Warning: Sphere_3 constructor uses square radius !) - Mesh_domain domain(Function_wrapper(v, vps), K::Sphere_3(CGAL::ORIGIN, 5.*5.)); + /// [Domain creation] (Warning: Sphere_3 constructor uses square radius !) + namespace param = CGAL::parameters; + Mesh_domain domain(param::function = Function_wrapper(v, vps), + param::bounding_object = K::Sphere_3(CGAL::ORIGIN, + 5.*5.), + param::relative_error_bound = 1e-6); + /// [Domain creation] // Set mesh criteria Facet_criteria facet_criteria(30, 0.2, 0.02); // angle, size, approximation diff --git a/Mesh_3/examples/Mesh_3/mesh_implicit_ellipsoid.cpp b/Mesh_3/examples/Mesh_3/mesh_implicit_ellipsoid.cpp index dbc162aa2c4..f4beb65d75b 100644 --- a/Mesh_3/examples/Mesh_3/mesh_implicit_ellipsoid.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_implicit_ellipsoid.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include #include #include @@ -14,7 +14,7 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel K; typedef K::FT FT; typedef K::Point_3 Point; typedef FT (Function)(const Point&); -typedef CGAL::Implicit_mesh_domain_3 Mesh_domain; +typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; // Triangulation typedef CGAL::Mesh_triangulation_3::type Tr; @@ -41,7 +41,9 @@ using namespace CGAL::parameters; int main() { // Domain (Warning: Sphere_3 constructor uses square radius !) - Mesh_domain domain(ellipsoid_function, K::Sphere_3(CGAL::ORIGIN, 2.)); + Mesh_domain domain = + Mesh_domain::create_implicit_mesh_domain(ellipsoid_function, + K::Sphere_3(CGAL::ORIGIN, 2.)); // Criteria Facet_criteria facet_criteria(30, 0.08, 0.025); // angle, size, approximation diff --git a/Mesh_3/examples/Mesh_3/mesh_implicit_sphere.cpp b/Mesh_3/examples/Mesh_3/mesh_implicit_sphere.cpp index 8e3f1234f2f..be66887e6c1 100644 --- a/Mesh_3/examples/Mesh_3/mesh_implicit_sphere.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_implicit_sphere.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include // Domain @@ -12,7 +12,7 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel K; typedef K::FT FT; typedef K::Point_3 Point; typedef FT (Function)(const Point&); -typedef CGAL::Implicit_mesh_domain_3 Mesh_domain; +typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; #ifdef CGAL_CONCURRENT_MESH_3 typedef CGAL::Parallel_tag Concurrency_tag; @@ -37,9 +37,11 @@ FT sphere_function (const Point& p) int main() { - // Domain (Warning: Sphere_3 constructor uses squared radius !) - Mesh_domain domain(sphere_function, - K::Sphere_3(CGAL::ORIGIN, 2.)); + /// [Domain creation] (Warning: Sphere_3 constructor uses squared radius !) + Mesh_domain domain = + Mesh_domain::create_implicit_mesh_domain(sphere_function, + K::Sphere_3(CGAL::ORIGIN, 2.)); + /// [Domain creation] // Mesh criteria Mesh_criteria criteria(facet_angle=30, facet_size=0.1, facet_distance=0.025, diff --git a/Mesh_3/examples/Mesh_3/mesh_implicit_sphere_variable_size.cpp b/Mesh_3/examples/Mesh_3/mesh_implicit_sphere_variable_size.cpp index 42547d8b07b..ef1dd3ef01d 100644 --- a/Mesh_3/examples/Mesh_3/mesh_implicit_sphere_variable_size.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_implicit_sphere_variable_size.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include // Domain @@ -12,7 +12,7 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel K; typedef K::FT FT; typedef K::Point_3 Point; typedef FT (Function)(const Point&); -typedef CGAL::Implicit_mesh_domain_3 Mesh_domain; +typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; #ifdef CGAL_CONCURRENT_MESH_3 typedef CGAL::Parallel_tag Concurrency_tag; @@ -51,9 +51,13 @@ FT sphere_function (const Point& p) int main() { - // Domain (Warning: Sphere_3 constructor uses squared radius !) - Mesh_domain domain(sphere_function, - K::Sphere_3(CGAL::ORIGIN, 2.)); + /// [Domain creation] (Warning: Sphere_3 constructor uses squared radius !) + namespace p = CGAL::parameters; + Mesh_domain domain = Mesh_domain::create_implicit_mesh_domain + (p::function = &sphere_function, + p::bounding_object = K::Sphere_3(CGAL::ORIGIN, 2.) + ); + /// [Domain creation] // Mesh criteria Spherical_sizing_field size; diff --git a/Mesh_3/examples/Mesh_3/mesh_optimization_example.cpp b/Mesh_3/examples/Mesh_3/mesh_optimization_example.cpp index ad6a215093a..b7239352384 100644 --- a/Mesh_3/examples/Mesh_3/mesh_optimization_example.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_optimization_example.cpp @@ -4,13 +4,13 @@ #include #include -#include +#include #include #include // Domain typedef CGAL::Exact_predicates_inexact_constructions_kernel K; -typedef CGAL::Labeled_image_mesh_domain_3 Mesh_domain; +typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; #ifdef CGAL_CONCURRENT_MESH_3 typedef CGAL::Parallel_tag Concurrency_tag; @@ -39,7 +39,7 @@ int main(int argc, char* argv[]) return EXIT_FAILURE; } - Mesh_domain domain(image); + Mesh_domain domain = Mesh_domain::create_labeled_image_mesh_domain(image); // Mesh criteria Mesh_criteria criteria(facet_angle=30, facet_size=5, facet_distance=1.5, diff --git a/Mesh_3/examples/Mesh_3/mesh_optimization_lloyd_example.cpp b/Mesh_3/examples/Mesh_3/mesh_optimization_lloyd_example.cpp index 2f00593c4eb..e79eb4e9c90 100644 --- a/Mesh_3/examples/Mesh_3/mesh_optimization_lloyd_example.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_optimization_lloyd_example.cpp @@ -4,13 +4,13 @@ #include #include -#include +#include #include #include // Domain typedef CGAL::Exact_predicates_inexact_constructions_kernel K; -typedef CGAL::Labeled_image_mesh_domain_3 Mesh_domain; +typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; #ifdef CGAL_CONCURRENT_MESH_3 typedef CGAL::Parallel_tag Concurrency_tag; @@ -38,7 +38,7 @@ int main(int argc, char*argv[]) std::cerr << "Error: Cannot read file " << fname << std::endl; return EXIT_FAILURE; } - Mesh_domain domain(image); + Mesh_domain domain = Mesh_domain::create_labeled_image_mesh_domain(image); // Mesh criteria Mesh_criteria criteria(facet_angle=30, facet_distance=1.2, diff --git a/Mesh_3/examples/Mesh_3/mesh_two_implicit_spheres_with_balls.cpp b/Mesh_3/examples/Mesh_3/mesh_two_implicit_spheres_with_balls.cpp index efab3c774bf..c40e737b389 100644 --- a/Mesh_3/examples/Mesh_3/mesh_two_implicit_spheres_with_balls.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_two_implicit_spheres_with_balls.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include #include @@ -16,7 +16,7 @@ typedef K::FT FT; typedef K::Point_3 Point; typedef FT (Function)(const Point&); typedef CGAL::Mesh_domain_with_polyline_features_3< - CGAL::Implicit_mesh_domain_3 > Mesh_domain; + CGAL::Labeled_mesh_domain_3 > Mesh_domain; // Polyline typedef std::vector Polyline_3; @@ -60,8 +60,9 @@ FT sphere_function (const Point& p) int main() { // Domain (Warning: Sphere_3 constructor uses squared radius !) - Mesh_domain domain(sphere_function, - K::Sphere_3(Point(1, 0, 0), 6.)); + Mesh_domain domain = + Mesh_domain::create_implicit_mesh_domain(sphere_function, + K::Sphere_3(Point(1, 0, 0), 6.)); // Mesh criteria Mesh_criteria criteria(edge_size = 0.15, diff --git a/Mesh_3/include/CGAL/Gray_image_mesh_domain_3.h b/Mesh_3/include/CGAL/Gray_image_mesh_domain_3.h index 7a2f33e94b4..79da0114811 100644 --- a/Mesh_3/include/CGAL/Gray_image_mesh_domain_3.h +++ b/Mesh_3/include/CGAL/Gray_image_mesh_domain_3.h @@ -31,25 +31,10 @@ #include #include #include - -#include +#include namespace CGAL { -namespace internal { - - template - struct Greater_than { - typedef T argument_type; - Greater_than(const T& second) : second(second) {} - bool operator()(const T& first) const { - return std::greater()(first, second); - } - T second; - }; - -} - /** * @class Gray_image_mesh_domain_3 * @@ -57,26 +42,25 @@ namespace internal { */ template, + typename Image_word_type_ = float, + typename Transform = internal::Mesh_3::Greater_than, typename Subdomain_index = int> -class Gray_image_mesh_domain_3 - : public Labeled_mesh_domain_3< - Mesh_3::Image_to_labeled_function_wrapper , - BGT> +class +CGAL_DEPRECATED_MSG +( "The class template `CGAL::Gray_image_mesh_domain_3` is now deprecated. " + "Use the static member function template " + "`Labeled_mesh_domain_3::create_gray_image_mesh_domain` instead.") +Gray_image_mesh_domain_3 + : public Labeled_mesh_domain_3 { public: - typedef Mesh_3::Image_to_labeled_function_wrapper Wrapper; - typedef Labeled_mesh_domain_3 Base; + typedef Labeled_mesh_domain_3 Base; typedef typename Base::Sphere_3 Sphere_3; typedef typename Base::FT FT; @@ -92,9 +76,8 @@ public: : Base(Wrapper(image, Transform(iso_value), Transform(iso_value)(value_outside)), - compute_bounding_box(image), + internal::Mesh_3::compute_bounding_box(image), error_bound, - Null_subdomain_index(), p_rng) { CGAL_assertion(Transform(iso_value)(value_outside) == 0); @@ -106,9 +89,8 @@ public: const FT& error_bound = FT(1e-3), CGAL::Random* p_rng = NULL) : Base(Wrapper(image, transform, transform(value_outside)), - compute_bounding_box(image), + internal::Mesh_3::compute_bounding_box(image), error_bound, - Null_subdomain_index(), p_rng) { CGAL_assertion(transform(value_outside) == 0); @@ -116,30 +98,11 @@ public: /// Destructor virtual ~Gray_image_mesh_domain_3() {} - - -private: - /// Returns a box enclosing image \c im - Bbox_3 compute_bounding_box(const Image& im) const - { - return Bbox_3(-1,-1,-1, - double(im.xdim())*im.vx()+1, - double(im.ydim())*im.vy()+1, - double(im.zdim())*im.vz()+1); - } - -private: - // Disabled copy constructor & assignment operator - typedef Gray_image_mesh_domain_3 Self; - Gray_image_mesh_domain_3(const Self& src); - Self& operator=(const Self& src); - }; // end class Gray_image_mesh_domain_3 - - } // end namespace CGAL #include + #endif // CGAL_GRAY_IMAGE_MESH_DOMAIN_3_H diff --git a/Mesh_3/include/CGAL/Implicit_mesh_domain_3.h b/Mesh_3/include/CGAL/Implicit_mesh_domain_3.h index a690ed5ee7b..3e2a43f3831 100644 --- a/Mesh_3/include/CGAL/Implicit_mesh_domain_3.h +++ b/Mesh_3/include/CGAL/Implicit_mesh_domain_3.h @@ -44,15 +44,20 @@ namespace CGAL { * Implements mesh_traits for a domain defined as the negative values of * an implicit function. */ -template > -class Implicit_mesh_domain_3 - : public Labeled_mesh_domain_3 + class Wrapper = Implicit_to_labeling_function_wrapper > +class +CGAL_DEPRECATED_MSG +( "The class template `CGAL::Implicit_mesh_domain_3` is now deprecated. " + "Use the static member function template " + "`Labeled_mesh_domain_3::create_implicit_image_mesh_domain` instead.") +Implicit_mesh_domain_3 + : public Labeled_mesh_domain_3 { public: /// Base type - typedef Labeled_mesh_domain_3 Base; + typedef Labeled_mesh_domain_3 Base; /// Public types typedef typename Base::Sphere_3 Sphere_3; @@ -65,7 +70,7 @@ public: * @param bounding_sphere a bounding sphere of the domain * @param error_bound the error bound relative to the sphere radius */ - Implicit_mesh_domain_3(const Function& f, + Implicit_mesh_domain_3(const Function_& f, const Sphere_3& bounding_sphere, const FT& error_bound = FT(1e-6), CGAL::Random* p_rng = NULL) @@ -78,7 +83,7 @@ public: using Base::bbox; private: // Disabled copy constructor & assignment operator - typedef Implicit_mesh_domain_3 Self; + typedef Implicit_mesh_domain_3 Self; Implicit_mesh_domain_3(const Self& src); Self& operator=(const Self& src); diff --git a/Mesh_3/include/CGAL/Implicit_to_labeling_function_wrapper.h b/Mesh_3/include/CGAL/Implicit_to_labeling_function_wrapper.h index 401d307dd31..5bfa882bcff 100644 --- a/Mesh_3/include/CGAL/Implicit_to_labeling_function_wrapper.h +++ b/Mesh_3/include/CGAL/Implicit_to_labeling_function_wrapper.h @@ -43,6 +43,8 @@ #include #include #include +#include +#include #include #include @@ -66,26 +68,31 @@ public: /// Constructor Implicit_to_labeling_function_wrapper(const Function_& f) - : r_f_(f) {} + : f_(f) {} - // Default copy constructor and assignment operator are ok - - /// Destructor - ~Implicit_to_labeling_function_wrapper() {} + // Default copy constructor, assignment operator, and destructor are ok /// Operator () - return_type operator()(const Point_3& p, const bool = true) const + return_type operator()(const Point_3& p) const { - return ( (r_f_(p)<0) ? 1 : 0 ); + return ( (f_(p)<0) ? 1 : 0 ); } private: + typedef typename boost::mpl::if_, + Function_*, + Function_>::type Stored_function; /// Function to wrap - const Function_& r_f_; + Stored_function f_; }; // end class Implicit_to_labeling_function_wrapper - +template +Implicit_to_labeling_function_wrapper +make_implicit_to_labeling_function_wrapper(const Function& f) +{ + return Implicit_to_labeling_function_wrapper(f); +} /** * \deprecated @@ -125,7 +132,7 @@ public: ~Implicit_vector_to_labeling_function_wrapper() {} /// Operator () - return_type operator()(const Point_3& p, const bool = true) const + return_type operator()(const Point_3& p) const { const int nb_func = static_cast(function_vector_.size()); char bits = 0; @@ -192,7 +199,7 @@ public: typename Bmask::size_type bit_index = 0; for (std::vector::const_iterator iter = mask.begin(), endIter = mask.end(); iter != endIter; ++iter) { - std::string::value_type character = static_cast(*iter); + Sign character = *iter; CGAL_assertion(character == POSITIVE || character == NEGATIVE); bmask[bit_index] = (character == POSITIVE); @@ -259,7 +266,7 @@ public: std::sort(bmasks.begin(), bmasks.end()); } - return_type operator() (const Point_3& p, const bool = true) const + return_type operator() (const Point_3& p) const { Bmask bmask(funcs.size() * 2, false); diff --git a/Mesh_3/include/CGAL/Labeled_image_mesh_domain_3.h b/Mesh_3/include/CGAL/Labeled_image_mesh_domain_3.h index e1d75276105..275a4b312d8 100644 --- a/Mesh_3/include/CGAL/Labeled_image_mesh_domain_3.h +++ b/Mesh_3/include/CGAL/Labeled_image_mesh_domain_3.h @@ -51,30 +51,26 @@ template -class Labeled_image_mesh_domain_3 -: public Labeled_mesh_domain_3 - - >::type, - BGT, - Null_subdomain_index - > +class +CGAL_DEPRECATED_MSG +( "The class template `CGAL::Labeled_image_mesh_domain_3` is now deprecated. " + "Use the static member function template " + "`Labeled_mesh_domain_3::create_labeled_image_mesh_domain` instead.") +Labeled_image_mesh_domain_3 + : public Labeled_mesh_domain_3 { public: typedef Image_word_type_ Image_word_type; typedef typename Default::Get >::type Wrapper; typedef typename Default::Get::type Null; - typedef Labeled_mesh_domain_3 Base; + typedef Labeled_mesh_domain_3 Base; typedef typename Base::Sphere_3 Sphere_3; typedef typename Base::FT FT; @@ -91,21 +87,8 @@ public: : Base(Wrapper(image, Identity(), value_outside), compute_bounding_box(image), error_bound, - null, - p_rng) - {} - - Labeled_image_mesh_domain_3(const Image& image, - const CGAL::Bbox_3& bbox, - const FT& error_bound = FT(1e-3), - Subdomain_index value_outside = 0, - Null null = Null(), - CGAL::Random* p_rng = NULL) - : Base(Wrapper(image, Identity(), value_outside), - bbox, - error_bound, - null, - p_rng) + parameters::null_subdomain_index = null, + parameters::p_rng = p_rng) {} Labeled_image_mesh_domain_3(const Image& image, @@ -114,18 +97,6 @@ public: : Base(Wrapper(image), compute_bounding_box(image), error_bound, - Null(), - p_rng) - {} - - Labeled_image_mesh_domain_3(const Image& image, - const CGAL::Bbox_3& bbox, - const FT error_bound, - CGAL::Random* p_rng) - : Base(Wrapper(image), - bbox, - error_bound, - Null(), p_rng) {} @@ -145,13 +116,6 @@ private: double(im.ydim()+1)*im.vy(), double(im.zdim()+1)*im.vz()); } - -private: - // Disabled copy constructor & assignment operator - typedef Labeled_image_mesh_domain_3 Self; - Labeled_image_mesh_domain_3(const Self& src); - Self& operator=(const Self& src); - }; // end class Labeled_image_mesh_domain_3 diff --git a/Mesh_3/include/CGAL/Labeled_mesh_domain_3.h b/Mesh_3/include/CGAL/Labeled_mesh_domain_3.h index 103bf98007a..f015060e4fb 100644 --- a/Mesh_3/include/CGAL/Labeled_mesh_domain_3.h +++ b/Mesh_3/include/CGAL/Labeled_mesh_domain_3.h @@ -37,23 +37,218 @@ #include -#include -#include +#include +#include +#include +#ifdef CGAL_MESH_3_VERBOSE +# include +#endif #include +#include #include #include -#include +#include +#include #include +#include + +// support for `CGAL::Image_3` +#include +#include + +// support for implicit functions +#include + namespace CGAL { +namespace internal { + +namespace Mesh_3 { + + struct Identity { + template + const T& operator()(const T& x) { return x; } + }; + + template + struct Greater_than { + typedef T argument_type; + typedef bool result_type; + Greater_than(const T& second) : second(second) {} + bool operator()(const T& first) const { + return std::greater()(first, second); + } + T second; + }; + + struct Do_not_delete { + template void operator()(T*) const { } + }; + + /// Returns a box enclosing image \c im + inline Bbox_3 compute_bounding_box(const Image_3& im) + { + return Bbox_3(-1,-1,-1, + double(im.xdim())*im.vx()+1, + double(im.ydim())*im.vy()+1, + double(im.zdim())*im.vz()+1); + } + + template + struct Create_gray_image_values_to_subdomain_indices { + typedef Image_values_to_subdom_indices type; + template + type operator()(Image_values_to_subdom_indices functor, const FT&) const { + return functor; + } + }; + + // specialization for `Null_functor`: create the default functor + template <> + struct Create_gray_image_values_to_subdomain_indices { + typedef internal::Mesh_3::Greater_than type; + template + type operator()(Null_functor, const FT& iso_value) const { + return type(iso_value); + } + }; + + template + struct Create_labeled_image_values_to_subdomain_indices { + typedef Image_values_to_subdom_indices type; + type operator()(Image_values_to_subdom_indices functor) const { + return functor; + } + }; + + // specialization for `Null_functor`: create the default functor + template <> + struct Create_labeled_image_values_to_subdomain_indices { + typedef Identity type; + type operator()(Null_functor) const { + return type(); + } + }; + +} // end namespace CGAL::internal::Mesh_3 +} // end namespace CGAL::internal + struct Null_subdomain_index { template bool operator()(const T& x) const { return 0 == x; } }; +template +struct Construct_pair_from_subdomain_indices { + typedef std::pair result_type; + + result_type operator()(Subdomain_index a, Subdomain_index b) const { + return result_type(a, b); + } +}; // end class template Construct_pair_from_subdomain_indices + +template +class Labeled_mesh_domain_3_impl_details { +protected: + typedef Surface_patch_index_ Surface_patch_index; + typedef typename Geom_traits::Point_3 Point_3; + typedef typename Geom_traits::Sphere_3 Sphere_3; + typedef typename Geom_traits::Iso_cuboid_3 Iso_cuboid_3; + typedef typename Geom_traits::FT FT; + typedef boost::shared_ptr CGAL_Random_share_ptr_t; + /// Returns squared error bound from \c bbox and \c error + FT squared_error_bound(const Iso_cuboid_3& bbox, const FT& error) const + { + typename Geom_traits::Compute_squared_distance_3 squared_distance = + Geom_traits().compute_squared_distance_3_object(); + return squared_distance((bbox.min)(), (bbox.max)())*error*error/4; + } + + static Iso_cuboid_3 iso_cuboid(const Bbox_3& bbox) + { + const Point_3 p_min(bbox.xmin(), bbox.ymin(), bbox.zmin()); + const Point_3 p_max(bbox.xmax(), bbox.ymax(), bbox.zmax()); + + return Iso_cuboid_3(p_min,p_max); + } + + static Iso_cuboid_3 iso_cuboid(const typename Geom_traits::Sphere_3& sphere) + { + return iso_cuboid(sphere.bbox()); + } + + static Iso_cuboid_3 iso_cuboid(const typename Geom_traits::Iso_cuboid_3& c) + { + return c; + } + + static Construct_pair_from_subdomain_indices + construct_pair_functor() { + return Construct_pair_from_subdomain_indices(); + } + + template + Labeled_mesh_domain_3_impl_details(ArgumentPack const& args) + : function_(args[parameters::function]) + , bbox_(iso_cuboid(args[parameters::bounding_object])) + , cstr_s_p_index(args[parameters::construct_surface_patch_index | + construct_pair_functor()]) + , null(args[parameters::null_subdomain_index | Null_subdomain_index()]) + , p_rng_(args[parameters::p_rng|0] == 0 ? + CGAL_Random_share_ptr_t(new CGAL::Random(0)) : + CGAL_Random_share_ptr_t(args[parameters::p_rng|(CGAL::Random*)(0)], + internal::Mesh_3::Do_not_delete())) + , squared_error_bound_ + ( squared_error_bound(bbox_, + args[parameters::relative_error_bound|FT(1e-3)])) + { + } + + template + Labeled_mesh_domain_3_impl_details(const Function& f, + const Bounding_object& bounding, + const FT& error_bound, + Construct_surface_patch_index cstr_s_p_i, + Null null, + CGAL::Random* p_rng) + : function_(f) + , bbox_(iso_cuboid(bounding)) + , cstr_s_p_index(cstr_s_p_i) + , null(null) + , p_rng_(p_rng == 0 ? + CGAL_Random_share_ptr_t(new CGAL::Random(0)) : + CGAL_Random_share_ptr_t(p_rng, internal::Mesh_3::Do_not_delete())) + , squared_error_bound_(squared_error_bound(bbox_,error_bound)) + {} + + /// The function which answers subdomain queries + typedef CGAL::cpp11::function Function; + Function function_; + /// The bounding box + const Iso_cuboid_3 bbox_; + + typedef CGAL::cpp11::function< + Surface_patch_index(Subdomain_index, + Subdomain_index)> Construct_surface_patch_index; + Construct_surface_patch_index cstr_s_p_index; + /// The functor that decides which sub-domain indices correspond to the + /// outside of the domain. + typedef CGAL::cpp11::function Null; + Null null; + /// The random number generator used by Construct_initial_points + CGAL_Random_share_ptr_t p_rng_; + /// Error bound relative to sphere radius + FT squared_error_bound_; +}; // Labeled_mesh_domain_3_impl_details + /** * \class Labeled_mesh_domain_3 * @@ -66,12 +261,42 @@ struct Null_subdomain_index { * tags of it's incident subdomain. * Thus, a boundary facet of the domain is labelled <0,b>, where b!=0. */ -template -class Labeled_mesh_domain_3 +template > +class Labeled_mesh_domain_3 : + protected Labeled_mesh_domain_3_impl_details { - typedef typename Default::Get::type Null; +public: + //------------------------------------------------------- + // Index Types + //------------------------------------------------------- + /// Type of indexes for cells of the input complex + typedef Subdomain_index_ Subdomain_index; + typedef boost::optional Subdomain; + + /// Type of indexes for cells of the input complex + typedef Surface_patch_index_ Surface_patch_index; + typedef boost::optional Surface_patch; + + /// Type of indexes to characterize the lowest dimensional face of the input + /// complex on which a vertex lie + typedef typename CGAL::internal::Mesh_3:: + Index_generator::Index Index; + +private: + typedef Labeled_mesh_domain_3_impl_details Impl_details; + typedef typename Impl_details::Null Null; + typedef typename Impl_details::Construct_surface_patch_index + Construct_surface_patch_index; + typedef typename Impl_details::Function Function; + public: /// Geometric object types typedef typename BGT::Point_3 Point_3; @@ -91,66 +316,178 @@ public: // access Function type from inherited class typedef Function Fct; - //------------------------------------------------------- - // Index Types - //------------------------------------------------------- - /// Type of indexes for cells of the input complex - typedef typename Function::return_type Subdomain_index; - typedef boost::optional Subdomain; - /// Type of indexes for surface patch of the input complex - typedef std::pair Surface_patch_index; - typedef boost::optional Surface_patch; - /// Type of indexes to characterize the lowest dimensional face of the input - /// complex on which a vertex lie - typedef boost::variant Index; typedef CGAL::cpp11::tuple Intersection; typedef typename BGT::FT FT; typedef BGT Geom_traits; + + BOOST_PARAMETER_CONSTRUCTOR(Labeled_mesh_domain_3, + (Impl_details), + parameters::tag, + (required + (function_,(Function)) + (bounding_object_,*) + ) + (optional + (relative_error_bound_, (const FT&)) + (p_rng_, (CGAL::Random*)) + (null_subdomain_index_,(Null)) + (construct_surface_patch_index_, + (Construct_surface_patch_index)) + ) + ) + using Impl_details::construct_pair_functor; /** - * @brief Constructor + * Backward-compatibility constructors, with `null_subdomain_index` as + * fourth parameter. + * @{ */ Labeled_mesh_domain_3(const Function& f, const Sphere_3& bounding_sphere, const FT& error_bound = FT(1e-3), - Null null = Null(), - CGAL::Random* p_rng = NULL); + Null null = Null_subdomain_index(), + CGAL::Random* p_rng = NULL) + : Impl_details(f, bounding_sphere, + error_bound, + construct_pair_functor(), + null, p_rng) {} Labeled_mesh_domain_3(const Function& f, const Bbox_3& bbox, const FT& error_bound = FT(1e-3), - Null null = Null(), - CGAL::Random* p_rng = NULL); + Null null = Null_subdomain_index(), + CGAL::Random* p_rng = NULL) + : Impl_details(f, bbox, + error_bound, + construct_pair_functor(), + null, p_rng) {} Labeled_mesh_domain_3(const Function& f, const Iso_cuboid_3& bbox, const FT& error_bound = FT(1e-3), - Null null = Null(), - CGAL::Random* p_rng = NULL); + Null null = Null_subdomain_index(), + CGAL::Random* p_rng = NULL) + : Impl_details(f, bbox, error_bound, + construct_pair_functor(), + null, p_rng) + {} + /** + * @} + */ - Labeled_mesh_domain_3(const Function& f, - const Sphere_3& bounding_sphere, - const FT& error_bound, - CGAL::Random* p_rng); - - Labeled_mesh_domain_3(const Function& f, - const Bbox_3& bbox, - const FT& error_bound, - CGAL::Random* p_rng); - - Labeled_mesh_domain_3(const Function& f, - const Iso_cuboid_3& bbox, - const FT& error_bound, - CGAL::Random* p_rng); - /// Destructor - virtual ~Labeled_mesh_domain_3() + /// Named constructors, for domains created from 3D images + /// @{ +#if defined(BOOST_MSVC) +# pragma warning(push) +# pragma warning(disable: 4003) +#endif + BOOST_PARAMETER_MEMBER_FUNCTION( + (Labeled_mesh_domain_3), + static create_gray_image_mesh_domain, + parameters::tag, + (required + (image_, (const CGAL::Image_3&)) + ) + (optional + (iso_value_, *, 0) + (value_outside_, *, 0) + (relative_error_bound_, (const FT&), + FT(1e-3)) + (p_rng_, (CGAL::Random*), (CGAL::Random*)(0)) + (image_values_to_subdomain_indices_, *, + Null_functor()) + (null_subdomain_index_,*,Null_functor()) + (construct_surface_patch_index_, *, + Null_functor()) + ) + ) { - if(delete_rng_) - delete p_rng_; + namespace p = CGAL::parameters; + return Labeled_mesh_domain_3 + (create_gray_image_wrapper + (image_, + iso_value_, + image_values_to_subdomain_indices_, + value_outside_), + internal::Mesh_3::compute_bounding_box(image_), + p::relative_error_bound = relative_error_bound_, + p::p_rng = p_rng_, + p::null_subdomain_index = + create_null_subdomain_index(null_subdomain_index_), + p::construct_surface_patch_index = + create_construct_surface_patch_index(construct_surface_patch_index_)); } + BOOST_PARAMETER_MEMBER_FUNCTION( + (Labeled_mesh_domain_3), + static create_labeled_image_mesh_domain, + parameters::tag, + (required + (image_, (const CGAL::Image_3&)) + ) + (optional + (relative_error_bound_, (const FT&), + FT(1e-3)) + (value_outside_, *, 0) + (p_rng_, (CGAL::Random*), (CGAL::Random*)(0)) + (image_values_to_subdomain_indices_, *, + Null_functor()) + (null_subdomain_index_,*,Null_functor()) + (construct_surface_patch_index_, *, + Null_functor()) + ) + ) + { + namespace p = CGAL::parameters; + return Labeled_mesh_domain_3 + (create_labeled_image_wrapper + (image_, + image_values_to_subdomain_indices_, + value_outside_), + internal::Mesh_3::compute_bounding_box(image_), + p::relative_error_bound = relative_error_bound_, + p::p_rng = p_rng_, + p::null_subdomain_index = + create_null_subdomain_index(null_subdomain_index_), + p::construct_surface_patch_index = + create_construct_surface_patch_index(construct_surface_patch_index_)); + } + BOOST_PARAMETER_MEMBER_FUNCTION( + (Labeled_mesh_domain_3), + static create_implicit_mesh_domain, + parameters::tag, + (required + (function_, *) + (bounding_object_,*) + ) + (optional + (relative_error_bound_, (const FT&), + FT(1e-3)) + (p_rng_, (CGAL::Random*), (CGAL::Random*)(0)) + (null_subdomain_index_,*,Null_functor()) + (construct_surface_patch_index_, *, + Null_functor()) + ) + ) + { + namespace p = CGAL::parameters; + return Labeled_mesh_domain_3 + (make_implicit_to_labeling_function_wrapper(function_), + bounding_object_, + p::relative_error_bound = relative_error_bound_, + p::p_rng = p_rng_, + p::null_subdomain_index = + create_null_subdomain_index(null_subdomain_index_), + p::construct_surface_patch_index = + create_construct_surface_patch_index(construct_surface_patch_index_)); + } + +#if defined(BOOST_MSVC) +# pragma warning(pop) +#endif + /// @} /** * Constructs a set of \ccc{n} points on the surface, and output them to @@ -179,7 +516,7 @@ public: * Returns a bounding box of the domain */ Bbox_3 bbox() const { - return bbox_.bbox(); + return this->bbox_.bbox(); } /** @@ -344,7 +681,7 @@ public: // Cannot be const: those values are modified below. Subdomain_index value_at_p1 = r_domain_.function_(p1); Subdomain_index value_at_p2 = r_domain_.function_(p2); - Subdomain_index value_at_mid = r_domain_.function_(mid,true); + Subdomain_index value_at_mid = r_domain_.function_(mid); // If both extremities are in the same subdomain, // there is no intersection. @@ -390,7 +727,7 @@ public: } mid = midpoint(p1, p2); - value_at_mid = r_domain_.function_(mid,true); + value_at_mid = r_domain_.function_(mid); } } @@ -468,29 +805,15 @@ public: // ----------------------------------- -private: +protected: /// Returns Surface_patch_index from \c i and \c j Surface_patch_index make_surface_index(const Subdomain_index i, - const Subdomain_index j) const + const Subdomain_index j) const { - if ( i < j ) return Surface_patch_index(i,j); - else return Surface_patch_index(j,i); - } - - /// Returns squared error bound from \c bbox and \c error - FT squared_error_bound(const Iso_cuboid_3& bbox, const FT& error) const - { - typename BGT::Compute_squared_distance_3 squared_distance = - BGT().compute_squared_distance_3_object(); - return squared_distance((bbox.min)(), (bbox.max)())*error*error/4; - } - - /// Returns squared error bound from \c sphere and \c error - FT squared_error_bound(const Sphere_3& sphere, const FT& error) const - { - typename BGT::Compute_squared_radius_3 squared_radius = - BGT().compute_squared_radius_3_object(); - return squared_radius(sphere)*error*error; + if(i < j) + return this->cstr_s_p_index(i, j); + else + return this->cstr_s_p_index(j, i); } /// Returns the bounding sphere of an Iso_cuboid_3 @@ -500,39 +823,118 @@ private: return sphere((bbox.min)(), (bbox.max)()); } - /// Returns and Iso_cuboid_3 from a Bbox_3 - Iso_cuboid_3 iso_cuboid(const Bbox_3& bbox) + template + static + Function + create_gray_image_wrapper_with_known_word_type + (const CGAL::Image_3& image, + const FT& iso_value, + const Functor& image_values_to_subdomain_indices, + const FT2& value_outside) { - const Point_3 p_min(bbox.xmin(), bbox.ymin(), bbox.zmin()); - const Point_3 p_max(bbox.xmax(), bbox.ymax(), bbox.zmax()); + using internal::Mesh_3::Create_gray_image_values_to_subdomain_indices; + typedef Create_gray_image_values_to_subdomain_indices C_i_v_t_s_i; + typedef typename C_i_v_t_s_i::type Image_values_to_subdomain_indices; + Image_values_to_subdomain_indices transform_fct = + C_i_v_t_s_i()(image_values_to_subdomain_indices, iso_value); - return Iso_cuboid_3(p_min,p_max); + typedef Mesh_3::Image_to_labeled_function_wrapper Wrapper; + return Wrapper(image, + transform_fct, + transform_fct(value_outside)); + } + + template + static + Function + create_gray_image_wrapper(const CGAL::Image_3& image, + const FT& iso_value, + const Functor& image_values_to_subdomain_indices, + const FT2& value_outside) + { + CGAL_IMAGE_IO_CASE(image.image(), + return create_gray_image_wrapper_with_known_word_type + (image, + iso_value, + image_values_to_subdomain_indices, + value_outside); + ); + CGAL_error_msg("This place should never be reached, because it would mean " + "the image word type is a type that is not handled by " + "CGAL_ImageIO."); + return Function(); + } + + template + static + Function + create_labeled_image_wrapper_with_known_word_type + (const CGAL::Image_3& image, + const Functor& image_values_to_subdomain_indices, + const FT& value_outside) + { + using internal::Mesh_3::Create_labeled_image_values_to_subdomain_indices; + typedef Create_labeled_image_values_to_subdomain_indices C_i_v_t_s_i; + typedef typename C_i_v_t_s_i::type Image_values_to_subdomain_indices; + Image_values_to_subdomain_indices transform_fct = + C_i_v_t_s_i()(image_values_to_subdomain_indices); + + typedef Mesh_3::Image_to_labeled_function_wrapper Wrapper; + return Wrapper(image, + transform_fct, + transform_fct(value_outside)); + } + + template + static + Function + create_labeled_image_wrapper(const CGAL::Image_3& image, + const Functor& image_values_to_subdomain_indices, + const FT& value_outside) + { + CGAL_IMAGE_IO_CASE(image.image(), + return create_labeled_image_wrapper_with_known_word_type + (image, + image_values_to_subdomain_indices, + value_outside); + ); + CGAL_error_msg("This place should never be reached, because it would mean " + "the image word type is a type that is not handled by " + "CGAL_ImageIO."); + return Function(); + } + + static + Construct_surface_patch_index + create_construct_surface_patch_index(const Null_functor&) { + return Impl_details::construct_pair_functor(); + } + + template + static + Construct_surface_patch_index + create_construct_surface_patch_index(const Functor& functor) { + return functor; + } + + static Null create_null_subdomain_index(const Null_functor&) { + return Null_subdomain_index(); + } + + template + static Null create_null_subdomain_index(const Functor& functor) { + return functor; } -protected: /// Returns bounding box - const Iso_cuboid_3& bounding_box() const { return bbox_; } - -private: - /// The function which answers subdomain queries - const Function function_; - /// The bounding box - const Iso_cuboid_3 bbox_; - /// The functor that decides which sub-domain indices correspond to the - /// outside of the domain. - Null null; - /// The random number generator used by Construct_initial_points - CGAL::Random* p_rng_; - bool delete_rng_; - /// Error bound relative to sphere radius - FT squared_error_bound_; - - -private: - // Disabled copy constructor & assignment operator - typedef Labeled_mesh_domain_3 Self; - Labeled_mesh_domain_3(const Self& src); - Self& operator=(const Self& src); + const Iso_cuboid_3& bounding_box() const { return this->bbox_; } }; // end class Labeled_mesh_domain_3 @@ -542,109 +944,12 @@ private: //------------------------------------------------------- // Method implementation //------------------------------------------------------- -template -Labeled_mesh_domain_3::Labeled_mesh_domain_3( - const F& f, - const Sphere_3& bounding_sphere, - const FT& error_bound, - Null null /* = Null() */, - CGAL::Random* p_rng) -: function_(f) -, bbox_(iso_cuboid(bounding_sphere.bbox())) -, null(null) -, p_rng_(p_rng == 0 ? new CGAL::Random(0) : p_rng) -, delete_rng_(p_rng == 0) -, squared_error_bound_(squared_error_bound(bounding_sphere,error_bound)) -{ -} - -template -Labeled_mesh_domain_3::Labeled_mesh_domain_3( - const F& f, - const Bbox_3& bbox, - const FT& error_bound, - Null null /* = Null() */, - CGAL::Random* p_rng) -: function_(f) -, bbox_(iso_cuboid(bbox)) -, null(null) -, p_rng_(p_rng == 0 ? new CGAL::Random(0) : p_rng) -, delete_rng_(p_rng == 0) -, squared_error_bound_(squared_error_bound(bbox_,error_bound)) -{ -} - -template -Labeled_mesh_domain_3::Labeled_mesh_domain_3( - const F& f, - const Iso_cuboid_3& bbox, - const FT& error_bound, - Null null /* = Null() */, - CGAL::Random* p_rng) -: function_(f) -, bbox_(bbox) -, null(null) -, p_rng_(p_rng == 0 ? new CGAL::Random(0) : p_rng) -, delete_rng_(p_rng == 0) -, squared_error_bound_(squared_error_bound(bbox_,error_bound)) -{ -} - - - - -template -Labeled_mesh_domain_3::Labeled_mesh_domain_3( - const F& f, - const Sphere_3& bounding_sphere, - const FT& error_bound, - CGAL::Random* p_rng) -: function_(f) -, bbox_(iso_cuboid(bounding_sphere.bbox())) -, null(Null()) -, p_rng_(p_rng == 0 ? new CGAL::Random(0) : p_rng) -, delete_rng_(p_rng == 0) -, squared_error_bound_(squared_error_bound(bounding_sphere,error_bound)) -{ -} - -template -Labeled_mesh_domain_3::Labeled_mesh_domain_3( - const F& f, - const Bbox_3& bbox, - const FT& error_bound, - CGAL::Random* p_rng) -: function_(f) -, bbox_(iso_cuboid(bbox)) -, null(Null()) -, p_rng_(p_rng == 0 ? new CGAL::Random(0) : p_rng) -, delete_rng_(p_rng == 0) -, squared_error_bound_(squared_error_bound(bbox_,error_bound)) -{ -} - -template -Labeled_mesh_domain_3::Labeled_mesh_domain_3( - const F& f, - const Iso_cuboid_3& bbox, - const FT& error_bound, - CGAL::Random* p_rng) -: function_(f) -, bbox_(bbox) -, null(Null()) -, p_rng_(p_rng == 0 ? new CGAL::Random(0) : p_rng) -, delete_rng_(p_rng == 0) -, squared_error_bound_(squared_error_bound(bbox_,error_bound)) -{ -} - - -template +template template OutputIterator -Labeled_mesh_domain_3::Construct_initial_points::operator()( - OutputIterator pts, - const int nb_points) const +Labeled_mesh_domain_3:: +Construct_initial_points::operator()(OutputIterator pts, + const int nb_points) const { // Create point_iterator on and in bounding_sphere typedef Random_points_on_sphere_3 Random_points_on_sphere_3; diff --git a/Mesh_3/include/CGAL/Mesh_3/C3T3_helpers.h b/Mesh_3/include/CGAL/Mesh_3/C3T3_helpers.h index c0ce67121ee..c2ce1bf910b 100644 --- a/Mesh_3/include/CGAL/Mesh_3/C3T3_helpers.h +++ b/Mesh_3/include/CGAL/Mesh_3/C3T3_helpers.h @@ -1252,11 +1252,6 @@ private: facet.first->set_facet_surface_center(facet.second,surface_center); facet_m.first->set_facet_surface_center(facet_m.second,surface_center); } - else - { - facet.first->set_facet_surface_center(facet.second,Bare_point()); - facet_m.first->set_facet_surface_center(facet_m.second,Bare_point()); - } } return surface; @@ -1687,9 +1682,27 @@ private: /** * Returns the least square plane from v, using adjacent surface points */ - Plane_3 get_least_square_surface_plane(const Vertex_handle& v, - Bare_point& ref_point, - Surface_patch_index index = Surface_patch_index()) const; + boost::optional + get_least_square_surface_plane(const Vertex_handle& v, + Bare_point& ref_point, + Surface_patch_index index = Surface_patch_index()) const; + + /** + * @brief Project \c p on surface, using incident facets of \c v + * @param p The point to project + * @param v The vertex from which p was moved + * @param index The index of the surface patch where v lies, if known. + * @return a boost::optional with the projected point if the projection + * was possible, or boost::none + * + * \c p is projected as follows using normal of least square fitting plane + * on \c v incident surface points. If \c index is specified, only + * surface points that are on the same surface patch are used to compute + * the fitting plane. + */ + boost::optional + project_on_surface_if_possible(const Bare_point& p, const Vertex_handle& v, + Surface_patch_index index = Surface_patch_index()) const; /** * @brief Returns the projection of \c p, using direction of @@ -2667,7 +2680,6 @@ C3T3_helpers:: rebuild_restricted_delaunay(OutdatedCells& outdated_cells, Moving_vertices_set& moving_vertices) { - typename Gt::Equal_3 equal = tr_.geom_traits().equal_3_object(); typename OutdatedCells::iterator first_cell = outdated_cells.begin(); typename OutdatedCells::iterator last_cell = outdated_cells.end(); Update_c3t3 updater(domain_,c3t3_); @@ -2766,15 +2778,16 @@ rebuild_restricted_delaunay(OutdatedCells& outdated_cells, it != vertex_to_proj.end() ; ++it ) { - Bare_point new_pos = project_on_surface(wp2p_((*it)->point()),*it); + boost::optional opt_new_pos = + project_on_surface(wp2p_((*it)->point()),*it); - if ( ! equal(new_pos, Bare_point()) ) + if ( opt_new_pos ) { //freezing needs 'erase' to be done before the vertex is actually destroyed // Update moving vertices (it becomes new_vertex) moving_vertices.erase(*it); - Vertex_handle new_vertex = update_mesh(p2wp_(new_pos),*it); + Vertex_handle new_vertex = update_mesh(p2wp_(*opt_new_pos),*it); c3t3_.set_dimension(new_vertex,2); moving_vertices.insert(new_vertex); @@ -2873,15 +2886,16 @@ rebuild_restricted_delaunay(ForwardIterator first_cell, it != vertex_to_proj.end() ; ++it ) { - Bare_point new_pos = project_on_surface(wp2p_((it->first)->point()),it->first,it->second); + boost::optional opt_new_pos = + project_on_surface(wp2p_((it->first)->point()),it->first,it->second); - if ( ! equal(new_pos, Bare_point()) ) + if ( opt_new_pos ) { //freezing needs 'erase' to be done before the vertex is actually destroyed // Update moving vertices (it becomes new_vertex) moving_vertices.erase(it->first); - Vertex_handle new_vertex = update_mesh(p2wp_(new_pos), it->first); + Vertex_handle new_vertex = update_mesh(p2wp_(*opt_new_pos), it->first); c3t3_.set_dimension(new_vertex,2); moving_vertices.insert(new_vertex); @@ -3333,7 +3347,7 @@ project_on_surface_aux(const Bare_point& p, template -typename C3T3_helpers::Plane_3 +boost::optional::Plane_3> C3T3_helpers:: get_least_square_surface_plane(const Vertex_handle& v, Bare_point& reference_point, @@ -3373,7 +3387,7 @@ get_least_square_surface_plane(const Vertex_handle& v, // In some cases point is not a real surface point if ( surface_point_vector.empty() ) - return Plane_3(); + return boost::none; // Compute least square fitting plane Plane_3 plane; @@ -3399,25 +3413,39 @@ C3T3_helpers:: project_on_surface(const Bare_point& p, const Vertex_handle& v, Surface_patch_index index) const +{ + boost::optional opt_point = + project_on_surface_if_possible(p, v, index); + if(opt_point) return *opt_point; + else return p; +} + + +template +boost::optional::Bare_point> +C3T3_helpers:: +project_on_surface_if_possible(const Bare_point& p, + const Vertex_handle& v, + Surface_patch_index index) const { typename Gt::Equal_3 equal = tr_.geom_traits().equal_3_object(); // return domain_.project_on_surface(p); // Get plane - Bare_point reference_point(CGAL::ORIGIN); - Plane_3 plane = get_least_square_surface_plane(v,reference_point, index); + Bare_point reference_point; + boost::optional opt_plane = + get_least_square_surface_plane(v,reference_point, index); - if ( equal(reference_point, CGAL::ORIGIN) ) - return p; + if(!opt_plane) return boost::none; // Project if ( ! equal(p, wp2p_(v->point())) ) return project_on_surface_aux(p, wp2p_(v->point()), - plane.orthogonal_vector()); + opt_plane->orthogonal_vector()); else return project_on_surface_aux(p, reference_point, - plane.orthogonal_vector()); + opt_plane->orthogonal_vector()); } diff --git a/Mesh_3/include/CGAL/Mesh_3/Image_to_labeled_function_wrapper.h b/Mesh_3/include/CGAL/Mesh_3/Image_to_labeled_function_wrapper.h index 745c059784b..70dbcd7de06 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Image_to_labeled_function_wrapper.h +++ b/Mesh_3/include/CGAL/Mesh_3/Image_to_labeled_function_wrapper.h @@ -34,7 +34,8 @@ #include #include - +#include +#include namespace CGAL { @@ -47,25 +48,27 @@ namespace Mesh_3 { * N. Uses trilinear interpolation. * Note: Image has to be labeled with unsigned char */ -template, bool labeled_image = true, bool use_trilinear_interpolation=true> class Image_to_labeled_function_wrapper { public: + typedef CGAL::cpp11::function + Image_values_to_labels; + // Types typedef Return_type return_type; typedef Image_word_type word_type; - typedef typename BGT::Point_3 Point_3; + typedef CGAL::Image_3 Image_; /// Constructor - Image_to_labeled_function_wrapper(const Image_& image, - const Transform& transform = Transform(), - const Return_type value_outside = 0) + Image_to_labeled_function_wrapper + (const Image_& image, + Image_values_to_labels transform = Identity(), + const Interpolation_type value_outside = Interpolation_type()) : r_im_(image) , transform(transform) , value_outside(value_outside) @@ -82,7 +85,8 @@ public: * @param p the input point * @return the label at point \c p */ - return_type operator()(const Point_3& p, const bool = true) const + template + return_type operator()(const Point_3& p) const { return eval(p, CGAL::Boolean_tag(), @@ -90,38 +94,41 @@ public: } private: + template return_type eval(const Point_3& p, CGAL::Tag_true /*trilinear*/, CGAL::Tag_true /*labeled*/) const { return static_cast(transform( - r_im_.template labellized_trilinear_interpolation( - CGAL::to_double(p.x()), - CGAL::to_double(p.y()), - CGAL::to_double(p.z()), + r_im_.template labellized_trilinear_interpolation( + CGAL::to_double(p.x()-r_im_.image()->tx), + CGAL::to_double(p.y()-r_im_.image()->ty), + CGAL::to_double(p.z()-r_im_.image()->tz), value_outside))); } + template return_type eval(const Point_3& p, CGAL::Tag_true /*trilinear*/, CGAL::Tag_false /*labeled*/) const { return transform( - r_im_.template trilinear_interpolation( - CGAL::to_double(p.x()), - CGAL::to_double(p.y()), - CGAL::to_double(p.z()), + r_im_.template trilinear_interpolation( + CGAL::to_double(p.x()-r_im_.image()->tx), + CGAL::to_double(p.y()-r_im_.image()->ty), + CGAL::to_double(p.z()-r_im_.image()->tz), value_outside)); } - template + template return_type eval(const Point_3& p, CGAL::Tag_false /*trilinear*/, Labeled_tag /*labeled*/) const { - const std::ptrdiff_t px = static_cast(p.x()/r_im_.vx()); - const std::ptrdiff_t py = static_cast(p.y()/r_im_.vy()); - const std::ptrdiff_t pz = static_cast(p.z()/r_im_.vz()); + const std::ptrdiff_t px = static_cast((p.x()-r_im_.image()->tx)/r_im_.vx()); + const std::ptrdiff_t py = static_cast((p.y()-r_im_.image()->ty)/r_im_.vy()); + const std::ptrdiff_t pz = static_cast((p.z()-r_im_.image()->tz)/r_im_.vz()); const std::ptrdiff_t dimx = static_cast(r_im_.xdim()); const std::ptrdiff_t dimy = static_cast(r_im_.ydim()); @@ -144,8 +151,8 @@ private: /// Labeled image to wrap const Image_& r_im_; - const Transform transform; - const Return_type value_outside; + const Image_values_to_labels transform; + const Interpolation_type value_outside; }; // end class Image_to_labeled_function_wrapper diff --git a/Mesh_3/include/CGAL/Mesh_3/Implicit_to_labeled_function_wrapper.h b/Mesh_3/include/CGAL/Mesh_3/Implicit_to_labeled_function_wrapper.h deleted file mode 100644 index 5349a6ba5e3..00000000000 --- a/Mesh_3/include/CGAL/Mesh_3/Implicit_to_labeled_function_wrapper.h +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright (c) 2009 INRIA Sophia-Antipolis (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org). -// You can redistribute it and/or modify it under the terms of the GNU -// General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: GPL-3.0+ -// -// -// Author(s) : Stéphane Tayeb -// -//****************************************************************************** -// File Description : -// Implicit_to_labeling_function_wrapper and -// Implicit_vector_to_labeling_function_wrapper class declaration -// and implementation. -// -// See classes description to have more information. -//****************************************************************************** - -#ifndef CGAL_MESH_3_IMPLICIT_TO_LABELED_FUNCTION_WRAPPER_H -#define CGAL_MESH_3_IMPLICIT_TO_LABELED_FUNCTION_WRAPPER_H - -#include - -#include - -#define CGAL_DEPRECATED_HEADER "" -#define CGAL_REPLACEMENT_HEADER "" -#include - -#include - -namespace CGAL { - -namespace Mesh_3 { - -#include - -/** - * @class Implicit_to_labeled_function_wrapper - * - * This class is designed to wrap an implicit function which describes a domain - * by [p is inside if f(p)<0] to a function which takes its values into {0,1}. - * f(p)=0 means that p is outside the domain. - */ -template -class Implicit_to_labeled_function_wrapper -{ -public: - // Types - typedef int return_type; - typedef typename BGT::Point_3 Point_3; - - /// Constructor - Implicit_to_labeled_function_wrapper(const Function_& f) - : r_f_(f) {} - - // Default copy constructor and assignment operator are ok - - /// Destructor - ~Implicit_to_labeled_function_wrapper() {} - - /// Operator () - return_type operator()(const Point_3& p, const bool = true) const - { - return ( (r_f_(p)<0) ? 1 : 0 ); - } - -private: - /// Function to wrap - const Function_& r_f_; - -}; // end class Implicit_to_labeled_function_wrapper - - - -/** - * \deprecated - * - * @class Implicit_vector_to_labeled_function_wrapper - * - * Wraps a set of implicit function [f1,f2,...] to one function F which - * takes its values into N. - * - * Let p be a point. - * F(p) = 0b000000(f2(p)<0)(f1(p)<0) - * - * It can handle at most 8 functions. - */ -template -class Implicit_vector_to_labeled_function_wrapper -{ -public: - // Types - typedef int return_type; - typedef std::vector Function_vector; - typedef typename BGT::Point_3 Point_3; - - /// Constructor - Implicit_vector_to_labeled_function_wrapper(const std::vector& v) - : function_vector_(v) - { - if ( v.size() > 8 ) - { - CGAL_error_msg("We support at most 8 functions !"); - } - } - - // Default copy constructor and assignment operator are ok - - /// Destructor - ~Implicit_vector_to_labeled_function_wrapper() {} - - /// Operator () - return_type operator()(const Point_3& p, const bool = true) const - { - const int nb_func = static_cast(function_vector_.size()); - char bits = 0; - for ( int i = 0 ; i < nb_func ; ++i ) - { - // Insert value into bits : we compute fi(p) and insert result at - // bit i of bits - bits = char(bits | ( ((*function_vector_[i])(p) < 0) << i )); - } - - return ( static_cast(bits) ); - } - -private: - /// Functions to wrap - const Function_vector function_vector_; - -}; // end class Implicit_to_labeled_function_wrapper - -} // end namespace Mesh_3 - -} // end namespace CGAL - - - -#include - -#endif // CGAL_MESH_3_IMPLICIT_TO_LABELED_FUNCTION_WRAPPER_H diff --git a/Mesh_3/include/CGAL/Mesh_3/Labeled_mesh_domain_3.h b/Mesh_3/include/CGAL/Mesh_3/Labeled_mesh_domain_3.h deleted file mode 100644 index 1c8c1af7d9e..00000000000 --- a/Mesh_3/include/CGAL/Mesh_3/Labeled_mesh_domain_3.h +++ /dev/null @@ -1,636 +0,0 @@ -// Copyright (c) 2009 INRIA Sophia-Antipolis (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org). -// You can redistribute it and/or modify it under the terms of the GNU -// General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: GPL-3.0+ -// -// -// Author(s) : Stéphane Tayeb -// -//****************************************************************************** -// File Description : -// class Labeled_mesh_domain_3. See class description. -//****************************************************************************** - -#ifndef CGAL_MESH_3_LABELED_MESH_DOMAIN_3_H -#define CGAL_MESH_3_LABELED_MESH_DOMAIN_3_H - -#include - -#include - -#define CGAL_DEPRECATED_HEADER "" -#define CGAL_REPLACEMENT_HEADER "" -#include - -#include - -#include - -#include - -#include -#include -#include -#include -#include -#include - -namespace CGAL { - -namespace Mesh_3 { - -/** - * \class Labeled_mesh_domain_3 - * - * Function f must take his values into N. - * Let p be a Point. - * - f(p)=0 means that p is outside domain. - * - f(p)=a, a!=0 means that p is inside subdomain a. - * - * Any boundary facet is labelled , a, where b!=0. - */ -template -class Labeled_mesh_domain_3 -{ -public: - /// Geometric object types - typedef typename BGT::Point_3 Point_3; - typedef typename BGT::Segment_3 Segment_3; - typedef typename BGT::Ray_3 Ray_3; - typedef typename BGT::Line_3 Line_3; - typedef typename BGT::Vector_3 Vector_3; - typedef typename BGT::Sphere_3 Sphere_3; - typedef CGAL::Bbox_3 Bbox_3; - - typedef typename BGT::Iso_cuboid_3 Iso_cuboid_3; - -public: - // Kernel_traits compatibility - typedef BGT R; - - //------------------------------------------------------- - // Index Types - //------------------------------------------------------- - /// Type of indexes for cells of the input complex - typedef typename Function::return_type Subdomain_index; - typedef boost::optional Subdomain; - /// Type of indexes for surface patch of the input complex - typedef std::pair Surface_patch_index; - typedef boost::optional Surface_patch; - /// Type of indexes to characterize the lowest dimensional face of the input - /// complex on which a vertex lie - typedef boost::variant Index; - typedef CGAL::cpp11::tuple Intersection; - - - typedef typename BGT::FT FT; - typedef BGT Geom_traits; - - /** - * @brief Constructor - */ - Labeled_mesh_domain_3(const Function& f, - const Sphere_3& bounding_sphere, - const FT& error_bound = FT(1e-3), - CGAL::Random* p_rng = NULL); - - Labeled_mesh_domain_3(const Function& f, - const Bbox_3& bbox, - const FT& error_bound = FT(1e-3), - CGAL::Random* p_rng = NULL); - - /// Destructor - virtual ~Labeled_mesh_domain_3() - { - if(delete_rng_) - delete p_rng_; - } - - /** - * Returns a bounding box of the domain - */ - Bbox_3 bbox() const { - return this->bbox_.bbox(); - } - - /** - * Constructs a set of \ccc{n} points on the surface, and output them to - * the output iterator \ccc{pts} whose value type is required to be - * \ccc{std::pair}. - */ - struct Construct_initial_points - { - Construct_initial_points(const Labeled_mesh_domain_3& domain) - : r_domain_(domain) {} - - template - OutputIterator operator()(OutputIterator pts, const int n = 12) const; - - private: - const Labeled_mesh_domain_3& r_domain_; - }; - - /// Returns Construct_initial_points object - Construct_initial_points construct_initial_points_object() const - { - return Construct_initial_points(*this); - } - - /** - * Returns true if point~\ccc{p} is in the domain. If \ccc{p} is in the - * domain, the parameter index is set to the index of the subdomain - * including $p$. It is set to the default value otherwise. - */ - struct Is_in_domain - { - Is_in_domain(const Labeled_mesh_domain_3& domain) : r_domain_(domain) {} - - Subdomain operator()(const Point_3& p) const - { - // f(p)==0 means p is outside the domain - Subdomain_index index = (r_domain_.function_)(p); - if ( Subdomain_index() == index ) - return Subdomain(); - else - return Subdomain(index); - } - private: - const Labeled_mesh_domain_3& r_domain_; - }; - - /// Returns Is_in_domain object - Is_in_domain is_in_domain_object() const { return Is_in_domain(*this); } - - /** - * Returns true is the element \ccc{type} intersect properly any of the - * surface patches describing the either the domain boundary or some - * subdomain boundary. - * \ccc{Type} is either \ccc{Segment_3}, \ccc{Ray_3} or \ccc{Line_3}. - * Parameter index is set to the index of the intersected surface patch - * if \ccc{true} is returned and to the default \ccc{Surface_patch_index} - * value otherwise. - */ - struct Do_intersect_surface - { - Do_intersect_surface(const Labeled_mesh_domain_3& domain) - : r_domain_(domain) {} - - Surface_patch operator()(const Segment_3& s) const - { - return this->operator()(s.source(), s.target()); - } - - Surface_patch operator()(const Ray_3& r) const - { - return clip_to_segment(r); - } - - Surface_patch operator()(const Line_3& l) const - { - return clip_to_segment(l); - } - - private: - /// Returns true if points \c a & \c b do not belong to the same subdomain - /// \c index is set to the surface index of subdomains f(a), f(b) - Surface_patch operator()(const Point_3& a, const Point_3& b) const - { - // If f(a) != f(b), then [a,b] intersects some surface. Here we consider - // [a,b] intersects surface_patch labelled (or ). - // It may be false, further rafinement will improve precision - const Subdomain_index value_a = r_domain_.function_(a); - const Subdomain_index value_b = r_domain_.function_(b); - - if ( value_a != value_b ) - return Surface_patch(r_domain_.make_surface_index(value_a, value_b)); - else - return Surface_patch(); - } - - /** - * Clips \c query to a segment \c s, and call operator()(s) - */ - template - Surface_patch clip_to_segment(const Query& query) const - { - typename cpp11::result_of::type - clipped = CGAL::intersection(query, r_domain_.bbox_); - - if(clipped) -#if CGAL_INTERSECTION_VERSION > 1 - if(const Segment_3* s = boost::get(&*clipped)) - return this->operator()(*s); -#else - if(const Segment_3* s = object_cast(&clipped)) - return this->operator()(*s); -#endif - - return Surface_patch(); - } - - private: - const Labeled_mesh_domain_3& r_domain_; - }; - - /// Returns Do_intersect_surface object - Do_intersect_surface do_intersect_surface_object() const - { - return Do_intersect_surface(*this); - } - - /** - * Returns a point in the intersection of the primitive \ccc{type} - * with some boundary surface. - * \ccc{Type1} is either \ccc{Segment_3}, \ccc{Ray_3} or \ccc{Line_3}. - * The integer \ccc{dimension} is set to the dimension of the lowest - * dimensional face in the input complex containing the returned point, and - * \ccc{index} is set to the index to be stored at a mesh vertex lying - * on this face. - */ - struct Construct_intersection - { - Construct_intersection(const Labeled_mesh_domain_3& domain) - : r_domain_(domain) {} - - Intersection operator()(const Segment_3& s) const - { -#ifndef CGAL_MESH_3_NO_LONGER_CALLS_DO_INTERSECT_3 - CGAL_precondition(r_domain_.do_intersect_surface_object()(s)); -#endif // NOT CGAL_MESH_3_NO_LONGER_CALLS_DO_INTERSECT_3 - return this->operator()(s.source(),s.target()); - } - - Intersection operator()(const Ray_3& r) const - { - return clip_to_segment(r); - } - - Intersection operator()(const Line_3& l) const - { - return clip_to_segment(l); - } - - private: - /** - * Returns a point in the intersection of [a,b] with the surface - * \c a must be the source point, and \c b the out point. It's important - * because it drives bisection cuts. - * Indeed, the returned point is the first intersection from \c [a,b] - * with a subdomain surface. - */ - Intersection operator()(const Point_3& a, const Point_3& b) const - { - // Functors - typename BGT::Compute_squared_distance_3 squared_distance = - BGT().compute_squared_distance_3_object(); - typename BGT::Construct_midpoint_3 midpoint = - BGT().construct_midpoint_3_object(); - - // Non const points - Point_3 p1 = a; - Point_3 p2 = b; - Point_3 mid = midpoint(p1, p2); - - // Cannot be const: those values are modified below. - Subdomain_index value_at_p1 = r_domain_.function_(p1); - Subdomain_index value_at_p2 = r_domain_.function_(p2); - Subdomain_index value_at_mid = r_domain_.function_(mid,true); - - // If both extremities are in the same subdomain, - // there is no intersection. - // This should not happen... - if( value_at_p1 == value_at_p2 ) - { - return Intersection(); - } - - // Construct the surface patch index and index from the values at 'a' - // and 'b'. Even if the bissection find out a different pair of - // values, the reported index will be constructed from the initial - // values. - const Surface_patch_index sp_index = - r_domain_.make_surface_index(value_at_p1, value_at_p2); - const Index index = r_domain_.index_from_surface_patch_index(sp_index); - - // Else lets find a point (by bisection) - // Bisection ends when the point is near than error bound from surface - while(true) - { - // If the two points are enough close, then we return midpoint - if ( squared_distance(p1, p2) < r_domain_.squared_error_bound_ ) - { - CGAL_assertion(value_at_p1 != value_at_p2); - return Intersection(mid, index, 2); - } - - // Else we must go on - // Here we consider that p1(a) is the source point. Thus, we keep p1 and - // change p2 if f(p1)!=f(p2). - // That allows us to find the first intersection from a of [a,b] with - // a surface. - if ( value_at_p1 != value_at_mid ) - { - p2 = mid; - value_at_p2 = value_at_mid; - } - else - { - p1 = mid; - value_at_p1 = value_at_mid; - } - - mid = midpoint(p1, p2); - value_at_mid = r_domain_.function_(mid,true); - } - } - - /// Clips \c query to a segment \c s, and call operator()(s) - template - Intersection clip_to_segment(const Query& query) const - { - typename cpp11::result_of::type - clipped = CGAL::intersection(query, r_domain_.bbox_); - - if(clipped) -#if CGAL_INTERSECTION_VERSION > 1 - if(const Segment_3* s = boost::get(&*clipped)) - return this->operator()(*s); -#else - if(const Segment_3* s = object_cast(&clipped)) - return this->operator()(*s); -#endif - - return Intersection(); - } - - private: - const Labeled_mesh_domain_3& r_domain_; - }; - - /// Returns Construct_intersection object - Construct_intersection construct_intersection_object() const - { - return Construct_intersection(*this); - } - - /** - * Returns the index to be stored in a vertex lying on the surface identified - * by \c index. - */ - Index index_from_surface_patch_index(const Surface_patch_index& index) const - { return Index(index); } - - /** - * Returns the index to be stored in a vertex lying in the subdomain - * identified by \c index. - */ - Index index_from_subdomain_index(const Subdomain_index& index) const - { return Index(index); } - - /** - * Returns the \c Surface_patch_index of the surface patch - * where lies a vertex with dimension 2 and index \c index. - */ - Surface_patch_index surface_patch_index(const Index& index) const - { return boost::get(index); } - - /** - * Returns the index of the subdomain containing a vertex - * with dimension 3 and index \c index. - */ - Subdomain_index subdomain_index(const Index& index) const - { return boost::get(index); } - - // ----------------------------------- - // Backward Compatibility - // ----------------------------------- -#ifndef CGAL_MESH_3_NO_DEPRECATED_SURFACE_INDEX - typedef Surface_patch_index Surface_index; - - Index index_from_surface_index(const Surface_index& index) const - { return index_from_surface_patch_index(index); } - - Surface_index surface_index(const Index& index) const - { return surface_patch_index(index); } -#endif // CGAL_MESH_3_NO_DEPRECATED_SURFACE_INDEX - // ----------------------------------- - // End backward Compatibility - // ----------------------------------- - - -private: - /// Returns Surface_patch_index from \c i and \c j - Surface_patch_index make_surface_index(const Subdomain_index i, - const Subdomain_index j) const - { - if ( i < j ) return Surface_patch_index(i,j); - else return Surface_patch_index(j,i); - } - - /// Returns squared error bound from \c bbox and \c error - FT squared_error_bound(const Iso_cuboid_3& bbox, const FT& error) const - { - typename BGT::Compute_squared_distance_3 squared_distance = - BGT().compute_squared_distance_3_object(); - return squared_distance((bbox.min)(), (bbox.max)())*error*error/4; - } - - /// Returns squared error bound from \c sphere and \c error - FT squared_error_bound(const Sphere_3& sphere, const FT& error) const - { - typename BGT::Compute_squared_radius_3 squared_radius = - BGT().compute_squared_radius_3_object(); - return squared_radius(sphere)*error*error; - } - - /// Returns the bounding sphere of an Iso_cuboid_3 - Sphere_3 bounding_sphere(const Iso_cuboid_3& bbox) const - { - typename BGT::Construct_sphere_3 sphere = BGT().construct_sphere_3_object(); - return sphere((bbox.min)(), (bbox.max)()); - } - - /// Returns and Iso_cuboid_3 from a Bbox_3 - Iso_cuboid_3 iso_cuboid(const Bbox_3& bbox) - { - const Point_3 p_min(bbox.xmin(), bbox.ymin(), bbox.zmin()); - const Point_3 p_max(bbox.xmax(), bbox.ymax(), bbox.zmax()); - - return Iso_cuboid_3(p_min,p_max); - } - -protected: - /// Returns bounding box - const Iso_cuboid_3& bounding_box() const { return bbox_; } - -private: - /// The function which answers subdomain queries - const Function function_; - /// The bounding box - const Iso_cuboid_3 bbox_; - /// The random number generator used by Construct_initial_points - CGAL::Random* p_rng_; - bool delete_rng_; - /// Error bound relative to sphere radius - FT squared_error_bound_; - - -private: - // Disabled copy constructor & assignment operator - typedef Labeled_mesh_domain_3 Self; - Labeled_mesh_domain_3(const Self& src); - Self& operator=(const Self& src); - -}; // end class Labeled_mesh_domain_3 - - - - -//------------------------------------------------------- -// Method implementation -//------------------------------------------------------- -template -Labeled_mesh_domain_3::Labeled_mesh_domain_3( - const F& f, - const Sphere_3& bounding_sphere, - const FT& error_bound, - CGAL::Random* p_rng) -: function_(f) -, bbox_(iso_cuboid(bounding_sphere.bbox())) -, p_rng_(p_rng) -, delete_rng_(false) -, squared_error_bound_(squared_error_bound(bounding_sphere,error_bound)) -{ - // TODO : CGAL_ASSERT(0 < f(bounding_sphere.get_center()) ) ? - if(!p_rng_) - { - p_rng_ = new CGAL::Random(0); - delete_rng_ = true; - } -} - -template -Labeled_mesh_domain_3::Labeled_mesh_domain_3( - const F& f, - const Bbox_3& bbox, - const FT& error_bound, - CGAL::Random* p_rng) -: function_(f) -, bbox_(iso_cuboid(bbox)) -, p_rng_(p_rng) -, delete_rng_(false) -, squared_error_bound_(squared_error_bound(bbox_,error_bound)) -{ - // TODO : CGAL_ASSERT(0 < f(bounding_sphere.get_center()) ) ? - if(!p_rng_) - { - p_rng_ = new CGAL::Random(0); - delete_rng_ = true; - } -} - - -template -template -OutputIterator -Labeled_mesh_domain_3::Construct_initial_points::operator()( - OutputIterator pts, - const int nb_points) const -{ - // Create point_iterator on and in bounding_sphere - typedef Random_points_on_sphere_3 Random_points_on_sphere_3; - typedef Random_points_in_sphere_3 Random_points_in_sphere_3; - - - const FT squared_radius = BGT().compute_squared_radius_3_object()( - r_domain_.bounding_sphere(r_domain_.bbox_)); - - const double radius = std::sqrt(CGAL::to_double(squared_radius)); - - CGAL::Random& rng = *(r_domain_.p_rng_); - Random_points_on_sphere_3 random_point_on_sphere(radius, rng); - Random_points_in_sphere_3 random_point_in_sphere(radius, rng); - - // Get some functors - typename BGT::Construct_segment_3 segment_3 = - BGT().construct_segment_3_object(); - typename BGT::Construct_vector_3 vector_3 = - BGT().construct_vector_3_object(); - typename BGT::Construct_translated_point_3 translate = - BGT().construct_translated_point_3_object(); - typename BGT::Construct_center_3 center = BGT().construct_center_3_object(); - - // Get translation from origin to sphere center - Point_3 center_pt = center(r_domain_.bounding_sphere(r_domain_.bbox_)); - const Vector_3 sphere_translation = vector_3(CGAL::ORIGIN, center_pt); - - // Create nb_point points - int n = nb_points; -#ifdef CGAL_MESH_3_VERBOSE - std::cerr << "construct initial points:\n"; -#endif - while ( 0 != n ) - { - // Get a random segment - const Point_3 random_point = translate(*random_point_on_sphere, - sphere_translation); - const Segment_3 random_seg = segment_3(center_pt, random_point); - - // Add the intersection to the output if it exists - Surface_patch surface = r_domain_.do_intersect_surface_object()(random_seg); - if ( surface ) - { - const Point_3 intersect_pt = CGAL::cpp11::get<0>( - r_domain_.construct_intersection_object()(random_seg)); - *pts++ = std::make_pair(intersect_pt, - r_domain_.index_from_surface_patch_index(*surface)); - --n; - -#ifdef CGAL_MESH_3_VERBOSE - std::cerr << boost::format("\r \r" - "%1%/%2% initial point(s) found...") - % (nb_points - n) - % nb_points; -#endif - } - else - { - // Get a new random point into sphere as center of object - // It may be necessary if the center of the domain is empty, e.g. torus - // In general case, it is good for input point dispersion - ++random_point_in_sphere; - center_pt = translate(*random_point_in_sphere, sphere_translation); - } - ++random_point_on_sphere; - } - -#ifdef CGAL_MESH_3_VERBOSE - std::cerr << "\n"; -#endif - return pts; -} - - -} // end namespace Mesh_3 - -} // end namespace CGAL - -#include - -#endif // LABELLED_MESH_TRAITS_3_H_ diff --git a/Mesh_3/include/CGAL/Mesh_3/Mesher_3.h b/Mesh_3/include/CGAL/Mesh_3/Mesher_3.h index d0ee40fb0d7..a8e60a55232 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Mesher_3.h +++ b/Mesh_3/include/CGAL/Mesh_3/Mesher_3.h @@ -461,6 +461,18 @@ refine_mesh(std::string dump_after_refine_surface_prefix) % r_tr.number_of_vertices() % nbsteps % cells_mesher_.debug_info() % (nbsteps / timer.time()); + if(refinement_stage == REFINE_FACETS && + facets_mesher_.is_algorithm_done()) + { + facets_mesher_.scan_edges(); + refinement_stage = REFINE_FACETS_AND_EDGES; + } + if(refinement_stage == REFINE_FACETS_AND_EDGES && + facets_mesher_.is_algorithm_done()) + { + facets_mesher_.scan_vertices(); + refinement_stage = REFINE_FACETS_AND_EDGES_AND_VERTICES; + } ++nbsteps; } std::cerr << std::endl; diff --git a/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h b/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h index 37a2f7d0d71..7f2e66af85c 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h +++ b/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h @@ -44,9 +44,12 @@ # include #endif #ifdef CGAL_MESH_3_DUMP_FEATURES_PROTECTION_ITERATIONS -#include +# include #endif #include +#if CGAL_MESH_3_PROTECTION_DEBUG +# include +#endif namespace CGAL { namespace Mesh_3 { diff --git a/Mesh_3/include/CGAL/Mesh_3/polylines_to_protect.h b/Mesh_3/include/CGAL/Mesh_3/polylines_to_protect.h index 1fc27924116..36fcf7d26a0 100644 --- a/Mesh_3/include/CGAL/Mesh_3/polylines_to_protect.h +++ b/Mesh_3/include/CGAL/Mesh_3/polylines_to_protect.h @@ -33,10 +33,10 @@ #include #include #include -#include // for - // CGAL::Null_subdomain_index +#include // for CGAL::Null_subdomain_index #include // for boost::prior #include +#include #include #include @@ -58,6 +58,201 @@ struct Returns_midpoint { = K().construct_midpoint_3_object(); return a < b ? midpt(a, b) : midpt(b, a); } + double operator()(const NT, + const NT) const + { + return 0.5; + } +}; + +template +struct Linear_interpolator { + typedef typename K::Point_3 Point_3; + + Point_3 interpolate(const Point_3& pa, + const Point_3& pb, + const NT a, + const NT b) const + { + return pa + (a / (a - b)) * ( pb - pa); + } + + + Point_3 operator()(const Point_3& pa, + const Point_3& pb, + const NT a, + const NT b) const + { + return + (a < b) ? + interpolate(pa, pb, a, b) : + interpolate(pb, pa, b, a); + } + double operator()(const NT a, + const NT b) const + { + return a / ( a - b ); + } +}; + + +class Isoline_equation { + double a; + double b; + double c; + double d; + +public: + Isoline_equation(double a, double b, double c, double d) + : a(a) + , b(b) + , c(c) + , d(d) + {} + + double y(double x) const { + return ( x*(a-b)-a ) / + ( c-a+x*(a-b-c+d) ); + // If (a+d) == (b+c), then the curve is a straight line. + } + double x(double y) const { + return ( y*(a-c)-a ) / + ( b-a+y*(a-b-c+d) ); + // If (a+d) == (b+c), then the curve is a straight line. + } +}; // end of class Isoline_equation + +template +class Insert_curve_in_graph { + typedef typename Geom_traits::Point_3 Point; + typedef typename Geom_traits::Vector_3 Vector; + + G_manip& g_manip; + const vertex_descriptor null_vertex; + const Geom_traits& gt; + const typename Geom_traits::Construct_translated_point_3 translate; + const typename Geom_traits::Construct_scaled_vector_3 scale; + const int prec; + const double max_squared_distance; + +public: + Insert_curve_in_graph(G_manip& g_manip, + const Geom_traits& gt, + const int prec = 10, + const double max_squared_distance = 0) + : g_manip(g_manip) + , null_vertex(g_manip.null_vertex()) + , gt(gt) + , translate(gt.construct_translated_point_3_object()) + , scale(gt.construct_scaled_vector_3_object()) + , prec(prec) + , max_squared_distance(max_squared_distance) + {} + + struct Coords { + Coords(double x, double y) : x(x), y(y) {} + double x; + double y; + }; + + void insert_curve(Isoline_equation equation, + vertex_descriptor start_v, + vertex_descriptor end_v, + Coords start, + Coords end, + Point p00, + Vector vx, + Vector vy) + { + if(CGAL::abs(start.x - end.x) >= CGAL::abs(start.y - end.y)) { + insert_curve(equation, &Isoline_equation::y, + start_v, end_v, + start.x, end.x, p00, vx, vy); + } else { + insert_curve(equation, &Isoline_equation::x, + start_v, end_v, + start.y, end.y, p00, vy, vx); + } + } +private: + void insert_curve(Isoline_equation equation, + double (Isoline_equation::* f)(double) const, + vertex_descriptor start_v, + vertex_descriptor end_v, + double start, + double end, + Point p00, + Vector vx, + Vector vy) + { +#ifdef CGAL_MESH_3_DEBUG_POLYLINES_TO_PROTECT + std::cerr << "New curve:\n"; +#endif // CGAL_MESH_3_DEBUG_POLYLINES_TO_PROTECT + const double step = (end - start)/prec; + const double stop = end-step/2; + const bool step_is_positive = (step > 0); + vertex_descriptor old = start_v; + vertex_descriptor v_int = null_vertex; + for(double x = start + step; + (step_is_positive ? x < stop : x > stop); + x += step) + { + const double y = (equation.*f)(x); +#ifdef CGAL_MESH_3_DEBUG_POLYLINES_TO_PROTECT + std::cerr << " (" << x << ", " << y << ")\n"; +#endif // CGAL_MESH_3_DEBUG_POLYLINES_TO_PROTECT + const Point inter_p = + translate(translate(p00, + scale(vx, x)), + scale(vy, y)); + v_int = g_manip.get_vertex(inter_p, false); + g_manip.try_add_edge(old, v_int); + +#ifndef CGAL_CFG_NO_CPP0X_LAMBDAS + CGAL_assertion_msg(max_squared_distance == 0 || + CGAL::squared_distance(g_manip.g[old].point, + g_manip.g[v_int].point) < + max_squared_distance, + ([this, old, v_int] { + std::stringstream s; + s << "Problem at segment (" + << this->g_manip.g[old].point << ", " + << this->g_manip.g[v_int].point << ")"; + return s.str(); + }().c_str())); +#else // no C++ lamdbas + CGAL_assertion(max_squared_distance == 0 || + CGAL::squared_distance(g_manip.g[old].point, + g_manip.g[v_int].point) < + max_squared_distance); +#endif // no C++ lamdbas + + old = v_int; + } + if(null_vertex != v_int) { + // v_int can be null if the curve is degenerated into one point. + g_manip.try_add_edge(v_int, end_v); +#ifndef CGAL_CFG_NO_CPP0X_LAMBDAS + CGAL_assertion_msg(max_squared_distance == 0 || + CGAL::squared_distance(g_manip.g[end_v].point, + g_manip.g[v_int].point) < + max_squared_distance, + ([this, end_v, v_int] { + std::stringstream s; + s << "Problem at segment (" + << this->g_manip.g[end_v].point << ", " + << this->g_manip.g[v_int].point << ")"; + return s.str(); + }().c_str())); +#else // no C++ lamdbas + CGAL_assertion(max_squared_distance == 0 || + CGAL::squared_distance(g_manip.g[end_v].point, + g_manip.g[v_int].point) < + max_squared_distance); +#endif // no C++ lamdbas + + } + } }; template }} // namespaces: end Mesh_3, end internal @@ -107,7 +303,7 @@ struct Polyline_visitor void add_node(typename boost::graph_traits::vertex_descriptor vd) { std::vector

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

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

::Kernel K; - typedef boost::adjacency_list Graph; + using CGAL::internal::polylines_to_protect_namespace::Vertex_info; + typedef boost::adjacency_list > Graph; typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; typedef typename std::iterator_traits::value_type Polyline; @@ -727,8 +1034,8 @@ polylines_to_protect(std::vector >& polylines, typename Polyline::iterator pit = polyline.begin(); while (boost::next(pit) != polyline.end()) { - vertex_descriptor v = g_manip.get_vertex(*pit); - vertex_descriptor w = g_manip.get_vertex(*boost::next(pit)); + vertex_descriptor v = g_manip.get_vertex(*pit, false); + vertex_descriptor w = g_manip.get_vertex(*boost::next(pit), false); g_manip.try_add_edge(v, w); ++pit; } diff --git a/Mesh_3/include/CGAL/Mesh_criteria_3.h b/Mesh_3/include/CGAL/Mesh_criteria_3.h index ecb5ead9ffb..57854afdeb5 100644 --- a/Mesh_3/include/CGAL/Mesh_criteria_3.h +++ b/Mesh_3/include/CGAL/Mesh_criteria_3.h @@ -33,6 +33,7 @@ #include #include +#include #include #include #include diff --git a/Mesh_3/include/CGAL/Mesh_domain_with_polyline_features_3.h b/Mesh_3/include/CGAL/Mesh_domain_with_polyline_features_3.h index 312d17274d1..4b7da73de33 100644 --- a/Mesh_3/include/CGAL/Mesh_domain_with_polyline_features_3.h +++ b/Mesh_3/include/CGAL/Mesh_domain_with_polyline_features_3.h @@ -47,6 +47,10 @@ #include // for boost::prior and boost::next #include #include +#include +#include +#include +#include namespace CGAL { @@ -538,6 +542,7 @@ template < typename MeshDomain_3 > class Mesh_domain_with_polyline_features_3 : public MeshDomain_3 { + typedef Mesh_domain_with_polyline_features_3 Self; public: /// \name Types /// @{ @@ -563,24 +568,11 @@ public: typedef typename MeshDomain_3::Point_3 Point_3; #endif // DOXYGEN_RUNNING -#ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES /// \name Creation +/// Constructors. Forwards the arguments to the constructor +/// of the base class. /// @{ -/*! -Constructor. Forwards the arguments to the constructor -of the base class. -*/ - template - Mesh_domain_with_polyline_features_3(const T& ...t) - : MeshDomain_3(t...) - , current_corner_index_(1) - , current_curve_index_(1) - , curves_aabb_tree_is_built(false) {} -/// @} -#else - /// Constructors - /// Call the base class constructor Mesh_domain_with_polyline_features_3() : MeshDomain_3() , current_corner_index_(1) @@ -588,12 +580,25 @@ of the base class. , curves_aabb_tree_is_built(false) {} template - Mesh_domain_with_polyline_features_3(const T1& o1) + Mesh_domain_with_polyline_features_3 + (const T1& o1, typename boost::disable_if, + CGAL::Tag_false>::type* = 0) : MeshDomain_3(o1) , current_corner_index_(1) , current_curve_index_(1) , curves_aabb_tree_is_built(false) {} +#ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES + template + Mesh_domain_with_polyline_features_3(const T1& o1, const T2& o2, const T& ...o) + : MeshDomain_3(o1, o2, o...) + , current_corner_index_(1) + , current_curve_index_(1) + , curves_aabb_tree_is_built(false) {} +/// @} +#else + /// Constructors + /// Call the base class constructor template Mesh_domain_with_polyline_features_3(const T1& o1, const T2& o2) : MeshDomain_3(o1, o2) @@ -866,7 +871,7 @@ public: typedef CGAL::AABB_tree Curves_AABB_tree; private: - mutable Curves_AABB_tree curves_aabb_tree_; + mutable boost::shared_ptr curves_aabb_tree_ptr_; mutable bool curves_aabb_tree_is_built; public: @@ -875,7 +880,7 @@ public: const Curves_AABB_tree& curves_aabb_tree() const { if(!curves_aabb_tree_is_built) build_curves_aabb_tree(); - return curves_aabb_tree_; + return *curves_aabb_tree_ptr_; } Curve_index maximal_curve_index() const { if(edges_incidences_.empty()) return Curve_index(); @@ -888,7 +893,11 @@ public: CGAL::Real_timer timer; timer.start(); #endif - curves_aabb_tree_.clear(); + if(curves_aabb_tree_ptr_) { + curves_aabb_tree_ptr_->clear(); + } else { + curves_aabb_tree_ptr_ = boost::make_shared(); + } for(typename Edges::const_iterator edges_it = edges_.begin(), edges_end = edges_.end(); @@ -900,10 +909,10 @@ public: end = polyline.points_.end() - 1; pit != end; ++pit) { - curves_aabb_tree_.insert(std::make_pair(edges_it, pit)); + curves_aabb_tree_ptr_->insert(std::make_pair(edges_it, pit)); } } - curves_aabb_tree_.build(); + curves_aabb_tree_ptr_->build(); curves_aabb_tree_is_built = true; #if CGAL_MESH_3_VERBOSE timer.stop(); @@ -911,12 +920,6 @@ public: #endif } // end build_curves_aabb_tree() /// @endcond -private: - // Disabled copy constructor & assignment operator - typedef Mesh_domain_with_polyline_features_3 Self; - Mesh_domain_with_polyline_features_3(const Self& src); - Self& operator=(const Self& src); - }; // end class Mesh_domain_with_polyline_features_3 diff --git a/Mesh_3/include/CGAL/Polyhedral_complex_mesh_domain_3.h b/Mesh_3/include/CGAL/Polyhedral_complex_mesh_domain_3.h index 52e5996cde2..600de3aeb0c 100644 --- a/Mesh_3/include/CGAL/Polyhedral_complex_mesh_domain_3.h +++ b/Mesh_3/include/CGAL/Polyhedral_complex_mesh_domain_3.h @@ -885,7 +885,6 @@ add_features_from_split_graph_into_polylines(Featured_edges_copy_graph& g_copy) std::vector polylines; internal::Mesh_3::Extract_polyline_with_context_visitor< - Polyhedral_complex_mesh_domain_3, Polyline_with_context, Featured_edges_copy_graph > visitor(g_copy, polylines); diff --git a/Mesh_3/include/CGAL/Polyhedral_mesh_domain_3.h b/Mesh_3/include/CGAL/Polyhedral_mesh_domain_3.h index 755835811a3..45cdf910255 100644 --- a/Mesh_3/include/CGAL/Polyhedral_mesh_domain_3.h +++ b/Mesh_3/include/CGAL/Polyhedral_mesh_domain_3.h @@ -32,7 +32,6 @@ #include -#include #include #include @@ -68,6 +67,8 @@ // default) #include +#include + namespace CGAL { namespace Mesh_3 { @@ -82,24 +83,6 @@ max_length(const Bbox_3& b) (std::max)(b.ymax()-b.ymin(),b.zmax()-b.zmin()) ); } -// ----------------------------------- -// Index_generator -// Don't use boost::variant if types are the same type -// ----------------------------------- -template < typename Subdomain_index, typename Surface_patch_index > -struct Index_generator -{ - typedef boost::variant Index; - typedef Index type; -}; - -template < typename T > -struct Index_generator -{ - typedef T Index; - typedef Index type; -}; - // ----------------------------------- // Geometric traits generator // ----------------------------------- @@ -213,7 +196,7 @@ public: typedef boost::optional Surface_patch; /// Type of indexes to characterize the lowest dimensional face of the input /// complex on which a vertex lie - typedef typename Mesh_3::details::Index_generator< + typedef typename internal::Mesh_3::Index_generator< Subdomain_index, Surface_patch_index>::type Index; typedef CGAL::cpp11::tuple Intersection; diff --git a/Mesh_3/include/CGAL/Polyhedral_mesh_domain_with_features_3.h b/Mesh_3/include/CGAL/Polyhedral_mesh_domain_with_features_3.h index 2240b0f1080..cf7e50f8cbc 100644 --- a/Mesh_3/include/CGAL/Polyhedral_mesh_domain_with_features_3.h +++ b/Mesh_3/include/CGAL/Polyhedral_mesh_domain_with_features_3.h @@ -138,6 +138,8 @@ public: this->build(); } +#ifndef CGAL_NO_DEPRECATED_CODE + CGAL_DEPRECATED Polyhedral_mesh_domain_with_features_3(const std::string& filename, CGAL::Random* p_rng = NULL) @@ -156,6 +158,7 @@ public: { load_from_file(filename); } +#endif // not CGAL_NO_DEPRECATED_CODE Polyhedral_mesh_domain_with_features_3(const Polyhedron& p, const Polyhedron& bounding_p, @@ -392,7 +395,6 @@ add_features_from_split_graph_into_polylines(Featured_edges_copy_graph& g_copy) std::vector polylines; internal::Mesh_3::Extract_polyline_with_context_visitor< - Polyhedral_mesh_domain_with_features_3, Polyline_with_context, Featured_edges_copy_graph > visitor(g_copy, polylines); diff --git a/Mesh_3/include/CGAL/exude_mesh_3.h b/Mesh_3/include/CGAL/exude_mesh_3.h index 04dad363b92..9f4a018cea5 100644 --- a/Mesh_3/include/CGAL/exude_mesh_3.h +++ b/Mesh_3/include/CGAL/exude_mesh_3.h @@ -35,6 +35,7 @@ #include #include #include +#include namespace CGAL { diff --git a/Mesh_3/include/CGAL/internal/Mesh_3/Graph_manipulations.h b/Mesh_3/include/CGAL/internal/Mesh_3/Graph_manipulations.h index fec1373724e..3d3f8d4957a 100644 --- a/Mesh_3/include/CGAL/internal/Mesh_3/Graph_manipulations.h +++ b/Mesh_3/include/CGAL/internal/Mesh_3/Graph_manipulations.h @@ -54,22 +54,43 @@ struct Graph_manipulations , interpolate(interpolate) {} - vertex_descriptor get_vertex(const Point_3& p) { + static vertex_descriptor null_vertex() { + return boost::graph_traits::null_vertex(); + } + + vertex_descriptor get_vertex(const Point_3& p, bool force_terminal) { typename std::map::iterator it = p2v.find(p); if(it == p2v.end()){ vertex_descriptor v0 = add_vertex(g); p2v[p] = v0; g[v0] = p; + g[v0].force_terminal = force_terminal; return v0; } else { return it->second; } } + template + vertex_descriptor split(const Enriched_pixel& epa, + const Enriched_pixel& epb, + const Null& null) + { + return split(epa.point, + epb.point, + epa.word, + epb.word, + null(epa.domain), + null(epb.domain), + epa.on_edge_of_the_cube, + epb.on_edge_of_the_cube); + } + vertex_descriptor split(const Point_3& a, const Point_3& b, const NT v_a, const NT v_b, - bool a_is_outside, bool b_is_outside) + bool a_is_outside, bool b_is_outside, + bool a_on_edge, bool b_on_edge) { #ifdef CGAL_MESH_3_DEBUG_GRAPH_MANIPULATION std::cerr << "split(" << a << ", " << b << ", " @@ -78,7 +99,7 @@ struct Graph_manipulations #endif // CGAL_MESH_3_DEBUG_GRAPH_MANIPULATION const Point_3 mid = interpolate(a, b, v_a, v_b); - vertex_descriptor vmid = get_vertex(mid); + vertex_descriptor vmid = get_vertex(mid, a_on_edge && b_on_edge); typename std::map::iterator it_a = p2v.find(a), it_b = p2v.find(b); @@ -108,8 +129,11 @@ struct Graph_manipulations bool try_add_edge(vertex_descriptor v1, vertex_descriptor v2) { #ifdef CGAL_MESH_3_DEBUG_GRAPH_MANIPULATION - std::cerr << "try_add_edge(" << v1 << " (" << g[v1] - << "), " << v2 << " (" << g[v2] << "))\n"; + std::cerr << "try_add_edge(" << v1 << " (" << g[v1].point + << ", " << std::boolalpha << g[v1].force_terminal + << "), " << v2 << " (" << g[v2].point + << ", " << std::boolalpha << g[v2].force_terminal + << "))\n"; #endif // CGAL_MESH_3_DEBUG_GRAPH_MANIPULATION if(v1 != v2) { edge_descriptor edge; diff --git a/Mesh_3/include/CGAL/internal/Mesh_3/get_index.h b/Mesh_3/include/CGAL/internal/Mesh_3/get_index.h index 8b091e5a1a0..df6b1d681f9 100644 --- a/Mesh_3/include/CGAL/internal/Mesh_3/get_index.h +++ b/Mesh_3/include/CGAL/internal/Mesh_3/get_index.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 INRIA Sophia-Antipolis (France). +// Copyright (c) 2018 GeometryFactory Sarl (France). // All rights reserved. // // This file is part of CGAL (www.cgal.org). @@ -16,12 +16,11 @@ // $Id$ // SPDX-License-Identifier: GPL-3.0+ // -// Author(s) : Stéphane Tayeb +// Author(s) : Laurent Rineau // //****************************************************************************** -// File Description : -// -// +// File Description : trivial backward-compatibility for undocumented +// classes/function templates //****************************************************************************** #ifndef CGAL_INTERNAL_MESH_3_GET_INDEX_3_H @@ -29,146 +28,6 @@ #include +#include -#include -#include -#include - -namespace CGAL { -namespace internal { -namespace Mesh_3 { - - -template -const T& get_index(const Boost_variant& x, - typename boost::disable_if >::type * = 0) -{ return boost::get(x); } - -template -const T& get_index(const T& x) { return x; } - -template ::value> -struct Read_mesh_domain_index { - // here we have has_feature==true - - typedef Mesh_domain MT; // was named "mesh traits" previously - - typename Mesh_domain::Index - operator()(int dimension, std::istream& is) const { - switch(dimension) { - case 0: - typename MT::Corner_index ci; - if(is_ascii(is)) is >> ci; - else CGAL::read(is, ci); - return ci; - break; - case 1: - typename MT::Curve_index si; - if(is_ascii(is)) is >> si; - else CGAL::read(is, si); - return si; - break; - default: - return Read_mesh_domain_index()(dimension, is); - } - } -}; // end template partial specialization - // Read_mesh_domain_index - -template ::value> -struct Write_mesh_domain_index { - // here we have has_feature==true - - typedef Mesh_domain MT; // was named "mesh traits" previously - typedef typename MT::Corner_index Ci; - typedef typename MT::Curve_index Si; - - void - operator()(std::ostream& os, int dimension, - const typename Mesh_domain::Index& index) const { - switch(dimension) { - case 0: { - const Ci& ci = get_index(index); - if(is_ascii(os)) os << oformat(ci); - else CGAL::write(os, ci); - } - break; - case 1: { - const Si& si = get_index(index); - if(is_ascii(os)) os << oformat(si); - else CGAL::write(os, si); - } - break; - default: - Write_mesh_domain_index()(os, dimension, index); - } - } -}; // end template partial specialization - // Write_mesh_domain_index - -template -struct Read_mesh_domain_index { - // here we have has_feature==false - - typedef Mesh_domain MT; // was named "mesh traits" previously - - typename Mesh_domain::Index - operator()(int dimension, std::istream& is) const { - switch(dimension) { - case 2: { - typename MT::Surface_patch_index spi; - if(is_ascii(is)) is >> iformat(spi); - else CGAL::read(is, spi); - return spi; - } - break; - default: {// 3 - typename MT::Subdomain_index di; - if(is_ascii(is)) is >> iformat(di); - else CGAL::read(is, di); - return di; - } - break; - } - } -}; // end template partial specialization - // Read_mesh_domain_index - -template -struct Write_mesh_domain_index { - // here we have has_feature==false - - typedef Mesh_domain MT; // was named "mesh traits" previously - typedef typename MT::Surface_patch_index Spi; - typedef typename MT::Subdomain_index Di; - - void - operator()(std::ostream& os, int dimension, - const typename Mesh_domain::Index& index) const { - switch(dimension) { - case 2: { - const Spi& spi = get_index(index); - if(is_ascii(os)) os << oformat(spi); - else CGAL::write(os, spi); - } - break; - default: {// 3 - const Di& di = get_index(index); - if(is_ascii(os)) os << oformat(di); - else CGAL::write(os, di); - } - break; - } - } -}; // end template partial specialization - // Write_mesh_domain_index - - - -} -} -} - -#endif +#endif // CGAL_INTERNAL_MESH_3_GET_INDEX_3_H diff --git a/Mesh_3/include/CGAL/internal/Mesh_3/helpers.h b/Mesh_3/include/CGAL/internal/Mesh_3/helpers.h index 6baa4ed6dd8..9c728889c46 100644 --- a/Mesh_3/include/CGAL/internal/Mesh_3/helpers.h +++ b/Mesh_3/include/CGAL/internal/Mesh_3/helpers.h @@ -119,12 +119,10 @@ struct Is_border_edge { } }; // end Is_featured_edge -template struct Extract_polyline_with_context_visitor { - typedef typename Polyhedral_mesh_domain::Polyhedron_type Polyhedron; std::vector& polylines; const Graph& graph; diff --git a/Mesh_3/include/CGAL/internal/Mesh_3/indices_management.h b/Mesh_3/include/CGAL/internal/Mesh_3/indices_management.h new file mode 100644 index 00000000000..595ed00829a --- /dev/null +++ b/Mesh_3/include/CGAL/internal/Mesh_3/indices_management.h @@ -0,0 +1,194 @@ +// Copyright (c) 2009 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0+ +// +// Author(s) : Stéphane Tayeb +// +//****************************************************************************** +// File Description : +// +// +//****************************************************************************** + +#ifndef CGAL_INTERNAL_MESH_3_INDICES_MANAGEMENT_H +#define CGAL_INTERNAL_MESH_3_INDICES_MANAGEMENT_H + +#include + + +#include +#include +#include +#include +#include + +namespace CGAL { +namespace internal { +namespace Mesh_3 { + + +// ----------------------------------- +// Index_generator +// Don't use boost::variant if types are the same type +// ----------------------------------- +template < typename Subdomain_index, typename Surface_patch_index > +struct Index_generator +{ + typedef boost::variant Index; + typedef Index type; +}; + +template < typename T > +struct Index_generator +{ + typedef T Index; + typedef Index type; +}; + +template +const T& get_index(const Boost_variant& x, + typename boost::disable_if >::type * = 0) +{ return boost::get(x); } + +template +const T& get_index(const T& x) { return x; } + +template ::value> +struct Read_mesh_domain_index { + // here we have has_feature==true + + typedef Mesh_domain MT; // was named "mesh traits" previously + + typename Mesh_domain::Index + operator()(int dimension, std::istream& is) const { + switch(dimension) { + case 0: + typename MT::Corner_index ci; + if(is_ascii(is)) is >> ci; + else CGAL::read(is, ci); + return ci; + break; + case 1: + typename MT::Curve_index si; + if(is_ascii(is)) is >> si; + else CGAL::read(is, si); + return si; + break; + default: + return Read_mesh_domain_index()(dimension, is); + } + } +}; // end template partial specialization + // Read_mesh_domain_index + +template ::value> +struct Write_mesh_domain_index { + // here we have has_feature==true + + typedef Mesh_domain MT; // was named "mesh traits" previously + typedef typename MT::Corner_index Ci; + typedef typename MT::Curve_index Si; + + void + operator()(std::ostream& os, int dimension, + const typename Mesh_domain::Index& index) const { + switch(dimension) { + case 0: { + const Ci& ci = get_index(index); + if(is_ascii(os)) os << oformat(ci); + else CGAL::write(os, ci); + } + break; + case 1: { + const Si& si = get_index(index); + if(is_ascii(os)) os << oformat(si); + else CGAL::write(os, si); + } + break; + default: + Write_mesh_domain_index()(os, dimension, index); + } + } +}; // end template partial specialization + // Write_mesh_domain_index + +template +struct Read_mesh_domain_index { + // here we have has_feature==false + + typedef Mesh_domain MT; // was named "mesh traits" previously + + typename Mesh_domain::Index + operator()(int dimension, std::istream& is) const { + switch(dimension) { + case 2: { + typename MT::Surface_patch_index spi; + if(is_ascii(is)) is >> iformat(spi); + else CGAL::read(is, spi); + return spi; + } + break; + default: {// 3 + typename MT::Subdomain_index di; + if(is_ascii(is)) is >> iformat(di); + else CGAL::read(is, di); + return di; + } + break; + } + } +}; // end template partial specialization + // Read_mesh_domain_index + +template +struct Write_mesh_domain_index { + // here we have has_feature==false + + typedef Mesh_domain MT; // was named "mesh traits" previously + typedef typename MT::Surface_patch_index Spi; + typedef typename MT::Subdomain_index Di; + + void + operator()(std::ostream& os, int dimension, + const typename Mesh_domain::Index& index) const { + switch(dimension) { + case 2: { + const Spi& spi = get_index(index); + if(is_ascii(os)) os << oformat(spi); + else CGAL::write(os, spi); + } + break; + default: {// 3 + const Di& di = get_index(index); + if(is_ascii(os)) os << oformat(di); + else CGAL::write(os, di); + } + break; + } + } +}; // end template partial specialization + // Write_mesh_domain_index + + + +} +} +} + +#endif // CGAL_INTERNAL_MESH_3_INDICES_MANAGEMENT_H diff --git a/Mesh_3/include/CGAL/lloyd_optimize_mesh_3.h b/Mesh_3/include/CGAL/lloyd_optimize_mesh_3.h index 3f2a3c051d8..a86f6f4f994 100644 --- a/Mesh_3/include/CGAL/lloyd_optimize_mesh_3.h +++ b/Mesh_3/include/CGAL/lloyd_optimize_mesh_3.h @@ -31,6 +31,7 @@ #include #include +#include #include #include #include diff --git a/Mesh_3/include/CGAL/make_mesh_3.h b/Mesh_3/include/CGAL/make_mesh_3.h index 8d31b78da54..36e1d155d17 100644 --- a/Mesh_3/include/CGAL/make_mesh_3.h +++ b/Mesh_3/include/CGAL/make_mesh_3.h @@ -32,6 +32,7 @@ #include #include +#include #include #include #include diff --git a/Mesh_3/include/CGAL/odt_optimize_mesh_3.h b/Mesh_3/include/CGAL/odt_optimize_mesh_3.h index 7627ab07510..163b5cf28bd 100644 --- a/Mesh_3/include/CGAL/odt_optimize_mesh_3.h +++ b/Mesh_3/include/CGAL/odt_optimize_mesh_3.h @@ -31,6 +31,7 @@ #include #include +#include #include #include #include diff --git a/Mesh_3/include/CGAL/perturb_mesh_3.h b/Mesh_3/include/CGAL/perturb_mesh_3.h index 74c68e397c5..2982717043e 100644 --- a/Mesh_3/include/CGAL/perturb_mesh_3.h +++ b/Mesh_3/include/CGAL/perturb_mesh_3.h @@ -31,6 +31,7 @@ #include #include +#include #include #include #include diff --git a/Mesh_3/include/CGAL/refine_mesh_3.h b/Mesh_3/include/CGAL/refine_mesh_3.h index 21547fc6ca6..4c21d5ef81d 100644 --- a/Mesh_3/include/CGAL/refine_mesh_3.h +++ b/Mesh_3/include/CGAL/refine_mesh_3.h @@ -32,6 +32,7 @@ #include #include +#include #include #include #include diff --git a/Mesh_3/test/Mesh_3/CMakeLists.txt b/Mesh_3/test/Mesh_3/CMakeLists.txt index 9eb5f4fb69a..3a3302cc942 100644 --- a/Mesh_3/test/Mesh_3/CMakeLists.txt +++ b/Mesh_3/test/Mesh_3/CMakeLists.txt @@ -24,19 +24,18 @@ if ( CGAL_FOUND ) create_single_source_cgal_program( "test_c3t3.cpp" ) create_single_source_cgal_program( "test_mesh_capsule_var_distance_bound.cpp" ) create_single_source_cgal_program( "test_implicit_multi_domain_to_labeling_function_wrapper.cpp" ) - create_single_source_cgal_program( "test_mesh_3_implicit_vector_to_labeled_function_wrapper.cpp" ) create_single_source_cgal_program( "test_c3t3_io.cpp" ) create_single_source_cgal_program( "test_c3t3_with_features.cpp" ) create_single_source_cgal_program( "test_criteria.cpp" ) create_single_source_cgal_program( "test_domain_with_polyline_features.cpp" ) - create_single_source_cgal_program( "test_mesh_3_labeled_mesh_domain_3.cpp" ) - create_single_source_cgal_program( "test_mesh_implicit_domains.cpp" "implicit_functions.cpp" ) create_single_source_cgal_program( "test_labeled_mesh_domain_3.cpp" ) create_single_source_cgal_program( "test_mesh_criteria_creation.cpp" ) create_single_source_cgal_program( "test_c3t3_into_facegraph.cpp" ) if(CGAL_ImageIO_USE_ZLIB) create_single_source_cgal_program( "test_meshing_3D_image.cpp" ) + create_single_source_cgal_program( "test_meshing_3D_image_deprecated.cpp" ) create_single_source_cgal_program( "test_meshing_3D_gray_image.cpp" ) + create_single_source_cgal_program( "test_meshing_3D_gray_image_deprecated.cpp" ) else() message(STATUS "test_meshing_3D_image requires the ZLIB library, and will not be compiled.") endif() @@ -45,14 +44,17 @@ if ( CGAL_FOUND ) create_single_source_cgal_program( "test_meshing_polyhedron.cpp" ) create_single_source_cgal_program( "test_meshing_polylines_only.cpp" ) create_single_source_cgal_program( "test_meshing_polyhedron_with_features.cpp" ) + create_single_source_cgal_program( "test_meshing_verbose.cpp" ) create_single_source_cgal_program( "test_meshing_unit_tetrahedron.cpp" ) create_single_source_cgal_program( "test_meshing_with_default_edge_size.cpp" ) create_single_source_cgal_program( "test_meshing_determinism.cpp" ) create_single_source_cgal_program( "test_c3t3_extract_subdomains_boundaries.cpp" ) create_single_source_cgal_program( "test_mesh_3_issue_1554.cpp" ) create_single_source_cgal_program( "test_mesh_polyhedral_domain_with_features_deprecated.cpp" ) + create_single_source_cgal_program( "test_meshing_with_one_step.cpp" ) foreach(target + test_meshing_verbose test_meshing_polyhedron_with_features test_meshing_utilities.h test_mesh_implicit_domains diff --git a/Mesh_3/test/Mesh_3/test_c3t3_extract_subdomains_boundaries.cpp b/Mesh_3/test/Mesh_3/test_c3t3_extract_subdomains_boundaries.cpp index f606a7821da..bd666212ead 100644 --- a/Mesh_3/test/Mesh_3/test_c3t3_extract_subdomains_boundaries.cpp +++ b/Mesh_3/test/Mesh_3/test_c3t3_extract_subdomains_boundaries.cpp @@ -46,7 +46,7 @@ typedef FT_to_point_function_wrapper Function; typedef CGAL::Implicit_multi_domain_to_labeling_function_wrapper Function_wrapper; typedef Function_wrapper::Function_vector Function_vector; -typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; +typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; // Triangulation typedef CGAL::Mesh_triangulation_3::type Tr; @@ -68,7 +68,7 @@ int main() v.push_back(f1); v.push_back(f2); // Domain (Warning: Sphere_3 constructor uses square radius !) - Mesh_domain domain(v, K::Sphere_3(CGAL::ORIGIN, 5.*5.), 1e-6); + Mesh_domain domain(Function_wrapper(v), K::Sphere_3(CGAL::ORIGIN, 5.*5.), 1e-6); // Set mesh criteria Facet_criteria facet_criteria(30, 0.2, 0.02); // angle, size, approximation diff --git a/Mesh_3/test/Mesh_3/test_c3t3_with_features.cpp b/Mesh_3/test/Mesh_3/test_c3t3_with_features.cpp index 3d0c27a5f60..1cdccbfd80f 100644 --- a/Mesh_3/test/Mesh_3/test_c3t3_with_features.cpp +++ b/Mesh_3/test/Mesh_3/test_c3t3_with_features.cpp @@ -27,7 +27,7 @@ #include "test_utilities.h" -#include +#include #include // IO @@ -40,9 +40,7 @@ template struct Tester { - typedef typename K::FT (Function)(const typename K::Point_3&); - - typedef CGAL::Implicit_mesh_domain_3 Base_domain; + typedef CGAL::Labeled_mesh_domain_3 Base_domain; typedef CGAL::Mesh_domain_with_polyline_features_3 Md; typedef typename CGAL::Mesh_triangulation_3::type Tr; typedef CGAL::Mesh_complex_3_in_triangulation_3< diff --git a/Mesh_3/test/Mesh_3/test_labeled_mesh_domain_3.cpp b/Mesh_3/test/Mesh_3/test_labeled_mesh_domain_3.cpp index 97f0b9ff927..8045a6772a5 100644 --- a/Mesh_3/test/Mesh_3/test_labeled_mesh_domain_3.cpp +++ b/Mesh_3/test/Mesh_3/test_labeled_mesh_domain_3.cpp @@ -47,7 +47,7 @@ struct LM3_tester }; typedef CGAL::Implicit_to_labeling_function_wrapper Function_wrapper; - typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; + typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; static FT shape_function (const Point_3& p) { diff --git a/Mesh_3/test/Mesh_3/test_mesh_3_implicit_vector_to_labeled_function_wrapper.cpp b/Mesh_3/test/Mesh_3/test_mesh_3_implicit_vector_to_labeled_function_wrapper.cpp deleted file mode 100644 index 9293e47a8c0..00000000000 --- a/Mesh_3/test/Mesh_3/test_mesh_3_implicit_vector_to_labeled_function_wrapper.cpp +++ /dev/null @@ -1,66 +0,0 @@ -#include - -#include -#include - - -typedef CGAL::Exact_predicates_inexact_constructions_kernel K_e_i; -typedef K_e_i::Point_3 Point_3; -typedef double (Function) (const Point_3&); - -typedef CGAL::Mesh_3::Implicit_vector_to_labeled_function_wrapper Labeling_function; -typedef Labeling_function::Function_vector Function_vector; - - -double cube_function_1 (const Point_3& p) -{ - if( p.x() > 0 && p.x() < 2 && - p.y() > 0 && p.y() < 2 && - p.z() > 0 && p.z() < 2 ) - return -1.; - return 1.; -} - -double cube_function_2 (const Point_3& p) -{ - if( p.x() > 1 && p.x() < 3 && - p.y() > 1 && p.y() < 3 && - p.z() > 1 && p.z() < 3 ) - return -1.; - return 1.; -} - - -void test_constructor_vfunc () -{ - Function_vector vfunc; - vfunc.push_back(cube_function_1); - vfunc.push_back(cube_function_2); - - Labeling_function lfunc(vfunc); - - Point_3 p1(0.5, 0.5, 0.5); - Point_3 p2(2.5, 2.5, 2.5); - Point_3 p3(1.5, 1.5, 1.5); - Point_3 p_out(4., 4., 4.); - - Labeling_function::return_type rp1 = lfunc(p1); - Labeling_function::return_type rp2 = lfunc(p2); - Labeling_function::return_type rp3 = lfunc(p3); - Labeling_function::return_type rp_out = lfunc(p_out); - - assert(rp1 != 0); - assert(rp2 != 0); - assert(rp3 != 0); - assert(rp_out == 0); - - assert(rp1 != rp2); - assert(rp1 != rp3); - assert(rp2 != rp3); -} - -int main () -{ - test_constructor_vfunc(); - return 0; -} diff --git a/Mesh_3/test/Mesh_3/test_mesh_3_issue_1554.cpp b/Mesh_3/test/Mesh_3/test_mesh_3_issue_1554.cpp index 998e4588162..034b1e4d067 100644 --- a/Mesh_3/test/Mesh_3/test_mesh_3_issue_1554.cpp +++ b/Mesh_3/test/Mesh_3/test_mesh_3_issue_1554.cpp @@ -1,3 +1,7 @@ +// Mesh_3 bug: The surface of c3t3 has holes +// +// https://github.com/CGAL/cgal/issues/1554 +// #include #include diff --git a/Mesh_3/test/Mesh_3/test_mesh_3_labeled_mesh_domain_3.cpp b/Mesh_3/test/Mesh_3/test_mesh_3_labeled_mesh_domain_3.cpp deleted file mode 100644 index 6d51adfc953..00000000000 --- a/Mesh_3/test/Mesh_3/test_mesh_3_labeled_mesh_domain_3.cpp +++ /dev/null @@ -1,271 +0,0 @@ -// Copyright (c) 2009 INRIA Sophia-Antipolis (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org). -// You can redistribute it and/or modify it under the terms of the GNU -// General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: GPL-3.0+ -// -// -// Author(s) : Aymeric PELLE -// -//****************************************************************************** -// File Description : -//****************************************************************************** - -#include - -#include "test_meshing_utilities.h" -#include -#include - -template -struct LM3_tester -{ - typedef typename K::Point_3 Point_3; - typedef typename K::FT FT; - - struct Function - { - typedef Point_3 Point; - typedef FT (*Func)(const Point_3&); - - Function (Func f) : f_(f) {} - FT operator() (const Point_3& p) const { return f_(p); } - - private: - Func f_; - }; - - typedef CGAL::Mesh_3::Implicit_to_labeled_function_wrapper Function_wrapper; - typedef CGAL::Mesh_3::Labeled_mesh_domain_3 Mesh_domain; - - static FT shape_function (const Point_3& p) - { - if (p.x() < 0) - return -1; - const FT x2=p.x()*p.x(), y2=p.y()*p.y(), z2=p.z()*p.z(); - return x2 + y2 + z2 - 1; - } - - static FT sphere_function (const Point_3& p) - { - const FT x2=p.x()*p.x(), y2=p.y()*p.y(), z2=p.z()*p.z(); - return x2 + y2 + z2 - 1; - } - - void operator() () const - { - typedef typename K::Sphere_3 Sphere_3; - - test_domain(Sphere_3(CGAL::ORIGIN, 4.)); - test_domain(CGAL::Bbox_3(-2.,-2.,-2., 2.,2.,2.)); - } - -private: - template - void test_domain (const BoundingShape& bounding_shape) const - { - FT error_bound(1e-3); - - Function f_sphere(&sphere_function); - Function_wrapper wrapper_1(f_sphere); - Mesh_domain domain(wrapper_1, bounding_shape, error_bound); - test_construct_initial_points(domain, error_bound); - - Function f_shape(&shape_function); - Function_wrapper wrapper_2(f_shape); - Mesh_domain domain_2(wrapper_2, bounding_shape, error_bound); - test_is_in_domain(domain_2); - test_do_intersect_surface(domain_2); - test_construct_intersection(domain_2); - } - - void test_construct_initial_points (const Mesh_domain& domain, FT error_bound) const - { - typedef typename Mesh_domain::Construct_initial_points Construct_initial_points; - typedef typename Mesh_domain::Index Index; - typedef typename std::vector >::const_iterator Points_const_iterator; - typedef typename K::Compute_squared_distance_3 Compute_squared_distance_3; - - Compute_squared_distance_3 squared_distance = K().compute_squared_distance_3_object(); - - Construct_initial_points construct_initial_points = domain.construct_initial_points_object(); - std::vector > points; - int point_count = 12; - construct_initial_points(std::back_inserter(points), point_count); - - for (Points_const_iterator iter = points.begin(), end_iter = points.end(); iter != end_iter; ++iter) - { - const Point_3& p = iter->first; - - FT sd = squared_distance(CGAL::ORIGIN, p); - FT diff = sd - 1; - if (diff < FT(0.)) - diff = -diff; - assert(diff <= error_bound); - } - } - - void test_is_in_domain (const Mesh_domain& domain) const - { - typedef typename Mesh_domain::Is_in_domain Is_in_domain; - typedef typename Mesh_domain::Subdomain Subdomain; - typedef typename Mesh_domain::Subdomain_index Subdomain_index; - - Is_in_domain is_in_domain = domain.is_in_domain_object(); - - { - Subdomain subdomain = is_in_domain(Point_3(CGAL::ORIGIN)); - assert(subdomain); - Subdomain_index subdomain_index = *subdomain; - assert(subdomain_index == 1); - } - - { - Subdomain subdomain = is_in_domain(Point_3(1.5, 0., 0.)); - assert(!subdomain); - } - } - - void test_do_intersect_surface (const Mesh_domain& domain) const - { - typedef typename Mesh_domain::Do_intersect_surface Do_intersect_surface; - typedef typename Mesh_domain::Surface_patch Surface_patch; - typedef typename Mesh_domain::Surface_patch_index Surface_patch_index; - typedef typename Mesh_domain::Segment_3 Segment_3; - typedef typename Mesh_domain::Ray_3 Ray_3; - typedef typename Mesh_domain::Line_3 Line_3; - typedef typename Mesh_domain::Vector_3 Vector_3; - - Do_intersect_surface do_intersect_surface = domain.do_intersect_surface_object(); - - { - Segment_3 s(Point_3(CGAL::ORIGIN), Point_3(1.5, 0., 0.)); - Surface_patch p = do_intersect_surface(s); - assert(p); - Surface_patch_index pi = *p; - assert(pi.first == 0 && pi.second == 1); - } - - { - Segment_3 s(Point_3(1.5, 1.5, 0.), Point_3(1.5, 0., 0.)); - Surface_patch p = do_intersect_surface(s); - assert(!p); - } - - { - Ray_3 r(Point_3(CGAL::ORIGIN), Vector_3(1., 0., 0.)); - Surface_patch p = do_intersect_surface(r); - assert(p); - Surface_patch_index pi = *p; - assert(pi.first == 0 && pi.second == 1); - } - - { - Ray_3 r(Point_3(1.5, 0., 0.), Vector_3(0., 1., 0.)); - Surface_patch p = do_intersect_surface(r); - assert(!p); - } - - { - Line_3 l(Point_3(CGAL::ORIGIN), Point_3(1.5, 0., 0.)); - Surface_patch p = do_intersect_surface(l); - assert(p); - Surface_patch_index pi = *p; - assert(pi.first == 0 && pi.second == 1); - } - - { - Line_3 l(Point_3(1.5, 0., 0.), Point_3(1.5, 0.5, 0.)); - Surface_patch p = do_intersect_surface(l); - assert(!p); - } - } - - - void test_construct_intersection (const Mesh_domain& domain) const - { - typedef typename Mesh_domain::Construct_intersection Construct_intersection; - typedef typename Mesh_domain::Intersection Intersection; - typedef typename Mesh_domain::Subdomain_index Subdomain_index; - typedef typename Mesh_domain::Surface_patch_index Surface_patch_index; - typedef typename Mesh_domain::Index Index; - typedef typename Mesh_domain::Segment_3 Segment_3; - typedef typename Mesh_domain::Ray_3 Ray_3; - typedef typename Mesh_domain::Line_3 Line_3; - typedef typename Mesh_domain::Vector_3 Vector_3; - - Construct_intersection construct_intersection = domain.construct_intersection_object(); - - { - Segment_3 s(Point_3(CGAL::ORIGIN), Point_3(1.5, 0., 0.)); - Intersection i = construct_intersection(s); - assert(CGAL::cpp11::get<0>(i) != Point_3(1., 0., 0.)); - Index ii = CGAL::cpp11::get<1>(i); - assert(boost::get(&ii)); - assert(CGAL::cpp11::get<2>(i) == 2); - } - - { - Segment_3 s(Point_3(1.5, 1.5, 0.), Point_3(1.5, 0., 0.)); - Intersection i = construct_intersection(s); - Index ii = CGAL::cpp11::get<1>(i); - assert(boost::get(&ii)); - assert(CGAL::cpp11::get<2>(i) == 0); - } - - { - Ray_3 r(Point_3(CGAL::ORIGIN), Vector_3(1., 0., 0.)); - Intersection i = construct_intersection(r); - assert(CGAL::cpp11::get<0>(i) != Point_3(1., 0., 0.)); - Index ii = CGAL::cpp11::get<1>(i); - assert(boost::get(&ii)); - assert(CGAL::cpp11::get<2>(i) == 2); - } - - { - Ray_3 r(Point_3(1.5, 0., 0.), Vector_3(0., 1., 0.)); - Intersection i = construct_intersection(r); - Index ii = CGAL::cpp11::get<1>(i); - assert(boost::get(&ii)); - assert(CGAL::cpp11::get<2>(i) == 0); - } - - { - Line_3 l(Point_3(CGAL::ORIGIN), Point_3(1.5, 0., 0.)); - Intersection i = construct_intersection(l); - assert(CGAL::cpp11::get<0>(i) != Point_3(1., 0., 0.)); - Index ii = CGAL::cpp11::get<1>(i); - assert(boost::get(&ii)); - assert(CGAL::cpp11::get<2>(i) == 2); - } - - { - Line_3 l(Point_3(1.5, 0., 0.), Point_3(1.5, 0.5, 0.)); - Intersection i = construct_intersection(l); - Index ii = CGAL::cpp11::get<1>(i); - assert(boost::get(&ii)); - assert(CGAL::cpp11::get<2>(i) == 0); - } - } -}; - - -int main () -{ - LM3_tester test_epic; - test_epic(); - - return EXIT_SUCCESS; -} diff --git a/Mesh_3/test/Mesh_3/test_mesh_capsule_var_distance_bound.cpp b/Mesh_3/test/Mesh_3/test_mesh_capsule_var_distance_bound.cpp index 95d39895575..bde524dbaa5 100644 --- a/Mesh_3/test/Mesh_3/test_mesh_capsule_var_distance_bound.cpp +++ b/Mesh_3/test/Mesh_3/test_mesh_capsule_var_distance_bound.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include // Domain @@ -12,7 +12,7 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel K; typedef K::FT FT; typedef K::Point_3 Point; typedef FT (Function)(const Point&); -typedef CGAL::Implicit_mesh_domain_3 Mesh_domain; +typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; #ifdef CGAL_CONCURRENT_MESH_3 typedef CGAL::Parallel_tag Concurrency_tag; @@ -55,8 +55,9 @@ struct Field { int main() { - Mesh_domain domain(capsule_function, - K::Sphere_3(CGAL::ORIGIN, 49.)); + Mesh_domain domain = + Mesh_domain::create_implicit_mesh_domain(capsule_function, + K::Sphere_3(CGAL::ORIGIN, 49.)); // Mesh criteria Mesh_criteria criteria(facet_angle=30, facet_size=0.5, diff --git a/Mesh_3/test/Mesh_3/test_mesh_implicit_domains.cpp b/Mesh_3/test/Mesh_3/test_mesh_implicit_domains.cpp deleted file mode 100644 index 921a6bbea04..00000000000 --- a/Mesh_3/test/Mesh_3/test_mesh_implicit_domains.cpp +++ /dev/null @@ -1,91 +0,0 @@ - -//****************************************************************************** -// File Description : -// Outputs to out.mesh a mesh of implicit domains. These domains are defined -// by a vector of functions. Each n-uplet of sign of function values defines a -// subdomain. -//****************************************************************************** - -#include "debug.h" -#include - -#include -#include -#include - -#include -#include -#include -#include "implicit_functions.h" - -// IO -#include - -using namespace CGAL::parameters; - -template -void test() -{ - // Domain - typedef CGAL::Exact_predicates_inexact_constructions_kernel K; - typedef FT_to_point_function_wrapper Function; - typedef CGAL::Implicit_vector_to_labeling_function_wrapper - Function_wrapper; - typedef Function_wrapper::Function_vector Function_vector; - typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; - - // Triangulation - typedef typename CGAL::Mesh_triangulation_3< - Mesh_domain, - CGAL::Kernel_traits::Kernel, - Concurrency_tag>::type Tr; - typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; - - // Mesh Criteria - typedef CGAL::Mesh_criteria_3 Mesh_criteria; - typedef typename Mesh_criteria::Facet_criteria Facet_criteria; - typedef typename Mesh_criteria::Cell_criteria Cell_criteria; - - // Define functions - Function f1(&torus_function); - Function f2(&sphere_function<5>); - Function f3(&sphere_function<2>); - - Function_vector v; - v.push_back(&f1); - v.push_back(&f2); - //v.push_back(&f3); - - // Domain (Warning: Sphere_3 constructor uses square radius !) - Mesh_domain domain(v, K::Sphere_3(CGAL::ORIGIN, 5.*5.), 1e-6); - - // Set mesh criteria - Facet_criteria facet_criteria(30, 0.2, 0.02); // angle, size, approximation - Cell_criteria cell_criteria(2., 0.4); // radius-edge ratio, size - Mesh_criteria criteria(facet_criteria, cell_criteria); - - // Mesh generation - C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria, no_exude(), no_perturb()); - - // Perturbation (maximum cpu time: 10s, targeted dihedral angle: default) - CGAL::perturb_mesh_3(c3t3, domain, time_limit = 10); - - // Exudation - CGAL::exude_mesh_3(c3t3,12); - - // Output - std::ofstream medit_file("out.mesh"); - CGAL::output_to_medit(medit_file, c3t3); -} - -int main() -{ - std::cout << "==== Test sequential meshing ====" << std::endl; - test(); -#ifdef CGAL_LINKED_WITH_TBB - std::cout << "==== Test parallel meshing ====" << std::endl; - test(); -#endif - - return 0; -} diff --git a/Mesh_3/test/Mesh_3/test_mesh_polyhedral_domain_with_features_deprecated.cpp b/Mesh_3/test/Mesh_3/test_mesh_polyhedral_domain_with_features_deprecated.cpp index 26e7093cb91..5faef60a0ae 100644 --- a/Mesh_3/test/Mesh_3/test_mesh_polyhedral_domain_with_features_deprecated.cpp +++ b/Mesh_3/test/Mesh_3/test_mesh_polyhedral_domain_with_features_deprecated.cpp @@ -1,4 +1,5 @@ -#include +#ifndef CGAL_NO_DEPRECATED_CODE +#define CGAL_NO_DEPRECATION_WARNINGS #include @@ -53,3 +54,11 @@ int main() std::ofstream medit_file("out.mesh"); c3t3.output_to_medit(medit_file); } + +#else // CGAL_NO_DEPRECATED_CODE +#include +int main() { + std::cerr << "CGAL_NO_DEPRECATED_CODE is defined. Nothing to test.\n"; + return 0; +} +#endif // CGAL_NO_DEPRECATED_CODE diff --git a/Mesh_3/test/Mesh_3/test_meshing_3D_gray_image.cpp b/Mesh_3/test/Mesh_3/test_meshing_3D_gray_image.cpp index d1230c0ced2..1ee420467b2 100644 --- a/Mesh_3/test/Mesh_3/test_meshing_3D_gray_image.cpp +++ b/Mesh_3/test/Mesh_3/test_meshing_3D_gray_image.cpp @@ -25,7 +25,7 @@ #include "test_meshing_utilities.h" #include -#include +#include #include #include @@ -49,13 +49,8 @@ struct Image_tester : public Tester public: void image() const { - typedef float Image_word_type; typedef CGAL::Image_3 Image; - typedef CGAL::Gray_image_mesh_domain_3< - Image, - K_e_i, - Image_word_type, - Greater_than > Mesh_domain; + typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; typedef typename CGAL::Mesh_triangulation_3< Mesh_domain, @@ -78,13 +73,15 @@ public: std::cout << "\tSeed is\t" << CGAL::get_default_random().get_seed() << std::endl; - + namespace p = CGAL::parameters; // Domain - Mesh_domain domain(image, - 2.9f, //isovalue - 0.f, //value_outside - 1e-3, //error_bound - &CGAL::get_default_random());//random generator for determinism + Mesh_domain domain = + Mesh_domain::create_gray_image_mesh_domain(image, + p::iso_value = 2.9f, + p::value_outside = 0.f, + p::relative_error_bound = 1e-3, + p::p_rng = + &CGAL::get_default_random()); // Mesh criteria Mesh_criteria criteria(facet_angle = 30, diff --git a/Mesh_3/test/Mesh_3/test_meshing_3D_gray_image_deprecated.cpp b/Mesh_3/test/Mesh_3/test_meshing_3D_gray_image_deprecated.cpp new file mode 100644 index 00000000000..52bb90c7f2e --- /dev/null +++ b/Mesh_3/test/Mesh_3/test_meshing_3D_gray_image_deprecated.cpp @@ -0,0 +1,136 @@ +// Copyright (c) 2015 GeometryFactory (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0+ +// +// +// Author(s) : Laurent Rineau, Jane Tournois +// +//****************************************************************************** +// File Description : +//*************************************************************************** + +#ifndef CGAL_NO_DEPRECATED_CODE +#define CGAL_NO_DEPRECATION_WARNINGS 1 + +#include "test_meshing_utilities.h" +#include +#include +#include + +#include + +// To avoid verbose function and named parameters call +using namespace CGAL::parameters; + +template +struct Greater_than { + typedef T argument_type; + Greater_than(const T& second) : second(second) {} + bool operator()(const T& first) const { + return std::greater()(first, second); + } + T second; +}; + +template +struct Image_tester : public Tester +{ +public: + void image() const + { + typedef float Image_word_type; + typedef CGAL::Image_3 Image; + typedef CGAL::Gray_image_mesh_domain_3< + Image, + K_e_i, + Image_word_type, + Greater_than > Mesh_domain; + + typedef typename CGAL::Mesh_triangulation_3< + Mesh_domain, + CGAL::Kernel_traits::Kernel, + Concurrency_tag>::type Tr; + typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; + typedef CGAL::Mesh_criteria_3 Mesh_criteria; + + CGAL_USE_TYPE(typename Mesh_domain::Surface_patch_index); + + //------------------------------------------------------- + // Data generation + //------------------------------------------------------- + Image image; + if (!image.read("data/skull_2.9.inr")) + { + std::cout << "Image reading error. Exit test.\n"; + return; + } + + std::cout << "\tSeed is\t" + << CGAL::get_default_random().get_seed() << std::endl; + + // Domain + Mesh_domain domain(image, + 2.9f, //isovalue + 0.f, //value_outside + 1e-3, //error_bound + &CGAL::get_default_random());//random generator for determinism + + // Mesh criteria + Mesh_criteria criteria(facet_angle = 30, + facet_size = 6, + facet_distance = 2, + facet_topology = CGAL::MANIFOLD, + cell_radius_edge_ratio = 3, + cell_size = 8); + + // Mesh generation + C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria, + no_perturb(), + no_exude(), + mesh_3_options(number_of_initial_points = 30), + non_manifold() + ); + + // Verify + this->verify_c3t3_volume(c3t3, 1236086 * 0.95, 1236086 * 1.05); + this->verify(c3t3, domain, criteria, Bissection_tag()); + } +}; + + +int main() +{ + Image_tester<> test_epic; + std::cerr << "Mesh generation from a 3D image:\n"; + test_epic.image(); + +#ifdef CGAL_LINKED_WITH_TBB + Image_tester test_epic_p; + std::cerr << "Parallel mesh generation from a 3D image:\n"; + test_epic_p.image(); +#endif + + return EXIT_SUCCESS; +} + +#else // CGAL_NO_DEPRECATED_CODE +#include +int main() { + std::cerr << "CGAL_NO_DEPRECATED_CODE is defined. Nothing to test.\n"; + return 0; +} +#endif // CGAL_NO_DEPRECATED_CODE diff --git a/Mesh_3/test/Mesh_3/test_meshing_3D_image.cpp b/Mesh_3/test/Mesh_3/test_meshing_3D_image.cpp index 1b3a846c39a..c80ecd2e86d 100644 --- a/Mesh_3/test/Mesh_3/test_meshing_3D_image.cpp +++ b/Mesh_3/test/Mesh_3/test_meshing_3D_image.cpp @@ -25,7 +25,7 @@ #include "test_meshing_utilities.h" #include -#include +#include #include template @@ -35,7 +35,7 @@ public: void image() const { typedef CGAL::Image_3 Image; - typedef CGAL::Labeled_image_mesh_domain_3 Mesh_domain; + typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; typedef typename CGAL::Mesh_triangulation_3< Mesh_domain, @@ -55,7 +55,10 @@ public: std::cout << "\tSeed is\t" << CGAL::get_default_random().get_seed() << std::endl; - Mesh_domain domain(image, 1e-9, &CGAL::get_default_random()); + Mesh_domain domain = Mesh_domain::create_labeled_image_mesh_domain + (image, + 1e-9, + CGAL::parameters::p_rng = &CGAL::get_default_random()); // Set mesh criteria Facet_criteria facet_criteria(25, 20*image.vx(), 5*image.vx()); diff --git a/Mesh_3/test/Mesh_3/test_meshing_3D_image_deprecated.cpp b/Mesh_3/test/Mesh_3/test_meshing_3D_image_deprecated.cpp new file mode 100644 index 00000000000..7beb6765bb1 --- /dev/null +++ b/Mesh_3/test/Mesh_3/test_meshing_3D_image_deprecated.cpp @@ -0,0 +1,107 @@ +// Copyright (c) 2009 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0+ +// +// +// Author(s) : Stephane Tayeb +// +//****************************************************************************** +// File Description : +//****************************************************************************** + +#ifndef CGAL_NO_DEPRECATED_CODE +#define CGAL_NO_DEPRECATION_WARNINGS 1 + +#include "test_meshing_utilities.h" +#include +#include +#include + +template +struct Image_tester : public Tester +{ +public: + void image() const + { + typedef CGAL::Image_3 Image; + typedef CGAL::Labeled_image_mesh_domain_3 Mesh_domain; + + typedef typename CGAL::Mesh_triangulation_3< + Mesh_domain, + CGAL::Kernel_traits::Kernel, + Concurrency_tag>::type Tr; + typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; + + typedef CGAL::Mesh_criteria_3 Mesh_criteria; + typedef typename Mesh_criteria::Facet_criteria Facet_criteria; + typedef typename Mesh_criteria::Cell_criteria Cell_criteria; + + //------------------------------------------------------- + // Data generation + //------------------------------------------------------- + Image image; + image.read("data/liver.inr.gz"); + + std::cout << "\tSeed is\t" + << CGAL::get_default_random().get_seed() << std::endl; + Mesh_domain domain(image, 1e-9, &CGAL::get_default_random()); + + // Set mesh criteria + Facet_criteria facet_criteria(25, 20*image.vx(), 5*image.vx()); + Cell_criteria cell_criteria(4, 25*image.vx()); + Mesh_criteria criteria(facet_criteria, cell_criteria); + + // Mesh generation + C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria, + CGAL::parameters::no_exude(), + CGAL::parameters::no_perturb()); + + // Verify + this->verify_c3t3_volume(c3t3, 1772330*0.95, 1772330*1.05); + this->verify(c3t3,domain,criteria, Bissection_tag()); + + typedef typename Mesh_domain::Surface_patch_index Patch_id; + CGAL_static_assertion(CGAL::Output_rep::is_specialized); + CGAL_USE_TYPE(Patch_id); + } + +}; + + + +int main() +{ + Image_tester<> test_epic; + std::cerr << "Mesh generation from a 3D image:\n"; + test_epic.image(); + +#ifdef CGAL_LINKED_WITH_TBB + Image_tester test_epic_p; + std::cerr << "Parallel mesh generation from a 3D image:\n"; + test_epic_p.image(); +#endif + + return EXIT_SUCCESS; +} + +#else // CGAL_NO_DEPRECATED_CODE +#include +int main() { + std::cerr << "CGAL_NO_DEPRECATED_CODE is defined. Nothing to test.\n"; + return 0; +} +#endif // CGAL_NO_DEPRECATED_CODE diff --git a/Mesh_3/test/Mesh_3/test_meshing_implicit_function.cpp b/Mesh_3/test/Mesh_3/test_meshing_implicit_function.cpp index 28ce9021278..ec8effb5f4a 100644 --- a/Mesh_3/test/Mesh_3/test_meshing_implicit_function.cpp +++ b/Mesh_3/test/Mesh_3/test_meshing_implicit_function.cpp @@ -24,7 +24,7 @@ //****************************************************************************** #include "test_meshing_utilities.h" -#include +#include #include @@ -42,9 +42,7 @@ struct Implicit_tester : public Tester void implicit() const { - typedef FT (Function)(const Point&); - - typedef CGAL::Implicit_mesh_domain_3 Mesh_domain; + typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; typedef typename CGAL::Mesh_triangulation_3< Mesh_domain, @@ -65,10 +63,14 @@ struct Implicit_tester : public Tester //------------------------------------------------------- std::cout << "\tSeed is\t" << CGAL::get_default_random().get_seed() << std::endl; - Mesh_domain domain(Implicit_tester::sphere_function, - Sphere_3(CGAL::ORIGIN,2.), - 1e-3, - &CGAL::get_default_random()); + + namespace p = CGAL::parameters; + Mesh_domain domain = + Mesh_domain::create_implicit_mesh_domain + (p::function = Implicit_tester::sphere_function, + p::bounding_object = Sphere_3(CGAL::ORIGIN,2.), + p::p_rng = &CGAL::get_default_random(), + p::relative_error_bound = 1e-3); // Set mesh criteria Facet_criteria facet_criteria(0, 0, 0.3); diff --git a/Mesh_3/test/Mesh_3/test_meshing_polyhedron_with_features.cpp b/Mesh_3/test/Mesh_3/test_meshing_polyhedron_with_features.cpp index 248a1b651db..67d58f98179 100644 --- a/Mesh_3/test/Mesh_3/test_meshing_polyhedron_with_features.cpp +++ b/Mesh_3/test/Mesh_3/test_meshing_polyhedron_with_features.cpp @@ -72,13 +72,20 @@ struct Polyhedron_with_features_tester : public Tester CGAL_USE(polyhedra); // Set mesh criteria +#ifndef CGAL_MESH_3_VERBOSE Edge_criteria edge_criteria(0.2); Facet_criteria facet_criteria(30, 0.2, 0.02); Cell_criteria cell_criteria(3, 0.2); +#else // a different set of criteria, for the test of CGAL_MESH_3_VERBOSE + Edge_criteria edge_criteria(0.3); + Facet_criteria facet_criteria(30, 0.3, 0.03); + Cell_criteria cell_criteria(3, 0.4); +#endif Mesh_criteria criteria(edge_criteria, facet_criteria, cell_criteria); // Mesh generation C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria, + CGAL::parameters::manifold(), CGAL::parameters::no_exude(), CGAL::parameters::no_perturb()); diff --git a/Mesh_3/test/Mesh_3/test_meshing_verbose.cpp b/Mesh_3/test/Mesh_3/test_meshing_verbose.cpp new file mode 100644 index 00000000000..59a96e24ba1 --- /dev/null +++ b/Mesh_3/test/Mesh_3/test_meshing_verbose.cpp @@ -0,0 +1,5 @@ +#define CGAL_MESH_3_VERBOSE 1 +#include "test_meshing_polyhedron_with_features.cpp" + +// This comment is for the shell script cgal_test +// int main() { return 0; } diff --git a/Mesh_3/test/Mesh_3/test_meshing_with_one_step.cpp b/Mesh_3/test/Mesh_3/test_meshing_with_one_step.cpp new file mode 100644 index 00000000000..cdc18b0888c --- /dev/null +++ b/Mesh_3/test/Mesh_3/test_meshing_with_one_step.cpp @@ -0,0 +1,78 @@ +#define CGAL_MESH_3_VERBOSE 1 +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +// Domain +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef CGAL::Surface_mesh Polyhedron; +typedef CGAL::Polyhedral_mesh_domain_3 Mesh_domain; + +typedef CGAL::Sequential_tag Concurrency_tag; + +// Triangulation +typedef CGAL::Mesh_triangulation_3::type Tr; + +typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; + +// Criteria +typedef CGAL::Mesh_criteria_3 Mesh_criteria; + +typedef CGAL::Mesh_3::Mesher_3 Mesher; + +// To avoid verbose function and named parameters call +using namespace CGAL::parameters; + +int main(int argc, char*argv[]) +{ + const char* fname = (argc>1)?argv[1]:"data/sphere.off"; + // Create input polyhedron + Polyhedron polyhedron; + std::ifstream input(fname); + input >> polyhedron; + if(input.fail()){ + std::cerr << "Error: Cannot read file " << fname << std::endl; + return EXIT_FAILURE; + } + input.close(); + + if (!CGAL::is_triangle_mesh(polyhedron)){ + std::cerr << "Input geometry is not triangulated." << std::endl; + return EXIT_FAILURE; + } + + // Create domain + Mesh_domain domain(polyhedron); + + // Mesh criteria (no cell_size set) + Mesh_criteria criteria(facet_angle=25, facet_size=0.2, facet_distance=0.01, + cell_size = 0.2, cell_radius_edge_ratio=3); + + // Mesh generation + C3t3 c3t3; + CGAL::internal::Mesh_3::C3t3_initializer()(c3t3, domain, criteria, false); + Mesher mesher(c3t3, domain, criteria,CGAL::FACET_VERTICES_ON_SAME_SURFACE_PATCH); + mesher.initialize(); + while ( ! mesher.is_algorithm_done() ) mesher.one_step(); + assert(c3t3.triangulation().number_of_vertices() > 200); + // Output + std::ofstream medit_file("out.mesh"); + c3t3.output_to_medit(medit_file); + medit_file.close(); + + return EXIT_SUCCESS; +} diff --git a/Point_set_processing_3/examples/Point_set_processing_3/CMakeLists.txt b/Point_set_processing_3/examples/Point_set_processing_3/CMakeLists.txt index 2712f080b1c..1950f28e20e 100644 --- a/Point_set_processing_3/examples/Point_set_processing_3/CMakeLists.txt +++ b/Point_set_processing_3/examples/Point_set_processing_3/CMakeLists.txt @@ -42,7 +42,7 @@ if ( CGAL_FOUND ) endif() # Executables that do *not* require EIGEN or LAPACK - create_single_source_cgal_program( "average_spacing_example.cpp" ) + create_single_source_cgal_program( "average_spacing_example.cpp" ) create_single_source_cgal_program( "bilateral_smooth_point_set_example.cpp" ) create_single_source_cgal_program( "grid_simplification_example.cpp" ) create_single_source_cgal_program( "grid_simplify_indices.cpp" ) diff --git a/Point_set_processing_3/include/CGAL/structure_point_set.h b/Point_set_processing_3/include/CGAL/structure_point_set.h index 241bde88ec0..3721e82f110 100644 --- a/Point_set_processing_3/include/CGAL/structure_point_set.h +++ b/Point_set_processing_3/include/CGAL/structure_point_set.h @@ -36,7 +36,6 @@ #include #include -#include #include #include diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/NamedParameters.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/NamedParameters.txt index d9b8e95c9ac..4202b10e136 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/NamedParameters.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/NamedParameters.txt @@ -6,9 +6,9 @@ In this package, all functions optional parameters are implemented as BGL option named parameters (see \ref BGLNamedParameters for more information on how to use them). Since the parameters of the various polygon mesh processing functions defined in this package are redundant, their long descriptions are centralized below. -The sequence of named parameters should start with `CGAL::parameters::`. +The sequence of named parameters starts with `CGAL::parameters::`. `CGAL::parameters::all_default()` can be used to indicate -that default values of optional named parameters must be used. +that default values of optional named parameters shall be used. In the following, we assume that the following types are provided as template parameters of polygon mesh processing functions and classes. Note that, for some of these functions, @@ -45,7 +45,7 @@ is the property map containing the index of each face of the input polygon mesh. `boost::graph_traits::%face_descriptor` as key type and the value type: \code typename boost::property_traits::type>::value_type \endcode Default: \code boost::get(CGAL::face_index, pmesh)\endcode -If this internal property map exists, its values should be initialized. +If this internal property map exists, its values must be initialized. \cgalNPEnd \cgalNPBegin{edge_is_constrained_map} \anchor PMP_edge_is_constrained_map @@ -54,7 +54,7 @@ being marked or not. In `isotropic_remeshing()` and `connected_components()`, the marked edges are constrained.\n Type: a class model of `ReadWritePropertyMap` with `boost::graph_traits::%edge_descriptor` as key type and -`bool` as value type. It should be default constructible.\n +`bool` as value type. It must be default constructible.\n Default: a default property map where no edge is constrained \cgalNPEnd \cgalNPTableEnd @@ -63,7 +63,7 @@ In addition to these named parameters, this package offers the following named p \cgalNPTableBegin \cgalNPBegin{geom_traits} \anchor PMP_geom_traits -is the geometric traits instance in which the mesh processing operation should be performed.\n +is the geometric traits instance used for the mesh processing operation.\n Type: a Geometric traits class.\n Default: \code typename CGAL::Kernel_traits< @@ -85,7 +85,7 @@ inserted several times.\n is the property map containing the number of feature edges being incident to the vertices of the polygon mesh `pmesh`.\n Type: a class model of `ReadWritePropertyMap` with `boost::graph_traits::%vertex_descriptor` as key type and -`int` as value type. It should be default constructible.\n +`int` as value type. It must be default constructible.\n Default: \code boost::get(CGAL::vertex_feature_degree_t(), pmesh) \endcode \cgalNPEnd @@ -95,7 +95,7 @@ Constrained vertices may be replaced by new vertices, but the number and locatio of vertices remain unchanged.\n Type: a class model of `ReadWritePropertyMap` with `boost::graph_traits::%vertex_descriptor` as key type and -`bool` as value type. It should be default constructible.\n +`bool` as value type. It must be default constructible.\n Default: a default property map where no vertex is constrained is provided. \cgalNPEnd @@ -188,21 +188,21 @@ enables the use of the Delaunay triangulation facet search space for hole fillin \cgalNPEnd \cgalNPBegin{use_random_uniform_sampling} \anchor PMP_use_random_uniform_sampling -is a parameter used in `sample_triangle_mesh()` to indicate if points should be picked +is a parameter used in `sample_triangle_mesh()` to indicate that the points are picked in a random uniform way.\n Type: `bool` \n Default: `true` \cgalNPEnd \cgalNPBegin{use_grid_sampling} \anchor PMP_use_grid_sampling -is a parameter used in `sample_triangle_mesh()` to indicate if points should be picked -in on a grid in each face.\n +is a parameter used in `sample_triangle_mesh()` to indicate that the points are picked +on a grid in each face.\n Type: `bool` \n Default: `false` \cgalNPEnd \cgalNPBegin{use_monte_carlo_sampling} \anchor PMP_use_monte_carlo_sampling -is a parameter used in `sample_triangle_mesh()` to indicate if points should be picked +is a parameter used in `sample_triangle_mesh()` to indicate that the points are picked using a Monte-Carlo approach.\n Type: `bool` \n Default: `false` @@ -210,21 +210,21 @@ using a Monte-Carlo approach.\n \cgalNPBegin{sample_edges} \anchor PMP_sample_edges is a parameter used in `sample_triangle_mesh()` to indicate if a dedicated sampling -of edges should be done.\n +of edges is done.\n Type: `bool` \n Default: `true` \cgalNPEnd \cgalNPBegin{sample_vertices} \anchor PMP_sample_vertices -is a parameter used in `sample_triangle_mesh()` to indicate if triangle vertices should -be copied in the output iterator.\n +is a parameter used in `sample_triangle_mesh()` to indicate that triangle vertices are +copied in the output iterator.\n Type: `bool` \n Default: `true` \cgalNPEnd \cgalNPBegin{sample_faces} \anchor PMP_sample_faces is a parameter used in `sample_triangle_mesh()` to indicate if the interior of faces -should be considered for the sampling.\n +is considered for the sampling.\n Type: `bool` \n Default: `true` \cgalNPEnd @@ -281,7 +281,7 @@ Monte-Carlo methods.\n \cgalNPEnd \cgalNPBegin{do_project} \anchor PMP_do_project -is a parameter used in `random_perturbation()` to set whether vertices should be re-projected +is a parameter used in `random_perturbation()` to set whether vertices are re-projected to the input surface after their geometric perturbation.\n Type: `bool` \n Default: `true` @@ -304,7 +304,7 @@ Parameter used in orientation functions to choose between an outward or inward o \cgalNPBegin{do_overlap_test_of_bounded_sides} \anchor PMP_do_overlap_test_of_bounded_sides Parameter used in intersection test functions to indicate whether overlapping tests of bounded sides -of close meshes should be done in addition to surface intersection tests. +of close meshes are done in addition to surface intersection tests. \n \b Type : `bool` \n \b Default value is `false` diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt index de632eeadf7..6482ee54e73 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt @@ -571,11 +571,11 @@ and store them in property maps provided by the class `Surface_mesh`. \cgalExample{Polygon_mesh_processing/compute_normals_example.cpp} -\subsubsection NormalsExampleP Normals Computation for a Poyhedron_3 +\subsubsection NormalsExampleP Normals Computation for a Polyhedron_3 The following example illustrates how to compute the normals to faces and vertices -and store them in ordered or unordered maps as the class `Polyhedron` does +and store them in ordered or unordered maps as the class `Polyhedron_3` does not provide storage for the normals. \cgalExample{Polygon_mesh_processing/compute_normals_example_Polyhedron.cpp} diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/dependencies b/Polygon_mesh_processing/doc/Polygon_mesh_processing/dependencies index 52428e7009d..e9a5e6baf02 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/dependencies +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/dependencies @@ -12,3 +12,5 @@ Surface_mesh_deformation AABB_tree Triangulation_2 Spatial_sorting +Generator + diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/bbox.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/bbox.h index 033364bac9b..0c73a8655dd 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/bbox.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/bbox.h @@ -51,7 +51,7 @@ namespace CGAL { * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `PolygonMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `PolygonMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, * providing the functor `Construct_bbox_3` and the function * `Construct_bbox_3 construct_bbox_3_object()`. `Construct_bbox_3` @@ -101,7 +101,7 @@ namespace CGAL { * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `PolygonMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `PolygonMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, * providing the functor `Construct_bbox_3` and the function * `Construct_bbox_3 construct_bbox_3_object()`. `Construct_bbox_3` @@ -144,7 +144,7 @@ namespace CGAL { * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `PolygonMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `PolygonMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, * providing the functor `Construct_bbox_3` and the function * `Construct_bbox_3 construct_bbox_3_object()`. `Construct_bbox_3` @@ -188,7 +188,7 @@ namespace CGAL { * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `PolygonMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `PolygonMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, * providing the functor `Construct_bbox_3` and the function * `Construct_bbox_3 construct_bbox_3_object()`. `Construct_bbox_3` diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/border.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/border.h index 43dc3381ecd..6c30cb6d077 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/border.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/border.h @@ -155,7 +155,7 @@ namespace Polygon_mesh_processing { * @tparam PolygonMesh model of `HalfedgeGraph`. If `PolygonMesh` * has an internal property map * for `CGAL::face_index_t` and no `face_index_map` is given - * as a named parameter, then the internal one should be initialized + * as a named parameter, then the internal one must be initialized * @tparam FaceRange range of `boost::graph_traits::%face_descriptor`, model of `Range`. Its iterator type is `InputIterator`. diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/compute_normal.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/compute_normal.h index 900e8abd7d6..3fc5faadc0f 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/compute_normal.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/compute_normal.h @@ -109,7 +109,7 @@ void sum_normals(const PM& pmesh, * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for -* `CGAL::vertex_point_t` should be available in `PolygonMesh`\cgalParamEnd +* `CGAL::vertex_point_t` must be available in `PolygonMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `Kernel`\cgalParamEnd * \cgalNamedParamsEnd * @@ -168,7 +168,7 @@ compute_face_normal(typename boost::graph_traits::face_descriptor f * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for -* `CGAL::vertex_point_t` should be available in `PolygonMesh`\cgalParamEnd +* `CGAL::vertex_point_t` must be available in `PolygonMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `Kernel`\cgalParamEnd * \cgalNamedParamsEnd * @@ -205,7 +205,7 @@ compute_face_normals(const PolygonMesh& pmesh * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for -* `CGAL::vertex_point_t` should be available in `PolygonMesh`\cgalParamEnd +* `CGAL::vertex_point_t` must be available in `PolygonMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `Kernel`\cgalParamEnd * \cgalNamedParamsEnd * @@ -285,7 +285,7 @@ compute_vertex_normal(typename boost::graph_traits::vertex_descript * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for -* `CGAL::vertex_point_t` should be available in `PolygonMesh`\cgalParamEnd +* `CGAL::vertex_point_t` must be available in `PolygonMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `Kernel`\cgalParamEnd * \cgalNamedParamsEnd * @@ -331,7 +331,7 @@ compute_vertex_normals(const PolygonMesh& pmesh * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for -* `CGAL::vertex_point_t` should be available in `PolygonMesh`\cgalParamEnd +* `CGAL::vertex_point_t` must be available in `PolygonMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `Kernel`\cgalParamEnd * \cgalNamedParamsEnd * diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/connected_components.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/connected_components.h index b08cea61b7e..c72b3d54d98 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/connected_components.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/connected_components.h @@ -183,7 +183,7 @@ connected_component(typename boost::graph_traits::face_descriptor s * \ingroup keep_connected_components_grp * computes for each face the index of the corresponding connected component. * - * A property map for `CGAL::face_index_t` should be either available as an internal property map + * A property map for `CGAL::face_index_t` must be either available as an internal property map * to `pmesh` or provided as one of the \ref pmp_namedparameters "Named Parameters". * * \tparam PolygonMesh a model of `FaceListGraph` @@ -269,7 +269,7 @@ void keep_connected_components(PolygonMesh& pmesh * Keep `nb_components_to_keep` largest connected components. * * Property maps for `CGAL::face_index_t` and `CGAL::vertex_index_t` - * should be either available as internal property maps + * must be either available as internal property maps * to `pmesh` or provided as \ref pmp_namedparameters "Named Parameters". * * \tparam PolygonMesh a model of `FaceListGraph` and `MutableFaceGraph` @@ -352,7 +352,7 @@ std::size_t keep_largest_connected_components(PolygonMesh& pmesh, * removes connected components with less than a given number of faces. * * Property maps for `CGAL::face_index_t` and `CGAL::vertex_index_t` - * should be either available as internal property maps + * must be either available as internal property maps * to `pmesh` or provided as \ref pmp_namedparameters "Named Parameters". * * \tparam PolygonMesh a model of `FaceListGraph` and `MutableFaceGraph` @@ -567,7 +567,7 @@ void keep_or_remove_connected_components(PolygonMesh& pmesh * then the behavior of this function is undefined. * * Property maps for `CGAL::vertex_index_t` -* should be either available as internal property map +* must be either available as internal property map * to `pmesh` or provided as \ref pmp_namedparameters "Named Parameters". * * \tparam PolygonMesh a model of `FaceListGraph` and `MutableFaceGraph` @@ -610,7 +610,7 @@ void keep_connected_components(PolygonMesh& pmesh * then the behavior of this function is undefined. * * Property maps for `CGAL::vertex_index_t` -* should be either available as internal property map +* must be either available as internal property map * to `pmesh` or provided as \ref pmp_namedparameters "Named Parameters". * * @@ -651,7 +651,7 @@ void remove_connected_components(PolygonMesh& pmesh * and removes the other connected components and all isolated vertices. * * Property maps for `CGAL::face_index_t` and `CGAL::vertex_index_t` -* should be either available as internal property maps +* must be either available as internal property maps * to `pmesh` or provided as \ref pmp_namedparameters "Named Parameters". * * \note If the removal of the connected components makes `pmesh` a non-manifold surface, @@ -709,7 +709,7 @@ void remove_connected_components(PolygonMesh& pmesh * and removes the other connected components and all isolated vertices. * * Property maps for `CGAL::face_index_t` and `CGAL::vertex_index_t` -* should be either available as internal property maps +* must be either available as internal property maps * to `pmesh` or provided as \ref pmp_namedparameters "Named Parameters". * * \note If the removal of the connected components makes `pmesh` a non-manifold surface, diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/corefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/corefinement.h index c6f4c83e0fd..b92329c24d4 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/corefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/corefinement.h @@ -144,7 +144,7 @@ bool recursive_does_bound_a_volume(const TriangleMesh& tm, * \cgalParamBegin{vertex_point_map} * the property map with the points associated to the vertices of `tm`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `TriangleMesh` + * `CGAL::vertex_point_t` must be available in `TriangleMesh` * \cgalParamEnd * \cgalParamBegin{face_index_map} * a property map containing the index of each face of `tm`. @@ -453,7 +453,7 @@ boolean_operation( TriangleMesh& tm1, * \cgalParamBegin{vertex_point_map} * the property map with the points associated to the vertices of `tm1` (`tm2`). * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `TriangleMesh` + * `CGAL::vertex_point_t` must be available in `TriangleMesh` * \cgalParamEnd * \cgalParamBegin{edge_is_constrained_map} a property map containing the * constrained-or-not status of each edge of `tm1` (`tm2`). @@ -470,7 +470,7 @@ boolean_operation( TriangleMesh& tm1, * \cgalParamBegin{vertex_point_map} * the property map with the points associated to the vertices of `tm_out`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `TriangleMesh` + * `CGAL::vertex_point_t` must be available in `TriangleMesh` * \cgalParamEnd * \cgalParamBegin{edge_is_constrained_map} a property map containing the * constrained-or-not status of each edge of `tm_out`. An edge of `tm_out` is constrained @@ -597,7 +597,7 @@ corefine_and_compute_difference( TriangleMesh& tm1, * \cgalParamBegin{vertex_point_map} * the property map with the points associated to the vertices of `tm1` (`tm2`). * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `TriangleMesh` + * `CGAL::vertex_point_t` must be available in `TriangleMesh` * \cgalParamEnd * \cgalParamBegin{edge_is_constrained_map} a property map containing the * constrained-or-not status of each edge of `tm1` (`tm2`) @@ -690,7 +690,7 @@ namespace experimental { * \cgalParamBegin{vertex_point_map} * the property map with the points associated to the vertices of `tm`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `TriangleMesh` + * `CGAL::vertex_point_t` must be available in `TriangleMesh` * \cgalParamEnd * \cgalParamBegin{edge_is_constrained_map} a property map containing the * constrained-or-not status of each edge of `tm` @@ -756,7 +756,7 @@ namespace experimental { * \cgalParamBegin{vertex_point_map} * the property map with the points associated to the vertices of `tm`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `TriangleMesh` + * `CGAL::vertex_point_t` must be available in `TriangleMesh` * \cgalParamEnd * \cgalParamBegin{edge_is_constrained_map} a property map containing the * constrained-or-not status of each edge of `tm` diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/detect_features.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/detect_features.h index ea86140bca8..330e348277b 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/detect_features.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/detect_features.h @@ -252,7 +252,7 @@ template::%edge_descriptor` - * as key type and `bool` as value type. It should be default constructible. + * as key type and `bool` as value type. It must be default constructible. * \tparam NamedParameters a sequence of \ref pmp_namedparameters "Named Parameters" * * \param pmesh the polygon mesh @@ -380,7 +380,7 @@ namespace internal * computing a * surface patch id for each face. * - * A property map for `CGAL::face_index_t`should be either available + * A property map for `CGAL::face_index_t` must be either available * as an internal property map to `pmesh` or provided as one of the Named Parameters. * * \tparam PolygonMesh a model of `FaceGraph` diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/distance.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/distance.h index 76fa27eb53d..cbde9dc433c 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/distance.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/distance.h @@ -244,7 +244,7 @@ sample_triangles(const FaceRange& triangles, * \cgalParamBegin{vertex_point_map} the property map with the points * associated to the vertices of `tm`. If this parameter is omitted, * an internal property map for `CGAL::vertex_point_t` - * should be available for `TriangleMesh`. + * must be available for `TriangleMesh`. * \cgalParamEnd * \cgalParamBegin{geom_traits} a model of `PMPDistanceTraits`. \cgalParamEnd * \cgalParamBegin{use_random_uniform_sampling} @@ -611,8 +611,8 @@ double approximate_Hausdorff_distance( * * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `tm2` - * If this parameter is omitted, an internal property map for CGAL::vertex_point_t should be available in `TriangleMesh` - * and in all places where vertex_point_map is used. + * If this parameter is omitted, an internal property map for `CGAL::vertex_point_t` must be available in `TriangleMesh` + * and in all places where `vertex_point_map` is used. * \cgalParamEnd * \cgalNamedParamsEnd * The function `CGAL::parameters::all_default()` can be used to indicate to use the default values for @@ -671,7 +671,7 @@ double approximate_symmetric_Hausdorff_distance( * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} * the property map with the points associated to the vertices of `tm`. If this parameter is omitted, - * an internal property map for `CGAL::vertex_point_t` should be available for the + * an internal property map for `CGAL::vertex_point_t` must be available for the vertices of `tm` \cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `PMPDistanceTraits`\cgalParamEnd * \cgalNamedParamsEnd @@ -708,7 +708,7 @@ double max_distance_to_triangle_mesh(const PointRange& points, * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} * the property map with the points associated to the vertices of `tm`. If this parameter is omitted, - * an internal property map for `CGAL::vertex_point_t` should be available for the + * an internal property map for `CGAL::vertex_point_t` must be available for the vertices of `tm` \cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `PMPDistanceTraits`. \cgalParamEnd * \cgalNamedParamsEnd diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/fair.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/fair.h index e955324d22c..ecc2f3ebdad 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/fair.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/fair.h @@ -96,7 +96,7 @@ namespace internal { \cgalNamedParamsBegin \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `tmesh`. If this parameter is omitted, an internal property map for - `CGAL::vertex_point_t` should be available in `TriangleMesh`\cgalParamEnd + `CGAL::vertex_point_t` must be available in `TriangleMesh`\cgalParamEnd \cgalParamBegin{fairing_continuity} tangential continuity of the output surface patch. The larger `fairing_continuity` gets, the more fixed vertices are required \cgalParamEnd \cgalParamBegin{sparse_linear_solver} an instance of the sparse linear solver used for fairing \cgalParamEnd \cgalNamedParamsEnd diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Isotropic_remeshing/remesh_impl.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Isotropic_remeshing/remesh_impl.h index 97a400388ce..acf556b71e3 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Isotropic_remeshing/remesh_impl.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Isotropic_remeshing/remesh_impl.h @@ -331,8 +331,6 @@ namespace internal { { tag_halfedges_status(face_range); //called first - constrain_patch_corners(face_range); - BOOST_FOREACH(face_descriptor f, face_range) { if (is_degenerate_triangle_face(halfedge(f,mesh_),mesh_,vpmap_,GeomTraits())){ @@ -663,29 +661,30 @@ namespace internal { vertex_descriptor va = source(he, mesh_); vertex_descriptor vb = target(he, mesh_); - bool swap_done = false; - if (is_on_patch_border(va) && !is_on_patch_border(vb)) + bool is_va_constrained = is_constrained(va) || is_on_patch_border(va); + bool is_vb_constrained = is_constrained(vb) || is_on_patch_border(vb); + + + // do not collapse edge with two constrained vertices + if (is_va_constrained && is_vb_constrained) continue; + + bool can_swap = !is_vb_constrained; + if (is_va_constrained) { he = opposite(he, mesh_); - va = source(he, mesh_); - vb = target(he, mesh_); - swap_done = true; - CGAL_assertion(is_on_patch_border(vb) && !is_on_patch_border(va)); + e=edge(he, mesh_); + std::swap(va, vb); + can_swap=false; } if(!collapse_does_not_invert_face(he)) { - if (!swap_done//if swap has already been done, don't re-swap - && collapse_does_not_invert_face(opposite(he, mesh_))) + if (can_swap//if swap allowed (no constrained vertices) + && collapse_does_not_invert_face(opposite(he, mesh_))) { he = opposite(he, mesh_); - va = source(he, mesh_); - vb = target(he, mesh_); - - if (is_on_patch_border(va) && !is_on_patch_border(vb)) - continue;//we cannot swap again. It would lead to a face inversion - else if (is_corner(va) && !is_corner(vb)) - continue;//idem + e=edge(he, mesh_); + std::swap(va, vb); } else continue;//both directions invert a face @@ -693,9 +692,7 @@ namespace internal { CGAL_assertion(collapse_does_not_invert_face(he)); CGAL_assertion(is_collapse_allowed(e)); - if (degree(va, mesh_) < 3 - || degree(vb, mesh_) < 3 - || !CGAL::Euler::does_satisfy_link_condition(e, mesh_))//necessary to collapse + if (!CGAL::Euler::does_satisfy_link_condition(e, mesh_))//necessary to collapse continue; //check that collapse would not create an edge with length > high @@ -710,9 +707,9 @@ namespace internal { break; } } - //before collapsing va into vb, check that it does not break a corner - //if it is allowed, perform the collapse - if (collapse_ok && !is_constrained(va) && !is_corner(va)) + // before collapsing va into vb, check that it does not break a corner + // or a constrained vertex + if (collapse_ok) { //"collapse va into vb along e" // remove edges incident to va and vb, because their lengths will change @@ -728,12 +725,13 @@ namespace internal { } //before collapse + halfedge_descriptor he_opp= opposite(he, mesh_); bool mesh_border_case = is_on_border(he); - bool mesh_border_case_opp = is_on_border(opposite(he, mesh_)); - halfedge_descriptor ep_p = prev(opposite(he, mesh_), mesh_); + bool mesh_border_case_opp = is_on_border(he_opp); + halfedge_descriptor ep_p = prev(he_opp, mesh_); halfedge_descriptor epo_p = opposite(ep_p, mesh_); halfedge_descriptor en = next(he, mesh_); - halfedge_descriptor en_p = next(opposite(he, mesh_), mesh_); + halfedge_descriptor en_p = next(he_opp, mesh_); Halfedge_status s_ep_p = status(ep_p); Halfedge_status s_epo_p = status(epo_p); Halfedge_status s_ep = status(prev(he, mesh_)); @@ -743,34 +741,33 @@ namespace internal { //do it before collapse is performed to be sure everything is valid if (!mesh_border_case) merge_status(en, s_epo, s_ep); - if (!mesh_border_case_opp) + if (!mesh_border_case_opp && s_ep_p!=PATCH_BORDER) merge_status(en_p, s_epo_p, s_ep_p); halfedge_and_opp_removed(he); if (!mesh_border_case) halfedge_and_opp_removed(prev(he, mesh_)); if (!mesh_border_case_opp) - halfedge_and_opp_removed(prev(opposite(he, mesh_), mesh_)); - - //constrained case - bool constrained_case = is_constrained(va) || is_constrained(vb); - if (constrained_case) { - CGAL_assertion(is_constrained(va) ^ is_constrained(vb));//XOR - set_constrained(va, false); - set_constrained(vb, false); + if (s_ep_p!=PATCH_BORDER) + halfedge_and_opp_removed(prev(he_opp, mesh_)); + else{ + // swap edges so as to keep constained edges: + // replace en_p by epo_p and ep_p by eno_p + ::CGAL::internal::swap_edges(en_p, epo_p, mesh_); + CGAL_assertion(is_valid(mesh_)); + } } //perform collapse - Point target_point = get(vpmap_, vb); + CGAL_assertion(target(halfedge(e, mesh_), mesh_) == vb); vertex_descriptor vkept = CGAL::Euler::collapse_edge(e, mesh_); - put(vpmap_, vkept, target_point); + CGAL_assertion(is_valid(mesh_)); + CGAL_assertion(vkept == vb);//is the constrained point still here ++nb_collapses; //fix constrained case - if (constrained_case)//we have made sure that collapse goes to constrained vertex - set_constrained(vkept, true); - + CGAL_assertion((is_constrained(vkept) || is_on_patch_border(vb)) == (is_va_constrained || is_vb_constrained)); fix_degenerate_faces(vkept, short_edges, sq_low); #ifdef CGAL_PMP_REMESHING_DEBUG @@ -944,10 +941,10 @@ namespace internal { else if (is_on_patch(v)) { - Vector_3 vn = PMP::compute_vertex_normal(v, mesh_ - , PMP::parameters::vertex_point_map(vpmap_) - .geom_traits(GeomTraits())); - put(propmap_normals, v, vn); + Vector_3 vn = PMP::compute_vertex_normal(v, mesh_ + , PMP::parameters::vertex_point_map(vpmap_) + .geom_traits(GeomTraits())); + put(propmap_normals, v, vn); Vector_3 move = CGAL::NULL_VECTOR; unsigned int star_size = 0; @@ -1369,10 +1366,6 @@ private: { return get(vcmap_, v); } - void set_constrained(const vertex_descriptor& v, const bool b) - { - put(vcmap_, v, b); - } bool is_isolated(const vertex_descriptor& v) const { return halfedges_around_target(v, mesh_).empty(); @@ -1415,43 +1408,6 @@ private: return PMP::compute_face_normal(f, mesh_, parameters::vertex_point_map(vpmap_)); } - template - void constrain_patch_corners(const FaceRange& face_range) - { - boost::container::flat_set visited; - - BOOST_FOREACH(face_descriptor f, face_range) - { - BOOST_FOREACH(halfedge_descriptor h, - halfedges_around_face(halfedge(f, mesh_), mesh_)) - { - vertex_descriptor vt = target(h, mesh_); - //treat target(h, mesh_) - if (visited.find(vt) != visited.end()) - continue;//already treated - - if (status(h) == PATCH)//h not on patch boundary - continue; //so neither is target(h, mesh_) - - //count incident MESH_BORDER edges - unsigned int nb_incident_borders = 0; - BOOST_FOREACH(halfedge_descriptor hv, - halfedges_around_target(h, mesh_)) - { - CGAL_assertion(vt == target(hv, mesh_)); - if ( (status(hv) == PATCH_BORDER && status(opposite(hv, mesh_)) == MESH_BORDER) - || (status(hv) == MESH_BORDER && status(opposite(hv, mesh_)) == PATCH_BORDER)) - nb_incident_borders++; - } - - if (nb_incident_borders == 1) //this is a special corner - set_constrained(vt, true); - - visited.insert(vt); - } - } - } - template void tag_halfedges_status(const FaceRange& face_range) { diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/intersection.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/intersection.h index 4a841e38e2c..16986c73b1b 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/intersection.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/intersection.h @@ -383,7 +383,7 @@ struct Throw_at_first_output { * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `TriangleMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `TriangleMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `PMPSelfIntersectionTraits` \cgalParamEnd * \cgalNamedParamsEnd * \return `out` @@ -503,7 +503,7 @@ compute_face_face_intersection(const FaceRange& face_range1, * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `tm`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `TriangleMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `TriangleMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `PMPSelfIntersectionTraits` \cgalParamEnd * \cgalNamedParamsEnd * \return `out` @@ -627,7 +627,7 @@ compute_face_polyline_intersection( const FaceRange& face_range, * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `tm`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `TriangleMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `TriangleMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `PMPSelfIntersectionTraits` \cgalParamEnd * \cgalNamedParamsEnd * \return `out` @@ -934,7 +934,7 @@ compute_polylines_polylines_intersection(const PolylineRange& polylines1, * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `TriangleMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `TriangleMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `PMPSelfIntersectionTraits` \cgalParamEnd * \cgalNamedParamsEnd * \return `out` @@ -983,7 +983,7 @@ compute_face_face_intersection(const TriangleMesh& tm1, * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `TriangleMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `TriangleMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `PMPSelfIntersectionTraits` \cgalParamEnd * \cgalNamedParamsEnd * \return `out` @@ -1189,7 +1189,7 @@ bool do_intersect(const Polyline& polyline1, * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `tm1` (tm2`). * \attention The two property maps must have the same `value_type`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `TriangleMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `TriangleMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `PMPSelfIntersectionTraits` \cgalParamEnd * \cgalParamBegin{do_overlap_test_of_bounded_sides} if set to `true` tests also the overlap of the bounded sides of `tm1` and `tm2`. * If `false` (default), only the intersection of surface triangles are tested. @@ -1273,7 +1273,7 @@ bool do_intersect(const TriangleMesh& tm1, * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `tm`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `TriangleMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `TriangleMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `PMPSelfIntersectionTraits` \cgalParamEnd * \cgalNamedParamsEnd * @@ -1329,7 +1329,7 @@ bool do_intersect(const TriangleMesh& tm, * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `tn`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `TriangleMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `TriangleMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `PMPSelfIntersectionTraits` \cgalParamEnd * \cgalNamedParamsEnd * @@ -1550,13 +1550,13 @@ struct Mesh_callback * \cgalParamEnd * \cgalNamedParamsEnd * \param nps an optional range of `vertex_point_map` named parameters containing the `VertexPointMap` of each mesh in `range`, in the same order. - * If this parameter is omitted, then an internal property map for `CGAL::vertex_point_t` should be available for every mesh in the range. + * If this parameter is omitted, then an internal property map for `CGAL::vertex_point_t` must be available for every mesh in the range. * All the vertex point maps must be of the same type. * * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of a mesh. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in the triangle mesh type used in the range + * `CGAL::vertex_point_t` must be available in the triangle mesh type used in the range * \cgalParamEnd * \cgalNamedParamsEnd */ diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/measure.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/measure.h index 358b5750667..e630333f6eb 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/measure.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/measure.h @@ -73,7 +73,7 @@ public: * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `PolygonMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `PolygonMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `Kernel`\cgalParamEnd * \cgalNamedParamsEnd * @@ -154,7 +154,7 @@ public: * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `PolygonMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `PolygonMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `Kernel`\cgalParamEnd * \cgalNamedParamsEnd * @@ -217,7 +217,7 @@ public: * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `PolygonMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `PolygonMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `Kernel`\cgalParamEnd * \cgalNamedParamsEnd * @@ -293,7 +293,7 @@ public: * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `TriangleMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `TriangleMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `Kernel`\cgalParamEnd * \cgalNamedParamsEnd * @@ -367,7 +367,7 @@ public: * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `TriangleMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `TriangleMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `Kernel` \cgalParamEnd * \cgalNamedParamsEnd * @@ -426,7 +426,7 @@ public: * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `TriangleMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `TriangleMesh`\cgalParamEnd * \cgalParamBegin{geom_traits}an instance of a geometric traits class, model of `Kernel`\cgalParamEnd * \cgalNamedParamsEnd * @@ -479,7 +479,7 @@ public: * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `TriangleMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `TriangleMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `Kernel`\cgalParamEnd * \cgalNamedParamsEnd * diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index 7fa9845c48b..7434a130cec 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -456,7 +456,7 @@ void recursive_orient_volume_ccs( TriangleMesh& tm, * \cgalParamBegin{vertex_point_map} * the property map with the points associated to the vertices of `tm`. * If this parameter is omitted, an internal property map for -* `CGAL::vertex_point_t` should be available in `TriangleMesh` +* `CGAL::vertex_point_t` must be available in `TriangleMesh` * \cgalParamEnd * \cgalParamBegin{face_index_map} * a property map containing the index of each face of `tm`. @@ -561,7 +561,7 @@ void orient(TriangleMesh& tm) * \cgalParamBegin{vertex_point_map} * the property map with the points associated to the vertices of `tm`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `TriangleMesh` + * `CGAL::vertex_point_t` must be available in `TriangleMesh` * \cgalParamEnd * \cgalParamBegin{face_index_map} * a property map containing the index of each face of `tm`. diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/random_perturbation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/random_perturbation.h index d0fac0391c0..ea7362e1a95 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/random_perturbation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/random_perturbation.h @@ -135,7 +135,7 @@ namespace internal { * constrained-or-not status of each vertex of `tmesh`. A constrained vertex * cannot be modified at all during perturbation * \cgalParamEnd -* \cgalParamBegin{do_project} a boolean that sets whether vertices should be reprojected +* \cgalParamBegin{do_project} a boolean that sets whether vertices are reprojected * on the input surface after their coordinates random perturbation * \cgalParamEnd * \cgalParamBegin{random_seed} a non-negative integer value to seed the random diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine.h index a2be7b0ca52..8a6319284b5 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine.h @@ -57,7 +57,7 @@ namespace Polygon_mesh_processing { \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `tmesh` Instance of a class model of `ReadWritePropertyMap`. If this parameter is omitted, an internal property map for - `CGAL::vertex_point_t` should be available in `TriangleMesh` + `CGAL::vertex_point_t` must be available in `TriangleMesh` \cgalParamEnd \cgalParamBegin{density_control_factor} factor to control density of the output mesh, where larger values lead to denser refinements. diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/remesh.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/remesh.h index 4a7dc4daead..d689e3db724 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/remesh.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/remesh.h @@ -63,7 +63,7 @@ namespace Polygon_mesh_processing { * If `0` is passed then only the edge-flip, tangential relaxation, and projection steps will be done. * @param np optional sequence of \ref pmp_namedparameters "Named Parameters" among the ones listed below * -* @pre if constraints protection is activated, the constrained edges should +* @pre if constraints protection is activated, the constrained edges must * not be longer than 4/3*`target_edge_length` * * \cgalNamedParamsBegin diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair.h index 46a46db6e3b..6fcb1e929dd 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair.h @@ -676,7 +676,7 @@ std::size_t remove_null_edges( /// \cgalNamedParamsBegin /// \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. The type of this map is model of `ReadWritePropertyMap`. /// If this parameter is omitted, an internal property map for -/// `CGAL::vertex_point_t` should be available in `TriangleMesh` +/// `CGAL::vertex_point_t` must be available in `TriangleMesh` /// \cgalParamEnd /// \cgalParamBegin{geom_traits} a geometric traits class instance. /// The traits class must provide the nested type `Point_3`, diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h index 415a6641d4e..230870511b8 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h @@ -253,7 +253,7 @@ self_intersections( const FaceRange& face_range, * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `TriangleMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `TriangleMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `PMPSelfIntersectionTraits` \cgalParamEnd * \cgalNamedParamsEnd * @@ -312,7 +312,7 @@ self_intersections(const TriangleMesh& tmesh, OutputIterator out) * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `TriangleMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `TriangleMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `PMPSelfIntersectionTraits` \cgalParamEnd * \cgalNamedParamsEnd @@ -403,7 +403,7 @@ OutputIterator self_intersections(const FaceRange& face_range, * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `tmesh`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `TriangleMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `TriangleMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `PMPSelfIntersectionTraits` \cgalParamEnd * \cgalNamedParamsEnd * @@ -445,11 +445,11 @@ bool does_self_intersect(const TriangleMesh& tmesh * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `tmesh`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `TriangleMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `TriangleMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `SelfIntersectionTraits` \cgalParamEnd * \cgalNamedParamsEnd * - * @return true if the faces in `face_range` self-intersects + * @return true if the faces in `face_range` self-intersect */ template diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/transform.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/transform.h index bf11b1a4856..efff419092c 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/transform.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/transform.h @@ -44,7 +44,7 @@ namespace Polygon_mesh_processing{ * * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `mesh`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `PolygonMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `PolygonMesh`\cgalParamEnd * \cgalNamedParamsEnd * */ @@ -62,6 +62,15 @@ void transform(const Transformation& transformation, put(vpm, vd, transformation(get(vpm, vd))); } } + +/// \cond SKIP_IN_MANUAL +template +void transform(const Transformation& transformation, + PolygonMesh& mesh) +{ + transform(transformation, mesh, parameters::all_default()); +} +/// \endcond } } diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/triangulate_faces.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/triangulate_faces.h index 5c4c5fad8ab..be59a7eb69a 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/triangulate_faces.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/triangulate_faces.h @@ -412,7 +412,7 @@ public: * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for -* `CGAL::vertex_point_t` should be available in `PolygonMesh`\cgalParamEnd +* `CGAL::vertex_point_t` must be available in `PolygonMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} a geometric traits class instance \cgalParamEnd * \cgalNamedParamsEnd * @@ -464,7 +464,7 @@ bool triangulate_face(typename boost::graph_traits::face_descriptor * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for -* `CGAL::vertex_point_t` should be available in `PolygonMesh`\cgalParamEnd +* `CGAL::vertex_point_t` must be available in `PolygonMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} a geometric traits class instance \cgalParamEnd * \cgalNamedParamsEnd * @@ -511,7 +511,7 @@ bool triangulate_faces(FaceRange face_range, PolygonMesh& pmesh) * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for -* `CGAL::vertex_point_t` should be available in `PolygonMesh`\cgalParamEnd +* `CGAL::vertex_point_t` must be available in `PolygonMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} a geometric traits class instance \cgalParamEnd * \cgalNamedParamsEnd * diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/triangulate_hole.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/triangulate_hole.h index ffd95e7cc6a..24c2983604b 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/triangulate_hole.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/triangulate_hole.h @@ -64,7 +64,7 @@ namespace Polygon_mesh_processing { \cgalNamedParamsBegin \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. If this parameter is omitted, an internal property map for - `CGAL::vertex_point_t` should be available in `PolygonMesh`\cgalParamEnd + `CGAL::vertex_point_t` must be available in `PolygonMesh`\cgalParamEnd \cgalParamBegin{use_delaunay_triangulation} if `true`, use the Delaunay triangulation facet search space \cgalParamEnd \cgalParamBegin{geom_traits} a geometric traits class instance \cgalParamEnd \cgalNamedParamsEnd diff --git a/Polyhedron/demo/Polyhedron/C3t3_type.h b/Polyhedron/demo/Polyhedron/C3t3_type.h index 639242b908b..d059f437a35 100644 --- a/Polyhedron/demo/Polyhedron/C3t3_type.h +++ b/Polyhedron/demo/Polyhedron/C3t3_type.h @@ -10,13 +10,11 @@ #include "SMesh_type.h" #ifdef CGAL_MESH_3_DEMO_ACTIVATE_SEGMENTED_IMAGES #include "Image_type.h" -#include +#include #include -#include "Polyhedron_demo_mesh_3_labeled_mesh_domain_3.h" #endif #ifdef CGAL_MESH_3_DEMO_ACTIVATE_IMPLICIT_FUNCTIONS #include "implicit_functions/Implicit_function_interface.h" -#include "Polyhedron_demo_mesh_3_labeled_mesh_domain_3.h" #endif #include @@ -55,14 +53,12 @@ typedef CGAL::Polyhedral_mesh_domain_with_features_3< // The last `Tag_true` says the Patch_id type will be int, and not pair #ifdef CGAL_MESH_3_DEMO_ACTIVATE_SEGMENTED_IMAGES -typedef CGAL::Labeled_image_mesh_domain_3 Image_domain1; -typedef CGAL::Polyhedron_demo_labeled_mesh_domain_3 Image_domain; +typedef CGAL::Labeled_mesh_domain_3 Image_domain; typedef CGAL::Mesh_domain_with_polyline_features_3 Image_mesh_domain; #endif #ifdef CGAL_MESH_3_DEMO_ACTIVATE_IMPLICIT_FUNCTIONS typedef Wrapper Function_wrapper; -typedef CGAL::Labeled_mesh_domain_3 Function_domain; -typedef CGAL::Polyhedron_demo_labeled_mesh_domain_3 Function_mesh_domain; +typedef CGAL::Labeled_mesh_domain_3 Function_mesh_domain; #endif //Robust_cc_geom_traits diff --git a/Polyhedron/demo/Polyhedron/MainWindow.cpp b/Polyhedron/demo/Polyhedron/MainWindow.cpp index 5344f2e6c8d..9fcb2ffb6c9 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.cpp +++ b/Polyhedron/demo/Polyhedron/MainWindow.cpp @@ -2104,6 +2104,8 @@ void MainWindow::insertActionBeforeLoadPlugin(QMenu* menu, QAction* actionToInse void MainWindow::colorItems() { std::size_t nb_files = scene->selectionIndices().size(); + if(nb_files<2) + return; std::vector colors_; colors_.reserve(nb_files); compute_color_map(scene->item(scene->selectionIndices().last())->color(), diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt b/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt index a1fa6892011..d3c8a046946 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt @@ -20,10 +20,10 @@ polyhedron_demo_plugin(polylines_io_plugin Polylines_io_plugin) target_link_libraries(polylines_io_plugin PUBLIC scene_polylines_item) polyhedron_demo_plugin(selection_io_plugin Selection_io_plugin) -target_link_libraries(selection_io_plugin PUBLIC scene_polyhedron_selection_item) +target_link_libraries(selection_io_plugin PUBLIC scene_polyhedron_selection_item selection_plugin) polyhedron_demo_plugin(selection_io_sm_plugin Selection_io_plugin) -target_link_libraries(selection_io_sm_plugin PUBLIC scene_surface_mesh_selection_item) +target_link_libraries(selection_io_sm_plugin PUBLIC scene_surface_mesh_selection_item selection_sm_plugin) polyhedron_demo_plugin(stl_plugin STL_io_plugin) target_link_libraries(stl_plugin PUBLIC scene_polyhedron_item scene_surface_mesh_item scene_polygon_soup_item) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Io_image_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Io_image_plugin.cpp index cdb8af83737..7c3ce0d2beb 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Io_image_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Io_image_plugin.cpp @@ -71,8 +71,8 @@ struct IntConverter { std::pair min_max; int operator()(float f) { - float s = f * (min_max.second - min_max.first); - return s + min_max.first; + float s = f * float((min_max.second - min_max.first)); + return s + float(min_max.first); } }; @@ -163,7 +163,7 @@ public Q_SLOTS: float sum1 = float(a + b + c); float sum2 = float(v.x + v.y + v.z); sum1 /= sum2; - setValue(sum1 * scale); + setValue(sum1 * float(scale)); ready_to_cut = false; } @@ -644,7 +644,10 @@ private: Volume_plane_intersection* i = new Volume_plane_intersection(img->xdim() * img->vx()-1, img->ydim() * img->vy()-1, - img->zdim() * img->vz()-1); + img->zdim() * img->vz()-1, + img->image()->tx, + img->image()->ty, + img->image()->tz); this->intersection_id = scene->addItem(i); scene->changeGroup(i, group); group->lockChild(i); @@ -667,9 +670,9 @@ private: switchReaderConverter< Word >(minmax); - Volume_plane *x_item = new Volume_plane(); - Volume_plane *y_item = new Volume_plane(); - Volume_plane *z_item = new Volume_plane(); + Volume_plane *x_item = new Volume_plane(img->image()->tx,img->image()->ty, img->image()->tz); + Volume_plane *y_item = new Volume_plane(img->image()->tx,img->image()->ty, img->image()->tz); + Volume_plane *z_item = new Volume_plane(img->image()->tx,img->image()->ty, img->image()->tz); x_item->setProperty("img",qVariantFromValue((void*)seg_img)); y_item->setProperty("img",qVariantFromValue((void*)seg_img)); diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp index 6fd110b52c3..83e6ad3f671 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp @@ -294,7 +294,7 @@ void Mesh_3_plugin::mesh_3(const bool surface_only, const bool use_defaults) else if (NULL != image_item) { item = image_item; - features_protection_available = (polylines_item != NULL) || !image_item->isGray(); + features_protection_available = true; bool fit_wrdtp = true; std::size_t img_wdim = image_item->image()->image()->wdim; @@ -462,7 +462,6 @@ void Mesh_3_plugin::mesh_3(const bool surface_only, const bool use_defaults) ui.protectEdges->addItem(QString("Input polylines")); else { - CGAL_assertion(!image_item->isGray()); ui.protectEdges->addItem(QString("Polylines on cube")); } } diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin_cgal_code.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin_cgal_code.cpp index 333dc7862a0..2e67a7c18fc 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin_cgal_code.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin_cgal_code.cpp @@ -19,6 +19,19 @@ using namespace CGAL::Three; typedef Tr::Bare_point Bare_point; +struct Compare_to_isovalue { + double iso_value; + bool less; + typedef bool result_type; + + Compare_to_isovalue(double iso_value, bool less) + : iso_value(iso_value), less(less) {} + + bool operator()(double x) const { + return (x < iso_value) == less; + } +}; + template struct Polyhedral_mesh_domain_selector { @@ -219,9 +232,12 @@ Meshing_thread* cgal_code_mesh_3(const Implicit_function_interface* pfunction, pfunction->bbox().xmax(), pfunction->bbox().ymax(), pfunction->bbox().zmax()); - + namespace p = CGAL::parameters; Function_mesh_domain* p_domain = - new Function_mesh_domain(Function_wrapper(*pfunction), domain_bbox, 1e-7); + new Function_mesh_domain(Function_wrapper(*pfunction), domain_bbox, 1e-7, + p::construct_surface_patch_index = + [](int i, int j) { return (i * 1000 + j); } + ); Scene_c3t3_item* p_new_item = new Scene_c3t3_item; p_new_item->setScene(scene); @@ -246,10 +262,9 @@ Meshing_thread* cgal_code_mesh_3(const Implicit_function_interface* pfunction, #ifdef CGAL_MESH_3_DEMO_ACTIVATE_SEGMENTED_IMAGES -#include +#include -typedef CGAL::Gray_image_mesh_domain_3 Gray_image_domain1; -typedef CGAL::Polyhedron_demo_labeled_mesh_domain_3 Gray_image_domain; +typedef CGAL::Labeled_mesh_domain_3 Gray_image_domain; typedef CGAL::Mesh_domain_with_polyline_features_3 Gray_Image_mesh_domain; Meshing_thread* cgal_code_mesh_3(const Image* pImage, @@ -271,21 +286,7 @@ Meshing_thread* cgal_code_mesh_3(const Image* pImage, { if (NULL == pImage) { return NULL; } - Image_mesh_domain* p_domain = new Image_mesh_domain(*pImage, 1e-6); - - if(protect_features && polylines.empty()) - { - std::vector > polylines_on_bbox; - if(pImage->image()->wordKind == WK_FLOAT) - CGAL::polylines_to_protect(*pImage, polylines_on_bbox); - else //WK_FIXED - CGAL::polylines_to_protect(*pImage, polylines_on_bbox); - - p_domain->add_features(polylines_on_bbox.begin(), polylines_on_bbox.end()); - } if(! polylines.empty()){ - // Insert edge in domain - p_domain->add_features(polylines.begin(), polylines.end()); protect_features = true; // so that it will be passed in make_mesh_3 } Mesh_parameters param; @@ -303,14 +304,30 @@ Meshing_thread* cgal_code_mesh_3(const Image* pImage, p_new_item->setScene(scene); if(!is_gray) { - Image_mesh_domain* p_domain = new Image_mesh_domain(*pImage, 1e-6); + namespace p = CGAL::parameters; + + Image_mesh_domain* p_domain = new Image_mesh_domain + (Image_mesh_domain::create_labeled_image_mesh_domain + (p::image = *pImage, + p::relative_error_bound = 1e-6, + p::construct_surface_patch_index = + [](int i, int j) { return (i * 1000 + j); } + ) + ); if(protect_features && polylines.empty()){ std::vector > polylines_on_bbox; - CGAL::polylines_to_protect< - Bare_point, - Image_mesh_domain::Image_word_type>(*pImage, polylines_on_bbox); - p_domain->add_features(polylines_on_bbox.begin(), polylines_on_bbox.end()); + + CGAL_IMAGE_IO_CASE(pImage->image(), + { + typedef Word Image_word_type; + (CGAL::polylines_to_protect< + Bare_point, + Image_word_type>(*pImage, polylines_on_bbox)); + p_domain->add_features(polylines_on_bbox.begin(), + polylines_on_bbox.end()); + } + ); } if(! polylines.empty()){ // Insert edge in domain @@ -324,20 +341,53 @@ Meshing_thread* cgal_code_mesh_3(const Image* pImage, } else { - if(CGAL::Compare_to_isovalue(iso_value, inside_is_less)(value_outside) !=0) + if(Compare_to_isovalue(iso_value, inside_is_less)(value_outside) !=0) { std::cerr << "Warning : \"Value inside is less than iso value\"'s value has been inverted to avoid crash. " << " " << std::endl; inside_is_less = !inside_is_less; } - Gray_Image_mesh_domain* p_domain = new Gray_Image_mesh_domain(*pImage, CGAL::Compare_to_isovalue(iso_value, inside_is_less), value_outside); + Compare_to_isovalue domain_functor(iso_value, inside_is_less); + namespace p = CGAL::parameters; + Gray_Image_mesh_domain* p_domain = new Gray_Image_mesh_domain + (Gray_Image_mesh_domain::create_gray_image_mesh_domain + (p::image = *pImage, + p::relative_error_bound = 1e-6, + p::image_values_to_subdomain_indices = domain_functor, + p::value_outside = value_outside, + p::construct_surface_patch_index = + [](int i, int j) { return (i * 1000 + j); } + ) + ); if(protect_features && polylines.empty()) { - std::cerr << "Warning : Automatic detection of features" - << " in Gray images is not implemented yet" << std::endl; - //std::vector > polylines_on_bbox; - //CGAL::polylines_to_protect(*pImage, polylines_on_bbox); - //p_domain->add_features(polylines_on_bbox.begin(), polylines_on_bbox.end()); + using CGAL::internal::Mesh_3::Linear_interpolator; + std::vector > polylines_on_bbox; + + CGAL_IMAGE_IO_CASE(pImage->image(), + + typedef Word Image_word_type; + (CGAL::polylines_to_protect + ( *pImage, + pImage->vx(), + pImage->vy(), + pImage->vz(), + polylines_on_bbox, + (Image_word_type*)0, + CGAL::Null_subdomain_index(), + domain_functor, + Linear_interpolator(), + 0, + 0, + Image_word_type(iso_value), + (std::max)(10, int(10 * (std::min)((std::min)(pImage->vx(), + pImage->vy()), + pImage->vz()) + / edge_size)))); + + ); + + p_domain->add_features(polylines_on_bbox.begin(), polylines_on_bbox.end()); } if(! polylines.empty()){ // Insert edge in domain diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_function.h b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_function.h index d5529cf1054..9db5fdb62de 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_function.h +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_function.h @@ -218,12 +218,14 @@ initialize(const Mesh_criteria& criteria, Mesh_fnt::Labeled_image_domain_tag) // for a labeled image { if(p_.detect_connected_components) { - initialize_triangulation_from_labeled_image(c3t3_ - , *domain_ - , *p_.image_3_ptr - , criteria - , typename D_::Image_word_type() - , p_.protect_features); + CGAL_IMAGE_IO_CASE(p_.image_3_ptr->image(), + initialize_triangulation_from_labeled_image(c3t3_ + , *domain_ + , *p_.image_3_ptr + , criteria + , Word() + , p_.protect_features); + ); } else { initialize(criteria, Mesh_fnt::Domain_tag()); } diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Optimization_plugin_cgal_code.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Optimization_plugin_cgal_code.cpp index ae4d364facf..eb618fe9410 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Optimization_plugin_cgal_code.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Optimization_plugin_cgal_code.cpp @@ -111,9 +111,14 @@ Optimizer_thread* cgal_code_optimization(Scene_c3t3_item& c3t3_item, { return NULL; } - - Image_mesh_domain* p_domain = new Image_mesh_domain(*p_image, 1e-6); - + + Image_mesh_domain* p_domain = + new Image_mesh_domain(Image_mesh_domain::create_labeled_image_mesh_domain + (CGAL::parameters::image = *p_image, + CGAL::parameters::relative_error_bound = 1e-6, + CGAL::parameters::construct_surface_patch_index = + [](int i, int j) { return (i * 1000 + j); } )); + // Create thread typedef Optimization_function Opt_function; Opt_function* p_opt_function = new Opt_function(p_result_item->c3t3(), p_domain, param); @@ -182,8 +187,10 @@ Optimizer_thread* cgal_code_optimization(Scene_c3t3_item& c3t3_item, p_function->bbox().zmax()); Function_mesh_domain* p_domain = - new Function_mesh_domain(Function_wrapper(*p_function), dom_bbox, 1e-7); - + new Function_mesh_domain(Function_wrapper(*p_function), dom_bbox, 1e-7, + CGAL::parameters::construct_surface_patch_index = + [](int i, int j) { return (i * 1000 + j); } ); + // Create thread typedef Optimization_function Opt_function; Opt_function* p_opt_function = new Opt_function(p_result_item->c3t3(), p_domain, param); diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Polyhedron_demo_mesh_3_labeled_mesh_domain_3.h b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Polyhedron_demo_mesh_3_labeled_mesh_domain_3.h deleted file mode 100644 index 062d68ee74a..00000000000 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Polyhedron_demo_mesh_3_labeled_mesh_domain_3.h +++ /dev/null @@ -1,291 +0,0 @@ -// Copyright (c) 2009 INRIA Sophia-Antipolis (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org). -// You can redistribute it and/or modify it under the terms of the GNU -// General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: GPL-3.0+ -// -// -// Author(s) : Jane Tournois -// -//****************************************************************************** -// File Description : -// class Labeled_mesh_domain_3. See class description. -//****************************************************************************** - -#ifndef CGAL_POLYHEDRON_DEMO_LABELED_MESH_DOMAIN_3_H -#define CGAL_POLYHEDRON_DEMO_LABELED_MESH_DOMAIN_3_H - -#include -#include -#include "Image_type.h" - -#include - -namespace CGAL { - -struct Compare_to_isovalue { - float iso_value; - bool less; - - Compare_to_isovalue(float iso_value, bool less) - : iso_value(iso_value), less(less) {} - - bool operator()(float x) const { - return (x < iso_value) == less; - } -}; - -/** - * \class Polyhedron_demo_labeled_mesh_domain_3 - * LabeledDomain must be a Labeled_mesh_domain_3 - */ -template -class Polyhedron_demo_labeled_mesh_domain_3 - : public LabeledDomain -{ -public: - typedef LabeledDomain Base; - typedef Polyhedron_demo_labeled_mesh_domain_3 Domain; - - //------------------------------------------------------- - // Index Types - //------------------------------------------------------- - /// Type of indexes for cells of the input complex - typedef typename Base::Subdomain_index Subdomain_index; - typedef boost::optional Subdomain; - - /// Type of indexes for surface patch of the input complex - typedef int Surface_patch_index; - typedef boost::optional Surface_patch; - - typedef typename Base::Point_3 Point_3; - typedef typename Base::Segment_3 Segment_3; - - /// Type of indexes to characterize the lowest dimensional face of the input - /// complex on which a vertex lie - typedef int Index; - typedef CGAL::cpp11::tuple Intersection; - - //constructors - Polyhedron_demo_labeled_mesh_domain_3( - const typename Base::Fct& f, - const typename Base::Bbox_3& bbox, - const typename Base::FT& error_bound = Base::FT(1e-3), - CGAL::Random* p_rng = NULL) - : Base(f, bbox, error_bound, - // Subdomain_index(), Null_subdomain_index(), - p_rng) - {} - - Polyhedron_demo_labeled_mesh_domain_3( - const Image& img, - const typename Base::FT& error_bound = Base::FT(1e-3), - CGAL::Random* p_rng = NULL) - : Base(img, error_bound, - // Subdomain_index(), Null_subdomain_index(), - p_rng) - {} - - ///Constructor for the Gray-level Images - Polyhedron_demo_labeled_mesh_domain_3( - const Image& img, - const Compare_to_isovalue iso_value_transform, - const float value_outside) - : Base(img, iso_value_transform, value_outside) - {} - - /** - * Returns the index to be stored in a vertex lying on the surface identified - * by \c index. - */ - Index index_from_surface_patch_index( - const Surface_patch_index& index) const - { - return Index(index); - } - - Index index_from_surface_patch_index( - const typename Base::Surface_patch_index& index_pair) const - { - return Index(index_pair.first * 1000 + index_pair.second); - } - - Index index_from_surface_patch_index( - const typename Base::Index& index) const - { - return index_from_surface_patch_index(surface_patch_index(index)); - } - - Index index_from_index( - const typename Base::Index& index) const - { - if (const typename Base::Surface_patch_index* index_pair = - boost::get(&index)) - return Index(index_pair->first * 1000 + index_pair->second); - - else if (const typename Base::Subdomain_index* sub_index = - boost::get(&index)) - return Index(*sub_index); - - return Index(-1);//~error - } - - /** - * Returns the index to be stored in a vertex lying in the subdomain - * identified by \c index. - */ - Index index_from_subdomain_index(const Subdomain_index& index) const - { return Index(index); } - - /** - * Returns the \c Surface_patch_index of the surface patch - * where lies a vertex with dimension 2 and index \c index. - */ - Surface_patch_index - surface_patch_index(const Index& index) const - { - return index; - } - - Surface_patch_index - surface_patch_index(const typename Base::Index& index) const - { - typename Base::Surface_patch_index index_pair = - boost::get(index); - return Surface_patch_index(index_pair.first * 1000 + index_pair.second); - } - - typename Base::Surface_patch_index - surface_patch_index_base(const Index& index) const - { - return typename Base::Surface_patch_index(index / 1000, - index % 1000); - } - - /** - * Returns the index of the subdomain containing a vertex - * with dimension 3 and index \c index. - */ - Subdomain_index subdomain_index(const Index& index) const - { return index; } - - // ----------------------------------- - // Backward Compatibility - // ----------------------------------- -#ifndef CGAL_MESH_3_NO_DEPRECATED_SURFACE_INDEX - typedef Surface_patch_index Surface_index; - - Index index_from_surface_index(const Surface_index& index) const - { return index_from_surface_patch_index(index); } - - Surface_index surface_index(const Index& index) const - { return surface_patch_index(index); } -#endif // CGAL_MESH_3_NO_DEPRECATED_SURFACE_INDEX - // ----------------------------------- - // End backward Compatibility - // ----------------------------------- - - - struct Construct_initial_points - { - Construct_initial_points(const Domain& domain) - : r_domain_(domain) {} - - template - OutputIterator operator()(OutputIterator pts, const int n = 12) const - { - typename Base::Construct_initial_points cip = - r_domain_.Base::construct_initial_points_object(); - - std::vector > initial_points; - cip(std::back_inserter(initial_points), n); - - for (std::size_t i = 0; i < initial_points.size(); ++i) - { - std::pair p = initial_points[i]; - *pts++ = std::make_pair(p.first, - r_domain_.surface_patch_index(p.second)); - } - return pts; - } - - private: - const Domain& r_domain_; - }; - - /// Returns Construct_initial_points object - Construct_initial_points construct_initial_points_object() const - { - return Construct_initial_points(*this); - } - - - struct Construct_intersection - { - Construct_intersection(const Domain& domain) - : r_domain_(domain) {} - - template - Intersection operator()(const Query& q) const - { - typename Base::Construct_intersection - ci = r_domain_.Base::construct_intersection_object(); - typename Base::Intersection bi = ci(q); - - return CGAL::cpp11::make_tuple( - CGAL::cpp11::get<0>(bi), - r_domain_.index_from_index(CGAL::cpp11::get<1>(bi)), - CGAL::cpp11::get<2>(bi)); - } - - private: - const Domain& r_domain_; - }; - - /// Returns Construct_intersection object - Construct_intersection construct_intersection_object() const - { - return Construct_intersection(*this); - } - - -private: - ///// Returns Surface_patch_index from \c i and \c j - //typename Base::Surface_patch_index - // make_surface_index(const Subdomain_index i, - // const Subdomain_index j) const - //{ - // if ( i < j ) - // return typename Base::Surface_patch_index(i, j); - // else - // return typename Base::Surface_patch_index(j, i); - //} - - Surface_patch_index - make_surface_index(const Subdomain_index i, - const Subdomain_index j) const - { - if (i < j) - return (i * 1000 + j); - else - return (j * 1000 + i); - } - -}; // end class Labeled_mesh_domain_3 - -} // end namespace CGAL - -#endif // CGAL_POLYHEDRON_DEMO_LABELED_MESH_DOMAIN_3_H - diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Volume_plane.h b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Volume_plane.h index 4824641ed7d..a0bf54f9488 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Volume_plane.h +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Volume_plane.h @@ -59,8 +59,10 @@ struct z_tag {}; template class Volume_plane : public Volume_plane_interface, public Tag { +private : + float tx, ty, tz; public: - Volume_plane(); + Volume_plane(float tx, float ty, float tz); void invalidateOpenGLBuffers() { @@ -75,20 +77,20 @@ public: void compute_bbox(x_tag)const { - _bbox = Bbox(0,0,0, - 0, (adim_ - 1) * yscale_, (bdim_ - 1) * zscale_); + _bbox = Bbox(tx,ty,tz, + tx, ty+(adim_ - 1) * yscale_, tz+(bdim_ - 1) * zscale_); } void compute_bbox(y_tag)const { - _bbox = Bbox(0,0,0, - (adim_ - 1) * xscale_, 0, (bdim_ - 1) * zscale_); + _bbox = Bbox(tx,ty,tz, + tx+(adim_ - 1) * xscale_, ty, tz+(bdim_ - 1) * zscale_); } void compute_bbox(z_tag)const { - _bbox = Bbox(0,0,0, - (adim_ - 1) * xscale_, (bdim_ - 1) * yscale_, 0); + _bbox = Bbox(tx,ty,tz, + tx+(adim_ - 1) * xscale_,ty+ (bdim_ - 1) * yscale_, tz); } void setData(unsigned int adim, unsigned int bdim, unsigned int cdim, @@ -380,8 +382,9 @@ const char* Volume_plane::fragmentShader_bordures_source = template -Volume_plane::Volume_plane() - : Volume_plane_interface(new CGAL::qglviewer::ManipulatedFrame) +Volume_plane::Volume_plane(float tx, float ty, float tz) + : Volume_plane_interface(new CGAL::qglviewer::ManipulatedFrame), + tx(tx), ty(ty), tz(tz) { const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); mFrame_->setPosition(offset.x, offset.y, offset.z); @@ -432,6 +435,7 @@ void Volume_plane::draw(Viewer_interface *viewer) const { mvp.data()[i] = (float)mat[i]; f.data()[i] = (float)mFrame_->matrix()[i]; } + mvp.translate(QVector3D(tx, ty, tz)); program_bordures.bind(); @@ -473,7 +477,7 @@ void Volume_plane::draw(Viewer_interface *viewer) const { cbuffer.bind(); int colorLoc = program.attributeLocation("color"); program.enableAttributeArray(colorLoc); - program.setAttributeBuffer(colorLoc, GL_FLOAT, (currentCube*sizeof(float)) * (bdim_) * (adim_), 1, 0 ); + program.setAttributeBuffer(colorLoc, GL_FLOAT, (currentCube*int(sizeof(float))) * (bdim_) * (adim_), 1, 0 ); cbuffer.release(); @@ -579,7 +583,10 @@ void Volume_plane::init(Viewer_interface* viewer) { for(unsigned int i = 0; i < indices.size(); i+=slice) { QOpenGLBuffer ebo = QOpenGLBuffer(QOpenGLBuffer::IndexBuffer); - unsigned int left_over = (i + slice) > indices.size() ? std::distance(indices.begin() + i, indices.end()) : slice; + unsigned int left_over = + (i + slice) > indices.size() ? + (unsigned int)(std::distance(indices.begin() + i, indices.end())) : + slice; ebo.create(); ebo.bind(); ebo.allocate(&indices[i],static_cast(sizeof(unsigned int) * left_over)); @@ -642,7 +649,7 @@ bool Volume_plane::eventFilter(QObject *, QEvent *event) //is the picked point on the sphere ? for (int i=0; i<4; ++i) { - center = CGAL::qglviewer::Vec(c_spheres[i*3], c_spheres[i*3+1], c_spheres[i*3+2]); + center = CGAL::qglviewer::Vec(c_spheres[i*3]+tx, c_spheres[i*3+1]+ty, c_spheres[i*3+2]+tz); if( (center.x - pos.x) * (center.x - pos.x) + (center.y - pos.y) * (center.y - pos.y) + diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Volume_plane_intersection.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Volume_plane_intersection.cpp index 17556dea369..d48b46f3663 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Volume_plane_intersection.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Volume_plane_intersection.cpp @@ -6,13 +6,16 @@ #include struct Volume_plane_intersection_priv { - Volume_plane_intersection_priv(float x, float y, float z, Volume_plane_intersection* parent) - : a(NULL), b(NULL), c(NULL), x(x), y(y), z(z) , item(parent) + Volume_plane_intersection_priv(float x, float y, float z, + float tx, float ty, float tz, + Volume_plane_intersection* parent) + : a(NULL), b(NULL), c(NULL), x(x), y(y), z(z), + tx(tx), ty(ty), tz(tz), item(parent) { item->are_buffers_filled = false; } Volume_plane_interface *a, *b, *c; - float x, y, z; + float x, y, z, tx, ty, tz; enum VAOs{ AArray = 0, @@ -50,29 +53,29 @@ void Volume_plane_intersection_priv::computeElements() c_vertex.resize(0); const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); - a_vertex.push_back(0.0-offset.x); - a_vertex.push_back(0.0-offset.y); - a_vertex.push_back(0.0-offset.z); - a_vertex.push_back(x -offset.x); - a_vertex.push_back(0.0-offset.y); - a_vertex.push_back(0.0-offset.z); + a_vertex.push_back(0.0-offset.x+tx); + a_vertex.push_back(0.0-offset.y+ty); + a_vertex.push_back(0.0-offset.z+tz); + a_vertex.push_back(x -offset.x+tx); + a_vertex.push_back(0.0-offset.y+ty); + a_vertex.push_back(0.0-offset.z+tz); - b_vertex.push_back(0.0-offset.x); - b_vertex.push_back(0.0-offset.y); - b_vertex.push_back(0.0-offset.z); - b_vertex.push_back(0.0-offset.x); - b_vertex.push_back(y -offset.y); - b_vertex.push_back(0.0-offset.z); + b_vertex.push_back(0.0-offset.x+tx); + b_vertex.push_back(0.0-offset.y+ty); + b_vertex.push_back(0.0-offset.z+tz); + b_vertex.push_back(0.0-offset.x+tx); + b_vertex.push_back(y -offset.y+ty); + b_vertex.push_back(0.0-offset.z+tz); - c_vertex.push_back(0.0-offset.x); - c_vertex.push_back(0.0-offset.y); - c_vertex.push_back(0.0-offset.z); - c_vertex.push_back(0.0-offset.x); - c_vertex.push_back(0.0-offset.y); - c_vertex.push_back(z -offset.z); + c_vertex.push_back(0.0-offset.x+tx); + c_vertex.push_back(0.0-offset.y+ty); + c_vertex.push_back(0.0-offset.z+tz); + c_vertex.push_back(0.0-offset.x+tx); + c_vertex.push_back(0.0-offset.y+ty); + c_vertex.push_back(z -offset.z+tz); - item->_bbox = Scene_item::Bbox( 0, 0, 0, - x, y, z); + item->_bbox = Scene_item::Bbox( tx, ty, tz, + tz+x, ty+y, tz+z); QApplication::restoreOverrideCursor(); } @@ -188,9 +191,10 @@ void Volume_plane_intersection::draw(Viewer_interface* viewer) const { viewer->glDepthRange(0.00001,1.0); } -Volume_plane_intersection::Volume_plane_intersection(float x, float y, float z) +Volume_plane_intersection::Volume_plane_intersection(float x, float y, float z, + float tx, float ty, float tz) :Scene_item(Volume_plane_intersection_priv::NumberOfVbos, Volume_plane_intersection_priv::NumberOfVaos), - d(new Volume_plane_intersection_priv(x,y,z,this)) + d(new Volume_plane_intersection_priv(x,y,z,tx,ty,tz,this)) { setColor(QColor(255, 128, 0)); setName("Volume plane intersection"); diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Volume_plane_intersection.h b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Volume_plane_intersection.h index baf72b36513..d258a4892af 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Volume_plane_intersection.h +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Volume_plane_intersection.h @@ -18,7 +18,7 @@ class Volume_plane_intersection typedef std::pair Interface_pair; Q_OBJECT public: - Volume_plane_intersection(float x, float y, float z); + Volume_plane_intersection(float x, float y, float z, float tx, float ty, float tz); ~Volume_plane_intersection(); bool isFinite() const { return true; } diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Volume_plane_thread.h b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Volume_plane_thread.h index 5c3c14e4d3a..97a336f9b61 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Volume_plane_thread.h +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Volume_plane_thread.h @@ -78,7 +78,8 @@ void X_plane_thread::run() { for(unsigned int i = 0; i < img->xdim(); ++i) { for(unsigned int j = 0; j < img->ydim(); ++j) { for(unsigned int k = 0; k < img->zdim(); ++k) { - float x = CGAL::IMAGEIO::static_evaluate(img->image(), i, j, k); + float x = float(CGAL::IMAGEIO::static_evaluate(img->image(), + i, j, k)); x = clamper(x); buffer.push_back(x); } @@ -98,7 +99,8 @@ void Y_plane_thread::run() { for(unsigned int i = 0; i < img->ydim(); ++i) { for(unsigned int j = 0; j < img->xdim(); ++j) { for(unsigned int k = 0; k < img->zdim(); ++k) { - float x = CGAL::IMAGEIO::static_evaluate(img->image(), j, i, k); + float x = float(CGAL::IMAGEIO::static_evaluate(img->image(), + j, i, k)); x = clamper(x); buffer.push_back(x); } @@ -116,7 +118,8 @@ void Z_plane_thread::run() { for(unsigned int i = 0; i < img->zdim(); ++i) { for(unsigned int j = 0; j < img->xdim(); ++j) { for(unsigned int k = 0; k < img->ydim(); ++k) { - float x = CGAL::IMAGEIO::static_evaluate(img->image(), j, k, i); + float x = float(CGAL::IMAGEIO::static_evaluate(img->image(), + j, k, i)); x = clamper(x); buffer.push_back(x); } diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Affine_transform_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PCA/Affine_transform_plugin.cpp index 891d6d7e7e0..b6e0a942670 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/Affine_transform_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Affine_transform_plugin.cpp @@ -680,9 +680,9 @@ void Polyhedron_demo_affine_transform_plugin::applySingleTransformation() ui.lineEditZ->text().toDouble()); if(!is_point_set) - transform_item->manipulatedFrame()->rotate(CGAL::qglviewer::Quaternion(axis, ui.lineEditA->text().toDouble()*M_PI/180.0)); + transform_item->manipulatedFrame()->rotate(CGAL::qglviewer::Quaternion(axis, ui.lineEditA->text().toDouble()*CGAL_PI/180.0)); else - transform_points_item->manipulatedFrame()->rotate(CGAL::qglviewer::Quaternion(axis, ui.lineEditA->text().toDouble()*M_PI/180.0)); + transform_points_item->manipulatedFrame()->rotate(CGAL::qglviewer::Quaternion(axis, ui.lineEditA->text().toDouble()*CGAL_PI/180.0)); break; } //translation diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Basic_generator_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PCA/Basic_generator_plugin.cpp index 3b4933e54cf..c3b3f4f15ef 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/Basic_generator_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Basic_generator_plugin.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/CMakeLists.txt b/Polyhedron/demo/Polyhedron/Plugins/PMP/CMakeLists.txt index 98ddd774a71..a626bc567d9 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/CMakeLists.txt @@ -87,11 +87,13 @@ polyhedron_demo_plugin(polyhedron_stitching_plugin Polyhedron_stitching_plugin) target_link_libraries(polyhedron_stitching_plugin PUBLIC scene_polyhedron_item scene_surface_mesh_item scene_polylines_item) qt5_wrap_ui( selectionUI_FILES Selection_widget.ui) -polyhedron_demo_plugin(selection_plugin Selection_plugin ${selectionUI_FILES}) +add_library(selection_plugin SHARED Selection_plugin.cpp ${selectionUI_FILES}) +#polyhedron_demo_plugin(selection_plugin Selection_plugin ${selectionUI_FILES}) target_link_libraries(selection_plugin PUBLIC scene_polyhedron_selection_item scene_points_with_normal_item scene_polylines_item) qt5_wrap_ui( selectionUI_FILES Selection_widget.ui) -polyhedron_demo_plugin(selection_sm_plugin Selection_plugin ${selectionUI_FILES}) +add_library(selection_sm_plugin SHARED Selection_plugin.cpp ${selectionUI_FILES}) +#polyhedron_demo_plugin(selection_sm_plugin Selection_plugin ${selectionUI_FILES}) target_link_libraries(selection_sm_plugin PUBLIC scene_surface_mesh_selection_item scene_points_with_normal_item scene_polylines_item) target_compile_definitions(selection_sm_plugin PUBLIC "-DUSE_SURFACE_MESH" ) diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Scene_facegraph_item_k_ring_selection.h b/Polyhedron/demo/Polyhedron/Plugins/PMP/Scene_facegraph_item_k_ring_selection.h index cca1c9db01f..72b65c0f3bb 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Scene_facegraph_item_k_ring_selection.h +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Scene_facegraph_item_k_ring_selection.h @@ -206,8 +206,21 @@ public Q_SLOTS: const CGAL::qglviewer::Vec& point = camera->pointUnderPixel(paint_pos, found) - offset; if(found) { - const CGAL::qglviewer::Vec& orig = camera->position() - offset; - const CGAL::qglviewer::Vec& dir = point - orig; + CGAL::qglviewer::Vec orig; + CGAL::qglviewer::Vec dir; + if(camera->type() == CGAL::qglviewer::Camera::PERSPECTIVE) + { + orig = camera->position() - offset; + dir = point - orig; + } + else + { + dir = camera->viewDirection(); + orig = CGAL::qglviewer::Vec(point.x - dir.x, + point.y - dir.y, + point.z - dir.z); + + } poly_item->select(orig.x, orig.y, orig.z, dir.x, dir.y, dir.z); } viewer->doneCurrent(); @@ -268,7 +281,6 @@ public Q_SLOTS: BOOST_FOREACH(fg_face_descriptor f, face_sel) { - int cc_id = get(fccmap, f); if(is_cc_done[cc_id]) { @@ -287,14 +299,26 @@ public Q_SLOTS: if(total == 0) continue; CGAL::qglviewer::Vec center(x/(double)total, y/(double)total, z/(double)total); - const CGAL::qglviewer::Vec& orig = camera->position() - offset; - CGAL::qglviewer::Vec direction = center - orig; + CGAL::qglviewer::Vec orig; + CGAL::qglviewer::Vec dir; + if(camera->type() == CGAL::qglviewer::Camera::PERSPECTIVE) + { + orig = camera->position() - offset; + dir = center - orig; + } + else + { + dir = camera->viewDirection(); + orig = CGAL::qglviewer::Vec(center.x - dir.x, + center.y - dir.y, + center.z - dir.z); + } if(poly_item->intersect_face(orig.x, orig.y, orig.z, - direction.x, - direction.y, - direction.z, + dir.x, + dir.y, + dir.z, f)) { is_cc_done[cc_id] = true; @@ -367,8 +391,21 @@ public Q_SLOTS: const CGAL::qglviewer::Vec& point = camera->pointUnderPixel(hl_pos, found) - offset; if(found) { - const CGAL::qglviewer::Vec& orig = camera->position() - offset; - const CGAL::qglviewer::Vec& dir = point - orig; + CGAL::qglviewer::Vec orig; + CGAL::qglviewer::Vec dir; + if(camera->type() == CGAL::qglviewer::Camera::PERSPECTIVE) + { + orig = camera->position() - offset; + dir = point - orig; + } + else + { + dir = camera->viewDirection(); + orig = CGAL::qglviewer::Vec(point.x - dir.x, + point.y - dir.y, + point.z - dir.z); + + } is_highlighting = true; poly_item->select(orig.x, orig.y, orig.z, dir.x, dir.y, dir.z); is_highlighting = false; @@ -641,7 +678,10 @@ protected: if(!poly.empty()) for(std::size_t j=0; jdrawLine(poly[j].x(), poly[j].y(), poly[j+1].x(), poly[j+1].y()); + painter->drawLine(int(poly[j].x()), + int(poly[j].y()), + int(poly[j+1].x()), + int(poly[j+1].y())); } } painter->end(); diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Selection_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Selection_plugin.cpp index 885a74ba5ac..a6cf3a63299 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Selection_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Selection_plugin.cpp @@ -761,6 +761,9 @@ public Q_SLOTS: tr("Degenerated faces have been detected. Problems may occur " "for operations other tha \"Move point\". ")); } + //remove lasso mode + selection_item->set_lasso_mode(false); + ui_widget.lassoCheckBox->setChecked(false); Q_EMIT save_handleType(); on_editionBox_changed(ui_widget.editionBox->currentIndex()); break; diff --git a/Polyhedron/demo/Polyhedron/Plugins/Point_set/Features_detection_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Point_set/Features_detection_plugin.cpp index 1f3a07194c7..6e463e7c875 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Point_set/Features_detection_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Point_set/Features_detection_plugin.cpp @@ -1,3 +1,4 @@ +#include #include #include #include diff --git a/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_selection_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_selection_plugin.cpp index ac2c608ad35..14a237d3043 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_selection_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_selection_plugin.cpp @@ -246,10 +246,12 @@ public: const Kernel::Point_3& p = point_set->point (*it); CGAL::qglviewer::Vec vp (p.x (), p.y (), p.z ()); - CGAL::qglviewer::Vec vsp = camera->projectedCoordinatesOf (vp + offset); bool now_selected = false; if(!ui_widget.box->isChecked()) + { + CGAL::qglviewer::Vec vsp = camera->projectedCoordinatesOf (vp + offset); now_selected = visualizer->is_selected (vsp); + } else if(edit_box) { if(p.x() >= edit_box->point(0,0) - offset.x && diff --git a/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh_deformation/Scene_edit_polyhedron_item.h b/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh_deformation/Scene_edit_polyhedron_item.h index 63d178be327..a5eaf6a28d5 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh_deformation/Scene_edit_polyhedron_item.h +++ b/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh_deformation/Scene_edit_polyhedron_item.h @@ -162,9 +162,6 @@ typedef CGAL::Surface_mesh_deformation > Deform_sm_mesh; -typedef Deform_mesh::Point Point; -typedef Deform_sm_mesh::Point SM_Point; - /// For storing associated data with a group of control vertices template class Control_vertices_data diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_plugin_helper.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_plugin_helper.cpp index 0883de288cf..0418d405f72 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_plugin_helper.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_plugin_helper.cpp @@ -8,7 +8,7 @@ void CGAL::Three::Polyhedron_demo_plugin_helper::addDockWidget(QDockWidget* dock_widget) { mw->addDockWidget(::Qt::LeftDockWidgetArea, dock_widget); - dock_widget->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed)); + dock_widget->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred)); QList dockWidgets = mw->findChildren(); int counter = 0; diff --git a/Polyhedron/demo/Polyhedron/Scene_c3t3_item.cpp b/Polyhedron/demo/Polyhedron/Scene_c3t3_item.cpp index d6f2c820ae0..4e3eb0bd689 100644 --- a/Polyhedron/demo/Polyhedron/Scene_c3t3_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_c3t3_item.cpp @@ -790,9 +790,11 @@ Scene_c3t3_item::build_histogram() // draw min value and max value - const int min_tr_width = static_cast(2 * (std::floor(min_value)*cell_width + left_margin)); - const int max_tr_width = static_cast( - 2 * ((histo_data.size() - std::floor(max_value))*cell_width + left_margin)); + const int min_tr_width = + static_cast(2 * (std::floor(min_value)*cell_width + left_margin)); + const int max_tr_width = + static_cast(2 * ((double(histo_data.size()) - + std::floor(max_value))*cell_width + left_margin)); const int tr_y = drawing_height + top_margin + text_margin; painter.setPen(get_histogram_color(min_value)); @@ -828,20 +830,20 @@ Scene_c3t3_item_priv::compute_color_map(const QColor& c) typedef Indices::size_type size_type; const size_type nb_domains = subdomain_indices_.size(); - size_type i = 0; + double i = 0; for (Indices::iterator it = subdomain_indices_.begin(), - end = subdomain_indices_.end(); it != end; ++it, ++i) + end = subdomain_indices_.end(); it != end; ++it, i += 1.) { - double hue = c.hueF() + 1. / nb_domains * i; + double hue = c.hueF() + 1. / double(nb_domains) * i; if (hue > 1) { hue -= 1.; } colors_subdomains[*it] = QColor::fromHsvF(hue, c.saturationF(), c.valueF()); } const size_type nb_patch_indices = surface_patch_indices_.size(); i = 0; for (Indices::iterator it = surface_patch_indices_.begin(), - end = surface_patch_indices_.end(); it != end; ++it, ++i) + end = surface_patch_indices_.end(); it != end; ++it, i += 1.) { - double hue = c.hueF() + 1. / nb_patch_indices * i; + double hue = c.hueF() + 1. / double(nb_patch_indices) * i; if (hue > 1) { hue -= 1.; } colors[*it] = QColor::fromHsvF(hue, c.saturationF(), c.valueF()); } @@ -1422,6 +1424,7 @@ void Scene_c3t3_item_priv::computeIntersection(const Primitive& facet) Geom_traits::Construct_point_3 wp2p = c3t3.triangulation().geom_traits().construct_point_3_object(); + typedef unsigned char UC; Tr::Cell_handle ch = facet.id().first; if(intersected_cells.find(ch) == intersected_cells.end()) { @@ -1432,7 +1435,7 @@ void Scene_c3t3_item_priv::computeIntersection(const Primitive& facet) const Tr::Bare_point& pc = wp2p(ch->vertex(2)->point()); const Tr::Bare_point& pd = wp2p(ch->vertex(3)->point()); - CGAL::Color color(c.red(), c.green(), c.blue()); + CGAL::Color color(UC(c.red()), UC(c.green()), UC(c.blue())); intersection->addTriangle(pb, pa, pc, color); intersection->addTriangle(pa, pb, pd, color); @@ -1452,7 +1455,7 @@ void Scene_c3t3_item_priv::computeIntersection(const Primitive& facet) QColor c = this->colors_subdomains[nh->subdomain_index()].light(50); - CGAL::Color color(c.red(), c.green(), c.blue()); + CGAL::Color color(UC(c.red()), UC(c.green()), UC(c.blue())); intersection->addTriangle(pb, pa, pc, color); intersection->addTriangle(pa, pb, pd, color); @@ -1545,8 +1548,9 @@ void Scene_c3t3_item_priv::computeSpheres() wp2p(vit->point()).y() + offset.y, wp2p(vit->point()).z() + offset.z); float radius = vit->point().weight() ; + typedef unsigned char UC; spheres->add_sphere(Geom_traits::Sphere_3(center, radius), - CGAL::Color(c.red(), c.green(), c.blue())); + CGAL::Color(UC(c.red()), UC(c.green()), UC(c.blue()))); } spheres->invalidateOpenGLBuffers(); } @@ -1568,7 +1572,7 @@ void Scene_c3t3_item_priv::computeElements() float x = (2 * (float)complex_diag()) / 10.0; float y = (2 * (float)complex_diag()) / 10.0; - for (int u = 0; u < 11; u++) + for (float u = 0; u < 11; u += 1.f) { positions_grid.push_back(-(float)complex_diag() + x* u); @@ -1579,7 +1583,7 @@ void Scene_c3t3_item_priv::computeElements() positions_grid.push_back((float)complex_diag()); positions_grid.push_back(0.0); } - for (int v = 0; v<11; v++) + for (float v = 0; v<11; v += 1.f) { positions_grid.push_back(-(float)complex_diag()); @@ -1818,7 +1822,7 @@ void Scene_c3t3_item::set_valid(bool b) } float Scene_c3t3_item::getShrinkFactor() const { - return d->tet_Slider->value()/100.0f; + return float(d->tet_Slider->value())/100.0f; } bool Scene_c3t3_item::keyPressEvent(QKeyEvent *event) { diff --git a/Polyhedron/demo/Polyhedron/Scene_image_item.cpp b/Polyhedron/demo/Polyhedron/Scene_image_item.cpp index 7cece92507f..b0a3d2553ca 100644 --- a/Polyhedron/demo/Polyhedron/Scene_image_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_image_item.cpp @@ -34,6 +34,10 @@ public: double vy() const { return im_.vy(); } double vz() const { return im_.vz(); } + double tx() const { return im_.image()->tx; } + double ty() const { return im_.image()->ty; } + double tz() const { return im_.image()->tz; } + private: unsigned char non_null_neighbor_data(std::size_t i, std::size_t j, @@ -77,12 +81,12 @@ Image_accessor::Image_accessor(const Image& im, int dx, int dy, int dz) } } - int i=0; + double i=0; const double starting_hue = 45./360.; // magenta for ( std::map::iterator it = colors_.begin(), - end = colors_.end() ; it != end ; ++it, ++i ) + end = colors_.end() ; it != end ; ++it, i += 1.) { - double hue = starting_hue + 1./colors_.size() * i; + double hue = starting_hue + 1./double(colors_.size()) * i; if ( hue > 1. ) { hue -= 1.; } it->second = QColor::fromHsvF(hue, .75, .75); } @@ -202,9 +206,9 @@ add_to_normal(unsigned char v, { if ( 0 != v ) { - x += dx; - y += dy; - z += dz; + x += float(dx); + y += float(dy); + z += float(dz); } } @@ -296,9 +300,9 @@ Vertex_buffer_helper::push_color(std::size_t i, std::size_t j, std::size_t k) { const QColor& color = data_.vertex_color(i,j,k); if ( ! color.isValid() ) { return; } - colors_.push_back(color.red()/255.f); - colors_.push_back(color.green()/255.f); - colors_.push_back(color.blue()/255.f); + colors_.push_back(float(color.red())/255.f); + colors_.push_back(float(color.green())/255.f); + colors_.push_back(float(color.blue())/255.f); } void @@ -320,27 +324,26 @@ Vertex_buffer_helper::push_normal(std::size_t i, std::size_t j, std::size_t k) void Vertex_buffer_helper::push_vertex(std::size_t i, std::size_t j, std::size_t k) { - const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); indices_.insert(std::make_pair(compute_position(i,j,k), vertices_.size()/3)); //resize the "border vertices" - double di(i),dj(j),dk(k); + double di = double(i),dj = double(j),dk = double(k); if (di == 0) di = 0.5; if (dj == 0) dj = 0.5; if (dk == 0) dk = 0.5; - if (di == data_.xdim()) - di = data_.xdim()-0.5; - if (dj == data_.ydim()) - dj = data_.ydim()-0.5; - if (dk == data_.zdim()) - dk = data_.zdim()-0.5; + if (di == double(data_.xdim())) + di = double(data_.xdim())-0.5; + if (dj == double(data_.ydim())) + dj = double(data_.ydim())-0.5; + if (dk == double(data_.zdim())) + dk = double(data_.zdim())-0.5; - vertices_.push_back( (di - 0.5) * data_.vx()+offset.x); - vertices_.push_back( (dj - 0.5) * data_.vy()+offset.y); - vertices_.push_back( (dk - 0.5) * data_.vz()+offset.z); + vertices_.push_back( (di - 0.5) * data_.vx() + data_.tx()); + vertices_.push_back( (dj - 0.5) * data_.vy() + data_.ty()); + vertices_.push_back( (dk - 0.5) * data_.vz() + data_.tz()); } void @@ -675,12 +678,12 @@ Scene_image_item::compute_bbox() const if(!m_image) _bbox = Bbox(); else - _bbox = Bbox(0, - 0, - 0, - (m_image->xdim()-1) * m_image->vx(), - (m_image->ydim()-1) * m_image->vy(), - (m_image->zdim()-1) * m_image->vz()); + _bbox = Bbox(m_image->image()->tx, + m_image->image()->ty, + m_image->image()->tz, + m_image->image()->tx+(m_image->xdim()-1) * m_image->vx(), + m_image->image()->ty+(m_image->ydim()-1) * m_image->vy(), + m_image->image()->tz+(m_image->zdim()-1) * m_image->vz()); } void @@ -809,9 +812,9 @@ Scene_image_item_priv::draw_gl(Viewer_interface* viewer) const { vao[0].bind(); if(!is_ogl_4_3) - viewer->glDrawElements(GL_TRIANGLES, m_ibo->size()/sizeof(GLuint), GL_UNSIGNED_INT, 0); + viewer->glDrawElements(GL_TRIANGLES, GLsizei(m_ibo->size()/sizeof(GLuint)), GL_UNSIGNED_INT, 0); else - viewer->glDrawElements(GL_LINES_ADJACENCY, m_ibo->size()/sizeof(GLuint), GL_UNSIGNED_INT, 0); + viewer->glDrawElements(GL_LINES_ADJACENCY, GLsizei(m_ibo->size()/sizeof(GLuint)), GL_UNSIGNED_INT, 0); vao[0].release(); } rendering_program.release(); @@ -833,7 +836,7 @@ Scene_image_item_priv::ibo_size() const GLint nb_elts = m_ibo->size(); m_ibo->release(); - return nb_elts/sizeof(GLuint); + return GLint(nb_elts/sizeof(GLuint)); return 0; } @@ -845,7 +848,7 @@ void Scene_image_item::changed() void Scene_image_item_priv::draw_Bbox(Scene_item::Bbox bbox, std::vector *vertices) { - const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); vertices->push_back(bbox.xmin()+offset.x); vertices->push_back(bbox.ymin()+offset.y); vertices->push_back(bbox.zmin()+offset.z); diff --git a/Polyhedron/demo/Polyhedron/Scene_item.cpp b/Polyhedron/demo/Polyhedron/Scene_item.cpp index a11c68658e8..c4cbea6d3d1 100644 --- a/Polyhedron/demo/Polyhedron/Scene_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_item.cpp @@ -184,16 +184,18 @@ void CGAL::Three::Scene_item::attribBuffers(CGAL::Three::Viewer_interface* viewe if(is_selected) c = c.lighter(120); viewer->getShaderProgram(program_name)->setAttributeValue ("color_facets", - c.redF(), - c.greenF(), - c.blueF()); + GLfloat(c.redF()), + GLfloat(c.greenF()), + GLfloat(c.blueF())); } else if(program_name == PROGRAM_WITH_TEXTURED_EDGES) { if(is_selected) c = c.lighter(50); viewer->getShaderProgram(program_name)->setUniformValue ("color_lines", - QVector3D(c.redF(), c.greenF(), c.blueF())); + QVector3D(float(c.redF()), + float(c.greenF()), + float(c.blueF()))); } viewer->getShaderProgram(program_name)->release(); } diff --git a/Polyhedron/demo/Polyhedron/Scene_plane_item.cpp b/Polyhedron/demo/Polyhedron/Scene_plane_item.cpp index cb7e5ba4d93..630f559f485 100644 --- a/Polyhedron/demo/Polyhedron/Scene_plane_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_plane_item.cpp @@ -84,7 +84,7 @@ void Scene_plane_item::compute_normals_and_vertices(void) const float x = (2*diag)/10.0; float y = (2*diag)/10.0; { - for(int u = 0; u < 11; u++) + for(float u = 0; u < 11; u += 1.f) { positions_lines.push_back(-diag + x* u); @@ -95,7 +95,7 @@ void Scene_plane_item::compute_normals_and_vertices(void) const positions_lines.push_back(diag ); positions_lines.push_back(0.0 ); } - for(int v=0; v<11; v++) + for(float v=0; v<11; v += 1.f) { positions_lines.push_back(-diag ); diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp index e375a6ce04a..e4a6b4eb931 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp @@ -248,6 +248,9 @@ typedef Polygon_soup::Polygon_3 Facet; void Scene_polygon_soup_item_priv::triangulate_polygon(Polygons_iterator pit, int polygon_id) const { + const CGAL::qglviewer::Vec off = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); + EPICK::Vector_3 offset(off.x,off.y,off.z); + //Computes the normal of the facet const Point_3& pa = soup->points[pit->at(0)]; const Point_3& pb = soup->points[pit->at(1)]; @@ -267,7 +270,7 @@ Scene_polygon_soup_item_priv::triangulate_polygon(Polygons_iterator pit, int pol do { FT::PointAndId pointId; - pointId.point = soup->points[pit->at(it)]; + pointId.point = soup->points[pit->at(it)]+offset; pointId.id = pit->at(it); pointIds.push_back(pointId); } while( ++it != it_end ); diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp index e9b878e1c93..58a466c7ad1 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp @@ -480,7 +480,7 @@ Scene_polyhedron_item_priv::triangulate_facet(Scene_polyhedron_item::Facet_itera diagonal = item->diagonalBbox(); else diagonal = 0.0; - FT triangulation(fit,normal,poly,diagonal); + FT triangulation(fit,normal,poly,diagonal,offset); if(triangulation.cdt->dimension() != 2 ) { @@ -515,9 +515,9 @@ Scene_polyhedron_item_priv::triangulate_facet(Scene_polyhedron_item::Facet_itera if(is_multicolor || !no_flat || !is_recent) { - push_back_xyz(ffit->vertex(0)->point()+offset, positions_facets); - push_back_xyz(ffit->vertex(1)->point()+offset, positions_facets); - push_back_xyz(ffit->vertex(2)->point()+offset, positions_facets); + push_back_xyz(ffit->vertex(0)->point(), positions_facets); + push_back_xyz(ffit->vertex(1)->point(), positions_facets); + push_back_xyz(ffit->vertex(2)->point(), positions_facets); if(!draw_two_sides) { push_back_xyz(normal, normals_flat); diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp index c89b80cd686..6df22ab25e7 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp @@ -421,13 +421,16 @@ void Scene_polyhedron_selection_item_priv::triangulate_facet(fg_face_descriptor fit,const Vector normal, std::vector &p_facets,std::vector &p_normals ) const { + const CGAL::qglviewer::Vec off = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); + Kernel::Vector_3 offset(off.x,off.y,off.z); + typedef FacetTriangulator FT; double diagonal; if(item->poly_item->diagonalBbox() != std::numeric_limits::infinity()) diagonal = item->poly_item->diagonalBbox(); else diagonal = 0.0; - FT triangulation(fit,normal,poly,diagonal); + FT triangulation(fit,normal,poly,diagonal, offset); //iterates on the internal faces to add the vertices to the positions //and the normals to the appropriate vectors for(FT::CDT::Finite_faces_iterator @@ -2251,7 +2254,7 @@ void Scene_polyhedron_selection_item::select_boundary() QString Scene_polyhedron_selection_item::toolTip() const { - if(!poly_item->polyhedron()) + if(!poly_item || !poly_item->polyhedron()) return QString(); return QObject::tr("

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

" diff --git a/Polyhedron/demo/Polyhedron/Scene_polylines_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polylines_item.cpp index d9dce50d31f..6565e39515f 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polylines_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polylines_item.cpp @@ -139,7 +139,7 @@ Scene_polylines_item_private::computeElements() const } if(!computed_stats) - mean_length = mean/nb_edges; + mean_length = mean/double(nb_edges); computed_stats = true; QApplication::restoreOverrideCursor(); } @@ -211,7 +211,7 @@ Scene_polylines_item_private::computeSpheres() p_it != end; ++p_it) { const K::Point_3& center = p_it->first; - int colors[3]; + unsigned char colors[3]; switch(p_it->second) { case 1: colors[0] = 0; // black @@ -388,7 +388,7 @@ Scene_polylines_item::drawEdges(CGAL::Three::Viewer_interface* viewer) const { d->initializeBuffers(viewer); } - viewer->glLineWidth(d->line_Slider->value()); + viewer->glLineWidth(GLfloat(d->line_Slider->value())); vaos[Scene_polylines_item_private::Edges]->bind(); attribBuffers(viewer, PROGRAM_NO_SELECTION); QOpenGLShaderProgram *program = getShaderProgram(PROGRAM_NO_SELECTION); diff --git a/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp b/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp index d3de2a71771..90ac461904f 100644 --- a/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp @@ -815,7 +815,9 @@ Scene_surface_mesh_item_priv::triangulate_facet(face_descriptor fd, diagonal = item->diagonalBbox(); else diagonal = 0.0; - FT triangulation(fd,normal,smesh_,diagonal); + const CGAL::qglviewer::Vec off = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); + EPICK::Vector_3 offset(off.x,off.y,off.z); + FT triangulation(fd,normal,smesh_,diagonal, offset); //iterates on the internal faces for(FT::CDT::Finite_faces_iterator ffit = triangulation.cdt->finite_faces_begin(), @@ -834,14 +836,14 @@ Scene_surface_mesh_item_priv::triangulate_facet(face_descriptor fd, else color = 0; - addFlatData(ffit->vertex(0)->point(), + addFlatData(ffit->vertex(0)->point()-offset, (*fnormals)[fd], color); - addFlatData(ffit->vertex(1)->point(), + addFlatData(ffit->vertex(1)->point()-offset, (*fnormals)[fd], color); - addFlatData(ffit->vertex(2)->point(), + addFlatData(ffit->vertex(2)->point()-offset, (*fnormals)[fd], color); } @@ -1557,11 +1559,23 @@ void Scene_surface_mesh_item::zoomToPosition(const QPoint &point, CGAL::Three::V const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); //find clicked facet bool found = false; - const EPICK::Point_3 ray_origin(viewer->camera()->position().x - offset.x, - viewer->camera()->position().y - offset.y, - viewer->camera()->position().z - offset.z); CGAL::qglviewer::Vec point_under = viewer->camera()->pointUnderPixel(point,found); - CGAL::qglviewer::Vec dir = point_under - viewer->camera()->position(); + EPICK::Point_3 ray_origin; + CGAL::qglviewer::Vec dir; + if(viewer->camera()->type() == CGAL::qglviewer::Camera::PERSPECTIVE) + { + ray_origin = EPICK::Point_3(viewer->camera()->position().x - offset.x, + viewer->camera()->position().y - offset.y, + viewer->camera()->position().z - offset.z); + dir = point_under - viewer->camera()->position(); + } + else + { + dir = viewer->camera()->viewDirection(); + ray_origin = EPICK::Point_3(point_under.x - dir.x, + point_under.y - dir.y, + point_under.z - dir.z); + } const EPICK::Vector_3 ray_dir(dir.x, dir.y, dir.z); const EPICK::Ray_3 ray(ray_origin, ray_dir); typedef std::list Intersections; diff --git a/Polyhedron/demo/Polyhedron/TextRenderer.cpp b/Polyhedron/demo/Polyhedron/TextRenderer.cpp index 62de73bbbb9..2821f4bfc7a 100644 --- a/Polyhedron/demo/Polyhedron/TextRenderer.cpp +++ b/Polyhedron/demo/Polyhedron/TextRenderer.cpp @@ -23,15 +23,15 @@ void TextRenderer::draw(CGAL::Three::Viewer_interface *viewer) if(viewer->testDisplayId(src.x, src.y, src.z)) { if(item->is_3D()) - rect = QRect(camera->projectedCoordinatesOf(src).x-item->width()/2, - camera->projectedCoordinatesOf(src).y-item->height()/2, - item->width(), - item->height()); + rect = QRect(int(camera->projectedCoordinatesOf(src).x-item->width()/2), + int(camera->projectedCoordinatesOf(src).y-item->height()/2), + int(item->width()), + int(item->height())); else - rect = QRect(src.x-item->width()/2, - src.y-item->height()/2, - item->width(), - item->height()); + rect = QRect(int(src.x-item->width()/2), + int(src.y-item->height()/2), + int(item->width()), + int(item->height())); painter->setFont(item->font()); painter->setPen(QPen(item->color())); @@ -48,18 +48,18 @@ void TextRenderer::draw(CGAL::Three::Viewer_interface *viewer) { if(item->is_always_visible() || viewer->testDisplayId(src.x, src.y, src.z)) { - rect = QRect(camera->projectedCoordinatesOf(src).x-item->width()/2, - camera->projectedCoordinatesOf(src).y-item->height()/2, - item->width(), - item->height()); + rect = QRect(int(camera->projectedCoordinatesOf(src).x-item->width()/2), + int(camera->projectedCoordinatesOf(src).y-item->height()/2), + int(item->width()), + int(item->height())); } } else { - rect = QRect(src.x-item->width()/2, - src.y-item->height()/2, - item->width(), - item->height()); + rect = QRect(int(src.x-item->width()/2), + int(src.y-item->height()/2), + int(item->width()), + int(item->height())); } painter->setFont(item->font()); painter->setPen(QPen(item->color())); diff --git a/Polyhedron/demo/Polyhedron/Viewer.cpp b/Polyhedron/demo/Polyhedron/Viewer.cpp index acbf788d131..6513f174988 100644 --- a/Polyhedron/demo/Polyhedron/Viewer.cpp +++ b/Polyhedron/demo/Polyhedron/Viewer.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #if defined(_WIN32) #include @@ -38,6 +39,7 @@ public: QTimer messageTimer; QOpenGLFunctions_4_3_Compatibility* _recentFunctions; bool is_2d_selection_mode; + QOpenGLDebugLogger *logger; //! The buffers used to draw the axis system QOpenGLBuffer buffer; @@ -197,6 +199,13 @@ void Viewer::init() else { d->_recentFunctions = new QOpenGLFunctions_4_3_Compatibility(); + d->logger = new QOpenGLDebugLogger(this); + if(!d->logger->initialize()) + qDebug()<<"logger could not init."; + else{ + connect(d->logger, SIGNAL(messageLogged(QOpenGLDebugMessage)), this, SLOT(messageLogged(QOpenGLDebugMessage))); + d->logger->startLogging(); + } d->_recentFunctions->initializeOpenGLFunctions(); } glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDARBPROC)this->context()->getProcAddress("glDrawArraysInstancedARB"); @@ -489,8 +498,17 @@ void Viewer::postSelection(const QPoint& pixel) Q_EMIT selectedPoint(point.x, point.y, point.z); - const CGAL::qglviewer::Vec orig = camera()->position() - offset(); - const CGAL::qglviewer::Vec dir = point - orig; + CGAL::qglviewer::Vec dir; + CGAL::qglviewer::Vec orig; + if(d->projection_is_ortho) + { + dir = camera()->viewDirection(); + orig = point; + } + else{ + orig = camera()->position() - offset(); + dir = point - orig; + } Q_EMIT selectionRay(orig.x, orig.y, orig.z, dir.x, dir.y, dir.z); } @@ -706,7 +724,10 @@ void Viewer::drawVisualHints() //Prints the displayMessage QFont font = QFont(); QFontMetrics fm(font); - TextItem *message_text = new TextItem(10 + fm.width(d->message)/2, height()-20, 0, d->message, false, QFont(), Qt::gray ); + TextItem *message_text = new TextItem(float(10 + fm.width(d->message)/2), + float(height()-20), + 0, d->message, false, + QFont(), Qt::gray ); if (d->_displayMessage) { d->textRenderer->addText(message_text); @@ -848,7 +869,10 @@ void Viewer::paintGL() else { d->painter->beginNativePainting(); - glClearColor(backgroundColor().redF(), backgroundColor().greenF(), backgroundColor().blueF(), 1.0); + glClearColor(GLfloat(backgroundColor().redF()), + GLfloat(backgroundColor().greenF()), + GLfloat(backgroundColor().blueF()), + 1.f); glClearDepth(1.0f); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); //set the default frustum @@ -907,8 +931,8 @@ void Viewer_impl::showDistance(QPoint pixel) // fills the buffers std::vector v; v.resize(6); - v[0] = APoint.x; v[1] = APoint.y; v[2] = APoint.z; - v[3] = BPoint.x; v[4] = BPoint.y; v[5] = BPoint.z; + v[0] = float(APoint.x); v[1] = float(APoint.y); v[2] = float(APoint.z); + v[3] = float(BPoint.x); v[4] = float(BPoint.y); v[5] = float(BPoint.z); rendering_program_dist.bind(); vao.bind(); buffer.bind(); @@ -922,12 +946,21 @@ void Viewer_impl::showDistance(QPoint pixel) double dist = std::sqrt((BPoint.x-APoint.x)*(BPoint.x-APoint.x) + (BPoint.y-APoint.y)*(BPoint.y-APoint.y) + (BPoint.z-APoint.z)*(BPoint.z-APoint.z)); QFont font; font.setBold(true); - TextItem *ACoord = new TextItem(APoint.x, APoint.y, APoint.z,QString("A(%1,%2,%3)").arg(APoint.x-viewer->offset().x).arg(APoint.y-viewer->offset().y).arg(APoint.z-viewer->offset().z), true, font, Qt::red, true); + TextItem *ACoord = new TextItem(float(APoint.x), + float(APoint.y), + float(APoint.z), + QString("A(%1,%2,%3)").arg(APoint.x-viewer->offset().x).arg(APoint.y-viewer->offset().y).arg(APoint.z-viewer->offset().z), true, font, Qt::red, true); distance_text.append(ACoord); - TextItem *BCoord = new TextItem(BPoint.x, BPoint.y, BPoint.z,QString("B(%1,%2,%3)").arg(BPoint.x-viewer->offset().x).arg(BPoint.y-viewer->offset().y).arg(BPoint.z-viewer->offset().z), true, font, Qt::red, true); + TextItem *BCoord = new TextItem(float(BPoint.x), + float(BPoint.y), + float(BPoint.z), + QString("B(%1,%2,%3)").arg(BPoint.x-viewer->offset().x).arg(BPoint.y-viewer->offset().y).arg(BPoint.z-viewer->offset().z), true, font, Qt::red, true); distance_text.append(BCoord); CGAL::qglviewer::Vec centerPoint = 0.5*(BPoint+APoint); - TextItem *centerCoord = new TextItem(centerPoint.x, centerPoint.y, centerPoint.z,QString(" distance: %1").arg(dist), true, font, Qt::red, true); + TextItem *centerCoord = new TextItem(float(centerPoint.x), + float(centerPoint.y), + float(centerPoint.z), + QString(" distance: %1").arg(dist), true, font, Qt::red, true); distance_text.append(centerCoord); Q_FOREACH(TextItem* ti, distance_text) @@ -1025,3 +1058,67 @@ void Viewer::setStaticImage(QImage image) { d->static_image = image; } const QImage& Viewer:: staticImage() const { return d->static_image; } +void Viewer::messageLogged(QOpenGLDebugMessage msg) +{ + QString error; + + // Format based on severity + switch (msg.severity()) + { + case QOpenGLDebugMessage::NotificationSeverity: + return; + break; + case QOpenGLDebugMessage::HighSeverity: + error += "GL ERROR :"; + break; + case QOpenGLDebugMessage::MediumSeverity: + error += "GL WARNING :"; + break; + case QOpenGLDebugMessage::LowSeverity: + error += "GL NOTE :"; + break; + default: + break; + } + + error += " ("; + + // Format based on source +#define CASE(c) case QOpenGLDebugMessage::c: error += #c; break + switch (msg.source()) + { + CASE(APISource); + CASE(WindowSystemSource); + CASE(ShaderCompilerSource); + CASE(ThirdPartySource); + CASE(ApplicationSource); + CASE(OtherSource); + CASE(InvalidSource); + default: + break; + } +#undef CASE + + error += " : "; + + // Format based on type +#define CASE(c) case QOpenGLDebugMessage::c: error += #c; break + switch (msg.type()) + { + CASE(ErrorType); + CASE(DeprecatedBehaviorType); + CASE(UndefinedBehaviorType); + CASE(PortabilityType); + CASE(PerformanceType); + CASE(OtherType); + CASE(MarkerType); + CASE(GroupPushType); + CASE(GroupPopType); + default: + break; + } +#undef CASE + + error += ")"; + qDebug() << qPrintable(error) << "\n" << qPrintable(msg.message()) << "\n"; +} diff --git a/Polyhedron/demo/Polyhedron/Viewer.h b/Polyhedron/demo/Polyhedron/Viewer.h index b36ed537775..5d636d98775 100644 --- a/Polyhedron/demo/Polyhedron/Viewer.h +++ b/Polyhedron/demo/Polyhedron/Viewer.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -116,6 +117,7 @@ public Q_SLOTS: { setMouseBinding(::Qt::ShiftModifier, ::Qt::LeftButton, CGAL::qglviewer::NO_CLICK_ACTION); } + void messageLogged(QOpenGLDebugMessage); protected: void paintEvent(QPaintEvent *)Q_DECL_OVERRIDE; diff --git a/Polyhedron/demo/Polyhedron/create_sphere.h b/Polyhedron/demo/Polyhedron/create_sphere.h index 32af267e33b..5b3d846be32 100644 --- a/Polyhedron/demo/Polyhedron/create_sphere.h +++ b/Polyhedron/demo/Polyhedron/create_sphere.h @@ -13,15 +13,18 @@ void create_flat_sphere(FLOAT R, { //The more small they are, the more precise the Sphere will be. // Must be divisors of 180 and 360. - const int rings=prec/2; - const int sectors=prec; + const float rings=float(prec)/2; + const float sectors=float(prec); const float to_rad = static_cast(CGAL_PI / 180.0); float T, P; float x[4],y[4],z[4]; + using std::cos; + using std::sin; + //Top of the sphere - for(int t=0; t<360; t+=sectors) + for(float t=0; t<360.f; t+=sectors) { positions_spheres.push_back(0); @@ -61,8 +64,8 @@ void create_flat_sphere(FLOAT R, } //Body of the sphere - for (int p=rings; p<180-rings; p+=rings) - for(int t=0; t<360; t+=sectors) + for (float p=rings; p<180.f-rings; p+=rings) + for(float t=0; t<360.f; t+=sectors) { //A P = p*to_rad; @@ -140,7 +143,7 @@ void create_flat_sphere(FLOAT R, } //Bottom of the sphere - for(int t=0; t<360; t+=sectors) + for(float t=0; t<360.f; t+=sectors) { positions_spheres.push_back(0); positions_spheres.push_back(0); @@ -190,8 +193,8 @@ void create_flat_and_wire_sphere(FLOAT R, { //The smaller they are, the more precise the Sphere will be. // Must be a divisor of 360 and 180. - const int rings=prec/2; - const int sectors=prec; + const float rings=float(prec)/2; + const float sectors=float(prec); const float to_rad = static_cast(CGAL_PI / 180.0); create_flat_sphere(R, positions_spheres, normals_spheres); @@ -199,8 +202,11 @@ void create_flat_and_wire_sphere(FLOAT R, float T, P; float x[4],y[4],z[4]; + using std::cos; + using std::sin; + //Top of the sphere - for(int t=0; t<360; t+=sectors) + for(float t=0; t<360; t+=sectors) { positions_wire_spheres.push_back(0); positions_wire_spheres.push_back(0); @@ -240,8 +246,8 @@ void create_flat_and_wire_sphere(FLOAT R, } //Body of the sphere - for (int p=rings; p<180-rings; p+=rings) - for(int t=0; t<360; t+=sectors) + for (float p=rings; p<180.f-rings; p+=rings) + for(float t=0; t<360.f; t+=sectors) { //A P = p*to_rad; @@ -315,7 +321,7 @@ void create_flat_and_wire_sphere(FLOAT R, } //Bottom of the sphere - for(int t=0; t<360; t+=sectors) + for(float t=0; t<360.f; t+=sectors) { P = (180-rings)*to_rad; T = t*to_rad; diff --git a/Polyhedron/demo/Polyhedron/include/id_printing.h b/Polyhedron/demo/Polyhedron/include/id_printing.h index a28bb940214..f195eb97f53 100644 --- a/Polyhedron/demo/Polyhedron/include/id_printing.h +++ b/Polyhedron/demo/Polyhedron/include/id_printing.h @@ -120,10 +120,22 @@ bool find_primitive_id(const QPoint& point, const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); //find clicked facet - CGAL::qglviewer::Vec dir = point_under - viewer->camera()->position(); - const Point ray_origin(viewer->camera()->position().x - offset.x, - viewer->camera()->position().y - offset.y, - viewer->camera()->position().z - offset.z); + CGAL::qglviewer::Vec dir; + Point ray_origin; + if(viewer->camera()->type() == CGAL::qglviewer::Camera::PERSPECTIVE) + { + dir = point_under - viewer->camera()->position(); + ray_origin = Point(viewer->camera()->position().x - offset.x, + viewer->camera()->position().y - offset.y, + viewer->camera()->position().z - offset.z); + } + else + { + dir = viewer->camera()->viewDirection(); + ray_origin = Point(point_under.x - dir.x, + point_under.y - dir.y, + point_under.z - dir.z); + } const typename Traits::Vector_3 ray_dir(dir.x, dir.y, dir.z); const typename Traits::Ray_3 ray(ray_origin, ray_dir); @@ -215,9 +227,9 @@ void compute_displayed_ids(Mesh& mesh, } } QVector3D point( - get(ppmap, displayed_vertices[0]).x() + offset.x, - get(ppmap, displayed_vertices[0]).y() + offset.y, - get(ppmap, displayed_vertices[0]).z() + offset.z); + float(get(ppmap, displayed_vertices[0]).x() + offset.x), + float(get(ppmap, displayed_vertices[0]).y() + offset.y), + float(get(ppmap, displayed_vertices[0]).z() + offset.z)); //test if we want to erase or not BOOST_FOREACH(TextItem* text_item, *targeted_ids) @@ -342,7 +354,10 @@ void compute_displayed_ids(Mesh& mesh, Point pos=Point(get(ppmap, vh).x()+offset.x, get(ppmap, vh).y()+offset.y, get(ppmap, vh).z()+offset.z); - TextItem* text_item = new TextItem(pos.x(), pos.y(), pos.z(), QString("%1").arg(get(vidmap, vh)), true, font, Qt::red); + TextItem* text_item = new TextItem(float(pos.x()), + float(pos.y()), + float(pos.z()), + QString("%1").arg(get(vidmap, vh)), true, font, Qt::red); vitems->append(text_item); targeted_ids->push_back(text_item); } @@ -354,7 +369,10 @@ void compute_displayed_ids(Mesh& mesh, pos.y()+offset.y, pos.z()+offset.z); - TextItem* text_item = new TextItem(pos.x(), pos.y(), pos.z(), QString("%1").arg(get(hidmap, h)/2), true, font, Qt::green); + TextItem* text_item = new TextItem(float(pos.x()), + float(pos.y()), + float(pos.z()), + QString("%1").arg(get(hidmap, h)/2), true, font, Qt::green); eitems->append(text_item); } @@ -373,7 +391,10 @@ void compute_displayed_ids(Mesh& mesh, Point pos(x/total+offset.x, y/total+offset.y, z/total+offset.z); - TextItem* text_item = new TextItem(pos.x(), pos.y(), pos.z(), QString("%1").arg(get(fidmap,f)), true, font, Qt::blue); + TextItem* text_item = new TextItem(float(pos.x()), + float(pos.y()), + float(pos.z()), + QString("%1").arg(get(fidmap,f)), true, font, Qt::blue); fitems->append(text_item); } } @@ -398,9 +419,9 @@ bool printVertexIds(const Mesh& mesh, BOOST_FOREACH(typename boost::graph_traits::vertex_descriptor vh, vertices(mesh)) { const Point& p = get(ppmap, vh); - vitems->append(new TextItem((float)p.x() + offset.x, - (float)p.y() + offset.y, - (float)p.z() + offset.z, + vitems->append(new TextItem(float(p.x() + offset.x), + float(p.y() + offset.y), + float(p.z() + offset.z), QString("%1").arg(get(idmap, vh)), true, font, Qt::red)); } @@ -433,9 +454,9 @@ bool printEdgeIds(const Mesh& mesh, { const Point& p1 = get(ppmap, source(e, mesh)); const Point& p2 = get(ppmap, target(e, mesh)); - eitems->append(new TextItem((float)(p1.x() + p2.x()) / 2 + offset.x, - (float)(p1.y() + p2.y()) / 2 + offset.y, - (float)(p1.z() + p2.z()) / 2 + offset.z, + eitems->append(new TextItem(float((p1.x() + p2.x()) / 2 + offset.x), + float((p1.y() + p2.y()) / 2 + offset.y), + float((p1.z() + p2.z()) / 2 + offset.z), QString("%1").arg(get(idmap, halfedge(e, mesh)) / 2), true, font, Qt::green)); } //add the QList to the render's pool @@ -464,18 +485,18 @@ bool printFaceIds(const Mesh& mesh, BOOST_FOREACH(typename boost::graph_traits::face_descriptor fh, faces(mesh)) { double x(0), y(0), z(0); - int total(0); + float total(0); BOOST_FOREACH(typename boost::graph_traits::vertex_descriptor vh, vertices_around_face(halfedge(fh, mesh), mesh)) { x += get(ppmap, vh).x(); y += get(ppmap, vh).y(); z += get(ppmap, vh).z(); - ++total; + total += 1.f; } - fitems->append(new TextItem((float)x / total + offset.x, - (float)y / total + offset.y, - (float)z / total + offset.z, + fitems->append(new TextItem(float(x / total + offset.x), + float(y / total + offset.y), + float(z / total + offset.z), QString("%1").arg(get(idmap, fh)), true, font, Qt::blue)); } //add the QList to the render's pool diff --git a/Polyhedron/demo/Polyhedron/triangulate_primitive.h b/Polyhedron/demo/Polyhedron/triangulate_primitive.h index 55e737aad24..0d5e2c915eb 100644 --- a/Polyhedron/demo/Polyhedron/triangulate_primitive.h +++ b/Polyhedron/demo/Polyhedron/triangulate_primitive.h @@ -50,15 +50,16 @@ public: //Constructor FacetTriangulator(typename boost::graph_traits::face_descriptor fd, - const Vector& normal, + const Vector& normal, Mesh *poly, - const double item_diag) + const double item_diag, + Vector offset = Vector(0,0,0)) { std::vector idPoints; BOOST_FOREACH(halfedge_descriptor he_circ, halfedges_around_face( halfedge(fd, *poly), *poly)) { PointAndId idPoint; - idPoint.point = get(boost::vertex_point,*poly,source(he_circ, *poly)); + idPoint.point = get(boost::vertex_point,*poly,source(he_circ, *poly))+offset; idPoint.id = source(he_circ, *poly); idPoints.push_back(idPoint); @@ -70,13 +71,14 @@ public: const std::vector& more_points, const Vector& normal, Mesh *poly, - const double item_diag) + const double item_diag, + Vector offset = Vector(0,0,0)) { std::vector idPoints; BOOST_FOREACH(halfedge_descriptor he_circ, halfedges_around_face( halfedge(fd, *poly), *poly)) { PointAndId idPoint; - idPoint.point = get(boost::vertex_point,*poly,source(he_circ, *poly)); + idPoint.point = get(boost::vertex_point,*poly,source(he_circ, *poly))+offset; idPoint.id = source(he_circ, *poly); idPoints.push_back(idPoint); diff --git a/Polyhedron/doc/Polyhedron/CGAL/draw_polyhedron.h b/Polyhedron/doc/Polyhedron/CGAL/draw_polyhedron.h new file mode 100644 index 00000000000..8ac1c401b79 --- /dev/null +++ b/Polyhedron/doc/Polyhedron/CGAL/draw_polyhedron.h @@ -0,0 +1,15 @@ +namespace CGAL { + +/*! +\ingroup PkgDrawPolyhedron + +Open a new window and draw `apoly`, an instance of the `CGAL::Polyhedron_3` class. The function is blocking, that is the program continues as soon as the user closes the window. This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time. +\tparam POLY an instance of the `CGAL::Polyhedron_3` class. +\param apoly the polyhedron to draw. + +*/ +template +void draw(const POLY& apoly); + +} /* namespace CGAL */ + diff --git a/Polyhedron/doc/Polyhedron/PackageDescription.txt b/Polyhedron/doc/Polyhedron/PackageDescription.txt index aa9cf8ed001..05972f40034 100644 --- a/Polyhedron/doc/Polyhedron/PackageDescription.txt +++ b/Polyhedron/doc/Polyhedron/PackageDescription.txt @@ -4,6 +4,15 @@ /// \defgroup PkgPolyhedronIOFunc I/O Functions /// \ingroup PkgPolyhedron + +/*! Draw. + \code + #include + \endcode +*/ +/// \defgroup PkgDrawPolyhedron Draw a Polyhedron 3 +/// \ingroup PkgPolyhedron + /*! \addtogroup PkgPolyhedron \todo check generated documentation @@ -62,5 +71,9 @@ surface can be used without knowing the halfedge data structure. - \link PkgPolyhedronIOFunc `CGAL::operator>>()` \endlink - \link PkgPolyhedronIOFunc `write_off()` \endlink - \link PkgPolyhedronIOFunc `read_off()` \endlink + +### Draw a Polyhedron 3 ### +- `CGAL::draw` + */ diff --git a/Polyhedron/doc/Polyhedron/Polyhedron.txt b/Polyhedron/doc/Polyhedron/Polyhedron.txt index 7e39194363e..b960089fa00 100644 --- a/Polyhedron/doc/Polyhedron/Polyhedron.txt +++ b/Polyhedron/doc/Polyhedron/Polyhedron.txt @@ -275,6 +275,19 @@ are also marked in the program code. \cgalExample{Polyhedron/polyhedron_prog_cube.cpp} +\subsection PolyhedronDraw Draw a Polyhedron +\anchor ssecDrawPolyhedron + +A polyhedron can be visualized by calling the `CGAL::draw()` function as shown in the following example. This function opens a new window showing the given polyhedron. The function is blocking, that is the program continues as soon as the user closes the window. + +\cgalExample{Polyhedron/draw_polyhedron.cpp} + +This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time. + +\cgalFigureBegin{fig_draw_polyhedron,draw_polyhedron.png} +Result of the run of the draw_polyhedron program. A window shows the polyhedron and allows to navigate through the 3D scene. +\cgalFigureEnd + \section PolyhedronFile File I/O \anchor sectionPolyIO diff --git a/Polyhedron/doc/Polyhedron/examples.txt b/Polyhedron/doc/Polyhedron/examples.txt index 8fc56694e39..e106785f37d 100644 --- a/Polyhedron/doc/Polyhedron/examples.txt +++ b/Polyhedron/doc/Polyhedron/examples.txt @@ -10,4 +10,5 @@ \example Polyhedron/polyhedron_prog_subdiv.cpp \example Polyhedron/polyhedron_prog_tetra.cpp \example Polyhedron/polyhedron_prog_vector.cpp +\example Polyhedron/draw_polyhedron.cpp */ diff --git a/Polyhedron/doc/Polyhedron/fig/draw_polyhedron.png b/Polyhedron/doc/Polyhedron/fig/draw_polyhedron.png new file mode 100644 index 00000000000..0d711aef842 Binary files /dev/null and b/Polyhedron/doc/Polyhedron/fig/draw_polyhedron.png differ diff --git a/Polyhedron/examples/Polyhedron/CMakeLists.txt b/Polyhedron/examples/Polyhedron/CMakeLists.txt index f2b82769342..d191da8a473 100644 --- a/Polyhedron/examples/Polyhedron/CMakeLists.txt +++ b/Polyhedron/examples/Polyhedron/CMakeLists.txt @@ -4,9 +4,18 @@ project( Polyhedron_Examples ) -cmake_minimum_required(VERSION 2.8.10) +cmake_minimum_required(VERSION 3.1) -find_package(CGAL QUIET) +if(NOT POLICY CMP0070 AND POLICY CMP0053) + # Only set CMP0053 to OLD with CMake<3.10, otherwise there is a warning. + cmake_policy(SET CMP0053 OLD) +endif() + +find_package(CGAL COMPONENTS Qt5) + +if(CGAL_Qt5_FOUND) + add_definitions(-DCGAL_USE_BASIC_VIEWER -DQT_NO_KEYWORDS) +endif() if ( CGAL_FOUND ) @@ -16,12 +25,17 @@ if ( CGAL_FOUND ) include_directories (BEFORE "../../include") + # create a target per cppfile file(GLOB cppfiles RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) foreach(cppfile ${cppfiles}) create_single_source_cgal_program( "${cppfile}" ) endforeach() + if(CGAL_Qt5_FOUND ) + target_link_libraries(draw_polyhedron PUBLIC CGAL::CGAL_Qt5) + endif() + else() message(STATUS "This program requires the CGAL library, and will not be compiled.") diff --git a/Polyhedron/examples/Polyhedron/corner.off b/Polyhedron/examples/Polyhedron/data/corner.off similarity index 100% rename from Polyhedron/examples/Polyhedron/corner.off rename to Polyhedron/examples/Polyhedron/data/corner.off diff --git a/Polyhedron/examples/Polyhedron/corner_with_hole.off b/Polyhedron/examples/Polyhedron/data/corner_with_hole.off similarity index 100% rename from Polyhedron/examples/Polyhedron/corner_with_hole.off rename to Polyhedron/examples/Polyhedron/data/corner_with_hole.off diff --git a/Polyhedron/examples/Polyhedron/corner_with_sharp_edge.off b/Polyhedron/examples/Polyhedron/data/corner_with_sharp_edge.off similarity index 100% rename from Polyhedron/examples/Polyhedron/corner_with_sharp_edge.off rename to Polyhedron/examples/Polyhedron/data/corner_with_sharp_edge.off diff --git a/Polyhedron/examples/Polyhedron/cross.off b/Polyhedron/examples/Polyhedron/data/cross.off similarity index 100% rename from Polyhedron/examples/Polyhedron/cross.off rename to Polyhedron/examples/Polyhedron/data/cross.off diff --git a/Polyhedron/examples/Polyhedron/polyhedron_prog_subdiv.cin b/Polyhedron/examples/Polyhedron/data/cube.off similarity index 100% rename from Polyhedron/examples/Polyhedron/polyhedron_prog_subdiv.cin rename to Polyhedron/examples/Polyhedron/data/cube.off diff --git a/Polyhedron/examples/Polyhedron/polyhedron_prog_subdiv_with_boundary.cin b/Polyhedron/examples/Polyhedron/data/lshape_with_boundary.off similarity index 100% rename from Polyhedron/examples/Polyhedron/polyhedron_prog_subdiv_with_boundary.cin rename to Polyhedron/examples/Polyhedron/data/lshape_with_boundary.off diff --git a/Polyhedron/examples/Polyhedron/polyhedron_self_intersection.cin b/Polyhedron/examples/Polyhedron/data/tetra_intersected_by_triangle.off similarity index 100% rename from Polyhedron/examples/Polyhedron/polyhedron_self_intersection.cin rename to Polyhedron/examples/Polyhedron/data/tetra_intersected_by_triangle.off diff --git a/Polyhedron/examples/Polyhedron/draw_polyhedron.cpp b/Polyhedron/examples/Polyhedron/draw_polyhedron.cpp new file mode 100644 index 00000000000..a41fc79cc02 --- /dev/null +++ b/Polyhedron/examples/Polyhedron/draw_polyhedron.cpp @@ -0,0 +1,18 @@ +#include +#include +#include +#include +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; +typedef CGAL::Polyhedron_3 Polyhedron; + +int main(int argc, char* argv[]) +{ + Polyhedron P; + std::ifstream in1((argc>1)?argv[1]:"data/cross.off"); + in1 >> P; + CGAL::draw(P); + + return EXIT_SUCCESS; +} diff --git a/Polyhedron/examples/Polyhedron/polyhedron_prog_subdiv.cpp b/Polyhedron/examples/Polyhedron/polyhedron_prog_subdiv.cpp index bf1104c3c3b..b7d997bcfc1 100644 --- a/Polyhedron/examples/Polyhedron/polyhedron_prog_subdiv.cpp +++ b/Polyhedron/examples/Polyhedron/polyhedron_prog_subdiv.cpp @@ -4,6 +4,7 @@ #include #include #include +#include typedef CGAL::Simple_cartesian Kernel; typedef Kernel::Vector_3 Vector; @@ -90,9 +91,10 @@ void subdiv( Polyhedron& P) { CGAL_postcondition( P.is_valid()); } -int main() { +int main(int argc, char* argv[]) { Polyhedron P; - std::cin >> P; + std::ifstream in1((argc>1)?argv[1]:"data/cube.off"); + in1 >> P; P.normalize_border(); if ( P.size_of_border_edges() != 0) { std::cerr << "The input object has border edges. Cannot subdivide." diff --git a/Polyhedron/examples/Polyhedron/polyhedron_prog_subdiv_with_boundary.cpp b/Polyhedron/examples/Polyhedron/polyhedron_prog_subdiv_with_boundary.cpp index 744440fd123..296c910239a 100644 --- a/Polyhedron/examples/Polyhedron/polyhedron_prog_subdiv_with_boundary.cpp +++ b/Polyhedron/examples/Polyhedron/polyhedron_prog_subdiv_with_boundary.cpp @@ -6,6 +6,7 @@ #include #include #include +#include typedef CGAL::Simple_cartesian Kernel; typedef Kernel::Vector_3 Vector; @@ -172,21 +173,22 @@ void subdiv_border( Polyhedron& P) { using namespace std; int main( int argc, char* argv[]) { - if ( argc > 2 || (argc == 2 && ! isdigit( argv[1][0]))) { - cerr << "Usage: " << argv[0] << " []" << endl; - cerr << " subdivides times the polyhedron read from stdin." + if ( argc > 3 || (argc == 3 && ! isdigit( argv[2][0]))) { + cerr << "Usage: " << argv[0] << " [offfile] []]" << endl; + cerr << " subdivides times the polyhedron read from offfile." << endl; exit(1); } int n = 1; - if ( argc >= 2) - n = atoi( argv[1]); + std::ifstream in1((argc>1)?argv[1]:"data/lshape_with_boundary.off"); + if ( argc == 3) + n = atoi( argv[2]); if ( n < 1 || n > 12) { cerr << "Error: Choose reasonable value for in [1..12]" << endl; exit(1); } Polyhedron P; - cin >> P; + in1 >> P; for ( int i = 0; i != n; ++i) { cerr << "Subdivision " << i+1 << " ..." << endl; diff --git a/Polyhedron/examples/Polyhedron/polyhedron_self_intersection.cpp b/Polyhedron/examples/Polyhedron/polyhedron_self_intersection.cpp index a70ee0fd0e2..5bfc3f0ced6 100644 --- a/Polyhedron/examples/Polyhedron/polyhedron_self_intersection.cpp +++ b/Polyhedron/examples/Polyhedron/polyhedron_self_intersection.cpp @@ -7,6 +7,7 @@ #include #include #include +#include using std::cerr; using std::endl; @@ -138,12 +139,13 @@ void intersection( const Polyhedron& P) { Intersect_facets(), std::ptrdiff_t(2000)); } -int main() { +int main(int argc, char* argv[]) { CGAL::Timer user_time; cerr << "Loading OFF file ... " << endl; user_time.start(); Polyhedron P; - cin >> P; + std::ifstream in1((argc>1)?argv[1]:"data/tetra_intersected_by_triangle.off"); + in1 >> P; cerr << "Loading OFF file : " << user_time.time() << " seconds." << endl; if ( ! P.is_pure_triangle()) { cerr << "The input object is not triangulated. Cannot intersect." @@ -155,5 +157,6 @@ int main() { intersection( P); cerr << "Intersection : " << user_time.time() << " seconds." << endl; write_off(); + return 0; } diff --git a/Polyhedron/include/CGAL/draw_polyhedron.h b/Polyhedron/include/CGAL/draw_polyhedron.h new file mode 100644 index 00000000000..b8464757097 --- /dev/null +++ b/Polyhedron/include/CGAL/draw_polyhedron.h @@ -0,0 +1,240 @@ +// Copyright (c) 2018 ETH Zurich (Switzerland). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0+ +// +// Author(s) : Guillaume Damiand + +#ifndef CGAL_DRAW_POLYHEDRON_H +#define CGAL_DRAW_POLYHEDRON_H + +#include +#include + +#ifdef CGAL_USE_BASIC_VIEWER + +#include + +namespace CGAL +{ + +// Default color functor; user can change it to have its own face color +struct DefaultColorFunctorPolyhedron +{ + template + static CGAL::Color run(const Polyhedron&, + typename Polyhedron::Facet_const_handle fh) + { + if (fh==boost::graph_traits::null_face()) // use to get the mono color + return CGAL::Color(100, 125, 200); // R G B between 0-255 + + CGAL::Random random((unsigned int)(std::size_t)(&(*fh))); + return get_random_color(random); + } +}; + +// Viewer class for Polyhedron +template +class SimplePolyhedronViewerQt : public Basic_viewer_qt +{ + typedef Basic_viewer_qt Base; + typedef typename Polyhedron::Traits Kernel; + typedef typename Polyhedron::Halfedge_const_handle Halfedge_const_handle; + typedef typename Polyhedron::Vertex_const_handle Vertex_const_handle; + typedef typename Polyhedron::Facet_const_handle Facet_const_handle; + +public: + /// Construct the viewer. + /// @param apoly the polyhedron to view + /// @param title the title of the window + /// @param anofaces if true, do not draw faces (faces are not computed; this can be + /// usefull for very big object where this time could be long) + SimplePolyhedronViewerQt(QWidget* parent, + const Polyhedron& apoly, + const char* title="Basic Polyhedron Viewer", + bool anofaces=false, + const ColorFunctor& fcolor=ColorFunctor()) : + // First draw: no vertex; edges, faces; mono-color; inverse normal + Base(parent, title, false, true, true, true, false), + poly(apoly), + m_nofaces(anofaces), + m_fcolor(fcolor) + { + compute_elements(); + } + +protected: + void compute_face(Facet_const_handle fh) + { + CGAL::Color c=m_fcolor.run(poly, fh); + face_begin(c); + Halfedge_const_handle he=fh->facet_begin(); + do + { + add_point_in_face(he->vertex()->point(), + get_vertex_normal(he)); + he=he->next(); + } + while (he!=fh->facet_begin()); + face_end(); + } + + void compute_edge(Halfedge_const_handle he) + { + add_segment(he->vertex()->point(), + he->opposite()->vertex()->point()); + // We can use add_segment(p1, p2, c) with c a CGAL::Color to add a colored segment + } + + void compute_vertex(Vertex_const_handle vh) + { + add_point(vh->point()); + // We can use add_point(p, c) with c a CGAL::Color to add a colored point + } + + void compute_elements() + { + clear(); + + if (!m_nofaces) + { + for(typename Polyhedron::Facet_const_iterator f=poly.facets_begin(); + f!=poly.facets_end(); f++) + { + if (f!=boost::graph_traits::null_face()) + { compute_face(f); } + } + } + + for ( typename Polyhedron::Halfedge_const_iterator e=poly.halfedges_begin(); + e!=poly.halfedges_end(); ++e) + { + if (eopposite()) + { compute_edge(e); } + } + + for ( typename Polyhedron::Vertex_const_iterator v=poly.vertices_begin(); + v!=poly.vertices_end(); ++v) + { compute_vertex(v); } + } + + virtual void keyPressEvent(QKeyEvent *e) + { + // Test key pressed: + // const ::Qt::KeyboardModifiers modifiers = e->modifiers(); + // if ((e->key()==Qt::Key_PageUp) && (modifiers==Qt::NoButton)) { ... } + + // Call: * compute_elements() if the model changed, followed by + // * redraw() if some viewing parameters changed that implies some + // modifications of the buffers + // (eg. type of normal, color/mono) + // * update() just to update the drawing + + // Call the base method to process others/classicals key + Base::keyPressEvent(e); + } + +protected: + typename Kernel::Vector_3 get_face_normal(Halfedge_const_handle he) + { + typename Kernel::Vector_3 normal=CGAL::NULL_VECTOR; + Halfedge_const_handle end=he; + unsigned int nb=0; + do + { + internal::newell_single_step_3(he->vertex()->point(), + he->next()->vertex()->point(), + normal); + ++nb; + he=he->next(); + } + while (he!=end); + assert(nb>0); + return (typename Kernel::Construct_scaled_vector_3()(normal, 1.0/nb)); + } + + typename Kernel::Vector_3 get_vertex_normal(Halfedge_const_handle he) + { + typename Kernel::Vector_3 normal=CGAL::NULL_VECTOR; + Halfedge_const_handle end=he; + do + { + if (!he->is_border()) + { + typename Kernel::Vector_3 n=get_face_normal(he); + normal=typename Kernel::Construct_sum_of_vectors_3()(normal, n); + } + he=he->next()->opposite(); + } + while (he!=end); + + if (!typename Kernel::Equal_3()(normal, CGAL::NULL_VECTOR)) + { normal=(typename Kernel::Construct_scaled_vector_3() + (normal, 1.0/CGAL::sqrt(normal.squared_length()))); } + + return normal; + } + +protected: + const Polyhedron& poly; + bool m_nofaces; + const ColorFunctor& m_fcolor; +}; + +template +void draw(const Polyhedron& apoly, + const char* title, + bool nofill, + const ColorFunctor& fcolor) +{ +#if defined(CGAL_TEST_SUITE) + bool cgal_test_suite=true; +#else + bool cgal_test_suite=false; +#endif + + if (!cgal_test_suite) + { + int argc=1; + const char* argv[2]={"polyhedron_viewer","\0"}; + QApplication app(argc,const_cast(argv)); + SimplePolyhedronViewerQt + mainwindow(app.activeWindow(), apoly, title, nofill, fcolor); + mainwindow.show(); + app.exec(); + } +} + +template +void draw(const Polyhedron& apoly, const char* title, bool nofill) +{ + DefaultColorFunctorPolyhedron c; + draw(apoly, title, nofill, c); +} + +template +void draw(const Polyhedron& apoly, const char* title) +{ draw(apoly, title, false); } + +template +void draw(const Polyhedron& apoly) +{ draw(apoly, "Basic Polyhedron Viewer"); } + +} // End namespace CGAL + +#endif // CGAL_USE_BASIC_VIEWER + +#endif // CGAL_DRAW_POLYHEDRON_H diff --git a/Polyhedron/package_info/Polyhedron/dependencies b/Polyhedron/package_info/Polyhedron/dependencies index 47699a9637a..70c007e409d 100644 --- a/Polyhedron/package_info/Polyhedron/dependencies +++ b/Polyhedron/package_info/Polyhedron/dependencies @@ -2,6 +2,7 @@ Algebraic_foundations BGL Circulator Distance_2 +GraphicsView HalfedgeDS Hash_map Installation diff --git a/Property_map/include/CGAL/property_map.h b/Property_map/include/CGAL/property_map.h index a4f5c52d3fd..d025f3962e2 100644 --- a/Property_map/include/CGAL/property_map.h +++ b/Property_map/include/CGAL/property_map.h @@ -36,6 +36,9 @@ #include // defines std::pair +#include +#include + namespace CGAL { /// \cond SKIP_DOXYGEN @@ -469,7 +472,7 @@ struct Constant_property_map }; /// \ingroup PkgProperty_map -/// Read-write Property map turning a set (such a `std::set`, +/// Read-write property map turning a set (such a `std::set`, /// `boost::unordered_set`, `std::unordered_set`) into a property map /// associating a Boolean to the value type of the set. The function `get` will /// return `true` if the key is inside the set and `false` otherwise. The `put` @@ -515,6 +518,50 @@ make_boolean_property_map(Set& set_) return Boolean_property_map(set_); } +/// \ingroup PkgProperty_map +/// Read-write property map doing on-the-fly conversions between two default constructible \cgal %Cartesian kernels. +/// Its value type is `GeomObject` and its key type is the same as `Vpm`. +/// `GeomObject` must be a geometric object from a \cgal kernel. +/// `Vpm` is a model `of ReadWritePropertyMap` and its value type must be +/// a geometric object of the same type as `GeomObject` but possibly from +/// another kernel. +/// Conversions between the two geometric objects are done using `Cartesian_converter`. +/// \cgalModels `ReadWritePropertyMap` +template +struct Cartesian_converter_property_map +{ + typedef typename boost::property_traits::key_type key_type; + typedef GeomObject value_type; + typedef value_type reference; + typedef boost::read_write_property_map_tag category; + Vpm vpm; + + typedef typename Kernel_traits::type K2; + typedef typename Kernel_traits::value_type>::type K1; + + Cartesian_converter_property_map(Vpm vpm):vpm(vpm){} + + friend value_type get(const Cartesian_converter_property_map& pm, const key_type& k) + { + return + CGAL::Cartesian_converter()(get(pm.vpm, k)); + } + + friend void put(Cartesian_converter_property_map& pm, const key_type& k, const value_type& v) + { + put(pm.vpm, k, CGAL::Cartesian_converter()(v)); + } +}; + +/// \ingroup PkgProperty_map +/// returns `Cartesian_converter_property_map(vpm)` +template +Cartesian_converter_property_map +make_cartesian_converter_property_map(Vpm vpm) +{ + return Cartesian_converter_property_map(vpm); +} + } // namespace CGAL diff --git a/Property_map/test/Property_map/CMakeLists.txt b/Property_map/test/Property_map/CMakeLists.txt index 768e08015fb..cf2d22c7469 100644 --- a/Property_map/test/Property_map/CMakeLists.txt +++ b/Property_map/test/Property_map/CMakeLists.txt @@ -55,6 +55,8 @@ create_single_source_cgal_program( "dynamic_property_map.cpp" ) create_single_source_cgal_program( "dynamic_properties_test.cpp" ) +create_single_source_cgal_program( "kernel_converter_properties_test.cpp" ) + if(OpenMesh_FOUND) target_link_libraries( dynamic_properties_test PRIVATE ${OPENMESH_LIBRARIES} ) endif() diff --git a/Property_map/test/Property_map/kernel_converter_properties_test.cpp b/Property_map/test/Property_map/kernel_converter_properties_test.cpp new file mode 100644 index 00000000000..586cdd49383 --- /dev/null +++ b/Property_map/test/Property_map/kernel_converter_properties_test.cpp @@ -0,0 +1,37 @@ + +#include +#include +#include +#include +#include +#include + +typedef CGAL::Simple_cartesian K1; +typedef CGAL::Simple_cartesian > K2; +typedef K1::Point_3 Point_3; + +template +void +test() +{ + Mesh m; + CGAL::make_triangle(Point_3(2,0,0),Point_3(1,0,0),Point_3(1,1,0),m); + + typedef typename boost::property_map::type VPMap; + VPMap vmap = get(CGAL::vertex_point, m); + + CGAL::Cartesian_converter_property_map kcmap =CGAL::make_cartesian_converter_property_map(vmap); + CGAL_assertion(get(kcmap, *vertices(m).begin()) == CGAL::Point_3(2,0,0)); + put(kcmap, *vertices(m).begin(), CGAL::Point_3(0,2,3)); + CGAL_assertion(get(kcmap, *vertices(m).begin()) == CGAL::Point_3(0,2,3)); + +} + +int main() +{ + + typedef CGAL::Surface_mesh SM; + test(); + return 0; +} + diff --git a/STL_Extension/include/CGAL/assertions_behaviour.h b/STL_Extension/include/CGAL/assertions_behaviour.h index cd082c3892f..be0941fba1d 100644 --- a/STL_Extension/include/CGAL/assertions_behaviour.h +++ b/STL_Extension/include/CGAL/assertions_behaviour.h @@ -28,6 +28,12 @@ #ifndef CGAL_ASSERTIONS_BEHAVIOUR_H #define CGAL_ASSERTIONS_BEHAVIOUR_H +// workaround against the definition of EXIT in +#ifdef EXIT +# undef EXIT +#endif + + namespace CGAL { enum Failure_behaviour { ABORT, EXIT, EXIT_WITH_SUCCESS, CONTINUE, diff --git a/STL_Extension/include/CGAL/exceptions.h b/STL_Extension/include/CGAL/exceptions.h index 2dcc47a63e1..b07c0c50267 100644 --- a/STL_Extension/include/CGAL/exceptions.h +++ b/STL_Extension/include/CGAL/exceptions.h @@ -26,7 +26,19 @@ #include #include #include + +// Address the warning C4003: not enough actual parameters for macro 'BOOST_PP_SEQ_DETAIL_IS_NOT_EMPTY' +// lexical_cast.hpp includes files from boost/preprocessor +// This concerns boost 1_67_0 +#if defined(BOOST_MSVC) +# pragma warning(push) +# pragma warning(disable: 4003) +#endif #include +#if defined(BOOST_MSVC) +# pragma warning(pop) +#endif + namespace CGAL { diff --git a/STL_Extension/include/CGAL/result_of.h b/STL_Extension/include/CGAL/result_of.h index 59c8f02e7f4..5d9382d5c4d 100644 --- a/STL_Extension/include/CGAL/result_of.h +++ b/STL_Extension/include/CGAL/result_of.h @@ -27,9 +27,21 @@ #ifndef CGAL_RESULT_OF_H #define CGAL_RESULT_OF_H +#include #include +// Address the warning C4003: not enough actual parameters for macro 'BOOST_PP_SEQ_DETAIL_IS_NOT_EMPTY' +// result_of.hpp includes files from boost/preprocessor +// This concerns boost 1_65_1 +#if defined(BOOST_MSVC) +# pragma warning(push) +# pragma warning(disable: 4003) +#endif #include +#if defined(BOOST_MSVC) +# pragma warning(pop) +#endif + #include namespace CGAL{ diff --git a/Scripts/developer_scripts/cgal_check_dependencies.sh b/Scripts/developer_scripts/cgal_check_dependencies.sh index f05b8e064ce..65b989a8ca2 100644 --- a/Scripts/developer_scripts/cgal_check_dependencies.sh +++ b/Scripts/developer_scripts/cgal_check_dependencies.sh @@ -10,6 +10,8 @@ do echo "0 otherwise." exit 0 ;; + --check_headers) DO_CHECK_HEADERS="True" + ;; --*) echo "bad option $1" ;; *) DOX_PATH="$1" @@ -29,6 +31,9 @@ do done cmake -DCGAL_HEADER_ONLY=FALSE -DCGAL_ENABLE_CHECK_HEADERS=TRUE -DDOXYGEN_EXECUTABLE="$DOX_PATH" -DCGAL_COPY_DEPENDENCIES=TRUE -DCMAKE_CXX_FLAGS="-std=c++11" .. +if [ -n "$DO_CHECK_HEADERS" ]; then + make -j$(nproc --all) -k check_headers +fi make -j$(nproc --all) -k packages_dependencies echo " Checks finished" for pkg_path in $CGAL_ROOT/* @@ -52,7 +57,7 @@ echo " Checks finished" cd $CGAL_ROOT rm -r dep_check_build if [ -n "$TOTAL_RES" ]; then - echo "$TOTAL_RES" + printf "$TOTAL_RES" echo " You can run cmake with options CGAL_ENABLE_CHECK_HEADERS and CGAL_COPY_DEPENDENCIES ON, make the target packages_dependencies and commit the new dependencies files," echo " or simply manually edit the problematic files." exit 1 diff --git a/Spatial_searching/doc/Spatial_searching/CGAL/Fuzzy_iso_box.h b/Spatial_searching/doc/Spatial_searching/CGAL/Fuzzy_iso_box.h index 2366cfa35ba..134640fea7f 100644 --- a/Spatial_searching/doc/Spatial_searching/CGAL/Fuzzy_iso_box.h +++ b/Spatial_searching/doc/Spatial_searching/CGAL/Fuzzy_iso_box.h @@ -3,23 +3,20 @@ namespace CGAL { /*! \ingroup RangeQueryItemClasses -The class `Fuzzy_iso_box` implements fuzzy `d`-dimensional iso boxes. A fuzzy iso -box with fuzziness value \f$ \epsilon\f$ has as inner and outer approximations +The class `Fuzzy_iso_box` implements fuzzy `d`-dimensional (closed) iso boxes. +A fuzzy iso box with fuzziness value \f$ \epsilon\f$ has as inner and outer approximations a box respectively eroded and dilated by a `d`-dim square with side length \f$ \epsilon\f$. - -\attention Points in the interior of the inner approximation are always reported and points -that are not in the closure of the outer approximation are never reported. Other -points may or may not be reported. Subsequently, points on the boundary of the -inner and outer approximations may or may not be reported. Specifically when \f$ \epsilon = 0\f$, -points on the boundary of the box may or may not be reported. +Points are returned depending on their location respective to the approximations, +as follows: +- points in the inner approximation (boundary included) are always returned. +- points in the outer approximation (boundary included) and not in the previous + category may or may not be returned. +- points that do not fit in the two previous categories are never returned. \tparam Traits must be a model of the concept `SearchTraits`, for example `CGAL::Search_traits_2 >`. \cgalModels `FuzzyQueryItem` - -\sa `FuzzyQueryItem` - */ template< typename Traits > class Fuzzy_iso_box { diff --git a/Spatial_searching/doc/Spatial_searching/CGAL/Fuzzy_sphere.h b/Spatial_searching/doc/Spatial_searching/CGAL/Fuzzy_sphere.h index db3aec07db3..e5340061349 100644 --- a/Spatial_searching/doc/Spatial_searching/CGAL/Fuzzy_sphere.h +++ b/Spatial_searching/doc/Spatial_searching/CGAL/Fuzzy_sphere.h @@ -7,23 +7,20 @@ The class `Fuzzy_sphere` implements fuzzy `d`-dimensional spheres. A fuzzy sphere with radius \f$ r\f$ and fuzziness value \f$ \epsilon\f$ has as inner approximation a sphere with radius \f$ r-\epsilon\f$ and as outer approximation a sphere with radius \f$ r+\epsilon\f$. +Points are returned depending on their location respective to the approximations, +as follows: +- points in the inner approximation (boundary included) are always returned. +- points in the outer approximation (boundary included) and not in the previous + category may or may not be returned. +- points that do not fit in the two previous categories are never returned. -\attention The fuzziness of a `Fuzzy_sphere` is specified by a parameter \f$ \epsilon\f$ -denoting a maximal allowed distance to the boundary of a sphere. -If the distance to the boundary is greater than \f$ \epsilon\f$, points inside the -object are always reported and points outside the sphere are never reported. -Points whose distance to the boundary is less than or equal to \f$ \epsilon\f$ -may or may not be reported. Subsequently, points on the inner and outer spheres -may or may not be reported. Specifically when \f$ \epsilon = 0\f$, points -on the sphere of radius \f$ r\f$ may or may not be reported. +Note that if the fuzziness value is strictly greater than the radius, there is no +inner approximation. \tparam Traits must be a model of the concept `SearchTraits`, for example `CGAL::Cartesian_d`. \cgalModels `FuzzyQueryItem` - -\sa `FuzzyQueryItem` - */ template< typename Traits > class Fuzzy_sphere { diff --git a/Spatial_searching/doc/Spatial_searching/Spatial_searching.txt b/Spatial_searching/doc/Spatial_searching/Spatial_searching.txt index 40ca743f96f..24a45166d30 100644 --- a/Spatial_searching/doc/Spatial_searching/Spatial_searching.txt +++ b/Spatial_searching/doc/Spatial_searching/Spatial_searching.txt @@ -151,16 +151,21 @@ GeneralDistance, Splitter, SpatialTree>` Exact range searching and approximate range searching are supported using exact or fuzzy `d`-dimensional objects enclosing a region. The fuzziness of the query object is specified by a parameter -\f$ \epsilon\f$ used to define inner and outer approximations of the query object. -Points in the interior of the inner approximation are always reported and points -that are not in the closure of the outer approximation are never reported. Other -points may or may not be reported. For exact range searching, -the fuzziness parameter \f$ \epsilon\f$ is set to zero. +\f$ \epsilon\f$ used to define inner and outer +approximations of the object. For example, in the class `Fuzzy_sphere`, +the \f$ \epsilon\f$-inner and outer approximations of a sphere of radius \f$ r\f$ +are defined as the spheres of radius \f$ r-\epsilon\f$ and \f$ r+\epsilon\f$, respectively. +When using fuzzy items, queries are reported as follows: +- Points that are within the inner approximation are always reported. +- Points that are within the outer approximation but not within the inner approximation +might or might not be reported. +- Points thare not within the outer approximation are never reported. + +For exact range searching the fuzziness parameter \f$ \epsilon\f$ is set to zero. The class `Kd_tree` implements range searching in the method `search`, which is a template method with an output iterator and a model of the -concept `FuzzyQueryItem` as `Fuzzy_iso_box` -or `Fuzzy_sphere`. +concept `FuzzyQueryItem` such as `Fuzzy_iso_box` or `Fuzzy_sphere`. For range searching of large data sets, the user may set the parameter `bucket_size` used in building the `kd` tree to a large value (e.g. 100), because in general the query time will be less than using the default value. diff --git a/Spatial_searching/examples/Spatial_searching/iso_rectangle_2_query.cpp b/Spatial_searching/examples/Spatial_searching/iso_rectangle_2_query.cpp index e4f30d6acd0..4ef739e9819 100644 --- a/Spatial_searching/examples/Spatial_searching/iso_rectangle_2_query.cpp +++ b/Spatial_searching/examples/Spatial_searching/iso_rectangle_2_query.cpp @@ -47,8 +47,7 @@ main() { // using value 0.1 for fuzziness paramater Fuzzy_iso_box approximate_range(p, q, 0.1); tree.search(std::back_inserter( result ), approximate_range); - std::cout << "The points in the fuzzy box [[0.1, 0.3], [0.6, 0.9]]^2 are: " - << std::endl; + std::cout << "The points in the fuzzy box [[0.1, 0.3], [0.6, 0.9]]^2 are: " << std::endl; std::copy (result.begin(), result.end(), std::ostream_iterator(std::cout,"\n") ); std::cout << std::endl; return 0; diff --git a/Spatial_searching/include/CGAL/Fuzzy_iso_box.h b/Spatial_searching/include/CGAL/Fuzzy_iso_box.h index b9f27e0992f..5fdb08c8fa3 100644 --- a/Spatial_searching/include/CGAL/Fuzzy_iso_box.h +++ b/Spatial_searching/include/CGAL/Fuzzy_iso_box.h @@ -97,59 +97,61 @@ namespace CGAL { public: - // default constructor - Fuzzy_iso_box(const SearchTraits& traits_=SearchTraits()):traits(traits_) {} + // default constructor + Fuzzy_iso_box(const SearchTraits& traits_=SearchTraits()):traits(traits_) {} - // constructor - Fuzzy_iso_box(const Point_d& p, const Point_d& q, FT epsilon=FT(0),const SearchTraits& traits_=SearchTraits()) - : traits(traits_), eps(epsilon) - { - construct(p,q); - } + // constructor + Fuzzy_iso_box(const Point_d& p, const Point_d& q, FT epsilon=FT(0),const SearchTraits& traits_=SearchTraits()) + : traits(traits_), eps(epsilon) + { + CGAL_precondition(epsilon >= 0); + construct(p,q); + } - //additional constructor if SearchTraits = Search_traits_adapter - template - Fuzzy_iso_box(const Point& p,const Point&q,FT epsilon=FT(0),const SearchTraits& traits_=SearchTraits(), - typename boost::enable_if::type>::type* = 0) - : traits(traits_), eps(epsilon) - { - construct(p,q); - } + //additional constructor if SearchTraits = Search_traits_adapter + template + Fuzzy_iso_box(const Point& p,const Point&q,FT epsilon=FT(0),const SearchTraits& traits_=SearchTraits(), + typename boost::enable_if::type>::type* = 0) + : traits(traits_), eps(epsilon) + { + CGAL_precondition(epsilon >= 0); + construct(p,q); + } - bool contains(const Point_d& p) const { - Construct_cartesian_const_iterator_d construct_it=traits.construct_cartesian_const_iterator_d_object(); - Cartesian_const_iterator_d pit = construct_it(p); - Cartesian_const_iterator_d minit= min_begin, maxit = max_begin; - for (unsigned int i = 0; i < dim; ++i, ++pit, ++minit, ++maxit) { - if ( ((*pit) < (*minit)) || ((*pit) >= (*maxit)) ) return false; - } - return true; - } + bool contains(const Point_d& p) const { + Construct_cartesian_const_iterator_d construct_it=traits.construct_cartesian_const_iterator_d_object(); + Cartesian_const_iterator_d pit = construct_it(p); + Cartesian_const_iterator_d minit= min_begin, maxit = max_begin; + for (unsigned int i = 0; i < dim; ++i, ++pit, ++minit, ++maxit) { + if ( ((*pit) < (*minit)) || ((*pit) > (*maxit)) ) + return false; + } + return true; + } - bool inner_range_intersects(const Kd_tree_rectangle& rectangle) const { - Cartesian_const_iterator_d minit= min_begin, maxit = max_begin; - for (unsigned int i = 0; i < dim; ++i, ++minit, ++maxit) { - if ( ((*maxit)-eps < rectangle.min_coord(i)) - || ((*minit)+eps >= rectangle.max_coord(i)) ) return false; - } - return true; - } + bool inner_range_intersects(const Kd_tree_rectangle& rectangle) const { + // test whether the box eroded by 'eps' intersects 'rectangle' + Cartesian_const_iterator_d minit= min_begin, maxit = max_begin; + for (unsigned int i = 0; i < dim; ++i, ++minit, ++maxit) { + if ( ((*maxit)-eps < rectangle.min_coord(i)) + || ((*minit)+eps > rectangle.max_coord(i)) ) + return false; + } + return true; + } - bool outer_range_contains(const Kd_tree_rectangle& rectangle) const { - Cartesian_const_iterator_d minit= min_begin, maxit = max_begin; - for (unsigned int i = 0; i < dim; ++i, ++minit, ++maxit) { - if ( ((*maxit)+eps < rectangle.max_coord(i) ) - || ((*minit)-eps >= rectangle.min_coord(i)) ) return false; - } - return true; - } - - - - - - }; // class Fuzzy_iso_box + bool outer_range_contains(const Kd_tree_rectangle& rectangle) const { + // test whether the box dilated by 'eps' contains 'rectangle' + Cartesian_const_iterator_d minit= min_begin, maxit = max_begin; + for (unsigned int i = 0; i < dim; ++i, ++minit, ++maxit) { + if ( ((*maxit)+eps < rectangle.max_coord(i) ) + || ((*minit)-eps > rectangle.min_coord(i)) ) + return false; + } + return true; + } +}; // class Fuzzy_iso_box } // namespace CGAL #endif // FUZZY_ISO_BOX_H diff --git a/Spatial_searching/include/CGAL/Fuzzy_sphere.h b/Spatial_searching/include/CGAL/Fuzzy_sphere.h index a89af1c9b0d..5953ac767a6 100644 --- a/Spatial_searching/include/CGAL/Fuzzy_sphere.h +++ b/Spatial_searching/include/CGAL/Fuzzy_sphere.h @@ -25,6 +25,7 @@ #include +#include #include #include @@ -33,134 +34,131 @@ namespace CGAL { - namespace internal{ - - template - class Fuzzy_sphere_impl{ - SearchTraits traits; - public: +namespace internal{ - typedef typename SearchTraits::FT FT; - typedef typename SearchTraits::Dimension Dimension; - private: +template +class Fuzzy_sphere_impl +{ +public: + typedef typename SearchTraits::FT FT; + typedef typename SearchTraits::Dimension Dimension; - Point_d c; - FT r; - FT eps; +private: + SearchTraits traits; - public: + Point_d c; + FT sq_radius; + FT sq_inner_radius; + FT sq_outer_radius; +public: + // default constructor + Fuzzy_sphere_impl(const SearchTraits& traits_=SearchTraits()):traits(traits_) {} - // default constructor - Fuzzy_sphere_impl(const SearchTraits& traits_=SearchTraits()):traits(traits_) {} - - - // constructor - Fuzzy_sphere_impl(const Point_d& center, FT radius, FT epsilon=FT(0),const SearchTraits& traits_=SearchTraits()) : - traits(traits_),c(center), r(radius), eps(epsilon) - { // avoid problems if eps > r - if (eps>r) eps=r; - } - - bool contains(const typename SearchTraits::Point_d& p) const { - // test whether the distance between c and p is less than the radius - FT squared_radius = r*r; - FT distance=FT(0); - typename SearchTraits::Construct_cartesian_const_iterator_d construct_it= - traits.construct_cartesian_const_iterator_d_object(); - typename SearchTraits::Cartesian_const_iterator_d cit = construct_it(c), - pit = construct_it(p), - end = construct_it(c, 0); - for (; cit != end - && (distance < squared_radius); ++cit, ++pit) { - distance += - ((*cit)-(*pit))*((*cit)-(*pit)); - } - - return (distance < squared_radius); - } - - bool inner_range_intersects(const Kd_tree_rectangle& rectangle) const { - // test whether the interior of a sphere - // with radius (r-eps) intersects 'rectangle', i.e. - // if the minimal distance of c to 'rectangle' is less than r-eps - FT distance = FT(0); - FT squared_radius = (r-eps)*(r-eps); - typename SearchTraits::Construct_cartesian_const_iterator_d construct_it= - traits.construct_cartesian_const_iterator_d_object(); - typename SearchTraits::Cartesian_const_iterator_d cit = construct_it(c), - end = construct_it(c, 0); - for (int i = 0; cit != end && (distance < squared_radius); ++cit, ++i) { - if ((*cit) < rectangle.min_coord(i)) - distance += - (rectangle.min_coord(i)-(*cit))*(rectangle.min_coord(i)-(*cit)); - if ((*cit) > rectangle.max_coord(i)) - distance += - ((*cit)-rectangle.max_coord(i))*((*cit)-rectangle.max_coord(i)); - } - - return (distance < squared_radius); - } - - - bool outer_range_contains(const Kd_tree_rectangle& rectangle) const { - // test whether the interior of a sphere - // with radius (r+eps) is contained by 'rectangle', i.e. - // if the maximal distance of c to the boundary of 'rectangle' - // is less than r+eps - FT distance=FT(0); - FT squared_radius = (r+eps)*(r+eps); - typename SearchTraits::Construct_cartesian_const_iterator_d construct_it= - traits.construct_cartesian_const_iterator_d_object(); - typename SearchTraits::Cartesian_const_iterator_d cit = construct_it(c), - end = construct_it(c, 0); - for (int i = 0; cit != end && (distance < squared_radius) ; ++cit,++i) { - if ((*cit) <= (rectangle.min_coord(i)+rectangle.max_coord(i))/FT(2)) - distance += - (rectangle.max_coord(i)-(*cit))*(rectangle.max_coord(i)-(*cit)); - else - distance += ((*cit)-rectangle.min_coord(i))*((*cit)-rectangle.min_coord(i)); - } - - return (distance < squared_radius); - } - }; // class Fuzzy_sphere_impl + // constructor + Fuzzy_sphere_impl(const Point_d& center, FT r, FT eps=FT(0), + const SearchTraits& traits_ = SearchTraits()) + : traits(traits_), c(center), sq_radius(r*r) + { + CGAL_precondition(r >= 0); + CGAL_precondition(eps >= 0); + sq_inner_radius = (eps > r) ? FT(-1) : (r - eps) * (r - eps); + sq_outer_radius = (r + eps) * (r + eps); } - - template - class Fuzzy_sphere: + + bool contains(const typename SearchTraits::Point_d& p) const { + // test whether the distance between c and p is less than the radius + FT distance=FT(0); + typename SearchTraits::Construct_cartesian_const_iterator_d construct_it= + traits.construct_cartesian_const_iterator_d_object(); + typename SearchTraits::Cartesian_const_iterator_d cit = construct_it(c), + pit = construct_it(p), end = construct_it(c, 0); + for (; cit != end && (distance <= sq_radius); ++cit, ++pit) { + distance += CGAL::square((*cit)-(*pit)); + } + + return (distance <= sq_radius); + } + + bool inner_range_intersects(const Kd_tree_rectangle& rectangle) const { + // test whether the sphere with radius (r-eps) intersects 'rectangle', i.e. + // if the minimal distance of c to 'rectangle' is less than r-eps + FT distance = FT(0); + typename SearchTraits::Construct_cartesian_const_iterator_d construct_it= + traits.construct_cartesian_const_iterator_d_object(); + typename SearchTraits::Cartesian_const_iterator_d cit = construct_it(c), + end = construct_it(c, 0); + for (int i = 0; cit != end && (distance <= sq_inner_radius); ++cit, ++i) { + if ((*cit) < rectangle.min_coord(i)) + distance += CGAL::square(rectangle.min_coord(i)-(*cit)); + else if ((*cit) > rectangle.max_coord(i)) + distance += CGAL::square((*cit)-rectangle.max_coord(i)); + } + + return (distance <= sq_inner_radius); + } + + + bool outer_range_contains(const Kd_tree_rectangle& rectangle) const { + // test whether the sphere with radius (r+eps) contains 'rectangle', + // i.e. if the maximal distance of c to the boundary of 'rectangle' + // is less than r+eps + FT distance=FT(0); + typename SearchTraits::Construct_cartesian_const_iterator_d construct_it= + traits.construct_cartesian_const_iterator_d_object(); + typename SearchTraits::Cartesian_const_iterator_d cit = construct_it(c), + end = construct_it(c, 0); + for (int i = 0; cit != end && (distance <= sq_outer_radius) ; ++cit,++i) { + if ((*cit) <= (rectangle.min_coord(i)+rectangle.max_coord(i))/FT(2)) + distance += CGAL::square(rectangle.max_coord(i)-(*cit)); + else + distance += CGAL::square((*cit)-rectangle.min_coord(i)); + } + + return (distance <= sq_outer_radius); + } +}; // class Fuzzy_sphere_impl + +} + +template +class Fuzzy_sphere: public internal::Fuzzy_sphere_impl - { - typedef internal::Fuzzy_sphere_impl Base; - typedef typename Base::FT FT; - public: - // constructors - Fuzzy_sphere(const SearchTraits& traits_=SearchTraits()):Base(traits_){}; - Fuzzy_sphere(const typename SearchTraits::Point_d& center, FT radius, FT epsilon=FT(0),const SearchTraits& traits_=SearchTraits()) : - Base(center,radius,epsilon,traits_) {} - }; - - //specialization for Search_traits_adapter - template - class Fuzzy_sphere< Search_traits_adapter > : - public internal::Fuzzy_sphere_impl,typename Base_traits::Point_d> - { - typedef Search_traits_adapter SearchTraits; - typedef internal::Fuzzy_sphere_impl Base; - typedef typename Base_traits::FT FT; - public: - // constructors - Fuzzy_sphere(const SearchTraits& traits_=SearchTraits()):Base(traits_){}; - Fuzzy_sphere(const typename Base_traits::Point_d& center, FT radius, FT epsilon=FT(0),const SearchTraits& traits_=SearchTraits()) : - Base(center,radius,epsilon,traits_) {} - Fuzzy_sphere(const typename SearchTraits::Point_d& center, FT radius, FT epsilon=FT(0), - const SearchTraits& traits_=SearchTraits(), - typename boost::disable_if< - boost::is_same >::type* = 0) - : Base(get(traits_.point_property_map(),center),radius,epsilon,traits_) {} - }; - +{ + typedef internal::Fuzzy_sphere_impl Base; + typedef typename Base::FT FT; +public: + // constructors + Fuzzy_sphere(const SearchTraits& traits_=SearchTraits()):Base(traits_){} + Fuzzy_sphere(const typename SearchTraits::Point_d& center, FT radius, FT epsilon=FT(0),const SearchTraits& traits_=SearchTraits()) : + Base(center,radius,epsilon,traits_) {} +}; + +//specialization for Search_traits_adapter +template +class Fuzzy_sphere< Search_traits_adapter > + : public internal::Fuzzy_sphere_impl,typename Base_traits::Point_d> +{ + typedef Search_traits_adapter SearchTraits; + typedef internal::Fuzzy_sphere_impl Base; + typedef typename Base_traits::FT FT; +public: + // constructors + Fuzzy_sphere(const SearchTraits& traits_=SearchTraits()):Base(traits_){} + + // Constructor for any point type that is not `SearchTraits::Point_d` + template // boost::disable_if requires a template argument to work + Fuzzy_sphere(const Point& center, FT radius, FT epsilon=FT(0),const SearchTraits& traits_=SearchTraits(), + typename boost::disable_if< + boost::is_same >::type* = 0) + : Base(center,radius,epsilon,traits_) {} + + Fuzzy_sphere(const typename SearchTraits::Point_d& center, FT radius, FT epsilon=FT(0), + const SearchTraits& traits_=SearchTraits()) + : Base(get(traits_.point_property_map(),center),radius,epsilon,traits_) {} +}; + } // namespace CGAL #endif // FUZZY_SPHERE_H diff --git a/Spatial_searching/include/CGAL/Search_traits_adapter.h b/Spatial_searching/include/CGAL/Search_traits_adapter.h index f6d4eae7c6d..1fc87b33290 100644 --- a/Spatial_searching/include/CGAL/Search_traits_adapter.h +++ b/Spatial_searching/include/CGAL/Search_traits_adapter.h @@ -33,6 +33,7 @@ #include #include +#include namespace CGAL{ @@ -111,11 +112,23 @@ public: // This is needed because of an undocumented requirement of // Orthogonal_k_neighbor_search and Orthogonal_incremental_neighbor_search: // Traits::Construct_cartesian_const_iterator should be callable - // on the query point type - typename Base_traits::Cartesian_const_iterator_d operator()(const typename Base_traits::Point_d& p) const + // on the query point type. If the query point type is the same as + // Point_with_info, we disable it. + + template // boost::disable_if requires a template argument to work + typename Base_traits::Cartesian_const_iterator_d operator()(const Point& p, + typename boost::disable_if< + boost::is_same >::type* = 0 + ) const { return Base::operator() (p); } - typename Base_traits::Cartesian_const_iterator_d operator()(const typename Base_traits::Point_d& p, int) const + template // boost::disable_if requires a template argument to work + typename Base_traits::Cartesian_const_iterator_d operator()(const Point& p, int, + typename boost::disable_if< + boost::is_same >::type* = 0 + ) const { return Base::operator() (p,0); } }; diff --git a/Spatial_searching/test/Spatial_searching/Circular_query.cpp b/Spatial_searching/test/Spatial_searching/Circular_query.cpp index 4b6ca65a341..fc1f92f335a 100644 --- a/Spatial_searching/test/Spatial_searching/Circular_query.cpp +++ b/Spatial_searching/test/Spatial_searching/Circular_query.cpp @@ -1,108 +1,171 @@ -// file : test/Spatial_searching/Circular_query.C // test whether circular queries are computed correctly for random data // // 1) generate list of query points using report_all // 2) remove and check reported points from these list // 3) check if no remaining points should have been reported +#include "Point_with_info.h" + #include -#include + #include #include #include -#include -#include #include + +#include #include -#include "Point_with_info.h" +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +typedef CGAL::Cartesian K; +typedef K::FT FT; +typedef K::Point_2 Point; +typedef K::Vector_2 Vector; + +typedef CGAL::Random_points_in_square_2 Random_points_iterator; +typedef CGAL::Random_points_on_circle_2 Random_points_on_circle_iterator; +typedef CGAL::Counting_iterator N_Random_points_iterator; +typedef CGAL::Search_traits_2 Traits; -typedef CGAL::Cartesian K; -typedef K::Point_2 Point; -typedef CGAL::Random_points_in_square_2 Random_points_iterator; -typedef CGAL::Counting_iterator N_Random_points_iterator; -typedef CGAL::Search_traits_2 Traits; //for Point_with_info -typedef Point_with_info_helper::type Point_with_info; -typedef Point_property_map Ppmap; -typedef CGAL::Search_traits_adapter Traits_with_info; +typedef Point_with_info_helper::type Point_with_info; +typedef Point_property_map Ppmap; +typedef CGAL::Search_traits_adapter Traits_with_info; -template -void run(std::list all_points){ - typedef CGAL::Fuzzy_sphere Fuzzy_circle; - typedef CGAL::Kd_tree Tree; +template +void run_with_fuzziness(std::list all_points, // intentional copy + const Point& center, + const FT radius, + const FT fuzziness, + CGAL::Random& rnd) +{ + typedef CGAL::Fuzzy_sphere Fuzzy_circle; + + std::cout << "test with center: " << center << " radius: " << radius << " eps: " << fuzziness << "... "; + + const FT inner_radius = radius - fuzziness; + const FT sq_inner_radius = (inner_radius < FT(0)) ? FT(-1) : inner_radius * inner_radius; + const FT outer_radius = radius + fuzziness; + const FT sq_outer_radius = outer_radius * outer_radius; + + // add a bunch of points on the boundary of the inner approximation + // (in general all the constructed points won't be exactly on the boundary, + // but as long as some are, that's okay) + std::size_t N = all_points.size(); + Random_points_on_circle_iterator rpocit(inner_radius, rnd); + for(std::size_t i=0, max=N/10; i Tree; // Insert also the N points in the tree Tree tree( - boost::make_transform_iterator(all_points.begin(),Create_point_with_info()), - boost::make_transform_iterator(all_points.end(),Create_point_with_info()) + boost::make_transform_iterator(all_points.begin(), Create_point_with_info()), + boost::make_transform_iterator(all_points.end(), Create_point_with_info()) ); - // define exact circular range query (fuzziness=0) - Point center(0.25, 0.25); - Fuzzy_circle exact_range(typename Traits::Point_d(center), 0.25); + Fuzzy_circle default_range(typename SearchTraits::Point_d(center), radius); + std::list result; + tree.search(std::back_inserter(result), default_range); - std::list result; - tree.search(std::back_inserter( result ), exact_range); - - typedef std::vector V; + typedef std::vector V; V vec; vec.resize(result.size()); - typename V::iterator it = tree.search(vec.begin(), exact_range); + typename V::iterator it = tree.search(vec.begin(), default_range); + CGAL_USE(it); assert(it == vec.end()); - - tree.search(CGAL::Emptyset_iterator(), Fuzzy_circle(center, 0.25) ); //test compilation when Point != Traits::Point_d - - // test the results of the exact query - std::list copy_all_points(all_points); - for (typename std::list::iterator pt=result.begin(); (pt != result.end()); ++pt) { - // a point with distance d to the center may be reported if d <= r - assert(CGAL::squared_distance(center, get_point(*pt)) <= 0.0625); - copy_all_points.remove(get_point(*pt)); - } - - for (std::list::iterator pt=copy_all_points.begin(); (pt != copy_all_points.end()); ++pt) { - if(CGAL::squared_distance(center, *pt) < 0.0625){ - // all points with a distance d < r must be reported - std::cout << "we missed " << *pt << " with distance = " << CGAL::squared_distance(center,*pt) << std::endl; - } - assert(CGAL::squared_distance(center, *pt) >= 0.0625); - } - result.clear(); - // approximate range searching using value 0.125 for fuzziness parameter - Fuzzy_circle approximate_range(typename Traits::Point_d(center), 0.25, 0.125); - tree.search(std::back_inserter( result ), approximate_range); - // test the results of the approximate query - for (typename std::list::iterator pt=result.begin(); (pt != result.end()); ++pt) { - // a point with distance d to the center may be reported if d <= r + eps - assert(CGAL::squared_distance(center,get_point(*pt))<=0.140625); // (0.25 + 0.125)² + tree.search(CGAL::Emptyset_iterator(), Fuzzy_circle(center, radius) ); //test compilation when Point != Traits::Point_d + + // range searching + Fuzzy_circle approximate_range(typename SearchTraits::Point_d(center), radius, fuzziness); + tree.search(std::back_inserter(result), approximate_range); + std::cout << result.size() << " hits... Verifying correctness..."; + + // test the results + for(typename std::list::iterator pt=result.begin(); (pt != result.end()); ++pt) + { + // a point with distance d to the center can only be reported if d <= r + eps + bool is_correct = (CGAL::squared_distance(center, get_point(*pt)) <= sq_outer_radius); + if(!is_correct) + std::cout << get_point(*pt) << " at distance = " << CGAL::squared_distance(center, get_point(*pt)) + << " should not have been reported (max is: " << sq_outer_radius << ")" << std::endl; + assert(is_correct); all_points.remove(get_point(*pt)); } - for (std::list::iterator pt=all_points.begin(); (pt != all_points.end()); ++pt) { - // all points with a distance d < r - eps must be reported - if(CGAL::squared_distance(center, *pt) < 0.015625){ // (0.25 - 0.125)² - std::cout << "we missed " << *pt << " with distance = " << CGAL::squared_distance(center,*pt) << std::endl; + // note: if eps > r, the squared radius is set to '-1'. We cannot have missed + // any point because there is no inner approximation. + if(sq_inner_radius >= FT(0)) + { + for(std::list::const_iterator pt=all_points.begin(); (pt != all_points.end()); ++pt) + { + // all points with a distance d <= r - eps must have been reported + bool is_correct = (CGAL::squared_distance(center,*pt) > sq_inner_radius); + if(!is_correct) + std::cout << "missed " << *pt << " with distance = " << CGAL::squared_distance(center,*pt) << std::endl; + + assert(is_correct); } - assert(CGAL::squared_distance(center,*pt) >= 0.015625); } + std::cout << "done" << std::endl; } -int main() { +template +void run(std::list all_points, // intentional copy + CGAL::Random& rnd) +{ + Point center(0.25, 0.25); - const int N=1000; + // add some interesting points + all_points.push_back(center); + + run_with_fuzziness(all_points, center, 0. /*radius*/, 0. /*fuzziness*/, rnd); + run_with_fuzziness(all_points, center, 0.25 /*radius*/, 0. /*fuzziness*/, rnd); + run_with_fuzziness(all_points, center, 0.25 /*radius*/, 0.125 /*fuzziness*/, rnd); + run_with_fuzziness(all_points, center, 0.25 /*radius*/, 0.25 /*fuzziness*/, rnd); + run_with_fuzziness(all_points, center, 0.25 /*radius*/, 1. /*fuzziness*/, rnd); + run_with_fuzziness(all_points, center, 1. /*radius*/, 0. /*fuzziness*/, rnd); + run_with_fuzziness(all_points, center, 1. /*radius*/, 0.25 /*fuzziness*/, rnd); + run_with_fuzziness(all_points, center, 10. /*radius*/, 0. /*fuzziness*/, rnd); + run_with_fuzziness(all_points, center, 10. /*radius*/, 10. /*fuzziness*/, rnd); + run_with_fuzziness(all_points, center, 10. /*radius*/, 100. /*fuzziness*/, rnd); +} + +int main() +{ + CGAL::Set_ieee_double_precision pfr; + + CGAL::Random rnd = CGAL::get_default_random(); + std::cout << "seed: " << rnd.get_seed() << std::endl; // generator for random data points in the square ( (-1,-1), (1,1) ) - Random_points_iterator rpit(1.0); + Random_points_iterator rpit(1.0, rnd); // construct list containing N random points + const int N=1000; std::list all_points(N_Random_points_iterator(rpit,0), N_Random_points_iterator(N)); - run(all_points); - run(all_points); + run(all_points, rnd); + run(all_points, rnd); return 0; } diff --git a/Spatial_searching/test/Spatial_searching/Iso_rectangle_2_query.cpp b/Spatial_searching/test/Spatial_searching/Iso_rectangle_2_query.cpp index 15abb583eb1..a5afbefee39 100644 --- a/Spatial_searching/test/Spatial_searching/Iso_rectangle_2_query.cpp +++ b/Spatial_searching/test/Spatial_searching/Iso_rectangle_2_query.cpp @@ -1,101 +1,188 @@ -// file: Iso_rectangle_2_query.C +// test whether box queries are computed correctly for random data +// +// 1) generate list of query points using report_all +// 2) remove and check reported points from these list +// 3) check if no remaining points should have been reported #include -#include + +#include "Point_with_info.h" + #include #include #include -#include #include -#include -#include "Point_with_info.h" +#include +#include + +#include #include #include -typedef CGAL::Simple_cartesian K; -typedef K::Point_2 Point; -typedef K::Vector_2 Vector; -typedef K::Iso_rectangle_2 Iso_rectangle; -typedef CGAL::Random_points_in_square_2 Random_points_iterator; -typedef CGAL::Counting_iterator N_Random_points_iterator; -typedef CGAL::Search_traits_2 Traits; -typedef Point_with_info_helper::type Point_with_info; -typedef Point_property_map Ppmap; -typedef CGAL::Search_traits_adapter Traits_with_info; +typedef CGAL::Simple_cartesian K; +typedef K::FT FT; +typedef K::Point_2 Point; +typedef K::Vector_2 Vector; +typedef K::Iso_rectangle_2 Iso_rectangle; + +typedef CGAL::Random_points_in_square_2 Random_points_iterator; +typedef CGAL::Counting_iterator N_Random_points_iterator; +typedef CGAL::Search_traits_2 Traits; +typedef Point_with_info_helper::type Point_with_info; +typedef Point_property_map Ppmap; +typedef CGAL::Search_traits_adapter Traits_with_info; template -void run(std::list all_points) +void run_with_fuzziness(std::list all_points, + const Point& p, const Point& q, + const FT fuzziness, + CGAL::Random& rnd) { typedef CGAL::Fuzzy_iso_box Fuzzy_box; + std::cout << "test with box: [" << p << " || " << q << "] and eps: " << fuzziness << "... "; + + // test the results of the approximate query + Iso_rectangle inner_ic(p + fuzziness*Vector(1,1), q - fuzziness*Vector(1,1)); + Iso_rectangle outer_ic(p - fuzziness*Vector(1,1), q + fuzziness*Vector(1,1)); + + // If the fuziness is greater than half of the largest dimension of the box, + // then the inner box does not exist + const FT max_box_edge_length = (std::max)(q[1] - p[1], q[0] - p[0]); + const bool is_inner_c_empty = (fuzziness > 0.5 * max_box_edge_length); + if(is_inner_c_empty) + std::cout << " (empty inner box)... "; + + // Insert a bunch of points on the boundary of the inner approximation + std::size_t N = all_points.size(); + + if(!is_inner_c_empty) + { + for(std::size_t i=0, max=N/10; i tree( - boost::make_transform_iterator(all_points.begin(),Create_point_with_info()), - boost::make_transform_iterator(all_points.end(),Create_point_with_info()) + boost::make_transform_iterator(all_points.begin(), Create_point_with_info()), + boost::make_transform_iterator(all_points.end(), Create_point_with_info()) ); - Point p(0.1, 0.2); - Point q(0.3, 0.5); + tree.search(CGAL::Emptyset_iterator(), Fuzzy_box(p,q)); //test compilation when Point != Traits::Point_d + typename SearchTraits::Point_d pp(p); typename SearchTraits::Point_d qq(q); - - Iso_rectangle ic(p,q); - - Fuzzy_box default_range(pp,qq); - + // approximate range searching std::list result; - // Searching the box ic - tree.search( std::back_inserter( result ), default_range); + Fuzzy_box approximate_range(pp, qq, fuzziness); + tree.search(std::back_inserter(result), approximate_range); + std::cout << result.size() << " hits... Verifying correctness..."; - tree.search(CGAL::Emptyset_iterator(), Fuzzy_box(p,q) ); //test compilation when Point != Traits::Point_d - - // test the results of the default query - std::list copy_all_points(all_points); - for (typename std::list::iterator pt=result.begin(); (pt != result.end()); ++pt) { - assert(! ic.has_on_unbounded_side(get_point(*pt)) || ic.has_on_boundary(get_point(*pt))); - copy_all_points.remove(get_point(*pt)); - } - - for (std::list::iterator pt=copy_all_points.begin(); (pt != copy_all_points.end()); ++pt) { - assert(ic.has_on_unbounded_side(*pt) || ic.has_on_boundary(*pt)); - } - - - result.clear(); - // approximate range searching using value 0.1 for fuzziness parameter - Fuzzy_box approximate_range(pp,qq,0.05); - Iso_rectangle inner_ic(p+ 0.05*Vector(1,1),q-0.05*Vector(1,1)); - Iso_rectangle outer_ic(p- 0.05*Vector(1,1),q+0.05*Vector(1,1)); - - tree.search(std::back_inserter( result ), approximate_range); - // test the results of the approximate query - for (typename std::list::iterator pt=result.begin(); (pt != result.end()); ++pt) { - // a point we found may be slighlty outside the isorectangle - assert(! outer_ic.has_on_unbounded_side(get_point(*pt)) || outer_ic.has_on_boundary(get_point(*pt))); + for (typename std::list::iterator pt=result.begin(); (pt != result.end()); ++pt) + { + // a point can only be reported if it is in the outer box + bool is_correct = outer_ic.has_on_bounded_side(get_point(*pt)) || outer_ic.has_on_boundary(get_point(*pt)); + if(!is_correct) + std::cout << get_point(*pt) << " should have not been reported" << std::endl; + assert(is_correct); all_points.remove(get_point(*pt)); } - for (std::list::iterator pt=all_points.begin(); (pt != all_points.end()); ++pt) { - assert(inner_ic.has_on_unbounded_side(*pt) || inner_ic.has_on_boundary(*pt)); + // nothing to test if the inner box is empty because everything is on the unbounded side + if(!is_inner_c_empty) + { + for (std::list::iterator pt=all_points.begin(); (pt != all_points.end()); ++pt) + { + // all points that have not been reported must be outside the inner box + bool is_correct = inner_ic.has_on_unbounded_side(*pt); + if(!is_correct) + std::cout << *pt << " should have been reported" << std::endl; + + assert(is_correct); + } } + std::cout << "done" << std::endl; } -int main() { +template +void run(std::list all_points, // intentional copy + CGAL::Random& rnd) +{ + // bigger box + Point p0(-10., -10.); + Point q0( 10., 10.); + // a subset + Point p1(-CGAL_PI/10., -CGAL_PI/10.); + Point q1( CGAL_PI/10., CGAL_PI/10.); + + // another subset + Point p2(0.1, 0.2); + Point q2(0.3, 0.4); + + // degenerate + Point p3(0., 0.); + Point q3(0., 0.); + + run_with_fuzziness(all_points, p0, q0, 0. /*fuzziness*/, rnd); + run_with_fuzziness(all_points, p0, q0, 0.1 /*fuzziness*/, rnd); + run_with_fuzziness(all_points, p0, q0, 1. /*fuzziness*/, rnd); + run_with_fuzziness(all_points, p0, q0, 10. /*fuzziness*/, rnd); + + run_with_fuzziness(all_points, p1, q1, 0. /*fuzziness*/, rnd); + run_with_fuzziness(all_points, p1, q1, 0.1 /*fuzziness*/, rnd); + run_with_fuzziness(all_points, p1, q1, 1. /*fuzziness*/, rnd); + run_with_fuzziness(all_points, p1, q1, 10. /*fuzziness*/, rnd); + + run_with_fuzziness(all_points, p2, q2, 0. /*fuzziness*/, rnd); + run_with_fuzziness(all_points, p2, q2, 0.1 /*fuzziness*/, rnd); + run_with_fuzziness(all_points, p2, q2, 0.4 /*fuzziness*/, rnd); + + run_with_fuzziness(all_points, p3, q3, 0. /*fuzziness*/, rnd); + run_with_fuzziness(all_points, p3, q3, 0.33 /*fuzziness*/, rnd); + run_with_fuzziness(all_points, p3, q3, 1. /*fuzziness*/, rnd); +} + +int main() +{ const int N=10000; + CGAL::Random rnd = CGAL::get_default_random(); + std::cout << "seed: " << rnd.get_seed() << std::endl; + // generator for random data points in the square ( (-1,-1), (1,1) ) - Random_points_iterator rpit( 1.0); + Random_points_iterator rpit(1.0, rnd); // construct list containing N random points std::list all_points(N_Random_points_iterator(rpit,0), - N_Random_points_iterator(N)); + N_Random_points_iterator(N)); - run(all_points); - run(all_points); + // add some interesting points + all_points.push_back(Point(0., 0.)); + all_points.push_back(Point(-CGAL_PI/10.+0.1, -CGAL_PI/10.+0.1)); + all_points.push_back(Point(1., 1.)); + all_points.push_back(Point(0., 1.)); + all_points.push_back(Point(0.3, 0.4)); + all_points.push_back(Point(0.2, 0.3)); + all_points.push_back(Point(0., 0.1)); + + run(all_points, rnd); + run(all_points, rnd); return 0; } diff --git a/Spatial_searching/test/Spatial_searching/Search_traits_adapter_with_identity_map.cpp b/Spatial_searching/test/Spatial_searching/Search_traits_adapter_with_identity_map.cpp new file mode 100644 index 00000000000..00e66ca1d0f --- /dev/null +++ b/Spatial_searching/test/Spatial_searching/Search_traits_adapter_with_identity_map.cpp @@ -0,0 +1,38 @@ +#include +#include +#include +#include +#include +#include +#include + +typedef CGAL::Simple_cartesian Kernel; +typedef Kernel::Point_2 Point_2; +typedef CGAL::Random_points_in_disc_2 Random_points; + +typedef CGAL::Identity_property_map Point_map; +typedef CGAL::Search_traits_2 Search_base; +typedef CGAL::Search_traits_adapter Search_traits; +typedef CGAL::Fuzzy_sphere Fuzzy_circle; +typedef CGAL::Kd_tree Tree; + +int main () +{ + Random_points rdpts; + std::vector pts; + for (std::size_t i = 0; i < 50; ++ i) + pts.push_back (*(rdpts ++)); + + Tree tree (pts.begin(), pts.end()); + + Point_2 center(0., 0.); + Fuzzy_circle circle (center, 0.5); + std::vector result; + tree.search(std::back_inserter(result), circle); + std::cout << "The points in the fuzzy circle centered at (0., 0.) "; + std::cout << "with fuzzy radius (0.5) are: " << std::endl; + for (std::size_t i = 0; i < result.size(); ++ i) + std::cout << " * " << result[i] << std::endl; + + return 0; +} diff --git a/Surface_mesh/doc/Surface_mesh/PackageDescription.txt b/Surface_mesh/doc/Surface_mesh/PackageDescription.txt index 58ead2eda6c..1707c8a7a3f 100644 --- a/Surface_mesh/doc/Surface_mesh/PackageDescription.txt +++ b/Surface_mesh/doc/Surface_mesh/PackageDescription.txt @@ -1,6 +1,14 @@ /// \defgroup PkgSurface_mesh Surface Mesh Reference +/*! Draw. + \code + #include + \endcode +*/ +/// \defgroup PkgDrawSurfaceMesh Draw a Surface Mesh +/// \ingroup PkgSurface_mesh + /*! \addtogroup PkgSurface_mesh \cgalPkgDescriptionBegin{Surface Mesh,PkgSurfaceMeshSummary} @@ -31,5 +39,8 @@ and faces is much simpler and can be used at runtime and not at compile time.} - `CGAL::Surface_mesh

` +### Draw a Surface Mesh ### +- `CGAL::draw` + */ diff --git a/Surface_mesh/doc/Surface_mesh/Surface_mesh.txt b/Surface_mesh/doc/Surface_mesh/Surface_mesh.txt index 395ec2ca8b1..06b7c0dc14d 100644 --- a/Surface_mesh/doc/Surface_mesh/Surface_mesh.txt +++ b/Surface_mesh/doc/Surface_mesh/Surface_mesh.txt @@ -344,6 +344,20 @@ refering to the right vertices. \subsection SubsectionSurfaceMeshMemoryManagementExample Example \cgalExample{Surface_mesh/sm_memory.cpp} +\section SurfaceMeshDraw Draw a Surface Mesh +\anchor ssecDrawSurfaceMesh + +A surface mesh can be visualized by calling the `CGAL::draw()` function as shown in the following example. This function opens a new window showing the given surface mesh. The function is blocking, that is the program continues as soon as the user closes the window. + +\cgalExample{Surface_mesh/draw_surface_mesh.cpp} + +This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time. + +\cgalFigureBegin{fig_draw_surface_mesh,draw_surface_mesh.png} +Result of the run of the draw_surface_mesh program. A window shows the surface mesh and allows to navigate through the 3D scene. +\cgalFigureEnd + + \section sectionSurfaceMeshImplementation Implementation Details As integer type for the indices we have chosen `boost::uint32_t`. On 64 bit operating systems they diff --git a/Surface_mesh/doc/Surface_mesh/examples.txt b/Surface_mesh/doc/Surface_mesh/examples.txt index 7d76ae3218a..b19e4dfa646 100644 --- a/Surface_mesh/doc/Surface_mesh/examples.txt +++ b/Surface_mesh/doc/Surface_mesh/examples.txt @@ -10,4 +10,5 @@ \example Surface_mesh/sm_do_intersect.cpp \example Surface_mesh/sm_aabbtree.cpp @endcond +\example Surface_mesh/draw_surface_mesh.cpp */ diff --git a/Surface_mesh/doc/Surface_mesh/fig/draw_surface_mesh.png b/Surface_mesh/doc/Surface_mesh/fig/draw_surface_mesh.png new file mode 100644 index 00000000000..1c0800bfe46 Binary files /dev/null and b/Surface_mesh/doc/Surface_mesh/fig/draw_surface_mesh.png differ diff --git a/Surface_mesh/examples/Surface_mesh/CMakeLists.txt b/Surface_mesh/examples/Surface_mesh/CMakeLists.txt index cdd0587bf7f..6170d1bb2b7 100644 --- a/Surface_mesh/examples/Surface_mesh/CMakeLists.txt +++ b/Surface_mesh/examples/Surface_mesh/CMakeLists.txt @@ -6,8 +6,16 @@ project( Surface_mesh_Examples ) cmake_minimum_required(VERSION 2.8.11) +if(NOT POLICY CMP0070 AND POLICY CMP0053) + # Only set CMP0053 to OLD with CMake<3.10, otherwise there is a warning. + cmake_policy(SET CMP0053 OLD) +endif() -find_package(CGAL QUIET) +find_package(CGAL COMPONENTS Qt5) + +if(CGAL_Qt5_FOUND) + add_definitions(-DCGAL_USE_BASIC_VIEWER -DQT_NO_KEYWORDS) +endif() if ( CGAL_FOUND ) @@ -28,6 +36,11 @@ if ( CGAL_FOUND ) create_single_source_cgal_program( "sm_memory.cpp" ) create_single_source_cgal_program( "sm_properties.cpp" ) + create_single_source_cgal_program("draw_surface_mesh.cpp") + if(CGAL_Qt5_FOUND ) + target_link_libraries(draw_surface_mesh PUBLIC CGAL::CGAL_Qt5) + endif() + else() message(STATUS "This program requires the CGAL library, and will not be compiled.") diff --git a/Surface_mesh/examples/Surface_mesh/cube.off b/Surface_mesh/examples/Surface_mesh/cube.off deleted file mode 100644 index b1afa5a6858..00000000000 --- a/Surface_mesh/examples/Surface_mesh/cube.off +++ /dev/null @@ -1,22 +0,0 @@ -OFF -8 12 0 --1 -1 -1 --1 1 -1 -1 1 -1 -1 -1 -1 --1 -1 1 --1 1 1 -1 1 1 -1 -1 1 -3 0 1 3 -3 3 1 2 -3 0 4 1 -3 1 4 5 -3 3 2 7 -3 7 2 6 -3 4 0 3 -3 7 4 3 -3 6 4 7 -3 6 5 4 -3 1 5 6 -3 2 1 6 diff --git a/Surface_mesh/examples/Surface_mesh/draw_surface_mesh.cpp b/Surface_mesh/examples/Surface_mesh/draw_surface_mesh.cpp new file mode 100644 index 00000000000..4735193c89f --- /dev/null +++ b/Surface_mesh/examples/Surface_mesh/draw_surface_mesh.cpp @@ -0,0 +1,19 @@ +#include +#include +#include +#include + +typedef CGAL::Simple_cartesian Kernel; +typedef Kernel::Point_3 Point; +typedef CGAL::Surface_mesh Mesh; + +int main(int argc, char* argv[]) +{ + Mesh sm1; + std::ifstream in1((argc>1)?argv[1]:"data/triangle.off"); + in1 >> sm1; + + CGAL::draw(sm1); + + return EXIT_SUCCESS; +} diff --git a/Surface_mesh/examples/Surface_mesh/sm_join.cpp b/Surface_mesh/examples/Surface_mesh/sm_join.cpp index c892bfc4cd9..e787eb66c70 100644 --- a/Surface_mesh/examples/Surface_mesh/sm_join.cpp +++ b/Surface_mesh/examples/Surface_mesh/sm_join.cpp @@ -36,5 +36,4 @@ int main(int argc, char* argv[]) std::cout << sm1 << std::endl; - } diff --git a/Surface_mesh/include/CGAL/draw_surface_mesh.h b/Surface_mesh/include/CGAL/draw_surface_mesh.h new file mode 100644 index 00000000000..3e5f602d94c --- /dev/null +++ b/Surface_mesh/include/CGAL/draw_surface_mesh.h @@ -0,0 +1,252 @@ +// Copyright (c) 2018 GeometryFactory (France) +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0+ +// +// Author(s) : Guillaume Damiand + +#ifndef CGAL_DRAW_SURFACE_MESH_H +#define CGAL_DRAW_SURFACE_MESH_H + +#ifdef DOXYGEN_RUNNING + +/*! +\ingroup PkgDrawSurfaceMesh + +Open a new window and draw `asm`, an instance of the `CGAL::Surface_mesh` class. The function is blocking, that is the program continues as soon as the user closes the window. This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time. +\tparam SM an instance of the `CGAL::Surface_mesh` class. +\param asm the surface mesh to draw. + +*/ +template +void draw(const SM& asm); + +#else // DOXYGEN_RUNNING + +#include +#include + +#ifdef CGAL_USE_BASIC_VIEWER + +#include + +namespace CGAL +{ + +// Default color functor; user can change it to have its own face color +struct DefaultColorFunctorSM +{ + template + static CGAL::Color run(const SM&, + typename SM::Face_index fh) + { + if (fh==boost::graph_traits::null_face()) // use to get the mono color + return CGAL::Color(100, 125, 200); // R G B between 0-255 + + CGAL::Random random((unsigned int)fh); + return get_random_color(random); + } +}; + +template +class SimpleSurfaceMeshViewerQt : public Basic_viewer_qt +{ + typedef Basic_viewer_qt Base; + typedef typename SM::Point Point; + typedef typename CGAL::Kernel_traits::Kernel Kernel; + typedef typename SM::Vertex_index vertex_descriptor; + typedef typename SM::Face_index face_descriptor; + typedef typename SM::Edge_index edge_descriptor; + typedef typename SM::Halfedge_index halfedge_descriptor; + +public: + /// Construct the viewer. + /// @param amesh the surface mesh to view + /// @param title the title of the window + /// @param anofaces if true, do not draw faces (faces are not computed; this can be + /// usefull for very big object where this time could be long) + SimpleSurfaceMeshViewerQt(QWidget* parent, + const SM& amesh, + const char* title="Basic Surface_mesh Viewer", + bool anofaces=false, + const ColorFunctor& fcolor=ColorFunctor()) : + // First draw: no vertex; edges, faces; mono-color; inverse normal + Base(parent, title, false, true, true, true, false), + sm(amesh), + m_nofaces(anofaces), + m_fcolor(fcolor) + { + compute_elements(); + } + +protected: + void compute_face(face_descriptor fh) + { + CGAL::Color c=m_fcolor.run(sm, fh); + face_begin(c); + halfedge_descriptor hd=sm.halfedge(fh); + do + { + add_point_in_face(sm.point(sm.source(hd)), get_vertex_normal(hd)); + hd=sm.next(hd); + } + while(hd!=sm.halfedge(fh)); + face_end(); + } + + void compute_edge(edge_descriptor e) + { + add_segment(sm.point(sm.source(sm.halfedge(e))), + sm.point(sm.target(sm.halfedge(e)))); + } + + void compute_vertex(vertex_descriptor vh) + { add_point(sm.point(vh)); } + + void compute_elements() + { + clear(); + + if (!m_nofaces) + { + for (typename SM::Face_range::iterator f=sm.faces().begin(); + f!=sm.faces().end(); ++f) + { + if (*f!=boost::graph_traits::null_face()) + { compute_face(*f); } + } + } + + for (typename SM::Edge_range::iterator e=sm.edges().begin(); + e!=sm.edges().end(); ++e) + { compute_edge(*e); } + + for (typename SM::Vertex_range::iterator v=sm.vertices().begin(); + v!=sm.vertices().end(); ++v) + { compute_vertex(*v); } + } + + virtual void keyPressEvent(QKeyEvent *e) + { + // Test key pressed: + // const ::Qt::KeyboardModifiers modifiers = e->modifiers(); + // if ((e->key()==Qt::Key_PageUp) && (modifiers==Qt::NoButton)) { ... } + + // Call: * compute_elements() if the model changed, followed by + // * redraw() if some viewing parameters changed that implies some + // modifications of the buffers + // (eg. type of normal, color/mono) + // * update() just to update the drawing + + // Call the base method to process others/classicals key + Base::keyPressEvent(e); + } + +protected: + typename Kernel::Vector_3 get_face_normal(halfedge_descriptor he) + { + typename Kernel::Vector_3 normal=CGAL::NULL_VECTOR; + halfedge_descriptor end=he; + unsigned int nb=0; + do + { + internal::newell_single_step_3(sm.point(sm.source(he)), + sm.point(sm.target(he)), normal); + ++nb; + he=sm.next(he); + } + while (he!=end); + assert(nb>0); + return (typename Kernel::Construct_scaled_vector_3()(normal, 1.0/nb)); + } + + typename Kernel::Vector_3 get_vertex_normal(halfedge_descriptor he) + { + typename Kernel::Vector_3 normal=CGAL::NULL_VECTOR; + halfedge_descriptor end=he; + do + { + if (!sm.is_border(he)) + { + typename Kernel::Vector_3 n=get_face_normal(he); + normal=typename Kernel::Construct_sum_of_vectors_3()(normal, n); + } + he=sm.next(sm.opposite(he)); + } + while (he!=end); + + if (!typename Kernel::Equal_3()(normal, CGAL::NULL_VECTOR)) + { normal=(typename Kernel::Construct_scaled_vector_3() + (normal, 1.0/CGAL::sqrt(normal.squared_length()))); } + + return normal; + } + +protected: + const SM& sm; + bool m_nofaces; + const ColorFunctor& m_fcolor; +}; + +template +void draw(const SM& amesh, + const char* title, + bool nofill, + const ColorFunctor& fcolor) +{ +#if defined(CGAL_TEST_SUITE) + bool cgal_test_suite=true; +#else + bool cgal_test_suite=false; +#endif + + if (!cgal_test_suite) + { + int argc=1; + const char* argv[2]={"surface_mesh_viewer","\0"}; + QApplication app(argc,const_cast(argv)); + SimpleSurfaceMeshViewerQt mainwindow(app.activeWindow(), + amesh, + title, + nofill, + fcolor); + mainwindow.show(); + app.exec(); + } +} + +template +void draw(const SM& amesh, const char* title, bool nofill) +{ + DefaultColorFunctorSM c; + draw(amesh, title, nofill, c); +} + +template +void draw(const SM& amesh, const char* title) +{ draw(amesh, title, false); } + +template +void draw(const SM& amesh) +{ draw(amesh, "Basic Surface_mesh Viewer"); } + +} // End namespace CGAL + +#endif // CGAL_USE_BASIC_VIEWER + +#endif // DOXYGEN_RUNNING + +#endif // CGAL_DRAW_SURFACE_MESH_H diff --git a/Surface_mesh/package_info/Surface_mesh/dependencies b/Surface_mesh/package_info/Surface_mesh/dependencies index c34f3a297ff..474db4e6713 100644 --- a/Surface_mesh/package_info/Surface_mesh/dependencies +++ b/Surface_mesh/package_info/Surface_mesh/dependencies @@ -4,6 +4,7 @@ Cartesian_kernel Circulator Distance_2 Distance_3 +GraphicsView Hash_map Installation Interval_support diff --git a/Surface_mesher/demo/Surface_mesher/volume.cpp b/Surface_mesher/demo/Surface_mesher/volume.cpp index 5f0d705bcf3..75064dece0c 100644 --- a/Surface_mesher/demo/Surface_mesher/volume.cpp +++ b/Surface_mesher/demo/Surface_mesher/volume.cpp @@ -769,15 +769,15 @@ void Volume::display_marchin_cube() const unsigned int nbt = facets.size() / 9; for(unsigned int i=begin;iitem(value_id))); + m_surface_mc.push_back(Facet_(t,n,values_list->item(value_id))); } nbs_of_mc_triangles[value_id]=m_surface_mc.size(); mc_timer.start(); @@ -791,7 +791,7 @@ void Volume::display_marchin_cube() list_draw_marching_cube_is_valid = false; } CGAL::Bbox_3 bbox(0,0,0,0,0,0); - for(std::vector::const_iterator + for(std::vector::const_iterator it = m_surface_mc.begin(), end = m_surface_mc.end(); it != end; ++it) { @@ -876,7 +876,7 @@ void Volume::display_surface_mesher_result() if(mw->searchSeedsCheckBox->isChecked()) { - typedef std::vector > Seeds; + typedef std::vector > Seeds; Seeds seeds; { std::cerr << "Search seeds...\n"; @@ -905,13 +905,13 @@ void Volume::display_surface_mesher_result() it != end; ++it) { seeds_out << it->first << std::endl; - CGAL::Random_points_on_sphere_3 random_points_on_sphere_3(it->second); + CGAL::Random_points_on_sphere_3 random_points_on_sphere_3(it->second); Oracle::Intersect_3 intersect = oracle.intersect_3_object(); for(int i = 0; i < 20; ++i) { - const Point test = it->first + (*random_points_on_sphere_3++ - CGAL::ORIGIN); + const Point_3 test = it->first + (*random_points_on_sphere_3++ - CGAL::ORIGIN); CGAL::Object o = intersect(surface, Segment_3(it->first, test)); - if (const Point* intersection = CGAL::object_cast(&o)) { + if (const Point_3* intersection = CGAL::object_cast(&o)) { segments_out << "2 " << it->first << " " << *intersection << std::endl; del.insert(*intersection); } @@ -1043,8 +1043,8 @@ void Volume::display_surface_mesher_result() const int index = fit->second; // here "left" means nothing - const Point left_circumcenter = cell->circumcenter(); - const Point right_circumcenter = cell->neighbor(index)->circumcenter(); + const Point_3 left_circumcenter = cell->circumcenter(); + const Point_3 right_circumcenter = cell->neighbor(index)->circumcenter(); const Triangle_3 t = Triangle_3(cell->vertex(del.vertex_triple_index(index, 0))->point(), @@ -1056,13 +1056,13 @@ void Volume::display_surface_mesher_result() n = n / std::sqrt(n*n); if(mw->labellizedRadioButton->isChecked()) { - m_surface.push_back(Facet(t, + m_surface.push_back(Facet_(t, n, values_list->search((std::max)(surface(left_circumcenter), surface(right_circumcenter))))); } else { - m_surface.push_back(Facet(t,n,cell->vertex(del.vertex_triple_index(index, 0))->point().element_index())); + m_surface.push_back(Facet_(t,n,cell->vertex(del.vertex_triple_index(index, 0))->point().element_index())); } } @@ -1072,7 +1072,7 @@ void Volume::display_surface_mesher_result() } CGAL::Bbox_3 bbox(0,0,0,0,0,0); - for(std::vector::const_iterator + for(std::vector::const_iterator it = m_surface.begin(), end = m_surface.end(); it != end; ++it) { @@ -1253,8 +1253,8 @@ void Volume::draw() end = del.finite_edges_end(); eit != end; ++eit) { - const Point p1 = eit->first->vertex(eit->second)->point(); - const Point p2 = eit->first->vertex(eit->third)->point(); + const Point_3 p1 = eit->first->vertex(eit->second)->point(); + const Point_3 p2 = eit->first->vertex(eit->third)->point(); ::glVertex3d(p1.x(),p1.y(),p1.z()); ::glVertex3d(p2.x(),p2.y(),p2.z()); } @@ -1354,9 +1354,9 @@ void Volume::gl_draw_surface() if(c2t3.face_status(facet_cell, facet_index) == C2t3::NOT_IN_COMPLEX) { continue; } - const Point& a = facet_cell->vertex(del.vertex_triple_index(facet_index, 0))->point(); - const Point& b = facet_cell->vertex(del.vertex_triple_index(facet_index, 1))->point(); - const Point& c = facet_cell->vertex(del.vertex_triple_index(facet_index, 2))->point(); + const Point_3& a = facet_cell->vertex(del.vertex_triple_index(facet_index, 0))->point(); + const Point_3& b = facet_cell->vertex(del.vertex_triple_index(facet_index, 1))->point(); + const Point_3& c = facet_cell->vertex(del.vertex_triple_index(facet_index, 2))->point(); Vector n = CGAL::cross_product(b-a,c-a); n = n / std::sqrt(n*n); // unit normal if(m_inverse_normals) { @@ -1443,9 +1443,9 @@ void Volume::gl_draw_surface() else continue; // go to next facet } - const Point& a = opposite_cell->vertex(del.vertex_triple_index(opposite_index, 0))->point(); - const Point& b = opposite_cell->vertex(del.vertex_triple_index(opposite_index, 1))->point(); - const Point& c = opposite_cell->vertex(del.vertex_triple_index(opposite_index, 2))->point(); + const Point_3& a = opposite_cell->vertex(del.vertex_triple_index(opposite_index, 0))->point(); + const Point_3& b = opposite_cell->vertex(del.vertex_triple_index(opposite_index, 1))->point(); + const Point_3& c = opposite_cell->vertex(del.vertex_triple_index(opposite_index, 2))->point(); Vector n = CGAL::cross_product(b-a,c-a); n = n / std::sqrt(n*n); // unit normal if(m_inverse_normals) { @@ -1480,7 +1480,7 @@ void Volume::gl_draw_surface(Iterator begin, Iterator end, const QTreeWidgetItem unsigned int counter = 0; for(Iterator it = begin; it != end; ++it) { - const Facet& f = *it; + const Facet_& f = *it; if(f.get<2>() != i) continue; @@ -1492,9 +1492,9 @@ void Volume::gl_draw_surface(Iterator begin, Iterator end, const QTreeWidgetItem ::glNormal3d(n.x(),n.y(),n.z()); const Triangle_3& t = f.get<0>(); - const Point& a = t[0]; - const Point& b = t[1]; - const Point& c = t[2]; + const Point_3& a = t[0]; + const Point_3& b = t[1]; + const Point_3& c = t[2]; ::glVertex3d(a.x(),a.y(),a.z()); ::glVertex3d(b.x(),b.y(),b.z()); diff --git a/Surface_mesher/demo/Surface_mesher/volume.h b/Surface_mesher/demo/Surface_mesher/volume.h index 408cb6d71ee..7ec0b223e9f 100644 --- a/Surface_mesher/demo/Surface_mesher/volume.h +++ b/Surface_mesher/demo/Surface_mesher/volume.h @@ -43,7 +43,7 @@ struct Kernel : public Kernel1 { }; typedef Kernel::FT FT; -typedef Kernel::Point_3 Point; +typedef Kernel::Point_3 Point_3; typedef Kernel::Sphere_3 Sphere; typedef Kernel::Vector_3 Vector; typedef Kernel::Triangle_3 Triangle_3; @@ -51,9 +51,10 @@ typedef Kernel::Segment_3 Segment_3; // typedef CGAL::Triple Facet; -typedef boost::tuple Facet; +typedef boost::tuple Facet_; -typedef CBinary_image_3 Binary_image; + +typedef CBinary_image_3 Binary_image; class QTreeWidgetItem; @@ -112,7 +113,7 @@ private: bool use_gouraud; bool show_bbox; - std::vector m_surface; + std::vector m_surface; Tr del; // 3D-Delaunay triangulation C2t3 c2t3; // 2D complex in 3D triangulation @@ -132,7 +133,7 @@ private: int sm_total_time; #ifdef CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE - std::vector m_surface_mc; + std::vector m_surface_mc; MarchingCubes mc ; std::vector nbs_of_mc_triangles; std::vector lists_draw_surface_mc; diff --git a/Triangulation_2/doc/Triangulation_2/CGAL/draw_triangulation_2.h b/Triangulation_2/doc/Triangulation_2/CGAL/draw_triangulation_2.h new file mode 100644 index 00000000000..11d13a005a1 --- /dev/null +++ b/Triangulation_2/doc/Triangulation_2/CGAL/draw_triangulation_2.h @@ -0,0 +1,15 @@ +namespace CGAL { + +/*! +\ingroup PkgDrawTriangulation2 + +Open a new window and draw `at2`, a model of the `TriangulationDataStructure_2` concept. The function is blocking, that is the program continues as soon as the user closes the window. This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time. +\tparam T2 a model of the `TriangulationDataStructure_2` concept. +\param at2 the triangulation to draw. + +*/ +template +void draw(const T2& at2); + +} /* namespace CGAL */ + diff --git a/Triangulation_2/doc/Triangulation_2/Concepts/ConstrainedTriangulationTraits_2.h b/Triangulation_2/doc/Triangulation_2/Concepts/ConstrainedTriangulationTraits_2.h index 70518403f11..dd235e31e37 100644 --- a/Triangulation_2/doc/Triangulation_2/Concepts/ConstrainedTriangulationTraits_2.h +++ b/Triangulation_2/doc/Triangulation_2/Concepts/ConstrainedTriangulationTraits_2.h @@ -76,6 +76,15 @@ between `p` and `l`. */ typedef unspecified_type Compute_squared_distance_2; +/*! +A function object whose +`operator()` computes the bounding box of a point. + +`unspecified_type operator()(Point_2 p);` Returns the bounding box of `p`. +The result type is either `Bbox_2` or `Bbox_3` (for projection traits classes). +*/ +typedef unspecified_type Compute_bounding_box_2; + /// @} /// \name Access to Constructor Objects diff --git a/Triangulation_2/doc/Triangulation_2/PackageDescription.txt b/Triangulation_2/doc/Triangulation_2/PackageDescription.txt index a5d99c7a98b..0984fbd61b3 100644 --- a/Triangulation_2/doc/Triangulation_2/PackageDescription.txt +++ b/Triangulation_2/doc/Triangulation_2/PackageDescription.txt @@ -16,6 +16,14 @@ /// \defgroup PkgTriangulation2Miscellaneous Miscellaneous /// \ingroup PkgTriangulation2 +/*! Draw. + \code + #include + \endcode +*/ +/// \defgroup PkgDrawTriangulation2 Draw a Triangulation 2 +/// \ingroup PkgTriangulation2 + /*! \addtogroup PkgTriangulation2 \todo check generated documentation @@ -104,5 +112,8 @@ are described in Chapter \ref PkgTDS2 "2D Triangulation Data Structure". ## Enum ## - \link CGAL::Triangulation_2::Locate_type `CGAL::Triangulation_2::Locate_type` \endlink +### Draw a Triangulation 2 ### +- `CGAL::draw` + */ diff --git a/Triangulation_2/doc/Triangulation_2/Triangulation_2.txt b/Triangulation_2/doc/Triangulation_2/Triangulation_2.txt index eb0daf0d94a..65688e950b0 100644 --- a/Triangulation_2/doc/Triangulation_2/Triangulation_2.txt +++ b/Triangulation_2/doc/Triangulation_2/Triangulation_2.txt @@ -472,6 +472,19 @@ and inserted in the triangulation. Finally points on the convex hull are written to cout. \cgalExample{Triangulation_2/triangulation_prog1.cpp} +\subsection Triangulation2Draw Draw a 2D Triangulation +\anchor ssecDrawT2 + +A 2D triangulation can be visualized by calling the `CGAL::draw()` function as shown in the following example. This function opens a new window showing the given 2D triangulation. The function is blocking, that is the program continues as soon as the user closes the window. + +\cgalExample{Triangulation_2/draw_triangulation_2.cpp} + +This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time. + +\cgalFigureBegin{fig_draw_triangulation_2,draw_triangulation_2.png} +Result of the run of the draw_triangulation_2 program. A window shows the 2D triangulation and allows to navigate through the scene. +\cgalFigureEnd + \section Section_2D_Triangulations_Delaunay Delaunay Triangulations \subsection Subsection_2D_Triangulations_Delaunay_Description Description diff --git a/Triangulation_2/doc/Triangulation_2/examples.txt b/Triangulation_2/doc/Triangulation_2/examples.txt index 86a3c4fd016..9bff70297db 100644 --- a/Triangulation_2/doc/Triangulation_2/examples.txt +++ b/Triangulation_2/doc/Triangulation_2/examples.txt @@ -18,4 +18,5 @@ \example Triangulation_2/voronoi.cpp \example Triangulation_2/copy_triangulation_2.cpp \example Triangulation_2/polylines_triangulation.cpp +\example Triangulation_2/draw_triangulation_2.cpp */ diff --git a/Triangulation_2/doc/Triangulation_2/fig/draw_triangulation_2.png b/Triangulation_2/doc/Triangulation_2/fig/draw_triangulation_2.png new file mode 100644 index 00000000000..fee87844199 Binary files /dev/null and b/Triangulation_2/doc/Triangulation_2/fig/draw_triangulation_2.png differ diff --git a/Triangulation_2/examples/Triangulation_2/CMakeLists.txt b/Triangulation_2/examples/Triangulation_2/CMakeLists.txt index 5eb6e369b69..f1a119e58b6 100644 --- a/Triangulation_2/examples/Triangulation_2/CMakeLists.txt +++ b/Triangulation_2/examples/Triangulation_2/CMakeLists.txt @@ -4,9 +4,18 @@ project( Triangulation_2_Examples ) -cmake_minimum_required(VERSION 2.8.10) +cmake_minimum_required(VERSION 3.1) -find_package(CGAL QUIET) +if(NOT POLICY CMP0070 AND POLICY CMP0053) + # Only set CMP0053 to OLD with CMake<3.10, otherwise there is a warning. + cmake_policy(SET CMP0053 OLD) +endif() + +find_package(CGAL COMPONENTS Qt5) + +if(CGAL_Qt5_FOUND) + add_definitions(-DCGAL_USE_BASIC_VIEWER -DQT_NO_KEYWORDS) +endif() if ( CGAL_FOUND ) @@ -22,6 +31,10 @@ if ( CGAL_FOUND ) create_single_source_cgal_program( "${cppfile}" ) endforeach() + if(CGAL_Qt5_FOUND) + target_link_libraries(draw_triangulation_2 PUBLIC CGAL::CGAL_Qt5) + endif() + else() message(STATUS "This program requires the CGAL library, and will not be compiled.") diff --git a/Triangulation_2/examples/Triangulation_2/draw_triangulation_2.cpp b/Triangulation_2/examples/Triangulation_2/draw_triangulation_2.cpp new file mode 100644 index 00000000000..ec8f03b0e3b --- /dev/null +++ b/Triangulation_2/examples/Triangulation_2/draw_triangulation_2.cpp @@ -0,0 +1,21 @@ +#include +#include +#include +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef CGAL::Triangulation_2 Triangulation; +typedef Triangulation::Point Point; + +int main() { + std::ifstream in("data/triangulation_prog1.cin"); + std::istream_iterator begin(in); + std::istream_iterator end; + + Triangulation t; + t.insert(begin, end); + + CGAL::draw(t); + + return EXIT_SUCCESS; +} diff --git a/Triangulation_2/examples/Triangulation_2/regular.cpp b/Triangulation_2/examples/Triangulation_2/regular.cpp index 2bbfe11e823..4cc0a1857ad 100644 --- a/Triangulation_2/examples/Triangulation_2/regular.cpp +++ b/Triangulation_2/examples/Triangulation_2/regular.cpp @@ -24,5 +24,6 @@ int main() std::cout << rt.number_of_vertices() << std::endl; std::cout << "number of hidden vertices : " ; std::cout << rt.number_of_hidden_vertices() << std::endl; + return 0; } diff --git a/Triangulation_2/include/CGAL/Constrained_triangulation_2.h b/Triangulation_2/include/CGAL/Constrained_triangulation_2.h index a7cb8b2cc69..44c6da5fee9 100644 --- a/Triangulation_2/include/CGAL/Constrained_triangulation_2.h +++ b/Triangulation_2/include/CGAL/Constrained_triangulation_2.h @@ -40,6 +40,10 @@ #include #include + +#include +#include + namespace CGAL { struct No_intersection_tag{}; @@ -1440,11 +1444,72 @@ intersection(const Gt& gt, const typename Gt::Point_2& pc, const typename Gt::Point_2& pd, typename Gt::Point_2& pi, - Exact_predicates_tag) + Exact_predicates_tag, + CGAL::Tag_false /* not a FT is not floating-point */) { return compute_intersection(gt,pa,pb,pc,pd,pi); } +template +inline bool +intersection(const Gt& gt, + const typename Gt::Point_2& pa, + const typename Gt::Point_2& pb, + const typename Gt::Point_2& pc, + const typename Gt::Point_2& pd, + typename Gt::Point_2& pi, + Exact_predicates_tag, + CGAL::Tag_true /* FT is a floating-point type */) +{ + const bool result = compute_intersection(gt,pa,pb,pc,pd,pi); + if(!result) return result; + if(pi == pa || pi == pb || pi == pc || pi == pd) { +#ifdef CGAL_CDT_2_DEBUG_INTERSECTIONS + std::cerr << " CT_2::intersection: intersection is an existing point " + << pi << std::endl; +#endif + return result; + } + + +#ifdef CGAL_CDT_2_INTERSECTION_SNAPPING_ULP_DISTANCE + const int dist = CGAL_CDT_2_INTERSECTION_SNAPPING_ULP_DISTANCE; +#else + const int dist = 4; +#endif + typedef typename Gt::Construct_bbox_2 Construct_bbox_2; + Construct_bbox_2 bbox = gt.construct_bbox_2_object(); + typename boost::result_of::type bb(bbox(pi)); + bb.dilate(dist); + if(do_overlap(bb, bbox(pa))) pi = pa; + if(do_overlap(bb, bbox(pb))) pi = pb; + if(do_overlap(bb, bbox(pc))) pi = pc; + if(do_overlap(bb, bbox(pd))) pi = pd; +#ifdef CGAL_CDT_2_DEBUG_INTERSECTIONS + if(pi == pa || pi == pb || pi == pc || pi == pd) { + std::cerr << " CT_2::intersection: intersection SNAPPED to an existing point " + << pi << std::endl; + } +#endif + return result; +} + +template +inline bool +intersection(const Gt& gt, + const typename Gt::Point_2& pa, + const typename Gt::Point_2& pb, + const typename Gt::Point_2& pc, + const typename Gt::Point_2& pd, + typename Gt::Point_2& pi, + Exact_predicates_tag exact_predicates_tag) +{ + typedef typename Gt::FT FT; + return intersection(gt,pa,pb,pc,pd,pi, + exact_predicates_tag, + Boolean_tag::value>()); +} + template bool diff --git a/Triangulation_2/include/CGAL/Regular_triangulation_2.h b/Triangulation_2/include/CGAL/Regular_triangulation_2.h index 7d29dad74dd..121595ab3c8 100644 --- a/Triangulation_2/include/CGAL/Regular_triangulation_2.h +++ b/Triangulation_2/include/CGAL/Regular_triangulation_2.h @@ -443,7 +443,8 @@ private: template struct Index_to_Bare_point { - const Bare_point& operator()(const std::size_t& i) const + typename boost::result_of::type + operator()(const std::size_t& i) const { return cp(c[i]); } diff --git a/Triangulation_2/include/CGAL/draw_triangulation_2.h b/Triangulation_2/include/CGAL/draw_triangulation_2.h new file mode 100644 index 00000000000..a1cfc460fdb --- /dev/null +++ b/Triangulation_2/include/CGAL/draw_triangulation_2.h @@ -0,0 +1,185 @@ +// Copyright(c) 2018 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0+ +// +// Author(s) : Guillaume Damiand + +#ifndef CGAL_DRAW_T2_H +#define CGAL_DRAW_T2_H + +#include +#include + +#ifdef CGAL_USE_BASIC_VIEWER + +#include + +namespace CGAL +{ + +// Default color functor; user can change it to have its own face color +struct DefaultColorFunctorT2 +{ + template + static CGAL::Color run(const T2&, + const typename T2::Finite_faces_iterator fh) + { + CGAL::Random random((unsigned int)(std::size_t)(&*fh)); + return get_random_color(random); + } +}; + +// Viewer class for T2 +template +class SimpleTriangulation2ViewerQt : public Basic_viewer_qt +{ + typedef Basic_viewer_qt Base; + typedef typename T2::Vertex_handle Vertex_const_handle; + typedef typename T2::Finite_edges_iterator Edge_const_handle; + typedef typename T2::Finite_faces_iterator Facet_const_handle; + typedef typename T2::Point Point; + +public: + /// Construct the viewer. + /// @param at2 the t2 to view + /// @param title the title of the window + /// @param anofaces if true, do not draw faces (faces are not computed; this can be + /// usefull for very big object where this time could be long) + SimpleTriangulation2ViewerQt(QWidget* parent, const T2& at2, + const char* title="Basic T2 Viewer", + bool anofaces=false, + const ColorFunctor& fcolor=ColorFunctor()) : + // First draw: vertices; edges, faces; multi-color; no inverse normal + Base(parent, title, true, true, true, false, false), + t2(at2), + m_nofaces(anofaces), + m_fcolor(fcolor) + { + compute_elements(); + } + +protected: + void compute_face(Facet_const_handle fh) + { + CGAL::Color c=m_fcolor.run(t2, fh); + face_begin(c); + + add_point_in_face(fh->vertex(0)->point()); + add_point_in_face(fh->vertex(1)->point()); + add_point_in_face(fh->vertex(2)->point()); + + face_end(); + } + + void compute_edge(Edge_const_handle eh) + { + add_segment(eh->first->vertex(eh->first->cw(eh->second))->point(), + eh->first->vertex(eh->first->ccw(eh->second))->point()); + } + + void compute_vertex(Vertex_const_handle vh) + { add_point(vh->point()); } + + void compute_elements() + { + clear(); + + if (!m_nofaces) + { + for (typename T2::Finite_faces_iterator it=t2.finite_faces_begin(); + it!=t2.finite_faces_end(); ++it) + { compute_face(it); } + } + + for (typename T2::Finite_edges_iterator it=t2.finite_edges_begin(); + it!=t2.finite_edges_end(); ++it) + { compute_edge(it); } + + for (typename T2::Finite_vertices_iterator it=t2.finite_vertices_begin(); + it!=t2.finite_vertices_end(); ++it) + { compute_vertex(it); } + } + + virtual void keyPressEvent(QKeyEvent *e) + { + // Test key pressed: + // const ::Qt::KeyboardModifiers modifiers = e->modifiers(); + // if ((e->key()==Qt::Key_PageUp) && (modifiers==Qt::NoButton)) { ... } + + // Call: * compute_elements() if the model changed, followed by + // * redraw() if some viewing parameters changed that implies some + // modifications of the buffers + // (eg. type of normal, color/mono) + // * update() just to update the drawing + + // Call the base method to process others/classicals key + Base::keyPressEvent(e); + } + +protected: + const T2& t2; + bool m_nofaces; + const ColorFunctor& m_fcolor; +}; + +template +void draw(const T2& at2, + const char* title, + bool nofill, + const ColorFunctor& fcolor) +{ +#if defined(CGAL_TEST_SUITE) + bool cgal_test_suite=true; +#else + bool cgal_test_suite=false; +#endif + + if (!cgal_test_suite) + { + int argc=1; + const char* argv[2]={"t2_viewer","\0"}; + QApplication app(argc,const_cast(argv)); + SimpleTriangulation2ViewerQt mainwindow(app.activeWindow(), + at2, + title, + nofill, + fcolor); + mainwindow.show(); + app.exec(); + } +} + +template +void draw(const T2& at2, const char* title, bool nofill) +{ + DefaultColorFunctorT2 c; + draw(at2, title, nofill, c); +} + +template +void draw(const T2& at2, const char* title) +{ draw(at2, title, false); } + +template +void draw(const T2& at2) +{ draw(at2, "Basic T2 Viewer"); } + +} // End namespace CGAL + +#endif // CGAL_USE_BASIC_VIEWER + +#endif // CGAL_DRAW_T2_H diff --git a/Triangulation_2/include/CGAL/internal/Triangulation_2_projection_traits_base_3.h b/Triangulation_2/include/CGAL/internal/Triangulation_2_projection_traits_base_3.h index f0b8b747403..00937af94ef 100644 --- a/Triangulation_2/include/CGAL/internal/Triangulation_2_projection_traits_base_3.h +++ b/Triangulation_2/include/CGAL/internal/Triangulation_2_projection_traits_base_3.h @@ -380,6 +380,7 @@ public: typedef typename K::Construct_circumcenter_3 Construct_circumcenter_2; typedef typename K::Compute_area_3 Compute_area_2; + typedef typename K::Construct_bbox_3 Construct_bbox_2; Less_x_2 less_x_2_object() const @@ -466,6 +467,9 @@ public: {return Compute_area_2();} + Construct_bbox_2 construct_bbox_2_object() const + {return Construct_bbox_2();} + // Special functor, not in the Kernel concept class Projection_to_plan { diff --git a/Triangulation_2/package_info/Triangulation_2/dependencies b/Triangulation_2/package_info/Triangulation_2/dependencies index b28aeef4d20..90dd0267b28 100644 --- a/Triangulation_2/package_info/Triangulation_2/dependencies +++ b/Triangulation_2/package_info/Triangulation_2/dependencies @@ -7,6 +7,7 @@ Distance_2 Distance_3 Filtered_kernel Geomview +GraphicsView Hash_map Homogeneous_kernel Installation diff --git a/Triangulation_3/doc/Triangulation_3/CGAL/draw_triangulation_3.h b/Triangulation_3/doc/Triangulation_3/CGAL/draw_triangulation_3.h new file mode 100644 index 00000000000..b7704903210 --- /dev/null +++ b/Triangulation_3/doc/Triangulation_3/CGAL/draw_triangulation_3.h @@ -0,0 +1,15 @@ +namespace CGAL { + +/*! +\ingroup PkgDrawTriangulation3 + +Open a new window and draw `at3`, a model of the `TriangulationDataStructure_3` concept. The function is blocking, that is the program continues as soon as the user closes the window. This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time. +\tparam T3 a model of the `TriangulationDataStructure_3` concept. +\param at3 the triangulation to draw. + +*/ +template +void draw(const T3& at3); + +} /* namespace CGAL */ + diff --git a/Triangulation_3/doc/Triangulation_3/PackageDescription.txt b/Triangulation_3/doc/Triangulation_3/PackageDescription.txt index 5af6493c805..11a1a0fe6a6 100644 --- a/Triangulation_3/doc/Triangulation_3/PackageDescription.txt +++ b/Triangulation_3/doc/Triangulation_3/PackageDescription.txt @@ -13,6 +13,13 @@ /// \defgroup PkgTriangulation3VertexCellClasses Vertex and Cell Classes /// \ingroup PkgTriangulation3 +/*! Draw. + \code + #include + \endcode +*/ +/// \defgroup PkgDrawTriangulation3 Draw a Triangulation 3 +/// \ingroup PkgTriangulation3 /*! \addtogroup PkgTriangulation3 @@ -111,6 +118,8 @@ is opposite to the vertex with the same index. See - `CGAL::Triangulation_3::Locate_type` +### Draw a Triangulation 3 ### +- `CGAL::draw` */ diff --git a/Triangulation_3/doc/Triangulation_3/Triangulation_3.txt b/Triangulation_3/doc/Triangulation_3/Triangulation_3.txt index 481610b3806..4d9385e07c8 100644 --- a/Triangulation_3/doc/Triangulation_3/Triangulation_3.txt +++ b/Triangulation_3/doc/Triangulation_3/Triangulation_3.txt @@ -535,6 +535,20 @@ removal of the first 100,000 vertices. \cgalExample{Triangulation_3/parallel_insertion_and_removal_in_regular_3.cpp} +\subsection Triangulation3Draw Draw a 3D Triangulation +\anchor ssecDrawT3 + +A 3D triangulation can be visualized by calling the `CGAL::draw()` function as shown in the following example. This function opens a new window showing the given 3D triangulation. The function is blocking, that is the program continues as soon as the user closes the window. + +\cgalExample{Triangulation_3/draw_triangulation_3.cpp} + +This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time. + +\cgalFigureBegin{fig_draw_triangulation_3,draw_triangulation_3.png} +Result of the run of the draw_triangulation_3 program. A window shows the 3D triangulation and allows to navigate through the 3D scene. +\cgalFigureEnd + + \section Triangulation3seccomplexity Complexity and Performance In 3D, the worst case complexity of a triangulation is quadratic in the number diff --git a/Triangulation_3/doc/Triangulation_3/examples.txt b/Triangulation_3/doc/Triangulation_3/examples.txt index 78ba6d23c9a..1a34261199c 100644 --- a/Triangulation_3/doc/Triangulation_3/examples.txt +++ b/Triangulation_3/doc/Triangulation_3/examples.txt @@ -13,4 +13,5 @@ \example Triangulation_3/copy_triangulation_3.cpp \example Triangulation_3/parallel_insertion_in_delaunay_3.cpp \example Triangulation_3/parallel_insertion_and_removal_in_regular_3.cpp +\example Triangulation_3/draw_triangulation_3.cpp */ diff --git a/Triangulation_3/doc/Triangulation_3/fig/draw_triangulation_3.png b/Triangulation_3/doc/Triangulation_3/fig/draw_triangulation_3.png new file mode 100644 index 00000000000..486aab9df08 Binary files /dev/null and b/Triangulation_3/doc/Triangulation_3/fig/draw_triangulation_3.png differ diff --git a/Triangulation_3/examples/Triangulation_3/CMakeLists.txt b/Triangulation_3/examples/Triangulation_3/CMakeLists.txt index c9673ba28b7..c13b8b4bbe0 100644 --- a/Triangulation_3/examples/Triangulation_3/CMakeLists.txt +++ b/Triangulation_3/examples/Triangulation_3/CMakeLists.txt @@ -2,8 +2,16 @@ project( Triangulation_3_Examples ) cmake_minimum_required(VERSION 2.8.12) +if(NOT POLICY CMP0070 AND POLICY CMP0053) + # Only set CMP0053 to OLD with CMake<3.10, otherwise there is a warning. + cmake_policy(SET CMP0053 OLD) +endif() -find_package(CGAL QUIET) +find_package(CGAL COMPONENTS Qt5) + +if(CGAL_Qt5_FOUND) + add_definitions(-DCGAL_USE_BASIC_VIEWER -DQT_NO_KEYWORDS) +endif() if ( CGAL_FOUND ) create_single_source_cgal_program( "adding_handles_3.cpp" ) @@ -20,19 +28,9 @@ if ( CGAL_FOUND ) create_single_source_cgal_program( "simple_triangulation_3.cpp" ) create_single_source_cgal_program( "simplex.cpp" ) - find_package( TBB QUIET ) - - if( TBB_FOUND ) - include( CGAL_target_use_TBB ) - - create_single_source_cgal_program( "parallel_insertion_and_removal_in_regular_3.cpp" ) - create_single_source_cgal_program( "parallel_insertion_in_delaunay_3.cpp" ) - create_single_source_cgal_program( "sequential_parallel.cpp" ) - CGAL_target_use_TBB( parallel_insertion_and_removal_in_regular_3 ) - CGAL_target_use_TBB( parallel_insertion_in_delaunay_3 ) - CGAL_target_use_TBB( sequential_parallel ) - else() - message(STATUS "NOTICE: a few examples require TBB and will not be compiled.") + create_single_source_cgal_program("draw_triangulation_3.cpp") + if(CGAL_Qt5_FOUND) + target_link_libraries(draw_triangulation_3 PUBLIC CGAL::CGAL_Qt5) endif() else() diff --git a/Triangulation_3/examples/Triangulation_3/draw_triangulation_3.cpp b/Triangulation_3/examples/Triangulation_3/draw_triangulation_3.cpp new file mode 100644 index 00000000000..3806854f938 --- /dev/null +++ b/Triangulation_3/examples/Triangulation_3/draw_triangulation_3.cpp @@ -0,0 +1,21 @@ +#include +#include +#include +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef CGAL::Delaunay_triangulation_3 DT3; +typedef CGAL::Creator_uniform_3 Creator; + +int main() +{ + std::vector points; + CGAL::Random_points_in_sphere_3 g(1.0); + CGAL::cpp11::copy_n(g, 50, std::back_inserter(points)); + + DT3 dt3(points.begin(), points.end()); + + CGAL::draw(dt3); + + return EXIT_SUCCESS; +} diff --git a/Triangulation_3/include/CGAL/Regular_triangulation_3.h b/Triangulation_3/include/CGAL/Regular_triangulation_3.h index d3f440ad362..8692371ebb2 100644 --- a/Triangulation_3/include/CGAL/Regular_triangulation_3.h +++ b/Triangulation_3/include/CGAL/Regular_triangulation_3.h @@ -426,7 +426,8 @@ namespace CGAL { template struct Index_to_Bare_point { - const Bare_point& operator()(const std::size_t& i) const + typename boost::result_of::type + operator()(const std::size_t& i) const { return cp(c[i]); } diff --git a/Triangulation_3/include/CGAL/draw_triangulation_3.h b/Triangulation_3/include/CGAL/draw_triangulation_3.h new file mode 100644 index 00000000000..709bd15924f --- /dev/null +++ b/Triangulation_3/include/CGAL/draw_triangulation_3.h @@ -0,0 +1,192 @@ +// Copyright (c) 2018 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0+ +// +// Author(s) : Guillaume Damiand + +#ifndef CGAL_DRAW_T3_H +#define CGAL_DRAW_T3_H + +#include +#include + +#ifdef CGAL_USE_BASIC_VIEWER + +#include + +namespace CGAL +{ + +// Default color functor; user can change it to have its own face color +struct DefaultColorFunctorT3 +{ + template + static CGAL::Color run(const T3&, + const typename T3::Finite_facets_iterator* fh) + { + if (fh==NULL) // use to get the mono color + return CGAL::Color(100, 125, 200); // R G B between 0-255 + + CGAL::Random random((unsigned int)((std::size_t)(&*((*fh)->first))+ + (std::size_t)((*fh)->second))); + return get_random_color(random); + } +}; + +// Viewer class for T3 +template +class SimpleTriangulation3ViewerQt : public Basic_viewer_qt +{ + typedef Basic_viewer_qt Base; + typedef typename T3::Vertex_handle Vertex_const_handle; + typedef typename T3::Finite_edges_iterator Edge_const_handle; + typedef typename T3::Finite_facets_iterator Facet_const_handle; + typedef typename T3::Cell_handle Cell_handle; + typedef typename T3::Point Point; + +public: + /// Construct the viewer. + /// @param at3 the t3 to view + /// @param title the title of the window + /// @param anofaces if true, do not draw faces (faces are not computed; this can be + /// usefull for very big object where this time could be long) + SimpleTriangulation3ViewerQt(QWidget* parent, + const T3& at3, + const char* title="Basic T3 Viewer", + bool anofaces=false, + const ColorFunctor& fcolor=ColorFunctor()) : + // First draw: vertices; edges, faces; multi-color; no inverse normal + Base(parent, title, true, true, true, false, false), + t3(at3), + m_nofaces(anofaces), + m_fcolor(fcolor) + { + compute_elements(); + } + +protected: + void compute_face(Facet_const_handle fh) + { + CGAL::Color c=m_fcolor.run(t3, &fh); + face_begin(c); + + add_point_in_face(fh->first->vertex((fh->second+1)%4)->point()); + add_point_in_face(fh->first->vertex((fh->second+2)%4)->point()); + add_point_in_face(fh->first->vertex((fh->second+3)%4)->point()); + + face_end(); + } + + void compute_edge(Edge_const_handle eh) + { + add_segment(eh->first->vertex(eh->second)->point(), + eh->first->vertex(eh->third)->point()); + } + + void compute_vertex(Vertex_const_handle vh) + { add_point(vh->point()); } + + void compute_elements() + { + clear(); + + if (!m_nofaces) + { + for (typename T3::Finite_facets_iterator it=t3.finite_facets_begin(); + it!=t3.finite_facets_end(); ++it) + { compute_face(it); } + } + + for (typename T3::Finite_edges_iterator it=t3.finite_edges_begin(); + it!=t3.finite_edges_end(); ++it) + { compute_edge(it); } + + for (typename T3::Finite_vertices_iterator it=t3.finite_vertices_begin(); + it!=t3.finite_vertices_end(); ++it) + { compute_vertex(it); } + } + + virtual void keyPressEvent(QKeyEvent *e) + { + // Test key pressed: + // const ::Qt::KeyboardModifiers modifiers = e->modifiers(); + // if ((e->key()==Qt::Key_PageUp) && (modifiers==Qt::NoButton)) { ... } + + // Call: * compute_elements() if the model changed, followed by + // * redraw() if some viewing parameters changed that implies some + // modifications of the buffers + // (eg. type of normal, color/mono) + // * update() just to update the drawing + + // Call the base method to process others/classicals key + Base::keyPressEvent(e); + } + +protected: + const T3& t3; + bool m_nofaces; + const ColorFunctor& m_fcolor; +}; + +template +void draw(const T3& at3, + const char* title, + bool nofill, + const ColorFunctor& fcolor) +{ + +#if defined(CGAL_TEST_SUITE) + bool cgal_test_suite=true; +#else + bool cgal_test_suite=false; +#endif + + if (!cgal_test_suite) + { + int argc=1; + const char* argv[2]={"t3_viewer","\0"}; + QApplication app(argc,const_cast(argv)); + SimpleTriangulation3ViewerQt mainwindow(app.activeWindow(), + at3, + title, + nofill, + fcolor); + mainwindow.show(); + app.exec(); + } +} + +template +void draw(const T3& at3, const char* title, bool nofill) +{ + DefaultColorFunctorT3 c; + draw(at3, title, nofill, c); +} + +template +void draw(const T3& at3, const char* title) +{ draw(at3, title, false); } + +template +void draw(const T3& at3) +{ draw(at3, "Basic T3 Viewer"); } + +} // End namespace CGAL + +#endif // CGAL_USE_BASIC_VIEWER + +#endif // CGAL_DRAW_T3_H diff --git a/Triangulation_3/package_info/Triangulation_3/dependencies b/Triangulation_3/package_info/Triangulation_3/dependencies index c07b218e4eb..df63288cf1d 100644 --- a/Triangulation_3/package_info/Triangulation_3/dependencies +++ b/Triangulation_3/package_info/Triangulation_3/dependencies @@ -7,6 +7,7 @@ Distance_2 Distance_3 Filtered_kernel Geomview +GraphicsView Hash_map Homogeneous_kernel Installation diff --git a/Triangulation_3/test/Triangulation_3/test_regular_insert_range_with_info.cpp b/Triangulation_3/test/Triangulation_3/test_regular_insert_range_with_info.cpp index 31a0bb1d85d..22577d1f1e2 100644 --- a/Triangulation_3/test/Triangulation_3/test_regular_insert_range_with_info.cpp +++ b/Triangulation_3/test/Triangulation_3/test_regular_insert_range_with_info.cpp @@ -1,184 +1,226 @@ - #include "test_dependencies.h" + #include +#include + #include #include + +#include + +#include +#include #include -typedef CGAL::Exact_predicates_inexact_constructions_kernel K; -typedef K Traits; -typedef CGAL::Regular_triangulation_vertex_base_3 Vbb; -typedef CGAL::Triangulation_vertex_base_with_info_3 Vb; -typedef CGAL::Triangulation_data_structure_3 > Tds; -typedef CGAL::Regular_triangulation_3 Regular; -typedef K::Weighted_point_3 Weighted_point; -typedef K::Point_3 Point; +typedef CGAL::Exact_predicates_exact_constructions_kernel K; + +template +struct Tester +{ + typedef K Traits; + typedef CGAL::Regular_triangulation_vertex_base_3 Vbb; + typedef CGAL::Triangulation_vertex_base_with_info_3 Vb; + typedef CGAL::Regular_triangulation_cell_base_3 Cb; + typedef CGAL::Triangulation_data_structure_3 Tds; + + typedef CGAL::Regular_triangulation_3 RT; + typedef typename RT::Bare_point Bare_point; + typedef typename RT::Weighted_point Weighted_point; #ifdef CGAL_LINKED_WITH_TBB -typedef CGAL::Spatial_lock_grid_3 Lock_ds; -typedef CGAL::Triangulation_data_structure_3, CGAL::Parallel_tag> Tds_parallel; -typedef CGAL::Regular_triangulation_3 RT_parallel; + typedef CGAL::Spatial_lock_grid_3 Lock_ds; + typedef CGAL::Triangulation_data_structure_3 Tds_parallel; + typedef CGAL::Regular_triangulation_3 RT_parallel; #endif -template -void test_iterator_on_pair(){ - typedef std::vector< std::pair > Container; - typedef typename boost::mpl::if_< boost::mpl::bool_,boost::add_const::type,Container >::type Cast_type; - Container points; - - - points.push_back( std::make_pair( Weighted_point(Point(0,0,0),1),0 ) ); - points.push_back( std::make_pair( Weighted_point(Point(1,0,0),2),1 ) ); - points.push_back( std::make_pair( Weighted_point(Point(0,1,0),3),2 ) ); - points.push_back( std::make_pair( Weighted_point(Point(0,0,1),4),3 ) ); - points.push_back( std::make_pair( Weighted_point(Point(2,2,2),5),4 ) ); - points.push_back( std::make_pair( Weighted_point(Point(-1,0,1),6),5 ) ); - - - Regular R( static_cast(points).begin(),static_cast(points).end() ); - - assert( R.number_of_vertices() == 6 ); - - // check that the info was correctly set. - Regular::Finite_vertices_iterator vit; - for (vit = R.finite_vertices_begin(); vit != R.finite_vertices_end(); ++vit) - assert(points[vit->info()].first == vit->point()); - -#ifdef CGAL_LINKED_WITH_TBB + template + void test_iterator_on_pair() const { - // Construct the locking data-structure, using the bounding-box of the points - typename RT_parallel::Lock_data_structure locking_ds( - CGAL::Bbox_3(-1., 0., 0., 2, 2, 2), 50); - // Contruct the triangulation in parallel - RT_parallel R( - static_cast(points).begin(), - static_cast(points).end(), - &locking_ds); + typedef std::vector > Container; + typedef typename boost::mpl::if_, + typename boost::add_const::type, + Container>::type Cast_type; - assert(R.number_of_vertices() == 6); + Container points; + points.push_back(std::make_pair(Weighted_point(Bare_point(0.160385, 0.599679, 0.374932), -0.118572), 0)); + points.push_back(std::make_pair(Weighted_point(Bare_point(0.17093, 0.82228, 0.51697), -0.0226131), 1)); + points.push_back(std::make_pair(Weighted_point(Bare_point(0.15773, 0.66293, 0.458541), -0.0753074), 2)); + points.push_back(std::make_pair(Weighted_point(Bare_point(0.388417, 0.685989, 0.401349), -0.0616195), 3)); + points.push_back(std::make_pair(Weighted_point(Bare_point(0.380061, 0.852124, 0.538984), -0.0145638), 4)); + points.push_back(std::make_pair(Weighted_point(Bare_point(0.0402467, 0.519724, 0.417205), -0.0698374), 5)); + points.push_back(std::make_pair(Weighted_point(Bare_point(0.0270472, 0.360373, 0.358776), -0.0109982), 6)); + points.push_back(std::make_pair(Weighted_point(Bare_point(0.257734, 0.383432, 0.301584), -0.0601458), 7)); + points.push_back(std::make_pair(Weighted_point(Bare_point(0.142091, 0.643406, 0.61943), -0.251061), 8)); - // check that the info was correctly set. - RT_parallel::Finite_vertices_iterator vit; - for (vit = R.finite_vertices_begin(); vit != R.finite_vertices_end(); ++vit) - assert(points[vit->info()].first == vit->point()); - } + RT R(static_cast(points).begin(), static_cast(points).end()); + assert(R.number_of_vertices() == 9); + + R.clear(); + R.insert(static_cast(points).begin(), static_cast(points).end()); + assert(R.number_of_vertices() == 9); + + // check that the info was correctly set. + typename RT::Finite_vertices_iterator vit; + for(vit = R.finite_vertices_begin(); vit != R.finite_vertices_end(); ++vit) + assert(points[vit->info()].first == vit->point()); + + #ifdef CGAL_LINKED_WITH_TBB + { + // Construct the locking data-structure, using the bounding-box of the points + typename RT_parallel::Lock_data_structure locking_ds(CGAL::Bbox_3(-1., 0., 0., 2, 2, 2), 50); + + // Contruct the triangulation in parallel + RT_parallel R(static_cast(points).begin(), static_cast(points).end(), &locking_ds); + assert(R.number_of_vertices() == 9); + + R.clear(); + R.insert(static_cast(points).begin(), static_cast(points).end(), &locking_ds); + assert(R.number_of_vertices() == 9); + + // check that the info was correctly set. + typename RT_parallel::Finite_vertices_iterator vit; + for(vit = R.finite_vertices_begin(); vit != R.finite_vertices_end(); ++vit) { + assert(points[vit->info()].first == vit->point()); + } + } #endif -} + } -void toto(int){} - -template -void test_zip_iterator(){ - typedef std::vector< Weighted_point > Container; - Container points; - typedef typename boost::mpl::if_< boost::mpl::bool_,boost::add_const::type,Container >::type Cast_type; - - points.push_back( Weighted_point(Point(0,0,0),1) ); - points.push_back( Weighted_point(Point(1,0,0),2) ); - points.push_back( Weighted_point(Point(0,1,0),3) ); - points.push_back( Weighted_point(Point(0,0,1),4) ); - points.push_back( Weighted_point(Point(2,2,2),5) ); - points.push_back( Weighted_point(Point(-1,0,1),6) ); - - std::vector indices; - indices.push_back(0); - indices.push_back(1); - indices.push_back(2); - indices.push_back(3); - indices.push_back(4); - indices.push_back(5); - - Regular R( boost::make_zip_iterator(boost::make_tuple( static_cast(points).begin(),indices.begin() )), - boost::make_zip_iterator(boost::make_tuple( static_cast(points).end(),indices.end() ) ) ); - assert( R.number_of_vertices() == 6 ); - - // check that the info was correctly set. - Regular::Finite_vertices_iterator vit; - for (vit = R.finite_vertices_begin(); vit != R.finite_vertices_end(); ++vit) - assert( points[ vit->info() ] == vit->point() ); - -#ifdef CGAL_LINKED_WITH_TBB + template + void test_zip_iterator() const { - // Construct the locking data-structure, using the bounding-box of the points - typename RT_parallel::Lock_data_structure locking_ds( - CGAL::Bbox_3(-1., 0., 0., 2, 2, 2), 50); - // Contruct the triangulation in parallel - RT_parallel R( - boost::make_zip_iterator(boost::make_tuple(static_cast(points).begin(), indices.begin())), - boost::make_zip_iterator(boost::make_tuple(static_cast(points).end(), indices.end())), - &locking_ds); + typedef std::vector Container; + typedef typename boost::mpl::if_, + typename boost::add_const::type, + Container >::type Cast_type; - assert(R.number_of_vertices() == 6); + Container points; + points.push_back(Weighted_point(Bare_point(0,0,0),1)); + points.push_back(Weighted_point(Bare_point(1,0,0),2)); + points.push_back(Weighted_point(Bare_point(0,1,0),3)); + points.push_back(Weighted_point(Bare_point(0,0,1),4)); + points.push_back(Weighted_point(Bare_point(2,2,2),5)); + points.push_back(Weighted_point(Bare_point(-1,0,1),6)); - // check that the info was correctly set. - RT_parallel::Finite_vertices_iterator vit; - for (vit = R.finite_vertices_begin(); vit != R.finite_vertices_end(); ++vit) - assert(points[vit->info()] == vit->point()); - } + std::vector indices; + indices.push_back(0); + indices.push_back(1); + indices.push_back(2); + indices.push_back(3); + indices.push_back(4); + indices.push_back(5); + + RT R(boost::make_zip_iterator(boost::make_tuple(static_cast(points).begin(), indices.begin())), + boost::make_zip_iterator(boost::make_tuple(static_cast(points).end(), indices.end()))); + assert(R.number_of_vertices() == 6); + + // check that the info was correctly set. + typename RT::Finite_vertices_iterator vit; + for(vit = R.finite_vertices_begin(); vit != R.finite_vertices_end(); ++vit) + assert(points[ vit->info() ] == vit->point()); + +#ifdef CGAL_LINKED_WITH_TBB + { + // Construct the locking data-structure, using the bounding-box of the points + typename RT_parallel::Lock_data_structure locking_ds(CGAL::Bbox_3(-1., 0., 0., 2, 2, 2), 50); + + // Contruct the triangulation in parallel + RT_parallel R(boost::make_zip_iterator(boost::make_tuple(static_cast(points).begin(), indices.begin())), + boost::make_zip_iterator(boost::make_tuple(static_cast(points).end(), indices.end())), + &locking_ds); + assert(R.number_of_vertices() == 6); + + // check that the info was correctly set. + typename RT_parallel::Finite_vertices_iterator vit; + for(vit = R.finite_vertices_begin(); vit != R.finite_vertices_end(); ++vit) { + assert(points[vit->info()] == vit->point()); + } + } #endif -} + } -struct Auto_count : public CGAL::unary_function >{ - mutable unsigned i; - Auto_count() : i(0){} - std::pair operator()(const Weighted_point& p) const { - return std::make_pair(p,i++); + struct Auto_count + : public CGAL::unary_function > + { + mutable unsigned i; + Auto_count() : i(0){} + std::pair operator()(const Weighted_point& p) const + { + return std::make_pair(p,i++); + } + }; + + template + void test_transform_iterator() const + { + typedef std::vector< Weighted_point > Container; + typedef typename boost::mpl::if_, + typename boost::add_const::type, + Container >::type Cast_type; + + Container points; + points.push_back(Weighted_point(Bare_point(0,0,0),1)); + points.push_back(Weighted_point(Bare_point(1,0,0),2)); + points.push_back(Weighted_point(Bare_point(0,1,0),3)); + points.push_back(Weighted_point(Bare_point(0,0,1),4)); + points.push_back(Weighted_point(Bare_point(2,2,2),5)); + points.push_back(Weighted_point(Bare_point(-1,0,1),6)); + + RT R(boost::make_transform_iterator(static_cast(points).begin(), Auto_count()), + boost::make_transform_iterator(static_cast(points).end(), Auto_count())); + + assert(R.number_of_vertices() == 6); + + // check that the info was correctly set. + typename RT::Finite_vertices_iterator vit; + for(vit = R.finite_vertices_begin(); vit != R.finite_vertices_end(); ++vit) + assert(points[ vit->info() ] == vit->point()); + +#ifdef CGAL_LINKED_WITH_TBB + { + // Construct the locking data-structure, using the bounding-box of the points + typename RT_parallel::Lock_data_structure locking_ds(CGAL::Bbox_3(-1., 0., 0., 2, 2, 2), 50); + + // Contruct the triangulation in parallel + RT_parallel R(boost::make_transform_iterator(static_cast(points).begin(), Auto_count()), + boost::make_transform_iterator(static_cast(points).end(), Auto_count()), + &locking_ds); + assert(R.number_of_vertices() == 6); + + // check that the info was correctly set. + typename RT_parallel::Finite_vertices_iterator vit; + for(vit = R.finite_vertices_begin(); vit != R.finite_vertices_end(); ++vit) { + assert(points[vit->info()] == vit->point()); + } + } +#endif + } + + void operator()() const + { + test_iterator_on_pair(); + test_iterator_on_pair(); + test_zip_iterator(); + test_zip_iterator(); + test_transform_iterator(); + test_transform_iterator(); } }; -template -void test_transform_iterator(){ - typedef std::vector< Weighted_point > Container; - Container points; - typedef typename boost::mpl::if_< boost::mpl::bool_,boost::add_const::type,Container >::type Cast_type; - - points.push_back( Weighted_point(Point(0,0,0),1) ); - points.push_back( Weighted_point(Point(1,0,0),2) ); - points.push_back( Weighted_point(Point(0,1,0),3) ); - points.push_back( Weighted_point(Point(0,0,1),4) ); - points.push_back( Weighted_point(Point(2,2,2),5) ); - points.push_back( Weighted_point(Point(-1,0,1),6) ); - - Regular R( boost::make_transform_iterator(static_cast(points).begin(),Auto_count()), - boost::make_transform_iterator(static_cast(points).end(), Auto_count() ) ); - - assert( R.number_of_vertices() == 6 ); - - // check that the info was correctly set. - Regular::Finite_vertices_iterator vit; - for (vit = R.finite_vertices_begin(); vit != R.finite_vertices_end(); ++vit) - assert( points[ vit->info() ] == vit->point() ); - -#ifdef CGAL_LINKED_WITH_TBB - { - // Construct the locking data-structure, using the bounding-box of the points - typename RT_parallel::Lock_data_structure locking_ds( - CGAL::Bbox_3(-1., 0., 0., 2, 2, 2), 50); - // Contruct the triangulation in parallel - RT_parallel R( - boost::make_transform_iterator(static_cast(points).begin(), Auto_count()), - boost::make_transform_iterator(static_cast(points).end(), Auto_count()), - &locking_ds); - - assert(R.number_of_vertices() == 6); - - // check that the info was correctly set. - RT_parallel::Finite_vertices_iterator vit; - for (vit = R.finite_vertices_begin(); vit != R.finite_vertices_end(); ++vit) - assert(points[vit->info()] == vit->point()); - } -#endif -} - int main() { - test_iterator_on_pair(); - test_iterator_on_pair(); - test_zip_iterator(); - test_zip_iterator(); - test_transform_iterator(); - test_transform_iterator(); - return 0; -} + typedef CGAL::Exact_predicates_inexact_constructions_kernel Epick; + typedef CGAL::Exact_predicates_exact_constructions_kernel Epeck; + std::cerr << "TESTING WITH Exact_predicates_inexact_constructions_kernel...\n"; + Tester test_epic; + test_epic(); + + std::cerr << "TESTING WITH Exact_predicates_exact_constructions_kernel...\n"; + Tester test_epec; + test_epec(); + + return EXIT_SUCCESS; +}