From 13909da1c16c05550c440c8bf22c4a5bfc4fcdf9 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Wed, 7 Oct 2015 10:45:09 +0000 Subject: cpplint fixes on contraction + Eigen3 cmake find modules git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/trunk@837 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 9f2afcb6bc8721680442c97d5297528d41c9d9b0 --- .../CGAL_queue/Modifiable_priority_queue.h | 120 +-- .../include/gudhi/Contraction/Edge_profile.h | 199 ++-- src/Contraction/include/gudhi/Edge_contraction.h | 36 +- .../include/gudhi/Skeleton_blocker_contractor.h | 1009 ++++++++++---------- src/cmake/modules/FindEigen3.cmake | 86 ++ src/cmake/modules/UseEigen3.cmake | 9 + 6 files changed, 760 insertions(+), 699 deletions(-) create mode 100644 src/cmake/modules/FindEigen3.cmake create mode 100644 src/cmake/modules/UseEigen3.cmake (limited to 'src') diff --git a/src/Contraction/include/gudhi/Contraction/CGAL_queue/Modifiable_priority_queue.h b/src/Contraction/include/gudhi/Contraction/CGAL_queue/Modifiable_priority_queue.h index 10b89e13..f4eb59fd 100644 --- a/src/Contraction/include/gudhi/Contraction/CGAL_queue/Modifiable_priority_queue.h +++ b/src/Contraction/include/gudhi/Contraction/CGAL_queue/Modifiable_priority_queue.h @@ -16,8 +16,8 @@ // // Author(s) : Fernando Cacciola // -#ifndef CGAL_MODIFIABLE_PRIORITY_QUEUE_H -#define CGAL_MODIFIABLE_PRIORITY_QUEUE_H +#ifndef CONTRACTION_CGAL_MODIFIABLE_PRIORITY_QUEUE_H +#define CONTRACTION_CGAL_MODIFIABLE_PRIORITY_QUEUE_H #define CGAL_SURFACE_MESH_SIMPLIFICATION_USE_RELAXED_HEAP @@ -27,65 +27,73 @@ namespace CGAL { -template - ,class ID_ = boost::identity_property_map - > -class Modifiable_priority_queue -{ -public: - +template , class ID_ = boost::identity_property_map> +class Modifiable_priority_queue { + public: typedef Modifiable_priority_queue Self; - - typedef IndexedType_ IndexedType ; - typedef Compare_ Compare; - typedef ID_ ID ; - - typedef boost::relaxed_heap Heap; + + typedef IndexedType_ IndexedType; + typedef Compare_ Compare; + typedef ID_ ID; + + typedef boost::relaxed_heap Heap; typedef typename Heap::value_type value_type; - typedef typename Heap::size_type size_type; - - typedef bool handle ; - -public: - - Modifiable_priority_queue( size_type largest_ID, Compare const& c, ID const& id ) : mHeap(largest_ID,c,id) {} - - handle push ( value_type const& v ) { mHeap.push(v) ; return handle(true) ; } - - handle update ( value_type const& v, handle h ) { mHeap.update(v); return h ; } - - handle erase ( value_type const& v, handle ) { mHeap.remove(v); return null_handle() ; } - - value_type top() const { return mHeap.top() ; } - - void pop() { mHeap.pop(); } - - bool empty() const { return mHeap.empty() ; } - - bool contains ( value_type const& v ) { return mHeap.contains(v) ; } - - boost::optional extract_top() - { - boost::optional r ; - if ( !empty() ) - { + typedef typename Heap::size_type size_type; + + typedef bool handle; + + public: + Modifiable_priority_queue(size_type largest_ID, Compare const& c, ID const& id) : mHeap(largest_ID, c, id) { } + + handle push(value_type const& v) { + mHeap.push(v); + return handle(true); + } + + handle update(value_type const& v, handle h) { + mHeap.update(v); + return h; + } + + handle erase(value_type const& v, handle) { + mHeap.remove(v); + return null_handle(); + } + + value_type top() const { + return mHeap.top(); + } + + void pop() { + mHeap.pop(); + } + + bool empty() const { + return mHeap.empty(); + } + + bool contains(value_type const& v) { + return mHeap.contains(v); + } + + boost::optional extract_top() { + boost::optional r; + if (!empty()) { value_type v = top(); pop(); - r = boost::optional(v) ; - } - return r ; + r = boost::optional(v); + } + return r; + } + + static handle null_handle() { + return handle(false); } - - static handle null_handle() { return handle(false); } - -private: - Heap mHeap ; - -} ; + private: + Heap mHeap; +}; -} //namespace CGAL +} //namespace CGAL -#endif - +#endif // CONTRACTION_CGAL_MODIFIABLE_PRIORITY_QUEUE_H diff --git a/src/Contraction/include/gudhi/Contraction/Edge_profile.h b/src/Contraction/include/gudhi/Contraction/Edge_profile.h index f90bd71a..b6dfd63b 100644 --- a/src/Contraction/include/gudhi/Contraction/Edge_profile.h +++ b/src/Contraction/include/gudhi/Contraction/Edge_profile.h @@ -1,130 +1,129 @@ - /* 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 . - */ - -#ifndef GUDHI_EDGE_PROFILE_H_ -#define GUDHI_EDGE_PROFILE_H_ -//#include "combinatorics/Skeleton_blocker/Simplex.h" - - -namespace Gudhi{ +/* 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 . + */ + +#ifndef CONTRACTION_EDGE_PROFILE_H_ +#define CONTRACTION_EDGE_PROFILE_H_ + +namespace Gudhi { namespace contraction { -template class Edge_profile{ -public: - typedef GeometricSimplifiableComplex Complex; - typedef typename Complex::GT GT; +template class Edge_profile { + public: + typedef GeometricSimplifiableComplex Complex; + typedef typename Complex::GT GT; - typedef typename GeometricSimplifiableComplex::Vertex_handle Vertex_handle; - typedef typename GeometricSimplifiableComplex::Root_vertex_handle Root_vertex_handle; + typedef typename GeometricSimplifiableComplex::Vertex_handle Vertex_handle; + typedef typename GeometricSimplifiableComplex::Root_vertex_handle Root_vertex_handle; - typedef typename GeometricSimplifiableComplex::Edge_handle Edge_handle; - typedef typename GeometricSimplifiableComplex::Graph_vertex Graph_vertex; - typedef typename GeometricSimplifiableComplex::Graph_edge Graph_edge; - typedef typename GeometricSimplifiableComplex::Point Point; + typedef typename GeometricSimplifiableComplex::Edge_handle Edge_handle; + typedef typename GeometricSimplifiableComplex::Graph_vertex Graph_vertex; + typedef typename GeometricSimplifiableComplex::Graph_edge Graph_edge; + typedef typename GeometricSimplifiableComplex::Point Point; + Edge_profile(GeometricSimplifiableComplex& complex, Edge_handle edge) : complex_(complex), edge_handle_(edge), + v0_(complex_.first_vertex(edge_handle_)), v1_(complex_.second_vertex(edge_handle_)) { + assert(complex_.get_address(complex_[edge_handle_].first())); + assert(complex_.get_address(complex_[edge_handle_].second())); + assert(complex_.contains_edge(v0_handle(), v1_handle())); + assert(v0_handle() != v1_handle()); + } + virtual ~Edge_profile() { } + GeometricSimplifiableComplex& complex() const { + return complex_; + } - Edge_profile( GeometricSimplifiableComplex& complex,Edge_handle edge):complex_(complex),edge_handle_(edge), - v0_(complex_.first_vertex(edge_handle_)),v1_(complex_.second_vertex(edge_handle_)) -{ - assert(complex_.get_address(complex_[edge_handle_].first())); - assert(complex_.get_address(complex_[edge_handle_].second())); - assert(complex_.contains_edge(v0_handle(),v1_handle())); - assert(v0_handle() != v1_handle()); -} + Edge_handle edge_handle() const { + return edge_handle_; + } - virtual ~Edge_profile(){ } + Graph_edge& edge() const { + return complex_[edge_handle_]; + } + Graph_vertex& v0() const { + return complex_[v0_handle()]; + } - GeometricSimplifiableComplex& complex() const { - return complex_; - } + Graph_vertex& v1() const { + return complex_[v1_handle()]; + } - Edge_handle edge_handle() const{ - return edge_handle_; - } + Vertex_handle v0_handle() const { + return v0_; + // Root_vertex_handle root = complex_[edge_handle_].first(); + // assert(complex_.get_address(root)); + // return *complex_.get_address(root); + } - Graph_edge& edge() const{ - return complex_[edge_handle_]; - } + Vertex_handle v1_handle() const { + return v1_; + // Root_vertex_handle root = complex_[edge_handle_].second(); + // assert(complex_.get_address(root)); + // return *complex_.get_address(root); + } + const Point& p0() const { + return complex_.point(v0_handle()); + } - Graph_vertex& v0() const{return complex_[v0_handle()];} - Graph_vertex& v1() const{return complex_[v1_handle()];} + const Point& p1() const { + return complex_.point(v1_handle()); + } + friend std::ostream& operator<<(std::ostream& o, const Edge_profile & v) { + o << "v0:" << v.v0_handle() << " v1:" << v.v1_handle(); + return o; + } - Vertex_handle v0_handle() const{ - return v0_; -// Root_vertex_handle root = complex_[edge_handle_].first(); -// assert(complex_.get_address(root)); -// return *complex_.get_address(root); - } + private: + GeometricSimplifiableComplex& complex_; - Vertex_handle v1_handle() const{ - return v1_; -// Root_vertex_handle root = complex_[edge_handle_].second(); -// assert(complex_.get_address(root)); -// return *complex_.get_address(root); - } + Edge_handle edge_handle_; - const Point& p0() const {return complex_.point(v0_handle());} + Vertex_handle v0_; - const Point& p1() const {return complex_.point(v1_handle());} - - friend std::ostream& operator << (std::ostream& o, const Edge_profile & v){ - o << "v0:"< class Edge_profile_factory { + public: + typedef typename EdgeProfile::Edge_handle Edge_handle_; + typedef typename EdgeProfile::Complex Complex_; -}; + virtual EdgeProfile make_profile( + Complex_& complex, + Edge_handle_ edge) const { + return EdgeProfile(complex, edge); + } -template class Edge_profile_factory{ -public: - typedef typename EdgeProfile::Edge_handle Edge_handle_; - typedef typename EdgeProfile::Complex Complex_; - virtual EdgeProfile make_profile( - Complex_& complex, - Edge_handle_ edge) const{ - return EdgeProfile(complex,edge); - } - - virtual ~Edge_profile_factory(){}; + virtual ~Edge_profile_factory() { } }; - } // namespace contraction -} // namespace GUDHI +} // namespace Gudhi -#endif /* GUDHI_EDGE_PROFILE_H_ */ +#endif // CONTRACTION_EDGE_PROFILE_H_ diff --git a/src/Contraction/include/gudhi/Edge_contraction.h b/src/Contraction/include/gudhi/Edge_contraction.h index 2c254710..dfce8d1b 100644 --- a/src/Contraction/include/gudhi/Edge_contraction.h +++ b/src/Contraction/include/gudhi/Edge_contraction.h @@ -20,21 +20,21 @@ * along with this program. If not, see . */ -#ifndef GUDHI_EDGE_CONTRACTION_H_ -#define GUDHI_EDGE_CONTRACTION_H_ +#ifndef EDGE_CONTRACTION_H_ +#define EDGE_CONTRACTION_H_ -#include "gudhi/Skeleton_blocker_contractor.h" -#include "gudhi/Contraction/policies/Edge_length_cost.h" -#include "gudhi/Contraction/policies/First_vertex_placement.h" -#include "gudhi/Contraction/policies/Valid_contraction_policy.h" -#include "gudhi/Contraction/policies/Dummy_valid_contraction.h" -#include "gudhi/Contraction/policies/Link_condition_valid_contraction.h" -#include "gudhi/Utils.h" +#include +#include +#include +#include +#include +#include +#include +namespace Gudhi { -namespace Gudhi{ -namespace contraction{ +namespace contraction { /** \defgroup contr Contraction @@ -120,9 +120,9 @@ while ensuring its homotopy type is preserved during the contraction (edge are c \code{.cpp} #include #include -#include "gudhi/Edge_contraction.h" -#include "gudhi/Skeleton_blocker.h" -#include "gudhi/Off_reader.h" +#include +#include +#include using namespace std; @@ -228,9 +228,9 @@ Time to simplify and enumerate simplices: \copyright GNU General Public License v3. \verbatim Contact: David Salinas, david.salinas@inria.fr \endverbatim */ -/** @} */ // end defgroup +/** @} */ // end defgroup +} // namespace contraction -} -} +} // namespace Gudhi -#endif /* GUDHI_EDGE_CONTRACTION_H_ */ +#endif // EDGE_CONTRACTION_H_ diff --git a/src/Contraction/include/gudhi/Skeleton_blocker_contractor.h b/src/Contraction/include/gudhi/Skeleton_blocker_contractor.h index dcc05c22..2759b540 100644 --- a/src/Contraction/include/gudhi/Skeleton_blocker_contractor.h +++ b/src/Contraction/include/gudhi/Skeleton_blocker_contractor.h @@ -20,80 +20,69 @@ * along with this program. If not, see . */ -#ifndef GUDHI_SKELETON_BLOCKER_CONTRACTOR_H_ -#define GUDHI_SKELETON_BLOCKER_CONTRACTOR_H_ - -#include -#include +#ifndef SKELETON_BLOCKER_CONTRACTOR_H_ +#define SKELETON_BLOCKER_CONTRACTOR_H_ // todo remove the queue to be independent from cgald -#include "gudhi/Contraction/CGAL_queue/Modifiable_priority_queue.h" +#include +#include +#include +#include +#include +#include +#include +#include // xxx remove +#include // xxx remove +#include -#include -#include -#include +#include +#include -#include "gudhi/Contraction/Edge_profile.h" -#include "gudhi/Contraction/policies/Cost_policy.h" -#include "gudhi/Contraction/policies/Edge_length_cost.h" -#include "gudhi/Contraction/policies/Placement_policy.h" -#include "gudhi/Contraction/policies/First_vertex_placement.h" - -#include "gudhi/Contraction/policies/Valid_contraction_policy.h" -#include "gudhi/Contraction/policies/Dummy_valid_contraction.h" //xxx remove -#include "gudhi/Contraction/policies/Link_condition_valid_contraction.h" //xxx remove - -#include "gudhi/Contraction/policies/Contraction_visitor.h" - -#include "gudhi/Skeleton_blocker/Skeleton_blocker_complex_visitor.h" +#include +#include -#include "gudhi/Utils.h" +#include +#include +#include +#include // for pair +#include -namespace Gudhi{ +namespace Gudhi { namespace contraction { - - - template -Placement_policy* make_first_vertex_placement(){ - return new First_vertex_placement(); +Placement_policy* make_first_vertex_placement() { + return new First_vertex_placement(); } template -Valid_contraction_policy* make_link_valid_contraction(){ - return new Link_condition_valid_contraction(); +Valid_contraction_policy* make_link_valid_contraction() { + return new Link_condition_valid_contraction(); } - /** -*@brief Visitor to remove popable blockers after an edge contraction. -*/ + *@brief Visitor to remove popable blockers after an edge contraction. + */ template -class Contraction_visitor_remove_popable : public Contraction_visitor{ -public: - typedef typename Profile::Point Point; - typedef typename Profile::Complex Complex; - typedef typename Complex::Vertex_handle Vertex_handle; - - void on_contracted(const Profile &profile, boost::optional< Point > placement) override{ - profile.complex().remove_all_popable_blockers(profile.v0_handle()); - } +class Contraction_visitor_remove_popable : public Contraction_visitor { + public: + typedef typename Profile::Point Point; + typedef typename Profile::Complex Complex; + typedef typename Complex::Vertex_handle Vertex_handle; + + void on_contracted(const Profile &profile, boost::optional< Point > placement) override { + profile.complex().remove_all_popable_blockers(profile.v0_handle()); + } }; template -Contraction_visitor* make_remove_popable_blockers_visitor(){ - return new Contraction_visitor_remove_popable(); +Contraction_visitor* make_remove_popable_blockers_visitor() { + return new Contraction_visitor_remove_popable(); } - - - - - /** *@class Skeleton_blocker_contractor *@brief Class that allows to contract iteratively edges of a simplicial complex. @@ -110,519 +99,489 @@ Contraction_visitor* make_remove_popable_blockers_visitor(){ * a topological condition (link condition) or a geometrical condition (normals messed up). * */ -template< -class GeometricSimplifiableComplex, -class EdgeProfile = Edge_profile -> -class Skeleton_blocker_contractor : private skbl::Dummy_complex_visitor{ - - GeometricSimplifiableComplex& complex_; - -public: - typedef typename GeometricSimplifiableComplex::Graph_vertex Graph_vertex; - typedef typename GeometricSimplifiableComplex::Vertex_handle Vertex_handle; - typedef typename GeometricSimplifiableComplex::Simplex_handle Simplex_handle; - typedef typename GeometricSimplifiableComplex::Simplex_handle_iterator Simplex_handle_iterator; - - - - typedef typename GeometricSimplifiableComplex::Root_vertex_handle Root_vertex_handle; - - typedef typename GeometricSimplifiableComplex::Graph_edge Graph_edge; - typedef typename GeometricSimplifiableComplex::Edge_handle Edge_handle; - typedef typename GeometricSimplifiableComplex::Point Point; - - typedef EdgeProfile Profile; - - - typedef Cost_policy Cost_policy_; - typedef Placement_policy Placement_policy_; - typedef Valid_contraction_policy Valid_contraction_policy_; - typedef Contraction_visitor Contraction_visitor_; - typedef Edge_profile_factory Edge_profile_factory_; +template> +class Skeleton_blocker_contractor : private skbl::Dummy_complex_visitor< +typename GeometricSimplifiableComplex::Vertex_handle> { + GeometricSimplifiableComplex& complex_; + public: + typedef typename GeometricSimplifiableComplex::Graph_vertex Graph_vertex; + typedef typename GeometricSimplifiableComplex::Vertex_handle Vertex_handle; + typedef typename GeometricSimplifiableComplex::Simplex_handle Simplex_handle; + typedef typename GeometricSimplifiableComplex::Simplex_handle_iterator Simplex_handle_iterator; - typedef boost::optional Cost_type; - typedef boost::optional Placement_type ; - typedef size_t size_type; + typedef typename GeometricSimplifiableComplex::Root_vertex_handle Root_vertex_handle; - typedef Skeleton_blocker_contractor Self ; + typedef typename GeometricSimplifiableComplex::Graph_edge Graph_edge; + typedef typename GeometricSimplifiableComplex::Edge_handle Edge_handle; + typedef typename GeometricSimplifiableComplex::Point Point; + typedef EdgeProfile Profile; -private: + typedef Cost_policy Cost_policy_; + typedef Placement_policy Placement_policy_; + typedef Valid_contraction_policy Valid_contraction_policy_; + typedef Contraction_visitor Contraction_visitor_; + typedef Edge_profile_factory Edge_profile_factory_; - struct Compare_id - { - Compare_id() : algorithm_(0) {} - Compare_id( Self const* aAlgorithm ) : algorithm_(aAlgorithm) {} - bool operator() ( Edge_handle a, Edge_handle b ) const - { - return algorithm_->get_undirected_edge_id(a) < algorithm_->get_undirected_edge_id(b); - } + typedef boost::optional Cost_type; + typedef boost::optional Placement_type; - Self const* algorithm_ ; - } ; + typedef size_t size_type; - struct Compare_cost - { - Compare_cost() : algorithm_(0) { - } + typedef Skeleton_blocker_contractor Self; - Compare_cost( Self const* aAlgorithm ) : algorithm_(aAlgorithm) { - } + private: + struct Compare_id { + Compare_id() : algorithm_(0) { } - bool operator() ( Edge_handle a, Edge_handle b ) const - { - // NOTE: A cost is an optional<> value. - // Absent optionals are ordered first; that is, "none < T" and "T > none" for any defined T != none. - // In consequence, edges with undefined costs will be promoted to the top of the priority queue and poped out first. - return algorithm_->get_data(a).cost() < algorithm_->get_data(b).cost(); - } + Compare_id(Self const* aAlgorithm) : algorithm_(aAlgorithm) { } - Self const* algorithm_ ; + bool operator()(Edge_handle a, Edge_handle b) const { + return algorithm_->get_undirected_edge_id(a) < algorithm_->get_undirected_edge_id(b); + } - } ; + Self const* algorithm_; + }; - struct Undirected_edge_id : boost::put_get_helper - { - typedef boost::readable_property_map_tag category; - typedef size_type value_type; - typedef size_type reference; - typedef Edge_handle key_type; + struct Compare_cost { + Compare_cost() : algorithm_(0) { } - Undirected_edge_id() : algorithm_(0) {} + Compare_cost(Self const* aAlgorithm) : algorithm_(aAlgorithm) { } - Undirected_edge_id( Self const* aAlgorithm ) : algorithm_(aAlgorithm) {} + bool operator()(Edge_handle a, Edge_handle b) const { + // NOTE: A cost is an optional<> value. + // Absent optionals are ordered first; that is, "none < T" and "T > none" for any defined T != none. + // In consequence, edges with undefined costs will be promoted to the top of the priority queue and popped out + // first. + return algorithm_->get_data(a).cost() < algorithm_->get_data(b).cost(); + } - size_type operator[] ( Edge_handle e ) const { return algorithm_->get_undirected_edge_id(e); } + Self const* algorithm_; + }; - Self const* algorithm_ ; - } ; + struct Undirected_edge_id : boost::put_get_helper { + typedef boost::readable_property_map_tag category; + typedef size_type value_type; + typedef size_type reference; + typedef Edge_handle key_type; - typedef CGAL::Modifiable_priority_queue PQ ; - typedef typename PQ::handle pq_handle ; + Undirected_edge_id() : algorithm_(0) { } + Undirected_edge_id(Self const* aAlgorithm) : algorithm_(aAlgorithm) { } - // An Edge_data is associated with EVERY edge in the complex (collapsible or not). - // It relates the edge with the PQ-handle needed to update the priority queue - // It also relates the edge with a policy-based cache - class Edge_data - { - public : + size_type operator[](Edge_handle e) const { + return algorithm_->get_undirected_edge_id(e); + } - Edge_data() : PQHandle_(),cost_() {} + Self const* algorithm_; + }; - Cost_type const& cost() const { return cost_ ; } - Cost_type & cost() { return cost_ ; } + typedef CGAL::Modifiable_priority_queue PQ; + typedef typename PQ::handle pq_handle; - pq_handle PQ_handle() const { return PQHandle_ ;} - bool is_in_PQ() const { return PQHandle_ != PQ::null_handle() ; } + // An Edge_data is associated with EVERY edge in the complex (collapsible or not). + // It relates the edge with the PQ-handle needed to update the priority queue + // It also relates the edge with a policy-based cache - void set_PQ_handle( pq_handle h ) { PQHandle_ = h ; } + class Edge_data { + public: + Edge_data() : PQHandle_(), cost_() { } - void reset_PQ_handle() { PQHandle_ = PQ::null_handle() ; } + Cost_type const& cost() const { + return cost_; + } - private: - pq_handle PQHandle_ ; - Cost_type cost_ ; + Cost_type & cost() { + return cost_; + } - } ; - typedef Edge_data* Edge_data_ptr ; - typedef boost::scoped_array Edge_data_array ; + pq_handle PQ_handle() const { + return PQHandle_; + } + bool is_in_PQ() const { + return PQHandle_ != PQ::null_handle(); + } - int get_undirected_edge_id ( Edge_handle edge ) const { - return complex_[edge].index() ; - } + void set_PQ_handle(pq_handle h) { + PQHandle_ = h; + } + void reset_PQ_handle() { + PQHandle_ = PQ::null_handle(); + } - const Edge_data& get_data ( Edge_handle edge ) const - { - return edge_data_array_[get_undirected_edge_id(edge)]; - } - - - Edge_data& get_data ( Edge_handle edge ) - { - return edge_data_array_[get_undirected_edge_id(edge)]; - } - - Cost_type get_cost(const Profile & profile) const{ - return (*cost_policy_)(profile,get_placement(profile)); - } - - Profile create_profile(Edge_handle edge) const{ - if(edge_profile_factory_) - return edge_profile_factory_->make_profile(complex_,edge); - else - return Profile(complex_,edge); - } - - - void insert_in_PQ( Edge_handle edge, Edge_data& data ) - { - data.set_PQ_handle(heap_PQ_->push(edge)); - ++current_num_edges_heap_; - } - - void update_in_PQ( Edge_handle edge, Edge_data& data ) - { - data.set_PQ_handle(heap_PQ_->update(edge,data.PQ_handle())) ; - } - - void remove_from_PQ( Edge_handle edge, Edge_data& data ) - { - data.set_PQ_handle(heap_PQ_->erase(edge,data.PQ_handle())); - --current_num_edges_heap_; - } - - boost::optional pop_from_PQ() { - boost::optional edge = heap_PQ_->extract_top(); - if ( edge ) - get_data(*edge).reset_PQ_handle(); - return edge ; - } - - - -private: - - /** - * @brief Collect edges. - * - * Iterates over all edges of the simplicial complex and - * 1) inserts them in the priority queue sorted according to the Cost policy. - * 2) set the id() field of each edge - */ - void collect_edges(){ - // - // Loop over all the edges in the complex in the heap - // - size_type size = complex_.num_edges(); - DBG("Collecting edges ..."); - DBGMSG("num edges :",size); - - edge_data_array_.reset( new Edge_data[size] ) ; - - heap_PQ_.reset( new PQ (size, Compare_cost(this), Undirected_edge_id(this) ) ) ; - - std::size_t id = 0 ; - - //xxx do a parralel for - for(auto edge : complex_.edge_range()){ - complex_[edge].index() = id++; - Profile const& profile = create_profile(edge); - Edge_data& data = get_data(edge); - data.cost() = get_cost(profile) ; - ++initial_num_edges_heap_; - insert_in_PQ(edge,data); - if(contraction_visitor_) contraction_visitor_->on_collected(profile,data.cost()); - } - - DBG("Edges collected."); - - } - - bool should_stop(double lCost,const Profile &profile) const{ - return false; - } - - boost::optional get_placement(const Profile& profile) const{ - return (*placement_policy_)(profile); - } - - bool is_contraction_valid( Profile const& profile, Placement_type placement ) const{ - if(!valid_contraction_policy_) return true; - return (*valid_contraction_policy_)(profile,placement); - } - - -public: - /** - * \brief Contract edges. - * - * While the heap is not empty, it extracts the edge with the minimum - * cost in the heap then try to contract it. - * It stops when the Stop policy says so or when the number of contractions - * given by 'num_max_contractions' is reached (if this number is positive). - */ - void contract_edges(int num_max_contractions=-1){ - - DBG("\n\nContract edges"); - int num_contraction = 0 ; - - bool unspecified_num_contractions = (num_max_contractions == -1); - // - // Pops and processes each edge from the PQ - // - boost::optional edge ; - while ( (edge = pop_from_PQ())&& ((num_contractionon_selected(profile,cost,0,0); - - DBGMSG("\n\n---- Pop edge - num vertices :",complex_.num_vertices()); - - if (cost){ - DBGMSG("sqrt(cost):",std::sqrt(*cost)); - if (should_stop(*cost,profile) ) - { - if(contraction_visitor_) contraction_visitor_->on_stop_condition_reached(); - DBG("should_stop"); - break ; - } - Placement_type placement = get_placement(profile); - if ( is_contraction_valid(profile,placement) && placement ) - { - DBG("contraction_valid"); - contract_edge(profile,placement); - ++ num_contraction; - } - else - { - DBG("contraction not valid"); - if(contraction_visitor_) contraction_visitor_->on_non_valid(profile); - } - } - else - DBG("uncomputable cost"); - } - if(contraction_visitor_) contraction_visitor_->on_stop_condition_reached(); - } - - - bool is_in_heap(Edge_handle edge) const{ - if(heap_PQ_->empty()) return false; - else{ - return edge_data_array_[get_undirected_edge_id(edge)].is_in_PQ(); - } - } - - bool is_heap_empty() const{ - return heap_PQ_->empty(); - } - - - /** - * @brief Returns an Edge_handle and a Placement_type. This pair consists in - * the edge with the lowest cost in the heap together with its placement. - * The returned value is initialized iff the heap is non-empty. - */ - boost::optional > top_edge(){ - boost::optional > res; - - if(!heap_PQ_->empty()) { - auto edge = heap_PQ_->top(); - Profile const& profile = create_profile(edge); - Placement_type placement = get_placement(profile); - res = make_pair(edge,placement); - DBGMSG("top edge:",complex_[edge]); - - } - return res; - } - - - /** - * @brief Constructor with default policies. - * - * @details The default cost, placement, valid and visitor policies - * are respectively : the edge length, the first point, the link condition - */ - Skeleton_blocker_contractor(GeometricSimplifiableComplex& complex) - :complex_(complex), - cost_policy_(new Edge_length_cost), - placement_policy_(new First_vertex_placement), - valid_contraction_policy_(new Link_condition_valid_contraction), - contraction_visitor_(new Contraction_visitor_()), - edge_profile_factory_(0), - initial_num_edges_heap_(0), - current_num_edges_heap_(0) - { - complex_.set_visitor(this); - if(contraction_visitor_) contraction_visitor_->on_started(complex); - collect_edges(); - } - - /** - * @brief Constructor with customed policies. - * @remark Policies destruction is handle by the class with smart pointers. - */ - Skeleton_blocker_contractor(GeometricSimplifiableComplex& complex, - Cost_policy_ *cost_policy, - Placement_policy_ * placement_policy = new First_vertex_placement, - Valid_contraction_policy_ * valid_contraction_policy = new Link_condition_valid_contraction, - Contraction_visitor_* contraction_visitor = new Contraction_visitor_(), - Edge_profile_factory_* edge_profile_factory = NULL - ): - complex_(complex), - cost_policy_(cost_policy), - placement_policy_(placement_policy), - valid_contraction_policy_(valid_contraction_policy), - contraction_visitor_(contraction_visitor), - edge_profile_factory_(edge_profile_factory), - initial_num_edges_heap_(0), - current_num_edges_heap_(0) - { - complex_.set_visitor(this); - if(contraction_visitor) contraction_visitor->on_started(complex); - collect_edges(); - } - - - ~Skeleton_blocker_contractor(){ - complex_.set_visitor(0); - } - -private: - - - void contract_edge(const Profile& profile, Placement_type placement ) { - if(contraction_visitor_) contraction_visitor_->on_contracting(profile,placement); - - assert(complex_.contains_vertex(profile.v0_handle())); - assert(complex_.contains_vertex(profile.v1_handle())); - assert(placement); - - profile.complex().point(profile.v0_handle()) = *placement; - - // remark : this is not necessary since v1 will be deactivated - // profile.complex().point(profile.v1_handle()) = *placement; - - complex_.contract_edge(profile.v0_handle(),profile.v1_handle()); - - assert(complex_.contains_vertex(profile.v0_handle())); - assert(!complex_.contains_vertex(profile.v1_handle())); - - update_changed_edges(); - - // the visitor could do something as complex_.remove_popable_blockers(); - if(contraction_visitor_) contraction_visitor_->on_contracted(profile,placement); - } - -private: - - // every time the visitor's method on_changed_edge is called, it adds an - // edge to changed_edges_ - std::vector< Edge_handle > changed_edges_; - - /** - * @brief we update the cost and the position in the heap of an edge that has - * been changed - */ - inline void on_changed_edge(Vertex_handle a,Vertex_handle b) override{ - boost::optional ab(complex_[std::make_pair(a,b)]); - assert(ab); - changed_edges_.push_back(*ab); - } - - void update_changed_edges(){ - //xxx do a parralel for - - DBG("update edges"); - - // sequential loop - for(auto ab : changed_edges_){ - //1-get the Edge_handle corresponding to ab - //2-change the data in mEdgeArray[ab.id()] - //3-update the heap - Edge_data& data = get_data(ab); - Profile const& profile = create_profile(ab); - data.cost() = get_cost(profile) ; - if ( data.is_in_PQ()){ - update_in_PQ(ab,data); - } - else{ - insert_in_PQ(ab,data); - } - } - changed_edges_.clear(); - } - - -private: - void on_remove_edge(Vertex_handle a,Vertex_handle b) override{ - - boost::optional ab((complex_[std::make_pair(a,b)])); - assert(ab); - Edge_data& lData = get_data(*ab) ; - if ( lData.is_in_PQ() ) - { - remove_from_PQ(*ab,lData) ; - } - } -private: - /** - * @brief Called when the edge 'ax' has been added while the edge 'bx' - * is still there but will be removed on next instruction. - * We assign the index of 'bx' to the edge index of 'ax' - */ - void on_swaped_edge(Vertex_handle a,Vertex_handle b,Vertex_handle x) override{ - boost::optional ax(complex_[std::make_pair(a,x)]); - boost::optional bx(complex_[std::make_pair(b,x)]); - assert(ax&& bx); - complex_[*ax].index() =complex_[*bx].index(); - } -private: - /** - * @brief Called when a blocker is removed. - * All the edges that passes through the blocker may be edge-contractible - * again and are thus reinserted in the heap. - */ - void on_delete_blocker(const Simplex_handle * blocker) override{ - // we go for all pairs xy that belongs to the blocker - // note that such pairs xy are necessarily edges of the complex - // by definition of a blocker - - // todo uniqument utile pour la link condition - // laisser à l'utilisateur? booleen update_heap_on_removed_blocker? - Simplex_handle blocker_copy(*blocker); - for (auto x = blocker_copy.begin(); x!= blocker_copy.end(); ++x){ - for(auto y=x ; ++y != blocker_copy.end(); ){ - auto edge_descr(complex_[std::make_pair(*x,*y)]); - assert(edge_descr); - Edge_data& data = get_data(*edge_descr); - Profile const& profile = create_profile(*edge_descr); - data.cost() = get_cost(profile) ; - - // If the edge is already in the heap - // its priority has not changed. - // If the edge is not present, we reinsert it - // remark : we could also reinsert the edge - // only if it is valid - if ( !data.is_in_PQ() ){ - insert_in_PQ(*edge_descr,data); - } - } - } - } - - -private: - std::shared_ptr cost_policy_; - std::shared_ptr placement_policy_; - std::shared_ptr valid_contraction_policy_; - std::shared_ptr contraction_visitor_; - - //in case the user wants to do something special when the edge profile - //are created (for instance add some info) - std::shared_ptr edge_profile_factory_; - Edge_data_array edge_data_array_ ; - - boost::scoped_ptr heap_PQ_ ; - int initial_num_edges_heap_; - int current_num_edges_heap_; - + private: + pq_handle PQHandle_; + Cost_type cost_; + }; + typedef Edge_data* Edge_data_ptr; + typedef boost::scoped_array Edge_data_array; + + int get_undirected_edge_id(Edge_handle edge) const { + return complex_[edge].index(); + } + + const Edge_data& get_data(Edge_handle edge) const { + return edge_data_array_[get_undirected_edge_id(edge)]; + } + + Edge_data& get_data(Edge_handle edge) { + return edge_data_array_[get_undirected_edge_id(edge)]; + } + + Cost_type get_cost(const Profile & profile) const { + return (*cost_policy_)(profile, get_placement(profile)); + } + + Profile create_profile(Edge_handle edge) const { + if (edge_profile_factory_) + return edge_profile_factory_->make_profile(complex_, edge); + else + return Profile(complex_, edge); + } + + void insert_in_PQ(Edge_handle edge, Edge_data& data) { + data.set_PQ_handle(heap_PQ_->push(edge)); + ++current_num_edges_heap_; + } + + void update_in_PQ(Edge_handle edge, Edge_data& data) { + data.set_PQ_handle(heap_PQ_->update(edge, data.PQ_handle())); + } + + void remove_from_PQ(Edge_handle edge, Edge_data& data) { + data.set_PQ_handle(heap_PQ_->erase(edge, data.PQ_handle())); + --current_num_edges_heap_; + } + + boost::optional pop_from_PQ() { + boost::optional edge = heap_PQ_->extract_top(); + if (edge) + get_data(*edge).reset_PQ_handle(); + return edge; + } + + private: + /** + * @brief Collect edges. + * + * Iterates over all edges of the simplicial complex and + * 1) inserts them in the priority queue sorted according to the Cost policy. + * 2) set the id() field of each edge + */ + void collect_edges() { + // + // Loop over all the edges in the complex in the heap + // + size_type size = complex_.num_edges(); + DBG("Collecting edges ..."); + DBGMSG("num edges :", size); + + edge_data_array_.reset(new Edge_data[size]); + + heap_PQ_.reset(new PQ(size, Compare_cost(this), Undirected_edge_id(this))); + + std::size_t id = 0; + + // xxx do a parralel for + for (auto edge : complex_.edge_range()) { + complex_[edge].index() = id++; + Profile const& profile = create_profile(edge); + Edge_data& data = get_data(edge); + data.cost() = get_cost(profile); + ++initial_num_edges_heap_; + insert_in_PQ(edge, data); + if (contraction_visitor_) contraction_visitor_->on_collected(profile, data.cost()); + } + + DBG("Edges collected."); + } + + bool should_stop(double lCost, const Profile &profile) const { + return false; + } + + boost::optional get_placement(const Profile& profile) const { + return (*placement_policy_)(profile); + } + + bool is_contraction_valid(Profile const& profile, Placement_type placement) const { + if (!valid_contraction_policy_) return true; + return (*valid_contraction_policy_)(profile, placement); + } + + + public: + /** + * \brief Contract edges. + * + * While the heap is not empty, it extracts the edge with the minimum + * cost in the heap then try to contract it. + * It stops when the Stop policy says so or when the number of contractions + * given by 'num_max_contractions' is reached (if this number is positive). + */ + void contract_edges(int num_max_contractions = -1) { + DBG("\n\nContract edges"); + int num_contraction = 0; + + bool unspecified_num_contractions = (num_max_contractions == -1); + // + // Pops and processes each edge from the PQ + // + boost::optional edge; + while ((edge = pop_from_PQ()) && ((num_contraction < num_max_contractions) || (unspecified_num_contractions))) { + Profile const& profile = create_profile(*edge); + Cost_type cost(get_data(*edge).cost()); + if (contraction_visitor_) contraction_visitor_->on_selected(profile, cost, 0, 0); + + DBGMSG("\n\n---- Pop edge - num vertices :", complex_.num_vertices()); + + if (cost) { + DBGMSG("sqrt(cost):", std::sqrt(*cost)); + if (should_stop(*cost, profile)) { + if (contraction_visitor_) contraction_visitor_->on_stop_condition_reached(); + DBG("should_stop"); + break; + } + Placement_type placement = get_placement(profile); + if (is_contraction_valid(profile, placement) && placement) { + DBG("contraction_valid"); + contract_edge(profile, placement); + ++num_contraction; + } else { + DBG("contraction not valid"); + if (contraction_visitor_) contraction_visitor_->on_non_valid(profile); + } + } else { + DBG("uncomputable cost"); + } + } + if (contraction_visitor_) contraction_visitor_->on_stop_condition_reached(); + } + + bool is_in_heap(Edge_handle edge) const { + if (heap_PQ_->empty()) { + return false; + } else { + return edge_data_array_[get_undirected_edge_id(edge)].is_in_PQ(); + } + } + + bool is_heap_empty() const { + return heap_PQ_->empty(); + } + + /** + * @brief Returns an Edge_handle and a Placement_type. This pair consists in + * the edge with the lowest cost in the heap together with its placement. + * The returned value is initialized iff the heap is non-empty. + */ + boost::optional > top_edge() { + boost::optional > res; + + if (!heap_PQ_->empty()) { + auto edge = heap_PQ_->top(); + Profile const& profile = create_profile(edge); + Placement_type placement = get_placement(profile); + res = std::make_pair(edge, placement); + DBGMSG("top edge:", complex_[edge]); + } + return res; + } + + /** + * @brief Constructor with default policies. + * + * @details The default cost, placement, valid and visitor policies + * are respectively : the edge length, the first point, the link condition + */ + Skeleton_blocker_contractor(GeometricSimplifiableComplex& complex) + : complex_(complex), + cost_policy_(new Edge_length_cost), + placement_policy_(new First_vertex_placement), + valid_contraction_policy_(new Link_condition_valid_contraction), + contraction_visitor_(new Contraction_visitor_()), + edge_profile_factory_(0), + initial_num_edges_heap_(0), + current_num_edges_heap_(0) { + complex_.set_visitor(this); + if (contraction_visitor_) contraction_visitor_->on_started(complex); + collect_edges(); + } + + /** + * @brief Constructor with customed policies. + * @remark Policies destruction is handle by the class with smart pointers. + */ + Skeleton_blocker_contractor(GeometricSimplifiableComplex& complex, + Cost_policy_ *cost_policy, + Placement_policy_ * placement_policy = new First_vertex_placement, + Valid_contraction_policy_ * valid_contraction_policy = + new Link_condition_valid_contraction, + Contraction_visitor_* contraction_visitor = new Contraction_visitor_(), + Edge_profile_factory_* edge_profile_factory = NULL) : + complex_(complex), + cost_policy_(cost_policy), + placement_policy_(placement_policy), + valid_contraction_policy_(valid_contraction_policy), + contraction_visitor_(contraction_visitor), + edge_profile_factory_(edge_profile_factory), + initial_num_edges_heap_(0), + current_num_edges_heap_(0) { + complex_.set_visitor(this); + if (contraction_visitor) contraction_visitor->on_started(complex); + collect_edges(); + } + + ~Skeleton_blocker_contractor() { + complex_.set_visitor(0); + } + + private: + void contract_edge(const Profile& profile, Placement_type placement) { + if (contraction_visitor_) contraction_visitor_->on_contracting(profile, placement); + + assert(complex_.contains_vertex(profile.v0_handle())); + assert(complex_.contains_vertex(profile.v1_handle())); + assert(placement); + + profile.complex().point(profile.v0_handle()) = *placement; + + // remark : this is not necessary since v1 will be deactivated + // profile.complex().point(profile.v1_handle()) = *placement; + + complex_.contract_edge(profile.v0_handle(), profile.v1_handle()); + + assert(complex_.contains_vertex(profile.v0_handle())); + assert(!complex_.contains_vertex(profile.v1_handle())); + + update_changed_edges(); + + // the visitor could do something as complex_.remove_popable_blockers(); + if (contraction_visitor_) contraction_visitor_->on_contracted(profile, placement); + } + + private: + // every time the visitor's method on_changed_edge is called, it adds an + // edge to changed_edges_ + std::vector< Edge_handle > changed_edges_; + + /** + * @brief we update the cost and the position in the heap of an edge that has + * been changed + */ + inline void on_changed_edge(Vertex_handle a, Vertex_handle b) override { + boost::optional ab(complex_[std::make_pair(a, b)]); + assert(ab); + changed_edges_.push_back(*ab); + } + + void update_changed_edges() { + // xxx do a parralel for + DBG("update edges"); + + // sequential loop + for (auto ab : changed_edges_) { + // 1-get the Edge_handle corresponding to ab + // 2-change the data in mEdgeArray[ab.id()] + // 3-update the heap + Edge_data& data = get_data(ab); + Profile const& profile = create_profile(ab); + data.cost() = get_cost(profile); + if (data.is_in_PQ()) { + update_in_PQ(ab, data); + } else { + insert_in_PQ(ab, data); + } + } + changed_edges_.clear(); + } + + + private: + void on_remove_edge(Vertex_handle a, Vertex_handle b) override { + boost::optional ab((complex_[std::make_pair(a, b)])); + assert(ab); + Edge_data& lData = get_data(*ab); + if (lData.is_in_PQ()) { + remove_from_PQ(*ab, lData); + } + } + + private: + /** + * @brief Called when the edge 'ax' has been added while the edge 'bx' + * is still there but will be removed on next instruction. + * We assign the index of 'bx' to the edge index of 'ax' + */ + void on_swaped_edge(Vertex_handle a, Vertex_handle b, Vertex_handle x) override { + boost::optional ax(complex_[std::make_pair(a, x)]); + boost::optional bx(complex_[std::make_pair(b, x)]); + assert(ax && bx); + complex_[*ax].index() = complex_[*bx].index(); + } + + private: + /** + * @brief Called when a blocker is removed. + * All the edges that passes through the blocker may be edge-contractible + * again and are thus reinserted in the heap. + */ + void on_delete_blocker(const Simplex_handle * blocker) override { + // we go for all pairs xy that belongs to the blocker + // note that such pairs xy are necessarily edges of the complex + // by definition of a blocker + + // todo uniqument utile pour la link condition + // laisser a l'utilisateur ? booleen update_heap_on_removed_blocker? + Simplex_handle blocker_copy(*blocker); + for (auto x = blocker_copy.begin(); x != blocker_copy.end(); ++x) { + for (auto y = x; ++y != blocker_copy.end();) { + auto edge_descr(complex_[std::make_pair(*x, *y)]); + assert(edge_descr); + Edge_data& data = get_data(*edge_descr); + Profile const& profile = create_profile(*edge_descr); + data.cost() = get_cost(profile); + + // If the edge is already in the heap + // its priority has not changed. + // If the edge is not present, we reinsert it + // remark : we could also reinsert the edge + // only if it is valid + if (!data.is_in_PQ()) { + insert_in_PQ(*edge_descr, data); + } + } + } + } + + + private: + std::shared_ptr cost_policy_; + std::shared_ptr placement_policy_; + std::shared_ptr valid_contraction_policy_; + std::shared_ptr contraction_visitor_; + + // in case the user wants to do something special when the edge profile + // are created (for instance add some info) + std::shared_ptr edge_profile_factory_; + Edge_data_array edge_data_array_; + + boost::scoped_ptr heap_PQ_; + int initial_num_edges_heap_; + int current_num_edges_heap_; }; } // namespace contraction -} // namespace GUDHI -#endif /* GUDHI_SKELETON_BLOCKER_CONTRACTOR_H_ */ +} // namespace Gudhi + +#endif // SKELETON_BLOCKER_CONTRACTOR_H_ diff --git a/src/cmake/modules/FindEigen3.cmake b/src/cmake/modules/FindEigen3.cmake new file mode 100644 index 00000000..70c07dfb --- /dev/null +++ b/src/cmake/modules/FindEigen3.cmake @@ -0,0 +1,86 @@ +# - Try to find Eigen3 lib +# +# This module supports requiring a minimum version, e.g. you can do +# find_package(Eigen3 3.1.2) +# to require version 3.1.2 or newer of Eigen3. +# +# Once done this will define +# +# EIGEN3_FOUND - system has eigen lib with correct version +# EIGEN3_INCLUDE_DIR - the eigen include directory +# EIGEN3_VERSION - eigen version + +# Copyright (c) 2006, 2007 Montel Laurent, +# Copyright (c) 2008, 2009 Gael Guennebaud, +# Copyright (c) 2009 Benoit Jacob +# Redistribution and use is allowed according to the terms of the 2-clause BSD license. + +include(FindPackageHandleStandardArgs) + +if(NOT Eigen3_FIND_VERSION) + if(NOT Eigen3_FIND_VERSION_MAJOR) + set(Eigen3_FIND_VERSION_MAJOR 2) + endif(NOT Eigen3_FIND_VERSION_MAJOR) + if(NOT Eigen3_FIND_VERSION_MINOR) + set(Eigen3_FIND_VERSION_MINOR 91) + endif(NOT Eigen3_FIND_VERSION_MINOR) + if(NOT Eigen3_FIND_VERSION_PATCH) + set(Eigen3_FIND_VERSION_PATCH 0) + endif(NOT Eigen3_FIND_VERSION_PATCH) + + set(Eigen3_FIND_VERSION "${Eigen3_FIND_VERSION_MAJOR}.${Eigen3_FIND_VERSION_MINOR}.${Eigen3_FIND_VERSION_PATCH}") +endif(NOT Eigen3_FIND_VERSION) + +macro(_eigen3_get_version) + file(READ "${EIGEN3_INCLUDE_DIR}/Eigen/src/Core/util/Macros.h" _eigen3_version_header) + + string(REGEX MATCH "define[ \t]+EIGEN_WORLD_VERSION[ \t]+([0-9]+)" _eigen3_world_version_match "${_eigen3_version_header}") + set(EIGEN3_WORLD_VERSION "${CMAKE_MATCH_1}") + string(REGEX MATCH "define[ \t]+EIGEN_MAJOR_VERSION[ \t]+([0-9]+)" _eigen3_major_version_match "${_eigen3_version_header}") + set(EIGEN3_MAJOR_VERSION "${CMAKE_MATCH_1}") + string(REGEX MATCH "define[ \t]+EIGEN_MINOR_VERSION[ \t]+([0-9]+)" _eigen3_minor_version_match "${_eigen3_version_header}") + set(EIGEN3_MINOR_VERSION "${CMAKE_MATCH_1}") + + set(EIGEN3_VERSION ${EIGEN3_WORLD_VERSION}.${EIGEN3_MAJOR_VERSION}.${EIGEN3_MINOR_VERSION}) +endmacro(_eigen3_get_version) + +set(EIGEN3_USE_FILE "UseEigen3") + +if (EIGEN3_INCLUDE_DIR) + + if (EXISTS ${EIGEN3_INCLUDE_DIR}/signature_of_eigen3_matrix_library) + # in cache already and valid + _eigen3_get_version() + set(EIGEN3_FOUND ${EIGEN3_VERSION_OK}) + + find_package_handle_standard_args(Eigen3 + REQUIRED_VARS EIGEN3_INCLUDE_DIR + VERSION_VAR EIGEN3_VERSION) + + else() + message(STATUS "Eigen3 path specified in cmake variable EIGEN3_INCLUDE_DIR is " + "set to ${EIGEN3_INCLUDE_DIR}, but that path does not contains the file " + "signature_of_eigen3_matrix_library and is considered as invalid.") + endif() + + + +else (EIGEN3_INCLUDE_DIR) + + find_path(EIGEN3_INCLUDE_DIR NAMES signature_of_eigen3_matrix_library + HINTS ENV EIGEN3_INC_DIR + ENV EIGEN3_DIR + PATHS ${KDE4_INCLUDE_DIR} + PATH_SUFFIXES include eigen3 eigen + DOC "Directory containing the Eigen3 header files" + ) + + if(EIGEN3_INCLUDE_DIR) + _eigen3_get_version() + endif(EIGEN3_INCLUDE_DIR) + + find_package_handle_standard_args(Eigen3 + REQUIRED_VARS EIGEN3_INCLUDE_DIR + VERSION_VAR EIGEN3_VERSION) + +endif(EIGEN3_INCLUDE_DIR) diff --git a/src/cmake/modules/UseEigen3.cmake b/src/cmake/modules/UseEigen3.cmake new file mode 100644 index 00000000..e3ed18be --- /dev/null +++ b/src/cmake/modules/UseEigen3.cmake @@ -0,0 +1,9 @@ +# This module setups the compiler for using Eigen v3 library. +# It assumes that find_package(Eigen3) was already called. + + +include_directories( SYSTEM ${EIGEN3_INCLUDE_DIR} ) + +add_definitions(-DCGAL_EIGEN3_ENABLED) + +set (EIGEN3_SETUP TRUE) -- cgit v1.2.3