- added code for update mesh rendering data after filter execution

- bug "don't update" still present
This commit is contained in:
Guido Ranzuglia granzuglia 2015-10-09 03:08:04 +00:00
parent d561185388
commit 9f9ee6f312
6 changed files with 165 additions and 53 deletions

View File

@ -29,11 +29,11 @@ bool MLThreadSafeGLMeshAttributesFeeder::renderedWithBO() const
return GLMeshAttributesFeeder<CMeshO>::isPossibleToUseBORendering();
}
void MLThreadSafeGLMeshAttributesFeeder::meshAttributesUpdated( int mask )
{
QWriteLocker locker(&_lock);
GLMeshAttributesFeeder<CMeshO>::meshAttributesUpdated(mask);
}
//void MLThreadSafeGLMeshAttributesFeeder::meshAttributesUpdated( int mask )
//{
// QWriteLocker locker(&_lock);
// GLMeshAttributesFeeder<CMeshO>::meshAttributesUpdated(mask);
//}
vcg::GLFeederInfo::ReqAtts MLThreadSafeGLMeshAttributesFeeder::setupRequestedAttributes(const vcg::GLFeederInfo::ReqAtts& rq,bool& allocated )
{
@ -180,12 +180,24 @@ void MLThreadSafeGLMeshAttributesFeeder::deAllocateBO()
GLMeshAttributesFeeder<CMeshO>::buffersDeAllocationRequested();
}
void MLThreadSafeGLMeshAttributesFeeder::deAllocateBO(const vcg::GLFeederInfo::ReqAtts& req)
{
QWriteLocker locker(&_lock);
GLMeshAttributesFeeder<CMeshO>::buffersDeAllocationRequested(req);
}
void MLThreadSafeGLMeshAttributesFeeder::deAllocateTextures()
{
QWriteLocker locker(&_lock);
_textids.clear();
}
void MLThreadSafeGLMeshAttributesFeeder::invalidateRequestedAttributes( vcg::GLFeederInfo::ReqAtts& rq )
{
QWriteLocker locker(&_lock);
GLMeshAttributesFeeder<CMeshO>::invalidateRequestedAttributes(rq);
}
MLThreadSafeGLMeshAttributesFeeder::MLThreadSafeTextureNamesContainer::MLThreadSafeTextureNamesContainer()
:_tmid(),_lock(QReadWriteLock::Recursive)
{
@ -598,6 +610,32 @@ vcg::GLFeederInfo::PRIMITIVE_MODALITY MLSceneRenderModeAdapter::renderModeToPrim
return vcg::GLFeederInfo::PR_NONE;
}
vcg::GLFeederInfo::ReqAtts MLSceneRenderModeAdapter::convertUpdateMaskToMinimalReqAtts( int updatemask,const MeshModel& m,const RenderMode& rm )
{
vcg::GLFeederInfo::ReqAtts res;
if (updatemask & MeshModel::MM_NONE)
return res;
MLSceneRenderModeAdapter::renderModeToReqAtts(rm,res);
if ((updatemask & MeshModel::MM_UNKNOWN) || (updatemask & MeshModel::MM_ALL) || (updatemask & MeshModel::MM_VERTNUMBER) || (updatemask & MeshModel::MM_FACENUMBER) || (updatemask & MeshModel::MM_VERTFACETOPO) || (updatemask & MeshModel::MM_FACEFACETOPO))
{
vcg::GLFeederInfo::ReqAtts::computeARequestedAttributesSetCompatibleWithMesh(res,m.cm);
return res;
}
res[vcg::GLFeederInfo::ATT_VERTPOSITION] = (updatemask & MeshModel::MM_VERTCOORD);
res[vcg::GLFeederInfo::ATT_VERTNORMAL] = (updatemask & MeshModel::MM_VERTNORMAL);
res[vcg::GLFeederInfo::ATT_FACENORMAL] = (updatemask & MeshModel::MM_FACENORMAL);
res[vcg::GLFeederInfo::ATT_VERTCOLOR] = (updatemask & MeshModel::MM_VERTCOLOR);
res[vcg::GLFeederInfo::ATT_FACECOLOR] = (updatemask & MeshModel::MM_FACECOLOR);
res[vcg::GLFeederInfo::ATT_MESHCOLOR] = (updatemask & MeshModel::MM_COLOR);
res[vcg::GLFeederInfo::ATT_VERTTEXTURE] = (updatemask & MeshModel::MM_VERTTEXCOORD);
res[vcg::GLFeederInfo::ATT_WEDGETEXTURE] = (updatemask & MeshModel::MM_WEDGTEXCOORD);
vcg::GLFeederInfo::ReqAtts::computeARequestedAttributesSetCompatibleWithMesh(res,m.cm);
return res;
}
//bool MLSceneRenderModeAdapter::setupRequestedAttributesAccordingToRenderMode( unsigned int meshid,GLArea& area )
//{
// bool res = false;

View File

@ -64,14 +64,20 @@ public:
GLuint bufferObjectHandle() const;
void meshAttributesUpdated(int mask);
//void meshAttributesUpdated(int mask);
vcg::GLFeederInfo::ReqAtts setupRequestedAttributes(const vcg::GLFeederInfo::ReqAtts& rq,bool& allocated);
vcg::GLFeederInfo::ReqAtts removeRequestedAttributes(const vcg::GLFeederInfo::ReqAtts& rq);
void invalidateRequestedAttributes(vcg::GLFeederInfo::ReqAtts& rq);
//Deallocate all the BO
void deAllocateBO();
//Deallocate just the BO requested by the req parameter
void deAllocateBO(const vcg::GLFeederInfo::ReqAtts& req);
void deAllocateTextures();
void drawWire(vcg::GLFeederInfo::ReqAtts& rq);
@ -84,6 +90,8 @@ public:
void drawBBox(vcg::GLFeederInfo::ReqAtts& rq);
inline CMeshO& mesh() {return _mesh;}
inline MLThreadSafeTextureNamesContainer& textureIDContainer() {return _textids;}
@ -145,6 +153,7 @@ struct MLSceneRenderModeAdapter
static void renderModeToReqAtts(const RenderMode& rm,vcg::GLFeederInfo::ReqAtts& rq);
/*static bool setupRequestedAttributesAccordingToRenderMode(unsigned int meshid,GLArea& area);*/
static void renderMesh(QGLContext& area,MLThreadSafeGLMeshAttributesFeeder& feed,const RenderMode& rm,int pointsz,bool pointsmooth,bool pointatt);
static vcg::GLFeederInfo::ReqAtts convertUpdateMaskToMinimalReqAtts(int updatemask,const MeshModel& m,const RenderMode& rm);
private:
static vcg::GLFeederInfo::PRIMITIVE_MODALITY renderModeToPrimitiveModality(const RenderMode& rm);
static void renderModeColorToReqAtts(const RenderMode& rm,vcg::GLFeederInfo::ReqAtts& rq);

View File

@ -10,7 +10,7 @@ GLEWDIR = ../external/glew-1.7.0
CONFIG += c++11
QMAKE_CXXFLAGS += -Wno-inconsistent-missing-override
macx:QMAKE_CXXFLAGS += -Wno-inconsistent-missing-override
MACLIBDIR = ../../external/lib/macx64

View File

@ -257,7 +257,9 @@ private:
void initDocumentMeshRenderState(MeshLabXMLFilterContainer* mfc);
void initDocumentRasterRenderState(MeshLabXMLFilterContainer* mfc);
void deallocateReqAttsConsideringAllOtherGLArea(GLArea* ar,const int meshid,const RenderMode& currentrendmode,const RenderMode& newrendermode);
void updatePerMeshRenderingDataAccordingToUpdateMaskConsideringAllGLArea(int meshid,int updatemask);
void deallocateNotMoreNecessaryPerMeshAndPerGLAreaRenderingDataConsideringAllOtherGLArea(const int meshid,GLArea* gla,const RenderMode& currentrendmode,const RenderMode& newrendermode);
QNetworkAccessManager *httpReq;
QBuffer myLocalBuf;
@ -521,8 +523,17 @@ private:
QAction *onscreenHelpAct;
QAction *checkUpdatesAct;
////////////////////////////////////////////////////
struct MeshModelTmpData
{
int _mask;
size_t _nvert;
size_t _nface;
QSet<int> existingmeshesbeforefilterexecution;
MeshModelTmpData(int mask,size_t nvert,size_t nface)
:_mask(mask),_nvert(nvert),_nface(nface)
{}
};
QMap<int,MeshModelTmpData> existingmeshesbeforefilterexecution;
static QString getDecoratedFileName(const QString& name);
void updateRenderToolBar( RenderModeAction* act );

