mirror of https://github.com/CGAL/cgal
Second step towards run of mesh optimization process in a separated thread:
+ A message box pops up when optimizer is launched. + Optimization can be stop using 'stop' button of this message box + todo: add (dynamic) information in message box about status of running optimizer
This commit is contained in:
parent
fb29cad175
commit
08e6269f08
|
|
@ -53,7 +53,7 @@ Optimizer_thread* cgal_code_exude_mesh_3(Scene_c3t3_item& c3t3_item,
|
||||||
const double sliver_bound,
|
const double sliver_bound,
|
||||||
const bool create_new_item);
|
const bool create_new_item);
|
||||||
|
|
||||||
std::string translate(CGAL::Mesh_optimization_return_code rc);
|
QString translate(CGAL::Mesh_optimization_return_code rc);
|
||||||
|
|
||||||
// Mesh_3_optimization_plugin class
|
// Mesh_3_optimization_plugin class
|
||||||
class Mesh_3_optimization_plugin :
|
class Mesh_3_optimization_plugin :
|
||||||
|
|
@ -72,9 +72,13 @@ public slots:
|
||||||
void perturb();
|
void perturb();
|
||||||
void exude();
|
void exude();
|
||||||
|
|
||||||
|
void optimization_done(Optimizer_thread* t);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void treat_result(Scene_c3t3_item& source_item, Scene_c3t3_item& result_item,
|
void treat_result(Scene_c3t3_item& source_item, Scene_c3t3_item& result_item,
|
||||||
const QString& name, bool new_item_created) const;
|
const QString& name) const;
|
||||||
|
|
||||||
|
void launch_thread(Optimizer_thread* thread, const QString& msg);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QAction* actionOdt;
|
QAction* actionOdt;
|
||||||
|
|
@ -82,6 +86,9 @@ private:
|
||||||
QAction* actionPerturb;
|
QAction* actionPerturb;
|
||||||
QAction* actionExude;
|
QAction* actionExude;
|
||||||
Messages_interface* msg;
|
Messages_interface* msg;
|
||||||
|
QMessageBox* message_box_;
|
||||||
|
|
||||||
|
Scene_c3t3_item* source_item_;
|
||||||
}; // end class Mesh_3_optimization_plugin
|
}; // end class Mesh_3_optimization_plugin
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -187,8 +194,6 @@ Mesh_3_optimization_plugin::odt()
|
||||||
// Launch optimization
|
// Launch optimization
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||||
QTime timer;
|
|
||||||
timer.start();
|
|
||||||
|
|
||||||
Optimizer_thread* opt_thread = cgal_code_odt_mesh_3(*item,
|
Optimizer_thread* opt_thread = cgal_code_odt_mesh_3(*item,
|
||||||
max_time,
|
max_time,
|
||||||
|
|
@ -203,27 +208,8 @@ Mesh_3_optimization_plugin::odt()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
opt_thread->start();
|
source_item_ = item;
|
||||||
opt_thread->wait();
|
launch_thread(opt_thread, "Odt iterations are running...");
|
||||||
Scene_c3t3_item* result_item = opt_thread->item();
|
|
||||||
CGAL::Mesh_optimization_return_code return_code = opt_thread->return_code();
|
|
||||||
|
|
||||||
std::stringstream sstr;
|
|
||||||
sstr << "Odt-smoothing of \"" << qPrintable(item->name()) << "\" done in "
|
|
||||||
<< timer.elapsed()/1000. << "s<br>"
|
|
||||||
<< "End reason: '" << translate(return_code) << "'<br>"
|
|
||||||
<< "( max time: " << max_time << " )<br>"
|
|
||||||
<< "( convergence: " << convergence << " )<br>"
|
|
||||||
<< "( freeze bound: " << freeze << " )<br>"
|
|
||||||
<< "( max iteration number: " << max_iteration_nb << " )<br>";
|
|
||||||
msg->information(sstr.str().c_str());
|
|
||||||
|
|
||||||
// -----------------------------------
|
|
||||||
// Treat result
|
|
||||||
// -----------------------------------
|
|
||||||
QString name("odt");
|
|
||||||
treat_result(*item, *result_item, name, create_new_item);
|
|
||||||
|
|
||||||
QApplication::restoreOverrideCursor();
|
QApplication::restoreOverrideCursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -283,8 +269,6 @@ Mesh_3_optimization_plugin::lloyd()
|
||||||
// Launch optimization
|
// Launch optimization
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||||
QTime timer;
|
|
||||||
timer.start();
|
|
||||||
|
|
||||||
Optimizer_thread* opt_thread = cgal_code_lloyd_mesh_3(*item,
|
Optimizer_thread* opt_thread = cgal_code_lloyd_mesh_3(*item,
|
||||||
max_time,
|
max_time,
|
||||||
|
|
@ -299,27 +283,8 @@ Mesh_3_optimization_plugin::lloyd()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
opt_thread->start();
|
source_item_ = item;
|
||||||
opt_thread->wait();
|
launch_thread(opt_thread, "Lloyd iterations are running...");
|
||||||
Scene_c3t3_item* result_item = opt_thread->item();
|
|
||||||
CGAL::Mesh_optimization_return_code return_code = opt_thread->return_code();
|
|
||||||
|
|
||||||
std::stringstream sstr;
|
|
||||||
sstr << "Lloyd-smoothing of \"" << qPrintable(item->name()) << "\" done in "
|
|
||||||
<< timer.elapsed()/1000. << "s<br>"
|
|
||||||
<< "End reason: '" << translate(return_code) << "'<br>"
|
|
||||||
<< "( max time: " << max_time << " )<br>"
|
|
||||||
<< "( convergence: " << convergence << " )<br>"
|
|
||||||
<< "( freeze bound: " << freeze << " )<br>"
|
|
||||||
<< "( max iteration number: " << max_iteration_nb << " )<br>";
|
|
||||||
msg->information(sstr.str().c_str());
|
|
||||||
|
|
||||||
// -----------------------------------
|
|
||||||
// Treat result
|
|
||||||
// -----------------------------------
|
|
||||||
QString name("lloyd");
|
|
||||||
treat_result(*item, *result_item, name, create_new_item);
|
|
||||||
|
|
||||||
QApplication::restoreOverrideCursor();
|
QApplication::restoreOverrideCursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -373,8 +338,6 @@ Mesh_3_optimization_plugin::perturb()
|
||||||
// Launch optimization
|
// Launch optimization
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||||
QTime timer;
|
|
||||||
timer.start();
|
|
||||||
|
|
||||||
Optimizer_thread* opt_thread = cgal_code_perturb_mesh_3(*item,
|
Optimizer_thread* opt_thread = cgal_code_perturb_mesh_3(*item,
|
||||||
max_time,
|
max_time,
|
||||||
|
|
@ -388,25 +351,8 @@ Mesh_3_optimization_plugin::perturb()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
opt_thread->start();
|
source_item_ = item;
|
||||||
opt_thread->wait();
|
launch_thread(opt_thread, "Sliver perturbation is running...");
|
||||||
Scene_c3t3_item* result_item = opt_thread->item();
|
|
||||||
CGAL::Mesh_optimization_return_code return_code = opt_thread->return_code();
|
|
||||||
|
|
||||||
std::stringstream sstr;
|
|
||||||
sstr << "Perturbation of \"" << qPrintable(item->name()) << "\" done in "
|
|
||||||
<< timer.elapsed()/1000. << "s<br>"
|
|
||||||
<< "End reason: '" << translate(return_code) << "'<br>"
|
|
||||||
<< "( max time: " << max_time << " )<br>"
|
|
||||||
<< "( sliver bound: " << sliver_bound << " )<br>";
|
|
||||||
msg->information(sstr.str().c_str());
|
|
||||||
|
|
||||||
// -----------------------------------
|
|
||||||
// Treat result
|
|
||||||
// -----------------------------------
|
|
||||||
QString name("perturb");
|
|
||||||
treat_result(*item, *result_item, name, create_new_item);
|
|
||||||
|
|
||||||
QApplication::restoreOverrideCursor();
|
QApplication::restoreOverrideCursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -454,8 +400,6 @@ Mesh_3_optimization_plugin::exude()
|
||||||
// Launch optimization
|
// Launch optimization
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||||
QTime timer;
|
|
||||||
timer.start();
|
|
||||||
|
|
||||||
Optimizer_thread* opt_thread = cgal_code_exude_mesh_3(*item,
|
Optimizer_thread* opt_thread = cgal_code_exude_mesh_3(*item,
|
||||||
max_time,
|
max_time,
|
||||||
|
|
@ -468,25 +412,8 @@ Mesh_3_optimization_plugin::exude()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
opt_thread->start();
|
source_item_ = item;
|
||||||
opt_thread->wait();
|
launch_thread(opt_thread, "Sliver exudation is running...");
|
||||||
Scene_c3t3_item* result_item = opt_thread->item();
|
|
||||||
CGAL::Mesh_optimization_return_code return_code = opt_thread->return_code();
|
|
||||||
|
|
||||||
std::stringstream sstr;
|
|
||||||
sstr << "Exudation of \"" << qPrintable(item->name()) << "\" done in "
|
|
||||||
<< timer.elapsed()/1000. << "s<br>"
|
|
||||||
<< "End reason: '" << translate(return_code) << "'<br>"
|
|
||||||
<< "( max time: " << max_time << " )<br>"
|
|
||||||
<< "( sliver bound: " << sliver_bound << " )<br>";
|
|
||||||
msg->information(sstr.str().c_str());
|
|
||||||
|
|
||||||
// -----------------------------------
|
|
||||||
// Treat result
|
|
||||||
// -----------------------------------
|
|
||||||
QString name("exude");
|
|
||||||
treat_result(*item, *result_item, name, create_new_item);
|
|
||||||
|
|
||||||
QApplication::restoreOverrideCursor();
|
QApplication::restoreOverrideCursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -496,13 +423,13 @@ void
|
||||||
Mesh_3_optimization_plugin::
|
Mesh_3_optimization_plugin::
|
||||||
treat_result(Scene_c3t3_item& source_item,
|
treat_result(Scene_c3t3_item& source_item,
|
||||||
Scene_c3t3_item& result_item,
|
Scene_c3t3_item& result_item,
|
||||||
const QString& name,
|
const QString& name) const
|
||||||
bool new_item_created) const
|
|
||||||
{
|
{
|
||||||
result_item.setName(tr("%1 [%2]").arg(source_item.name())
|
result_item.setName(tr("%1 [%2]").arg(source_item.name())
|
||||||
.arg(name));
|
.arg(name));
|
||||||
|
|
||||||
if ( new_item_created )
|
// If a new item has been created
|
||||||
|
if ( &source_item != &result_item)
|
||||||
{
|
{
|
||||||
const Scene_item::Bbox& bbox = result_item.bbox();
|
const Scene_item::Bbox& bbox = result_item.bbox();
|
||||||
result_item.setPosition((bbox.xmin + bbox.xmax)/2.f,
|
result_item.setPosition((bbox.xmin + bbox.xmax)/2.f,
|
||||||
|
|
@ -530,19 +457,87 @@ treat_result(Scene_c3t3_item& source_item,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string
|
|
||||||
|
void
|
||||||
|
Mesh_3_optimization_plugin::
|
||||||
|
optimization_done(Optimizer_thread* thread)
|
||||||
|
{
|
||||||
|
CGAL::Mesh_optimization_return_code return_code = thread->return_code();
|
||||||
|
QString name = thread->optimizer_name();
|
||||||
|
|
||||||
|
// Print message in console
|
||||||
|
QString str = QString("%1 of \"%2\" done in %3s<br>"
|
||||||
|
"End reason: '%4'<br>")
|
||||||
|
.arg(name)
|
||||||
|
.arg(source_item_->name())
|
||||||
|
.arg(thread->time())
|
||||||
|
.arg(translate(return_code));
|
||||||
|
|
||||||
|
Q_FOREACH( QString param, thread->parameters_log() )
|
||||||
|
{
|
||||||
|
str.append(QString("( %1 )<br>").arg(param));
|
||||||
|
}
|
||||||
|
|
||||||
|
msg->information(qPrintable(str));
|
||||||
|
|
||||||
|
// Treat new c3t3 item
|
||||||
|
Scene_c3t3_item* result_item = thread->item();
|
||||||
|
treat_result( *source_item_, *result_item, name);
|
||||||
|
|
||||||
|
// close message box
|
||||||
|
message_box_->close();
|
||||||
|
|
||||||
|
// free memory
|
||||||
|
delete thread;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Mesh_3_optimization_plugin::
|
||||||
|
launch_thread(Optimizer_thread* opt_thread, const QString& window_text)
|
||||||
|
{
|
||||||
|
// -----------------------------------
|
||||||
|
// Create message box with stop button
|
||||||
|
// -----------------------------------
|
||||||
|
message_box_ = new QMessageBox(QMessageBox::NoIcon,
|
||||||
|
"Optimization...",
|
||||||
|
window_text,
|
||||||
|
QMessageBox::Cancel,
|
||||||
|
mw);
|
||||||
|
|
||||||
|
message_box_->setDefaultButton(QMessageBox::Cancel);
|
||||||
|
QAbstractButton* cancelButton = message_box_->button(QMessageBox::Cancel);
|
||||||
|
cancelButton->setText(tr("Stop"));
|
||||||
|
|
||||||
|
QObject::connect(cancelButton, SIGNAL(clicked()),
|
||||||
|
opt_thread, SLOT(stop()));
|
||||||
|
|
||||||
|
message_box_->show();
|
||||||
|
|
||||||
|
// -----------------------------------
|
||||||
|
// Connect main thread to optimization thread and launch optimizer
|
||||||
|
// -----------------------------------
|
||||||
|
QObject::connect(opt_thread, SIGNAL(done(Optimizer_thread*)),
|
||||||
|
this, SLOT(optimization_done(Optimizer_thread*)));
|
||||||
|
|
||||||
|
opt_thread->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QString
|
||||||
translate(CGAL::Mesh_optimization_return_code rc)
|
translate(CGAL::Mesh_optimization_return_code rc)
|
||||||
{
|
{
|
||||||
switch (rc)
|
switch (rc)
|
||||||
{
|
{
|
||||||
case CGAL::BOUND_REACHED: return std::string("Bound reached");
|
case CGAL::MESH_OPTIMIZATION_UNKNOWN_ERROR: return QString("Unexpected error");
|
||||||
case CGAL::TIME_LIMIT_REACHED: return std::string("Time limit reached");
|
case CGAL::BOUND_REACHED: return QString("Bound reached");
|
||||||
case CGAL::CANT_IMPROVE_ANYMORE: return std::string("Can't improve anymore");
|
case CGAL::TIME_LIMIT_REACHED: return QString("Time limit reached");
|
||||||
case CGAL::CONVERGENCE_REACHED: return std::string("Convergence reached");
|
case CGAL::CANT_IMPROVE_ANYMORE: return QString("Can't improve anymore");
|
||||||
case CGAL::MAX_ITERATION_NUMBER_REACHED: return std::string("Max iteration number reached");
|
case CGAL::CONVERGENCE_REACHED: return QString("Convergence reached");
|
||||||
|
case CGAL::MAX_ITERATION_NUMBER_REACHED: return QString("Max iteration number reached");
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::string("ERROR");
|
return QString("ERROR");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
#include "Optimizer_thread.h"
|
#include "Optimizer_thread.h"
|
||||||
|
|
||||||
#include <CGAL/optimize_mesh_3.h>
|
#include <CGAL/optimize_mesh_3.h>
|
||||||
|
#include <CGAL/Mesh_3/Mesh_optimizer_interface.h>
|
||||||
#include <CGAL/Bbox_3.h>
|
#include <CGAL/Bbox_3.h>
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
@ -19,45 +20,53 @@ namespace cgp = CGAL::parameters;
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
// Optimization_function template class
|
// Optimization_function_base template class
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
template <typename Domain, typename Function>
|
template <typename Domain>
|
||||||
class Optimization_function
|
class Optimization_function_base
|
||||||
: public Optimization_function_interface
|
: public Optimization_function_interface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// This class takes the responsability of d
|
/// Constructor
|
||||||
Optimization_function(Scene_c3t3_item* i, Domain* d, const Function& f)
|
/// Takes the responsability of d
|
||||||
: item_(i), domain_(d), function_(f) {}
|
explicit
|
||||||
|
Optimization_function_base(C3t3& c3t3, Domain* d)
|
||||||
|
: c3t3_(c3t3), domain_(d) {}
|
||||||
|
|
||||||
virtual ~Optimization_function()
|
/// Destructor
|
||||||
|
virtual ~Optimization_function_base()
|
||||||
{
|
{
|
||||||
delete domain_;
|
delete domain_;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual CGAL::Mesh_optimization_return_code launch() const
|
/// Launch
|
||||||
|
virtual CGAL::Mesh_optimization_return_code launch()
|
||||||
{
|
{
|
||||||
return function_(item_->c3t3(), *domain_);
|
return (*this)(c3t3_, *domain_);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Scene_c3t3_item* item() const
|
protected:
|
||||||
{
|
/// Virtual operator() which should be overloaded
|
||||||
return item_;
|
virtual CGAL::Mesh_optimization_return_code
|
||||||
}
|
operator()(C3t3& c3t3, const Domain& domain) = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Scene_c3t3_item* item_;
|
C3t3& c3t3_;
|
||||||
Domain* domain_;
|
Domain* domain_;
|
||||||
Function function_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Prototype which will be partially specialized for each Parameter class
|
||||||
|
template < typename Domain, typename Parameters >
|
||||||
|
class Optimization_function {};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
// Optimization generic function (responsible of dynamic casting)
|
// Optimization generic function (responsible of dynamic casting)
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
template <typename Function>
|
template <typename Parameters>
|
||||||
Optimizer_thread* cgal_code_optimization(Scene_c3t3_item& c3t3_item,
|
Optimizer_thread* cgal_code_optimization(Scene_c3t3_item& c3t3_item,
|
||||||
const Function& f,
|
const Parameters& param,
|
||||||
const bool create_new_item)
|
const bool create_new_item)
|
||||||
{
|
{
|
||||||
// Create result item
|
// Create result item
|
||||||
|
|
@ -89,10 +98,10 @@ Optimizer_thread* cgal_code_optimization(Scene_c3t3_item& c3t3_item,
|
||||||
Image_mesh_domain* p_domain = new Image_mesh_domain(*p_image, 1e-6);
|
Image_mesh_domain* p_domain = new Image_mesh_domain(*p_image, 1e-6);
|
||||||
|
|
||||||
// Create thread
|
// Create thread
|
||||||
typedef Optimization_function<Image_mesh_domain,Function> Opt_function;
|
typedef Optimization_function<Image_mesh_domain,Parameters> Opt_function;
|
||||||
Opt_function* p_opt_function = new Opt_function(p_result_item, p_domain, f);
|
Opt_function* p_opt_function = new Opt_function(p_result_item->c3t3(), p_domain, param);
|
||||||
|
|
||||||
return new Optimizer_thread(p_opt_function);
|
return new Optimizer_thread(p_opt_function, p_result_item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -112,10 +121,10 @@ Optimizer_thread* cgal_code_optimization(Scene_c3t3_item& c3t3_item,
|
||||||
Mesh_domain* p_domain = new Mesh_domain(*p_poly);
|
Mesh_domain* p_domain = new Mesh_domain(*p_poly);
|
||||||
|
|
||||||
// Create thread
|
// Create thread
|
||||||
typedef Optimization_function<Mesh_domain,Function> Opt_function;
|
typedef Optimization_function<Mesh_domain,Parameters> Opt_function;
|
||||||
Opt_function* p_opt_function = new Opt_function(p_result_item, p_domain, f);
|
Opt_function* p_opt_function = new Opt_function(p_result_item->c3t3(), p_domain, param);
|
||||||
|
|
||||||
return new Optimizer_thread(p_opt_function);
|
return new Optimizer_thread(p_opt_function, p_result_item);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function
|
// Function
|
||||||
|
|
@ -139,10 +148,10 @@ Optimizer_thread* cgal_code_optimization(Scene_c3t3_item& c3t3_item,
|
||||||
new Function_mesh_domain(Function_wrapper(*p_function), dom_bbox, 1e-7);
|
new Function_mesh_domain(Function_wrapper(*p_function), dom_bbox, 1e-7);
|
||||||
|
|
||||||
// Create thread
|
// Create thread
|
||||||
typedef Optimization_function<Function_mesh_domain,Function> Opt_function;
|
typedef Optimization_function<Function_mesh_domain,Parameters> Opt_function;
|
||||||
Opt_function* p_opt_function = new Opt_function(p_result_item, p_domain, f);
|
Opt_function* p_opt_function = new Opt_function(p_result_item->c3t3(), p_domain, param);
|
||||||
|
|
||||||
return new Optimizer_thread(p_opt_function);
|
return new Optimizer_thread(p_opt_function, p_result_item);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -153,28 +162,93 @@ Optimizer_thread* cgal_code_optimization(Scene_c3t3_item& c3t3_item,
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
// Odt
|
// Odt
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
struct Odt_function
|
struct Odt_parameters
|
||||||
{
|
{
|
||||||
double time_limit;
|
double time_limit;
|
||||||
double convergence_ratio;
|
double convergence_ratio;
|
||||||
double freeze_ratio;
|
double freeze_ratio;
|
||||||
int max_iteration_nb;
|
int max_iteration_nb;
|
||||||
|
|
||||||
template <typename Domain>
|
QStringList log() const
|
||||||
CGAL::Mesh_optimization_return_code
|
|
||||||
operator()(C3t3& c3t3, const Domain& domain) const
|
|
||||||
{
|
{
|
||||||
// Odt
|
return QStringList()
|
||||||
return CGAL::odt_optimize_mesh_3(c3t3,
|
<< QString("time limit: %1").arg(time_limit)
|
||||||
domain,
|
<< QString("convergence ratio: %1").arg(convergence_ratio)
|
||||||
cgp::time_limit = time_limit,
|
<< QString("freeze ratio: %1").arg(freeze_ratio)
|
||||||
cgp::convergence = convergence_ratio,
|
<< QString("maximum iterations: %1").arg(max_iteration_nb);
|
||||||
cgp::freeze_bound = freeze_ratio,
|
|
||||||
cgp::max_iteration_number = max_iteration_nb);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class Odt_function
|
||||||
|
* Partial specialization of class Optimization_function for Odt
|
||||||
|
* Runs odt global optimization
|
||||||
|
*/
|
||||||
|
template <typename Domain>
|
||||||
|
class Optimization_function < Domain, Odt_parameters >
|
||||||
|
: public Optimization_function_base< Domain >
|
||||||
|
{
|
||||||
|
// Private types
|
||||||
|
typedef C3t3::Triangulation Tr;
|
||||||
|
typedef Tr::Geom_traits Gt;
|
||||||
|
|
||||||
|
typedef CGAL::Mesh_3::Mesh_sizing_field<Tr> Sizing;
|
||||||
|
typedef CGAL::Mesh_3::Odt_move<C3t3,Sizing> Move;
|
||||||
|
|
||||||
|
typedef typename CGAL::Mesh_3::Mesh_global_optimizer<C3t3,Domain,Move> Odt_optimizer;
|
||||||
|
|
||||||
|
typedef Optimization_function_base< Domain > Base;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// Constructor
|
||||||
|
Optimization_function(C3t3& c3t3, Domain* d, const Odt_parameters& p)
|
||||||
|
: Base(c3t3,d)
|
||||||
|
, odt_(NULL)
|
||||||
|
, p_(p) {}
|
||||||
|
|
||||||
|
/// Destructor
|
||||||
|
virtual ~Optimization_function() { delete odt_; }
|
||||||
|
|
||||||
|
/// Stops process (set time limit to 1ms)
|
||||||
|
virtual void stop() { odt_->set_time_limit(0.001); }
|
||||||
|
|
||||||
|
/// Log strings
|
||||||
|
virtual QString name() const { return QString("Odt"); }
|
||||||
|
virtual QStringList parameters_log() const { return p_.log(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/// Launch odt optimization
|
||||||
|
/// The content of this method is taken from CGAL::odt_optimize_mesh_3()
|
||||||
|
virtual CGAL::Mesh_optimization_return_code
|
||||||
|
operator()(C3t3& c3t3, const Domain& domain)
|
||||||
|
{
|
||||||
|
if ( NULL != odt_ ) { return CGAL::MESH_OPTIMIZATION_UNKNOWN_ERROR; }
|
||||||
|
|
||||||
|
// Create optimizer
|
||||||
|
odt_ = new Odt_optimizer(c3t3, domain, p_.freeze_ratio, p_.convergence_ratio);
|
||||||
|
if ( NULL == odt_ ) { return CGAL::MESH_OPTIMIZATION_UNKNOWN_ERROR; }
|
||||||
|
|
||||||
|
// Set max time
|
||||||
|
odt_->set_time_limit(p_.time_limit);
|
||||||
|
|
||||||
|
// 1000 iteration max to avoid infinite loops
|
||||||
|
int max_iteration_nb = ( 0 == p_.max_iteration_nb ) ? 1000
|
||||||
|
: p_.max_iteration_nb;
|
||||||
|
|
||||||
|
// Launch optimization
|
||||||
|
return (*odt_)(max_iteration_nb);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Odt_optimizer* odt_;
|
||||||
|
Odt_parameters p_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Global function cgal_code_odt_mesh_3
|
||||||
|
*/
|
||||||
Optimizer_thread*
|
Optimizer_thread*
|
||||||
cgal_code_odt_mesh_3(Scene_c3t3_item& c3t3_item,
|
cgal_code_odt_mesh_3(Scene_c3t3_item& c3t3_item,
|
||||||
const double time_limit,
|
const double time_limit,
|
||||||
|
|
@ -183,13 +257,13 @@ cgal_code_odt_mesh_3(Scene_c3t3_item& c3t3_item,
|
||||||
const int max_iteration_number,
|
const int max_iteration_number,
|
||||||
const bool create_new_item)
|
const bool create_new_item)
|
||||||
{
|
{
|
||||||
Odt_function f;
|
Odt_parameters p;
|
||||||
f.time_limit = time_limit;
|
p.time_limit = time_limit;
|
||||||
f.convergence_ratio = convergence_ratio;
|
p.convergence_ratio = convergence_ratio;
|
||||||
f.freeze_ratio = freeze_ratio;
|
p.freeze_ratio = freeze_ratio;
|
||||||
f.max_iteration_nb = max_iteration_number;
|
p.max_iteration_nb = max_iteration_number;
|
||||||
|
|
||||||
return cgal_code_optimization(c3t3_item, f, create_new_item);
|
return cgal_code_optimization(c3t3_item, p, create_new_item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -197,28 +271,93 @@ cgal_code_odt_mesh_3(Scene_c3t3_item& c3t3_item,
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
// Lloyd
|
// Lloyd
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
struct Lloyd_function
|
struct Lloyd_parameters
|
||||||
{
|
{
|
||||||
double time_limit;
|
double time_limit;
|
||||||
double convergence_ratio;
|
double convergence_ratio;
|
||||||
double freeze_ratio;
|
double freeze_ratio;
|
||||||
int max_iteration_nb;
|
int max_iteration_nb;
|
||||||
|
|
||||||
template <typename Domain>
|
QStringList log() const
|
||||||
CGAL::Mesh_optimization_return_code
|
|
||||||
operator()(C3t3& c3t3, const Domain& domain) const
|
|
||||||
{
|
{
|
||||||
// Lloyd
|
return QStringList()
|
||||||
return CGAL::lloyd_optimize_mesh_3(c3t3,
|
<< QString("time limit: %1").arg(time_limit)
|
||||||
domain,
|
<< QString("convergence ratio: %1").arg(convergence_ratio)
|
||||||
cgp::time_limit = time_limit,
|
<< QString("freeze ratio: %1").arg(freeze_ratio)
|
||||||
cgp::convergence = convergence_ratio,
|
<< QString("maximum iterations: %1").arg(max_iteration_nb);
|
||||||
cgp::freeze_bound = freeze_ratio,
|
|
||||||
cgp::max_iteration_number = max_iteration_nb);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class Lloyd_function
|
||||||
|
* Partial specialization of class Optimization_function for Lloyd
|
||||||
|
* Runs lloyd global optimization
|
||||||
|
*/
|
||||||
|
template <typename Domain>
|
||||||
|
class Optimization_function < Domain, Lloyd_parameters >
|
||||||
|
: public Optimization_function_base< Domain >
|
||||||
|
{
|
||||||
|
// Private types
|
||||||
|
typedef C3t3::Triangulation Tr;
|
||||||
|
typedef Tr::Geom_traits Gt;
|
||||||
|
|
||||||
|
typedef CGAL::Mesh_3::Mesh_sizing_field<Tr> Sizing;
|
||||||
|
typedef CGAL::Mesh_3::Lloyd_move<C3t3,Sizing> Move;
|
||||||
|
|
||||||
|
typedef typename CGAL::Mesh_3::Mesh_global_optimizer<C3t3,Domain,Move> Lloyd_optimizer;
|
||||||
|
|
||||||
|
typedef Optimization_function_base< Domain > Base;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// Constructor
|
||||||
|
Optimization_function(C3t3& c3t3, Domain* d, const Lloyd_parameters& p)
|
||||||
|
: Base(c3t3,d)
|
||||||
|
, lloyd_(NULL)
|
||||||
|
, p_(p) {}
|
||||||
|
|
||||||
|
/// Destructor
|
||||||
|
virtual ~Optimization_function() { delete lloyd_; }
|
||||||
|
|
||||||
|
/// Stops process (set time limit to 1ms)
|
||||||
|
virtual void stop() { lloyd_->set_time_limit(0.001); }
|
||||||
|
|
||||||
|
/// Log strings
|
||||||
|
virtual QString name() const { return QString("Lloyd"); }
|
||||||
|
virtual QStringList parameters_log() const { return p_.log(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/// Launch lloyd optimization
|
||||||
|
/// The content of this method is taken from CGAL::lloyd_optimize_mesh_3()
|
||||||
|
virtual CGAL::Mesh_optimization_return_code
|
||||||
|
operator()(C3t3& c3t3, const Domain& domain)
|
||||||
|
{
|
||||||
|
if ( NULL != lloyd_ ) { return CGAL::MESH_OPTIMIZATION_UNKNOWN_ERROR; }
|
||||||
|
|
||||||
|
// Create optimizer
|
||||||
|
lloyd_ = new Lloyd_optimizer(c3t3, domain, p_.freeze_ratio, p_.convergence_ratio);
|
||||||
|
if ( NULL == lloyd_ ) { return CGAL::MESH_OPTIMIZATION_UNKNOWN_ERROR; }
|
||||||
|
|
||||||
|
// Set max time
|
||||||
|
lloyd_->set_time_limit(p_.time_limit);
|
||||||
|
|
||||||
|
// 1000 iteration max to avoid infinite loops
|
||||||
|
int max_iteration_nb = ( 0 == p_.max_iteration_nb ) ? 1000
|
||||||
|
: p_.max_iteration_nb;
|
||||||
|
|
||||||
|
// Launch optimization
|
||||||
|
return (*lloyd_)(max_iteration_nb);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Lloyd_optimizer* lloyd_;
|
||||||
|
Lloyd_parameters p_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Global function cgal_code_lloyd_mesh_3
|
||||||
|
*/
|
||||||
Optimizer_thread*
|
Optimizer_thread*
|
||||||
cgal_code_lloyd_mesh_3(Scene_c3t3_item& c3t3_item,
|
cgal_code_lloyd_mesh_3(Scene_c3t3_item& c3t3_item,
|
||||||
const double time_limit,
|
const double time_limit,
|
||||||
|
|
@ -227,13 +366,13 @@ cgal_code_lloyd_mesh_3(Scene_c3t3_item& c3t3_item,
|
||||||
const int max_iteration_number,
|
const int max_iteration_number,
|
||||||
const bool create_new_item)
|
const bool create_new_item)
|
||||||
{
|
{
|
||||||
Lloyd_function f;
|
Lloyd_parameters p;
|
||||||
f.time_limit = time_limit;
|
p.time_limit = time_limit;
|
||||||
f.convergence_ratio = convergence_ratio;
|
p.convergence_ratio = convergence_ratio;
|
||||||
f.freeze_ratio = freeze_ratio;
|
p.freeze_ratio = freeze_ratio;
|
||||||
f.max_iteration_nb = max_iteration_number;
|
p.max_iteration_nb = max_iteration_number;
|
||||||
|
|
||||||
return cgal_code_optimization(c3t3_item, f, create_new_item);
|
return cgal_code_optimization(c3t3_item, p, create_new_item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -241,57 +380,186 @@ cgal_code_lloyd_mesh_3(Scene_c3t3_item& c3t3_item,
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
// Perturbation
|
// Perturbation
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
struct Perturb_function
|
struct Perturb_parameters
|
||||||
{
|
{
|
||||||
double time_limit;
|
double time_limit;
|
||||||
double sliver_bound;
|
double sliver_bound;
|
||||||
|
|
||||||
template <typename Domain>
|
QStringList log() const
|
||||||
CGAL::Mesh_optimization_return_code
|
|
||||||
operator()(C3t3& c3t3, const Domain& domain) const
|
|
||||||
{
|
{
|
||||||
// Perturbation
|
return QStringList()
|
||||||
return CGAL::perturb_mesh_3(c3t3,
|
<< QString("time limit: %1").arg(time_limit)
|
||||||
domain,
|
<< QString("sliver bound: %1").arg(sliver_bound);
|
||||||
cgp::sliver_bound = sliver_bound,
|
|
||||||
cgp::time_limit = time_limit);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class Perturb_function
|
||||||
|
* Partial specialization of class Optimization_function for perturbation
|
||||||
|
* Runs sliver perturbation
|
||||||
|
*/
|
||||||
|
template <typename Domain>
|
||||||
|
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<Gt> Sc;
|
||||||
|
|
||||||
|
typedef CGAL::Mesh_3::Sliver_perturber<C3t3,Domain,Sc> Perturber;
|
||||||
|
|
||||||
|
typedef Optimization_function_base< Domain > Base;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// Constructor
|
||||||
|
Optimization_function(C3t3& c3t3, Domain* d, const Perturb_parameters& p)
|
||||||
|
: Base(c3t3,d)
|
||||||
|
, perturb_(NULL)
|
||||||
|
, p_(p) {}
|
||||||
|
|
||||||
|
/// Destructor
|
||||||
|
~Optimization_function() { delete perturb_; }
|
||||||
|
|
||||||
|
/// Stops process (set time limit to 1ms)
|
||||||
|
virtual void stop() { perturb_->set_time_limit(0.001); }
|
||||||
|
|
||||||
|
/// Log strings
|
||||||
|
virtual QString name() const { return QString("Perturb"); }
|
||||||
|
virtual QStringList parameters_log() const { return p_.log(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/// Launch sliver perturbation
|
||||||
|
/// The content of this method is taken from CGAL::perturb_mesh_3()
|
||||||
|
virtual CGAL::Mesh_optimization_return_code
|
||||||
|
operator()(C3t3& c3t3, const Domain& domain)
|
||||||
|
{
|
||||||
|
if ( NULL != perturb_ ) { return CGAL::MESH_OPTIMIZATION_UNKNOWN_ERROR; }
|
||||||
|
|
||||||
|
typedef CGAL::Mesh_3::Sq_radius_perturbation<C3t3,Domain,Sc> Sq_radius;
|
||||||
|
typedef CGAL::Mesh_3::Volume_perturbation<C3t3,Domain,Sc> Volume;
|
||||||
|
typedef CGAL::Mesh_3::Dihedral_angle_perturbation<C3t3,Domain,Sc> Dihedral_angle;
|
||||||
|
typedef CGAL::Mesh_3::Li_random_perturbation<C3t3,Domain,Sc> Li_random;
|
||||||
|
|
||||||
|
// Build perturber
|
||||||
|
perturb_ = new Perturber(c3t3,domain);
|
||||||
|
if ( NULL == perturb_ ) { return CGAL::MESH_OPTIMIZATION_UNKNOWN_ERROR; }
|
||||||
|
|
||||||
|
// Add perturbations
|
||||||
|
perturb_->add_perturbation(new Sq_radius(40,0.02));
|
||||||
|
perturb_->add_perturbation(new Volume(40,0.02));
|
||||||
|
perturb_->add_perturbation(new Dihedral_angle(40,0.02));
|
||||||
|
perturb_->add_perturbation(new Li_random(100,0.05));
|
||||||
|
|
||||||
|
// Set max time
|
||||||
|
perturb_->set_time_limit(p_.time_limit);
|
||||||
|
|
||||||
|
// Launch perturber
|
||||||
|
if ( p_.sliver_bound != 0 ) { return (*perturb_)(p_.sliver_bound); }
|
||||||
|
else { return (*perturb_)(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Perturber* perturb_;
|
||||||
|
Perturb_parameters p_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Global function cgal_code_perturb_mesh_3
|
||||||
|
*/
|
||||||
Optimizer_thread*
|
Optimizer_thread*
|
||||||
cgal_code_perturb_mesh_3(Scene_c3t3_item& c3t3_item,
|
cgal_code_perturb_mesh_3(Scene_c3t3_item& c3t3_item,
|
||||||
const double time_limit,
|
const double time_limit,
|
||||||
const double sliver_bound,
|
const double sliver_bound,
|
||||||
const bool create_new_item)
|
const bool create_new_item)
|
||||||
{
|
{
|
||||||
Perturb_function f;
|
Perturb_parameters p;
|
||||||
f.sliver_bound = sliver_bound;
|
p.sliver_bound = sliver_bound;
|
||||||
f.time_limit = time_limit;
|
p.time_limit = time_limit;
|
||||||
|
|
||||||
return cgal_code_optimization(c3t3_item, f, create_new_item);
|
return cgal_code_optimization(c3t3_item, p, create_new_item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
// Exudation
|
// Exudation
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
struct Exude_function
|
struct Exude_parameters
|
||||||
{
|
{
|
||||||
double time_limit;
|
double time_limit;
|
||||||
double sliver_bound;
|
double sliver_bound;
|
||||||
|
|
||||||
CGAL::Mesh_optimization_return_code
|
QStringList log() const
|
||||||
operator()(C3t3& c3t3, int) const
|
|
||||||
{
|
{
|
||||||
// Perturbation
|
return QStringList()
|
||||||
return CGAL::exude_mesh_3(c3t3,
|
<< QString("time limit: %1").arg(time_limit)
|
||||||
cgp::sliver_bound = sliver_bound,
|
<< QString("sliver bound: %1").arg(sliver_bound);
|
||||||
cgp::time_limit = time_limit);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class Exude_function
|
||||||
|
* Partial specialization of class Optimization_function for exudation
|
||||||
|
* Runs sliver exudation
|
||||||
|
*/
|
||||||
|
template <typename Domain>
|
||||||
|
class Optimization_function < Domain, Exude_parameters >
|
||||||
|
: public Optimization_function_base< Domain >
|
||||||
|
{
|
||||||
|
// Private types
|
||||||
|
typedef C3t3::Triangulation::Geom_traits Gt;
|
||||||
|
typedef CGAL::Mesh_3::Min_dihedral_angle_criterion<Gt> Sc;
|
||||||
|
typedef CGAL::Mesh_3::Slivers_exuder<C3t3, Sc> Exuder;
|
||||||
|
|
||||||
|
typedef Optimization_function_base< Domain > Base;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Constructor
|
||||||
|
Optimization_function(C3t3& c3t3, Domain* d, const Exude_parameters& p)
|
||||||
|
: Base(c3t3,d)
|
||||||
|
, exude_(NULL)
|
||||||
|
, p_(p) {}
|
||||||
|
|
||||||
|
/// Destructor
|
||||||
|
~Optimization_function() { delete exude_; }
|
||||||
|
|
||||||
|
/// Stops process (set time limit to 1ms)
|
||||||
|
virtual void stop() { exude_->set_time_limit(0.001); }
|
||||||
|
|
||||||
|
// Log strings
|
||||||
|
virtual QString name() const { return QString("Exude"); }
|
||||||
|
virtual QStringList parameters_log() const { return p_.log(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/// Launch sliver exudation
|
||||||
|
/// The content of this method is taken from CGAL::exude_mesh_3()
|
||||||
|
virtual CGAL::Mesh_optimization_return_code
|
||||||
|
operator()(C3t3& c3t3, const Domain&)
|
||||||
|
{
|
||||||
|
if ( NULL != exude_ ) { return CGAL::MESH_OPTIMIZATION_UNKNOWN_ERROR; }
|
||||||
|
|
||||||
|
// Create exuder
|
||||||
|
exude_ = new Exuder(c3t3);
|
||||||
|
if ( NULL == exude_ ) { return CGAL::MESH_OPTIMIZATION_UNKNOWN_ERROR; }
|
||||||
|
|
||||||
|
// Set time_limit
|
||||||
|
exude_->set_time_limit(p_.time_limit);
|
||||||
|
|
||||||
|
// Launch exudation
|
||||||
|
return (*exude_)(p_.sliver_bound);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Exuder* exude_;
|
||||||
|
Exude_parameters p_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Global function cgal_code_exude_mesh_3
|
||||||
|
*/
|
||||||
Optimizer_thread*
|
Optimizer_thread*
|
||||||
cgal_code_exude_mesh_3(Scene_c3t3_item& c3t3_item,
|
cgal_code_exude_mesh_3(Scene_c3t3_item& c3t3_item,
|
||||||
const double time_limit,
|
const double time_limit,
|
||||||
|
|
@ -308,13 +576,13 @@ cgal_code_exude_mesh_3(Scene_c3t3_item& c3t3_item,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exudation
|
// Exudation
|
||||||
Exude_function f;
|
Exude_parameters p;
|
||||||
f.sliver_bound = sliver_bound;
|
p.sliver_bound = sliver_bound;
|
||||||
f.time_limit = time_limit;
|
p.time_limit = time_limit;
|
||||||
|
|
||||||
// Create thread
|
// Create thread
|
||||||
typedef Optimization_function<int,Exude_function> Opt_function;
|
typedef Optimization_function<int,Exude_parameters> Opt_function;
|
||||||
Opt_function* p_opt_function = new Opt_function(p_result_item, NULL, f);
|
Opt_function* p_opt_function = new Opt_function(p_result_item->c3t3(), NULL, p);
|
||||||
|
|
||||||
return new Optimizer_thread(p_opt_function);
|
return new Optimizer_thread(p_opt_function, p_result_item);
|
||||||
}
|
}
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
// File Description :
|
// File Description :
|
||||||
//******************************************************************************
|
//******************************************************************************
|
||||||
|
|
||||||
|
#include <QTime>
|
||||||
#include "Optimizer_thread.h"
|
#include "Optimizer_thread.h"
|
||||||
|
|
||||||
Optimizer_thread::~Optimizer_thread()
|
Optimizer_thread::~Optimizer_thread()
|
||||||
|
|
@ -33,7 +34,23 @@ void
|
||||||
Optimizer_thread::
|
Optimizer_thread::
|
||||||
run()
|
run()
|
||||||
{
|
{
|
||||||
|
QTime timer;
|
||||||
|
timer.start();
|
||||||
|
|
||||||
rc_ = f_->launch();
|
rc_ = f_->launch();
|
||||||
|
|
||||||
|
time_ = double(timer.elapsed()) / 1000;
|
||||||
|
|
||||||
|
emit done(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Optimizer_thread::
|
||||||
|
stop()
|
||||||
|
{
|
||||||
|
f_->stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#include "Optimizer_thread.moc"
|
#include "Optimizer_thread.moc"
|
||||||
|
|
@ -26,6 +26,8 @@
|
||||||
|
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QString>
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
#include <CGAL/Mesh_optimization_return_code.h>
|
#include <CGAL/Mesh_optimization_return_code.h>
|
||||||
|
|
||||||
|
|
@ -35,28 +37,56 @@ class Optimization_function_interface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~Optimization_function_interface() {}
|
virtual ~Optimization_function_interface() {}
|
||||||
virtual CGAL::Mesh_optimization_return_code launch() const = 0;
|
|
||||||
virtual Scene_c3t3_item* item() const = 0;
|
// Launch
|
||||||
|
virtual CGAL::Mesh_optimization_return_code launch() = 0;
|
||||||
|
|
||||||
|
// Stop
|
||||||
|
virtual void stop() = 0;
|
||||||
|
|
||||||
|
// Logs
|
||||||
|
virtual QString name() const = 0;
|
||||||
|
virtual QStringList parameters_log() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Optimizer_thread : public QThread
|
class Optimizer_thread : public QThread
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
Optimizer_thread(Optimization_function_interface* f)
|
Optimizer_thread(Optimization_function_interface* f, Scene_c3t3_item* item)
|
||||||
: f_(f), rc_() {}
|
: f_(f), item_(item), rc_(), time_(0) {}
|
||||||
|
|
||||||
virtual ~Optimizer_thread();
|
virtual ~Optimizer_thread();
|
||||||
|
|
||||||
Scene_c3t3_item* item() const { return f_->item(); }
|
// Scene item
|
||||||
|
Scene_c3t3_item* item() const { return item_; }
|
||||||
|
|
||||||
|
// Infos about optimization
|
||||||
CGAL::Mesh_optimization_return_code return_code() const { return rc_; }
|
CGAL::Mesh_optimization_return_code return_code() const { return rc_; }
|
||||||
|
double time() const { return time_; }
|
||||||
|
|
||||||
|
// Logs
|
||||||
|
QString optimizer_name() const { return f_->name(); }
|
||||||
|
QStringList parameters_log() const { return f_->parameters_log(); }
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
// Stop
|
||||||
|
void stop();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
// Emitted at the end of the process
|
||||||
|
void done(Optimizer_thread*);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void run();
|
// Overload of QThread function
|
||||||
|
virtual void run();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Optimization_function_interface* f_;
|
Optimization_function_interface* f_;
|
||||||
|
Scene_c3t3_item* item_;
|
||||||
CGAL::Mesh_optimization_return_code rc_;
|
CGAL::Mesh_optimization_return_code rc_;
|
||||||
|
double time_; // in seconds
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // DEMO_MESH_3_OPTIMIZER_THREAD_H
|
#endif // DEMO_MESH_3_OPTIMIZER_THREAD_H
|
||||||
|
|
@ -28,6 +28,7 @@ namespace CGAL {
|
||||||
|
|
||||||
enum Mesh_optimization_return_code
|
enum Mesh_optimization_return_code
|
||||||
{
|
{
|
||||||
|
MESH_OPTIMIZATION_UNKNOWN_ERROR=-1,
|
||||||
BOUND_REACHED=0,
|
BOUND_REACHED=0,
|
||||||
TIME_LIMIT_REACHED,
|
TIME_LIMIT_REACHED,
|
||||||
CANT_IMPROVE_ANYMORE,
|
CANT_IMPROVE_ANYMORE,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue