Update basic viewer and corresponding examples; remove one example since it is now in the demo.

This commit is contained in:
Guillaume Damiand 2015-10-02 14:44:42 +02:00
parent b5c34bf9cc
commit 2ee49ba5f3
6 changed files with 186 additions and 327 deletions

View File

@ -11,8 +11,8 @@ endif()
# If you want to visualize a linear cell complex, you can use the following viewer
# based on qt. Just uncomment the following two lines, plus the lines qt5_use_modules below
#find_package(CGAL COMPONENTS Qt5)
#include("CMakeLCCViewerQt.inc")
# find_package(CGAL COMPONENTS Qt5)
# include("CMakeLCCViewerQt.inc")
# If you don't want to visualize, use the following line (otherwise comment it)
find_package(CGAL QUIET COMPONENTS Core)
@ -40,13 +40,6 @@ if ( CGAL_FOUND )
create_single_source_cgal_program("plane_graph_to_lcc_2.cpp")
create_single_source_cgal_program("linear_cell_complex_3_attributes_management.cpp")
add_executable(linear_cell_complex_3_triangulation
linear_cell_complex_3_triangulation.cpp)
target_link_libraries(linear_cell_complex_3_triangulation ${CGAL_LIBRARIES}
${CGAL_3RD_PARTY_LIBRARIES}
${MAP_VIEWER_LIBRARIES})
# qt5_use_modules(linear_cell_complex_3_triangulation ${MAP_VIEWER_MODULES})
add_executable(voronoi_2 voronoi_2.cpp)
target_link_libraries(voronoi_2 ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES}
${MAP_VIEWER_LIBRARIES})

View File

@ -13,12 +13,6 @@ Examples for Linear_cell_complex package:
Program allowing to transform a planar graph into a 2D linear cell complex.
* linear_cell_complex_3_triangulation.cpp
Example showing how to triangulate a face of a Linear_cell_complex,
using CGAL::Constrained_Delaunay_triangulation_2.
* voronoi_2.cpp
Example showing how to compute 2D voronoi diagram of a set of 2D points.

View File

