From 55c7181126aa7defce38c9b82872d14223d4c1dd Mon Sep 17 00:00:00 2001 From: Gard Spreemann Date: Tue, 7 Feb 2017 17:33:01 +0100 Subject: Initial import of upstream's 1.3.1. --- GudhUI/CMakeLists.txt | 68 ++++++ GudhUI/gui/KNearestNeighborsMenu.ui | 150 +++++++++++++ GudhUI/gui/MainWindow.cpp | 299 +++++++++++++++++++++++++ GudhUI/gui/MainWindow.h | 118 ++++++++++ GudhUI/gui/MenuEdgeContraction.ui | 118 ++++++++++ GudhUI/gui/Menu_edge_contraction.cpp | 97 ++++++++ GudhUI/gui/Menu_edge_contraction.h | 63 ++++++ GudhUI/gui/Menu_k_nearest_neighbors.cpp | 59 +++++ GudhUI/gui/Menu_k_nearest_neighbors.h | 51 +++++ GudhUI/gui/Menu_persistence.cpp | 53 +++++ GudhUI/gui/Menu_persistence.h | 51 +++++ GudhUI/gui/Menu_uniform_neighbors.cpp | 60 +++++ GudhUI/gui/Menu_uniform_neighbors.h | 51 +++++ GudhUI/gui/PersistenceMenu.ui | 139 ++++++++++++ GudhUI/gui/UniformNeighborsMenu.ui | 153 +++++++++++++ GudhUI/gui/gudhui.cpp | 38 ++++ GudhUI/gui/main_window.ui | 255 +++++++++++++++++++++ GudhUI/model/Complex_typedefs.h | 49 +++++ GudhUI/model/Model.h | 355 ++++++++++++++++++++++++++++++ GudhUI/todo.txt | 22 ++ GudhUI/utils/Bar_code_persistence.h | 90 ++++++++ GudhUI/utils/Critical_points.h | 132 +++++++++++ GudhUI/utils/Edge_collapsor.h | 97 ++++++++ GudhUI/utils/Edge_contractor.h | 97 ++++++++ GudhUI/utils/Furthest_point_epsilon_net.h | 132 +++++++++++ GudhUI/utils/Is_manifold.h | 103 +++++++++ GudhUI/utils/K_nearest_builder.h | 90 ++++++++ GudhUI/utils/Lloyd_builder.h | 91 ++++++++ GudhUI/utils/MClock.h | 70 ++++++ GudhUI/utils/Persistence_compute.h | 91 ++++++++ GudhUI/utils/Rips_builder.h | 69 ++++++ GudhUI/utils/UI_utils.h | 45 ++++ GudhUI/utils/Vertex_collapsor.h | 88 ++++++++ GudhUI/utils/homsimpl | Bin 0 -> 118624 bytes GudhUI/view/Color.h | 35 +++ GudhUI/view/FirstCoordProjector.h | 42 ++++ GudhUI/view/Projector3D.h | 39 ++++ GudhUI/view/View_parameter.h | 151 +++++++++++++ GudhUI/view/Viewer.cpp | 186 ++++++++++++++++ GudhUI/view/Viewer.h | 120 ++++++++++ GudhUI/view/Viewer_instructor.cpp | 192 ++++++++++++++++ GudhUI/view/Viewer_instructor.h | 117 ++++++++++ 42 files changed, 4326 insertions(+) create mode 100644 GudhUI/CMakeLists.txt create mode 100644 GudhUI/gui/KNearestNeighborsMenu.ui create mode 100644 GudhUI/gui/MainWindow.cpp create mode 100644 GudhUI/gui/MainWindow.h create mode 100644 GudhUI/gui/MenuEdgeContraction.ui create mode 100644 GudhUI/gui/Menu_edge_contraction.cpp create mode 100644 GudhUI/gui/Menu_edge_contraction.h create mode 100644 GudhUI/gui/Menu_k_nearest_neighbors.cpp create mode 100644 GudhUI/gui/Menu_k_nearest_neighbors.h create mode 100644 GudhUI/gui/Menu_persistence.cpp create mode 100644 GudhUI/gui/Menu_persistence.h create mode 100644 GudhUI/gui/Menu_uniform_neighbors.cpp create mode 100644 GudhUI/gui/Menu_uniform_neighbors.h create mode 100644 GudhUI/gui/PersistenceMenu.ui create mode 100644 GudhUI/gui/UniformNeighborsMenu.ui create mode 100644 GudhUI/gui/gudhui.cpp create mode 100644 GudhUI/gui/main_window.ui create mode 100644 GudhUI/model/Complex_typedefs.h create mode 100644 GudhUI/model/Model.h create mode 100644 GudhUI/todo.txt create mode 100644 GudhUI/utils/Bar_code_persistence.h create mode 100644 GudhUI/utils/Critical_points.h create mode 100644 GudhUI/utils/Edge_collapsor.h create mode 100644 GudhUI/utils/Edge_contractor.h create mode 100644 GudhUI/utils/Furthest_point_epsilon_net.h create mode 100644 GudhUI/utils/Is_manifold.h create mode 100644 GudhUI/utils/K_nearest_builder.h create mode 100644 GudhUI/utils/Lloyd_builder.h create mode 100644 GudhUI/utils/MClock.h create mode 100644 GudhUI/utils/Persistence_compute.h create mode 100644 GudhUI/utils/Rips_builder.h create mode 100644 GudhUI/utils/UI_utils.h create mode 100644 GudhUI/utils/Vertex_collapsor.h create mode 100755 GudhUI/utils/homsimpl create mode 100644 GudhUI/view/Color.h create mode 100644 GudhUI/view/FirstCoordProjector.h create mode 100644 GudhUI/view/Projector3D.h create mode 100644 GudhUI/view/View_parameter.h create mode 100644 GudhUI/view/Viewer.cpp create mode 100644 GudhUI/view/Viewer.h create mode 100644 GudhUI/view/Viewer_instructor.cpp create mode 100644 GudhUI/view/Viewer_instructor.h (limited to 'GudhUI') diff --git a/GudhUI/CMakeLists.txt b/GudhUI/CMakeLists.txt new file mode 100644 index 00000000..a43294ea --- /dev/null +++ b/GudhUI/CMakeLists.txt @@ -0,0 +1,68 @@ +cmake_minimum_required(VERSION 2.8) +project(GudhUI) + +find_package(Qt4) +find_package(QGLViewer) +find_package(OpenGL) + +if ( CGAL_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND ) + set( QT_USE_QTXML TRUE ) + set( QT_USE_QTMAIN TRUE ) + set( QT_USE_QTSCRIPT TRUE ) + set( QT_USE_QTOPENGL TRUE ) + SET(Boost_USE_STATIC_LIBS ON) + SET(Boost_USE_MULTITHREAD OFF) + + include(${QT_USE_FILE}) + + include_directories (${QGLVIEWER_INCLUDE_DIR}) + include_directories(.) + + # qt : ui file, created wih Qt Designer ############### + set(CMAKE_CURRENT_BINARY_DIR "${CMAKE_CURRENT_SOURCE_DIR}/gui") + qt4_wrap_ui( uis + gui/main_window.ui + gui/MenuEdgeContraction.ui + gui/KNearestNeighborsMenu.ui + gui/UniformNeighborsMenu.ui + gui/PersistenceMenu.ui + ) + + set(CMAKE_CURRENT_BINARY_DIR "${CMAKE_CURRENT_SOURCE_DIR}/gui") + qt4_automoc( + gui/MainWindow.cpp + gui/Menu_k_nearest_neighbors.cpp + gui/Menu_uniform_neighbors.cpp + gui/Menu_edge_contraction.cpp + gui/Menu_persistence.cpp + ) + + set(CMAKE_CURRENT_BINARY_DIR "${CMAKE_CURRENT_SOURCE_DIR}/view") + qt4_automoc(view/Viewer_instructor.cpp + view/Viewer.cpp + ) + ##################################################################### + + add_executable ( GudhUI + gui/gudhui.cpp + gui/MainWindow.cpp + gui/Menu_k_nearest_neighbors.cpp + gui/Menu_uniform_neighbors.cpp + gui/Menu_edge_contraction.cpp + gui/Menu_persistence.cpp + view/Viewer_instructor.cpp + view/Viewer.cpp + ${uis} + ) + + target_link_libraries( GudhUI ${QT_LIBRARIES} ${QGLVIEWER_LIBRARIES} ) + target_link_libraries( GudhUI ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ) +if (TBB_FOUND) + target_link_libraries( GudhUI ${TBB_LIBRARIES}) +endif() + +############################################################################### + +else() + message(STATUS "NOTICE: GudhUI requires CGAL, the QGLViewer, OpenGL and Qt4, and will not be compiled.") +endif() diff --git a/GudhUI/gui/KNearestNeighborsMenu.ui b/GudhUI/gui/KNearestNeighborsMenu.ui new file mode 100644 index 00000000..472db48b --- /dev/null +++ b/GudhUI/gui/KNearestNeighborsMenu.ui @@ -0,0 +1,150 @@ + + + KNearestNeighborsMenu + + + + 0 + 0 + 298 + 209 + + + + k-nearest neighbors + + + + + 50 + 160 + 171 + 32 + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + 30 + 10 + 229 + 84 + + + + + QFormLayout::AllNonFixedFieldsGrow + + + + + k + + + + + + + 10000000 + + + 0 + + + + + + + Metric + + + + + + + + Ambient + + + + + Reduced Space + + + + + + + + + + 30 + 110 + 250 + 40 + + + + + + + Compute + + + + + + + auto update + + + true + + + + + + + + + + buttonBox + accepted() + KNearestNeighborsMenu + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + KNearestNeighborsMenu + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/GudhUI/gui/MainWindow.cpp b/GudhUI/gui/MainWindow.cpp new file mode 100644 index 00000000..779ccd33 --- /dev/null +++ b/GudhUI/gui/MainWindow.cpp @@ -0,0 +1,299 @@ +/* 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 . + */ + +#include "MainWindow.h" + +#include +#include +#include + +#include + +#include "gui/Menu_k_nearest_neighbors.h" +#include "gui/Menu_uniform_neighbors.h" +#include "gui/Menu_edge_contraction.h" +#include "gui/Menu_persistence.h" + +MainWindow::MainWindow(QWidget* parent) : + menu_k_nearest_neighbors_(new Menu_k_nearest_neighbors(this)), + menu_uniform_neighbors_(new Menu_uniform_neighbors(this)), + menu_edge_contraction_(new Menu_edge_contraction(this, model_)), + menu_persistence_(new Menu_persistence(this)) { + // #ifndef NDEBUG // catch nan + // feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW); + // #endif + + setupUi(this); + + viewer_instructor_ = new Viewer_instructor( + this, + this->viewer, + model_.complex_); + + connectActions(); + + update_view(); +} + +void +MainWindow::closeEvent(QCloseEvent *event) { + exit(0); +} + +void +MainWindow::connectActions() { + QObject::connect(this->actionLoad_complex, SIGNAL(triggered()), this, + SLOT(off_file_open())); + QObject::connect(this->actionLoad_points, SIGNAL(triggered()), this, + SLOT(off_points_open())); + QObject::connect(this->actionSave_complex, SIGNAL(triggered()), this, + SLOT(off_file_save())); + QObject::connect(this->actionSave_points, SIGNAL(triggered()), this, + SLOT(off_points_save())); + + QObject::connect(this->actionShow_graph_stats, SIGNAL(triggered()), this, + SLOT(show_graph_stats())); + QObject::connect(this->actionShow_complex_stats, SIGNAL(triggered()), this, + SLOT(show_complex_stats())); + QObject::connect(this->actionShow_complex_dimension, SIGNAL(triggered()), this, + SLOT(show_complex_dimension())); + + QObject::connect(this->actionUniform_proximity_graph, SIGNAL(triggered()), this, + SLOT(build_rips_menu())); + QObject::connect(this->actionK_nearest_neighbors_graph, SIGNAL(triggered()), this, + SLOT(build_k_nearest_neighbors_menu())); + + + QObject::connect(this->actionContract_edges, SIGNAL(triggered()), this, + SLOT(contract_edge_menu())); + + QObject::connect(this->actionCollapse_vertices, SIGNAL(triggered()), this, + SLOT(collapse_vertices())); + + QObject::connect(this->actionCollapse_edges, SIGNAL(triggered()), this, + SLOT(collapse_edges())); + + QObject::connect(this->actionNoise, SIGNAL(triggered()), this, + SLOT(uniform_noise())); + QObject::connect(this->actionLloyd, SIGNAL(triggered()), this, + SLOT(lloyd())); + + + // view + QObject::connect(this->actionPoints, SIGNAL(triggered()), this->viewer_instructor_, + SLOT(change_draw_vertices())); + QObject::connect(this->actionEdges, SIGNAL(triggered()), this->viewer_instructor_, + SLOT(change_draw_edges())); + QObject::connect(this->actionTriangles, SIGNAL(triggered()), this->viewer_instructor_, + SLOT(change_draw_triangles())); + + // topology + QObject::connect(this->actionShow_homology_group, SIGNAL(triggered()), this, + SLOT(show_homology_group())); + QObject::connect(this->actionEuler_characteristic, SIGNAL(triggered()), this, + SLOT(show_euler_characteristic())); + QObject::connect(this->actionPersistence, SIGNAL(triggered()), this, + SLOT(persistence_menu())); + QObject::connect(this->actionEstimate_topological_changes, SIGNAL(triggered()), this, + SLOT(critical_points_menu())); + QObject::connect(this->actionIs_manifold, SIGNAL(triggered()), this, + SLOT(is_manifold_menu())); + + + QObject::connect(this, SIGNAL(sceneChanged()), this->viewer_instructor_, + SLOT(sceneChanged())); +} + +void +MainWindow::init_view() const { + viewer_instructor_->initialize_bounding_box(); + viewer_instructor_->show_entire_scene(); + update_view(); +} + +void +MainWindow::update_view() const { + emit(sceneChanged()); +} + +/** + * open a file chooser to choose an off to load + */ +void +MainWindow::off_file_open() { + QString fileName = QFileDialog::getOpenFileName(this, tr("Open off File"), + "~/", tr("off files (*.off)")); + if (!fileName.isEmpty()) { + model_.off_file_open(fileName.toStdString()); + init_view(); + } +} + +void +MainWindow::off_points_open() { + QString fileName = QFileDialog::getOpenFileName(this, tr("Open points in a off file"), + "~/", tr("off files (*.off)")); + if (!fileName.isEmpty()) { + model_.off_points_open(fileName.toStdString()); + init_view(); + } +} + +/** + * open a file chooser to choose an off to save + */ +void +MainWindow::off_file_save() { + QString fileName = QFileDialog::getOpenFileName(this, tr("Save to off File"), + "~/", tr("off files (*.off)")); + if (!fileName.isEmpty()) { + model_.off_file_save(fileName.toStdString()); + } +} + +/** + * open a file chooser to choose an off to save + */ +void +MainWindow::off_points_save() { + QString fileName = QFileDialog::getOpenFileName(this, tr("Save to off File"), + "~/", tr("off files (*.off)")); + if (!fileName.isEmpty()) { + model_.off_points_save(fileName.toStdString()); + } +} + +void +MainWindow::show_graph_stats() { + model_.show_graph_stats(); +} + +void +MainWindow::show_complex_stats() { + model_.show_complex_stats(); +} + +void +MainWindow::show_complex_dimension() { + model_.show_complex_dimension(); +} + +void +MainWindow::build_rips_menu() { + menu_uniform_neighbors_->show(); +} + +void +MainWindow::build_rips(double alpha) { + model_.build_rips(alpha); + update_view(); +} + +void +MainWindow::build_k_nearest_neighbors_menu() { + menu_k_nearest_neighbors_->show(); +} + +void +MainWindow::build_k_nearest_neighbors(unsigned k) { + model_.build_k_nearest_neighbors(k); + update_view(); +} + +void +MainWindow::contract_edge_menu() { + menu_edge_contraction_->show(); +} + +void +MainWindow::contract_edges(unsigned num_collapses) { + std::cerr << "Collapse " << num_collapses << " vertices\n"; + model_.contract_edges(num_collapses); + update_view(); +} + +void +MainWindow::collapse_edges() { + model_.collapse_edges(model_.num_edges()); + update_view(); +} + +void +MainWindow::collapse_vertices() { + std::cerr << "Collapse vertices edges\n"; + model_.collapse_vertices(0); + update_view(); +} + +void +MainWindow::uniform_noise() { + bool ok; + double amplitude = QInputDialog::getDouble(this, tr("Uniform noise"), + tr("Amplitude:"), 0, 0, 10000, 3, &ok); + srand(time(NULL)); + if (ok) + model_.uniform_noise(amplitude); +} + +void +MainWindow::lloyd() { + // todo 1 ask lloyd parameters + model_.lloyd(0, 0); + update_view(); +} + +void +MainWindow::show_homology_group() { + model_.show_homology_group(); +} + +void +MainWindow::show_euler_characteristic() { + model_.show_euler_characteristic(); +} + +void +MainWindow::persistence_menu() { + menu_persistence_->show(); +} + +void +MainWindow::compute_persistence(int p, double threshold, int max_dim, double min_pers) { + model_.show_persistence(p, threshold, max_dim, min_pers); +} + +void +MainWindow::critical_points_menu() { + bool ok; + double max_length = QInputDialog::getDouble(this, tr("Maximal edge length for the Rips"), + tr("Maximal edge length:"), 0, 0, 10000, 3, &ok); + if (ok) + model_.show_critical_points(max_length); +} + +void +MainWindow::is_manifold_menu() { + model_.show_is_manifold(); +} + + +#include "MainWindow.moc" diff --git a/GudhUI/gui/MainWindow.h b/GudhUI/gui/MainWindow.h new file mode 100644 index 00000000..c8c3fcf6 --- /dev/null +++ b/GudhUI/gui/MainWindow.h @@ -0,0 +1,118 @@ +/* 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 GUI_MAINWINDOW_H_ +#define GUI_MAINWINDOW_H_ + +// Workaround for moc-qt4 not parsing boost headers +#include + +#include +#include "ui_main_window.h" +#include "model/Model.h" +#include "view/Viewer_instructor.h" + + +class Menu_k_nearest_neighbors; +class Menu_uniform_neighbors; +class Menu_edge_contraction; +class Menu_persistence; + +class MainWindow : public QMainWindow, public Ui::MainWindow { + Q_OBJECT + + private: + Model model_; + Viewer_instructor* viewer_instructor_; + Menu_k_nearest_neighbors* menu_k_nearest_neighbors_; + Menu_uniform_neighbors* menu_uniform_neighbors_; + Menu_edge_contraction* menu_edge_contraction_; + Menu_persistence* menu_persistence_; + + public: + MainWindow(QWidget* parent = 0); + void connectActions(); + + /** + * compute the bounding box and calls update view + */ + void init_view() const; + void update_view() const; + + + protected: + void closeEvent(QCloseEvent *event); + + void keyPressEvent(QKeyEvent *event) { } + + public: + public slots: + /** + * open a file chooser to choose an off to load + */ + void off_file_open(); + + void off_points_open(); + + /** + * open a file chooser to choose an off to save + */ + void off_file_save(); + void off_points_save(); + + void show_graph_stats(); + void show_complex_stats(); + void show_complex_dimension(); + + + void build_rips_menu(); + void build_rips(double alpha); + void build_k_nearest_neighbors_menu(); + void build_k_nearest_neighbors(unsigned k); + + + void contract_edge_menu(); + void contract_edges(unsigned num_collapses); + + + void collapse_vertices(); + void collapse_edges(); + + + void uniform_noise(); + void lloyd(); + + void show_homology_group(); + void show_euler_characteristic(); + void persistence_menu(); + void compute_persistence(int p, double threshold, int max_dim, double min_pers); + void critical_points_menu(); + void is_manifold_menu(); + + + public: + signals: + void sceneChanged() const; +}; + + +#endif // GUI_MAINWINDOW_H_ diff --git a/GudhUI/gui/MenuEdgeContraction.ui b/GudhUI/gui/MenuEdgeContraction.ui new file mode 100644 index 00000000..b1696431 --- /dev/null +++ b/GudhUI/gui/MenuEdgeContraction.ui @@ -0,0 +1,118 @@ + + + MenuEdgeContraction + + + + 0 + 0 + 362 + 209 + + + + Edge contraction + + + + + + 1 + + + 999999999 + + + 1 + + + + + + + false + + + Link condition + + + true + + + + + + + 1 + + + + + + + Policy + + + + + + + + Length_midpoint + + + + + + + + 0 + + + + + + + Number of vertices + + + + + + + Number of contractions + + + + + + + Number of vertices after + + + + + + + 0 + + + 100 + + + Qt::Horizontal + + + + + + + Perform collapse + + + + + + + + diff --git a/GudhUI/gui/Menu_edge_contraction.cpp b/GudhUI/gui/Menu_edge_contraction.cpp new file mode 100644 index 00000000..a679b0bf --- /dev/null +++ b/GudhUI/gui/Menu_edge_contraction.cpp @@ -0,0 +1,97 @@ +/* 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 GUI_MENU_EDGE_CONTRACTION_CPP_ +#define GUI_MENU_EDGE_CONTRACTION_CPP_ + +#include "Menu_edge_contraction.h" + +Menu_edge_contraction::Menu_edge_contraction(MainWindow* parent, const Model& model) : + parent_(parent), model_(model) { + setupUi(this); + connectActions(parent_); +} + +void Menu_edge_contraction::connectActions(MainWindow* parent) { + QObject::connect( + this->horizontalSlider, + SIGNAL(valueChanged(int)), + this, + SLOT(slider_value_changed(int))); + + + QObject::connect(this, SIGNAL(contract_edges(unsigned)), parent, SLOT(contract_edges(unsigned))); + + QObject::connect(this->pushButton_collapse, SIGNAL(clicked()), this, SLOT(send_contract_edges())); +} + +void Menu_edge_contraction::slider_value_changed(int new_slider_value) { + int num_collapses = + (horizontalSlider->value() == 1) ? 1 : horizontalSlider->value() * model_.num_vertices() / 100; + this->txt_nb_vertices->setNum(static_cast(model_.num_vertices())); + this->txt_nb_collapses->setNum(num_collapses); + this->spinBox_nb_remaining_vertices->setValue(model_.num_vertices() - num_collapses); +} + +void +Menu_edge_contraction::update_slider_value() { + int num_vertices = model_.num_vertices(); + int num_collapses = (horizontalSlider->value() == 1) ? 1 : horizontalSlider->value() * num_vertices / 100; + int horizontal_slider_position = num_vertices > 0 ? num_collapses / static_cast(num_vertices * 100) : 1; + horizontalSlider->setValue(horizontal_slider_position); +} + +void +Menu_edge_contraction::update_gui_numbers() { + update_slider_value(); + bool ok; + int num_collapses = this->txt_nb_collapses->text().toInt(&ok, 10); + if (!ok) return; + this->txt_nb_vertices->setNum(static_cast(model_.num_vertices())); + this->txt_nb_collapses->setNum(num_collapses); + this->spinBox_nb_remaining_vertices->setValue(model_.num_vertices() - num_collapses); +} + +void +Menu_edge_contraction::update_gui_numbers(int new_value) { + update_gui_numbers(); +} + +void +Menu_edge_contraction::send_contract_edges() { + emit(contract_edges(num_collapses())); + update_gui_numbers(); +} + +unsigned +Menu_edge_contraction::num_vertices() { + return model_.num_vertices(); +} + +unsigned +Menu_edge_contraction::num_collapses() { + return (horizontalSlider->value() == 1) ? 1 : horizontalSlider->value() * num_vertices() / 100; +} + +#include "Menu_edge_contraction.moc" + +#endif // GUI_MENU_EDGE_CONTRACTION_CPP_ diff --git a/GudhUI/gui/Menu_edge_contraction.h b/GudhUI/gui/Menu_edge_contraction.h new file mode 100644 index 00000000..08f0bf67 --- /dev/null +++ b/GudhUI/gui/Menu_edge_contraction.h @@ -0,0 +1,63 @@ +/* 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 GUI_MENU_EDGE_CONTRACTION_H_ +#define GUI_MENU_EDGE_CONTRACTION_H_ + +// Workaround for moc-qt4 not parsing boost headers +#include + +#include "gui/MainWindow.h" +#include "gui/ui_MenuEdgeContraction.h" + +#include "model/Model.h" + +class Menu_edge_contraction : public QDialog, public Ui::MenuEdgeContraction { + Q_OBJECT + + private: + MainWindow* parent_; + const Model& model_; + + void update_slider_value(); + + public: + Menu_edge_contraction(MainWindow* parent, const Model& model); + + void connectActions(MainWindow* parent); + + private: + unsigned num_vertices(); + unsigned num_collapses(); + + public slots: + void slider_value_changed(int new_slider_value); + void update_gui_numbers(); + void update_gui_numbers(int gui_numbers); + + void send_contract_edges(); + + signals: + void contract_edges(unsigned num_collapses); +}; + +#endif // GUI_MENU_EDGE_CONTRACTION_H_ diff --git a/GudhUI/gui/Menu_k_nearest_neighbors.cpp b/GudhUI/gui/Menu_k_nearest_neighbors.cpp new file mode 100644 index 00000000..e24865f2 --- /dev/null +++ b/GudhUI/gui/Menu_k_nearest_neighbors.cpp @@ -0,0 +1,59 @@ +/* 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 . + */ + +#include "Menu_k_nearest_neighbors.h" + +Menu_k_nearest_neighbors::Menu_k_nearest_neighbors(QMainWindow* parent_) + : parent(parent_) { + setupUi(this); + connectActions(parent_); +} + +void Menu_k_nearest_neighbors::connectActions(QMainWindow* parent) { + QObject::connect(this->pushButtonCompute, + SIGNAL(clicked()), + this, + SLOT(send_compute_k_nearest_neighbors())); + QObject::connect(this->spinBoxK, + SIGNAL(valueChanged(int)), + this, + SLOT(update_k(int))); + QObject::connect(this, + SIGNAL(compute_k_nearest_neighbors(unsigned)), + parent, + SLOT(build_k_nearest_neighbors(unsigned))); +} + +void Menu_k_nearest_neighbors::send_compute_k_nearest_neighbors() { + emit(compute_k_nearest_neighbors((unsigned) spinBoxK->value())); +} + +void Menu_k_nearest_neighbors::accept() { + send_compute_k_nearest_neighbors(); +} + +void Menu_k_nearest_neighbors::update_k(int new_k_value) { + if (checkBoxAutoUpdate->isChecked()) + emit(compute_k_nearest_neighbors((unsigned) spinBoxK->value())); +} + +#include "Menu_k_nearest_neighbors.moc" diff --git a/GudhUI/gui/Menu_k_nearest_neighbors.h b/GudhUI/gui/Menu_k_nearest_neighbors.h new file mode 100644 index 00000000..8088b768 --- /dev/null +++ b/GudhUI/gui/Menu_k_nearest_neighbors.h @@ -0,0 +1,51 @@ +/* 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 GUI_MENU_K_NEAREST_NEIGHBORS_H_ +#define GUI_MENU_K_NEAREST_NEIGHBORS_H_ + +#include +#include "gui/ui_KNearestNeighborsMenu.h" + +class QWidget; + +class Menu_k_nearest_neighbors : public QDialog, public Ui::KNearestNeighborsMenu { + Q_OBJECT + + private: + QMainWindow* parent; + + public: + Menu_k_nearest_neighbors(QMainWindow* parent_); + + void connectActions(QMainWindow* parent); + + public slots: + void send_compute_k_nearest_neighbors(); + void update_k(int k); + void accept(); + + signals: + void compute_k_nearest_neighbors(unsigned k); +}; + +#endif // GUI_MENU_K_NEAREST_NEIGHBORS_H_ diff --git a/GudhUI/gui/Menu_persistence.cpp b/GudhUI/gui/Menu_persistence.cpp new file mode 100644 index 00000000..016c076b --- /dev/null +++ b/GudhUI/gui/Menu_persistence.cpp @@ -0,0 +1,53 @@ +/* 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 . + * + */ + + +#include "Menu_persistence.h" + +Menu_persistence::Menu_persistence(QMainWindow* parent_) : parent(parent_) { + setupUi(this); + connectActions(parent_); +} + +void Menu_persistence::connectActions(QMainWindow* parent) { + QObject::connect(this, + SIGNAL(compute_persistence(int, double, int, double)), + parent, + SLOT(compute_persistence(int, double, int, double))); +} + +void Menu_persistence::send_compute_persistence() { + emit(compute_persistence(p_spinBox->value(), threshold_doubleSpinBox->value(), + maxdimension_spinBox->value(), minpersistence_doubleSpinBox->value())); +} + +void Menu_persistence::accept() { + send_compute_persistence(); +} + +// void Menu_persistence::compute_persistence(int p_fied,double threshold,int dim_max,double min_persistence) { +// if(checkBoxAutoUpdate->isChecked()) +// emit(compute_k_nearest_neighbors((unsigned)spinBoxK->value())); +// } + +#include "Menu_persistence.moc" diff --git a/GudhUI/gui/Menu_persistence.h b/GudhUI/gui/Menu_persistence.h new file mode 100644 index 00000000..8c4df158 --- /dev/null +++ b/GudhUI/gui/Menu_persistence.h @@ -0,0 +1,51 @@ +/* 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 GUI_MENU_PERSISTENCE_H_ +#define GUI_MENU_PERSISTENCE_H_ + +#include +#include "gui/ui_PersistenceMenu.h" + +class QWidget; + +class Menu_persistence : public QDialog, public Ui::PersistenceMenu { + Q_OBJECT + + private: + QMainWindow* parent; + + public: + Menu_persistence(QMainWindow* parent_); + + void connectActions(QMainWindow* parent); + + public slots: + void send_compute_persistence(); + void accept(); + + signals: + void compute_persistence(int p_fied, double threshold, int dim_max, double min_persistence); +}; + +#endif // GUI_MENU_PERSISTENCE_H_ diff --git a/GudhUI/gui/Menu_uniform_neighbors.cpp b/GudhUI/gui/Menu_uniform_neighbors.cpp new file mode 100644 index 00000000..20e4f98f --- /dev/null +++ b/GudhUI/gui/Menu_uniform_neighbors.cpp @@ -0,0 +1,60 @@ +/* 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 . + * + */ + +#include "Menu_uniform_neighbors.h" + +Menu_uniform_neighbors::Menu_uniform_neighbors(QMainWindow* parent_) : + parent(parent_) { + setupUi(this); + connectActions(parent_); +} + +void Menu_uniform_neighbors::connectActions(QMainWindow* parent) { + QObject::connect(this->pushButtonCompute, + SIGNAL(clicked()), + this, + SLOT(send_compute_uniform_neighbors())); + QObject::connect(this->doubleSpinBoxAlpha, + SIGNAL(valueChanged(double)), + this, + SLOT(update_alpha(double))); + QObject::connect(this, + SIGNAL(compute_uniform_neighbors(double)), + parent, + SLOT(build_rips(double))); +} + +void Menu_uniform_neighbors::send_compute_uniform_neighbors() { + emit(compute_uniform_neighbors(doubleSpinBoxAlpha->value())); +} + +void Menu_uniform_neighbors::accept() { + send_compute_uniform_neighbors(); +} + +void Menu_uniform_neighbors::update_alpha(double alpha) { + if (checkBoxAutoUpdate->isChecked()) + emit(compute_uniform_neighbors(doubleSpinBoxAlpha->value())); +} + +#include "Menu_uniform_neighbors.moc" diff --git a/GudhUI/gui/Menu_uniform_neighbors.h b/GudhUI/gui/Menu_uniform_neighbors.h new file mode 100644 index 00000000..0b6f65fe --- /dev/null +++ b/GudhUI/gui/Menu_uniform_neighbors.h @@ -0,0 +1,51 @@ +/* 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 GUI_MENU_UNIFORM_NEIGHBORS_H_ +#define GUI_MENU_UNIFORM_NEIGHBORS_H_ + +#include +#include "gui/ui_UniformNeighborsMenu.h" + +class Menu_uniform_neighbors : public QDialog, public Ui::UniformMenu { + Q_OBJECT + + private: + QMainWindow* parent; + + public: + Menu_uniform_neighbors(QMainWindow* parent_); + + void connectActions(QMainWindow* parent); + + public slots: + void send_compute_uniform_neighbors(); + void update_alpha(double alpha); + void accept(); + + signals: + void compute_uniform_neighbors(double alpha); +}; + + +#endif // GUI_MENU_UNIFORM_NEIGHBORS_H_ diff --git a/GudhUI/gui/PersistenceMenu.ui b/GudhUI/gui/PersistenceMenu.ui new file mode 100644 index 00000000..29327db2 --- /dev/null +++ b/GudhUI/gui/PersistenceMenu.ui @@ -0,0 +1,139 @@ + + + PersistenceMenu + + + + 0 + 0 + 354 + 275 + + + + Point cloud persistence + + + + + 20 + 23 + 318 + 226 + + + + + + + + + 2 + + + 2 + + + + + + + Coefficient Z/pZ + + + + + + + 9999 + + + 10 + + + + + + + Max dimension + + + + + + + 9999.000000000000000 + + + 1.000000000000000 + + + + + + + Max Rips offset + + + + + + + + + + Minimum Persistence + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + + buttonBox + accepted() + PersistenceMenu + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + PersistenceMenu + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/GudhUI/gui/UniformNeighborsMenu.ui b/GudhUI/gui/UniformNeighborsMenu.ui new file mode 100644 index 00000000..f8ef7a24 --- /dev/null +++ b/GudhUI/gui/UniformNeighborsMenu.ui @@ -0,0 +1,153 @@ + + + UniformMenu + + + + 0 + 0 + 292 + 209 + + + + Uniform neighbors (Rips) + + + + + 50 + 160 + 171 + 32 + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + 30 + 10 + 262 + 84 + + + + + QFormLayout::AllNonFixedFieldsGrow + + + + + alpha + + + + + + + Metric + + + + + + + + Ambient + + + + + Reduced Space + + + + + + + + 3 + + + 100000000.000000000000000 + + + 0.100000000000000 + + + + + + + + + 30 + 110 + 250 + 40 + + + + + + + Compute + + + + + + + auto update + + + true + + + + + + + + + + buttonBox + accepted() + UniformMenu + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + UniformMenu + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/GudhUI/gui/gudhui.cpp b/GudhUI/gui/gudhui.cpp new file mode 100644 index 00000000..276c4a5f --- /dev/null +++ b/GudhUI/gui/gudhui.cpp @@ -0,0 +1,38 @@ +/* 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 . + * + */ + +#include "MainWindow.h" +#include +#include + +int main(int argc, char** argv) { + QApplication application(argc, argv); + application.setOrganizationDomain("inria.fr"); + application.setOrganizationName("INRIA"); + application.setApplicationName("GudhUI"); + + MainWindow mw; + application.setQuitOnLastWindowClosed(false); + mw.show(); + return application.exec(); +} diff --git a/GudhUI/gui/main_window.ui b/GudhUI/gui/main_window.ui new file mode 100644 index 00000000..312480b6 --- /dev/null +++ b/GudhUI/gui/main_window.ui @@ -0,0 +1,255 @@ + + + MainWindow + + + + 0 + 0 + 861 + 880 + + + + GudhUI + + + QTabWidget::Rounded + + + + + + + + + false + + + + + + + + + + + 0 + 0 + 861 + 34 + + + + + File + + + + + + + + + Points + + + + + + Graph + + + + + + + + Complex + + + + + + + + + + View + + + + + + + + + Topology + + + + + + + + + + + + + + + + + + Load points + + + + + Load complex + + + + + Save points + + + + + Save complex + + + + + Noise + + + + + Lloyd + + + + + Uniform proximity graph + + + + + k-nearest neighbors graph + + + + + Show graph stats + + + + + Graph expansion + + + + + Delaunay from points + + + + + Contract edges + + + + + Collapse vertices + + + + + Collapse edges + + + + + Points + + + + + Edges + + + + + Triangles + + + + + Change projection + + + + + Show complex stats + + + + + Show complex dimension + + + + + Homology groups + + + + + Point cloud persistence + + + + + true + + + Euler characteristic + + + true + + + + + Homology groups + + + + + false + + + Rips critical points approximation + + + false + + + + + Is manifold + + + + + + Viewer + QWidget +
view/Viewer.h
+
+
+ + +
diff --git a/GudhUI/model/Complex_typedefs.h b/GudhUI/model/Complex_typedefs.h new file mode 100644 index 00000000..a4df2c94 --- /dev/null +++ b/GudhUI/model/Complex_typedefs.h @@ -0,0 +1,49 @@ +/* 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 MODEL_COMPLEX_TYPEDEFS_H_ +#define MODEL_COMPLEX_TYPEDEFS_H_ + +#include +#include + +#include +#include +#include + +struct Geometry_trait : public CGAL::Cartesian_d { + typedef CGAL::Cartesian::Point_3 Point_3; + typedef CGAL::Cartesian::Vector_3 Vector_3; + typedef CGAL::Point_d> Point; + typedef CGAL::Vector_d> Vector; +}; + +typedef Geometry_trait::Point Point; + +using namespace Gudhi; +using namespace Gudhi::skeleton_blocker; + +typedef Skeleton_blocker_simple_geometric_traits Complex_geometric_traits; +typedef Skeleton_blocker_geometric_complex< Complex_geometric_traits > Complex; + +#endif // MODEL_COMPLEX_TYPEDEFS_H_ diff --git a/GudhUI/model/Model.h b/GudhUI/model/Model.h new file mode 100644 index 00000000..1c39c0d7 --- /dev/null +++ b/GudhUI/model/Model.h @@ -0,0 +1,355 @@ +/* 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 MODEL_MODEL_H_ +#define MODEL_MODEL_H_ + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include "utils/UI_utils.h" +#include "utils/Lloyd_builder.h" +#include "utils/Rips_builder.h" +#include "utils/K_nearest_builder.h" +#include "utils/Vertex_collapsor.h" +#include "utils/Edge_collapsor.h" +#include "utils/Edge_contractor.h" +#include "utils/Persistence_compute.h" +#include "utils/Critical_points.h" +#include "utils/Is_manifold.h" + +#include "Complex_typedefs.h" + +template +class CGAL_geometric_flag_complex_wrapper { + Complex& complex_; + typedef typename Complex::Vertex_handle Vertex_handle; + typedef typename Complex::Point Point; + + const bool load_only_points_; + + public: + CGAL_geometric_flag_complex_wrapper(Complex& complex, bool load_only_points = false) : + complex_(complex), + load_only_points_(load_only_points) { } + + void init(int dim, int num_vertices, int num_max_faces, int num_edges) const { } + + void point(const std::vector& coords) { + Point p(coords.size(), coords.begin(), coords.end()); + complex_.add_vertex(p); + } + + void maximal_face(std::vector vertices) { + if (!load_only_points_) { + // std::cout << "size:" << vertices.size() << std::endl; + for (int i = 0; i < vertices.size(); ++i) + for (int j = i + 1; j < vertices.size(); ++j) + complex_.add_edge(Vertex_handle(vertices[i]), Vertex_handle(vertices[j])); + } + } + + void done() const { } +}; + +class Model { + public: + Complex complex_; + typedef Complex::Vertex_handle Vertex_handle; + + Model() : complex_() { } + + public: + void off_file_open(const std::string& name_file) { + UIDBGMSG("load off file", name_file); + complex_.clear(); + CGAL_geometric_flag_complex_wrapper read_wraper(complex_, false); + Gudhi::read_off(name_file, read_wraper); + } + + void off_points_open(const std::string& name_file) { + UIDBGMSG("load off points", name_file); + complex_.clear(); + CGAL_geometric_flag_complex_wrapper read_wraper(complex_, true); + Gudhi::read_off(name_file, read_wraper); + } + + void off_file_save(const std::string& name_file) { + UIDBG("save off file"); + UIDBG("save off off_points_save"); + std::ofstream file(name_file); + if (file.is_open()) { + file << "OFF\n"; + file << complex_.num_vertices() << " " << complex_.num_edges() << " 0\n"; + for (auto v : complex_.vertex_range()) { + const auto& pt(complex_.point(v)); + for (auto it = pt.cartesian_begin(); it != pt.cartesian_end(); ++it) + file << *it << " "; + file << std::endl; + } + for (auto e : complex_.edge_range()) + file << "2 " << complex_.first_vertex(e) << " " << complex_.second_vertex(e) << "\n"; + file.close(); + } else { + std::cerr << "Could not open file " << name_file << std::endl; + } + } + + void off_points_save(const std::string& name_file) { + UIDBG("save off off_points_save"); + std::ofstream file(name_file); + if (file.is_open()) { + file << "OFF\n"; + file << complex_.num_vertices() << " 0 0\n"; + for (auto v : complex_.vertex_range()) { + const auto& pt(complex_.point(v)); + for (auto it = pt.cartesian_begin(); it != pt.cartesian_end(); ++it) + file << *it << " "; + file << std::endl; + } + file.close(); + } else { + std::cerr << "Could not open file " << name_file << std::endl; + } + } + + // point sets operations + void uniform_noise(double amplitude) { + UIDBG("unif noise"); + for (auto v : complex_.vertex_range()) + complex_.point(v) = add_uniform_noise(complex_.point(v), amplitude); + } + + private: + Point add_uniform_noise(const Point& point, double amplitude) { + std::vector new_point(point.dimension()); + for (int i = 0; i < point.dimension(); ++i) { + new_point[i] = point[i] + (rand() % 2 - .5) * amplitude; + } + return Point(point.dimension(), new_point.begin(), new_point.end()); + } + + public: + void lloyd(int num_iterations, int num_closest_neighbors) { + UIDBG("lloyd"); + Lloyd_builder lloyd_builder(complex_, 1); + } + + double squared_eucl_distance(const Point& p1, const Point& p2) const { + return Geometry_trait::Squared_distance_d()(p1, p2); + } + + // complex operations from points + + void build_rips(double alpha) { + UIDBG("build_rips"); + Rips_builder rips_builder(complex_, alpha); + } + + void build_k_nearest_neighbors(unsigned k) { + UIDBG("build_k_nearest"); + complex_.keep_only_vertices(); + K_nearest_builder k_nearest_builder(complex_, k); + } + + void build_delaunay() { + UIDBG("build_delaunay"); + complex_.keep_only_vertices(); + } + + void contract_edges(unsigned num_contractions) { + Clock c; + Edge_contractor contractor(complex_, num_contractions); + std::cout << "Time to simplify: " << c.num_seconds() << "s" << std::endl; + } + + void collapse_vertices(unsigned num_collapses) { + auto old_num_vertices = complex_.num_vertices(); + Vertex_collapsor collapsor(complex_, complex_.num_vertices()); + UIDBGMSG("num vertices collapsed:", old_num_vertices - complex_.num_vertices()); + } + + void collapse_edges(unsigned num_collapses) { + Edge_collapsor collapsor(complex_, num_collapses); + } + + void show_graph_stats() { + std::cout << "++++++ Graph stats +++++++" << std::endl; + std::cout << "Num vertices : " << complex_.num_vertices() << std::endl; + std::cout << "Num edges : " << complex_.num_edges() << std::endl; + std::cout << "Num connected components : " << complex_.num_connected_components() << std::endl; + std::cout << "Min/avg/max degree : " << min_degree() << "/" << avg_degree() << "/" << max_degree() << std::endl; + std::cout << "Num connected components : " << complex_.num_connected_components() << std::endl; + std::cout << "Num connected components : " << complex_.num_connected_components() << std::endl; + std::cout << "+++++++++++++++++++++++++" << std::endl; + } + + private: + int min_degree() const { + int res = (std::numeric_limits::max)(); + for (auto v : complex_.vertex_range()) + res = (std::min)(res, complex_.degree(v)); + return res; + } + + int max_degree() const { + int res = 0; + for (auto v : complex_.vertex_range()) + res = (std::max)(res, complex_.degree(v)); + return res; + } + + int avg_degree() const { + int res = 0; + for (auto v : complex_.vertex_range()) + res += complex_.degree(v); + return res / complex_.num_vertices(); + } + + public: + void show_complex_stats() { + std::cout << "++++++ Mesh stats +++++++" << std::endl; + std::cout << "Num vertices : " << complex_.num_vertices() << std::endl; + std::cout << "Num edges : " << complex_.num_edges() << std::endl; + std::cout << "Num connected components : " << complex_.num_connected_components() << std::endl; + std::cout << "+++++++++++++++++++++++++" << std::endl; + } + + void show_complex_dimension() { + unsigned num_simplices = 0; + int euler = 0; + int dimension = 0; + Clock clock; + for (const auto &s : complex_.complex_simplex_range()) { + num_simplices++; + dimension = (std::max)(s.dimension(), dimension); + if (s.dimension() % 2 == 0) + euler += 1; + else + euler -= 1; + } + clock.end(); + std::cout << "++++++ Mesh dimension +++++++" << std::endl; + std::cout << "Dimension : " << dimension << std::endl; + std::cout << "Euler characteristic : " << euler << std::endl; + std::cout << "Num simplices : " << num_simplices << std::endl; + std::cout << "Total time: " << clock << std::endl; + std::cout << "Time per simplex: " << clock.num_seconds() / num_simplices << " s" << std::endl; + std::cout << "+++++++++++++++++++++++++" << std::endl; + } + + void show_homology_group() { +#ifdef _WIN32 + std::cout << "Works only on linux x64 for the moment\n"; +#else + Clock clock; + run_chomp(); + clock.end(); +#endif + } + + void show_euler_characteristic() { + unsigned num_simplices = 0; + int euler = 0; + int dimension = 0; + for (const auto &s : complex_.complex_simplex_range()) { + num_simplices++; + dimension = (std::max)(s.dimension(), dimension); + if (s.dimension() % 2 == 0) + euler += 1; + else + euler -= 1; + } + std::cout << "Saw " << num_simplices << " simplices with maximum dimension " << dimension << std::endl; + std::cout << "The euler characteristic is : " << euler << std::endl; + } + + void show_persistence(int p, double threshold, int max_dim, double min_pers) { + Persistence_compute persistence(complex_, std::cout, Persistence_params(p, threshold, max_dim, min_pers)); + } + + void show_critical_points(double max_distance) { + Critical_points critical_points(complex_, std::cout, max_distance); + } + + void show_is_manifold() { + unsigned dim; + bool is_manifold; + Is_manifold test_manifold(complex_, dim, is_manifold); + + if (is_manifold) { + std::cout << "The complex is a " << dim << "-manifold\n"; + } else { + if (dim < 4) { + std::cout << "The complex has dimension greater than " << dim << " and is not a manifold\n"; + } else { + std::cout << "The complex has dimension>=4 and may or may not be a manifold\n"; + } + } + } + + private: + void run_chomp() { + save_complex_in_file_for_chomp(); + std::cout << "Call CHOMP library\n"; + int returnValue = system("utils/homsimpl chomp.sim"); + std::cout << "CHOMP returns" << returnValue << std::endl; + } + + void save_complex_in_file_for_chomp() { + std::ofstream file; + file.open("chomp.sim"); + for (const auto &s : complex_.complex_simplex_range()) { + bool first = true; + file << "("; + for (auto x : s) { + if (first) + first = false; + else + file << ","; + file << x; + } + file << ")\n"; + } + } + + public: + unsigned num_vertices() const { + return complex_.num_vertices(); + } + + unsigned num_edges() const { + return complex_.num_edges(); + } +}; + +#endif // MODEL_MODEL_H_ diff --git a/GudhUI/todo.txt b/GudhUI/todo.txt new file mode 100644 index 00000000..19d99a77 --- /dev/null +++ b/GudhUI/todo.txt @@ -0,0 +1,22 @@ +-- general + +o bug avec kreanrest neighbors lorsqu on baisse k après contraction après collapse vertices + +o clarify visitor sk_bl + + + +-- ui + +x points dimension arbitraire +x contractions + + +x faire le lien MainWindow - Model + + + + +-- bug +x bug ordre contraction -> just that first vertex placement dont work great +x pb construction rips diff --git a/GudhUI/utils/Bar_code_persistence.h b/GudhUI/utils/Bar_code_persistence.h new file mode 100644 index 00000000..b527d684 --- /dev/null +++ b/GudhUI/utils/Bar_code_persistence.h @@ -0,0 +1,90 @@ +#include // isfinite + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include // NaN, infinity +#include // for pair +#include + +#ifndef UTILS_BAR_CODE_PERSISTENCE_H_ +#define UTILS_BAR_CODE_PERSISTENCE_H_ + +class Bar_code_persistence { + private: + typedef std::vector> Persistence; + Persistence persistence_vector; + double min_birth; + double max_death; + + public: + Bar_code_persistence() + : min_birth(std::numeric_limits::quiet_NaN()), + max_death(std::numeric_limits::quiet_NaN()) { } + + void insert(double birth, double death) { + persistence_vector.push_back(std::make_pair(birth, death)); + if (std::isfinite(birth)) { + if ((birth < min_birth) || (std::isnan(min_birth))) + min_birth = birth; + if ((birth > max_death) || (std::isnan(max_death))) + max_death = birth; + } + if (std::isfinite(death)) + if ((death > max_death) || (std::isnan(max_death))) + max_death = death; + } + + void show(const std::string& window_title) { + // Create a view, put a scene in it + QGraphicsView * view = new QGraphicsView(); + QGraphicsScene * scene = new QGraphicsScene(); + view->setScene(scene); + double ratio = 600.0 / (max_death - min_birth); + // std::cout << "min_birth=" << min_birth << " - max_death=" << max_death << " - ratio=" << ratio << std::endl; + + double height = 0.0, birth = 0.0, death = 0.0; + int pers_num = 1; + for (auto& persistence : persistence_vector) { + height = 5.0 * pers_num; + // std::cout << "[" << pers_num << "] birth=" << persistence.first << " - death=" << persistence.second << std::endl; + if (std::isfinite(persistence.first)) + birth = ((persistence.first - min_birth) * ratio) + 50.0; + else + birth = 0.0; + + if (std::isfinite(persistence.second)) + death = ((persistence.second - min_birth) * ratio) + 50.0; + else + death = 700.0; + + scene->addLine(birth, height, death, height, QPen(Qt::blue, 2)); + pers_num++; + } + height += 10.0; + // scale line + scene->addLine(0, height, 700.0, height, QPen(Qt::black, 1)); + int modulo = 0; + for (double scale = 50.0; scale < 700.0; scale += 50.0) { + modulo++; + // scale small dash + scene->addLine(scale, height - 3.0, scale, height + 3.0, QPen(Qt::black, 1)); + // scale text + QString scale_value = QString::number(((scale - 50.0) / ratio) + min_birth); + QGraphicsTextItem* dimText = scene->addText(scale_value, QFont("Helvetica", 8)); + dimText->setPos(scale - (3.0 * scale_value.size()), height + 9.0 * (modulo % 2)); + } + view->setWindowTitle(window_title.c_str()); + // Show the view + view->show(); + } +}; + +#endif // UTILS_BAR_CODE_PERSISTENCE_H_ diff --git a/GudhUI/utils/Critical_points.h b/GudhUI/utils/Critical_points.h new file mode 100644 index 00000000..3021a5fe --- /dev/null +++ b/GudhUI/utils/Critical_points.h @@ -0,0 +1,132 @@ +/* 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 UTILS_CRITICAL_POINTS_H_ +#define UTILS_CRITICAL_POINTS_H_ + +#include +#include // for pair<> +#include // for sort + +#include "utils/Edge_contractor.h" + +/** + * Iteratively tries to anticollapse smallest edge non added so far. + * If its link is contractible then no topological change and else possible topological change. + * + * todo do a sparsification with some parameter eps while growing + */ +template class Critical_points { + private: + SkBlComplex filled_complex_; + const SkBlComplex& input_complex_; + double max_length_; + std::ostream& stream_; + + public: + typedef typename SkBlComplex::Vertex_handle Vertex_handle; + typedef typename SkBlComplex::Edge_handle Edge_handle; + typedef typename std::pair Edge; + + /** + * @brief check all pair of points with length smaller than max_length + */ + Critical_points(const SkBlComplex& input_complex, std::ostream& stream, double max_length) : + input_complex_(input_complex), max_length_(max_length), stream_(stream) { + std::deque edges; + auto vertices = input_complex.vertex_range(); + for (auto p = vertices.begin(); p != vertices.end(); ++p) { + filled_complex_.add_vertex(input_complex.point(*p)); + for (auto q = p; ++q != vertices.end(); /**/) + if (squared_eucl_distance(input_complex.point(*p), input_complex.point(*q)) < max_length_ * max_length_) + edges.emplace_back(*p, *q); + } + + std::sort(edges.begin(), edges.end(), + [&](Edge e1, Edge e2) { + return squared_edge_length(e1) < squared_edge_length(e2); + }); + + anti_collapse_edges(edges); + } + + private: + double squared_eucl_distance(const Point& p1, const Point& p2) const { + return Geometry_trait::Squared_distance_d()(p1, p2); + } + + void anti_collapse_edges(const std::deque& edges) { + unsigned pos = 0; + for (Edge e : edges) { + std::cout << "edge " << pos++ << "/" << edges.size() << "\n"; + auto eh = filled_complex_.add_edge(e.first, e.second); + int is_contractible(is_link_reducible(eh)); + + switch (is_contractible) { + case 0: + stream_ << "alpha=" << std::sqrt(squared_edge_length(e)) << " topological change" << std::endl; + break; + case 2: + stream_ << "alpha=" << std::sqrt(squared_edge_length(e)) << " maybe a topological change" << std::endl; + break; + default: + break; + } + } + } + + // 0 -> not + // 1 -> yes + // 2 -> maybe + + int is_link_reducible(Edge_handle e) { + auto link = filled_complex_.link(e); + + if (link.empty()) + return 0; + + Edge_contractor contractor(link, link.num_vertices() - 1); + + if (link.num_connected_components() > 1) + // one than more CC -> not contractible + return 0; + + if (link.num_vertices() == 1) + // reduced to one point -> contractible + return 1; + else + // we dont know + return 2; + } + + double squared_edge_length(Edge_handle e) const { + return squared_eucl_distance(input_complex_.point(input_complex_.first_vertex(e)), + input_complex_.point(input_complex_.second_vertex(e))); + } + + double squared_edge_length(Edge e) const { + return squared_eucl_distance(input_complex_.point(e.first), input_complex_.point(e.second)); + } +}; + +#endif // UTILS_CRITICAL_POINTS_H_ diff --git a/GudhUI/utils/Edge_collapsor.h b/GudhUI/utils/Edge_collapsor.h new file mode 100644 index 00000000..151e9b01 --- /dev/null +++ b/GudhUI/utils/Edge_collapsor.h @@ -0,0 +1,97 @@ +/* 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 UTILS_EDGE_COLLAPSOR_H_ +#define UTILS_EDGE_COLLAPSOR_H_ + +#include +#include "utils/Edge_contractor.h" +#include "utils/UI_utils.h" + +/** + * Iteratively puts every vertex at the center of its neighbors + */ +template class Edge_collapsor { + private: + SkBlComplex& complex_; + unsigned num_collapses_; + + public: + typedef typename SkBlComplex::Vertex_handle Vertex_handle; + typedef typename SkBlComplex::Edge_handle Edge_handle; + + /** + * @brief Collapse num_collapses edges. If num_collapses<0 then it collapses all possible edges. + * Largest edges are collapsed first. + * + */ + Edge_collapsor(SkBlComplex& complex, unsigned num_collapses) : + complex_(complex), num_collapses_(num_collapses) { + std::list edges; + edges.insert(edges.begin(), complex_.edge_range().begin(), complex_.edge_range().end()); + + edges.sort( + [&](Edge_handle e1, Edge_handle e2) { + return squared_edge_length(e1) < squared_edge_length(e2); + }); + + collapse_edges(edges); + } + + private: + void collapse_edges(std::list& edges) { + while (!edges.empty() && num_collapses_--) { + Edge_handle current_edge = edges.front(); + edges.pop_front(); + if (is_link_reducible(current_edge)) + complex_.remove_edge(current_edge); + } + } + + bool is_link_reducible(Edge_handle e) { + auto link = complex_.link(e); + + if (link.empty()) + return false; + + if (link.is_cone()) + return true; + + if (link.num_connected_components() > 1) + return false; + + Edge_contractor contractor(link, link.num_vertices() - 1); + + return (link.num_vertices() == 1); + } + + double squared_edge_length(Edge_handle e) const { + return squared_eucl_distance(complex_.point(complex_.first_vertex(e)), complex_.point(complex_.second_vertex(e))); + } + + double squared_eucl_distance(const Point& p1, const Point& p2) const { + return Geometry_trait::Squared_distance_d()(p1, p2); + } +}; + +#endif // UTILS_EDGE_COLLAPSOR_H_ diff --git a/GudhUI/utils/Edge_contractor.h b/GudhUI/utils/Edge_contractor.h new file mode 100644 index 00000000..45079a40 --- /dev/null +++ b/GudhUI/utils/Edge_contractor.h @@ -0,0 +1,97 @@ +/* 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 UTILS_EDGE_CONTRACTOR_H_ +#define UTILS_EDGE_CONTRACTOR_H_ + + +#include +#include +#include + +#include + +/** + * Iteratively puts every vertex at the center of its neighbors + */ +template class Edge_contractor { + private: + SkBlComplex& complex_; + unsigned num_contractions_; + + /** + * @brief return a cost corresponding to the squared length of the edge + */ + template< typename EdgeProfile> class Length_cost : public contraction::Cost_policy { + public: + typedef typename contraction::Cost_policy::Cost_type Cost_type; + typedef typename EdgeProfile::Point Point; + + Cost_type operator()(const EdgeProfile& profile, const boost::optional& placement) const override { + Cost_type res; + if (!placement) + return res; + return Geometry_trait::Squared_distance_d()(profile.p0(), profile.p1()); // not working?? + } + }; + + /** + * @brief return a cost corresponding to the squared length of the edge + */ + template< typename EdgeProfile> class Middle_placement : public contraction::Placement_policy { + public: + typedef typename contraction::Placement_policy::Placement_type Placement_type; + typedef typename EdgeProfile::Point Point; + + Placement_type operator()(const EdgeProfile& profile) const override { + std::vector mid_coords(profile.p0().dimension(), 0); + for (size_t i = 0; i < profile.p0().dimension(); ++i) { + mid_coords[i] = (profile.p0()[i] + profile.p1()[i]) / 2.; + } + return Point(profile.p0().dimension(), mid_coords.begin(), mid_coords.end()); + } + }; + + public: + typedef typename SkBlComplex::Vertex_handle Vertex_handle; + typedef typename SkBlComplex::Edge_handle Edge_handle; + + /** + * @brief Modify complex to be the expansion of the k-nearest neighbor + * symetric graph. + */ + Edge_contractor(SkBlComplex& complex, unsigned num_contractions) : + complex_(complex), num_contractions_(num_contractions) { + typedef typename contraction::Edge_profile Profile; + num_contractions = (std::min)(static_cast(num_contractions), static_cast(complex_.num_vertices() - 1)); + typedef typename contraction::Skeleton_blocker_contractor Contractor; + Contractor contractor(complex_, + new Length_cost> (), + new Middle_placement> (), + contraction::make_link_valid_contraction(), + contraction::make_remove_popable_blockers_visitor()); + contractor.contract_edges(num_contractions); + } +}; + +#endif // UTILS_EDGE_CONTRACTOR_H_ diff --git a/GudhUI/utils/Furthest_point_epsilon_net.h b/GudhUI/utils/Furthest_point_epsilon_net.h new file mode 100644 index 00000000..f2a216f6 --- /dev/null +++ b/GudhUI/utils/Furthest_point_epsilon_net.h @@ -0,0 +1,132 @@ +/* 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 UTILS_FURTHEST_POINT_EPSILON_NET_H_ +#define UTILS_FURTHEST_POINT_EPSILON_NET_H_ + +#include +#include // for sort + +#include "utils/UI_utils.h" + +/** + * Computes an epsilon net with furthest point strategy. + */ +template class Furthest_point_epsilon_net { + private: + SkBlComplex& complex_; + typedef typename SkBlComplex::Vertex_handle Vertex_handle; + typedef typename SkBlComplex::Edge_handle Edge_handle; + + /** + * Let V be the set of vertices. + * Initially v0 is one arbitrarly vertex and the set V0 is {v0}. + * Then Vk is computed as follows. + * First we compute the vertex pk that is the furthest from Vk + * then Vk = Vk \cup pk. + * The radius of pk is its distance to Vk and its meeting vertex + * is the vertex of Vk for which this distance is achieved. + */ + struct Net_filtration_vertex { + Vertex_handle vertex_handle; + Vertex_handle meeting_vertex; + double radius; + + Net_filtration_vertex(Vertex_handle vertex_handle_, + Vertex_handle meeting_vertex_, + double radius_) : + vertex_handle(vertex_handle_), meeting_vertex(meeting_vertex_), radius(radius_) { } + + bool operator<(const Net_filtration_vertex& other) const { + return radius < other.radius; + } + }; + + public: + std::vector net_filtration_; + + /** + * @brief Modify complex to be the expansion of the k-nearest neighbor + * symetric graph. + */ + Furthest_point_epsilon_net(SkBlComplex& complex) : + complex_(complex) { + if (!complex.empty()) { + init_filtration(); + for (int k = 2; k < net_filtration_.size(); ++k) { + update_radius_value(k); + } + } + } + + // xxx does not work if complex not full + + double radius(Vertex_handle v) { + return net_filtration_[v.vertex].radius; + } + + private: + void init_filtration() { + Vertex_handle v0 = *(complex_.vertex_range().begin()); + net_filtration_.reserve(complex_.num_vertices()); + for (auto v : complex_.vertex_range()) { + if (v != v0) + net_filtration_.push_back(Net_filtration_vertex(v, + Vertex_handle(-1), + squared_eucl_distance(v, v0))); + } + net_filtration_.push_back(Net_filtration_vertex(v0, Vertex_handle(-1), 1e10)); + auto n = net_filtration_.size(); + sort_filtration(n - 1); + } + + void update_radius_value(int k) { + int n = net_filtration_.size(); + int index_to_update = n - k; + for (int i = 0; i < index_to_update; ++i) { + net_filtration_[i].radius = (std::min)(net_filtration_[i].radius, + squared_eucl_distance(net_filtration_[i].vertex_handle, + net_filtration_[index_to_update].vertex_handle)); + } + sort_filtration(n - k); + } + + /** + * sort all i first elements. + */ + void sort_filtration(int i) { + std::sort(net_filtration_.begin(), net_filtration_.begin() + i); + } + + double squared_eucl_distance(Vertex_handle v1, Vertex_handle v2) const { + return std::sqrt(Geometry_trait::Squared_distance_d()(complex_.point(v1), complex_.point(v2))); + } + + void print_filtration() const { + for (auto v : net_filtration_) { + std::cerr << "v=" << v.vertex_handle << "-> d=" << v.radius << std::endl; + } + } +}; + +#endif // UTILS_FURTHEST_POINT_EPSILON_NET_H_ diff --git a/GudhUI/utils/Is_manifold.h b/GudhUI/utils/Is_manifold.h new file mode 100644 index 00000000..0640ea47 --- /dev/null +++ b/GudhUI/utils/Is_manifold.h @@ -0,0 +1,103 @@ +/* + * Is_manifold.h + * Created on: Jan 28, 2015 + * 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 UTILS_IS_MANIFOLD_H_ +#define UTILS_IS_MANIFOLD_H_ + +#include "utils/UI_utils.h" +#include "utils/Edge_contractor.h" + +/** + * Iteratively tries to anticollapse smallest edge non added so far. + * If its link is contractible then no topological change and else possible topological change. + * + * todo do a sparsification with some parameter eps while growing + */ +template class Is_manifold { + private: + const SkBlComplex& input_complex_; + typedef typename SkBlComplex::Vertex_handle Vertex_handle; + + public: + /* + * return dim the maximum dimension around one simplex and res which is true if the complex is a manifold. + * If the complex has dimension <= 3 then if res is false, the complex is not a manifold. + * For d-manifold with d>=4, res may be false while the complex is a manifold. + */ + Is_manifold(const SkBlComplex& input_complex, unsigned& dim, bool & res) : input_complex_(input_complex) { + res = true; + dim = -1; + if (!input_complex_.empty()) { + for (auto v : input_complex_.vertex_range()) { + dim = local_dimension(v); + break; + } + // check that the link of every vertex is a dim-1 sphere + for (auto v : input_complex_.vertex_range()) { + if (!is_k_sphere(v, dim - 1)) { + res = false; + break; + } + } + } + } + + private: + unsigned local_dimension(Vertex_handle v) { + unsigned dim = 0; + for (const auto& s : input_complex_.star_simplex_range(v)) + dim = (std::max)(dim, (unsigned) s.dimension()); + return dim; + } + + bool is_k_sphere(Vertex_handle v, int k) { + auto link = input_complex_.link(v); + Edge_contractor contractor(link, link.num_vertices() - 1); + return (is_sphere_simplex(link) == k); + } + + // A minimal sphere is a complex that contains vertices v1...vn and all faces + // made upon this set except the face {v1,...,vn} + // return -2 if not a minimal sphere + // and d otherwise if complex is a d minimal sphere + + template + int is_sphere_simplex(const SubComplex& complex) { + if (complex.empty()) return -1; + if (complex.num_blockers() != 1) return -2; + + // necessary and sufficient condition : there exists a unique blocker that passes through all vertices + auto first_blocker = *(complex.const_blocker_range().begin()); + + if (first_blocker->dimension() + 1 != complex.num_vertices()) + return -2; + else + return (first_blocker->dimension() - 1); + } +}; + +#endif // UTILS_IS_MANIFOLD_H_ diff --git a/GudhUI/utils/K_nearest_builder.h b/GudhUI/utils/K_nearest_builder.h new file mode 100644 index 00000000..7be0a4f4 --- /dev/null +++ b/GudhUI/utils/K_nearest_builder.h @@ -0,0 +1,90 @@ +/* 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 UTILS_K_NEAREST_BUILDER_H_ +#define UTILS_K_NEAREST_BUILDER_H_ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "utils/UI_utils.h" +#include "model/Complex_typedefs.h" + +template class K_nearest_builder { + private: + typedef Geometry_trait Kernel; + typedef Point Point_d; + typedef std::pair Point_d_with_id; + typedef CGAL::Search_traits_d Traits_base; + typedef CGAL::Search_traits_adapter, + Traits_base> Traits; + typedef CGAL::Orthogonal_k_neighbor_search Neighbor_search; + typedef Neighbor_search::Tree Tree; + typedef Neighbor_search::Distance Distance; + + SkBlComplex& complex_; + + public: + /** + * @brief Modify complex to be the expansion of the k-nearest neighbor + * symetric graph. + */ + K_nearest_builder(SkBlComplex& complex, unsigned k) : complex_(complex) { + complex.keep_only_vertices(); + compute_edges(k); + } + + private: + double squared_eucl_distance(const Point& p1, const Point& p2) const { + return Geometry_trait::Squared_distance_d()(p1, p2); + } + + void compute_edges(unsigned k) { + std::list points_with_id; + for (auto v : complex_.vertex_range()) { + Point_d_with_id point_v(complex_.point(v), v.vertex); + points_with_id.push_back(point_v); + } + + Tree tree(points_with_id.begin(), points_with_id.end()); + + typedef typename SkBlComplex::Vertex_handle Vertex_handle; + for (auto p : complex_.vertex_range()) { + Neighbor_search search(tree, complex_.point(p), k + 1); + for (auto it = ++search.begin(); it != search.end(); ++it) { + Vertex_handle q(std::get<1>(it->first)); + if (p != q && complex_.contains_vertex(p) && complex_.contains_vertex(q)) + complex_.add_edge(p, q); + } + } + } +}; + +#endif // UTILS_K_NEAREST_BUILDER_H_ diff --git a/GudhUI/utils/Lloyd_builder.h b/GudhUI/utils/Lloyd_builder.h new file mode 100644 index 00000000..18ec9fac --- /dev/null +++ b/GudhUI/utils/Lloyd_builder.h @@ -0,0 +1,91 @@ +/* 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 UTILS_LLOYD_BUILDER_H_ +#define UTILS_LLOYD_BUILDER_H_ + +#include +#include + +/** + * Iteratively puts every vertex at the center of its neighbors + */ +template class Lloyd_builder { + private: + SkBlComplex& complex_; + int dim; + + public: + typedef typename SkBlComplex::Vertex_handle Vertex_handle; + + /** + * @brief Modify complex to be the expansion of the k-nearest neighbor + * symetric graph. + */ + Lloyd_builder(SkBlComplex& complex, unsigned num_iterations) : complex_(complex), dim(-1) { + if (!complex_.empty()) { + dim = get_dimension(); + while (num_iterations--) { + std::list new_points; + for (auto v : complex.vertex_range()) + new_points.push_back(barycenter_neighbors(v)); + + auto new_points_it = new_points.begin(); + for (auto v : complex.vertex_range()) + complex_.point(v) = *(new_points_it++); + } + } + } + + private: + int get_dimension() { + assert(!complex_.empty()); + for (auto v : complex_.vertex_range()) + return complex_.point(v).dimension(); + return -1; + } + + Point barycenter_neighbors(Vertex_handle v) const { + if (complex_.degree(v) == 0) + return complex_.point(v); + + std::vector res(dim, 0); + unsigned num_points = 0; + for (auto nv : complex_.vertex_range(v)) { + ++num_points; + const Point& point = complex_.point(nv); + assert(point.dimension() == dim); + for (int i = 0; i < point.dimension(); ++i) + res[i] += point[i]; + } + for (auto& x : res) + x /= num_points; + return Point(dim, res.begin(), res.end()); + } + + double squared_eucl_distance(const Point& p1, const Point& p2) const { + return Geometry_trait::Squared_distance_d()(p1, p2); + } +}; + +#endif // UTILS_LLOYD_BUILDER_H_ diff --git a/GudhUI/utils/MClock.h b/GudhUI/utils/MClock.h new file mode 100644 index 00000000..e8d8918a --- /dev/null +++ b/GudhUI/utils/MClock.h @@ -0,0 +1,70 @@ +/* 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 UTILS_MCLOCK_H_ +#define UTILS_MCLOCK_H_ + +#include + +class MClock { + public: + MClock() { + end_called = false; + begin(); + } + + void begin() const { + end_called = false; + gettimeofday(&startTime, NULL); + } + + void end() const { + end_called = true; + gettimeofday(&endTime, NULL); + } + + friend std::ostream& operator<<(std::ostream& stream, const MClock& clock) { + // if(!clock.end_called) clock.end(); + if (!clock.end_called) { + stream << "end not called"; + } else { + long totalTime = (clock.endTime.tv_sec - clock.startTime.tv_sec) * 1000000L; + totalTime += (clock.endTime.tv_usec - clock.startTime.tv_usec); + stream << clock.num_seconds() << "s"; + } + return stream; + } + + double num_seconds() const { + if (!end_called) end(); + long totalTime = (endTime.tv_sec - startTime.tv_sec) * 1000000L; + totalTime += (endTime.tv_usec - startTime.tv_usec); + return (totalTime / 1000L) / static_cast(1000); + } + + private: + mutable struct timeval startTime, endTime; + mutable bool end_called; +}; + +#endif // UTILS_MCLOCK_H_ diff --git a/GudhUI/utils/Persistence_compute.h b/GudhUI/utils/Persistence_compute.h new file mode 100644 index 00000000..97165490 --- /dev/null +++ b/GudhUI/utils/Persistence_compute.h @@ -0,0 +1,91 @@ +/* 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 UTILS_PERSISTENCE_COMPUTE_H_ +#define UTILS_PERSISTENCE_COMPUTE_H_ + +#include +#include +#include +#include + +#include + +struct Persistence_params { + int p; + double threshold; + int max_dim; + double min_pers; + + Persistence_params(int p_, double th_, int max_dim_ = 10, double min_pers_ = 0) + : p(p_), threshold(th_), max_dim(max_dim_), min_pers(min_pers_) { } +}; + +/** + * Show persistence into output stream + */ +template class Persistence_compute { + public: + typedef typename SkBlComplex::Vertex_handle Vertex_handle; + typedef typename SkBlComplex::Edge_handle Edge_handle; + + /** + * @brief Compute persistence + * parameters : + * unsigned dim_max + * double threshold + * int p for coefficient Z_p + */ + Persistence_compute(SkBlComplex& complex, std::ostream& stream, const Persistence_params& params) { + // for now everything is copied, todo boost adapt iterators to points of SkBlComplex instead of copying to an + // initial vector + typedef std::vector Point_t; + std::vector< Point_t > points; + points.reserve(complex.num_vertices()); + for (auto v : complex.vertex_range()) { + const auto & pt = complex.point(v); + Point_t pt_to_add(pt.cartesian_begin(), pt.cartesian_end()); + points.emplace_back(std::move(pt_to_add)); + } + + + Graph_t prox_graph = compute_proximity_graph(points, params.threshold, euclidean_distance); + Gudhi::Simplex_tree<> st; + st.insert_graph(prox_graph); + st.expansion(params.max_dim); + + Gudhi::persistent_cohomology::Persistent_cohomology< Gudhi::Simplex_tree<>, + Gudhi::persistent_cohomology::Field_Zp > pcoh(st); + // initializes the coefficient field for homology + pcoh.init_coefficients(params.p); + // put params.min_pers + pcoh.compute_persistent_cohomology(params.min_pers); + stream << "persistence: \n"; + stream << "p dimension birth death: \n"; + + pcoh.output_diagram(stream); + } +}; + +#endif // UTILS_PERSISTENCE_COMPUTE_H_ diff --git a/GudhUI/utils/Rips_builder.h b/GudhUI/utils/Rips_builder.h new file mode 100644 index 00000000..b22f4db6 --- /dev/null +++ b/GudhUI/utils/Rips_builder.h @@ -0,0 +1,69 @@ +/* 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 UTILS_RIPS_BUILDER_H_ +#define UTILS_RIPS_BUILDER_H_ + +#include + +#include +#include +#include + +#include "utils/UI_utils.h" +#include "model/Complex_typedefs.h" + +template class Rips_builder { + private: + SkBlComplex& complex_; + + public: + /** + * @brief Modify complex to be the Rips complex + * of its points with offset alpha. + */ + Rips_builder(SkBlComplex& complex, double alpha) : complex_(complex) { + complex.keep_only_vertices(); + if (alpha <= 0) return; + compute_edges(alpha); + } + + private: + double squared_eucl_distance(const Point& p1, const Point& p2) const { + return Geometry_trait::Squared_distance_d()(p1, p2); + } + + void compute_edges(double alpha) { + auto vertices = complex_.vertex_range(); + for (auto p = vertices.begin(); p != vertices.end(); ++p) { + std::cout << *p << " "; + std::cout.flush(); + for (auto q = p; ++q != vertices.end(); /**/) + if (squared_eucl_distance(complex_.point(*p), complex_.point(*q)) < 4 * alpha * alpha) + complex_.add_edge(*p, *q); + } + std::cout << std::endl; + } +}; + +#endif // UTILS_RIPS_BUILDER_H_ diff --git a/GudhUI/utils/UI_utils.h b/GudhUI/utils/UI_utils.h new file mode 100644 index 00000000..9cc209d3 --- /dev/null +++ b/GudhUI/utils/UI_utils.h @@ -0,0 +1,45 @@ +/* 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 UTILS_UI_UTILS_H_ +#define UTILS_UI_UTILS_H_ + +#define UIDBG_VERBOSE + +#ifdef UIDBG_VERBOSE +#define UIDBG(a) std::cerr << "UIDBG: " << (a) << std::endl +#define UIDBGMSG(a, b) std::cerr << "UIDBG: " << a << b << std::endl +#define UIDBGVALUE(a) std::cerr << "UIDBG: " << #a << ": " << a << std::endl +#define UIDBGCONT(a) std::cerr << "UIDBG: container " << #a << " -> "; for (auto x : a) std::cerr << x << ","; std::cerr << std::endl } +#else +// #define DBG(a) a +// #define DBGMSG(a, b) b +// #define DBGVALUE(a) a +// #define DBGCONT(a) a +#define UIDBG(a) +#define UIDBGMSG(a, b) +#define UIDBGVALUE(a) +#define UIDBGCONT(a) +#endif + +#endif // UTILS_UI_UTILS_H_ diff --git a/GudhUI/utils/Vertex_collapsor.h b/GudhUI/utils/Vertex_collapsor.h new file mode 100644 index 00000000..2b36cb3a --- /dev/null +++ b/GudhUI/utils/Vertex_collapsor.h @@ -0,0 +1,88 @@ +/* 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 UTILS_VERTEX_COLLAPSOR_H_ +#define UTILS_VERTEX_COLLAPSOR_H_ + +#include + +#include "utils/Edge_contractor.h" +#include "utils/Furthest_point_epsilon_net.h" +#include "utils/UI_utils.h" + +/** + * Iteratively puts every vertex at the center of its neighbors + */ +template class Vertex_collapsor { + private: + SkBlComplex& complex_; + size_t num_collapses_; + + public: + typedef typename SkBlComplex::Vertex_handle Vertex_handle; + typedef typename SkBlComplex::Edge_handle Edge_handle; + + /** + * @brief Modify complex to be the expansion of the k-nearest neighbor + * symetric graph. + */ + Vertex_collapsor(SkBlComplex& complex, size_t num_collapses) : + complex_(complex), num_collapses_(num_collapses) { + // std::list vertices; + // vertices.insert(vertices.begin(),complex_.vertex_range().begin(),complex_.vertex_range().end()); + // UIDBG("Collapse vertices"); + // collapse_vertices(vertices); + + std::list vertices; + + UIDBG("Compute eps net"); + Furthest_point_epsilon_net eps_net(complex_); + + for (auto vh : eps_net.net_filtration_) + vertices.push_back(vh.vertex_handle); + + UIDBG("Collapse vertices"); + collapse_vertices(vertices); + } + + private: + void collapse_vertices(std::list& vertices) { + while (!vertices.empty() && num_collapses_--) { + Vertex_handle current_vertex = vertices.front(); + vertices.pop_front(); + if (is_link_reducible(current_vertex)) + complex_.remove_vertex(current_vertex); + } + } + + bool is_link_reducible(Vertex_handle v) { + auto link = complex_.link(v); + if (link.empty()) return false; + if (link.is_cone()) return true; + if (link.num_connected_components() > 1) return false; + Edge_contractor contractor(link, link.num_vertices() - 1); + return (link.num_vertices() == 1); + } +}; + +#endif // UTILS_VERTEX_COLLAPSOR_H_ diff --git a/GudhUI/utils/homsimpl b/GudhUI/utils/homsimpl new file mode 100755 index 00000000..12227502 Binary files /dev/null and b/GudhUI/utils/homsimpl differ diff --git a/GudhUI/view/Color.h b/GudhUI/view/Color.h new file mode 100644 index 00000000..ba0592e1 --- /dev/null +++ b/GudhUI/view/Color.h @@ -0,0 +1,35 @@ +/* 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 VIEW_COLOR_H_ +#define VIEW_COLOR_H_ + +struct Color { + double r; + double g; + double b; + + Color(double r_, double g_, double b_) : r(r_), g(g_), b(b_) { } +}; + +#endif // VIEW_COLOR_H_ diff --git a/GudhUI/view/FirstCoordProjector.h b/GudhUI/view/FirstCoordProjector.h new file mode 100644 index 00000000..a4027b7f --- /dev/null +++ b/GudhUI/view/FirstCoordProjector.h @@ -0,0 +1,42 @@ +/* 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 VIEW_FIRSTCOORDPROJECTOR_H_ +#define VIEW_FIRSTCOORDPROJECTOR_H_ + +#include "utils/UI_utils.h" +#include "Projector3D.h" + +class FirstCoordProjector3D : public Projector3D { + typedef Projector3D::Point Point; + typedef Projector3D::Point_3 Point_3; + + Point_3 operator()(const Point& p) const { + if (p.dimension() >= 3) + return Point_3(p.x(), p.y(), p.z()); + else if (p.dimension() >= 2) + return Point_3(p.x(), p.y(), 0.0); + } +}; + +#endif // VIEW_FIRSTCOORDPROJECTOR_H_ diff --git a/GudhUI/view/Projector3D.h b/GudhUI/view/Projector3D.h new file mode 100644 index 00000000..2a756541 --- /dev/null +++ b/GudhUI/view/Projector3D.h @@ -0,0 +1,39 @@ +/* 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 VIEW_PROJECTOR3D_H_ +#define VIEW_PROJECTOR3D_H_ + +#include "model/Complex_typedefs.h" + +class Projector3D { + public: + typedef Geometry_trait::Point Point; + typedef Geometry_trait::Point_3 Point_3; + + virtual Point_3 operator()(const Point&) const = 0; + + virtual ~Projector3D() { } +}; + +#endif // VIEW_PROJECTOR3D_H_ diff --git a/GudhUI/view/View_parameter.h b/GudhUI/view/View_parameter.h new file mode 100644 index 00000000..9805abc2 --- /dev/null +++ b/GudhUI/view/View_parameter.h @@ -0,0 +1,151 @@ +/* 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 VIEW_VIEW_PARAMETER_H_ +#define VIEW_VIEW_PARAMETER_H_ + +#include + +/** + * Different parameters for the view such as the camera angle, + * the light, options for vertices/edges/triangles. + */ +class View_parameter { + public: + bool light; + bool relative_light; + + double size_vertices; + double size_edges; + double light_edges; // in 0-1 + double light_triangles; // in 0-1 + + /** + * light angle + */ + double theta; + double phi; + + enum VERTEX_MODE { + V_NONE, V_SIMPLE, V_COUNT + }; + + enum EDGE_MODE { + E_NONE, E_SIMPLE, E_COUNT + }; + + enum TRIANGLE_MODE { + T_NONE, T_SIMPLE, T_COUNT + }; + + VERTEX_MODE vertex_mode; + EDGE_MODE edge_mode; + TRIANGLE_MODE triangle_mode; + + void change_vertex_mode() { + int current_value = vertex_mode; + vertex_mode = static_cast (++current_value % V_COUNT); + std::cout << "Vertex mode : "; + switch (vertex_mode) { + case V_NONE: + std::cout << "empty\n"; + break; + case V_SIMPLE: + std::cout << "simple\n"; + break; + default: + break; + } + } + + void change_vertex_mode(int new_mode) { + vertex_mode = static_cast (new_mode % V_COUNT); + } + + void change_edge_mode() { + int current_value = edge_mode; + edge_mode = static_cast (++current_value % E_COUNT); + } + + void change_edge_mode(int new_mode) { + edge_mode = static_cast (new_mode % E_COUNT); + } + + void change_triangle_mode() { + int current_value = triangle_mode; + triangle_mode = static_cast (++current_value % T_COUNT); + } + + View_parameter() { + light = true; + relative_light = true; + vertex_mode = V_SIMPLE; + edge_mode = E_SIMPLE; + triangle_mode = T_NONE; + + size_vertices = 3; + size_edges = 2; + + light_edges = 0.3; + light_triangles = 0.85; + theta = 0; + phi = 0; + } + + friend std::ostream& operator<<(std::ostream& stream, const View_parameter& param) { + stream << param.light << " "; + stream << param.relative_light << " "; + stream << param.vertex_mode << " "; + stream << param.edge_mode << " "; + stream << param.triangle_mode << " "; + stream << param.size_vertices << " "; + stream << param.size_edges << " "; + stream << param.light_edges << " "; + stream << param.light_triangles << " "; + stream << param.theta << " "; + stream << param.phi << " "; + return stream; + } + + friend std::istream& operator>>(std::istream& stream, View_parameter& param) { + stream >> param.light; + stream >> param.relative_light; + int a; + stream >> a; + param.vertex_mode = static_cast (a % V_COUNT); + stream >> a; + param.edge_mode = static_cast (a % E_COUNT); + stream >> a; + param.triangle_mode = static_cast (a % T_COUNT); + stream >> a; + stream >> param.size_vertices; + stream >> param.size_edges; + stream >> param.light_edges; + stream >> param.light_triangles; + stream >> param.theta; + stream >> param.phi; + return stream; + } +}; + +#endif // VIEW_VIEW_PARAMETER_H_ diff --git a/GudhUI/view/Viewer.cpp b/GudhUI/view/Viewer.cpp new file mode 100644 index 00000000..c6c2b345 --- /dev/null +++ b/GudhUI/view/Viewer.cpp @@ -0,0 +1,186 @@ +/* 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 . + * + */ + +#include "Viewer.h" +#include "utils/UI_utils.h" + +Viewer::Viewer(QWidget* parent) : QGLViewer(QGLFormat(QGL::SampleBuffers), parent), instructor(0), theta(0), phi(0) { } + +void Viewer::set_instructor(Viewer_instructor* instructor_) { + instructor = instructor_; +} + +void Viewer::show_entire_scene() { + this->showEntireScene(); +} + +void Viewer::draw() { + instructor->give_instructions(); +} + +void Viewer::set_bounding_box(const Point_3 & lower_left, const Point_3 & upper_right) { + this->camera()->setSceneBoundingBox(qglviewer::Vec(lower_left[0], lower_left[1], lower_left[2]), + qglviewer::Vec(upper_right[0], upper_right[1], upper_right[2])); +} + +void Viewer::update_GL() { + this->updateGL(); +} + +void Viewer::init_scene() { + this->setBackgroundColor(Qt::white); + ::glEnable(GL_LINE_SMOOTH); + init_light(); +} + +void Viewer::init_light() { + ::glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); +} + +void Viewer::set_light() { + if (theta >= 0 && phi >= 0) { + const GLfloat pos[4] = {static_cast (sin(phi) * cos(theta)), + static_cast (sin(phi) * sin(theta)), + static_cast (cos(phi)), 0.}; + glLightfv(GL_LIGHT0, GL_POSITION, pos); + } +} + +void Viewer::set_light_direction(double theta_, double phi_) { + theta = theta_; + phi = phi_; +} + +/** + * set the light in the direction of the observer + */ +void Viewer::set_light_direction() { + theta = -1; + phi = -1; +} + +void Viewer::postSelection(const QPoint& point) { + bool found; + + auto vec = this->camera()->pointUnderPixel(point, found); + + if (found) { + Point_3 position(vec[0], vec[1], vec[2]); + emit(click(position)); + } +} + +//////////////////////// +// draw +//////////////////////// + +void Viewer::set_size_point(double size_points) { + ::glPointSize(size_points); +} + +void Viewer::draw_point(const Point_3& p, const Color& color, double size_points) { + ::glColor3f(color.r, color.g, color.b); + ::glDisable(GL_LIGHTING); + ::glEnable(GL_POINT_SMOOTH); + ::glPointSize(size_points); + ::glBegin(GL_POINTS); + ::glVertex3d(p.x(), p.y(), p.z()); + ::glEnd(); + ::glDisable(GL_POINT_SMOOTH); +} + +void Viewer::begin_draw_points(double size, bool light) { + light ? glEnable(GL_LIGHTING) : glDisable(GL_LIGHTING); + ::glEnable(GL_POINT_SMOOTH); + ::glPointSize(size); + ::glBegin(GL_POINTS); +} + +void Viewer::set_color(const Color& color) { + ::glColor3f(color.r, color.g, color.b); +} + +void Viewer::draw_points(const Point_3 & point) { + ::glVertex3d(point.x(), point.y(), point.z()); +} + +void Viewer::end_draw_points() { + ::glEnd(); + ::glDisable(GL_POINT_SMOOTH); +} + +void Viewer::draw_edge(const Point_3 &a, const Point_3 &b, const Color& color, double size) { + ::glColor3f(color.r, color.g, color.b); + ::glPointSize(3.0); + ::glLineWidth(size); + ::glBegin(GL_LINES); + ::glVertex3f(a.x(), a.y(), a.z()); + ::glVertex3f(b.x(), b.y(), b.z()); + ::glEnd(); +} + +void Viewer::begin_draw_edges(double size, bool light) { + ::glLineWidth(size); + ::glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + ::glEnable(GL_POLYGON_OFFSET_LINE); + ::glPolygonOffset(3.0f, -3.0f); + light ? glEnable(GL_LIGHTING) : glDisable(GL_LIGHTING); + ::glBegin(GL_LINES); +} + +void Viewer::draw_edges(const Point_3 &a, const Point_3 &b) { + ::glVertex3f(a.x(), a.y(), a.z()); + ::glVertex3f(b.x(), b.y(), b.z()); +} + +void Viewer::end_draw_edges() { + ::glEnd(); +} + +void Viewer::begin_draw_triangles(double size, bool light, bool transparent) { + if (transparent) { + ::glEnable(GL_BLEND); + ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + ::glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + ::glEnable(GL_POLYGON_OFFSET_FILL); + ::glPolygonOffset(3.0f, -3.0f); + light ? glEnable(GL_LIGHTING) : glDisable(GL_LIGHTING); + ::glBegin(GL_TRIANGLES); +} + +void Viewer::draw_triangles(const Point_3& p1, const Point_3& p2, const Point_3& p3) { + if (!CGAL::collinear(p1, p2, p3)) { + auto triangle_normal = CGAL::unit_normal(p1, p2, p3); + ::glNormal3d(triangle_normal.x(), triangle_normal.y(), triangle_normal.z()); + ::glVertex3d(p1.x(), p1.y(), p1.z()); + ::glVertex3d(p2.x(), p2.y(), p2.z()); + ::glVertex3d(p3.x(), p3.y(), p3.z()); + } +} + +void Viewer::end_draw_triangles() { + ::glEnd(); +} + +#include "Viewer.moc" diff --git a/GudhUI/view/Viewer.h b/GudhUI/view/Viewer.h new file mode 100644 index 00000000..319c8e04 --- /dev/null +++ b/GudhUI/view/Viewer.h @@ -0,0 +1,120 @@ +/* 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 VIEW_VIEWER_H_ +#define VIEW_VIEWER_H_ + +// Workaround for moc-qt4 not parsing boost headers +#include + +#include + +#include + +#include "View_parameter.h" +#include "model/Complex_typedefs.h" +#include "Color.h" +#include "Viewer_instructor.h" + +class Viewer_instructor; + +class Viewer : public QGLViewer { + Q_OBJECT + + Viewer_instructor * instructor; + + /** + * light angles + */ + double theta, phi; + typedef Complex::GT Gudhi_kernel; + typedef Gudhi_kernel::Point_3 Point_3; + + public: + Viewer(QWidget* parent); + + void set_instructor(Viewer_instructor* instructor_); + + void show_entire_scene(); + + void draw(); + + void set_bounding_box(const Point_3 & lower_left, const Point_3 & upper_right); + + void update_GL(); + + void init_scene(); + + void init_light(); + + void set_light(); + + void set_light_direction(double theta, double phi); + + /** + * set the light in the direction of the observer + */ + void set_light_direction(); + + protected: + virtual void postSelection(const QPoint& point); + + public: + //////////////////////// + // draw + //////////////////////// + void set_size_point(double size_points); + + void set_color(const Color& color); + + void draw_point(const Point_3& p, const Color& color, double size_points); + + void begin_draw_points(double size, bool light = false); + + void draw_points(const Point_3 & point); + + void end_draw_points(); + + void draw_edge(const Point_3 &a, const Point_3 &b, const Color& color, double size); + + void begin_draw_edges(double size, bool light = false); + + void draw_edges(const Point_3 &a, const Point_3 &b); + + void end_draw_edges(); + + void begin_draw_triangles(double size, bool light, bool transparent = false); + + void draw_triangles(const Point_3& p1, const Point_3& p2, const Point_3& p3); + + // todo remove + void draw_triangles(const std::vector& points); + + void end_draw_triangles(); + + + signals: + void click(const Point_3& position); +}; + +#endif // VIEW_VIEWER_H_ diff --git a/GudhUI/view/Viewer_instructor.cpp b/GudhUI/view/Viewer_instructor.cpp new file mode 100644 index 00000000..1ddd4d8b --- /dev/null +++ b/GudhUI/view/Viewer_instructor.cpp @@ -0,0 +1,192 @@ +/* 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 . + * + */ + +#include + +#include "Viewer_instructor.h" +#include "utils/UI_utils.h" +#include "FirstCoordProjector.h" + +Viewer_instructor::Viewer_instructor(QWidget* parent, + Viewer* viewer, + const Complex& mesh + ) + : viewer_(viewer), mesh_(mesh), projector_(new FirstCoordProjector3D()) { + viewer_->set_instructor(this); +} + +void Viewer_instructor::initialize_bounding_box() { + auto pair_bounding_box = compute_bounding_box_corners(); + viewer_->set_bounding_box(proj(pair_bounding_box.first), proj(pair_bounding_box.second)); + viewer_->init_scene(); +} + +std::pair Viewer_instructor::compute_bounding_box_corners() { + if (mesh_.empty()) { + return std::make_pair(Point(-1, -1, -1, 1), Point(1, 1, 1, 1)); + } else { + double x_min = 1e10; + double y_min = 1e10; + double z_min = 1e10; + double x_max = -1e10; + double y_max = -1e10; + double z_max = -1e10; + for (auto vi : mesh_.vertex_range()) { + auto pt = proj(mesh_.point(vi)); + x_min = (std::min)(x_min, pt.x()); + y_min = (std::min)(y_min, pt.y()); + z_min = (std::min)(z_min, pt.z()); + + x_max = (std::max)(x_max, pt.x()); + y_max = (std::max)(y_max, pt.y()); + z_max = (std::max)(z_max, pt.z()); + } + return std::make_pair(Point(x_min, y_min, z_min, 1.), + Point(x_max, y_max, z_max, 1.)); + } +} + +void Viewer_instructor::show_entire_scene() { + viewer_->show_entire_scene(); +} + +const qglviewer::Camera* Viewer_instructor::camera() const { + return viewer_->camera(); +} + +int +Viewer_instructor::width() const { + return viewer_->width(); +} + +int +Viewer_instructor::height() const { + return viewer_->height(); +} + +/** + * to change display parameters + */ +View_parameter& Viewer_instructor::view_params() { + return view_params_; +} + +void +Viewer_instructor::give_instructions() { + if (view_params_.relative_light) + viewer_->set_light_direction(); + else + viewer_->set_light_direction(view_params_.theta, view_params_.phi); + viewer_->set_light(); + + if (view_params_.edge_mode) draw_edges(); + if (view_params_.triangle_mode) draw_triangles(); + if (view_params_.vertex_mode) draw_points(); +} + +void Viewer_instructor::draw_edges() { + viewer_->begin_draw_edges(view_params_.size_edges, false); + + for (auto edge : mesh_.edge_range()) { + set_color_edge(edge); + const Point& a = mesh_.point(mesh_.first_vertex(edge)); + const Point& b = mesh_.point(mesh_.second_vertex(edge)); + viewer_->draw_edges(proj(a), proj(b)); + } + + viewer_->end_draw_edges(); +} + +void Viewer_instructor::draw_triangles() { + const double size_triangles = 1.0; + viewer_->begin_draw_triangles(size_triangles, view_params_.light); + + for (const auto& fit : mesh_.triangle_range()) { + set_color_triangle(fit); + if (view_params_.triangle_mode) { + auto fit_it = fit.begin(); + const Point& p1 = mesh_.point(*fit_it); + const Point& p2 = mesh_.point(*(++fit_it)); + const Point& p3 = mesh_.point(*(++fit_it)); + viewer_->draw_triangles(proj(p1), proj(p2), proj(p3)); + } + } + viewer_->end_draw_triangles(); +} + +void Viewer_instructor::draw_points() { + viewer_->begin_draw_points(view_params_.size_vertices); + for (auto vi : mesh_.vertex_range()) { + viewer_->set_size_point(view_params_.size_vertices); + set_color_vertex(vi); + viewer_->draw_points(proj(mesh_.point(vi))); + } + viewer_->end_draw_points(); +} + +void Viewer_instructor::draw_edge(const Point&, const Point&) { } + +void Viewer_instructor::draw_point(const Point&) { } + +/** + * set the right color of vertex/edge/triangle considering the view_params choice + */ +void Viewer_instructor::set_color_vertex(Vertex_handle vh) { + viewer_->set_color(Color(view_params_.light_edges, view_params_.light_edges, view_params_.light_edges)); +} + +void Viewer_instructor::set_color_edge(Edge_handle eh) { + viewer_->set_color(Color(view_params_.light_edges, view_params_.light_edges, view_params_.light_edges)); +} + +void Viewer_instructor::set_color_triangle(const Simplex& triangle) { + viewer_->set_color(Color(view_params_.light_triangles, view_params_.light_triangles, view_params_.light_triangles)); +} + +Viewer_instructor::Point_3 +Viewer_instructor::proj(const Point& p) const { + return (*projector_)(p); +} + +void Viewer_instructor::sceneChanged() { + UIDBG("sceneChanged"); + viewer_->update_GL(); +} + +void Viewer_instructor::change_draw_vertices() { + view_params_.change_vertex_mode(); +} + +void Viewer_instructor::change_draw_edges() { + view_params_.change_edge_mode(); +} + +void Viewer_instructor::change_draw_triangles() { + view_params_.change_triangle_mode(); +} + +void Viewer_instructor::change_light() { + view_params_.light = !view_params_.light; +} + +#include "Viewer_instructor.moc" diff --git a/GudhUI/view/Viewer_instructor.h b/GudhUI/view/Viewer_instructor.h new file mode 100644 index 00000000..1da28009 --- /dev/null +++ b/GudhUI/view/Viewer_instructor.h @@ -0,0 +1,117 @@ +/* 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 VIEW_VIEWER_INSTRUCTOR_H_ +#define VIEW_VIEWER_INSTRUCTOR_H_ + +// todo do a viewer instructor that have directely a pointer to a QGLviewer and buffer ot not triangles + +// Workaround for moc-qt4 not parsing boost headers +#include + +#include +#include +#include + +#include +#include // for pair<> + +#include "model/Complex_typedefs.h" + +#include "Projector3D.h" +#include "View_parameter.h" +#include "Viewer.h" + +class Viewer; +class Viewer_parameter; + +class Viewer_instructor : public QWidget { + Q_OBJECT + + typedef Geometry_trait::Point_3 Point_3; + typedef Complex::Point Point; + typedef Complex::Vertex_handle Vertex_handle; + typedef Complex::Edge_handle Edge_handle; + typedef Complex::Simplex Simplex; + + Viewer* viewer_; + View_parameter view_params_; + const Complex& mesh_; + std::unique_ptr projector_; + + public: + Viewer_instructor(QWidget* parent, Viewer* viewer, const Complex& mesh); + + void initialize_bounding_box(); + + std::pair compute_bounding_box_corners(); + + void show_entire_scene(); + + const qglviewer::Camera* camera() const; + + int width() const; + int height() const; + + /** + * to change display parameters + */ + View_parameter& view_params(); + + public: + /** + * gives instructions to the viewer + */ + void give_instructions(); + + void draw_edges(); + void draw_triangles(); + void draw_points(); + + void draw_edge(const Point&, const Point&); + + void draw_point(const Point&); + + /** + * set the right color of vertex/edge/triangle considering the view_params choice + */ + void set_color_vertex(Vertex_handle vh); + void set_color_edge(Edge_handle eh); + + void set_color_triangle(const Simplex& triangle); + + private: + /** + * Projection to 3D needed for the viewer. + */ + Point_3 proj(const Point& p) const; + + public slots: + void sceneChanged(); + void change_draw_vertices(); + void change_draw_edges(); + void change_draw_triangles(); + void change_light(); +}; + +#endif // VIEW_VIEWER_INSTRUCTOR_H_ -- cgit v1.2.3