Commit b7365130 authored by Matthias Möller's avatar Matthias Möller

add process interface to decimater and using the observer pattern for progress bar

git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@20247 383ad7c9-94d9-4d36-a494-682f7c89f535
parent cf8b535b
#include "DecimateThread.hh"
void DecimateThread::notify(size_t _step)
{
emit state(jobId(),(100*_step)/maxCollapses_);
}
bool DecimateThread::abort() const
{
return abort_;
}
DecimateThread::DecimateThread(Params _param, QString _jobId, int _objId):
OpenFlipperThread(_jobId), Observer(1),
abort_(false), maxCollapses_(0),
param_(_param), baseDec_(0), objId_(_objId)
{
connect( this ,SIGNAL(function()), this,SLOT(decimate()), Qt::DirectConnection) ;
if (param_.dec)
baseDec_ = param_.dec;
else if (param_.mcDec)
baseDec_ = param_.mcDec;
else if (param_.mixedDec)
baseDec_ = param_.mixedDec;
baseDec_->set_observer(this);
if (param_.verticesCount != -1)
maxCollapses_ = baseDec_->mesh().n_vertices() - param_.verticesCount;
else if (param_.facesCount != -1)
maxCollapses_ = baseDec_->mesh().n_faces() - param_.facesCount;
else
maxCollapses_ = 0.8*baseDec_->mesh().n_vertices(); //0.8 just magic number since we cannot say, when it stops
}
DecimateThread::~DecimateThread()
{
}
void DecimateThread::cancel()
{
abort_ = true;
}
DecimateThread::BaseDecimaterType* DecimateThread::baseDecimater()
{
return baseDec_;
}
int DecimateThread::objectId() const
{
return objId_;
}
void DecimateThread::decimate()
{
if(param_.dec )
{
if ( param_.verticesCount != -1 )
param_.dec->decimate_to(param_.verticesCount);
else if (param_.facesCount != -1)
param_.dec->decimate_to_faces(0, param_.facesCount);
else // constraints only
param_.dec->decimate_to_faces(0, 1);
}
else if (param_.mcDec)
{
param_.mcDec->set_samples(param_.samples);
if ( param_.verticesCount != -1 )
param_.mcDec->decimate_to(param_.verticesCount);
else if (param_.facesCount != -1 )
param_.mcDec->decimate_to_faces(0, param_.facesCount);
else // constraints only
param_.mcDec->decimate_to_faces(0, 1);
}
else if (param_.mixedDec)
{
param_.mixedDec->set_samples(param_.samples);
if ( param_.verticesCount != -1 )
param_.mixedDec->decimate_to(param_.verticesCount,param_.mc_factor);
else if (param_.facesCount != -1 )
param_.mixedDec->decimate_to_faces(0, param_.facesCount,param_.mc_factor);
else // constraints only
param_.mixedDec->decimate_to_faces(0, 1,param_.mc_factor);
}
emit state(jobId(),100);
}
/*===========================================================================*\
* *
* OpenFlipper *
* Copyright (C) 2001-2014 by Computer Graphics Group, RWTH Aachen *
* www.openflipper.org *
* *
*--------------------------------------------------------------------------- *
* This file is part of OpenFlipper. *
* *
* OpenFlipper is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of *
* the License, or (at your option) any later version with the *
* following exceptions: *
* *
* If other files instantiate templates or use macros *
* or inline functions from this file, or you compile this file and *
* link it with other files to produce an executable, this file does *
* not by itself cause the resulting executable to be covered by the *
* GNU Lesser General Public License. This exception does not however *
* invalidate any other reasons why the executable file might be *
* covered by the GNU Lesser General Public License. *
* *
* OpenFlipper 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 Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU LesserGeneral Public *
* License along with OpenFlipper. If not, *
* see <http://www.gnu.org/licenses/>. *
* *
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision$ *
* $LastChangedBy$ *
* $Date$ *
* *
\*===========================================================================*/
#ifndef DECIMATETHREAD_HH
#define DECIMATETHREAD_HH
#include <OpenMesh/Tools/Decimater/DecimaterT.hh>
#include <OpenMesh/Tools/Decimater/McDecimaterT.hh>
#include <OpenMesh/Tools/Decimater/MixedDecimaterT.hh>
#include <ObjectTypes/TriangleMesh/TriangleMesh.hh>
#include <QObject>
#include <OpenFlipper/threads/OpenFlipperThread.hh>
class DecimateThread : public OpenFlipperThread, public OpenMesh::Decimater::Observer
{
Q_OBJECT
public:
typedef OpenMesh::Decimater::BaseDecimaterT< TriMesh > BaseDecimaterType;
typedef OpenMesh::Decimater::DecimaterT< TriMesh > DecimaterType;
typedef OpenMesh::Decimater::McDecimaterT< TriMesh > McDecimaterType;
typedef OpenMesh::Decimater::MixedDecimaterT< TriMesh > MixedDecimaterType;
struct Params
{
DecimaterType* dec;
McDecimaterType* mcDec;
MixedDecimaterType* mixedDec;
bool useIncremental;
bool useMC;
bool useMixed;
float mc_factor;
int verticesCount; // -1 if not decimate to vertices
int facesCount; // -1 if not decimate to faces
int samples;
};
private:
bool abort_;
int maxCollapses_;
Params param_;
QString jobId_;
BaseDecimaterType* baseDec_;
int objId_;
public:
virtual void notify(size_t _step);
virtual bool abort() const;
public slots:
void decimate();
public:
void cancel();
DecimateThread(Params _param, QString _jobId, int _objId);
~DecimateThread();
BaseDecimaterType* baseDecimater();
int objectId() const;
};
#endif // DECIMATETHREAD_HH
......@@ -73,7 +73,9 @@
DecimaterPlugin::DecimaterPlugin() :
tool_(0),
toolIcon_(0)
decimater_objects_(),
toolIcon_(0),
runningJobs_(0)
{
}
......@@ -433,6 +435,7 @@ void DecimaterPlugin::slot_decimate()
return;
//decimate
runningJobs_ = decimater_objects_.size();
for (std::vector< ptr::shared_ptr<DecimaterInit> >::iterator decIter = decimater_objects_.begin();
decIter != decimater_objects_.end(); ++decIter)
{
......@@ -460,57 +463,68 @@ void DecimaterPlugin::slot_decimate()
decimater->module( decInit->hModEdgeLength ).set_edge_length( tool_->edgeLength->value() );
}
DecimaterType* dec = dynamic_cast<DecimaterType*>(decimater.get());
McDecimaterType* mcDec = dynamic_cast<McDecimaterType*>(decimater.get());
MixedDecimaterType* mixedDec = dynamic_cast<MixedDecimaterType*>(decimater.get());
// fill data for the decimate thread
DecimateThread::Params params;
params.dec = (tool_->rbUseDecimater->isChecked()) ? dynamic_cast<DecimaterType*>(decimater.get()) : NULL;
params.mcDec = (tool_->rbUseMC->isChecked()) ? dynamic_cast<McDecimaterType*>(decimater.get()) : NULL;
params.mixedDec = (tool_->rbUseMixed->isChecked()) ? dynamic_cast<MixedDecimaterType*>(decimater.get()) : NULL;
if(dec && tool_->rbUseDecimater->isChecked())
{
if ( tool_->rbVertices->isChecked() )
dec->decimate_to(tool_->verticesCount->value());
else if (tool_->rbTriangles->isChecked() )
dec->decimate_to_faces(0, tool_->trianglesCount->value());
else // constraints only
dec->decimate_to_faces(0, 1);
}
else if (mcDec && tool_->rbUseMC->isChecked())
{
mcDec->set_samples(tool_->randomSamplesCounter->value());
if ( tool_->rbVertices->isChecked() )
mcDec->decimate_to(tool_->verticesCount->value());
else if (tool_->rbTriangles->isChecked() )
mcDec->decimate_to_faces(0, tool_->trianglesCount->value());
else // constraints only
mcDec->decimate_to_faces(0, 1);
}
else if (mixedDec && tool_->rbUseMixed->isChecked())
{
float mc_factor = 1.0 - (tool_->mixedFactorCounter->value()*0.01);
mixedDec->set_samples(tool_->randomSamplesCounter->value());
params.facesCount = (tool_->rbTriangles->isChecked()) ? tool_->trianglesCount->value() : -1;
params.verticesCount = (tool_->rbVertices->isChecked() ) ? tool_->verticesCount->value() : -1;
params.samples = tool_->randomSamplesCounter->value();
params.mc_factor = 1.0 - (tool_->mixedFactorCounter->value()*0.01);
if ( tool_->rbVertices->isChecked() )
mixedDec->decimate_to(tool_->verticesCount->value(),mc_factor);
else if (tool_->rbTriangles->isChecked() )
mixedDec->decimate_to_faces(0, tool_->trianglesCount->value(),mc_factor);
else // constraints only
mixedDec->decimate_to_faces(0, 1,mc_factor);
}else
{
emit log(LOGERR,tr("Could not find Decimater Type"));
}
// create and start decimate thread
QString jobId = QString("Decimate_Object_%1").arg(decInit->objId);
DecimateThread* th = new DecimateThread(params, jobId, decInit->objId);
connect(th, SIGNAL(finished(QString)), this,SIGNAL(finishJob(QString)));
connect(th, SIGNAL(finished(QString)), this, SLOT(slot_decimate_finished(QString)));
connect(th, SIGNAL(state(QString, int)), this, SIGNAL(setJobState(QString, int)));
connect(this, SIGNAL(jobCanceled(QString)), th, SLOT(slotCancel(QString)));
TriMeshObject* object = PluginFunctions::triMeshObject(decInit->objId);
tool_->pbDecimate->setEnabled(false);
tool_->pbInitialize->setEnabled(false);
decInit->decimater->mesh().garbage_collection();
decInit->decimater->mesh().update_normals();
object->update();
emit startJob(jobId , QString("Decimate Object with Id %1").arg(decInit->objId) , 0, 100, false);
th->start();
th->startProcessing();
// Create backup
emit createBackup(decInit->objId, "Decimation");
emit updatedObject( decInit->objId , UPDATE_TOPOLOGY );
}
emit updateView();
}
void DecimaterPlugin::canceledJob (QString _job )
{
emit jobCanceled(_job);
}
void DecimaterPlugin::slot_decimate_finished(QString _jobId)
{
//This function is executed by the main thread! but the sender is the finished thread
DecimateThread* thread = dynamic_cast<DecimateThread*>(sender());
if (!thread)
return;
if (!thread->baseDecimater())
return;
//update mesh
thread->baseDecimater()->mesh().garbage_collection();
thread->baseDecimater()->mesh().update_normals();
emit updatedObject( thread->objectId() , UPDATE_TOPOLOGY );
emit createBackup( thread->objectId(), "Decimation");
//cleanup when all threads are done
--runningJobs_;//running in main thread, so no race condition
if (runningJobs_ == 0)
{
tool_->pbDecimate->setEnabled(true);
tool_->pbInitialize->setEnabled(true);
emit updateView();
}
}
......
......@@ -45,10 +45,6 @@
//== INCLUDES =================================================================
#include <QObject>
#include <QMenuBar>
#include <QTimer>
#include <OpenFlipper/BasePlugin/BaseInterface.hh>
#include <OpenFlipper/BasePlugin/ToolboxInterface.hh>
#include <OpenFlipper/BasePlugin/BackupInterface.hh>
......@@ -56,6 +52,7 @@
#include <OpenFlipper/BasePlugin/ScriptInterface.hh>
#include <OpenFlipper/BasePlugin/RPCInterface.hh>
#include <OpenFlipper/BasePlugin/LoadSaveInterface.hh>
#include <OpenFlipper/BasePlugin/ProcessInterface.hh>
#include <OpenFlipper/common/Types.hh>
......@@ -65,6 +62,8 @@
#include "DecimaterToolbarWidget.hh"
#include "DecimateThread.hh"
#include <OpenMesh/Tools/Decimater/DecimaterT.hh>
#include <OpenMesh/Tools/Decimater/McDecimaterT.hh>
#include <OpenMesh/Tools/Decimater/MixedDecimaterT.hh>
......@@ -82,12 +81,16 @@
#include <ACG/Utils/SmartPointer.hh>
#include <vector>
#include <QObject>
#include <QMenuBar>
#include <QTimer>
//== CLASS DEFINITION =========================================================
/** Plugin for Decimater Support
*/
class DecimaterPlugin : public QObject, BaseInterface, ToolboxInterface, LoggingInterface, ScriptInterface, BackupInterface, RPCInterface, LoadSaveInterface
class DecimaterPlugin : public QObject, BaseInterface, ToolboxInterface, LoggingInterface, ScriptInterface, BackupInterface, RPCInterface, LoadSaveInterface, ProcessInterface
{
Q_OBJECT
Q_INTERFACES(BaseInterface)
......@@ -97,6 +100,7 @@ class DecimaterPlugin : public QObject, BaseInterface, ToolboxInterface, Logging
Q_INTERFACES(ScriptInterface)
Q_INTERFACES(RPCInterface)
Q_INTERFACES(LoadSaveInterface)
Q_INTERFACES(ProcessInterface)
#if QT_VERSION >= 0x050000
Q_PLUGIN_METADATA(IID "org.OpenFlipper.Plugins.Plugin-Decimater")
......@@ -126,6 +130,17 @@ signals:
// BackupInterface
void createBackup( int _id , QString _name, UpdateType _type = UPDATE_ALL );
// ProcessInterface
void startJob( QString _jobId, QString _description , int _min , int _max , bool _blocking = false);
void cancelJob(QString _jobId );
void finishJob(QString _jobId );
void setJobState(QString, int);
void setJobName(QString _jobId, QString _name );
void setJobDescription(QString _jobId, QString _text );
//self defined signals
void jobCanceled(QString _jobId);
private slots:
// BaseInterface
void initializePlugin();
......@@ -141,6 +156,9 @@ private slots:
// Tell system that this plugin runs without ui
void noguiSupported( ) {} ;
// ProcessInterface
void canceledJob (QString _job );
public :
/// Default constructor
......@@ -155,12 +173,12 @@ public :
/// Description of the Plugin
QString description() { return (QString(tr("Mesh Decimation ..."))); };
private :
typedef OpenMesh::Decimater::BaseDecimaterT< TriMesh > BaseDecimaterType;
typedef OpenMesh::Decimater::DecimaterT< TriMesh > DecimaterType;
typedef OpenMesh::Decimater::McDecimaterT< TriMesh > McDecimaterType;
typedef OpenMesh::Decimater::MixedDecimaterT< TriMesh > MixedDecimaterType;
private :
typedef DecimateThread::BaseDecimaterType BaseDecimaterType;
typedef DecimateThread::DecimaterType DecimaterType;
typedef DecimateThread::McDecimaterType McDecimaterType;
typedef DecimateThread::MixedDecimaterType MixedDecimaterType;
typedef OpenMesh::Decimater::ModAspectRatioT< TriMesh >::Handle ModAspectRatioH;
typedef OpenMesh::Decimater::ModEdgeLengthT< TriMesh >::Handle ModEdgeLengthH;
......@@ -191,10 +209,13 @@ private :
std::vector< ptr::shared_ptr<DecimaterInit> > decimater_objects_;
QIcon* toolIcon_;
int runningJobs_;
public slots:
/// decimating called from button in toolbox
void slot_decimate();
void slot_decimate_finished(QString _jobId); //postprocess after threads finished
/// init called from button in toolbox
void slot_initialize();
......@@ -245,9 +266,7 @@ public slots:
public slots:
QString version() { return QString("1.0"); };
};
#endif //DECIMATERPLUGIN_HH
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment