diff --git a/Mesh_3/demo/Mesh_3/Mesh_3_optimization_plugin.cpp b/Mesh_3/demo/Mesh_3/Mesh_3_optimization_plugin.cpp index 757a28024f2..90bbcdb468b 100644 --- a/Mesh_3/demo/Mesh_3/Mesh_3_optimization_plugin.cpp +++ b/Mesh_3/demo/Mesh_3/Mesh_3_optimization_plugin.cpp @@ -63,6 +63,8 @@ class Mesh_3_optimization_plugin : Q_OBJECT Q_INTERFACES(Plugin_interface); public: + Mesh_3_optimization_plugin(); + virtual void init(QMainWindow*, Scene_interface*, Messages_interface*); inline virtual QList actions() const; @@ -73,6 +75,7 @@ public slots: void exude(); void optimization_done(Optimizer_thread* t); + void status_report(QString s); private: Scene_c3t3_item* get_c3t3_item() const; @@ -94,6 +97,18 @@ private: }; // end class Mesh_3_optimization_plugin +Mesh_3_optimization_plugin:: +Mesh_3_optimization_plugin() + : actionOdt(NULL) + , actionLloyd(NULL) + , actionPerturb(NULL) + , actionExude(NULL) + , msg(NULL) + , message_box_(NULL) + , source_item_(NULL) +{ +} + void Mesh_3_optimization_plugin:: init(QMainWindow* mainWindow, @@ -508,10 +523,23 @@ launch_thread(Optimizer_thread* opt_thread, const QString& window_text) QObject::connect(opt_thread, SIGNAL(done(Optimizer_thread*)), this, SLOT(optimization_done(Optimizer_thread*))); + QObject::connect(opt_thread, SIGNAL(status_report(QString)), + this, SLOT(status_report(QString))); + opt_thread->start(); } +void +Mesh_3_optimization_plugin:: +status_report(QString str) +{ + if ( NULL == message_box_ ) { return; } + + message_box_->setInformativeText(str); +} + + QString translate(CGAL::Mesh_optimization_return_code rc) { diff --git a/Mesh_3/demo/Mesh_3/Mesh_3_optimization_plugin_cgal_code.cpp b/Mesh_3/demo/Mesh_3/Mesh_3_optimization_plugin_cgal_code.cpp index 697a7186134..e2456c7c507 100644 --- a/Mesh_3/demo/Mesh_3/Mesh_3_optimization_plugin_cgal_code.cpp +++ b/Mesh_3/demo/Mesh_3/Mesh_3_optimization_plugin_cgal_code.cpp @@ -11,10 +11,21 @@ #include #include +#include namespace cgp = CGAL::parameters; +// ----------------------------------- +// Helper function +// ----------------------------------- +QString translate_bool(const bool b) +{ + return b ? QString("done") + : QString("in progress"); +} + + // ----------------------------------- // Optimization_function_base template class // ----------------------------------- @@ -155,6 +166,89 @@ Optimizer_thread* cgal_code_optimization(Scene_c3t3_item& c3t3_item, +// ----------------------------------- +// Global optimization +// ----------------------------------- +struct Global_optimization_status +{ + bool compute_moves_done; + bool move_points_done; + bool rebuild_restricted_delaunay_done; + int iteration_done; + + Global_optimization_status() + : compute_moves_done(false) + , move_points_done(false) + , rebuild_restricted_delaunay_done(false) + , iteration_done(-1) {} +}; + +struct Global_visitor +{ + Global_visitor(Global_optimization_status* status) : p_status_(status) {} + Global_visitor(const Global_visitor& rhs) : p_status_(rhs.p_status_) {} + + void after_compute_moves() { p_status_->compute_moves_done = true; } + void after_move_points() { p_status_->move_points_done = true; } + void after_rebuild_restricted_delaunay() { p_status_->rebuild_restricted_delaunay_done = true; } + + void end_of_iteration(int iteration_number) + { + p_status_->iteration_done = iteration_number; + p_status_->compute_moves_done = false; + p_status_->move_points_done = false; + p_status_->rebuild_restricted_delaunay_done = false; + } + +private: + Global_optimization_status* p_status_; +}; + + +template +class Global_optimization_function + : public Optimization_function_base< Domain > +{ + typedef Global_visitor Visitor; + typedef Optimization_function_base< Domain > Base; + +public: + /// Constructor + Global_optimization_function(C3t3& c3t3, Domain* d) + : Base(c3t3,d) + , status_() {} + + /// Destructor + virtual ~Global_optimization_function() {} + + // Logs + virtual QString status(double time_period) const + { + QString res = QString("Iteration %1

" + "Compute moves: %2
") + .arg(status_.iteration_done + 2) + .arg(translate_bool(status_.compute_moves_done)); + + if ( status_.compute_moves_done ) + { + res += QString("Move points: %1
") + .arg(translate_bool(status_.move_points_done)); + } + + if ( status_.move_points_done ) + { + res += QString("Rebuild restricted Delaunay: %1") + .arg(translate_bool(status_.rebuild_restricted_delaunay_done)); + } + + return res; + } + +protected: + Global_optimization_status status_; +}; + + // ----------------------------------- // Odt // ----------------------------------- @@ -183,7 +277,7 @@ struct Odt_parameters */ template class Optimization_function < Domain, Odt_parameters > - : public Optimization_function_base< Domain > + : public Global_optimization_function< Domain > { // Private types typedef C3t3::Triangulation Tr; @@ -191,10 +285,11 @@ class Optimization_function < Domain, Odt_parameters > typedef CGAL::Mesh_3::Mesh_sizing_field Sizing; typedef CGAL::Mesh_3::Odt_move Move; + typedef Global_visitor Visitor; - typedef typename CGAL::Mesh_3::Mesh_global_optimizer Odt_optimizer; + typedef typename CGAL::Mesh_3::Mesh_global_optimizer Odt_optimizer; - typedef Optimization_function_base< Domain > Base; + typedef Global_optimization_function< Domain > Base; public: /// Constructor @@ -233,7 +328,7 @@ protected: : p_.max_iteration_nb; // Launch optimization - return (*odt_)(max_iteration_nb); + return (*odt_)(max_iteration_nb, Visitor(&(this->status_))); } private: @@ -292,7 +387,7 @@ struct Lloyd_parameters */ template class Optimization_function < Domain, Lloyd_parameters > - : public Optimization_function_base< Domain > + : public Global_optimization_function< Domain > { // Private types typedef C3t3::Triangulation Tr; @@ -300,10 +395,11 @@ class Optimization_function < Domain, Lloyd_parameters > typedef CGAL::Mesh_3::Mesh_sizing_field Sizing; typedef CGAL::Mesh_3::Lloyd_move Move; + typedef Global_visitor Visitor; - typedef typename CGAL::Mesh_3::Mesh_global_optimizer Lloyd_optimizer; + typedef typename CGAL::Mesh_3::Mesh_global_optimizer Lloyd_optimizer; - typedef Optimization_function_base< Domain > Base; + typedef Global_optimization_function< Domain > Base; public: /// Constructor @@ -342,7 +438,7 @@ protected: : p_.max_iteration_nb; // Launch optimization - return (*lloyd_)(max_iteration_nb); + return (*lloyd_)(max_iteration_nb, Visitor(&(this->status_))); } private: @@ -390,6 +486,27 @@ struct Perturb_parameters }; +struct Perturb_status +{ + double bound_reached; + double vertices_left; + + Perturb_status() : bound_reached(0), vertices_left(0) {} +}; + +struct Perturb_visitor +{ + Perturb_visitor(Perturb_status* status) : p_status_(status) {} + Perturb_visitor(const Perturb_visitor& rhs) : p_status_(rhs.p_status_) {} + + void bound_reached(const double bound) { p_status_->bound_reached = bound; } + void end_of_perturbation_iteration(std::size_t v) { p_status_->vertices_left = v;} + +private: + Perturb_status* p_status_; +}; + + /** * @class Perturb_function * Partial specialization of class Optimization_function for perturbation @@ -400,10 +517,11 @@ class Optimization_function < Domain, Perturb_parameters > : public Optimization_function_base< Domain > { // Private types - typedef C3t3::Triangulation::Geom_traits Gt; - typedef CGAL::Mesh_3::Min_dihedral_angle_criterion Sc; + typedef C3t3::Triangulation::Geom_traits Gt; + typedef CGAL::Mesh_3::Min_dihedral_angle_criterion Sc; + typedef Perturb_visitor Visitor; - typedef CGAL::Mesh_3::Sliver_perturber Perturber; + typedef CGAL::Mesh_3::Sliver_perturber Perturber; typedef Optimization_function_base< Domain > Base; @@ -423,6 +541,13 @@ public: /// Log strings virtual QString name() const { return QString("Perturb"); } virtual QStringList parameters_log() const { return p_.log(); } + virtual QString status(double time_period) const + { + return QString("Dihedral angle reached: %1

