mirror of https://github.com/CGAL/cgal
Merge pull request #2835 from gdamiand/CGAL-basic_viewers-gdamiand
Add basic viewers
This commit is contained in:
commit
08043e442c
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) )
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
@ -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ébastien Loriot and Laurent Rineau. Monique Teillaud and Bernd Gärtner contributed to the manual.
|
||||
|
|
|
|||
|
|
@ -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>`
|
||||
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -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 |
|
|
@ -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)
|
||||
|
|
@ -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()
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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>();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -8,6 +8,7 @@ Distance_2
|
|||
Distance_3
|
||||
Filtered_kernel
|
||||
Generalized_map
|
||||
GraphicsView
|
||||
HalfedgeDS
|
||||
Hash_map
|
||||
Homogeneous_kernel
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
@ -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>`
|
||||
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 |
|
|
@ -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.")
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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."
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -2,6 +2,7 @@ Algebraic_foundations
|
|||
BGL
|
||||
Circulator
|
||||
Distance_2
|
||||
GraphicsView
|
||||
HalfedgeDS
|
||||
Hash_map
|
||||
Installation
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>`
|
||||
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 |
|
|
@ -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.")
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -36,5 +36,4 @@ int main(int argc, char* argv[])
|
|||
|
||||
|
||||
std::cout << sm1 << std::endl;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -4,6 +4,7 @@ Cartesian_kernel
|
|||
Circulator
|
||||
Distance_2
|
||||
Distance_3
|
||||
GraphicsView
|
||||
Hash_map
|
||||
Installation
|
||||
Interval_support
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
@ -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>`
|
||||
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 |
|
|
@ -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.")
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -7,6 +7,7 @@ Distance_2
|
|||
Distance_3
|
||||
Filtered_kernel
|
||||
Geomview
|
||||
GraphicsView
|
||||
Hash_map
|
||||
Homogeneous_kernel
|
||||
Installation
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
@ -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>`
|
||||
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 |
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -7,6 +7,7 @@ Distance_2
|
|||
Distance_3
|
||||
Filtered_kernel
|
||||
Geomview
|
||||
GraphicsView
|
||||
Hash_map
|
||||
Homogeneous_kernel
|
||||
Installation
|
||||
|
|
|
|||
Loading…
Reference in New Issue