From 7551f8afe45c8cecbf5af8566c33b4df9e8565e7 Mon Sep 17 00:00:00 2001
From: zaza <zain.selman@rwth-aachen.de>
Date: Wed, 12 Aug 2020 16:45:48 +0200
Subject: [PATCH] adds additional conditions that will reduce the number of
 materials written. so far the speed is already useable again

---
 FileOBJT_impl.hh | 524 ++++++++++++++++++++++++-----------------------
 1 file changed, 264 insertions(+), 260 deletions(-)

diff --git a/FileOBJT_impl.hh b/FileOBJT_impl.hh
index 66f7104..c82599e 100644
--- a/FileOBJT_impl.hh
+++ b/FileOBJT_impl.hh
@@ -39,41 +39,36 @@
 *                                                                            *
 \*===========================================================================*/
 
-
-
-
 #define FILEOBJPLUGIN_C
 
 #include "FileOBJ.hh"
 
-#include <OpenMesh/Core/Utils/color_cast.hh>
 #include <OpenMesh/Core/Geometry/VectorT.hh>
-
+#include <OpenMesh/Core/Utils/color_cast.hh>
 
 //-----------------------------------------------------------------------------------------------------
 
-template< class MeshT >
-bool FileOBJPlugin::writeMaterial(QString _filename, MeshT& _mesh, int _objId )
-{
-  bool optionColorAlpha      = false;
-  bool optionTextures        = false;
-  bool optionCopyTextures    = false;
+template <class MeshT>
+bool FileOBJPlugin::writeMaterial(QString _filename, MeshT& _mesh, int _objId) {
+  bool optionColorAlpha = false;
+  bool optionTextures = false;
+  bool optionCopyTextures = false;
   bool optionCreateTexFolder = false;
 
   // check options
-  if ( !OpenFlipper::Options::savingSettings() && saveOptions_ != 0) {
-      optionColorAlpha      = saveAlpha_->isChecked();
-      optionTextures        = saveTextures_->isChecked();
-      optionCopyTextures    = saveCopyTextures_->isChecked();
-      optionCreateTexFolder = saveCreateTexFolder_->isChecked();
+  if (!OpenFlipper::Options::savingSettings() && saveOptions_ != 0) {
+    optionColorAlpha = saveAlpha_->isChecked();
+    optionTextures = saveTextures_->isChecked();
+    optionCopyTextures = saveCopyTextures_->isChecked();
+    optionCreateTexFolder = saveCreateTexFolder_->isChecked();
   }
   // \TODO Fetch options from ini states if dialog box is not available
 
-  std::fstream matStream( _filename.toStdString().c_str(), std::ios_base::out );
-
-  if ( !matStream ){
+  std::fstream matStream(_filename.toStdString().c_str(), std::ios_base::out);
 
-    emit log(LOGERR, tr("writeMaterial : cannot not open file %1").arg(_filename) );
+  if (!matStream) {
+    emit log(LOGERR,
+             tr("writeMaterial : cannot not open file %1").arg(_filename));
     return false;
   }
 
@@ -83,47 +78,49 @@ bool FileOBJPlugin::writeMaterial(QString _filename, MeshT& _mesh, int _objId )
 
   materials_.clear();
 
-  //iterate over faces
+  // iterate over faces
   typename MeshT::FaceIter f_it;
   typename MeshT::FaceIter f_end = _mesh.faces_end();
 
   // Prepare materials ( getMaterial handles a list that is set up by this call)
-  for (f_it = _mesh.faces_begin(); f_it != f_end; ++f_it){
+  for (f_it = _mesh.faces_begin(); f_it != f_end; ++f_it) {
     getMaterial(_mesh, *f_it, _objId);
   }
 
-  //write the materials
-  for(MaterialList::iterator it = materials_.begin(); it != materials_.end(); ++it) {
-      Material& mat = (*it).second;
-      matStream << "newmtl " << mat << '\n';
-      matStream << "Ka 0.5000 0.5000 0.5000" << '\n';
-      ACG::Vec3f c = mat.Kd();
-      matStream << "Kd " << c[0] << " " << c[1] << " " << c[2] << '\n';
-      if(optionColorAlpha) {
-          matStream << "Tr " << mat.Tr() << '\n';
-      }
-      matStream << "illum 1" << '\n';
-
-      // Write out texture info
-      if(optionTextures && mat.has_Texture()) {
-          if(optionCopyTextures) {
-              // Use file path in target folder (relative)
-              QFileInfo file(mat.map_Kd().c_str());
-              if(optionCreateTexFolder) {
-                  QFileInfo materialFilename(_filename);
-
-                  matStream << "map_Kd " << materialFilename.baseName().toStdString() << "_textures" << QDir::separator().toLatin1()
-                      << file.fileName().toStdString() << '\n';
-              } else {
-                  matStream << "map_Kd " << file.fileName().toStdString() << '\n';
-              }
-          } else {
-              // Use original file path
-              matStream << "map_Kd " << mat.map_Kd() << '\n';
-          }
+  // write the materials
+  for (MaterialList::iterator it = materials_.begin(); it != materials_.end();
+       ++it) {
+    Material& mat = (*it).second;
+    matStream << "newmtl " << mat << '\n';
+    matStream << "Ka 0.5000 0.5000 0.5000" << '\n';
+    ACG::Vec3f c = mat.Kd();
+    matStream << "Kd " << c[0] << " " << c[1] << " " << c[2] << '\n';
+    if (optionColorAlpha) {
+      matStream << "Tr " << mat.Tr() << '\n';
+    }
+    matStream << "illum 1" << '\n';
+
+    // Write out texture info
+    if (optionTextures && mat.has_Texture()) {
+      if (optionCopyTextures) {
+        // Use file path in target folder (relative)
+        QFileInfo file(mat.map_Kd().c_str());
+        if (optionCreateTexFolder) {
+          QFileInfo materialFilename(_filename);
+
+          matStream << "map_Kd " << materialFilename.baseName().toStdString()
+                    << "_textures" << QDir::separator().toLatin1()
+                    << file.fileName().toStdString() << '\n';
+        } else {
+          matStream << "map_Kd " << file.fileName().toStdString() << '\n';
+        }
+      } else {
+        // Use original file path
+        matStream << "map_Kd " << mat.map_Kd() << '\n';
       }
+    }
 
-      matStream << '\n';
+    matStream << '\n';
   }
 
   matStream.close();
@@ -133,148 +130,151 @@ bool FileOBJPlugin::writeMaterial(QString _filename, MeshT& _mesh, int _objId )
 
 //-----------------------------------------------------------------------------------------------------
 
-template< class MeshT >
-Material& FileOBJPlugin::getMaterial(MeshT& _mesh, const OpenMesh::FaceHandle& _fh, int _objId)
-{
-    // check options
-    bool optionColorAlpha = false;
-    if ( !OpenFlipper::Options::savingSettings() && saveOptions_ != 0)
-        optionColorAlpha = saveAlpha_->isChecked();
-    // \TODO Fetch options from ini states if dialog box is not available
-
-    OpenMesh::Vec4f c = _mesh.color( _fh );
-
-    // If one of the entries is out of range, assume uninitialized color and set to default
-    // Ugly hack to ensure that materials will only be generated if initialized
-    if ( c[0] > 255.0 || c[1] > 255.0 || c[2] > 255.0 || c[0] < 0.0 || c[1] < 0.0 || c[2] < 0.0) {
-      c[0] = 155.0;
-      c[1] = 155.0;
-      c[2] = 155.0;
-      c[3] = 1.0;
-    }
+template <class MeshT>
+Material& FileOBJPlugin::getMaterial(MeshT& _mesh,
+                                     const OpenMesh::FaceHandle& _fh,
+                                     int _objId) {
+  // check options
+  bool optionColorAlpha = false;
+  if (!OpenFlipper::Options::savingSettings() && saveOptions_ != 0)
+    optionColorAlpha = saveAlpha_->isChecked();
+  // \TODO Fetch options from ini states if dialog box is not available
 
-    // First off, try to fetch texture index of current face/object...
-    if(!textureIndexPropFetched_) {
-        emit textureIndexPropertyName(_objId, textureIndexPropertyName_);
-        textureIndexPropFetched_ = true;
-    }
+  OpenMesh::Vec4f c = _mesh.color(_fh);
+
+  // If one of the entries is out of range, assume uninitialized color and set
+  // to default Ugly hack to ensure that materials will only be generated if
+  // initialized
+  if (c[0] > 255.0 || c[1] > 255.0 || c[2] > 255.0 || c[0] < 0.0 ||
+      c[1] < 0.0 || c[2] < 0.0 || std::isnan(c[0]) || std::isnan(c[1]) ||
+      std::isnan(c[2])) {
+    c[0] = 155.0;
+    c[1] = 155.0;
+    c[2] = 155.0;
+    c[3] = 1.0;
+  }
 
-    int texIndex = -1;
-    OpenMesh::FPropHandleT< int > texture_index_property;
-    if ( _mesh.get_property_handle(texture_index_property, textureIndexPropertyName_.toStdString()) ) {
-        texIndex = _mesh.property(texture_index_property, _fh);
-    } else if ( _mesh.get_property_handle(texture_index_property, "f:textureindex") ) {
-        texIndex = _mesh.property(texture_index_property, _fh);
-    } else if(_mesh.has_face_texture_index()) {
-        texIndex = _mesh.texture_index(_fh);
-    } else {
-        QString texName;
-        emit getCurrentTexture(_objId, texName);
-        if(texName != "NONE")
-          emit textureIndex(texName, _objId, texIndex);
-    }
+  // First off, try to fetch texture index of current face/object...
+  if (!textureIndexPropFetched_) {
+    emit textureIndexPropertyName(_objId, textureIndexPropertyName_);
+    textureIndexPropFetched_ = true;
+  }
 
-    QString filename;
-    bool hasTexture = false;
+  int texIndex = -1;
+  OpenMesh::FPropHandleT<int> texture_index_property;
+  if (_mesh.get_property_handle(texture_index_property,
+                                textureIndexPropertyName_.toStdString())) {
+    texIndex = _mesh.property(texture_index_property, _fh);
+  } else if (_mesh.get_property_handle(texture_index_property,
+                                       "f:textureindex")) {
+    texIndex = _mesh.property(texture_index_property, _fh);
+  } else if (_mesh.has_face_texture_index()) {
+    texIndex = _mesh.texture_index(_fh);
+  } else {
+    QString texName;
+    emit getCurrentTexture(_objId, texName);
+    if (texName != "NONE") emit textureIndex(texName, _objId, texIndex);
+  }
 
-    if(texIndex != -1) {
+  QString filename;
+  bool hasTexture = false;
 
-        // Search for texture index in local map
-        std::map<int,QString>::iterator it = texIndexFileMap_.find(texIndex);
+  if (texIndex != -1) {
+    // Search for texture index in local map
+    std::map<int, QString>::iterator it = texIndexFileMap_.find(texIndex);
 
-        if(it != texIndexFileMap_.end()) {
-            // We already know this file
-            filename = (*it).second;
-            hasTexture = true;
-        } else {
-            // A new texture file has been found
-            QString texName;
-            emit textureName(_objId, texIndex, texName);
-
-            if(texName != "NOT_FOUND") {
-                emit textureFilename( _objId, texName, filename );
-                // => Add to local map
-                texIndexFileMap_.insert(std::pair<int,QString>(texIndex, filename));
-                hasTexture = true;
-            }
-        }
+    if (it != texIndexFileMap_.end()) {
+      // We already know this file
+      filename = (*it).second;
+      hasTexture = true;
+    } else {
+      // A new texture file has been found
+      QString texName;
+      emit textureName(_objId, texIndex, texName);
+
+      if (texName != "NOT_FOUND") {
+        emit textureFilename(_objId, texName, filename);
+        // => Add to local map
+        texIndexFileMap_.insert(std::pair<int, QString>(texIndex, filename));
+        hasTexture = true;
+      }
     }
+  }
 
-    for (MaterialList::iterator it = materials_.begin(); it != materials_.end(); ++it) {
-
-        // No texture has been found
-        if(!hasTexture) {
-            // ... just look for diffuse color in materials list
-            if(((*it).second).Kd() == ACG::Vec3f(c[0], c[1], c[2]) &&
-                ((optionColorAlpha && ((*it).second).Tr() == c[3]) || !optionColorAlpha))
-                return (*it).second;
-        } else {
-            // Texture has been found, look for both, matching texture and color
-            QString mKd(((*it).second).map_Kd().c_str());
-            if((((*it).second).Kd() == ACG::Vec3f(c[0], c[1], c[2]) &&
-                ((optionColorAlpha && ((*it).second).Tr() == c[3]) || !optionColorAlpha)) &&
-                (filename == mKd && ((*it).second).map_Kd_index() == texIndex))
-                return (*it).second;
-        }
+  for (MaterialList::iterator it = materials_.begin(); it != materials_.end();
+       ++it) {
+    // No texture has been found
+    if (!hasTexture) {
+      // ... just look for diffuse color in materials list
+      if (((*it).second).Kd() == ACG::Vec3f(c[0], c[1], c[2]) &&
+          ((optionColorAlpha && ((*it).second).Tr() == c[3]) ||
+           !optionColorAlpha))
+        return (*it).second;
+    } else {
+      // Texture has been found, look for both, matching texture and color
+      QString mKd(((*it).second).map_Kd().c_str());
+      if ((((*it).second).Kd() == ACG::Vec3f(c[0], c[1], c[2]) &&
+           ((optionColorAlpha && ((*it).second).Tr() == c[3]) ||
+            !optionColorAlpha)) &&
+          (filename == mKd && ((*it).second).map_Kd_index() == texIndex))
+        return (*it).second;
     }
+  }
 
-    // If not found, add new material(s)
-    Material mat;
-    // Set diffuse color
-    mat.set_Kd(c[0], c[1], c[2]);
-    // Add transparency if available
-    if(optionColorAlpha) mat.set_Tr(c[3]);
-    mat.material_number(materials_.size());
-    // Set texture info
-    if(hasTexture)
-        mat.set_map_Kd(filename.toStdString(), texIndex);
-
-    materials_.insert(std::make_pair(QString("Material%1").arg(mat.material_number()).toStdString(), mat));
-    MaterialList::iterator it = materials_.end();
-    --it;
-    return (*it).second;
+  // If not found, add new material(s)
+  Material mat;
+  // Set diffuse color
+  mat.set_Kd(c[0], c[1], c[2]);
+  // Add transparency if available
+  if (optionColorAlpha) mat.set_Tr(c[3]);
+  mat.material_number(materials_.size());
+  // Set texture info
+  if (hasTexture) mat.set_map_Kd(filename.toStdString(), texIndex);
+
+  materials_.insert(std::make_pair(
+      QString("Material%1").arg(mat.material_number()).toStdString(), mat));
+  MaterialList::iterator it = materials_.end();
+  --it;
+  return (*it).second;
 }
 
-
-
-
 //-----------------------------------------------------------------------------------------------------
 
-template< class MeshT >
-bool FileOBJPlugin::writeMesh(std::ostream& _out, QString _filename, MeshT& _mesh, int _objId){
-
+template <class MeshT>
+bool FileOBJPlugin::writeMesh(std::ostream& _out, QString _filename,
+                              MeshT& _mesh, int _objId) {
   unsigned int i, nV, idx;
   Vec3f v, n;
-  Vec2f t(0.0f,0.0f);
+  Vec2f t(0.0f, 0.0f);
   typename MeshT::VertexHandle vh;
   bool useMaterial = false;
   OpenMesh::Vec4f c;
 
-  bool optionFaceColors      = false;
-  bool optionVertexNormals   = false;
+  bool optionFaceColors = false;
+  bool optionVertexNormals = false;
   bool optionVertexTexCoords = true;
-  bool optionTextures        = false;
-  bool optionCopyTextures    = false;
+  bool optionTextures = false;
+  bool optionCopyTextures = false;
   bool optionCreateTexFolder = false;
 
   QFileInfo fi(_filename);
 
   // check options
-  if ( !OpenFlipper::Options::savingSettings() && saveOptions_ != 0) {
-    optionFaceColors      = saveFaceColor_->isChecked();
-    optionVertexNormals   = saveNormals_->isChecked();
+  if (!OpenFlipper::Options::savingSettings() && saveOptions_ != 0) {
+    optionFaceColors = saveFaceColor_->isChecked();
+    optionVertexNormals = saveNormals_->isChecked();
     optionVertexTexCoords = saveTexCoords_->isChecked();
-    optionTextures        = saveTextures_->isChecked();
-    optionCopyTextures    = saveCopyTextures_->isChecked();
+    optionTextures = saveTextures_->isChecked();
+    optionCopyTextures = saveCopyTextures_->isChecked();
     optionCreateTexFolder = saveCreateTexFolder_->isChecked();
     _out.precision(savePrecision_->value());
   };
   // \TODO Fetch options from ini states if dialog box is not available
 
-  //create material file if needed
-  if ( optionFaceColors || optionTextures ){
-
-    QString matFile = fi.absolutePath() + QDir::separator() + fi.baseName() + ".mtl";
+  // create material file if needed
+  if (optionFaceColors || optionTextures) {
+    QString matFile =
+        fi.absolutePath() + QDir::separator() + fi.baseName() + ".mtl";
 
     useMaterial = writeMaterial(matFile, _mesh, _objId);
   }
@@ -284,7 +284,7 @@ bool FileOBJPlugin::writeMesh(std::ostream& _out, QString _filename, MeshT& _mes
   _out << _mesh.n_faces() << " faces" << '\n';
 
   // Material file
-  if (useMaterial &&  optionFaceColors )
+  if (useMaterial && optionFaceColors)
     _out << "mtllib " << fi.baseName().toStdString() << ".mtl" << '\n';
 
   // Store indices of vertices in a map such that
@@ -294,25 +294,25 @@ bool FileOBJPlugin::writeMesh(std::ostream& _out, QString _filename, MeshT& _mes
 
   int cf = 1;
   // vertex data (point, normals, texcoords)
-  for (i=0, nV=_mesh.n_vertices(); i<nV; ++i)
-  {
+  for (i = 0, nV = _mesh.n_vertices(); i < nV; ++i) {
     vh = typename MeshT::VertexHandle(i);
-    v  = _mesh.point(vh);
-    n  = _mesh.normal(vh);
+    v = _mesh.point(vh);
+    n = _mesh.normal(vh);
 
-    if ( _mesh.has_vertex_texcoords2D() && !_mesh.has_halfedge_texcoords2D() )
-      t  = _mesh.texcoord2D(vh);
+    if (_mesh.has_vertex_texcoords2D() && !_mesh.has_halfedge_texcoords2D())
+      t = _mesh.texcoord2D(vh);
 
     // Write out vertex coordinates
-    _out << "v " << v[0] <<" "<< v[1] <<" "<< v[2] << '\n';
+    _out << "v " << v[0] << " " << v[1] << " " << v[2] << '\n';
 
     // Write out vertex coordinates
-    if ( optionVertexNormals)
-      _out << "vn " << n[0] <<" "<< n[1] <<" "<< n[2] << '\n';
+    if (optionVertexNormals)
+      _out << "vn " << n[0] << " " << n[1] << " " << n[2] << '\n';
 
     // Write out vertex texture coordinates
-    if ( optionVertexTexCoords && _mesh.has_vertex_texcoords2D() && !_mesh.has_halfedge_texcoords2D()) {
-      _out << "vt " << t[0] <<" "<< t[1] << '\n';
+    if (optionVertexTexCoords && _mesh.has_vertex_texcoords2D() &&
+        !_mesh.has_halfedge_texcoords2D()) {
+      _out << "vt " << t[0] << " " << t[1] << '\n';
       vtMapV.insert(std::pair<typename MeshT::VertexHandle, int>(vh, cf));
       cf++;
     }
@@ -328,115 +328,123 @@ bool FileOBJPlugin::writeMesh(std::ostream& _out, QString _filename, MeshT& _mes
   std::map<typename MeshT::HalfedgeHandle, int> vtMap;
 
   // If mesh has halfedge tex coords, write them out instead of vertex texcoords
-  if(optionVertexTexCoords && _mesh.has_halfedge_texcoords2D()) {
-      int count = 1;
-      for ( auto f_it : _mesh.faces() ) {
-          for(fh_it=_mesh.fh_iter(f_it); fh_it.is_valid(); ++fh_it) {
-              typename MeshT::TexCoord2D t = _mesh.texcoord2D(*fh_it);
-              _out << "vt " << t[0] << " " << t[1] << '\n';
-              vtMap.insert(std::pair<typename MeshT::HalfedgeHandle, int>(*fh_it, count));
-              count++;
-          }
+  if (optionVertexTexCoords && _mesh.has_halfedge_texcoords2D()) {
+    int count = 1;
+    for (auto f_it : _mesh.faces()) {
+      for (fh_it = _mesh.fh_iter(f_it); fh_it.is_valid(); ++fh_it) {
+        typename MeshT::TexCoord2D t = _mesh.texcoord2D(*fh_it);
+        _out << "vt " << t[0] << " " << t[1] << '\n';
+        vtMap.insert(
+            std::pair<typename MeshT::HalfedgeHandle, int>(*fh_it, count));
+        count++;
       }
+    }
   }
 
   Material lastMat;
+  lastMat.material_number(std::numeric_limits<unsigned int>::max());
 
   // we do not want to write separators if we only write vertex indices
-  bool vertexOnly =     !(optionVertexTexCoords && _mesh.has_halfedge_texcoords2D())
-                    &&  !(optionVertexTexCoords && !_mesh.has_halfedge_texcoords2D() && _mesh.has_vertex_texcoords2D())
-                    &&  !(optionVertexNormals);
-
-  for ( auto f_it : _mesh.faces() ){
+  bool vertexOnly =
+      !(optionVertexTexCoords && _mesh.has_halfedge_texcoords2D()) &&
+      !(optionVertexTexCoords && !_mesh.has_halfedge_texcoords2D() &&
+        _mesh.has_vertex_texcoords2D()) &&
+      !(optionVertexNormals);
 
+  for (auto f_it : _mesh.faces()) {
     if (useMaterial && optionFaceColors) {
+      Material& material = getMaterial(_mesh, f_it, _objId);
 
-        Material& material = getMaterial(_mesh, f_it, _objId);
-
-        // If we are ina a new material block, specify in the file which material to use
-        if(lastMat.material_number() != material.material_number() ) {
-            _out << "usemtl " << material << '\n';
-            lastMat = material;
-        }
+      // If we are ina a new material block, specify in the file which material
+      // to use
+      if (lastMat.material_number() != material.material_number()) {
+        _out << "usemtl " << material << '\n';
+        lastMat = material;
+      }
     }
 
     _out << "f";
 
     // Write out face information
-    for(fh_it=_mesh.fh_iter(f_it); fh_it.is_valid(); ++fh_it) {
-
-        // Write vertex index
-        idx = _mesh.to_vertex_handle(*fh_it).idx() + 1;
-        _out << " " << idx;
-
-        if (!vertexOnly) {
-
-          // Write separator
-          _out << "/" ;
-
-          if ( optionVertexTexCoords ) {
-            // Write vertex texture coordinate index
-            if ( optionVertexTexCoords && _mesh.has_halfedge_texcoords2D()) {
-              // Refer to halfedge texture coordinates
-              typename std::map<typename MeshT::HalfedgeHandle, int>::iterator it = vtMap.find(*fh_it);
-              if(it != vtMap.end())
-                _out  << (*it).second;
-            } else if (optionVertexTexCoords && !_mesh.has_halfedge_texcoords2D() && _mesh.has_vertex_texcoords2D()) {
-              // Refer to vertex texture coordinates
-              typename std::map<typename MeshT::VertexHandle, int>::iterator it = vtMapV.find(_mesh.to_vertex_handle(*fh_it));
-              if(it != vtMapV.end())
-                _out  << (*it).second;
-            }
+    for (fh_it = _mesh.fh_iter(f_it); fh_it.is_valid(); ++fh_it) {
+      // Write vertex index
+      idx = _mesh.to_vertex_handle(*fh_it).idx() + 1;
+      _out << " " << idx;
+
+      if (!vertexOnly) {
+        // Write separator
+        _out << "/";
+
+        if (optionVertexTexCoords) {
+          // Write vertex texture coordinate index
+          if (optionVertexTexCoords && _mesh.has_halfedge_texcoords2D()) {
+            // Refer to halfedge texture coordinates
+            typename std::map<typename MeshT::HalfedgeHandle, int>::iterator
+                it = vtMap.find(*fh_it);
+            if (it != vtMap.end()) _out << (*it).second;
+          } else if (optionVertexTexCoords &&
+                     !_mesh.has_halfedge_texcoords2D() &&
+                     _mesh.has_vertex_texcoords2D()) {
+            // Refer to vertex texture coordinates
+            typename std::map<typename MeshT::VertexHandle, int>::iterator it =
+                vtMapV.find(_mesh.to_vertex_handle(*fh_it));
+            if (it != vtMapV.end()) _out << (*it).second;
           }
+        }
 
-          // Write vertex normal index
-          if ( optionVertexNormals ) {
-            // Write separator
-            _out << "/" ;
+        // Write vertex normal index
+        if (optionVertexNormals) {
+          // Write separator
+          _out << "/";
 
-            _out << idx;
-          }
+          _out << idx;
         }
+      }
     }
 
     _out << '\n';
   }
 
   // Copy texture files (if demanded)
-  if(optionCopyTextures) {
-      // Only test existence of folder once
-      // (for multiple textures)
-      bool testedOnce = false;
-      for(MaterialList::iterator it = materials_.begin(); it != materials_.end(); ++it) {
-          Material& mat = (*it).second;
-
-          if(!mat.has_Texture()) continue;
-
-          QImage img(mat.map_Kd().c_str());
-          QFileInfo img_f(mat.map_Kd().c_str());
-
-          if(img.isNull()) {
-              // Something happened wrong
-              emit log(LOGERR, tr("An error occurred when trying to copy a texture file."));
-              continue;
+  if (optionCopyTextures) {
+    // Only test existence of folder once
+    // (for multiple textures)
+    bool testedOnce = false;
+    for (MaterialList::iterator it = materials_.begin(); it != materials_.end();
+         ++it) {
+      Material& mat = (*it).second;
+
+      if (!mat.has_Texture()) continue;
+
+      QImage img(mat.map_Kd().c_str());
+      QFileInfo img_f(mat.map_Kd().c_str());
+
+      if (img.isNull()) {
+        // Something happened wrong
+        emit log(LOGERR,
+                 tr("An error occurred when trying to copy a texture file."));
+        continue;
+      } else {
+        if (optionCreateTexFolder) {
+          // Create folder
+          QDir dir(fi.absolutePath());
+          if (!testedOnce && dir.exists(fi.absolutePath() + QDir::separator() +
+                                        fi.baseName() + "_textures")) {
+            emit log(LOGERR, tr("The specified target folder already contains "
+                                "a subfolder called textures. Skipping!"));
+            continue;
           } else {
-              if(optionCreateTexFolder) {
-                  // Create folder
-                  QDir dir(fi.absolutePath());
-                  if(!testedOnce && dir.exists(fi.absolutePath() + QDir::separator() + fi.baseName() + "_textures")) {
-                      emit log(LOGERR, tr("The specified target folder already contains a subfolder called textures. Skipping!"));
-                      continue;
-                  } else {
-                      dir.mkdir(fi.baseName() + "_textures");
-                      img.save(fi.absolutePath() + QDir::separator() + fi.baseName() + "_textures" + QDir::separator() + img_f.fileName());
-                      testedOnce = true;
-                  }
-
-              } else {
-                  img.save(fi.absolutePath() + QDir::separator() + img_f.fileName());
-              }
+            dir.mkdir(fi.baseName() + "_textures");
+            img.save(fi.absolutePath() + QDir::separator() + fi.baseName() +
+                     "_textures" + QDir::separator() + img_f.fileName());
+            testedOnce = true;
           }
+
+        } else {
+          img.save(fi.absolutePath() + QDir::separator() + img_f.fileName());
+        }
       }
+    }
   }
 
   materials_.clear();
@@ -445,7 +453,3 @@ bool FileOBJPlugin::writeMesh(std::ostream& _out, QString _filename, MeshT& _mes
 
   return true;
 }
-
-
-
-
-- 
GitLab