Add an example for simplifying an OpenMesh

This commit is contained in:
Andreas Fabri 2014-05-30 16:19:28 +02:00
parent 223b188f03
commit b866447f54
12 changed files with 375 additions and 101 deletions

View File

@ -0,0 +1,99 @@
# Created by the script cgal_create_cmake_script_with_options
# This is the CMake script for compiling a set of CGAL applications.
project( Surface_mesh_simplification )
cmake_minimum_required(VERSION 2.6.2)
if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" VERSION_GREATER 2.6)
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()
endif()
set( CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true )
if ( COMMAND cmake_policy )
cmake_policy( SET CMP0003 NEW )
endif()
# 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()
# Activate concurrency?
option(ACTIVATE_CONCURRENCY
"Enable concurrency"
ON)
if( ACTIVATE_CONCURRENCY )
find_package( TBB REQUIRED )
if( TBB_FOUND )
include(${TBB_USE_FILE})
list(APPEND CGAL_3RD_PARTY_LIBRARIES ${TBB_LIBRARIES})
endif()
endif()
# include for local directory
# include for local package
include_directories( BEFORE ../../include )
include_directories (BEFORE "c:/3rdPartyLibs/OpenMesh/src")
add_definitions(
-D_USE_MATH_DEFINES -DNOMINMAX
)
link_directories ( c:/3rdPartyLibs/OpenMesh/VC11/Build/lib )
# Creating entries for all .cpp/.C files with "main" routine
# ##########################################################
include( CGAL_CreateSingleSourceCGALProgram )
create_single_source_cgal_program( "tbb.cpp" )
create_single_source_cgal_program( "edge_collapse_constrain_sharp_edges.cpp" )
create_single_source_cgal_program( "edge_collapse_constrained_border_polyhedron.cpp" )
create_single_source_cgal_program( "edge_collapse_enriched_polyhedron.cpp" )
create_single_source_cgal_program( "edge_collapse_polyhedron.cpp" )
create_single_source_cgal_program( "edge_collapse_OpenMesh.cpp" )
target_link_libraries( edge_collapse_OpenMesh debug OpenMeshCored optimized OpenMeshCore )

View File