" + "Vertices left in queue (to reach next bound): %2") + .arg(status_.bound_reached) + .arg(status_.vertices_left); + } protected: /// Launch sliver perturbation @@ -450,14 +575,17 @@ protected: // Set max time perturb_->set_time_limit(p_.time_limit); + // Set sliver bound (0 means no sliver bound) + if ( 0 == p_.sliver_bound ) { p_.sliver_bound = Sc::max_value; } + // Launch perturber - if ( p_.sliver_bound != 0 ) { return (*perturb_)(p_.sliver_bound); } - else { return (*perturb_)(); } + return (*perturb_)(p_.sliver_bound, 1, Visitor(&status_)); } private: Perturber* perturb_; Perturb_parameters p_; + Perturb_status status_; }; @@ -495,6 +623,26 @@ struct Exude_parameters }; +struct Exude_status +{ + double cells_left_in_queue; + double vertices_pumped; + + Exude_status() : cells_left_in_queue(0), vertices_pumped(0) {} +}; + +struct Exude_visitor +{ + Exude_visitor(Exude_status* status) : p_status_(status) {} + Exude_visitor(const Exude_visitor& rhs) : p_status_(rhs.p_status_) {} + + void after_cell_pumped(std::size_t n) { p_status_->cells_left_in_queue = n; } + +private: + Exude_status* p_status_; +}; + + /** * @class Exude_function * Partial specialization of class Optimization_function for exudation @@ -507,7 +655,8 @@ class Optimization_function < Domain, Exude_parameters > // Private types typedef C3t3::Triangulation::Geom_traits Gt; typedef CGAL::Mesh_3::Min_dihedral_angle_criterion Sc; - typedef CGAL::Mesh_3::Slivers_exuder Exuder; + typedef Exude_visitor Visitor; + typedef CGAL::Mesh_3::Slivers_exuder Exuder; typedef Optimization_function_base< Domain > Base; @@ -527,6 +676,13 @@ public: // Log strings virtual QString name() const { return QString("Exude"); } virtual QStringList parameters_log() const { return p_.log(); } + virtual QString status(double time_period) const + { + return QString("Cells left in queue: %1
") + //"Vertices pumped: %2") + .arg(status_.cells_left_in_queue); + //.arg(status_.vertices_pumped); + } protected: /// Launch sliver exudation @@ -544,12 +700,13 @@ protected: exude_->set_time_limit(p_.time_limit); // Launch exudation - return (*exude_)(p_.sliver_bound); + return (*exude_)(p_.sliver_bound, Visitor(&status_)); } private: Exuder* exude_; Exude_parameters p_; + Exude_status status_; }; diff --git a/Mesh_3/demo/Mesh_3/Optimizer_thread.cpp b/Mesh_3/demo/Mesh_3/Optimizer_thread.cpp index ecc7e2e4590..356ad8fc1a1 100644 --- a/Mesh_3/demo/Mesh_3/Optimizer_thread.cpp +++ b/Mesh_3/demo/Mesh_3/Optimizer_thread.cpp @@ -22,9 +22,27 @@ //****************************************************************************** #include +#include #include "Optimizer_thread.h" #include "Scene_c3t3_item.h" + +Optimizer_thread:: +Optimizer_thread(Optimization_function_interface* f, Scene_c3t3_item* item) + : f_(f) + , item_(item) + , rc_() + , time_(0) + , timer_(new QTimer(this)) + , timer_period_(1) +{ + connect(timer_, SIGNAL(timeout()), + this, SLOT(emit_status())); + + timer_->start(timer_period_*1000); +} + + Optimizer_thread::~Optimizer_thread() { delete f_; @@ -52,5 +70,12 @@ stop() f_->stop(); } +void +Optimizer_thread:: +emit_status() +{ + emit (status_report(f_->status(timer_period_))); +} + #include "Optimizer_thread.moc" \ No newline at end of file diff --git a/Mesh_3/demo/Mesh_3/Optimizer_thread.h b/Mesh_3/demo/Mesh_3/Optimizer_thread.h index cbff5ef699d..adecbaed285 100644 --- a/Mesh_3/demo/Mesh_3/Optimizer_thread.h +++ b/Mesh_3/demo/Mesh_3/Optimizer_thread.h @@ -28,6 +28,7 @@ #include #include #include +#include #include @@ -47,6 +48,7 @@ public: // Logs virtual QString name() const = 0; virtual QStringList parameters_log() const = 0; + virtual QString status(double time_period) const = 0; }; @@ -54,9 +56,7 @@ class Optimizer_thread : public QThread { Q_OBJECT public: - Optimizer_thread(Optimization_function_interface* f, Scene_c3t3_item* item) - : f_(f), item_(item), rc_(), time_(0) {} - + Optimizer_thread(Optimization_function_interface* f, Scene_c3t3_item* item); virtual ~Optimizer_thread(); // Scene item @@ -74,9 +74,15 @@ public slots: // Stop void stop(); +private slots: + // emit signal status report + void emit_status(); + signals: // Emitted at the end of the process void done(Optimizer_thread*); + // Informs about status of the process + void status_report(QString); protected: // Overload of QThread function @@ -87,6 +93,8 @@ private: Scene_c3t3_item* item_; CGAL::Mesh_optimization_return_code rc_; double time_; // in seconds + QTimer* timer_; + double timer_period_; }; #endif // DEMO_MESH_3_OPTIMIZER_THREAD_H \ No newline at end of file