added new mechanism to interactive render the filter when it's running.

This commit is contained in:
Guido Ranzuglia granzuglia 2012-03-16 08:36:57 +00:00
parent 0de224dbe7
commit 9e6dd26cd5
6 changed files with 139 additions and 17 deletions

View File

@ -0,0 +1,28 @@
#include "mainwindow.h"
#include <exception>
#include "../common/scriptinterface.h"
#include "../common/meshlabdocumentxml.h"
#include "../common/meshlabdocumentbundler.h"
#include "filterthread.h"
FilterThread::FilterThread(QString fname,MeshLabXMLFilterContainer *mfc, MeshDocument& md,EnvWrap& env, QObject *parent)
:QThread(parent), _fname(fname), _mfc(mfc),_md(md),_env(env)
{
}
FilterThread *cur=0;
bool FilterThread::QCallBackLocal(const int pos, const char * str)
{
/*emit cur->ThreadCB(pos,QString(str));*/
return true;
}
void FilterThread::run()
{
/*assert(cur==0);
cur=this;*/
_ret = _mfc->filterInterface->applyFilter(_fname, _md, _env, QCallBackLocal);
/*cur=0;*/
}

View File

@ -0,0 +1,33 @@
#ifndef FILTERTHREAD_H
#define FILTERTHREAD_H
#include <QThread>
#include "mainwindow.h"
class FilterThread : public QThread
{
Q_OBJECT
public:
explicit FilterThread(QString fname,MeshLabXMLFilterContainer *mfc, MeshDocument& md,EnvWrap& env, QObject *parent = 0);
MeshLabXMLFilterContainer *_mfc;
QString _fname;
MeshDocument& _md;
//vcg::CallBackPos *_qc;
EnvWrap & _env;
bool _ret;
static bool QCallBackLocal(const int pos, const char * str);
protected:
void run();
signals:
void ThreadCB(const int pos, QString str);
public slots:
};
#endif // FILTERTHREAD_H

View File

@ -87,6 +87,7 @@ private slots:
void endEdit();
void updateDocumentScriptBindings();
void loadAndInsertXMLPlugin(const QString& xmlpath,const QString& scriptname);
void postFilterExecution(/*MeshLabXMLFilterContainer* mfc*/);
//void evaluateExpression(const Expression& exp,Value** res);
public:

View File

