Review of draw for face graph, polyhedron and sm

This commit is contained in:
Guillaume Damiand 2022-10-14 15:08:32 +02:00
parent 9c77619fde
commit afc0eaedf5
3 changed files with 164 additions and 97 deletions

View File

@ -16,41 +16,40 @@
#include <CGAL/Graphic_buffer.h> #include <CGAL/Graphic_buffer.h>
#include <CGAL/Drawing_functor.h> #include <CGAL/Drawing_functor.h>
#include <CGAL/Qt/Basic_viewer_qt.h>
#ifdef CGAL_USE_BASIC_VIEWER
#include <CGAL/Dynamic_property_map.h> #include <CGAL/Dynamic_property_map.h>
#include <CGAL/Random.h> #include <CGAL/Random.h>
#include <CGAL/boost/graph/helpers.h> #include <CGAL/boost/graph/helpers.h>
namespace CGAL { namespace CGAL {
namespace draw_function_for_SM { namespace draw_function_for_FG {
template <typename BufferType = float, typename SM, typename DrawingFunctor> template <typename BufferType=float, typename FG, typename DrawingFunctor>
void compute_elements(const SM &sm, void compute_elements(const FG &fg,
CGAL::Graphic_buffer<BufferType> &graphic_buffer, CGAL::Graphic_buffer<BufferType> &graphic_buffer,
const DrawingFunctor &m_drawing_functor, bool anofaces = false) { const DrawingFunctor &m_drawing_functor)
{
using Point = using Point=typename boost::property_map_value<FG, CGAL::vertex_point_t>::type;
typename boost::property_map_value<SM, CGAL::vertex_point_t>::type;
using Kernel = typename CGAL::Kernel_traits<Point>::Kernel; using Kernel = typename CGAL::Kernel_traits<Point>::Kernel;
using Vector = typename Kernel::Vector_3; using Vector = typename Kernel::Vector_3;
auto vnormals = get(CGAL::dynamic_vertex_property_t<Vector>(), sm); auto vnormals = get(CGAL::dynamic_vertex_property_t<Vector>(), fg);
auto point_pmap = get(CGAL::vertex_point, sm); auto point_pmap = get(CGAL::vertex_point, fg);
for (auto v : vertices(sm)) { for (auto v : vertices(fg))
{
Vector n(NULL_VECTOR); Vector n(NULL_VECTOR);
int i = 0; int i = 0;
for (auto h : halfedges_around_target(halfedge(v, sm), sm)) { for (auto h : halfedges_around_target(halfedge(v, fg), fg))
if (!is_border(h, sm)) { {
if (!is_border(h, fg))
{
Vector ni = CGAL::cross_product( Vector ni = CGAL::cross_product(
Vector(get(point_pmap, source(h, sm)), Vector(get(point_pmap, source(h, fg)),
get(point_pmap, target(h, sm))), get(point_pmap, target(h, fg))),
Vector(get(point_pmap, target(h, sm)), Vector(get(point_pmap, target(h, fg)),
get(point_pmap, target(next(h, sm), sm)))); get(point_pmap, target(next(h, fg), fg))));
if (ni != NULL_VECTOR) { if (ni != NULL_VECTOR)
{
n += ni; n += ni;
++i; ++i;
} }
@ -59,70 +58,104 @@ void compute_elements(const SM &sm,
put(vnormals, v, n / i); put(vnormals, v, n / i);
} }
if (!anofaces) { if (m_drawing_functor.are_faces_enabled())
for (auto fh : faces(sm)) { {
if (fh != boost::graph_traits<SM>::null_face() && m_drawing_functor.colored_face(sm, fh)) { for (auto fh : faces(fg))
CGAL::IO::Color c = m_drawing_functor.face_color(sm, fh); {
graphic_buffer.face_begin(c); if (fh != boost::graph_traits<FG>::null_face() && // face exists
auto hd = halfedge(fh, sm); m_drawing_functor.colored_face && // std::function is not null
m_drawing_functor.colored_face(fg, fh)) // and face is colored
{
graphic_buffer.face_begin(m_drawing_functor.face_color(fg, fh));
auto hd = halfedge(fh, fg);
const auto first_hd = hd; const auto first_hd = hd;
do { do
auto v = source(hd, sm); {
auto v = source(hd, fg);
graphic_buffer.add_point_in_face(get(point_pmap, v), get(vnormals, v)); graphic_buffer.add_point_in_face(get(point_pmap, v), get(vnormals, v));
hd = next(hd, sm); hd = next(hd, fg);
} while (hd != first_hd); }
while (hd != first_hd);
graphic_buffer.face_end(); graphic_buffer.face_end();
} }
} }
} }
for (auto e : edges(sm)) { if(m_drawing_functor.are_edges_enabled())
graphic_buffer.add_segment(get(point_pmap, source(halfedge(e, sm), sm)), {
get(point_pmap, target(halfedge(e, sm), sm))); for (auto e : edges(fg))
{
if(m_drawing_functor.colored_edge && // std::function is not null
m_drawing_functor.colored_edge(fg, e)) // and edge is colored
{
graphic_buffer.add_segment(get(point_pmap, source(halfedge(e, fg), fg)),
get(point_pmap, target(halfedge(e, fg), fg)),
m_drawing_functor.edge_color(fg, e));
}
else
{
graphic_buffer.add_segment(get(point_pmap, source(halfedge(e, fg), fg)),
get(point_pmap, target(halfedge(e, fg), fg)));
}
}
} }
for (auto v : vertices(sm)) { if(m_drawing_functor.are_vertices_enabled())
{
for (auto v : vertices(fg))
{
if(m_drawing_functor.colored_vertex && // std::function is not null
m_drawing_functor.colored_vertex(fg, v)) // and vertex is colored
{
graphic_buffer.add_point(get(point_pmap, v),
m_drawing_functor.vertex_color(fg, v));
}
else
{
graphic_buffer.add_point(get(point_pmap, v)); graphic_buffer.add_point(get(point_pmap, v));
} }
} }
}
} // draw_function_for_SM
template <typename BufferType = float, class SM, class DrawingFunctor>
void add_in_graphic_buffer(const SM &sm, CGAL::Graphic_buffer<BufferType> &graphic_buffer,
const DrawingFunctor &m_drawing_functor) {
draw_function_for_SM::compute_elements(sm, graphic_buffer, m_drawing_functor);
} }
template <typename BufferType = float, class SM> } // draw_function_for_FG
void add_in_graphic_buffer(const SM &sm, CGAL::Graphic_buffer<BufferType> &graphic_buffer) {
// Default functor; user can add his own functor. template <typename BufferType=float, class FG, class DrawingFunctor>
Drawing_functor<SM, typename boost::graph_traits<SM>::face_descriptor, void add_in_graphic_buffer_for_fg(const FG &fg,
typename boost::graph_traits<SM>::face_descriptor, CGAL::Graphic_buffer<BufferType> &graphic_buffer,
typename boost::graph_traits<SM>::face_descriptor> const DrawingFunctor &drawing_functor)
{
draw_function_for_FG::compute_elements(fg, graphic_buffer, drawing_functor);
}
template <typename BufferType=float, class FG>
void add_in_graphic_buffer_for_fg(const FG &fg,
CGAL::Graphic_buffer<BufferType> &graphic_buffer)
{
Drawing_functor<FG,
typename boost::graph_traits<FG>::vertex_descriptor,
typename boost::graph_traits<FG>::edge_descriptor,
typename boost::graph_traits<FG>::face_descriptor>
drawing_functor; drawing_functor;
drawing_functor.colored_face = [](const SM &, drawing_functor.colored_face = [](const FG&,
typename boost::graph_traits<SM>::face_descriptor fh) -> bool typename boost::graph_traits<FG>::face_descriptor) -> bool
{ return true; }; { return true; };
drawing_functor.face_color = [] (const SM &, drawing_functor.face_color = [] (const FG&,
typename boost::graph_traits<SM>::face_descriptor fh) -> CGAL::IO::Color typename boost::graph_traits<FG>::face_descriptor fh) -> CGAL::IO::Color
{ {
if (fh == if (fh==boost::graph_traits<FG>::null_face())
boost::graph_traits<SM>::null_face()) // use to get the mono color { return CGAL::IO::Color(100, 125, 200); }
return CGAL::IO::Color(100, 125, 200); // R G B between 0-255
// TODO (?) use a seed given fh (cannot directly cast because FG is either a polyhedron or a surface mesh)
return get_random_color(CGAL::get_default_random()); return get_random_color(CGAL::get_default_random());
}; };
add_in_graphic_buffer(sm, graphic_buffer, drawing_functor); add_in_graphic_buffer_for_fg(fg, graphic_buffer, drawing_functor);
} }
} // End namespace CGAL } // End namespace CGAL
#endif // CGAL_USE_BASIC_VIEWER
#endif // CGAL_DRAW_SURFACE_MESH_H #endif // CGAL_DRAW_SURFACE_MESH_H

View File

@ -13,57 +13,81 @@
#ifndef CGAL_DRAW_POLYHEDRON_H #ifndef CGAL_DRAW_POLYHEDRON_H
#define CGAL_DRAW_POLYHEDRON_H #define CGAL_DRAW_POLYHEDRON_H
#include <CGAL/license/Polyhedron.h>
#include <CGAL/Graphic_buffer.h> #include <CGAL/Graphic_buffer.h>
#include <CGAL/Drawing_functor.h> #include <CGAL/Drawing_functor.h>
#include <CGAL/license/Polyhedron.h>
#include <CGAL/Qt/Basic_viewer_qt.h>
#ifdef CGAL_USE_BASIC_VIEWER
#include <CGAL/Qt/init_ogl_context.h>
#include <CGAL/Polyhedron_3.h> #include <CGAL/Polyhedron_3.h>
#include <CGAL/draw_face_graph.h> #include <CGAL/draw_face_graph.h>
#include <CGAL/Random.h>
#ifdef CGAL_USE_BASIC_VIEWER
#include <CGAL/Qt/Basic_viewer_qt.h>
#endif
namespace CGAL namespace CGAL
{ {
// Specialization of draw function.
#define CGAL_POLY_TYPE CGAL::Polyhedron_3 \ #define CGAL_POLY_TYPE CGAL::Polyhedron_3 \
<PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> <PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc>
// Specialization of add_in_graphic_buffer function.
template<class PolyhedronTraits_3, template<class PolyhedronTraits_3,
class PolyhedronItems_3, class PolyhedronItems_3,
template < class T, class I, class A> template < class T, class I, class A>
class T_HDS, class T_HDS,
class Alloc, typename BufferType = float> class Alloc,
typename BufferType=float,
class DrawingFunctor>
void add_in_graphic_buffer(const CGAL_POLY_TYPE& apoly,
CGAL::Graphic_buffer<BufferType> &graphic_buffer,
const DrawingFunctor &drawing_functor)
{ add_in_graphic_buffer_for_fg(apoly, graphic_buffer, drawing_functor); }
template<class PolyhedronTraits_3,
class PolyhedronItems_3,
template < class T, class I, class A>
class T_HDS,
class Alloc,
typename BufferType=float>
void add_in_graphic_buffer(const CGAL_POLY_TYPE& apoly,
CGAL::Graphic_buffer<BufferType> &graphic_buffer)
{ add_in_graphic_buffer_for_fg(apoly, graphic_buffer); }
// Specialization of draw function: require Qt and the CGAL basic viewer.
#ifdef CGAL_USE_BASIC_VIEWER
template<class PolyhedronTraits_3,
class PolyhedronItems_3,
template < class T, class I, class A>
class T_HDS,
class Alloc,
typename BufferType=float>
void draw(const CGAL_POLY_TYPE& apoly, void draw(const CGAL_POLY_TYPE& apoly,
const char* title="Polyhedron Basic Viewer", const char* title="Polyhedron Basic Viewer")
bool nofill=false)
{ {
CGAL::Graphic_buffer<BufferType> buffer; CGAL::Graphic_buffer<BufferType> buffer;
add_in_graphic_buffer(apoly, buffer); add_in_graphic_buffer_for_fg(apoly, buffer);
draw_buffer(buffer); draw_buffer(buffer, title);
} }
template<class PolyhedronTraits_3, template<class PolyhedronTraits_3,
class PolyhedronItems_3, class PolyhedronItems_3,
template < class T, class I, class A> template < class T, class I, class A>
class T_HDS, class T_HDS,
class Alloc, typename BufferType = float, class DrawingFunctor> class Alloc,
typename BufferType=float,
class DrawingFunctor>
void draw(const CGAL_POLY_TYPE& apoly, void draw(const CGAL_POLY_TYPE& apoly,
const DrawingFunctor &drawing_functor, const DrawingFunctor &drawing_functor,
const char* title="Polyhedron Basic Viewer", const char* title="Polyhedron Basic Viewer")
bool nofill=false)
{ {
CGAL::Graphic_buffer<BufferType> buffer; CGAL::Graphic_buffer<BufferType> buffer;
add_in_graphic_buffer(apoly, buffer, drawing_functor); add_in_graphic_buffer_for_fg(apoly, buffer, drawing_functor);
draw_buffer(buffer); draw_buffer(buffer, title);
} }
#endif // CGAL_USE_BASIC_VIEWER
#undef CGAL_POLY_TYPE #undef CGAL_POLY_TYPE
} // End namespace CGAL } // End namespace CGAL
#endif // CGAL_USE_BASIC_VIEWER
#endif // CGAL_DRAW_POLYHEDRON_H #endif // CGAL_DRAW_POLYHEDRON_H

View File

@ -29,46 +29,56 @@ void draw(const SM& asm);
#else // DOXYGEN_RUNNING #else // DOXYGEN_RUNNING
#include <CGAL/license/Surface_mesh.h>
#include <CGAL/Graphic_buffer.h> #include <CGAL/Graphic_buffer.h>
#include <CGAL/Drawing_functor.h> #include <CGAL/Drawing_functor.h>
#include <CGAL/license/Surface_mesh.h>
#include <CGAL/Qt/Basic_viewer_qt.h>
#ifdef CGAL_USE_BASIC_VIEWER
#include <CGAL/Qt/init_ogl_context.h>
#include <CGAL/Surface_mesh.h> #include <CGAL/Surface_mesh.h>
#include <CGAL/draw_face_graph.h> #include <CGAL/draw_face_graph.h>
#ifdef CGAL_USE_BASIC_VIEWER
#include <CGAL/Qt/Basic_viewer_qt.h>
#endif
namespace CGAL namespace CGAL
{ {
template<class K, typename BufferType=float, class DrawingFunctor>
void add_in_graphic_buffer(const Surface_mesh<K>& amesh,
CGAL::Graphic_buffer<BufferType> &graphic_buffer,
const DrawingFunctor &drawing_functor)
{ add_in_graphic_buffer_for_fg(amesh, graphic_buffer, drawing_functor); }
template<class K, typename BufferType=float>
void add_in_graphic_buffer(const Surface_mesh<K>& amesh,
CGAL::Graphic_buffer<BufferType> &graphic_buffer)
{ add_in_graphic_buffer_for_fg(amesh, graphic_buffer); }
#ifdef CGAL_USE_BASIC_VIEWER
// Specialization of draw function. // Specialization of draw function.
template<class K, typename BufferType=float> template<class K, typename BufferType=float>
void draw(const Surface_mesh<K>& amesh, void draw(const Surface_mesh<K>& amesh,
const char* title="Surface_mesh Basic Viewer", const char* title="Surface_mesh Basic Viewer")
bool nofill=false)
{ {
CGAL::Graphic_buffer<BufferType> buffer; CGAL::Graphic_buffer<BufferType> buffer;
add_in_graphic_buffer(amesh, buffer); add_in_graphic_buffer_for_fg(amesh, buffer);
draw_buffer(buffer); draw_buffer(buffer, title);
} }
template<class K, typename BufferType=float, class DrawingFunctor> template<class K, typename BufferType=float, class DrawingFunctor>
void draw(const Surface_mesh<K>& amesh, void draw(const Surface_mesh<K>& amesh,
const DrawingFunctor &drawing_functor, const DrawingFunctor &drawing_functor,
const char* title="Surface_mesh Basic Viewer", const char* title="Surface_mesh Basic Viewer")
bool nofill=false)
{ {
CGAL::Graphic_buffer<BufferType> buffer; CGAL::Graphic_buffer<BufferType> buffer;
add_in_graphic_buffer(amesh, buffer, drawing_functor); add_in_graphic_buffer_for_fg(amesh, buffer, drawing_functor);
draw_buffer(buffer); draw_buffer(buffer, title);
} }
} // End namespace CGAL
#endif // CGAL_USE_BASIC_VIEWER #endif // CGAL_USE_BASIC_VIEWER
} // End namespace CGAL
#endif // DOXYGEN_RUNNING #endif // DOXYGEN_RUNNING
#endif // CGAL_DRAW_SURFACE_MESH_H #endif // CGAL_DRAW_SURFACE_MESH_H