Browse Source

Merge branch 'master' into master

Kim Kulling 5 năm trước cách đây
mục cha
commit
27449f17ca
64 tập tin đã thay đổi với 152 bổ sung77 xóa
  1. 0 4
      code/CMakeLists.txt
  2. 21 18
      code/MDL/HalfLife/HL1MDLLoader.cpp
  3. BIN
      test/models-nonbsd/3DS/m_rifl.bmp
  4. BIN
      test/models-nonbsd/AMF/screenshot_3_bananas.jpeg
  5. BIN
      test/models-nonbsd/B3D/turtle1.png
  6. BIN
      test/models-nonbsd/FBX/2013_ASCII/duck_sample.jpg
  7. BIN
      test/models-nonbsd/FBX/2013_ASCII/m_rifl.bmp
  8. BIN
      test/models-nonbsd/IRR/skybox/default_skybox3.jpg
  9. BIN
      test/models-nonbsd/IRR/skybox/default_skyboxdn.jpg
  10. BIN
      test/models-nonbsd/IRR/skybox/default_skyboxup.jpg
  11. BIN
      test/models-nonbsd/MD3/q3root/models/mapobjects/kt_kubalwagon/euro_frnt_2.tga
  12. BIN
      test/models-nonbsd/MD3/q3root/models/mapobjects/kt_kubalwagon/european_fnt.tga
  13. BIN
      test/models-nonbsd/MD3/water_can.tga
  14. BIN
      test/models-nonbsd/MD5/guard1_body.png
  15. BIN
      test/models-nonbsd/MD5/guard1_face.png
  16. BIN
      test/models-nonbsd/MD5/guard1_helmet.png
  17. BIN
      test/models-nonbsd/MD5/iron_grill.png
  18. BIN
      test/models-nonbsd/MD5/round_grill.png
  19. BIN
      test/models-nonbsd/MDL/MDL7 (3DGS A7)/branchD_texture.png
  20. BIN
      test/models-nonbsd/Ogre/OgreSDK/fish.jpg
  21. BIN
      test/models/3DS/CWALL02.jpg
  22. BIN
      test/models/3DS/IMAGE2.jpg
  23. BIN
      test/models/3DS/UVTransformTest/UVTransformTestImg.png
  24. BIN
      test/models/3DS/test.png
  25. BIN
      test/models/Collada/duck_sample.jpg
  26. BIN
      test/models/Collada/teapots_reference.png
  27. BIN
      test/models/IRRMesh/1.png
  28. BIN
      test/models/LWO/LWO2/MappingModes/earthCylindric.jpg
  29. BIN
      test/models/LWO/LWO2/MappingModes/earthSpherical.jpg
  30. BIN
      test/models/LWO/LWO2/boxuv.png
  31. BIN
      test/models/LWO/LWO2/uvtest.png
  32. BIN
      test/models/MD2/faerie2.bmp
  33. BIN
      test/models/MD2/sydney.bmp
  34. BIN
      test/models/Ogre/TheThing/Reference.JPG
  35. BIN
      test/models/ReferenceImages/MappingModes/cylindrical.png
  36. BIN
      test/models/ReferenceImages/MappingModes/spherical.png
  37. BIN
      test/models/ReferenceImages/UVTransform/UVTransform_Normal.png
  38. BIN
      test/models/ReferenceImages/UVTransform/UVTransform_OffsetUV0.5-clampUV.png
  39. BIN
      test/models/ReferenceImages/UVTransform/UVTransform_OffsetUV0.5-mirrorUV.png
  40. BIN
      test/models/ReferenceImages/UVTransform/UVTransform_OffsetUV0.5.png
  41. BIN
      test/models/ReferenceImages/UVTransform/UVTransform_ScaleUV1-2_OffsetUV0-0.9_Rotate-72.png
  42. BIN
      test/models/ReferenceImages/UVTransform/UVTransform_ScaleUV1-2_OffsetUV0-0.9_Rotate-72_mirrorU.png
  43. BIN
      test/models/ReferenceImages/UVTransform/UVTransform_ScaleUV10-2_OffsetUV10-mirrorUV.png
  44. BIN
      test/models/ReferenceImages/UVTransform/UVTransform_ScaleUV2x.png
  45. BIN
      test/models/ReferenceImages/UVTransform/UVTransform_ScaleUV2x_Rotate45.png
  46. BIN
      test/models/SIB/This Way Up.png
  47. BIN
      test/models/SIB/UV Mapping.png
  48. BIN
      test/models/X/bottom.tga
  49. BIN
      test/models/X/test.png
  50. BIN
      test/models/X/top.tga
  51. BIN
      test/models/glTF/BoxTextured-glTF-MaterialsCommon/CesiumLogoFlat.png
  52. BIN
      test/models/glTF/BoxTextured-glTF/CesiumLogoFlat.png
  53. BIN
      test/models/glTF/CesiumMilkTruck/CesiumMilkTruck.png
  54. BIN
      test/models/glTF2/BoxTextured-glTF-pbrSpecularGlossiness/CesiumLogoFlat.png
  55. BIN
      test/models/glTF2/BoxTextured-glTF-techniqueWebGL/CesiumLogoFlat.png
  56. BIN
      test/models/glTF2/BoxTextured-glTF/CesiumLogoFlat.png
  57. 13 2
      test/unit/ImportExport/utMDLImporter.cpp
  58. 8 8
      tools/assimp_cmd/CompareDump.cpp
  59. 5 5
      tools/assimp_cmd/Export.cpp
  60. 11 9
      tools/assimp_cmd/ImageExtractor.cpp
  61. 6 6
      tools/assimp_cmd/Info.cpp
  62. 13 13
      tools/assimp_cmd/Main.cpp
  63. 70 7
      tools/assimp_cmd/Main.h
  64. 5 5
      tools/assimp_cmd/WriteDumb.cpp

