Просмотр исходного кода

Merge branch 'master' into master

Kim Kulling 5 лет назад
Родитель
Сommit
cebb96aa5b
46 измененных файлов с 827 добавлено и 164 удалено
  1. 3 0
      .travis.yml
  2. 5 3
      appveyor.yml
  3. 5 5
      code/Assjson/cencode.c
  4. 1 1
      code/CSM/CSMLoader.cpp
  5. 1 1
      code/FBX/FBXConverter.cpp
  6. 2 2
      code/MDL/HalfLife/HL1MDLLoader.cpp
  7. 91 80
      code/MDL/MDLLoader.cpp
  8. 3 3
      code/MDL/MDLMaterialLoader.cpp
  9. 1 1
      code/Material/MaterialSystem.cpp
  10. 1 1
      code/Q3BSP/Q3BSPFileImporter.cpp
  11. 1 1
      code/SMD/SMDLoader.cpp
  12. 1 1
      code/Unreal/UnrealLoader.cpp
  13. 1 1
      code/X/XFileImporter.cpp
  14. 3 1
      code/glTF/glTFAsset.inl
  15. 4 5
      code/glTF/glTFExporter.cpp
  16. 1 1
      code/glTF/glTFExporter.h
  17. 5 2
      code/glTF2/glTF2Asset.inl
  18. 2 4
      code/glTF2/glTF2Exporter.cpp
  19. 3 0
      test/CMakeLists.txt
  20. BIN
      test/models-nonbsd/3DS/pyramob.3DS
  21. BIN
      test/models-nonbsd/FBX/2013_BINARY/Granate.fbx
  22. BIN
      test/models-nonbsd/FBX/2013_BINARY/duck.fbx
  23. BIN
      test/models-nonbsd/FBX/2013_BINARY/jeep1.fbx
  24. BIN
      test/models-nonbsd/FBX/2013_BINARY/kwxport_test_vcolors.fbx
  25. BIN
      test/models-nonbsd/FBX/2013_BINARY/mar_rifle.fbx
  26. BIN
      test/models-nonbsd/FBX/2013_BINARY/pyramob.fbx
  27. BIN
      test/models-nonbsd/HMP/terrain_withtexture.hmp
  28. BIN
      test/models-nonbsd/LWO/LWO2/LWSReferences/QuickDraw--Chasis.lwo
  29. BIN
      test/models/COB/dwarf.cob
  30. BIN
      test/models/MS3D/Wuson.ms3d
  31. BIN
      test/models/Q3D/WusonOrange.q3o
  32. BIN
      test/models/Q3D/WusonOrange.q3s
  33. BIN
      test/models/STL/3DSMaxExport.STL
  34. BIN
      test/models/TER/RealisticTerrain_Large.ter
  35. BIN
      test/models/X/fromtruespace_bin32.x
  36. BIN
      test/models/XGL/Spider_ascii.zgl
  37. BIN
      test/models/glTF2/BoxTextured-glTF-Binary/BoxTextured.glb
  38. 58 12
      test/unit/ImportExport/utCOBImportExport.cpp
  39. 87 0
      test/unit/ImportExport/utMD2Importer.cpp
  40. 73 0
      test/unit/ImportExport/utMD3Importer.cpp
  41. 80 0
      test/unit/ImportExport/utMD5Importer.cpp
  42. 55 13
      test/unit/ImportExport/utXGLImportExport.cpp
  43. 20 13
      test/unit/ut3DImportExport.cpp
  44. 71 13
      test/unit/utACImportExport.cpp
  45. 172 0
      test/unit/utBlenderImportExport.cpp
  46. 77 0
      test/unit/utXImporterExporter.cpp

+ 3 - 0
.travis.yml

@@ -30,6 +30,9 @@ env:
     - secure: "lZ7pHQvl5dpZWzBQAaIMf0wqrvtcZ4wiZKeIZjf83TEsflW8+z0uTpIuN30ZV6Glth/Sq1OhLnTP5+N57fZU/1ebA5twHdvP4bS5CIUUg71/CXQZNl36xeaqvxsG/xRrdpKOsPdjAOsQ9KPTQulsX43XDLS7CasMiLvYOpqKcPc="
     - PV=r8e PLATF=linux-x86_64 NDK_HOME=${TRAVIS_BUILD_DIR}/android-ndk-${PV} PATH=${PATH}:${NDK_HOME}
 
+git:
+  depth: 1
+
 matrix:
   include:
     - os: linux

+ 5 - 3
appveyor.yml

@@ -4,6 +4,8 @@
 # clone directory
 clone_folder: c:\projects\assimp
 
+clone_depth: 1
+
 # branches to build
 branches:
   # whitelist
@@ -52,11 +54,11 @@ cache:
   - bin\.mtime_cache
   
 before_build:
+  - echo NUMBER_OF_PROCESSORS=%NUMBER_OF_PROCESSORS%
   - ruby scripts\AppVeyor\mtime_cache -g scripts\AppVeyor\cacheglobs.txt -c bin\.mtime_cache\cache.json
   
-build:
-  parallel: true
-  project: Assimp.sln
+build_script:
+  cmake --build . --config Release -- /maxcpucount:2
   
 after_build:
   - if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2017" (

+ 5 - 5
code/Assjson/cencode.c

