diff options
Diffstat (limited to 'src')
23 files changed, 119 insertions, 490 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c2085a40..b910d477 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -24,4 +24,5 @@ else() add_subdirectory(example/Skeleton_blocker) add_subdirectory(example/Contraction) + endif() diff --git a/src/Contraction/include/gudhi/Contraction/policies/Cost_policy.h b/src/Contraction/include/gudhi/Contraction/policies/Cost_policy.h index eddfec44..60ef3b5f 100644 --- a/src/Contraction/include/gudhi/Contraction/policies/Cost_policy.h +++ b/src/Contraction/include/gudhi/Contraction/policies/Cost_policy.h @@ -29,6 +29,9 @@ namespace Gudhi{ namespace contraction { +/** +*@brief Policy to specify the cost of contracting an edge. +*/ template< typename EdgeProfile> class Cost_policy{ public: typedef typename EdgeProfile::Point Point; diff --git a/src/Contraction/include/gudhi/Contraction/policies/Dummy_valid_contraction.h b/src/Contraction/include/gudhi/Contraction/policies/Dummy_valid_contraction.h index a3cbbd2e..de473944 100644 --- a/src/Contraction/include/gudhi/Contraction/policies/Dummy_valid_contraction.h +++ b/src/Contraction/include/gudhi/Contraction/policies/Dummy_valid_contraction.h @@ -31,7 +31,9 @@ namespace contraction { - + /** + *@brief Policy that accept all edge contraction. + */ template< typename EdgeProfile> class Dummy_valid_contraction : public Valid_contraction_policy<EdgeProfile>{ public: typedef typename EdgeProfile::Point Point; diff --git a/src/Contraction/include/gudhi/Contraction/policies/Link_condition_valid_contraction.h b/src/Contraction/include/gudhi/Contraction/policies/Link_condition_valid_contraction.h index d1e0b7db..31c02e43 100644 --- a/src/Contraction/include/gudhi/Contraction/policies/Link_condition_valid_contraction.h +++ b/src/Contraction/include/gudhi/Contraction/policies/Link_condition_valid_contraction.h @@ -32,7 +32,9 @@ namespace Gudhi{ namespace contraction { - + /** + *@brief Policy that only accept edges verifying the link condition (and therefore whose contraction preserving homotopy type). + */ template< typename EdgeProfile> class Link_condition_valid_contraction : public Valid_contraction_policy<EdgeProfile>{ public: typedef typename EdgeProfile::Edge_handle Edge_handle; diff --git a/src/Contraction/include/gudhi/Contraction/policies/Middle_placement.h b/src/Contraction/include/gudhi/Contraction/policies/Middle_placement.h index 3d7a72e8..30f0a570 100644 --- a/src/Contraction/include/gudhi/Contraction/policies/Middle_placement.h +++ b/src/Contraction/include/gudhi/Contraction/policies/Middle_placement.h @@ -30,6 +30,8 @@ namespace Gudhi{ namespace contraction { + + template< typename EdgeProfile> class Middle_placement : public Placement_policy<EdgeProfile>{ public: diff --git a/src/Contraction/include/gudhi/Contraction/policies/Placement_policy.h b/src/Contraction/include/gudhi/Contraction/policies/Placement_policy.h index b4ff6301..37b36dfe 100644 --- a/src/Contraction/include/gudhi/Contraction/policies/Placement_policy.h +++ b/src/Contraction/include/gudhi/Contraction/policies/Placement_policy.h @@ -28,6 +28,10 @@ namespace Gudhi { namespace contraction { + + /** + *@brief Policy to specify where the merged point had to be placed after an edge contraction. + */ template< typename EdgeProfile> class Placement_policy{ public: typedef typename EdgeProfile::Point Point; diff --git a/src/Contraction/include/gudhi/Contraction/policies/Valid_contraction_policy.h b/src/Contraction/include/gudhi/Contraction/policies/Valid_contraction_policy.h index b8e7d6d7..a053042b 100644 --- a/src/Contraction/include/gudhi/Contraction/policies/Valid_contraction_policy.h +++ b/src/Contraction/include/gudhi/Contraction/policies/Valid_contraction_policy.h @@ -25,6 +25,10 @@ namespace Gudhi { namespace contraction { + + /** + *@brief Policy to specify if an edge contraction is valid or not. + */ template< typename EdgeProfile> class Valid_contraction_policy{ public: typedef typename EdgeProfile::Point Point; diff --git a/src/Contraction/include/gudhi/Skeleton_blocker_contractor.h b/src/Contraction/include/gudhi/Skeleton_blocker_contractor.h index f8037897..56f4891f 100644 --- a/src/Contraction/include/gudhi/Skeleton_blocker_contractor.h +++ b/src/Contraction/include/gudhi/Skeleton_blocker_contractor.h @@ -28,7 +28,6 @@ // todo remove the queue to be independent from cgald #include "gudhi/Contraction/CGAL_queue/Modifiable_priority_queue.h" -//#include <CGAL/Modifiable_priority_queue.h> #include <list> @@ -68,7 +67,9 @@ Valid_contraction_policy<Profile>* make_link_valid_contraction(){ } -// visitor that remove popable blockers after an edge contraction +/** +*@brief Visitor to remove popable blockers after an edge contraction. +*/ template <class Profile> class Contraction_visitor_remove_popable : public Contraction_visitor<Profile>{ public: @@ -116,9 +117,9 @@ Contraction_visitor<Profile>* make_remove_popable_blockers_visitor(){ *@class Skeleton_blocker_contractor *@brief Class that allows to contract iteratively edges of a simplicial complex. * - * @details Basically, the simplification algorithm consists in iteratively picking the + * @details The simplification algorithm consists in iteratively picking the * edge with lowest cost and performing an edge contraction if the contraction is valid. - * This class is policy based (and much inspired from the edge collapse package of CGAL). + * This class is policy based (and much inspired from the edge collapse package of CGAL http://doc.cgal.org/latest/Surface_mesh_simplification/index.html). * * Policies that can be changed are : * - the cost policy : how much cost an edge contraction @@ -126,7 +127,6 @@ Contraction_visitor<Profile>* make_remove_popable_blockers_visitor(){ * - the valid contraction policy : is the contraction valid. For instance, it can be * a topological condition (link condition) or a geometrical condition (normals messed up). * - * TODO expliquer la pile */ template< class GeometricSimplifiableComplex, diff --git a/src/Contraction/test/CMakeLists.txt b/src/Contraction/test/CMakeLists.txt deleted file mode 100644 index 049b4ea1..00000000 --- a/src/Contraction/test/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -cmake_minimum_required(VERSION 2.6) -project(GUDHIskbl) - -add_executable ( TestContraction TestContraction.cpp ) - - diff --git a/src/Contraction/test/TestContraction.cpp b/src/Contraction/test/TestContraction.cpp deleted file mode 100644 index 42bf7d82..00000000 --- a/src/Contraction/test/TestContraction.cpp +++ /dev/null @@ -1,201 +0,0 @@ - /* This file is part of the Gudhi Library. The Gudhi library - * (Geometric Understanding in Higher Dimensions) is a generic C++ - * library for computational topology. - * - * Author(s): David Salinas - * - * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (France) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ -#include <ctime> -#include <list> - -#include "combinatorics/Skeleton_blocker/Skeleton_blocker_simple_traits.h" -#include "geometry/Skeleton_blocker_simple_geometric_traits.h" -//#include "Skeleton_blocker/Simplex.h" -#include "contraction/Skeleton_blocker_contractor.h" -#include "Utils.h" -#include "iofile.h" -#include "Test.h" -#include "Skeleton_blocker_geometric_complex.h" -//#include <CGAL/Exact_predicates_inexact_constructions_kernel.h> - - -#include "contraction/Edge_profile.h" - -#include "contraction/policies/Cost_policy.h" -#include "contraction/policies/Edge_length_cost.h" -#include "contraction/policies/Placement_policy.h" -#include "contraction/policies/Middle_placement.h" - -#include "contraction/policies/Valid_contraction_policy.h" -#include "contraction/policies/Dummy_valid_contraction.h" -#include "contraction/policies/Link_condition_valid_contraction.h" - - -using namespace std; - -using namespace Gudhi; - -using namespace skbl; - -struct Geometry_trait{ - typedef std::vector<double> Point; -}; - -typedef Geometry_trait::Point Point; - - -typedef Skeleton_blocker_complex<Skeleton_blocker_simple_traits> AbstractComplex; -typedef Skeleton_blocker_simple_geometric_traits<Geometry_trait> Complex_geometric_traits; - - -typedef Skeleton_blocker_geometric_complex< Complex_geometric_traits > Complex; - -typedef Complex::Vertex_handle Vertex_handle; -typedef Complex::Simplex_handle Simplex_handle; - -typedef Complex::Root_vertex_handle Root_vertex_handle; - -using namespace contraction; - -typedef Skeleton_blocker_contractor<Complex> Complex_contractor; - -typedef Edge_profile<Complex> Profile; - -// compute the distance todo utiliser Euclidean_geometry a la place -template<typename Point> -double eucl_distance(const Point& a,const Point& b){ - double res = 0; - auto a_coord = a.begin(); - auto b_coord = b.begin(); - for(; a_coord != a.end(); a_coord++, b_coord++){ - res += (*a_coord - *b_coord) * (*a_coord - *b_coord); - } - return sqrt(res); -} - -// build the Rips complex todo utiliser Euclidean_geometry a la place -template<typename ComplexType> -void build_rips(ComplexType& complex, double offset){ - if (offset<=0) return; - auto vertices = complex.vertex_range(); - for (auto p = vertices.begin(); p != vertices.end(); ++p) - for (auto q = p; ++q != vertices.end(); /**/) - if (eucl_distance(complex.point(*p), complex.point(*q)) < 2 * offset){ - complex.add_edge(*p,*q); - } -} - - - - -void test_contraction_rips(string name_file, double offset){ - Complex complex; - // load the points - if (!read_off_file<Complex>(name_file,complex,true)){ - std::cerr << "Unable to read file:"<<name_file<<std::endl; - std::cerr << "current path : "; - system("pwd"); - std::cerr<<endl; - return; - } - - clock_t time = clock(); - - TEST("build the Rips complex"); - - build_rips(complex,offset); - - std::cerr << "Rips contruction took "<< ( (float)(clock()-time))/CLOCKS_PER_SEC << " seconds\n"; - - TESTMSG("Initial number of vertices :",complex.num_vertices()); - TESTMSG("Initial number of edges :",complex.num_edges()); - TESTMSG("Initial number of blockers:",complex.num_blockers()); - - time = clock(); - - Complex_contractor contractor(complex, - new Edge_length_cost<Profile>, - contraction::make_first_vertex_placement<Profile>(), - contraction::make_link_valid_contraction<Profile>(), - contraction::make_remove_popable_blockers_visitor<Profile>()); - contractor.contract_edges(); - - TESTVALUE(complex.to_string()); - - TESTVALUE(complex.num_vertices()); - TESTVALUE(complex.num_edges()); - TESTVALUE(complex.num_blockers()); - - std::cerr << "Edge contractions took "<< ( (float)(clock()-time))/CLOCKS_PER_SEC << " seconds\n"; - -} - - -void test_geometric_link(){ - - Complex complex; - std::vector<double> p0(2,0); - std::vector<double> p1(2,0); p1[0] = 1.; - std::vector<double> p2(2,1); - complex.add_vertex(p0); - complex.add_vertex(p1); - complex.add_vertex(p2); - - complex.add_edge(Vertex_handle(0),Vertex_handle(1)); - complex.add_edge(Vertex_handle(1),Vertex_handle(2)); - complex.add_edge(Vertex_handle(2),Vertex_handle(0)); - - - - cerr << "complex points:" <<endl; - for(auto v : complex.vertex_range()){ - cerr <<v <<" -> "; - DBGCONT(complex.point(v)); - } - - cerr << "complex : "<<complex.to_string()<<endl; - - - - - auto link = complex.link(Vertex_handle(0)); - - - cerr << "link of 0 points:" <<endl; - for(auto v : link.vertex_range()){ - cerr <<v <<" -> "; - DBGCONT(link.point(v)); - } - - cerr << "link : "<<link.to_string()<<endl; -} - - - - -int main (int argc, char *argv[]) -{ - if (argc!=3){ - std::cerr << "Usage "<<argv[0]<<" GUDHIPATH/src/data/sphere3D.off 0.1 to load the file GUDHIPATH/src/data/sphere3D.off and contract the Rips complex built with paremeter 0.2.\n"; - return -1; - } - - std::string name_file(argv[1]); - test_contraction_rips(name_file,atof(argv[2])); -} - - diff --git a/src/Skeleton_blocker/concept/SkeletonBlockerDS.h b/src/Skeleton_blocker/concept/SkeletonBlockerDS.h index 5cd3a22c..c0386590 100644 --- a/src/Skeleton_blocker/concept/SkeletonBlockerDS.h +++ b/src/Skeleton_blocker/concept/SkeletonBlockerDS.h @@ -16,9 +16,11 @@ namespace skbl { -/** \brief Concept that must be passed to - * the template class Skeleton_blockers_complex - * +/** \brief Concept for the template class passed for Skeleton_blocker_complex. + * Most importantly, it contains the nodes for vertices and edges + * (Graph_vertex and Graph_edge) that are stored in the simplicial + * complex. The user can redefine these classes to attach + * additional information to vertices and edges. */ struct SkeletonBlockerDS { diff --git a/src/Skeleton_blocker/concept/SkeletonBlockerGeometricDS.h b/src/Skeleton_blocker/concept/SkeletonBlockerGeometricDS.h index 23edaaef..fad680d0 100644 --- a/src/Skeleton_blocker/concept/SkeletonBlockerGeometricDS.h +++ b/src/Skeleton_blocker/concept/SkeletonBlockerGeometricDS.h @@ -9,10 +9,15 @@ #ifndef GUDHI_SKELETONBLOCKERGEOMETRICDS_H_ #define GUDHI_SKELETONBLOCKERGEOMETRICDS_H_ -/** \brief Concept that must be passed to - * the template class Skeleton_blocker_geometric_complex - * +/** + * \brief Concept for template class of Skeleton_blocker_geometric_complex . + * It must specify a GeometryTrait which contains a Point definition. + * + * Graph_vertex must specify how to access to a point. + * Graph_edge must specify how to access to an index. + * */ + //todo the index is just for contraction, to remove template<typename GeometryTrait> struct SkeletonBlockerGeometricDS : public SkeletonBlockerDS { @@ -35,11 +40,11 @@ struct SkeletonBlockerGeometricDS : public SkeletonBlockerDS /** * @brief Access to the point. */ - Point& point(){ return point_; } + Point& point(); /** * @brief Access to the point. */ - const Point& point() const { return point_; } + const Point& point(); }; /** diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker.h index d05bdc19..eff37a18 100644 --- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker.h +++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker.h @@ -41,7 +41,7 @@ \section Introduction The Skeleton-Blocker data-structure had been introduced in the two papers -\cite socg_blockers_2011,\cite blockers2012\cite blockers2012. +\cite socg_blockers_2011,\cite blockers2012. It proposes a light encoding for simplicial complexes by storing only an *implicit* representation of its simplices. Intuitively, it just stores the 1-skeleton of a simplicial complex with a graph and the set of its "missing faces" that @@ -53,7 +53,8 @@ This data-structure handles all simplicial complexes operations such as \section Definitions -We recall briefly classical definitions of simplicial complexes \cite Munkres-elementsalgtop1984. +We recall briefly classical definitions of simplicial complexes + \cite Munkres-elementsalgtop1984. An abstract simplex is a finite non-empty set and its dimension is its number of elements minus 1. Whenever \f$\tau \subset \sigma\f$ and \f$\tau \neq \emptyset \f$, \f$ \tau \f$ is called a face of \f$ \sigma\f$ and \f$ \sigma\f$ is called a coface of \f$ \tau \f$ . Furthermore, @@ -91,22 +92,24 @@ in figure X. \subsection Overview -Four classes define a simplicial complex namely : +Four classes are implemented for simplicial complex in this representation namely : \li Skeleton_blocker_complex : a simplicial complex with basic operations such as vertex/edge/simplex enumeration and construction \li Skeleton_blocker_link_complex : the link of a simplex in a parent complex. It is represented as a sub complex of the parent complex \li Skeleton_blocker_simplifiable_complex : a simplicial complex with simplification operations such as edge contraction or simplex collapse -\li Skeleton_blocker_geometric_complex : a simplicial complex who has access to geometric points in \f$R^d\f$ +\li Skeleton_blocker_geometric_complex : a simplifiable simplicial complex who has access to geometric points in \f$R^d\f$ The two last classes are derived classes from the <Code>Skeleton_blocker_complex</Code> class. The class <Code>Skeleton_blocker_link_complex</Code> inheritates from a template passed parameter that may be either <Code>Skeleton_blocker_complex</Code> or <Code>Skeleton_blocker_geometric_complex</Code> (a link may store points coordinates or not). +Most user will just need to use Skeleton_blocker_geometric_complex. \subsection Visitor The class <Code>Skeleton_blocker_complex</Code> has a visitor that is called when usual operations such as adding an edge or remove a vertex are called. You may want to use this visitor to compute statistics or to update another data-structure (for instance this visitor is heavily used in the -<Code>Contraction</Code> package). +<Code>Contraction</Code> package). + diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_off_io.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_off_io.h index a02dfe29..fd44fba5 100644 --- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_off_io.h +++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_off_io.h @@ -28,6 +28,9 @@ namespace Gudhi { namespace skbl { +/** + *@brief Off reader visitor that can be passed to Off_reader to read a Skeleton_blocker_complex. + */ template<typename Complex> class Skeleton_blocker_off_visitor_reader{ Complex& complex_; @@ -65,6 +68,9 @@ public: } }; +/** +*@brief Class that allows to load a Skeleton_blocker_complex from an off file. +*/ template<typename Complex> class Skeleton_blocker_off_reader{ public: diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_simple_geometric_traits.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_simple_geometric_traits.h index bb48cd8e..a24bea25 100644 --- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_simple_geometric_traits.h +++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_simple_geometric_traits.h @@ -30,8 +30,12 @@ namespace Gudhi{ namespace skbl{ + /** * @extends SkeletonBlockerGeometricDS + * @ingroup skbl + * @brief Simple traits that is a model of SkeletonBlockerGeometricDS and + * can be passed as a template argument to Skeleton_blocker_geometric_complex */ template<typename GeometryTrait> struct Skeleton_blocker_simple_geometric_traits : public skbl::Skeleton_blocker_simple_traits { @@ -49,6 +53,7 @@ public: template<class ComplexGeometricTraits> friend class Skeleton_blocker_geometric_complex; private: Point point_; + Point& point(){ return point_; } const Point& point() const { return point_; } }; diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_simple_traits.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_simple_traits.h index 9d945d46..e17ea9b5 100644 --- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_simple_traits.h +++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_simple_traits.h @@ -32,11 +32,14 @@ namespace skbl { /** * @extends SkeletonBlockerDS + * @ingroup skbl + * @brief Simple traits that is a model of SkeletonBlockerDS and + * can be passed as a template argument to Skeleton_blocker_complex */ struct Skeleton_blocker_simple_traits{ /** - * @brief global and local handle similar to <a href="http://www.boost.org/doc/libs/1_38_0/libs/graph/doc/subgraph.html">boost subgraphs</a>. - * In gross, vertices are stored in a vector. + * @brief Global and local handle similar to <a href="http://www.boost.org/doc/libs/1_38_0/libs/graph/doc/subgraph.html">boost subgraphs</a>. + * Vertices are stored in a vector. * For the root simplicial complex, the local and global descriptors are the same. * For a subcomplex L and one of its vertices 'v', the local descriptor of 'v' is its position in * the vertex vector of the subcomplex L whereas its global descriptor is the position of 'v' diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_sub_complex.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_sub_complex.h index 97cadfc9..9b4253d1 100644 --- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_sub_complex.h +++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker/Skeleton_blocker_sub_complex.h @@ -33,7 +33,7 @@ namespace skbl { /** * @brief Simplicial subcomplex of a complex represented by a skeleton/blockers pair. - * + * @extends Skeleton_blocker_complex * @details Stores a subcomplex of a simplicial complex. * To simplify explanations below, we will suppose that : * - K is the root simplicial complex diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_complex.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_complex.h index c0a0a2eb..81ff0231 100644 --- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_complex.h +++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_complex.h @@ -74,19 +74,35 @@ class Skeleton_blocker_complex public: - + /** + * @brief The type of stored vertex node, specified by the template SkeletonBlockerDS + */ typedef typename SkeletonBlockerDS::Graph_vertex Graph_vertex; + + /** + * @brief The type of stored edge node, specified by the template SkeletonBlockerDS + */ typedef typename SkeletonBlockerDS::Graph_edge Graph_edge; typedef typename SkeletonBlockerDS::Root_vertex_handle Root_vertex_handle; + + /** + * @brief The type of an handle to a vertex of the complex. + */ typedef typename SkeletonBlockerDS::Vertex_handle Vertex_handle; typedef typename Root_vertex_handle::boost_vertex_handle boost_vertex_handle; + /** + * @brief A ordered set of integers that represents a simplex. + */ typedef Skeleton_blocker_simplex<Vertex_handle> Simplex_handle; typedef Skeleton_blocker_simplex<Root_vertex_handle> Root_simplex_handle; + /** + * @brief Handle to a blocker of the complex. + */ typedef Simplex_handle* Blocker_handle; @@ -118,12 +134,12 @@ protected: public: /** - * Handle to an edge of the complex. + * @brief Handle to an edge of the complex. */ typedef typename boost::graph_traits<Graph>::edge_descriptor Edge_handle; - +protected: typedef std::multimap<Vertex_handle,Simplex_handle *> BlockerMap; typedef typename std::multimap<Vertex_handle,Simplex_handle *>::value_type BlockerPair; typedef typename std::multimap<Vertex_handle,Simplex_handle *>::iterator BlockerMapIterator; @@ -166,6 +182,9 @@ public: /** @name Constructors, Destructors */ //@{ + /** + *@brief constructs a simplicial complex with a given number of vertices and a visitor. + */ Skeleton_blocker_complex(int num_vertices_ = 0,Visitor* visitor_=NULL):visitor(visitor_){ clear(); for (int i=0; i<num_vertices_; ++i){ @@ -277,10 +296,9 @@ private: public: /** - * @brief Constructor with a list of simplices + * @brief Constructor with a list of simplices. * @details The list of simplices must be the list - * of simplices of a simplicial complex. - * + * of simplices of a simplicial complex. */ Skeleton_blocker_complex(std::list<Simplex_handle>& simplices,Visitor* visitor_=NULL): num_vertices_(0),num_blockers_(0), @@ -330,6 +348,8 @@ public: } } +/** +*/ Skeleton_blocker_complex& operator=(const Skeleton_blocker_complex& copy){ clear(); visitor = NULL; @@ -370,6 +390,9 @@ public: skeleton.clear(); } +/** +*@brief allows to change the visitor. +*/ void set_visitor(Visitor* other_visitor){ visitor = other_visitor; } @@ -445,11 +468,15 @@ public: if (visitor) visitor->on_remove_vertex(address); } +/** +*/ bool contains_vertex(Vertex_handle u) const{ if (u.vertex<0 || u.vertex>=boost::num_vertices(skeleton)) return false; return (*this)[u].is_active(); } +/** +*/ bool contains_vertex(Root_vertex_handle u) const{ boost::optional<Vertex_handle> address = get_address(u); return address && (*this)[*address].is_active(); @@ -923,8 +950,9 @@ public: * @brief Compute the local vertices of 's' in the current complex * If one of them is not present in the complex then the return value is uninitialized. * - * xxx rename get_address et place un using dans sub_complex + * */ + //xxx rename get_address et place un using dans sub_complex boost::optional<Simplex_handle> get_simplex_address(const Root_simplex_handle& s) const { boost::optional<Simplex_handle> res; @@ -1126,6 +1154,7 @@ private: public: typedef Triangle_around_vertex_iterator<Skeleton_blocker_complex,Superior_link> Superior_triangle_around_vertex_iterator; + typedef boost::iterator_range < Triangle_around_vertex_iterator<Skeleton_blocker_complex,Link> > Complex_triangle_around_vertex_range; /** @@ -1320,6 +1349,7 @@ public: */ //@{ public: + std::string to_string() const{ std::ostringstream stream; stream<<num_vertices()<<" vertices:\n"<<vertices_to_string()<<std::endl; diff --git a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_simplifiable_complex.h b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_simplifiable_complex.h index 968e8be4..1a51e709 100644 --- a/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_simplifiable_complex.h +++ b/src/Skeleton_blocker/include/gudhi/Skeleton_blocker_simplifiable_complex.h @@ -32,6 +32,7 @@ namespace skbl { * \brief Class that allows simplification operation on a simplicial complex represented * by a skeleton/blockers pair. * \ingroup skbl + * @extends Skeleton_blocker_complex */ template<typename SkeletonBlockerDS> class Skeleton_blocker_simplifiable_complex : public Skeleton_blocker_complex<SkeletonBlockerDS> diff --git a/src/Skeleton_blocker/test/TestSimplifiable.cpp b/src/Skeleton_blocker/test/TestSimplifiable.cpp index 8df4dade..2dafda52 100644 --- a/src/Skeleton_blocker/test/TestSimplifiable.cpp +++ b/src/Skeleton_blocker/test/TestSimplifiable.cpp @@ -74,8 +74,8 @@ bool test_contraction1(){ Complex complex(n); build_complete(n,complex); complex.remove_edge(Vertex_handle(b),Vertex_handle(z)); - complex.add_blocker(Vertex_handle(a),Vertex_handle(x),Vertex_handle(y)); - complex.add_blocker(Vertex_handle(b),Vertex_handle(x),Vertex_handle(y)); + complex.add_blocker(Simplex_handle(Vertex_handle(a),Vertex_handle(x),Vertex_handle(y))); + complex.add_blocker(Simplex_handle(Vertex_handle(b),Vertex_handle(x),Vertex_handle(y))); // Print result cerr << "complex before complex"<< complex.to_string()<<endl; @@ -136,7 +136,7 @@ bool test_link_condition1(){ Complex complex(0); // Build the complexes build_complete(4,complex); - complex.add_blocker(Vertex_handle(0),Vertex_handle(1),Vertex_handle(2)); + complex.add_blocker(Simplex_handle(Vertex_handle(0),Vertex_handle(1),Vertex_handle(2))); // Print result @@ -183,7 +183,7 @@ bool test_collapse2(){ complex.add_edge(Vertex_handle(1),Vertex_handle(4)); complex.add_edge(Vertex_handle(2),Vertex_handle(4)); complex.add_edge(Vertex_handle(3),Vertex_handle(4)); - complex.add_blocker(Vertex_handle(1),Vertex_handle(2),Vertex_handle(3),Vertex_handle(4)); + complex.add_blocker(Simplex_handle(Vertex_handle(1),Vertex_handle(2),Vertex_handle(3),Vertex_handle(4))); // Print result cerr << "initial complex :\n"<< complex.to_string(); cerr <<endl<<endl; @@ -206,7 +206,7 @@ bool test_collapse3(){ complex.add_edge(Vertex_handle(1),Vertex_handle(4)); complex.add_edge(Vertex_handle(2),Vertex_handle(4)); complex.add_edge(Vertex_handle(3),Vertex_handle(4)); - complex.add_blocker(Vertex_handle(1),Vertex_handle(2),Vertex_handle(3),Vertex_handle(4)); + complex.add_blocker(Simplex_handle(Vertex_handle(1),Vertex_handle(2),Vertex_handle(3),Vertex_handle(4))); // Print result cerr << "initial complex:\n"<< complex.to_string(); cerr <<endl<<endl; diff --git a/src/Skeleton_blocker/test/TestSkeletonBlockerComplex.cpp b/src/Skeleton_blocker/test/TestSkeletonBlockerComplex.cpp index 1ebb7f6d..f7bf289a 100644 --- a/src/Skeleton_blocker/test/TestSkeletonBlockerComplex.cpp +++ b/src/Skeleton_blocker/test/TestSkeletonBlockerComplex.cpp @@ -224,7 +224,7 @@ bool test_iterator_triangles(){ complex.add_vertex(); complex.add_edge(Vertex_handle(4),Vertex_handle(7)); complex.add_edge(Vertex_handle(3),Vertex_handle(7)); - complex.add_blocker(Vertex_handle(0),Vertex_handle(1),Vertex_handle(6)); + complex.add_blocker(Simplex_handle(Vertex_handle(0),Vertex_handle(1),Vertex_handle(6))); num_triangles_seen=0; TEST("triangles (should be 6 of them):"); @@ -255,7 +255,7 @@ bool test_iterator_simplices(){ complex.add_edge(Vertex_handle(4),Vertex_handle(5)); complex.add_edge(Vertex_handle(3),Vertex_handle(4)); - complex.add_blocker(Vertex_handle(2),Vertex_handle(3),Vertex_handle(4),Vertex_handle(5)); + complex.add_blocker(Simplex_handle(Vertex_handle(2),Vertex_handle(3),Vertex_handle(4),Vertex_handle(5))); bool correct_number_simplices = true; @@ -322,7 +322,7 @@ bool test_iterator_simplices3(){ complex.add_edge(Vertex_handle(0),Vertex_handle(1)); complex.add_edge(Vertex_handle(1),Vertex_handle(2)); complex.add_edge(Vertex_handle(2),Vertex_handle(0)); - complex.add_blocker(Vertex_handle(0),Vertex_handle(1),Vertex_handle(2)); + complex.add_blocker(Simplex_handle(Vertex_handle(0),Vertex_handle(1),Vertex_handle(2))); unsigned num_simplices = 0 ; @@ -470,7 +470,7 @@ bool test_link2(){ for (int j=i+1;j<15;j++) complex.add_edge(Vertex_handle(i),Vertex_handle(j)); } - complex.add_blocker(Vertex_handle(10),Vertex_handle(11),Vertex_handle(13)); + complex.add_blocker(Simplex_handle(Vertex_handle(10),Vertex_handle(11),Vertex_handle(13))); alpha = Simplex_handle(Vertex_handle(12),Vertex_handle(14)); Skeleton_blocker_link_complex<Complex> L(complex,alpha); // Complexes built @@ -508,7 +508,7 @@ bool test_link3(){ for (int j=i+1;j<15;j++) complex.add_edge(Vertex_handle(i),Vertex_handle(j)); } - complex.add_blocker(Vertex_handle(10),Vertex_handle(11),Vertex_handle(12)); + complex.add_blocker(Simplex_handle(Vertex_handle(10),Vertex_handle(11),Vertex_handle(12))); alpha = Simplex_handle(Vertex_handle(12),Vertex_handle(14)); Skeleton_blocker_link_complex<Complex> L(complex,alpha); // Complexes built @@ -540,7 +540,7 @@ bool test_link4(){ for (int j=i+1;j<15;j++) complex.add_edge(Vertex_handle(i),Vertex_handle(j)); } - complex.add_blocker(Vertex_handle(10),Vertex_handle(11),Vertex_handle(12),Vertex_handle(13)); + complex.add_blocker(Simplex_handle(Vertex_handle(10),Vertex_handle(11),Vertex_handle(12),Vertex_handle(13))); Simplex_handle alpha(Vertex_handle(12),Vertex_handle(14)); Skeleton_blocker_link_complex<Complex> L(complex,alpha); // Complexes built @@ -565,7 +565,7 @@ bool test_link5(){ Complex complex(0,new Print_complex_visitor<Vertex_handle>()); // Build the complexes build_complete(4,complex); - complex.add_blocker(Vertex_handle(0),Vertex_handle(1),Vertex_handle(2),Vertex_handle(3)); + complex.add_blocker(Simplex_handle(Vertex_handle(0),Vertex_handle(1),Vertex_handle(2),Vertex_handle(3))); Simplex_handle alpha(Vertex_handle(0),Vertex_handle(1),Vertex_handle(2)); @@ -585,7 +585,7 @@ bool test_link6(){ Complex complex(0,new Print_complex_visitor<Vertex_handle>()); // Build the complexes build_complete(4,complex); - complex.add_blocker(Vertex_handle(0),Vertex_handle(1),Vertex_handle(2)); + complex.add_blocker(Simplex_handle(Vertex_handle(0),Vertex_handle(1),Vertex_handle(2))); Simplex_handle alpha(Vertex_handle(0),Vertex_handle(1),Vertex_handle(2)); @@ -614,8 +614,8 @@ bool test_link7(){ complex.add_edge(Vertex_handle(i),Vertex_handle(7)); } complex.add_edge(Vertex_handle(6),Vertex_handle(7)); - complex.add_blocker(Vertex_handle(0),Vertex_handle(1),Vertex_handle(2)); - complex.add_blocker(Vertex_handle(3),Vertex_handle(4),Vertex_handle(5)); + complex.add_blocker(Simplex_handle(Vertex_handle(0),Vertex_handle(1),Vertex_handle(2))); + complex.add_blocker(Simplex_handle(Vertex_handle(3),Vertex_handle(4),Vertex_handle(5))); Simplex_handle alpha(Vertex_handle(3),Vertex_handle(4),Vertex_handle(5)); diff --git a/src/common/doc/main_page.h b/src/common/doc/main_page.h index 547e738d..b640ea7b 100644 --- a/src/common/doc/main_page.h +++ b/src/common/doc/main_page.h @@ -30,7 +30,7 @@ Some packages require additional libraries : The procedure to install these packages according to your operating system is detailled here http://doc.cgal.org/latest/Manual/installation.html -The library compiles in Linux, Mac OSX. +The library compiles in Linux and Mac OSX. \section d Demos and Examples diff --git a/src/common/include/gudhi/iofile.h b/src/common/include/gudhi/iofile.h deleted file mode 100644 index 06145be0..00000000 --- a/src/common/include/gudhi/iofile.h +++ /dev/null @@ -1,237 +0,0 @@ - -//todo remove and use off_reader instead - -#ifndef GUDHI_IOFILE_H_ -#define GUDHI_IOFILE_H_ - -#include <iostream> -#include <fstream> -#include <sstream> -#include <vector> -#include <cstdio> -#include <cstring> -#include <list> -#include <cassert> - - - -////todo use my new visitor based off instead -///** -// * @brief OFF reader, save the content of the file (vertices and maximal faces) in 'complex'. -// * The class Complex has to handle the following operations: -// * - void add_vertex(double[dim],int dim) -// * - void add_face(int dimension ,int[dimension] vertices) -// * Source from : http://www.holmes3d.net/graphics/offfiles/OFFLoading.txt -// * -// * @todo todo ignore comments in the file -> # comment -// */ -//template<typename Complex> inline -//bool general_read_off_file(const std::string & file_name, Complex& complex){ -// // Declare temporary variables to read data into. -// // If the read goes well, we'll copy these into -// // our class variables, overwriting what used to -// // be there. If it doesn't, we won't have messed up -// // our previous data structures. -// int tempNumPoints = 0; // Number of x,y,z coordinate triples -// int tempNumFaces = 0; // Number of polygon sets -// int tempNumEdges = 0; // Unused, except for reading. -// int tempDimPoints = 0; -// double** tempPoints = NULL; // An array of x,y,z coordinates. -// int** tempFaces = NULL; // An array of arrays of point -// // pointers. Each entry in this -// // is an array of integers. Each -// // integer in that array is the -// // index of the x, y, and z -// // coordinates in the corresponding -// // arrays. -// int* tempFaceSizes = NULL; // An array of polygon point counts. -// // Each of the arrays in the tempFaces -// // array may be of different lengths. -// // This array corresponds to that -// // array, and gives their lengths. -// int i; // Generic loop variable. -// bool goodLoad = true; // Set to false if the file appears -// // not to be a valid OFF file. -// char tempBuf[128]; // A buffer for reading strings -// // from the file. -// -// // Create an input file stream for the file the CArchive -// // is connected to. This allows use of the overloaded -// // extraction operator for conversion from string -// // data to doubles and ints. -// std::ifstream ifs (file_name.c_str(), std::ios::in); -// if(!ifs.is_open()) { -// std::cerr << "Unable to open file " << file_name << std::endl; -// return false; -// } -// -// // Grab the first string. If it's "OFF", we think this -// // is an OFF file and continue. Otherwise we give up. -// ifs >> tempBuf; -// if (strcmp(tempBuf, "OFF") != 0) { -// goodLoad = false; -// std::cerr << "No OFF preambule\n"; -// } -// -// // Read the sizes for our two arrays, and the third -// // int on the line. If the important two are zero -// // sized, this is a messed up OFF file. Otherwise, -// // we setup our temporary arrays. -// if (goodLoad) { -// ifs >> tempNumPoints >> tempNumFaces >> tempNumEdges; -// if (tempNumPoints < 1 || tempNumFaces < 0) { -// // If either of these were negative, we make -// // sure that both are set to zero. This is -// // important for later deleting our temporary -// // storage. -// goodLoad = false; -// std::cerr << "tempNumPoints < 1 || tempNumFaces < 0\n"; -// tempNumPoints = 0; -// tempNumFaces = 0; -// } else { -// tempPoints = new double*[tempNumPoints]; -// tempFaces = new int*[tempNumFaces]; -// tempFaceSizes = new int[tempNumFaces]; -// } -// } -// -// if (goodLoad) { -// // Load all of the points. -// -// // we start by loading the first one -// // the case is difference because then we dont know the dimension by advance -// // we discover the point dimension by reading the first line -// std::string lineFirstPoint; -// std::getline(ifs, lineFirstPoint); -// while(lineFirstPoint.size()<3){ -// std::getline(ifs, lineFirstPoint); -// } -// -// // we store the first point in a temporary list -// std::istringstream lineFirstPointStream(lineFirstPoint); -// std::list<double> firstTempPoint; -// double coord; -// while(lineFirstPointStream>>coord){ -// firstTempPoint.push_back(coord); -// ++tempDimPoints; -// } -// // we store the point in our points array -// tempPoints[0]=new double[tempDimPoints]; -// for( int j = 0 ; j<tempDimPoints; ++j){ -// tempPoints[0][j] = firstTempPoint.front(); -// firstTempPoint.pop_front(); -// } -// -// // now, we know the dimension and can read safely other points -// for (i = 1; i < tempNumPoints; i++) { -// tempPoints[i] = new double[tempDimPoints]; -// for (int j = 0 ; j<tempDimPoints ; ++j){ -// ifs>>tempPoints[i][j]; -// } -// } -// -// // Load all of the faces. -// for (i = 0; i < tempNumFaces; i++) { -// // This tells us how many points make up -// // this face. -// ifs >> tempFaceSizes[i]; -// // So we declare a new array of that size -// tempFaces[i] = new int[tempFaceSizes[i]]; -// // And load its elements with the vertex indices. -// for (int j = 0; j < tempFaceSizes[i]; j++) { -// ifs >> tempFaces[i][j]; -// } -// // Clear out any face color data by reading up to -// // the newline. 128 is probably considerably more -// // space than necessary, but better safe than -// // sorry. -// ifs.getline(tempBuf, 128); -// } -// } -// -// // Here is where we copy the data from the temp -// // structures into our permanent structures. We -// // probably will do some more processing on the -// // data at the same time. This code you must fill -// // in on your own. -// if (goodLoad) { -// // we save vertices first in the complex -// for (i = 0; i < tempNumPoints; i++) -// complex.add_vertex(tempPoints[i],tempDimPoints); -// -// // we save faces -// for (i = 0; i < tempNumFaces; i++) { -// for (int j = 0; j < tempFaceSizes[i]; j++) -// complex.add_face(tempFaceSizes[i],tempFaces[i]); -// } -// } -// -// // Now that we're done, we have to make sure we -// // free our dynamic memory. -// for (i = 0; i < tempNumPoints; i++) { -// delete []tempPoints[i]; -// } -// delete []tempPoints; -// -// for (i = 0; i < tempNumFaces; i++) { -// delete tempFaces[i]; -// } -// delete []tempFaces; -// delete []tempFaceSizes; -// -// // Clean up our ifstream. The MFC framework will -// // take care of the CArchive. -// ifs.close(); -// -// return goodLoad; -//} - - -template<typename Complex> -class Geometric_flag_complex_wrapper{ - Complex& complex_; - typedef typename Complex::Vertex_handle Vertex_handle; - typedef typename Complex::Point Point; - - const bool load_only_points_; - -public: - Geometric_flag_complex_wrapper(Complex& complex,bool load_only_points = false): - complex_(complex), - load_only_points_(load_only_points) -{} - - - void add_vertex(double* xyz,int dim){ - Point p(dim); - for(int i=0;i<dim;++i) - p[i] = xyz[i]; - complex_.add_vertex(p); - } - - void add_face(int dimension ,int* vertices){ - if (!load_only_points_){ - for (int i = 0; i<dimension ; ++i) - for (int j = i+1; j<dimension ; ++j) - complex_.add_edge(Vertex_handle(vertices[i]),Vertex_handle(vertices[j])); - } - } -}; - - - - -/** - * @brief Read a mesh into a OFF file - * load_only_points should be true if only the points have to be loaded. - */ -template<typename Complex> -bool read_off_file(std::string file_name,Complex &complex,bool load_only_points = false){ - complex.clear(); - Geometric_flag_complex_wrapper<Complex> complex_wrapper(complex,load_only_points); - return general_read_off_file(file_name,complex_wrapper); - -} - - -#endif |