diff --git a/src/common/ml_document/mesh_model.h b/src/common/ml_document/mesh_model.h index a4d7b513d..97a54dc73 100644 --- a/src/common/ml_document/mesh_model.h +++ b/src/common/ml_document/mesh_model.h @@ -168,7 +168,7 @@ public: void setVisible(bool vis = true) { visible = vis;} std::list loadTextures(GLLogStream* log = nullptr, vcg::CallBackPos* cb = nullptr); - void saveTextures(const QString& basePath, int quality = 66, GLLogStream* log = nullptr, vcg::CallBackPos* cb = nullptr); + void saveTextures(const QString& basePath, int quality = -1, GLLogStream* log = nullptr, vcg::CallBackPos* cb = nullptr); QImage getTexture(const std::string& tn) const; void clearTextures(); diff --git a/src/common/plugins/interfaces/io_plugin.h b/src/common/plugins/interfaces/io_plugin.h index 695544306..a03b358c9 100644 --- a/src/common/plugins/interfaces/io_plugin.h +++ b/src/common/plugins/interfaces/io_plugin.h @@ -282,7 +282,7 @@ public: const QString& format, const QString& /*fileName*/, const QImage& /*image*/, - int /*quality*/ = 66, + int /*quality*/ = -1, vcg::CallBackPos* /*cb*/ = nullptr) { wrongSaveFormat(format); diff --git a/src/common/utilities/load_save.cpp b/src/common/utilities/load_save.cpp index 61dff539c..4874e0d7c 100644 --- a/src/common/utilities/load_save.cpp +++ b/src/common/utilities/load_save.cpp @@ -249,7 +249,7 @@ void saveMeshWithStandardParameters( ioPlugin->save(extension, fileName, m, capability, saveParams, cb); m.setFileName(fileName); - m.saveTextures(fi.absolutePath(), 66, log, cb); + m.saveTextures(fi.absolutePath(), -1, log, cb); } void saveAllMeshes( diff --git a/src/common/utilities/load_save.h b/src/common/utilities/load_save.h index 3a18ba193..e58e65010 100644 --- a/src/common/utilities/load_save.h +++ b/src/common/utilities/load_save.h @@ -75,7 +75,7 @@ QImage loadImage( void saveImage( const QString& filename, const QImage& image, - int quality = 66, + int quality = -1, GLLogStream* log = nullptr, vcg::CallBackPos* cb = nullptr); diff --git a/src/meshlab/dialogs/save_mesh_attributes_dialog.cpp b/src/meshlab/dialogs/save_mesh_attributes_dialog.cpp index f1afa95f4..22adf24ea 100644 --- a/src/meshlab/dialogs/save_mesh_attributes_dialog.cpp +++ b/src/meshlab/dialogs/save_mesh_attributes_dialog.cpp @@ -107,6 +107,11 @@ std::vector SaveMeshAttributesDialog::getTextureNames() const return textureNames; } +bool SaveMeshAttributesDialog::saveTextures() const +{ + return ui->saveTextureCheckBox->isChecked(); +} + int SaveMeshAttributesDialog::getTextureQuality() const { return textureQuality; @@ -304,3 +309,19 @@ void SaveMeshAttributesDialog::updateMask() this->mask=newmask; } + +void SaveMeshAttributesDialog::on_saveTextureCheckBox_stateChanged(int arg1) +{ + ui->textureQualitySpinBox->setEnabled(arg1 == Qt::Checked); + ui->textureQualityLabel->setEnabled(arg1 == Qt::Checked); +} + +void SaveMeshAttributesDialog::on_textureQualitySpinBox_valueChanged(int arg1) +{ + if (arg1 == -1){ + ui->textureQualitySpinBox->setSuffix(" (default)"); + } + else { + ui->textureQualitySpinBox->setSuffix(""); + } +} diff --git a/src/meshlab/dialogs/save_mesh_attributes_dialog.h b/src/meshlab/dialogs/save_mesh_attributes_dialog.h index 2b85827fc..f74543d64 100644 --- a/src/meshlab/dialogs/save_mesh_attributes_dialog.h +++ b/src/meshlab/dialogs/save_mesh_attributes_dialog.h @@ -64,6 +64,7 @@ public: int getNewMask() const; RichParameterList getNewAdditionalSaveParameters() const; std::vector getTextureNames() const; + bool saveTextures() const; int getTextureQuality() const; private slots: @@ -75,6 +76,10 @@ private slots: void on_AllButton_clicked(); void on_NoneButton_clicked(); + void on_saveTextureCheckBox_stateChanged(int arg1); + + void on_textureQualitySpinBox_valueChanged(int arg1); + private: void setMaskCapability(); void checkAndEnable(QCheckBox *qcb,int bit, int capabilityBits, int defaultBits); diff --git a/src/meshlab/dialogs/save_mesh_attributes_dialog.ui b/src/meshlab/dialogs/save_mesh_attributes_dialog.ui index 914c2535f..800bc6552 100644 --- a/src/meshlab/dialogs/save_mesh_attributes_dialog.ui +++ b/src/meshlab/dialogs/save_mesh_attributes_dialog.ui @@ -237,6 +237,19 @@ + + + + Save Texture File(s) + + + true + + + true + + + @@ -270,6 +283,9 @@ + + + -1 @@ -277,7 +293,7 @@ 100 - 66 + -1 diff --git a/src/meshlab/layerDialog.cpp b/src/meshlab/layerDialog.cpp index 8b9bac28d..04d721201 100644 --- a/src/meshlab/layerDialog.cpp +++ b/src/meshlab/layerDialog.cpp @@ -799,7 +799,7 @@ void LayerDialog::addDefaultNotes(QTreeWidgetItem * parent, MeshModel *meshModel for(const std::string& name: vertPointNames) { QTreeWidgetItem *vertItem = new QTreeWidgetItem(); - vertItem->setText(2, QString("Vert (point):")); + vertItem->setText(2, QString("Vert (vec3):")); vertItem->setText(3, QString(name.c_str())); parent->addChild(vertItem); updateColumnNumber(vertItem); @@ -815,7 +815,7 @@ void LayerDialog::addDefaultNotes(QTreeWidgetItem * parent, MeshModel *meshModel for(const std::string& name: facePointNames) { QTreeWidgetItem *vertItem = new QTreeWidgetItem(); - vertItem->setText(2, QString("Face (point):")); + vertItem->setText(2, QString("Face (vec3):")); vertItem->setText(3, QString(name.c_str())); parent->addChild(vertItem); updateColumnNumber(vertItem); diff --git a/src/meshlab/mainwindow.h b/src/meshlab/mainwindow.h index 760ed7664..92ad2752c 100644 --- a/src/meshlab/mainwindow.h +++ b/src/meshlab/mainwindow.h @@ -152,12 +152,9 @@ private slots: public: bool exportMesh(QString fileName,MeshModel* mod,const bool saveAllPossibleAttributes); - bool loadMesh(const QString& fileName, IOPlugin *pCurrentIOPlugin, const std::list& meshList, std::list& maskList, const RichParameterList& prePar, const Matrix44m &mtr=Matrix44m::Identity(), bool isareload = false, MLRenderingData* rendOpt = NULL); void computeRenderingDataOnLoading(MeshModel* mm,bool isareload, MLRenderingData* rendOpt = NULL); - bool loadMeshWithStandardParams(QString& fullPath, MeshModel* mm, const Matrix44m &mtr = Matrix44m::Identity(), bool isareload = false, MLRenderingData* rendOpt = NULL); - void defaultPerViewRenderingData(MLRenderingData& dt) const; void getRenderingData(int mid,MLRenderingData& dt) const; void setRenderingData(int mid,const MLRenderingData& dt); diff --git a/src/meshlab/mainwindow_RunTime.cpp b/src/meshlab/mainwindow_RunTime.cpp index 4887cee57..c0a9b1317 100644 --- a/src/meshlab/mainwindow_RunTime.cpp +++ b/src/meshlab/mainwindow_RunTime.cpp @@ -2006,137 +2006,6 @@ bool MainWindow::importRaster(const QString& fileImg) return true; } -bool MainWindow::loadMesh(const QString& fileName, IOPlugin *pCurrentIOPlugin, const std::list& meshList, std::list& maskList, const RichParameterList& prePar, const Matrix44m &mtr, bool isareload, MLRenderingData* rendOpt) -{ - if ((GLA() == NULL)) - return false; - - QFileInfo fi(fileName); - QString extension = fi.suffix(); - - // the original directory path before we switch it - QString origDir = QDir::current().path(); - - // this change of dir is needed for subsequent textures/materials loading - QDir::setCurrent(fi.absoluteDir().absolutePath()); - - // Adjust the file name after changing the directory - QString fileNameSansDir = fi.fileName(); - - // retrieving corresponding IO plugin - if (pCurrentIOPlugin == 0) - { - QString errorMsgFormat = "Error encountered while opening file:\n\"%1\"\n\nError details: The \"%2\" file extension does not correspond to any supported format."; - QMessageBox::critical(this, tr("Opening Error"), errorMsgFormat.arg(fileName, extension)); - QDir::setCurrent(origDir); // undo the change of directory before leaving - return false; - } - meshDoc()->setBusy(true); - pCurrentIOPlugin->setLog(&meshDoc()->Log); - - unsigned int nMeshes = pCurrentIOPlugin->numberMeshesContainedInFile(extension, fileNameSansDir, prePar); - if (nMeshes != meshList.size()) { - QMessageBox::warning( - this, - tr("Opening Failure"), - "Expected one mesh but " + fileName + " contains " + nMeshes + " meshes."); - meshDoc()->setBusy(false); - QDir::setCurrent(origDir); // undo the change of directory before leaving - return false; - } - - try { - meshlab::loadMesh(fileName, pCurrentIOPlugin, prePar, meshList, maskList, QCallBack); - } - catch(const MLException& e) { - QMessageBox::warning( - this, - tr("Opening Failure"), - "While opening: " + fileName + "\n\n" + e.what()); - meshDoc()->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->warningMessageString(); - if (!err.isEmpty()) - { - QMessageBox::warning(this, tr("Opening Problems"), QString("While opening: '%1'\n\n").arg(fileName)+ err); - } - - saveRecentFileList(fileName); - - auto itmesh = meshList.begin(); - auto itmask = maskList.begin(); - for (unsigned int i = 0; i < meshList.size(); ++i){ - MeshModel* mm = *itmesh; - int mask = *itmask; - - 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 = tri::Clean::RemoveDegenerateFace(mm->cm); - if(degNum) - GLA()->Logf(0,"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); - tri::Allocator::CompactEveryVector(mm->cm); - if(delVertNum>0 || delFaceNum>0 ) - QMessageBox::warning(this, "MeshLab Warning", QString("Warning mesh contains %1 vertices with NAN coords and %2 degenerated faces.\nCorrected.").arg(delVertNum).arg(delFaceNum) ); - mm->cm.Tr = mtr; - - computeRenderingDataOnLoading(mm,isareload, rendOpt); - ++itmesh; - ++itmask; - } - - updateLayerDialog(); - - meshDoc()->setBusy(false); - - QDir::setCurrent(origDir); // undo the change of directory before leaving - - return true; -} - void MainWindow::computeRenderingDataOnLoading(MeshModel* mm,bool isareload, MLRenderingData* rendOpt) { MultiViewer_Container* mv = currentViewContainer(); @@ -2145,8 +2014,26 @@ void MainWindow::computeRenderingDataOnLoading(MeshModel* mm,bool isareload, MLR MLSceneGLSharedDataContext* shared = mv->sharedDataContext(); if ((shared != NULL) && (mm != NULL)) { + //count the number of faces contained in the whole meshdocument before the newly inserted mm + unsigned int totalSumFaces = 0; + bool found = false; + for (const MeshModel* m : meshDoc()->meshIterator()){ + if (!found){ + if (m != mm){ + totalSumFaces += mm->cm.FN(); + } + else { //found mm: stop counting + found = true; + } + } + } + unsigned int minNumberPolFlatShading = mwsettings.minpolygonpersmoothrendering; + //if the total number of faces is greater than 5*minpolynumber, + //the newly mesh will be set with flat shading + if (totalSumFaces > 5 * minNumberPolFlatShading) + minNumberPolFlatShading = 0; MLRenderingData defdt; - MLPoliciesStandAloneFunctions::suggestedDefaultPerViewRenderingData(mm, defdt,mwsettings.minpolygonpersmoothrendering); + MLPoliciesStandAloneFunctions::suggestedDefaultPerViewRenderingData(mm, defdt, minNumberPolFlatShading); if (rendOpt != NULL) defdt = *rendOpt; for (int glarid = 0; glarid < mv->viewerCounter(); ++glarid) @@ -2314,8 +2201,7 @@ bool MainWindow::importMesh(QString fileName) }// end foreach file of the input list GLA()->Logf(0,"All files opened in %i msec",allFileTime.elapsed()); - if (_currviewcontainer != NULL) - { + if (_currviewcontainer != NULL) { _currviewcontainer->resetAllTrackBall(); _currviewcontainer->updateAllDecoratorsForAllViewers(); } @@ -2337,50 +2223,6 @@ void MainWindow::openRecentProj() if (action) openProject(action->data().toString()); } -/** - * **TODO**: this function assumes that the loaded file will contain just one - * mesh....... - */ -bool MainWindow::loadMeshWithStandardParams(QString& fullPath, MeshModel* mm, const Matrix44m &mtr, bool isreload, MLRenderingData* rendOpt) -{ - if ((meshDoc() == NULL) || (mm == NULL)) - return false; - bool ret = false; - if (!mm->isVisible()) - { - mm->clear(); - mm->setVisible(false); - } - else - mm->clear(); - QFileInfo fi(fullPath); - QString extension = fi.suffix(); - IOPlugin *pCurrentIOPlugin = PM.inputMeshPlugin(extension); - - if(pCurrentIOPlugin != NULL) - { - RichParameterList prePar = pCurrentIOPlugin->initPreOpenParameter(extension); - prePar.join(currentGlobalParams); - - QElapsedTimer t;t.start(); - - std::list ml; - std::list masks; - ml.push_back(mm); - bool open = loadMesh(fullPath,pCurrentIOPlugin,ml,masks,prePar,mtr,isreload, rendOpt); - if(open) - { - GLA()->Logf(0, "Opened mesh %s in %i msec", qUtf8Printable(fullPath), t.elapsed()); - ret = true; - } - else - GLA()->Logf(0, "Warning: Mesh %s has not been opened", qUtf8Printable(fullPath)); - } - else - GLA()->Logf(0, "Warning: Mesh %s cannot be opened. Your MeshLab version has not plugin to read %s file format", qUtf8Printable(fullPath), qUtf8Printable(extension)); - return ret; -} - void MainWindow::reloadAllMesh() { // Discards changes and reloads current file @@ -2482,7 +2324,7 @@ bool MainWindow::exportMesh(QString fileName,MeshModel* mod,const bool saveAllPo mod->setMeshModified(false); QString laylabel = "Save \"" + mod->label() + "\" Layer"; QFileDialog* saveDialog = new QFileDialog(this,laylabel, fi.absolutePath()); - saveDialog->setOption(QFileDialog::DontUseNativeDialog); + //saveDialog->setOption(QFileDialog::DontUseNativeDialog); saveDialog->setNameFilters(suffixList); saveDialog->setAcceptMode(QFileDialog::AcceptSave); saveDialog->setFileMode(QFileDialog::AnyFile); @@ -2540,7 +2382,8 @@ bool MainWindow::exportMesh(QString fileName,MeshModel* mod,const bool saveAllPo RichParameterList savePar = pCurrentIOPlugin->initSaveParameter(extension,*(mod)); SaveMeshAttributesDialog maskDialog(this, mod, capability, defaultBits, savePar, this->GLA()); - int quality = 66; + int quality = -1; + bool saveTextures = true; if (!saveAllPossibleAttributes) maskDialog.exec(); else { @@ -2552,13 +2395,17 @@ bool MainWindow::exportMesh(QString fileName,MeshModel* mod,const bool saveAllPo int mask = maskDialog.getNewMask(); savePar = maskDialog.getNewAdditionalSaveParameters(); quality = maskDialog.getTextureQuality(); - std::vector textureNames = maskDialog.getTextureNames(); + saveTextures = maskDialog.saveTextures(); - for (unsigned int i = 0; i < mod->cm.textures.size(); ++i){ - if (textureNames[i].find('.') == std::string::npos){ - textureNames[i] += ".png"; + if (!saveTextures){ + std::vector textureNames = maskDialog.getTextureNames(); + + for (unsigned int i = 0; i < mod->cm.textures.size(); ++i){ + if (textureNames[i].find('.') == std::string::npos){ + textureNames[i] += ".png"; + } + mod->changeTextureName(mod->cm.textures[i], textureNames[i]); } - mod->changeTextureName(mod->cm.textures[i], textureNames[i]); } if (!saveAllPossibleAttributes) { maskDialog.close(); @@ -2576,7 +2423,8 @@ bool MainWindow::exportMesh(QString fileName,MeshModel* mod,const bool saveAllPo try { pCurrentIOPlugin->save(extension, fileName, *mod ,mask,savePar,QCallBack); QFileInfo finfo(fileName); - mod->saveTextures(finfo.absolutePath(), quality, &meshDoc()->Log, QCallBack); + if (saveTextures) + mod->saveTextures(finfo.absolutePath(), quality, &meshDoc()->Log, QCallBack); GLA()->Logf(GLLogStream::SYSTEM, "Saved Mesh %s in %i msec", qUtf8Printable(fileName), tt.elapsed()); mod->setFileName(fileName); QSettings settings;