@@ -42,7 +42,7 @@ int base64_encode_block(const char* plaintext_in, int length_in, char* code_out,
 			{
 				state_in->result = result;
 				state_in->step = step_A;
-				return codechar - code_out;
+				return (int)(codechar - code_out);
 			}
 			fragment = *plainchar++;
 			result = (fragment & 0x0fc) >> 2;
@@ -53,7 +53,7 @@ int base64_encode_block(const char* plaintext_in, int length_in, char* code_out,
 			{
 				state_in->result = result;
 				state_in->step = step_B;
-				return codechar - code_out;
+				return (int)(codechar - code_out);
 			}
 			fragment = *plainchar++;
 			result |= (fragment & 0x0f0) >> 4;
@@ -64,7 +64,7 @@ int base64_encode_block(const char* plaintext_in, int length_in, char* code_out,
 			{
 				state_in->result = result;
 				state_in->step = step_C;
-				return codechar - code_out;
+				return (int)(codechar - code_out);
 			}
 			fragment = *plainchar++;
 			result |= (fragment & 0x0c0) >> 6;
@@ -81,7 +81,7 @@ int base64_encode_block(const char* plaintext_in, int length_in, char* code_out,
 		}
 	}
 	/* control should not reach here */
-	return codechar - code_out;
+	return (int)(codechar - code_out);
 }
 
 int base64_encode_blockend(char* code_out, base64_encodestate* state_in)
@@ -104,6 +104,6 @@ int base64_encode_blockend(char* code_out, base64_encodestate* state_in)
 	}
 	*codechar++ = '\n';
 	
-	return codechar - code_out;
+	return (int)(codechar - code_out);
 }
 

+ 1 - 1
code/CSM/CSMLoader.cpp

@@ -178,7 +178,7 @@ void CSMImporter::InternReadFile( const std::string& pFile,
                         *ot++ = *buffer++;
 
                     *ot = '\0';
-                    nda->mNodeName.length = (size_t)(ot-nda->mNodeName.data);
+                    nda->mNodeName.length = (ai_uint32)(ot-nda->mNodeName.data);
                 }
 
                 anim->mNumChannels = static_cast<unsigned int>(anims_temp.size());

+ 1 - 1
code/FBX/FBXConverter.cpp

@@ -1564,7 +1564,7 @@ namespace Assimp {
 
                 bone_map.clear();
             }
-            catch (std::exception&e) {
+            catch (std::exception&) {
                 std::for_each(bones.begin(), bones.end(), Util::delete_fun<aiBone>());
                 throw;
             }

+ 2 - 2
code/MDL/HalfLife/HL1MDLLoader.cpp

@@ -175,9 +175,9 @@ void HL1MDLLoader::load_file() {
 
         release_resources();
 
-    } catch (const std::exception &e) {
+    } catch (...) {
         release_resources();
-        throw e;
+        throw;
     }
 }
 

+ 91 - 80
code/MDL/MDLLoader.cpp

@@ -179,93 +179,104 @@ void MDLImporter::InternReadFile( const std::string& pFile,
     }
 
     // This should work for all other types of MDL files, too ...
-    // the quake header is one of the smallest, afaik
+    // the HL1 sequence group header is one of the smallest, afaik
     iFileSize = (unsigned int)file->FileSize();
-    if( iFileSize < sizeof(MDL::Header)) {
+    if( iFileSize < sizeof(MDL::HalfLife::SequenceHeader_HL1)) {
         throw DeadlyImportError( "MDL File is too small.");
     }
-
-    // Allocate storage and copy the contents of the file to a memory buffer
-    mBuffer =new unsigned char[iFileSize+1];
-    file->Read( (void*)mBuffer, 1, iFileSize);
-
-    // Append a binary zero to the end of the buffer.
-    // this is just for safety that string parsing routines
-    // find the end of the buffer ...
-    mBuffer[iFileSize] = '\0';
-    const uint32_t iMagicWord = *((uint32_t*)mBuffer);
-
-    // Determine the file subtype and call the appropriate member function
-
-    // Original Quake1 format
-    if (AI_MDL_MAGIC_NUMBER_BE == iMagicWord || AI_MDL_MAGIC_NUMBER_LE == iMagicWord)   {
-        ASSIMP_LOG_DEBUG("MDL subtype: Quake 1, magic word is IDPO");
-        iGSFileVersion = 0;
-        InternReadFile_Quake1();
-    }
-    // GameStudio A<old> MDL2 format - used by some test models that come with 3DGS
-    else if (AI_MDL_MAGIC_NUMBER_BE_GS3 == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS3 == iMagicWord)  {
-        ASSIMP_LOG_DEBUG("MDL subtype: 3D GameStudio A2, magic word is MDL2");
-        iGSFileVersion = 2;
-        InternReadFile_Quake1();
-    }
-    // GameStudio A4 MDL3 format
-    else if (AI_MDL_MAGIC_NUMBER_BE_GS4 == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS4 == iMagicWord)  {
-        ASSIMP_LOG_DEBUG("MDL subtype: 3D GameStudio A4, magic word is MDL3");
-        iGSFileVersion = 3;
-        InternReadFile_3DGS_MDL345();
-    }
-    // GameStudio A5+ MDL4 format
-    else if (AI_MDL_MAGIC_NUMBER_BE_GS5a == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS5a == iMagicWord)    {
-        ASSIMP_LOG_DEBUG("MDL subtype: 3D GameStudio A4, magic word is MDL4");
-        iGSFileVersion = 4;
-        InternReadFile_3DGS_MDL345();
-    }
-    // GameStudio A5+ MDL5 format
-    else if (AI_MDL_MAGIC_NUMBER_BE_GS5b == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS5b == iMagicWord)    {
-        ASSIMP_LOG_DEBUG("MDL subtype: 3D GameStudio A5, magic word is MDL5");
-        iGSFileVersion = 5;
-        InternReadFile_3DGS_MDL345();
-    }
-    // GameStudio A7 MDL7 format
-    else if (AI_MDL_MAGIC_NUMBER_BE_GS7 == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS7 == iMagicWord)  {
-        ASSIMP_LOG_DEBUG("MDL subtype: 3D GameStudio A7, magic word is MDL7");
-        iGSFileVersion = 7;
-        InternReadFile_3DGS_MDL7();
-    }
-    // IDST/IDSQ Format (CS:S/HL^2, etc ...)
-    else if (AI_MDL_MAGIC_NUMBER_BE_HL2a == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_HL2a == iMagicWord ||
-        AI_MDL_MAGIC_NUMBER_BE_HL2b == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_HL2b == iMagicWord)
-    {
-        iGSFileVersion = 0;
-
-        HalfLife::HalfLifeMDLBaseHeader *pHeader = (HalfLife::HalfLifeMDLBaseHeader *)mBuffer;
-        if (pHeader->version == AI_MDL_HL1_VERSION)
-        {
-            ASSIMP_LOG_DEBUG("MDL subtype: Half-Life 1/Goldsrc Engine, magic word is IDST/IDSQ");
-            InternReadFile_HL1(pFile, iMagicWord);
+    
+    // delete the file buffer and cleanup.
+    auto DeleteBufferAndCleanup = [&]() {
+        if (mBuffer) {
+            delete [] mBuffer;
+            mBuffer = nullptr;
+        }
+        AI_DEBUG_INVALIDATE_PTR(pIOHandler);
+        AI_DEBUG_INVALIDATE_PTR(pScene);
+    };
+    
+    try {
+        // Allocate storage and copy the contents of the file to a memory buffer
+        mBuffer = new unsigned char[iFileSize+1];
+        file->Read( (void*)mBuffer, 1, iFileSize);
+
+        // Append a binary zero to the end of the buffer.
+        // this is just for safety that string parsing routines
+        // find the end of the buffer ...
+        mBuffer[iFileSize] = '\0';
+        const uint32_t iMagicWord = *((uint32_t*)mBuffer);
+
+        // Determine the file subtype and call the appropriate member function
+
+        // Original Quake1 format
+        if (AI_MDL_MAGIC_NUMBER_BE == iMagicWord || AI_MDL_MAGIC_NUMBER_LE == iMagicWord)   {
+            ASSIMP_LOG_DEBUG("MDL subtype: Quake 1, magic word is IDPO");
+            iGSFileVersion = 0;
+            InternReadFile_Quake1();
+        }
+        // GameStudio A<old> MDL2 format - used by some test models that come with 3DGS
+        else if (AI_MDL_MAGIC_NUMBER_BE_GS3 == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS3 == iMagicWord)  {
+            ASSIMP_LOG_DEBUG("MDL subtype: 3D GameStudio A2, magic word is MDL2");
+            iGSFileVersion = 2;
+            InternReadFile_Quake1();
         }
-        else
+        // GameStudio A4 MDL3 format
+        else if (AI_MDL_MAGIC_NUMBER_BE_GS4 == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS4 == iMagicWord)  {
+            ASSIMP_LOG_DEBUG("MDL subtype: 3D GameStudio A4, magic word is MDL3");
+            iGSFileVersion = 3;
+            InternReadFile_3DGS_MDL345();
+        }
+        // GameStudio A5+ MDL4 format
+        else if (AI_MDL_MAGIC_NUMBER_BE_GS5a == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS5a == iMagicWord)    {
+            ASSIMP_LOG_DEBUG("MDL subtype: 3D GameStudio A4, magic word is MDL4");
+            iGSFileVersion = 4;
+            InternReadFile_3DGS_MDL345();
+        }
+        // GameStudio A5+ MDL5 format
+        else if (AI_MDL_MAGIC_NUMBER_BE_GS5b == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS5b == iMagicWord)    {
+            ASSIMP_LOG_DEBUG("MDL subtype: 3D GameStudio A5, magic word is MDL5");
+            iGSFileVersion = 5;
+            InternReadFile_3DGS_MDL345();
+        }
+        // GameStudio A7 MDL7 format
+        else if (AI_MDL_MAGIC_NUMBER_BE_GS7 == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS7 == iMagicWord)  {
+            ASSIMP_LOG_DEBUG("MDL subtype: 3D GameStudio A7, magic word is MDL7");
+            iGSFileVersion = 7;
+            InternReadFile_3DGS_MDL7();
+        }
+        // IDST/IDSQ Format (CS:S/HL^2, etc ...)
+        else if (AI_MDL_MAGIC_NUMBER_BE_HL2a == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_HL2a == iMagicWord ||
+            AI_MDL_MAGIC_NUMBER_BE_HL2b == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_HL2b == iMagicWord)
         {
-            ASSIMP_LOG_DEBUG("MDL subtype: Source(tm) Engine, magic word is IDST/IDSQ");
-            InternReadFile_HL2();
+            iGSFileVersion = 0;
+
+            HalfLife::HalfLifeMDLBaseHeader *pHeader = (HalfLife::HalfLifeMDLBaseHeader *)mBuffer;
+            if (pHeader->version == AI_MDL_HL1_VERSION)
+            {
+                ASSIMP_LOG_DEBUG("MDL subtype: Half-Life 1/Goldsrc Engine, magic word is IDST/IDSQ");
+                InternReadFile_HL1(pFile, iMagicWord);
+            }
+            else
+            {
+                ASSIMP_LOG_DEBUG("MDL subtype: Source(tm) Engine, magic word is IDST/IDSQ");
+                InternReadFile_HL2();
+            }
+        }
+        else {
+            // print the magic word to the log file
+            throw DeadlyImportError( "Unknown MDL subformat " + pFile +
+                ". Magic word (" + std::string((char*)&iMagicWord,4) + ") is not known");
         }
-    }
-    else    {
-        // print the magic word to the log file
-        throw DeadlyImportError( "Unknown MDL subformat " + pFile +
-            ". Magic word (" + std::string((char*)&iMagicWord,4) + ") is not known");
-    }
 
-    // Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system
-    pScene->mRootNode->mTransformation = aiMatrix4x4(1.f,0.f,0.f,0.f,
-        0.f,0.f,1.f,0.f,0.f,-1.f,0.f,0.f,0.f,0.f,0.f,1.f);
+        // Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system
+        pScene->mRootNode->mTransformation = aiMatrix4x4(1.f,0.f,0.f,0.f,
+            0.f,0.f,1.f,0.f,0.f,-1.f,0.f,0.f,0.f,0.f,0.f,1.f);
 
-    // delete the file buffer and cleanup
-    delete [] mBuffer;
-    mBuffer= nullptr;
-    AI_DEBUG_INVALIDATE_PTR(pIOHandler);
-    AI_DEBUG_INVALIDATE_PTR(pScene);
+        DeleteBufferAndCleanup();
+    } catch(...) {
+        DeleteBufferAndCleanup();
+        throw;
+    }
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -1575,7 +1586,7 @@ void MDLImporter::InternReadFile_3DGS_MDL7( )
 				const size_t maxSize(buffersize - (i*AI_MDL7_MAX_GROUPNAMESIZE));
 				pcNode->mName.length = ai_snprintf(szBuffer, maxSize, "Group_%u", p);
 			} else {
-				pcNode->mName.length = ::strlen(szBuffer);
+				pcNode->mName.length = (ai_uint32)::strlen(szBuffer);
 			}
             ::strncpy(pcNode->mName.data,szBuffer,MAXLEN-1);
             ++p;

+ 3 - 3
code/MDL/MDLMaterialLoader.cpp

@@ -541,7 +541,7 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
         size_t iLen2 = iLen+1;
         iLen2 = iLen2 > MAXLEN ? MAXLEN : iLen2;
         memcpy(szFile.data,(const char*)szCurrent,iLen2);
-        szFile.length = iLen;
+        szFile.length = (ai_uint32)iLen;
 
         szCurrent += iLen2;
 
@@ -710,7 +710,7 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
         aiString szFile;
         const size_t iLen = strlen((const char*)szCurrent);
         ::memcpy(szFile.data,(const char*)szCurrent,iLen+1);
-        szFile.length = iLen;
+        szFile.length = (ai_uint32)iLen;
 
         pcMatOut->AddProperty(&szFile,AI_MATKEY_TEXTURE_DIFFUSE(0));
 
@@ -831,7 +831,7 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
         aiString szFile;
         ::memcpy(szFile.data,pcSkin->texture_name,sizeof(pcSkin->texture_name));
         szFile.data[sizeof(pcSkin->texture_name)] = '\0';
-        szFile.length = ::strlen(szFile.data);
+        szFile.length = (ai_uint32)::strlen(szFile.data);
 
         pcMatOut->AddProperty(&szFile,AI_MATKEY_NAME);
     }

+ 1 - 1
code/Material/MaterialSystem.cpp

@@ -504,7 +504,7 @@ aiReturn aiMaterial::AddBinaryProperty (const void* pInput,
     pcNew->mData = new char[pSizeInBytes];
     memcpy (pcNew->mData,pInput,pSizeInBytes);
 
-    pcNew->mKey.length = ::strlen(pKey);
+    pcNew->mKey.length = (ai_uint32)::strlen(pKey);
     ai_assert ( MAXLEN > pcNew->mKey.length);
     strcpy( pcNew->mKey.data, pKey );
 

+ 1 - 1
code/Q3BSP/Q3BSPFileImporter.cpp

@@ -616,7 +616,7 @@ bool Q3BSPFileImporter::importTextureFromArchive( const Q3BSP::Q3BSPModel *model
             // We'll leave it up to the user to figure out which extension the file has.
             aiString name;
             strncpy( name.data, pTexture->strName, sizeof name.data );
-            name.length = strlen( name.data );
+            name.length = (ai_uint32)strlen( name.data );
             pMatHelper->AddProperty( &name, AI_MATKEY_TEXTURE_DIFFUSE( 0 ) );
         }
     }

+ 1 - 1
code/SMD/SMDLoader.cpp

@@ -616,7 +616,7 @@ void SMDImporter::CreateOutputMaterials() {
         if (aszTextures[iMat].length())
         {
             ::strncpy(szName.data, aszTextures[iMat].c_str(),MAXLEN-1);
-            szName.length = aszTextures[iMat].length();
+            szName.length = (ai_uint32)aszTextures[iMat].length();
             pcMat->AddProperty(&szName,AI_MATKEY_TEXTURE_DIFFUSE(0));
         }
     }

+ 1 - 1
code/Unreal/UnrealLoader.cpp

@@ -403,7 +403,7 @@ void UnrealImporter::InternReadFile( const std::string& pFile,
 
         // set color and name
         mat->AddProperty(&color,1,AI_MATKEY_COLOR_DIFFUSE);
-        s.length = ::strlen(s.data);
+        s.length = (ai_uint32)::strlen(s.data);
         mat->AddProperty(&s,AI_MATKEY_NAME);
 
         // set texture, if any

+ 1 - 1
code/X/XFileImporter.cpp

@@ -211,7 +211,7 @@ aiNode* XFileImporter::CreateNodes( aiScene* pScene, aiNode* pParent, const XFil
 
     // create node
     aiNode* node = new aiNode;
-    node->mName.length = pNode->mName.length();
+    node->mName.length = (ai_uint32)pNode->mName.length();
     node->mParent = pParent;
     memcpy( node->mName.data, pNode->mName.c_str(), pNode->mName.length());
     node->mName.data[node->mName.length] = 0;

+ 3 - 1
code/glTF/glTFAsset.inl

@@ -688,7 +688,9 @@ inline void Image::SetData(uint8_t* data, size_t length, Asset& r)
         bufferView->byteOffset = b->AppendData(data, length);
     }
     else { // text file: will be stored as a data uri
-        this->mData.reset(data);
+        uint8_t *temp = new uint8_t[length];
+        memcpy(temp, data, length);
+        this->mData.reset(temp);
         this->mDataLength = length;
     }
 }

+ 4 - 5
code/glTF/glTFExporter.cpp

@@ -100,17 +100,16 @@ glTFExporter::glTFExporter(const char* filename, IOSystem* pIOSystem, const aiSc
 {
     aiScene* sceneCopy_tmp;
     SceneCombiner::CopyScene(&sceneCopy_tmp, pScene);
-    aiScene *sceneCopy(sceneCopy_tmp);
 
     SplitLargeMeshesProcess_Triangle tri_splitter;
     tri_splitter.SetLimit(0xffff);
-    tri_splitter.Execute(sceneCopy);
+    tri_splitter.Execute(sceneCopy_tmp);
 
     SplitLargeMeshesProcess_Vertex vert_splitter;
     vert_splitter.SetLimit(0xffff);
-    vert_splitter.Execute(sceneCopy);
+    vert_splitter.Execute(sceneCopy_tmp);
 
-    mScene = sceneCopy;
+    mScene.reset(sceneCopy_tmp);
 
     mAsset.reset( new glTF::Asset( pIOSystem ) );
 
@@ -877,7 +876,7 @@ void glTFExporter::ExportMetadata()
 
 	// Copyright
 	aiString copyright_str;
-	if (mScene->mMetaData->Get(AI_METADATA_SOURCE_COPYRIGHT, copyright_str)) {
+	if (mScene->mMetaData != nullptr && mScene->mMetaData->Get(AI_METADATA_SOURCE_COPYRIGHT, copyright_str)) {
 		asset.copyright = copyright_str.C_Str();
 	}
 }

+ 1 - 1
code/glTF/glTFExporter.h

@@ -90,7 +90,7 @@ namespace Assimp
 
         const char* mFilename;
         IOSystem* mIOSystem;
-        const aiScene* mScene;
+        std::shared_ptr<const aiScene> mScene;
         const ExportProperties* mProperties;
 
         std::map<std::string, unsigned int> mTexturesByPath;

+ 5 - 2
code/glTF2/glTF2Asset.inl

@@ -752,6 +752,7 @@ inline uint8_t* Image::StealData()
 	return mData.release();
 }
 
+// Never take over the ownership of data whenever binary or not
 inline void Image::SetData(uint8_t* data, size_t length, Asset& r)
 {
     Ref<Buffer> b = r.GetBodyBuffer();
@@ -764,8 +765,10 @@ inline void Image::SetData(uint8_t* data, size_t length, Asset& r)
         bufferView->byteOffset = b->AppendData(data, length);
     }
     else { // text file: will be stored as a data uri
-		this->mData.reset(data);
-		this->mDataLength = length;
+        uint8_t *temp = new uint8_t[length];
+        memcpy(temp, data, length);
+        this->mData.reset(temp);
+        this->mDataLength = length;
     }
 }
 

+ 2 - 4
code/glTF2/glTF2Exporter.cpp