+ 0 - 4
code/CMakeLists.txt

@@ -1213,10 +1213,6 @@ SET_TARGET_PROPERTIES( assimp PROPERTIES
 )
 
 if (APPLE)
-  SET_TARGET_PROPERTIES( assimp PROPERTIES
-    INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/${ASSIMP_LIB_INSTALL_DIR}"
-  )
-
   if (BUILD_FRAMEWORK)
     SET_TARGET_PROPERTIES( assimp PROPERTIES
       FRAMEWORK TRUE

+ 21 - 18
code/MDL/HalfLife/HL1MDLLoader.cpp

@@ -182,6 +182,13 @@ void HL1MDLLoader::load_file() {
 
         read_global_info();
 
+        if (!header_->numbodyparts) {
+            // This could be an MDL external texture file. In this case,
+            // add this flag to allow the scene to be loaded even if it
+            // has no meshes.
+            scene_->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
+        }
+
         // Append children to root node.
         if (rootnode_children_.size()) {
             scene_->mRootNode->addChildren(
@@ -218,21 +225,6 @@ void HL1MDLLoader::validate_header(const Header_HL1 *header, bool is_texture_hea
         }
 
     } else {
-        // Every single Half-Life model is assumed to have at least one bodypart.
-        if (!header->numbodyparts) {
-            throw DeadlyImportError(MDL_HALFLIFE_LOG_HEADER "Model has no bodyparts");
-        }
-
-        // Every single Half-Life model is assumed to have at least one bone.
-        if (!header->numbones) {
-            throw DeadlyImportError(MDL_HALFLIFE_LOG_HEADER "Model has no bones");
-        }
-
-        // Every single Half-Life model is assumed to have at least one sequence group,
-        // which is the "default" sequence group.
-        if (!header->numseqgroups) {
-            throw DeadlyImportError(MDL_HALFLIFE_LOG_HEADER "Model has no sequence groups");
-        }
 
         if (header->numbodyparts > AI_MDL_HL1_MAX_BODYPARTS) {
             log_warning_limit_exceeded<AI_MDL_HL1_MAX_BODYPARTS>(header->numbodyparts, "bodyparts");
@@ -381,9 +373,9 @@ void HL1MDLLoader::read_texture(const Texture_HL1 *ptexture,
     pResult->mFilename = ptexture->name;
     pResult->mWidth = outwidth;
     pResult->mHeight = outheight;
-    pResult->achFormatHint[0] = 'b';
+    pResult->achFormatHint[0] = 'r';
     pResult->achFormatHint[1] = 'g';
-    pResult->achFormatHint[2] = 'r';
+    pResult->achFormatHint[2] = 'b';
     pResult->achFormatHint[3] = 'a';
     pResult->achFormatHint[4] = '8';
     pResult->achFormatHint[5] = '8';
@@ -498,6 +490,10 @@ void HL1MDLLoader::read_skins() {
 
 // ------------------------------------------------------------------------------------------------
 void HL1MDLLoader::read_bones() {
+    if (!header_->numbones) {
+        return;
+    }
+
     const Bone_HL1 *pbone = (const Bone_HL1 *)((uint8_t *)header_ + header_->boneindex);
 
     std::vector<std::string> unique_bones_names(header_->numbones);
@@ -588,6 +584,9 @@ void HL1MDLLoader::read_bones() {
     triangles, respectively (3 indices per face).
 */
 void HL1MDLLoader::read_meshes() {
+    if (!header_->numbodyparts) {
+        return;
+    }
 
     int total_verts = 0;
     int total_triangles = 0;
@@ -964,8 +963,9 @@ void HL1MDLLoader::read_meshes() {
 
 // ------------------------------------------------------------------------------------------------
 void HL1MDLLoader::read_animations() {
-    if (!header_->numseq)
+    if (!header_->numseq) {
         return;
+    }
 
     const SequenceDesc_HL1 *pseqdesc = (const SequenceDesc_HL1 *)((uint8_t *)header_ + header_->seqindex);
     const SequenceGroup_HL1 *pseqgroup = nullptr;
@@ -1067,6 +1067,9 @@ void HL1MDLLoader::read_animations() {
 
 // ------------------------------------------------------------------------------------------------
 void HL1MDLLoader::read_sequence_groups_info() {
+    if (!header_->numseqgroups) {
+        return;
+    }
 
     aiNode *sequence_groups_node = new aiNode(AI_MDL_HL1_NODE_SEQUENCE_GROUPS);
     rootnode_children_.push_back(sequence_groups_node);

BIN
test/models-nonbsd/3DS/m_rifl.bmp


BIN
test/models-nonbsd/AMF/screenshot_3_bananas.jpeg


BIN
test/models-nonbsd/B3D/turtle1.png


BIN
test/models-nonbsd/FBX/2013_ASCII/duck_sample.jpg


BIN
test/models-nonbsd/FBX/2013_ASCII/m_rifl.bmp


BIN
test/models-nonbsd/IRR/skybox/default_skybox3.jpg


BIN
test/models-nonbsd/IRR/skybox/default_skyboxdn.jpg


BIN
test/models-nonbsd/IRR/skybox/default_skyboxup.jpg


BIN
test/models-nonbsd/MD3/q3root/models/mapobjects/kt_kubalwagon/euro_frnt_2.tga


BIN
test/models-nonbsd/MD3/q3root/models/mapobjects/kt_kubalwagon/european_fnt.tga


BIN
test/models-nonbsd/MD3/water_can.tga


BIN
test/models-nonbsd/MD5/guard1_body.png


BIN
test/models-nonbsd/MD5/guard1_face.png


BIN
test/models-nonbsd/MD5/guard1_helmet.png


BIN
test/models-nonbsd/MD5/iron_grill.png


BIN
test/models-nonbsd/MD5/round_grill.png


BIN
test/models-nonbsd/MDL/MDL7 (3DGS A7)/branchD_texture.png


BIN
test/models-nonbsd/Ogre/OgreSDK/fish.jpg


BIN
test/models/3DS/CWALL02.jpg


BIN
test/models/3DS/IMAGE2.jpg


BIN
test/models/3DS/UVTransformTest/UVTransformTestImg.png


BIN
test/models/3DS/test.png


BIN
test/models/Collada/duck_sample.jpg


BIN
test/models/Collada/teapots_reference.png


BIN
test/models/IRRMesh/1.png


BIN
test/models/LWO/LWO2/MappingModes/earthCylindric.jpg


BIN
test/models/LWO/LWO2/MappingModes/earthSpherical.jpg


BIN
test/models/LWO/LWO2/boxuv.png


BIN
test/models/LWO/LWO2/uvtest.png


BIN
test/models/MD2/faerie2.bmp


BIN
test/models/MD2/sydney.bmp


BIN
test/models/Ogre/TheThing/Reference.JPG


BIN
test/models/ReferenceImages/MappingModes/cylindrical.png


BIN
test/models/ReferenceImages/MappingModes/spherical.png


BIN
test/models/ReferenceImages/UVTransform/UVTransform_Normal.png


BIN
test/models/ReferenceImages/UVTransform/UVTransform_OffsetUV0.5-clampUV.png


BIN
test/models/ReferenceImages/UVTransform/UVTransform_OffsetUV0.5-mirrorUV.png


BIN
test/models/ReferenceImages/UVTransform/UVTransform_OffsetUV0.5.png


BIN
test/models/ReferenceImages/UVTransform/UVTransform_ScaleUV1-2_OffsetUV0-0.9_Rotate-72.png


BIN
test/models/ReferenceImages/UVTransform/UVTransform_ScaleUV1-2_OffsetUV0-0.9_Rotate-72_mirrorU.png


BIN
test/models/ReferenceImages/UVTransform/UVTransform_ScaleUV10-2_OffsetUV10-mirrorUV.png


BIN
test/models/ReferenceImages/UVTransform/UVTransform_ScaleUV2x.png


BIN
test/models/ReferenceImages/UVTransform/UVTransform_ScaleUV2x_Rotate45.png


BIN
test/models/SIB/This Way Up.png


BIN
test/models/SIB/UV Mapping.png


BIN
test/models/X/bottom.tga


BIN
test/models/X/test.png


BIN
test/models/X/top.tga


BIN
test/models/glTF/BoxTextured-glTF-MaterialsCommon/CesiumLogoFlat.png


BIN
test/models/glTF/BoxTextured-glTF/CesiumLogoFlat.png


BIN
test/models/glTF/CesiumMilkTruck/CesiumMilkTruck.png


BIN
test/models/glTF2/BoxTextured-glTF-pbrSpecularGlossiness/CesiumLogoFlat.png


BIN
test/models/glTF2/BoxTextured-glTF-techniqueWebGL/CesiumLogoFlat.png


BIN
test/models/glTF2/BoxTextured-glTF/CesiumLogoFlat.png


+ 13 - 2
test/unit/ImportExport/utMDLImporter.cpp

@@ -57,13 +57,24 @@ public:
     virtual bool importerTest() {
 
         Assimp::Importer importer;
-        const aiScene *scene = importer.ReadFile(MDL_HL1_FILE_MAN, 0);
-        EXPECT_NE(nullptr, scene);
+        importerTest_HL1(&importer);
 
         // Add further MDL tests...
 
         return true;
     }
+
+private:
+    void importerTest_HL1(Assimp::Importer* const importer) {
+        const aiScene *scene = importer->ReadFile(MDL_HL1_FILE_MAN, 0);
+        EXPECT_NE(nullptr, scene);
+
+        // Test that the importer can directly load an HL1 MDL external texture file.
+        scene = importer->ReadFile(ASSIMP_TEST_MDL_HL1_MODELS_DIR "manT.mdl", aiProcess_ValidateDataStructure);
+        EXPECT_NE(nullptr, scene);
+        EXPECT_NE(0u, scene->mNumTextures);
+        EXPECT_NE(0u, scene->mNumMaterials);
+    }
 };
 
 TEST_F(utMDLImporter, importMDLFromFileTest) {

+ 8 - 8
tools/assimp_cmd/CompareDump.cpp

@@ -885,19 +885,19 @@ int Assimp_CompareDump (const char* const* params, unsigned int num)
     // --help
     if ((num == 1 && !strcmp( params[0], "-h")) || !strcmp( params[0], "--help") || !strcmp( params[0], "-?") ) {
         printf("%s",AICMD_MSG_CMPDUMP_HELP);
-        return 0;
+        return AssimpCmdError::Success;
     }
 
     // assimp cmpdump actual expected
     if (num < 2) {
         std::cout << "assimp cmpdump: Invalid number of arguments. "
             "See \'assimp cmpdump --help\'\r\n" << std::endl;
-        return 1;
+        return AssimpCmdError::InvalidNumberOfArguments;
     }
 
     if(!strcmp(params[0],params[1])) {
         std::cout << "assimp cmpdump: same file, same content." << std::endl;
-        return 0;
+        return AssimpCmdError::Success;
     }
 
     class file_ptr
@@ -924,13 +924,13 @@ int Assimp_CompareDump (const char* const* params, unsigned int num)
     if (!actual) {
         std::cout << "assimp cmpdump: Failure reading ACTUAL data from " <<
             params[0]  << std::endl;
-        return -5;
+        return AssimpCmdError::FailedToLoadInputFile;
     }
     file_ptr expected(fopen(params[1],"rb"));
     if (!expected) {
         std::cout << "assimp cmpdump: Failure reading EXPECT data from " <<
             params[1]  << std::endl;
-        return -6;
+        return AssimpCmdCompareDumpError::FailedToLoadExpectedInputFile;
     }
 
     comparer_context comp(actual,expected);
@@ -940,17 +940,17 @@ int Assimp_CompareDump (const char* const* params, unsigned int num)
     }
     catch(const compare_fails_exception& ex) {
         printf("%s",ex.what());
-        return -1;
+        return AssimpCmdCompareDumpError::FileComparaisonFailure;
     }
     catch(...) {
         // we don't bother checking too rigourously here, so
         // we might end up here ...
         std::cout << "Unknown failure, are the input files well-defined?";
-        return -3;
+        return AssimpCmdCompareDumpError::UnknownFailure;
     }
 
     std::cout << "Success (totally " << std::dec << comp.get_num_chunks() <<
         " chunks)" << std::endl;
 
-    return 0;
+    return AssimpCmdError::Success;
 }

+ 5 - 5
tools/assimp_cmd/Export.cpp

@@ -76,13 +76,13 @@ int Assimp_Export(const char* const* params, unsigned int num)
 	const char* const invalid = "assimp export: Invalid number of arguments. See \'assimp export --help\'\n";
 	if (num < 1) {
 		printf(invalid);
-		return 1;
+		return AssimpCmdError::InvalidNumberOfArguments;
 	}
 
 	// --help
 	if (!strcmp( params[0], "-h") || !strcmp( params[0], "--help") || !strcmp( params[0], "-?") ) {
 		printf("%s",AICMD_MSG_EXPORT_HELP_E);
-		return 0;
+		return AssimpCmdError::Success;
 	}
 
 	std::string in  = std::string(params[0]);
@@ -156,7 +156,7 @@ int Assimp_Export(const char* const* params, unsigned int num)
 	// import the  model
 	const aiScene* scene = ImportModel(import,in);
 	if (!scene) {
-		return -39;
+		return AssimpCmdExportError::FailedToImportModel;
 	}
 
 	// derive the final file name
@@ -164,10 +164,10 @@ int Assimp_Export(const char* const* params, unsigned int num)
 
 	// and call the export routine
 	if(!ExportModel(scene, import, out,e->id)) {
-		return -25;
+		return AssimpCmdExportError::FailedToExportModel;
 	}
 	printf("assimp export: wrote output file: %s\n",out.c_str());
-	return 0;
+	return AssimpCmdError::Success;
 }
 
 #endif // no export

+ 11 - 9
tools/assimp_cmd/ImageExtractor.cpp

@@ -219,9 +219,9 @@ int DoExport(const aiTexture* tx, FILE* p, const std::string& extension,
     }
     else {
         printf("assimp extract: No available texture encoder found for %s\n", extension.c_str());
-        return 1;
+        return AssimpCmdExtractError::NoAvailableTextureEncoderFound;
     }
-    return 0;
+    return AssimpCmdError::Success;
 }
 
 // -----------------------------------------------------------------------------------
@@ -232,13 +232,13 @@ int Assimp_Extract (const char* const* params, unsigned int num)
     // assimp extract in out [options]
     if (num < 1) {
         printf(invalid);
-        return 1;
+        return AssimpCmdError::InvalidNumberOfArguments;
     }
 
     // --help
     if (!strcmp( params[0], "-h") || !strcmp( params[0], "--help") || !strcmp( params[0], "-?") ) {
         printf("%s",AICMD_MSG_DUMP_HELP_E);
-        return 0;
+        return AssimpCmdError::Success;
     }
 
 
@@ -308,7 +308,7 @@ int Assimp_Extract (const char* const* params, unsigned int num)
     const aiScene* scene = ImportModel(import,in);
     if (!scene) {
         printf("assimp extract: Unable to load input file %s\n",in.c_str());
-        return 5;
+        return AssimpCmdError::FailedToLoadInputFile;
     }
 
     // get the texture(s) to be exported
@@ -318,7 +318,7 @@ int Assimp_Extract (const char* const* params, unsigned int num)
         if (texIdx >= scene->mNumTextures) {
             ::printf("assimp extract: Texture %i requested, but there are just %i textures\n",
                 texIdx, scene->mNumTextures);
-            return 6;
+            return AssimpCmdExtractError::TextureIndexIsOutOfRange;
         }
     }
     else {
@@ -358,12 +358,14 @@ int Assimp_Extract (const char* const* params, unsigned int num)
         FILE* p = ::fopen(out_cpy.c_str(),"wb");
         if (!p)  {
             printf("assimp extract: Unable to open output file %s\n",out_cpy.c_str());
-            return 7;
+            return AssimpCmdError::FailedToOpenOutputFile;
         }
         int m;
 
         if (!tex->mHeight) {
-            m = (1 != fwrite(tex->pcData,tex->mWidth,1,p));
+            m = (1 != fwrite(tex->pcData,tex->mWidth,1,p)) 
+				? static_cast<int>(AssimpCmdError::Success) 
+				: static_cast<int>(AssimpCmdExtractError::FailedToExportCompressedTexture);
         }
         else m = DoExport(tex,p,extension,flags);
         ::fclose(p);
@@ -372,5 +374,5 @@ int Assimp_Extract (const char* const* params, unsigned int num)
         if (texIdx != 0xffffffff)
             return m;
     }
-    return 0;
+    return AssimpCmdError::Success;
 }

+ 6 - 6
tools/assimp_cmd/Info.cpp

@@ -283,14 +283,14 @@ int Assimp_Info (const char* const* params, unsigned int num) {
 	// --help
 	if (!strcmp( params[0],"-h")||!strcmp( params[0],"--help")||!strcmp( params[0],"-?") ) {
 		printf("%s",AICMD_MSG_INFO_HELP_E);
-		return 0;
+		return AssimpCmdError::Success;
 	}
 
 	// asssimp info <file> [-r]
 	if (num < 1) {
 		printf("assimp info: Invalid number of arguments. "
 			"See \'assimp info --help\'\n");
-		return 1;
+		return AssimpCmdError::InvalidNumberOfArguments;
 	}
 
 	const std::string in  = std::string(params[0]);
@@ -314,7 +314,7 @@ int Assimp_Info (const char* const* params, unsigned int num) {
 	// Verbose and silent at the same time are not allowed
 	if ( verbose && silent ) {
 		printf("assimp info: Invalid arguments, verbose and silent at the same time are forbitten. ");
-		return 1;
+		return AssimpCmdInfoError::InvalidCombinaisonOfArguments;
 	}
 	
 	// Parse post-processing flags unless -r was specified
@@ -333,7 +333,7 @@ int Assimp_Info (const char* const* params, unsigned int num) {
 	if (!scene) {
 		printf("assimp info: Unable to load input file %s\n",
 			in.c_str());
-		return 5;
+		return AssimpCmdError::FailedToLoadInputFile;
 	}
 
 	aiMemoryInfo mem;
@@ -391,7 +391,7 @@ int Assimp_Info (const char* const* params, unsigned int num) {
 	if (silent)
 	{
 		printf("\n");
-		return 0;
+		return AssimpCmdError::Success;
 	}
 
 	// meshes
@@ -473,5 +473,5 @@ int Assimp_Info (const char* const* params, unsigned int num) {
 	PrintHierarchy(scene->mRootNode,"",verbose);
 
 	printf("\n");
-	return 0;
+	return AssimpCmdError::Success;
 }

+ 13 - 13
tools/assimp_cmd/Main.cpp

@@ -85,7 +85,7 @@ int main (int argc, char* argv[])
 {
 	if (argc <= 1)	{
 		printf("assimp: No command specified. Use \'assimp help\' for a detailed command list\n");
-		return 0;
+		return AssimpCmdError::Success;
 	}
 
 	// assimp version
@@ -102,7 +102,7 @@ int main (int argc, char* argv[])
 			(flags & ASSIMP_CFLAGS_STLPORT ?		"-stlport " : ""),
 			aiGetVersionRevision());
 
-		return 0;
+		return AssimpCmdError::Success;
 	}
 
 	// assimp help
@@ -110,7 +110,7 @@ int main (int argc, char* argv[])
 	// because people could try them intuitively)
 	if (!strcmp(argv[1], "help") || !strcmp(argv[1], "--help") || !strcmp(argv[1], "-h")) {
 		printf("%s",AICMD_MSG_HELP);
-		return 0;
+		return AssimpCmdError::Success;
 	}
 
 	// assimp cmpdump
@@ -137,7 +137,7 @@ int main (int argc, char* argv[])
 		imp.GetExtensionList(s);
 
 		printf("%s\n",s.data);
-		return 0;
+		return AssimpCmdError::Success;
 	}
 
 #ifndef ASSIMP_BUILD_NO_EXPORT
@@ -155,7 +155,7 @@ int main (int argc, char* argv[])
 		}
 
 		printf("%s\n",s.data);
-		return 0;
+		return AssimpCmdError::Success;
 	}
 
 
@@ -166,19 +166,19 @@ int main (int argc, char* argv[])
 
 		if (argc<3) {
 			printf("Expected file format id\n");
-			return -11;
+			return AssimpCmdError::NoFileFormatSpecified;
 		}
 
 		for(size_t i = 0, end = exp.GetExportFormatCount(); i < end; ++i) {
 			const aiExportFormatDesc* const e = exp.GetExportFormatDescription(i);
 			if (!strcmp(e->id,argv[2])) {
 				printf("%s\n%s\n%s\n",e->id,e->fileExtension,e->description);
-				return 0;
+				return AssimpCmdError::Success;
 			}
 		}
 		
 		printf("Unknown file format id: \'%s\'\n",argv[2]);
-		return -12;
+		return AssimpCmdError::UnknownFileFormat;
 	}
 
 	// assimp export
@@ -194,11 +194,11 @@ int main (int argc, char* argv[])
 	if (! strcmp(argv[1], "knowext")) {
 		if (argc<3) {
 			printf("Expected file extension");
-			return -10;
+			return AssimpCmdError::NoFileExtensionSpecified;
 		}
 		const bool b = imp.IsExtensionSupported(argv[2]);
 		printf("File extension \'%s\'  is %sknown\n",argv[2],(b?"":"not "));
-		return b?0:-1;
+		return b? AssimpCmdError::Success : AssimpCmdError::UnknownFileExtension;
 	}
 
 	// assimp info
@@ -228,7 +228,7 @@ int main (int argc, char* argv[])
 	}
 
 	printf("Unrecognized command. Use \'assimp help\' for a detailed command list\n");
-	return 1;
+	return AssimpCmdError::UnrecognizedCommand;
 }
 
 
@@ -505,7 +505,7 @@ int ProcessStandardArguments(
 		fill.log = true;
 	}
 
-	return 0;
+	return AssimpCmdError::Success;
 }
 
 // ------------------------------------------------------------------------------
@@ -517,5 +517,5 @@ int Assimp_TestBatchLoad (
 		globalImporter->ReadFile(params[i],aiProcessPreset_TargetRealtime_MaxQuality);
 		// we're totally silent. scene destructs automatically.
 	}
-	return 0;
+	return AssimpCmdError::Success;
 }

+ 70 - 7
tools/assimp_cmd/Main.h

@@ -114,13 +114,31 @@ struct ImportData {
 	bool log;
 };
 
+/// \enum AssimpCmdError
+/// \brief General error codes used among assimp_cmd's utilities.
+enum AssimpCmdError {
+	Success = 0,
+	InvalidNumberOfArguments,
+	UnrecognizedCommand,
+	FailedToLoadInputFile,
+	FailedToOpenOutputFile,
+	NoFileFormatSpecified,
+	UnknownFileFormat,
+	NoFileExtensionSpecified,
+	UnknownFileExtension,
+
+	// Add new error codes here...
+
+	LastAssimpCmdError, // Must be last.
+};
+
 // ------------------------------------------------------------------------------
 /** Process standard arguments
  *
  *  @param fill Filled by function
  *  @param params Command line parameters to be processed
  *  @param num NUmber of params
- *  @return 0 for success */
+ *  @return An #AssimpCmdError value. */
 int ProcessStandardArguments(ImportData& fill, 
 	const char* const* params,
 	unsigned int num);
@@ -151,43 +169,88 @@ bool ExportModel(const aiScene* pOut,
 /** assimp_dump utility
  *  @param params Command line parameters to 'assimp dumb'
  *  @param Number of params
- *  @return 0 for success*/
+ *  @return An #AssimpCmdError value.*/
 int Assimp_Dump (
 	const char* const* params, 
 	unsigned int num);
 
+/// \enum AssimpCmdExportError
+/// \brief Error codes used by the 'Export' utility.
+enum AssimpCmdExportError {
+	FailedToImportModel = AssimpCmdError::LastAssimpCmdError,
+	FailedToExportModel,
+
+	// Add new error codes here...
+	
+	LastAssimpCmdExportError, // Must be last.
+};
+
 // ------------------------------------------------------------------------------
 /** assimp_export utility
  *  @param params Command line parameters to 'assimp export'
  *  @param Number of params
- *  @return 0 for success*/
+ *  @return Either an #AssimpCmdError or #AssimpCmdExportError value. */
 int Assimp_Export (
 	const char* const* params, 
 	unsigned int num);
 
+/// \enum AssimpCmdExtractError
+/// \brief Error codes used by the 'Image Extractor' utility.
+enum AssimpCmdExtractError {
+	TextureIndexIsOutOfRange = AssimpCmdError::LastAssimpCmdError,
+	NoAvailableTextureEncoderFound,
+	FailedToExportCompressedTexture,
+
+	// Add new error codes here...
+
+	LastAssimpCmdExtractError, // Must be last.
+};
+
 // ------------------------------------------------------------------------------
 /** assimp_extract utility
  *  @param params Command line parameters to 'assimp extract'
  *  @param Number of params
- *  @return 0 for success*/
+ *  @return Either an #AssimpCmdError or #AssimpCmdExtractError value. */
 int Assimp_Extract (
 	const char* const* params, 
 	unsigned int num);
 
+/// \enum AssimpCmdCompareDumpError
+/// \brief Error codes used by the 'Compare Dump' utility.
+enum AssimpCmdCompareDumpError {
+	FailedToLoadExpectedInputFile = AssimpCmdError::LastAssimpCmdError,
+	FileComparaisonFailure,
+	UnknownFailure,
+
+	// Add new error codes here...
+
+	LastAssimpCmdCompareDumpError, // Must be last.
+};
+
 // ------------------------------------------------------------------------------
 /** assimp_cmpdump utility
  *  @param params Command line parameters to 'assimp cmpdump'
  *  @param Number of params
- *  @return 0 for success*/
+ *  @return Either an #AssimpCmdError or #AssimpCmdCompareDumpError. */
 int Assimp_CompareDump (
 	const char* const* params, 
 	unsigned int num);
 
+/// \enum AssimpCmdInfoError
+/// \brief Error codes used by the 'Info' utility.
+enum AssimpCmdInfoError {
+	InvalidCombinaisonOfArguments = AssimpCmdError::LastAssimpCmdError,
+
+	// Add new error codes here...
+
+	LastAssimpCmdInfoError, // Must be last.
+};
+
 // ------------------------------------------------------------------------------
 /** @brief assimp info utility
  *  @param params Command line parameters to 'assimp info'
  *  @param Number of params
- *  @return 0 for success */
+ *  @return Either an #AssimpCmdError or #AssimpCmdInfoError value. */
 int Assimp_Info (
 	const char* const* params, 
 	unsigned int num);
@@ -196,7 +259,7 @@ int Assimp_Info (
 /** @brief assimp testbatchload utility
  *  @param params Command line parameters to 'assimp testbatchload'
  *  @param Number of params
- *  @return 0 for success */
+ *  @return An #AssimpCmdError value. */
 int Assimp_TestBatchLoad (
 	const char* const* params, 
 	unsigned int num);

+ 5 - 5
tools/assimp_cmd/WriteDumb.cpp

@@ -1341,13 +1341,13 @@ int Assimp_Dump (const char* const* params, unsigned int num)
 	// --help
 	if (!strcmp( params[0], "-h") || !strcmp( params[0], "--help") || !strcmp( params[0], "-?") ) {
 		printf("%s",AICMD_MSG_DUMP_HELP);
-		return 0;
+		return AssimpCmdError::Success;
 	}
 
 	// asssimp dump in out [options]
 	if (num < 1) {
 		printf("%s", fail);
-		return 1;
+		return AssimpCmdError::InvalidNumberOfArguments;
 	}
 
 	std::string in  = std::string(params[0]);
@@ -1405,14 +1405,14 @@ int Assimp_Dump (const char* const* params, unsigned int num)
 	const aiScene* scene = ImportModel(import,in);
 	if (!scene) {
 		printf("assimp dump: Unable to load input file %s\n",in.c_str());
-		return 5;
+		return AssimpCmdError::FailedToLoadInputFile;
 	}
 
 	// open the output file and build the dump
 	FILE* o = ::fopen(out.c_str(),(binary ? "wb" : "wt"));
 	if (!o) {
 		printf("assimp dump: Unable to open output file %s\n",out.c_str());
-		return 12;
+		return AssimpCmdError::FailedToOpenOutputFile;
 	}
 
 	if (binary) {
@@ -1426,6 +1426,6 @@ int Assimp_Dump (const char* const* params, unsigned int num)
 	}
 
 	printf("assimp dump: Wrote output dump %s\n",out.c_str());
-	return 0;
+	return AssimpCmdError::Success;
 }