mirror of https://github.com/CGAL/cgal
Merge branch 'BGL-SurfaceMesh2SurfaceMesh-GF' into Polygon_mesh_processing-local_remeshing-GF
This commit is contained in:
commit
54ca52b538
|
|
@ -148,7 +148,7 @@ namespace CGAL {
|
|||
if(first_vertex != S.triangulation_3().finite_vertices_end()) {
|
||||
pos = first_vertex;
|
||||
pos->set_post_mark(mark);
|
||||
assert(pos->is_on_border());
|
||||
CGAL_assertion(pos->is_on_border());
|
||||
|
||||
} else {
|
||||
pos = NULL;
|
||||
|
|
@ -469,7 +469,7 @@ namespace CGAL {
|
|||
inline void set_interior_edge(Vertex_handle w, Vertex_handle v)
|
||||
{
|
||||
if(w->m_ie_last == ie_sentinel){ // empty set
|
||||
assert(w->m_ie_first == w->m_ie_last);
|
||||
CGAL_assertion(w->m_ie_first == w->m_ie_last);
|
||||
w->m_ie_last = interior_edges.insert(w->m_ie_last, v);
|
||||
w->m_ie_first = w->m_ie_last;
|
||||
} else {
|
||||
|
|
@ -477,7 +477,7 @@ namespace CGAL {
|
|||
e++;
|
||||
#ifdef DEBUG
|
||||
typename std::list<Vertex_handle>::iterator r = std::find(w->m_ie_first, e, v);
|
||||
assert(r == e);
|
||||
CGAL_assertion(r == e);
|
||||
#endif
|
||||
w->m_ie_last = interior_edges.insert(e, v);
|
||||
}
|
||||
|
|
@ -487,7 +487,7 @@ namespace CGAL {
|
|||
inline void remove_interior_edge(Vertex_handle w, Vertex_handle v)
|
||||
{
|
||||
if(w->m_ie_first == ie_sentinel){
|
||||
assert(w->m_ie_last == w->m_ie_first);
|
||||
CGAL_assertion(w->m_ie_last == w->m_ie_first);
|
||||
} else if(w->m_ie_first == w->m_ie_last){ // there is only one element
|
||||
if(*(w->m_ie_first) == v){
|
||||
interior_edges.erase(w->m_ie_first);
|
||||
|
|
@ -516,7 +516,7 @@ namespace CGAL {
|
|||
inline void set_incidence_request(Vertex_handle w, const Incidence_request_elt& ir)
|
||||
{
|
||||
if(w->m_ir_last == sentinel ){
|
||||
assert(w->m_ir_first == w->m_ir_last);
|
||||
CGAL_assertion(w->m_ir_first == w->m_ir_last);
|
||||
w->m_ir_last = incidence_requests.insert(w->m_ir_last, ir);
|
||||
w->m_ir_first = w->m_ir_last;
|
||||
} else {
|
||||
|
|
@ -529,7 +529,7 @@ namespace CGAL {
|
|||
inline bool is_incidence_requested(Vertex_handle w) const
|
||||
{
|
||||
if(w->m_ir_last == sentinel ){
|
||||
assert(w->m_ir_first == sentinel );
|
||||
CGAL_assertion(w->m_ir_first == sentinel );
|
||||
}
|
||||
return (w->m_ir_last != sentinel );
|
||||
}
|
||||
|
|
@ -542,7 +542,7 @@ namespace CGAL {
|
|||
inline Incidence_request_iterator incidence_request_end(Vertex_handle w)
|
||||
{
|
||||
if(w->m_ir_last != sentinel ){
|
||||
assert(w->m_ir_first != sentinel );
|
||||
CGAL_assertion(w->m_ir_first != sentinel );
|
||||
Incidence_request_iterator it(w->m_ir_last);
|
||||
it++;
|
||||
return it;
|
||||
|
|
@ -553,7 +553,7 @@ namespace CGAL {
|
|||
inline void erase_incidence_request(Vertex_handle w)
|
||||
{
|
||||
if(w->m_ir_last != sentinel ){
|
||||
assert(w->m_ir_first != sentinel );
|
||||
CGAL_assertion(w->m_ir_first != sentinel );
|
||||
w->m_ir_last++;
|
||||
incidence_requests.erase(w->m_ir_first, w->m_ir_last);
|
||||
w->m_ir_first = sentinel ;
|
||||
|
|
@ -570,7 +570,7 @@ namespace CGAL {
|
|||
}
|
||||
|
||||
if(w->m_ir_first != sentinel ){
|
||||
assert(w->m_ir_last != sentinel );
|
||||
CGAL_assertion(w->m_ir_last != sentinel );
|
||||
typename std::list< Incidence_request_elt >::iterator b(w->m_ir_first), e(w->m_ir_last);
|
||||
e++;
|
||||
incidence_requests.erase(b, e);
|
||||
|
|
@ -627,14 +627,14 @@ namespace CGAL {
|
|||
w->delete_border();
|
||||
}
|
||||
if(w->m_ir_first != sentinel ){
|
||||
assert(w->m_ir_last != sentinel );
|
||||
CGAL_assertion(w->m_ir_last != sentinel );
|
||||
typename std::list< Incidence_request_elt >::iterator b(w->m_ir_first), e(w->m_ir_last);
|
||||
e++;
|
||||
incidence_requests.erase(b, e);
|
||||
}
|
||||
|
||||
if(w->m_ie_first != ie_sentinel){
|
||||
assert(w->m_ie_last != ie_sentinel);
|
||||
CGAL_assertion(w->m_ie_last != ie_sentinel);
|
||||
typename std::list<Vertex_handle>::iterator b(w->m_ie_first), e(w->m_ie_last);
|
||||
e++;
|
||||
interior_edges.erase(b, e);
|
||||
|
|
@ -746,7 +746,7 @@ namespace CGAL {
|
|||
void run(double radius_ratio_bound=5, double beta= 0.52)
|
||||
{
|
||||
K = radius_ratio_bound;
|
||||
COS_BETA = acos(beta);
|
||||
COS_BETA = cos(beta);
|
||||
if(T.dimension() < 3){
|
||||
return;
|
||||
}
|
||||
|
|
@ -2186,7 +2186,7 @@ namespace CGAL {
|
|||
{
|
||||
_facet_number--;
|
||||
|
||||
assert(c->is_selected_facet(index));
|
||||
CGAL_assertion(c->is_selected_facet(index));
|
||||
unselect_facet(c, index);
|
||||
|
||||
Facet f32 =
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ namespace CGAL {
|
|||
tds.set_adjacency(fn, 2, inf_edge_map);
|
||||
edge_map.erase(edge_map.begin());
|
||||
}
|
||||
CGAL_triangulation_assertion(inf_edge_map.empty());
|
||||
CGAL_assertion(inf_edge_map.empty());
|
||||
}
|
||||
tds.reorient_faces();
|
||||
return vinf;
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ namespace CGAL {
|
|||
tds.set_adjacency(fn, 2, inf_edge_map);
|
||||
edge_map.erase(edge_map.begin());
|
||||
}
|
||||
CGAL_triangulation_assertion(inf_edge_map.empty());
|
||||
CGAL_assertion(inf_edge_map.empty());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
|
||||
|
||||
#include <CGAL/basic.h>
|
||||
#include <CGAL/assertions.h>
|
||||
#include <CGAL/Cache.h>
|
||||
#include <CGAL/function_objects.h>
|
||||
#include <CGAL/Handle_with_policy.h>
|
||||
|
|
@ -904,7 +905,7 @@ private:
|
|||
break;
|
||||
}
|
||||
default:{
|
||||
assert(false); // !!! Never reached
|
||||
CGAL_assertion(false); // !!! Never reached
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
#ifndef CGAL_INTERNAL_LAZY_ALPHA_NT_2_H
|
||||
#define CGAL_INTERNAL_LAZY_ALPHA_NT_2_H
|
||||
|
||||
#include <CGAL/assertions.h>
|
||||
#include <CGAL/Weighted_alpha_shape_euclidean_traits_2.h>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/mpl/has_xxx.hpp>
|
||||
|
|
@ -139,7 +139,7 @@ public:
|
|||
exact_ = Exact_squared_radius()( to_exact(*data()[0]),to_exact(*data()[1]),to_exact(*data()[2]) );
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
CGAL_assertion(false);
|
||||
}
|
||||
updated=true;
|
||||
}
|
||||
|
|
@ -156,7 +156,7 @@ public:
|
|||
approx_ = Approx_squared_radius()( to_approx(*data()[0]),to_approx(*data()[1]),to_approx(*data()[2]) );
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
CGAL_assertion(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#ifndef CGAL_INTERNAL_LAZY_ALPHA_NT_3_H
|
||||
#define CGAL_INTERNAL_LAZY_ALPHA_NT_3_H
|
||||
|
||||
#include <CGAL/assertions.h>
|
||||
#include <CGAL/Regular_triangulation_euclidean_traits_3.h>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
|
|
@ -140,7 +141,7 @@ public:
|
|||
exact_ = Exact_squared_radius()( to_exact(*data()[0]),to_exact(*data()[1]),to_exact(*data()[2]),to_exact(*data()[3]) );
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
CGAL_assertion(false);
|
||||
}
|
||||
updated=true;
|
||||
}
|
||||
|
|
@ -160,7 +161,7 @@ public:
|
|||
approx_ = Approx_squared_radius()( to_approx(*data()[0]),to_approx(*data()[1]),to_approx(*data()[2]),to_approx(*data()[3]) );
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
CGAL_assertion(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -553,13 +553,13 @@ public:
|
|||
Comparison_result operator() (const Vertical_segment & cv1,
|
||||
const Non_vertical_x_curve_2 & cv2) const
|
||||
{
|
||||
assert(false);
|
||||
CGAL_assertion(false);
|
||||
return CGAL::SMALLER;
|
||||
}
|
||||
Comparison_result operator() (const Non_vertical_x_curve_2& cv1,
|
||||
const Vertical_segment & cv2) const
|
||||
{
|
||||
assert(false);
|
||||
CGAL_assertion(false);
|
||||
return CGAL::LARGER;
|
||||
}
|
||||
Comparison_result operator() (const Vertical_segment & cv1,
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include <CGAL/Arr_rat_arc/Base_rational_arc_ds_1.h>
|
||||
#include <CGAL/Arr_rat_arc/Rational_function.h>
|
||||
#include <CGAL/Handle_with_policy.h>
|
||||
#include <CGAL/assertions.h>
|
||||
|
||||
namespace CGAL {
|
||||
namespace Arr_rational_arc {
|
||||
|
|
@ -69,7 +70,7 @@ public:
|
|||
#if 1
|
||||
solve_1(_resultant,std::back_inserter(rm_vec));
|
||||
#else
|
||||
assert(false);
|
||||
CGAL_assertion(false);
|
||||
// don't use this code yet since g and resultant/g may still have a
|
||||
// common root
|
||||
if( CGAL::internal::may_have_common_factor(_f.denom(),_g.denom())){
|
||||
|
|
|
|||
|
|
@ -20,9 +20,11 @@
|
|||
|
||||
|
||||
|
||||
#ifndef SINGLETON_H_
|
||||
#ifndef CGAL_SINGLETON_H_
|
||||
#define SINGLETON_H_
|
||||
|
||||
#include <CGAL/assertions.h>
|
||||
|
||||
namespace CGAL {
|
||||
namespace Arr_rational_arc {
|
||||
template <class T>
|
||||
|
|
@ -33,7 +35,7 @@ public:
|
|||
{
|
||||
if(!m_pInstance)
|
||||
m_pInstance = new T;
|
||||
assert(m_pInstance !=NULL);
|
||||
CGAL_assertion(m_pInstance !=NULL);
|
||||
return m_pInstance;
|
||||
}
|
||||
|
||||
|
|
@ -53,4 +55,4 @@ template <class T> T* Singleton<T>::m_pInstance=NULL;
|
|||
|
||||
} // namespace Arr_rational_arc
|
||||
} //namespace CGAL {
|
||||
#endif // SINGLETON_H_
|
||||
#endif // CGAL_SINGLETON_H_
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#ifndef CGAL_ARR_RATIONAL_ARC_TRAITS_D_1_H
|
||||
#define CGAL_ARR_RATIONAL_ARC_TRAITS_D_1_H
|
||||
|
||||
#include <CGAL/assertions.h>
|
||||
#include <CGAL/tags.h>
|
||||
#include <CGAL/Fraction_traits.h>
|
||||
#include <CGAL/Arr_tags.h>
|
||||
|
|
@ -1295,7 +1296,7 @@ public:
|
|||
Approximate_number_type operator()(const Point_2& p, int i){
|
||||
if(i==0) return approx_x(p);
|
||||
if(i==1) return approx_y(p);
|
||||
assert(false);
|
||||
CGAL_assertion(false);
|
||||
return Approximate_number_type(0);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#include <CGAL/Arr_topology_traits/Arr_unb_planar_batched_pl_helper.h>
|
||||
#include <CGAL/Arr_topology_traits/Arr_unb_planar_vert_decomp_helper.h>
|
||||
#include <CGAL/Arr_topology_traits/Arr_inc_insertion_zone_visitor.h>
|
||||
#include <CGAL/assertions.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
|
|
@ -507,7 +508,7 @@ public:
|
|||
*/
|
||||
const Face* reference_face() const
|
||||
{
|
||||
assert(v_tr->halfedge()->direction() == ARR_LEFT_TO_RIGHT);
|
||||
CGAL_assertion(v_tr->halfedge()->direction() == ARR_LEFT_TO_RIGHT);
|
||||
return v_tr->halfedge()->outer_ccb()->face();
|
||||
}
|
||||
|
||||
|
|
@ -519,7 +520,7 @@ public:
|
|||
*/
|
||||
Face* reference_face()
|
||||
{
|
||||
assert(v_tr->halfedge()->direction() == ARR_LEFT_TO_RIGHT);
|
||||
CGAL_assertion(v_tr->halfedge()->direction() == ARR_LEFT_TO_RIGHT);
|
||||
return v_tr->halfedge()->outer_ccb()->face();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -131,12 +131,14 @@ user might encounter.
|
|||
- `CGAL::is_bivalent_mesh()`
|
||||
- `CGAL::is_trivalent()`
|
||||
- `CGAL::is_trivalent_mesh()`
|
||||
- `CGAL::is_isolated_triangle()`
|
||||
- `CGAL::is_closed()`
|
||||
|
||||
- `CGAL::is_triangle()`
|
||||
- `CGAL::is_triangle_mesh()`
|
||||
- `CGAL::is_quad()`
|
||||
- `CGAL::is_quad_mesh()`
|
||||
- `CGAL::is_isolated_quad()`
|
||||
|
||||
- `CGAL::is_tetrahedron()`
|
||||
- `CGAL::is_hexahedron()`
|
||||
|
|
@ -150,10 +152,16 @@ user might encounter.
|
|||
- `CGAL::Halfedge_around_target_iterator`
|
||||
- `CGAL::Halfedge_around_face_iterator`
|
||||
- `CGAL::Vertex_around_target_iterator`
|
||||
- `CGAL::Vertex_around_face_iterator`
|
||||
- `CGAL::Face_around_face_iterator`
|
||||
- `CGAL::Face_around_target_iterator`
|
||||
- `CGAL::halfedges_around_source`
|
||||
- `CGAL::halfedges_around_target`
|
||||
- `CGAL::halfedges_around_face`
|
||||
- `CGAL::halfedges_around_source()`
|
||||
- `CGAL::halfedges_around_target()`
|
||||
- `CGAL::halfedges_around_face()`
|
||||
- `CGAL::faces_around_face()`
|
||||
- `CGAL::faces_around_target()`
|
||||
- `CGAL::vertices_around_face()`
|
||||
- `CGAL::vertices_around_target()`
|
||||
|
||||
## Circulators ##
|
||||
- `CGAL::Halfedge_around_source_circulator`
|
||||
|
|
@ -161,26 +169,29 @@ user might encounter.
|
|||
- `CGAL::Halfedge_around_face_circulator`
|
||||
- `CGAL::Vertex_around_target_circulator`
|
||||
- `CGAL::Face_around_target_circulator`
|
||||
- `CGAL::Face_around_face_circulator`
|
||||
|
||||
## Euler Operations ##
|
||||
|
||||
- `CGAL::Euler::join_vertex()`
|
||||
- `CGAL::Euler::split_vertex()`
|
||||
- `CGAL::Euler::split_edge()`
|
||||
- `CGAL::Euler::join_face()`
|
||||
- `CGAL::Euler::split_face()`
|
||||
- `CGAL::Euler::join_loop()`
|
||||
- `CGAL::Euler::split_loop()`
|
||||
- `CGAL::Euler::remove_face()`
|
||||
- `CGAL::Euler::make_hole()`
|
||||
- `CGAL::Euler::fill_hole()`
|
||||
- `CGAL::Euler::add_center_vertex()`
|
||||
- `CGAL::Euler::add_edge()`
|
||||
- `CGAL::Euler::add_face()`
|
||||
- `CGAL::Euler::add_face_to_border()`
|
||||
- `CGAL::Euler::add_vertex_and_face_to_border()`
|
||||
- `CGAL::Euler::collapse_edge()`
|
||||
- `CGAL::Euler::does_satisfy_link_condition()`
|
||||
- `CGAL::Euler::fill_hole()`
|
||||
- `CGAL::Euler::flip_edge()`
|
||||
- `CGAL::Euler::join_face()`
|
||||
- `CGAL::Euler::join_loop()`
|
||||
- `CGAL::Euler::join_vertex()`
|
||||
- `CGAL::Euler::make_hole()`
|
||||
- `CGAL::Euler::remove_center_vertex()`
|
||||
- `CGAL::Euler::add_vertex_and_face_to_border()`
|
||||
- `CGAL::Euler::add_face_to_border()`
|
||||
- `CGAL::Euler::collapse_edge()`
|
||||
- `CGAL::Euler::does_satisfy_link_condition()`
|
||||
|
||||
- `CGAL::Euler::remove_face()`
|
||||
- `CGAL::Euler::split_edge()`
|
||||
- `CGAL::Euler::split_face()`
|
||||
- `CGAL::Euler::split_loop()`
|
||||
- `CGAL::Euler::split_vertex()`
|
||||
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,57 @@
|
|||
# Created by the script cgal_create_CMakeLists
|
||||
# This is the CMake script for compiling a set of CGAL applications.
|
||||
|
||||
project( BGL_OpenMesh )
|
||||
|
||||
|
||||
cmake_minimum_required(VERSION 2.8.11)
|
||||
|
||||
# CGAL and its components
|
||||
find_package( CGAL QUIET COMPONENTS )
|
||||
|
||||
if ( NOT CGAL_FOUND )
|
||||
|
||||
message(STATUS "This project requires the CGAL library, and will not be compiled.")
|
||||
return()
|
||||
|
||||
endif()
|
||||
|
||||
# include helper file
|
||||
include( ${CGAL_USE_FILE} )
|
||||
|
||||
|
||||
# Boost and its components
|
||||
find_package( Boost REQUIRED )
|
||||
|
||||
if ( NOT Boost_FOUND )
|
||||
|
||||
message(STATUS "This project requires the Boost library, and will not be compiled.")
|
||||
|
||||
return()
|
||||
|
||||
endif()
|
||||
|
||||
find_package( OpenMesh QUIET )
|
||||
|
||||
if ( OpenMesh_FOUND )
|
||||
include( UseOpenMesh )
|
||||
else()
|
||||
message(STATUS "Examples that use OpenMesh will not be compiled.")
|
||||
endif()
|
||||
|
||||
# include for local directory
|
||||
|
||||
# include for local package
|
||||
include_directories( BEFORE ../../include )
|
||||
|
||||
|
||||
# Creating entries for all C++ files with "main" routine
|
||||
# ##########################################################
|
||||
|
||||
include( CGAL_CreateSingleSourceCGALProgram )
|
||||
|
||||
if(OpenMesh_FOUND)
|
||||
create_single_source_cgal_program( "TriMesh.cpp" )
|
||||
target_link_libraries( TriMesh ${OPENMESH_LIBRARIES} )
|
||||
endif()
|
||||
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
|
||||
#include <OpenMesh/Core/IO/MeshIO.hh>
|
||||
#include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
|
||||
|
||||
#include <CGAL/boost/graph/graph_traits_TriMesh_ArrayKernelT.h>
|
||||
#include <CGAL/boost/graph/iterator.h>
|
||||
#include <CGAL/boost/graph/Euler_operations.h>
|
||||
|
||||
#include <CGAL/mesh_segmentation.h>
|
||||
|
||||
#include <CGAL/property_map.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
|
||||
|
||||
typedef OpenMesh::TriMesh_ArrayKernelT</* MyTraits*/> Mesh;
|
||||
|
||||
typedef boost::graph_traits<Mesh>::vertex_descriptor vertex_descriptor;
|
||||
typedef boost::graph_traits<Mesh>::face_descriptor face_descriptor;
|
||||
typedef boost::graph_traits<Mesh>::halfedge_descriptor halfedge_descriptor;
|
||||
|
||||
|
||||
int main(int argc, char** argv )
|
||||
{
|
||||
Mesh mesh;
|
||||
|
||||
std::vector<vertex_descriptor> V;
|
||||
V.push_back(add_vertex(mesh));
|
||||
V.push_back(add_vertex(mesh));
|
||||
V.push_back(add_vertex(mesh));
|
||||
add_face(V.begin(), V.end(), mesh);
|
||||
|
||||
// OpenMesh::IO::read_mesh(mesh, (argc>1)?argv[1]:"in.off");
|
||||
|
||||
BOOST_FOREACH(vertex_descriptor vd, vertices(mesh)){
|
||||
BOOST_FOREACH(halfedge_descriptor hd, CGAL::halfedges_around_target(vd,mesh)){
|
||||
if(! CGAL::is_border(edge(hd,mesh),mesh)){
|
||||
CGAL::Euler::flip_edge(hd,mesh);
|
||||
OpenMesh::IO::write_mesh(mesh, (argc>2)?argv[2]:"out.off");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
# Created by the script cgal_create_CMakeLists
|
||||
# This is the CMake script for compiling a set of CGAL applications.
|
||||
|
||||
project( BGL_polyhedron_3 )
|
||||
|
||||
|
||||
cmake_minimum_required(VERSION 2.8.11)
|
||||
|
||||
# CGAL and its components
|
||||
find_package( CGAL QUIET COMPONENTS )
|
||||
|
||||
if ( NOT CGAL_FOUND )
|
||||
|
||||
message(STATUS "This project requires the CGAL library, and will not be compiled.")
|
||||
return()
|
||||
|
||||
endif()
|
||||
|
||||
# include helper file
|
||||
include( ${CGAL_USE_FILE} )
|
||||
|
||||
|
||||
# Boost and its components
|
||||
find_package( Boost REQUIRED )
|
||||
|
||||
if ( NOT Boost_FOUND )
|
||||
|
||||
message(STATUS "This project requires the Boost library, and will not be compiled.")
|
||||
|
||||
return()
|
||||
|
||||
endif()
|
||||
|
||||
find_package( OpenMesh QUIET )
|
||||
|
||||
if ( OpenMesh_FOUND )
|
||||
include( UseOpenMesh )
|
||||
else()
|
||||
message(STATUS "Examples that use OpenMesh will not be compiled.")
|
||||
endif()
|
||||
|
||||
# include for local directory
|
||||
|
||||
# include for local package
|
||||
include_directories( BEFORE ../../include )
|
||||
|
||||
|
||||
# Creating entries for all C++ files with "main" routine
|
||||
# ##########################################################
|
||||
|
||||
include( CGAL_CreateSingleSourceCGALProgram )
|
||||
|
||||
create_single_source_cgal_program( "distance.cpp" )
|
||||
|
||||
create_single_source_cgal_program( "incident_vertices.cpp" )
|
||||
|
||||
create_single_source_cgal_program( "kruskal.cpp" )
|
||||
|
||||
create_single_source_cgal_program( "kruskal_with_stored_id.cpp" )
|
||||
|
||||
create_single_source_cgal_program( "normals.cpp" )
|
||||
|
||||
create_single_source_cgal_program( "range.cpp" )
|
||||
|
||||
create_single_source_cgal_program( "transform_iterator.cpp" )
|
||||
|
||||
|
||||
|
||||
if(OpenMesh_FOUND)
|
||||
create_single_source_cgal_program( "polyhedron_2_OpenMesh.cpp" )
|
||||
target_link_libraries( polyhedron_2_OpenMesh ${OPENMESH_LIBRARIES} )
|
||||
endif()
|
||||
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
|
||||
#include <CGAL/Polyhedron_3.h>
|
||||
#include <CGAL/IO/Polyhedron_iostream.h>
|
||||
#include <CGAL/boost/graph/graph_traits_Polyhedron_3.h>
|
||||
|
||||
#include <OpenMesh/Core/IO/MeshIO.hh>
|
||||
|
||||
#if 1
|
||||
#include <OpenMesh/Core/Mesh/PolyMesh_ArrayKernelT.hh>
|
||||
#include <CGAL/boost/graph/graph_traits_PolyMesh_ArrayKernelT.h>
|
||||
#else
|
||||
#include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
|
||||
#include <CGAL/boost/graph/graph_traits_TriMesh_ArrayKernelT.h>
|
||||
#endif
|
||||
|
||||
#include <CGAL/boost/graph/convert_surface_mesh.h>
|
||||
|
||||
#include <boost/unordered_map.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
|
||||
typedef Kernel::Vector_3 Vector;
|
||||
typedef Kernel::Point_3 Point;
|
||||
typedef CGAL::Polyhedron_3<Kernel> Source;
|
||||
|
||||
#if 1
|
||||
typedef OpenMesh::PolyMesh_ArrayKernelT</* MyTraits*/> Target;
|
||||
#else
|
||||
typedef OpenMesh::TriMesh_ArrayKernelT</* MyTraits*/> Target;
|
||||
#endif
|
||||
typedef boost::graph_traits<Source>::vertex_descriptor sm_vertex_descriptor;
|
||||
typedef boost::graph_traits<Target>::vertex_descriptor tm_vertex_descriptor;
|
||||
|
||||
typedef boost::graph_traits<Source>::halfedge_descriptor sm_halfedge_descriptor;
|
||||
typedef boost::graph_traits<Target>::halfedge_descriptor tm_halfedge_descriptor;
|
||||
|
||||
namespace OpenMesh {
|
||||
|
||||
inline std::size_t hash_value(const VertexHandle& i)
|
||||
{
|
||||
return i.idx();
|
||||
}
|
||||
|
||||
inline std::size_t hash_value(const HalfedgeHandle& i)
|
||||
{
|
||||
return i.idx();
|
||||
}
|
||||
|
||||
inline std::size_t hash_value(const FaceHandle& i)
|
||||
{
|
||||
return i.idx();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main(int, char* argv[])
|
||||
{
|
||||
Source S;
|
||||
Target T;
|
||||
std::ifstream in(argv[1]);
|
||||
in >> S;
|
||||
|
||||
{
|
||||
boost::unordered_map<sm_vertex_descriptor, tm_vertex_descriptor> v2v;
|
||||
boost::unordered_map<sm_halfedge_descriptor, tm_halfedge_descriptor> h2h;
|
||||
|
||||
convert_surface_mesh(S,T,v2v,h2h);
|
||||
OpenMesh::IO::write_mesh(T, "om.off");
|
||||
}
|
||||
|
||||
{
|
||||
boost::unordered_map<tm_vertex_descriptor, sm_vertex_descriptor> v2v;
|
||||
boost::unordered_map<tm_halfedge_descriptor, sm_halfedge_descriptor> h2h;
|
||||
|
||||
convert_surface_mesh(T,S,v2v,h2h);
|
||||
std::ofstream out("reverse.off");
|
||||
out << S << std::endl;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1095,7 +1095,7 @@ collapse_edge(typename boost::graph_traits<Graph>::edge_descriptor v0v1,
|
|||
remove_vertex(p,g);
|
||||
Halfedge_around_target_circulator<Graph> beg(ppt,g), end(pqb,g);
|
||||
while(beg != end){
|
||||
assert(target(*beg,g) == p);
|
||||
CGAL_assertion(target(*beg,g) == p);
|
||||
set_target(*beg,q,g);
|
||||
--beg;
|
||||
}
|
||||
|
|
@ -1322,7 +1322,7 @@ flip_edge(typename boost::graph_traits<Graph>::halfedge_descriptor h,
|
|||
vertex_descriptor s2 = target(nh,g), t2 = target(noh,g);
|
||||
face_descriptor fh = face(h,g), foh = face(oh,g);
|
||||
|
||||
assert(fh != Traits::null_face() && foh != Traits::null_face());
|
||||
CGAL_assertion(fh != Traits::null_face() && foh != Traits::null_face());
|
||||
|
||||
if(halfedge(s,g) == oh){
|
||||
set_halfedge(s,nnh,g);
|
||||
|
|
@ -1455,6 +1455,7 @@ bool
|
|||
}
|
||||
|
||||
#ifndef CGAL_NO_DEPRECATED_CODE
|
||||
/// \cond SKIP_IN_MANUAL
|
||||
template<typename Graph>
|
||||
bool
|
||||
satisfies_link_condition(typename boost::graph_traits<Graph>::edge_descriptor e,
|
||||
|
|
@ -1462,6 +1463,7 @@ bool
|
|||
{
|
||||
return does_satisfy_link_condition(e, g);
|
||||
}
|
||||
/// \endcond
|
||||
#endif
|
||||
/// @}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,64 @@
|
|||
|
||||
|
||||
#ifndef CGAL_BOOST_GRAPH_CONVERT_SURFACE_MESH_H
|
||||
#define CGAL_BOOST_GRAPH_CONVERT_SURFACE_MESH_H
|
||||
|
||||
#include <CGAL/boost/graph/Euler_operations.h>
|
||||
#include <CGAL/boost/graph/iterator.h>
|
||||
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
template <typename SourceMesh, typename TargetMesh, typename V2V, typename H2H>
|
||||
void convert_surface_mesh(const SourceMesh& sm, TargetMesh& tm, V2V& v2v, H2H& h2h)
|
||||
{
|
||||
typedef boost::graph_traits<SourceMesh>::vertex_descriptor sm_vertex_descriptor;
|
||||
typedef boost::graph_traits<TargetMesh>::vertex_descriptor tm_vertex_descriptor;
|
||||
|
||||
typedef boost::graph_traits<SourceMesh>::face_descriptor sm_face_descriptor;
|
||||
typedef boost::graph_traits<TargetMesh>::face_descriptor tm_face_descriptor;
|
||||
|
||||
typedef boost::graph_traits<SourceMesh>::halfedge_descriptor sm_halfedge_descriptor;
|
||||
typedef boost::graph_traits<TargetMesh>::halfedge_descriptor tm_halfedge_descriptor;
|
||||
|
||||
typedef typename boost::property_map<SourceMesh, vertex_point_t>::const_type sm_PMap;
|
||||
typedef typename boost::property_map<TargetMesh, vertex_point_t>::type tm_PMap;
|
||||
|
||||
sm_PMap sm_pmap = get(vertex_point, sm);
|
||||
tm_PMap tm_pmap = get(vertex_point, tm);
|
||||
|
||||
|
||||
BOOST_FOREACH(sm_vertex_descriptor svd, vertices(sm)){
|
||||
tm_vertex_descriptor tvd = add_vertex(tm);
|
||||
v2v.insert(std::make_pair(svd, tvd));
|
||||
put(tm_pmap, tvd, get(sm_pmap, svd));
|
||||
}
|
||||
|
||||
boost::unordered_map<sm_face_descriptor, tm_face_descriptor> f2f;
|
||||
BOOST_FOREACH(sm_face_descriptor sfd, faces(sm)){
|
||||
std::vector<tm_vertex_descriptor> tv;
|
||||
BOOST_FOREACH(sm_vertex_descriptor svd, vertices_around_face(halfedge(sfd,sm),sm)){
|
||||
tv.push_back(v2v.at(svd));
|
||||
}
|
||||
f2f[sfd] = Euler::add_face(tv,tm);
|
||||
}
|
||||
|
||||
BOOST_FOREACH(sm_face_descriptor sfd, faces(sm)){
|
||||
sm_halfedge_descriptor shd = halfedge(sfd,sm), done(shd);
|
||||
tm_halfedge_descriptor thd = halfedge(f2f[sfd],tm);
|
||||
tm_vertex_descriptor tvd = v2v.at(target(shd,sm));
|
||||
while(target(thd,tm) != tvd){
|
||||
thd = next(thd,tm);
|
||||
}
|
||||
do {
|
||||
h2h.insert(std::make_pair(shd, thd));
|
||||
shd = next(shd,sm);
|
||||
thd = next(thd,tm);
|
||||
}while(shd != done);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // namespace CGAL
|
||||
|
||||
#endif // CGAL_BOOST_GRAPH_CONVERT_SURFACE_MESH_H
|
||||
|
|
@ -30,6 +30,7 @@
|
|||
#include <CGAL/boost/graph/iterator.h>
|
||||
#include <CGAL/Iterator_range.h>
|
||||
#include <CGAL/boost/graph/helpers.h>
|
||||
#include <CGAL/assertions.h>
|
||||
|
||||
#include <OpenMesh/Core/Mesh/PolyMesh_ArrayKernelT.hh>
|
||||
|
||||
|
|
@ -354,6 +355,9 @@ typename boost::graph_traits<OpenMesh::PolyMesh_ArrayKernelT<K> >::halfedge_desc
|
|||
halfedge(typename boost::graph_traits<OpenMesh::PolyMesh_ArrayKernelT<K> >::vertex_descriptor v,
|
||||
const OpenMesh::PolyMesh_ArrayKernelT<K>& sm)
|
||||
{
|
||||
if(sm.halfedge_handle(v) == boost::graph_traits<OpenMesh::PolyMesh_ArrayKernelT<K> >::null_halfedge()){
|
||||
return boost::graph_traits<OpenMesh::PolyMesh_ArrayKernelT<K> >::null_halfedge();
|
||||
}
|
||||
// prev because OpenMesh stores out-going halfedges
|
||||
// return sm.prev_halfedge_handle(sm.halfedge_handle(v));
|
||||
return sm.opposite_halfedge_handle(sm.halfedge_handle(v));
|
||||
|
|
@ -540,7 +544,7 @@ template <typename K>
|
|||
void
|
||||
clear_vertex(typename boost::graph_traits<OpenMesh::PolyMesh_ArrayKernelT<K> >::vertex_descriptor,
|
||||
OpenMesh::PolyMesh_ArrayKernelT<K>&) {
|
||||
assert(false);
|
||||
CGAL_assert(false);
|
||||
}
|
||||
|
||||
*/
|
||||
|
|
@ -606,12 +610,12 @@ remove_face(typename boost::graph_traits<OpenMesh::PolyMesh_ArrayKernelT<K> >::f
|
|||
sm.request_face_status();
|
||||
sm.request_vertex_status();
|
||||
sm.request_halfedge_status();
|
||||
set_halfedge(f, typename boost::graph_traits<OpenMesh::PolyMesh_ArrayKernelT<K> >::halfedge_descriptor(), sm);
|
||||
|
||||
set_halfedge(f, typename boost::graph_traits<OpenMesh::PolyMesh_ArrayKernelT<K> >::halfedge_descriptor(), sm);
|
||||
sm.status(f).set_deleted(true);
|
||||
}
|
||||
|
||||
|
||||
#if 0 // conflits with function in Euler_operations.h
|
||||
template<typename K>
|
||||
std::pair<typename boost::graph_traits<OpenMesh::PolyMesh_ArrayKernelT<K> >::edge_descriptor,
|
||||
bool>
|
||||
|
|
@ -621,6 +625,7 @@ add_edge(typename boost::graph_traits<OpenMesh::PolyMesh_ArrayKernelT<K> >::vert
|
|||
|
||||
return sm.new_edge(v1, v2);
|
||||
}
|
||||
#endif
|
||||
|
||||
template<typename K>
|
||||
typename boost::graph_traits<OpenMesh::PolyMesh_ArrayKernelT<K> >::face_descriptor
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
#include <CGAL/boost/graph/iterator.h>
|
||||
|
||||
#include <CGAL/Surface_mesh.h>
|
||||
|
||||
#include <CGAL/assertions.h>
|
||||
|
||||
|
||||
namespace boost {
|
||||
|
|
@ -445,7 +445,7 @@ template <typename P>
|
|||
void
|
||||
clear_vertex(typename boost::graph_traits<CGAL::Surface_mesh<P> >::vertex_descriptor,
|
||||
CGAL::Surface_mesh<P>&) {
|
||||
assert(false);
|
||||
CGAL_assertion(false);
|
||||
}
|
||||
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -0,0 +1,614 @@
|
|||
// Copyright (c) 2007 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 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$
|
||||
//
|
||||
//
|
||||
// Author(s) : Andreas Fabri, Philipp Moeller
|
||||
|
||||
#ifndef CGAL_BOOST_GRAPH_GRAPH_TRAITS_TRIMESH_ARRAYKERNELT_H
|
||||
#define CGAL_BOOST_GRAPH_GRAPH_TRAITS_TRIMESH_ARRAYKERNELT_H
|
||||
|
||||
#include <boost/graph/graph_traits.hpp>
|
||||
#include <boost/graph/properties.hpp>
|
||||
|
||||
#include <boost/iterator/transform_iterator.hpp>
|
||||
|
||||
#include <CGAL/boost/graph/properties_TriMesh_ArrayKernelT.h>
|
||||
#include <CGAL/boost/graph/graph_traits_PolyMesh_ArrayKernelT.h>
|
||||
#include <CGAL/boost/graph/internal/OM_iterator_from_circulator.h>
|
||||
#include <CGAL/boost/graph/iterator.h>
|
||||
#include <CGAL/Iterator_range.h>
|
||||
#include <CGAL/boost/graph/helpers.h>
|
||||
#include <CGAL/assertions.h>
|
||||
|
||||
#include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
|
||||
|
||||
// http://openmesh.org/Documentation/OpenMesh-Doc-Latest/classOpenMesh_1_1Concepts_1_1KernelT.html
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:4267)
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
template <class K>
|
||||
struct graph_traits< OpenMesh::TriMesh_ArrayKernelT<K> >
|
||||
{
|
||||
private:
|
||||
typedef OpenMesh::TriMesh_ArrayKernelT<K> SM;
|
||||
|
||||
struct SM_graph_traversal_category : public virtual boost::bidirectional_graph_tag,
|
||||
public virtual boost::vertex_list_graph_tag,
|
||||
public virtual boost::edge_list_graph_tag
|
||||
{};
|
||||
|
||||
public:
|
||||
// Graph
|
||||
typedef typename SM::VertexHandle vertex_descriptor;
|
||||
typedef typename SM::Point vertex_property_type;
|
||||
typedef typename CGAL::internal::OMesh_edge<typename SM::HalfedgeHandle> edge_descriptor;
|
||||
typedef boost::undirected_tag directed_category;
|
||||
typedef boost::disallow_parallel_edge_tag edge_parallel_category;
|
||||
typedef SM_graph_traversal_category traversal_category;
|
||||
|
||||
// HalfedgeGraph
|
||||
typedef typename SM::HalfedgeHandle halfedge_descriptor;
|
||||
|
||||
// FaceGraph
|
||||
typedef typename SM::FaceHandle face_descriptor;
|
||||
|
||||
// VertexListGraph
|
||||
typedef typename SM::VertexIter vertex_iterator;
|
||||
typedef unsigned int vertices_size_type;
|
||||
// EdgeListGraph
|
||||
typedef boost::transform_iterator<
|
||||
CGAL::internal::Convert_omesh_edge<typename SM::HalfedgeHandle, typename SM::EdgeHandle>,
|
||||
typename SM::EdgeIter,
|
||||
edge_descriptor> edge_iterator;
|
||||
|
||||
typedef unsigned int edges_size_type;
|
||||
// HalfEdgeListGraph
|
||||
typedef typename SM::HalfedgeIter halfedge_iterator;
|
||||
typedef unsigned int halfedges_size_type;
|
||||
// FaceListGraph
|
||||
typedef typename SM::FaceIter face_iterator;
|
||||
typedef unsigned int faces_size_type;
|
||||
|
||||
// IncidenceGraph
|
||||
typedef unsigned int degree_size_type;
|
||||
|
||||
|
||||
typedef CGAL::In_edge_iterator<SM> in_edge_iterator;
|
||||
|
||||
typedef CGAL::Out_edge_iterator<SM> out_edge_iterator;
|
||||
|
||||
// nulls
|
||||
static vertex_descriptor null_vertex() { return vertex_descriptor(); }
|
||||
static face_descriptor null_face() { return face_descriptor(); }
|
||||
static halfedge_descriptor null_halfedge() { return halfedge_descriptor(); }
|
||||
};
|
||||
|
||||
template<typename K>
|
||||
struct graph_traits< const OpenMesh::TriMesh_ArrayKernelT<K> >
|
||||
: public graph_traits< OpenMesh::TriMesh_ArrayKernelT<K> >
|
||||
{ };
|
||||
|
||||
} // namespace boost
|
||||
|
||||
namespace OpenMesh {
|
||||
|
||||
template <typename K>
|
||||
typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::vertices_size_type
|
||||
num_vertices(const OpenMesh::TriMesh_ArrayKernelT<K>& sm)
|
||||
{
|
||||
return sm.n_vertices();
|
||||
}
|
||||
|
||||
|
||||
template <typename K>
|
||||
typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::edges_size_type
|
||||
num_edges(const OpenMesh::TriMesh_ArrayKernelT<K>& sm)
|
||||
{
|
||||
return sm.n_edges();
|
||||
}
|
||||
|
||||
|
||||
template <typename K>
|
||||
typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::degree_size_type
|
||||
degree(typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::vertex_descriptor v,
|
||||
const OpenMesh::TriMesh_ArrayKernelT<K>& sm)
|
||||
{
|
||||
return sm.valence(v);
|
||||
}
|
||||
|
||||
|
||||
template <typename K>
|
||||
typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::degree_size_type
|
||||
out_degree(typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::vertex_descriptor v,
|
||||
const OpenMesh::TriMesh_ArrayKernelT<K>& sm)
|
||||
{
|
||||
return sm.valence(v);
|
||||
}
|
||||
|
||||
|
||||
template <typename K>
|
||||
typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::degree_size_type
|
||||
in_degree(typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::vertex_descriptor v,
|
||||
const OpenMesh::TriMesh_ArrayKernelT<K>& sm)
|
||||
{
|
||||
return sm.valence(v);
|
||||
}
|
||||
|
||||
|
||||
template <typename K>
|
||||
typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::vertex_descriptor
|
||||
source(typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::edge_descriptor e,
|
||||
const OpenMesh::TriMesh_ArrayKernelT<K>& sm)
|
||||
{
|
||||
return sm.from_vertex_handle(e.halfedge());
|
||||
}
|
||||
|
||||
template <typename K>
|
||||
typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::vertex_descriptor
|
||||
source(typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::halfedge_descriptor h,
|
||||
const OpenMesh::TriMesh_ArrayKernelT<K>& sm)
|
||||
{
|
||||
return sm.from_vertex_handle(h);
|
||||
}
|
||||
|
||||
|
||||
template <typename K>
|
||||
typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::vertex_descriptor
|
||||
target(typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::edge_descriptor e,
|
||||
const OpenMesh::TriMesh_ArrayKernelT<K>& sm)
|
||||
{
|
||||
return sm.to_vertex_handle(e.halfedge());
|
||||
}
|
||||
|
||||
template <typename K>
|
||||
typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::vertex_descriptor
|
||||
target(typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::halfedge_descriptor h,
|
||||
const OpenMesh::TriMesh_ArrayKernelT<K>& sm)
|
||||
{
|
||||
return sm.to_vertex_handle(h);
|
||||
}
|
||||
|
||||
template <typename K>
|
||||
CGAL::Iterator_range<typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::vertex_iterator>
|
||||
vertices(const OpenMesh::TriMesh_ArrayKernelT<K>& sm)
|
||||
{
|
||||
return CGAL::make_range(sm.vertices_sbegin(), sm.vertices_end());
|
||||
}
|
||||
|
||||
|
||||
template <typename K>
|
||||
CGAL::Iterator_range<typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::edge_iterator>
|
||||
edges(const OpenMesh::TriMesh_ArrayKernelT<K>& sm)
|
||||
{
|
||||
typedef typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::edge_iterator iterator;
|
||||
iterator beg(sm.edges_sbegin());
|
||||
iterator end(sm.edges_end());
|
||||
return CGAL::make_range(beg,end);
|
||||
}
|
||||
|
||||
|
||||
template <typename K>
|
||||
CGAL::Iterator_range<typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::in_edge_iterator>
|
||||
in_edges(typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::vertex_descriptor v,
|
||||
const OpenMesh::TriMesh_ArrayKernelT<K>& sm)
|
||||
{
|
||||
typedef typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::in_edge_iterator Iter;
|
||||
|
||||
return CGAL::make_range(Iter(halfedge(v,sm),sm), Iter(halfedge(v,sm),sm,1));
|
||||
}
|
||||
|
||||
|
||||
template <typename K>
|
||||
CGAL::Iterator_range<typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::out_edge_iterator>
|
||||
out_edges(typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::vertex_descriptor v,
|
||||
const OpenMesh::TriMesh_ArrayKernelT<K>& sm)
|
||||
{
|
||||
typedef typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::out_edge_iterator Iter;
|
||||
return CGAL::make_range(Iter(halfedge(v,sm),sm), Iter(halfedge(v,sm),sm,1));
|
||||
}
|
||||
|
||||
|
||||
template<typename K>
|
||||
std::pair<typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::edge_descriptor,
|
||||
bool>
|
||||
edge(typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::vertex_descriptor u,
|
||||
typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::vertex_descriptor v,
|
||||
const OpenMesh::TriMesh_ArrayKernelT<K>& sm) {
|
||||
typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::edge_descriptor
|
||||
he(sm.find_halfedge(u, v));
|
||||
return std::make_pair(he, he.is_valid());
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// HalfedgeGraph
|
||||
//
|
||||
template <typename K>
|
||||
typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::halfedge_descriptor
|
||||
next(typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::halfedge_descriptor h,
|
||||
const OpenMesh::TriMesh_ArrayKernelT<K>& sm)
|
||||
{
|
||||
return sm.next_halfedge_handle(h);
|
||||
}
|
||||
|
||||
template <typename K>
|
||||
typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::halfedge_descriptor
|
||||
prev(typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::halfedge_descriptor h,
|
||||
const OpenMesh::TriMesh_ArrayKernelT<K>& sm)
|
||||
{
|
||||
return sm.prev_halfedge_handle(h);
|
||||
}
|
||||
|
||||
template <typename K>
|
||||
typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::halfedge_descriptor
|
||||
opposite(typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::halfedge_descriptor h,
|
||||
const OpenMesh::TriMesh_ArrayKernelT<K>& sm)
|
||||
{
|
||||
return sm.opposite_halfedge_handle(h);
|
||||
}
|
||||
|
||||
template <typename K>
|
||||
typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::edge_descriptor
|
||||
edge(typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::halfedge_descriptor h,
|
||||
const OpenMesh::TriMesh_ArrayKernelT<K>& /*sm*/)
|
||||
{
|
||||
return typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::edge_descriptor(h);
|
||||
}
|
||||
|
||||
template <typename K>
|
||||
typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::halfedge_descriptor
|
||||
halfedge(typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::edge_descriptor e,
|
||||
const OpenMesh::TriMesh_ArrayKernelT<K>&)
|
||||
{
|
||||
return e.halfedge();
|
||||
}
|
||||
|
||||
template <typename K>
|
||||
typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::halfedge_descriptor
|
||||
halfedge(typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::vertex_descriptor v,
|
||||
const OpenMesh::TriMesh_ArrayKernelT<K>& sm)
|
||||
{
|
||||
if(sm.halfedge_handle(v) == boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::null_halfedge()){
|
||||
return boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::null_halfedge();
|
||||
}
|
||||
// prev because OpenMesh stores out-going halfedges
|
||||
// return sm.prev_halfedge_handle(sm.halfedge_handle(v));
|
||||
return sm.opposite_halfedge_handle(sm.halfedge_handle(v));
|
||||
}
|
||||
|
||||
|
||||
template <typename K>
|
||||
std::pair<
|
||||
typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::halfedge_descriptor,
|
||||
bool
|
||||
>
|
||||
halfedge(typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::vertex_descriptor u,
|
||||
typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::vertex_descriptor v,
|
||||
const OpenMesh::TriMesh_ArrayKernelT<K>& sm)
|
||||
{
|
||||
typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::halfedge_descriptor h = sm.find_halfedge(u, v);
|
||||
return std::make_pair(h, h.is_valid());
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// HalfedgeListGraph
|
||||
//
|
||||
template <typename K>
|
||||
CGAL::Iterator_range<typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::halfedge_iterator>
|
||||
halfedges(const OpenMesh::TriMesh_ArrayKernelT<K>& sm)
|
||||
{
|
||||
return CGAL::make_range(sm.halfedges_sbegin(), sm.halfedges_end());
|
||||
}
|
||||
|
||||
template <typename K>
|
||||
typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::halfedges_size_type
|
||||
num_halfedges(const OpenMesh::TriMesh_ArrayKernelT<K>& sm)
|
||||
{
|
||||
return sm.n_halfedges();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// MutableHalfedgeGraph
|
||||
//
|
||||
template<typename K>
|
||||
void
|
||||
set_next(typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::halfedge_descriptor h1,
|
||||
typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::halfedge_descriptor h2,
|
||||
OpenMesh::TriMesh_ArrayKernelT<K>& sm)
|
||||
{
|
||||
sm.set_next_halfedge_handle(h1, h2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename K>
|
||||
void
|
||||
set_target(typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::halfedge_descriptor h,
|
||||
typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::vertex_descriptor v,
|
||||
OpenMesh::TriMesh_ArrayKernelT<K>& sm)
|
||||
{
|
||||
sm.set_vertex_handle(h, v);
|
||||
}
|
||||
|
||||
|
||||
template<typename K>
|
||||
void
|
||||
set_halfedge(typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::vertex_descriptor v,
|
||||
typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::halfedge_descriptor h,
|
||||
OpenMesh::TriMesh_ArrayKernelT<K>& sm)
|
||||
{
|
||||
sm.set_halfedge_handle(v, sm.opposite_halfedge_handle(h));
|
||||
}
|
||||
|
||||
|
||||
template<typename K>
|
||||
void
|
||||
adjust_border_halfedge(typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::vertex_descriptor v,
|
||||
OpenMesh::TriMesh_ArrayKernelT<K>& sm)
|
||||
{
|
||||
sm.adjust_outgoing_halfedge(v);
|
||||
}
|
||||
|
||||
template<typename K>
|
||||
void
|
||||
garbage_collection(OpenMesh::TriMesh_ArrayKernelT<K>& sm)
|
||||
{
|
||||
sm.garbage_collection();
|
||||
}
|
||||
|
||||
template<typename K>
|
||||
typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::edge_descriptor
|
||||
add_edge(OpenMesh::TriMesh_ArrayKernelT<K>& sm)
|
||||
{
|
||||
return edge(sm.new_edge(boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::null_vertex(),
|
||||
boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::null_vertex() ), sm);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// FaceGraph
|
||||
//
|
||||
template<typename K>
|
||||
typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::halfedge_descriptor
|
||||
halfedge(typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::face_descriptor f,
|
||||
const OpenMesh::TriMesh_ArrayKernelT<K>& sm)
|
||||
{
|
||||
return sm.halfedge_handle(f);
|
||||
}
|
||||
|
||||
template<typename K>
|
||||
typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::face_descriptor
|
||||
face(typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::halfedge_descriptor h,
|
||||
const OpenMesh::TriMesh_ArrayKernelT<K>& sm)
|
||||
{
|
||||
return sm.face_handle(h);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// MutableFaceGraph
|
||||
//
|
||||
template<typename K>
|
||||
void
|
||||
set_face(typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::halfedge_descriptor h,
|
||||
typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::face_descriptor f,
|
||||
OpenMesh::TriMesh_ArrayKernelT<K>& sm)
|
||||
{
|
||||
sm.set_face_handle(h, f);
|
||||
}
|
||||
|
||||
|
||||
template<typename K>
|
||||
void
|
||||
set_halfedge(typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::face_descriptor f,
|
||||
typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::halfedge_descriptor h,
|
||||
OpenMesh::TriMesh_ArrayKernelT<K>& sm)
|
||||
{
|
||||
sm.set_halfedge_handle(f, h);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// FaceListGraph
|
||||
//
|
||||
template <typename K>
|
||||
typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::faces_size_type
|
||||
num_faces(const OpenMesh::TriMesh_ArrayKernelT<K>& sm)
|
||||
{
|
||||
return sm.n_faces();
|
||||
}
|
||||
|
||||
template <typename K>
|
||||
CGAL::Iterator_range<typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::face_iterator>
|
||||
faces(const OpenMesh::TriMesh_ArrayKernelT<K>& sm)
|
||||
{
|
||||
return CGAL::make_range(sm.faces_sbegin(), sm.faces_end());
|
||||
}
|
||||
|
||||
|
||||
template <typename K>
|
||||
typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::vertex_descriptor
|
||||
add_vertex(OpenMesh::TriMesh_ArrayKernelT<K>& sm) {
|
||||
return sm.new_vertex();
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
// MutableGraph
|
||||
// add a vertex with a default constructed property
|
||||
template <typename K>
|
||||
typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::vertex_descriptor
|
||||
add_vertex(OpenMesh::TriMesh_ArrayKernelT<K>& sm) {
|
||||
return sm.add_vertex(typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::vertex_property_type());
|
||||
}
|
||||
|
||||
template <typename K>
|
||||
typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::vertex_descriptor
|
||||
add_vertex(const typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::vertex_property_type& p, OpenMesh::TriMesh_ArrayKernelT<K>& sm) {
|
||||
return sm.add_vertex(p);
|
||||
}
|
||||
|
||||
template <typename K>
|
||||
void
|
||||
clear_vertex(typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::vertex_descriptor,
|
||||
OpenMesh::TriMesh_ArrayKernelT<K>&) {
|
||||
CGAL_assert(false);
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
template <typename K>
|
||||
void
|
||||
remove_vertex(typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::vertex_descriptor v,
|
||||
OpenMesh::TriMesh_ArrayKernelT<K>& sm) {
|
||||
|
||||
sm.request_face_status();
|
||||
sm.request_vertex_status();
|
||||
sm.request_halfedge_status();
|
||||
sm.set_halfedge_handle(v, typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::halfedge_descriptor());
|
||||
sm.status(v).set_deleted(true);
|
||||
}
|
||||
|
||||
|
||||
template <typename K>
|
||||
void
|
||||
remove_edge(typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::vertex_descriptor u,
|
||||
typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::vertex_descriptor v,
|
||||
OpenMesh::TriMesh_ArrayKernelT<K>& sm)
|
||||
{
|
||||
typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::edge_descriptor e = edge(u, v, sm);
|
||||
remove_edge(e,sm);
|
||||
}
|
||||
|
||||
template <typename K>
|
||||
void
|
||||
remove_edge(typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::edge_descriptor e,
|
||||
OpenMesh::TriMesh_ArrayKernelT<K>& sm)
|
||||
{
|
||||
sm.request_face_status();
|
||||
sm.request_vertex_status();
|
||||
sm.request_halfedge_status();
|
||||
sm.request_edge_status();
|
||||
|
||||
typedef typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::halfedge_descriptor halfedge_descriptor;
|
||||
|
||||
halfedge_descriptor h1 = halfedge(e,sm);
|
||||
halfedge_descriptor h2 = opposite(halfedge(e,sm),sm);
|
||||
sm.status(sm.edge_handle(h1)).set_deleted(true);
|
||||
sm.status(h1).set_deleted(true);
|
||||
sm.status(h2).set_deleted(true);
|
||||
|
||||
}
|
||||
|
||||
|
||||
template <typename K>
|
||||
void
|
||||
remove_edge(typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::edge_iterator eiter,
|
||||
OpenMesh::TriMesh_ArrayKernelT<K>& sm)
|
||||
{
|
||||
remove_edge(*eiter, sm);
|
||||
}
|
||||
|
||||
template<typename K>
|
||||
void
|
||||
remove_face(typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::face_descriptor f,
|
||||
OpenMesh::TriMesh_ArrayKernelT<K>& sm)
|
||||
{
|
||||
|
||||
sm.request_face_status();
|
||||
sm.request_vertex_status();
|
||||
sm.request_halfedge_status();
|
||||
|
||||
set_halfedge(f, typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::halfedge_descriptor(), sm);
|
||||
sm.status(f).set_deleted(true);
|
||||
}
|
||||
|
||||
#if 0 // conflits with function in Euler_operations.h
|
||||
template<typename K>
|
||||
std::pair<typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::edge_descriptor,
|
||||
bool>
|
||||
add_edge(typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::vertex_descriptor v1,
|
||||
typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::vertex_descriptor v2,
|
||||
OpenMesh::TriMesh_ArrayKernelT<K>& sm) {
|
||||
|
||||
return sm.new_edge(v1, v2);
|
||||
}
|
||||
#endif
|
||||
|
||||
template<typename K>
|
||||
typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::face_descriptor
|
||||
add_face(OpenMesh::TriMesh_ArrayKernelT<K>& sm)
|
||||
{
|
||||
return sm.new_face();
|
||||
}
|
||||
|
||||
template<typename K, typename InputIterator>
|
||||
typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::face_descriptor
|
||||
add_face(InputIterator begin, InputIterator end, OpenMesh::TriMesh_ArrayKernelT<K>& sm)
|
||||
{
|
||||
typedef typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::vertex_descriptor vertex_descriptor;
|
||||
assert(begin!= end);
|
||||
vertex_descriptor u = *begin;
|
||||
++begin;
|
||||
assert(begin!= end);
|
||||
vertex_descriptor v = *begin;
|
||||
++begin;
|
||||
assert(begin!= end);
|
||||
vertex_descriptor w = *begin;
|
||||
|
||||
return sm.add_face(u,v,w);
|
||||
}
|
||||
|
||||
template<typename K>
|
||||
bool is_valid(OpenMesh::TriMesh_ArrayKernelT<K>& sm, bool /* verbose */ = false)
|
||||
{
|
||||
return CGAL::is_valid_polygon_mesh(sm);
|
||||
}
|
||||
|
||||
} // namespace OpenMesh
|
||||
|
||||
|
||||
#ifndef CGAL_NO_DEPRECATED_CODE
|
||||
#include <CGAL/boost/graph/backward_compatibility_functions.h>
|
||||
|
||||
namespace boost {
|
||||
// The following functions were defined in the namespace boost
|
||||
using OpenMesh::vertices;
|
||||
using OpenMesh::edges;
|
||||
using OpenMesh::num_vertices;
|
||||
using OpenMesh::num_edges;
|
||||
using OpenMesh::out_edges;
|
||||
using OpenMesh::in_edges;
|
||||
using OpenMesh::target;
|
||||
using OpenMesh::source;
|
||||
} // namespace boost
|
||||
#endif //CGAL_NO_DEPRECATED_CODE
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif // CGAL_BOOST_GRAPH_TRAITS_TRIMESH_ARRAYKERNELT_H
|
||||
|
|
@ -872,7 +872,16 @@ halfedges_around_face(typename boost::graph_traits<Graph>::halfedge_descriptor h
|
|||
return make_range(I(h,g), I(h,g,1));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \ingroup PkgBGLIterators
|
||||
* A bidirectional iterator with value type `boost::graph_traits<Graph>::%face_descriptor`.
|
||||
* It iterates over the same halfedges as the `Halfedge_around_face_iterator`,
|
||||
* and provides the face descriptor associated to the opposite halfedge. The face descriptor
|
||||
* may be the null face, and it may be several times the same face descriptor.
|
||||
*
|
||||
* \tparam Graph must be a model of the concept `HalfedgeGraph`
|
||||
* \cgalModels `BidirectionalCirculator`
|
||||
*/
|
||||
template <typename Graph>
|
||||
class Face_around_face_iterator
|
||||
#ifndef DOXYGEN_RUNNING
|
||||
|
|
@ -1023,6 +1032,13 @@ private:
|
|||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* \ingroup PkgBGLIterators
|
||||
* A bidirectional iterator with value type `boost::graph_traits<Graph>::%vertex_descriptor`
|
||||
* over all vertices incident to the same face or border.
|
||||
* \tparam Graph must be a model of the concept `HalfedgeGraph`
|
||||
* \cgalModels `BidirectionalIterator`
|
||||
*/
|
||||
template <typename Graph>
|
||||
class Vertex_around_face_iterator
|
||||
#ifndef DOXYGEN_RUNNING
|
||||
|
|
@ -1111,7 +1127,7 @@ opposite_edges_around_face(typename boost::graph_traits<Graph>::halfedge_descrip
|
|||
|
||||
/**
|
||||
* \ingroup PkgBGLIterators
|
||||
* A bidirectional circulator with value type `boost::graph_traits<Graph>::%vertex_descriptor` over all vertices adjacent to the same vertex.
|
||||
* A bidirectional circulator with value type `boost::graph_traits<Graph>::%vertex_descriptor` over all vertices adjacent to the same vertex.
|
||||
* It circulates over the same halfedges as the `Halfedge_around_target_circulator`.
|
||||
*
|
||||
* \tparam Graph must be a model of the concept `HalfedgeGraph`
|
||||
|
|
|
|||
|
|
@ -85,17 +85,17 @@ public:
|
|||
};
|
||||
|
||||
|
||||
template <typename K>
|
||||
template <typename OpenMesh>
|
||||
class OM_edge_weight_pmap
|
||||
: public boost::put_get_helper<typename OpenMesh::PolyMesh_ArrayKernelT<K>::Scalar , OM_edge_weight_pmap<K> >
|
||||
: public boost::put_get_helper<typename OpenMesh::Scalar , OM_edge_weight_pmap<OpenMesh> >
|
||||
{
|
||||
public:
|
||||
typedef boost::readable_property_map_tag category;
|
||||
typedef typename OpenMesh::PolyMesh_ArrayKernelT<K>::Scalar value_type;
|
||||
typedef typename OpenMesh::Scalar value_type;
|
||||
typedef value_type reference;
|
||||
typedef typename boost::graph_traits<OpenMesh::PolyMesh_ArrayKernelT<K> >::edge_descriptor key_type;
|
||||
typedef typename boost::graph_traits<OpenMesh>::edge_descriptor key_type;
|
||||
|
||||
OM_edge_weight_pmap(const OpenMesh::PolyMesh_ArrayKernelT<K>& sm)
|
||||
OM_edge_weight_pmap(const OpenMesh& sm)
|
||||
: sm_(sm)
|
||||
{}
|
||||
|
||||
|
|
@ -105,7 +105,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
const OpenMesh::PolyMesh_ArrayKernelT<K>& sm_;
|
||||
const OpenMesh& sm_;
|
||||
};
|
||||
|
||||
template <typename K, typename VEF>
|
||||
|
|
@ -124,25 +124,25 @@ public:
|
|||
};
|
||||
|
||||
|
||||
template<typename K, typename P>
|
||||
class OM_point_pmap //: public boost::put_get_helper<bool, OM_point_pmap<K> >
|
||||
template<typename OpenMesh, typename P>
|
||||
class OM_point_pmap //: public boost::put_get_helper<bool, OM_point_pmap<OpenMesh> >
|
||||
{
|
||||
public:
|
||||
typedef boost::read_write_property_map_tag category;
|
||||
#if defined(CGAL_USE_OM_POINTS)
|
||||
typedef typename OpenMesh::PolyMesh_ArrayKernelT<K>::Point value_type;
|
||||
typedef const typename OpenMesh::PolyMesh_ArrayKernelT<K>::Point& reference;
|
||||
typedef typename OpenMesh::Point value_type;
|
||||
typedef const typename OpenMesh::Point& reference;
|
||||
#else
|
||||
typedef P value_type;
|
||||
typedef P reference;
|
||||
#endif
|
||||
typedef typename boost::graph_traits< OpenMesh::PolyMesh_ArrayKernelT<K> >::vertex_descriptor key_type;
|
||||
typedef typename boost::graph_traits<OpenMesh>::vertex_descriptor key_type;
|
||||
|
||||
OM_point_pmap()
|
||||
: sm_(NULL)
|
||||
{}
|
||||
|
||||
OM_point_pmap(const OpenMesh::PolyMesh_ArrayKernelT<K>& sm)
|
||||
OM_point_pmap(const OpenMesh& sm)
|
||||
: sm_(&sm)
|
||||
{}
|
||||
|
||||
|
|
@ -156,36 +156,36 @@ public:
|
|||
return sm_->point(v);
|
||||
#else
|
||||
CGAL_assertion(sm_!=NULL);
|
||||
typename OpenMesh::PolyMesh_ArrayKernelT<K>::Point const& omp = sm_->point(v);
|
||||
typename OpenMesh::Point const& omp = sm_->point(v);
|
||||
return value_type(omp[0], omp[1], omp[2]);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline friend reference get(const OM_point_pmap<K,P>& pm, key_type v)
|
||||
inline friend reference get(const OM_point_pmap<OpenMesh,P>& pm, key_type v)
|
||||
{
|
||||
CGAL_precondition(pm.sm_!=NULL);
|
||||
#if defined(CGAL_USE_OM_POINTS)
|
||||
return pm.sm_->point(v);
|
||||
#else
|
||||
CGAL_assertion(pm.sm_!=NULL);
|
||||
typename OpenMesh::PolyMesh_ArrayKernelT<K>::Point const& omp = pm.sm_->point(v);
|
||||
typename OpenMesh::Point const& omp = pm.sm_->point(v);
|
||||
return value_type(omp[0], omp[1], omp[2]);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline friend void put(const OM_point_pmap<K,P>& pm, key_type v, const value_type& p)
|
||||
inline friend void put(const OM_point_pmap<OpenMesh,P>& pm, key_type v, const value_type& p)
|
||||
{
|
||||
CGAL_precondition(pm.sm_!=NULL);
|
||||
#if defined(CGAL_USE_OM_POINTS)
|
||||
const_cast<OpenMesh::PolyMesh_ArrayKernelT<K>&>(*pm.sm_).set_point(v,p);
|
||||
const_cast<OpenMesh&>(*pm.sm_).set_point(v,p);
|
||||
#else
|
||||
const_cast<OpenMesh::PolyMesh_ArrayKernelT<K>&>(*pm.sm_).set_point
|
||||
(v, typename OpenMesh::PolyMesh_ArrayKernelT<K>::Point((float)p[0], (float)p[1], (float)p[2]));
|
||||
const_cast<OpenMesh&>(*pm.sm_).set_point
|
||||
(v, typename OpenMesh::Point((float)p[0], (float)p[1], (float)p[2]));
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
const OpenMesh::PolyMesh_ArrayKernelT<K>* sm_;
|
||||
const OpenMesh* sm_;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -202,8 +202,9 @@ namespace boost {
|
|||
template <typename K>
|
||||
struct property_map<OpenMesh::PolyMesh_ArrayKernelT<K>, boost::edge_weight_t >
|
||||
{
|
||||
typedef CGAL::OM_edge_weight_pmap<K> type;
|
||||
typedef CGAL::OM_edge_weight_pmap<K> const_type;
|
||||
typedef OpenMesh::PolyMesh_ArrayKernelT<K> Mesh;
|
||||
typedef CGAL::OM_edge_weight_pmap<Mesh> type;
|
||||
typedef CGAL::OM_edge_weight_pmap<Mesh> const_type;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -215,8 +216,9 @@ struct property_map<OpenMesh::PolyMesh_ArrayKernelT<K>, boost::edge_weight_t >
|
|||
template <typename K>
|
||||
struct property_map<OpenMesh::PolyMesh_ArrayKernelT<K>, boost::vertex_index_t >
|
||||
{
|
||||
typedef CGAL::OM_index_pmap<K, typename boost::graph_traits<OpenMesh::PolyMesh_ArrayKernelT<K> >::vertex_descriptor> type;
|
||||
typedef CGAL::OM_index_pmap<K, typename boost::graph_traits<OpenMesh::PolyMesh_ArrayKernelT<K> >::vertex_descriptor> const_type;
|
||||
typedef OpenMesh::PolyMesh_ArrayKernelT<K> Mesh;
|
||||
typedef CGAL::OM_index_pmap<K, typename boost::graph_traits<Mesh>::vertex_descriptor> type;
|
||||
typedef CGAL::OM_index_pmap<K, typename boost::graph_traits<Mesh>::vertex_descriptor> const_type;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -227,8 +229,9 @@ struct property_map<OpenMesh::PolyMesh_ArrayKernelT<K>, boost::vertex_index_t >
|
|||
template <typename K>
|
||||
struct property_map<OpenMesh::PolyMesh_ArrayKernelT<K>, boost::face_index_t >
|
||||
{
|
||||
typedef CGAL::OM_index_pmap<K, typename boost::graph_traits<OpenMesh::PolyMesh_ArrayKernelT<K> >::face_descriptor> type;
|
||||
typedef CGAL::OM_index_pmap<K, typename boost::graph_traits<OpenMesh::PolyMesh_ArrayKernelT<K> >::face_descriptor> const_type;
|
||||
typedef OpenMesh::PolyMesh_ArrayKernelT<K> Mesh;
|
||||
typedef CGAL::OM_index_pmap<K, typename boost::graph_traits<Mesh>::face_descriptor> type;
|
||||
typedef CGAL::OM_index_pmap<K, typename boost::graph_traits<Mesh>::face_descriptor> const_type;
|
||||
};
|
||||
|
||||
//
|
||||
|
|
@ -238,8 +241,9 @@ struct property_map<OpenMesh::PolyMesh_ArrayKernelT<K>, boost::face_index_t >
|
|||
template <typename K>
|
||||
struct property_map<OpenMesh::PolyMesh_ArrayKernelT<K>, boost::edge_index_t >
|
||||
{
|
||||
typedef CGAL::OM_index_pmap<K, typename boost::graph_traits<OpenMesh::PolyMesh_ArrayKernelT<K> >::edge_descriptor> type;
|
||||
typedef CGAL::OM_index_pmap<K, typename boost::graph_traits<OpenMesh::PolyMesh_ArrayKernelT<K> >::edge_descriptor> const_type;
|
||||
typedef OpenMesh::PolyMesh_ArrayKernelT<K> Mesh;
|
||||
typedef CGAL::OM_index_pmap<K, typename Mesh::edge_descriptor> type;
|
||||
typedef CGAL::OM_index_pmap<K, typename Mesh::edge_descriptor> const_type;
|
||||
};
|
||||
|
||||
//
|
||||
|
|
@ -249,8 +253,9 @@ struct property_map<OpenMesh::PolyMesh_ArrayKernelT<K>, boost::edge_index_t >
|
|||
template <typename K>
|
||||
struct property_map<OpenMesh::PolyMesh_ArrayKernelT<K>, boost::halfedge_index_t >
|
||||
{
|
||||
typedef CGAL::OM_index_pmap<K, typename boost::graph_traits<OpenMesh::PolyMesh_ArrayKernelT<K> >::halfedge_descriptor> type;
|
||||
typedef CGAL::OM_index_pmap<K, typename boost::graph_traits<OpenMesh::PolyMesh_ArrayKernelT<K> >::halfedge_descriptor> const_type;
|
||||
typedef OpenMesh::PolyMesh_ArrayKernelT<K> Mesh;
|
||||
typedef CGAL::OM_index_pmap<K, typename Mesh::halfedge_descriptor> type;
|
||||
typedef CGAL::OM_index_pmap<K, typename Mesh::halfedge_descriptor> const_type;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -258,7 +263,8 @@ template<typename K>
|
|||
struct property_map<OpenMesh::PolyMesh_ArrayKernelT<K>, boost::vertex_point_t >
|
||||
{
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel::Point_3 P;
|
||||
typedef CGAL::OM_point_pmap<K,P> type;
|
||||
typedef OpenMesh::PolyMesh_ArrayKernelT<K> Mesh;
|
||||
typedef CGAL::OM_point_pmap<Mesh, P> type;
|
||||
typedef type const_type;
|
||||
};
|
||||
|
||||
|
|
@ -271,7 +277,8 @@ template <typename K>
|
|||
typename boost::property_map<OpenMesh::PolyMesh_ArrayKernelT<K>, boost::edge_weight_t>::const_type
|
||||
get(boost::edge_weight_t, const OpenMesh::PolyMesh_ArrayKernelT<K>& sm)
|
||||
{
|
||||
return CGAL::OM_edge_weight_pmap<K>(sm);
|
||||
typedef OpenMesh::PolyMesh_ArrayKernelT<K> Mesh;
|
||||
return CGAL::OM_edge_weight_pmap<Mesh>(sm);
|
||||
}
|
||||
|
||||
template <typename K>
|
||||
|
|
@ -279,7 +286,8 @@ typename OpenMesh::PolyMesh_ArrayKernelT<K>::Scalar
|
|||
get(boost::edge_weight_t, const OpenMesh::PolyMesh_ArrayKernelT<K>& sm,
|
||||
const typename boost::graph_traits<OpenMesh::PolyMesh_ArrayKernelT<K> >::edge_descriptor& e)
|
||||
{
|
||||
return CGAL::OM_edge_weight_pmap<K>(sm)[e];
|
||||
typedef OpenMesh::PolyMesh_ArrayKernelT<K> Mesh;
|
||||
return CGAL::OM_edge_weight_pmap<Mesh>(sm)[e];
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -287,13 +295,15 @@ template <typename K>
|
|||
CGAL::OM_index_pmap<K, typename boost::graph_traits<OpenMesh::PolyMesh_ArrayKernelT<K> >::vertex_descriptor>
|
||||
get(const boost::vertex_index_t&, const OpenMesh::PolyMesh_ArrayKernelT<K>&)
|
||||
{
|
||||
return CGAL::OM_index_pmap<K, typename boost::graph_traits<OpenMesh::PolyMesh_ArrayKernelT<K> >::vertex_descriptor>();
|
||||
typedef OpenMesh::PolyMesh_ArrayKernelT<K> Mesh;
|
||||
return CGAL::OM_index_pmap<K, typename boost::graph_traits<Mesh>::vertex_descriptor>();
|
||||
}
|
||||
|
||||
template <typename K>
|
||||
typename boost::property_map<OpenMesh::PolyMesh_ArrayKernelT<K>, boost::face_index_t>::const_type
|
||||
get(const boost::face_index_t&, const OpenMesh::PolyMesh_ArrayKernelT<K>&)
|
||||
{
|
||||
typedef OpenMesh::PolyMesh_ArrayKernelT<K> Mesh;
|
||||
return CGAL::OM_index_pmap<K, typename boost::graph_traits<OpenMesh::PolyMesh_ArrayKernelT<K> >::face_descriptor>();
|
||||
}
|
||||
|
||||
|
|
@ -312,11 +322,12 @@ get(const boost::halfedge_index_t&, const OpenMesh::PolyMesh_ArrayKernelT<K>&)
|
|||
}
|
||||
|
||||
template<typename K>
|
||||
CGAL::OM_point_pmap<K,typename CGAL::Exact_predicates_inexact_constructions_kernel::Point_3>
|
||||
CGAL::OM_point_pmap<OpenMesh::PolyMesh_ArrayKernelT<K>,
|
||||
typename CGAL::Exact_predicates_inexact_constructions_kernel::Point_3>
|
||||
get(boost::vertex_point_t, const OpenMesh::PolyMesh_ArrayKernelT<K>& g)
|
||||
{
|
||||
typedef typename CGAL::Exact_predicates_inexact_constructions_kernel::Point_3 P;
|
||||
return CGAL::OM_point_pmap<K,P>(g);
|
||||
return CGAL::OM_point_pmap<OpenMesh::PolyMesh_ArrayKernelT<K>, P>(g);
|
||||
}
|
||||
|
||||
// get for intrinsic properties
|
||||
|
|
|
|||
|
|
@ -0,0 +1,195 @@
|
|||
// Copyright (c) 2014 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 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$
|
||||
//
|
||||
//
|
||||
// Author(s) : Philipp Möller
|
||||
|
||||
|
||||
#ifndef CGAL_PROPERTIES_TRIMESH_ARRAYKERNELT_H
|
||||
#define CGAL_PROPERTIES_TRIMESH_ARRAYKERNELT_H
|
||||
|
||||
#include <CGAL/assertions.h>
|
||||
#include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
|
||||
#include <CGAL/boost/graph/properties.h>
|
||||
#include <CGAL/boost/graph/properties_PolyMesh_ArrayKernelT.h>
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <boost/mpl/if.hpp>
|
||||
|
||||
|
||||
// overloads and specializations in the boost namespace
|
||||
namespace boost {
|
||||
|
||||
//
|
||||
// edge_weight
|
||||
//
|
||||
template <typename K>
|
||||
struct property_map<OpenMesh::TriMesh_ArrayKernelT<K>, boost::edge_weight_t >
|
||||
{
|
||||
typedef OpenMesh::TriMesh_ArrayKernelT<K> Mesh;
|
||||
typedef CGAL::OM_edge_weight_pmap<Mesh> type;
|
||||
typedef CGAL::OM_edge_weight_pmap<Mesh> const_type;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//
|
||||
// vertex_index
|
||||
//
|
||||
template <typename K>
|
||||
struct property_map<OpenMesh::TriMesh_ArrayKernelT<K>, boost::vertex_index_t >
|
||||
{
|
||||
typedef CGAL::OM_index_pmap<K, typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::vertex_descriptor> type;
|
||||
typedef CGAL::OM_index_pmap<K, typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::vertex_descriptor> const_type;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// face_index
|
||||
//
|
||||
|
||||
template <typename K>
|
||||
struct property_map<OpenMesh::TriMesh_ArrayKernelT<K>, boost::face_index_t >
|
||||
{
|
||||
typedef CGAL::OM_index_pmap<K, typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::face_descriptor> type;
|
||||
typedef CGAL::OM_index_pmap<K, typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::face_descriptor> const_type;
|
||||
};
|
||||
|
||||
//
|
||||
// edge_index
|
||||
//
|
||||
|
||||
template <typename K>
|
||||
struct property_map<OpenMesh::TriMesh_ArrayKernelT<K>, boost::edge_index_t >
|
||||
{
|
||||
typedef CGAL::OM_index_pmap<K, typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::edge_descriptor> type;
|
||||
typedef CGAL::OM_index_pmap<K, typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::edge_descriptor> const_type;
|
||||
};
|
||||
|
||||
//
|
||||
// halfedge_index
|
||||
//
|
||||
|
||||
template <typename K>
|
||||
struct property_map<OpenMesh::TriMesh_ArrayKernelT<K>, boost::halfedge_index_t >
|
||||
{
|
||||
typedef CGAL::OM_index_pmap<K, typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::halfedge_descriptor> type;
|
||||
typedef CGAL::OM_index_pmap<K, typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::halfedge_descriptor> const_type;
|
||||
};
|
||||
|
||||
|
||||
template<typename K>
|
||||
struct property_map<OpenMesh::TriMesh_ArrayKernelT<K>, boost::vertex_point_t >
|
||||
{
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel::Point_3 P;
|
||||
typedef OpenMesh::TriMesh_ArrayKernelT<K> Mesh;
|
||||
typedef CGAL::OM_point_pmap<Mesh,P> type;
|
||||
typedef type const_type;
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
namespace boost {
|
||||
|
||||
|
||||
template <typename K>
|
||||
typename boost::property_map<OpenMesh::TriMesh_ArrayKernelT<K>, boost::edge_weight_t>::const_type
|
||||
get(boost::edge_weight_t, const OpenMesh::TriMesh_ArrayKernelT<K>& sm)
|
||||
{
|
||||
return CGAL::OM_edge_weight_pmap<K>(sm);
|
||||
}
|
||||
|
||||
template <typename K>
|
||||
typename OpenMesh::TriMesh_ArrayKernelT<K>::Scalar
|
||||
get(boost::edge_weight_t, const OpenMesh::TriMesh_ArrayKernelT<K>& sm,
|
||||
const typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::edge_descriptor& e)
|
||||
{
|
||||
return CGAL::OM_edge_weight_pmap<K>(sm)[e];
|
||||
}
|
||||
|
||||
|
||||
template <typename K>
|
||||
CGAL::OM_index_pmap<K, typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::vertex_descriptor>
|
||||
get(const boost::vertex_index_t&, const OpenMesh::TriMesh_ArrayKernelT<K>&)
|
||||
{
|
||||
return CGAL::OM_index_pmap<K, typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::vertex_descriptor>();
|
||||
}
|
||||
|
||||
template <typename K>
|
||||
typename boost::property_map<OpenMesh::TriMesh_ArrayKernelT<K>, boost::face_index_t>::const_type
|
||||
get(const boost::face_index_t&, const OpenMesh::TriMesh_ArrayKernelT<K>&)
|
||||
{
|
||||
return CGAL::OM_index_pmap<K, typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::face_descriptor>();
|
||||
}
|
||||
|
||||
template <typename K>
|
||||
CGAL::OM_index_pmap<K, typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::edge_descriptor>
|
||||
get(const boost::edge_index_t&, const OpenMesh::TriMesh_ArrayKernelT<K>&)
|
||||
{
|
||||
return CGAL::OM_index_pmap<K, typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::edge_descriptor>();
|
||||
}
|
||||
|
||||
template <typename K>
|
||||
CGAL::OM_index_pmap<K, typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::halfedge_descriptor>
|
||||
get(const boost::halfedge_index_t&, const OpenMesh::TriMesh_ArrayKernelT<K>&)
|
||||
{
|
||||
return CGAL::OM_index_pmap<K, typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::halfedge_descriptor>();
|
||||
}
|
||||
|
||||
template<typename K>
|
||||
CGAL::OM_point_pmap<OpenMesh::TriMesh_ArrayKernelT<K>,
|
||||
typename CGAL::Exact_predicates_inexact_constructions_kernel::Point_3>
|
||||
get(boost::vertex_point_t, const OpenMesh::TriMesh_ArrayKernelT<K>& g)
|
||||
{
|
||||
typedef typename CGAL::Exact_predicates_inexact_constructions_kernel::Point_3 P;
|
||||
typedef OpenMesh::TriMesh_ArrayKernelT<K> Mesh;
|
||||
return CGAL::OM_point_pmap<Mesh, P>(g);
|
||||
}
|
||||
|
||||
// get for intrinsic properties
|
||||
#define CGAL_OM_INTRINSIC_PROPERTY(RET, PROP, TYPE) \
|
||||
template<typename K> \
|
||||
RET \
|
||||
get(PROP p, const OpenMesh::TriMesh_ArrayKernelT<K>& sm, \
|
||||
typename boost::graph_traits< OpenMesh::TriMesh_ArrayKernelT<K> >::TYPE x) \
|
||||
{ return get(get(p, sm), x); } \
|
||||
|
||||
CGAL_OM_INTRINSIC_PROPERTY(int, boost::vertex_index_t, vertex_descriptor)
|
||||
CGAL_OM_INTRINSIC_PROPERTY(int, boost::edge_index_t, edge_descriptor)
|
||||
CGAL_OM_INTRINSIC_PROPERTY(int, boost::halfedge_index_t, halfedge_descriptor)
|
||||
CGAL_OM_INTRINSIC_PROPERTY(int, boost::face_index_t, face_descriptor)
|
||||
// CGAL_OM_INTRINSIC_PROPERTY(std::size_t, boost::halfedge_index_t, face_descriptor)
|
||||
CGAL_OM_INTRINSIC_PROPERTY(typename CGAL::Exact_predicates_inexact_constructions_kernel::Point_3, boost::vertex_point_t, vertex_descriptor)
|
||||
|
||||
#undef CGAL_OM_INTRINSIC_PROPERTY
|
||||
|
||||
// put for intrinsic properties
|
||||
// only available for vertex_point
|
||||
|
||||
template<typename K>
|
||||
void
|
||||
put(boost::vertex_point_t p, OpenMesh::TriMesh_ArrayKernelT<K>& g,
|
||||
typename boost::graph_traits< OpenMesh::TriMesh_ArrayKernelT<K> >::vertex_descriptor vd,
|
||||
const typename K::Point& point)
|
||||
{
|
||||
put(get(p,g), vd, point);
|
||||
}
|
||||
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
||||
|
||||
#endif /* CGAL_PROPERTIES_TRIMESH_ARRAYKERNELT_H */
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
\cgalPkgPicture{barcoord_thumb.png}
|
||||
\cgalPkgSummaryBegin
|
||||
\cgalPkgAuthors{Dmitry Anisimov, David Bommes, Kai Hormann, and Pierre Alliez}
|
||||
\cgalPkgDesc{The package 2D Generalized Barycentric Coordinates offers an efficient and robust implementation of two-dimensional closed-form generalized barycentric coordinates defined for simple two-dimensional polygons. If coordinates with respect to multivariate scattered points instead of a polygon are required, please refer to natural neighbour coordinates from the package 2D and Surface Function Interpolation.}
|
||||
\cgalPkgDesc{The package 2D Generalized Barycentric Coordinates offers an efficient and robust implementation of two-dimensional closed-form generalized barycentric coordinates defined for simple two-dimensional polygons. If coordinates with respect to multivariate scattered points instead of a polygon are required, please refer to natural neighbor coordinates from the Package \ref PkgInterpolation2Summary.}
|
||||
\cgalPkgManuals{Chapter_2D_Generalized_Barycentric_Coordinates, PkgBarycentric_coordinates_2}
|
||||
\cgalPkgSummaryEnd
|
||||
\cgalPkgShortInfoBegin
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
#define _CORE_BIGFLOAT_H_
|
||||
|
||||
#include <CGAL/CORE/BigFloatRep.h>
|
||||
#include <CGAL/assertions.h>
|
||||
|
||||
namespace CORE {
|
||||
|
||||
|
|
@ -246,7 +247,7 @@ public:
|
|||
/** \note This is only the sign of the mantissa, it can be taken to be
|
||||
the sign of the BigFloat only if !(isZeroIn()). */
|
||||
int sign() const {
|
||||
assert((err() == 0 && m() == 0) || !(isZeroIn()));
|
||||
CGAL_assertion((err() == 0 && m() == 0) || !(isZeroIn()));
|
||||
return rep->signM();
|
||||
}
|
||||
/// check whether contains zero
|
||||
|
|
@ -553,7 +554,7 @@ inline bool isDivisible(double x, double y) {
|
|||
// normalizing it then we get zero.
|
||||
inline BigFloat div_exact(const BigFloat& x, const BigFloat& y) {
|
||||
BigInt z;
|
||||
assert (isDivisible(x,y));
|
||||
CGAL_assertion (isDivisible(x,y));
|
||||
unsigned long bin_x = getBinExpo(x.m());
|
||||
unsigned long bin_y = getBinExpo(y.m());
|
||||
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@
|
|||
#define _CORE_EXPR_H_
|
||||
|
||||
#include <CGAL/CORE/ExprRep.h>
|
||||
#include <CGAL/assertions.h>
|
||||
|
||||
namespace CORE {
|
||||
|
||||
|
|
@ -534,7 +535,7 @@ inline Expr rootOf(const Polynomial<NT>& p, int x, int y) {
|
|||
* */
|
||||
template <class NT>
|
||||
inline Expr radical(const NT& n, int m) {
|
||||
assert(n>=0 && m>=1);
|
||||
CGAL_assertion(n>=0 && m>=1);
|
||||
if (n == 0 || n == 1 || m == 1)
|
||||
return Expr(n);
|
||||
Polynomial<NT> Q(m);
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
#define _CORE_FILTER_H_
|
||||
|
||||
#include <CGAL/config.h>
|
||||
#include <CGAL/assertions.h>
|
||||
#include <CGAL/CORE/Real.h>
|
||||
#include <cmath>
|
||||
|
||||
|
|
@ -111,7 +112,7 @@ public:
|
|||
before call this function.) */
|
||||
int sign() const {
|
||||
#ifdef CORE_DEBUG
|
||||
assert(isOK());
|
||||
CGAL_assertion(isOK());
|
||||
#endif
|
||||
if (fpVal == 0.0)
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
|
||||
#include <new> // for placement new
|
||||
#include <cassert>
|
||||
#include <CGAL/assertions.h>
|
||||
|
||||
namespace CORE {
|
||||
|
||||
|
|
@ -96,7 +97,7 @@ void* MemoryPool< T, nObjects >::allocate(std::size_t) {
|
|||
|
||||
template< class T, int nObjects >
|
||||
void MemoryPool< T, nObjects >::free(void* t) {
|
||||
assert(t != 0);
|
||||
CGAL_assertion(t != 0);
|
||||
if (t == 0) return; // for safety
|
||||
|
||||
// recycle the object memory, by putting it back into the chain
|
||||
|
|
|
|||
|
|
@ -192,7 +192,7 @@ BiPoly<NT>::~BiPoly(){
|
|||
//Sets the input BiPoly to X^n
|
||||
template <class NT>
|
||||
void BiPoly<NT>::constructX(int n, BiPoly<NT>& P){
|
||||
assert(n>= -1);
|
||||
CGAL_assertion(n>= -1);
|
||||
P.deleteCoeffX();//Clear the present coeffecients
|
||||
Polynomial<NT> q(n);//Nominal degree n
|
||||
q.setCoeff(n,NT(1));
|
||||
|
|
@ -807,7 +807,7 @@ BiPoly<NT> & BiPoly<NT>::differentiateX() {
|
|||
|
||||
template <class NT>
|
||||
BiPoly<NT> & BiPoly<NT>::differentiateXY(int m, int n) {//m times wrt X and n times wrt Y
|
||||
assert(m >=0); assert(n >=0);
|
||||
CGAL_assertion(m >=0); CGAL_assertion(n >=0);
|
||||
for(int i=1; i <=m; i++)
|
||||
(*this).differentiateX();
|
||||
for(int i=1; i <=n; i++)
|
||||
|
|
@ -1158,7 +1158,7 @@ int Curve<NT>::verticalIntersections(const BigFloat & x, BFVecInterval & vI,
|
|||
// This returns a NULL vI, which should be caught by caller
|
||||
|
||||
Polynomial<Expr> PY = this->yExprPolynomial(x); // should be replaced
|
||||
// assert(x.isExact());
|
||||
// CGAL_assertion(x.isExact());
|
||||
// Polynomial<BigFloat> PY = yBFPolynomial(x); // unstable still
|
||||
|
||||
d = PY.getTrueDegree();
|
||||
|
|
@ -1205,9 +1205,9 @@ int Curve<NT>::plot( BigFloat eps, BigFloat x1,
|
|||
|
||||
const char* filename[] = {"data/input", "data/plot", "data/plot2"};
|
||||
|
||||
assert(eps.isExact()); // important for plotting...
|
||||
assert(x1.isExact());
|
||||
assert(y1.isExact());
|
||||
CGAL_assertion(eps.isExact()); // important for plotting...
|
||||
CGAL_assertion(x1.isExact());
|
||||
CGAL_assertion(y1.isExact());
|
||||
|
||||
ofstream outFile;
|
||||
outFile.open(filename[fileNo]); // ought to check if open is successful!
|
||||
|
|
@ -1230,7 +1230,7 @@ int Curve<NT>::plot( BigFloat eps, BigFloat x1,
|
|||
outFile << "0.99 \t 0.99 \t 0.99" << std::endl;
|
||||
outFile << 0 << "\t" << y1 << std::endl;
|
||||
outFile << 0 << "\t" << y2 << std::endl;
|
||||
// assert(eps>0)
|
||||
// CGAL_assertion(eps>0)
|
||||
int aprec = -(eps.lMSB()).toLong(); // By definition, eps.lMSB() <= lg(eps)
|
||||
|
||||
BigFloat xCurr = x1;
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@
|
|||
#include <CGAL/CORE/BigFloat.h>
|
||||
#include <CGAL/CORE/Promote.h>
|
||||
#include <vector>
|
||||
#include <CGAL/assertions.h>
|
||||
|
||||
namespace CORE {
|
||||
using namespace std;
|
||||
|
|
@ -412,7 +413,7 @@ template < class NT >
|
|||
CORE_INLINE
|
||||
const NT& Polynomial<NT>::getCoeff(int i) const {
|
||||
//if (i > degree) return NULL;
|
||||
assert(i <= degree);
|
||||
CGAL_assertion(i <= degree);
|
||||
return coeff[i];
|
||||
}
|
||||
// set functions
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ Polynomial<NT>::Polynomial(void) {
|
|||
//Creates a polynomial with nominal degree n
|
||||
template <class NT>
|
||||
Polynomial<NT>::Polynomial(int n) {
|
||||
assert(n>= -1);
|
||||
CGAL_assertion(n>= -1);
|
||||
degree = n;
|
||||
if (n == -1)
|
||||
return; // return the zero polynomial!
|
||||
|
|
@ -80,7 +80,7 @@ Polynomial<NT>::Polynomial(int n) {
|
|||
|
||||
template <class NT>
|
||||
Polynomial<NT>::Polynomial(int n, const NT * c) {
|
||||
//assert("array c has n+1 elements");
|
||||
//CGAL_assertion("array c has n+1 elements");
|
||||
degree = n;
|
||||
if (n >= 0) {
|
||||
coeff = new NT[n+1];
|
||||
|
|
@ -113,7 +113,7 @@ Polynomial<NT>::Polynomial(const Polynomial<NT> & p):degree(-1) {
|
|||
///////////////////////////////////////
|
||||
template <class NT>
|
||||
Polynomial<NT>::Polynomial(int n, const char * s[]) {
|
||||
//assert("array s has n+1 elements");
|
||||
//CGAL_assertion("array s has n+1 elements");
|
||||
degree = n;
|
||||
if (n >= 0) {
|
||||
coeff = new NT[n+1];
|
||||
|
|
@ -826,7 +826,7 @@ template <>
|
|||
CORE_INLINE
|
||||
BigFloat Polynomial<BigInt>::evalApprox(const BigFloat& /*f*/,
|
||||
const extLong& /*r*/, const extLong& /*a*/) const { // evaluation
|
||||
assert(0);
|
||||
CGAL_assertion(0);
|
||||
return BigFloat(0);
|
||||
}
|
||||
|
||||
|
|
@ -861,7 +861,7 @@ BigFloat Polynomial<BigInt>::evalApprox(const BigFloat& /*f*/,
|
|||
template <class NT>
|
||||
BigFloat Polynomial<NT>::evalExactSign(const BigFloat& val,
|
||||
const extLong& oldMSB) const {
|
||||
assert(val.isExact());
|
||||
CGAL_assertion(val.isExact());
|
||||
if (getTrueDegree() == -1)
|
||||
return BigFloat(0);
|
||||
|
||||
|
|
@ -1063,7 +1063,7 @@ Polynomial<NT> & Polynomial<NT>::differentiate() { // self-differentiation
|
|||
// multi-differentiate
|
||||
template <class NT>
|
||||
Polynomial<NT> & Polynomial<NT>::differentiate(int n) {
|
||||
assert(n >= 0);
|
||||
CGAL_assertion(n >= 0);
|
||||
for (int i=1; i<=n; i++)
|
||||
this->differentiate();
|
||||
return *this;
|
||||
|
|
@ -1128,7 +1128,7 @@ template <class NT>
|
|||
Polynomial<NT> & Polynomial<NT>::primPart() {
|
||||
// ASSERT: GCD must be provided by NT
|
||||
int d = getTrueDegree();
|
||||
assert (d >= 0);
|
||||
CGAL_assertion (d >= 0);
|
||||
if (d == 0) {
|
||||
if (coeff[0] > 0) coeff[0] = 1;
|
||||
else coeff[0] = -1;
|
||||
|
|
@ -1371,7 +1371,7 @@ Polynomial<NT> differentiate(const Polynomial<NT> & p) { // differentiate
|
|||
template <class NT>
|
||||
Polynomial<NT> differentiate(const Polynomial<NT> & p, int n) {//multi-differentiate
|
||||
Polynomial<NT> q(p);
|
||||
assert(n >= 0);
|
||||
CGAL_assertion(n >= 0);
|
||||
for (int i=1; i<=n; i++)
|
||||
q.differentiate();
|
||||
return q;
|
||||
|
|
@ -1491,7 +1491,7 @@ NT res(Polynomial<NT> p, Polynomial<NT> q) {
|
|||
template <class NT>
|
||||
NT psc(int i,Polynomial<NT> p, Polynomial<NT> q) {
|
||||
|
||||
assert(i >= 0);
|
||||
CGAL_assertion(i >= 0);
|
||||
if(i == 0)
|
||||
return res(p,q);
|
||||
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@
|
|||
#ifndef CORE_STURM_H
|
||||
#define CORE_STURM_H
|
||||
|
||||
#include <CGAL/assertions.h>
|
||||
#include "CGAL/CORE/BigFloat.h"
|
||||
#include "CGAL/CORE/Expr.h"
|
||||
#include "CGAL/CORE/poly/Poly.h"
|
||||
|
|
@ -205,7 +206,7 @@ public:
|
|||
// where sx = sign of evaluating seq[0] at x
|
||||
// PRE-CONDITION: sx != 0 and len > 0
|
||||
int signVariations(const BigFloat & x, int sx) const {
|
||||
assert((sx != 0) && (len >0));
|
||||
CGAL_assertion((sx != 0) && (len >0));
|
||||
int cnt = 0;
|
||||
int last_sign = sx;
|
||||
for (int i=1; i<=len; i++) {// Chee (4/29/04): Bug fix,
|
||||
|
|
@ -237,7 +238,7 @@ public:
|
|||
if (len <= 0) return len;
|
||||
int cnt = 0;
|
||||
int last_sign = sign(seq[0].coeff[seq[0].getTrueDegree()]);
|
||||
assert(last_sign != 0);
|
||||
CGAL_assertion(last_sign != 0);
|
||||
for (int i=1; i<=len; i++) {
|
||||
int sgn = sign(seq[i].coeff[seq[i].getTrueDegree()]);
|
||||
if (sgn*last_sign < 0)
|
||||
|
|
@ -255,7 +256,7 @@ public:
|
|||
int last_sign = sign(seq[0].coeff[seq[0].getTrueDegree()]);
|
||||
if (seq[0].getTrueDegree() % 2 != 0)
|
||||
last_sign *= -1;
|
||||
assert(last_sign != 0);
|
||||
CGAL_assertion(last_sign != 0);
|
||||
for (int i=1; i<=len; i++) {
|
||||
int parity = (seq[i].getTrueDegree() % 2 == 0) ? 1 : -1;
|
||||
int sgn = parity * sign(seq[i].coeff[seq[i].getTrueDegree()]);
|
||||
|
|
@ -275,7 +276,7 @@ public:
|
|||
// "x.makeExact(); y.makeExact()" before calling].
|
||||
///////////////////////////////////////////
|
||||
int numberOfRoots(const BigFloat &x, const BigFloat &y) const {
|
||||
assert(x <= y); // we allow x=y
|
||||
CGAL_assertion(x <= y); // we allow x=y
|
||||
if (len <= 0) return len; // return of -1 means infinity of roots!
|
||||
int signx = sign(seq[0].evalExactSign(x));
|
||||
if (x == y) return ((signx == 0) ? 1 : 0);
|
||||
|
|
@ -354,7 +355,7 @@ public:
|
|||
*/
|
||||
void isolateRoots(const BigFloat &x, const BigFloat &y,
|
||||
BFVecInterval &v) const {
|
||||
assert(x<=y);
|
||||
CGAL_assertion(x<=y);
|
||||
|
||||
int n = numberOfRoots(x,y);
|
||||
if (n == 0) return;
|
||||
|
|
@ -767,7 +768,7 @@ public:
|
|||
// says that z is a robust approximate zero).
|
||||
//
|
||||
bool smaleBoundTest(const BigFloat& z){
|
||||
assert(z.isExact()); // the bound only makes sense for exact z
|
||||
CGAL_assertion(z.isExact()); // the bound only makes sense for exact z
|
||||
|
||||
#ifdef CORE_DEBUG
|
||||
std::cout <<"Computing Smale's bound = " << std::endl;
|
||||
|
|
@ -869,7 +870,7 @@ std::cout << "In newtonRefine, input J=" << J.first
|
|||
return J;
|
||||
}
|
||||
|
||||
assert( leftSign * rightSign < 0 );
|
||||
CGAL_assertion( leftSign * rightSign < 0 );
|
||||
|
||||
//N is number of times Newton is called without checking
|
||||
// whether the result is still in the interval or not
|
||||
|
|
@ -1060,7 +1061,7 @@ std::cout << "In newtonRefine, input J=" << J.first
|
|||
<< J.first.err() << " Err at end = " << J.second.err() << std::endl;
|
||||
#endif
|
||||
|
||||
assert( (seq[0].evalExactSign(J.first) * seq[0].evalExactSign(J.second) <= 0) );
|
||||
CGAL_assertion( (seq[0].evalExactSign(J.first) * seq[0].evalExactSign(J.second) <= 0) );
|
||||
|
||||
#ifdef CORE_DEBUG_NEWTON
|
||||
if (seq[0].evalExactSign(J.first) * seq[0].evalExactSign(J.second) > 0)
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ typedef unsigned int uint;
|
|||
#include <CGAL/tuple.h>
|
||||
#include<CGAL/Exact_circular_kernel_2.h>
|
||||
#include <CGAL/Cartesian_converter.h>
|
||||
#include <CGAL/assertions.h>
|
||||
|
||||
#include <boost/utility.hpp>
|
||||
|
||||
|
|
@ -538,10 +539,10 @@ public:
|
|||
++next_s; if (next_s==map_theta.end()) next_s=map_theta.begin();
|
||||
do{
|
||||
if (current->second.first==OTRG) return;
|
||||
assert(current->second.first==SRC);
|
||||
CGAL_assertion(current->second.first==SRC);
|
||||
draw_in_ipe(Circular_arc_2(circle,*(current->second.second),*(next_s->second.second),CGAL::COUNTERCLOCKWISE));
|
||||
if (next_s->second.first==OTRG) return;
|
||||
assert(next_s->second.first==TRG);
|
||||
CGAL_assertion(next_s->second.first==TRG);
|
||||
++next_s; if (next_s==map_theta.end()) next_s=map_theta.begin();
|
||||
current=next_s;
|
||||
++next_s; if (next_s==map_theta.end()) next_s=map_theta.begin();
|
||||
|
|
@ -843,7 +844,7 @@ public:
|
|||
switch (ints.size()){
|
||||
case 1:
|
||||
ok=CGAL::assign(tmp_pt,ints[0]);
|
||||
assert(ok);
|
||||
CGAL_assertion(ok);
|
||||
points.push_back(tmp_pt);
|
||||
index=points.size()-1;
|
||||
indices[i]=index;
|
||||
|
|
@ -852,12 +853,12 @@ public:
|
|||
case 2:
|
||||
int right_ind=i<2?0:1;
|
||||
ok=CGAL::assign(tmp_pt,ints[right_ind]);
|
||||
assert(ok);
|
||||
CGAL_assertion(ok);
|
||||
points.push_back(tmp_pt);
|
||||
index=points.size()-1;
|
||||
indices[i]=index;
|
||||
ok=CGAL::assign(tmp_pt,ints[(right_ind+1)%2]);
|
||||
assert(ok);
|
||||
CGAL_assertion(ok);
|
||||
points.push_back(tmp_pt);
|
||||
index=points.size()-1;
|
||||
indices[(i+1)%4+4]=index;
|
||||
|
|
@ -900,7 +901,7 @@ public:
|
|||
*out++=build_arc(exact_circle,points[ indices[pair[1]] ].first,points[ indices[pair[0]] ].first);
|
||||
return;
|
||||
}
|
||||
assert (rem_pt==0);
|
||||
CGAL_assertion (rem_pt==0);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@ typedef unsigned int uint;
|
|||
#include <CGAL/tuple.h>
|
||||
#include<CGAL/Exact_circular_kernel_2.h>
|
||||
#include <CGAL/Cartesian_converter.h>
|
||||
#include <CGAL/assertions.h>
|
||||
#include <CGAL/use.h>
|
||||
|
||||
#include <boost/utility.hpp>
|
||||
|
||||
|
|
@ -546,10 +548,10 @@ public:
|
|||
++next_s; if (next_s==map_theta.end()) next_s=map_theta.begin();
|
||||
do{
|
||||
if (current->second.first==OTRG) return;
|
||||
assert(current->second.first==SRC);
|
||||
CGAL_assertion(current->second.first==SRC);
|
||||
draw_in_ipe(Circular_arc_2(circle,*(current->second.second),*(next_s->second.second),CGAL::COUNTERCLOCKWISE));
|
||||
if (next_s->second.first==OTRG) return;
|
||||
assert(next_s->second.first==TRG);
|
||||
CGAL_assertion(next_s->second.first==TRG);
|
||||
++next_s; if (next_s==map_theta.end()) next_s=map_theta.begin();
|
||||
current=next_s;
|
||||
++next_s; if (next_s==map_theta.end()) next_s=map_theta.begin();
|
||||
|
|
@ -848,7 +850,7 @@ public:
|
|||
switch (ints.size()){
|
||||
case 1:
|
||||
ok=CGAL::assign(tmp_pt,ints[0]);
|
||||
assert(ok);
|
||||
CGAL_assertion(ok); CGAL_USE(ok);
|
||||
points.push_back(tmp_pt);
|
||||
index=points.size()-1;
|
||||
indices[i]=index;
|
||||
|
|
@ -857,12 +859,12 @@ public:
|
|||
case 2:
|
||||
int right_ind=i<2?0:1;
|
||||
ok=CGAL::assign(tmp_pt,ints[right_ind]);
|
||||
assert(ok);
|
||||
CGAL_assertion(ok); CGAL_USE(ok);
|
||||
points.push_back(tmp_pt);
|
||||
index=points.size()-1;
|
||||
indices[i]=index;
|
||||
ok=CGAL::assign(tmp_pt,ints[(right_ind+1)%2]);
|
||||
assert(ok);
|
||||
CGAL_assertion(ok); CGAL_USE(ok);
|
||||
points.push_back(tmp_pt);
|
||||
index=points.size()-1;
|
||||
indices[(i+1)%4+4]=index;
|
||||
|
|
@ -905,7 +907,7 @@ public:
|
|||
*out++=build_arc(exact_circle,points[ indices[pair[1]] ].first,points[ indices[pair[0]] ].first);
|
||||
return;
|
||||
}
|
||||
assert (rem_pt==0);
|
||||
CGAL_assertion (rem_pt==0);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@
|
|||
|
||||
#include <CGAL/Compact_container.h>
|
||||
#include <CGAL/internal/Combinatorial_map_utility.h>
|
||||
#include <CGAL/internal/Combinatorial_map_internal_functors.h>
|
||||
#include <CGAL/internal/Combinatorial_map_group_functors.h>
|
||||
#include <CGAL/internal/Combinatorial_map_copy_functors.h>
|
||||
#include <CGAL/internal/Combinatorial_map_sewable.h>
|
||||
|
|
@ -350,6 +349,18 @@ namespace CGAL {
|
|||
bool is_empty() const
|
||||
{ return mdarts.empty(); }
|
||||
|
||||
friend std::ostream& operator<< (std::ostream& os, const Self& amap)
|
||||
{
|
||||
save_combinatorial_map(amap, os);
|
||||
return os;
|
||||
}
|
||||
|
||||
friend std::ifstream& operator>> (std::ifstream& is, Self& amap)
|
||||
{
|
||||
load_combinatorial_map(is, amap);
|
||||
return is;
|
||||
}
|
||||
|
||||
/** Create a new dart and add it to the map.
|
||||
* The marks of the darts are initialised with mmask_marks, i.e. the dart
|
||||
* is unmarked for all the marks.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,800 @@
|
|||
// Copyright (c) 2010-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$
|
||||
//
|
||||
// Author(s) : Guillaume Damiand <guillaume.damiand@liris.cnrs.fr>
|
||||
// Guillaume Castano <guillaume.castano@gmail.com>
|
||||
// Pascal Khieu <pascal.khieu@gmail.com>
|
||||
//
|
||||
#ifndef CGAL_COMBINATORIAL_MAP_SAVE_LOAD_H
|
||||
#define CGAL_COMBINATORIAL_MAP_SAVE_LOAD_H
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/property_tree/xml_parser.hpp>
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include <CGAL/Combinatorial_map.h>
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||
#include <CGAL/Cell_attribute_with_point.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <typeinfo>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
typedef Exact_predicates_inexact_constructions_kernel::Point_3 RPoint_3;
|
||||
typedef Exact_predicates_exact_constructions_kernel::Point_3 EPoint_3;
|
||||
|
||||
// Tags used in xml tree:
|
||||
// For darts:
|
||||
// <darts>
|
||||
// <d> // new dart
|
||||
// <b i="1"> neighbor dart index for beta1 </b>
|
||||
// ...
|
||||
// <v> value of dart (optional) </v>
|
||||
// </d>
|
||||
// ...
|
||||
// </darts>
|
||||
// For attributes:
|
||||
// <attributes>
|
||||
// <dimension index="1"> // new type of non void attribute
|
||||
// <type>type of the info associated</type>
|
||||
// <a> // new attribute
|
||||
// <d> dart index </d>
|
||||
// <v> value of attribute </v>
|
||||
// </a>
|
||||
// ...
|
||||
// </attributes>
|
||||
|
||||
// Here T is a Dart_const_handle so we don't need &
|
||||
template<typename T>
|
||||
void write_cmap_dart_node(boost::property_tree::ptree & /*node*/, T)
|
||||
{}
|
||||
|
||||
template<typename T>
|
||||
void write_cmap_attribute_node(boost::property_tree::ptree & /*node*/, const T&)
|
||||
{}
|
||||
|
||||
inline
|
||||
void write_cmap_attribute_node(boost::property_tree::ptree & node,
|
||||
char val)
|
||||
{node.add("v",val);}
|
||||
inline
|
||||
void write_cmap_attribute_node(boost::property_tree::ptree & node,
|
||||
unsigned char val)
|
||||
{node.add("v",val);}
|
||||
inline
|
||||
void write_cmap_attribute_node(boost::property_tree::ptree & node,
|
||||
short int val)
|
||||
{node.add("v",val);}
|
||||
inline
|
||||
void write_cmap_attribute_node(boost::property_tree::ptree & node,
|
||||
unsigned short int val)
|
||||
{node.add("v",val);}
|
||||
inline
|
||||
void write_cmap_attribute_node(boost::property_tree::ptree & node,
|
||||
int val)
|
||||
{node.add("v",val);}
|
||||
inline
|
||||
void write_cmap_attribute_node(boost::property_tree::ptree & node,
|
||||
unsigned int val)
|
||||
{node.add("v",val);}
|
||||
inline
|
||||
void write_cmap_attribute_node(boost::property_tree::ptree & node,
|
||||
long int val)
|
||||
{node.add("v",val);}
|
||||
inline
|
||||
void write_cmap_attribute_node(boost::property_tree::ptree & node,
|
||||
unsigned long int val)
|
||||
{node.add("v",val);}
|
||||
inline
|
||||
void write_cmap_attribute_node(boost::property_tree::ptree & node,
|
||||
float val)
|
||||
{node.add("v",val);}
|
||||
inline
|
||||
void write_cmap_attribute_node(boost::property_tree::ptree & node,
|
||||
double val)
|
||||
{node.add("v",val);}
|
||||
inline
|
||||
void write_cmap_attribute_node(boost::property_tree::ptree & node,
|
||||
long double val)
|
||||
{node.add("v",val);}
|
||||
inline
|
||||
void write_cmap_attribute_node(boost::property_tree::ptree & node,
|
||||
bool val)
|
||||
{node.add("v",val);}
|
||||
inline
|
||||
void write_cmap_attribute_node(boost::property_tree::ptree & node,
|
||||
const std::string& val)
|
||||
{node.add("v",val);}
|
||||
inline
|
||||
void write_cmap_attribute_node(boost::property_tree::ptree & node,
|
||||
const RPoint_3& val)
|
||||
{
|
||||
node.add("p.x",val.x());
|
||||
node.add("p.y",val.y());
|
||||
node.add("p.z",val.z());
|
||||
}
|
||||
inline
|
||||
void write_cmap_attribute_node(boost::property_tree::ptree & node,
|
||||
const EPoint_3& val)
|
||||
{
|
||||
node.add("p.x",CGAL::to_double(val.x()));
|
||||
node.add("p.y",CGAL::to_double(val.y()));
|
||||
node.add("p.z",CGAL::to_double(val.z()));
|
||||
}
|
||||
|
||||
template<typename CMap, unsigned int i,
|
||||
bool WithInfo=CGAL::Is_attribute_has_non_void_info
|
||||
<typename CMap::template Attribute_type<i>::type>::value,
|
||||
bool WithPoint=CGAL::Is_attribute_has_point
|
||||
<typename CMap::template Attribute_type<i>::type >::value >
|
||||
struct My_functor_cmap_save_one_attrib;
|
||||
|
||||
// An attrib with point and with info
|
||||
template<typename CMap, unsigned int i>
|
||||
struct My_functor_cmap_save_one_attrib<CMap, i, true, true>
|
||||
{
|
||||
static void run(const CMap* amap, boost::property_tree::ptree* ptree,
|
||||
std::map<typename CMap::Dart_const_handle, typename CMap::size_type>* myDarts)
|
||||
{
|
||||
// to check all i-cells of the map
|
||||
typename CMap::template Attribute_range<i>::type::const_iterator
|
||||
it_attrib, itend_attrib;
|
||||
it_attrib=amap->template attributes<i>().begin();
|
||||
itend_attrib=amap->template attributes<i>().end();
|
||||
|
||||
// add dimension & type
|
||||
boost::property_tree::ptree & ndim = ptree->add("dimension", "");
|
||||
ndim.put("<xmlattr>.index", i);
|
||||
ndim.add("type", typeid(typename CMap::template Attribute_type<i>::type::Info).name());
|
||||
ndim.add("type_point", typeid(RPoint_3).name());
|
||||
|
||||
// for every attribute of the dimension
|
||||
for (; it_attrib!=itend_attrib; ++it_attrib)
|
||||
{
|
||||
// make composant, dart and property node
|
||||
boost::property_tree::ptree & nattr = ndim.add("a", "");
|
||||
/* boost::property_tree::ptree & ndarts = */
|
||||
nattr.add("d", (*myDarts)[it_attrib->dart()]);
|
||||
|
||||
// update property node to add a value node (from basic or custom type
|
||||
write_cmap_attribute_node(nattr, it_attrib->info());
|
||||
write_cmap_attribute_node(nattr, it_attrib->point());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// An attribute with point and without info
|
||||
template<typename CMap, unsigned int i>
|
||||
struct My_functor_cmap_save_one_attrib<CMap, i, false, true>
|
||||
{
|
||||
static void run(const CMap* amap, boost::property_tree::ptree* ptree,
|
||||
std::map<typename CMap::Dart_const_handle, typename CMap::size_type>* myDarts)
|
||||
{
|
||||
// to check all i-cells of the map
|
||||
typename CMap::template Attribute_range<i>::type::const_iterator
|
||||
it_attrib, itend_attrib;
|
||||
it_attrib=amap->template attributes<i>().begin();
|
||||
itend_attrib=amap->template attributes<i>().end();
|
||||
|
||||
// add dimension & type
|
||||
boost::property_tree::ptree & ndim = ptree->add("dimension", "");
|
||||
ndim.put("<xmlattr>.index", i);
|
||||
ndim.add("type", "void");
|
||||
ndim.add("type_point", typeid(RPoint_3).name());
|
||||
|
||||
// for every attribute of the dimension
|
||||
for (; it_attrib!=itend_attrib; ++it_attrib)
|
||||
{
|
||||
// make composant, dart and property node
|
||||
boost::property_tree::ptree & nattr = ndim.add("a", "");
|
||||
/* boost::property_tree::ptree & ndarts = */
|
||||
nattr.add("d", (*myDarts)[it_attrib->dart()]);
|
||||
|
||||
// update property node to add a value node (from basic or custom type
|
||||
write_cmap_attribute_node(nattr, it_attrib->point());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// An attribute without point and with info
|
||||
template<typename CMap, unsigned int i>
|
||||
struct My_functor_cmap_save_one_attrib<CMap, i, true, false>
|
||||
{
|
||||
static void run(const CMap* amap, boost::property_tree::ptree* ptree,
|
||||
std::map<typename CMap::Dart_const_handle, typename CMap::size_type>* myDarts)
|
||||
{
|
||||
// to check all i-cells of the map
|
||||
typename CMap::template Attribute_range<i>::type::const_iterator
|
||||
it_attrib, itend_attrib;
|
||||
it_attrib=amap->template attributes<i>().begin();
|
||||
itend_attrib=amap->template attributes<i>().end();
|
||||
|
||||
// add dimension & type
|
||||
boost::property_tree::ptree & ndim = ptree->add("dimension", "");
|
||||
ndim.put("<xmlattr>.index", i);
|
||||
ndim.add("type", typeid(typename CMap::template Attribute_type<i>::type::Info).name());
|
||||
ndim.add("type_point", "void");
|
||||
|
||||
// for every attribute of the dimension
|
||||
for (; it_attrib!=itend_attrib; ++it_attrib)
|
||||
{
|
||||
// make composant, dart and property node
|
||||
boost::property_tree::ptree & nattr = ndim.add("a", "");
|
||||
/* boost::property_tree::ptree & ndarts = */
|
||||
nattr.add("d", (*myDarts)[it_attrib->dart()]);
|
||||
|
||||
// update property node to add a value node (from basic or custom type
|
||||
write_cmap_attribute_node(nattr, it_attrib->info());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// An attrib without point and without info
|
||||
template<typename CMap, unsigned int i>
|
||||
struct My_functor_cmap_save_one_attrib<CMap, i, false, false>
|
||||
{
|
||||
static void run(const CMap* amap, boost::property_tree::ptree* ptree,
|
||||
std::map<typename CMap::Dart_const_handle, typename CMap::size_type>* myDarts)
|
||||
{
|
||||
// to check all i-cells of the map
|
||||
typename CMap::template Attribute_range<i>::type::const_iterator
|
||||
it_attrib, itend_attrib;
|
||||
it_attrib=amap->template attributes<i>().begin();
|
||||
itend_attrib=amap->template attributes<i>().end();
|
||||
|
||||
// add dimension & type
|
||||
boost::property_tree::ptree & ndim = ptree->add("dimension", "");
|
||||
ndim.put("<xmlattr>.index", i);
|
||||
ndim.add("type", "void");
|
||||
ndim.add("type_point", "void");
|
||||
|
||||
// for every attribute of the dimension
|
||||
for (; it_attrib!=itend_attrib; ++it_attrib)
|
||||
{
|
||||
// make composant, dart and property node
|
||||
boost::property_tree::ptree & nattr = ndim.add("a", "");
|
||||
/* boost::property_tree::ptree & ndarts = */
|
||||
nattr.add("d", (*myDarts)[it_attrib->dart()]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename CMap>
|
||||
struct My_functor_cmap_save_attrib
|
||||
{
|
||||
template <unsigned int i>
|
||||
static void run(const CMap* amap, boost::property_tree::ptree* ptree,
|
||||
std::map<typename CMap::Dart_const_handle, typename CMap::size_type>* myDarts)
|
||||
{
|
||||
My_functor_cmap_save_one_attrib<CMap, i>::run(amap, ptree, myDarts);
|
||||
}
|
||||
};
|
||||
|
||||
template < class CMap >
|
||||
boost::property_tree::ptree cmap_save_darts
|
||||
(const CMap& amap, std::map<typename CMap::Dart_const_handle, typename CMap::size_type>& myDarts)
|
||||
{
|
||||
assert( myDarts.empty() );
|
||||
|
||||
// First we numbered each dart by using the std::map.
|
||||
typename CMap::Dart_range::const_iterator it(amap.darts().begin());
|
||||
for(typename CMap::size_type num=1; num<=amap.number_of_darts();
|
||||
++num, ++it)
|
||||
{
|
||||
myDarts[it] = num;
|
||||
}
|
||||
|
||||
// make a tree
|
||||
using boost::property_tree::ptree;
|
||||
ptree pt;
|
||||
|
||||
// Now we save each dart, and its neighbors.
|
||||
it=amap.darts().begin();
|
||||
for(typename CMap::size_type num=0; num<amap.number_of_darts(); ++num, ++it)
|
||||
{
|
||||
// make a dart node
|
||||
ptree & ndart = pt.add("d", "");
|
||||
|
||||
// the beta, only for non free sews
|
||||
for(unsigned int dim=1; dim<=amap.dimension; dim++)
|
||||
{
|
||||
if(!amap.is_free(it, dim))
|
||||
{
|
||||
ptree & currentNext = ndart.add("b", myDarts[amap.beta(it, dim)]);
|
||||
currentNext.put("<xmlattr>.i", dim);
|
||||
}
|
||||
}
|
||||
|
||||
// update property node to add a value node (if user defined its own
|
||||
// function)
|
||||
write_cmap_dart_node(ndart, it);
|
||||
}
|
||||
|
||||
return pt;
|
||||
}
|
||||
|
||||
template < class CMap >
|
||||
boost::property_tree::ptree cmap_save_attributes
|
||||
(const CMap& amap, std::map<typename CMap::Dart_const_handle, typename CMap::size_type>& myDarts)
|
||||
{
|
||||
using boost::property_tree::ptree;
|
||||
ptree pt;
|
||||
|
||||
// update pt adding nodes containing attributes informations
|
||||
CMap::Helper::template Foreach_enabled_attributes
|
||||
<My_functor_cmap_save_attrib<CMap> >::run(&amap, &pt, &myDarts);
|
||||
|
||||
return pt;
|
||||
}
|
||||
|
||||
template < class CMap >
|
||||
bool save_combinatorial_map(const CMap& amap, std::ostream & output)
|
||||
{
|
||||
using boost::property_tree::ptree;
|
||||
ptree data;
|
||||
|
||||
// map dart => number
|
||||
std::map<typename CMap::Dart_const_handle, typename CMap::size_type> myDarts;
|
||||
|
||||
// Get darts
|
||||
ptree pt_darts;
|
||||
pt_darts = cmap_save_darts(amap, myDarts);
|
||||
data.add_child("data.darts",pt_darts);
|
||||
|
||||
// Get attributes
|
||||
ptree pt_attr;
|
||||
pt_attr = cmap_save_attributes(amap, myDarts);
|
||||
data.add_child("data.attributes", pt_attr);
|
||||
|
||||
// save data in output
|
||||
write_xml(output, data);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template < class CMap >
|
||||
bool save_combinatorial_map(const CMap& amap, const char* filename)
|
||||
{
|
||||
std::ofstream output(filename);
|
||||
if (!output) return false;
|
||||
return save_combinatorial_map(amap, output);
|
||||
}
|
||||
|
||||
// Here T is a Dart_handle so no need of &
|
||||
template<typename T>
|
||||
void read_cmap_dart_node
|
||||
(const boost::property_tree::ptree::value_type &/*v*/, T /*val*/)
|
||||
{}
|
||||
template<typename T>
|
||||
void read_cmap_attribute_node
|
||||
(const boost::property_tree::ptree::value_type &/*v*/, T &/*val*/)
|
||||
{}
|
||||
template<> inline
|
||||
void read_cmap_attribute_node
|
||||
(const boost::property_tree::ptree::value_type &v,char &val)
|
||||
{val=boost::lexical_cast< char >(v.second.data());}
|
||||
template<> inline
|
||||
void read_cmap_attribute_node
|
||||
(const boost::property_tree::ptree::value_type &v,unsigned char &val)
|
||||
{val=boost::lexical_cast< unsigned char >(v.second.data());}
|
||||
template<> inline
|
||||
void read_cmap_attribute_node
|
||||
(const boost::property_tree::ptree::value_type &v,short int &val)
|
||||
{val=boost::lexical_cast< short int >(v.second.data());}
|
||||
template<> inline
|
||||
void read_cmap_attribute_node
|
||||
(const boost::property_tree::ptree::value_type &v,unsigned short int &val)
|
||||
{val=boost::lexical_cast< unsigned short int >(v.second.data());}
|
||||
template<> inline
|
||||
void read_cmap_attribute_node
|
||||
(const boost::property_tree::ptree::value_type &v,int &val)
|
||||
{val=boost::lexical_cast< int >(v.second.data());}
|
||||
template<> inline
|
||||
void read_cmap_attribute_node
|
||||
(const boost::property_tree::ptree::value_type &v,unsigned int &val)
|
||||
{val=boost::lexical_cast< unsigned int >(v.second.data());}
|
||||
template<> inline
|
||||
void read_cmap_attribute_node
|
||||
(const boost::property_tree::ptree::value_type &v,long int &val)
|
||||
{val=boost::lexical_cast< long int >(v.second.data());}
|
||||
template<> inline
|
||||
void read_cmap_attribute_node
|
||||
(const boost::property_tree::ptree::value_type &v,unsigned long int &val)
|
||||
{val=boost::lexical_cast< unsigned long int >(v.second.data());}
|
||||
template<> inline
|
||||
void read_cmap_attribute_node
|
||||
(const boost::property_tree::ptree::value_type &v,float &val)
|
||||
{val=boost::lexical_cast< float >(v.second.data());}
|
||||
template<> inline
|
||||
void read_cmap_attribute_node
|
||||
(const boost::property_tree::ptree::value_type &v,double &val)
|
||||
{val=boost::lexical_cast< double >(v.second.data());}
|
||||
template<> inline
|
||||
void read_cmap_attribute_node
|
||||
(const boost::property_tree::ptree::value_type &v,long double &val)
|
||||
{val=boost::lexical_cast< long double >(v.second.data());}
|
||||
template<> inline
|
||||
void read_cmap_attribute_node
|
||||
(const boost::property_tree::ptree::value_type &v,bool &val)
|
||||
{val=boost::lexical_cast< bool >(v.second.data());}
|
||||
template<> inline
|
||||
void read_cmap_attribute_node
|
||||
(const boost::property_tree::ptree::value_type &v,std::string &val)
|
||||
{val=boost::lexical_cast< std::string >(v.second.data());}
|
||||
template<> inline
|
||||
void read_cmap_attribute_node
|
||||
(const boost::property_tree::ptree::value_type &v,RPoint_3 &val)
|
||||
{
|
||||
double x=v.second.get<double>("x");
|
||||
double y=v.second.get<double>("y");
|
||||
double z=v.second.get<double>("z");
|
||||
val = RPoint_3(x,y,z);
|
||||
}
|
||||
|
||||
template<typename CMap, unsigned int i,
|
||||
bool WithInfo=CGAL::Is_attribute_has_non_void_info
|
||||
<typename CMap::template Attribute_type<i>::type>::value,
|
||||
bool WithPoint=CGAL::Is_attribute_has_point
|
||||
<typename CMap::template Attribute_type<i>::type >::value >
|
||||
struct My_functor_cmap_load_one_attrib;
|
||||
|
||||
// An attrib with point and with info
|
||||
template<typename CMap, unsigned int i>
|
||||
struct My_functor_cmap_load_one_attrib<CMap, i, true, true>
|
||||
{
|
||||
static void run(const boost::property_tree::ptree& pt, CMap* amap,
|
||||
const std::vector<typename CMap::Dart_handle>& myDarts)
|
||||
{
|
||||
BOOST_FOREACH( const boost::property_tree::ptree::value_type &v0,
|
||||
pt.get_child("data.attributes") )
|
||||
{
|
||||
// <dimension>
|
||||
if (v0.first == "dimension")
|
||||
{
|
||||
int dimension=v0.second.get("<xmlattr>.index", -1);
|
||||
|
||||
// if map.dimension == dimension saved in the xml file
|
||||
if (dimension==i)
|
||||
{
|
||||
unsigned int id_dart_cellule=0;
|
||||
std::string type = v0.second.get<std::string>("type");
|
||||
std::string type_map=std::string
|
||||
(typeid(typename CMap::template Attribute_type<i>::type::Info).name());
|
||||
|
||||
std::string ptype = v0.second.get<std::string>("type_point");
|
||||
std::string ptype_map= std::string
|
||||
(typeid(typename CMap::template Attribute_type<i>::type::Point).name());
|
||||
|
||||
// std::cout<<"ptype="<<ptype<<" and type_map="<<type_map<<std::endl;
|
||||
/* if(type!=type_map && ptype!=ptype_map)
|
||||
{
|
||||
// std::cout<<"Not loaded."<<std::endl;
|
||||
return;
|
||||
}*/
|
||||
|
||||
BOOST_FOREACH(const boost::property_tree::ptree::value_type &v1,
|
||||
v0.second )
|
||||
{
|
||||
if( v1.first == "a" )
|
||||
{
|
||||
id_dart_cellule=v1.second.get<unsigned int>("d")-1;
|
||||
|
||||
BOOST_FOREACH(const boost::property_tree::ptree::value_type &v2,
|
||||
v1.second )
|
||||
{
|
||||
if( type==type_map && v2.first == "v" )
|
||||
{
|
||||
if (myDarts[id_dart_cellule]->
|
||||
template attribute<i>()==NULL )
|
||||
amap->template set_attribute<i>
|
||||
(myDarts[id_dart_cellule],
|
||||
amap->template create_attribute<i>());
|
||||
read_cmap_attribute_node
|
||||
(v2,
|
||||
myDarts[id_dart_cellule]->
|
||||
template attribute<i>()->info());
|
||||
}
|
||||
if( ptype==ptype_map && v2.first == "p" )
|
||||
{
|
||||
if (myDarts[id_dart_cellule]->
|
||||
template attribute<i>()==NULL )
|
||||
amap->template set_attribute<i>
|
||||
(myDarts[id_dart_cellule],
|
||||
amap->template create_attribute<i>());
|
||||
read_cmap_attribute_node
|
||||
(v2,
|
||||
myDarts[id_dart_cellule]->
|
||||
template attribute<i>()->point());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// An attribute with point and without info
|
||||
template<typename CMap, unsigned int i>
|
||||
struct My_functor_cmap_load_one_attrib<CMap, i, false, true>
|
||||
{
|
||||
static void run(const boost::property_tree::ptree& pt, CMap* amap,
|
||||
const std::vector<typename CMap::Dart_handle>& myDarts)
|
||||
{
|
||||
BOOST_FOREACH( const boost::property_tree::ptree::value_type &v0,
|
||||
pt.get_child("data.attributes") )
|
||||
{
|
||||
// <dimension>
|
||||
if (v0.first == "dimension")
|
||||
{
|
||||
int dimension=v0.second.get("<xmlattr>.index", -1);
|
||||
|
||||
// if map.dimension == dimension saved in the xml file
|
||||
if (dimension==i)
|
||||
{
|
||||
unsigned int id_dart_cellule=0;
|
||||
std::string ptype = v0.second.get<std::string>("type_point");
|
||||
std::string type_map= typeid
|
||||
(typename CMap::template Attribute_type<i>::type::Point).name();
|
||||
// std::cout<<"ptype="<<ptype<<" and type_map="<<type_map<<std::endl;
|
||||
/* if(ptype!=type_map)
|
||||
{
|
||||
// std::cout<<"Not loaded."<<std::endl;
|
||||
return;
|
||||
}*/
|
||||
|
||||
BOOST_FOREACH(const boost::property_tree::ptree::value_type &v1,
|
||||
v0.second )
|
||||
{
|
||||
if( v1.first == "a" )
|
||||
{
|
||||
id_dart_cellule=v1.second.get<unsigned int>("d")-1;
|
||||
|
||||
BOOST_FOREACH(const boost::property_tree::ptree::value_type &v2,
|
||||
v1.second )
|
||||
{
|
||||
if( v2.first == "p" )
|
||||
{
|
||||
if (myDarts[id_dart_cellule]->
|
||||
template attribute<i>()==NULL )
|
||||
amap->template set_attribute<i>
|
||||
(myDarts[id_dart_cellule],
|
||||
amap->template create_attribute<i>());
|
||||
|
||||
read_cmap_attribute_node
|
||||
(v2,
|
||||
myDarts[id_dart_cellule]->
|
||||
template attribute<i>()->point());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// An attribute without point and with info
|
||||
template<typename CMap, unsigned int i>
|
||||
struct My_functor_cmap_load_one_attrib<CMap, i, true, false>
|
||||
{
|
||||
static void run(const boost::property_tree::ptree& pt, CMap* amap,
|
||||
const std::vector<typename CMap::Dart_handle>& myDarts)
|
||||
{
|
||||
BOOST_FOREACH( const boost::property_tree::ptree::value_type &v0,
|
||||
pt.get_child("data.attributes") )
|
||||
{
|
||||
// <dimension>
|
||||
if (v0.first == "dimension")
|
||||
{
|
||||
int dimension=v0.second.get("<xmlattr>.index", -1);
|
||||
|
||||
// if map.dimension == dimension saved in the xml file
|
||||
if (dimension==i)
|
||||
{
|
||||
unsigned int id_dart_cellule=0;
|
||||
std::string ptype = v0.second.get<std::string>("type");
|
||||
std::string type_map= typeid
|
||||
(typename CMap::template Attribute_type<i>::type::Info).name();
|
||||
// std::cout<<"ptype="<<ptype<<" and type_map="<<type_map<<std::endl;
|
||||
/* if(ptype!=type_map)
|
||||
{
|
||||
// std::cout<<"Not loaded."<<std::endl;
|
||||
return;
|
||||
} */
|
||||
|
||||
BOOST_FOREACH(const boost::property_tree::ptree::value_type &v1,
|
||||
v0.second )
|
||||
{
|
||||
if( v1.first == "a" )
|
||||
{
|
||||
id_dart_cellule=v1.second.get<unsigned int>("d")-1;
|
||||
|
||||
BOOST_FOREACH(const boost::property_tree::ptree::value_type &v2,
|
||||
v1.second )
|
||||
{
|
||||
if( v2.first == "v" )
|
||||
{
|
||||
if (myDarts[id_dart_cellule]->
|
||||
template attribute<i>()==NULL )
|
||||
amap->template set_attribute<i>
|
||||
(myDarts[id_dart_cellule],
|
||||
amap->template create_attribute<i>());
|
||||
read_cmap_attribute_node
|
||||
(v2,
|
||||
myDarts[id_dart_cellule]->
|
||||
template attribute<i>()->info());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// An attribute without point and without info
|
||||
template<typename CMap, unsigned int i>
|
||||
struct My_functor_cmap_load_one_attrib<CMap, i, false, false>
|
||||
{
|
||||
static void run(const boost::property_tree::ptree& pt, CMap* amap,
|
||||
const std::vector<typename CMap::Dart_handle>& myDarts)
|
||||
{
|
||||
BOOST_FOREACH( const boost::property_tree::ptree::value_type &v0,
|
||||
pt.get_child("data.attributes") )
|
||||
{
|
||||
// <dimension>
|
||||
if (v0.first == "dimension")
|
||||
{
|
||||
int dimension=v0.second.get("<xmlattr>.index", -1);
|
||||
|
||||
// if map.dimension == dimension saved in the xml file
|
||||
if (dimension==i)
|
||||
{
|
||||
unsigned int id_dart_cellule=0;
|
||||
|
||||
BOOST_FOREACH(const boost::property_tree::ptree::value_type &v1,
|
||||
v0.second )
|
||||
{
|
||||
if( v1.first == "a" )
|
||||
{
|
||||
id_dart_cellule=v1.second.get<unsigned int>("d")-1;
|
||||
|
||||
if (myDarts[id_dart_cellule]->
|
||||
template attribute<i>()==NULL )
|
||||
amap->template set_attribute<i>
|
||||
(myDarts[id_dart_cellule],
|
||||
amap->template create_attribute<i>());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/** Functor called to load i-attributes.
|
||||
* @param pt a boost::property_tree::ptree load from an xml file
|
||||
* @param amap a pointer to the map to load into
|
||||
* @param myDarts an array of Dart_handle st myDarts[i] is the ith dart.
|
||||
*/
|
||||
template<class CMap>
|
||||
struct My_functor_cmap_load_attrib
|
||||
{
|
||||
template <unsigned int i>
|
||||
static void run(const boost::property_tree::ptree& pt, CMap* amap,
|
||||
const std::vector<typename CMap::Dart_handle>& myDarts)
|
||||
{
|
||||
My_functor_cmap_load_one_attrib<CMap, i>::run(pt, amap, myDarts);
|
||||
}
|
||||
};
|
||||
|
||||
template < class CMap >
|
||||
bool cmap_load_darts(boost::property_tree::ptree &pt, CMap& amap,
|
||||
std::vector<typename CMap::Dart_handle>& myDarts)
|
||||
{
|
||||
// use a boost::property_tree
|
||||
using boost::property_tree::ptree;
|
||||
|
||||
// make darts
|
||||
BOOST_FOREACH( const ptree::value_type &v, pt.get_child("data.darts") )
|
||||
{
|
||||
if( v.first == "d" )
|
||||
myDarts.push_back(amap.create_dart());
|
||||
}
|
||||
|
||||
// update beta links
|
||||
unsigned int index;
|
||||
unsigned int currentDartInt = 0;
|
||||
unsigned int nextDartInt;
|
||||
|
||||
BOOST_FOREACH( const ptree::value_type &v, pt.get_child("data.darts") )
|
||||
{
|
||||
if( v.first == "d" )
|
||||
{
|
||||
BOOST_FOREACH( const ptree::value_type &v2, v.second )
|
||||
{
|
||||
if (v2.first == "b")
|
||||
{
|
||||
index = v2.second.get("<xmlattr>.i", 0);
|
||||
nextDartInt = boost::lexical_cast< int >(v2.second.data())-1;
|
||||
|
||||
if ( index<=amap.dimension )
|
||||
{
|
||||
// A->B
|
||||
amap.basic_link_beta(myDarts[currentDartInt],
|
||||
myDarts[nextDartInt],
|
||||
index);
|
||||
|
||||
//B->A
|
||||
amap.basic_link_beta(myDarts[nextDartInt],
|
||||
myDarts[currentDartInt],
|
||||
CGAL_BETAINV(index));
|
||||
}
|
||||
}
|
||||
else if (v2.first=="v")
|
||||
read_cmap_dart_node(v2,myDarts[currentDartInt]);
|
||||
}
|
||||
}
|
||||
++currentDartInt;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template < class CMap >
|
||||
void cmap_load_attributes(const boost::property_tree::ptree& pt, CMap& amap,
|
||||
const std::vector<typename CMap::Dart_handle>& myDarts)
|
||||
{
|
||||
CMap::Helper::template Foreach_enabled_attributes
|
||||
<My_functor_cmap_load_attrib<CMap> >::run(pt,&amap,myDarts);
|
||||
}
|
||||
|
||||
template < class CMap >
|
||||
bool load_combinatorial_map(std::ifstream & input, CMap& amap)
|
||||
{
|
||||
using boost::property_tree::ptree;
|
||||
ptree pt;
|
||||
read_xml(input, pt);
|
||||
std::vector<typename CMap::Dart_handle> myDarts;
|
||||
cmap_load_darts(pt,amap,myDarts);
|
||||
cmap_load_attributes(pt,amap,myDarts);
|
||||
return true;
|
||||
}
|
||||
|
||||
template < class CMap >
|
||||
bool load_combinatorial_map(const char* filename, CMap& amap)
|
||||
{
|
||||
std::ifstream input(filename);
|
||||
if (!input) return false;
|
||||
return load_combinatorial_map(input, amap);
|
||||
}
|
||||
|
||||
} // namespace CGAL
|
||||
|
||||
#endif // CGAL_COMBINATORIAL_MAP_SAVE_LOAD_H //
|
||||
// EOF //
|
||||
|
|
@ -55,14 +55,10 @@ bool test2D()
|
|||
dh = map.create_dart ();
|
||||
dh2 = map.create_dart();
|
||||
|
||||
if (!map.is_dart_used(dh) ) return false;
|
||||
|
||||
if ( map.is_valid() ) cout << "Map valid." << endl;
|
||||
cout << "Nombre de brins : " << map.number_of_darts() << endl;
|
||||
map.clear();
|
||||
|
||||
if ( map.is_dart_used(dh) ) return false;
|
||||
|
||||
cout << "***************************** TEST BASIC CREATION 2D DONE."
|
||||
<< endl;
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include <CGAL/Polyhedron_incremental_builder_3.h>
|
||||
#include <CGAL/Origin.h>
|
||||
#include <CGAL/convex_hull_3.h>
|
||||
#include <CGAL/assertions.h>
|
||||
|
||||
// For interior_polyhedron_3
|
||||
#include <CGAL/Convex_hull_3/dual/interior_polyhedron_3.h>
|
||||
|
|
@ -87,7 +88,7 @@ namespace CGAL
|
|||
for (Vertex_const_iterator it = _primal.vertices_begin();
|
||||
it != _primal.vertices_end(); ++it)
|
||||
{
|
||||
assert (it->is_bivalent() == false);
|
||||
CGAL_assertion (it->is_bivalent() == false);
|
||||
|
||||
typename Polyhedron::Halfedge_around_vertex_const_circulator
|
||||
h0 = it->vertex_begin(), hf = h0;
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
#include <CGAL/QP_models.h>
|
||||
#include <limits>
|
||||
#include <CGAL/number_utils.h>
|
||||
#include <CGAL/assertions.h>
|
||||
|
||||
// Description taken from http://www.qhull.org/html/qhalf.htm
|
||||
|
||||
|
|
@ -109,10 +110,10 @@ class Interior_polyhedron_3 {
|
|||
const double cj = CGAL::to_double(plane.c());
|
||||
const double dj = CGAL::to_double(plane.d());
|
||||
|
||||
assert(!isinf(aj));
|
||||
assert(!isinf(bj));
|
||||
assert(!isinf(cj));
|
||||
assert(!isinf(dj));
|
||||
CGAL_assertion(!isinf(aj));
|
||||
CGAL_assertion(!isinf(bj));
|
||||
CGAL_assertion(!isinf(cj));
|
||||
CGAL_assertion(!isinf(dj));
|
||||
|
||||
// plane defined the halfspace: aj * x1 + bj * x2 + cj * x3 + dj <= 0
|
||||
// <=> - (aj * x1 + bj * x2 + cj * x3 + dj) >= 0
|
||||
|
|
|
|||
|
|
@ -552,7 +552,7 @@ ch_quickhull_3_scan(TDS_2& tds,
|
|||
border.erase(it);
|
||||
while(! border.empty()){
|
||||
it = border.find(e.first->vertex(TDS_2::ccw(e.second)));
|
||||
assert(it != border.end());
|
||||
CGAL_ch_assertion(it != border.end());
|
||||
e = it->second;
|
||||
e.first->info() = 0;
|
||||
edges.push_back(e);
|
||||
|
|
|
|||
|
|
@ -35,7 +35,6 @@ function(configure_doxygen_package CGAL_PACKAGE_NAME)
|
|||
file(APPEND ${CGAL_DOC_PACKAGE_DEFAULTS} "GENERATE_BUGLIST = NO\n")
|
||||
endif()
|
||||
|
||||
file(APPEND ${CGAL_DOC_PACKAGE_DEFAULTS} "IMAGE_PATH = ${CGAL_PACKAGE_DIR}/doc/${CGAL_PACKAGE_NAME}/fig\n")
|
||||
file(APPEND ${CGAL_DOC_PACKAGE_DEFAULTS} "EXAMPLE_PATH = ${CGAL_PACKAGE_DIR}/examples\n")
|
||||
file(APPEND ${CGAL_DOC_PACKAGE_DEFAULTS} "GENERATE_TAGFILE = ${CGAL_DOC_TAG_GEN_DIR}/${CGAL_PACKAGE_NAME}.tag\n")
|
||||
file(APPEND ${CGAL_DOC_PACKAGE_DEFAULTS} "STRIP_FROM_PATH = ${CGAL_PACKAGE_DIR}/doc/${CGAL_PACKAGE_NAME}/\n")
|
||||
|
|
@ -44,19 +43,45 @@ function(configure_doxygen_package CGAL_PACKAGE_NAME)
|
|||
file(APPEND ${CGAL_DOC_PACKAGE_DEFAULTS} "STRIP_FROM_INC_PATH += ${CGAL_PACKAGE_DIR}/include/\n")
|
||||
file(APPEND ${CGAL_DOC_PACKAGE_DEFAULTS} "ALIASES += \"cgalPkgDescriptionBegin{2}=\\details \"\n")
|
||||
file(APPEND ${CGAL_DOC_PACKAGE_DEFAULTS} "ALIASES += \"cgalPkgManuals{2}=<BR>\"\n")
|
||||
|
||||
# figure out the dependencies
|
||||
if(EXISTS ${CGAL_PACKAGE_DIR}/doc/${CGAL_PACKAGE_NAME}/dependencies)
|
||||
file(STRINGS ${CGAL_PACKAGE_DIR}/doc/${CGAL_PACKAGE_NAME}/dependencies DEPENDENCIES)
|
||||
|
||||
# IMAGE_PATH is set by default. For Documentation, we generate the extra path using packages.txt
|
||||
set(IMAGE_PATH_VALUES "IMAGE_PATH = ${CGAL_PACKAGE_DIR}/doc/${CGAL_PACKAGE_NAME}/fig")
|
||||
set(DEPENDENCIES "")
|
||||
# figure out the dependencies, using the file `dependencies` or `packages.txt` for Documentation
|
||||
if (${CGAL_PACKAGE_NAME} STREQUAL "Documentation")
|
||||
set(PackageFile ${CGAL_PACKAGE_DIR}/doc/${CGAL_PACKAGE_NAME}/packages.txt)
|
||||
file(READ ${PackageFile} Entries)
|
||||
string(REPLACE "\n" ";" EntriesAsList ${Entries})
|
||||
foreach(Line ${EntriesAsList})
|
||||
if("${Line}" MATCHES "^\\\\package_listing{.+}$")
|
||||
string(REGEX REPLACE "^\\\\package_listing{(.*/)?(.+)}$" "\\2" PKG "${Line}")
|
||||
list(APPEND DEPENDENCIES ${PKG})
|
||||
# update IMAGE_PATH
|
||||
SET(PKG_DIR "${PKG}")
|
||||
if("${Line}" MATCHES "^\\\\package_listing{.+/.+}$")
|
||||
string(REGEX REPLACE "^\\\\package_listing{(.+)/.+}$" "\\1" PKG_DIR "${Line}")
|
||||
endif()
|
||||
SET(IMG_DIR "${CMAKE_SOURCE_DIR}/${PKG_DIR}/doc/${PKG}/fig")
|
||||
if(EXISTS ${IMG_DIR})
|
||||
string(CONCAT IMAGE_PATH_VALUES "${IMAGE_PATH_VALUES}" " \\\n ${IMG_DIR}" )
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
set(DOCUMENTATION_DEPENDENCIES ${DEPENDENCIES} PARENT_SCOPE)
|
||||
else()
|
||||
set(DEPENDENCIES "")
|
||||
if(EXISTS ${CGAL_PACKAGE_DIR}/doc/${CGAL_PACKAGE_NAME}/dependencies)
|
||||
file(STRINGS ${CGAL_PACKAGE_DIR}/doc/${CGAL_PACKAGE_NAME}/dependencies DEPENDENCIES)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
foreach(depend ${DEPENDENCIES})
|
||||
file(APPEND ${CGAL_DOC_PACKAGE_DEFAULTS}
|
||||
"TAGFILES += ${CGAL_DOC_TAG_DIR}/${depend}.tag=../${depend}\n")
|
||||
endforeach()
|
||||
|
||||
#now write IMAGE_PATH
|
||||
file(APPEND ${CGAL_DOC_PACKAGE_DEFAULTS} "${IMAGE_PATH_VALUES}\n")
|
||||
|
||||
configure_file(${CGAL_PACKAGE_DIR}/doc/${CGAL_PACKAGE_NAME}/Doxyfile.in
|
||||
${CGAL_DOC_DXY_DIR}/${CGAL_PACKAGE_NAME}.dxy)
|
||||
|
||||
|
|
@ -197,8 +222,7 @@ if(DOXYGEN_FOUND)
|
|||
set_target_properties(Documentation_doc PROPERTIES FOLDER Documentation)
|
||||
|
||||
# hard-code that doc depends on all packages
|
||||
file(STRINGS ${CMAKE_SOURCE_DIR}/Documentation/doc/Documentation/dependencies DEPENDENCIES)
|
||||
foreach(depend ${DEPENDENCIES})
|
||||
foreach(depend ${DOCUMENTATION_DEPENDENCIES})
|
||||
add_dependencies(doc_pre ${depend}_internal_doxygen_run)
|
||||
add_dependencies(doc_post ${depend}_copy_doc_tags)
|
||||
add_dependencies(${depend}_copy_doc_tags doc_pre)
|
||||
|
|
|
|||
|
|
@ -30,99 +30,3 @@ SEARCHENGINE = true
|
|||
ALIASES += "cgalPkgDescriptionBegin{2}=\subsection \2 \1"
|
||||
ALIASES += "cgalPkgManuals{2}=<div class=\"PkgManuals\"> <span> \ref \1 \"User Manual\" </span> <span style=\"padding-left: 20px;\">\ref \2 \"Reference Manual\" </span> </div>"
|
||||
ALIASES += "cgalReleaseNumber=${CGAL_CREATED_VERSION_NUM}"
|
||||
|
||||
# all image paths, maybe auto-generate this?
|
||||
IMAGE_PATH = ${CMAKE_SOURCE_DIR}/Documentation/doc/Documentation/fig \
|
||||
${CMAKE_SOURCE_DIR}/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/fig \
|
||||
${CMAKE_SOURCE_DIR}/Algebraic_foundations/doc/Algebraic_foundations/fig \
|
||||
${CMAKE_SOURCE_DIR}/AABB_tree/doc/AABB_tree/fig \
|
||||
${CMAKE_SOURCE_DIR}/Polygon/doc/Polygon/fig \
|
||||
${CMAKE_SOURCE_DIR}/Polygon_mesh_processing/doc/Polygon_mesh_processing/fig \
|
||||
${CMAKE_SOURCE_DIR}/Polyline_simplification_2/doc/Polyline_simplification_2/fig \
|
||||
${CMAKE_SOURCE_DIR}/Number_types/doc/Number_types/fig \
|
||||
${CMAKE_SOURCE_DIR}/Alpha_shapes_2/doc/Alpha_shapes_2/fig \
|
||||
${CMAKE_SOURCE_DIR}/Alpha_shapes_3/doc/Alpha_shapes_3/fig \
|
||||
${CMAKE_SOURCE_DIR}/Apollonius_graph_2/doc/Apollonius_graph_2/fig \
|
||||
${CMAKE_SOURCE_DIR}/Bounding_volumes/doc/Bounding_volumes/fig \
|
||||
${CMAKE_SOURCE_DIR}/Inscribed_areas/doc/Inscribed_areas/fig \
|
||||
${CMAKE_SOURCE_DIR}/Matrix_search/doc/Matrix_search/fig \
|
||||
${CMAKE_SOURCE_DIR}/Box_intersection_d/doc/Box_intersection_d/fig \
|
||||
${CMAKE_SOURCE_DIR}/CGAL_ipelets/doc/CGAL_ipelets/fig \
|
||||
${CMAKE_SOURCE_DIR}/Circulator/doc/Circulator/fig \
|
||||
${CMAKE_SOURCE_DIR}/Convex_decomposition_3/doc/Convex_decomposition_3/fig \
|
||||
${CMAKE_SOURCE_DIR}/Convex_hull_2/doc/Convex_hull_2/fig \
|
||||
${CMAKE_SOURCE_DIR}/Convex_hull_3/doc/Convex_hull_3/fig \
|
||||
${CMAKE_SOURCE_DIR}/Convex_hull_d/doc/Convex_hull_d/fig \
|
||||
${CMAKE_SOURCE_DIR}/Envelope_2/doc/Envelope_2/fig \
|
||||
${CMAKE_SOURCE_DIR}/Envelope_3/doc/Envelope_3/fig \
|
||||
${CMAKE_SOURCE_DIR}/Generator/doc/Generator/fig \
|
||||
${CMAKE_SOURCE_DIR}/Geomview/doc/Geomview/fig \
|
||||
${CMAKE_SOURCE_DIR}/GraphicsView/doc/GraphicsView/fig \
|
||||
${CMAKE_SOURCE_DIR}/HalfedgeDS/doc/HalfedgeDS/fig \
|
||||
${CMAKE_SOURCE_DIR}/BGL/doc/BGL/fig \
|
||||
${CMAKE_SOURCE_DIR}/Combinatorial_map/doc/Combinatorial_map/fig \
|
||||
${CMAKE_SOURCE_DIR}/Linear_cell_complex/doc/Linear_cell_complex/fig \
|
||||
${CMAKE_SOURCE_DIR}/Interval_skip_list/doc/Interval_skip_list/fig \
|
||||
${CMAKE_SOURCE_DIR}/Nef_2/doc/Nef_2/fig \
|
||||
${CMAKE_SOURCE_DIR}/Nef_S2/doc/Nef_S2/fig \
|
||||
${CMAKE_SOURCE_DIR}/Nef_3/doc/Nef_3/fig \
|
||||
${CMAKE_SOURCE_DIR}/QP_solver/doc/QP_solver/fig \
|
||||
${CMAKE_SOURCE_DIR}/Mesh_2/doc/Mesh_2/fig \
|
||||
${CMAKE_SOURCE_DIR}/Surface_mesher/doc/Surface_mesher/fig \
|
||||
${CMAKE_SOURCE_DIR}/Mesh_3/doc/Mesh_3/fig \
|
||||
${CMAKE_SOURCE_DIR}/Jet_fitting_3/doc/Jet_fitting_3/fig \
|
||||
${CMAKE_SOURCE_DIR}/Minkowski_sum_2/doc/Minkowski_sum_2/fig \
|
||||
${CMAKE_SOURCE_DIR}/Minkowski_sum_3/doc/Minkowski_sum_3/fig \
|
||||
${CMAKE_SOURCE_DIR}/Miscellany/doc/Miscellany/fig \
|
||||
${CMAKE_SOURCE_DIR}/Modular_arithmetic/doc/Modular_arithmetic/fig \
|
||||
${CMAKE_SOURCE_DIR}/Partition_2/doc/Partition_2/fig \
|
||||
${CMAKE_SOURCE_DIR}/Interpolation/doc/Interpolation/fig \
|
||||
${CMAKE_SOURCE_DIR}/Kernel_23/doc/Kernel_23/fig \
|
||||
${CMAKE_SOURCE_DIR}/Circular_kernel_2/doc/Circular_kernel_2/fig \
|
||||
${CMAKE_SOURCE_DIR}/Circular_kernel_3/doc/Circular_kernel_3/fig \
|
||||
${CMAKE_SOURCE_DIR}/Algebraic_kernel_d/doc/Algebraic_kernel_d/fig \
|
||||
${CMAKE_SOURCE_DIR}/Kernel_d/doc/Kernel_d/fig \
|
||||
${CMAKE_SOURCE_DIR}/Point_set_2/doc/Point_set_2/fig \
|
||||
${CMAKE_SOURCE_DIR}/SearchStructures/doc/SearchStructures/fig \
|
||||
${CMAKE_SOURCE_DIR}/Polytope_distance_d/doc/Polytope_distance_d/fig \
|
||||
${CMAKE_SOURCE_DIR}/Polyhedron/doc/Polyhedron/fig \
|
||||
${CMAKE_SOURCE_DIR}/Polynomial/doc/Polynomial/fig \
|
||||
${CMAKE_SOURCE_DIR}/Principal_component_analysis/doc/Principal_component_analysis/fig \
|
||||
${CMAKE_SOURCE_DIR}/STL_Extension/doc/STL_Extension/fig \
|
||||
${CMAKE_SOURCE_DIR}/Skin_surface_3/doc/Skin_surface_3/fig \
|
||||
${CMAKE_SOURCE_DIR}/Snap_rounding_2/doc/Snap_rounding_2/fig \
|
||||
${CMAKE_SOURCE_DIR}/Arrangement_on_surface_2/doc/Sweep_line_2/fig \
|
||||
${CMAKE_SOURCE_DIR}/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/fig \
|
||||
${CMAKE_SOURCE_DIR}/Boolean_set_operations_2/doc/Boolean_set_operations_2/fig \
|
||||
${CMAKE_SOURCE_DIR}/Triangulation_2/doc/TDS_2/fig \
|
||||
${CMAKE_SOURCE_DIR}/Triangulation_2/doc/Triangulation_2/fig \
|
||||
${CMAKE_SOURCE_DIR}/Triangulation_3/doc/TDS_3/fig \
|
||||
${CMAKE_SOURCE_DIR}/Triangulation_3/doc/Triangulation_3/fig \
|
||||
${CMAKE_SOURCE_DIR}/Triangulation/doc/Triangulation/fig \
|
||||
${CMAKE_SOURCE_DIR}/Ridges_3/doc/Ridges_3/fig \
|
||||
${CMAKE_SOURCE_DIR}/Point_set_processing_3/doc/Point_set_processing_3/fig \
|
||||
${CMAKE_SOURCE_DIR}/Point_set_processing_3/doc/Property_map/fig \
|
||||
${CMAKE_SOURCE_DIR}/Point_set_shape_detection_3/doc/Point_set_shape_detection_3/fig \
|
||||
${CMAKE_SOURCE_DIR}/Kinetic_data_structures/doc/Kinetic_framework/fig \
|
||||
${CMAKE_SOURCE_DIR}/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/fig \
|
||||
${CMAKE_SOURCE_DIR}/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/fig \
|
||||
${CMAKE_SOURCE_DIR}/Scale_space_reconstruction_3/doc/Scale_space_reconstruction_3/fig \
|
||||
${CMAKE_SOURCE_DIR}/Spatial_searching/doc/Spatial_searching/fig \
|
||||
${CMAKE_SOURCE_DIR}/Spatial_sorting/doc/Spatial_sorting/fig \
|
||||
${CMAKE_SOURCE_DIR}/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/fig \
|
||||
${CMAKE_SOURCE_DIR}/Segment_Delaunay_graph_Linf_2/doc/Segment_Delaunay_graph_Linf_2/fig \
|
||||
${CMAKE_SOURCE_DIR}/Straight_skeleton_2/doc/Straight_skeleton_2/fig \
|
||||
${CMAKE_SOURCE_DIR}/Visibility_2/doc/Visibility_2/fig \
|
||||
${CMAKE_SOURCE_DIR}/Voronoi_diagram_2/doc/Voronoi_diagram_2/fig \
|
||||
${CMAKE_SOURCE_DIR}/Surface_mesh_simplification/doc/Surface_mesh_simplification/fig \
|
||||
${CMAKE_SOURCE_DIR}/Surface_mesh_skeletonization/doc/Surface_mesh_skeletonization/fig \
|
||||
${CMAKE_SOURCE_DIR}/Surface_mesh_segmentation/doc/Surface_mesh_segmentation/fig \
|
||||
${CMAKE_SOURCE_DIR}/Subdivision_method_3/doc/Subdivision_method_3/fig \
|
||||
${CMAKE_SOURCE_DIR}/Surface_mesh_parameterization/doc/Surface_mesh_parameterization/fig \
|
||||
${CMAKE_SOURCE_DIR}/Surface_mesh/doc/Surface_mesh/fig \
|
||||
${CMAKE_SOURCE_DIR}/Surface_reconstruction_points_3/doc/Surface_reconstruction_points_3/fig \
|
||||
${CMAKE_SOURCE_DIR}/Stream_lines_2/doc/Stream_lines_2/fig \
|
||||
${CMAKE_SOURCE_DIR}/Stream_support/doc/Stream_support/fig \
|
||||
${CMAKE_SOURCE_DIR}/Surface_modeling/doc/Surface_modeling/fig \
|
||||
${CMAKE_SOURCE_DIR}/Barycentric_coordinates_2/doc/Barycentric_coordinates_2/fig \
|
||||
${CMAKE_SOURCE_DIR}/Surface_mesh_shortest_path/doc/Surface_mesh_shortest_path/fig \
|
||||
|
|
|
|||
|
|
@ -159,7 +159,7 @@ In order to build the \cgal libraries, you need a \cpp compiler.
|
|||
|\sc{Gnu} `g++` 4.1 or later\cgalFootnote{<A HREF="http://gcc.gnu.org/">`http://gcc.gnu.org/`</A>} | Linux / MacOS X |
|
||||
| | \sc{MS} Windows 95/98/2000/XP/NT4 |
|
||||
| \sc{Intel} `C++` 15.0\cgalFootnote{<A HREF="http://software.intel.com/en-us/intel-compilers/">`http://software.intel.com/en-us/intel-compilers/`</A>} | Linux |
|
||||
|\sc{MS} Visual `C++` 10.0, 11.0, 12.0 (\sc{Visual Studio} 2010, 2012, and 2013)\cgalFootnote{<A HREF="http://msdn.microsoft.com/en-us/vstudio/">`http://msdn.microsoft.com/en-us/vstudio/`</A>} | \sc{MS} Windows 95/98/2000/XP/NT4/Vista/7/8 |
|
||||
|\sc{MS} Visual `C++` 10.0, 11.0, 12.0, 14.0 (\sc{Visual Studio} 2010, 2012, 2013, and 2015)\cgalFootnote{<A HREF="http://msdn.microsoft.com/en-us/vstudio/">`http://msdn.microsoft.com/en-us/vstudio/`</A>} | \sc{MS} Windows 95/98/2000/XP/NT4/Vista/7/8 |
|
||||
| `Clang` \cgalFootnote{<A HREF="http://clang.llvm.org/">`http://clang.llvm.org/`</A>} compiler version 3.5 and 3.6.2 | Linux / MacOS X |
|
||||
| Apple `Clang` compiler version 6.0 and 4.2 | MacOS X |
|
||||
|
||||
|
|
|
|||
|
|
@ -1,97 +0,0 @@
|
|||
Algebraic_foundations
|
||||
Advancing_front_surface_reconstruction
|
||||
AABB_tree
|
||||
Polygon
|
||||
Number_types
|
||||
Alpha_shapes_2
|
||||
Alpha_shapes_3
|
||||
Apollonius_graph_2
|
||||
Bounding_volumes
|
||||
Inscribed_areas
|
||||
Matrix_search
|
||||
Box_intersection_d
|
||||
CGAL_ipelets
|
||||
Circulator
|
||||
Convex_decomposition_3
|
||||
Convex_hull_2
|
||||
Convex_hull_3
|
||||
Convex_hull_d
|
||||
Envelope_2
|
||||
Envelope_3
|
||||
Generator
|
||||
Geomview
|
||||
GraphicsView
|
||||
HalfedgeDS
|
||||
BGL
|
||||
Combinatorial_map
|
||||
Linear_cell_complex
|
||||
Interval_skip_list
|
||||
Nef_2
|
||||
Nef_S2
|
||||
Nef_3
|
||||
QP_solver
|
||||
Mesh_2
|
||||
Surface_mesher
|
||||
Mesh_3
|
||||
Jet_fitting_3
|
||||
Minkowski_sum_2
|
||||
Minkowski_sum_3
|
||||
Miscellany
|
||||
Modular_arithmetic
|
||||
Partition_2
|
||||
Interpolation
|
||||
Kernel_23
|
||||
Circular_kernel_2
|
||||
Circular_kernel_3
|
||||
Algebraic_kernel_d
|
||||
Kernel_d
|
||||
Point_set_2
|
||||
SearchStructures
|
||||
Surface_mesh_skeletonization
|
||||
Polytope_distance_d
|
||||
Polyhedron
|
||||
Polynomial
|
||||
Principal_component_analysis
|
||||
STL_Extension
|
||||
Skin_surface_3
|
||||
Snap_rounding_2
|
||||
Sweep_line_2
|
||||
Arrangement_on_surface_2
|
||||
Boolean_set_operations_2
|
||||
TDS_2
|
||||
Triangulation_2
|
||||
TDS_3
|
||||
Triangulation_3
|
||||
Triangulation
|
||||
Ridges_3
|
||||
Point_set_processing_3
|
||||
Point_set_shape_detection_3
|
||||
Polyline_simplification_2
|
||||
Property_map
|
||||
Kinetic_framework
|
||||
Kinetic_data_structures
|
||||
Periodic_2_triangulation_2
|
||||
Periodic_3_triangulation_3
|
||||
Scale_space_reconstruction_3
|
||||
Spatial_searching
|
||||
Spatial_sorting
|
||||
Segment_Delaunay_graph_2
|
||||
Segment_Delaunay_graph_Linf_2
|
||||
Straight_skeleton_2
|
||||
Visibility_2
|
||||
Voronoi_diagram_2
|
||||
Surface_mesh_simplification
|
||||
Subdivision_method_3
|
||||
Surface_mesh_parameterization
|
||||
Surface_reconstruction_points_3
|
||||
Surface_mesh_segmentation
|
||||
Stream_lines_2
|
||||
Stream_support
|
||||
Surface_modeling
|
||||
Barycentric_coordinates_2
|
||||
Surface_mesh
|
||||
Surface_mesh_shortest_path
|
||||
Polygon_mesh_processing
|
||||
|
||||
|
||||
|
||||
|
|
@ -43,7 +43,7 @@ Manuals for the Previous Releases
|
|||
For releases >= 4.2, visit [http://doc.cgal.org/X.Y](http://doc.cgal.org/4.2)
|
||||
|
||||
For releases X.Y, with 3.1 <= X.Y <= 4.1 visit
|
||||
[http://www.cgal.org/Manual/X.Y/doc_html/cgal_manual/contents.html](http://www.cgal.org/Manual/3.1/doc_html/cgal_manual/contents.html)
|
||||
[http://doc.cgal.org/Manual/X.Y/doc_html/cgal_manual/packages.html](http://doc.cgal.org/Manual/3.1/doc_html/cgal_manual/packages.html)
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ h1 {
|
|||
\package_listing{Straight_skeleton_2}
|
||||
\package_listing{Minkowski_sum_2}
|
||||
\package_listing{Polyline_simplification_2}
|
||||
\package_listing{Visibility_2}
|
||||
|
||||
|
||||
\section PartPolyhedra Cell Complexes and Polyhedra
|
||||
|
|
@ -68,7 +69,6 @@ h1 {
|
|||
\package_listing{Snap_rounding_2}
|
||||
\package_listing{Envelope_2}
|
||||
\package_listing{Envelope_3}
|
||||
\package_listing{Visibility_2}
|
||||
|
||||
\section PartTriangulationsAndDelaunayTriangulations Triangulations and Delaunay Triangulations
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
\cgalPkgSummaryEnd
|
||||
\cgalPkgShortInfoBegin
|
||||
\cgalPkgSince{3.4}
|
||||
\cgalPkgDependsOn{\ref thirdpartyQt}
|
||||
\cgalPkgDependsOn{\sc{Qt} 5}
|
||||
\cgalPkgBib{cgal:fr-cqgvf}
|
||||
\cgalPkgLicense{\ref licensesGPL "GPL"}
|
||||
\cgalPkgShortInfoEnd
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
-------------------------------- Release 4.7 --------------------------------
|
||||
|
||||
Release date: September 2015
|
||||
Release date: October 2015
|
||||
|
||||
|
||||
* Installation
|
||||
|
|
@ -20,13 +20,10 @@ Release date: September 2015
|
|||
- The code of the 3D demos now use modern OpenGL, with shaders, instead of
|
||||
the fixed pipeline API of OpenGL-1.
|
||||
|
||||
- Initial support of the Microsoft Windows Visual C++ compiler 2015 (VC14).
|
||||
|
||||
|
||||
* General
|
||||
|
||||
- Support for unordered sets and maps of the stdlib and of boost for handle
|
||||
and index classes.
|
||||
- The Microsoft Windows Visual C++ compiler 2015 (VC14) is now supported.
|
||||
However, since this compiler is not officially supported by Intel TBB 4.4
|
||||
and Qt 5.5 (the latest versions available at the time of this release), the
|
||||
parallelism features of CGAL and Qt5 demos will not work.
|
||||
|
||||
|
||||
* L Infinity Segment Delaunay Graphs (new package)
|
||||
|
|
@ -93,6 +90,12 @@ Release date: September 2015
|
|||
mesh processing.
|
||||
|
||||
|
||||
* General
|
||||
|
||||
- Support for unordered sets and maps of the stdlib and of boost for handle
|
||||
and index classes.
|
||||
|
||||
|
||||
* Approximation of Ridges and Umbilics on Triangulated Surface Meshes
|
||||
|
||||
- This package now supports any model of the concept FaceGraph.
|
||||
|
|
@ -102,8 +105,6 @@ Release date: September 2015
|
|||
FaceGraph.
|
||||
|
||||
|
||||
|
||||
|
||||
* dD Geometry Kernel
|
||||
|
||||
- Epick_d gains 3 new functors: Construct_circumcenter_d,
|
||||
|
|
@ -111,8 +112,6 @@ Release date: September 2015
|
|||
the computation of alpha-shapes.
|
||||
|
||||
|
||||
|
||||
|
||||
* 2D Arrangements
|
||||
|
||||
- Introduced a new traits class, called
|
||||
|
|
@ -154,18 +153,16 @@ Release date: September 2015
|
|||
|
||||
* 3D Periodic Triangulations
|
||||
|
||||
- Rename Periodic_3_triangulation_traits_3
|
||||
- Rename Periodic_3_triangulation_traits_3 to
|
||||
Periodic_3_Delaunay_triangulation_traits_3.
|
||||
|
||||
- Rename the concept Periodic_3TriangulationTraits_3
|
||||
- Rename the concept Periodic_3TriangulationTraits_3 to
|
||||
Periodic_3DelaunayTriangulationTraits_3.
|
||||
|
||||
- Create Periodic_3_triangulation_traits_3 and the concept
|
||||
Periodic_3TriangulationTraits_3.
|
||||
|
||||
|
||||
|
||||
|
||||
* 2D Conforming Triangulations and Meshes
|
||||
|
||||
- Add an optimization method CGAL::lloyd_optimize_mesh_2() that implements
|
||||
|
|
@ -192,8 +189,6 @@ Release date: September 2015
|
|||
spatial_sort_on_sphere.
|
||||
|
||||
|
||||
|
||||
|
||||
* Geometric Object Generators
|
||||
|
||||
- Add new random generator of points in a 2D and 3D triangle and in a
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@
|
|||
<td width="28%">
|
||||
|
||||
<table CELLSPACING=0>
|
||||
<tr><td><a href="#release4.7">4.7</a> <td> (September 2015)
|
||||
<tr><td><a href="#release4.7">4.7</a> <td> (October 2015)
|
||||
<tr><td><a href="#release4.6.2">4.6.2</a> <td> (August 2015)
|
||||
<tr><td><a href="#release4.6.1">4.6.1</a> <td> (June 2015)
|
||||
<tr><td><a href="#release4.6">4.6</a> <td> (April 2015)
|
||||
|
|
@ -114,37 +114,67 @@ and <code>src/</code> directories).
|
|||
</table>
|
||||
|
||||
<HR>
|
||||
<h2 id="release4.7">Release 4.7 </h2>
|
||||
<!-- to remove once 4.7 is published
|
||||
|
||||
<h2 id="release4.8">Release 4.8 </h2>
|
||||
<div>
|
||||
<p>Release date: September 2015 </p>
|
||||
|
||||
to remove once 4.7 is published: -->
|
||||
|
||||
<!-- Installation (and general changes) -->
|
||||
<!-- New packages -->
|
||||
<!-- Major and breaking changes -->
|
||||
<!-- Arithmetic and Algebra -->
|
||||
<!-- Combinatorial Algorithms -->
|
||||
<!-- Geometry Kernels -->
|
||||
<!-- Convex Hull Algorithms -->
|
||||
<!-- Polygons -->
|
||||
<!-- Cell Complexes and Polyhedra -->
|
||||
<!-- Arrangements -->
|
||||
<!-- Triangulations and Delaunay Triangulations -->
|
||||
<!-- Voronoi Diagrams -->
|
||||
<!-- Mesh Generation -->
|
||||
<!-- Geometry Processing -->
|
||||
<!-- Spatial Searching and Sorting -->
|
||||
<!-- Geometric Optimization -->
|
||||
<!-- Interpolation -->
|
||||
<!-- Support Library -->
|
||||
|
||||
<!-- end of the div for 4.8 -->
|
||||
|
||||
<!-- to remove once 4.7 is published
|
||||
|
||||
</div>
|
||||
|
||||
to remove once 4.7 is published: -->
|
||||
|
||||
<h2 id="release4.7">Release 4.7 </h2>
|
||||
<div>
|
||||
<p>Release date: October 2015 </p>
|
||||
|
||||
<h3>Installation</h3>
|
||||
<ul>
|
||||
<li>The minimum required version of CMake is now 2.8.11. CMake versions
|
||||
3.1, 3.2, and 3.3 are supported.</li>
|
||||
3.1, 3.2, and 3.3 are supported.</li>
|
||||
<li>All Qt4 demos have been updated and now require Qt5 to be
|
||||
compiled. Qt5 version 5.3 or higher is required.
|
||||
The support for Qt4 is dropped. To compile libCGAL_Qt5 and demos,
|
||||
you must set the cmake or environment variable <code>Qt5_DIR</code> to point to
|
||||
the path to the directory containing the file <code>Qt5Config.cmake</code> created
|
||||
by your Qt5 installation.
|
||||
If you are using the open source edition it should be
|
||||
compiled. Qt5 version 5.3 or higher is required. The support for Qt4
|
||||
is dropped. To compile libCGAL_Qt5 and demos, you must set the cmake
|
||||
or environment variable <code>Qt5_DIR</code> to point to the path to
|
||||
the directory containing the file <code>Qt5Config.cmake</code>
|
||||
created by your Qt5 installation. If you are using the open source
|
||||
edition it should be
|
||||
<code>/path-to/qt-everywhere-opensource-src-<version>/qtbase/lib/cmake/Qt5</code>.
|
||||
</li>
|
||||
<li>The code of the 3D demos now use modern OpenGL, with shaders,
|
||||
instead of the fixed pipeline API of OpenGL-1.</li>
|
||||
<li>Initial support of the Microsoft Windows Visual C++ compiler 2015
|
||||
(VC14).</li>
|
||||
</ul>
|
||||
|
||||
<h3>General</h3>
|
||||
<ul>
|
||||
<li>Support for unordered sets and maps of the stdlib and of boost for
|
||||
handle and index classes.
|
||||
<li>The Microsoft Windows Visual C++ compiler 2015 (VC14) is now
|
||||
supported. However, since this compiler is not officially supported
|
||||
by Intel TBB 4.4 and Qt 5.5 (the latest versions available at the
|
||||
time of this release), the parallelism features of CGAL and Qt5 demos
|
||||
will not work.
|
||||
</li>
|
||||
</ul>
|
||||
<!-- New packages -->
|
||||
|
||||
<h3>L Infinity Segment Delaunay Graphs (new package)</h3>
|
||||
<ul>
|
||||
|
|
@ -186,25 +216,25 @@ and <code>src/</code> directories).
|
|||
<h3>Triangulated Surface Mesh Skeletonization (new package)</h3>
|
||||
<ul>
|
||||
<li>
|
||||
This package provides a (1D) curve skeleton extraction algorithm
|
||||
for a triangulated polygonal mesh without borders based on the
|
||||
mean curvature flow. The particularity of this skeleton is that
|
||||
it captures the topology of the input. For each skeleton vertex
|
||||
one can obtain its location and its corresponding vertices from
|
||||
the input mesh. The code is generic and works with any model of
|
||||
the `FaceListGraph` concept.
|
||||
This package provides a (1D) curve skeleton extraction algorithm for
|
||||
a triangulated polygonal mesh without borders based on the mean
|
||||
curvature flow. The particularity of this skeleton is that it
|
||||
captures the topology of the input. For each skeleton vertex one can
|
||||
obtain its location and its corresponding vertices from the input
|
||||
mesh. The code is generic and works with any model of the
|
||||
`FaceListGraph` concept.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>3D Point-Set Shape Detection (new package)</h3>
|
||||
<ul>
|
||||
<li>
|
||||
This package implements the efficient RANSAC method for shape detection,
|
||||
contributed by Schnabel et al. From an unstructured point set with
|
||||
unoriented normals, the algorithm detects a set of shapes. Five
|
||||
types of primitive shapes are provided by this package: plane,
|
||||
sphere, cylinder, cone and torus. Detecting other types of shapes
|
||||
is possible by implementing a class derived from a base shape.
|
||||
This package implements the efficient RANSAC method for shape
|
||||
detection, contributed by Schnabel et al. From an unstructured point
|
||||
set with unoriented normals, the algorithm detects a set of
|
||||
shapes. Five types of primitive shapes are provided by this package:
|
||||
plane, sphere, cylinder, cone and torus. Detecting other types of
|
||||
shapes is possible by implementing a class derived from a base shape.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
@ -217,126 +247,134 @@ and <code>src/</code> directories).
|
|||
|
||||
<h3>Polygon Mesh Processing (new package)</h3>
|
||||
<ul>
|
||||
<li>
|
||||
This package implements a collection of methods and classes
|
||||
for polygon mesh processing, ranging from basic operations on simplices,
|
||||
to complex geometry processing algorithms.
|
||||
The implementation of this package mainly follows algorithms and references
|
||||
given in Botsch et al.'s book on polygon mesh processing.
|
||||
</li>
|
||||
<li> This package implements a collection of methods and classes for
|
||||
polygon mesh processing, ranging from basic operations on simplices,
|
||||
to complex geometry processing algorithms. The implementation of
|
||||
this package mainly follows algorithms and references given in Botsch
|
||||
et al.'s book on polygon mesh processing.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h3>General</h3>
|
||||
<ul>
|
||||
<li>Support for unordered sets and maps of the stdlib and of boost for
|
||||
handle and index classes.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<!-- Major and breaking changes -->
|
||||
<h3>Approximation of Ridges and Umbilics on Triangulated Surface Meshes</h3>
|
||||
<ul>
|
||||
<li> This package now supports any model of the concept <code>FaceGraph</code>.
|
||||
<li> <b>Breaking change:</b> The package no longer support models
|
||||
of <code>TriangulatedSurfaceMesh</code> which are not at the same time
|
||||
model of the concept <code>FaceGraph</code>.
|
||||
</li>
|
||||
</ul>
|
||||
<!-- Arithmetic and Algebra -->
|
||||
<!-- Combinatorial Algorithms -->
|
||||
<!-- Geometry Kernels -->
|
||||
<ul>
|
||||
<li> This package now supports any model of the
|
||||
concept <code>FaceGraph</code>.
|
||||
<li> <b>Breaking change:</b> The package no longer support models
|
||||
of <code>TriangulatedSurfaceMesh</code> which are not at the same
|
||||
time model of the concept <code>FaceGraph</code>.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>dD Geometry Kernel</h3>
|
||||
<ul>
|
||||
<li>
|
||||
Epick_d gains 3 new functors: <code>Construct_circumcenter_d</code>,
|
||||
<code>Compute_squared_radius_d</code>, <code>Side_of_bounded_sphere_d</code>.
|
||||
<code>Compute_squared_radius_d</code>,
|
||||
<code>Side_of_bounded_sphere_d</code>.
|
||||
Those are essential for the computation of alpha-shapes.
|
||||
</li>
|
||||
</ul>
|
||||
<!-- Convex Hull Algorithms -->
|
||||
<!-- Polygons -->
|
||||
<!-- Cell Complexes and Polyhedra -->
|
||||
<!-- Arrangements -->
|
||||
|
||||
<h3>2D Arrangements</h3>
|
||||
<ul>
|
||||
<li>Introduced a new traits class, called
|
||||
<code>Arr_polycurve_traits_2<SubcurveTraits></code>, which handles
|
||||
general piece-wise (polycurve) curves. The pieces do not necessarily
|
||||
have to be linear.</li>
|
||||
<code>Arr_polycurve_traits_2<SubcurveTraits></code>, which
|
||||
handles general piece-wise (polycurve) curves. The pieces do not
|
||||
necessarily have to be linear.</li>
|
||||
<li>Introduced two new concepts called
|
||||
<code>ArrangementApproximateTraits_2</code> and
|
||||
<code>ArrangementConstructXMonotoneCurveTraits_2</code>.
|
||||
<ul>
|
||||
<li>The existing <code>ArrangementLandmarkTraits_2</code> concept,
|
||||
which has two requirements, now refines the two respective concepts
|
||||
above.</li>
|
||||
which has two requirements, now refines the two respective
|
||||
concepts above.</li>
|
||||
<li>The template parameter of the exsting
|
||||
<code>Arr_polyline_traits_2<SegmentTraits></code> template must
|
||||
be substituted with a traits class that is a model of
|
||||
the <code>ArrangementConstructXMonotoneTraits_2</code> concept among
|
||||
the other when <code>Arr_polyline_traits_2</code> is
|
||||
instantiated.</li>
|
||||
</ul></li>
|
||||
<code>Arr_polyline_traits_2<SegmentTraits></code> template
|
||||
must be substituted with a traits class that is a model of
|
||||
the <code>ArrangementConstructXMonotoneTraits_2</code> concept
|
||||
among the other when <code>Arr_polyline_traits_2</code> is
|
||||
instantiated.
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>2D Minkowski Sums</h3>
|
||||
<ul>
|
||||
<li>Added support for polygons with holes and optimized the construction
|
||||
of Minkowski sums.
|
||||
<ul>
|
||||
<li>Introduced an implementation of the "reduced convolution" method, a
|
||||
variant of the method described in "2D Minkowski Sum of Polygons Using
|
||||
Reduced Convolution" by Behar and Lien. The new method supports polygons
|
||||
with holes and in many cases out pergorms the implementation of the
|
||||
exsisting (full) convolution method.</li>
|
||||
<li>Introduced two new classes that decompose polygons into convex pieces
|
||||
(models of the <code>PolygonConvexDecomposition_2</code> concept) based
|
||||
on vertical decomposition and constrained Delaunay triangulation,
|
||||
respectively. These new models also support the convex decomposition of
|
||||
polygons with holes.</li>
|
||||
</ul></li>
|
||||
<li>Added support for polygons with holes and optimized the
|
||||
construction of Minkowski sums.
|
||||
<ul>
|
||||
<li>Introduced an implementation of the "reduced convolution"
|
||||
method, a variant of the method described in "2D Minkowski Sum of
|
||||
Polygons Using Reduced Convolution" by Behar and Lien. The new
|
||||
method supports polygons with holes and in many cases out
|
||||
pergorms the implementation of the exsisting (full) convolution
|
||||
method.</li>
|
||||
<li>Introduced two new classes that decompose polygons into convex
|
||||
pieces (models of the <code>PolygonConvexDecomposition_2</code>
|
||||
concept) based on vertical decomposition and constrained Delaunay
|
||||
triangulation, respectively. These new models also support the
|
||||
convex decomposition of polygons with holes.
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<!-- Triangulations and Delaunay Triangulations -->
|
||||
<h3>3D Periodic Triangulations</h3>
|
||||
<ul>
|
||||
<li>Rename Periodic_3_triangulation_traits_3 Periodic_3_Delaunay_triangulation_traits_3.
|
||||
<li>Rename <code>Periodic_3_triangulation_traits_3</code> to
|
||||
<code>Periodic_3_Delaunay_triangulation_traits_3</code>.
|
||||
</li>
|
||||
<li>Rename the concept Periodic_3TriangulationTraits_3 Periodic_3DelaunayTriangulationTraits_3.
|
||||
<li>Rename the concept <code>Periodic_3TriangulationTraits_3</code> to
|
||||
<code>Periodic_3DelaunayTriangulationTraits_3</code>.
|
||||
</li>
|
||||
<li>Create Periodic_3_triangulation_traits_3 and the concept Periodic_3TriangulationTraits_3.
|
||||
<li>Create <code>Periodic_3_triangulation_traits_3</code> and the
|
||||
concept <code>Periodic_3TriangulationTraits_3</code>.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<!-- Voronoi Diagrams -->
|
||||
<!-- Mesh Generation -->
|
||||
<h3>2D Conforming Triangulations and Meshes</h3>
|
||||
<ul>
|
||||
<li>
|
||||
Add an optimization method <code>CGAL::lloyd_optimize_mesh_2()</code>
|
||||
that implements the Lloyd (or Centroidal Voronoi Tesselation)
|
||||
optimization algorithm in a Constrained Delaunay Triangulation. For
|
||||
optimization, the triangulation data structure on which the mesher
|
||||
relies needs its <code>VertexBase</code> template parameter to be a
|
||||
model of the new concept <code>DelaunayMeshVertexBase_2</code>.
|
||||
Add an optimization method <code>CGAL::lloyd_optimize_mesh_2()</code>
|
||||
that implements the Lloyd (or Centroidal Voronoi Tesselation)
|
||||
optimization algorithm in a Constrained Delaunay Triangulation. For
|
||||
optimization, the triangulation data structure on which the mesher
|
||||
relies needs its <code>VertexBase</code> template parameter to be a
|
||||
model of the new concept <code>DelaunayMeshVertexBase_2</code>.
|
||||
</li>
|
||||
</ul>
|
||||
<!-- Geometry Processing -->
|
||||
|
||||
<h3>Point Set Processing and Surface Reconstruction from Point Sets</h3>
|
||||
<ul>
|
||||
<li>
|
||||
Add the function <code>CGAL::compute_vcm()</code> for computing the
|
||||
Voronoi Covariance Measure (VCM) of a point set. The output of this function
|
||||
can be used with the function <code>CGAL::vcm_is_on_feature_edge()</code>
|
||||
to determine whether a point is on or close to a feature edge. The former
|
||||
function is also internally used by <code>CGAL::vcm_estimate_normals()</code>
|
||||
to estimate the normals of a point set and it is particularly suited to point
|
||||
set with noise.
|
||||
Add the function <code>CGAL::compute_vcm()</code> for computing the
|
||||
Voronoi Covariance Measure (VCM) of a point set. The output of this
|
||||
function can be used with the
|
||||
function <code>CGAL::vcm_is_on_feature_edge()</code> to determine
|
||||
whether a point is on or close to a feature edge. The former function
|
||||
is also internally used by <code>CGAL::vcm_estimate_normals()</code>
|
||||
to estimate the normals of a point set and it is particularly suited
|
||||
to point set with noise.
|
||||
</li>
|
||||
</ul>
|
||||
<!-- Spatial Searching and Sorting -->
|
||||
|
||||
<h3>Spatial Sorting</h3>
|
||||
<ul>
|
||||
<li>Add the possibility to sort points on a sphere along
|
||||
a space-filling curve using the functions
|
||||
<code>CGAL::hilbert_sort_on_sphere</code> and
|
||||
<code>CGAL::spatial_sort_on_sphere</code>.</li>
|
||||
<li>Add the possibility to sort points on a sphere along
|
||||
a space-filling curve using the functions
|
||||
<code>CGAL::hilbert_sort_on_sphere</code> and
|
||||
<code>CGAL::spatial_sort_on_sphere</code>.</li>
|
||||
</ul>
|
||||
<!-- Geometric Optimization -->
|
||||
<!-- Interpolation -->
|
||||
<!-- Support Library -->
|
||||
|
||||
<h3>Geometric Object Generators</h3>
|
||||
<ul>
|
||||
<li>Add new random generator of points in a 2D and 3D triangle and in a
|
||||
|
|
@ -347,7 +385,6 @@ model of the concept <code>FaceGraph</code>.
|
|||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<!-- end of the div for 4.7 -->
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -102,6 +102,17 @@ if (WIN32)
|
|||
if(MSVC11)
|
||||
set(_TBB_COMPILER "vc11")
|
||||
endif(MSVC11)
|
||||
if(MSVC12)
|
||||
set(_TBB_COMPILER "vc12")
|
||||
endif(MSVC12)
|
||||
#note there was no MSVC13
|
||||
if(MSVC14)
|
||||
if(RUNNING_CGAL_AUTO_TEST)
|
||||
set (TBB_FOUND "NO")
|
||||
return()#binaries for TBB not publicly available when CGAL-4.7 is published
|
||||
endif(RUNNING_CGAL_AUTO_TEST)
|
||||
message(STATUS "[Warning] FindTBB.cmake: TBB 4.4 (latest available when CGAL-4.7 is published) does not provide support for MSVC 2015.")
|
||||
endif(MSVC14)
|
||||
# Todo: add other Windows compilers such as ICL.
|
||||
set(_TBB_ARCHITECTURE ${TBB_ARCHITECTURE})
|
||||
endif (WIN32)
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@ Kernel::FT area() const;
|
|||
/*!
|
||||
returns a bounding box containing `r`.
|
||||
*/
|
||||
Bbox bbox() const;
|
||||
Bbox_2 bbox() const;
|
||||
|
||||
/*!
|
||||
returns the iso-oriented rectangle obtained by applying `t` on
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ side is the bounded interior of the sphere.
|
|||
\pre `A` contains \f$ d+1\f$ points in \f$ d\f$-space.
|
||||
\cgalRequires The value type of `ForwardIterator` is `Kernel_d::Point_d`.
|
||||
*/
|
||||
template <class ForwardIterator> Bounded_side
|
||||
template <class ForwardIterator> Oriented_side
|
||||
operator()( ForwardIterator first, ForwardIterator last, const
|
||||
Kernel_d::Point_d& p);
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
\cgalPkgSummaryEnd
|
||||
\cgalPkgShortInfoBegin
|
||||
\cgalPkgSince{3.2}
|
||||
\cgalPkgDependsOn{\ref PkgKdsFrameworkSummary. Two dimensional visualization depends on \ref thirdpartyQt\, three dimensional visualization depends on \ref thirdpartyCoin.}
|
||||
\cgalPkgDependsOn{\ref PkgKdsFrameworkSummary. Two dimensional visualization depends on \sc{Qt} 3, three dimensional visualization depends on \ref thirdpartyCoin.}
|
||||
\cgalPkgBib{cgal:r-kds}
|
||||
\cgalPkgLicense{\ref licensesLGPL "LGPL"}
|
||||
\cgalPkgShortInfoEnd
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
\cgalPkgSummaryEnd
|
||||
\cgalPkgShortInfoBegin
|
||||
\cgalPkgSince{3.2}
|
||||
\cgalPkgDependsOn{Two dimensional visualization depends on \ref thirdpartyQt\, three dimensional visualization depends on \ref thirdpartyCoin.}
|
||||
\cgalPkgDependsOn{Two dimensional visualization depends on \sc{Qt} 3, three dimensional visualization depends on \ref thirdpartyCoin.}
|
||||
\cgalPkgBib{cgal:r-kdsf}
|
||||
\cgalPkgLicense{\ref licensesLGPL "LGPL"}
|
||||
\cgalPkgShortInfoEnd
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ endif()
|
|||
|
||||
## To add expensive tests
|
||||
# add_definitions("-DCGAL_CHECK_EXPENSIVE")
|
||||
# add_definitions("-Wall -Wextra")
|
||||
|
||||
## For profilling with gprof
|
||||
# add_definitions("-pg")
|
||||
|
|
@ -72,7 +73,6 @@ target_link_libraries(Linear_cell_complex_3_demo ${CGAL_LIBRARIES}
|
|||
${CGAL_3RD_PARTY_LIBRARIES})
|
||||
target_link_libraries(Linear_cell_complex_3_demo ${QT_LIBRARIES}
|
||||
${QGLVIEWER_LIBRARIES} )
|
||||
target_link_libraries(Linear_cell_complex_3_demo ${OPENGL_gl_LIBRARY}
|
||||
${OPENGL_glu_LIBRARY} )
|
||||
target_link_libraries(Linear_cell_complex_3_demo ${OPENGL_gl_LIBRARY} )
|
||||
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include <QSettings>
|
||||
#include <CGAL/Timer.h>
|
||||
#include <CGAL/ipower.h>
|
||||
#include "import_moka.h"
|
||||
|
||||
// Function defined in Linear_cell_complex_3_subivision.cpp
|
||||
void subdivide_lcc_3 (LCC & m);
|
||||
|
|
@ -58,7 +59,7 @@ MainWindow::MainWindow (QWidget * parent):CGAL::Qt::DemosMainWindow (parent),
|
|||
labels.append(QString(tr("Hidden")));
|
||||
volumeList->setHorizontalHeaderLabels(labels);
|
||||
//volumeList->resizeColumnsToContents();
|
||||
volumeList->setFixedWidth(200);
|
||||
volumeList->setFixedWidth(220);
|
||||
/* volumeList->setColumnWidth(0,85);
|
||||
volumeList->setColumnWidth(1,35);
|
||||
volumeList->setColumnWidth(2,35);*/
|
||||
|
|
@ -82,7 +83,7 @@ MainWindow::MainWindow (QWidget * parent):CGAL::Qt::DemosMainWindow (parent),
|
|||
|
||||
this->addRecentFiles (this->menuFile, this->actionQuit);
|
||||
connect (this, SIGNAL (openRecentFile (QString)),
|
||||
this, SLOT (load_off (QString)));
|
||||
this, SLOT (load_depend_on_extension(QString)));
|
||||
|
||||
statusMessage = new QLabel
|
||||
("Darts: 0, Vertices: 0 (Points: 0), Edges: 0, Facets: 0,"
|
||||
|
|
@ -223,6 +224,32 @@ void MainWindow::init_all_new_volumes()
|
|||
{ on_new_volume(it); }
|
||||
}
|
||||
|
||||
void MainWindow::on_actionSave_triggered ()
|
||||
{
|
||||
QString fileName = QFileDialog::getSaveFileName (this,
|
||||
tr ("Save"),
|
||||
"save.3map",
|
||||
tr ("3-map files (*.3map)"));
|
||||
|
||||
if (!fileName.isEmpty ())
|
||||
{
|
||||
save(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_actionLoad_triggered ()
|
||||
{
|
||||
QString fileName = QFileDialog::getOpenFileName (this,
|
||||
tr ("Load"),
|
||||
"./3map",
|
||||
tr ("3-map files (*.3map)"));
|
||||
|
||||
if (!fileName.isEmpty ())
|
||||
{
|
||||
load(fileName, true);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_actionImportOFF_triggered ()
|
||||
{
|
||||
QString fileName = QFileDialog::getOpenFileName (this,
|
||||
|
|
@ -236,6 +263,19 @@ void MainWindow::on_actionImportOFF_triggered ()
|
|||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_actionImportMoka_triggered()
|
||||
{
|
||||
QString fileName = QFileDialog::getOpenFileName (this,
|
||||
tr ("Import Moka"),
|
||||
"./moka",
|
||||
tr ("Moka files (*.moka)"));
|
||||
|
||||
if (!fileName.isEmpty ())
|
||||
{
|
||||
load_moka(fileName, true);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_actionImport3DTDS_triggered ()
|
||||
{
|
||||
QString fileName = QFileDialog::getOpenFileName (this,
|
||||
|
|
@ -264,6 +304,84 @@ void MainWindow::on_actionAddOFF_triggered()
|
|||
}
|
||||
}
|
||||
|
||||
void MainWindow::load_depend_on_extension(const QString & fileName, bool clear)
|
||||
{
|
||||
QString ext = QFileInfo(fileName).suffix();
|
||||
if ( ext=="3map")
|
||||
{
|
||||
load(fileName, clear);
|
||||
}
|
||||
else if (ext=="off")
|
||||
{
|
||||
load_off(fileName, clear);
|
||||
}
|
||||
else if (ext=="moka")
|
||||
{
|
||||
load_moka(fileName, clear);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout<<"Extension not considered."<<std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::load(const QString & fileName, bool clear)
|
||||
{
|
||||
QApplication::setOverrideCursor (Qt::WaitCursor);
|
||||
|
||||
if (clear) this->clear_all();
|
||||
|
||||
#ifdef CGAL_PROFILE_LCC_DEMO
|
||||
CGAL::Timer timer;
|
||||
timer.start();
|
||||
#endif
|
||||
|
||||
bool res = load_combinatorial_map(fileName.toStdString().c_str(), *(scene.lcc));
|
||||
|
||||
#ifdef CGAL_PROFILE_LCC_DEMO
|
||||
timer.stop();
|
||||
std::cout<<"Time to load 3-map "<<qPrintable(fileName)<<": "
|
||||
<<timer.time()<<" seconds."<<std::endl;
|
||||
#endif
|
||||
|
||||
recreate_whole_volume_list();
|
||||
|
||||
this->addToRecentFiles(fileName);
|
||||
QApplication::restoreOverrideCursor ();
|
||||
|
||||
if (res)
|
||||
statusBar ()->showMessage (QString ("3-map loaded ") + fileName,
|
||||
DELAY_STATUSMSG);
|
||||
else
|
||||
statusBar ()->showMessage (QString ("Problem: 3-map not loaded ") + fileName,
|
||||
DELAY_STATUSMSG);
|
||||
Q_EMIT (sceneChanged ());
|
||||
}
|
||||
|
||||
void MainWindow::save(const QString & fileName)
|
||||
{
|
||||
QApplication::setOverrideCursor (Qt::WaitCursor);
|
||||
|
||||
#ifdef CGAL_PROFILE_LCC_DEMO
|
||||
CGAL::Timer timer;
|
||||
timer.start();
|
||||
#endif
|
||||
|
||||
if ( save_combinatorial_map(*(scene.lcc), fileName.toStdString().c_str()) )
|
||||
statusBar ()->showMessage (QString ("3-map saved ") + fileName,
|
||||
DELAY_STATUSMSG);
|
||||
else
|
||||
statusBar ()->showMessage (QString ("Problem: 3-map not saved ") + fileName,
|
||||
DELAY_STATUSMSG);
|
||||
QApplication::restoreOverrideCursor ();
|
||||
|
||||
#ifdef CGAL_PROFILE_LCC_DEMO
|
||||
timer.stop();
|
||||
std::cout<<"Time to save 3-map "<<qPrintable(fileName)<<": "
|
||||
<<timer.time()<<" seconds."<<std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
void MainWindow::load_off (const QString & fileName, bool clear)
|
||||
{
|
||||
QApplication::setOverrideCursor (Qt::WaitCursor);
|
||||
|
|
@ -333,6 +451,40 @@ void MainWindow::load_3DTDS (const QString & fileName, bool clear)
|
|||
Q_EMIT (sceneChanged ());
|
||||
}
|
||||
|
||||
void MainWindow::load_moka(const QString & fileName, bool clear)
|
||||
{
|
||||
QApplication::setOverrideCursor (Qt::WaitCursor);
|
||||
|
||||
if (clear) this->clear_all();
|
||||
|
||||
#ifdef CGAL_PROFILE_LCC_DEMO
|
||||
CGAL::Timer timer;
|
||||
timer.start();
|
||||
#endif
|
||||
|
||||
CGAL::import_from_moka < LCC > (*scene.lcc, qPrintable (fileName));
|
||||
|
||||
#ifdef CGAL_PROFILE_LCC_DEMO
|
||||
timer.stop();
|
||||
std::cout<<"Time to load off "<<qPrintable(fileName)<<": "
|
||||
<<timer.time()<<" seconds."<<std::endl;
|
||||
#endif
|
||||
|
||||
init_all_new_volumes();
|
||||
recreate_whole_volume_list();
|
||||
|
||||
this->addToRecentFiles (fileName);
|
||||
QApplication::restoreOverrideCursor ();
|
||||
|
||||
if (clear)
|
||||
statusBar ()->showMessage (QString ("Load off file") + fileName,
|
||||
DELAY_STATUSMSG);
|
||||
else
|
||||
statusBar ()->showMessage (QString ("Add off file") + fileName,
|
||||
DELAY_STATUSMSG);
|
||||
Q_EMIT (sceneChanged ());
|
||||
}
|
||||
|
||||
Dart_handle MainWindow::make_iso_cuboid(const Point_3 basepoint, LCC::FT lg)
|
||||
{
|
||||
return scene.lcc->make_hexahedron(basepoint,
|
||||
|
|
@ -783,7 +935,7 @@ void MainWindow::on_actionRemove_filled_volumes_triggered()
|
|||
DELAY_STATUSMSG);
|
||||
}
|
||||
|
||||
void MainWindow::on_actionTriangulate_all_facets_triggered()
|
||||
void MainWindow::on_actionInsert_center_vertices_triggered()
|
||||
{
|
||||
QApplication::setOverrideCursor (Qt::WaitCursor);
|
||||
|
||||
|
|
@ -805,17 +957,113 @@ void MainWindow::on_actionTriangulate_all_facets_triggered()
|
|||
|
||||
#ifdef CGAL_PROFILE_LCC_DEMO
|
||||
timer.stop();
|
||||
std::cout<<"Time to triangulate all filled faces: "
|
||||
std::cout<<"Time to insert center vertices in all filled faces: "
|
||||
<<timer.time()<<" seconds."<<std::endl;
|
||||
#endif
|
||||
|
||||
QApplication::restoreOverrideCursor ();
|
||||
Q_EMIT (sceneChanged ());
|
||||
statusBar()->showMessage
|
||||
(QString ("Facets of visible and filled volume(s) triangulated"),
|
||||
(QString ("Vertices are inserted in center of facets of visible and filled volume(s)"),
|
||||
DELAY_STATUSMSG);
|
||||
}
|
||||
|
||||
double compute_angle3d(const Vector_3& v1, const Vector_3& v2)
|
||||
{
|
||||
double a = CGAL::to_double( (v1*v2) /
|
||||
( sqrt(v1.squared_length()) * sqrt(v2.squared_length()) ) ) ;
|
||||
|
||||
if (a < -1.0) return acos(-1.0)/M_PI*180.0;
|
||||
else if (a > 1.0) return acos(1.0)/M_PI*180.0;
|
||||
else return acos(a)/M_PI*180.0;
|
||||
}
|
||||
|
||||
void MainWindow::on_actionMerge_coplanar_faces_triggered()
|
||||
{
|
||||
QApplication::setOverrideCursor (Qt::WaitCursor);
|
||||
|
||||
#ifdef CGAL_PROFILE_LCC_DEMO
|
||||
CGAL::Timer timer;
|
||||
timer.start();
|
||||
#endif
|
||||
|
||||
scene.lcc->set_update_attributes(false);
|
||||
|
||||
std::vector<Dart_handle> edges;
|
||||
int treated = scene.lcc->get_new_mark();
|
||||
int treated2 = scene.lcc->get_new_mark();
|
||||
|
||||
for ( LCC::Dart_range::iterator it= scene.lcc->darts().begin(),
|
||||
itend = scene.lcc->darts().end(); it!=itend; ++it )
|
||||
{
|
||||
if (!scene.lcc->is_marked(it, treated) )
|
||||
{
|
||||
if ( CGAL::is_removable<LCC, 1>(*scene.lcc, it) )
|
||||
{
|
||||
LCC::Vector normal1 = CGAL::compute_normal_of_cell_2(*scene.lcc,it);
|
||||
LCC::Vector normal2 = CGAL::compute_normal_of_cell_2(*scene.lcc, scene.lcc->beta<2>(it) );
|
||||
double angle = compute_angle3d(normal1, normal2);
|
||||
|
||||
if ( ((angle<5.0 || angle>355.0) || (angle<185.0 && angle>175.0)) )
|
||||
{
|
||||
edges.push_back(it);
|
||||
}
|
||||
}
|
||||
CGAL::mark_cell<LCC, 1>(*scene.lcc, it, treated);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (std::vector<Dart_handle>::iterator it=edges.begin(),
|
||||
itend=edges.end(); it!=itend; ++it)
|
||||
{
|
||||
CGAL::mark_cell<LCC, 1>(*scene.lcc, *it, treated2);
|
||||
|
||||
if ( scene.lcc->beta<0, 2>(*it)==*it || scene.lcc->beta<1, 2>(*it)==*it)
|
||||
{ // To process dangling edges
|
||||
|
||||
Dart_handle actu = *it, prev=NULL;
|
||||
do
|
||||
{
|
||||
if ( scene.lcc->beta<0, 2>(actu)==actu ) prev = scene.lcc->beta<1>(actu);
|
||||
else prev = scene.lcc->beta<0>(actu);
|
||||
|
||||
if (scene.lcc->is_marked(actu, treated2) &&
|
||||
(scene.lcc->beta<0, 2>(actu)!=actu || scene.lcc->beta<1, 2>(actu)!=actu) )
|
||||
{
|
||||
CGAL::remove_cell<LCC, 1>(*scene.lcc, actu);
|
||||
actu = prev;
|
||||
}
|
||||
else
|
||||
actu = NULL;
|
||||
}
|
||||
while (actu!=NULL && (scene.lcc->beta<0, 2>(actu)==actu || scene.lcc->beta<1, 2>(actu)==actu));
|
||||
}
|
||||
else if ( !CGAL::belong_to_same_cell<LCC, 2>(*scene.lcc, *it,
|
||||
scene.lcc->beta<2>(*it)) )
|
||||
CGAL::remove_cell<LCC, 1>(*scene.lcc, *it);
|
||||
}
|
||||
|
||||
assert(scene.lcc->is_whole_map_marked(treated));
|
||||
scene.lcc->free_mark(treated);
|
||||
scene.lcc->free_mark(treated2);
|
||||
|
||||
scene.lcc->set_update_attributes(true);
|
||||
|
||||
#ifdef CGAL_PROFILE_LCC_DEMO
|
||||
timer.stop();
|
||||
std::cout<<"Time to merge all coplanar faces: "
|
||||
<<timer.time()<<" seconds."<<std::endl;
|
||||
#endif
|
||||
|
||||
recreate_whole_volume_list();
|
||||
|
||||
QApplication::restoreOverrideCursor ();
|
||||
Q_EMIT (sceneChanged ());
|
||||
statusBar()->showMessage
|
||||
(QString ("Coplanar face(s) merged"), DELAY_STATUSMSG);
|
||||
}
|
||||
|
||||
void MainWindow::on_actionMerge_all_volumes_triggered()
|
||||
{
|
||||
QApplication::setOverrideCursor (Qt::WaitCursor);
|
||||
|
|
@ -861,6 +1109,179 @@ void MainWindow::on_actionMerge_all_volumes_triggered()
|
|||
(QString ("Visible and filled volume(s) merged"), DELAY_STATUSMSG);
|
||||
}
|
||||
|
||||
bool is_external(CDT::Face_handle fh)
|
||||
{
|
||||
return fh->info().is_external;
|
||||
}
|
||||
|
||||
int number_of_existing_edge(CDT::Face_handle fh)
|
||||
{
|
||||
unsigned res=0;
|
||||
for (int i=0; i<3; ++i)
|
||||
if (fh->info().exist_edge[i]) ++res;
|
||||
return res;
|
||||
}
|
||||
|
||||
int get_free_edge(CDT::Face_handle fh)
|
||||
{
|
||||
CGAL_assertion( number_of_existing_edge(fh)==2 );
|
||||
for (int i=0; i<3; ++i)
|
||||
if (!fh->info().exist_edge[i]) return i;
|
||||
|
||||
CGAL_assertion(false);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void constrained_delaunay_triangulation(LCC &lcc, Dart_handle d1)
|
||||
{
|
||||
Vector_3 normal = CGAL::compute_normal_of_cell_2(lcc,d1);
|
||||
P_traits cdt_traits(normal);
|
||||
CDT cdt(cdt_traits);
|
||||
|
||||
//inserting the constraints edge by edge
|
||||
LCC::Dart_of_orbit_range<1>::iterator
|
||||
it(lcc.darts_of_orbit<1>(d1).begin());
|
||||
|
||||
CDT::Vertex_handle previous=LCC::null_handle, first=LCC::null_handle,
|
||||
vh=LCC::null_handle;
|
||||
|
||||
for (LCC::Dart_of_orbit_range<1>::iterator
|
||||
itend(lcc.darts_of_orbit<1>(d1).end()); it!=itend; ++it)
|
||||
{
|
||||
vh = cdt.insert(lcc.point(it));
|
||||
vh->info()=it;
|
||||
if( first==NULL )
|
||||
{
|
||||
first=vh;
|
||||
}
|
||||
if( previous!=NULL)
|
||||
{
|
||||
CGAL_assertion( previous !=vh );
|
||||
cdt.insert_constraint(previous,vh);
|
||||
}
|
||||
|
||||
previous=vh;
|
||||
}
|
||||
cdt.insert_constraint(previous,first);
|
||||
CGAL_assertion(cdt.is_valid());
|
||||
|
||||
// sets mark is_external
|
||||
for( CDT::All_faces_iterator fit = cdt.all_faces_begin(),
|
||||
fitend = cdt.all_faces_end(); fit != fitend; ++fit)
|
||||
{
|
||||
fit->info().is_external = false;
|
||||
fit->info().exist_edge[0]=false;
|
||||
fit->info().exist_edge[1]=false;
|
||||
fit->info().exist_edge[2]=false;
|
||||
}
|
||||
|
||||
std::queue<CDT::Face_handle> face_queue;
|
||||
|
||||
face_queue.push(cdt.infinite_vertex()->face());
|
||||
while(! face_queue.empty() )
|
||||
{
|
||||
CDT::Face_handle fh = face_queue.front();
|
||||
face_queue.pop();
|
||||
if(!fh->info().is_external)
|
||||
{
|
||||
fh->info().is_external = true;
|
||||
for(int i = 0; i <3; ++i)
|
||||
{
|
||||
if(!cdt.is_constrained(std::make_pair(fh, i)))
|
||||
{
|
||||
face_queue.push(fh->neighbor(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for( CDT::Finite_edges_iterator eit = cdt.finite_edges_begin(),
|
||||
eitend = cdt.finite_edges_end(); eit != eitend; ++eit)
|
||||
{
|
||||
CDT::Face_handle fh = eit->first;
|
||||
int index = eit->second;
|
||||
CDT::Face_handle opposite_fh = fh->neighbor(index);
|
||||
if(cdt.is_constrained(std::make_pair(fh, index)))
|
||||
{
|
||||
fh->info().exist_edge[index]=true;
|
||||
opposite_fh->info().exist_edge[cdt.mirror_index(fh,index)]=true;
|
||||
|
||||
if ( !fh->info().is_external && number_of_existing_edge(fh)==2 )
|
||||
face_queue.push(fh);
|
||||
if ( !opposite_fh->info().is_external &&
|
||||
number_of_existing_edge(opposite_fh)==2 )
|
||||
face_queue.push(opposite_fh);
|
||||
}
|
||||
}
|
||||
|
||||
while( !face_queue.empty() )
|
||||
{
|
||||
CDT::Face_handle fh = face_queue.front();
|
||||
face_queue.pop();
|
||||
CGAL_assertion( number_of_existing_edge(fh)>=2 ); // i.e. ==2 or ==3
|
||||
CGAL_assertion( !fh->info().is_external );
|
||||
|
||||
if (number_of_existing_edge(fh)==2)
|
||||
{
|
||||
int index = get_free_edge(fh);
|
||||
CDT::Face_handle opposite_fh = fh->neighbor(index);
|
||||
|
||||
CGAL_assertion( !fh->info().exist_edge[index] );
|
||||
CGAL_assertion( !opposite_fh->info().
|
||||
exist_edge[cdt.mirror_index(fh,index)] );
|
||||
const CDT::Vertex_handle va = fh->vertex(cdt. cw(index));
|
||||
const CDT::Vertex_handle vb = fh->vertex(cdt.ccw(index));
|
||||
|
||||
Dart_handle ndart=
|
||||
CGAL::insert_cell_1_in_cell_2(lcc,va->info(),vb->info());
|
||||
va->info()=lcc.beta<2>(ndart);
|
||||
|
||||
fh->info().exist_edge[index]=true;
|
||||
opposite_fh->info().exist_edge[cdt.mirror_index(fh,index)]=true;
|
||||
|
||||
if ( !opposite_fh->info().is_external &&
|
||||
number_of_existing_edge(opposite_fh)==2 )
|
||||
face_queue.push(opposite_fh);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_actionTriangulate_all_facets_triggered()
|
||||
{
|
||||
QApplication::setOverrideCursor (Qt::WaitCursor);
|
||||
|
||||
#ifdef CGAL_PROFILE_LCC_DEMO
|
||||
CGAL::Timer timer;
|
||||
timer.start();
|
||||
#endif
|
||||
|
||||
std::vector<LCC::Dart_handle> v;
|
||||
for (LCC::One_dart_per_cell_range<2>::iterator
|
||||
it(scene.lcc->one_dart_per_cell<2>().begin()); it.cont(); ++it)
|
||||
{
|
||||
if ( scene.lcc->info<3>(it).is_filled_and_visible() ||
|
||||
(!scene.lcc->is_free<3>(it) &&
|
||||
scene.lcc->info<3>(scene.lcc->beta<3>(it)).is_filled_and_visible()) )
|
||||
v.push_back(it);
|
||||
}
|
||||
|
||||
for (std::vector<LCC::Dart_handle>::iterator itv(v.begin());
|
||||
itv!=v.end(); ++itv)
|
||||
constrained_delaunay_triangulation(*scene.lcc, *itv);
|
||||
|
||||
#ifdef CGAL_PROFILE_LCC_DEMO
|
||||
timer.stop();
|
||||
std::cout<<"Time to triangulate all filled faces: "
|
||||
<<timer.time()<<" seconds."<<std::endl;
|
||||
#endif
|
||||
|
||||
recreate_whole_volume_list();
|
||||
|
||||
QApplication::restoreOverrideCursor ();
|
||||
Q_EMIT (sceneChanged ());
|
||||
statusBar()->showMessage
|
||||
(QString ("All visible and filled faces were triangulated"), DELAY_STATUSMSG);
|
||||
}
|
||||
|
||||
bool MainWindow::is_volume_in_list(LCC::Attribute_handle<3>::type ah)
|
||||
{
|
||||
for(int row=0; row < volumeList->rowCount(); ++row)
|
||||
|
|
@ -975,6 +1396,8 @@ void MainWindow::recreate_whole_volume_list()
|
|||
|
||||
void MainWindow::onCellChanged(int row, int col)
|
||||
{
|
||||
volumeList->disconnect(this);
|
||||
|
||||
LCC::Attribute_type<3>::type* ptr=
|
||||
reinterpret_cast<LCC::Attribute_type<3>::type*>
|
||||
( volumeList->item(row,3)->data(Qt::UserRole).value<quintptr>() );
|
||||
|
|
@ -994,6 +1417,7 @@ void MainWindow::onCellChanged(int row, int col)
|
|||
(volumeList->item(row,1)->flags()|Qt::ItemIsEnabled);
|
||||
}
|
||||
|
||||
connectVolumeListHandlers();
|
||||
Q_EMIT( sceneChanged());
|
||||
}
|
||||
|
||||
|
|
@ -1875,64 +2299,6 @@ void MainWindow::onSierpinskiCarpetUpdateAttributes(bool newValue)
|
|||
sierpinskiCarpetUpdateAttributes = newValue;
|
||||
}
|
||||
|
||||
/*void MainWindow::onSierpinskiCarpetNeverUpdateAttributes(bool newValue)
|
||||
{
|
||||
if (afterConstructionUpdateAttributes)
|
||||
{
|
||||
dialogsierpinskicarpet.groupBox2->setEnabled(false);
|
||||
}
|
||||
|
||||
neverUpdateAttributes = true;
|
||||
duringConstructionUpdateAttributes = false;
|
||||
afterConstructionUpdateAttributes = false;
|
||||
}
|
||||
|
||||
void MainWindow::onSierpinskiCarpetDuringConstructionUpdateAttributes(bool newValue)
|
||||
{
|
||||
if (afterConstructionUpdateAttributes)
|
||||
{
|
||||
dialogsierpinskicarpet.groupBox2->setEnabled(false);
|
||||
}
|
||||
|
||||
neverUpdateAttributes = false;
|
||||
duringConstructionUpdateAttributes = true;
|
||||
afterConstructionUpdateAttributes = false;
|
||||
}
|
||||
|
||||
void MainWindow::onSierpinskiCarpetAfterConstructionUpdateAttributes(bool newValue)
|
||||
{
|
||||
if (!afterConstructionUpdateAttributes)
|
||||
{
|
||||
dialogsierpinskicarpet.groupBox2->setEnabled(true);
|
||||
}
|
||||
|
||||
neverUpdateAttributes = false;
|
||||
duringConstructionUpdateAttributes = false;
|
||||
afterConstructionUpdateAttributes = true;
|
||||
}
|
||||
|
||||
void MainWindow::onSierpinskiCarpetUpdateAttributesMethodStdMap(bool newValue)
|
||||
{
|
||||
updateAttributesMethodStdMap = true;
|
||||
updateAttributesMethodTraversal = false;
|
||||
}
|
||||
|
||||
void MainWindow::onSierpinskiCarpetUpdateAttributesMethodTraversal(bool newValue)
|
||||
{
|
||||
updateAttributesMethodStdMap = false;
|
||||
updateAttributesMethodTraversal = true;
|
||||
}
|
||||
|
||||
void MainWindow::onSierpinskiCarpetComputeGeometry(bool newValue)
|
||||
{
|
||||
sierpinski_carpet_compute_geometry();
|
||||
|
||||
computeGeometry = false;
|
||||
dialogsierpinskicarpet.computeGeometry->setEnabled(false);
|
||||
|
||||
Q_EMIT( sceneChanged());
|
||||
}*/
|
||||
|
||||
void MainWindow::onSierpinskiCarpetInc()
|
||||
{
|
||||
QApplication::setOverrideCursor (Qt::WaitCursor);
|
||||
|
|
|
|||
|
|
@ -110,9 +110,12 @@ public:
|
|||
|
||||
public Q_SLOTS:
|
||||
// File menu
|
||||
void on_actionSave_triggered();
|
||||
void on_actionLoad_triggered();
|
||||
void on_actionImportOFF_triggered();
|
||||
void on_actionAddOFF_triggered();
|
||||
void on_actionImport3DTDS_triggered();
|
||||
void on_actionImportMoka_triggered();
|
||||
void on_actionCompute_Voronoi_3D_triggered();
|
||||
void on_actionClear_triggered();
|
||||
|
||||
|
|
@ -130,19 +133,25 @@ public Q_SLOTS:
|
|||
void on_actionSubdivide_pqq_triggered();
|
||||
void on_actionDual_3_triggered();
|
||||
void on_actionClose_volume_triggered();
|
||||
void on_actionTriangulate_all_facets_triggered();
|
||||
void on_actionSew3_same_facets_triggered();
|
||||
void on_actionUnsew3_all_triggered();
|
||||
void on_actionMerge_coplanar_faces_triggered();
|
||||
void on_actionMerge_all_volumes_triggered();
|
||||
void on_actionRemove_filled_volumes_triggered();
|
||||
void on_actionInsert_center_vertices_triggered();
|
||||
void on_actionTriangulate_all_facets_triggered();
|
||||
|
||||
// View menu
|
||||
void on_actionExtend_filled_volumes_triggered();
|
||||
void on_actionExtend_hidden_volumes_triggered();
|
||||
|
||||
// Other slots
|
||||
void load_depend_on_extension(const QString& fileName, bool clear=true);
|
||||
void load(const QString& fileName, bool clear=true);
|
||||
void save(const QString& fileName);
|
||||
void load_off(const QString& fileName, bool clear=true);
|
||||
void load_3DTDS(const QString& fileName, bool clear=true);
|
||||
void load_moka(const QString& fileName, bool clear=true);
|
||||
|
||||
void onSceneChanged();
|
||||
|
||||
|
|
|
|||
|
|
@ -33,15 +33,19 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>635</width>
|
||||
<height>22</height>
|
||||
<height>25</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuFile">
|
||||
<property name="title">
|
||||
<string>&File</string>
|
||||
</property>
|
||||
<addaction name="actionLoad"/>
|
||||
<addaction name="actionSave"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionImportOFF"/>
|
||||
<addaction name="actionAddOFF"/>
|
||||
<addaction name="actionImportMoka"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionImport3DTDS"/>
|
||||
<addaction name="actionCompute_Voronoi_3D"/>
|
||||
|
|
@ -54,12 +58,15 @@
|
|||
<property name="title">
|
||||
<string>&Operations</string>
|
||||
</property>
|
||||
<addaction name="actionInsert_center_vertices"/>
|
||||
<addaction name="actionTriangulate_all_facets"/>
|
||||
<addaction name="actionSew3_same_facets"/>
|
||||
<addaction name="actionUnsew3_all"/>
|
||||
<addaction name="actionMerge_coplanar_faces"/>
|
||||
<addaction name="actionMerge_all_volumes"/>
|
||||
<addaction name="actionRemove_filled_volumes"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionSew3_same_facets"/>
|
||||
<addaction name="actionUnsew3_all"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionSubdivide"/>
|
||||
<addaction name="actionSubdivide_pqq"/>
|
||||
<addaction name="actionClose_volume"/>
|
||||
|
|
@ -221,6 +228,31 @@
|
|||
<string>Create Sierpinski Triangle</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionLoad">
|
||||
<property name="text">
|
||||
<string>&Load</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSave">
|
||||
<property name="text">
|
||||
<string>&Save</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionImportMoka">
|
||||
<property name="text">
|
||||
<string>Import Moka</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionMerge_coplanar_faces">
|
||||
<property name="text">
|
||||
<string>Merge coplanar faces</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionInsert_center_vertices">
|
||||
<property name="text">
|
||||
<string>Insert center vertices in faces</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -22,57 +22,29 @@
|
|||
#define VIEWER_H
|
||||
|
||||
#include "typedefs.h"
|
||||
|
||||
#include <vector>
|
||||
#include <QGLViewer/qglviewer.h>
|
||||
#include <QKeyEvent>
|
||||
|
||||
#include <QOpenGLFunctions_2_1>
|
||||
#include <QOpenGLVertexArrayObject>
|
||||
#include <QGLBuffer>
|
||||
#include <QOpenGLShaderProgram>
|
||||
class Viewer : public QGLViewer, QOpenGLFunctions_2_1
|
||||
|
||||
class Viewer : public QGLViewer, public QOpenGLFunctions_2_1
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
CGAL::Timer timer;
|
||||
Scene* scene;
|
||||
bool wireframe;
|
||||
bool flatShading;
|
||||
bool edges;
|
||||
bool vertices;
|
||||
CGAL::Bbox_3 bb;
|
||||
|
||||
GLuint m_dlFaces;
|
||||
GLuint m_dlFacesFlat;
|
||||
GLuint m_dlEdges;
|
||||
GLuint m_dlVertices;
|
||||
bool m_displayListCreated;
|
||||
|
||||
typedef LCC::Dart_handle Dart_handle;
|
||||
typedef LCC::Dart_const_handle Dart_const_handle;
|
||||
|
||||
|
||||
public:
|
||||
Viewer(QWidget* parent);
|
||||
~Viewer()
|
||||
{
|
||||
buffers[0].destroy();
|
||||
buffers[1].destroy();
|
||||
buffers[2].destroy();
|
||||
buffers[3].destroy();
|
||||
buffers[4].destroy();
|
||||
buffers[5].destroy();
|
||||
buffers[6].destroy();
|
||||
buffers[7].destroy();
|
||||
vao[0].destroy();
|
||||
vao[1].destroy();
|
||||
vao[2].destroy();
|
||||
vao[3].destroy();
|
||||
|
||||
}
|
||||
~Viewer();
|
||||
|
||||
void setScene(Scene* scene_)
|
||||
{
|
||||
scene = scene_;
|
||||
}
|
||||
{ scene = scene_; }
|
||||
|
||||
public:
|
||||
void draw();
|
||||
|
|
@ -87,12 +59,27 @@ public Q_SLOTS:
|
|||
|
||||
void sceneChanged();
|
||||
|
||||
private:
|
||||
void initialize_buffers();
|
||||
void attrib_buffers(QGLViewer*);
|
||||
void compile_shaders();
|
||||
|
||||
void compute_elements();
|
||||
void compute_faces(Dart_handle dh);
|
||||
void compute_edges(Dart_handle dh);
|
||||
void compute_vertices(Dart_handle dh, bool empty);
|
||||
|
||||
private:
|
||||
|
||||
Scene* scene;
|
||||
bool wireframe;
|
||||
bool flatShading;
|
||||
bool edges;
|
||||
bool vertices;
|
||||
CGAL::Bbox_3 bb;
|
||||
bool m_previous_scene_empty;
|
||||
bool are_buffers_initialized;
|
||||
//Shaders elements
|
||||
|
||||
//Shaders elements
|
||||
int vertexLocation[3];
|
||||
int normalsLocation;
|
||||
int mvpLocation[2];
|
||||
|
|
@ -101,24 +88,17 @@ private:
|
|||
int colorsLocation;
|
||||
int lightLocation[5];
|
||||
|
||||
|
||||
std::vector<float> pos_points;
|
||||
std::vector<float> pos_lines;
|
||||
std::vector<float> pos_facets;
|
||||
std::vector<float> smooth_normals;
|
||||
std::vector<float> flat_normals;
|
||||
std::vector <float> colors;
|
||||
std::vector<float> colors;
|
||||
|
||||
QGLBuffer buffers[10];
|
||||
QOpenGLVertexArrayObject vao[10];
|
||||
QOpenGLShaderProgram rendering_program;
|
||||
QOpenGLShaderProgram rendering_program_p_l;
|
||||
|
||||
void initialize_buffers();
|
||||
void compute_elements();
|
||||
void attrib_buffers(QGLViewer*);
|
||||
void compile_shaders();
|
||||
void triangulate_facet();
|
||||
bool is_Triangulated();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -0,0 +1,192 @@
|
|||
// 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$
|
||||
//
|
||||
// Author(s) : Guillaume Damiand <guillaume.damiand@liris.cnrs.fr>
|
||||
//
|
||||
#ifndef IMPORT_MOKA_H
|
||||
#define IMPORT_MOKA_H
|
||||
|
||||
namespace CGAL
|
||||
{
|
||||
struct GDart
|
||||
{
|
||||
unsigned int alpha[4];
|
||||
Dart_handle dh;
|
||||
LCC::Vertex_attribute_handle vh;
|
||||
|
||||
GDart() : dh(NULL), vh(NULL)
|
||||
{}
|
||||
|
||||
GDart(const GDart& adart) : dh(adart.dh),
|
||||
vh(adart.vh)
|
||||
{
|
||||
for (unsigned int i=0; i<4; ++i)
|
||||
alpha[i]=adart.alpha[i];
|
||||
}
|
||||
};
|
||||
|
||||
template<typename LCC>
|
||||
bool import_from_moka(LCC& lcc, const char* filename)
|
||||
{
|
||||
typedef typename LCC::Point Point;
|
||||
|
||||
std::ifstream ifile(filename);
|
||||
if (!ifile)
|
||||
{
|
||||
std::cout<<"Error opening file "<<filename<<"."<<std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string line;
|
||||
std::getline(ifile, line);
|
||||
|
||||
if ( line == "Moka file [binary]" )
|
||||
{
|
||||
std::cout<<"Binary file not (yet) considered.\n";
|
||||
return false;
|
||||
}
|
||||
else if ( line != "Moka file [ascii]" )
|
||||
{
|
||||
std::cout<<"File "<<filename<<" is not a moka file.\n";
|
||||
std::cout<< line;
|
||||
return false;
|
||||
}
|
||||
|
||||
// To skip the masks mark (TODO read the marks ?)
|
||||
std::getline(ifile, line);
|
||||
|
||||
std::vector<GDart> gdarts;
|
||||
unsigned int nbLoaded = 0;
|
||||
unsigned int number;
|
||||
double x,y,z;
|
||||
|
||||
// First load all the gdarts, and create vertex attributes
|
||||
while(ifile)
|
||||
{
|
||||
GDart agdart;
|
||||
ifile>>agdart.alpha[0]>>agdart.alpha[1]
|
||||
>>agdart.alpha[2]>>agdart.alpha[3]; // the 4 alpha
|
||||
ifile>>number>>number>>number>>number; // to skip the 4*8 marks
|
||||
if ( agdart.alpha[0]==nbLoaded )
|
||||
{
|
||||
std::cout<<"Impossible to load a moka file with 0-free darts.\n";
|
||||
return false;
|
||||
}
|
||||
if ( ifile )
|
||||
{
|
||||
ifile>>number; // bool to know if dart has a vertex of not.
|
||||
if (number)
|
||||
{
|
||||
ifile>>x>>y>>z;
|
||||
agdart.vh = lcc.create_vertex_attribute(Point(x, y, z));
|
||||
}
|
||||
|
||||
gdarts.push_back(agdart);
|
||||
++nbLoaded;
|
||||
}
|
||||
}
|
||||
ifile.close();
|
||||
|
||||
// Second orient the gmap, and create oriented darts.
|
||||
std::stack<unsigned int> totreat;
|
||||
for (unsigned int startingdart = 0; startingdart<nbLoaded; ++startingdart)
|
||||
{
|
||||
bool orient=(gdarts[startingdart].dh==NULL);
|
||||
for (unsigned int dim=0; orient && dim<4; ++dim)
|
||||
if (gdarts[gdarts[startingdart].alpha[dim]].dh!=NULL) orient=false;
|
||||
|
||||
if ( orient )
|
||||
{
|
||||
totreat.push(startingdart);
|
||||
gdarts[startingdart].dh=lcc.create_dart();
|
||||
|
||||
while ( !totreat.empty() )
|
||||
{
|
||||
unsigned int i=totreat.top();
|
||||
totreat.pop();
|
||||
|
||||
assert(gdarts[i].dh!=NULL);
|
||||
|
||||
for (unsigned int dim=1; dim<4; ++dim)
|
||||
{
|
||||
if (gdarts[i].alpha[dim]!=i &&
|
||||
gdarts[gdarts[i].alpha[dim]].vh!=NULL)
|
||||
{
|
||||
gdarts[i].vh = gdarts[gdarts[i].alpha[dim]].vh;
|
||||
gdarts[gdarts[i].alpha[dim]].vh = NULL;
|
||||
}
|
||||
|
||||
unsigned int alpha0 = gdarts[i].alpha[0];
|
||||
assert( alpha0!=i );
|
||||
|
||||
if (gdarts[alpha0].alpha[dim]!=alpha0)
|
||||
{
|
||||
if ( gdarts[gdarts[alpha0].alpha[dim]].dh==NULL )
|
||||
{
|
||||
totreat.push(gdarts[alpha0].alpha[dim]);
|
||||
gdarts[gdarts[alpha0].alpha[dim]].dh = lcc.create_dart();
|
||||
lcc.basic_link_beta(gdarts[i].dh,
|
||||
gdarts[gdarts[alpha0].alpha[dim]].dh,
|
||||
dim);
|
||||
}
|
||||
else if (lcc.is_free(gdarts[i].dh, dim))
|
||||
{
|
||||
lcc.basic_link_beta(gdarts[i].dh,
|
||||
gdarts[gdarts[alpha0].alpha[dim]].dh,
|
||||
dim);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test that the gmap was orientable.
|
||||
bool orientable = true;
|
||||
for (unsigned int i = 0; i<nbLoaded; ++i)
|
||||
{
|
||||
if (gdarts[i].dh!=NULL)
|
||||
{
|
||||
for (unsigned int dim=0; dim<4; ++dim)
|
||||
{
|
||||
if (orientable &&
|
||||
gdarts[i].alpha[dim]!=i &&
|
||||
gdarts[gdarts[i].alpha[dim]].dh!=NULL)
|
||||
{
|
||||
std::cout<<"Pb, the gmap is NOT orientable."<<std::endl;
|
||||
orientable=false;
|
||||
// lcc.clear();
|
||||
}
|
||||
}
|
||||
|
||||
if ( gdarts[i].dh->attribute<3>() == NULL )
|
||||
{
|
||||
lcc.template set_attribute<3>(gdarts[i].dh, lcc.template create_attribute<3>());
|
||||
}
|
||||
}
|
||||
if (gdarts[i].vh!=NULL)
|
||||
{
|
||||
lcc.set_vertex_attribute(gdarts[i].dh, gdarts[i].vh);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -24,6 +24,13 @@
|
|||
#include <CGAL/Linear_cell_complex_constructors.h>
|
||||
#include <CGAL/Linear_cell_complex_operations.h>
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Combinatorial_map_save_load.h>
|
||||
|
||||
#include <CGAL/Triangulation_2_filtered_projection_traits_3.h>
|
||||
#include <CGAL/Triangulation_vertex_base_with_info_2.h>
|
||||
#include <CGAL/Triangulation_face_base_with_info_2.h>
|
||||
#include <CGAL/Constrained_Delaunay_triangulation_2.h>
|
||||
#include <CGAL/Constrained_triangulation_plus_2.h>
|
||||
|
||||
#include <CGAL/IO/Color.h>
|
||||
#include <CGAL/Timer.h>
|
||||
|
|
@ -45,6 +52,11 @@ extern CGAL::Random myrandom;
|
|||
|
||||
class Volume_info
|
||||
{
|
||||
friend void CGAL::read_cmap_attribute_node<Volume_info>
|
||||
(const boost::property_tree::ptree::value_type &v,Volume_info &val);
|
||||
|
||||
friend void CGAL::write_cmap_attribute_node<Volume_info>(boost::property_tree::ptree & node,
|
||||
const Volume_info& arg);
|
||||
public:
|
||||
Volume_info() : m_color(CGAL::Color(myrandom.get_int(0,256),
|
||||
myrandom.get_int(0,256),
|
||||
|
|
@ -91,22 +103,61 @@ public:
|
|||
void negate_filled()
|
||||
{ set_filled(!is_filled()); }
|
||||
|
||||
private:
|
||||
private:
|
||||
CGAL::Color m_color;
|
||||
char m_status;
|
||||
};
|
||||
|
||||
namespace CGAL
|
||||
{
|
||||
|
||||
template<>
|
||||
inline void read_cmap_attribute_node<Volume_info>
|
||||
(const boost::property_tree::ptree::value_type &v,Volume_info &val)
|
||||
{
|
||||
try
|
||||
{
|
||||
val.m_status = v.second.get<int>("status");
|
||||
}
|
||||
catch(const std::exception & )
|
||||
{}
|
||||
|
||||
try
|
||||
{
|
||||
char r = v.second.get<int>("color-r");
|
||||
char g = v.second.get<int>("color-g");
|
||||
char b = v.second.get<int>("color-b");
|
||||
val.m_color = CGAL::Color(r,g,b);
|
||||
}
|
||||
catch(const std::exception & )
|
||||
{}
|
||||
}
|
||||
|
||||
// Definition of function allowing to save custon information.
|
||||
template<>
|
||||
inline void write_cmap_attribute_node<Volume_info>(boost::property_tree::ptree & node,
|
||||
const Volume_info& arg)
|
||||
{
|
||||
boost::property_tree::ptree & nValue = node.add("v","");
|
||||
nValue.add("status",(int)arg.m_status);
|
||||
nValue.add("color-r",(int)arg.m_color.r());
|
||||
nValue.add("color-g",(int)arg.m_color.g());
|
||||
nValue.add("color-b",(int)arg.m_color.b());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class Myitems
|
||||
{
|
||||
public:
|
||||
template < class Refs >
|
||||
struct Dart_wrapper
|
||||
struct Dart_wrapper
|
||||
{
|
||||
typedef CGAL::Dart<3, Refs > Dart;
|
||||
|
||||
|
||||
typedef CGAL::Cell_attribute_with_point< Refs > Vertex_attrib;
|
||||
typedef CGAL::Cell_attribute< Refs, Volume_info> Volume_attrib;
|
||||
|
||||
|
||||
typedef CGAL::cpp11::tuple<Vertex_attrib,void,void,
|
||||
Volume_attrib> Attributes;
|
||||
};
|
||||
|
|
@ -124,6 +175,22 @@ typedef LCC::Vector Vector_3;
|
|||
|
||||
typedef CGAL::Timer Timer;
|
||||
|
||||
typedef CGAL::Triangulation_2_filtered_projection_traits_3<Mytraits> P_traits;
|
||||
typedef CGAL::Triangulation_vertex_base_with_info_2<Dart_handle,P_traits> Vb;
|
||||
|
||||
struct Face_info {
|
||||
bool exist_edge[3];
|
||||
bool is_external;
|
||||
};
|
||||
|
||||
typedef CGAL::Triangulation_face_base_with_info_2<Face_info,P_traits> Fb1;
|
||||
|
||||
typedef CGAL::Constrained_triangulation_face_base_2<P_traits, Fb1> Fb;
|
||||
typedef CGAL::Triangulation_data_structure_2<Vb,Fb> TDS;
|
||||
typedef CGAL::No_intersection_tag Itag;
|
||||
typedef CGAL::Constrained_Delaunay_triangulation_2<P_traits, TDS,
|
||||
Itag> CDT;
|
||||
|
||||
struct Scene {
|
||||
LCC* lcc;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ LC_CTYPE=en_US.UTF-8
|
|||
# "master" alone
|
||||
0 21 * * Sun cd $HOME/CGAL/create_internal_release && $HOME/bin/create_release $HOME/CGAL/branches/master.git --public --do-it
|
||||
# "integration"
|
||||
0 21 * * Mon,Tue,Wed,Thu,Fri cd $HOME/CGAL/create_internal_release && $HOME/bin/create_release $HOME/CGAL/branches/integration.git $HOME/CGAL/branches/empty-dir --do-it --public
|
||||
0 21 * * Mon,Tue,Wed,Thu,Fri cd $HOME/CGAL/create_internal_release && $HOME/bin/create_release $HOME/CGAL/branches/integration.git $HOME/CGAL/branches/empty-dir --do-it
|
||||
# from branch 4.6
|
||||
0 21 * * Sat cd $HOME/CGAL/create_internal_release-4.6-branch && $HOME/bin/create_release $HOME/CGAL/branches/CGAL-4.6-branch.git --public --do-it
|
||||
# from branch 4.5
|
||||
|
|
|
|||
|
|
@ -1,28 +1,41 @@
|
|||
Subject: CGAL 4.7 Beta 1 Released, Computational Geometry Algorithms Library
|
||||
Subject: CGAL 4.7 Beta 2 Released, Computational Geometry Algorithms Library
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Body:
|
||||
|
||||
The CGAL Open Source Project is pleased to announce the release 4.7 Beta 1
|
||||
The CGAL Open Source Project is pleased to announce the release 4.7 Beta 2
|
||||
of CGAL, the Computational Geometry Algorithms Library.
|
||||
|
||||
CGAL version 4.7 Beta 1 is a public testing release. It should provide
|
||||
CGAL version 4.7 Beta 2 is a public testing release. It should provide
|
||||
a solid ground to report bugs that need to be tackled before the
|
||||
release of the final version of CGAL 4.7 in September.
|
||||
release of the final version of CGAL 4.7 in October.
|
||||
|
||||
That is the second "beta" release for CGAL-4.7. The reason is that the
|
||||
switches from Qt4 to Qt5, and from OpenGL 1 to modern OpenGL with shaders,
|
||||
were not as smooth as we hopped. A lot of bugs have been fixed in the Qt5
|
||||
demos since CGAL-4.7-beta1.
|
||||
|
||||
You can find the detailed description of all changes here on Github:
|
||||
|
||||
https://github.com/CGAL/cgal/issues?q=milestone%3A4.7-beta2
|
||||
|
||||
|
||||
Besides fixes to existing packages, the following has changed since
|
||||
CGAL 4.6:
|
||||
As a reminder, you can find below the major changes since CGAL 4.6:
|
||||
|
||||
o Installation
|
||||
|
||||
- The minimum required version of CMake is now 2.8.11. CMake versions 3.1,
|
||||
3.2, and 3.3 are supported.
|
||||
- The minimum required version of CMake is now 2.8.11. CMake versions
|
||||
3.1, 3.2, and 3.3 are supported.
|
||||
|
||||
- All Qt4 demos have been updated and now require Qt5 to be
|
||||
compiled. Qt5 version 5.3 or higher is required. The support for Qt4
|
||||
is dropped. The code of the 3D demos now use modern OpenGL, with
|
||||
shaders, instead of the fixed pipeline API of OpenGL-1.
|
||||
|
||||
- The Microsoft Windows Visual C++ compiler 2015 (VC14) is now
|
||||
supported. However, since this compiler is not officially supported
|
||||
by Intel TBB 4.4 and Qt 5.5 (the latest versions available at the
|
||||
time of this release), the parallelism features of CGAL and Qt5 demos
|
||||
will not work.
|
||||
|
||||
o Advancing Front Surface Reconstruction (new package)
|
||||
|
||||
|
|
@ -89,104 +102,6 @@ CGAL 4.6:
|
|||
of a point within polygonal regions in two dimensions.
|
||||
|
||||
|
||||
|
||||
|
||||
See http://www.cgal.org/releases.html for a complete list of changes.
|
||||
|
||||
|
||||
The CGAL project is a collaborative effort to develop a robust,
|
||||
easy-to-use, and efficient C++ software library of geometric data
|
||||
structures and algorithms, like
|
||||
- triangulations (2D constrained triangulations, Delaunay triangulations
|
||||
and periodic triangulations in 2D and 3D),The CGAL Open Source Project is pleased to announce the release 4.7 Beta 1
|
||||
of CGAL, the Computational Geometry Algorithms Library.
|
||||
|
||||
CGAL version 4.7 Beta 1 is a public testing release. It should provide
|
||||
a solid ground to report bugs that need to be tackled before the
|
||||
release of the final version of CGAL 4.7 in September.
|
||||
|
||||
|
||||
Besides fixes to existing packages, the following has changed since
|
||||
CGAL 4.6:
|
||||
|
||||
o Installation
|
||||
|
||||
- The minimum required version of CMake is now 2.8.11. CMake versions 3.1,
|
||||
3.2, and 3.3 are supported.
|
||||
|
||||
- All Qt4 demos have been updated and now require Qt5 to be
|
||||
compiled. Qt5 version 5.3 or higher is required. The support for Qt4
|
||||
is dropped. The code of the 3D demos now use modern OpenGL, with
|
||||
shaders, instead of the fixed pipeline API of OpenGL-1.
|
||||
|
||||
|
||||
o Advancing Front Surface Reconstruction (new package)
|
||||
|
||||
This package provides a greedy algorithm for surface reconstruction
|
||||
from an unorganized point set. Starting from a seed facet, a piecewise
|
||||
linear surface is grown by adding Delaunay triangles one by one. The
|
||||
most plausible triangles are added first, in a way that avoids the
|
||||
appearance of topological singularities.
|
||||
|
||||
|
||||
o Triangulated Surface Mesh Shortest Paths (new package)
|
||||
|
||||
The package provides methods for computing shortest path on
|
||||
triangulated surface meshes. Given a set of source points on the
|
||||
surface, this package provides a data structure that can efficiently
|
||||
provides the shortest path from any point on the surface to the sources
|
||||
points. There is no restriction on the genus or the number of
|
||||
connected components of the mesh.
|
||||
|
||||
|
||||
o Triangulated Surface Mesh Skeletonization (new package)
|
||||
|
||||
This package provides a (1D) curve skeleton extraction algorithm for a
|
||||
triangulated polygonal mesh without borders based on the mean curvature
|
||||
flow. The particularity of this skeleton is that it captures the
|
||||
topology of the input. For each skeleton vertex one can obtain its
|
||||
location and its corresponding vertices from the input mesh. The code
|
||||
is generic and works with any model of the `FaceListGraph` concept.
|
||||
|
||||
|
||||
o Polygon Mesh Processing (new package)
|
||||
|
||||
This package implements a collection of methods and classes for polygon
|
||||
mesh processing, ranging from basic operations on simplices, to complex
|
||||
geometry processing algorithms. The implementation of this package
|
||||
mainly follows algorithms and references given in Botsch et al.'s book
|
||||
on polygon mesh processing.
|
||||
|
||||
|
||||
o 3D Point-Set Shape Detection (new package)
|
||||
|
||||
This package implements the efficient RANSAC method for shape
|
||||
detection, contributed by Schnabel et al. From an unstructured point
|
||||
set with unoriented normals, the algorithm detects a set of
|
||||
shapes. Five types of primitive shapes are provided by this package:
|
||||
plane, sphere, cylinder, cone and torus. Detecting other types of
|
||||
shapes is possible by implementing a class derived from a base shape.
|
||||
|
||||
|
||||
o L Infinity Segment Delaunay Graphs (new package)
|
||||
|
||||
The package provides the geometric traits for constructing the segment
|
||||
Delaunay graph in the max-norm (L Infinity). The traits also contain
|
||||
methods to draw the edges of the dual of the segment Delaunay graph in
|
||||
the max-norm i.e., the segment Voronoi diagram in the max-norm. The
|
||||
algorithm and traits rely on the segment Delaunay graph algorithm and
|
||||
traits under the Euclidean distance. The segment Voronoi diagram in the
|
||||
max-norm has applications in VLSI CAD.
|
||||
|
||||
|
||||
o 2D Visibility (new package)
|
||||
|
||||
This package provides several variants to compute the visibility area
|
||||
of a point within polygonal regions in two dimensions.
|
||||
|
||||
|
||||
|
||||
|
||||
See http://www.cgal.org/releases.html for a complete list of changes.
|
||||
|
||||
|
||||
|
|
@ -217,40 +132,6 @@ structures and algorithms, like
|
|||
|
||||
|
||||
|
||||
Some modules are distributed under the terms of the LGPL Open Source
|
||||
license (GNU Lesser General Public License v3 or later versions).
|
||||
Most modules are distributed under the terms of the GPL Open Source
|
||||
license (GNU General Public License v3 or later versions).
|
||||
If your intended usage does not meet the criteria of the
|
||||
aforementioned licenses, a commercial license can be purchased from
|
||||
GeometryFactory (http://www.geometryfactory.com/).
|
||||
|
||||
|
||||
For further information and for downloading the library and its
|
||||
documentation, please visit the CGAL web site: http://www.cgal.org/
|
||||
|
||||
- Voronoi diagrams (for 2D and 3D points, 2D additively weighted
|
||||
Voronoi diagrams, and segment Voronoi diagrams),
|
||||
- Boolean operations on polygons and polyhedra,
|
||||
- regularized Boolean operations on polygons with curved arcs
|
||||
- arrangements of curves,
|
||||
- mesh generation (2D, 3D and surface mesh generation,
|
||||
surface mesh subdivision and parametrization),
|
||||
- alpha shapes (in 2D and 3D),
|
||||
- convex hull algorithms (in 2D, 3D and dD),
|
||||
- operations on polygons (straight skeleton and offset polygon),
|
||||
- search structures (kd trees for nearest neighbor search, and
|
||||
range and segment trees),
|
||||
- interpolation (natural neighbor interpolation and placement of
|
||||
streamlines),
|
||||
- optimization algorithms (smallest enclosing sphere of points or
|
||||
spheres, smallest enclosing ellipsoid of points, principal
|
||||
component analysis),
|
||||
- kinetic data structures
|
||||
|
||||
|
||||
|
||||
|
||||
Some modules are distributed under the terms of the LGPL Open Source
|
||||
license (GNU Lesser General Public License v3 or later versions).
|
||||
Most modules are distributed under the terms of the GPL Open Source
|
||||
|
|
|
|||
|
|
@ -1,15 +1,21 @@
|
|||
Subject: CGAL 4.6.2 Released, Computational Geometry Algorithms Library
|
||||
Subject: CGAL 4.6.3 Released, Computational Geometry Algorithms Library
|
||||
From: Laurent Rineau <laurent.rineau@cgal.org>
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
Body:
|
||||
|
||||
The CGAL Open Source Project is pleased to announce the release 4.6.2
|
||||
The CGAL Open Source Project is pleased to announce the release 4.6.3
|
||||
of CGAL, the Computational Geometry Algorithms Library.
|
||||
|
||||
Version 4.6.2 is a bug-fix release for version 4.6. The list of fixed bugs
|
||||
Version 4.6.3 is a bug-fix release for version 4.6. The list of fixed bugs
|
||||
can be seen Github:
|
||||
|
||||
- fixed in CGAL-4.6.2:
|
||||
|
||||
- fixed in CGAL-4.6.3:
|
||||
|
||||
https://github.com/CGAL/cgal/issues?q=milestone%3A4.6.3
|
||||
|
||||
|
||||
- fixed earlier in CGAL-4.6.2:
|
||||
|
||||
https://github.com/CGAL/cgal/issues?q=milestone%3A4.6.2
|
||||
|
||||
|
|
|
|||
|
|
@ -58,7 +58,15 @@ rm -rf Surface_modeling_Demo
|
|||
# Demo not announced in the CGAL manual, from CGAL-3.8:
|
||||
rm -rf Circular_kernel_3_Demo
|
||||
|
||||
# CGAL-4.6
|
||||
pushd Polyline_simplification_2_Demo; zip ../polyline_simplification_2.zip *; popd
|
||||
|
||||
# CGAL-4.7
|
||||
|
||||
pushd Segment_Delaunay_graph_Linf_2_Demo; zip ../segment_voronoi_diagram_2.zip *; popd
|
||||
|
||||
# check
|
||||
echo CHECK now
|
||||
echo CHECK now. The following lines should be empty.
|
||||
for f in *zip; do unzip -qql $f; done | awk '{print $4}' >| done
|
||||
for f in */**/*(.); do grep -qF ${f:t} done || ls $f; done
|
||||
echo
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
7
|
||||
8
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
CGAL-4.7-beta2
|
||||
CGAL-4.8-dev
|
||||
|
|
|
|||
|
|
@ -62,13 +62,13 @@ if ( CGAL_FOUND )
|
|||
create_single_source_cgal_program( "mesh_polyhedral_domain.cpp" )
|
||||
create_single_source_cgal_program( "mesh_polyhedral_domain_with_features.cpp" )
|
||||
if( WITH_CGAL_ImageIO )
|
||||
create_single_source_cgal_program( "mesh_optimization_example.cpp" )
|
||||
create_single_source_cgal_program( "mesh_optimization_lloyd_example.cpp" )
|
||||
if( CGAL_ImageIO_USE_ZLIB )
|
||||
create_single_source_cgal_program( "mesh_optimization_example.cpp" )
|
||||
create_single_source_cgal_program( "mesh_optimization_lloyd_example.cpp" )
|
||||
create_single_source_cgal_program( "mesh_3D_image.cpp" )
|
||||
create_single_source_cgal_program( "mesh_3D_image_variable_size.cpp" )
|
||||
else()
|
||||
message( STATUS "NOTICE: The examples mesh_3D_image.cpp and mesh_3D_image_variable_size.cpp need CGAL_ImageIO to be configured with ZLIB support, and will not be compiled." )
|
||||
message( STATUS "NOTICE: The examples mesh_3D_image.cpp, mesh_3D_image_variable_size.cpp, mesh_optimization_example.cpp and mesh_optimization_lloyd_example.cpp need CGAL_ImageIO to be configured with ZLIB support, and will not be compiled." )
|
||||
endif()
|
||||
else()
|
||||
message( STATUS "NOTICE: Some examples need the CGAL_ImageIO library, and will not be compiled." )
|
||||
|
|
|
|||
|
|
@ -173,7 +173,7 @@ public:
|
|||
Implicit_multi_domain_to_labeling_function_wrapper (const Function_vector& vf, const std::vector<std::vector<Sign> >& vps)
|
||||
: funcs(vf), bmasks(vps.size(), Bmask(funcs.size() * 2, false))
|
||||
{
|
||||
assert(funcs.size());
|
||||
CGAL_assertion(funcs.size() != 0);
|
||||
|
||||
std::size_t mask_index = 0;
|
||||
for (std::vector<std::vector<Sign> >::const_iterator mask_iter = vps.begin(), mask_end_iter = vps.end();
|
||||
|
|
@ -181,14 +181,14 @@ public:
|
|||
++mask_iter)
|
||||
{
|
||||
const std::vector<Sign>& mask = *mask_iter;
|
||||
assert(funcs.size() == mask.size());
|
||||
CGAL_assertion(funcs.size() == mask.size());
|
||||
Bmask& bmask = bmasks[mask_index++];
|
||||
|
||||
typename Bmask::size_type bit_index = 0;
|
||||
for (std::vector<Sign>::const_iterator iter = mask.begin(), endIter = mask.end(); iter != endIter; ++iter)
|
||||
{
|
||||
std::string::value_type character = *iter;
|
||||
assert(character == POSITIVE || character == NEGATIVE);
|
||||
CGAL_assertion(character == POSITIVE || character == NEGATIVE);
|
||||
|
||||
bmask[bit_index] = (character == POSITIVE);
|
||||
++bit_index;
|
||||
|
|
@ -202,7 +202,7 @@ public:
|
|||
Implicit_multi_domain_to_labeling_function_wrapper (const Function_vector& vf)
|
||||
: funcs(vf)
|
||||
{
|
||||
assert(funcs.size());
|
||||
CGAL_assertion(funcs.size() != 0);
|
||||
|
||||
bmasks.reserve((1 << funcs.size()) - 1);
|
||||
bmasks.push_back(Bmask(std::string("10")));
|
||||
|
|
@ -228,7 +228,7 @@ public:
|
|||
Implicit_multi_domain_to_labeling_function_wrapper (const Function_vector& vf, const std::vector<std::string>& vps)
|
||||
: funcs(vf), bmasks(vps.size(), Bmask(funcs.size() * 2, false))
|
||||
{
|
||||
assert(funcs.size());
|
||||
CGAL_assertion(funcs.size() != 0);
|
||||
|
||||
std::size_t mask_index = 0;
|
||||
for (std::vector<std::string>::const_iterator mask_iter = vps.begin(), mask_end_iter = vps.end();
|
||||
|
|
@ -236,14 +236,14 @@ public:
|
|||
++mask_iter)
|
||||
{
|
||||
const std::string& mask_str = *mask_iter;
|
||||
assert(funcs.size() == mask_str.length());
|
||||
CGAL_assertion(funcs.size() == mask_str.length());
|
||||
Bmask& bmask = bmasks[mask_index++];
|
||||
|
||||
typename Bmask::size_type bit_index = 0;
|
||||
for (std::string::const_iterator iter = mask_str.begin(), endIter = mask_str.end(); iter != endIter; ++iter)
|
||||
{
|
||||
std::string::value_type character = *iter;
|
||||
assert(character == '+' || character == '-');
|
||||
CGAL_assertion(character == '+' || character == '-');
|
||||
|
||||
bmask[bit_index] = (character == '+');
|
||||
++bit_index;
|
||||
|
|
|
|||
|
|
@ -1162,7 +1162,7 @@ private:
|
|||
Subdomain operator()(const Cell_handle& ch, const bool update = true) const
|
||||
{
|
||||
if ( c3t3_.triangulation().is_infinite(ch) )
|
||||
return false;
|
||||
return Subdomain();
|
||||
|
||||
// treat cell
|
||||
const Subdomain subdomain =
|
||||
|
|
|
|||
|
|
@ -1185,7 +1185,7 @@ public:
|
|||
/*!
|
||||
creates a Nef polyhedron consisting of a single polygon
|
||||
spanned by the list of points in the iterator range
|
||||
`[begin,end)`. If the points do not on a common
|
||||
`[begin,end)`. If the points do not lie on a common
|
||||
supporting plane, the constructor tries to triangulate
|
||||
the polygon into multiple facets.If the construction does
|
||||
not succeed, the empty set is created.
|
||||
|
|
@ -1193,8 +1193,10 @@ public:
|
|||
Nef_polyhedron_3(Input_iterator begin, Input_iterator end);
|
||||
|
||||
/*!
|
||||
The iterator range [it, end) defines a set point
|
||||
ranges, each of which defines a polyline.
|
||||
creates a Nef polyhedron consisting of polylines.
|
||||
The iterator range [it, end) defines a range of polylines.
|
||||
Each polyline is defined as a range of points, first and
|
||||
past-the-end iterators being provided as a `std::pair` of iterators.
|
||||
*/
|
||||
template <class Forward_iterator>
|
||||
Nef_polyhedron_3(Forward_iterator it, Forward_iterator end,
|
||||
|
|
|
|||
|
|
@ -483,7 +483,7 @@ struct Mpzf {
|
|||
}
|
||||
#endif
|
||||
if(u.s.sig) size=-size;
|
||||
//assert(to_double()==IA_force_to_double(d));
|
||||
//CGAL_assertion(to_double()==IA_force_to_double(d));
|
||||
}
|
||||
|
||||
#ifdef CGAL_USE_GMPXX
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include <CGAL/convert_to_bfi.h>
|
||||
#include <CGAL/Coercion_traits.h>
|
||||
#include <CGAL/Sqrt_extension/Sqrt_extension_type.h>
|
||||
#include <CGAL/assertions.h>
|
||||
|
||||
|
||||
// Disbale SQRT_EXTENSION_TO_BFI_CACHE by default
|
||||
|
|
@ -92,8 +93,8 @@ convert_to_bfi(const CGAL::Sqrt_extension<NT,ROOT,ACDE_TAG,FP_TAG>& x) {
|
|||
}else{
|
||||
result_ = convert_to_bfi(x.a0());
|
||||
}
|
||||
assert(lower(result) == lower(result_));
|
||||
assert(upper(result) == upper(result_));
|
||||
CGAL_assertion(lower(result) == lower(result_));
|
||||
CGAL_assertion(upper(result) == upper(result_));
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1396,7 +1396,7 @@ class Intersection_of_Polyhedra_3{
|
|||
switch(type){
|
||||
case internal_IOP::COPLNR:
|
||||
#ifndef DO_NOT_HANDLE_COPLANAR_FACETS
|
||||
assert(!"COPLNR : this point should never be reached!");
|
||||
CGAL_assertion(!"COPLANR : this point should never be reached!");
|
||||
#else
|
||||
//nothing need to be done, cf. comments at the beginning of the file
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
\cgalPkgShortInfoBegin
|
||||
\cgalPkgSince{4.3}
|
||||
\cgalPkgDependsOn{\ref PkgTDS2Summary and \ref PkgTriangulation2Summary}
|
||||
\cgalPkgDependsOn{\ref PkgTriangulation2Summary}
|
||||
\cgalPkgBib{cgal:k-pt2-13}
|
||||
\cgalPkgLicense{\ref licensesGPL "GPL"}
|
||||
\cgalPkgDemo{Periodic Delaunay Triangulation,Periodic_2_Delaunay_triangulation_2.zip}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
\cgalPkgSummaryEnd
|
||||
\cgalPkgShortInfoBegin
|
||||
\cgalPkgSince{3.5}
|
||||
\cgalPkgDependsOn{\ref PkgTriangulation3Summary and \ref PkgTDS3Summary}
|
||||
\cgalPkgDependsOn{\ref PkgTDS3Summary}
|
||||
\cgalPkgBib{cgal:ct-pt3}
|
||||
\cgalPkgLicense{\ref licensesGPL "GPL"}
|
||||
\cgalPkgDemo{3D Periodic Delaunay Triangulation,periodic_3_triangulation_3.zip,3D Periodic Lloyd,periodic_3_lloyd.zip}
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ namespace CGAL {
|
|||
///
|
||||
/// @tparam ForwardIterator iterator over input points.
|
||||
/// @tparam PointPMap is a model of `ReadablePropertyMap` with a value type = `Point_3<Kernel>`.
|
||||
/// It can be omitted if the value type of `ForwardIterator value_type is convertible to `Point_3<Kernel>`.
|
||||
/// It can be omitted if the value type of `ForwardIterator` is convertible to `Point_3<Kernel>`.
|
||||
/// @tparam NormalPMap is a model of `ReadablePropertyMap` with a value type `Vector_3<Kernel>`.
|
||||
/// @tparam Kernel Geometric traits class.
|
||||
/// It can be omitted and deduced automatically from the value type of `PointPMap`.
|
||||
|
|
|
|||
|
|
@ -449,9 +449,9 @@ bilateral_smooth_point_set(
|
|||
CGAL_point_set_processing_precondition(n.squared_length() > 1e-10);
|
||||
|
||||
pwns.push_back(Pwn(p, n));
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int nb_points = pwns.size();
|
||||
std::size_t nb_points = pwns.size();
|
||||
|
||||
#ifdef CGAL_PSP3_VERBOSE
|
||||
std::cout << "Initialization and compute max spacing: " << std::endl;
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ update_new_point(
|
|||
typedef typename Kernel::FT FT;
|
||||
typedef typename rich_grid_internal::Rich_point<Kernel> Rich_point;
|
||||
|
||||
CGAL_assertion_code( unsigned int size = rich_point_set.size() );
|
||||
CGAL_assertion_code( unsigned int size = static_cast<unsigned int>(rich_point_set.size()) );
|
||||
CGAL_point_set_processing_precondition(father_index >= 0 &&
|
||||
father_index < size);
|
||||
CGAL_point_set_processing_precondition(mother_index >= 0 &&
|
||||
|
|
@ -431,7 +431,7 @@ edge_aware_upsample_point_set(
|
|||
std::cout << "current radius: " << current_radius << std::endl;
|
||||
#endif
|
||||
|
||||
unsigned int current_size = rich_point_set.size();
|
||||
std::size_t current_size = rich_point_set.size();
|
||||
std::vector<bool> is_pass_threshold(current_size, false);
|
||||
|
||||
if (iter_time == 0)
|
||||
|
|
@ -533,7 +533,7 @@ edge_aware_upsample_point_set(
|
|||
Rich_point& base = rich_point_set[mother_index];
|
||||
Vector diff_v_base = base.pt - v.pt;
|
||||
new_v.pt = v.pt + (diff_v_base * FT(0.5));
|
||||
new_v.index = rich_point_set.size();
|
||||
new_v.index = static_cast<unsigned int>(rich_point_set.size());
|
||||
|
||||
unsigned int new_point_index = new_v.index;
|
||||
rich_point_set.push_back(new_v);
|
||||
|
|
@ -570,7 +570,7 @@ edge_aware_upsample_point_set(
|
|||
}
|
||||
}
|
||||
|
||||
for (unsigned int i = number_of_input; i < rich_point_set.size(); ++i)
|
||||
for (std::size_t i = number_of_input; i < rich_point_set.size(); ++i)
|
||||
{
|
||||
Rich_point& v = rich_point_set[i];
|
||||
Point point = v.pt;
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ ranging from basic operations on simplices, to complex geometry processing algor
|
|||
|
||||
\cgalPkgShortInfoBegin
|
||||
\cgalPkgSince{4.7}
|
||||
\cgalPkgDependsOn{\ref PkgTriangulation3Summary, Sparse square solver such as those from \ref thirdpartyEigen}
|
||||
\cgalPkgDependsOn{documented for each function; Sparse square solver such as those from \ref thirdpartyEigen}
|
||||
\cgalPkgBib{cgal:lty-pmp}
|
||||
\cgalPkgLicense{\ref licensesGPL "GPL"}
|
||||
\cgalPkgDemo{Operations on Polyhedra,polyhedron_3.zip}
|
||||
|
|
@ -72,6 +72,7 @@ and provides a list of the parameters that are used in this package.
|
|||
- \link stitching_grp `CGAL::Polygon_mesh_processing::stitch_borders()` \endlink
|
||||
- `CGAL::Polygon_mesh_processing::polygon_soup_to_polygon_mesh()`
|
||||
- `CGAL::Polygon_mesh_processing::orient_polygon_soup()`
|
||||
<!---
|
||||
- \link reverse_face_orientations_grp `CGAL::Polygon_mesh_processing::remove_degenerate_faces()` \endlink
|
||||
- `CGAL::Polygon_mesh_processing::remove_isolated_vertices()`
|
||||
|
||||
|
|
@ -99,4 +100,6 @@ It can be made short to PM. And TriangleMesh (or TM) specifies when the paramete
|
|||
\todo document `BGL/include/CGAL/boost/graph/split_graph_into_polylines.h`
|
||||
\todo add in BGL `clear(pmesh)` and use it in `keep_largest_connected_components(pmesh, 0);`
|
||||
\todo document BGL/include/CGAL/boost/graph/Dual.h and remove the example from dont_submit
|
||||
\todo fix and restore remove_degenerate_faces in the user and the reference manual
|
||||
\todo publish `is_polygon_soup_a_polygon_mesh` defined in `polygon_soup_to_polygon_mesh.h`
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -270,6 +270,7 @@ with duplicated border edges.
|
|||
\cgalExample{Polygon_mesh_processing/stitch_borders_example.cpp}
|
||||
|
||||
*******************
|
||||
<!---
|
||||
\subsection DegenerateFaces Removing Degenerate Faces
|
||||
|
||||
Some degenerate faces may be part of a given triangle mesh.
|
||||
|
|
@ -289,7 +290,7 @@ are removed, the connectivity is fixed, and the number of removed faces
|
|||
is output.
|
||||
|
||||
\cgalExample{Polygon_mesh_processing/remove_degeneracies_example.cpp}
|
||||
|
||||
--->
|
||||
|
||||
*******************
|
||||
\subsection PolygonSoups Polygon Soups
|
||||
|
|
@ -457,7 +458,6 @@ Function or Class | Pure Triangle | Self-Intersection Free
|
|||
`stitch_borders()` | no | no | no
|
||||
`polygon_soup_to_polygon_mesh()` | no | no | no
|
||||
`orient_polygon_soup()` | no | no | no
|
||||
`remove_degenerate_faces()` | yes | no | no
|
||||
`remove_isolated_vertices()` | no | no | no
|
||||
`compute_face_normal()` | no | no | no
|
||||
`compute_face_normals()` | no | no | no
|
||||
|
|
@ -471,6 +471,9 @@ Function or Class | Pure Triangle | Self-Intersection Free
|
|||
`keep_connected_components()` | no | no | no
|
||||
`remove_connected_components()` | no | no | no
|
||||
</center>
|
||||
<!---
|
||||
`remove_degenerate_faces()` | yes | no | no
|
||||
--->
|
||||
****************************************
|
||||
\section PMPHistory Implementation History
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,5 @@
|
|||
\example Polygon_mesh_processing/triangulate_polyline_example.cpp
|
||||
\example Polygon_mesh_processing/refine_fair_example.cpp
|
||||
\example Polygon_mesh_processing/mesh_slicer_example.cpp
|
||||
\example Polygon_mesh_processing/remove_degeneracies_example.cpp
|
||||
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
examples/Polygon_mesh_processing/remove_degeneracies_example.cpp
|
||||
examples/Polygon_mesh_processing/remove_degeneracies_example_OM.cpp
|
||||
|
|
@ -81,7 +81,7 @@ create_single_source_cgal_program( "connected_components_example.cpp")
|
|||
create_single_source_cgal_program( "polygon_soup_example.cpp")
|
||||
create_single_source_cgal_program( "triangulate_polyline_example.cpp")
|
||||
create_single_source_cgal_program( "mesh_slicer_example.cpp")
|
||||
create_single_source_cgal_program( "remove_degeneracies_example.cpp")
|
||||
#create_single_source_cgal_program( "remove_degeneracies_example.cpp")
|
||||
create_single_source_cgal_program( "isotropic_remeshing_example.cpp")
|
||||
|
||||
if(NOT (${EIGEN3_VERSION} VERSION_LESS 3.2.0))
|
||||
|
|
@ -105,8 +105,8 @@ target_link_libraries( point_inside_example_OM ${OPENMESH_LIBRARIES} )
|
|||
create_single_source_cgal_program( "stitch_borders_example_OM.cpp" )
|
||||
target_link_libraries( stitch_borders_example_OM ${OPENMESH_LIBRARIES} )
|
||||
|
||||
create_single_source_cgal_program( "remove_degeneracies_example_OM.cpp")
|
||||
target_link_libraries( remove_degeneracies_example_OM ${OPENMESH_LIBRARIES} )
|
||||
#create_single_source_cgal_program( "remove_degeneracies_example_OM.cpp")
|
||||
#target_link_libraries( remove_degeneracies_example_OM ${OPENMESH_LIBRARIES} )
|
||||
|
||||
create_single_source_cgal_program( "triangulate_faces_example_OM.cpp")
|
||||
target_link_libraries( triangulate_faces_example_OM ${OPENMESH_LIBRARIES} )
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#include <CGAL/boost/graph/iterator.h>
|
||||
#include <CGAL/boost/graph/helpers.h>
|
||||
|
||||
#include <CGAL/assertions.h>
|
||||
#include <CGAL/Polyhedron_3.h>
|
||||
#include <CGAL/Polyhedron_incremental_builder_3.h>
|
||||
#include <CGAL/Union_find.h>
|
||||
|
|
@ -724,7 +725,7 @@ void keep_or_remove_connected_components(PolygonMesh& pmesh
|
|||
}
|
||||
else {
|
||||
// no face kept
|
||||
assert((is_border(h, pmesh) || !get(fcm,fh)) && (is_border(oh, pmesh) || !get(fcm,ofh)));
|
||||
CGAL_assertion((is_border(h, pmesh) || !get(fcm,fh)) && (is_border(oh, pmesh) || !get(fcm,ofh)));
|
||||
// vertices pointing to e must change their halfedge
|
||||
if (halfedge(v, pmesh) == oh){
|
||||
set_halfedge(v, prev(h, pmesh), pmesh);
|
||||
|
|
@ -746,7 +747,7 @@ void keep_or_remove_connected_components(PolygonMesh& pmesh
|
|||
remove_edge(e, pmesh);
|
||||
}
|
||||
else {
|
||||
assert(keep_vertex[w]);
|
||||
CGAL_assertion(keep_vertex[w]);
|
||||
if (halfedge(w, pmesh) == h){
|
||||
set_halfedge(w, prev(oh, pmesh), pmesh);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
//
|
||||
// $URL$
|
||||
// $Id$
|
||||
//
|
||||
//
|
||||
//
|
||||
// Author(s) : Laurent Rineau and Ilker O. Yaz
|
||||
|
||||
|
|
@ -91,6 +91,42 @@ public:
|
|||
};
|
||||
}//end namespace internal
|
||||
|
||||
|
||||
/// \cond SKIP_IN_MANUAL
|
||||
/**
|
||||
* \ingroup PkgPolygonMeshProcessing
|
||||
* returns `true` if the soup of polygons defines a valid polygon mesh
|
||||
* that can be handled by `CGAL::Polygon_mesh_processing::polygon_soup_to_polygon_mesh()`.
|
||||
*
|
||||
* @tparam Polygon a `std::vector<std::size_t>` containing the indices
|
||||
* of the points of the polygon face
|
||||
*
|
||||
* @param polygons each element in the vector describes a polygon using the index of the vertices
|
||||
*
|
||||
*/
|
||||
template<class Polygon>
|
||||
bool is_polygon_soup_a_polygon_mesh(const std::vector<Polygon>& polygons)
|
||||
{
|
||||
typedef typename std::iterator_traits<
|
||||
typename Polygon::iterator >::value_type V_ID;
|
||||
|
||||
std::set< std::pair<V_ID, V_ID> > edge_set;
|
||||
BOOST_FOREACH(const Polygon& polygon, polygons)
|
||||
{
|
||||
std::size_t nb_edges = polygon.size();
|
||||
if (nb_edges<3) return false;
|
||||
V_ID prev=polygon.back();
|
||||
BOOST_FOREACH(V_ID id, polygon)
|
||||
if (! edge_set.insert(std::pair<V_ID, V_ID>(prev,id)).second )
|
||||
return false;
|
||||
else
|
||||
prev=id;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
/// \endcond
|
||||
|
||||
/**
|
||||
* \ingroup PkgPolygonMeshProcessing
|
||||
* builds a polygon mesh from a soup of polygons.
|
||||
|
|
|
|||
|
|
@ -33,6 +33,61 @@
|
|||
namespace CGAL{
|
||||
namespace Polygon_mesh_processing {
|
||||
|
||||
namespace debug{
|
||||
template <class TriangleMesh, class VertexPointMap>
|
||||
std::ostream& dump_edge_neighborhood(
|
||||
typename boost::graph_traits<TriangleMesh>::edge_descriptor ed,
|
||||
TriangleMesh& tmesh,
|
||||
const VertexPointMap& vpmap,
|
||||
std::ostream& out)
|
||||
{
|
||||
typedef boost::graph_traits<TriangleMesh> GT;
|
||||
typedef typename GT::halfedge_descriptor halfedge_descriptor;
|
||||
typedef typename GT::vertex_descriptor vertex_descriptor;
|
||||
typedef typename GT::face_descriptor face_descriptor;
|
||||
|
||||
halfedge_descriptor h = halfedge(ed, tmesh);
|
||||
|
||||
std::map<vertex_descriptor, int> vertices;
|
||||
std::set<face_descriptor> faces;
|
||||
int vindex=0;
|
||||
BOOST_FOREACH(halfedge_descriptor hd, halfedges_around_target(h, tmesh))
|
||||
{
|
||||
if ( vertices.insert(std::make_pair(source(hd, tmesh), vindex)).second )
|
||||
++vindex;
|
||||
if (!is_border(hd, tmesh))
|
||||
faces.insert( face(hd, tmesh) );
|
||||
}
|
||||
|
||||
h=opposite(h, tmesh);
|
||||
BOOST_FOREACH(halfedge_descriptor hd, halfedges_around_target(h, tmesh))
|
||||
{
|
||||
if ( vertices.insert(std::make_pair(source(hd, tmesh), vindex)).second )
|
||||
++vindex;
|
||||
if (!is_border(hd, tmesh))
|
||||
faces.insert( face(hd, tmesh) );
|
||||
}
|
||||
|
||||
std::vector<vertex_descriptor> ordered_vertices(vertices.size());
|
||||
typedef std::pair<const vertex_descriptor, int> Pair_type;
|
||||
BOOST_FOREACH(const Pair_type& p, vertices)
|
||||
ordered_vertices[p.second]=p.first;
|
||||
|
||||
out << "OFF\n" << ordered_vertices.size() << " " << faces.size() << " 0\n";
|
||||
BOOST_FOREACH(vertex_descriptor vd, ordered_vertices)
|
||||
out << get(vpmap, vd) << "\n";
|
||||
BOOST_FOREACH(face_descriptor fd, faces)
|
||||
{
|
||||
out << "3";
|
||||
h=halfedge(fd,tmesh);
|
||||
BOOST_FOREACH(halfedge_descriptor hd, halfedges_around_face(h, tmesh))
|
||||
out << " " << vertices[target(hd, tmesh)];
|
||||
out << "\n";
|
||||
}
|
||||
return out;
|
||||
}
|
||||
} //end of namespace debug
|
||||
|
||||
template <class HalfedgeGraph, class VertexPointMap, class Traits>
|
||||
struct Less_vertex_point{
|
||||
typedef typename boost::graph_traits<HalfedgeGraph>::vertex_descriptor vertex_descriptor;
|
||||
|
|
@ -87,155 +142,300 @@ bool is_degenerated(
|
|||
return is_degenerated(halfedge(fd,tmesh), tmesh, vpmap, traits);
|
||||
}
|
||||
|
||||
#if 0
|
||||
namespace internal {
|
||||
///\cond SKIP_IN_MANUAL
|
||||
template <class EdgeRange, class TriangleMesh, class NamedParameters>
|
||||
std::size_t remove_null_edges(
|
||||
const EdgeRange& edge_range,
|
||||
TriangleMesh& tmesh,
|
||||
const NamedParameters& np)
|
||||
{
|
||||
CGAL_assertion(CGAL::is_triangle_mesh(tmesh));
|
||||
|
||||
// hbase is an edge of length 0 we cannot contract because
|
||||
// the link condition is not satisfied.
|
||||
// In this function we look whether the condition is not
|
||||
// satisfied because of some faces on the "side" of hbase.
|
||||
// Here we look for two halfedges that together with hbase
|
||||
// enclose a set of degenerate faces so as to replace that
|
||||
// set with only one triangle
|
||||
template <class Traits, class TriangleMesh, class VertexPointMap>
|
||||
boost::optional<
|
||||
std::pair<
|
||||
typename boost::graph_traits<TriangleMesh>::halfedge_descriptor,
|
||||
typename boost::graph_traits<TriangleMesh>::halfedge_descriptor >
|
||||
>
|
||||
find_larger_triangle(
|
||||
typename boost::graph_traits<TriangleMesh>::halfedge_descriptor hbase,
|
||||
TriangleMesh& tmesh,
|
||||
const VertexPointMap& vpmap,
|
||||
const Traits& traits)
|
||||
using boost::choose_const_pmap;
|
||||
using boost::get_param;
|
||||
using boost::choose_param;
|
||||
|
||||
typedef TriangleMesh TM;
|
||||
typedef typename boost::graph_traits<TriangleMesh> GT;
|
||||
typedef typename GT::edge_descriptor edge_descriptor;
|
||||
typedef typename GT::halfedge_descriptor halfedge_descriptor;
|
||||
typedef typename GT::face_descriptor face_descriptor;
|
||||
typedef typename GT::vertex_descriptor vertex_descriptor;
|
||||
|
||||
typedef typename GetVertexPointMap<TM, NamedParameters>::type VertexPointMap;
|
||||
VertexPointMap vpmap = choose_pmap(get_param(np, boost::vertex_point),
|
||||
tmesh,
|
||||
boost::vertex_point);
|
||||
typedef typename GetGeomTraits<TM, NamedParameters>::type Traits;
|
||||
Traits traits = choose_param(get_param(np, geom_traits), Traits());
|
||||
|
||||
std::size_t nb_deg_faces = 0;
|
||||
|
||||
// collect edges of length 0
|
||||
std::set<edge_descriptor> null_edges_to_remove;
|
||||
BOOST_FOREACH(edge_descriptor ed, edge_range)
|
||||
{
|
||||
typedef typename boost::graph_traits<TriangleMesh> GT;
|
||||
typedef typename GT::halfedge_descriptor halfedge_descriptor;
|
||||
if ( traits.equal_3_object()(get(vpmap, target(ed, tmesh)), get(vpmap, source(ed, tmesh))) )
|
||||
null_edges_to_remove.insert(ed);
|
||||
}
|
||||
|
||||
bool no_pb=false;
|
||||
// hbase = v0 -> v1
|
||||
// consider hedges with v0 as target
|
||||
halfedge_descriptor left_hedge = prev(hbase, tmesh), o_right_hedge=left_hedge;
|
||||
do
|
||||
while (!null_edges_to_remove.empty())
|
||||
{
|
||||
edge_descriptor ed = *null_edges_to_remove.begin();
|
||||
null_edges_to_remove.erase(null_edges_to_remove.begin());
|
||||
|
||||
halfedge_descriptor h = halfedge(ed, tmesh);
|
||||
|
||||
if (CGAL::Euler::does_satisfy_link_condition(ed,tmesh))
|
||||
{
|
||||
left_hedge = prev( opposite(left_hedge, tmesh), tmesh );
|
||||
if ( face(left_hedge, tmesh) == GT::null_face() ||
|
||||
!is_degenerated(left_hedge, tmesh, vpmap, traits) )
|
||||
// remove edges that could also be set for removal
|
||||
if ( face(h, tmesh)!=GT::null_face() )
|
||||
{
|
||||
no_pb=true;
|
||||
break;
|
||||
++nb_deg_faces;
|
||||
null_edges_to_remove.erase(edge(prev(h, tmesh), tmesh));
|
||||
}
|
||||
// look for a halfedge with v1 as target
|
||||
BOOST_FOREACH(o_right_hedge, halfedges_around_source(left_hedge, tmesh) )
|
||||
if (face(opposite(h, tmesh), tmesh)!=GT::null_face())
|
||||
{
|
||||
if ( target(o_right_hedge, tmesh) == target(hbase, tmesh) )
|
||||
++nb_deg_faces;
|
||||
null_edges_to_remove.erase(edge(prev(opposite(h, tmesh), tmesh), tmesh));
|
||||
}
|
||||
//now remove the edge
|
||||
CGAL::Euler::collapse_edge(ed, tmesh);
|
||||
}
|
||||
else{
|
||||
//handle the case when the edge is incident to a triangle hole
|
||||
//we first fill the hole and try again
|
||||
if ( is_border(ed, tmesh) )
|
||||
{
|
||||
halfedge_descriptor hd = halfedge(ed,tmesh);
|
||||
if (!is_border(hd,tmesh)) hd=opposite(hd,tmesh);
|
||||
if (is_triangle(hd, tmesh))
|
||||
{
|
||||
if ( !is_degenerated( opposite(o_right_hedge, tmesh), tmesh, vpmap, traits) )
|
||||
no_pb=true;
|
||||
break;
|
||||
Euler::fill_hole(hd, tmesh);
|
||||
null_edges_to_remove.insert(ed);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ( target(o_right_hedge, tmesh) == target(hbase, tmesh) )
|
||||
break;
|
||||
}
|
||||
while(true);
|
||||
|
||||
if (!no_pb)
|
||||
return std::make_pair(left_hedge, opposite(o_right_hedge, tmesh));
|
||||
return boost::none;
|
||||
}
|
||||
// When the edge does not satisfy the link condition, it means that it cannot be
|
||||
// collapsed as is. In the following we assume that there is no topological issue
|
||||
// with contracting the edge (no volume will disappear).
|
||||
// We start by marking the faces that are incident to an edge endpoint.
|
||||
// If the set of marked faces is a topologically disk, then we simply remove all the simplicies
|
||||
// inside the disk and star the hole with the edge vertex kept.
|
||||
// If the set of marked faces is not a topological disk, it has some non-manifold vertices
|
||||
// on its boundary. We need to mark additional faces to make it a topological disk.
|
||||
// We can then apply the star hole procedure.
|
||||
// Right now we additionally mark the smallest connected components of non-marked faces
|
||||
// (using the numnber of faces)
|
||||
|
||||
// h2 is a halfedge of length 0 but collapsing the edge
|
||||
// is not directly possible because the link condition is not
|
||||
// satisfied. We remove all simplices bounded by h1, h2 and h3
|
||||
// so as to keep only that triangle
|
||||
template <class TriangleMesh, class EdgeMap>
|
||||
void
|
||||
remove_faces_inside_triangle(
|
||||
typename boost::graph_traits<TriangleMesh>::halfedge_descriptor h1,
|
||||
typename boost::graph_traits<TriangleMesh>::halfedge_descriptor h2,
|
||||
typename boost::graph_traits<TriangleMesh>::halfedge_descriptor h3,
|
||||
TriangleMesh& tmesh,
|
||||
EdgeMap& edge_map1,
|
||||
EdgeMap& edge_map2)
|
||||
{
|
||||
typedef typename boost::graph_traits<TriangleMesh> GT;
|
||||
typedef typename GT::edge_descriptor edge_descriptor;
|
||||
typedef typename GT::halfedge_descriptor halfedge_descriptor;
|
||||
typedef typename GT::face_descriptor face_descriptor;
|
||||
typedef typename GT::vertex_descriptor vertex_descriptor;
|
||||
//backup central point
|
||||
typename Traits::Point_3 pt = get(vpmap, source(ed, tmesh));
|
||||
|
||||
CGAL_assertion( source(h1,tmesh) == target(h3, tmesh) );
|
||||
CGAL_assertion( source(h2,tmesh) == target(h1, tmesh) );
|
||||
CGAL_assertion( source(h3,tmesh) == target(h2, tmesh) );
|
||||
// mark faces of the link of each endpoints of the edge which collapse is not topologically valid
|
||||
std::set<face_descriptor> marked_faces;
|
||||
// first endpoint
|
||||
BOOST_FOREACH( halfedge_descriptor hd, CGAL::halfedges_around_target(halfedge(ed,tmesh), tmesh) )
|
||||
if (!is_border(hd,tmesh)) marked_faces.insert( face(hd, tmesh) );
|
||||
// second endpoint
|
||||
BOOST_FOREACH( halfedge_descriptor hd, CGAL::halfedges_around_target(opposite(halfedge(ed, tmesh), tmesh), tmesh) )
|
||||
if (!is_border(hd,tmesh)) marked_faces.insert( face(hd, tmesh) );
|
||||
|
||||
std::set<face_descriptor> all_faces;
|
||||
all_faces.insert(face(h1, tmesh));
|
||||
all_faces.insert(face(h2, tmesh));
|
||||
all_faces.insert(face(h3, tmesh));
|
||||
// extract the halfedges on the boundary of the marked region
|
||||
std::vector<halfedge_descriptor> border;
|
||||
BOOST_FOREACH(face_descriptor fd, marked_faces)
|
||||
BOOST_FOREACH(halfedge_descriptor hd, CGAL::halfedges_around_face(halfedge(fd,tmesh), tmesh))
|
||||
{
|
||||
halfedge_descriptor hd_opp = opposite(hd, tmesh);
|
||||
if ( is_border(hd_opp, tmesh) ||
|
||||
marked_faces.count( face(hd, tmesh) )!=
|
||||
marked_faces.count( face(hd_opp, tmesh) ) )
|
||||
{
|
||||
border.push_back( hd );
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<halfedge_descriptor> queue;
|
||||
queue.push_back( opposite(prev(h1,tmesh), tmesh) );
|
||||
queue.push_back( opposite(next(h1,tmesh), tmesh) );
|
||||
queue.push_back( opposite(prev(h2,tmesh), tmesh) );
|
||||
queue.push_back( opposite(next(h2,tmesh), tmesh) );
|
||||
queue.push_back( opposite(prev(h3,tmesh), tmesh) );
|
||||
queue.push_back( opposite(next(h3,tmesh), tmesh) );
|
||||
// define cc of border halfedges: two halfedges are in the same cc
|
||||
// if they are on the border of the cc of non-marked faces.
|
||||
typedef CGAL::Union_find<halfedge_descriptor> UF_ds;
|
||||
UF_ds uf;
|
||||
std::map<halfedge_descriptor, typename UF_ds::handle> handles;
|
||||
// one cc per border halfedge
|
||||
BOOST_FOREACH(halfedge_descriptor hd, border)
|
||||
handles.insert( std::make_pair(hd, uf.make_set(hd)) );
|
||||
|
||||
std::set<edge_descriptor> all_edges;
|
||||
while(!queue.empty())
|
||||
{
|
||||
halfedge_descriptor back=queue.back();
|
||||
queue.pop_back();
|
||||
all_edges.insert( edge(back, tmesh) );
|
||||
|
||||
if ( all_faces.insert( face(back, tmesh) ).second )
|
||||
// join cc's
|
||||
BOOST_FOREACH(halfedge_descriptor hd, border)
|
||||
{
|
||||
queue.push_back( opposite(prev(back,tmesh), tmesh) );
|
||||
queue.push_back( opposite(next(back,tmesh), tmesh) );
|
||||
CGAL_assertion( marked_faces.count( face( hd, tmesh) ) > 0);
|
||||
CGAL_assertion( marked_faces.count( face( opposite(hd, tmesh), tmesh) ) == 0 );
|
||||
halfedge_descriptor candidate = hd;
|
||||
|
||||
do{
|
||||
candidate = prev( opposite(candidate, tmesh), tmesh );
|
||||
} while( !marked_faces.count( face( opposite(candidate, tmesh), tmesh) ) );
|
||||
uf.unify_sets( handles[hd], handles[opposite(candidate, tmesh)] );
|
||||
}
|
||||
}
|
||||
|
||||
std::set<vertex_descriptor> all_vertices;
|
||||
BOOST_FOREACH(edge_descriptor ed, all_edges)
|
||||
{
|
||||
all_vertices.insert( source(ed, tmesh) );
|
||||
all_vertices.insert( target(ed, tmesh) );
|
||||
}
|
||||
all_vertices.erase( target(h1, tmesh) );
|
||||
all_vertices.erase( target(h2, tmesh) );
|
||||
all_vertices.erase( target(h3, tmesh) );
|
||||
std::size_t nb_cc = uf.number_of_sets();
|
||||
if ( nb_cc != 1 )
|
||||
{
|
||||
// if more than one connected component is found then the patch
|
||||
// made of marked faces contains "non-manifold" vertices.
|
||||
// The smallest components need to be marked so that the patch
|
||||
// made of marked faces is a topological disk
|
||||
|
||||
// create the triangle
|
||||
face_descriptor remaining_face = *all_faces.begin();
|
||||
all_faces.erase(all_faces.begin());
|
||||
// update next-prev pointers
|
||||
set_next(h1, h2, tmesh);
|
||||
set_next(h2, h3, tmesh);
|
||||
set_next(h3, h1, tmesh);
|
||||
// update vertex pointers
|
||||
set_halfedge(target(h1,tmesh), h1, tmesh);
|
||||
set_halfedge(target(h2,tmesh), h2, tmesh);
|
||||
set_halfedge(target(h3,tmesh), h3, tmesh);
|
||||
// update face-halfedge pointers
|
||||
set_face(h1, remaining_face, tmesh);
|
||||
set_face(h2, remaining_face, tmesh);
|
||||
set_face(h3, remaining_face, tmesh);
|
||||
set_halfedge(remaining_face, h2, tmesh);
|
||||
// we will explore in parallel the connected components and will stop
|
||||
// when all but one connected component have been entirely explored.
|
||||
// We add one face at a time for each cc in order to not explore a
|
||||
// potentially very large cc.
|
||||
std::vector< std::vector<halfedge_descriptor> > stacks_per_cc(nb_cc);
|
||||
std::vector< std::set<face_descriptor> > faces_per_cc(nb_cc);
|
||||
std::vector< bool > exploration_finished(nb_cc, false);
|
||||
|
||||
// remove interior simplices
|
||||
BOOST_FOREACH(edge_descriptor ed, all_edges){
|
||||
edge_map1.erase(ed);
|
||||
edge_map2.erase(ed);
|
||||
remove_edge(ed, tmesh);
|
||||
|
||||
// init the stacks of halfedges using the cc of the boundary
|
||||
std::size_t index=0;
|
||||
std::map< halfedge_descriptor, std::size_t > ccs;
|
||||
typedef std::pair<const halfedge_descriptor, typename UF_ds::handle> Pair_type;
|
||||
BOOST_FOREACH(Pair_type p, handles)
|
||||
{
|
||||
halfedge_descriptor opp_hedge = opposite(p.first, tmesh);
|
||||
if (is_border(opp_hedge, tmesh)) continue; // nothing to do on the boundary
|
||||
|
||||
typedef typename std::map< halfedge_descriptor, std::size_t >::iterator Map_it;
|
||||
std::pair<Map_it, bool> insert_res=
|
||||
ccs.insert( std::make_pair(*uf.find( p.second ), index) );
|
||||
if (insert_res.second) ++index;
|
||||
|
||||
stacks_per_cc[ insert_res.first->second ].push_back( prev(opp_hedge, tmesh) );
|
||||
stacks_per_cc[ insert_res.first->second ].push_back( next(opp_hedge, tmesh) );
|
||||
faces_per_cc[ insert_res.first->second ].insert( face(opp_hedge, tmesh) );
|
||||
}
|
||||
|
||||
std::size_t nb_ccs_to_be_explored = nb_cc;
|
||||
index=0;
|
||||
//explore the cc's
|
||||
do{
|
||||
// try to extract one more face for a given cc
|
||||
do{
|
||||
CGAL_assertion( !exploration_finished[index] );
|
||||
halfedge_descriptor hd = stacks_per_cc[index].back();
|
||||
stacks_per_cc[index].pop_back();
|
||||
hd = opposite(hd, tmesh);
|
||||
if ( !is_border(hd,tmesh) && !marked_faces.count(face(hd, tmesh) ) )
|
||||
{
|
||||
if ( faces_per_cc[index].insert( face(hd, tmesh) ).second )
|
||||
{
|
||||
stacks_per_cc[index].push_back( next(hd, tmesh) );
|
||||
stacks_per_cc[index].push_back( prev(hd, tmesh) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (stacks_per_cc[index].empty()) break;
|
||||
}
|
||||
while(true);
|
||||
// the exploration of a cc is finished when its stack is empty
|
||||
exploration_finished[index]=stacks_per_cc[index].empty();
|
||||
if ( exploration_finished[index] ) --nb_ccs_to_be_explored;
|
||||
if ( nb_ccs_to_be_explored==1 ) break;
|
||||
while ( exploration_finished[(++index)%nb_cc] );
|
||||
index=index%nb_cc;
|
||||
}while(true);
|
||||
|
||||
/// \todo use the area criteria? this means maybe continue exploration of larger cc
|
||||
// mark faces of completetly explored cc
|
||||
for (index=0; index< nb_cc; ++index)
|
||||
if( exploration_finished[index] )
|
||||
{
|
||||
BOOST_FOREACH(face_descriptor fd, faces_per_cc[index])
|
||||
marked_faces.insert(fd);
|
||||
}
|
||||
}
|
||||
|
||||
// collect simplices to be removed
|
||||
std::set<vertex_descriptor> vertices_to_keep;
|
||||
std::set<halfedge_descriptor> halfedges_to_keep;
|
||||
BOOST_FOREACH(halfedge_descriptor hd, border)
|
||||
if ( !marked_faces.count(face(opposite(hd, tmesh), tmesh)) )
|
||||
{
|
||||
halfedges_to_keep.insert( hd );
|
||||
vertices_to_keep.insert( target(hd, tmesh) );
|
||||
}
|
||||
|
||||
// backup next,prev relationships to set after patch removal
|
||||
std::vector< std::pair<halfedge_descriptor, halfedge_descriptor> > next_prev_halfedge_pairs;
|
||||
halfedge_descriptor first_border_hd=*( halfedges_to_keep.begin() );
|
||||
halfedge_descriptor current_border_hd=first_border_hd;
|
||||
do{
|
||||
halfedge_descriptor prev_border_hd=current_border_hd;
|
||||
current_border_hd=next(current_border_hd, tmesh);
|
||||
while( marked_faces.count( face( opposite(current_border_hd, tmesh), tmesh) ) )
|
||||
current_border_hd=next(opposite(current_border_hd, tmesh), tmesh);
|
||||
next_prev_halfedge_pairs.push_back( std::make_pair(prev_border_hd, current_border_hd) );
|
||||
}while(current_border_hd!=first_border_hd);
|
||||
|
||||
// collect vertices and edges to remove and do remove faces
|
||||
std::set<edge_descriptor> edges_to_remove;
|
||||
std::set<vertex_descriptor> vertices_to_remove;
|
||||
BOOST_FOREACH(face_descriptor fd, marked_faces)
|
||||
{
|
||||
halfedge_descriptor hd=halfedge(fd, tmesh);
|
||||
for(int i=0; i<3; ++i)
|
||||
{
|
||||
if ( !halfedges_to_keep.count(hd) )
|
||||
edges_to_remove.insert( edge(hd, tmesh) );
|
||||
if ( !vertices_to_keep.count(target(hd,tmesh)) )
|
||||
vertices_to_remove.insert( target(hd,tmesh) );
|
||||
hd=next(hd, tmesh);
|
||||
}
|
||||
remove_face(fd, tmesh);
|
||||
}
|
||||
|
||||
// remove vertices
|
||||
BOOST_FOREACH(vertex_descriptor vd, vertices_to_remove)
|
||||
remove_vertex(vd, tmesh);
|
||||
// remove edges
|
||||
BOOST_FOREACH(edge_descriptor ed, edges_to_remove)
|
||||
{
|
||||
null_edges_to_remove.erase(ed);
|
||||
remove_edge(ed, tmesh);
|
||||
}
|
||||
|
||||
// add a new face, set all border edges pointing to it
|
||||
// and update halfedge vertex of patch boundary vertices
|
||||
face_descriptor new_face = add_face(tmesh);
|
||||
typedef std::pair<halfedge_descriptor, halfedge_descriptor> Pair_type;
|
||||
BOOST_FOREACH(const Pair_type& p, next_prev_halfedge_pairs)
|
||||
{
|
||||
set_face(p.first, new_face, tmesh);
|
||||
set_next(p.first, p.second, tmesh);
|
||||
set_halfedge(target(p.first, tmesh), p.first, tmesh);
|
||||
}
|
||||
set_halfedge(new_face, first_border_hd, tmesh);
|
||||
// triangulate the new face and update the coordinate of the central vertex
|
||||
halfedge_descriptor new_hd=Euler::add_center_vertex(first_border_hd, tmesh);
|
||||
put(vpmap, target(new_hd, tmesh), pt);
|
||||
|
||||
BOOST_FOREACH(halfedge_descriptor hd, halfedges_around_target(new_hd, tmesh))
|
||||
if ( traits.equal_3_object()(get(vpmap, target(hd, tmesh)), get(vpmap, source(hd, tmesh))) )
|
||||
null_edges_to_remove.insert(edge(hd, tmesh));
|
||||
|
||||
CGAL_assertion( is_valid(tmesh) );
|
||||
}
|
||||
BOOST_FOREACH(vertex_descriptor vd, all_vertices)
|
||||
remove_vertex(vd, tmesh);
|
||||
BOOST_FOREACH(face_descriptor fd, all_faces)
|
||||
remove_face(fd, tmesh);
|
||||
}
|
||||
} // end of namespace internal
|
||||
#endif
|
||||
|
||||
return nb_deg_faces;
|
||||
}
|
||||
|
||||
template <class EdgeRange, class TriangleMesh>
|
||||
std::size_t remove_null_edges(
|
||||
const EdgeRange& edge_range,
|
||||
TriangleMesh& tmesh)
|
||||
{
|
||||
return remove_null_edges(edge_range, tmesh,
|
||||
parameters::all_default());
|
||||
}
|
||||
|
||||
/// \ingroup PkgPolygonMeshProcessing
|
||||
/// removes the degenerate faces from a triangulated surface mesh.
|
||||
|
|
@ -266,7 +466,7 @@ namespace internal {
|
|||
/// \cgalNamedParamsEnd
|
||||
///
|
||||
/// \return number of removed degenerate faces
|
||||
///
|
||||
/// \endcond
|
||||
template <class TriangleMesh, class NamedParameters>
|
||||
std::size_t remove_degenerate_faces(TriangleMesh& tmesh,
|
||||
const NamedParameters& np)
|
||||
|
|
@ -291,286 +491,10 @@ std::size_t remove_degenerate_faces(TriangleMesh& tmesh,
|
|||
typedef typename GetGeomTraits<TM, NamedParameters>::type Traits;
|
||||
Traits traits = choose_param(get_param(np, geom_traits), Traits());
|
||||
|
||||
std::size_t nb_deg_faces = 0;
|
||||
|
||||
// First remove edges of length 0
|
||||
std::set<edge_descriptor> null_edges_to_remove;
|
||||
std::size_t nb_deg_faces = remove_null_edges(edges(tmesh), tmesh, np);
|
||||
|
||||
BOOST_FOREACH(edge_descriptor ed, edges(tmesh))
|
||||
{
|
||||
if ( traits.equal_3_object()(get(vpmap, target(ed, tmesh)), get(vpmap, source(ed, tmesh))) )
|
||||
null_edges_to_remove.insert(ed);
|
||||
}
|
||||
|
||||
std::size_t nb_edges_previously_skipped = 0;
|
||||
do{
|
||||
std::set<edge_descriptor> edges_to_remove_skipped;
|
||||
while (!null_edges_to_remove.empty())
|
||||
{
|
||||
edge_descriptor ed = *null_edges_to_remove.begin();
|
||||
null_edges_to_remove.erase(null_edges_to_remove.begin());
|
||||
|
||||
halfedge_descriptor h = halfedge(ed, tmesh);
|
||||
|
||||
if (CGAL::Euler::does_satisfy_link_condition(ed,tmesh))
|
||||
{
|
||||
// remove edges that could also be set for removal
|
||||
if ( face(h, tmesh)!=GT::null_face() )
|
||||
{
|
||||
++nb_deg_faces;
|
||||
null_edges_to_remove.erase(edge(prev(h, tmesh), tmesh));
|
||||
edges_to_remove_skipped.erase(edge(prev(h, tmesh), tmesh));
|
||||
}
|
||||
if (face(opposite(h, tmesh), tmesh)!=GT::null_face())
|
||||
{
|
||||
++nb_deg_faces;
|
||||
null_edges_to_remove.erase(edge(prev(opposite(h, tmesh), tmesh), tmesh));
|
||||
edges_to_remove_skipped.erase(edge(prev(opposite(h, tmesh), tmesh), tmesh));
|
||||
}
|
||||
//now remove the edge
|
||||
CGAL::Euler::collapse_edge(ed, tmesh);
|
||||
}
|
||||
else{
|
||||
//backup central point
|
||||
typename Traits::Point_3 pt = get(vpmap, source(ed, tmesh));
|
||||
|
||||
// mark faces of the link of each endpoints of the edge which collapse is not topologically valid
|
||||
std::set<face_descriptor> marked_faces;
|
||||
std::vector<halfedge_descriptor> candidate_border;
|
||||
// first endpoint
|
||||
BOOST_FOREACH( halfedge_descriptor hd, CGAL::halfedges_around_target(halfedge(ed,tmesh), tmesh) )
|
||||
{
|
||||
marked_faces.insert( face(hd, tmesh) );
|
||||
candidate_border.push_back( prev(hd, tmesh) );
|
||||
}
|
||||
// second endpoint
|
||||
BOOST_FOREACH( halfedge_descriptor hd, CGAL::halfedges_around_target(opposite(halfedge(ed, tmesh), tmesh), tmesh) )
|
||||
{
|
||||
marked_faces.insert( face(hd, tmesh) );
|
||||
candidate_border.push_back( prev(hd, tmesh) );
|
||||
}
|
||||
|
||||
// extract the halfedge on the boundary of the marked region
|
||||
std::vector<halfedge_descriptor> border;
|
||||
BOOST_FOREACH(halfedge_descriptor hd, candidate_border)
|
||||
{
|
||||
if ( marked_faces.count( face(hd, tmesh) )!=
|
||||
marked_faces.count( face(opposite(hd, tmesh), tmesh) ) )
|
||||
{
|
||||
border.push_back( hd );
|
||||
}
|
||||
}
|
||||
|
||||
// define cc of border halfedges: two halfedges are in the same cc
|
||||
// if they are on the border of a set of non-marked faces sharing
|
||||
// a common vertex
|
||||
typedef CGAL::Union_find<halfedge_descriptor> UF_ds;
|
||||
UF_ds uf;
|
||||
std::map<halfedge_descriptor, typename UF_ds::handle> handles;
|
||||
// one cc per border halfedge
|
||||
BOOST_FOREACH(halfedge_descriptor hd, border)
|
||||
handles.insert( std::make_pair(hd, uf.make_set(hd)) );
|
||||
|
||||
// join cc's
|
||||
BOOST_FOREACH(halfedge_descriptor hd, border)
|
||||
{
|
||||
CGAL_assertion( marked_faces.count( face( hd, tmesh) ) > 0);
|
||||
CGAL_assertion( marked_faces.count( face( opposite(hd, tmesh), tmesh) ) == 0 );
|
||||
halfedge_descriptor candidate = hd;
|
||||
|
||||
do{
|
||||
candidate = prev( opposite(candidate, tmesh), tmesh );
|
||||
} while( !marked_faces.count( face( opposite(candidate, tmesh), tmesh) ) );
|
||||
uf.unify_sets( handles[hd], handles[opposite(candidate, tmesh)] );
|
||||
}
|
||||
|
||||
std::size_t nb_cc = uf.number_of_sets();
|
||||
if ( nb_cc != 1 )
|
||||
{
|
||||
// if more than one connected component is found then the patch
|
||||
// made of marked faces contains "non-manifold" vertices.
|
||||
// The smallest components need to be marked so that the patch
|
||||
// made of marked faces is a topological disk
|
||||
|
||||
// extract one border halfedge per cc
|
||||
std::set< halfedge_descriptor > ccs;
|
||||
BOOST_FOREACH(halfedge_descriptor hd, border)
|
||||
ccs.insert( *uf.find( handles[hd] ) );
|
||||
|
||||
// we will explore in parallel the connected components and will stop
|
||||
// when all but one connected component have been entirely explored.
|
||||
// We have one face at a time for each cc in order to not explore a
|
||||
// potentially very large cc.
|
||||
std::vector< std::vector<halfedge_descriptor> > stacks_per_cc(nb_cc);
|
||||
std::vector< std::set<face_descriptor> > faces_per_cc(nb_cc);
|
||||
std::vector< bool > exploration_finished(nb_cc, false);
|
||||
|
||||
// init stacks
|
||||
std::size_t index=0;
|
||||
BOOST_FOREACH( halfedge_descriptor hd, ccs)
|
||||
{
|
||||
halfedge_descriptor opp_hedge = opposite(hd, tmesh);
|
||||
stacks_per_cc[ index ].push_back( prev(opp_hedge, tmesh) );
|
||||
stacks_per_cc[ index ].push_back( next(opp_hedge, tmesh) );
|
||||
faces_per_cc[ index ].insert( face(opp_hedge, tmesh) );
|
||||
++index;
|
||||
}
|
||||
|
||||
std::size_t nb_ccs_to_be_explored = nb_cc;
|
||||
index=0;
|
||||
//explore the cc's
|
||||
do{
|
||||
// try to extract one more face for a given cc
|
||||
do{
|
||||
CGAL_assertion( !exploration_finished[index] );
|
||||
halfedge_descriptor hd = stacks_per_cc[index].back();
|
||||
stacks_per_cc[index].pop_back();
|
||||
hd = opposite(hd, tmesh);
|
||||
if ( !marked_faces.count(face(hd, tmesh) ) )
|
||||
{
|
||||
if ( faces_per_cc[index].insert( face(hd, tmesh) ).second )
|
||||
{
|
||||
stacks_per_cc[index].push_back( next(hd, tmesh) );
|
||||
stacks_per_cc[index].push_back( prev(hd, tmesh) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (stacks_per_cc[index].empty()) break;
|
||||
}
|
||||
while(true);
|
||||
// the exploration of a cc is finished when its stack is empty
|
||||
exploration_finished[index]=stacks_per_cc[index].empty();
|
||||
if ( exploration_finished[index] ) --nb_ccs_to_be_explored;
|
||||
if ( nb_ccs_to_be_explored==1 ) break;
|
||||
while ( exploration_finished[(++index)%nb_cc] );
|
||||
index=index%nb_cc;
|
||||
}while(true);
|
||||
|
||||
/// \todo use the area criteria? this means maybe continue exploration of larger cc
|
||||
// mark faces of completetly explored cc
|
||||
for (index=0; index< nb_cc; ++index)
|
||||
if( exploration_finished[index] )
|
||||
{
|
||||
BOOST_FOREACH(face_descriptor fd, faces_per_cc[index])
|
||||
marked_faces.insert(fd);
|
||||
}
|
||||
}
|
||||
|
||||
// collect simplices to be removed
|
||||
std::set<vertex_descriptor> vertices_to_keep;
|
||||
std::set<halfedge_descriptor> halfedges_to_keep;
|
||||
BOOST_FOREACH(halfedge_descriptor hd, border)
|
||||
if ( !marked_faces.count(face(opposite(hd, tmesh), tmesh)) )
|
||||
{
|
||||
halfedges_to_keep.insert( hd );
|
||||
vertices_to_keep.insert( target(hd, tmesh) );
|
||||
}
|
||||
|
||||
// backup next,prev relationships to set after patch removal
|
||||
std::vector< std::pair<halfedge_descriptor, halfedge_descriptor> > next_prev_halfedge_pairs;
|
||||
halfedge_descriptor first_border_hd=*( halfedges_to_keep.begin() );
|
||||
halfedge_descriptor current_border_hd=first_border_hd;
|
||||
do{
|
||||
halfedge_descriptor prev_border_hd=current_border_hd;
|
||||
current_border_hd=next(current_border_hd, tmesh);
|
||||
while( marked_faces.count( face( opposite(current_border_hd, tmesh), tmesh) ) )
|
||||
current_border_hd=next(opposite(current_border_hd, tmesh), tmesh);
|
||||
next_prev_halfedge_pairs.push_back( std::make_pair(prev_border_hd, current_border_hd) );
|
||||
}while(current_border_hd!=first_border_hd);
|
||||
|
||||
// collect vertices and edges to remove and do remove faces
|
||||
std::set<edge_descriptor> edges_to_remove;
|
||||
std::set<vertex_descriptor> vertices_to_remove;
|
||||
BOOST_FOREACH(face_descriptor fd, marked_faces)
|
||||
{
|
||||
halfedge_descriptor hd=halfedge(fd, tmesh);
|
||||
for(int i=0; i<3; ++i)
|
||||
{
|
||||
if ( !halfedges_to_keep.count(hd) )
|
||||
edges_to_remove.insert( edge(hd, tmesh) );
|
||||
if ( !vertices_to_keep.count(target(hd,tmesh)) )
|
||||
vertices_to_remove.insert( target(hd,tmesh) );
|
||||
hd=next(hd, tmesh);
|
||||
}
|
||||
remove_face(fd, tmesh);
|
||||
}
|
||||
|
||||
// remove vertices
|
||||
BOOST_FOREACH(vertex_descriptor vd, vertices_to_remove)
|
||||
remove_vertex(vd, tmesh);
|
||||
// remove edges
|
||||
BOOST_FOREACH(edge_descriptor ed, edges_to_remove)
|
||||
{
|
||||
null_edges_to_remove.erase(ed);
|
||||
remove_edge(ed, tmesh);
|
||||
}
|
||||
|
||||
// add a new face, set all border edges pointing to it
|
||||
// and update halfedge vertex of patch boundary vertices
|
||||
face_descriptor new_face = add_face(tmesh);
|
||||
typedef std::pair<halfedge_descriptor, halfedge_descriptor> Pair_type;
|
||||
BOOST_FOREACH(const Pair_type& p, next_prev_halfedge_pairs)
|
||||
{
|
||||
set_face(p.first, new_face, tmesh);
|
||||
set_next(p.first, p.second, tmesh);
|
||||
set_halfedge(target(p.first, tmesh), p.first, tmesh);
|
||||
}
|
||||
set_halfedge(new_face, first_border_hd, tmesh);
|
||||
// triangulate the new face and update the coordinate of the central vertex
|
||||
halfedge_descriptor new_hd=Euler::add_center_vertex(first_border_hd, tmesh);
|
||||
put(vpmap, target(new_hd, tmesh), pt);
|
||||
|
||||
BOOST_FOREACH(halfedge_descriptor hd, halfedges_around_target(new_hd, tmesh))
|
||||
if ( traits.equal_3_object()(get(vpmap, target(hd, tmesh)), get(vpmap, source(hd, tmesh))) )
|
||||
null_edges_to_remove.insert(edge(hd, tmesh));
|
||||
|
||||
#if 0
|
||||
// the following test filters in particular cases where the
|
||||
// detection of the vertex that breaks the link condition
|
||||
// is not correctly detected by find_larger_triangle
|
||||
// (i.e. when the hedges detected should be used with the opposite edge)
|
||||
if ( traits.collinear_3_object()(
|
||||
get(vpmap, target(h, tmesh)),
|
||||
get(vpmap, target(next(h, tmesh), tmesh)),
|
||||
get(vpmap, target(next(opposite(h, tmesh), tmesh), tmesh)) ) )
|
||||
{
|
||||
// we handle this case in the next loop removing set of degenerated
|
||||
// triangles which points are collinear
|
||||
edges_to_remove_skipped.insert(ed);
|
||||
continue;
|
||||
}
|
||||
|
||||
do{
|
||||
// improve the link condition on h's side
|
||||
boost::optional< std::pair<halfedge_descriptor, halfedge_descriptor> >
|
||||
res = internal::find_larger_triangle(h, tmesh, vpmap, traits);
|
||||
if (res)
|
||||
internal::remove_faces_inside_triangle(res->first, h, res->second, tmesh, null_edges_to_remove, edges_to_remove_skipped);
|
||||
|
||||
// improve the link condition on opposite(h)'s side
|
||||
h=opposite(h, tmesh);
|
||||
res = internal::find_larger_triangle(h, tmesh, vpmap, traits);
|
||||
if (res)
|
||||
internal::remove_faces_inside_triangle(res->first, h, res->second, tmesh, null_edges_to_remove, edges_to_remove_skipped);
|
||||
h=opposite(h, tmesh);
|
||||
ed=edge(h, tmesh);
|
||||
|
||||
} while(!CGAL::Euler::does_satisfy_link_condition(ed,tmesh));
|
||||
|
||||
null_edges_to_remove.insert( ed );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// check if some edges were skipped due to link condition not satisfied
|
||||
// that could now be satisfied
|
||||
if (edges_to_remove_skipped.empty() ||
|
||||
edges_to_remove_skipped.size()==nb_edges_previously_skipped) break;
|
||||
null_edges_to_remove.swap(edges_to_remove_skipped);
|
||||
nb_edges_previously_skipped = null_edges_to_remove.size();
|
||||
} while(true);
|
||||
|
||||
// remove triangles made of 3 collinear points
|
||||
// Then, remove triangles made of 3 collinear points
|
||||
std::set<face_descriptor> degenerate_face_set;
|
||||
BOOST_FOREACH(face_descriptor fd, faces(tmesh))
|
||||
if ( is_degenerated(fd, tmesh, vpmap, traits) )
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
OFF
|
||||
7 7 0
|
||||
1 0 0
|
||||
0 1 0
|
||||
1 1 0
|
||||
2 1 0
|
||||
1 1 0
|
||||
1 2 0
|
||||
0.5 1 0
|
||||
3 0 2 1
|
||||
3 0 3 2
|
||||
3 4 3 5
|
||||
3 1 4 5
|
||||
3 1 2 6
|
||||
3 6 2 4
|
||||
3 6 4 1
|
||||
|
|
@ -32,6 +32,7 @@ int main()
|
|||
fix("data_degeneracies/degtri_on_border.off");
|
||||
fix("data_degeneracies/degtri_three.off");
|
||||
fix("data_degeneracies/degtri_single.off");
|
||||
fix("data_degeneracies/trihole.off");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ class Scene_item;
|
|||
// OpenGL rendering mode
|
||||
enum RenderingMode { Points = 0,
|
||||
PointsPlusNormals,
|
||||
Splatting,
|
||||
Wireframe,
|
||||
Flat,
|
||||
FlatPlusEdges,
|
||||
|
|
|
|||
|
|
@ -32,8 +32,10 @@ public:
|
|||
virtual bool inFastDrawing() const = 0;
|
||||
typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDARBPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
|
||||
typedef void (APIENTRYP PFNGLVERTEXATTRIBDIVISORARBPROC) (GLuint index, GLuint divisor);
|
||||
typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLuint target, GLuint attachment, GLuint textarget, GLuint texture, GLint level);
|
||||
PFNGLDRAWARRAYSINSTANCEDARBPROC glDrawArraysInstanced;
|
||||
PFNGLVERTEXATTRIBDIVISORARBPROC glVertexAttribDivisor;
|
||||
PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2D;
|
||||
bool extension_is_found;
|
||||
GLfloat pickMatrix_[16];
|
||||
|
||||
|
|
|
|||
|
|
@ -62,6 +62,20 @@ if (EIGEN3_FOUND)
|
|||
include( ${EIGEN3_USE_FILE} )
|
||||
endif(EIGEN3_FOUND)
|
||||
|
||||
# Activate concurrency?
|
||||
option(POLYHEDRON_DEMO_ACTIVATE_CONCURRENCY
|
||||
"Enable concurrency"
|
||||
ON)
|
||||
|
||||
if( POLYHEDRON_DEMO_ACTIVATE_CONCURRENCY )
|
||||
find_package( TBB )
|
||||
if( TBB_FOUND )
|
||||
include( ${TBB_USE_FILE} )
|
||||
list( APPEND CGAL_3RD_PARTY_LIBRARIES ${TBB_LIBRARIES} )
|
||||
else()
|
||||
message( STATUS "NOTICE: Intel TBB was not found. Bilateral smoothing and WLOP plugins are faster if TBB is linked." )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND)
|
||||
|
||||
|
|
@ -101,6 +115,11 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND)
|
|||
|
||||
|
||||
qt5_add_resources ( RESOURCE_FILES Polyhedron_3.qrc )
|
||||
qt5_add_resources(gl_splat_rc GlSplat/glsplat.qrc)
|
||||
add_library(gl_splat SHARED
|
||||
GlSplat/GlSplat.cpp GlSplat/Shader.cpp ${gl_splat_rc})
|
||||
qt5_use_modules(gl_splat OpenGL Gui Xml)
|
||||
target_link_libraries(gl_splat ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTOPENGL_LIBRARY} ${GLEW_LIBRARIES})
|
||||
|
||||
qt5_generate_moc( "CGAL_demo/Viewer_interface.h" "${CMAKE_CURRENT_BINARY_DIR}/Viewer_interface_moc.cpp" )
|
||||
|
||||
|
|
@ -187,6 +206,8 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND)
|
|||
|
||||
target_link_libraries(scene_nef_polyhedron_item scene_polyhedron_item)
|
||||
add_item(scene_points_with_normal_item Scene_points_with_normal_item.cpp)# Scene_points_with_normal_item.moc)
|
||||
target_link_libraries( scene_points_with_normal_item gl_splat ${GLEW_LIBRARIES} )
|
||||
target_link_libraries( demo_framework gl_splat ${GLEW_LIBRARIES} )
|
||||
|
||||
foreach( lib
|
||||
demo_framework
|
||||
|
|
@ -228,6 +249,7 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND)
|
|||
target_link_libraries( Polyhedron_3 ${QT_LIBRARIES} )
|
||||
target_link_libraries( Polyhedron_3 demo_framework )
|
||||
target_link_libraries( Polyhedron_3 point_dialog )
|
||||
target_link_libraries( Polyhedron_3 gl_splat ${GLEW_LIBRARIES})
|
||||
|
||||
# Link with CGAL
|
||||
target_link_libraries( Polyhedron_3 ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES} )
|
||||
|
|
@ -235,6 +257,7 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND)
|
|||
# Link with libQGLViewer, OpenGL
|
||||
target_link_libraries( Polyhedron_3 ${QGLVIEWER_LIBRARIES} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} )
|
||||
|
||||
|
||||
add_to_cached_list( CGAL_EXECUTABLE_TARGETS Polyhedron_3 )
|
||||
|
||||
|
||||
|
|
@ -439,6 +462,20 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND)
|
|||
polyhedron_demo_plugin(point_set_shape_detection_plugin Polyhedron_demo_point_set_shape_detection_plugin ${point_set_shape_detectionUI_FILES})
|
||||
target_link_libraries(point_set_shape_detection_plugin scene_polyhedron_item scene_points_with_normal_item)
|
||||
|
||||
qt5_wrap_ui(point_set_wlopFILES Polyhedron_demo_point_set_wlop_plugin.ui)
|
||||
polyhedron_demo_plugin(point_set_wlop_plugin Polyhedron_demo_point_set_wlop_plugin ${point_set_wlopFILES})
|
||||
target_link_libraries(point_set_wlop_plugin scene_points_with_normal_item)
|
||||
|
||||
qt5_wrap_ui(point_set_bilateral_smoothingUI_FILES Polyhedron_demo_point_set_bilateral_smoothing_plugin.ui)
|
||||
polyhedron_demo_plugin(point_set_bilateral_smoothing_plugin Polyhedron_demo_point_set_bilateral_smoothing_plugin ${point_set_bilateral_smoothingUI_FILES})
|
||||
target_link_libraries(point_set_bilateral_smoothing_plugin scene_points_with_normal_item)
|
||||
|
||||
qt5_wrap_ui(point_set_upsamplingUI_FILES Polyhedron_demo_point_set_upsampling_plugin.ui)
|
||||
polyhedron_demo_plugin(point_set_upsampling_plugin Polyhedron_demo_point_set_upsampling_plugin ${point_set_upsamplingUI_FILES})
|
||||
target_link_libraries(point_set_upsampling_plugin scene_points_with_normal_item)
|
||||
|
||||
qt5_wrap_ui( ps_outliers_removal_UI_FILES Polyhedron_demo_point_set_outliers_removal_plugin.ui)
|
||||
|
||||
polyhedron_demo_plugin(point_set_outliers_removal_plugin Polyhedron_demo_point_set_outliers_removal_plugin ${ps_outliers_removal_UI_FILES})
|
||||
target_link_libraries(point_set_outliers_removal_plugin scene_points_with_normal_item)
|
||||
|
||||
|
|
@ -486,6 +523,12 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND)
|
|||
NAMESPACE Polyhedron_
|
||||
APPEND FILE polyhedron_demo_targets.cmake)
|
||||
|
||||
export(
|
||||
TARGETS
|
||||
gl_splat
|
||||
NAMESPACE Polyhedron_
|
||||
APPEND FILE polyhedron_demo_targets.cmake)
|
||||
|
||||
configure_file(CGAL_polyhedron_demoConfig.cmake.in CGAL_polyhedron_demoConfig.cmake)
|
||||
|
||||
else (CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
|
||||
project(GlSplat)
|
||||
|
||||
cmake_minimum_required(VERSION 2.6.0)
|
||||
if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}" VERSION_GREATER 2.8.3)
|
||||
cmake_policy(VERSION 2.8.4)
|
||||
else()
|
||||
cmake_policy(VERSION 2.6)
|
||||
endif()
|
||||
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
|
||||
|
||||
find_package(Qt4 REQUIRED)
|
||||
find_package(GLEW REQUIRED)
|
||||
|
||||
set(QT_USE_QTOPENGL TRUE)
|
||||
set(QT_USE_QTXML TRUE)
|
||||
include(${QT_USE_FILE})
|
||||
include_directories( ${QT_QTOPENGL_INCLUDE_DIR} ${QT_QTXML_INCLUDE_DIR} ${GLEW_INCLUDE_DIR})
|
||||
|
||||
set(srcs Shader.cpp GlSplat.cpp)
|
||||
|
||||
qt4_automoc( ${srcs})
|
||||
qt4_add_resources(srcs glsplat.qrc)
|
||||
|
||||
add_library(GlSplat SHARED ${srcs})
|
||||
target_link_libraries(GlSplat ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTOPENGL_LIBRARY} ${GLEW_LIBRARIES})
|
||||
|
||||
find_package(QGLViewer)
|
||||
if(QGLVIEWER_FOUND)
|
||||
include_directories( ${QGLViewer_INCLUDES})
|
||||
add_executable(demo demo.cpp)
|
||||
target_link_libraries(demo ${QT_QTXML_LIBRARY} ${QGLViewer_LIBRARIES} GlSplat)
|
||||
else()
|
||||
message("QGLViewer not found, demo won't be built")
|
||||
endif()
|
||||
|
|
@ -0,0 +1,535 @@
|
|||
// This file is part of GlSplat, a simple splatting C++ library
|
||||
//
|
||||
// Copyright (C) 2008-2009 Gael Guennebaud <g.gael@free.fr>
|
||||
//
|
||||
// GlSplat is free software; 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 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// GlSplat is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with GlSplat. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include <QtGui>
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
|
||||
#include "GlSplat.h"
|
||||
#include "Shader.h"
|
||||
|
||||
#include <QGLWidget>
|
||||
#include <QTextStream>
|
||||
#include <QGLFramebufferObject>
|
||||
|
||||
|
||||
namespace GlSplat {
|
||||
|
||||
SplatRenderer::SplatRenderer()
|
||||
{
|
||||
mNormalTextureID = 0;
|
||||
mDepthTextureID = 0;
|
||||
mIsSupported = false;
|
||||
viewer_is_set = false;
|
||||
mRenderBuffer = 0;
|
||||
mWorkaroundATI = false;
|
||||
mBuggedAtiBlending = false;
|
||||
mDummyTexId = 0;
|
||||
mIsInitialized = false;
|
||||
|
||||
mFlags = DEFERRED_SHADING_BIT | DEPTH_CORRECTION_BIT | FLOAT_BUFFER_BIT | OUTPUT_DEPTH_BIT;
|
||||
mCachedFlags = ~mFlags;
|
||||
// union of bits which controls the render buffer
|
||||
mRenderBufferMask = DEFERRED_SHADING_BIT | FLOAT_BUFFER_BIT;
|
||||
}
|
||||
|
||||
QString SplatRenderer::loadSource(const QString& func,const QString& filename)
|
||||
{
|
||||
QString res;
|
||||
QFile f(":/SplatRenderer/shaders/" + filename);
|
||||
if (!f.open(QFile::ReadOnly))
|
||||
{
|
||||
std::cerr << "failed to load shader file " << filename.toLatin1().data() << "\n";
|
||||
return res;
|
||||
}
|
||||
else qDebug("Succesfully loaded shader func '%s' in file '%s'",qPrintable(func),qPrintable(filename));
|
||||
QTextStream stream(&f);
|
||||
res = stream.readAll();
|
||||
f.close();
|
||||
res = QString("#define GLSPLAT__%1__ 1\n").arg(func)
|
||||
+ QString("#define %1 main\n").arg(func)
|
||||
+ res;
|
||||
return res;
|
||||
}
|
||||
|
||||
void SplatRenderer::configureShaders()
|
||||
{
|
||||
// const char* passNames[3] = {"Visibility","Attribute","Finalization"};
|
||||
QString defines = "";
|
||||
if (mFlags & DEFERRED_SHADING_BIT)
|
||||
defines += "#define ES_DEFERRED_SHADING\n";
|
||||
if (mFlags & DEPTH_CORRECTION_BIT)
|
||||
defines += "#define ES_DEPTH_CORRECTION\n";
|
||||
if (mFlags & OUTPUT_DEPTH_BIT)
|
||||
defines += "#define ES_OUTPUT_DEPTH 1\n";
|
||||
if (mFlags & BACKFACE_SHADING_BIT)
|
||||
defines += "#define ES_BACKFACE_SHADING\n";
|
||||
if (mWorkaroundATI)
|
||||
defines += "#define ES_ATI_WORKAROUND\n";
|
||||
|
||||
QString shading =
|
||||
"vec4 meshlabLighting(vec4 color, vec3 eyePos, vec3 normal)"
|
||||
"{"
|
||||
" normal = normalize(normal);"
|
||||
" vec3 lightVec = normalize(gl_LightSource[0].position.xyz);"
|
||||
" vec3 halfVec = normalize( lightVec - normalize(eyePos) );"
|
||||
" float aux_dot = dot(normal,lightVec);"
|
||||
" float diffuseCoeff = clamp(aux_dot, 0.0, 1.0);"
|
||||
" float specularCoeff = aux_dot>0.0 ? clamp(pow(clamp(dot(halfVec, normal),0.0,1.0),gl_FrontMaterial.shininess), 0.0, 1.0) : 0.0;"
|
||||
" return vec4(color.rgb * ( gl_FrontLightProduct[0].ambient.rgb + diffuseCoeff * gl_FrontLightProduct[0].diffuse.rgb) + specularCoeff * gl_FrontLightProduct[0].specular.rgb, 1.0);"
|
||||
"}\n";
|
||||
|
||||
for (int k=0;k<3;++k)
|
||||
{
|
||||
QString vsrc = shading + defines + mShaderSrcs[k*2+0];
|
||||
QString fsrc = shading + defines + mShaderSrcs[k*2+1];
|
||||
if(!mShaders[k].loadSources(mShaderSrcs[k*2+0]!="" ? vsrc.toLatin1().data() : 0,
|
||||
mShaderSrcs[k*2+1]!="" ? fsrc.toLatin1().data() : 0/*,
|
||||
Shader::Warnings*/))
|
||||
mIsSupported = false;
|
||||
}
|
||||
}
|
||||
|
||||
void SplatRenderer::init(QGLWidget *qglw)
|
||||
{
|
||||
mIsSupported = true;
|
||||
if(qglw)
|
||||
qglw->makeCurrent();
|
||||
|
||||
//glewInit();
|
||||
const char* rs = (const char*)glGetString(GL_RENDERER);
|
||||
QString rendererString("");
|
||||
if(rs)
|
||||
rendererString = QString(rs);
|
||||
mWorkaroundATI = rendererString.startsWith("ATI") || rendererString.startsWith("AMD");
|
||||
// FIXME: maybe some recent HW correctly supports floating point blending...
|
||||
mBuggedAtiBlending = rendererString.startsWith("ATI") || rendererString.startsWith("AMD");
|
||||
|
||||
if (mWorkaroundATI && mDummyTexId==0)
|
||||
{
|
||||
viewer->glActiveTexture(GL_TEXTURE0);
|
||||
viewer->glGenTextures(1,&mDummyTexId);
|
||||
viewer->glBindTexture(GL_TEXTURE_2D, mDummyTexId);
|
||||
viewer->glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 4, 4, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0);
|
||||
}
|
||||
|
||||
// let's check the GPU capabilities
|
||||
mSupportedMask = DEPTH_CORRECTION_BIT | BACKFACE_SHADING_BIT;
|
||||
if (!QGLFramebufferObject::hasOpenGLFramebufferObjects ())
|
||||
{
|
||||
std::cout << "SplatRenderer: error OpenGL frame buffer objects are not supported. (please, try to update your drivers)\n";
|
||||
mIsSupported = false;
|
||||
return;
|
||||
}
|
||||
//if (GLEW_ARB_texture_float)
|
||||
mSupportedMask |= FLOAT_BUFFER_BIT;
|
||||
//else
|
||||
// std::cout << "SplatRenderer: warning floating point textures are not supported.\n";
|
||||
|
||||
// if (GLEW_ARB_draw_buffers && (!mBuggedAtiBlending))
|
||||
mSupportedMask |= DEFERRED_SHADING_BIT;
|
||||
//else
|
||||
// std::cout << "SplatRenderer: warning deferred shading is not supported.\n";
|
||||
|
||||
//if (GLEW_ARB_shadow)
|
||||
mSupportedMask |= OUTPUT_DEPTH_BIT;
|
||||
//else
|
||||
// std::cerr << "SplatRenderer: warning copy of the depth buffer is not supported.\n";
|
||||
|
||||
mFlags = mFlags & mSupportedMask;
|
||||
|
||||
// load shader source
|
||||
mShaderSrcs[0] = loadSource("VisibilityVP","Raycasting.glsl");
|
||||
mShaderSrcs[1] = loadSource("VisibilityFP","Raycasting.glsl");
|
||||
mShaderSrcs[2] = loadSource("AttributeVP","Raycasting.glsl");
|
||||
mShaderSrcs[3] = loadSource("AttributeFP","Raycasting.glsl");
|
||||
mShaderSrcs[4] = "";
|
||||
mShaderSrcs[5] = loadSource("Finalization","Finalization.glsl");
|
||||
|
||||
mCurrentPass = 2;
|
||||
mBindedPass = -1;
|
||||
mIsInitialized = true;
|
||||
|
||||
}
|
||||
|
||||
void SplatRenderer::updateRenderBuffer()
|
||||
{
|
||||
if ( (!mRenderBuffer)
|
||||
|| (mRenderBuffer->width()!=mCachedVP[2])
|
||||
|| (mRenderBuffer->height()!=mCachedVP[3])
|
||||
|| ( (mCachedFlags & mRenderBufferMask) != (mFlags & mRenderBufferMask) ))
|
||||
{
|
||||
delete mRenderBuffer;
|
||||
GLenum fmt = (mFlags&FLOAT_BUFFER_BIT) ? GL_RGBA16F_ARB : GL_RGBA;
|
||||
mRenderBuffer = new QGLFramebufferObject(mCachedVP[2], mCachedVP[3],
|
||||
(mFlags&OUTPUT_DEPTH_BIT) ? QGLFramebufferObject::NoAttachment : QGLFramebufferObject::Depth,
|
||||
GL_TEXTURE_RECTANGLE_ARB, fmt);
|
||||
|
||||
if (!mRenderBuffer->isValid())
|
||||
{
|
||||
std::cout << "SplatRenderer: invalid FBO\n";
|
||||
}
|
||||
|
||||
|
||||
if (mFlags&DEFERRED_SHADING_BIT)
|
||||
{
|
||||
// in deferred shading mode we need an additional buffer to accumulate the normals
|
||||
if (mNormalTextureID==0)
|
||||
viewer->glGenTextures(1,&mNormalTextureID);
|
||||
//glBindTexture(GL_TEXTURE_RECTANGLE_ARB, mNormalTextureID);
|
||||
viewer->glBindTexture(GL_TEXTURE_RECTANGLE, mNormalTextureID);
|
||||
//glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, fmt, mCachedVP[2], mCachedVP[3], 0, GL_RGBA, GL_FLOAT, 0);
|
||||
viewer->glTexImage2D(GL_TEXTURE_RECTANGLE, 0, fmt, mCachedVP[2], mCachedVP[3], 0, GL_RGBA, GL_FLOAT, 0);
|
||||
//glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
viewer->glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
//glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
viewer->glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
mRenderBuffer->bind();
|
||||
viewer->glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)viewer->context()->getProcAddress("glFramebufferTexture2DEXT");
|
||||
viewer->glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_RECTANGLE_ARB, mNormalTextureID, 0);
|
||||
mRenderBuffer->release();
|
||||
|
||||
}
|
||||
|
||||
if (mFlags&OUTPUT_DEPTH_BIT)
|
||||
{
|
||||
// to output the depth values to the final depth buffer we need to
|
||||
// attach a depth buffer as a texture
|
||||
if (mDepthTextureID==0)
|
||||
viewer->glGenTextures(1,&mDepthTextureID);
|
||||
//glBindTexture(GL_TEXTURE_RECTANGLE_ARB, mDepthTextureID);
|
||||
viewer->glBindTexture(GL_TEXTURE_RECTANGLE, mDepthTextureID);
|
||||
//glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_DEPTH_COMPONENT24_ARB, mCachedVP[2], mCachedVP[3], 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
|
||||
viewer->glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_DEPTH_COMPONENT24, mCachedVP[2], mCachedVP[3], 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
|
||||
//glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
viewer->glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
//glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
viewer->glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
mRenderBuffer->bind();
|
||||
viewer->glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_RECTANGLE_ARB, mDepthTextureID, 0);
|
||||
mRenderBuffer->release();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool SplatRenderer::beginVisibilityPass()
|
||||
{
|
||||
if (!mIsInitialized)
|
||||
{
|
||||
init();
|
||||
}
|
||||
if (!isSupported())
|
||||
{
|
||||
std::cerr << "SplatRenderer error: not supported hardware\n";
|
||||
return false;
|
||||
}
|
||||
if (mCurrentPass!=2)
|
||||
{
|
||||
std::cerr << "SplatRenderer error: programming error when calling beginVisibilityPass\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
viewer->glPushAttrib(GL_ALL_ATTRIB_BITS);
|
||||
|
||||
mCurrentPass = 0;
|
||||
|
||||
// grab projection info
|
||||
viewer->glGetIntegerv(GL_VIEWPORT, mCachedVP);
|
||||
viewer->glGetFloatv(GL_MODELVIEW_MATRIX, mCachedMV);
|
||||
viewer->glGetFloatv(GL_PROJECTION_MATRIX, mCachedProj);
|
||||
|
||||
updateRenderBuffer();
|
||||
if (mCachedFlags != mFlags)
|
||||
configureShaders();
|
||||
|
||||
// configureShaders may detect that shaders are actually not supported.
|
||||
if (!isSupported())
|
||||
{
|
||||
std::cerr << "SplatRenderer error: not supported hardware\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
mCachedFlags = mFlags;
|
||||
|
||||
mParams.update(mCachedMV, mCachedProj, mCachedVP);
|
||||
mParams.loadTo(mShaders[mCurrentPass]);
|
||||
|
||||
mRenderBuffer->bind();
|
||||
if (mFlags & DEFERRED_SHADING_BIT)
|
||||
{
|
||||
//GLenum buf[2] = {GL_COLOR_ATTACHMENT0_EXT,GL_COLOR_ATTACHMENT1_EXT};
|
||||
GLenum buf[2] = {GL_COLOR_ATTACHMENT0,GL_COLOR_ATTACHMENT1};
|
||||
//glDrawBuffersARB(2, buf);
|
||||
viewer->glDrawBuffers(2, buf);
|
||||
}
|
||||
viewer->glViewport(mCachedVP[0],mCachedVP[1],mCachedVP[2],mCachedVP[3]);
|
||||
viewer->glClearColor(0,0,0,0);
|
||||
viewer->glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
|
||||
enablePass(mCurrentPass);
|
||||
;
|
||||
return true;
|
||||
}
|
||||
bool SplatRenderer::beginAttributePass()
|
||||
{
|
||||
if (!isSupported())
|
||||
{
|
||||
std::cerr << "SplatRenderer error: not supported hardware\n";
|
||||
return false;
|
||||
}
|
||||
if (mCurrentPass!=0)
|
||||
{
|
||||
std::cerr << "SplatRenderer error: programming error when calling beginAttributePass (must be called after the visiblity pass)\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
mCurrentPass = 1;
|
||||
mParams.loadTo(mShaders[mCurrentPass]);
|
||||
enablePass(mCurrentPass);
|
||||
;
|
||||
return true;
|
||||
}
|
||||
bool SplatRenderer::finalize()
|
||||
{
|
||||
if (!isSupported())
|
||||
{
|
||||
std::cerr << "SplatRenderer error: not supported hardware\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
// this is the last pass: normalization by the sum of weights + deferred shading
|
||||
mShaders[mCurrentPass].release();
|
||||
mRenderBuffer->release();
|
||||
|
||||
if ( (mCurrentPass!=0) && (mCurrentPass!=1))
|
||||
{
|
||||
std::cerr << "SplatRenderer error: programming error when calling finalize (must be called after the visiblity or attribute pass)\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
mCurrentPass = 2;
|
||||
|
||||
if (mFlags&DEFERRED_SHADING_BIT)
|
||||
viewer->glDrawBuffer(GL_BACK);
|
||||
|
||||
enablePass(mCurrentPass);
|
||||
|
||||
// switch to normalized 2D rendering mode
|
||||
viewer->glMatrixMode(GL_PROJECTION);
|
||||
viewer->glPushMatrix();
|
||||
viewer->glLoadIdentity();
|
||||
viewer->glMatrixMode(GL_MODELVIEW);
|
||||
viewer->glPushMatrix();
|
||||
viewer->glLoadIdentity();
|
||||
|
||||
|
||||
mShaders[2].setUniform("viewport",float(mCachedVP[0]),float(mCachedVP[1]),float(mCachedVP[2]),float(mCachedVP[3]));
|
||||
mShaders[2].setUniform("ColorWeight",0); // this is a texture unit
|
||||
viewer->glActiveTexture(GL_TEXTURE0);
|
||||
//glBindTexture(GL_TEXTURE_RECTANGLE_ARB,mRenderBuffer->texture());
|
||||
viewer->glBindTexture(GL_TEXTURE_RECTANGLE,mRenderBuffer->texture());
|
||||
|
||||
if (mFlags&DEFERRED_SHADING_BIT)
|
||||
{
|
||||
mShaders[2].setUniform("unproj", mCachedProj[10], mCachedProj[14]);
|
||||
mShaders[2].setUniform("NormalWeight",1); // this is a texture unit
|
||||
viewer->glActiveTexture(GL_TEXTURE1);
|
||||
//glBindTexture(GL_TEXTURE_RECTANGLE_ARB,mNormalTextureID);
|
||||
viewer->glBindTexture(GL_TEXTURE_RECTANGLE,mNormalTextureID);
|
||||
|
||||
}
|
||||
|
||||
if (mFlags&OUTPUT_DEPTH_BIT)
|
||||
{
|
||||
mShaders[2].setUniform("Depth",2); // this is a texture unit
|
||||
viewer->glActiveTexture(GL_TEXTURE2);
|
||||
//glBindTexture(GL_TEXTURE_RECTANGLE_ARB,mDepthTextureID);
|
||||
viewer->glBindTexture(GL_TEXTURE_RECTANGLE,mDepthTextureID);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
viewer->glDisable(GL_DEPTH_TEST);
|
||||
viewer->glDepthMask(GL_FALSE);
|
||||
}
|
||||
|
||||
// draw a quad covering the whole screen
|
||||
float viewVec[] = {1.f/mCachedProj[0], 1.f/mCachedProj[5], -1};
|
||||
|
||||
viewer->glBegin(GL_QUADS);
|
||||
viewer->glColor3f(1, 0, 0);
|
||||
viewer->glTexCoord3f(viewVec[0],viewVec[1],viewVec[2]);
|
||||
viewer->glMultiTexCoord2f(GL_TEXTURE1,1.,1.);
|
||||
viewer->glVertex3f(1,1,0);
|
||||
|
||||
viewer->glColor3f(1, 1, 0);
|
||||
viewer->glTexCoord3f(-viewVec[0],viewVec[1],viewVec[2]);
|
||||
viewer->glMultiTexCoord2f(GL_TEXTURE1,0.,1.);
|
||||
viewer->glVertex3f(-1,1,0);
|
||||
|
||||
viewer->glColor3f(0, 1, 1);
|
||||
viewer->glTexCoord3f(-viewVec[0],-viewVec[1],viewVec[2]);
|
||||
viewer->glMultiTexCoord2f(GL_TEXTURE1,0.,0.);
|
||||
viewer->glVertex3f(-1,-1,0);
|
||||
|
||||
viewer->glColor3f(1, 0, 1);
|
||||
viewer->glTexCoord3f(viewVec[0],-viewVec[1],viewVec[2]);
|
||||
viewer->glMultiTexCoord2f(GL_TEXTURE1,1.,0.);
|
||||
viewer->glVertex3f(1,-1,0);
|
||||
viewer->glEnd();
|
||||
if (!(mFlags&OUTPUT_DEPTH_BIT))
|
||||
{
|
||||
viewer->glEnable(GL_DEPTH_TEST);
|
||||
viewer->glDepthMask(GL_TRUE);
|
||||
}
|
||||
|
||||
mShaders[mCurrentPass].release();
|
||||
|
||||
// restore matrices
|
||||
viewer->glMatrixMode(GL_PROJECTION);
|
||||
viewer->glPopMatrix();
|
||||
viewer->glMatrixMode(GL_MODELVIEW);
|
||||
viewer->glPopMatrix();
|
||||
|
||||
viewer->glPopAttrib();
|
||||
return true;
|
||||
}
|
||||
|
||||
void SplatRenderer::enablePass(int n)
|
||||
{
|
||||
if (!isSupported())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (mBindedPass!=n)
|
||||
{
|
||||
if (mBindedPass>=0)
|
||||
mShaders[mBindedPass].release();
|
||||
mShaders[n].activate();
|
||||
mBindedPass = n;
|
||||
|
||||
// set GL states
|
||||
if (n==0)
|
||||
{
|
||||
viewer->glDisable(GL_LIGHTING);
|
||||
// glDisable(GL_POINT_SMOOTH);
|
||||
viewer->glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
|
||||
|
||||
viewer->glAlphaFunc(GL_LESS,1);
|
||||
viewer->glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
|
||||
viewer->glDepthMask(GL_TRUE);
|
||||
viewer->glDisable(GL_BLEND);
|
||||
viewer->glEnable(GL_ALPHA_TEST);
|
||||
viewer->glEnable(GL_DEPTH_TEST);
|
||||
|
||||
// glActiveTexture(GL_TEXTURE0);
|
||||
// glTexEnvf(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
|
||||
// glEnable(GL_POINT_SPRITE_ARB);
|
||||
}
|
||||
if (n==1)
|
||||
{
|
||||
viewer->glDisable(GL_LIGHTING);
|
||||
viewer->glEnable(GL_POINT_SMOOTH);
|
||||
viewer->glActiveTexture(GL_TEXTURE0);
|
||||
viewer->glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
|
||||
|
||||
viewer->glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
|
||||
viewer->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_ONE,GL_ONE);
|
||||
// //glBlendFuncSeparate(GL_ONE, GL_ZERO, GL_ONE,GL_ZERO);
|
||||
// glBlendFunc(GL_ONE,GL_ZERO);
|
||||
viewer->glDepthMask(GL_FALSE);
|
||||
viewer->glEnable(GL_BLEND);
|
||||
viewer->glEnable(GL_DEPTH_TEST);
|
||||
viewer->glDisable(GL_ALPHA_TEST);
|
||||
|
||||
// glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
}
|
||||
if ( (n==0) || (n==1) )
|
||||
{
|
||||
// enable point sprite rendering mode
|
||||
viewer->glActiveTexture(GL_TEXTURE0);
|
||||
if (mWorkaroundATI)
|
||||
{
|
||||
viewer->glBindTexture(GL_TEXTURE_2D, mDummyTexId);
|
||||
viewer->glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 2, 2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0);
|
||||
viewer->glPointParameterf(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
|
||||
// hm... ^^^^
|
||||
}
|
||||
viewer->glTexEnvf(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
|
||||
viewer->glEnable(GL_POINT_SPRITE_ARB);
|
||||
}
|
||||
if (n==2)
|
||||
{
|
||||
viewer->glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
|
||||
viewer->glDepthMask(GL_TRUE);
|
||||
viewer->glDisable(GL_LIGHTING);
|
||||
viewer->glDisable(GL_BLEND);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SplatRenderer::UniformParameters::update(float* mv, float* proj, GLint* vp)
|
||||
{
|
||||
// extract the uniform scale
|
||||
float scale = sqrtf(mv[0]*mv[0]+mv[1]*mv[1]+mv[2]*mv[2]);
|
||||
|
||||
radiusScale = scale;
|
||||
preComputeRadius = - (std::max)(proj[0]*vp[2], proj[5]*vp[3]);
|
||||
depthOffset = 2.0;
|
||||
oneOverEwaRadius = 0.70710678118654f;
|
||||
halfVp[0] = 0.5*vp[2];
|
||||
halfVp[1] = 0.5*vp[3];
|
||||
rayCastParameter1[0] = 2./(proj[0]*vp[2]);
|
||||
rayCastParameter1[1] = 2./(proj[5]*vp[3]);
|
||||
rayCastParameter1[2] = 0.0;
|
||||
rayCastParameter2[0] = -1./proj[0];
|
||||
rayCastParameter2[1] = -1./proj[5];
|
||||
rayCastParameter2[2] = -1.0;
|
||||
depthParameterCast[0] = 0.5*proj[14];
|
||||
depthParameterCast[1] = 0.5-0.5*proj[10];
|
||||
}
|
||||
|
||||
void SplatRenderer::UniformParameters::loadTo(Shader& prg)
|
||||
{
|
||||
prg.activate();
|
||||
prg.setUniform("expeRadiusScale", radiusScale);
|
||||
prg.setUniform("expePreComputeRadius", preComputeRadius);
|
||||
prg.setUniform("expeDepthOffset", depthOffset);
|
||||
prg.setUniform("oneOverEwaRadius", oneOverEwaRadius);
|
||||
prg.setUniform2("halfVp", halfVp);
|
||||
prg.setUniform3("rayCastParameter1", rayCastParameter1);
|
||||
prg.setUniform3("rayCastParameter2", rayCastParameter2);
|
||||
prg.setUniform2("depthParameterCast", depthParameterCast);
|
||||
}
|
||||
|
||||
void SplatRenderer::setRadiusScale(float v)
|
||||
{
|
||||
mParams.radiusScale = v;
|
||||
}
|
||||
|
||||
void SplatRenderer::setViewer(Viewer_interface *v)
|
||||
{
|
||||
viewer = v;
|
||||
for(int i=0; i<3; i++)
|
||||
mShaders[i].setViewer(v);
|
||||
|
||||
viewer_is_set = true;
|
||||
}
|
||||
} // namepsace GlSplat
|
||||
|
||||
|
|
@ -0,0 +1,153 @@
|
|||
// This file is part of GlSplat, a simple splatting C++ library
|
||||
//
|
||||
// Copyright (C) 2008-2009 Gael Guennebaud <g.gael@free.fr>
|
||||
//
|
||||
// GlSplat is free software; 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 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// GlSplat is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with GlSplat. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef _GLSPLAT_SPLATRENDERER_H_
|
||||
#define _GLSPLAT_SPLATRENDERER_H_
|
||||
|
||||
#include "GlSplat_config.h"
|
||||
#include "Shader.h"
|
||||
#include <QObject>
|
||||
#include <QAction>
|
||||
#include <QString>
|
||||
#include <map>
|
||||
|
||||
class QGLFramebufferObject;
|
||||
class QGLWidget;
|
||||
|
||||
namespace GlSplat {
|
||||
|
||||
/** \class SplatRenderer
|
||||
* \brief Helper class to render a set of points using a splatting alogirthm
|
||||
*
|
||||
* This class aims to render a set of oriented point with radius (called splats) using an
|
||||
* OpenGL based splating algorithm. This class is only responsible for the managing of the
|
||||
* OpenGL stats and shaders related to the splatting. The drawing of the geometry, i.e.,
|
||||
* sending the point data to the GPU has to be done by the user.
|
||||
*
|
||||
* Here is an example:
|
||||
* \code
|
||||
* SplatRenderer renderer;
|
||||
* renderer.init();
|
||||
*
|
||||
* renderer.beginVisibilityPass();
|
||||
* drawpoints();
|
||||
* renderer.beginAttributePass();
|
||||
* drawpoints();
|
||||
* renderer.finalize();
|
||||
* \endcode
|
||||
*
|
||||
* Have a look at the demo to see a complete example based on QGLviewer.
|
||||
*/
|
||||
class GLSPLAT_EXPORT SplatRenderer
|
||||
{
|
||||
bool mIsSupported;
|
||||
enum {
|
||||
DEFERRED_SHADING_BIT = 0x000001,
|
||||
DEPTH_CORRECTION_BIT = 0x000002,
|
||||
OUTPUT_DEPTH_BIT = 0x000004,
|
||||
BACKFACE_SHADING_BIT = 0x000008,
|
||||
FLOAT_BUFFER_BIT = 0x000010
|
||||
};
|
||||
int mFlags;
|
||||
int mCachedFlags;
|
||||
int mRenderBufferMask;
|
||||
int mSupportedMask;
|
||||
|
||||
int mCurrentPass;
|
||||
int mBindedPass;
|
||||
GLuint mDummyTexId; // on ATI graphics card we need to bind a texture to get point sprite working !
|
||||
bool mWorkaroundATI;
|
||||
bool mBuggedAtiBlending;
|
||||
bool mIsInitialized;
|
||||
GLuint mNormalTextureID;
|
||||
GLuint mDepthTextureID;
|
||||
Shader mShaders[3];
|
||||
QString mShaderSrcs[6];
|
||||
QGLFramebufferObject* mRenderBuffer;
|
||||
float mCachedMV[16]; // modelview matrix
|
||||
float mCachedProj[16]; // projection matrix
|
||||
GLint mCachedVP[4]; // viewport
|
||||
|
||||
struct UniformParameters
|
||||
{
|
||||
float radiusScale;
|
||||
float preComputeRadius;
|
||||
float depthOffset;
|
||||
float oneOverEwaRadius;
|
||||
float halfVp[2];
|
||||
float rayCastParameter1[3];
|
||||
float rayCastParameter2[3];
|
||||
float depthParameterCast[2];
|
||||
|
||||
void loadTo(Shader& prg);
|
||||
void update(float* mv, float* proj, GLint* vp);
|
||||
};
|
||||
|
||||
UniformParameters mParams;
|
||||
|
||||
QString loadSource(const QString& func,const QString& file);
|
||||
void configureShaders();
|
||||
void updateRenderBuffer();
|
||||
void enablePass(int n);
|
||||
|
||||
public:
|
||||
bool viewer_is_set;
|
||||
|
||||
SplatRenderer();
|
||||
~SplatRenderer()
|
||||
{
|
||||
}
|
||||
|
||||
/** Must be called once an OpenGL context has been activated.
|
||||
* The main OpenGL context must be enabled, or, if you are using a QGLwiget,
|
||||
* you can pass it to this function without caring about the OpenGL context.
|
||||
*/
|
||||
void init(QGLWidget *qglw = 0);
|
||||
|
||||
/** \returns true is the hardware is supported
|
||||
* Must be called after init.
|
||||
*/
|
||||
bool isSupported() { return mIsSupported; }
|
||||
|
||||
/** Starts the first rendering pass
|
||||
* \returns false if an error occured
|
||||
*/
|
||||
bool beginVisibilityPass();
|
||||
/** Starts the (optional) second rendering pass
|
||||
* \returns false if an error occured
|
||||
*/
|
||||
bool beginAttributePass();
|
||||
/** Draw the rendered splats inside the main render target.
|
||||
* \returns false if an error occured
|
||||
*/
|
||||
bool finalize();
|
||||
|
||||
/** Sets a global scale factor for the splat radii
|
||||
* Default value is 1
|
||||
*/
|
||||
void setRadiusScale(float v);
|
||||
|
||||
void setViewer(Viewer_interface *v);
|
||||
|
||||
private :
|
||||
Viewer_interface *viewer;
|
||||
};
|
||||
|
||||
|
||||
} // namepsace GlSplat
|
||||
|
||||
#endif // _GLSPLAT_SPLATRENDERER_H_
|
||||
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
#ifndef GLSPLAT_CONFIG_H
|
||||
#define GLSPLAT_CONFIG_H
|
||||
|
||||
#include <CGAL/export/helpers.h>
|
||||
|
||||
#ifdef gl_splat_EXPORTS
|
||||
#define GLSPLAT_EXPORT CGAL_DLL_EXPORT
|
||||
#else
|
||||
#define GLSPLAT_EXPORT CGAL_DLL_IMPORT
|
||||
#endif
|
||||
|
||||
#endif // GLSPLAT_CONFIG_H
|
||||
|
|
@ -0,0 +1,140 @@
|
|||
// This file is part of GlSplat, a simple splatting C++ library
|
||||
//
|
||||
// Copyright (C) 2008-2009 Gael Guennebaud <g.gael@free.fr>
|
||||
//
|
||||
// GlSplat is free software; 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 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// GlSplat is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with GlSplat. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "Shader.h"
|
||||
#include <iostream>
|
||||
|
||||
#include <qfile.h>
|
||||
#include <qtextstream.h>
|
||||
#include <assert.h>
|
||||
#include <QDebug>
|
||||
|
||||
namespace GlSplat {
|
||||
|
||||
void Shader::define(const char* name, const char* value)
|
||||
{
|
||||
mDefines[std::string(name)] = value;
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
bool Shader::loadSources(const char* vsrc, const char* fsrc)
|
||||
{
|
||||
bool allIsOk = true;
|
||||
mProgramID = viewer->glCreateProgram();
|
||||
|
||||
std::string defineStr = "";
|
||||
for(DefineMap::iterator it = mDefines.begin() ; it!=mDefines.end() ; ++it)
|
||||
{
|
||||
defineStr += "#define " + it->first + " " + it->second + "\n";
|
||||
}
|
||||
|
||||
if(vsrc)
|
||||
{
|
||||
GLuint shaderID = viewer->glCreateShader(GL_VERTEX_SHADER);
|
||||
|
||||
std::string source = defineStr + std::string(vsrc);
|
||||
const GLchar * arbSource = source.c_str();
|
||||
|
||||
viewer->glShaderSource(shaderID, 1, (const GLchar **)&arbSource, 0);
|
||||
viewer->glCompileShader(shaderID);
|
||||
|
||||
int compiled;
|
||||
viewer->glGetShaderiv(shaderID,GL_COMPILE_STATUS,&compiled);
|
||||
allIsOk = allIsOk && compiled;
|
||||
//printInfoLog(shaderID);
|
||||
|
||||
viewer->glAttachShader(mProgramID, shaderID);
|
||||
}
|
||||
|
||||
if(fsrc)
|
||||
{
|
||||
GLuint shaderID = viewer->glCreateShader(GL_FRAGMENT_SHADER);
|
||||
|
||||
std::string source = defineStr + std::string(fsrc);
|
||||
const GLchar * arbSource = source.c_str();
|
||||
|
||||
viewer->glShaderSource(shaderID, 1, (const GLchar **)&arbSource, 0);
|
||||
viewer->glCompileShader(shaderID);
|
||||
|
||||
int compiled;
|
||||
viewer->glGetShaderiv(shaderID,GL_COMPILE_STATUS,&compiled);
|
||||
allIsOk = allIsOk && compiled;
|
||||
//printInfoLog(shaderID);
|
||||
|
||||
viewer->glAttachShader(mProgramID, shaderID);
|
||||
}
|
||||
|
||||
viewer->glLinkProgram(mProgramID);
|
||||
|
||||
int isLinked;
|
||||
viewer->glGetProgramiv(mProgramID, GL_LINK_STATUS, &isLinked);
|
||||
allIsOk = allIsOk && isLinked;
|
||||
mIsValid = isLinked == GL_TRUE;
|
||||
printInfoLog(mProgramID);
|
||||
|
||||
return allIsOk;
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
void Shader::activate()
|
||||
{
|
||||
assert(mIsValid);
|
||||
viewer->glUseProgram(mProgramID);
|
||||
}
|
||||
void Shader::release(void)
|
||||
{
|
||||
viewer->glUseProgram(0);
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
int Shader::getUniformLocation(const char* name)
|
||||
{
|
||||
assert(mIsValid);
|
||||
int loc = viewer->glGetUniformLocation(mProgramID, name);
|
||||
return loc;
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
void Shader::setSamplerUnit(const char* sampler, int unit)
|
||||
{
|
||||
activate();
|
||||
viewer->glUniform1i(getUniformLocation(sampler), unit);
|
||||
release();
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
int Shader::getAttribLocation(const char* name)
|
||||
{
|
||||
assert(mIsValid);
|
||||
int loc = viewer->glGetAttribLocation(mProgramID, name);
|
||||
return loc;
|
||||
}
|
||||
//--------------------------------------------------------------------------------
|
||||
void Shader::printInfoLog(GLuint objectID)
|
||||
{
|
||||
int infologLength, charsWritten;
|
||||
GLchar *infoLog;
|
||||
viewer->glGetProgramiv(objectID,GL_INFO_LOG_LENGTH, &infologLength);
|
||||
if(infologLength > 0)
|
||||
{
|
||||
infoLog = new GLchar[infologLength];
|
||||
viewer->glGetProgramInfoLog(objectID, infologLength, &charsWritten, infoLog);
|
||||
if (charsWritten>0)
|
||||
std::cerr << "Shader info : \n" << infoLog << std::endl;
|
||||
delete[] infoLog;
|
||||
}
|
||||
}
|
||||
|
||||
void Shader::setViewer(Viewer_interface *v)
|
||||
{
|
||||
viewer = v;
|
||||
}
|
||||
} // namepsace GlSplat
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
// This file is part of GlSplat, a simple splatting C++ library
|
||||
//
|
||||
// Copyright (C) 2008-2009 Gael Guennebaud <g.gael@free.fr>
|
||||
//
|
||||
// GlSplat is free software; 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 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// GlSplat is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with GlSplat. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef _GLSPLAT_Shader_h_
|
||||
#define _GLSPLAT_Shader_h_
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <QOpenGLFunctions_3_3_Core>
|
||||
#include "Viewer_interface.h"
|
||||
|
||||
namespace GlSplat {
|
||||
|
||||
/** Permet de manipuler des shaders en GLSL (OpenGL2.0)
|
||||
Exemple d'utilisation:
|
||||
\code
|
||||
// shader creation:
|
||||
Shader* myShader = new Shader();
|
||||
// loading from files (compilation + linking):
|
||||
myShader->loadFromFiles("myShaderFile.vtx", "myShaderFile.frg");
|
||||
|
||||
// ...
|
||||
|
||||
// at rending time:
|
||||
myShader->enable();
|
||||
// draw objects
|
||||
myShader->disable();
|
||||
\endcode
|
||||
*/
|
||||
|
||||
class Shader
|
||||
{
|
||||
public:
|
||||
Shader(void)
|
||||
: mIsValid(false)
|
||||
{ }
|
||||
~Shader()
|
||||
{
|
||||
}
|
||||
void setViewer(Viewer_interface *);
|
||||
/** add a \#define
|
||||
*/
|
||||
void define(const char* name, const char* value);
|
||||
|
||||
/** Compiles and links the shader from 2 source files
|
||||
\param fileV vertex shader ("" if no vertex shader)
|
||||
\param fileF fragment shader ("" if no fragment shader)
|
||||
\return true if no error occurs
|
||||
*/
|
||||
// bool loadFromFiles(const std::string& fileV, const std::string& fileF);
|
||||
|
||||
bool loadSources(const char* vsrc, const char* fsrc);
|
||||
|
||||
/** Enable the shader
|
||||
*/
|
||||
void activate();
|
||||
|
||||
/** Releases the shader
|
||||
*/
|
||||
void release() ;
|
||||
|
||||
/** \return the index of the uniform variable \a name
|
||||
*/
|
||||
int getUniformLocation(const char* name);
|
||||
|
||||
/** Forces a sampler to a given unit
|
||||
Example:
|
||||
\code
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
glBindTexture(GL_TEXTURE2D, myTextureID);
|
||||
myShader->setSamplerUnit("mySampler", 2);
|
||||
\endcode
|
||||
*/
|
||||
void setSamplerUnit(const char* samplerName, int textureUnit);
|
||||
|
||||
/** \returns the index of the generic attribute \a name
|
||||
Tp be used with glVertexAttrib*(...) ou glVertexAttribPointer(...)
|
||||
Example:
|
||||
\code
|
||||
int tangentAttribID = myShader->getAttribLocation("tangent");
|
||||
Vector3 tangent(...);
|
||||
glVertexAttrib3fv(tangentAttribID, tangent);
|
||||
// ou
|
||||
Vector3* tangents = new Vector3[...];
|
||||
glVertexAttribPointer(tangentAttribID, 3, GL_FLOAT, GL_FALSE, 0, tangents);
|
||||
glEnableVertexAttribArray(tangentAttribID);
|
||||
\endcode
|
||||
*/
|
||||
int getAttribLocation(const char* name);
|
||||
|
||||
inline void setUniform(const char* name, float a)
|
||||
{ viewer->glUniform1f(viewer->glGetUniformLocation(mProgramID, name), a); }
|
||||
|
||||
inline void setUniform(const char* name, int a)
|
||||
{ viewer->glUniform1i(viewer->glGetUniformLocation(mProgramID, name), a); }
|
||||
|
||||
inline void setUniform2(const char* name, float* a)
|
||||
{ viewer->glUniform2fv(viewer->glGetUniformLocation(mProgramID, name), 1, a); }
|
||||
|
||||
inline void setUniform3(const char* name, float* a)
|
||||
{ viewer->glUniform3fv(viewer->glGetUniformLocation(mProgramID, name), 1, a); }
|
||||
|
||||
inline void setUniform4(const char* name, float* a)
|
||||
{ viewer->glUniform4fv(viewer->glGetUniformLocation(mProgramID, name), 1, a); }
|
||||
|
||||
inline void setUniform(const char* name, float a, float b)
|
||||
{ viewer->glUniform2f(viewer->glGetUniformLocation(mProgramID, name), a, b); }
|
||||
|
||||
inline void setUniform(const char* name, float a, float b, float c)
|
||||
{ viewer->glUniform3f(viewer->glGetUniformLocation(mProgramID, name), a, b, c); }
|
||||
|
||||
inline void setUniform(const char* name, float a, float b, float c, float d)
|
||||
{ viewer->glUniform4f(viewer->glGetUniformLocation(mProgramID, name), a, b, c, d); }
|
||||
|
||||
Viewer_interface *viewer;
|
||||
protected:
|
||||
|
||||
bool mIsValid;
|
||||
typedef std::map<std::string,std::string> DefineMap;
|
||||
DefineMap mDefines;
|
||||
void printInfoLog(GLuint objectID);
|
||||
GLuint mProgramID;
|
||||
};
|
||||
|
||||
} // namepsace GlSplat
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue