mirror of https://github.com/CGAL/cgal
Add an example for simplifying an OpenMesh
This commit is contained in:
parent
223b188f03
commit
b866447f54
|
|
@ -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 )
|
||||
|
|
@ -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 //
|
||||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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..." ) ;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()));
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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 ;
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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()));
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue