This commit is contained in:
Fernando Cacciola 2006-05-29 14:32:27 +00:00
parent 6ef682ab12
commit cce86b3375
34 changed files with 3624 additions and 1273 deletions

25
.gitattributes vendored
View File

@ -1615,6 +1615,31 @@ Surface_mesh_parameterization/test/Surface_mesh_parameterization/data/cube.off -
Surface_mesh_parameterization/test/Surface_mesh_parameterization/data/high_genus.off -text Surface_mesh_parameterization/test/Surface_mesh_parameterization/data/high_genus.off -text
Surface_mesh_parameterization/test/Surface_mesh_parameterization/data/knot2.off -text Surface_mesh_parameterization/test/Surface_mesh_parameterization/data/knot2.off -text
Surface_mesh_parameterization/test/Surface_mesh_parameterization/data/oni.off -text Surface_mesh_parameterization/test/Surface_mesh_parameterization/data/oni.off -text
Surface_mesh_simplification/demo/Surface_mesh_simplification/simplification_demo.cpp -text
Surface_mesh_simplification/dont_submit -text
Surface_mesh_simplification/include/CGAL/Cartesian/MatrixC33.h -text
Surface_mesh_simplification/include/CGAL/Extended_BGL.h -text
Surface_mesh_simplification/include/CGAL/HalfedgeDS_BGL_aux.h -text
Surface_mesh_simplification/include/CGAL/Modifiable_priority_queue.h -text
Surface_mesh_simplification/include/CGAL/Null_matrix.h -text
Surface_mesh_simplification/include/CGAL/Polyhedron_BGL.h -text
Surface_mesh_simplification/include/CGAL/Polyhedron_BGL_properties.h -text
Surface_mesh_simplification/include/CGAL/Polyhedron_extended_BGL.h -text
Surface_mesh_simplification/include/CGAL/Surface_mesh_simplification/Policies/Construct_minimal_collapse_data.h -text
Surface_mesh_simplification/include/CGAL/Surface_mesh_simplification/Policies/Count_stop_pred.h -text
Surface_mesh_simplification/include/CGAL/Surface_mesh_simplification/Policies/Detail/Lindstrom_Turk.h -text
Surface_mesh_simplification/include/CGAL/Surface_mesh_simplification/Policies/Detail/Lindstrom_Turk_impl.h -text
Surface_mesh_simplification/include/CGAL/Surface_mesh_simplification/Policies/Edge_length_cost.h -text
Surface_mesh_simplification/include/CGAL/Surface_mesh_simplification/Policies/LindstromTurk.h -text
Surface_mesh_simplification/include/CGAL/Surface_mesh_simplification/Policies/LindstromTurk_collapse_data.h -text
Surface_mesh_simplification/include/CGAL/Surface_mesh_simplification/Policies/LindstromTurk_construct_collapse_data.h -text
Surface_mesh_simplification/include/CGAL/Surface_mesh_simplification/Policies/LindstromTurk_cost.h -text
Surface_mesh_simplification/include/CGAL/Surface_mesh_simplification/Policies/LindstromTurk_vertex_placement.h -text
Surface_mesh_simplification/include/CGAL/Surface_mesh_simplification/Policies/Minimal_collapse_data.h -text
Surface_mesh_simplification/include/CGAL/Surface_mesh_simplification/Vertex_pair_collapse_impl.h -text
Surface_mesh_simplification/test/Surface_mesh_simplification/LT_edge_collapse_test.cpp -text
Surface_mesh_simplification/test/Surface_mesh_simplification/LT_edge_collapse_test.kdevelop -text
Surface_mesh_simplification/test/Surface_mesh_simplification/makefile -text
Surface_mesher/demo/Surface_mesher/windows/Mesh.suo -text svneol=unset#unset Surface_mesher/demo/Surface_mesher/windows/Mesh.suo -text svneol=unset#unset
Surface_mesher/demo/Surface_mesher/windows/res/Mesh.ico -text svneol=unset#unset Surface_mesher/demo/Surface_mesher/windows/res/Mesh.ico -text svneol=unset#unset
Surface_mesher/demo/Surface_mesher/windows/res/MeshDoc.ico -text svneol=unset#unset Surface_mesher/demo/Surface_mesher/windows/res/MeshDoc.ico -text svneol=unset#unset

View File

@ -9,7 +9,7 @@
<ignoreparts/> <ignoreparts/>
<projectdirectory>.</projectdirectory> <projectdirectory>.</projectdirectory>
<absoluteprojectpath>false</absoluteprojectpath> <absoluteprojectpath>false</absoluteprojectpath>
<description></description> <description/>
</general> </general>
<kdevcustomproject> <kdevcustomproject>
<run> <run>
@ -23,15 +23,15 @@
</run> </run>
<build> <build>
<buildtool>make</buildtool> <buildtool>make</buildtool>
<builddir></builddir> <builddir/>
</build> </build>
<make> <make>
<abortonerror>false</abortonerror> <abortonerror>false</abortonerror>
<numberofjobs>1</numberofjobs> <numberofjobs>1</numberofjobs>
<prio>0</prio> <prio>0</prio>
<dontact>false</dontact> <dontact>false</dontact>
<makebin></makebin> <makebin/>
<defaulttarget></defaulttarget> <defaulttarget/>
<makeoptions>CGAL_MAKEFILE=/home/fcacciola/Programming/CGAL/make/makefile_i686_Linux-2.6_g++-4.0.2 DEBUGGING=yes</makeoptions> <makeoptions>CGAL_MAKEFILE=/home/fcacciola/Programming/CGAL/make/makefile_i686_Linux-2.6_g++-4.0.2 DEBUGGING=yes</makeoptions>
<selectedenvironment>default</selectedenvironment> <selectedenvironment>default</selectedenvironment>
<environments> <environments>
@ -41,12 +41,12 @@
</kdevcustomproject> </kdevcustomproject>
<kdevdebugger> <kdevdebugger>
<general> <general>
<dbgshell></dbgshell> <dbgshell/>
<programargs></programargs> <programargs/>
<gdbpath></gdbpath> <gdbpath/>
<configGdbScript></configGdbScript> <configGdbScript/>
<runShellScript></runShellScript> <runShellScript/>
<runGdbScript></runGdbScript> <runGdbScript/>
<breakonloadinglibs>true</breakonloadinglibs> <breakonloadinglibs>true</breakonloadinglibs>
<separatetty>false</separatetty> <separatetty>false</separatetty>
<floatingtoolbar>false</floatingtoolbar> <floatingtoolbar>false</floatingtoolbar>
@ -126,7 +126,7 @@
<headerCompletionDelay>250</headerCompletionDelay> <headerCompletionDelay>250</headerCompletionDelay>
</codecompletion> </codecompletion>
<creategettersetter> <creategettersetter>
<prefixGet></prefixGet> <prefixGet/>
<prefixSet>set</prefixSet> <prefixSet>set</prefixSet>
<prefixVariable>m_,_</prefixVariable> <prefixVariable>m_,_</prefixVariable>
<parameterName>theValue</parameterName> <parameterName>theValue</parameterName>
@ -152,8 +152,8 @@
</cppsupportpart> </cppsupportpart>
<kdevvisualadvance> <kdevvisualadvance>
<emulator>VisualBoyAdvance</emulator> <emulator>VisualBoyAdvance</emulator>
<binary></binary> <binary/>
<addOptions></addOptions> <addOptions/>
<terminal>false</terminal> <terminal>false</terminal>
<fullscreen>false</fullscreen> <fullscreen>false</fullscreen>
<graphicFilter>-f0</graphicFilter> <graphicFilter>-f0</graphicFilter>

View File

@ -11,8 +11,8 @@
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
// //
// $URL$ // $URL: svn+ssh://fcacciola@scm.gforge.inria.fr/svn/cgal/trunk/Polyhedron_IO/demo/Polyhedron_IO/geomview_demo.C $
// $Id$ // $Id: geomview_demo.C 28567 2006-02-16 14:30:13Z lsaboret $
// //
// //
// Author(s) : Fernando Cacciola // Author(s) : Fernando Cacciola
@ -36,11 +36,13 @@ int main() {
#include <CGAL/Cartesian.h> #include <CGAL/Cartesian.h>
#include <CGAL/Polyhedron_3.h> #include <CGAL/Polyhedron_3.h>
#include <CGAL/Polyhedron_graph_traits_3.h> #include <CGAL/Polyhedron_BGL.h>
#include <CGAL/Polyhedron_extended_BGL.h>
#include <CGAL/Polyhedron_BGL_properties.h>
#include <CGAL/IO/Polyhedron_geomview_ostream.h> #include <CGAL/IO/Polyhedron_geomview_ostream.h>
#include <CGAL/IO/Polyhedron_iostream.h> #include <CGAL/IO/Polyhedron_iostream.h>
//#define CGAL_SURFACE_SIMPLIFICATION_ENABLE_TRACE 2 //#define CGAL_SURFACE_SIMPLIFICATION_ENABLE_TRACE 4
void Surface_simplification_external_trace( std::string s ) void Surface_simplification_external_trace( std::string s )
{ {
@ -49,9 +51,10 @@ void Surface_simplification_external_trace( std::string s )
#include <CGAL/Surface_mesh_simplification_vertex_pair_collapse.h> #include <CGAL/Surface_mesh_simplification_vertex_pair_collapse.h>
#include <CGAL/Surface_mesh_simplification/Policies/LindstromTurk_selection_map.h> #include <CGAL/Surface_mesh_simplification/Policies/Construct_minimal_collapse_data.h>
#include <CGAL/Surface_mesh_simplification/Policies/Edge_length_cost_map.h> #include <CGAL/Surface_mesh_simplification/Policies/Edge_length_cost.h>
#include <CGAL/Surface_mesh_simplification/Policies/Midpoint_vertex_placement.h> #include <CGAL/Surface_mesh_simplification/Policies/Midpoint_vertex_placement.h>
#include <CGAL/Surface_mesh_simplification/Policies/LindstromTurk.h>
#include <CGAL/Surface_mesh_simplification/Policies/Count_stop_pred.h> #include <CGAL/Surface_mesh_simplification/Policies/Count_stop_pred.h>
#include <iostream> #include <iostream>
@ -199,55 +202,76 @@ void error_handler ( char const* what, char const* expr, char const* file, int l
std::cerr << "Explanation:" << msg << std::endl; std::cerr << "Explanation:" << msg << std::endl;
} }
using namespace CGAL::Triangulated_surface_mesh::Simplification ;
int Simplify_midpoint ( Polyhedron& aP, int aMax )
{
typedef Minimal_collapse_data<Polyhedron> CollapseData ;
Construct_minimal_collapse_data<Polyhedron> Construct_collapse_data ;
Edge_length_cost <CollapseData> Get_cost ;
Midpoint_vertex_placement<CollapseData> Get_vertex_point ;
Count_stop_condition <CollapseData> Should_stop(aMax);
return vertex_pair_collapse(aP,Construct_collapse_data,(void*)0,Get_cost,Get_vertex_point,Should_stop);
}
int Simplify_LT ( Polyhedron& aP, int aMax )
{
typedef LindstromTurk_collapse_data<Polyhedron> CollapseData ;
Construct_LindstromTurk_collapse_data<Polyhedron> Construct_collapse_data ;
LindstromTurk_cost <Polyhedron> Get_cost ;
LindstromTurk_vertex_placement <Polyhedron> Get_vertex_point ;
Count_stop_condition <CollapseData> Should_stop(aMax);
LindstromTurk_params lParams(1,1,1);
return vertex_pair_collapse(aP,Construct_collapse_data,&lParams,Get_cost,Get_vertex_point,Should_stop);
}
void Simplify ( Polyhedron& aP, int aMax ) void Simplify ( Polyhedron& aP, int aMax )
{ {
std::cout << "Simplifying surface with " << (aP.size_of_halfedges()/2) << " edges..." << std::endl ; std::cout << "Simplifying surface with " << (aP.size_of_halfedges()/2) << " edges..." << std::endl ;
#ifdef VISUALIZE #ifdef VISUALIZE
CGAL::Geomview_stream gv; CGAL::Geomview_stream gv;
gv.set_bg_color(CGAL::BLACK); gv.set_bg_color(CGAL::BLACK);
gv.set_face_color(CGAL::WHITE); gv.set_face_color(CGAL::WHITE);
gv.set_edge_color(CGAL::BLUE); gv.set_edge_color(CGAL::BLUE);
gv.set_vertex_color(CGAL::RED); gv.set_vertex_color(CGAL::RED);
#endif #endif
using namespace CGAL::Triangulated_surface_mesh::Simplification ; std::cout << std::setprecision(19) ;
Lindstrom_Turk_selection<Polyhedron> selection_map ; int lVertexID = 0 ;
Edge_length_cost_map<Polyhedron> cost_map ; for ( Polyhedron::Vertex_iterator vi = aP.vertices_begin(); vi != aP.vertices_end() ; ++ vi )
Midpoint_vertex_placement<Polyhedron> vertex_placement ; vi->ID = lVertexID ++ ;
Count_stop_condition<Polyhedron> stop_condition(aMax);
std::cout << std::setprecision(19) ; int lHalfedgeID = 0 ;
for ( Polyhedron::Halfedge_iterator hi = aP.halfedges_begin(); hi != aP.halfedges_end() ; ++ hi )
hi->ID = lHalfedgeID++ ;
int lVertexID = 0 ; int lFacetID = 0 ;
for ( Polyhedron::Vertex_iterator vi = aP.vertices_begin(); vi != aP.vertices_end() ; ++ vi ) for ( Polyhedron::Facet_iterator fi = aP.facets_begin(); fi != aP.facets_end() ; ++ fi )
vi->ID = lVertexID ++ ; fi->ID = lFacetID ++ ;
int lHalfedgeID = 0 ;
for ( Polyhedron::Halfedge_iterator hi = aP.halfedges_begin(); hi != aP.halfedges_end() ; ++ hi )
hi->ID = lHalfedgeID++ ;
int lFacetID = 0 ; int r = Simplify_LT(aP,aMax);
for ( Polyhedron::Facet_iterator fi = aP.facets_begin(); fi != aP.facets_end() ; ++ fi )
fi->ID = lFacetID ++ ;
int r = vertex_pair_collapse(aP,selection_map,cost_map,vertex_placement,stop_condition); std::cout << "Finished...\n"
std::cout << "Finished...\n" << r << " edges removed.\n"
<< r << " edges removed.\n" << aP.size_of_vertices() << " vertices.\n"
<< aP.size_of_vertices() << " vertices.\n" << (aP.size_of_halfedges()/2) << " edges.\n"
<< (aP.size_of_halfedges()/2) << " edges.\n" << aP.size_of_facets() << " triangles.\n"
<< aP.size_of_facets() << " triangles.\n" << ( aP.is_valid() ? " valid" : " INVALID!!" )
<< ( aP.is_valid() ? " valid" : " INVALID!!" ) << std::endl ;
<< std::endl ;
;
#ifdef VISUALIZE #ifdef VISUALIZE
gv << aP ; gv << aP ;
std::cout << "Press any key to finish..." << std::endl ; std::cout << "Press any key to finish..." << std::endl ;
char k ; char k ;
std::cin >> k ; std::cin >> k ;
#endif #endif
} }
@ -258,13 +282,13 @@ int main( int argc, char** argv )
Polyhedron lP; Polyhedron lP;
char const* infile = argc > 1 ? argv[1] : "./data/Sample0.off" ; char const* infile = argc > 1 ? argv[1] : "./data/tetra2.off" ; //"./data/Sample0.off" ;
std::ifstream in(infile); std::ifstream in(infile);
if ( in ) if ( in )
{ {
in >> lP ; in >> lP ;
int lMax = argc > 2 ? std::atoi(argv[2]) : 1000 ; //lP.size_of_halfedges() ; int lMax = argc > 2 ? std::atoi(argv[2]) : 1 ; // 1000
Simplify(lP,lMax); Simplify(lP,lMax);

View File

@ -0,0 +1,3 @@
Doxyfile
*kdevelop*
*kdevses*

View File

@ -0,0 +1,238 @@
// Copyright (c) 2005, 2006 Fernando Luis Cacciola Carballal. All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// 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) : Fernando Cacciola <fernando_cacciola@ciudad.com.ar>
//
#ifndef CGAL_CARTESIAN_MATRIXC33_H
#define CGAL_CARTESIAN_MATRIXC33_H
#include <CGAL/Vector_3.h>
#include <CGAL/determinant.h>
#include <CGAL/number_utils.h>
#include <CGAL/Null_matrix.h>
#include <boost/optional/optional.hpp>
CGAL_BEGIN_NAMESPACE
template <class R_>
class MatrixC33
{
public:
typedef R_ R ;
typedef typename R::RT RT ;
typedef typename R::Vector_3 Vector_3;
MatrixC33 ( Null_matrix )
:
mR0(NULL_VECTOR)
,mR1(NULL_VECTOR)
,mR2(NULL_VECTOR)
{}
MatrixC33 ( RT const& r0x, RT const& r0y, RT const& r0z
, RT const& r1x, RT const& r1y, RT const& r1z
, RT const& r2x, RT const& r2y, RT const& r2z
)
:
mR0(r0x,r0y,r0z)
,mR1(r1x,r1y,r1z)
,mR2(r2x,r2y,r2z)
{}
MatrixC33 ( Vector_3 const& r0, Vector_3 const& r1, Vector_3 const& r2 )
:
mR0(r0)
,mR1(r1)
,mR2(r2)
{}
Vector_3 const& r0() const { return mR0; }
Vector_3 const& r1() const { return mR1; }
Vector_3 const& r2() const { return mR2; }
Vector_3& r0() { return mR0; }
Vector_3& r1() { return mR1; }
Vector_3& r2() { return mR2; }
Vector_3 const& operator[] ( int row ) const { return row == 0 ? mR0 : ( row == 1 ? mR1 : mR2 ) ; }
Vector_3& operator[] ( int row ) { return row == 0 ? mR0 : ( row == 1 ? mR1 : mR2 ) ; }
MatrixC33& operator+= ( MatrixC33 const& m )
{
mR0 = mR0 + m.r0() ;
mR1 = mR1 + m.r1() ;
mR2 = mR2 + m.r2() ;
return *this ;
}
MatrixC33& operator-= ( MatrixC33 const& m )
{
mR0 = mR0 - m.r0() ;
mR1 = mR1 - m.r1() ;
mR2 = mR2 - m.r2() ;
return *this ;
}
MatrixC33& operator*= ( RT const& c )
{
mR0 = mR0 * c ;
mR1 = mR1 * c ;
mR2 = mR2 * c ;
return *this ;
}
MatrixC33& operator/= ( RT const& c )
{
mR0 = mR0 / c ;
mR1 = mR1 / c ;
mR2 = mR2 / c ;
return *this ;
}
friend MatrixC33 operator+ ( MatrixC33 const& a, MatrixC33 const& b )
{
return MatrixC33(a.r0()+b.r0()
,a.r1()+b.r1()
,a.r2()+b.r2()
);
}
friend MatrixC33 operator- ( MatrixC33 const& a, MatrixC33 const& b )
{
return MatrixC33(a.r0()-b.r0()
,a.r1()-b.r1()
,a.r2()-b.r2()
);
}
friend MatrixC33 operator* ( MatrixC33 const& m, RT const& c )
{
return MatrixC33(m.r0()*c,m.r1()*c,m.r2()*c);
}
friend MatrixC33 operator* ( RT const& c, MatrixC33 const& m )
{
return MatrixC33(m.r0()*c,m.r1()*c,m.r2()*c);
}
friend MatrixC33 operator/ ( MatrixC33 const& m, RT const& c )
{
return MatrixC33(m.r0()/c,m.r1()/c,m.r2()/c);
}
friend Vector_3 operator* ( MatrixC33 const& m, Vector_3 const& v )
{
return Vector_3(m.r0()*v,m.r1()*v,m.r2()*v);
}
friend Vector_3 operator* ( Vector_3 const& v, MatrixC33 const& m )
{
return Vector_3(v*m.r0(),v*m.r1(),v*m.r2());
}
RT determinant() const
{
return det3x3_by_formula(r0().x(),r0().y(),r0().z()
,r1().x(),r1().y(),r1().z()
,r2().x(),r2().y(),r2().z()
);
}
MatrixC33& transpose()
{
mR0 = Vector_3(r0().x(),r1().x(),r2().x());
mR1 = Vector_3(r0().y(),r1().y(),r2().y());
mR2 = Vector_3(r0().z(),r1().z(),r2().z());
return *this ;
}
private:
Vector_3 mR0 ;
Vector_3 mR1 ;
Vector_3 mR2 ;
} ;
template<class R>
inline
MatrixC33<R> direct_product ( Vector_3<R> const& u, Vector_3<R> const& v )
{
return MatrixC33<R>( v * u.x()
, v * u.y()
, v * u.z()
) ;
}
template<class R>
MatrixC33<R> transposed_matrix ( MatrixC33<R> const& m )
{
MatrixC33<R> copy = m ;
copy.Transpose();
return copy ;
}
template<class R>
MatrixC33<R> cofactors_matrix ( MatrixC33<R> const& m )
{
typedef typename R::RT RT ;
RT c00 = det2x2_by_formula(m.r1().y(),m.r1().z(),m.r2().y(),m.r2().z());
RT c01 = -det2x2_by_formula(m.r1().x(),m.r1().z(),m.r2().x(),m.r2().z());
RT c02 = det2x2_by_formula(m.r1().x(),m.r1().y(),m.r2().x(),m.r2().y());
RT c10 = -det2x2_by_formula(m.r0().y(),m.r0().z(),m.r2().y(),m.r2().z());
RT c11 = det2x2_by_formula(m.r0().x(),m.r0().z(),m.r2().x(),m.r2().z());
RT c12 = -det2x2_by_formula(m.r0().x(),m.r0().y(),m.r2().x(),m.r2().y());
RT c20 = det2x2_by_formula(m.r0().y(),m.r0().z(),m.r1().y(),m.r1().z());
RT c21 = -det2x2_by_formula(m.r0().x(),m.r0().z(),m.r1().x(),m.r1().z());
RT c22 = det2x2_by_formula(m.r0().x(),m.r0().y(),m.r1().x(),m.r1().y());
return MatrixC33<R>(c00,c01,c02
,c10,c11,c12
,c20,c21,c22
);
}
template<class R>
MatrixC33<R> adjoint_matrix ( MatrixC33<R> const& m )
{
return cofactors_matrix(m).transpose() ;
}
template<class R>
boost::optional< MatrixC33<R> > inverse_matrix ( MatrixC33<R> const& m )
{
typedef typename R::RT RT ;
typedef boost::optional< MatrixC33<R> > result_type ;
result_type rInverse ;
RT det = m.determinant();
if ( ! CGAL_NTS is_zero(det) )
rInverse = result_type( adjoint_matrix(m) / det ) ;
return rInverse ;
}
CGAL_END_NAMESPACE
#endif // CGAL_CARTESIAN_MATRIXC33_H //
// EOF //

View File

@ -0,0 +1,203 @@
// Copyright (c) 2006 Geometry Factory (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// 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) : Fernando Caccciola <fernando.cacciola@gmail.com>
#ifndef CGAL_EXTENDED_BGL_H
#define CGAL_EXTENDED_BGL_H
#include <CGAL/Polyhedron_BGL.h>
#ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
# define CGAL_HDS_PARAM_ template < class Traits, class Items, class Alloc> class HDS
#else
# define CGAL_HDS_PARAM_ class HDS
#endif
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
struct graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> > : HDS_graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> >
CGAL_BEGIN_NAMESPACE
template<class HDS>
typename boost::graph_traits<HDS>::edge_descriptor
next_edge( typename boost::graph_traits<HDS>::edge_descriptor outedge, HDS& hds)
{
return outedge->next();
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
template<class HDS>
typename boost::graph_traits<HDS>::edge_const_descriptor
next_edge( typename boost::graph_traits<HDS>::edge_const_descriptor outedge, HDS const& hds)
{
return outedge->next();
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
template<class HDS>
typename boost::graph_traits<HDS>::edge_descriptor
prev_edge( typename boost::graph_traits<HDS>::edge_descriptor outedge, HDS& hds)
{
CGAL::HalfedgeDS_items_decorator<HDS> D ;
return D.get_prev(outedge);
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
template<class HDS>
typename boost::graph_traits<HDS>::edge_const_descriptor
prev_edge( typename boost::graph_traits<HDS>::edge_const_descriptor outedge, HDS const& hds)
{
CGAL::HalfedgeDS_items_decorator<HDS> D ;
return D.get_prev(outedge);
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
template<class HDS>
typename boost::graph_traits<HDS>::edge_descriptor
opposite_edge( typename boost::graph_traits<HDS>::edge_descriptor e, HDS& hds)
{
return e->opposite();
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
template<class HDS>
typename boost::graph_traits<HDS>::edge_const_descriptor
opposite_edge( typename boost::graph_traits<HDS>::edge_const_descriptor e, HDS const& hds)
{
return e->opposite();
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
template<class HDS>
typename boost::graph_traits<HDS>::edge_descriptor
next_edge_ccw( typename boost::graph_traits<HDS>::edge_descriptor outedge, HDS& hds)
{
CGAL::HalfedgeDS_items_decorator<HDS> D ;
return D.get_prev(outedge)->opposite();
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
template<class HDS>
typename boost::graph_traits<HDS>::edge_const_descriptor
next_edge_ccw( typename boost::graph_traits<HDS>::edge_const_descriptor outedge, HDS const& hds)
{
CGAL::HalfedgeDS_items_decorator<HDS> D ;
return D.get_prev(outedge)->opposite();
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
template<class HDS>
typename boost::graph_traits<HDS>::edge_descriptor
next_edge_cw( typename boost::graph_traits<HDS>::edge_descriptor outedge, HDS& hds)
{
return outedge->opposite()->next();
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
template<class HDS>
typename boost::graph_traits<HDS>::edge_const_descriptor
next_edge_cw( typename boost::graph_traits<HDS>::edge_const_descriptor outedge, HDS const& hds)
{
return outedge->opposite()->next();
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
template<class HDS>
typename boost::graph_traits<HDS>::edge_descriptor
next_edge( typename boost::graph_traits<HDS>::edge_descriptor outedge, HDS& hds)
{
return outedge->next();
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
template<class HDS>
typename boost::graph_traits<HDS>::edge_descriptor
out_edge( typename boost::graph_traits<HDS>::vertex_descriptor u, HDS& hds)
{
HalfedgeDS_items_decorator<HDS> D ;
return D.get_vertex_edge(u)->opposite();
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
template<class HDS>
typename boost::graph_traits<HDS>::edge_const_descriptor
out_edge( typename boost::graph_traits<HDS>::vertex_const_descriptor u, HDS const& hds)
{
HalfedgeDS_items_decorator<HDS> D ;
return D.get_vertex_edge(u)->opposite();
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
template<class HDS>
typename boost::graph_traits<HDS>::edge_descriptor
in_edge( typename boost::graph_traits<HDS>::vertex_descriptor u, HDS& hds)
{
HalfedgeDS_items_decorator<HDS> D ;
return D.get_vertex_edge(u);
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
template<class HDS>
typename boost::graph_traits<HDS>::edge_const_descriptor
in_edge( typename boost::graph_traits<HDS>::vertex_const_descriptor u, HDS const& hds)
{
HalfedgeDS_items_decorator<HDS> D ;
return D.get_vertex_edge(u);
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
template<class HDS>
typename boost::graph_traits<HDS>::vertex_descriptor
next_vertex( typename boost::graph_traits<HDS>::vertex_descriptor v, HDS& hds)
{
return boost::target(out_edge(v,hds),hds);
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
template<class HDS>
typename boost::graph_traits<HDS>::vertex_const_descriptor
next_vertex( typename boost::graph_traits<HDS>::vertex_const_descriptor v, HDS const& hds)
{
return boost::target(out_edge(v,hds),hds);
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
template<class HDS>
typename boost::graph_traits<HDS>::vertex_descriptor
prev_vertex( typename boost::graph_traits<HDS>::vertex_descriptor v, HDS& hds)
{
return boost::source(prev_edge(out_edge(v,hds)),hds);
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
template<class HDS>
typename boost::graph_traits<HDS>::vertex_const_descriptor
prev_vertex( typename boost::graph_traits<HDS>::vertex_const_descriptor v, HDS const& hds)
{
return boost::source(prev_edge(out_edge(v,hds)),hds);
}
CGAL_END_NAMESPACE
#undef CGAL_HDS_
#endif // CGAL_POLYHEDRON_EXTENDED_TRAITS_H

View File

@ -0,0 +1,362 @@
// Copyright (c) 2006 Geometry Factory (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// 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): Fernando Cacciola <fernando.cacciola@gmail.com>, Andreas Fabri <andreas.fabri@geometryfactory.com>
#ifndef CGAL_HALFEDGEDS_BGL_AUX_H
#define CGAL_HALFEDGEDS_BGL_AUX_H
#include <boost/config.hpp>
#include <boost/iterator_adaptors.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/properties.hpp>
CGAL_BEGIN_NAMESPACE
template <class Circ, class E>
class HDS_in_halfedge_circulator : public Circ
{
private:
mutable E e;
public:
typedef E value_type;
typedef E* pointer;
typedef E& reference;
HDS_in_halfedge_circulator()
: Circ()
{}
HDS_in_halfedge_circulator(Circ c)
: Circ(c)
{}
const E& operator*() const
{
e = *this;
return e;
}
};
template <class Circ, class E>
class HDS_out_halfedge_circulator : public Circ
{
private:
mutable E e;
public:
typedef E value_type;
typedef E* pointer;
typedef E& reference;
HDS_out_halfedge_circulator()
: Circ()
{}
HDS_out_halfedge_circulator(Circ c)
: Circ(c)
{}
const E& operator*() const
{
e = *this;
e = e->opposite();
return e;
}
};
// The vertex iterator of the bgl must evaluate to a vertex handle, not to a vertex
template < class HDS, class Vertex_iterator, class Vertex_handle>
class HDS_all_vertices_iterator_base {
protected:
Vertex_iterator nt;
public:
typedef Vertex_iterator Iterator;
typedef HDS_all_vertices_iterator_base<HDS,Vertex_iterator,Vertex_handle> Self;
typedef typename std::iterator_traits<Iterator>::iterator_category iterator_category;
typedef typename std::iterator_traits<Iterator>::difference_type difference_type;
typedef Vertex_handle value_type;
typedef value_type reference;
typedef value_type pointer;
protected:
HDS_all_vertices_iterator_base() {}
HDS_all_vertices_iterator_base( Iterator j) : nt(j) {}
public:
// OPERATIONS Forward Category
// ---------------------------
bool operator==( const Self& i) const { return ( nt == i.nt); }
bool operator!=( const Self& i) const { return !(nt == i.nt ); }
value_type operator*() const { return nt; }
value_type operator->() { return nt; }
Self& operator++() {
++nt;
return *this;
}
Self operator++(int) {
Self tmp = *this;
++*this;
return tmp;
}
};
template < class HDS >
class HDS_all_vertices_const_iterator
: public HDS_all_vertices_iterator_base<HDS,typename HDS::Vertex_const_iterator,typename HDS::Vertex_const_handle>
{
typedef HDS_all_vertices_iterator_base<HDS,typename HDS::Vertex_const_iterator,typename HDS::Vertex_const_handle> Base ;
public:
typedef typename HDS::Vertex_const_iterator Iterator;
HDS_all_vertices_const_iterator() {}
HDS_all_vertices_const_iterator( Iterator j) : Base(j) {}
};
template < class HDS >
class HDS_all_vertices_iterator
: public HDS_all_vertices_iterator_base<HDS,typename HDS::Vertex_iterator,typename HDS::Vertex_handle>
{
typedef HDS_all_vertices_iterator_base<HDS,typename HDS::Vertex_iterator,typename HDS::Vertex_handle> Base ;
public:
typedef typename HDS::Vertex_iterator Iterator;
HDS_all_vertices_iterator() {}
HDS_all_vertices_iterator( Iterator j) : Base(j) {}
};
template < class HDS, class Iterator_, class Value_type>
class HDS_all_edges_iterator_base {
protected:
Iterator_ nt;
public:
typedef Iterator_ Iterator;
typedef HDS_all_edges_iterator_base<HDS,Iterator_,Value_type> Self;
typedef typename std::iterator_traits<Iterator>::iterator_category iterator_category;
typedef typename std::iterator_traits<Iterator>::difference_type difference_type;
typedef Value_type value_type;
typedef value_type reference;
typedef value_type pointer;
protected:
HDS_all_edges_iterator_base() {}
HDS_all_edges_iterator_base( Iterator j) : nt(j) {}
public:
// OPERATIONS Forward Category
// ---------------------------
bool operator==( const Self& i) const { return ( nt == i.nt); }
bool operator!=( const Self& i) const { return !(nt == i.nt ); }
value_type operator*() const { return nt; }
value_type operator->() { return nt; }
Self& operator++() {
++nt;
return *this;
}
Self operator++(int) {
Self tmp = *this;
++*this;
return tmp;
}
};
template < class HDS >
class HDS_all_halfedges_const_iterator
: public HDS_all_edges_iterator_base<HDS,typename HDS::Halfedge_const_iterator,typename HDS::Halfedge_const_handle>
{
typedef HDS_all_edges_iterator_base<HDS,typename HDS::Halfedge_const_iterator,typename HDS::Halfedge_const_handle> Base ;
public:
typedef typename HDS::Halfdge_const_iterator Iterator;
HDS_all_halfedges_const_iterator() {}
HDS_all_halfedges_const_iterator( Iterator j) : Base(j) {}
};
template < class HDS >
class HDS_all_halfedges_iterator
: public HDS_all_edges_iterator_base<HDS,typename HDS::Halfdge_iterator,typename HDS::Halfedge_handle>
{
typedef HDS_all_edges_iterator_base<HDS,typename HDS::Halfdge_iterator,typename HDS::Halfedge_handle> Base ;
public:
typedef typename HDS::Halfedge_iterator Iterator;
HDS_all_halfedges_iterator() {}
HDS_all_halfedges_iterator( Iterator j) : Base(j) {}
};
template < class HDS >
class HDS_all_undirected_edges_const_iterator
: public HDS_all_edges_iterator_base<HDS,typename HDS::Edge_const_iterator,typename HDS::Halfedge_const_handle>
{
typedef HDS_all_edges_iterator_base<HDS,typename HDS::Edge_const_iterator,typename HDS::Halfedge_const_handle> Base ;
public:
typedef typename HDS::Edge_const_iterator Iterator;
HDS_all_undirected_edges_const_iterator() {}
HDS_all_undirected_edges_const_iterator( Iterator j) : Base(j) {}
};
template < class HDS >
class HDS_all_undirected_edges_iterator
: public HDS_all_edges_iterator_base<HDS,typename HDS::Edge_iterator,typename HDS::Halfedge_handle>
{
typedef HDS_all_edges_iterator_base<HDS,typename HDS::Edge_iterator,typename HDS::Halfedge_handle> Base ;
public:
typedef typename HDS::Edge_iterator Iterator;
HDS_all_undirected_edges_iterator() {}
HDS_all_undirected_edges_iterator( Iterator j) : Base(j) {}
};
template <class HDS_>
struct HDS_graph_traits
{
public :
struct HDS_graph_traversal_category : public virtual boost::bidirectional_graph_tag,
public virtual boost::adjacency_graph_tag,
public virtual boost::vertex_list_graph_tag,
public virtual boost::edge_list_graph_tag
{};
typedef HDS_ HDS;
typedef typename HDS::Vertex_handle vertex_descriptor;
typedef typename HDS::Halfedge_handle edge_descriptor;
typedef HDS_all_vertices_iterator<HDS> vertex_iterator;
typedef HDS_all_halfedges_iterator<HDS> edge_iterator;
private:
typedef typename HDS::Halfedge_around_vertex_circulator Halfedge_around_vertex_circulator ;
typedef HDS_out_halfedge_circulator<Halfedge_around_vertex_circulator,edge_descriptor> out_edge_circulator ;
typedef HDS_in_halfedge_circulator <Halfedge_around_vertex_circulator,edge_descriptor> in_edge_circulator ;
public :
typedef Counting_iterator<out_edge_circulator, edge_descriptor> out_edge_iterator;
typedef Counting_iterator<in_edge_circulator , edge_descriptor> in_edge_iterator;
typedef boost::directed_tag directed_category;
typedef boost::disallow_parallel_edge_tag edge_parallel_category;
typedef HDS_graph_traversal_category traversal_category;
typedef typename HDS::size_type vertices_size_type;
typedef vertices_size_type edges_size_type;
typedef vertices_size_type degree_size_type;
};
template <class HDS_>
struct HDS_graph_traits<HDS_ const>
{
public :
struct HDS_graph_traversal_category : public virtual boost::bidirectional_graph_tag,
public virtual boost::adjacency_graph_tag,
public virtual boost::vertex_list_graph_tag,
public virtual boost::edge_list_graph_tag
{};
typedef HDS_ HDS;
typedef typename HDS::Vertex_const_handle vertex_descriptor;
typedef typename HDS::Halfedge_const_handle edge_descriptor;
typedef HDS_all_vertices_const_iterator<HDS> vertex_iterator;
typedef HDS_all_halfedges_const_iterator<HDS> edge_iterator;
private:
typedef typename HDS::Halfedge_around_vertex_const_circulator Halfedge_around_vertex_const_circulator ;
typedef HDS_out_halfedge_circulator<Halfedge_around_vertex_const_circulator,edge_descriptor> out_edge_const_circulator ;
typedef HDS_in_halfedge_circulator <Halfedge_around_vertex_const_circulator,edge_descriptor> in_edge_const_circulator ;
public :
typedef Counting_iterator<out_edge_const_circulator, edge_descriptor> out_edge_iterator;
typedef Counting_iterator<in_edge_const_circulator , edge_descriptor> in_edge_iterator;
typedef boost::directed_tag directed_category;
typedef boost::disallow_parallel_edge_tag edge_parallel_category;
typedef HDS_graph_traversal_category traversal_category;
typedef typename HDS::size_type vertices_size_type;
typedef vertices_size_type edges_size_type;
typedef vertices_size_type degree_size_type;
};
template <class HDS_>
struct HDS_undirected_graph_traits
{
public :
typedef HDS_ HDS;
typedef HDS_all_undirected_edges_iterator<HDS> edge_iterator;
};
template <class HDS_>
struct HDS_undirected_graph_traits<HDS_ const>
{
public :
typedef HDS_ HDS;
typedef HDS_all_undirected_edges_const_iterator<HDS> edge_iterator;
};
CGAL_END_NAMESPACE
#endif // CGAL_HALFEDGEDS_BGL_AUX_H

View File

@ -0,0 +1,91 @@
// Copyright (c) 2005, 2006 Fernando Luis Cacciola Carballal. All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// 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) : Fernando Cacciola <fernando_cacciola@ciudad.com.ar>
//
#ifndef CGAL_MODIFIABLE_PRIORITY_QUEUE_H
#define CGAL_MODIFIABLE_PRIORITY_QUEUE_H
#include<CGAL/Multiset.h>
CGAL_BEGIN_NAMESPACE
template <class Type_
,class Compare_ = CGAL::Compare<Type_>
,class Allocator_ = CGAL_ALLOCATOR(int)
>
class Modifiable_priority_queue
{
public:
typedef Multiset<Type_,Compare_,Allocator_> Heap ;
typedef Modifiable_priority_queue Self;
typedef Compare_ Compare;
typedef typename Heap::value_type value_type;
typedef typename Heap::reference reference;
typedef typename Heap::const_reference const_reference;
typedef typename Heap::size_type size_type;
typedef typename Heap::iterator iterator ;
public:
Modifiable_priority_queue() {}
Modifiable_priority_queue( Compare const& c ) : mHeap(c) {}
template<class InputIterator>
Modifiable_priority_queue( InputIterator first, InputIterator last, Compare const& c )
:
mHeap(first,last,c)
{}
iterator push ( value_type const& v ) { return mHeap.insert(v) ; }
iterator update ( iterator i ) { value_type v = *i; mHeap.erase(i); return mHeap.insert(v); }
void erase ( iterator i ) { mHeap.erase(i); }
bool contains ( value_type const& v ) { return mHeap.find(v) != mHeap.end() ; }
value_type top() const { return *mHeap.begin() ; }
void pop() { mHeap.erase(mHeap.begin()); }
bool empty() const { return mHeap.empty() ; }
size_type size() const { return mHeap.size() ; }
bool is_valid_iterator ( iterator j )
{
for( iterator it = mHeap.begin(); it != mHeap.end() ; ++ it )
if ( j == it )
return true ;
return false ;
}
private:
Heap mHeap ;
} ;
CGAL_END_NAMESPACE
#endif

View File

@ -0,0 +1,35 @@
// Copyright (c) 2005, 2006 Fernando Luis Cacciola Carballal. All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// 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) : Fernando Cacciola <fernando_cacciola@ciudad.com.ar>
//
#ifndef CGAL_NULL_MATRIX_H
#define CGAL_NULL_MATRIX_H
CGAL_BEGIN_NAMESPACE
class Null_matrix {};
extern const Null_matrix NULL_MATRIX;
CGAL_END_NAMESPACE
#endif // CGAL_NULL_MATRIX_H //
// EOF //

View File

@ -0,0 +1,219 @@
// Copyright (c) 2006 Geometry Factory (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// 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 <andreas.fabri@geometryfactory.com>, Fernando Cacciola <fernando.cacciola@gmail.com>
#ifndef CGAL_POLYHEDRON_BGL_H
#define CGAL_POLYHEDRON_BGL_H
#include <CGAL/HalfedgeDS_BGL_aux.h>
#ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
# define CGAL_HDS_PARAM_ template < class Traits, class Items, class Alloc> class HDS
#else
# define CGAL_HDS_PARAM_ class HDS
#endif
namespace boost
{
template<class T> struct undirected_graph_traits ;
//
// Const versions
//
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
struct graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> const >
: CGAL::HDS_graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> const>
{};
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
struct undirected_graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> const >
: CGAL::HDS_undirected_graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> const>
{};
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
typename graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> >::vertices_size_type
num_vertices(const CGAL::Polyhedron_3<Gt,I,HDS,A>& p)
{
return p.size_of_vertices();
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
typename graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> const>::edges_size_type
num_edges(const CGAL::Polyhedron_3<Gt,I,HDS,A>& p)
{
return p.size_of_halfedges() ;
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
typename graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> const>::degree_size_type
degree(typename graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> const >::vertex_descriptor v, const CGAL::Polyhedron_3<Gt,I,HDS,A>&)
{
return v->vertex_degree();
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
typename graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> const>::degree_size_type
out_degree(typename graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> const>::vertex_descriptor v, const CGAL::Polyhedron_3<Gt,I,HDS,A>&)
{
return v->vertex_degree();
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
typename graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> const>::degree_size_type
in_degree(typename graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> const>::vertex_descriptor v, const CGAL::Polyhedron_3<Gt,I,HDS,A>&)
{
return v->vertex_degree();
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
typename graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> const>::vertex_descriptor
source(typename graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> const>::edge_descriptor e, CGAL::Polyhedron_3<Gt,I,HDS,A> const& p)
{
return e->opposite()->vertex();
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
typename graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> const>::vertex_descriptor
target(typename graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> const>::edge_descriptor e, CGAL::Polyhedron_3<Gt,I,HDS,A> const& p)
{
return e->vertex();
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
inline std::pair<typename graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> const>::vertex_iterator
,typename graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> const>::vertex_iterator
>
vertices( CGAL::Polyhedron_3<Gt,I,HDS,A> const& p)
{
typedef typename graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> const>::vertex_iterator Iter;
return std::make_pair( Iter(p.vertices_begin()), Iter(p.vertices_end()) );
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
inline std::pair<typename graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> const>::edge_iterator
,typename graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> const>::edge_iterator
>
edges( CGAL::Polyhedron_3<Gt,I,HDS,A> const& p)
{
typedef typename graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> const>::edge_iterator Iter;
return std::make_pair( Iter(p.halfedges_begin()), Iter(p.halfedges_end()) );
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
inline std::pair<typename graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> const>::in_edge_iterator
,typename graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> const>::in_edge_iterator
>
in_edges( typename graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> const>::vertex_descriptor u, CGAL::Polyhedron_3<Gt,I,HDS,A> const& g)
{
typename CGAL::Polyhedron_3<Gt,I,HDS,A>::Halfedge_around_vertex_const_circulator ec = u->vertex_begin();
int in_deg = in_degree(u,g);
typedef typename graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> const>::in_edge_iterator Iter;
return std::make_pair( Iter(ec), Iter(ec,in_deg) );
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
inline std::pair<typename graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> const>::out_edge_iterator,
typename graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> const>::out_edge_iterator
>
out_edges( typename graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> const>::vertex_descriptor u, CGAL::Polyhedron_3<Gt,I,HDS,A> const& g)
{
typename CGAL::Polyhedron_3<Gt,I,HDS,A>::Halfedge_around_vertex_const_circulator ec = u->vertex_begin();
int out_deg = out_degree(u,g);
typedef typename graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> const>::out_edge_iterator Iter;
return std::make_pair( Iter(ec), Iter(ec,out_deg) );
}
//
// Non-Const versions
//
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
struct graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> >
: CGAL::HDS_graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> >
{};
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
struct undirected_graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> >
: CGAL::HDS_undirected_graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> >
{};
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
typename graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> >::vertex_descriptor
source(typename graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> >::edge_descriptor e, CGAL::Polyhedron_3<Gt,I,HDS,A> & p)
{
return e->opposite()->vertex();
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
typename graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> >::vertex_descriptor
target(typename graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> >::edge_descriptor e, CGAL::Polyhedron_3<Gt,I,HDS,A> & p)
{
return e->vertex();
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
inline std::pair<typename graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> >::vertex_iterator
,typename graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> >::vertex_iterator
>
vertices( CGAL::Polyhedron_3<Gt,I,HDS,A>& p)
{
typedef typename graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> >::vertex_iterator Iter;
return std::make_pair( Iter(p.vertices_begin()), Iter(p.vertices_end()) );
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
inline std::pair<typename graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> >::edge_iterator
,typename graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> >::edge_iterator
>
edges( CGAL::Polyhedron_3<Gt,I,HDS,A>& p)
{
typedef typename graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> >::edge_iterator Iter;
return std::make_pair( Iter(p.halfedges_begin()), Iter(p.halfedges_end()) );
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
inline std::pair<typename graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> >::in_edge_iterator
,typename graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> >::in_edge_iterator
>
in_edges( typename graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> >::vertex_descriptor u, CGAL::Polyhedron_3<Gt,I,HDS,A>& g)
{
typename CGAL::Polyhedron_3<Gt,I,HDS,A>::Halfedge_around_vertex_circulator ec = u->vertex_begin();
typename graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> >::edges_size_type in_deg = in_degree(u,g);
typedef typename graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> >::in_edge_iterator Iter;
return std::make_pair( Iter(ec), Iter(ec,in_deg) );
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
inline std::pair<typename graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> >::out_edge_iterator
,typename graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> >::out_edge_iterator
>
out_edges( typename graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> >::vertex_descriptor u, CGAL::Polyhedron_3<Gt,I,HDS,A>& g)
{
typename CGAL::Polyhedron_3<Gt,I,HDS,A>::Halfedge_around_vertex_circulator ec = u->vertex_begin();
typename graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> >::edges_size_type out_deg = out_degree(u,g);
typedef typename graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> >::out_edge_iterator Iter;
return std::make_pair( Iter(ec), Iter(ec,out_deg) );
}
} // namespace boost
#undef CGAL_HDS_
#endif // CGAL_POLYHEDRON_BGL_H

View File

@ -0,0 +1,218 @@
// Copyright (c) 2006 Geometry Factory (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// 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 <andreas.fabri@geometryfactory.com>, Fernando Cacciola <fernando.cacciola@gmail.com>
#ifndef CGAL_POLYHEDRON_BGL_PROPERTIES_H
#define CGAL_POLYHEDRON_BGL_PROPERTIES_H
#include <CGAL/Polyhedron_BGL.h>
#ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
# define CGAL_HDS_PARAM_ template < class Traits, class Items, class Alloc> class HDS
#else
# define CGAL_HDS_PARAM_ class HDS
#endif
namespace boost
{
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
class Polyhedron_edge_weight_map : public put_get_helper<double, Polyhedron_edge_weight_map<Gt, I, HDS, A> >
{
private:
typedef CGAL::Polyhedron_3<Gt,I,HDS,A> Polyhedron ;
public:
typedef readable_property_map_tag category;
typedef double value_type;
typedef double reference;
typedef typename graph_traits<Polyhedron const>::edge_descriptor key_type;
Polyhedron_edge_weight_map( Polyhedron const& p_)
{}
reference operator[](key_type const& e) const {
return CGAL::squared_distance(e->vertex()->point(), e->opposite()->vertex()->point());
}
};
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
class Polyhedron_edge_is_border_map : public put_get_helper<double, Polyhedron_edge_is_border_map<Gt, I, HDS, A> >
{
private:
typedef CGAL::Polyhedron_3<Gt,I,HDS,A> Polyhedron ;
public:
typedef readable_property_map_tag category;
typedef bool value_type;
typedef bool reference;
typedef typename graph_traits<Polyhedron const>::edge_descriptor key_type;
Polyhedron_edge_is_border_map( Polyhedron const& p_)
{ }
reference operator[](key_type const& e) const
{
return e->is_border();
}
};
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
class Polyhedron_vertex_point_map : public put_get_helper< typename Gt::Point_3, Polyhedron_vertex_point_map<Gt, I, HDS, A> >
{
private:
typedef CGAL::Polyhedron_3<Gt,I,HDS,A> Polyhedron ;
public:
typedef typename Gt::Point_3 Point_3 ;
typedef lvalue_property_map_tag category;
typedef Point_3 value_type;
typedef Point_3 & reference;
typedef typename graph_traits<Polyhedron>::vertex_descriptor key_type;
Polyhedron_vertex_point_map( Polyhedron& p_)
{ }
reference operator[](key_type const& e) const
{
return e->point();
}
};
struct edge_is_border_t {} ;
struct vertex_point_t {} ;
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
inline Polyhedron_edge_weight_map<Gt, I, HDS, A>
get(edge_weight_t, const CGAL::Polyhedron_3<Gt,I,HDS,A>& p)
{
Polyhedron_edge_weight_map<Gt, I, HDS, A> m(p);
return m;
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
inline Polyhedron_edge_is_border_map<Gt, I, HDS, A>
get(edge_is_border_t, const CGAL::Polyhedron_3<Gt,I,HDS,A>& p)
{
Polyhedron_edge_is_border_map<Gt, I, HDS, A> m(p);
return m;
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
inline Polyhedron_vertex_point_map<Gt, I, HDS, A>
get(vertex_point_t, CGAL::Polyhedron_3<Gt,I,HDS,A>& p)
{
Polyhedron_vertex_point_map<Gt, I, HDS, A> m(p);
return m;
}
template <class Tag>
struct Polyhedron_property_map { };
template <>
struct Polyhedron_property_map<edge_weight_t>
{
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
struct bind_ {
typedef Polyhedron_edge_weight_map<Gt, I, HDS, A> type;
typedef Polyhedron_edge_weight_map<Gt, I, HDS, A> const_type;
};
};
template <>
struct Polyhedron_property_map<edge_is_border_t>
{
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
struct bind_ {
typedef Polyhedron_edge_is_border_map<Gt, I, HDS, A> type;
typedef Polyhedron_edge_is_border_map<Gt, I, HDS, A> const_type;
};
};
template <>
struct Polyhedron_property_map<vertex_point_t>
{
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
struct bind_ {
typedef Polyhedron_vertex_point_map<Gt, I, HDS, A> type;
typedef Polyhedron_vertex_point_map<Gt, I, HDS, A> const_type;
};
};
// g++ 'enumeral_type' in template unification not implemented workaround
template<class Gt, class I, CGAL_HDS_PARAM_, class A, class Tag>
struct property_map<CGAL::Polyhedron_3<Gt,I,HDS,A>, Tag>
{
typedef typename Polyhedron_property_map<Tag>::template bind_<Gt, I, HDS, A> map_gen;
typedef typename map_gen::type type;
typedef typename map_gen::const_type const_type;
};
template<class Gt, class I, CGAL_HDS_PARAM_, class A, class PropertyTag, class Key>
inline
typename property_traits< typename property_map<CGAL::Polyhedron_3<Gt,I,HDS,A>,PropertyTag>::type>::value_type
get(PropertyTag p, CGAL::Polyhedron_3<Gt,I,HDS,A>& g, const Key& key)
{
return get(get(p, g), key);
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A, class PropertyTag, class Key>
inline
typename property_traits< typename property_map<CGAL::Polyhedron_3<Gt,I,HDS,A>,PropertyTag>::const_type>::value_type
get(PropertyTag p, const CGAL::Polyhedron_3<Gt,I,HDS,A>& g, const Key& key)
{
return get(get(p, g), key);
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A, class PropertyTag, class Key,class Value>
inline void put(PropertyTag p, CGAL::Polyhedron_3<Gt,I,HDS,A>& g, const Key& key, const Value& value)
{
typedef typename property_map<CGAL::Polyhedron_3<Gt,I,HDS,A>, PropertyTag>::type Map;
Map pmap = get(p, g);
put(pmap, key, value);
}
// What are those needed for ???
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
struct edge_property_type<CGAL::Polyhedron_3<Gt,I,HDS,A> >
{
typedef edge_weight_t type;
};
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
struct vertex_property_type<CGAL::Polyhedron_3<Gt,I,HDS,A> >
{
typedef vertex_point_t type;
};
} // namespace boost
#undef CGAL_HDS_
#endif // CGAL_POLYHEDRON_BGL_PROPERTIES_H

View File

@ -0,0 +1,207 @@
// Copyright (c) 2006 Geometry Factory (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// 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) : Fernando Caccciola <fernando.cacciola@gmail.com>
#ifndef CGAL_POLYHEDRON_EXTENDED_BGL_H
#define CGAL_POLYHEDRON_EXTENDED_BGL_H
#include <CGAL/HalfedgeDS_items_decorator.h>
#include <CGAL/Polyhedron_BGL.h>
#ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
# define CGAL_HDS_PARAM_ template < class Traits, class Items, class Alloc> class HDS
#else
# define CGAL_HDS_PARAM_ class HDS
#endif
CGAL_BEGIN_NAMESPACE
//
// Const versions
//
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
inline std::pair<typename boost::undirected_graph_traits< Polyhedron_3<Gt,I,HDS,A> const>::edge_iterator
,typename boost::undirected_graph_traits< Polyhedron_3<Gt,I,HDS,A> const>::edge_iterator
>
undirected_edges( Polyhedron_3<Gt,I,HDS,A> const& p )
{
typedef typename boost::undirected_graph_traits< Polyhedron_3<Gt,I,HDS,A> const>::edge_iterator Iter;
return std::make_pair( Iter(p.edges_begin()), Iter(p.edges_end()) );
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
typename boost::graph_traits< Polyhedron_3<Gt,I,HDS,A> const>::edge_descriptor
next_edge( typename boost::graph_traits< Polyhedron_3<Gt,I,HDS,A> const>::edge_descriptor outedge
, Polyhedron_3<Gt,I,HDS,A> const&
)
{
return outedge->next();
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
typename boost::graph_traits< Polyhedron_3<Gt,I,HDS,A> const>::edge_descriptor
prev_edge( typename boost::graph_traits< Polyhedron_3<Gt,I,HDS,A> const>::edge_descriptor outedge
, Polyhedron_3<Gt,I,HDS,A> const&
)
{
HalfedgeDS_items_decorator< Polyhedron_3<Gt,I,HDS,A> > D ;
return D.get_prev(outedge);
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
typename boost::graph_traits< Polyhedron_3<Gt,I,HDS,A> const>::edge_descriptor
opposite_edge( typename boost::graph_traits< Polyhedron_3<Gt,I,HDS,A> const>::edge_descriptor e
, Polyhedron_3<Gt,I,HDS,A> const&
)
{
return e->opposite();
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
typename boost::graph_traits< Polyhedron_3<Gt,I,HDS,A> const>::edge_descriptor
next_edge_ccw( typename boost::graph_traits< Polyhedron_3<Gt,I,HDS,A> const>::edge_descriptor outedge
, Polyhedron_3<Gt,I,HDS,A> const&
)
{
HalfedgeDS_items_decorator< Polyhedron_3<Gt,I,HDS,A> > D ;
return D.get_prev(outedge)->opposite();
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
typename boost::graph_traits< Polyhedron_3<Gt,I,HDS,A> const>::edge_descriptor
next_edge_cw( typename boost::graph_traits< Polyhedron_3<Gt,I,HDS,A> const>::edge_descriptor outedge
, Polyhedron_3<Gt,I,HDS,A> const&
)
{
return outedge->opposite()->next();
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
typename boost::graph_traits< Polyhedron_3<Gt,I,HDS,A> const>::edge_descriptor
out_edge( typename boost::graph_traits< Polyhedron_3<Gt,I,HDS,A> const>::vertex_descriptor u
, Polyhedron_3<Gt,I,HDS,A> const&
)
{
HalfedgeDS_items_decorator< Polyhedron_3<Gt,I,HDS,A> > D ;
return D.get_vertex_edge(u)->opposite();
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
typename boost::graph_traits< Polyhedron_3<Gt,I,HDS,A> const>::edge_descriptor
in_edge( typename boost::graph_traits< Polyhedron_3<Gt,I,HDS,A> const>::vertex_descriptor u
, Polyhedron_3<Gt,I,HDS,A> const&
)
{
HalfedgeDS_items_decorator< Polyhedron_3<Gt,I,HDS,A> > D ;
return D.get_vertex_edge(u);
}
//
// Non-Const versions
//
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
inline std::pair<typename boost::undirected_graph_traits< Polyhedron_3<Gt,I,HDS,A> >::edge_iterator
,typename boost::undirected_graph_traits< Polyhedron_3<Gt,I,HDS,A> >::edge_iterator
>
undirected_edges( Polyhedron_3<Gt,I,HDS,A>& p )
{
typedef typename boost::undirected_graph_traits< Polyhedron_3<Gt,I,HDS,A> >::edge_iterator Iter;
return std::make_pair( Iter(p.edges_begin()), Iter(p.edges_end()) );
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
typename boost::graph_traits< Polyhedron_3<Gt,I,HDS,A> >::edge_descriptor
next_edge( typename boost::graph_traits< Polyhedron_3<Gt,I,HDS,A> >::edge_descriptor outedge
, Polyhedron_3<Gt,I,HDS,A>&
)
{
return outedge->next();
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
typename boost::graph_traits< Polyhedron_3<Gt,I,HDS,A> >::edge_descriptor
prev_edge( typename boost::graph_traits< Polyhedron_3<Gt,I,HDS,A> >::edge_descriptor outedge
, Polyhedron_3<Gt,I,HDS,A>& p
)
{
CGAL::HalfedgeDS_items_decorator< Polyhedron_3<Gt,I,HDS,A> > D ;
return D.get_prev(outedge);
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
typename boost::graph_traits< Polyhedron_3<Gt,I,HDS,A> >::edge_descriptor
opposite_edge( typename boost::graph_traits< Polyhedron_3<Gt,I,HDS,A> >::edge_descriptor e
, Polyhedron_3<Gt,I,HDS,A>&
)
{
return e->opposite();
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
typename boost::graph_traits< Polyhedron_3<Gt,I,HDS,A> >::edge_descriptor
next_edge_ccw( typename boost::graph_traits< Polyhedron_3<Gt,I,HDS,A> >::edge_descriptor outedge
, Polyhedron_3<Gt,I,HDS,A>&
)
{
HalfedgeDS_items_decorator< Polyhedron_3<Gt,I,HDS,A> > D ;
return D.get_prev(outedge)->opposite();
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
typename boost::graph_traits< Polyhedron_3<Gt,I,HDS,A> >::edge_descriptor
next_edge_cw( typename boost::graph_traits< Polyhedron_3<Gt,I,HDS,A> >::edge_descriptor outedge
, Polyhedron_3<Gt,I,HDS,A>&
)
{
return outedge->opposite()->next();
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
typename boost::graph_traits< Polyhedron_3<Gt,I,HDS,A> >::edge_descriptor
out_edge( typename boost::graph_traits< Polyhedron_3<Gt,I,HDS,A> >::vertex_descriptor u
, Polyhedron_3<Gt,I,HDS,A>&
)
{
HalfedgeDS_items_decorator< Polyhedron_3<Gt,I,HDS,A> > D ;
return D.get_vertex_edge(u)->opposite();
}
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
typename boost::graph_traits< Polyhedron_3<Gt,I,HDS,A> >::edge_descriptor
in_edge( typename boost::graph_traits< Polyhedron_3<Gt,I,HDS,A> >::vertex_descriptor u
, Polyhedron_3<Gt,I,HDS,A>&
)
{
HalfedgeDS_items_decorator< Polyhedron_3<Gt,I,HDS,A> > D ;
return D.get_vertex_edge(u);
}
CGAL_END_NAMESPACE
#undef CGAL_HDS_
#endif // CGAL_POLYHEDRON_EXTENDED_BGL_H

View File

@ -1,904 +0,0 @@
// Copyright (c) 2006 Geometry Factory (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// 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 <andreas.fabri@geometryfactory.com>)
#ifndef CGAL_POLYHEDRON_GRAPH_TRAITS_3_H
#define CGAL_POLYHEDRON_GRAPH_TRAITS_3_H
#include <boost/config.hpp>
#include <boost/iterator_adaptors.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/properties.hpp>
#include <CGAL/HalfedgeDS_items_decorator.h>
namespace boost {
namespace detail {
template <class Circ, class E>
class In_edge_circulator : public Circ
{
private:
mutable E e;
public:
typedef E value_type;
typedef E* pointer;
typedef E& reference;
In_edge_circulator()
: Circ()
{}
In_edge_circulator(Circ c)
: Circ(c)
{}
const E& operator*() const
{
e = *this;
return e;
}
};
template <class Circ, class E>
class Out_edge_circulator : public Circ
{
private:
mutable E e;
public:
typedef E value_type;
typedef E* pointer;
typedef E& reference;
Out_edge_circulator()
: Circ()
{}
Out_edge_circulator(Circ c)
: Circ(c)
{}
const E& operator*() const
{
e = *this;
e = e->opposite();
return e;
}
};
// The vertex iterator of the bgl must evaluate to a vertex handle, not to a vertex
template < class P, class Vertex_iterator, class Vertex_handle>
class boost_P_all_vertices_iterator_base {
protected:
Vertex_iterator nt;
public:
typedef Vertex_iterator Iterator;
typedef boost_P_all_vertices_iterator_base<P,Vertex_iterator,Vertex_handle> Self;
typedef typename std::iterator_traits<Iterator>::iterator_category iterator_category;
typedef Vertex_handle value_type;
typedef typename std::iterator_traits<Iterator>::difference_type difference_type;
typedef value_type reference;
typedef value_type pointer;
protected:
// CREATION
// --------
boost_P_all_vertices_iterator_base()
{}
boost_P_all_vertices_iterator_base( Iterator j) : nt(j) {}
public:
// OPERATIONS Forward Category
// ---------------------------
bool operator==( const Self& i) const { return ( nt == i.nt); }
bool operator!=( const Self& i) const { return !(nt == i.nt ); }
value_type operator*() const { return nt; }
value_type operator->() { return nt; }
Self& operator++() {
++nt;
return *this;
}
Self operator++(int) {
Self tmp = *this;
++*this;
return tmp;
}
};
template < class P >
class boost_P_all_vertices_const_iterator
: public boost_P_all_vertices_iterator_base<P,typename P::Vertex_const_iterator,typename P::Vertex_const_handle>
{
typedef boost_P_all_vertices_iterator_base<P,typename P::Vertex_const_iterator,typename P::Vertex_const_handle> Base ;
public:
typedef typename P::Vertex_const_iterator Iterator;
// CREATION
// --------
boost_P_all_vertices_const_iterator() {}
boost_P_all_vertices_const_iterator( Iterator j) : Base(j) {}
};
template < class P >
class boost_P_all_vertices_iterator
: public boost_P_all_vertices_iterator_base<P,typename P::Vertex_iterator,typename P::Vertex_handle>
{
typedef boost_P_all_vertices_iterator_base<P,typename P::Vertex_iterator,typename P::Vertex_handle> Base ;
public:
typedef typename P::Vertex_iterator Iterator;
// CREATION
// --------
boost_P_all_vertices_iterator() {}
boost_P_all_vertices_iterator( Iterator j) : Base(j) {}
};
template < class P, class Halfedge_iterator, class Halfedge_handle >
class boost_P_all_edges_iterator_base {
protected:
Halfedge_iterator nt;
public:
typedef Halfedge_iterator Iterator;
typedef boost_P_all_edges_iterator_base<P,Halfedge_iterator,Halfedge_handle> Self;
typedef typename std::iterator_traits<Iterator>::iterator_category iterator_category;
typedef Halfedge_handle value_type;
typedef typename std::iterator_traits<Iterator>::difference_type difference_type;
typedef value_type reference;
typedef value_type pointer;
protected:
// CREATION
// --------
boost_P_all_edges_iterator_base()
{}
boost_P_all_edges_iterator_base( Iterator j) : nt(j) {}
public:
// OPERATIONS Forward Category
// ---------------------------
bool operator==( const Self& i) const { return ( nt == i.nt); }
bool operator!=( const Self& i) const { return !(nt == i.nt ); }
value_type operator*() const { return nt; }
value_type operator->() { return nt; }
Self& operator++() {
++nt;
return *this;
}
Self operator++(int) {
Self tmp = *this;
++*this;
return tmp;
}
};
template < class P >
class boost_P_all_edges_const_iterator
: public boost_P_all_edges_iterator_base<P,typename P::Edge_const_iterator,typename P::Halfedge_const_handle>
{
typedef boost_P_all_edges_iterator_base<P,typename P::Edge_const_iterator,typename P::Halfedge_const_handle> Base ;
public:
typedef typename P::Edge_const_iterator Iterator;
// CREATION
// --------
boost_P_all_edges_const_iterator() {}
boost_P_all_edges_const_iterator( Iterator j) : Base(j) {}
};
template < class P >
class boost_P_all_edges_iterator
: public boost_P_all_edges_iterator_base<P,typename P::Edge_iterator,typename P::Halfedge_handle>
{
typedef boost_P_all_edges_iterator_base<P,typename P::Edge_iterator,typename P::Halfedge_handle> Base ;
public:
typedef typename P::Edge_iterator Iterator;
// CREATION
// --------
boost_P_all_edges_iterator() {}
boost_P_all_edges_iterator( Iterator j) : Base(j) {}
};
} // namespace detail
template < class PolyhedronTraits_3, class PolyhedronItems_3,
#ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
template < class T, class I, class A>
#endif
class T_HDS, class Alloc>
struct graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> > {
struct Polyhedron_graph_traversal_category :
public virtual bidirectional_graph_tag,
public virtual adjacency_graph_tag,
public virtual vertex_list_graph_tag,
public virtual edge_list_graph_tag
{ };
typedef CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> Polyhedron;
typedef typename Polyhedron::Vertex_handle vertex_descriptor;
typedef typename Polyhedron::Halfedge_handle edge_descriptor;
// NOTE: These are NOT defined as part of the BGL graph_traits class
typedef typename Polyhedron::Vertex_const_handle vertex_const_descriptor;
typedef typename Polyhedron::Halfedge_const_handle edge_const_descriptor;
typedef detail::boost_P_all_vertices_iterator<Polyhedron> vertex_iterator;
typedef detail::boost_P_all_edges_iterator <Polyhedron> edge_iterator;
// NOTE: These are NOT defined as part of the BGL graph_traits class
typedef detail::boost_P_all_vertices_const_iterator<Polyhedron> vertex_const_iterator;
typedef detail::boost_P_all_edges_const_iterator <Polyhedron> edge_const_iterator;
typedef CGAL::Counting_iterator<detail::Out_edge_circulator<typename Polyhedron::Halfedge_around_vertex_circulator
,edge_descriptor
>
, edge_descriptor
> out_edge_iterator;
typedef CGAL::Counting_iterator<detail::In_edge_circulator<typename Polyhedron::Halfedge_around_vertex_circulator
,edge_descriptor
>
, edge_descriptor
> in_edge_iterator;
// NOTE: This is NOT defined as part of the BGL graph_traits class
typedef CGAL::Counting_iterator<detail::Out_edge_circulator<typename Polyhedron::Halfedge_around_vertex_const_circulator
,edge_const_descriptor
>
, edge_const_descriptor
> out_edge_const_iterator;
// NOTE: This is NOT defined as part of the BGL graph_traits class
typedef CGAL::Counting_iterator<detail::In_edge_circulator<typename Polyhedron::Halfedge_around_vertex_const_circulator
,edge_const_descriptor
>
, edge_const_descriptor
> in_edge_const_iterator;
//typedef CGAL::Counting_iterator<typename Triangulation::Vertex_circulator> Incident_vertices_iterator;
//typedef Incident_vertices_iterator adjacency_iterator;
typedef directed_tag directed_category;
typedef disallow_parallel_edge_tag edge_parallel_category;
typedef Polyhedron_graph_traversal_category traversal_category;
typedef typename Polyhedron::size_type vertices_size_type;
typedef typename Polyhedron::size_type edges_size_type;
typedef typename Polyhedron::size_type degree_size_type;
};
template < class PolyhedronTraits_3, class PolyhedronItems_3,
#ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
template < class T, class I, class A>
#endif
class T_HDS, class Alloc>
typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::vertex_descriptor
source(typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::edge_descriptor e,
CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> & p)
{
return e->opposite()->vertex();
}
template < class PolyhedronTraits_3, class PolyhedronItems_3,
#ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
template < class T, class I, class A>
#endif
class T_HDS, class Alloc>
typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::vertex_const_descriptor
source(typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::edge_const_descriptor e,
CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> const& p)
{
return e->opposite()->vertex();
}
template < class PolyhedronTraits_3, class PolyhedronItems_3,
#ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
template < class T, class I, class A>
#endif
class T_HDS, class Alloc>
typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::vertex_descriptor
target(typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::edge_descriptor e,
CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> & p)
{
return e->vertex();
}
template < class PolyhedronTraits_3, class PolyhedronItems_3,
#ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
template < class T, class I, class A>
#endif
class T_HDS, class Alloc>
typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::vertex_const_descriptor
target(typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::edge_const_descriptor e,
CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> const& p)
{
return e->vertex();
}
template < class PolyhedronTraits_3, class PolyhedronItems_3,
#ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
template < class T, class I, class A>
#endif
class T_HDS, class Alloc>
inline std::pair<
typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::vertex_iterator,
typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::vertex_iterator >
vertices( CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc>& p)
{
typedef typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::vertex_iterator
Iter;
return std::make_pair( Iter(p.vertices_begin()), Iter(p.vertices_end()) );
}
template < class PolyhedronTraits_3, class PolyhedronItems_3,
#ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
template < class T, class I, class A>
#endif
class T_HDS, class Alloc>
inline std::pair<
typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::vertex_const_iterator,
typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::vertex_const_iterator >
vertices( CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> const& p)
{
typedef typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::vertex_const_iterator
Iter;
return std::make_pair( Iter(p.vertices_begin()), Iter(p.vertices_end()) );
}
template < class PolyhedronTraits_3, class PolyhedronItems_3,
#ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
template < class T, class I, class A>
#endif
class T_HDS, class Alloc>
inline std::pair<
typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::edge_iterator,
typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::edge_iterator >
edges( CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc>& p)
{
typedef typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::edge_iterator
Iter;
return std::make_pair( Iter(p.edges_begin()), Iter(p.edges_end()) );
}
template < class PolyhedronTraits_3, class PolyhedronItems_3,
#ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
template < class T, class I, class A>
#endif
class T_HDS, class Alloc>
inline std::pair<
typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::edge_const_iterator,
typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::edge_const_iterator >
edges( CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> const& p)
{
typedef typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::edge_const_iterator
Iter;
return std::make_pair( Iter(p.edges_begin()), Iter(p.edges_end()) );
}
template < class PolyhedronTraits_3, class PolyhedronItems_3,
#ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
template < class T, class I, class A>
#endif
class T_HDS, class Alloc>
inline std::pair<
typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::in_edge_iterator,
typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::in_edge_iterator >
in_edges(
typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::vertex_descriptor u,
CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc>& g)
{
typename CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc>::Halfedge_around_vertex_circulator
ec = u->vertex_begin();
int in_deg = in_degree(u,g);
typedef typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >
::in_edge_iterator Iter;
return std::make_pair( Iter(ec), Iter(ec,in_deg) );
}
template < class PolyhedronTraits_3, class PolyhedronItems_3,
#ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
template < class T, class I, class A>
#endif
class T_HDS, class Alloc>
inline std::pair<
typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::in_edge_const_iterator,
typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::in_edge_const_iterator >
in_edges(
typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::vertex_const_descriptor u,
CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> const& g)
{
typename CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc>::Halfedge_around_vertex_const_circulator
ec = u->vertex_begin();
int in_deg = in_degree(u,g);
typedef typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >
::in_edge_const_iterator Iter;
return std::make_pair( Iter(ec), Iter(ec,in_deg) );
}
template < class PolyhedronTraits_3, class PolyhedronItems_3,
#ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
template < class T, class I, class A>
#endif
class T_HDS, class Alloc>
inline std::pair<
typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::out_edge_iterator,
typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::out_edge_iterator >
out_edges(
typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::vertex_descriptor u,
const CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc>& g)
{
typename CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc>::Halfedge_around_vertex_circulator
ec = u->vertex_begin();
int out_deg = out_degree(u,g);
typedef typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >
::out_edge_iterator Iter;
return std::make_pair( Iter(ec), Iter(ec,out_deg) );
}
template < class PolyhedronTraits_3, class PolyhedronItems_3,
#ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
template < class T, class I, class A>
#endif
class T_HDS, class Alloc>
inline std::pair<
typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::out_edge_const_iterator,
typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::out_edge_const_iterator >
out_edges(
typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::vertex_const_descriptor u,
CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> const& g)
{
typename CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc>::Halfedge_around_vertex_const_circulator
ec = u->vertex_begin();
int out_deg = out_degree(u,g);
typedef typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >
::out_edge_const_iterator Iter;
return std::make_pair( Iter(ec), Iter(ec,out_deg) );
}
template < class PolyhedronTraits_3, class PolyhedronItems_3,
#ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
template < class T, class I, class A>
#endif
class T_HDS, class Alloc>
typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::vertices_size_type
num_vertices(const CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc>& p)
{
return p.size_of_vertices();
}
template < class PolyhedronTraits_3, class PolyhedronItems_3,
#ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
template < class T, class I, class A>
#endif
class T_HDS, class Alloc>
typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::edges_size_type
num_edges(const CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc>& p)
{
return p.size_of_halfedges() / 2 ;
}
template < class PolyhedronTraits_3, class PolyhedronItems_3,
#ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
template < class T, class I, class A>
#endif
class T_HDS, class Alloc>
typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::degree_size_type
degree(typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::vertex_const_descriptor v,
const CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc>&)
{
return v->vertex_degree();
}
template < class PolyhedronTraits_3, class PolyhedronItems_3,
#ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
template < class T, class I, class A>
#endif
class T_HDS, class Alloc>
typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::degree_size_type
out_degree(typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::vertex_const_descriptor v,
const CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc>&)
{
return v->vertex_degree();
}
template < class PolyhedronTraits_3, class PolyhedronItems_3,
#ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
template < class T, class I, class A>
#endif
class T_HDS, class Alloc>
typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::degree_size_type
in_degree(typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::vertex_const_descriptor v,
const CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc>&)
{
return v->vertex_degree();
}
template < class PolyhedronTraits_3, class PolyhedronItems_3,
#ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
template < class T, class I, class A>
#endif
class T_HDS, class Alloc>
class Polyhedron_edge_weight_map
: public put_get_helper<double, Polyhedron_edge_weight_map<PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >
{
private:
typedef CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> Polyhedron ;
Polyhedron const* p;
public:
typedef readable_property_map_tag category;
typedef double value_type;
typedef double reference;
typedef typename graph_traits<Polyhedron>::edge_const_descriptor key_type;
Polyhedron_edge_weight_map( Polyhedron const& p_)
: p( boost::addressof(p_) )
{ }
reference operator[](key_type const& e) const {
return CGAL::squared_distance(e->vertex()->point(), e->opposite()->vertex()->point());
}
};
template < class PolyhedronTraits_3, class PolyhedronItems_3,
#ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
template < class T, class I, class A>
#endif
class T_HDS, class Alloc>
inline Polyhedron_edge_weight_map<PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc>
get(edge_weight_t, const CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc>& p) {
Polyhedron_edge_weight_map<PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> m(p);
return m;
}
template < class PolyhedronTraits_3, class PolyhedronItems_3,
#ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
template < class T, class I, class A>
#endif
class T_HDS, class Alloc>
class Polyhedron_vertex_point_map
: public put_get_helper< typename PolyhedronTraits_3::Point_3
, Polyhedron_vertex_point_map<PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc>
>
{
private:
typedef CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> Polyhedron ;
Polyhedron* p;
public:
typedef typename PolyhedronTraits_3::Point_3 Point_3 ;
typedef lvalue_property_map_tag category;
typedef Point_3 value_type;
typedef Point_3 & reference;
typedef typename graph_traits<Polyhedron>::vertex_descriptor key_type;
Polyhedron_vertex_point_map( Polyhedron& p_)
: p( boost::addressof(p_) )
{ }
reference operator[](key_type const& e) const {
return e->point();
}
};
struct vertex_point_t {} ;
template < class PolyhedronTraits_3, class PolyhedronItems_3,
#ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
template < class T, class I, class A>
#endif
class T_HDS, class Alloc>
inline Polyhedron_vertex_point_map<PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc>
get(vertex_point_t, CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc>& p) {
Polyhedron_vertex_point_map<PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> m(p);
return m;
}
template <class Tag>
struct Polyhedron_property_map { };
template <>
struct Polyhedron_property_map<edge_weight_t> {
template < class PolyhedronTraits_3, class PolyhedronItems_3,
#ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
template < class T, class I, class A>
#endif
class T_HDS, class Alloc>
struct bind_ {
typedef Polyhedron_edge_weight_map<PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> type;
typedef Polyhedron_edge_weight_map<PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> const_type;
};
};
template <>
struct Polyhedron_property_map<vertex_point_t> {
template < class PolyhedronTraits_3, class PolyhedronItems_3,
#ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
template < class T, class I, class A>
#endif
class T_HDS, class Alloc>
struct bind_ {
typedef Polyhedron_vertex_point_map<PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> type;
typedef Polyhedron_vertex_point_map<PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> const_type;
};
};
// g++ 'enumeral_type' in template unification not implemented workaround
template <class PolyhedronTraits_3, class PolyhedronItems_3,
#ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
template < class T, class I, class A>
#endif
class T_HDS, class Alloc, class Tag>
struct property_map<CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc>, Tag> {
typedef typename
Polyhedron_property_map<Tag>::template bind_<PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> map_gen;
typedef typename map_gen::type type;
typedef typename map_gen::const_type const_type;
};
template <class PolyhedronTraits_3, class PolyhedronItems_3,
#ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
template < class T, class I, class A>
#endif
class T_HDS, class Alloc, class PropertyTag, class Key>
inline
typename boost::property_traits<
typename boost::property_map<CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc>,PropertyTag>::type>::value_type
get(PropertyTag p, CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc>& g, const Key& key) {
return get(get(p, g), key);
}
template <class PolyhedronTraits_3, class PolyhedronItems_3,
#ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
template < class T, class I, class A>
#endif
class T_HDS, class Alloc, class PropertyTag, class Key>
inline
typename boost::property_traits<
typename boost::property_map<CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc>,PropertyTag>::const_type>::value_type
get(PropertyTag p, const CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc>& g, const Key& key) {
return get(get(p, g), key);
}
template <class PolyhedronTraits_3, class PolyhedronItems_3,
#ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
template < class T, class I, class A>
#endif
class T_HDS, class Alloc, class PropertyTag, class Key,class Value>
inline void
put(PropertyTag p, CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc>& g,
const Key& key, const Value& value)
{
typedef typename property_map<CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc>, PropertyTag>::type Map;
Map pmap = get(p, g);
put(pmap, key, value);
}
// What are those needed for ???
template < class PolyhedronTraits_3, class PolyhedronItems_3,
#ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
template < class T, class I, class A>
#endif
class T_HDS, class Alloc>
struct edge_property_type<CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> > {
typedef edge_weight_t type;
};
template < class PolyhedronTraits_3, class PolyhedronItems_3,
#ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
template < class T, class I, class A>
#endif
class T_HDS, class Alloc>
struct vertex_property_type<CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> > {
typedef vertex_point_t type;
};
//****************************************************************************************************************
//
// Extended-BGL interface
//
//
// Some queries typical of CGAL data-structures can be handled by the BGL interface but with an unneccesary
// high complexity. For example, accessing the halfedge incident upon a HDS vertex can be done via out_edges(),
// but out_edges() has complexity O(number_of_adjacent_vertices).
// For that reason, the following "Extended-BGL" interface is defined.
// Algorithms MUST indicate whether they need a DS to support this Extended-BGL interface.
//
// first_in_edge(v,dag)
// first_out_edge(v,dag)
// next_in_edge_ccw(e,dag)
// next_in_edge_cw(e,dag)
// next_out_edge_ccw(e,dag)
// next_out_edge_cw(e,dag)
// opposite_edge(e,dag)
//
template < class PolyhedronTraits_3, class PolyhedronItems_3,
#ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
template < class T, class I, class A>
#endif
class T_HDS, class Alloc>
typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::edge_descriptor
out_edge(
typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::vertex_descriptor u,
CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc>& g)
{
CGAL::HalfedgeDS_items_decorator< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> > D ;
return D.get_vertex_halfedge(u)->opposite();
}
template < class PolyhedronTraits_3, class PolyhedronItems_3,
#ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
template < class T, class I, class A>
#endif
class T_HDS, class Alloc>
typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::edge_const_descriptor
out_edge(
typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::vertex_const_descriptor u,
CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> const& g)
{
CGAL::HalfedgeDS_items_decorator< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> > D ;
return D.get_vertex_halfedge(u)->opposite();
}
template < class PolyhedronTraits_3, class PolyhedronItems_3,
#ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
template < class T, class I, class A>
#endif
class T_HDS, class Alloc>
typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::edge_descriptor
next_edge_ccw(
typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::edge_descriptor outedge,
CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc>& g)
{
CGAL::HalfedgeDS_items_decorator< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> > D ;
return D.get_prev(outedge)->opposite();
}
template < class PolyhedronTraits_3, class PolyhedronItems_3,
#ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
template < class T, class I, class A>
#endif
class T_HDS, class Alloc>
typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::edge_const_descriptor
next_edge_ccw(
typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::edge_const_descriptor outedge,
CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> const& g)
{
CGAL::HalfedgeDS_items_decorator< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> > D ;
return D.get_prev(outedge)->opposite();
}
template < class PolyhedronTraits_3, class PolyhedronItems_3,
#ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
template < class T, class I, class A>
#endif
class T_HDS, class Alloc>
typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::edge_descriptor
next_edge_cw(
typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::edge_descriptor outedge,
CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc>& g)
{
return outedge->opposite()->next();
}
template < class PolyhedronTraits_3, class PolyhedronItems_3,
#ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
template < class T, class I, class A>
#endif
class T_HDS, class Alloc>
typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::edge_const_descriptor
next_edge_cw(
typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::edge_const_descriptor outedge,
CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> const& g)
{
return outedge->opposite()->next();
}
template < class PolyhedronTraits_3, class PolyhedronItems_3,
#ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
template < class T, class I, class A>
#endif
class T_HDS, class Alloc>
typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::edge_descriptor
opposite_edge(
typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::edge_descriptor e,
CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc>& g)
{
return e->opposite();
}
template < class PolyhedronTraits_3, class PolyhedronItems_3,
#ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
template < class T, class I, class A>
#endif
class T_HDS, class Alloc>
typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::edge_const_descriptor
opposite_edge(
typename graph_traits< CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> >::edge_const_descriptor e,
CGAL::Polyhedron_3< PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc> const& g)
{
return e->opposite();
}
} // namespace boost
#endif // CGAL_POLYHEDRON_GRAPH_TRAITS_3_H

View File

@ -0,0 +1,65 @@
// Copyright (c) 2006 Fernando Luis Cacciola Carballal. All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// 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) : Fernando Cacciola <fernando_cacciola@ciudad.com.ar>
//
#ifndef CGAL_SURFACE_MESH_SIMPLIFICATION_CONSRTUCT_MINIMAL_COLLAPSE_DATA_H
#define CGAL_SURFACE_MESH_SIMPLIFICATION_CONSTRUCT_MINIMAL_COLLAPSE_DATA_H
#include <CGAL/Surface_mesh_simplification/TSMS_common.h>
#include <CGAL/Surface_mesh_simplification/Policies/Minimal_collapse_data.h>
CGAL_BEGIN_NAMESPACE
namespace Triangulated_surface_mesh { namespace Simplification
{
template<class Collapse_data_>
class Construct_minimal_collapse_data
{
public:
typedef Collapse_data_ Collapse_data ;
typedef typename Collapse_data::TSM TSM ;
typedef typename Collapse_data::vertex_descriptor vertex_descriptor ;
typedef typename Collapse_data::edge_descriptor edge_descriptor ;
typedef shared_ptr<Collapse_data> result_type ;
typedef void Params ;
public :
result_type operator() ( vertex_descriptor const& aP
, vertex_descriptor const& aQ
, edge_descriptor const& aEdge
, TSM & aSurface
, Params const*
) const
{
return result_type( new Collapse_data(aP,aQ,aEdge,aSurface) ) ;
}
};
} } // namespace Triangulated_surface_mesh::Simplification
CGAL_END_NAMESPACE
#endif // CGAL_SURFACE_MESH_SIMPLIFICATION_MINIMAL_COLLAPSE_DATA_H
// EOF //

View File

@ -36,29 +36,24 @@ namespace Triangulated_surface_mesh { namespace Simplification
// //
// Stops when the ratio of initial to current vertex pairs is below some value. // Stops when the ratio of initial to current vertex pairs is below some value.
// //
template<class TSM_> template<class Collapse_data_>
class Count_ratio_stop_condition class Count_ratio_stop_condition
{ {
public: public:
typedef TSM_ TSM ; typedef Collapse_data_ Collapse_data ;
typedef typename boost::graph_traits<TSM>::vertex_descriptor vertex_descriptor ; typedef typename Collapse_data::FT FT ;
typedef typename boost::graph_traits<TSM>::edges_size_type size_type ; typedef typename Collapse_data::size_type size_type ;
typedef typename Surface_geometric_traits<TSM>::FT FT ;
public : public :
Count_ratio_stop_condition( double aRatio ) : mRatio(aRatio) {} Count_ratio_stop_condition( double aRatio ) : mRatio(aRatio) {}
bool operator()( FT // aCurrentCost bool operator()( FT const& // aCurrentCost
, vertex_descriptor // p , Collapse_data const& //aData
, vertex_descriptor // q , size_type aInitialCount
, bool // aIsEdge , size_type aCurrentCount
, size_type aInitialCount
, size_type aCurrentCount
, TSM& // aSurface
) const ) const
{ {
return ( static_cast<double>(aCurrentCount) / static_cast<double>(aInitialCount) ) < mRatio ; return ( static_cast<double>(aCurrentCount) / static_cast<double>(aInitialCount) ) < mRatio ;

View File

@ -0,0 +1,73 @@
// Copyright (c) 2005, 2006 Fernando Luis Cacciola Carballal. All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// 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) : Fernando Cacciola <fernando_cacciola@ciudad.com.ar>
//
#ifndef CGAL_SURFACE_MESH_SIMPLIFICATION_COUNT_STOP_PRED_H
#define CGAL_SURFACE_MESH_SIMPLIFICATION_COUNT_STOP_PRED_H 1
#include <CGAL/Surface_mesh_simplification/TSMS_common.h>
CGAL_BEGIN_NAMESPACE
namespace Triangulated_surface_mesh { namespace Simplification
{
//*******************************************************************************************************************
// -= stopping condition predicate =-
//
// Determines whether the simplification has finished.
// The arguments are (current_cost,vertex,vertex,is_edge,initial_pair_count,current_pair_count,surface) and the result is bool
//
//*******************************************************************************************************************
//
// Stops when the number of edges left falls below a given number.
//
template<class Collapse_data_>
class Count_stop_condition
{
public:
typedef Collapse_data_ Collapse_data ;
typedef typename Collapse_data::FT FT ;
typedef typename Collapse_data::size_type size_type ;
public :
Count_stop_condition( size_type aThres ) : mThres(aThres) {}
bool operator()( FT const& // aCurrentCost
, Collapse_data const& //aData
, size_type aInitialCount
, size_type aCurrentCount
) const
{
return aCurrentCount < mThres ;
}
private:
size_type mThres ;
};
} } // namespace Triangulated_surface_mesh::Simplification
CGAL_END_NAMESPACE
#endif // CGAL_SURFACE_MESH_SIMPLIFICATION_COUNT_STOP_PRED_H //
// EOF //

View File

@ -0,0 +1,248 @@
// Copyright (c) 2005, 2006 Fernando Luis Cacciola Carballal. All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// 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) : Fernando Cacciola <fernando_cacciola@ciudad.com.ar>
//
#ifndef CGAL_SURFACE_MESH_SIMPLIFICATION_LINDSTROM_TURK_H
#define CGAL_SURFACE_MESH_SIMPLIFICATION_LINDSTROM_TURK_H 1
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Surface_mesh_simplification/TSMS_common.h>
#include <CGAL/Surface_mesh_simplification/Policies/LindstromTurk_collapse_data.h>
#include <CGAL/Cartesian/MatrixC33.h>
CGAL_BEGIN_NAMESPACE
//
// This should be in
//
// Implementation of the collapsing cost and placement strategy from:
//
// "Fast and Memory Efficient Polygonal Symplification"
// Peter Lindstrom, Greg Turk
//
namespace Triangulated_surface_mesh { namespace Simplification
{
template<class Collapse_data_>
class LindstromTurkImpl
{
public:
typedef Collapse_data_ Collapse_data ;
typedef typename Collapse_data::TSM TSM ;
typedef typename Collapse_data::vertex_descriptor vertex_descriptor ;
typedef typename Collapse_data::edge_descriptor edge_descriptor ;
typedef typename Collapse_data::Params Params ;
typedef typename Surface_geometric_traits<TSM>::Kernel Kernel ;
typedef typename Kernel::Point_3 Point ;
typedef typename Kernel::Vector_3 Vector ;
typedef typename Kernel::FT FT ;
typedef optional<FT> Optional_FT ;
typedef optional<Point> Optional_point ;
typedef Simple_cartesian<FT> CKernel ;
typedef MatrixC33<CKernel> CMatrix ;
typedef Vector_3<CKernel> CVector ;
public:
typedef shared_ptr<Collapse_data> result_type ;
LindstromTurkImpl( Params const& aParams
, vertex_descriptor const& aP
, vertex_descriptor const& aQ
, edge_descriptor const& aP_Q
, edge_descriptor const& aQ_P
, TSM& aSurface
) ;
result_type result() const { return mResult ; }
private :
struct Triangle
{
Triangle() {}
Triangle( CVector const& aNormalV, FT const& aNormalL ) : NormalV(aNormalV), NormalL(aNormalL) {}
CVector NormalV ;
FT NormalL ;
} ;
typedef std::vector<Triangle> Triangles ;
typedef std::vector<vertex_descriptor> Link ;
struct Boundary
{
Boundary ( CVector const& op_
, CVector const& opN_
, CVector const& pq_
, CVector const& pqN_
, CVector const& qr_
, CVector const& qrN_
)
:
op(op_), opN(opN_), pq(pq_), pqN(pqN_), qr(qr_), qrN(qrN_)
{}
CVector op, opN, pq, pqN, qr, qrN ;
} ;
typedef optional<Boundary> OptionalBoundary ;
class Constrians
{
public:
Constrians() : n(0), A(NULL_MATRIX), b(NULL_VECTOR) {}
void Add_if_alpha_compatible( CVector const& Ai, FT const& bi ) ;
void Add_from_gradient ( CMatrix const& H, CVector const& c ) ;
int n ;
CMatrix A ;
CVector b ;
private:
// alpha = 1 degree
static double squared_cos_alpha() { return 0.999695413509 ; }
static double squared_sin_alpha() { return 3.04586490453e-4; }
} ;
private :
void Add_boundary_preservation_constrians( OptionalBoundary const& aBdry ) ;
void Add_volume_preservation_constrians( Triangles const& aTriangles );
void Add_boundary_and_volume_optimization_constrians( OptionalBoundary const& aBdry, Triangles const& aTriangles ) ;
void Add_shape_optimization_constrians( Link const& aLink ) ;
bool is_border ( edge_descriptor const& edge ) const
{
edge_is_border_t is_border_property ;
return get(is_border_property,mSurface,edge) ;
}
bool is_undirected_edge_a_border ( edge_descriptor const& edge ) const
{
return is_border(edge) || is_border(opposite_edge(edge,mSurface)) ;
}
Point get_point( vertex_descriptor const& v ) const
{
vertex_point_t vertex_point_property ;
return get(vertex_point_property,mSurface,v) ;
}
static CVector toCVector ( Vector const& v )
{
return CVector(v.x(),v.y(),v.z());
}
static Vector toVector ( CVector const& cv )
{
Rational_traits<FT> rat ;
if ( (rat.denominator(cv.x()) != rat.denominator(cv.y()) )
|| (rat.denominator(cv.x()) != rat.denominator(cv.z()) )
)
return Vector(rat.numerator (cv.x()) * rat.denominator(cv.y()) * rat.denominator(cv.z())
,rat.numerator (cv.y()) * rat.denominator(cv.x()) * rat.denominator(cv.z())
,rat.numerator (cv.z()) * rat.denominator(cv.x()) * rat.denominator(cv.y())
,rat.denominator(cv.x()) * rat.denominator(cv.y()) * rat.denominator(cv.z())
);
else
return Vector(rat.numerator(cv.x())
,rat.numerator(cv.y())
,rat.numerator(cv.z())
,rat.denominator(cv.x())
);
}
static CVector Point_cross_product ( Point const& a, Point const& b )
{
return toCVector(cross_product(a-ORIGIN,b-ORIGIN));
}
// This is the (uX)(Xu) product described in the Lindstrom-Turk paper
static CMatrix LT_product( CVector const& u )
{
FT a00 = ( u.y()*u.y() ) + ( u.z()*u.z() ) ;
FT a01 = -u.x()*u.y();
FT a02 = -u.x()*u.z();
FT a10 = a01 ;
FT a11 = ( u.x()*u.x() ) + ( u.z()*u.z() ) ;
FT a12 = - u.y() * u.z();
FT a20 = a02 ;
FT a21 = a12 ;
FT a22 = ( u.x()*u.x() ) + ( u.y()*u.y() ) ;
return CMatrix(a00,a01,a02
,a10,a11,a12
,a20,a21,a22
);
}
Triangle Get_triangle ( vertex_descriptor const& v0
, vertex_descriptor const& v1
, vertex_descriptor const& v2
) ;
void Extract_triangle( vertex_descriptor const& v0
, vertex_descriptor const& v1
, vertex_descriptor const& v2
, edge_descriptor const& e02
, Triangles& rTriangles
) ;
void Extract_triangles_and_link( Triangles& rTriangles, Link& rLink );
OptionalBoundary Extract_boundary() ;
private:
Params const& mParams ;
vertex_descriptor const& mP ;
vertex_descriptor const& mQ ;
edge_descriptor const& mP_Q ;
edge_descriptor const& mQ_P ;
TSM& mSurface ;
private:
Constrians mConstrians ;
result_type mResult;
};
} } // namespace Triangulated_surface_mesh::Simplification
CGAL_END_NAMESPACE
#include <CGAL/Surface_mesh_simplification/Policies/Detail/Lindstrom_Turk_impl.h>
#endif // CGAL_SURFACE_MESH_SIMPLIFICATION_LINDSTROM_TURK_H //
// EOF //

View File

@ -0,0 +1,531 @@
// Copyright (c) 2005, 2006 Fernando Luis Cacciola Carballal. All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// 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) : Fernando Cacciola <fernando_cacciola@ciudad.com.ar>
//
#ifndef CGAL_SURFACE_MESH_SIMPLIFICATION_LINDSTROM_TURK_IMPL_H
#define CGAL_SURFACE_MESH_SIMPLIFICATION_LINDSTROM_TURK_IMPL_H 1
CGAL_BEGIN_NAMESPACE
//
// Implementation of the Vertex Placement strategy from:
//
// "Fast and Memory Efficient Polygonal Symplification"
// Peter Lindstrom, Greg Turk
//
namespace Triangulated_surface_mesh { namespace Simplification
{
template<class CD>
LindstromTurkImpl<CD>::LindstromTurkImpl( Params const& aParams
, vertex_descriptor const& aP
, vertex_descriptor const& aQ
, edge_descriptor const& aP_Q
, edge_descriptor const& aQ_P
, TSM& aSurface
)
:
mParams(aParams)
,mP(aP)
,mQ(aQ)
,mP_Q(aP_Q)
,mQ_P(aQ_P)
,mSurface(aSurface)
{
//
// Each vertex constrian is an equation of the form: Ai * v = bi
// Where 'v' is a CVector representing the vertex,
// Ai is a (row) CVector
// and bi a scalar.
//
// The vertex is completely determined with 3 such constrian, so is the solution
// to the folloing system:
//
// A.r0(). * v = b0
// A1 * v = b1
// A2 * v = b2
//
// Which in matrix form is : A * v = b
//
// (with A a 3x3 matrix and b a vector)
//
// The member variable mConstrinas contains A and b. Indidivual constrians (Ai,bi) can be added to it.
// Once 3 such constrians have been added v is directly solved a:
//
// v = b*inverse(A)
//
// A constrian (Ai,bi) must be alpha-compatible with the previously added constrians (see Paper); if it's not, is discarded.
//
// Volume preservation and optimization constrians are based on the normals to the triangles in the star of the collapsing egde
// Triangle shape optimization constrians are based on the link of the collapsing edge (the cycle of vertices around the edge)
Triangles lTriangles;
Link lLink;
lTriangles.reserve(16);
lLink .reserve(16);
Extract_triangles_and_link(lTriangles,lLink);
// If the collapsing edge is a boundary edge, the "local boundary" is cached in a Boundary object.
OptionalBoundary lBdry ;
if ( is_undirected_edge_a_border(mP_Q) )
{
lBdry = Extract_boundary();
Add_boundary_preservation_constrians(lBdry);
}
if ( mConstrians.n < 3 )
Add_volume_preservation_constrians(lTriangles);
if ( mConstrians.n < 3 )
Add_boundary_and_volume_optimization_constrians(lBdry,lTriangles);
if ( mConstrians.n < 3 )
Add_shape_optimization_constrians(lLink);
Optional_FT lCost ;
Optional_point lVertexPoint ;
// It might happen that there were not enough alpha-compatible constrians.
// In that case there is simply no good vertex placement (mResult is left absent)
if ( mConstrians.n == 3 )
{
optional<CMatrix> OptAi = inverse_matrix(mConstrians.A);
if ( OptAi )
{
CMatrix const& Ai = *OptAi ;
CVector v = mConstrians.b * Ai ;
lVertexPoint = Optional_point(ORIGIN + toVector(v) ) ;
}
}
mResult = result_type( new Collapse_data(mP,mQ,mP_Q,mSurface,lCost,lVertexPoint) );
}
//
// Caches the "local boundary", that is, the sequence of 3 border edges: o->p, p->q, q->e
//
template<class CD>
typename LindstromTurkImpl<CD>::OptionalBoundary LindstromTurkImpl<CD>::Extract_boundary()
{
// Since p_q is a boundary edge, one of the previous edges (ccw or cw) is the previous boundary edge
// Likewise, one of the next edges (ccw or cw) is the next boundary edge.
edge_descriptor p_pt = next_edge_ccw(mP_Q,mSurface);
edge_descriptor p_pb = next_edge_cw (mP_Q,mSurface);
edge_descriptor q_qt = next_edge_cw (mQ_P,mSurface);
edge_descriptor q_qb = next_edge_ccw(mQ_P,mSurface);
edge_descriptor border_1 = mP_Q;
edge_descriptor border_0 = is_undirected_edge_a_border(p_pt) ? p_pt : p_pb ;
edge_descriptor border_2 = is_undirected_edge_a_border(q_qt) ? q_qt : q_qb ;
CGAL_assertion(is_undirected_edge_a_border(border_0));
CGAL_assertion(is_undirected_edge_a_border(border_2));
// opposite(border0)->border1->border2 is the local boundary
vertex_descriptor ov = target(border_0,mSurface);
vertex_descriptor rv = target(border_2,mSurface);
// o->p->q->r is the local boundary
Point o = get_point(ov);
Point p = get_point(mP);
Point q = get_point(mQ);
Point r = get_point(rv);
//
// The boundary cached contains vectors instead of points
//
CVector op = toCVector(p - o) ;
CVector opN = Point_cross_product(p,o);
CVector pq = toCVector(q - p) ;
CVector pqN = Point_cross_product(q,p);
CVector qr = toCVector(r - q) ;
CVector qrN = Point_cross_product(r,q);
return OptionalBoundary(Boundary(op,opN,pq,pqN,qr,qrN)) ;
}
//
// Calculates the normal of the triangle (v0,v1,v2) (both vector and its length as (v0xv1).v2)
//
template<class CD>
typename LindstromTurkImpl<CD>::Triangle LindstromTurkImpl<CD>::Get_triangle( vertex_descriptor const& v0
, vertex_descriptor const& v1
, vertex_descriptor const& v2
)
{
Point p0 = get_point(v0);
Point p1 = get_point(v1);
Point p2 = get_point(v2);
CVector v01 = toCVector(p1 - p0) ;
CVector v02 = toCVector(p2 - p0) ;
CVector lNormalV = cross_product(v01,v02);
FT lNormalL = Point_cross_product(p0,p1) * toCVector(p2-ORIGIN);
return Triangle(lNormalV,lNormalL);
}
//
// If (v0,v1,v2) is a finite triangular facet of the mesh, that is, NONE of these vertices are boundary vertices,
// the triangle (properly oriented) is added to rTriangles.
// The triangle is encoded as its normal, calculated using the actual facet orientation [(v0,v1,v2) or (v0,v2,v1)]
//
template<class CD>
void LindstromTurkImpl<CD>::Extract_triangle( vertex_descriptor const& v0
, vertex_descriptor const& v1
, vertex_descriptor const& v2
, edge_descriptor const& e02
, Triangles& rTriangles
)
{
// The 3 vertices are obtained by circulating ccw around v0, that is, e02 = next_ccw(e01).
// Since these vertices are NOT obtained by circulating the face, the actual triangle orientation is unspecified.
// If target(next_edge(v0))==v1 then the triangle is oriented v0->v2->v1; otherwise is oriented v0->v1->v2 ;
if ( target(next_edge(e02,mSurface),mSurface) == v1 )
{
// The triangle is oriented v0->v2->v1.
// In this case e02 is an edge of the facet.
// If this facet edge is a border edge then this triangle is not in the mesh .
if ( !is_border(e02) )
rTriangles.push_back(Get_triangle(v0,v2,v1) ) ;
}
else
{
// The triangle is oriented v0->v1->v2.
// In this case, e20 and not e02, is an edge of the facet.
// If this facet edge is a border edge then this triangle is not in the mesh .
if ( !is_border(opposite_edge(e02,mSurface)) )
rTriangles.push_back(Get_triangle(v0,v1,v2) ) ;
}
}
//
// Extract all triangles (its normals) and vertices (the link) around the collpasing edge p_q
//
template<class CD>
void LindstromTurkImpl<CD>::Extract_triangles_and_link( Triangles& rTriangles, Link& rLink )
{
//
// Extract around mP CCW
//
vertex_descriptor v0 = mP;
vertex_descriptor v1 = mQ;
edge_descriptor e02 = mP_Q;
do
{
e02 = next_edge_ccw(e02,mSurface);
vertex_descriptor v2 = target(e02,mSurface);
if ( v2 != mQ )
rLink.push_back(v2) ;
Extract_triangle(v0,v1,v2,e02,rTriangles);
v1 = v2 ;
}
while ( e02 != mP_Q ) ;
//
// Extract around mQ CCW
//
vertex_descriptor vt = target(next_edge_cw(mQ_P,mSurface),mSurface); // This was added to the link while circulating mP
v0 = mQ;
e02 = next_edge_ccw(mQ_P,mSurface);
v1 = target(e02,mSurface); // This was added to the link while circulating around mP
e02 = next_edge_ccw(e02,mSurface);
do
{
vertex_descriptor v2 = target(e02,mSurface);
if ( v2 != vt )
rLink.push_back(v2) ;
Extract_triangle(v0,v1,v2,e02,rTriangles);
v1 = v2 ;
e02 = next_edge_cw(e02,mSurface);
}
while ( e02 != mQ_P ) ;
}
template<class CD>
void LindstromTurkImpl<CD>::Add_boundary_preservation_constrians( OptionalBoundary const& aBdry )
{
CVector e1 = aBdry->op + aBdry->pq + aBdry->qr ;
CVector e3 = aBdry->opN + aBdry->pqN + aBdry->qrN ;
CMatrix H = LT_product(e1);
CVector c = cross_product(e1,e3);
mConstrians.Add_from_gradient(H,c);
}
template<class CD>
void LindstromTurkImpl<CD>::Add_volume_preservation_constrians( Triangles const& aTriangles )
{
CVector lSumV = NULL_VECTOR ;
FT lSumL(0) ;
for( typename Triangles::const_iterator it = aTriangles.begin(), eit = aTriangles.end() ; it != eit ; ++it )
{
lSumV = lSumV + it->NormalV ;
lSumL = lSumL + it->NormalL ;
}
mConstrians.Add_if_alpha_compatible(lSumV,lSumL);
}
template<class CD>
void LindstromTurkImpl<CD>::Add_boundary_and_volume_optimization_constrians( OptionalBoundary const& aBdry, Triangles const& aTriangles )
{
CMatrix H = NULL_MATRIX ;
CVector c = NULL_VECTOR ;
//
// Volume optimization
//
for( typename Triangles::const_iterator it = aTriangles.begin(), eit = aTriangles.end() ; it != eit ; ++it )
{
Triangle const& lTri = *it ;
H += direct_product(lTri.NormalV,lTri.NormalV) ;
c = c + ( lTri.NormalL * lTri.NormalV ) ;
}
if ( aBdry )
{
//
// Boundary optimization
//
CMatrix Hb = LT_product(aBdry->op) + LT_product(aBdry->pq) + LT_product(aBdry->qr) ;
CVector cb = cross_product(aBdry->op,aBdry->opN) + cross_product(aBdry->pq,aBdry->pqN) + cross_product(aBdry->qr,aBdry->qrN);
//
// Weighted average
//
FT lBoundaryWeight = ( FT(9) * mParams.BoundaryWeight * squared_distance ( get_point(mP), get_point(mQ) ) ) / FT(10) ;
H *= mParams.VolumeWeight ;
c = c * mParams.VolumeWeight ;
H += lBoundaryWeight * Hb ;
c = c + ( lBoundaryWeight * cb ) ;
}
mConstrians.Add_from_gradient(H,c);
}
template<class CD>
void LindstromTurkImpl<CD>::Add_shape_optimization_constrians( Link const& aLink )
{
FT s(aLink.size());
CMatrix H (s,0,0
,0,s,0
,0,0,s
);
CVector c = NULL_VECTOR ;
for( typename Link::const_iterator it = aLink.begin(), eit = aLink.end() ; it != eit ; ++it )
c = c + toCVector(ORIGIN - get_point(*it)) ;
mConstrians.Add_from_gradient(H,c);
}
template<class Vector>
Vector normalized_vector ( Vector const& c )
{
}
template<class CD>
void LindstromTurkImpl<CD>::Constrians::Add_if_alpha_compatible( CVector const& Ai, FT const& bi )
{
double slai = to_double(Ai*Ai) ;
if ( slai > 0.0 )
{
bool lAddIt = true ;
if ( n == 1 )
{
FT d01 = A.r0() * Ai ;
double sla0 = to_double(A.r0() * A.r0()) ;
double sd01 = to_double(d01 * d01) ;
if ( sd01 > ( sla0 * slai * squared_cos_alpha() ) )
lAddIt = false ;
}
else if ( n == 2 )
{
CVector N = cross_product(A.r0(),A.r1());
FT dc012 = N * Ai ;
double slc01 = to_double(N * N) ;
double sdc012 = to_double(dc012 * dc012);
if ( sdc012 <= slc01 * slai * squared_sin_alpha() )
lAddIt = false ;
}
if ( lAddIt )
{
switch ( n )
{
case 0 :
A.r0() = Ai ;
b = CVector(bi,b.y(),b.z());
break ;
case 1 :
A.r1() = Ai ;
b = CVector(b.x(),bi,b.z());
break ;
case 2 :
A.r2() = Ai ;
b = CVector(b.x(),b.y(),bi);
break ;
}
++ n ;
}
}
}
template<class V>
int index_of_max_component ( V const& v )
{
typedef typename Kernel_traits<V>::Kernel::FT FT ;
int i = 0 ;
FT max = v.x();
if ( max < v.y() )
{
max = v.y();
i = 1 ;
}
if ( max < v.z() )
{
max = v.z();
i = 2 ;
}
return i ;
}
template<class CD>
void LindstromTurkImpl<CD>::Constrians::Add_from_gradient ( CMatrix const& H, CVector const& c )
{
CGAL_precondition(n >= 0 && n<=2 );
switch(n)
{
case 0 :
Add_if_alpha_compatible(H.r0(),-c.x());
Add_if_alpha_compatible(H.r1(),-c.y());
Add_if_alpha_compatible(H.r2(),-c.z());
break;
case 1 :
{
CVector const& A0 = A.r0();
CVector A02( A0.x()*A0.x()
, A0.y()*A0.y()
, A0.z()*A0.z()
);
CVector Q0 ;
switch ( index_of_max_component(A02) )
{
case 0: Q0 = CVector(- A0.z()/A0.x(),0 ,1 ); break;
case 1: Q0 = CVector(0 ,- A0.z()/A0.y(),1 ); break;
case 2: Q0 = CVector(1 ,0 ,- A0.x()/A0.z()); break;
}
CVector Q1 = cross_product(A0,Q0);
CVector A1 = H * Q0 ;
CVector A2 = H * Q1 ;
FT b1 = - ( Q0 * c ) ;
FT b2 = - ( Q1 * c ) ;
Add_if_alpha_compatible(A1,b1);
Add_if_alpha_compatible(A2,b2);
}
break ;
case 2:
{
CVector Q = cross_product(A.r0(),A.r1());
CVector A2 = H * Q ;
FT b2 = - ( Q * c ) ;
Add_if_alpha_compatible(A2,b2);
}
break ;
}
}
} } // namespace Triangulated_surface_mesh::Simplification
CGAL_END_NAMESPACE
#endif // CGAL_SURFACE_MESH_SIMPLIFICATION_LINDSTROMTURK_IMPL_H //
// EOF //

View File

@ -10,8 +10,8 @@
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
// //
// $URL$ // $URL: $
// $Id$ // $Id: $
// //
// Author(s) : Fernando Cacciola <fernando_cacciola@ciudad.com.ar> // Author(s) : Fernando Cacciola <fernando_cacciola@ciudad.com.ar>
// //
@ -30,7 +30,6 @@ namespace Triangulated_surface_mesh { namespace Simplification
// -= cost property maps =- // -= cost property maps =-
// //
// Computes the cost of collapsing a vertex-pair. // Computes the cost of collapsing a vertex-pair.
// The key-type is a [vertex,vertex,is_edge] tuple and the value_type is optional<FT>.
// The map can return an empty optional if the cost is too-high or uncomputable (due to overflow for example). // The map can return an empty optional if the cost is too-high or uncomputable (due to overflow for example).
// //
//******************************************************************************************************************* //*******************************************************************************************************************
@ -38,34 +37,23 @@ namespace Triangulated_surface_mesh { namespace Simplification
// //
// Edge-length cost: the square distance between the collapsing vertices. // Edge-length cost: the square distance between the collapsing vertices.
// //
template<class TSM_> template<class CollapseData_>
class Edge_length_cost_map class Edge_length_cost
: public boost::put_get_helper< boost::optional< typename Surface_geometric_traits<TSM_>::FT >, Edge_length_cost_map<TSM_> >
{ {
public: public:
typedef TSM_ TSM ; typedef CollapseData_ CollapseData ;
typedef typename boost::graph_traits<TSM>::vertex_descriptor vertex_descriptor ; typedef typename CollapseData::FT FT ;
typedef typename Surface_geometric_traits<TSM>::FT FT ;
public: public:
typedef boost::readable_property_map_tag category; typedef optional<FT> result_type;
typedef boost::optional<FT> value_type; result_type operator()( CollapseData const& data ) const
{
typedef value_type reference ; return result_type(squared_distance(data.p()->point(), data.q()->point()));
}
typedef boost::tuple<vertex_descriptor,vertex_descriptor,bool,TSM*> key_type;
value_type operator[](key_type const& e) const
{
vertex_descriptor p, q ;
boost::tie(p,q,boost::tuples::ignore,boost::tuples::ignore) = e ;
return value_type(CGAL::squared_distance(p->point(), q->point()));
}
}; };

View File

@ -0,0 +1,28 @@
// Copyright (c) 2005, 2006 Fernando Luis Cacciola Carballal. All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// 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) : Fernando Cacciola <fernando_cacciola@ciudad.com.ar>
//
#ifndef CGAL_SURFACE_MESH_SIMPLIFICATION_LINDSTROMTURK_H
#define CGAL_SURFACE_MESH_SIMPLIFICATION_LINDSTROMTURK_H 1
#include <CGAL/Surface_mesh_simplification/Policies/LindstromTurk_collapse_data.h>
#include <CGAL/Surface_mesh_simplification/Policies/LindstromTurk_construct_collapse_data.h>
#include <CGAL/Surface_mesh_simplification/Policies/LindstromTurk_cost.h>
#include <CGAL/Surface_mesh_simplification/Policies/LindstromTurk_vertex_placement.h>
#endif // CGAL_SURFACE_MESH_SIMPLIFICATION_LINDSTROMTURK_H //
// EOF //

View File

@ -0,0 +1,92 @@
// Copyright (c) 2005, 2006 Fernando Luis Cacciola Carballal. All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// 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) : Fernando Cacciola <fernando_cacciola@ciudad.com.ar>
//
#ifndef CGAL_SURFACE_MESH_SIMPLIFICATION_LINDSTROMTURK_COLLAPSE_DATA_H
#define CGAL_SURFACE_MESH_SIMPLIFICATION_LINDSTROMTURK_COLLAPSE_DATA_H 1
#include <CGAL/Surface_mesh_simplification/TSMS_common.h>
#include <CGAL/Surface_mesh_simplification/Policies/Minimal_collapse_data.h>
CGAL_BEGIN_NAMESPACE
namespace Triangulated_surface_mesh { namespace Simplification
{
template<class TSM_>
class LindstromTurk_collapse_data : public Minimal_collapse_data<TSM_>
{
public:
typedef Minimal_collapse_data<TSM_> Base ;
typedef typename Base::TSM TSM ;
typedef typename Base::vertex_descriptor vertex_descriptor;
typedef typename Base::edge_descriptor edge_descriptor;
typedef typename Base::size_type size_type ;
typedef typename Base::Point_3 Point_3 ;
typedef typename Base::FT FT ;
typedef optional<Point_3> Optional_point_3 ;
typedef optional<FT> Optional_FT ;
struct Params
{
Params( FT const& aVolumeWeight, FT const& aBoundaryWeight, FT const& aShapeWeight )
:
VolumeWeight (aVolumeWeight)
,BoundaryWeight(aBoundaryWeight)
,ShapeWeight (aShapeWeight)
{}
FT VolumeWeight ;
FT BoundaryWeight ;
FT ShapeWeight ;
};
public :
LindstromTurk_collapse_data ( vertex_descriptor const& aP
, vertex_descriptor const& aQ
, edge_descriptor const& aEdge
, TSM& aSurface
, Optional_FT const& aCost
, Optional_point_3 const& aVertexPoint
)
:
Base(aP,aQ,aEdge,aSurface)
,mCost (aCost)
,mVertexPoint (aVertexPoint)
{}
Optional_FT cost () const { return mCost ; }
Optional_point_3 vertex_point() const { return mVertexPoint ; }
private:
Optional_FT mCost ;
Optional_point_3 mVertexPoint ;
};
} } // namespace Triangulated_surface_mesh::Simplification
CGAL_END_NAMESPACE
#endif // CGAL_SURFACE_MESH_SIMPLIFICATION_LINDSTROMTURK_COLLAPSE_DATA_H //
// EOF //

View File

@ -0,0 +1,77 @@
// Copyright (c) 2005, 2006 Fernando Luis Cacciola Carballal. All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// 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) : Fernando Cacciola <fernando_cacciola@ciudad.com.ar>
//
#ifndef CGAL_SURFACE_MESH_SIMPLIFICATION_LINDSTROMTURK_CONSTRUCT_COLLAPSE_DATA_H
#define CGAL_SURFACE_MESH_SIMPLIFICATION_LINDSTROMTURK_CONSTRUCT_COLLAPSE_DATA_H 1
#include <CGAL/Surface_mesh_simplification/TSMS_common.h>
#include <CGAL/Surface_mesh_simplification/Policies/LindstromTurk_collapse_data.h>
#include <CGAL/Surface_mesh_simplification/Policies/Detail/Lindstrom_Turk.h>
CGAL_BEGIN_NAMESPACE
namespace Triangulated_surface_mesh { namespace Simplification
{
template<class Collapse_data_>
class Construct_LindstromTurk_collapse_data
{
public:
typedef Collapse_data_ Collapse_data ;
typedef typename Collapse_data::TSM TSM ;
typedef typename Collapse_data::vertex_descriptor vertex_descriptor ;
typedef typename Collapse_data::edge_descriptor edge_descriptor ;
typedef typename Collapse_data::Params Params ;
typedef shared_ptr<Collapse_data> result_type ;
public :
result_type operator() ( vertex_descriptor const& aP
, vertex_descriptor const& aQ
, edge_descriptor const& aEdge
, TSM& aSurface
, Params const* aParams
) const
{
result_type r ;
CGAL_assertion(aParams);
if ( handle_assigned(aEdge) )
{
LindstromTurkImpl<Collapse_data> impl(*aParams,aP,aQ,aEdge,opposite_edge(aEdge,aSurface),aSurface);
r = impl.result() ;
}
return r ;
}
};
} } // namespace Triangulated_surface_mesh::Simplification
CGAL_END_NAMESPACE
#endif // CGAL_SURFACE_MESH_SIMPLIFICATION_LINDSTROMTURK_CONSTRUCT_COLLAPSE_DATA_H //
// EOF //

View File

@ -0,0 +1,52 @@
// Copyright (c) 2005, 2006 Fernando Luis Cacciola Carballal. All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// 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) : Fernando Cacciola <fernando_cacciola@ciudad.com.ar>
//
#ifndef CGAL_SURFACE_MESH_SIMPLIFICATION_LINDSTROMTURK_COST_H
#define CGAL_SURFACE_MESH_SIMPLIFICATION_LINDSTROMTURK_COST_H 1
#include <CGAL/Surface_mesh_simplification/TSMS_common.h>
#include <CGAL/Surface_mesh_simplification/Policies/LindstromTurk_collapse_data.h>
CGAL_BEGIN_NAMESPACE
namespace Triangulated_surface_mesh { namespace Simplification
{
template<class Collapse_data_>
class LindstromTurk_cost
{
public:
typedef Collapse_data_ Collapse_data ;
typedef typename Collapse_data::Optional_FT result_type ;
public:
result_type operator()( Collapse_data const& data ) const
{
return data.cost();
}
};
} } // namespace Triangulated_surface_mesh::Simplification
CGAL_END_NAMESPACE
#endif // CGAL_SURFACE_MESH_SIMPLIFICATION_LINDSTROMTURK_COST_H //
// EOF //

View File

@ -1,73 +0,0 @@
// Copyright (c) 2005, 2006 Fernando Luis Cacciola Carballal. All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// 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) : Fernando Cacciola <fernando_cacciola@ciudad.com.ar>
//
#ifndef CGAL_SURFACE_MESH_SIMPLIFICATION_LINDSTROMTURK_SELECTION_MAP_H
#define CGAL_SURFACE_MESH_SIMPLIFICATION_LINDSTROMTURK_SELECTION_MAP_H 1
#include <CGAL/Surface_mesh_simplification/TSMS_common.h>
CGAL_BEGIN_NAMESPACE
namespace Triangulated_surface_mesh { namespace Simplification
{
//*******************************************************************************************************************
// -= vertex-pair selection property maps =-
//
// Determines up-front whether a pair must be considered for collapsation
//
//*******************************************************************************************************************
//
// Lindstrom-Turk selection: only vertex-pairs which are edges of the triangulated surface mesh
//
template<class TSM_>
class Lindstrom_Turk_selection : public boost::put_get_helper< bool, Lindstrom_Turk_selection<TSM_> >
{
public:
typedef TSM_ TSM ;
typedef typename boost::graph_traits<TSM>::vertex_descriptor vertex_descriptor ;
public:
typedef boost::readable_property_map_tag category;
typedef bool value_type;
typedef value_type reference ;
typedef boost::tuple<vertex_descriptor,vertex_descriptor,bool,TSM*> key_type;
value_type operator[](key_type const& e) const
{
bool lIsEdge ;
boost::tie(boost::tuples::ignore,boost::tuples::ignore,lIsEdge,boost::tuples::ignore) = e ;
return lIsEdge ;
}
};
} } // namespace Triangulated_surface_mesh::Simplification
CGAL_END_NAMESPACE
#endif // CGAL_SURFACE_MESH_SIMPLIFICATION_LINDSTROMTURK_SELECTION_MAP_H //
// EOF //

View File

@ -0,0 +1,54 @@
// Copyright (c) 2005, 2006 Fernando Luis Cacciola Carballal. All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// 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) : Fernando Cacciola <fernando_cacciola@ciudad.com.ar>
//
#ifndef CGAL_SURFACE_MESH_SIMPLIFICATION_LINDSTROMTURK_VERTEX_PLACEMENT_H
#define CGAL_SURFACE_MESH_SIMPLIFICATION_LINDSTROMTURK_VERTEX_PLACEMENT_H 1
#include <CGAL/Surface_mesh_simplification/TSMS_common.h>
#include <CGAL/Surface_mesh_simplification/Policies/LindstromTurk_collapse_data.h>
CGAL_BEGIN_NAMESPACE
namespace Triangulated_surface_mesh { namespace Simplification
{
template<class Collapse_data_>
class LindstromTurk_vertex_placement
{
public:
typedef Collapse_data_ Collapse_data ;
typedef typename Collapse_data::Optional_point_3 result_type ;
public:
result_type operator()( Collapse_data const& data ) const
{
return data.vertex_point();
}
};
} } // namespace Triangulated_surface_mesh::Simplification
CGAL_END_NAMESPACE
#endif // CGAL_SURFACE_MESH_SIMPLIFICATION_LINDSTROMTURK_VERTEX_PLACEMENT_H //
// EOF //

View File

@ -30,7 +30,6 @@ namespace Triangulated_surface_mesh { namespace Simplification
// -= new vertex placement functor =- // -= new vertex placement functor =-
// //
// Constructs the point of location of the new vertex that replaces a collapsing vertex-pair. // Constructs the point of location of the new vertex that replaces a collapsing vertex-pair.
// The arguments are (vertex,vertex,is_edge) and the result is optional<Point_3>.
// The functor can return an empty optional if the point cannot be placed in a way that satisfies the deeesired constriants. // The functor can return an empty optional if the point cannot be placed in a way that satisfies the deeesired constriants.
// //
//******************************************************************************************************************* //*******************************************************************************************************************
@ -38,29 +37,23 @@ namespace Triangulated_surface_mesh { namespace Simplification
// //
// Mid-point placement // Mid-point placement
// //
template<class TSM_> template<class Collapse_data_>
class Midpoint_vertex_placement class Midpoint_vertex_placement
{ {
public: public:
typedef TSM_ TSM ; typedef Collapse_data_ Collapse_data ;
typedef typename boost::graph_traits<TSM>::vertex_descriptor vertex_descriptor ; typedef typename Collapse_data::Point_3 Point_3 ;
typedef typename Surface_geometric_traits<TSM>::Point_3 Point_3 ; typedef optional<Point_3> result_type ;
public: public:
typedef boost::optional<Point_3> result_type ; result_type operator()( Collapse_data const& data ) const
{
result_type operator()( vertex_descriptor p return result_type(midpoint(data.p()->point(), data.q()->point()));
, vertex_descriptor q }
, bool //aIsEdge
, TSM& //aSurface
) const
{
return result_type(CGAL::midpoint(p->point(), q->point()));
}
}; };

View File

@ -0,0 +1,79 @@
// Copyright (c) 2006 Fernando Luis Cacciola Carballal. All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// 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) : Fernando Cacciola <fernando_cacciola@ciudad.com.ar>
//
#ifndef CGAL_SURFACE_MESH_SIMPLIFICATION_MINIMAL_COLLAPSE_DATA_H
#define CGAL_SURFACE_MESH_SIMPLIFICATION_MINIMAL_COLLAPSE_DATA_H
#include <CGAL/Surface_mesh_simplification/TSMS_common.h>
CGAL_BEGIN_NAMESPACE
namespace Triangulated_surface_mesh { namespace Simplification
{
template<class TSM_>
class Minimal_collapse_data
{
public:
typedef TSM_ TSM ;
typedef typename boost::graph_traits<TSM>::vertex_descriptor vertex_descriptor ;
typedef typename boost::graph_traits<TSM>::edge_descriptor edge_descriptor ;
typedef typename boost::graph_traits<TSM>::edges_size_type size_type ;
typedef typename Surface_geometric_traits<TSM>::Point_3 Point_3 ;
typedef typename Surface_geometric_traits<TSM>::FT FT ;
public :
Minimal_collapse_data ( vertex_descriptor const& aP
, vertex_descriptor const& aQ
, edge_descriptor const& aEdge
, TSM& aSurface
)
:
mP (aP)
,mQ (aQ)
,mEdge (aEdge)
,mSurface(addressof(aSurface))
{}
virtual ~Minimal_collapse_data() {}
vertex_descriptor const& p() const { return mP ; }
vertex_descriptor const& q() const { return mQ ; }
edge_descriptor const& edge() const { return mEdge ; }
TSM& surface() const { return *mSurface ; }
protected:
vertex_descriptor mP ;
vertex_descriptor mQ ;
edge_descriptor mEdge ;
TSM* mSurface ;
};
} } // namespace Triangulated_surface_mesh::Simplification
CGAL_END_NAMESPACE
#endif // CGAL_SURFACE_MESH_SIMPLIFICATION_MINIMAL_COLLAPSE_DATA_H
// EOF //

View File

@ -20,10 +20,9 @@
#include <functional> #include <functional>
#include <utility> #include <utility>
#include <vector>
#include <boost/graph/graph_traits.hpp> #include <boost/shared_ptr.hpp>
#include <boost/graph/properties.hpp>
#include <boost/property_map.hpp>
#include <boost/optional/optional.hpp> #include <boost/optional/optional.hpp>
#include <boost/none.hpp> #include <boost/none.hpp>
#include <boost/tuple/tuple.hpp> #include <boost/tuple/tuple.hpp>
@ -33,6 +32,26 @@ CGAL_BEGIN_NAMESPACE
namespace Triangulated_surface_mesh { namespace Simplification namespace Triangulated_surface_mesh { namespace Simplification
{ {
using boost::num_edges ;
using boost::num_vertices ;
using boost::edges ;
using boost::out_edges ;
using boost::in_edges ;
using boost::source ;
using boost::target ;
using boost::edge_is_border_t ;
using boost::vertex_point_t ;
using boost::shared_ptr ;
using boost::optional ;
using boost::none ;
using boost::put_get_helper ;
using boost::get ;
using boost::put ;
using boost::addressof ;
using namespace boost::tuples ;
template<class Handle> template<class Handle>
inline bool handle_assigned( Handle h ) { Handle null ; return h != null ; } inline bool handle_assigned( Handle h ) { Handle null ; return h != null ; }
@ -56,6 +75,7 @@ struct Surface_geometric_traits
typedef typename Kernel_traits<Point_3>::Kernel Kernel ; typedef typename Kernel_traits<Point_3>::Kernel Kernel ;
typedef typename Kernel::FT FT ; typedef typename Kernel::FT FT ;
} ; } ;
} } // namespace Triangulated_surface_mesh::Simplification } } // namespace Triangulated_surface_mesh::Simplification

View File

@ -15,8 +15,8 @@
// //
// Author(s) : Fernando Cacciola <fernando_cacciola@ciudad.com.ar> // Author(s) : Fernando Cacciola <fernando_cacciola@ciudad.com.ar>
// //
#ifndef CGAL_SURFACE_MESH_SIMPLIFICATION_VERTEX_PAIR_COLLAPSE_IMPL_H #ifndef CGAL_SURFACE_MESH_SIMPLIFICATION__VERTEX_PAIR_COLLAPSE_H
#define CGAL_SURFACE_MESH_SIMPLIFICATION_VERTEX_PAIR_COLLAPSE_IMPL_H 1 #define CGAL_SURFACE_MESH_SIMPLIFICATION__VERTEX_PAIR_COLLAPSE_H 1
#include <vector> #include <vector>
@ -41,24 +41,25 @@ namespace Triangulated_surface_mesh { namespace Simplification
// Implementation of the vertex-pair collapse triangulated surface mesh simplification algorithm // Implementation of the vertex-pair collapse triangulated surface mesh simplification algorithm
// //
template<class TSM_ template<class TSM_
,class SelectMap_ ,class GetCollapseData_
,class CostMap_ ,class GetCost_
,class VertexPlacement_ ,class GetVertexPoint_
,class StopPred_ ,class ShouldStop_
> >
class VertexPairCollapse class VertexPairCollapse
{ {
public: public:
typedef TSM_ TSM ; typedef TSM_ TSM ;
typedef SelectMap_ SelectMap ; typedef GetCollapseData_ GetCollapseData ;
typedef CostMap_ CostMap ; typedef GetCost_ GetCost ;
typedef VertexPlacement_ VertexPlacement ; typedef GetVertexPoint_ GetVertexPoint ;
typedef StopPred_ StopPred ; typedef ShouldStop_ ShouldStop ;
typedef VertexPairCollapse Self ; typedef VertexPairCollapse Self ;
typedef boost::graph_traits<TSM> GraphTraits ; typedef boost::graph_traits <TSM> GraphTraits ;
typedef boost::undirected_graph_traits<TSM> UndirectedGraphTraits ;
typedef typename GraphTraits::vertex_descriptor vertex_descriptor ; typedef typename GraphTraits::vertex_descriptor vertex_descriptor ;
typedef typename GraphTraits::vertex_iterator vertex_iterator ; typedef typename GraphTraits::vertex_iterator vertex_iterator ;
@ -69,9 +70,15 @@ public:
typedef typename GraphTraits::traversal_category traversal_category ; typedef typename GraphTraits::traversal_category traversal_category ;
typedef typename GraphTraits::edges_size_type size_type ; typedef typename GraphTraits::edges_size_type size_type ;
typedef typename boost::property_traits<CostMap>::value_type optional_cost_type ; typedef typename UndirectedGraphTraits::edge_iterator undirected_edge_iterator ;
typedef typename VertexPlacement::result_type optional_vertex_point_type ; typedef typename GetCollapseData::Params GetCollapseDataParams ;
typedef typename GetCollapseData::Collapse_data Collapse_data ;
typedef typename GetCollapseData::result_type Collapse_data_ptr ;
typedef typename GetCost ::result_type Optional_cost_type ;
typedef typename GetVertexPoint::result_type Optional_vertex_point_type ;
typedef Surface_geometric_traits<TSM> Traits ; typedef Surface_geometric_traits<TSM> Traits ;
@ -79,14 +86,14 @@ public:
class vertex_pair ; class vertex_pair ;
typedef boost::shared_ptr<vertex_pair> vertex_pair_ptr ; typedef shared_ptr<vertex_pair> vertex_pair_ptr ;
typedef Modifiable_priority_queue<vertex_pair_ptr> PQ ; typedef Modifiable_priority_queue<vertex_pair_ptr> PQ ;
typedef typename PQ::iterator pq_handle ; typedef typename PQ::iterator pq_handle ;
// The algoritm is centered around vertex-pairs, encapsulated in this type. // The algoritm is centered around vertex-pairs, encapsulated in this type.
// For each pair there is a cost value provided by the external CostMap. // For each pair there is a cost value provided by the external GetCost functor.
// Vertex-pairs are stored in a priority queue based on their cost. // Vertex-pairs are stored in a priority queue based on their cost.
// //
// Each edge in the TSM contributes one vertex_pair. // Each edge in the TSM contributes one vertex_pair.
@ -102,19 +109,13 @@ public:
public : public :
vertex_pair( size_type aID vertex_pair( size_type aID
, vertex_descriptor const& aP , Collapse_data_ptr const& aData
, vertex_descriptor const& aQ , GetCost const& aGet_cost
, edge_descriptor const& aEdge
, TSM* aSurface
, CostMap const* aCost_map
) )
: :
mID(aID) mID(aID)
, mP(aP) , mData(aData)
, mQ(aQ) , Get_cost(addressof(aGet_cost))
, mEdge(aEdge)
, mSurface(aSurface)
, Cost_map(aCost_map)
, mCostStored(false) , mCostStored(false)
, mIsFixed(false) , mIsFixed(false)
, mMark(0) , mMark(0)
@ -123,31 +124,32 @@ public:
size_type id() const { return mID ; } size_type id() const { return mID ; }
// The cost of collapsing a vertex-pair is cached in this record. // The cost of collapsing a vertex-pair is cached in this record.
// When calling cost() for the first time, the cached cost is taken from the external CostMap. // When calling cost() for the first time, the cached cost is taken from the external GetCost functor.
// Subsequent calls to cost() returns the same cached cost, that is, CostMap[] IS NOT called each time. // Subsequent calls to cost() returns the same cached cost, that is, GetCost() IS NOT called each time.
// //
// Such a cache cost is an optional<> value. This is because the CostMap can return "none" for too high or incomputable costs. // Such a cache cost is an optional<> value. This is because the GetCost can return "none" for too high or incomputable costs.
// Therefore, even if the cost is cached, it might be "absent" (that is, == boost::none) // Therefore, even if the cost is cached, it might be "absent" (that is, == boost::none)
// //
// OTOH, the algorithm can invalidate the cached cost of any given pair. // OTOH, the algorithm can invalidate the cached cost of any given pair.
// If invalidate_cost() is called, the next call to cost() will take it again from the external CostMap. // If invalidate_cost() is called, the next call to cost() will take it again from the external GetCost.
// NOTE: Whether the cost is cached or not is independent from whether it is absent or none. // NOTE: Whether the cost is cached or not is independent from whether it is absent or none.
// The former is controlled by the algorithm by explicitely calling InvalidateCost() while the later is defined by the CostMap // The former is controlled by the algorithm by explicitely calling InvalidateCost() while the later is defined by the GetCost
// which can retiurn boost::none for incomputable or logically invalid costs. // which can retiurn boost::none for incomputable or logically invalid costs.
// //
optional_cost_type cost() const { return UpdateCost() ; } Optional_cost_type cost() const { return UpdateCost() ; }
void invalidate_cost() { mCostStored = false ; } void reset_data( Collapse_data_ptr const& aData ) { mData = aData ; mCostStored = false ; }
vertex_descriptor p() const { return mP ; } Collapse_data_ptr data () const { return mData ; }
vertex_descriptor q() const { return mQ ; } vertex_descriptor const& p () const { return mData->p() ; }
vertex_descriptor const& q () const { return mData->q() ; }
edge_descriptor edge() const { return mEdge ; } edge_descriptor const& edge () const { return mData->edge() ; }
TSM& surface() const { return mData->surface() ; }
bool is_edge() const bool is_edge() const
{ {
edge_descriptor null ; edge_descriptor null ;
return mEdge != null ; return edge() != null ;
} }
// A pair is fixed if it cannot be collpased. // A pair is fixed if it cannot be collpased.
@ -165,35 +167,23 @@ public:
void reset_PQ_handle() { mPQHandle = null_PQ_handle() ; } void reset_PQ_handle() { mPQHandle = null_PQ_handle() ; }
void update_vertex ( vertex_descriptor oldv, vertex_descriptor newv ) friend bool operator< ( shared_ptr<vertex_pair> const& a, shared_ptr<vertex_pair> const& b )
{
CGAL_assertion( mP == oldv || mQ == oldv );
CGAL_assertion( oldv != newv );
if ( mP == oldv )
mP = newv ;
else mQ = newv ;
invalidate_cost();
}
friend bool operator< ( boost::shared_ptr<vertex_pair> const& a, boost::shared_ptr<vertex_pair> const& b )
{ {
// NOTE: cost() is an optional<> value. // NOTE: cost() is an optional<> value.
// Absent optionals are ordered first; that is, "none < T" and "T > none" for any defined T != none. // Absent optionals are ordered first; that is, "none < T" and "T > none" for any defined T != none.
// In consequence, vertex-pairs with undefined costs will be promoted to the top of the priority queue and poped out first. // In consequence, vertex-pairs with undefined costs will be promoted to the top of the priority queue and poped out first.
return a->cost() < b->cost() ; return a->cost() < b->cost() ;
} }
friend bool operator== ( boost::shared_ptr<vertex_pair> const& a, boost::shared_ptr<vertex_pair> const& b ) friend bool operator== ( shared_ptr<vertex_pair> const& a, shared_ptr<vertex_pair> const& b )
{ {
return a->cost() == b->cost() ; return a->cost() == b->cost() ;
} }
#ifdef CGAL_SURFACE_SIMPLIFICATION_ENABLE_TRACE #ifdef CGAL_SURFACE_SIMPLIFICATION_ENABLE_TRACE
bool is_p_in_surface () const { return handle_exists(mSurface->vertices_begin(),mSurface->vertices_end(),p()) ; } bool is_p_in_surface () const { return handle_exists(surface().vertices_begin (),surface().vertices_end(),p()) ; }
bool is_q_in_surface () const { return handle_exists(mSurface->vertices_begin(),mSurface->vertices_end(),q()) ; } bool is_q_in_surface () const { return handle_exists(surface().vertices_begin (),surface().vertices_end(),q()) ; }
bool is_edge_in_surface() const { return handle_exists(mSurface->halfedges_begin(),mSurface->halfedges_end(),edge()) ; } bool is_edge_in_surface() const { return handle_exists(surface().halfedges_begin(),surface().halfedges_end(),edge()) ; }
bool is_valid() const { return is_p_in_surface() && is_q_in_surface() && is_edge_in_surface() ; } bool is_valid() const { return is_p_in_surface() && is_q_in_surface() && is_edge_in_surface() ; }
@ -226,11 +216,11 @@ public:
private: private:
// Caches the cost if not currently cached, and returns it. // Caches the cost if not currently cached, and returns it.
optional_cost_type UpdateCost() const Optional_cost_type UpdateCost() const
{ {
if ( !mCostStored ) if ( !mCostStored )
{ {
mCost = boost::get(*Cost_map, boost::make_tuple(p(),q(),is_edge(),mSurface)) ; mCost = (*Get_cost)(*mData);
mCostStored = true ; mCostStored = true ;
} }
return mCost ; return mCost ;
@ -240,15 +230,12 @@ public:
private: private:
size_type mID ; size_type mID ;
vertex_descriptor mP ; Collapse_data_ptr mData ;
vertex_descriptor mQ ; GetCost const* Get_cost ;
edge_descriptor mEdge ;
TSM* mSurface ;
CostMap const* Cost_map ;
mutable bool mCostStored ; mutable bool mCostStored ;
mutable optional_cost_type mCost ; mutable Optional_cost_type mCost ;
bool mIsFixed ; bool mIsFixed ;
pq_handle mPQHandle ; pq_handle mPQHandle ;
@ -265,12 +252,13 @@ public:
public: public:
VertexPairCollapse( TSM& aSurface VertexPairCollapse( TSM& aSurface
, SelectMap const& aSelectMap , GetCollapseData const& aGetCollapseData
, CostMap const& aCostMap , GetCollapseDataParams const* aGetCollapseDataParams
, VertexPlacement const& aVertexPlacement , GetCost const& aGetCost
, StopPred const& aStopPred , GetVertexPoint const& aGetVertexPoint
, bool aIncludeNonEdgePairs , ShouldStop const& aShouldStop
, bool aIncludeNonEdgePairs
) ; ) ;
int run() ; int run() ;
@ -291,7 +279,7 @@ private:
void set_pair ( edge_descriptor const& e, vertex_pair_ptr aPair ) void set_pair ( edge_descriptor const& e, vertex_pair_ptr aPair )
{ {
edge_descriptor o = boost::opposite_edge(e,mSurface) ; edge_descriptor o = opposite_edge(e,mSurface) ;
mEdgesToPairsMap[e] = aPair ; mEdgesToPairsMap[e] = aPair ;
mEdgesToPairsMap[o] = aPair ; mEdgesToPairsMap[o] = aPair ;
@ -339,16 +327,19 @@ private:
private: private:
TSM& mSurface ; TSM& mSurface ;
GetCollapseDataParams const* mGetCollapseDataParams ;
SelectMap const& Select_map ; GetCollapseData const& Get_collapse_data;
CostMap const& Cost_map ; GetCost const& Get_cost ;
VertexPlacement const& construct_new_vertex_point ; GetVertexPoint const& Get_vertex_point ;
StopPred const& stop_simplification ; ShouldStop const& Should_stop ;
Collapse_triangulation_edge<TSM> collapse_triangulation_edge ;
bool mIncludeNonEdgePairs; bool mIncludeNonEdgePairs;
private:
Collapse_triangulation_edge<TSM> Collapse_triangulation_edge ;
edges_2_pairs_map mEdgesToPairsMap ; edges_2_pairs_map mEdgesToPairsMap ;
PQ mPQ ; PQ mPQ ;
@ -361,10 +352,8 @@ private:
CGAL_END_NAMESPACE CGAL_END_NAMESPACE
#ifdef CGAL_CFG_NO_AUTOMATIC_TEMPLATE_INCLUSION #include <CGAL/Surface_mesh_simplification/Vertex_pair_collapse_impl.h>
# include <CGAL/Surface_mesh_simplification/Vertex_pair_collapse.C>
#endif
#endif // CGAL_SURFACE_MESH_SIMPLIFICATION_VERTEX_PAIR_COLLAPSE_IMPL_H // #endif // CGAL_SURFACE_MESH_SIMPLIFICATION__VERTEX_PAIR_COLLAPSE_H //
// EOF // // EOF //

View File

@ -10,43 +10,44 @@
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
// //
// $URL$ // $URL: $
// $Id$ // $Id: $
// //
// Author(s) : Fernando Cacciola <fernando_cacciola@ciudad.com.ar> // Author(s) : Fernando Cacciola <fernando_cacciola@ciudad.com.ar>
// //
#ifndef CGAL_SURFACE_MESH_SIMPLIFICATION_VERTEX_PAIR_COLLAPSE_C #ifndef CGAL_SURFACE_MESH_SIMPLIFICATION_VERTEX_PAIR_COLLAPSE_IMPL_H
#define CGAL_SURFACE_MESH_SIMPLIFICATION_VERTEX_PAIR_COLLAPSE_C #define CGAL_SURFACE_MESH_SIMPLIFICATION_VERTEX_PAIR_COLLAPSE_IMPL_H
CGAL_BEGIN_NAMESPACE CGAL_BEGIN_NAMESPACE
namespace Triangulated_surface_mesh { namespace Simplification namespace Triangulated_surface_mesh { namespace Simplification
{ {
template<class TSM,class SM,class CM,class VP,class SP> template<class M,class D,class C,class V,class S>
VertexPairCollapse<TSM,SM,CM,VP,SP>::VertexPairCollapse( TSM& aSurface VertexPairCollapse<M,D,C,V,S>::VertexPairCollapse( TSM& aSurface
, SelectMap const& aSelectMap , GetCollapseData const& aGet_collapse_data
, CostMap const& aCostMap , GetCollapseDataParams const* aGetCollapseDataParams
, VertexPlacement const& aVertexPlacement , GetCost const& aGet_cost
, StopPred const& aStopPred , GetVertexPoint const& aGet_vertex_point
, bool aIncludeNonEdgePairs , ShouldStop const& aShould_stop
) , bool aIncludeNonEdgePairs
)
: :
mSurface (aSurface) mSurface (aSurface)
,mGetCollapseDataParams(aGetCollapseDataParams)
,Select_map(aSelectMap) ,Get_collapse_data(aGet_collapse_data)
,Cost_map(aCostMap) ,Get_cost (aGet_cost)
,Get_vertex_point (aGet_vertex_point)
,construct_new_vertex_point(aVertexPlacement) ,Should_stop (aShould_stop)
,stop_simplification(aStopPred)
,mIncludeNonEdgePairs(aIncludeNonEdgePairs) ,mIncludeNonEdgePairs(aIncludeNonEdgePairs)
{ {
CGAL_TSMS_TRACE(0,"VertexPairCollapse of TSM with " << boost::num_edges(aSurface) << " edges" ); CGAL_TSMS_TRACE(0,"VertexPairCollapse of TSM with " << num_edges(aSurface) << " edges" );
} }
template<class TSM,class SM,class CM,class VP,class SP> template<class M,class D,class C,class V,class S>
int VertexPairCollapse<TSM,SM,CM,VP,SP>::run() int VertexPairCollapse<M,D,C,V,S>::run()
{ {
Collect(); Collect();
Loop(); Loop();
@ -56,40 +57,38 @@ int VertexPairCollapse<TSM,SM,CM,VP,SP>::run()
return (int)(mInitialPairCount - mCurrentPairCount) ; return (int)(mInitialPairCount - mCurrentPairCount) ;
} }
template<class TSM,class SM,class CM,class VP,class SP> template<class M,class D,class C,class V,class S>
void VertexPairCollapse<TSM,SM,CM,VP,SP>::Collect() void VertexPairCollapse<M,D,C,V,S>::Collect()
{ {
CGAL_TSMS_TRACE(0,"Collecting vertex-pairs..."); CGAL_TSMS_TRACE(0,"Collecting vertex-pairs...");
// Loop over all the edges in the surface putting the accepted vertex-pairs in the PQ // Loop over all the edges in the surface putting the accepted vertex-pairs in the PQ
boost::vertex_point_t vertex_point ; vertex_point_t vertex_point ;
typedef typename Kernel_traits<Point_3>::Kernel Kernel ; typedef typename Kernel_traits<Point_3>::Kernel Kernel ;
Kernel kernel ; Kernel kernel ;
typename Kernel::Equal_3 equal_points = kernel.equal_3_object(); typename Kernel::Equal_3 equal_points = kernel.equal_3_object();
size_type lID = 0 ; size_type lID = 0 ;
edge_iterator eb, ee ; undirected_edge_iterator eb, ee ;
for ( boost::tie(eb,ee) = boost::edges(mSurface); eb!=ee; ++eb ) for ( tie(eb,ee) = undirected_edges(mSurface); eb!=ee; ++eb )
{ {
edge_descriptor edge = *eb ; edge_descriptor edge = *eb ;
vertex_descriptor s = boost::source(edge,mSurface); vertex_descriptor s = source(edge,mSurface);
vertex_descriptor t = boost::target(edge,mSurface); vertex_descriptor t = target(edge,mSurface);
Point_3 sp = boost::get(vertex_point,mSurface,s) ; Point_3 sp = get(vertex_point,mSurface,s) ;
Point_3 tp = boost::get(vertex_point,mSurface,t) ; Point_3 tp = get(vertex_point,mSurface,t) ;
if ( ! equal_points(sp,tp) ) if ( ! equal_points(sp,tp) )
{ {
if ( boost::get(Select_map, boost::make_tuple(s,t,true,boost::addressof(mSurface))) ) Collapse_data_ptr lData = Get_collapse_data(s,t,edge,mSurface,mGetCollapseDataParams) ;
{ vertex_pair_ptr lPair( new vertex_pair(lID++,lData,Get_cost) ) ;
vertex_pair_ptr lPair( new vertex_pair(lID++,s,t,edge,boost::addressof(mSurface),boost::addressof(Cost_map)) ) ; set_pair(edge,lPair);
set_pair(edge,lPair); insert_in_PQ(lPair);
insert_in_PQ(lPair); CGAL_TSMS_TRACE(3, *lPair << " accepted." );
CGAL_TSMS_TRACE(3, *lPair << " accepted." );
}
} }
} }
@ -101,8 +100,8 @@ void VertexPairCollapse<TSM,SM,CM,VP,SP>::Collect()
CGAL_TSMS_TRACE(0,"Initial pair count: " << mInitialPairCount ) ; CGAL_TSMS_TRACE(0,"Initial pair count: " << mInitialPairCount ) ;
} }
template<class TSM,class SM,class CM,class VP,class SP> template<class M,class D,class C,class V,class S>
void VertexPairCollapse<TSM,SM,CM,VP,SP>::Loop() void VertexPairCollapse<M,D,C,V,S>::Loop()
{ {
CGAL_TSMS_TRACE(0,"Removing pairs...") ; CGAL_TSMS_TRACE(0,"Removing pairs...") ;
@ -114,15 +113,15 @@ void VertexPairCollapse<TSM,SM,CM,VP,SP>::Loop()
CGAL_TSMS_TRACE(3,"Poped " << *lPair ) ; CGAL_TSMS_TRACE(3,"Poped " << *lPair ) ;
// Pairs in the queue might be "fixed", that is, marked as uncollapsable, or their cost might be undefined. // Pairs in the queue might be "fixed", that is, marked as uncollapsable, or their cost might be undefined.
if ( !lPair->is_fixed() && lPair->cost() != boost::none ) if ( !lPair->is_fixed() && lPair->cost() != none )
{ {
if ( boost::num_vertices(mSurface) <= 4 ) if ( num_vertices(mSurface) <= 4 )
{ {
CGAL_TSMS_TRACE(0,"Thetrahedron reached."); CGAL_TSMS_TRACE(0,"Thetrahedron reached.");
break ; break ;
} }
if ( stop_simplification(*lPair->cost(),lPair->p(),lPair->q(),lPair->is_edge(),mInitialPairCount,mCurrentPairCount,mSurface) ) if ( Should_stop(*lPair->cost(),*lPair->data(),mInitialPairCount,mCurrentPairCount) )
{ {
CGAL_TSMS_TRACE(0,"Stop condition reached with InitialCount=" << mInitialPairCount CGAL_TSMS_TRACE(0,"Stop condition reached with InitialCount=" << mInitialPairCount
<< " CurrentPairCount=" << mCurrentPairCount << " CurrentPairCount=" << mCurrentPairCount
@ -138,29 +137,29 @@ void VertexPairCollapse<TSM,SM,CM,VP,SP>::Loop()
} }
} }
template<class TSM,class SM,class CM,class VP,class SP> template<class M,class D,class C,class V,class S>
bool VertexPairCollapse<TSM,SM,CM,VP,SP>::Is_collapsable( vertex_pair_ptr const& aPair ) bool VertexPairCollapse<M,D,C,V,S>::Is_collapsable( vertex_pair_ptr const& aPair )
{ {
bool rR = true ; bool rR = true ;
edge_descriptor p_q = aPair->edge(); edge_descriptor p_q = aPair->edge();
edge_descriptor q_p = boost::opposite_edge(p_q,mSurface); edge_descriptor q_p = opposite_edge(p_q,mSurface);
edge_descriptor p_t = boost::next_edge_ccw(p_q,mSurface); edge_descriptor p_t = next_edge_ccw(p_q,mSurface);
edge_descriptor p_b = boost::next_edge_cw (p_q,mSurface); edge_descriptor p_b = next_edge_cw (p_q,mSurface);
edge_descriptor q_t = boost::next_edge_cw (q_p,mSurface); edge_descriptor q_t = next_edge_cw (q_p,mSurface);
edge_descriptor q_b = boost::next_edge_ccw(q_p,mSurface); edge_descriptor q_b = next_edge_ccw(q_p,mSurface);
// degree(p) and degree(q) >= 3 // degree(p) and degree(q) >= 3
if ( boost::target(p_t,mSurface) != aPair->q() if ( target(p_t,mSurface) != aPair->q()
&& boost::target(p_b,mSurface) != aPair->q() && target(p_b,mSurface) != aPair->q()
&& boost::target(q_t,mSurface) != aPair->p() && target(q_t,mSurface) != aPair->p()
&& boost::target(q_b,mSurface) != aPair->p() && target(q_b,mSurface) != aPair->p()
) )
{ {
// link('p') .intersection. link('q') == link('p_q') (that is, exactly {'t','b'}) // link('p') .intersection. link('q') == link('p_q') (that is, exactly {'t','b'})
if ( boost::target(p_t,mSurface) == boost::target(q_t,mSurface) if ( target(p_t,mSurface) == target(q_t,mSurface)
&& boost::target(p_b,mSurface) == boost::target(q_b,mSurface) && target(p_b,mSurface) == target(q_b,mSurface)
) )
{ {
edge_descriptor p_tn = p_t ; edge_descriptor p_tn = p_t ;
@ -170,13 +169,13 @@ bool VertexPairCollapse<TSM,SM,CM,VP,SP>::Is_collapsable( vertex_pair_ptr const&
do do
{ {
p_tn = boost::next_edge_ccw(p_tn,mSurface); p_tn = next_edge_ccw(p_tn,mSurface);
p_bn = boost::next_edge_cw (p_bn,mSurface); p_bn = next_edge_cw (p_bn,mSurface);
q_tn = boost::next_edge_cw (q_tn,mSurface); q_tn = next_edge_cw (q_tn,mSurface);
q_bn = boost::next_edge_ccw(q_bn,mSurface); q_bn = next_edge_ccw(q_bn,mSurface);
if ( boost::target(p_tn,mSurface) == boost::target(q_tn,mSurface) if ( target(p_tn,mSurface) == target(q_tn,mSurface)
|| boost::target(p_bn,mSurface) == boost::target(q_bn,mSurface) || target(p_bn,mSurface) == target(q_bn,mSurface)
) )
{ {
rR = false ; rR = false ;
@ -192,17 +191,19 @@ bool VertexPairCollapse<TSM,SM,CM,VP,SP>::Is_collapsable( vertex_pair_ptr const&
return rR ; return rR ;
} }
template<class TSM,class SM,class CM,class VP,class SP> template<class M,class D,class C,class V,class S>
void VertexPairCollapse<TSM,SM,CM,VP,SP>::Collapse( vertex_pair_ptr const& aPair ) void VertexPairCollapse<M,D,C,V,S>::Collapse( vertex_pair_ptr const& aPair )
{ {
CGAL_TSMS_TRACE(1,"Collapsig " << *aPair ) ; CGAL_TSMS_TRACE(1,"Collapsig " << *aPair ) ;
vertex_descriptor lP = aPair->p(); vertex_descriptor lP = aPair->p();
vertex_descriptor lQ = aPair->q(); vertex_descriptor lQ = aPair->q();
CGAL_assertion( lP != lQ );
// This external function is allowed to return an absent point if there is no way to place the vertex // This external function is allowed to return an absent point if there is no way to place the vertex
// satisfying its constrians. In that case the vertex-pair is simply not removed. // satisfying its constrians. In that case the vertex-pair is simply not removed.
optional_vertex_point_type lNewVertexPoint = construct_new_vertex_point(lP,lQ,aPair->is_edge(),mSurface); Optional_vertex_point_type lNewVertexPoint = Get_vertex_point(*aPair->data());
if ( lNewVertexPoint ) if ( lNewVertexPoint )
{ {
CGAL_TSMS_TRACE(2,"New vertex point: (" << lNewVertexPoint->x() << "," << lNewVertexPoint->y() << "," << lNewVertexPoint->z() << ")"); CGAL_TSMS_TRACE(2,"New vertex point: (" << lNewVertexPoint->x() << "," << lNewVertexPoint->y() << "," << lNewVertexPoint->z() << ")");
@ -212,11 +213,11 @@ void VertexPairCollapse<TSM,SM,CM,VP,SP>::Collapse( vertex_pair_ptr const& aPair
edge_descriptor lEdgePQ = aPair->edge(); edge_descriptor lEdgePQ = aPair->edge();
edge_descriptor lEdgeQP = boost::opposite_edge(lEdgePQ,mSurface); edge_descriptor lEdgeQP = opposite_edge(lEdgePQ,mSurface);
edge_descriptor lEdgePT = boost::next_edge_ccw(lEdgePQ,mSurface); edge_descriptor lEdgePT = next_edge_ccw(lEdgePQ,mSurface);
edge_descriptor lEdgeQB = boost::next_edge_ccw(lEdgeQP,mSurface); edge_descriptor lEdgeQB = next_edge_ccw(lEdgeQP,mSurface);
CGAL_TSMS_TRACE(3,"EdgePQ E" << lEdgePQ->ID << " Opposite EdgePQ E" << lEdgePQ->opposite()->ID CGAL_TSMS_TRACE(3,"EdgePQ E" << lEdgePQ->ID << " Opposite EdgePQ E" << lEdgePQ->opposite()->ID
<< " V" << lEdgePQ->opposite()->vertex()->ID << "->V" << lEdgePQ->vertex()->ID ) ; << " V" << lEdgePQ->opposite()->vertex()->ID << "->V" << lEdgePQ->vertex()->ID ) ;
@ -236,7 +237,27 @@ void VertexPairCollapse<TSM,SM,CM,VP,SP>::Collapse( vertex_pair_ptr const& aPair
{ {
vertex_pair_ptr lPair = get_pair(outedge); vertex_pair_ptr lPair = get_pair(outedge);
CGAL_TSMS_TRACE(4,"Updating vertex P in " << *lPair) ; CGAL_TSMS_TRACE(4,"Updating vertex P in " << *lPair) ;
lPair->update_vertex(lP,lQ) ;
CGAL_assertion( lPair->p() == lP || lPair->q() == lP );
vertex_descriptor v0, v1 ;
edge_descriptor edge ;
if ( lPair->p() == lP )
{
v0 = lQ ;
v1 = lPair->q() ;
edge = outedge ;
}
else
{
v0 = lPair->p() ;
v1 = lQ ;
edge = opposite_edge(outedge,mSurface);
}
Collapse_data_ptr lNewData = Get_collapse_data(v0,v1,edge,mSurface,mGetCollapseDataParams);
lPair->reset_data(lNewData);
CGAL_TSMS_TRACE(4,"...after update: " << *lPair ) ; CGAL_TSMS_TRACE(4,"...after update: " << *lPair ) ;
} }
} }
@ -266,11 +287,11 @@ void VertexPairCollapse<TSM,SM,CM,VP,SP>::Collapse( vertex_pair_ptr const& aPair
// This operator IS NOT passed as a policy. It is a traits. Users only need to specialize it for // This operator IS NOT passed as a policy. It is a traits. Users only need to specialize it for
// the particular surface type. // the particular surface type.
collapse_triangulation_edge(lEdgePQ,lEdgePT,lEdgeQB,mSurface); Collapse_triangulation_edge(lEdgePQ,lEdgePT,lEdgeQB,mSurface);
// Reset the point of placement of Q (the vertex that "replaces" the collapsed edge) // Reset the point of placement of Q (the vertex that "replaces" the collapsed edge)
boost::vertex_point_t vertex_point ; boost::vertex_point_t vertex_point ;
boost::put(vertex_point,mSurface,lQ,*lNewVertexPoint) ; put(vertex_point,mSurface,lQ,*lNewVertexPoint) ;
// Updates the cost of all pairs in the PQ // Updates the cost of all pairs in the PQ
Update_neighbors(lQ); Update_neighbors(lQ);
@ -284,8 +305,8 @@ void VertexPairCollapse<TSM,SM,CM,VP,SP>::Collapse( vertex_pair_ptr const& aPair
} }
template<class TSM,class SM,class CM,class VP,class SP> template<class M,class D,class C,class V,class S>
void VertexPairCollapse<TSM,SM,CM,VP,SP>::Update_neighbors( vertex_descriptor const& v ) void VertexPairCollapse<M,D,C,V,S>::Update_neighbors( vertex_descriptor const& v )
{ {
CGAL_TSMS_TRACE(3,"Updating cost of neighboring edges..." ) ; CGAL_TSMS_TRACE(3,"Updating cost of neighboring edges..." ) ;
@ -298,36 +319,43 @@ void VertexPairCollapse<TSM,SM,CM,VP,SP>::Update_neighbors( vertex_descriptor co
// (A.1) Loop around all vertices adjacent to v // (A.1) Loop around all vertices adjacent to v
in_edge_iterator eb1, ee1 ; in_edge_iterator eb1, ee1 ;
for ( boost::tie(eb1,ee1) = boost::in_edges(v,mSurface) ; eb1 != ee1 ; ++ eb1 ) for ( tie(eb1,ee1) = in_edges(v,mSurface) ; eb1 != ee1 ; ++ eb1 )
{ {
edge_descriptor edge1 = *eb1 ; edge_descriptor edge1 = *eb1 ;
CGAL_TSMS_TRACE(4,"Inedge around V" << v->ID << " E" << edge1->ID << " Opposite E" << edge1->opposite()->ID
<< " V" << edge1->opposite()->vertex()->ID << "->V" << edge1->vertex()->ID ) ;
vertex_pair_ptr lPair1 = get_pair(edge1) ; vertex_pair_ptr lPair1 = get_pair(edge1) ;
CGAL_TSMS_TRACE(4,"Inedge around V" << v->ID << " E" << edge1->ID << " Opposite E" << edge1->opposite()->ID
<< " V" << edge1->opposite()->vertex()->ID << "->V" << edge1->vertex()->ID
<< "\n" << *lPair1
) ;
// This is required to satisfy the transitive link_condition. // This is required to satisfy the transitive link_condition.
// That is, the edges around the replacement vertex 'v' cannot be collapsed again. // That is, the edges around the replacement vertex 'v' cannot be collapsed again.
//lPair1->is_fixed() = true ; //lPair1->is_fixed() = true ;
vertex_descriptor adj_v = boost::source(edge1,mSurface); vertex_descriptor adj_v = source(edge1,mSurface);
// (A.2) Loop around all edges incident on each adjacent vertex // (A.2) Loop around all edges incident on each adjacent vertex
in_edge_iterator eb2, ee2 ; in_edge_iterator eb2, ee2 ;
for ( boost::tie(eb2,ee2) = boost::in_edges(adj_v,mSurface) ; eb2 != ee2 ; ++ eb2 ) for ( tie(eb2,ee2) = in_edges(adj_v,mSurface) ; eb2 != ee2 ; ++ eb2 )
{ {
edge_descriptor edge2 = *eb2 ; edge_descriptor edge2 = *eb2 ;
CGAL_TSMS_TRACE(4,"Inedge around V" << adj_v->ID << " E" << edge2->ID << " Opposite E" << edge2->opposite()->ID
<< " V" << edge2->opposite()->vertex()->ID << "->V" << edge2->vertex()->ID ) ;
vertex_pair_ptr lPair2 = get_pair(edge2); vertex_pair_ptr lPair2 = get_pair(edge2);
CGAL_TSMS_TRACE(4,"Inedge around V" << adj_v->ID << " E" << edge2->ID << " Opposite E" << edge2->opposite()->ID
<< " V" << edge2->opposite()->vertex()->ID << "->V" << edge2->vertex()->ID
<< "\n" << *lPair2
) ;
// Only those pairs still in the PQ are update. // Only those pairs still in the PQ are update.
// The mark is used because in the way we loop here the same pair is found many times. // The mark is used because in the way we loop here the same pair is found many times.
if ( lPair2->is_in_PQ() && lPair2->mark() == 0 ) if ( lPair2->is_in_PQ() && lPair2->mark() == 0 )
{ {
CGAL_TSMS_TRACE(4,"Pair registered for updating.") ;
lPair2->mark() = 1 ; lPair2->mark() = 1 ;
lToUpdate.push_back(lPair2); lToUpdate.push_back(lPair2);
} }
@ -346,7 +374,8 @@ void VertexPairCollapse<TSM,SM,CM,VP,SP>::Update_neighbors( vertex_descriptor co
// The cost of a pair can be recalculated by invalidating its cache and updating the PQ. // The cost of a pair can be recalculated by invalidating its cache and updating the PQ.
// The PQ update will reposition the pair in the heap querying its cost(), // The PQ update will reposition the pair in the heap querying its cost(),
// but since the cost was invalidated, it will be computed again // but since the cost was invalidated, it will be computed again
lPair->invalidate_cost(); Collapse_data_ptr lNewData = Get_collapse_data(lPair->p(),lPair->q(),lPair->edge(),lPair->surface(),mGetCollapseDataParams) ;
lPair->reset_data(lNewData);
update_in_PQ(lPair); update_in_PQ(lPair);
lPair->mark() = 0 ; lPair->mark() = 0 ;
} }
@ -357,6 +386,6 @@ void VertexPairCollapse<TSM,SM,CM,VP,SP>::Update_neighbors( vertex_descriptor co
CGAL_END_NAMESPACE CGAL_END_NAMESPACE
#endif // CGAL_SURFACE_MESH_SIMPLIFICATION_VERTEX_PAIR_COLLAPSE_C // #endif // CGAL_SURFACE_MESH_SIMPLIFICATION_VERTEX_PAIR_COLLAPSE_IMPL_H //
// EOF // // EOF //

View File

@ -32,37 +32,45 @@ namespace Triangulated_surface_mesh { namespace Simplification
// //
// Candidate vertex-pairs are selected via a user-defined selection property map. // Candidate vertex-pairs are selected via a user-defined selection property map.
// Selected vertex-pairs are sorted according to a user-defined cost property map. // Selected vertex-pairs are sorted according to a user-defined cost property map.
// Each vertex-pair removed is replaced by a new vertex whose location is given by a user-defined vertex placement function. // Each vertex-pair removed is replaced by a new vertex whose location is given by the cost property-map.
// The simplification continues until a user-defined stoping conidition is verified. // The simplification continues until a user-defined stoping conidition is verified or there are no collapsable edges remaining.
// //
// Template Parameters: // Template Parameters:
// //
// TSM : the triangulated surface mesh type (a Polyhedron_3 for example) // TSM : the triangulated surface mesh type (a Polyhedron_3 for example)
// SelectionMap: the property map used to select candidate vertex-pairs. // SelectionMap: the property map used to select candidate vertex-pairs.
// CostMap: the property map providing the collapsing-cost of each selected vertex-pair. // CostMap: the property map providing the collapsing-cost of each selected vertex-pair, along with the location of the
// VertexPlacement: the functor that constructs the 3D point of placement of the new vertex replacing each removed vertex-pair. // replacement vertex.
// StopPred: the stopping condition predicate. // StopPred: the stopping condition predicate.
// //
// NOTE: The CostMap and the VertexPlacement functors return optional<> values. This allows any of those functions to reject a // NOTE: The CostMap returns an optional<> value. This allows the function to reject a
// vertex-pair becasue it's cost is too high or uncomputable or the vertex cannot be placed in any way that satisfies the constriants // vertex-pair becasue it's cost is too high or uncomputable or the vertex cannot be placed in any way that satisfies the constriants
// required. Consequently, an accepted vertex-pair (via the SelectMap) might not be removed in the end. // required. Consequently, an accepted vertex-pair (via the SelectMap) might not be removed in the end.
// Vertex-pairs are only removed if they are selected _and_ have a well defined collapsing cost and new vertex location. // Vertex-pairs are only removed if they are selected _and_ have a well defined collapsing cost and new vertex location.
// //
// Returns the number of vertex-pairs removed or -1 if there was an error (like the surface not being a valid triangulated surface mesh) // Returns the number of vertex-pairs removed or -1 if there was an error (like the surface not being a valid triangulated surface mesh)
// //
template<class TSM,class SelectionMap,class CostMap,class VertexPlacement,class StopPred> template<class TSM,class GetCollapseData,class GetCollapseDataParams,class GetCost,class GetVertexPoint,class ShouldStop>
int vertex_pair_collapse ( TSM& aSurface int vertex_pair_collapse ( TSM& aSurface
, SelectionMap const& aSelectMap , GetCollapseData const& aGet_collapse_data
, CostMap const& aCostMap , GetCollapseDataParams const* aGet_collapse_data_params
, VertexPlacement const& aVertexPlacement , GetCost const& aGet_cost
, StopPred const& aStopPred , GetVertexPoint const& aGet_vertex_point
, bool aIncludeNonEdgePairs = false , ShouldStop const& aShould_stop
, bool aIncludeNonEdgePairs = false
) )
{ {
if ( is_valid_triangulated_surface_mesh(aSurface) ) if ( is_valid_triangulated_surface_mesh(aSurface) )
{ {
typedef VertexPairCollapse<TSM,SelectionMap,CostMap,VertexPlacement,StopPred> Algorithm ; typedef VertexPairCollapse<TSM,GetCollapseData,GetCost,GetVertexPoint,ShouldStop> Algorithm ;
Algorithm algorithm(aSurface,aSelectMap,aCostMap,aVertexPlacement,aStopPred,aIncludeNonEdgePairs) ; Algorithm algorithm(aSurface
,aGet_collapse_data
,aGet_collapse_data_params
,aGet_cost
,aGet_vertex_point
,aShould_stop
,aIncludeNonEdgePairs
) ;
return algorithm.run(); return algorithm.run();
} }
else return -1 ; else return -1 ;

View File

@ -0,0 +1,212 @@
// Copyright (c) 2002 Max Planck Institut fuer Informatik (Germany).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// 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) : Fernando Cacciola <fernando.cacciola@gmail.com>
#include <iostream>
#include <iomanip>
#include <iostream>
#include <fstream>
#include <CGAL/Simple_homogeneous.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/Polyhedron_BGL.h>
#include <CGAL/Polyhedron_extended_BGL.h>
#include <CGAL/Polyhedron_BGL_properties.h>
#include <CGAL/IO/Polyhedron_geomview_ostream.h>
#include <CGAL/IO/Polyhedron_iostream.h>
//#define CGAL_SURFACE_SIMPLIFICATION_ENABLE_TRACE 4
#define CREATE_TESTCASE
void Surface_simplification_external_trace( std::string s )
{
std::cout << s << std::endl ;
}
int exit_code = 0 ;
#include <CGAL/Surface_mesh_simplification_vertex_pair_collapse.h>
#include <CGAL/Surface_mesh_simplification/Policies/Construct_minimal_collapse_data.h>
#include <CGAL/Surface_mesh_simplification/Policies/Edge_length_cost.h>
#include <CGAL/Surface_mesh_simplification/Policies/Midpoint_vertex_placement.h>
#include <CGAL/Surface_mesh_simplification/Policies/LindstromTurk.h>
#include <CGAL/Surface_mesh_simplification/Policies/Count_stop_pred.h>
template <class Refs, class Traits>
struct My_vertex : public CGAL::HalfedgeDS_vertex_base<Refs,CGAL::Tag_true,typename Traits::Point_3>
{
typedef CGAL::HalfedgeDS_vertex_base<Refs,CGAL::Tag_true,typename Traits::Point_3> Base ;
My_vertex() {}
My_vertex( typename Traits::Point_3 p ) : Base(p) {}
int ID;
} ;
template <class Refs, class Traits>
struct My_halfedge : public CGAL::HalfedgeDS_halfedge_base<Refs>
{
My_halfedge() {}
int ID;
};
template <class Refs, class Traits>
struct My_face : public CGAL::HalfedgeDS_face_base<Refs,CGAL::Tag_true,typename Traits::Plane_3>
{
typedef CGAL::HalfedgeDS_face_base<Refs,CGAL::Tag_true,typename Traits::Plane_3> Base ;
My_face() {}
My_face( typename Traits::Plane_3 plane ) : Base(plane) {}
int ID;
};
struct My_items : public CGAL::Polyhedron_items_3
{
template < class Refs, class Traits>
struct Vertex_wrapper {
typedef My_vertex<Refs,Traits> Vertex;
};
template < class Refs, class Traits>
struct Halfedge_wrapper {
typedef My_halfedge<Refs,Traits> Halfedge;
};
template < class Refs, class Traits>
struct Face_wrapper {
typedef My_face<Refs,Traits> Face;
};
};
typedef CGAL::Simple_homogeneous<int> Kernel;
//typedef CGAL::Simple_cartesian<double> Kernel;
typedef Kernel::Vector_3 Vector;
typedef Kernel::Point_3 Point;
typedef CGAL::Polyhedron_3<Kernel,My_items> Polyhedron;
typedef Polyhedron::Vertex Vertex;
typedef Polyhedron::Vertex_iterator Vertex_iterator;
typedef Polyhedron::Halfedge_handle Halfedge_handle;
typedef Polyhedron::Edge_iterator Edge_iterator;
typedef Polyhedron::Facet_iterator Facet_iterator;
typedef Polyhedron::Halfedge_around_vertex_const_circulator HV_circulator;
typedef Polyhedron::Halfedge_around_facet_circulator HF_circulator;
using namespace std ;
// This is here only to allow a breakpoint to be placed so I can trace back the problem.
void error_handler ( char const* what, char const* expr, char const* file, int line, char const* msg )
{
cerr << "CGAL error: " << what << " violation!" << endl
<< "Expr: " << expr << endl
<< "File: " << file << endl
<< "Line: " << line << endl;
if ( msg != 0)
cerr << "Explanation:" << msg << endl;
}
using namespace CGAL::Triangulated_surface_mesh::Simplification ;
void Test ( char const* testcase )
{
ifstream in(testcase);
if ( in )
{
Polyhedron lP;
in >> lP ;
cout << "Testing Lindstrom Turk simplification of suracewith " << (lP.size_of_halfedges()/2) << " edges..." << endl ;
cout << setprecision(19) ;
int lVertexID = 0 ;
for ( Polyhedron::Vertex_iterator vi = lP.vertices_begin(); vi != lP.vertices_end() ; ++ vi )
vi->ID = lVertexID ++ ;
int lHalfedgeID = 0 ;
for ( Polyhedron::Halfedge_iterator hi = lP.halfedges_begin(); hi != lP.halfedges_end() ; ++ hi )
hi->ID = lHalfedgeID++ ;
int lFacetID = 0 ;
for ( Polyhedron::Facet_iterator fi = lP.facets_begin(); fi != lP.facets_end() ; ++ fi )
fi->ID = lFacetID ++ ;
typedef LindstromTurk_collapse_data<Polyhedron> Collapse_data ;
Construct_LindstromTurk_collapse_data<Collapse_data> Construct_collapse_data ;
LindstromTurk_cost <Collapse_data> Get_cost ;
LindstromTurk_vertex_placement <Collapse_data> Get_vertex_point ;
Count_stop_condition <Collapse_data> Should_stop(0);
Collapse_data::Params lParams(1,1,1);
int r = vertex_pair_collapse(lP,Construct_collapse_data,&lParams,Get_cost,Get_vertex_point,Should_stop);
cout << "Finished...\n"
<< r << " edges removed.\n"
<< lP.size_of_vertices() << " vertices.\n"
<< (lP.size_of_halfedges()/2) << " edges.\n"
<< lP.size_of_facets() << " triangles.\n"
<< ( lP.is_valid() ? " valid" : " INVALID!!" )
<< endl ;
}
else
{
cerr << "Unable to open test file " << testcase << endl ;
exit_code = 1 ;
}
}
void CreateTestCase()
{
Polyhedron lP;
Point p( 1, 0, 0);
Point q( 0, 1, 0);
Point r( 0, 0, 1);
Point s( 0, 0, 0);
lP.make_tetrahedron( p, q, r, s);
ofstream out("data/sample0.off");
if ( out )
out << lP ;
}
int main( int argc, char** argv )
{
CGAL::set_error_handler (error_handler);
CGAL::set_warning_handler(error_handler);
#ifdef CREATE_TESTCASE
CreateTestCase();
#else
for ( int i = 1 ; i < argc ; ++i )
Test(argv[i]);
#endif
return exit_code;
}
// EOF //

View File

@ -0,0 +1,114 @@
<?xml version = '1.0'?>
<kdevelop>
<general>
<author>fcacciola</author>
<email>fernando.cacciola@gmail.com</email>
<version>$VERSION$</version>
<projectmanagement>KDevCustomProject</projectmanagement>
<primarylanguage>C++</primarylanguage>
<ignoreparts/>
</general>
<kdevcustomproject>
<run>
<mainprogram>LT_edge_collapse_test</mainprogram>
<directoryradio>executable</directoryradio>
</run>
<make>
<abortonerror>false</abortonerror>
<numberofjobs>1</numberofjobs>
<prio>0</prio>
<dontact>false</dontact>
<makebin/>
<defaulttarget/>
<makeoptions>CGAL_MAKEFILE=/home/fcacciola/Programming/CGAL/make/makefile_i686_Linux-2.6_g++-4.0.2 DEBUGGING=yes</makeoptions>
<selectedenvironment>default</selectedenvironment>
<environments>
<default/>
</environments>
</make>
</kdevcustomproject>
<kdevdebugger>
<general>
<dbgshell/>
</general>
</kdevdebugger>
<kdevdoctreeview>
<ignoretocs>
<toc>ada</toc>
<toc>ada_bugs_gcc</toc>
<toc>bash</toc>
<toc>bash_bugs</toc>
<toc>clanlib</toc>
<toc>fortran_bugs_gcc</toc>
<toc>gnome1</toc>
<toc>gnustep</toc>
<toc>gtk</toc>
<toc>gtk_bugs</toc>
<toc>haskell</toc>
<toc>haskell_bugs_ghc</toc>
<toc>java_bugs_gcc</toc>
<toc>java_bugs_sun</toc>
<toc>kde2book</toc>
<toc>opengl</toc>
<toc>pascal_bugs_fp</toc>
<toc>php</toc>
<toc>php_bugs</toc>
<toc>perl</toc>
<toc>perl_bugs</toc>
<toc>python</toc>
<toc>python_bugs</toc>
<toc>qt-kdev3</toc>
<toc>ruby</toc>
<toc>ruby_bugs</toc>
<toc>sdl</toc>
<toc>sw</toc>
<toc>w3c-dom-level2-html</toc>
<toc>w3c-svg</toc>
<toc>w3c-uaag10</toc>
<toc>wxwidgets_bugs</toc>
</ignoretocs>
<ignoreqt_xml>
<toc>Guide to the Qt Translation Tools</toc>
<toc>Qt Assistant Manual</toc>
<toc>Qt Designer Manual</toc>
<toc>Qt Reference Documentation</toc>
<toc>qmake User Guide</toc>
</ignoreqt_xml>
<ignoredoxygen>
<toc>KDE Libraries (Doxygen)</toc>
</ignoredoxygen>
</kdevdoctreeview>
<kdevfilecreate>
<filetypes/>
<useglobaltypes>
<type ext="ui" />
<type ext="cpp" />
<type ext="h" />
</useglobaltypes>
</kdevfilecreate>
<kdevcppsupport>
<references/>
<codecompletion>
<includeGlobalFunctions>true</includeGlobalFunctions>
<includeTypes>true</includeTypes>
<includeEnums>true</includeEnums>
<includeTypedefs>false</includeTypedefs>
<automaticCodeCompletion>true</automaticCodeCompletion>
<automaticArgumentsHint>true</automaticArgumentsHint>
<automaticHeaderCompletion>true</automaticHeaderCompletion>
<codeCompletionDelay>250</codeCompletionDelay>
<argumentsHintDelay>400</argumentsHintDelay>
<headerCompletionDelay>250</headerCompletionDelay>
</codecompletion>
</kdevcppsupport>
<kdevfileview>
<groups>
<hidenonprojectfiles>false</hidenonprojectfiles>
<hidenonlocation>false</hidenonlocation>
</groups>
<tree>
<hidepatterns>*.o,*.lo,CVS</hidepatterns>
<hidenonprojectfiles>false</hidenonprojectfiles>
</tree>
</kdevfileview>
</kdevelop>

View File

@ -0,0 +1,56 @@
# Created by the script cgal_create_makefile
# This is the makefile for compiling a CGAL application.
#---------------------------------------------------------------------#
# include platform specific settings
#---------------------------------------------------------------------#
# Choose the right include file from the <cgalroot>/make directory.
# CGAL_MAKEFILE = ENTER_YOUR_INCLUDE_MAKEFILE_HERE
include $(CGAL_MAKEFILE)
#---------------------------------------------------------------------#
# compiler flags
#---------------------------------------------------------------------#
CXXFLAGS = -I../../include/\
$(TESTSUITE_CXXFLAGS) \
$(EXTRA_FLAGS) \
$(CGAL_CXXFLAGS) \
$(DEBUG_OPT)
#---------------------------------------------------------------------#
# linker flags
#---------------------------------------------------------------------#
LIBPATH = \
$(TESTSUITE_LIBPATH) \
$(CGAL_LIBPATH)
LDFLAGS = \
$(TESTSUITE_LDFLAGS) \
$(CGAL_LDFLAGS)
#---------------------------------------------------------------------#
# target entries
#---------------------------------------------------------------------#
all: \
LT_edge_collapse_test
LT_edge_collapse_test$(EXE_EXT): LT_edge_collapse_test$(OBJ_EXT)
$(CGAL_CXX) $(LIBPATH) $(EXE_OPT)LT_edge_collapse_test LT_edge_collapse_test$(OBJ_EXT) $(LDFLAGS)
clean: \
LT_edge_collapse_test.clean
#---------------------------------------------------------------------#
# suffix rules
#---------------------------------------------------------------------#
.C$(OBJ_EXT):
$(CGAL_CXX) $(CXXFLAGS) $(OBJ_OPT) $<
.cpp$(OBJ_EXT):
$(CGAL_CXX) $(CXXFLAGS) $(OBJ_OPT) $<