diff --git a/AABB_tree/demo/AABB_tree/Scene.cpp b/AABB_tree/demo/AABB_tree/Scene.cpp index 7a416bbde35..6303fb2140b 100644 --- a/AABB_tree/demo/AABB_tree/Scene.cpp +++ b/AABB_tree/demo/AABB_tree/Scene.cpp @@ -1297,7 +1297,7 @@ void Scene::refine_loop() return; } std::cout << "Loop subdivision..."; - CGAL::Subdivision_method_3::Loop_subdivision(*m_pPolyhedron, 1); + CGAL::Subdivision_method_3::Loop_subdivision(*m_pPolyhedron); std::cout << "done (" << m_pPolyhedron->size_of_facets() << " facets)" << std::endl; clear_internal_data(); diff --git a/AABB_tree/examples/AABB_tree/AABB_custom_indexed_triangle_set_array_example.cpp b/AABB_tree/examples/AABB_tree/AABB_custom_indexed_triangle_set_array_example.cpp index 8505b99ed49..87dfc24553f 100644 --- a/AABB_tree/examples/AABB_tree/AABB_custom_indexed_triangle_set_array_example.cpp +++ b/AABB_tree/examples/AABB_tree/AABB_custom_indexed_triangle_set_array_example.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include diff --git a/AABB_tree/include/CGAL/internal/AABB_tree/AABB_ray_intersection.h b/AABB_tree/include/CGAL/internal/AABB_tree/AABB_ray_intersection.h index c5c388d4304..ccebce05bb8 100644 --- a/AABB_tree/include/CGAL/internal/AABB_tree/AABB_ray_intersection.h +++ b/AABB_tree/include/CGAL/internal/AABB_tree/AABB_ray_intersection.h @@ -31,10 +31,18 @@ #include #include #if BOOST_VERSION >= 105000 -#include +# if defined(BOOST_MSVC) +# pragma warning(push) +# pragma warning(disable: 4996) +# endif +# include +# if defined(BOOST_MSVC) +# pragma warning(pop) +# endif #else -#include +# include #endif + #include namespace CGAL { diff --git a/Algebraic_kernel_d/doc/Algebraic_kernel_d/Algebraic_kernel_d.txt b/Algebraic_kernel_d/doc/Algebraic_kernel_d/Algebraic_kernel_d.txt index 52cdc3b4292..d6082d26967 100644 --- a/Algebraic_kernel_d/doc/Algebraic_kernel_d/Algebraic_kernel_d.txt +++ b/Algebraic_kernel_d/doc/Algebraic_kernel_d/Algebraic_kernel_d.txt @@ -325,27 +325,27 @@ efficiency. The following example illustrates the construction of `AlgebraicKernel_d_1::Algebraic_real_1` using `AlgebraicKernel_d_1::Construct_algebraic_real_1`: -\cgalExample{Algebraic_kernel_d/Construct_algebraic_real_1.cpp} +\cgalExample{Algebraic_kernel_d/Construct_algebraic_real_1.cpp} \subsection CGALAK1Solving Solving Univariate Polynomials The following example illustrates the construction of `AlgebraicKernel_d_1::Algebraic_real_1` -using `AlgebraicKernel_d_1::Solve_1`: \cgalExample{Algebraic_kernel_d/Solve_1.cpp} +using `AlgebraicKernel_d_1::Solve_1`: \cgalExample{Algebraic_kernel_d/Solve_1.cpp} \subsection CGALAK1EGCompare_1 Comparison and Approximation of Algebraic Real Numbers The following example illustrates the comparison of `AlgebraicKernel_d_1::Algebraic_real_1` numbers: -\cgalExample{Algebraic_kernel_d/Compare_1.cpp} +\cgalExample{Algebraic_kernel_d/Compare_1.cpp} \subsection CGALAK1EGIsolate_1 Isolation of Algebraic Real Numbers with respect to roots of other polynomials The following example illustrates the isolation of `AlgebraicKernel_d_1::Algebraic_real_1` numbers: -\cgalExample{Algebraic_kernel_d/Isolate_1.cpp} +\cgalExample{Algebraic_kernel_d/Isolate_1.cpp} \subsection CGALAK1EGSign_at_1 Interplay with Polynomials The following example illustrates the sign evaluation of `AlgebraicKernel_d_1::Algebraic_real_1` numbers in polynomials: -\cgalExample{Algebraic_kernel_d/Sign_at_1.cpp} +\cgalExample{Algebraic_kernel_d/Sign_at_1.cpp} \section Algebraic_kernel_dDesign Design and Implementation History diff --git a/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Curve_pair_analysis_2.h b/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Curve_pair_analysis_2.h index cc8ba6b58cb..8c338f83e35 100644 --- a/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Curve_pair_analysis_2.h +++ b/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Curve_pair_analysis_2.h @@ -1524,17 +1524,11 @@ compute_intermediate_values_and_slices() const { #if CGAL_ACK_DEBUG_FLAG CGAL_ACK_DEBUG_PRINT << "Prepare intermediate slices.." << std::flush; #endif + std::size_t size = event_x_coordinates().size()+1; this->ptr()->intermediate_values=std::vector(); this->ptr()->intermediate_slices=std::vector(); - - for(size_type i=0; - i<=static_cast(event_x_coordinates().size()); - i++) { - this->ptr()->intermediate_values.get().push_back(Lazy_bound()); - this->ptr()->intermediate_slices.get().push_back - (Lazy_status_line_CPA_1()); - } - + this->ptr()->intermediate_values.get().resize(size); + this->ptr()->intermediate_slices.get().resize(size); #if CGAL_ACK_DEBUG_FLAG CGAL_ACK_DEBUG_PRINT << "done" << std::endl; #endif diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/CMakeLists.txt b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/CMakeLists.txt index 31b49747cf8..449c2d25303 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/CMakeLists.txt +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/CMakeLists.txt @@ -8,6 +8,10 @@ if(NOT POLICY CMP0070 AND POLICY CMP0053) cmake_policy(SET CMP0053 OLD) endif() +if(POLICY CMP0071) + cmake_policy(SET CMP0071 NEW) +endif() + find_package(CGAL COMPONENTS Core Qt5 ) find_package( Qt5 QUIET COMPONENTS Gui Widgets) diff --git a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/Arrangement_on_surface_2.txt b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/Arrangement_on_surface_2.txt index 719b0deceed..dc4d957e931 100644 --- a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/Arrangement_on_surface_2.txt +++ b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/Arrangement_on_surface_2.txt @@ -2209,10 +2209,10 @@ representing line segments. A polyline can be constructed given one of the following inputs: -- A range of \a points, where two succeeding points in the +- A range of points, where two succeeding points in the range represent the endpoints of a segment of the polyline. -- A range of \a segments. Note that , if the types +- A range of segments. Note that , if the types `SubcurveTraits_2::Curve_2` and `SubcurveTraits_2::X_monotone_curve_2` are not the same, then when `Make_x_monotone_2` is invoked the segments that compose the polyline will be broken into \f$x\f$-monotone @@ -2681,7 +2681,7 @@ manner whenever possible. Thus, it resorts to exact computations only when the approximate computation fails to produce an unambiguous result. Note that most arrangement vertices are therefore associated with approximated points. You cannot access the coordinates of such points and obtain them as -algebraic numbers, and only access to the approximate coordinates in possible. +algebraic numbers, and only access to the approximate coordinates is possible. See the Reference Manual for the exact interface of the `Point_2`, `Curve_2` and `X_monotone_curve_2` defined by the traits class. diff --git a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_observer.h b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_observer.h index cc860dbf95b..38b372ad59d 100644 --- a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_observer.h +++ b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_observer.h @@ -167,7 +167,7 @@ virtual void before_detach (); issued immediately after the observer has been detached from its arrangement instance. */ -virtual void after_attach (); +virtual void after_detach (); /// @} diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_spherical_gaussian_map_3/Arr_polyhedral_sgm.h b/Arrangement_on_surface_2/include/CGAL/Arr_spherical_gaussian_map_3/Arr_polyhedral_sgm.h index b2be5687c10..8a57cd28808 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_spherical_gaussian_map_3/Arr_polyhedral_sgm.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_spherical_gaussian_map_3/Arr_polyhedral_sgm.h @@ -242,6 +242,11 @@ private: /*! Set the marked-face index */ void set_marked_facet_index(size_type id) {m_marked_facet_index = id;} + /*! Add vertices to the current facet. */ + template + void add_vertices_to_facet(Iterator begin, Iterator end, Builder& B) + { for (Iterator it = begin; it != end; ++it) B.add_vertex_to_facet(*it); } + /*! builds the polyhedron */ void operator()(HDS& hds) { @@ -262,11 +267,11 @@ private: for (CoordIndexIter it = m_indices_begin; it != m_indices_end; ++it) { Polyhedron_facet_handle fh = B.begin_facet(); if (counter == m_marked_facet_index) fh->set_marked(true); - //! \todo EF: when upgrading to C++11 change the type of the following - // iterator to auto. Better yet, use for (auto blah : foo). - for (std::vector::const_iterator iit = it->begin(); - iit != it->end(); ++iit) - B.add_vertex_to_facet(*iit); + //! \todo EF: when upgrading to C++11 enable the following code and + // remove add_vertices_to_facet(). + // for (const auto& facet : *it) B.add_vertex_to_facet(facet); + // B.end_facet(); + add_vertices_to_facet(it->begin(), it->end(), B); B.end_facet(); ++counter; } diff --git a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/cgal_test.cmake b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/cgal_test.cmake index 1baad5bed5f..fc61895ed77 100644 --- a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/cgal_test.cmake +++ b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/cgal_test.cmake @@ -197,7 +197,7 @@ function(run_test_alt name datafile) set(command ${name} ${datafile} ${ARGN}) string(MAKE_C_IDENTIFIER "${name} ${ARGV4} ${ARGV5}" test_name) add_test(NAME ${test_name} COMMAND ${command} - WORKING_DIRECTORY ${CGAL_CURRENT_SOURCE_DIR}) + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) set_property(TEST "${test_name}" APPEND PROPERTY DEPENDS "compilation_of__${name}") if(POLICY CMP0066) # CMake 3.7 or later diff --git a/BGL/doc/BGL/PackageDescription.txt b/BGL/doc/BGL/PackageDescription.txt index 6ba2f1ba2d6..d069c70ee55 100644 --- a/BGL/doc/BGL/PackageDescription.txt +++ b/BGL/doc/BGL/PackageDescription.txt @@ -708,6 +708,7 @@ user might encounter. ## I/O Functions ## - \link PkgBGLIOFct CGAL::read_off() \endlink - \link PkgBGLIOFct CGAL::write_off() \endlink +- \link PkgBGLIOFct CGAL::write_wrl() \endlink */ diff --git a/BGL/doc/BGL/fig/hexahedron.png b/BGL/doc/BGL/fig/hexahedron.png new file mode 100644 index 00000000000..34a4fb17085 Binary files /dev/null and b/BGL/doc/BGL/fig/hexahedron.png differ diff --git a/BGL/doc/BGL/fig/tetrahedron.png b/BGL/doc/BGL/fig/tetrahedron.png new file mode 100644 index 00000000000..b0cb6a42259 Binary files /dev/null and b/BGL/doc/BGL/fig/tetrahedron.png differ diff --git a/BGL/examples/BGL_surface_mesh/gwdwg.cpp b/BGL/examples/BGL_surface_mesh/gwdwg.cpp index b857d5a774d..07ed87cc639 100644 --- a/BGL/examples/BGL_surface_mesh/gwdwg.cpp +++ b/BGL/examples/BGL_surface_mesh/gwdwg.cpp @@ -25,10 +25,10 @@ int main() Point_3(1,-1,-1), Point_3(1,1,-1), Point_3(-1,1,-1), + Point_3(-1,1,1), Point_3(-1,-1,1), Point_3(1,-1,1), Point_3(1,1,1), - Point_3(-1,1,1), sm ); @@ -45,10 +45,10 @@ int main() Point_3(0.5,-0.5,-0.5), Point_3(0.5,0.5,-0.5), Point_3(-0.5,0.5,-0.5), + Point_3(-0.5,0.5,0.5), Point_3(-0.5,-0.5,0.5), Point_3(0.5,-0.5,0.5), Point_3(0.5,0.5,0.5), - Point_3(-0.5,0.5,0.5), poly ); pvertex_descriptor pvd = * vertices(pmesh).first; diff --git a/BGL/include/CGAL/boost/graph/Euler_operations.h b/BGL/include/CGAL/boost/graph/Euler_operations.h index 874141e8776..eb63b9dc6df 100644 --- a/BGL/include/CGAL/boost/graph/Euler_operations.h +++ b/BGL/include/CGAL/boost/graph/Euler_operations.h @@ -585,8 +585,16 @@ add_face(const VertexRange& vr, Graph& g) std::vector vertices(vr.begin(), vr.end()); // quick and dirty copy unsigned int n = (unsigned int)vertices.size(); + //check that every vertex is unique + std::sort(vertices.begin(), vertices.end()); + if(std::adjacent_find(vertices.begin(), vertices.end()) != vertices.end()){ + return boost::graph_traits::null_face(); + } + std::copy(vr.begin(), vr.end(), vertices.begin()); // don't allow degenerated faces - CGAL_assertion(n > 2); + if(n <= 2){ + return boost::graph_traits::null_face(); + } std::vector halfedges(n); std::vector is_new(n); diff --git a/BGL/include/CGAL/boost/graph/Face_filtered_graph.h b/BGL/include/CGAL/boost/graph/Face_filtered_graph.h index 472583030bd..9a869d8a250 100644 --- a/BGL/include/CGAL/boost/graph/Face_filtered_graph.h +++ b/BGL/include/CGAL/boost/graph/Face_filtered_graph.h @@ -129,7 +129,7 @@ struct Face_filtered_graph * a property map containing an index for each face initialized from 0 to `num_vertices(graph)` * \cgalParamEnd * \cgalParamBegin{vertex_index_map} - * a property map containing an index for each vertex initialized 0 to `num_vertices(vertex)` + * a property map containing an index for each vertex initialized 0 to `num_vertices(graph)` * \cgalParamEnd * \cgalParamBegin{halfedge_index_map} * a property map containing an index for each halfedge initialized 0 to `num_halfedges(graph)` @@ -189,7 +189,7 @@ struct Face_filtered_graph * a property map containing an index for each face initialized from 0 to `num_vertices(graph)` * \cgalParamEnd * \cgalParamBegin{vertex_index_map} - * a property map containing an index for each vertex initialized 0 to `num_vertices(vertex)` + * a property map containing an index for each vertex initialized 0 to `num_vertices(graph)` * \cgalParamEnd * \cgalParamBegin{halfedge_index_map} * a property map containing an index for each halfedge initialized 0 to `num_halfedges(graph)` @@ -236,7 +236,7 @@ struct Face_filtered_graph * a property map containing an index for each face initialized from 0 to `num_vertices(graph)` * \cgalParamEnd * \cgalParamBegin{vertex_index_map} - * a property map containing an index for each vertex initialized 0 to `num_vertices(vertex)` + * a property map containing an index for each vertex initialized 0 to `num_vertices(graph)` * \cgalParamEnd * \cgalParamBegin{halfedge_index_map} * a property map containing an index for each halfedge initialized 0 to `num_halfedges(graph)` diff --git a/BGL/include/CGAL/boost/graph/METIS/partition_dual_graph.h b/BGL/include/CGAL/boost/graph/METIS/partition_dual_graph.h index 8bfeb002ae1..7e2a15870a7 100644 --- a/BGL/include/CGAL/boost/graph/METIS/partition_dual_graph.h +++ b/BGL/include/CGAL/boost/graph/METIS/partition_dual_graph.h @@ -36,12 +36,15 @@ #include #include +#include + namespace CGAL { namespace METIS { template -void partition_dual_graph(const TriangleMesh& tm, int nparts, +void partition_dual_graph(const TriangleMesh& tm, + int nparts, METIS_options options, // options array const NamedParameters& np) { @@ -93,11 +96,11 @@ void partition_dual_graph(const TriangleMesh& tm, int nparts, idx_t objval; // partition info for the nodes - idx_t* npart = (idx_t*) calloc(nn, sizeof(idx_t)); + idx_t* npart = (idx_t*) calloc(num_vertices(tm), sizeof(idx_t)); CGAL_assertion(npart != NULL); // partition info for the elements - idx_t* epart = (idx_t*) calloc(ne, sizeof(idx_t)); + idx_t* epart = (idx_t*) calloc(num_faces(tm), sizeof(idx_t)); CGAL_assertion(epart != NULL); // do not support Fortran-style arrays @@ -118,6 +121,12 @@ void partition_dual_graph(const TriangleMesh& tm, int nparts, Output_face_partition_ids fo; vo(tm, indices, npart, get_param(np, internal_np::vertex_partition_id)); fo(tm, epart, get_param(np, internal_np::face_partition_id)); + + delete[] eptr; + delete[] eind; + + std::free(npart); + std::free(epart); } template diff --git a/BGL/include/CGAL/boost/graph/METIS/partition_graph.h b/BGL/include/CGAL/boost/graph/METIS/partition_graph.h index 65176d37131..d0f3e56b759 100644 --- a/BGL/include/CGAL/boost/graph/METIS/partition_graph.h +++ b/BGL/include/CGAL/boost/graph/METIS/partition_graph.h @@ -34,6 +34,8 @@ #include #include +#include + namespace CGAL { namespace METIS { @@ -76,7 +78,8 @@ struct Output_face_partition_ids }; template -void partition_graph(const TriangleMesh& tm, int nparts, +void partition_graph(const TriangleMesh& tm, + int nparts, METIS_options options, // pointer to the options array const NamedParameters& np) { @@ -125,11 +128,11 @@ void partition_graph(const TriangleMesh& tm, int nparts, idx_t objval; // partition info for the nodes - idx_t* npart = (idx_t*) calloc(nn, sizeof(idx_t)); + idx_t* npart = (idx_t*) calloc(num_vertices(tm), sizeof(idx_t)); CGAL_assertion(npart != NULL); // partition info for the elements - idx_t* epart = (idx_t*) calloc(ne, sizeof(idx_t)); + idx_t* epart = (idx_t*) calloc(num_faces(tm), sizeof(idx_t)); CGAL_assertion(epart != NULL); // do not support Fortran-style arrays @@ -150,6 +153,12 @@ void partition_graph(const TriangleMesh& tm, int nparts, Output_face_partition_ids fo; vo(tm, indices, npart, get_param(np, internal_np::vertex_partition_id)); fo(tm, epart, get_param(np, internal_np::face_partition_id)); + + delete[] eptr; + delete[] eind; + + std::free(npart); + std::free(epart); } template diff --git a/BGL/include/CGAL/boost/graph/helpers.h b/BGL/include/CGAL/boost/graph/helpers.h index c62b5c9ebba..d574d7cc9ca 100644 --- a/BGL/include/CGAL/boost/graph/helpers.h +++ b/BGL/include/CGAL/boost/graph/helpers.h @@ -837,6 +837,8 @@ make_quad(const P& p0, const P& p1, const P& p2, const P& p3, Graph& g) * \ingroup PkgBGLHelperFct * \brief Creates an isolated hexahedron * with its vertices initialized to `p0`, `p1`, ...\ , and `p7`, and adds it to the graph `g`. + * \image html hexahedron.png + * \image latex hexahedron.png * \returns the halfedge that has the target vertex associated with `p0`, in the face with the vertices with the points `p0`, `p1`, `p2`, and `p3`. **/ template @@ -868,16 +870,16 @@ make_hexahedron(const P& p0, const P& p1, const P& p2, const P& p3, ppmap[v6] = p6; ppmap[v7] = p7; - halfedge_descriptor ht = internal::make_quad(v7, v4, v5, v6, g); - halfedge_descriptor hb = prev(internal::make_quad(v1, v0, v3, v2, g),g); + halfedge_descriptor ht = internal::make_quad(v4, v5, v6, v7, g); + halfedge_descriptor hb = prev(internal::make_quad(v0, v3, v2, v1, g),g); for(int i=0; i <4; i++){ halfedge_descriptor h = halfedge(add_edge(g),g); set_target(h,target(hb,g),g); set_next(h,opposite(hb,g),g); - set_next(opposite(next(ht,g),g),h,g); + set_next(opposite(prev(ht,g),g),h,g); h = opposite(h,g); - set_target(h,target(ht,g),g); - set_next(h,opposite(ht,g),g); + set_target(h,source(prev(ht,g),g),g); + set_next(h,opposite(next(next(ht,g),g),g),g); set_next(opposite(next(hb,g),g),h,g); hb = next(hb,g); ht = prev(ht,g); @@ -892,6 +894,8 @@ make_hexahedron(const P& p0, const P& p1, const P& p2, const P& p3, * \ingroup PkgBGLHelperFct * \brief Creates an isolated tetrahedron * with its vertices initialized to `p0`, `p1`, `p2`, and `p3`, and adds it to the graph `g`. + * \image html tetrahedron.png + * \image latex tetrahedron.png * \returns the halfedge that has the target vertex associated with `p0`, in the face with the vertices with the points `p0`, `p1`, and `p2`. **/ template @@ -1081,7 +1085,7 @@ make_regular_prism( * \ingroup PkgBGLHelperFct * \brief Creates a pyramid, outward oriented, having `nb_vertices` vertices in its base and adds it to the graph `g`. * - * If `center` is (0, 0, 0), then the first point of the base is (`radius`, 0`, 0) + * If `center` is `(0, 0, 0)`, then the first point of the base is `(radius, 0, 0)` * \param nb_vertices the number of vertices in the base. It must be greater than or equal to 3. * \param g the graph in which the pyramid will be created * \param base_center the center of the circle in which the base is inscribed. diff --git a/BGL/include/CGAL/boost/graph/io.h b/BGL/include/CGAL/boost/graph/io.h index 2ad04ff8fe8..60dcfca72ad 100644 --- a/BGL/include/CGAL/boost/graph/io.h +++ b/BGL/include/CGAL/boost/graph/io.h @@ -36,6 +36,89 @@ #include namespace CGAL { + /*! + \ingroup PkgBGLIOFct + writes the graph `g` in the wrl format (VRML 2.0). + + \cgalNamedParamsBegin + * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `g`. + * If this parameter is omitted, an internal property map for + * `CGAL::vertex_point_t` should be available in `FaceGraph`\cgalParamEnd + * \cgalNamedParamsEnd + */ +template +bool write_wrl(std::ostream& os, + const FaceGraph& g, + const NamedParameters& np) +{ + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef typename boost::graph_traits::face_descriptor face_descriptor; + typedef typename boost::graph_traits::vertices_size_type vertices_size_type; + + typename Polygon_mesh_processing::GetVertexPointMap::const_type + vpm = choose_param(get_param(np, internal_np::vertex_point), + get_const_property_map(CGAL::vertex_point, g)); + + boost::container::flat_map reindex; + int n = 0; + + os << "#VRML V2.0 utf8\n" + "Group {\n" + "children [\n" + "Shape {\n" + "appearance DEF A1 Appearance {\n" + "material Material {\n" + "diffuseColor .6 .5 .9\n" + "}\n" + "}\n" + "appearance\n" + "Appearance {\n" + "material DEF Material Material {}\n" + "}\n" + "}\n" + "Group {\n" + "children [\n" + "Shape {\n" + "appearance Appearance { material USE Material }\n" + "geometry IndexedFaceSet {\n" + "convex FALSE\n" + "solid FALSE\n" + "coord Coordinate {\n" + "point [\n"; + + BOOST_FOREACH(vertex_descriptor v, vertices(g)){ + os << get(vpm,v) << ",\n"; + reindex[v]=n++; + } + os << "] #point\n" + "} #coord Coordinate\n" + "coordIndex [\n"; + BOOST_FOREACH(face_descriptor f, faces(g)){ + BOOST_FOREACH(vertex_descriptor v, vertices_around_face(halfedge(f,g),g)){ + os << reindex[v] << ","; + } + os << "-1,\n"; + } + + os << "] #coordIndex\n" + "} #geometry\n" + "} #Shape\n" + "] #children\n" + "} #group\n" + "]\n" + "}\n"; + + return os.good(); +} + +template +bool write_wrl(std::ostream& os, + const FaceGraph& g) +{ + return write_wrl(os, g, + parameters::all_default()); +} + /*! \ingroup PkgBGLIOFct writes the graph `g` in the OFF format. diff --git a/BGL/include/CGAL/boost/graph/named_params_helper.h b/BGL/include/CGAL/boost/graph/named_params_helper.h index 517a750d901..e585269eba0 100644 --- a/BGL/include/CGAL/boost/graph/named_params_helper.h +++ b/BGL/include/CGAL/boost/graph/named_params_helper.h @@ -325,11 +325,17 @@ namespace CGAL { template class GetK { - typedef typename boost::property_traits< - typename GetPointMap::type - >::value_type Point; + typedef typename GetPointMap::type Vpm; + typedef typename Kernel_traits< + typename boost::property_traits::value_type + >::Kernel Default_kernel; + public: - typedef typename CGAL::Kernel_traits::Kernel Kernel; + typedef typename boost::lookup_named_param_def < + internal_np::geom_traits_t, + NamedParameters, + Default_kernel + > ::type Kernel; }; template @@ -399,6 +405,29 @@ namespace CGAL { > ::type type; }; + template + class GetIsConstrainedMap + { + struct DummyConstrainedMap + { + typedef typename std::iterator_traits::value_type key_type; + typedef bool value_type; + typedef value_type reference; + typedef boost::readable_property_map_tag category; + + typedef DummyConstrainedMap Self; + friend reference get(const Self&, const key_type&) { return false; } + }; + + public: + typedef DummyConstrainedMap NoMap; + typedef typename boost::lookup_named_param_def < + internal_np::point_is_constrained_t, + NamedParameters, + DummyConstrainedMap //default + > ::type type; + }; + } // namespace Point_set_processing_3 template diff --git a/BGL/include/CGAL/boost/graph/parameters_interface.h b/BGL/include/CGAL/boost/graph/parameters_interface.h index 4b30d28f70c..5c4c5ceb3b5 100644 --- a/BGL/include/CGAL/boost/graph/parameters_interface.h +++ b/BGL/include/CGAL/boost/graph/parameters_interface.h @@ -117,6 +117,7 @@ CGAL_add_named_parameter(plane_t, plane_map, plane_map) CGAL_add_named_parameter(plane_index_t, plane_index_map, plane_index_map) CGAL_add_named_parameter(select_percentage_t, select_percentage, select_percentage) CGAL_add_named_parameter(require_uniform_sampling_t, require_uniform_sampling, require_uniform_sampling) +CGAL_add_named_parameter(point_is_constrained_t, point_is_constrained, point_is_constrained_map) // List of named parameters used in Surface_mesh_approximation package CGAL_add_named_parameter(verbose_level_t, verbose_level, verbose_level) @@ -137,3 +138,4 @@ CGAL_add_named_parameter(face_proxy_map_t, face_proxy_map, face_proxy_map) CGAL_add_named_parameter(proxies_t, proxies, proxies) CGAL_add_named_parameter(anchors_t, anchors, anchors) CGAL_add_named_parameter(triangles_t, triangles, triangles) + diff --git a/BGL/test/BGL/CMakeLists.txt b/BGL/test/BGL/CMakeLists.txt index 8b6ef06e78d..0949c353647 100644 --- a/BGL/test/BGL/CMakeLists.txt +++ b/BGL/test/BGL/CMakeLists.txt @@ -97,6 +97,8 @@ create_single_source_cgal_program( "test_graph_traits.cpp" ) create_single_source_cgal_program( "test_Properties.cpp" ) +create_single_source_cgal_program( "test_wrl.cpp" ) + if(OpenMesh_FOUND) target_link_libraries( test_clear PRIVATE ${OPENMESH_LIBRARIES}) target_link_libraries( test_Euler_operations PRIVATE ${OPENMESH_LIBRARIES}) diff --git a/BGL/test/BGL/test_helpers.cpp b/BGL/test/BGL/test_helpers.cpp index e4d0e145829..3ba16eb4d6e 100644 --- a/BGL/test/BGL/test_helpers.cpp +++ b/BGL/test/BGL/test_helpers.cpp @@ -132,7 +132,7 @@ int main() assert(CGAL::is_triangle_mesh(m)); assert(CGAL::is_valid_polygon_mesh(m)); m.clear(); - hd = CGAL::make_hexahedron(a,b,c,d,aa,bb,cc,dd,m); + hd = CGAL::make_hexahedron(a,b,c,d,dd,aa,bb,cc,m); assert(CGAL::is_hexahedron(hd,m)); assert(CGAL::is_quad_mesh(m)); assert(CGAL::is_valid_polygon_mesh(m)); diff --git a/BGL/test/BGL/test_wrl.cpp b/BGL/test/BGL/test_wrl.cpp new file mode 100644 index 00000000000..f8a29ee8533 --- /dev/null +++ b/BGL/test/BGL/test_wrl.cpp @@ -0,0 +1,18 @@ +#include +#include +#include +#include +#include + +typedef CGAL::Simple_cartesian Kernel; +typedef Kernel::Point_3 Point; +typedef CGAL::Surface_mesh Mesh; + +int main() +{ + Mesh sm; + + CGAL::make_tetrahedron(Point(0,0,0), Point(1,0,0), Point(1,1,0), Point(0,0,1), sm); + CGAL::write_wrl(std::cout, sm); + return 0; +} diff --git a/Boolean_set_operations_2/doc/Boolean_set_operations_2/Boolean_set_operations_2.txt b/Boolean_set_operations_2/doc/Boolean_set_operations_2/Boolean_set_operations_2.txt index f62ef5d35b8..ff6ffd789b8 100644 --- a/Boolean_set_operations_2/doc/Boolean_set_operations_2/Boolean_set_operations_2.txt +++ b/Boolean_set_operations_2/doc/Boolean_set_operations_2/Boolean_set_operations_2.txt @@ -74,7 +74,7 @@ polygon vertices is referred to as the polygon (outer) boundary.
  • A polygon whose curves are pairwise disjoint in their interior, and whose vertices' degree equals two is defined as a Simple polygon. Such a polygon has a well-defined interior and exterior and is topologically equivalent to a disk. Note that while traversing the edges of the relatively simple polygon illustrated above (B), no curve is crossed over. -
  • A Relatively simple polygon allows vertices with a degree\f$\gt 2\f$, but all of its edges are disjoint in their interior. Furthermore, it must be an orientable polygon. Namely when it is inserted into an arrangement and its outer boundary is traversed, the same face is adjacent to all of the halfedges (no crossing over any curve during the traversal). +
  • A Relatively simple polygon allows vertices with a degree\f$> 2\f$, but all of its edges are disjoint in their interior. Furthermore, it must be an orientable polygon. Namely when it is inserted into an arrangement and its outer boundary is traversed, the same face is adjacent to all of the halfedges (no crossing over any curve during the traversal). Note that while polygon C has the same curves as polygon B, traversal of the curves leads to crossing over a previously traversed curve, and is therefore neither simple nor relatively simple.
  • A polygon in our context must be relatively simple and its outer boundary vertices must be ordered in a counterclockwise direction around the interior of the polygon. diff --git a/Bounding_volumes/doc/Bounding_volumes/CGAL/Approximate_min_ellipsoid_d.h b/Bounding_volumes/doc/Bounding_volumes/CGAL/Approximate_min_ellipsoid_d.h index c53940face3..535dc70d085 100644 --- a/Bounding_volumes/doc/Bounding_volumes/CGAL/Approximate_min_ellipsoid_d.h +++ b/Bounding_volumes/doc/Bounding_volumes/CGAL/Approximate_min_ellipsoid_d.h @@ -13,28 +13,28 @@ x\in\E^d \mid x^T E x + x^T e + \eta\leq 0 \}\f$, where \f$ E\f$ is some positive definite matrix from the set \f$ \mathbb{R}^{d\times d}\f$, \f$ e\f$ is some real \f$ d\f$-vector, and \f$ \eta\in\mathbb{R}\f$. A pointset \f$ P\subseteq \E^d\f$ is called full-dimensional if its affine hull has dimension \f$ d\f$. -For a finite, full-dimensional pointset \f$ P\f$ we denote by \f$ \mel(P)\f$ the +For a finite, full-dimensional pointset \f$ P\f$ we denote by \f$ (P)\f$ the smallest ellipsoid that contains all points of \f$ P\f$; this ellipsoid exists and is unique. For a given finite and full-dimensional pointset \f$ P\subset \E^d\f$ and a real number \f$ \epsilon\ge 0\f$, we say that an ellipsoid \f$ {\cal -E}\subset\E^d\f$ is an \f$ (1+\epsilon)\f$-appoximation to \f$ \mel(P)\f$ if -\f$ P\subset {\cal E}\f$ and \f$ \vol({\cal E}) \leq (1+\epsilon) -\vol(\mel(P))\f$. In other words, an \f$ (1+\epsilon)\f$-approximation to -\f$ \mel(P)\f$ is an enclosing ellipsoid whose volume is by at most a +E}\subset\E^d\f$ is an \f$ (1+\epsilon)\f$-appoximation to \f$ (P)\f$ if +\f$ P\subset {\cal E}\f$ and \f$ ({\cal E}) \leq (1+\epsilon) +((P))\f$. In other words, an \f$ (1+\epsilon)\f$-approximation to +\f$ (P)\f$ is an enclosing ellipsoid whose volume is by at most a factor of \f$ 1+\epsilon\f$ larger than the volume of the smallest enclosing ellipsoid of \f$ P\f$. Given this notation, an object of class `Approximate_min_ellipsoid_d` represents an -\f$ (1+\epsilon)\f$-approximation to \f$ \mel(P)\f$ for a given finite and +\f$ (1+\epsilon)\f$-approximation to \f$ (P)\f$ for a given finite and full-dimensional multiset of points \f$ P\subset\E^d\f$ and a real constant \f$ \epsilon>0\f$.\cgalFootnote{A multiset is a set where elements may have multiplicity greater than \f$ 1\f$.} When an `Approximate_min_ellipsoid_d` object is constructed, an iterator over the points \f$ P\f$ and the number \f$ \epsilon\f$ have to be specified; the number \f$ \epsilon\f$ defines the desired approximation ratio \f$ 1+\epsilon\f$. The underlying algorithm will then -try to compute an \f$ (1+\epsilon)\f$-approximation to \f$ \mel(P)\f$, and one of +try to compute an \f$ (1+\epsilon)\f$-approximation to \f$ (P)\f$, and one of the following two cases takes place.
    • The algorithm determines that \f$ P\f$ is not full-dimensional (see @@ -44,7 +44,7 @@ the following two cases takes place. in all cases decide correctly whether \f$ P\f$ is full-dimensional or not. If `is_full_dimensional()` returns `false`, the points lie in such a "thin" subspace of \f$ \E^d\f$ that the algorithm is -incapable of computing an approximation to \f$ \mel(P)\f$. More +incapable of computing an approximation to \f$ (P)\f$. More precisely, if `is_full_dimensional()` returns `false`, there exist two parallel hyperplanes in \f$ \E^d\f$ with the points \f$ P\f$ in between so that the distance \f$ \delta\f$ between the hyperplanes is @@ -55,7 +55,7 @@ If \f$ P\f$ is not full-dimensional, linear algebra techniques should be used to determine an affine subspace \f$ S\f$ of \f$ \E^d\f$ that contains the points \f$ P\f$ as a (w.r.t.\ \f$ S\f$) full-dimensional pointset; once \f$ S\f$ is determined, the algorithm can be invoked again to compute an -approximation to (the lower-dimensional) \f$ \mel(P)\f$ in \f$ S\f$. Since +approximation to (the lower-dimensional) \f$ (P)\f$ in \f$ S\f$. Since `is_full_dimensional()` might (due to rounding errors, see above) return `false` even though \f$ P\f$ is full-dimensional, the lower-dimensional subspace \f$ S\f$ containing \f$ P\f$ need not exist. @@ -66,7 +66,7 @@ ellipsoid of the projected points within \f$ H\f$; the fitting can be done for instance using the `linear_least_squares_fitting()` function from the \cgal package `Principal_component_analysis`.
    • The algorithm determines that \f$ P\f$ is full-dimensional. In this -case, it provides an approximation \f$ {\cal E}\f$ to \f$ \mel(P)\f$, but +case, it provides an approximation \f$ {\cal E}\f$ to \f$ (P)\f$, but depending on the input problem (i.e., on the pair \f$ (P,\epsilon)\f$), it may not have achieved the desired approximation ratio but merely some worse approximation ratio \f$ 1+\epsilon'>1+\epsilon\f$. The @@ -126,7 +126,7 @@ Cholesky-decomposition. The algorithm's running time is To illustrate the usage of `Approximate_min_ellipsoid_d` we give two examples in 2D. The first program generates a random set \f$ P\subset\E^2\f$ and outputs the -points and a \f$ 1.01\f$-approximation of \f$ \mel(P)\f$ as an EPS-file, which +points and a \f$ 1.01\f$-approximation of \f$ (P)\f$ as an EPS-file, which you can view using gv, for instance. (In both examples you can change the variables `n` and `d` to experiment with the code.) @@ -204,7 +204,7 @@ typedef unspecified_type Axis_direction_iterator; /*! initializes `ame` to an \f$ (1+\epsilon)\f$-approximation of -\f$ \mel(P)\f$ with \f$ P\f$ being the set of points in the range +\f$ (P)\f$ with \f$ P\f$ being the set of points in the range [`first`,`last`). The number \f$ \epsilon\f$ in this will be at most `eps`, if possible. However, due to the limited precision in the algorithm's underlying arithmetic, it @@ -260,7 +260,7 @@ unsigned int number_of_points( ) const; returns a number \f$ \epsilon'\f$ such that the computed approximation is (under exact arithmetic) guaranteed to be an \f$ (1+\epsilon')\f$-approximation to -\f$ \mel(P)\f$. +\f$ (P)\f$. \pre `ame.is_full_dimensional() == true`. \post \f$ \epsilon'>0\f$. */ @@ -404,7 +404,7 @@ bool is_full_dimensional( ) const; /// An object `ame` is valid iff
      • `ame` contains all points of /// its defining set \f$ P\f$,
      • `ame` is an \f$ /// (1+\epsilon')\f$-approximation to the smallest ellipsoid \f$ -/// \mel(P)\f$ of \f$ P\f$,
      • The ellipsoid represented by `ame` +/// (P)\f$ of \f$ P\f$,
      • The ellipsoid represented by `ame` /// fulfills the inclusion ( \ref eqapproximate_min_ellipsoid_incl /// ).
      /// @{ @@ -426,7 +426,7 @@ bool is_valid( bool verbose = false) const; /*! Writes the points \f$ P\f$ and the computed approximation to -\f$ \mel(P)\f$ as an EPS-file under pathname `name`. \pre The dimension of points \f$ P\f$ must be \f$ 2\f$. +\f$ (P)\f$ as an EPS-file under pathname `name`. \pre The dimension of points \f$ P\f$ must be \f$ 2\f$. Note: this routine is provided as a debugging routine; future version of \cgal might not provide it anymore. diff --git a/Bounding_volumes/include/CGAL/Min_ellipse_2.h b/Bounding_volumes/include/CGAL/Min_ellipse_2.h index 3a15bef505b..4348f8a5f80 100644 --- a/Bounding_volumes/include/CGAL/Min_ellipse_2.h +++ b/Bounding_volumes/include/CGAL/Min_ellipse_2.h @@ -360,7 +360,20 @@ class Min_ellipse_2 { // default constructor inline - Min_ellipse_2( const Traits& traits = Traits()) + Min_ellipse_2() + : n_support_points( 0) + { + // allocate support points' array + support_points = new Point[ 5]; + + // initialize ellipse + tco.ellipse.set(); + + CGAL_optimisation_postcondition( is_empty()); + } + + inline + Min_ellipse_2( const Traits& traits ) : tco( traits), n_support_points( 0) { // allocate support points' array diff --git a/CGAL_ImageIO/examples/CGALimageIO/CMakeLists.txt b/CGAL_ImageIO/examples/CGALimageIO/CMakeLists.txt index abf713eb1c8..3dcdf8d8c3d 100644 --- a/CGAL_ImageIO/examples/CGALimageIO/CMakeLists.txt +++ b/CGAL_ImageIO/examples/CGALimageIO/CMakeLists.txt @@ -5,6 +5,10 @@ project( CGALimageIO_Examples ) cmake_minimum_required(VERSION 3.1) +if(POLICY CMP0074) + cmake_policy(SET CMP0074 NEW) +endif() + find_package(CGAL QUIET COMPONENTS ImageIO ) if(CGAL_ImageIO_FOUND) diff --git a/CGAL_ImageIO/include/CGAL/ImageIO_impl.h b/CGAL_ImageIO/include/CGAL/ImageIO_impl.h index da049f853db..6e8ec0ffb05 100644 --- a/CGAL_ImageIO/include/CGAL/ImageIO_impl.h +++ b/CGAL_ImageIO/include/CGAL/ImageIO_impl.h @@ -168,7 +168,7 @@ unsigned int ImageIO_limit_len(size_t to_be_read) CGAL_INLINE_FUNCTION size_t ImageIO_write(const _image *im, const void *buf, size_t len) { size_t to_be_written = len; - int l = -1; + std::ptrdiff_t l = -1; char *b = (char*)buf; switch(im->openMode) { diff --git a/CGAL_ImageIO/include/CGAL/read_vtk_image_data.h b/CGAL_ImageIO/include/CGAL/read_vtk_image_data.h index 2c28a44c25a..c592d3a0be2 100644 --- a/CGAL_ImageIO/include/CGAL/read_vtk_image_data.h +++ b/CGAL_ImageIO/include/CGAL/read_vtk_image_data.h @@ -63,6 +63,7 @@ read_vtk_image_data(vtkImageData* vtk_image) _image* image = ::_initImage(); const int* dims = vtk_image->GetDimensions(); const double* spacing = vtk_image->GetSpacing(); + const double* offset = vtk_image->GetOrigin(); image->vectMode = VM_SCALAR; image->xdim = dims[0]; image->ydim = dims[1]; @@ -71,6 +72,9 @@ read_vtk_image_data(vtkImageData* vtk_image) image->vx = spacing[0]; image->vy = spacing[1]; image->vz = spacing[2]; + image->tx = offset[0]; + image->ty = offset[1]; + image->tz = offset[2]; image->endianness = ::_getEndianness(); int vtk_type = vtk_image->GetScalarType(); if(vtk_type == VTK_SIGNED_CHAR) vtk_type = VTK_CHAR; diff --git a/CGAL_ImageIO/test/CGAL_ImageIO/CMakeLists.txt b/CGAL_ImageIO/test/CGAL_ImageIO/CMakeLists.txt index 7b39be42ee8..81eec777452 100644 --- a/CGAL_ImageIO/test/CGAL_ImageIO/CMakeLists.txt +++ b/CGAL_ImageIO/test/CGAL_ImageIO/CMakeLists.txt @@ -6,6 +6,10 @@ project( CGAL_ImageIO_Tests ) cmake_minimum_required(VERSION 3.1) +if(POLICY CMP0074) + cmake_policy(SET CMP0074 NEW) +endif() + find_package(CGAL QUIET COMPONENTS ImageIO ) if ( CGAL_FOUND ) diff --git a/Cartesian_kernel/include/CGAL/constructions/kernel_ftC2.h b/Cartesian_kernel/include/CGAL/constructions/kernel_ftC2.h index 48dba7821ae..9373f9feeda 100644 --- a/Cartesian_kernel/include/CGAL/constructions/kernel_ftC2.h +++ b/Cartesian_kernel/include/CGAL/constructions/kernel_ftC2.h @@ -28,6 +28,7 @@ #include #include +#include namespace CGAL { @@ -284,7 +285,16 @@ line_get_pointC2(const FT &a, const FT &b, const FT &c, int i, { if (CGAL_NTS is_zero(b)) { - x = (-b-c)/a + i * b; + // Laurent Rineau, 2018/12/07: I add this CGAL_assume to calm + // down a warning from MSVC 2017: + // > include\cgal\constructions\kernel_ftc2.h(287) : + // > warning C4723: potential divide by 0 + // The test `!boost::is_integral::value` is there to avoid + // that `a != 0` is tested on anything but integral types, for + // performance reasons. + CGAL_assume(!boost::is_integral::value || a != FT(0)); + + x = -c/a; y = 1 - i * a; } else diff --git a/Circular_kernel_3/demo/Circular_kernel_3/CMakeLists.txt b/Circular_kernel_3/demo/Circular_kernel_3/CMakeLists.txt index 7b855adddbf..f66a1c8c7b7 100644 --- a/Circular_kernel_3/demo/Circular_kernel_3/CMakeLists.txt +++ b/Circular_kernel_3/demo/Circular_kernel_3/CMakeLists.txt @@ -6,6 +6,10 @@ if(NOT POLICY CMP0070 AND POLICY CMP0053) cmake_policy(SET CMP0053 OLD) endif() +if(POLICY CMP0071) + cmake_policy(SET CMP0071 NEW) +endif() + find_package(CGAL COMPONENTS Qt5) find_package(Qt5 QUIET COMPONENTS Xml Script OpenGL) diff --git a/Classification/doc/Classification/PackageDescription.txt b/Classification/doc/Classification/PackageDescription.txt index b1a3dafe536..6452aa25b39 100644 --- a/Classification/doc/Classification/PackageDescription.txt +++ b/Classification/doc/Classification/PackageDescription.txt @@ -1,6 +1,6 @@ -/*! -\defgroup PkgClassificationRef Classification Reference +/// \defgroup PkgClassificationRef Classification Reference +/*! \defgroup PkgClassificationConcepts Concepts \ingroup PkgClassificationRef diff --git a/Classification/include/CGAL/Classification/ETHZ_random_forest_classifier.h b/Classification/include/CGAL/Classification/ETHZ_random_forest_classifier.h index cf3ae810df9..1587baf4b9b 100644 --- a/Classification/include/CGAL/Classification/ETHZ_random_forest_classifier.h +++ b/Classification/include/CGAL/Classification/ETHZ_random_forest_classifier.h @@ -38,6 +38,7 @@ # pragma warning(disable:4267) # pragma warning(disable:4275) # pragma warning(disable:4251) +# pragma warning(disable:4996) #endif #include diff --git a/Cone_spanners_2/doc/Cone_spanners_2/PackageDescription.txt b/Cone_spanners_2/doc/Cone_spanners_2/PackageDescription.txt index 5833bf7e4ae..94e5022fa37 100644 --- a/Cone_spanners_2/doc/Cone_spanners_2/PackageDescription.txt +++ b/Cone_spanners_2/doc/Cone_spanners_2/PackageDescription.txt @@ -1,5 +1,3 @@ -// PRETTY PACKAGE NAME should equal the project title in Doxyfile.in - /// \defgroup PkgConeSpanners2Ref Cone-Based Spanners Reference /*! diff --git a/Documentation/doc/CMakeLists.txt b/Documentation/doc/CMakeLists.txt index 3e630a9ae3e..c45057f806d 100644 --- a/Documentation/doc/CMakeLists.txt +++ b/Documentation/doc/CMakeLists.txt @@ -93,7 +93,7 @@ function(configure_doxygen_package CGAL_PACKAGE_NAME) file(APPEND ${CGAL_DOC_PACKAGE_DEFAULTS} "STRIP_FROM_INC_PATH = ${CGAL_PACKAGE_DOC_DIR}/\n") file(APPEND ${CGAL_DOC_PACKAGE_DEFAULTS} "STRIP_FROM_INC_PATH += ${CGAL_PACKAGE_DIR}/include/\n") file(APPEND ${CGAL_DOC_PACKAGE_DEFAULTS} "ALIASES += \"cgalPkgDescriptionBegin{2}=\\details \"\n") - file(APPEND ${CGAL_DOC_PACKAGE_DEFAULTS} "ALIASES += \"cgalPkgManuals{2}=
      \"\n") + file(APPEND ${CGAL_DOC_PACKAGE_DEFAULTS} "ALIASES += \"cgalPkgManuals{2}=
      \"\n") file(APPEND ${CGAL_DOC_PACKAGE_DEFAULTS} "INPUT = ${CGAL_PACKAGE_DOC_DIR}\n") if(NOT EXISTS "${CGAL_PACKAGE_DOC_DIR}/CGAL") # This package has in-source documentation. diff --git a/Documentation/doc/biblio/cgal_manual.bib b/Documentation/doc/biblio/cgal_manual.bib index 8aa45b4b302..524c68b9a45 100644 --- a/Documentation/doc/biblio/cgal_manual.bib +++ b/Documentation/doc/biblio/cgal_manual.bib @@ -102,7 +102,7 @@ ,howpublished = {American National Standards Institute, 11 West 42nd Street, New York 10036} ,year = 1998 - ,url = "http://webstore.ansi.org/" + ,url = "https://webstore.ansi.org/" ,update = "04.03 kettner, 01.06 hoffmann" } @@ -281,8 +281,8 @@ Boissonnat} ,author = {Gavin Bell and Anthony Parisi and Mark Pesce} ,title = {VRML The Virtual Reality Modeling Language: Version 1.0 Specification} - ,howpublished = {\url{http://www.web3d.org/x3d/specifications/vrml/VRML1.0/index.html}} - ,url = "http://www.web3d.org/x3d/specifications/vrml/VRML1.0/index.html" + ,howpublished = {\url{http://www.web3d.org/standards}} + ,url = "http://www.web3d.org/standards" ,month = {May 26} ,year = 1995 ,update = "13.04 lrineau" @@ -325,7 +325,7 @@ Boissonnat} ,school = "Universit\'e de {Nice-Sophia Antipolis}" ,address = "France" ,year = 2010 - ,url = "http://tel.archives-ouvertes.fr/tel-00552215/" + ,url = "https://tel.archives-ouvertes.fr/tel-00552215/" } @article{cgal:cc-rgbss-78 @@ -448,7 +448,7 @@ note="Conference version: Symp. on Geometry Processing 2003" , year = 2009 , volume = 5757 , pages = "37--48" -, note = "Full version available as INRIA Research Report 6823 \url{http://hal.inria.fr/inria-00356871}" +, note = "Full version available as INRIA Research Report 6823 \url{https://hal.inria.fr/inria-00356871}" } @inproceedings{cgal:pt-rs-14, @@ -607,7 +607,7 @@ Mourrain and Monique Teillaud" , nickname = "ALENEX '03" , year = 2003 , pages = "37--44" - , url = "http://hal.inria.fr/inria-00344517/" + , url = "https://hal.inria.fr/inria-00344517/" } @article{ cgal:dpt-wt-02 @@ -626,7 +626,7 @@ Teillaud" , author = "Olivier Devillers and Monique Teillaud" , title = "Perturbations and Vertex Removal in a {3D Delaunay} Triangulation" , booktitle = "Proc. 14th ACM-SIAM Sympos. Discrete Algorithms (SODA)" - , url = "http://hal.inria.fr/inria-00166710/" + , url = "https://hal.inria.fr/inria-00166710/" , year = 2003 , pages = "313-319" } @@ -1535,7 +1535,7 @@ ABSTRACT = {We present the first complete, exact and efficient C++ implementatio ,title = {The {LEDA} {U}ser {M}anual} ,organization = {Algorithmic Solutions} ,address = {66123 Saarbr\"ucken, Germany} - ,url = {http://www.algorithmic-solutions.info/leda_manual/manual.html} + ,url = {http://www.algorithmic-solutions.info/leda_manual/MANUAL.html} } @article{ cgal:mog-vbcfe-11 @@ -1593,7 +1593,7 @@ ABSTRACT = {We present the first complete, exact and efficient C++ implementatio title = {{MPFR} - The Multiple Precision Floating-Point Reliable Library}, howpublished = {The {MPFR} Team}, - url = {http://mpfr.org}, + url = {https://mpfr.org}, update = "09.11 penarand" } @@ -1774,7 +1774,6 @@ ABSTRACT = {We present the first complete, exact and efficient C++ implementatio key = {RS}, title = {{RS - A} Software for real solving of algebraic systems}, howpublished = {{R}ouillier, {F}abrice}, - url = {http://www.loria.fr/equipes/vegas/rs/}, update = "09.11 penarand" } @@ -1908,7 +1907,6 @@ ABSTRACT = {We present the first complete, exact and efficient C++ implementatio @misc{ cgal:sgcsi-stlpg-97 ,author = {{Silicon Graphics Computer Systems{,} Inc.}} ,title = {Standard Template Library Programmer's Guide} - ,url = {http://www.sgi.com/Technology/STL/} ,year = 1997 ,annote = {Web reference to the STL from SGI. recommended C++ and STL reference material.} @@ -1950,7 +1948,7 @@ ABSTRACT = {We present the first complete, exact and efficient C++ implementatio ,month = dec ,year = {2000} ,issn = {0946-011X} - ,url = {http://www.mpi-sb.mpg.de/~mehlhorn/ftp/InfiFrames.ps} + ,url = {https://www.mpi-sb.mpg.de/~mehlhorn/ftp/InfiFrames.ps} } @InProceedings{cgal:sp-mrbee-05 @@ -2040,7 +2038,7 @@ location = {Salt Lake City, Utah, USA} , pages = "75:1-75:9" , note = "SIGGRAPH '2009 Conference Proceedings" , volume = "28(3)" -, url = "http://hal.inria.fr/inria-00359288" +, url = "https://hal.inria.fr/inria-00359288" , geombib = "not yet" , x-editorial-board = {yes} , x-proceedings = {yes} @@ -2173,7 +2171,7 @@ location = {Salt Lake City, Utah, USA} howpublished = {Stefan Walk (ETH Zurich, Department of Civil, Environmental and Geomatic Engineering, Institute of Geodesy and Photogrammetry)}, - url = {http://www.prs.igp.ethz.ch/research/Source_code_and_datasets.html}, + url = {https://www.prs.igp.ethz.ch/research/Source_code_and_datasets.html}, year = 2014 @inproceedings{ cgal:wk-srhvs-05, @@ -2262,7 +2260,7 @@ location = {Salt Lake City, Utah, USA} editor = "L{\'{a}}szl{\'{o}} Szirmay Kalos", pages = "210--218", year = "1998", - url = "citeseer.ist.psu.edu/article/felkel98straight.html" + url = "http://citeseer.ist.psu.edu/article/felkel98straight.html" } @inproceedings{ cgal:ee-rrccpp-98, @@ -2271,7 +2269,7 @@ location = {Salt Lake City, Utah, USA} booktitle = "Symposium on Computational Geometry", pages = "58--67", year = "1998", - url = "citeseer.ist.psu.edu/eppstein98raising.html" + url = "http://citeseer.ist.psu.edu/eppstein98raising.html" } @inproceedings{ cgal:ld-agrm-03, @@ -2324,7 +2322,7 @@ pages = {69-79}, ee = {http://link.springer.de/link/service/series/0558/bibs/1766/17660069.htm}, crossref = {cgal:jlm-isgp-98}, bibsource = {DBLP, http://dblp.uni-trier.de}, -url = "http://www.boost.org/community/exception_safety.html" +url = "https://www.boost.org/community/exception_safety.html" } @misc{ cgal:asprs-lasf-13 @@ -2332,7 +2330,7 @@ url = "http://www.boost.org/community/exception_safety.html" ,title = "LASer ({LAS}) File Format Exchange Activities" ,howpublished = {American Society for Photogrammetry \& Remote Sensing} ,year = 2013 - ,url = "https://www.asprs.org/committee-general/laser-las-file-format-exchange-activities.html" + ,url = "https://www.asprs.org/divisions-committees/lidar-division/laser-las-file-format-exchange-activities" } @article{cgal:as-solri-92 @@ -2466,7 +2464,7 @@ author = "Pedro M.M. de Castro and Frederic Cazals and Sebastien Loriot and Moni AUTHOR = {Otfried Cheong}, EDITION = {6.0pre32}, YEAR = {2009}, - URL = {http://tclab.kaist.ac.kr/ipe/} + URL = {http://ipe.otfried.org/} } @misc{cgal:t-ocdl-05, @@ -2484,7 +2482,7 @@ author = "Pedro M.M. de Castro and Frederic Cazals and Sebastien Loriot and Moni editor = "Jacob E. Goodman, J\'anos Pach and Emo Welzl", year = {2005}, pages = {439-458}, - URL = {http://www.msri.org/communications/books/Book52/files/23liu.pdf}, + URL = {http://library.msri.org/books/Book52/files/23liu.pdf}, publisher = {MSRI Publications} } @@ -2497,7 +2495,7 @@ author = "Pedro M.M. de Castro and Frederic Cazals and Sebastien Loriot and Moni , volume = "40" , number = "1" , pages = "61-78" -, url = "http://hal.inria.fr/inria-00344310/" +, url = "https://hal.inria.fr/inria-00344310/" , doi = "10.1016/j.comgeo.2007.06.003" , x-international-audience = "yes" , x-editorial-board = "yes" @@ -2517,7 +2515,7 @@ author = "Pedro M.M. de Castro and Frederic Cazals and Sebastien Loriot and Moni , title = "Complexity of {Delaunay} triangulation for points on lower-dimensional polyhedra" , booktitle = "Proc. 18th ACM-SIAM Sympos. Discrete Algorithms" , nickname = "SODA" -, url = "http://hal.inria.fr/inria-00182835/" +, url = "https://hal.inria.fr/inria-00182835/" , year = 2007 , pages = "1106--1113" } @@ -2643,7 +2641,7 @@ ADDRESS = "Saarbr{\"u}cken, Germany" author={Sorkine, Olga}, year={2009}, pages={1-6}, - howpublished = {http://igl.ethz.ch/projects/ARAP/} + url = {https://igl.ethz.ch/projects/ARAP/} @book{cgal:bc:m-dbc-27, Address = {Leipzig}, @@ -2789,7 +2787,7 @@ pages = "207--221" journal = {CoRR}, year = {2014}, volume = {abs/1403.3905}, - url = {http://arxiv.org/abs/1403.3905}, + url = {https://arxiv.org/abs/1403.3905}, timestamp = {Wed, 17 Sep 2014 16:30:16 +0200}, biburl = {http://dblp.uni-trier.de/rec/bib/journals/corr/BungiuHHHK14}, bibsource = {dblp computer science bibliography, http://dblp.org} diff --git a/Documentation/doc/biblio/geom.bib b/Documentation/doc/biblio/geom.bib index 801a459f83e..b6602668758 100644 --- a/Documentation/doc/biblio/geom.bib +++ b/Documentation/doc/biblio/geom.bib @@ -7010,7 +7010,6 @@ cell neighborhood in $O(m)$ time." , type = "Research {Report}" , institution = "Xerox PARC" , year = 1997 -, url = "http://www.geom.umn.edu/~nina/papers/crust.ps.gz" , precedes = "abe-cbscc-98" , update = "00.03 devillers, 98.03 devillers" } @@ -11387,7 +11386,7 @@ method that uses very different techniques." , address = "BP93, 06902 Sophia-Antipolis, France" , month = jun , year = 1993 -, url = "http://www.inria.fr/cgi-bin/wais_ra_sophia?question=1990" +, url = "https://hal.inria.fr/inria-00074682" , keywords = "parallel algorithms, hypercube, multisearching, point location" , update = "95.09 devillers, 95.01 devillers, 93.09 devillers+milone+mitchell" } @@ -19005,7 +19004,6 @@ $O(n^2)$ in the plane." , address = "Berlin" , year = 1997 , isbn = "3-540-61270-X" -, url = "http://www.cs.ruu.nl/geobook/" , keywords = "textbook" , update = "98.03 agarwal+mitchell, 97.11 oostrum+orourke" } @@ -19734,7 +19732,7 @@ $O(n^2)$ in the plane." , booktitle = "Proc. 11th Canad. Conf. Comput. Geom." , year = 1999 , pages = "13--16" -, note = "Full version: http://arXiv.org/abs/cs/9908003/" +, note = "Full version: https://arXiv.org/abs/cs/9908003/" , url = "http://www.cs.ubc.ca/conferences/CCCG/elec_proc/elecproc.html" , update = "01.11 orourke, 00.03 orourke" } @@ -24218,7 +24216,7 @@ must lie in the halfplanes delimited by the query lines." , volume = 8 , year = 1992 , pages = "51--71" -, url = "http://www-sop.inria.fr/prisme/publis/bdsty-arsol-92.ps.gz" +, url = "https://hal.inria.fr/inria-00090675" , keywords = "randomized algorithms, Delaunay triangulation, semi-dynamic algorithms, arrangement of line-segments" , succeeds = "bdsty-olgag-91i" , update = "99.11 bibrelex, 99.07 devillers, 98.07 bibrelex, 97.03 devillers, 96.01 devillers, 95.09 devillers, 95.01 devillers" @@ -24669,7 +24667,6 @@ present a polynomial-time exact algorithm to solve this problem." , address = "UK" , year = 1998 , note = "Translated by Herv{\'e} Br{\"o}nnimann" -, url = "http://www.cup.cam.ac.uk/Scripts/webbook.asp?isbn=0521563224" , succeeds = "by-ga-95" , update = "99.11 devillers, 99.07 devillers, 99.03 bibrelex+devillers, 98.07 devillers" , annote = "translated from {\cite{by-ga-95}} by Herv{\'e} Br{\"o}nnimann" @@ -24681,7 +24678,6 @@ present a polynomial-time exact algorithm to solve this problem." , publisher = "Ediscience international" , address = "Paris" , year = 1995 -, url = "http://www-sop.inria.fr/prisme/personnel/yvinec/livre.html" , precedes = "by-ag-98" , update = "99.07 devillers, 99.03 bibrelex, 98.07 devillers, 96.01 devillers" } @@ -27495,7 +27491,7 @@ and solids on dynamically evolving grids without remeshing." , year = 1999 , pages = "173--197" , note = "Special Issue on Real Numbers and Computers" -, url = "http://www-sop.inria.fr/prisme/personnel/pion/publis/TCS.ps.gz" +, url = "https://hal.inria.fr/inria-00344324" , succeeds = "bepp-cegpu-97" , update = "99.07 devillers" } @@ -44299,7 +44295,7 @@ Contains C code." , booktitle = "Proc. 14th Annu. ACM Sympos. Comput. Geom." , year = 1998 , pages = "106--115" -, url = "http://www-sop.inria.fr/prisme/publis/d-iirdt-98.ps.gz" +, url = "https://hal.inria.fr/hal-01179446" , archive = "XXX:cs.CG/9907024" , update = "99.11 bibrelex+devillers, 99.07 devillers, 98.11 devillers" , abstract = "We propose a new data structure to compute the Delaunay triangulation of a set of points in the plane. It combines good worst case complexity, fast behavior on real data, and small memory occupation. The location structure is organized into several levels. The lowest level just consists of the triangulation, then each level contains the triangulation of a small sample of the levels below. Point location is done by marching in a triangulation to determine the nearest neighbor of the query at that level, then the march restarts from that neighbor at the level below. Using a small sample (3 {\%}) allows a small memory occupation; the march and the use of the nearest neighbor to change levels quickly locate the query." @@ -44337,7 +44333,7 @@ Contains C code." , year = 2009 , type = "Research Report" , number = 7104 -, url = "http://hal.inria.fr/inria-00433107/" +, url = "https://hal.inria.fr/inria-00433107/" } @inproceedings{d-ddt-99 @@ -44363,7 +44359,7 @@ Contains C code." , number = 1 , year = 1992 , pages = "97--111" -, url = "http://www-sop.inria.fr/prisme/publis/d-rysoa-92.ps.gz" +, url = "https://hal.inria.fr/inria-00167206" , archive = "XXX:cs.CG/9810007" , keywords = "randomized algorithms, Delaunay triangulation, skeleton, medial axis, minimum spanning tree, simple polygon" , succeeds = "d-sroa-91" @@ -44583,7 +44579,7 @@ respectively, we obtain a speedup of $\frac p{\log p}$." , number = 3 , year = 1995 , pages = "157--164" -, url = "http://www-sop.inria.fr/prisme/biblio/search.html" +, url = "https://hal.inria.fr/inria-00074391" , succeeds = "dg-iafch-94" , cites = "a-dcgp-85, bcddy-acchs-92, r-chada-92" , update = "99.11 devillers, 99.07 devillers, 96.01 devillers" @@ -44838,7 +44834,7 @@ respectively, we obtain a speedup of $\frac p{\log p}$." , volume = 20 , year = 1998 , pages = "523--547" -, url = "http://www-sop.inria.fr/prisme/publis/dp-papaf-98.ps.gz" +, url = "https://hal.inria.fr/inria-00090653" , archive = "XXX:cs.CG/9907029" , succeeds = "dp-papaf-96" , cites = "b-g-87, bkmnsu-egcl-95, bms-hcvdl-94, fv-eeacg-93, lpt-rpqiv-96, mn-iga-94, y-tegc-97" @@ -52318,7 +52314,6 @@ library." , month = jan , year = 1994 , pages = "43--72" -, url = "https://users.cs.duke.edu/~edels/Papers/1994-J-04-3DAlphaShapes.pdf" , comments = "Software in \url{ftp://cs.uiuc.edu/pub/edels/geometry/alpha-2.1a.tar.Z}" , update = "94.09 orourke" } @@ -68865,7 +68860,7 @@ generated in O(dn2d+1) time. We present a simple proof that the (d - @misc{g-ggmpa , author = "Torbj{\"o}rn Granlund" , title = "{GMP}, The {GNU} Multiple Precision Arithmetic Library" -, url = "http://gmplib.org/" +, url = "https://gmplib.org/" , update = "02.03 devillers" } @@ -85658,7 +85653,7 @@ fitting method." , title = "The {CORE} Library Project" , edition = "1.2" , year = 1999 -, url = "http://www.cs.nyu.edu/exact/core/" +, url = "https://www.cs.nyu.edu/exact/core/" , update = "00.03 devillers" } @@ -140391,7 +140386,7 @@ code." , publisher = "INRIA Sophia-Antipolis" , year = 1999 , pages = "175--178" -, url = "ftp://ftp-sop.inria.fr/geometrica/publis/t-3tc-99.pdf" +, url = "https://hal.inria.fr/inria-00167199" , update = "00.03 bibrelex+devillers, 99.07 bibrelex" } @@ -150728,7 +150723,6 @@ This improves previous bound of $O(mt+m\log m)$ in , address = "Singapore" , year = 1995 , pages = "452--492" -, url = "http://cs.nyu.edu/cs/faculty/yap/papers/paradigm.ps" , keywords = "survey paper, numeral computing, exact compuation, fixed-precision, multiprecision number packages" , update = "98.07 icking+vismara, 97.11 icking, 97.03 devillers+pocchiola" , abstract = "A survey of the approaches to non-robustness of geometric algorithms, and especially the exact computation approach. Also surveys available big-number packages." @@ -151944,7 +151938,7 @@ pages = {179--189} , number = "RR-8467" , month = "Feb" , year = "2014" -, url = "http://hal.inria.fr/hal-00943409" +, url = "https://hal.inria.fr/hal-00943409" } @article{XinWang2009improvingchenandhan, diff --git a/Documentation/doc/resources/1.8.13/BaseDoxyfile.in b/Documentation/doc/resources/1.8.13/BaseDoxyfile.in index 49b2e2c11b3..e3f372bcf3d 100644 --- a/Documentation/doc/resources/1.8.13/BaseDoxyfile.in +++ b/Documentation/doc/resources/1.8.13/BaseDoxyfile.in @@ -250,9 +250,9 @@ ALIASES = "sc{1}=\1
      \image html \2 \n \image latex \2 \"\" width=2.1cm \n \image html \3 \n \image latex \3 \"\" width=2.1cm \n \image html \4 \n \image latex \4 \"\" width=2.1cm \n \image html \5 \n \image latex \5 \"\" width=2.1cm \n \image html \6 \n \image latex \6 \"\" width=2.1cm \n \image html \7 \n \image latex \7 \"\" width=2.1cm \n \image html \8 \n \image latex \8 \"\" width=2.1cm \n
      \htmlonly
      \endhtmlonly \n \latexonly \n \endlatexonly \ref fig__\1" \ "cgalFigureBegin{9}=\anchor fig__\1 \n
      \image html \2 \n \image latex \2 \"\" width=1.9cm \n \image html \3 \n \image latex \3 \"\" width=1.9cm \n \image html \4 \n \image latex \4 \"\" width=1.9cm \n \image html \5 \n \image latex \5 \"\" width=1.9cm \n \image html \6 \n \image latex \6 \"\" width=1.9cm \n \image html \7 \n \image latex \7 \"\" width=1.9cm \n \image html \8 \n \image latex \8 \"\" width=1.9cm \n \image html \9 \n \image latex \9 \"\" width=1.9cm \n
      \htmlonly
      \endhtmlonly \n \latexonly \n \endlatexonly \ref fig__\1" \ "cgalFigureBegin{10}=\anchor fig__\1 \n
      \image html \2 \n \image latex \2 \"\" width=1.6cm \n \image html \3 \n \image latex \3 \"\" width=1.6cm \n \image html \4 \n \image latex \4 \"\" width=1.6cm \n \image html \5 \n \image latex \5 \"\" width=1.6cm \n \image html \6 \n \image latex \6 \"\" width=1.6cm \n \image html \7 \n \image latex \7 \"\" width=1.6cm \n \image html \8 \n \image latex \8 \"\" width=1.6cm \n \image html \9 \n \image latex \9 \"\" width=1.6cm \n \image html \10 \n \image latex \10 \"\" width=1.6cm \n
      \htmlonly
      \endhtmlonly \n \latexonly \n \endlatexonly \ref fig__\1" \ - "cgalFigureEnd=\htmlonly
      \endhtmlonly
      " \ + "cgalFigureEnd=\htmlonly

      \endhtmlonly" \ "cgalFigureCaptionBegin{1}=\htmlonly
      \endhtmlonly \ref fig__\1" \ - "cgalFigureCaptionEnd=\htmlonly
      \endhtmlonly
      " \ + "cgalFigureCaptionEnd=\htmlonly

      \endhtmlonly" \ "cgalConcept=\details
      \n \brief" \ "cgalConceptNamespace=\details
      \n \brief" \ "cgalRefines=\xrefitem refines \"Refines\" \"Refinement Relationships\"" \ diff --git a/Documentation/doc/resources/1.8.13/deprecated.html b/Documentation/doc/resources/1.8.13/deprecated.html index 4d8329a9fb2..823d7ea093c 100644 --- a/Documentation/doc/resources/1.8.13/deprecated.html +++ b/Documentation/doc/resources/1.8.13/deprecated.html @@ -1,4 +1,4 @@ - + diff --git a/Documentation/doc/resources/1.8.13/header.html b/Documentation/doc/resources/1.8.13/header.html index 5edbcbc3ec0..f5ed0edf20d 100644 --- a/Documentation/doc/resources/1.8.13/header.html +++ b/Documentation/doc/resources/1.8.13/header.html @@ -1,8 +1,8 @@ - + - + diff --git a/Documentation/doc/resources/1.8.13/header_package.html b/Documentation/doc/resources/1.8.13/header_package.html index a70e9ff6742..46521a96a54 100644 --- a/Documentation/doc/resources/1.8.13/header_package.html +++ b/Documentation/doc/resources/1.8.13/header_package.html @@ -1,8 +1,8 @@ - + - + diff --git a/Documentation/doc/resources/1.8.14/BaseDoxyfile.in b/Documentation/doc/resources/1.8.14/BaseDoxyfile.in index 9bc583f5cd8..56a2538e6dc 100644 --- a/Documentation/doc/resources/1.8.14/BaseDoxyfile.in +++ b/Documentation/doc/resources/1.8.14/BaseDoxyfile.in @@ -242,29 +242,29 @@ ALIASES = "sc{1}=\1File \ref \1 \include \1" \ "cgalFigureAnchor{1}=\anchor fig__\1" \ "cgalFigureRef{1}=\ref fig__\1" \ - "cgalFigureBegin{2}=\anchor fig__\1 ^^ \image html \2 ^^ \image latex \2 \"\" width=15cm ^^ \htmlonly
      \endhtmlonly \latexonly ^^ \endlatexonly ^^ \ref fig__\1" \ - "cgalFigureBegin{3}=\anchor fig__\1 ^^
      \image html \2 ^^ \image latex \2 \"\" width=7.5cm ^^ \image html \3 ^^ \image latex \3 \"\" width=7.5cm ^^
      \htmlonly
      \endhtmlonly ^^ \latexonly ^^ \endlatexonly \ref fig__\1" \ - "cgalFigureBegin{4}=\anchor fig__\1 ^^
      \image html \2 ^^ \image latex \2 \"\" width=5cm ^^ \image html \3 ^^ \image latex \3 \"\" width=5cm ^^ \image html \4 ^^ \image latex \4 \"\" width=5cm ^^
      \htmlonly
      \endhtmlonly ^^ \latexonly ^^ \endlatexonly \ref fig__\1" \ - "cgalFigureBegin{5}=\anchor fig__\1 ^^
      \image html \2 ^^ \image latex \2 \"\" width=3.75cm ^^ \image html \3 ^^ \image latex \3 \"\" width=3.75cm ^^ \image html \4 ^^ \image latex \4 \"\" width=3.75cm ^^ \image html \5 ^^ \image latex \5 \"\" width=3.75cm ^^
      \htmlonly
      \endhtmlonly ^^ \latexonly ^^ \endlatexonly \ref fig__\1" \ - "cgalFigureBegin{6}=\anchor fig__\1 ^^
      \image html \2 ^^ \image latex \2 \"\" width=3cm ^^ \image html \3 ^^ \image latex \3 \"\" width=3cm ^^ \image html \4 ^^ \image latex \4 \"\" width=3cm ^^ \image html \5 ^^ \image latex \5 \"\" width=3cm ^^ \image html \6 ^^ \image latex \6 \"\" width=3cm ^^
      \htmlonly
      \endhtmlonly ^^ \latexonly ^^ \endlatexonly \ref fig__\1" \ - "cgalFigureBegin{7}=\anchor fig__\1 ^^
      \image html \2 ^^ \image latex \2 \"\" width=2.5cm ^^ \image html \3 ^^ \image latex \3 \"\" width=2.5cm ^^ \image html \4 ^^ \image latex \4 \"\" width=2.5cm ^^ \image html \5 ^^ \image latex \5 \"\" width=2.5cm ^^ \image html \6 ^^ \image latex \6 \"\" width=2.5cm ^^ \image html \7 ^^ \image latex \7 \"\" width=2.5cm ^^
      \htmlonly
      \endhtmlonly ^^ \latexonly ^^ \endlatexonly \ref fig__\1" \ - "cgalFigureBegin{8}=\anchor fig__\1 ^^
      \image html \2 ^^ \image latex \2 \"\" width=2.1cm ^^ \image html \3 ^^ \image latex \3 \"\" width=2.1cm ^^ \image html \4 ^^ \image latex \4 \"\" width=2.1cm ^^ \image html \5 ^^ \image latex \5 \"\" width=2.1cm ^^ \image html \6 ^^ \image latex \6 \"\" width=2.1cm ^^ \image html \7 ^^ \image latex \7 \"\" width=2.1cm ^^ \image html \8 ^^ \image latex \8 \"\" width=2.1cm ^^
      \htmlonly
      \endhtmlonly ^^ \latexonly ^^ \endlatexonly \ref fig__\1" \ - "cgalFigureBegin{9}=\anchor fig__\1 ^^
      \image html \2 ^^ \image latex \2 \"\" width=1.9cm ^^ \image html \3 ^^ \image latex \3 \"\" width=1.9cm ^^ \image html \4 ^^ \image latex \4 \"\" width=1.9cm ^^ \image html \5 ^^ \image latex \5 \"\" width=1.9cm ^^ \image html \6 ^^ \image latex \6 \"\" width=1.9cm ^^ \image html \7 ^^ \image latex \7 \"\" width=1.9cm ^^ \image html \8 ^^ \image latex \8 \"\" width=1.9cm ^^ \image html \9 ^^ \image latex \9 \"\" width=1.9cm ^^
      \htmlonly
      \endhtmlonly ^^ \latexonly ^^ \endlatexonly \ref fig__\1" \ - "cgalFigureBegin{10}=\anchor fig__\1 ^^
      \image html \2 ^^ \image latex \2 \"\" width=1.6cm ^^ \image html \3 ^^ \image latex \3 \"\" width=1.6cm ^^ \image html \4 ^^ \image latex \4 \"\" width=1.6cm ^^ \image html \5 ^^ \image latex \5 \"\" width=1.6cm ^^ \image html \6 ^^ \image latex \6 \"\" width=1.6cm ^^ \image html \7 ^^ \image latex \7 \"\" width=1.6cm ^^ \image html \8 ^^ \image latex \8 \"\" width=1.6cm ^^ \image html \9 ^^ \image latex \9 \"\" width=1.6cm ^^ \image html \10 ^^ \image latex \10 \"\" width=1.6cm ^^
      \htmlonly
      \endhtmlonly ^^ \latexonly ^^ \endlatexonly \ref fig__\1" \ - "cgalFigureEnd=\htmlonly
      \endhtmlonly
      " \ - "cgalFigureCaptionBegin{1}=\htmlonly
      \endhtmlonly \ref fig__\1" \ - "cgalFigureCaptionEnd=\htmlonly
      \endhtmlonly
      " \ + "cgalFigureBegin{2}=\anchor fig__\1 ^^ \image html \2 ^^ \image latex \2 \"\" width=15cm ^^ \htmlonly[block]
      \endhtmlonly \latexonly ^^ \endlatexonly ^^ \ref fig__\1" \ + "cgalFigureBegin{3}=\anchor fig__\1 ^^
      \image html \2 ^^ \image latex \2 \"\" width=7.5cm ^^ \image html \3 ^^ \image latex \3 \"\" width=7.5cm ^^
      \htmlonly[block]
      \endhtmlonly ^^ \latexonly ^^ \endlatexonly \ref fig__\1" \ + "cgalFigureBegin{4}=\anchor fig__\1 ^^
      \image html \2 ^^ \image latex \2 \"\" width=5cm ^^ \image html \3 ^^ \image latex \3 \"\" width=5cm ^^ \image html \4 ^^ \image latex \4 \"\" width=5cm ^^
      \htmlonly[block]
      \endhtmlonly ^^ \latexonly ^^ \endlatexonly \ref fig__\1" \ + "cgalFigureBegin{5}=\anchor fig__\1 ^^
      \image html \2 ^^ \image latex \2 \"\" width=3.75cm ^^ \image html \3 ^^ \image latex \3 \"\" width=3.75cm ^^ \image html \4 ^^ \image latex \4 \"\" width=3.75cm ^^ \image html \5 ^^ \image latex \5 \"\" width=3.75cm ^^
      \htmlonly[block]
      \endhtmlonly ^^ \latexonly ^^ \endlatexonly \ref fig__\1" \ + "cgalFigureBegin{6}=\anchor fig__\1 ^^
      \image html \2 ^^ \image latex \2 \"\" width=3cm ^^ \image html \3 ^^ \image latex \3 \"\" width=3cm ^^ \image html \4 ^^ \image latex \4 \"\" width=3cm ^^ \image html \5 ^^ \image latex \5 \"\" width=3cm ^^ \image html \6 ^^ \image latex \6 \"\" width=3cm ^^
      \htmlonly[block]
      \endhtmlonly ^^ \latexonly ^^ \endlatexonly \ref fig__\1" \ + "cgalFigureBegin{7}=\anchor fig__\1 ^^
      \image html \2 ^^ \image latex \2 \"\" width=2.5cm ^^ \image html \3 ^^ \image latex \3 \"\" width=2.5cm ^^ \image html \4 ^^ \image latex \4 \"\" width=2.5cm ^^ \image html \5 ^^ \image latex \5 \"\" width=2.5cm ^^ \image html \6 ^^ \image latex \6 \"\" width=2.5cm ^^ \image html \7 ^^ \image latex \7 \"\" width=2.5cm ^^
      \htmlonly[block]
      \endhtmlonly ^^ \latexonly ^^ \endlatexonly \ref fig__\1" \ + "cgalFigureBegin{8}=\anchor fig__\1 ^^
      \image html \2 ^^ \image latex \2 \"\" width=2.1cm ^^ \image html \3 ^^ \image latex \3 \"\" width=2.1cm ^^ \image html \4 ^^ \image latex \4 \"\" width=2.1cm ^^ \image html \5 ^^ \image latex \5 \"\" width=2.1cm ^^ \image html \6 ^^ \image latex \6 \"\" width=2.1cm ^^ \image html \7 ^^ \image latex \7 \"\" width=2.1cm ^^ \image html \8 ^^ \image latex \8 \"\" width=2.1cm ^^
      \htmlonly[block]
      \endhtmlonly ^^ \latexonly ^^ \endlatexonly \ref fig__\1" \ + "cgalFigureBegin{9}=\anchor fig__\1 ^^
      \image html \2 ^^ \image latex \2 \"\" width=1.9cm ^^ \image html \3 ^^ \image latex \3 \"\" width=1.9cm ^^ \image html \4 ^^ \image latex \4 \"\" width=1.9cm ^^ \image html \5 ^^ \image latex \5 \"\" width=1.9cm ^^ \image html \6 ^^ \image latex \6 \"\" width=1.9cm ^^ \image html \7 ^^ \image latex \7 \"\" width=1.9cm ^^ \image html \8 ^^ \image latex \8 \"\" width=1.9cm ^^ \image html \9 ^^ \image latex \9 \"\" width=1.9cm ^^
      \htmlonly[block]
      \endhtmlonly ^^ \latexonly ^^ \endlatexonly \ref fig__\1" \ + "cgalFigureBegin{10}=\anchor fig__\1 ^^
      \image html \2 ^^ \image latex \2 \"\" width=1.6cm ^^ \image html \3 ^^ \image latex \3 \"\" width=1.6cm ^^ \image html \4 ^^ \image latex \4 \"\" width=1.6cm ^^ \image html \5 ^^ \image latex \5 \"\" width=1.6cm ^^ \image html \6 ^^ \image latex \6 \"\" width=1.6cm ^^ \image html \7 ^^ \image latex \7 \"\" width=1.6cm ^^ \image html \8 ^^ \image latex \8 \"\" width=1.6cm ^^ \image html \9 ^^ \image latex \9 \"\" width=1.6cm ^^ \image html \10 ^^ \image latex \10 \"\" width=1.6cm ^^
      \htmlonly[block]
      \endhtmlonly ^^ \latexonly ^^ \endlatexonly \ref fig__\1" \ + "cgalFigureEnd=\htmlonly[block]
      \endhtmlonly
      " \ + "cgalFigureCaptionBegin{1}=\htmlonly[block]
      \endhtmlonly \ref fig__\1" \ + "cgalFigureCaptionEnd=\htmlonly[block]
      \endhtmlonly
      " \ "cgalConcept=\details
      ^^ \brief" \ "cgalConceptNamespace=\details
      ^^ \brief" \ "cgalRefines=\xrefitem refines \"Refines\" \"Refinement Relationships\"" \ "cgalModels=\xrefitem models \"Is Model Of\" \"Is Model Relationships\"" \ "cgalGeneralizes=\xrefitem generalizes \"Generalizes\" \"Generalization Relationships\"" \ "cgalHasModel=\xrefitem hasModels \"Has Models\" \"Has Model Relationships\"" \ - "cgalDebugBegin=\htmlonly
      Debugging Support
      \endhtmlonly ^^" \ - "cgalDebugEnd=\htmlonly
      \endhtmlonly" \ + "cgalDebugBegin=\htmlonly[block]
      Debugging Support
      \endhtmlonly ^^" \ + "cgalDebugEnd=\htmlonly[block]
      \endhtmlonly" \ "cgalDebugFunction=This is a function for debugging purpose." \ - "cgalAdvancedBegin=\htmlonly
      Advanced
      \endhtmlonly ^^" \ - "cgalAdvancedEnd=\htmlonly
      \endhtmlonly" \ + "cgalAdvancedBegin=\htmlonly[block]
      Advanced
      \endhtmlonly ^^" \ + "cgalAdvancedEnd=\htmlonly[block]
      \endhtmlonly" \ "cgalAdvancedFunction=This is an advanced function." \ "cgalAdvancedClass=This is an advanced class." \ "cgalRequiresCPP11=\warning This function requires a C++11 compiler." \ @@ -287,11 +287,11 @@ ALIASES = "sc{1}=\1 \endhtmlonly \latexonly END MODIFICATIONS \endlatexonly" \ "cgalPkgBib{1}=BibTeX: \1-${CGAL_RELEASE_YEAR_ID}
      " \ "cgalFootnote{1}=\1" \ - "cgalAutoToc=\htmlonly
      \endhtmlonly" \ + "cgalAutoToc=\htmlonly[block]
      \endhtmlonly" \ "cgalTagTrue=\link CGAL::Tag_true `CGAL::Tag_true`\endlink" \ "cgalTagFalse=\link CGAL::Tag_false `CGAL::Tag_false`\endlink" \ "cgalHeading{1}= \1
      " \ - "cgalClassifedRefPages=\htmlonly

      Classified Reference Pages

      \endhtmlonly" \ + "cgalClassifedRefPages=\htmlonly[block]

      Classified Reference Pages

      \endhtmlonly" \ "cgalCite{1}=\cite \1" # This tag can be used to specify a number of word-keyword mappings (TCL only). diff --git a/Documentation/doc/resources/1.8.14/deprecated.html b/Documentation/doc/resources/1.8.14/deprecated.html index 60d1c4e90bc..a8baa72c005 100644 --- a/Documentation/doc/resources/1.8.14/deprecated.html +++ b/Documentation/doc/resources/1.8.14/deprecated.html @@ -1,4 +1,4 @@ - + diff --git a/Documentation/doc/resources/1.8.14/header.html b/Documentation/doc/resources/1.8.14/header.html index 5edbcbc3ec0..f5ed0edf20d 100644 --- a/Documentation/doc/resources/1.8.14/header.html +++ b/Documentation/doc/resources/1.8.14/header.html @@ -1,8 +1,8 @@ - + - + diff --git a/Documentation/doc/resources/1.8.14/header_package.html b/Documentation/doc/resources/1.8.14/header_package.html index a70e9ff6742..df3a1bcba36 100644 --- a/Documentation/doc/resources/1.8.14/header_package.html +++ b/Documentation/doc/resources/1.8.14/header_package.html @@ -1,8 +1,8 @@ - + - + diff --git a/Documentation/doc/resources/1.8.4/deprecated.html b/Documentation/doc/resources/1.8.4/deprecated.html index 4d8329a9fb2..823d7ea093c 100644 --- a/Documentation/doc/resources/1.8.4/deprecated.html +++ b/Documentation/doc/resources/1.8.4/deprecated.html @@ -1,4 +1,4 @@ - + diff --git a/Documentation/doc/resources/1.8.4/header.html b/Documentation/doc/resources/1.8.4/header.html index b125e40186c..4b0aae2bff8 100644 --- a/Documentation/doc/resources/1.8.4/header.html +++ b/Documentation/doc/resources/1.8.4/header.html @@ -1,7 +1,7 @@ - + - + $projectname: $title diff --git a/Documentation/doc/resources/1.8.4/header_package.html b/Documentation/doc/resources/1.8.4/header_package.html index 65b3e1d9eac..37a9f67fdca 100644 --- a/Documentation/doc/resources/1.8.4/header_package.html +++ b/Documentation/doc/resources/1.8.4/header_package.html @@ -1,7 +1,7 @@ - + - + $projectname: $title diff --git a/Documentation/doc/scripts/html_output_post_processing.py b/Documentation/doc/scripts/html_output_post_processing.py index c2a0b34941f..e89c7e7b61a 100755 --- a/Documentation/doc/scripts/html_output_post_processing.py +++ b/Documentation/doc/scripts/html_output_post_processing.py @@ -62,7 +62,7 @@ def conceptify_ns(d): def write_out_html(d, fn): f = codecs.open(fn, 'w', encoding='utf-8') # this is the normal doxygen doctype, which is thrown away by pyquery - f.write('\n') + f.write('\n') f.write('') f.write(d.html()) f.write('\n') diff --git a/Generator/doc/Generator/Generator.txt b/Generator/doc/Generator/Generator.txt index 138c4a7a7a5..cadcc924ab8 100644 --- a/Generator/doc/Generator/Generator.txt +++ b/Generator/doc/Generator/Generator.txt @@ -277,7 +277,7 @@ triangle (2D and 3D) and in tetrahedra (3D). Basically, in order to generate a random point in a \f$N\f$-simplex (a triangle for \f$N = 2\f$, and tetrahedron for \f$N = 3\f$), we generate numbers \f$a_1,a_2,\ldots,a_N\f$ identically and independently uniformly distributed in \f$(0,1)\f$, we sort them, we let \f$a_0 = 0\f$ and \f$a_{N+1} = 1\f$, -and then \f$a_{i+1}−a_i\f$, for \f$i = 1,\ldots,N\f$ becomes its +and then \f$a_{i+1}-a_i\f$, for \f$i = 1,\ldots,N\f$ becomes its barycentric coordinates with respect to the simplex. Maxime Gimemo introduced the random generators on 2D and 3D triangle meshes. diff --git a/Generator/include/CGAL/point_generators_d.h b/Generator/include/CGAL/point_generators_d.h index 1cc01033b5d..c7f40cbf5a7 100644 --- a/Generator/include/CGAL/point_generators_d.h +++ b/Generator/include/CGAL/point_generators_d.h @@ -151,6 +151,7 @@ void Random_points_in_cube_d

      :: generate_point() { typedef typename Kernel_traits

      ::Kernel::RT RT; + CGAL_assume(dimension>0); std::vector coord(dimension); for(int i=0; id_range * ( 2 * this->_rnd.get_double() - 1.0)); diff --git a/Generator/test/Generator/generic_random_test.cpp b/Generator/test/Generator/generic_random_test.cpp index 7ea066f4233..3090ddbfc80 100644 --- a/Generator/test/Generator/generic_random_test.cpp +++ b/Generator/test/Generator/generic_random_test.cpp @@ -288,8 +288,10 @@ int main() Polyhedron polyhedron; // A cube - make_hexahedron(Point_3(-0.5,-0.5,-0.5), Point_3(0.5,-0.5,-0.5), Point_3(0.5,0.5,-0.5), Point_3(-0.5,0.5,-0.5), - Point_3(-0.5,0.5,0.5), Point_3(-0.5,-0.5,0.5), Point_3(0.5,-0.5,0.5), Point_3(0.5,0.5,0.5), + make_hexahedron( + Point_3(-0.5,-0.5,-0.5), Point_3(0.5,-0.5,-0.5), Point_3(0.5,0.5,-0.5), + Point_3(-0.5,0.5,-0.5), Point_3(-0.5,0.5,0.5), Point_3(-0.5,-0.5,0.5), + Point_3(0.5,-0.5,0.5), Point_3(0.5,0.5,0.5), polyhedron); boost::graph_traits::halfedge_descriptor facets[6]; diff --git a/Geomview/doc/Geomview/CGAL/IO/Geomview_stream.h b/Geomview/doc/Geomview/CGAL/IO/Geomview_stream.h index d189bb8367f..a93f3b86950 100644 --- a/Geomview/doc/Geomview/CGAL/IO/Geomview_stream.h +++ b/Geomview/doc/Geomview/CGAL/IO/Geomview_stream.h @@ -363,19 +363,6 @@ operator<<(Geomview_stream& gs, const Bbox_2& b); Geomview_stream& operator<<(Geomview_stream& gs, const Bbox_3& b); -/*! - Inserts the bounding box `b` into the stream `gs`. - \relates Geomview_stream -*/ -Geomview_stream& -operator<<(Geomview_stream& gs, const Bbox_3& b); - -/*! - Inserts the bounding box `b` into the stream `gs`. - \relates Geomview_stream -*/ -Geomview_stream& -operator<<(Geomview_stream& gs, const Bbox_3& b); /// @} diff --git a/GraphicsView/demo/Alpha_shapes_2/CMakeLists.txt b/GraphicsView/demo/Alpha_shapes_2/CMakeLists.txt index af389e5aa20..37dde3bd982 100644 --- a/GraphicsView/demo/Alpha_shapes_2/CMakeLists.txt +++ b/GraphicsView/demo/Alpha_shapes_2/CMakeLists.txt @@ -9,6 +9,10 @@ if(NOT POLICY CMP0070 AND POLICY CMP0053) cmake_policy(SET CMP0053 OLD) endif() +if(POLICY CMP0071) + cmake_policy(SET CMP0071 NEW) +endif() + find_package(CGAL COMPONENTS Qt5) find_package(Qt5 QUIET COMPONENTS Xml Script OpenGL Svg) diff --git a/GraphicsView/demo/Apollonius_graph_2/CMakeLists.txt b/GraphicsView/demo/Apollonius_graph_2/CMakeLists.txt index 1a858439904..81032979285 100644 --- a/GraphicsView/demo/Apollonius_graph_2/CMakeLists.txt +++ b/GraphicsView/demo/Apollonius_graph_2/CMakeLists.txt @@ -9,6 +9,10 @@ if(NOT POLICY CMP0070 AND POLICY CMP0053) cmake_policy(SET CMP0053 OLD) endif() +if(POLICY CMP0071) + cmake_policy(SET CMP0071 NEW) +endif() + find_package(CGAL COMPONENTS Qt5) find_package(Qt5 QUIET COMPONENTS Xml Script OpenGL Svg) diff --git a/GraphicsView/demo/Bounding_volumes/CMakeLists.txt b/GraphicsView/demo/Bounding_volumes/CMakeLists.txt index 2ac22c9815b..3226cd34f12 100644 --- a/GraphicsView/demo/Bounding_volumes/CMakeLists.txt +++ b/GraphicsView/demo/Bounding_volumes/CMakeLists.txt @@ -9,6 +9,10 @@ if(NOT POLICY CMP0070 AND POLICY CMP0053) cmake_policy(SET CMP0053 OLD) endif() +if(POLICY CMP0071) + cmake_policy(SET CMP0071 NEW) +endif() + find_package(CGAL COMPONENTS Qt5) find_package(Qt5 QUIET COMPONENTS Xml Script OpenGL Svg) diff --git a/GraphicsView/demo/Circular_kernel_2/CMakeLists.txt b/GraphicsView/demo/Circular_kernel_2/CMakeLists.txt index 60a6c359d4c..42b93286ba8 100644 --- a/GraphicsView/demo/Circular_kernel_2/CMakeLists.txt +++ b/GraphicsView/demo/Circular_kernel_2/CMakeLists.txt @@ -9,6 +9,10 @@ if(NOT POLICY CMP0070 AND POLICY CMP0053) cmake_policy(SET CMP0053 OLD) endif() +if(POLICY CMP0071) + cmake_policy(SET CMP0071 NEW) +endif() + find_package(CGAL COMPONENTS Qt5) diff --git a/GraphicsView/demo/Generator/CMakeLists.txt b/GraphicsView/demo/Generator/CMakeLists.txt index 53b33e71048..bd373d9f2f8 100644 --- a/GraphicsView/demo/Generator/CMakeLists.txt +++ b/GraphicsView/demo/Generator/CMakeLists.txt @@ -8,6 +8,10 @@ if(NOT POLICY CMP0070 AND POLICY CMP0053) cmake_policy(SET CMP0053 OLD) endif() +if(POLICY CMP0071) + cmake_policy(SET CMP0071 NEW) +endif() + find_package(CGAL COMPONENTS Qt5) find_package(Qt5 QUIET COMPONENTS Xml Script OpenGL Svg) diff --git a/GraphicsView/demo/GraphicsView/CMakeLists.txt b/GraphicsView/demo/GraphicsView/CMakeLists.txt index 5f92ac528dc..68f0d001b0a 100644 --- a/GraphicsView/demo/GraphicsView/CMakeLists.txt +++ b/GraphicsView/demo/GraphicsView/CMakeLists.txt @@ -8,6 +8,10 @@ if(NOT POLICY CMP0070 AND POLICY CMP0053) cmake_policy(SET CMP0053 OLD) endif() +if(POLICY CMP0071) + cmake_policy(SET CMP0071 NEW) +endif() + find_package(CGAL COMPONENTS Qt5) find_package(Qt5 QUIET COMPONENTS Xml Script OpenGL Svg) diff --git a/GraphicsView/demo/L1_Voronoi_diagram_2/CMakeLists.txt b/GraphicsView/demo/L1_Voronoi_diagram_2/CMakeLists.txt index 9903f9ca190..1b901707799 100644 --- a/GraphicsView/demo/L1_Voronoi_diagram_2/CMakeLists.txt +++ b/GraphicsView/demo/L1_Voronoi_diagram_2/CMakeLists.txt @@ -9,6 +9,10 @@ if(NOT POLICY CMP0070 AND POLICY CMP0053) cmake_policy(SET CMP0053 OLD) endif() +if(POLICY CMP0071) + cmake_policy(SET CMP0071 NEW) +endif() + find_package(CGAL COMPONENTS Qt5) find_package(Qt5 QUIET COMPONENTS Xml Script OpenGL Svg) diff --git a/GraphicsView/demo/Largest_empty_rect_2/CMakeLists.txt b/GraphicsView/demo/Largest_empty_rect_2/CMakeLists.txt index 1faba1f18d0..13abece7acf 100644 --- a/GraphicsView/demo/Largest_empty_rect_2/CMakeLists.txt +++ b/GraphicsView/demo/Largest_empty_rect_2/CMakeLists.txt @@ -9,6 +9,10 @@ if(NOT POLICY CMP0070 AND POLICY CMP0053) cmake_policy(SET CMP0053 OLD) endif() +if(POLICY CMP0071) + cmake_policy(SET CMP0071 NEW) +endif() + find_package(CGAL COMPONENTS Qt5) find_package(Qt5 QUIET COMPONENTS Xml Script OpenGL Svg) diff --git a/GraphicsView/demo/Periodic_2_triangulation_2/CMakeLists.txt b/GraphicsView/demo/Periodic_2_triangulation_2/CMakeLists.txt index 6e2d6348e65..7e1d94d806e 100644 --- a/GraphicsView/demo/Periodic_2_triangulation_2/CMakeLists.txt +++ b/GraphicsView/demo/Periodic_2_triangulation_2/CMakeLists.txt @@ -6,6 +6,10 @@ if(NOT POLICY CMP0070 AND POLICY CMP0053) cmake_policy(SET CMP0053 OLD) endif() +if(POLICY CMP0071) + cmake_policy(SET CMP0071 NEW) +endif() + find_package(CGAL COMPONENTS Qt5) @@ -30,12 +34,6 @@ qt5_add_resources ( CGAL_Qt5_RESOURCE_FILES ./Periodic_2_triangulation_2.qrc ) qt5_generate_moc( Periodic_2_Delaunay_triangulation_2.cpp Periodic_2_triangulation_2.moc ) # find header files for projects that can show them - -cmake_minimum_required(VERSION 3.1) -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() file(GLOB headers "*.h") file(GLOB QT_headers "include/CGAL/Qt/*.h") file(GLOB P2T2_headers "../../../include/CGAL/*.h") diff --git a/GraphicsView/demo/Polygon/CMakeLists.txt b/GraphicsView/demo/Polygon/CMakeLists.txt index 0e4e0a01d38..33e16c25117 100644 --- a/GraphicsView/demo/Polygon/CMakeLists.txt +++ b/GraphicsView/demo/Polygon/CMakeLists.txt @@ -9,6 +9,10 @@ if(NOT POLICY CMP0070 AND POLICY CMP0053) cmake_policy(SET CMP0053 OLD) endif() +if(POLICY CMP0071) + cmake_policy(SET CMP0071 NEW) +endif() + find_package(CGAL COMPONENTS Qt5 Core) find_package(Eigen3 3.1.0) #(requires 3.1.0 or greater) diff --git a/GraphicsView/demo/Segment_Delaunay_graph_2/CMakeLists.txt b/GraphicsView/demo/Segment_Delaunay_graph_2/CMakeLists.txt index a2fd30a9230..97af016cffd 100644 --- a/GraphicsView/demo/Segment_Delaunay_graph_2/CMakeLists.txt +++ b/GraphicsView/demo/Segment_Delaunay_graph_2/CMakeLists.txt @@ -9,6 +9,10 @@ if(NOT POLICY CMP0070 AND POLICY CMP0053) cmake_policy(SET CMP0053 OLD) endif() +if(POLICY CMP0071) + cmake_policy(SET CMP0071 NEW) +endif() + find_package(CGAL COMPONENTS Qt5 Core) set( QT_USE_QTXML TRUE ) diff --git a/GraphicsView/demo/Segment_Delaunay_graph_Linf_2/CMakeLists.txt b/GraphicsView/demo/Segment_Delaunay_graph_Linf_2/CMakeLists.txt index 03685cdbfef..556e8577984 100644 --- a/GraphicsView/demo/Segment_Delaunay_graph_Linf_2/CMakeLists.txt +++ b/GraphicsView/demo/Segment_Delaunay_graph_Linf_2/CMakeLists.txt @@ -9,6 +9,10 @@ if(NOT POLICY CMP0070 AND POLICY CMP0053) cmake_policy(SET CMP0053 OLD) endif() +if(POLICY CMP0071) + cmake_policy(SET CMP0071 NEW) +endif() + find_package(CGAL COMPONENTS Qt5 Core) set( QT_USE_QTXML TRUE ) diff --git a/GraphicsView/demo/Snap_rounding_2/CMakeLists.txt b/GraphicsView/demo/Snap_rounding_2/CMakeLists.txt index d19002e1bd4..2d0631da561 100644 --- a/GraphicsView/demo/Snap_rounding_2/CMakeLists.txt +++ b/GraphicsView/demo/Snap_rounding_2/CMakeLists.txt @@ -9,6 +9,10 @@ if(NOT POLICY CMP0070 AND POLICY CMP0053) cmake_policy(SET CMP0053 OLD) endif() +if(POLICY CMP0071) + cmake_policy(SET CMP0071 NEW) +endif() + find_package(CGAL COMPONENTS Qt5) find_package(Qt5 QUIET COMPONENTS Xml Script OpenGL Svg) diff --git a/GraphicsView/demo/Spatial_searching_2/CMakeLists.txt b/GraphicsView/demo/Spatial_searching_2/CMakeLists.txt index b3aaa8bd452..63f2a37ffe5 100644 --- a/GraphicsView/demo/Spatial_searching_2/CMakeLists.txt +++ b/GraphicsView/demo/Spatial_searching_2/CMakeLists.txt @@ -9,6 +9,10 @@ if(NOT POLICY CMP0070 AND POLICY CMP0053) cmake_policy(SET CMP0053 OLD) endif() +if(POLICY CMP0071) + cmake_policy(SET CMP0071 NEW) +endif() + find_package(CGAL COMPONENTS Qt5) find_package(Qt5 QUIET COMPONENTS Xml Script OpenGL Svg) diff --git a/GraphicsView/demo/Stream_lines_2/CMakeLists.txt b/GraphicsView/demo/Stream_lines_2/CMakeLists.txt index 999e107fbbf..a9bf93ac1fe 100644 --- a/GraphicsView/demo/Stream_lines_2/CMakeLists.txt +++ b/GraphicsView/demo/Stream_lines_2/CMakeLists.txt @@ -9,6 +9,10 @@ if(NOT POLICY CMP0070 AND POLICY CMP0053) cmake_policy(SET CMP0053 OLD) endif() +if(POLICY CMP0071) + cmake_policy(SET CMP0071 NEW) +endif() + find_package(CGAL COMPONENTS Qt5) diff --git a/GraphicsView/include/CGAL/Buffer_for_vao.h b/GraphicsView/include/CGAL/Buffer_for_vao.h index b7658d45021..a0148cd4c0b 100644 --- a/GraphicsView/include/CGAL/Buffer_for_vao.h +++ b/GraphicsView/include/CGAL/Buffer_for_vao.h @@ -426,25 +426,7 @@ public: 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()); - if(std::isnan(S.x()) || - std::isnan(S.y()) || - std::isnan(S.z())) - { - return false; - } - if(std::isnan(T.x()) || - std::isnan(T.y()) || - std::isnan(T.z())) - { - return false; - } - const Local_point& U=facet[(id+2==facet.size())?0:id+2]; - if(std::isnan(U.x()) || - std::isnan(U.y()) || - std::isnan(U.z())) - { - return false; - } + const Local_point& U=facet[(id+2>=facet.size())?id+2-facet.size():id+2]; Local_vector V2=Local_vector((U-T).x(), (U-T).y(), (U-T).z()); orientation = Local_kernel::Orientation_3()(V1, V2, normal); @@ -465,7 +447,7 @@ public: 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]; + const Local_point& U=facet[(id+2>=facet.size())?id+2-facet.size():id+2]; Local_vector V2=Local_vector((U-T).x(), (U-T).y(), (U-T).z()); local_orientation=Local_kernel::Orientation_3()(V1, V2, normal) ; diff --git a/GraphicsView/include/CGAL/Qt/Basic_viewer_qt.h b/GraphicsView/include/CGAL/Qt/Basic_viewer_qt.h index de17e0d32f5..18213239d26 100644 --- a/GraphicsView/include/CGAL/Qt/Basic_viewer_qt.h +++ b/GraphicsView/include/CGAL/Qt/Basic_viewer_qt.h @@ -740,7 +740,7 @@ protected: 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_M, "Toggles mono color"); setKeyDescription(::Qt::Key_N, "Inverse direction of normals"); setKeyDescription(::Qt::Key_V, "Toggles vertices display"); setKeyDescription(::Qt::Key_Plus, "Increase size of edges"); @@ -935,8 +935,11 @@ protected: } virtual QString helpString() const + { return helpString("CGAL Basic Viewer"); } + + virtual QString helpString(const char* title) const { - QString text("

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

      "); + QString text(QString("

      ")+QString(title)+QString("

      ")); 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. "; @@ -966,7 +969,7 @@ protected: return text; } -private: +protected: bool m_draw_vertices; bool m_draw_edges; bool m_draw_faces; diff --git a/Installation/CHANGES.md b/Installation/CHANGES.md index e9f1e07defa..6c988b63b82 100644 --- a/Installation/CHANGES.md +++ b/Installation/CHANGES.md @@ -37,6 +37,14 @@ Release date: March 2019 - Added the class `CGAL::Rigid_triangle_mesh_collision_detection` to detect intersections between meshes and volumes undergoing affine transformations. +### Point Set Processing + +- `CGAL::mst_orient_normals()` can now be called with a set of user-selected + seed points that are known to be already oriented. A new optional named + parameter `point_is_constrained_map` is added for this purpose. The + original behavior (using one unique and automatically selected seed) is + kept if this parameter is not used. + ### 3D Fast Intersection and Distance Computation - The primitives `AABB_face_graph_triangle_primitive` and @@ -59,6 +67,10 @@ Release date: March 2019 `Arr_polyline_traits_2`, `Arr_polycurve_traits_2`, and `Arr_polycurve_basic_traits_2`. +### CGAL and the Boost Graph Library (BGL) + +- Add function `write_wrl()` for writing into VRML 2.0 format. + Release 4.13 ------------ diff --git a/Installation/cmake/modules/CGAL_UseLEDA.cmake b/Installation/cmake/modules/CGAL_UseLEDA.cmake index ead5900736c..70474f24a29 100644 --- a/Installation/cmake/modules/CGAL_UseLEDA.cmake +++ b/Installation/cmake/modules/CGAL_UseLEDA.cmake @@ -21,9 +21,6 @@ if ( LEDA_FOUND AND NOT LEDA_SETUP ) link_libraries( ${LEDA_LIBRARIES} ) endif() - if (LEDA_CGAL_FRIEND_INJECTION) - message( STATUS "${LEDA_CGAL_FRIEND_INJECTION}" ) - endif() if (LEDA_CGAL_NO_STRICT_ALIASING) message( STATUS "${LEDA_CGAL_NO_STRICT_ALIASING}" ) endif() diff --git a/Installation/cmake/modules/CGAL_add_test.cmake b/Installation/cmake/modules/CGAL_add_test.cmake index 79bef011112..2f0aec7163a 100644 --- a/Installation/cmake/modules/CGAL_add_test.cmake +++ b/Installation/cmake/modules/CGAL_add_test.cmake @@ -42,7 +42,7 @@ endif() # Process a list, and replace items contains a file pattern (like # `*.off`) by the sublist that corresponds to the globbing of the -# pattern in the directory `${CGAL_CURRENT_SOURCE_DIR}`. +# pattern in the directory `${CMAKE_CURRENT_SOURCE_DIR}`. # # # For example: the `file @@ -71,7 +71,7 @@ function(expand_list_with_globbing list_name) list(GET input_list ${n} item_n) # message(STATUS "argument ${n} is ${item_n}") if(item_n MATCHES ".*\\*.*") - file(GLOB files RELATIVE ${CGAL_CURRENT_SOURCE_DIR} ${item_n}) + file(GLOB files RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${item_n}) list(APPEND output_list ${files}) else() list(APPEND output_list ${item_n}) @@ -97,7 +97,7 @@ function(cgal_setup_test_properties test_name) endif() set_property(TEST "${test_name}" APPEND PROPERTY LABELS "${PROJECT_NAME}") - # message(STATUS " working dir: ${CGAL_CURRENT_SOURCE_DIR}") + # message(STATUS " working dir: ${CMAKE_CURRENT_SOURCE_DIR}") set_property(TEST "${test_name}" PROPERTY WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) if(exe_name) @@ -198,7 +198,7 @@ function(cgal_add_test exe_name) return() endif() # message("Add test ${test_name}") - set(cin_file "${CGAL_CURRENT_SOURCE_DIR}/${exe_name}.cin") + set(cin_file "${CMAKE_CURRENT_SOURCE_DIR}/${exe_name}.cin") if(NOT ARGS AND EXISTS ${cin_file}) add_test(NAME ${test_name} COMMAND ${TIME_COMMAND} ${CMAKE_COMMAND} @@ -213,11 +213,11 @@ function(cgal_add_test exe_name) else() if(NOT ARGS AND NOT cgal_add_test_TEST_NAME) if(ARGC GREATER 2 AND ARGV2) - set(cmd_file "${CGAL_CURRENT_SOURCE_DIR}/${ARGV2}.cmd") + set(cmd_file "${CMAKE_CURRENT_SOURCE_DIR}/${ARGV2}.cmd") elseif(ARGC GREATER 1 AND ARGV1 AND NOT EXISTS ${cmd_file}) - set(cmd_file "${CGAL_CURRENT_SOURCE_DIR}/${ARGV1}.cmd") + set(cmd_file "${CMAKE_CURRENT_SOURCE_DIR}/${ARGV1}.cmd") elseif(NOT EXISTS ${cmd_file}) - set(cmd_file "${CGAL_CURRENT_SOURCE_DIR}/${exe_name}.cmd") + set(cmd_file "${CMAKE_CURRENT_SOURCE_DIR}/${exe_name}.cmd") endif() if(EXISTS ${cmd_file}) file(STRINGS "${cmd_file}" CMD_LINES) diff --git a/Installation/cmake/modules/FindLEDA.cmake b/Installation/cmake/modules/FindLEDA.cmake index 1fc99eeecc3..9c50f51807a 100644 --- a/Installation/cmake/modules/FindLEDA.cmake +++ b/Installation/cmake/modules/FindLEDA.cmake @@ -92,11 +92,6 @@ if ( LEDA_INCLUDE_DIR AND LEDA_LIBRARIES) if ( CMAKE_COMPILER_IS_GNUCXX ) get_dependency_version (GCC) - if ( NOT "${GCC_VERSION}" VERSION_LESS "4.1" ) - set(LEDA_CGAL_FRIEND_INJECTION TRUE) - typed_cache_set( INTERNAL "Add -ffriend-injection on gcc >= 4.1" LEDA_CGAL_FRIEND_INJECTION "Using LEDA with gcc version 4.1 or later: Adding -ffriend-injection") - uniquely_add_flags (LEDA_CXX_FLAGS "-ffriend-injection") - endif() if ( NOT "${GCC_VERSION}" VERSION_LESS "4.4" ) set(LEDA_CGAL_NO_STRICT_ALIASING TRUE) typed_cache_set( INTERNAL "Add -fno-strict-aliasing on gcc >= 4.4" LEDA_CGAL_NO_STRICT_ALIASING "Using LEDA with gcc version 4.4 or later: Adding -fno-strict-aliasing") diff --git a/Installation/cmake/modules/UseCGAL.cmake b/Installation/cmake/modules/UseCGAL.cmake index 5128023cc5d..0187802b524 100644 --- a/Installation/cmake/modules/UseCGAL.cmake +++ b/Installation/cmake/modules/UseCGAL.cmake @@ -9,11 +9,6 @@ include(${CGAL_MODULES_DIR}/CGAL_Macros.cmake) cgal_setup_module_path() -# Save the current source directory. That variable can be changed by -# a `CMakeLists.txt`, for `CMakeLists.txt` files that are created in -# the binary directory. -set(CGAL_CURRENT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) - if(NOT USE_CGAL_FILE_INCLUDED) set(USE_CGAL_FILE_INCLUDED 1) diff --git a/Installation/lib/cmake/CGAL/CGALConfig.cmake b/Installation/lib/cmake/CGAL/CGALConfig.cmake index 486f1ff6746..0cb7f0326bb 100644 --- a/Installation/lib/cmake/CGAL/CGALConfig.cmake +++ b/Installation/lib/cmake/CGAL/CGALConfig.cmake @@ -11,11 +11,6 @@ get_filename_component(CGAL_CONFIG_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) set(CGAL_HEADER_ONLY TRUE) -# Save the current source directory. That variable can be changed by -# a `CMakeLists.txt`, for `CMakeLists.txt` files that are created in -# the binary directory. -set(CGAL_CURRENT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) - function(cgal_detect_branch_build VAR_NAME) if(IS_DIRECTORY ${CGAL_CONFIG_DIR}/../../../../Installation/package_info/Installation/) set(${VAR_NAME} TRUE PARENT_SCOPE) @@ -26,7 +21,11 @@ endfunction() cgal_detect_branch_build(BRANCH_BUILD) if(BRANCH_BUILD) - set(CGAL_ROOT ${CGAL_CONFIG_DIR}/../../../..) + set(CGAL_ROOT ${CGAL_CONFIG_DIR}) + get_filename_component(CGAL_ROOT "${CGAL_ROOT}" DIRECTORY) + get_filename_component(CGAL_ROOT "${CGAL_ROOT}" DIRECTORY) + get_filename_component(CGAL_ROOT "${CGAL_ROOT}" DIRECTORY) + get_filename_component(CGAL_ROOT "${CGAL_ROOT}" DIRECTORY) set(CGAL_INSTALLATION_PACKAGE_DIR ${CGAL_ROOT}/Installation) set(CGAL_GRAPHICSVIEW_PACKAGE_DIR ${CGAL_ROOT}/GraphicsView) set(CGAL_MODULES_DIR ${CGAL_ROOT}/Installation/cmake/modules) @@ -43,7 +42,10 @@ if(BRANCH_BUILD) endif() endforeach() else() - set(CGAL_ROOT ${CGAL_CONFIG_DIR}/../../..) + set(CGAL_ROOT ${CGAL_CONFIG_DIR}) + get_filename_component(CGAL_ROOT "${CGAL_ROOT}" DIRECTORY) + get_filename_component(CGAL_ROOT "${CGAL_ROOT}" DIRECTORY) + get_filename_component(CGAL_ROOT "${CGAL_ROOT}" DIRECTORY) # not BRANCH_BUILD: it can be an installed CGAL, or the tarball layout if(EXISTS ${CGAL_CONFIG_DIR}/CGAL_add_test.cmake) @@ -66,6 +68,9 @@ include(${CGAL_MODULES_DIR}/CGAL_CreateSingleSourceCGALProgram.cmake) include(${CGAL_MODULES_DIR}/CGAL_Macros.cmake) include(${CGAL_MODULES_DIR}/CGAL_Common.cmake) +set(CGAL_USE_FILE ${CGAL_MODULES_DIR}/UseCGAL.cmake) + + if(CGAL_BUILDING_LIBS) foreach(comp ${CGAL_FIND_COMPONENTS}) if(CGAL_${comp}_FOUND) @@ -139,8 +144,6 @@ endforeach() # Temporary? Change the CMAKE module path cgal_setup_module_path() -set(CGAL_USE_FILE ${CGAL_MODULES_DIR}/UseCGAL.cmake) - include("${CGAL_MODULES_DIR}/CGAL_parse_version_h.cmake") cgal_parse_version_h( "${CGAL_INSTALLATION_PACKAGE_DIR}/include/CGAL/version.h" "CGAL_VERSION_NAME" diff --git a/Jet_fitting_3/doc/Jet_fitting_3/CGAL/Monge_via_jet_fitting.h b/Jet_fitting_3/doc/Jet_fitting_3/CGAL/Monge_via_jet_fitting.h index 2bfe86e437a..a0778b4c18e 100644 --- a/Jet_fitting_3/doc/Jet_fitting_3/CGAL/Monge_via_jet_fitting.h +++ b/Jet_fitting_3/doc/Jet_fitting_3/CGAL/Monge_via_jet_fitting.h @@ -199,7 +199,7 @@ Monge_via_jet_fitting(); This operator performs all the computations. The \f$ N\f$ input points are given by the `InputIterator` parameters which value-type are `Data_kernel::Point_3`, `d` is the degree of the fitted -polynomial, `d'` is the degree of the expected Monge +polynomial, \c d' is the degree of the expected Monge coefficients. \pre \f$ N \geq N_{d}:=(d+1)(d+2)/2\f$, \f$ 1 \leq d' \leq\min(d,4) \f$. */ template Monge_form diff --git a/Jet_fitting_3/doc/Jet_fitting_3/Jet_fitting_3.txt b/Jet_fitting_3/doc/Jet_fitting_3/Jet_fitting_3.txt index 36d39ebf838..d89781711dc 100644 --- a/Jet_fitting_3/doc/Jet_fitting_3/Jet_fitting_3.txt +++ b/Jet_fitting_3/doc/Jet_fitting_3/Jet_fitting_3.txt @@ -77,13 +77,11 @@ the surface can locally be written as the graph of a bivariate function. Letting \f$ h.o.t.\f$ stand for higher order terms, one has : -\f[ -\begin{equation} +\f{equation}{ z(x,y)=J_{B,d}(x,y) + h.o.t. \ ; \quad J_{B,d}(x,y)=\ccSum{k=0}{d}{(\ccSum{i=0}{i}{ \frac{B_{k-i,i}x^{k-i}y^{i}}{i!(k-i)!}})}. -\end{equation} -\f] +\f} The degree \f$ d\f$ polynomial \f$ J_{B,d}\f$ is the Taylor expansion of the function \f$ z\f$, and is called its \f$ d\f$-jet. Notice that a \f$ d\f$-jet contains @@ -343,12 +341,10 @@ The fitting process consists of finding the coefficients \f$ A_{i,j}\f$ of the degree \f$ d\f$ polynomial \anchor eqanswer -\f[ -\begin{equation} +\f{equation}{ J_{A,d}= \ccSum{k=0}{d}{(\ccSum{i=0}{k}{ \frac{A_{k-i,i}x^{k-i}y^{i}}{i!(k-i)!}})}. -\end{equation} -\f] +\f} Denote \f$ p_i=(x_i,y_i,z_i), \ i=1,\ldots , N\f$ the coordinates of the sample points of \f$ P^+\f$. @@ -362,7 +358,7 @@ given by A = & (A_{0,0}, A_{1,0},A_{0,1}, \ldots , A_{0,d})^T \\ Z= &(z_1, z_2,\ldots , z_N)^T \\ M= &(1,x_i,\ y_i,\ \frac{x_i^2}{2},\ldots , -\ \frac{x_iy_i^{d-1}}{(d-1)!},\ \frac{y_i^d}{d!})_{i=1,...,N}\\ +\ \frac{x_iy_i^{d-1}}{(d-1)!},\ \frac{y_i^d}{d!})_{i=1,...,N} \f} The equations for interpolation become \f$ MA=Z\f$. For approximation, the @@ -395,8 +391,7 @@ The number \f$ r\f$, which is the number of non zero singular values, is strictly lower than \f$ N_d\f$ if the system is under constrained. In any case, the unique solution which minimize \f$ ||A||_2\f$ is given by: -\f[ -\begin{equation} +\f{equation}{ A= V \left( \begin{array}{cc} D_r^{-1} & 0_{N_d-r,\ r}\\ @@ -404,8 +399,7 @@ D_r^{-1} & 0_{N_d-r,\ r}\\ \end{array} \right) U^TZ. -\end{equation} -\f] +\f} One can provide the condition number of the matrix \f$ M\f$ (after preconditioning) which is the ratio of the maximal and the minimal @@ -491,22 +485,18 @@ We use explicit formula. The implicit equation of the fitted polynomial surface in the fitting-basis with origin the point \f$ (0,0,A_{0,0})\f$ is \f$ Q=0\f$ with -\f[ -\begin{equation} +\f{equation}{ Q=-w-A_{0,0} +\ccSum{i,j}{}{\frac{A_{i,j}u^iv^j}{i!j!}}. -\end{equation} -\f] +\f} The equation in the Monge basis is obtained by substituting \f$ (u,v,w)\f$ by \f$ P^T_{F\rightarrow M}(x,y,z)\f$. Denote \f$ f(x,y,z)=0\f$ this implicit equation. By definition of the Monge basis, we have locally (at \f$ (0,0,0)\f$) -\f[ -\begin{equation} +\f{equation}{ f(x,y,z)=0 \Leftrightarrow z=g(x,y) -\end{equation} -\f] +\f} and the Taylor expansion of \f$ g\f$ at \f$ (0,0)\f$ are the Monge coefficients sought. @@ -526,7 +516,7 @@ f_{0,0,1} ^{2}}} \\ &b_1=g_{2,1}=-{\frac {- f_{0,1,1} f_{2,0,0} + f_{2,1,0} f_{0,0,1} }{ f_{0,0,1} ^{2}}} \\ -& .... \\ +& .... \f} diff --git a/Kernel_23/test/Kernel_23/include/CGAL/_test_io.h b/Kernel_23/test/Kernel_23/include/CGAL/_test_io.h index bf7dacd2f97..765527e0a58 100644 --- a/Kernel_23/test/Kernel_23/include/CGAL/_test_io.h +++ b/Kernel_23/test/Kernel_23/include/CGAL/_test_io.h @@ -40,7 +40,7 @@ _test_io_for(const T& t) } std::ifstream iFile(TEST_FILENAME, std::ios::in); - T u; + T u = t; iFile >> u; assert(!iFile.fail()); assert(u == t); diff --git a/Kernel_23/test/Kernel_23/issue_129.cpp b/Kernel_23/test/Kernel_23/issue_129.cpp index cb9ae603e25..06b6c674782 100644 --- a/Kernel_23/test/Kernel_23/issue_129.cpp +++ b/Kernel_23/test/Kernel_23/issue_129.cpp @@ -28,7 +28,7 @@ int main() { try { - CGAL::Point_3 a, b, c, d; + CGAL::Point_3 a(CGAL::ORIGIN), b(a), c(a), d(a); CGAL::squared_radius(a, b, c, d); } catch(...) {} return EXIT_SUCCESS; diff --git a/Kernel_d/doc/Kernel_d/CGAL/Kernel_d/Vector_d.h b/Kernel_d/doc/Kernel_d/CGAL/Kernel_d/Vector_d.h index d09974defaa..541a6f73f8a 100644 --- a/Kernel_d/doc/Kernel_d/CGAL/Kernel_d/Vector_d.h +++ b/Kernel_d/doc/Kernel_d/CGAL/Kernel_d/Vector_d.h @@ -96,8 +96,8 @@ InputIterator first, InputIterator last); introduces a variable `v` of type `Vector_d` in dimension `d` initialized to the vector with homogeneous coordinates as defined by -`H = set [first,last)` and `D`: \f$ (\pmH[0], -\pmH[1], \ldots, \pmH[d-1], \pmD)\f$. The sign +`H = set [first,last)` and `D`: \f$ (\pm H_0, +\pm H_1, \ldots, \pm H_{D-1}, \pm H_D)\f$. The sign chosen is the sign of \f$ D\f$. \pre `D` is non-zero, the iterator range defines a \f$ d\f$-tuple of `RT`. diff --git a/Linear_cell_complex/demo/Linear_cell_complex/CMakeLists.txt b/Linear_cell_complex/demo/Linear_cell_complex/CMakeLists.txt index 108432031ff..d23afa5eb3d 100644 --- a/Linear_cell_complex/demo/Linear_cell_complex/CMakeLists.txt +++ b/Linear_cell_complex/demo/Linear_cell_complex/CMakeLists.txt @@ -46,7 +46,7 @@ if ( NOT (CGAL_FOUND AND CGAL_Qt5_FOUND AND Qt5_FOUND ) ) else() -add_definitions(-DQT_NO_KEYWORDS) +add_definitions(-DCGAL_USE_BASIC_VIEWER -DQT_NO_KEYWORDS) # ui file, created wih Qt Designer qt5_wrap_ui(uis MainWindow.ui CreateMesh.ui CreateMenger.ui @@ -64,7 +64,7 @@ add_executable(Linear_cell_complex_3_demo add_to_cached_list(CGAL_EXECUTABLE_TARGETS Linear_cell_complex_3_demo) -target_link_libraries(Linear_cell_complex_3_demo PRIVATE +target_link_libraries(Linear_cell_complex_3_demo PUBLIC CGAL::CGAL CGAL::CGAL_Qt5 Qt5::Gui Qt5::OpenGL) include(${CGAL_MODULES_DIR}/CGAL_add_test.cmake) diff --git a/Linear_cell_complex/demo/Linear_cell_complex/MainWindow.cpp b/Linear_cell_complex/demo/Linear_cell_complex/MainWindow.cpp index a78780d3e78..e2713d93608 100644 --- a/Linear_cell_complex/demo/Linear_cell_complex/MainWindow.cpp +++ b/Linear_cell_complex/demo/Linear_cell_complex/MainWindow.cpp @@ -39,7 +39,7 @@ void subdivide_lcc_pqq (LCC & m); #define DELAY_STATUSMSG 1500 -MainWindow::MainWindow (QWidget * parent):CGAL::Qt::DemosMainWindow (parent), +MainWindow::MainWindow (QWidget * parent) : CGAL::Qt::DemosMainWindow (parent), nbcube (0), dialogmesh (this), dialogmenger(this), @@ -78,7 +78,7 @@ MainWindow::MainWindow (QWidget * parent):CGAL::Qt::DemosMainWindow (parent), QObject::connect(&dialogmesh, SIGNAL(accepted()), this, SLOT(onCreateMeshOk())); - this->viewer->setScene(&scene); + this->viewer->setScene(&scene, false); connect_actions (); this->addAboutDemo (":/cgal/help/about_Linear_cell_complex_3.html"); diff --git a/Linear_cell_complex/demo/Linear_cell_complex/Viewer.cpp b/Linear_cell_complex/demo/Linear_cell_complex/Viewer.cpp index 3bef476f899..018d0bdad69 100644 --- a/Linear_cell_complex/demo/Linear_cell_complex/Viewer.cpp +++ b/Linear_cell_complex/demo/Linear_cell_complex/Viewer.cpp @@ -19,928 +19,44 @@ // Author(s) : Guillaume Damiand // Contributor(s): Kumar Snehasish // + #include "Viewer.h" - -#include -#include -#include -#include - #include -#include -//Vertex source code -const char vertex_source[] = - { - "#version 120 \n" - "attribute highp vec4 vertex;\n" - "attribute highp vec3 normal;\n" - "attribute highp vec3 color;\n" +Viewer::Viewer(QWidget* parent) : + Base(parent, NULL, ""), + m_previous_scene_empty(true) +{} - "uniform highp mat4 mvp_matrix;\n" - "uniform highp mat4 mv_matrix; \n" - "uniform highp float point_size; \n" - - "varying highp vec4 fP; \n" - "varying highp vec3 fN; \n" - "varying highp vec4 fColor; \n" - "void main(void)\n" - "{\n" - " gl_PointSize = point_size; \n" - " fP = mv_matrix * vertex; \n" - " fN = mat3(mv_matrix)* normal; \n" - " fColor = vec4(color, 1.0); \n" - " gl_Position = mvp_matrix * vertex;\n" - "}" - }; - -//Vertex source code -const char fragment_source[] = - { - "#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" - }; - -//Vertex source code -const char vertex_source_p_l[] = - { - "#version 120 \n" - "attribute highp vec4 vertex;\n" - "uniform highp mat4 mvp_matrix;\n" - "uniform highp float point_size; \n" - "void main(void)\n" - "{\n" - " gl_PointSize = point_size; \n" - " gl_Position = mvp_matrix * vertex;\n" - "}" - }; -//Vertex source code -const char fragment_source_p_l[] = - { - "#version 120 \n" - "uniform highp vec4 color; \n" - "void main(void) { \n" - "gl_FragColor = color; \n" - "} \n" - "\n" - }; - -Viewer::Viewer(QWidget* parent) - : CGAL::QGLViewer(parent), - wireframe(false), - flatShading(true), - edges(true), - vertices(true), - inverse_normal(false), - size_points(7.), - size_edges(3.1), - ambient(0.6f, 0.5f, 0.5f, 0.5f), - m_previous_scene_empty(true), - are_buffers_initialized(false) +void Viewer::setScene(Scene* scene_, bool doredraw) { -} - -Viewer::~Viewer() -{ - for (int i=0; icompileSourceCode(vertex_source)) - { - std::cerr<<"Compiling vertex source FAILED"<compileSourceCode(fragment_source)) - { - std::cerr<<"Compiling fragmentsource FAILED"<compileSourceCode(vertex_source_p_l)) - { - std::cerr<<"Compiling vertex source FAILED"<compileSourceCode(fragment_source_p_l)) - { - std::cerr<<"Compiling fragmentsource FAILED"<(pos_facets.size()*sizeof(float))); - vertexLocation[0] = rendering_program.attributeLocation("vertex"); - rendering_program.bind(); - rendering_program.enableAttributeArray(vertexLocation[0]); - rendering_program.setAttributeBuffer(vertexLocation[0],GL_FLOAT,0,3); - rendering_program.release(); - buffers[0].release(); - - //normals of the facets - buffers[1].bind(); - buffers[1].allocate(flat_normals.data(), - static_cast(flat_normals.size()*sizeof(float))); - normalsLocation = rendering_program.attributeLocation("normal"); - rendering_program.bind(); - rendering_program.enableAttributeArray(normalsLocation); - rendering_program.setAttributeBuffer(normalsLocation,GL_FLOAT,0,3); - buffers[1].release(); - - //colors of the facets - buffers[2].bind(); - buffers[2].allocate(colors.data(), - static_cast(colors.size()*sizeof(float))); - colorsLocation = rendering_program.attributeLocation("color"); - rendering_program.bind(); - rendering_program.enableAttributeArray(colorsLocation); - rendering_program.setAttributeBuffer(colorsLocation,GL_FLOAT,0,3); - buffers[2].release(); - rendering_program.release(); - - vao[0].release(); - vao[1].bind(); - - //points of the facets - buffers[3].bind(); - buffers[3].allocate(pos_facets.data(), static_cast(pos_facets.size()*sizeof(float))); - vertexLocation[0] = rendering_program.attributeLocation("vertex"); - rendering_program.bind(); - rendering_program.enableAttributeArray(vertexLocation[0]); - rendering_program.setAttributeBuffer(vertexLocation[0],GL_FLOAT,0,3); - rendering_program.release(); - buffers[3].release(); - - //normals of the facets - buffers[4].bind(); - buffers[4].allocate(smooth_normals.data(), - static_cast(smooth_normals.size()*sizeof(float))); - normalsLocation = rendering_program.attributeLocation("normal"); - rendering_program.bind(); - rendering_program.enableAttributeArray(normalsLocation); - rendering_program.setAttributeBuffer(normalsLocation,GL_FLOAT,0,3); - buffers[4].release(); - - //colors of the facets - buffers[5].bind(); - buffers[5].allocate(colors.data(), static_cast(colors.size()*sizeof(float))); - colorsLocation = rendering_program.attributeLocation("color"); - rendering_program.bind(); - rendering_program.enableAttributeArray(colorsLocation); - rendering_program.setAttributeBuffer(colorsLocation,GL_FLOAT,0,3); - buffers[5].release(); - rendering_program.release(); - - vao[1].release(); - - //The lines - vao[2].bind(); - buffers[6].bind(); - buffers[6].allocate(pos_lines.data(), static_cast(pos_lines.size()*sizeof(float))); - vertexLocation[2] = rendering_program_p_l.attributeLocation("vertex"); - rendering_program_p_l.bind(); - rendering_program_p_l.enableAttributeArray(vertexLocation[2]); - rendering_program_p_l.setAttributeBuffer(vertexLocation[2],GL_FLOAT,0,3); - buffers[6].release(); - rendering_program_p_l.release(); - vao[2].release(); - - //The points - vao[3].bind(); - buffers[7].bind(); - buffers[7].allocate(pos_points.data(), static_cast(pos_points.size()*sizeof(float))); - vertexLocation[2] = rendering_program_p_l.attributeLocation("vertex"); - rendering_program_p_l.bind(); - rendering_program_p_l.enableAttributeArray(vertexLocation[2]); - rendering_program_p_l.setAttributeBuffer(vertexLocation[2],GL_FLOAT,0,3); - buffers[7].release(); - rendering_program_p_l.release(); - vao[3].release(); - - are_buffers_initialized = true; -} - -void Viewer::compute_face(Dart_handle dh, LCC::size_type markface) -{ - LCC &lcc = *scene->lcc; - - CGAL::mark_cell(lcc, dh, markface); - - double r = (double)lcc.info<3>(dh).color().r()/255.0; - double g = (double)lcc.info<3>(dh).color().g()/255.0; - double b = (double)lcc.info<3>(dh).color().b()/255.0; - if ( !lcc.is_free(dh, 3) ) - { - r += (double)lcc.info<3>(lcc.beta(dh,3)).color().r()/255.0; - g += (double)lcc.info<3>(lcc.beta(dh,3)).color().g()/255.0; - b += (double)lcc.info<3>(lcc.beta(dh,3)).color().b()/255.0; - r /= 2; g /= 2; b /= 2; - } - - //compute flat normals - LCC::Vector normal = CGAL::compute_normal_of_cell_2(lcc,dh); - normal = normal/(CGAL::sqrt(normal*normal)); - if (inverse_normal) - normal=normal*-1; - - if (lcc.beta<1,1,1>(dh)!=dh) - { - try // Try catch to avoir crash of triangulation - { - P_traits cdt_traits(normal); - CDT cdt(cdt_traits); - - // Iterates on the vector of facet handles - CDT::Vertex_handle previous = NULL, first = NULL; - for (LCC::Dart_of_orbit_range<1>::const_iterator - he_circ = lcc.darts_of_orbit<1>(dh).begin(), - he_circ_end = lcc.darts_of_orbit<1>(dh).end(); - he_circ!=he_circ_end; ++he_circ) - { - CDT::Vertex_handle vh = cdt.insert(lcc.point(he_circ)); - if(first == NULL) - { first = vh; } - vh->info().v = CGAL::compute_normal_of_cell_0(lcc, he_circ); - if (inverse_normal) vh->info().v=vh->info().v*-1; - if(previous!=NULL && previous != vh) - { cdt.insert_constraint(previous, vh); } - previous = vh; - } - if (previous!=NULL) - cdt.insert_constraint(previous, first); - - // sets mark is_external - for(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; - } - //check if the facet is external or internal - std::queue face_queue; - CDT::Face_handle face_internal = NULL; - face_queue.push(cdt.infinite_vertex()->face()); - while(! face_queue.empty() ) - { - 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))) - { - 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() ) - { - 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(int i = 0; i <3; ++i) - { - if(!cdt.is_constrained(std::make_pair(fh, i))) - { - face_queue.push(fh->neighbor(i)); - } - } - } - } - - //iterates on the internal faces to add the vertices to the positions - //and the normals to the appropriate vectors - for(CDT::Finite_faces_iterator ffit = cdt.finite_faces_begin(), - ffitend = cdt.finite_faces_end(); ffit != ffitend; ++ffit) - { - if(!ffit->info().is_external) - { - flat_normals.push_back(normal.x()); - flat_normals.push_back(normal.y()); - flat_normals.push_back(normal.z()); - - flat_normals.push_back(normal.x()); - flat_normals.push_back(normal.y()); - flat_normals.push_back(normal.z()); - - flat_normals.push_back(normal.x()); - flat_normals.push_back(normal.y()); - flat_normals.push_back(normal.z()); - - smooth_normals.push_back(ffit->vertex(0)->info().v.x()); - smooth_normals.push_back(ffit->vertex(0)->info().v.y()); - smooth_normals.push_back(ffit->vertex(0)->info().v.z()); - - smooth_normals.push_back(ffit->vertex(1)->info().v.x()); - smooth_normals.push_back(ffit->vertex(1)->info().v.y()); - smooth_normals.push_back(ffit->vertex(1)->info().v.z()); - - smooth_normals.push_back(ffit->vertex(2)->info().v.x()); - smooth_normals.push_back(ffit->vertex(2)->info().v.y()); - smooth_normals.push_back(ffit->vertex(2)->info().v.z()); - - pos_facets.push_back(ffit->vertex(0)->point().x()); - pos_facets.push_back(ffit->vertex(0)->point().y()); - pos_facets.push_back(ffit->vertex(0)->point().z()); - - pos_facets.push_back(ffit->vertex(1)->point().x()); - pos_facets.push_back(ffit->vertex(1)->point().y()); - pos_facets.push_back(ffit->vertex(1)->point().z()); - - pos_facets.push_back(ffit->vertex(2)->point().x()); - pos_facets.push_back(ffit->vertex(2)->point().y()); - pos_facets.push_back(ffit->vertex(2)->point().z()); - - colors.push_back(r);colors.push_back(g);colors.push_back(b); - colors.push_back(r);colors.push_back(g);colors.push_back(b); - colors.push_back(r);colors.push_back(g);colors.push_back(b); - } - } - } - catch(...) - { // Triangulation crash: the face is not filled - } - } - else - { // The face is a triangle - colors.push_back(r);colors.push_back(g);colors.push_back(b); - colors.push_back(r);colors.push_back(g);colors.push_back(b); - colors.push_back(r);colors.push_back(g);colors.push_back(b); - - flat_normals.push_back(normal.x()); - flat_normals.push_back(normal.y()); - flat_normals.push_back(normal.z()); - - flat_normals.push_back(normal.x()); - flat_normals.push_back(normal.y()); - flat_normals.push_back(normal.z()); - - flat_normals.push_back(normal.x()); - flat_normals.push_back(normal.y()); - flat_normals.push_back(normal.z()); - - for (LCC::Dart_of_orbit_range<1>::const_iterator - orbitIter = lcc.darts_of_orbit<1>(dh).begin(); - orbitIter.cont(); ++orbitIter) - { - //compute Smooth normals - LCC::Vector normal = CGAL::compute_normal_of_cell_0(lcc,orbitIter); - normal = normal/(CGAL::sqrt(normal*normal)); - if (inverse_normal) normal=normal*-1; - - smooth_normals.push_back(normal.x()); - smooth_normals.push_back(normal.y()); - smooth_normals.push_back(normal.z()); - - const LCC::Point& p = lcc.point(orbitIter); - pos_facets.push_back(p.x()); - pos_facets.push_back(p.y()); - pos_facets.push_back(p.z()); - } - } -} - -void Viewer::compute_edge(Dart_handle dh, LCC::size_type markedge) -{ - LCC &lcc = *scene->lcc; - - CGAL::mark_cell(lcc, dh, markedge); - - const LCC::Point& p = lcc.point(dh); - Dart_handle d2 = lcc.other_extremity(dh); - if ( d2!=NULL ) - { - const LCC::Point& p2 = lcc.point(d2); - pos_lines.push_back(p.x()); - pos_lines.push_back(p.y()); - pos_lines.push_back(p.z()); - - pos_lines.push_back(p2.x()); - pos_lines.push_back(p2.y()); - pos_lines.push_back(p2.z()); - } -} - -void Viewer::compute_vertex(Dart_handle dh, LCC::size_type markvertex, bool& empty) -{ - LCC &lcc = *scene->lcc; - - CGAL::mark_cell(lcc, dh, markvertex); - - const LCC::Point& p = lcc.point(dh); - pos_points.push_back(p.x()); - pos_points.push_back(p.y()); - pos_points.push_back(p.z()); - - if ( empty ) - { - bb = p.bbox(); - empty = false; - } - else - bb = bb + p.bbox(); -} - -void Viewer::compute_elements() -{ - LCC &lcc = *scene->lcc; - - pos_facets.clear(); - flat_normals.clear(); - smooth_normals.clear(); - colors.clear(); - pos_lines.clear(); - pos_points.clear(); - - if ( lcc.is_empty() ) - { - bb = LCC::Point(CGAL::ORIGIN).bbox(); - bb = bb + LCC::Point(1,1,1).bbox(); // To avoid a warning from Qglviewer - return; - } - - LCC::size_type markvertex = lcc.get_new_mark(); - LCC::size_type markedge = lcc.get_new_mark(); - LCC::size_type markface = lcc.get_new_mark(); - - bool empty = true; - for (LCC::Attribute_range<3>::type::iterator it=lcc.attributes<3>().begin(), - itend=lcc.attributes<3>().end(); it!=itend; ++it ) - { - if ( it->info().is_visible() ) - { - for(LCC::Dart_of_cell_range<3>::iterator - dartIter=lcc.darts_of_cell<3>(lcc.dart_of_attribute<3>(it)).begin(); - dartIter.cont(); ++dartIter) - { - if ( it->info().is_filled() && !lcc.is_marked(dartIter, markface) ) - compute_face(dartIter, markface); - - if ( !lcc.is_marked(dartIter, markedge) ) - compute_edge(dartIter, markedge); - - if ( !lcc.is_marked(dartIter, markvertex) ) - compute_vertex(dartIter, markvertex, empty); - } - } - } - - if ( empty ) - { - bb = LCC::Point(CGAL::ORIGIN).bbox(); - bb = bb + LCC::Point(1,1,1).bbox(); // To avoid a warning from Qglviewer - } - - for (LCC::Dart_range::iterator it=lcc.darts().begin(), - itend=lcc.darts().end(); it!=itend; ++it ) - { - lcc.unmark(it, markvertex); - lcc.unmark(it, markedge); - lcc.unmark(it, markface); - } - - lcc.free_mark(markvertex); - lcc.free_mark(markedge); - lcc.free_mark(markface); -} - -void Viewer::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 ); - - - QVector4D position((bb.xmax()-bb.xmin())/2, (bb.ymax()-bb.ymin())/2,bb.zmax(), 0.0 ); - GLfloat shininess = 1.0f; - - rendering_program.bind(); - mvpLocation[0] = rendering_program.uniformLocation("mvp_matrix"); - mvLocation = rendering_program.uniformLocation("mv_matrix"); - lightLocation[0] = rendering_program.uniformLocation("light_pos"); - lightLocation[1] = rendering_program.uniformLocation("light_diff"); - lightLocation[2] = rendering_program.uniformLocation("light_spec"); - lightLocation[3] = rendering_program.uniformLocation("light_amb"); - lightLocation[4] = rendering_program.uniformLocation("spec_power"); - - rendering_program.setUniformValue(lightLocation[0], position); - rendering_program.setUniformValue(lightLocation[1], diffuse); - rendering_program.setUniformValue(lightLocation[2], specular); - rendering_program.setUniformValue(lightLocation[3], ambient); - rendering_program.setUniformValue(lightLocation[4], shininess); - rendering_program.setUniformValue(mvpLocation[0], mvpMatrix); - rendering_program.setUniformValue(mvLocation, mvMatrix); - - rendering_program.release(); - rendering_program_p_l.bind(); - mvpLocation[1] = rendering_program_p_l.uniformLocation("mvp_matrix"); - colorLocation = rendering_program_p_l.uniformLocation("color"); - rendering_program.setUniformValue(mvpLocation[1], mvpMatrix); - rendering_program_p_l.release(); + scene = scene_; + set_lcc(scene->lcc, doredraw); } void Viewer::sceneChanged() { - compute_elements(); - this->camera()->setSceneBoundingBox(CGAL::qglviewer::Vec(bb.xmin(), - bb.ymin(), - bb.zmin()), - CGAL::qglviewer::Vec(bb.xmax(), - bb.ymax(), - bb.zmax())); - are_buffers_initialized = false; - + Base::compute_elements(); + this->camera()-> + setSceneBoundingBox(CGAL::qglviewer::Vec(m_bounding_box.xmin(), + m_bounding_box.ymin(), + m_bounding_box.zmin()), + CGAL::qglviewer::Vec(m_bounding_box.xmax(), + m_bounding_box.ymax(), + m_bounding_box.zmax())); + Base::redraw(); if (m_previous_scene_empty) - this->showEntireScene(); - else - this->update(); + { this->showEntireScene(); } m_previous_scene_empty = scene->lcc->is_empty(); // for the next call to sceneChanged } -void Viewer::draw() -{ - if(scene) - { - glEnable(GL_DEPTH_TEST); - if(!are_buffers_initialized) - initialize_buffers(); - - QColor color; - if ( !wireframe ) - { - if(flatShading) - { - vao[0].bind(); - attrib_buffers(this); - rendering_program.bind(); - glDrawArrays(GL_TRIANGLES, 0, static_cast(pos_facets.size()/3)); - rendering_program.release(); - vao[0].release(); - } - else - { - vao[1].bind(); - attrib_buffers(this); - rendering_program.bind(); - glDrawArrays(GL_TRIANGLES, 0, static_cast(pos_facets.size()/3)); - rendering_program.release(); - vao[1].release(); - } - } - if(edges) - { - vao[2].bind(); - attrib_buffers(this); - color.setRgbF(0.2f, 0.2f, 0.7f); - rendering_program_p_l.bind(); - rendering_program_p_l.setAttributeValue(colorLocation,color); - glLineWidth(size_edges); - glDrawArrays(GL_LINES, 0, static_cast(pos_lines.size()/3)); - rendering_program_p_l.release(); - vao[2].release(); - } - if(vertices) - { - vao[3].bind(); - attrib_buffers(this); - color.setRgbF(.2f,.2f,.6f); - rendering_program_p_l.bind(); - rendering_program_p_l.setAttributeValue(colorLocation,color); - rendering_program_p_l.setUniformValue("point_size", GLfloat(size_points)); - glDrawArrays(GL_POINTS, 0, static_cast(pos_points.size()/3)); - rendering_program_p_l.release(); - vao[3].release(); - } - } -} -void Viewer::init() -{ - // Restore previous viewer state. - restoreStateFromFile(); - initializeOpenGLFunctions(); - // Define 'Control+Q' as the new exit shortcut (default was 'Escape') - setShortcut(CGAL::qglviewer::EXIT_VIEWER, Qt::CTRL+Qt::Key_Q); - - // Add custom key description (see keyPressEvent). - setKeyDescription(Qt::Key_W, "Toggles wire frame display"); - setKeyDescription(Qt::Key_F, "Toggles flat shading display"); - setKeyDescription(Qt::Key_E, "Toggles edges display"); - setKeyDescription(Qt::Key_V, "Toggles vertices display"); - setKeyDescription(Qt::Key_N, "Inverse direction of normals"); - setKeyDescription(Qt::Key_Plus, "Increase size of edges"); - setKeyDescription(Qt::Key_Minus, "Decrease size of edges"); - setKeyDescription(Qt::Key_Plus+Qt::ShiftModifier, "Increase size of vertices"); - setKeyDescription(Qt::Key_Minus+Qt::ShiftModifier, "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(size_edges); - glEnable(GL_POLYGON_OFFSET_FILL); - glPolygonOffset(1.0f,1.0f); - glClearColor(1.0f,1.0f,1.0f,0.0f); - - glDisable(GL_BLEND); - glDisable(GL_LINE_SMOOTH); - glDisable(GL_POLYGON_SMOOTH_HINT); - glBlendFunc(GL_ONE, GL_ZERO); - glHint(GL_LINE_SMOOTH_HINT, GL_FASTEST); - compile_shaders(); -} - void Viewer::keyPressEvent(QKeyEvent *e) { - const Qt::KeyboardModifiers modifiers = e->modifiers(); - - if ((e->key()==Qt::Key_W) && (modifiers==Qt::NoButton)) - { - wireframe = !wireframe; - if (wireframe) - { - displayMessage("Wireframe."); - } - else - { - displayMessage("Filled faces."); - } - update(); - } - else if ((e->key()==Qt::Key_F) && (modifiers==Qt::NoButton)) - { - flatShading = !flatShading; - if (flatShading) - displayMessage("Flat shading."); - else - displayMessage("Gouraud shading."); - - update(); - - } - else if ((e->key()==Qt::Key_E) && (modifiers==Qt::NoButton)) - { - edges = !edges; - displayMessage(QString("Draw edges=%1.").arg(edges?"true":"false")); - - update(); - } - else if ((e->key()==Qt::Key_V) && (modifiers==Qt::NoButton)) - { - vertices = !vertices; - displayMessage(QString("Draw vertices=%1.").arg(vertices?"true":"false")); - update(); - } - else if ((e->key()==Qt::Key_N) && (modifiers==Qt::NoButton)) - { - inverse_normal = !inverse_normal; - displayMessage(QString("Inverse normal=%1.").arg(inverse_normal?"true":"false")); - sceneChanged(); - } - else if ((e->key()==Qt::Key_Plus) && (modifiers==Qt::KeypadModifier)) - { - size_edges+=.5; - displayMessage(QString("Size of edges=%1.").arg(size_edges)); - update(); - } - else if ((e->key()==Qt::Key_Minus) && (modifiers==Qt::KeypadModifier)) - { - if (size_edges>.5) size_edges-=.5; - displayMessage(QString("Size of edges=%1.").arg(size_edges)); - update(); - } - else if ((e->key()==Qt::Key_Plus) && (modifiers==(Qt::ShiftModifier|Qt::KeypadModifier))) - { - size_points+=.5; - displayMessage(QString("Size of points=%1.").arg(size_points)); - update(); - } - else if ((e->key()==Qt::Key_Minus) && (modifiers==(Qt::ShiftModifier|Qt::KeypadModifier))) - { - if (size_points>.5) size_points-=.5; - displayMessage(QString("Size of points=%1.").arg(size_points)); - update(); - } - else if ((e->key()==Qt::Key_PageUp) && (modifiers==Qt::NoButton)) - { - ambient.setX(ambient.x()+.1); - if (ambient.x()>1.) ambient.setX(1.); - ambient.setY(ambient.x()+.1); - if (ambient.y()>1.) ambient.setY(1.); - ambient.setZ(ambient.x()+.1); - if (ambient.z()>1.) ambient.setZ(1.); - displayMessage(QString("Light color=(%1 %2 %3)."). - arg(ambient.x()).arg(ambient.y()).arg(ambient.z())); - update(); - } - else if ((e->key()==Qt::Key_PageDown) && (modifiers==Qt::NoButton)) - { - ambient.setX(ambient.x()-.1); - if (ambient.x()<0.) ambient.setX(0.); - ambient.setY(ambient.y()-.1); - if (ambient.y()<0.) ambient.setY(0.); - ambient.setZ(ambient.z()-.1); - if (ambient.z()<0.) ambient.setZ(0.); - displayMessage(QString("Light color=(%1 %2 %3)."). - arg(ambient.x()).arg(ambient.y()).arg(ambient.z())); - update(); - } - else if ((e->key()==Qt::Key_PageUp) && (modifiers==Qt::ShiftModifier)) - { - ambient.setX(ambient.x()+.1); - if (ambient.x()>1.) ambient.setX(1.); - displayMessage(QString("Light color=(%1 %2 %3)."). - arg(ambient.x()).arg(ambient.y()).arg(ambient.z())); - update(); - } - else if ((e->key()==Qt::Key_PageUp) && (modifiers==Qt::AltModifier)) - { - ambient.setY(ambient.y()+.1); - if (ambient.y()>1.) ambient.setY(1.); - displayMessage(QString("Light color=(%1 %2 %3)."). - arg(ambient.x()).arg(ambient.y()).arg(ambient.z())); - update(); - } - else if ((e->key()==Qt::Key_PageUp) && (modifiers==Qt::ControlModifier)) - { - ambient.setZ(ambient.z()+.1); - if (ambient.z()>1.) ambient.setZ(1.); - displayMessage(QString("Light color=(%1 %2 %3)."). - arg(ambient.x()).arg(ambient.y()).arg(ambient.z())); - update(); - } - else if ((e->key()==Qt::Key_PageDown) && (modifiers==Qt::ShiftModifier)) - { - ambient.setX(ambient.x()-.1); - if (ambient.x()<0.) ambient.setX(0.); - displayMessage(QString("Light color=(%1 %2 %3)."). - arg(ambient.x()).arg(ambient.y()).arg(ambient.z())); - update(); - } - else if ((e->key()==Qt::Key_PageDown) && (modifiers==Qt::AltModifier)) - { - ambient.setY(ambient.y()-.1); - if (ambient.y()<0.) ambient.setY(0.); - displayMessage(QString("Light color=(%1 %2 %3)."). - arg(ambient.x()).arg(ambient.y()).arg(ambient.z())); - update(); - } - else if ((e->key()==Qt::Key_PageDown) && (modifiers==Qt::ControlModifier)) - { - ambient.setZ(ambient.z()-.1); - if (ambient.z()<0.) ambient.setZ(0.); - displayMessage(QString("Light color=(%1 %2 %3)."). - arg(ambient.x()).arg(ambient.y()).arg(ambient.z())); - update(); - } - else - CGAL::QGLViewer::keyPressEvent(e); + // const Qt::KeyboardModifiers modifiers = e->modifiers(); + Base::keyPressEvent(e); } QString Viewer::helpString() const -{ - QString text("

      L C 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; -} +{ return Base::helpString("LCC Demo"); } diff --git a/Linear_cell_complex/demo/Linear_cell_complex/Viewer.h b/Linear_cell_complex/demo/Linear_cell_complex/Viewer.h index 894ec46eaa3..d42dbbe6713 100644 --- a/Linear_cell_complex/demo/Linear_cell_complex/Viewer.h +++ b/Linear_cell_complex/demo/Linear_cell_complex/Viewer.h @@ -23,96 +23,114 @@ #define VIEWER_H #include "typedefs.h" +#include -#include -#include -#include -#include -#include -#include -#include -#include +// Functor used by SimpleLCCViewerQt to colorize of not elements. +struct MyDrawingFunctorLCC +{ + /// @return true iff the volume containing dh is drawn. + template + bool draw_volume(const LCC& alcc, + typename LCC::Dart_const_handle dh) const + { return alcc.template info<3>(dh).is_visible(); } + /// @return true iff the face containing dh is drawn. + template + bool draw_face(const LCC&, + typename LCC::Dart_const_handle) const + { return true; } + /// @return true iff the edge containing dh is drawn. + template + bool draw_edge(const LCC&, + typename LCC::Dart_const_handle) const + { return true; } + /// @return true iff the vertex containing dh is drawn. + template + bool draw_vertex(const LCC&, + typename LCC::Dart_const_handle) const + { return true; } -#define NB_VBO_BUFFERS 8 -#define NB_VAO_BUFFERS 4 + /// @return true iff the volume containing dh is drawn in wireframe. + template + bool volume_wireframe(const LCC& alcc, + typename LCC::Dart_const_handle dh) const + { return !(alcc.template info<3>(dh).is_filled()); } + /// @return true iff the face containing dh is drawn in wireframe. + template + bool face_wireframe(const LCC&, + typename LCC::Dart_const_handle) const + { return false; } -class Viewer : public CGAL::QGLViewer + /// @return true iff the volume containing dh is colored. + template + bool colored_volume(const LCC&, + typename LCC::Dart_const_handle) const + { return true; } + /// @return true iff the face containing dh is colored. + /// if we have also colored_volume(alcc, dh), the volume color is + /// ignored and only the face color is considered. + template + bool colored_face(const LCC&, + typename LCC::Dart_const_handle) const + { return false; } + /// @return true iff the edge containing dh is colored. + template + bool colored_edge(const LCC&, + typename LCC::Dart_const_handle) const + { return false; } + /// @return true iff the vertex containing dh is colored. + template + bool colored_vertex(const LCC&, + typename LCC::Dart_const_handle) const + { return false; } + + /// @return the color of the volume containing dh + /// used only if colored_volume(alcc, dh) and !colored_face(alcc, dh) + template + CGAL::Color volume_color(const LCC& alcc, + typename LCC::Dart_const_handle dh) const + { return alcc.template info<3>(dh).color(); } + /// @return the color of the face containing dh + /// used only if colored_face(alcc, dh) + template + CGAL::Color face_color(const LCC& alcc, + typename LCC::Dart_const_handle dh) const + { + CGAL::Random random((unsigned int)(alcc.darts().index(dh))); + return get_random_color(random); + } + /// @return the color of the edge containing dh + /// used only if colored_edge(alcc, dh) + template + CGAL::Color edge_color(const LCC&, + typename LCC::Dart_const_handle) const + { return CGAL::Color(0, 0, 0); } + /// @return the color of the vertex containing dh + /// used only if colored_vertex(alcc, dh) + template + CGAL::Color vertex_color(const LCC&, + typename LCC::Dart_const_handle) const + { return CGAL::Color(0, 0, 0); } +}; + + +class Viewer : public CGAL::SimpleLCCViewerQt { Q_OBJECT - typedef LCC::Dart_handle Dart_handle; - typedef LCC::Dart_const_handle Dart_const_handle; + typedef CGAL::SimpleLCCViewerQt Base; public: Viewer(QWidget* parent); - - ~Viewer(); - - void setScene(Scene* scene_) - { scene = scene_; } - -public: - void draw(); - - virtual void init(); - + void setScene(Scene* scene_, bool doredraw=true); void keyPressEvent(QKeyEvent *e); - virtual QString helpString() const; public Q_SLOTS: - void sceneChanged(); -private: - void initialize_buffers(); - void attrib_buffers(CGAL::QGLViewer*); - void compile_shaders(); - - void compute_elements(); - void compute_face(Dart_handle dh, LCC::size_type markface); - void compute_edge(Dart_handle dh, LCC::size_type markedge); - void compute_vertex(Dart_handle dh, LCC::size_type markvertex, bool& empty); - private: Scene* scene; - - bool wireframe; - bool flatShading; - bool edges; - bool vertices; - bool inverse_normal; - - double size_points; - double size_edges; - - QVector4D ambient; - bool m_previous_scene_empty; - bool are_buffers_initialized; - - //Shaders elements - int vertexLocation[3]; - int normalsLocation; - int mvpLocation[2]; - int mvLocation; - int colorLocation; - int colorsLocation; - int lightLocation[5]; - - std::vector pos_points; - std::vector pos_lines; - std::vector pos_facets; - std::vector smooth_normals; - std::vector flat_normals; - std::vector colors; - - QGLBuffer buffers[NB_VBO_BUFFERS]; - QOpenGLVertexArrayObject vao[NB_VAO_BUFFERS]; - QOpenGLShaderProgram rendering_program; - QOpenGLShaderProgram rendering_program_p_l; - - CGAL::Bbox_3 bb; }; #endif diff --git a/Linear_cell_complex/examples/Linear_cell_complex/CMakeLists.txt b/Linear_cell_complex/examples/Linear_cell_complex/CMakeLists.txt index 653f6e2bc8b..4ed3f8f2f2c 100644 --- a/Linear_cell_complex/examples/Linear_cell_complex/CMakeLists.txt +++ b/Linear_cell_complex/examples/Linear_cell_complex/CMakeLists.txt @@ -9,6 +9,10 @@ if(NOT POLICY CMP0070 AND POLICY CMP0053) cmake_policy(SET CMP0053 OLD) endif() +if(POLICY CMP0071) + cmake_policy(SET CMP0071 NEW) +endif() + find_package(CGAL COMPONENTS Qt5) if(CGAL_Qt5_FOUND) diff --git a/Linear_cell_complex/include/CGAL/draw_linear_cell_complex.h b/Linear_cell_complex/include/CGAL/draw_linear_cell_complex.h index 70249fd05f6..1cdc247d855 100644 --- a/Linear_cell_complex/include/CGAL/draw_linear_cell_complex.h +++ b/Linear_cell_complex/include/CGAL/draw_linear_cell_complex.h @@ -31,15 +31,96 @@ namespace CGAL { // Default color functor; user can change it to have its own face color -struct DefaultColorFunctorLCC +struct DefaultDrawingFunctorLCC { + /// @return true iff the volume containing dh is drawn. 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 + bool draw_volume(const LCC&, + typename LCC::Dart_const_handle) const + { return true; } + /// @return true iff the face containing dh is drawn. + template + bool draw_face(const LCC&, + typename LCC::Dart_const_handle) const + { return true; } + /// @return true iff the edge containing dh is drawn. + template + bool draw_edge(const LCC&, + typename LCC::Dart_const_handle) const + { return true; } + /// @return true iff the vertex containing dh is drawn. + template + bool draw_vertex(const LCC&, + typename LCC::Dart_const_handle) const + { return true; } + /// @return true iff the volume containing dh is drawn in wireframe. + template + bool volume_wireframe(const LCC&, + typename LCC::Dart_const_handle) const + { return false; } + /// @return true iff the face containing dh is drawn in wireframe. + template + bool face_wireframe(const LCC&, + typename LCC::Dart_const_handle) const + { return false; } + + /// @return true iff the volume containing dh is colored. + template + bool colored_volume(const LCC&, + typename LCC::Dart_const_handle) const + { return true; } + /// @return true iff the face containing dh is colored. + /// if we have also colored_volume(alcc, dh), the volume color is + /// ignored and only the face color is considered. + template + bool colored_face(const LCC&, + typename LCC::Dart_const_handle) const + { return false; } + /// @return true iff the edge containing dh is colored. + template + bool colored_edge(const LCC&, + typename LCC::Dart_const_handle) const + { return false; } + /// @return true iff the vertex containing dh is colored. + template + bool colored_vertex(const LCC&, + typename LCC::Dart_const_handle) const + { return false; } + + /// @return the color of the volume containing dh + /// used only if colored_volume(alcc, dh) and !colored_face(alcc, dh) + template + CGAL::Color volume_color(const LCC& alcc, + typename LCC::Dart_const_handle dh) const + { + CGAL::Random random((unsigned int)(alcc.darts().index(dh))); + return get_random_color(random); + } + /// @return the color of the face containing dh + /// used only if colored_face(alcc, dh) + template + CGAL::Color face_color(const LCC& alcc, + typename LCC::Dart_const_handle dh) const + { + CGAL::Random random((unsigned int)(alcc.darts().index(dh))); + return get_random_color(random); + } + /// @return the color of the edge containing dh + /// used only if colored_edge(alcc, dh) + template + CGAL::Color edge_color(const LCC& alcc, + typename LCC::Dart_const_handle dh) const + { + CGAL::Random random((unsigned int)(alcc.darts().index(dh))); + return get_random_color(random); + } + /// @return the color of the vertex containing dh + /// used only if colored_vertex(alcc, dh) + template + CGAL::Color vertex_color(const LCC& alcc, + typename LCC::Dart_const_handle dh) const + { CGAL::Random random((unsigned int)(alcc.darts().index(dh))); return get_random_color(random); } @@ -73,7 +154,7 @@ struct LCC_geom_utils }; // Viewer class for LCC -template +template class SimpleLCCViewerQt : public Basic_viewer_qt { typedef Basic_viewer_qt Base; @@ -89,42 +170,68 @@ public: /// @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 LCC* alcc=NULL, const char* title="Basic LCC Viewer", bool anofaces=false, - const ColorFunctor& fcolor=ColorFunctor()) : + const DrawingFunctorLCC& drawing_functor=DrawingFunctorLCC()) : // 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) + m_random_face_color(false), + m_drawing_functor(drawing_functor) { compute_elements(); } protected: - void compute_face(Dart_const_handle dh) + void set_lcc(const LCC* alcc, bool doredraw=true) { + lcc=alcc; + compute_elements(); + if (doredraw) { redraw(); } + } + + void compute_face(Dart_const_handle dh, Dart_const_handle voldh) + { + if (m_nofaces || !m_drawing_functor.draw_face(*lcc, dh)) return; + // 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 (!lcc->is_next_exist(cur)) return; // open face=>not filled if (curnext(cur); } while(cur!=dh); - - CGAL::Color c=m_fcolor.run(lcc, dh); - face_begin(c); + + if (m_random_face_color) + { + CGAL::Random random((unsigned int)(lcc->darts().index(dh))); + CGAL::Color c=get_random_color(random); + face_begin(c); + } + else if (m_drawing_functor.colored_face(*lcc, dh)) + { + CGAL::Color c=m_drawing_functor.face_color(*lcc, dh); + face_begin(c); + } + else if (m_drawing_functor.colored_volume(*lcc, voldh)) + { + CGAL::Color c=m_drawing_functor.volume_color(*lcc, voldh); + face_begin(c); + } + else + { face_begin(); } cur=dh; do { - add_point_in_face(lcc.point(cur), LCC_geom_utils:: - get_vertex_normal(lcc, cur)); - cur=lcc.next(cur); + add_point_in_face(lcc->point(cur), LCC_geom_utils:: + get_vertex_normal(*lcc, cur)); + cur=lcc->next(cur); } while(cur!=dh); @@ -133,77 +240,143 @@ protected: void compute_edge(Dart_const_handle dh) { - Point p1 = lcc.point(dh); - Dart_const_handle d2 = lcc.other_extremity(dh); + if (!m_drawing_functor.draw_edge(*lcc, dh)) return; + + Point p1 = lcc->point(dh); + Dart_const_handle d2 = lcc->other_extremity(dh); if (d2!=NULL) - { add_segment(p1, lcc.point(d2)); } + { + if (m_drawing_functor.colored_edge(*lcc, dh)) + { add_segment(p1, lcc->point(d2), m_drawing_functor.edge_color(*lcc, dh)); } + else + { add_segment(p1, lcc->point(d2)); } + } } void compute_vertex(Dart_const_handle dh) - { add_point(lcc.point(dh)); } + { + if (!m_drawing_functor.draw_vertex(*lcc, dh)) return; + + if (m_drawing_functor.colored_vertex(*lcc, dh)) + { add_point(lcc->point(dh), m_drawing_functor.vertex_color(*lcc, dh)); } + else + { add_point(lcc->point(dh)); } + } void compute_elements() { clear(); + if (lcc==NULL) return; + + typename LCC::size_type markvolumes = lcc->get_new_mark(); + 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(); - 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 ) + 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) ) + if (!lcc->is_marked(it, markvolumes) && + m_drawing_functor.draw_volume(*lcc, it)) { - 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); + for (typename LCC::template Dart_of_cell_basic_range<3>:: + const_iterator itv=lcc->template darts_of_cell_basic<3>(it, markvolumes).begin(), + itvend=lcc->template darts_of_cell_basic<3>(it, markvolumes).end(); + itv!=itvend; ++itv) + { + lcc->mark(itv, markvolumes); // To be sure that all darts of the basic iterator will be marked + if (!lcc->is_marked(itv, markfaces) && + m_drawing_functor.draw_face(*lcc, itv)) + { + if (!m_drawing_functor.volume_wireframe(*lcc, itv) && + !m_drawing_functor.face_wireframe(*lcc, itv)) + { compute_face(itv, it); } + for (typename LCC::template Dart_of_cell_basic_range<2>:: + const_iterator itf=lcc->template darts_of_cell_basic<2>(itv, markfaces).begin(), + itfend=lcc->template darts_of_cell_basic<2>(itv, markfaces).end(); + itf!=itfend; ++itf) + { + if (!m_drawing_functor.volume_wireframe(*lcc, itv) && + !m_drawing_functor.face_wireframe(*lcc, itv)) + { lcc->mark(itf, markfaces); } // To be sure that all darts of the basic iterator will be marked + if ( !lcc->is_marked(itf, markedges) && + m_drawing_functor.draw_edge(*lcc, itf)) + { + compute_edge(itf); + for (typename LCC::template Dart_of_cell_basic_range<1>:: + const_iterator ite=lcc->template darts_of_cell_basic<1>(itf, markedges).begin(), + iteend=lcc->template darts_of_cell_basic<1>(itf, markedges).end(); + ite!=iteend; ++ite) + { + lcc->mark(ite, markedges); // To be sure that all darts of the basic iterator will be marked + if ( !lcc->is_marked(ite, markvertices) && + m_drawing_functor.draw_vertex(*lcc, ite)) + { + compute_vertex(ite); + CGAL::mark_cell(*lcc, ite, markvertices); + } + } + } + } + } + } } } - lcc.free_mark(markfaces); - lcc.free_mark(markedges); - lcc.free_mark(markvertices); - } + for (typename LCC::Dart_range::const_iterator it=lcc->darts().begin(), + itend=lcc->darts().end(); it!=itend; ++it ) + { + lcc->unmark(it, markvertices); + lcc->unmark(it, markedges); + lcc->unmark(it, markfaces); + lcc->unmark(it, markvolumes); + } + + lcc->free_mark(markvolumes); + lcc->free_mark(markfaces); + lcc->free_mark(markedges); + lcc->free_mark(markvertices); + } + + virtual void init() + { + Base::init(); + setKeyDescription(::Qt::Key_C, "Toggles random face colors"); + } + virtual void keyPressEvent(QKeyEvent *e) { - // Test key pressed: - // const ::Qt::KeyboardModifiers modifiers = e->modifiers(); - // if ((e->key()==Qt::Key_PageUp) && (modifiers==Qt::NoButton)) { ... } + const ::Qt::KeyboardModifiers modifiers = e->modifiers(); + if ((e->key()==::Qt::Key_C) && (modifiers==::Qt::NoButton)) + { + m_random_face_color=!m_random_face_color; + displayMessage(QString("Random face color=%1.").arg(m_random_face_color?"true":"false")); + compute_elements(); + redraw(); + } + else + { Base::keyPressEvent(e); } // Call the base method to process others/classicals key // 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; + const LCC* lcc; bool m_nofaces; - const ColorFunctor& m_fcolor; + bool m_random_face_color; + const DrawingFunctorLCC& m_drawing_functor; }; -template +template void draw(const LCC& alcc, const char* title, bool nofill, - const ColorFunctor& fcolor) + const DrawingFunctorLCC& drawing_functor) { #if defined(CGAL_TEST_SUITE) bool cgal_test_suite=true; @@ -216,11 +389,11 @@ void draw(const LCC& alcc, int argc=1; const char* argv[2]={"lccviewer","\0"}; QApplication app(argc,const_cast(argv)); - SimpleLCCViewerQt mainwindow(app.activeWindow(), - alcc, - title, - nofill, - fcolor); + SimpleLCCViewerQt mainwindow(app.activeWindow(), + &alcc, + title, + nofill, + drawing_functor); mainwindow.show(); app.exec(); } @@ -229,8 +402,8 @@ void draw(const LCC& alcc, template void draw(const LCC& alcc, const char* title, bool nofill) { - DefaultColorFunctorLCC c; - draw(alcc, title, nofill, c); + DefaultDrawingFunctorLCC f; + draw(alcc, title, nofill, f); } template diff --git a/Mesh_2/test/Mesh_2/test_double_map.cpp b/Mesh_2/test/Mesh_2/test_double_map.cpp index a8e1597cf75..7d05a3f7cfc 100644 --- a/Mesh_2/test/Mesh_2/test_double_map.cpp +++ b/Mesh_2/test/Mesh_2/test_double_map.cpp @@ -71,7 +71,7 @@ int main(int argc, char** argv) std::cerr << "Assignment f2=f...\n"; f2 = f; // check the assignment std::cerr << "Auto-assignment f=f...\n"; - f2 = f2; // check the auto-assignment + f2 = (Map&)f2; // check the auto-assignment std::cerr << "Copy-construction...\n"; Map f3(f); // check the copy constructor diff --git a/Mesh_3/examples/Mesh_3/CMakeLists.txt b/Mesh_3/examples/Mesh_3/CMakeLists.txt index 73911e50fc1..40112d910f1 100644 --- a/Mesh_3/examples/Mesh_3/CMakeLists.txt +++ b/Mesh_3/examples/Mesh_3/CMakeLists.txt @@ -14,6 +14,10 @@ if ( MESH_3_VERBOSE ) add_definitions(-DCGAL_MESH_3_VERBOSE) endif() +if(POLICY CMP0074) + cmake_policy(SET CMP0074 NEW) +endif() + find_package(CGAL COMPONENTS ImageIO) if ( CGAL_FOUND ) diff --git a/Mesh_3/include/CGAL/Mesh_3/Mesher_level.h b/Mesh_3/include/CGAL/Mesh_3/Mesher_level.h index 932de589365..c5554f3e109 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Mesher_level.h +++ b/Mesh_3/include/CGAL/Mesh_3/Mesher_level.h @@ -1048,6 +1048,11 @@ public: { // Lock the element area on the grid Element element = derivd.extract_element_from_container_value(ce); + + // This is safe to do with the concurrent compact container because even if the element `ce` + // gets removed from the TDS at this point, it is not actually deleted in the cells container and + // `ce->vertex(0-3)` still points to a vertex of the vertices container whose `.point()` + // can be safely accessed (even if that vertex has itself also been removed from the TDS). bool locked = derivd.try_lock_element(element, FIRST_GRID_LOCK_RADIUS); if( locked ) diff --git a/Mesh_3/test/Mesh_3/CMakeLists.txt b/Mesh_3/test/Mesh_3/CMakeLists.txt index 61800ebca61..1dd4729c042 100644 --- a/Mesh_3/test/Mesh_3/CMakeLists.txt +++ b/Mesh_3/test/Mesh_3/CMakeLists.txt @@ -6,6 +6,9 @@ project( Mesh_3_Tests ) cmake_minimum_required(VERSION 3.1) +if(POLICY CMP0074) + cmake_policy(SET CMP0074 NEW) +endif() find_package(CGAL QUIET COMPONENTS ImageIO) 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 abb6cdf0909..9255e725f81 100644 --- a/Mesh_3/test/Mesh_3/test_c3t3_with_features.cpp +++ b/Mesh_3/test/Mesh_3/test_c3t3_with_features.cpp @@ -314,7 +314,9 @@ struct Tester // Test edge iterators //------------------------------------------------------- std::cout << "Test edge iterators\n"; - const Edge& edge_to_modify = *(c3t3.edges_in_complex_begin()); + typename C3t3::Edges_in_complex_iterator eit = c3t3.edges_in_complex_begin(); + assert(eit != c3t3.edges_in_complex_end()); + const Edge& edge_to_modify = *eit; c3t3.remove_from_complex(edge_to_modify); c3t3.add_to_complex(edge_to_modify,curve_index_bis); diff --git a/Mesher_level/include/CGAL/Double_map.h b/Mesher_level/include/CGAL/Double_map.h index 517cb223b13..7de1f9d66e6 100644 --- a/Mesher_level/include/CGAL/Double_map.h +++ b/Mesher_level/include/CGAL/Double_map.h @@ -40,8 +40,15 @@ #endif #ifdef CGAL_USE_BOOST_BIMAP +# if defined(BOOST_MSVC) +# pragma warning(push) +# pragma warning(disable: 4996) +# endif #include #include +# if defined(BOOST_MSVC) +# pragma warning(pop) +# endif #endif namespace CGAL { diff --git a/Modular_arithmetic/test/Modular_arithmetic/Residue.cpp b/Modular_arithmetic/test/Modular_arithmetic/Residue.cpp index 2329d54e81e..1fdadfd0888 100644 --- a/Modular_arithmetic/test/Modular_arithmetic/Residue.cpp +++ b/Modular_arithmetic/test/Modular_arithmetic/Residue.cpp @@ -102,7 +102,7 @@ int main() assert(mod_x == CGAL::modular_image(int_x)); int_x -= int_x; int_x = CGAL::mod(int_x, prime); - mod_x -= mod_x; + mod_x -= (CGAL::Residue&)mod_x; } { CGAL::Residue::set_current_prime(67111043); diff --git a/Nef_3/include/CGAL/boost/graph/convert_nef_polyhedron_to_polygon_mesh.h b/Nef_3/include/CGAL/boost/graph/convert_nef_polyhedron_to_polygon_mesh.h index 369db23902d..7393881de00 100644 --- a/Nef_3/include/CGAL/boost/graph/convert_nef_polyhedron_to_polygon_mesh.h +++ b/Nef_3/include/CGAL/boost/graph/convert_nef_polyhedron_to_polygon_mesh.h @@ -343,36 +343,45 @@ void collect_polygon_mesh_info( } //end of namespace nef_to_pm - -template -void convert_nef_polyhedron_to_polygon_mesh(const Nef_polyhedron& nef, Polygon_mesh& pm, bool triangulate_all_faces = false) +template +void convert_nef_polyhedron_to_polygon_soup(const Nef_polyhedron& nef, + std::vector& points, + std::vector< std::vector >& polygons, + bool triangulate_all_faces = false) { typedef typename Nef_polyhedron::Point_3 Point_3; - typedef typename boost::property_traits::type>::value_type PM_Point; - typedef typename Kernel_traits::Kernel PM_Kernel; typedef typename Kernel_traits::Kernel Nef_Kernel; - typedef Cartesian_converter Converter; - + typedef Cartesian_converter Converter; + typedef typename Output_kernel::Point_3 Out_point; typename Nef_polyhedron::Volume_const_iterator vol_it = nef.volumes_begin(), vol_end = nef.volumes_end(); if ( Nef_polyhedron::Infi_box::extended_kernel() ) ++vol_it; // skip Infi_box CGAL_assertion ( vol_it != vol_end ); ++vol_it; // skip unbounded volume + Converter to_output; + for (;vol_it!=vol_end;++vol_it) + nef_to_pm::collect_polygon_mesh_info(points, + polygons, + nef, + vol_it->shells_begin(), + to_output, + triangulate_all_faces); +} + +template +void convert_nef_polyhedron_to_polygon_mesh(const Nef_polyhedron& nef, Polygon_mesh& pm, bool triangulate_all_faces = false) +{ + typedef typename boost::property_traits::type>::value_type PM_Point; + typedef typename Kernel_traits::Kernel PM_Kernel; + std::vector points; std::vector< std::vector > polygons; - Converter to_inexact; - for (;vol_it!=vol_end;++vol_it) - nef_to_pm::collect_polygon_mesh_info(points, - polygons, - nef, - vol_it->shells_begin(), - to_inexact, - triangulate_all_faces); - + convert_nef_polyhedron_to_polygon_soup(nef, points, polygons, triangulate_all_faces); Polygon_mesh_processing::polygon_soup_to_polygon_mesh(points, polygons, pm); } + } //end of namespace CGAL diff --git a/Nef_S2/include/CGAL/Nef_S2/Sphere_geometry_OGL.h b/Nef_S2/include/CGAL/Nef_S2/Sphere_geometry_OGL.h index e7904529787..f0527bb932b 100644 --- a/Nef_S2/include/CGAL/Nef_S2/Sphere_geometry_OGL.h +++ b/Nef_S2/include/CGAL/Nef_S2/Sphere_geometry_OGL.h @@ -71,6 +71,23 @@ VVector convert(const CGAL::Vector_3& v) CGAL::to_double(v.y()), CGAL::to_double(v.z())); } +template +VVector normalize_and_convert(const CGAL::Vector_3& v) +{ + typename R::FT xa = CGAL::abs(v.x()); + typename R::FT ya = CGAL::abs(v.y()); + typename R::FT za = CGAL::abs(v.z()); + typename R::FT m = (std::max)((std::max)(xa,ya),za); + if (m==0) { + return VVector(0,0,0); + } else { + double xd = CGAL::to_double(v.x()/m); + double yd = CGAL::to_double(v.y()/m); + double zd = CGAL::to_double(v.z()/m); + VVector u(xd,yd,zd); + return u / CGAL_NTS sqrt(u*u) ; // normalize + } +} const double refinement_angle = 0.1; const double shrink_fac = 0.995; @@ -80,8 +97,7 @@ class Approximator { public: static VPoint approximate(const CGAL::Sphere_point& p) { - VVector v = convert(p-CGAL::ORIGIN); - v = v / CGAL_NTS sqrt(v*v) ; // normalize + VVector v = normalize_and_convert(p-CGAL::ORIGIN); return CGAL::ORIGIN+v; } diff --git a/Nef_S2/include/CGAL/Nef_polyhedron_S2.h b/Nef_S2/include/CGAL/Nef_polyhedron_S2.h index 7a5dc5ffc9d..c980fabd6f3 100644 --- a/Nef_S2/include/CGAL/Nef_polyhedron_S2.h +++ b/Nef_S2/include/CGAL/Nef_polyhedron_S2.h @@ -350,6 +350,11 @@ public: f->mark() == true); } + bool is_sphere() const + { + return is_plane(); + } + void extract_complement() { CGAL_NEF_TRACEN("extract complement"); if ( this->is_shared() ) clone_rep(); @@ -375,7 +380,7 @@ public: SHalfedge_iterator e; CGAL_forall_svertices(v,D) v->mark() = false; CGAL_forall_sedges(e,D) e->mark() = false; - if ( D.has_sloop() ) D.shalfloop()->mark() = false; + if ( D.has_shalfloop() ) D.shalfloop()->mark() = false; D.simplify(); } @@ -390,7 +395,7 @@ public: CGAL_forall_svertices(v,D) v->mark() = true; CGAL_forall_sedges(e,D) e->mark() = true; CGAL_forall_sfaces(f,D) f->mark() = false; - if ( D.has_sloop() ) D.shalfloop()->mark() = D.shalfoop()->twin() = true; + if ( D.has_shalfloop() ) D.shalfloop()->mark() = D.shalfoop()->twin()->mark() = true; D.simplify(); } diff --git a/NewKernel_d/include/CGAL/NewKernel_d/Vector/array.h b/NewKernel_d/include/CGAL/NewKernel_d/Vector/array.h index 2a80ddf7e41..6f9aa5bb3f2 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/Vector/array.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/Vector/array.h @@ -70,6 +70,7 @@ template struct Array_vector { CGAL_assertion(d<=d_); //TODO: optimize for forward iterators Vector a; + CGAL_assume(f!=e); std::copy(f,e,a.begin()); return a; } diff --git a/Number_types/test/Number_types/Interval_nt.cpp b/Number_types/test/Number_types/Interval_nt.cpp index f2ca4dcf5ab..9d6ff105124 100644 --- a/Number_types/test/Number_types/Interval_nt.cpp +++ b/Number_types/test/Number_types/Interval_nt.cpp @@ -211,7 +211,7 @@ bool multiplication_test() g = d * e; h = d * f; i = a * e; - j = j; + j = (IA_nt&)j; // When CGAL_IA_DEBUG is defined, it'll test the current rounding mode for // these operations. diff --git a/Optimal_transportation_reconstruction_2/demo/Optimal_transportation_reconstruction_2/CMakeLists.txt b/Optimal_transportation_reconstruction_2/demo/Optimal_transportation_reconstruction_2/CMakeLists.txt index 347644cd409..86f1b6be942 100644 --- a/Optimal_transportation_reconstruction_2/demo/Optimal_transportation_reconstruction_2/CMakeLists.txt +++ b/Optimal_transportation_reconstruction_2/demo/Optimal_transportation_reconstruction_2/CMakeLists.txt @@ -8,6 +8,10 @@ if(NOT POLICY CMP0070 AND POLICY CMP0053) cmake_policy(SET CMP0053 OLD) endif() +if(POLICY CMP0071) + cmake_policy(SET CMP0071 NEW) +endif() + # Include this package's headers first include_directories( BEFORE ./ ./include ) diff --git a/Optimal_transportation_reconstruction_2/doc/Optimal_transportation_reconstruction_2/Concepts/OptimalTransportationReconstructionTraits_2.h b/Optimal_transportation_reconstruction_2/doc/Optimal_transportation_reconstruction_2/Concepts/OptimalTransportationReconstructionTraits_2.h index 04c9035a830..54551b8a64d 100644 --- a/Optimal_transportation_reconstruction_2/doc/Optimal_transportation_reconstruction_2/Concepts/OptimalTransportationReconstructionTraits_2.h +++ b/Optimal_transportation_reconstruction_2/doc/Optimal_transportation_reconstruction_2/Concepts/OptimalTransportationReconstructionTraits_2.h @@ -149,7 +149,6 @@ public: /// @{ Construct_point_2 construct_point_2_object(); Construct_vector_2 construct_vector_2_object(); - Construct_vector_2 construct_vector_2_object(); Construct_line_2 construct_line_2_object(); Construct_translated_point_2 construct_translated_point_2_object(); Construct_scaled_vector_2 construct_scaled_vector_2_object(); diff --git a/Periodic_3_mesh_3/include/CGAL/Periodic_3_mesh_3/Protect_edges_sizing_field.h b/Periodic_3_mesh_3/include/CGAL/Periodic_3_mesh_3/Protect_edges_sizing_field.h index 05b76b7b2ec..ef21d9dc89b 100644 --- a/Periodic_3_mesh_3/include/CGAL/Periodic_3_mesh_3/Protect_edges_sizing_field.h +++ b/Periodic_3_mesh_3/include/CGAL/Periodic_3_mesh_3/Protect_edges_sizing_field.h @@ -772,7 +772,6 @@ get_positions_with_vertex_at_extremity(const Bare_point& known_point, << " inverted order ? " << std::boolalpha << inverted_return_order << std::endl; #endif - CGAL_precondition(known_point != Bare_point()); CGAL_precondition(!domain_.is_loop(curve_index)); CGAL_precondition(extremity_points.size() == 2); diff --git a/Periodic_3_mesh_3/include/CGAL/optimize_periodic_3_mesh_3.h b/Periodic_3_mesh_3/include/CGAL/optimize_periodic_3_mesh_3.h index 31f5fb4b8cc..8aeb4874ea2 100644 --- a/Periodic_3_mesh_3/include/CGAL/optimize_periodic_3_mesh_3.h +++ b/Periodic_3_mesh_3/include/CGAL/optimize_periodic_3_mesh_3.h @@ -33,6 +33,11 @@ namespace CGAL { +#if defined(BOOST_MSVC) +# pragma warning(push) +# pragma warning(disable:4003) // not enough actual parameters for macro +#endif + // see CGAL_PRAGMA_DIAG_PUSH // see @@ -120,6 +125,10 @@ BOOST_PARAMETER_FUNCTION( CGAL_PRAGMA_DIAG_POP +#if defined(BOOST_MSVC) +# pragma warning(pop) +#endif + } // namespace CGAL #endif // CGAL_OPTIMIZE_PERIODIC_3_MESH_3_H diff --git a/Periodic_3_mesh_3/include/CGAL/refine_periodic_3_mesh_3.h b/Periodic_3_mesh_3/include/CGAL/refine_periodic_3_mesh_3.h index c39ed5d3d6b..16e854200c5 100644 --- a/Periodic_3_mesh_3/include/CGAL/refine_periodic_3_mesh_3.h +++ b/Periodic_3_mesh_3/include/CGAL/refine_periodic_3_mesh_3.h @@ -116,7 +116,6 @@ void project_points(C3T3& c3t3, const Weighted_point& vh_wp = c3t3.triangulation().point(vh); const Bare_point& vh_p = cp(vh_wp); const Bare_point new_point = helper.project_on_surface(vh, vh_p); - CGAL_assertion(new_point != Bare_point()); const FT sq_d = CGAL::squared_distance(new_point, vh_p); @@ -144,6 +143,11 @@ void project_points(C3T3& c3t3, } // namespace internal +#if defined(BOOST_MSVC) +# pragma warning(push) +# pragma warning(disable:4003) // not enough actual parameters for macro +#endif + // see CGAL_PRAGMA_DIAG_PUSH // see @@ -181,6 +185,10 @@ BOOST_PARAMETER_FUNCTION( CGAL_PRAGMA_DIAG_POP +#if defined(BOOST_MSVC) +# pragma warning(pop) +#endif + /** * @brief This function refines the mesh c3t3 wrt domain & criteria * diff --git a/Periodic_3_triangulation_3/demo/Periodic_3_triangulation_3/CMakeLists.txt b/Periodic_3_triangulation_3/demo/Periodic_3_triangulation_3/CMakeLists.txt index 78cf24b1e25..b3b8b63f561 100644 --- a/Periodic_3_triangulation_3/demo/Periodic_3_triangulation_3/CMakeLists.txt +++ b/Periodic_3_triangulation_3/demo/Periodic_3_triangulation_3/CMakeLists.txt @@ -10,6 +10,10 @@ if(NOT POLICY CMP0070 AND POLICY CMP0053) cmake_policy(SET CMP0053 OLD) endif() +if(POLICY CMP0071) + cmake_policy(SET CMP0071 NEW) +endif() + # Find CGAL find_package(CGAL COMPONENTS Qt5) diff --git a/Point_set_3/doc/Point_set_3/PackageDescription.txt b/Point_set_3/doc/Point_set_3/PackageDescription.txt index 9353b29bc54..2c2a538ef71 100644 --- a/Point_set_3/doc/Point_set_3/PackageDescription.txt +++ b/Point_set_3/doc/Point_set_3/PackageDescription.txt @@ -1,6 +1,6 @@ -/*! -\defgroup PkgPointSet3Ref 3D Point Set Reference +/// \defgroup PkgPointSet3Ref 3D Point Set Reference +/*! \cgalPkgDescriptionBegin{3D Point Set, PkgPointSet3} \cgalPkgPicture{point_set_3.png} \cgalPkgSummaryBegin diff --git a/Point_set_3/include/CGAL/Point_set_3/IO.h b/Point_set_3/include/CGAL/Point_set_3/IO.h index 93117799195..35560d89027 100644 --- a/Point_set_3/include/CGAL/Point_set_3/IO.h +++ b/Point_set_3/include/CGAL/Point_set_3/IO.h @@ -135,7 +135,7 @@ private: struct Abstract_ply_property_to_point_set_property { virtual ~Abstract_ply_property_to_point_set_property() { } - virtual void assign (PLY_reader& reader, typename Point_set::Index index) = 0; + virtual void assign (PLY_element& element, typename Point_set::Index index) = 0; }; template @@ -154,10 +154,10 @@ private: m_pmap = ps.push_property_map (m_map); } - virtual void assign (PLY_reader& reader, typename Point_set::Index index) + virtual void assign (PLY_element& element, typename Point_set::Index index) { - Type t; - reader.assign (t, m_name.c_str()); + Type t{}; + element.assign (t, m_name.c_str()); put(m_pmap, index, t); } }; @@ -178,123 +178,121 @@ public: delete m_properties[i]; } - void instantiate_properties (PLY_reader& reader) + void instantiate_properties (PLY_element& element) { - const std::vector& readers - = reader.readers(); - bool has_normal[3] = { false, false, false }; - for (std::size_t i = 0; i < readers.size(); ++ i) + for (std::size_t j = 0; j < element.number_of_properties(); ++ j) + { + internal::PLY::PLY_read_number* property = element.property(j); + + const std::string& name = property->name(); + if (name == "x" || + name == "y" || + name == "z") { - const std::string& name = readers[i]->name(); - if (name == "x" || - name == "y" || - name == "z") - { - if (dynamic_cast*>(readers[i])) - m_use_floats = true; - continue; - } - if (name == "nx") - { - has_normal[0] = true; - continue; - } - if (name == "ny") - { - has_normal[1] = true; - continue; - } - if (name == "nz") - { - has_normal[2] = true; - continue; - } - - if (dynamic_cast*>(readers[i])) - { - m_properties.push_back - (new PLY_property_to_point_set_property(m_point_set, - name)); - } - else if (dynamic_cast*>(readers[i])) - { - m_properties.push_back - (new PLY_property_to_point_set_property(m_point_set, - name)); - } - else if (dynamic_cast*>(readers[i])) - { - m_properties.push_back - (new PLY_property_to_point_set_property(m_point_set, - name)); - } - else if (dynamic_cast*>(readers[i])) - { - m_properties.push_back - (new PLY_property_to_point_set_property(m_point_set, - name)); - } - else if (dynamic_cast*>(readers[i])) - { - m_properties.push_back - (new PLY_property_to_point_set_property(m_point_set, - name)); - } - else if (dynamic_cast*>(readers[i])) - { - m_properties.push_back - (new PLY_property_to_point_set_property(m_point_set, - name)); - } - else if (dynamic_cast*>(readers[i])) - { - m_properties.push_back - (new PLY_property_to_point_set_property(m_point_set, - name)); - } - else if (dynamic_cast*>(readers[i])) - { - m_properties.push_back - (new PLY_property_to_point_set_property(m_point_set, - name)); - } + if (dynamic_cast*>(property)) + m_use_floats = true; + continue; + } + if (name == "nx") + { + has_normal[0] = true; + continue; + } + if (name == "ny") + { + has_normal[1] = true; + continue; + } + if (name == "nz") + { + has_normal[2] = true; + continue; } + if (dynamic_cast*>(property)) + { + m_properties.push_back + (new PLY_property_to_point_set_property(m_point_set, + name)); + } + else if (dynamic_cast*>(property)) + { + m_properties.push_back + (new PLY_property_to_point_set_property(m_point_set, + name)); + } + else if (dynamic_cast*>(property)) + { + m_properties.push_back + (new PLY_property_to_point_set_property(m_point_set, + name)); + } + else if (dynamic_cast*>(property)) + { + m_properties.push_back + (new PLY_property_to_point_set_property(m_point_set, + name)); + } + else if (dynamic_cast*>(property)) + { + m_properties.push_back + (new PLY_property_to_point_set_property(m_point_set, + name)); + } + else if (dynamic_cast*>(property)) + { + m_properties.push_back + (new PLY_property_to_point_set_property(m_point_set, + name)); + } + else if (dynamic_cast*>(property)) + { + m_properties.push_back + (new PLY_property_to_point_set_property(m_point_set, + name)); + } + else if (dynamic_cast*>(property)) + { + m_properties.push_back + (new PLY_property_to_point_set_property(m_point_set, + name)); + } + } if (has_normal[0] && has_normal[1] && has_normal[2]) m_point_set.add_normal_map(); } - void process_line (PLY_reader& reader) + void process_line (PLY_element& element) { m_point_set.insert(); if (m_use_floats) - process_line(reader); + process_line(element); else - process_line(reader); + process_line(element); for (std::size_t i = 0; i < m_properties.size(); ++ i) - m_properties[i]->assign (reader, *(m_point_set.end() - 1)); + m_properties[i]->assign (element, *(m_point_set.end() - 1)); } template - void process_line (PLY_reader& reader) + void process_line (PLY_element& element) { FT x = (FT)0.,y = (FT)0., z = (FT)0., nx = (FT)0., ny = (FT)0., nz = (FT)0.; - reader.assign (x, "x"); - reader.assign (y, "y"); - reader.assign (z, "z"); + element.assign (x, "x"); + element.assign (y, "y"); + element.assign (z, "z"); Point point (x, y, z); m_point_set.point(*(m_point_set.end() - 1)) = point; if (m_point_set.has_normal_map()) { - reader.assign (nx, "nx"); - reader.assign (ny, "ny"); - reader.assign (nz, "nz"); + element.assign (nx, "nx"); + element.assign (ny, "ny"); + element.assign (nz, "nz"); Vector normal (nx, ny, nz); m_point_set.normal(*(m_point_set.end() - 1)) = normal; } @@ -396,29 +394,40 @@ read_ply_point_set( internal::PLY::Point_set_3_filler filler(point_set); if (!(reader.init (stream))) + { + stream.setstate(std::ios::failbit); return false; + } if (comments != NULL) *comments = reader.comments(); - filler.instantiate_properties (reader); + for (std::size_t i = 0; i < reader.number_of_elements(); ++ i) + { + internal::PLY::PLY_element& element = reader.element(i); - point_set.reserve (reader.m_nb_points); - - std::size_t points_read = 0; - - while (!(stream.eof()) && points_read < reader.m_nb_points) + if (element.name() == "vertex" || element.name() == "vertices") { - for (std::size_t i = 0; i < reader.readers().size (); ++ i) - reader.readers()[i]->get (stream); - - filler.process_line (reader); - - ++ points_read; + point_set.reserve (element.number_of_items()); + filler.instantiate_properties (element); } - // Skip remaining lines + + for (std::size_t j = 0; j < element.number_of_items(); ++ j) + { + for (std::size_t k = 0; k < element.number_of_properties(); ++ k) + { + internal::PLY::PLY_read_number* property = element.property(k); + property->get (stream); + if (stream.fail()) + return false; + } - return (points_read == reader.m_nb_points); + if (element.name() == "vertex" || element.name() == "vertices") + filler.process_line (element); + } + } + + return true; } /*! diff --git a/Point_set_processing_3/doc/Point_set_processing_3/NamedParameters.txt b/Point_set_processing_3/doc/Point_set_processing_3/NamedParameters.txt index dcb0f56f626..ee321dfd95e 100644 --- a/Point_set_processing_3/doc/Point_set_processing_3/NamedParameters.txt +++ b/Point_set_processing_3/doc/Point_set_processing_3/NamedParameters.txt @@ -31,17 +31,17 @@ typename CGAL::Kernel_traits::Kernel \cgalNPEnd \cgalNPBegin{point_map} \anchor PSP_point_map - is the property map containing the points associated to the iterators of the point range `points`.\n + is the property map containing the points associated to the elements of the point range `points`.\n \b Type: a class model of `ReadablePropertyMap` with -`PointRange::iterator` as key type and +`PointRange::iterator::value_type` as key type and `geom_traits::Point_3` as value type. \n Default value: \code CGAL::Identity_property_map\endcode \cgalNPEnd \cgalNPBegin{normal_map} \anchor PSP_normal_map - is the property map containing the normal vectors associated to the iterators of the point range `points`.\n + is the property map containing the normal vectors associated to the elements of the point range `points`.\n \b Type: a class model of `ReadablePropertyMap` with -`PointRange::iterator` as key type and +`PointRange::iterator::value_type` as key type and `geom_traits::Vector_3` as value type. \n No default value. \cgalNPEnd @@ -67,9 +67,9 @@ Note that when a callback is run on a parallelized algorithm with `CGAL::Paralle \cgalNPEnd \cgalNPBegin{query_point_map} \anchor PSP_query_point_map - is the property map containing the points associated to the iterators of the point range `queries`.\n + is the property map containing the points associated to the elements of the point range `queries`.\n \b Type: a class model of `ReadablePropertyMap` with -`PointRange::iterator` as key type and +`PointRange::iterator::value_type` as key type and `geom_traits::Point_3` as value type. \n Default value: \code CGAL::Identity_property_map\endcode \cgalNPEnd @@ -146,9 +146,9 @@ multiple of a tolerance `epsilon` used to connect simplices. \cgalNPEnd \cgalNPBegin{plane_map} \anchor PSP_plane_map - is the property map containing the planes associated to the iterators of the plane range `planes`.\n + is the property map containing the planes associated to the elements of the plane range `planes`.\n \b Type: a class model of `ReadablePropertyMap` with -`PlaneRange::iterator` as key type and +`PlaneRange::iterator::value_type` as key type and `geom_traits::Plane_3` as value type. \n Default value: \code CGAL::Identity_property_map\endcode \cgalNPEnd @@ -182,6 +182,15 @@ give better result if the distribution of the input points is highly non-uniform Default value: `false` \cgalNPEnd +\cgalNPBegin{point_is_constrained_map} \anchor PSP_point_is_constrained_map +is the property map containing information about points being constrained or not. +Constrained points are left unaltered and are used as seeds in `mst_orient_normals()`.\n +\b Type: a class model of `ReadablePropertyMap` with +`PointRange::iterator::value_type` as key type and +`bool` as value type. \n +Default value: a property map with only the highest point constrained. +\cgalNPEnd + \cgalNPTableEnd */ diff --git a/Point_set_processing_3/doc/Point_set_processing_3/PackageDescription.txt b/Point_set_processing_3/doc/Point_set_processing_3/PackageDescription.txt index fd9ed9c57b9..a14dd5e1df7 100644 --- a/Point_set_processing_3/doc/Point_set_processing_3/PackageDescription.txt +++ b/Point_set_processing_3/doc/Point_set_processing_3/PackageDescription.txt @@ -1,7 +1,6 @@ +/// \defgroup PkgPointSetProcessing3Ref Point Set Processing Reference + /*! - -\defgroup PkgPointSetProcessing3Ref Point Set Processing Reference - \defgroup PkgPointSetProcessing3Algorithms Algorithms \ingroup PkgPointSetProcessing3Ref diff --git a/Point_set_processing_3/include/CGAL/IO/read_ply_points.h b/Point_set_processing_3/include/CGAL/IO/read_ply_points.h index d828d8052c3..1dd14548a94 100644 --- a/Point_set_processing_3/include/CGAL/IO/read_ply_points.h +++ b/Point_set_processing_3/include/CGAL/IO/read_ply_points.h @@ -48,12 +48,12 @@ #define TRY_TO_GENERATE_PROPERTY(STD_TYPE, T_TYPE, TYPE) \ if (type == STD_TYPE || type == T_TYPE) \ - m_properties->push_back (new PLY_read_typed_number< TYPE > (name, format)) + m_elements.back().add_property (new PLY_read_typed_number< TYPE > (name, format)) #define TRY_TO_GENERATE_SIZED_LIST_PROPERTY(STD_SIZE_TYPE, T_SIZE_TYPE, SIZE_TYPE, STD_INDEX_TYPE, T_INDEX_TYPE, INDEX_TYPE) \ if ((size_type == STD_SIZE_TYPE || size_type == T_SIZE_TYPE) && \ (index_type == STD_INDEX_TYPE || index_type == T_INDEX_TYPE)) \ - m_properties->push_back (new PLY_read_typed_list_with_typed_size< SIZE_TYPE , INDEX_TYPE > (name, format)) + m_elements.back().add_property (new PLY_read_typed_list_with_typed_size< SIZE_TYPE , INDEX_TYPE > (name, format)) #define TRY_TO_GENERATE_LIST_PROPERTY(STD_INDEX_TYPE, T_INDEX_TYPE, INDEX_TYPE) \ TRY_TO_GENERATE_SIZED_LIST_PROPERTY("uchar", "uint8", boost::uint8_t, STD_INDEX_TYPE, T_INDEX_TYPE, INDEX_TYPE); \ @@ -317,24 +317,145 @@ namespace internal { } }; + class PLY_element + { + std::string m_name; + std::size_t m_number; + + std::vector m_properties; + public: + + PLY_element (const std::string& name, std::size_t number) + : m_name (name), m_number (number) + { } + + PLY_element (const PLY_element& other) + : m_name (other.m_name), m_number (other.m_number), m_properties (other.m_properties) + { + const_cast(other).m_properties.clear(); + } + + PLY_element& operator= (const PLY_element& other) + { + m_name = other.m_name; + m_number = other.m_number; + m_properties = other.m_properties; + const_cast(other).m_properties.clear(); + return *this; + } + + ~PLY_element() + { + for (std::size_t i = 0; i < m_properties.size(); ++ i) + delete m_properties[i]; + } + + const std::string& name() const { return m_name; } + std::size_t number_of_items() const { return m_number; } + std::size_t number_of_properties() const { return m_properties.size(); } + + PLY_read_number* property (std::size_t idx) { return m_properties[idx]; } + + void add_property (PLY_read_number* read_number) + { + m_properties.push_back (read_number); + } + + template + bool has_property (const char* tag) + { + return has_property (tag, Type()); + } + template + bool has_property (const char* tag, const std::vector&) + { + for (std::size_t i = 0; i < number_of_properties(); ++ i) + if (m_properties[i]->name () == tag) + return (dynamic_cast*>(m_properties[i]) != NULL); + return false; + } + + template + bool has_property (const char* tag, Type) + { + for (std::size_t i = 0; i < number_of_properties(); ++ i) + if (m_properties[i]->name () == tag) + return (dynamic_cast*>(m_properties[i]) != NULL); + return false; + } + bool has_property (const char* tag, double) + { + for (std::size_t i = 0; i < number_of_properties(); ++ i) + if (m_properties[i]->name () == tag) + return (dynamic_cast*>(m_properties[i]) != NULL + || dynamic_cast*>(m_properties[i]) != NULL); + + return false; + } + + template + void assign (Type& t, const char* tag) + { + for (std::size_t i = 0; i < number_of_properties (); ++ i) + if (m_properties[i]->name () == tag) + { + PLY_read_typed_number* + property = dynamic_cast*>(m_properties[i]); + CGAL_assertion (property != NULL); + t = property->buffer(); + return; + } + } + + template + void assign (std::vector& t, const char* tag) + { + for (std::size_t i = 0; i < number_of_properties (); ++ i) + if (m_properties[i]->name () == tag) + { + PLY_read_typed_list* + property = dynamic_cast*>(m_properties[i]); + CGAL_assertion (property != NULL); + t = property->buffer(); + return; + } + } + + void assign (double& t, const char* tag) + { + for (std::size_t i = 0; i < number_of_properties (); ++ i) + if (m_properties[i]->name () == tag) + { + PLY_read_typed_number* + property_double = dynamic_cast*>(m_properties[i]); + if (property_double == NULL) + { + PLY_read_typed_number* + property_float = dynamic_cast*>(m_properties[i]); + CGAL_assertion (property_float != NULL); + t = property_float->buffer(); + } + else + t = property_double->buffer(); + + return; + } + } + + }; class PLY_reader { - std::vector m_point_properties; - std::vector m_face_properties; - std::vector* m_properties; + std::vector m_elements; std::string m_comments; public: - std::size_t m_nb_points; - std::size_t m_nb_faces; + PLY_reader () { } - PLY_reader () : m_properties (&m_point_properties), m_nb_points (0), m_nb_faces(0) { } - - const std::vector& readers() const { return *m_properties; } - void read_faces() + std::size_t number_of_elements() const { return m_elements.size(); } + PLY_element& element (std::size_t idx) { - m_properties = &m_face_properties; + return m_elements[idx]; } const std::string& comments() const { return m_comments; } @@ -349,9 +470,6 @@ namespace internal { std::string line; std::istringstream iss; - // Check the order of the properties of the point set - bool reading_vertices = false, reading_faces = false; - while (getline (stream,line)) { iss.clear(); @@ -401,9 +519,6 @@ namespace internal { if (keyword == "property") { - if (!reading_vertices && !reading_faces) - continue; - std::string type, name; if (!(iss >> type >> name)) { @@ -455,9 +570,6 @@ namespace internal { m_comments += "\n"; } } - // When end_header is reached, stop loop and begin reading points - else if (keyword == "end_header") - break; else if (keyword == "element") { std::string type; @@ -468,120 +580,18 @@ namespace internal { return false; } - if (type == "vertex") - { - m_nb_points = number; - reading_vertices = true; - reading_faces = false; - } - - else if (type == "face") - { - m_nb_faces = number; - reading_faces = true; - reading_vertices = false; - m_properties = &m_face_properties; - } - else - { - reading_faces = false; - reading_vertices = false; - continue; - } + m_elements.push_back (PLY_element(type, number)); } - + // When end_header is reached, stop loop and begin reading points + else if (keyword == "end_header") + break; } } - m_properties = &m_point_properties; return true; } ~PLY_reader () { - for (std::size_t i = 0; i < m_point_properties.size (); ++ i) - delete m_point_properties[i]; - m_point_properties.clear(); - } - - template - bool does_tag_exist (const char* tag) - { - return does_tag_exist (tag, Type()); - } - - template - void assign (Type& t, const char* tag) - { - for (std::size_t i = 0; i < m_properties->size (); ++ i) - if ((*m_properties)[i]->name () == tag) - { - PLY_read_typed_number* - reader = dynamic_cast*>((*m_properties)[i]); - CGAL_assertion (reader != NULL); - t = reader->buffer(); - return; - } - } - - template - void assign (std::vector& t, const char* tag) - { - for (std::size_t i = 0; i < m_properties->size (); ++ i) - if ((*m_properties)[i]->name () == tag) - { - PLY_read_typed_list* - reader = dynamic_cast*>((*m_properties)[i]); - CGAL_assertion (reader != NULL); - t = reader->buffer(); - return; - } - } - - template - bool does_tag_exist (const char* tag, const std::vector&) - { - for (std::size_t i = 0; i < m_properties->size (); ++ i) - if ((*m_properties)[i]->name () == tag) - return (dynamic_cast*>((*m_properties)[i]) != NULL); - return false; - } - - template - bool does_tag_exist (const char* tag, Type) - { - for (std::size_t i = 0; i < m_properties->size (); ++ i) - if ((*m_properties)[i]->name () == tag) - return (dynamic_cast*>((*m_properties)[i]) != NULL); - return false; - } - bool does_tag_exist (const char* tag, double) - { - for (std::size_t i = 0; i < m_properties->size (); ++ i) - if ((*m_properties)[i]->name () == tag) - return (dynamic_cast*>((*m_properties)[i]) != NULL - || dynamic_cast*>((*m_properties)[i]) != NULL); - - return false; - } - void assign (double& t, const char* tag) - { - for (std::size_t i = 0; i < m_properties->size (); ++ i) - if ((*m_properties)[i]->name () == tag) - { - PLY_read_typed_number* - reader_double = dynamic_cast*>((*m_properties)[i]); - if (reader_double == NULL) - { - PLY_read_typed_number* - reader_float = dynamic_cast*>((*m_properties)[i]); - CGAL_assertion (reader_float != NULL); - t = reader_float->buffer(); - } - else - t = reader_double->buffer(); - - return; - } } }; @@ -640,12 +650,12 @@ namespace internal { typename PropertyMap, typename Constructor, typename ... T> - void process_properties (PLY_reader& reader, OutputValueType& new_element, + void process_properties (PLY_element& element, OutputValueType& new_element, std::tuple...>&& current) { typedef typename PropertyMap::value_type PmapValueType; std::tuple values; - Filler::fill(reader, values, current); + Filler::fill(element, values, current); PmapValueType new_value = call_functor(std::get<1>(current), values); put (std::get<0>(current), new_element, new_value); } @@ -656,42 +666,42 @@ namespace internal { typename ... T, typename NextPropertyBinder, typename ... PropertyMapBinders> - void process_properties (PLY_reader& reader, OutputValueType& new_element, + void process_properties (PLY_element& element, OutputValueType& new_element, std::tuple...>&& current, NextPropertyBinder&& next, PropertyMapBinders&& ... properties) { typedef typename PropertyMap::value_type PmapValueType; std::tuple values; - Filler::fill(reader, values, current); + Filler::fill(element, values, current); PmapValueType new_value = call_functor(std::get<1>(current), values); put (std::get<0>(current), new_element, new_value); - process_properties (reader, new_element, std::forward(next), + process_properties (element, new_element, std::forward(next), std::forward(properties)...); } template - void process_properties (PLY_reader& reader, OutputValueType& new_element, + void process_properties (PLY_element& element, OutputValueType& new_element, std::pair >&& current) { T new_value = T(); - reader.assign (new_value, current.second.name); + element.assign (new_value, current.second.name); put (current.first, new_element, new_value); } template - void process_properties (PLY_reader& reader, OutputValueType& new_element, + void process_properties (PLY_element& element, OutputValueType& new_element, std::pair >&& current, NextPropertyBinder&& next, PropertyMapBinders&& ... properties) { T new_value = T(); - reader.assign (new_value, current.second.name); + element.assign (new_value, current.second.name); put (current.first, new_element, new_value); - process_properties (reader, new_element, std::forward(next), + process_properties (element, new_element, std::forward(next), std::forward(properties)...); } @@ -755,26 +765,36 @@ bool read_ply_points_with_properties (std::istream& stream, internal::PLY::PLY_reader reader; if (!(reader.init (stream))) + { + stream.setstate(std::ios::failbit); return false; + } - std::size_t points_read = 0; - - while (!(stream.eof()) && points_read < reader.m_nb_points) + for (std::size_t i = 0; i < reader.number_of_elements(); ++ i) + { + internal::PLY::PLY_element& element = reader.element(i); + + for (std::size_t j = 0; j < element.number_of_items(); ++ j) { - for (std::size_t i = 0; i < reader.readers().size (); ++ i) - reader.readers()[i]->get (stream); + for (std::size_t k = 0; k < element.number_of_properties(); ++ k) + { + internal::PLY::PLY_read_number* property = element.property(k); + property->get (stream); - OutputValueType new_element; + if (stream.fail()) + return false; + } - internal::PLY::process_properties (reader, new_element, std::forward(properties)...); - - *(output ++) = new_element; - - ++ points_read; + if (element.name() == "vertex" || element.name() == "vertices") + { + OutputValueType new_element; + internal::PLY::process_properties (element, new_element, std::forward(properties)...); + *(output ++) = new_element; + } } - // Skip remaining lines + } - return (points_read == reader.m_nb_points); + return true; } /// \cond SKIP_IN_MANUAL diff --git a/Point_set_processing_3/include/CGAL/mst_orient_normals.h b/Point_set_processing_3/include/CGAL/mst_orient_normals.h index 4935cd7d208..72cd4e3b48f 100644 --- a/Point_set_processing_3/include/CGAL/mst_orient_normals.h +++ b/Point_set_processing_3/include/CGAL/mst_orient_normals.h @@ -121,6 +121,34 @@ public: const NormalMap m_normal_map; }; +template +class Default_constrained_map +{ +public: + + typedef boost::readable_property_map_tag category; + typedef typename ForwardIterator::value_type key_type; + typedef bool value_type; + typedef value_type reference; + +private: + + ForwardIterator m_source_point; + +public: + + Default_constrained_map () { } + Default_constrained_map (ForwardIterator source_point) + : m_source_point (source_point) { } + + /// Free function to access the map elements. + friend inline + reference get(const Default_constrained_map& map, key_type p) + { + return (p == *map.m_source_point); + } + +}; /// Helper class: Propagate_normal_orientation /// @@ -145,10 +173,12 @@ struct Propagate_normal_orientation : public boost::base_visitor< Propagate_normal_orientation > { typedef internal::MST_graph MST_graph; + typedef typename MST_graph::vertex_descriptor vertex_descriptor; typedef boost::on_examine_edge event_filter; - Propagate_normal_orientation(double angle_max = CGAL_PI/2.) ///< max angle to propagate the normal orientation (radians) - : m_angle_max(angle_max) + Propagate_normal_orientation(vertex_descriptor source, + double angle_max = CGAL_PI/2.) ///< max angle to propagate the normal orientation (radians) + : m_source(source), m_angle_max(angle_max) { // Precondition: 0 < angle_max <= PI/2 CGAL_point_set_processing_precondition(0 < angle_max && angle_max <= CGAL_PI/2.); @@ -158,16 +188,28 @@ struct Propagate_normal_orientation void operator()(Edge& edge, const MST_graph& mst_graph) { typedef typename boost::property_traits::reference Vector_ref; - typedef typename MST_graph::vertex_descriptor vertex_descriptor; + + // Gets source + vertex_descriptor source_vertex = source(edge, mst_graph); + + // Gets target + vertex_descriptor target_vertex = target(edge, mst_graph); + bool& target_normal_is_oriented = ((MST_graph&)mst_graph)[target_vertex].is_oriented; + + // special case if vertex is source vertex (and thus has no related point/normal) + if (source_vertex == m_source) + { + target_normal_is_oriented = true; + return; + } // Gets source normal - vertex_descriptor source_vertex = source(edge, mst_graph); Vector_ref source_normal = get(mst_graph.m_normal_map, *(mst_graph[source_vertex].input_point) ); const bool source_normal_is_oriented = mst_graph[source_vertex].is_oriented; - // Gets target normal - vertex_descriptor target_vertex = target(edge, mst_graph); + + // Gets target Vector_ref target_normal = get( mst_graph.m_normal_map, *(mst_graph[target_vertex].input_point) ); - bool& target_normal_is_oriented = ((MST_graph&)mst_graph)[target_vertex].is_oriented; + if ( ! target_normal_is_oriented ) { // -> -> @@ -188,6 +230,7 @@ struct Propagate_normal_orientation // Data // Implementation note: boost::breadth_first_search() makes copies of this object => data must be constant or shared. private: + vertex_descriptor m_source; const double m_angle_max; ///< max angle to propagate the normal orientation (radians). }; @@ -264,6 +307,7 @@ template Riemannian_graph @@ -273,6 +317,7 @@ create_riemannian_graph( PointMap point_map, ///< property map: value_type of ForwardIterator -> Point_3 NormalMap normal_map, ///< property map: value_type of ForwardIterator -> Vector_3 IndexMap index_map, ///< property map ForwardIterator -> index + ConstrainedMap constrained_map, ///< property map ForwardIterator -> bool unsigned int k, ///< number of neighbors const Kernel& /*kernel*/) ///< geometric traits. { @@ -337,6 +382,11 @@ create_riemannian_graph( CGAL_point_set_processing_assertion(v == get(index_map,it)); riemannian_graph[v].input_point = it; } + + // add source vertex (virtual, does not correspond to a point) + add_vertex(riemannian_graph); + std::size_t source_point_index = num_input_points; + // // add edges Riemannian_graph_weight_map riemannian_graph_weight_map = get(boost::edge_weight, riemannian_graph); @@ -384,6 +434,20 @@ create_riemannian_graph( search_iterator++; } + + // Check if point is source + if (get(constrained_map, *it)) + { + typename boost::graph_traits::edge_descriptor e; + bool inserted; + boost::tie(e, inserted) = add_edge(vertex(it_index, riemannian_graph), + vertex(source_point_index, riemannian_graph), + riemannian_graph); + CGAL_point_set_processing_assertion(inserted); + + riemannian_graph_weight_map[e] = 0.; + } + } return riemannian_graph; @@ -418,8 +482,7 @@ create_mst_graph( IndexMap index_map, ///< property map ForwardIterator -> index unsigned int k, ///< number of neighbors const Kernel& kernel, ///< geometric traits. - const Riemannian_graph& riemannian_graph, ///< graph connecting each vertex to its knn - ForwardIterator source_point) ///< source point (with an oriented normal) + const Riemannian_graph& riemannian_graph) ///< graph connecting each vertex to its knn { // prevents warnings CGAL_USE(point_map); @@ -440,16 +503,17 @@ create_mst_graph( CGAL_point_set_processing_precondition(first != beyond); // Number of input points - const std::size_t num_input_points = num_vertices(riemannian_graph); + const std::size_t num_input_points = num_vertices(riemannian_graph) - 1; std::size_t memory = CGAL::Memory_sizer().virtual_size(); CGAL_TRACE(" %ld Mb allocated\n", memory>>20); CGAL_TRACE(" Calls boost::prim_minimum_spanning_tree()\n"); // Computes Minimum Spanning Tree. - std::size_t source_point_index = get(index_map, source_point); + std::size_t source_point_index = num_input_points; + Riemannian_graph_weight_map riemannian_graph_weight_map = get(boost::edge_weight, riemannian_graph); typedef std::vector PredecessorMap; - PredecessorMap predecessor(num_input_points); + PredecessorMap predecessor(num_input_points + 1); boost::prim_minimum_spanning_tree(riemannian_graph, &predecessor[0], weight_map( riemannian_graph_weight_map ) .root_vertex( vertex(source_point_index, riemannian_graph) )); @@ -472,8 +536,13 @@ create_mst_graph( typename MST_graph::vertex_descriptor v = add_vertex(mst_graph); CGAL_point_set_processing_assertion(v == get(index_map,it)); mst_graph[v].input_point = it; - mst_graph[v].is_oriented = (it == source_point); + mst_graph[v].is_oriented = false; } + + typename MST_graph::vertex_descriptor v = add_vertex(mst_graph); + CGAL_point_set_processing_assertion(v == source_point_index); + mst_graph[v].is_oriented = true; + // add edges for (std::size_t i=0; i < predecessor.size(); i++) // add edges { @@ -525,6 +594,11 @@ create_mst_graph( If this parameter is omitted, `CGAL::Identity_property_map` is used.\cgalParamEnd \cgalParamBegin{normal_map} a model of `ReadWritePropertyMap` with value type `geom_traits::Vector_3`.\cgalParamEnd + \cgalParamBegin{point_is_constrained_map} a model of `ReadablePropertyMap` with value type + `bool`. Points with a `true` value will be used as seed points: their normal will be considered as already + oriented, it won't be altered and it will be propagated to its neighbors. If this parameter is omitted, + the highest point (highest Z coordinate) will be used as the unique seed with an upward oriented + normal\cgalParamEnd \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `Kernel`\cgalParamEnd \cgalNamedParamsEnd @@ -545,6 +619,7 @@ mst_orient_normals( typedef typename Point_set_processing_3::GetPointMap::type PointMap; typedef typename Point_set_processing_3::GetNormalMap::type NormalMap; typedef typename Point_set_processing_3::GetK::Kernel Kernel; + typedef typename Point_set_processing_3::GetIsConstrainedMap::type ConstrainedMap; CGAL_static_assertion_msg(!(boost::is_same::NoMap>::value), @@ -552,6 +627,7 @@ mst_orient_normals( PointMap point_map = choose_param(get_param(np, internal_np::point_map), PointMap()); NormalMap normal_map = choose_param(get_param(np, internal_np::normal_map), NormalMap()); + ConstrainedMap constrained_map = choose_param(get_param(np, internal_np::point_is_constrained), ConstrainedMap()); Kernel kernel; // Bring private stuff to scope @@ -584,37 +660,46 @@ mst_orient_normals( // and get() requires a lookup in the map. IndexMap index_map(points.begin(), points.end()); - // Orients the normal of the point with maximum Z towards +Z axis. - typename PointRange::iterator source_point - = mst_find_source(points.begin(), points.end(), - point_map, normal_map, - kernel); - // Iterates over input points and creates Riemannian Graph: // - vertices are numbered like the input points index. // - vertices are empty. // - we add the edge (i, j) if either vertex i is in the k-neighborhood of vertex j, // or vertex j is in the k-neighborhood of vertex i. - Riemannian_graph riemannian_graph - = create_riemannian_graph(points.begin(), points.end(), - point_map, normal_map, index_map, - k, - kernel); + Riemannian_graph riemannian_graph; + + if (boost::is_same::NoMap>::value) + riemannian_graph = create_riemannian_graph(points.begin(), points.end(), + point_map, normal_map, index_map, + Default_constrained_map + (mst_find_source(points.begin(), points.end(), + point_map, normal_map, + kernel)), + k, + kernel); + else + riemannian_graph = create_riemannian_graph(points.begin(), points.end(), + point_map, normal_map, index_map, + constrained_map, + k, + kernel); // Creates a Minimum Spanning Tree starting at source_point MST_graph mst_graph = create_mst_graph(points.begin(), points.end(), point_map, normal_map, index_map, k, kernel, - riemannian_graph, - source_point); + riemannian_graph); memory = CGAL::Memory_sizer().virtual_size(); CGAL_TRACE(" %ld Mb allocated\n", memory>>20); CGAL_TRACE(" Calls boost::breadth_first_search()\n"); + const std::size_t num_input_points = distance(points.begin(), points.end()); + std::size_t source_point_index = num_input_points; + // Traverse the point set along the MST to propagate source_point's orientation - Propagate_normal_orientation orienter; - std::size_t source_point_index = get(index_map, source_point); + Propagate_normal_orientation orienter(source_point_index); + boost::breadth_first_search(mst_graph, vertex(source_point_index, mst_graph), // source visitor(boost::make_bfs_visitor(orienter))); diff --git a/Point_set_shape_detection_3/doc/Point_set_shape_detection_3/Concepts/ShapeDetectionTraits.h b/Point_set_shape_detection_3/doc/Point_set_shape_detection_3/Concepts/ShapeDetectionTraits.h index 44db0198c28..acbb8d24111 100644 --- a/Point_set_shape_detection_3/doc/Point_set_shape_detection_3/Concepts/ShapeDetectionTraits.h +++ b/Point_set_shape_detection_3/doc/Point_set_shape_detection_3/Concepts/ShapeDetectionTraits.h @@ -35,7 +35,7 @@ public: /// The circle type, only required if you want to detect tori typedef unspecified_type Circle_2; /// The 2D vector type, only required if you want to detect tori - typedef unspecified_type Vector_3; + typedef unspecified_type Vector_2; /// The number type of the Cartesian coordinates of types Point_3 typedef unspecified_type FT; diff --git a/Point_set_shape_detection_3/doc/Point_set_shape_detection_3/PackageDescription.txt b/Point_set_shape_detection_3/doc/Point_set_shape_detection_3/PackageDescription.txt index e9a6eda262e..71989dbe994 100644 --- a/Point_set_shape_detection_3/doc/Point_set_shape_detection_3/PackageDescription.txt +++ b/Point_set_shape_detection_3/doc/Point_set_shape_detection_3/PackageDescription.txt @@ -1,6 +1,6 @@ -/*! -\defgroup PkgPointSetShapeDetection3Ref Point Set Shape Detection Reference +/// \defgroup PkgPointSetShapeDetection3Ref Point Set Shape Detection Reference +/*! \defgroup PkgPointSetShapeDetection3Concepts Concepts \ingroup PkgPointSetShapeDetection3Ref 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 c3207e9acbb..0419603d52c 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/bbox.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/bbox.h @@ -76,13 +76,12 @@ namespace CGAL { GT gt = choose_param(get_param(np, internal_np::geom_traits), GT()); typename GT::Construct_bbox_3 get_bbox = gt.construct_bbox_3_object(); - typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - halfedge_descriptor h0 = *(halfedges(pmesh).first); - CGAL::Bbox_3 bb = get(vpm, target(h0, pmesh)).bbox(); - BOOST_FOREACH(halfedge_descriptor h, halfedges(pmesh)) + CGAL::Bbox_3 bb; + BOOST_FOREACH(vertex_descriptor v, vertices(pmesh)) { - bb += get_bbox( get(vpm, target(h, pmesh)) ); + bb += get_bbox( get(vpm, v) ); } return bb; } diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/clip.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/clip.h index 1c2ac748d32..078097a4ebf 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/clip.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/clip.h @@ -119,34 +119,47 @@ clip_to_bbox(const Plane_3& plane, int current_id = face_indices[4*i + k]; int next_id = face_indices[4*i + (k+1)%4]; - if ( orientations[ current_id ] != ON_POSITIVE_SIDE ) + switch(orientations[ current_id ]) { - all_out=false; - // point on or on the negative side - output_faces[i].push_back( current_id ); - in_point_ids.insert( output_faces[i].back() ); - // check for intersection of the edge - if (orientations[ current_id ] == ON_NEGATIVE_SIDE && - orientations[ next_id ] == ON_POSITIVE_SIDE) + case ON_NEGATIVE_SIDE: { - output_faces[i].push_back( - inter_pt_index(current_id, next_id, plane, corners, id_map) ); + all_out=false; + // point on or on the negative side + output_faces[i].push_back( current_id ); in_point_ids.insert( output_faces[i].back() ); + // check for intersection of the edge + if (orientations[ next_id ] == ON_POSITIVE_SIDE) + { + output_faces[i].push_back( + inter_pt_index(current_id, next_id, plane, corners, id_map) ); + in_point_ids.insert( output_faces[i].back() ); + } + break; } - } - else - { - all_in = false; - // check for intersection of the edge - if ( orientations[ next_id ] == ON_NEGATIVE_SIDE ) + case ON_POSITIVE_SIDE: { - output_faces[i].push_back( - inter_pt_index(current_id, next_id, plane, corners, id_map) ); + all_in = false; + // check for intersection of the edge + if ( orientations[ next_id ] == ON_NEGATIVE_SIDE ) + { + output_faces[i].push_back( + inter_pt_index(current_id, next_id, plane, corners, id_map) ); + in_point_ids.insert( output_faces[i].back() ); + } + break; + } + case ON_ORIENTED_BOUNDARY: + { + output_faces[i].push_back( current_id ); in_point_ids.insert( output_faces[i].back() ); } } } - CGAL_assertion( output_faces[i].empty() || output_faces[i].size() >= 3 ); + if (output_faces[i].size() < 3){ + CGAL_assertion(output_faces[i].empty() || + (output_faces[i].front()<8 && output_faces[i].back()<8) ); + output_faces[i].clear(); // edge of the bbox included in the plane + } } // the intersection is the full bbox 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 0dcfea83909..c7ba7288508 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/corefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/corefinement.h @@ -440,6 +440,58 @@ corefine_and_compute_boolean_operations( return CGAL::make_array(true, true, true, true); } + // handle case of empty meshes (isolated vertices are ignored) + if (faces(tm1).empty()) + { + if(faces(tm2).empty()) + { + for (int i=0; i<4; ++i) + if (output[i] != boost::none) + clear(*(*output[i])); + return CGAL::make_array(true, true, true, true); + } + // tm2 is not empty + if (output[Corefinement::UNION] != boost::none) + if (&tm2 != *output[Corefinement::UNION]) + copy_face_graph(tm2, + *(*output[Corefinement::UNION]), + parameters::vertex_point_map(vpm2), + parameters::vertex_point_map(*cpp11::get(vpm_out_tuple))); + if (output[Corefinement::INTERSECTION] != boost::none) + clear(*(*output[Corefinement::INTERSECTION])); + if (output[Corefinement::TM1_MINUS_TM2] != boost::none) + clear(*(*output[Corefinement::TM1_MINUS_TM2])); + if (output[Corefinement::TM2_MINUS_TM1] != boost::none) + if (&tm2 != *output[Corefinement::TM2_MINUS_TM1]) + copy_face_graph(tm2, + *(*output[Corefinement::TM2_MINUS_TM1]), + parameters::vertex_point_map(vpm2), + parameters::vertex_point_map(*cpp11::get(vpm_out_tuple))); + return CGAL::make_array(true, true, true, true); + } + else + if (faces(tm2).empty()) + { + // tm1 is not empty + if (output[Corefinement::UNION] != boost::none) + if (&tm1 != *output[Corefinement::UNION]) + copy_face_graph(tm1, + *(*output[Corefinement::UNION]), + parameters::vertex_point_map(vpm1), + parameters::vertex_point_map(*cpp11::get(vpm_out_tuple))); + if (output[Corefinement::INTERSECTION] != boost::none) + clear(*(*output[Corefinement::INTERSECTION])); + if (output[Corefinement::TM2_MINUS_TM1] != boost::none) + clear(*(*output[Corefinement::TM2_MINUS_TM1])); + if (output[Corefinement::TM1_MINUS_TM2] != boost::none) + if (&tm1 != *output[Corefinement::TM1_MINUS_TM2]) + copy_face_graph(tm1, + *(*output[Corefinement::TM1_MINUS_TM2]), + parameters::vertex_point_map(vpm1), + parameters::vertex_point_map(*cpp11::get(vpm_out_tuple))); + return CGAL::make_array(true, true, true, true); + } + // Edge is-constrained maps //for input meshes typedef typename boost::lookup_named_param_def < diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Face_graph_output_builder.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Face_graph_output_builder.h index 5913eb21694..c9eed95cef6 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Face_graph_output_builder.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Face_graph_output_builder.h @@ -103,8 +103,7 @@ class Face_graph_output_builder // Internal typedefs typedef std::size_t Node_id; typedef std::pair Node_id_pair; - typedef boost::unordered_map Intersection_edge_map; + typedef boost::unordered_set Intersection_edge_map; // to maintain a halfedge on each polyline per TriangleMesh + pair // with first = "is the key (pair) was reversed?" and // second is the number of edges -1 in the polyline @@ -127,6 +126,9 @@ class Face_graph_output_builder const VpmOutTuple& output_vpms; EdgeMarkMapTuple& out_edge_mark_maps; UserVisitor& user_visitor; + // mapping vertex to node id + Node_id_map vertex_to_node_id1, vertex_to_node_id2; + // output meshes const cpp11::array, 4>& requested_output; // input meshes closed ? @@ -310,9 +312,8 @@ class Face_graph_output_builder { std::vector edges; edges.reserve(edge_map.size()); - typedef std::pair Pair; - BOOST_FOREACH(const Pair& p, edge_map) - edges.push_back(p.first); + BOOST_FOREACH(edge_descriptor ed, edge_map) + edges.push_back(ed); CGAL_assertion(tuple_id < 4 && tuple_id >= 0); switch (tuple_id) @@ -427,8 +428,7 @@ public: //register an intersection halfedge // It is important here not to use operator[] since a two edges might be // equals while the indices are reversed - mesh_to_intersection_edges[&tm]. - insert(std::make_pair(edge(hedge, tm), indices)); + mesh_to_intersection_edges[&tm].insert(edge(hedge, tm)); if (indices.first>indices.second) { @@ -445,6 +445,17 @@ public: } } + void set_vertex_id(vertex_descriptor v, Node_id node_id, const TriangleMesh& tm) + { + if (&tm == &tm1) + vertex_to_node_id1.insert( std::make_pair(v, node_id) ); + else + { + CGAL_assertion(&tm == &tm2); + vertex_to_node_id2.insert( std::make_pair(v, node_id) ); + } + } + template void operator()( const Nodes_vector& nodes, @@ -452,30 +463,11 @@ public: const boost::dynamic_bitset<>& is_node_of_degree_one, const Mesh_to_map_node&) { - // first build an unordered_map mapping a vertex to its node id + CGAL_assertion( vertex_to_node_id1.size() == vertex_to_node_id2.size()); + CGAL_assertion( vertex_to_node_id1.size() == nodes.size()); + Intersection_edge_map& intersection_edges1 = mesh_to_intersection_edges[&tm1]; - Node_id_map vertex_to_node_id1; - - for (typename Intersection_edge_map::iterator - it=intersection_edges1.begin(), - it_end=intersection_edges1.end(); it!=it_end; ++it) - { - vertex_to_node_id1[source(it->first,tm1)]=it->second.first; - vertex_to_node_id1[target(it->first,tm1)]=it->second.second; - } - Intersection_edge_map& intersection_edges2 = mesh_to_intersection_edges[&tm2]; - Node_id_map vertex_to_node_id2; - - for (typename Intersection_edge_map::iterator - it=intersection_edges2.begin(), - it_end=intersection_edges2.end(); it!=it_end; ++it) - { - vertex_to_node_id2[source(it->first,tm2)]=it->second.first; - vertex_to_node_id2[target(it->first,tm2)]=it->second.second; - } - - CGAL_assertion(intersection_edges1.size()==intersection_edges2.size()); // this will initialize face indices if the face index map is writable. helpers::init_face_indices(tm1, fids1); @@ -504,11 +496,6 @@ public: halfedge_descriptor h2 = epp_it->second.first[&tm2]; halfedge_descriptor h2_opp = opposite(h2, tm2); - if (is_border_edge(h1,tm1) || is_border_edge(h2,tm2)){ - ++epp_it; - continue; - } - //vertices from tm1 vertex_descriptor p1 = target(next(h1_opp, tm1), tm1); vertex_descriptor p2 = target(next(h1, tm1), tm1); @@ -521,41 +508,53 @@ public: Node_id index_q2 = get_node_id(q2, vertex_to_node_id2); // set boolean for the position of p1 wrt to q1 and q2 - bool p1_eq_q1=false, p1_eq_q2=false; + bool p1_eq_q1=is_border(h1_opp, tm1), p1_eq_q2=p1_eq_q1; if (!is_border(h1_opp, tm1) && index_p1!=NID) { if (!is_border(h2_opp, tm2)) + { p1_eq_q1 = index_p1 == index_q1; + if (p1_eq_q1) + { + //mark coplanar facets if any + tm1_coplanar_faces.set(get(fids1, face(h1_opp, tm1))); + tm2_coplanar_faces.set(get(fids2, face(h2_opp, tm2))); + } + } if (!is_border(h2, tm2)) + { p1_eq_q2 = index_p1 == index_q2; + if (p1_eq_q2) + { + //mark coplanar facets if any + tm1_coplanar_faces.set(get(fids1, face(h1_opp, tm1))); + tm2_coplanar_faces.set(get(fids2, face(h2, tm2))); + } + } } // set boolean for the position of p2 wrt to q1 and q2 - bool p2_eq_q1=false, p2_eq_q2=false; + bool p2_eq_q1=is_border(h1, tm1), p2_eq_q2=p2_eq_q1; if (!is_border(h1, tm1) && index_p2!=NID) { if (!is_border(h2_opp, tm2)) + { p2_eq_q1 = index_p2 == index_q1; + if (p2_eq_q1){ + //mark coplanar facets if any + tm1_coplanar_faces.set(get(fids1, face(h1, tm1))); + tm2_coplanar_faces.set(get(fids2, face(h2_opp, tm2))); + } + } if (!is_border(h2, tm2)) + { p2_eq_q2 = index_p2 == index_q2; - } - - //mark coplanar facets if any - if (p1_eq_q1){ - tm1_coplanar_faces.set(get(fids1, face(h1_opp, tm1))); - tm2_coplanar_faces.set(get(fids2, face(h2_opp, tm2))); - } - if (p1_eq_q2){ - tm1_coplanar_faces.set(get(fids1, face(h1_opp, tm1))); - tm2_coplanar_faces.set(get(fids2, face(h2, tm2))); - } - if (p2_eq_q1){ - tm1_coplanar_faces.set(get(fids1, face(h1, tm1))); - tm2_coplanar_faces.set(get(fids2, face(h2_opp, tm2))); - } - if (p2_eq_q2){ - tm1_coplanar_faces.set(get(fids1, face(h1, tm1))); - tm2_coplanar_faces.set(get(fids2, face(h2, tm2))); + if (p2_eq_q2){ + //mark coplanar facets if any + tm1_coplanar_faces.set(get(fids1, face(h1, tm1))); + tm2_coplanar_faces.set(get(fids2, face(h2, tm2))); + } + } } if ( (p1_eq_q1 || p1_eq_q2) && (p2_eq_q1 || p2_eq_q2) ) @@ -565,6 +564,48 @@ public: an_edge_per_polyline.erase(it_to_rm); inter_edges_to_remove1.insert(edge(h1,tm1)); inter_edges_to_remove2.insert(edge(h2,tm2)); + + // on the border, we can have a degree 2 node so prev/next + // halfedge should be also considered for removal + // (as the coplanar edge will not be reported in an_edge_per_polyline + // and thus not removed from intersection_edges[12]) + if ( !is_border(h1, tm1) ) + { + h1 = opposite(h1, tm1); + h2 = opposite(h2, tm2); + } + if ( is_border(h1, tm1) ) + { + if ( opposite(next(h1, tm1), tm1) == prev(opposite(h1, tm1), tm1) ) + { + inter_edges_to_remove1.insert(edge(next(h1, tm1),tm1)); + inter_edges_to_remove1.insert(edge(next(h2, tm2),tm2)); + } + if ( opposite(prev(h1, tm1), tm1) == next(opposite(h1, tm1), tm1) ) + { + inter_edges_to_remove1.insert(edge(prev(h1, tm1), tm1)); + inter_edges_to_remove1.insert(edge(prev(h2, tm2), tm2)); + } + } + // same but for h2 + if ( !is_border(h2, tm2) ) + { + h1 = opposite(h1, tm1); + h2 = opposite(h2, tm2); + } + if ( is_border(h2, tm2) ) + { + if ( opposite(next(h2, tm2), tm2) == prev(opposite(h2, tm2), tm2) ) + { + inter_edges_to_remove1.insert(edge(next(h1, tm1),tm1)); + inter_edges_to_remove1.insert(edge(next(h2, tm2),tm2)); + } + if ( opposite(prev(h2, tm2), tm2) == next(opposite(h2, tm2), tm2) ) + { + inter_edges_to_remove1.insert(edge(prev(h1, tm1), tm1)); + inter_edges_to_remove1.insert(edge(prev(h2, tm2), tm2)); + } + } } else ++epp_it; @@ -601,7 +642,7 @@ public: .face_index_map(fids2)); std::vector tm2_patch_sizes(nb_patches_tm2, 0); - BOOST_FOREACH(std::size_t i, tm2_patch_ids) + BOOST_FOREACH(Node_id i, tm2_patch_ids) if(i!=NID) ++tm2_patch_sizes[i]; @@ -677,11 +718,55 @@ public: impossible_operation.set(); return; } + else + { + //Sort the three triangle faces around their common edge + // we assume that the exterior of the volume is indicated by + // counterclockwise oriented faces + // (corrected by is_tmi_inside_tmi). + halfedge_descriptor h = is_border(h1, tm1) ? opposite(h1, tm1) : h1; + vertex_descriptor p = target(next(h,tm1),tm1); + // when looking from the side of indices.second, + // the interior of the first triangle mesh is described + // by turning counterclockwise from p1 to p2 + vertex_descriptor q1=target(next(opposite(h2,tm2),tm2),tm2); + vertex_descriptor q2=target(next(h2,tm2),tm2); + // when looking from the side of indices.second, + // the interior of the second volume is described + // by turning from q1 to q2 + + //check if the third point of each triangular face is an original point (stay NID) + //or a intersection point (in that case we need the index of the corresponding node to + //have the exact value of the point) + Node_id index_p = get_node_id(p, vertex_to_node_id1); + Node_id index_q1 = get_node_id(q1, vertex_to_node_id2); + Node_id index_q2 = get_node_id(q2, vertex_to_node_id2); + + std::size_t patch_id_p=tm1_patch_ids[ get(fids1, face(h,tm1)) ]; + std::size_t patch_id_q1=tm2_patch_ids[ get(fids2, face(opposite(h2,tm2),tm2)) ]; + std::size_t patch_id_q2=tm2_patch_ids[ get(fids2, face(h2,tm2)) ]; + + //indicates that patch status will be updated + patch_status_not_set_tm1.reset(patch_id_p); + patch_status_not_set_tm2.reset(patch_id_q1); + patch_status_not_set_tm2.reset(patch_id_q2); + + bool p_is_between_q1q2 = sorted_around_edge( + ids.first, ids.second, + index_q1, index_q2, index_p, + q1, q2, p, + vpm2, vpm1, + nodes); + + if (p_is_between_q1q2) + is_patch_inside_tm2.set(patch_id_p); + } } } else if ( is_border_edge(h2,tm2) ) { + CGAL_assertion(!used_to_clip_a_surface); //Ambiguous, we do nothing impossible_operation.set(); return; @@ -989,37 +1074,51 @@ public: BOOST_FOREACH(face_descriptor f, faces(tm1)) { - std::size_t patch_id=tm1_patch_ids[ get(fids1, f) ]; + const std::size_t f_id = get(fids1, f); + const std::size_t patch_id = tm1_patch_ids[ f_id ]; if ( patch_status_not_set_tm1.test( patch_id ) ) { patch_status_not_set_tm1.reset( patch_id ); - vertex_descriptor v = target(halfedge(f, tm1), tm1); - Bounded_side position = inside_tm2( get(vpm1, v)); - if ( position == in_tm2 ) - is_patch_inside_tm2.set(patch_id); - else - if( position == ON_BOUNDARY) + halfedge_descriptor h = halfedge(f, tm1); + Node_id index_p1 = get_node_id(target(h, tm1), vertex_to_node_id1); + if (index_p1 != NID) + { + h=next(h, tm1); + index_p1 = get_node_id(target(h, tm1), vertex_to_node_id1); + if (index_p1 != NID) { - if (tm1_coplanar_faces.test(get(fids1, f))) - { - coplanar_patches_of_tm1.set(patch_id); - coplanar_patches_of_tm1_for_union_and_intersection.set(patch_id); - } - else - { - vertex_descriptor vn = source(halfedge(f, tm1), tm1); - Bounded_side other_position = inside_tm2( get(vpm1, vn) ); - if (other_position==ON_BOUNDARY) - { - // \todo improve this part which is not robust with a kernel - // with inexact constructions. - other_position = inside_tm2(midpoint(get(vpm1, vn), - get(vpm1, v) )); - } - if ( other_position == in_tm2 ) - is_patch_inside_tm2.set(patch_id); - } + h=next(h, tm1); + index_p1 = get_node_id(target(h, tm1), vertex_to_node_id1); } + } + if (index_p1 != NID) + { + if (tm1_coplanar_faces.test(f_id)) + { + coplanar_patches_of_tm1.set(patch_id); + coplanar_patches_of_tm1_for_union_and_intersection.set(patch_id); + } + else + { + // triangle which is tangent at its 3 vertices + // \todo improve this part which is not robust with a kernel + // with inexact constructions. + Bounded_side position = inside_tm2(midpoint(get(vpm1, source(h, tm1)), + get(vpm1, target(h, tm1)) )); + CGAL_assertion( position != ON_BOUNDARY); + if ( position == in_tm2 ) + is_patch_inside_tm2.set(patch_id); + } + } + else + { + // TODO: tm2 might have been modified and an inexact vpm will + // provide a non-robust result. + Bounded_side position = inside_tm2( get(vpm1, target(h, tm1))); + CGAL_assertion( position != ON_BOUNDARY); + if ( position == in_tm2 ) + is_patch_inside_tm2.set(patch_id); + } if ( patch_status_not_set_tm1.none() ) break; } } @@ -1035,37 +1134,51 @@ public: Inside_poly_test inside_tm1(tm1, vpm1); BOOST_FOREACH(face_descriptor f, faces(tm2)) { - std::size_t patch_id=tm2_patch_ids[ get(fids2, f) ]; + const std::size_t f_id = get(fids2, f); + std::size_t patch_id=tm2_patch_ids[ f_id ]; if ( patch_status_not_set_tm2.test( patch_id ) ) { patch_status_not_set_tm2.reset( patch_id ); - vertex_descriptor v = target(halfedge(f, tm2), tm2); - Bounded_side position = inside_tm1( get(vpm2, v)); - if ( position == in_tm1 ) - is_patch_inside_tm1.set(patch_id); - else - if( position == ON_BOUNDARY) + halfedge_descriptor h = halfedge(f, tm2); + Node_id index_p2 = get_node_id(target(h, tm2), vertex_to_node_id2); + if (index_p2 != NID) + { + h=next(h, tm2); + index_p2 = get_node_id(target(h, tm2), vertex_to_node_id2); + if (index_p2 != NID) { - if (tm2_coplanar_faces.test(get(fids2, f))) - { - coplanar_patches_of_tm2.set(patch_id); - coplanar_patches_of_tm2_for_union_and_intersection.set(patch_id); - } - else - { - vertex_descriptor vn = source(halfedge(f, tm2), tm2); - Bounded_side other_position = inside_tm1( get(vpm2, vn) ); - if (other_position==ON_BOUNDARY) - { - // \todo improve this part which is not robust with a kernel - // with inexact constructions. - other_position = inside_tm1(midpoint(get(vpm2, vn), - get(vpm2, v) )); - } - if ( other_position == in_tm1 ) - is_patch_inside_tm1.set(patch_id); - } + h=next(h, tm2); + index_p2 = get_node_id(target(h, tm2), vertex_to_node_id2); } + } + if (index_p2 != NID) + { + if (tm2_coplanar_faces.test(f_id)) + { + coplanar_patches_of_tm2.set(patch_id); + coplanar_patches_of_tm2_for_union_and_intersection.set(patch_id); + } + else + { + // triangle which is tangent at its 3 vertices + // \todo improve this part which is not robust with a kernel + // with inexact constructions. + Bounded_side position = inside_tm1(midpoint(get(vpm2, source(h, tm2)), + get(vpm2, target(h, tm2)) )); + CGAL_assertion( position != ON_BOUNDARY); + if ( position == in_tm1 ) + is_patch_inside_tm1.set(patch_id); + } + } + else + { + // TODO: tm1 might have been modified and an inexact vpm will + // provide a non-robust result. + Bounded_side position = inside_tm1( get(vpm2, target(h, tm2))); + CGAL_assertion( position != ON_BOUNDARY); + if ( position == in_tm1 ) + is_patch_inside_tm1.set(patch_id); + } if ( patch_status_not_set_tm2.none() ) break; } } @@ -1436,6 +1549,59 @@ public: patches_of_tm1_used[inplace_operation_tm1], patches_of_tm2_used[inplace_operation_tm1], fids1, fids2, tm1, tm2); + + if (used_to_clip_a_surface) + { + // The following code is here to handle the case when an intersection polyline + // contains some border edges of tm1 that should be considered as an independant polyline. + // This polyline removal should be handled by remove_unused_polylines. + // However, since all nodes are of degree 2 the polyline is not split at + // the correct point and trouble happen. Here the workaround consists in + // removing border edges of patches to be removed that are not in a + // polyline schedule for removal. + boost::dynamic_bitset<> patches_to_remove = ~patches_of_tm1_used[inplace_operation_tm1]; + for (std::size_t i = patches_to_remove.find_first(); + i < patches_to_remove.npos; + i = patches_to_remove.find_next(i)) + { + typedef typename std::vector::iterator Hedge_iterator; + std::vector< Hedge_iterator > to_rm; + for (Hedge_iterator it = patches_of_tm1[i].shared_edges.begin(); + it!= patches_of_tm1[i].shared_edges.end(); + ++it) + { + if ( is_border(opposite(*it, tm1), tm1) ) + to_rm.push_back(it); + } + if (!to_rm.empty()) + { + std::reverse(to_rm.begin(), to_rm.end()); + BOOST_FOREACH(Hedge_iterator it, to_rm) + { + patches_of_tm1[i].interior_edges.push_back(*it); + if (it!=cpp11::prev(patches_of_tm1[i].shared_edges.end())) + std::swap(patches_of_tm1[i].shared_edges.back(), *it); + patches_of_tm1[i].shared_edges.pop_back(); + } + //now update interior vertices + std::set border_vertices; + BOOST_FOREACH(halfedge_descriptor h, patches_of_tm1[i].shared_edges) + { + border_vertices.insert( target(h,tm1) ); + border_vertices.insert( source(h,tm1) ); + } + + BOOST_FOREACH(halfedge_descriptor h, patches_of_tm1[i].interior_edges) + { + if ( !border_vertices.count( target(h,tm1) ) ) + patches_of_tm1[i].interior_vertices.insert( target(h,tm1) ); + if ( !border_vertices.count( source(h,tm1) ) ) + patches_of_tm1[i].interior_vertices.insert( source(h,tm1) ); + } + } + } + } + #define CGAL_COREF_FUNCTION_CALL_DEF(BO_type) \ compute_inplace_operation( \ tm1, tm2, \ diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Output_builder_for_autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Output_builder_for_autorefinement.h index ba32b8948f2..0b04ec00e8b 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Output_builder_for_autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Output_builder_for_autorefinement.h @@ -110,6 +110,7 @@ class Output_builder_for_autorefinement const VertexPointMap &vpm; const FaceIdMap &fids; Ecm& ecm; + Node_id_map vertex_to_node_id; // input meshes closed ? bool is_tm_closed; // orientation of input surface mesh @@ -208,6 +209,13 @@ public: all_intersection_edges_map[indices].add(hedge); } + void set_vertex_id(vertex_descriptor v, Node_id node_id, const TriangleMesh& tm_) + { + CGAL_USE(tm_); + CGAL_assertion(&tm_==&tm); + vertex_to_node_id.insert( std::make_pair(v, node_id) ); + } + template void operator()( const Nodes_vector& nodes, @@ -220,7 +228,6 @@ public: // first build an unordered_map mapping a vertex to its node id + a set // of all intersection edges - Node_id_map vertex_to_node_id; typedef boost::unordered_set Intersection_edge_map; Intersection_edge_map intersection_edges; @@ -233,10 +240,10 @@ public: // and will be discarded later if (p.second.h2==boost::graph_traits::null_halfedge()) continue; - vertex_to_node_id[source(p.second.h1, tm)] = p.first.first; - vertex_to_node_id[target(p.second.h1, tm)] = p.first.second; - vertex_to_node_id[source(p.second.h2, tm)] = p.first.first; - vertex_to_node_id[target(p.second.h2, tm)] = p.first.second; + CGAL_assertion( vertex_to_node_id[source(p.second.h1, tm)] == p.first.first); + CGAL_assertion( vertex_to_node_id[target(p.second.h1, tm)] == p.first.second); + CGAL_assertion( vertex_to_node_id[source(p.second.h2, tm)] == p.first.first); + CGAL_assertion( vertex_to_node_id[target(p.second.h2, tm)] == p.first.second); intersection_edges.insert(edge(p.second.h1, tm)); intersection_edges.insert(edge(p.second.h2, tm)); } diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Visitor.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Visitor.h index 3ca6e2d833c..ade1e28dd0c 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Visitor.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Visitor.h @@ -96,6 +96,8 @@ struct No_extra_output_from_corefinement void set_edge_per_polyline(G& /*tm*/, Node_id_pair /*indices*/, halfedge_descriptor /*hedge*/){} + template + void set_vertex_id(vertex_descriptor, Node_id, const G&){} template void operator()( @@ -360,6 +362,7 @@ public: node_id_to_vertex[node_id]=target(h_2,tm2); all_incident_faces_got_a_node_as_vertex(h_2,node_id,*tm2_ptr); // check_node_on_non_manifold_vertex(node_id,h_2,tm2); + output_builder.set_vertex_id(target(h_2, tm2), node_id, tm2); } break; default: @@ -377,6 +380,8 @@ public: node_id_to_vertex.resize(node_id+1,Graph_traits::null_vertex()); node_id_to_vertex[node_id]=target(h_1,tm1); all_incident_faces_got_a_node_as_vertex(h_1,node_id, *tm1_ptr); + // register the vertex in the output builder + output_builder.set_vertex_id(target(h_1, tm1), node_id, tm1); // check_node_on_non_manifold_vertex(node_id,h_1,tm1); } else{ @@ -389,6 +394,8 @@ public: node_id_to_vertex.resize(node_id+1,Graph_traits::null_vertex()); node_id_to_vertex[node_id]=source(h_1,tm1); all_incident_faces_got_a_node_as_vertex(h_1_opp,node_id, *tm1_ptr); + // register the vertex in the output builder + output_builder.set_vertex_id(source(h_1, tm1), node_id, tm1); // check_node_on_non_manifold_vertex(node_id,h_1_opp,tm1); } else{ @@ -753,7 +760,8 @@ public: vertex_descriptor vnew=target(hnew,tm); // user_visitor.new_vertex_added(node_id, vnew, tm); // NODE_VISITOR_TAG nodes.call_put(vpm, vnew, node_id, tm); - + // register the new vertex in the output builder + output_builder.set_vertex_id(vnew, node_id, tm); node_id_to_vertex[node_id]=vnew; if (first){ first=false; @@ -997,7 +1005,7 @@ public: // import the triangle in `cdt` in the face `f` of `tm` triangulate_a_face(f, tm, nodes, node_ids, node_id_to_vertex, - edge_to_hedge, cdt, vpm, user_visitor); + edge_to_hedge, cdt, vpm, output_builder, user_visitor); // TODO Here we do the update only for internal edges. // Update for border halfedges could be done during the split diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h index be442040d31..22e785a8246 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h @@ -263,6 +263,7 @@ template < class TriangleMesh, class Node_id, class Node_vector, class CDT, + class OutputBuilder, class UserVisitor> void triangulate_a_face( @@ -277,6 +278,7 @@ triangulate_a_face( ::halfedge_descriptor>& edge_to_hedge, const CDT& cdt, const VertexPointMap& vpm, + OutputBuilder& output_builder, UserVisitor& user_visitor) { typedef boost::graph_traits GT; @@ -292,6 +294,9 @@ triangulate_a_face( vertex_descriptor v=add_vertex(tm); // user_visitor.new_vertex_added(node_id, v, tm); // NODE_VISITOR_TAG nodes.call_put(vpm, v, node_id, tm); + // register the new vertex in the output builder + output_builder.set_vertex_id(v, node_id, tm); + CGAL_assertion(node_id_to_vertex.size()>node_id); node_id_to_vertex[node_id]=v; } @@ -378,12 +383,10 @@ triangulate_a_face( template class Border_edge_map { - typedef std::size_t Node_id; typedef boost::graph_traits GT; typedef typename GT::halfedge_descriptor halfedge_descriptor; typedef typename GT::edge_descriptor edge_descriptor; - typedef boost::unordered_map > Intersection_edge_map; + typedef boost::unordered_set Intersection_edge_map; const Intersection_edge_map* intersection_edges; const PolygonMesh* tm; public: 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 7dd14e43a7d..33d3b231cf0 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 @@ -675,6 +675,7 @@ namespace internal { if (is_on_border(he) || is_on_mesh(he)) { he = opposite(he, mesh_); //he now is PATCH_BORDER + e = edge(he, mesh_); CGAL_assertion(is_on_patch_border(he)); } }//end if(not on PATCH) 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 64f83de0869..0005edca6ac 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair.h @@ -900,9 +900,53 @@ bool remove_degenerate_faces( TriangleMesh& tmesh, } #endif + // Then, remove triangles made of 3 collinear points std::set degenerate_face_set; degenerate_faces(tmesh, std::inserter(degenerate_face_set, degenerate_face_set.begin()), np); + +// start by filtering out border faces + std::set border_deg_faces; + BOOST_FOREACH(face_descriptor f, degenerate_face_set) + { + halfedge_descriptor h = halfedge(f, tmesh); + for (int i=0; i<3; ++i) + { + if ( is_border( opposite(h, tmesh), tmesh) ) + { + border_deg_faces.insert(f); + break; + } + h = next(h, tmesh); + } + } + + while( !border_deg_faces.empty() ) + { + face_descriptor f_to_rm = *border_deg_faces.begin(); + border_deg_faces.erase(border_deg_faces.begin()); + + halfedge_descriptor h = halfedge(f_to_rm, tmesh); + for (int i=0; i<3; ++i) + { + if (is_border(h, tmesh) ) + { + face_descriptor f = face(opposite(h, tmesh), tmesh); + if (is_degenerate_triangle_face(f, tmesh, np) ) + border_deg_faces.insert(f); + } + h = next(h, tmesh); + } + + while( !is_border(opposite(h, tmesh), tmesh) ) + { + h = next(h, tmesh); + } + + degenerate_face_set .erase(f_to_rm); + Euler::remove_face(h, tmesh); + } + // Ignore faces with null edges if (!all_removed) { diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/stitch_borders.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/stitch_borders.h index 7b79a6c68b5..2bfb06cdd15 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/stitch_borders.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/stitch_borders.h @@ -115,13 +115,15 @@ void fill_pairs(const Halfedge& he, ++set_it->second.first; // increase the multiplicity if(set_it->second.first == 2) { + set_it->second.second = halfedge_pairs.size(); // set the id of the pair in the vector + halfedge_pairs.push_back( std::make_pair(set_it->first, he) ); if ( get(vpmap, source(he,pmesh))==get(vpmap, target(set_it->first,pmesh)) && get(vpmap, target(he,pmesh))==get(vpmap, source(set_it->first,pmesh)) ) { - set_it->second.second = halfedge_pairs.size(); // set the id of the pair in the vector - halfedge_pairs.push_back( std::make_pair(set_it->first, he) ); manifold_halfedge_pairs.push_back(true); } + else + manifold_halfedge_pairs.push_back(false); } else if ( set_it->second.first > 2 ) diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/data-clip/clipper_1.off b/Polygon_mesh_processing/test/Polygon_mesh_processing/data-clip/clipper_1.off new file mode 100644 index 00000000000..9cb3aa719fb --- /dev/null +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/data-clip/clipper_1.off @@ -0,0 +1,16 @@ +OFF +6 8 0 +-0.98999999999999977 10 0.99999999999999978 +-0.98999999999999999 -2.4671622769447923e-19 2.4671622769447923e-19 +-0.98999999999999999 10 10 +-0.99999999999999978 10 0.99999999999999978 +-1 0 0 +-1 10 10 +3 2 0 1 +3 4 3 5 +3 5 3 0 +3 0 2 5 +3 3 4 1 +3 1 0 3 +3 4 5 2 +3 2 1 4 diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/data-clip/tm_1.off b/Polygon_mesh_processing/test/Polygon_mesh_processing/data-clip/tm_1.off new file mode 100644 index 00000000000..be60022538b --- /dev/null +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/data-clip/tm_1.off @@ -0,0 +1,19 @@ +OFF +9 8 0 +-0.99999999999999978 10 0.99999999999999978 +-10 0 1 +0 0 1 +-1 0 1 +-0.98999999999999999 1 1 +-0.98999999999999999 1.1102230246251566e-19 1 +-0.99899999999999989 1.1102230246251564e-20 1 +-0.99099999999999988 1 1 +-1 1 1 +3 0 8 7 +3 0 1 8 +3 8 1 3 +3 0 4 2 +3 5 6 2 +3 4 5 2 +3 6 3 2 +3 0 7 4 diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_clip.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_clip.cpp index 3dae87fb73c..d1c11f037dd 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_clip.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_clip.cpp @@ -216,6 +216,73 @@ void test() PMP::clip(tm1, K::Plane_3(-1, 0, 0, 2)); assert(vertices(tm1).size()==3); CGAL::clear(tm1); + + // test with clipper on border edge + make_triangle( K::Point_3(0, 0, 0), K::Point_3(0, 1, 0), K::Point_3(1, 0, 0), tm1 ); + PMP::clip(tm1, K::Plane_3(0, 1, 0 , 0)); + assert(vertices(tm1).size()==0); + CGAL::clear(tm1); + + make_triangle( K::Point_3(0, 0, 0), K::Point_3(0, 1, 0), K::Point_3(1, 0, 0), tm1 ); + PMP::clip(tm1, K::Plane_3(0, -1, 0 , 0)); + assert(vertices(tm1).size()==4); + CGAL::clear(tm1); + + // test with clipper on border edge: full triangle + make_triangle( K::Point_3(0, 0, 0), K::Point_3(0, 4, 0), K::Point_3(4, 0, 0), tm1 ); + PMP::clip(tm1, K::Plane_3(0, 0, 1, 0), params::use_compact_clipper(true)); + assert(vertices(tm1).size()!=0); + CGAL::clear(tm1); + + make_triangle( K::Point_3(0, 0, 0), K::Point_3(0, 4, 0), K::Point_3(4, 0, 0), tm1 ); + PMP::clip(tm1, K::Plane_3(0, 0, 1, 0), params::use_compact_clipper(false)); + assert(vertices(tm1).size()==0); + CGAL::clear(tm1); + + // test tangencies + make_triangle( K::Point_3(0, 0, 0), K::Point_3(0, 2, 0), K::Point_3(1, 1, 0), tm1 ); + PMP::clip(tm1, K::Plane_3(1, 0, 0, -1)); + assert(vertices(tm1).size()==3); + CGAL::clear(tm1); + + make_triangle( K::Point_3(0, 0, 0), K::Point_3(0, 2, 0), K::Point_3(1, 1, 0), tm1 ); + PMP::clip(tm1, K::Plane_3(-1, 0, 0, 1)); + assert(vertices(tm1).size()==0); + CGAL::clear(tm1); + + make_triangle( K::Point_3(0.5, 0, 0.5), K::Point_3(1, 0.5, 0.5), K::Point_3(0.5, 1, 0.5), tm1 ); + input.open("data-coref/cube.off"); + input >> tm2; + input.close(); + PMP::clip(tm1, tm2, params::face_index_map(get(CGAL::dynamic_face_property_t(), tm1)), + params::face_index_map(get(CGAL::dynamic_face_property_t(), tm2))); + assert(vertices(tm1).size()==3); + CGAL::clear(tm1); + CGAL::clear(tm2); + + make_triangle( K::Point_3(0.5, 0, 0.5), K::Point_3(1, 0.5, 0.5), K::Point_3(0.5, 1, 0.5), tm1 ); + input.open("data-coref/cube.off"); + input >> tm2; + input.close(); + PMP::reverse_face_orientations(tm2); + PMP::clip(tm1, tm2, params::face_index_map(get(CGAL::dynamic_face_property_t(), tm1)), + params::face_index_map(get(CGAL::dynamic_face_property_t(), tm2))); + assert(vertices(tm1).size()==0); + CGAL::clear(tm1); + CGAL::clear(tm2); + + // test special case + input.open("data-clip/tm_1.off"); + input >> tm1; + input.close(); + input.open("data-clip/clipper_1.off"); + input >> tm2; + input.close(); + PMP::clip(tm1, tm2, params::face_index_map(get(CGAL::dynamic_face_property_t(), tm1)), + params::face_index_map(get(CGAL::dynamic_face_property_t(), tm2))); + assert(is_valid_polygon_mesh(tm1)); + CGAL::clear(tm1); + CGAL::clear(tm2); } int main() diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_stitching.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_stitching.cpp index 975c1dbee5b..f2cdf958b64 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_stitching.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_stitching.cpp @@ -118,6 +118,20 @@ void test_surface_mesh_cc(const char* fname) std::cout << "OK\n"; } +void bug_test() +{ + typedef CGAL::Simple_cartesian K; + typedef K::Point_3 Point_3; + CGAL::Surface_mesh tm; + + CGAL::make_triangle(Point_3(0,0,0), Point_3(1,0,0), Point_3(0,1,0), tm); + CGAL::make_triangle(Point_3(0,0,0), Point_3(1,0,0), Point_3(0,1,0), tm); + CGAL::make_triangle(Point_3(0,0,0), Point_3(1,0,0), Point_3(0,1,0), tm); + CGAL::make_triangle(Point_3(0,0,0), Point_3(1,0,0), Point_3(0,1,0), tm); + + CGAL::Polygon_mesh_processing::stitch_borders(tm); +} + int main() { test_stitch_boundary_cycles("data_stitching/boundary_cycle.off"); @@ -150,5 +164,7 @@ int main() test_surface_mesh("data_stitching/non_manifold.off"); test_surface_mesh_cc("data_stitching/nm_cubes.off"); + bug_test(); + return EXIT_SUCCESS; } diff --git a/Polyhedron/demo/Polyhedron/CMakeLists.txt b/Polyhedron/demo/Polyhedron/CMakeLists.txt index b3f3f88a19b..857b3622def 100644 --- a/Polyhedron/demo/Polyhedron/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/CMakeLists.txt @@ -15,6 +15,11 @@ if(POLICY CMP0072) cmake_policy(SET CMP0072 NEW) endif() +if(POLICY CMP0074) + cmake_policy(SET CMP0074 NEW) +endif() + + # Find includes in corresponding build directories set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -133,7 +138,7 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND ) qt5_wrap_ui( statisticsUI_FILES Statistics_on_item_dialog.ui) qt5_wrap_ui( FileLoaderDialogUI_files FileLoaderDialog.ui ) qt5_wrap_ui( Show_point_dialogUI_FILES Show_point_dialog.ui ) - qt5_wrap_ui( PreferencesUI_FILES Preferences.ui ) + qt5_wrap_ui( PreferencesUI_FILES Preferences.ui Details.ui) qt5_wrap_ui( Show_point_dialogUI_FILES Show_point_dialog.ui ) qt5_wrap_ui( ViewerUI_FILES LightingDialog.ui) qt5_generate_moc( "File_loader_dialog.h" "${CMAKE_CURRENT_BINARY_DIR}/File_loader_dialog_moc.cpp" ) @@ -347,7 +352,13 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND ) add_subdirectory( implicit_functions ) - +# +# EXECUTABLES +# +add_executable ( CGAL_Mesh_3 Mesh_3.cpp ) +add_dependencies(CGAL_Mesh_3 Mesh_3) +target_link_libraries( CGAL_Mesh_3 PRIVATE polyhedron_demo ) +add_to_cached_list( CGAL_EXECUTABLE_TARGETS CGAL_Mesh_3 ) # # Exporting # diff --git a/Polyhedron/demo/Polyhedron/Details.ui b/Polyhedron/demo/Polyhedron/Details.ui new file mode 100644 index 00000000000..459cc4ce2c6 --- /dev/null +++ b/Polyhedron/demo/Polyhedron/Details.ui @@ -0,0 +1,86 @@ + + + DetailsDialog + + + + 0 + 0 + 790 + 326 + + + + Dialog + + + + + + true + + + + 1 + + + + + + + + + 16777215 + 70 + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Close + + + + + + + + + buttonBox + accepted() + DetailsDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + DetailsDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/Polyhedron/demo/Polyhedron/MainWindow.cpp b/Polyhedron/demo/Polyhedron/MainWindow.cpp index 1f012d30843..b45aca5ac1b 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.cpp +++ b/Polyhedron/demo/Polyhedron/MainWindow.cpp @@ -8,10 +8,10 @@ #include #include +#include #include #include #include -#include #include #include #include @@ -30,8 +30,6 @@ #include #include #include -#include -#include #include #include #include @@ -39,8 +37,10 @@ #include #include #include +#include #include #include + #ifdef QT_SCRIPT_LIB # include # ifdef QT_SCRIPTTOOLS_LIB @@ -54,6 +54,7 @@ #include #include "ui_MainWindow.h" #include "ui_Preferences.h" +#include "ui_Details.h" #include "ui_Statistics_on_item_dialog.h" #include "Show_point_dialog.h" #include "File_loader_dialog.h" @@ -131,9 +132,11 @@ MainWindow::~MainWindow() delete ui; delete statistics_ui; } -MainWindow::MainWindow(bool verbose, QWidget* parent) - : CGAL::Qt::DemosMainWindow(parent) +MainWindow::MainWindow(const QStringList &keywords, bool verbose, QWidget* parent) + : CGAL::Qt::DemosMainWindow(parent), + accepted_keywords(keywords) { + bbox_need_update = true; ui = new Ui::MainWindow; ui->setupUi(this); menuBar()->setNativeMenuBar(false); @@ -207,7 +210,7 @@ MainWindow::MainWindow(bool verbose, QWidget* parent) this, SLOT(removeManipulatedFrame(CGAL::Three::Scene_item*))); connect(scene, SIGNAL(updated_bbox(bool)), - this, SLOT(updateViewerBBox(bool))); + this, SLOT(invalidate_bbox(bool))); connect(scene, SIGNAL(selectionChanged(int)), this, SLOT(selectSceneItem(int))); @@ -568,9 +571,10 @@ bool MainWindow::load_plugin(QString fileName, bool blacklisted) if(blacklisted) { if ( plugin_blacklist.contains(name) ){ - pluginsStatus_map[name] = QString("ignored"); + pluginsStatus_map[name] = QString("Blacklisted."); + ignored_map[name] = true; //qDebug("### Ignoring plugin \"%s\".", qPrintable(fileName)); - PathNames_map[fileinfo.absoluteDir().absolutePath()].push_back(name); + PathNames_map[name].push_back(fileinfo.absoluteDir().absolutePath()); return true; } } @@ -579,8 +583,28 @@ bool MainWindow::load_plugin(QString fileName, bool blacklisted) qdebug << "### Loading \"" << fileName.toUtf8().data() << "\"... "; QPluginLoader loader; loader.setFileName(fileinfo.absoluteFilePath()); + QJsonArray keywords = loader.metaData().value("MetaData").toObject().value("Keywords").toArray(); + QString date = loader.metaData().value("MetaData").toObject().value("ConfigDate").toString(); + QStringList s_keywords; + for(int i = 0; i < keywords.size(); ++i) + { + s_keywords.append(keywords[i].toString()); + } + plugin_metadata_map[name] = qMakePair(s_keywords, date); QObject *obj = loader.instance(); - if(obj) { + bool do_load = accepted_keywords.empty(); + if(!do_load) + { + Q_FOREACH(QString k, s_keywords) + { + if(accepted_keywords.contains(k)) + { + do_load = true; + break; + } + } + } + if(do_load && obj) { obj->setObjectName(name); bool init1 = initPlugin(obj); bool init2 = initIOPlugin(obj); @@ -593,12 +617,17 @@ bool MainWindow::load_plugin(QString fileName, bool blacklisted) //qdebug << "success"; pluginsStatus_map[name] = QString("success"); } - else { + else if(!do_load) + { + pluginsStatus_map[name]="Wrong Keywords."; + ignored_map[name] = true; + } + else{ //qdebug << "error: " << qPrintable(loader.errorString()); pluginsStatus_map[name] = loader.errorString(); } - PathNames_map[fileinfo.absoluteDir().absolutePath()].push_back(name); + PathNames_map[name].push_back(fileinfo.absoluteDir().absolutePath()); return true; } return false; @@ -881,50 +910,54 @@ void MainWindow::error(QString text) { void MainWindow::updateViewerBBox(bool recenter = true) { - const Scene::Bbox bbox = scene->bbox(); + if(bbox_need_update) + { + const Scene::Bbox bbox = scene->bbox(); CGAL::qglviewer::Vec center = viewer->camera()->pivotPoint(); - const double xmin = bbox.xmin(); - const double ymin = bbox.ymin(); - const double zmin = bbox.zmin(); - const double xmax = bbox.xmax(); - const double ymax = bbox.ymax(); - const double zmax = bbox.zmax(); - - - CGAL::qglviewer::Vec - vec_min(xmin, ymin, zmin), - vec_max(xmax, ymax, zmax), - bbox_center((xmin+xmax)/2, (ymin+ymax)/2, (zmin+zmax)/2); - CGAL::qglviewer::Vec offset(0,0,0); - double l_dist = (std::max)((std::abs)(bbox_center.x - viewer->offset().x), - (std::max)((std::abs)(bbox_center.y - viewer->offset().y), - (std::abs)(bbox_center.z - viewer->offset().z))); - if((std::log2)(l_dist) > 13.0 ) - for(int i=0; i<3; ++i) + const double xmin = bbox.xmin(); + const double ymin = bbox.ymin(); + const double zmin = bbox.zmin(); + const double xmax = bbox.xmax(); + const double ymax = bbox.ymax(); + const double zmax = bbox.zmax(); + + + CGAL::qglviewer::Vec + vec_min(xmin, ymin, zmin), + vec_max(xmax, ymax, zmax), + bbox_center((xmin+xmax)/2, (ymin+ymax)/2, (zmin+zmax)/2); + CGAL::qglviewer::Vec offset(0,0,0); + double l_dist = (std::max)((std::abs)(bbox_center.x - viewer->offset().x), + (std::max)((std::abs)(bbox_center.y - viewer->offset().y), + (std::abs)(bbox_center.z - viewer->offset().z))); + if((std::log2)(l_dist) > 13.0 ) + for(int i=0; i<3; ++i) + { + offset[i] = -bbox_center[i]; + + } + if(offset != viewer->offset()) { - offset[i] = -bbox_center[i]; - + viewer->setOffset(offset); + for(int i=0; inumberOfEntries(); ++i) + { + scene->item(i)->invalidateOpenGLBuffers(); + scene->item(i)->itemChanged(); + } } - if(offset != viewer->offset()) - { - viewer->setOffset(offset); - for(int i=0; inumberOfEntries(); ++i) + + + viewer->setSceneBoundingBox(vec_min, + vec_max); + if(recenter) { - scene->item(i)->invalidateOpenGLBuffers(); - scene->item(i)->itemChanged(); + viewer->camera()->showEntireScene(); } - } - - - viewer->setSceneBoundingBox(vec_min, - vec_max); - if(recenter) - { - viewer->camera()->showEntireScene(); - } - else - { - viewer->camera()->setPivotPoint(center); + else + { + viewer->camera()->setPivotPoint(center); + } + bbox_need_update = false; } } @@ -1100,6 +1133,7 @@ void MainWindow::open(QString filename) qobject_cast(scene_item); if(group) scene->redraw_model(); + updateViewerBBox(true); } bool MainWindow::open(QString filename, QString loader_name) { @@ -1593,7 +1627,6 @@ void MainWindow::updateDisplayInfo() { void MainWindow::readSettings() { - QSettings settings; viewer->setAntiAliasing(settings.value("antialiasing", false).toBool()); viewer->setFastDrawing(settings.value("quick_camera_mode", true).toBool()); scene->enableVisibilityRecentering(settings.value("offset_update", true).toBool()); @@ -1616,7 +1649,6 @@ void MainWindow::writeSettings() { this->writeState("MainWindow"); { - QSettings settings; //setting plugin blacklist QStringList blacklist; Q_FOREACH(QString name,plugin_blacklist){ blacklist << name; } @@ -1944,13 +1976,16 @@ void MainWindow::on_actionDuplicate_triggered() void MainWindow::on_actionShowHide_triggered() { + scene->setUpdatesEnabled(false); Q_FOREACH(QModelIndex index, sceneView->selectionModel()->selectedRows()) { int i = scene->getIdFromModelIndex(proxyModel->mapToSource(index)); CGAL::Three::Scene_item* item = scene->item(i); item->setVisible(!item->visible()); - scene->itemChanged(i); + item->redraw(); } + scene->setUpdatesEnabled(true); + updateViewerBBox(false); } void MainWindow::on_actionSetPolyhedronA_triggered() @@ -1969,7 +2004,6 @@ void MainWindow::on_actionPreferences_triggered() { QDialog dialog(this); Ui::PreferencesDialog prefdiag; - QSettings settings; prefdiag.setupUi(&dialog); float lineWidth[2]; @@ -2048,43 +2082,68 @@ void MainWindow::on_actionPreferences_triggered() this, [this](const QString& text){ this->s_defaultPSRM = CGAL::Three::Three::modeFromName(text); }); + std::vector items; QBrush successBrush(Qt::green), errorBrush(Qt::red), ignoredBrush(Qt::lightGray); //add blacklisted plugins - Q_FOREACH (QString path, PathNames_map.keys()) + Q_FOREACH (QString name, PathNames_map.keys()) { - QTreeWidgetItem* pluginItem = new QTreeWidgetItem(prefdiag.treeWidget); - pluginItem->setText(1, path); - prefdiag.treeWidget->setItemExpanded(pluginItem, true); - QFont boldFont = pluginItem->font(1); - boldFont.setBold(true); - pluginItem->setFont(1, boldFont); - Q_FOREACH(QString name, PathNames_map[path]) - { - QTreeWidgetItem *item = new QTreeWidgetItem(pluginItem); - item->setText(1, name); - if(plugin_blacklist.contains(name)){ - item->setCheckState(0, Qt::Unchecked); - } - else{ - item->setCheckState(0, Qt::Checked); - } - if(pluginsStatus_map[name] == QString("success")) - item->setBackground(1, successBrush); - else if(pluginsStatus_map[name] == QString("ignored")){ - item->setBackground(1, ignoredBrush); - item->setToolTip(1, QString("This plugin is currently blacklisted, so it has been ignored.")); - } - else{ - item->setBackground(1, errorBrush); - item->setToolTip(1, pluginsStatus_map[name]); - } - items.push_back(item); + QTreeWidgetItem *item = new QTreeWidgetItem(prefdiag.treeWidget); + item->setText(1, name); + if(plugin_blacklist.contains(name)){ + item->setCheckState(0, Qt::Unchecked); } + else{ + item->setCheckState(0, Qt::Checked); + } + if(pluginsStatus_map[name] == QString("success")) + item->setBackground(1, successBrush); + else if(ignored_map[name]){ + item->setBackground(1, ignoredBrush); + } + else{ + item->setBackground(1, errorBrush); + } + items.push_back(item); } + connect(prefdiag.detailsPushButton, &QPushButton::clicked, + this, [this, prefdiag](){ + QStringList titles; + titles << "Name" << "Keywords" << "ConfigDate"; + QDialog dialog(this); + Ui::DetailsDialog detdiag; + detdiag.setupUi(&dialog); + QTreeWidgetItem *header = new QTreeWidgetItem(titles); + detdiag.treeWidget->setHeaderItem(header); + Q_FOREACH(QTreeWidgetItem* plugin_item, prefdiag.treeWidget->selectedItems()) + { + QString name = plugin_item->text(1); + QString keywords = plugin_metadata_map[name].first.join(", "); + QString date = plugin_metadata_map[name].second; + QStringList values; + values << name << keywords << date; + new QTreeWidgetItem(detdiag.treeWidget, values); + } + for(int i=0; i<3; ++i) + { + detdiag.treeWidget->resizeColumnToContents(i); + } + connect(detdiag.treeWidget, &QTreeWidget::clicked, + this, [this, detdiag](){ + if(detdiag.treeWidget->selectedItems().isEmpty()) + detdiag.textBrowser->setText(""); + else { + QString name = detdiag.treeWidget->selectedItems().first()->text(0); + QString status = pluginsStatus_map[name]; + QString path = PathNames_map[name]; + detdiag.textBrowser->setText(QString("Path: %1 \nStatus: %2").arg(path).arg(status)); + } + }); + dialog.exec(); + }); dialog.exec(); if ( dialog.result() ) @@ -2219,7 +2278,9 @@ void MainWindow::setAddKeyFrameKeyboardModifiers(::Qt::KeyboardModifiers m) void MainWindow::on_actionRecenterScene_triggered() { - updateViewerBBox(); + //force the recomputaion of the bbox + bbox_need_update = true; + updateViewerBBox(true); viewer->camera()->showEntireScene(); } @@ -2534,6 +2595,88 @@ void MainWindow::propagate_action() } } } + +void MainWindow::on_actionSa_ve_Scene_as_Script_triggered() +{ + QString filename = + QFileDialog::getSaveFileName(this, + "Save the Scene as a Script File", + last_saved_dir, + "Qt Script files (*.js)"); + std::ofstream os(filename.toUtf8()); + if(!os) + return; + std::vector names; + std::vector loaders; + std::vector colors; + std::vector rendering_modes; + QStringList not_saved; + for(int i = 0; i < scene->numberOfEntries(); ++i) + { + Scene_item* item = scene->item(i); + QString loader = item->property("loader_name").toString(); + QString source = item->property("source filename").toString(); + if(loader.isEmpty()) + { + not_saved.push_back(item->name()); + continue; + } + names.push_back(source); + loaders.push_back(loader); + colors.push_back(item->color()); + rendering_modes.push_back(item->renderingMode()); + } + //path + os << "var camera = \""<dumpCameraCoordinates().toStdString()<<"\";\n"; + os << "var items = ["; + for(std::size_t i = 0; i< names.size() -1; ++i) + { + os << "\'" << names[i].toStdString() << "\', "; + } + os<<"\'"<setTotalPass(val); @@ -2569,6 +2712,13 @@ void MainWindow::setDefaultSaveDir() QString dirpath = QFileDialog::getExistingDirectory(this, "Set Default Save as Directory", def_save_dir); if(!dirpath.isEmpty()) def_save_dir = dirpath; - QSettings settings; settings.setValue("default_saveas_dir", def_save_dir); } + +void MainWindow::invalidate_bbox(bool do_recenter) +{ + bbox_need_update = true; + if(do_recenter) + updateViewerBBox(true); + +} diff --git a/Polyhedron/demo/Polyhedron/MainWindow.h b/Polyhedron/demo/Polyhedron/MainWindow.h index 845a28c1ae8..7a23e664b61 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.h +++ b/Polyhedron/demo/Polyhedron/MainWindow.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -71,7 +72,7 @@ public: * Then it creates and initializes the scene and do the * connexions with the UI. Finally it loads the plugins.*/ - MainWindow(bool verbose = false,QWidget* parent = 0); + MainWindow(const QStringList& keywords, bool verbose = false,QWidget* parent = 0); ~MainWindow(); /*! Finds an IO plugin. @@ -400,7 +401,7 @@ private: void setMenus(QString, QString, QAction *a); /// plugin black-list QSet plugin_blacklist; - QMap > PathNames_map; //For each non-empty plugin directory, contains a vector of plugin names + QMap PathNames_map; //For each non-empty plugin directory, contains a vector of plugin names QMap pluginsStatus_map; //For each non-empty plugin directory, contains a vector of plugin names Scene* scene; Viewer* viewer; @@ -439,13 +440,19 @@ public: const QString & fileName = QString()); #endif public Q_SLOTS: + void on_actionSa_ve_Scene_as_Script_triggered(); void toggleFullScreen(); void setDefaultSaveDir(); + void invalidate_bbox(bool do_recenter); private: QList visibleDockWidgets; QLineEdit operationSearchBar; QWidgetAction* searchAction; QString def_save_dir; + bool bbox_need_update; + QMap >plugin_metadata_map; + QMap ignored_map; + const QStringList& accepted_keywords; }; #endif // ifndef MAINWINDOW_H diff --git a/Polyhedron/demo/Polyhedron/MainWindow.ui b/Polyhedron/demo/Polyhedron/MainWindow.ui index 38eaa51b87a..c5057750dcf 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.ui +++ b/Polyhedron/demo/Polyhedron/MainWindow.ui @@ -49,6 +49,7 @@ + @@ -492,6 +493,11 @@ Set Different Colors for Selected Items + + + Sa&ve the Scene as a Script File... + + diff --git a/Polyhedron/demo/Polyhedron/Mesh_3.cpp b/Polyhedron/demo/Polyhedron/Mesh_3.cpp new file mode 100644 index 00000000000..10070f21a59 --- /dev/null +++ b/Polyhedron/demo/Polyhedron/Mesh_3.cpp @@ -0,0 +1,29 @@ +#include "Polyhedron_demo.h" +#include +#include +#include + + +/*! + * \brief Defines the entry point of the demo. + * Creates the application and sets a main window. + */ +int main(int argc, char **argv) +{ + QSurfaceFormat fmt; + + fmt.setVersion(4, 3); + fmt.setRenderableType(QSurfaceFormat::OpenGL); + fmt.setProfile(QSurfaceFormat::CoreProfile); + fmt.setOption(QSurfaceFormat::DebugContext); + QSurfaceFormat::setDefaultFormat(fmt); + QStringList keywords; + keywords << "Mesh_3"; + Polyhedron_demo app(argc, argv, + "Mesh_3 demo", + "CGAL Mesh_3 Demo", + keywords); + //We set the locale to avoid any trouble with VTK + std::setlocale(LC_ALL, "C"); + return app.try_exec(); +} diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt b/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt index 45ecd036a1c..4a642daba09 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt @@ -1,32 +1,29 @@ include( polyhedron_demo_macros ) -polyhedron_demo_plugin(gocad_plugin GOCAD_io_plugin) +polyhedron_demo_plugin(gocad_plugin GOCAD_io_plugin KEYWORDS IO) target_link_libraries(gocad_plugin PUBLIC scene_surface_mesh_item) qt5_wrap_ui( funcUI_FILES Function_dialog.ui ) -polyhedron_demo_plugin(io_implicit_function_plugin Implicit_function_io_plugin ${funcUI_FILES}) +polyhedron_demo_plugin(io_implicit_function_plugin Implicit_function_io_plugin ${funcUI_FILES} KEYWORDS IO Mesh_3) target_link_libraries(io_implicit_function_plugin PUBLIC scene_implicit_function_item) -polyhedron_demo_plugin(nef_io_plugin Nef_io_plugin) +polyhedron_demo_plugin(nef_io_plugin Nef_io_plugin KEYWORDS IO) target_link_libraries(nef_io_plugin PUBLIC scene_nef_polyhedron_item) -polyhedron_demo_plugin(off_plugin OFF_io_plugin) +polyhedron_demo_plugin(off_plugin OFF_io_plugin KEYWORDS IO Mesh_3) target_link_libraries(off_plugin PUBLIC scene_polygon_soup_item scene_points_with_normal_item scene_surface_mesh_item) -polyhedron_demo_plugin(off_to_nef_plugin OFF_to_nef_io_plugin) +polyhedron_demo_plugin(off_to_nef_plugin OFF_to_nef_io_plugin KEYWORDS IO) target_link_libraries(off_to_nef_plugin PUBLIC scene_nef_polyhedron_item) -polyhedron_demo_plugin(polylines_io_plugin Polylines_io_plugin) +polyhedron_demo_plugin(polylines_io_plugin Polylines_io_plugin KEYWORDS IO Mesh_3) 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_selection_item selection_plugin) - -polyhedron_demo_plugin(stl_plugin STL_io_plugin) +polyhedron_demo_plugin(stl_plugin STL_io_plugin KEYWORDS IO) target_link_libraries(stl_plugin PUBLIC scene_surface_mesh_item scene_polygon_soup_item) -polyhedron_demo_plugin(surf_io_plugin Surf_io_plugin) +polyhedron_demo_plugin(surf_io_plugin Surf_io_plugin KEYWORDS IO) target_link_libraries(surf_io_plugin PUBLIC scene_surface_mesh_item) @@ -37,7 +34,7 @@ if (VTK_FOUND) include(${VTK_USE_FILE}) if ("${VTK_VERSION_MAJOR}" GREATER "5") if(VTK_LIBRARIES) - polyhedron_demo_plugin(vtk_plugin VTK_io_plugin) + polyhedron_demo_plugin(vtk_plugin VTK_io_plugin KEYWORDS IO Mesh_3) target_link_libraries(vtk_plugin PUBLIC scene_surface_mesh_item scene_polylines_item scene_c3t3_item vtkCommonCore vtkIOCore vtkIOLegacy vtkIOXML vtkFiltersCore vtkFiltersSources) @@ -51,7 +48,7 @@ if (VTK_FOUND) else() message(STATUS "NOTICE : the vtk IO plugin needs VTK 6.0 or greater and will not be compiled.") endif() -polyhedron_demo_plugin(xyz_plugin XYZ_io_plugin) +polyhedron_demo_plugin(xyz_plugin XYZ_io_plugin KEYWORDS IO) target_link_libraries(xyz_plugin PUBLIC scene_points_with_normal_item) list(FIND CMAKE_CXX_COMPILE_FEATURES cxx_rvalue_references has_cxx_rvalues) @@ -62,12 +59,12 @@ if(has_cxx_rvalues LESS 0 OR has_cxx_variadic LESS 0) else() set(needed_cxx_features cxx_rvalue_references cxx_variadic_templates) - polyhedron_demo_plugin(ply_plugin PLY_io_plugin) + polyhedron_demo_plugin(ply_plugin PLY_io_plugin KEYWORDS IO) target_link_libraries(ply_plugin PUBLIC scene_points_with_normal_item scene_polygon_soup_item scene_surface_mesh_item scene_polygon_soup_item) target_compile_features(ply_plugin PRIVATE ${needed_cxx_features}) if (LASLIB_FOUND) - polyhedron_demo_plugin(las_plugin LAS_io_plugin) + polyhedron_demo_plugin(las_plugin LAS_io_plugin KEYWORDS IO) target_link_libraries(las_plugin PUBLIC scene_points_with_normal_item ${LASLIB_LIBRARIES}) target_compile_features(las_plugin PRIVATE ${needed_cxx_features}) else() diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/GOCAD_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/GOCAD_io_plugin.cpp index 243f3f947a7..d5316ad04f6 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/GOCAD_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/GOCAD_io_plugin.cpp @@ -22,8 +22,8 @@ class Polyhedron_demo_gocad_plugin : { Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface CGAL::Three::Polyhedron_demo_io_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "gocad_io_plugin.json") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0" ) public: void init(QMainWindow* mainWindow, diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/Implicit_function_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/Implicit_function_io_plugin.cpp index d6502c608d4..928e974cf8b 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/Implicit_function_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/Implicit_function_io_plugin.cpp @@ -47,7 +47,7 @@ class Io_implicit_function_plugin : { Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "implicit_function_io_plugin.json") public: Io_implicit_function_plugin(); diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/LAS_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/LAS_io_plugin.cpp index bd7fef56910..37878451544 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/LAS_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/LAS_io_plugin.cpp @@ -9,7 +9,7 @@ class Polyhedron_demo_las_plugin : { Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0" FILE "las_io_plugin.json") public: QString name() const { return "las_plugin"; } diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/Nef_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/Nef_io_plugin.cpp index 9a18386d813..499b2f7db4b 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/Nef_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/Nef_io_plugin.cpp @@ -11,7 +11,7 @@ class Polyhedron_demo_io_nef_plugin : { Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "nef_io_plugin.json") public: QString nameFilters() const; diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/OFF_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/OFF_io_plugin.cpp index aa064d2952f..c2cbb3c5684 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/OFF_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/OFF_io_plugin.cpp @@ -21,7 +21,7 @@ class Polyhedron_demo_off_plugin : { Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0" FILE "off_io_plugin.json") public: bool isDefaultLoader(const Scene_item *item) const diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/OFF_to_nef_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/OFF_to_nef_io_plugin.cpp index 0ac3e1f8b0e..cd557823bd8 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/OFF_to_nef_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/OFF_to_nef_io_plugin.cpp @@ -10,7 +10,7 @@ class Polyhedron_demo_off_to_nef_plugin : { Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0" FILE "off_to_nef_io_plugin.json") public: QString name() const { return "off_to_nef_plugin"; } diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/PLY_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/PLY_io_plugin.cpp index ed37933d0e4..0a57fac8fee 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/PLY_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/PLY_io_plugin.cpp @@ -19,7 +19,7 @@ class Polyhedron_demo_ply_plugin : { Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0" FILE "ply_io_plugin.json") public: bool isDefaultLoader(const CGAL::Three::Scene_item *item) const diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/Polylines_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/Polylines_io_plugin.cpp index e4997939f80..0c4a3308503 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/Polylines_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/Polylines_io_plugin.cpp @@ -16,7 +16,7 @@ class Polyhedron_demo_polylines_io_plugin : { Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface CGAL::Three::Polyhedron_demo_io_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "polylines_io_plugin.json") Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0") diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/STL_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/STL_io_plugin.cpp index 0bcfbaba51a..4591567722f 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/STL_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/STL_io_plugin.cpp @@ -29,7 +29,7 @@ class Polyhedron_demo_stl_plugin : { Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface CGAL::Three::Polyhedron_demo_io_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "stl_io_plugin.json") Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0") public: diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/Selection_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/Selection_io_plugin.cpp deleted file mode 100644 index 67440917a89..00000000000 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/Selection_io_plugin.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#include "Scene_polyhedron_selection_item.h" -#include -#include -#include -using namespace CGAL::Three; -class Polyhedron_demo_selection_io_plugin : - public QObject, - public Polyhedron_demo_io_plugin_interface -{ - Q_OBJECT - Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") -public: - - QString name() const { return "selection_io_sm_plugin"; } - QString nameFilters() const { return "Selection files(*.selection.txt)"; } - - bool canLoad() const { - Scene_item * item = CGAL::Three::Three::scene()->item( - CGAL::Three::Three::scene()->mainSelectionIndex()); - Scene_facegraph_item* fg_item = qobject_cast(item); - if(fg_item) - return true; - Scene_polyhedron_selection_item* sel_item = - qobject_cast(item); - if (sel_item) - return true; - return false; - } - CGAL::Three::Scene_item* load(QFileInfo fileinfo) { - if(fileinfo.suffix().toLower() != "txt") return 0; - // There will be no actual loading at this step. - // Polyhedron_demo_selection_plugin will trigger load when item in new_item_created - Scene_polyhedron_selection_item* item = new Scene_polyhedron_selection_item(); - if(!item->load(fileinfo.filePath().toStdString())) { - delete item; - return NULL; - } - item->setName(fileinfo.baseName()); - return item; - } - - bool canSave(const CGAL::Three::Scene_item* scene_item) { - return qobject_cast(scene_item); - } - bool save(const CGAL::Three::Scene_item* scene_item, QFileInfo fileinfo) { - const Scene_polyhedron_selection_item* item = qobject_cast(scene_item); - if(item == NULL) { return false; } - - return item->save(fileinfo.filePath().toStdString()); - } -}; - -#include -#include "Selection_io_plugin.moc" diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/Surf_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/Surf_io_plugin.cpp index becb78272b1..87b7e5c5a4e 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/Surf_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/Surf_io_plugin.cpp @@ -24,7 +24,7 @@ class Surf_io_plugin: { Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface CGAL::Three::Polyhedron_demo_io_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "surf_io_plugin.json") Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0") public: diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/VTK_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/VTK_io_plugin.cpp index badf88cc4e3..2cc6a37fdb7 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/VTK_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/VTK_io_plugin.cpp @@ -271,7 +271,7 @@ class Polyhedron_demo_vtk_plugin : { Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0" FILE "vtk_io_plugin.json") public: typedef boost::graph_traits::vertex_descriptor vertex_descriptor; diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/XYZ_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/XYZ_io_plugin.cpp index 3228bf27d90..17873a0081f 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/XYZ_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/XYZ_io_plugin.cpp @@ -15,7 +15,7 @@ class Polyhedron_demo_xyz_plugin : { Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0" FILE "xyz_io_plugin.json") public: diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/C3t3_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/C3t3_io_plugin.cpp index f71a15aff64..b3009ddef89 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/C3t3_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/C3t3_io_plugin.cpp @@ -17,7 +17,7 @@ class Polyhedron_demo_c3t3_binary_io_plugin : Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface) Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "c3t3_io_plugin.json") public: void init(QMainWindow*, CGAL::Three::Scene_interface* sc, Messages_interface*) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/C3t3_rib_exporter_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/C3t3_rib_exporter_plugin.cpp index 35c1bfd2529..6bfb5b7e468 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/C3t3_rib_exporter_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/C3t3_rib_exporter_plugin.cpp @@ -36,7 +36,7 @@ class C3t3_rib_exporter_plugin : { Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "c3t3_rib_exporter_plugin.json") public: C3t3_rib_exporter_plugin(); diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/CMakeLists.txt b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/CMakeLists.txt index 7b420f5c6a3..641279dce31 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/CMakeLists.txt @@ -8,7 +8,7 @@ if ( Boost_VERSION GREATER 103400 ) qt5_wrap_ui( meshingUI_FILES Meshing_dialog.ui Smoother_dialog.ui Local_optimizers_dialog.ui ) polyhedron_demo_plugin(mesh_3_plugin Mesh_3_plugin Mesh_3_plugin_cgal_code.cpp Meshing_thread.cpp split_polylines.cpp - ${meshingUI_FILES}) + ${meshingUI_FILES} KEYWORDS Mesh_3) target_link_libraries(mesh_3_plugin PUBLIC scene_polygon_soup_item scene_polylines_item scene_implicit_function_item scene_image_item scene_surface_mesh_item scene_c3t3_item ${OPENGL_gl_LIBRARY} ) @@ -32,7 +32,7 @@ if ( Boost_VERSION GREATER 103400 ) endif() if(Boost_FILESYSTEM_FOUND) qt5_wrap_ui( imgUI_FILES Image_res_dialog.ui raw_image.ui) - polyhedron_demo_plugin(io_image_plugin Io_image_plugin Volume_plane_intersection.cpp Raw_image_dialog.cpp ${imgUI_FILES} ${VOLUME_MOC_OUTFILES}) + polyhedron_demo_plugin(io_image_plugin Io_image_plugin Volume_plane_intersection.cpp Raw_image_dialog.cpp ${imgUI_FILES} ${VOLUME_MOC_OUTFILES} KEYWORDS IO Mesh_3) target_link_libraries(io_image_plugin PUBLIC scene_image_item ${VTK_LIBS} ) target_link_libraries(io_image_plugin PUBLIC CGAL::CGAL_ImageIO) else() @@ -40,19 +40,19 @@ if ( Boost_VERSION GREATER 103400 ) endif() polyhedron_demo_plugin(mesh_3_optimization_plugin Optimization_plugin Optimization_plugin_cgal_code.cpp Optimizer_thread.cpp - ${meshingUI_FILES}) + ${meshingUI_FILES} KEYWORDS Mesh_3) target_link_libraries(mesh_3_optimization_plugin PUBLIC scene_c3t3_item scene_surface_mesh_item scene_image_item scene_implicit_function_item ) - polyhedron_demo_plugin(c3t3_io_plugin C3t3_io_plugin) + polyhedron_demo_plugin(c3t3_io_plugin C3t3_io_plugin KEYWORDS IO Mesh_3) target_link_libraries(c3t3_io_plugin PUBLIC scene_c3t3_item) else( Boost_VERSION GREATER 103400 ) message(STATUS "warning: the plugin mesh_3_plugin requires Boost>=1.34.1 and will not be compiled.") endif( Boost_VERSION GREATER 103400 ) qt5_wrap_ui( ribUI_FILES Rib_dialog.ui) -polyhedron_demo_plugin(c3t3_rib_exporter_plugin C3t3_rib_exporter_plugin ${ribUI_FILES}) +polyhedron_demo_plugin(c3t3_rib_exporter_plugin C3t3_rib_exporter_plugin ${ribUI_FILES} KEYWORDS Mesh_3) target_link_libraries(c3t3_rib_exporter_plugin PUBLIC scene_c3t3_item) if(TBB_FOUND) 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 1e363259796..dfac33c6d67 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Io_image_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Io_image_plugin.cpp @@ -1,5 +1,8 @@ #ifdef _MSC_VER # pragma warning(disable:4244) // conversion with loss of data +# pragma warning(disable:4996) // boost_1_65_1\boost/iostreams/positioning.hpp(96): + // warning C4996: 'std::fpos<_Mbstatet>::seekpos': warning STL4019: + // The member std::fpos::seekpos() is non-Standard #endif #include "Volume_plane.h" @@ -202,7 +205,7 @@ class Io_image_plugin : Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface) Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0" FILE "io_image_plugin.json") public: 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 f249bb1455b..c4320a49e8d 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp @@ -45,7 +45,7 @@ class Mesh_3_plugin : { Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "mesh_3_plugin.json") public: void init(QMainWindow* mainWindow, @@ -502,6 +502,7 @@ void Mesh_3_plugin::mesh_3(const bool surface_only, const bool use_defaults) edge_size, radius_edge, manifold, + surface_only, scene); } #endif @@ -527,6 +528,7 @@ void Mesh_3_plugin::mesh_3(const bool surface_only, const bool use_defaults) radius_edge, protect_features, manifold, + surface_only, scene, detect_connected_components, image_item->isGray(), 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 4d6cbfc8f52..211c98f1bd4 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 @@ -181,6 +181,7 @@ Meshing_thread* cgal_code_mesh_3(const Implicit_function_interface* pfunction, const double edge_size, const double tet_shape, const int manifold, + const bool surface_only, CGAL::Three::Scene_interface* scene) { if (pfunction == NULL) { return NULL; } @@ -198,7 +199,7 @@ Meshing_thread* cgal_code_mesh_3(const Implicit_function_interface* pfunction, [](int i, int j) { return (i * 1000 + j); } ); - Scene_c3t3_item* p_new_item = new Scene_c3t3_item; + Scene_c3t3_item* p_new_item = new Scene_c3t3_item(surface_only); p_new_item->setScene(scene); Mesh_parameters param; @@ -236,6 +237,7 @@ Meshing_thread* cgal_code_mesh_3(const Image* pImage, const double tet_shape, bool protect_features, const int manifold, + const bool surface_only, CGAL::Three::Scene_interface* scene, bool detect_connected_components, bool is_gray, @@ -259,7 +261,7 @@ Meshing_thread* cgal_code_mesh_3(const Image* pImage, param.tet_shape = tet_shape; param.manifold = manifold; param.image_3_ptr = pImage; - Scene_c3t3_item* p_new_item = new Scene_c3t3_item; + Scene_c3t3_item* p_new_item = new Scene_c3t3_item(surface_only); p_new_item->setScene(scene); if(!is_gray) { diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin_cgal_code.h b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin_cgal_code.h index ca90415d036..20b01d11e6d 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin_cgal_code.h +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin_cgal_code.h @@ -44,6 +44,7 @@ Meshing_thread* cgal_code_mesh_3(const Implicit_function_interface* pfunction, const double edge_size, const double tet_shape, const int manifold, + const bool surface_only, CGAL::Three::Scene_interface* scene); #endif @@ -58,6 +59,7 @@ Meshing_thread* cgal_code_mesh_3(const CGAL::Image_3* pImage, const double tet_shape, bool protect_features, const int manifold, + const bool surface_only, CGAL::Three::Scene_interface* scene, bool detect_connected_components, bool is_gray = false, diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Optimization_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Optimization_plugin.cpp index 43a63d2df36..344ab89ad0d 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Optimization_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Optimization_plugin.cpp @@ -79,7 +79,7 @@ class Mesh_3_optimization_plugin : { Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "optimization_plugin.json") typedef Polyhedron_demo_plugin_interface Base; public: diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Basic_generator_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PCA/Basic_generator_plugin.cpp index e5242bd41bf..5de2a0610ad 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/Basic_generator_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Basic_generator_plugin.cpp @@ -34,13 +34,15 @@ typedef Kernel::Point_3 Point; namespace euler = CGAL::Euler; using namespace CGAL::Three; +namespace params = CGAL::parameters; + class Q_DECL_EXPORT Basic_generator_plugin : public QObject, public Polyhedron_demo_plugin_helper { Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "basic_generator_plugin.json") public : void init(QMainWindow* mainWindow, CGAL::Three::Scene_interface* scene_interface, @@ -548,7 +550,7 @@ void Basic_generator_plugin::generateSphere() typedef typename boost::property_map::type VPMap; if(precision !=0) CGAL::Subdivision_method_3::Sqrt3_subdivision(sphere, - precision); + params::number_of_iterations(precision)); VPMap vpmap = get(CGAL::vertex_point, sphere); //emplace the points back on the sphere BOOST_FOREACH(typename boost::graph_traits::vertex_descriptor vd, vertices(sphere)) diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/CMakeLists.txt b/Polyhedron/demo/Polyhedron/Plugins/PCA/CMakeLists.txt index 0f2692d32b9..ee9332ff8bd 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/CMakeLists.txt @@ -18,5 +18,5 @@ polyhedron_demo_plugin(create_bbox_mesh_plugin Create_bbox_mesh_plugin) target_link_libraries(create_bbox_mesh_plugin PUBLIC scene_surface_mesh_item) qt5_wrap_ui( volumesUI_FILES Basic_generator_widget.ui) -polyhedron_demo_plugin(basic_generator_plugin Basic_generator_plugin ${volumesUI_FILES}) +polyhedron_demo_plugin(basic_generator_plugin Basic_generator_plugin ${volumesUI_FILES} KEYWORDS PolygonMesh) target_link_libraries(basic_generator_plugin PUBLIC scene_surface_mesh_item scene_points_with_normal_item scene_polylines_item) diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/CMakeLists.txt b/Polyhedron/demo/Polyhedron/Plugins/PMP/CMakeLists.txt index 9be832c313a..f7d3860eac6 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/CMakeLists.txt @@ -64,7 +64,7 @@ polyhedron_demo_plugin(polyhedron_stitching_plugin Polyhedron_stitching_plugin) target_link_libraries(polyhedron_stitching_plugin PUBLIC scene_surface_mesh_item scene_polylines_item) qt5_wrap_ui( selectionUI_FILES Selection_widget.ui) -add_library(selection_plugin SHARED Selection_plugin.cpp ${selectionUI_FILES}) +polyhedron_demo_plugin(selection_plugin Selection_plugin ${selectionUI_FILES} KEYWORDS PolygonMesh IO) target_link_libraries(selection_plugin PUBLIC scene_selection_item scene_points_with_normal_item scene_polylines_item) polyhedron_demo_plugin(self_intersection_plugin Self_intersection_plugin) @@ -109,6 +109,9 @@ target_link_libraries(random_perturbation_plugin PUBLIC scene_surface_mesh_item polyhedron_demo_plugin(degenerated_faces_plugin Degenerated_faces_plugin) target_link_libraries(degenerated_faces_plugin PUBLIC scene_surface_mesh_item scene_selection_item) +qt5_wrap_ui( engravUI_FILES Engrave_dock_widget.ui ) +polyhedron_demo_plugin(engrave_text_plugin Engrave_text_plugin ${engravUI_FILES}) +target_link_libraries(engrave_text_plugin PUBLIC scene_surface_mesh_item scene_selection_item scene_polylines_item) polyhedron_demo_plugin(extrude_plugin Extrude_plugin) target_link_libraries(extrude_plugin PUBLIC scene_surface_mesh_item scene_selection_item) diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Engrave_dock_widget.ui b/Polyhedron/demo/Polyhedron/Plugins/PMP/Engrave_dock_widget.ui new file mode 100644 index 00000000000..a893a256196 --- /dev/null +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Engrave_dock_widget.ui @@ -0,0 +1,316 @@ + + + EngraveWidget + + + + 0 + 0 + 293 + 515 + + + + Engraving + + + + + + + An Example Text + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Visualize + + + + + + + false + + + Engrave + + + + + + + false + + + Generate Text Mesh + + + + + + + Reset + + + + + + + + + + + + + + + + + :/cgal/icons/resources/up.png:/cgal/icons/resources/up.png + + + + + + + -179 + + + 179 + + + Qt::Horizontal + + + + + + + + + + + :/cgal/icons/resources/right_arrow.png:/cgal/icons/resources/right_arrow.png + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + :/cgal/icons/resources/down.png:/cgal/icons/resources/down.png + + + + + + + Scaling factor in X: + + + + + + + + + + + :/cgal/icons/resources/left_arrow.png:/cgal/icons/resources/left_arrow.png + + + + + + + Rotation degree: + + + + + + + 2000 + + + 1 + + + 1000 + + + 1000 + + + Qt::Horizontal + + + + + + + 2000 + + + 10 + + + 1000 + + + Qt::Horizontal + + + + + + + Scaling factor in Y: + + + + + + + 1 + + + 15 + + + Qt::Horizontal + + + + + + + Text Precision + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Engraving Depth + + + + + + 10000 + + + 1000 + + + Qt::Horizontal + + + + + + + 10000 + + + 1000 + + + Qt::Horizontal + + + + + + + Inside depth: + + + + + + + Outside depth: + + + + + + + Uniform letter mode + + + + + + + + + + + + + + + + + + + diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Engrave_text_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Engrave_text_plugin.cpp new file mode 100644 index 00000000000..6cad4ed03c9 --- /dev/null +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Engrave_text_plugin.cpp @@ -0,0 +1,931 @@ +//General Plugin Data +#include +#include + +#include "ui_Engrave_dock_widget.h" +//Items +#include "Scene_surface_mesh_item.h" +#include "Scene_polyhedron_selection_item.h" +#include "Scene_polylines_item.h" +#include "Messages_interface.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include + +using namespace CGAL::Three; +namespace SMP = CGAL::Surface_mesh_parameterization; +typedef EPICK::Point_2 Point_2; +typedef EPICK::Point_3 Point_3; + +typedef boost::graph_traits:: +edge_descriptor edge_descriptor; +typedef boost::graph_traits:: +halfedge_descriptor halfedge_descriptor; +typedef boost::graph_traits:: +vertex_descriptor vertex_descriptor; + +typedef boost::unordered_set:: +face_descriptor> Component; + +struct FaceInfo2 +{ + FaceInfo2(){} + int nesting_level; + bool in_domain(){ + return nesting_level%2 == 1; + } +}; + +template +struct Bot +{ + Bot(NMAP nmap, + double d, + PMAP pmap):d(d), + pmap(pmap), + nmap(nmap){} + template + void operator()(const T& v1,VD v2) const + { + put(pmap, v2, get(pmap, v2)-d*get(nmap, v1)); + } + double d; + PMAP pmap; + NMAP nmap; + +}; + +template +struct Top +{ + Top(NMAP nmap, + PMAP pmap, + double d):d(d), + nmap(nmap), + pmap(pmap){} + + template + void operator()(const T& v1, VD v2) const + { + put(pmap, v2, get(pmap, v2)+d*get(nmap, v1)); + } + double d; + NMAP nmap; + PMAP pmap; +}; + +typedef EPICK Gt; +typedef CGAL::Triangulation_vertex_base_2 Vb; +typedef CGAL::Triangulation_face_base_with_info_2 Fbb; +typedef CGAL::Constrained_triangulation_face_base_2 Fb; +typedef CGAL::Triangulation_data_structure_2 TDS; +typedef CGAL::No_intersection_tag Tag; +typedef CGAL::Constrained_Delaunay_triangulation_2 CDT; + +//Parameterization and text displaying +class ParamItem : public QGraphicsItem +{ +public : + ParamItem(Component* component, + const std::vector > &polylines, + EPICK::Aff_transformation_2 transfo, + SMesh* graph, + QRectF brect) + : + QGraphicsItem(), + bounding_rect(brect), + component(component), + polylines(polylines), + graph(graph), + transfo(transfo){} + + ~ParamItem() + { + delete component; + } + + QRectF boundingRect() const + { + return bounding_rect; + } + + void set_transfo(EPICK::Aff_transformation_2 t){ transfo = t;} + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) + { + QPen pen; + QBrush brush; + brush.setColor(QColor(100, 100, 255)); + brush.setStyle(Qt::SolidPattern); + pen.setColor(Qt::black); + pen.setWidth(0); + painter->setPen(pen); + painter->setBrush(brush); + SMesh::Property_map > uv; + uv = graph->add_property_map > + ("h:uv",std::make_pair(0.0f,0.0f)).first; + for( Component::iterator + fi = component->begin(); + fi != component->end(); + ++fi) + { + boost::graph_traits::face_descriptor f(*fi); + QPointF points[3]; + boost::graph_traits::halfedge_descriptor h = halfedge(f, *graph);; + points[0] = QPointF(get(uv, h).first, -get(uv, h).second); + h = next(halfedge(f, *graph), *graph); + points[1] = QPointF(get(uv, h).first, -get(uv, h).second); + h = next(next(halfedge(f, *graph), *graph), *graph); + points[2] = QPointF(get(uv, h).first, -get(uv, h).second); + painter->drawPolygon(points,3); + } + + pen.setColor(Qt::red); + pen.setWidth(0); + painter->setPen(pen); + for(std::size_t i =0; i points; + points.reserve(polylines[i].size()); + for(std::size_t j =0; jdrawPolyline(points.data(), static_cast(points.size())); + } + } + +private: + QString texMesh_name; + QRectF bounding_rect; + Component* component; + const std::vector >& polylines; + + SMesh* graph; + EPICK::Aff_transformation_2 transfo; +}; + +class Navigation : public CGAL::Qt::GraphicsViewNavigation +{ +public: + Navigation() + :CGAL::Qt::GraphicsViewNavigation(), + prev_pos(QPoint(0,0)) + { } + +protected: + bool eventFilter(QObject *obj, QEvent *ev) + { + QGraphicsView* v = qobject_cast(obj); + if(v == NULL) { + QWidget* viewport = qobject_cast(obj); + if(viewport == NULL) { + return false; + } + v = qobject_cast(viewport->parent()); + if(v == NULL) { + return false; + } + } + switch(ev->type()) + { + case QEvent::MouseMove: { + QMouseEvent* me = static_cast(ev); + if(is_dragging) + { + qreal dir[2] = {v->mapToScene(me->pos()).x() - prev_pos.x(), + v->mapToScene(me->pos()).y() - prev_pos.y()}; + + v->translate(dir[0],dir[1]); + v->update(); + } + prev_pos = v->mapToScene(me->pos()); + break; + } + + case QEvent::MouseButtonPress: { + is_dragging = true; + break; + } + case QEvent::MouseButtonRelease: { + is_dragging = false; + break; + } + case QEvent::Wheel: { + QWheelEvent* event = static_cast(ev); + QPointF old_pos = v->mapToScene(event->pos()); + if(event->delta() <0) + v->scale(1.2, 1.2); + else + v->scale(0.8, 0.8); + QPointF new_pos = v->mapToScene(event->pos()); + QPointF delta = new_pos - old_pos; + v->translate(delta.x(), delta.y()); + v->update(); + break; + } + + case QEvent::MouseButtonDblClick: { + v->fitInView(v->scene()->itemsBoundingRect(), Qt::KeepAspectRatio); + break; + } + default: + CGAL::Qt::GraphicsViewNavigation::eventFilter(obj, ev); + } + return false; + } +private: + bool is_dragging; + QPointF prev_pos; +}; + + +class EngraveWidget : + public QDockWidget, + public Ui::EngraveWidget +{ +public: + EngraveWidget(QString name, QWidget *parent) + :QDockWidget(name,parent) + { + setupUi(this); + } +}; + +class Q_DECL_EXPORT Engrave_text_plugin : + public QObject, + public Polyhedron_demo_plugin_helper +{ + Q_OBJECT + Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface) + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") + +private: + typedef CGAL::Surface_mesh_shortest_path_traits SP_traits; + typedef CGAL::Surface_mesh_shortest_path Surface_mesh_shortest_path; + typedef Surface_mesh_shortest_path::Face_location Face_location; + typedef CGAL::AABB_face_graph_triangle_primitive Primitive; + typedef CGAL::AABB_traits Tree_traits; + typedef CGAL::AABB_tree Tree; + typedef EPICK::Point_3 Point_3; + Messages_interface* messages; + +public : + + void init(QMainWindow*, + CGAL::Three::Scene_interface*, + Messages_interface* m) Q_DECL_OVERRIDE{ + //get refs + this->scene = Three::scene(); + this->mw = Three::mainWindow(); + messages = m; + + //action + QAction* actionFitText= new QAction("Fit Text", mw); + connect(actionFitText, SIGNAL(triggered()), + this, SLOT(showWidget())); + _actions << actionFitText; + //widget + dock_widget = new EngraveWidget("Engraving", mw); + dock_widget->setVisible(false); // do not show at the beginning + addDockWidget(dock_widget); + connect(dock_widget->visualizeButton, &QPushButton::clicked, + this, &Engrave_text_plugin::visualize); + connect(dock_widget->engraveButton, &QPushButton::clicked, + this, &Engrave_text_plugin::engrave); + connect(dock_widget->text_meshButton, &QPushButton::clicked, + this, &Engrave_text_plugin::generateTextItem); + connect(dock_widget->letter_checkBox, &QCheckBox::toggled, + this, &Engrave_text_plugin::generateTextItem); + + //items + visu_item = nullptr; + sel_item = nullptr; + textMesh = nullptr; + sm = nullptr; + + //transfo + angle = 0.0; + scalX=1.0; + scalY=1.0; + translation = EPICK::Vector_2(0,0); + pointsize = 15; + locked = false; + connect(dock_widget->text_prec_slider, &QSlider::valueChanged, + this, [this](){ + pointsize = dock_widget->text_prec_slider->value(); + scene->setSelectedItem(scene->item_id(sel_item)); + visualize(); + }); + connect(dock_widget->scalX_slider, &QSlider::valueChanged, + this, [this](){ + scalX = dock_widget->scalX_slider->value()/1000.0; + scene->setSelectedItem(scene->item_id(sel_item)); + visualize(); + }); + connect(dock_widget->scalY_slider, &QSlider::valueChanged, + this, [this](){ + scalY = dock_widget->scalY_slider->value()/1000.0; + scene->setSelectedItem(scene->item_id(sel_item)); + visualize(); + }); + + connect(dock_widget->bot_slider, &QSlider::valueChanged, + this, [this](){ + if(textMesh) + generateTextItem(); + }); + + connect(dock_widget->top_slider, &QSlider::valueChanged, + this, [this](){ + if(textMesh) + generateTextItem(); + }); + + connect(dock_widget->reset_button, &QPushButton::clicked, + this, [this](){ + cleanup(); + }); + + connect(dock_widget->t_up_pushButton, &QPushButton::clicked, + this, [this](){ + translation += EPICK::Vector_2(0,0.005); + scene->setSelectedItem(scene->item_id(sel_item)); + visualize(); + }); + + connect(dock_widget->t_down_pushButton, &QPushButton::clicked, + this, [this](){ + translation -= EPICK::Vector_2(0,0.005); + scene->setSelectedItem(scene->item_id(sel_item)); + visualize(); + }); + + connect(dock_widget->t_right_pushButton, &QPushButton::clicked, + this, [this](){ + translation += EPICK::Vector_2(0.005,0); + scene->setSelectedItem(scene->item_id(sel_item)); + visualize(); + }); + + connect(dock_widget->t_left_pushButton, &QPushButton::clicked, + this, [this](){ + translation -= EPICK::Vector_2(0.005,0); + scene->setSelectedItem(scene->item_id(sel_item)); + visualize(); + }); + connect(dock_widget->rot_slider, &QSlider::valueChanged, + this, [this](){ + if(!locked) + { + angle = dock_widget->rot_slider->value() * CGAL_PI/180.0; + scene->setSelectedItem(scene->item_id(sel_item)); + visualize(); + } + }); + graphics_scene = new QGraphicsScene(dock_widget); + dock_widget->graphicsView->setScene(graphics_scene); + dock_widget->graphicsView->setRenderHints(QPainter::Antialiasing); + navigation = new Navigation(); + dock_widget->graphicsView->installEventFilter(navigation); + dock_widget->graphicsView->viewport()->installEventFilter(navigation); + } + bool applicable(QAction*) const Q_DECL_OVERRIDE + { + return qobject_cast + (scene->item(scene->mainSelectionIndex())); + } + QList actions() const Q_DECL_OVERRIDE{ + return _actions; + } +public Q_SLOTS: + void showWidget() + { + dock_widget->setVisible(!dock_widget->isVisible()); + } + + void visualize() { + if(!sel_item) + sel_item = + qobject_cast + (scene->item(scene->mainSelectionIndex())); + if(!sel_item) + return; + if(sel_item->selected_facets.empty()) + { + cleanup(); + return; + } + if(!CGAL::is_closed(*sel_item->polyhedron())) + { + cleanup(); + return; + } + if(visu_item) + scene->erase(scene->item_id(visu_item)); + visu_item = nullptr; + + if(!sm) + { + sm = new SMesh(); + sel_item->export_selected_facets_as_polyhedron(sm); + SMesh::Halfedge_index hd = + CGAL::Polygon_mesh_processing::longest_border(*sm).first; + SMesh::Property_map uv_map = + sm->add_property_map("v:uv").first; + + // Parameterized bool pmap + boost::unordered_set vs; + SMP::internal::Bool_property_map< boost::unordered_set > vpm(vs); + + // Parameterizer + SMP::ARAP_parameterizer_3 parameterizer; + + SMP::Error_code status = parameterizer.parameterize(*sm, hd, uv_map, + get(boost::vertex_index, *sm), vpm); + if(status != SMP::OK) { + std::cout << "Encountered a problem: " << status << std::endl; + cleanup(); + return ; + } + + std::cout << "Parameterized with ARAP (SM) computed." << std::endl; + xmin = std::numeric_limits::max(); + xmax = std::numeric_limits::min(); + ymin = std::numeric_limits::max(); + ymax = std::numeric_limits::min(); + uv_map_3 = + sm->add_property_map("v:uv3").first; + for(SMesh::Vertex_index v : sm->vertices()) + { + uv_map_3[v] = Point_3(uv_map[v][0], uv_map[v] + [1], 0); + if(uv_map[v][0] > xmax) + xmax = uv_map[v][0]; + if(uv_map[v][0] < xmin) + xmin = uv_map[v][0]; + + if(uv_map[v][1] > ymax) + ymax = uv_map[v][1]; + if(uv_map[v][1] < ymin) + ymin = uv_map[v][1]; + } + + CGAL::linear_least_squares_fitting_2( + uv_map.begin(), + uv_map.end(), + bf_line, + CGAL::Dimension_tag<0>()); + + EPICK::Vector_2 A(bf_line.to_vector()), + B(EPICK::Point_2(0,0), + EPICK::Point_2(1,0)); + if (A.x()<0) A=-A; + angle = std::acos(A.x()/CGAL::sqrt(A.squared_length())); + if ( A.y()<0 ) angle+=3*CGAL_PI/2.; + if (angle>2*CGAL_PI) angle-=2*CGAL_PI; + + locked = true; + dock_widget->rot_slider->setSliderPosition(angle*180.0/CGAL_PI); + locked = false; + } + //create Text Polyline + QPainterPath path; + QFont font; + font.setPointSize(pointsize); + path.addText(QPoint(xmin,ymin), font, dock_widget->lineEdit->text()); + QList polys = path.toSubpathPolygons(); + polylines.clear(); + float pxmin(8000),pxmax(-8000), + pymin(8000), pymax(-8000); + + Q_FOREACH(QPolygonF poly, polys){ + Q_FOREACH(QPointF pf, poly) + { + EPICK::Point_2 v = EPICK::Point_2(pf.x(),-pf.y()); + if(v.x() < pxmin) + pxmin = v.x(); + if(v.x() > pxmax) + pxmax = v.x(); + if(v.y() < pymin) + pymin = v.y(); + if(v.y() > pymax) + pymax = v.y(); + } + } + Q_FOREACH(QPolygonF poly, polys){ + polylines.push_back(std::vector()); + Q_FOREACH(QPointF pf, poly) + { + EPICK::Point_2 v = EPICK::Point_2(pf.x(),-pf.y()); + polylines.back().push_back(EPICK::Point_2(v.x()*(xmax-xmin)/(pxmax-pxmin) +xmin , + v.y()*(ymax-ymin)/(pymax-pymin)+ymin + )); + } + } + + // build AABB-tree for face location queries + Tree aabb_tree(faces(*sm).first, faces(*sm).second, *sm, uv_map_3); + + visu_item = new Scene_polylines_item; + + + // compute 3D coordinates + transfo = + EPICK::Aff_transformation_2(CGAL::TRANSLATION, + EPICK::Vector_2((xmax-xmin)/2+xmin, + (ymax-ymin)/2+ymin)+ translation) + * EPICK::Aff_transformation_2(CGAL::ROTATION,sin(angle), cos(angle)) + * EPICK::Aff_transformation_2(scalX, 0.0,0.0,scalY) + * EPICK::Aff_transformation_2(CGAL::TRANSLATION, + EPICK::Vector_2(-(xmax-xmin)/2-xmin, + -(ymax-ymin)/2-ymin)); + BOOST_FOREACH(const std::vector& polyline, polylines) + { + visu_item->polylines.push_back(std::vector()); + BOOST_FOREACH(const EPICK::Point_2& p, polyline) + { + EPICK::Point_2 p_2 = transfo.transform(p); + + Face_location loc = Surface_mesh_shortest_path::locate( + Point_3(p_2.x(), p_2.y(), 0), + aabb_tree, *sm, uv_map_3); + visu_item->polylines.back().push_back( + Surface_mesh_shortest_path::point(loc.first, loc.second, *sm, sm->points())); + } + } + visu_item->setName("Text"); + visu_item->setColor(QColor(Qt::red)); + scene->addItem(visu_item); + dock_widget->engraveButton->setEnabled(true); + dock_widget->text_meshButton->setEnabled(true); + + if(graphics_scene->items().empty()) + { + Component* component = new Component(); + face_iterator bfit; + for(bfit = faces(*sm).begin(); + bfit != faces(*sm).end(); + ++bfit) + { + component->insert(*bfit); + } + SMesh::Property_map > uv; + uv = sm->add_property_map >( + "h:uv",std::make_pair(0.0f,0.0f)).first; + SMesh::Halfedge_iterator it; + SMesh::Property_map uv_map = + sm->property_map("v:uv").first; + for(it = sm->halfedges_begin(); + it != sm->halfedges_end(); + ++it) + { + halfedge_descriptor hd(*it); + EPICK::FT u = uv_map[target(hd, *sm)].x(); + EPICK::FT v = uv_map[target(hd, *sm)].y(); + put(uv, *it, std::make_pair(static_cast(u),static_cast(v))); + } + + //ParamItem does not take ownership of text_mesh_bottom + ParamItem *param_item= new ParamItem(component, polylines, transfo, sm, + QRectF(QPointF(xmin, -ymax), QPointF(xmax, -ymin))); + graphics_scene->addItem(param_item); + dock_widget->graphicsView->fitInView(param_item->boundingRect(), Qt::KeepAspectRatio); + } + else + { + ParamItem* param_item = static_cast(graphics_scene->items().first()); + param_item->set_transfo(transfo); + dock_widget->graphicsView->activateWindow(); + graphics_scene->update(); + } + // dock_widget->visualizeButton->setEnabled(false); + } + + void create_text_mesh(SMesh& text_mesh) + { + if(!visu_item) + return; + if(!sel_item) + return; + if(sel_item->selected_facets.empty()) + return; + if(!CGAL::is_closed(*sel_item->polyhedron())) + return; + CDT cdt; + //polylines is duplicated so the transformation is only performed once + std::vector > local_polylines + = polylines; + try{ + for(std::size_t i = 0; + i < local_polylines.size(); ++i) + { + std::vector& points = local_polylines[i]; + for(std::size_t j = 0; j< points.size(); ++j) + { + Point_2 &p = points[j]; + p = transfo.transform(p); + } + cdt.insert_constraint(points.begin(),points.end()); + } + }catch(std::runtime_error&) + { + QApplication::restoreOverrideCursor(); + throw; + } + if (cdt.dimension()!=2){ + QApplication::restoreOverrideCursor(); + std::cout << "Triangulation is not of dimension 2" << std::endl; + return; + } + CGAL::Bbox_2 bbox= CGAL::bbox_2(local_polylines.front().begin(), + local_polylines.front().end(), + EPICK()); + Q_FOREACH(const std::vector& points, + local_polylines) + { + bbox += CGAL::bbox_2(points.begin(), points.end(), EPICK()); + } + mark_nested_domains(cdt); + + SMesh text_mesh_bottom; + cdt2_to_face_graph(cdt, + text_mesh_bottom); + typedef boost::property_map::type VPMap; + typedef SMesh::Property_map NPMAP; + NPMAP vnormals = + text_mesh_bottom.add_property_map("v:normal").first; + + if(!dock_widget->letter_checkBox->isChecked()) + { + CGAL::Polygon_mesh_processing::compute_vertex_normals(text_mesh_bottom, vnormals); + } + else{ + // \todo Computing normals before the final + // mesh would be better. + + //foreach CC + SMesh::Property_map fcmap = + text_mesh_bottom.add_property_map("f:cc", 0).first; + std::size_t nb_cc = PMP::connected_components(text_mesh_bottom, + fcmap); + for(std::size_t cc = 0; cc fmesh(text_mesh_bottom, + static_cast(cc), + fcmap); + BOOST_FOREACH(vertex_descriptor vd, vertices(fmesh)) + { + normal += CGAL::Polygon_mesh_processing::compute_vertex_normal(vd, fmesh); + } + normal /= CGAL::sqrt(normal.squared_length()); + BOOST_FOREACH(vertex_descriptor vd, vertices(fmesh)) + { + put(vnormals, vd, normal); + } + } + } + Bot bot(vnormals, dock_widget->bot_slider->value()/100000.0, + get(CGAL::vertex_point, text_mesh)); + Top top(vnormals, get(CGAL::vertex_point, text_mesh), + dock_widget->top_slider->value()/100000.0); + PMP::extrude_mesh(text_mesh_bottom, text_mesh, bot, top); + } + + void engrave() { + QApplication::setOverrideCursor(Qt::WaitCursor); + SMesh text_mesh_complete; + create_text_mesh(text_mesh_complete); + + if (PMP::does_self_intersect(text_mesh_complete)) + { + QApplication::restoreOverrideCursor(); + messages->information("Error: text mesh self-intersects!"); + return; + } + + SMesh result; + CGAL::copy_face_graph(*sel_item->polyhedron(), result); + bool OK = PMP::corefine_and_compute_difference(result, text_mesh_complete, result); + + if (!OK) + { + QApplication::restoreOverrideCursor(); + messages->information("Error: the output mesh is not manifold!"); + return; + } + + CGAL::Polygon_mesh_processing::triangulate_faces(result); + Scene_surface_mesh_item* result_item = new Scene_surface_mesh_item( + result); + scene->addItem(result_item); + graphics_scene->clear(); + cleanup(); + if(textMesh) + { + textMesh->setVisible(false); + } + QApplication::restoreOverrideCursor(); + dock_widget->engraveButton->setEnabled(false); + dock_widget->text_meshButton->setEnabled(false); + dock_widget->visualizeButton->setEnabled(true); + } + + void generateTextItem() + { + QApplication::setOverrideCursor(Qt::WaitCursor); + + if(textMesh) + { + textMesh->face_graph()->clear(); + create_text_mesh(*textMesh->face_graph()); + textMesh->invalidateOpenGLBuffers(); + } + else + { + SMesh text_mesh; + create_text_mesh(text_mesh); + textMesh = new Scene_surface_mesh_item(text_mesh); + connect(textMesh, &Scene_surface_mesh_item::aboutToBeDestroyed, + this, [this](){ + textMesh = nullptr;}); + textMesh->setName("Extruded Text"); + scene->addItem(textMesh); + } + QApplication::restoreOverrideCursor(); + } + + void closure()Q_DECL_OVERRIDE + { + dock_widget->hide(); + } + +private: + template + void + mark_domains(CDT& ct, + typename CDT::Face_handle start, + int index, + std::list& border ) + { + if(start->info().nesting_level != -1){ + return; + } + std::list queue; + queue.push_back(start); + while(! queue.empty()){ + typename CDT::Face_handle fh = queue.front(); + queue.pop_front(); + if(fh->info().nesting_level == -1){ + fh->info().nesting_level = index; + for(int i = 0; i < 3; i++){ + typename CDT::Edge e(fh,i); + typename CDT::Face_handle n = fh->neighbor(i); + if(n->info().nesting_level == -1){ + if(ct.is_constrained(e)) border.push_back(e); + else queue.push_back(n); + } + } + } + } + } + + + template + void + mark_nested_domains(CDT& cdt) + { + for(typename CDT::All_faces_iterator it = cdt.all_faces_begin(); it != + cdt.all_faces_end(); ++it){ + it->info().nesting_level = -1; + } + std::list border; + mark_domains(cdt, cdt.infinite_face(), 0, border); + while(! border.empty()){ + typename CDT::Edge e = border.front(); + border.pop_front(); + typename CDT::Face_handle n = e.first->neighbor(e.second); + if(n->info().nesting_level == -1){ + mark_domains(cdt, n, e.first->info().nesting_level+1, border); + } + } + } + + template + void cdt2_to_face_graph(const CDT& cdt, + TriangleMesh& tm) + { + + Tree aabb_tree(faces(*sm).first, faces(*sm).second, *sm, uv_map_3); + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + + typedef std::map Map; + Map descriptors; + for (typename CDT::Finite_faces_iterator fit=cdt.finite_faces_begin(), + fit_end=cdt.finite_faces_end(); + fit!=fit_end; ++fit) + { + if (!fit->info().in_domain()) continue; + CGAL::cpp11::array vds; + for(int i=0; i<3; ++i) + { + typename Map::iterator it; + bool insert_ok; + boost::tie(it,insert_ok) = + descriptors.insert(std::make_pair(fit->vertex(i),vertex_descriptor())); + if (insert_ok){ + const EPICK::Point_2& pt=fit->vertex(i)->point(); + Face_location loc = Surface_mesh_shortest_path::locate( + Point_3(pt.x(), pt.y(), 0), + aabb_tree, *sm, uv_map_3); + it->second = add_vertex(Surface_mesh_shortest_path::point(loc.first, loc.second, + *sm, sm->points()), tm); + } + vds[i]=it->second; + } + + CGAL::Euler::add_face(vds, tm); + } + } + + void cleanup() + { + dock_widget->scalX_slider->setValue(1000); + dock_widget->scalY_slider->setValue(1000); + dock_widget->rot_slider->setValue(0); + translation = EPICK::Vector_2(0,0); + uv_map_3.reset(); + graphics_scene->clear(); + if(sel_item) + { + scene->erase(scene->item_id(sel_item)); + sel_item =nullptr; + } + if(sm) + { + delete sm; + sm = nullptr; + } + if(visu_item) + { + scene->erase(scene->item_id(visu_item)); + visu_item = nullptr; + } + } + + QList _actions; + EngraveWidget* dock_widget; + Scene_polylines_item* visu_item; + Scene_polyhedron_selection_item* sel_item; + Scene_surface_mesh_item* textMesh; + double angle; + double scalX; + double scalY; + EPICK::Vector_2 translation; + EPICK::Aff_transformation_2 transfo; + std::vector > polylines; + SMesh::Property_map uv_map_3; + SMesh* sm; + float xmin, xmax, ymin, ymax; + int pointsize; + bool locked; + EPICK::Line_2 bf_line; + QGraphicsScene *graphics_scene; + Navigation* navigation; +}; +#include "Engrave_text_plugin.moc" + diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Hole_filling_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Hole_filling_plugin.cpp index 5199a7fe048..88523da2286 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Hole_filling_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Hole_filling_plugin.cpp @@ -125,9 +125,9 @@ public: else { it->polyline->setWidth(3); } if(selected_holes.find(it) != selected_holes.end()) - { it->polyline->setRbgColor(255, 0, 0); } + { it->polyline->setRgbColor(255, 0, 0); } else - { it->polyline->setRbgColor(0, 0, 255); } + { it->polyline->setRgbColor(0, 0, 255); } it->polyline->drawEdges(viewer); } diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Join_and_split_polyhedra_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Join_and_split_polyhedra_plugin.cpp index a04801e613c..fc681f37cde 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Join_and_split_polyhedra_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Join_and_split_polyhedra_plugin.cpp @@ -228,7 +228,7 @@ void Polyhedron_demo_join_and_split_polyhedra_plugin::on_actionColorConnectedCom PatchIDMap pidmap = get(CGAL::face_patch_id_t(), *item->face_graph()); int nb_patch_ids = CGAL::Polygon_mesh_processing::connected_components(*item->face_graph(), pidmap); - + item->computeItemColorVectorAutomatically(true); item->invalidateOpenGLBuffers(); item->setProperty("NbPatchIds", nb_patch_ids); scene->itemChanged(item); diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Mean_curvature_flow_skeleton_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Mean_curvature_flow_skeleton_plugin.cpp index cd7f6c5fbab..940fe1144d9 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Mean_curvature_flow_skeleton_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Mean_curvature_flow_skeleton_plugin.cpp @@ -872,7 +872,7 @@ Polyhedron_demo_mean_curvature_flow_skeleton_plugin::createContractedItem(Scene_ { if(!item) return; - if(item->mcs == NULL) + if(item->mcs != NULL) delete item->mcs; double omega_H = ui->omega_H->value(); double omega_P = ui->omega_P->value(); diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Selection_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Selection_plugin.cpp index 338a0f979ce..baf70e4deed 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Selection_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Selection_plugin.cpp @@ -11,6 +11,8 @@ #include #include +#include +#include #include "ui_Selection_widget.h" #include @@ -66,12 +68,52 @@ struct Polyline_visitor using namespace CGAL::Three; class Polyhedron_demo_selection_plugin : public QObject, - public Polyhedron_demo_plugin_helper + public Polyhedron_demo_plugin_helper, + public Polyhedron_demo_io_plugin_interface { Q_OBJECT - Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") + Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface CGAL::Three::Polyhedron_demo_io_plugin_interface) + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "selection_plugin.json") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0") public: + QString nameFilters() const { return "Selection files(*.selection.txt)"; } + QString name() const { return "selection_sm_plugin"; } + + bool canLoad() const { + Scene_item * item = CGAL::Three::Three::scene()->item( + CGAL::Three::Three::scene()->mainSelectionIndex()); + Scene_facegraph_item* fg_item = qobject_cast(item); + if(fg_item) + return true; + Scene_polyhedron_selection_item* sel_item = + qobject_cast(item); + if (sel_item) + return true; + return false; + } + + CGAL::Three::Scene_item* load(QFileInfo fileinfo) { + if(fileinfo.suffix().toLower() != "txt") return 0; + // There will be no actual loading at this step. + Scene_polyhedron_selection_item* item = new Scene_polyhedron_selection_item(); + if(!item->load(fileinfo.filePath().toStdString())) { + delete item; + return NULL; + } + item->setName(fileinfo.baseName()); + return item; + } + + bool canSave(const CGAL::Three::Scene_item* scene_item) { + return qobject_cast(scene_item); + } + bool save(const CGAL::Three::Scene_item* scene_item, QFileInfo fileinfo) { + const Scene_polyhedron_selection_item* item = qobject_cast(scene_item); + if(item == NULL) { return false; } + + return item->save(fileinfo.filePath().toStdString()); + } + bool applicable(QAction*) const { return qobject_cast(scene->item(scene->mainSelectionIndex())) || qobject_cast(scene->item(scene->mainSelectionIndex())); diff --git a/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_normal_estimation_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_normal_estimation_plugin.cpp index ab53c6c887b..5193fec725f 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_normal_estimation_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_normal_estimation_plugin.cpp @@ -18,6 +18,8 @@ #include #include +#include + #include "run_with_qprogressdialog.h" #include "ui_Point_set_normal_estimation_plugin.h" @@ -77,6 +79,25 @@ struct Jet_estimate_normals_functor } }; +struct Vector_to_pmap +{ + typedef boost::readable_property_map_tag category; + typedef Point_set::Index key_type; + typedef bool value_type; + typedef value_type reference; + + std::vector* vec; + + Vector_to_pmap (std::vector* vec = NULL) : vec (vec) { } + + friend inline + reference get(const Vector_to_pmap& map, key_type p) + { + return (*map.vec)[p]; + } + +}; + using namespace CGAL::Three; class Polyhedron_demo_point_set_normal_estimation_plugin : @@ -88,6 +109,7 @@ class Polyhedron_demo_point_set_normal_estimation_plugin : Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") QAction* actionNormalEstimation; + QAction* actionNormalOrientation; QAction* actionNormalInversion; public: @@ -99,6 +121,10 @@ public: actionNormalEstimation->setObjectName("actionNormalEstimation"); actionNormalEstimation->setProperty("subMenuName","Point Set Processing"); + actionNormalOrientation = new QAction(tr("Normal Orientation"), mainWindow); + actionNormalOrientation->setObjectName("actionNormalOrientation"); + actionNormalOrientation->setProperty("subMenuName","Point Set Processing"); + actionNormalInversion = new QAction(tr("Inverse Normal Orientations"), mainWindow); actionNormalInversion->setObjectName("actionNormalInversion"); actionNormalInversion->setProperty("subMenuName","Point Set Processing"); @@ -106,7 +132,7 @@ public: } QList actions() const { - return QList() << actionNormalEstimation << actionNormalInversion; + return QList() << actionNormalEstimation << actionNormalOrientation << actionNormalInversion; } bool applicable(QAction* action) const { @@ -124,6 +150,7 @@ public: public Q_SLOTS: void on_actionNormalEstimation_triggered(); + void on_actionNormalOrientation_triggered(); void on_actionNormalInversion_triggered(); }; // end PS_demo_smoothing_plugin @@ -142,7 +169,6 @@ class Point_set_demo_normal_estimation_dialog : public QDialog, private Ui::Norm unsigned int convolution_neighbors() const { return m_convolution_neighbors->value(); } double convolution_radius() const { return m_convolution_radius->value(); } double offset_radius() const { return m_offset_radius->value(); } - int orient_neighbors() const { return m_orient_neighbors->value(); } unsigned int method () const { @@ -151,10 +177,6 @@ class Point_set_demo_normal_estimation_dialog : public QDialog, private Ui::Norm if (buttonVCM->isChecked ()) return 2; return -1; } - bool orient () const - { - return buttonOrient->isChecked(); - } bool use_convolution_radius () const { return buttonRadius->isChecked(); @@ -209,9 +231,6 @@ void Polyhedron_demo_point_set_normal_estimation_plugin::on_actionNormalEstimati QApplication::setOverrideCursor(Qt::BusyCursor); QApplication::processEvents(); - // First point to delete - Point_set::iterator first_unoriented_point = points->end(); - //*************************************** // normal estimation //*************************************** @@ -275,59 +294,112 @@ void Polyhedron_demo_point_set_normal_estimation_plugin::on_actionNormalEstimati << (memory>>20) << " Mb allocated" << std::endl; } + item->resetMenu(); item->setRenderingMode(ShadedPoints); + // Updates scene + item->invalidateOpenGLBuffers(); + scene->itemChanged(index); + + QApplication::restoreOverrideCursor(); + } +#endif // !CGAL_DISABLE_NORMAL_ESTIMATION_PLUGIN +} + +void Polyhedron_demo_point_set_normal_estimation_plugin::on_actionNormalOrientation_triggered() +{ + const CGAL::Three::Scene_interface::Item_id index = scene->mainSelectionIndex(); + + Scene_points_with_normal_item* item = + qobject_cast(scene->item(index)); + + if(item) + { + // Gets point set + Point_set* points = item->point_set(); + if(points == NULL) + return; + + // Gets options + QMultipleInputDialog dialog ("Normal Orientation", mw); + QSpinBox* neighborhood = dialog.add ("Neighborhood Size: "); + neighborhood->setRange (1, 10000000); + neighborhood->setValue (18); + + QRadioButton* use_seed_points = NULL; + QRadioButton* orient_selection = NULL; + + if (points->nb_selected_points() != 0) + { + use_seed_points = dialog.add ("Use selection as seed points and orient the unselected points"); + use_seed_points->setChecked(true); + orient_selection = dialog.add ("Orient selection"); + orient_selection->setChecked(false); + } + + if(!dialog.exec()) + return; + + QApplication::setOverrideCursor(Qt::BusyCursor); + QApplication::processEvents(); + + // First point to delete + Point_set::iterator first_unoriented_point = points->end(); + //*************************************** // normal orientation //*************************************** - if (dialog.orient ()) - { - CGAL::Timer task_timer; task_timer.start(); - std::cerr << "Orient normals with a Minimum Spanning Tree (k=" << dialog.orient_neighbors() << ")...\n"; + CGAL::Timer task_timer; task_timer.start(); + std::cerr << "Orient normals with a Minimum Spanning Tree (k=" << neighborhood->value() << ")...\n"; - // Tries to orient normals - first_unoriented_point = - CGAL::mst_orient_normals(points->all_or_selection_if_not_empty(), - dialog.orient_neighbors(), - points->parameters()); + // Tries to orient normals + if (points->nb_selected_points() != 0 && use_seed_points->isChecked()) + { + std::vector constrained_map (points->size(), false); - std::size_t nb_unoriented_normals = std::distance(first_unoriented_point, points->end()); - std::size_t memory = CGAL::Memory_sizer().virtual_size(); - std::cerr << "Orient normals: " << nb_unoriented_normals << " point(s) with an unoriented normal are selected (" - << task_timer.time() << " seconds, " - << (memory>>20) << " Mb allocated)" - << std::endl; - - // Selects points with an unoriented normal - points->set_first_selected (first_unoriented_point); - - // Updates scene - item->invalidateOpenGLBuffers(); - scene->itemChanged(index); - - QApplication::restoreOverrideCursor(); - - // Warns user - if (nb_unoriented_normals > 0) - { - QMessageBox::information(NULL, - tr("Points with an unoriented normal"), - tr("%1 point(s) with an unoriented normal are selected.\nPlease orient them or remove them before running Poisson reconstruction.") - .arg(nb_unoriented_normals)); - } - } + for (Point_set::iterator it = points->first_selected(); it != points->end(); ++ it) + constrained_map[*it] = true; + + first_unoriented_point = + CGAL::mst_orient_normals(*points, + std::size_t(neighborhood->value()), + points->parameters(). + point_is_constrained_map(Vector_to_pmap(&constrained_map))); + } else - { - // Updates scene - item->invalidateOpenGLBuffers(); - scene->itemChanged(index); + first_unoriented_point = + CGAL::mst_orient_normals(points->all_or_selection_if_not_empty(), + std::size_t(neighborhood->value()), + points->parameters()); - QApplication::restoreOverrideCursor(); - } + std::size_t nb_unoriented_normals = std::distance(first_unoriented_point, points->end()); + std::size_t memory = CGAL::Memory_sizer().virtual_size(); + std::cerr << "Orient normals: " << nb_unoriented_normals << " point(s) with an unoriented normal are selected (" + << task_timer.time() << " seconds, " + << (memory>>20) << " Mb allocated)" + << std::endl; + + // Selects points with an unoriented normal + points->set_first_selected (first_unoriented_point); + + // Updates scene + item->invalidateOpenGLBuffers(); + scene->itemChanged(index); + + QApplication::restoreOverrideCursor(); + + // Warns user + if (nb_unoriented_normals > 0) + { + QMessageBox::information(NULL, + tr("Points with an unoriented normal"), + tr("%1 point(s) with an unoriented normal are selected.\nPlease orient them or remove them before running Poisson reconstruction.") + .arg(nb_unoriented_normals)); + } } -#endif // !CGAL_DISABLE_NORMAL_ESTIMATION_PLUGIN } + #include "Point_set_normal_estimation_plugin.moc" diff --git a/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_normal_estimation_plugin.ui b/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_normal_estimation_plugin.ui index 905ba695a9d..8ceaeaea887 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_normal_estimation_plugin.ui +++ b/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_normal_estimation_plugin.ui @@ -6,8 +6,8 @@ 0 0 - 400 - 473 + 301 + 372 @@ -201,74 +201,6 @@ - - - - Qt::Horizontal - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - Orient Estimated Normals - - - true - - - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - QFormLayout::AllNonFixedFieldsGrow - - - - - Neighborhood Size - - - - - - - Nearest Neighbors - - - 6 - - - 100000000 - - - 18 - - - - - - @@ -279,19 +211,6 @@ - - - - Qt::Vertical - - - - 20 - 40 - - - - @@ -344,22 +263,6 @@ - - buttonOrient - toggled(bool) - frame_4 - setEnabled(bool) - - - 199 - 316 - - - 199 - 355 - - - buttonRadius toggled(bool) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_shape_detection_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_shape_detection_plugin.cpp index 1f138064785..c433fa2ebec 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_shape_detection_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_shape_detection_plugin.cpp @@ -346,7 +346,7 @@ private: g = static_cast(64 + rand.get_int(0, 192)); b = static_cast(64 + rand.get_int(0, 192)); - point_item->setRbgColor(r, g, b); + point_item->setRgbColor(r, g, b); std::size_t nb_colored_pts = 0; if (dialog.generate_colored_point_set()) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Point_set/Surface_reconstruction_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Point_set/Surface_reconstruction_plugin.cpp index 8836464f409..f5dcb92714a 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Point_set/Surface_reconstruction_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Point_set/Surface_reconstruction_plugin.cpp @@ -1160,6 +1160,7 @@ void Polyhedron_demo_surface_reconstruction_plugin::advancing_front_reconstructi reco_item->setColor(Qt::lightGray); reco_item->setRenderingMode(FlatPlusEdges); reco_item->invalidateOpenGLBuffers(); + scene->addItem(reco_item); QApplication::restoreOverrideCursor(); } } diff --git a/Polyhedron/demo/Polyhedron/Plugins/Subdivision_methods/Subdivision_methods_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Subdivision_methods/Subdivision_methods_plugin.cpp index c5c3067099e..2b54e27cf3e 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Subdivision_methods/Subdivision_methods_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Subdivision_methods/Subdivision_methods_plugin.cpp @@ -11,7 +11,10 @@ #include "Scene_surface_mesh_item.h" #include "SMesh_type.h" #include + using namespace CGAL::Three; +namespace params = CGAL::parameters; + class Polyhedron_demo_subdivision_methods_plugin : public QObject, public Polyhedron_demo_plugin_helper @@ -81,7 +84,7 @@ void Polyhedron_demo_subdivision_methods_plugin::apply_loop(FaceGraphItem* item, time.start(); messages->information("Loop subdivision..."); QApplication::setOverrideCursor(Qt::WaitCursor); - CGAL::Subdivision_method_3::Loop_subdivision(*graph, nb_steps); + CGAL::Subdivision_method_3::Loop_subdivision(*graph, params::number_of_iterations(nb_steps)); messages->information(QString("ok (%1 ms)").arg(time.elapsed())); QApplication::restoreOverrideCursor(); item->invalidateOpenGLBuffers(); @@ -113,7 +116,7 @@ void Polyhedron_demo_subdivision_methods_plugin::apply_catmullclark(FaceGraphIte time.start(); messages->information("Catmull-Clark subdivision..."); QApplication::setOverrideCursor(Qt::WaitCursor); - CGAL::Subdivision_method_3::CatmullClark_subdivision(*graph, nb_steps); + CGAL::Subdivision_method_3::CatmullClark_subdivision(*graph, params::number_of_iterations(nb_steps)); messages->information(QString("ok (%1 ms)").arg(time.elapsed())); QApplication::restoreOverrideCursor(); item->invalidateOpenGLBuffers(); @@ -143,7 +146,7 @@ void Polyhedron_demo_subdivision_methods_plugin::apply_sqrt3(FaceGraphItem* item time.start(); messages->information("Sqrt-3 subdivision..."); QApplication::setOverrideCursor(Qt::WaitCursor); - CGAL::Subdivision_method_3::Sqrt3_subdivision(*graph, nb_steps); + CGAL::Subdivision_method_3::Sqrt3_subdivision(*graph, params::number_of_iterations(nb_steps)); messages->information(QString("ok (%1 ms)").arg(time.elapsed())); QApplication::restoreOverrideCursor(); item->invalidateOpenGLBuffers(); @@ -175,7 +178,7 @@ void Polyhedron_demo_subdivision_methods_plugin::apply_doosabin(FaceGraphItem* i time.start(); messages->information("Doo-Sabin subdivision..."); QApplication::setOverrideCursor(Qt::WaitCursor); - CGAL::Subdivision_method_3::DooSabin_subdivision(*graph, nb_steps); + CGAL::Subdivision_method_3::DooSabin_subdivision(*graph, params::number_of_iterations(nb_steps)); messages->information(QString("ok (%1 ms)").arg(time.elapsed())); QApplication::restoreOverrideCursor(); item->invalidateOpenGLBuffers(); diff --git a/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh/CMakeLists.txt b/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh/CMakeLists.txt index fcda85250af..d81c3fbd17d 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh/CMakeLists.txt @@ -1,5 +1,9 @@ include( polyhedron_demo_macros ) +if(POLICY CMP0074) + cmake_policy(SET CMP0074 NEW) +endif() + if(EIGEN3_FOUND) find_package(CGAL COMPONENTS Core) diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo.cpp index f489df44bb9..c0e957bd645 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo.cpp @@ -19,7 +19,8 @@ struct Polyhedron_demo_impl { Polyhedron_demo::Polyhedron_demo(int& argc, char **argv, QString application_name, - QString main_window_title) + QString main_window_title, + QStringList input_keywords) : QApplication(argc, argv) , d_ptr_is_initialized(false) , d_ptr(new Polyhedron_demo_impl) @@ -43,6 +44,11 @@ Polyhedron_demo::Polyhedron_demo(int& argc, char **argv, QCommandLineParser parser; parser.addHelpOption(); + + QCommandLineOption use_keyword("keyword", + tr("Only loads the plugins associated with the following keyword. Can be called multiple times."), + "keyword"); + parser.addOption(use_keyword); QCommandLineOption use_meta("use-meta", tr("Use the [Meta] key to move frames, instead of [Tab].")); @@ -67,7 +73,10 @@ Polyhedron_demo::Polyhedron_demo(int& argc, char **argv, parser.addOption(old); parser.addPositionalArgument("files", tr("Files to open"), "[files...]"); parser.process(*this); - d_ptr->mainWindow.reset(new MainWindow(parser.isSet(verbose))); + QStringList keywords = input_keywords; + QStringList parser_keywords = parser.values(use_keyword); + keywords.append(parser_keywords); + d_ptr->mainWindow.reset(new MainWindow(keywords, parser.isSet(verbose))); MainWindow& mainWindow = *d_ptr->mainWindow; mainWindow.setWindowTitle(main_window_title); diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo.h b/Polyhedron/demo/Polyhedron/Polyhedron_demo.h index b6baa4a84bf..1cc498aa314 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo.h +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo.h @@ -7,6 +7,7 @@ #include #include +#include struct Polyhedron_demo_impl; @@ -20,7 +21,8 @@ public: */ Polyhedron_demo(int& argc, char **argv, QString application_name = "Polyhedron_3 demo", - QString main_window_title = "CGAL Polyhedron demo"); + QString main_window_title = "CGAL Polyhedron demo", + QStringList input_keywords = QStringList()); ~Polyhedron_demo(); diff --git a/Polyhedron/demo/Polyhedron/Preferences.ui b/Polyhedron/demo/Polyhedron/Preferences.ui index ee852a82298..596e8cf2513 100644 --- a/Polyhedron/demo/Polyhedron/Preferences.ui +++ b/Polyhedron/demo/Polyhedron/Preferences.ui @@ -7,7 +7,7 @@ 0 0 631 - 631 + 526 @@ -60,7 +60,7 @@ 0 0 278 - 537 + 432 @@ -318,10 +318,13 @@ - false + true - QAbstractItemView::NoSelection + QAbstractItemView::ExtendedSelection + + + QAbstractItemView::SelectRows true @@ -344,6 +347,30 @@ + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Details + + + + + diff --git a/Polyhedron/demo/Polyhedron/Scene.cpp b/Polyhedron/demo/Polyhedron/Scene.cpp index 19304b2f735..890940606fe 100644 --- a/Polyhedron/demo/Polyhedron/Scene.cpp +++ b/Polyhedron/demo/Polyhedron/Scene.cpp @@ -42,6 +42,7 @@ Scene::Scene(QObject* parent) this, SLOT(adjustIds(Scene_interface::Item_id))); picked = false; gl_init = false; + dont_emit_changes = false; } Scene::Item_id @@ -1294,14 +1295,23 @@ void Scene::itemChanged() void Scene::itemChanged(Item_id i) { - if(i < 0 || i >= m_entries.size()) - return; + if(dont_emit_changes) + return; + if(i < 0 || i >= m_entries.size()) + return; Q_EMIT dataChanged(this->createIndex(i, 0), this->createIndex(i, LastColumn)); } -void Scene::itemChanged(CGAL::Three::Scene_item*) +void Scene::itemChanged(CGAL::Three::Scene_item*item ) +{ + if(dont_emit_changes) + return; + itemChanged(item_id(item)); +} + +void Scene::allItemsChanged() { Q_EMIT dataChanged(this->createIndex(0, 0), this->createIndex(m_entries.size() - 1, LastColumn)); @@ -1320,8 +1330,10 @@ void Scene::itemVisibilityChanged(CGAL::Three::Scene_item* item) && !item->isEmpty()) { //does not recenter - if(visibility_recentering_enabled) - Q_EMIT updated_bbox(false); + if(visibility_recentering_enabled){ + Q_EMIT updated_bbox(true); + + } } } diff --git a/Polyhedron/demo/Polyhedron/Scene.h b/Polyhedron/demo/Polyhedron/Scene.h index 753bfc9e13f..d993765b96a 100644 --- a/Polyhedron/demo/Polyhedron/Scene.h +++ b/Polyhedron/demo/Polyhedron/Scene.h @@ -139,7 +139,13 @@ public: void zoomToPosition(QPoint point, CGAL::Three::Viewer_interface*) Q_DECL_OVERRIDE; - + void setUpdatesEnabled(bool b) Q_DECL_OVERRIDE + { + dont_emit_changes = b; + if(b) + allItemsChanged(); + } + public Q_SLOTS: //!Specifies a group as Expanded for the Geometric Objects view void setExpanded(QModelIndex); @@ -149,6 +155,7 @@ public Q_SLOTS: void itemChanged(); void itemChanged(int i) Q_DECL_OVERRIDE; void itemChanged(CGAL::Three::Scene_item*) Q_DECL_OVERRIDE; + void allItemsChanged() Q_DECL_OVERRIDE; //!Transmits a CGAL::Three::Scene_item::itemVisibilityChanged() signal to the scene. void itemVisibilityChanged(); void itemVisibilityChanged(CGAL::Three::Scene_item*) Q_DECL_OVERRIDE; @@ -286,6 +293,8 @@ private: QOpenGLShaderProgram program; QOpenGLVertexArrayObject* vao; mutable QOpenGLBuffer vbo[2]; + //the scene will ignore the itemChanged() signals while this is true. + bool dont_emit_changes; bool visibility_recentering_enabled; bool sort_lists(QVector >&sorted_lists, bool up); }; // end class Scene diff --git a/Polyhedron/demo/Polyhedron/implicit_functions/CMakeLists.txt b/Polyhedron/demo/Polyhedron/implicit_functions/CMakeLists.txt index 47dfb9ba3d3..6d3fcbd6a36 100644 --- a/Polyhedron/demo/Polyhedron/implicit_functions/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/implicit_functions/CMakeLists.txt @@ -10,6 +10,10 @@ if(NOT POLICY CMP0070 AND POLICY CMP0053) cmake_policy(SET CMP0053 OLD) endif() +if(POLICY CMP0074) + cmake_policy(SET CMP0074 NEW) +endif() + # Let plugins be compiled in the same directory as the executable. set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}") @@ -38,9 +42,9 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND) include(AddFileDependencies) remove_definitions(-DQT_STATICPLUGIN) - polyhedron_demo_plugin(p_sphere_function_plugin Sphere_implicit_function) - polyhedron_demo_plugin(p_tanglecube_function_plugin Tanglecube_implicit_function) - polyhedron_demo_plugin(p_klein_function_plugin Klein_implicit_function) + polyhedron_demo_plugin(p_sphere_function_plugin Sphere_implicit_function KEYWORDS Mesh_3) + polyhedron_demo_plugin(p_tanglecube_function_plugin Tanglecube_implicit_function KEYWORDS Mesh_3) + polyhedron_demo_plugin(p_klein_function_plugin Klein_implicit_function KEYWORDS Mesh_3) else (CGAL_Qt5_FOUND AND Qt5_FOUND) diff --git a/Polyhedron/demo/Polyhedron/implicit_functions/Klein_implicit_function.cpp b/Polyhedron/demo/Polyhedron/implicit_functions/Klein_implicit_function.cpp index 650b249bcb8..ec6b2c66a78 100644 --- a/Polyhedron/demo/Polyhedron/implicit_functions/Klein_implicit_function.cpp +++ b/Polyhedron/demo/Polyhedron/implicit_functions/Klein_implicit_function.cpp @@ -32,7 +32,7 @@ class Klein_implicit_function : { Q_OBJECT Q_INTERFACES(Implicit_function_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.Mesh3Demo.Implicit_function_interface/1.0") + Q_PLUGIN_METADATA(IID "com.geometryfactory.Mesh3Demo.Implicit_function_interface/1.0" FILE "klein_implicit_function.json") public: virtual QString name() const { return "Klein function"; } diff --git a/Polyhedron/demo/Polyhedron/implicit_functions/Sphere_implicit_function.cpp b/Polyhedron/demo/Polyhedron/implicit_functions/Sphere_implicit_function.cpp index 5d1f62cef17..d5b5de4980a 100644 --- a/Polyhedron/demo/Polyhedron/implicit_functions/Sphere_implicit_function.cpp +++ b/Polyhedron/demo/Polyhedron/implicit_functions/Sphere_implicit_function.cpp @@ -35,7 +35,7 @@ class Sphere_implicit_function : { Q_OBJECT Q_INTERFACES(Implicit_function_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.Mesh3Demo.Implicit_function_interface/1.0") + Q_PLUGIN_METADATA(IID "com.geometryfactory.Mesh3Demo.Implicit_function_interface/1.0" FILE "sphere_implicit_function.json") public: virtual QString name() const { return "Sphere function"; } diff --git a/Polyhedron/demo/Polyhedron/implicit_functions/Tanglecube_implicit_function.cpp b/Polyhedron/demo/Polyhedron/implicit_functions/Tanglecube_implicit_function.cpp index bf2223f43f1..4d7a04fee30 100644 --- a/Polyhedron/demo/Polyhedron/implicit_functions/Tanglecube_implicit_function.cpp +++ b/Polyhedron/demo/Polyhedron/implicit_functions/Tanglecube_implicit_function.cpp @@ -35,7 +35,7 @@ class Tanglecube_implicit_function : { Q_OBJECT Q_INTERFACES(Implicit_function_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.Mesh3Demo.Implicit_function_interface/1.0") + Q_PLUGIN_METADATA(IID "com.geometryfactory.Mesh3Demo.Implicit_function_interface/1.0" FILE "tanglecube_implicit_function.json") public: virtual QString name() const { return "Tanglecube function"; } diff --git a/Polyhedron/demo/Polyhedron/include/QMultipleInputDialog.h b/Polyhedron/demo/Polyhedron/include/QMultipleInputDialog.h index 17147651f29..4825f59a6c0 100644 --- a/Polyhedron/demo/Polyhedron/include/QMultipleInputDialog.h +++ b/Polyhedron/demo/Polyhedron/include/QMultipleInputDialog.h @@ -9,6 +9,7 @@ #include #include #include +#include class QMultipleInputDialog { @@ -29,8 +30,19 @@ public: template QObjectType* add (const char* name) { - QObjectType* out = new QObjectType (dialog); - form->addRow (QString(name), out); + QObjectType* out = NULL; + + if (boost::is_same::value) + { + out = dynamic_cast(new QRadioButton (QString(name), dialog)); + form->addRow (out); + } + else + { + out = new QObjectType (dialog); + form->addRow (QString(name), out); + } + return out; } diff --git a/Polyhedron/demo/Polyhedron/polyhedron_demo_macros.cmake b/Polyhedron/demo/Polyhedron/polyhedron_demo_macros.cmake index 852c81448cc..303b9922f0e 100644 --- a/Polyhedron/demo/Polyhedron/polyhedron_demo_macros.cmake +++ b/Polyhedron/demo/Polyhedron/polyhedron_demo_macros.cmake @@ -2,10 +2,11 @@ include(AddFileDependencies) include(${CGAL_MODULES_DIR}/CGAL_add_test.cmake) macro(polyhedron_demo_plugin plugin_name plugin_implementation_base_name) - list_split(option ARGN_TAIL ${ARGN} ) + cmake_parse_arguments(ARG "" "" "KEYWORDS" ${ARGN}) + list_split(option ARGN_TAIL ${ARG_UNPARSED_ARGUMENTS} ) if(NOT ${option} STREQUAL "EXCLUDE_FROM_ALL") if(NOT ${option} STREQUAL "NO_MOC") - set(other_sources ${ARGN}) + set(other_sources ${ARG_UNPARSED_ARGUMENTS}) set(option "") else() set(other_sources ${ARGN_TAIL}) @@ -42,4 +43,34 @@ include(${CGAL_MODULES_DIR}/CGAL_add_test.cmake) if(TARGET Polyhedron_3) add_dependencies( ${plugin_name} Polyhedron_3 ) endif() + #metadata management + #create "${plugin_implementation_base_name}.json" in BINARY_DIR + STRING(TOLOWER "${plugin_implementation_base_name}.json" base_name) + SET(filename "${CMAKE_CURRENT_BINARY_DIR}/${base_name}") + LIST(LENGTH ARG_KEYWORDS size) + if(${size} GREATER 0) + SET(keywords ) + FILE(WRITE ${filename} "{ \"Keywords\" : [") + foreach(keyword ${ARG_KEYWORDS}) + LIST(APPEND keywords "\"${keyword}\", ") + if(NOT TARGET ${keyword}) + add_custom_target(${keyword}) + endif() + add_dependencies( ${keyword} ${plugin_name}) + endforeach() + LIST(LENGTH keywords size) + math(EXPR size "${size} - 1") + LIST(GET keywords -1 last_element) + LIST(REMOVE_AT keywords ${size}) + STRING(LENGTH ${last_element} size) + math(EXPR size "${size} - 2") + STRING(SUBSTRING ${last_element} 0 ${size} last_element) + LIST(APPEND keywords ${last_element}) + foreach(keyword ${keywords}) + file(APPEND ${filename} ${keyword}) + endforeach() + file(APPEND ${filename} "], \n") + string(TIMESTAMP VERSION "%Y-%m-%d %H:%M") + file(APPEND ${filename} "\"ConfigDate\" : \"${VERSION}\" }") + endif() endmacro(polyhedron_demo_plugin) diff --git a/Polyhedron/examples/Polyhedron/CMakeLists.txt b/Polyhedron/examples/Polyhedron/CMakeLists.txt index c190c02a009..e5574f90c81 100644 --- a/Polyhedron/examples/Polyhedron/CMakeLists.txt +++ b/Polyhedron/examples/Polyhedron/CMakeLists.txt @@ -11,6 +11,10 @@ if(NOT POLICY CMP0070 AND POLICY CMP0053) cmake_policy(SET CMP0053 OLD) endif() +if(POLICY CMP0071) + cmake_policy(SET CMP0071 NEW) +endif() + find_package(CGAL COMPONENTS Qt5) if(CGAL_Qt5_FOUND) diff --git a/Polyhedron_IO/include/CGAL/IO/PLY_reader.h b/Polyhedron_IO/include/CGAL/IO/PLY_reader.h index 371114bd353..2f7522c36fd 100644 --- a/Polyhedron_IO/include/CGAL/IO/PLY_reader.h +++ b/Polyhedron_IO/include/CGAL/IO/PLY_reader.h @@ -29,36 +29,40 @@ namespace CGAL{ template bool read_PLY_faces (std::istream& in, - PLY::PLY_reader& reader, + internal::PLY::PLY_element& element, std::vector< Polygon_3 >& polygons, std::vector< Color_rgb >& fcolors, const char* vertex_indices_tag) { - std::size_t faces_read = 0; - bool has_colors = false; std::string rtag = "r", gtag = "g", btag = "b"; - if ((reader.does_tag_exist("red") || reader.does_tag_exist("r")) && - (reader.does_tag_exist("green") || reader.does_tag_exist("g")) && - (reader.does_tag_exist("blue") || reader.does_tag_exist("b"))) + if ((element.has_property("red") || element.has_property("r")) && + (element.has_property("green") || element.has_property("g")) && + (element.has_property("blue") || element.has_property("b"))) { has_colors = true; - if (reader.does_tag_exist("red")) + if (element.has_property("red")) { rtag = "red"; gtag = "green"; btag = "blue"; } } - while (!(in.eof()) && faces_read < reader.m_nb_faces) + for (std::size_t j = 0; j < element.number_of_items(); ++ j) { - for (std::size_t i = 0; i < reader.readers().size (); ++ i) - reader.readers()[i]->get (in); + for (std::size_t k = 0; k < element.number_of_properties(); ++ k) + { + internal::PLY::PLY_read_number* property = element.property(k); + property->get (in); + + if (in.fail()) + return false; + } cpp11::tuple, boost::uint8_t, boost::uint8_t, boost::uint8_t> new_face; if (has_colors) { - PLY::process_properties (reader, new_face, + PLY::process_properties (element, new_face, std::make_pair (CGAL::make_nth_of_tuple_property_map<0>(new_face), PLY_property >(vertex_indices_tag)), std::make_pair (CGAL::make_nth_of_tuple_property_map<1>(new_face), @@ -71,18 +75,16 @@ namespace CGAL{ fcolors.push_back (Color_rgb (get<1>(new_face), get<2>(new_face), get<3>(new_face))); } else - PLY::process_properties (reader, new_face, + PLY::process_properties (element, new_face, std::make_pair (CGAL::make_nth_of_tuple_property_map<0>(new_face), PLY_property >(vertex_indices_tag))); polygons.push_back (Polygon_3(get<0>(new_face).size())); for (std::size_t i = 0; i < get<0>(new_face).size(); ++ i) polygons.back()[i] = std::size_t(get<0>(new_face)[i]); - - ++ faces_read; } - return !in.bad(); + return true; } } @@ -104,47 +106,71 @@ namespace CGAL{ internal::PLY::PLY_reader reader; if (!(reader.init (in))) - return false; - - std::size_t points_read = 0; - - while (!(in.eof()) && points_read < reader.m_nb_points) { - for (std::size_t i = 0; i < reader.readers().size (); ++ i) - reader.readers()[i]->get (in); + in.setstate(std::ios::failbit); + return false; + } + + for (std::size_t i = 0; i < reader.number_of_elements(); ++ i) + { + internal::PLY::PLY_element& element = reader.element(i); - Point_3 new_vertex; + if (element.name() == "vertex" || element.name() == "vertices") + { + for (std::size_t j = 0; j < element.number_of_items(); ++ j) + { + for (std::size_t k = 0; k < element.number_of_properties(); ++ k) + { + internal::PLY::PLY_read_number* property = element.property(k); + property->get (in); - internal::PLY::process_properties (reader, new_vertex, - make_ply_point_reader (CGAL::Identity_property_map())); - + if (in.fail()) + return false; + } - points.push_back (new_vertex); + Point_3 new_vertex; + + internal::PLY::process_properties (element, new_vertex, + make_ply_point_reader (CGAL::Identity_property_map())); - ++ points_read; + points.push_back (get<0>(new_vertex)); + } + } + else if (element.name() == "face" || element.name() == "faces") + { + std::vector dummy; + + if (element.has_property > ("vertex_indices")) + internal::read_PLY_faces (in, element, polygons, dummy, "vertex_indices"); + else if (element.has_property > ("vertex_indices")) + internal::read_PLY_faces (in, element, polygons, dummy, "vertex_indices"); + else if (element.has_property > ("vertex_index")) + internal::read_PLY_faces (in, element, polygons, dummy, "vertex_index"); + else if (element.has_property > ("vertex_index")) + internal::read_PLY_faces (in, element, polygons, dummy, "vertex_index"); + else + { + std::cerr << "Error: can't find vertex indices in PLY input" << std::endl; + return false; + } + } + else // Read other elements and ignore + { + for (std::size_t j = 0; j < element.number_of_items(); ++ j) + { + for (std::size_t k = 0; k < element.number_of_properties(); ++ k) + { + internal::PLY::PLY_read_number* property = element.property(k); + property->get (in); + + if (in.fail()) + return false; + } + } + } } - if (points_read != reader.m_nb_points) - return false; - - std::vector dummy; - - reader.read_faces(); - - if (reader.does_tag_exist > ("vertex_indices")) - return internal::read_PLY_faces (in, reader, polygons, dummy, "vertex_indices"); - - if (reader.does_tag_exist > ("vertex_indices")) - return internal::read_PLY_faces (in, reader, polygons, dummy, "vertex_indices"); - - if (reader.does_tag_exist > ("vertex_index")) - return internal::read_PLY_faces (in, reader, polygons, dummy, "vertex_index"); - - if (reader.does_tag_exist > ("vertex_index")) - return internal::read_PLY_faces (in, reader, polygons, dummy, "vertex_index"); - - std::cerr << "Error: can't find vertex indices in PLY input" << std::endl; - return false; + return true; } template @@ -161,75 +187,99 @@ namespace CGAL{ std::cerr << "Error: cannot open file" << std::endl; return false; } - internal::PLY::PLY_reader reader; if (!(reader.init (in))) - return false; - - std::size_t points_read = 0; - - bool has_colors = false; - std::string rtag = "r", gtag = "g", btag = "b"; - if ((reader.does_tag_exist("red") || reader.does_tag_exist("r")) && - (reader.does_tag_exist("green") || reader.does_tag_exist("g")) && - (reader.does_tag_exist("blue") || reader.does_tag_exist("b"))) { - has_colors = true; - if (reader.does_tag_exist("red")) + in.setstate(std::ios::failbit); + return false; + } + + for (std::size_t i = 0; i < reader.number_of_elements(); ++ i) + { + internal::PLY::PLY_element& element = reader.element(i); + + if (element.name() == "vertex" || element.name() == "vertices") { - rtag = "red"; gtag = "green"; btag = "blue"; + bool has_colors = false; + std::string rtag = "r", gtag = "g", btag = "b"; + if ((element.has_property("red") || element.has_property("r")) && + (element.has_property("green") || element.has_property("g")) && + (element.has_property("blue") || element.has_property("b"))) + { + has_colors = true; + if (element.has_property("red")) + { + rtag = "red"; gtag = "green"; btag = "blue"; + } + } + + for (std::size_t j = 0; j < element.number_of_items(); ++ j) + { + for (std::size_t k = 0; k < element.number_of_properties(); ++ k) + { + internal::PLY::PLY_read_number* property = element.property(k); + property->get (in); + + if (in.fail()) + return false; + } + + cpp11::tuple new_vertex; + + if (has_colors) + { + internal::PLY::process_properties (element, new_vertex, + make_ply_point_reader (CGAL::make_nth_of_tuple_property_map<0>(new_vertex)), + std::make_pair (CGAL::make_nth_of_tuple_property_map<1>(new_vertex), + PLY_property(rtag.c_str())), + std::make_pair (CGAL::make_nth_of_tuple_property_map<2>(new_vertex), + PLY_property(gtag.c_str())), + std::make_pair (CGAL::make_nth_of_tuple_property_map<3>(new_vertex), + PLY_property(btag.c_str()))); + + vcolors.push_back (Color_rgb (get<1>(new_vertex), get<2>(new_vertex), get<3>(new_vertex))); + } + else + internal::PLY::process_properties (element, new_vertex, + make_ply_point_reader (CGAL::make_nth_of_tuple_property_map<0>(new_vertex))); + + points.push_back (get<0>(new_vertex)); + } + } + else if (element.name() == "face" || element.name() == "faces") + { + if (element.has_property > ("vertex_indices")) + internal::read_PLY_faces (in, element, polygons, fcolors, "vertex_indices"); + else if (element.has_property > ("vertex_indices")) + internal::read_PLY_faces (in, element, polygons, fcolors, "vertex_indices"); + else if (element.has_property > ("vertex_index")) + internal::read_PLY_faces (in, element, polygons, fcolors, "vertex_index"); + else if (element.has_property > ("vertex_index")) + internal::read_PLY_faces (in, element, polygons, fcolors, "vertex_index"); + else + { + std::cerr << "Error: can't find vertex indices in PLY input" << std::endl; + return false; + } + } + else // Read other elements and ignore + { + for (std::size_t j = 0; j < element.number_of_items(); ++ j) + { + for (std::size_t k = 0; k < element.number_of_properties(); ++ k) + { + internal::PLY::PLY_read_number* property = element.property(k); + property->get (in); + + if (in.fail()) + return false; + } + } } } - while (!(in.eof()) && points_read < reader.m_nb_points) - { - for (std::size_t i = 0; i < reader.readers().size (); ++ i) - reader.readers()[i]->get (in); - - cpp11::tuple new_vertex; - - if (has_colors) - { - internal::PLY::process_properties (reader, new_vertex, - make_ply_point_reader (CGAL::make_nth_of_tuple_property_map<0>(new_vertex)), - std::make_pair (CGAL::make_nth_of_tuple_property_map<1>(new_vertex), - PLY_property(rtag.c_str())), - std::make_pair (CGAL::make_nth_of_tuple_property_map<2>(new_vertex), - PLY_property(gtag.c_str())), - std::make_pair (CGAL::make_nth_of_tuple_property_map<3>(new_vertex), - PLY_property(btag.c_str()))); - - vcolors.push_back (Color_rgb (get<1>(new_vertex), get<2>(new_vertex), get<3>(new_vertex))); - } - else - internal::PLY::process_properties (reader, new_vertex, - make_ply_point_reader (CGAL::make_nth_of_tuple_property_map<0>(new_vertex))); - - points.push_back (get<0>(new_vertex)); - - ++ points_read; - } - - if (points_read != reader.m_nb_points) - return false; - - reader.read_faces(); - - if (reader.does_tag_exist > ("vertex_indices")) - return internal::read_PLY_faces (in, reader, polygons, fcolors, "vertex_indices"); - - if (reader.does_tag_exist > ("vertex_indices")) - return internal::read_PLY_faces (in, reader, polygons, fcolors, "vertex_indices"); - - if (reader.does_tag_exist > ("vertex_index")) - return internal::read_PLY_faces (in, reader, polygons, fcolors, "vertex_index"); - - if (reader.does_tag_exist > ("vertex_index")) - return internal::read_PLY_faces (in, reader, polygons, fcolors, "vertex_index"); - - std::cerr << "Error: can't find vertex indices in PLY input" << std::endl; - return false; + return true; } diff --git a/Polyline_simplification_2/demo/Polyline_simplification_2/CMakeLists.txt b/Polyline_simplification_2/demo/Polyline_simplification_2/CMakeLists.txt index 5ff66f49e79..4017702ca44 100644 --- a/Polyline_simplification_2/demo/Polyline_simplification_2/CMakeLists.txt +++ b/Polyline_simplification_2/demo/Polyline_simplification_2/CMakeLists.txt @@ -9,6 +9,10 @@ if(NOT POLICY CMP0070 AND POLICY CMP0053) cmake_policy(SET CMP0053 OLD) endif() +if(POLICY CMP0071) + cmake_policy(SET CMP0071 NEW) +endif() + find_package(CGAL COMPONENTS Qt5) find_package(Qt5 QUIET COMPONENTS Xml Script OpenGL Widgets Svg) diff --git a/Principal_component_analysis/demo/Principal_component_analysis/CMakeLists.txt b/Principal_component_analysis/demo/Principal_component_analysis/CMakeLists.txt index fc970ec50e6..a5ef7c1c906 100644 --- a/Principal_component_analysis/demo/Principal_component_analysis/CMakeLists.txt +++ b/Principal_component_analysis/demo/Principal_component_analysis/CMakeLists.txt @@ -8,6 +8,10 @@ if(NOT POLICY CMP0070 AND POLICY CMP0053) cmake_policy(SET CMP0053 OLD) endif() +if(POLICY CMP0071) + cmake_policy(SET CMP0071 NEW) +endif() + foreach(INCDIR ../../../STL_Extension/include ../../../GraphicsView/include ../../../filtered_kernel/include ) if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${INCDIR}") include_directories (BEFORE "${CMAKE_CURRENT_SOURCE_DIR}/${INCDIR}") diff --git a/Principal_component_analysis/demo/Principal_component_analysis/Scene.cpp b/Principal_component_analysis/demo/Principal_component_analysis/Scene.cpp index 38a89df8036..129799a7aa3 100644 --- a/Principal_component_analysis/demo/Principal_component_analysis/Scene.cpp +++ b/Principal_component_analysis/demo/Principal_component_analysis/Scene.cpp @@ -225,7 +225,7 @@ void Scene::refine_loop() return; } std::cout << "Loop subdivision..."; - CGAL::Subdivision_method_3::Loop_subdivision(*m_pPolyhedron, 1); + CGAL::Subdivision_method_3::Loop_subdivision(*m_pPolyhedron); std::cout << "done (" << m_pPolyhedron->size_of_facets() << " facets)" << std::endl; } diff --git a/QP_solver/doc/QP_solver/CGAL/QP_functions.h b/QP_solver/doc/QP_solver/CGAL/QP_functions.h index 1c8b614dd2b..f06b7f6f9a4 100644 --- a/QP_solver/doc/QP_solver/CGAL/QP_functions.h +++ b/QP_solver/doc/QP_solver/CGAL/QP_functions.h @@ -4,6 +4,8 @@ namespace CGAL { /// @{ /*! +\tparam LinearProgram a model of `LinearProgram`. + This function writes a linear program to an output stream (in `MPSFormat`). The time complexity is \f$ \Theta (mn)\f$, even if the program is very sparse. @@ -12,18 +14,9 @@ It writes the linear program `lp` to `out` in `MPSFormat`. The name of the program will be the one provided by `problem_name`. -Requirements --------------- - +\cgalHeading{Requirements} Output operators are defined for all entry types of `lp`. -Example --------------- - -\ref QP_solver/print_first_lp.cpp - -\sa The concept `LinearProgram` - */ template void print_linear_program @@ -32,6 +25,8 @@ const std::string& problem_name = std::string("MY_MPS")); /*! +\tparam NonnegativeLinearProgram a model of `NonnegativeLinearProgram` + This function writes a nonnegative linear program to an output stream (in `MPSFormat`). The time complexity is \f$ \Theta (mn)\f$, even if the program is very sparse. @@ -40,18 +35,9 @@ Writes the nonnegative linear program `lp` to `out` in `MPSFormat`. The name of the program will be the one provided by `problem_name`. -Requirements --------------- - +\cgalHeading{Requirements} Output operators are defined for all entry types of `lp`. -Example --------------- - -\ref QP_solver/print_first_nonnegative_lp.cpp - -\sa The concept `NonnegativeLinearProgram` - */ template void print_nonnegative_linear_program @@ -60,6 +46,8 @@ const std::string& problem_name = std::string("MY_MPS")); /*! +\tparam NonnegativeQuadraticProgram a model of `NonnegativeQuadraticProgram` + This function writes a nonnegative quadratic program to an output stream (in `MPSFormat`). The time complexity is \f$ \Theta (n^2 + mn)\f$, even if the program is very sparse. @@ -68,18 +56,9 @@ Writes the nonnegative quadratic program `qp` to `out` in `MPSFormat`. The name of the program will be the one provided by `problem_name`. -Requirements --------------- - +\cgalHeading{Requirements} Output operators are defined for all entry types of `qp`. -Example --------------- - -\ref QP_solver/print_first_nonnegative_qp.cpp - -\sa The concept `NonnegativeQuadraticProgram` - */ template void print_nonnegative_quadratic_program @@ -88,6 +67,9 @@ const std::string& problem_name = std::string("MY_MPS")); /*! +\tparam QuadraticProgram a model of `QuadraticProgram` + + This function writes a quadratic program to an output stream (in `MPSFormat`). The time complexity is \f$ \Theta (n^2 + mn)\f$, even if the program is very sparse. @@ -95,17 +77,9 @@ if the program is very sparse. Writes the quadratic program `qp` to `out` in `MPSFormat`. The name of the program will be the one provided by `problem_name`. -Requirements --------------- - +\cgalHeading{Requirements} Output operators are defined for all entry types of `qp`. -Example --------------- - -\ref QP_solver/print_first_qp.cpp - -\sa The concept `QuadraticProgram` */ template void print_quadratic_program @@ -118,10 +92,10 @@ This function solves a linear program, using some exact Integral Domain `ET` for its computations. Various options may be provided, see `Quadratic_program_options`. -Requirements --------------- +\tparam LinearProgram a model of `LinearProgram` such as `Quadratic_program`, +`Quadratic_program_from_mps`, or `Linear_program_from_iterators` -`ET` is a model of the concepts `IntegralDomain` and +\tparam ET a model of the concepts `IntegralDomain` and `RealEmbeddable`; it must be an exact type, and all entries of `qp` are convertible to `ET`. @@ -144,15 +118,6 @@ factor. For maximum efficiency, it is advisable to define the macros \returns the solution of the linear program `lp`, solved with exact number type `ET`. -Example --------------- - -\ref QP_solver/first_lp.cpp - -\sa `Quadratic_program` -\sa `Quadratic_program_from_mps` -\sa `Linear_program_from_iterators` - */ template Quadratic_program_solution solve_linear_program @@ -165,10 +130,10 @@ This function solves a nonnegative linear program, using some exact Integral Domain `ET` for its computations. Various options may be provided, see `Quadratic_program_options`. -Requirements --------------- +\tparam NonnegativeQuadraticProgram a model of `NonnegativeQuadraticProgram` such as +`Quadratic_program`, `Quadratic_program_from_mps`, or `Nonnegative_quadratic_program_from_iterators`. -`ET` is a model of the concepts `IntegralDomain` and +\tparam ET is a model of the concepts `IntegralDomain` and `RealEmbeddable`; it must be an exact type, and all entries of `qp` are convertible to `ET`. @@ -191,16 +156,6 @@ factor. For maximum efficiency, it is advisable to define the macros \returns the solution of the nonnegative linear program `lp`, solved with exact number type `ET`. -Example --------------- - -\ref QP_solver/first_nonnegative_lp.cpp - -The models of \ref NonnegativeLinearProgram\: -\sa `Quadratic_program` -\sa `Quadratic_program_from_mps` -\sa `Nonnegative_linear_program_from_iterators` - */ template Quadratic_program_solution solve_nonnegative_linear_program @@ -213,10 +168,10 @@ This function solves a nonnegative quadratic program, using some exact Integral Domain `ET` for its computations. Various options may be provided, see `Quadratic_program_options`. -Requirements --------------- +\tparam NonnegativeQuadraticProgram a model of `NonnegativeQuadraticProgram` such as +`Quadratic_program`, `Quadratic_program_from_mps`, or `Nonnegative_quadratic_program_from_iterators`. -`ET` is a model of the concepts `IntegralDomain` and +\tparam ET a model of the concepts `IntegralDomain` and `RealEmbeddable`; it must be an exact type, and all entries of `qp` are convertible to `ET`. @@ -239,15 +194,6 @@ factor. For maximum efficiency, it is advisable to define the macros \returns the solution of the nonnegative quadratic program `qp`, solved with exact number type `ET`. -Example --------------- - -\ref QP_solver/first_nonnegative_qp.cpp - -The models of \ref ::NonnegativeQuadraticProgram\: -\sa `Quadratic_program` -\sa `Quadratic_program_from_mps` -\sa `Nonnegative_quadratic_program_from_iterators` */ template Quadratic_program_solution solve_nonnegative_quadratic_program @@ -260,10 +206,11 @@ This function solves a quadratic program, using some exact Integral Domain `ET` for its computations. Various options may be provided, see `Quadratic_program_options`. -Requirements --------------- -`ET` is a model of the concepts `IntegralDomain` and +\tparam NonnegativeQuadraticProgram a model of `NonnegativeQuadraticProgram` such as +`Quadratic_program`, `Quadratic_program_from_mps`, or `Nonnegative_quadratic_program_from_iterators`. + +\tparam ET is a model of the concepts `IntegralDomain` and `RealEmbeddable`; it must be an exact type, and all entries of `qp` are convertible to `ET`. @@ -286,16 +233,6 @@ factor. For maximum efficiency, it is advisable to define the macros \returns the solution of the quadratic program `qp`, solved with exact number type `ET`. -Example --------------- - -\ref QP_solver/first_qp.cpp - -The models of \ref QuadraticProgram\: -\sa `Quadratic_program` -\sa `Quadratic_program_from_mps` -\sa `Quadratic_program_from_iterators` - */ template Quadratic_program_solution solve_quadratic_program diff --git a/QP_solver/doc/QP_solver/CGAL/QP_models.h b/QP_solver/doc/QP_solver/CGAL/QP_models.h index 1ede1029905..28748e7f103 100644 --- a/QP_solver/doc/QP_solver/CGAL/QP_models.h +++ b/QP_solver/doc/QP_solver/CGAL/QP_models.h @@ -57,8 +57,7 @@ namespace CGAL { \cgalModels `QuadraticProgram` \cgalModels `LinearProgram` - Example - -------------- + \cgalHeading{Example} \ref QP_solver/first_lp_from_iterators.cpp @@ -113,8 +112,7 @@ public: \returns an instance of `Linear_program_from_iterators`, constructed from the given iterators. - Example - -------------- + \cgalHeading{Example} The following example demonstrates the typical usage of makers with the simpler function `make_nonnegative_linear_program_from_iterators()`. @@ -160,8 +158,7 @@ make_linear_program_from_iterators ( \returns an instance of `Nonnegative_linear_program_from_iterators`, constructed from the given iterators. - Example - -------------- + \cgalHeading{Example} `QP_solver/solve_convex_hull_containment_lp2.h` @@ -198,8 +195,7 @@ make_nonnegative_linear_program_from_iterators ( `Nonnegative_quadratic_program_from_iterators`, constructed from the given iterators. - Example - -------------- + \cgalHeading{Example} The following example demonstrates the typical usage of makers with the simpler function `make_nonnegative_linear_program_from_iterators()`. @@ -240,8 +236,7 @@ make_nonnegative_quadratic_program_from_iterators ( \returns an instance of `Quadratic_program_from_iterators`, constructed from the given iterators. - Example - -------------- + \cgalHeading{Example} The following example demonstrates the typical usage of makers with the simpler function `make_nonnegative_linear_program_from_iterators()`. @@ -330,8 +325,7 @@ make_quadratic_program_from_iterators ( \cgalModels `NonnegativeQuadraticProgram` \cgalModels `NonnegativeLinearProgram` - Example - -------------- + \cgalHeading{Example} \ref QP_solver/first_nonnegative_lp_from_iterators.cpp @@ -422,8 +416,7 @@ public: \cgalModels `QuadraticProgram` \cgalModels `NonnegativeQuadraticProgram` - Example - -------------- + \cgalHeading{Example} \ref QP_solver/first_nonnegative_qp_from_iterators.cpp @@ -522,8 +515,7 @@ public: \cgalModels `QuadraticProgram` - Example - -------------- + \cgalHeading{Example} \ref QP_solver/first_qp_from_iterators.cpp @@ -630,8 +622,7 @@ public: \cgalModels `NonnegativeQuadraticProgram` \cgalModels `NonnegativeLinearProgram` - Example - -------------- + \cgalHeading{Example} \ref QP_solver/first_qp_from_mps.cpp @@ -854,8 +845,7 @@ namespace CGAL { \cgalModels `NonnegativeQuadraticProgram` \cgalModels `NonnegativeLinearProgram` - Example - -------------- + \cgalHeading{Example} \ref QP_solver/first_qp.cpp diff --git a/QP_solver/doc/QP_solver/CGAL/QP_options.h b/QP_solver/doc/QP_solver/CGAL/QP_options.h index 658363321e9..389f4dc81c2 100644 --- a/QP_solver/doc/QP_solver/CGAL/QP_options.h +++ b/QP_solver/doc/QP_solver/CGAL/QP_options.h @@ -15,8 +15,7 @@ options referring to The idea is that this list grows in the future. -Operations --------------- +\cgalHeading{Operations} Here we just have set/get pairs for any option type. diff --git a/QP_solver/doc/QP_solver/CGAL/QP_solution.h b/QP_solver/doc/QP_solver/CGAL/QP_solution.h index b3b9776dbfe..4335cfac32f 100644 --- a/QP_solver/doc/QP_solver/CGAL/QP_solution.h +++ b/QP_solver/doc/QP_solver/CGAL/QP_solution.h @@ -36,13 +36,11 @@ the four functions `solve_nonnegative_quadratic_program`, and `solve_nonnegative_linear_program`. -Example --------------- +\cgalHeading{Example} \ref QP_solver/first_qp.cpp -Terminology --------------- +\cgalHeading{Terminology} If there is no \f$ \qpx\f$ that satisfies all the (in)equalities, the program is called infeasible, otherwise, it is feasible, @@ -495,9 +493,9 @@ then \f$\lambda_i\geq 0\f$ (\f$\lambda_i\leq 0\f$, respectively).
    • \f[ \begin{array}{llll} -&&\geq 0 & \mbox{if \f$u_j=\infty\f$} \\ +&&\geq 0 & \mbox{if $u_j=\infty$} \\ \qplambda^T A_j &\quad \\ -&&\leq 0 & \mbox{if \f$l_j=-\infty\f$.} +&&\leq 0 & \mbox{if $l_j=-\infty$}. \end{array} \f]
    • \f[\qplambda^T\qpb \quad<\quad \ccSum{j: \qplambda^TA_j <0}{}{ \qplambda^TA_j u_j } @@ -508,12 +506,12 @@ then \f$\lambda_i\geq 0\f$ (\f$\lambda_i\leq 0\f$, respectively). that there is a feasible solution \f$\qpx\f$. Then we get \f[ \begin{array}{lcll} -0 &\geq& \qplambda^T(A\qpx -\qpb) & \mbox{(by \f$A\qpx\qprel \qpb\f$ and 1.)} \\ +0 &\geq& \qplambda^T(A\qpx -\qpb) & \mbox{(by $A\qpx\qprel \qpb$ and 1.)} \\ &=& \ccSum{j: \qplambda^TA_j <0}{}{ \qplambda^TA_j x_j } \quad+\quad \ccSum{j: \qplambda^TA_j >0}{}{ \qplambda^TA_j x_j} - \qplambda^T \qpb \\ &\geq& \ccSum{j: \qplambda^TA_j <0}{}{ \qplambda^TA_j u_j } \quad+\quad \ccSum{j: \qplambda^TA_j >0}{}{ \qplambda^TA_j l_j} - \qplambda^T \qpb & -\mbox{(by \f$\qpl\leq \qpx \leq \qpu\f$ and 2.)} \\ +\mbox{(by $\qpl\leq \qpx \leq \qpu$ and 2.)} \\ &>& 0 & \mbox{(by 3.)}, \end{array} \f] @@ -547,9 +545,9 @@ solution of (QP). The program (QP) is unbounded if an \f$n\f$-vector then \f$(A\qpw)_i\leq 0\f$ (\f$(A\qpw)_i\geq 0, (A\qpw)_i=0\f$, respectively).
    • \f[ \begin{array}{llll} -&&\geq 0 & \mbox{if \f$l_j\f$ is finite} \\ +&&\geq 0 & \mbox{if $l_j$ is finite} \\ w_j &\quad \\ -&&\leq 0 & \mbox{if \f$u_j\f$ is finite.} +&&\leq 0 & \mbox{if $u_j$ is finite.} \end{array} \f]
    • \f$\qpw^TD\qpw=0\f$ and \f$(\qpc^T+2{\qpx^*}^TD)\qpw<0\f$. diff --git a/QP_solver/doc/QP_solver/Doxyfile.in b/QP_solver/doc/QP_solver/Doxyfile.in index b3330c4cb4e..5d8e054a416 100644 --- a/QP_solver/doc/QP_solver/Doxyfile.in +++ b/QP_solver/doc/QP_solver/Doxyfile.in @@ -1,3 +1,5 @@ @INCLUDE = ${CGAL_DOC_PACKAGE_DEFAULTS} PROJECT_NAME = "CGAL ${CGAL_DOC_VERSION} - Linear and Quadratic Programming Solver" + +EXCLUDE = ${CGAL_PACKAGE_DOC_DIR}/fig_src diff --git a/QP_solver/doc/QP_solver/QP_solver.txt b/QP_solver/doc/QP_solver/QP_solver.txt index c7850995e6d..b61aa94727e 100644 --- a/QP_solver/doc/QP_solver/QP_solver.txt +++ b/QP_solver/doc/QP_solver/QP_solver.txt @@ -528,7 +528,7 @@ when we use the homogeneous representations of the points: if \f$ q_1,\ldots,q_n,q\in\mathbb{R}^{d+1}\f$ are homogeneous coordinates for \f$ p_1,\ldots,p_n,p\f$ with positive homogenizing coordinates \f$ h_1,\ldots,h_n,h\f$, we have -\f[$q_j = h_j \cdot (p_j \mid 1) \mbox{~for all $j$, and~} q = h \cdot +\f[q_j = h_j \cdot (p_j \mid 1) \mbox{~for all $j$, and~} q = h \cdot (p\mid 1).\f] Now, nonnegative \f$\lambda_1,\ldots,\lambda_n\f$ are suitable coefficients for a convex combination if and only if \f[\ccSum{j=1}{n}{~ \lambda_j(p_j \mid 1)} = (p\mid 1), \f] diff --git a/Ridges_3/doc/Ridges_3/Ridges_3.txt b/Ridges_3/doc/Ridges_3/Ridges_3.txt index ab9993f0822..8bbb53826c8 100644 --- a/Ridges_3/doc/Ridges_3/Ridges_3.txt +++ b/Ridges_3/doc/Ridges_3/Ridges_3.txt @@ -113,20 +113,16 @@ The Taylor expansion of \f$ k_1\f$ (resp. \f$ k_2\f$) along the max by \f$ x\f$ (resp. \f$ y\f$) are: \anchor eqtaylor_along_line -\f[ -\begin{equation} +\f{equation}{ k_1(x) = k_1 + b_0x + \frac{P_1}{2(k_1-k_2)}x^2 + ... , \quad \quad \quad P_1= 3b_1^2+(k_1-k_2)(c_0-3k_1^3). -\end{equation} -\f] +\f} \anchor eqtaylor_along_red_line -\f[ -\begin{equation} +\f{equation}{ k_2(y) = k_2 + b_3y + \frac{P_2}{2(k_2-k_1)}y^2 + ... , \quad \quad \quad P_2= 3b_2^2+(k_2-k_1)(c_4-3k_2^3). -\end{equation} -\f] +\f} Notice also that switching from one to the other of the two afore-mentioned coordinate systems reverts the sign of all the odd diff --git a/STL_Extension/include/CGAL/In_place_list.h b/STL_Extension/include/CGAL/In_place_list.h index face144af5e..25c8aed4c57 100644 --- a/STL_Extension/include/CGAL/In_place_list.h +++ b/STL_Extension/include/CGAL/In_place_list.h @@ -58,6 +58,10 @@ public: template < class T > class In_place_list_base { public: + In_place_list_base() + : next_link(NULL), prev_link(NULL) + {} + T* next_link; // forward pointer T* prev_link; // backwards pointer //friend class internal::In_place_list_iterator; diff --git a/STL_Extension/test/STL_Extension/test_dispatch_output.cpp b/STL_Extension/test/STL_Extension/test_dispatch_output.cpp index 8036587fc81..b8df6175cdc 100644 --- a/STL_Extension/test/STL_Extension/test_dispatch_output.cpp +++ b/STL_Extension/test/STL_Extension/test_dispatch_output.cpp @@ -23,7 +23,7 @@ void check_types(output out){ CGAL_USE_TYPE(typename output::pointer); CGAL_USE_TYPE(typename output::reference); T1 tmp=out.get_iterator_tuple(); - tmp=tmp; + tmp=(T1&)tmp; } template @@ -69,8 +69,8 @@ void complete_test(std::vector data1,std::list data2){ check_types(disp); check_types(drop); - disp = disp; - drop = drop; + disp = (Dispatcher&)disp; + drop = (Dropper&)drop; std::back_insert_iterator > bck_ins(cont_2); diff --git a/Scripts/developer_scripts/git-show-content b/Scripts/developer_scripts/git-show-content index 5ccd986a7ac..3c96f2efa27 100755 --- a/Scripts/developer_scripts/git-show-content +++ b/Scripts/developer_scripts/git-show-content @@ -3,9 +3,24 @@ zmodload zsh/stat set -e -git=git +if [ "x$1" = "x--help" -o "x$1" = "x-h" ]; then + cat < /dev/null 2>&1 gzip -f bundle size=${(l:4:)$(( $(zstat +size bundle.gz) / 1024 ))} - git show --no-patch --pretty='%C(auto)%h (SIZE: %C(auto)'"${size}kB)"' %s <%an> %cD' $c + git --no-pager show --no-patch --pretty='%C(auto)%h (SIZE: %C(auto)'"${size}kB)"' %s <%an> %cD' $c parents=(${(@)$(git rev-parse $c^@)}) if ! [ ${#${parents:1}[@]} -eq 0 ]; then - git show --no-patch --pretty=' merge: %h%C(auto)% d' ${parents:1} + git --no-pager show --no-patch --pretty=' merge: %h%C(auto)% d' ${parents:1} fi done last=$c -[ -n "$last" ] && git log -1 --pretty='Base commit: %C(auto)%h %d' ${last}'~' +[ -n "$last" ] && git --no-pager log -1 --pretty='Base commit: %C(auto)%h %d' ${last}'~' diff --git a/Segment_Delaunay_graph_2/examples/Segment_Delaunay_graph_2/sdg-filtered-traits.cpp b/Segment_Delaunay_graph_2/examples/Segment_Delaunay_graph_2/sdg-filtered-traits.cpp index 6945fb1c3a5..13e05eb5087 100644 --- a/Segment_Delaunay_graph_2/examples/Segment_Delaunay_graph_2/sdg-filtered-traits.cpp +++ b/Segment_Delaunay_graph_2/examples/Segment_Delaunay_graph_2/sdg-filtered-traits.cpp @@ -26,7 +26,8 @@ int main() assert( ifs ); SDG2 sdg; - SDG2::Site_2 site; + SDG2::Site_2 site = + SDG2::Site_2::construct_site_2(K::Point_2(CGAL::ORIGIN)); // read the sites and insert them in the segment Delaunay graph while ( ifs >> site ) { diff --git a/Segment_Delaunay_graph_2/test/Segment_Delaunay_graph_2/include/test_info.h b/Segment_Delaunay_graph_2/test/Segment_Delaunay_graph_2/include/test_info.h index 3db6956d14b..9ba280559d7 100644 --- a/Segment_Delaunay_graph_2/test/Segment_Delaunay_graph_2/include/test_info.h +++ b/Segment_Delaunay_graph_2/test/Segment_Delaunay_graph_2/include/test_info.h @@ -17,7 +17,8 @@ bool test_info(SDG& sdg, const char* fname) assert( ifs ); sdg.clear(); - typename SDG::Site_2 site; + typename SDG::Site_2 site = + SDG::Site_2::construct_site_2(typename SDG::Point_2(CGAL::ORIGIN)); // read the sites and insert them in the segment Delaunay graph int info_id = 1; diff --git a/Segment_Delaunay_graph_2/test/Segment_Delaunay_graph_2/include/test_types.h b/Segment_Delaunay_graph_2/test/Segment_Delaunay_graph_2/include/test_types.h index 630d7411361..612bcffa80b 100644 --- a/Segment_Delaunay_graph_2/test/Segment_Delaunay_graph_2/include/test_types.h +++ b/Segment_Delaunay_graph_2/test/Segment_Delaunay_graph_2/include/test_types.h @@ -167,7 +167,7 @@ bool test_sdg(InputStream&, const SDG&, const char* ifname, const char* ofname, start_testing("assignment operator"); sdg.insert(site_list.begin(), site_list.end()); - sdg = sdg; + sdg = (Segment_Delaunay_graph_2&)sdg; sdg2 = sdg; assert( sdg.is_valid() ); diff --git a/Segment_Delaunay_graph_Linf_2/examples/Segment_Delaunay_graph_Linf_2/sdg-filtered-traits-linf.cpp b/Segment_Delaunay_graph_Linf_2/examples/Segment_Delaunay_graph_Linf_2/sdg-filtered-traits-linf.cpp index 1b1777855a0..b7f9642ab6b 100644 --- a/Segment_Delaunay_graph_Linf_2/examples/Segment_Delaunay_graph_Linf_2/sdg-filtered-traits-linf.cpp +++ b/Segment_Delaunay_graph_Linf_2/examples/Segment_Delaunay_graph_Linf_2/sdg-filtered-traits-linf.cpp @@ -30,7 +30,8 @@ int main( int argc, char *argv[] ) assert( ifs ); SDG2 sdg; - SDG2::Site_2 site; + SDG2::Site_2 site = + SDG2::Site_2::construct_site_2(Rep::Point_2(CGAL::ORIGIN)); // read the sites and insert them in the segment Delaunay graph while ( ifs >> site ) { diff --git a/Segment_Delaunay_graph_Linf_2/test/Segment_Delaunay_graph_Linf_2/include/test_types.h b/Segment_Delaunay_graph_Linf_2/test/Segment_Delaunay_graph_Linf_2/include/test_types.h index b28f452f0a3..a2e414a691c 100644 --- a/Segment_Delaunay_graph_Linf_2/test/Segment_Delaunay_graph_Linf_2/include/test_types.h +++ b/Segment_Delaunay_graph_Linf_2/test/Segment_Delaunay_graph_Linf_2/include/test_types.h @@ -167,7 +167,7 @@ bool test_sdg(InputStream&, const SDG&, const char* ifname, const char* ofname, start_testing("assignment operator"); sdg.insert(site_list.begin(), site_list.end()); - sdg = sdg; + sdg = (Segment_Delaunay_graph_2&)sdg; sdg2 = sdg; assert( sdg.is_valid() ); diff --git a/Snap_rounding_2/test/Snap_rounding_2/cgal_test_base b/Snap_rounding_2/test/Snap_rounding_2/cgal_test_base index 42fd5193cd0..eb20f1c06cf 100755 --- a/Snap_rounding_2/test/Snap_rounding_2/cgal_test_base +++ b/Snap_rounding_2/test/Snap_rounding_2/cgal_test_base @@ -25,7 +25,7 @@ configure() { echo "Configuring... " - if eval 'cmake --no-warn-unused-cli "$CMAKE_GENERATOR" -DRUNNING_CGAL_AUTO_TEST=TRUE \ + if eval 'cmake --no-warn-unused-cli ${INIT_FILE:+"-C${INIT_FILE}"} "$CMAKE_GENERATOR" -DRUNNING_CGAL_AUTO_TEST=TRUE \ -DCGAL_DIR="$CGAL_DIR" \ .' ; then diff --git a/Spatial_searching/doc/Spatial_searching/CGAL/Splitters.h b/Spatial_searching/doc/Spatial_searching/CGAL/Splitters.h index 5f6fe92cb62..19a379dfad3 100644 --- a/Spatial_searching/doc/Spatial_searching/CGAL/Splitters.h +++ b/Spatial_searching/doc/Spatial_searching/CGAL/Splitters.h @@ -160,7 +160,7 @@ namespace CGAL { Implements the midpoint of max spread splitting rule. A rectangle is cut through \f$ (\mathrm{Mind}+\mathrm{Maxd})/2\f$ orthogonal -to the dimension with the maximum point spread \f$ [\mathrm{Mind},\matrm{Maxd}]\f$. +to the dimension with the maximum point spread \f$ [\mathrm{Mind},\mathrm{Maxd}]\f$. \cgalHeading{Parameters} diff --git a/Spatial_searching/include/CGAL/Kd_tree_rectangle.h b/Spatial_searching/include/CGAL/Kd_tree_rectangle.h index 1eb6efad609..042dbb088f0 100644 --- a/Spatial_searching/include/CGAL/Kd_tree_rectangle.h +++ b/Spatial_searching/include/CGAL/Kd_tree_rectangle.h @@ -166,6 +166,7 @@ namespace CGAL { inline FT min_coord(int i) const { + CGAL_assume(i -void CatmullClark_subdivision(PolygonMesh& pmesh, int step = 1) { +CGAL_DEPRECATED_MSG("you are using the deprecated API of CatmullClark_subdivision(), please update your code") +void CatmullClark_subdivision(PolygonMesh& pmesh, int step) { PQQ(pmesh, CatmullClark_mask_3(&pmesh, get(vertex_point,pmesh)), step); } +#endif #endif /*! @@ -138,14 +141,22 @@ void CatmullClark_subdivision(PolygonMesh& pmesh, const NamedParameters& np) { internal::PQQ_1step(pmesh, vpm, mask); } +template +void CatmullClark_subdivision(PolygonMesh& pmesh) +{ + CatmullClark_subdivision(pmesh, CGAL::parameters::all_default()); +} // ----------------------------------------------------------------------------- #ifndef DOXYGEN_RUNNING // backward compatibility +#ifndef CGAL_NO_DEPRECATED_CODE template -void Loop_subdivision(PolygonMesh& pmesh, int step = 1) { +CGAL_DEPRECATED_MSG("you are using the deprecated API of Loop_subdivision(), please update your code") +void Loop_subdivision(PolygonMesh& pmesh, int step) { PTQ(pmesh, Loop_mask_3(&pmesh, get(vertex_point,pmesh)) , step); } +#endif #endif /*! @@ -183,15 +194,23 @@ void Loop_subdivision(PolygonMesh& pmesh, const NamedParameters& np) { internal::PTQ_1step(pmesh, vpm, mask); } +template +void Loop_subdivision(PolygonMesh& pmesh) +{ + Loop_subdivision(pmesh, CGAL::parameters::all_default()); +} // ----------------------------------------------------------------------------- #ifndef DOXYGEN_RUNNING // backward compatibility +#ifndef CGAL_NO_DEPRECATED_CODE template -void DooSabin_subdivision(PolygonMesh& pmesh, int step = 1) { +CGAL_DEPRECATED_MSG("you are using the deprecated API of DooSabin_subdivision(), please update your code") +void DooSabin_subdivision(PolygonMesh& pmesh, int step) { DQQ(pmesh, DooSabin_mask_3(&pmesh, get(vertex_point, pmesh)), step); } #endif +#endif /*! * @@ -227,16 +246,24 @@ void DooSabin_subdivision(PolygonMesh& pmesh, const NamedParameters& np) { for(unsigned int i = 0; i < step; i++) internal::DQQ_1step(pmesh, vpm, mask); } - + +template +void DooSabin_subdivision(PolygonMesh& pmesh) +{ + DooSabin_subdivision(pmesh, CGAL::parameters::all_default()); +} // ----------------------------------------------------------------------------- #ifndef DOXYGEN_RUNNING // backward compatibility +#ifndef CGAL_NO_DEPRECATED_CODE template -void Sqrt3_subdivision(PolygonMesh& pmesh, int step = 1) { +CGAL_DEPRECATED_MSG("you are using the deprecated API of Sqrt3_subdivision(), please update your code") +void Sqrt3_subdivision(PolygonMesh& pmesh, int step) { Sqrt3(pmesh, Sqrt3_mask_3(&pmesh, get(vertex_point,pmesh)), step); } #endif +#endif /*! * @@ -277,7 +304,12 @@ void Sqrt3_subdivision(PolygonMesh& pmesh, const NamedParameters& np) { for(unsigned int i = 0; i < step; i++) internal::Sqrt3_1step(pmesh, vpm, mask, (i%2==1)); } - + +template +void Sqrt3_subdivision(PolygonMesh& pmesh) +{ + Sqrt3_subdivision(pmesh, CGAL::parameters::all_default()); +} /// @} } // namespace Subdivision_method_3 diff --git a/Subdivision_method_3/test/Subdivision_method_3/test_Subdivision_method_3.cpp b/Subdivision_method_3/test/Subdivision_method_3/test_Subdivision_method_3.cpp index 7b0e8f399e5..b467aea5e90 100644 --- a/Subdivision_method_3/test/Subdivision_method_3/test_Subdivision_method_3.cpp +++ b/Subdivision_method_3/test/Subdivision_method_3/test_Subdivision_method_3.cpp @@ -57,7 +57,7 @@ void test_Subdivision_surface_3() { Polyhedron P; mesh >> P; - Subdivision_method_3::CatmullClark_subdivision(P,TEST_DEPTH); + Subdivision_method_3::CatmullClark_subdivision(P); assert(CGAL::is_valid_polygon_mesh(P)); } @@ -68,7 +68,7 @@ void test_Subdivision_surface_3() { Polyhedron P; mesh >> P; - Subdivision_method_3::CatmullClark_subdivision(P,TEST_DEPTH); + Subdivision_method_3::CatmullClark_subdivision(P); assert(CGAL::is_valid_polygon_mesh(P)); } @@ -80,7 +80,7 @@ void test_Subdivision_surface_3() { Polyhedron P; mesh >> P; - Subdivision_method_3::Loop_subdivision(P,TEST_DEPTH); + Subdivision_method_3::Loop_subdivision(P); assert(CGAL::is_valid_polygon_mesh(P)); } @@ -91,7 +91,7 @@ void test_Subdivision_surface_3() { Polyhedron P; mesh >> P; - Subdivision_method_3::Loop_subdivision(P,TEST_DEPTH); + Subdivision_method_3::Loop_subdivision(P); assert(CGAL::is_valid_polygon_mesh(P)); } @@ -102,7 +102,7 @@ void test_Subdivision_surface_3() { Polyhedron P; mesh >> P; - Subdivision_method_3::DooSabin_subdivision(P,TEST_DEPTH); + Subdivision_method_3::DooSabin_subdivision(P); assert(CGAL::is_valid_polygon_mesh(P)); } @@ -113,7 +113,7 @@ void test_Subdivision_surface_3() { Polyhedron P; mesh >> P; - Subdivision_method_3::Sqrt3_subdivision(P,TEST_DEPTH); + Subdivision_method_3::Sqrt3_subdivision(P); assert(CGAL::is_valid_polygon_mesh(P)); } } @@ -129,7 +129,7 @@ void test_Subdivision_surface_3_SM() { Polyhedron P; mesh >> P; - Subdivision_method_3::CatmullClark_subdivision(P,TEST_DEPTH); + Subdivision_method_3::CatmullClark_subdivision(P); assert(CGAL::is_valid_polygon_mesh(P)); } @@ -140,7 +140,7 @@ void test_Subdivision_surface_3_SM() { Polyhedron P; mesh >> P; - Subdivision_method_3::CatmullClark_subdivision(P,TEST_DEPTH); + Subdivision_method_3::CatmullClark_subdivision(P); assert(CGAL::is_valid_polygon_mesh(P)); } @@ -152,7 +152,7 @@ void test_Subdivision_surface_3_SM() { Polyhedron P; mesh >> P; - Subdivision_method_3::Loop_subdivision(P,TEST_DEPTH); + Subdivision_method_3::Loop_subdivision(P); assert(CGAL::is_valid_polygon_mesh(P)); } @@ -163,7 +163,7 @@ void test_Subdivision_surface_3_SM() { Polyhedron P; mesh >> P; - Subdivision_method_3::Loop_subdivision(P,TEST_DEPTH); + Subdivision_method_3::Loop_subdivision(P); assert(CGAL::is_valid_polygon_mesh(P)); } @@ -174,7 +174,7 @@ void test_Subdivision_surface_3_SM() { Polyhedron P; mesh >> P; - Subdivision_method_3::DooSabin_subdivision(P,TEST_DEPTH); + Subdivision_method_3::DooSabin_subdivision(P); assert(CGAL::is_valid_polygon_mesh(P, true)); } @@ -185,7 +185,7 @@ void test_Subdivision_surface_3_SM() { Polyhedron P; mesh >> P; - Subdivision_method_3::DooSabin_subdivision(P,TEST_DEPTH); + Subdivision_method_3::DooSabin_subdivision(P); assert(CGAL::is_valid_polygon_mesh(P)); } @@ -196,7 +196,7 @@ void test_Subdivision_surface_3_SM() { Polyhedron P; mesh >> P; - Subdivision_method_3::Sqrt3_subdivision(P,TEST_DEPTH); + Subdivision_method_3::Sqrt3_subdivision(P); assert(CGAL::is_valid_polygon_mesh(P)); } @@ -207,7 +207,7 @@ void test_Subdivision_surface_3_SM() { Polyhedron P; mesh >> P; - Subdivision_method_3::Sqrt3_subdivision(P,TEST_DEPTH); + Subdivision_method_3::Sqrt3_subdivision(P); assert(CGAL::is_valid_polygon_mesh(P)); } } @@ -284,7 +284,7 @@ void test_Subdivision_surface_3_SM_NP() { Polyhedron P; mesh >> P; - Subdivision_method_3::DooSabin_subdivision(P,TEST_DEPTH); + Subdivision_method_3::DooSabin_subdivision(P,Subdivision_method_3::parameters::number_of_iterations(TEST_DEPTH)); assert(CGAL::is_valid_polygon_mesh(P)); } diff --git a/Subdivision_method_3/test/Subdivision_method_3/test_deprecated_Subdivision_method_3.cpp b/Subdivision_method_3/test/Subdivision_method_3/test_deprecated_Subdivision_method_3.cpp new file mode 100644 index 00000000000..c8a6c85c632 --- /dev/null +++ b/Subdivision_method_3/test/Subdivision_method_3/test_deprecated_Subdivision_method_3.cpp @@ -0,0 +1,362 @@ +#include +// ============================================================================ +// +// Copyright (c) 2005-2006, 2017 Le-Jeng Shiue +// +// This software and related documentation is part of an INTERNAL release +// of the Computational Geometry Algorithms Library (CGAL). It is not +// intended for general use. +// +// ---------------------------------------------------------------------------- +// +// release : $CGAL_Revision: $ +// release_date : $CGAL_Date: $ +// +// file : test/Subdivision_method_3/test_Subdivision_method_3.C +// package : Subdivision_method_3 +// chapter : Subdivision Method +// +// revision : $Id$ +// revision_date : $Date$ +// +// author(s) : Le-Jeng Shiue +// +// Test subdivision methods +// ============================================================================ + +#include +#include +#include + +#include + +#include +#include +#include + +using namespace std; +using namespace CGAL; + +#define TEST_DEPTH (3) + +//#define TESTMESH_GENERAL "data/??.off" + +#define TESTMESH_QUAD "data/corner.off" +#define TESTMESH_QUAD_OPEN "data/corner_with_hole.off" + +#define TESTMESH_TRI "data/quint_tris.off" +#define TESTMESH_TRI_OPEN "data/nefertiti.off" + +void test_Subdivision_surface_3() { + typedef CGAL::Simple_cartesian Kernel; + typedef CGAL::Polyhedron_3 Polyhedron; + + // test Catmull-Clark subdivision on quad mesh + { + ifstream mesh(TESTMESH_QUAD); + + Polyhedron P; + mesh >> P; + + Subdivision_method_3::CatmullClark_subdivision(P,TEST_DEPTH); + assert(CGAL::is_valid_polygon_mesh(P)); + } + + // test Catmull-Clark subdivision on 'opened' quad mesh + { + ifstream mesh(TESTMESH_QUAD_OPEN); + + Polyhedron P; + mesh >> P; + + Subdivision_method_3::CatmullClark_subdivision(P,TEST_DEPTH); + assert(CGAL::is_valid_polygon_mesh(P)); + } + + + // test Loop subdivision on tri mesh + { + ifstream mesh(TESTMESH_TRI); + + Polyhedron P; + mesh >> P; + + Subdivision_method_3::Loop_subdivision(P,TEST_DEPTH); + assert(CGAL::is_valid_polygon_mesh(P)); + } + + // test Loop subdivision on 'opened' tri mesh + { + ifstream mesh(TESTMESH_TRI_OPEN); + + Polyhedron P; + mesh >> P; + + Subdivision_method_3::Loop_subdivision(P,TEST_DEPTH); + assert(CGAL::is_valid_polygon_mesh(P)); + } + + // test Doo-Sabin subdivision on general mesh + { + ifstream mesh(TESTMESH_TRI_OPEN); + + Polyhedron P; + mesh >> P; + + Subdivision_method_3::DooSabin_subdivision(P,TEST_DEPTH); + assert(CGAL::is_valid_polygon_mesh(P)); + } + + // test Sqrt-3 subdivision on tri mesh + { + ifstream mesh(TESTMESH_TRI); + + Polyhedron P; + mesh >> P; + + Subdivision_method_3::Sqrt3_subdivision(P,TEST_DEPTH); + assert(CGAL::is_valid_polygon_mesh(P)); + } +} + +void test_Subdivision_surface_3_SM() { + typedef CGAL::Simple_cartesian Kernel; + typedef CGAL::Surface_mesh Polyhedron; + + // test Catmull-Clark subdivision on quad mesh + { + ifstream mesh(TESTMESH_QUAD); + + Polyhedron P; + mesh >> P; + + Subdivision_method_3::CatmullClark_subdivision(P,TEST_DEPTH); + assert(CGAL::is_valid_polygon_mesh(P)); + } + + // test Catmull-Clark subdivision on 'opened' quad mesh + { + ifstream mesh(TESTMESH_QUAD_OPEN); + + Polyhedron P; + mesh >> P; + + Subdivision_method_3::CatmullClark_subdivision(P,TEST_DEPTH); + assert(CGAL::is_valid_polygon_mesh(P)); + } + + + // test Loop subdivision on tri mesh + { + ifstream mesh(TESTMESH_TRI); + + Polyhedron P; + mesh >> P; + + Subdivision_method_3::Loop_subdivision(P,TEST_DEPTH); + assert(CGAL::is_valid_polygon_mesh(P)); + } + + // test Loop subdivision on 'opened' tri mesh + { + ifstream mesh(TESTMESH_TRI_OPEN); + + Polyhedron P; + mesh >> P; + + Subdivision_method_3::Loop_subdivision(P,TEST_DEPTH); + assert(CGAL::is_valid_polygon_mesh(P)); + } + + // test Doo-Sabin subdivision on general mesh + { + ifstream mesh(TESTMESH_TRI_OPEN); + + Polyhedron P; + mesh >> P; + + Subdivision_method_3::DooSabin_subdivision(P,TEST_DEPTH); + assert(CGAL::is_valid_polygon_mesh(P, true)); + } + + // test Doo-Sabin subdivision on 'opened' quad mesh + { + ifstream mesh(TESTMESH_QUAD_OPEN); + + Polyhedron P; + mesh >> P; + + Subdivision_method_3::DooSabin_subdivision(P,TEST_DEPTH); + assert(CGAL::is_valid_polygon_mesh(P)); + } + + // test Sqrt-3 subdivision on tri mesh + { + ifstream mesh(TESTMESH_TRI); + + Polyhedron P; + mesh >> P; + + Subdivision_method_3::Sqrt3_subdivision(P,TEST_DEPTH); + assert(CGAL::is_valid_polygon_mesh(P)); + } + + // test Sqrt-3 subdivision on 'opened' tri mesh + { + ifstream mesh(TESTMESH_TRI_OPEN); + + Polyhedron P; + mesh >> P; + + Subdivision_method_3::Sqrt3_subdivision(P,TEST_DEPTH); + assert(CGAL::is_valid_polygon_mesh(P)); + } +} + +void test_Subdivision_surface_3_SM_NP() { + typedef CGAL::Simple_cartesian Kernel; + typedef CGAL::Surface_mesh Polyhedron; + + // test Catmull-Clark subdivision on quad mesh + { + ifstream mesh(TESTMESH_QUAD); + + Polyhedron P; + mesh >> P; + + Subdivision_method_3::CatmullClark_subdivision(P,Subdivision_method_3::parameters::vertex_point_map(get(vertex_point, P)) + .number_of_iterations(TEST_DEPTH)); + assert(CGAL::is_valid_polygon_mesh(P)); + } + + // test Catmull-Clark subdivision on 'opened' quad mesh + { + ifstream mesh(TESTMESH_QUAD_OPEN); + + Polyhedron P; + mesh >> P; + + Subdivision_method_3::CatmullClark_subdivision(P,Subdivision_method_3::parameters::vertex_point_map(get(vertex_point, P)) + .number_of_iterations(TEST_DEPTH)); + assert(CGAL::is_valid_polygon_mesh(P)); + } + + + // test Loop subdivision on tri mesh + { + ifstream mesh(TESTMESH_TRI); + + Polyhedron P; + mesh >> P; + + Subdivision_method_3::Loop_subdivision(P,Subdivision_method_3::parameters::vertex_point_map(get(vertex_point, P)) + .number_of_iterations(TEST_DEPTH)); + assert(CGAL::is_valid_polygon_mesh(P)); + } + + // test Loop subdivision on 'opened' tri mesh + { + ifstream mesh(TESTMESH_TRI_OPEN); + + Polyhedron P; + mesh >> P; + + Subdivision_method_3::Loop_subdivision(P,Subdivision_method_3::parameters::vertex_point_map(get(vertex_point, P)) + .number_of_iterations(TEST_DEPTH)); + assert(CGAL::is_valid_polygon_mesh(P)); + } + + // test Doo-Sabin subdivision on 'opened' tri mesh + { + ifstream mesh(TESTMESH_TRI_OPEN); + + Polyhedron P; + mesh >> P; + + Subdivision_method_3::DooSabin_subdivision(P,Subdivision_method_3::parameters::vertex_point_map(get(vertex_point, P)) + .number_of_iterations(TEST_DEPTH)); + assert(CGAL::is_valid_polygon_mesh(P)); + } + + // test Doo-Sabin subdivision on 'opened' quad mesh + { + ifstream mesh(TESTMESH_QUAD_OPEN); + + Polyhedron P; + mesh >> P; + + Subdivision_method_3::DooSabin_subdivision(P,TEST_DEPTH); + assert(CGAL::is_valid_polygon_mesh(P)); + } + + // test Sqrt-3 subdivision on tri mesh + { + ifstream mesh(TESTMESH_TRI); + + Polyhedron P; + mesh >> P; + + Subdivision_method_3::Sqrt3_subdivision(P,Subdivision_method_3::parameters::vertex_point_map(get(vertex_point, P)) + .number_of_iterations(TEST_DEPTH)); + + assert(CGAL::is_valid_polygon_mesh(P)); + } + + // test Sqrt-3 subdivision on 'opened' tri mesh + { + ifstream mesh(TESTMESH_TRI_OPEN); + + Polyhedron P; + mesh >> P; + + Subdivision_method_3::Sqrt3_subdivision(P,Subdivision_method_3::parameters::vertex_point_map(get(vertex_point, P)) + .number_of_iterations(TEST_DEPTH)); + + std::ofstream out("out_0.off"); + out << P; + + assert(CGAL::is_valid_polygon_mesh(P)); + } + + // test Sqrt-3 subdivision on 'opened' tri mesh & with external property map + { + ifstream mesh(TESTMESH_TRI_OPEN); + + Polyhedron P; + mesh >> P; + + typedef Kernel::Point_3 Point; + typedef Kernel::Vector_3 Vector; + + typedef boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef boost::unordered_map Point_pmap; + typedef boost::associative_property_map APM; + typedef boost::property_map::type VPM; + + Point_pmap um; + APM apm(um); + VPM vpm = get(vertex_point, P); + + // some arbitrary new coordinates (different from the internal vpm) + BOOST_FOREACH(vertex_descriptor vd, vertices(P)) { + boost::property_traits::reference pt = get(vpm, vd); + Vector v = pt - Point(0., 0., -3.); + put(apm, vd, pt + 0.5*v); + } + + Subdivision_method_3::Sqrt3_subdivision(P, + Subdivision_method_3::parameters::vertex_point_map(apm) + .number_of_iterations(TEST_DEPTH)); + + assert(CGAL::is_valid_polygon_mesh(P)); + } +} + +int main() { + test_Subdivision_surface_3(); + test_Subdivision_surface_3_SM(); + test_Subdivision_surface_3_SM_NP(); + std::cerr << "Done" << std::endl; + return 0; +} +// EOF // diff --git a/Surface_mesh/doc/Surface_mesh/PackageDescription.txt b/Surface_mesh/doc/Surface_mesh/PackageDescription.txt index 4fecf7ee900..af323cdd4a7 100644 --- a/Surface_mesh/doc/Surface_mesh/PackageDescription.txt +++ b/Surface_mesh/doc/Surface_mesh/PackageDescription.txt @@ -1,4 +1,3 @@ - /// \defgroup PkgSurface_mesh Surface Mesh Reference /*! Draw. diff --git a/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h b/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h index 88aad1e20b9..e6cee1568a3 100644 --- a/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h +++ b/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h @@ -1112,28 +1112,33 @@ public: bool join(const Surface_mesh& other) { + // increase capacity const size_type nv = num_vertices(), nh = num_halfedges(), nf = num_faces(); resize(num_vertices()+ other.num_vertices(), num_edges()+ other.num_edges(), num_faces()+ other.num_faces()); + // append properties in the free space created by resize vprops_.transfer(other.vprops_); hprops_.transfer(other.hprops_); fprops_.transfer(other.fprops_); eprops_.transfer(other.eprops_); + // translate halfedge index in vertex -> halfedge for(size_type i = nv; i < nv+other.num_vertices(); i++){ Vertex_index vi(i); if(vconn_[vi].halfedge_ != null_halfedge()){ vconn_[vi].halfedge_ = Halfedge_index(size_type(vconn_[vi].halfedge_)+nh); } } + // translate halfedge index in face -> halfedge for(size_type i = nf; i < nf+other.num_faces(); i++){ Face_index fi(i); if(fconn_[fi].halfedge_ != null_halfedge()){ fconn_[fi].halfedge_ = Halfedge_index(size_type(fconn_[fi].halfedge_)+nh); } } + // translate indices in halfedge -> face, halfedge -> target, halfedge -> prev, and halfedge -> next for(size_type i = nh; i < nh+other.num_halfedges(); i++){ Halfedge_index hi(i); if(hconn_[hi].face_ != null_face()){ @@ -1150,43 +1155,50 @@ public: } } size_type inf_value = (std::numeric_limits::max)(); + + // merge vertex free list if(other.vertices_freelist_ != inf_value){ - if(vertices_freelist_ != inf_value){ - Vertex_index vi(nv+other.vertices_freelist_); - Halfedge_index inf((std::numeric_limits::max)()); - while(vconn_[vi].halfedge_ != inf){ - Vertex_index corrected_vi = Vertex_index(size_type(vconn_[vi].halfedge_)+nv-nh); - vconn_[vi].halfedge_ = Halfedge_index(corrected_vi); - vi = corrected_vi; - } - vconn_[vi].halfedge_ = Halfedge_index(vertices_freelist_); + Vertex_index vi(nv+other.vertices_freelist_); + Halfedge_index inf((std::numeric_limits::max)()); + // correct the indices in the linked list of free vertices copied (due to vconn_ translation) + while(vconn_[vi].halfedge_ != inf){ + Vertex_index corrected_vi = Vertex_index(size_type(vconn_[vi].halfedge_)+nv-nh); + vconn_[vi].halfedge_ = Halfedge_index(corrected_vi); + vi = corrected_vi; } + // append the vertex free linked list of `this` to the copy of `other` + vconn_[vi].halfedge_ = Halfedge_index(vertices_freelist_); + // update the begin of the vertex free linked list vertices_freelist_ = nv + other.vertices_freelist_; } + // merge face free list if(other.faces_freelist_ != inf_value){ - if(faces_freelist_ != inf_value){ - Face_index fi(nf+other.faces_freelist_); - Halfedge_index inf((std::numeric_limits::max)()); - while(fconn_[fi].halfedge_ != inf){ - Face_index corrected_fi = Face_index(size_type(fconn_[fi].halfedge_)+nf-nh); - fconn_[fi].halfedge_ = Halfedge_index(corrected_fi); - fi = corrected_fi; - } - fconn_[fi].halfedge_ = Halfedge_index(faces_freelist_); + Face_index fi(nf+other.faces_freelist_); + Halfedge_index inf((std::numeric_limits::max)()); + // correct the indices in the linked list of free faces copied (due to fconn_ translation) + while(fconn_[fi].halfedge_ != inf){ + Face_index corrected_fi = Face_index(size_type(fconn_[fi].halfedge_)+nf-nh); + fconn_[fi].halfedge_ = Halfedge_index(corrected_fi); + fi = corrected_fi; } + // append the face free linked list of `this` to the copy of `other` + fconn_[fi].halfedge_ = Halfedge_index(faces_freelist_); + // update the begin of the face free linked list faces_freelist_ = nf + other.faces_freelist_; } + // merge edge free list if(other.edges_freelist_ != inf_value){ - if(edges_freelist_ != inf_value){ - Halfedge_index hi(nh+other.edges_freelist_); - Halfedge_index inf((std::numeric_limits::max)()); - while(hconn_[hi].next_halfedge_ != inf){ - hi = hconn_[hi].next_halfedge_; - } - hconn_[hi].next_halfedge_ = Halfedge_index(edges_freelist_); + Halfedge_index hi(nh+other.edges_freelist_); + Halfedge_index inf((std::numeric_limits::max)()); + while(hconn_[hi].next_halfedge_ != inf){ + hi = hconn_[hi].next_halfedge_; } + // append the halfedge free linked list of `this` to the copy of `other` + hconn_[hi].next_halfedge_ = Halfedge_index(edges_freelist_); + // update the begin of the halfedge free linked list edges_freelist_ = nh + other.edges_freelist_; } + // update garbage infos garbage_ = garbage_ || other.garbage_; removed_vertices_ += other.removed_vertices_; removed_edges_ += other.removed_edges_; @@ -1423,6 +1435,33 @@ public: if(!valid && verbose){ std::cerr << "#faces: iterated: " << fcount << " vs number_of_faces(): " << number_of_faces()<< std::endl; } + + size_type inf = (std::numeric_limits::max)(); + size_type vfl = vertices_freelist_; + size_type rv = 0; + while(vfl != inf){ + vfl = (size_type)vconn_[Vertex_index(vfl)].halfedge_; + rv++; + } + valid = valid && ( rv == removed_vertices_ ); + + + size_type efl = edges_freelist_; + size_type re = 0; + while(efl != inf){ + efl = (size_type)hconn_[Halfedge_index(efl)].next_halfedge_; + re++; + } + valid = valid && ( re == removed_edges_ ); + + size_type ffl = faces_freelist_; + size_type rf = 0; + while(ffl != inf){ + ffl = (size_type)fconn_[Face_index(ffl)].halfedge_; + rf++; + } + valid = valid && ( rf == removed_faces_ ); + return valid; } @@ -2155,10 +2194,18 @@ private: //------------------------------------------------------- private data std::string off; is >> sm_skip_comments; is >> off; - CGAL_assertion( (off == "OFF") || (off == "COFF") || (off == "NOFF") || (off == "CNOFF")); - + if(! ( + (off == "OFF") || (off == "COFF") || (off == "NOFF") || (off == "CNOFF") + ) + ) + { + is.setstate(std::ios::failbit); + return false; + } is >> n >> f >> e; - + if(!is){ + return false; + } sm.reserve(sm.num_vertices()+n, sm.num_faces()+2*f, sm.num_edges()+e); std::vector vertexmap(n); P p; @@ -2215,6 +2262,10 @@ private: //------------------------------------------------------- private data for(int i=0; i < f; i++){ is >> sm_skip_comments; is >> d; + if(!is){ + sm.clear(); + return false; + } vr.resize(d); for(std::size_t j=0; j> vi; @@ -2551,6 +2602,11 @@ void Surface_mesh

      :: collect_garbage() { + if (!has_garbage()) + { + return; + } + int i, i0, i1, nV(num_vertices()), nE(num_edges()), diff --git a/Surface_mesh_deformation/doc/Surface_mesh_deformation/Surface_mesh_deformation.txt b/Surface_mesh_deformation/doc/Surface_mesh_deformation/Surface_mesh_deformation.txt index b5df4208507..9368c7905a8 100644 --- a/Surface_mesh_deformation/doc/Surface_mesh_deformation/Surface_mesh_deformation.txt +++ b/Surface_mesh_deformation/doc/Surface_mesh_deformation/Surface_mesh_deformation.txt @@ -255,12 +255,10 @@ The Laplacian representation (referred to as Laplace coordinatesencode the local neighborhood of a vertex in the surface mesh. In this representation, a vertex \f$ \mathbf{v}_i \f$ is associated a 3D vector defined as: -\f[ -\begin{equation} +\f{equation}{ L(\mathbf{v}_i) = \sum_{\mathbf{v}_j \in N(\mathbf{v}_i)} w_{ij}(\mathbf{v}_i - \mathbf{v}_j), \label{eq:lap_open} -\end{equation} -\f] +\f} where: - \f$N(\mathbf{v}_i)\f$ denotes the set of vertices adjacent to \f$\mathbf{v}_i\f$; @@ -282,12 +280,10 @@ Laplacian representation of \f$ v_i \f$ with uniform weights: the red square ver Considering a surface mesh with \f$n\f$ vertices, it is possible to define its Laplacian representation \f$\Delta\f$ as a \f$n \times 3\f$ matrix: -\f[ -\begin{equation} +\f{equation}{ \mathbf{L}\mathbf{V} = \Delta, \label{eq:lap_system} -\end{equation} -\f] +\f} where: - \f$\mathbf{L}\f$ is a \f$n \times n\f$ sparse matrix, referred to as the Laplacian matrix. Its elements \f$ m_{ij} \f$, \f$i,j \in \{1 \dots n\} \f$ are defined as follows: @@ -313,8 +309,7 @@ This package supports hard constraints, that is, target positions of control ver Given a surface mesh deformation system with a ROI made of \f$ n \f$ vertices and \f$ k \f$ control vertices, we consider the following linear system: -\f[ -\begin{equation} +\f{equation}{ \left[ \begin{array}{ccc} \mathbf{L}_f\\ @@ -329,8 +324,7 @@ Given a surface mesh deformation system with a ROI made of \f$ n \f$ vertices an \end{array} \right], \label{eq:lap_energy_system} -\end{equation} -\f] +\f} where: - \f$\mathbf{V}\f$ is a \f$n \times 3\f$ matrix denoting the unknowns of the system that represent the vertex coordinates after deformation. The system is built so that the \f$ k \f$ last rows correspond to the control vertices. @@ -348,14 +342,12 @@ preserves the Laplacian representation of the surface mesh restricted to the unc Given a surface mesh \f$M\f$ with \f$ n \f$ vertices \f$ \{\mathbf{v}_i\} i \in \{1 \dots n \} \f$ and some deformation constraints, we consider the following energy function: -\f[ -\begin{equation} +\f{equation}{ \sum_{\mathbf{v}_i \in M} \sum_{\mathbf{v}_j \in N(\mathbf{v}_i)} w_{ij} \left\| (\mathbf{v}'_i - \mathbf{v}'_j) - \mathbf{R}_i(\mathbf{v}_i - \mathbf{v}_j) \right\|^2, \label{eq:arap_energy} -\end{equation} -\f] +\f} where: - \f$\mathbf{R}_i\f$ is a \f$ 3 \times 3 \f$ rotation matrix @@ -387,12 +379,10 @@ Each such term of the energy is minimized by using a two-step optimization appro In the first step, the positions of the vertices are considered as fixed so that the rotation matrices are the only unknowns. For the vertex \f$\mathbf{v}_i\f$, we consider the covariance matrix \f$\mathbf{S}_i\f$: -\f[ -\begin{equation} +\f{equation}{ \mathbf{S}_i = \sum_{\mathbf{v}_j \in N(\mathbf{v}_i)} w_{ij} (\mathbf{v}_i - \mathbf{v}_j)(\mathbf{v}'_i - \mathbf{v}'_j)^T, \label{eq:cov_matrix} -\end{equation} -\f] +\f} It was shown \cgalCite{Sorkine2009LeastSquaresRigid} that minimizing the energy contribution of \f$\mathbf{v}_i\f$ in Eq. \f$\eqref{eq:arap_energy}\f$ is equivalent to maximizing the trace of the matrix @@ -404,13 +394,11 @@ In the second step, the rotation matrices are substituted into the partial deriv with respect to \f$\mathbf{v}'_i\f$. Assuming the weights are symmetric, setting the derivative to zero results in the following equation: -\f[ -\begin{equation} +\f{equation}{ \sum_{\mathbf{v}_j \in N(\mathbf{v}_i)} w_{ij}(\mathbf{v}'_i - \mathbf{v}'_j) = \sum_{\mathbf{v}_j \in N(\mathbf{v}_i)} w_{ij} \frac{(\mathbf{R}_i + \mathbf{R}_j)}{2} (\mathbf{v}_i - \mathbf{v}_j). \label{eq:lap_ber} -\end{equation} -\f] +\f} The left-hand side of this equation corresponds to the one of Eq.\f$\eqref{eq:lap_open}\f$, and we can set \f$\Delta\f$ to be the right-hand side. @@ -428,13 +416,11 @@ The original algorithm \cgalCite{Sorkine2007AsRigidAs} we described assumes that - the weight between two vertices is symmetric. In order to support asymmetric weights in our implementation, we slightly change Eq. \f$\eqref{eq:lap_ber}\f$ to: -\f[ -\begin{equation} +\f{equation}{ \sum_{\mathbf{v}_j \in N(\mathbf{v}_i)} (w_{ij} + w_{ji})(\mathbf{v}'_i - \mathbf{v}'_j) = \sum_{\mathbf{v}_j \in N(\mathbf{v}_i)} (w_{ij}\mathbf{R}_i + w_{ji}\mathbf{R}_j)(\mathbf{v}_i - \mathbf{v}_j). \label{eq:lap_ber_asym} -\end{equation} -\f] +\f} - The energy contribution of each vertex is positive. If the weight between two vertices is always positive, this is always the case. However, when using the cotangent weighting scheme (the default in our implementation), if the sum of the angles opposite to an edge is greater than \f$ \pi \f$, @@ -448,14 +434,12 @@ A method minimizing another energy function is described next to avoid the latte The elastic energy function proposed by \cgalCite{Chao2010SimpleGeomModel} additionally takes into account all the opposite edges in the facets incident to a vertex. The energy function to minimize becomes: -\f[ -\begin{equation} +\f{equation}{ \sum_{\mathbf{v}_i \in M} \sum_{(\mathbf{v}_j, \mathbf{v}_k) \in E(\mathbf{v}_i)} w_{jk} \left\| (\mathbf{v}'_j - \mathbf{v}'_k) - \mathbf{R}_i(\mathbf{v}_j - \mathbf{v}_k) \right\|^2, \label{eq:arap_energy_rims} -\end{equation} -\f] +\f} where \f$E(\mathbf{v}_i)\f$ consists of the set of edges incident to \f$\mathbf{v}_i\f$ (the spokes) and the set of edges in the link (the rims) of \f$\mathbf{v}_i\f$ in the surface mesh \f$M\f$ @@ -470,23 +454,19 @@ The method to get the new positions of the unconstrained vertices is similar to method explained in \ref SMD_Overview_ARAP. For the first step, the Eq. \f$\eqref{eq:cov_matrix}\f$ is modified to take into account the edges in \f$E(\mathbf{v}_i)\f$: -\f[ -\begin{equation} +\f{equation}{ \mathbf{S}_i = \sum_{(\mathbf{v}_j, \mathbf{v}_k) \in E(\mathbf{v}_i)} w_{jk} (\mathbf{v}_j - \mathbf{v}_k)(\mathbf{v}'_j - \mathbf{v}'_k)^T, \label{eq:cov_matrix_sr} -\end{equation} -\f] +\f} For the second step, setting partial derivative of Eq. \f$\eqref{eq:arap_energy_rims}\f$ to zero with respect to \f$\mathbf{v}_i\f$ gives the following equation: -\f[ -\begin{equation} +\f{equation}{ \sum_{\mathbf{v}_j \in N(\mathbf{v}_i)} (w_{ij} + w_{ji})(\mathbf{v}'_i - \mathbf{v}'_j) = \sum_{\mathbf{v}_j \in N(\mathbf{v}_i)} \frac{w_{ij}(\mathbf{R}_i + \mathbf{R}_j + \mathbf{R}_m) + w_{ji}(\mathbf{R}_i + \mathbf{R}_j + \mathbf{R}_n)}{3} (\mathbf{v}_i - \mathbf{v}_j). \label{eq:lap_ber_rims} -\end{equation} -\f] +\f} where \f$\mathbf{R}_m\f$ and \f$\mathbf{R}_n\f$ are the rotation matrices of the vertices \f$\mathbf{v}_m\f$, \f$\mathbf{v}_n\f$ which are the opposite vertices of the edge \f$\mathbf{v}_i \mathbf{v}_j\f$ @@ -504,14 +484,12 @@ The implementation in this package uses the cotangent weights by default (negati \subsection SMD_Overview_SRE_ARAP Smoothed Rotation Enhanced As-Rigid-As Possible (SR_ARAP) Deformation Using 1-ring elements, SR-ARAP adds a bending element to Eq. \f$\eqref{eq:arap_energy}\f$: -\f[ -\begin{equation} +\f{equation}{ \sum_{\mathbf{v}_i \in M} \sum_{\mathbf{v}_j \in N(\mathbf{v}_i)} w_{ij} \left\| (\mathbf{v}'_i - \mathbf{v}'_j) - \mathbf{R}_i(\mathbf{v}_i - \mathbf{v}_j) \right\|^2 + \alpha A \left\| \mathbf{R}_i - \mathbf{R}_j \right\|^2_F \label{eq:sre_arap_energy} -\end{equation} -\f] +\f} where - \f$\alpha=0.02\f$ is a weighting coefficient. diff --git a/Surface_mesh_parameterization/test/Surface_mesh_parameterization/CMakeLists.txt b/Surface_mesh_parameterization/test/Surface_mesh_parameterization/CMakeLists.txt index 9455b197844..e325bf4aafa 100644 --- a/Surface_mesh_parameterization/test/Surface_mesh_parameterization/CMakeLists.txt +++ b/Surface_mesh_parameterization/test/Surface_mesh_parameterization/CMakeLists.txt @@ -14,24 +14,7 @@ find_package(CGAL QUIET) if ( CGAL_FOUND ) - # VisualC++ optimization for applications dealing with large data - if (MSVC) - # Allow Windows applications to use up to 3GB of RAM - SET (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /LARGEADDRESSAWARE") - - # Turn off stupid VC++ warnings - SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4267 /wd4311 /wd4800 /wd4503 /wd4244 /wd4345 /wd4996 /wd4396 /wd4018") - - # Print new compilation options - message( STATUS "USING DEBUG CXXFLAGS = '${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_DEBUG}'" ) - message( STATUS "USING DEBUG EXEFLAGS = '${CMAKE_EXE_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS_DEBUG}'" ) - message( STATUS "USING RELEASE CXXFLAGS = '${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE}'" ) - message( STATUS "USING RELEASE EXEFLAGS = '${CMAKE_EXE_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS_RELEASE}'" ) - endif(MSVC) - - - #find Eigen find_package(Eigen3 3.1.0) #(requires 3.1.0 or greater) if(EIGEN3_FOUND) include( ${EIGEN3_USE_FILE} ) diff --git a/Surface_mesh_shortest_path/doc/Surface_mesh_shortest_path/PackageDescription.txt b/Surface_mesh_shortest_path/doc/Surface_mesh_shortest_path/PackageDescription.txt index 97fe67ef39b..d174e2cc7d5 100644 --- a/Surface_mesh_shortest_path/doc/Surface_mesh_shortest_path/PackageDescription.txt +++ b/Surface_mesh_shortest_path/doc/Surface_mesh_shortest_path/PackageDescription.txt @@ -1,5 +1,3 @@ -// Triangulated Surface Mesh Geodesic Shortest Paths - /// \defgroup PkgSurfaceMeshShortestPathRef Triangulated Surface Mesh Geodesic Shortest Paths Reference /// \defgroup PkgSurfaceMeshShortestPathConcepts Concepts diff --git a/Surface_mesh_skeletonization/include/CGAL/Mean_curvature_flow_skeletonization.h b/Surface_mesh_skeletonization/include/CGAL/Mean_curvature_flow_skeletonization.h index cc403bb788a..ba18f094c0b 100644 --- a/Surface_mesh_skeletonization/include/CGAL/Mean_curvature_flow_skeletonization.h +++ b/Surface_mesh_skeletonization/include/CGAL/Mean_curvature_flow_skeletonization.h @@ -93,8 +93,8 @@ template < class Refs, class Point, class ID, class vertex_descriptor> struct Skel_HDS_vertex_type : public HalfedgeDS_vertex_max_base_with_id { typedef HalfedgeDS_vertex_max_base_with_id Base; - Skel_HDS_vertex_type() : Base (), is_fixed(false) {} - Skel_HDS_vertex_type( Point const& p) : Base(p), is_fixed(false) {} + Skel_HDS_vertex_type() : Base (), pole(ORIGIN), is_fixed(false) {} + Skel_HDS_vertex_type( Point const& p) : Base(p), pole(ORIGIN), is_fixed(false) {} std::vector vertices; Point pole; bool is_fixed; diff --git a/Surface_mesher/demo/Surface_mesher/CMakeLists.txt b/Surface_mesher/demo/Surface_mesher/CMakeLists.txt index 6644c8d37ff..3bc6c16965c 100644 --- a/Surface_mesher/demo/Surface_mesher/CMakeLists.txt +++ b/Surface_mesher/demo/Surface_mesher/CMakeLists.txt @@ -21,6 +21,10 @@ if(POLICY CMP0072) cmake_policy(SET CMP0072 NEW) endif() +if(POLICY CMP0074) + cmake_policy(SET CMP0074 NEW) +endif() + set(PACKAGE_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../..) # Add several CGAL packages to the include and link paths, diff --git a/Surface_mesher/examples/Surface_mesher/CMakeLists.txt b/Surface_mesher/examples/Surface_mesher/CMakeLists.txt index 589ad5d54c7..3446a487e88 100644 --- a/Surface_mesher/examples/Surface_mesher/CMakeLists.txt +++ b/Surface_mesher/examples/Surface_mesher/CMakeLists.txt @@ -5,6 +5,10 @@ project( Surface_mesher_Examples ) cmake_minimum_required(VERSION 3.1) +if(POLICY CMP0074) + cmake_policy(SET CMP0074 NEW) +endif() + find_package(CGAL QUIET COMPONENTS ImageIO) if ( CGAL_FOUND AND CGAL_ImageIO_FOUND ) diff --git a/TDS_3/include/CGAL/Triangulation_data_structure_3.h b/TDS_3/include/CGAL/Triangulation_data_structure_3.h index f248dd783f3..ff1fce1d78e 100644 --- a/TDS_3/include/CGAL/Triangulation_data_structure_3.h +++ b/TDS_3/include/CGAL/Triangulation_data_structure_3.h @@ -78,9 +78,13 @@ class Triangulation_data_structure_3 typedef Triangulation_data_structure_3 Tds; public: - typedef Concurrency_tag_ Concurrency_tag; + // This tag is used in the parallel operations of RT_3 to access some functions + // of the TDS (tds.vertices().is_used(Vertex_handle)) that are much more efficient + // than what is exposed by the TDS concept (tds.is_vertex(Vertex_handle)). + typedef CGAL::Tag_true Is_CGAL_TDS_3; + // Tools to change the Vertex and Cell types of the TDS. template < typename Vb2 > struct Rebind_vertex { diff --git a/Three/demo/Three/CMakeLists.txt b/Three/demo/Three/CMakeLists.txt index e118f6b919f..b8a2631a535 100644 --- a/Three/demo/Three/CMakeLists.txt +++ b/Three/demo/Three/CMakeLists.txt @@ -11,9 +11,7 @@ set(CMAKE_CXX_STANDARD 14) find_package(CGAL QUIET COMPONENTS Core ) if ( CGAL_FOUND ) - include(${CGAL_USE_FILE}) - else() message(STATUS "This program requires the CGAL library, and will not be compiled.") diff --git a/Three/doc/Three/PackageDescription.txt b/Three/doc/Three/PackageDescription.txt index 72012cfaaae..4b83fd601ca 100644 --- a/Three/doc/Three/PackageDescription.txt +++ b/Three/doc/Three/PackageDescription.txt @@ -1,4 +1,4 @@ -/// \defgroup PkgThreeRef Three +/// \defgroup PkgThreeRef Three Reference /// /*! \addtogroup PkgThreeRef diff --git a/Three/include/CGAL/Three/Scene_interface.h b/Three/include/CGAL/Three/Scene_interface.h index b6e39f9feb6..71d772a3263 100644 --- a/Three/include/CGAL/Three/Scene_interface.h +++ b/Three/include/CGAL/Three/Scene_interface.h @@ -148,7 +148,17 @@ public: virtual void itemVisibilityChanged(CGAL::Three::Scene_item*) = 0; //! Clears the current selection then sets the selected item to the target index. //! Used to update the selection in the Geometric Objects view. - virtual void setSelectedItem(Item_id) = 0; + virtual void setSelectedItem(Item_id) = 0; + //! \brief ignore data updating. + //! + //! This will ignore all the individual calls to `itemChanged()` until + //! `setUpdatesEnabled()` is called whith `b` being `true`. + //! + virtual void setUpdatesEnabled(bool b) =0; + //! + //! \brief Updates all the items in the SceneView. + //! + virtual void allItemsChanged() = 0; }; // end interface Scene_interface } } diff --git a/Three/include/CGAL/Three/Scene_item.h b/Three/include/CGAL/Three/Scene_item.h index 4d5539a35f3..6d72d641f2b 100644 --- a/Three/include/CGAL/Three/Scene_item.h +++ b/Three/include/CGAL/Three/Scene_item.h @@ -316,7 +316,7 @@ public Q_SLOTS: virtual void setColor(QColor c) { color_ = c;} //!Setter for the RGB color of the item. Calls setColor(QColor). //!@see setColor(QColor c) - void setRbgColor(int r, int g, int b) { setColor(QColor(r, g, b)); } + void setRgbColor(int r, int g, int b) { setColor(QColor(r, g, b)); } //!Sets the name of the item. virtual void setName(QString n) { name_ = n; } //!Sets the visibility of the item. @@ -325,6 +325,7 @@ public Q_SLOTS: //!This function is called by `Scene::changeGroup` and should not be //!called manually. virtual void moveToGroup(Scene_group_item* group); + void setRenderingMode(int m) { setRenderingMode((RenderingMode)m);} //!Sets the rendering mode of the item. //!@see RenderingMode virtual void setRenderingMode(RenderingMode m) { diff --git a/Triangulation/doc/Triangulation/PackageDescription.txt b/Triangulation/doc/Triangulation/PackageDescription.txt index bc863b04bc8..bee59fb6c26 100644 --- a/Triangulation/doc/Triangulation/PackageDescription.txt +++ b/Triangulation/doc/Triangulation/PackageDescription.txt @@ -1,4 +1,4 @@ -/// \defgroup PkgTriangulationsRef dD Triangulations +/// \defgroup PkgTriangulationsRef dD Triangulations Reference /// \defgroup PkgTriangulationsConcepts Concepts /// \ingroup PkgTriangulationsRef diff --git a/Triangulation/examples/Triangulation/delaunay_triangulation.cpp b/Triangulation/examples/Triangulation/delaunay_triangulation.cpp index 73fafb3d1c7..036c0de6d50 100644 --- a/Triangulation/examples/Triangulation/delaunay_triangulation.cpp +++ b/Triangulation/examples/Triangulation/delaunay_triangulation.cpp @@ -24,7 +24,7 @@ int main() { 100, 100, 100, 100, 100, 100, 100 } }; - typedef CGAL::Triangulation > > T; + typedef CGAL::Delaunay_triangulation > > T; T dt(7); std::vector points; diff --git a/Triangulation_2/examples/Triangulation_2/CMakeLists.txt b/Triangulation_2/examples/Triangulation_2/CMakeLists.txt index b6972c19b0a..20ef6aa9331 100644 --- a/Triangulation_2/examples/Triangulation_2/CMakeLists.txt +++ b/Triangulation_2/examples/Triangulation_2/CMakeLists.txt @@ -11,6 +11,10 @@ if(NOT POLICY CMP0070 AND POLICY CMP0053) cmake_policy(SET CMP0053 OLD) endif() +if(POLICY CMP0071) + cmake_policy(SET CMP0071 NEW) +endif() + find_package(CGAL COMPONENTS Qt5) if(CGAL_Qt5_FOUND) diff --git a/Triangulation_2/include/CGAL/Triangulation_line_face_circulator_2.h b/Triangulation_2/include/CGAL/Triangulation_line_face_circulator_2.h index 12d7220fdbc..2572e4fdbc2 100644 --- a/Triangulation_2/include/CGAL/Triangulation_line_face_circulator_2.h +++ b/Triangulation_2/include/CGAL/Triangulation_line_face_circulator_2.h @@ -266,7 +266,7 @@ Triangulation_line_face_circulator_2(const Point& pp, int in; switch(pqs) { case LEFT_TURN: - *this = Line_face_circulator(); + pos = Face_handle(); return; case COLLINEAR: fn = fc->neighbor(i); @@ -306,7 +306,7 @@ Triangulation_line_face_circulator_2(const Point& pp, // if line (p,q) does not intersect the convex hull in an edge // the circulator has a singular value - *this=Line_face_circulator(); + pos=Face_handle(); return; } @@ -368,7 +368,7 @@ Triangulation_line_face_circulator_2(const Point& pp, return; } else { // singular value - *this = Line_face_circulator(); + pos=Face_handle(); return; } case LEFT_TURN : diff --git a/Triangulation_3/examples/Triangulation_3/CMakeLists.txt b/Triangulation_3/examples/Triangulation_3/CMakeLists.txt index 371b8c62fb2..121d27795ca 100644 --- a/Triangulation_3/examples/Triangulation_3/CMakeLists.txt +++ b/Triangulation_3/examples/Triangulation_3/CMakeLists.txt @@ -7,6 +7,10 @@ if(NOT POLICY CMP0070 AND POLICY CMP0053) cmake_policy(SET CMP0053 OLD) endif() +if(POLICY CMP0071) + cmake_policy(SET CMP0071 NEW) +endif() + find_package(CGAL COMPONENTS Qt5) if(CGAL_Qt5_FOUND) diff --git a/Triangulation_3/include/CGAL/Regular_triangulation_3.h b/Triangulation_3/include/CGAL/Regular_triangulation_3.h index 5170956468e..22095049387 100644 --- a/Triangulation_3/include/CGAL/Regular_triangulation_3.h +++ b/Triangulation_3/include/CGAL/Regular_triangulation_3.h @@ -776,6 +776,38 @@ public: return std::copy(vertices.begin(), vertices.end(), res); } + // In parallel operations, we need to be able to check the health of the 'hint' vertex handle, + // which might be invalided by other threads. One way to do that is the 'is_vertex()' function + // of the TDS, but it runs in O(sqrt(n)) complexity. When we are using our TDS, we can use + // a lower level function from the compact container, which runs in constant time. + BOOST_MPL_HAS_XXX_TRAIT_DEF(Is_CGAL_TDS_3) + + template ::value> + struct Is_CGAL_TDS_3 : public CGAL::Tag_false + { }; + + template + struct Is_CGAL_TDS_3 : public CGAL::Boolean_tag + { }; + + template ::value> + struct Vertex_validity_checker + { + bool operator()(const typename TDS_::Vertex_handle vh_, const TDS_& tds_) { + return tds_.is_vertex(vh_); + } + }; + + template + struct Vertex_validity_checker + { + bool operator()(const typename TDS_::Vertex_handle vh_, const TDS_& tds_) { + return tds_.vertices().is_used(vh_); + } + }; + void remove(Vertex_handle v); // Concurrency-safe // See Triangulation_3::remove for more information @@ -1359,14 +1391,40 @@ protected: #endif Vertex_handle& hint = m_tls_hint.local(); + Vertex_validity_checker vertex_validity_check; + for(size_t i_point = r.begin() ; i_point != r.end() ; ++i_point) { bool success = false; const Weighted_point& p = m_points[i_point]; while(!success) { - if(m_rt.try_lock_vertex(hint) && m_rt.try_lock_point(p)) + // The 'hint' is unsafe to use immediately because we are in a regular triangulation, + // and the insertion of a (weighted) point in another thread might have hidden (deleted) + // the hint. + if(!vertex_validity_check(hint, m_rt.tds())) { + hint = m_rt.finite_vertices_begin(); + continue; + } + + // We need to make sure that while are locking the position P1 := hint->point(), 'hint' + // does not get its position changed to P2 != P1. + const Weighted_point hint_point_mem = hint->point(); + + if(m_rt.try_lock_point(hint_point_mem) && m_rt.try_lock_point(p)) + { + // Make sure that the hint is still valid (so that we can safely take hint->cell()) and + // that its position hasn't changed to ensure that we will start the locate from where + // we have locked. + if(!vertex_validity_check(hint, m_rt.tds()) || + hint->point() != hint_point_mem) + { + hint = m_rt.finite_vertices_begin(); + m_rt.unlock_all_elements(); + continue; + } + bool could_lock_zone; Locate_type lt; int li, lj; @@ -1445,6 +1503,8 @@ protected: #endif Vertex_handle& hint = m_tls_hint.local(); + Vertex_validity_checker vertex_validity_check; + for(size_t i_idx = r.begin() ; i_idx != r.end() ; ++i_idx) { bool success = false; @@ -1452,14 +1512,37 @@ protected: const Weighted_point& p = m_points[i_point]; while(!success) { - if(m_rt.try_lock_vertex(hint) && m_rt.try_lock_point(p)) + // The 'hint' is unsafe to use immediately because we are in a regular triangulation, + // and the insertion of a (weighted) point in another thread might have hidden (deleted) + // the hint. + if(!vertex_validity_check(hint, m_rt.tds())) { + hint = m_rt.finite_vertices_begin(); + continue; + } + + // We need to make sure that while are locking the position P1 := hint->point(), 'hint' + // does not get its position changed to P2 != P1. + const Weighted_point hint_point_mem = hint->point(); + + if(m_rt.try_lock_point(hint_point_mem) && m_rt.try_lock_point(p)) + { + // Make sure that the hint is still valid (so that we can safely take hint->cell()) and + // that its position hasn't changed to ensure that we will start the locate from where + // we have locked. + if(!vertex_validity_check(hint, m_rt.tds()) || + hint->point() != hint_point_mem) + { + hint = m_rt.finite_vertices_begin(); + m_rt.unlock_all_elements(); + continue; + } + bool could_lock_zone; Locate_type lt; int li, lj; - Cell_handle c = m_rt.locate(p, lt, li, lj, hint->cell(), - &could_lock_zone); + Cell_handle c = m_rt.locate(p, lt, li, lj, hint->cell(), &could_lock_zone); Vertex_handle v; if(could_lock_zone) v = m_rt.insert(p, lt, c, li, lj, &could_lock_zone); @@ -2461,8 +2544,13 @@ remove(Vertex_handle v, bool *could_lock_zone) } else { - Vertex_handle hint = (v->cell()->vertex(0) == v ? - v->cell()->vertex(1) : v->cell()->vertex(0)); + Vertex_validity_checker vertex_validity_check; + + // Check that the vertex hasn't be deleted from the TDS while we were locking it + if(!vertex_validity_check(v, tds())) + return true; // vertex is already gone from the TDS, nothing to do + + Vertex_handle hint = v->cell()->vertex(0) == v ? v->cell()->vertex(1) : v->cell()->vertex(0); Self tmp; Vertex_remover remover(tmp); @@ -2470,21 +2558,62 @@ remove(Vertex_handle v, bool *could_lock_zone) if(*could_lock_zone && removed) { - // Re-insert the points that v was hiding. - for(typename Vertex_remover::Hidden_points_iterator - hi = remover.hidden_points_begin(); - hi != remover.hidden_points_end(); ++hi) - { - bool could_lock_zone = false; - Vertex_handle hv; - while(!could_lock_zone) - { - hv = insert(*hi, hint, &could_lock_zone); - } + // The vertex has been removed, re-insert the points that 'v' was hiding - if(hv != Vertex_handle()) - hint = hv; + // Start by unlocking the area of the removed vertex to avoid deadlocks + this->unlock_all_elements(); + + for(typename Vertex_remover::Hidden_points_iterator + hi = remover.hidden_points_begin(); + hi != remover.hidden_points_end(); ++hi) + { + const Weighted_point& wp = *hi; + + // try to lock the positions of the hint and the hidden point + bool success = false; + while(!success) + { + // The 'hint' is unsafe to use immediately because we are in a regular triangulation, + // and the insertion of a (weighted) point in another thread might have hidden (deleted) + // the hint. + if(!vertex_validity_check(hint, tds())) + { + hint = finite_vertices_begin(); + continue; + } + + // We need to make sure that while are locking the position P1 := hint->point(), 'hint' + // does not get its position changed to P2 != P1. + const Weighted_point hint_point_mem = hint->point(); + + if(this->try_lock_point(hint_point_mem) && this->try_lock_point(wp)) + { + // Make sure that the hint is still valid (so that we can safely take hint->cell()) and + // that its position hasn't changed to ensure that we will start the locate from where + // we have locked. + if(!vertex_validity_check(hint, tds()) || + hint->point() != hint_point_mem) + { + hint = finite_vertices_begin(); + this->unlock_all_elements(); + continue; + } + + Vertex_handle hv = insert(wp, hint, could_lock_zone); + + if(*could_lock_zone) + { + success = true; + if(hv != Vertex_handle()) + hint = hv; + } + } + + // This unlocks everything in all cases: partial lock failure, failed insertion, successful insertion + this->unlock_all_elements(); + } } + CGAL_triangulation_expensive_postcondition(is_valid()); } } diff --git a/Triangulation_3/test/Triangulation_3/include/CGAL/_test_cls_parallel_triangulation_3.h b/Triangulation_3/test/Triangulation_3/include/CGAL/_test_cls_parallel_triangulation_3.h index 59abb7b6da2..facbd70f2d7 100644 --- a/Triangulation_3/test/Triangulation_3/include/CGAL/_test_cls_parallel_triangulation_3.h +++ b/Triangulation_3/test/Triangulation_3/include/CGAL/_test_cls_parallel_triangulation_3.h @@ -27,42 +27,82 @@ #include +template +struct PTR_random_pts_generator +{ + typedef typename Parallel_triangulation::Point Point; + + void operator()(const int num, CGAL::Random& rnd, std::vector& points) const + { + CGAL::Random_points_in_cube_3 gen(1., rnd); + + points.reserve(num); + for(int i=0; i!=num; ++i) + points.push_back(*gen++); + } +}; + +template +struct PTR_random_pts_generator +{ + typedef typename Parallel_triangulation::Bare_point Bare_point; + typedef typename Parallel_triangulation::Weighted_point Weighted_point; + + void operator()(const int num, CGAL::Random& rnd, std::vector& points) const + { + CGAL::Random_points_in_cube_3 gen(1., rnd); + + points.reserve(num); + for(int i=0; i!=num; ++i) + points.push_back(Weighted_point(*gen++, rnd.get_double(-1., 1.))); + } +}; + template void _test_cls_parallel_triangulation_3(const Parallel_triangulation &) { - const int NUM_INSERTED_POINTS = 5000; - typedef Parallel_triangulation Cls; typedef typename Cls::Vertex_handle Vertex_handle; typedef typename Cls::Point Point; - CGAL::Random_points_in_cube_3 rnd(1.); + typedef std::vector Point_container; + + CGAL::Random rnd; + std::cout << "Seed: " << rnd.get_seed() << std::endl; + + const int num_insert = 5000; + Point_container points; + PTR_random_pts_generator points_gen; + points_gen(num_insert, rnd, points); - // Construction from a vector of points - std::vector points; - points.reserve(NUM_INSERTED_POINTS); - for (int i = 0; i != NUM_INSERTED_POINTS; ++i) - points.push_back(*rnd++); - // Construct the locking data-structure, using the bounding-box of the points - typename Cls::Lock_data_structure locking_ds( - CGAL::Bbox_3(-1., -1., -1., 1., 1., 1.), 50); + typename Cls::Lock_data_structure locking_ds(CGAL::Bbox_3(-1., -1., -1., 1., 1., 1.), 50); + // Contruct the triangulation in parallel std::cout << "Construction and parallel insertion" << std::endl; Cls tr(points.begin(), points.end(), &locking_ds); + std::cout << "Triangulation has " << tr.number_of_vertices() << " vertices" << std::endl; + assert(tr.is_valid()); std::cout << "Parallel removal" << std::endl; - // Remove the first 100,000 vertices std::vector vertices_to_remove; typename Cls::Finite_vertices_iterator vit = tr.finite_vertices_begin(); - for (int i = 0 ; i < NUM_INSERTED_POINTS/10 ; ++i) + + const std::size_t num_remove = tr.number_of_vertices() / 10; + std::cout << "Removing " << num_remove << " from " << tr.number_of_vertices() << " vertices" << std::endl; + + for(std::size_t i=0 ; i Tds_parallel; typedef CGAL::Regular_triangulation_3< traits, Tds_parallel, Lock_ds> RT_parallel; - // The following test won't do things in parallel since it doesn't provide - // a lock data structure + + // The following test won't do things in parallel since it doesn't provide a lock data structure test_RT(); + // This test performs parallel operations _test_cls_parallel_triangulation_3( RT_parallel() ); #endif diff --git a/Visibility_2/doc/Visibility_2/visibility_2.txt b/Visibility_2/doc/Visibility_2/visibility_2.txt index 34fa2d8674e..c72f5d03f29 100644 --- a/Visibility_2/doc/Visibility_2/visibility_2.txt +++ b/Visibility_2/doc/Visibility_2/visibility_2.txt @@ -129,7 +129,6 @@ does not require preprocessing is advantageous. The following example shows how to obtain the regularized and non-regularized visibility regions. \cgalFigureBegin{simple_example, simple_example.png} - The visibility region of \f$ q \f$ in a simple polygon: (1) non-regularized visibility; and (2) regularized visibility. \cgalFigureEnd \cgalExample{Visibility_2/simple_polygon_visibility_2.cpp}