@@ -352,10 +352,8 @@ void glTF2Exporter::GetMatTex(const aiMaterial* mat, Ref<Texture>& texture, aiTe
                     if (path[0] == '*') { // embedded
                         aiTexture* tex = mScene->mTextures[atoi(&path[1])];
 
-                        // copy data since lifetime control is handed over to the asset
-                        uint8_t* data = new uint8_t[tex->mWidth];
-                        memcpy(data, tex->pcData, tex->mWidth);
-                        texture->source->SetData(data, tex->mWidth, *mAsset);
+                        // The asset has its own buffer, see Image::SetData
+                        texture->source->SetData(reinterpret_cast<uint8_t*> (tex->pcData), tex->mWidth, *mAsset);
 
                         if (tex->achFormatHint[0]) {
                             std::string mimeType = "image/";

+ 3 - 0
test/CMakeLists.txt

@@ -128,6 +128,9 @@ SET( IMPORTERS
   unit/ImportExport/utOFFImportExport.cpp
   unit/ImportExport/utNFFImportExport.cpp
   unit/ImportExport/utXGLImportExport.cpp
+  unit/ImportExport/utMD2Importer.cpp
+  unit/ImportExport/utMD3Importer.cpp
+  unit/ImportExport/utMD5Importer.cpp
   unit/ImportExport/utMDLImporter.cpp
   unit/ImportExport/MDL/MDLHL1TestFiles.h
   unit/ImportExport/MDL/utMDLImporter_HL1_ImportSettings.cpp

BIN
test/models-nonbsd/3DS/pyramob.3DS


BIN
test/models-nonbsd/FBX/2013_BINARY/Granate.fbx


BIN
test/models-nonbsd/FBX/2013_BINARY/duck.fbx


BIN
test/models-nonbsd/FBX/2013_BINARY/jeep1.fbx


BIN
test/models-nonbsd/FBX/2013_BINARY/kwxport_test_vcolors.fbx


BIN
test/models-nonbsd/FBX/2013_BINARY/mar_rifle.fbx


BIN
test/models-nonbsd/FBX/2013_BINARY/pyramob.fbx


BIN
test/models-nonbsd/HMP/terrain_withtexture.hmp


BIN
test/models-nonbsd/LWO/LWO2/LWSReferences/QuickDraw--Chasis.lwo


BIN
test/models/COB/dwarf.cob


BIN
test/models/MS3D/Wuson.ms3d


BIN
test/models/Q3D/WusonOrange.q3o


BIN
test/models/Q3D/WusonOrange.q3s


BIN
test/models/STL/3DSMaxExport.STL


BIN
test/models/TER/RealisticTerrain_Large.ter


BIN
test/models/X/fromtruespace_bin32.x


BIN
test/models/XGL/Spider_ascii.zgl


BIN
test/models/glTF2/BoxTextured-glTF-Binary/BoxTextured.glb


+ 58 - 12
test/unit/ImportExport/utCOBImportExport.cpp

@@ -43,22 +43,68 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include "UnitTestPCH.h"
 #include "SceneDiffer.h"
-#include "AbstractImportExportBase.h"
 
 #include <assimp/Importer.hpp>
 #include <assimp/postprocess.h>
 
 using namespace Assimp;
 
-class utCOBImportExport : public AbstractImportExportBase {
-public:
-    virtual bool importerTest() {
-        Assimp::Importer importer;
-        const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/COB/molecule.cob", aiProcess_ValidateDataStructure);
-        return nullptr != scene;
-    }
-};
-
-TEST_F(utCOBImportExport, importAMFFromFileTest) {
-    EXPECT_TRUE(importerTest());
+
+TEST(utCOBImporter, importDwarfASCII) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/COB/dwarf_ascii.cob", aiProcess_ValidateDataStructure);
+    // FIXME: this is wrong, it should succeed
+    // change to ASSERT_NE after it's been fixed
+    ASSERT_EQ(nullptr, scene);
+}
+
+
+TEST(utCOBImporter, importDwarf) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/COB/dwarf.cob", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(utCOBImporter, importMoleculeASCII) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/COB/molecule_ascii.cob", aiProcess_ValidateDataStructure);
+    // FIXME: this is wrong, it should succeed
+    // change to ASSERT_NE after it's been fixed
+    ASSERT_EQ(nullptr, scene);
+}
+
+
+TEST(utCOBImporter, importMolecule) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/COB/molecule.cob", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(utCOBImporter, importSpider43ASCII) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/COB/spider_4_3_ascii.cob", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(utCOBImporter, importSpider43) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/COB/spider_4_3.cob", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(utCOBImporter, importSpider66ASCII) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/COB/spider_6_6_ascii.cob", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(utCOBImporter, importSpider66) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/COB/spider_6_6.cob", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
 }

+ 87 - 0
test/unit/ImportExport/utMD2Importer.cpp

@@ -0,0 +1,87 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2020, assimp team
+
+
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+* Redistributions of source code must retain the above
+copyright notice, this list of conditions and the
+following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the
+following disclaimer in the documentation and/or other
+materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+contributors may be used to endorse or promote products
+derived from this software without specific prior
+written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
+*/
+
+#include "UnitTestPCH.h"
+
+#include <assimp/postprocess.h>
+#include <assimp/scene.h>
+#include <assimp/Importer.hpp>
+
+
+using namespace Assimp;
+
+
+
+TEST(utMD2Importer, importFaerie) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/MD2/faerie.md2", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(utMD2Importer, importSydney) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/MD2/sydney.md2", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(utMD2Importer, importDolphin) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_NONBSD_DIR "/MD2/dolphin.md2", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(utMD2Importer, importFlag) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_NONBSD_DIR "/MD2/flag.md2", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(utMD2Importer, importHorse) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_NONBSD_DIR "/MD2/horse.md2", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}

+ 73 - 0
test/unit/ImportExport/utMD3Importer.cpp

@@ -0,0 +1,73 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2020, assimp team
+
+
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+* Redistributions of source code must retain the above
+copyright notice, this list of conditions and the
+following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the
+following disclaimer in the documentation and/or other
+materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+contributors may be used to endorse or promote products
+derived from this software without specific prior
+written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
+*/
+
+#include "UnitTestPCH.h"
+
+#include <assimp/postprocess.h>
+#include <assimp/scene.h>
+#include <assimp/Importer.hpp>
+
+
+using namespace Assimp;
+
+
+
+TEST(utMD3Importer, importWatercan) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_NONBSD_DIR "/MD3/watercan.md3", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(utMD3Importer, importWatercan_dmg) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_NONBSD_DIR "/MD3/watercan_dmg.md3", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(utMD3Importer, importEuropean_fnt_v2) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_NONBSD_DIR "/MD3/q3root/models/mapobjects/kt_kubalwagon/european_fnt_v2.md3", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}

+ 80 - 0
test/unit/ImportExport/utMD5Importer.cpp

@@ -0,0 +1,80 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2020, assimp team
+
+
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+* Redistributions of source code must retain the above
+copyright notice, this list of conditions and the
+following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the
+following disclaimer in the documentation and/or other
+materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+contributors may be used to endorse or promote products
+derived from this software without specific prior
+written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
+*/
+
+#include "UnitTestPCH.h"
+
+#include <assimp/postprocess.h>
+#include <assimp/scene.h>
+#include <assimp/Importer.hpp>
+
+
+using namespace Assimp;
+
+
+
+TEST(utMD5Importer, importEmpty) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/MD5/invalid/empty.md5mesh", aiProcess_ValidateDataStructure);
+    ASSERT_EQ(nullptr, scene);
+}
+
+
+TEST(utMD5Importer, importSimpleCube) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/MD5/SimpleCube.md5mesh", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(utMD5Importer, importBoarMan) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_NONBSD_DIR "/MD5/BoarMan.md5mesh", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(utMD5Importer, importBob) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_NONBSD_DIR "/MD5/Bob.md5mesh", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}

+ 55 - 13
test/unit/ImportExport/utXGLImportExport.cpp

@@ -42,22 +42,64 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
 #include "UnitTestPCH.h"
-#include "AbstractImportExportBase.h"
 #include <assimp/Importer.hpp>
 #include <assimp/postprocess.h>
 
+
 using namespace Assimp;
 
-class utXGLImportExport : public AbstractImportExportBase {
-public:
-    virtual bool importerTest() {
-        Assimp::Importer importer;
-        const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/XGL/sample_official.xgl", 0);
-        return true;
-        return nullptr != scene;
-    }
-};
-
-TEST_F(utXGLImportExport, importXGLFromFileTest) {
-    EXPECT_TRUE(importerTest());
+
+TEST(utXGLImporter, importBCN_Epileptic) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/XGL/BCN_Epileptic.zgl", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(utXGLImporter, importCubesWithAlpha) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/XGL/cubes_with_alpha.zgl", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(utXGLImporter, importSample_official) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/XGL/sample_official.xgl", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(utXGLImporter, importSample_official_asxml) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/XGL/sample_official_asxml.xml", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(utXGLImporter, importSphereWithMatGloss) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/XGL/sphere_with_mat_gloss_10pc.zgl", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(utXGLImporter, importSpiderASCII) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/XGL/Spider_ascii.zgl", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(utXGLImporter, importWuson) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/XGL/Wuson.zgl", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(utXGLImporter, importWusonDXF) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/XGL/wuson_dxf.zgl", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
 }

+ 20 - 13
test/unit/ut3DImportExport.cpp

@@ -42,23 +42,30 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
 #include "UnitTestPCH.h"
-#include "SceneDiffer.h"
-#include "AbstractImportExportBase.h"
 
 #include <assimp/Importer.hpp>
 #include <assimp/postprocess.h>
 
+
 using namespace Assimp;
 
-class ut3DImportExport : public AbstractImportExportBase {
-public:
-    virtual bool importerTest() {
-        Assimp::Importer importer;
-        const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/3D/box_a.3d", aiProcess_ValidateDataStructure );
-        return nullptr != scene;
-    }
-};
-
-TEST_F( ut3DImportExport, import3DFromFileTest ) {
-    EXPECT_TRUE( importerTest() );
+
+TEST(ut3DImportExport, importBoxA) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/3D/box_a.3d", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(ut3DImportExport, importBoxD) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/3D/box_d.3d", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(ut3DImportExport, importBoxUC) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/3D/box.uc", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
 }

+ 71 - 13
test/unit/utACImportExport.cpp

@@ -42,23 +42,81 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
 #include "UnitTestPCH.h"
-#include "SceneDiffer.h"
-#include "AbstractImportExportBase.h"
 
 #include <assimp/Importer.hpp>
 #include <assimp/postprocess.h>
 
+
 using namespace Assimp;
 
-class utACImportExport : public AbstractImportExportBase {
-public:
-    virtual bool importerTest() {
-        Assimp::Importer importer;
-        const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/AC/Wuson.ac", aiProcess_ValidateDataStructure );
-        return nullptr != scene;
-    }
-};
-
-TEST_F( utACImportExport, importACFromFileTest ) {
-    EXPECT_TRUE( importerTest() );
+
+TEST(utACImportExport, importClosedLine) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/AC/closedLine.ac", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(utACImportExport, importNoSurfaces) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/AC/nosurfaces.ac", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(utACImportExport, importOpenLine) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/AC/openLine.ac", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(utACImportExport, importSampleSubdiv) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/AC/sample_subdiv.ac", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(utACImportExport, importSphereWithLight) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/AC/SphereWithLight.ac", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(utACImportExport, importSphereWithLightUTF16) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/AC/SphereWithLight_UTF16LE.ac", aiProcess_ValidateDataStructure);
+    // FIXME: this is probably wrong, loading the file should succeed
+    ASSERT_EQ(nullptr, scene);
+}
+
+
+TEST(utACImportExport, importSphereWithLightUTF8BOM) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/AC/SphereWithLight_UTF8BOM.ac", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(utACImportExport, importSphereWithLightUvScaling4X) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/AC/SphereWithLightUvScaling4X.ac", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
 }
+
+
+TEST(utACImportExport, importWuson) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/AC/Wuson.ac", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(utACImportExport, testFormatDetection) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/AC/TestFormatDetection", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+

+ 172 - 0
test/unit/utBlenderImportExport.cpp

@@ -60,3 +60,175 @@ public:
 TEST_F( utBlenderImporterExporter, importBlenFromFileTest ) {
     EXPECT_TRUE( importerTest() );
 }
+
+
+TEST( utBlenderImporter, import4cubes ) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/BLEND/4Cubes4Mats_248.blend", aiProcess_ValidateDataStructure);
+    // FIXME: this is probably not right, loading this should succeed
+    ASSERT_EQ(nullptr, scene);
+}
+
+
+TEST( utBlenderImporter, import269_regress1 ) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/BLEND/blender_269_regress1.blend", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST( utBlenderImporter, importBlenderDefault248 ) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/BLEND/BlenderDefault_248.blend", aiProcess_ValidateDataStructure);
+    // FIXME: this is probably not right, loading this should succeed
+    ASSERT_EQ(nullptr, scene);
+}
+
+
+TEST( utBlenderImporter, importBlenderDefault250 ) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/BLEND/BlenderDefault_250.blend", aiProcess_ValidateDataStructure);
+    // FIXME: this is probably not right, loading this should succeed
+    ASSERT_EQ(nullptr, scene);
+}
+
+
+TEST( utBlenderImporter, importBlenderDefault250Compressed ) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/BLEND/BlenderDefault_250_Compressed.blend", aiProcess_ValidateDataStructure);
+    // FIXME: this is probably not right, loading this should succeed
+    ASSERT_EQ(nullptr, scene);
+}
+
+
+TEST( utBlenderImporter, importBlenderDefault262 ) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/BLEND/BlenderDefault_262.blend", aiProcess_ValidateDataStructure);
+    // FIXME: this is probably not right, loading this should succeed
+    ASSERT_EQ(nullptr, scene);
+}
+
+
+TEST( utBlenderImporter, importBlenderDefault269 ) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/BLEND/BlenderDefault_269.blend", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST( utBlenderImporter, importBlenderDefault271 ) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/BLEND/BlenderDefault_271.blend", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST( utBlenderImporter, importCubeHierarchy_248 ) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/BLEND/CubeHierarchy_248.blend", aiProcess_ValidateDataStructure);
+    // FIXME: this is probably not right, loading this should succeed
+    ASSERT_EQ(nullptr, scene);
+}
+
+
+TEST( utBlenderImporter, importHuman ) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/BLEND/HUMAN.blend", aiProcess_ValidateDataStructure);
+    // FIXME: this is probably not right, loading this should succeed
+    ASSERT_EQ(nullptr, scene);
+}
+
+
+TEST( utBlenderImporter, importMirroredCube_252 ) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/BLEND/MirroredCube_252.blend", aiProcess_ValidateDataStructure);
+    // FIXME: this is probably not right, loading this should succeed
+    ASSERT_EQ(nullptr, scene);
+}
+
+
+TEST( utBlenderImporter, importNoisyTexturedCube_VoronoiGlob_248 ) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/BLEND/NoisyTexturedCube_VoronoiGlob_248.blend", aiProcess_ValidateDataStructure);
+    // FIXME: this is probably not right, loading this should succeed
+    ASSERT_EQ(nullptr, scene);
+}
+
+
+TEST( utBlenderImporter, importSmoothVsSolidCube_248 ) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/BLEND/SmoothVsSolidCube_248.blend", aiProcess_ValidateDataStructure);
+    // FIXME: this is probably not right, loading this should succeed
+    ASSERT_EQ(nullptr, scene);
+}
+
+
+TEST( utBlenderImporter, importSuzanne_248 ) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/BLEND/Suzanne_248.blend", aiProcess_ValidateDataStructure);
+    // FIXME: this is probably not right, loading this should succeed
+    ASSERT_EQ(nullptr, scene);
+}
+
+
+TEST( utBlenderImporter, importSuzanneSubdiv_252 ) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/BLEND/SuzanneSubdiv_252.blend", aiProcess_ValidateDataStructure);
+    // FIXME: this is probably not right, loading this should succeed
+    ASSERT_EQ(nullptr, scene);
+}
+
+
+TEST( utBlenderImporter, importTexturedCube_ImageGlob_248 ) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/BLEND/TexturedCube_ImageGlob_248.blend", aiProcess_ValidateDataStructure);
+    // FIXME: this is probably not right, loading this should succeed
+    ASSERT_EQ(nullptr, scene);
+}
+
+
+TEST( utBlenderImporter, importTexturedPlane_ImageUv_248 ) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/BLEND/TexturedPlane_ImageUv_248.blend", aiProcess_ValidateDataStructure);
+    // FIXME: this is probably not right, loading this should succeed
+    ASSERT_EQ(nullptr, scene);
+}
+
+
+TEST( utBlenderImporter, importTexturedPlane_ImageUvPacked_248 ) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/BLEND/TexturedPlane_ImageUvPacked_248.blend", aiProcess_ValidateDataStructure);
+    // FIXME: this is probably not right, loading this should succeed
+    ASSERT_EQ(nullptr, scene);
+}
+
+
+TEST( utBlenderImporter, importTorusLightsCams_250_compressed ) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/BLEND/TorusLightsCams_250_compressed.blend", aiProcess_ValidateDataStructure);
+    // FIXME: this is probably not right, loading this should succeed
+    ASSERT_EQ(nullptr, scene);
+}
+
+
+TEST( utBlenderImporter, import_yxa_1 ) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/BLEND/yxa_1.blend", aiProcess_ValidateDataStructure);
+    // FIXME: this is probably not right, loading this should succeed
+    ASSERT_EQ(nullptr, scene);
+}
+
+
+TEST( utBlenderImporter, importBob ) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_NONBSD_DIR "/BLEND/Bob.blend", aiProcess_ValidateDataStructure);
+    // FIXME: this is probably not right, loading this should succeed
+    ASSERT_EQ(nullptr, scene);
+}
+
+
+TEST( utBlenderImporter, importFleurOptonl ) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_NONBSD_DIR "/BLEND/fleurOptonl.blend", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}

+ 77 - 0
test/unit/utXImporterExporter.cpp

@@ -67,3 +67,80 @@ TEST_F( utXImporterExporter, heap_overflow_in_tokenizer ) {
     Assimp::Importer importer;
     EXPECT_NO_THROW( importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/X/OV_GetNextToken", 0 ) );
 }
+
+
+TEST(utXImporter, importAnimTest) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/X/anim_test.x", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(utXImporter, importBCNEpileptic) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/X/BCN_Epileptic.X", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(utXImporter, importFromTrueSpaceBin32) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/X/fromtruespace_bin32.x", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(utXImporter, import_kwxport_test_cubewithvcolors) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/X/kwxport_test_cubewithvcolors.x", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(utXImporter, importTestCubeBinary) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/X/test_cube_binary.x", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(utXImporter, importTestCubeCompressed) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/X/test_cube_compressed.x", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(utXImporter, importTestCubeText) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/X/test_cube_text.x", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(utXImporter, importTestWuson) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/X/Testwuson.X", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+TEST(utXImporter, TestFormatDetection) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/X/TestFormatDetection", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+#if 0  // FIXME: disabled because it leaks memory
+
+
+TEST(utXImporter, importDwarf) {
+    Assimp::Importer importer;
+    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_NONBSD_DIR "/X/dwarf.x", aiProcess_ValidateDataStructure);
+    ASSERT_NE(nullptr, scene);
+}
+
+
+#endif  // 0
+