// Copyright (c) 2018-2022 GeometryFactory (France) // All rights reserved. // // This file is part of CGAL (www.cgal.org). // // $URL$ // $Id$ // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // // Author(s) : Guillaume Damiand // Laurent Rineau // Mostafa Ashraf #ifndef CGAL_DRAW_FACE_GRAPH_H #define CGAL_DRAW_FACE_GRAPH_H #include #include #include #include #include namespace CGAL { namespace draw_function_for_FG { template void compute_elements(const FG &fg, CGAL::Graphics_scene &graphics_scene, const GSOptions &gs_options) { using Point=typename boost::property_map_value::type; using Kernel = typename CGAL::Kernel_traits::Kernel; using Vector = typename Kernel::Vector_3; auto vnormals = get(CGAL::dynamic_vertex_property_t(), fg); auto point_pmap = get(CGAL::vertex_point, fg); for (auto v : vertices(fg)) { Vector n(NULL_VECTOR); int i = 0; for (auto h : halfedges_around_target(halfedge(v, fg), fg)) { if (!is_border(h, fg)) { Vector ni = CGAL::cross_product( Vector(get(point_pmap, source(h, fg)), get(point_pmap, target(h, fg))), Vector(get(point_pmap, target(h, fg)), get(point_pmap, target(next(h, fg), fg)))); if (ni!=NULL_VECTOR) { n += ni; ++i; } } } put(vnormals, v, n / i); } if (gs_options.are_faces_enabled()) { for (auto fh : faces(fg)) { if (fh != boost::graph_traits::null_face() && // face exists gs_options.draw_face(fg, fh)) // face is drawn { if(gs_options.colored_face(fg, fh)) // face is colored { graphics_scene.face_begin(gs_options.face_color(fg, fh)); } else { graphics_scene.face_begin(); } auto hd = halfedge(fh, fg); const auto first_hd = hd; do { auto v = source(hd, fg); graphics_scene.add_point_in_face(get(point_pmap, v), get(vnormals, v)); hd = next(hd, fg); } while (hd != first_hd); graphics_scene.face_end(); } } } if(gs_options.are_edges_enabled()) { for (auto e : edges(fg)) { if(gs_options.colored_edge(fg, e)) // edge is colored { graphics_scene.add_segment(get(point_pmap, source(halfedge(e, fg), fg)), get(point_pmap, target(halfedge(e, fg), fg)), gs_options.edge_color(fg, e)); } else { graphics_scene.add_segment(get(point_pmap, source(halfedge(e, fg), fg)), get(point_pmap, target(halfedge(e, fg), fg))); } } } if(gs_options.are_vertices_enabled()) { for (auto v : vertices(fg)) { if(gs_options.colored_vertex(fg, v)) // vertex is colored { graphics_scene.add_point(get(point_pmap, v), gs_options.vertex_color(fg, v)); } else { graphics_scene.add_point(get(point_pmap, v)); } } } } } // draw_function_for_FG template void add_to_graphics_scene_for_fg(const FG &fg, CGAL::Graphics_scene &graphics_scene, const GSOptions &gs_options) { draw_function_for_FG::compute_elements(fg, graphics_scene, gs_options); } template void add_to_graphics_scene_for_fg(const FG &fg, CGAL::Graphics_scene &graphics_scene) { Graphics_scene_options::vertex_descriptor, typename boost::graph_traits::edge_descriptor, typename boost::graph_traits::face_descriptor> gs_options; gs_options.colored_face = [](const FG&, typename boost::graph_traits::face_descriptor) -> bool { return true; }; gs_options.face_color = [] (const FG&, typename boost::graph_traits::face_descriptor fh) -> CGAL::IO::Color { if (fh==boost::graph_traits::null_face()) { return CGAL::IO::Color(100, 125, 200); } return get_random_color(CGAL::get_default_random()); }; add_to_graphics_scene_for_fg(fg, graphics_scene, gs_options); } } // End namespace CGAL #endif // CGAL_DRAW_SURFACE_MESH_H