mirror of https://github.com/CGAL/cgal
Merge branch 'master' into Surface_mesh_topology-gdamiand
This commit is contained in:
commit
3d0b69be50
|
|
@ -273,7 +273,7 @@ public:
|
|||
add_segment(kp1, kp2);
|
||||
add_color(c);
|
||||
add_color(c);
|
||||
}
|
||||
}
|
||||
|
||||
// 2.3) Add an indexed segment, without color.
|
||||
template<typename T>
|
||||
|
|
@ -900,7 +900,7 @@ protected:
|
|||
|
||||
bool m_inverse_normal;;
|
||||
|
||||
// Local variables, used when we started a new face.
|
||||
// Local variables, used when we started a new face.g
|
||||
bool m_face_started;
|
||||
bool m_started_face_is_colored;
|
||||
bool m_started_face_has_normal;
|
||||
|
|
|
|||
|
|
@ -94,7 +94,6 @@ const char fragment_source_color[] =
|
|||
"uniform float spec_power ; \n"
|
||||
|
||||
"void main(void) { \n"
|
||||
|
||||
" highp vec3 L = light_pos.xyz - fP.xyz; \n"
|
||||
" highp vec3 V = -fP.xyz; \n"
|
||||
|
||||
|
|
@ -105,8 +104,7 @@ const char fragment_source_color[] =
|
|||
" highp vec3 R = reflect(-L, N); \n"
|
||||
" highp vec4 diffuse = max(dot(N,L), 0.0) * light_diff * fColor; \n"
|
||||
" highp vec4 specular = pow(max(dot(R,V), 0.0), spec_power) * light_spec; \n"
|
||||
|
||||
"gl_FragColor = light_amb*fColor + diffuse ; \n"
|
||||
" gl_FragColor = light_amb*fColor + diffuse ; \n"
|
||||
"} \n"
|
||||
"\n"
|
||||
};
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ LC_CTYPE=en_US.UTF-8
|
|||
|
||||
# Launch our Docker testsuite , at 21:36,
|
||||
# after a pull of all new images at 20:23.
|
||||
06 20 * * * /usr/bin/time docker pull -a docker.io/cgal/testsuite-docker; docker rmi $(docker images | awk '/<none>/ {print $3}')
|
||||
06 20 * * * for i in $(cat /home/lrineau/.config/CGAL/test_cgal_docker_images); do docker pull $i; done; docker rmi $(docker images | awk '/<none>/ {print $3}')
|
||||
36 21 * * * cd /home/lrineau/Git/cgal-testsuite-dockerfiles && /usr/bin/time ./test_cgal.py --use-fedora-selinux-policy --force-rm --max-cpus 12 --container-cpus 4 --jobs 5 --upload-results --images $($HOME/bin/docker_images_to_test_today)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
namespace CGAL {
|
||||
|
||||
/*!
|
||||
\ingroup PkgDrawNef3
|
||||
|
||||
Open a new window and draws `anef3`, the `Nef_polyhedron_3`. A call to this function is blocking, that is the program continues as soon as the user closes the window.
|
||||
This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time.
|
||||
\tparam Nef3 a model of the `Nef_polyhedron_3` concept.
|
||||
\param anef3 the nef polyhedron to draw.
|
||||
|
||||
*/
|
||||
template<class Nef3>
|
||||
void draw(const Nef3& anef3);
|
||||
|
||||
} /* namespace CGAL */
|
||||
|
|
@ -425,6 +425,18 @@ the symbolical value, large but finite, for the size of the infimaximal box.
|
|||
|
||||
\cgalExample{Nef_3/extended_kernel.cpp}
|
||||
|
||||
\subsection Nef_3DrawNefPolyhedron Draw a Nef Polyhedron
|
||||
|
||||
A nef polyhedron can be visualised by calling the \link PkgDrawNef3 CGAL::draw<Nef_3>() \endlink function as shown in the following example. This function opens a new window showing the given Nef Polyhedron.
|
||||
|
||||
\cgalExample{Nef_3/draw_nef_3.cpp}
|
||||
|
||||
This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time.
|
||||
|
||||
\cgalFigureBegin{fig_draw_nef_polyhedron, draw_nef_3.png}
|
||||
Result of the run of the draw_nef_3 program. A window shows the nef polyhedron and allows to navigate through the 3D scene.
|
||||
\cgalFigureEnd
|
||||
|
||||
\section Nef_3File File I/O
|
||||
|
||||
\anchor sectionNef_3IO
|
||||
|
|
|
|||
|
|
@ -3,6 +3,13 @@
|
|||
/// \defgroup PkgNef3IOFunctions I/O Functions
|
||||
/// \ingroup PkgNef3Ref
|
||||
|
||||
/*! Draw.
|
||||
\code
|
||||
#include <CGAL/draw_nef_3.h>
|
||||
\endcode
|
||||
*/
|
||||
/// \defgroup PkgDrawNef3 Draw a Nef Polyhedron
|
||||
/// \ingroup PkgNef3Ref
|
||||
|
||||
/*!
|
||||
\addtogroup PkgNef3Ref
|
||||
|
|
@ -64,5 +71,8 @@ a simple OpenGL visualization for debugging and illustrations.
|
|||
- \link PkgNef3IOFunctions `CGAL::operator<<()` \endlink
|
||||
- \link PkgNef3IOFunctions `CGAL::operator>>()` \endlink
|
||||
|
||||
\cgalCRPSection{Draw a Nef Polyhedron}
|
||||
- \link PkgDrawNef3 CGAL::draw<Nef3>() \endlink
|
||||
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -11,3 +11,4 @@ Number_types
|
|||
BGL
|
||||
Surface_mesh
|
||||
Polygon_mesh_processing
|
||||
GraphicsView
|
||||
|
|
|
|||
|
|
@ -17,4 +17,5 @@
|
|||
\example Nef_3/topological_operations.cpp
|
||||
\example Nef_3/transformation.cpp
|
||||
\example Nef_3/nef_3_to_surface_mesh.cpp
|
||||
\example Nef_3/draw_nef_3.cpp
|
||||
*/
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
|
|
@ -6,7 +6,11 @@ cmake_minimum_required(VERSION 3.1...3.15)
|
|||
project( Nef_3_Examples )
|
||||
|
||||
|
||||
find_package(CGAL QUIET)
|
||||
find_package(CGAL COMPONENTS Qt5)
|
||||
|
||||
if(CGAL_Qt5_FOUND)
|
||||
add_definitions(-DCGAL_USE_BASIC_VIEWER -DQT_NO_KEYWORDS)
|
||||
endif()
|
||||
|
||||
if ( CGAL_FOUND )
|
||||
|
||||
|
|
@ -16,6 +20,10 @@ if ( CGAL_FOUND )
|
|||
create_single_source_cgal_program( "${cppfile}" )
|
||||
endforeach()
|
||||
|
||||
if(CGAL_Qt5_FOUND)
|
||||
target_link_libraries(draw_nef_3 PUBLIC CGAL::CGAL_Qt5)
|
||||
endif()
|
||||
|
||||
else()
|
||||
|
||||
message(STATUS "This program requires the CGAL library, and will not be compiled.")
|
||||
|
|
|
|||
|
|
@ -0,0 +1,85 @@
|
|||
OFF
|
||||
40 38 0
|
||||
|
||||
0 3 0
|
||||
1 3 0
|
||||
2 3 0
|
||||
2 4 0
|
||||
2 5 0
|
||||
3 5 0
|
||||
3 4 0
|
||||
3 3 0
|
||||
4 3 0
|
||||
5 3 0
|
||||
5 2 0
|
||||
4 2 0
|
||||
3 2 0
|
||||
3 1 0
|
||||
3 0 0
|
||||
2 0 0
|
||||
2 1 0
|
||||
2 2 0
|
||||
1 2 0
|
||||
0 2 0
|
||||
|
||||
0 3 1
|
||||
1 3 1
|
||||
2 3 1
|
||||
2 4 1
|
||||
2 5 1
|
||||
3 5 1
|
||||
3 4 1
|
||||
3 3 1
|
||||
4 3 1
|
||||
5 3 1
|
||||
5 2 1
|
||||
4 2 1
|
||||
3 2 1
|
||||
3 1 1
|
||||
3 0 1
|
||||
2 0 1
|
||||
2 1 1
|
||||
2 2 1
|
||||
1 2 1
|
||||
0 2 1
|
||||
|
||||
4 0 1 18 19
|
||||
4 1 2 17 18
|
||||
4 2 7 12 17
|
||||
4 2 3 6 7
|
||||
4 3 4 5 6
|
||||
4 7 8 11 12
|
||||
4 8 9 10 11
|
||||
4 12 13 16 17
|
||||
4 13 14 15 16
|
||||
|
||||
4 1 0 20 21
|
||||
4 2 1 21 22
|
||||
4 3 2 22 23
|
||||
4 4 3 23 24
|
||||
4 5 4 24 25
|
||||
4 6 5 25 26
|
||||
4 7 6 26 27
|
||||
4 8 7 27 28
|
||||
4 9 8 28 29
|
||||
4 10 9 29 30
|
||||
4 11 10 30 31
|
||||
4 12 11 31 32
|
||||
4 13 12 32 33
|
||||
4 14 13 33 34
|
||||
4 15 14 34 35
|
||||
4 16 15 35 36
|
||||
4 17 16 36 37
|
||||
4 18 17 37 38
|
||||
4 19 18 38 39
|
||||
4 0 19 39 20
|
||||
|
||||
4 39 38 21 20
|
||||
4 38 37 22 21
|
||||
4 37 32 27 22
|
||||
4 27 26 23 22
|
||||
4 26 25 24 23
|
||||
4 32 31 28 27
|
||||
4 31 30 29 28
|
||||
4 37 36 33 32
|
||||
4 36 35 34 33
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||
#include <CGAL/Nef_polyhedron_3.h>
|
||||
#include <CGAL/Polyhedron_3.h>
|
||||
#include <CGAL/draw_nef_3.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;
|
||||
typedef CGAL::Polyhedron_3<Kernel> Polyhedron;
|
||||
typedef CGAL::Nef_polyhedron_3<Kernel> Nef_polyhedron;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// read OFF file into a polyhedron
|
||||
Polyhedron P;
|
||||
std::ifstream ifs((argc > 1) ? argv[1] : "data/cross.off");
|
||||
ifs >> P;
|
||||
|
||||
// initialize nef from polyhedron
|
||||
Nef_polyhedron N(P);
|
||||
|
||||
// draw Nef Polyhedron
|
||||
CGAL::draw(N);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
@ -0,0 +1,272 @@
|
|||
// Copyright (c) 2019 Max-Planck-Institute Saarbruecken (Germany).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org).
|
||||
//
|
||||
// $URL$
|
||||
// $Id$
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||
//
|
||||
//
|
||||
// Author(s) : Jasmeet Singh <jasmeet.singh.mec11@iitbhu.ac.in>
|
||||
|
||||
#ifndef DRAW_NEF_3_H
|
||||
#define DRAW_NEF_3_H
|
||||
|
||||
#include <CGAL/license/Nef_3.h>
|
||||
#include <CGAL/Qt/Basic_viewer_qt.h>
|
||||
|
||||
#ifdef CGAL_USE_BASIC_VIEWER
|
||||
|
||||
#include <CGAL/Nef_3/SNC_iteration.h>
|
||||
#include <CGAL/circulator.h>
|
||||
#include <CGAL/Random.h>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
// Default color functor; user can change it to have its own face color
|
||||
struct DefaultColorFunctorNefPolyhedron
|
||||
{
|
||||
template<typename NefPolyhedron>
|
||||
static CGAL::Color run(const NefPolyhedron&,
|
||||
typename NefPolyhedron::Halffacet_const_handle fh)
|
||||
{
|
||||
if (fh == nullptr) // use to get the mono color
|
||||
return CGAL::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 Nef_Polyhedron, class ColorFunctor>
|
||||
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;
|
||||
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::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);
|
||||
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.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<Halffacet_const_handle, bool> facets_done;
|
||||
std::unordered_map<Halfedge_const_handle, bool> 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::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;
|
||||
}
|
||||
|
||||
assert(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;
|
||||
};
|
||||
|
||||
#define CGAL_NEF3_TYPE Nef_polyhedron_3<Kernel_, Items_, Mark_>
|
||||
|
||||
template <typename Kernel_, typename Items_, typename Mark_>
|
||||
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)
|
||||
{
|
||||
int argc = 1;
|
||||
const char *argv[2] = {"nef_polyhedron_viewer", "\0"};
|
||||
QApplication app(argc, const_cast<char **>(argv));
|
||||
DefaultColorFunctorNefPolyhedron fcolor;
|
||||
SimpleNefPolyhedronViewerQt<CGAL_NEF3_TYPE,
|
||||
DefaultColorFunctorNefPolyhedron>
|
||||
mainwindow(app.activeWindow(), anef, title, nofill, fcolor);
|
||||
mainwindow.show();
|
||||
app.exec();
|
||||
}
|
||||
}
|
||||
|
||||
} // End namespace CGAL
|
||||
|
||||
#endif // CGAL_USE_BASIC_VIEWER
|
||||
|
||||
#endif // DRAW_NEF_3_H
|
||||
|
|
@ -7,6 +7,7 @@ Circulator
|
|||
Distance_2
|
||||
Distance_3
|
||||
Filtered_kernel
|
||||
GraphicsView
|
||||
HalfedgeDS
|
||||
Hash_map
|
||||
Homogeneous_kernel
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
namespace CGAL {
|
||||
|
||||
/*!
|
||||
\ingroup PkgDrawPeriodic2Triangulation2
|
||||
|
||||
opens a new window and draws `ap2t2`, the `Periodic_2_Triangulation_2`. A call to this function is blocking, that is the program continues as soon as the user closes the window.
|
||||
This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time.
|
||||
\tparam P2T2 a model of the `Periodic_2TriangulationTraits_2` concept.
|
||||
\param ap2t2 the 2D periodic trinagulation to draw.
|
||||
|
||||
*/
|
||||
template<class P2T2>
|
||||
void draw(const P2T2& ap2t2);
|
||||
|
||||
} /* namespace CGAL */
|
||||
|
|
@ -15,6 +15,14 @@
|
|||
/// \defgroup PkgPeriodic2Triangulation2Enums Enums
|
||||
/// \ingroup PkgPeriodic2Triangulation2Ref
|
||||
|
||||
/*! Draw.
|
||||
\code
|
||||
#include <CGAL/draw_periodic_2_triangulation_2.h>
|
||||
\endcode
|
||||
*/
|
||||
/// \defgroup PkgDrawPeriodic2Triangulation2 Draw a 2D Periodic Triangulation
|
||||
/// \ingroup PkgPeriodic2Triangulation2Ref
|
||||
|
||||
/*!
|
||||
\addtogroup PkgPeriodic2Triangulation2Ref
|
||||
|
||||
|
|
@ -103,5 +111,8 @@ of the concept `Periodic_2Offset_2`.
|
|||
- `CGAL::Periodic_2_triangulation_2::Iterator_type`
|
||||
- `CGAL::Periodic_2_triangulation_2::Locate_type`
|
||||
|
||||
\cgalCRPSection{Draw 2D Periodic Triangulation}
|
||||
- \link PkgDrawPeriodic2Triangulation2 CGAL::draw<P2T2>() \endlink
|
||||
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -394,6 +394,26 @@ in the unit rectangle. The tests were done on an Intel i7 @ 2.67GHz.
|
|||
\image html p2dt2_performance.png
|
||||
\image latex p2dt2_performance.png
|
||||
|
||||
\section P2T2_Draw_Periodic_Triangulation Draw a 2D Periodic Triangulation
|
||||
|
||||
A 2D periodic triangulation can be visualized by calling the \link PkgDrawPeriodic2Triangulation2 CGAL::draw<P2T2>() \endlink function as shown in the following example. This function opens a new window showing the given Periodic Triangulation. Elements of the periodic triangulation can be viewed in four different modes:
|
||||
|
||||
\cgalExample{Periodic_2_triangulation_2/draw_periodic_2_triangulation_2.cpp}
|
||||
|
||||
- <B>STORED</B> Display all geometric primitives as they are stored in Triangulation_data_structure_2;
|
||||
- <B>UNIQUE</B> Display only one representative of each geometric primitive even if the triangulation is computed in multiply sheeted covering space;
|
||||
- <B>STORED_COVER_DOMAIN</B> Same as STORED but also display all primitives whose intersection with the original domain of the current covering space is non-empty;
|
||||
- <B>UNIQUE_COVER_DOMAIN</B> Same as UNIQUE but also display all primitives whose intersection with the original domain of the current covering space is non-empty.
|
||||
|
||||
The domain can also be visualized by a key press. To see how to visualize the Periodic Triangulation in various modes, press key H when the viewer window is active and go to Keyboard tab. See \cgalFigureRef{P2Triangulation2figdraw1} and \cgalFigureRef{P2Triangulation2figdraw2}.
|
||||
|
||||
\cgalFigureBegin{P2Triangulation2figdraw1, unique.png, unique-cover.png}
|
||||
Result of the run of the draw_periodic_2_triangulation_2 program for display modes Unique(left) and Unique Cover Domain(right). The window allows to navigate through the 2D scene.
|
||||
\cgalFigureEnd
|
||||
\cgalFigureBegin{P2Triangulation2figdraw2, stored.png, stored-cover.png}
|
||||
Result of the run of the draw_periodic_2_triangulation_2 program for display modes Stored(left) and Stored Cover Domain(right).
|
||||
\cgalFigureEnd
|
||||
|
||||
\section P2T2_Design Design and Implementation History
|
||||
|
||||
The periodic 2D-triangulation is based on the 2D triangulation package
|
||||
|
|
|
|||
|
|
@ -7,3 +7,4 @@ Stream_support
|
|||
TDS_2
|
||||
Triangulation_2
|
||||
Spatial_sorting
|
||||
GraphicsView
|
||||
|
|
|
|||
|
|
@ -9,4 +9,5 @@
|
|||
\example Periodic_2_triangulation_2/p2t2_info_insert_with_transform_iterator_2.cpp
|
||||
\example Periodic_2_triangulation_2/p2t2_info_insert_with_zip_iterator_2.cpp
|
||||
\example Periodic_2_triangulation_2/p2t2_large_point_set.cpp
|
||||
\example Periodic_2_triangulation_2/draw_periodic_2_triangulation_2.cpp
|
||||
*/
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 39 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 36 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
|
|
@ -6,7 +6,11 @@ cmake_minimum_required(VERSION 3.1...3.15)
|
|||
project( Periodic_2_triangulation_2_Examples )
|
||||
|
||||
|
||||
find_package(CGAL QUIET)
|
||||
find_package(CGAL COMPONENTS Qt5)
|
||||
|
||||
if(CGAL_Qt5_FOUND)
|
||||
add_definitions(-DCGAL_USE_BASIC_VIEWER -DQT_NO_KEYWORDS)
|
||||
endif()
|
||||
|
||||
if ( CGAL_FOUND )
|
||||
|
||||
|
|
@ -16,6 +20,9 @@ if ( CGAL_FOUND )
|
|||
create_single_source_cgal_program( "${cppfile}" )
|
||||
endforeach()
|
||||
|
||||
if(CGAL_Qt5_FOUND)
|
||||
target_link_libraries(draw_periodic_2_triangulation_2 PUBLIC CGAL::CGAL_Qt5)
|
||||
endif()
|
||||
else()
|
||||
|
||||
message(STATUS "This program requires the CGAL library, and will not be compiled.")
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
0.192592592592593 0.037037037037037
|
||||
0.17037037037037 0.177777777777778
|
||||
0.451851851851852 0.111111111111111
|
||||
0.274074074074074 0.37037037037037
|
||||
0.133333333333333 0.592592592592593
|
||||
0.037037037037037 0.688888888888889
|
||||
0.177777777777778 0.844444444444444
|
||||
0.288888888888889 0.674074074074074
|
||||
0.318518518518519 0.925925925925926
|
||||
0.540740740740741 0.844444444444444
|
||||
0.637037037037037 0.703703703703704
|
||||
0.511111111111111 0.496296296296296
|
||||
0.725925925925926 0.237037037037037
|
||||
0.933333333333333 0.22962962962963
|
||||
0.733333333333333 0.511111111111111
|
||||
0.925925925925926 0.459259259259259
|
||||
0.866666666666667 0.777777777777778
|
||||
0.77037037037037 0.925925925925926
|
||||
0.881481481481482 0.977777777777778
|
||||
0.990000000000000 0.911111111111111
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
#include <CGAL/Periodic_2_Delaunay_triangulation_2.h>
|
||||
#include <CGAL/Periodic_2_Delaunay_triangulation_traits_2.h>
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/draw_periodic_2_triangulation_2.h>
|
||||
|
||||
#include <fstream>
|
||||
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
|
||||
typedef CGAL::Periodic_2_Delaunay_triangulation_traits_2<K> GT;
|
||||
typedef CGAL::Periodic_2_Delaunay_triangulation_2<GT> PDT;
|
||||
|
||||
typedef PDT::Point Point;
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
// Declare periodic triangulation 2D
|
||||
PDT T;
|
||||
|
||||
// Read points and insert in T
|
||||
Point p;
|
||||
std::ifstream ifs((argc > 1) ? argv[1] : "data/data1.dt.cin");
|
||||
if (ifs)
|
||||
{
|
||||
while (ifs >> p)
|
||||
{ T.insert(p); }
|
||||
CGAL_assertion(T.is_valid());
|
||||
|
||||
if( T.is_triangulation_in_1_sheet())
|
||||
{ T.convert_to_9_sheeted_covering(); }
|
||||
|
||||
// Draw the periodic triangulation
|
||||
CGAL::draw(T);
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
@ -0,0 +1,279 @@
|
|||
// Copyright (c) 2019 INRIA Sophia-Antipolis (France).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org).
|
||||
//
|
||||
// $URL$
|
||||
// $Id$
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||
//
|
||||
// Author(s) : Jasmeet Singh <jasmeet.singh.mec11@iitbhu.ac.in>
|
||||
|
||||
#ifndef DRAW_PERIODIC_2_TRIANGULATION_2_H
|
||||
#define DRAW_PERIODIC_2_TRIANGULATION_2_H
|
||||
|
||||
#include <CGAL/license/Periodic_2_triangulation_2.h>
|
||||
#include <CGAL/Qt/Basic_viewer_qt.h>
|
||||
|
||||
#ifdef CGAL_USE_BASIC_VIEWER
|
||||
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Random.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
// Default color functor; user can change it to have its own face color
|
||||
struct DefaultColorFunctorP2T2 {
|
||||
template <typename P2T2>
|
||||
static CGAL::Color run(const P2T2 &,
|
||||
const typename P2T2::Periodic_triangle_iterator /*ti*/) {
|
||||
//CGAL::Random random((unsigned int)(std::size_t)(&*ti));
|
||||
//return get_random_color(random);
|
||||
return CGAL::Color(73, 250, 117);
|
||||
}
|
||||
};
|
||||
|
||||
// Viewer class for P2T2
|
||||
template <class P2T2, class ColorFunctor>
|
||||
class SimplePeriodic2Triangulation2ViewerQt : public Basic_viewer_qt
|
||||
{
|
||||
typedef Basic_viewer_qt Base;
|
||||
|
||||
typedef typename P2T2::Iterator_type Iterator_type;
|
||||
|
||||
// Vertex iterators
|
||||
typedef typename P2T2::Periodic_point_iterator Periodic_point_iterator;
|
||||
|
||||
// Edge iterators
|
||||
typedef typename P2T2::Periodic_segment_iterator Periodic_segment_iterator;
|
||||
typedef typename P2T2::Segment Segment;
|
||||
|
||||
// Face iterators
|
||||
typedef typename P2T2::Periodic_triangle_iterator Periodic_triangle_iterator;
|
||||
typedef typename P2T2::Triangle Triangle;
|
||||
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
|
||||
|
||||
public:
|
||||
/// Construct the viewer.
|
||||
/// @param ap2t2 the p2t2 to view
|
||||
/// @param title the title of the window
|
||||
/// @param anofaces if true, do not draw faces (faces are not computed; this can be
|
||||
/// usefull for very big object where this time could be long)
|
||||
SimplePeriodic2Triangulation2ViewerQt(QWidget* parent, const P2T2& ap2t2,
|
||||
const char* title="Basic P2T2 Viewer",
|
||||
bool anofaces=false,
|
||||
const ColorFunctor& fcolor=ColorFunctor()) :
|
||||
// First draw: vertices; edges, faces; multi-color; no inverse normal
|
||||
Base(parent, title, true, true, true, false, false),
|
||||
p2t2(ap2t2),
|
||||
m_nofaces(anofaces),
|
||||
m_fcolor(fcolor),
|
||||
m_display_type(STORED_COVER_DOMAIN),
|
||||
m_domain(true)
|
||||
{
|
||||
// Add custom key description (see keyPressEvent).
|
||||
setKeyDescription(::Qt::Key_1, "STORED: Display all geometric primitives as they are stored in "
|
||||
"Triangulation_data_structure_2");
|
||||
setKeyDescription(::Qt::Key_2, "UNIQUE: Display only one representative of each geometric primitive even "
|
||||
"if the triangulation is computed in multiply sheeted covering space.");
|
||||
setKeyDescription(::Qt::Key_3, "STORED_COVER_DOMAIN: Same as STORED but also display "
|
||||
"all primitives whose intersection with the original "
|
||||
"domain of the current covering space is non-empty");
|
||||
setKeyDescription(::Qt::Key_4, "UNIQUE_COVER_DOMAIN: Same as UNIQUE but also display "
|
||||
"all primitives whose intersection with the original "
|
||||
"domain of the current covering space is non-empty");
|
||||
setKeyDescription(::Qt::Key_D, "Toggle 9-sheeted domain display");
|
||||
|
||||
compute_elements();
|
||||
}
|
||||
protected:
|
||||
void compute_vertex(Periodic_point_iterator pi)
|
||||
{
|
||||
// Construct the point in 9-sheeted covering space and add to viewer
|
||||
add_point(p2t2.point(*pi));
|
||||
}
|
||||
|
||||
void compute_edge(Periodic_segment_iterator si)
|
||||
{
|
||||
// Construct the segment in 9-sheeted covering space and add to viewer
|
||||
Segment s(p2t2.segment(*si));
|
||||
add_segment(s[0], s[1]);
|
||||
}
|
||||
|
||||
void compute_face(Periodic_triangle_iterator ti)
|
||||
{
|
||||
// Construct the triangle in 9-sheeted covering space and add to viewer
|
||||
Triangle t(p2t2.triangle(*ti));
|
||||
|
||||
CGAL::Color c=m_fcolor.run(p2t2, ti);
|
||||
face_begin(c);
|
||||
add_point_in_face(t[0]);
|
||||
add_point_in_face(t[1]);
|
||||
add_point_in_face(t[2]);
|
||||
face_end();
|
||||
|
||||
// Display the edges of the faces as segments with a
|
||||
// light gray color for better visualization
|
||||
add_segment(t[0], t[1], CGAL::Color(207, 213, 211));
|
||||
add_segment(t[1], t[2], CGAL::Color(207, 213, 211));
|
||||
add_segment(t[2], t[0], CGAL::Color(207, 213, 211));
|
||||
}
|
||||
|
||||
void compute_domain()
|
||||
{
|
||||
Kernel::Iso_rectangle_2 orig_domain = p2t2.domain();
|
||||
std::array<int, 2> covering_sheets = p2t2.number_of_sheets();
|
||||
|
||||
for(int i = 0; i < covering_sheets[0]; i++){
|
||||
for(int j = 0; j < covering_sheets[1]; j++){
|
||||
Kernel::Vector_2 shift(i * (orig_domain.xmax() - orig_domain.xmin()),
|
||||
j * orig_domain.ymax() - orig_domain.ymin());
|
||||
Kernel::Point_2 p1(orig_domain.min());
|
||||
Kernel::Point_2 p2(orig_domain.xmin(), orig_domain.ymax());
|
||||
Kernel::Point_2 p3(orig_domain.xmax(), orig_domain.ymin());
|
||||
Kernel::Point_2 p4(orig_domain.max());
|
||||
|
||||
add_segment(p1 + shift, p2 + shift, CGAL::Color(96, 104, 252));
|
||||
add_segment(p1 + shift, p3 + shift, CGAL::Color(96, 104, 252));
|
||||
add_segment(p2 + shift, p4 + shift, CGAL::Color(96, 104, 252));
|
||||
add_segment(p3 + shift, p4 + shift, CGAL::Color(96, 104, 252));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void compute_elements() {
|
||||
// Clear the buffers
|
||||
clear();
|
||||
|
||||
// Get the display type, iterate through periodic elements according
|
||||
// to the display type
|
||||
Iterator_type it_type = (Iterator_type)m_display_type;
|
||||
|
||||
// Iterate through vertices, edges and faces, add elements to buffer
|
||||
for (Periodic_point_iterator it =
|
||||
p2t2.periodic_points_begin(it_type);
|
||||
it != p2t2.periodic_points_end(it_type); it++)
|
||||
{
|
||||
compute_vertex(it);
|
||||
}
|
||||
|
||||
for (Periodic_segment_iterator it =
|
||||
p2t2.periodic_segments_begin(it_type);
|
||||
it != p2t2.periodic_segments_end(it_type); it++)
|
||||
{
|
||||
compute_edge(it);
|
||||
}
|
||||
|
||||
for (Periodic_triangle_iterator it =
|
||||
p2t2.periodic_triangles_begin(it_type);
|
||||
it != p2t2.periodic_triangles_end(it_type); it++)
|
||||
{
|
||||
compute_face(it);
|
||||
}
|
||||
|
||||
if(m_domain){
|
||||
// Compute the (9-sheet covering space) domain of the periodic triangulation
|
||||
compute_domain();
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
const ::Qt::KeyboardModifiers modifiers = e->modifiers();
|
||||
if (e->text()=="1")
|
||||
{
|
||||
m_display_type = Display_type::UNIQUE;
|
||||
displayMessage(QString("Display type= UNIQUE"));
|
||||
compute_elements();
|
||||
redraw();
|
||||
} else if (e->text()=="2")
|
||||
{
|
||||
m_display_type = Display_type::UNIQUE_COVER_DOMAIN;
|
||||
displayMessage(QString("Display type= UNIQUE_COVER_DOMAIN"));
|
||||
compute_elements();
|
||||
redraw();
|
||||
} else if (e->text()=="3")
|
||||
{
|
||||
m_display_type = Display_type::STORED;
|
||||
displayMessage(QString("Display type= STORED"));
|
||||
compute_elements();
|
||||
redraw();
|
||||
} else if (e->text()=="4")
|
||||
{
|
||||
m_display_type = Display_type::STORED_COVER_DOMAIN;
|
||||
displayMessage(QString("Display type= STORED_COVER_DOMAIN"));
|
||||
compute_elements();
|
||||
redraw();
|
||||
} else if ((e->key() == ::Qt::Key_D) && (modifiers == ::Qt::NoButton))
|
||||
{
|
||||
m_domain=!m_domain;
|
||||
displayMessage(QString("Draw domain=%1.").arg(m_domain?"true":"false"));
|
||||
compute_elements();
|
||||
redraw();
|
||||
} else {
|
||||
Base::keyPressEvent(e);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
const P2T2& p2t2;
|
||||
bool m_nofaces;
|
||||
const ColorFunctor& m_fcolor;
|
||||
enum Display_type
|
||||
{
|
||||
STORED = 0,
|
||||
UNIQUE, // 1
|
||||
STORED_COVER_DOMAIN, // 2
|
||||
UNIQUE_COVER_DOMAIN // 3
|
||||
};
|
||||
Display_type m_display_type;
|
||||
bool m_domain;
|
||||
};
|
||||
|
||||
// Specialization of draw function
|
||||
#define CGAL_P2T2_TYPE CGAL::Periodic_2_triangulation_2 \
|
||||
<Gt, Tds >
|
||||
|
||||
template < class Gt,
|
||||
class Tds >
|
||||
void draw(const CGAL_P2T2_TYPE& ap2t2,
|
||||
const char* title = "2D Periodic Triangulation 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)
|
||||
{
|
||||
int argc=1;
|
||||
const char* argv[2]={"p2t2_viewer","\0"};
|
||||
QApplication app(argc,const_cast<char**>(argv));
|
||||
DefaultColorFunctorP2T2 fcolor;
|
||||
SimplePeriodic2Triangulation2ViewerQt<CGAL_P2T2_TYPE,
|
||||
DefaultColorFunctorP2T2>
|
||||
mainwindow(app.activeWindow(), ap2t2, title, nofill, fcolor);
|
||||
mainwindow.show();
|
||||
app.exec();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace CGAL
|
||||
|
||||
#endif // CGAL_USE_BASIC_VIEWER
|
||||
|
||||
#endif // DRAW_PERIODIC_2_TRIANGULATION_2_H
|
||||
|
|
@ -4,6 +4,7 @@ Circulator
|
|||
Distance_2
|
||||
Distance_3
|
||||
Filtered_kernel
|
||||
GraphicsView
|
||||
Hash_map
|
||||
Installation
|
||||
Intersections_2
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
namespace CGAL {
|
||||
|
||||
/*!
|
||||
\ingroup PkgDrawVoronoiDiagram2
|
||||
|
||||
opens a new window and draws `av2`, the `Voronoi_diagram_2` constructed from a Delaunay Graph which is a model of `DelaunayGraph_2` concept.
|
||||
The class `Voronoi_diagram_2` provides an adaptor to view a triangulated Delaunay graph as their dual subdivision, the
|
||||
Voronoi diagram. A call to this function is blocking, that is the program continues as soon as the user closes the window.
|
||||
This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time.
|
||||
\tparam V2 a model of the `AdaptationTraits_2` concept.
|
||||
\param av2 the voronoi diagram to draw.
|
||||
|
||||
*/
|
||||
template<class V2>
|
||||
void draw(const V2& av2);
|
||||
|
||||
} /* namespace CGAL */
|
||||
|
|
@ -12,6 +12,14 @@
|
|||
/// \defgroup PkgVoronoiDiagram2Disks Voronoi Diagram of Disks
|
||||
/// \ingroup PkgVoronoiDiagram2Ref
|
||||
|
||||
/*!
|
||||
\code
|
||||
#include <CGAL/draw_voronoi_diagram_2.h>
|
||||
\endcode
|
||||
*/
|
||||
/// \defgroup PkgDrawVoronoiDiagram2 Draw a 2D Voronoi Diagram
|
||||
/// \ingroup PkgVoronoiDiagram2Ref
|
||||
|
||||
/*!
|
||||
\addtogroup PkgVoronoiDiagram2Ref
|
||||
\todo check generated documentation
|
||||
|
|
@ -81,5 +89,9 @@ performing this adaptation.
|
|||
- `CGAL::Segment_Delaunay_graph_degeneracy_removal_policy_2<SDG2>`
|
||||
- `CGAL::Segment_Delaunay_graph_caching_degeneracy_removal_policy_2<SDG2>`
|
||||
|
||||
\cgalCRPSection{Draw Voronoi Diagram}
|
||||
|
||||
- \link PkgDrawVoronoiDiagram2 CGAL::draw<VD>() \endlink
|
||||
|
||||
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -488,6 +488,20 @@ location queries.
|
|||
|
||||
\cgalExample{Voronoi_diagram_2/vd_2_point_location.cpp}
|
||||
|
||||
\section secvda2drawvoronoi Draw a Voronoi Diagram
|
||||
|
||||
A 2D Voronoi Diagram can be visualized by calling the \link PkgDrawVoronoiDiagram2 CGAL::draw<VD>() \endlink function as
|
||||
shown in the following example. This function opens a new window showing the Voronoi Diagram of the given input sites/vertix locations. A call to this function is blocking, that is the program continues as soon as the user closes the window.
|
||||
|
||||
This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time.
|
||||
|
||||
\cgalExample{Voronoi_diagram_2/draw_voronoi_diagram_2.cpp}
|
||||
|
||||
\cgalFigureBegin{draw_voronoi_diagram, draw_voronoi_diagram.png}
|
||||
Result of the draw_voronoi_diagram_2 program. A window shows the Voronoi vertices and edges.
|
||||
The window allows navigation through the 2D scene.
|
||||
\cgalFigureEnd
|
||||
|
||||
*/
|
||||
} /* namespace CGAL */
|
||||
|
||||
|
|
|
|||
|
|
@ -7,3 +7,4 @@ Stream_support
|
|||
Triangulation_2
|
||||
Segment_Delaunay_graph_2
|
||||
Apollonius_graph_2
|
||||
GraphicsView
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
/*!
|
||||
\example Voronoi_diagram_2/vd_2_point_location.cpp
|
||||
\example Voronoi_diagram_2/vd_2_point_location_sdg_linf.cpp
|
||||
\example Voronoi_diagram_2/draw_voronoi_diagram_2.cpp
|
||||
*/
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
|
|
@ -6,7 +6,11 @@ cmake_minimum_required(VERSION 3.1...3.15)
|
|||
project( Voronoi_diagram_2_Examples )
|
||||
|
||||
|
||||
find_package(CGAL QUIET)
|
||||
find_package(CGAL COMPONENTS Qt5)
|
||||
|
||||
if(CGAL_Qt5_FOUND)
|
||||
add_definitions(-DCGAL_USE_BASIC_VIEWER -DQT_NO_KEYWORDS)
|
||||
endif()
|
||||
|
||||
if ( CGAL_FOUND )
|
||||
|
||||
|
|
@ -16,6 +20,11 @@ if ( CGAL_FOUND )
|
|||
create_single_source_cgal_program( "${cppfile}" )
|
||||
endforeach()
|
||||
|
||||
if(CGAL_Qt5_FOUND )
|
||||
target_link_libraries(draw_voronoi_diagram_2 PUBLIC CGAL::CGAL_Qt5)
|
||||
endif()
|
||||
|
||||
|
||||
else()
|
||||
|
||||
message(STATUS "This program requires the CGAL library, and will not be compiled.")
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
0 0
|
||||
100 0
|
||||
100 100
|
||||
0 100
|
||||
200 0
|
||||
300 0
|
||||
350 0
|
||||
150 150
|
||||
100 150
|
||||
300 325
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
// standard includes
|
||||
#include <fstream>
|
||||
|
||||
// includes for drawing the Voronoi Diagram
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Voronoi_diagram_2.h>
|
||||
#include <CGAL/Delaunay_triangulation_2.h>
|
||||
#include <CGAL/Delaunay_triangulation_adaptation_traits_2.h>
|
||||
#include <CGAL/Delaunay_triangulation_adaptation_policies_2.h>
|
||||
#include <CGAL/draw_voronoi_diagram_2.h>
|
||||
|
||||
// typedefs for defining the adaptor
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
|
||||
typedef CGAL::Delaunay_triangulation_2<K> DT;
|
||||
typedef CGAL::Delaunay_triangulation_adaptation_traits_2<DT> AT;
|
||||
typedef CGAL::Delaunay_triangulation_caching_degeneracy_removal_policy_2<DT> AP;
|
||||
typedef CGAL::Voronoi_diagram_2<DT,AT,AP> VD;
|
||||
|
||||
// typedef for the result type of the point location
|
||||
typedef AT::Site_2 Site_2;
|
||||
|
||||
int main()
|
||||
{
|
||||
VD vd;
|
||||
std::ifstream ifs("data/data4.dt.cin");
|
||||
assert(ifs);
|
||||
|
||||
Site_2 t;
|
||||
while ( ifs >> t ) { vd.insert(t); }
|
||||
ifs.close();
|
||||
|
||||
assert( vd.is_valid() );
|
||||
|
||||
CGAL::draw(vd);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
@ -0,0 +1,335 @@
|
|||
// Copyright(c) 2019 Foundation for Research and Technology-Hellas (Greece).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org).
|
||||
//
|
||||
// $URL$
|
||||
// $Id$
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||
//
|
||||
// Author(s) : Jasmeet Singh <jasmeet.singh.mec11@iitbhu.ac.in>
|
||||
|
||||
#ifndef CGAL_DRAW_VORONOI_DIAGRAM_2_H
|
||||
#define CGAL_DRAW_VORONOI_DIAGRAM_2_H
|
||||
|
||||
#include <CGAL/Qt/Basic_viewer_qt.h>
|
||||
#include <CGAL/license/Voronoi_diagram_2.h>
|
||||
|
||||
#ifdef CGAL_USE_BASIC_VIEWER
|
||||
|
||||
#include <CGAL/Random.h>
|
||||
#include <CGAL/Triangulation_utils_2.h>
|
||||
#include <CGAL/Voronoi_diagram_2/Face.h>
|
||||
#include <CGAL/Voronoi_diagram_2/Handle_adaptor.h>
|
||||
#include <CGAL/Voronoi_diagram_2/Vertex.h>
|
||||
#include <CGAL/Voronoi_diagram_2/basic.h>
|
||||
#include <CGAL/Voronoi_diagram_2/Accessor.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
// Default color functor; user can change it to have its own face color
|
||||
struct DefaultColorFunctorV2
|
||||
{
|
||||
template <typename V2>
|
||||
static CGAL::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::Color(73, 250, 117);
|
||||
}
|
||||
};
|
||||
|
||||
// Viewer for Voronoi diagram
|
||||
template <class V2, class ColorFunctor>
|
||||
class SimpleVoronoiDiagram2ViewerQt : public Basic_viewer_qt
|
||||
{
|
||||
typedef Basic_viewer_qt Base;
|
||||
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;
|
||||
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
|
||||
|
||||
public:
|
||||
/// Construct the viewer.
|
||||
/// @param av2 the voronoi diagram 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 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::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 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));
|
||||
add_ray(he->source()->point(), direction, CGAL::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);
|
||||
add_line(pointOnLine, direction);
|
||||
}
|
||||
}
|
||||
|
||||
void compute_face(Face_const_handle fh)
|
||||
{
|
||||
CGAL::Color c = m_fcolor.run(v2, fh);
|
||||
|
||||
Ccb_halfedge_circulator ec_start = fh->ccb();
|
||||
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.
|
||||
#define CGAL_VORONOI_TYPE CGAL::Voronoi_diagram_2 <DG, AT, AP>
|
||||
|
||||
template<class DG,
|
||||
class AT,
|
||||
class AP>
|
||||
void draw(const CGAL_VORONOI_TYPE &av2,
|
||||
const char *title="2D Voronoi Diagram Basic Viewer",
|
||||
bool nofill = false,
|
||||
bool draw_voronoi_vertices = true,
|
||||
bool draw_dual_vertices = true)
|
||||
{
|
||||
#if defined(CGAL_TEST_SUITE)
|
||||
bool cgal_test_suite = true;
|
||||
#else
|
||||
bool cgal_test_suite = qEnvironmentVariableIsSet("CGAL_TEST_SUITE");
|
||||
#endif
|
||||
|
||||
if (!cgal_test_suite) {
|
||||
int argc = 1;
|
||||
const char *argv[2] = {"voronoi_2_viewer", "\0"};
|
||||
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
|
||||
|
||||
#endif // CGAL_USE_BASIC_VIEWER
|
||||
|
||||
#endif // CGAL_DRAW_VORONOI_DIAGRAM_2_H
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
Algebraic_foundations
|
||||
Apollonius_graph_2
|
||||
Circulator
|
||||
GraphicsView
|
||||
Hash_map
|
||||
Installation
|
||||
Interval_support
|
||||
|
|
|
|||
Loading…
Reference in New Issue