@ -0,0 +1,156 @@
#include <iostream>
#include <fstream>
#include <CGAL/Simple_cartesian.h>
#include <OpenMesh/Core/IO/MeshIO.hh>
#include <OpenMesh/Core/Mesh/PolyMesh_ArrayKernelT.hh>
#include <CGAL/boost/graph/graph_traits_PolyMesh_ArrayKernelT.h>
#include <CGAL/boost/graph/properties_PolyMesh_ArrayKernelT.h>
// Simplification function
#include <CGAL/Surface_mesh_simplification/edge_collapse.h>
#include <CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Count_stop_predicate.h>
#include <CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Edge_length_cost.h>
#include <CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Midpoint_placement.h>
typedef OpenMesh::PolyMesh_ArrayKernelT</* MyTraits*/> Surface_mesh;
typedef CGAL::Simple_cartesian<double> Kern;
typedef Kern::Point_3 Point_3;
typedef Kern::Vector_3 Vector_3;
struct OM_Squared_distance_3 {
double operator()(const Surface_mesh::Point& p, const Surface_mesh::Point& q) const
{
return CGAL::squared_distance(Point_3(p[0],p[1],p[2]),Point_3(q[0],q[1],q[2]));
}
};
struct OM_Midpoint_3 {
Surface_mesh::Point operator()(const Surface_mesh::Point& p, const Surface_mesh::Point& q) const
{
Point_3 m = CGAL::midpoint(Point_3(p[0],p[1],p[2]),Point_3(q[0],q[1],q[2]));
std::cerr << m << std::endl;
return Surface_mesh::Point(m.x(), m.y(), m.z());
}
};
struct OM_Construct_cross_product_vector_3 {
Surface_mesh::Point operator()(const Surface_mesh::Point& p, const Surface_mesh::Point& q) const
{
Vector_3 v = CGAL::cross_product(Point_3(p[0],p[1],p[2]) - CGAL::ORIGIN,Point_3(q[0],q[1],q[2])-CGAL::ORIGIN);
return Surface_mesh::Point(v.x(), v.y(), v.z());
}
};
struct OM_Compute_scalar_product_3 {
double operator()(const Surface_mesh::Point& p, const Surface_mesh::Point& q) const
{
return (Point_3(p[0],p[1],p[2]) - CGAL::ORIGIN) * (Point_3(q[0],q[1],q[2])-CGAL::ORIGIN);
}
};
struct OM_Construct_vector_3 {
Surface_mesh::Point operator()(const Surface_mesh::Point& p, const Surface_mesh::Point& q) const
{
return Surface_mesh::Point(p[0]-q[0],p[1]-q[1],p[2]-q[2]);
}
};
struct OM_Equal_3 {
bool operator()(const Surface_mesh::Point& p, const Surface_mesh::Point& q) const
{
return p[0]==q[0] && p[1]==q[1] && p[2]==q[2];
}
};
class OM_kernel {
public:
typedef Surface_mesh::Point Point_3;
typedef Surface_mesh::Point Vector_3;
typedef double FT;
typedef OM_Squared_distance_3 Squared_distance_3;
typedef OM_Midpoint_3 Midpoint_3;
typedef OM_Construct_vector_3 Construct_vector_3;
typedef OM_Construct_cross_product_vector_3 Construct_cross_product_vector_3;
typedef OM_Compute_scalar_product_3 Compute_scalar_product_3;
typedef OM_Equal_3 Equal_3;
Squared_distance_3
compute_squared_distance_3_object() const
{
return Squared_distance_3();
}
Midpoint_3
construct_midpoint_3_object() const
{
return Midpoint_3();
}
Construct_vector_3
construct_vector_3_object() const
{
return Construct_vector_3();
}
Construct_cross_product_vector_3
construct_cross_product_vector_3_object() const
{
return Construct_cross_product_vector_3();
}
Compute_scalar_product_3
compute_scalar_product_3_object() const
{
return Compute_scalar_product_3();
}
Equal_3
equal_3_object() const
{
return Equal_3();
}
};
namespace SMS = CGAL::Surface_mesh_simplification ;
int main( int argc, char** argv )
{
Surface_mesh surface_mesh;
OpenMesh::IO::read_mesh(surface_mesh, argv[1]);
// This is a stop predicate (defines when the algorithm terminates).
// In this example, the simplification stops when the number of undirected edges
// left in the surface mesh drops below the specified number (1000)
SMS::Count_stop_predicate<Surface_mesh> stop(100);
// This the actual call to the simplification algorithm.
// The surface mesh and stop conditions are mandatory arguments.
int r = SMS::edge_collapse
(surface_mesh
,stop
, OM_kernel()
, CGAL::get_cost (SMS::Edge_length_cost <Surface_mesh, OM_kernel>())
.get_placement(SMS::Midpoint_placement<Surface_mesh,OM_kernel>())
);
std::cout << "\nFinished...\n" << r << " edges removed.\n"
<< num_edges(surface_mesh) << " final edges.\n" ;
// std::ofstream os( argc > 2 ? argv[2] : "out.off" ) ; os << surface_mesh ;
return 0 ;
}
// EOF //

View File

@ -13,6 +13,9 @@
// Stop-condition policy
#include <CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Count_stop_predicate.h>
#include <CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Edge_length_cost.h>
#include <CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Midpoint_placement.h>
typedef CGAL::Simple_cartesian<double> Kernel;
typedef CGAL::Polyhedron_3<Kernel> Surface_mesh;
@ -28,7 +31,7 @@ int main( int argc, char** argv )
// This is a stop predicate (defines when the algorithm terminates).
// In this example, the simplification stops when the number of undirected edges
// left in the surface mesh drops below the specified number (1000)
SMS::Count_stop_predicate<Surface_mesh> stop(1000);
SMS::Count_stop_predicate<Surface_mesh> stop(100);
// This the actual call to the simplification algorithm.
// The surface mesh and stop conditions are mandatory arguments.
@ -39,6 +42,8 @@ int main( int argc, char** argv )
,stop
,CGAL::vertex_index_map(get(CGAL::vertex_external_index,surface_mesh))
.halfedge_index_map (get(CGAL::halfedge_external_index ,surface_mesh))
.get_cost (SMS::Edge_length_cost <Surface_mesh>())
.get_placement(SMS::Midpoint_placement<Surface_mesh>())
);
std::cout << "\nFinished...\n" << r << " edges removed.\n"

