- added shared rendering data support for plugins living on a different thread than the main window's one

This commit is contained in:
Guido Ranzuglia granzuglia 2016-06-10 08:54:34 +00:00
parent e9ffd1ee3e
commit 97b6b67e95
6 changed files with 262 additions and 38 deletions

View File

@ -321,7 +321,7 @@ public:
* \sa errorMsg
* \sa initParameterSet
*/
virtual bool applyFilter(QAction * filter, MeshDocument &md, RichParameterSet & par, vcg::CallBackPos *cb) =0;
virtual bool applyFilter(QAction * filter, MeshDocument &md, RichParameterSet & par, vcg::CallBackPos *cb) =0;
/** \brief tests if a filter is applicable to a mesh.
This function is a handy wrapper used by the framework for the \a getPreConditions callback;
@ -381,10 +381,7 @@ public:
int previewOnCreatedAttributes(QAction* act,const MeshModel& mm);
QString generatedScriptCode;
/** If you need to init your QGLContext in order to use GPU redefine this function. */
virtual bool initGLContext() {return true;}
QGLContext* glContext;
MLPluginGLContext* glContext;
protected:
// Each plugins exposes a set of filtering possibilities.
// Each filtering procedure corresponds to a single QAction with a corresponding FilterIDType id.
@ -627,7 +624,7 @@ public:
MeshLabFilterInterface();
virtual ~MeshLabFilterInterface() {}
QGLContext* glContext;
MLPluginGLContext* glContext;
static void initConvertingMap(QMap<QString,MeshModel::MeshElement>& convertingMap);
static void initConvertingCategoryMap(QMap<QString,MeshFilterInterface::FilterClass>& convertingMap);
@ -656,6 +653,8 @@ protected:
// this string is used to pass back to the framework error messages in case of failure of a filter apply.
QString errorMessage;
bool intteruptreq;
signals:
void renderingDataRequested(int);
};
#if (QT_VERSION >= 0x050000)

View File