@ -1,272 +0,0 @@
#include <CGAL/Linear_cell_complex.h>
#include <CGAL/Linear_cell_complex_constructors.h>
#include <CGAL/Linear_cell_complex_operations.h>
#include <CGAL/Triangulation_2_filtered_projection_traits_3.h>
#include <CGAL/Triangulation_vertex_base_with_info_2.h>
#include <CGAL/Triangulation_face_base_with_info_2.h>
#include <CGAL/Constrained_Delaunay_triangulation_2.h>
#include <iostream>
#include <algorithm>
#include <vector>
/* If you want to use a viewer, you can use one of the following file
* depending if you use vtk or qglviewer. */
#ifdef CGAL_LCC_USE_QT
#include "linear_cell_complex_3_viewer_qt.h"
#else
#ifdef CGAL_LCC_USE_VTK
#include "linear_cell_complex_3_viewer_vtk.h"
#endif
#endif
typedef CGAL::Linear_cell_complex<3> LCC_3;
typedef LCC_3::Dart_handle Dart_handle;
typedef LCC_3::Point Point;
typedef LCC_3::FT FT;
typedef LCC_3::Traits Traits;
typedef CGAL::Triangulation_2_filtered_projection_traits_3<Traits> P_traits;
typedef CGAL::Triangulation_vertex_base_with_info_2<Dart_handle,P_traits> Vb;
struct Face_info {
bool exist_edge[3];
bool is_external;
};
typedef CGAL::Triangulation_face_base_with_info_2<Face_info,P_traits> Fb1;
typedef CGAL::Constrained_triangulation_face_base_2<P_traits, Fb1> Fb;
typedef CGAL::Triangulation_data_structure_2<Vb,Fb> TDS;
typedef CGAL::No_intersection_tag Itag;
typedef CGAL::Constrained_Delaunay_triangulation_2<P_traits, TDS,
Itag> CDT;
bool is_external(CDT::Face_handle fh)
{
return fh->info().is_external;
}
int number_of_existing_edge(CDT::Face_handle fh)
{
unsigned res=0;
for (int i=0; i<3; ++i)
if (fh->info().exist_edge[i]) ++res;
return res;
}
int get_free_edge(CDT::Face_handle fh)
{
CGAL_assertion( number_of_existing_edge(fh)==2 );
for (int i=0; i<3; ++i)
if (!fh->info().exist_edge[i]) return i;
CGAL_assertion(false);
return -1;
}
void constrained_delaunay_triangulation(LCC_3 &lcc, Dart_handle d1)
{
CGAL::set_ascii_mode(std::cout);
std::cout<<"Vertices: ";
for (LCC_3::Vertex_attribute_const_range::iterator
v=lcc.vertex_attributes().begin(),
vend=lcc.vertex_attributes().end(); v!=vend; ++v)
std::cout << lcc.point_of_vertex_attribute(v) << "; ";
std::cout<<std::endl;
LCC_3::Vector normal = CGAL::compute_normal_of_cell_2(lcc,d1);
P_traits cdt_traits(normal);
CDT cdt(cdt_traits);
//inserting the constraints edge by edge
LCC_3::Dart_of_orbit_range<1>::iterator
it(lcc.darts_of_orbit<1>(d1).begin());
CDT::Vertex_handle previous=LCC_3::null_handle, first=LCC_3::null_handle,
vh=LCC_3::null_handle;
for (LCC_3::Dart_of_orbit_range<1>::iterator
itend(lcc.darts_of_orbit<1>(d1).end()); it!=itend; ++it)
{
vh = cdt.insert(lcc.point(it));
vh->info()=it;
if( first==NULL ){
first=vh;
}
if( previous!=NULL){
CGAL_assertion( previous !=vh );
cdt.insert_constraint(previous,vh);
}
previous=vh;
}
cdt.insert_constraint(previous,first);
CGAL_assertion(cdt.is_valid());
// sets mark is_external
for( CDT::All_faces_iterator fit = cdt.all_faces_begin(),
fitend = cdt.all_faces_end(); fit != fitend; ++fit)
{
fit->info().is_external = false;
fit->info().exist_edge[0]=false;
fit->info().exist_edge[1]=false;
fit->info().exist_edge[2]=false;
}
std::queue<CDT::Face_handle> face_queue;
face_queue.push(cdt.infinite_vertex()->face());
while(! face_queue.empty() )
{
CDT::Face_handle fh = face_queue.front();
face_queue.pop();
if(!fh->info().is_external)
{
fh->info().is_external = true;
for(int i = 0; i <3; ++i)
{
if(!cdt.is_constrained(std::make_pair(fh, i)))
{
face_queue.push(fh->neighbor(i));
}
}
}
}
for( CDT::Finite_edges_iterator eit = cdt.finite_edges_begin(),
eitend = cdt.finite_edges_end(); eit != eitend; ++eit)
{
CDT::Face_handle fh = eit->first;
int index = eit->second;
CDT::Face_handle opposite_fh = fh->neighbor(index);
if(cdt.is_constrained(std::make_pair(fh, index)))
{
fh->info().exist_edge[index]=true;
opposite_fh->info().exist_edge[cdt.mirror_index(fh,index)]=true;
if ( !fh->info().is_external && number_of_existing_edge(fh)==2 )
face_queue.push(fh);
if ( !opposite_fh->info().is_external &&
number_of_existing_edge(opposite_fh)==2 )
face_queue.push(opposite_fh);
}
}
while( !face_queue.empty() )
{
CDT::Face_handle fh = face_queue.front();
face_queue.pop();
CGAL_assertion( number_of_existing_edge(fh)>=2 ); // i.e. ==2 or ==3
CGAL_assertion( !fh->info().is_external );
if (number_of_existing_edge(fh)==2)
{
int index = get_free_edge(fh);
CDT::Face_handle opposite_fh = fh->neighbor(index);
CGAL_assertion( !fh->info().exist_edge[index] );
CGAL_assertion( !opposite_fh->info().
exist_edge[cdt.mirror_index(fh,index)] );
const CDT::Vertex_handle va = fh->vertex(cdt. cw(index));
const CDT::Vertex_handle vb = fh->vertex(cdt.ccw(index));
Dart_handle ndart=
CGAL::insert_cell_1_in_cell_2(lcc,va->info(),vb->info());
va->info()=lcc.beta<2>(ndart);
fh->info().exist_edge[index]=true;
opposite_fh->info().exist_edge[cdt.mirror_index(fh,index)]=true;
if ( !opposite_fh->info().is_external &&
number_of_existing_edge(opposite_fh)==2 )
face_queue.push(opposite_fh);
}
}
}
Dart_handle make_facet(LCC_3& lcc,const std::vector<Point>& points)
{
Dart_handle d =
CGAL::make_combinatorial_polygon<LCC_3>(lcc,(unsigned int)points.size());
for (unsigned int i=0; i<points.size(); ++i)
{
lcc.set_vertex_attribute_of_dart(d, lcc.create_vertex_attribute(points[i]));
d=lcc.beta<1>(d);
}
return d;
}
int main()
{
LCC_3 lcc;
// Create one tetrahedra.
Dart_handle d1 = lcc.make_tetrahedron(Point(-1, 0, 0), Point(0, 2, 0),
Point(1, 0, 0), Point(1, 1, 2));
lcc.display_characteristics(std::cout) << ", valid="
<< lcc.is_valid()<<std::endl;
constrained_delaunay_triangulation(lcc,d1);
lcc.display_characteristics(std::cout) << ", valid="
<< lcc.is_valid()<<std::endl;
lcc.clear();
std::cout<<std::endl
<<"###################################################### \n"
<<std::endl;
// Create one hexahedron.
d1 = lcc.make_hexahedron(Point(0,0,0), Point(1,0,0), Point(1,1,0),
Point(0,1,0), Point(0,1,1), Point(0,0,1),
Point(1,0,1), Point(1,1,1));
lcc.display_characteristics(std::cout) << ", valid="
<< lcc.is_valid()<<std::endl;
constrained_delaunay_triangulation(lcc,d1);
lcc.display_characteristics(std::cout) << ", valid="
<< lcc.is_valid()<<std::endl;
constrained_delaunay_triangulation(lcc,lcc.beta<2>(d1));
lcc.display_characteristics(std::cout) << ", valid="
<< lcc.is_valid()<<std::endl;
lcc.clear();
std::cout<<std::endl
<<"###################################################### \n"
<<std::endl;
std::vector<Point> points;
points.push_back(Point(0,0,0));
points.push_back(Point(5,15,0));
points.push_back(Point(8,18,0));
points.push_back(Point(12,5,0));
points.push_back(Point(8,3,0));
points.push_back(Point(8,-9,0));
points.push_back(Point(5,0,0));
points.push_back(Point(2,-3,2));
d1=make_facet(lcc,points);
lcc.display_characteristics(std::cout) << ", valid="
<< lcc.is_valid()<<std::endl;
#ifdef CGAL_LCC_USE_VIEWER
display_lcc(lcc);
#endif // CGAL_LCC_USE_VIEWER
constrained_delaunay_triangulation(lcc,d1);
lcc.display_characteristics(std::cout) << ", valid="
<< lcc.is_valid()<<std::endl;
#ifdef CGAL_LCC_USE_VIEWER
display_lcc(lcc);
#endif // CGAL_LCC_USE_VIEWER
lcc.clear();
std::cout<<std::endl
<<"###################################################### \n"
<<std::endl;
return EXIT_SUCCESS;
}

