From 74f55f52730b5e8317f27f3db8296fed69a1bd74 Mon Sep 17 00:00:00 2001 From: Chelsea Jaggi Date: Tue, 23 Jun 2020 16:22:21 -0700 Subject: [PATCH] Allow all filetypes supported by meshlab to be opened with meshlabserver VisualSFM (and some other formats) output *.nvm, *.rd.out projects that meshlab can easily import and use, but the logic for this never made it into meshlabserver. I pretty much just wholesale copied/adapted the existing code from meshlab into meshlabserver, allowing any supported project to be imported like any other mlb file. --- src/{meshlab => common}/alnParser.h | 0 src/meshlab/mainwindow_RunTime.cpp | 2 +- src/meshlabplugins/filter_plymc/plymc.pro | 2 +- src/meshlabserver/mainserver.cpp | 306 ++++++++++++++++-- src/meshlabserver/meshlabserver.txt | 3 +- .../edit_arc3D/edit_arc3D.cpp | 2 +- .../edit_arc3D/edit_arc3D.h | 2 +- src/plugins_unsupported/io_epoch/epoch_io.cpp | 2 +- .../oldplymc/simplemeshprovider.h | 2 +- 9 files changed, 280 insertions(+), 41 deletions(-) rename src/{meshlab => common}/alnParser.h (100%) diff --git a/src/meshlab/alnParser.h b/src/common/alnParser.h similarity index 100% rename from src/meshlab/alnParser.h rename to src/common/alnParser.h diff --git a/src/meshlab/mainwindow_RunTime.cpp b/src/meshlab/mainwindow_RunTime.cpp index 0944f8b02..6d06f6f04 100644 --- a/src/meshlab/mainwindow_RunTime.cpp +++ b/src/meshlab/mainwindow_RunTime.cpp @@ -30,7 +30,6 @@ #include "saveSnapshotDialog.h" #include "ui_aboutDialog.h" #include "savemaskexporter.h" -#include "alnParser.h" #include #include "ml_default_decorators.h" @@ -44,6 +43,7 @@ #include "../common/meshlabdocumentxml.h" #include "../common/meshlabdocumentbundler.h" #include "../common/mlapplication.h" +#include "../common/alnParser.h" #include "../common/filterscript.h" #include "../common/mlexception.h" diff --git a/src/meshlabplugins/filter_plymc/plymc.pro b/src/meshlabplugins/filter_plymc/plymc.pro index 282fa9edc..ffad99fa2 100755 --- a/src/meshlabplugins/filter_plymc/plymc.pro +++ b/src/meshlabplugins/filter_plymc/plymc.pro @@ -21,7 +21,7 @@ HEADERS = plymc.h \ trivial_walker.h \ tri_edge_collapse_mc.h \ simplemeshprovider.h \ - ../../meshlab/alnParser.h + ../../common/alnParser.h !CONFIG(system_glew): INCLUDEPATH *= ../../code/lib/glew/include diff --git a/src/meshlabserver/mainserver.cpp b/src/meshlabserver/mainserver.cpp index 15e6cd7d6..a322d1668 100644 --- a/src/meshlabserver/mainserver.cpp +++ b/src/meshlabserver/mainserver.cpp @@ -28,6 +28,8 @@ #include #include #include +#include +#include #include #include #include @@ -242,40 +244,282 @@ public: return true; } - bool openProject(MeshDocument& md,const QString& filename) + bool loadMesh(const QString& fileName, MeshIOInterface *pCurrentIOPlugin, MeshModel* mm, int& mask,RichParameterSet* prePar, const Matrix44m &mtr, MeshDocument* md, FILE* fp = stdout) { - QDir curDir = QDir::current(); - QFileInfo fi(filename); - std::map tmp; - bool opened = MeshDocumentFromXML(md,fi.absoluteFilePath(), fi.suffix().toLower() == "mlb",tmp); - if (!opened) + if (mm == NULL) return false; - QDir::setCurrent(fi.absolutePath()); - //WARNING! I'm not putting inside MeshDocumentFromXML function because I'm too scared of what can happen inside MeshLab code.... - md.setFileName(fi.absoluteFilePath()); - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - for (int i=0; isetBusy(true); + pCurrentIOPlugin->setLog(&md->Log); + + if (!pCurrentIOPlugin->open(extension, fileNameSansDir, *mm ,mask,*prePar)) + { + fprintf(fp, "Opening Failure: %s", (QString("While opening: '%1'\n\n").arg(fileName)+pCurrentIOPlugin->errorMsg()).toStdString().c_str()); // text+ + pCurrentIOPlugin->clearErrorString(); + md->setBusy(false); + QDir::setCurrent(origDir); // undo the change of directory before leaving + return false; + } + + + //std::cout << "Opened mesh: in " << tm.elapsed() << " secs\n"; + // After opening the mesh lets ask to the io plugin if this format + // requires some optional, or userdriven post-opening processing. + // and in that case ask for the required parameters and then + // ask to the plugin to perform that processing + //RichParameterSet par; + //pCurrentIOPlugin->initOpenParameter(extension, *mm, par); + //pCurrentIOPlugin->applyOpenParameter(extension, *mm, par); + + QString err = pCurrentIOPlugin->errorMsg(); + if (!err.isEmpty()) + { + fprintf(fp, "Opening Problems: %s", (QString("While opening: '%1'\n\n").arg(fileName)+pCurrentIOPlugin->errorMsg()).toStdString().c_str()); + pCurrentIOPlugin->clearErrorString(); + } + + //saveRecentFileList(fileName); + + //if (!(mm->cm.textures.empty())) + // updateTexture(mm->id()); + + // In case of polygonal meshes the normal should be updated accordingly + if( mask & vcg::tri::io::Mask::IOM_BITPOLYGONAL) + { + mm->updateDataMask(MeshModel::MM_POLYGONAL); // just to be sure. Hopefully it should be done in the plugin... + int degNum = vcg::tri::Clean::RemoveDegenerateFace(mm->cm); + if(degNum) + fprintf(stdout, "Warning model contains %i degenerate faces. Removed them.",degNum); + mm->updateDataMask(MeshModel::MM_FACEFACETOPO); + vcg::tri::UpdateNormal::PerBitQuadFaceNormalized(mm->cm); + vcg::tri::UpdateNormal::PerVertexFromCurrentFaceNormal(mm->cm); + } // standard case + else + { + vcg::tri::UpdateNormal::PerFaceNormalized(mm->cm); + if(!( mask & vcg::tri::io::Mask::IOM_VERTNORMAL) ) + vcg::tri::UpdateNormal::PerVertexAngleWeighted(mm->cm); + } + + vcg::tri::UpdateBounding::Box(mm->cm); // updates bounding box + if(mm->cm.fn==0 && mm->cm.en==0) + { + if(mask & vcg::tri::io::Mask::IOM_VERTNORMAL) + mm->updateDataMask(MeshModel::MM_VERTNORMAL); + } + + if(mm->cm.fn==0 && mm->cm.en>0) + { + if (mask & vcg::tri::io::Mask::IOM_VERTNORMAL) + mm->updateDataMask(MeshModel::MM_VERTNORMAL); + } + + //updateMenus(); + int delVertNum = vcg::tri::Clean::RemoveDegenerateVertex(mm->cm); + int delFaceNum = vcg::tri::Clean::RemoveDegenerateFace(mm->cm); + vcg::tri::Allocator::CompactEveryVector(mm->cm); + if(delVertNum>0 || delFaceNum>0 ) + fprintf(fp, "MeshLab Warning: %s", (QString("Warning mesh contains %1 vertices with NAN coords and %2 degenerated faces.\nCorrected.").arg(delVertNum).arg(delFaceNum)).toStdString().c_str() ); + mm->cm.Tr = mtr; + + //computeRenderingDataOnLoading(mm,isareload, rendOpt); + //updateLayerDialog(); + + + md->setBusy(false); + + QDir::setCurrent(origDir); // undo the change of directory before leaving + + return true; + } + + bool loadMeshWithStandardParams(QString& fullPath, MeshModel* mm, const Matrix44m &mtr = Matrix44m::Identity(), MeshDocument* md = NULL) + { + if ((mm == NULL) || (md == NULL)) + return false; + bool ret = false; + if (!mm->isVisible()) + { + mm->Clear(); + mm->visible = false; + } + else + mm->Clear(); + QFileInfo fi(fullPath); + QString extension = fi.suffix(); + MeshIOInterface *pCurrentIOPlugin = PM.allKnowInputFormats[extension.toLower()]; + + if(pCurrentIOPlugin != NULL) + { + RichParameterSet prePar; + pCurrentIOPlugin->initPreOpenParameter(extension, fullPath,prePar); + //prePar = prePar.join(currentGlobalParams); + int mask = 0; + QElapsedTimer t;t.start(); + bool open = loadMesh(fullPath,pCurrentIOPlugin,mm,mask,&prePar,mtr, md, stdout); + if(open) { - QString fullPath = md.meshList[i]->fullName(); - md.setBusy(true); - Matrix44m trm = md.meshList[i]->cm.Tr; // save the matrix, because loadMeshClear it... - if (!importMesh(*md.meshList[i],fullPath)) - { - md.delMesh(md.meshList[i]); - md.setBusy(false); - QDir::setCurrent(curDir.absolutePath()); - return false; - } - else - md.meshList[i]->cm.Tr=trm; - md.setCurrentMesh(md.meshList[i]->id()); - md.setBusy(false); + RichParameterSet par; + pCurrentIOPlugin->initOpenParameter(extension, *mm, par); + pCurrentIOPlugin->applyOpenParameter(extension,*mm,par); + ret = true; } } - QDir::setCurrent(curDir.absolutePath()); + return ret; + } + + bool openProject(MeshDocument& md,const QString& fileName,FILE* fp = stdout) + { + //bool visiblelayer = layerDialog->isVisible(); + //showLayerDlg(false); + //globrendtoolbar->setEnabled(false); + if (fileName.isEmpty()) return false; + + QFileInfo fi(fileName); + //lastUsedDirectory = fi.absoluteDir(); + //TODO: move this to main() + if((fi.suffix().toLower()!="aln") && (fi.suffix().toLower()!="mlp") && (fi.suffix().toLower() != "mlb") && (fi.suffix().toLower()!="out") && (fi.suffix().toLower()!="nvm")) + { + //QMessageBox::critical(this, tr("Meshlab Opening Error"), "Unknown project file extension"); + fprintf(fp, "Meshlab Opening Error: Unknown project file extension\n"); + return false; + } + + // Common Part: init a Doc if necessary, and + //bool activeDoc = (bool) !mdiarea->subWindowList().empty() && mdiarea->currentSubWindow(); + //bool activeEmpty = activeDoc && md.meshList.empty(); + + //if (!activeEmpty) newProject(fileName); + + md.setFileName(fileName); + //mdiarea->currentSubWindow()->setWindowTitle(fileName); + md.setDocLabel(fileName); + + md.setBusy(true); + + // this change of dir is needed for subsequent textures/materials loading + QDir::setCurrent(fi.absoluteDir().absolutePath()); + //qb->show(); + + if (QString(fi.suffix()).toLower() == "aln") + { + std::vector rmv; + int retVal = ALNParser::ParseALN(rmv, qUtf8Printable(fileName)); + if(retVal != ALNParser::NoError) + { + //QMessageBox::critical(this, tr("Meshlab Opening Error"), "Unable to open ALN file"); + fprintf(fp,"Meshlab Opening Error: Unable to open ALN file\n"); + return false; + } + + bool openRes=true; + std::vector::iterator ir; + for(ir=rmv.begin();ir!=rmv.end() && openRes;++ir) + { + QString relativeToProj = fi.absoluteDir().absolutePath() + "/" + (*ir).filename.c_str(); + md.addNewMesh(relativeToProj,relativeToProj); + openRes = loadMeshWithStandardParams(relativeToProj,md.mm(),ir->trasformation, &md); + if(!openRes) + md.delMesh(md.mm()); + } + } + + if (QString(fi.suffix()).toLower() == "mlp" || QString(fi.suffix()).toLower() == "mlb") + { + std::map rendOpt; + if (!MeshDocumentFromXML(md, fileName, (QString(fi.suffix()).toLower() == "mlb"), rendOpt)) + { + //QMessageBox::critical(this, tr("Meshlab Opening Error"), "Unable to open MeshLab Project file"); + fprintf(fp,"Meshlab Opening Error: Unable to open MeshLab Project file\n"); + return false; + } + //GLA()->updateMeshSetVisibilities(); + for (int i=0; ifullName(); + //md.setBusy(true); + Matrix44m trm = md.meshList[i]->cm.Tr; // save the matrix, because loadMeshClear it... + if (!loadMeshWithStandardParams(fullPath, md.meshList[i], trm, &md)) + md.delMesh(md.meshList[i]); + } + } + + ////// BUNDLER + if (QString(fi.suffix()).toLower() == "out"){ + + QString cameras_filename = fileName; + QString image_list_filename; + QString model_filename; + + image_list_filename = "list.txt"; + if(image_list_filename.isEmpty()) + return false; + + if(!MeshDocumentFromBundler(md,cameras_filename,image_list_filename,model_filename)){ + //QMessageBox::critical(this, tr("Meshlab Opening Error"), "Unable to open OUTs file"); + fprintf(fp,"Meshlab Opening Error: Unable to open OUTs file\n"); + return false; + } + + + //WARNING!!!!! i suppose it's not useful anymore but....... + /*GLA()->setColorMode(GLW::CMPerVert); + GLA()->setDrawMode(GLW::DMPoints);*/ + ///////////////////////////////////////////////////////// + } + + //////NVM + if (QString(fi.suffix()).toLower() == "nvm"){ + + QString cameras_filename = fileName; + QString model_filename; + + if(!MeshDocumentFromNvm(md,cameras_filename,model_filename)){ + //QMessageBox::critical(this, tr("Meshlab Opening Error"), "Unable to open NVMs file"); + fprintf(fp,"Meshlab Opening Error: Unable to open NVMs file\n"); + return false; + } + //WARNING!!!!! i suppose it's not useful anymore but....... + /*GLA()->setColorMode(GLW::CMPerVert); + GLA()->setDrawMode(GLW::DMPoints);*/ + ///////////////////////////////////////////////////////// + } + + md.setBusy(false); + //qb->reset(); + return true; } @@ -655,13 +899,7 @@ int main(int argc, char *argv[]) { QFileInfo finfo(argv[i+1]); QString inputproject = finfo.absoluteFilePath(); - if (finfo.completeSuffix().toLower() != "mlp") - { - fprintf(logfp,"Project %s is not a valid \'mlp\' file format. MeshLabServer application will exit.\n",qUtf8Printable(inputproject)); - //system("pause"); - exit(-1); - } - bool opened = server.openProject(meshDocument,inputproject); + bool opened = server.openProject(meshDocument,inputproject, logfp); if (!opened) { fprintf(logfp,"MeshLab Project %s has not been correctly opened. MeshLabServer application will exit.\n",qUtf8Printable(inputproject)); diff --git a/src/meshlabserver/meshlabserver.txt b/src/meshlabserver/meshlabserver.txt index 083d72aa9..7a538c0ac 100644 --- a/src/meshlabserver/meshlabserver.txt +++ b/src/meshlabserver/meshlabserver.txt @@ -10,7 +10,8 @@ meshlabserver [logargs] [args] where args can be: - -p filename meshlab project (.mlp) to be loaded + -p filename meshlab project (.mlp/.mlb/.aln/.out/.nvm) to + be loaded -w filename [-x] output meshlab project (.mlp) to be saved. If -x flag is specified a 3D model meshfile.ext diff --git a/src/plugins_unsupported/edit_arc3D/edit_arc3D.cpp b/src/plugins_unsupported/edit_arc3D/edit_arc3D.cpp index bfc8b231c..dc890fd13 100644 --- a/src/plugins_unsupported/edit_arc3D/edit_arc3D.cpp +++ b/src/plugins_unsupported/edit_arc3D/edit_arc3D.cpp @@ -42,7 +42,7 @@ $Log: meshedit.cpp,v $ #include #include #include -#include +#include using namespace std; using namespace vcg; diff --git a/src/plugins_unsupported/edit_arc3D/edit_arc3D.h b/src/plugins_unsupported/edit_arc3D/edit_arc3D.h index e2e7e44c0..7f2bb6fee 100644 --- a/src/plugins_unsupported/edit_arc3D/edit_arc3D.h +++ b/src/plugins_unsupported/edit_arc3D/edit_arc3D.h @@ -35,7 +35,7 @@ #include #include #include -#include +#include class EditArc3DPlugin : public QObject, public MeshEditInterface diff --git a/src/plugins_unsupported/io_epoch/epoch_io.cpp b/src/plugins_unsupported/io_epoch/epoch_io.cpp index 6afd7320d..bb62c0c26 100644 --- a/src/plugins_unsupported/io_epoch/epoch_io.cpp +++ b/src/plugins_unsupported/io_epoch/epoch_io.cpp @@ -40,7 +40,7 @@ #include #include #include -#include +#include FILE *logFP=0; using namespace std; diff --git a/src/plugins_unsupported/oldplymc/simplemeshprovider.h b/src/plugins_unsupported/oldplymc/simplemeshprovider.h index 8a55846f7..3f4d0c615 100644 --- a/src/plugins_unsupported/oldplymc/simplemeshprovider.h +++ b/src/plugins_unsupported/oldplymc/simplemeshprovider.h @@ -1,6 +1,6 @@ #ifndef SIMPLEMESHPROVIDER_H #define SIMPLEMESHPROVIDER_H -#include "../../meshlab/alnParser.h" +#include "../../common/alnParser.h" #include #include #include