@ -12,6 +12,13 @@ MLSceneGLSharedDataContext::MLSceneGLSharedDataContext(MeshDocument& md,vcg::QtT
_timer = new QTimer(this);
connect(_timer,SIGNAL(timeout()),this,SLOT(updateGPUMemInfo()));
/*connection intended for the plugins living in another thread*/
connect(this,SIGNAL(initPerMeshViewRequest(int,QGLContext*,const MLRenderingData&)),this,SLOT(initPerMeshViewRequested(int,QGLContext*,const MLRenderingData&)),Qt::BlockingQueuedConnection);
connect(this,SIGNAL(removePerMeshViewRequest(QGLContext*)),this,SLOT(removePerMeshViewRequested(QGLContext*)),Qt::BlockingQueuedConnection);
connect(this,SIGNAL(setPerMeshViewRenderingDataRequest(QGLContext*)),this,SLOT(setPerMeshViewRenderingDataRequested(QGLContext*)),Qt::BlockingQueuedConnection);
/****************************************************************/
_timer->start(1000);
updateGPUMemInfo();
}
@ -42,7 +49,7 @@ void MLSceneGLSharedDataContext::initializeGL()
}
void MLSceneGLSharedDataContext::setRequestedAttributesPerMeshView( int mmid,QGLContext* viewerid,const MLRenderingData& perviewdata )
void MLSceneGLSharedDataContext::setRenderingDataPerMeshView( int mmid,QGLContext* viewerid,const MLRenderingData& perviewdata )
{
MeshModel* mm = _md.getMesh(mmid);
if (mm == NULL)
@ -189,7 +196,7 @@ void MLSceneGLSharedDataContext::setGLOptions( int mmid,QGLContext* viewid,const
man->setGLOptions(viewid,opts);
}
void MLSceneGLSharedDataContext::draw( int mmid,QGLContext* viewid )
void MLSceneGLSharedDataContext::draw( int mmid,QGLContext* viewid ) const
{
PerMeshMultiViewManager* man = meshAttributesMultiViewerManager(mmid);
if (man != NULL)
@ -219,12 +226,26 @@ void MLSceneGLSharedDataContext::addView( QGLContext* viewerid,MLRenderingData&
if (mesh != NULL)
{
MLPoliciesStandAloneFunctions::suggestedDefaultPerViewRenderingData(mesh,dt);
setRequestedAttributesPerMeshView(it.key(),viewerid,dt);
setRenderingDataPerMeshView(it.key(),viewerid,dt);
manageBuffers(it.key());
}
}
}
void MLSceneGLSharedDataContext::addView(QGLContext* viewerid)
{
for(MeshIDManMap::iterator it = _meshboman.begin();it != _meshboman.end();++it)
{
MeshModel* mesh = _md.getMesh(it.key());
if (mesh != NULL)
{
MLRenderingData dt;
setRenderingDataPerMeshView(it.key(),viewerid,dt);
//manageBuffers(it.key());
}
}
}
void MLSceneGLSharedDataContext::deAllocateGPUSharedData()
{
makeCurrent();
@ -347,6 +368,39 @@ void MLSceneGLSharedDataContext::updateRequested( int meshid,vcg::GLMeshAttribut
}
void MLSceneGLSharedDataContext::initPerMeshViewRequested( int meshid,QGLContext* cont,const MLRenderingData& dt)
{
addView(cont);
setRenderingDataPerMeshView(meshid,cont,dt);
manageBuffers(meshid);
}
void MLSceneGLSharedDataContext::setPerMeshViewRenderingDataRequested( int meshid,QGLContext* cont,const MLRenderingData& dt )
{
setRenderingDataPerMeshView(meshid,cont,dt);
manageBuffers(meshid);
}
void MLSceneGLSharedDataContext::removePerMeshViewRequested(QGLContext* cont )
{
removeView(cont);
}
void MLSceneGLSharedDataContext::requestInitPerMeshView( int meshid,QGLContext* cont,const MLRenderingData& dt )
{
emit initPerMeshViewRequest(meshid,cont,dt);
}
void MLSceneGLSharedDataContext::requestRemovePerMeshView(QGLContext* cont )
{
emit removePerMeshViewRequest(cont);
}
void MLSceneGLSharedDataContext::requestSetPerMeshViewRenderingData( int meshid,QGLContext* cont,const MLRenderingData& dt )
{
emit setPerMeshViewRenderingDataRequest(meshid,cont,dt);
}
void MLPoliciesStandAloneFunctions::computeRequestedRenderingDataCompatibleWithMesh( MeshModel* meshmodel,const MLRenderingData& inputdt,MLRenderingData& outputdt)
{
if (meshmodel == NULL)
@ -602,6 +656,22 @@ void MLPoliciesStandAloneFunctions::filterFauxUdpateAccordingToMeshMask( MeshMod
atts[vcg::GLMeshAttributesInfo::ATT_NAMES::ATT_VERTTEXTURE] &= m->hasDataMask(MeshModel::MM_VERTTEXCOORD);
}
vcg::GLMeshAttributesInfo::PRIMITIVE_MODALITY MLPoliciesStandAloneFunctions::bestPrimitiveModalityAccordingToMesh( MeshModel* m )
{
if (m != NULL)
{
if (m->cm.FN() > 0)
return MLRenderingData::PR_SOLID;
else
if ((m->cm.VN() > 0) && (m->cm.EN() > 0))
return MLRenderingData::PR_WIREFRAME_EDGES;
else
if (m->cm.VN() > 0)
return MLRenderingData::PR_POINTS;
}
return MLRenderingData::PR_ARITY;
}
//void MLPoliciesStandAloneFunctions::bestPrimitiveModalityMaskAfterUpdate( MeshModel* meshmodel,int meshmodelmask,const vcg::GLMeshAttributesInfo::PRIMITIVE_MODALITY_MASK& inputpm,vcg::GLMeshAttributesInfo::PRIMITIVE_MODALITY_MASK& outputpm )
//{
// vcg::GLMeshAttributesInfo::PRIMITIVE_MODALITY_MASK tmpmask = 0;
@ -654,3 +724,55 @@ void MLRenderingData::set( const MLPerViewGLOptions& opts )
{
vcg::PerViewData<MLPerViewGLOptions>::set(opts);
}
MLPluginGLContext::MLPluginGLContext(const QGLFormat& frmt,QPaintDevice* dvc,MLSceneGLSharedDataContext& cont )
:QGLContext(frmt,dvc),_shared(cont)
{
}
MLPluginGLContext::~MLPluginGLContext()
{
}
void MLPluginGLContext::drawMeshModel( int meshid) const
{
MLPluginGLContext* id = const_cast<MLPluginGLContext*>(this);
_shared.draw(meshid,id);
}
void MLPluginGLContext::setRenderingData( int meshid,MLRenderingData& dt )
{
/*_shared.setRenderingDataPerMeshView(meshid,this,dt);
_shared.manageBuffers(meshid);*/
}
void MLPluginGLContext::initPerViewRenderingData(int meshid,MLRenderingData& dt)
{
_shared.requestInitPerMeshView(meshid,this,dt);
}
void MLPluginGLContext::removePerViewRenderindData()
{
_shared.requestRemovePerMeshView(this);
}
void MLPluginGLContext::smoothModalitySuggestedRenderingData( MLRenderingData& dt )
{
vcg::GLMeshAttributesInfo::RendAtts att;
att[vcg::GLMeshAttributesInfo::ATT_NAMES::ATT_VERTPOSITION] = true;
att[vcg::GLMeshAttributesInfo::ATT_NAMES::ATT_VERTNORMAL] = true;
dt.set(vcg::GLMeshAttributesInfo::PRIMITIVE_MODALITY::PR_SOLID,att);
}
void MLPluginGLContext::pointModalitySuggestedRenderingData( MLRenderingData& dt )
{
vcg::GLMeshAttributesInfo::RendAtts att;
att[vcg::GLMeshAttributesInfo::ATT_NAMES::ATT_VERTPOSITION] = true;
att[vcg::GLMeshAttributesInfo::ATT_NAMES::ATT_VERTNORMAL] = true;
dt.set(vcg::GLMeshAttributesInfo::PRIMITIVE_MODALITY::PR_POINTS,att);
}

View File

@ -142,6 +142,10 @@ public:
bool set(vcg::GLMeshAttributesInfo::PRIMITIVE_MODALITY pm,vcg::GLMeshAttributesInfo::ATT_NAMES att,bool onoff);
bool set(vcg::GLMeshAttributesInfo::PRIMITIVE_MODALITY pm,bool onoff);
void set(const MLPerViewGLOptions& opts);
typedef vcg::GLMeshAttributesInfo::RendAtts RendAtts;
typedef vcg::GLMeshAttributesInfo::ATT_NAMES ATT_NAMES;
typedef vcg::GLMeshAttributesInfo::PRIMITIVE_MODALITY PRIMITIVE_MODALITY;
};
/*{
vcg::GLMeshAttributesInfo::PRIMITIVE_MODALITY_MASK _mask;
@ -188,6 +192,8 @@ struct MLPoliciesStandAloneFunctions
static bool isPrimitiveModalityWorthToBeActivated(vcg::GLMeshAttributesInfo::PRIMITIVE_MODALITY pm,bool wasvisualized,bool wasmeanigful,bool ismeaningful);
static MLRenderingData::PRIMITIVE_MODALITY bestPrimitiveModalityAccordingToMesh(MeshModel* m);
static void filterFauxUdpateAccordingToMeshMask(MeshModel* m,vcg::GLMeshAttributesInfo::RendAtts& atts);
};
@ -219,7 +225,7 @@ public:
void initializeGL();
void deAllocateGPUSharedData();
void draw(int mmid,QGLContext* viewid);
void draw(int mmid,QGLContext* viewid) const;
void setSceneTransformationMatrix(const Matrix44m& m);
void setMeshTransformationMatrix(int mmid,const Matrix44m& m);
@ -235,16 +241,30 @@ public:
void getLog(int mmid,vcg::GLMeshAttributesInfo::DebugInfo& debug);
bool isBORenderingAvailable(int mmid);
/*functions intended for the plugins living in another thread*/
void requestInitPerMeshView(int meshid,QGLContext* cont,const MLRenderingData& dt);
void requestRemovePerMeshView(QGLContext* cont);
void requestSetPerMeshViewRenderingData(int meshid,QGLContext* cont,const MLRenderingData& dt);
/***************************************/
public slots:
void meshDeallocated(int mmid);
void setRequestedAttributesPerMeshView(int mmid,QGLContext* viewerid,const MLRenderingData& perviewdata);
void setRenderingDataPerMeshView(int mmid,QGLContext* viewerid,const MLRenderingData& perviewdata);
void setGLOptions(int mmid,QGLContext* viewid,const MLPerViewGLOptions& opts);
void addView(QGLContext* viewerid);
void addView(QGLContext* viewerid,MLRenderingData& dt);
void removeView(QGLContext* viewerid);
void meshAttributesUpdated(int mmid,bool conntectivitychanged,const vcg::GLMeshAttributesInfo::RendAtts& dt);
void updateGPUMemInfo();
void updateRequested(int meshid,vcg::GLMeshAttributesInfo::ATT_NAMES name);
/*slots intended for the plugins living in another thread*/
void initPerMeshViewRequested(int meshid,QGLContext* cont,const MLRenderingData& dt);
void removePerMeshViewRequested(QGLContext* cont);
void setPerMeshViewRenderingDataRequested(int meshid,QGLContext* cont,const MLRenderingData& dt);
/***************************************/
private:
typedef vcg::QtThreadSafeGLMeshAttributesMultiViewerBOManager<CMeshO,QGLContext*,MLPerViewGLOptions> PerMeshMultiViewManager;
PerMeshMultiViewManager* meshAttributesMultiViewerManager(int mmid ) const;
@ -258,8 +278,30 @@ private:
QTimer* _timer;
signals:
void currentAllocatedGPUMem(int all,int current);
/*signals intended for the plugins living in another thread*/
void initPerMeshViewRequest(int,QGLContext*,const MLRenderingData&);
void removePerMeshViewRequest(QGLContext*);
void setPerMeshViewRenderingDataRequest(int meshid,QGLContext* cont,const MLRenderingData& dt);
/***************************************/
};
class MLPluginGLContext : public QGLContext
{
public:
MLPluginGLContext(const QGLFormat& frmt,QPaintDevice* dvc,MLSceneGLSharedDataContext& shared);
~MLPluginGLContext();
void initPerViewRenderingData(int meshid,MLRenderingData& dt);
void removePerViewRenderindData();
void setRenderingData(int meshid,MLRenderingData& dt);
void drawMeshModel( int meshid) const;
static void smoothModalitySuggestedRenderingData(MLRenderingData& dt);
static void pointModalitySuggestedRenderingData(MLRenderingData& dt);
private:
MLSceneGLSharedDataContext& _shared;
};
#endif

View File

@ -11,7 +11,8 @@ FilterThread* FilterThread::_cur = NULL;
FilterThread::FilterThread(const QString& fname,const QMap<QString,QString>& parexpval,PluginManager& pm, MeshDocument& md,MainWindow* mw)
:QThread(),_fname(fname),_parexpval(parexpval),_pm(pm),_md(md),_glwid(NULL),_mw(mw)
{
_glwid = new QGLWidget();
if ((_mw != NULL) && (_mw->currentViewContainer() != NULL))
_glwid = new QGLWidget(NULL,_mw->currentViewContainer()->sharedDataContext());
}
bool FilterThread::localCallBack(const int pos, const char * str)
@ -24,6 +25,7 @@ bool FilterThread::localCallBack(const int pos, const char * str)
return true;
}
void FilterThread::run()
{
try
@ -43,16 +45,48 @@ void FilterThread::run()
throw MLException("Filter " + _fname + " has not been found.\n");
if (it->filterInterface != NULL)
{
MLSceneGLSharedDataContext* cont = NULL;
if ((_mw != NULL) && (_mw->currentViewContainer() != NULL))
{
cont = _mw->currentViewContainer()->sharedDataContext();
it->filterInterface->glContext = new MLPluginGLContext(QGLFormat::defaultFormat(),_glwid->context()->device(),(*cont));
it->filterInterface->glContext->create(_glwid->context());
MLRenderingData dt;
MLRenderingData::RendAtts atts;
atts[MLRenderingData::ATT_NAMES::ATT_VERTPOSITION] = true;
atts[MLRenderingData::ATT_NAMES::ATT_VERTNORMAL] = true;
it->filterInterface->glContext = new QGLContext(QGLFormat::defaultFormat(),_glwid->context()->device());
it->filterInterface->glContext->create(_glwid->context());
if (it->xmlInfo->filterAttribute(_fname,MLXMLElNames::filterArity) == MLXMLElNames::singleMeshArity)
{
MLRenderingData::PRIMITIVE_MODALITY pm = MLPoliciesStandAloneFunctions::bestPrimitiveModalityAccordingToMesh(_md.mm());
if ((pm != MLRenderingData::PR_ARITY) && (_md.mm() != NULL))
{
dt.set(pm,atts);
it->filterInterface->glContext->initPerViewRenderingData(_md.mm()->id(),dt);
}
}
else
{
for(int ii = 0;ii < _md.meshList.size();++ii)
{
MeshModel* mm = _md.meshList[ii];
MLRenderingData::PRIMITIVE_MODALITY pm = MLPoliciesStandAloneFunctions::bestPrimitiveModalityAccordingToMesh(mm);
if ((pm != MLRenderingData::PR_ARITY) && (mm != NULL))
{
dt.set(pm,atts);
it->filterInterface->glContext->initPerViewRenderingData(mm->id(),dt);
}
}
}
}
for (QMap<QString,QString>::const_iterator itp = _parexpval.constBegin();itp != _parexpval.constEnd();++itp)
env.insertExpressionBinding(itp.key(),itp.value());
EnvWrap envwrap(env);
_cur = this;
_success = it->filterInterface->applyFilter(_fname, _md, envwrap, &localCallBack);
_cur = NULL;
it->filterInterface->glContext->removePerViewRenderindData();
delete it->filterInterface->glContext;
}
else
@ -66,5 +100,5 @@ void FilterThread::run()
FilterThread::~FilterThread()
{
delete _glwid;
delete _glwid;
}

View File

@ -831,9 +831,18 @@ void MainWindow::runFilterScript()
}
}
//iFilter->applyFilter( action, *(meshDoc()->mm()), (*ii).second, QCallBack );
QGLWidget wid;
iFilter->glContext = new QGLContext(QGLFormat::defaultFormat(),wid.context()->device());
bool created = iFilter->glContext->create(wid.context());
bool created = false;
MLSceneGLSharedDataContext* shar = NULL;
if (currentViewContainer() != NULL)
{
shar = currentViewContainer()->sharedDataContext();
//GLA() is only the parent
QGLWidget* filterWidget = new QGLWidget(GLA(),shar);
QGLFormat defForm = QGLFormat::defaultFormat();
iFilter->glContext = new MLPluginGLContext(defForm,filterWidget->context()->device(),*shar);
created = iFilter->glContext->create(filterWidget->context());
}
if ((!created) || (!iFilter->glContext->isValid()))
throw MLException("A valid GLContext is required by the filter to work.\n");
meshDoc()->setBusy(true);
@ -883,9 +892,17 @@ void MainWindow::runFilterScript()
}
}
disconnect(meshDoc(),SIGNAL(documentUpdated()),GLA(),SLOT(completeUpdateRequested()));
QGLWidget wid;
cppfilt->glContext = new QGLContext(QGLFormat::defaultFormat(),wid.context()->device());
bool created = cppfilt->glContext->create(wid.context());
MLSceneGLSharedDataContext* shar = NULL;
bool created = false;
if (currentViewContainer() != NULL)
{
shar = currentViewContainer()->sharedDataContext();
//GLA() is only the parent
QGLWidget* filterWidget = new QGLWidget(GLA(),shar);
QGLFormat defForm = QGLFormat::defaultFormat();
cppfilt->glContext = new MLPluginGLContext(defForm,filterWidget->context()->device(),*shar);
created = cppfilt->glContext->create(filterWidget->context());
}
if ((!created) || (!cppfilt->glContext->isValid()))
throw MLException("A valid GLContext is required by the filter to work.\n");
@ -1203,7 +1220,7 @@ void MainWindow::updateSharedContextDataAfterFilterExecution(int postcondmask,in
curr.set(pm,rd);
MLPoliciesStandAloneFunctions::setPerViewGLOptionsPriorities(mm,curr);
}
shared->setRequestedAttributesPerMeshView(mm->id(),GLA()->context(),curr);
shared->setRenderingDataPerMeshView(mm->id(),GLA()->context(),curr);
currentmeshnewlycreated = false;
}
else
@ -1215,12 +1232,12 @@ void MainWindow::updateSharedContextDataAfterFilterExecution(int postcondmask,in
foreach(GLArea* gla,mvc->viewerList)
{
if (gla != NULL)
shared->setRequestedAttributesPerMeshView(mm->id(),gla->context(),dttoberendered);
shared->setRenderingDataPerMeshView(mm->id(),gla->context(),dttoberendered);
}
}
shared->manageBuffers(mm->id());
updateLayerDialog();
addRenderingSystemLogInfo(mm->id());
//addRenderingSystemLogInfo(mm->id());
}
}
}
@ -1271,11 +1288,16 @@ void MainWindow::executeFilter(QAction *action, RichParameterSet &params, bool i
RichParameterSet MergedEnvironment(params);
MergedEnvironment.join(currentGlobalParams);
//GLA() is only the parent
QGLWidget* filterWidget = new QGLWidget(GLA());
QGLFormat defForm = QGLFormat::defaultFormat();
iFilter->glContext = new QGLContext(defForm,filterWidget->context()->device());
iFilter->glContext->create(filterWidget->context());
MLSceneGLSharedDataContext* shar = NULL;
if (currentViewContainer() != NULL)
{
shar = currentViewContainer()->sharedDataContext();
//GLA() is only the parent
QGLWidget* filterWidget = new QGLWidget(GLA(),shar);
QGLFormat defForm = QGLFormat::defaultFormat();
iFilter->glContext = new MLPluginGLContext(defForm,filterWidget->context()->device(),*shar);
iFilter->glContext->create(filterWidget->context());
}
bool newmeshcreated = false;
try
{
@ -1568,7 +1590,13 @@ void MainWindow::executeFilter(MeshLabXMLFilterContainer* mfc,const QMap<QString
connect(ft,SIGNAL(finished()),this,SLOT(postFilterExecution()));
connect(ft,SIGNAL(threadCB(const int, const QString&)),this,SLOT(updateProgressBar(const int,const QString&)));
connect(xmldialog,SIGNAL(filterInterrupt(const bool)),PM.stringXMLFilterMap[fname].filterInterface,SLOT(setInterrupt(const bool)));
/*if ((_mw != NULL) && (_mw->currentViewContainer() != NULL))
{
QGLWidget* tmpglwid = new QGLWidget(NULL,currentViewContainer()->sharedDataContext());
filtercpp->glContext = new MLPluginGLContext(QGLFormat::defaultFormat(),tmpglwid->context()->device(),(*currentViewContainer()->sharedDataContext()));
bool res = it->filterInterface->glContext->create(tmpglwid->context());
}*/
ft->start();
}
else
@ -1595,8 +1623,6 @@ void MainWindow::postFilterExecution()
{
emit filterExecuted();
//meshDoc()->renderState().clearState();
qApp->restoreOverrideCursor();
qb->reset();
//foreach(QAction* act,filterMenu->actions())
@ -2429,7 +2455,7 @@ bool MainWindow::loadMesh(const QString& fileName, MeshIOInterface *pCurrentIOPl
{
GLArea* ar = mv->getViewer(glarid);
if (ar != NULL)
shared->setRequestedAttributesPerMeshView(mm->id(),ar->context(),defdt);
shared->setRenderingDataPerMeshView(mm->id(),ar->context(),defdt);
}
shared->manageBuffers(mm->id());
updateLayerDialog();
@ -3151,7 +3177,7 @@ void MainWindow::meshAdded(int mid)
{
GLArea* ar = mvc->getViewer(glarid);
if (ar != NULL)
shared->setRequestedAttributesPerMeshView(mid,ar->context(),defdt);
shared->setRenderingDataPerMeshView(mid,ar->context(),defdt);
}
shared->manageBuffers(mid);
}
@ -3192,9 +3218,9 @@ void MainWindow::setRenderingData(int mid,const MLRenderingData& dt)
MLSceneGLSharedDataContext* share = cont->sharedDataContext();
if ((share != NULL) && (GLA() != NULL))
{
share->setRequestedAttributesPerMeshView(mid,GLA()->context(),dt);
share->setRenderingDataPerMeshView(mid,GLA()->context(),dt);
share->manageBuffers(mid);
addRenderingSystemLogInfo(mid);
//addRenderingSystemLogInfo(mid);
}
}
}

View File

@ -18,6 +18,7 @@ SUBDIRS = common \
meshlabplugins/edit_quality \
meshlabplugins/filter_meshing \
meshlabplugins/filter_voronoi \
meshlabplugins/filter_mutualinfoxml \
# meshlabplugins/filter_colorize\
# meshlabplugins/filter_meshing \
# meshlabplugins/filter_sampling \