View File

@ -32,6 +32,7 @@ namespace Surface_mesh_simplification
// Implementation of the vertex-pair collapse triangulated surface mesh simplification algorithm
//
template<class ECM_
,class Traits_
,class ShouldStop_
,class VertexIndexMap_
,class EdgeIndexMap_
@ -46,6 +47,7 @@ class EdgeCollapse
public:
typedef ECM_ ECM ;
typedef Traits_ Traits;
typedef ShouldStop_ ShouldStop ;
typedef VertexIndexMap_ VertexIndexMap ;
typedef EdgeIndexMap_ EdgeIndexMap ;
@ -78,12 +80,10 @@ public:
typedef typename GetCost ::result_type Cost_type ;
typedef typename GetPlacement::result_type Placement_type ;
typedef typename Kernel_traits<Point>::Kernel Kernel ;
typedef typename Traits::Equal_3 Equal_3 ;
typedef typename Kernel::Equal_3 Equal_3 ;
typedef typename Kernel::Vector_3 Vector ;
typedef typename Kernel::FT FT ;
typedef typename Traits::Vector_3 Vector ;
typedef typename Traits::FT FT ;
struct Compare_id
{
@ -169,6 +169,7 @@ public:
EdgeCollapse( ECM& aSurface
, ShouldStop const& aShouldStop
, Traits const& aGeomTraits
, VertexIndexMap const& aVertex_index_map
, EdgeIndexMap const& aEdge_index_map
, EdgeIsBorderMap const& aEdge_is_border_map

View File

@ -24,9 +24,10 @@ namespace CGAL {
namespace Surface_mesh_simplification
{
template<class M,class SP, class VIM,class EIM,class EBM,class ECTM, class CF,class PF,class V>
EdgeCollapse<M,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::EdgeCollapse( ECM& aSurface
template<class M, class T, class SP, class VIM, class EIM, class EBM, class ECTM, class CF, class PF, class V>
EdgeCollapse<M,T,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::EdgeCollapse( ECM& aSurface
, ShouldStop const& aShould_stop
, T const& aGeomTraits
, VertexIndexMap const& aVertex_index_map
, EdgeIndexMap const& aEdge_index_map
, EdgeIsBorderMap const& aEdge_is_border_map
@ -75,8 +76,8 @@ EdgeCollapse<M,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::EdgeCollapse( ECM&
#endif
}
template<class M,class SP, class VIM,class EIM,class EBM,class ECTM, class CF,class PF,class V>
int EdgeCollapse<M,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::run()
template<class M,class T,class SP, class VIM,class EIM,class EBM,class ECTM, class CF,class PF,class V>
int EdgeCollapse<M,T,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::run()
{
CGAL_SURF_SIMPL_TEST_assertion( mSurface.is_valid() && mSurface.is_pure_triangle() ) ;
@ -97,8 +98,8 @@ int EdgeCollapse<M,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::run()
return r ;
}
template<class M,class SP, class VIM,class EIM,class EBM,class ECTM, class CF,class PF,class V>
void EdgeCollapse<M,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::Collect()
template<class M,class T,class SP, class VIM,class EIM,class EBM,class ECTM, class CF,class PF,class V>
void EdgeCollapse<M,T,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::Collect()
{
CGAL_ECMS_TRACE(0,"Collecting edges...");
@ -106,7 +107,7 @@ void EdgeCollapse<M,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::Collect()
// Loop over all the _undirected_ edges in the surface putting them in the PQ
//
Equal_3 equal_points = Kernel().equal_3_object();
Equal_3 equal_points = Traits().equal_3_object();
size_type lSize = num_edges(mSurface);
@ -206,8 +207,8 @@ void EdgeCollapse<M,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::Collect()
CGAL_ECMS_TRACE(0,"Initial edge count: " << mInitialEdgeCount ) ;
}
template<class M,class SP, class VIM,class EIM,class EBM,class ECTM, class CF,class PF,class V>
void EdgeCollapse<M,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::Loop()
template<class M,class T,class SP, class VIM,class EIM,class EBM,class ECTM, class CF,class PF,class V>
void EdgeCollapse<M,T,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::Loop()
{
CGAL_ECMS_TRACE(0,"Collapsing edges...") ;
@ -288,8 +289,8 @@ void EdgeCollapse<M,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::Loop()
}
}
template<class M,class SP, class VIM,class EIM,class EBM,class ECTM, class CF,class PF,class V>
bool EdgeCollapse<M,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::is_border( vertex_descriptor const& aV ) const
template<class M, class T,class SP, class VIM,class EIM,class EBM,class ECTM, class CF,class PF,class V>
bool EdgeCollapse<M,T,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::is_border( vertex_descriptor const& aV ) const
{
bool rR = false ;
@ -307,8 +308,8 @@ bool EdgeCollapse<M,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::is_border( vertex_descriptor c
return rR ;
}
template<class M,class SP, class VIM,class EIM,class EBM,class ECTM, class CF,class PF,class V>
bool EdgeCollapse<M,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::is_border_or_constrained( vertex_descriptor const& aV ) const
template<class M, class T,class SP, class VIM,class EIM,class EBM,class ECTM, class CF,class PF,class V>
bool EdgeCollapse<M,T,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::is_border_or_constrained( vertex_descriptor const& aV ) const
{
in_edge_iterator eb, ee ;
for ( boost::tie(eb,ee) = halfedges_around_target(aV,mSurface) ; eb != ee ; ++ eb )
@ -320,8 +321,8 @@ bool EdgeCollapse<M,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::is_border_or_constrained( vert
return false;
}
template<class M,class SP, class VIM,class EIM,class EBM,class ECTM, class CF,class PF,class V>
bool EdgeCollapse<M,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::is_constrained( vertex_descriptor const& aV ) const
template<class M, class T,class SP, class VIM,class EIM,class EBM,class ECTM, class CF,class PF,class V>
bool EdgeCollapse<M,T,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::is_constrained( vertex_descriptor const& aV ) const
{
in_edge_iterator eb, ee ;
for ( boost::tie(eb,ee) = halfedges_around_target(aV,mSurface) ; eb != ee ; ++ eb )
@ -338,8 +339,8 @@ bool EdgeCollapse<M,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::is_constrained( vertex_descrip
// The link condition is as follows: for every vertex 'k' adjacent to both 'p and 'q',
// "p,k,q" is a facet of the mesh.
//
template<class M,class SP, class VIM,class EIM,class EBM,class ECTM, class CF,class PF,class V>
bool EdgeCollapse<M,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::Is_collapse_topologically_valid( Profile const& aProfile )
template<class M, class T,class SP, class VIM,class EIM,class EBM,class ECTM, class CF,class PF,class V>
bool EdgeCollapse<M,T,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::Is_collapse_topologically_valid( Profile const& aProfile )
{
bool rR = true ;
@ -483,8 +484,8 @@ bool EdgeCollapse<M,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::Is_collapse_topologically_vali
return rR ;
}
template<class M,class SP, class VIM,class EIM,class EBM,class ECTM, class CF,class PF,class V>
bool EdgeCollapse<M,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::Is_tetrahedron( halfedge_descriptor const& h1 )
template<class M, class T,class SP, class VIM,class EIM,class EBM,class ECTM, class CF,class PF,class V>
bool EdgeCollapse<M,T,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::Is_tetrahedron( halfedge_descriptor const& h1 )
{
//
// Code copied from Polyhedron_3::is_tetrahedron()
@ -535,8 +536,8 @@ bool EdgeCollapse<M,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::Is_tetrahedron( halfedge_descr
return true;
}
template<class M,class SP, class VIM,class EIM,class EBM,class ECTM, class CF,class PF,class V>
bool EdgeCollapse<M,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::Is_open_triangle( halfedge_descriptor const& h1 )
template<class M, class T,class SP, class VIM,class EIM,class EBM,class ECTM, class CF,class PF,class V>
bool EdgeCollapse<M,T,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::Is_open_triangle( halfedge_descriptor const& h1 )
{
bool rR = false ;
@ -566,20 +567,20 @@ bool EdgeCollapse<M,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::Is_open_triangle( halfedge_des
// respective areas is no greater than a max value and the internal
// dihedral angle formed by their supporting planes is no greater than
// a given threshold
template<class M,class SP, class VIM,class EIM,class EBM,class ECTM, class CF,class PF,class V>
bool EdgeCollapse<M,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::are_shared_triangles_valid( Point const& p0, Point const& p1, Point const& p2, Point const& p3 ) const
template<class M, class T,class SP, class VIM,class EIM,class EBM,class ECTM, class CF,class PF,class V>
bool EdgeCollapse<M,T,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::are_shared_triangles_valid( Point const& p0, Point const& p1, Point const& p2, Point const& p3 ) const
{
bool rR = false ;
Vector e01 = p1 - p0 ;
Vector e02 = p2 - p0 ;
Vector e03 = p3 - p0 ;
Vector e01 = Traits().construct_vector_3_object()(p0,p1) ;
Vector e02 = Traits().construct_vector_3_object()(p0,p2) ;
Vector e03 = Traits().construct_vector_3_object()(p0,p3) ;
Vector n012 = cross_product(e01,e02);
Vector n023 = cross_product(e02,e03);
Vector n012 = Traits().construct_cross_product_vector_3_object()(e01,e02);
Vector n023 = Traits().construct_cross_product_vector_3_object()(e02,e03);
FT l012 = n012 * n012 ;
FT l023 = n023 * n023 ;
FT l012 = Traits().compute_scalar_product_3_object()(n012, n012) ;
FT l023 = Traits().compute_scalar_product_3_object()(n023, n023) ;
FT larger = (std::max)(l012,l023);
FT smaller = (std::min)(l012,l023);
@ -595,7 +596,7 @@ bool EdgeCollapse<M,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::are_shared_triangles_valid( Po
if ( larger < cMaxAreaRatio * smaller )
{
FT l0123 = n012 * n023 ;
FT l0123 = Traits().compute_scalar_product_3_object()(n012, n023) ;
CGAL_ECMS_TRACE(4,"\n l0123=" << n_to_string(l0123) );
if ( CGAL_NTS is_positive(l0123) )
@ -617,9 +618,9 @@ bool EdgeCollapse<M,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::are_shared_triangles_valid( Po
}
// Returns the directed halfedge connecting v0 to v1, if exists.
template<class M,class SP, class VIM,class EIM,class EBM,class ECTM, class CF,class PF,class V>
typename EdgeCollapse<M,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::halfedge_descriptor
EdgeCollapse<M,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::find_connection ( vertex_descriptor const& v0, vertex_descriptor const& v1 ) const
template<class M, class T,class SP, class VIM,class EIM,class EBM,class ECTM, class CF,class PF,class V>
typename EdgeCollapse<M,T,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::halfedge_descriptor
EdgeCollapse<M,T,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::find_connection ( vertex_descriptor const& v0, vertex_descriptor const& v1 ) const
{
out_edge_iterator eb, ee ;
for ( boost::tie(eb,ee) = halfedges_around_source(v0,mSurface) ; eb != ee ; ++ eb )
@ -634,9 +635,9 @@ EdgeCollapse<M,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::find_connection ( vertex_descriptor
// Given the edge 'e' around the link for the collapsinge edge "v0-v1", finds the vertex that makes a triangle adjacent to 'e' but exterior to the link (i.e not containing v0 nor v1)
// If 'e' is a null handle OR 'e' is a border edge, there is no such triangle and a null handle is returned.
template<class M,class SP, class VIM,class EIM,class EBM,class ECTM, class CF,class PF,class V>
typename EdgeCollapse<M,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::vertex_descriptor
EdgeCollapse<M,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::find_exterior_link_triangle_3rd_vertex ( halfedge_descriptor const& e, vertex_descriptor const& v0, vertex_descriptor const& v1 ) const
template<class M, class T,class SP, class VIM,class EIM,class EBM,class ECTM, class CF,class PF,class V>
typename EdgeCollapse<M,T,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::vertex_descriptor
EdgeCollapse<M,T,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::find_exterior_link_triangle_3rd_vertex ( halfedge_descriptor const& e, vertex_descriptor const& v0, vertex_descriptor const& v1 ) const
{
vertex_descriptor r ;
@ -668,8 +669,8 @@ EdgeCollapse<M,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::find_exterior_link_triangle_3rd_ver
// A collapse is geometrically valid if, in the resulting local mesh no two adjacent triangles form an internal dihedral angle
// greater than a fixed threshold (i.e. triangles do not "fold" into each other)
//
template<class M,class SP, class VIM,class EIM,class EBM,class ECTM, class CF,class PF,class V>
bool EdgeCollapse<M,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::Is_collapse_geometrically_valid( Profile const& aProfile, Placement_type k0)
template<class M, class T,class SP, class VIM,class EIM,class EBM,class ECTM, class CF,class PF,class V>
bool EdgeCollapse<M,T,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::Is_collapse_geometrically_valid( Profile const& aProfile, Placement_type k0)
{
bool rR = true ;
@ -753,8 +754,8 @@ bool EdgeCollapse<M,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::Is_collapse_geometrically_vali
return rR ;
}
template<class M,class SP, class VIM,class EIM,class EBM,class ECTM, class CF,class PF,class V>
void EdgeCollapse<M,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::Collapse( Profile const& aProfile, Placement_type aPlacement )
template<class M, class T,class SP, class VIM,class EIM,class EBM,class ECTM, class CF,class PF,class V>
void EdgeCollapse<M,T,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::Collapse( Profile const& aProfile, Placement_type aPlacement )
{
CGAL_ECMS_TRACE(1,"S" << mStep << ". Collapsing " << edge_to_string(aProfile.v0_v1()) ) ;
@ -855,8 +856,8 @@ void EdgeCollapse<M,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::Collapse( Profile const& aProf
CGAL_ECMS_DEBUG_CODE ( ++mStep ; )
}
template<class M,class SP, class VIM,class EIM,class EBM,class ECTM, class CF,class PF,class V>
void EdgeCollapse<M,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::Update_neighbors( vertex_descriptor const& aKeptV )
template<class M, class T, class SP, class VIM,class EIM,class EBM,class ECTM, class CF,class PF,class V>
void EdgeCollapse<M,T,SP,VIM,EIM,EBM,ECTM,CF,PF,V>::Update_neighbors( vertex_descriptor const& aKeptV )
{
CGAL_ECMS_TRACE(3,"Updating cost of neighboring edges..." ) ;

View File

@ -49,17 +49,11 @@ public:
typedef typename boost::graph_traits<ECM>::edge_descriptor edge_descriptor ;
typedef typename boost::graph_traits<ECM>::edges_size_type size_type ;
typedef typename boost::property_map<ECM, CGAL::vertex_point_t>::type Vertex_point_pmap;
typedef typename boost::property_traits<Vertex_point_pmap>::value_type Point;
typedef typename Kernel_traits<Point>::Kernel Kernel ;
typedef typename Kernel::FT FT ;
public :
Count_ratio_stop_predicate( double aRatio ) : mRatio(aRatio) {}
bool operator()( FT const& // aCurrentCost
template <typename F>
bool operator()( F const& // aCurrentCost
, Profile const& //aEdgeProfile
, size_type aInitialCount
, size_type aCurrentCount

View File

@ -47,24 +47,16 @@ public:
typedef Edge_profile<ECM> Profile ;
private :
typedef typename boost::property_map<ECM, CGAL::vertex_point_t>::type Vertex_point_pmap;
typedef typename boost::property_traits<Vertex_point_pmap>::value_type Point;
typedef typename Kernel_traits<Point>::Kernel Kernel ;
public :
typedef typename boost::graph_traits<ECM>::halfedge_descriptor halfedge_descriptor ;
typedef typename boost::graph_traits<ECM>::edges_size_type size_type ;
typedef typename Kernel::FT FT ;
// typedef typename Kernel::FT FT ;
public :
Count_stop_predicate( size_type aThres ) : mThres(aThres) {}
bool operator()( FT const& // aCurrentCost
template <typename F>
bool operator()( F const& // aCurrentCost
, Profile const& //aEdgeProfile
, size_type //aInitialCount
, size_type aCurrentCount

View File

@ -30,7 +30,7 @@ namespace Surface_mesh_simplification
//
// Edge-length cost: the squared length of the collapsing edge
//
template<class ECM_>
template<class ECM_, class Traits = typename ECM_::Traits>
class Edge_length_cost
{
@ -39,14 +39,8 @@ public:
typedef ECM_ ECM ;
typedef Edge_profile<ECM> Profile ;
typedef typename boost::property_map<ECM, CGAL::vertex_point_t>::type Vertex_point_pmap;
typedef typename boost::property_traits<Vertex_point_pmap>::value_type Point;
typedef typename Kernel_traits<Point>::Kernel Kernel ;
typedef typename Kernel::FT FT ;
typedef typename Traits::Point_3 Point;
typedef typename Traits::FT FT ;
typedef optional<FT> result_type ;
public:
@ -55,7 +49,7 @@ public:
result_type operator()( Profile const& aProfile, optional<Point> const& /*aPlacement*/ ) const
{
return result_type(squared_distance(aProfile.p0(),aProfile.p1()));
return result_type(Traits().compute_squared_distance_3_object()(aProfile.p0(),aProfile.p1()));
}
};

View File

@ -27,7 +27,7 @@ namespace CGAL {
namespace Surface_mesh_simplification
{
template<class ECM_>
template<class ECM_, class Traits>
class LindstromTurk_cost
{
public:
@ -35,12 +35,8 @@ public:
typedef ECM_ ECM ;
typedef Edge_profile<ECM> Profile ;
typedef typename boost::property_map<ECM, CGAL::vertex_point_t>::type Vertex_point_pmap;
typedef typename boost::property_traits<Vertex_point_pmap>::value_type Point;
typedef typename Kernel_traits<Point>::Kernel Kernel ;
typedef typename Kernel::FT FT ;
typedef typename Traits::Point_3 Point;
typedef typename Traits::FT FT ;
typedef optional<FT> result_type ;

View File

@ -27,7 +27,7 @@ namespace CGAL {
namespace Surface_mesh_simplification
{
template<class ECM_>
template<class ECM_, class Traits>
class LindstromTurk_placement
{
public:
@ -36,9 +36,8 @@ public:
typedef Edge_profile<ECM> Profile ;
typedef typename boost::property_map<ECM, CGAL::vertex_point_t>::type Vertex_point_pmap;
typedef typename boost::property_traits<Vertex_point_pmap>::value_type Point;
typedef typename Traits::Point_3 Point;
typedef typename Traits::FT FT ;
typedef optional<Point> result_type ;
public:

View File

@ -27,7 +27,7 @@ namespace CGAL {
namespace Surface_mesh_simplification
{
template<class ECM_>
template<class ECM_, class Traits = typename ECM_::Traits>
class Midpoint_placement
{
public:
@ -36,9 +36,7 @@ public:
typedef Edge_profile<ECM> Profile ;
typedef typename boost::property_map<ECM, CGAL::vertex_point_t>::type Vertex_point_pmap;
typedef typename boost::property_traits<Vertex_point_pmap>::value_type Point;
typedef typename Traits::Point_3 Point;
typedef optional<Point> result_type ;
public:
@ -47,7 +45,7 @@ public:
result_type operator()( Profile const& aProfile ) const
{
return result_type(midpoint(aProfile.p0(),aProfile.p1()));
return result_type(Traits().construct_midpoint_3_object()(aProfile.p0(),aProfile.p1()));
}
};

View File

@ -33,6 +33,7 @@ namespace Surface_mesh_simplification
template<class ECM
,class ShouldStop
,class Traits
,class VertexIndexMap
,class EdgeIndexMap
,class EdgeIsBorderMap
@ -42,8 +43,8 @@ template<class ECM
,class Visitor
>
int edge_collapse ( ECM& aSurface
, ShouldStop const& aShould_stop
, ShouldStop const& aShould_stop
,Traits const& aGeomTraits
// optional mesh information policies
, VertexIndexMap const& aVertex_index_map // defaults to get(vertex_index,aSurface)
, EdgeIndexMap const& aEdge_index_map // defaults to get(edge_index,aSurface)
@ -58,6 +59,7 @@ int edge_collapse ( ECM& aSurface
)
{
typedef EdgeCollapse< ECM
, Traits
, ShouldStop
, VertexIndexMap
, EdgeIndexMap
@ -71,6 +73,7 @@ int edge_collapse ( ECM& aSurface
Algorithm algorithm( aSurface
, aShould_stop
, aGeomTraits
, aVertex_index_map
, aEdge_index_map
, aEdge_is_border_map
@ -109,15 +112,45 @@ int edge_collapse ( ECM& aSurface
LindstromTurk_params lPolicyParams ;
boost::graph_visitor_t vis = boost::graph_visitor_t() ;
typedef typename ECM::Traits Traits;
return edge_collapse(aSurface
,aShould_stop
,Traits()
,choose_const_pmap(get_param(aParams,boost::vertex_index),aSurface,boost::vertex_index)
,choose_const_pmap(get_param(aParams,boost::halfedge_index),aSurface,boost::halfedge_index)
,choose_const_pmap(get_param(aParams,halfedge_is_border),aSurface,halfedge_is_border)
,choose_param (get_param(aParams,edge_is_constrained),No_constrained_edge_map<ECM>())
,choose_param (get_param(aParams,get_cost_policy), LindstromTurk_cost<ECM>())
,choose_param (get_param(aParams,get_placement_policy), LindstromTurk_placement<ECM>())
,choose_param (get_param(aParams,get_cost_policy), LindstromTurk_cost<ECM,Traits>())
,choose_param (get_param(aParams,get_placement_policy), LindstromTurk_placement<ECM,Traits>())
,choose_param (get_param(aParams,vis), Dummy_visitor())
);
}
template<class ECM, class ShouldStop, class GT, class P, class T, class R>
int edge_collapse ( ECM& aSurface
, ShouldStop const& aShould_stop
, const GT& aGeomTraits
, cgal_bgl_named_params<P,T,R> const& aParams
)
{
using boost::choose_param ;
using boost::choose_const_pmap ;
using boost::get_param ;
LindstromTurk_params lPolicyParams ;
boost::graph_visitor_t vis = boost::graph_visitor_t() ;
return edge_collapse(aSurface
,aShould_stop
,aGeomTraits
,choose_const_pmap(get_param(aParams,boost::vertex_index),aSurface,boost::vertex_index)
,choose_const_pmap(get_param(aParams,boost::halfedge_index),aSurface,boost::halfedge_index)
,choose_const_pmap(get_param(aParams,halfedge_is_border),aSurface,halfedge_is_border)
,choose_param (get_param(aParams,edge_is_constrained),No_constrained_edge_map<ECM>())
,choose_param (get_param(aParams,get_cost_policy), LindstromTurk_cost<ECM,GT>())
,choose_param (get_param(aParams,get_placement_policy), LindstromTurk_placement<ECM,GT>())
,choose_param (get_param(aParams,vis), Dummy_visitor())
);
@ -126,7 +159,13 @@ int edge_collapse ( ECM& aSurface
template<class ECM, class ShouldStop>
int edge_collapse ( ECM& aSurface, ShouldStop const& aShould_stop )
{
return edge_collapse(aSurface,aShould_stop, halfedge_index_map(get(boost::halfedge_index,aSurface)));
return edge_collapse(aSurface,aShould_stop, halfedge_index_map(get(boost::halfedge_index,aSurface))); // AF why the halfedge_index_map?
}
template<class ECM, class ShouldStop, class GT>
int edge_collapse ( ECM& aSurface, ShouldStop const& aShould_stop, const GT& aGeomTraits )
{
return edge_collapse(aSurface,aShould_stop, aGeomTraits, CGAL::halfedge_index_map(get(boost::halfedge_index,aSurface)));
}
} // namespace Surface_mesh_simplification