View File

@ -27,10 +27,15 @@
#include <QGLViewer/qglviewer.h>
#include <GL/gl.h>
#include <CGAL/Linear_cell_complex.h>
#include <CGAL/Cartesian.h>
#include <CGAL/Cartesian_converter.h>
typedef CGAL::Cartesian<double> Local_kernel;
#include <CGAL/Triangulation_2_filtered_projection_traits_3.h>
#include <CGAL/Triangulation_vertex_base_with_info_2.h>
#include <CGAL/Triangulation_face_base_with_info_2.h>
#include <CGAL/Constrained_Delaunay_triangulation_2.h>
#include <CGAL/Constrained_triangulation_plus_2.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel Local_kernel;
typedef typename Local_kernel::Point_3 Local_point;
typedef typename Local_kernel::Vector_3 Local_vector;
@ -116,6 +121,24 @@ class SimpleLCCViewerQt : public QGLViewer
{
typedef typename LCC::Dart_handle Dart_handle;
struct Face_info
{
bool exist_edge[3];
bool is_external;
bool is_process;
};
typedef CGAL::Triangulation_2_filtered_projection_traits_3<CGAL::Exact_predicates_inexact_constructions_kernel> P_traits;
typedef CGAL::Triangulation_vertex_base_with_info_2<Local_vector,P_traits> Vb;
typedef CGAL::Triangulation_face_base_with_info_2<Face_info,P_traits> Fb1;
typedef CGAL::Constrained_triangulation_face_base_2<P_traits, Fb1> Fb;
typedef CGAL::Triangulation_data_structure_2<Vb,Fb> TDS;
typedef CGAL::No_intersection_tag Itag;
typedef CGAL::Constrained_Delaunay_triangulation_2<P_traits, TDS,
Itag> CDT;
public:
// Constructor/Destructor
@ -132,39 +155,170 @@ public:
}
protected :
void drawTriangleFace(Dart_handle dh, bool flat)
{
CGAL_assertion((lcc.template beta<1,1,1>(dh)==dh));
if(flat)
{
Local_vector normal = geomutils.get_facet_normal(lcc,dh);
::glNormal3d(normal.x(), normal.y(), normal.z());
}
for (typename LCC::template Dart_of_orbit_range<1>::const_iterator
orbitIter = lcc.template darts_of_orbit<1>(dh).begin();
orbitIter.cont(); ++orbitIter)
{
if(!flat)
{
// If Gouraud shading: 1 normal per vertex
Local_vector n = geomutils.get_vertex_normal(lcc,orbitIter);
::glNormal3d(n.x(),n.y(),n.z());
}
Local_point p = geomutils.get_point(lcc, orbitIter);
::glVertex3d(p.x(),p.y(),p.z());
}
}
void drawNonTriangleFace(Dart_handle dh, bool flat)
{
CGAL_assertion((lcc.template beta<1,1,1>(dh)!=dh));
Local_vector normal = geomutils.get_facet_normal(lcc,dh);
P_traits cdt_traits(normal);
CDT cdt(cdt_traits);
// Iterates on the vector of facet handles
typename CDT::Vertex_handle previous = NULL, first = NULL;
for (typename LCC::template Dart_of_orbit_range<1>::const_iterator
he_circ = lcc.template darts_of_orbit<1>(dh).begin(),
he_circ_end = lcc.template darts_of_orbit<1>(dh).end();
he_circ!=he_circ_end; ++he_circ)
{
typename CDT::Vertex_handle vh = cdt.insert(geomutils.get_point(lcc, he_circ));
if(first == NULL)
{ first = vh; }
vh->info() = geomutils.get_vertex_normal(lcc, he_circ);
if(previous!=NULL && previous != vh)
{ cdt.insert_constraint(previous, vh); }
previous = vh;
}
if (previous!=NULL)
cdt.insert_constraint(previous, first);
// sets mark is_external
for(typename CDT::All_faces_iterator fit = cdt.all_faces_begin(),
fitend = cdt.all_faces_end(); fit!=fitend; ++fit)
{
fit->info().is_external = true;
fit->info().is_process = false;
}
//check if the facet is external or internal
std::queue<typename CDT::Face_handle> face_queue;
typename CDT::Face_handle face_internal = NULL;
face_queue.push(cdt.infinite_vertex()->face());
while(! face_queue.empty() )
{
typename CDT::Face_handle fh = face_queue.front();
face_queue.pop();
if(!fh->info().is_process)
{
fh->info().is_process = true;
for(int i = 0; i <3; ++i)
{
if(!cdt.is_constrained(std::make_pair(fh, i)))
{
face_queue.push(fh->neighbor(i));
}
else if (face_internal==NULL)
{
face_internal = fh->neighbor(i);
}
}
}
}
if ( face_internal!=NULL )
face_queue.push(face_internal);
while(! face_queue.empty() )
{
typename CDT::Face_handle fh = face_queue.front();
face_queue.pop();
if(!fh->info().is_process)
{
fh->info().is_process = true;
fh->info().is_external = false;
for(int i = 0; i <3; ++i)
{
if(!cdt.is_constrained(std::make_pair(fh, i)))
{
face_queue.push(fh->neighbor(i));
}
}
}
}
//iterates on the internal faces to draw the corresponding triangles
for(typename CDT::Finite_faces_iterator ffit = cdt.finite_faces_begin(),
ffitend = cdt.finite_faces_end(); ffit != ffitend; ++ffit)
{
if(!ffit->info().is_external)
{
if(flat)
{
::glNormal3d(normal.x(), normal.y(), normal.z());
}
else
{
::glNormal3d(ffit->vertex(0)->info().x(),
ffit->vertex(0)->info().y(),
ffit->vertex(0)->info().z());
}
::glVertex3d(ffit->vertex(0)->point().x(),
ffit->vertex(0)->point().y(),
ffit->vertex(0)->point().z());
if(!flat)
{
::glNormal3d(ffit->vertex(1)->info().x(),
ffit->vertex(1)->info().y(),
ffit->vertex(1)->info().z());
}
::glVertex3d(ffit->vertex(1)->point().x(),
ffit->vertex(1)->point().y(),
ffit->vertex(1)->point().z());
if(!flat)
{
::glNormal3d(ffit->vertex(2)->info().x(),
ffit->vertex(2)->info().y(),
ffit->vertex(2)->info().z());
}
::glVertex3d(ffit->vertex(2)->point().x(),
ffit->vertex(2)->point().y(),
ffit->vertex(2)->point().z());
}
}
}
void drawAllFaces(bool flat)
{
::glColor3f(1.0f, .7f, .7f);
::glBegin(GL_TRIANGLES);
for(typename LCC::template One_dart_per_cell_range<2>::iterator
dartIter=lcc.template one_dart_per_cell<2>().begin();
dartIter.cont(); ++dartIter)
{
Dart_handle& dart = dartIter;
::glBegin(GL_POLYGON);
::glColor3f(1.0f, .7f, .7f);
if(flat)
{
Local_vector normal = geomutils.get_facet_normal(lcc,dart);
::glNormal3d(normal.x(), normal.y(), normal.z());
}
for (typename LCC::template Dart_of_orbit_range<1>::const_iterator
orbitIter = lcc.template darts_of_orbit<1>(dart).begin();
orbitIter.cont(); ++orbitIter)
{
if(!flat)
{
// If Gouraud shading: 1 normal per vertex
Local_vector n = geomutils.get_vertex_normal(lcc,orbitIter);
::glNormal3d(n.x(),n.y(),n.z());
}
Local_point p = geomutils.get_point(lcc, orbitIter);
::glVertex3d(p.x(),p.y(),p.z());
}
::glEnd();
if (lcc.template beta<1,1,1>(dartIter)!=dartIter)
drawNonTriangleFace(dartIter, flat);
else
drawTriangleFace(dartIter, flat);
}
::glEnd();
}
void drawAllEdges()

View File

@ -5,14 +5,9 @@
#include <iostream>
#include <fstream>
/* If you want to use a viewer, you can use one of the following file
* depending if you use vtk or qglviewer. */
/* If you want to use a viewer, you can use qglviewer. */
#ifdef CGAL_LCC_USE_QT
#include "linear_cell_complex_3_viewer_qt.h"
#else
#ifdef CGAL_LCC_USE_VTK
#include "linear_cell_complex_3_viewer_vtk.h"
#endif
#endif
/* // If you want to use exact constructions.

View File

@ -5,14 +5,9 @@
#include <iostream>
#include <fstream>
/* If you want to use a viewer, you can use one of the following file
* depending if you use vtk or qglviewer. */
/* If you want to use a viewer, you can use one qglviewer. */
#ifdef CGAL_LCC_USE_QT
#include "linear_cell_complex_3_viewer_qt.h"
#else
#ifdef CGAL_LCC_USE_VTK
#include "linear_cell_complex_3_viewer_vtk.h"
#endif
#endif
/* // If you want to use exact constructions.