Merge pull request #2835 from gdamiand/CGAL-basic_viewers-gdamiand

Add basic viewers
This commit is contained in:
Laurent Rineau 2018-06-14 17:36:37 +02:00
commit 08043e442c
68 changed files with 3428 additions and 424 deletions

View File

@ -1250,7 +1250,7 @@ namespace CGAL {
/** Test if the map is valid.
* @return true iff the map is valid.
*/
bool is_valid() const
bool is_valid(bool show_errors=true) const
{
bool valid = true;
unsigned int i = 0, j = 0;
@ -1276,9 +1276,11 @@ namespace CGAL {
if ((!is_free(it, 0) && beta(it, 0, 1)!=it) ||
(!is_free(it, 1) && beta(it, 1, 0)!=it ))
{
std::cerr << "Map not valid: beta(0) "
"is not the inverse of beta(1) for dart "
<<darts().index(it) << std::endl;
if (show_errors)
{ std::cerr << "Map not valid: beta(0) "
"is not the inverse of beta(1) for dart "
<<darts().index(it) << std::endl;
}
valid = false;
}
@ -1286,9 +1288,11 @@ namespace CGAL {
for ( i = 2; i <= dimension; ++i)
if (!is_free(it, i) && beta(it, i, i)!=it)
{
std::cerr << "Map not valid: beta(" << i
<< ") is not an involution for dart "
<<darts().index(it)<< std::endl;
if (show_errors)
{ std::cerr << "Map not valid: beta(" << i
<< ") is not an involution for dart "
<<darts().index(it)<< std::endl;
}
valid = false;
}
@ -1299,9 +1303,12 @@ namespace CGAL {
if ((is_free(it, i) != is_free(beta(it, 0), i)) ||
(!is_free(it, i) && beta(it, 0, i)!=beta(it, i, 1)))
{
std::cerr << "Map not valid: beta(0) o beta(" << i
<< ") is not an involution for dart "
<<darts().index(it)<< std::endl;
if (show_errors)
{
std::cerr << "Map not valid: beta(0) o beta(" << i
<< ") is not an involution for dart "
<<darts().index(it)<< std::endl;
}
valid = false;
}
}
@ -1311,9 +1318,12 @@ namespace CGAL {
if ((is_free(it, i) != is_free(beta(it, 1), i)) ||
(!is_free(it, i) && beta(it, 1, i)!=beta(it, i, 0)))
{
std::cerr << "Map not valid: beta(1) o beta(" << i
<< ") is not an involution for dart "
<<darts().index(it)<< std::endl;
if (show_errors)
{
std::cerr << "Map not valid: beta(1) o beta(" << i
<< ") is not an involution for dart "
<<darts().index(it)<< std::endl;
}
valid = false;
}
}
@ -1327,10 +1337,13 @@ namespace CGAL {
if ((is_free(it, j)!=is_free(beta(it, i), j)) ||
(!is_free(it, j) && beta(it, i, j)!=beta(it, j, i)))
{
std::cerr << "Map not valid: beta(" << i
<< ") o beta(" << j
<< ") is not an involution for dart "
<< darts().index(it)<< std::endl;
if (show_errors)
{
std::cerr << "Map not valid: beta(" << i
<< ") o beta(" << j
<< ") is not an involution for dart "
<< darts().index(it)<< std::endl;
}
valid = false;
}
}

View File

@ -329,7 +329,7 @@ struct Correct_invalid_attributes_functor
unsigned int nb=0;
bool found_dart = false;
for ( CGAL::CMap_dart_iterator_basic_of_cell<CMap,i>
for ( typename CMap::template Dart_of_cell_basic_range<i>::iterator
it(amap, adart, amark); it.cont(); ++it, ++nb )
{
if ( a!=amap.template attribute<i>(it) )

View File

@ -0,0 +1,800 @@
// Copyright (c) 2018 GeometryFactory Sarl (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
// You can redistribute it and/or modify it under the terms of the GNU
// General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0+
//
//
// Author(s) : Guillaume Damiand <guillaume.damiand@liris.cnrs.fr>
#ifndef CGAL_VBO_BUFFER_FILLER_H
#define CGAL_VBO_BUFFER_FILLER_H
#include <CGAL/license/GraphicsView.h>
#include <CGAL/Triangulation_2_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>
#include <CGAL/Cartesian_converter.h>
#include <CGAL/IO/Color.h>
#include <vector>
#include <cstdlib>
#include <queue>
#include <boost/unordered_map.hpp>
namespace CGAL
{
typedef CGAL::Exact_predicates_inexact_constructions_kernel Local_kernel;
typedef Local_kernel::Point_3 Local_point;
typedef Local_kernel::Vector_3 Local_vector;
//------------------------------------------------------------------------------
namespace internal
{
template <class Point, class Vector>
void newell_single_step_3(const Point& p, const Point& q, Vector& n)
{
// Compute normal of the face by using Newell's method: for each edge PQ
// Nx += (Py - Qy) * (Pz + Qz);
// Ny += (Pz - Qz) * (Px + Qx);
// Nz += (Px - Qx) * (Py + Qy);
n = Vector(n.x()+((p.y()-q.y())*(p.z()+q.z())),
n.y()+((p.z()-q.z())*(p.x()+q.x())),
n.z()+((p.x()-q.x())*(p.y()+q.y())));
}
inline
Local_vector compute_normal_of_face(const std::vector<Local_point>& points)
{
Local_vector normal(CGAL::NULL_VECTOR);
unsigned int nb = 0;
for (std::size_t i=0; i<points.size(); ++i)
{
newell_single_step_3(points[i], points[(i+1)%points.size()], normal);
++nb;
}
assert(nb>0);
return (Local_kernel::Construct_scaled_vector_3()(normal, 1.0/nb));
}
////////////////////////////////////////////////////////////////
// Structs to transform any CGAL point/vector into a Local_point/Local_vector
template<typename K>
struct Geom_utils
{
static Local_point get_local_point(const typename K::Point_2& p)
{
CGAL::Cartesian_converter<K, Local_kernel> converter;
return Local_point(converter(p.x()), 0, converter(p.y()));
}
static Local_point get_local_point(const typename K::Weighted_point_2& p)
{
typename K::Point_2 lp(p);
return Geom_utils<K>::get_local_point(lp);
}
static Local_point get_local_point(const typename K::Point_3& p)
{
CGAL::Cartesian_converter<K, Local_kernel> converter;
return converter(p);
}
static Local_point get_local_point(const typename K::Weighted_point_3& p)
{
typename K::Point_3 lp(p);
return Geom_utils<K>::get_local_point(lp);
}
static Local_vector get_local_vector(const typename K::Vector_2& v)
{
CGAL::Cartesian_converter<K, Local_kernel> converter;
return Local_vector(converter(v.x()), 0, converter(v.y()));
}
static Local_vector get_local_vector(const typename K::Vector_3& v)
{
CGAL::Cartesian_converter<K, Local_kernel> converter;
return converter(v);
}
};
// Specialization for Local_kernel, because there is no need of convertion here.
template<>
struct Geom_utils<Local_kernel>
{
static Local_point get_local_point(const Local_kernel::Point_2& p)
{ return Local_point(p.x(), 0, p.y()); }
static Local_point get_local_point(const Local_kernel::Weighted_point_2& p)
{ return Local_point(p.point().x(), 0, p.point().y());}
static const Local_point & get_local_point(const Local_kernel::Point_3& p)
{ return p; }
static Local_point get_local_point(const Local_kernel::Weighted_point_3& p)
{ return Local_point(p);}
static Local_vector get_local_vector(const Local_kernel::Vector_2& v)
{ return Local_vector(v.x(), 0, v.y()); }
static const Local_vector& get_local_vector(const Local_kernel::Vector_3& v)
{ return v; }
};
////////////////////////////////////////////////////////////////
// Global function to simplify function calls.
template<typename KPoint>
Local_point get_local_point(const KPoint& p)
{
return Geom_utils<typename CGAL::Kernel_traits<KPoint>::Kernel>::
get_local_point(p);
}
template<typename KVector>
Local_vector get_local_vector(const KVector& v)
{
return Geom_utils<typename CGAL::Kernel_traits<KVector>::Kernel>::
get_local_vector(v);
}
} // End namespace internal
//------------------------------------------------------------------------------
template<typename BufferType=float, typename IndexType=std::size_t>
class Buffer_for_vao
{
public:
Buffer_for_vao(std::vector<BufferType>* pos=NULL,
std::vector<IndexType>* indices=NULL,
CGAL::Bbox_3* bbox=NULL,
std::vector<BufferType>* color=NULL,
std::vector<BufferType>* flat_normal=NULL,
std::vector<BufferType>* gouraud_normal=NULL) :
m_pos_buffer(pos),
m_index_buffer(indices),
m_color_buffer(color),
m_flat_normal_buffer(flat_normal),
m_gouraud_normal_buffer(gouraud_normal),
m_bb(bbox),
m_face_started(false)
{}
void clear()
{
if (m_pos_buffer!=NULL) { m_pos_buffer->clear(); }
if (m_color_buffer!=NULL) { m_color_buffer->clear(); }
if (m_index_buffer!=NULL) { m_index_buffer->clear(); }
if (m_flat_normal_buffer!=NULL) { m_flat_normal_buffer->clear(); }
if (m_gouraud_normal_buffer!=NULL) { m_gouraud_normal_buffer->clear(); }
}
bool is_empty() const
{
return
(m_pos_buffer!=NULL && m_pos_buffer->empty()) &&
(m_color_buffer!=NULL || m_color_buffer->empty()) &&
(m_flat_normal_buffer!=NULL || m_flat_normal_buffer->empty()) &&
(m_gouraud_normal_buffer!=NULL || m_gouraud_normal_buffer->empty()) &&
(m_index_buffer!=NULL || m_index_buffer->empty());
}
bool has_position() const
{ return m_pos_buffer!=NULL; }
bool has_indices() const
{ return m_index_buffer!=NULL; }
bool has_color() const
{ return m_color_buffer!=NULL; }
bool has_flat_normal() const
{ return m_flat_normal_buffer!=NULL; }
bool has_gouraud_normal() const
{ return m_gouraud_normal_buffer!=NULL; }
// 1.1) Add a point, without color. Return the index of the added point.
template<typename KPoint>
std::size_t add_point(const KPoint& kp)
{
if (!has_position()) return (std::size_t)-1;
Local_point p=internal::get_local_point(kp);
add_point_in_buffer(p, *m_pos_buffer);
if (m_bb!=NULL)
{ (*m_bb)=(*m_bb)+p.bbox(); }
return m_pos_buffer->size()-3;
}
// 1.2) Add a point, with color.
template<typename KPoint>
void add_point(const KPoint& kp, const CGAL::Color& c)
{
add_point(kp);
add_color(c);
}
// 1.3) Add an indexed point, without color.
template<typename T>
void add_indexed_point(T index)
{
if (!has_indices()) return;
m_index_buffer->push_back((IndexType)index);
}
// 2.1) Add a segment, without color.
template<typename KPoint>
void add_segment(const KPoint& kp1, const KPoint& kp2)
{
add_point(kp1);
add_point(kp2);
}
// 2.2) Add a segment, with color.
template<typename KPoint>
void add_segment(const KPoint& kp1, const KPoint& kp2, const CGAL::Color& c)
{
add_segment(kp1, kp2);
add_color(c);
add_color(c);
}
// 2.3) Add an indexed segment, without color.
template<typename T>
void add_indexed_segment(T index1, T index2)
{
add_indexed_point(index1);
add_indexed_point(index2);
}
/// @return true iff a face has begun.
bool is_a_face_started() const
{ return m_face_started; }
// 3.1) Add a face, without color, without normal.
void face_begin()
{ face_begin_internal(false, false); }
// 3.2) Add a face, with a color, without normal.
void face_begin(const CGAL::Color& c)
{
m_color_of_face=c;
face_begin_internal(true, false);
}
// 3.3) Add a face, without a color, with a normal.
template<typename KNormal>
void face_begin(const KNormal& kv)
{
m_normal_of_face=internal::get_local_vector(kv);
face_begin_internal(false, true);
}
// 3.3) Add a face, with a color and with a normal.
template<typename KNormal>
void face_begin(const CGAL::Color& c, const KNormal& kv)
{
m_color_of_face=c;
m_normal_of_face=internal::get_local_vector(kv);
face_begin_internal(true, true);
}
/// Add a point at the end of the current face, without giving the vertex normal.
/// When this method is used, it is not possible to use the Gouraud shading.
/// @param p the point to add
template<typename KPoint>
bool add_point_in_face(const KPoint& kp)
{
if (!is_a_face_started()) return false;
Local_point p=internal::get_local_point(kp);
if (m_points_of_face.empty() || m_points_of_face.back()!=p) // TODO test if the distance between prev point and kp is smaller than an epsilon (?? not sure ??)
{
m_points_of_face.push_back(p);
return true;
}
return false;
}
/// Add a point at the end of the current face
/// @param p the point to add
/// @p_normal the vertex normal at this point (for Gouraud shading)
template<typename KPoint, typename KVector>
bool add_point_in_face(const KPoint& kp, const KVector& p_normal)
{
if (add_point_in_face(kp))
{
m_vertex_normals_for_face.push_back(internal::get_local_vector(p_normal));
return true;
}
return false;
}
/// Add an indexed point at the end of the current face, without giving the vertex normal.
/// When Indexation is used, it is not possible to use flat shading or multiple colors
/// for face sor edges.
/// Note that we still need the point itself, in order to triangulate the face when necessary.
template<typename T, typename KPoint>
bool add_indexed_point_in_face(T index, const KPoint& kp)
{
if (add_point_in_face(kp))
{
m_indices_of_points_of_face.push_back(index);
return true;
}
return false;
}
/// End the face: compute the triangulation.
void face_end()
{
if (!is_a_face_started()) return;
if (m_points_of_face.size()<3)
{
std::cerr<<"PB: you try to triangulate a face with "<<m_points_of_face.size()<<" vertices."
<<std::endl;
m_face_started=false;
m_points_of_face.clear();
m_vertex_normals_for_face.clear();
return;
}
if (m_indices_of_points_of_face.size()>0 &&
m_indices_of_points_of_face.size()!=m_points_of_face.size())
{
std::cerr<<"PB: you mixed some add_point_in_face(...) and some add_indexed_point_in_face(...)"
<<" for a same face. Indices for this face are ignored."<<std::endl;
m_indices_of_points_of_face.clear();
}
if (m_vertex_normals_for_face.size()>0 &&
m_vertex_normals_for_face.size()!=m_points_of_face.size())
{
std::cerr<<"PB: you only gave some vertex normals (and not all) for a same face. "
<<"All vertex normal are ignored and thus it is not possible to use Gouraud "
<<"shading for this face."
<<std::endl;
m_vertex_normals_for_face.clear();
}
Local_vector normal=(m_started_face_has_normal?m_normal_of_face:
internal::compute_normal_of_face(m_points_of_face));
if (m_points_of_face.size()==3)
{ triangular_face_end_internal(normal); } // Triangle: no need to triangulate
else if (is_current_face_convex(normal))
{
if (m_points_of_face.size()==4)
{ convex_quadrangular_face_end_internal(normal); } // Convex quad
else
{ convex_face_end_internal(normal); } // Convex face with > 4 vertices
}
else
{ // Non convex and more than 3 points: we triangulate
nonconvex_face_end_internal(normal);
}
m_face_started=false;
}
/// adds `kp` coordinates to `buffer`
template<typename KPoint>
static void add_point_in_buffer(const KPoint& kp, std::vector<float>& buffer)
{
Local_point p=internal::get_local_point(kp);
buffer.push_back(p.x());
buffer.push_back(p.y());
buffer.push_back(p.z());
}
/// adds `kv` coordinates to `buffer`
template<typename KVector>
static void add_normal_in_buffer(const KVector& kv, std::vector<float>& buffer)
{
Local_vector n=internal::get_local_vector(kv);
buffer.push_back(n.x());
buffer.push_back(n.y());
buffer.push_back(n.z());
}
///adds `acolor` RGB components to `buffer`
static void add_color_in_buffer(const CGAL::Color& acolor, std::vector<float>& buffer)
{
buffer.push_back((float)acolor.red()/(float)255);
buffer.push_back((float)acolor.green()/(float)255);
buffer.push_back((float)acolor.blue()/(float)255);
}
/// @return true iff the points of 'facet' form a convex face
static bool is_facet_convex(const std::vector<Local_point>& facet,
const Local_vector& normal)
{
Local_kernel::Orientation orientation, local_orientation;
std::size_t id=0;
do
{
const Local_point& S=facet[id];
const Local_point& T=facet[(id+1==facet.size())?0:id+1];
Local_vector V1=Local_vector((T-S).x(), (T-S).y(), (T-S).z());
const Local_point& U=facet[(id+2==facet.size())?0:id+2];
Local_vector V2=Local_vector((U-T).x(), (U-T).y(), (U-T).z());
orientation = Local_kernel::Orientation_3()(V1, V2, normal);
// Is it possible that orientation==COPLANAR ? Maybe if V1 or V2 is very small ?
}
while(++id!=facet.size() &&
(orientation==CGAL::COPLANAR || orientation==CGAL::ZERO));
//Here, all orientations were COPLANAR. Not sure this case is possible,
// but we stop here.
if (orientation==CGAL::COPLANAR || orientation==CGAL::ZERO)
{ return false; }
// Now we compute convexness
for(id=0; id<facet.size(); ++id)
{
const Local_point& S=facet[id];
const Local_point& T=facet[(id+1==facet.size())?0:id+1];
Local_vector V1=Local_vector((T-S).x(), (T-S).y(), (T-S).z());
const Local_point& U=facet[(id+2==facet.size())?0:id+2];
Local_vector V2=Local_vector((U-T).x(), (U-T).y(), (U-T).z());
local_orientation=Local_kernel::Orientation_3()(V1, V2, normal) ;
if(local_orientation!=CGAL::ZERO && local_orientation!=orientation)
{ return false; }
}
return true;
}
protected:
void face_begin_internal(bool has_color, bool has_normal)
{
if (is_a_face_started())
{
std::cerr<<"You cannot start a new face before to finish the previous one."<<std::endl;
return;
}
m_face_started=true;
m_started_face_is_colored=has_color;
m_started_face_has_normal=has_normal;
m_points_of_face.clear();
m_vertex_normals_for_face.clear();
m_indices_of_points_of_face.clear();
}
void triangular_face_end_internal(const Local_vector& normal)
{
for (int i=0; i<3; ++i)
{
// If user gave vertex indices
if (m_indices_of_points_of_face.size()>0)
{
add_indexed_point(m_indices_of_points_of_face[i]);
}
else
{
add_point(m_points_of_face[i]); // Add the position of the point
if (m_started_face_is_colored)
{ add_color(m_color_of_face); } // Add the color
add_flat_normal(normal); // Add the flat normal
// Its smooth normal (if given by the user)
if (m_vertex_normals_for_face.size()>0)
{ // Here we have 3 vertex normals; we can use Gouraud
add_gouraud_normal(m_vertex_normals_for_face[i]);
}
else
{ // Here user does not provide all vertex normals: we use face normal istead
// and thus we will not be able to use Gouraud
add_gouraud_normal(normal);
}
}
}
}
void convex_quadrangular_face_end_internal(const Local_vector& normal)
{
// Add indices when they exist
if (m_indices_of_points_of_face.size()>0)
{
add_indexed_point(m_indices_of_points_of_face[0]);
add_indexed_point(m_indices_of_points_of_face[1]);
add_indexed_point(m_indices_of_points_of_face[2]);
add_indexed_point(m_indices_of_points_of_face[0]);
add_indexed_point(m_indices_of_points_of_face[2]);
add_indexed_point(m_indices_of_points_of_face[3]);
}
else
{
// (1) add points
add_point(m_points_of_face[0]);
add_point(m_points_of_face[1]);
add_point(m_points_of_face[2]);
add_point(m_points_of_face[0]);
add_point(m_points_of_face[2]);
add_point(m_points_of_face[3]);
// (2) Add flat and smooth normals and color
for(unsigned int i=0; i<6; ++i)
{
if (m_started_face_is_colored)
{ add_color(m_color_of_face); }
add_flat_normal(normal);
if (m_vertex_normals_for_face.size()==0)
{ add_gouraud_normal(normal); }
}
if (m_vertex_normals_for_face.size()>0)
{
add_gouraud_normal(m_vertex_normals_for_face[0]);
add_gouraud_normal(m_vertex_normals_for_face[1]);
add_gouraud_normal(m_vertex_normals_for_face[2]);
add_gouraud_normal(m_vertex_normals_for_face[0]);
add_gouraud_normal(m_vertex_normals_for_face[2]);
add_gouraud_normal(m_vertex_normals_for_face[3]);
}
}
}
void convex_face_end_internal(const Local_vector& normal)
{
for(std::size_t i=1; i<m_points_of_face.size()-1; ++i)
{
// Add indices when they exist
if (m_indices_of_points_of_face.size()>0)
{
add_indexed_point(m_indices_of_points_of_face[0]);
add_indexed_point(m_indices_of_points_of_face[i]);
add_indexed_point(m_indices_of_points_of_face[i+1]);
}
else
{
Local_point& p0 = m_points_of_face[0];
Local_point& p1 = m_points_of_face[i];
Local_point& p2 = m_points_of_face[i+1];
// (1) add points
add_point(p0);
add_point(p1);
add_point(p2);
// (2) Add flat normal and color
for(unsigned int j=0; j<3; ++j)
{
if (m_started_face_is_colored)
{ add_color(m_color_of_face); }
add_flat_normal(normal);
if (m_vertex_normals_for_face.size()==0)
{ add_gouraud_normal(normal); } // No smooth normal, we use the flat one instead
}
// (3) Add smooth normals if they exist
if (m_vertex_normals_for_face.size()>0)
{
add_gouraud_normal(m_vertex_normals_for_face[0]);
add_gouraud_normal(m_vertex_normals_for_face[i]);
add_gouraud_normal(m_vertex_normals_for_face[i+1]);
}
}
}
}
void nonconvex_face_end_internal(const Local_vector& normal)
{
try
{
P_traits cdt_traits(normal);
CDT cdt(cdt_traits);
bool with_vertex_normal=(m_vertex_normals_for_face.size()==m_points_of_face.size());
// (1) We insert all the edges as contraint in the CDT.
typename CDT::Vertex_handle previous=NULL, first=NULL;
for (unsigned int i=0; i<m_points_of_face.size(); ++i)
{
typename CDT::Vertex_handle vh = cdt.insert(m_points_of_face[i]);
if(first==NULL)
{ first=vh; }
if (with_vertex_normal)
{ vh->info().v=m_vertex_normals_for_face[i]; }
else
{ vh->info().v=normal; }
if (m_indices_of_points_of_face.size()>0)
{ vh->info().index=m_indices_of_points_of_face[i]; }
if(previous!=NULL && previous!=vh)
{ cdt.insert_constraint(previous, vh); }
previous=vh;
}
if (previous!=NULL && previous!=first)
{ cdt.insert_constraint(previous, first); }
// (2) We mark all external triangles
// (2.1) We initialize is_external and is_process values
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;
}
// (2.2) We check if the facet is external or internal
std::queue<typename CDT::Face_handle> face_queue;
typename CDT::Face_handle face_internal = NULL;
if (cdt.infinite_vertex()->face()!=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)))
{
if (fh->neighbor(i)!=NULL)
{ 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(unsigned int i=0; i<3; ++i)
{
if(!cdt.is_constrained(std::make_pair(fh, i)))
{
if (fh->neighbor(i)!=NULL)
{ face_queue.push(fh->neighbor(i)); }
}
}
}
}
// (3) Now we iterates on the internal faces to add the vertices
// and the normals to the appropriate vectors
for(typename CDT::Finite_faces_iterator ffit=cdt.finite_faces_begin(),
ffitend = cdt.finite_faces_end(); ffit!=ffitend; ++ffit)
{
if(!ffit->info().is_external)
{
for(unsigned int i=0; i<3; ++i)
{
// Add indices when they exist
if (m_indices_of_points_of_face.size()>0)
{ add_indexed_point(ffit->vertex(i)->info().index); }
else
{
// (1) add point
add_point(ffit->vertex(i)->point());
// (2) Add face color
if (m_started_face_is_colored)
{ add_color(m_color_of_face); }
// (3) Add flat normal
add_flat_normal(normal);
// (4) Add smooth normals (or flat if smooth normals do not exist)
add_gouraud_normal(ffit->vertex(i)->info().v);
}
}
}
}
}
catch(...)
{ // Triangulation crash: the face is not filled
std::cerr<<"Catch: face not filled."<<std::endl;
}
}
/// @return true iff the current face is convex
bool is_current_face_convex(const Local_vector& N) const
{
return is_facet_convex(m_points_of_face, N);
}
void add_color(const CGAL::Color& acolor)
{
if (m_color_buffer!=NULL)
{ add_color_in_buffer(acolor, *m_color_buffer); }
}
template<typename KVector>
void add_flat_normal(const KVector& kv)
{
if(m_flat_normal_buffer != NULL)
{ add_normal_in_buffer(kv, *m_flat_normal_buffer); }
}
template<typename KVector>
void add_gouraud_normal(const KVector& kv)
{
if(m_gouraud_normal_buffer != NULL)
{ add_normal_in_buffer(kv, *m_gouraud_normal_buffer); }
}
protected:
// Types usefull for triangulation
struct Vertex_info
{
Local_vector v;
std::size_t index;
};
struct Face_info
{
bool exist_edge[3];
bool is_external;
bool is_process;
};
typedef CGAL::Triangulation_2_projection_traits_3<CGAL::Exact_predicates_inexact_constructions_kernel> P_traits;
typedef CGAL::Triangulation_vertex_base_with_info_2<Vertex_info, 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::Exact_predicates_tag Itag;
typedef CGAL::Constrained_Delaunay_triangulation_2<P_traits, TDS, Itag> CDT;
protected:
std::vector<BufferType>* m_pos_buffer;
std::vector<IndexType>* m_index_buffer;
std::vector<BufferType>* m_color_buffer;
std::vector<BufferType>* m_flat_normal_buffer;
std::vector<BufferType>* m_gouraud_normal_buffer;
CGAL::Bbox_3* m_bb;
// Local variables, used when we started a new face.
bool m_face_started;
bool m_started_face_is_colored;
bool m_started_face_has_normal;
std::vector<Local_point> m_points_of_face;
std::vector<Local_vector> m_vertex_normals_for_face;
std::vector<std::size_t> m_indices_of_points_of_face;
CGAL::Color m_color_of_face;
Local_vector m_normal_of_face;
};
} // End namespace CGAL
#endif // CGAL_VBO_BUFFER_FILLER_H

File diff suppressed because it is too large Load Diff

View File

@ -58,7 +58,6 @@ qt5_wrap_ui(uis MainWindow.ui CreateMesh.ui CreateMenger.ui
# qrc files (resources files, that contain icons, at least)
qt5_add_resources (CGAL_Qt5_RESOURCE_FILES ./Linear_cell_complex_3.qrc)
add_executable(Linear_cell_complex_3_demo
Linear_cell_complex_3_demo.cpp MainWindow.cpp
Viewer.cpp Linear_cell_complex_3_subdivision.cpp

View File

@ -0,0 +1,15 @@
namespace CGAL {
/*!
\ingroup PkgDrawLinearCellComplex
Open a new window and draw `alcc`, a model of the `LinearCellComplex` concept. The 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 LCC a model of the `LinearCellComplex` concept.
\param alcc the linear cell complex to draw.
*/
template<class LCC>
void draw(const LCC& alcc);
} /* namespace CGAL */

View File

@ -241,7 +241,7 @@ point: 1 0 0, color: 19
Before applying the sew operation, the eight vertices of the first cube are colored by `1`, and the eight vertices of the second cube by `19`. After the sew operation, there are eight vertices which are merged two by two, and due to the average functor, the color of the four resulting vertices is now 10. Then we insert a vertex in the center of the common 2-cell between the two cubes. The coordinates of this vertex are initialized with the barycenter of the 2-cell (-1,0.5,0.5), and its color is not initialized by the method, thus we set its color manually by using the result of \link LinearCellComplex::insert_barycenter_in_cell `insert_barycenter_in_cell<2>`\endlink which is a dart incident to the new vertex.
\subsection Linear_cell_complexAutomaticAttributesManagement Automatic attributes management
\subsection Linear_cell_complexAutomaticAttributesManagement Automatic Attribute Management
\anchor ssecAttributesManagement
The following example illustrates the use of the automatic attributes management for a linear cell complex. An off file is loaded into a 2D linear cell complex embedded in 3D. Then, a certain percentage of edges is removed from the linear cell complex. The same method is applied twice: the first time by using the automatic attributes management (which is the default behaviour) and the second time by calling first \link GenericMap::set_automatic_attributes_management `set_automatic_attributes_management(false)`\endlink to disable the automatic updating of attributes.
@ -250,6 +250,19 @@ We can observe that the second run is faster than the first one. Indeed, updatin
\cgalExample{Linear_cell_complex/linear_cell_complex_3_attributes_management.cpp}
\subsection Linear_cell_complexDraw Draw a Linear Cell Complex
\anchor ssecDrawLCC
A linear cell complex can be visualized by calling the `CGAL::draw()` function as shown in the following example. This function opens a new window showing the given linear cell complex. The function is blocking, that is the program continues as soon as the user closes the window.
\cgalExample{Linear_cell_complex/draw_linear_cell_complex.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_lcc,draw_lcc.png}
Result of the run of the draw_linear_cell_complex program. A window shows two 3D cubes and allows to navigate through the 3D scene.
\cgalFigureEnd
\section Linear_cell_complexDesign Design and Implementation History
This package was developed by Guillaume Damiand, with the help of Andreas Fabri, S&eacute;bastien Loriot and Laurent Rineau. Monique Teillaud and Bernd G&auml;rtner contributed to the manual.

View File

@ -19,6 +19,14 @@
/// \defgroup PkgLinearCellComplexOperations Operations for Linear Cell Complex
/// \ingroup PkgLinearCellComplex
/*! Draw.
\code
#include <CGAL/draw_linear_cell_complex.h>
\endcode
*/
/// \defgroup PkgDrawLinearCellComplex Draw a Linear Cell Complex
/// \ingroup PkgLinearCellComplex
/*!
\addtogroup PkgLinearCellComplex
@ -57,14 +65,17 @@
- `CGAL::Linear_cell_complex<d,d2,LCCTraits,Items,Alloc>`
## Global Functions ##
### Constructions for Linear cell complex ###
### Constructions for Linear Cell Complex ###
- `CGAL::import_from_plane_graph<LCC>`
- `CGAL::import_from_triangulation_3<LCC,Triangulation>`
- `CGAL::import_from_polyhedron_3<LCC,Polyhedron>`
### Operations for Linear cell complex ###
### Operations for Linear Cell Complex ###
- `CGAL::compute_normal_of_cell_0<LCC>`
- `CGAL::compute_normal_of_cell_2<LCC>`
### Draw a Linear cell complex ###
- `CGAL::draw<LCC>`
*/

View File

@ -3,4 +3,5 @@
\example Linear_cell_complex/linear_cell_complex_3.cpp
\example Linear_cell_complex/linear_cell_complex_4.cpp
\example Linear_cell_complex/linear_cell_complex_3_attributes_management.cpp
\example Linear_cell_complex/draw_linear_cell_complex.cpp
*/

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View File

@ -1,33 +0,0 @@
# This file must be included in your CMakeLists.txt to use the basic viewer
# You need to link the libraries in your executable by using
# TARGET_LINK_LIBRARIES( myexec ${BASIC_VIEWER_LIBRARIES})
if ( NOT CGAL_FOUND OR NOT CGAL_Qt5_FOUND)
message(STATUS "NOTICE: Libraries for basic viewer not found "
"(CGAL, Qt5, QGLViewer).")
endif( NOT CGAL_FOUND OR NOT CGAL_Qt5_FOUND)
include( ${CGAL_USE_FILE} )
set(CMAKE_INCLUDE_CURRENT_DIR ON)
FIND_PACKAGE(Qt5 REQUIRED COMPONENTS OpenGL Xml)
find_package(QGLViewer REQUIRED)
find_package(OpenGL REQUIRED)
add_definitions(${QT_DEFINITIONS})
add_definitions(-DQT_NO_KEYWORDS)
include_directories( ${QGLVIEWER_INCLUDE_DIR} )
add_definitions(${QGLVIEWER_DEFINITIONS})
set (BASIC_VIEWER_LIBRARIES ${QT_LIBRARIES} ${QGLVIEWER_LIBRARIES}
${OPENGL_gl_LIBRARY}) # ${OPENGL_glu_LIBRARY}
set(BASIC_VIEWER_MODULES Xml OpenGL)
ADD_DEFINITIONS("-DCGAL_USE_BASIC_VIEWER")
message(STATUS "Libraries for lcc_viewer found. You need to link them "
"in your executable by using "
"TARGET_LINK_LIBRARIES( myexec \${BASIC_VIEWER_LIBRARIES})")
set(USE_BASIC_VIEWER true)

View File

@ -9,14 +9,11 @@ if(NOT POLICY CMP0070 AND POLICY CMP0053)
cmake_policy(SET CMP0053 OLD)
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)
# find_package(CGAL COMPONENTS Qt5)
# include("CMakeBasicViewerQt.inc")
# If you don't want to visualize, use the following line (otherwise comment it)
find_package(CGAL QUIET)
if(CGAL_Qt5_FOUND)
add_definitions(-DCGAL_USE_BASIC_VIEWER -DQT_NO_KEYWORDS)
endif()
# For Gprof.
# ADD_DEFINITIONS("-pg")
@ -25,50 +22,31 @@ find_package(CGAL QUIET)
# To use valgrind, we must disable rounding math ckeck.
# add_definition(-DCGAL_DISABLE_ROUNDING_MATH_CHECK)
if ( CGAL_FOUND )
if (CGAL_FOUND)
include( ${CGAL_USE_FILE} )
include( CGAL_CreateSingleSourceCGALProgram )
include(CGAL_CreateSingleSourceCGALProgram)
include_directories(BEFORE ../../include)
create_single_source_cgal_program( "linear_cell_complex_3.cpp" )
create_single_source_cgal_program( "linear_cell_complex_4.cpp" )
create_single_source_cgal_program(
"linear_cell_complex_3_with_colored_vertices.cpp" )
create_single_source_cgal_program(
"linear_cell_complex_3_with_mypoint.cpp" )
create_single_source_cgal_program("plane_graph_to_lcc_2.cpp")
create_single_source_cgal_program("gmap_linear_cell_complex_3.cpp")
create_single_source_cgal_program("linear_cell_complex_3.cpp")
create_single_source_cgal_program("linear_cell_complex_3_attributes_management.cpp")
create_single_source_cgal_program("linear_cell_complex_3_operations.cpp")
create_single_source_cgal_program("linear_cell_complex_3_with_colored_vertices.cpp")
create_single_source_cgal_program("linear_cell_complex_3_with_mypoint.cpp")
create_single_source_cgal_program("linear_cell_complex_4.cpp")
create_single_source_cgal_program("plane_graph_to_lcc_2.cpp")
create_single_source_cgal_program("voronoi_2.cpp")
create_single_source_cgal_program("voronoi_3.cpp")
add_executable(voronoi_2 voronoi_2.cpp)
target_link_libraries(voronoi_2 ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES}
${BASIC_VIEWER_LIBRARIES})
if (USE_BASIC_VIEWER)
qt5_use_modules(voronoi_2 ${BASIC_VIEWER_MODULES})
endif(USE_BASIC_VIEWER)
create_single_source_cgal_program("draw_linear_cell_complex.cpp")
if(CGAL_Qt5_FOUND)
target_link_libraries(draw_linear_cell_complex PUBLIC CGAL::CGAL_Qt5)
endif()
add_executable(voronoi_3 voronoi_3.cpp)
target_link_libraries(voronoi_3 ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES}
${BASIC_VIEWER_LIBRARIES})
if (USE_BASIC_VIEWER)
qt5_use_modules(voronoi_3 ${BASIC_VIEWER_MODULES})
endif(USE_BASIC_VIEWER)
create_single_source_cgal_program( "gmap_linear_cell_complex_3.cpp" )
add_executable(linear_cell_complex_3_operations linear_cell_complex_3_operations.cpp)
target_link_libraries(linear_cell_complex_3_operations ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES}
${BASIC_VIEWER_LIBRARIES})
if (USE_BASIC_VIEWER)
qt5_use_modules(linear_cell_complex_3_operations ${BASIC_VIEWER_MODULES})
endif(USE_BASIC_VIEWER)
else()
message(STATUS "This program requires the CGAL library, "
"and will not be compiled.")
message(STATUS "This program requires the CGAL library, and will not be compiled.")
endif()

View File

@ -0,0 +1,29 @@
#include <CGAL/Linear_cell_complex_for_combinatorial_map.h>
#include <CGAL/draw_linear_cell_complex.h>
typedef CGAL::Linear_cell_complex_for_combinatorial_map<3> LCC;
typedef LCC::Dart_handle Dart_handle;
typedef LCC::Point Point;
int main()
{
LCC lcc;
Dart_handle dh1=
lcc.make_hexahedron(Point(0,0,0), Point(5,0,0),
Point(5,5,0), Point(0,5,0),
Point(0,5,4), Point(0,0,4),
Point(5,0,4), Point(5,5,4));
Dart_handle dh2=
lcc.make_hexahedron(Point(5,0,0), Point(10,0,0),
Point(10,5,0), Point(5,5,0),
Point(5,5,4), Point(5,0,4),
Point(10,0,4), Point(10,5,4));
lcc.sew<3>(lcc.beta(dh1, 1, 1, 2), lcc.beta(dh2, 2));
lcc.display_characteristics(std::cout)<<", valid="
<<lcc.is_valid()<<std::endl;
CGAL::draw(lcc);
return EXIT_SUCCESS;
}

View File

@ -2,11 +2,6 @@
#include <CGAL/Linear_cell_complex_for_generalized_map.h>
#include <vector>
/* If you want to use a viewer, you can use qglviewer. */
#ifdef CGAL_USE_BASIC_VIEWER
#include "linear_cell_complex_3_viewer_qt.h"
#endif
typedef CGAL::Linear_cell_complex_for_combinatorial_map<3> LCC_3_cmap;
typedef CGAL::Linear_cell_complex_for_generalized_map<3> LCC_3_gmap;
@ -54,10 +49,6 @@ void run_test()
lcc.template sew<3>(lcc.template opposite<2>(lcc.next(dh1)),
lcc.other_orientation(lcc.template opposite<2>(lcc.previous(dh3))));
#ifdef CGAL_USE_BASIC_VIEWER
display_lcc(lcc);
#endif // CGAL_USE_BASIC_VIEWER
lcc.insert_cell_1_in_cell_2(lcc.next(dh1),
Alpha1<LCC>::run(lcc, lcc.previous(dh1)));
dh2=lcc.template opposite<2>(lcc.next(lcc.next
@ -73,14 +64,9 @@ void run_test()
lcc.insert_cell_2_in_cell_3(path.begin(),path.end());
lcc.display_characteristics(std::cout) << ", valid="
<< lcc.is_valid() << std::endl;
#ifdef CGAL_USE_BASIC_VIEWER
display_lcc(lcc);
#endif // CGAL_USE_BASIC_VIEWER
<< lcc.is_valid() << std::endl;
}
int main()
{
run_test<LCC_3_cmap>();

View File

@ -1,242 +0,0 @@
// Copyright (c) 2011 CNRS and LIRIS' Establishments (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: LGPL-3.0+
//
// Author(s) : Guillaume Damiand <guillaume.damiand@liris.cnrs.fr>
#ifndef CGAL_LCC_3_VIEWER_QT_H
#define CGAL_LCC_3_VIEWER_QT_H
#include "basic_viewer.h"
#include <CGAL/Linear_cell_complex.h>
#include <CGAL/Cartesian_converter.h>
#include <CGAL/Random.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel Local_kernel;
typedef Local_kernel::Point_3 Local_point;
typedef Local_kernel::Vector_3 Local_vector;
// Default color functor; user can change it to have its own face color
struct DefaultColorFunctor
{
template<typename LCC>
static CGAL::Color run(const LCC& alcc,
typename LCC::Dart_const_handle dh)
{
if (dh==alcc.null_handle) // use to get the mono color
return CGAL::Color(100, 125, 200); // R G B between 0-255
// Here dh is the smaller dart of its face
CGAL::Random random(alcc.darts().index(dh));
CGAL::Color res;
do
{
res=CGAL::Color(random.get_int(0,256),
random.get_int(0,256),
random.get_int(0,256));
}
while(res.red()==255 && res.green()==255 && res.blue()==255);
return res;
}
};
template<class LCC, int dim=LCC::ambient_dimension>
struct Geom_utils;
template<class LCC>
struct Geom_utils<LCC,3>
{
Local_point get_point(const LCC& lcc,
typename LCC::Vertex_attribute_const_handle vh)
{ return converter(lcc.point_of_vertex_attribute(vh)); }
Local_point get_point(const LCC& lcc, typename LCC::Dart_const_handle dh)
{ return converter(lcc.point(dh)); }
Local_vector get_vertex_normal(const LCC& lcc,
typename LCC::Dart_const_handle dh)
{
Local_vector n = converter(CGAL::compute_normal_of_cell_0<LCC>(lcc,dh));
n = n/(CGAL::sqrt(n*n));
return n;
}
protected:
CGAL::Cartesian_converter<typename LCC::Traits, Local_kernel> converter;
};
template<class LCC>
struct Geom_utils<LCC,2>
{
Local_point get_point(const LCC& lcc,
typename LCC::Vertex_attribute_const_handle vh)
{
Local_point p(converter(lcc.point_of_vertex_attribute(vh).x()),0,
converter(lcc.point_of_vertex_attribute(vh).y()));
return p;
}
Local_point get_point(const LCC& lcc, typename LCC::Dart_const_handle dh)
{ return get_point(lcc, lcc.vertex_attribute(dh)); }
Local_vector get_vertex_normal(const LCC&, typename LCC::Dart_const_handle)
{
Local_vector n(0,-1,0);
return n;
}
protected:
CGAL::Cartesian_converter<typename LCC::Traits, Local_kernel> converter;
};
// Viewer class for LCC
template<class LCC, class ColorFunctor>
class SimpleLCCViewerQt : public Basic_viewer
{
typedef Basic_viewer Base;
typedef typename LCC::Dart_const_handle Dart_const_handle;
public:
/// Construct the viewer.
/// @param alcc the lcc 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 LCC where this time could be long)
SimpleLCCViewerQt(const LCC& alcc, const char* title="", bool anofaces=false) :
Base(title),
lcc(alcc),
m_nofaces(anofaces)
{
compute_elements();
}
protected:
void compute_face(Dart_const_handle dh)
{
// We fill only closed faces.
Dart_const_handle cur=dh;
Dart_const_handle min=dh;
do
{
if (!lcc.is_next_exist(cur)) return; // open face=>not filled
if (cur<min) min=cur;
cur=lcc.next(cur);
}
while(cur!=dh);
CGAL::Color c=ColorFunctor::run(lcc, dh);
if (c.red()<60 || c.green()<60 || c.blue()<60)
mono_face_begin();
else
colored_face_begin(c);
cur=dh;
do
{
add_point_in_face(geomutils.get_point(lcc, cur),
geomutils.get_vertex_normal(lcc, cur));
cur=lcc.next(cur);
}
while(cur!=dh);
face_end();
}
void compute_edge(Dart_const_handle dh)
{
Local_point p1 = geomutils.get_point(lcc, dh);
Dart_const_handle d2 = lcc.other_extremity(dh);
if ( d2!=NULL )
{
Local_point p2 = geomutils.get_point(lcc, d2);
add_mono_segment(p1, p2);
}
}
void compute_vertex(Dart_const_handle dh, bool& empty)
{
Local_point p = geomutils.get_point(lcc, dh);
add_mono_point(p);
}
void compute_elements()
{
clear();
unsigned int markfaces = lcc.get_new_mark();
unsigned int markedges = lcc.get_new_mark();
unsigned int markvertices = lcc.get_new_mark();
bool empty = true;
for (typename LCC::Dart_range::const_iterator it=lcc.darts().begin(),
itend=lcc.darts().end(); it!=itend; ++it )
{
if ( !m_nofaces && !lcc.is_marked(it, markfaces) )
{
compute_face(it);
CGAL::mark_cell<LCC, 2>(lcc, it, markfaces);
}
if ( !lcc.is_marked(it, markedges) )
{
compute_edge(it);
CGAL::mark_cell<LCC, 1>(lcc, it, markedges);
}
if ( !lcc.is_marked(it, markvertices) )
{
compute_vertex(it, empty);
CGAL::mark_cell<LCC, 0>(lcc, it, markvertices);
}
}
lcc.free_mark(markfaces);
lcc.free_mark(markedges);
lcc.free_mark(markvertices);
}
virtual void keyPressEvent(QKeyEvent *e)
{
const Qt::KeyboardModifiers modifiers = e->modifiers();
Base::keyPressEvent(e);
}
protected:
const LCC& lcc;
bool m_nofaces;
Geom_utils<LCC> geomutils;
};
template<class LCC, class ColorFunctor=DefaultColorFunctor>
void display_lcc(const LCC& alcc,
const char* title="",
bool nofill=false)
{
int argc=1;
const char* argv[2]={"lccviewer","\0"};
QApplication app(argc,const_cast<char**>(argv));
SimpleLCCViewerQt<LCC, ColorFunctor> mainwindow(alcc, title, nofill);
mainwindow.show();
app.exec();
}
#endif // CGAL_LCC_3_VIEWER_QT_H

View File

@ -6,10 +6,6 @@
#include <iostream>
#include <fstream>
/* If you want to use a viewer, you can use qglviewer. */
#ifdef CGAL_USE_BASIC_VIEWER
#include "linear_cell_complex_3_viewer_qt.h"
#endif
// This example works both with cmap and gmap as combinatorial data structure.
//typedef CGAL::Linear_cell_complex_for_combinatorial_map<2> LCC_2;
@ -56,10 +52,6 @@ void display_voronoi(LCC_2& alcc, Dart_handle adart)
alcc.display_characteristics(std::cout) << ", valid="
<< alcc.is_valid()
<< std::endl;
#ifdef CGAL_USE_BASIC_VIEWER
display_lcc(alcc);
#endif // CGAL_USE_BASIC_VIEWER
}
template<typename LCC, typename TR>

View File

@ -5,11 +5,6 @@
#include <iostream>
#include <fstream>
/* If you want to use a viewer, you can use one qglviewer. */
#ifdef CGAL_USE_BASIC_VIEWER
#include "linear_cell_complex_3_viewer_qt.h"
#endif
/* // If you want to use exact constructions.
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
typedef CGAL::Linear_cell_complex<3,3,
@ -59,10 +54,6 @@ void display_voronoi(LCC_3& alcc, Dart_handle adart)
alcc.display_characteristics(std::cout) << ", valid="
<< alcc.is_valid()
<< std::endl;
#ifdef CGAL_USE_BASIC_VIEWER
display_lcc(alcc);
#endif // CGAL_USE_BASIC_VIEWER
}
template<typename LCC, typename TR>

View File

@ -0,0 +1,247 @@
// Copyright (c) 2018 CNRS and LIRIS' Establishments (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: LGPL-3.0+
//
// Author(s) : Guillaume Damiand <guillaume.damiand@liris.cnrs.fr>
#ifndef CGAL_DRAW_LCC_H
#define CGAL_DRAW_LCC_H
#include <CGAL/Qt/Basic_viewer_qt.h>
#ifdef CGAL_USE_BASIC_VIEWER
#include <CGAL/Random.h>
namespace CGAL
{
// Default color functor; user can change it to have its own face color
struct DefaultColorFunctorLCC
{
template<typename LCC>
static CGAL::Color run(const LCC& alcc,
typename LCC::Dart_const_handle dh)
{
if (dh==alcc.null_handle) // use to get the mono color
return CGAL::Color(100, 125, 200); // R G B between 0-255
CGAL::Random random((unsigned int)(alcc.darts().index(dh)));
return get_random_color(random);
}
};
template<class LCC, int dim=LCC::ambient_dimension>
struct Geom_utils;
template<class LCC>
struct Geom_utils<LCC, 3>
{
static typename LCC::Vector get_vertex_normal(const LCC& lcc,
typename LCC::Dart_const_handle dh)
{
typename LCC::Vector n = CGAL::compute_normal_of_cell_0<LCC>(lcc,dh);
n = n/(CGAL::sqrt(n*n));
return n;
}
};
template<class LCC>
struct Geom_utils<LCC, 2>
{
static typename LCC::Vector get_vertex_normal(const LCC&,
typename LCC::Dart_const_handle)
{
typename LCC::Vector res=CGAL::NULL_VECTOR;
return res;
}
};
// Viewer class for LCC
template<class LCC, class ColorFunctor>
class SimpleLCCViewerQt : public Basic_viewer_qt
{
typedef Basic_viewer_qt Base;
typedef typename LCC::Dart_const_handle Dart_const_handle;
typedef typename LCC::Traits Kernel;
typedef typename Kernel::Point Point;
typedef typename Kernel::Vector Vector;
public:
/// Construct the viewer.
/// @param alcc the lcc 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)
SimpleLCCViewerQt(QWidget* parent,
const LCC& alcc,
const char* title="Basic LCC Viewer",
bool anofaces=false,
const ColorFunctor& fcolor=ColorFunctor()) :
// First draw: vertices; edges, faces; multi-color; inverse normal
Base(parent, title, true, true, true, false, true),
lcc(alcc),
m_nofaces(anofaces),
m_fcolor(fcolor)
{
compute_elements();
}
protected:
void compute_face(Dart_const_handle dh)
{
// We fill only closed faces.
Dart_const_handle cur=dh;
Dart_const_handle min=dh;
do
{
if (!lcc.is_next_exist(cur)) return; // open face=>not filled
if (cur<min) min=cur;
cur=lcc.next(cur);
}
while(cur!=dh);
CGAL::Color c=m_fcolor.run(lcc, dh);
face_begin(c);
cur=dh;
do
{
add_point_in_face(lcc.point(cur),
Geom_utils<LCC>::get_vertex_normal(lcc, cur));
cur=lcc.next(cur);
}
while(cur!=dh);
face_end();
}
void compute_edge(Dart_const_handle dh)
{
Point p1 = lcc.point(dh);
Dart_const_handle d2 = lcc.other_extremity(dh);
if (d2!=NULL)
{ add_segment(p1, lcc.point(d2)); }
}
void compute_vertex(Dart_const_handle dh)
{ add_point(lcc.point(dh)); }
void compute_elements()
{
clear();
typename LCC::size_type markfaces = lcc.get_new_mark();
typename LCC::size_type markedges = lcc.get_new_mark();
typename LCC::size_type markvertices = lcc.get_new_mark();
for (typename LCC::Dart_range::const_iterator it=lcc.darts().begin(),
itend=lcc.darts().end(); it!=itend; ++it )
{
if ( !m_nofaces && !lcc.is_marked(it, markfaces) )
{
compute_face(it);
CGAL::mark_cell<LCC, 2>(lcc, it, markfaces);
}
if ( !lcc.is_marked(it, markedges) )
{
compute_edge(it);
CGAL::mark_cell<LCC, 1>(lcc, it, markedges);
}
if ( !lcc.is_marked(it, markvertices) )
{
compute_vertex(it);
CGAL::mark_cell<LCC, 0>(lcc, it, markvertices);
}
}
lcc.free_mark(markfaces);
lcc.free_mark(markedges);
lcc.free_mark(markvertices);
}
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:
const LCC& lcc;
bool m_nofaces;
const ColorFunctor& m_fcolor;
};
template<class LCC, class ColorFunctor>
void draw(const LCC& alcc,
const char* title,
bool nofill,
const ColorFunctor& fcolor)
{
#if defined(CGAL_TEST_SUITE)
bool cgal_test_suite=true;
#else
bool cgal_test_suite=false;
#endif
if (!cgal_test_suite)
{
int argc=1;
const char* argv[2]={"lccviewer","\0"};
QApplication app(argc,const_cast<char**>(argv));
SimpleLCCViewerQt<LCC, ColorFunctor> mainwindow(app.activeWindow(),
alcc,
title,
nofill,
fcolor);
mainwindow.show();
app.exec();
}
}
template<class LCC>
void draw(const LCC& alcc, const char* title, bool nofill)
{
DefaultColorFunctorLCC c;
draw(alcc, title, nofill, c);
}
template<class LCC>
void draw(const LCC& alcc, const char* title)
{ draw(alcc, title, false); }
template<class LCC>
void draw(const LCC& alcc)
{ draw(alcc, "Basic LCC Viewer"); }
} // End namespace CGAL
#endif // CGAL_USE_BASIC_VIEWER
#endif // CGAL_DRAW_LCC_H

View File

@ -8,6 +8,7 @@ Distance_2
Distance_3
Filtered_kernel
Generalized_map
GraphicsView
HalfedgeDS
Hash_map
Homogeneous_kernel

View File

@ -0,0 +1,15 @@
namespace CGAL {
/*!
\ingroup PkgDrawPolyhedron
Open a new window and draw `apoly`, an instance of the `CGAL::Polyhedron_3` class. The 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 POLY an instance of the `CGAL::Polyhedron_3` class.
\param apoly the polyhedron to draw.
*/
template<class POLY>
void draw(const POLY& apoly);
} /* namespace CGAL */

View File

@ -4,6 +4,15 @@
/// \defgroup PkgPolyhedronIOFunc I/O Functions
/// \ingroup PkgPolyhedron
/*! Draw.
\code
#include <CGAL/draw_polyhedron.h>
\endcode
*/
/// \defgroup PkgDrawPolyhedron Draw a Polyhedron 3
/// \ingroup PkgPolyhedron
/*!
\addtogroup PkgPolyhedron
\todo check generated documentation
@ -62,5 +71,9 @@ surface can be used without knowing the halfedge data structure.
- \link PkgPolyhedronIOFunc `CGAL::operator>>()` \endlink
- \link PkgPolyhedronIOFunc `write_off()` \endlink
- \link PkgPolyhedronIOFunc `read_off()` \endlink
### Draw a Polyhedron 3 ###
- `CGAL::draw<POLY>`
*/

View File

@ -275,6 +275,19 @@ are also marked in the program code.
\cgalExample{Polyhedron/polyhedron_prog_cube.cpp}
\subsection PolyhedronDraw Draw a Polyhedron
\anchor ssecDrawPolyhedron
A polyhedron can be visualized by calling the `CGAL::draw()` function as shown in the following example. This function opens a new window showing the given polyhedron. The function is blocking, that is the program continues as soon as the user closes the window.
\cgalExample{Polyhedron/draw_polyhedron.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_polyhedron,draw_polyhedron.png}
Result of the run of the draw_polyhedron program. A window shows the polyhedron and allows to navigate through the 3D scene.
\cgalFigureEnd
\section PolyhedronFile File I/O
\anchor sectionPolyIO

View File

@ -10,4 +10,5 @@
\example Polyhedron/polyhedron_prog_subdiv.cpp
\example Polyhedron/polyhedron_prog_tetra.cpp
\example Polyhedron/polyhedron_prog_vector.cpp
\example Polyhedron/draw_polyhedron.cpp
*/

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View File

@ -4,9 +4,18 @@
project( Polyhedron_Examples )
cmake_minimum_required(VERSION 2.8.10)
cmake_minimum_required(VERSION 3.1)
find_package(CGAL QUIET)
if(NOT POLICY CMP0070 AND POLICY CMP0053)
# Only set CMP0053 to OLD with CMake<3.10, otherwise there is a warning.
cmake_policy(SET CMP0053 OLD)
endif()
find_package(CGAL COMPONENTS Qt5)
if(CGAL_Qt5_FOUND)
add_definitions(-DCGAL_USE_BASIC_VIEWER -DQT_NO_KEYWORDS)
endif()
if ( CGAL_FOUND )
@ -16,12 +25,17 @@ if ( CGAL_FOUND )
include_directories (BEFORE "../../include")
# create a target per cppfile
file(GLOB cppfiles RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
foreach(cppfile ${cppfiles})
create_single_source_cgal_program( "${cppfile}" )
endforeach()
if(CGAL_Qt5_FOUND )
target_link_libraries(draw_polyhedron PUBLIC CGAL::CGAL_Qt5)
endif()
else()
message(STATUS "This program requires the CGAL library, and will not be compiled.")

View File

@ -0,0 +1,18 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/IO/Polyhedron_iostream.h>
#include <CGAL/draw_polyhedron.h>
#include <fstream>
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef CGAL::Polyhedron_3<Kernel> Polyhedron;
int main(int argc, char* argv[])
{
Polyhedron P;
std::ifstream in1((argc>1)?argv[1]:"data/cross.off");
in1 >> P;
CGAL::draw(P);
return EXIT_SUCCESS;
}

View File

@ -4,6 +4,7 @@
#include <algorithm>
#include <vector>
#include <cmath>
#include <fstream>
typedef CGAL::Simple_cartesian<double> Kernel;
typedef Kernel::Vector_3 Vector;
@ -90,9 +91,10 @@ void subdiv( Polyhedron& P) {
CGAL_postcondition( P.is_valid());
}
int main() {
int main(int argc, char* argv[]) {
Polyhedron P;
std::cin >> P;
std::ifstream in1((argc>1)?argv[1]:"data/cube.off");
in1 >> P;
P.normalize_border();
if ( P.size_of_border_edges() != 0) {
std::cerr << "The input object has border edges. Cannot subdivide."

View File

@ -6,6 +6,7 @@
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <fstream>
typedef CGAL::Simple_cartesian<double> Kernel;
typedef Kernel::Vector_3 Vector;
@ -172,21 +173,22 @@ void subdiv_border( Polyhedron& P) {
using namespace std;
int main( int argc, char* argv[]) {
if ( argc > 2 || (argc == 2 && ! isdigit( argv[1][0]))) {
cerr << "Usage: " << argv[0] << " [<n>]" << endl;
cerr << " subdivides <n> times the polyhedron read from stdin."
if ( argc > 3 || (argc == 3 && ! isdigit( argv[2][0]))) {
cerr << "Usage: " << argv[0] << " [offfile] [<n>]]" << endl;
cerr << " subdivides <n> times the polyhedron read from offfile."
<< endl;
exit(1);
}
int n = 1;
if ( argc >= 2)
n = atoi( argv[1]);
std::ifstream in1((argc>1)?argv[1]:"data/lshape_with_boundary.off");
if ( argc == 3)
n = atoi( argv[2]);
if ( n < 1 || n > 12) {
cerr << "Error: Choose reasonable value for <n> in [1..12]" << endl;
exit(1);
}
Polyhedron P;
cin >> P;
in1 >> P;
for ( int i = 0; i != n; ++i) {
cerr << "Subdivision " << i+1 << " ..." << endl;

View File

@ -7,6 +7,7 @@
#include <iostream>
#include <algorithm>
#include <vector>
#include <fstream>
using std::cerr;
using std::endl;
@ -138,12 +139,13 @@ void intersection( const Polyhedron& P) {
Intersect_facets(), std::ptrdiff_t(2000));
}
int main() {
int main(int argc, char* argv[]) {
CGAL::Timer user_time;
cerr << "Loading OFF file ... " << endl;
user_time.start();
Polyhedron P;
cin >> P;
std::ifstream in1((argc>1)?argv[1]:"data/tetra_intersected_by_triangle.off");
in1 >> P;
cerr << "Loading OFF file : " << user_time.time() << " seconds." << endl;
if ( ! P.is_pure_triangle()) {
cerr << "The input object is not triangulated. Cannot intersect."
@ -155,5 +157,6 @@ int main() {
intersection( P);
cerr << "Intersection : " << user_time.time() << " seconds." << endl;
write_off();
return 0;
}

View File

@ -0,0 +1,240 @@
// Copyright (c) 2018 ETH Zurich (Switzerland).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
// You can redistribute it and/or modify it under the terms of the GNU
// General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0+
//
// Author(s) : Guillaume Damiand <guillaume.damiand@liris.cnrs.fr>
#ifndef CGAL_DRAW_POLYHEDRON_H
#define CGAL_DRAW_POLYHEDRON_H
#include <CGAL/license/Polyhedron.h>
#include <CGAL/Qt/Basic_viewer_qt.h>
#ifdef CGAL_USE_BASIC_VIEWER
#include <CGAL/Random.h>
namespace CGAL
{
// Default color functor; user can change it to have its own face color
struct DefaultColorFunctorPolyhedron
{
template<typename Polyhedron>
static CGAL::Color run(const Polyhedron&,
typename Polyhedron::Facet_const_handle fh)
{
if (fh==boost::graph_traits<Polyhedron>::null_face()) // 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 Polyhedron
template<class Polyhedron, class ColorFunctor>
class SimplePolyhedronViewerQt : public Basic_viewer_qt
{
typedef Basic_viewer_qt Base;
typedef typename Polyhedron::Traits Kernel;
typedef typename Polyhedron::Halfedge_const_handle Halfedge_const_handle;
typedef typename Polyhedron::Vertex_const_handle Vertex_const_handle;
typedef typename Polyhedron::Facet_const_handle Facet_const_handle;
public:
/// Construct the viewer.
/// @param apoly the 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
/// usefull for very big object where this time could be long)
SimplePolyhedronViewerQt(QWidget* parent,
const Polyhedron& apoly,
const char* title="Basic Polyhedron Viewer",
bool anofaces=false,
const ColorFunctor& fcolor=ColorFunctor()) :
// First draw: no vertex; edges, faces; mono-color; inverse normal
Base(parent, title, false, true, true, true, false),
poly(apoly),
m_nofaces(anofaces),
m_fcolor(fcolor)
{
compute_elements();
}
protected:
void compute_face(Facet_const_handle fh)
{
CGAL::Color c=m_fcolor.run(poly, fh);
face_begin(c);
Halfedge_const_handle he=fh->facet_begin();
do
{
add_point_in_face(he->vertex()->point(),
get_vertex_normal(he));
he=he->next();
}
while (he!=fh->facet_begin());
face_end();
}
void compute_edge(Halfedge_const_handle he)
{
add_segment(he->vertex()->point(),
he->opposite()->vertex()->point());
// We can use add_segment(p1, p2, c) with c a CGAL::Color to add a colored segment
}
void compute_vertex(Vertex_const_handle vh)
{
add_point(vh->point());
// We can use add_point(p, c) with c a CGAL::Color to add a colored point
}
void compute_elements()
{
clear();
if (!m_nofaces)
{
for(typename Polyhedron::Facet_const_iterator f=poly.facets_begin();
f!=poly.facets_end(); f++)
{
if (f!=boost::graph_traits<Polyhedron>::null_face())
{ compute_face(f); }
}
}
for ( typename Polyhedron::Halfedge_const_iterator e=poly.halfedges_begin();
e!=poly.halfedges_end(); ++e)
{
if (e<e->opposite())
{ compute_edge(e); }
}
for ( typename Polyhedron::Vertex_const_iterator v=poly.vertices_begin();
v!=poly.vertices_end(); ++v)
{ compute_vertex(v); }
}
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:
typename Kernel::Vector_3 get_face_normal(Halfedge_const_handle he)
{
typename Kernel::Vector_3 normal=CGAL::NULL_VECTOR;
Halfedge_const_handle end=he;
unsigned int nb=0;
do
{
internal::newell_single_step_3(he->vertex()->point(),
he->next()->vertex()->point(),
normal);
++nb;
he=he->next();
}
while (he!=end);
assert(nb>0);
return (typename Kernel::Construct_scaled_vector_3()(normal, 1.0/nb));
}
typename Kernel::Vector_3 get_vertex_normal(Halfedge_const_handle he)
{
typename Kernel::Vector_3 normal=CGAL::NULL_VECTOR;
Halfedge_const_handle end=he;
do
{
if (!he->is_border())
{
typename Kernel::Vector_3 n=get_face_normal(he);
normal=typename Kernel::Construct_sum_of_vectors_3()(normal, n);
}
he=he->next()->opposite();
}
while (he!=end);
if (!typename Kernel::Equal_3()(normal, CGAL::NULL_VECTOR))
{ normal=(typename Kernel::Construct_scaled_vector_3()
(normal, 1.0/CGAL::sqrt(normal.squared_length()))); }
return normal;
}
protected:
const Polyhedron& poly;
bool m_nofaces;
const ColorFunctor& m_fcolor;
};
template<class Polyhedron, class ColorFunctor>
void draw(const Polyhedron& apoly,
const char* title,
bool nofill,
const ColorFunctor& fcolor)
{
#if defined(CGAL_TEST_SUITE)
bool cgal_test_suite=true;
#else
bool cgal_test_suite=false;
#endif
if (!cgal_test_suite)
{
int argc=1;
const char* argv[2]={"polyhedron_viewer","\0"};
QApplication app(argc,const_cast<char**>(argv));
SimplePolyhedronViewerQt<Polyhedron, ColorFunctor>
mainwindow(app.activeWindow(), apoly, title, nofill, fcolor);
mainwindow.show();
app.exec();
}
}
template<class Polyhedron>
void draw(const Polyhedron& apoly, const char* title, bool nofill)
{
DefaultColorFunctorPolyhedron c;
draw(apoly, title, nofill, c);
}
template<class Polyhedron>
void draw(const Polyhedron& apoly, const char* title)
{ draw(apoly, title, false); }
template<class Polyhedron>
void draw(const Polyhedron& apoly)
{ draw(apoly, "Basic Polyhedron Viewer"); }
} // End namespace CGAL
#endif // CGAL_USE_BASIC_VIEWER
#endif // CGAL_DRAW_POLYHEDRON_H

View File

@ -2,6 +2,7 @@ Algebraic_foundations
BGL
Circulator
Distance_2
GraphicsView
HalfedgeDS
Hash_map
Installation

View File

@ -57,7 +57,7 @@ echo " Checks finished"
cd $CGAL_ROOT
rm -r dep_check_build
if [ -n "$TOTAL_RES" ]; then
echo "$TOTAL_RES"
printf "$TOTAL_RES"
echo " You can run cmake with options CGAL_ENABLE_CHECK_HEADERS and CGAL_COPY_DEPENDENCIES ON, make the target packages_dependencies and commit the new dependencies files,"
echo " or simply manually edit the problematic files."
exit 1

View File

@ -1,6 +1,14 @@
/// \defgroup PkgSurface_mesh Surface Mesh Reference
/*! Draw.
\code
#include <CGAL/draw_surface_mesh.h>
\endcode
*/
/// \defgroup PkgDrawSurfaceMesh Draw a Surface Mesh
/// \ingroup PkgSurface_mesh
/*!
\addtogroup PkgSurface_mesh
\cgalPkgDescriptionBegin{Surface Mesh,PkgSurfaceMeshSummary}
@ -31,5 +39,8 @@ and faces is much simpler and can be used at runtime and not at compile time.}
- `CGAL::Surface_mesh<P>`
### Draw a Surface Mesh ###
- `CGAL::draw<SM>`
*/

View File

@ -344,6 +344,20 @@ refering to the right vertices.
\subsection SubsectionSurfaceMeshMemoryManagementExample Example
\cgalExample{Surface_mesh/sm_memory.cpp}
\section SurfaceMeshDraw Draw a Surface Mesh
\anchor ssecDrawSurfaceMesh
A surface mesh can be visualized by calling the `CGAL::draw()` function as shown in the following example. This function opens a new window showing the given surface mesh. The function is blocking, that is the program continues as soon as the user closes the window.
\cgalExample{Surface_mesh/draw_surface_mesh.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_surface_mesh,draw_surface_mesh.png}
Result of the run of the draw_surface_mesh program. A window shows the surface mesh and allows to navigate through the 3D scene.
\cgalFigureEnd
\section sectionSurfaceMeshImplementation Implementation Details
As integer type for the indices we have chosen `boost::uint32_t`. On 64 bit operating systems they

View File

@ -10,4 +10,5 @@
\example Surface_mesh/sm_do_intersect.cpp
\example Surface_mesh/sm_aabbtree.cpp
@endcond
\example Surface_mesh/draw_surface_mesh.cpp
*/

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

View File

@ -6,8 +6,16 @@ project( Surface_mesh_Examples )
cmake_minimum_required(VERSION 2.8.11)
if(NOT POLICY CMP0070 AND POLICY CMP0053)
# Only set CMP0053 to OLD with CMake<3.10, otherwise there is a warning.
cmake_policy(SET CMP0053 OLD)
endif()
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 )
@ -28,6 +36,11 @@ if ( CGAL_FOUND )
create_single_source_cgal_program( "sm_memory.cpp" )
create_single_source_cgal_program( "sm_properties.cpp" )
create_single_source_cgal_program("draw_surface_mesh.cpp")
if(CGAL_Qt5_FOUND )
target_link_libraries(draw_surface_mesh PUBLIC CGAL::CGAL_Qt5)
endif()
else()
message(STATUS "This program requires the CGAL library, and will not be compiled.")

View File

@ -1,22 +0,0 @@
OFF
8 12 0
-1 -1 -1
-1 1 -1
1 1 -1
1 -1 -1
-1 -1 1
-1 1 1
1 1 1
1 -1 1
3 0 1 3
3 3 1 2
3 0 4 1
3 1 4 5
3 3 2 7
3 7 2 6
3 4 0 3
3 7 4 3
3 6 4 7
3 6 5 4
3 1 5 6
3 2 1 6

View File

@ -0,0 +1,19 @@
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/draw_surface_mesh.h>
#include <fstream>
typedef CGAL::Simple_cartesian<double> Kernel;
typedef Kernel::Point_3 Point;
typedef CGAL::Surface_mesh<Point> Mesh;
int main(int argc, char* argv[])
{
Mesh sm1;
std::ifstream in1((argc>1)?argv[1]:"data/triangle.off");
in1 >> sm1;
CGAL::draw(sm1);
return EXIT_SUCCESS;
}

View File

@ -36,5 +36,4 @@ int main(int argc, char* argv[])
std::cout << sm1 << std::endl;
}

View File

@ -0,0 +1,252 @@
// Copyright (c) 2018 GeometryFactory (France)
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
// You can redistribute it and/or modify it under the terms of the GNU
// General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0+
//
// Author(s) : Guillaume Damiand <guillaume.damiand@liris.cnrs.fr>
#ifndef CGAL_DRAW_SURFACE_MESH_H
#define CGAL_DRAW_SURFACE_MESH_H
#ifdef DOXYGEN_RUNNING
/*!
\ingroup PkgDrawSurfaceMesh
Open a new window and draw `asm`, an instance of the `CGAL::Surface_mesh` class. The 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 SM an instance of the `CGAL::Surface_mesh` class.
\param asm the surface mesh to draw.
*/
template<class SM>
void draw(const SM& asm);
#else // DOXYGEN_RUNNING
#include <CGAL/license/Surface_mesh.h>
#include <CGAL/Qt/Basic_viewer_qt.h>
#ifdef CGAL_USE_BASIC_VIEWER
#include <CGAL/Random.h>
namespace CGAL
{
// Default color functor; user can change it to have its own face color
struct DefaultColorFunctorSM
{
template<typename SM>
static CGAL::Color run(const SM&,
typename SM::Face_index fh)
{
if (fh==boost::graph_traits<SM>::null_face()) // use to get the mono color
return CGAL::Color(100, 125, 200); // R G B between 0-255
CGAL::Random random((unsigned int)fh);
return get_random_color(random);
}
};
template<class SM, class ColorFunctor>
class SimpleSurfaceMeshViewerQt : public Basic_viewer_qt
{
typedef Basic_viewer_qt Base;
typedef typename SM::Point Point;
typedef typename CGAL::Kernel_traits<Point>::Kernel Kernel;
typedef typename SM::Vertex_index vertex_descriptor;
typedef typename SM::Face_index face_descriptor;
typedef typename SM::Edge_index edge_descriptor;
typedef typename SM::Halfedge_index halfedge_descriptor;
public:
/// Construct the viewer.
/// @param amesh the surface mesh 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)
SimpleSurfaceMeshViewerQt(QWidget* parent,
const SM& amesh,
const char* title="Basic Surface_mesh Viewer",
bool anofaces=false,
const ColorFunctor& fcolor=ColorFunctor()) :
// First draw: no vertex; edges, faces; mono-color; inverse normal
Base(parent, title, false, true, true, true, false),
sm(amesh),
m_nofaces(anofaces),
m_fcolor(fcolor)
{
compute_elements();
}
protected:
void compute_face(face_descriptor fh)
{
CGAL::Color c=m_fcolor.run(sm, fh);
face_begin(c);
halfedge_descriptor hd=sm.halfedge(fh);
do
{
add_point_in_face(sm.point(sm.source(hd)), get_vertex_normal(hd));
hd=sm.next(hd);
}
while(hd!=sm.halfedge(fh));
face_end();
}
void compute_edge(edge_descriptor e)
{
add_segment(sm.point(sm.source(sm.halfedge(e))),
sm.point(sm.target(sm.halfedge(e))));
}
void compute_vertex(vertex_descriptor vh)
{ add_point(sm.point(vh)); }
void compute_elements()
{
clear();
if (!m_nofaces)
{
for (typename SM::Face_range::iterator f=sm.faces().begin();
f!=sm.faces().end(); ++f)
{
if (*f!=boost::graph_traits<SM>::null_face())
{ compute_face(*f); }
}
}
for (typename SM::Edge_range::iterator e=sm.edges().begin();
e!=sm.edges().end(); ++e)
{ compute_edge(*e); }
for (typename SM::Vertex_range::iterator v=sm.vertices().begin();
v!=sm.vertices().end(); ++v)
{ compute_vertex(*v); }
}
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:
typename Kernel::Vector_3 get_face_normal(halfedge_descriptor he)
{
typename Kernel::Vector_3 normal=CGAL::NULL_VECTOR;
halfedge_descriptor end=he;
unsigned int nb=0;
do
{
internal::newell_single_step_3(sm.point(sm.source(he)),
sm.point(sm.target(he)), normal);
++nb;
he=sm.next(he);
}
while (he!=end);
assert(nb>0);
return (typename Kernel::Construct_scaled_vector_3()(normal, 1.0/nb));
}
typename Kernel::Vector_3 get_vertex_normal(halfedge_descriptor he)
{
typename Kernel::Vector_3 normal=CGAL::NULL_VECTOR;
halfedge_descriptor end=he;
do
{
if (!sm.is_border(he))
{
typename Kernel::Vector_3 n=get_face_normal(he);
normal=typename Kernel::Construct_sum_of_vectors_3()(normal, n);
}
he=sm.next(sm.opposite(he));
}
while (he!=end);
if (!typename Kernel::Equal_3()(normal, CGAL::NULL_VECTOR))
{ normal=(typename Kernel::Construct_scaled_vector_3()
(normal, 1.0/CGAL::sqrt(normal.squared_length()))); }
return normal;
}
protected:
const SM& sm;
bool m_nofaces;
const ColorFunctor& m_fcolor;
};
template<class SM, class ColorFunctor>
void draw(const SM& amesh,
const char* title,
bool nofill,
const ColorFunctor& fcolor)
{
#if defined(CGAL_TEST_SUITE)
bool cgal_test_suite=true;
#else
bool cgal_test_suite=false;
#endif
if (!cgal_test_suite)
{
int argc=1;
const char* argv[2]={"surface_mesh_viewer","\0"};
QApplication app(argc,const_cast<char**>(argv));
SimpleSurfaceMeshViewerQt<SM, ColorFunctor> mainwindow(app.activeWindow(),
amesh,
title,
nofill,
fcolor);
mainwindow.show();
app.exec();
}
}
template<class SM>
void draw(const SM& amesh, const char* title, bool nofill)
{
DefaultColorFunctorSM c;
draw(amesh, title, nofill, c);
}
template<class SM>
void draw(const SM& amesh, const char* title)
{ draw(amesh, title, false); }
template<class SM>
void draw(const SM& amesh)
{ draw(amesh, "Basic Surface_mesh Viewer"); }
} // End namespace CGAL
#endif // CGAL_USE_BASIC_VIEWER
#endif // DOXYGEN_RUNNING
#endif // CGAL_DRAW_SURFACE_MESH_H

View File

@ -4,6 +4,7 @@ Cartesian_kernel
Circulator
Distance_2
Distance_3
GraphicsView
Hash_map
Installation
Interval_support

View File

@ -0,0 +1,15 @@
namespace CGAL {
/*!
\ingroup PkgDrawTriangulation2
Open a new window and draw `at2`, a model of the `TriangulationDataStructure_2` concept. The 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 T2 a model of the `TriangulationDataStructure_2` concept.
\param at2 the triangulation to draw.
*/
template<class T2>
void draw(const T2& at2);
} /* namespace CGAL */

View File

@ -16,6 +16,14 @@
/// \defgroup PkgTriangulation2Miscellaneous Miscellaneous
/// \ingroup PkgTriangulation2
/*! Draw.
\code
#include <CGAL/draw_triangulation_2.h>
\endcode
*/
/// \defgroup PkgDrawTriangulation2 Draw a Triangulation 2
/// \ingroup PkgTriangulation2
/*!
\addtogroup PkgTriangulation2
\todo check generated documentation
@ -104,5 +112,8 @@ are described in Chapter \ref PkgTDS2 "2D Triangulation Data Structure".
## Enum ##
- \link CGAL::Triangulation_2::Locate_type `CGAL::Triangulation_2<Traits,Tds>::Locate_type` \endlink
### Draw a Triangulation 2 ###
- `CGAL::draw<T2>`
*/

View File

@ -472,6 +472,19 @@ and inserted in the triangulation.
Finally points on the convex hull are written to <TT>cout</TT>.
\cgalExample{Triangulation_2/triangulation_prog1.cpp}
\subsection Triangulation2Draw Draw a 2D Triangulation
\anchor ssecDrawT2
A 2D triangulation can be visualized by calling the `CGAL::draw()` function as shown in the following example. This function opens a new window showing the given 2D triangulation. The function is blocking, that is the program continues as soon as the user closes the window.
\cgalExample{Triangulation_2/draw_triangulation_2.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_triangulation_2,draw_triangulation_2.png}
Result of the run of the draw_triangulation_2 program. A window shows the 2D triangulation and allows to navigate through the scene.
\cgalFigureEnd
\section Section_2D_Triangulations_Delaunay Delaunay Triangulations
\subsection Subsection_2D_Triangulations_Delaunay_Description Description

View File

@ -18,4 +18,5 @@
\example Triangulation_2/voronoi.cpp
\example Triangulation_2/copy_triangulation_2.cpp
\example Triangulation_2/polylines_triangulation.cpp
\example Triangulation_2/draw_triangulation_2.cpp
*/

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -4,9 +4,18 @@
project( Triangulation_2_Examples )
cmake_minimum_required(VERSION 2.8.10)
cmake_minimum_required(VERSION 3.1)
find_package(CGAL QUIET)
if(NOT POLICY CMP0070 AND POLICY CMP0053)
# Only set CMP0053 to OLD with CMake<3.10, otherwise there is a warning.
cmake_policy(SET CMP0053 OLD)
endif()
find_package(CGAL COMPONENTS Qt5)
if(CGAL_Qt5_FOUND)
add_definitions(-DCGAL_USE_BASIC_VIEWER -DQT_NO_KEYWORDS)
endif()
if ( CGAL_FOUND )
@ -22,6 +31,10 @@ if ( CGAL_FOUND )
create_single_source_cgal_program( "${cppfile}" )
endforeach()
if(CGAL_Qt5_FOUND)
target_link_libraries(draw_triangulation_2 PUBLIC CGAL::CGAL_Qt5)
endif()
else()
message(STATUS "This program requires the CGAL library, and will not be compiled.")

View File

@ -0,0 +1,21 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Triangulation_2.h>
#include <CGAL/draw_triangulation_2.h>
#include <fstream>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Triangulation_2<K> Triangulation;
typedef Triangulation::Point Point;
int main() {
std::ifstream in("data/triangulation_prog1.cin");
std::istream_iterator<Point> begin(in);
std::istream_iterator<Point> end;
Triangulation t;
t.insert(begin, end);
CGAL::draw(t);
return EXIT_SUCCESS;
}

View File

@ -24,5 +24,6 @@ int main()
std::cout << rt.number_of_vertices() << std::endl;
std::cout << "number of hidden vertices : " ;
std::cout << rt.number_of_hidden_vertices() << std::endl;
return 0;
}

View File

@ -0,0 +1,185 @@
// Copyright(c) 2018 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
// You can redistribute it and/or modify it under the terms of the GNU
// General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0+
//
// Author(s) : Guillaume Damiand <guillaume.damiand@liris.cnrs.fr>
#ifndef CGAL_DRAW_T2_H
#define CGAL_DRAW_T2_H
#include <CGAL/license/Triangulation_2.h>
#include <CGAL/Qt/Basic_viewer_qt.h>
#ifdef CGAL_USE_BASIC_VIEWER
#include <CGAL/Random.h>
namespace CGAL
{
// Default color functor; user can change it to have its own face color
struct DefaultColorFunctorT2
{
template<typename T2>
static CGAL::Color run(const T2&,
const typename T2::Finite_faces_iterator fh)
{
CGAL::Random random((unsigned int)(std::size_t)(&*fh));
return get_random_color(random);
}
};
// Viewer class for T2
template<class T2, class ColorFunctor>
class SimpleTriangulation2ViewerQt : public Basic_viewer_qt
{
typedef Basic_viewer_qt Base;
typedef typename T2::Vertex_handle Vertex_const_handle;
typedef typename T2::Finite_edges_iterator Edge_const_handle;
typedef typename T2::Finite_faces_iterator Facet_const_handle;
typedef typename T2::Point Point;
public:
/// Construct the viewer.
/// @param at2 the t2 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)
SimpleTriangulation2ViewerQt(QWidget* parent, const T2& at2,
const char* title="Basic T2 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),
t2(at2),
m_nofaces(anofaces),
m_fcolor(fcolor)
{
compute_elements();
}
protected:
void compute_face(Facet_const_handle fh)
{
CGAL::Color c=m_fcolor.run(t2, fh);
face_begin(c);
add_point_in_face(fh->vertex(0)->point());
add_point_in_face(fh->vertex(1)->point());
add_point_in_face(fh->vertex(2)->point());
face_end();
}
void compute_edge(Edge_const_handle eh)
{
add_segment(eh->first->vertex(eh->first->cw(eh->second))->point(),
eh->first->vertex(eh->first->ccw(eh->second))->point());
}
void compute_vertex(Vertex_const_handle vh)
{ add_point(vh->point()); }
void compute_elements()
{
clear();
if (!m_nofaces)
{
for (typename T2::Finite_faces_iterator it=t2.finite_faces_begin();
it!=t2.finite_faces_end(); ++it)
{ compute_face(it); }
}
for (typename T2::Finite_edges_iterator it=t2.finite_edges_begin();
it!=t2.finite_edges_end(); ++it)
{ compute_edge(it); }
for (typename T2::Finite_vertices_iterator it=t2.finite_vertices_begin();
it!=t2.finite_vertices_end(); ++it)
{ compute_vertex(it); }
}
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:
const T2& t2;
bool m_nofaces;
const ColorFunctor& m_fcolor;
};
template<class T2, class ColorFunctor>
void draw(const T2& at2,
const char* title,
bool nofill,
const ColorFunctor& fcolor)
{
#if defined(CGAL_TEST_SUITE)
bool cgal_test_suite=true;
#else
bool cgal_test_suite=false;
#endif
if (!cgal_test_suite)
{
int argc=1;
const char* argv[2]={"t2_viewer","\0"};
QApplication app(argc,const_cast<char**>(argv));
SimpleTriangulation2ViewerQt<T2, ColorFunctor> mainwindow(app.activeWindow(),
at2,
title,
nofill,
fcolor);
mainwindow.show();
app.exec();
}
}
template<class T2>
void draw(const T2& at2, const char* title, bool nofill)
{
DefaultColorFunctorT2 c;
draw(at2, title, nofill, c);
}
template<class T2>
void draw(const T2& at2, const char* title)
{ draw(at2, title, false); }
template<class T2>
void draw(const T2& at2)
{ draw(at2, "Basic T2 Viewer"); }
} // End namespace CGAL
#endif // CGAL_USE_BASIC_VIEWER
#endif // CGAL_DRAW_T2_H

View File

@ -7,6 +7,7 @@ Distance_2
Distance_3
Filtered_kernel
Geomview
GraphicsView
Hash_map
Homogeneous_kernel
Installation

View File

@ -0,0 +1,15 @@
namespace CGAL {
/*!
\ingroup PkgDrawTriangulation3
Open a new window and draw `at3`, a model of the `TriangulationDataStructure_3` concept. The 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 T3 a model of the `TriangulationDataStructure_3` concept.
\param at3 the triangulation to draw.
*/
template<class T3>
void draw(const T3& at3);
} /* namespace CGAL */

View File

@ -13,6 +13,13 @@
/// \defgroup PkgTriangulation3VertexCellClasses Vertex and Cell Classes
/// \ingroup PkgTriangulation3
/*! Draw.
\code
#include <CGAL/draw_triangulation_3.h>
\endcode
*/
/// \defgroup PkgDrawTriangulation3 Draw a Triangulation 3
/// \ingroup PkgTriangulation3
/*!
\addtogroup PkgTriangulation3
@ -111,6 +118,8 @@ is opposite to the vertex with the same index. See
- `CGAL::Triangulation_3::Locate_type`
### Draw a Triangulation 3 ###
- `CGAL::draw<T3>`
*/

View File

@ -535,6 +535,20 @@ removal of the first 100,000 vertices.
\cgalExample{Triangulation_3/parallel_insertion_and_removal_in_regular_3.cpp}
\subsection Triangulation3Draw Draw a 3D Triangulation
\anchor ssecDrawT3
A 3D triangulation can be visualized by calling the `CGAL::draw()` function as shown in the following example. This function opens a new window showing the given 3D triangulation. The function is blocking, that is the program continues as soon as the user closes the window.
\cgalExample{Triangulation_3/draw_triangulation_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_triangulation_3,draw_triangulation_3.png}
Result of the run of the draw_triangulation_3 program. A window shows the 3D triangulation and allows to navigate through the 3D scene.
\cgalFigureEnd
\section Triangulation3seccomplexity Complexity and Performance
In 3D, the worst case complexity of a triangulation is quadratic in the number

View File

@ -13,4 +13,5 @@
\example Triangulation_3/copy_triangulation_3.cpp
\example Triangulation_3/parallel_insertion_in_delaunay_3.cpp
\example Triangulation_3/parallel_insertion_and_removal_in_regular_3.cpp
\example Triangulation_3/draw_triangulation_3.cpp
*/

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View File

@ -2,8 +2,16 @@ project( Triangulation_3_Examples )
cmake_minimum_required(VERSION 2.8.12)
if(NOT POLICY CMP0070 AND POLICY CMP0053)
# Only set CMP0053 to OLD with CMake<3.10, otherwise there is a warning.
cmake_policy(SET CMP0053 OLD)
endif()
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 )
create_single_source_cgal_program( "adding_handles_3.cpp" )
@ -20,19 +28,9 @@ if ( CGAL_FOUND )
create_single_source_cgal_program( "simple_triangulation_3.cpp" )
create_single_source_cgal_program( "simplex.cpp" )
find_package( TBB QUIET )
if( TBB_FOUND )
include( CGAL_target_use_TBB )
create_single_source_cgal_program( "parallel_insertion_and_removal_in_regular_3.cpp" )
create_single_source_cgal_program( "parallel_insertion_in_delaunay_3.cpp" )
create_single_source_cgal_program( "sequential_parallel.cpp" )
CGAL_target_use_TBB( parallel_insertion_and_removal_in_regular_3 )
CGAL_target_use_TBB( parallel_insertion_in_delaunay_3 )
CGAL_target_use_TBB( sequential_parallel )
else()
message(STATUS "NOTICE: a few examples require TBB and will not be compiled.")
create_single_source_cgal_program("draw_triangulation_3.cpp")
if(CGAL_Qt5_FOUND)
target_link_libraries(draw_triangulation_3 PUBLIC CGAL::CGAL_Qt5)
endif()
else()

View File

@ -0,0 +1,21 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Delaunay_triangulation_3.h>
#include <CGAL/point_generators_3.h>
#include <CGAL/draw_triangulation_3.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Delaunay_triangulation_3<K> DT3;
typedef CGAL::Creator_uniform_3<double,K::Point_3> Creator;
int main()
{
std::vector<K::Point_3> points;
CGAL::Random_points_in_sphere_3<K::Point_3,Creator> g(1.0);
CGAL::cpp11::copy_n(g, 50, std::back_inserter(points));
DT3 dt3(points.begin(), points.end());
CGAL::draw(dt3);
return EXIT_SUCCESS;
}

View File

@ -0,0 +1,192 @@
// Copyright (c) 2018 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
// You can redistribute it and/or modify it under the terms of the GNU
// General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0+
//
// Author(s) : Guillaume Damiand <guillaume.damiand@liris.cnrs.fr>
#ifndef CGAL_DRAW_T3_H
#define CGAL_DRAW_T3_H
#include <CGAL/license/Triangulation_3.h>
#include <CGAL/Qt/Basic_viewer_qt.h>
#ifdef CGAL_USE_BASIC_VIEWER
#include <CGAL/Random.h>
namespace CGAL
{
// Default color functor; user can change it to have its own face color
struct DefaultColorFunctorT3
{
template<typename T3>
static CGAL::Color run(const T3&,
const typename T3::Finite_facets_iterator* fh)
{
if (fh==NULL) // 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)->first))+
(std::size_t)((*fh)->second)));
return get_random_color(random);
}
};
// Viewer class for T3
template<class T3, class ColorFunctor>
class SimpleTriangulation3ViewerQt : public Basic_viewer_qt
{
typedef Basic_viewer_qt Base;
typedef typename T3::Vertex_handle Vertex_const_handle;
typedef typename T3::Finite_edges_iterator Edge_const_handle;
typedef typename T3::Finite_facets_iterator Facet_const_handle;
typedef typename T3::Cell_handle Cell_handle;
typedef typename T3::Point Point;
public:
/// Construct the viewer.
/// @param at3 the t3 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)
SimpleTriangulation3ViewerQt(QWidget* parent,
const T3& at3,
const char* title="Basic T3 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),
t3(at3),
m_nofaces(anofaces),
m_fcolor(fcolor)
{
compute_elements();
}
protected:
void compute_face(Facet_const_handle fh)
{
CGAL::Color c=m_fcolor.run(t3, &fh);
face_begin(c);
add_point_in_face(fh->first->vertex((fh->second+1)%4)->point());
add_point_in_face(fh->first->vertex((fh->second+2)%4)->point());
add_point_in_face(fh->first->vertex((fh->second+3)%4)->point());
face_end();
}
void compute_edge(Edge_const_handle eh)
{
add_segment(eh->first->vertex(eh->second)->point(),
eh->first->vertex(eh->third)->point());
}
void compute_vertex(Vertex_const_handle vh)
{ add_point(vh->point()); }
void compute_elements()
{
clear();
if (!m_nofaces)
{
for (typename T3::Finite_facets_iterator it=t3.finite_facets_begin();
it!=t3.finite_facets_end(); ++it)
{ compute_face(it); }
}
for (typename T3::Finite_edges_iterator it=t3.finite_edges_begin();
it!=t3.finite_edges_end(); ++it)
{ compute_edge(it); }
for (typename T3::Finite_vertices_iterator it=t3.finite_vertices_begin();
it!=t3.finite_vertices_end(); ++it)
{ compute_vertex(it); }
}
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:
const T3& t3;
bool m_nofaces;
const ColorFunctor& m_fcolor;
};
template<class T3, class ColorFunctor>
void draw(const T3& at3,
const char* title,
bool nofill,
const ColorFunctor& fcolor)
{
#if defined(CGAL_TEST_SUITE)
bool cgal_test_suite=true;
#else
bool cgal_test_suite=false;
#endif
if (!cgal_test_suite)
{
int argc=1;
const char* argv[2]={"t3_viewer","\0"};
QApplication app(argc,const_cast<char**>(argv));
SimpleTriangulation3ViewerQt<T3, ColorFunctor> mainwindow(app.activeWindow(),
at3,
title,
nofill,
fcolor);
mainwindow.show();
app.exec();
}
}
template<class T3>
void draw(const T3& at3, const char* title, bool nofill)
{
DefaultColorFunctorT3 c;
draw(at3, title, nofill, c);
}
template<class T3>
void draw(const T3& at3, const char* title)
{ draw(at3, title, false); }
template<class T3>
void draw(const T3& at3)
{ draw(at3, "Basic T3 Viewer"); }
} // End namespace CGAL
#endif // CGAL_USE_BASIC_VIEWER
#endif // CGAL_DRAW_T3_H

View File

@ -7,6 +7,7 @@ Distance_2
Distance_3
Filtered_kernel
Geomview
GraphicsView
Hash_map
Homogeneous_kernel
Installation