View File

@ -51,7 +51,7 @@
QProgressBar *MainWindow::qb;
MainWindow::MainWindow()
:mwsettings(),xmlfiltertimer(),wama(),gpumeminfo(NULL)
:mwsettings(),xmlfiltertimer(),wama(),gpumeminfo(NULL),existingmeshesbeforefilterexecution()
{
//xmlfiltertimer will be called repeatedly, so like Qt documentation suggests, the first time start function should be called.
//Subsequently restart function will be invoked.

View File

@ -1199,9 +1199,9 @@ void MainWindow::executeFilter(QAction *action, RichParameterSet &params, bool i
iFilter->glContext->create(filterWidget->context());
try
{
QSet<int> existingmeshesbeforefilterexecutionlocal;
existingmeshesbeforefilterexecution.clear();
for(MeshModel* mm = meshDoc()->nextMesh();mm != NULL;mm=meshDoc()->nextMesh(mm))
existingmeshesbeforefilterexecutionlocal.insert(mm->id());
existingmeshesbeforefilterexecution.insert(mm->id(),MeshModelTmpData(mm->dataMask(),(size_t) mm->cm.VN(),(size_t) mm->cm.FN()));
ret=iFilter->applyFilter(action, *(meshDoc()), MergedEnvironment, QCallBack);
meshDoc()->setBusy(false);
@ -1265,7 +1265,7 @@ void MainWindow::executeFilter(QAction *action, RichParameterSet &params, bool i
}
int fclasses = iFilter->getClass(action);
MLSceneGLSharedDataContext* sharedcont = GLA()->getSceneGLSharedContext();
for(MeshModel* mm = meshDoc()->nextMesh();mm != NULL;mm = meshDoc()->nextMesh(mm))
{
int postCondMask = iFilter->postCondition(action);
@ -1283,16 +1283,23 @@ void MainWindow::executeFilter(QAction *action, RichParameterSet &params, bool i
if ((mm->hasDataMask(MeshModel::MM_VERTQUALITY)) && (fclasses & MeshFilterInterface::Quality ))
postCondMask = postCondMask | MeshModel::MM_VERTQUALITY;
RenderMode rm = GLA()->rendermodemap[mm->id()];
vcg::GLW::NormalMode nmmode = vcg::GlTrimesh<CMeshO>::convertDrawModeToNormalMode(rm.drawMode);
QMap<int,MeshModelTmpData>::Iterator existit = existingmeshesbeforefilterexecution.find(mm->id());
if (existit != existingmeshesbeforefilterexecution.end())
{
RenderMode rm = GLA()->rendermodemap[mm->id()];
int updatemask = MeshModel::MM_NONE;
if ((mm->cm.VN() != existit->_nvert) || (mm->cm.FN() != existit->_nface) || (postCondMask == MeshModel::MM_UNKNOWN) || (postCondMask == MeshModel::MM_ALL) || (postCondMask == MeshModel::MM_VERTNUMBER) || (postCondMask == MeshModel::MM_FACENUMBER) || (postCondMask == MeshModel::MM_VERTFACETOPO) || (postCondMask == MeshModel::MM_FACEFACETOPO))
updatemask = MeshModel::MM_ALL;
else
//masks differences bitwise operator (^) -> remove the attributes that didn't apparently change + the ones that for sure changed according to the postCondition function
//this operation has been introduced in order to minimize problems with filters that didn't declared properly the postCondition mask
updatemask = (existit->_mask ^ mm->dataMask()) | postCondMask;
//WARNING!!!!!!!!!!!!!!!! TOBEDELETED
//init the buffer object structures for the newly created mesh. It covers both the MeshCreating filters and the filters creating a new layer (i.e. poisson)
// if (!existingmeshesbeforefilterexecutionlocal.contains(mm->id()))
// mm->bor.update(mm->cm,MeshModel::MM_ALL,rm.drawMode,nmmode,rm.colorMode,rm.textureMode);
// else
// mm->bor.update(mm->cm,postCondMask,rm.drawMode,nmmode,rm.colorMode,rm.textureMode);
updatePerMeshRenderingDataAccordingToUpdateMaskConsideringAllGLArea(mm->id(),updatemask);
}
else
updatePerMeshRenderingDataAccordingToUpdateMaskConsideringAllGLArea(mm->id(),(int) MeshModel::MM_ALL);
existingmeshesbeforefilterexecution.clear();
}
}
catch (std::bad_alloc& bdall)
@ -1506,7 +1513,7 @@ void MainWindow::executeFilter(MeshLabXMLFilterContainer* mfc,const QMap<QString
meshDoc()->xmlhistory << funcall;
existingmeshesbeforefilterexecution.clear();
for(MeshModel* mm = meshDoc()->nextMesh();mm != NULL;mm=meshDoc()->nextMesh(mm))
existingmeshesbeforefilterexecution.insert(mm->id());
existingmeshesbeforefilterexecution.insert(mm->id(),MeshModelTmpData(mm->dataMask(),(size_t) mm->cm.VN(),(size_t) mm->cm.FN()));
if (filtercpp)
{
enableDocumentSensibleActionsContainer(false);
@ -1596,6 +1603,23 @@ void MainWindow::postFilterExecution()
rm = ci.value();
nm = vcg::GlTrimesh<CMeshO>::convertDrawModeToNormalMode(rm.drawMode);
}
QMap<int,MeshModelTmpData>::Iterator existit = existingmeshesbeforefilterexecution.find(mm->id());
if (existit != existingmeshesbeforefilterexecution.end())
{
RenderMode rm = GLA()->rendermodemap[mm->id()];
int updatemask = MeshModel::MM_NONE;
if ((mm->cm.VN() != existit->_nvert) || (mm->cm.FN() != existit->_nface) || (postCondMask == MeshModel::MM_UNKNOWN) || (postCondMask == MeshModel::MM_ALL) || (postCondMask == MeshModel::MM_VERTNUMBER) || (postCondMask == MeshModel::MM_FACENUMBER) || (postCondMask == MeshModel::MM_VERTFACETOPO) || (postCondMask == MeshModel::MM_FACEFACETOPO))
updatemask = MeshModel::MM_ALL;
else
//masks differences bitwise operator (^) -> remove the attributes that didn't apparently change + the ones that for sure changed according to the postCondition function
//this operation has been introduced in order to minimize problems with filters that didn't declared properly the postCondition mask
updatemask = (existit->_mask ^ mm->dataMask()) | postCondMask;
updatePerMeshRenderingDataAccordingToUpdateMaskConsideringAllGLArea(mm->id(),updatemask);
}
else
updatePerMeshRenderingDataAccordingToUpdateMaskConsideringAllGLArea(mm->id(),(int) MeshModel::MM_ALL);
//WARNING!!!!!!!!!!!!!!!! TOBEDELETED
//init the buffer object structures for the newly created mesh. It covers both the MeshCreating filters and the filters creating a new layer (i.e. poisson)
// if (!existingmeshesbeforefilterexecution.contains(mm->id()))
@ -3046,8 +3070,8 @@ void MainWindow::updateRenderMode( )
MeshModel* mmod = meshDoc()->getMesh(it.key());
if (mmod == NULL)
throw MeshLabException("A RenderModeAction referred to a non-existent mesh.");
deallocateReqAttsConsideringAllOtherGLArea(GLA(),it.key(),old,rm);
deallocateNotMoreNecessaryPerMeshAndPerGLAreaRenderingDataConsideringAllOtherGLArea(it.key(),GLA(),old,rm);
GLA()->setupRequestedAttributesPerMesh(it.key());
}
}
@ -3069,39 +3093,12 @@ void MainWindow::updateRenderMode( )
if (mmod == NULL)
throw MeshLabException("A RenderModeAction referred to a non-existent mesh.");
deallocateReqAttsConsideringAllOtherGLArea(GLA(),it.key(),old,rm);
deallocateNotMoreNecessaryPerMeshAndPerGLAreaRenderingDataConsideringAllOtherGLArea(it.key(),GLA(),old,rm);
GLA()->setupRequestedAttributesPerMesh(it.key());
}
GLA()->update();
}
void MainWindow::deallocateReqAttsConsideringAllOtherGLArea(GLArea* ar,const int meshid,const RenderMode& currentrendmode,const RenderMode& newrendermode)
{
MultiViewer_Container* mvc = currentViewContainer();
if ((mvc == NULL) || (ar == NULL))
return;
int currentid = ar->getId();
vcg::GLFeederInfo::ReqAtts oldatts;
MLSceneRenderModeAdapter::renderModeToReqAtts(currentrendmode,oldatts);
vcg::GLFeederInfo::ReqAtts newatts;
MLSceneRenderModeAdapter::renderModeToReqAtts(newrendermode,newatts);
oldatts = vcg::GLFeederInfo::ReqAtts::setComplement(oldatts,newatts);
for(int ii = 0; ii < mvc->viewerCounter();++ii)
{
GLArea* otherarea = mvc->getViewer(ii);
if ((ii != currentid) && (otherarea != NULL))
{
vcg::GLFeederInfo::ReqAtts othermeshview;
MLSceneRenderModeAdapter::renderModeToReqAtts(mvc->getViewer(ii)->rendermodemap[meshid],othermeshview);
oldatts = vcg::GLFeederInfo::ReqAtts::setComplement(oldatts,othermeshview);
}
}
MLThreadSafeGLMeshAttributesFeeder* feed = mvc->sharedDataContext()->meshAttributesFeeder(meshid);
if (feed != NULL)
feed->invalidateRequestedAttributes(oldatts);
}
void MainWindow::connectRenderModeActionList(QList<RenderModeAction*>& actlist)
{
for (int ii = 0; ii < actlist.size();++ii)
@ -3133,3 +3130,60 @@ void MainWindow::setBestTextureModePerMesh(RenderModeAction* textact,const int m
rm.setTextureMode(texmode);
}
}
void MainWindow::updatePerMeshRenderingDataAccordingToUpdateMaskConsideringAllGLArea(int meshid,int updatemask)
{
MultiViewer_Container* mvc = currentViewContainer();
if ((meshDoc() == NULL) || (mvc == NULL))
return;
vcg::GLFeederInfo::ReqAtts res;
MeshModel* mm = meshDoc()->getMesh(meshid);
if (mm == NULL)
return;
for(int ii = 0; ii < mvc->viewerCounter();++ii)
{
GLArea* glar = mvc->getViewer(ii);
if (glar != NULL)
{
QMap<int,RenderMode>::const_iterator it =glar->rendermodemap.find(meshid);
if (it != NULL)
{
vcg::GLFeederInfo::ReqAtts reqattperglarea;
reqattperglarea = MLSceneRenderModeAdapter::convertUpdateMaskToMinimalReqAtts(updatemask,*mm,it.value());
res = vcg::GLFeederInfo::ReqAtts::setUnion(res,reqattperglarea);
}
}
}
MLThreadSafeGLMeshAttributesFeeder* feed = mvc->sharedDataContext()->meshAttributesFeeder(meshid);
bool allocated;
feed->invalidateRequestedAttributes(res);
feed->setupRequestedAttributes(res,allocated);
}
void MainWindow::deallocateNotMoreNecessaryPerMeshAndPerGLAreaRenderingDataConsideringAllOtherGLArea(const int meshid,GLArea* gla,const RenderMode& currentrendmode,const RenderMode& newrendermode)
{
MultiViewer_Container* mvc = currentViewContainer();
if ((meshDoc() == NULL) || (mvc == NULL))
return;
if (gla == NULL)
return;
vcg::GLFeederInfo::ReqAtts oldatts;
MLSceneRenderModeAdapter::renderModeToReqAtts(currentrendmode,oldatts);
vcg::GLFeederInfo::ReqAtts newatts;
MLSceneRenderModeAdapter::renderModeToReqAtts(newrendermode,newatts);
oldatts = vcg::GLFeederInfo::ReqAtts::setComplement(oldatts,newatts);
for(int ii = 0; ii < mvc->viewerCounter();++ii)
{
GLArea* otherarea = mvc->getViewer(ii);
if ((otherarea != NULL) && (otherarea->getId() != gla->getId()))
{
vcg::GLFeederInfo::ReqAtts othermeshview;
MLSceneRenderModeAdapter::renderModeToReqAtts(otherarea->rendermodemap[meshid],othermeshview);
oldatts = vcg::GLFeederInfo::ReqAtts::setComplement(oldatts,othermeshview);
}
}
MLThreadSafeGLMeshAttributesFeeder* feed = mvc->sharedDataContext()->meshAttributesFeeder(meshid);
if (feed != NULL)
feed->deAllocateBO(oldatts);
}