mirror of https://github.com/CGAL/cgal
Applied new APIs version in Voronoi 2, with modifications in Basic_viewer_qt.
This commit is contained in:
parent
7404eb629f
commit
cc4aa7cd9d
|
|
@ -399,7 +399,6 @@ public:
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
|
||||||
// Shortcuts to simplify function calls.
|
// Shortcuts to simplify function calls.
|
||||||
template<typename KPoint>
|
template<typename KPoint>
|
||||||
static Local_point get_local_point(const KPoint& p)
|
static Local_point get_local_point(const KPoint& p)
|
||||||
|
|
@ -414,6 +413,7 @@ protected:
|
||||||
get_local_vector(v);
|
get_local_vector(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
void compile_shaders()
|
void compile_shaders()
|
||||||
{
|
{
|
||||||
rendering_program_face.removeAllShaders();
|
rendering_program_face.removeAllShaders();
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,13 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
//
|
//
|
||||||
// Author(s) : Jasmeet Singh <jasmeet.singh.mec11@iitbhu.ac.in>
|
// Author(s) : Jasmeet Singh <jasmeet.singh.mec11@iitbhu.ac.in>
|
||||||
|
// Mostafa Ashraf <mostaphaashraf1996@gmail.com>
|
||||||
|
|
||||||
#ifndef CGAL_DRAW_VORONOI_DIAGRAM_2_H
|
#ifndef CGAL_DRAW_VORONOI_DIAGRAM_2_H
|
||||||
#define CGAL_DRAW_VORONOI_DIAGRAM_2_H
|
#define CGAL_DRAW_VORONOI_DIAGRAM_2_H
|
||||||
|
|
||||||
|
#include <CGAL/Graphic_buffer.h>
|
||||||
|
#include <CGAL/Drawing_functor.h>
|
||||||
#include <CGAL/Qt/Basic_viewer_qt.h>
|
#include <CGAL/Qt/Basic_viewer_qt.h>
|
||||||
#include <CGAL/license/Voronoi_diagram_2.h>
|
#include <CGAL/license/Voronoi_diagram_2.h>
|
||||||
|
|
||||||
|
|
@ -28,306 +31,301 @@
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
||||||
// Default color functor; user can change it to have its own face color
|
namespace draw_function_for_v2
|
||||||
struct DefaultColorFunctorV2
|
|
||||||
{
|
{
|
||||||
template <typename V2>
|
|
||||||
static CGAL::IO::Color run(const V2 &, const typename V2::Face_iterator /*fh*/) {
|
|
||||||
//CGAL::Random random((unsigned int)(std::size_t)(&*fh));
|
|
||||||
//return get_random_color(random);
|
|
||||||
return CGAL::IO::Color(73, 250, 117);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Viewer for Voronoi diagram
|
typedef CGAL::Exact_predicates_inexact_constructions_kernel Local_kernel;
|
||||||
template <class V2, class ColorFunctor>
|
typedef Local_kernel::Point_3 Local_point;
|
||||||
class SimpleVoronoiDiagram2ViewerQt : public Basic_viewer_qt
|
typedef Local_kernel::Vector_3 Local_vector;
|
||||||
|
|
||||||
|
template <typename BufferType = float, class V2>
|
||||||
|
void compute_vertex(typename V2::Vertex_iterator vh, CGAL::Graphic_buffer<BufferType> &graphic_buffer) {
|
||||||
|
|
||||||
|
graphic_buffer.add_point(vh->point());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename BufferType = float, class V2>
|
||||||
|
void compute_dual_vertex(typename V2::Delaunay_graph::Finite_vertices_iterator vi, CGAL::Graphic_buffer<BufferType> &graphic_buffer)
|
||||||
{
|
{
|
||||||
typedef Basic_viewer_qt Base;
|
graphic_buffer.add_point(vi->point(), CGAL::IO::Color(50, 100, 180));
|
||||||
typedef typename V2::Vertex_iterator Vertex_const_handle;
|
}
|
||||||
typedef typename V2::Delaunay_vertex_handle Delaunay_vertex_const_handle;
|
|
||||||
typedef typename V2::Delaunay_graph::Finite_vertices_iterator Dual_vertices_iterator;
|
|
||||||
|
|
||||||
typedef typename V2::Halfedge_iterator Halfedge_const_handle;
|
|
||||||
typedef typename V2::Ccb_halfedge_circulator Ccb_halfedge_circulator;
|
|
||||||
typedef typename V2::Halfedge_handle Halfedge_handle;
|
|
||||||
|
|
||||||
typedef typename V2::Face_iterator Face_const_handle;
|
|
||||||
|
|
||||||
|
template <typename BufferType = float, class V2>
|
||||||
|
void add_segments_and_update_bounding_box(typename V2::Halfedge_handle he, CGAL::Graphic_buffer<BufferType> &graphic_buffer)
|
||||||
|
{
|
||||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
|
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
|
||||||
|
typedef typename V2::Delaunay_vertex_handle Delaunay_vertex_const_handle;
|
||||||
|
|
||||||
public:
|
if (he->is_segment()) {
|
||||||
/// Construct the viewer.
|
graphic_buffer.add_segment(he->source()->point(), he->target()->point());
|
||||||
/// @param av2 the voronoi diagram to view
|
} else {
|
||||||
/// @param title the title of the window
|
|
||||||
/// @param anofaces if true, do not draw faces (faces are not computed; this
|
|
||||||
/// can be useful for very big object where this time could be long)
|
|
||||||
SimpleVoronoiDiagram2ViewerQt(QWidget *parent, const V2 &av2,
|
|
||||||
const char *title = "Basic Voronoi Viewer",
|
|
||||||
bool anofaces = false,
|
|
||||||
bool draw_voronoi_vertices = true,
|
|
||||||
bool draw_delaunay_vertices = true,
|
|
||||||
const ColorFunctor &fcolor = ColorFunctor())
|
|
||||||
: // First draw: vertices; half-edges; faces; multi-color; no inverse
|
|
||||||
// normal
|
|
||||||
Base(parent, title, true, true, true, false, false, true, true),
|
|
||||||
v2(av2), m_nofaces(anofaces),
|
|
||||||
m_draw_voronoi_vertices(draw_voronoi_vertices),
|
|
||||||
m_draw_dual_vertices(draw_delaunay_vertices), m_fcolor(fcolor) {
|
|
||||||
// Add custom key description (see keyPressEvent)
|
|
||||||
setKeyDescription(::Qt::Key_R, "Toggles rays display");
|
|
||||||
setKeyDescription(::Qt::Key_D, "Toggles dual vertices display");
|
|
||||||
setKeyDescription(::Qt::Key_V, "Toggles voronoi vertices display");
|
|
||||||
|
|
||||||
compute_elements();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
void compute_vertex(Vertex_const_handle vh) { add_point(vh->point()); }
|
|
||||||
|
|
||||||
void compute_dual_vertex(Dual_vertices_iterator vi)
|
|
||||||
{
|
|
||||||
add_point(vi->point(), CGAL::IO::Color(50, 100, 180));
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_segments_and_update_bounding_box(Halfedge_handle he)
|
|
||||||
{
|
|
||||||
if (he->is_segment()) {
|
|
||||||
add_segment(he->source()->point(), he->target()->point());
|
|
||||||
} else {
|
|
||||||
Delaunay_vertex_const_handle v1 = he->up();
|
|
||||||
Delaunay_vertex_const_handle v2 = he->down();
|
|
||||||
|
|
||||||
Kernel::Vector_2 direction(v1->point().y() - v2->point().y(),
|
|
||||||
v2->point().x() - v1->point().x());
|
|
||||||
if (he->is_ray()) {
|
|
||||||
Kernel::Point_2 end_point;
|
|
||||||
if (he->has_source()) {
|
|
||||||
end_point = he->source()->point();
|
|
||||||
update_bounding_box_for_ray(end_point, direction);
|
|
||||||
}
|
|
||||||
} else if (he->is_bisector()) {
|
|
||||||
Kernel::Point_2 pointOnLine((v1->point().x() + v2->point().x()) / 2,
|
|
||||||
(v1->point().y() + v2->point().y()) / 2);
|
|
||||||
Kernel::Vector_2 perpendicularDirection(
|
|
||||||
v2->point().x() - v1->point().x(),
|
|
||||||
v2->point().y() - v1->point().y());
|
|
||||||
update_bounding_box_for_line(pointOnLine, direction,
|
|
||||||
perpendicularDirection);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Local_kernel::Point_2 get_second_point(Halfedge_handle ray)
|
|
||||||
{
|
|
||||||
Delaunay_vertex_const_handle v1 = ray->up();
|
|
||||||
Delaunay_vertex_const_handle v2 = ray->down();
|
|
||||||
|
|
||||||
// calculate direction of ray and its inverse
|
|
||||||
Kernel::Vector_2 v(v1->point().y() - v2->point().y(),
|
|
||||||
v2->point().x() - v1->point().x());
|
|
||||||
Local_kernel::Vector_2 inv(1 / v.x(), 1 / v.y());
|
|
||||||
|
|
||||||
// origin of the ray
|
|
||||||
Kernel::Point_2 p;
|
|
||||||
if (ray->has_source()) {
|
|
||||||
p = ray->source()->point();
|
|
||||||
} else {
|
|
||||||
p = ray->target()->point();
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the bounding box of the viewer
|
|
||||||
Local_kernel::Vector_2 boundsMin(m_bounding_box.xmin(),
|
|
||||||
m_bounding_box.zmin());
|
|
||||||
Local_kernel::Vector_2 boundsMax(m_bounding_box.xmax(),
|
|
||||||
m_bounding_box.zmax());
|
|
||||||
// calculate intersection
|
|
||||||
double txmax, txmin, tymax, tymin;
|
|
||||||
|
|
||||||
if (inv.x() >= 0) {
|
|
||||||
txmax = (boundsMax.x() - p.x()) * inv.x();
|
|
||||||
txmin = (boundsMin.x() - p.x()) * inv.x();
|
|
||||||
} else {
|
|
||||||
txmax = (boundsMin.x() - p.x()) * inv.x();
|
|
||||||
txmin = (boundsMax.x() - p.x()) * inv.x();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inv.y() >= 0) {
|
|
||||||
tymax = (boundsMax.y() - p.y()) * inv.y();
|
|
||||||
tymin = (boundsMin.y() - p.y()) * inv.y();
|
|
||||||
} else {
|
|
||||||
tymax = (boundsMin.y() - p.y()) * inv.y();
|
|
||||||
tymin = (boundsMax.y() - p.y()) * inv.y();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tymin > txmin)
|
|
||||||
txmin = tymin;
|
|
||||||
if (tymax < txmax)
|
|
||||||
txmax = tymax;
|
|
||||||
|
|
||||||
Local_kernel::Point_2 p1;
|
|
||||||
if (v.x() == 0) {
|
|
||||||
p1 = Local_kernel::Point_2(p.x(), p.y() + tymax * v.y());
|
|
||||||
} else if (v.y() == 0) {
|
|
||||||
p1 = Local_kernel::Point_2(p.x() + txmax * v.x(), p.y());
|
|
||||||
} else {
|
|
||||||
p1 = Local_kernel::Point_2(p.x() + txmax * v.x(), p.y() + tymax * v.y());
|
|
||||||
}
|
|
||||||
return p1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void compute_rays_and_bisectors(Halfedge_const_handle he)
|
|
||||||
{
|
|
||||||
Delaunay_vertex_const_handle v1 = he->up();
|
Delaunay_vertex_const_handle v1 = he->up();
|
||||||
Delaunay_vertex_const_handle v2 = he->down();
|
Delaunay_vertex_const_handle v2 = he->down();
|
||||||
|
|
||||||
Kernel::Vector_2 direction(v1->point().y() - v2->point().y(),
|
Kernel::Vector_2 direction(v1->point().y() - v2->point().y(),
|
||||||
v2->point().x() - v1->point().x());
|
v2->point().x() - v1->point().x());
|
||||||
if (he->is_ray()) {
|
if (he->is_ray()) {
|
||||||
|
Kernel::Point_2 end_point;
|
||||||
if (he->has_source()) {
|
if (he->has_source()) {
|
||||||
// add_ray_segment(he->source()->point(), get_second_point(he));
|
end_point = he->source()->point();
|
||||||
add_ray(he->source()->point(), direction, CGAL::IO::Color(100, 0, 0));
|
|
||||||
|
// update_bounding_box_for_ray(end_point, direction);
|
||||||
|
|
||||||
|
// update_bounding_box_for_ray
|
||||||
|
Local_point lp = Basic_viewer_qt<>::get_local_point(end_point);
|
||||||
|
Local_vector lv = Basic_viewer_qt<>::get_local_vector(direction);
|
||||||
|
CGAL::Bbox_3 b = (lp + lv).bbox();
|
||||||
|
graphic_buffer.update_bounding_box(b);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
} else if (he->is_bisector()) {
|
} else if (he->is_bisector()) {
|
||||||
Kernel::Point_2 pointOnLine((v1->point().x() + v2->point().x()) / 2,
|
Kernel::Point_2 pointOnLine((v1->point().x() + v2->point().x()) / 2,
|
||||||
(v1->point().y() + v2->point().y()) / 2);
|
(v1->point().y() + v2->point().y()) / 2);
|
||||||
add_line(pointOnLine, direction);
|
Kernel::Vector_2 perpendicularDirection(
|
||||||
|
v2->point().x() - v1->point().x(),
|
||||||
|
v2->point().y() - v1->point().y());
|
||||||
|
|
||||||
|
// update_bounding_box_for_line(pointOnLine, direction,
|
||||||
|
// perpendicularDirection);
|
||||||
|
|
||||||
|
// update_bounding_box_for_line
|
||||||
|
Local_point lp = Basic_viewer_qt<>::get_local_point(pointOnLine);
|
||||||
|
Local_vector lv = Basic_viewer_qt<>::get_local_vector(direction);
|
||||||
|
Local_vector lpv = Basic_viewer_qt<>::get_local_vector(perpendicularDirection);
|
||||||
|
|
||||||
|
CGAL::Bbox_3 b = lp.bbox() + (lp + lv).bbox() + (lp + lpv).bbox();
|
||||||
|
graphic_buffer.update_bounding_box(b);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class V2>
|
||||||
|
Local_kernel::Point_2 get_second_point(typename V2::Halfedge_handle ray, const CGAL::Bbox_3 & m_bounding_box)
|
||||||
|
{
|
||||||
|
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
|
||||||
|
typedef typename V2::Delaunay_vertex_handle Delaunay_vertex_const_handle;
|
||||||
|
|
||||||
|
Delaunay_vertex_const_handle v1 = ray->up();
|
||||||
|
Delaunay_vertex_const_handle v2 = ray->down();
|
||||||
|
|
||||||
|
// calculate direction of ray and its inverse
|
||||||
|
Kernel::Vector_2 v(v1->point().y() - v2->point().y(),
|
||||||
|
v2->point().x() - v1->point().x());
|
||||||
|
Local_kernel::Vector_2 inv(1 / v.x(), 1 / v.y());
|
||||||
|
|
||||||
|
// origin of the ray
|
||||||
|
Kernel::Point_2 p;
|
||||||
|
if (ray->has_source()) {
|
||||||
|
p = ray->source()->point();
|
||||||
|
} else {
|
||||||
|
p = ray->target()->point();
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the bounding box of the viewer
|
||||||
|
Local_kernel::Vector_2 boundsMin(m_bounding_box.xmin(),
|
||||||
|
m_bounding_box.zmin());
|
||||||
|
Local_kernel::Vector_2 boundsMax(m_bounding_box.xmax(),
|
||||||
|
m_bounding_box.zmax());
|
||||||
|
// calculate intersection
|
||||||
|
double txmax, txmin, tymax, tymin;
|
||||||
|
|
||||||
|
if (inv.x() >= 0) {
|
||||||
|
txmax = (boundsMax.x() - p.x()) * inv.x();
|
||||||
|
txmin = (boundsMin.x() - p.x()) * inv.x();
|
||||||
|
} else {
|
||||||
|
txmax = (boundsMin.x() - p.x()) * inv.x();
|
||||||
|
txmin = (boundsMax.x() - p.x()) * inv.x();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inv.y() >= 0) {
|
||||||
|
tymax = (boundsMax.y() - p.y()) * inv.y();
|
||||||
|
tymin = (boundsMin.y() - p.y()) * inv.y();
|
||||||
|
} else {
|
||||||
|
tymax = (boundsMin.y() - p.y()) * inv.y();
|
||||||
|
tymin = (boundsMax.y() - p.y()) * inv.y();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tymin > txmin)
|
||||||
|
txmin = tymin;
|
||||||
|
if (tymax < txmax)
|
||||||
|
txmax = tymax;
|
||||||
|
|
||||||
|
Local_kernel::Point_2 p1;
|
||||||
|
if (v.x() == 0) {
|
||||||
|
p1 = Local_kernel::Point_2(p.x(), p.y() + tymax * v.y());
|
||||||
|
} else if (v.y() == 0) {
|
||||||
|
p1 = Local_kernel::Point_2(p.x() + txmax * v.x(), p.y());
|
||||||
|
} else {
|
||||||
|
p1 = Local_kernel::Point_2(p.x() + txmax * v.x(), p.y() + tymax * v.y());
|
||||||
|
}
|
||||||
|
return p1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Halfedge_const_handle
|
||||||
|
template <typename BufferType = float, class V2>
|
||||||
|
void compute_rays_and_bisectors(typename V2::Halfedge_iterator he, CGAL::Graphic_buffer<BufferType> &graphic_buffer)
|
||||||
|
{
|
||||||
|
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
|
||||||
|
typedef typename V2::Delaunay_vertex_handle Delaunay_vertex_const_handle;
|
||||||
|
|
||||||
|
Delaunay_vertex_const_handle v1 = he->up();
|
||||||
|
Delaunay_vertex_const_handle v2 = he->down();
|
||||||
|
|
||||||
|
Kernel::Vector_2 direction(v1->point().y() - v2->point().y(),
|
||||||
|
v2->point().x() - v1->point().x());
|
||||||
|
if (he->is_ray()) {
|
||||||
|
if (he->has_source()) {
|
||||||
|
// add_ray_segment(he->source()->point(), get_second_point(he, graphic_buffer.get_bounding_box()));
|
||||||
|
graphic_buffer.add_ray(he->source()->point(), direction, CGAL::IO::Color(100, 0, 0));
|
||||||
|
}
|
||||||
|
} else if (he->is_bisector()) {
|
||||||
|
Kernel::Point_2 pointOnLine((v1->point().x() + v2->point().x()) / 2,
|
||||||
|
(v1->point().y() + v2->point().y()) / 2);
|
||||||
|
graphic_buffer.add_line(pointOnLine, direction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename BufferType = float, class V2, class DrawingFunctor>
|
||||||
|
void compute_face(typename V2::Face_iterator fh, const V2& v2, CGAL::Graphic_buffer<BufferType> &graphic_buffer, const DrawingFunctor &m_drawing_functor)
|
||||||
|
{
|
||||||
|
typedef typename V2::Ccb_halfedge_circulator Ccb_halfedge_circulator;
|
||||||
|
|
||||||
|
if(m_drawing_functor.colored_face(v2, fh)) {
|
||||||
|
|
||||||
|
CGAL::IO::Color c = m_drawing_functor.face_color(v2, fh);
|
||||||
|
|
||||||
|
Ccb_halfedge_circulator ec_start = fh->ccb();
|
||||||
|
Ccb_halfedge_circulator ec = ec_start;
|
||||||
|
|
||||||
|
if (!fh->is_unbounded()) {
|
||||||
|
graphic_buffer.face_begin(c);
|
||||||
|
do {
|
||||||
|
graphic_buffer.add_point_in_face(ec->source()->point());
|
||||||
|
} while (++ec != ec_start);
|
||||||
|
graphic_buffer.face_end();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
// Test: for unbounded faces
|
||||||
|
// else {
|
||||||
|
// do{
|
||||||
|
// if( ec->has_source() ){
|
||||||
|
// add_point_in_face(ec->source()->point());
|
||||||
|
// }
|
||||||
|
// else{
|
||||||
|
// add_point_in_face(get_second_point(ec->twin(), graphic_buffer.get_bounding_box()));
|
||||||
|
// }
|
||||||
|
// } while(++ec != ec_start);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename BufferType = float, class V2, class DrawingFunctor>
|
||||||
|
void compute_elements(const V2& v2, CGAL::Graphic_buffer<BufferType> &graphic_buffer,
|
||||||
|
const DrawingFunctor &m_drawing_functor , bool m_nofaces = false, bool m_draw_voronoi_vertices = true, bool m_draw_dual_vertices = true)
|
||||||
|
{
|
||||||
|
typedef typename V2::Delaunay_graph::Finite_vertices_iterator Dual_vertices_iterator;
|
||||||
|
|
||||||
|
// Draw the voronoi vertices
|
||||||
|
if (m_draw_voronoi_vertices) {
|
||||||
|
for (typename V2::Vertex_iterator it = v2.vertices_begin();
|
||||||
|
it != v2.vertices_end(); ++it) {
|
||||||
|
compute_vertex<BufferType, V2>(it, graphic_buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void compute_face(Face_const_handle fh)
|
// Draw the dual vertices
|
||||||
|
if (m_draw_dual_vertices) {
|
||||||
|
for (Dual_vertices_iterator it = v2.dual().finite_vertices_begin();
|
||||||
|
it != v2.dual().finite_vertices_end(); ++it) {
|
||||||
|
compute_dual_vertex<BufferType, V2>(it, graphic_buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add segments and update bounding box
|
||||||
|
for (typename V2::Halfedge_iterator it = v2.halfedges_begin();
|
||||||
|
it != v2.halfedges_end(); ++it) {
|
||||||
|
add_segments_and_update_bounding_box<BufferType, V2>(it, graphic_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (typename V2::Halfedge_iterator it = v2.halfedges_begin();
|
||||||
|
it != v2.halfedges_end(); ++it) {
|
||||||
|
compute_rays_and_bisectors<BufferType, V2>(it, graphic_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_nofaces) {
|
||||||
|
for (typename V2::Face_iterator it = v2.faces_begin();
|
||||||
|
it != v2.faces_end(); ++it) {
|
||||||
|
compute_face(it, v2, graphic_buffer, m_drawing_functor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace draw_function_for_v2
|
||||||
|
|
||||||
|
template <typename BufferType = float, class V2, class DrawingFunctor>
|
||||||
|
void add_in_graphic_buffer(const V2 &v2, CGAL::Graphic_buffer<BufferType> &graphic_buffer,
|
||||||
|
const DrawingFunctor &m_drawing_functor, bool m_nofaces = false,
|
||||||
|
bool m_draw_voronoi_vertices = true, bool m_draw_dual_vertices = true ) {
|
||||||
|
draw_function_for_v2::compute_elements(v2, graphic_buffer, m_drawing_functor, m_nofaces, m_draw_voronoi_vertices, m_draw_dual_vertices);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename BufferType = float, class V2>
|
||||||
|
void add_in_graphic_buffer(const V2 &v2, CGAL::Graphic_buffer<BufferType> &graphic_buffer,
|
||||||
|
bool m_nofaces = false, bool m_draw_voronoi_vertices = true,
|
||||||
|
bool m_draw_dual_vertices = true ) {
|
||||||
|
|
||||||
|
// Default functor; user can add his own functor.
|
||||||
|
Drawing_functor<V2, typename V2::Vertex_iterator,
|
||||||
|
typename V2::Halfedge_iterator,
|
||||||
|
typename V2::Face_iterator>
|
||||||
|
drawing_functor;
|
||||||
|
|
||||||
|
drawing_functor.colored_face = [](const V2&,
|
||||||
|
typename V2::Face_iterator fh) -> bool
|
||||||
|
{ return true; };
|
||||||
|
|
||||||
|
|
||||||
|
drawing_functor.face_color = [] (const V2& alcc,
|
||||||
|
typename V2::Face_iterator fh) -> CGAL::IO::Color
|
||||||
{
|
{
|
||||||
CGAL::IO::Color c = m_fcolor.run(v2, fh);
|
return CGAL::IO::Color(73, 250, 117);
|
||||||
|
};
|
||||||
|
|
||||||
Ccb_halfedge_circulator ec_start = fh->ccb();
|
add_in_graphic_buffer(v2, graphic_buffer, drawing_functor, m_nofaces, m_draw_voronoi_vertices, m_draw_dual_vertices);
|
||||||
Ccb_halfedge_circulator ec = ec_start;
|
}
|
||||||
|
|
||||||
if (!fh->is_unbounded()) {
|
|
||||||
face_begin(c);
|
|
||||||
do {
|
|
||||||
add_point_in_face(ec->source()->point());
|
|
||||||
} while (++ec != ec_start);
|
|
||||||
face_end();
|
|
||||||
}
|
|
||||||
// Test: for unbounded faces
|
|
||||||
// else {
|
|
||||||
// do{
|
|
||||||
// if( ec->has_source() ){
|
|
||||||
// add_point_in_face(ec->source()->point());
|
|
||||||
// }
|
|
||||||
// else{
|
|
||||||
// add_point_in_face(get_second_point(ec->twin()));
|
|
||||||
// }
|
|
||||||
// } while(++ec != ec_start);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
void compute_elements()
|
|
||||||
{
|
|
||||||
clear();
|
|
||||||
|
|
||||||
// Draw the voronoi vertices
|
|
||||||
if (m_draw_voronoi_vertices) {
|
|
||||||
for (typename V2::Vertex_iterator it = v2.vertices_begin();
|
|
||||||
it != v2.vertices_end(); ++it) {
|
|
||||||
compute_vertex(it);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw the dual vertices
|
|
||||||
if (m_draw_dual_vertices) {
|
|
||||||
for (Dual_vertices_iterator it = v2.dual().finite_vertices_begin();
|
|
||||||
it != v2.dual().finite_vertices_end(); ++it) {
|
|
||||||
compute_dual_vertex(it);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add segments and update bounding box
|
|
||||||
for (typename V2::Halfedge_iterator it = v2.halfedges_begin();
|
|
||||||
it != v2.halfedges_end(); ++it) {
|
|
||||||
add_segments_and_update_bounding_box(it);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (typename V2::Halfedge_iterator it = v2.halfedges_begin();
|
|
||||||
it != v2.halfedges_end(); ++it) {
|
|
||||||
compute_rays_and_bisectors(it);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_nofaces) {
|
|
||||||
for (typename V2::Face_iterator it = v2.faces_begin();
|
|
||||||
it != v2.faces_end(); ++it) {
|
|
||||||
compute_face(it);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void keyPressEvent(QKeyEvent *e)
|
|
||||||
{
|
|
||||||
/// [Keypress]
|
|
||||||
const ::Qt::KeyboardModifiers modifiers = e->modifiers();
|
|
||||||
if ((e->key() == ::Qt::Key_R) && (modifiers == ::Qt::NoButton)) {
|
|
||||||
m_draw_rays = !m_draw_rays;
|
|
||||||
displayMessage(
|
|
||||||
QString("Draw rays=%1.").arg(m_draw_rays ? "true" : "false"));
|
|
||||||
update();
|
|
||||||
} else if ((e->key() == ::Qt::Key_V) && (modifiers == ::Qt::NoButton)) {
|
|
||||||
m_draw_voronoi_vertices = !m_draw_voronoi_vertices;
|
|
||||||
displayMessage(
|
|
||||||
QString("Voronoi vertices=%1.").arg(m_draw_voronoi_vertices? "true" : "false"));
|
|
||||||
compute_elements();
|
|
||||||
redraw();
|
|
||||||
} else if ((e->key() == ::Qt::Key_D) && (modifiers == ::Qt::NoButton)) {
|
|
||||||
m_draw_dual_vertices = !m_draw_dual_vertices;
|
|
||||||
displayMessage(QString("Dual vertices=%1.")
|
|
||||||
.arg(m_draw_dual_vertices ? "true" : "false"));
|
|
||||||
compute_elements();
|
|
||||||
redraw();
|
|
||||||
} else {
|
|
||||||
// Call the base method to process others/classicals key
|
|
||||||
Base::keyPressEvent(e);
|
|
||||||
}
|
|
||||||
/// [Keypress]
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
const V2 &v2;
|
|
||||||
bool m_nofaces;
|
|
||||||
bool m_draw_voronoi_vertices;
|
|
||||||
bool m_draw_dual_vertices;
|
|
||||||
const ColorFunctor &m_fcolor;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Specialization of draw function.
|
// Specialization of draw function.
|
||||||
#define CGAL_VORONOI_TYPE CGAL::Voronoi_diagram_2 <DG, AT, AP>
|
#define CGAL_VORONOI_TYPE CGAL::Voronoi_diagram_2 <DG, AT, AP>
|
||||||
|
|
||||||
template<class DG,
|
template<class DG,
|
||||||
class AT,
|
class AT,
|
||||||
class AP>
|
class AP, typename BufferType = float, class DrawingFunctor>
|
||||||
|
void draw(const CGAL_VORONOI_TYPE &av2,
|
||||||
|
const DrawingFunctor &drawing_functor,
|
||||||
|
bool nofill = false,
|
||||||
|
bool draw_voronoi_vertices = true,
|
||||||
|
bool draw_dual_vertices = true)
|
||||||
|
{
|
||||||
|
CGAL::Graphic_buffer<BufferType> buffer;
|
||||||
|
add_in_graphic_buffer(av2, buffer, drawing_functor, nofill, draw_voronoi_vertices, draw_dual_vertices);
|
||||||
|
draw_buffer(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class DG,
|
||||||
|
class AT,
|
||||||
|
class AP, typename BufferType = float>
|
||||||
void draw(const CGAL_VORONOI_TYPE &av2,
|
void draw(const CGAL_VORONOI_TYPE &av2,
|
||||||
const char *title="2D Voronoi Diagram Basic Viewer",
|
const char *title="2D Voronoi Diagram Basic Viewer",
|
||||||
bool nofill = false,
|
bool nofill = false,
|
||||||
bool draw_voronoi_vertices = true,
|
bool draw_voronoi_vertices = true,
|
||||||
bool draw_dual_vertices = true)
|
bool draw_dual_vertices = true)
|
||||||
{
|
{
|
||||||
#if defined(CGAL_TEST_SUITE)
|
CGAL::Graphic_buffer<BufferType> buffer;
|
||||||
bool cgal_test_suite = true;
|
add_in_graphic_buffer(av2, buffer, nofill, draw_voronoi_vertices, draw_dual_vertices);
|
||||||
#else
|
draw_buffer(buffer);
|
||||||
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] = {"voronoi_2_viewer", nullptr};
|
|
||||||
QApplication app(argc, const_cast<char **>(argv));
|
|
||||||
DefaultColorFunctorV2 fcolor;
|
|
||||||
SimpleVoronoiDiagram2ViewerQt<CGAL_VORONOI_TYPE, DefaultColorFunctorV2>
|
|
||||||
mainwindow(app.activeWindow(), av2, title, nofill,
|
|
||||||
draw_voronoi_vertices, draw_dual_vertices, fcolor);
|
|
||||||
mainwindow.show();
|
|
||||||
app.exec();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // End namespace CGAL
|
} // End namespace CGAL
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue