浏览代码

Merge branch 'ov-issue-707'

Kim Kulling 9 年之前
父节点
当前提交
f75b919d42
共有 7 个文件被更改,包括 98 次插入26 次删除
  1. 2 0
      code/ObjFileMtlImporter.cpp
  2. 31 24
      code/ObjFileParser.cpp
  3. 8 0
      code/ObjTools.h
  4. 11 0
      test/models/OBJ/cube_usemtl.mtl
  5. 44 0
      test/models/OBJ/cube_usemtl.obj
  6. 2 2
      test/regression/README.txt
  7. 二进制
      test/regression/db.zip

+ 2 - 0
code/ObjFileMtlImporter.cpp

@@ -284,6 +284,8 @@ void ObjFileMtlImporter::createMaterial()
         }
     }
 
+    name = trim_whitespaces(name);
+
     std::map<std::string, ObjFile::Material*>::iterator it = m_pModel->m_MaterialMap.find( name );
     if ( m_pModel->m_MaterialMap.end() == it) {
         // New Material created

+ 31 - 24
code/ObjFileParser.cpp

@@ -457,15 +457,6 @@ void ObjFileParser::getFace(aiPrimitiveType type)
 //  Get values for a new material description
 void ObjFileParser::getMaterialDesc()
 {
-    // Each material request a new object.
-    // Sometimes the object is already created (see 'o' tag by example), but it is not initialized !
-    // So, we create a new object only if the current on is already initialized !
-    if (m_pModel->m_pCurrent != NULL &&
-        (   m_pModel->m_pCurrent->m_Meshes.size() > 1 ||
-            (m_pModel->m_pCurrent->m_Meshes.size() == 1 && m_pModel->m_Meshes[m_pModel->m_pCurrent->m_Meshes[0]]->m_Faces.size() != 0)  )
-        )
-        m_pModel->m_pCurrent = NULL;
-
     // Get next data for material data
     m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
     if (m_DataIt == m_DataItEnd) {
@@ -477,25 +468,41 @@ void ObjFileParser::getMaterialDesc()
         ++m_DataIt;
     }
 
+    // In some cases we should ignore this 'usemtl' command, this variable helps us to do so
+    bool skip = false;
+
     // Get name
     std::string strName(pStart, &(*m_DataIt));
-    if ( strName.empty())
-        return;
+    strName = trim_whitespaces(strName);
+    if (strName.empty())
+        skip = true;
 
-    // Search for material
-    std::map<std::string, ObjFile::Material*>::iterator it = m_pModel->m_MaterialMap.find( strName );
-    if ( it == m_pModel->m_MaterialMap.end() ) {
-        // Not found, use default material
-        m_pModel->m_pCurrentMaterial = m_pModel->m_pDefaultMaterial;
-        DefaultLogger::get()->error("OBJ: failed to locate material " + strName + ", skipping");
-    } else {
-        // Found, using detected material
-        m_pModel->m_pCurrentMaterial = (*it).second;
-        if ( needsNewMesh( strName ))
+    // If the current mesh has the same material, we simply ignore that 'usemtl' command
+    // There is no need to create another object or even mesh here
+    if (m_pModel->m_pCurrentMaterial && m_pModel->m_pCurrentMaterial->MaterialName == aiString(strName))
+        skip = true;
+
+    if (!skip)
+    {
+        // Search for material
+        std::map<std::string, ObjFile::Material*>::iterator it = m_pModel->m_MaterialMap.find(strName);
+        if (it == m_pModel->m_MaterialMap.end())
+        {
+            // Not found, use default material
+            m_pModel->m_pCurrentMaterial = m_pModel->m_pDefaultMaterial;
+            DefaultLogger::get()->error("OBJ: failed to locate material " + strName + ", skipping");
+            strName = m_pModel->m_pDefaultMaterial->MaterialName.C_Str();
+        }
+        else
         {
-            createMesh( strName  );
+            // Found, using detected material
+            m_pModel->m_pCurrentMaterial = (*it).second;
         }
-        m_pModel->m_pCurrentMesh->m_uiMaterialIndex = getMaterialIndex( strName );
+
+        if (needsNewMesh(strName))
+            createMesh(strName);
+
+        m_pModel->m_pCurrentMesh->m_uiMaterialIndex = getMaterialIndex(strName);
     }
 
     // Skip rest of line
@@ -762,7 +769,7 @@ bool ObjFileParser::needsNewMesh( const std::string &rMaterialName )
     bool newMat = false;
     int matIdx = getMaterialIndex( rMaterialName );
     int curMatIdx = m_pModel->m_pCurrentMesh->m_uiMaterialIndex;
-    if ( curMatIdx != int(ObjFile::Mesh::NoMaterial) || curMatIdx != matIdx )
+    if ( curMatIdx != int(ObjFile::Mesh::NoMaterial) && curMatIdx != matIdx )
     {
         // New material -> only one material per mesh, so we need to create a new
         // material

+ 8 - 0
code/ObjTools.h

@@ -238,6 +238,14 @@ unsigned int tokenize( const string_type& str, std::vector<string_type>& tokens,
     return static_cast<unsigned int>( tokens.size() );
 }
 
+template <class string_type>
+string_type trim_whitespaces(string_type str)
+{
+    while (!str.empty() && IsSpace(str[0])) str.erase(0);
+    while (!str.empty() && IsSpace(str[str.length() - 1])) str.erase(str.length() - 1);
+    return str;
+}
+
 } // Namespace Assimp
 
 #endif // OBJ_TOOLS_H_INC

+ 11 - 0
test/models/OBJ/cube_usemtl.mtl

@@ -0,0 +1,11 @@
+newmtl mtl
+Ka 1.000 1.000 1.000
+Kd 1.000 1.000 1.000
+Ns 200.000
+Ks 0.050 0.050 0.050
+
+newmtl mtl2
+Ka 1.000 1.000 1.000
+Kd 1.000 1.000 1.000
+Ns 16.000
+Ks 0.375 0.375 0.375

+ 44 - 0
test/models/OBJ/cube_usemtl.obj

@@ -0,0 +1,44 @@
+mtllib cube_usemtl.mtl
+ 
+g cube
+ 
+v  0.0  0.0  0.0
+v  0.0  0.0  1.0
+v  0.0  1.0  0.0
+v  0.0  1.0  1.0
+v  1.0  0.0  0.0
+v  1.0  0.0  1.0
+v  1.0  1.0  0.0
+v  1.0  1.0  1.0
+
+vn  0.0  0.0  1.0
+vn  0.0  0.0 -1.0
+vn  0.0  1.0  0.0
+vn  0.0 -1.0  0.0
+vn  1.0  0.0  0.0
+vn -1.0  0.0  0.0
+
+usemtl mtl3
+f  1//2  7//2  5//2
+usemtl mtl3
+f  1//2  3//2  7//2 
+usemtl mtl
+f  1//6  4//6  3//6 
+usemtl mtl
+f  1//6  2//6  4//6 
+usemtl mtl
+f  3//3  8//3  7//3 
+usemtl mtl2
+f  3//3  4//3  8//3 
+usemtl mtl2
+f  5//5  7//5  8//5 
+usemtl mtl2
+f  5//5  8//5  6//5 
+usemtl mtl2
+f  1//4  5//4  6//4 
+usemtl mtl
+f  1//4  6//4  2//4 
+usemtl mtl
+f  2//1  6//1  8//1 
+usemtl mtl
+f  2//1  8//1  4//1 

+ 2 - 2
test/regression/README.txt

@@ -1,5 +1,5 @@
-Assimp Regression Test Suite
-============================
+Asset Importer Lib Regression Test Suite
+========================================
 
 1) How does it work?
 ---------------------------------------------------------------------------------

二进制
test/regression/db.zip