draw polygon set

This commit is contained in:
Guillaume Damiand 2023-11-20 18:24:17 +01:00
parent 12e7492f33
commit c379872a79
2 changed files with 163 additions and 62 deletions

View File

@ -46,6 +46,41 @@ void draw(const PS& aps);
namespace CGAL {
template <typename DS,
typename VertexDescriptor,
typename EdgeDescriptor,
typename FaceDescriptor>
struct Graphics_scene_options_polygon_set_2 :
public CGAL::Graphics_scene_options<DS, VertexDescriptor, EdgeDescriptor, FaceDescriptor>
{
void unbounded_face_color(const CGAL::IO::Color& c)
{ m_unbounded_face_color=c; }
const CGAL::IO::Color& unbounded_face_color() const
{ return m_unbounded_face_color; }
bool draw_unbounded() const
{ return m_draw_unbounded; }
void draw_unbounded(bool b) const
{ m_draw_unbounded=b; }
void toggle_draw_unbounded()
{ m_draw_unbounded=!m_draw_unbounded; }
int height() const
{ return m_height; }
int width() const
{ return m_width; }
void height(int i)
{ m_height=i; }
void width(int i)
{ m_width=i; }
protected:
bool m_draw_unbounded=true;
CGAL::IO::Color m_unbounded_face_color=CGAL::IO::Color(75,160,255);
int m_width=0, m_height=0;
};
namespace draw_function_for_boolean_set_2 {
template <typename PS2, class GSOptions>
@ -53,23 +88,57 @@ void compute_loop(const typename PS2::Polygon_2& p, bool hole,
CGAL::Graphics_scene& gs,
const GSOptions& gso)
{
if (hole)
if (gso.are_faces_enabled() && hole)
{ gs.add_point_in_face(p.vertex(p.size()-1)); }
auto prev = p.vertices_begin();
auto it = prev;
gs.add_point(*it);
gs.add_point_in_face(*it);
for (++it; it != p.vertices_end(); ++it)
if (gso.are_vertices_enabled() &&
gso.draw_vertex(p, it))
{
gs.add_point(*it); // add vertex
gs.add_segment(*prev, *it); // add segment with previous point
gs.add_point_in_face(*it); // add point in face
if(gso.colored_vertex(p, it))
{ gs.add_point(*it, gso.vertex_color(p, it)); }
else
{ gs.add_point(*it); }
}
if (gso.are_faces_enabled())
{ gs.add_point_in_face(*it); }
for (++it; it!=p.vertices_end(); ++it)
{
if (gso.are_vertices_enabled() &&
gso.draw_vertex(p, it))
{ // Add point
if(gso.colored_vertex(p, it))
{ gs.add_point(*it, gso.vertex_color(p, it)); }
else
{ gs.add_point(*it); }
}
if (gso.are_edges_enabled() &&
gso.draw_edge(p, prev))
{ // Add segment with previous point
if(gso.colored_edge(p, prev))
{ gs.add_segment(*prev, *it, gso.edge_color(p, prev)); }
else
{ gs.add_segment(*prev, *it); }
}
if (gso.are_faces_enabled())
{ gs.add_point_in_face(*it); } // add point in face
prev = it;
}
// Add the last segment between the last point and the first one
gs.add_segment(*prev, *(p.vertices_begin()));
if (gso.are_edges_enabled() &&
gso.draw_edge(p, prev))
{ // Add the last segment between the last point and the first one
if(gso.colored_edge(p, prev))
{ gs.add_segment(*prev, *(p.vertices_begin()), gso.edge_color(p, prev)); }
else
{ gs.add_segment(*prev, *(p.vertices_begin())); }
}
}
/// Compute the elements of a polygon with holes.
@ -80,41 +149,44 @@ void compute_elements(const PWH& pwh,
{
if (!gso.draw_unbounded() && pwh.outer_boundary().is_empty()) return;
CGAL::IO::Color c(75,160,255);
gs.face_begin(c);
if (gso.are_faces_enabled())
{ gs.face_begin(gso.unbounded_face_color()); }
const typename PWH::Point_2* point_in_face;
if (pwh.outer_boundary().is_empty())
using Pnt=typename PWH::Polygon_2::Point_2;
const Pnt* point_in_face=nullptr;
if (pwh.outer_boundary().is_empty() && (gso.width()!=0 || gso.height()!=0))
{
typename PWH::Polygon_2 pgn;
pgn.push_back(Pnt(-gso.width(), -gso.height()));
pgn.push_back(Pnt(gso.width(), -gso.height()));
pgn.push_back(Pnt(gso.width(), gso.height()));
pgn.push_back(Pnt(-gso.width(), gso.height()));
compute_loop(pgn, false, gs);
draw_function_for_boolean_set_2::compute_loop<PWH>(pgn, false, gs, gso);
point_in_face = &(pgn.vertex(pgn.size()-1));
}
else
{
const auto& outer_boundary = pwh.outer_boundary();
compute_loop(outer_boundary, false, gs);
draw_function_for_boolean_set_2::compute_loop<PWH>(outer_boundary, false, gs, gso);
point_in_face = &(outer_boundary.vertex(outer_boundary.size()-1));
}
for (auto it = pwh.holes_begin(); it != pwh.holes_end(); ++it)
{
compute_loop(*it, true, gs);
gs.add_point_in_face(*point_in_face);
draw_function_for_boolean_set_2::compute_loop<PWH>(*it, true, gs, gso);
if (gso.are_faces_enabled())
{ gs.add_point_in_face(*point_in_face); }
}
gs.face_end();
if (gso.are_faces_enabled())
{ gs.face_end(); }
}
} // End namespace draw_function_for_boolean_set_2
#ifdef CGAL_USE_BASIC_VIEWER
template <typename PolygonSet_2>
template <typename PolygonSet_2, typename GSOptions>
class Polygon_set_2_basic_viewer_qt : public Basic_viewer
{
using Base = Basic_viewer;
@ -125,12 +197,11 @@ class Polygon_set_2_basic_viewer_qt : public Basic_viewer
public:
Polygon_set_2_basic_viewer_qt(QWidget* parent, const Ps& ps,
const char* title = "Basic Polygon_set_2 Viewer",
bool draw_unbounded = false,
bool draw_vertices = false) :
Base(parent, graphics_scene, title, draw_vertices),
GSOptions& gs_options,
const char* title = "Basic Polygon_set_2 Viewer") :
Base(parent, graphics_scene, title),
m_ps(ps),
m_draw_unbounded(draw_unbounded)
gso(gs_options)
{
if (ps.is_empty()) return;
@ -146,11 +217,12 @@ public:
*/
virtual void resizeGL(int width, int height) {
CGAL::QGLViewer::resizeGL(width, height);
m_width = width;
m_height = height;
gso.width(width);
gso.height(height);
CGAL::qglviewer::Vec p;
auto ratio = this->camera()->pixelGLRatio(p);
if (ratio != m_pixel_ratio) {
if (ratio != m_pixel_ratio)
{
m_pixel_ratio = ratio;
add_elements();
}
@ -168,7 +240,7 @@ public:
std::vector<Pwh> pwhs;
m_ps.polygons_with_holes(std::back_inserter(pwhs));
for (const auto& pwh : pwhs)
{ compute_elements(pwh, graphics_scene, graphics_scene_options); }
{ draw_function_for_boolean_set_2::compute_elements(pwh, graphics_scene, gso); }
}
/*! Compute the bounding box.
@ -205,15 +277,37 @@ private:
bool m_draw_unbounded = false;
Graphics_scene graphics_scene;
Graphics_scene_options<Ps> graphics_scene_options;
GSOptions& gso;
};
// Specialization of draw function.
#endif // CGAL_USE_BASIC_VIEWER
#define CGAL_PS2_TYPE CGAL::Polygon_set_2<T, C, D>
// Specializations of add_to_graphics_scene function
template<class T, class C, class D, class GSOptions>
void add_to_graphics_scene(const CGAL_PS2_TYPE& ap2,
CGAL::Graphics_scene& graphics_scene,
const GSOptions& gso)
{ draw_function_for_boolean_set_2::compute_elements(ap2, graphics_scene, gso); }
template<class T, class C, class D>
void draw(const CGAL::Polygon_set_2<T, C, D>& ps,
const char* title = "Polygon_set_2 Basic Viewer",
bool draw_vertices = false,
bool draw_unbounded = false)
void add_to_graphics_scene(const CGAL_PS2_TYPE& ap2,
CGAL::Graphics_scene &graphics_scene)
{
CGAL::Graphics_scene_options_polygon_set_2<typename CGAL_PS2_TYPE::Polygon_2,
typename CGAL_PS2_TYPE::Vertex_const_iterator,
typename CGAL_PS2_TYPE::Vertex_const_iterator,
void*> gso;
draw_function_for_boolean_set_2::compute_elements(ap2, graphics_scene, gso);
}
#ifdef CGAL_USE_BASIC_VIEWER
// Specialization of draw function.
template<class T, class C, class D, class GSOptions>
void draw(const CGAL_PS2_TYPE& ps, GSOptions& gso,
const char* title = "Polygon_set_2 Basic Viewer")
{
#if defined(CGAL_TEST_SUITE)
bool cgal_test_suite = true;
@ -224,21 +318,30 @@ void draw(const CGAL::Polygon_set_2<T, C, D>& ps,
if (! cgal_test_suite)
{
using Ps = CGAL::Polygon_set_2<T, C, D>;
using Viewer = Polygon_set_2_basic_viewer_qt<Ps>;
using Viewer = Polygon_set_2_basic_viewer_qt<Ps, GSOptions>;
CGAL::Qt::init_ogl_context(4,3);
int argc = 1;
const char* argv[2] = {"t2_viewer", nullptr};
QApplication app(argc, const_cast<char**>(argv));
Viewer basic_viewer(app.activeWindow(), ps,
title, draw_unbounded, draw_vertices);
basic_viewer.add_elements();
Viewer basic_viewer(app.activeWindow(), ps, gso, title);
basic_viewer.show();
app.exec();
}
}
} // End namespace CGAL
template<class T, class C, class D>
void draw(const CGAL_PS2_TYPE& ps,
const char* title = "Polygon_set_2 Basic Viewer")
{
CGAL::Graphics_scene_options_polygon_set_2<typename CGAL_PS2_TYPE::Polygon_2,
typename CGAL_PS2_TYPE::Polygon_2::Vertex_const_iterator,
typename CGAL_PS2_TYPE::Polygon_2::Vertex_const_iterator,
void*> gso;
draw(ps, gso, title);
}
#endif // CGAL_USE_BASIC_VIEWER
} // End namespace CGAL
#endif // CGAL_DRAW_POLYGON_SET_2_H

View File

@ -49,17 +49,17 @@ namespace draw_function_for_p2 {
template <class P2, class GSOptions>
void compute_elements(const P2& p2,
CGAL::Graphics_scene &graphics_scene,
const GSOptions& gs_options)
const GSOptions& gso)
{
if (p2.is_empty())
return;
typename P2::Point_2 prev=p2.vertex(p2.size()-1);
if (gs_options.are_faces_enabled())
if (gso.are_faces_enabled())
{
if(gs_options.colored_face(p2, nullptr))
{ graphics_scene.face_begin(gs_options.face_color(p2, nullptr)); }
if(gso.colored_face(p2, nullptr))
{ graphics_scene.face_begin(gso.face_color(p2, nullptr)); }
else
{ graphics_scene.face_begin(); }
}
@ -67,31 +67,31 @@ void compute_elements(const P2& p2,
for (typename P2::Vertex_const_iterator i=p2.vertices_begin();
i!=p2.vertices_end(); ++i)
{
if(gs_options.are_vertices_enabled() &&
gs_options.draw_vertex(p2, i))
if(gso.are_vertices_enabled() &&
gso.draw_vertex(p2, i))
{ // Add vertex
if(gs_options.colored_vertex(p2, i))
{ graphics_scene.add_point(*i, gs_options.vertex_color(p2, i)); }
if(gso.colored_vertex(p2, i))
{ graphics_scene.add_point(*i, gso.vertex_color(p2, i)); }
else
{ graphics_scene.add_point(*i); }
}
if(gs_options.are_edges_enabled() &&
gs_options.draw_edge(p2, i))
if(gso.are_edges_enabled() &&
gso.draw_edge(p2, i))
{ // Add edge with previous point
if(gs_options.colored_vertex(p2, i))
{ graphics_scene.add_segment(prev, *i, gs_options.edge_color(p2, i)); }
if(gso.colored_edge(p2, i))
{ graphics_scene.add_segment(prev, *i, gso.edge_color(p2, i)); }
else
{ graphics_scene.add_segment(prev, *i); }
}
if(gs_options.are_faces_enabled())
if(gso.are_faces_enabled())
{ graphics_scene.add_point_in_face(*i); } // Add point in face
prev = *i;
}
if (gs_options.are_faces_enabled())
if (gso.are_faces_enabled())
{ graphics_scene.face_end(); }
}
@ -100,12 +100,11 @@ void compute_elements(const P2& p2,
#define CGAL_P2_TYPE CGAL::Polygon_2<T, C>
// Specializations of add_to_graphics_scene function
template<class T, class C, class GSOptions>
void add_to_graphics_scene(const CGAL_P2_TYPE& ap2,
CGAL::Graphics_scene& graphics_scene,
const GSOptions& gs_options)
{ draw_function_for_p2::compute_elements(ap2, graphics_scene, gs_options); }
const GSOptions& gso)
{ draw_function_for_p2::compute_elements(ap2, graphics_scene, gso); }
template<class T, class C>
void add_to_graphics_scene(const CGAL_P2_TYPE& ap2,
@ -114,14 +113,13 @@ void add_to_graphics_scene(const CGAL_P2_TYPE& ap2,
CGAL::Graphics_scene_options<CGAL_P2_TYPE,
typename CGAL_P2_TYPE::Vertex_const_iterator,
typename CGAL_P2_TYPE::Vertex_const_iterator,
void*> gs_options;
draw_function_for_p2::compute_elements(ap2, graphics_scene, gs_options);
void*> gso;
draw_function_for_p2::compute_elements(ap2, graphics_scene, gso);
}
// Specialization of draw function.
#ifdef CGAL_USE_BASIC_VIEWER
// Specialization of draw function.
template <class T, class C>
void draw(const CGAL_P2_TYPE &ap2,
const char *title="Polygon_2 Basic Viewer")
@ -133,11 +131,11 @@ void draw(const CGAL_P2_TYPE &ap2,
template <class T, class C, class GSOptions>
void draw(const CGAL_P2_TYPE &ap2,
const GSOptions& gs_options,
const GSOptions& gso,
const char *title="Polygon_2 Basic Viewer")
{
CGAL::Graphics_scene buffer;
add_to_graphics_scene(ap2, buffer, gs_options);
add_to_graphics_scene(ap2, buffer, gso);
draw_graphics_scene(buffer, title);
}