diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h index de0f3d73ec1..8f0c7d85544 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -148,7 +148,7 @@ namespace CGAL { if(first_vertex != S.triangulation_3().finite_vertices_end()) { pos = first_vertex; pos->set_post_mark(mark); - assert(pos->is_on_border()); + CGAL_assertion(pos->is_on_border()); } else { pos = NULL; @@ -469,7 +469,7 @@ namespace CGAL { inline void set_interior_edge(Vertex_handle w, Vertex_handle v) { if(w->m_ie_last == ie_sentinel){ // empty set - assert(w->m_ie_first == w->m_ie_last); + CGAL_assertion(w->m_ie_first == w->m_ie_last); w->m_ie_last = interior_edges.insert(w->m_ie_last, v); w->m_ie_first = w->m_ie_last; } else { @@ -477,7 +477,7 @@ namespace CGAL { e++; #ifdef DEBUG typename std::list::iterator r = std::find(w->m_ie_first, e, v); - assert(r == e); + CGAL_assertion(r == e); #endif w->m_ie_last = interior_edges.insert(e, v); } @@ -487,7 +487,7 @@ namespace CGAL { inline void remove_interior_edge(Vertex_handle w, Vertex_handle v) { if(w->m_ie_first == ie_sentinel){ - assert(w->m_ie_last == w->m_ie_first); + CGAL_assertion(w->m_ie_last == w->m_ie_first); } else if(w->m_ie_first == w->m_ie_last){ // there is only one element if(*(w->m_ie_first) == v){ interior_edges.erase(w->m_ie_first); @@ -516,7 +516,7 @@ namespace CGAL { inline void set_incidence_request(Vertex_handle w, const Incidence_request_elt& ir) { if(w->m_ir_last == sentinel ){ - assert(w->m_ir_first == w->m_ir_last); + CGAL_assertion(w->m_ir_first == w->m_ir_last); w->m_ir_last = incidence_requests.insert(w->m_ir_last, ir); w->m_ir_first = w->m_ir_last; } else { @@ -529,7 +529,7 @@ namespace CGAL { inline bool is_incidence_requested(Vertex_handle w) const { if(w->m_ir_last == sentinel ){ - assert(w->m_ir_first == sentinel ); + CGAL_assertion(w->m_ir_first == sentinel ); } return (w->m_ir_last != sentinel ); } @@ -542,7 +542,7 @@ namespace CGAL { inline Incidence_request_iterator incidence_request_end(Vertex_handle w) { if(w->m_ir_last != sentinel ){ - assert(w->m_ir_first != sentinel ); + CGAL_assertion(w->m_ir_first != sentinel ); Incidence_request_iterator it(w->m_ir_last); it++; return it; @@ -553,7 +553,7 @@ namespace CGAL { inline void erase_incidence_request(Vertex_handle w) { if(w->m_ir_last != sentinel ){ - assert(w->m_ir_first != sentinel ); + CGAL_assertion(w->m_ir_first != sentinel ); w->m_ir_last++; incidence_requests.erase(w->m_ir_first, w->m_ir_last); w->m_ir_first = sentinel ; @@ -570,7 +570,7 @@ namespace CGAL { } if(w->m_ir_first != sentinel ){ - assert(w->m_ir_last != sentinel ); + CGAL_assertion(w->m_ir_last != sentinel ); typename std::list< Incidence_request_elt >::iterator b(w->m_ir_first), e(w->m_ir_last); e++; incidence_requests.erase(b, e); @@ -627,14 +627,14 @@ namespace CGAL { w->delete_border(); } if(w->m_ir_first != sentinel ){ - assert(w->m_ir_last != sentinel ); + CGAL_assertion(w->m_ir_last != sentinel ); typename std::list< Incidence_request_elt >::iterator b(w->m_ir_first), e(w->m_ir_last); e++; incidence_requests.erase(b, e); } if(w->m_ie_first != ie_sentinel){ - assert(w->m_ie_last != ie_sentinel); + CGAL_assertion(w->m_ie_last != ie_sentinel); typename std::list::iterator b(w->m_ie_first), e(w->m_ie_last); e++; interior_edges.erase(b, e); @@ -746,7 +746,7 @@ namespace CGAL { void run(double radius_ratio_bound=5, double beta= 0.52) { K = radius_ratio_bound; - COS_BETA = acos(beta); + COS_BETA = cos(beta); if(T.dimension() < 3){ return; } @@ -2186,7 +2186,7 @@ namespace CGAL { { _facet_number--; - assert(c->is_selected_facet(index)); + CGAL_assertion(c->is_selected_facet(index)); unselect_facet(c, index); Facet f32 = diff --git a/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/construct_surface_2.h b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/construct_surface_2.h index 47d9f179d25..4eef347b979 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/construct_surface_2.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/construct_surface_2.h @@ -134,7 +134,7 @@ namespace CGAL { tds.set_adjacency(fn, 2, inf_edge_map); edge_map.erase(edge_map.begin()); } - CGAL_triangulation_assertion(inf_edge_map.empty()); + CGAL_assertion(inf_edge_map.empty()); } tds.reorient_faces(); return vinf; diff --git a/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/orient.h b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/orient.h index f38b0ad9d58..09a0a0a6e75 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/orient.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/orient.h @@ -122,7 +122,7 @@ namespace CGAL { tds.set_adjacency(fn, 2, inf_edge_map); edge_map.erase(edge_map.begin()); } - CGAL_triangulation_assertion(inf_edge_map.empty()); + CGAL_assertion(inf_edge_map.empty()); } diff --git a/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Curve_analysis_2.h b/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Curve_analysis_2.h index 945b743c907..c38eedf4317 100644 --- a/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Curve_analysis_2.h +++ b/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Curve_analysis_2.h @@ -35,6 +35,7 @@ #include +#include #include #include #include @@ -904,7 +905,7 @@ private: break; } default:{ - assert(false); // !!! Never reached + CGAL_assertion(false); // !!! Never reached } } } diff --git a/Alpha_shapes_2/include/CGAL/internal/Lazy_alpha_nt_2.h b/Alpha_shapes_2/include/CGAL/internal/Lazy_alpha_nt_2.h index 07504bb2a2e..b5a71ff0f35 100644 --- a/Alpha_shapes_2/include/CGAL/internal/Lazy_alpha_nt_2.h +++ b/Alpha_shapes_2/include/CGAL/internal/Lazy_alpha_nt_2.h @@ -20,7 +20,7 @@ #ifndef CGAL_INTERNAL_LAZY_ALPHA_NT_2_H #define CGAL_INTERNAL_LAZY_ALPHA_NT_2_H - +#include #include #include #include @@ -139,7 +139,7 @@ public: exact_ = Exact_squared_radius()( to_exact(*data()[0]),to_exact(*data()[1]),to_exact(*data()[2]) ); break; default: - assert(false); + CGAL_assertion(false); } updated=true; } @@ -156,7 +156,7 @@ public: approx_ = Approx_squared_radius()( to_approx(*data()[0]),to_approx(*data()[1]),to_approx(*data()[2]) ); break; default: - assert(false); + CGAL_assertion(false); } } diff --git a/Alpha_shapes_3/include/CGAL/internal/Lazy_alpha_nt_3.h b/Alpha_shapes_3/include/CGAL/internal/Lazy_alpha_nt_3.h index 7ded7ec6ef0..6d4c7f20fe3 100644 --- a/Alpha_shapes_3/include/CGAL/internal/Lazy_alpha_nt_3.h +++ b/Alpha_shapes_3/include/CGAL/internal/Lazy_alpha_nt_3.h @@ -21,6 +21,7 @@ #ifndef CGAL_INTERNAL_LAZY_ALPHA_NT_3_H #define CGAL_INTERNAL_LAZY_ALPHA_NT_3_H +#include #include #include #include @@ -140,7 +141,7 @@ public: exact_ = Exact_squared_radius()( to_exact(*data()[0]),to_exact(*data()[1]),to_exact(*data()[2]),to_exact(*data()[3]) ); break; default: - assert(false); + CGAL_assertion(false); } updated=true; } @@ -160,7 +161,7 @@ public: approx_ = Approx_squared_radius()( to_approx(*data()[0]),to_approx(*data()[1]),to_approx(*data()[2]),to_approx(*data()[3]) ); break; default: - assert(false); + CGAL_assertion(false); } } diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_extended_rational_arc_traits_d_1.h b/Arrangement_on_surface_2/include/CGAL/Arr_extended_rational_arc_traits_d_1.h index 4aff08c6fd9..f2230546e63 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_extended_rational_arc_traits_d_1.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_extended_rational_arc_traits_d_1.h @@ -553,13 +553,13 @@ public: Comparison_result operator() (const Vertical_segment & cv1, const Non_vertical_x_curve_2 & cv2) const { - assert(false); + CGAL_assertion(false); return CGAL::SMALLER; } Comparison_result operator() (const Non_vertical_x_curve_2& cv1, const Vertical_segment & cv2) const { - assert(false); + CGAL_assertion(false); return CGAL::LARGER; } Comparison_result operator() (const Vertical_segment & cv1, diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_rat_arc/Rational_function_canonicalized_pair.h b/Arrangement_on_surface_2/include/CGAL/Arr_rat_arc/Rational_function_canonicalized_pair.h index 713eb92c318..e3dec644b78 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_rat_arc/Rational_function_canonicalized_pair.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_rat_arc/Rational_function_canonicalized_pair.h @@ -24,6 +24,7 @@ #include #include #include +#include namespace CGAL { namespace Arr_rational_arc { @@ -69,7 +70,7 @@ public: #if 1 solve_1(_resultant,std::back_inserter(rm_vec)); #else - assert(false); + CGAL_assertion(false); // don't use this code yet since g and resultant/g may still have a // common root if( CGAL::internal::may_have_common_factor(_f.denom(),_g.denom())){ diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_rat_arc/Singleton.h b/Arrangement_on_surface_2/include/CGAL/Arr_rat_arc/Singleton.h index 3f4148968b7..3d41d72d426 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_rat_arc/Singleton.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_rat_arc/Singleton.h @@ -20,9 +20,11 @@ -#ifndef SINGLETON_H_ +#ifndef CGAL_SINGLETON_H_ #define SINGLETON_H_ +#include + namespace CGAL { namespace Arr_rational_arc { template @@ -33,7 +35,7 @@ public: { if(!m_pInstance) m_pInstance = new T; - assert(m_pInstance !=NULL); + CGAL_assertion(m_pInstance !=NULL); return m_pInstance; } @@ -53,4 +55,4 @@ template T* Singleton::m_pInstance=NULL; } // namespace Arr_rational_arc } //namespace CGAL { -#endif // SINGLETON_H_ +#endif // CGAL_SINGLETON_H_ diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_rational_function_traits_2.h b/Arrangement_on_surface_2/include/CGAL/Arr_rational_function_traits_2.h index 7f8a00d56b7..0ffeec96c72 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_rational_function_traits_2.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_rational_function_traits_2.h @@ -21,6 +21,7 @@ #ifndef CGAL_ARR_RATIONAL_ARC_TRAITS_D_1_H #define CGAL_ARR_RATIONAL_ARC_TRAITS_D_1_H +#include #include #include #include @@ -1295,7 +1296,7 @@ public: Approximate_number_type operator()(const Point_2& p, int i){ if(i==0) return approx_x(p); if(i==1) return approx_y(p); - assert(false); + CGAL_assertion(false); return Approximate_number_type(0); } }; diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_unb_planar_topology_traits_2.h b/Arrangement_on_surface_2/include/CGAL/Arr_unb_planar_topology_traits_2.h index 7432611cb9d..71feb804a6f 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_unb_planar_topology_traits_2.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_unb_planar_topology_traits_2.h @@ -34,6 +34,7 @@ #include #include #include +#include namespace CGAL { @@ -507,7 +508,7 @@ public: */ const Face* reference_face() const { - assert(v_tr->halfedge()->direction() == ARR_LEFT_TO_RIGHT); + CGAL_assertion(v_tr->halfedge()->direction() == ARR_LEFT_TO_RIGHT); return v_tr->halfedge()->outer_ccb()->face(); } @@ -519,7 +520,7 @@ public: */ Face* reference_face() { - assert(v_tr->halfedge()->direction() == ARR_LEFT_TO_RIGHT); + CGAL_assertion(v_tr->halfedge()->direction() == ARR_LEFT_TO_RIGHT); return v_tr->halfedge()->outer_ccb()->face(); } diff --git a/BGL/doc/BGL/PackageDescription.txt b/BGL/doc/BGL/PackageDescription.txt index 84fb0f5d505..c67b7135796 100644 --- a/BGL/doc/BGL/PackageDescription.txt +++ b/BGL/doc/BGL/PackageDescription.txt @@ -131,12 +131,14 @@ user might encounter. - `CGAL::is_bivalent_mesh()` - `CGAL::is_trivalent()` - `CGAL::is_trivalent_mesh()` +- `CGAL::is_isolated_triangle()` - `CGAL::is_closed()` - `CGAL::is_triangle()` - `CGAL::is_triangle_mesh()` - `CGAL::is_quad()` - `CGAL::is_quad_mesh()` +- `CGAL::is_isolated_quad()` - `CGAL::is_tetrahedron()` - `CGAL::is_hexahedron()` @@ -150,10 +152,16 @@ user might encounter. - `CGAL::Halfedge_around_target_iterator` - `CGAL::Halfedge_around_face_iterator` - `CGAL::Vertex_around_target_iterator` +- `CGAL::Vertex_around_face_iterator` +- `CGAL::Face_around_face_iterator` - `CGAL::Face_around_target_iterator` -- `CGAL::halfedges_around_source` -- `CGAL::halfedges_around_target` -- `CGAL::halfedges_around_face` +- `CGAL::halfedges_around_source()` +- `CGAL::halfedges_around_target()` +- `CGAL::halfedges_around_face()` +- `CGAL::faces_around_face()` +- `CGAL::faces_around_target()` +- `CGAL::vertices_around_face()` +- `CGAL::vertices_around_target()` ## Circulators ## - `CGAL::Halfedge_around_source_circulator` @@ -161,26 +169,29 @@ user might encounter. - `CGAL::Halfedge_around_face_circulator` - `CGAL::Vertex_around_target_circulator` - `CGAL::Face_around_target_circulator` +- `CGAL::Face_around_face_circulator` ## Euler Operations ## -- `CGAL::Euler::join_vertex()` -- `CGAL::Euler::split_vertex()` -- `CGAL::Euler::split_edge()` -- `CGAL::Euler::join_face()` -- `CGAL::Euler::split_face()` -- `CGAL::Euler::join_loop()` -- `CGAL::Euler::split_loop()` -- `CGAL::Euler::remove_face()` -- `CGAL::Euler::make_hole()` -- `CGAL::Euler::fill_hole()` - `CGAL::Euler::add_center_vertex()` +- `CGAL::Euler::add_edge()` +- `CGAL::Euler::add_face()` +- `CGAL::Euler::add_face_to_border()` +- `CGAL::Euler::add_vertex_and_face_to_border()` +- `CGAL::Euler::collapse_edge()` +- `CGAL::Euler::does_satisfy_link_condition()` +- `CGAL::Euler::fill_hole()` +- `CGAL::Euler::flip_edge()` +- `CGAL::Euler::join_face()` +- `CGAL::Euler::join_loop()` +- `CGAL::Euler::join_vertex()` +- `CGAL::Euler::make_hole()` - `CGAL::Euler::remove_center_vertex()` -- `CGAL::Euler::add_vertex_and_face_to_border()` -- `CGAL::Euler::add_face_to_border()` -- `CGAL::Euler::collapse_edge()` -- `CGAL::Euler::does_satisfy_link_condition()` - +- `CGAL::Euler::remove_face()` +- `CGAL::Euler::split_edge()` +- `CGAL::Euler::split_face()` +- `CGAL::Euler::split_loop()` +- `CGAL::Euler::split_vertex()` */ diff --git a/BGL/examples/BGL_OpenMesh/CMakeLists.txt b/BGL/examples/BGL_OpenMesh/CMakeLists.txt new file mode 100644 index 00000000000..02119ee3340 --- /dev/null +++ b/BGL/examples/BGL_OpenMesh/CMakeLists.txt @@ -0,0 +1,57 @@ +# Created by the script cgal_create_CMakeLists +# This is the CMake script for compiling a set of CGAL applications. + +project( BGL_OpenMesh ) + + +cmake_minimum_required(VERSION 2.8.11) + +# CGAL and its components +find_package( CGAL QUIET COMPONENTS ) + +if ( NOT CGAL_FOUND ) + + message(STATUS "This project requires the CGAL library, and will not be compiled.") + return() + +endif() + +# include helper file +include( ${CGAL_USE_FILE} ) + + +# Boost and its components +find_package( Boost REQUIRED ) + +if ( NOT Boost_FOUND ) + + message(STATUS "This project requires the Boost library, and will not be compiled.") + + return() + +endif() + +find_package( OpenMesh QUIET ) + +if ( OpenMesh_FOUND ) +include( UseOpenMesh ) +else() + message(STATUS "Examples that use OpenMesh will not be compiled.") +endif() + +# include for local directory + +# include for local package +include_directories( BEFORE ../../include ) + + +# Creating entries for all C++ files with "main" routine +# ########################################################## + +include( CGAL_CreateSingleSourceCGALProgram ) + +if(OpenMesh_FOUND) +create_single_source_cgal_program( "TriMesh.cpp" ) + target_link_libraries( TriMesh ${OPENMESH_LIBRARIES} ) +endif() + diff --git a/BGL/examples/BGL_OpenMesh/TriMesh.cpp b/BGL/examples/BGL_OpenMesh/TriMesh.cpp new file mode 100644 index 00000000000..c28e11f7886 --- /dev/null +++ b/BGL/examples/BGL_OpenMesh/TriMesh.cpp @@ -0,0 +1,51 @@ + +#include + +#include +#include + +#include +#include +#include + +#include + +#include + +#include +#include + +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; + +typedef OpenMesh::TriMesh_ArrayKernelT Mesh; + +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef boost::graph_traits::face_descriptor face_descriptor; +typedef boost::graph_traits::halfedge_descriptor halfedge_descriptor; + + +int main(int argc, char** argv ) +{ + Mesh mesh; + + std::vector V; + V.push_back(add_vertex(mesh)); + V.push_back(add_vertex(mesh)); + V.push_back(add_vertex(mesh)); + add_face(V.begin(), V.end(), mesh); + + // OpenMesh::IO::read_mesh(mesh, (argc>1)?argv[1]:"in.off"); + + BOOST_FOREACH(vertex_descriptor vd, vertices(mesh)){ + BOOST_FOREACH(halfedge_descriptor hd, CGAL::halfedges_around_target(vd,mesh)){ + if(! CGAL::is_border(edge(hd,mesh),mesh)){ + CGAL::Euler::flip_edge(hd,mesh); + OpenMesh::IO::write_mesh(mesh, (argc>2)?argv[2]:"out.off"); + return 0; + } + } + } + return 0; +} diff --git a/BGL/examples/BGL_polyhedron_3/CMakeLists.txt b/BGL/examples/BGL_polyhedron_3/CMakeLists.txt new file mode 100644 index 00000000000..a84cf7493c0 --- /dev/null +++ b/BGL/examples/BGL_polyhedron_3/CMakeLists.txt @@ -0,0 +1,73 @@ +# Created by the script cgal_create_CMakeLists +# This is the CMake script for compiling a set of CGAL applications. + +project( BGL_polyhedron_3 ) + + +cmake_minimum_required(VERSION 2.8.11) + +# CGAL and its components +find_package( CGAL QUIET COMPONENTS ) + +if ( NOT CGAL_FOUND ) + + message(STATUS "This project requires the CGAL library, and will not be compiled.") + return() + +endif() + +# include helper file +include( ${CGAL_USE_FILE} ) + + +# Boost and its components +find_package( Boost REQUIRED ) + +if ( NOT Boost_FOUND ) + + message(STATUS "This project requires the Boost library, and will not be compiled.") + + return() + +endif() + +find_package( OpenMesh QUIET ) + +if ( OpenMesh_FOUND ) +include( UseOpenMesh ) +else() + message(STATUS "Examples that use OpenMesh will not be compiled.") +endif() + +# include for local directory + +# include for local package +include_directories( BEFORE ../../include ) + + +# Creating entries for all C++ files with "main" routine +# ########################################################## + +include( CGAL_CreateSingleSourceCGALProgram ) + +create_single_source_cgal_program( "distance.cpp" ) + +create_single_source_cgal_program( "incident_vertices.cpp" ) + +create_single_source_cgal_program( "kruskal.cpp" ) + +create_single_source_cgal_program( "kruskal_with_stored_id.cpp" ) + +create_single_source_cgal_program( "normals.cpp" ) + +create_single_source_cgal_program( "range.cpp" ) + +create_single_source_cgal_program( "transform_iterator.cpp" ) + + + +if(OpenMesh_FOUND) + create_single_source_cgal_program( "polyhedron_2_OpenMesh.cpp" ) + target_link_libraries( polyhedron_2_OpenMesh ${OPENMESH_LIBRARIES} ) +endif() + diff --git a/BGL/examples/BGL_polyhedron_3/polyhedron_2_OpenMesh.cpp b/BGL/examples/BGL_polyhedron_3/polyhedron_2_OpenMesh.cpp new file mode 100644 index 00000000000..6282060f28c --- /dev/null +++ b/BGL/examples/BGL_polyhedron_3/polyhedron_2_OpenMesh.cpp @@ -0,0 +1,87 @@ + +#include + +#include +#include +#include + +#include + +#if 1 +#include +#include +#else +#include +#include +#endif + +#include + +#include + +#include +#include + + +typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; +typedef Kernel::Vector_3 Vector; +typedef Kernel::Point_3 Point; +typedef CGAL::Polyhedron_3 Source; + +#if 1 +typedef OpenMesh::PolyMesh_ArrayKernelT Target; +#else +typedef OpenMesh::TriMesh_ArrayKernelT Target; +#endif +typedef boost::graph_traits::vertex_descriptor sm_vertex_descriptor; +typedef boost::graph_traits::vertex_descriptor tm_vertex_descriptor; + +typedef boost::graph_traits::halfedge_descriptor sm_halfedge_descriptor; +typedef boost::graph_traits::halfedge_descriptor tm_halfedge_descriptor; + +namespace OpenMesh { + +inline std::size_t hash_value(const VertexHandle& i) + { + return i.idx(); + } + +inline std::size_t hash_value(const HalfedgeHandle& i) + { + return i.idx(); + } + +inline std::size_t hash_value(const FaceHandle& i) + { + return i.idx(); + } + +} + +int main(int, char* argv[]) +{ + Source S; + Target T; + std::ifstream in(argv[1]); + in >> S; + + { + boost::unordered_map v2v; + boost::unordered_map h2h; + + convert_surface_mesh(S,T,v2v,h2h); + OpenMesh::IO::write_mesh(T, "om.off"); + } + + { + boost::unordered_map v2v; + boost::unordered_map h2h; + + convert_surface_mesh(T,S,v2v,h2h); + std::ofstream out("reverse.off"); + out << S << std::endl; + } + + + return 0; +} diff --git a/BGL/include/CGAL/boost/graph/Euler_operations.h b/BGL/include/CGAL/boost/graph/Euler_operations.h index 664b6085755..fe39cfd0c0f 100644 --- a/BGL/include/CGAL/boost/graph/Euler_operations.h +++ b/BGL/include/CGAL/boost/graph/Euler_operations.h @@ -1095,7 +1095,7 @@ collapse_edge(typename boost::graph_traits::edge_descriptor v0v1, remove_vertex(p,g); Halfedge_around_target_circulator beg(ppt,g), end(pqb,g); while(beg != end){ - assert(target(*beg,g) == p); + CGAL_assertion(target(*beg,g) == p); set_target(*beg,q,g); --beg; } @@ -1322,7 +1322,7 @@ flip_edge(typename boost::graph_traits::halfedge_descriptor h, vertex_descriptor s2 = target(nh,g), t2 = target(noh,g); face_descriptor fh = face(h,g), foh = face(oh,g); - assert(fh != Traits::null_face() && foh != Traits::null_face()); + CGAL_assertion(fh != Traits::null_face() && foh != Traits::null_face()); if(halfedge(s,g) == oh){ set_halfedge(s,nnh,g); @@ -1455,6 +1455,7 @@ bool } #ifndef CGAL_NO_DEPRECATED_CODE +/// \cond SKIP_IN_MANUAL template bool satisfies_link_condition(typename boost::graph_traits::edge_descriptor e, @@ -1462,6 +1463,7 @@ bool { return does_satisfy_link_condition(e, g); } +/// \endcond #endif /// @} diff --git a/BGL/include/CGAL/boost/graph/convert_surface_mesh.h b/BGL/include/CGAL/boost/graph/convert_surface_mesh.h new file mode 100644 index 00000000000..5751b41cebd --- /dev/null +++ b/BGL/include/CGAL/boost/graph/convert_surface_mesh.h @@ -0,0 +1,64 @@ + + +#ifndef CGAL_BOOST_GRAPH_CONVERT_SURFACE_MESH_H +#define CGAL_BOOST_GRAPH_CONVERT_SURFACE_MESH_H + +#include +#include + + +namespace CGAL { + + template + void convert_surface_mesh(const SourceMesh& sm, TargetMesh& tm, V2V& v2v, H2H& h2h) +{ + typedef boost::graph_traits::vertex_descriptor sm_vertex_descriptor; + typedef boost::graph_traits::vertex_descriptor tm_vertex_descriptor; + + typedef boost::graph_traits::face_descriptor sm_face_descriptor; + typedef boost::graph_traits::face_descriptor tm_face_descriptor; + + typedef boost::graph_traits::halfedge_descriptor sm_halfedge_descriptor; + typedef boost::graph_traits::halfedge_descriptor tm_halfedge_descriptor; + + typedef typename boost::property_map::const_type sm_PMap; + typedef typename boost::property_map::type tm_PMap; + + sm_PMap sm_pmap = get(vertex_point, sm); + tm_PMap tm_pmap = get(vertex_point, tm); + + + BOOST_FOREACH(sm_vertex_descriptor svd, vertices(sm)){ + tm_vertex_descriptor tvd = add_vertex(tm); + v2v.insert(std::make_pair(svd, tvd)); + put(tm_pmap, tvd, get(sm_pmap, svd)); + } + + boost::unordered_map f2f; + BOOST_FOREACH(sm_face_descriptor sfd, faces(sm)){ + std::vector tv; + BOOST_FOREACH(sm_vertex_descriptor svd, vertices_around_face(halfedge(sfd,sm),sm)){ + tv.push_back(v2v.at(svd)); + } + f2f[sfd] = Euler::add_face(tv,tm); + } + + BOOST_FOREACH(sm_face_descriptor sfd, faces(sm)){ + sm_halfedge_descriptor shd = halfedge(sfd,sm), done(shd); + tm_halfedge_descriptor thd = halfedge(f2f[sfd],tm); + tm_vertex_descriptor tvd = v2v.at(target(shd,sm)); + while(target(thd,tm) != tvd){ + thd = next(thd,tm); + } + do { + h2h.insert(std::make_pair(shd, thd)); + shd = next(shd,sm); + thd = next(thd,tm); + }while(shd != done); + } + +} + +} // namespace CGAL + +#endif // CGAL_BOOST_GRAPH_CONVERT_SURFACE_MESH_H diff --git a/BGL/include/CGAL/boost/graph/graph_traits_PolyMesh_ArrayKernelT.h b/BGL/include/CGAL/boost/graph/graph_traits_PolyMesh_ArrayKernelT.h index d8ceeb786d4..220001a37b1 100644 --- a/BGL/include/CGAL/boost/graph/graph_traits_PolyMesh_ArrayKernelT.h +++ b/BGL/include/CGAL/boost/graph/graph_traits_PolyMesh_ArrayKernelT.h @@ -30,6 +30,7 @@ #include #include #include +#include #include @@ -354,6 +355,9 @@ typename boost::graph_traits >::halfedge_desc halfedge(typename boost::graph_traits >::vertex_descriptor v, const OpenMesh::PolyMesh_ArrayKernelT& sm) { + if(sm.halfedge_handle(v) == boost::graph_traits >::null_halfedge()){ + return boost::graph_traits >::null_halfedge(); + } // prev because OpenMesh stores out-going halfedges // return sm.prev_halfedge_handle(sm.halfedge_handle(v)); return sm.opposite_halfedge_handle(sm.halfedge_handle(v)); @@ -540,7 +544,7 @@ template void clear_vertex(typename boost::graph_traits >::vertex_descriptor, OpenMesh::PolyMesh_ArrayKernelT&) { - assert(false); + CGAL_assert(false); } */ @@ -606,12 +610,12 @@ remove_face(typename boost::graph_traits >::f sm.request_face_status(); sm.request_vertex_status(); sm.request_halfedge_status(); - set_halfedge(f, typename boost::graph_traits >::halfedge_descriptor(), sm); + set_halfedge(f, typename boost::graph_traits >::halfedge_descriptor(), sm); sm.status(f).set_deleted(true); } - +#if 0 // conflits with function in Euler_operations.h template std::pair >::edge_descriptor, bool> @@ -621,6 +625,7 @@ add_edge(typename boost::graph_traits >::vert return sm.new_edge(v1, v2); } +#endif template typename boost::graph_traits >::face_descriptor diff --git a/BGL/include/CGAL/boost/graph/graph_traits_Surface_mesh.h b/BGL/include/CGAL/boost/graph/graph_traits_Surface_mesh.h index c2ccc9f9dd2..222eca98593 100644 --- a/BGL/include/CGAL/boost/graph/graph_traits_Surface_mesh.h +++ b/BGL/include/CGAL/boost/graph/graph_traits_Surface_mesh.h @@ -29,7 +29,7 @@ #include #include - +#include namespace boost { @@ -445,7 +445,7 @@ template void clear_vertex(typename boost::graph_traits >::vertex_descriptor, CGAL::Surface_mesh

&) { - assert(false); + CGAL_assertion(false); } */ diff --git a/BGL/include/CGAL/boost/graph/graph_traits_TriMesh_ArrayKernelT.h b/BGL/include/CGAL/boost/graph/graph_traits_TriMesh_ArrayKernelT.h new file mode 100644 index 00000000000..53e6a5754f4 --- /dev/null +++ b/BGL/include/CGAL/boost/graph/graph_traits_TriMesh_ArrayKernelT.h @@ -0,0 +1,614 @@ +// Copyright (c) 2007 GeometryFactory (France). All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Andreas Fabri, Philipp Moeller + +#ifndef CGAL_BOOST_GRAPH_GRAPH_TRAITS_TRIMESH_ARRAYKERNELT_H +#define CGAL_BOOST_GRAPH_GRAPH_TRAITS_TRIMESH_ARRAYKERNELT_H + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +// http://openmesh.org/Documentation/OpenMesh-Doc-Latest/classOpenMesh_1_1Concepts_1_1KernelT.html + +#if defined(BOOST_MSVC) +# pragma warning(push) +# pragma warning(disable:4267) +#endif + +namespace boost { + +template +struct graph_traits< OpenMesh::TriMesh_ArrayKernelT > +{ +private: + typedef OpenMesh::TriMesh_ArrayKernelT SM; + + struct SM_graph_traversal_category : public virtual boost::bidirectional_graph_tag, + public virtual boost::vertex_list_graph_tag, + public virtual boost::edge_list_graph_tag + {}; + +public: + // Graph + typedef typename SM::VertexHandle vertex_descriptor; + typedef typename SM::Point vertex_property_type; + typedef typename CGAL::internal::OMesh_edge edge_descriptor; + typedef boost::undirected_tag directed_category; + typedef boost::disallow_parallel_edge_tag edge_parallel_category; + typedef SM_graph_traversal_category traversal_category; + + // HalfedgeGraph + typedef typename SM::HalfedgeHandle halfedge_descriptor; + + // FaceGraph + typedef typename SM::FaceHandle face_descriptor; + + // VertexListGraph + typedef typename SM::VertexIter vertex_iterator; + typedef unsigned int vertices_size_type; + // EdgeListGraph + typedef boost::transform_iterator< + CGAL::internal::Convert_omesh_edge, + typename SM::EdgeIter, + edge_descriptor> edge_iterator; + + typedef unsigned int edges_size_type; + // HalfEdgeListGraph + typedef typename SM::HalfedgeIter halfedge_iterator; + typedef unsigned int halfedges_size_type; + // FaceListGraph + typedef typename SM::FaceIter face_iterator; + typedef unsigned int faces_size_type; + + // IncidenceGraph + typedef unsigned int degree_size_type; + + + typedef CGAL::In_edge_iterator in_edge_iterator; + + typedef CGAL::Out_edge_iterator out_edge_iterator; + + // nulls + static vertex_descriptor null_vertex() { return vertex_descriptor(); } + static face_descriptor null_face() { return face_descriptor(); } + static halfedge_descriptor null_halfedge() { return halfedge_descriptor(); } +}; + +template +struct graph_traits< const OpenMesh::TriMesh_ArrayKernelT > + : public graph_traits< OpenMesh::TriMesh_ArrayKernelT > +{ }; + +} // namespace boost + +namespace OpenMesh { + +template +typename boost::graph_traits >::vertices_size_type +num_vertices(const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + return sm.n_vertices(); +} + + +template +typename boost::graph_traits >::edges_size_type +num_edges(const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + return sm.n_edges(); +} + + +template +typename boost::graph_traits >::degree_size_type +degree(typename boost::graph_traits >::vertex_descriptor v, + const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + return sm.valence(v); +} + + +template +typename boost::graph_traits >::degree_size_type +out_degree(typename boost::graph_traits >::vertex_descriptor v, + const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + return sm.valence(v); +} + + +template +typename boost::graph_traits >::degree_size_type +in_degree(typename boost::graph_traits >::vertex_descriptor v, + const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + return sm.valence(v); +} + + +template +typename boost::graph_traits >::vertex_descriptor +source(typename boost::graph_traits >::edge_descriptor e, + const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + return sm.from_vertex_handle(e.halfedge()); +} + +template +typename boost::graph_traits >::vertex_descriptor +source(typename boost::graph_traits >::halfedge_descriptor h, + const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + return sm.from_vertex_handle(h); +} + + +template +typename boost::graph_traits >::vertex_descriptor +target(typename boost::graph_traits >::edge_descriptor e, + const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + return sm.to_vertex_handle(e.halfedge()); +} + +template +typename boost::graph_traits >::vertex_descriptor +target(typename boost::graph_traits >::halfedge_descriptor h, + const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + return sm.to_vertex_handle(h); +} + +template +CGAL::Iterator_range >::vertex_iterator> +vertices(const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + return CGAL::make_range(sm.vertices_sbegin(), sm.vertices_end()); +} + + +template +CGAL::Iterator_range >::edge_iterator> +edges(const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + typedef typename boost::graph_traits >::edge_iterator iterator; + iterator beg(sm.edges_sbegin()); + iterator end(sm.edges_end()); + return CGAL::make_range(beg,end); +} + + +template +CGAL::Iterator_range >::in_edge_iterator> +in_edges(typename boost::graph_traits >::vertex_descriptor v, + const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + typedef typename boost::graph_traits >::in_edge_iterator Iter; + + return CGAL::make_range(Iter(halfedge(v,sm),sm), Iter(halfedge(v,sm),sm,1)); +} + + +template +CGAL::Iterator_range >::out_edge_iterator> +out_edges(typename boost::graph_traits >::vertex_descriptor v, + const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + typedef typename boost::graph_traits >::out_edge_iterator Iter; + return CGAL::make_range(Iter(halfedge(v,sm),sm), Iter(halfedge(v,sm),sm,1)); +} + + +template +std::pair >::edge_descriptor, + bool> +edge(typename boost::graph_traits >::vertex_descriptor u, + typename boost::graph_traits >::vertex_descriptor v, + const OpenMesh::TriMesh_ArrayKernelT& sm) { + typename boost::graph_traits >::edge_descriptor + he(sm.find_halfedge(u, v)); + return std::make_pair(he, he.is_valid()); +} + + +// +// HalfedgeGraph +// +template +typename boost::graph_traits >::halfedge_descriptor +next(typename boost::graph_traits >::halfedge_descriptor h, + const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + return sm.next_halfedge_handle(h); +} + +template +typename boost::graph_traits >::halfedge_descriptor +prev(typename boost::graph_traits >::halfedge_descriptor h, + const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + return sm.prev_halfedge_handle(h); +} + +template +typename boost::graph_traits >::halfedge_descriptor +opposite(typename boost::graph_traits >::halfedge_descriptor h, + const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + return sm.opposite_halfedge_handle(h); +} + +template +typename boost::graph_traits >::edge_descriptor +edge(typename boost::graph_traits >::halfedge_descriptor h, + const OpenMesh::TriMesh_ArrayKernelT& /*sm*/) +{ + return typename boost::graph_traits >::edge_descriptor(h); +} + +template +typename boost::graph_traits >::halfedge_descriptor +halfedge(typename boost::graph_traits >::edge_descriptor e, + const OpenMesh::TriMesh_ArrayKernelT&) +{ + return e.halfedge(); +} + +template +typename boost::graph_traits >::halfedge_descriptor +halfedge(typename boost::graph_traits >::vertex_descriptor v, + const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + if(sm.halfedge_handle(v) == boost::graph_traits >::null_halfedge()){ + return boost::graph_traits >::null_halfedge(); + } + // prev because OpenMesh stores out-going halfedges + // return sm.prev_halfedge_handle(sm.halfedge_handle(v)); + return sm.opposite_halfedge_handle(sm.halfedge_handle(v)); +} + + +template +std::pair< + typename boost::graph_traits >::halfedge_descriptor, + bool +> +halfedge(typename boost::graph_traits >::vertex_descriptor u, + typename boost::graph_traits >::vertex_descriptor v, + const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + typename boost::graph_traits >::halfedge_descriptor h = sm.find_halfedge(u, v); + return std::make_pair(h, h.is_valid()); +} + + + +// +// HalfedgeListGraph +// +template +CGAL::Iterator_range >::halfedge_iterator> +halfedges(const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + return CGAL::make_range(sm.halfedges_sbegin(), sm.halfedges_end()); +} + +template +typename boost::graph_traits >::halfedges_size_type +num_halfedges(const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + return sm.n_halfedges(); +} + + + +// +// MutableHalfedgeGraph +// +template +void +set_next(typename boost::graph_traits >::halfedge_descriptor h1, + typename boost::graph_traits >::halfedge_descriptor h2, + OpenMesh::TriMesh_ArrayKernelT& sm) +{ + sm.set_next_halfedge_handle(h1, h2); +} + + + +template +void +set_target(typename boost::graph_traits >::halfedge_descriptor h, + typename boost::graph_traits >::vertex_descriptor v, + OpenMesh::TriMesh_ArrayKernelT& sm) +{ + sm.set_vertex_handle(h, v); +} + + +template +void +set_halfedge(typename boost::graph_traits >::vertex_descriptor v, + typename boost::graph_traits >::halfedge_descriptor h, + OpenMesh::TriMesh_ArrayKernelT& sm) +{ + sm.set_halfedge_handle(v, sm.opposite_halfedge_handle(h)); +} + + +template +void +adjust_border_halfedge(typename boost::graph_traits >::vertex_descriptor v, + OpenMesh::TriMesh_ArrayKernelT& sm) +{ + sm.adjust_outgoing_halfedge(v); +} + +template +void +garbage_collection(OpenMesh::TriMesh_ArrayKernelT& sm) +{ + sm.garbage_collection(); +} + +template +typename boost::graph_traits >::edge_descriptor +add_edge(OpenMesh::TriMesh_ArrayKernelT& sm) +{ + return edge(sm.new_edge(boost::graph_traits >::null_vertex(), + boost::graph_traits >::null_vertex() ), sm); +} + + +// +// FaceGraph +// +template +typename boost::graph_traits >::halfedge_descriptor +halfedge(typename boost::graph_traits >::face_descriptor f, + const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + return sm.halfedge_handle(f); +} + +template +typename boost::graph_traits >::face_descriptor +face(typename boost::graph_traits >::halfedge_descriptor h, + const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + return sm.face_handle(h); +} + + + +// +// MutableFaceGraph +// +template +void +set_face(typename boost::graph_traits >::halfedge_descriptor h, + typename boost::graph_traits >::face_descriptor f, + OpenMesh::TriMesh_ArrayKernelT& sm) +{ + sm.set_face_handle(h, f); +} + + +template +void +set_halfedge(typename boost::graph_traits >::face_descriptor f, + typename boost::graph_traits >::halfedge_descriptor h, + OpenMesh::TriMesh_ArrayKernelT& sm) +{ + sm.set_halfedge_handle(f, h); +} + + +// +// FaceListGraph +// +template +typename boost::graph_traits >::faces_size_type +num_faces(const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + return sm.n_faces(); +} + +template +CGAL::Iterator_range >::face_iterator> +faces(const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + return CGAL::make_range(sm.faces_sbegin(), sm.faces_end()); +} + + +template +typename boost::graph_traits >::vertex_descriptor +add_vertex(OpenMesh::TriMesh_ArrayKernelT& sm) { + return sm.new_vertex(); +} + + /* + +// MutableGraph +// add a vertex with a default constructed property +template +typename boost::graph_traits >::vertex_descriptor +add_vertex(OpenMesh::TriMesh_ArrayKernelT& sm) { + return sm.add_vertex(typename boost::graph_traits >::vertex_property_type()); +} + +template +typename boost::graph_traits >::vertex_descriptor +add_vertex(const typename boost::graph_traits >::vertex_property_type& p, OpenMesh::TriMesh_ArrayKernelT& sm) { + return sm.add_vertex(p); +} + +template +void +clear_vertex(typename boost::graph_traits >::vertex_descriptor, + OpenMesh::TriMesh_ArrayKernelT&) { + CGAL_assert(false); +} + + */ + +template +void +remove_vertex(typename boost::graph_traits >::vertex_descriptor v, + OpenMesh::TriMesh_ArrayKernelT& sm) { + + sm.request_face_status(); + sm.request_vertex_status(); + sm.request_halfedge_status(); + sm.set_halfedge_handle(v, typename boost::graph_traits >::halfedge_descriptor()); + sm.status(v).set_deleted(true); +} + + +template +void +remove_edge(typename boost::graph_traits >::vertex_descriptor u, + typename boost::graph_traits >::vertex_descriptor v, + OpenMesh::TriMesh_ArrayKernelT& sm) +{ + typename boost::graph_traits >::edge_descriptor e = edge(u, v, sm); + remove_edge(e,sm); +} + +template +void +remove_edge(typename boost::graph_traits >::edge_descriptor e, + OpenMesh::TriMesh_ArrayKernelT& sm) +{ + sm.request_face_status(); + sm.request_vertex_status(); + sm.request_halfedge_status(); + sm.request_edge_status(); + + typedef typename boost::graph_traits >::halfedge_descriptor halfedge_descriptor; + + halfedge_descriptor h1 = halfedge(e,sm); + halfedge_descriptor h2 = opposite(halfedge(e,sm),sm); + sm.status(sm.edge_handle(h1)).set_deleted(true); + sm.status(h1).set_deleted(true); + sm.status(h2).set_deleted(true); + +} + + +template +void +remove_edge(typename boost::graph_traits >::edge_iterator eiter, + OpenMesh::TriMesh_ArrayKernelT& sm) +{ + remove_edge(*eiter, sm); +} + +template +void +remove_face(typename boost::graph_traits >::face_descriptor f, + OpenMesh::TriMesh_ArrayKernelT& sm) +{ + + sm.request_face_status(); + sm.request_vertex_status(); + sm.request_halfedge_status(); + + set_halfedge(f, typename boost::graph_traits >::halfedge_descriptor(), sm); + sm.status(f).set_deleted(true); +} + +#if 0 // conflits with function in Euler_operations.h +template +std::pair >::edge_descriptor, + bool> +add_edge(typename boost::graph_traits >::vertex_descriptor v1, + typename boost::graph_traits >::vertex_descriptor v2, + OpenMesh::TriMesh_ArrayKernelT& sm) { + + return sm.new_edge(v1, v2); +} +#endif + +template +typename boost::graph_traits >::face_descriptor +add_face(OpenMesh::TriMesh_ArrayKernelT& sm) +{ + return sm.new_face(); +} + +template +typename boost::graph_traits >::face_descriptor +add_face(InputIterator begin, InputIterator end, OpenMesh::TriMesh_ArrayKernelT& sm) +{ + typedef typename boost::graph_traits >::vertex_descriptor vertex_descriptor; + assert(begin!= end); + vertex_descriptor u = *begin; + ++begin; + assert(begin!= end); + vertex_descriptor v = *begin; + ++begin; + assert(begin!= end); + vertex_descriptor w = *begin; + + return sm.add_face(u,v,w); +} + +template +bool is_valid(OpenMesh::TriMesh_ArrayKernelT& sm, bool /* verbose */ = false) +{ + return CGAL::is_valid_polygon_mesh(sm); +} + +} // namespace OpenMesh + + +#ifndef CGAL_NO_DEPRECATED_CODE +#include + +namespace boost { + // The following functions were defined in the namespace boost + using OpenMesh::vertices; + using OpenMesh::edges; + using OpenMesh::num_vertices; + using OpenMesh::num_edges; + using OpenMesh::out_edges; + using OpenMesh::in_edges; + using OpenMesh::target; + using OpenMesh::source; +} // namespace boost +#endif //CGAL_NO_DEPRECATED_CODE + +#if defined(BOOST_MSVC) +# pragma warning(pop) +#endif + +#endif // CGAL_BOOST_GRAPH_TRAITS_TRIMESH_ARRAYKERNELT_H diff --git a/BGL/include/CGAL/boost/graph/iterator.h b/BGL/include/CGAL/boost/graph/iterator.h index 635b9e5c424..74867ba8db4 100644 --- a/BGL/include/CGAL/boost/graph/iterator.h +++ b/BGL/include/CGAL/boost/graph/iterator.h @@ -872,7 +872,16 @@ halfedges_around_face(typename boost::graph_traits::halfedge_descriptor h return make_range(I(h,g), I(h,g,1)); } - +/** + * \ingroup PkgBGLIterators + * A bidirectional iterator with value type `boost::graph_traits::%face_descriptor`. + * It iterates over the same halfedges as the `Halfedge_around_face_iterator`, + * and provides the face descriptor associated to the opposite halfedge. The face descriptor + * may be the null face, and it may be several times the same face descriptor. + * + * \tparam Graph must be a model of the concept `HalfedgeGraph` + * \cgalModels `BidirectionalCirculator` + */ template class Face_around_face_iterator #ifndef DOXYGEN_RUNNING @@ -1023,6 +1032,13 @@ private: #endif }; +/** + * \ingroup PkgBGLIterators + * A bidirectional iterator with value type `boost::graph_traits::%vertex_descriptor` + * over all vertices incident to the same face or border. + * \tparam Graph must be a model of the concept `HalfedgeGraph` + * \cgalModels `BidirectionalIterator` + */ template class Vertex_around_face_iterator #ifndef DOXYGEN_RUNNING @@ -1111,7 +1127,7 @@ opposite_edges_around_face(typename boost::graph_traits::halfedge_descrip /** * \ingroup PkgBGLIterators - * A bidirectional circulator with value type `boost::graph_traits::%vertex_descriptor` over all vertices adjacent to the same vertex. + * A bidirectional circulator with value type `boost::graph_traits::%vertex_descriptor` over all vertices adjacent to the same vertex. * It circulates over the same halfedges as the `Halfedge_around_target_circulator`. * * \tparam Graph must be a model of the concept `HalfedgeGraph` diff --git a/BGL/include/CGAL/boost/graph/properties_PolyMesh_ArrayKernelT.h b/BGL/include/CGAL/boost/graph/properties_PolyMesh_ArrayKernelT.h index d5c092e638a..9b72934c666 100644 --- a/BGL/include/CGAL/boost/graph/properties_PolyMesh_ArrayKernelT.h +++ b/BGL/include/CGAL/boost/graph/properties_PolyMesh_ArrayKernelT.h @@ -85,17 +85,17 @@ public: }; -template +template class OM_edge_weight_pmap - : public boost::put_get_helper::Scalar , OM_edge_weight_pmap > + : public boost::put_get_helper > { public: typedef boost::readable_property_map_tag category; - typedef typename OpenMesh::PolyMesh_ArrayKernelT::Scalar value_type; + typedef typename OpenMesh::Scalar value_type; typedef value_type reference; - typedef typename boost::graph_traits >::edge_descriptor key_type; + typedef typename boost::graph_traits::edge_descriptor key_type; - OM_edge_weight_pmap(const OpenMesh::PolyMesh_ArrayKernelT& sm) + OM_edge_weight_pmap(const OpenMesh& sm) : sm_(sm) {} @@ -105,7 +105,7 @@ public: } private: - const OpenMesh::PolyMesh_ArrayKernelT& sm_; + const OpenMesh& sm_; }; template @@ -124,25 +124,25 @@ public: }; - template -class OM_point_pmap //: public boost::put_get_helper > +template +class OM_point_pmap //: public boost::put_get_helper > { public: typedef boost::read_write_property_map_tag category; #if defined(CGAL_USE_OM_POINTS) - typedef typename OpenMesh::PolyMesh_ArrayKernelT::Point value_type; - typedef const typename OpenMesh::PolyMesh_ArrayKernelT::Point& reference; + typedef typename OpenMesh::Point value_type; + typedef const typename OpenMesh::Point& reference; #else typedef P value_type; typedef P reference; #endif - typedef typename boost::graph_traits< OpenMesh::PolyMesh_ArrayKernelT >::vertex_descriptor key_type; + typedef typename boost::graph_traits::vertex_descriptor key_type; OM_point_pmap() : sm_(NULL) {} - OM_point_pmap(const OpenMesh::PolyMesh_ArrayKernelT& sm) + OM_point_pmap(const OpenMesh& sm) : sm_(&sm) {} @@ -156,36 +156,36 @@ public: return sm_->point(v); #else CGAL_assertion(sm_!=NULL); - typename OpenMesh::PolyMesh_ArrayKernelT::Point const& omp = sm_->point(v); + typename OpenMesh::Point const& omp = sm_->point(v); return value_type(omp[0], omp[1], omp[2]); #endif } - inline friend reference get(const OM_point_pmap& pm, key_type v) + inline friend reference get(const OM_point_pmap& pm, key_type v) { CGAL_precondition(pm.sm_!=NULL); #if defined(CGAL_USE_OM_POINTS) return pm.sm_->point(v); #else CGAL_assertion(pm.sm_!=NULL); - typename OpenMesh::PolyMesh_ArrayKernelT::Point const& omp = pm.sm_->point(v); + typename OpenMesh::Point const& omp = pm.sm_->point(v); return value_type(omp[0], omp[1], omp[2]); #endif } - inline friend void put(const OM_point_pmap& pm, key_type v, const value_type& p) + inline friend void put(const OM_point_pmap& pm, key_type v, const value_type& p) { CGAL_precondition(pm.sm_!=NULL); #if defined(CGAL_USE_OM_POINTS) - const_cast&>(*pm.sm_).set_point(v,p); + const_cast(*pm.sm_).set_point(v,p); #else - const_cast&>(*pm.sm_).set_point - (v, typename OpenMesh::PolyMesh_ArrayKernelT::Point((float)p[0], (float)p[1], (float)p[2])); + const_cast(*pm.sm_).set_point + (v, typename OpenMesh::Point((float)p[0], (float)p[1], (float)p[2])); #endif } private: - const OpenMesh::PolyMesh_ArrayKernelT* sm_; + const OpenMesh* sm_; }; @@ -202,8 +202,9 @@ namespace boost { template struct property_map, boost::edge_weight_t > { - typedef CGAL::OM_edge_weight_pmap type; - typedef CGAL::OM_edge_weight_pmap const_type; + typedef OpenMesh::PolyMesh_ArrayKernelT Mesh; + typedef CGAL::OM_edge_weight_pmap type; + typedef CGAL::OM_edge_weight_pmap const_type; }; @@ -215,8 +216,9 @@ struct property_map, boost::edge_weight_t > template struct property_map, boost::vertex_index_t > { - typedef CGAL::OM_index_pmap >::vertex_descriptor> type; - typedef CGAL::OM_index_pmap >::vertex_descriptor> const_type; + typedef OpenMesh::PolyMesh_ArrayKernelT Mesh; + typedef CGAL::OM_index_pmap::vertex_descriptor> type; + typedef CGAL::OM_index_pmap::vertex_descriptor> const_type; }; @@ -227,8 +229,9 @@ struct property_map, boost::vertex_index_t > template struct property_map, boost::face_index_t > { - typedef CGAL::OM_index_pmap >::face_descriptor> type; - typedef CGAL::OM_index_pmap >::face_descriptor> const_type; + typedef OpenMesh::PolyMesh_ArrayKernelT Mesh; + typedef CGAL::OM_index_pmap::face_descriptor> type; + typedef CGAL::OM_index_pmap::face_descriptor> const_type; }; // @@ -238,8 +241,9 @@ struct property_map, boost::face_index_t > template struct property_map, boost::edge_index_t > { - typedef CGAL::OM_index_pmap >::edge_descriptor> type; - typedef CGAL::OM_index_pmap >::edge_descriptor> const_type; + typedef OpenMesh::PolyMesh_ArrayKernelT Mesh; + typedef CGAL::OM_index_pmap type; + typedef CGAL::OM_index_pmap const_type; }; // @@ -249,8 +253,9 @@ struct property_map, boost::edge_index_t > template struct property_map, boost::halfedge_index_t > { - typedef CGAL::OM_index_pmap >::halfedge_descriptor> type; - typedef CGAL::OM_index_pmap >::halfedge_descriptor> const_type; + typedef OpenMesh::PolyMesh_ArrayKernelT Mesh; + typedef CGAL::OM_index_pmap type; + typedef CGAL::OM_index_pmap const_type; }; @@ -258,7 +263,8 @@ template struct property_map, boost::vertex_point_t > { typedef CGAL::Exact_predicates_inexact_constructions_kernel::Point_3 P; - typedef CGAL::OM_point_pmap type; + typedef OpenMesh::PolyMesh_ArrayKernelT Mesh; + typedef CGAL::OM_point_pmap type; typedef type const_type; }; @@ -271,7 +277,8 @@ template typename boost::property_map, boost::edge_weight_t>::const_type get(boost::edge_weight_t, const OpenMesh::PolyMesh_ArrayKernelT& sm) { - return CGAL::OM_edge_weight_pmap(sm); + typedef OpenMesh::PolyMesh_ArrayKernelT Mesh; + return CGAL::OM_edge_weight_pmap(sm); } template @@ -279,7 +286,8 @@ typename OpenMesh::PolyMesh_ArrayKernelT::Scalar get(boost::edge_weight_t, const OpenMesh::PolyMesh_ArrayKernelT& sm, const typename boost::graph_traits >::edge_descriptor& e) { - return CGAL::OM_edge_weight_pmap(sm)[e]; + typedef OpenMesh::PolyMesh_ArrayKernelT Mesh; + return CGAL::OM_edge_weight_pmap(sm)[e]; } @@ -287,13 +295,15 @@ template CGAL::OM_index_pmap >::vertex_descriptor> get(const boost::vertex_index_t&, const OpenMesh::PolyMesh_ArrayKernelT&) { - return CGAL::OM_index_pmap >::vertex_descriptor>(); + typedef OpenMesh::PolyMesh_ArrayKernelT Mesh; + return CGAL::OM_index_pmap::vertex_descriptor>(); } template typename boost::property_map, boost::face_index_t>::const_type get(const boost::face_index_t&, const OpenMesh::PolyMesh_ArrayKernelT&) { + typedef OpenMesh::PolyMesh_ArrayKernelT Mesh; return CGAL::OM_index_pmap >::face_descriptor>(); } @@ -312,11 +322,12 @@ get(const boost::halfedge_index_t&, const OpenMesh::PolyMesh_ArrayKernelT&) } template -CGAL::OM_point_pmap +CGAL::OM_point_pmap, + typename CGAL::Exact_predicates_inexact_constructions_kernel::Point_3> get(boost::vertex_point_t, const OpenMesh::PolyMesh_ArrayKernelT& g) { typedef typename CGAL::Exact_predicates_inexact_constructions_kernel::Point_3 P; - return CGAL::OM_point_pmap(g); + return CGAL::OM_point_pmap, P>(g); } // get for intrinsic properties diff --git a/BGL/include/CGAL/boost/graph/properties_TriMesh_ArrayKernelT.h b/BGL/include/CGAL/boost/graph/properties_TriMesh_ArrayKernelT.h new file mode 100644 index 00000000000..f19093c3670 --- /dev/null +++ b/BGL/include/CGAL/boost/graph/properties_TriMesh_ArrayKernelT.h @@ -0,0 +1,195 @@ +// Copyright (c) 2014 GeometryFactory (France). All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Philipp Möller + + +#ifndef CGAL_PROPERTIES_TRIMESH_ARRAYKERNELT_H +#define CGAL_PROPERTIES_TRIMESH_ARRAYKERNELT_H + +#include +#include +#include +#include +#include +#include + + +// overloads and specializations in the boost namespace +namespace boost { + +// +// edge_weight +// +template +struct property_map, boost::edge_weight_t > +{ + typedef OpenMesh::TriMesh_ArrayKernelT Mesh; + typedef CGAL::OM_edge_weight_pmap type; + typedef CGAL::OM_edge_weight_pmap const_type; +}; + + + +// +// vertex_index +// +template +struct property_map, boost::vertex_index_t > +{ + typedef CGAL::OM_index_pmap >::vertex_descriptor> type; + typedef CGAL::OM_index_pmap >::vertex_descriptor> const_type; +}; + + +// +// face_index +// + +template +struct property_map, boost::face_index_t > +{ + typedef CGAL::OM_index_pmap >::face_descriptor> type; + typedef CGAL::OM_index_pmap >::face_descriptor> const_type; +}; + +// +// edge_index +// + +template +struct property_map, boost::edge_index_t > +{ + typedef CGAL::OM_index_pmap >::edge_descriptor> type; + typedef CGAL::OM_index_pmap >::edge_descriptor> const_type; +}; + +// +// halfedge_index +// + +template +struct property_map, boost::halfedge_index_t > +{ + typedef CGAL::OM_index_pmap >::halfedge_descriptor> type; + typedef CGAL::OM_index_pmap >::halfedge_descriptor> const_type; +}; + + +template +struct property_map, boost::vertex_point_t > +{ + typedef CGAL::Exact_predicates_inexact_constructions_kernel::Point_3 P; + typedef OpenMesh::TriMesh_ArrayKernelT Mesh; + typedef CGAL::OM_point_pmap type; + typedef type const_type; +}; + +} // namespace boost + +namespace boost { + + +template +typename boost::property_map, boost::edge_weight_t>::const_type +get(boost::edge_weight_t, const OpenMesh::TriMesh_ArrayKernelT& sm) +{ + return CGAL::OM_edge_weight_pmap(sm); +} + +template +typename OpenMesh::TriMesh_ArrayKernelT::Scalar +get(boost::edge_weight_t, const OpenMesh::TriMesh_ArrayKernelT& sm, + const typename boost::graph_traits >::edge_descriptor& e) +{ + return CGAL::OM_edge_weight_pmap(sm)[e]; +} + + +template +CGAL::OM_index_pmap >::vertex_descriptor> +get(const boost::vertex_index_t&, const OpenMesh::TriMesh_ArrayKernelT&) +{ + return CGAL::OM_index_pmap >::vertex_descriptor>(); +} + +template +typename boost::property_map, boost::face_index_t>::const_type +get(const boost::face_index_t&, const OpenMesh::TriMesh_ArrayKernelT&) +{ + return CGAL::OM_index_pmap >::face_descriptor>(); +} + +template +CGAL::OM_index_pmap >::edge_descriptor> +get(const boost::edge_index_t&, const OpenMesh::TriMesh_ArrayKernelT&) +{ + return CGAL::OM_index_pmap >::edge_descriptor>(); +} + +template +CGAL::OM_index_pmap >::halfedge_descriptor> +get(const boost::halfedge_index_t&, const OpenMesh::TriMesh_ArrayKernelT&) +{ + return CGAL::OM_index_pmap >::halfedge_descriptor>(); +} + +template +CGAL::OM_point_pmap, + typename CGAL::Exact_predicates_inexact_constructions_kernel::Point_3> +get(boost::vertex_point_t, const OpenMesh::TriMesh_ArrayKernelT& g) +{ + typedef typename CGAL::Exact_predicates_inexact_constructions_kernel::Point_3 P; + typedef OpenMesh::TriMesh_ArrayKernelT Mesh; + return CGAL::OM_point_pmap(g); +} + +// get for intrinsic properties +#define CGAL_OM_INTRINSIC_PROPERTY(RET, PROP, TYPE) \ + template \ + RET \ + get(PROP p, const OpenMesh::TriMesh_ArrayKernelT& sm, \ + typename boost::graph_traits< OpenMesh::TriMesh_ArrayKernelT >::TYPE x) \ + { return get(get(p, sm), x); } \ + + CGAL_OM_INTRINSIC_PROPERTY(int, boost::vertex_index_t, vertex_descriptor) + CGAL_OM_INTRINSIC_PROPERTY(int, boost::edge_index_t, edge_descriptor) + CGAL_OM_INTRINSIC_PROPERTY(int, boost::halfedge_index_t, halfedge_descriptor) + CGAL_OM_INTRINSIC_PROPERTY(int, boost::face_index_t, face_descriptor) + // CGAL_OM_INTRINSIC_PROPERTY(std::size_t, boost::halfedge_index_t, face_descriptor) + CGAL_OM_INTRINSIC_PROPERTY(typename CGAL::Exact_predicates_inexact_constructions_kernel::Point_3, boost::vertex_point_t, vertex_descriptor) + +#undef CGAL_OM_INTRINSIC_PROPERTY + +// put for intrinsic properties +// only available for vertex_point + +template +void +put(boost::vertex_point_t p, OpenMesh::TriMesh_ArrayKernelT& g, + typename boost::graph_traits< OpenMesh::TriMesh_ArrayKernelT >::vertex_descriptor vd, + const typename K::Point& point) +{ + put(get(p,g), vd, point); +} + + +} // namespace boost + + + +#endif /* CGAL_PROPERTIES_TRIMESH_ARRAYKERNELT_H */ diff --git a/Barycentric_coordinates_2/doc/Barycentric_coordinates_2/PackageDescription.txt b/Barycentric_coordinates_2/doc/Barycentric_coordinates_2/PackageDescription.txt index 5eb0ab1b4b4..a74f83709c8 100644 --- a/Barycentric_coordinates_2/doc/Barycentric_coordinates_2/PackageDescription.txt +++ b/Barycentric_coordinates_2/doc/Barycentric_coordinates_2/PackageDescription.txt @@ -10,7 +10,7 @@ \cgalPkgPicture{barcoord_thumb.png} \cgalPkgSummaryBegin \cgalPkgAuthors{Dmitry Anisimov, David Bommes, Kai Hormann, and Pierre Alliez} -\cgalPkgDesc{The package 2D Generalized Barycentric Coordinates offers an efficient and robust implementation of two-dimensional closed-form generalized barycentric coordinates defined for simple two-dimensional polygons. If coordinates with respect to multivariate scattered points instead of a polygon are required, please refer to natural neighbour coordinates from the package 2D and Surface Function Interpolation.} +\cgalPkgDesc{The package 2D Generalized Barycentric Coordinates offers an efficient and robust implementation of two-dimensional closed-form generalized barycentric coordinates defined for simple two-dimensional polygons. If coordinates with respect to multivariate scattered points instead of a polygon are required, please refer to natural neighbor coordinates from the Package \ref PkgInterpolation2Summary.} \cgalPkgManuals{Chapter_2D_Generalized_Barycentric_Coordinates, PkgBarycentric_coordinates_2} \cgalPkgSummaryEnd \cgalPkgShortInfoBegin diff --git a/CGAL_Core/include/CGAL/CORE/BigFloat.h b/CGAL_Core/include/CGAL/CORE/BigFloat.h index 4cf2dedc80a..f264568bcce 100644 --- a/CGAL_Core/include/CGAL/CORE/BigFloat.h +++ b/CGAL_Core/include/CGAL/CORE/BigFloat.h @@ -36,6 +36,7 @@ #define _CORE_BIGFLOAT_H_ #include +#include namespace CORE { @@ -246,7 +247,7 @@ public: /** \note This is only the sign of the mantissa, it can be taken to be the sign of the BigFloat only if !(isZeroIn()). */ int sign() const { - assert((err() == 0 && m() == 0) || !(isZeroIn())); + CGAL_assertion((err() == 0 && m() == 0) || !(isZeroIn())); return rep->signM(); } /// check whether contains zero @@ -553,7 +554,7 @@ inline bool isDivisible(double x, double y) { // normalizing it then we get zero. inline BigFloat div_exact(const BigFloat& x, const BigFloat& y) { BigInt z; - assert (isDivisible(x,y)); + CGAL_assertion (isDivisible(x,y)); unsigned long bin_x = getBinExpo(x.m()); unsigned long bin_y = getBinExpo(y.m()); diff --git a/CGAL_Core/include/CGAL/CORE/Expr.h b/CGAL_Core/include/CGAL/CORE/Expr.h index 4a68a9d9e12..f1215cdf985 100644 --- a/CGAL_Core/include/CGAL/CORE/Expr.h +++ b/CGAL_Core/include/CGAL/CORE/Expr.h @@ -40,6 +40,7 @@ #define _CORE_EXPR_H_ #include +#include namespace CORE { @@ -534,7 +535,7 @@ inline Expr rootOf(const Polynomial& p, int x, int y) { * */ template inline Expr radical(const NT& n, int m) { - assert(n>=0 && m>=1); + CGAL_assertion(n>=0 && m>=1); if (n == 0 || n == 1 || m == 1) return Expr(n); Polynomial Q(m); diff --git a/CGAL_Core/include/CGAL/CORE/Filter.h b/CGAL_Core/include/CGAL/CORE/Filter.h index 198da10c4d0..4a8ff2dea7b 100644 --- a/CGAL_Core/include/CGAL/CORE/Filter.h +++ b/CGAL_Core/include/CGAL/CORE/Filter.h @@ -39,6 +39,7 @@ #define _CORE_FILTER_H_ #include +#include #include #include @@ -111,7 +112,7 @@ public: before call this function.) */ int sign() const { #ifdef CORE_DEBUG - assert(isOK()); + CGAL_assertion(isOK()); #endif if (fpVal == 0.0) return 0; diff --git a/CGAL_Core/include/CGAL/CORE/MemoryPool.h b/CGAL_Core/include/CGAL/CORE/MemoryPool.h index f3f4c2f3da3..dd47f53a9d9 100644 --- a/CGAL_Core/include/CGAL/CORE/MemoryPool.h +++ b/CGAL_Core/include/CGAL/CORE/MemoryPool.h @@ -36,6 +36,7 @@ #include // for placement new #include +#include namespace CORE { @@ -96,7 +97,7 @@ void* MemoryPool< T, nObjects >::allocate(std::size_t) { template< class T, int nObjects > void MemoryPool< T, nObjects >::free(void* t) { - assert(t != 0); + CGAL_assertion(t != 0); if (t == 0) return; // for safety // recycle the object memory, by putting it back into the chain diff --git a/CGAL_Core/include/CGAL/CORE/poly/Curves.tcc b/CGAL_Core/include/CGAL/CORE/poly/Curves.tcc index 45895466a0e..9e89be0322a 100644 --- a/CGAL_Core/include/CGAL/CORE/poly/Curves.tcc +++ b/CGAL_Core/include/CGAL/CORE/poly/Curves.tcc @@ -192,7 +192,7 @@ BiPoly::~BiPoly(){ //Sets the input BiPoly to X^n template void BiPoly::constructX(int n, BiPoly& P){ - assert(n>= -1); + CGAL_assertion(n>= -1); P.deleteCoeffX();//Clear the present coeffecients Polynomial q(n);//Nominal degree n q.setCoeff(n,NT(1)); @@ -807,7 +807,7 @@ BiPoly & BiPoly::differentiateX() { template BiPoly & BiPoly::differentiateXY(int m, int n) {//m times wrt X and n times wrt Y - assert(m >=0); assert(n >=0); + CGAL_assertion(m >=0); CGAL_assertion(n >=0); for(int i=1; i <=m; i++) (*this).differentiateX(); for(int i=1; i <=n; i++) @@ -1158,7 +1158,7 @@ int Curve::verticalIntersections(const BigFloat & x, BFVecInterval & vI, // This returns a NULL vI, which should be caught by caller Polynomial PY = this->yExprPolynomial(x); // should be replaced - // assert(x.isExact()); + // CGAL_assertion(x.isExact()); // Polynomial PY = yBFPolynomial(x); // unstable still d = PY.getTrueDegree(); @@ -1205,9 +1205,9 @@ int Curve::plot( BigFloat eps, BigFloat x1, const char* filename[] = {"data/input", "data/plot", "data/plot2"}; - assert(eps.isExact()); // important for plotting... - assert(x1.isExact()); - assert(y1.isExact()); + CGAL_assertion(eps.isExact()); // important for plotting... + CGAL_assertion(x1.isExact()); + CGAL_assertion(y1.isExact()); ofstream outFile; outFile.open(filename[fileNo]); // ought to check if open is successful! @@ -1230,7 +1230,7 @@ int Curve::plot( BigFloat eps, BigFloat x1, outFile << "0.99 \t 0.99 \t 0.99" << std::endl; outFile << 0 << "\t" << y1 << std::endl; outFile << 0 << "\t" << y2 << std::endl; - // assert(eps>0) + // CGAL_assertion(eps>0) int aprec = -(eps.lMSB()).toLong(); // By definition, eps.lMSB() <= lg(eps) BigFloat xCurr = x1; diff --git a/CGAL_Core/include/CGAL/CORE/poly/Poly.h b/CGAL_Core/include/CGAL/CORE/poly/Poly.h index 72a0c3fd49c..83cd7a2fe86 100644 --- a/CGAL_Core/include/CGAL/CORE/poly/Poly.h +++ b/CGAL_Core/include/CGAL/CORE/poly/Poly.h @@ -60,6 +60,7 @@ #include #include #include +#include namespace CORE { using namespace std; @@ -412,7 +413,7 @@ template < class NT > CORE_INLINE const NT& Polynomial::getCoeff(int i) const { //if (i > degree) return NULL; - assert(i <= degree); + CGAL_assertion(i <= degree); return coeff[i]; } // set functions diff --git a/CGAL_Core/include/CGAL/CORE/poly/Poly.tcc b/CGAL_Core/include/CGAL/CORE/poly/Poly.tcc index d5ccb582e5f..8112417a132 100644 --- a/CGAL_Core/include/CGAL/CORE/poly/Poly.tcc +++ b/CGAL_Core/include/CGAL/CORE/poly/Poly.tcc @@ -67,7 +67,7 @@ Polynomial::Polynomial(void) { //Creates a polynomial with nominal degree n template Polynomial::Polynomial(int n) { - assert(n>= -1); + CGAL_assertion(n>= -1); degree = n; if (n == -1) return; // return the zero polynomial! @@ -80,7 +80,7 @@ Polynomial::Polynomial(int n) { template Polynomial::Polynomial(int n, const NT * c) { - //assert("array c has n+1 elements"); + //CGAL_assertion("array c has n+1 elements"); degree = n; if (n >= 0) { coeff = new NT[n+1]; @@ -113,7 +113,7 @@ Polynomial::Polynomial(const Polynomial & p):degree(-1) { /////////////////////////////////////// template Polynomial::Polynomial(int n, const char * s[]) { - //assert("array s has n+1 elements"); + //CGAL_assertion("array s has n+1 elements"); degree = n; if (n >= 0) { coeff = new NT[n+1]; @@ -826,7 +826,7 @@ template <> CORE_INLINE BigFloat Polynomial::evalApprox(const BigFloat& /*f*/, const extLong& /*r*/, const extLong& /*a*/) const { // evaluation - assert(0); + CGAL_assertion(0); return BigFloat(0); } @@ -861,7 +861,7 @@ BigFloat Polynomial::evalApprox(const BigFloat& /*f*/, template BigFloat Polynomial::evalExactSign(const BigFloat& val, const extLong& oldMSB) const { - assert(val.isExact()); + CGAL_assertion(val.isExact()); if (getTrueDegree() == -1) return BigFloat(0); @@ -1063,7 +1063,7 @@ Polynomial & Polynomial::differentiate() { // self-differentiation // multi-differentiate template Polynomial & Polynomial::differentiate(int n) { - assert(n >= 0); + CGAL_assertion(n >= 0); for (int i=1; i<=n; i++) this->differentiate(); return *this; @@ -1128,7 +1128,7 @@ template Polynomial & Polynomial::primPart() { // ASSERT: GCD must be provided by NT int d = getTrueDegree(); - assert (d >= 0); + CGAL_assertion (d >= 0); if (d == 0) { if (coeff[0] > 0) coeff[0] = 1; else coeff[0] = -1; @@ -1371,7 +1371,7 @@ Polynomial differentiate(const Polynomial & p) { // differentiate template Polynomial differentiate(const Polynomial & p, int n) {//multi-differentiate Polynomial q(p); - assert(n >= 0); + CGAL_assertion(n >= 0); for (int i=1; i<=n; i++) q.differentiate(); return q; @@ -1491,7 +1491,7 @@ NT res(Polynomial p, Polynomial q) { template NT psc(int i,Polynomial p, Polynomial q) { - assert(i >= 0); + CGAL_assertion(i >= 0); if(i == 0) return res(p,q); diff --git a/CGAL_Core/include/CGAL/CORE/poly/Sturm.h b/CGAL_Core/include/CGAL/CORE/poly/Sturm.h index 14321f60c69..28024e99a8a 100644 --- a/CGAL_Core/include/CGAL/CORE/poly/Sturm.h +++ b/CGAL_Core/include/CGAL/CORE/poly/Sturm.h @@ -59,6 +59,7 @@ #ifndef CORE_STURM_H #define CORE_STURM_H +#include #include "CGAL/CORE/BigFloat.h" #include "CGAL/CORE/Expr.h" #include "CGAL/CORE/poly/Poly.h" @@ -205,7 +206,7 @@ public: // where sx = sign of evaluating seq[0] at x // PRE-CONDITION: sx != 0 and len > 0 int signVariations(const BigFloat & x, int sx) const { - assert((sx != 0) && (len >0)); + CGAL_assertion((sx != 0) && (len >0)); int cnt = 0; int last_sign = sx; for (int i=1; i<=len; i++) {// Chee (4/29/04): Bug fix, @@ -237,7 +238,7 @@ public: if (len <= 0) return len; int cnt = 0; int last_sign = sign(seq[0].coeff[seq[0].getTrueDegree()]); - assert(last_sign != 0); + CGAL_assertion(last_sign != 0); for (int i=1; i<=len; i++) { int sgn = sign(seq[i].coeff[seq[i].getTrueDegree()]); if (sgn*last_sign < 0) @@ -255,7 +256,7 @@ public: int last_sign = sign(seq[0].coeff[seq[0].getTrueDegree()]); if (seq[0].getTrueDegree() % 2 != 0) last_sign *= -1; - assert(last_sign != 0); + CGAL_assertion(last_sign != 0); for (int i=1; i<=len; i++) { int parity = (seq[i].getTrueDegree() % 2 == 0) ? 1 : -1; int sgn = parity * sign(seq[i].coeff[seq[i].getTrueDegree()]); @@ -275,7 +276,7 @@ public: // "x.makeExact(); y.makeExact()" before calling]. /////////////////////////////////////////// int numberOfRoots(const BigFloat &x, const BigFloat &y) const { - assert(x <= y); // we allow x=y + CGAL_assertion(x <= y); // we allow x=y if (len <= 0) return len; // return of -1 means infinity of roots! int signx = sign(seq[0].evalExactSign(x)); if (x == y) return ((signx == 0) ? 1 : 0); @@ -354,7 +355,7 @@ public: */ void isolateRoots(const BigFloat &x, const BigFloat &y, BFVecInterval &v) const { - assert(x<=y); + CGAL_assertion(x<=y); int n = numberOfRoots(x,y); if (n == 0) return; @@ -767,7 +768,7 @@ public: // says that z is a robust approximate zero). // bool smaleBoundTest(const BigFloat& z){ - assert(z.isExact()); // the bound only makes sense for exact z + CGAL_assertion(z.isExact()); // the bound only makes sense for exact z #ifdef CORE_DEBUG std::cout <<"Computing Smale's bound = " << std::endl; @@ -869,7 +870,7 @@ std::cout << "In newtonRefine, input J=" << J.first return J; } - assert( leftSign * rightSign < 0 ); + CGAL_assertion( leftSign * rightSign < 0 ); //N is number of times Newton is called without checking // whether the result is still in the interval or not @@ -1060,7 +1061,7 @@ std::cout << "In newtonRefine, input J=" << J.first << J.first.err() << " Err at end = " << J.second.err() << std::endl; #endif - assert( (seq[0].evalExactSign(J.first) * seq[0].evalExactSign(J.second) <= 0) ); + CGAL_assertion( (seq[0].evalExactSign(J.first) * seq[0].evalExactSign(J.second) <= 0) ); #ifdef CORE_DEBUG_NEWTON if (seq[0].evalExactSign(J.first) * seq[0].evalExactSign(J.second) > 0) diff --git a/CGAL_ipelets/include/CGAL/CGAL_Ipelet_base_v6.h b/CGAL_ipelets/include/CGAL/CGAL_Ipelet_base_v6.h index 3b23c8fcb97..6464f2f266a 100644 --- a/CGAL_ipelets/include/CGAL/CGAL_Ipelet_base_v6.h +++ b/CGAL_ipelets/include/CGAL/CGAL_Ipelet_base_v6.h @@ -37,6 +37,7 @@ typedef unsigned int uint; #include #include #include +#include #include @@ -538,10 +539,10 @@ public: ++next_s; if (next_s==map_theta.end()) next_s=map_theta.begin(); do{ if (current->second.first==OTRG) return; - assert(current->second.first==SRC); + CGAL_assertion(current->second.first==SRC); draw_in_ipe(Circular_arc_2(circle,*(current->second.second),*(next_s->second.second),CGAL::COUNTERCLOCKWISE)); if (next_s->second.first==OTRG) return; - assert(next_s->second.first==TRG); + CGAL_assertion(next_s->second.first==TRG); ++next_s; if (next_s==map_theta.end()) next_s=map_theta.begin(); current=next_s; ++next_s; if (next_s==map_theta.end()) next_s=map_theta.begin(); @@ -843,7 +844,7 @@ public: switch (ints.size()){ case 1: ok=CGAL::assign(tmp_pt,ints[0]); - assert(ok); + CGAL_assertion(ok); points.push_back(tmp_pt); index=points.size()-1; indices[i]=index; @@ -852,12 +853,12 @@ public: case 2: int right_ind=i<2?0:1; ok=CGAL::assign(tmp_pt,ints[right_ind]); - assert(ok); + CGAL_assertion(ok); points.push_back(tmp_pt); index=points.size()-1; indices[i]=index; ok=CGAL::assign(tmp_pt,ints[(right_ind+1)%2]); - assert(ok); + CGAL_assertion(ok); points.push_back(tmp_pt); index=points.size()-1; indices[(i+1)%4+4]=index; @@ -900,7 +901,7 @@ public: *out++=build_arc(exact_circle,points[ indices[pair[1]] ].first,points[ indices[pair[0]] ].first); return; } - assert (rem_pt==0); + CGAL_assertion (rem_pt==0); } }; diff --git a/CGAL_ipelets/include/CGAL/CGAL_Ipelet_base_v7.h b/CGAL_ipelets/include/CGAL/CGAL_Ipelet_base_v7.h index 4a2c4153bff..d2202a01c49 100644 --- a/CGAL_ipelets/include/CGAL/CGAL_Ipelet_base_v7.h +++ b/CGAL_ipelets/include/CGAL/CGAL_Ipelet_base_v7.h @@ -37,6 +37,8 @@ typedef unsigned int uint; #include #include #include +#include +#include #include @@ -546,10 +548,10 @@ public: ++next_s; if (next_s==map_theta.end()) next_s=map_theta.begin(); do{ if (current->second.first==OTRG) return; - assert(current->second.first==SRC); + CGAL_assertion(current->second.first==SRC); draw_in_ipe(Circular_arc_2(circle,*(current->second.second),*(next_s->second.second),CGAL::COUNTERCLOCKWISE)); if (next_s->second.first==OTRG) return; - assert(next_s->second.first==TRG); + CGAL_assertion(next_s->second.first==TRG); ++next_s; if (next_s==map_theta.end()) next_s=map_theta.begin(); current=next_s; ++next_s; if (next_s==map_theta.end()) next_s=map_theta.begin(); @@ -848,7 +850,7 @@ public: switch (ints.size()){ case 1: ok=CGAL::assign(tmp_pt,ints[0]); - assert(ok); + CGAL_assertion(ok); CGAL_USE(ok); points.push_back(tmp_pt); index=points.size()-1; indices[i]=index; @@ -857,12 +859,12 @@ public: case 2: int right_ind=i<2?0:1; ok=CGAL::assign(tmp_pt,ints[right_ind]); - assert(ok); + CGAL_assertion(ok); CGAL_USE(ok); points.push_back(tmp_pt); index=points.size()-1; indices[i]=index; ok=CGAL::assign(tmp_pt,ints[(right_ind+1)%2]); - assert(ok); + CGAL_assertion(ok); CGAL_USE(ok); points.push_back(tmp_pt); index=points.size()-1; indices[(i+1)%4+4]=index; @@ -905,7 +907,7 @@ public: *out++=build_arc(exact_circle,points[ indices[pair[1]] ].first,points[ indices[pair[0]] ].first); return; } - assert (rem_pt==0); + CGAL_assertion (rem_pt==0); } }; diff --git a/Combinatorial_map/include/CGAL/Combinatorial_map.h b/Combinatorial_map/include/CGAL/Combinatorial_map.h index 34cdaf7f0b3..6a84b6ba0a5 100644 --- a/Combinatorial_map/include/CGAL/Combinatorial_map.h +++ b/Combinatorial_map/include/CGAL/Combinatorial_map.h @@ -22,7 +22,6 @@ #include #include -#include #include #include #include @@ -350,6 +349,18 @@ namespace CGAL { bool is_empty() const { return mdarts.empty(); } + friend std::ostream& operator<< (std::ostream& os, const Self& amap) + { + save_combinatorial_map(amap, os); + return os; + } + + friend std::ifstream& operator>> (std::ifstream& is, Self& amap) + { + load_combinatorial_map(is, amap); + return is; + } + /** Create a new dart and add it to the map. * The marks of the darts are initialised with mmask_marks, i.e. the dart * is unmarked for all the marks. diff --git a/Combinatorial_map/include/CGAL/Combinatorial_map_save_load.h b/Combinatorial_map/include/CGAL/Combinatorial_map_save_load.h new file mode 100644 index 00000000000..debd26b66e8 --- /dev/null +++ b/Combinatorial_map/include/CGAL/Combinatorial_map_save_load.h @@ -0,0 +1,800 @@ +// Copyright (c) 2010-2011 CNRS and LIRIS' Establishments (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Guillaume Damiand +// Guillaume Castano +// Pascal Khieu +// +#ifndef CGAL_COMBINATORIAL_MAP_SAVE_LOAD_H +#define CGAL_COMBINATORIAL_MAP_SAVE_LOAD_H + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace CGAL { + + typedef Exact_predicates_inexact_constructions_kernel::Point_3 RPoint_3; + typedef Exact_predicates_exact_constructions_kernel::Point_3 EPoint_3; + + // Tags used in xml tree: + // For darts: + // + // // new dart + // neighbor dart index for beta1 + // ... + // value of dart (optional) + // + // ... + // + // For attributes: + // + // // new type of non void attribute + // type of the info associated + // // new attribute + // dart index + // value of attribute + // + // ... + // + + // Here T is a Dart_const_handle so we don't need & + template + void write_cmap_dart_node(boost::property_tree::ptree & /*node*/, T) + {} + + template + void write_cmap_attribute_node(boost::property_tree::ptree & /*node*/, const T&) + {} + + inline + void write_cmap_attribute_node(boost::property_tree::ptree & node, + char val) + {node.add("v",val);} + inline + void write_cmap_attribute_node(boost::property_tree::ptree & node, + unsigned char val) + {node.add("v",val);} + inline + void write_cmap_attribute_node(boost::property_tree::ptree & node, + short int val) + {node.add("v",val);} + inline + void write_cmap_attribute_node(boost::property_tree::ptree & node, + unsigned short int val) + {node.add("v",val);} + inline + void write_cmap_attribute_node(boost::property_tree::ptree & node, + int val) + {node.add("v",val);} + inline + void write_cmap_attribute_node(boost::property_tree::ptree & node, + unsigned int val) + {node.add("v",val);} + inline + void write_cmap_attribute_node(boost::property_tree::ptree & node, + long int val) + {node.add("v",val);} + inline + void write_cmap_attribute_node(boost::property_tree::ptree & node, + unsigned long int val) + {node.add("v",val);} + inline + void write_cmap_attribute_node(boost::property_tree::ptree & node, + float val) + {node.add("v",val);} + inline + void write_cmap_attribute_node(boost::property_tree::ptree & node, + double val) + {node.add("v",val);} + inline + void write_cmap_attribute_node(boost::property_tree::ptree & node, + long double val) + {node.add("v",val);} + inline + void write_cmap_attribute_node(boost::property_tree::ptree & node, + bool val) + {node.add("v",val);} + inline + void write_cmap_attribute_node(boost::property_tree::ptree & node, + const std::string& val) + {node.add("v",val);} + inline + void write_cmap_attribute_node(boost::property_tree::ptree & node, + const RPoint_3& val) + { + node.add("p.x",val.x()); + node.add("p.y",val.y()); + node.add("p.z",val.z()); + } + inline + void write_cmap_attribute_node(boost::property_tree::ptree & node, + const EPoint_3& val) + { + node.add("p.x",CGAL::to_double(val.x())); + node.add("p.y",CGAL::to_double(val.y())); + node.add("p.z",CGAL::to_double(val.z())); + } + + template::type>::value, + bool WithPoint=CGAL::Is_attribute_has_point + ::type >::value > + struct My_functor_cmap_save_one_attrib; + + // An attrib with point and with info + template + struct My_functor_cmap_save_one_attrib + { + static void run(const CMap* amap, boost::property_tree::ptree* ptree, + std::map* myDarts) + { + // to check all i-cells of the map + typename CMap::template Attribute_range::type::const_iterator + it_attrib, itend_attrib; + it_attrib=amap->template attributes().begin(); + itend_attrib=amap->template attributes().end(); + + // add dimension & type + boost::property_tree::ptree & ndim = ptree->add("dimension", ""); + ndim.put(".index", i); + ndim.add("type", typeid(typename CMap::template Attribute_type::type::Info).name()); + ndim.add("type_point", typeid(RPoint_3).name()); + + // for every attribute of the dimension + for (; it_attrib!=itend_attrib; ++it_attrib) + { + // make composant, dart and property node + boost::property_tree::ptree & nattr = ndim.add("a", ""); + /* boost::property_tree::ptree & ndarts = */ + nattr.add("d", (*myDarts)[it_attrib->dart()]); + + // update property node to add a value node (from basic or custom type + write_cmap_attribute_node(nattr, it_attrib->info()); + write_cmap_attribute_node(nattr, it_attrib->point()); + } + } + }; + + // An attribute with point and without info + template + struct My_functor_cmap_save_one_attrib + { + static void run(const CMap* amap, boost::property_tree::ptree* ptree, + std::map* myDarts) + { + // to check all i-cells of the map + typename CMap::template Attribute_range::type::const_iterator + it_attrib, itend_attrib; + it_attrib=amap->template attributes().begin(); + itend_attrib=amap->template attributes().end(); + + // add dimension & type + boost::property_tree::ptree & ndim = ptree->add("dimension", ""); + ndim.put(".index", i); + ndim.add("type", "void"); + ndim.add("type_point", typeid(RPoint_3).name()); + + // for every attribute of the dimension + for (; it_attrib!=itend_attrib; ++it_attrib) + { + // make composant, dart and property node + boost::property_tree::ptree & nattr = ndim.add("a", ""); + /* boost::property_tree::ptree & ndarts = */ + nattr.add("d", (*myDarts)[it_attrib->dart()]); + + // update property node to add a value node (from basic or custom type + write_cmap_attribute_node(nattr, it_attrib->point()); + } + } + }; + + // An attribute without point and with info + template + struct My_functor_cmap_save_one_attrib + { + static void run(const CMap* amap, boost::property_tree::ptree* ptree, + std::map* myDarts) + { + // to check all i-cells of the map + typename CMap::template Attribute_range::type::const_iterator + it_attrib, itend_attrib; + it_attrib=amap->template attributes().begin(); + itend_attrib=amap->template attributes().end(); + + // add dimension & type + boost::property_tree::ptree & ndim = ptree->add("dimension", ""); + ndim.put(".index", i); + ndim.add("type", typeid(typename CMap::template Attribute_type::type::Info).name()); + ndim.add("type_point", "void"); + + // for every attribute of the dimension + for (; it_attrib!=itend_attrib; ++it_attrib) + { + // make composant, dart and property node + boost::property_tree::ptree & nattr = ndim.add("a", ""); + /* boost::property_tree::ptree & ndarts = */ + nattr.add("d", (*myDarts)[it_attrib->dart()]); + + // update property node to add a value node (from basic or custom type + write_cmap_attribute_node(nattr, it_attrib->info()); + } + } + }; + + // An attrib without point and without info + template + struct My_functor_cmap_save_one_attrib + { + static void run(const CMap* amap, boost::property_tree::ptree* ptree, + std::map* myDarts) + { + // to check all i-cells of the map + typename CMap::template Attribute_range::type::const_iterator + it_attrib, itend_attrib; + it_attrib=amap->template attributes().begin(); + itend_attrib=amap->template attributes().end(); + + // add dimension & type + boost::property_tree::ptree & ndim = ptree->add("dimension", ""); + ndim.put(".index", i); + ndim.add("type", "void"); + ndim.add("type_point", "void"); + + // for every attribute of the dimension + for (; it_attrib!=itend_attrib; ++it_attrib) + { + // make composant, dart and property node + boost::property_tree::ptree & nattr = ndim.add("a", ""); + /* boost::property_tree::ptree & ndarts = */ + nattr.add("d", (*myDarts)[it_attrib->dart()]); + } + } + }; + + template + struct My_functor_cmap_save_attrib + { + template + static void run(const CMap* amap, boost::property_tree::ptree* ptree, + std::map* myDarts) + { + My_functor_cmap_save_one_attrib::run(amap, ptree, myDarts); + } + }; + + template < class CMap > + boost::property_tree::ptree cmap_save_darts + (const CMap& amap, std::map& myDarts) + { + assert( myDarts.empty() ); + + // First we numbered each dart by using the std::map. + typename CMap::Dart_range::const_iterator it(amap.darts().begin()); + for(typename CMap::size_type num=1; num<=amap.number_of_darts(); + ++num, ++it) + { + myDarts[it] = num; + } + + // make a tree + using boost::property_tree::ptree; + ptree pt; + + // Now we save each dart, and its neighbors. + it=amap.darts().begin(); + for(typename CMap::size_type num=0; num.i", dim); + } + } + + // update property node to add a value node (if user defined its own + // function) + write_cmap_dart_node(ndart, it); + } + + return pt; + } + + template < class CMap > + boost::property_tree::ptree cmap_save_attributes + (const CMap& amap, std::map& myDarts) + { + using boost::property_tree::ptree; + ptree pt; + + // update pt adding nodes containing attributes informations + CMap::Helper::template Foreach_enabled_attributes + >::run(&amap, &pt, &myDarts); + + return pt; + } + + template < class CMap > + bool save_combinatorial_map(const CMap& amap, std::ostream & output) + { + using boost::property_tree::ptree; + ptree data; + + // map dart => number + std::map myDarts; + + // Get darts + ptree pt_darts; + pt_darts = cmap_save_darts(amap, myDarts); + data.add_child("data.darts",pt_darts); + + // Get attributes + ptree pt_attr; + pt_attr = cmap_save_attributes(amap, myDarts); + data.add_child("data.attributes", pt_attr); + + // save data in output + write_xml(output, data); + + return true; + } + + template < class CMap > + bool save_combinatorial_map(const CMap& amap, const char* filename) + { + std::ofstream output(filename); + if (!output) return false; + return save_combinatorial_map(amap, output); + } + + // Here T is a Dart_handle so no need of & + template + void read_cmap_dart_node + (const boost::property_tree::ptree::value_type &/*v*/, T /*val*/) + {} + template + void read_cmap_attribute_node + (const boost::property_tree::ptree::value_type &/*v*/, T &/*val*/) + {} + template<> inline + void read_cmap_attribute_node + (const boost::property_tree::ptree::value_type &v,char &val) + {val=boost::lexical_cast< char >(v.second.data());} + template<> inline + void read_cmap_attribute_node + (const boost::property_tree::ptree::value_type &v,unsigned char &val) + {val=boost::lexical_cast< unsigned char >(v.second.data());} + template<> inline + void read_cmap_attribute_node + (const boost::property_tree::ptree::value_type &v,short int &val) + {val=boost::lexical_cast< short int >(v.second.data());} + template<> inline + void read_cmap_attribute_node + (const boost::property_tree::ptree::value_type &v,unsigned short int &val) + {val=boost::lexical_cast< unsigned short int >(v.second.data());} + template<> inline + void read_cmap_attribute_node + (const boost::property_tree::ptree::value_type &v,int &val) + {val=boost::lexical_cast< int >(v.second.data());} + template<> inline + void read_cmap_attribute_node + (const boost::property_tree::ptree::value_type &v,unsigned int &val) + {val=boost::lexical_cast< unsigned int >(v.second.data());} + template<> inline + void read_cmap_attribute_node + (const boost::property_tree::ptree::value_type &v,long int &val) + {val=boost::lexical_cast< long int >(v.second.data());} + template<> inline + void read_cmap_attribute_node + (const boost::property_tree::ptree::value_type &v,unsigned long int &val) + {val=boost::lexical_cast< unsigned long int >(v.second.data());} + template<> inline + void read_cmap_attribute_node + (const boost::property_tree::ptree::value_type &v,float &val) + {val=boost::lexical_cast< float >(v.second.data());} + template<> inline + void read_cmap_attribute_node + (const boost::property_tree::ptree::value_type &v,double &val) + {val=boost::lexical_cast< double >(v.second.data());} + template<> inline + void read_cmap_attribute_node + (const boost::property_tree::ptree::value_type &v,long double &val) + {val=boost::lexical_cast< long double >(v.second.data());} + template<> inline + void read_cmap_attribute_node + (const boost::property_tree::ptree::value_type &v,bool &val) + {val=boost::lexical_cast< bool >(v.second.data());} + template<> inline + void read_cmap_attribute_node + (const boost::property_tree::ptree::value_type &v,std::string &val) + {val=boost::lexical_cast< std::string >(v.second.data());} + template<> inline + void read_cmap_attribute_node + (const boost::property_tree::ptree::value_type &v,RPoint_3 &val) + { + double x=v.second.get("x"); + double y=v.second.get("y"); + double z=v.second.get("z"); + val = RPoint_3(x,y,z); + } + + template::type>::value, + bool WithPoint=CGAL::Is_attribute_has_point + ::type >::value > + struct My_functor_cmap_load_one_attrib; + + // An attrib with point and with info + template + struct My_functor_cmap_load_one_attrib + { + static void run(const boost::property_tree::ptree& pt, CMap* amap, + const std::vector& myDarts) + { + BOOST_FOREACH( const boost::property_tree::ptree::value_type &v0, + pt.get_child("data.attributes") ) + { + // + if (v0.first == "dimension") + { + int dimension=v0.second.get(".index", -1); + + // if map.dimension == dimension saved in the xml file + if (dimension==i) + { + unsigned int id_dart_cellule=0; + std::string type = v0.second.get("type"); + std::string type_map=std::string + (typeid(typename CMap::template Attribute_type::type::Info).name()); + + std::string ptype = v0.second.get("type_point"); + std::string ptype_map= std::string + (typeid(typename CMap::template Attribute_type::type::Point).name()); + + // std::cout<<"ptype="<("d")-1; + + BOOST_FOREACH(const boost::property_tree::ptree::value_type &v2, + v1.second ) + { + if( type==type_map && v2.first == "v" ) + { + if (myDarts[id_dart_cellule]-> + template attribute()==NULL ) + amap->template set_attribute + (myDarts[id_dart_cellule], + amap->template create_attribute()); + read_cmap_attribute_node + (v2, + myDarts[id_dart_cellule]-> + template attribute()->info()); + } + if( ptype==ptype_map && v2.first == "p" ) + { + if (myDarts[id_dart_cellule]-> + template attribute()==NULL ) + amap->template set_attribute + (myDarts[id_dart_cellule], + amap->template create_attribute()); + read_cmap_attribute_node + (v2, + myDarts[id_dart_cellule]-> + template attribute()->point()); + } + } + } + } + } + } + } + } + }; + + // An attribute with point and without info + template + struct My_functor_cmap_load_one_attrib + { + static void run(const boost::property_tree::ptree& pt, CMap* amap, + const std::vector& myDarts) + { + BOOST_FOREACH( const boost::property_tree::ptree::value_type &v0, + pt.get_child("data.attributes") ) + { + // + if (v0.first == "dimension") + { + int dimension=v0.second.get(".index", -1); + + // if map.dimension == dimension saved in the xml file + if (dimension==i) + { + unsigned int id_dart_cellule=0; + std::string ptype = v0.second.get("type_point"); + std::string type_map= typeid + (typename CMap::template Attribute_type::type::Point).name(); + // std::cout<<"ptype="<("d")-1; + + BOOST_FOREACH(const boost::property_tree::ptree::value_type &v2, + v1.second ) + { + if( v2.first == "p" ) + { + if (myDarts[id_dart_cellule]-> + template attribute()==NULL ) + amap->template set_attribute + (myDarts[id_dart_cellule], + amap->template create_attribute()); + + read_cmap_attribute_node + (v2, + myDarts[id_dart_cellule]-> + template attribute()->point()); + } + } + } + } + } + } + } + } + }; + + // An attribute without point and with info + template + struct My_functor_cmap_load_one_attrib + { + static void run(const boost::property_tree::ptree& pt, CMap* amap, + const std::vector& myDarts) + { + BOOST_FOREACH( const boost::property_tree::ptree::value_type &v0, + pt.get_child("data.attributes") ) + { + // + if (v0.first == "dimension") + { + int dimension=v0.second.get(".index", -1); + + // if map.dimension == dimension saved in the xml file + if (dimension==i) + { + unsigned int id_dart_cellule=0; + std::string ptype = v0.second.get("type"); + std::string type_map= typeid + (typename CMap::template Attribute_type::type::Info).name(); + // std::cout<<"ptype="<("d")-1; + + BOOST_FOREACH(const boost::property_tree::ptree::value_type &v2, + v1.second ) + { + if( v2.first == "v" ) + { + if (myDarts[id_dart_cellule]-> + template attribute()==NULL ) + amap->template set_attribute + (myDarts[id_dart_cellule], + amap->template create_attribute()); + read_cmap_attribute_node + (v2, + myDarts[id_dart_cellule]-> + template attribute()->info()); + } + } + } + } + } + } + } + } + }; + + // An attribute without point and without info + template + struct My_functor_cmap_load_one_attrib + { + static void run(const boost::property_tree::ptree& pt, CMap* amap, + const std::vector& myDarts) + { + BOOST_FOREACH( const boost::property_tree::ptree::value_type &v0, + pt.get_child("data.attributes") ) + { + // + if (v0.first == "dimension") + { + int dimension=v0.second.get(".index", -1); + + // if map.dimension == dimension saved in the xml file + if (dimension==i) + { + unsigned int id_dart_cellule=0; + + BOOST_FOREACH(const boost::property_tree::ptree::value_type &v1, + v0.second ) + { + if( v1.first == "a" ) + { + id_dart_cellule=v1.second.get("d")-1; + + if (myDarts[id_dart_cellule]-> + template attribute()==NULL ) + amap->template set_attribute + (myDarts[id_dart_cellule], + amap->template create_attribute()); + } + } + } + } + } + } + }; + + /** Functor called to load i-attributes. + * @param pt a boost::property_tree::ptree load from an xml file + * @param amap a pointer to the map to load into + * @param myDarts an array of Dart_handle st myDarts[i] is the ith dart. + */ + template + struct My_functor_cmap_load_attrib + { + template + static void run(const boost::property_tree::ptree& pt, CMap* amap, + const std::vector& myDarts) + { + My_functor_cmap_load_one_attrib::run(pt, amap, myDarts); + } + }; + + template < class CMap > + bool cmap_load_darts(boost::property_tree::ptree &pt, CMap& amap, + std::vector& myDarts) + { + // use a boost::property_tree + using boost::property_tree::ptree; + + // make darts + BOOST_FOREACH( const ptree::value_type &v, pt.get_child("data.darts") ) + { + if( v.first == "d" ) + myDarts.push_back(amap.create_dart()); + } + + // update beta links + unsigned int index; + unsigned int currentDartInt = 0; + unsigned int nextDartInt; + + BOOST_FOREACH( const ptree::value_type &v, pt.get_child("data.darts") ) + { + if( v.first == "d" ) + { + BOOST_FOREACH( const ptree::value_type &v2, v.second ) + { + if (v2.first == "b") + { + index = v2.second.get(".i", 0); + nextDartInt = boost::lexical_cast< int >(v2.second.data())-1; + + if ( index<=amap.dimension ) + { + // A->B + amap.basic_link_beta(myDarts[currentDartInt], + myDarts[nextDartInt], + index); + + //B->A + amap.basic_link_beta(myDarts[nextDartInt], + myDarts[currentDartInt], + CGAL_BETAINV(index)); + } + } + else if (v2.first=="v") + read_cmap_dart_node(v2,myDarts[currentDartInt]); + } + } + ++currentDartInt; + } + + return true; + } + + template < class CMap > + void cmap_load_attributes(const boost::property_tree::ptree& pt, CMap& amap, + const std::vector& myDarts) + { + CMap::Helper::template Foreach_enabled_attributes + >::run(pt,&amap,myDarts); + } + + template < class CMap > + bool load_combinatorial_map(std::ifstream & input, CMap& amap) + { + using boost::property_tree::ptree; + ptree pt; + read_xml(input, pt); + std::vector myDarts; + cmap_load_darts(pt,amap,myDarts); + cmap_load_attributes(pt,amap,myDarts); + return true; + } + + template < class CMap > + bool load_combinatorial_map(const char* filename, CMap& amap) + { + std::ifstream input(filename); + if (!input) return false; + return load_combinatorial_map(input, amap); + } + +} // namespace CGAL + +#endif // CGAL_COMBINATORIAL_MAP_SAVE_LOAD_H // +// EOF // diff --git a/Combinatorial_map/test/Combinatorial_map/Combinatorial_map_2_test.h b/Combinatorial_map/test/Combinatorial_map/Combinatorial_map_2_test.h index 21c5801f1f5..998fd602e74 100644 --- a/Combinatorial_map/test/Combinatorial_map/Combinatorial_map_2_test.h +++ b/Combinatorial_map/test/Combinatorial_map/Combinatorial_map_2_test.h @@ -55,14 +55,10 @@ bool test2D() dh = map.create_dart (); dh2 = map.create_dart(); - if (!map.is_dart_used(dh) ) return false; - if ( map.is_valid() ) cout << "Map valid." << endl; cout << "Nombre de brins : " << map.number_of_darts() << endl; map.clear(); - if ( map.is_dart_used(dh) ) return false; - cout << "***************************** TEST BASIC CREATION 2D DONE." << endl; diff --git a/Convex_hull_3/include/CGAL/Convex_hull_3/dual/halfspace_intersection_with_constructions_3.h b/Convex_hull_3/include/CGAL/Convex_hull_3/dual/halfspace_intersection_with_constructions_3.h index 66110f949e8..51ab1b6094c 100644 --- a/Convex_hull_3/include/CGAL/Convex_hull_3/dual/halfspace_intersection_with_constructions_3.h +++ b/Convex_hull_3/include/CGAL/Convex_hull_3/dual/halfspace_intersection_with_constructions_3.h @@ -26,6 +26,7 @@ #include #include #include +#include // For interior_polyhedron_3 #include @@ -87,7 +88,7 @@ namespace CGAL for (Vertex_const_iterator it = _primal.vertices_begin(); it != _primal.vertices_end(); ++it) { - assert (it->is_bivalent() == false); + CGAL_assertion (it->is_bivalent() == false); typename Polyhedron::Halfedge_around_vertex_const_circulator h0 = it->vertex_begin(), hf = h0; diff --git a/Convex_hull_3/include/CGAL/Convex_hull_3/dual/interior_polyhedron_3.h b/Convex_hull_3/include/CGAL/Convex_hull_3/dual/interior_polyhedron_3.h index 3bc2c0ec36f..64f43823808 100644 --- a/Convex_hull_3/include/CGAL/Convex_hull_3/dual/interior_polyhedron_3.h +++ b/Convex_hull_3/include/CGAL/Convex_hull_3/dual/interior_polyhedron_3.h @@ -28,6 +28,7 @@ #include #include #include +#include // Description taken from http://www.qhull.org/html/qhalf.htm @@ -109,10 +110,10 @@ class Interior_polyhedron_3 { const double cj = CGAL::to_double(plane.c()); const double dj = CGAL::to_double(plane.d()); - assert(!isinf(aj)); - assert(!isinf(bj)); - assert(!isinf(cj)); - assert(!isinf(dj)); + CGAL_assertion(!isinf(aj)); + CGAL_assertion(!isinf(bj)); + CGAL_assertion(!isinf(cj)); + CGAL_assertion(!isinf(dj)); // plane defined the halfspace: aj * x1 + bj * x2 + cj * x3 + dj <= 0 // <=> - (aj * x1 + bj * x2 + cj * x3 + dj) >= 0 diff --git a/Convex_hull_3/include/CGAL/convex_hull_3.h b/Convex_hull_3/include/CGAL/convex_hull_3.h index a93bbe7f997..b828c791970 100644 --- a/Convex_hull_3/include/CGAL/convex_hull_3.h +++ b/Convex_hull_3/include/CGAL/convex_hull_3.h @@ -552,7 +552,7 @@ ch_quickhull_3_scan(TDS_2& tds, border.erase(it); while(! border.empty()){ it = border.find(e.first->vertex(TDS_2::ccw(e.second))); - assert(it != border.end()); + CGAL_ch_assertion(it != border.end()); e = it->second; e.first->info() = 0; edges.push_back(e); diff --git a/Documentation/CMakeLists.txt b/Documentation/CMakeLists.txt index 6a7f67a9639..b4fa742805d 100644 --- a/Documentation/CMakeLists.txt +++ b/Documentation/CMakeLists.txt @@ -35,7 +35,6 @@ function(configure_doxygen_package CGAL_PACKAGE_NAME) file(APPEND ${CGAL_DOC_PACKAGE_DEFAULTS} "GENERATE_BUGLIST = NO\n") endif() - file(APPEND ${CGAL_DOC_PACKAGE_DEFAULTS} "IMAGE_PATH = ${CGAL_PACKAGE_DIR}/doc/${CGAL_PACKAGE_NAME}/fig\n") file(APPEND ${CGAL_DOC_PACKAGE_DEFAULTS} "EXAMPLE_PATH = ${CGAL_PACKAGE_DIR}/examples\n") file(APPEND ${CGAL_DOC_PACKAGE_DEFAULTS} "GENERATE_TAGFILE = ${CGAL_DOC_TAG_GEN_DIR}/${CGAL_PACKAGE_NAME}.tag\n") file(APPEND ${CGAL_DOC_PACKAGE_DEFAULTS} "STRIP_FROM_PATH = ${CGAL_PACKAGE_DIR}/doc/${CGAL_PACKAGE_NAME}/\n") @@ -44,19 +43,45 @@ function(configure_doxygen_package CGAL_PACKAGE_NAME) 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") - - # figure out the dependencies - if(EXISTS ${CGAL_PACKAGE_DIR}/doc/${CGAL_PACKAGE_NAME}/dependencies) - file(STRINGS ${CGAL_PACKAGE_DIR}/doc/${CGAL_PACKAGE_NAME}/dependencies DEPENDENCIES) + + # IMAGE_PATH is set by default. For Documentation, we generate the extra path using packages.txt + set(IMAGE_PATH_VALUES "IMAGE_PATH = ${CGAL_PACKAGE_DIR}/doc/${CGAL_PACKAGE_NAME}/fig") + set(DEPENDENCIES "") + # figure out the dependencies, using the file `dependencies` or `packages.txt` for Documentation + if (${CGAL_PACKAGE_NAME} STREQUAL "Documentation") + set(PackageFile ${CGAL_PACKAGE_DIR}/doc/${CGAL_PACKAGE_NAME}/packages.txt) + file(READ ${PackageFile} Entries) + string(REPLACE "\n" ";" EntriesAsList ${Entries}) + foreach(Line ${EntriesAsList}) + if("${Line}" MATCHES "^\\\\package_listing{.+}$") + string(REGEX REPLACE "^\\\\package_listing{(.*/)?(.+)}$" "\\2" PKG "${Line}") + list(APPEND DEPENDENCIES ${PKG}) + # update IMAGE_PATH + SET(PKG_DIR "${PKG}") + if("${Line}" MATCHES "^\\\\package_listing{.+/.+}$") + string(REGEX REPLACE "^\\\\package_listing{(.+)/.+}$" "\\1" PKG_DIR "${Line}") + endif() + SET(IMG_DIR "${CMAKE_SOURCE_DIR}/${PKG_DIR}/doc/${PKG}/fig") + if(EXISTS ${IMG_DIR}) + string(CONCAT IMAGE_PATH_VALUES "${IMAGE_PATH_VALUES}" " \\\n ${IMG_DIR}" ) + endif() + endif() + endforeach() + set(DOCUMENTATION_DEPENDENCIES ${DEPENDENCIES} PARENT_SCOPE) else() - set(DEPENDENCIES "") + if(EXISTS ${CGAL_PACKAGE_DIR}/doc/${CGAL_PACKAGE_NAME}/dependencies) + file(STRINGS ${CGAL_PACKAGE_DIR}/doc/${CGAL_PACKAGE_NAME}/dependencies DEPENDENCIES) + endif() endif() - + foreach(depend ${DEPENDENCIES}) file(APPEND ${CGAL_DOC_PACKAGE_DEFAULTS} "TAGFILES += ${CGAL_DOC_TAG_DIR}/${depend}.tag=../${depend}\n") endforeach() + #now write IMAGE_PATH + file(APPEND ${CGAL_DOC_PACKAGE_DEFAULTS} "${IMAGE_PATH_VALUES}\n") + configure_file(${CGAL_PACKAGE_DIR}/doc/${CGAL_PACKAGE_NAME}/Doxyfile.in ${CGAL_DOC_DXY_DIR}/${CGAL_PACKAGE_NAME}.dxy) @@ -197,8 +222,7 @@ if(DOXYGEN_FOUND) set_target_properties(Documentation_doc PROPERTIES FOLDER Documentation) # hard-code that doc depends on all packages - file(STRINGS ${CMAKE_SOURCE_DIR}/Documentation/doc/Documentation/dependencies DEPENDENCIES) - foreach(depend ${DEPENDENCIES}) + foreach(depend ${DOCUMENTATION_DEPENDENCIES}) add_dependencies(doc_pre ${depend}_internal_doxygen_run) add_dependencies(doc_post ${depend}_copy_doc_tags) add_dependencies(${depend}_copy_doc_tags doc_pre) diff --git a/Documentation/doc/Documentation/Doxyfile.in b/Documentation/doc/Documentation/Doxyfile.in index d0fab13cedd..cd73cb2258a 100644 --- a/Documentation/doc/Documentation/Doxyfile.in +++ b/Documentation/doc/Documentation/Doxyfile.in @@ -30,99 +30,3 @@ SEARCHENGINE = true ALIASES += "cgalPkgDescriptionBegin{2}=\subsection \2 \1" ALIASES += "cgalPkgManuals{2}=

\ref \1 \"User Manual\" \ref \2 \"Reference Manual\"
" ALIASES += "cgalReleaseNumber=${CGAL_CREATED_VERSION_NUM}" - -# all image paths, maybe auto-generate this? -IMAGE_PATH = ${CMAKE_SOURCE_DIR}/Documentation/doc/Documentation/fig \ - ${CMAKE_SOURCE_DIR}/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/fig \ - ${CMAKE_SOURCE_DIR}/Algebraic_foundations/doc/Algebraic_foundations/fig \ - ${CMAKE_SOURCE_DIR}/AABB_tree/doc/AABB_tree/fig \ - ${CMAKE_SOURCE_DIR}/Polygon/doc/Polygon/fig \ - ${CMAKE_SOURCE_DIR}/Polygon_mesh_processing/doc/Polygon_mesh_processing/fig \ - ${CMAKE_SOURCE_DIR}/Polyline_simplification_2/doc/Polyline_simplification_2/fig \ - ${CMAKE_SOURCE_DIR}/Number_types/doc/Number_types/fig \ - ${CMAKE_SOURCE_DIR}/Alpha_shapes_2/doc/Alpha_shapes_2/fig \ - ${CMAKE_SOURCE_DIR}/Alpha_shapes_3/doc/Alpha_shapes_3/fig \ - ${CMAKE_SOURCE_DIR}/Apollonius_graph_2/doc/Apollonius_graph_2/fig \ - ${CMAKE_SOURCE_DIR}/Bounding_volumes/doc/Bounding_volumes/fig \ - ${CMAKE_SOURCE_DIR}/Inscribed_areas/doc/Inscribed_areas/fig \ - ${CMAKE_SOURCE_DIR}/Matrix_search/doc/Matrix_search/fig \ - ${CMAKE_SOURCE_DIR}/Box_intersection_d/doc/Box_intersection_d/fig \ - ${CMAKE_SOURCE_DIR}/CGAL_ipelets/doc/CGAL_ipelets/fig \ - ${CMAKE_SOURCE_DIR}/Circulator/doc/Circulator/fig \ - ${CMAKE_SOURCE_DIR}/Convex_decomposition_3/doc/Convex_decomposition_3/fig \ - ${CMAKE_SOURCE_DIR}/Convex_hull_2/doc/Convex_hull_2/fig \ - ${CMAKE_SOURCE_DIR}/Convex_hull_3/doc/Convex_hull_3/fig \ - ${CMAKE_SOURCE_DIR}/Convex_hull_d/doc/Convex_hull_d/fig \ - ${CMAKE_SOURCE_DIR}/Envelope_2/doc/Envelope_2/fig \ - ${CMAKE_SOURCE_DIR}/Envelope_3/doc/Envelope_3/fig \ - ${CMAKE_SOURCE_DIR}/Generator/doc/Generator/fig \ - ${CMAKE_SOURCE_DIR}/Geomview/doc/Geomview/fig \ - ${CMAKE_SOURCE_DIR}/GraphicsView/doc/GraphicsView/fig \ - ${CMAKE_SOURCE_DIR}/HalfedgeDS/doc/HalfedgeDS/fig \ - ${CMAKE_SOURCE_DIR}/BGL/doc/BGL/fig \ - ${CMAKE_SOURCE_DIR}/Combinatorial_map/doc/Combinatorial_map/fig \ - ${CMAKE_SOURCE_DIR}/Linear_cell_complex/doc/Linear_cell_complex/fig \ - ${CMAKE_SOURCE_DIR}/Interval_skip_list/doc/Interval_skip_list/fig \ - ${CMAKE_SOURCE_DIR}/Nef_2/doc/Nef_2/fig \ - ${CMAKE_SOURCE_DIR}/Nef_S2/doc/Nef_S2/fig \ - ${CMAKE_SOURCE_DIR}/Nef_3/doc/Nef_3/fig \ - ${CMAKE_SOURCE_DIR}/QP_solver/doc/QP_solver/fig \ - ${CMAKE_SOURCE_DIR}/Mesh_2/doc/Mesh_2/fig \ - ${CMAKE_SOURCE_DIR}/Surface_mesher/doc/Surface_mesher/fig \ - ${CMAKE_SOURCE_DIR}/Mesh_3/doc/Mesh_3/fig \ - ${CMAKE_SOURCE_DIR}/Jet_fitting_3/doc/Jet_fitting_3/fig \ - ${CMAKE_SOURCE_DIR}/Minkowski_sum_2/doc/Minkowski_sum_2/fig \ - ${CMAKE_SOURCE_DIR}/Minkowski_sum_3/doc/Minkowski_sum_3/fig \ - ${CMAKE_SOURCE_DIR}/Miscellany/doc/Miscellany/fig \ - ${CMAKE_SOURCE_DIR}/Modular_arithmetic/doc/Modular_arithmetic/fig \ - ${CMAKE_SOURCE_DIR}/Partition_2/doc/Partition_2/fig \ - ${CMAKE_SOURCE_DIR}/Interpolation/doc/Interpolation/fig \ - ${CMAKE_SOURCE_DIR}/Kernel_23/doc/Kernel_23/fig \ - ${CMAKE_SOURCE_DIR}/Circular_kernel_2/doc/Circular_kernel_2/fig \ - ${CMAKE_SOURCE_DIR}/Circular_kernel_3/doc/Circular_kernel_3/fig \ - ${CMAKE_SOURCE_DIR}/Algebraic_kernel_d/doc/Algebraic_kernel_d/fig \ - ${CMAKE_SOURCE_DIR}/Kernel_d/doc/Kernel_d/fig \ - ${CMAKE_SOURCE_DIR}/Point_set_2/doc/Point_set_2/fig \ - ${CMAKE_SOURCE_DIR}/SearchStructures/doc/SearchStructures/fig \ - ${CMAKE_SOURCE_DIR}/Polytope_distance_d/doc/Polytope_distance_d/fig \ - ${CMAKE_SOURCE_DIR}/Polyhedron/doc/Polyhedron/fig \ - ${CMAKE_SOURCE_DIR}/Polynomial/doc/Polynomial/fig \ - ${CMAKE_SOURCE_DIR}/Principal_component_analysis/doc/Principal_component_analysis/fig \ - ${CMAKE_SOURCE_DIR}/STL_Extension/doc/STL_Extension/fig \ - ${CMAKE_SOURCE_DIR}/Skin_surface_3/doc/Skin_surface_3/fig \ - ${CMAKE_SOURCE_DIR}/Snap_rounding_2/doc/Snap_rounding_2/fig \ - ${CMAKE_SOURCE_DIR}/Arrangement_on_surface_2/doc/Sweep_line_2/fig \ - ${CMAKE_SOURCE_DIR}/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/fig \ - ${CMAKE_SOURCE_DIR}/Boolean_set_operations_2/doc/Boolean_set_operations_2/fig \ - ${CMAKE_SOURCE_DIR}/Triangulation_2/doc/TDS_2/fig \ - ${CMAKE_SOURCE_DIR}/Triangulation_2/doc/Triangulation_2/fig \ - ${CMAKE_SOURCE_DIR}/Triangulation_3/doc/TDS_3/fig \ - ${CMAKE_SOURCE_DIR}/Triangulation_3/doc/Triangulation_3/fig \ - ${CMAKE_SOURCE_DIR}/Triangulation/doc/Triangulation/fig \ - ${CMAKE_SOURCE_DIR}/Ridges_3/doc/Ridges_3/fig \ - ${CMAKE_SOURCE_DIR}/Point_set_processing_3/doc/Point_set_processing_3/fig \ - ${CMAKE_SOURCE_DIR}/Point_set_processing_3/doc/Property_map/fig \ - ${CMAKE_SOURCE_DIR}/Point_set_shape_detection_3/doc/Point_set_shape_detection_3/fig \ - ${CMAKE_SOURCE_DIR}/Kinetic_data_structures/doc/Kinetic_framework/fig \ - ${CMAKE_SOURCE_DIR}/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/fig \ - ${CMAKE_SOURCE_DIR}/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/fig \ - ${CMAKE_SOURCE_DIR}/Scale_space_reconstruction_3/doc/Scale_space_reconstruction_3/fig \ - ${CMAKE_SOURCE_DIR}/Spatial_searching/doc/Spatial_searching/fig \ - ${CMAKE_SOURCE_DIR}/Spatial_sorting/doc/Spatial_sorting/fig \ - ${CMAKE_SOURCE_DIR}/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/fig \ - ${CMAKE_SOURCE_DIR}/Segment_Delaunay_graph_Linf_2/doc/Segment_Delaunay_graph_Linf_2/fig \ - ${CMAKE_SOURCE_DIR}/Straight_skeleton_2/doc/Straight_skeleton_2/fig \ - ${CMAKE_SOURCE_DIR}/Visibility_2/doc/Visibility_2/fig \ - ${CMAKE_SOURCE_DIR}/Voronoi_diagram_2/doc/Voronoi_diagram_2/fig \ - ${CMAKE_SOURCE_DIR}/Surface_mesh_simplification/doc/Surface_mesh_simplification/fig \ - ${CMAKE_SOURCE_DIR}/Surface_mesh_skeletonization/doc/Surface_mesh_skeletonization/fig \ - ${CMAKE_SOURCE_DIR}/Surface_mesh_segmentation/doc/Surface_mesh_segmentation/fig \ - ${CMAKE_SOURCE_DIR}/Subdivision_method_3/doc/Subdivision_method_3/fig \ - ${CMAKE_SOURCE_DIR}/Surface_mesh_parameterization/doc/Surface_mesh_parameterization/fig \ - ${CMAKE_SOURCE_DIR}/Surface_mesh/doc/Surface_mesh/fig \ - ${CMAKE_SOURCE_DIR}/Surface_reconstruction_points_3/doc/Surface_reconstruction_points_3/fig \ - ${CMAKE_SOURCE_DIR}/Stream_lines_2/doc/Stream_lines_2/fig \ - ${CMAKE_SOURCE_DIR}/Stream_support/doc/Stream_support/fig \ - ${CMAKE_SOURCE_DIR}/Surface_modeling/doc/Surface_modeling/fig \ - ${CMAKE_SOURCE_DIR}/Barycentric_coordinates_2/doc/Barycentric_coordinates_2/fig \ - ${CMAKE_SOURCE_DIR}/Surface_mesh_shortest_path/doc/Surface_mesh_shortest_path/fig \ diff --git a/Documentation/doc/Documentation/Installation.txt b/Documentation/doc/Documentation/Installation.txt index f97e1a58731..e19523dd3ca 100644 --- a/Documentation/doc/Documentation/Installation.txt +++ b/Documentation/doc/Documentation/Installation.txt @@ -159,7 +159,7 @@ In order to build the \cgal libraries, you need a \cpp compiler. |\sc{Gnu} `g++` 4.1 or later\cgalFootnote{`http://gcc.gnu.org/`} | Linux / MacOS X | | | \sc{MS} Windows 95/98/2000/XP/NT4 | | \sc{Intel} `C++` 15.0\cgalFootnote{`http://software.intel.com/en-us/intel-compilers/`} | Linux | -|\sc{MS} Visual `C++` 10.0, 11.0, 12.0 (\sc{Visual Studio} 2010, 2012, and 2013)\cgalFootnote{`http://msdn.microsoft.com/en-us/vstudio/`} | \sc{MS} Windows 95/98/2000/XP/NT4/Vista/7/8 | +|\sc{MS} Visual `C++` 10.0, 11.0, 12.0, 14.0 (\sc{Visual Studio} 2010, 2012, 2013, and 2015)\cgalFootnote{`http://msdn.microsoft.com/en-us/vstudio/`} | \sc{MS} Windows 95/98/2000/XP/NT4/Vista/7/8 | | `Clang` \cgalFootnote{`http://clang.llvm.org/`} compiler version 3.5 and 3.6.2 | Linux / MacOS X | | Apple `Clang` compiler version 6.0 and 4.2 | MacOS X | diff --git a/Documentation/doc/Documentation/dependencies b/Documentation/doc/Documentation/dependencies deleted file mode 100644 index 279d79c3d12..00000000000 --- a/Documentation/doc/Documentation/dependencies +++ /dev/null @@ -1,97 +0,0 @@ -Algebraic_foundations -Advancing_front_surface_reconstruction -AABB_tree -Polygon -Number_types -Alpha_shapes_2 -Alpha_shapes_3 -Apollonius_graph_2 -Bounding_volumes -Inscribed_areas -Matrix_search -Box_intersection_d -CGAL_ipelets -Circulator -Convex_decomposition_3 -Convex_hull_2 -Convex_hull_3 -Convex_hull_d -Envelope_2 -Envelope_3 -Generator -Geomview -GraphicsView -HalfedgeDS -BGL -Combinatorial_map -Linear_cell_complex -Interval_skip_list -Nef_2 -Nef_S2 -Nef_3 -QP_solver -Mesh_2 -Surface_mesher -Mesh_3 -Jet_fitting_3 -Minkowski_sum_2 -Minkowski_sum_3 -Miscellany -Modular_arithmetic -Partition_2 -Interpolation -Kernel_23 -Circular_kernel_2 -Circular_kernel_3 -Algebraic_kernel_d -Kernel_d -Point_set_2 -SearchStructures -Surface_mesh_skeletonization -Polytope_distance_d -Polyhedron -Polynomial -Principal_component_analysis -STL_Extension -Skin_surface_3 -Snap_rounding_2 -Sweep_line_2 -Arrangement_on_surface_2 -Boolean_set_operations_2 -TDS_2 -Triangulation_2 -TDS_3 -Triangulation_3 -Triangulation -Ridges_3 -Point_set_processing_3 -Point_set_shape_detection_3 -Polyline_simplification_2 -Property_map -Kinetic_framework -Kinetic_data_structures -Periodic_2_triangulation_2 -Periodic_3_triangulation_3 -Scale_space_reconstruction_3 -Spatial_searching -Spatial_sorting -Segment_Delaunay_graph_2 -Segment_Delaunay_graph_Linf_2 -Straight_skeleton_2 -Visibility_2 -Voronoi_diagram_2 -Surface_mesh_simplification -Subdivision_method_3 -Surface_mesh_parameterization -Surface_reconstruction_points_3 -Surface_mesh_segmentation -Stream_lines_2 -Stream_support -Surface_modeling -Barycentric_coordinates_2 -Surface_mesh -Surface_mesh_shortest_path -Polygon_mesh_processing - - - diff --git a/Documentation/doc/Documentation/main.txt b/Documentation/doc/Documentation/main.txt index 11498255ad0..ce7b9c8784b 100644 --- a/Documentation/doc/Documentation/main.txt +++ b/Documentation/doc/Documentation/main.txt @@ -43,7 +43,7 @@ Manuals for the Previous Releases For releases >= 4.2, visit [http://doc.cgal.org/X.Y](http://doc.cgal.org/4.2) For releases X.Y, with 3.1 <= X.Y <= 4.1 visit -[http://www.cgal.org/Manual/X.Y/doc_html/cgal_manual/contents.html](http://www.cgal.org/Manual/3.1/doc_html/cgal_manual/contents.html) +[http://doc.cgal.org/Manual/X.Y/doc_html/cgal_manual/packages.html](http://doc.cgal.org/Manual/3.1/doc_html/cgal_manual/packages.html) diff --git a/Documentation/doc/Documentation/packages.txt b/Documentation/doc/Documentation/packages.txt index 96a7f4eb2aa..863a75f0c76 100644 --- a/Documentation/doc/Documentation/packages.txt +++ b/Documentation/doc/Documentation/packages.txt @@ -47,6 +47,7 @@ h1 { \package_listing{Straight_skeleton_2} \package_listing{Minkowski_sum_2} \package_listing{Polyline_simplification_2} +\package_listing{Visibility_2} \section PartPolyhedra Cell Complexes and Polyhedra @@ -68,7 +69,6 @@ h1 { \package_listing{Snap_rounding_2} \package_listing{Envelope_2} \package_listing{Envelope_3} -\package_listing{Visibility_2} \section PartTriangulationsAndDelaunayTriangulations Triangulations and Delaunay Triangulations diff --git a/GraphicsView/doc/GraphicsView/PackageDescription.txt b/GraphicsView/doc/GraphicsView/PackageDescription.txt index e4c20c4278a..01513917180 100644 --- a/GraphicsView/doc/GraphicsView/PackageDescription.txt +++ b/GraphicsView/doc/GraphicsView/PackageDescription.txt @@ -18,7 +18,7 @@ \cgalPkgSummaryEnd \cgalPkgShortInfoBegin \cgalPkgSince{3.4} -\cgalPkgDependsOn{\ref thirdpartyQt} +\cgalPkgDependsOn{\sc{Qt} 5} \cgalPkgBib{cgal:fr-cqgvf} \cgalPkgLicense{\ref licensesGPL "GPL"} \cgalPkgShortInfoEnd diff --git a/Installation/CHANGES b/Installation/CHANGES index 91b421a5697..07e5a4a60a0 100644 --- a/Installation/CHANGES +++ b/Installation/CHANGES @@ -1,7 +1,7 @@ -------------------------------- Release 4.7 -------------------------------- -Release date: September 2015 +Release date: October 2015 * Installation @@ -20,13 +20,10 @@ Release date: September 2015 - The code of the 3D demos now use modern OpenGL, with shaders, instead of the fixed pipeline API of OpenGL-1. - - Initial support of the Microsoft Windows Visual C++ compiler 2015 (VC14). - - -* General - - - Support for unordered sets and maps of the stdlib and of boost for handle - and index classes. + - The Microsoft Windows Visual C++ compiler 2015 (VC14) is now supported. + However, since this compiler is not officially supported by Intel TBB 4.4 + and Qt 5.5 (the latest versions available at the time of this release), the + parallelism features of CGAL and Qt5 demos will not work. * L Infinity Segment Delaunay Graphs (new package) @@ -93,6 +90,12 @@ Release date: September 2015 mesh processing. +* General + + - Support for unordered sets and maps of the stdlib and of boost for handle + and index classes. + + * Approximation of Ridges and Umbilics on Triangulated Surface Meshes - This package now supports any model of the concept FaceGraph. @@ -102,8 +105,6 @@ Release date: September 2015 FaceGraph. - - * dD Geometry Kernel - Epick_d gains 3 new functors: Construct_circumcenter_d, @@ -111,8 +112,6 @@ Release date: September 2015 the computation of alpha-shapes. - - * 2D Arrangements - Introduced a new traits class, called @@ -154,18 +153,16 @@ Release date: September 2015 * 3D Periodic Triangulations - - Rename Periodic_3_triangulation_traits_3 + - Rename Periodic_3_triangulation_traits_3 to Periodic_3_Delaunay_triangulation_traits_3. - - Rename the concept Periodic_3TriangulationTraits_3 + - Rename the concept Periodic_3TriangulationTraits_3 to Periodic_3DelaunayTriangulationTraits_3. - Create Periodic_3_triangulation_traits_3 and the concept Periodic_3TriangulationTraits_3. - - * 2D Conforming Triangulations and Meshes - Add an optimization method CGAL::lloyd_optimize_mesh_2() that implements @@ -192,8 +189,6 @@ Release date: September 2015 spatial_sort_on_sphere. - - * Geometric Object Generators - Add new random generator of points in a 2D and 3D triangle and in a diff --git a/Installation/changes.html b/Installation/changes.html index 4186a62a0df..fbf582e011a 100644 --- a/Installation/changes.html +++ b/Installation/changes.html @@ -59,7 +59,7 @@ -
4.7  (September 2015) +
4.7  (October 2015)
4.6.2  (August 2015)
4.6.1  (June 2015)
4.6  (April 2015) @@ -114,37 +114,67 @@ and src/ directories).

-

Release 4.7

+ + + + + + + + + + + + + + + + + + + + + + + + +

Release 4.7

+
+

Release date: October 2015

+

Installation

  • The minimum required version of CMake is now 2.8.11. CMake versions - 3.1, 3.2, and 3.3 are supported.
  • + 3.1, 3.2, and 3.3 are supported.
  • All Qt4 demos have been updated and now require Qt5 to be - compiled. Qt5 version 5.3 or higher is required. - The support for Qt4 is dropped. To compile libCGAL_Qt5 and demos, - you must set the cmake or environment variable Qt5_DIR to point to - the path to the directory containing the file Qt5Config.cmake created - by your Qt5 installation. - If you are using the open source edition it should be + compiled. Qt5 version 5.3 or higher is required. The support for Qt4 + is dropped. To compile libCGAL_Qt5 and demos, you must set the cmake + or environment variable Qt5_DIR to point to the path to + the directory containing the file Qt5Config.cmake + created by your Qt5 installation. If you are using the open source + edition it should be /path-to/qt-everywhere-opensource-src-<version>/qtbase/lib/cmake/Qt5.
  • The code of the 3D demos now use modern OpenGL, with shaders, instead of the fixed pipeline API of OpenGL-1.
  • -
  • Initial support of the Microsoft Windows Visual C++ compiler 2015 - (VC14).
  • -
- -

General

-
    -
  • Support for unordered sets and maps of the stdlib and of boost for - handle and index classes. +
  • The Microsoft Windows Visual C++ compiler 2015 (VC14) is now + supported. However, since this compiler is not officially supported + by Intel TBB 4.4 and Qt 5.5 (the latest versions available at the + time of this release), the parallelism features of CGAL and Qt5 demos + will not work.
-

L Infinity Segment Delaunay Graphs (new package)

    @@ -186,25 +216,25 @@ and src/ directories).

    Triangulated Surface Mesh Skeletonization (new package)

    • - This package provides a (1D) curve skeleton extraction algorithm - for a triangulated polygonal mesh without borders based on the - mean curvature flow. The particularity of this skeleton is that - it captures the topology of the input. For each skeleton vertex - one can obtain its location and its corresponding vertices from - the input mesh. The code is generic and works with any model of - the `FaceListGraph` concept. + This package provides a (1D) curve skeleton extraction algorithm for + a triangulated polygonal mesh without borders based on the mean + curvature flow. The particularity of this skeleton is that it + captures the topology of the input. For each skeleton vertex one can + obtain its location and its corresponding vertices from the input + mesh. The code is generic and works with any model of the + `FaceListGraph` concept.

    3D Point-Set Shape Detection (new package)

    • - This package implements the efficient RANSAC method for shape detection, - contributed by Schnabel et al. From an unstructured point set with - unoriented normals, the algorithm detects a set of shapes. Five - types of primitive shapes are provided by this package: plane, - sphere, cylinder, cone and torus. Detecting other types of shapes - is possible by implementing a class derived from a base shape. + This package implements the efficient RANSAC method for shape + detection, contributed by Schnabel et al. From an unstructured point + set with unoriented normals, the algorithm detects a set of + shapes. Five types of primitive shapes are provided by this package: + plane, sphere, cylinder, cone and torus. Detecting other types of + shapes is possible by implementing a class derived from a base shape.
    @@ -217,126 +247,134 @@ and src/ directories).

    Polygon Mesh Processing (new package)

      -
    • - This package implements a collection of methods and classes - for polygon mesh processing, ranging from basic operations on simplices, - to complex geometry processing algorithms. - The implementation of this package mainly follows algorithms and references - given in Botsch et al.'s book on polygon mesh processing. -
    • +
    • This package implements a collection of methods and classes for + polygon mesh processing, ranging from basic operations on simplices, + to complex geometry processing algorithms. The implementation of + this package mainly follows algorithms and references given in Botsch + et al.'s book on polygon mesh processing. +
    • +
    + + +

    General

    +
      +
    • Support for unordered sets and maps of the stdlib and of boost for + handle and index classes. +
    -

    Approximation of Ridges and Umbilics on Triangulated Surface Meshes

    -
      -
    • This package now supports any model of the concept FaceGraph. -
    • Breaking change: The package no longer support models -of TriangulatedSurfaceMesh which are not at the same time -model of the concept FaceGraph. -
    • -
    - - - +
      +
    • This package now supports any model of the + concept FaceGraph. +
    • Breaking change: The package no longer support models + of TriangulatedSurfaceMesh which are not at the same + time model of the concept FaceGraph. +
    • +
    +

    dD Geometry Kernel

    • Epick_d gains 3 new functors: Construct_circumcenter_d, - Compute_squared_radius_d, Side_of_bounded_sphere_d. + Compute_squared_radius_d, + Side_of_bounded_sphere_d. Those are essential for the computation of alpha-shapes.
    - - - - +

    2D Arrangements

    • Introduced a new traits class, called - Arr_polycurve_traits_2<SubcurveTraits>, which handles - general piece-wise (polycurve) curves. The pieces do not necessarily - have to be linear.
    • + Arr_polycurve_traits_2<SubcurveTraits>, which + handles general piece-wise (polycurve) curves. The pieces do not + necessarily have to be linear.
    • Introduced two new concepts called ArrangementApproximateTraits_2 and ArrangementConstructXMonotoneCurveTraits_2.
      • The existing ArrangementLandmarkTraits_2 concept, - which has two requirements, now refines the two respective concepts - above.
      • + which has two requirements, now refines the two respective + concepts above.
      • The template parameter of the exsting - Arr_polyline_traits_2<SegmentTraits> template must - be substituted with a traits class that is a model of - the ArrangementConstructXMonotoneTraits_2 concept among - the other when Arr_polyline_traits_2 is - instantiated.
      • -
    • + Arr_polyline_traits_2<SegmentTraits> template + must be substituted with a traits class that is a model of + the ArrangementConstructXMonotoneTraits_2 concept + among the other when Arr_polyline_traits_2 is + instantiated. + +
    +
+

2D Minkowski Sums

    -
  • Added support for polygons with holes and optimized the construction - of Minkowski sums. -
      -
    • Introduced an implementation of the "reduced convolution" method, a - variant of the method described in "2D Minkowski Sum of Polygons Using - Reduced Convolution" by Behar and Lien. The new method supports polygons - with holes and in many cases out pergorms the implementation of the - exsisting (full) convolution method.
    • -
    • Introduced two new classes that decompose polygons into convex pieces - (models of the PolygonConvexDecomposition_2 concept) based - on vertical decomposition and constrained Delaunay triangulation, - respectively. These new models also support the convex decomposition of - polygons with holes.
    • -
  • +
  • Added support for polygons with holes and optimized the + construction of Minkowski sums. +
      +
    • Introduced an implementation of the "reduced convolution" + method, a variant of the method described in "2D Minkowski Sum of + Polygons Using Reduced Convolution" by Behar and Lien. The new + method supports polygons with holes and in many cases out + pergorms the implementation of the exsisting (full) convolution + method.
    • +
    • Introduced two new classes that decompose polygons into convex + pieces (models of the PolygonConvexDecomposition_2 + concept) based on vertical decomposition and constrained Delaunay + triangulation, respectively. These new models also support the + convex decomposition of polygons with holes. +
    • +
    +
-

3D Periodic Triangulations

    -
  • Rename Periodic_3_triangulation_traits_3 Periodic_3_Delaunay_triangulation_traits_3. +
  • Rename Periodic_3_triangulation_traits_3 to + Periodic_3_Delaunay_triangulation_traits_3.
  • -
  • Rename the concept Periodic_3TriangulationTraits_3 Periodic_3DelaunayTriangulationTraits_3. +
  • Rename the concept Periodic_3TriangulationTraits_3 to + Periodic_3DelaunayTriangulationTraits_3.
  • -
  • Create Periodic_3_triangulation_traits_3 and the concept Periodic_3TriangulationTraits_3. +
  • Create Periodic_3_triangulation_traits_3 and the + concept Periodic_3TriangulationTraits_3.
- -

2D Conforming Triangulations and Meshes

  • - Add an optimization method CGAL::lloyd_optimize_mesh_2() - that implements the Lloyd (or Centroidal Voronoi Tesselation) - optimization algorithm in a Constrained Delaunay Triangulation. For - optimization, the triangulation data structure on which the mesher - relies needs its VertexBase template parameter to be a - model of the new concept DelaunayMeshVertexBase_2. + Add an optimization method CGAL::lloyd_optimize_mesh_2() + that implements the Lloyd (or Centroidal Voronoi Tesselation) + optimization algorithm in a Constrained Delaunay Triangulation. For + optimization, the triangulation data structure on which the mesher + relies needs its VertexBase template parameter to be a + model of the new concept DelaunayMeshVertexBase_2.
- +

Point Set Processing and Surface Reconstruction from Point Sets

  • - Add the function CGAL::compute_vcm() for computing the - Voronoi Covariance Measure (VCM) of a point set. The output of this function - can be used with the function CGAL::vcm_is_on_feature_edge() - to determine whether a point is on or close to a feature edge. The former - function is also internally used by CGAL::vcm_estimate_normals() - to estimate the normals of a point set and it is particularly suited to point - set with noise. + Add the function CGAL::compute_vcm() for computing the + Voronoi Covariance Measure (VCM) of a point set. The output of this + function can be used with the + function CGAL::vcm_is_on_feature_edge() to determine + whether a point is on or close to a feature edge. The former function + is also internally used by CGAL::vcm_estimate_normals() + to estimate the normals of a point set and it is particularly suited + to point set with noise.
- +

Spatial Sorting

    -
  • Add the possibility to sort points on a sphere along - a space-filling curve using the functions - CGAL::hilbert_sort_on_sphere and - CGAL::spatial_sort_on_sphere.
  • +
  • Add the possibility to sort points on a sphere along + a space-filling curve using the functions + CGAL::hilbert_sort_on_sphere and + CGAL::spatial_sort_on_sphere.
- - - +

Geometric Object Generators

  • Add new random generator of points in a 2D and 3D triangle and in a @@ -347,7 +385,6 @@ model of the concept FaceGraph.
-
diff --git a/Installation/cmake/modules/FindTBB.cmake b/Installation/cmake/modules/FindTBB.cmake index 096c00c3edd..a29c6d9ca9e 100644 --- a/Installation/cmake/modules/FindTBB.cmake +++ b/Installation/cmake/modules/FindTBB.cmake @@ -102,6 +102,17 @@ if (WIN32) if(MSVC11) set(_TBB_COMPILER "vc11") endif(MSVC11) + if(MSVC12) + set(_TBB_COMPILER "vc12") + endif(MSVC12) + #note there was no MSVC13 + if(MSVC14) + if(RUNNING_CGAL_AUTO_TEST) + set (TBB_FOUND "NO") + return()#binaries for TBB not publicly available when CGAL-4.7 is published + endif(RUNNING_CGAL_AUTO_TEST) + message(STATUS "[Warning] FindTBB.cmake: TBB 4.4 (latest available when CGAL-4.7 is published) does not provide support for MSVC 2015.") + endif(MSVC14) # Todo: add other Windows compilers such as ICL. set(_TBB_ARCHITECTURE ${TBB_ARCHITECTURE}) endif (WIN32) diff --git a/Kernel_23/doc/Kernel_23/CGAL/Iso_rectangle_2.h b/Kernel_23/doc/Kernel_23/CGAL/Iso_rectangle_2.h index 05f6d6c0baa..53f64846fca 100644 --- a/Kernel_23/doc/Kernel_23/CGAL/Iso_rectangle_2.h +++ b/Kernel_23/doc/Kernel_23/CGAL/Iso_rectangle_2.h @@ -191,7 +191,7 @@ Kernel::FT area() const; /*! returns a bounding box containing `r`. */ -Bbox bbox() const; +Bbox_2 bbox() const; /*! returns the iso-oriented rectangle obtained by applying `t` on diff --git a/Kernel_d/doc/Kernel_d/Concepts/Kernel--Side_of_oriented_sphere_d.h b/Kernel_d/doc/Kernel_d/Concepts/Kernel--Side_of_oriented_sphere_d.h index 9f6fdd64e04..db5945c63e0 100644 --- a/Kernel_d/doc/Kernel_d/Concepts/Kernel--Side_of_oriented_sphere_d.h +++ b/Kernel_d/doc/Kernel_d/Concepts/Kernel--Side_of_oriented_sphere_d.h @@ -22,7 +22,7 @@ side is the bounded interior of the sphere. \pre `A` contains \f$ d+1\f$ points in \f$ d\f$-space. \cgalRequires The value type of `ForwardIterator` is `Kernel_d::Point_d`. */ -template Bounded_side +template Oriented_side operator()( ForwardIterator first, ForwardIterator last, const Kernel_d::Point_d& p); diff --git a/Kinetic_data_structures/doc/Kinetic_data_structures/PackageDescription.txt b/Kinetic_data_structures/doc/Kinetic_data_structures/PackageDescription.txt index 86bee759eab..6da5a6ef74b 100644 --- a/Kinetic_data_structures/doc/Kinetic_data_structures/PackageDescription.txt +++ b/Kinetic_data_structures/doc/Kinetic_data_structures/PackageDescription.txt @@ -28,7 +28,7 @@ \cgalPkgSummaryEnd \cgalPkgShortInfoBegin \cgalPkgSince{3.2} -\cgalPkgDependsOn{\ref PkgKdsFrameworkSummary. Two dimensional visualization depends on \ref thirdpartyQt\, three dimensional visualization depends on \ref thirdpartyCoin.} +\cgalPkgDependsOn{\ref PkgKdsFrameworkSummary. Two dimensional visualization depends on \sc{Qt} 3, three dimensional visualization depends on \ref thirdpartyCoin.} \cgalPkgBib{cgal:r-kds} \cgalPkgLicense{\ref licensesLGPL "LGPL"} \cgalPkgShortInfoEnd diff --git a/Kinetic_data_structures/doc/Kinetic_framework/PackageDescription.txt b/Kinetic_data_structures/doc/Kinetic_framework/PackageDescription.txt index d39d9ce0c94..7f79506ec1c 100644 --- a/Kinetic_data_structures/doc/Kinetic_framework/PackageDescription.txt +++ b/Kinetic_data_structures/doc/Kinetic_framework/PackageDescription.txt @@ -31,7 +31,7 @@ \cgalPkgSummaryEnd \cgalPkgShortInfoBegin \cgalPkgSince{3.2} -\cgalPkgDependsOn{Two dimensional visualization depends on \ref thirdpartyQt\, three dimensional visualization depends on \ref thirdpartyCoin.} +\cgalPkgDependsOn{Two dimensional visualization depends on \sc{Qt} 3, three dimensional visualization depends on \ref thirdpartyCoin.} \cgalPkgBib{cgal:r-kdsf} \cgalPkgLicense{\ref licensesLGPL "LGPL"} \cgalPkgShortInfoEnd diff --git a/Linear_cell_complex/demo/Linear_cell_complex/CMakeLists.txt b/Linear_cell_complex/demo/Linear_cell_complex/CMakeLists.txt index 00a9cb20db1..763c25d968e 100644 --- a/Linear_cell_complex/demo/Linear_cell_complex/CMakeLists.txt +++ b/Linear_cell_complex/demo/Linear_cell_complex/CMakeLists.txt @@ -16,6 +16,7 @@ endif() ## To add expensive tests # add_definitions("-DCGAL_CHECK_EXPENSIVE") +# add_definitions("-Wall -Wextra") ## For profilling with gprof # add_definitions("-pg") @@ -72,7 +73,6 @@ target_link_libraries(Linear_cell_complex_3_demo ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES}) target_link_libraries(Linear_cell_complex_3_demo ${QT_LIBRARIES} ${QGLVIEWER_LIBRARIES} ) -target_link_libraries(Linear_cell_complex_3_demo ${OPENGL_gl_LIBRARY} - ${OPENGL_glu_LIBRARY} ) +target_link_libraries(Linear_cell_complex_3_demo ${OPENGL_gl_LIBRARY} ) endif() diff --git a/Linear_cell_complex/demo/Linear_cell_complex/MainWindow.cpp b/Linear_cell_complex/demo/Linear_cell_complex/MainWindow.cpp index 6d7dcbee5bd..558cea911db 100644 --- a/Linear_cell_complex/demo/Linear_cell_complex/MainWindow.cpp +++ b/Linear_cell_complex/demo/Linear_cell_complex/MainWindow.cpp @@ -24,6 +24,7 @@ #include #include #include +#include "import_moka.h" // Function defined in Linear_cell_complex_3_subivision.cpp void subdivide_lcc_3 (LCC & m); @@ -58,7 +59,7 @@ MainWindow::MainWindow (QWidget * parent):CGAL::Qt::DemosMainWindow (parent), labels.append(QString(tr("Hidden"))); volumeList->setHorizontalHeaderLabels(labels); //volumeList->resizeColumnsToContents(); - volumeList->setFixedWidth(200); + volumeList->setFixedWidth(220); /* volumeList->setColumnWidth(0,85); volumeList->setColumnWidth(1,35); volumeList->setColumnWidth(2,35);*/ @@ -82,7 +83,7 @@ MainWindow::MainWindow (QWidget * parent):CGAL::Qt::DemosMainWindow (parent), this->addRecentFiles (this->menuFile, this->actionQuit); connect (this, SIGNAL (openRecentFile (QString)), - this, SLOT (load_off (QString))); + this, SLOT (load_depend_on_extension(QString))); statusMessage = new QLabel ("Darts: 0, Vertices: 0 (Points: 0), Edges: 0, Facets: 0," @@ -223,6 +224,32 @@ void MainWindow::init_all_new_volumes() { on_new_volume(it); } } +void MainWindow::on_actionSave_triggered () +{ + QString fileName = QFileDialog::getSaveFileName (this, + tr ("Save"), + "save.3map", + tr ("3-map files (*.3map)")); + + if (!fileName.isEmpty ()) + { + save(fileName); + } +} + +void MainWindow::on_actionLoad_triggered () +{ + QString fileName = QFileDialog::getOpenFileName (this, + tr ("Load"), + "./3map", + tr ("3-map files (*.3map)")); + + if (!fileName.isEmpty ()) + { + load(fileName, true); + } +} + void MainWindow::on_actionImportOFF_triggered () { QString fileName = QFileDialog::getOpenFileName (this, @@ -236,6 +263,19 @@ void MainWindow::on_actionImportOFF_triggered () } } +void MainWindow::on_actionImportMoka_triggered() +{ + QString fileName = QFileDialog::getOpenFileName (this, + tr ("Import Moka"), + "./moka", + tr ("Moka files (*.moka)")); + + if (!fileName.isEmpty ()) + { + load_moka(fileName, true); + } +} + void MainWindow::on_actionImport3DTDS_triggered () { QString fileName = QFileDialog::getOpenFileName (this, @@ -264,6 +304,84 @@ void MainWindow::on_actionAddOFF_triggered() } } +void MainWindow::load_depend_on_extension(const QString & fileName, bool clear) +{ + QString ext = QFileInfo(fileName).suffix(); + if ( ext=="3map") + { + load(fileName, clear); + } + else if (ext=="off") + { + load_off(fileName, clear); + } + else if (ext=="moka") + { + load_moka(fileName, clear); + } + else + { + std::cout<<"Extension not considered."<clear_all(); + +#ifdef CGAL_PROFILE_LCC_DEMO + CGAL::Timer timer; + timer.start(); +#endif + + bool res = load_combinatorial_map(fileName.toStdString().c_str(), *(scene.lcc)); + +#ifdef CGAL_PROFILE_LCC_DEMO + timer.stop(); + std::cout<<"Time to load 3-map "<addToRecentFiles(fileName); + QApplication::restoreOverrideCursor (); + + if (res) + statusBar ()->showMessage (QString ("3-map loaded ") + fileName, + DELAY_STATUSMSG); + else + statusBar ()->showMessage (QString ("Problem: 3-map not loaded ") + fileName, + DELAY_STATUSMSG); + Q_EMIT (sceneChanged ()); +} + +void MainWindow::save(const QString & fileName) +{ + QApplication::setOverrideCursor (Qt::WaitCursor); + +#ifdef CGAL_PROFILE_LCC_DEMO + CGAL::Timer timer; + timer.start(); +#endif + + if ( save_combinatorial_map(*(scene.lcc), fileName.toStdString().c_str()) ) + statusBar ()->showMessage (QString ("3-map saved ") + fileName, + DELAY_STATUSMSG); + else + statusBar ()->showMessage (QString ("Problem: 3-map not saved ") + fileName, + DELAY_STATUSMSG); + QApplication::restoreOverrideCursor (); + +#ifdef CGAL_PROFILE_LCC_DEMO + timer.stop(); + std::cout<<"Time to save 3-map "<clear_all(); + +#ifdef CGAL_PROFILE_LCC_DEMO + CGAL::Timer timer; + timer.start(); +#endif + + CGAL::import_from_moka < LCC > (*scene.lcc, qPrintable (fileName)); + +#ifdef CGAL_PROFILE_LCC_DEMO + timer.stop(); + std::cout<<"Time to load off "<addToRecentFiles (fileName); + QApplication::restoreOverrideCursor (); + + if (clear) + statusBar ()->showMessage (QString ("Load off file") + fileName, + DELAY_STATUSMSG); + else + statusBar ()->showMessage (QString ("Add off file") + fileName, + DELAY_STATUSMSG); + Q_EMIT (sceneChanged ()); +} + Dart_handle MainWindow::make_iso_cuboid(const Point_3 basepoint, LCC::FT lg) { return scene.lcc->make_hexahedron(basepoint, @@ -783,7 +935,7 @@ void MainWindow::on_actionRemove_filled_volumes_triggered() DELAY_STATUSMSG); } -void MainWindow::on_actionTriangulate_all_facets_triggered() +void MainWindow::on_actionInsert_center_vertices_triggered() { QApplication::setOverrideCursor (Qt::WaitCursor); @@ -805,17 +957,113 @@ void MainWindow::on_actionTriangulate_all_facets_triggered() #ifdef CGAL_PROFILE_LCC_DEMO timer.stop(); - std::cout<<"Time to triangulate all filled faces: " + std::cout<<"Time to insert center vertices in all filled faces: " <showMessage - (QString ("Facets of visible and filled volume(s) triangulated"), + (QString ("Vertices are inserted in center of facets of visible and filled volume(s)"), DELAY_STATUSMSG); } +double compute_angle3d(const Vector_3& v1, const Vector_3& v2) +{ + double a = CGAL::to_double( (v1*v2) / + ( sqrt(v1.squared_length()) * sqrt(v2.squared_length()) ) ) ; + + if (a < -1.0) return acos(-1.0)/M_PI*180.0; + else if (a > 1.0) return acos(1.0)/M_PI*180.0; + else return acos(a)/M_PI*180.0; +} + +void MainWindow::on_actionMerge_coplanar_faces_triggered() +{ + QApplication::setOverrideCursor (Qt::WaitCursor); + +#ifdef CGAL_PROFILE_LCC_DEMO + CGAL::Timer timer; + timer.start(); +#endif + + scene.lcc->set_update_attributes(false); + + std::vector edges; + int treated = scene.lcc->get_new_mark(); + int treated2 = scene.lcc->get_new_mark(); + + for ( LCC::Dart_range::iterator it= scene.lcc->darts().begin(), + itend = scene.lcc->darts().end(); it!=itend; ++it ) + { + if (!scene.lcc->is_marked(it, treated) ) + { + if ( CGAL::is_removable(*scene.lcc, it) ) + { + LCC::Vector normal1 = CGAL::compute_normal_of_cell_2(*scene.lcc,it); + LCC::Vector normal2 = CGAL::compute_normal_of_cell_2(*scene.lcc, scene.lcc->beta<2>(it) ); + double angle = compute_angle3d(normal1, normal2); + + if ( ((angle<5.0 || angle>355.0) || (angle<185.0 && angle>175.0)) ) + { + edges.push_back(it); + } + } + CGAL::mark_cell(*scene.lcc, it, treated); + } + } + + + for (std::vector::iterator it=edges.begin(), + itend=edges.end(); it!=itend; ++it) + { + CGAL::mark_cell(*scene.lcc, *it, treated2); + + if ( scene.lcc->beta<0, 2>(*it)==*it || scene.lcc->beta<1, 2>(*it)==*it) + { // To process dangling edges + + Dart_handle actu = *it, prev=NULL; + do + { + if ( scene.lcc->beta<0, 2>(actu)==actu ) prev = scene.lcc->beta<1>(actu); + else prev = scene.lcc->beta<0>(actu); + + if (scene.lcc->is_marked(actu, treated2) && + (scene.lcc->beta<0, 2>(actu)!=actu || scene.lcc->beta<1, 2>(actu)!=actu) ) + { + CGAL::remove_cell(*scene.lcc, actu); + actu = prev; + } + else + actu = NULL; + } + while (actu!=NULL && (scene.lcc->beta<0, 2>(actu)==actu || scene.lcc->beta<1, 2>(actu)==actu)); + } + else if ( !CGAL::belong_to_same_cell(*scene.lcc, *it, + scene.lcc->beta<2>(*it)) ) + CGAL::remove_cell(*scene.lcc, *it); + } + + assert(scene.lcc->is_whole_map_marked(treated)); + scene.lcc->free_mark(treated); + scene.lcc->free_mark(treated2); + + scene.lcc->set_update_attributes(true); + +#ifdef CGAL_PROFILE_LCC_DEMO + timer.stop(); + std::cout<<"Time to merge all coplanar faces: " + <showMessage + (QString ("Coplanar face(s) merged"), DELAY_STATUSMSG); +} + void MainWindow::on_actionMerge_all_volumes_triggered() { QApplication::setOverrideCursor (Qt::WaitCursor); @@ -861,6 +1109,179 @@ void MainWindow::on_actionMerge_all_volumes_triggered() (QString ("Visible and filled volume(s) merged"), DELAY_STATUSMSG); } +bool is_external(CDT::Face_handle fh) +{ + return fh->info().is_external; +} + +int number_of_existing_edge(CDT::Face_handle fh) +{ + unsigned res=0; + for (int i=0; i<3; ++i) + if (fh->info().exist_edge[i]) ++res; + return res; +} + +int get_free_edge(CDT::Face_handle fh) +{ + CGAL_assertion( number_of_existing_edge(fh)==2 ); + for (int i=0; i<3; ++i) + if (!fh->info().exist_edge[i]) return i; + + CGAL_assertion(false); + return -1; +} + +void constrained_delaunay_triangulation(LCC &lcc, Dart_handle d1) +{ + Vector_3 normal = CGAL::compute_normal_of_cell_2(lcc,d1); + P_traits cdt_traits(normal); + CDT cdt(cdt_traits); + + //inserting the constraints edge by edge + LCC::Dart_of_orbit_range<1>::iterator + it(lcc.darts_of_orbit<1>(d1).begin()); + + CDT::Vertex_handle previous=LCC::null_handle, first=LCC::null_handle, + vh=LCC::null_handle; + + for (LCC::Dart_of_orbit_range<1>::iterator + itend(lcc.darts_of_orbit<1>(d1).end()); it!=itend; ++it) + { + vh = cdt.insert(lcc.point(it)); + vh->info()=it; + if( first==NULL ) + { + first=vh; + } + if( previous!=NULL) + { + CGAL_assertion( previous !=vh ); + cdt.insert_constraint(previous,vh); + } + + previous=vh; + } + cdt.insert_constraint(previous,first); + CGAL_assertion(cdt.is_valid()); + + // 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 = false; + fit->info().exist_edge[0]=false; + fit->info().exist_edge[1]=false; + fit->info().exist_edge[2]=false; + } + + std::queue face_queue; + + 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_external) + { + fh->info().is_external = true; + for(int i = 0; i <3; ++i) + { + if(!cdt.is_constrained(std::make_pair(fh, i))) + { + face_queue.push(fh->neighbor(i)); + } + } + } + } + for( CDT::Finite_edges_iterator eit = cdt.finite_edges_begin(), + eitend = cdt.finite_edges_end(); eit != eitend; ++eit) + { + CDT::Face_handle fh = eit->first; + int index = eit->second; + CDT::Face_handle opposite_fh = fh->neighbor(index); + if(cdt.is_constrained(std::make_pair(fh, index))) + { + fh->info().exist_edge[index]=true; + opposite_fh->info().exist_edge[cdt.mirror_index(fh,index)]=true; + + if ( !fh->info().is_external && number_of_existing_edge(fh)==2 ) + face_queue.push(fh); + if ( !opposite_fh->info().is_external && + number_of_existing_edge(opposite_fh)==2 ) + face_queue.push(opposite_fh); + } + } + + while( !face_queue.empty() ) + { + CDT::Face_handle fh = face_queue.front(); + face_queue.pop(); + CGAL_assertion( number_of_existing_edge(fh)>=2 ); // i.e. ==2 or ==3 + CGAL_assertion( !fh->info().is_external ); + + if (number_of_existing_edge(fh)==2) + { + int index = get_free_edge(fh); + CDT::Face_handle opposite_fh = fh->neighbor(index); + + CGAL_assertion( !fh->info().exist_edge[index] ); + CGAL_assertion( !opposite_fh->info(). + exist_edge[cdt.mirror_index(fh,index)] ); + const CDT::Vertex_handle va = fh->vertex(cdt. cw(index)); + const CDT::Vertex_handle vb = fh->vertex(cdt.ccw(index)); + + Dart_handle ndart= + CGAL::insert_cell_1_in_cell_2(lcc,va->info(),vb->info()); + va->info()=lcc.beta<2>(ndart); + + fh->info().exist_edge[index]=true; + opposite_fh->info().exist_edge[cdt.mirror_index(fh,index)]=true; + + if ( !opposite_fh->info().is_external && + number_of_existing_edge(opposite_fh)==2 ) + face_queue.push(opposite_fh); + } + } +} + +void MainWindow::on_actionTriangulate_all_facets_triggered() +{ + QApplication::setOverrideCursor (Qt::WaitCursor); + +#ifdef CGAL_PROFILE_LCC_DEMO + CGAL::Timer timer; + timer.start(); +#endif + + std::vector v; + for (LCC::One_dart_per_cell_range<2>::iterator + it(scene.lcc->one_dart_per_cell<2>().begin()); it.cont(); ++it) + { + if ( scene.lcc->info<3>(it).is_filled_and_visible() || + (!scene.lcc->is_free<3>(it) && + scene.lcc->info<3>(scene.lcc->beta<3>(it)).is_filled_and_visible()) ) + v.push_back(it); + } + + for (std::vector::iterator itv(v.begin()); + itv!=v.end(); ++itv) + constrained_delaunay_triangulation(*scene.lcc, *itv); + +#ifdef CGAL_PROFILE_LCC_DEMO + timer.stop(); + std::cout<<"Time to triangulate all filled faces: " + <showMessage + (QString ("All visible and filled faces were triangulated"), DELAY_STATUSMSG); +} + bool MainWindow::is_volume_in_list(LCC::Attribute_handle<3>::type ah) { for(int row=0; row < volumeList->rowCount(); ++row) @@ -975,6 +1396,8 @@ void MainWindow::recreate_whole_volume_list() void MainWindow::onCellChanged(int row, int col) { + volumeList->disconnect(this); + LCC::Attribute_type<3>::type* ptr= reinterpret_cast::type*> ( volumeList->item(row,3)->data(Qt::UserRole).value() ); @@ -994,6 +1417,7 @@ void MainWindow::onCellChanged(int row, int col) (volumeList->item(row,1)->flags()|Qt::ItemIsEnabled); } + connectVolumeListHandlers(); Q_EMIT( sceneChanged()); } @@ -1875,64 +2299,6 @@ void MainWindow::onSierpinskiCarpetUpdateAttributes(bool newValue) sierpinskiCarpetUpdateAttributes = newValue; } -/*void MainWindow::onSierpinskiCarpetNeverUpdateAttributes(bool newValue) -{ - if (afterConstructionUpdateAttributes) - { - dialogsierpinskicarpet.groupBox2->setEnabled(false); - } - - neverUpdateAttributes = true; - duringConstructionUpdateAttributes = false; - afterConstructionUpdateAttributes = false; -} - -void MainWindow::onSierpinskiCarpetDuringConstructionUpdateAttributes(bool newValue) -{ - if (afterConstructionUpdateAttributes) - { - dialogsierpinskicarpet.groupBox2->setEnabled(false); - } - - neverUpdateAttributes = false; - duringConstructionUpdateAttributes = true; - afterConstructionUpdateAttributes = false; -} - -void MainWindow::onSierpinskiCarpetAfterConstructionUpdateAttributes(bool newValue) -{ - if (!afterConstructionUpdateAttributes) - { - dialogsierpinskicarpet.groupBox2->setEnabled(true); - } - - neverUpdateAttributes = false; - duringConstructionUpdateAttributes = false; - afterConstructionUpdateAttributes = true; -} - -void MainWindow::onSierpinskiCarpetUpdateAttributesMethodStdMap(bool newValue) -{ - updateAttributesMethodStdMap = true; - updateAttributesMethodTraversal = false; -} - -void MainWindow::onSierpinskiCarpetUpdateAttributesMethodTraversal(bool newValue) -{ - updateAttributesMethodStdMap = false; - updateAttributesMethodTraversal = true; -} - -void MainWindow::onSierpinskiCarpetComputeGeometry(bool newValue) -{ - sierpinski_carpet_compute_geometry(); - - computeGeometry = false; - dialogsierpinskicarpet.computeGeometry->setEnabled(false); - - Q_EMIT( sceneChanged()); -}*/ - void MainWindow::onSierpinskiCarpetInc() { QApplication::setOverrideCursor (Qt::WaitCursor); diff --git a/Linear_cell_complex/demo/Linear_cell_complex/MainWindow.h b/Linear_cell_complex/demo/Linear_cell_complex/MainWindow.h index 4f4d5c751a1..2e58379a474 100644 --- a/Linear_cell_complex/demo/Linear_cell_complex/MainWindow.h +++ b/Linear_cell_complex/demo/Linear_cell_complex/MainWindow.h @@ -110,9 +110,12 @@ public: public Q_SLOTS: // File menu + void on_actionSave_triggered(); + void on_actionLoad_triggered(); void on_actionImportOFF_triggered(); void on_actionAddOFF_triggered(); void on_actionImport3DTDS_triggered(); + void on_actionImportMoka_triggered(); void on_actionCompute_Voronoi_3D_triggered(); void on_actionClear_triggered(); @@ -130,19 +133,25 @@ public Q_SLOTS: void on_actionSubdivide_pqq_triggered(); void on_actionDual_3_triggered(); void on_actionClose_volume_triggered(); - void on_actionTriangulate_all_facets_triggered(); void on_actionSew3_same_facets_triggered(); void on_actionUnsew3_all_triggered(); + void on_actionMerge_coplanar_faces_triggered(); void on_actionMerge_all_volumes_triggered(); void on_actionRemove_filled_volumes_triggered(); + void on_actionInsert_center_vertices_triggered(); + void on_actionTriangulate_all_facets_triggered(); // View menu void on_actionExtend_filled_volumes_triggered(); void on_actionExtend_hidden_volumes_triggered(); // Other slots + void load_depend_on_extension(const QString& fileName, bool clear=true); + void load(const QString& fileName, bool clear=true); + void save(const QString& fileName); void load_off(const QString& fileName, bool clear=true); void load_3DTDS(const QString& fileName, bool clear=true); + void load_moka(const QString& fileName, bool clear=true); void onSceneChanged(); diff --git a/Linear_cell_complex/demo/Linear_cell_complex/MainWindow.ui b/Linear_cell_complex/demo/Linear_cell_complex/MainWindow.ui index 3a6b68d7f72..321dc4f3bc1 100644 --- a/Linear_cell_complex/demo/Linear_cell_complex/MainWindow.ui +++ b/Linear_cell_complex/demo/Linear_cell_complex/MainWindow.ui @@ -33,15 +33,19 @@ 0 0 635 - 22 + 25 &File + + + + @@ -54,12 +58,15 @@ &Operations + - - + + + + @@ -221,6 +228,31 @@ Create Sierpinski Triangle + + + &Load + + + + + &Save + + + + + Import Moka + + + + + Merge coplanar faces + + + + + Insert center vertices in faces + + diff --git a/Linear_cell_complex/demo/Linear_cell_complex/Viewer.cpp b/Linear_cell_complex/demo/Linear_cell_complex/Viewer.cpp index 48569ec0990..d1ad8b71ebf 100644 --- a/Linear_cell_complex/demo/Linear_cell_complex/Viewer.cpp +++ b/Linear_cell_complex/demo/Linear_cell_complex/Viewer.cpp @@ -16,646 +16,585 @@ // $Id$ // // Author(s) : Guillaume Damiand -// Kumar Snehasish +// Contributor(s): Kumar Snehasish // #include "Viewer.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include #include + +#include #include -typedef LCC::Traits Traits; -typedef CGAL::Triangulation_2_filtered_projection_traits_3 P_traits; -struct Face_info { - LCC::Dart_handle e[3]; - bool is_external; -}; -typedef CGAL::Triangulation_vertex_base_with_info_2 Vb; -typedef CGAL::Triangulation_face_base_with_info_2 Fb1; -typedef CGAL::Constrained_triangulation_face_base_2 Fb; -typedef CGAL::Triangulation_data_structure_2 TDS; -typedef CGAL::No_intersection_tag Itag; -typedef CGAL::Constrained_Delaunay_triangulation_2 CDTbase; -typedef CGAL::Constrained_triangulation_plus_2 CDT; - Viewer::Viewer(QWidget* parent) - : QGLViewer(CGAL::Qt::createOpenGLContext(),parent), wireframe(false), flatShading(true), - edges(true), vertices(true), m_displayListCreated(false) + : QGLViewer(CGAL::Qt::createOpenGLContext(),parent), wireframe(false), + flatShading(true), edges(true), vertices(true), + m_previous_scene_empty(true), are_buffers_initialized(false) + { QGLFormat newFormat = this->format(); newFormat.setSampleBuffers(true); newFormat.setSamples(16); this->setFormat(newFormat); - are_buffers_initialized = false; -} -//Make sure all the facets are triangles -bool -Viewer::is_Triangulated() -{ - - LCC &lcc = *scene->lcc; - for (LCC::Attribute_range<3>::type::iterator - it=lcc.attributes<3>().begin(), - itend=lcc.attributes<3>().end(); it!=itend; ++it ) - { - - for(LCC::One_dart_per_incident_cell_range<2,3>::iterator - dartIter=lcc.one_dart_per_incident_cell<2,3> - (lcc.dart_of_attribute<3>(it)).begin(); dartIter.cont(); ++dartIter) - { - int nb_points_per_facet =0; - for (LCC::Dart_of_orbit_range<1>::const_iterator - orbitIter = lcc.darts_of_orbit<1>(dartIter).begin(); - orbitIter.cont(); ++orbitIter) - { - nb_points_per_facet++; - } - if(nb_points_per_facet != 3) - { - return false; - } - - } - } - return true; } -void Viewer::triangulate_facet() +Viewer::~Viewer() { - - - pos_facets.resize(0); - flat_normals.resize(0); - smooth_normals.resize(0); - colors.resize(0); - - LCC &lcc = *scene->lcc; - - 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::One_dart_per_incident_cell_range<2,3>::iterator - dartIter=lcc.one_dart_per_incident_cell<2,3> - (lcc.dart_of_attribute<3>(it)).begin(); dartIter.cont(); ++dartIter) - { - - //Computes the normal of the facet - Traits::Vector_3 normal = CGAL::compute_normal_of_cell_2(lcc,dartIter); - normal = normal/(CGAL::sqrt(normal*normal)); - - P_traits cdt_traits(normal); - CDT cdt(cdt_traits); - - LCC::Dart_of_orbit_range<1>::const_iterator - he_circ = lcc.darts_of_orbit<1>(dartIter).begin(), - he_circ_end = lcc.darts_of_orbit<1>(dartIter).end(); - - // Iterates on the vector of facet handles - CDT::Vertex_handle previous, first; - do { - CDT::Vertex_handle vh = cdt.insert(lcc.point(he_circ)); - if(first == 0) { - first = vh; - } - //vh->info() = he_circ; - if(previous != 0 && previous != vh) { - cdt.insert_constraint(previous, vh); - } - previous = vh; - } while( ++he_circ != he_circ_end ); - cdt.insert_constraint(previous, first); - - // sets mark is_external - for(CDT::All_faces_iterator - fit = cdt.all_faces_begin(), - end = cdt.all_faces_end(); - fit != end; ++fit) - { - fit->info().is_external = false; - } - //check if the facet is external or internal - std::queue face_queue; - 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_external) continue; - fh->info().is_external = true; - 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(), - end = cdt.finite_faces_end(); - ffit != end; ++ffit) - { - if(ffit->info().is_external) - continue; - - //compute normals (no smooth for non-triangle facets objects - LCC::Vector normal = CGAL::compute_normal_of_cell_2(lcc,dartIter); - normal = normal/(CGAL::sqrt(normal*normal)); - - smooth_normals.push_back(normal.x());smooth_normals.push_back(normal.y());smooth_normals.push_back(normal.z()); - smooth_normals.push_back(normal.x());smooth_normals.push_back(normal.y());smooth_normals.push_back(normal.z()); - smooth_normals.push_back(normal.x());smooth_normals.push_back(normal.y());smooth_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()); - flat_normals.push_back(normal.x());flat_normals.push_back(normal.y());flat_normals.push_back(normal.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()); - - double r = (double)lcc.info<3>(dartIter).color().r()/255.0; - double g = (double)lcc.info<3>(dartIter).color().g()/255.0; - double b = (double)lcc.info<3>(dartIter).color().b()/255.0; - if ( !lcc.is_free(dartIter, 3) ) - { - r += (double)lcc.info<3>(lcc.beta(dartIter,3)).color().r()/255.0; - g += (double)lcc.info<3>(lcc.beta(dartIter,3)).color().g()/255.0; - b += (double)lcc.info<3>(lcc.beta(dartIter,3)).color().b()/255.0; - r /= 2; g /= 2; b /= 2; - } - 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); - - - } - } - } - } + buffers[0].destroy(); + buffers[1].destroy(); + buffers[2].destroy(); + buffers[3].destroy(); + buffers[4].destroy(); + buffers[5].destroy(); + buffers[6].destroy(); + buffers[7].destroy(); + vao[0].destroy(); + vao[1].destroy(); + vao[2].destroy(); + vao[3].destroy(); } void Viewer::compile_shaders() { - if(! buffers[0].create() || !buffers[1].create() || !buffers[2].create() || !buffers[3].create() - || !buffers[4].create() || !buffers[5].create() || !buffers[6].create() - || !buffers[7].create()) + if(!buffers[0].create() || !buffers[1].create() || !buffers[2].create() || + !buffers[3].create() || !buffers[4].create() || !buffers[5].create() || + !buffers[6].create() || !buffers[7].create()) + { + std::cerr<<"VBO Creation FAILED"<compileSourceCode(vertex_source)) - { - std::cerr<<"Compiling vertex source FAILED"<compileSourceCode(fragment_source)) - { - std::cerr<<"Compiling fragmentsource FAILED"<compileSourceCode(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"<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(); + //points of the facets + vao[0].bind(); + buffers[0].bind(); + buffers[0].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[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(); + //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(); - //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(); + //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(); - //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(); + vao[0].release(); + vao[1].bind(); - are_buffers_initialized = true; + //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_faces(Dart_handle dh) +{ + LCC &lcc = *scene->lcc; + for(LCC::One_dart_per_incident_cell_range<2,3>::iterator + dartIter=lcc.one_dart_per_incident_cell<2,3>(dh).begin(); + dartIter.cont(); ++dartIter) + { + double r = (double)lcc.info<3>(dartIter).color().r()/255.0; + double g = (double)lcc.info<3>(dartIter).color().g()/255.0; + double b = (double)lcc.info<3>(dartIter).color().b()/255.0; + if ( !lcc.is_free(dartIter, 3) ) + { + r += (double)lcc.info<3>(lcc.beta(dartIter,3)).color().r()/255.0; + g += (double)lcc.info<3>(lcc.beta(dartIter,3)).color().g()/255.0; + b += (double)lcc.info<3>(lcc.beta(dartIter,3)).color().b()/255.0; + r /= 2; g /= 2; b /= 2; + } + + //compute flat normals + LCC::Vector normal = CGAL::compute_normal_of_cell_2(lcc,dartIter); + normal = normal/(CGAL::sqrt(normal*normal)); + + if (lcc.beta<1,1,1>(dartIter)!=dartIter) + { + 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>(dartIter).begin(), + he_circ_end = lcc.darts_of_orbit<1>(dartIter).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() = he_circ; + if(previous!=NULL && previous != vh) + { cdt.insert_constraint(previous, vh); } + previous = vh; + } + 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 = false; + } + //check if the facet is external or internal + std::queue face_queue; + 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_external) + { + fh->info().is_external = true; + 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) + { + smooth_normals.push_back(normal.x()); + smooth_normals.push_back(normal.y()); + smooth_normals.push_back(normal.z()); + + smooth_normals.push_back(normal.x()); + smooth_normals.push_back(normal.y()); + smooth_normals.push_back(normal.z()); + + smooth_normals.push_back(normal.x()); + smooth_normals.push_back(normal.y()); + smooth_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()); + + flat_normals.push_back(normal.x()); + flat_normals.push_back(normal.y()); + flat_normals.push_back(normal.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); + } + } + } + else + { + 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>(dartIter).begin(); + orbitIter.cont(); ++orbitIter) + { + //compute Smooth normals + LCC::Vector normal = CGAL::compute_normal_of_cell_0(lcc,orbitIter); + normal = normal/(CGAL::sqrt(normal*normal)); + + 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_edges(Dart_handle dh) +{ + LCC &lcc = *scene->lcc; + for(LCC::One_dart_per_incident_cell_range<1,3>::iterator + dartIter=lcc.one_dart_per_incident_cell<1,3>(dh).begin(); + dartIter.cont(); ++dartIter) + { + const LCC::Point& p = lcc.point(dartIter); + Dart_handle d2 = lcc.other_extremity(dartIter); + 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_vertices(Dart_handle dh, bool empty) +{ + LCC &lcc = *scene->lcc; + for(LCC::One_dart_per_incident_cell_range<0,3>::iterator + dartIter=lcc.one_dart_per_incident_cell<0,3>(dh).begin(); + dartIter.cont(); ++dartIter) + { + const LCC::Point& p = lcc.point(dartIter); + 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; - //Facets - if(is_Triangulated()) + 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; + } + + 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() ) { - pos_facets.resize(0); - flat_normals.resize(0); - smooth_normals.resize(0); - colors.resize(0); - LCC &lcc = *scene->lcc; - - 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::One_dart_per_incident_cell_range<2,3>::iterator - dartIter=lcc.one_dart_per_incident_cell<2,3> - (lcc.dart_of_attribute<3>(it)).begin(); dartIter.cont(); ++dartIter) - { - // We draw the polygon - - - // double r = (double)dartIter->attribute<3>()->info().r()/255.0; - float r = (float)lcc.info<3>(dartIter).color().r()/255.0; - float g = (float)lcc.info<3>(dartIter).color().g()/255.0; - float b = (float)lcc.info<3>(dartIter).color().b()/255.0; - if ( !lcc.is_free(dartIter, 3) ) - { - r += (float)lcc.info<3>(lcc.beta(dartIter,3)).color().r()/255.0; - g += (float)lcc.info<3>(lcc.beta(dartIter,3)).color().g()/255.0; - b += (float)lcc.info<3>(lcc.beta(dartIter,3)).color().b()/255.0; - r /= 2; g /= 2; b /= 2; - } - - 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); - //compute flat normals - LCC::Vector normal = CGAL::compute_normal_of_cell_2(lcc,dartIter); - normal = normal/(CGAL::sqrt(normal*normal)); - 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>(dartIter).begin(); - orbitIter.cont(); ++orbitIter) - { - //compute Smooth normals - LCC::Vector normal = CGAL::compute_normal_of_cell_0(lcc,orbitIter); - normal = normal/(CGAL::sqrt(normal*normal)); - 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()); - } - - } - } - } - - } - else - triangulate_facet(); - - //Edges - { - pos_lines.resize(0); - LCC &lcc = *scene->lcc; - - if ( !lcc.is_empty() ) - { - - 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::One_dart_per_incident_cell_range<1,3>::iterator - dartIter=lcc.one_dart_per_incident_cell<1,3> - (lcc.dart_of_attribute<3>(it)).begin(); dartIter.cont(); ++dartIter) - { - const LCC::Point& p = lcc.point(dartIter); - Dart_handle d2 = lcc.other_extremity(dartIter); - 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()); - } - } - } - } - - } - } - //Points - { - pos_points.resize(0); - LCC &lcc = *scene->lcc; - - 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; - } - - 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::One_dart_per_incident_cell_range<0,3>::iterator - dartIter=lcc.one_dart_per_incident_cell<0,3> - (lcc.dart_of_attribute<3>(it)).begin(); - dartIter.cont(); ++dartIter) - { - const LCC::Point& p = lcc.point(dartIter); - 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(); - } - } - } - - - if ( lcc.is_empty() ) - { - bb = LCC::Point(CGAL::ORIGIN).bbox(); - bb = bb + LCC::Point(1,1,1).bbox(); // To avoid a warning from Qglviewer - } + if (it->info().is_filled()) + compute_faces(lcc.dart_of_attribute<3>(it)); + compute_edges(lcc.dart_of_attribute<3>(it)); + compute_vertices(lcc.dart_of_attribute<3>(it), empty); + empty = false; } + } + if ( empty ) + { + bb = LCC::Point(CGAL::ORIGIN).bbox(); + bb = bb + LCC::Point(1,1,1).bbox(); // To avoid a warning from Qglviewer + } } void Viewer::attrib_buffers(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 ambient(0.1f, 0.1f, 0.1f, 1.0f); - QVector4D diffuse( 0.9f, - 0.9f, - 0.9f, - 0.0f ); + 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 ambient(0.4f, 0.4f, 0.4f, 0.4f); + QVector4D diffuse( 0.9f, + 0.9f, + 0.9f, + 0.9f ); - QVector4D specular( 0.0f, - 0.0f, - 0.0f, - 0.0f ); + QVector4D specular( 0.0f, + 0.0f, + 0.0f, + 1.0f ); - QVector4D position( 0.0f, -10.0f, -10.0f, 0.0f ); - GLfloat shininess = 1.0f; + QVector4D position( 10.0f, 10.0f, 10.0f, 0.0f ); + 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.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.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(); - are_buffers_initialized = true; + 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(); } -void -Viewer::sceneChanged() +void Viewer::sceneChanged() { compute_elements(); this->camera()->setSceneBoundingBox(qglviewer::Vec(bb.xmin(), @@ -665,62 +604,66 @@ Viewer::sceneChanged() bb.ymax(), bb.zmax())); are_buffers_initialized = false; - this->showEntireScene(); + + if (m_previous_scene_empty) + this->showEntireScene(); + else + this->updateGL(); + + m_previous_scene_empty = scene->lcc->is_empty(); // for the next call to sceneChanged } void Viewer::draw() { - glEnable(GL_DEPTH_TEST); -if(!are_buffers_initialized) + glEnable(GL_DEPTH_TEST); + if(!are_buffers_initialized) initialize_buffers(); - -QColor color; - if ( !wireframe ) + QColor color; + if ( !wireframe ) + { + if(flatShading) { - 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(); - } + 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(); } - if(edges) + else { - 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); - glDrawArrays(GL_LINES, 0, static_cast(pos_lines.size()/3)); - rendering_program_p_l.release(); - vao[2].release(); - } - if(vertices) - { - ::glPointSize(7.f); - vao[3].bind(); - attrib_buffers(this); - color.setRgbF(.2f,.2f,.6f); - rendering_program_p_l.bind(); - rendering_program_p_l.setAttributeValue(colorLocation,color); - glDrawArrays(GL_POINTS, 0, static_cast(pos_points.size()/3)); - rendering_program_p_l.release(); - vao[3].release(); + 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); + glDrawArrays(GL_LINES, 0, static_cast(pos_lines.size()/3)); + rendering_program_p_l.release(); + vao[2].release(); + } + if(vertices) + { + ::glPointSize(7.f); + vao[3].bind(); + attrib_buffers(this); + color.setRgbF(.2f,.2f,.6f); + rendering_program_p_l.bind(); + rendering_program_p_l.setAttributeValue(colorLocation,color); + glDrawArrays(GL_POINTS, 0, static_cast(pos_points.size()/3)); + rendering_program_p_l.release(); + vao[3].release(); + } } void Viewer::init() @@ -748,7 +691,6 @@ void Viewer::init() ::glEnable(GL_LIGHTING); ::glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); - // ::glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); if (flatShading) { @@ -776,7 +718,6 @@ void Viewer::keyPressEvent(QKeyEvent *e) { const Qt::KeyboardModifiers modifiers = e->modifiers(); - bool handled = false; if ((e->key()==Qt::Key_W) && (modifiers==Qt::NoButton)) { wireframe = !wireframe; @@ -784,7 +725,6 @@ void Viewer::keyPressEvent(QKeyEvent *e) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); else glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - handled = true; updateGL(); } else if ((e->key()==Qt::Key_F) && (modifiers==Qt::NoButton)) @@ -801,30 +741,26 @@ void Viewer::keyPressEvent(QKeyEvent *e) } else { - ::glShadeModel(GL_FLAT); - ::glDisable(GL_BLEND); - ::glDisable(GL_LINE_SMOOTH); - ::glDisable(GL_POLYGON_SMOOTH_HINT); - ::glBlendFunc(GL_ONE, GL_ZERO); - ::glHint(GL_LINE_SMOOTH_HINT, GL_FASTEST); + ::glShadeModel(GL_FLAT); + ::glDisable(GL_BLEND); + ::glDisable(GL_LINE_SMOOTH); + ::glDisable(GL_POLYGON_SMOOTH_HINT); + ::glBlendFunc(GL_ONE, GL_ZERO); + ::glHint(GL_LINE_SMOOTH_HINT, GL_FASTEST); } - handled = true; updateGL(); } else if ((e->key()==Qt::Key_E) && (modifiers==Qt::NoButton)) { edges = !edges; - handled = true; updateGL(); } else if ((e->key()==Qt::Key_V) && (modifiers==Qt::NoButton)) { vertices = !vertices; - handled = true; updateGL(); } - - if (!handled) + else QGLViewer::keyPressEvent(e); } diff --git a/Linear_cell_complex/demo/Linear_cell_complex/Viewer.h b/Linear_cell_complex/demo/Linear_cell_complex/Viewer.h index c03977f900a..450cea1da1a 100644 --- a/Linear_cell_complex/demo/Linear_cell_complex/Viewer.h +++ b/Linear_cell_complex/demo/Linear_cell_complex/Viewer.h @@ -22,57 +22,29 @@ #define VIEWER_H #include "typedefs.h" + +#include #include #include - #include #include #include #include -class Viewer : public QGLViewer, QOpenGLFunctions_2_1 + +class Viewer : public QGLViewer, public QOpenGLFunctions_2_1 { Q_OBJECT - CGAL::Timer timer; - Scene* scene; - bool wireframe; - bool flatShading; - bool edges; - bool vertices; - CGAL::Bbox_3 bb; - - GLuint m_dlFaces; - GLuint m_dlFacesFlat; - GLuint m_dlEdges; - GLuint m_dlVertices; - bool m_displayListCreated; - typedef LCC::Dart_handle Dart_handle; typedef LCC::Dart_const_handle Dart_const_handle; - public: Viewer(QWidget* parent); - ~Viewer() - { - buffers[0].destroy(); - buffers[1].destroy(); - buffers[2].destroy(); - buffers[3].destroy(); - buffers[4].destroy(); - buffers[5].destroy(); - buffers[6].destroy(); - buffers[7].destroy(); - vao[0].destroy(); - vao[1].destroy(); - vao[2].destroy(); - vao[3].destroy(); - } + ~Viewer(); + void setScene(Scene* scene_) - { - scene = scene_; - } + { scene = scene_; } public: void draw(); @@ -87,12 +59,27 @@ public Q_SLOTS: void sceneChanged(); +private: + void initialize_buffers(); + void attrib_buffers(QGLViewer*); + void compile_shaders(); + + void compute_elements(); + void compute_faces(Dart_handle dh); + void compute_edges(Dart_handle dh); + void compute_vertices(Dart_handle dh, bool empty); private: - + Scene* scene; + bool wireframe; + bool flatShading; + bool edges; + bool vertices; + CGAL::Bbox_3 bb; + bool m_previous_scene_empty; bool are_buffers_initialized; - //Shaders elements + //Shaders elements int vertexLocation[3]; int normalsLocation; int mvpLocation[2]; @@ -101,24 +88,17 @@ private: 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; + std::vector colors; QGLBuffer buffers[10]; QOpenGLVertexArrayObject vao[10]; QOpenGLShaderProgram rendering_program; QOpenGLShaderProgram rendering_program_p_l; - - void initialize_buffers(); - void compute_elements(); - void attrib_buffers(QGLViewer*); - void compile_shaders(); - void triangulate_facet(); - bool is_Triangulated(); }; + #endif diff --git a/Linear_cell_complex/demo/Linear_cell_complex/import_moka.h b/Linear_cell_complex/demo/Linear_cell_complex/import_moka.h new file mode 100644 index 00000000000..f0a62a6609e --- /dev/null +++ b/Linear_cell_complex/demo/Linear_cell_complex/import_moka.h @@ -0,0 +1,192 @@ +// Copyright (c) 2011 CNRS and LIRIS' Establishments (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Guillaume Damiand +// +#ifndef IMPORT_MOKA_H +#define IMPORT_MOKA_H + +namespace CGAL +{ +struct GDart +{ + unsigned int alpha[4]; + Dart_handle dh; + LCC::Vertex_attribute_handle vh; + + GDart() : dh(NULL), vh(NULL) + {} + + GDart(const GDart& adart) : dh(adart.dh), + vh(adart.vh) + { + for (unsigned int i=0; i<4; ++i) + alpha[i]=adart.alpha[i]; + } +}; + +template +bool import_from_moka(LCC& lcc, const char* filename) +{ + typedef typename LCC::Point Point; + + std::ifstream ifile(filename); + if (!ifile) + { + std::cout<<"Error opening file "< gdarts; + unsigned int nbLoaded = 0; + unsigned int number; + double x,y,z; + + // First load all the gdarts, and create vertex attributes + while(ifile) + { + GDart agdart; + ifile>>agdart.alpha[0]>>agdart.alpha[1] + >>agdart.alpha[2]>>agdart.alpha[3]; // the 4 alpha + ifile>>number>>number>>number>>number; // to skip the 4*8 marks + if ( agdart.alpha[0]==nbLoaded ) + { + std::cout<<"Impossible to load a moka file with 0-free darts.\n"; + return false; + } + if ( ifile ) + { + ifile>>number; // bool to know if dart has a vertex of not. + if (number) + { + ifile>>x>>y>>z; + agdart.vh = lcc.create_vertex_attribute(Point(x, y, z)); + } + + gdarts.push_back(agdart); + ++nbLoaded; + } + } + ifile.close(); + + // Second orient the gmap, and create oriented darts. + std::stack totreat; + for (unsigned int startingdart = 0; startingdartattribute<3>() == NULL ) + { + lcc.template set_attribute<3>(gdarts[i].dh, lcc.template create_attribute<3>()); + } + } + if (gdarts[i].vh!=NULL) + { + lcc.set_vertex_attribute(gdarts[i].dh, gdarts[i].vh); + } + } + + return true; +} + +} + +#endif diff --git a/Linear_cell_complex/demo/Linear_cell_complex/typedefs.h b/Linear_cell_complex/demo/Linear_cell_complex/typedefs.h index d31132c1de3..3609e6665cf 100644 --- a/Linear_cell_complex/demo/Linear_cell_complex/typedefs.h +++ b/Linear_cell_complex/demo/Linear_cell_complex/typedefs.h @@ -24,6 +24,13 @@ #include #include #include +#include + +#include +#include +#include +#include +#include #include #include @@ -45,6 +52,11 @@ extern CGAL::Random myrandom; class Volume_info { + friend void CGAL::read_cmap_attribute_node + (const boost::property_tree::ptree::value_type &v,Volume_info &val); + + friend void CGAL::write_cmap_attribute_node(boost::property_tree::ptree & node, + const Volume_info& arg); public: Volume_info() : m_color(CGAL::Color(myrandom.get_int(0,256), myrandom.get_int(0,256), @@ -91,22 +103,61 @@ public: void negate_filled() { set_filled(!is_filled()); } - private: +private: CGAL::Color m_color; char m_status; }; +namespace CGAL +{ + +template<> +inline void read_cmap_attribute_node +(const boost::property_tree::ptree::value_type &v,Volume_info &val) +{ + try + { + val.m_status = v.second.get("status"); + } + catch(const std::exception & ) + {} + + try + { + char r = v.second.get("color-r"); + char g = v.second.get("color-g"); + char b = v.second.get("color-b"); + val.m_color = CGAL::Color(r,g,b); + } + catch(const std::exception & ) + {} +} + +// Definition of function allowing to save custon information. +template<> +inline void write_cmap_attribute_node(boost::property_tree::ptree & node, + const Volume_info& arg) +{ + boost::property_tree::ptree & nValue = node.add("v",""); + nValue.add("status",(int)arg.m_status); + nValue.add("color-r",(int)arg.m_color.r()); + nValue.add("color-g",(int)arg.m_color.g()); + nValue.add("color-b",(int)arg.m_color.b()); +} + +} + class Myitems { public: template < class Refs > - struct Dart_wrapper + struct Dart_wrapper { typedef CGAL::Dart<3, Refs > Dart; - + typedef CGAL::Cell_attribute_with_point< Refs > Vertex_attrib; typedef CGAL::Cell_attribute< Refs, Volume_info> Volume_attrib; - + typedef CGAL::cpp11::tuple Attributes; }; @@ -124,6 +175,22 @@ typedef LCC::Vector Vector_3; typedef CGAL::Timer Timer; +typedef CGAL::Triangulation_2_filtered_projection_traits_3 P_traits; +typedef CGAL::Triangulation_vertex_base_with_info_2 Vb; + +struct Face_info { + bool exist_edge[3]; + bool is_external; +}; + +typedef CGAL::Triangulation_face_base_with_info_2 Fb1; + +typedef CGAL::Constrained_triangulation_face_base_2 Fb; +typedef CGAL::Triangulation_data_structure_2 TDS; +typedef CGAL::No_intersection_tag Itag; +typedef CGAL::Constrained_Delaunay_triangulation_2 CDT; + struct Scene { LCC* lcc; }; diff --git a/Maintenance/infrastructure/cgal.geometryfactory.com/crontab b/Maintenance/infrastructure/cgal.geometryfactory.com/crontab index a2cb07e31f5..2e4bb39c786 100644 --- a/Maintenance/infrastructure/cgal.geometryfactory.com/crontab +++ b/Maintenance/infrastructure/cgal.geometryfactory.com/crontab @@ -21,7 +21,7 @@ LC_CTYPE=en_US.UTF-8 # "master" alone 0 21 * * Sun cd $HOME/CGAL/create_internal_release && $HOME/bin/create_release $HOME/CGAL/branches/master.git --public --do-it # "integration" -0 21 * * Mon,Tue,Wed,Thu,Fri cd $HOME/CGAL/create_internal_release && $HOME/bin/create_release $HOME/CGAL/branches/integration.git $HOME/CGAL/branches/empty-dir --do-it --public +0 21 * * Mon,Tue,Wed,Thu,Fri cd $HOME/CGAL/create_internal_release && $HOME/bin/create_release $HOME/CGAL/branches/integration.git $HOME/CGAL/branches/empty-dir --do-it # from branch 4.6 0 21 * * Sat cd $HOME/CGAL/create_internal_release-4.6-branch && $HOME/bin/create_release $HOME/CGAL/branches/CGAL-4.6-branch.git --public --do-it # from branch 4.5 diff --git a/Maintenance/public_release/announcement/mailing-beta.eml b/Maintenance/public_release/announcement/mailing-beta.eml index e9861e1ca39..6e7119dcfa2 100644 --- a/Maintenance/public_release/announcement/mailing-beta.eml +++ b/Maintenance/public_release/announcement/mailing-beta.eml @@ -1,28 +1,41 @@ -Subject: CGAL 4.7 Beta 1 Released, Computational Geometry Algorithms Library +Subject: CGAL 4.7 Beta 2 Released, Computational Geometry Algorithms Library Content-Type: text/plain; charset="utf-8" Body: -The CGAL Open Source Project is pleased to announce the release 4.7 Beta 1 +The CGAL Open Source Project is pleased to announce the release 4.7 Beta 2 of CGAL, the Computational Geometry Algorithms Library. -CGAL version 4.7 Beta 1 is a public testing release. It should provide +CGAL version 4.7 Beta 2 is a public testing release. It should provide a solid ground to report bugs that need to be tackled before the -release of the final version of CGAL 4.7 in September. +release of the final version of CGAL 4.7 in October. + +That is the second "beta" release for CGAL-4.7. The reason is that the +switches from Qt4 to Qt5, and from OpenGL 1 to modern OpenGL with shaders, +were not as smooth as we hopped. A lot of bugs have been fixed in the Qt5 +demos since CGAL-4.7-beta1. + +You can find the detailed description of all changes here on Github: + + https://github.com/CGAL/cgal/issues?q=milestone%3A4.7-beta2 -Besides fixes to existing packages, the following has changed since -CGAL 4.6: +As a reminder, you can find below the major changes since CGAL 4.6: o Installation - - The minimum required version of CMake is now 2.8.11. CMake versions 3.1, - 3.2, and 3.3 are supported. + - The minimum required version of CMake is now 2.8.11. CMake versions + 3.1, 3.2, and 3.3 are supported. - All Qt4 demos have been updated and now require Qt5 to be compiled. Qt5 version 5.3 or higher is required. The support for Qt4 is dropped. The code of the 3D demos now use modern OpenGL, with shaders, instead of the fixed pipeline API of OpenGL-1. + - The Microsoft Windows Visual C++ compiler 2015 (VC14) is now + supported. However, since this compiler is not officially supported + by Intel TBB 4.4 and Qt 5.5 (the latest versions available at the + time of this release), the parallelism features of CGAL and Qt5 demos + will not work. o Advancing Front Surface Reconstruction (new package) @@ -89,104 +102,6 @@ CGAL 4.6: of a point within polygonal regions in two dimensions. - - -See http://www.cgal.org/releases.html for a complete list of changes. - - -The CGAL project is a collaborative effort to develop a robust, -easy-to-use, and efficient C++ software library of geometric data -structures and algorithms, like -- triangulations (2D constrained triangulations, Delaunay triangulations - and periodic triangulations in 2D and 3D),The CGAL Open Source Project is pleased to announce the release 4.7 Beta 1 -of CGAL, the Computational Geometry Algorithms Library. - -CGAL version 4.7 Beta 1 is a public testing release. It should provide -a solid ground to report bugs that need to be tackled before the -release of the final version of CGAL 4.7 in September. - - -Besides fixes to existing packages, the following has changed since -CGAL 4.6: - - o Installation - - - The minimum required version of CMake is now 2.8.11. CMake versions 3.1, - 3.2, and 3.3 are supported. - - - All Qt4 demos have been updated and now require Qt5 to be - compiled. Qt5 version 5.3 or higher is required. The support for Qt4 - is dropped. The code of the 3D demos now use modern OpenGL, with - shaders, instead of the fixed pipeline API of OpenGL-1. - - - o Advancing Front Surface Reconstruction (new package) - - This package provides a greedy algorithm for surface reconstruction - from an unorganized point set. Starting from a seed facet, a piecewise - linear surface is grown by adding Delaunay triangles one by one. The - most plausible triangles are added first, in a way that avoids the - appearance of topological singularities. - - - o Triangulated Surface Mesh Shortest Paths (new package) - - The package provides methods for computing shortest path on - triangulated surface meshes. Given a set of source points on the - surface, this package provides a data structure that can efficiently - provides the shortest path from any point on the surface to the sources - points. There is no restriction on the genus or the number of - connected components of the mesh. - - - o Triangulated Surface Mesh Skeletonization (new package) - - This package provides a (1D) curve skeleton extraction algorithm for a - triangulated polygonal mesh without borders based on the mean curvature - flow. The particularity of this skeleton is that it captures the - topology of the input. For each skeleton vertex one can obtain its - location and its corresponding vertices from the input mesh. The code - is generic and works with any model of the `FaceListGraph` concept. - - - o Polygon Mesh Processing (new package) - - This package implements a collection of methods and classes for polygon - mesh processing, ranging from basic operations on simplices, to complex - geometry processing algorithms. The implementation of this package - mainly follows algorithms and references given in Botsch et al.'s book - on polygon mesh processing. - - - o 3D Point-Set Shape Detection (new package) - - This package implements the efficient RANSAC method for shape - detection, contributed by Schnabel et al. From an unstructured point - set with unoriented normals, the algorithm detects a set of - shapes. Five types of primitive shapes are provided by this package: - plane, sphere, cylinder, cone and torus. Detecting other types of - shapes is possible by implementing a class derived from a base shape. - - - o L Infinity Segment Delaunay Graphs (new package) - - The package provides the geometric traits for constructing the segment - Delaunay graph in the max-norm (L Infinity). The traits also contain - methods to draw the edges of the dual of the segment Delaunay graph in - the max-norm i.e., the segment Voronoi diagram in the max-norm. The - algorithm and traits rely on the segment Delaunay graph algorithm and - traits under the Euclidean distance. The segment Voronoi diagram in the - max-norm has applications in VLSI CAD. - - - o 2D Visibility (new package) - - This package provides several variants to compute the visibility area - of a point within polygonal regions in two dimensions. - - - - See http://www.cgal.org/releases.html for a complete list of changes. @@ -217,40 +132,6 @@ structures and algorithms, like -Some modules are distributed under the terms of the LGPL Open Source -license (GNU Lesser General Public License v3 or later versions). -Most modules are distributed under the terms of the GPL Open Source -license (GNU General Public License v3 or later versions). -If your intended usage does not meet the criteria of the -aforementioned licenses, a commercial license can be purchased from -GeometryFactory (http://www.geometryfactory.com/). - - -For further information and for downloading the library and its -documentation, please visit the CGAL web site: http://www.cgal.org/ - -- Voronoi diagrams (for 2D and 3D points, 2D additively weighted - Voronoi diagrams, and segment Voronoi diagrams), -- Boolean operations on polygons and polyhedra, -- regularized Boolean operations on polygons with curved arcs -- arrangements of curves, -- mesh generation (2D, 3D and surface mesh generation, - surface mesh subdivision and parametrization), -- alpha shapes (in 2D and 3D), -- convex hull algorithms (in 2D, 3D and dD), -- operations on polygons (straight skeleton and offset polygon), -- search structures (kd trees for nearest neighbor search, and - range and segment trees), -- interpolation (natural neighbor interpolation and placement of - streamlines), -- optimization algorithms (smallest enclosing sphere of points or - spheres, smallest enclosing ellipsoid of points, principal - component analysis), -- kinetic data structures - - - - Some modules are distributed under the terms of the LGPL Open Source license (GNU Lesser General Public License v3 or later versions). Most modules are distributed under the terms of the GPL Open Source diff --git a/Maintenance/public_release/announcement/mailing.eml b/Maintenance/public_release/announcement/mailing.eml index 65916b9e79c..640339ed68e 100644 --- a/Maintenance/public_release/announcement/mailing.eml +++ b/Maintenance/public_release/announcement/mailing.eml @@ -1,15 +1,21 @@ -Subject: CGAL 4.6.2 Released, Computational Geometry Algorithms Library +Subject: CGAL 4.6.3 Released, Computational Geometry Algorithms Library From: Laurent Rineau Content-Type: text/plain; charset="utf-8" Body: -The CGAL Open Source Project is pleased to announce the release 4.6.2 +The CGAL Open Source Project is pleased to announce the release 4.6.3 of CGAL, the Computational Geometry Algorithms Library. -Version 4.6.2 is a bug-fix release for version 4.6. The list of fixed bugs +Version 4.6.3 is a bug-fix release for version 4.6. The list of fixed bugs can be seen Github: - - fixed in CGAL-4.6.2: + + - fixed in CGAL-4.6.3: + + https://github.com/CGAL/cgal/issues?q=milestone%3A4.6.3 + + + - fixed earlier in CGAL-4.6.2: https://github.com/CGAL/cgal/issues?q=milestone%3A4.6.2 diff --git a/Maintenance/public_release/scripts/precompiled_demos_zips b/Maintenance/public_release/scripts/precompiled_demos_zips index ee89445f210..d9f05492f6f 100755 --- a/Maintenance/public_release/scripts/precompiled_demos_zips +++ b/Maintenance/public_release/scripts/precompiled_demos_zips @@ -58,7 +58,15 @@ rm -rf Surface_modeling_Demo # Demo not announced in the CGAL manual, from CGAL-3.8: rm -rf Circular_kernel_3_Demo +# CGAL-4.6 +pushd Polyline_simplification_2_Demo; zip ../polyline_simplification_2.zip *; popd + +# CGAL-4.7 + +pushd Segment_Delaunay_graph_Linf_2_Demo; zip ../segment_voronoi_diagram_2.zip *; popd + # check -echo CHECK now +echo CHECK now. The following lines should be empty. for f in *zip; do unzip -qql $f; done | awk '{print $4}' >| done for f in */**/*(.); do grep -qF ${f:t} done || ls $f; done +echo diff --git a/Maintenance/release_building/MINOR_NUMBER b/Maintenance/release_building/MINOR_NUMBER index 7f8f011eb73..45a4fb75db8 100644 --- a/Maintenance/release_building/MINOR_NUMBER +++ b/Maintenance/release_building/MINOR_NUMBER @@ -1 +1 @@ -7 +8 diff --git a/Maintenance/release_building/public_release_name b/Maintenance/release_building/public_release_name index 1ffc3e32468..07373a13fc7 100644 --- a/Maintenance/release_building/public_release_name +++ b/Maintenance/release_building/public_release_name @@ -1 +1 @@ -CGAL-4.7-beta2 +CGAL-4.8-dev diff --git a/Mesh_3/examples/Mesh_3/CMakeLists.txt b/Mesh_3/examples/Mesh_3/CMakeLists.txt index da5d7e073ce..f1dd4198064 100644 --- a/Mesh_3/examples/Mesh_3/CMakeLists.txt +++ b/Mesh_3/examples/Mesh_3/CMakeLists.txt @@ -62,13 +62,13 @@ if ( CGAL_FOUND ) create_single_source_cgal_program( "mesh_polyhedral_domain.cpp" ) create_single_source_cgal_program( "mesh_polyhedral_domain_with_features.cpp" ) if( WITH_CGAL_ImageIO ) - create_single_source_cgal_program( "mesh_optimization_example.cpp" ) - create_single_source_cgal_program( "mesh_optimization_lloyd_example.cpp" ) if( CGAL_ImageIO_USE_ZLIB ) + create_single_source_cgal_program( "mesh_optimization_example.cpp" ) + create_single_source_cgal_program( "mesh_optimization_lloyd_example.cpp" ) create_single_source_cgal_program( "mesh_3D_image.cpp" ) create_single_source_cgal_program( "mesh_3D_image_variable_size.cpp" ) else() - message( STATUS "NOTICE: The examples mesh_3D_image.cpp and mesh_3D_image_variable_size.cpp need CGAL_ImageIO to be configured with ZLIB support, and will not be compiled." ) + message( STATUS "NOTICE: The examples mesh_3D_image.cpp, mesh_3D_image_variable_size.cpp, mesh_optimization_example.cpp and mesh_optimization_lloyd_example.cpp need CGAL_ImageIO to be configured with ZLIB support, and will not be compiled." ) endif() else() message( STATUS "NOTICE: Some examples need the CGAL_ImageIO library, and will not be compiled." ) diff --git a/Mesh_3/include/CGAL/Implicit_to_labeling_function_wrapper.h b/Mesh_3/include/CGAL/Implicit_to_labeling_function_wrapper.h index fe93dde3bc0..eb2a9459ee1 100644 --- a/Mesh_3/include/CGAL/Implicit_to_labeling_function_wrapper.h +++ b/Mesh_3/include/CGAL/Implicit_to_labeling_function_wrapper.h @@ -173,7 +173,7 @@ public: Implicit_multi_domain_to_labeling_function_wrapper (const Function_vector& vf, const std::vector >& vps) : funcs(vf), bmasks(vps.size(), Bmask(funcs.size() * 2, false)) { - assert(funcs.size()); + CGAL_assertion(funcs.size() != 0); std::size_t mask_index = 0; for (std::vector >::const_iterator mask_iter = vps.begin(), mask_end_iter = vps.end(); @@ -181,14 +181,14 @@ public: ++mask_iter) { const std::vector& mask = *mask_iter; - assert(funcs.size() == mask.size()); + CGAL_assertion(funcs.size() == mask.size()); Bmask& bmask = bmasks[mask_index++]; typename Bmask::size_type bit_index = 0; for (std::vector::const_iterator iter = mask.begin(), endIter = mask.end(); iter != endIter; ++iter) { std::string::value_type character = *iter; - assert(character == POSITIVE || character == NEGATIVE); + CGAL_assertion(character == POSITIVE || character == NEGATIVE); bmask[bit_index] = (character == POSITIVE); ++bit_index; @@ -202,7 +202,7 @@ public: Implicit_multi_domain_to_labeling_function_wrapper (const Function_vector& vf) : funcs(vf) { - assert(funcs.size()); + CGAL_assertion(funcs.size() != 0); bmasks.reserve((1 << funcs.size()) - 1); bmasks.push_back(Bmask(std::string("10"))); @@ -228,7 +228,7 @@ public: Implicit_multi_domain_to_labeling_function_wrapper (const Function_vector& vf, const std::vector& vps) : funcs(vf), bmasks(vps.size(), Bmask(funcs.size() * 2, false)) { - assert(funcs.size()); + CGAL_assertion(funcs.size() != 0); std::size_t mask_index = 0; for (std::vector::const_iterator mask_iter = vps.begin(), mask_end_iter = vps.end(); @@ -236,14 +236,14 @@ public: ++mask_iter) { const std::string& mask_str = *mask_iter; - assert(funcs.size() == mask_str.length()); + CGAL_assertion(funcs.size() == mask_str.length()); Bmask& bmask = bmasks[mask_index++]; typename Bmask::size_type bit_index = 0; for (std::string::const_iterator iter = mask_str.begin(), endIter = mask_str.end(); iter != endIter; ++iter) { std::string::value_type character = *iter; - assert(character == '+' || character == '-'); + CGAL_assertion(character == '+' || character == '-'); bmask[bit_index] = (character == '+'); ++bit_index; diff --git a/Mesh_3/include/CGAL/Mesh_3/C3T3_helpers.h b/Mesh_3/include/CGAL/Mesh_3/C3T3_helpers.h index 8f4c6c7b8f5..fdc80ae1618 100644 --- a/Mesh_3/include/CGAL/Mesh_3/C3T3_helpers.h +++ b/Mesh_3/include/CGAL/Mesh_3/C3T3_helpers.h @@ -1162,7 +1162,7 @@ private: Subdomain operator()(const Cell_handle& ch, const bool update = true) const { if ( c3t3_.triangulation().is_infinite(ch) ) - return false; + return Subdomain(); // treat cell const Subdomain subdomain = diff --git a/Nef_3/doc/Nef_3/CGAL/Nef_polyhedron_3.h b/Nef_3/doc/Nef_3/CGAL/Nef_polyhedron_3.h index bf4cd3a6224..5bd58016f54 100644 --- a/Nef_3/doc/Nef_3/CGAL/Nef_polyhedron_3.h +++ b/Nef_3/doc/Nef_3/CGAL/Nef_polyhedron_3.h @@ -1185,7 +1185,7 @@ public: /*! creates a Nef polyhedron consisting of a single polygon spanned by the list of points in the iterator range - `[begin,end)`. If the points do not on a common + `[begin,end)`. If the points do not lie on a common supporting plane, the constructor tries to triangulate the polygon into multiple facets.If the construction does not succeed, the empty set is created. @@ -1193,8 +1193,10 @@ public: Nef_polyhedron_3(Input_iterator begin, Input_iterator end); /*! - The iterator range [it, end) defines a set point - ranges, each of which defines a polyline. + creates a Nef polyhedron consisting of polylines. + The iterator range [it, end) defines a range of polylines. + Each polyline is defined as a range of points, first and + past-the-end iterators being provided as a `std::pair` of iterators. */ template Nef_polyhedron_3(Forward_iterator it, Forward_iterator end, diff --git a/Number_types/include/CGAL/Mpzf.h b/Number_types/include/CGAL/Mpzf.h index 661c96a78a8..eca5baf31e5 100644 --- a/Number_types/include/CGAL/Mpzf.h +++ b/Number_types/include/CGAL/Mpzf.h @@ -483,7 +483,7 @@ struct Mpzf { } #endif if(u.s.sig) size=-size; - //assert(to_double()==IA_force_to_double(d)); + //CGAL_assertion(to_double()==IA_force_to_double(d)); } #ifdef CGAL_USE_GMPXX diff --git a/Number_types/include/CGAL/Sqrt_extension/convert_to_bfi.h b/Number_types/include/CGAL/Sqrt_extension/convert_to_bfi.h index 4198c3e0986..fb48ed9e94e 100644 --- a/Number_types/include/CGAL/Sqrt_extension/convert_to_bfi.h +++ b/Number_types/include/CGAL/Sqrt_extension/convert_to_bfi.h @@ -27,6 +27,7 @@ #include #include #include +#include // Disbale SQRT_EXTENSION_TO_BFI_CACHE by default @@ -92,8 +93,8 @@ convert_to_bfi(const CGAL::Sqrt_extension& x) { }else{ result_ = convert_to_bfi(x.a0()); } - assert(lower(result) == lower(result_)); - assert(upper(result) == upper(result_)); + CGAL_assertion(lower(result) == lower(result_)); + CGAL_assertion(upper(result) == upper(result_)); #endif return result; } diff --git a/Operations_on_polyhedra/include/CGAL/intersection_of_Polyhedra_3.h b/Operations_on_polyhedra/include/CGAL/intersection_of_Polyhedra_3.h index 4f4159d4186..2d6ddeee48a 100644 --- a/Operations_on_polyhedra/include/CGAL/intersection_of_Polyhedra_3.h +++ b/Operations_on_polyhedra/include/CGAL/intersection_of_Polyhedra_3.h @@ -1396,7 +1396,7 @@ class Intersection_of_Polyhedra_3{ switch(type){ case internal_IOP::COPLNR: #ifndef DO_NOT_HANDLE_COPLANAR_FACETS - assert(!"COPLNR : this point should never be reached!"); + CGAL_assertion(!"COPLANR : this point should never be reached!"); #else //nothing need to be done, cf. comments at the beginning of the file #endif diff --git a/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/PackageDescription.txt b/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/PackageDescription.txt index 0a161f010c8..3964f68c68c 100644 --- a/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/PackageDescription.txt +++ b/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/PackageDescription.txt @@ -29,7 +29,7 @@ \cgalPkgShortInfoBegin \cgalPkgSince{4.3} -\cgalPkgDependsOn{\ref PkgTDS2Summary and \ref PkgTriangulation2Summary} +\cgalPkgDependsOn{\ref PkgTriangulation2Summary} \cgalPkgBib{cgal:k-pt2-13} \cgalPkgLicense{\ref licensesGPL "GPL"} \cgalPkgDemo{Periodic Delaunay Triangulation,Periodic_2_Delaunay_triangulation_2.zip} diff --git a/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/PackageDescription.txt b/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/PackageDescription.txt index 33167b5ceff..a8cc0b0288f 100644 --- a/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/PackageDescription.txt +++ b/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/PackageDescription.txt @@ -23,7 +23,7 @@ \cgalPkgSummaryEnd \cgalPkgShortInfoBegin \cgalPkgSince{3.5} -\cgalPkgDependsOn{\ref PkgTriangulation3Summary and \ref PkgTDS3Summary} +\cgalPkgDependsOn{\ref PkgTDS3Summary} \cgalPkgBib{cgal:ct-pt3} \cgalPkgLicense{\ref licensesGPL "GPL"} \cgalPkgDemo{3D Periodic Delaunay Triangulation,periodic_3_triangulation_3.zip,3D Periodic Lloyd,periodic_3_lloyd.zip} diff --git a/Point_set_processing_3/include/CGAL/IO/write_xyz_points.h b/Point_set_processing_3/include/CGAL/IO/write_xyz_points.h index b3bd3c89a84..b8b75c7fa52 100644 --- a/Point_set_processing_3/include/CGAL/IO/write_xyz_points.h +++ b/Point_set_processing_3/include/CGAL/IO/write_xyz_points.h @@ -46,7 +46,7 @@ namespace CGAL { /// /// @tparam ForwardIterator iterator over input points. /// @tparam PointPMap is a model of `ReadablePropertyMap` with a value type = `Point_3`. -/// It can be omitted if the value type of `ForwardIterator value_type is convertible to `Point_3`. +/// It can be omitted if the value type of `ForwardIterator` is convertible to `Point_3`. /// @tparam NormalPMap is a model of `ReadablePropertyMap` with a value type `Vector_3`. /// @tparam Kernel Geometric traits class. /// It can be omitted and deduced automatically from the value type of `PointPMap`. diff --git a/Point_set_processing_3/include/CGAL/bilateral_smooth_point_set.h b/Point_set_processing_3/include/CGAL/bilateral_smooth_point_set.h index 2197d1ba0c3..faa35a2bd8c 100644 --- a/Point_set_processing_3/include/CGAL/bilateral_smooth_point_set.h +++ b/Point_set_processing_3/include/CGAL/bilateral_smooth_point_set.h @@ -449,9 +449,9 @@ bilateral_smooth_point_set( CGAL_point_set_processing_precondition(n.squared_length() > 1e-10); pwns.push_back(Pwn(p, n)); - } + } - unsigned int nb_points = pwns.size(); + std::size_t nb_points = pwns.size(); #ifdef CGAL_PSP3_VERBOSE std::cout << "Initialization and compute max spacing: " << std::endl; diff --git a/Point_set_processing_3/include/CGAL/edge_aware_upsample_point_set.h b/Point_set_processing_3/include/CGAL/edge_aware_upsample_point_set.h index 3321f0d3155..83d3f70f7fe 100644 --- a/Point_set_processing_3/include/CGAL/edge_aware_upsample_point_set.h +++ b/Point_set_processing_3/include/CGAL/edge_aware_upsample_point_set.h @@ -153,7 +153,7 @@ update_new_point( typedef typename Kernel::FT FT; typedef typename rich_grid_internal::Rich_point Rich_point; - CGAL_assertion_code( unsigned int size = rich_point_set.size() ); + CGAL_assertion_code( unsigned int size = static_cast(rich_point_set.size()) ); CGAL_point_set_processing_precondition(father_index >= 0 && father_index < size); CGAL_point_set_processing_precondition(mother_index >= 0 && @@ -431,7 +431,7 @@ edge_aware_upsample_point_set( std::cout << "current radius: " << current_radius << std::endl; #endif - unsigned int current_size = rich_point_set.size(); + std::size_t current_size = rich_point_set.size(); std::vector is_pass_threshold(current_size, false); if (iter_time == 0) @@ -533,7 +533,7 @@ edge_aware_upsample_point_set( Rich_point& base = rich_point_set[mother_index]; Vector diff_v_base = base.pt - v.pt; new_v.pt = v.pt + (diff_v_base * FT(0.5)); - new_v.index = rich_point_set.size(); + new_v.index = static_cast(rich_point_set.size()); unsigned int new_point_index = new_v.index; rich_point_set.push_back(new_v); @@ -570,7 +570,7 @@ edge_aware_upsample_point_set( } } - for (unsigned int i = number_of_input; i < rich_point_set.size(); ++i) + for (std::size_t i = number_of_input; i < rich_point_set.size(); ++i) { Rich_point& v = rich_point_set[i]; Point point = v.pt; diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt index 79a83c474f8..69995aff662 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt @@ -28,7 +28,7 @@ ranging from basic operations on simplices, to complex geometry processing algor \cgalPkgShortInfoBegin \cgalPkgSince{4.7} -\cgalPkgDependsOn{\ref PkgTriangulation3Summary, Sparse square solver such as those from \ref thirdpartyEigen} +\cgalPkgDependsOn{documented for each function; Sparse square solver such as those from \ref thirdpartyEigen} \cgalPkgBib{cgal:lty-pmp} \cgalPkgLicense{\ref licensesGPL "GPL"} \cgalPkgDemo{Operations on Polyhedra,polyhedron_3.zip} @@ -72,6 +72,7 @@ and provides a list of the parameters that are used in this package. - \link stitching_grp `CGAL::Polygon_mesh_processing::stitch_borders()` \endlink - `CGAL::Polygon_mesh_processing::polygon_soup_to_polygon_mesh()` - `CGAL::Polygon_mesh_processing::orient_polygon_soup()` + ******************* \subsection PolygonSoups Polygon Soups @@ -457,7 +458,6 @@ Function or Class | Pure Triangle | Self-Intersection Free `stitch_borders()` | no | no | no `polygon_soup_to_polygon_mesh()` | no | no | no `orient_polygon_soup()` | no | no | no -`remove_degenerate_faces()` | yes | no | no `remove_isolated_vertices()` | no | no | no `compute_face_normal()` | no | no | no `compute_face_normals()` | no | no | no @@ -471,6 +471,9 @@ Function or Class | Pure Triangle | Self-Intersection Free `keep_connected_components()` | no | no | no `remove_connected_components()` | no | no | no + **************************************** \section PMPHistory Implementation History diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/examples.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/examples.txt index a2dfeb51fe6..edb3b337e9e 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/examples.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/examples.txt @@ -11,6 +11,5 @@ \example Polygon_mesh_processing/triangulate_polyline_example.cpp \example Polygon_mesh_processing/refine_fair_example.cpp \example Polygon_mesh_processing/mesh_slicer_example.cpp -\example Polygon_mesh_processing/remove_degeneracies_example.cpp */ diff --git a/Polygon_mesh_processing/dont_submit b/Polygon_mesh_processing/dont_submit new file mode 100644 index 00000000000..9ee49f9ce2d --- /dev/null +++ b/Polygon_mesh_processing/dont_submit @@ -0,0 +1,2 @@ +examples/Polygon_mesh_processing/remove_degeneracies_example.cpp +examples/Polygon_mesh_processing/remove_degeneracies_example_OM.cpp diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt b/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt index c9d58e10ff0..1e795107a15 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt @@ -81,7 +81,7 @@ create_single_source_cgal_program( "connected_components_example.cpp") create_single_source_cgal_program( "polygon_soup_example.cpp") create_single_source_cgal_program( "triangulate_polyline_example.cpp") create_single_source_cgal_program( "mesh_slicer_example.cpp") -create_single_source_cgal_program( "remove_degeneracies_example.cpp") +#create_single_source_cgal_program( "remove_degeneracies_example.cpp") create_single_source_cgal_program( "isotropic_remeshing_example.cpp") if(NOT (${EIGEN3_VERSION} VERSION_LESS 3.2.0)) @@ -105,8 +105,8 @@ target_link_libraries( point_inside_example_OM ${OPENMESH_LIBRARIES} ) create_single_source_cgal_program( "stitch_borders_example_OM.cpp" ) target_link_libraries( stitch_borders_example_OM ${OPENMESH_LIBRARIES} ) -create_single_source_cgal_program( "remove_degeneracies_example_OM.cpp") -target_link_libraries( remove_degeneracies_example_OM ${OPENMESH_LIBRARIES} ) +#create_single_source_cgal_program( "remove_degeneracies_example_OM.cpp") +#target_link_libraries( remove_degeneracies_example_OM ${OPENMESH_LIBRARIES} ) create_single_source_cgal_program( "triangulate_faces_example_OM.cpp") target_link_libraries( triangulate_faces_example_OM ${OPENMESH_LIBRARIES} ) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/connected_components.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/connected_components.h index 0ed1297c16b..a77dec77490 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/connected_components.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/connected_components.h @@ -32,6 +32,7 @@ #include #include +#include #include #include #include @@ -724,7 +725,7 @@ void keep_or_remove_connected_components(PolygonMesh& pmesh } else { // no face kept - assert((is_border(h, pmesh) || !get(fcm,fh)) && (is_border(oh, pmesh) || !get(fcm,ofh))); + CGAL_assertion((is_border(h, pmesh) || !get(fcm,fh)) && (is_border(oh, pmesh) || !get(fcm,ofh))); // vertices pointing to e must change their halfedge if (halfedge(v, pmesh) == oh){ set_halfedge(v, prev(h, pmesh), pmesh); @@ -746,7 +747,7 @@ void keep_or_remove_connected_components(PolygonMesh& pmesh remove_edge(e, pmesh); } else { - assert(keep_vertex[w]); + CGAL_assertion(keep_vertex[w]); if (halfedge(w, pmesh) == h){ set_halfedge(w, prev(oh, pmesh), pmesh); } diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/polygon_soup_to_polygon_mesh.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/polygon_soup_to_polygon_mesh.h index 2e0f343ec9d..58e072e9cf7 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/polygon_soup_to_polygon_mesh.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/polygon_soup_to_polygon_mesh.h @@ -14,7 +14,7 @@ // // $URL$ // $Id$ -// +// // // Author(s) : Laurent Rineau and Ilker O. Yaz @@ -91,6 +91,42 @@ public: }; }//end namespace internal + + /// \cond SKIP_IN_MANUAL + /** + * \ingroup PkgPolygonMeshProcessing + * returns `true` if the soup of polygons defines a valid polygon mesh + * that can be handled by `CGAL::Polygon_mesh_processing::polygon_soup_to_polygon_mesh()`. + * + * @tparam Polygon a `std::vector` containing the indices + * of the points of the polygon face + * + * @param polygons each element in the vector describes a polygon using the index of the vertices + * + */ + template + bool is_polygon_soup_a_polygon_mesh(const std::vector& polygons) + { + typedef typename std::iterator_traits< + typename Polygon::iterator >::value_type V_ID; + + std::set< std::pair > edge_set; + BOOST_FOREACH(const Polygon& polygon, polygons) + { + std::size_t nb_edges = polygon.size(); + if (nb_edges<3) return false; + V_ID prev=polygon.back(); + BOOST_FOREACH(V_ID id, polygon) + if (! edge_set.insert(std::pair(prev,id)).second ) + return false; + else + prev=id; + } + + return true; + } + /// \endcond + /** * \ingroup PkgPolygonMeshProcessing * builds a polygon mesh from a soup of polygons. 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 63d82d2c9e4..9163f9b0c0e 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair.h @@ -33,6 +33,61 @@ namespace CGAL{ namespace Polygon_mesh_processing { +namespace debug{ + template + std::ostream& dump_edge_neighborhood( + typename boost::graph_traits::edge_descriptor ed, + TriangleMesh& tmesh, + const VertexPointMap& vpmap, + std::ostream& out) + { + typedef boost::graph_traits GT; + typedef typename GT::halfedge_descriptor halfedge_descriptor; + typedef typename GT::vertex_descriptor vertex_descriptor; + typedef typename GT::face_descriptor face_descriptor; + + halfedge_descriptor h = halfedge(ed, tmesh); + + std::map vertices; + std::set faces; + int vindex=0; + BOOST_FOREACH(halfedge_descriptor hd, halfedges_around_target(h, tmesh)) + { + if ( vertices.insert(std::make_pair(source(hd, tmesh), vindex)).second ) + ++vindex; + if (!is_border(hd, tmesh)) + faces.insert( face(hd, tmesh) ); + } + + h=opposite(h, tmesh); + BOOST_FOREACH(halfedge_descriptor hd, halfedges_around_target(h, tmesh)) + { + if ( vertices.insert(std::make_pair(source(hd, tmesh), vindex)).second ) + ++vindex; + if (!is_border(hd, tmesh)) + faces.insert( face(hd, tmesh) ); + } + + std::vector ordered_vertices(vertices.size()); + typedef std::pair Pair_type; + BOOST_FOREACH(const Pair_type& p, vertices) + ordered_vertices[p.second]=p.first; + + out << "OFF\n" << ordered_vertices.size() << " " << faces.size() << " 0\n"; + BOOST_FOREACH(vertex_descriptor vd, ordered_vertices) + out << get(vpmap, vd) << "\n"; + BOOST_FOREACH(face_descriptor fd, faces) + { + out << "3"; + h=halfedge(fd,tmesh); + BOOST_FOREACH(halfedge_descriptor hd, halfedges_around_face(h, tmesh)) + out << " " << vertices[target(hd, tmesh)]; + out << "\n"; + } + return out; + } +} //end of namespace debug + template struct Less_vertex_point{ typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; @@ -87,155 +142,300 @@ bool is_degenerated( return is_degenerated(halfedge(fd,tmesh), tmesh, vpmap, traits); } -#if 0 -namespace internal { +///\cond SKIP_IN_MANUAL +template +std::size_t remove_null_edges( + const EdgeRange& edge_range, + TriangleMesh& tmesh, + const NamedParameters& np) +{ + CGAL_assertion(CGAL::is_triangle_mesh(tmesh)); - // hbase is an edge of length 0 we cannot contract because - // the link condition is not satisfied. - // In this function we look whether the condition is not - // satisfied because of some faces on the "side" of hbase. - // Here we look for two halfedges that together with hbase - // enclose a set of degenerate faces so as to replace that - // set with only one triangle - template - boost::optional< - std::pair< - typename boost::graph_traits::halfedge_descriptor, - typename boost::graph_traits::halfedge_descriptor > - > - find_larger_triangle( - typename boost::graph_traits::halfedge_descriptor hbase, - TriangleMesh& tmesh, - const VertexPointMap& vpmap, - const Traits& traits) + using boost::choose_const_pmap; + using boost::get_param; + using boost::choose_param; + + typedef TriangleMesh TM; + typedef typename boost::graph_traits GT; + typedef typename GT::edge_descriptor edge_descriptor; + typedef typename GT::halfedge_descriptor halfedge_descriptor; + typedef typename GT::face_descriptor face_descriptor; + typedef typename GT::vertex_descriptor vertex_descriptor; + + typedef typename GetVertexPointMap::type VertexPointMap; + VertexPointMap vpmap = choose_pmap(get_param(np, boost::vertex_point), + tmesh, + boost::vertex_point); + typedef typename GetGeomTraits::type Traits; + Traits traits = choose_param(get_param(np, geom_traits), Traits()); + + std::size_t nb_deg_faces = 0; + + // collect edges of length 0 + std::set null_edges_to_remove; + BOOST_FOREACH(edge_descriptor ed, edge_range) { - typedef typename boost::graph_traits GT; - typedef typename GT::halfedge_descriptor halfedge_descriptor; + if ( traits.equal_3_object()(get(vpmap, target(ed, tmesh)), get(vpmap, source(ed, tmesh))) ) + null_edges_to_remove.insert(ed); + } - bool no_pb=false; - // hbase = v0 -> v1 - // consider hedges with v0 as target - halfedge_descriptor left_hedge = prev(hbase, tmesh), o_right_hedge=left_hedge; - do + while (!null_edges_to_remove.empty()) + { + edge_descriptor ed = *null_edges_to_remove.begin(); + null_edges_to_remove.erase(null_edges_to_remove.begin()); + + halfedge_descriptor h = halfedge(ed, tmesh); + + if (CGAL::Euler::does_satisfy_link_condition(ed,tmesh)) { - left_hedge = prev( opposite(left_hedge, tmesh), tmesh ); - if ( face(left_hedge, tmesh) == GT::null_face() || - !is_degenerated(left_hedge, tmesh, vpmap, traits) ) + // remove edges that could also be set for removal + if ( face(h, tmesh)!=GT::null_face() ) { - no_pb=true; - break; + ++nb_deg_faces; + null_edges_to_remove.erase(edge(prev(h, tmesh), tmesh)); } - // look for a halfedge with v1 as target - BOOST_FOREACH(o_right_hedge, halfedges_around_source(left_hedge, tmesh) ) + if (face(opposite(h, tmesh), tmesh)!=GT::null_face()) { - if ( target(o_right_hedge, tmesh) == target(hbase, tmesh) ) + ++nb_deg_faces; + null_edges_to_remove.erase(edge(prev(opposite(h, tmesh), tmesh), tmesh)); + } + //now remove the edge + CGAL::Euler::collapse_edge(ed, tmesh); + } + else{ + //handle the case when the edge is incident to a triangle hole + //we first fill the hole and try again + if ( is_border(ed, tmesh) ) + { + halfedge_descriptor hd = halfedge(ed,tmesh); + if (!is_border(hd,tmesh)) hd=opposite(hd,tmesh); + if (is_triangle(hd, tmesh)) { - if ( !is_degenerated( opposite(o_right_hedge, tmesh), tmesh, vpmap, traits) ) - no_pb=true; - break; + Euler::fill_hole(hd, tmesh); + null_edges_to_remove.insert(ed); + continue; } } - if ( target(o_right_hedge, tmesh) == target(hbase, tmesh) ) - break; - } - while(true); - if (!no_pb) - return std::make_pair(left_hedge, opposite(o_right_hedge, tmesh)); - return boost::none; - } + // When the edge does not satisfy the link condition, it means that it cannot be + // collapsed as is. In the following we assume that there is no topological issue + // with contracting the edge (no volume will disappear). + // We start by marking the faces that are incident to an edge endpoint. + // If the set of marked faces is a topologically disk, then we simply remove all the simplicies + // inside the disk and star the hole with the edge vertex kept. + // If the set of marked faces is not a topological disk, it has some non-manifold vertices + // on its boundary. We need to mark additional faces to make it a topological disk. + // We can then apply the star hole procedure. + // Right now we additionally mark the smallest connected components of non-marked faces + // (using the numnber of faces) - // h2 is a halfedge of length 0 but collapsing the edge - // is not directly possible because the link condition is not - // satisfied. We remove all simplices bounded by h1, h2 and h3 - // so as to keep only that triangle - template - void - remove_faces_inside_triangle( - typename boost::graph_traits::halfedge_descriptor h1, - typename boost::graph_traits::halfedge_descriptor h2, - typename boost::graph_traits::halfedge_descriptor h3, - TriangleMesh& tmesh, - EdgeMap& edge_map1, - EdgeMap& edge_map2) - { - typedef typename boost::graph_traits GT; - typedef typename GT::edge_descriptor edge_descriptor; - typedef typename GT::halfedge_descriptor halfedge_descriptor; - typedef typename GT::face_descriptor face_descriptor; - typedef typename GT::vertex_descriptor vertex_descriptor; + //backup central point + typename Traits::Point_3 pt = get(vpmap, source(ed, tmesh)); - CGAL_assertion( source(h1,tmesh) == target(h3, tmesh) ); - CGAL_assertion( source(h2,tmesh) == target(h1, tmesh) ); - CGAL_assertion( source(h3,tmesh) == target(h2, tmesh) ); + // mark faces of the link of each endpoints of the edge which collapse is not topologically valid + std::set marked_faces; + // first endpoint + BOOST_FOREACH( halfedge_descriptor hd, CGAL::halfedges_around_target(halfedge(ed,tmesh), tmesh) ) + if (!is_border(hd,tmesh)) marked_faces.insert( face(hd, tmesh) ); + // second endpoint + BOOST_FOREACH( halfedge_descriptor hd, CGAL::halfedges_around_target(opposite(halfedge(ed, tmesh), tmesh), tmesh) ) + if (!is_border(hd,tmesh)) marked_faces.insert( face(hd, tmesh) ); - std::set all_faces; - all_faces.insert(face(h1, tmesh)); - all_faces.insert(face(h2, tmesh)); - all_faces.insert(face(h3, tmesh)); + // extract the halfedges on the boundary of the marked region + std::vector border; + BOOST_FOREACH(face_descriptor fd, marked_faces) + BOOST_FOREACH(halfedge_descriptor hd, CGAL::halfedges_around_face(halfedge(fd,tmesh), tmesh)) + { + halfedge_descriptor hd_opp = opposite(hd, tmesh); + if ( is_border(hd_opp, tmesh) || + marked_faces.count( face(hd, tmesh) )!= + marked_faces.count( face(hd_opp, tmesh) ) ) + { + border.push_back( hd ); + } + } - std::vector queue; - queue.push_back( opposite(prev(h1,tmesh), tmesh) ); - queue.push_back( opposite(next(h1,tmesh), tmesh) ); - queue.push_back( opposite(prev(h2,tmesh), tmesh) ); - queue.push_back( opposite(next(h2,tmesh), tmesh) ); - queue.push_back( opposite(prev(h3,tmesh), tmesh) ); - queue.push_back( opposite(next(h3,tmesh), tmesh) ); + // define cc of border halfedges: two halfedges are in the same cc + // if they are on the border of the cc of non-marked faces. + typedef CGAL::Union_find UF_ds; + UF_ds uf; + std::map handles; + // one cc per border halfedge + BOOST_FOREACH(halfedge_descriptor hd, border) + handles.insert( std::make_pair(hd, uf.make_set(hd)) ); - std::set all_edges; - while(!queue.empty()) - { - halfedge_descriptor back=queue.back(); - queue.pop_back(); - all_edges.insert( edge(back, tmesh) ); - - if ( all_faces.insert( face(back, tmesh) ).second ) + // join cc's + BOOST_FOREACH(halfedge_descriptor hd, border) { - queue.push_back( opposite(prev(back,tmesh), tmesh) ); - queue.push_back( opposite(next(back,tmesh), tmesh) ); + CGAL_assertion( marked_faces.count( face( hd, tmesh) ) > 0); + CGAL_assertion( marked_faces.count( face( opposite(hd, tmesh), tmesh) ) == 0 ); + halfedge_descriptor candidate = hd; + + do{ + candidate = prev( opposite(candidate, tmesh), tmesh ); + } while( !marked_faces.count( face( opposite(candidate, tmesh), tmesh) ) ); + uf.unify_sets( handles[hd], handles[opposite(candidate, tmesh)] ); } - } - std::set all_vertices; - BOOST_FOREACH(edge_descriptor ed, all_edges) - { - all_vertices.insert( source(ed, tmesh) ); - all_vertices.insert( target(ed, tmesh) ); - } - all_vertices.erase( target(h1, tmesh) ); - all_vertices.erase( target(h2, tmesh) ); - all_vertices.erase( target(h3, tmesh) ); + std::size_t nb_cc = uf.number_of_sets(); + if ( nb_cc != 1 ) + { + // if more than one connected component is found then the patch + // made of marked faces contains "non-manifold" vertices. + // The smallest components need to be marked so that the patch + // made of marked faces is a topological disk - // create the triangle - face_descriptor remaining_face = *all_faces.begin(); - all_faces.erase(all_faces.begin()); - // update next-prev pointers - set_next(h1, h2, tmesh); - set_next(h2, h3, tmesh); - set_next(h3, h1, tmesh); - // update vertex pointers - set_halfedge(target(h1,tmesh), h1, tmesh); - set_halfedge(target(h2,tmesh), h2, tmesh); - set_halfedge(target(h3,tmesh), h3, tmesh); - // update face-halfedge pointers - set_face(h1, remaining_face, tmesh); - set_face(h2, remaining_face, tmesh); - set_face(h3, remaining_face, tmesh); - set_halfedge(remaining_face, h2, tmesh); + // we will explore in parallel the connected components and will stop + // when all but one connected component have been entirely explored. + // We add one face at a time for each cc in order to not explore a + // potentially very large cc. + std::vector< std::vector > stacks_per_cc(nb_cc); + std::vector< std::set > faces_per_cc(nb_cc); + std::vector< bool > exploration_finished(nb_cc, false); - // remove interior simplices - BOOST_FOREACH(edge_descriptor ed, all_edges){ - edge_map1.erase(ed); - edge_map2.erase(ed); - remove_edge(ed, tmesh); + + // init the stacks of halfedges using the cc of the boundary + std::size_t index=0; + std::map< halfedge_descriptor, std::size_t > ccs; + typedef std::pair Pair_type; + BOOST_FOREACH(Pair_type p, handles) + { + halfedge_descriptor opp_hedge = opposite(p.first, tmesh); + if (is_border(opp_hedge, tmesh)) continue; // nothing to do on the boundary + + typedef typename std::map< halfedge_descriptor, std::size_t >::iterator Map_it; + std::pair insert_res= + ccs.insert( std::make_pair(*uf.find( p.second ), index) ); + if (insert_res.second) ++index; + + stacks_per_cc[ insert_res.first->second ].push_back( prev(opp_hedge, tmesh) ); + stacks_per_cc[ insert_res.first->second ].push_back( next(opp_hedge, tmesh) ); + faces_per_cc[ insert_res.first->second ].insert( face(opp_hedge, tmesh) ); + } + + std::size_t nb_ccs_to_be_explored = nb_cc; + index=0; + //explore the cc's + do{ + // try to extract one more face for a given cc + do{ + CGAL_assertion( !exploration_finished[index] ); + halfedge_descriptor hd = stacks_per_cc[index].back(); + stacks_per_cc[index].pop_back(); + hd = opposite(hd, tmesh); + if ( !is_border(hd,tmesh) && !marked_faces.count(face(hd, tmesh) ) ) + { + if ( faces_per_cc[index].insert( face(hd, tmesh) ).second ) + { + stacks_per_cc[index].push_back( next(hd, tmesh) ); + stacks_per_cc[index].push_back( prev(hd, tmesh) ); + break; + } + } + if (stacks_per_cc[index].empty()) break; + } + while(true); + // the exploration of a cc is finished when its stack is empty + exploration_finished[index]=stacks_per_cc[index].empty(); + if ( exploration_finished[index] ) --nb_ccs_to_be_explored; + if ( nb_ccs_to_be_explored==1 ) break; + while ( exploration_finished[(++index)%nb_cc] ); + index=index%nb_cc; + }while(true); + + /// \todo use the area criteria? this means maybe continue exploration of larger cc + // mark faces of completetly explored cc + for (index=0; index< nb_cc; ++index) + if( exploration_finished[index] ) + { + BOOST_FOREACH(face_descriptor fd, faces_per_cc[index]) + marked_faces.insert(fd); + } + } + + // collect simplices to be removed + std::set vertices_to_keep; + std::set halfedges_to_keep; + BOOST_FOREACH(halfedge_descriptor hd, border) + if ( !marked_faces.count(face(opposite(hd, tmesh), tmesh)) ) + { + halfedges_to_keep.insert( hd ); + vertices_to_keep.insert( target(hd, tmesh) ); + } + + // backup next,prev relationships to set after patch removal + std::vector< std::pair > next_prev_halfedge_pairs; + halfedge_descriptor first_border_hd=*( halfedges_to_keep.begin() ); + halfedge_descriptor current_border_hd=first_border_hd; + do{ + halfedge_descriptor prev_border_hd=current_border_hd; + current_border_hd=next(current_border_hd, tmesh); + while( marked_faces.count( face( opposite(current_border_hd, tmesh), tmesh) ) ) + current_border_hd=next(opposite(current_border_hd, tmesh), tmesh); + next_prev_halfedge_pairs.push_back( std::make_pair(prev_border_hd, current_border_hd) ); + }while(current_border_hd!=first_border_hd); + + // collect vertices and edges to remove and do remove faces + std::set edges_to_remove; + std::set vertices_to_remove; + BOOST_FOREACH(face_descriptor fd, marked_faces) + { + halfedge_descriptor hd=halfedge(fd, tmesh); + for(int i=0; i<3; ++i) + { + if ( !halfedges_to_keep.count(hd) ) + edges_to_remove.insert( edge(hd, tmesh) ); + if ( !vertices_to_keep.count(target(hd,tmesh)) ) + vertices_to_remove.insert( target(hd,tmesh) ); + hd=next(hd, tmesh); + } + remove_face(fd, tmesh); + } + + // remove vertices + BOOST_FOREACH(vertex_descriptor vd, vertices_to_remove) + remove_vertex(vd, tmesh); + // remove edges + BOOST_FOREACH(edge_descriptor ed, edges_to_remove) + { + null_edges_to_remove.erase(ed); + remove_edge(ed, tmesh); + } + + // add a new face, set all border edges pointing to it + // and update halfedge vertex of patch boundary vertices + face_descriptor new_face = add_face(tmesh); + typedef std::pair Pair_type; + BOOST_FOREACH(const Pair_type& p, next_prev_halfedge_pairs) + { + set_face(p.first, new_face, tmesh); + set_next(p.first, p.second, tmesh); + set_halfedge(target(p.first, tmesh), p.first, tmesh); + } + set_halfedge(new_face, first_border_hd, tmesh); + // triangulate the new face and update the coordinate of the central vertex + halfedge_descriptor new_hd=Euler::add_center_vertex(first_border_hd, tmesh); + put(vpmap, target(new_hd, tmesh), pt); + + BOOST_FOREACH(halfedge_descriptor hd, halfedges_around_target(new_hd, tmesh)) + if ( traits.equal_3_object()(get(vpmap, target(hd, tmesh)), get(vpmap, source(hd, tmesh))) ) + null_edges_to_remove.insert(edge(hd, tmesh)); + + CGAL_assertion( is_valid(tmesh) ); } - BOOST_FOREACH(vertex_descriptor vd, all_vertices) - remove_vertex(vd, tmesh); - BOOST_FOREACH(face_descriptor fd, all_faces) - remove_face(fd, tmesh); } -} // end of namespace internal -#endif + + return nb_deg_faces; +} + +template +std::size_t remove_null_edges( + const EdgeRange& edge_range, + TriangleMesh& tmesh) +{ + return remove_null_edges(edge_range, tmesh, + parameters::all_default()); +} /// \ingroup PkgPolygonMeshProcessing /// removes the degenerate faces from a triangulated surface mesh. @@ -266,7 +466,7 @@ namespace internal { /// \cgalNamedParamsEnd /// /// \return number of removed degenerate faces -/// +/// \endcond template std::size_t remove_degenerate_faces(TriangleMesh& tmesh, const NamedParameters& np) @@ -291,286 +491,10 @@ std::size_t remove_degenerate_faces(TriangleMesh& tmesh, typedef typename GetGeomTraits::type Traits; Traits traits = choose_param(get_param(np, geom_traits), Traits()); - std::size_t nb_deg_faces = 0; - // First remove edges of length 0 - std::set null_edges_to_remove; + std::size_t nb_deg_faces = remove_null_edges(edges(tmesh), tmesh, np); - BOOST_FOREACH(edge_descriptor ed, edges(tmesh)) - { - if ( traits.equal_3_object()(get(vpmap, target(ed, tmesh)), get(vpmap, source(ed, tmesh))) ) - null_edges_to_remove.insert(ed); - } - - std::size_t nb_edges_previously_skipped = 0; - do{ - std::set edges_to_remove_skipped; - while (!null_edges_to_remove.empty()) - { - edge_descriptor ed = *null_edges_to_remove.begin(); - null_edges_to_remove.erase(null_edges_to_remove.begin()); - - halfedge_descriptor h = halfedge(ed, tmesh); - - if (CGAL::Euler::does_satisfy_link_condition(ed,tmesh)) - { - // remove edges that could also be set for removal - if ( face(h, tmesh)!=GT::null_face() ) - { - ++nb_deg_faces; - null_edges_to_remove.erase(edge(prev(h, tmesh), tmesh)); - edges_to_remove_skipped.erase(edge(prev(h, tmesh), tmesh)); - } - if (face(opposite(h, tmesh), tmesh)!=GT::null_face()) - { - ++nb_deg_faces; - null_edges_to_remove.erase(edge(prev(opposite(h, tmesh), tmesh), tmesh)); - edges_to_remove_skipped.erase(edge(prev(opposite(h, tmesh), tmesh), tmesh)); - } - //now remove the edge - CGAL::Euler::collapse_edge(ed, tmesh); - } - else{ - //backup central point - typename Traits::Point_3 pt = get(vpmap, source(ed, tmesh)); - - // mark faces of the link of each endpoints of the edge which collapse is not topologically valid - std::set marked_faces; - std::vector candidate_border; - // first endpoint - BOOST_FOREACH( halfedge_descriptor hd, CGAL::halfedges_around_target(halfedge(ed,tmesh), tmesh) ) - { - marked_faces.insert( face(hd, tmesh) ); - candidate_border.push_back( prev(hd, tmesh) ); - } - // second endpoint - BOOST_FOREACH( halfedge_descriptor hd, CGAL::halfedges_around_target(opposite(halfedge(ed, tmesh), tmesh), tmesh) ) - { - marked_faces.insert( face(hd, tmesh) ); - candidate_border.push_back( prev(hd, tmesh) ); - } - - // extract the halfedge on the boundary of the marked region - std::vector border; - BOOST_FOREACH(halfedge_descriptor hd, candidate_border) - { - if ( marked_faces.count( face(hd, tmesh) )!= - marked_faces.count( face(opposite(hd, tmesh), tmesh) ) ) - { - border.push_back( hd ); - } - } - - // define cc of border halfedges: two halfedges are in the same cc - // if they are on the border of a set of non-marked faces sharing - // a common vertex - typedef CGAL::Union_find UF_ds; - UF_ds uf; - std::map handles; - // one cc per border halfedge - BOOST_FOREACH(halfedge_descriptor hd, border) - handles.insert( std::make_pair(hd, uf.make_set(hd)) ); - - // join cc's - BOOST_FOREACH(halfedge_descriptor hd, border) - { - CGAL_assertion( marked_faces.count( face( hd, tmesh) ) > 0); - CGAL_assertion( marked_faces.count( face( opposite(hd, tmesh), tmesh) ) == 0 ); - halfedge_descriptor candidate = hd; - - do{ - candidate = prev( opposite(candidate, tmesh), tmesh ); - } while( !marked_faces.count( face( opposite(candidate, tmesh), tmesh) ) ); - uf.unify_sets( handles[hd], handles[opposite(candidate, tmesh)] ); - } - - std::size_t nb_cc = uf.number_of_sets(); - if ( nb_cc != 1 ) - { - // if more than one connected component is found then the patch - // made of marked faces contains "non-manifold" vertices. - // The smallest components need to be marked so that the patch - // made of marked faces is a topological disk - - // extract one border halfedge per cc - std::set< halfedge_descriptor > ccs; - BOOST_FOREACH(halfedge_descriptor hd, border) - ccs.insert( *uf.find( handles[hd] ) ); - - // we will explore in parallel the connected components and will stop - // when all but one connected component have been entirely explored. - // We have one face at a time for each cc in order to not explore a - // potentially very large cc. - std::vector< std::vector > stacks_per_cc(nb_cc); - std::vector< std::set > faces_per_cc(nb_cc); - std::vector< bool > exploration_finished(nb_cc, false); - - // init stacks - std::size_t index=0; - BOOST_FOREACH( halfedge_descriptor hd, ccs) - { - halfedge_descriptor opp_hedge = opposite(hd, tmesh); - stacks_per_cc[ index ].push_back( prev(opp_hedge, tmesh) ); - stacks_per_cc[ index ].push_back( next(opp_hedge, tmesh) ); - faces_per_cc[ index ].insert( face(opp_hedge, tmesh) ); - ++index; - } - - std::size_t nb_ccs_to_be_explored = nb_cc; - index=0; - //explore the cc's - do{ - // try to extract one more face for a given cc - do{ - CGAL_assertion( !exploration_finished[index] ); - halfedge_descriptor hd = stacks_per_cc[index].back(); - stacks_per_cc[index].pop_back(); - hd = opposite(hd, tmesh); - if ( !marked_faces.count(face(hd, tmesh) ) ) - { - if ( faces_per_cc[index].insert( face(hd, tmesh) ).second ) - { - stacks_per_cc[index].push_back( next(hd, tmesh) ); - stacks_per_cc[index].push_back( prev(hd, tmesh) ); - break; - } - } - if (stacks_per_cc[index].empty()) break; - } - while(true); - // the exploration of a cc is finished when its stack is empty - exploration_finished[index]=stacks_per_cc[index].empty(); - if ( exploration_finished[index] ) --nb_ccs_to_be_explored; - if ( nb_ccs_to_be_explored==1 ) break; - while ( exploration_finished[(++index)%nb_cc] ); - index=index%nb_cc; - }while(true); - - /// \todo use the area criteria? this means maybe continue exploration of larger cc - // mark faces of completetly explored cc - for (index=0; index< nb_cc; ++index) - if( exploration_finished[index] ) - { - BOOST_FOREACH(face_descriptor fd, faces_per_cc[index]) - marked_faces.insert(fd); - } - } - - // collect simplices to be removed - std::set vertices_to_keep; - std::set halfedges_to_keep; - BOOST_FOREACH(halfedge_descriptor hd, border) - if ( !marked_faces.count(face(opposite(hd, tmesh), tmesh)) ) - { - halfedges_to_keep.insert( hd ); - vertices_to_keep.insert( target(hd, tmesh) ); - } - - // backup next,prev relationships to set after patch removal - std::vector< std::pair > next_prev_halfedge_pairs; - halfedge_descriptor first_border_hd=*( halfedges_to_keep.begin() ); - halfedge_descriptor current_border_hd=first_border_hd; - do{ - halfedge_descriptor prev_border_hd=current_border_hd; - current_border_hd=next(current_border_hd, tmesh); - while( marked_faces.count( face( opposite(current_border_hd, tmesh), tmesh) ) ) - current_border_hd=next(opposite(current_border_hd, tmesh), tmesh); - next_prev_halfedge_pairs.push_back( std::make_pair(prev_border_hd, current_border_hd) ); - }while(current_border_hd!=first_border_hd); - - // collect vertices and edges to remove and do remove faces - std::set edges_to_remove; - std::set vertices_to_remove; - BOOST_FOREACH(face_descriptor fd, marked_faces) - { - halfedge_descriptor hd=halfedge(fd, tmesh); - for(int i=0; i<3; ++i) - { - if ( !halfedges_to_keep.count(hd) ) - edges_to_remove.insert( edge(hd, tmesh) ); - if ( !vertices_to_keep.count(target(hd,tmesh)) ) - vertices_to_remove.insert( target(hd,tmesh) ); - hd=next(hd, tmesh); - } - remove_face(fd, tmesh); - } - - // remove vertices - BOOST_FOREACH(vertex_descriptor vd, vertices_to_remove) - remove_vertex(vd, tmesh); - // remove edges - BOOST_FOREACH(edge_descriptor ed, edges_to_remove) - { - null_edges_to_remove.erase(ed); - remove_edge(ed, tmesh); - } - - // add a new face, set all border edges pointing to it - // and update halfedge vertex of patch boundary vertices - face_descriptor new_face = add_face(tmesh); - typedef std::pair Pair_type; - BOOST_FOREACH(const Pair_type& p, next_prev_halfedge_pairs) - { - set_face(p.first, new_face, tmesh); - set_next(p.first, p.second, tmesh); - set_halfedge(target(p.first, tmesh), p.first, tmesh); - } - set_halfedge(new_face, first_border_hd, tmesh); - // triangulate the new face and update the coordinate of the central vertex - halfedge_descriptor new_hd=Euler::add_center_vertex(first_border_hd, tmesh); - put(vpmap, target(new_hd, tmesh), pt); - - BOOST_FOREACH(halfedge_descriptor hd, halfedges_around_target(new_hd, tmesh)) - if ( traits.equal_3_object()(get(vpmap, target(hd, tmesh)), get(vpmap, source(hd, tmesh))) ) - null_edges_to_remove.insert(edge(hd, tmesh)); - - #if 0 - // the following test filters in particular cases where the - // detection of the vertex that breaks the link condition - // is not correctly detected by find_larger_triangle - // (i.e. when the hedges detected should be used with the opposite edge) - if ( traits.collinear_3_object()( - get(vpmap, target(h, tmesh)), - get(vpmap, target(next(h, tmesh), tmesh)), - get(vpmap, target(next(opposite(h, tmesh), tmesh), tmesh)) ) ) - { - // we handle this case in the next loop removing set of degenerated - // triangles which points are collinear - edges_to_remove_skipped.insert(ed); - continue; - } - - do{ - // improve the link condition on h's side - boost::optional< std::pair > - res = internal::find_larger_triangle(h, tmesh, vpmap, traits); - if (res) - internal::remove_faces_inside_triangle(res->first, h, res->second, tmesh, null_edges_to_remove, edges_to_remove_skipped); - - // improve the link condition on opposite(h)'s side - h=opposite(h, tmesh); - res = internal::find_larger_triangle(h, tmesh, vpmap, traits); - if (res) - internal::remove_faces_inside_triangle(res->first, h, res->second, tmesh, null_edges_to_remove, edges_to_remove_skipped); - h=opposite(h, tmesh); - ed=edge(h, tmesh); - - } while(!CGAL::Euler::does_satisfy_link_condition(ed,tmesh)); - - null_edges_to_remove.insert( ed ); - #endif - } - } - - // check if some edges were skipped due to link condition not satisfied - // that could now be satisfied - if (edges_to_remove_skipped.empty() || - edges_to_remove_skipped.size()==nb_edges_previously_skipped) break; - null_edges_to_remove.swap(edges_to_remove_skipped); - nb_edges_previously_skipped = null_edges_to_remove.size(); - } while(true); - -// remove triangles made of 3 collinear points +// Then, remove triangles made of 3 collinear points std::set degenerate_face_set; BOOST_FOREACH(face_descriptor fd, faces(tmesh)) if ( is_degenerated(fd, tmesh, vpmap, traits) ) diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/data_degeneracies/trihole.off b/Polygon_mesh_processing/test/Polygon_mesh_processing/data_degeneracies/trihole.off new file mode 100644 index 00000000000..fe2b633bb8a --- /dev/null +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/data_degeneracies/trihole.off @@ -0,0 +1,16 @@ +OFF +7 7 0 +1 0 0 +0 1 0 +1 1 0 +2 1 0 +1 1 0 +1 2 0 +0.5 1 0 +3 0 2 1 +3 0 3 2 +3 4 3 5 +3 1 4 5 +3 1 2 6 +3 6 2 4 +3 6 4 1 diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/remove_degeneracies_test.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/remove_degeneracies_test.cpp index e30809571de..76c22bf4665 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/remove_degeneracies_test.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/remove_degeneracies_test.cpp @@ -32,6 +32,7 @@ int main() fix("data_degeneracies/degtri_on_border.off"); fix("data_degeneracies/degtri_three.off"); fix("data_degeneracies/degtri_single.off"); + fix("data_degeneracies/trihole.off"); return 0; } diff --git a/Polyhedron/demo/Polyhedron/CGAL_demo/Scene_interface.h b/Polyhedron/demo/Polyhedron/CGAL_demo/Scene_interface.h index 1cae5d3f22b..9ac8df9842a 100644 --- a/Polyhedron/demo/Polyhedron/CGAL_demo/Scene_interface.h +++ b/Polyhedron/demo/Polyhedron/CGAL_demo/Scene_interface.h @@ -12,6 +12,7 @@ class Scene_item; // OpenGL rendering mode enum RenderingMode { Points = 0, PointsPlusNormals, + Splatting, Wireframe, Flat, FlatPlusEdges, diff --git a/Polyhedron/demo/Polyhedron/CGAL_demo/Viewer_interface.h b/Polyhedron/demo/Polyhedron/CGAL_demo/Viewer_interface.h index fe99eda60b2..cb133b1054a 100644 --- a/Polyhedron/demo/Polyhedron/CGAL_demo/Viewer_interface.h +++ b/Polyhedron/demo/Polyhedron/CGAL_demo/Viewer_interface.h @@ -32,8 +32,10 @@ public: virtual bool inFastDrawing() const = 0; typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDARBPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); typedef void (APIENTRYP PFNGLVERTEXATTRIBDIVISORARBPROC) (GLuint index, GLuint divisor); + typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLuint target, GLuint attachment, GLuint textarget, GLuint texture, GLint level); PFNGLDRAWARRAYSINSTANCEDARBPROC glDrawArraysInstanced; PFNGLVERTEXATTRIBDIVISORARBPROC glVertexAttribDivisor; + PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2D; bool extension_is_found; GLfloat pickMatrix_[16]; diff --git a/Polyhedron/demo/Polyhedron/CMakeLists.txt b/Polyhedron/demo/Polyhedron/CMakeLists.txt index 8ae9a7a63b2..2a1efc4208d 100644 --- a/Polyhedron/demo/Polyhedron/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/CMakeLists.txt @@ -62,6 +62,20 @@ if (EIGEN3_FOUND) include( ${EIGEN3_USE_FILE} ) endif(EIGEN3_FOUND) +# Activate concurrency? +option(POLYHEDRON_DEMO_ACTIVATE_CONCURRENCY + "Enable concurrency" + ON) + +if( POLYHEDRON_DEMO_ACTIVATE_CONCURRENCY ) + find_package( TBB ) + if( TBB_FOUND ) + include( ${TBB_USE_FILE} ) + list( APPEND CGAL_3RD_PARTY_LIBRARIES ${TBB_LIBRARIES} ) + else() + message( STATUS "NOTICE: Intel TBB was not found. Bilateral smoothing and WLOP plugins are faster if TBB is linked." ) + endif() +endif() if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND) @@ -101,6 +115,11 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND) qt5_add_resources ( RESOURCE_FILES Polyhedron_3.qrc ) + qt5_add_resources(gl_splat_rc GlSplat/glsplat.qrc) + add_library(gl_splat SHARED + GlSplat/GlSplat.cpp GlSplat/Shader.cpp ${gl_splat_rc}) + qt5_use_modules(gl_splat OpenGL Gui Xml) + target_link_libraries(gl_splat ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTOPENGL_LIBRARY} ${GLEW_LIBRARIES}) qt5_generate_moc( "CGAL_demo/Viewer_interface.h" "${CMAKE_CURRENT_BINARY_DIR}/Viewer_interface_moc.cpp" ) @@ -187,6 +206,8 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND) target_link_libraries(scene_nef_polyhedron_item scene_polyhedron_item) add_item(scene_points_with_normal_item Scene_points_with_normal_item.cpp)# Scene_points_with_normal_item.moc) + target_link_libraries( scene_points_with_normal_item gl_splat ${GLEW_LIBRARIES} ) + target_link_libraries( demo_framework gl_splat ${GLEW_LIBRARIES} ) foreach( lib demo_framework @@ -228,6 +249,7 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND) target_link_libraries( Polyhedron_3 ${QT_LIBRARIES} ) target_link_libraries( Polyhedron_3 demo_framework ) target_link_libraries( Polyhedron_3 point_dialog ) + target_link_libraries( Polyhedron_3 gl_splat ${GLEW_LIBRARIES}) # Link with CGAL target_link_libraries( Polyhedron_3 ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES} ) @@ -235,6 +257,7 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND) # Link with libQGLViewer, OpenGL target_link_libraries( Polyhedron_3 ${QGLVIEWER_LIBRARIES} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ) + add_to_cached_list( CGAL_EXECUTABLE_TARGETS Polyhedron_3 ) @@ -439,6 +462,20 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND) polyhedron_demo_plugin(point_set_shape_detection_plugin Polyhedron_demo_point_set_shape_detection_plugin ${point_set_shape_detectionUI_FILES}) target_link_libraries(point_set_shape_detection_plugin scene_polyhedron_item scene_points_with_normal_item) + qt5_wrap_ui(point_set_wlopFILES Polyhedron_demo_point_set_wlop_plugin.ui) + polyhedron_demo_plugin(point_set_wlop_plugin Polyhedron_demo_point_set_wlop_plugin ${point_set_wlopFILES}) + target_link_libraries(point_set_wlop_plugin scene_points_with_normal_item) + + qt5_wrap_ui(point_set_bilateral_smoothingUI_FILES Polyhedron_demo_point_set_bilateral_smoothing_plugin.ui) + polyhedron_demo_plugin(point_set_bilateral_smoothing_plugin Polyhedron_demo_point_set_bilateral_smoothing_plugin ${point_set_bilateral_smoothingUI_FILES}) + target_link_libraries(point_set_bilateral_smoothing_plugin scene_points_with_normal_item) + + qt5_wrap_ui(point_set_upsamplingUI_FILES Polyhedron_demo_point_set_upsampling_plugin.ui) + polyhedron_demo_plugin(point_set_upsampling_plugin Polyhedron_demo_point_set_upsampling_plugin ${point_set_upsamplingUI_FILES}) + target_link_libraries(point_set_upsampling_plugin scene_points_with_normal_item) + + qt5_wrap_ui( ps_outliers_removal_UI_FILES Polyhedron_demo_point_set_outliers_removal_plugin.ui) + polyhedron_demo_plugin(point_set_outliers_removal_plugin Polyhedron_demo_point_set_outliers_removal_plugin ${ps_outliers_removal_UI_FILES}) target_link_libraries(point_set_outliers_removal_plugin scene_points_with_normal_item) @@ -486,6 +523,12 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND) NAMESPACE Polyhedron_ APPEND FILE polyhedron_demo_targets.cmake) + export( + TARGETS + gl_splat + NAMESPACE Polyhedron_ + APPEND FILE polyhedron_demo_targets.cmake) + configure_file(CGAL_polyhedron_demoConfig.cmake.in CGAL_polyhedron_demoConfig.cmake) else (CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND) diff --git a/Polyhedron/demo/Polyhedron/GlSplat/CMakeLists.txt b/Polyhedron/demo/Polyhedron/GlSplat/CMakeLists.txt new file mode 100644 index 00000000000..c6e51f95e9d --- /dev/null +++ b/Polyhedron/demo/Polyhedron/GlSplat/CMakeLists.txt @@ -0,0 +1,35 @@ + +project(GlSplat) + +cmake_minimum_required(VERSION 2.6.0) +if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}" VERSION_GREATER 2.8.3) + cmake_policy(VERSION 2.8.4) +else() + cmake_policy(VERSION 2.6) +endif() +set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) + +find_package(Qt4 REQUIRED) +find_package(GLEW REQUIRED) + +set(QT_USE_QTOPENGL TRUE) +set(QT_USE_QTXML TRUE) +include(${QT_USE_FILE}) +include_directories( ${QT_QTOPENGL_INCLUDE_DIR} ${QT_QTXML_INCLUDE_DIR} ${GLEW_INCLUDE_DIR}) + +set(srcs Shader.cpp GlSplat.cpp) + +qt4_automoc( ${srcs}) +qt4_add_resources(srcs glsplat.qrc) + +add_library(GlSplat SHARED ${srcs}) +target_link_libraries(GlSplat ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTOPENGL_LIBRARY} ${GLEW_LIBRARIES}) + +find_package(QGLViewer) +if(QGLVIEWER_FOUND) + include_directories( ${QGLViewer_INCLUDES}) + add_executable(demo demo.cpp) + target_link_libraries(demo ${QT_QTXML_LIBRARY} ${QGLViewer_LIBRARIES} GlSplat) +else() + message("QGLViewer not found, demo won't be built") +endif() diff --git a/Polyhedron/demo/Polyhedron/GlSplat/GlSplat.cpp b/Polyhedron/demo/Polyhedron/GlSplat/GlSplat.cpp new file mode 100644 index 00000000000..1f6d3ea6b27 --- /dev/null +++ b/Polyhedron/demo/Polyhedron/GlSplat/GlSplat.cpp @@ -0,0 +1,535 @@ +// This file is part of GlSplat, a simple splatting C++ library +// +// Copyright (C) 2008-2009 Gael Guennebaud +// +// GlSplat is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// GlSplat is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GlSplat. If not, see . + +#include + +#include +#include +#include + +#include "GlSplat.h" +#include "Shader.h" + +#include +#include +#include + + +namespace GlSplat { + +SplatRenderer::SplatRenderer() +{ + mNormalTextureID = 0; + mDepthTextureID = 0; + mIsSupported = false; + viewer_is_set = false; + mRenderBuffer = 0; + mWorkaroundATI = false; + mBuggedAtiBlending = false; + mDummyTexId = 0; + mIsInitialized = false; + + mFlags = DEFERRED_SHADING_BIT | DEPTH_CORRECTION_BIT | FLOAT_BUFFER_BIT | OUTPUT_DEPTH_BIT; + mCachedFlags = ~mFlags; + // union of bits which controls the render buffer + mRenderBufferMask = DEFERRED_SHADING_BIT | FLOAT_BUFFER_BIT; +} + +QString SplatRenderer::loadSource(const QString& func,const QString& filename) +{ + QString res; + QFile f(":/SplatRenderer/shaders/" + filename); + if (!f.open(QFile::ReadOnly)) + { + std::cerr << "failed to load shader file " << filename.toLatin1().data() << "\n"; + return res; + } + else qDebug("Succesfully loaded shader func '%s' in file '%s'",qPrintable(func),qPrintable(filename)); + QTextStream stream(&f); + res = stream.readAll(); + f.close(); + res = QString("#define GLSPLAT__%1__ 1\n").arg(func) + + QString("#define %1 main\n").arg(func) + + res; + return res; +} + +void SplatRenderer::configureShaders() +{ + // const char* passNames[3] = {"Visibility","Attribute","Finalization"}; + QString defines = ""; + if (mFlags & DEFERRED_SHADING_BIT) + defines += "#define ES_DEFERRED_SHADING\n"; + if (mFlags & DEPTH_CORRECTION_BIT) + defines += "#define ES_DEPTH_CORRECTION\n"; + if (mFlags & OUTPUT_DEPTH_BIT) + defines += "#define ES_OUTPUT_DEPTH 1\n"; + if (mFlags & BACKFACE_SHADING_BIT) + defines += "#define ES_BACKFACE_SHADING\n"; + if (mWorkaroundATI) + defines += "#define ES_ATI_WORKAROUND\n"; + + QString shading = +"vec4 meshlabLighting(vec4 color, vec3 eyePos, vec3 normal)" +"{" +" normal = normalize(normal);" +" vec3 lightVec = normalize(gl_LightSource[0].position.xyz);" +" vec3 halfVec = normalize( lightVec - normalize(eyePos) );" +" float aux_dot = dot(normal,lightVec);" +" float diffuseCoeff = clamp(aux_dot, 0.0, 1.0);" +" float specularCoeff = aux_dot>0.0 ? clamp(pow(clamp(dot(halfVec, normal),0.0,1.0),gl_FrontMaterial.shininess), 0.0, 1.0) : 0.0;" +" return vec4(color.rgb * ( gl_FrontLightProduct[0].ambient.rgb + diffuseCoeff * gl_FrontLightProduct[0].diffuse.rgb) + specularCoeff * gl_FrontLightProduct[0].specular.rgb, 1.0);" +"}\n"; + + for (int k=0;k<3;++k) + { + QString vsrc = shading + defines + mShaderSrcs[k*2+0]; + QString fsrc = shading + defines + mShaderSrcs[k*2+1]; + if(!mShaders[k].loadSources(mShaderSrcs[k*2+0]!="" ? vsrc.toLatin1().data() : 0, + mShaderSrcs[k*2+1]!="" ? fsrc.toLatin1().data() : 0/*, + Shader::Warnings*/)) + mIsSupported = false; + } +} + +void SplatRenderer::init(QGLWidget *qglw) +{ + mIsSupported = true; + if(qglw) + qglw->makeCurrent(); + + //glewInit(); + const char* rs = (const char*)glGetString(GL_RENDERER); + QString rendererString(""); + if(rs) + rendererString = QString(rs); + mWorkaroundATI = rendererString.startsWith("ATI") || rendererString.startsWith("AMD"); + // FIXME: maybe some recent HW correctly supports floating point blending... + mBuggedAtiBlending = rendererString.startsWith("ATI") || rendererString.startsWith("AMD"); + + if (mWorkaroundATI && mDummyTexId==0) + { + viewer->glActiveTexture(GL_TEXTURE0); + viewer->glGenTextures(1,&mDummyTexId); + viewer->glBindTexture(GL_TEXTURE_2D, mDummyTexId); + viewer->glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 4, 4, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0); + } + + // let's check the GPU capabilities + mSupportedMask = DEPTH_CORRECTION_BIT | BACKFACE_SHADING_BIT; + if (!QGLFramebufferObject::hasOpenGLFramebufferObjects ()) + { + std::cout << "SplatRenderer: error OpenGL frame buffer objects are not supported. (please, try to update your drivers)\n"; + mIsSupported = false; + return; + } + //if (GLEW_ARB_texture_float) + mSupportedMask |= FLOAT_BUFFER_BIT; + //else + // std::cout << "SplatRenderer: warning floating point textures are not supported.\n"; + + // if (GLEW_ARB_draw_buffers && (!mBuggedAtiBlending)) + mSupportedMask |= DEFERRED_SHADING_BIT; + //else + // std::cout << "SplatRenderer: warning deferred shading is not supported.\n"; + + //if (GLEW_ARB_shadow) + mSupportedMask |= OUTPUT_DEPTH_BIT; + //else + // std::cerr << "SplatRenderer: warning copy of the depth buffer is not supported.\n"; + + mFlags = mFlags & mSupportedMask; + + // load shader source + mShaderSrcs[0] = loadSource("VisibilityVP","Raycasting.glsl"); + mShaderSrcs[1] = loadSource("VisibilityFP","Raycasting.glsl"); + mShaderSrcs[2] = loadSource("AttributeVP","Raycasting.glsl"); + mShaderSrcs[3] = loadSource("AttributeFP","Raycasting.glsl"); + mShaderSrcs[4] = ""; + mShaderSrcs[5] = loadSource("Finalization","Finalization.glsl"); + + mCurrentPass = 2; + mBindedPass = -1; + mIsInitialized = true; + +} + +void SplatRenderer::updateRenderBuffer() +{ + if ( (!mRenderBuffer) + || (mRenderBuffer->width()!=mCachedVP[2]) + || (mRenderBuffer->height()!=mCachedVP[3]) + || ( (mCachedFlags & mRenderBufferMask) != (mFlags & mRenderBufferMask) )) + { + delete mRenderBuffer; + GLenum fmt = (mFlags&FLOAT_BUFFER_BIT) ? GL_RGBA16F_ARB : GL_RGBA; + mRenderBuffer = new QGLFramebufferObject(mCachedVP[2], mCachedVP[3], + (mFlags&OUTPUT_DEPTH_BIT) ? QGLFramebufferObject::NoAttachment : QGLFramebufferObject::Depth, + GL_TEXTURE_RECTANGLE_ARB, fmt); + + if (!mRenderBuffer->isValid()) + { + std::cout << "SplatRenderer: invalid FBO\n"; + } + + + if (mFlags&DEFERRED_SHADING_BIT) + { + // in deferred shading mode we need an additional buffer to accumulate the normals + if (mNormalTextureID==0) + viewer->glGenTextures(1,&mNormalTextureID); + //glBindTexture(GL_TEXTURE_RECTANGLE_ARB, mNormalTextureID); + viewer->glBindTexture(GL_TEXTURE_RECTANGLE, mNormalTextureID); + //glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, fmt, mCachedVP[2], mCachedVP[3], 0, GL_RGBA, GL_FLOAT, 0); + viewer->glTexImage2D(GL_TEXTURE_RECTANGLE, 0, fmt, mCachedVP[2], mCachedVP[3], 0, GL_RGBA, GL_FLOAT, 0); + //glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + viewer->glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + //glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + viewer->glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + mRenderBuffer->bind(); + viewer->glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)viewer->context()->getProcAddress("glFramebufferTexture2DEXT"); + viewer->glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_RECTANGLE_ARB, mNormalTextureID, 0); + mRenderBuffer->release(); + + } + + if (mFlags&OUTPUT_DEPTH_BIT) + { + // to output the depth values to the final depth buffer we need to + // attach a depth buffer as a texture + if (mDepthTextureID==0) + viewer->glGenTextures(1,&mDepthTextureID); + //glBindTexture(GL_TEXTURE_RECTANGLE_ARB, mDepthTextureID); + viewer->glBindTexture(GL_TEXTURE_RECTANGLE, mDepthTextureID); + //glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_DEPTH_COMPONENT24_ARB, mCachedVP[2], mCachedVP[3], 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0); + viewer->glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_DEPTH_COMPONENT24, mCachedVP[2], mCachedVP[3], 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0); + //glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + viewer->glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + //glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + viewer->glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + mRenderBuffer->bind(); + viewer->glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_RECTANGLE_ARB, mDepthTextureID, 0); + mRenderBuffer->release(); + + } + } +} + +bool SplatRenderer::beginVisibilityPass() +{ + if (!mIsInitialized) + { + init(); + } + if (!isSupported()) + { + std::cerr << "SplatRenderer error: not supported hardware\n"; + return false; + } + if (mCurrentPass!=2) + { + std::cerr << "SplatRenderer error: programming error when calling beginVisibilityPass\n"; + return false; + } + + viewer->glPushAttrib(GL_ALL_ATTRIB_BITS); + + mCurrentPass = 0; + + // grab projection info + viewer->glGetIntegerv(GL_VIEWPORT, mCachedVP); + viewer->glGetFloatv(GL_MODELVIEW_MATRIX, mCachedMV); + viewer->glGetFloatv(GL_PROJECTION_MATRIX, mCachedProj); + + updateRenderBuffer(); + if (mCachedFlags != mFlags) + configureShaders(); + + // configureShaders may detect that shaders are actually not supported. + if (!isSupported()) + { + std::cerr << "SplatRenderer error: not supported hardware\n"; + return false; + } + + mCachedFlags = mFlags; + + mParams.update(mCachedMV, mCachedProj, mCachedVP); + mParams.loadTo(mShaders[mCurrentPass]); + + mRenderBuffer->bind(); + if (mFlags & DEFERRED_SHADING_BIT) + { + //GLenum buf[2] = {GL_COLOR_ATTACHMENT0_EXT,GL_COLOR_ATTACHMENT1_EXT}; + GLenum buf[2] = {GL_COLOR_ATTACHMENT0,GL_COLOR_ATTACHMENT1}; + //glDrawBuffersARB(2, buf); + viewer->glDrawBuffers(2, buf); + } + viewer->glViewport(mCachedVP[0],mCachedVP[1],mCachedVP[2],mCachedVP[3]); + viewer->glClearColor(0,0,0,0); + viewer->glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + enablePass(mCurrentPass); + ; + return true; +} +bool SplatRenderer::beginAttributePass() +{ + if (!isSupported()) + { + std::cerr << "SplatRenderer error: not supported hardware\n"; + return false; + } + if (mCurrentPass!=0) + { + std::cerr << "SplatRenderer error: programming error when calling beginAttributePass (must be called after the visiblity pass)\n"; + return false; + } + + mCurrentPass = 1; + mParams.loadTo(mShaders[mCurrentPass]); + enablePass(mCurrentPass); + ; + return true; +} +bool SplatRenderer::finalize() +{ + if (!isSupported()) + { + std::cerr << "SplatRenderer error: not supported hardware\n"; + return false; + } + + // this is the last pass: normalization by the sum of weights + deferred shading + mShaders[mCurrentPass].release(); + mRenderBuffer->release(); + + if ( (mCurrentPass!=0) && (mCurrentPass!=1)) + { + std::cerr << "SplatRenderer error: programming error when calling finalize (must be called after the visiblity or attribute pass)\n"; + return false; + } + + mCurrentPass = 2; + + if (mFlags&DEFERRED_SHADING_BIT) + viewer->glDrawBuffer(GL_BACK); + + enablePass(mCurrentPass); + + // switch to normalized 2D rendering mode + viewer->glMatrixMode(GL_PROJECTION); + viewer->glPushMatrix(); + viewer->glLoadIdentity(); + viewer->glMatrixMode(GL_MODELVIEW); + viewer->glPushMatrix(); + viewer->glLoadIdentity(); + + + mShaders[2].setUniform("viewport",float(mCachedVP[0]),float(mCachedVP[1]),float(mCachedVP[2]),float(mCachedVP[3])); + mShaders[2].setUniform("ColorWeight",0); // this is a texture unit + viewer->glActiveTexture(GL_TEXTURE0); + //glBindTexture(GL_TEXTURE_RECTANGLE_ARB,mRenderBuffer->texture()); + viewer->glBindTexture(GL_TEXTURE_RECTANGLE,mRenderBuffer->texture()); + + if (mFlags&DEFERRED_SHADING_BIT) + { + mShaders[2].setUniform("unproj", mCachedProj[10], mCachedProj[14]); + mShaders[2].setUniform("NormalWeight",1); // this is a texture unit + viewer->glActiveTexture(GL_TEXTURE1); + //glBindTexture(GL_TEXTURE_RECTANGLE_ARB,mNormalTextureID); + viewer->glBindTexture(GL_TEXTURE_RECTANGLE,mNormalTextureID); + + } + + if (mFlags&OUTPUT_DEPTH_BIT) + { + mShaders[2].setUniform("Depth",2); // this is a texture unit + viewer->glActiveTexture(GL_TEXTURE2); + //glBindTexture(GL_TEXTURE_RECTANGLE_ARB,mDepthTextureID); + viewer->glBindTexture(GL_TEXTURE_RECTANGLE,mDepthTextureID); + + } + else + { + viewer->glDisable(GL_DEPTH_TEST); + viewer->glDepthMask(GL_FALSE); + } + + // draw a quad covering the whole screen + float viewVec[] = {1.f/mCachedProj[0], 1.f/mCachedProj[5], -1}; + + viewer->glBegin(GL_QUADS); + viewer->glColor3f(1, 0, 0); + viewer->glTexCoord3f(viewVec[0],viewVec[1],viewVec[2]); + viewer->glMultiTexCoord2f(GL_TEXTURE1,1.,1.); + viewer->glVertex3f(1,1,0); + + viewer->glColor3f(1, 1, 0); + viewer->glTexCoord3f(-viewVec[0],viewVec[1],viewVec[2]); + viewer->glMultiTexCoord2f(GL_TEXTURE1,0.,1.); + viewer->glVertex3f(-1,1,0); + + viewer->glColor3f(0, 1, 1); + viewer->glTexCoord3f(-viewVec[0],-viewVec[1],viewVec[2]); + viewer->glMultiTexCoord2f(GL_TEXTURE1,0.,0.); + viewer->glVertex3f(-1,-1,0); + + viewer->glColor3f(1, 0, 1); + viewer->glTexCoord3f(viewVec[0],-viewVec[1],viewVec[2]); + viewer->glMultiTexCoord2f(GL_TEXTURE1,1.,0.); + viewer->glVertex3f(1,-1,0); + viewer->glEnd(); + if (!(mFlags&OUTPUT_DEPTH_BIT)) + { + viewer->glEnable(GL_DEPTH_TEST); + viewer->glDepthMask(GL_TRUE); + } + + mShaders[mCurrentPass].release(); + + // restore matrices + viewer->glMatrixMode(GL_PROJECTION); + viewer->glPopMatrix(); + viewer->glMatrixMode(GL_MODELVIEW); + viewer->glPopMatrix(); + + viewer->glPopAttrib(); + return true; +} + +void SplatRenderer::enablePass(int n) +{ + if (!isSupported()) + { + return; + } + if (mBindedPass!=n) + { + if (mBindedPass>=0) + mShaders[mBindedPass].release(); + mShaders[n].activate(); + mBindedPass = n; + + // set GL states + if (n==0) + { + viewer->glDisable(GL_LIGHTING); +// glDisable(GL_POINT_SMOOTH); + viewer->glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); + + viewer->glAlphaFunc(GL_LESS,1); + viewer->glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE); + viewer->glDepthMask(GL_TRUE); + viewer->glDisable(GL_BLEND); + viewer->glEnable(GL_ALPHA_TEST); + viewer->glEnable(GL_DEPTH_TEST); + +// glActiveTexture(GL_TEXTURE0); +// glTexEnvf(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE); +// glEnable(GL_POINT_SPRITE_ARB); + } + if (n==1) + { + viewer->glDisable(GL_LIGHTING); + viewer->glEnable(GL_POINT_SMOOTH); + viewer->glActiveTexture(GL_TEXTURE0); + viewer->glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); + + viewer->glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); + viewer->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_ONE,GL_ONE); +// //glBlendFuncSeparate(GL_ONE, GL_ZERO, GL_ONE,GL_ZERO); +// glBlendFunc(GL_ONE,GL_ZERO); + viewer->glDepthMask(GL_FALSE); + viewer->glEnable(GL_BLEND); + viewer->glEnable(GL_DEPTH_TEST); + viewer->glDisable(GL_ALPHA_TEST); + +// glActiveTexture(GL_TEXTURE0); + + } + if ( (n==0) || (n==1) ) + { + // enable point sprite rendering mode + viewer->glActiveTexture(GL_TEXTURE0); + if (mWorkaroundATI) + { + viewer->glBindTexture(GL_TEXTURE_2D, mDummyTexId); + viewer->glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 2, 2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0); + viewer->glPointParameterf(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT); + // hm... ^^^^ + } + viewer->glTexEnvf(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE); + viewer->glEnable(GL_POINT_SPRITE_ARB); + } + if (n==2) + { + viewer->glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); + viewer->glDepthMask(GL_TRUE); + viewer->glDisable(GL_LIGHTING); + viewer->glDisable(GL_BLEND); + } + } +} + +void SplatRenderer::UniformParameters::update(float* mv, float* proj, GLint* vp) +{ + // extract the uniform scale + float scale = sqrtf(mv[0]*mv[0]+mv[1]*mv[1]+mv[2]*mv[2]); + + radiusScale = scale; + preComputeRadius = - (std::max)(proj[0]*vp[2], proj[5]*vp[3]); + depthOffset = 2.0; + oneOverEwaRadius = 0.70710678118654f; + halfVp[0] = 0.5*vp[2]; + halfVp[1] = 0.5*vp[3]; + rayCastParameter1[0] = 2./(proj[0]*vp[2]); + rayCastParameter1[1] = 2./(proj[5]*vp[3]); + rayCastParameter1[2] = 0.0; + rayCastParameter2[0] = -1./proj[0]; + rayCastParameter2[1] = -1./proj[5]; + rayCastParameter2[2] = -1.0; + depthParameterCast[0] = 0.5*proj[14]; + depthParameterCast[1] = 0.5-0.5*proj[10]; +} + +void SplatRenderer::UniformParameters::loadTo(Shader& prg) +{ + prg.activate(); + prg.setUniform("expeRadiusScale", radiusScale); + prg.setUniform("expePreComputeRadius", preComputeRadius); + prg.setUniform("expeDepthOffset", depthOffset); + prg.setUniform("oneOverEwaRadius", oneOverEwaRadius); + prg.setUniform2("halfVp", halfVp); + prg.setUniform3("rayCastParameter1", rayCastParameter1); + prg.setUniform3("rayCastParameter2", rayCastParameter2); + prg.setUniform2("depthParameterCast", depthParameterCast); +} + +void SplatRenderer::setRadiusScale(float v) +{ + mParams.radiusScale = v; +} + +void SplatRenderer::setViewer(Viewer_interface *v) +{ + viewer = v; + for(int i=0; i<3; i++) + mShaders[i].setViewer(v); + + viewer_is_set = true; +} +} // namepsace GlSplat + diff --git a/Polyhedron/demo/Polyhedron/GlSplat/GlSplat.h b/Polyhedron/demo/Polyhedron/GlSplat/GlSplat.h new file mode 100644 index 00000000000..850b01c3edb --- /dev/null +++ b/Polyhedron/demo/Polyhedron/GlSplat/GlSplat.h @@ -0,0 +1,153 @@ +// This file is part of GlSplat, a simple splatting C++ library +// +// Copyright (C) 2008-2009 Gael Guennebaud +// +// GlSplat is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// GlSplat is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GlSplat. If not, see . + +#ifndef _GLSPLAT_SPLATRENDERER_H_ +#define _GLSPLAT_SPLATRENDERER_H_ + +#include "GlSplat_config.h" +#include "Shader.h" +#include +#include +#include +#include + +class QGLFramebufferObject; +class QGLWidget; + +namespace GlSplat { + +/** \class SplatRenderer + * \brief Helper class to render a set of points using a splatting alogirthm + * + * This class aims to render a set of oriented point with radius (called splats) using an + * OpenGL based splating algorithm. This class is only responsible for the managing of the + * OpenGL stats and shaders related to the splatting. The drawing of the geometry, i.e., + * sending the point data to the GPU has to be done by the user. + * + * Here is an example: + * \code + * SplatRenderer renderer; + * renderer.init(); + * + * renderer.beginVisibilityPass(); + * drawpoints(); + * renderer.beginAttributePass(); + * drawpoints(); + * renderer.finalize(); + * \endcode + * + * Have a look at the demo to see a complete example based on QGLviewer. + */ +class GLSPLAT_EXPORT SplatRenderer +{ + bool mIsSupported; + enum { + DEFERRED_SHADING_BIT = 0x000001, + DEPTH_CORRECTION_BIT = 0x000002, + OUTPUT_DEPTH_BIT = 0x000004, + BACKFACE_SHADING_BIT = 0x000008, + FLOAT_BUFFER_BIT = 0x000010 + }; + int mFlags; + int mCachedFlags; + int mRenderBufferMask; + int mSupportedMask; + + int mCurrentPass; + int mBindedPass; + GLuint mDummyTexId; // on ATI graphics card we need to bind a texture to get point sprite working ! + bool mWorkaroundATI; + bool mBuggedAtiBlending; + bool mIsInitialized; + GLuint mNormalTextureID; + GLuint mDepthTextureID; + Shader mShaders[3]; + QString mShaderSrcs[6]; + QGLFramebufferObject* mRenderBuffer; + float mCachedMV[16]; // modelview matrix + float mCachedProj[16]; // projection matrix + GLint mCachedVP[4]; // viewport + + struct UniformParameters + { + float radiusScale; + float preComputeRadius; + float depthOffset; + float oneOverEwaRadius; + float halfVp[2]; + float rayCastParameter1[3]; + float rayCastParameter2[3]; + float depthParameterCast[2]; + + void loadTo(Shader& prg); + void update(float* mv, float* proj, GLint* vp); + }; + + UniformParameters mParams; + + QString loadSource(const QString& func,const QString& file); + void configureShaders(); + void updateRenderBuffer(); + void enablePass(int n); + +public: + bool viewer_is_set; + + SplatRenderer(); + ~SplatRenderer() + { + } + + /** Must be called once an OpenGL context has been activated. + * The main OpenGL context must be enabled, or, if you are using a QGLwiget, + * you can pass it to this function without caring about the OpenGL context. + */ + void init(QGLWidget *qglw = 0); + + /** \returns true is the hardware is supported + * Must be called after init. + */ + bool isSupported() { return mIsSupported; } + + /** Starts the first rendering pass + * \returns false if an error occured + */ + bool beginVisibilityPass(); + /** Starts the (optional) second rendering pass + * \returns false if an error occured + */ + bool beginAttributePass(); + /** Draw the rendered splats inside the main render target. + * \returns false if an error occured + */ + bool finalize(); + + /** Sets a global scale factor for the splat radii + * Default value is 1 + */ + void setRadiusScale(float v); + + void setViewer(Viewer_interface *v); + +private : + Viewer_interface *viewer; +}; + + +} // namepsace GlSplat + +#endif // _GLSPLAT_SPLATRENDERER_H_ + diff --git a/Polyhedron/demo/Polyhedron/GlSplat/GlSplat_config.h b/Polyhedron/demo/Polyhedron/GlSplat/GlSplat_config.h new file mode 100644 index 00000000000..b64e4065a68 --- /dev/null +++ b/Polyhedron/demo/Polyhedron/GlSplat/GlSplat_config.h @@ -0,0 +1,12 @@ +#ifndef GLSPLAT_CONFIG_H +#define GLSPLAT_CONFIG_H + +#include + +#ifdef gl_splat_EXPORTS + #define GLSPLAT_EXPORT CGAL_DLL_EXPORT +#else + #define GLSPLAT_EXPORT CGAL_DLL_IMPORT +#endif + +#endif // GLSPLAT_CONFIG_H diff --git a/Polyhedron/demo/Polyhedron/GlSplat/Shader.cpp b/Polyhedron/demo/Polyhedron/GlSplat/Shader.cpp new file mode 100644 index 00000000000..08e7303e4bf --- /dev/null +++ b/Polyhedron/demo/Polyhedron/GlSplat/Shader.cpp @@ -0,0 +1,140 @@ +// This file is part of GlSplat, a simple splatting C++ library +// +// Copyright (C) 2008-2009 Gael Guennebaud +// +// GlSplat is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// GlSplat is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GlSplat. If not, see . + +#include "Shader.h" +#include + +#include +#include +#include +#include + +namespace GlSplat { + +void Shader::define(const char* name, const char* value) +{ + mDefines[std::string(name)] = value; +} +//-------------------------------------------------------------------------------- +bool Shader::loadSources(const char* vsrc, const char* fsrc) +{ + bool allIsOk = true; + mProgramID = viewer->glCreateProgram(); + + std::string defineStr = ""; + for(DefineMap::iterator it = mDefines.begin() ; it!=mDefines.end() ; ++it) + { + defineStr += "#define " + it->first + " " + it->second + "\n"; + } + + if(vsrc) + { + GLuint shaderID = viewer->glCreateShader(GL_VERTEX_SHADER); + + std::string source = defineStr + std::string(vsrc); + const GLchar * arbSource = source.c_str(); + + viewer->glShaderSource(shaderID, 1, (const GLchar **)&arbSource, 0); + viewer->glCompileShader(shaderID); + + int compiled; + viewer->glGetShaderiv(shaderID,GL_COMPILE_STATUS,&compiled); + allIsOk = allIsOk && compiled; + //printInfoLog(shaderID); + + viewer->glAttachShader(mProgramID, shaderID); + } + + if(fsrc) + { + GLuint shaderID = viewer->glCreateShader(GL_FRAGMENT_SHADER); + + std::string source = defineStr + std::string(fsrc); + const GLchar * arbSource = source.c_str(); + + viewer->glShaderSource(shaderID, 1, (const GLchar **)&arbSource, 0); + viewer->glCompileShader(shaderID); + + int compiled; + viewer->glGetShaderiv(shaderID,GL_COMPILE_STATUS,&compiled); + allIsOk = allIsOk && compiled; + //printInfoLog(shaderID); + + viewer->glAttachShader(mProgramID, shaderID); + } + + viewer->glLinkProgram(mProgramID); + + int isLinked; + viewer->glGetProgramiv(mProgramID, GL_LINK_STATUS, &isLinked); + allIsOk = allIsOk && isLinked; + mIsValid = isLinked == GL_TRUE; + printInfoLog(mProgramID); + + return allIsOk; +} +//-------------------------------------------------------------------------------- +void Shader::activate() +{ + assert(mIsValid); + viewer->glUseProgram(mProgramID); +} +void Shader::release(void) +{ + viewer->glUseProgram(0); +} +//-------------------------------------------------------------------------------- +int Shader::getUniformLocation(const char* name) +{ + assert(mIsValid); + int loc = viewer->glGetUniformLocation(mProgramID, name); + return loc; +} +//-------------------------------------------------------------------------------- +void Shader::setSamplerUnit(const char* sampler, int unit) +{ + activate(); + viewer->glUniform1i(getUniformLocation(sampler), unit); + release(); +} +//-------------------------------------------------------------------------------- +int Shader::getAttribLocation(const char* name) +{ + assert(mIsValid); + int loc = viewer->glGetAttribLocation(mProgramID, name); + return loc; +} +//-------------------------------------------------------------------------------- +void Shader::printInfoLog(GLuint objectID) +{ + int infologLength, charsWritten; + GLchar *infoLog; + viewer->glGetProgramiv(objectID,GL_INFO_LOG_LENGTH, &infologLength); + if(infologLength > 0) + { + infoLog = new GLchar[infologLength]; + viewer->glGetProgramInfoLog(objectID, infologLength, &charsWritten, infoLog); + if (charsWritten>0) + std::cerr << "Shader info : \n" << infoLog << std::endl; + delete[] infoLog; + } +} + +void Shader::setViewer(Viewer_interface *v) +{ + viewer = v; +} +} // namepsace GlSplat diff --git a/Polyhedron/demo/Polyhedron/GlSplat/Shader.h b/Polyhedron/demo/Polyhedron/GlSplat/Shader.h new file mode 100644 index 00000000000..620953c3ffb --- /dev/null +++ b/Polyhedron/demo/Polyhedron/GlSplat/Shader.h @@ -0,0 +1,139 @@ +// This file is part of GlSplat, a simple splatting C++ library +// +// Copyright (C) 2008-2009 Gael Guennebaud +// +// GlSplat is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// GlSplat is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GlSplat. If not, see . + +#ifndef _GLSPLAT_Shader_h_ +#define _GLSPLAT_Shader_h_ +#include +#include +#include +#include "Viewer_interface.h" + +namespace GlSplat { + +/** Permet de manipuler des shaders en GLSL (OpenGL2.0) + Exemple d'utilisation: + \code + // shader creation: + Shader* myShader = new Shader(); + // loading from files (compilation + linking): + myShader->loadFromFiles("myShaderFile.vtx", "myShaderFile.frg"); + + // ... + + // at rending time: + myShader->enable(); + // draw objects + myShader->disable(); + \endcode +*/ + +class Shader +{ +public: + Shader(void) + : mIsValid(false) + { } + ~Shader() + { + } + void setViewer(Viewer_interface *); + /** add a \#define + */ + void define(const char* name, const char* value); + + /** Compiles and links the shader from 2 source files + \param fileV vertex shader ("" if no vertex shader) + \param fileF fragment shader ("" if no fragment shader) + \return true if no error occurs + */ +// bool loadFromFiles(const std::string& fileV, const std::string& fileF); + + bool loadSources(const char* vsrc, const char* fsrc); + + /** Enable the shader + */ + void activate(); + + /** Releases the shader + */ + void release() ; + + /** \return the index of the uniform variable \a name + */ + int getUniformLocation(const char* name); + + /** Forces a sampler to a given unit + Example: + \code + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE2D, myTextureID); + myShader->setSamplerUnit("mySampler", 2); + \endcode + */ + void setSamplerUnit(const char* samplerName, int textureUnit); + + /** \returns the index of the generic attribute \a name + Tp be used with glVertexAttrib*(...) ou glVertexAttribPointer(...) + Example: + \code + int tangentAttribID = myShader->getAttribLocation("tangent"); + Vector3 tangent(...); + glVertexAttrib3fv(tangentAttribID, tangent); + // ou + Vector3* tangents = new Vector3[...]; + glVertexAttribPointer(tangentAttribID, 3, GL_FLOAT, GL_FALSE, 0, tangents); + glEnableVertexAttribArray(tangentAttribID); + \endcode + */ + int getAttribLocation(const char* name); + + inline void setUniform(const char* name, float a) + { viewer->glUniform1f(viewer->glGetUniformLocation(mProgramID, name), a); } + + inline void setUniform(const char* name, int a) + { viewer->glUniform1i(viewer->glGetUniformLocation(mProgramID, name), a); } + + inline void setUniform2(const char* name, float* a) + { viewer->glUniform2fv(viewer->glGetUniformLocation(mProgramID, name), 1, a); } + + inline void setUniform3(const char* name, float* a) + { viewer->glUniform3fv(viewer->glGetUniformLocation(mProgramID, name), 1, a); } + + inline void setUniform4(const char* name, float* a) + { viewer->glUniform4fv(viewer->glGetUniformLocation(mProgramID, name), 1, a); } + + inline void setUniform(const char* name, float a, float b) + { viewer->glUniform2f(viewer->glGetUniformLocation(mProgramID, name), a, b); } + + inline void setUniform(const char* name, float a, float b, float c) + { viewer->glUniform3f(viewer->glGetUniformLocation(mProgramID, name), a, b, c); } + + inline void setUniform(const char* name, float a, float b, float c, float d) + { viewer->glUniform4f(viewer->glGetUniformLocation(mProgramID, name), a, b, c, d); } + + Viewer_interface *viewer; +protected: + + bool mIsValid; + typedef std::map DefineMap; + DefineMap mDefines; + void printInfoLog(GLuint objectID); + GLuint mProgramID; +}; + +} // namepsace GlSplat + +#endif diff --git a/Polyhedron/demo/Polyhedron/GlSplat/cmake/FindGLEW.cmake b/Polyhedron/demo/Polyhedron/GlSplat/cmake/FindGLEW.cmake new file mode 100644 index 00000000000..54da20f12bd --- /dev/null +++ b/Polyhedron/demo/Polyhedron/GlSplat/cmake/FindGLEW.cmake @@ -0,0 +1,105 @@ +# Copyright (c) 2009 Boudewijn Rempt +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. +# +# - try to find glew library and include files +# GLEW_INCLUDE_DIR, where to find GL/glew.h, etc. +# GLEW_LIBRARIES, the libraries to link against +# GLEW_FOUND, If false, do not try to use GLEW. +# Also defined, but not for general use are: +# GLEW_GLEW_LIBRARY = the full path to the glew library. + +IF (WIN32) + + IF(CYGWIN) + + FIND_PATH( GLEW_INCLUDE_DIR GL/glew.h) + + FIND_LIBRARY( GLEW_GLEW_LIBRARY glew32 + ${OPENGL_LIBRARY_DIR} + /usr/lib/w32api + /usr/X11R6/lib + ) + + + ELSE(CYGWIN) + + FIND_PATH( GLEW_INCLUDE_DIR GL/glew.h + $ENV{GLEW_ROOT_PATH}/include + ) + + FIND_LIBRARY( GLEW_GLEW_LIBRARY + NAMES glew glew32 + PATHS + $ENV{GLEW_ROOT_PATH}/lib + ${OPENGL_LIBRARY_DIR} + ) + + ENDIF(CYGWIN) + +ELSE (WIN32) + + IF (APPLE) +# These values for Apple could probably do with improvement. + FIND_PATH( GLEW_INCLUDE_DIR glew.h + /System/Library/Frameworks/GLEW.framework/Versions/A/Headers + ${OPENGL_LIBRARY_DIR} + ) + SET(GLEW_GLEW_LIBRARY "-framework GLEW" CACHE STRING "GLEW library for OSX") + SET(GLEW_cocoa_LIBRARY "-framework Cocoa" CACHE STRING "Cocoa framework for OSX") + ELSE (APPLE) + + FIND_PATH( GLEW_INCLUDE_DIR GL/glew.h + /usr/include/GL + /usr/openwin/share/include + /usr/openwin/include + /usr/X11R6/include + /usr/include/X11 + /opt/graphics/OpenGL/include + /opt/graphics/OpenGL/contrib/libglew + ) + + FIND_LIBRARY( GLEW_GLEW_LIBRARY GLEW + /usr/openwin/lib + /usr/X11R6/lib + ) + + ENDIF (APPLE) + +ENDIF (WIN32) + +SET( GLEW_FOUND "NO" ) +IF(GLEW_INCLUDE_DIR) + IF(GLEW_GLEW_LIBRARY) + # Is -lXi and -lXmu required on all platforms that have it? + # If not, we need some way to figure out what platform we are on. + SET( GLEW_LIBRARIES + ${GLEW_GLEW_LIBRARY} + ${GLEW_cocoa_LIBRARY} + ) + SET( GLEW_FOUND "YES" ) + +#The following deprecated settings are for backwards compatibility with CMake1.4 + SET (GLEW_LIBRARY ${GLEW_LIBRARIES}) + SET (GLEW_INCLUDE_PATH ${GLEW_INCLUDE_DIR}) + + ENDIF(GLEW_GLEW_LIBRARY) +ENDIF(GLEW_INCLUDE_DIR) + +IF(GLEW_FOUND) + IF(NOT GLEW_FIND_QUIETLY) + MESSAGE(STATUS "Found Glew: ${GLEW_LIBRARIES}") + ENDIF(NOT GLEW_FIND_QUIETLY) +ELSE(GLEW_FOUND) + IF(GLEW_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find Glew") + ENDIF(GLEW_FIND_REQUIRED) +ENDIF(GLEW_FOUND) + +MARK_AS_ADVANCED( + GLEW_INCLUDE_DIR + GLEW_GLEW_LIBRARY + GLEW_Xmu_LIBRARY + GLEW_Xi_LIBRARY +) diff --git a/Polyhedron/demo/Polyhedron/GlSplat/cmake/FindQGLViewer.cmake b/Polyhedron/demo/Polyhedron/GlSplat/cmake/FindQGLViewer.cmake new file mode 100644 index 00000000000..5e5bab0c1c8 --- /dev/null +++ b/Polyhedron/demo/Polyhedron/GlSplat/cmake/FindQGLViewer.cmake @@ -0,0 +1,20 @@ + +if (QGLViewer_INCLUDES AND QGLViewer_LIBRARIES) + set(QGLViewer_FIND_QUIETLY TRUE) +endif (QGLViewer_INCLUDES AND QGLViewer_LIBRARIES) + +find_path(QGLViewer_INCLUDES + NAMES + QGLViewer/qglviewer.h + PATHS + $ENV{QGLViewerDIR} + ${INCLUDE_INSTALL_DIR} +) + +find_library(QGLViewer_LIBRARIES QGLViewer PATHS $ENV{QGLVIEWER_DIR} ${LIB_INSTALL_DIR}) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(QGLViewer DEFAULT_MSG + QGLViewer_INCLUDES QGLViewer_LIBRARIES) + +mark_as_advanced(QGLViewer_INCLUDES QGLViewer_LIBRARIES) diff --git a/Polyhedron/demo/Polyhedron/GlSplat/demo.cpp b/Polyhedron/demo/Polyhedron/GlSplat/demo.cpp new file mode 100644 index 00000000000..39514a225dc --- /dev/null +++ b/Polyhedron/demo/Polyhedron/GlSplat/demo.cpp @@ -0,0 +1,131 @@ +// This file is part of GlSplat, a simple splatting C++ library +// +// Copyright (C) 2008-2009 Gael Guennebaud +// +// GlSplat is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// GlSplat is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GlSplat. If not, see . + +#include "GlSplat.h" +#include + +class Viewer : public QGLViewer +{ +protected : + virtual void draw(); + virtual void init(); + virtual QString helpString() const; + + virtual void drawpoints(); + GlSplat::SplatRenderer mRenderer; + std::vector mNormals; + std::vector mPositions; + std::vector mRadii; + std::vector mColors; + int mNbPoints; +}; + +void Viewer::draw() +{ + mRenderer.beginVisibilityPass(); + drawpoints(); + mRenderer.beginAttributePass(); + drawpoints(); + mRenderer.finalize(); +} + +void Viewer::drawpoints() +{ + glBegin(GL_POINTS); + for (int i=0; iS i m p l e V i e w e r"); + text += "Use the mouse to move the camera around the object. "; + text += "You can respectively revolve around, zoom and translate with the three mouse buttons. "; + text += "Left and middle buttons pressed together rotate around the camera view direction axis

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

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

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

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

"; + text += "Press Escape to exit the viewer."; + return text; +} + + +#include + +int main(int argc, char** argv) +{ + // Read command lines arguments. + QApplication application(argc,argv); + + // Instantiate the viewer. + Viewer viewer; + + viewer.setWindowTitle("simpleViewer"); + + // Make the viewer window visible on screen. + viewer.show(); + + // Run main loop. + return application.exec(); +} + diff --git a/Polyhedron/demo/Polyhedron/GlSplat/glsplat.qrc b/Polyhedron/demo/Polyhedron/GlSplat/glsplat.qrc new file mode 100644 index 00000000000..2aa027c792b --- /dev/null +++ b/Polyhedron/demo/Polyhedron/GlSplat/glsplat.qrc @@ -0,0 +1,6 @@ + + + shaders/Raycasting.glsl + shaders/Finalization.glsl + + diff --git a/Polyhedron/demo/Polyhedron/GlSplat/shaders/Finalization.glsl b/Polyhedron/demo/Polyhedron/GlSplat/shaders/Finalization.glsl new file mode 100644 index 00000000000..d587a28056f --- /dev/null +++ b/Polyhedron/demo/Polyhedron/GlSplat/shaders/Finalization.glsl @@ -0,0 +1,106 @@ +// This file is part of GlSplat, a simple splatting C++ library +// +// Copyright (C) 2008-2009 Gael Guennebaud +// +// GlSplat is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// GlSplat is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GlSplat. If not, see . + +#extension GL_ARB_texture_rectangle : enable + +#ifndef ES_DEPTH_INTERPOLATION + #define ES_DEPTH_INTERPOLATION 0 +#endif + +#ifndef ES_OUTPUT_DEPTH + #define ES_OUTPUT_DEPTH 0 +#endif + +// avoid an annoying bug with the nvidia driver 87XX serie. +#define epsilon 0.000001 + +uniform vec4 viewport; + +#ifndef ES_DEFERRED_SHADING + +uniform sampler2DRect ColorWeight; +#if (ES_OUTPUT_DEPTH==1) +uniform sampler2DRect Depth; +#endif + +void Finalization(void) +{ + vec4 color = texture2DRect(ColorWeight, gl_FragCoord.st - viewport.xy + epsilon); + #if (ES_OUTPUT_DEPTH==1) + gl_FragDepth = texture2DRect(Depth, gl_FragCoord.st + epsilon).x; + #endif + if (color.w<0.001) + discard; + gl_FragColor = color/color.w; + gl_FragColor.a = 1.; +} + +#else + +uniform vec2 unproj; + +uniform sampler2DRect ColorWeight; +uniform sampler2DRect NormalWeight; + +#if ( (ES_DEPTH_INTERPOLATION==0) || (ES_OUTPUT_DEPTH==1)) +uniform sampler2DRect Depth; +#endif + +void Finalization(void) +{ + vec4 color = texture2DRect(ColorWeight, gl_FragCoord.st - viewport.xy + epsilon); + + if (color.w<0.001) + discard; + + + if(color.w>0.001) + color.xyz /= color.w; + + vec3 viewVec = normalize(gl_TexCoord[0].xyz); + vec4 normaldepth = texture2DRect(NormalWeight, gl_FragCoord.st + epsilon); + + normaldepth.xyz = normaldepth.xyz/normaldepth.w; + + #if (ES_OUTPUT_DEPTH==1) + gl_FragDepth = texture2DRect(Depth, gl_FragCoord.st + epsilon).x; + #endif + + #if ES_DEPTH_INTERPOLATION==2 + float depth = -normaldepth.z; + #elif ES_DEPTH_INTERPOLATION==1 + float depth = unproj.y/(2.0*normaldepth.z+unproj.x-1.0); + #else + float depth = texture2DRect(Depth, gl_FragCoord.st + epsilon).x; + depth = unproj.y/(2.0*depth+unproj.x-1.0); + #endif + + vec3 normal = normaldepth.xyz; + #if ES_DEPTH_INTERPOLATION!=0 + normal.z = sqrt(1. - dot(vec3(normal.xy,0),vec3(normal.xy,0))); + #endif + normal = normalize(normal); + vec3 eyePos = gl_TexCoord[0].xyz * depth; + + gl_FragColor = meshlabLighting(color, eyePos, normal); + gl_FragColor.a = 1.0; +} + +#endif + + + diff --git a/Polyhedron/demo/Polyhedron/GlSplat/shaders/Raycasting.glsl b/Polyhedron/demo/Polyhedron/GlSplat/shaders/Raycasting.glsl new file mode 100644 index 00000000000..c2b4cc0539f --- /dev/null +++ b/Polyhedron/demo/Polyhedron/GlSplat/shaders/Raycasting.glsl @@ -0,0 +1,335 @@ +// This file is part of GlSplat, a simple splatting C++ library +// +// Copyright (C) 2008-2009 Gael Guennebaud +// +// GlSplat is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// GlSplat is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GlSplat. If not, see . + +#pragma optimize(on) + +#ifndef ES_EWA_HINT + #define ES_EWA_HINT 0 +#endif + +#ifndef ES_DEPTH_INTERPOLATION + #define ES_DEPTH_INTERPOLATION 0 +#endif + +//-------------------------------------------------------------------------------- +// shared variables +//-------------------------------------------------------------------------------- + +// custom vertex attributes +//attribute float radius; + +#ifdef CLIPPED_SPLAT +attribute vec3 secondNormal; +varying vec4 clipLine; +#endif + +// standard uniforms +uniform float expeRadiusScale; +uniform float expePreComputeRadius; +uniform float expeDepthOffset; + +// varying +varying vec4 covmat; +varying vec3 fragNormal; + +varying vec3 fragNoverCdotN; +varying vec3 fragCenter; +varying float scaleSquaredDistance; + +#ifdef ES_ATI_WORKAROUND +varying vec4 fragCenterAndRadius; +#endif + +#ifdef ES_DEPTH_CORRECTION +varying float depthOffset; +#endif + +uniform vec2 halfVp; +uniform float oneOverEwaRadius; + + +#ifdef ES_BACKFACE_SHADING + #undef ES_EARLY_BACK_FACE_CULLING + //#define ES_EWA_HINT 2 +#endif + +//-------------------------------------------------------------------------------- +// Visibility Splatting +// Vertex Shader +//-------------------------------------------------------------------------------- + +#ifdef GLSPLAT__VisibilityVP__ +varying vec2 scaledFragCenter2d; +void VisibilityVP(void) +{ + vec3 normal = normalize(gl_NormalMatrix * gl_Normal); + // Point in eye space + vec4 ePos = gl_ModelViewMatrix * gl_Vertex; + + float dotpn = dot(normal.xyz,ePos.xyz); + + vec4 oPos; + + #ifdef ES_EARLY_BACK_FACE_CULLING + // back_face culling + oPos = vec4(0,0,1,0); + if(dotpn<0.) + { + #endif + + float radius = gl_MultiTexCoord2.x * expeRadiusScale; + + vec4 pointSize; + pointSize.x = radius * expePreComputeRadius / ePos.z; + gl_PointSize = max(1.0, pointSize.x); + + scaleSquaredDistance = 1.0 / (radius * radius); + //fragNormal = normal; + fragCenter = ePos.xyz; + fragNoverCdotN = normal/dot(ePos.xyz,normal); + + #ifndef ES_DEPTH_CORRECTION + ePos.xyz += normalize(ePos.xyz) * expeDepthOffset * radius; + #else + //ePos.xyz += normalize(ePos.xyz) * expeDepthOffset * radius; + depthOffset = expeDepthOffset * radius; + #endif + + oPos = gl_ProjectionMatrix * ePos; + + #if (ES_EWA_HINT>0) + scaledFragCenter2d = 0.5*((oPos.xy/oPos.w)+1.0)*halfVp*oneOverEwaRadius; + #endif + + #ifdef ES_ATI_WORKAROUND + fragCenterAndRadius.xyz = (oPos.xyz/oPos.w) + 1.0; + fragCenterAndRadius.xy = fragCenterAndRadius.xy*halfVp; + fragCenterAndRadius.z = fragCenterAndRadius.z*0.5; + fragCenterAndRadius.w = pointSize.x; + #endif + + #ifndef ES_EARLY_BACK_FACE_CULLING + oPos.w = oPos.w * (dotpn<0.0 ? 1.0 : 0.0); + #else + } + #endif + + gl_Position = oPos; +} + +#endif + +//-------------------------------------------------------------------------------- +// Visibility Splatting +// Fragment Shader +//-------------------------------------------------------------------------------- + +#ifdef GLSPLAT__VisibilityFP__ +varying vec2 scaledFragCenter2d; +uniform vec3 rayCastParameter1; +uniform vec3 rayCastParameter2; +uniform vec2 depthParameterCast; + +void VisibilityFP(void) +{ + #ifdef ES_ATI_WORKAROUND + vec3 fragCoord; + fragCoord.xy = fragCenterAndRadius.xy + (gl_TexCoord[0].st-0.5) * fragCenterAndRadius.w; + fragCoord.z = fragCenterAndRadius.z; + #else + vec3 fragCoord = gl_FragCoord.xyz; + #endif + // compute q in object space + vec3 qOne = rayCastParameter1 * fragCoord + rayCastParameter2; + float oneOverDepth = dot(qOne,-fragNoverCdotN); + float depth = (1.0/oneOverDepth); + vec3 diff = fragCenter + qOne * depth; + float r2 = dot(diff,diff); + + #if (ES_EWA_HINT>0) + vec2 d2 = oneOverEwaRadius*gl_FragCoord.xy - scaledFragCenter2d; + float r2d = dot(d2,d2); + gl_FragColor = vec4(min(r2d,r2*scaleSquaredDistance)); + #else + gl_FragColor = vec4(r2*scaleSquaredDistance); + #endif + + #ifdef ES_DEPTH_CORRECTION + oneOverDepth = 1.0/(-depth+depthOffset); + gl_FragDepth = depthParameterCast.x * oneOverDepth + depthParameterCast.y; + #endif +} + +#endif + +#ifdef GLSPLAT__AttributeVP__ + +varying vec2 scaledFragCenter2d; + +void AttributeVP(void) +{ + // transform normal + vec3 normal = normalize(gl_NormalMatrix * gl_Normal); + // Point in eye space + vec4 ePos = gl_ModelViewMatrix * gl_Vertex; + + float dotpn = dot(normal.xyz,ePos.xyz); + + vec4 oPos; + + #ifdef ES_EARLY_BACK_FACE_CULLING + // back_face culling + oPos = vec4(0,0,1,0); + if(dotpn<0.) + { + #endif + + #ifdef ES_BACKFACE_SHADING + if(dotpn>0.) + { + dotpn = -dotpn; + normal = -normal; + } + #endif + + float radius = gl_MultiTexCoord2.x * expeRadiusScale * 1.1; + + vec4 pointSize; + pointSize.x = radius * expePreComputeRadius / ePos.z; + + #if (ES_EWA_HINT>0) + gl_PointSize = max(2.0, pointSize.x); + #else + gl_PointSize = max(1.0, pointSize.x); + #endif + + scaleSquaredDistance = 1. / (radius * radius); + fragNormal = normal; + fragCenter = ePos.xyz; + fragNoverCdotN = normal/dot(ePos.xyz,normal); + + // Output color + #ifdef ES_DEFERRED_SHADING + fragNormal.xyz = normal.xyz; + gl_FrontColor = gl_Color; + #else + // Output color + #ifdef ES_LIGHTING + gl_FrontColor = expeLighting(gl_Color, ePos.xyz, normal.xyz, 1.); + #else + gl_FrontColor = meshlabLighting(gl_Color, ePos.xyz, normal.xyz); + #endif + #endif + + oPos = gl_ModelViewProjectionMatrix * gl_Vertex; + + #ifdef ES_ATI_WORKAROUND + fragCenterAndRadius.xyz = (oPos.xyz/oPos.w) + 1.0; + fragCenterAndRadius.xy = fragCenterAndRadius.xy*halfVp; + fragCenterAndRadius.z = fragCenterAndRadius.z*0.5; + fragCenterAndRadius.w = pointSize.x; + #endif + + #if (ES_EWA_HINT>0) + scaledFragCenter2d = ((oPos.xy/oPos.w)+1.0)*halfVp*oneOverEwaRadius; + #endif + + #ifndef ES_EARLY_BACK_FACE_CULLING + oPos.w = oPos.w * (dotpn<0. ? 1.0 : 0.0); + #else + } + #endif + + gl_Position = oPos; +} + +#endif + +//-------------------------------------------------------------------------------- +// EWA Splatting +// Fragment Shader +//-------------------------------------------------------------------------------- + +#ifdef GLSPLAT__AttributeFP__ +// this sampler is only used by this fragment shader + +varying vec2 scaledFragCenter2d; +uniform vec3 rayCastParameter1; +uniform vec3 rayCastParameter2; +uniform vec2 depthParameterCast; + +// uniform sampler1D Kernel1dMap; + +void AttributeFP(void) +{ + #ifdef ES_ATI_WORKAROUND + vec3 fragCoord; + fragCoord.xy = fragCenterAndRadius.xy + (gl_TexCoord[0].st-0.5) * fragCenterAndRadius.w; + fragCoord.z = fragCenterAndRadius.z; + #else + vec3 fragCoord = gl_FragCoord.xyz; + #endif + +#if 1 + vec3 qOne = rayCastParameter1 * fragCoord + rayCastParameter2; + float oneOverDepth = dot(qOne,fragNoverCdotN); + float depth = (1.0/oneOverDepth); + vec3 diff = fragCenter - qOne * depth; + float r2 = dot(diff,diff); + + #if (ES_EWA_HINT>0) + vec2 d2 = oneOverEwaRadius*gl_FragCoord.xy - scaledFragCenter2d; + float r2d = dot(d2,d2); +// float weight = texture1D(Kernel1dMap, min(r2d,r2*scaleSquaredDistance)).a; + float weight = min(r2d,r2*scaleSquaredDistance); + weight = clamp(1.-weight,0,1); + weight = weight*weight; + #else + //float weight = texture1D(Kernel1dMap, r2*scaleSquaredDistance).a; + float weight = clamp(1.-r2*scaleSquaredDistance,0.0,1.0); + weight = weight*weight; + #endif + weight *= 0.1; // limits overflow + + #ifdef ES_DEPTH_CORRECTION + gl_FragDepth = depthParameterCast.x * oneOverDepth + depthParameterCast.y; + #endif + + #ifdef ES_DEFERRED_SHADING + gl_FragData[0].rgb = gl_Color.rgb; + gl_FragData[1].xyz = fragNormal.xyz; + gl_FragData[1].w = weight; + gl_FragData[0].w = weight; + + #if ES_DEPTH_INTERPOLATION==2 // linear space + gl_FragData[1].z = -depth; + #elif ES_DEPTH_INTERPOLATION==1 // window space + #ifdef ES_DEPTH_CORRECTION + gl_FragData[1].z = gl_FragDepth; + #else + gl_FragData[1].z = fragCoord.z; + #endif + #endif + + #else + gl_FragColor.rgb = gl_Color.rgb; + gl_FragColor.w = weight; + #endif +#endif +} + +#endif diff --git a/Polyhedron/demo/Polyhedron/MainWindow.cpp b/Polyhedron/demo/Polyhedron/MainWindow.cpp index 8a06dd6344e..1dc94f01231 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.cpp +++ b/Polyhedron/demo/Polyhedron/MainWindow.cpp @@ -699,7 +699,7 @@ void MainWindow::reload_item() { new_item->setColor(item->color()); new_item->setRenderingMode(item->renderingMode()); new_item->setVisible(item->visible()); - new_item->changed(); + new_item->invalidate_buffers(); scene->replaceItem(item_index, new_item, true); item->deleteLater(); } diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_corefinement_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_corefinement_plugin.cpp index 136cbc03735..2b96734a0bf 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_corefinement_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_corefinement_plugin.cpp @@ -168,7 +168,7 @@ void Polyhedron_demo_corefinement_plugin::corefinement() new_item->setColor(Qt::green); new_item->setRenderingMode(Wireframe); scene->addItem(new_item); - new_item->changed(); + new_item->invalidate_buffers(); std::cout << "ok (" << time.elapsed() << " ms)" << std::endl; } diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_cut_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_cut_plugin.cpp index d165d38856e..a0f233fb1a4 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_cut_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_cut_plugin.cpp @@ -80,7 +80,7 @@ public: } // Wireframe OpenGL drawing in a display list - void changed() + void invalidate_buffers() { compute_elements(); are_buffers_filled = false; @@ -163,7 +163,7 @@ public: bbox.ymax(), bbox.zmax()); } - void changed() + void invalidate_buffers() { compute_elements(); are_buffers_filled = false; @@ -473,6 +473,7 @@ void Polyhedron_demo_cut_plugin::cut() { } messages->information(QString("cut (%1 ms). %2 edges.").arg(time.elapsed()).arg(edges_item->edges.size())); + edges_item->invalidate_buffers(); scene->itemChanged(edges_item); } QApplication::restoreOverrideCursor(); diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_edit_polyhedron_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_edit_polyhedron_plugin.cpp index 36ab7c9728e..32db34b11c9 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_edit_polyhedron_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_edit_polyhedron_plugin.cpp @@ -158,6 +158,7 @@ void Polyhedron_demo_edit_polyhedron_plugin::on_PrevCtrlVertPushButton_clicked() if(!edit_item) return; // the selected item is not of the right type edit_item->prev_ctrl_vertices_group(); + edit_item->invalidate_buffers(); scene->itemChanged(edit_item); // for repaint } void Polyhedron_demo_edit_polyhedron_plugin::on_NextCtrlVertPushButton_clicked() @@ -176,6 +177,7 @@ void Polyhedron_demo_edit_polyhedron_plugin::on_SelectAllVerticesPushButton_clic if(!edit_item) return; // the selected item is not of the right type edit_item->set_all_vertices_as_roi(); + edit_item->invalidate_buffers(); scene->itemChanged(edit_item); // for repaint } void Polyhedron_demo_edit_polyhedron_plugin::on_DeleteCtrlVertPushButton_clicked() @@ -185,6 +187,7 @@ void Polyhedron_demo_edit_polyhedron_plugin::on_DeleteCtrlVertPushButton_clicked if(!edit_item) return; // the selected item is not of the right type edit_item->delete_ctrl_vertices_group(); + edit_item->invalidate_buffers(); scene->itemChanged(edit_item); // for repaint } void Polyhedron_demo_edit_polyhedron_plugin::on_ClearROIPushButton_clicked() @@ -194,6 +197,7 @@ void Polyhedron_demo_edit_polyhedron_plugin::on_ClearROIPushButton_clicked() if(!edit_item) return; // the selected item is not of the right type edit_item->clear_roi(); + edit_item->invalidate_buffers(); scene->itemChanged(edit_item); // for repaint } void Polyhedron_demo_edit_polyhedron_plugin::on_ApplyAndClosePushButton_clicked() @@ -299,6 +303,7 @@ void Polyhedron_demo_edit_polyhedron_plugin::on_ReadROIPushButton_clicked() if(fileName.isNull()) { return; } edit_item->read_roi(fileName.toLocal8Bit().data()); + edit_item->invalidate_buffers(); scene->itemChanged(edit_item); } void Polyhedron_demo_edit_polyhedron_plugin::dock_widget_visibility_changed(bool visible) diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_gocad_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_gocad_plugin.cpp index 31f7514cbf4..3b85e317caa 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_gocad_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_gocad_plugin.cpp @@ -73,7 +73,7 @@ Polyhedron_demo_gocad_plugin::load(QFileInfo fileinfo) { if(qcolor.isValid()) { item->setColor(qcolor); - item->changed(); + item->invalidate_buffers(); } diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_hole_filling_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_hole_filling_plugin.cpp index 43a9325e747..cd392caa64c 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_hole_filling_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_hole_filling_plugin.cpp @@ -102,8 +102,8 @@ public: void draw_edges(Viewer_interface* viewer) const { for(Polyline_data_list::const_iterator it = polyline_data_list.begin(); it != polyline_data_list.end(); ++it) { - if(it == active_hole) { ::glLineWidth(7.f); } - else { ::glLineWidth(3.f); } + if(it == active_hole) { viewer->glLineWidth(7.f); } + else { viewer->glLineWidth(3.f); } if(selected_holes.find(it) != selected_holes.end()) { it->polyline->setRbgColor(255, 0, 0); } @@ -338,6 +338,7 @@ protected: void change_poly_item_by_blocking(Scene_polyhedron_item* poly_item, Scene_hole_visualizer* collection) { if(collection) collection->block_poly_item_changed = true; + poly_item->invalidate_buffers(); scene->itemChanged(poly_item); if(collection) collection->block_poly_item_changed = false; } diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_inside_out_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_inside_out_plugin.cpp index 6c2c5fd3829..4fbe53793ef 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_inside_out_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_inside_out_plugin.cpp @@ -55,9 +55,11 @@ void Polyhedron_demo_inside_out_plugin::on_actionInsideOut_triggered() // inside out CGAL::Polygon_mesh_processing::reverse_face_orientations(*pMesh); + poly_item->invalidate_buffers(); } else { soup_item->inside_out(); + soup_item->invalidate_buffers(); } // update scene diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_intersection_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_intersection_plugin.cpp index 68f7485cb3d..8fa4dfbe973 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_intersection_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_intersection_plugin.cpp @@ -210,7 +210,7 @@ void Polyhedron_demo_intersection_plugin::intersection() new_item->setColor(Qt::green); new_item->setRenderingMode(Wireframe); scene->addItem(new_item); - new_item->changed(); + new_item->invalidate_buffers(); QApplication::restoreOverrideCursor(); } diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_jet_fitting_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_jet_fitting_plugin.cpp index 26cdf588dac..0065b3ecf10 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_jet_fitting_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_jet_fitting_plugin.cpp @@ -121,8 +121,8 @@ void Polyhedron_demo_jet_fitting_plugin::on_actionEstimateCurvature_triggered() scene->addItem(max_curv); scene->addItem(min_curv); - max_curv->changed(); - min_curv->changed(); + max_curv->invalidate_buffers(); + min_curv->invalidate_buffers(); // default cursor QApplication::restoreOverrideCursor(); diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_join_and_split_polyhedra_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_join_and_split_polyhedra_plugin.cpp index 5985d327b2b..b31506e427d 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_join_and_split_polyhedra_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_join_and_split_polyhedra_plugin.cpp @@ -82,6 +82,7 @@ void Polyhedron_demo_join_and_split_polyhedra_plugin::on_actionJoinPolyhedra_tri } } + mainSelectionItem->invalidate_buffers(); scene->itemChanged(mainSelectionIndex); //remove the other items @@ -162,6 +163,7 @@ void Polyhedron_demo_join_and_split_polyhedra_plugin::on_actionColorConnectedCom CGAL::internal::corefinement::Dummy_true(), marker ); + item->invalidate_buffers(); scene->itemChanged(item); } } diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_mean_curvature_flow_skeleton_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_mean_curvature_flow_skeleton_plugin.cpp index 98161cd4b11..0d25d1ca2d5 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_mean_curvature_flow_skeleton_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_mean_curvature_flow_skeleton_plugin.cpp @@ -332,6 +332,7 @@ public: { CGAL::Polyhedron_copy_3 modifier(mcs->meso_skeleton()); meso_skeleton->delegate(modifier); + scene->item(contractedItemIndex)->invalidate_buffers(); scene->itemChanged(contractedItemIndex); } @@ -510,7 +511,7 @@ void Polyhedron_demo_mean_curvature_flow_skeleton_plugin::on_actionConvert_to_me skeleton_item->setName(QString("Medial skeleton curve of %1").arg(item->name())); scene->addItem(skeleton_item); - skeleton_item->changed(); + skeleton_item->invalidate_buffers(); item->setPointsMode(); @@ -661,6 +662,7 @@ void Polyhedron_demo_mean_curvature_flow_skeleton_plugin::on_actionDegeneracy() } // update scene update_meso_skeleton(); + scene->item(fixedPointsItemIndex)->invalidate_buffers(); scene->itemChanged(fixedPointsItemIndex); scene->setSelectedItem(index); QApplication::restoreOverrideCursor(); @@ -824,7 +826,7 @@ void Polyhedron_demo_mean_curvature_flow_skeleton_plugin::on_actionSkeletonize() skeleton->setName(QString("skeleton curve of %1").arg(item->name())); scene->addItem(skeleton); - skeleton->changed(); + skeleton->invalidate_buffers(); // set the fixed points and contracted mesh as invisible if (fixedPointsItemIndex >= 0) @@ -895,6 +897,7 @@ void Polyhedron_demo_mean_curvature_flow_skeleton_plugin::on_actionConverge() delete temp; } + scene->item(fixedPointsItemIndex)->invalidate_buffers(); scene->itemChanged(fixedPointsItemIndex); update_meso_skeleton(); scene->setSelectedItem(index); diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_mesh_3_plugin_cgal_code.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_mesh_3_plugin_cgal_code.cpp index f05d890238e..c39bca47f0a 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_mesh_3_plugin_cgal_code.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_mesh_3_plugin_cgal_code.cpp @@ -66,7 +66,7 @@ public: delete frame; } - void changed() + void invalidate_buffers() { compute_elements(); are_buffers_filled = false; @@ -75,7 +75,7 @@ public: void contextual_changed() { if(frame->isManipulated()||frame->isSpinning()) - changed(); + invalidate_buffers(); } const C3t3& c3t3() const { return c3t3_; @@ -150,7 +150,7 @@ public: // Indicate if rendering mode is supported bool supportsRenderingMode(RenderingMode m) const { - return (m != Gouraud && m!=PointsPlusNormals); // CHECK THIS! + return (m != Gouraud && m!=PointsPlusNormals && m!=Splatting); // CHECK THIS! } void draw(Viewer_interface* viewer) const { diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_mesh_segmentation_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_mesh_segmentation_plugin.cpp index 0295adb49f3..1c1b7b538fb 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_mesh_segmentation_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_mesh_segmentation_plugin.cpp @@ -217,6 +217,7 @@ void Polyhedron_demo_mesh_segmentation_plugin::on_SDF_button_clicked() scene->setSelectedItem(index); } else { + item->invalidate_buffers(); scene->itemChanged(index); } @@ -288,6 +289,7 @@ void Polyhedron_demo_mesh_segmentation_plugin::on_Partition_button_clicked() scene->setSelectedItem(index); } else { + item->invalidate_buffers(); scene->itemChanged(index); } diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_mesh_simplification_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_mesh_simplification_plugin.cpp index f0bc7b35b2d..1df3f662b27 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_mesh_simplification_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_mesh_simplification_plugin.cpp @@ -76,6 +76,7 @@ void Polyhedron_demo_mesh_simplification_plugin::on_actionSimplify_triggered() << pMesh->size_of_halfedges() / 2 << " edges)" << std::endl; // update scene + item->invalidate_buffers(); scene->itemChanged(index); QApplication::restoreOverrideCursor(); } diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_normal_estimation_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_normal_estimation_plugin.cpp index 61f05490915..56b5bcc3e2e 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_normal_estimation_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_normal_estimation_plugin.cpp @@ -105,6 +105,7 @@ void Polyhedron_demo_normal_estimation_plugin::on_actionNormalInversion_triggere for(Point_set::iterator it = points->begin(); it != points->end(); ++it){ it->normal() = -1 * it->normal(); } + item->invalidate_buffers(); scene->itemChanged(item); } } @@ -206,6 +207,7 @@ void Polyhedron_demo_normal_estimation_plugin::on_actionNormalEstimation_trigger points->select(first_unoriented_point, points->end(), true); // Updates scene + item->invalidate_buffers(); scene->itemChanged(index); QApplication::restoreOverrideCursor(); diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_orient_soup_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_orient_soup_plugin.cpp index 40ddf8b6d6f..a66cc48b18c 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_orient_soup_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_orient_soup_plugin.cpp @@ -106,11 +106,12 @@ void Polyhedron_demo_orient_soup_plugin::orient() poly_item->setColor(item->color()); poly_item->setRenderingMode(item->renderingMode()); poly_item->setVisible(item->visible()); - poly_item->changed(); + poly_item->invalidate_buffers(); poly_item->setProperty("source filename", item->property("source filename")); scene->replaceItem(index, poly_item); delete item; } else { + item->invalidate_buffers(); scene->itemChanged(item); } @@ -131,7 +132,7 @@ void Polyhedron_demo_orient_soup_plugin::shuffle() if(item) { item->shuffle_orientations(); - scene->itemChanged(item); + //scene->itemChanged(item); } else { Scene_polyhedron_item* poly_item = @@ -161,7 +162,6 @@ void Polyhedron_demo_orient_soup_plugin::displayNonManifoldEdges() if(item) { item->setDisplayNonManifoldEdges(!item->displayNonManifoldEdges()); - item->changed(); scene->itemChanged(item); } } diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_parameterization_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_parameterization_plugin.cpp index 9d76eb00f1f..495fa8d28e9 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_parameterization_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_parameterization_plugin.cpp @@ -130,6 +130,8 @@ void Polyhedron_demo_parameterization_plugin::parameterize(const Parameterizatio new_item->setColor(Qt::white); new_item->setRenderingMode(poly_item->renderingMode()); + poly_item->setVisible(false); + scene->itemChanged(index); scene->addItem(new_item); QApplication::restoreOverrideCursor(); diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_inside_polyhedron_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_inside_polyhedron_plugin.cpp index 61b0b9781c2..1405ef8de05 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_inside_polyhedron_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_inside_polyhedron_plugin.cpp @@ -169,6 +169,7 @@ public Q_SLOTS: Q_FOREACH(Scene_interface::Item_id id, scene->selectionIndices()) { Scene_points_with_normal_item* point_item = qobject_cast(scene->item(id)); if(point_item) { + point_item->invalidate_buffers(); scene->itemChanged(point_item); } } diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_bilateral_smoothing_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_bilateral_smoothing_plugin.cpp new file mode 100644 index 00000000000..8e81c52d531 --- /dev/null +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_bilateral_smoothing_plugin.cpp @@ -0,0 +1,119 @@ +#include "config.h" +#include "Scene_points_with_normal_item.h" +#include "Polyhedron_demo_plugin_helper.h" +#include "Polyhedron_demo_plugin_interface.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "ui_Polyhedron_demo_point_set_bilateral_smoothing_plugin.h" + +class Polyhedron_demo_point_set_bilateral_smoothing_plugin : + public QObject, + public Polyhedron_demo_plugin_helper +{ + Q_OBJECT + Q_INTERFACES(Polyhedron_demo_plugin_interface) + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") + + QAction* actionBilateralSmoothing; + +public: + void init(QMainWindow* mainWindow, Scene_interface* scene_interface) { + actionBilateralSmoothing = new QAction(tr("Point set bilateral smoothing"), mainWindow); + actionBilateralSmoothing->setObjectName("actionBilateralSmoothing"); + + Polyhedron_demo_plugin_helper::init(mainWindow, scene_interface); + } + + bool applicable(QAction*) const { + return qobject_cast(scene->item(scene->mainSelectionIndex())); + } + + QList actions() const { + return QList() << actionBilateralSmoothing; + } + +public Q_SLOTS: + void on_actionBilateralSmoothing_triggered(); + +}; // end Polyhedron_demo_point_set_bilateral_smoothing_plugin + +class Point_set_demo_point_set_bilateral_smoothing_dialog : public QDialog, private Ui::PointSetBilateralSmoothingDialog +{ + Q_OBJECT + public: + Point_set_demo_point_set_bilateral_smoothing_dialog(QWidget * /*parent*/ = 0) + { + setupUi(this); + } + + unsigned int iterations() const { return m_iterations->value(); } + unsigned int neighborhood_size () const { return m_neighborhoodSize->value(); } + unsigned int sharpness_angle () const { return m_sharpnessAngle->value(); } +}; + +void Polyhedron_demo_point_set_bilateral_smoothing_plugin::on_actionBilateralSmoothing_triggered() +{ + const 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 + Point_set_demo_point_set_bilateral_smoothing_dialog dialog; + if(!dialog.exec()) + return; + + std::cerr << "Bilateral smoothing using " + << dialog.iterations () << " iteration(s), neighborhood size of " + << dialog.neighborhood_size () << " and sharpness angle of " + << dialog.sharpness_angle () << "... "; + QApplication::setOverrideCursor(Qt::WaitCursor); + + CGAL::Timer task_timer; task_timer.start(); + + for (unsigned int i = 0; i < dialog.iterations (); ++i) + { + /* double error = */ + CGAL::bilateral_smooth_point_set + (points->begin(), + points->end(), + CGAL::make_identity_property_map(Point_set::value_type()), + CGAL::make_normal_of_point_with_normal_pmap(Point_set::value_type()), + dialog.neighborhood_size (), + dialog.sharpness_angle ()); + } + + + + std::size_t memory = CGAL::Memory_sizer().virtual_size(); + std::cerr << task_timer.time() << " seconds, " + << (memory>>20) << " Mb allocated)" + << std::endl; + + // Updates scene + item->invalidate_buffers(); + scene->itemChanged(index); + + QApplication::restoreOverrideCursor(); + + } +} + +#include "Polyhedron_demo_point_set_bilateral_smoothing_plugin.moc" diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_bilateral_smoothing_plugin.ui b/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_bilateral_smoothing_plugin.ui new file mode 100644 index 00000000000..4844e44f0d1 --- /dev/null +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_bilateral_smoothing_plugin.ui @@ -0,0 +1,130 @@ + + + PointSetBilateralSmoothingDialog + + + + 0 + 0 + 357 + 141 + + + + Bilateral smoothing + + + + + + Iterations + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + Neighborhood size + + + + + + + 1 + + + 2147483647 + + + 1 + + + + + + + + + + + + + 1 + + + 2147483647 + + + 24 + + + + + + + ° + + + 90 + + + 25 + + + + + + + Sharpness Angle + + + + + + + + + buttonBox + accepted() + PointSetBilateralSmoothingDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + PointSetBilateralSmoothingDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_outliers_removal_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_outliers_removal_plugin.cpp index 696e8e574aa..a32faf63128 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_outliers_removal_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_outliers_removal_plugin.cpp @@ -107,6 +107,7 @@ void Polyhedron_demo_point_set_outliers_removal_plugin::on_actionOutlierRemoval_ points->select(first_point_to_remove, points->end(), true); // Updates scene + item->invalidate_buffers(); scene->itemChanged(index); QApplication::restoreOverrideCursor(); diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_selection_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_selection_plugin.cpp index a4cefb15f52..7afe8e38220 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_selection_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_selection_plugin.cpp @@ -74,7 +74,7 @@ public: } void draw_edges(Viewer_interface* viewer) const { - ::glLineWidth(3.f); + viewer->glLineWidth(3.f); polyline->setRbgColor(0, 255, 0); polyline->draw_edges(viewer); @@ -147,7 +147,6 @@ public: if (update_polyline ()) { Q_EMIT itemChanged(); - // polyline->changed(); } } @@ -358,7 +357,7 @@ protected: } - point_set_item->changed(); + point_set_item->invalidate_buffers(); } @@ -442,7 +441,7 @@ public Q_SLOTS: new_item->point_set()->push_back(*it); } new_item->resetSelection(); - new_item->changed(); + new_item->invalidate_buffers(); scene->addItem(new_item); } diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_simplification_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_simplification_plugin.cpp index b7478151bf5..fa799214d45 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_simplification_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_simplification_plugin.cpp @@ -125,6 +125,7 @@ void Polyhedron_demo_point_set_simplification_plugin::on_actionSimplify_triggere points->select(first_point_to_remove, points->end(), true); // Updates scene + item->invalidate_buffers(); scene->itemChanged(index); QApplication::restoreOverrideCursor(); diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_smoothing_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_smoothing_plugin.cpp index 3667d8be1a4..4acb5b9261f 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_smoothing_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_smoothing_plugin.cpp @@ -79,6 +79,7 @@ void Polyhedron_demo_point_set_smoothing_plugin::on_actionJetSmoothing_triggered item->set_has_normals(false); // update scene + item->invalidate_buffers(); scene->itemChanged(index); QApplication::restoreOverrideCursor(); diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_upsampling_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_upsampling_plugin.cpp new file mode 100644 index 00000000000..42982473682 --- /dev/null +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_upsampling_plugin.cpp @@ -0,0 +1,139 @@ +#include "config.h" +#include "Scene_points_with_normal_item.h" +#include "Polyhedron_demo_plugin_helper.h" +#include "Polyhedron_demo_plugin_interface.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "ui_Polyhedron_demo_point_set_upsampling_plugin.h" + +class Polyhedron_demo_point_set_upsampling_plugin : + public QObject, + public Polyhedron_demo_plugin_helper +{ + Q_OBJECT + Q_INTERFACES(Polyhedron_demo_plugin_interface) + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") + + QAction* actionEdgeAwareUpsampling; + +public: + void init(QMainWindow* mainWindow, Scene_interface* scene_interface) { + actionEdgeAwareUpsampling = new QAction(tr("Point set edge aware upsampling"), mainWindow); + actionEdgeAwareUpsampling->setObjectName("actionEdgeAwareUpsampling"); + + Polyhedron_demo_plugin_helper::init(mainWindow, scene_interface); + } + + bool applicable(QAction*) const { + return qobject_cast(scene->item(scene->mainSelectionIndex())); + } + + QList actions() const { + return QList() << actionEdgeAwareUpsampling; + } + +public Q_SLOTS: + void on_actionEdgeAwareUpsampling_triggered(); + +}; // end Polyhedron_demo_point_set_upsampling_plugin + +class Point_set_demo_point_set_upsampling_dialog : public QDialog, private Ui::PointSetUpsamplingDialog +{ + + Q_OBJECT +public: + Point_set_demo_point_set_upsampling_dialog(QWidget * /*parent*/ = 0) + { + setupUi(this); + } + + unsigned int sharpness_angle () const { return m_sharpnessAngle->value(); } + double edge_sensitivity() const { return m_edgeSensitivity->value(); } + double neighborhood_radius () const { return m_neighborhoodRadius->value(); } + double output_size () const { return m_outputSize->value(); } + +}; + +void Polyhedron_demo_point_set_upsampling_plugin::on_actionEdgeAwareUpsampling_triggered() +{ + const Scene_interface::Item_id index = scene->mainSelectionIndex(); + + Scene_points_with_normal_item* item = + qobject_cast(scene->item(index)); + + if(item) + { + if (!(item->has_normals ())) + { + std::cerr << "Error: upsampling algorithm requires point set with normals." << std::endl; + return; + } + + // Gets point set + Point_set* points = item->point_set(); + if(points == NULL) + return; + + // Gets options + Point_set_demo_point_set_upsampling_dialog dialog; + if(!dialog.exec()) + return; + + unsigned int output_size = static_cast(dialog.output_size () + * points->size ()); + std::cerr << "Edge aware upsampling (sharpness angle = " + << dialog.sharpness_angle () << ", edge sensitivity = " + << dialog.edge_sensitivity () << ", neighborhood radius = " + << dialog.neighborhood_radius () << " * average spacing, output size = " + << output_size << "...\n"; + + QApplication::setOverrideCursor(Qt::WaitCursor); + + CGAL::Timer task_timer; task_timer.start(); + + // Computes average spacing + double average_spacing = CGAL::compute_average_spacing( + points->begin(), points->end(), + 6 /* knn = 1 ring */); + + std::vector > new_points; + CGAL::edge_aware_upsample_point_set(points->begin(), + points->end(), + std::back_inserter(new_points), + CGAL::make_identity_property_map(Point_set::value_type()), + CGAL::make_normal_of_point_with_normal_pmap(Point_set::value_type()), + dialog.sharpness_angle(), + dialog.edge_sensitivity(), + dialog.neighborhood_radius() * average_spacing, + output_size); + + for (unsigned int i = 0; i < new_points.size (); ++ i) + points->push_back (Point_set::Point_with_normal (new_points[i].first, + new_points[i].second)); + + std::size_t memory = CGAL::Memory_sizer().virtual_size(); + std::cerr << task_timer.time() << " seconds, " + << (memory>>20) << " Mb allocated)" + << std::endl; + + // Updates scene + item->invalidate_buffers(); + scene->itemChanged(index); + + QApplication::restoreOverrideCursor(); + + } +} + +#include "Polyhedron_demo_point_set_upsampling_plugin.moc" diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_upsampling_plugin.ui b/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_upsampling_plugin.ui new file mode 100644 index 00000000000..564b6e2939c --- /dev/null +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_upsampling_plugin.ui @@ -0,0 +1,156 @@ + + + PointSetUpsamplingDialog + + + + 0 + 0 + 443 + 175 + + + + Edge Aware Upsampling + + + + + + Sharpness Angle + + + + + + + Neighborhood Radius + + + + + + + Edge Sensitivity + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + Output Size + + + + + + + 1.000000000000000 + + + 0.010000000000000 + + + + + + + + + + * input size + + + 1.000000000000000 + + + 1000.000000000000000 + + + 4.000000000000000 + + + + + + + ° + + + 90 + + + 25 + + + + + + + * average spacing + + + 2 + + + 0.100000000000000 + + + 10.000000000000000 + + + 0.100000000000000 + + + 3.000000000000000 + + + + + + + + + buttonBox + accepted() + PointSetUpsamplingDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + PointSetUpsamplingDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_wlop_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_wlop_plugin.cpp new file mode 100644 index 00000000000..f6718007691 --- /dev/null +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_wlop_plugin.cpp @@ -0,0 +1,120 @@ +#include "config.h" +#include "Scene_points_with_normal_item.h" +#include "Polyhedron_demo_plugin_helper.h" +#include "Polyhedron_demo_plugin_interface.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "ui_Polyhedron_demo_point_set_wlop_plugin.h" + +class Polyhedron_demo_point_set_wlop_plugin : + public QObject, + public Polyhedron_demo_plugin_helper +{ + Q_OBJECT + Q_INTERFACES(Polyhedron_demo_plugin_interface) + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") + + QAction* actionSimplifyAndRegularize; + +public: + void init(QMainWindow* mainWindow, Scene_interface* scene_interface) { + actionSimplifyAndRegularize = new QAction(tr("Point set WLOP simplification and regularization selection"), mainWindow); + actionSimplifyAndRegularize->setObjectName("actionSimplifyAndRegularize"); + + Polyhedron_demo_plugin_helper::init(mainWindow, scene_interface); + } + + bool applicable(QAction*) const { + return qobject_cast(scene->item(scene->mainSelectionIndex())); + } + + QList actions() const { + return QList() << actionSimplifyAndRegularize; + } + +public Q_SLOTS: + void on_actionSimplifyAndRegularize_triggered(); + +}; // end Polyhedron_demo_point_set_wlop_plugin + +class Point_set_demo_point_set_wlop_simplification_and_regularization_dialog : public QDialog, private Ui::WLOPRegularizationAndSimplificationDialog +{ + Q_OBJECT + public: + Point_set_demo_point_set_wlop_simplification_and_regularization_dialog(QWidget * /*parent*/ = 0) + { + setupUi(this); + } + + double retainedPercentage() const { return m_retainedPercentage->value(); } + double neighborhoodRadius() const { return m_neighborhoodRadius->value(); } +}; + +void Polyhedron_demo_point_set_wlop_plugin::on_actionSimplifyAndRegularize_triggered() +{ + const 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 + Point_set_demo_point_set_wlop_simplification_and_regularization_dialog dialog; + if(!dialog.exec()) + return; + + QApplication::setOverrideCursor(Qt::WaitCursor); + + CGAL::Timer task_timer; task_timer.start(); + + std::cerr << "Point cloud simplification and regularization by WLOP (" + << dialog.retainedPercentage () << "% retained points, neighborhood radius = " + << dialog.neighborhoodRadius() <<" * average spacing)...\n"; + + // Computes average spacing + double average_spacing = CGAL::compute_average_spacing(points->begin(), points->end(), + 6 /* knn = 1 ring */); + + Scene_points_with_normal_item* new_item + = new Scene_points_with_normal_item(); + new_item->setName (tr("%1 (WLOP processed)").arg(item->name())); + new_item->setVisible(true); + scene->addItem(new_item); + + CGAL::wlop_simplify_and_regularize_point_set // parallel version + (points->begin(), + points->end(), + std::back_inserter(*(new_item->point_set ())), + dialog.retainedPercentage (), + dialog.neighborhoodRadius()*average_spacing + ); + + std::size_t memory = CGAL::Memory_sizer().virtual_size(); + std::cerr << "Simplification and regularization: " + << new_item->point_set ()->size () << " point(s) created (" + << task_timer.time() << " seconds, " + << (memory>>20) << " Mb allocated)" + << std::endl; + + QApplication::restoreOverrideCursor(); + } +} + +#include "Polyhedron_demo_point_set_wlop_plugin.moc" diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_wlop_plugin.ui b/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_wlop_plugin.ui new file mode 100644 index 00000000000..d0326712214 --- /dev/null +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_wlop_plugin.ui @@ -0,0 +1,122 @@ + + + WLOPRegularizationAndSimplificationDialog + + + + 0 + 0 + 292 + 109 + + + + WLOP simplification and regularization + + + + + + Retained percentage + + + + + + + % + + + 2 + + + 0.100000000000000 + + + 100.000000000000000 + + + 0.100000000000000 + + + 50.000000000000000 + + + + + + + Neighborhood radius + + + + + + + * average spacing + + + 2 + + + 0.100000000000000 + + + 10.000000000000000 + + + 0.100000000000000 + + + 1.000000000000000 + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + WLOPRegularizationAndSimplificationDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + WLOPRegularizationAndSimplificationDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_polyhedron_slicer_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_polyhedron_slicer_plugin.cpp index 7fb2f93a929..534ce5a04c4 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_polyhedron_slicer_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_polyhedron_slicer_plugin.cpp @@ -306,7 +306,7 @@ void Polyhedron_demo_polyhedron_slicer_plugin::on_Generate_button_clicked() new_polylines_item->setColor(Qt::green); new_polylines_item->setRenderingMode(Wireframe); scene->addItem(new_polylines_item); - new_polylines_item->changed(); + new_polylines_item->invalidate_buffers(); } } } diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_polyhedron_stitching_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_polyhedron_stitching_plugin.cpp index 9ea5c4034ac..0f9ae0822b6 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_polyhedron_stitching_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_polyhedron_stitching_plugin.cpp @@ -139,7 +139,7 @@ void Polyhedron_demo_polyhedron_stitching_plugin::on_actionDetectBorders_trigger new_item->setName(tr("Boundary of %1").arg(item->name())); new_item->setColor(Qt::red); scene->addItem(new_item); - new_item->changed(); + new_item->invalidate_buffers(); } } } @@ -156,6 +156,7 @@ void Polyhedron_demo_polyhedron_stitching_plugin::on_actionStitchBorders_trigger { Polyhedron* pMesh = item->polyhedron(); CGAL::Polygon_mesh_processing::stitch_borders(*pMesh); + item->invalidate_buffers(); scene->itemChanged(item); } } diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_polylines_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_polylines_io_plugin.cpp index e902ccdeec6..f2ffbb44590 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_polylines_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_polylines_io_plugin.cpp @@ -76,7 +76,7 @@ Polyhedron_demo_polylines_io_plugin::load(QFileInfo fileinfo) { item->setColor(Qt::black); item->setProperty("polylines metadata", polylines_metadata); std::cerr << "Number of polylines in item: " << item->polylines.size() << std::endl; - item->changed(); + item->invalidate_buffers(); return item; } diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_scale_space_reconstruction_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_scale_space_reconstruction_plugin.cpp index ac1238f5aa1..91191438f34 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_scale_space_reconstruction_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_scale_space_reconstruction_plugin.cpp @@ -142,8 +142,6 @@ void Polyhedron_demo_scale_space_reconstruction_plugin::on_actionScaleSpaceRecon map_i2i[(*it)[2]] ); } - new_item->finalize_polygon_soup(); - new_item->setName(tr("%1-shell %2 (ss reconstruction)").arg(scene->item(index)->name()).arg(sh+1)); new_item->setColor(Qt::magenta); new_item->setRenderingMode(FlatPlusEdges); @@ -176,8 +174,6 @@ void Polyhedron_demo_scale_space_reconstruction_plugin::on_actionScaleSpaceRecon map_i2i_smoothed[(*it)[2]] ); } - new_item_smoothed->finalize_polygon_soup(); - new_item_smoothed->setName(tr("%1-shell %2 (ss smoothed reconstruction)").arg(scene->item(index)->name()).arg(sh+1)); new_item_smoothed->setColor(Qt::magenta); new_item_smoothed->setRenderingMode(FlatPlusEdges); diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_selection_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_selection_plugin.cpp index 6c05c43e9ad..73a62f6db0c 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_selection_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_selection_plugin.cpp @@ -303,7 +303,7 @@ public Q_SLOTS: Scene_polyhedron_item* poly_item = new Scene_polyhedron_item(); if(selection_item->export_selected_facets_as_polyhedron(poly_item->polyhedron())) { poly_item->setName(QString("%1-facets").arg(selection_item->name())); - poly_item->changed(); // for init() + poly_item->invalidate_buffers(); // for init() scene->setSelectedItem( scene->addItem(poly_item) ); scene->itemChanged(poly_item); } diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_self_intersection_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_self_intersection_plugin.cpp index 87d12a14d18..259d65073a8 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_self_intersection_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_self_intersection_plugin.cpp @@ -72,6 +72,7 @@ void Polyhedron_demo_self_intersection_plugin::on_actionSelfIntersection_trigger selection_item->selected_facets.insert(fb->first); selection_item->selected_facets.insert(fb->second); } + selection_item->invalidate_buffers(); selection_item->setName(tr("%1 (selection) (intersecting triangles)").arg(item->name())); scene->addItem(selection_item); item->setRenderingMode(Wireframe); diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_stl_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_stl_plugin.cpp index cc49cbd9cd5..c594b21cc62 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_stl_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_stl_plugin.cpp @@ -59,7 +59,8 @@ Polyhedron_demo_stl_plugin::load(QFileInfo fileinfo) { try{ // Try building a polyhedron Polyhedron P; - CGAL::Polygon_mesh_processing::polygon_soup_to_polygon_mesh(points, triangles, P); + if (CGAL::Polygon_mesh_processing::is_polygon_soup_a_polygon_mesh(triangles)) + CGAL::Polygon_mesh_processing::polygon_soup_to_polygon_mesh(points, triangles, P); if(! P.is_valid() || P.empty()){ std::cerr << "Error: Invalid polyhedron" << std::endl; diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_subdivision_methods_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_subdivision_methods_plugin.cpp index eec02ffc4db..708f7e95e6b 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_subdivision_methods_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_subdivision_methods_plugin.cpp @@ -48,6 +48,7 @@ void Polyhedron_demo_subdivision_methods_plugin::on_actionLoop_triggered() CGAL::Subdivision_method_3::Loop_subdivision(*poly, 1); std::cout << "ok (" << time.elapsed() << " ms)" << std::endl; QApplication::restoreOverrideCursor(); + item->invalidate_buffers(); scene->itemChanged(item); } @@ -68,6 +69,7 @@ void Polyhedron_demo_subdivision_methods_plugin::on_actionCatmullClark_triggered CGAL::Subdivision_method_3::CatmullClark_subdivision(*poly, 1); std::cout << "ok (" << time.elapsed() << " ms)" << std::endl; QApplication::restoreOverrideCursor(); + item->invalidate_buffers(); scene->itemChanged(item); } @@ -88,6 +90,7 @@ void Polyhedron_demo_subdivision_methods_plugin::on_actionSqrt3_triggered() CGAL::Subdivision_method_3::Sqrt3_subdivision(*poly, 1); std::cout << "ok (" << time.elapsed() << " ms)" << std::endl; QApplication::restoreOverrideCursor(); + item->invalidate_buffers(); scene->itemChanged(item); } diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_triangulate_facets_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_triangulate_facets_plugin.cpp index 2cb15fb4421..c887859cc96 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_triangulate_facets_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_triangulate_facets_plugin.cpp @@ -96,6 +96,7 @@ public Q_SLOTS: } CGAL_assertion_code(pMesh->normalize_border()); // CGAL_assertion(pMesh->is_valid(true, 3)); + item->invalidate_buffers(); scene->itemChanged(item); // default cursor QApplication::restoreOverrideCursor(); @@ -125,6 +126,7 @@ public Q_SLOTS: CGAL_assertion_code(pMesh->normalize_border()); CGAL_assertion(pMesh->is_valid(false, 3)); + item->invalidate_buffers(); scene->itemChanged(item); // default cursor QApplication::restoreOverrideCursor(); diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_trivial_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_trivial_plugin.cpp index f6ed8da5cff..3be86d7988c 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_trivial_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_trivial_plugin.cpp @@ -62,7 +62,7 @@ public: } - void changed() + void invalidate_buffers() { compute_elements(); are_buffers_filled = false; diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_vcm_normal_estimation_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_vcm_normal_estimation_plugin.cpp index 91bc305f133..49e535be6f9 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_vcm_normal_estimation_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_vcm_normal_estimation_plugin.cpp @@ -155,6 +155,7 @@ void Polyhedron_demo_vcm_normal_estimation_plugin::on_actionVCMNormalEstimation_ << std::endl; // Updates scene + item->invalidate_buffers(); scene->itemChanged(index); QApplication::restoreOverrideCursor(); diff --git a/Polyhedron/demo/Polyhedron/Scene.cpp b/Polyhedron/demo/Polyhedron/Scene.cpp index fc573bc5776..184c9926adf 100644 --- a/Polyhedron/demo/Polyhedron/Scene.cpp +++ b/Polyhedron/demo/Polyhedron/Scene.cpp @@ -1,3 +1,7 @@ +#include "GlSplat/GlSplat.h" + + + #include "config.h" #include "Scene.h" #include "Scene_item.h" @@ -16,11 +20,14 @@ #include -namespace { -void CGALglcolor(QColor c) + + +GlSplat::SplatRenderer* Scene::ms_splatting = 0; +int Scene::ms_splattingCounter = 0; +GlSplat::SplatRenderer* Scene::splatting() { - ::glColor4d(c.red()/255.0, c.green()/255.0, c.blue()/255.0, c.alpha()/255.0); -} + assert(ms_splatting!=0 && "A Scene object must be created before requesting the splatting object"); + return ms_splatting; } Scene::Scene(QObject* parent) @@ -34,8 +41,13 @@ Scene::Scene(QObject* parent) double, double, double)), this, SLOT(setSelectionRay(double, double, double, double, double, double))); -} + if(ms_splatting==0) + ms_splatting = new GlSplat::SplatRenderer(); + ms_splattingCounter++; + + +} Scene::Item_id Scene::addItem(Scene_item* item) { @@ -44,6 +56,8 @@ Scene::addItem(Scene_item* item) m_entries.push_back(item); connect(item, SIGNAL(itemChanged()), this, SLOT(itemChanged())); + connect(item, SIGNAL(renderingModeChanged()), + this, SLOT(callDraw())); if(bbox_before + item->bbox() != bbox_before) { Q_EMIT updated_bbox(); } QAbstractListModel::beginResetModel(); @@ -57,7 +71,6 @@ Scene::addItem(Scene_item* item) Scene_item* Scene::replaceItem(Scene::Item_id index, Scene_item* item, bool emit_item_about_to_be_destroyed) { - item->changed(); if(index < 0 || index >= m_entries.size()) return 0; @@ -150,6 +163,9 @@ Scene::~Scene() delete item_ptr; } m_entries.clear(); + + if((--ms_splattingCounter)==0) + delete ms_splatting; } Scene_item* @@ -193,6 +209,8 @@ Scene::duplicate(Item_id index) void Scene::initializeGL() { + ms_splatting->init(); + //Setting the light options // Create light components @@ -245,37 +263,37 @@ Scene::drawWithNames(Viewer_interface* viewer) void Scene::draw_aux(bool with_names, Viewer_interface* viewer) { + if(!ms_splatting->viewer_is_set) + ms_splatting->setViewer(viewer); // Flat/Gouraud OpenGL drawing for(int index = 0; index < m_entries.size(); ++index) { if(with_names) { - ::glPushName(index); + viewer->glPushName(index); } Scene_item& item = *m_entries[index]; if(item.visible()) { if(item.renderingMode() == Flat || item.renderingMode() == FlatPlusEdges || item.renderingMode() == Gouraud) { - ::glEnable(GL_LIGHTING); - ::glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); - ::glPointSize(2.f); - ::glLineWidth(1.0f); + viewer->glEnable(GL_LIGHTING); + viewer->glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); + viewer->glPointSize(2.f); + viewer->glLineWidth(1.0f); if(index == selected_item) { item.selection_changed(true); - CGALglcolor(item.color().lighter(120)); } else { item.selection_changed(false); - CGALglcolor(item.color()); } if(item.renderingMode() == Gouraud) - ::glShadeModel(GL_SMOOTH); + viewer->glShadeModel(GL_SMOOTH); else - ::glShadeModel(GL_FLAT); + viewer->glShadeModel(GL_FLAT); item.contextual_changed(); if(viewer) @@ -285,7 +303,7 @@ Scene::draw_aux(bool with_names, Viewer_interface* viewer) } } if(with_names) { - ::glPopName(); + viewer->glPopName(); } } glDepthFunc(GL_LEQUAL); @@ -293,25 +311,23 @@ glDepthFunc(GL_LEQUAL); for(int index = 0; index < m_entries.size(); ++index) { if(with_names) { - ::glPushName(index); + viewer->glPushName(index); } Scene_item& item = *m_entries[index]; if(item.visible()) { if(item.renderingMode() == FlatPlusEdges || item.renderingMode() == Wireframe) { - ::glDisable(GL_LIGHTING); - ::glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); - ::glPointSize(2.f); - ::glLineWidth(1.0f); + viewer->glDisable(GL_LIGHTING); + viewer->glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); + viewer->glPointSize(2.f); + viewer->glLineWidth(1.0f); if(index == selected_item) { - CGALglcolor(Qt::black); item.selection_changed(true); } else { - CGALglcolor(item.color().lighter(50)); item.selection_changed(false); } @@ -324,21 +340,19 @@ glDepthFunc(GL_LEQUAL); } else{ if( item.renderingMode() == PointsPlusNormals ){ - ::glDisable(GL_LIGHTING); - ::glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); - ::glPointSize(2.f); - ::glLineWidth(1.0f); + viewer->glDisable(GL_LIGHTING); + viewer->glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); + viewer->glPointSize(2.f); + viewer->glLineWidth(1.0f); if(index == selected_item) { item.selection_changed(true); - CGALglcolor(item.color().lighter(120)); } else { item.selection_changed(false); - CGALglcolor(item.color()); } if(viewer) item.draw_edges(viewer); @@ -349,7 +363,7 @@ glDepthFunc(GL_LEQUAL); } item.contextual_changed(); if(with_names) { - ::glPopName(); + viewer->glPopName(); } } @@ -358,18 +372,17 @@ glDepthFunc(GL_LEQUAL); for(int index = 0; index < m_entries.size(); ++index) { if(with_names) { - ::glPushName(index); + viewer->glPushName(index); } Scene_item& item = *m_entries[index]; if(item.visible()) { if(item.renderingMode() == Points || item.renderingMode() == PointsPlusNormals) { - ::glDisable(GL_LIGHTING); - ::glPolygonMode(GL_FRONT_AND_BACK,GL_POINT); - ::glPointSize(2.f); - ::glLineWidth(1.0f); - CGALglcolor(item.color()); + viewer->glDisable(GL_LIGHTING); + viewer->glPolygonMode(GL_FRONT_AND_BACK,GL_POINT); + viewer->glPointSize(2.f); + viewer->glLineWidth(1.0f); if(viewer) item.draw_points(viewer); @@ -379,13 +392,50 @@ glDepthFunc(GL_LEQUAL); } item.contextual_changed(); if(with_names) { - ::glPopName(); + viewer->glPopName(); } } glDepthFunc(GL_LESS); + // Splatting + if(!with_names && ms_splatting->isSupported()) + { + ms_splatting->beginVisibilityPass(); + for(int index = 0; index < m_entries.size(); ++index) + { + Scene_item& item = *m_entries[index]; + if(item.visible() && item.renderingMode() == Splatting) + { + + if(viewer) + { + item.draw_splats(viewer); + } + else + item.draw_splats(); + } + + } + ms_splatting->beginAttributePass(); + for(int index = 0; index < m_entries.size(); ++index) + { Scene_item& item = *m_entries[index]; + if(item.visible() && item.renderingMode() == Splatting) + { + viewer->glColor4d(item.color().redF(), item.color().greenF(), item.color().blueF(), item.color().alphaF()); + if(viewer) + item.draw_splats(viewer); + else + item.draw_splats(); + } + } + ms_splatting->finalize(); + + } } +// workaround for Qt-4.2 (see above) +#undef lighter + int Scene::rowCount(const QModelIndex & parent) const { @@ -529,13 +579,11 @@ Scene::setData(const QModelIndex &index, { case NameColumn: item->setName(value.toString()); - item->changed(); Q_EMIT dataChanged(index, index); return true; break; case ColorColumn: item->setColor(value.value()); - item->changed(); Q_EMIT dataChanged(index, index); return true; break; @@ -543,12 +591,13 @@ Scene::setData(const QModelIndex &index, { RenderingMode rendering_mode = static_cast(value.toInt()); // Find next supported rendering mode - while ( ! item->supportsRenderingMode(rendering_mode) ) + while ( ! item->supportsRenderingMode(rendering_mode) + // || (rendering_mode==Splatting && !Scene::splatting()->isSupported()) + ) { rendering_mode = static_cast( (rendering_mode+1) % NumberOfRenderingMode ); } item->setRenderingMode(rendering_mode); - item->changed(); Q_EMIT dataChanged(index, index); return true; break; @@ -603,14 +652,12 @@ void Scene::itemChanged(Item_id i) if(i < 0 || i >= m_entries.size()) return; - m_entries[i]->changed(); Q_EMIT dataChanged(this->createIndex(i, 0), this->createIndex(i, LastColumn)); } -void Scene::itemChanged(Scene_item* item) +void Scene::itemChanged(Scene_item* /* item */) { - item->changed(); Q_EMIT dataChanged(this->createIndex(0, 0), this->createIndex(m_entries.size() - 1, LastColumn)); } diff --git a/Polyhedron/demo/Polyhedron/Scene.h b/Polyhedron/demo/Polyhedron/Scene.h index a8990104a01..459d9867d3b 100644 --- a/Polyhedron/demo/Polyhedron/Scene.h +++ b/Polyhedron/demo/Polyhedron/Scene.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -21,6 +22,7 @@ class QEvent; class QMouseEvent; +namespace GlSplat { class SplatRenderer; } class Viewer_interface; @@ -160,6 +162,7 @@ Q_SIGNALS: private Q_SLOTS: void setSelectionRay(double, double, double, double, double, double); + void callDraw(){ QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); viewer->update();} private: void draw_aux(bool with_names, Viewer_interface*); @@ -169,6 +172,11 @@ private: QList selected_items_list; int item_A; int item_B; + static GlSplat::SplatRenderer* ms_splatting; + static int ms_splattingCounter; +public: + static GlSplat::SplatRenderer* splatting(); + }; // end class Scene class SCENE_EXPORT SceneDelegate : public QItemDelegate diff --git a/Polyhedron/demo/Polyhedron/Scene_c2t3_item.h b/Polyhedron/demo/Polyhedron/Scene_c2t3_item.h index 4c854075950..724867e4a5b 100644 --- a/Polyhedron/demo/Polyhedron/Scene_c2t3_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_c2t3_item.h @@ -72,11 +72,11 @@ public: // Indicate if rendering mode is supported bool supportsRenderingMode(RenderingMode m) const { - return (m != Gouraud && m!=PointsPlusNormals); // CHECK THIS! + return (m != Gouraud && m!=PointsPlusNormals && m!=Splatting); // CHECK THIS! } void draw() const { - ::glBegin(GL_TRIANGLES); + /* ::glBegin(GL_TRIANGLES); for(C2t3::Facet_iterator fit = c2t3().facets_begin(), end = c2t3().facets_end(); @@ -89,7 +89,7 @@ public: const Tr::Geom_traits::Point_3& pc = cell->vertex((index+3)&3)->point(); draw_triangle(pa, pb, pc); } - ::glEnd(); + ::glEnd();*/ } private: diff --git a/Polyhedron/demo/Polyhedron/Scene_combinatorial_map_item.cpp b/Polyhedron/demo/Polyhedron/Scene_combinatorial_map_item.cpp index 475c4670193..74d1e69d0e2 100644 --- a/Polyhedron/demo/Polyhedron/Scene_combinatorial_map_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_combinatorial_map_item.cpp @@ -11,7 +11,7 @@ #include #include -Scene_combinatorial_map_item::Scene_combinatorial_map_item(Scene_interface* scene,void* address):last_known_scene(scene),volume_to_display(0),exportSelectedVolume(NULL),address_of_A(address){m_combinatorial_map=NULL; are_buffers_filled = false;;} +Scene_combinatorial_map_item::Scene_combinatorial_map_item(Scene_interface* scene,void* address):last_known_scene(scene),volume_to_display(0),exportSelectedVolume(NULL),address_of_A(address){m_combinatorial_map=NULL; are_buffers_filled = false; nb_points = 0; nb_lines =0; nb_facets =0;} Scene_combinatorial_map_item::~Scene_combinatorial_map_item(){if (m_combinatorial_map!=NULL) delete m_combinatorial_map;} Scene_combinatorial_map_item* Scene_combinatorial_map_item::clone() const{return NULL;} @@ -52,6 +52,7 @@ void Scene_combinatorial_map_item::set_next_volume(){ ++volume_to_display; volume_to_display=volume_to_display%(combinatorial_map().attributes<3>().size()+1); are_buffers_filled = false; + invalidate_buffers(); Q_EMIT itemChanged(); if (exportSelectedVolume!=NULL && ( volume_to_display==1 || volume_to_display==0 ) ) @@ -350,7 +351,9 @@ void Scene_combinatorial_map_item::initialize_buffers(Viewer_interface *viewer) program->enableAttributeArray("vertex"); program->setAttributeBuffer("vertex",GL_DOUBLE,0,3); buffers[0].release(); - + nb_lines = positions_lines.size(); + positions_lines.resize(0); + std::vector(positions_lines).swap(positions_lines); vaos[0]->release(); program->release(); } @@ -367,6 +370,9 @@ void Scene_combinatorial_map_item::initialize_buffers(Viewer_interface *viewer) program->setAttributeBuffer("vertex",GL_DOUBLE,0,3); buffers[1].release(); vaos[1]->release(); + nb_points = positions_points.size(); + positions_points.resize(0); + std::vector(positions_points).swap(positions_points); program->release(); } //vao for the facets @@ -384,11 +390,15 @@ void Scene_combinatorial_map_item::initialize_buffers(Viewer_interface *viewer) buffers[3].bind(); buffers[3].allocate(normals.data(), - static_cast(positions_facets.size()*sizeof(double))); + static_cast(normals.size()*sizeof(double))); program->enableAttributeArray("normals"); program->setAttributeBuffer("normals",GL_DOUBLE,0,3); buffers[3].release(); - + nb_facets = positions_facets.size(); + positions_facets.resize(0); + std::vector(positions_facets).swap(positions_facets); + normals.resize(0); + std::vector(normals).swap(normals); vaos[2]->release(); program->release(); } @@ -469,7 +479,7 @@ void Scene_combinatorial_map_item::draw(Viewer_interface* viewer) const attrib_buffers(viewer,PROGRAM_WITH_LIGHT); program->bind(); program->setAttributeValue("colors", this->color()); - viewer->glDrawArrays(GL_TRIANGLES, 0, static_cast(positions_facets.size()/3)); + viewer->glDrawArrays(GL_TRIANGLES, 0, static_cast(nb_facets/3)); vaos[2]->release(); program->release(); @@ -486,7 +496,7 @@ void Scene_combinatorial_map_item::draw(Viewer_interface* viewer) const attrib_buffers(viewer,PROGRAM_WITHOUT_LIGHT); program->bind(); program->setAttributeValue("colors", this->color()); - viewer->glDrawArrays(GL_LINES, 0, static_cast(positions_lines.size()/3)); + viewer->glDrawArrays(GL_LINES, 0, static_cast(nb_lines/3)); vaos[0]->release(); program->release(); @@ -503,7 +513,7 @@ void Scene_combinatorial_map_item::draw(Viewer_interface* viewer) const attrib_buffers(viewer,PROGRAM_WITHOUT_LIGHT); program->bind(); program->setAttributeValue("colors", this->color()); - viewer->glDrawArrays(GL_POINTS, 0, static_cast(positions_points.size()/3)); + viewer->glDrawArrays(GL_POINTS, 0, static_cast(nb_points/3)); vaos[1]->release(); program->release(); diff --git a/Polyhedron/demo/Polyhedron/Scene_combinatorial_map_item.h b/Polyhedron/demo/Polyhedron/Scene_combinatorial_map_item.h index 7deadd70c06..1798d62940e 100644 --- a/Polyhedron/demo/Polyhedron/Scene_combinatorial_map_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_combinatorial_map_item.h @@ -39,7 +39,7 @@ public: QString toolTip() const; // Indicate if rendering mode is supported - virtual bool supportsRenderingMode(RenderingMode m) const { return (m != Gouraud && m!=PointsPlusNormals); } // CHECK THIS! + virtual bool supportsRenderingMode(RenderingMode m) const { return (m != Gouraud && m!=PointsPlusNormals && m!=Splatting); } // CHECK THIS! //Event handling virtual bool keyPressEvent(QKeyEvent*); //drawing of the scene @@ -77,6 +77,9 @@ private: mutable std::vector positions_points; mutable std::vector positions_facets; mutable std::vector normals; + mutable std::size_t nb_lines; + mutable std::size_t nb_points; + mutable std::size_t nb_facets; mutable QOpenGLShaderProgram *program; diff --git a/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.cpp index 78f51d3a37b..5738801b00e 100644 --- a/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.cpp @@ -18,12 +18,17 @@ Scene_edit_polyhedron_item::Scene_edit_polyhedron_item own_poly_item(true), k_ring_selector(poly_item, mw, Scene_polyhedron_item_k_ring_selection::Active_handle::VERTEX, true) { + nb_ROI = 0; + nb_sphere = 0; + nb_control = 0; + nb_axis = 0; + nb_bbox = 0; mw->installEventFilter(this); // bind vertex picking connect(&k_ring_selector, SIGNAL(selected(const std::set&)), this, SLOT(selected(const std::set&))); - poly_item->set_color_vector_read_only(true); // to prevent recomputation of color vector in changed() + poly_item->set_color_vector_read_only(true); // to prevent recomputation of color vector in invalidate_buffers() poly_item->update_vertex_indices(); deform_mesh = new Deform_mesh(*(poly_item->polyhedron()), @@ -92,8 +97,7 @@ Scene_edit_polyhedron_item::Scene_edit_polyhedron_item //the spheres : create_Sphere(length_of_axis/15.0); - pos_frame_plane.resize(0); - changed(); + invalidate_buffers(); } Scene_edit_polyhedron_item::~Scene_edit_polyhedron_item() @@ -151,10 +155,10 @@ void Scene_edit_polyhedron_item::initialize_buffers(Viewer_interface *viewer =0) program->setAttributeBuffer("colors",GL_DOUBLE,0,3); buffers[3].release(); vaos[1]->release(); + program->release(); } - //vao for the edges { program = getShaderProgram(PROGRAM_WITHOUT_LIGHT, viewer); @@ -209,6 +213,11 @@ void Scene_edit_polyhedron_item::initialize_buffers(Viewer_interface *viewer =0) viewer->glVertexAttribDivisor(program->attributeLocation("colors"), 1); } vaos[3]->release(); + ROI_color.resize(0); + std::vector(ROI_color).swap(ROI_color); + nb_ROI = ROI_points.size(); + ROI_points.resize(0); + std::vector(ROI_points).swap(ROI_points); } //vao for the BBOX { @@ -228,6 +237,11 @@ void Scene_edit_polyhedron_item::initialize_buffers(Viewer_interface *viewer =0) bbox_program.setAttributeBuffer("colors",GL_DOUBLE,0,3); buffers[10].release(); vaos[4]->release(); + nb_bbox = pos_bbox.size(); + pos_bbox.resize(0); + std::vector(pos_bbox).swap(pos_bbox); + color_bbox.resize(0); + std::vector(color_bbox).swap(color_bbox); bbox_program.release(); } //vao for the control points @@ -290,6 +304,16 @@ void Scene_edit_polyhedron_item::initialize_buffers(Viewer_interface *viewer =0) viewer->glVertexAttribDivisor(program->attributeLocation("colors"), 1); } vaos[6]->release(); + nb_sphere = pos_sphere.size(); + pos_sphere.resize(0); + std::vector(pos_sphere).swap(pos_sphere); + normals_sphere.resize(0); + std::vector(normals_sphere).swap(normals_sphere); + control_color.resize(0); + std::vector(control_color).swap(control_color); + nb_control = control_points.size(); + control_points.resize(0); + std::vector(control_points).swap(control_points); } //vao for the axis { @@ -311,6 +335,11 @@ void Scene_edit_polyhedron_item::initialize_buffers(Viewer_interface *viewer =0) buffers[18].release(); vaos[7]->release(); program->release(); + nb_axis = pos_axis.size(); + pos_axis.resize(0); + std::vector(pos_axis).swap(pos_axis); + color_lines.resize(0); + std::vector(color_lines).swap(color_lines); } //vao for the frame plane { @@ -546,6 +575,7 @@ void Scene_edit_polyhedron_item::timerEvent(QTimerEvent* /*event*/) { // just handle deformation - paint like selection is handled in eventFilter() if(state.ctrl_pressing && (state.left_button_pressing || state.right_button_pressing)) { if(!ui_widget->ActivatePivotingCheckBox->isChecked()) { + invalidate_buffers(); deform(); } else { @@ -694,7 +724,7 @@ void Scene_edit_polyhedron_item::draw_ROI_and_control_vertices(Viewer_interface* program = getShaderProgram(PROGRAM_WITHOUT_LIGHT); attrib_buffers(viewer,PROGRAM_WITHOUT_LIGHT); program->bind(); - viewer->glDrawArrays(GL_POINTS, 0, static_cast(ROI_points.size()/3)); + viewer->glDrawArrays(GL_POINTS, 0, static_cast(nb_ROI/3)); program->release(); vaos[1]->release(); } @@ -704,8 +734,8 @@ void Scene_edit_polyhedron_item::draw_ROI_and_control_vertices(Viewer_interface* attrib_buffers(viewer,PROGRAM_INSTANCED); program->bind(); viewer->glDrawArraysInstanced(GL_TRIANGLES, 0, - static_cast(pos_sphere.size()/3), - static_cast(ROI_points.size()/3)); + static_cast(nb_sphere/3), + static_cast(nb_ROI/3)); program->release(); vaos[3]->release(); } @@ -716,7 +746,7 @@ void Scene_edit_polyhedron_item::draw_ROI_and_control_vertices(Viewer_interface* program = getShaderProgram(PROGRAM_WITHOUT_LIGHT); attrib_buffers(viewer,PROGRAM_WITHOUT_LIGHT); program->bind(); - viewer->glDrawArrays(GL_POINTS, 0, static_cast(control_points.size()/3)); + viewer->glDrawArrays(GL_POINTS, 0, static_cast(nb_control/3)); program->release(); vaos[5]->release(); } @@ -726,8 +756,8 @@ void Scene_edit_polyhedron_item::draw_ROI_and_control_vertices(Viewer_interface* attrib_buffers(viewer,PROGRAM_INSTANCED); program->bind(); viewer->glDrawArraysInstanced(GL_TRIANGLES, 0, - static_cast(pos_sphere.size()/3), - static_cast(control_points.size()/3)); + static_cast(nb_sphere/3), + static_cast(nb_control/3)); program->release(); vaos[6]->release(); } @@ -748,7 +778,7 @@ void Scene_edit_polyhedron_item::draw_ROI_and_control_vertices(Viewer_interface* attrib_buffers(viewer, PROGRAM_WITHOUT_LIGHT); program->bind(); program->setUniformValue("f_matrix", f_mat); - viewer->glDrawArrays(GL_LINES, 0, static_cast(pos_axis.size()/3)); + viewer->glDrawArrays(GL_LINES, 0, static_cast(nb_axis/3)); program->release(); vaos[7]->release(); @@ -787,7 +817,7 @@ void Scene_edit_polyhedron_item::draw_ROI_and_control_vertices(Viewer_interface* bbox_program.setUniformValue("translation", vec); bbox_program.setUniformValue("translation_2", vec2); bbox_program.setUniformValue("mvp_matrix", mvp_mat); - viewer->glDrawArrays(GL_LINES, 0, static_cast(pos_bbox.size()/3)); + viewer->glDrawArrays(GL_LINES, 0, static_cast(nb_bbox/3)); bbox_program.release(); vaos[4]->release(); } @@ -832,7 +862,7 @@ void Scene_edit_polyhedron_item::compute_bbox(const Scene_interface::Bbox& bb){ } -void Scene_edit_polyhedron_item::changed() +void Scene_edit_polyhedron_item::invalidate_buffers() { compute_normals_and_vertices(); update_normals(); diff --git a/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.h b/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.h index f6ea3361257..737477ca44d 100644 --- a/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_edit_polyhedron_item.h @@ -248,7 +248,7 @@ protected: public Q_SLOTS: - void changed(); + void invalidate_buffers(); void selected(const std::set& m) { bool any_changes = false; @@ -266,7 +266,7 @@ public Q_SLOTS: } any_changes |= changed; } - if(any_changes) { Q_EMIT itemChanged(); } + if(any_changes) { invalidate_buffers(); Q_EMIT itemChanged(); } } void select(double orig_x, @@ -284,23 +284,30 @@ private: Ui::DeformMesh* ui_widget; Scene_polyhedron_item* poly_item; // For drawing - std::vector positions; - std::vector tris; - std::vector edges; - std::vector color_lines; - std::vector color_bbox; - std::vector ROI_points; - std::vector control_points; - std::vector ROI_color; - std::vector control_color; - std::vector normals; - std::vector pos_bbox; - std::vector pos_axis; - std::vector pos_sphere; - std::vector normals_sphere; + mutable std::vector positions; + mutable std::vector tris; + mutable std::vector edges; + mutable std::vector color_lines; + mutable std::vector color_bbox; + mutable std::vector ROI_points; + mutable std::vector control_points; + mutable std::vector ROI_color; + mutable std::vector control_color; + mutable std::vector normals; + mutable std::vector pos_bbox; + mutable std::vector pos_axis; + mutable std::vector pos_sphere; + mutable std::vector normals_sphere; mutable std::vector pos_frame_plane; mutable QOpenGLShaderProgram *program; mutable QOpenGLShaderProgram bbox_program; + mutable std::size_t nb_ROI; + mutable std::size_t nb_sphere; + mutable std::size_t nb_control; + mutable std::size_t nb_axis; + mutable std::size_t nb_bbox; + + mutable QOpenGLBuffer *in_bu; using Scene_item::initialize_buffers; @@ -407,6 +414,7 @@ public: active_group = --ctrl_vertex_frame_map.end(); + invalidate_buffers(); Q_EMIT itemChanged(); print_message("A new empty group of control vertices is created."); @@ -609,7 +617,7 @@ public: (vertices(*polyhedron()).first, vertices(*polyhedron()).second, polyhedron()->size_of_vertices(), Is_selected(deform_mesh), visitor); - if(visitor.any_inserted) { Q_EMIT itemChanged(); } + if(visitor.any_inserted) { invalidate_buffers(); Q_EMIT itemChanged(); } return visitor.minimum_visitor.minimum; } protected: diff --git a/Polyhedron/demo/Polyhedron/Scene_implicit_function_item.cpp b/Polyhedron/demo/Polyhedron/Scene_implicit_function_item.cpp index bc7b8d2f7c2..640eb2848e8 100644 --- a/Polyhedron/demo/Polyhedron/Scene_implicit_function_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_implicit_function_item.cpp @@ -367,7 +367,7 @@ Scene_implicit_function_item(Implicit_function_interface* f) frame_->setOrientation(1., 0, 0, 0); connect(frame_, SIGNAL(modified()), this, SLOT(plane_was_moved())); - changed(); + invalidate_buffers(); } @@ -457,6 +457,7 @@ Scene_implicit_function_item::supportsRenderingMode(RenderingMode m) const { switch ( m ) { + case Splatting: case Gouraud: return false; @@ -505,7 +506,7 @@ compute_function_grid() const typedef K::Point_3 Point_3; // Get transformation - const ::GLdouble* m = frame_->matrix(); + const GLdouble* m = frame_->matrix(); // OpenGL matrices are row-major matrices Aff_transformation t (m[0], m[4], m[8], m[12], @@ -536,7 +537,7 @@ compute_function_grid() const } // Update - const_cast(this)->changed(); + const_cast(this)->invalidate_buffers(); } @@ -574,9 +575,9 @@ compute_min_max() } void -Scene_implicit_function_item::changed() +Scene_implicit_function_item::invalidate_buffers() { - Scene_item::changed(); + Scene_item::invalidate_buffers(); compute_vertices_and_texmap(); are_buffers_filled = false; } diff --git a/Polyhedron/demo/Polyhedron/Scene_implicit_function_item.h b/Polyhedron/demo/Polyhedron/Scene_implicit_function_item.h index e99113f46c0..8424c37e831 100644 --- a/Polyhedron/demo/Polyhedron/Scene_implicit_function_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_implicit_function_item.h @@ -70,7 +70,7 @@ public: virtual QString toolTip() const; virtual void contextual_changed(); - virtual void changed(); + virtual void invalidate_buffers(); public Q_SLOTS: void plane_was_moved() { need_update_ = true; } void compute_function_grid() const; diff --git a/Polyhedron/demo/Polyhedron/Scene_item.cpp b/Polyhedron/demo/Polyhedron/Scene_item.cpp index 7b139864a7f..7dc5e3a4555 100644 --- a/Polyhedron/demo/Polyhedron/Scene_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_item.cpp @@ -39,6 +39,8 @@ QString modeName(RenderingMode mode) { return QObject::tr("Gouraud"); case PointsPlusNormals: return QObject::tr("pts+normals"); + case Splatting: + return QObject::tr("splats"); default: Q_ASSERT(false); return QObject::tr("unknown"); @@ -60,6 +62,8 @@ const char* slotName(RenderingMode mode) { return SLOT(setGouraudMode()); case PointsPlusNormals: return SLOT(setPointsPlusNormalsMode()); + case Splatting: + return SLOT(setSplattingMode()); default: Q_ASSERT(false); return ""; @@ -88,25 +92,18 @@ QMenu* Scene_item::contextMenu() { if(!supportsRenderingMode(RenderingMode(mode))) continue; QString mName = modeName(RenderingMode(mode)); - QAction* action = - defaultContextMenu->addAction(tr("Set %1 mode") - .arg(mName), - this, - slotName(RenderingMode(mode))); - QObject::connect(action, SIGNAL(triggered()), - this, SIGNAL(itemChanged())); + defaultContextMenu->addAction(tr("Set %1 mode") + .arg(mName), + this, + slotName(RenderingMode(mode))); } // defaultContextMenu->addAction(modeMenu->menuAction()); return defaultContextMenu; } -void Scene_item::changed() { - // Q_EMIT itemChanged(); -} +void Scene_item::invalidate_buffers() {} -void Scene_item::selection_changed(bool) { - // emit itemChanged(); -} +void Scene_item::selection_changed(bool) {} void Scene_item::select(double /*orig_x*/, diff --git a/Polyhedron/demo/Polyhedron/Scene_item.h b/Polyhedron/demo/Polyhedron/Scene_item.h index 03d5eca708d..83f1b5b641f 100644 --- a/Polyhedron/demo/Polyhedron/Scene_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_item.h @@ -103,6 +103,9 @@ public: // Points OpenGL drawing virtual void draw_points() const { draw(); } virtual void draw_points(Viewer_interface*) const { draw_points(); } + // Splats OpenGL drawing + virtual void draw_splats() const {} + virtual void draw_splats(Viewer_interface*) const {draw_splats();} virtual void selection_changed(bool); // Functions for displaying meta-data of the item @@ -135,17 +138,18 @@ public: public Q_SLOTS: // Call that once you have finished changing something in the item // (either the properties or internal data) - virtual void changed(); + virtual void invalidate_buffers(); virtual void contextual_changed(){} // Setters for the four basic properties - virtual void setColor(QColor c) { color_ = c; changed(); } + virtual void setColor(QColor c) { color_ = c; invalidate_buffers(); } void setRbgColor(int r, int g, int b) { setColor(QColor(r, g, b)); } virtual void setName(QString n) { name_ = n; } virtual void setVisible(bool b) { visible_ = b; } virtual void setRenderingMode(RenderingMode m) { if (supportsRenderingMode(m)) rendering_mode = m; + Q_EMIT renderingModeChanged(); } void setPointsMode() { setRenderingMode(Points); @@ -177,6 +181,10 @@ public Q_SLOTS: setRenderingMode(PointsPlusNormals); } + void setSplattingMode(){ + setRenderingMode(Splatting); + } + virtual void itemAboutToBeDestroyed(Scene_item*); virtual void select(double orig_x, @@ -189,6 +197,7 @@ public Q_SLOTS: Q_SIGNALS: void itemChanged(); void aboutToBeDestroyed(); + void renderingModeChanged(); protected: // The four basic properties diff --git a/Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.cpp index a029dbde921..cee38656a96 100644 --- a/Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.cpp @@ -52,6 +52,9 @@ Scene_nef_polyhedron_item::Scene_nef_polyhedron_item() nef_poly(new Nef_polyhedron) { is_selected = true; + nb_points = 0; + nb_lines = 0; + nb_facets = 0; } Scene_nef_polyhedron_item::Scene_nef_polyhedron_item(Nef_polyhedron* const p) @@ -59,6 +62,9 @@ Scene_nef_polyhedron_item::Scene_nef_polyhedron_item(Nef_polyhedron* const p) nef_poly(p) { is_selected = true; + nb_points = 0; + nb_lines = 0; + nb_facets = 0; } Scene_nef_polyhedron_item::Scene_nef_polyhedron_item(const Nef_polyhedron& p) @@ -66,6 +72,9 @@ Scene_nef_polyhedron_item::Scene_nef_polyhedron_item(const Nef_polyhedron& p) nef_poly(new Nef_polyhedron(p)) { is_selected = true; + nb_points = 0; + nb_lines = 0; + nb_facets = 0; } Scene_nef_polyhedron_item::~Scene_nef_polyhedron_item() @@ -104,6 +113,15 @@ void Scene_nef_polyhedron_item::initialize_buffers(Viewer_interface *viewer) con program->setAttributeBuffer("colors",GL_DOUBLE,0,3); buffers[2].release(); vaos[0]->release(); + nb_facets = positions_facets.size(); + positions_facets.resize(0); + std::vector(positions_facets).swap(positions_facets); + + normals.resize(0); + std::vector(normals).swap(normals); + + color_facets.resize(0); + std::vector(color_facets).swap(color_facets); program->release(); } @@ -129,6 +147,12 @@ void Scene_nef_polyhedron_item::initialize_buffers(Viewer_interface *viewer) con program->setAttributeBuffer("colors",GL_DOUBLE,0,3); buffers[4].release(); + nb_lines = positions_lines.size(); + positions_lines.resize(0); + std::vector(positions_lines).swap(positions_lines); + + color_lines.resize(0); + std::vector(color_lines).swap(color_lines); vaos[1]->release(); program->release(); } @@ -155,6 +179,13 @@ void Scene_nef_polyhedron_item::initialize_buffers(Viewer_interface *viewer) con buffers[6].release(); vaos[2]->release(); + + nb_points = positions_points.size(); + positions_points.resize(0); + std::vector(positions_points).swap(positions_points); + + color_points.resize(0); + std::vector(color_points).swap(color_points); program->release(); } are_buffers_filled = true; @@ -405,7 +436,7 @@ Scene_nef_polyhedron_item::load_from_off(std::istream& in) // Polyhedron poly; // in >> poly; // *nef_poly = Nef_polyhedron(poly); - changed(); + invalidate_buffers(); return (bool) in; } @@ -420,7 +451,7 @@ bool Scene_nef_polyhedron_item::load(std::istream& in) { in >> *nef_poly; - changed(); + invalidate_buffers(); return (bool) in; } @@ -462,7 +493,7 @@ void Scene_nef_polyhedron_item::draw(Viewer_interface* viewer) const program=getShaderProgram(PROGRAM_WITH_LIGHT); attrib_buffers(viewer,PROGRAM_WITH_LIGHT); program->bind(); - viewer->glDrawArrays(GL_TRIANGLES, 0, static_cast(positions_facets.size()/3)); + viewer->glDrawArrays(GL_TRIANGLES, 0, static_cast(nb_facets/3)); vaos[0]->release(); program->release(); GLfloat point_size; @@ -482,7 +513,7 @@ void Scene_nef_polyhedron_item::draw_edges(Viewer_interface* viewer) const program = getShaderProgram(PROGRAM_WITHOUT_LIGHT); attrib_buffers(viewer ,PROGRAM_WITHOUT_LIGHT); program->bind(); - viewer->glDrawArrays(GL_LINES,0,static_cast(positions_lines.size()/3)); + viewer->glDrawArrays(GL_LINES,0,static_cast(nb_lines/3)); vaos[1]->release(); program->release(); if(renderingMode() == PointsPlusNormals) @@ -503,7 +534,7 @@ void Scene_nef_polyhedron_item::draw_points(Viewer_interface* viewer) const program=getShaderProgram(PROGRAM_WITHOUT_LIGHT); attrib_buffers(viewer ,PROGRAM_WITHOUT_LIGHT); program->bind(); - viewer->glDrawArrays(GL_POINTS,0,static_cast(positions_points.size()/3)); + viewer->glDrawArrays(GL_POINTS,0,static_cast(nb_points/3)); vaos[2]->release(); program->release(); @@ -694,17 +725,17 @@ convex_decomposition(std::list< Scene_polyhedron_item*>& convex_parts) from_exact(P, *poly); Scene_polyhedron_item *spoly = new Scene_polyhedron_item(poly); convex_parts.push_back(spoly); - spoly->changed(); + spoly->invalidate_buffers(); } } } void Scene_nef_polyhedron_item:: -changed() +invalidate_buffers() { // init(); - Base::changed(); + Base::invalidate_buffers(); compute_normals_and_vertices(); are_buffers_filled = false; } @@ -715,7 +746,7 @@ Scene_nef_polyhedron_item::selection_changed(bool p_is_selected) if(p_is_selected != is_selected) { is_selected = p_is_selected; - changed(); + invalidate_buffers(); } } diff --git a/Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.h b/Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.h index ef18fd8bb3e..db90bc19d18 100644 --- a/Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.h @@ -26,10 +26,12 @@ public: QFont font() const; QString toolTip() const; - virtual void changed(); + virtual void invalidate_buffers(); virtual void selection_changed(bool); // Indicate if rendering mode is supported - virtual bool supportsRenderingMode(RenderingMode m) const { return m != Gouraud; } // CHECK THIS! + virtual bool supportsRenderingMode(RenderingMode m) const { return m != Gouraud && m!=Splatting; } // CHECK THIS! + // OpenGL drawing in a display list + void direct_draw() const; virtual void draw(Viewer_interface*) const; virtual void draw_edges() const {} @@ -73,13 +75,16 @@ private: Nef_polyhedron* nef_poly; - std::vector positions_lines; - std::vector positions_facets; - std::vector positions_points; - std::vector normals; - std::vector color_lines; - std::vector color_facets; - std::vector color_points; + mutable std::vector positions_lines; + mutable std::vector positions_facets; + mutable std::vector positions_points; + mutable std::vector normals; + mutable std::vector color_lines; + mutable std::vector color_facets; + mutable std::vector color_points; + mutable std::size_t nb_points; + mutable std::size_t nb_lines; + mutable std::size_t nb_facets; mutable QOpenGLShaderProgram *program; diff --git a/Polyhedron/demo/Polyhedron/Scene_plane_item.h b/Polyhedron/demo/Polyhedron/Scene_plane_item.h index 0d2cc19872c..32225356c07 100644 --- a/Polyhedron/demo/Polyhedron/Scene_plane_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_plane_item.h @@ -33,7 +33,7 @@ public: { setNormal(0., 0., 1.); //Generates an integer which will be used as ID for each buffer - changed(); + invalidate_buffers(); } ~Scene_plane_item() { @@ -116,7 +116,7 @@ private: } public Q_SLOTS: - virtual void changed() + virtual void invalidate_buffers() { compute_normals_and_vertices(); are_buffers_filled = false; diff --git a/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp b/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp index 3e81166f818..e583cbb6cf5 100644 --- a/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp @@ -29,6 +29,9 @@ Scene_points_with_normal_item::Scene_points_with_normal_item() { setRenderingMode(Points); is_selected = true; + nb_points = 0; + nb_selected_points = 0; + nb_lines = 0; } // Copy constructor @@ -47,7 +50,10 @@ Scene_points_with_normal_item::Scene_points_with_normal_item(const Scene_points_ setRenderingMode(Points); is_selected = true; } - changed(); + nb_points = 0; + nb_selected_points = 0; + nb_lines = 0; + invalidate_buffers(); } // Converts polyhedron to point set @@ -71,7 +77,10 @@ Scene_points_with_normal_item::Scene_points_with_normal_item(const Polyhedron& i setRenderingMode(PointsPlusNormals); is_selected = true; - changed(); + nb_points = 0; + nb_selected_points = 0; + nb_lines = 0; + invalidate_buffers(); } Scene_points_with_normal_item::~Scene_points_with_normal_item() @@ -84,6 +93,7 @@ Scene_points_with_normal_item::~Scene_points_with_normal_item() void Scene_points_with_normal_item::initialize_buffers(Viewer_interface *viewer) const { + compute_normals_and_vertices(); //vao for the edges { program = getShaderProgram(PROGRAM_WITHOUT_LIGHT, viewer); @@ -98,6 +108,9 @@ void Scene_points_with_normal_item::initialize_buffers(Viewer_interface *viewer) buffers[0].release(); vaos[0]->release(); + nb_lines = positions_lines.size(); + positions_lines.resize(0); + std::vector(positions_lines).swap(positions_lines); program->release(); } //vao for the points @@ -113,6 +126,9 @@ void Scene_points_with_normal_item::initialize_buffers(Viewer_interface *viewer) program->setAttributeBuffer("vertex",GL_DOUBLE,0,3); buffers[1].release(); vaos[1]->release(); + nb_points = positions_points.size(); + positions_points.resize(0); + std::vector(positions_points).swap(positions_points); program->release(); } //vao for the selected points @@ -129,13 +145,15 @@ void Scene_points_with_normal_item::initialize_buffers(Viewer_interface *viewer) buffers[2].release(); vaos[2]->release(); + nb_selected_points = positions_selected_points.size(); + positions_selected_points.resize(0); + std::vector(positions_selected_points).swap(positions_selected_points); program->release(); } are_buffers_filled = true; - - } -void Scene_points_with_normal_item::compute_normals_and_vertices(void) + +void Scene_points_with_normal_item::compute_normals_and_vertices() const { positions_points.resize(0); positions_lines.resize(0); @@ -167,7 +185,6 @@ void Scene_points_with_normal_item::compute_normals_and_vertices(void) // Draw *selected* points if (m_points->nb_selected_points() > 0) { - ::glPointSize(4.f); // selected => bigger for (Point_set_3::const_iterator it = m_points->begin(); it != m_points->end(); it++) { const UI_point& p = *it; @@ -262,6 +279,7 @@ void Scene_points_with_normal_item::deleteSelection() std::cerr << "done: " << task_timer.time() << " seconds, " << (memory>>20) << " Mb allocated" << std::endl; + invalidate_buffers(); Q_EMIT itemChanged(); } @@ -269,6 +287,7 @@ void Scene_points_with_normal_item::deleteSelection() void Scene_points_with_normal_item::invertSelection() { m_points->invert_selection(); + invalidate_buffers(); Q_EMIT itemChanged(); } @@ -276,6 +295,7 @@ void Scene_points_with_normal_item::invertSelection() void Scene_points_with_normal_item::selectAll() { m_points->select(m_points->begin(), m_points->end(), true); + invalidate_buffers(); Q_EMIT itemChanged(); } // Reset selection mark @@ -283,6 +303,7 @@ void Scene_points_with_normal_item::resetSelection() { // Un-select all points m_points->select(m_points->begin(), m_points->end(), false); + invalidate_buffers(); Q_EMIT itemChanged(); } //Select duplicated points @@ -292,6 +313,7 @@ void Scene_points_with_normal_item::selectDuplicates() for (Point_set::Point_iterator ptit=m_points->begin(); ptit!=m_points->end();++ptit ) if ( !unique_points.insert(*ptit).second ) m_points->select(&(*ptit)); + invalidate_buffers(); Q_EMIT itemChanged(); } @@ -306,7 +328,7 @@ bool Scene_points_with_normal_item::read_off_point_set(std::istream& stream) std::back_inserter(*m_points), CGAL::make_normal_of_point_with_normal_pmap(Point_set::value_type())) && !isEmpty(); - changed(); + invalidate_buffers(); return ok; } @@ -346,7 +368,7 @@ bool Scene_points_with_normal_item::read_xyz_point_set(std::istream& stream) } } } - changed(); + invalidate_buffers(); return ok; } @@ -376,8 +398,27 @@ Scene_points_with_normal_item::toolTip() const bool Scene_points_with_normal_item::supportsRenderingMode(RenderingMode m) const { - return m==Points || - ( has_normals() && m==PointsPlusNormals ); + return m==Points || + ( has_normals() && + ( m==PointsPlusNormals || m==Splatting ) ); +} + +void Scene_points_with_normal_item::draw_splats(Viewer_interface* viewer) const +{ + // TODO add support for selection + viewer->glBegin(GL_POINTS); + for ( Point_set_3::const_iterator it = m_points->begin(); it != m_points->end(); it++) + { + const UI_point& p = *it; + viewer->glNormal3dv(&p.normal().x()); + viewer->glMultiTexCoord1d(GL_TEXTURE2, p.radius()); + viewer->glVertex3dv(&p.x()); + + } + viewer->glEnd(); + + + } void Scene_points_with_normal_item::draw_edges(Viewer_interface* viewer) const @@ -389,7 +430,7 @@ void Scene_points_with_normal_item::draw_edges(Viewer_interface* viewer) const attrib_buffers(viewer,PROGRAM_WITHOUT_LIGHT); program->bind(); program->setAttributeValue("colors", this->color()); - viewer->glDrawArrays(GL_LINES, 0, static_cast(positions_lines.size()/3)); + viewer->glDrawArrays(GL_LINES, 0, static_cast(nb_lines/3)); vaos[0]->release(); program->release(); } @@ -403,7 +444,7 @@ void Scene_points_with_normal_item::draw_points(Viewer_interface* viewer) const attrib_buffers(viewer,PROGRAM_WITHOUT_LIGHT); program->bind(); program->setAttributeValue("colors", this->color()); - viewer->glDrawArrays(GL_POINTS, 0, static_cast(positions_points.size()/3)); + viewer->glDrawArrays(GL_POINTS, 0, static_cast(nb_points/3)); vaos[1]->release(); program->release(); GLfloat point_size; @@ -416,7 +457,7 @@ void Scene_points_with_normal_item::draw_points(Viewer_interface* viewer) const program->bind(); program->setAttributeValue("colors", QColor(255,0,0)); viewer->glDrawArrays(GL_POINTS, 0, - static_cast(positions_selected_points.size()/3)); + static_cast(nb_selected_points/3)); vaos[2]->release(); program->release(); viewer->glPointSize(point_size); @@ -519,6 +560,10 @@ QMenu* Scene_points_with_normal_item::contextMenu() void Scene_points_with_normal_item::setRenderingMode(RenderingMode m) { Scene_item::setRenderingMode(m); + if (rendering_mode==Splatting && (!m_points->are_radii_uptodate())) + { + computes_local_spacing(6); // default value = small + } } bool Scene_points_with_normal_item::has_normals() const { return m_has_normals; } @@ -532,9 +577,8 @@ void Scene_points_with_normal_item::set_has_normals(bool b) { } } -void Scene_points_with_normal_item::changed() +void Scene_points_with_normal_item::invalidate_buffers() { - compute_normals_and_vertices(); are_buffers_filled = false; } diff --git a/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.h b/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.h index 7cafc153119..4e4f6b82e0e 100644 --- a/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.h @@ -44,7 +44,7 @@ public: // Function for displaying meta-data of the item virtual QString toolTip() const; - virtual void changed(); + virtual void invalidate_buffers(); // Indicate if rendering mode is supported virtual bool supportsRenderingMode(RenderingMode m) const; @@ -52,6 +52,8 @@ public: virtual void draw_edges(Viewer_interface* viewer) const; virtual void draw_points(Viewer_interface*) const; + virtual void draw_splats(Viewer_interface*) const; + // Gets wrapped point set Point_set* point_set(); const Point_set* point_set() const; @@ -90,17 +92,20 @@ private: QAction* actionSelectDuplicatedPoints; - std::vector positions_lines; - std::vector positions_points; - std::vector positions_selected_points; - std::vector normals; + mutable std::vector positions_lines; + mutable std::vector positions_points; + mutable std::vector positions_selected_points; + mutable std::vector normals; + mutable std::size_t nb_points; + mutable std::size_t nb_selected_points; + mutable std::size_t nb_lines; mutable QOpenGLShaderProgram *program; using Scene_item::initialize_buffers; void initialize_buffers(Viewer_interface *viewer) const; - void compute_normals_and_vertices(void); + void compute_normals_and_vertices() const; }; // end class Scene_points_with_normal_item diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp index 9240eca0aeb..1b01c467972 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp @@ -103,6 +103,12 @@ Scene_polygon_soup_item::initialize_buffers(Viewer_interface* viewer) const program->release(); vaos[0]->release(); + nb_polys = positions_poly.size(); + positions_poly.resize(0); + std::vector(positions_poly).swap(positions_poly); + + normals.resize(0); + std::vector(normals).swap(normals); } //vao containing the data for the edges @@ -117,11 +123,29 @@ Scene_polygon_soup_item::initialize_buffers(Viewer_interface* viewer) const program->enableAttributeArray("vertex"); program->setAttributeBuffer("vertex",GL_FLOAT,0,4); buffers[3].release(); - program->release(); - vaos[1]->release(); + nb_lines = positions_lines.size(); + positions_lines.resize(0); + std::vector(positions_lines).swap(positions_lines); + + } + //vao containing the data for the non manifold edges + { + program = getShaderProgram(PROGRAM_WITHOUT_LIGHT, viewer); + program->bind(); + vaos[2]->bind(); + buffers[4].bind(); + buffers[4].allocate(positions_nm_lines.data(), + static_cast(positions_nm_lines.size()*sizeof(float))); + program->enableAttributeArray("vertex"); + program->setAttributeBuffer("vertex",GL_FLOAT,0,4); + buffers[4].release(); + vaos[2]->release(); + nb_nm_edges = positions_nm_lines.size(); + positions_nm_lines.resize(0); + std::vector (positions_nm_lines).swap(positions_nm_lines); } are_buffers_filled = true; } @@ -146,7 +170,7 @@ TDS, Itag> CDTbase; typedef CGAL::Constrained_triangulation_plus_2 CDT; void -Scene_polygon_soup_item::triangulate_polygon(Polygons_iterator pit) +Scene_polygon_soup_item::triangulate_polygon(Polygons_iterator pit) const { //Computes the normal of the facet const Point_3& pa = soup->points[pit->at(0)]; @@ -203,7 +227,6 @@ Scene_polygon_soup_item::triangulate_polygon(Polygons_iterator pit) } } - //iterates on the internal faces to add the vertices to the positions //and the normals to the appropriate vectors int count =0; @@ -256,13 +279,14 @@ Scene_polygon_soup_item::triangulate_polygon(Polygons_iterator pit) } } void -Scene_polygon_soup_item::compute_normals_and_vertices(){ +Scene_polygon_soup_item::compute_normals_and_vertices() const{ //get the vertices and normals - typedef Polygon_soup::Polygons::size_type size_type; positions_poly.resize(0); positions_lines.resize(0); normals.resize(0); + positions_nm_lines.resize(0); + soup->fill_edges(); for(Polygons_iterator it = soup->polygons.begin(); it != soup->polygons.end(); ++it) { @@ -321,14 +345,35 @@ Scene_polygon_soup_item::compute_normals_and_vertices(){ } } + //Non manifold edges + BOOST_FOREACH(const Polygon_soup::Edge& edge, + soup->non_manifold_edges) + { + + const Point_3& a = soup->points[edge[0]]; + const Point_3& b = soup->points[edge[1]]; + positions_nm_lines.push_back(a.x()); + positions_nm_lines.push_back(a.y()); + positions_nm_lines.push_back(a.z()); + positions_nm_lines.push_back(1.0); + + positions_nm_lines.push_back(b.x()); + positions_nm_lines.push_back(b.y()); + positions_nm_lines.push_back(b.z()); + positions_nm_lines.push_back(1.0); + } + } Scene_polygon_soup_item::Scene_polygon_soup_item() - : Scene_item(4,2), + : Scene_item(5,3), soup(0), oriented(false) { + nb_polys = 0; + nb_lines = 0; + nb_nm_edges = 0; } Scene_polygon_soup_item::~Scene_polygon_soup_item() @@ -353,7 +398,7 @@ Scene_polygon_soup_item::load(std::istream& in) else soup->clear(); bool result = CGAL::read_OFF(in, soup->points, soup->polygons); - Q_EMIT changed(); + Q_EMIT invalidate_buffers(); return result; } @@ -366,7 +411,7 @@ void Scene_polygon_soup_item::init_polygon_soup(std::size_t nb_pts, std::size_t oriented = false; } -void Scene_polygon_soup_item::finalize_polygon_soup(){ soup->fill_edges(); } + #include #include @@ -382,7 +427,7 @@ void Scene_polygon_soup_item::load(Scene_polyhedron_item* poly_item) { CGAL::generic_print_polyhedron(std::cerr, *poly_item->polyhedron(), writer); - Q_EMIT changed(); + Q_EMIT invalidate_buffers(); } void @@ -390,7 +435,6 @@ Scene_polygon_soup_item::setDisplayNonManifoldEdges(const bool b) { soup->display_non_manifold_edges = b; - changed(); } bool @@ -406,8 +450,7 @@ void Scene_polygon_soup_item::shuffle_orientations() { if(std::rand() % 2 == 0) soup->inverse_orientation(i); } - soup->fill_edges(); - changed(); + invalidate_buffers(); } void Scene_polygon_soup_item::inside_out() @@ -417,8 +460,7 @@ void Scene_polygon_soup_item::inside_out() { soup->inverse_orientation(i); } - soup->fill_edges(); - changed(); + invalidate_buffers(); } bool @@ -523,7 +565,8 @@ Scene_polygon_soup_item::toolTip() const void Scene_polygon_soup_item::draw(Viewer_interface* viewer) const { if(!are_buffers_filled) - { + { + compute_normals_and_vertices(); initialize_buffers(viewer); } if(soup == 0) return; @@ -540,19 +583,19 @@ Scene_polygon_soup_item::draw(Viewer_interface* viewer) const { program->setAttributeValue("colors", v_colors); //draw the polygons // the third argument is the number of vec4 that will be entered - viewer->glDrawArrays(GL_TRIANGLES, 0, static_cast(positions_poly.size()/4)); + viewer->glDrawArrays(GL_TRIANGLES, 0, static_cast(nb_polys/4)); // Clean-up program->release(); vaos[0]->release(); - } void Scene_polygon_soup_item::draw_points(Viewer_interface* viewer) const { if(!are_buffers_filled) { - initialize_buffers(viewer); - } + compute_normals_and_vertices(); + initialize_buffers(viewer); + } if(soup == 0) return; vaos[1]->bind(); attrib_buffers(viewer,PROGRAM_WITHOUT_LIGHT); @@ -561,7 +604,7 @@ Scene_polygon_soup_item::draw_points(Viewer_interface* viewer) const { QColor color = this->color(); program->setAttributeValue("colors", color); //draw the points - viewer->glDrawArrays(GL_POINTS, 0, static_cast(positions_lines.size()/4)); + viewer->glDrawArrays(GL_POINTS, 0, static_cast(nb_lines/4)); // Clean-up program->release(); vaos[1]->release(); @@ -571,10 +614,10 @@ void Scene_polygon_soup_item::draw_edges(Viewer_interface* viewer) const { if(!are_buffers_filled) { + compute_normals_and_vertices(); initialize_buffers(viewer); } if(soup == 0) return; - vaos[1]->bind(); attrib_buffers(viewer,PROGRAM_WITHOUT_LIGHT); program = getShaderProgram(PROGRAM_WITHOUT_LIGHT); @@ -583,10 +626,26 @@ Scene_polygon_soup_item::draw_edges(Viewer_interface* viewer) const { program->setAttributeValue("colors", color); //draw the edges - viewer->glDrawArrays(GL_LINES, 0,static_cast( positions_lines.size()/4)); + viewer->glDrawArrays(GL_LINES, 0,static_cast( nb_lines/4)); // Clean-up program->release(); vaos[1]->release(); + if(displayNonManifoldEdges()) + { + vaos[2]->bind(); + attrib_buffers(viewer,PROGRAM_WITHOUT_LIGHT); + program = getShaderProgram(PROGRAM_WITHOUT_LIGHT); + program->bind(); + QColor c = QColor(255,0,0,255); + + program->setAttributeValue("colors", c); + //draw the edges + viewer->glDrawArrays(GL_LINES, 0,static_cast( nb_nm_edges/4)); + // Clean-up + program->release(); + vaos[2]->release(); + } + } bool @@ -595,9 +654,8 @@ Scene_polygon_soup_item::isEmpty() const { return (soup == 0 || soup->points.empty()); } void -Scene_polygon_soup_item::changed() +Scene_polygon_soup_item::invalidate_buffers() { - compute_normals_and_vertices(); are_buffers_filled = false; } diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h index ce5b20df643..b5e15bdc2a1 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h @@ -15,7 +15,10 @@ struct Polygon_soup { typedef Kernel::Point_3 Point_3; typedef std::vector Points; + //vector containing 3 indices of points in Points typedef std::vector Polygon_3; + //vector containing a pair of indices of points in Points and a set of indices of Polygons + //containing the edge. typedef std::map, std::set > Edges_map; typedef boost::array Edge; typedef std::vector Polygons; @@ -71,9 +74,8 @@ struct Polygon_soup const std::size_t& i0 = polygons[i][j]; const std::size_t& i1 = polygons[i][ j+1 < size ? j+1: 0]; - if( (i0 < i1) && - (edges[std::make_pair(i0, i1)].size() + - edges[std::make_pair(i1, i0)].size() > 2) ) + if(edges[std::make_pair(i0, i1)].size() + + edges[std::make_pair(i1, i0)].size() > 2) { Edge edge; edge[0] = i0; @@ -127,8 +129,10 @@ public: soup->polygons[i].assign(polygons[i].begin(), polygons[i].end()); /// fill non-manifold edges container - soup->fill_edges(); + //soup->fill_edges(); oriented = false; + + Q_EMIT invalidate_buffers(); } bool save(std::ostream& out) const; @@ -136,13 +140,13 @@ public: QString toolTip() const; // Indicate if rendering mode is supported - virtual bool supportsRenderingMode(RenderingMode m) const { return (m!=Gouraud && m!=PointsPlusNormals); } // CHECK THIS! + virtual bool supportsRenderingMode(RenderingMode m) const { return (m!=Gouraud && m!=PointsPlusNormals && m!=Splatting); } // CHECK THIS! // OpenGL drawing in a display list virtual void draw() const {} virtual void draw(Viewer_interface*) const; virtual void draw_points(Viewer_interface*) const; virtual void draw_edges(Viewer_interface* viewer) const; - void changed(); + void invalidate_buffers(); bool isFinite() const { return true; } bool isEmpty() const; Bbox bbox() const; @@ -151,7 +155,6 @@ public: void new_triangle(const std::size_t, const std::size_t, const std::size_t); void init_polygon_soup(std::size_t nb_pts, std::size_t nb_polygons); - void finalize_polygon_soup(); public Q_SLOTS: void shuffle_orientations(); @@ -166,14 +169,17 @@ private: typedef Polygon_soup::Polygons::const_iterator Polygons_iterator; Polygon_soup* soup; bool oriented; - std::vector positions_poly; - std::vector positions_lines; - std::vector normals; - + mutable std::vector positions_poly; + mutable std::vector positions_lines; + mutable std::vector normals; + mutable std::vector positions_nm_lines; + mutable std::size_t nb_nm_edges; + mutable std::size_t nb_polys; + mutable std::size_t nb_lines; using Scene_item::initialize_buffers; void initialize_buffers(Viewer_interface *viewer) const; - void compute_normals_and_vertices(void); - void triangulate_polygon(Polygons_iterator ); + void compute_normals_and_vertices(void) const; + void triangulate_polygon(Polygons_iterator ) const; mutable QOpenGLShaderProgram *program; }; // end class Scene_polygon_soup_item diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp index b7ac84eb6f6..e79dc2b0b3e 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp @@ -88,7 +88,7 @@ typedef CGAL::Constrained_triangulation_plus_2 CDT; //Make sure all the facets are triangles void -Scene_polyhedron_item::is_Triangulated() +Scene_polyhedron_item::is_Triangulated() const { typedef Polyhedron::Halfedge_around_facet_circulator HF_circulator; Facet_iterator f = poly->facets_begin(); @@ -115,7 +115,7 @@ Scene_polyhedron_item::is_Triangulated() } } void -Scene_polyhedron_item::triangulate_facet(Facet_iterator fit) +Scene_polyhedron_item::triangulate_facet(Facet_iterator fit) const { //Computes the normal of the facet Traits::Vector_3 normal = @@ -192,29 +192,38 @@ Scene_polyhedron_item::triangulate_facet(Facet_iterator fit) positions_facets.push_back(ffit->vertex(2)->point().z()); positions_facets.push_back(1.0); - if (cur_shading == Flat || cur_shading == FlatPlusEdges || cur_shading == Gouraud) - { - typedef Kernel::Vector_3 Vector; - Vector n = CGAL::Polygon_mesh_processing::compute_face_normal(fit, *poly); - normals.push_back(n.x()); - normals.push_back(n.y()); - normals.push_back(n.z()); + typedef Kernel::Vector_3 Vector; + Vector n = CGAL::Polygon_mesh_processing::compute_face_normal(fit, *poly); + normals_flat.push_back(n.x()); + normals_flat.push_back(n.y()); + normals_flat.push_back(n.z()); - normals.push_back(n.x()); - normals.push_back(n.y()); - normals.push_back(n.z()); + normals_flat.push_back(n.x()); + normals_flat.push_back(n.y()); + normals_flat.push_back(n.z()); - normals.push_back(n.x()); - normals.push_back(n.y()); - normals.push_back(n.z()); - } + normals_flat.push_back(n.x()); + normals_flat.push_back(n.y()); + normals_flat.push_back(n.z()); + + normals_gouraud.push_back(n.x()); + normals_gouraud.push_back(n.y()); + normals_gouraud.push_back(n.z()); + + normals_gouraud.push_back(n.x()); + normals_gouraud.push_back(n.y()); + normals_gouraud.push_back(n.z()); + + normals_gouraud.push_back(n.x()); + normals_gouraud.push_back(n.y()); + normals_gouraud.push_back(n.z()); } } void -Scene_polyhedron_item::triangulate_facet_color(Facet_iterator fit) +Scene_polyhedron_item::triangulate_facet_color(Facet_iterator fit) const { Traits::Vector_3 normal = CGAL::Polygon_mesh_processing::compute_face_normal(fit, *poly); @@ -312,6 +321,7 @@ Scene_polyhedron_item::initialize_buffers(Viewer_interface* viewer) const { program = getShaderProgram(PROGRAM_WITH_LIGHT, viewer); program->bind(); + //flat vaos[0]->bind(); buffers[0].bind(); buffers[0].allocate(positions_facets.data(), @@ -323,8 +333,8 @@ Scene_polyhedron_item::initialize_buffers(Viewer_interface* viewer) const buffers[1].bind(); - buffers[1].allocate(normals.data(), - static_cast(normals.size()*sizeof(float))); + buffers[1].allocate(normals_flat.data(), + static_cast(normals_flat.size()*sizeof(float))); program->enableAttributeArray("normals"); program->setAttributeBuffer("normals",GL_FLOAT,0,3); buffers[1].release(); @@ -336,6 +346,27 @@ Scene_polyhedron_item::initialize_buffers(Viewer_interface* viewer) const program->setAttributeBuffer("colors",GL_FLOAT,0,3); buffers[2].release(); vaos[0]->release(); + + //gouraud + vaos[4]->bind(); + buffers[0].bind(); + program->enableAttributeArray("vertex"); + program->setAttributeBuffer("vertex",GL_FLOAT,0,4); + buffers[0].release(); + + buffers[10].bind(); + buffers[10].allocate(normals_gouraud.data(), + static_cast(normals_gouraud.size()*sizeof(float))); + program->enableAttributeArray("normals"); + program->setAttributeBuffer("normals",GL_FLOAT,0,3); + buffers[10].release(); + + buffers[2].bind(); + program->enableAttributeArray("colors"); + program->setAttributeBuffer("colors",GL_FLOAT,0,3); + buffers[2].release(); + vaos[4]->release(); + program->release(); } @@ -365,11 +396,12 @@ Scene_polyhedron_item::initialize_buffers(Viewer_interface* viewer) const } //vao containing the data for the selected facets { + program = getShaderProgram(PROGRAM_WITH_LIGHT, viewer); program->bind(); + + //flat vaos[2]->bind(); - - buffers[5].bind(); buffers[5].allocate(positions_facets.data(), static_cast(positions_facets.size()*sizeof(float))); @@ -378,8 +410,8 @@ Scene_polyhedron_item::initialize_buffers(Viewer_interface* viewer) const buffers[5].release(); buffers[6].bind(); - buffers[6].allocate(normals.data(), - static_cast(normals.size()*sizeof(float))); + buffers[6].allocate(normals_flat.data(), + static_cast(normals_flat.size()*sizeof(float))); program->enableAttributeArray("normals"); program->setAttributeBuffer("normals",GL_FLOAT,0,3); buffers[6].release(); @@ -391,9 +423,28 @@ Scene_polyhedron_item::initialize_buffers(Viewer_interface* viewer) const program->enableAttributeArray("colors"); program->setAttributeBuffer("colors",GL_FLOAT,0,3); buffers[7].release(); - program->release(); - vaos[2]->release(); + + //gouraud + vaos[5]->bind(); + buffers[5].bind(); + program->enableAttributeArray("vertex"); + program->setAttributeBuffer("vertex",GL_FLOAT,0,4); + buffers[5].release(); + + buffers[10].bind(); + program->enableAttributeArray("normals"); + program->setAttributeBuffer("normals",GL_FLOAT,0,3); + buffers[10].release(); + + + buffers[7].bind(); + program->enableAttributeArray("colors"); + program->setAttributeBuffer("colors",GL_FLOAT,0,3); + buffers[7].release(); + vaos[5]->release(); + + program->release(); } //vao containing the data for the selected lines { @@ -417,15 +468,36 @@ Scene_polyhedron_item::initialize_buffers(Viewer_interface* viewer) const vaos[3]->release(); } + nb_lines = positions_lines.size(); + positions_lines.resize(0); + std::vector(positions_lines).swap(positions_lines); + nb_facets = positions_facets.size(); + positions_facets.resize(0); + std::vector(positions_facets).swap(positions_facets); + + + color_lines_selected.resize(0); + std::vector(color_lines_selected).swap(color_lines_selected); + color_facets_selected.resize(0); + std::vector(color_facets_selected).swap(color_facets_selected); + color_lines.resize(0); + std::vector(color_lines).swap(color_lines); + color_facets.resize(0); + std::vector(color_facets).swap(color_facets); + normals_flat.resize(0); + std::vector(normals_flat).swap(normals_flat); + normals_gouraud.resize(0); + std::vector(normals_gouraud).swap(normals_gouraud); are_buffers_filled = true; } void -Scene_polyhedron_item::compute_normals_and_vertices(void) +Scene_polyhedron_item::compute_normals_and_vertices(void) const { positions_facets.resize(0); positions_lines.resize(0); - normals.resize(0); + normals_flat.resize(0); + normals_gouraud.resize(0); //Facets @@ -453,25 +525,20 @@ Scene_polyhedron_item::compute_normals_and_vertices(void) CGAL_For_all(he,end) { - // If Flat shading:1 normal per polygon added once per vertex - if (cur_shading == FlatPlusEdges || cur_shading == Flat ) - { + // // If Flat shading:1 normal per polygon added once per vertex - Vector n = CGAL::Polygon_mesh_processing::compute_face_normal(f, *poly); - normals.push_back(n.x()); - normals.push_back(n.y()); - normals.push_back(n.z()); - } + Vector n = CGAL::Polygon_mesh_processing::compute_face_normal(f, *poly); + normals_flat.push_back(n.x()); + normals_flat.push_back(n.y()); + normals_flat.push_back(n.z()); - // If Gouraud shading: 1 normal per vertex - else if (cur_shading == Gouraud) - { - Vector n = CGAL::Polygon_mesh_processing::compute_vertex_normal(he->vertex(), *poly); - normals.push_back(n.x()); - normals.push_back(n.y()); - normals.push_back(n.z()); - } + //// If Gouraud shading: 1 normal per vertex + + n = CGAL::Polygon_mesh_processing::compute_vertex_normal(he->vertex(), *poly); + normals_gouraud.push_back(n.x()); + normals_gouraud.push_back(n.y()); + normals_gouraud.push_back(n.z()); //position const Point& p = he->vertex()->point(); @@ -534,7 +601,7 @@ Scene_polyhedron_item::compute_normals_and_vertices(void) } void -Scene_polyhedron_item::compute_colors() +Scene_polyhedron_item::compute_colors() const { color_lines.resize(0); color_facets.resize(0); @@ -632,7 +699,7 @@ Scene_polyhedron_item::compute_colors() } Scene_polyhedron_item::Scene_polyhedron_item() - : Scene_item(10,4), + : Scene_item(11,6), is_Triangle(true), poly(new Polyhedron), show_only_feature_edges_m(false), @@ -643,12 +710,14 @@ Scene_polyhedron_item::Scene_polyhedron_item() { cur_shading=FlatPlusEdges; is_selected = true; + nb_facets = 0; + nb_lines = 0; init(); } Scene_polyhedron_item::Scene_polyhedron_item(Polyhedron* const p) - : Scene_item(10,4), + : Scene_item(11,6), is_Triangle(true), poly(p), show_only_feature_edges_m(false), @@ -659,12 +728,14 @@ Scene_polyhedron_item::Scene_polyhedron_item(Polyhedron* const p) { cur_shading=FlatPlusEdges; is_selected = true; + nb_facets = 0; + nb_lines = 0; init(); - changed(); + invalidate_buffers(); } Scene_polyhedron_item::Scene_polyhedron_item(const Polyhedron& p) - : Scene_item(10,4), + : Scene_item(11,6), is_Triangle(true), poly(new Polyhedron(p)), show_only_feature_edges_m(false), @@ -676,7 +747,9 @@ Scene_polyhedron_item::Scene_polyhedron_item(const Polyhedron& p) cur_shading=FlatPlusEdges; is_selected=true; init(); - changed(); + nb_facets = 0; + nb_lines = 0; + invalidate_buffers(); } Scene_polyhedron_item::~Scene_polyhedron_item() @@ -754,7 +827,7 @@ Scene_polyhedron_item::load(std::istream& in) if ( in && !isEmpty() ) { - changed(); + invalidate_buffers(); return true; } return false; @@ -870,11 +943,23 @@ void Scene_polyhedron_item::set_erase_next_picked_facet(bool b) void Scene_polyhedron_item::draw(Viewer_interface* viewer) const { if(!are_buffers_filled) + { + is_Triangulated(); + compute_normals_and_vertices(); initialize_buffers(viewer); + } - if(!is_selected) + if(!is_selected && renderingMode() == Flat) vaos[0]->bind(); + else if(!is_selected && renderingMode() == Gouraud) + { + vaos[4]->bind(); + } + else if (is_selected && renderingMode() == Gouraud) + { + vaos[5]->bind(); + } else { vaos[2]->bind(); @@ -882,10 +967,14 @@ void Scene_polyhedron_item::draw(Viewer_interface* viewer) const { attrib_buffers(viewer, PROGRAM_WITH_LIGHT); program = getShaderProgram(PROGRAM_WITH_LIGHT); program->bind(); - viewer->glDrawArrays(GL_TRIANGLES, 0, static_cast(positions_facets.size()/4)); + viewer->glDrawArrays(GL_TRIANGLES, 0, static_cast(nb_facets/4)); program->release(); - if(!is_selected) + if(!is_selected && renderingMode() == Flat) vaos[0]->release(); + else if(!is_selected && renderingMode() == Gouraud) + vaos[4]->release(); + else if (is_selected && renderingMode() == Gouraud) + vaos[5]->release(); else vaos[2]->release(); } @@ -895,6 +984,12 @@ void Scene_polyhedron_item::draw_edges(Viewer_interface* viewer) const { typedef Kernel::Point_3 Point; typedef Polyhedron::Edge_iterator Edge_iterator; + if(!are_buffers_filled) + { + is_Triangulated(); + compute_normals_and_vertices(); + initialize_buffers(viewer); + } ::glBegin(GL_LINES); Edge_iterator he; @@ -936,7 +1031,7 @@ void Scene_polyhedron_item::draw_edges(Viewer_interface* viewer) const program = getShaderProgram(PROGRAM_WITHOUT_LIGHT); program->bind(); //draw the edges - viewer->glDrawArrays(GL_LINES, 0, static_cast(positions_lines.size()/4)); + viewer->glDrawArrays(GL_LINES, 0, static_cast(nb_lines/4)); program->release(); if(!is_selected) vaos[1]->release(); @@ -946,13 +1041,19 @@ void Scene_polyhedron_item::draw_edges(Viewer_interface* viewer) const void Scene_polyhedron_item::draw_points(Viewer_interface* viewer) const { + if(!are_buffers_filled) + { + is_Triangulated(); + compute_normals_and_vertices(); + initialize_buffers(viewer); + } vaos[1]->bind(); attrib_buffers(viewer, PROGRAM_WITHOUT_LIGHT); program = getShaderProgram(PROGRAM_WITHOUT_LIGHT); program->bind(); //draw the points - viewer->glDrawArrays(GL_POINTS, 0, static_cast(positions_lines.size()/4)); + viewer->glDrawArrays(GL_POINTS, 0, static_cast(nb_lines/4)); // Clean-up program->release(); vaos[1]->release(); @@ -984,12 +1085,12 @@ Scene_polyhedron_item::bbox() const { void Scene_polyhedron_item:: -changed() +invalidate_buffers() { Q_EMIT item_is_about_to_be_changed(); delete_aabb_tree(this); init(); - Base::changed(); + Base::invalidate_buffers(); is_Triangulated(); compute_normals_and_vertices(); are_buffers_filled = false; @@ -1005,7 +1106,7 @@ contextual_changed() if(cur_shading == Flat || cur_shading == FlatPlusEdges ||cur_shading == Gouraud) { //Change the normals - changed(); + // invalidate_buffers(); } } @@ -1015,7 +1116,7 @@ Scene_polyhedron_item::selection_changed(bool p_is_selected) if(p_is_selected != is_selected) { is_selected = p_is_selected; - are_buffers_filled = false; + //are_buffers_filled = false; } } @@ -1024,7 +1125,7 @@ void Scene_polyhedron_item::setColor(QColor c) { // reset patch ids - if (plugin_has_set_color_vector_m) + if (colors_.size()>2 || plugin_has_set_color_vector_m) { BOOST_FOREACH(Polyhedron::Facet_handle fh, faces(*poly)) fh->set_patch_id(1); @@ -1139,7 +1240,7 @@ Scene_polyhedron_item::select(double orig_x, polyhedron()->erase_facet(selected_fh->halfedge()); polyhedron()->normalize_border(); //set_erase_next_picked_facet(false); - changed(); + invalidate_buffers(); Q_EMIT itemChanged(); } } diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.h b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.h index ec023d8bbaa..48b878d8cdb 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.h @@ -35,7 +35,7 @@ public: // IO bool load(std::istream& in); bool save(std::ostream& out) const; - bool is_Triangle; + mutable bool is_Triangle; // Function for displaying meta-data of the item virtual QString toolTip() const; @@ -44,7 +44,7 @@ public: QMenu* contextMenu(); // Indicate if rendering mode is supported - virtual bool supportsRenderingMode(RenderingMode m) const { return (m!=PointsPlusNormals); } + virtual bool supportsRenderingMode(RenderingMode m) const { return (m!=PointsPlusNormals && m!=Splatting); } // Points/Wireframe/Flat/Gouraud OpenGL drawing in a display list void draw() const {} virtual void draw(Viewer_interface*) const; @@ -64,7 +64,7 @@ public: void set_color_vector_read_only(bool on_off) {plugin_has_set_color_vector_m=on_off;} public Q_SLOTS: - virtual void changed(); + virtual void invalidate_buffers(); virtual void contextual_changed(); virtual void selection_changed(bool); virtual void setColor(QColor c); @@ -90,7 +90,7 @@ Q_SIGNALS: void selected_facet(void*); void selected_edge(void*); void selected_halfedge(void*); - void item_is_about_to_be_changed(); // emitted in changed() + void item_is_about_to_be_changed(); // emitted in invalidate_buffers() private: // Initialization @@ -114,23 +114,25 @@ private: bool plugin_has_set_color_vector_m; - std::vector positions_lines; - std::vector positions_facets; - std::vector normals; - std::vector color_lines; - std::vector color_facets; - std::vector color_lines_selected; - std::vector color_facets_selected; - + mutable std::vector positions_lines; + mutable std::vector positions_facets; + mutable std::vector normals_flat; + mutable std::vector normals_gouraud; + mutable std::vector color_lines; + mutable std::vector color_facets; + mutable std::vector color_lines_selected; + mutable std::vector color_facets_selected; + mutable std::size_t nb_facets; + mutable std::size_t nb_lines; mutable QOpenGLShaderProgram *program; using Scene_item::initialize_buffers; void initialize_buffers(Viewer_interface *viewer = 0) const; - void compute_normals_and_vertices(void); - void compute_colors(); - void triangulate_facet(Facet_iterator ); - void triangulate_facet_color(Facet_iterator ); - void is_Triangulated(); + void compute_normals_and_vertices(void) const; + void compute_colors() const; + void triangulate_facet(Facet_iterator ) const; + void triangulate_facet_color(Facet_iterator ) const; + void is_Triangulated() const; double volume, area; }; // end class Scene_polyhedron_item diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item_decorator.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item_decorator.cpp index a08960067b9..1b71ab96b69 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item_decorator.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item_decorator.cpp @@ -63,10 +63,10 @@ Scene_polyhedron_item_decorator::bbox() const { void Scene_polyhedron_item_decorator:: -changed() +invalidate_buffers() { - poly_item->changed(); - Scene_item::changed(); + poly_item->invalidate_buffers(); + Scene_item::invalidate_buffers(); } void diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item_decorator.h b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item_decorator.h index 2377fd00a79..03f0866b35c 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item_decorator.h +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item_decorator.h @@ -27,7 +27,7 @@ public: // QMenu* contextMenu(); // Indicate if rendering mode is supported - bool supportsRenderingMode(RenderingMode m) const { return m!=PointsPlusNormals; } + bool supportsRenderingMode(RenderingMode m) const { return (m!=PointsPlusNormals && m!=Splatting); } // Points/Wireframe/Flat/Gouraud OpenGL drawing in a display list // dispatch to poly_item direct_draw and direct_draw_edges void draw() const; @@ -49,7 +49,7 @@ public: void set_delete_item(bool delete_item) { delete_poly_item = delete_item; } public Q_SLOTS: - void changed(); + void invalidate_buffers(); void select(double orig_x, double orig_y, double orig_z, diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp index 2259e092666..0d78fed0b1c 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp @@ -65,6 +65,20 @@ void Scene_polyhedron_selection_item::initialize_buffers(Viewer_interface *viewe vaos[2]->release(); } + nb_facets = positions_facets.size(); + positions_facets.resize(0); + std::vector(positions_facets).swap(positions_facets); + + normals.resize(0); + std::vector(normals).swap(normals); + + nb_lines = positions_lines.size(); + positions_lines.resize(0); + std::vector(positions_lines).swap(positions_lines); + + nb_points = positions_points.size(); + positions_points.resize(0); + std::vector(positions_points).swap(positions_points); are_buffers_filled = true; } @@ -164,7 +178,7 @@ void Scene_polyhedron_selection_item::draw(Viewer_interface* viewer) const attrib_buffers(viewer,PROGRAM_WITH_LIGHT); program->bind(); program->setAttributeValue("colors",facet_color); - viewer->glDrawArrays(GL_TRIANGLES, 0, static_cast(positions_facets.size()/3)); + viewer->glDrawArrays(GL_TRIANGLES, 0, static_cast(nb_facets/3)); program->release(); vaos[0]->release(); glPolygonOffset(offset_factor, offset_units); @@ -182,7 +196,7 @@ void Scene_polyhedron_selection_item::draw_edges(Viewer_interface* viewer) const attrib_buffers(viewer,PROGRAM_WITHOUT_LIGHT); program->bind(); program->setAttributeValue("colors",edge_color); - viewer->glDrawArrays(GL_LINES, 0, static_cast(positions_lines.size()/3)); + viewer->glDrawArrays(GL_LINES, 0, static_cast(nb_lines/3)); program->release(); vaos[1]->release(); viewer->glLineWidth(1.f); @@ -196,7 +210,7 @@ void Scene_polyhedron_selection_item::draw_points(Viewer_interface* viewer) cons attrib_buffers(viewer,PROGRAM_WITHOUT_LIGHT); program->bind(); program->setAttributeValue("colors",vertex_color); - viewer->glDrawArrays(GL_POINTS, 0, static_cast(positions_points.size()/3)); + viewer->glDrawArrays(GL_POINTS, 0, static_cast(nb_points/3)); program->release(); vaos[2]->release(); viewer->glPointSize(1.f); diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.h b/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.h index 018423b9511..b5394d9a5cd 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.h @@ -186,12 +186,18 @@ public: { buffers[i].create(); } + nb_facets = 0; + nb_points = 0; + nb_lines = 0; } Scene_polyhedron_selection_item(Scene_polyhedron_item* poly_item, QMainWindow* mw) : Scene_polyhedron_item_decorator(NULL, false) { nbVaos = 0; + nb_facets = 0; + nb_points = 0; + nb_lines = 0; for(int i=0; i<3; i++) { addVaos(i); @@ -203,7 +209,7 @@ public: buffers[i].create(); } init(poly_item, mw); - changed(); + invalidate_buffers(); } ~Scene_polyhedron_selection_item() @@ -400,6 +406,7 @@ public: for(typename Tr::Iterator it = tr.iterator_begin() ; it != tr.iterator_end(); ++it) { tr.container().insert(*it); } + invalidate_buffers(); Q_EMIT itemChanged(); } @@ -421,6 +428,7 @@ public: Selection_traits tr(this); tr.container().clear(); + invalidate_buffers(); Q_EMIT itemChanged(); } @@ -472,7 +480,7 @@ public: Travel_isolated_components().travel (tr.iterator_begin(), tr.iterator_end(), tr.size(), tr.container(), visitor); - if(visitor.any_inserted) { Q_EMIT itemChanged(); } + if(visitor.any_inserted) { invalidate_buffers(); Q_EMIT itemChanged(); } return visitor.minimum_visitor.minimum; } @@ -572,7 +580,7 @@ public: any_change |= tr.container().insert(*it).second; } } - if(any_change) { Q_EMIT itemChanged(); } + if(any_change) { invalidate_buffers(); Q_EMIT itemChanged(); } } template @@ -601,7 +609,7 @@ public: any_change |= (tr.container().erase(*it)!=0); } } - if(any_change) { Q_EMIT itemChanged(); } + if(any_change) { invalidate_buffers(); Q_EMIT itemChanged(); } } void erase_selected_facets() { @@ -613,6 +621,7 @@ public: polyhedron()->erase_facet((*fb)->halfedge()); } selected_facets.clear(); + invalidate_buffers(); changed_with_poly_item(); } @@ -691,7 +700,8 @@ public: void changed_with_poly_item() { // no need to update indices - poly_item->changed(); + poly_item->invalidate_buffers(); + Q_EMIT poly_item->itemChanged(); Q_EMIT itemChanged(); } @@ -699,9 +709,10 @@ Q_SIGNALS: void simplicesSelected(Scene_item*); public Q_SLOTS: - void changed() { + void invalidate_buffers() { + // do not use decorator function, which calls changed on poly_item which cause deletion of AABB - // poly_item->changed(); + // poly_item->invalidate_buffers(); compute_elements(); are_buffers_filled = false; } @@ -768,7 +779,7 @@ protected: BOOST_FOREACH(HandleType h, selection) any_change |= (tr.container().erase(h)!=0); } - return any_change; + if(any_change) { invalidate_buffers(); Q_EMIT itemChanged(); } } Facet_handle face(Facet_handle fh) @@ -846,15 +857,17 @@ public: private: - std::vector positions_facets; - std::vector normals; - std::vector positions_lines; - std::vector positions_points; - - mutable QOpenGLShaderProgram *program; - using Scene_item::initialize_buffers; - void initialize_buffers(Viewer_interface *viewer) const; - void compute_elements(); + mutable std::vector positions_facets; + mutable std::vector normals; + mutable std::vector positions_lines; + mutable std::vector positions_points; + mutable std::size_t nb_facets; + mutable std::size_t nb_points; + mutable std::size_t nb_lines; + mutable QOpenGLShaderProgram *program; + using Scene_item::initialize_buffers; + void initialize_buffers(Viewer_interface *viewer) const; + void compute_elements(); }; diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_shortest_path_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_shortest_path_item.cpp index ee937dd2740..13db5c398c5 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_shortest_path_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_shortest_path_item.cpp @@ -177,9 +177,11 @@ void Scene_polyhedron_shortest_path_item::ensure_shortest_paths_tree() void Scene_polyhedron_shortest_path_item::poly_item_changed() { recreate_shortest_path_object(); + invalidate_buffers(); + Q_EMIT itemChanged(); } -void Scene_polyhedron_shortest_path_item::changed() +void Scene_polyhedron_shortest_path_item::invalidate_buffers() { compute_elements(); are_buffers_filled = false; @@ -380,7 +382,7 @@ bool Scene_polyhedron_shortest_path_item::run_point_select(const Ray_3& ray) } break; } - changed(); + invalidate_buffers(); return true; } } diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_shortest_path_item.h b/Polyhedron/demo/Polyhedron/Scene_polyhedron_shortest_path_item.h index 6a51bbcb1f6..e89a574ce22 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_shortest_path_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_shortest_path_item.h @@ -146,7 +146,7 @@ protected: public Q_SLOTS: virtual void poly_item_changed(); - virtual void changed(); + virtual void invalidate_buffers(); }; #endif // SCENE_POLYHEDRON_SHORTEST_PATH_ITEM_H diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_transform_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_transform_item.cpp index bc0dad001ec..77de6a687e1 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_transform_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_transform_item.cpp @@ -12,6 +12,7 @@ Scene_polyhedron_transform_item::Scene_polyhedron_transform_item(const qglviewer { frame->setPosition(pos); + nb_lines = 0; } void Scene_polyhedron_transform_item::initialize_buffers(Viewer_interface *viewer =0) const @@ -34,6 +35,10 @@ void Scene_polyhedron_transform_item::initialize_buffers(Viewer_interface *viewe vaos[0]->release(); program->release(); } + nb_lines = positions_lines.size(); + positions_lines.resize(0); + std::vector(positions_lines).swap(positions_lines); + are_buffers_filled = true; } @@ -75,7 +80,7 @@ void Scene_polyhedron_transform_item::draw_edges(Viewer_interface* viewer) const f_matrix.data()[i] = (float)frame->matrix()[i]; } program->setUniformValue("f_matrix", f_matrix); - viewer->glDrawArrays(GL_LINES, 0, static_cast(positions_lines.size()/3)); + viewer->glDrawArrays(GL_LINES, 0, static_cast(nb_lines/3)); vaos[0]->release(); program->release(); @@ -109,7 +114,7 @@ Scene_polyhedron_transform_item::bbox() const { } -void Scene_polyhedron_transform_item::changed() +void Scene_polyhedron_transform_item::invalidate_buffers() { compute_elements(); are_buffers_filled = false; diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_transform_item.h b/Polyhedron/demo/Polyhedron/Scene_polyhedron_transform_item.h index 274fa999d1c..116e64fcfc9 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_transform_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_transform_item.h @@ -27,7 +27,7 @@ public: const Scene_polyhedron_item* getBase() const{ return poly_item; }; const qglviewer::Vec& center() const { return center_; } virtual bool supportsRenderingMode(RenderingMode m) const { return m==Wireframe ; } - virtual void changed(); + virtual void invalidate_buffers(); virtual bool keyPressEvent(QKeyEvent*); private: @@ -37,7 +37,8 @@ private: const Polyhedron* poly; qglviewer::Vec center_; mutable QOpenGLShaderProgram *program; - std::vector positions_lines; + mutable std::vector positions_lines; + mutable std::size_t nb_lines; using Scene_item::initialize_buffers; void initialize_buffers(Viewer_interface *viewer) const; void compute_elements(); diff --git a/Polyhedron/demo/Polyhedron/Scene_polylines_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polylines_item.cpp index 93a8be66aea..b6dc2340194 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polylines_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polylines_item.cpp @@ -34,7 +34,7 @@ Scene_polylines_item::create_Sphere(double R) void Scene_polylines_item::initialize_buffers(Viewer_interface *viewer = 0) const { -//vao for the lines + //vao for the lines { program = getShaderProgram(PROGRAM_WITHOUT_LIGHT, viewer); program->bind(); @@ -87,6 +87,20 @@ Scene_polylines_item::initialize_buffers(Viewer_interface *viewer = 0) const viewer->glVertexAttribDivisor(program->attributeLocation("center"), 1); viewer->glVertexAttribDivisor(program->attributeLocation("colors"), 1); + + nb_lines = positions_lines.size(); + positions_lines.resize(0); + std::vector(positions_lines).swap(positions_lines); + nb_spheres = positions_spheres.size(); + positions_spheres.resize(0); + std::vector(positions_spheres).swap(positions_spheres); + normals_spheres.resize(0); + std::vector(normals_spheres).swap(normals_spheres); + color_spheres.resize(0); + std::vector(color_spheres).swap(color_spheres); + nb_centers = positions_center.size(); + positions_center.resize(0); + std::vector(positions_center).swap(positions_center); } else { @@ -319,7 +333,11 @@ Scene_polylines_item::Scene_polylines_item() ,nbSpheres(0) { setRenderingMode(FlatPlusEdges); - changed(); + nb_spheres = 0; + nb_wire = 0; + nb_centers = 0; + nb_lines = 0; + invalidate_buffers(); } @@ -417,7 +435,7 @@ Scene_polylines_item::draw(Viewer_interface* viewer) const { attrib_buffers(viewer, PROGRAM_INSTANCED); program->bind(); viewer->glDrawArraysInstanced(GL_TRIANGLES, 0, - static_cast(positions_spheres.size()/3), nbSpheres); + static_cast(nb_spheres/3), nbSpheres); program->release(); vaos[1]->release(); } @@ -429,7 +447,7 @@ Scene_polylines_item::draw(Viewer_interface* viewer) const { glPointSize(8.0f); glEnable(GL_POINT_SMOOTH); program->bind(); - viewer->glDrawArrays(GL_POINTS, 0, static_cast(positions_center.size()/3)); + viewer->glDrawArrays(GL_POINTS, 0, static_cast(nb_centers/3)); glDisable(GL_POINT_SMOOTH); program->release(); vaos[1]->release(); @@ -448,7 +466,7 @@ Scene_polylines_item::draw_edges(Viewer_interface* viewer) const { program = getShaderProgram(PROGRAM_WITHOUT_LIGHT); program->bind(); program->setAttributeValue("colors", this->color()); - viewer->glDrawArrays(GL_LINES, 0, static_cast(positions_lines.size()/4)); + viewer->glDrawArrays(GL_LINES, 0, static_cast(nb_lines/4)); program->release(); vaos[0]->release(); if(d->draw_extremities) @@ -460,7 +478,7 @@ Scene_polylines_item::draw_edges(Viewer_interface* viewer) const { program = getShaderProgram(PROGRAM_INSTANCED_WIRE); program->bind(); viewer->glDrawArraysInstanced(GL_LINES, 0, - static_cast(positions_wire_spheres.size()/3), nbSpheres); + static_cast(nb_wire/3), nbSpheres); program->release(); vaos[2]->release(); } @@ -479,7 +497,7 @@ Scene_polylines_item::draw_points(Viewer_interface* viewer) const { program->bind(); QColor temp = this->color(); program->setAttributeValue("colors", temp); - viewer->glDrawArrays(GL_POINTS, 0, static_cast(positions_lines.size()/4)); + viewer->glDrawArrays(GL_POINTS, 0, static_cast(nb_lines/4)); // Clean-up vaos[0]->release(); program->release(); @@ -511,7 +529,7 @@ QMenu* Scene_polylines_item::contextMenu() return menu; } -void Scene_polylines_item::changed() +void Scene_polylines_item::invalidate_buffers() { compute_elements(); are_buffers_filled = false; @@ -549,7 +567,7 @@ void Scene_polylines_item::change_corner_radii(double r) { if(r >= 0) { d->spheres_drawn_radius = r; d->draw_extremities = (r > 0); - this->changed(); + this->invalidate_buffers(); Q_EMIT itemChanged(); } } @@ -651,6 +669,6 @@ Scene_polylines_item::merge(Scene_polylines_item* other_item) { metadata.append(other_metadata_variant.toStringList()); setProperty("polylines metadata", metadata); } - changed(); + invalidate_buffers(); } diff --git a/Polyhedron/demo/Polyhedron/Scene_polylines_item.h b/Polyhedron/demo/Polyhedron/Scene_polylines_item.h index 6a9c7b356a4..0f44b179bf5 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polylines_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_polylines_item.h @@ -74,7 +74,7 @@ public: } public Q_SLOTS: - virtual void changed(); + virtual void invalidate_buffers(); void change_corner_radii(double); void change_corner_radii(); void split_at_sharp_angles(); @@ -84,7 +84,8 @@ public Q_SLOTS: void smooth(){ for (Polylines_container::iterator pit=polylines.begin(),pit_end=polylines.end();pit!=pit_end;++pit) smooth(*pit); - Q_EMIT itemChanged(); + invalidate_buffers(); + Q_EMIT itemChanged(); } public: Polylines_container polylines; @@ -92,17 +93,19 @@ public: // http://en.wikipedia.org/wiki/D-pointer Scene_polylines_item_private* d; private: - std::vector positions_lines; - std::vector positions_spheres; - std::vector positions_wire_spheres; - std::vector positions_center; - std::vector normals_spheres; - std::vector color_spheres; - std::vector color_wire_spheres; - - - mutable QOpenGLShaderProgram *program; - mutable GLuint nbSpheres; + mutable std::vector positions_lines; + mutable std::vector positions_spheres; + mutable std::vector positions_wire_spheres; + mutable std::vector positions_center; + mutable std::vector normals_spheres; + mutable std::vector color_spheres; + mutable std::vector color_wire_spheres; + mutable std::size_t nb_spheres; + mutable std::size_t nb_wire; + mutable std::size_t nb_centers; + mutable std::size_t nb_lines; + mutable QOpenGLShaderProgram *program; + mutable GLuint nbSpheres; typedef std::map Point_to_int_map; typedef Point_to_int_map::iterator iterator; void create_Sphere(double); diff --git a/Polyhedron/demo/Polyhedron/Scene_textured_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_textured_polyhedron_item.cpp index 15eac9ac599..399c2b48a80 100644 --- a/Polyhedron/demo/Polyhedron/Scene_textured_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_textured_polyhedron_item.cpp @@ -85,6 +85,19 @@ void Scene_textured_polyhedron_item::initialize_buffers(Viewer_interface *viewer viewer->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + nb_facets = positions_facets.size(); + positions_facets.resize(0); + std::vector(positions_facets).swap(positions_facets); + normals.resize(0); + std::vector(normals).swap(normals); + textures_map_facets.resize(0); + std::vector(textures_map_facets).swap(textures_map_facets); + nb_lines = positions_lines.size(); + positions_lines.resize(0); + std::vector(positions_lines).swap(positions_lines); + textures_map_lines.resize(0); + std::vector(textures_map_lines).swap(textures_map_lines); + are_buffers_filled = true; } @@ -200,7 +213,9 @@ Scene_textured_polyhedron_item::Scene_textured_polyhedron_item() texture.GenerateCheckerBoard(2048,2048,128,0,0,0,250,250,255); cur_shading=FlatPlusEdges; is_selected=false; - changed(); + nb_facets = 0; + nb_lines = 0; + invalidate_buffers(); } Scene_textured_polyhedron_item::Scene_textured_polyhedron_item(Textured_polyhedron* const p) @@ -209,7 +224,9 @@ Scene_textured_polyhedron_item::Scene_textured_polyhedron_item(Textured_polyhedr cur_shading=FlatPlusEdges; is_selected=false; texture.GenerateCheckerBoard(2048,2048,128,0,0,0,250,250,255); - changed(); + nb_facets = 0; + nb_lines = 0; + invalidate_buffers(); } Scene_textured_polyhedron_item::Scene_textured_polyhedron_item(const Textured_polyhedron& p) @@ -218,7 +235,9 @@ Scene_textured_polyhedron_item::Scene_textured_polyhedron_item(const Textured_po texture.GenerateCheckerBoard(2048,2048,128,0,0,0,250,250,255); cur_shading=FlatPlusEdges; is_selected=false; - changed(); + nb_facets = 0; + nb_lines = 0; + invalidate_buffers(); } Scene_textured_polyhedron_item::~Scene_textured_polyhedron_item() @@ -237,7 +256,7 @@ Scene_textured_polyhedron_item::load(std::istream& in) { std::cout<<"LOAD"<> *poly; - changed(); + invalidate_buffers(); return in && !isEmpty(); } @@ -279,7 +298,7 @@ void Scene_textured_polyhedron_item::draw(Viewer_interface* viewer) const { attrib_buffers(viewer, PROGRAM_WITH_TEXTURE); program=getShaderProgram(PROGRAM_WITH_TEXTURE); program->bind(); - viewer->glDrawArrays(GL_TRIANGLES, 0, static_cast(positions_facets.size()/4)); + viewer->glDrawArrays(GL_TRIANGLES, 0, static_cast(nb_facets/4)); //Clean-up program->release(); vaos[0]->release(); @@ -295,7 +314,7 @@ void Scene_textured_polyhedron_item::draw_edges(Viewer_interface* viewer) const program=getShaderProgram(PROGRAM_WITH_TEXTURED_EDGES); program->bind(); - viewer->glDrawArrays(GL_LINES, 0, static_cast(positions_lines.size()/4)); + viewer->glDrawArrays(GL_LINES, 0, static_cast(nb_lines/4)); //Clean-up program->release(); vaos[1]->release(); @@ -324,7 +343,7 @@ Scene_textured_polyhedron_item::bbox() const { bbox.xmax(),bbox.ymax(),bbox.zmax()); } void -Scene_textured_polyhedron_item::changed() +Scene_textured_polyhedron_item::invalidate_buffers() { compute_normals_and_vertices(); are_buffers_filled = false;} @@ -336,7 +355,7 @@ contextual_changed() cur_shading = renderingMode(); if(prev_shading != cur_shading) { - changed(); + invalidate_buffers(); } } void diff --git a/Polyhedron/demo/Polyhedron/Scene_textured_polyhedron_item.h b/Polyhedron/demo/Polyhedron/Scene_textured_polyhedron_item.h index d0e988b574e..0d3287a57d7 100644 --- a/Polyhedron/demo/Polyhedron/Scene_textured_polyhedron_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_textured_polyhedron_item.h @@ -28,7 +28,7 @@ public: virtual QString toolTip() const; // Indicate if rendering mode is supported - virtual bool supportsRenderingMode(RenderingMode) const { return true; } + virtual bool supportsRenderingMode(RenderingMode m) const { return m != Splatting; } // Points/Wireframe/Flat/Gouraud OpenGL drawing in a display list void draw() const {} virtual void draw(Viewer_interface*) const; @@ -44,19 +44,20 @@ public: bool isEmpty() const; Bbox bbox() const; - virtual void changed(); + virtual void invalidate_buffers(); virtual void contextual_changed(); virtual void selection_changed(bool); private: Textured_polyhedron* poly; Texture texture; - std::vector positions_lines; - std::vector positions_facets; - std::vector normals; - std::vector textures_map_facets; - std::vector textures_map_lines; - + mutable std::vector positions_lines; + mutable std::vector positions_facets; + mutable std::vector normals; + mutable std::vector textures_map_facets; + mutable std::vector textures_map_lines; + mutable std::size_t nb_facets; + mutable std::size_t nb_lines; mutable GLuint textureId; mutable QOpenGLShaderProgram* program; diff --git a/Polyhedron/demo/Polyhedron/Viewer.cpp b/Polyhedron/demo/Polyhedron/Viewer.cpp index 7da7c0d194f..fee167b5b4c 100644 --- a/Polyhedron/demo/Polyhedron/Viewer.cpp +++ b/Polyhedron/demo/Polyhedron/Viewer.cpp @@ -190,39 +190,39 @@ void Viewer_impl::draw_aux(bool with_names, Viewer* viewer) if(scene == 0) return; - ::glLineWidth(1.0f); - ::glPointSize(2.f); - ::glEnable(GL_POLYGON_OFFSET_FILL); - ::glPolygonOffset(1.0f,1.0f); - ::glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); + viewer->glLineWidth(1.0f); + viewer->glPointSize(2.f); + viewer->glEnable(GL_POLYGON_OFFSET_FILL); + viewer->glPolygonOffset(1.0f,1.0f); + viewer->glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); - ::glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); + viewer->glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); if(twosides) - ::glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); + viewer->glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); else - ::glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); + viewer->glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); if(antialiasing) { - ::glEnable(GL_BLEND); - ::glEnable(GL_LINE_SMOOTH); - ::glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); - ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + viewer->glEnable(GL_BLEND); + viewer->glEnable(GL_LINE_SMOOTH); + viewer->glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); + viewer->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } else { - ::glDisable(GL_BLEND); - ::glDisable(GL_LINE_SMOOTH); - ::glHint(GL_LINE_SMOOTH_HINT, GL_FASTEST); - ::glBlendFunc(GL_ONE, GL_ZERO); + viewer->glDisable(GL_BLEND); + viewer->glDisable(GL_LINE_SMOOTH); + viewer->glHint(GL_LINE_SMOOTH_HINT, GL_FASTEST); + viewer->glBlendFunc(GL_ONE, GL_ZERO); } if(with_names) scene->drawWithNames(viewer); else scene->draw(viewer); - ::glDisable(GL_POLYGON_OFFSET_FILL); - ::glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); + viewer->glDisable(GL_POLYGON_OFFSET_FILL); + viewer->glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); } void Viewer::drawWithNames() diff --git a/Polyhedron/demo/Polyhedron/cgal_test_with_cmake b/Polyhedron/demo/Polyhedron/cgal_test_with_cmake index 11b88d3f40b..2f49750a143 100755 --- a/Polyhedron/demo/Polyhedron/cgal_test_with_cmake +++ b/Polyhedron/demo/Polyhedron/cgal_test_with_cmake @@ -129,11 +129,14 @@ else point_dialog \ point_inside_polyhedron_plugin \ point_set_average_spacing_plugin \ + point_set_bilateral_smoothing_plugin \ point_set_outliers_removal_plugin \ point_set_selection_plugin \ point_set_shape_detection_plugin \ point_set_simplification_plugin \ point_set_smoothing_plugin \ + point_set_upsampling_plugin \ + point_set_wlop_plugin \ poisson_plugin \ polyhedron_slicer_plugin \ polyhedron_stitching_plugin \ diff --git a/Polyhedron/demo/Polyhedron/include/Point_set_3.h b/Polyhedron/demo/Polyhedron/include/Point_set_3.h index e84d1712173..ce10c0f0f4d 100644 --- a/Polyhedron/demo/Polyhedron/include/Point_set_3.h +++ b/Polyhedron/demo/Polyhedron/include/Point_set_3.h @@ -289,6 +289,24 @@ public: ::glEnd(); } } + + // Draw oriented points with radius using OpenGL calls. + // Preconditions: must be used inbetween calls to GlSplat library + void gl_draw_splats() const + { + // TODO add support for selection + ::glBegin(GL_POINTS); + for (const_iterator it = begin(); it != end(); it++) + { + const UI_point& p = *it; + ::glNormal3dv(&p.normal().x()); +#ifdef CGAL_GLEW_ENABLED + ::glMultiTexCoord1d(GL_TEXTURE2, p.radius()); +#endif + ::glVertex3dv(&p.x()); + } + ::glEnd(); + } bool are_radii_uptodate() const { return m_radii_are_uptodate; } void set_radii_uptodate(bool /*on*/) { m_radii_are_uptodate = false; } diff --git a/Polyhedron/demo/Polyhedron/resources/shader_with_texture.f b/Polyhedron/demo/Polyhedron/resources/shader_with_texture.f index 4d9bc7ca323..79034e2fcd6 100644 --- a/Polyhedron/demo/Polyhedron/resources/shader_with_texture.f +++ b/Polyhedron/demo/Polyhedron/resources/shader_with_texture.f @@ -5,5 +5,5 @@ uniform sampler2D s_texture; void main(void) { - gl_FragColor = vec4(vec3(texture(s_texture, f_texCoord))*fColors, 1.0); + gl_FragColor = vec4(vec3(texture2D(s_texture, f_texCoord))*fColors, 1.0); } diff --git a/Polyhedron/demo/Polyhedron/resources/shader_with_textured_edges.f b/Polyhedron/demo/Polyhedron/resources/shader_with_textured_edges.f index 888152005a4..eb35fed7437 100644 --- a/Polyhedron/demo/Polyhedron/resources/shader_with_textured_edges.f +++ b/Polyhedron/demo/Polyhedron/resources/shader_with_textured_edges.f @@ -5,5 +5,5 @@ uniform highp sampler2D s_texture; void main(void) { - gl_FragColor = vec4(vec3(texture(s_texture, f_texCoord))*fColors, 1.0); + gl_FragColor = vec4(vec3(texture2D(s_texture, f_texCoord))*fColors, 1.0); } diff --git a/Polyline_simplification_2/doc/Polyline_simplification_2/PackageDescription.txt b/Polyline_simplification_2/doc/Polyline_simplification_2/PackageDescription.txt index a6321a1c95d..7a4b2f38fe7 100644 --- a/Polyline_simplification_2/doc/Polyline_simplification_2/PackageDescription.txt +++ b/Polyline_simplification_2/doc/Polyline_simplification_2/PackageDescription.txt @@ -25,7 +25,7 @@ \cgalPkgDependsOn{\ref PkgTriangulation2Summary} \cgalPkgBib{cgal:f-ps2} \cgalPkgLicense{\ref licensesGPL "GPL"} -\cgalPkgDemo{Polygon Demo,polygon_2.zip} +\cgalPkgDemo{Polyline Simplification,polyline_simplification_2.zip} \cgalPkgShortInfoEnd \cgalPkgDescriptionEnd diff --git a/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/Stop_above_cost_threshold.h b/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/Stop_above_cost_threshold.h index febbdac29b4..8d2cc594b5d 100644 --- a/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/Stop_above_cost_threshold.h +++ b/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/Stop_above_cost_threshold.h @@ -30,7 +30,7 @@ namespace Polyline_simplification_2 /// This class is a stop predicate returning `true` when the cost for -/// simplifying a vertex is smaller than a certain threshold. +/// simplifying a vertex is greater than a certain threshold. /// /// \cgalModels `PolylineSimplificationStopPredicate`. class Stop_above_cost_threshold diff --git a/STL_Extension/test/STL_Extension/CMakeLists.txt b/STL_Extension/test/STL_Extension/CMakeLists.txt index 6856027a210..ee278e0a45d 100644 --- a/STL_Extension/test/STL_Extension/CMakeLists.txt +++ b/STL_Extension/test/STL_Extension/CMakeLists.txt @@ -27,6 +27,7 @@ if ( CGAL_FOUND ) create_single_source_cgal_program( "test_Boolean_tag.cpp" ) create_single_source_cgal_program( "test_Cache.cpp" ) create_single_source_cgal_program( "test_Compact_container.cpp" ) + create_single_source_cgal_program( "test_Compact_container_is_used.cpp" ) create_single_source_cgal_program( "test_complexity_tags.cpp" ) create_single_source_cgal_program( "test_composition.cpp" ) create_single_source_cgal_program( "test_Concatenate_iterator.cpp" ) diff --git a/STL_Extension/test/STL_Extension/test_Compact_container_is_used.cpp b/STL_Extension/test/STL_Extension/test_Compact_container_is_used.cpp new file mode 100644 index 00000000000..d92ddefb286 --- /dev/null +++ b/STL_Extension/test/STL_Extension/test_Compact_container_is_used.cpp @@ -0,0 +1,71 @@ +// test program for Compact_container. + +#include + +class Node_1 +{ + union { + Node_1 * p; + void * p_cc; + }; + +public: + + Node_1() : p(NULL) + {} + + void * for_compact_container() const { return p_cc; } + void * & for_compact_container() { return p_cc; } +}; + +int main() +{ + typedef CGAL::Compact_container C1; + + C1 c1; + if (!c1.empty()) + { + std::cout<<"PB new container is not empty."< "$LOCK_FILE" +fi + # that line makes the script remove the lock file in case of unwanted exit trap "rm -f \"$LOCK_FILE\"" EXIT HUP INT TERM diff --git a/Spatial_searching/doc/Spatial_searching/Spatial_searching.txt b/Spatial_searching/doc/Spatial_searching/Spatial_searching.txt index 4576cd8dfe6..143195a8e56 100644 --- a/Spatial_searching/doc/Spatial_searching/Spatial_searching.txt +++ b/Spatial_searching/doc/Spatial_searching/Spatial_searching.txt @@ -429,7 +429,7 @@ k | bucket size | Surface/Surface | Surface/Random | Random/Random \cgalFigureBegin{Spatial_searchingfigbenchmark,gargoyle.png} -Benchmark dataset(downsampled for visualization).\n +Benchmark dataset (downsampled for visualization).\n Blue: Gargoyle surface. Green: Gargoyle bbox random. \cgalFigureEnd diff --git a/Spatial_searching/examples/Spatial_searching/CMakeLists.txt b/Spatial_searching/examples/Spatial_searching/CMakeLists.txt index 074ab36bd76..b7ded86999d 100644 --- a/Spatial_searching/examples/Spatial_searching/CMakeLists.txt +++ b/Spatial_searching/examples/Spatial_searching/CMakeLists.txt @@ -70,6 +70,8 @@ create_single_source_cgal_program( "searching_surface_mesh_vertices.cpp" ) create_single_source_cgal_program( "searching_polyhedron_vertices.cpp" ) +create_single_source_cgal_program( "searching_polyhedron_vertices_with_fuzzy_sphere.cpp") + create_single_source_cgal_program( "user_defined_point_and_distance.cpp" ) create_single_source_cgal_program( "using_fair_splitting_rule.cpp" ) diff --git a/Spatial_searching/examples/Spatial_searching/searching_polyhedron_vertices_with_fuzzy_sphere.cpp b/Spatial_searching/examples/Spatial_searching/searching_polyhedron_vertices_with_fuzzy_sphere.cpp new file mode 100644 index 00000000000..a8c47066ee7 --- /dev/null +++ b/Spatial_searching/examples/Spatial_searching/searching_polyhedron_vertices_with_fuzzy_sphere.cpp @@ -0,0 +1,56 @@ +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; +typedef Kernel::Point_3 Point_3; + +typedef CGAL::Polyhedron_3 Mesh; +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; + +typedef boost::property_map::type Vertex_point_pmap; + +typedef CGAL::Search_traits_3 Traits_base; +typedef CGAL::Search_traits_adapter Traits; + +typedef CGAL::Kd_tree Tree; +typedef Tree::Splitter Splitter; + +int main(int argc, char* argv[]) +{ + Mesh mesh; + std::ifstream in((argc>1)?argv[1]:"data/tripod.off"); + in >> mesh; + const unsigned int K = 5; + + Vertex_point_pmap vppmap = get(CGAL::vertex_point,mesh); + + // Insert number_of_data_points in the tree + Tree tree(vertices(mesh).begin(), + vertices(mesh).end(), + Splitter(), + Traits(vppmap) + ); + Point_3 query(0.0, 0.0, 0.0); + double radius = 0.5; + double epsilon = 0.01; + + // search vertices + CGAL::Fuzzy_sphere fz(query, radius, epsilon); + + //collect vertices that are inside the sphere + std::list result; + tree.search(std::back_inserter(result), fz); + std::cout << "There are " << result.size() << " vertices inside the fuzzy sphere\n"; + + return 0; +} diff --git a/Spatial_searching/include/CGAL/Fuzzy_sphere.h b/Spatial_searching/include/CGAL/Fuzzy_sphere.h index a767d7f69be..0c00cdf2ef2 100644 --- a/Spatial_searching/include/CGAL/Fuzzy_sphere.h +++ b/Spatial_searching/include/CGAL/Fuzzy_sphere.h @@ -24,6 +24,9 @@ #include #include +#include +#include + namespace CGAL { namespace internal{ @@ -150,8 +153,12 @@ namespace CGAL { Fuzzy_sphere(const SearchTraits& traits_=SearchTraits()):Base(traits_){}; Fuzzy_sphere(const typename Base_traits::Point_d& center, FT radius, FT epsilon=FT(0),const SearchTraits& traits_=SearchTraits()) : Base(center,radius,epsilon,traits_) {} - Fuzzy_sphere(const typename SearchTraits::Point_d& center, FT radius, FT epsilon=FT(0),const SearchTraits& traits_=SearchTraits()) : - Base(get(traits_.point_property_map(),center),radius,epsilon,traits_) {} + Fuzzy_sphere(const typename SearchTraits::Point_d& center, FT radius, FT epsilon=FT(0), + const SearchTraits& traits_=SearchTraits(), + typename boost::disable_if< + boost::is_same >::type* = 0) + : Base(get(traits_.point_property_map(),center),radius,epsilon,traits_) {} }; } // namespace CGAL diff --git a/Straight_skeleton_2/doc/Straight_skeleton_2/CGAL/create_offset_polygons_from_polygon_with_holes_2.h b/Straight_skeleton_2/doc/Straight_skeleton_2/CGAL/create_offset_polygons_from_polygon_with_holes_2.h index 5c2d651e14f..b9a5ca632cc 100644 --- a/Straight_skeleton_2/doc/Straight_skeleton_2/CGAL/create_offset_polygons_from_polygon_with_holes_2.h +++ b/Straight_skeleton_2/doc/Straight_skeleton_2/CGAL/create_offset_polygons_from_polygon_with_holes_2.h @@ -8,11 +8,11 @@ holes
at distance `offset` of the 2D polygon `poly`. This is equivalent to `arrange_offset_polygons_2(create_exterior_skeleton_and_offset_polygons_2(offset,poly,okk,ssk))`. */ -template -std::vector< boost::shared_ptr< Polygon_with_holes_2 > > +template +std::vector< boost::shared_ptr< Polygon_with_holes_2 > > create_exterior_skeleton_and_offset_polygons_with_holes_2 ( FT offset - , CGAL::Polygon_2 poly_with_holes + , CGAL::Polygon_2 poly_with_holes , OffsettingK ofk = Exact_predicates_inexact_constructions_kernel , SkeletonK ssk = Exact_predicates_inexact_constructions_kernel ) ; @@ -32,19 +32,20 @@ A temporary straight skeleton is constructed in the interior of the input polygo If `SkeletonK != OffsettingK` the constructed straight skeleton is converted to `Straight_skeleton_2`. 3. `FT` is any number type implicitly convertible to `OffsettingK::FT`. -3. `Straight_skeleton` is `Straight_skeleton_2`. +4. `C` is the container of points in the polygons. +5. `Straight_skeleton` is `Straight_skeleton_2`. If `K != K2` the straight skeleton is converted to `Straight_skeleton_2`. -4. `HoleIterator::value_type` and `Polygon` are `Polygon_2` +6. `HoleIterator::value_type` and `Polygon` are `Polygon_2` or a standard container of `OffsettingK::Point_2` elements. \sa `create_exterior_straight_skeleton_2` \sa `Straight_skeleton_builder_2` */ -template -std::vector< boost::shared_ptr< Polygon_2 > > +template +std::vector< boost::shared_ptr< Polygon_2 > > create_interior_skeleton_and_offset_polygons_2 ( FT offset - , CGAL::Polygon_with_holes poly_with_holes + , CGAL::Polygon_with_holes poly_with_holes , OffsettingK ofk = CGAL::Exact_predicates_inexact_constructions_kernel , SkeletonK ssk @@ -66,20 +67,21 @@ This is equivalent to `arrange_offset_polygons_2(create_interior_skeleton_and_of If `SkeletonK != OffsettingK` the constructed straight skeleton is converted to `Straight_skeleton_2`. 3. `FT` is any number type implicitly convertible to `OffsettingK::FT`. -3. `Straight_skeleton` is `Straight_skeleton_2`. +4. `C` is the container of points in the polygons. +5. `Straight_skeleton` is `Straight_skeleton_2`. If `K != K2` the straight skeleton is converted to `Straight_skeleton_2`. -4. `HoleIterator::value_type` and `Polygon` are `CGAL::Polygon_2` +6. `HoleIterator::value_type` and `Polygon` are `CGAL::Polygon_2` or a standard container of `OffsettingK::Point_2` elements. \sa `create_exterior_straight_skeleton_2` \sa `Straight_skeleton_builder_2` */ -template -std::vector< boost::shared_ptr< Polygon_with_holes_2 > > +template +std::vector< boost::shared_ptr< Polygon_with_holes_2 > > create_interior_skeleton_and_offset_polygons_with_holes_2 ( FT offset - , CGAL::Polygon_2 poly + , CGAL::Polygon_2 poly , OffsettingK ofk = CGAL::Exact_predicates_inexact_constructions_kernel , SkeletonK ssk = CGAL::Exact_predicates_inexact_constructions_kernel ) ; @@ -99,20 +101,21 @@ This is equivalent to `arrange_offset_polygons_2(create_interior_skeleton_and_of If `SkeletonK != OffsettingK` the constructed straight skeleton is converted to `Straight_skeleton_2`. 3. `FT` is any number type implicitly convertible to `OffsettingK::FT`. -3. `Straight_skeleton` is `Straight_skeleton_2`. +4. `C` is the container of points in the polygons. +5. `Straight_skeleton` is `Straight_skeleton_2`. If `K != K2` the straight skeleton is converted to `Straight_skeleton_2`. -4. `HoleIterator::value_type` and `Polygon` are `CGAL::Polygon_2` +6. `HoleIterator::value_type` and `Polygon` are `CGAL::Polygon_2` or a standard container of `OffsettingK::Point_2` elements. \sa `create_exterior_straight_skeleton_2` \sa `Straight_skeleton_builder_2` */ -template -std::vector< boost::shared_ptr< Polygon_with_holes_2 > > +template +std::vector< boost::shared_ptr< Polygon_with_holes_2 > > create_interior_skeleton_and_offset_polygons_with_holes_2 ( FT offset - , CGAL::Polygon_with_holes_2 poly_with_holes + , CGAL::Polygon_with_holes_2 poly_with_holes , OffsettingK ofk = CGAL::Exact_predicates_inexact_constructions_kernel , SkeletonK ssk = CGAL::Exact_predicates_inexact_constructions_kernel ) ; diff --git a/Straight_skeleton_2/doc/Straight_skeleton_2/CGAL/create_straight_skeleton_from_polygon_with_holes_2.h b/Straight_skeleton_2/doc/Straight_skeleton_2/CGAL/create_straight_skeleton_from_polygon_with_holes_2.h index 5ac7570128b..b74ae3ed8e0 100644 --- a/Straight_skeleton_2/doc/Straight_skeleton_2/CGAL/create_straight_skeleton_from_polygon_with_holes_2.h +++ b/Straight_skeleton_2/doc/Straight_skeleton_2/CGAL/create_straight_skeleton_from_polygon_with_holes_2.h @@ -9,9 +9,9 @@ returns a new `Straight_skeleton_2` in the interior of the 2D polygon with ho \sa `Straight_skeleton_builder_2` */ -template + template boost::shared_ptr< Straight_skeleton_2 > -create_interior_straight_skeleton_2 ( Polygon_with_holes poly_with_holes + create_interior_straight_skeleton_2 ( Polygon_with_holes poly_with_holes , K const& k = Exact_predicates_inexact_constructions_kernel ) ; } /* namespace CGAL */ diff --git a/Straight_skeleton_2/examples/Straight_skeleton_2/Create_skeleton_and_offset_polygons_with_holes_2.cpp b/Straight_skeleton_2/examples/Straight_skeleton_2/Create_skeleton_and_offset_polygons_with_holes_2.cpp index fabe27e8116..d475567cbe8 100644 --- a/Straight_skeleton_2/examples/Straight_skeleton_2/Create_skeleton_and_offset_polygons_with_holes_2.cpp +++ b/Straight_skeleton_2/examples/Straight_skeleton_2/Create_skeleton_and_offset_polygons_with_holes_2.cpp @@ -13,7 +13,6 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel K ; typedef K::Point_2 Point ; typedef CGAL::Polygon_2 Polygon_2 ; typedef CGAL::Polygon_with_holes_2 PolygonWithHoles ; -typedef CGAL::Straight_skeleton_2 Ss ; typedef boost::shared_ptr PolygonWithHolesPtr ; diff --git a/Straight_skeleton_2/examples/Straight_skeleton_2/dump_to_eps.h b/Straight_skeleton_2/examples/Straight_skeleton_2/dump_to_eps.h index 8d81c950fbd..b74ef6ac001 100644 --- a/Straight_skeleton_2/examples/Straight_skeleton_2/dump_to_eps.h +++ b/Straight_skeleton_2/examples/Straight_skeleton_2/dump_to_eps.h @@ -4,12 +4,12 @@ namespace CGAL { -template -Bbox_2 bbox_2 ( Polygon_with_holes_2 const& aPolyWH ) +template +Bbox_2 bbox_2 ( Polygon_with_holes_2 const& aPolyWH ) { Bbox_2 rBbox = bbox_2(aPolyWH.outer_boundary().vertices_begin(), aPolyWH.outer_boundary().vertices_end()); - for ( typename Polygon_with_holes_2::Hole_const_iterator hit = aPolyWH.holes_begin() + for ( typename Polygon_with_holes_2::Hole_const_iterator hit = aPolyWH.holes_begin() ; hit != aPolyWH.holes_end() ; ++ hit ) @@ -20,10 +20,10 @@ Bbox_2 bbox_2 ( Polygon_with_holes_2 const& aPolyWH ) } -template -void dump_to_eps( CGAL::Polygon_2 const& aPoly, char const* aType, double aScale, std::ostream& rOut ) +template +void dump_to_eps( CGAL::Polygon_2 const& aPoly, char const* aType, double aScale, std::ostream& rOut ) { - typedef typename CGAL::Polygon_2::const_iterator vertex_const_iterator ; + typedef typename CGAL::Polygon_2::const_iterator vertex_const_iterator ; vertex_const_iterator begin = aPoly.vertices_begin() ; vertex_const_iterator end = aPoly.vertices_end () ; @@ -45,12 +45,12 @@ void dump_to_eps( CGAL::Polygon_2 const& aPoly, char const* aType, double aSc } } -template -void dump_to_eps( CGAL::Polygon_with_holes_2 const& aPWH, char const* aType, double aScale, std::ostream& rOut ) +template +void dump_to_eps( CGAL::Polygon_with_holes_2 const& aPWH, char const* aType, double aScale, std::ostream& rOut ) { dump_to_eps(aPWH.outer_boundary(), aType, aScale, rOut ) ; - for ( typename CGAL::Polygon_with_holes_2::Hole_const_iterator hit = aPWH.holes_begin() + for ( typename CGAL::Polygon_with_holes_2::Hole_const_iterator hit = aPWH.holes_begin() ; hit != aPWH.holes_end() ; ++ hit ) @@ -82,13 +82,13 @@ void dump_to_eps( CGAL::Straight_skeleton_2 const& aSkeleton, char const* aTy } } -template -void dump_to_eps ( CGAL::Polygon_with_holes_2 const& aInput - , std::vector< boost::shared_ptr< CGAL::Polygon_with_holes_2 > > const& aOutput +template +void dump_to_eps ( CGAL::Polygon_with_holes_2 const& aInput + , std::vector< boost::shared_ptr< CGAL::Polygon_with_holes_2 > > const& aOutput , std::ostream& rOut ) { - typedef std::vector< boost::shared_ptr< CGAL::Polygon_with_holes_2 > > PolyWH_vector ; + typedef std::vector< boost::shared_ptr< CGAL::Polygon_with_holes_2 > > PolyWH_vector ; CGAL::Bbox_2 lBbox = CGAL::bbox_2(aInput); @@ -129,8 +129,8 @@ void dump_to_eps ( CGAL::Polygon_with_holes_2 const& } -template -void dump_to_eps ( CGAL::Polygon_with_holes_2 const& aInput +template +void dump_to_eps ( CGAL::Polygon_with_holes_2 const& aInput , CGAL::Straight_skeleton_2 const& aSkeleton , std::ostream& rOut ) diff --git a/Straight_skeleton_2/examples/Straight_skeleton_2/print.h b/Straight_skeleton_2/examples/Straight_skeleton_2/print.h index 832471a9d19..dfcfb101a37 100644 --- a/Straight_skeleton_2/examples/Straight_skeleton_2/print.h +++ b/Straight_skeleton_2/examples/Straight_skeleton_2/print.h @@ -7,23 +7,23 @@ void print_point ( CGAL::Point_2 const& p ) std::cout << "(" << p.x() << "," << p.y() << ")" ; } -template -void print_polygon ( CGAL::Polygon_2 const& poly ) +template +void print_polygon ( CGAL::Polygon_2 const& poly ) { - typedef CGAL::Polygon_2 Polygon ; + typedef CGAL::Polygon_2 Polygon ; std::cout << "Polygon with " << poly.size() << " vertices" << std::endl ; for( typename Polygon::Vertex_const_iterator vi = poly.vertices_begin() ; vi != poly.vertices_end() ; ++ vi ) { print_point(*vi); std::cout << std::endl ; - } + } } -template -void print_polygons ( std::vector< boost::shared_ptr< CGAL::Polygon_2 > > const& polies ) +template +void print_polygons ( std::vector< boost::shared_ptr< CGAL::Polygon_2 > > const& polies ) { - typedef std::vector< boost::shared_ptr< CGAL::Polygon_2 > > PolygonVector ; + typedef std::vector< boost::shared_ptr< CGAL::Polygon_2 > > PolygonVector ; std::cout << "Polygon list with " << polies.size() << " polygons" << std::endl ; @@ -31,10 +31,10 @@ void print_polygons ( std::vector< boost::shared_ptr< CGAL::Polygon_2 > > con print_polygon(**pi); } -template -void print_polygon_with_holes ( CGAL::Polygon_with_holes_2 const& polywh ) +template +void print_polygon_with_holes ( CGAL::Polygon_with_holes_2 const& polywh ) { - typedef CGAL::Polygon_with_holes_2 PolygonWithHoles ; + typedef CGAL::Polygon_with_holes_2 PolygonWithHoles ; std::cout << "Polygon_with_holes having " << polywh.number_of_holes() << " holes" << std::endl ; @@ -44,17 +44,19 @@ void print_polygon_with_holes ( CGAL::Polygon_with_holes_2 const& polywh ) print_polygon(*hi); } -template -void print_polygons_with_holes ( std::vector< boost::shared_ptr< CGAL::Polygon_with_holes_2 > > const& polies ) +template +void print_polygons_with_holes ( std::vector< boost::shared_ptr< CGAL::Polygon_with_holes_2 > > const& polies ) { - typedef std::vector< boost::shared_ptr< CGAL::Polygon_with_holes_2 > > PolygonWithHolesVector ; - + + typedef std::vector< boost::shared_ptr< CGAL::Polygon_with_holes_2 > > PolygonWithHolesVector ; + std::cout << "Polygon_with_holes list with " << polies.size() << " element" << std::endl ; - + for( typename PolygonWithHolesVector::const_iterator pi = polies.begin() ; pi != polies.end() ; ++ pi ) print_polygon_with_holes(**pi); } + template void print_straight_skeleton( CGAL::Straight_skeleton_2 const& ss ) { @@ -80,3 +82,4 @@ void print_straight_skeleton( CGAL::Straight_skeleton_2 const& ss ) std::cout << " " << ( i->is_bisector() ? "bisector" : "contour" ) << std::endl; } } + diff --git a/Straight_skeleton_2/include/CGAL/arrange_offset_polygons_2.h b/Straight_skeleton_2/include/CGAL/arrange_offset_polygons_2.h index f61563a169c..bc69c2b2ad8 100644 --- a/Straight_skeleton_2/include/CGAL/arrange_offset_polygons_2.h +++ b/Straight_skeleton_2/include/CGAL/arrange_offset_polygons_2.h @@ -98,12 +98,12 @@ void arrange_offset_polygons_2 ( InputPolygonPtrIterator aBegin } } -template -std::vector< boost::shared_ptr< Polygon_with_holes_2 > > +template +std::vector< boost::shared_ptr< Polygon_with_holes_2 > > inline -arrange_offset_polygons_2 ( std::vector< boost::shared_ptr< Polygon_2 > > const& aPolygons ) +arrange_offset_polygons_2 ( std::vector< boost::shared_ptr< Polygon_2 > > const& aPolygons ) { - std::vector< boost::shared_ptr< Polygon_with_holes_2 > > rResult ; + std::vector< boost::shared_ptr< Polygon_with_holes_2 > > rResult ; arrange_offset_polygons_2(aPolygons.begin(), aPolygons.end(), std::back_inserter(rResult), K() ) ; diff --git a/Straight_skeleton_2/include/CGAL/create_offset_polygons_2.h b/Straight_skeleton_2/include/CGAL/create_offset_polygons_2.h index 652d19d9ee2..e86767c77f6 100644 --- a/Straight_skeleton_2/include/CGAL/create_offset_polygons_2.h +++ b/Straight_skeleton_2/include/CGAL/create_offset_polygons_2.h @@ -200,17 +200,7 @@ create_offset_polygons_2 ( FT const& aOffset, Skeleton const& aSs, K const& k ) return create_offset_polygons_2(aOffset, aSs, k ) ; } -#if !defined(_MSC_VER) || ( _MSC_VER >= 1500 ) -template -std::vector< boost::shared_ptr< Polygon_2< typename Skeleton::Traits::Kernel > > > -inline -create_offset_polygons_2 ( FT const& aOffset, Skeleton const& aSs ) -{ - typedef typename Skeleton::Traits::Kernel K ; - - return create_offset_polygons_2(aOffset, aSs, K() ) ; -} -#endif + template std::vector< boost::shared_ptr > diff --git a/Straight_skeleton_2/include/CGAL/create_offset_polygons_from_polygon_with_holes_2.h b/Straight_skeleton_2/include/CGAL/create_offset_polygons_from_polygon_with_holes_2.h index 55190c56338..2353f887a0d 100644 --- a/Straight_skeleton_2/include/CGAL/create_offset_polygons_from_polygon_with_holes_2.h +++ b/Straight_skeleton_2/include/CGAL/create_offset_polygons_from_polygon_with_holes_2.h @@ -26,10 +26,10 @@ namespace CGAL { -template -std::vector< boost::shared_ptr< Polygon_2 > > +template +std::vector< boost::shared_ptr< Polygon_2 > > inline -create_interior_skeleton_and_offset_polygons_2 ( FT const& aOffset, Polygon_with_holes_2 const& aPoly, SsK const& ssk ) +create_interior_skeleton_and_offset_polygons_2 ( FT const& aOffset, Polygon_with_holes_2 const& aPoly, SsK const& ssk ) { OfK ofk ; return create_interior_skeleton_and_offset_polygons_2(aOffset @@ -42,19 +42,19 @@ create_interior_skeleton_and_offset_polygons_2 ( FT const& aOffset, Polygon_with } -template -std::vector< boost::shared_ptr< Polygon_2 > > +template +std::vector< boost::shared_ptr< Polygon_2 > > inline -create_interior_skeleton_and_offset_polygons_2 ( FT const& aOffset, Polygon_with_holes_2 const& aPoly ) +create_interior_skeleton_and_offset_polygons_2 ( FT const& aOffset, Polygon_with_holes_2 const& aPoly ) { return create_interior_skeleton_and_offset_polygons_2(aOffset, aPoly, Exact_predicates_inexact_constructions_kernel() ); } -template -std::vector< boost::shared_ptr< Polygon_with_holes_2 > > +template +std::vector< boost::shared_ptr< Polygon_with_holes_2 > > inline create_exterior_skeleton_and_offset_polygons_with_holes_2 ( FT const& aOffset - , Polygon_2 const& aPoly + , Polygon_2 const& aPoly , bool aDontReverseOrientation = false ) { @@ -65,18 +65,19 @@ create_exterior_skeleton_and_offset_polygons_with_holes_2 ( FT const& ); } -template -std::vector< boost::shared_ptr< Polygon_with_holes_2 > > + template +std::vector< boost::shared_ptr< Polygon_with_holes_2 > > inline -create_interior_skeleton_and_offset_polygons_with_holes_2 ( FT const& aOffset, Polygon_with_holes_2 const& aPoly, SsK const& ssk ) +create_interior_skeleton_and_offset_polygons_with_holes_2 ( FT const& aOffset, Polygon_with_holes_2 const& aPoly, SsK const& ssk ) { return arrange_offset_polygons_2(create_interior_skeleton_and_offset_polygons_2(aOffset,aPoly,ssk)); } -template -std::vector< boost::shared_ptr< Polygon_with_holes_2 > > + + template +std::vector< boost::shared_ptr< Polygon_with_holes_2 > > inline -create_interior_skeleton_and_offset_polygons_with_holes_2 ( FT const& aOffset, Polygon_with_holes_2 const& aPoly ) +create_interior_skeleton_and_offset_polygons_with_holes_2 ( FT const& aOffset, Polygon_with_holes_2 const& aPoly ) { return arrange_offset_polygons_2(create_interior_skeleton_and_offset_polygons_2(aOffset,aPoly)); } diff --git a/Straight_skeleton_2/include/CGAL/create_straight_skeleton_from_polygon_with_holes_2.h b/Straight_skeleton_2/include/CGAL/create_straight_skeleton_from_polygon_with_holes_2.h index 8e64947cdd8..e4fa61c31b9 100644 --- a/Straight_skeleton_2/include/CGAL/create_straight_skeleton_from_polygon_with_holes_2.h +++ b/Straight_skeleton_2/include/CGAL/create_straight_skeleton_from_polygon_with_holes_2.h @@ -25,10 +25,10 @@ namespace CGAL { -template +template boost::shared_ptr< Straight_skeleton_2 > inline -create_interior_straight_skeleton_2 ( Polygon_with_holes_2 const& aPolyWithHoles ) +create_interior_straight_skeleton_2 ( Polygon_with_holes_2 const& aPolyWithHoles ) { return create_interior_straight_skeleton_2(aPolyWithHoles.outer_boundary().vertices_begin() ,aPolyWithHoles.outer_boundary().vertices_end () diff --git a/Surface_mesh/doc/Surface_mesh/Surface_mesh.txt b/Surface_mesh/doc/Surface_mesh/Surface_mesh.txt index d3d1c4d39ac..acecd731fff 100644 --- a/Surface_mesh/doc/Surface_mesh/Surface_mesh.txt +++ b/Surface_mesh/doc/Surface_mesh/Surface_mesh.txt @@ -341,7 +341,7 @@ refering to the right vertices. \section sectionSurfaceMeshImplementation Implementation Details As integer type for the indices we have chosen `boost::uint32_t`. On 64 bit operating systems they -take only have the size of a pointer. They still allow to have meshes with 2 billion elements. +take only half the size of a pointer. They still allow to have meshes with 2 billion elements. We use `std::vector` for storing properties. So by accessing the adress of the 0th element of a property map you can access the underlying diff --git a/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h b/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h index 92f742c0da9..ec85adfd8f6 100644 --- a/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h +++ b/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h @@ -2516,7 +2516,7 @@ private: //------------------------------------------------------- private data int n, f, e; std::string off; is >> off; - assert(off == "OFF" || off == "COFF"); + CGAL_assertion(off == "OFF" || off == "COFF"); is >> n >> f >> e; sm.reserve(n,2*f,e); P p; 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 50a6a2d8d36..a788dd0c007 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,6 +1,6 @@ -// Triangulated Surface Mesh Shortest Paths +// Triangulated Surface Mesh Geodesic Shortest Paths -/// \defgroup PkgSurfaceMeshShortestPath Triangulated Surface Mesh Shortest Paths Reference +/// \defgroup PkgSurfaceMeshShortestPath Triangulated Surface Mesh Geodesic Shortest Paths Reference /// \defgroup PkgSurfaceMeshShortestPathConcepts Concepts /// \ingroup PkgSurfaceMeshShortestPath @@ -19,12 +19,11 @@ \cgalPkgPicture{shortestpathspackage-ico.png} \cgalPkgSummaryBegin \cgalPkgAuthors{Stephen Kiazyk, Sébastien Loriot, Éric Colin de Verdière} -\cgalPkgDesc{The package provides methods for computing shortest path on triangulated surface meshes. The algorithm used is based on a paper by Xin and Wang \cgalCite{XinWang2009improvingchenandhan} . The input of this package can be any model of the `FaceListGraph` concept. } +\cgalPkgDesc{The package provides methods for computing geodesic shortest path on triangulated surface meshes. The algorithm used is based on a paper by Xin and Wang \cgalCite{XinWang2009improvingchenandhan} . The input of this package can be any model of the `FaceListGraph` concept. } \cgalPkgManuals{Chapter_Surface_mesh_shortest_path,PkgSurfaceMeshShortestPath} \cgalPkgSummaryEnd \cgalPkgShortInfoBegin \cgalPkgSince{4.7} -\cgalPkgDependsOn{\ref PkgBGLSummary and \ref PkgAABB_treeSummary for some convenience functions} \cgalPkgBib{cgal:klcdv-tsmsp} \cgalPkgLicense{\ref licensesGPL "GPL"} \cgalPkgDemo{Operations on Polyhedra,polyhedron_3.zip} diff --git a/Surface_mesh_shortest_path/doc/Surface_mesh_shortest_path/Surface_mesh_shortest_path.txt b/Surface_mesh_shortest_path/doc/Surface_mesh_shortest_path/Surface_mesh_shortest_path.txt index 083c6b2191f..4d5b8a364f1 100644 --- a/Surface_mesh_shortest_path/doc/Surface_mesh_shortest_path/Surface_mesh_shortest_path.txt +++ b/Surface_mesh_shortest_path/doc/Surface_mesh_shortest_path/Surface_mesh_shortest_path.txt @@ -7,7 +7,7 @@ namespace CGAL { \cgalAutoToc \author Stephen Kiazyk, Sébastien Loriot, and Éric Colin de Verdière -This package provides an algorithm to compute shortest paths on a triangulated surface mesh. +This package provides an algorithm to compute geodesic shortest paths on a triangulated surface mesh. \cgalFigureBegin{Shortest_path_main,shortest_paths_overview.png} Shortest paths on a terrain using one source point represented by a green square. @@ -21,7 +21,7 @@ Using a 2-dimensional approximation would fail to capture anything interesting a The algorithm implemented in this package builds a data structure to efficiently answer queries of the following form: Given a triangulated surface mesh \f$\cal{M}\f$, a set of source points \f$S\f$ on \f$\cal{M}\f$, and a target point \f$t\f$ also on \f$\cal{M}\f$, find a shortest path \f$\lambda\f$ between \f$t\f$ and any element in \f$ S \f$, where \f$\lambda\f$ is constrained to the surface of \f$\cal{M}\f$. -The algorithm used is based on a paper by Xin and Wang \cgalCite{XinWang2009improvingchenandhan}, a fast and practical algorithm for exact computation of shortest paths. It is an extension of earlier results by Chen and Han \cgalCite{ch-spp-96} and Mitchell, Mount, and Papadimitriou \cgalCite{mmp-dgp-87} . +The algorithm used is based on a paper by Xin and Wang \cgalCite{XinWang2009improvingchenandhan}, a fast and practical algorithm for exact computation of geodesic shortest paths. It is an extension of earlier results by Chen and Han \cgalCite{ch-spp-96} and Mitchell, Mount, and Papadimitriou \cgalCite{mmp-dgp-87} . \section Surface_mesh_shortest_pathHowToUse User Interface Description diff --git a/Surface_mesh_shortest_path/include/CGAL/Surface_mesh_shortest_path/Surface_mesh_shortest_path.h b/Surface_mesh_shortest_path/include/CGAL/Surface_mesh_shortest_path/Surface_mesh_shortest_path.h index 630aa3e4126..121c7f92332 100644 --- a/Surface_mesh_shortest_path/include/CGAL/Surface_mesh_shortest_path/Surface_mesh_shortest_path.h +++ b/Surface_mesh_shortest_path/include/CGAL/Surface_mesh_shortest_path/Surface_mesh_shortest_path.h @@ -34,6 +34,7 @@ #include #include +#include #include #include @@ -608,7 +609,7 @@ private: typename Traits::Construct_vertex_2 cv2(m_traits.construct_vertex_2_object()); typename Traits::Construct_triangle_3_along_segment_2_flattening ft3as2(m_traits.construct_triangle_3_along_segment_2_flattening_object()); - assert(cone->m_pendingLeftSubtree != NULL); + CGAL_assertion(cone->m_pendingLeftSubtree != NULL); cone->m_pendingLeftSubtree = NULL; @@ -635,7 +636,7 @@ private: typename Traits::Construct_vertex_2 cv2(m_traits.construct_vertex_2_object()); typename Traits::Construct_triangle_3_along_segment_2_flattening ft3as2(m_traits.construct_triangle_3_along_segment_2_flattening_object()); - assert(cone->m_pendingRightSubtree != NULL); + CGAL_assertion(cone->m_pendingRightSubtree != NULL); cone->m_pendingRightSubtree = NULL; @@ -693,7 +694,7 @@ private: } break; default: - assert(false && "Invalid face location"); + CGAL_assertion(false && "Invalid face location"); // Perhaps hit an assertion that the type must not be external or invalid? } } @@ -1567,11 +1568,11 @@ private: LineLineIntersectResult cgalIntersection = intersect_2(construct_line_2(entrySegment), construct_line_2(rayToLocation)); - assert(cgalIntersection); + CGAL_assertion(bool(cgalIntersection)); Point_2* result = boost::get(&*cgalIntersection); - assert(result && "Error, did not get point intersection on path walk to source"); + CGAL_assertion(result && "Error, did not get point intersection on path walk to source"); FT t0 = parametric_distance_along_segment_2(construct_source_2(entrySegment), construct_target_2(entrySegment), *result); @@ -1616,7 +1617,7 @@ private: current = current->parent(); break; default: - assert(false && "Unhandled node type found in tree"); + CGAL_assertion(false && "Unhandled node type found in tree"); } } } @@ -1771,7 +1772,7 @@ private: break; default: - assert(false && "Invalid face location"); + CGAL_assertion(false && "Invalid face location"); return std::pair(); } } @@ -2044,7 +2045,7 @@ public: std::cout << "Final node count: " << m_currentNodeCount << std::endl; } return; - assert(m_currentNodeCount == 0); + CGAL_assertion(m_currentNodeCount == 0); #endif } diff --git a/Surface_mesh_shortest_path/include/CGAL/Surface_mesh_shortest_path/function_objects.h b/Surface_mesh_shortest_path/include/CGAL/Surface_mesh_shortest_path/function_objects.h index 5e49da4c8ac..c9f9eb64658 100644 --- a/Surface_mesh_shortest_path/include/CGAL/Surface_mesh_shortest_path/function_objects.h +++ b/Surface_mesh_shortest_path/include/CGAL/Surface_mesh_shortest_path/function_objects.h @@ -23,6 +23,7 @@ #include #include #include +#include #include @@ -454,7 +455,7 @@ public: LineLineIntersectResult intersectResult1(m_intersect_2(s1Line, l1)); - assert(intersectResult1); + CGAL_assertion(bool(intersectResult1)); Point_2 p1; @@ -464,19 +465,19 @@ public: { Point_2* result = boost::get(&*intersectResult1); - assert(result && "Intersection should have been a point"); + CGAL_assertion(result && "Intersection should have been a point"); if (result) { t1 = m_parametric_distance_along_segment_2(s1, *result); p1 = *result; - assert(t1 >= FT(-0.00001) && t1 <= FT(1.00001)); + CGAL_assertion(t1 >= FT(-0.00001) && t1 <= FT(1.00001)); } } LineLineIntersectResult intersectResult2 = m_intersect_2(s2Line, l2); - assert(intersectResult2); + CGAL_assertion(bool(intersectResult2)); FT t2; Point_2 p2; @@ -485,13 +486,13 @@ public: { Point_2* result = boost::get(&*intersectResult2); - assert(result && "Intersection should have been a point"); + CGAL_assertion(result && "Intersection should have been a point"); if (result) { t2 = m_parametric_distance_along_segment_2(s2, *result); p2 = *result; - assert(t2 >= FT(-0.00001) && t2 <= FT(1.00001)); + CGAL_assertion(t2 >= FT(-0.00001) && t2 <= FT(1.00001)); } } @@ -589,7 +590,7 @@ public: CGAL::Orientation baseOrientation = m_orientation_2(m_construct_vertex_2(baseFace2, 0), m_construct_vertex_2(baseFace2, 2), m_construct_vertex_2(baseFace2, 1)); - assert(baseOrientation != CGAL::COLLINEAR); + CGAL_assertion(baseOrientation != CGAL::COLLINEAR); do { diff --git a/Surface_mesh_simplification/doc/Surface_mesh_simplification/PackageDescription.txt b/Surface_mesh_simplification/doc/Surface_mesh_simplification/PackageDescription.txt index a2cc7b8e568..3944e8ab49c 100644 --- a/Surface_mesh_simplification/doc/Surface_mesh_simplification/PackageDescription.txt +++ b/Surface_mesh_simplification/doc/Surface_mesh_simplification/PackageDescription.txt @@ -13,8 +13,6 @@ \cgalPkgSummaryEnd \cgalPkgShortInfoBegin \cgalPkgSince{3.3} -\cgalPkgDependsOn{\ref PkgBGLSummary} -\cgalPkgDependsOn{\ref PkgPolyhedronSummary} \cgalPkgBib{cgal:c-tsms-12} \cgalPkgLicense{\ref licensesGPL "GPL"} \cgalPkgDemo{Operations on Polyhedra,polyhedron_3.zip} diff --git a/Surface_mesh_skeletonization/benchmark/Surface_mesh_skeletonization/CMakeLists.txt b/Surface_mesh_skeletonization/benchmark/Surface_mesh_skeletonization/CMakeLists.txt index 72377a6abf9..f83982de324 100644 --- a/Surface_mesh_skeletonization/benchmark/Surface_mesh_skeletonization/CMakeLists.txt +++ b/Surface_mesh_skeletonization/benchmark/Surface_mesh_skeletonization/CMakeLists.txt @@ -65,4 +65,5 @@ endif(NOT EIGEN3_FOUND) include( CGAL_CreateSingleSourceCGALProgram ) create_single_source_cgal_program( "solver_benchmark.cpp" ) +create_single_source_cgal_program( "mcf_scale_invariance.cpp" ) diff --git a/Surface_mesh_skeletonization/benchmark/Surface_mesh_skeletonization/mcf_scale_invariance.cpp b/Surface_mesh_skeletonization/benchmark/Surface_mesh_skeletonization/mcf_scale_invariance.cpp new file mode 100644 index 00000000000..034834bf7ad --- /dev/null +++ b/Surface_mesh_skeletonization/benchmark/Surface_mesh_skeletonization/mcf_scale_invariance.cpp @@ -0,0 +1,111 @@ +#include +#include +#include +#include +#include + +#include +#include + +typedef CGAL::Simple_cartesian Kernel; +typedef Kernel::Point_3 Point; +typedef CGAL::Polyhedron_3 Polyhedron; + +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; + +typedef CGAL::Mean_curvature_flow_skeletonization Skeletonization; +typedef Skeletonization::Skeleton Skeleton; + +typedef Skeleton::vertex_descriptor Skeleton_vertex; +typedef Skeleton::edge_descriptor Skeleton_edge; + + +int main(int argc, char* argv[]) +{ + std::ifstream input((argc>1)?argv[1]:"data/elephant.off"); + Polyhedron tmesh; + input >> tmesh; + + //scale off + double factor = atof(argv[2]); + + CGAL::Bbox_3 bbox1=CGAL::bbox_3(tmesh.points_begin(), tmesh.points_end()); + Kernel::Vector_3 to_origin(-bbox1.xmin(), -bbox1.ymin(), -bbox1.zmin()); + + for(Polyhedron::Point_iterator pit=tmesh.points_begin(), + pit_end=tmesh.points_end();pit!=pit_end;++pit) + { + Point new_point = *pit+to_origin; + double x=new_point.x(); + double y=new_point.y(); + double z=new_point.z(); + + x = x * factor; + y = y * factor; + z = z * factor; + + *pit=Point(x, y, z) - to_origin ; + } + + CGAL::Bbox_3 bbox=CGAL::bbox_3(tmesh.points_begin(), tmesh.points_end()); + double l=std::sqrt( + CGAL::square(bbox.xmin()-bbox.xmax()) + + CGAL::square(bbox.ymin()-bbox.ymax()) + + CGAL::square(bbox.zmin()-bbox.zmax()) + ); + std::cout << "l is " << l << "\n"; + Skeleton skeleton; + Skeletonization mcs(tmesh); + + mcs.set_is_medially_centered(false); //just to be sure + //~ mcs.set_quality_speed_tradeoff(0.1 * std::pow(l,-0.01)); + mcs.set_quality_speed_tradeoff(20); + //~ mcs.set_medially_centered_speed_tradeoff(0.2 * std::pow(l,-0.75)); + + // Iteratively apply step 1 to 3 until convergence. + mcs.contract_until_convergence(); + + // Convert the contracted mesh into a curve skeleton and + // get the correspondent surface points + mcs.convert_to_skeleton(skeleton); + + std::cout << "Number of vertices of the skeleton: " << boost::num_vertices(skeleton) << "\n"; + std::cout << "Number of edges of the skeleton: " << boost::num_edges(skeleton) << "\n"; + + +//scale skelton + BOOST_FOREACH(Skeleton_vertex v, vertices(skeleton)) + { + Point new_point = skeleton[v].point+to_origin; + double x=new_point.x(); + double y=new_point.y(); + double z=new_point.z(); + + x = x / factor; + y = y / factor; + z = z / factor; + + skeleton[v].point=Point(x, y, z)-to_origin; + } + + // Output all the edges of the skeleton. + std::stringstream ss; + ss << "skel." << factor << ".cgal"; + std::ofstream output(ss.str().c_str()); + BOOST_FOREACH(Skeleton_edge e, edges(skeleton)) + { + const Point& s = skeleton[source(e, skeleton)].point; + const Point& t = skeleton[target(e, skeleton)].point; + output << "2 "<< s << " " << t << "\n"; + } + output.close(); + + // Output skeleton points and the corresponding surface points + output.open("correspondance.cgal"); + BOOST_FOREACH(Skeleton_vertex v, vertices(skeleton)) + BOOST_FOREACH(vertex_descriptor vd, skeleton[v].vertices) + output << "2 " << skeleton[v].point << " " << get(CGAL::vertex_point, tmesh, vd) << "\n"; + + return 0; +} + 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 0e74b7a641a..7abc05af66f 100644 --- a/Surface_mesh_skeletonization/include/CGAL/Mean_curvature_flow_skeletonization.h +++ b/Surface_mesh_skeletonization/include/CGAL/Mean_curvature_flow_skeletonization.h @@ -450,9 +450,9 @@ public: /// \cgalAdvancedBegin /// Controls the velocity of movement and approximation quality: - /// increasing this value makes the mean curvature flow based contraction converge + /// decreasing this value makes the mean curvature flow based contraction converge /// faster, but results in a skeleton of lower quality. - /// This parameter corresponds to \f$ w_L/w_H \f$ in the original publication. + /// This parameter corresponds to \f$ w_H \f$ in the original publication. /// \cgalAdvancedEnd double quality_speed_tradeoff() { @@ -470,10 +470,10 @@ public: /// \cgalAdvancedBegin /// Controls the smoothness of the medial approximation: - /// increasing this value results in a skeleton closer - /// to the medial axis, but slows down the speed of contraction. + /// increasing this value results in a (less smooth) skeleton closer + /// to the medial axis, as well as a lower convergence speed. /// It is only used if `is_medially_centered()==true`. - /// This parameter corresponds to \f$ w_L/w_M \f$ in the original publication. + /// This parameter corresponds to \f$ w_M \f$ in the original publication. /// \cgalAdvancedEnd double medially_centered_speed_tradeoff() { diff --git a/Surface_mesher/doc/Surface_mesher/PackageDescription.txt b/Surface_mesher/doc/Surface_mesher/PackageDescription.txt index a675d0f22a3..9bc0d7cb8a9 100644 --- a/Surface_mesher/doc/Surface_mesher/PackageDescription.txt +++ b/Surface_mesher/doc/Surface_mesher/PackageDescription.txt @@ -35,6 +35,7 @@ \cgalPkgSummaryEnd \cgalPkgShortInfoBegin \cgalPkgSince{3.2} +\cgalPkgDependsOn{\ref PkgTriangulation3Summary} \cgalPkgBib{cgal:ry-smg} \cgalPkgLicense{\ref licensesGPL} \cgalPkgDemo{Surface Mesh Generator,surface_mesher.zip} diff --git a/Triangulation_2/benchmark/Triangulation_2/Delaunay_remove.cpp b/Triangulation_2/benchmark/Triangulation_2/Delaunay_remove.cpp index 0d95e4893ac..5d3ef4595e9 100644 --- a/Triangulation_2/benchmark/Triangulation_2/Delaunay_remove.cpp +++ b/Triangulation_2/benchmark/Triangulation_2/Delaunay_remove.cpp @@ -3,7 +3,6 @@ #include #include - #include #include #include @@ -11,11 +10,12 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel K; typedef CGAL::Delaunay_triangulation_2 Delaunay; +typedef Delaunay::Finite_vertices_iterator FVI; +typedef Delaunay::Vertex_handle Vertex_handle; typedef K::Point_2 Point; typedef CGAL::Creator_uniform_2 Creator; - int main(int argc, char **argv) { int n=1000000; @@ -34,10 +34,14 @@ int main(int argc, char **argv) double res=0; for (int r=0;r vertices; + for(FVI fvi = delaunay.finite_vertices_begin(); fvi != delaunay.finite_vertices_end();++fvi){ + vertices.push_back(fvi); + } CGAL::Timer t; t.start(); - for (int k=0;kpos; ++pos; - assert(vbb == *pos); + CGAL_triangulation_assertion(vbb == *pos); while(!pos.input()){ ++pos; } @@ -483,8 +483,9 @@ std::size_t Polyline_constraint_hierarchy_2:: number_of_enclosing_constraints(T va, T vb) const { - Context_list* hcl; - if (! get_contexts(va,vb,hcl)) CGAL_triangulation_assertion(false); + Context_list* hcl = NULL; + CGAL_triangulation_assertion_code( bool found = ) get_contexts(va,vb,hcl); + CGAL_triangulation_assertion(found); return hcl->size(); } diff --git a/Triangulation_2/include/CGAL/Triangulation_2.h b/Triangulation_2/include/CGAL/Triangulation_2.h index 5f32861ee54..2ee47f2f4ee 100644 --- a/Triangulation_2/include/CGAL/Triangulation_2.h +++ b/Triangulation_2/include/CGAL/Triangulation_2.h @@ -1784,14 +1784,13 @@ fill_hole_delaunay(std::list & first_hole) Face_handle f, ff, fn; int i, ii, in; Hole_list hole_list; - Hole hole; hole_list.push_front(first_hole); while( ! hole_list.empty()) { - hole = hole_list.front(); - hole_list.pop_front(); + Hole& hole = hole_list.front(); + typename Hole::iterator hit = hole.begin(); // if the hole has only three edges, create the triangle @@ -1801,6 +1800,7 @@ fill_hole_delaunay(std::list & first_hole) ff = (* ++hit).first; ii = (*hit).second; fn = (* ++hit).first; in = (*hit).second; create_face(f,i,ff,ii,fn,in); + hole_list.pop_front(); continue; } @@ -1879,7 +1879,6 @@ fill_hole_delaunay(std::list & first_hole) newf = create_face(ff,ii,fn,in); hole.pop_front(); hole.push_front(Edge( newf,1)); - hole_list.push_front(hole); } else{ fn = (hole.back()).first; @@ -1888,7 +1887,6 @@ fill_hole_delaunay(std::list & first_hole) newf = create_face(fn,in,ff,ii); hole.pop_back(); hole.push_back(Edge(newf,1)); - hole_list.push_front(hole); } else{ // split the hole in two holes @@ -1903,7 +1901,6 @@ fill_hole_delaunay(std::list & first_hole) hole.push_front(Edge( newf,1)); new_hole.push_front(Edge( newf,0)); - hole_list.push_front(hole); hole_list.push_front(new_hole); } } @@ -1928,13 +1925,10 @@ fill_hole_delaunay(std::list & first_hole, OutputItFaces fit) Face_handle f, ff, fn; int i, ii, in; Hole_list hole_list; - Hole hole; - hole_list.push_front(first_hole); while(!hole_list.empty()) { - hole = hole_list.front(); - hole_list.pop_front(); + Hole& hole = hole_list.front(); typename Hole::iterator hit = hole.begin(); if (hole.size() == 3) { @@ -1944,6 +1938,7 @@ fill_hole_delaunay(std::list & first_hole, OutputItFaces fit) fn = (* ++hit).first; in = (*hit).second; Face_handle newf = create_face(f,i,ff,ii,fn,in); *fit++ = newf; + hole_list.pop_front(); continue; } @@ -2001,7 +1996,6 @@ fill_hole_delaunay(std::list & first_hole, OutputItFaces fit) newf = create_face(ff,ii,fn,in); hole.pop_front(); hole.push_front(Edge( newf,1)); - hole_list.push_front(hole); } else { fn = (hole.back()).first; in = (hole.back()).second; @@ -2009,7 +2003,6 @@ fill_hole_delaunay(std::list & first_hole, OutputItFaces fit) newf = create_face(fn,in,ff,ii); hole.pop_back(); hole.push_back(Edge(newf,1)); - hole_list.push_front(hole); } else { newf = create_face(ff,ii,v2); Hole new_hole; @@ -2020,7 +2013,6 @@ fill_hole_delaunay(std::list & first_hole, OutputItFaces fit) } hole.push_front(Edge(newf, 1)); new_hole.push_front(Edge(newf, 0)); - hole_list.push_front(hole); hole_list.push_front(new_hole); } } diff --git a/Triangulation_3/doc/Triangulation_3/PackageDescription.txt b/Triangulation_3/doc/Triangulation_3/PackageDescription.txt index f20577bc02b..a88e0da5726 100644 --- a/Triangulation_3/doc/Triangulation_3/PackageDescription.txt +++ b/Triangulation_3/doc/Triangulation_3/PackageDescription.txt @@ -25,6 +25,7 @@ \cgalPkgSummaryEnd \cgalPkgShortInfoBegin \cgalPkgSince{2.1} +\cgalPkgDependsOn{\ref PkgTDS3Summary} \cgalPkgBib{cgal:pt-t3} \cgalPkgLicense{\ref licensesGPL "GPL" } \cgalPkgDemo{3D Triangulations,triangulation_3.zip} diff --git a/Visibility_2/doc/OLD/ArrExtensionTraits_2.h b/Visibility_2/doc/OLD/ArrExtensionTraits_2.h deleted file mode 100644 index 333689eeab5..00000000000 --- a/Visibility_2/doc/OLD/ArrExtensionTraits_2.h +++ /dev/null @@ -1,87 +0,0 @@ -/*! -\ingroup PkgVisibility_2Concepts -\cgalConcept - -All visibility polgyon algorithms provided in \cgal are parameterized with a traits class 'Traits', which defines the extension of Arrangement_2 the output will have. - -\cgalHasModel `CGAL::Arr_extension_default_traits_2` - -\sa `Visibility_2` - -*/ -class ArrExtensionTraits_2 { -public : - - - -/// \name Types -/// @{ - -/*! - * The vertex handle type on which the functors will operate. - */ -typedef Hidden_type Vertex_handle; - -/*! - * The halfedge handle type on which the functors will operate. - */ -typedef Hidden_type Halfedge_handle; - -/*! - * The face handle type on which the functors will operate. - */ -typedef Hidden_type Face_handle; - -/*! - * Add auxiliary information to vertex. - */ -typedef Hidden_type Extend_vertex; - -/*! - * Add auxiliary information to halfedge. - */ -typedef Hidden_type Extend_halfedge; - -/*! - * Add auxiliary information to face. - */ -typedef Hidden_type Extend_face; - -/// \name Creation -/// @{ -/*! -default creator -*/ -ArrExtensionTraits_2 (); - -/*! -copy creator -*/ -ArrExtensionTraits_2 (const ArrExtensionTraits_2& Traits); - -/// @} - -/// \name Operations -/// The following member functions to create instances of the above predicate oject types. -/// @{ - -/*! - * - */ -Extend_vertex extend_vertex_object(); - -/*! - * - */ -Extend_halfedge extend_halfedge_object(); - -/*! - * - */ -Extend_face extend_face_object(); - -/// @} - - -} - diff --git a/Visibility_2/doc/OLD/Arr_extension_default_traits_2.h b/Visibility_2/doc/OLD/Arr_extension_default_traits_2.h deleted file mode 100644 index 40d8baa9328..00000000000 --- a/Visibility_2/doc/OLD/Arr_extension_default_traits_2.h +++ /dev/null @@ -1,80 +0,0 @@ -namespace CGAL { - -/*! -\ingroup PkgArrExtensionTraits - -The class `Arr_extension_default_traits_2` serves as a traits class for all visibility polygon calculation function. -This class extends the vertex, halfedges and face. User also may define their own traits class to choose which to extend. - -\cgalModels `ArrExtensionTraits_2` - -\sa `CGAL::Arr_extended_dcel` - - -*/ - -template< typename A_ > -class Arr_extension_default_traits_2 { -public: - - /// \name Types - /// @{ - /*! - * - */ - typedef A_::Vertex_iterator Vertex_iterator; - - /*! - * - */ - typedef A_::Halfedge_iterator Halfedge_iterator; - - /*! - * - */ - typedef A_::Fayce_iterator Face_iterator; - - /// @} - - /// \name Functor classes - /// @{ - - /*! - * - */ - class Extend_vertex; - - /*! - * - */ - class Extend_halfedge; - - /*! - * - */ - class Extend_face; - /// @} - - /// \name Operations - /// @{ - - /*! - * - */ - Extend_vertex extend_vertex_object(); - - /*! - * - */ - Extend_halfedge extend_halfedge_object(); - - /*! - * - */ - Extend_face extend_face_object(); - - /// @} - -}; - -} /* end namespace CGAL */ diff --git a/Visibility_2/doc/OLD/Preprocessed_rotational_sweep_visibility_2.h b/Visibility_2/doc/OLD/Preprocessed_rotational_sweep_visibility_2.h deleted file mode 100644 index 3f80ec8e27c..00000000000 --- a/Visibility_2/doc/OLD/Preprocessed_rotational_sweep_visibility_2.h +++ /dev/null @@ -1,158 +0,0 @@ -namespace CGAL { -/*! -\ingroup PkgVisibility_2Classes - -\brief This class is a model of the concept `Visibility_2` can answer visibility queries within -a polygon that may have holes. - -\details The class template comprises the implementation of the algorithm of Takao Asano and Tetsuo Asano \cite aaghi-vpsesp-85. The algorithm, as the name of the class template suggests, requires preprocessing. The preprocessing takes \f$ O(n^2)\f$ time and \f$ O(n^2)\f$ space, which reduces the query time to \f$O(n)\f$. - -The main preprocessing step is the dualization of all vertices of the input arrangment into an arrangment of lines. -Computing this arrangement takes \f$ O(n^2)\f$ time and \f$ O(n^2)\f$ space. -Using this arrangment it is possible to retrieve the angular order of all vertices around -a query point, which is one of the essential steps to achive linear query time. For more details we refer to \cite aaghi-vpsesp-85. - - - -\tparam Arrangement_2 is the type of input polygonal environment and output visibility polygon. - -\tparam RegularizationCategory indicates whether the output should be regularized. It can be -specified by one of the following: ::Tag_true or ::Tag_false, where ::Tag_false is the default value. - - -\cgalModels `Visibility_2` - -\sa `CGAL::Simple_polygon_visibility_2` -\sa `CGAL::Rotational_sweep_visibility_2` -\sa `CGAL::Triangular_expansion_visibility_2` - - -*/ -template -class Preprocessed_rotational_sweep_visibility_2 { -public: - -/// \name Types -/// @{ - - /*! - The type of the input arrangement. - */ - typedef Arrangement_2 Arrangement_2; - - /*! - The type of the output arrangement. - */ - typedef Arrangement_2 Visibility_arrangement_2; - - /*! - The 2D point type used for the queries. - */ - typedef Arrangement_2::Point_2 Point_2; - - /*! - Face_const_handle type of the input arrangement. - */ - typedef Arrangement_2::Face_const_handle Face_const_handle; - - /*! - Halfedge_const_handle type of the input arrangement. - */ - typedef Arrangement_2::Halfedge_const_handle Halfedge_const_handle; - - - -/// @} - - -/// \name Tags -/// @{ - /*! - identifies whether the regularized visibility area is computed. - */ - typedef RegularizationCategory Regularization_category; - - /*! - identifies that the class supports general polygons (i.e.\ with holes). - */ - typedef ::Tag_true Supports_general_polygon_category; - - /*! - identifies that the class supports general simple polygons. - */ - typedef ::Tag_true Supports_simple_polygon_category; -/// @} - - - -/// \name Constructors -/// @{ - -/*! -Default constructor creates an empty `Preprocessed_rotational_sweep_visibility_2` object that is not -attached to any arrangement yet. -*/ -Preprocessed_rotational_sweep_visibility_2(); - -/*! -Constructs a `Preprocessed_rotational_sweep_visibility_2` object that is attached to `arr`. -*/ -Preprocessed_rotational_sweep_visibility_2(const Arrangement_2& arr); - -/// @} - -/// \name functions -/// @{ - -/*! -Returns whether an arrangement is attached to the visibility object -*/ - bool is_attached() const; - -/*! -Attaches the given arrangement to the visibility object and applies preprocessing. -In case the object is already attached to another arrangement, -the visibility object gets detached before being attached to `arr`. -*/ - void attach(const Arrangement_2& arr); - -/*! -Detaches the arrangement from the visibility object it is currently attached to -*/ - void detach(); - -/*! -Access to the attached arrangement -*/ - const Arrangement_2& arr() const; - -/*! -Computes the visibility region of `q` in the -face `f` of the arrangement that is attached to the visibility object. -The visibility region of `q` will be stored in `out_arr`. -\param q is the query point -\param f is the face of the arrangement in which the visibility region is computed -\param out_arr is the output arrangement -\pre `f` is a face of `arr()` and represents a valid polygon. -\pre `q` is in the interior of the given face `f` -\return a handle to the face in `out_arr` that represents the visibility region -*/ - typename Visibility_arrangement_2::Face_handle compute_visibility(const Point_2& q, const Face_const_handle f, Visibility_arrangement_2& out_arr) const; - -/*! -Computes the visibility region of `q` that is on `e`. If `q` is an interior point of `e`, the computed visibility region is restricted to the halfplane indicated by `e`. If `q` is an endpoint of `e`, the visibility region is restricted by `e` and its next. -The visibility region of `q` will be stored in `out_arr`. -\param q is the query point -\param e the halfedge on which `q` is located -\param out_arr is the output arrangement -\pre `e` is a halfedge of `arr()` -\pre `q` is on `e` -\pre `q` equals to `e->target()->point()` if `q` is an endpoint of `e` -\return a handle to the face in `out_arr` that represents the visibility region -*/ - typename Visibility_arrangement_2::Face_handle compute_visibility(const Point_2& q, const Halfedge_const_handle e, Visibility_arrangement_2& out_arr) const; - -/// @} - -}; /* end Visibility_2 */ -} /* namespace CGAL */ diff --git a/Visibility_2/doc/Visibility_2/CGAL/Rotational_sweep_visibility_2.h b/Visibility_2/doc/Visibility_2/CGAL/Rotational_sweep_visibility_2.h index 8a384730b7d..f11a3ab543a 100644 --- a/Visibility_2/doc/Visibility_2/CGAL/Rotational_sweep_visibility_2.h +++ b/Visibility_2/doc/Visibility_2/CGAL/Rotational_sweep_visibility_2.h @@ -9,11 +9,11 @@ namespace CGAL { \tparam Arrangement_2_ is the type used to represent the input environment. -It must be an instance of CGAL::Arrangement_2, where its CGAL::Arrangement_2::Traits_2 must be an instance of -CGAL::Arr_segment_traits_2, or of CGAL::Arr_non_caching_segment_traits_2. +It must be an instance of `CGAL::Arrangement_2`, where its `CGAL::Arrangement_2::Traits_2` must be an instance of +`CGAL::Arr_segment_traits_2`, or of `CGAL::Arr_non_caching_segment_traits_2`. \tparam RegularizationCategory indicates whether the output should be regularized. It can be -specified by one of the following: ::Tag_true or ::Tag_false, where ::Tag_false is the default value. +specified by one of the following: `#Tag_true` or `#Tag_false`, where `#Tag_false` is the default value. @@ -47,12 +47,12 @@ public: /*! See \ref Visibility_2::Supports_general_polygon_category. */ - typedef ::Tag_true Supports_general_polygon_category; + typedef Tag_true Supports_general_polygon_category; /*! See \ref Visibility_2::Supports_simple_polygon_category. */ - typedef ::Tag_true Supports_simple_polygon_category; + typedef Tag_true Supports_simple_polygon_category; /// @} diff --git a/Visibility_2/doc/Visibility_2/CGAL/Simple_polygon_visibility_2.h b/Visibility_2/doc/Visibility_2/CGAL/Simple_polygon_visibility_2.h index 22095c24516..c1a906e1433 100644 --- a/Visibility_2/doc/Visibility_2/CGAL/Simple_polygon_visibility_2.h +++ b/Visibility_2/doc/Visibility_2/CGAL/Simple_polygon_visibility_2.h @@ -16,11 +16,11 @@ algorithm are \f$ O(n) \f$ even in case of degeneracies such as needles, where \ is the number of the vertices of the polygon. \tparam Arrangement_2_ is the type used to represent the input environment. -It must be an instance of CGAL::Arrangement_2, where its CGAL::Arrangement_2::Traits_2 must be an instance of -CGAL::Arr_segment_traits_2, or of CGAL::Arr_non_caching_segment_traits_2. +It must be an instance of `CGAL::Arrangement_2`, where its `CGAL::Arrangement_2::Traits_2` must be an instance of +`CGAL::Arr_segment_traits_2`, or of `CGAL::Arr_non_caching_segment_traits_2`. \tparam RegularizationCategory indicates whether the output should be regularized. It can be -specified by one of the following: ::Tag_true or ::Tag_false, where ::Tag_false is the default value. +specified by one of the following: `#Tag_true` or `#Tag_false`, where `#Tag_false` is the default value. \cgalModels `Visibility_2` @@ -52,12 +52,12 @@ public: /*! See \ref Visibility_2::Supports_general_polygon_category. */ - typedef ::Tag_false Supports_general_polygon_category; + typedef Tag_false Supports_general_polygon_category; /*! See \ref Visibility_2::Supports_simple_polygon_category. */ - typedef ::Tag_true Supports_simple_polygon_category; + typedef Tag_true Supports_simple_polygon_category; /// @} diff --git a/Visibility_2/doc/Visibility_2/CGAL/Triangular_expansion_visibility_2.h b/Visibility_2/doc/Visibility_2/CGAL/Triangular_expansion_visibility_2.h index 6a8b5fcccf8..ec9f8fdb981 100644 --- a/Visibility_2/doc/Visibility_2/CGAL/Triangular_expansion_visibility_2.h +++ b/Visibility_2/doc/Visibility_2/CGAL/Triangular_expansion_visibility_2.h @@ -11,11 +11,11 @@ The query time is \f$ O(nh)\f$, where \f$ h \f$ is the number of holes+1 of inpu \tparam Arrangement_2_ is the type used to represent the input environment. -It must be an instance of CGAL::Arrangement_2, where its CGAL::Arrangement_2::Traits_2 must be an instance of -CGAL::Arr_segment_traits_2, or of CGAL::Arr_non_caching_segment_traits_2. +It must be an instance of `CGAL::Arrangement_2`, where its `CGAL::Arrangement_2::Traits_2` must be an instance of +`CGAL::Arr_segment_traits_2`, or of `CGAL::Arr_non_caching_segment_traits_2`. \tparam RegularizationCategory indicates whether the output should be regularized. It can be -specified by one of the following: ::Tag_true or ::Tag_false, where ::Tag_false is the default value. +specified by one of the following: `#Tag_true` or `#Tag_false`, where `#Tag_false` is the default value. \cgalModels `Visibility_2` @@ -49,12 +49,12 @@ public: /*! See \ref Visibility_2::Supports_general_polygon_category. */ - typedef ::Tag_true Supports_general_polygon_category; + typedef Tag_true Supports_general_polygon_category; /*! See \ref Visibility_2::Supports_simple_polygon_category. */ - typedef ::Tag_true Supports_simple_polygon_category; + typedef Tag_true Supports_simple_polygon_category; /// @} diff --git a/Visibility_2/doc/Visibility_2/Concepts/Visibility_2.h b/Visibility_2/doc/Visibility_2/Concepts/Visibility_2.h index cc7f935ee2f..7ce62e3315e 100644 --- a/Visibility_2/doc/Visibility_2/Concepts/Visibility_2.h +++ b/Visibility_2/doc/Visibility_2/Concepts/Visibility_2.h @@ -42,12 +42,12 @@ public: /// \name Tags /// @{ /*! - identifies whether the regularized visibility area is computed (either \ref CGAL::Tag_true or \ref CGAL::Tag_false). + identifies whether the regularized visibility area is computed (either `#Tag_true` or `#Tag_false`). */ typedef unspecified_type Regularization_category; /*! - identifies whether general polygons (with holes) are supported (either \ref CGAL::Tag_true or \ref CGAL::Tag_false). + identifies whether general polygons (with holes) are supported (either `#Tag_true` or `#Tag_false`). A general polygon is represented by a face \f$ f \f$ with no isolated vertex and any edge of \f$ f \f$ separates \f$ f \f$ from another face. Note that this allows \f$ f \f$ to touch a vertex from several sides. @@ -55,7 +55,7 @@ public: typedef unspecified_type Supports_general_polygon_category; /*! - identifies whether simple polygons are supported (either \ref CGAL::Tag_true or \ref CGAL::Tag_false). + identifies whether simple polygons are supported (either `#Tag_true` or `#Tag_false`). A simple polygon is represented by a face \f$ f \f$ with no holes, no isolated vertex and any edge of \f$ f \f$ separates \f$ f \f$ from another face. @@ -114,8 +114,8 @@ The visibility region of `q` is stored in `out_arr`, that is, all features but the unbounded face of `out_arr` represent the visibility region. \tparam VisibilityArrangement_2 is the type of the output arrangement representing the visibility polygon. -It must be an instance of CGAL::Arrangement_2, where its CGAL::Arrangement_2::Traits_2 -must be mutual convertible to Visibility_2::Traits_2. +It must be an instance of `CGAL::Arrangement_2`, where its `CGAL::Arrangement_2::Traits_2` +must be mutual convertible to `VisibilityArrangement_2::Traits_2`. \param q is the query point \param f is the face of the arrangement in which the visibility region is computed @@ -138,8 +138,8 @@ The visibility region of `q` is stored in `out_arr`, that is, all features but the unbounded face of `out_arr` represent the visibility region. \tparam VisibilityArrangement_2 is the type of the output arrangement representing the visibility polygon. -It must be an instance of CGAL::Arrangement_2, where its CGAL::Arrangement_2::Traits_2 -must be mutual convertible to Visibility_2::Traits_2. +It must be an instance of `CGAL::Arrangement_2`, where its `CGAL::Arrangement_2::Traits_2` +must be mutual convertible to `VisibilityArrangement_2::Traits_2`. \param q is the query point \param e the halfedge on which `q` is located \param out_arr is the output arrangement diff --git a/Visibility_2/doc/Visibility_2/PackageDescription.txt b/Visibility_2/doc/Visibility_2/PackageDescription.txt index d02550f511e..3b3a2ad8672 100644 --- a/Visibility_2/doc/Visibility_2/PackageDescription.txt +++ b/Visibility_2/doc/Visibility_2/PackageDescription.txt @@ -3,6 +3,9 @@ /// \defgroup PkgVisibility_2Concepts Concepts /// \ingroup PkgVisibility_2 +/// \defgroup PkgVisibility_2Classes Classes +/// \ingroup PkgVisibility_2 + /*! \addtogroup PkgVisibility_2 \cgalPkgDescriptionBegin{2D Visibility Computation,PkgVisibility_2Summary} @@ -15,6 +18,8 @@ the visibility area of a point within polygonal regions in two dimensions.} \cgalPkgSummaryEnd \cgalPkgShortInfoBegin \cgalPkgSince{4.7} +\cgalPkgDependsOn{\ref PkgArrangement2Summary} +\cgalPkgDependsOn{\ref PkgTriangulation2Summary} \cgalPkgBib{hhb-visibility-2} \cgalPkgLicense{\ref licensesGPL "GPL"} \cgalPkgShortInfoEnd diff --git a/Visibility_2/include/CGAL/Rotational_sweep_visibility_2.h b/Visibility_2/include/CGAL/Rotational_sweep_visibility_2.h index b73060ab28c..46b34a44b85 100644 --- a/Visibility_2/include/CGAL/Rotational_sweep_visibility_2.h +++ b/Visibility_2/include/CGAL/Rotational_sweep_visibility_2.h @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -811,7 +812,7 @@ private: Ccb_halfedge_const_circulator curr = fh->outer_ccb(); Ccb_halfedge_const_circulator circ = curr; do { - assert(curr->face() == fh); + CGAL_assertion(curr->face() == fh); input_neighbor_f(curr); } while (++curr != circ); @@ -819,7 +820,7 @@ private: for (hi = fh->holes_begin(); hi != fh->holes_end(); ++hi) { Ccb_halfedge_const_circulator curr = *hi, circ = *hi; do { - assert(curr->face() == fh); + CGAL_assertion(curr->face() == fh); input_neighbor_f(curr); } while (++curr != circ); } @@ -847,7 +848,7 @@ private: Ccb_halfedge_const_circulator curr = fh->outer_ccb(); Ccb_halfedge_const_circulator circ = curr; do { - assert(curr->face() == fh); + CGAL_assertion(curr->face() == fh); input_edge(curr, good_edges); } while (++curr != circ); @@ -855,7 +856,7 @@ private: for (hi = fh->holes_begin(); hi != fh->holes_end(); ++hi) { Ccb_halfedge_const_circulator curr = circ = *hi; do { - assert(curr->face() == fh); + CGAL_assertion(curr->face() == fh); input_edge(curr, good_edges); } while (++curr != circ); } diff --git a/Visibility_2/include/CGAL/Simple_polygon_visibility_2.h b/Visibility_2/include/CGAL/Simple_polygon_visibility_2.h index ddd229f67bb..61c8de1efbb 100644 --- a/Visibility_2/include/CGAL/Simple_polygon_visibility_2.h +++ b/Visibility_2/include/CGAL/Simple_polygon_visibility_2.h @@ -404,7 +404,7 @@ namespace CGAL { if (Object_2 result = Intersect_2()(seg, ray_origin) ) { const Point_2 * ipoint = object_cast(&result); - assert( ipoint != NULL ); + CGAL_assertion( ipoint != NULL ); s_t = *ipoint; upcase = SCANB; } @@ -487,7 +487,7 @@ namespace CGAL { Object_2 result = Intersect_2()( seg, seg2 ); if(result) { const Point_2 * ipoint = object_cast(&result); - assert( ipoint != NULL ); + CGAL_assertion( ipoint != NULL ); u = *ipoint; mode = 2; break; @@ -495,7 +495,7 @@ namespace CGAL { } } - assert( mode != 0 ); + CGAL_assertion( mode != 0 ); if ( mode == 1 ) { orient1 = traits->orientation_2_object()(q, vertices[i], vertices[i+1] ); @@ -520,7 +520,7 @@ namespace CGAL { Object_2 result = Intersect_2()( seg, ray ); const Point_2 * ipoint = object_cast(&result); - assert( ipoint != NULL ); + CGAL_assertion( ipoint != NULL ); u = *ipoint; if ( stack.top() != u ) { @@ -539,7 +539,7 @@ namespace CGAL { Object_2 result = Intersect_2()( seg, ray ); const Point_2 * ipoint = object_cast(&result); - assert( ipoint != NULL ); + CGAL_assertion( ipoint != NULL ); u = *ipoint; if ( stack.top() != u ) { @@ -670,7 +670,7 @@ namespace CGAL { } old_orient = curr_orient; } - assert( k+1( &result ); if ( ipoint ) { u = *ipoint; diff --git a/Visibility_2/include/CGAL/Triangular_expansion_visibility_2.h b/Visibility_2/include/CGAL/Triangular_expansion_visibility_2.h index 4a7ba9a9ca3..d27d21e2eaf 100644 --- a/Visibility_2/include/CGAL/Triangular_expansion_visibility_2.h +++ b/Visibility_2/include/CGAL/Triangular_expansion_visibility_2.h @@ -27,6 +27,7 @@ #include #include #include +#include namespace CGAL { @@ -216,7 +217,7 @@ public: out_arr.clear(); needles.clear(); - assert(!face->is_unbounded()); + CGAL_assertion(!face->is_unbounded()); std::vector raw_output; @@ -268,7 +269,7 @@ public: init_cdt(); } - assert(!he->face()->is_unbounded()); + CGAL_assertion(!he->face()->is_unbounded()); out_arr.clear(); needles.clear(); @@ -276,7 +277,7 @@ public: typename CDT::Locate_type location; int index; typename CDT::Face_handle fh = p_cdt->locate(q,location,index); - assert(location == CDT::EDGE || location == CDT::VERTEX); + CGAL_assertion(location == CDT::EDGE || location == CDT::VERTEX); //the following code tries to figure out which triangle one should start in. @@ -292,8 +293,8 @@ public: index = nfh->index(fh); fh = nfh; } - assert(fh->vertex(p_cdt->cw(index))->point() == he->target()->point()); - assert(!p_cdt->is_infinite(fh->vertex(index))); + CGAL_assertion(fh->vertex(p_cdt->cw(index))->point() == he->target()->point()); + CGAL_assertion(!p_cdt->is_infinite(fh->vertex(index))); // output the edge the query lies on @@ -326,10 +327,10 @@ public: //std::cout << "query on vertex" << std::endl; //bool query_point_on_vertex_is_not_working_yet = false; - //assert(query_point_on_vertex_is_not_working_yet); + //CGAL_assertion(query_point_on_vertex_is_not_working_yet); - assert(q == he->target()->point()); - assert(fh->vertex(index)->point() == he->target()->point()); + CGAL_assertion(q == he->target()->point()); + CGAL_assertion(fh->vertex(index)->point() == he->target()->point()); // push points that are seen anyway // raw_output.push_back(he->source()->point()); inserted last @@ -347,15 +348,15 @@ public: int nindex = nfh->index(fh); index = p_cdt->ccw(nindex); fh = nfh; - assert(he->target()->point() == fh->vertex(index)->point()); + CGAL_assertion(he->target()->point() == fh->vertex(index)->point()); } - assert(he->next()->source()->point() == fh->vertex(index)->point()); - assert(he->next()->target()->point() == + CGAL_assertion(he->next()->source()->point() == fh->vertex(index)->point()); + CGAL_assertion(he->next()->target()->point() == fh->vertex(p_cdt->ccw(index))->point()); - assert(!p_cdt->is_infinite(fh)); - assert(p_cdt->is_constrained(get_edge(fh,p_cdt->cw(index)))); + CGAL_assertion(!p_cdt->is_infinite(fh)); + CGAL_assertion(p_cdt->is_constrained(get_edge(fh,p_cdt->cw(index)))); while(he->source()->point() != fh->vertex(p_cdt->ccw(index))->point()){ @@ -376,7 +377,7 @@ public: int nindex = nfh->index(fh); index = p_cdt->ccw(nindex); fh = nfh; - assert(fh->vertex(index)->point() == he->target()->point()); + CGAL_assertion(fh->vertex(index)->point() == he->target()->point()); } } return output(raw_output,out_arr); @@ -397,7 +398,7 @@ private: Ray_2 ray(q,b); Segment_2 seg(s,t); - assert(typename K::Do_intersect_2()(ray,seg)); + CGAL_assertion(typename K::Do_intersect_2()(ray,seg)); CGAL::Object obj = typename K::Intersect_2()(ray,seg); Point_2 result = object_cast(obj); return result; @@ -411,11 +412,11 @@ private: const { // the expanded edge should not be constrained - assert(!p_cdt->is_constrained(get_edge(fh,index))); - assert(!p_cdt->is_infinite(fh)); + CGAL_assertion(!p_cdt->is_constrained(get_edge(fh,index))); + CGAL_assertion(!p_cdt->is_infinite(fh)); // go into the new face const typename CDT::Face_handle nfh(fh->neighbor(index)); - assert(!p_cdt->is_infinite(nfh)); + CGAL_assertion(!p_cdt->is_infinite(nfh)); // get indices of neighbors int nindex = nfh->index(fh); // index of new vertex and old face @@ -426,9 +427,9 @@ private: const typename CDT::Vertex_handle nvh(nfh->vertex(nindex)); const typename CDT::Vertex_handle rvh(nfh->vertex(p_cdt->cw (nindex))); const typename CDT::Vertex_handle lvh(nfh->vertex(p_cdt->ccw(nindex))); - assert(!p_cdt->is_infinite(nvh)); - assert(!p_cdt->is_infinite(lvh)); - assert(!p_cdt->is_infinite(rvh)); + CGAL_assertion(!p_cdt->is_infinite(nvh)); + CGAL_assertion(!p_cdt->is_infinite(lvh)); + CGAL_assertion(!p_cdt->is_infinite(rvh)); // get edges seen from entering edge typename CDT::Edge re = get_edge(nfh,p_cdt->ccw(nindex)); @@ -476,7 +477,7 @@ private: } break; default: - assert(orient == CGAL::COLLINEAR); + CGAL_assertion(orient == CGAL::COLLINEAR); // looking on nvh, so it must be reported // if it wasn't already (triangles rotate around vh) if(vh != nvh){ @@ -505,12 +506,12 @@ private: const { // the expanded edge should not be constrained - assert(!p_cdt->is_constrained(get_edge(fh,index))); - assert(!p_cdt->is_infinite(fh)); + CGAL_assertion(!p_cdt->is_constrained(get_edge(fh,index))); + CGAL_assertion(!p_cdt->is_infinite(fh)); // go into the new face const typename CDT::Face_handle nfh(fh->neighbor(index)); - assert(!p_cdt->is_infinite(nfh)); + CGAL_assertion(!p_cdt->is_infinite(nfh)); // get indices of neighbors int nindex = nfh->index(fh); // index of new vertex and old face @@ -521,9 +522,9 @@ private: const typename CDT::Vertex_handle nvh(nfh->vertex(nindex)); const typename CDT::Vertex_handle rvh(nfh->vertex(p_cdt->cw (nindex))); const typename CDT::Vertex_handle lvh(nfh->vertex(p_cdt->ccw(nindex))); - assert(!p_cdt->is_infinite(nvh)); - assert(!p_cdt->is_infinite(lvh)); - assert(!p_cdt->is_infinite(rvh)); + CGAL_assertion(!p_cdt->is_infinite(nvh)); + CGAL_assertion(!p_cdt->is_infinite(lvh)); + CGAL_assertion(!p_cdt->is_infinite(rvh)); // get edges seen from entering edge typename CDT::Edge re = get_edge(nfh,p_cdt->ccw(nindex)); @@ -535,9 +536,9 @@ private: CGAL::Orientation ro = orientation(q,right,nvh->point()); CGAL::Orientation lo = orientation(q,left ,nvh->point()); - assert(typename K::Orientation_2()(q,left ,lvh->point()) + CGAL_assertion(typename K::Orientation_2()(q,left ,lvh->point()) != CGAL::CLOCKWISE); - assert(typename K::Orientation_2()(q,right,rvh->point()) + CGAL_assertion(typename K::Orientation_2()(q,right,rvh->point()) != CGAL::COUNTERCLOCKWISE); //std::cout << (ro == CGAL::COUNTERCLOCKWISE) << " " << @@ -588,7 +589,7 @@ private: *oit++ = nvh->point(); } if(!Regularization_category::value){ - assert(!(ro == CGAL::COLLINEAR && lo == CGAL::COLLINEAR)); + CGAL_assertion(!(ro == CGAL::COLLINEAR && lo == CGAL::COLLINEAR)); // we have to check whether a needle starts here. if(p_cdt->is_constrained(le) && !p_cdt->is_constrained(re) && ro == CGAL::COLLINEAR) @@ -676,7 +677,7 @@ private: ); } - assert(out_arr.number_of_faces() == 2); + CGAL_assertion(out_arr.number_of_faces() == 2); if(out_arr.faces_begin()->is_unbounded()) return ++out_arr.faces_begin();