@ -38,6 +38,7 @@
#include "alnParser.h"
#include <exception>
#include "xmlgeneratorgui.h"
#include "filterthread.h"
#include "../common/scriptinterface.h"
@ -1030,10 +1031,46 @@ void MainWindow::executeFilter(QAction *action, RichParameterSet &params, bool i
void MainWindow::executeFilter(MeshLabXMLFilterContainer* mfc, EnvWrap& env, bool /*isPreview*/)
{
if (mfc == NULL)
return;
MeshLabFilterInterface *iFilter = mfc->filterInterface;
bool jscode = (mfc->xmlInfo->filterScriptCode(mfc->act->text()) != "");
bool filtercpp = (iFilter != NULL) && (!jscode);
QString fname = mfc->act->text();
QString ar = mfc->xmlInfo->filterAttribute(fname,MLXMLElNames::filterArity);
MeshDocument* mmmmd = meshDoc();
if (ar == MLXMLElNames::singleMeshArity)
meshDoc()->renderState().addMesh(meshDoc()->mm()->id(),meshDoc()->mm()->cm);
if (ar == MLXMLElNames::fixedArity)
{
//I have to check which are the meshes requested as parameters by the filter. It's disgusting but there is not other way.
MLXMLPluginInfo::XMLMapList params = mfc->xmlInfo->filterParameters(fname);
for(int ii = 0;ii < params.size();++ii)
{
if (params[ii][MLXMLElNames::paramType] == MLXMLElNames::meshType)
{
try
{
MeshModel* tmp = env.evalMesh(params[ii][MLXMLElNames::paramName]);
if (tmp != NULL)
meshDoc()->renderState().addMesh(tmp->id(),tmp->cm);
}
catch (ExpressionHasNotThisTypeException& e)
{
QString st = "parameter " + params[ii][MLXMLElNames::paramName] + "declared of type mesh contains a not mesh value.\n";
meshDoc()->Log.Logf(GLLogStream::FILTER,qPrintable(st));
}
}
}
}
//In this case I can only copy all the meshes in the document!
if (ar == MLXMLElNames::variableArity)
{
for(int ii = 0;meshDoc()->meshList.size();++ii)
meshDoc()->renderState().addMesh(meshDoc()->meshList[ii]->id(),meshDoc()->meshList[ii]->cm);
}
qb->show();
if (filtercpp)
iFilter->setLog(&meshDoc()->Log);
@ -1064,7 +1101,7 @@ void MainWindow::executeFilter(MeshLabXMLFilterContainer* mfc, EnvWrap& env, boo
bool ret = true;
qApp->setOverrideCursor(QCursor(Qt::WaitCursor));
QTime tt; tt.start();
meshDoc()->setBusy(true);
//meshDoc()->setBusy(true);
//RichParameterSet MergedEnvironment(params);
//MergedEnvironment.join(currentGlobalParams);
@ -1079,12 +1116,12 @@ void MainWindow::executeFilter(MeshLabXMLFilterContainer* mfc, EnvWrap& env, boo
try
{
bool isinter = (mfc->xmlInfo->filterAttribute(fname,MLXMLElNames::filterIsInterruptible) == "true");
if (isinter)
/*if (isinter)
{
showInterruptButton(true);
if (filtercpp)
connect(iFilter,SIGNAL(filterUpdateRequest(const bool&,bool*)),this,SLOT(filterUpdateRequest(const bool&,bool*)),Qt::DirectConnection);
}
}*/
MLXMLPluginInfo::XMLMapList ml = mfc->xmlInfo->filterParametersExtendedInfo(fname);
QString funcall = "Plugins." + mfc->xmlInfo->pluginAttribute(MLXMLElNames::pluginScriptName) + "." + mfc->xmlInfo->filterAttribute(fname,MLXMLElNames::filterScriptFunctName) + "(";
if (mfc->xmlInfo->filterAttribute(fname,MLXMLElNames::filterArity) == MLXMLElNames::singleMeshArity && !jscode)
@ -1103,7 +1140,13 @@ void MainWindow::executeFilter(MeshLabXMLFilterContainer* mfc, EnvWrap& env, boo
if (meshDoc() != NULL)
meshDoc()->xmlhistory << funcall;
if (filtercpp)
ret = iFilter->applyFilter(fname, *(meshDoc()), env, QCallBack);
{
//I'm using PM.stringXMLFilterMap[fname] instead of mfc passed like parameter because i'm sure that the first one is still alive after the function will exit.
FilterThread* ft = new FilterThread(fname,&PM.stringXMLFilterMap[fname],*(meshDoc()),env,this);
connect(ft,SIGNAL(finished()),this,SLOT(postFilterExecution()));
ft->start();
//ret = iFilter->applyFilter(fname, *(meshDoc()), env, QCallBack);
}
else
{
QTime t;
@ -1114,32 +1157,46 @@ void MainWindow::executeFilter(MeshLabXMLFilterContainer* mfc, EnvWrap& env, boo
scriptCodeExecuted(result,t.elapsed(),"");
}
if (isinter)
/*if (isinter)
{
showInterruptButton(false);
if (filtercpp)
disconnect(iFilter,SIGNAL(filterUpdateRequest(const bool&,bool*)),this,SLOT(filterUpdateRequest(const bool&,bool*)));
}
}*/
}
catch(MeshLabException& e)
{
meshDoc()->Log.Logf(GLLogStream::SYSTEM,e.what());
ret = false;
}
meshDoc()->setBusy(false);
}
void MainWindow::postFilterExecution()
{
//meshDoc()->renderState().clearState();
FilterThread* obj = qobject_cast<FilterThread*>(QObject::sender());
if (obj == NULL)
return;
MeshLabXMLFilterContainer* mfc = obj->_mfc;
if (mfc == NULL)
return;
QString fname = mfc->act->text();
//meshDoc()->setBusy(false);
qApp->restoreOverrideCursor();
//// (5) Apply post filter actions (e.g. recompute non updated stuff if needed)
if(ret)
if(obj->_ret)
{
meshDoc()->Log.Logf(GLLogStream::SYSTEM,"Applied filter %s in %i msec",qPrintable(fname),tt.elapsed());
//meshDoc()->Log.Logf(GLLogStream::SYSTEM,"Applied filter %s in %i msec",qPrintable(fname),tt.elapsed());
MainWindow::globalStatusBar()->showMessage("Filter successfully completed...",2000);
if(GLA())
{
GLA()->setWindowModified(true);
GLA()->setLastAppliedFilter(mfc->act);
GLA()->setWindowModified(true);
}
lastFilterAct->setText(QString("Apply filter ") + fname);
lastFilterAct->setEnabled(true);
@ -1185,6 +1242,7 @@ void MainWindow::executeFilter(MeshLabXMLFilterContainer* mfc, EnvWrap& env, boo
if(mvc)
mvc->updateAllViewer();
delete obj;
}
void MainWindow::filterUpdateRequest(const bool& redraw,bool* interrupted)
@ -2241,3 +2299,4 @@ void MainWindow::sendHistory()
{
plugingui->getHistory(meshDoc()->xmlhistory);
}

View File

@ -26,7 +26,8 @@ HEADERS = ../common/interfaces.h \
xmlgeneratorgui.h \
$$VCGDIR/wrap/gui/trackball.h \
$$VCGDIR/wrap/gui/trackmode.h \
$$VCGDIR/wrap/gl/trimesh.h
$$VCGDIR/wrap/gl/trimesh.h \
filterthread.h
SOURCES = main.cpp \
mainwindow_Init.cpp \
mainwindow_RunTime.cpp \
@ -45,7 +46,8 @@ SOURCES = main.cpp \
xmlgeneratorgui.cpp \
$$VCGDIR/wrap/gui/trackball.cpp \
$$VCGDIR/wrap/gui/trackmode.cpp \
glarea_setting.cpp
glarea_setting.cpp \
filterthread.cpp
FORMS = ui/layerDialog.ui \
ui/filterScriptDialog.ui \

View File

@ -160,14 +160,13 @@ bool MeshLabXMLStdDialog::showAutoDialog(MeshLabXMLFilterContainer& mfc,PluginMa
void MeshLabXMLStdDialog::applyClick()
{
env.pushContext();
//env.pushContext();
assert(curParMap.size() == stdParFrame->xmlfieldwidgets.size());
for(int ii = 0;ii < curParMap.size();++ii)
{
XMLMeshLabWidget* wid = stdParFrame->xmlfieldwidgets[ii];
QString exp = wid->getWidgetExpression();
env.insertExpressionBinding(curParMap[ii][MLXMLElNames::paramName],exp);
//delete exp;
}
////int mask = 0;//curParSet.getDynamicFloatMask();
if(curmask)
@ -182,10 +181,10 @@ void MeshLabXMLStdDialog::applyClick()
//else
//{
QString nm = curmfc->act->text();
EnvWrap wrap(env);
curmwi->executeFilter(curmfc,wrap,false);
EnvWrap* wrap = new EnvWrap(env);
curmwi->executeFilter(curmfc,*wrap,false);
/*}*/
env.popContext();
//env.popContext();
if(curmask)
meshState.create(curmask, curModel);