From c4d612c85e2b026da65b71aa41728ca5ff498c9e Mon Sep 17 00:00:00 2001 From: Mostafa-ashraf19 Date: Fri, 7 Oct 2022 03:00:19 +0200 Subject: [PATCH] Uses new APIs version in Nef_3. --- Nef_3/include/CGAL/draw_nef_3.h | 478 +++++++++++++++----------------- 1 file changed, 231 insertions(+), 247 deletions(-) diff --git a/Nef_3/include/CGAL/draw_nef_3.h b/Nef_3/include/CGAL/draw_nef_3.h index e654ea9aae7..f211ecc380f 100644 --- a/Nef_3/include/CGAL/draw_nef_3.h +++ b/Nef_3/include/CGAL/draw_nef_3.h @@ -9,10 +9,13 @@ // // // Author(s) : Jasmeet Singh +// Mostafa Ashraf #ifndef DRAW_NEF_3_H #define DRAW_NEF_3_H +#include +#include #include #include @@ -28,268 +31,249 @@ namespace CGAL { -// Default color functor; user can change it to have its own face color -struct DefaultColorFunctorNefPolyhedron +typedef CGAL::Exact_predicates_inexact_constructions_kernel Local_kernel; +typedef Local_kernel::Vector_3 Local_vector; + +namespace draw_function_for_nef_polyhedron { - template - static CGAL::IO::Color run(const NefPolyhedron&, - typename NefPolyhedron::Halffacet_const_handle fh) + +template +Local_vector get_face_normal(typename Nef_Polyhedron::SHalfedge_const_handle she) +{ + typedef typename Nef_Polyhedron::SHalfedge_around_facet_const_circulator SHalfedge_around_facet_const_circulator; + + SHalfedge_around_facet_const_circulator he(she); + Local_vector normal = CGAL::NULL_VECTOR; + SHalfedge_around_facet_const_circulator end = he; + unsigned int nb = 0; + + CGAL_For_all(he, end) + { + internal::newell_single_step_3(Basic_viewer_qt<>::get_local_point + (he->next()->source()->center_vertex()->point()), + Basic_viewer_qt<>::get_local_point(he->source()->center_vertex()-> + point()), normal); + ++nb; + } + + CGAL_assertion(nb > 0); + return (typename Local_kernel::Construct_scaled_vector_3()(normal, 1.0 / nb)); +} + +template +Local_vector get_vertex_normal(typename Nef_Polyhedron::Vertex_const_handle vh) +{ + typedef typename Nef_Polyhedron::SHalfedge_const_handle SHalfedge_const_handle; + typedef typename Nef_Polyhedron::SHalfedge_const_iterator SHalfedge_const_iterator; + + Local_vector normal = CGAL::NULL_VECTOR; + + SHalfedge_const_iterator it = vh->shalfedges_begin(); + SHalfedge_const_handle end = it; + do { + Local_vector n = get_face_normal(it); + normal = typename Local_kernel::Construct_sum_of_vectors_3()(normal, n); + it = it->snext(); + } while( it != end ); + + if (!typename Local_kernel::Equal_3()(normal, CGAL::NULL_VECTOR)) + { + normal = (typename Local_kernel::Construct_scaled_vector_3()( + normal, 1.0 / CGAL::sqrt(normal.squared_length()))); + } + + return normal; +} + +// Visitor class to iterate through shell objects +template +class Nef_Visitor { + + typedef typename Nef_Polyhedron::Halfedge_const_handle Halfedge_const_handle; + typedef typename Nef_Polyhedron::Halffacet_const_handle Halffacet_const_handle; + typedef typename Nef_Polyhedron::SHalfedge_const_handle SHalfedge_const_handle; + typedef typename Nef_Polyhedron::SHalfedge_around_facet_const_circulator SHalfedge_around_facet_const_circulator; + typedef typename Nef_Polyhedron::Vertex_const_handle Vertex_const_handle; + typedef typename Nef_Polyhedron::SFace_const_handle SFace_const_handle; + typedef typename Nef_Polyhedron::SHalfloop_const_handle SHalfloop_const_handle; + typedef typename Nef_Polyhedron::Halffacet_cycle_const_iterator Halffacet_cycle_const_iterator; + +public: + Nef_Visitor(const Nef_Polyhedron &_nef, + CGAL::Graphic_buffer & _graphic_buffer, + const DrawingFunctor &_drawing_functor) + : n_faces(0), n_edges(0), + nef(_nef), + graphic_buffer(_graphic_buffer), + drawing_functor(_drawing_functor) {} + + void visit(Vertex_const_handle vh) { + graphic_buffer.add_point(vh->point()); + } + + void visit(Halffacet_const_handle opposite_facet) + { + Halffacet_const_handle f = opposite_facet->twin(); + + if (facets_done.find(f) != facets_done.end() || + facets_done.find(opposite_facet) != facets_done.end()) { + return; + } + + SHalfedge_const_handle se; + Halffacet_cycle_const_iterator fc = f->facet_cycles_begin(); + + se = SHalfedge_const_handle(fc); // non-zero if shalfedge is returned + if(se == 0) + { //return if not-shalfedge + return; + } + + if(drawing_functor.colored_face(nef, f)) { + CGAL::IO::Color c = drawing_functor.face_color(nef, f); + graphic_buffer.face_begin(c); + } + + SHalfedge_around_facet_const_circulator hc_start(se); + SHalfedge_around_facet_const_circulator hc_end(hc_start); + Vertex_const_handle lastvh; + CGAL_For_all(hc_start, hc_end) { + Vertex_const_handle vh=hc_start->source()->center_vertex(); + lastvh=vh; + graphic_buffer.add_point_in_face(vh->point(), draw_function_for_nef_polyhedron::get_vertex_normal(vh)); + } + + // Now iterate through holes of the face + ++fc; + while(fc!=f->facet_cycles_end()) + { + se = SHalfedge_const_handle(fc); + hc_start=se; + hc_end=hc_start; + CGAL_For_all(hc_start, hc_end) { + Vertex_const_handle vh=hc_start->source()->center_vertex(); + graphic_buffer.add_point_in_face(vh->point(), draw_function_for_nef_polyhedron::get_vertex_normal(vh)); + } + graphic_buffer.add_point_in_face(hc_start->source()->center_vertex()->point(), + draw_function_for_nef_polyhedron::get_vertex_normal(hc_start->source()->center_vertex())); + graphic_buffer.add_point_in_face(lastvh->point(), draw_function_for_nef_polyhedron::get_vertex_normal(lastvh)); + ++fc; + } + + graphic_buffer.face_end(); + facets_done[f]=true; + n_faces++; + } + + void visit(Halfedge_const_handle he) + { + Halfedge_const_handle twin = he->twin(); + if (edges_done.find(he) != edges_done.end() || + edges_done.find(twin) != edges_done.end()) + { + // Edge already added + return; + } + + graphic_buffer.add_segment(he->source()->point(), he->target()->point()); + edges_done[he] = true; + n_edges++; + } + + void visit(SHalfedge_const_handle ) {} + void visit(SHalfloop_const_handle ) {} + void visit(SFace_const_handle ) {} + int n_faces; + int n_edges; +protected: + std::unordered_map facets_done; + std::unordered_map edges_done; + CGAL::Graphic_buffer& graphic_buffer; + const DrawingFunctor& drawing_functor; + const Nef_Polyhedron &nef; +}; + +template +void compute_elements(const Nef_Polyhedron &nef, CGAL::Graphic_buffer &graphic_buffer, + const DrawingFunctor &m_drawing_functor) +{ + + typedef typename Nef_Polyhedron::Volume_const_iterator Volume_const_iterator; + typedef typename Nef_Polyhedron::Shell_entry_const_iterator Shell_entry_const_iterator; + typedef typename Nef_Polyhedron::SFace_const_handle SFace_const_handle; + + Volume_const_iterator c; + + Nef_Visitor V(nef, graphic_buffer, m_drawing_functor); + CGAL_forall_volumes(c, nef) + { + Shell_entry_const_iterator it; + CGAL_forall_shells_of(it, c) + { + nef.visit_shell_objects(SFace_const_handle(it), V); + } + } + + graphic_buffer.negate_all_normals(); +} + +} // namespace draw_function_for_nef_polyhedron + +template +void add_in_graphic_buffer(const Nef_Polyhedron &nef, + CGAL::Graphic_buffer &graphic_buffer, + const DrawingFunctor &m_drawing_functor) { + draw_function_for_nef_polyhedron::compute_elements(nef, graphic_buffer, m_drawing_functor); +} + +template +void add_in_graphic_buffer(const Nef_Polyhedron &nef, CGAL::Graphic_buffer &graphic_buffer) { + + // Default functor; user can add his own functor. + Drawing_functor + drawing_functor; + + drawing_functor.colored_face = [] (const Nef_Polyhedron&, + typename Nef_Polyhedron::Halffacet_const_handle fh) -> bool + { + return true; + }; + + drawing_functor.face_color = [] (const Nef_Polyhedron&, + typename Nef_Polyhedron::Halffacet_const_handle fh) -> CGAL::IO::Color { if (fh == nullptr) // use to get the mono color return CGAL::IO::Color(100, 125, 200); // R G B between 0-255 CGAL::Random random((unsigned int)(std::size_t)(&(*fh))); return get_random_color(random); - } -}; - -// Viewer class for Nef Polyhedron -template -class SimpleNefPolyhedronViewerQt : public Basic_viewer_qt -{ - typedef Basic_viewer_qt Base; - typedef typename Nef_Polyhedron::Kernel Kernel; - - typedef typename Nef_Polyhedron::Halffacet_cycle_const_iterator Halffacet_cycle_const_iterator; - typedef typename Nef_Polyhedron::SHalfedge_around_facet_const_circulator SHalfedge_around_facet_const_circulator; - - typedef typename Nef_Polyhedron::Shell_entry_const_iterator Shell_entry_const_iterator; - typedef typename Nef_Polyhedron::SHalfedge_const_iterator SHalfedge_const_iterator; - typedef typename Nef_Polyhedron::Volume_const_iterator Volume_const_iterator; - - typedef typename Nef_Polyhedron::Vertex_const_handle Vertex_const_handle; - typedef typename Nef_Polyhedron::SFace_const_handle SFace_const_handle; - typedef typename Nef_Polyhedron::Halfedge_const_handle Halfedge_const_handle; - typedef typename Nef_Polyhedron::Halffacet_const_handle Halffacet_const_handle; - typedef typename Nef_Polyhedron::SHalfedge_const_handle SHalfedge_const_handle; - typedef typename Nef_Polyhedron::SHalfloop_const_handle SHalfloop_const_handle; - -public: - /// Construct the viewer - /// @param anef the nef polyhedron to view - /// @param title the title of the window - /// @param anofaces if true, do not draw faces (faces are not - /// computed: this can be useful for big objects) - SimpleNefPolyhedronViewerQt(QWidget* parent, - const Nef_Polyhedron& anef, - const char* title="Basic Nef Polyhedron Viewer", - bool anofaces=false, - const ColorFunctor& fcolor=ColorFunctor()) : - //First draw: vertex; edges, faces; mon-color; inverse normal - Base(parent, title, false, true, true, true, false), - nef(anef), - m_nofaces(anofaces), - m_fcolor(fcolor) - { - compute_elements(); - } -protected: - // Visitor class to iterate through shell objects - class Nef_Visitor { - public: - Nef_Visitor(SimpleNefPolyhedronViewerQt &v) - : n_faces(0), n_edges(0), viewer(v) {} - - void visit(Vertex_const_handle vh) { - viewer.add_point(vh->point()); - } - - void visit(Halffacet_const_handle opposite_facet) - { - Halffacet_const_handle f = opposite_facet->twin(); - - if (facets_done.find(f) != facets_done.end() || - facets_done.find(opposite_facet) != facets_done.end()) { - return; - } - - - - SHalfedge_const_handle se; - Halffacet_cycle_const_iterator fc=f->facet_cycles_begin(); - - se = SHalfedge_const_handle(fc); // non-zero if shalfedge is returned - if(se == 0) - { //return if not-shalfedge - return; - } - - CGAL::IO::Color c = viewer.run_color(f); - viewer.face_begin(c); - - SHalfedge_around_facet_const_circulator hc_start(se); - SHalfedge_around_facet_const_circulator hc_end(hc_start); - Vertex_const_handle lastvh; - CGAL_For_all(hc_start, hc_end) { - Vertex_const_handle vh=hc_start->source()->center_vertex(); - lastvh=vh; - viewer.add_point_in_face(vh->point(), - viewer.get_vertex_normal(vh)); - } - - // Now iterate through holes of the face - ++fc; - while(fc!=f->facet_cycles_end()) - { - se = SHalfedge_const_handle(fc); - hc_start=se; - hc_end=hc_start; - CGAL_For_all(hc_start, hc_end) { - Vertex_const_handle vh=hc_start->source()->center_vertex(); - viewer.add_point_in_face(vh->point(), - viewer.get_vertex_normal(vh)); - } - viewer.add_point_in_face(hc_start->source()->center_vertex()->point(), - viewer.get_vertex_normal(hc_start->source()->center_vertex())); - viewer.add_point_in_face(lastvh->point(), - viewer.get_vertex_normal(lastvh)); - ++fc; - } - - viewer.face_end(); - facets_done[f]=true; - n_faces++; - } - - void visit(Halfedge_const_handle he) - { - Halfedge_const_handle twin = he->twin(); - if (edges_done.find(he) != edges_done.end() || - edges_done.find(twin) != edges_done.end()) - { - // Edge already added - return; - } - - viewer.add_segment(he->source()->point(), he->target()->point()); - edges_done[he] = true; - n_edges++; - } - - void visit(SHalfedge_const_handle ) {} - void visit(SHalfloop_const_handle ) {} - void visit(SFace_const_handle ) {} - int n_faces; - int n_edges; - protected: - std::unordered_map facets_done; - std::unordered_map edges_done; - SimpleNefPolyhedronViewerQt& viewer; }; - void compute_elements() - { - clear(); - - Volume_const_iterator c; - - Nef_Visitor V(*this); - CGAL_forall_volumes(c, nef) - { - Shell_entry_const_iterator it; - CGAL_forall_shells_of(it, c) - { - nef.visit_shell_objects(SFace_const_handle(it), V); - } - } - - negate_all_normals(); - } - - CGAL::IO::Color run_color(Halffacet_const_handle fh) - { - return m_fcolor.run(nef, fh); - } - - virtual void keyPressEvent(QKeyEvent *e) - { - // Test key pressed: - // const ::Qt::KeyboardModifiers modifiers = e->modifiers(); - // if ((e->key()==Qt::Key_PageUp) && (modifiers==Qt::NoButton)) { ... } - - // Call: * compute_elements() if the model changed, followed by - // * redraw() if some viewing parameters changed that implies some - // modifications of the buffers - // (eg. type of normal, color/mono) - // * update() just to update the drawing - - // Call the base method to process others/classicals key - Base::keyPressEvent(e); - } - -protected: - Local_vector get_face_normal(SHalfedge_const_handle she) - { - SHalfedge_around_facet_const_circulator he(she); - Local_vector normal = CGAL::NULL_VECTOR; - SHalfedge_around_facet_const_circulator end = he; - unsigned int nb = 0; - - CGAL_For_all(he, end) - { - internal::newell_single_step_3(this->get_local_point - (he->next()->source()->center_vertex()->point()), - this->get_local_point(he->source()->center_vertex()-> - point()), normal); - ++nb; - } - - CGAL_assertion(nb > 0); - return (typename Local_kernel::Construct_scaled_vector_3()(normal, 1.0 / nb)); - } - - Local_vector get_vertex_normal(Vertex_const_handle vh) - { - Local_vector normal = CGAL::NULL_VECTOR; - - SHalfedge_const_iterator it = vh->shalfedges_begin(); - SHalfedge_const_handle end = it; - do { - Local_vector n = get_face_normal(it); - normal = typename Local_kernel::Construct_sum_of_vectors_3()(normal, n); - it = it->snext(); - } while( it != end ); - - if (!typename Local_kernel::Equal_3()(normal, CGAL::NULL_VECTOR)) - { - normal = (typename Local_kernel::Construct_scaled_vector_3()( - normal, 1.0 / CGAL::sqrt(normal.squared_length()))); - } - - return normal; - } - -protected: - const Nef_Polyhedron &nef; - bool m_nofaces; - const ColorFunctor &m_fcolor; -}; + add_in_graphic_buffer(nef, graphic_buffer, drawing_functor); +} #define CGAL_NEF3_TYPE Nef_polyhedron_3 -template +template +void draw(const CGAL_NEF3_TYPE &anef, + const DrawingFunctor &drawing_functor, + bool nofill = false) { + CGAL::Graphic_buffer buffer; + add_in_graphic_buffer(anef, buffer, drawing_functor); + draw_buffer(buffer); +} + +template void draw(const CGAL_NEF3_TYPE &anef, const char *title = "Nef Polyhedron Viewer", bool nofill = false) { -#if defined(CGAL_TEST_SUITE) - bool cgal_test_suite = true; -#else - bool cgal_test_suite = qEnvironmentVariableIsSet("CGAL_TEST_SUITE"); -#endif - - if (!cgal_test_suite) - { - CGAL::Qt::init_ogl_context(4,3); - int argc = 1; - const char *argv[2] = {"nef_polyhedron_viewer", nullptr}; - QApplication app(argc, const_cast(argv)); - DefaultColorFunctorNefPolyhedron fcolor; - SimpleNefPolyhedronViewerQt - mainwindow(app.activeWindow(), anef, title, nofill, fcolor); - mainwindow.show(); - app.exec(); - } + CGAL::Graphic_buffer buffer; + add_in_graphic_buffer(anef, buffer); + draw_buffer(buffer); } } // End namespace CGAL