瀏覽代碼

- Change BaseImporter::GetExtensionList to add all known file extensions to a std::set, so uniqueness is guaranteed. Also rewrite all related functions in Importer. NOTE: This does *not* change the public interface.

- FIX build error on vc8/release-noboost x64, ConvertUTF.c had wrong PCH settings.
- ADD knowext and listext verbs to assimp_cmd, add some raw docs.
- Update unit tests to reflect these changes. Currently I keep getting failures in some tests, this needs to be resolved *urgently*.

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@567 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
aramis_acg 15 年之前
父節點
當前提交
5738860990
共有 72 個文件被更改,包括 416 次插入261 次删除
  1. 5 3
      code/3DSLoader.cpp
  2. 1 1
      code/3DSLoader.h
  3. 4 2
      code/ACLoader.cpp
  4. 1 1
      code/ACLoader.h
  5. 3 2
      code/ASELoader.cpp
  6. 1 1
      code/ASELoader.h
  7. 1 2
      code/Assimp.cpp
  8. 2 2
      code/B3DImporter.cpp
  9. 1 1
      code/B3DImporter.h
  10. 2 2
      code/BVHLoader.h
  11. 60 37
      code/BaseImporter.h
  12. 2 2
      code/CSMLoader.cpp
  13. 1 1
      code/CSMLoader.h
  14. 2 2
      code/ColladaLoader.cpp
  15. 1 1
      code/ColladaLoader.h
  16. 2 2
      code/DXFLoader.cpp
  17. 1 1
      code/DXFLoader.h
  18. 2 2
      code/HMPLoader.cpp
  19. 1 1
      code/HMPLoader.h
  20. 3 6
      code/IRRLoader.cpp
  21. 1 1
      code/IRRLoader.h
  22. 3 3
      code/IRRMeshLoader.cpp
  23. 1 1
      code/IRRMeshLoader.h
  24. 76 62
      code/Importer.cpp
  25. 3 2
      code/LWOLoader.h
  26. 3 2
      code/LWSLoader.cpp
  27. 1 1
      code/LWSLoader.h
  28. 2 2
      code/MD2Loader.cpp
  29. 1 1
      code/MD2Loader.h
  30. 13 6
      code/MD3Loader.cpp
  31. 1 1
      code/MD3Loader.h
  32. 4 2
      code/MD5Loader.cpp
  33. 1 1
      code/MD5Loader.h
  34. 2 2
      code/MDCLoader.cpp
  35. 1 1
      code/MDCLoader.h
  36. 2 2
      code/MDLLoader.cpp
  37. 1 1
      code/MDLLoader.h
  38. 2 2
      code/MS3DLoader.cpp
  39. 1 1
      code/MS3DLoader.h
  40. 3 2
      code/NFFLoader.cpp
  41. 1 1
      code/NFFLoader.h
  42. 2 2
      code/OFFLoader.cpp
  43. 1 1
      code/OFFLoader.h
  44. 3 3
      code/ObjFileImporter.h
  45. 2 2
      code/OgreImporter.cpp
  46. 1 1
      code/OgreImporter.h
  47. 2 2
      code/PlyLoader.cpp
  48. 1 1
      code/PlyLoader.h
  49. 3 2
      code/Q3DLoader.cpp
  50. 1 1
      code/Q3DLoader.h
  51. 2 2
      code/RawLoader.cpp
  52. 1 1
      code/RawLoader.h
  53. 3 2
      code/SMDLoader.cpp
  54. 1 1
      code/SMDLoader.h
  55. 2 2
      code/STLLoader.cpp
  56. 1 1
      code/STLLoader.h
  57. 2 2
      code/TerragenLoader.cpp
  58. 1 1
      code/TerragenLoader.h
  59. 4 3
      code/UnrealLoader.cpp
  60. 1 1
      code/UnrealLoader.h
  61. 2 2
      code/XFileImporter.cpp
  62. 1 1
      code/XFileImporter.h
  63. 4 4
      contrib/cppunit-1.12.1/src/cppunit/cppunit.vcproj
  64. 2 2
      doc/dox.h
  65. 43 39
      include/assimp.hpp
  66. 1 0
      test/unit/Main.cpp
  67. 9 6
      test/unit/utImporter.cpp
  68. 1 1
      test/unit/utImporter.h
  69. 3 3
      test/unit/utLimitBoneWeights.cpp
  70. 32 2
      tools/assimp_cmd/Main.cpp
  71. 1 1
      tools/assimp_cmd/WriteDumb.cpp
  72. 64 0
      workspaces/vc8/assimp.vcproj

+ 5 - 3
code/3DSLoader.cpp

@@ -109,9 +109,10 @@ bool Discreet3DSImporter::CanRead( const std::string& pFile, IOSystem* pIOHandle
 
 // ------------------------------------------------------------------------------------------------
 // Get list of all extension supported by this loader
-void Discreet3DSImporter::GetExtensionList(std::string& append)
+void Discreet3DSImporter::GetExtensionList(std::set<std::string>& extensions)
 {
-	append.append("*.3ds;*.prj");
+	extensions.insert("3ds");
+	extensions.insert("prj");
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -130,8 +131,9 @@ void Discreet3DSImporter::InternReadFile( const std::string& pFile,
 	this->stream = &stream;
 
 	// We should have at least one chunk
-	if (stream.GetRemainingSize() < 16)
+	if (stream.GetRemainingSize() < 16) {
 		throw new ImportErrorException("3DS file is either empty or corrupt: " + pFile);
+	}
 
 	// Allocate our temporary 3DS representation
 	mScene = new D3DS::Scene();

+ 1 - 1
code/3DSLoader.h

@@ -92,7 +92,7 @@ protected:
 	/** Called by Importer::GetExtensionList() for each loaded importer.
 	 * See BaseImporter::GetExtensionList() for details
 	 */
-	void GetExtensionList(std::string& append);
+	void GetExtensionList(std::set<std::string>& extensions);
 
 	// -------------------------------------------------------------------
 	/** Imports the given file into the given scene structure. 

+ 4 - 2
code/ACLoader.cpp

@@ -137,9 +137,11 @@ bool AC3DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
 
 // ------------------------------------------------------------------------------------------------
 // Get list of file extensions handled by this loader
-void AC3DImporter::GetExtensionList(std::string& append)
+void AC3DImporter::GetExtensionList(std::set<std::string>& extensions)
 {
-	append.append("*.ac;*.acc;*.ac3d");
+	extensions.insert("ac");
+	extensions.insert("acc");
+	extensions.insert("ac3d");
 }
 
 // ------------------------------------------------------------------------------------------------

+ 1 - 1
code/ACLoader.h

@@ -189,7 +189,7 @@ protected:
 	// -------------------------------------------------------------------
 	/** Called by Importer::GetExtensionList() for each loaded importer.
 	 * See BaseImporter::GetExtensionList() for details */
-	void GetExtensionList(std::string& append);
+	void GetExtensionList(std::set<std::string>& extensions);
 
 	// -------------------------------------------------------------------
 	/** Imports the given file into the given scene structure. 

+ 3 - 2
code/ASELoader.cpp

@@ -87,9 +87,10 @@ bool ASEImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
 }
 
 // ------------------------------------------------------------------------------------------------
-void ASEImporter::GetExtensionList(std::string& append)
+void ASEImporter::GetExtensionList(std::set<std::string>& extensions)
 {
-	append.append("*.ase;*.ask");
+	extensions.insert("ase");
+	extensions.insert("ask");
 }
 
 // ------------------------------------------------------------------------------------------------

+ 1 - 1
code/ASELoader.h

@@ -86,7 +86,7 @@ protected:
 	/** Called by Importer::GetExtensionList() for each loaded importer.
 	 * See BaseImporter::GetExtensionList() for details
 	 */
-	void GetExtensionList(std::string& append);
+	void GetExtensionList(std::set<std::string>& extensions);
 
 	// -------------------------------------------------------------------
 	/** Imports the given file into the given scene structure. 

+ 1 - 2
code/Assimp.cpp

@@ -524,8 +524,7 @@ void aiGetExtensionList(aiString* szOut)
 	boost::mutex::scoped_lock lock(gMutex);
 #endif
 
-	if (!gActiveImports.empty())
-	{
+	if (!gActiveImports.empty()) {
 		(*(gActiveImports.begin())).second->GetExtensionList(*szOut);
 		return;
 	}

+ 2 - 2
code/B3DImporter.cpp

@@ -74,8 +74,8 @@ bool B3DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
 }
 
 // ------------------------------------------------------------------------------------------------
-void B3DImporter::GetExtensionList( std::string& append ){
-	append.append("*.b3d");
+void B3DImporter::GetExtensionList( std::set<std::string>& extensions ){
+	extensions.insert("b3d");
 }
 
 #ifdef DEBUG_B3D

+ 1 - 1
code/B3DImporter.h

@@ -60,7 +60,7 @@ public:
 
 protected:
 
-	virtual void GetExtensionList(std::string& append);
+	virtual void GetExtensionList(std::set<std::string>& extensions);
 	virtual void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
 
 private:

+ 2 - 2
code/BVHLoader.h

@@ -101,9 +101,9 @@ protected:
 	/** Called by Importer::GetExtensionList() for each loaded importer.
 	 * See BaseImporter::GetExtensionList() for details
 	 */
-	void GetExtensionList( std::string& append)
+	void GetExtensionList(std::set<std::string>& extensions)
 	{
-		append.append("*.bvh");
+		extensions.insert("bvh");
 	}
 
 	/** Imports the given file into the given scene structure. 

+ 60 - 37
code/BaseImporter.h

@@ -63,8 +63,7 @@ class ASSIMP_API ImportErrorException
 {
 public:
 	/** Constructor with arguments */
-	ImportErrorException( const std::string& pErrorText)
-	{
+	ImportErrorException( const std::string& pErrorText) {
 		mErrorText = pErrorText;
 	}
 
@@ -164,7 +163,7 @@ public:
 	 * the file extension is enough. If no suitable loader is found with
 	 * this strategy, CanRead() is called again, the 'checkSig' parameter
 	 * set to true this time. Now the implementation is expected to
-	 * perform a full check of the file format, possibly searching the
+	 * perform a full check of the file structure, possibly searching the
 	 * first bytes of the file for magic identifiers or keywords.
 	 *
 	 * @param pFile Path and file name of the file to be examined.
@@ -174,14 +173,12 @@ public:
 	 *   contents of the file to be loaded for magic bytes, keywords, etc
 	 *   to be able to load files with unknown/not existent file extensions.
 	 * @return true if the class can read this file, false if not.
-	 *
-	 * @note Sometimes ASSIMP uses this method to determine whether a
-	 * a given file extension is generally supported. In this case the
-	 * file extension is passed in the pFile parameter, pIOHandler is NULL
 	 */
-	virtual bool CanRead( const std::string& pFile, 
-		IOSystem* pIOHandler, bool checkSig) const = 0;
-
+	virtual bool CanRead( 
+		const std::string& pFile, 
+		IOSystem* pIOHandler, 
+		bool checkSig
+		) const = 0;
 
 	// -------------------------------------------------------------------
 	/** Imports the given file and returns the imported data.
@@ -201,7 +198,10 @@ public:
 	 * in InternReadFile(), this function will catch it and transform it into
 	 *  a suitable response to the caller.
 	 */
-	aiScene* ReadFile( const std::string& pFile, IOSystem* pIOHandler);
+	aiScene* ReadFile(
+		const std::string& pFile, 
+		IOSystem* pIOHandler
+		);
 
 	// -------------------------------------------------------------------
 	/** Returns the error description of the last error that occured. 
@@ -218,18 +218,22 @@ public:
 	 * basing on the Importer's configuration property list.
 	 * @param pImp Importer instance
 	 */
-	virtual void SetupProperties(const Importer* pImp);
+	virtual void SetupProperties(
+		const Importer* pImp
+		);
 
 protected:
 
 	// -------------------------------------------------------------------
 	/** Called by Importer::GetExtensionList() for each loaded importer.
-	 *  Importer implementations should append all file extensions
-	 *  which they supported to the passed string.
-	 *  Example: "*.blabb;*.quak;*.gug;*.foo" (no delimiter after the last!)
-	 * @param append Output string
-	 */
-	virtual void GetExtensionList(std::string& append) = 0;
+	 *  Implementations are expected to insert() all file extensions
+	 *  handled by them into the extension set. A loader capable of
+	 *  reading certain files with the extension BLA would place the
+	 *  string bla (lower-case!) in the output set.
+	 * @param extensions Output set. */
+	virtual void GetExtensionList(
+		std::set<std::string>& extensions
+		) = 0;
 
 	// -------------------------------------------------------------------
 	/** Imports the given file into the given scene structure. The 
@@ -274,10 +278,12 @@ protected:
 	 * @param pScene The scene object to hold the imported data.
 	 * NULL is not a valid parameter.
 	 * @param pIOHandler The IO handler to use for any file access.
-	 * NULL is not a valid parameter.
-	 */
-	virtual void InternReadFile( const std::string& pFile, 
-		aiScene* pScene, IOSystem* pIOHandler) = 0;
+	 * NULL is not a valid parameter. */
+	virtual void InternReadFile( 
+		const std::string& pFile, 
+		aiScene* pScene, 
+		IOSystem* pIOHandler
+		) = 0;
 
 public: // static utilities
 
@@ -295,11 +301,12 @@ public: // static utilities
 	 *  @param numTokens Size of the token array
 	 *  @param searchBytes Number of bytes to be searched for the tokens.
 	 */
-	static bool SearchFileHeaderForToken(IOSystem* pIOSystem, 
+	static bool SearchFileHeaderForToken(
+		IOSystem* pIOSystem, 
 		const std::string&	file,
-		const char**		tokens, 
-		unsigned int		numTokens,
-		unsigned int		searchBytes = 200);
+		const char** tokens, 
+		unsigned int numTokens,
+		unsigned int searchBytes = 200);
 
 
 	// -------------------------------------------------------------------
@@ -310,7 +317,8 @@ public: // static utilities
 	 *  @param ext2 Optional third extension
 	 *  @note Case-insensitive
 	 */
-	static bool SimpleExtensionCheck (const std::string& pFile, 
+	static bool SimpleExtensionCheck (
+		const std::string& pFile, 
 		const char* ext0,
 		const char* ext1 = NULL,
 		const char* ext2 = NULL);
@@ -320,7 +328,8 @@ public: // static utilities
 	 *  @param pFile Input file
 	 *  @return Extension without trailing dot, all lowercase
 	 */
-	static std::string GetExtension (const std::string& pFile);
+	static std::string GetExtension (
+		const std::string& pFile);
 
 	// -------------------------------------------------------------------
 	/** @brief Check whether a file starts with one or more magic tokens
@@ -336,7 +345,9 @@ public: // static utilities
 	 *  byte-swapped variant of all tokens (big endian). Only for
 	 *  tokens of size 2,4.
 	 */
-	static bool CheckMagicToken(IOSystem* pIOHandler, const std::string& pFile, 
+	static bool CheckMagicToken(
+		IOSystem* pIOHandler, 
+		const std::string& pFile, 
 		const void* magic,
 		unsigned int num,
 		unsigned int offset = 0,
@@ -348,7 +359,8 @@ public: // static utilities
 	 *
 	 *  @param data File buffer to be converted to UTF8 data. The buffer 
 	 *  is resized as appropriate. */
-	static void ConvertToUTF8(std::vector<char>& data);
+	static void ConvertToUTF8(
+		std::vector<char>& data);
 
 	// -------------------------------------------------------------------
 	/** Utility for text file loaders which copies the contents of the
@@ -358,7 +370,8 @@ public: // static utilities
 	 *  @param data Output buffer to be resized and filled with the
 	 *   converted text file data. The buffer is terminated with
 	 *   a binary 0. */
-	static void TextFileToBuffer(IOStream* stream,
+	static void TextFileToBuffer(
+		IOStream* stream,
 		std::vector<char>& data);
 
 protected:
@@ -377,7 +390,7 @@ struct BatchData;
  *  could, this has not yet been implemented at the moment).
  *
  *  @note The class may not be used by more than one thread*/
-class ASSIMP_API BatchLoader
+class ASSIMP_API BatchLoader 
 {
 	// friend of Importer
 
@@ -408,10 +421,12 @@ public:
 	
 
 	// -------------------------------------------------------------------
-	/** Construct a batch loader from a given IO system to be used to acess external files */
+	/** Construct a batch loader from a given IO system to be used 
+	 *  to acess external files */
 	BatchLoader(IOSystem* pIO);
 	~BatchLoader();
 
+
 	// -------------------------------------------------------------------
 	/** Add a new file to the list of files to be loaded.
 	 *  @param file File to be loaded
@@ -420,8 +435,12 @@ public:
 	 *  @return 'Load request channel' - an unique ID that can later
 	 *    be used to access the imported file data.
 	 *  @see GetImport */
-	unsigned int AddLoadRequest	(const std::string& file,
-		unsigned int steps = 0, const PropertyMap* map = NULL);
+	unsigned int AddLoadRequest	(
+		const std::string& file,
+		unsigned int steps = 0, 
+		const PropertyMap* map = NULL
+		);
+
 
 	// -------------------------------------------------------------------
 	/** Get an imported scene.
@@ -432,10 +451,14 @@ public:
 	 *  @param which LRWC returned by AddLoadRequest().
 	 *  @return NULL if there is no scene with this file name
 	 *  in the queue of the scene hasn't been loaded yet. */
-	aiScene* GetImport	(unsigned int which);
+	aiScene* GetImport(
+		unsigned int which
+		);
+
 
 	// -------------------------------------------------------------------
-	/** Waits until all scenes have been loaded.  */
+	/** Waits until all scenes have been loaded. This returns
+	 *  immediately if no scenes are queued.*/
 	void LoadAll();
 
 private:

+ 2 - 2
code/CSMLoader.cpp

@@ -83,9 +83,9 @@ bool CSMImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
 
 // ------------------------------------------------------------------------------------------------
 // Build a string of all file extensions supported
-void CSMImporter::GetExtensionList(std::string& append)
+void CSMImporter::GetExtensionList(std::set<std::string>& extensions)
 {
-	append.append("*.csm");
+	extensions.insert("csm");
 }
 
 // ------------------------------------------------------------------------------------------------

+ 1 - 1
code/CSMLoader.h

@@ -76,7 +76,7 @@ public:
 protected:
 
 	// -------------------------------------------------------------------
-	void GetExtensionList(std::string& append);
+	void GetExtensionList(std::set<std::string>& extensions);
 
 
 	// -------------------------------------------------------------------

+ 2 - 2
code/ColladaLoader.cpp

@@ -91,9 +91,9 @@ bool ColladaLoader::CanRead( const std::string& pFile, IOSystem* pIOHandler, boo
 
 // ------------------------------------------------------------------------------------------------
 // Get file extension list
-void ColladaLoader::GetExtensionList( std::string& append)
+void ColladaLoader::GetExtensionList( std::set<std::string>& extensions )
 {
-	append.append("*.dae");
+	extensions.insert("dae");
 }
 
 // ------------------------------------------------------------------------------------------------

+ 1 - 1
code/ColladaLoader.h

@@ -96,7 +96,7 @@ protected:
 	/** Called by Importer::GetExtensionList() for each loaded importer.
 	 * See BaseImporter::GetExtensionList() for details
 	 */
-	void GetExtensionList( std::string& append);
+	void GetExtensionList( std::set<std::string>& extensions);
 
 	/** Imports the given file into the given scene structure. 
 	 * See BaseImporter::InternReadFile() for details

+ 2 - 2
code/DXFLoader.cpp

@@ -101,9 +101,9 @@ bool DXFImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
 
 // ------------------------------------------------------------------------------------------------
 // Get a list of all supported file extensions
-void DXFImporter::GetExtensionList(std::string& append)
+void DXFImporter::GetExtensionList(std::set<std::string>& extensions)
 {
-	append.append("*.dxf");
+	extensions.insert("dxf");
 }
 
 // ------------------------------------------------------------------------------------------------

+ 1 - 1
code/DXFLoader.h

@@ -96,7 +96,7 @@ protected:
 	/** Called by Importer::GetExtensionList() for each loaded importer.
 	 * See BaseImporter::GetExtensionList() for details
 	 */
-	void GetExtensionList(std::string& append);
+	void GetExtensionList(std::set<std::string>& extensions);
 
 	// -------------------------------------------------------------------
 	/** Imports the given file into the given scene structure. 

+ 2 - 2
code/HMPLoader.cpp

@@ -86,9 +86,9 @@ bool HMPImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
 
 // ------------------------------------------------------------------------------------------------
 // Get list of all file extensions that are handled by this loader
-void HMPImporter::GetExtensionList(std::string& append)
+void HMPImporter::GetExtensionList(std::set<std::string>& extensions)
 {
-	append.append("*.hmp");
+	extensions.insert("hmp");
 }
 
 // ------------------------------------------------------------------------------------------------

+ 1 - 1
code/HMPLoader.h

@@ -87,7 +87,7 @@ protected:
 	/** Called by Importer::GetExtensionList() for each loaded importer.
 	 * See BaseImporter::GetExtensionList() for details
 	 */
-	void GetExtensionList(std::string& append);
+	void GetExtensionList(std::set<std::string>& extensions);
 
 	// -------------------------------------------------------------------
 	/** Imports the given file into the given scene structure. 

+ 3 - 6
code/IRRLoader.cpp

@@ -103,13 +103,10 @@ bool IRRImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
 }
 
 // ------------------------------------------------------------------------------------------------
-void IRRImporter::GetExtensionList(std::string& append)
+void IRRImporter::GetExtensionList(std::set<std::string>& extensions)
 {
-	/*  NOTE: The file extenxsion .xml is too generic. We'll 
-	*  need to open the file in CanRead() and check whether it is 
-	*  a real irrlicht file
-	*/
-	append.append("*.xml;*.irr");
+	extensions.insert("irr");
+	extensions.insert("xml");
 }
 
 // ------------------------------------------------------------------------------------------------

+ 1 - 1
code/IRRLoader.h

@@ -84,7 +84,7 @@ protected:
 	// -------------------------------------------------------------------
 	/**
 	 */
-	void GetExtensionList(std::string& append);
+	void GetExtensionList(std::set<std::string>& extensions);
 
 	// -------------------------------------------------------------------
 	/** 

+ 3 - 3
code/IRRMeshLoader.cpp

@@ -88,10 +88,10 @@ bool IRRMeshImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, b
 
 // ------------------------------------------------------------------------------------------------
 // Get a list of all file extensions which are handled by this class
-void IRRMeshImporter::GetExtensionList(std::string& append)
+void IRRMeshImporter::GetExtensionList(std::set<std::string>& extensions)
 {
-	// fixme: consider cleaner handling of xml extension
-	append.append("*.xml;*.irrmesh");
+	extensions.insert("xml");
+	extensions.insert("irrmesh");
 }
 
 // ------------------------------------------------------------------------------------------------

+ 1 - 1
code/IRRMeshLoader.h

@@ -83,7 +83,7 @@ protected:
 	/** Called by Importer::GetExtensionList() for each loaded importer.
 	 * See BaseImporter::GetExtensionList() for details
 	 */
-	void GetExtensionList(std::string& append);
+	void GetExtensionList(std::set<std::string>& extensions);
 
 	// -------------------------------------------------------------------
 	/** Imports the given file into the given scene structure. 

+ 76 - 62
code/Importer.cpp

@@ -530,24 +530,26 @@ aiReturn Importer::RegisterLoader(BaseImporter* pImp)
 	// --------------------------------------------------------------------
 	// Check whether we would have two loaders for the same file extension 
 	// This is absolutely OK, but we should warn the developer of the new
-	// loader that his code will probably never be called.s
+	// loader that his code will probably never be called if the first 
+	// loader is a bit too lazy in his file checking.
 	// --------------------------------------------------------------------
-	std::string st;
+	std::set<std::string> st;
+	std::string baked;
 	pImp->GetExtensionList(st);
 
+	for(std::set<std::string>::const_iterator it = st.begin(); it != st.end(); ++it) {
+
 #ifdef _DEBUG
-	const char* sz = ::strtok(const_cast<char*>(st.c_str()),";"); // evil
-	while (sz)	{
-		if (IsExtensionSupported(std::string(sz)))
-			DefaultLogger::get()->warn(std::string( "The file extension " ) + sz + " is already in use");
-		
-		sz = ::strtok(NULL,";");
-	}
+		if (IsExtensionSupported(*it)) {
+			DefaultLogger::get()->warn("The file extension " + *it + " is already in use");
+		}
 #endif
+		baked += *it;
+	}
 
 	// add the loader
 	pimpl->mImporter.push_back(pImp);
-	DefaultLogger::get()->info("Registering custom importer: " + st);
+	DefaultLogger::get()->info("Registering custom importer for these file extensions: " + baked);
 	return AI_SUCCESS;
 }
 
@@ -555,14 +557,19 @@ aiReturn Importer::RegisterLoader(BaseImporter* pImp)
 // Unregister a custom loader plugin
 aiReturn Importer::UnregisterLoader(BaseImporter* pImp)
 {
-	ai_assert(NULL != pImp);
+	if(!pImp) {
+		// unregistering a NULL importer is no problem for us ... really!
+		return AI_SUCCESS;
+	}
+
 	std::vector<BaseImporter*>::iterator it = std::find(pimpl->mImporter.begin(),pimpl->mImporter.end(),pImp);
 	if (it != pimpl->mImporter.end())	{
 		pimpl->mImporter.erase(it);
 
-		std::string st;
+		std::set<std::string> st;
 		pImp->GetExtensionList(st);
-		DefaultLogger::get()->info("Unregistering custom importer: " + st);
+
+		DefaultLogger::get()->info("Unregistering custom importer: ");
 		return AI_SUCCESS;
 	}
 	DefaultLogger::get()->warn("Unable to remove custom importer: I can't find you ...");
@@ -573,7 +580,11 @@ aiReturn Importer::UnregisterLoader(BaseImporter* pImp)
 // Unregister a custom loader plugin
 aiReturn Importer::UnregisterPPStep(BaseProcess* pImp)
 {
-	ai_assert(NULL != pImp);
+	if(!pImp) {
+		// unregistering a NULL ppstep is no problem for us ... really!
+		return AI_SUCCESS;
+	}
+
 	std::vector<BaseProcess*>::iterator it = std::find(pimpl->mPostProcessingSteps.begin(),pimpl->mPostProcessingSteps.end(),pImp);
 	if (it != pimpl->mPostProcessingSteps.end())	{
 		pimpl->mPostProcessingSteps.erase(it);
@@ -949,22 +960,27 @@ bool Importer::IsExtensionSupported(const char* szExtension)
 
 // ------------------------------------------------------------------------------------------------
 // Find a loader plugin for a given file extension
-BaseImporter* Importer::FindLoader (const char* _szExtension)
+BaseImporter* Importer::FindLoader (const char* szExtension)
 {
-	std::string ext(_szExtension);
+	ai_assert(szExtension);
+
+	// skip over wildcard and dot characters at string head --
+	for(;*szExtension == '*' || *szExtension == '.'; ++szExtension);
+
+	std::string ext(szExtension);
 	if (ext.length() <= 1)
 		return NULL;
 
-	if (ext[0] != '.') {
-		// trailing dot is explicitly requested in the doc but we don't care for now ..
-		ext.erase(0,1);
-	}
-
+	std::set<std::string> str;
 	for (std::vector<BaseImporter*>::const_iterator i =  pimpl->mImporter.begin();i != pimpl->mImporter.end();++i)	{
+		str.clear();
 
-		// pass the file extension to the CanRead(..,NULL)-method
-		if ((*i)->CanRead(ext,NULL,false))
-			return *i;
+		(*i)->GetExtensionList(str);
+		for (std::set<std::string>::const_iterator it = str.begin(); it != str.end(); ++it) {
+			if (ext == *it) {
+				return (*i);
+			}
+		}
 	}
 	return NULL;
 }
@@ -973,20 +989,20 @@ BaseImporter* Importer::FindLoader (const char* _szExtension)
 // Helper function to build a list of all file extensions supported by ASSIMP
 void Importer::GetExtensionList(aiString& szOut)
 {
-	unsigned int iNum = 0;
-	std::string tmp; 
-	for (std::vector<BaseImporter*>::const_iterator i = pimpl->mImporter.begin();i != pimpl->mImporter.end();++i,++iNum)
-	{
-		// Insert a comma as delimiter character
-		// FIX: to take lazy loader implementations into account, we are
-		// slightly more tolerant here than we'd need to be.
-		if (0 != iNum && ';' != *(tmp.end()-1))
-			tmp.append(";");
+	std::set<std::string> str;
+	for (std::vector<BaseImporter*>::const_iterator i =  pimpl->mImporter.begin();i != pimpl->mImporter.end();++i)	{
+		(*i)->GetExtensionList(str);
+	}
+
+	for (std::set<std::string>::const_iterator it = str.begin();; ) {
+		szOut.Append("*.");
+		szOut.Append((*it).c_str());
 
-		(*i)->GetExtensionList(tmp);
+		if (++it == str.end()) {
+			break;
+		}
+		szOut.Append(";");
 	}
-	szOut.Set(tmp);
-	return;
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -1044,8 +1060,10 @@ inline void AddNodeWeight(unsigned int& iScene,const aiNode* pcNode)
 	iScene += sizeof(aiNode);
 	iScene += sizeof(unsigned int) * pcNode->mNumMeshes;
 	iScene += sizeof(void*) * pcNode->mNumChildren;
-	for (unsigned int i = 0; i < pcNode->mNumChildren;++i)
+	
+	for (unsigned int i = 0; i < pcNode->mNumChildren;++i) {
 		AddNodeWeight(iScene,pcNode->mChildren[i]);
+	}
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -1066,32 +1084,33 @@ void Importer::GetMemoryRequirements(aiMemoryInfo& in) const
 	for (unsigned int i = 0; i < mScene->mNumMeshes;++i)
 	{
 		in.meshes += sizeof(aiMesh);
-		if (mScene->mMeshes[i]->HasPositions())
+		if (mScene->mMeshes[i]->HasPositions()) {
 			in.meshes += sizeof(aiVector3D) * mScene->mMeshes[i]->mNumVertices;
+		}
 
-		if (mScene->mMeshes[i]->HasNormals())
+		if (mScene->mMeshes[i]->HasNormals()) {
 			in.meshes += sizeof(aiVector3D) * mScene->mMeshes[i]->mNumVertices;
+		}
 
-		if (mScene->mMeshes[i]->HasTangentsAndBitangents())
+		if (mScene->mMeshes[i]->HasTangentsAndBitangents()) {
 			in.meshes += sizeof(aiVector3D) * mScene->mMeshes[i]->mNumVertices * 2;
+		}
 
-		for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS;++a)
-		{
-			if (mScene->mMeshes[i]->HasVertexColors(a))
+		for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS;++a) {
+			if (mScene->mMeshes[i]->HasVertexColors(a)) {
 				in.meshes += sizeof(aiColor4D) * mScene->mMeshes[i]->mNumVertices;
+			}
 			else break;
 		}
-		for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS;++a)
-		{
-			if (mScene->mMeshes[i]->HasTextureCoords(a))
+		for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS;++a) {
+			if (mScene->mMeshes[i]->HasTextureCoords(a)) {
 				in.meshes += sizeof(aiVector3D) * mScene->mMeshes[i]->mNumVertices;
+			}
 			else break;
 		}
-		if (mScene->mMeshes[i]->HasBones())
-		{
+		if (mScene->mMeshes[i]->HasBones()) {
 			in.meshes += sizeof(void*) * mScene->mMeshes[i]->mNumBones;
-			for (unsigned int p = 0; p < mScene->mMeshes[i]->mNumBones;++p)
-			{
+			for (unsigned int p = 0; p < mScene->mMeshes[i]->mNumBones;++p) {
 				in.meshes += sizeof(aiBone);
 				in.meshes += mScene->mMeshes[i]->mBones[p]->mNumWeights * sizeof(aiVertexWeight);
 			}
@@ -1101,12 +1120,10 @@ void Importer::GetMemoryRequirements(aiMemoryInfo& in) const
     in.total += in.meshes;
 
 	// add all embedded textures
-	for (unsigned int i = 0; i < mScene->mNumTextures;++i)
-	{
+	for (unsigned int i = 0; i < mScene->mNumTextures;++i) {
 		const aiTexture* pc = mScene->mTextures[i];
 		in.textures += sizeof(aiTexture);
-		if (pc->mHeight)
-		{
+		if (pc->mHeight) {
 			in.textures += 4 * pc->mHeight * pc->mWidth;
 		}
 		else in.textures += pc->mWidth;
@@ -1114,14 +1131,12 @@ void Importer::GetMemoryRequirements(aiMemoryInfo& in) const
 	in.total += in.textures;
 
 	// add all animations
-	for (unsigned int i = 0; i < mScene->mNumAnimations;++i)
-	{
+	for (unsigned int i = 0; i < mScene->mNumAnimations;++i) {
 		const aiAnimation* pc = mScene->mAnimations[i];
 		in.animations += sizeof(aiAnimation);
 
 		// add all bone anims
-		for (unsigned int a = 0; a < pc->mNumChannels; ++a)
-		{
+		for (unsigned int a = 0; a < pc->mNumChannels; ++a) {
 			const aiNodeAnim* pc2 = pc->mChannels[i];
 			in.animations += sizeof(aiNodeAnim);
 			in.animations += pc2->mNumPositionKeys * sizeof(aiVectorKey);
@@ -1140,13 +1155,12 @@ void Importer::GetMemoryRequirements(aiMemoryInfo& in) const
 	in.total += in.nodes;
 
 	// add all materials
-	for (unsigned int i = 0; i < mScene->mNumMaterials;++i)
-	{
+	for (unsigned int i = 0; i < mScene->mNumMaterials;++i) {
 		const aiMaterial* pc = mScene->mMaterials[i];
 		in.materials += sizeof(aiMaterial);
 		in.materials += pc->mNumAllocated * sizeof(void*);
-		for (unsigned int a = 0; a < pc->mNumProperties;++a)
-		{
+
+		for (unsigned int a = 0; a < pc->mNumProperties;++a) {
 			in.materials += pc->mProperties[a]->mDataLength;
 		}
 	}

+ 3 - 2
code/LWOLoader.h

@@ -100,9 +100,10 @@ protected:
 	/** Called by Importer::GetExtensionList() for each loaded importer.
 	 * See BaseImporter::GetExtensionList() for details
 	 */
-	void GetExtensionList(std::string& append)
+	void GetExtensionList(std::set<std::string>& extensions)
 	{
-		append.append("*.lwo;*.lxo");
+		extensions.insert("lxo");
+		extensions.insert("lwo");
 	}
 
 	// -------------------------------------------------------------------

+ 3 - 2
code/LWSLoader.cpp

@@ -140,9 +140,10 @@ bool LWSImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler,bool c
 
 // ------------------------------------------------------------------------------------------------
 // Get list of file extensions
-void LWSImporter::GetExtensionList(std::string& append)
+void LWSImporter::GetExtensionList(std::set<std::string>& extensions)
 {
-	append.append("*.lws;*.mot");
+	extensions.insert("lws");
+	extensions.insert("mot");
 }
 
 // ------------------------------------------------------------------------------------------------

+ 1 - 1
code/LWSLoader.h

@@ -186,7 +186,7 @@ protected:
 
 	// -------------------------------------------------------------------
 	// Get list of supported extensions
-	void GetExtensionList(std::string& append);
+	void GetExtensionList(std::set<std::string>& extensions);
 
 	// -------------------------------------------------------------------
 	// Import file into given scene data structure

+ 2 - 2
code/MD2Loader.cpp

@@ -99,9 +99,9 @@ bool MD2Importer::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
 
 // ------------------------------------------------------------------------------------------------
 // Get a list of all extensions supported by this loader
-void MD2Importer::GetExtensionList(std::string& append)
+void MD2Importer::GetExtensionList(std::set<std::string>& extensions)
 {
-	append.append("*.md2");
+	extensions.insert("md2");
 }
 
 // ------------------------------------------------------------------------------------------------

+ 1 - 1
code/MD2Loader.h

@@ -91,7 +91,7 @@ protected:
 	/** Called by Importer::GetExtensionList() for each loaded importer.
 	 * See BaseImporter::GetExtensionList() for details
 	 */
-	void GetExtensionList(std::string& append);
+	void GetExtensionList(std::set<std::string>& extensions);
 
 	// -------------------------------------------------------------------
 	/** Imports the given file into the given scene structure. 

+ 13 - 6
code/MD3Loader.cpp

@@ -401,20 +401,27 @@ void MD3Importer::ValidateSurfaceHeaderOffsets(const MD3::Surface* pcSurf)
 
 	// Check whether all requirements for Q3 files are met. We don't
 	// care, but probably someone does.
-	if (pcSurf->NUM_TRIANGLES > AI_MD3_MAX_TRIANGLES)
+	if (pcSurf->NUM_TRIANGLES > AI_MD3_MAX_TRIANGLES) {
 		DefaultLogger::get()->warn("MD3: Quake III triangle limit exceeded");
-	if (pcSurf->NUM_SHADER > AI_MD3_MAX_SHADERS)
+	}
+
+	if (pcSurf->NUM_SHADER > AI_MD3_MAX_SHADERS) {
 		DefaultLogger::get()->warn("MD3: Quake III shader limit exceeded");
-	if (pcSurf->NUM_VERTICES > AI_MD3_MAX_VERTS)
+	}
+
+	if (pcSurf->NUM_VERTICES > AI_MD3_MAX_VERTS) {
 		DefaultLogger::get()->warn("MD3: Quake III vertex limit exceeded");
-	if (pcSurf->NUM_FRAMES > AI_MD3_MAX_FRAMES)
+	}
+
+	if (pcSurf->NUM_FRAMES > AI_MD3_MAX_FRAMES) {
 		DefaultLogger::get()->warn("MD3: Quake III frame limit exceeded");
+	}
 }
 
 // ------------------------------------------------------------------------------------------------
-void MD3Importer::GetExtensionList(std::string& append)
+void MD3Importer::GetExtensionList(std::set<std::string>& extensions)
 {
-	append.append("*.md3");
+	extensions.insert("md3");
 }
 
 // ------------------------------------------------------------------------------------------------

+ 1 - 1
code/MD3Loader.h

@@ -242,7 +242,7 @@ protected:
 	/** Called by Importer::GetExtensionList() for each loaded importer.
 	 * See BaseImporter::GetExtensionList() for details
 	 */
-	void GetExtensionList(std::string& append);
+	void GetExtensionList(std::set<std::string>& extensions);
 
 	// -------------------------------------------------------------------
 	/** Imports the given file into the given scene structure. 

+ 4 - 2
code/MD5Loader.cpp

@@ -89,9 +89,11 @@ bool MD5Importer::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
 
 // ------------------------------------------------------------------------------------------------
 // Get list of all supported extensions
-void MD5Importer::GetExtensionList(std::string& append)
+void MD5Importer::GetExtensionList(std::set<std::string>& extensions)
 {
-	append.append("*.md5mesh;*.md5anim;*.md5camera");
+	extensions.insert("md5anim");
+	extensions.insert("md5mesh");
+	extensions.insert("md5camera");
 }
 
 // ------------------------------------------------------------------------------------------------

+ 1 - 1
code/MD5Loader.h

@@ -85,7 +85,7 @@ protected:
 	/** Called by Importer::GetExtensionList() for each loaded importer.
 	 * See BaseImporter::GetExtensionList() for details
 	 */
-	void GetExtensionList(std::string& append);
+	void GetExtensionList(std::set<std::string>& extensions);
 
 	// -------------------------------------------------------------------
 	/** Called prior to ReadFile().

+ 2 - 2
code/MDCLoader.cpp

@@ -103,9 +103,9 @@ bool MDCImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
 }
 
 // ------------------------------------------------------------------------------------------------
-void MDCImporter::GetExtensionList(std::string& append)
+void MDCImporter::GetExtensionList(std::set<std::string>& extensions)
 {
-	append.append("*.mdc");
+	extensions.insert("mdc");
 }
 
 // ------------------------------------------------------------------------------------------------

+ 1 - 1
code/MDCLoader.h

@@ -88,7 +88,7 @@ protected:
 	/** Called by Importer::GetExtensionList() for each loaded importer.
 	 * See BaseImporter::GetExtensionList() for details
 	 */
-	void GetExtensionList(std::string& append);
+	void GetExtensionList(std::set<std::string>& extensions);
 
 	// -------------------------------------------------------------------
 	/** Imports the given file into the given scene structure. 

+ 2 - 2
code/MDLLoader.cpp

@@ -117,9 +117,9 @@ void MDLImporter::SetupProperties(const Importer* pImp)
 
 // ------------------------------------------------------------------------------------------------
 // Get a list of all supported extensions
-void MDLImporter::GetExtensionList(std::string& append)
+void MDLImporter::GetExtensionList(std::set<std::string>& extensions)
 {
-	append.append( ".mdl" );
+	extensions.insert( "mdl" );
 }
 
 // ------------------------------------------------------------------------------------------------

+ 1 - 1
code/MDLLoader.h

@@ -114,7 +114,7 @@ protected:
 	/** Called by Importer::GetExtensionList() for each loaded importer.
 	 * See BaseImporter::GetExtensionList() for details
 	 */
-	void GetExtensionList(std::string& append);
+	void GetExtensionList(std::set<std::string>& extensions);
 
 	// -------------------------------------------------------------------
 	/** Imports the given file into the given scene structure. 

+ 2 - 2
code/MS3DLoader.cpp

@@ -84,9 +84,9 @@ bool MS3DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
 }
 
 // ------------------------------------------------------------------------------------------------
-void MS3DImporter::GetExtensionList(std::string& append)
+void MS3DImporter::GetExtensionList(std::set<std::string>& extensions)
 {
-	append.append("*.ms3d");
+	extensions.insert("ms3d");
 }
 
 // ------------------------------------------------------------------------------------------------

+ 1 - 1
code/MS3DLoader.h

@@ -73,7 +73,7 @@ protected:
 	// -------------------------------------------------------------------
 	/** Called by Importer::GetExtensionList() for each loaded importer.
 	 * See BaseImporter::GetExtensionList() for details */
-	void GetExtensionList(std::string& append);
+	void GetExtensionList(std::set<std::string>& extensions);
 
 	// -------------------------------------------------------------------
 	/** Imports the given file into the given scene structure. 

+ 3 - 2
code/NFFLoader.cpp

@@ -72,9 +72,10 @@ bool NFFImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
 
 // ------------------------------------------------------------------------------------------------
 // Get the list of all supported file extensions
-void NFFImporter::GetExtensionList(std::string& append)
+void NFFImporter::GetExtensionList(std::set<std::string>& extensions)
 {
-	append.append("*.nff;*.enff");
+	extensions.insert("enff");
+	extensions.insert("nff");
 }
 
 // ------------------------------------------------------------------------------------------------

+ 1 - 1
code/NFFLoader.h

@@ -84,7 +84,7 @@ protected:
 	/** Called by Importer::GetExtensionList() for each loaded importer.
 	 * See BaseImporter::GetExtensionList() for details
 	 */
-	void GetExtensionList(std::string& append);
+	void GetExtensionList(std::set<std::string>& extensions);
 
 	// -------------------------------------------------------------------
 	/** Imports the given file into the given scene structure. 

+ 2 - 2
code/OFFLoader.cpp

@@ -82,9 +82,9 @@ bool OFFImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
 }
 
 // ------------------------------------------------------------------------------------------------
-void OFFImporter::GetExtensionList(std::string& append)
+void OFFImporter::GetExtensionList(std::set<std::string>& extensions)
 {
-	append.append("*.off");
+	extensions.insert("off");
 }
 
 // ------------------------------------------------------------------------------------------------

+ 1 - 1
code/OFFLoader.h

@@ -78,7 +78,7 @@ protected:
 	/** Called by Importer::GetExtensionList() for each loaded importer.
 	 * See BaseImporter::GetExtensionList() for details
 	 */
-	void GetExtensionList(std::string& append);
+	void GetExtensionList(std::set<std::string>& extensions);
 
 	// -------------------------------------------------------------------
 	/** Imports the given file into the given scene structure. 

+ 3 - 3
code/ObjFileImporter.h

@@ -81,7 +81,7 @@ public:
 private:
 
 	//! \brief	Appends the supported extention.
-	void GetExtensionList(std::string& append);
+	void GetExtensionList(std::set<std::string>& extensions);
 
 	//!	\brief	File import implementation.
 	void InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
@@ -124,9 +124,9 @@ private:
 
 // ------------------------------------------------------------------------------------------------
 //	
-inline void ObjFileImporter::GetExtensionList(std::string& append)
+inline void ObjFileImporter::GetExtensionList(std::set<std::string>& extensions)
 {
-	append.append("*.obj");
+	extensions.insert("obj");
 }
 
 // ------------------------------------------------------------------------------------------------

+ 2 - 2
code/OgreImporter.cpp

@@ -129,9 +129,9 @@ void OgreImporter::InternReadFile(const std::string &pFile, aiScene *pScene, Ass
 
 
 
-void OgreImporter::GetExtensionList(std::string &append)
+void OgreImporter::GetExtensionList(std::set<std::string>& extensions)
 {
-	append+="*.mesh.xml";
+	extensions.insert("mesh.xml");
 }
 
 

+ 1 - 1
code/OgreImporter.h

@@ -26,7 +26,7 @@ class OgreImporter : public BaseImporter
 public:
 	virtual bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
 	virtual void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
-	virtual void GetExtensionList(std::string& append);
+	virtual void GetExtensionList(std::set<std::string>& extensions);
 	virtual void SetupProperties(const Importer* pImp);
 private:
 

+ 2 - 2
code/PlyLoader.cpp

@@ -80,9 +80,9 @@ bool PLYImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
 }
 
 // ------------------------------------------------------------------------------------------------
-void PLYImporter::GetExtensionList(std::string& append)
+void PLYImporter::GetExtensionList(std::set<std::string>& extensions)
 {
-	append.append("*.ply");
+	extensions.insert("ply");
 }
 
 // ------------------------------------------------------------------------------------------------

+ 1 - 1
code/PlyLoader.h

@@ -85,7 +85,7 @@ protected:
 	/** Called by Importer::GetExtensionList() for each loaded importer.
 	 * See BaseImporter::GetExtensionList() for details
 	 */
-	void GetExtensionList(std::string& append);
+	void GetExtensionList(std::set<std::string>& extensions);
 
 	// -------------------------------------------------------------------
 	/** Imports the given file into the given scene structure. 

+ 3 - 2
code/Q3DLoader.cpp

@@ -81,9 +81,10 @@ bool Q3DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
 }
 
 // ------------------------------------------------------------------------------------------------
-void Q3DImporter::GetExtensionList(std::string& append)
+void Q3DImporter::GetExtensionList(std::set<std::string>& extensions)
 {
-	append.append("*.q3o;*.q3s");
+	extensions.insert("q3o");
+	extensions.insert("q3s");
 }
 
 // ------------------------------------------------------------------------------------------------

+ 1 - 1
code/Q3DLoader.h

@@ -78,7 +78,7 @@ protected:
 	/** Called by Importer::GetExtensionList() for each loaded importer.
 	 * See BaseImporter::GetExtensionList() for details
 	 */
-	void GetExtensionList(std::string& append);
+	void GetExtensionList(std::set<std::string>& extensions);
 
 	// -------------------------------------------------------------------
 	/** Imports the given file into the given scene structure. 

+ 2 - 2
code/RawLoader.cpp

@@ -72,9 +72,9 @@ bool RAWImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
 
 // ------------------------------------------------------------------------------------------------
 // Get the list of all supported file extensions
-void RAWImporter::GetExtensionList(std::string& append)
+void RAWImporter::GetExtensionList(std::set<std::string>& extensions)
 {
-	append.append("*.raw");
+	extensions.insert("raw");
 }
 
 // ------------------------------------------------------------------------------------------------

+ 1 - 1
code/RawLoader.h

@@ -79,7 +79,7 @@ protected:
 	/** Called by Importer::GetExtensionList() for each loaded importer.
 	 * See BaseImporter::GetExtensionList() for details
 	 */
-	void GetExtensionList(std::string& append);
+	void GetExtensionList(std::set<std::string>& extensions);
 
 	// -------------------------------------------------------------------
 	/** Imports the given file into the given scene structure. 

+ 3 - 2
code/SMDLoader.cpp

@@ -73,9 +73,10 @@ bool SMDImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool)
 
 // ------------------------------------------------------------------------------------------------
 // Get a list of all supported file extensions
-void SMDImporter::GetExtensionList(std::string& append)
+void SMDImporter::GetExtensionList(std::set<std::string>& extensions)
 {
-	append.append("*.smd;*.vta");
+	extensions.insert("smd");
+	extensions.insert("vta");
 }
 
 // ------------------------------------------------------------------------------------------------

+ 1 - 1
code/SMDLoader.h

@@ -204,7 +204,7 @@ protected:
 	/** Called by Importer::GetExtensionList() for each loaded importer.
 	 * See BaseImporter::GetExtensionList() for details
 	 */
-	void GetExtensionList(std::string& append);
+	void GetExtensionList(std::set<std::string>& extensions);
 
 	// -------------------------------------------------------------------
 	/** Imports the given file into the given scene structure. 

+ 2 - 2
code/STLLoader.cpp

@@ -80,9 +80,9 @@ bool STLImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
 }
 
 // ------------------------------------------------------------------------------------------------
-void STLImporter::GetExtensionList(std::string& append)
+void STLImporter::GetExtensionList(std::set<std::string>& extensions)
 {
-	append.append("*.stl");
+	extensions.insert("stl");
 }
 
 // ------------------------------------------------------------------------------------------------

+ 1 - 1
code/STLLoader.h

@@ -78,7 +78,7 @@ protected:
 	/** Called by Importer::GetExtensionList() for each loaded importer.
 	 * See BaseImporter::GetExtensionList() for details
 	 */
-	void GetExtensionList(std::string& append);
+	void GetExtensionList(std::set<std::string>& extensions);
 
 	// -------------------------------------------------------------------
 	/** Imports the given file into the given scene structure. 

+ 2 - 2
code/TerragenLoader.cpp

@@ -83,9 +83,9 @@ bool TerragenImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler,
 
 // ------------------------------------------------------------------------------------------------
 // Build a string of all file extensions supported
-void TerragenImporter::GetExtensionList(std::string& append)
+void TerragenImporter::GetExtensionList(std::set<std::string>& extensions)
 {
-	append.append("*.ter;");
+	extensions.insert("ter");
 }
 
 // ------------------------------------------------------------------------------------------------

+ 1 - 1
code/TerragenLoader.h

@@ -87,7 +87,7 @@ public:
 protected:
 
 	// -------------------------------------------------------------------
-	void GetExtensionList(std::string& append);
+	void GetExtensionList(std::set<std::string>& extensions);
 
 	// -------------------------------------------------------------------
 	void InternReadFile( const std::string& pFile, aiScene* pScene, 

+ 4 - 3
code/UnrealLoader.cpp

@@ -79,9 +79,10 @@ bool UnrealImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bo
 
 // ------------------------------------------------------------------------------------------------
 // Build a string of all file extensions supported
-void UnrealImporter::GetExtensionList(std::string& append)
+void UnrealImporter::GetExtensionList(std::set<std::string>& extensions)
 {
-	append.append("*.3d;*.uc");
+	extensions.insert("3d");
+	extensions.insert("uc");
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -322,7 +323,7 @@ void UnrealImporter::InternReadFile( const std::string& pFile,
 			++pScene->mNumMeshes;
 		}
 		else {
-			tri.matIndex = nt-materials.begin();
+			tri.matIndex = static_cast<unsigned int>(nt-materials.begin());
 			++nt->numFaces;
 		}
 	}

+ 1 - 1
code/UnrealLoader.h

@@ -171,7 +171,7 @@ protected:
 	 *
 	 * See BaseImporter::GetExtensionList() for details
 	 */
-	void GetExtensionList(std::string& append);
+	void GetExtensionList(std::set<std::string>& extensions);
 
 
 	// -------------------------------------------------------------------

+ 2 - 2
code/XFileImporter.cpp

@@ -78,9 +78,9 @@ bool XFileImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, boo
 }
 
 // ------------------------------------------------------------------------------------------------
-void XFileImporter::GetExtensionList(std::string& append)
+void XFileImporter::GetExtensionList(std::set<std::string>& extensions)
 {
-	append.append("*.x");
+	extensions.insert("x");
 }
 
 // ------------------------------------------------------------------------------------------------

+ 1 - 1
code/XFileImporter.h

@@ -88,7 +88,7 @@ protected:
 	/** Called by Importer::GetExtensionList() for each loaded importer.
 	 * See BaseImporter::GetExtensionList() for details
 	 */
-	void GetExtensionList(std::string& append);
+	void GetExtensionList(std::set<std::string>& extensions);
 
 	// -------------------------------------------------------------------
 	/** Imports the given file into the given scene structure. 

+ 4 - 4
contrib/cppunit-1.12.1/src/cppunit/cppunit.vcproj

@@ -653,11 +653,11 @@
 				</FileConfiguration>
 			</File>
 			<File
-				RelativePath="..\..\include\cppunit\ui\text\TextTestRunner.h"
+				RelativePath="..\..\include\cppunit\TextTestRunner.h"
 				>
 			</File>
 			<File
-				RelativePath="..\..\include\cppunit\TextTestRunner.h"
+				RelativePath="..\..\include\cppunit\ui\text\TextTestRunner.h"
 				>
 			</File>
 		</Filter>
@@ -2694,11 +2694,11 @@
 			>
 		</File>
 		<File
-			RelativePath="Makefile.am"
+			RelativePath="..\..\include\cppunit\Makefile.am"
 			>
 		</File>
 		<File
-			RelativePath="..\..\include\cppunit\Makefile.am"
+			RelativePath="Makefile.am"
 			>
 		</File>
 	</Files>

+ 2 - 2
doc/dox.h

@@ -964,9 +964,9 @@ bool xxxxImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler,
 
 // -------------------------------------------------------------------------------
 // Get list of file extensions handled by this loader
-void xxxxImporter::GetExtensionList(std::string& append)
+void xxxxImporter::GetExtensionList(std::set<std::string>& extensions)
 {
-	append.append("*.xxx");
+	extensions.insert("xxx");
 }
 
 // -------------------------------------------------------------------------------

+ 43 - 39
include/assimp.hpp

@@ -329,7 +329,9 @@ public:
 	 * automatically. However, to enable automatic detection of the file
 	 * format, the input path *must* not have an extension at all.
 	 */
-	const aiScene* ReadFile( const char* pFile, unsigned int pFlags);
+	const aiScene* ReadFile(
+		const char* pFile, 
+		unsigned int pFlags);
 
 	// -------------------------------------------------------------------
 	/** Reads the given file from a memory buffer and returns its
@@ -367,7 +369,8 @@ public:
 	 * external scripts. f you need the full functionality, provide
 	 * a custom IOSystem to make Assimp find these files.
 	 */
-	const aiScene* ReadFileFromMemory( const void* pBuffer,
+	const aiScene* ReadFileFromMemory( 
+		const void* pBuffer,
 		size_t pLength,
 		unsigned int pFlags,
 		const char* pHint = "");
@@ -389,8 +392,7 @@ public:
 	 *   cause the scene to be reset to NULL.
 	 *
 	 *  @note The method does nothing if no scene is currently bound
-	 *    to the #Importer instance. 
-	 */
+	 *    to the #Importer instance.  */
 	const aiScene* ApplyPostProcessing(unsigned int pFlags);
 
 	// -------------------------------------------------------------------
@@ -398,17 +400,17 @@ public:
 	 *
 	 * This function is provided for backward compatibility.
 	 * See the const char* version for detailled docs.
-	 * @see ReadFile(const char*, pFlags)
-	 */
-	const aiScene* ReadFile( const std::string& pFile, unsigned int pFlags);
+	 * @see ReadFile(const char*, pFlags)  */
+	const aiScene* ReadFile(
+		const std::string& pFile, 
+		unsigned int pFlags);
 
 	// -------------------------------------------------------------------
 	/** Frees the current scene.
 	 *
 	 *  The function does nothing if no scene has previously been 
 	 *  read via ReadFile(). FreeScene() is called automatically by the
-	 *  destructor and ReadFile() itself.
-	 */
+	 *  destructor and ReadFile() itself.  */
 	void FreeScene( );
 
 	// -------------------------------------------------------------------
@@ -419,65 +421,66 @@ public:
 	 *   error occurred. The string is never NULL.
 	 *
 	 * @note The returned function remains valid until one of the 
-	 * following methods is called: #ReadFile(), #FreeScene().
-	 */
+	 * following methods is called: #ReadFile(), #FreeScene(). */
 	const char* GetErrorString() const;
 
+
 	// -------------------------------------------------------------------
 	/** Returns whether a given file extension is supported by ASSIMP.
 	 *
 	 * @param szExtension Extension to be checked.
 	 *   Must include a trailing dot '.'. Example: ".3ds", ".md3".
 	 *   Cases-insensitive.
-	 * @return true if the extension is supported, false otherwise
-	 */
+	 * @return true if the extension is supported, false otherwise */
 	bool IsExtensionSupported(const char* szExtension);
 
 	// -------------------------------------------------------------------
 	/** @brief Returns whether a given file extension is supported by ASSIMP.
 	 *
 	 * This function is provided for backward compatibility.
-	 * See the const char* version for detailled docs.
-	 * @see IsExtensionSupported(const char*)
-	 */
+	 * See the const char* version for detailed and up-to-date docs.
+	 * @see IsExtensionSupported(const char*) */
 	inline bool IsExtensionSupported(const std::string& szExtension);
 
+
 	// -------------------------------------------------------------------
 	/** Get a full list of all file extensions supported by ASSIMP.
 	 *
 	 * If a file extension is contained in the list this does of course not
-	 * mean that ASSIMP is able to load all files with this extension.
-	 * @param szOut String to receive the extension list. It just means there
-     *   is a loader which handles such files.
-	 *   Format of the list: "*.3ds;*.obj;*.dae". 
-	 */
+	 * mean that ASSIMP is able to load all files with this extension ---
+     * it simply means there is an importer loaded which claims to handle
+	 * files with this file extension.
+	 * @param szOut String to receive the extension list. 
+	 *   Format of the list: "*.3ds;*.obj;*.dae". This is useful for
+	 *   use with the WinAPI call GetOpenFileName(Ex). */
 	void GetExtensionList(aiString& szOut);
 
 	// -------------------------------------------------------------------
 	/** @brief Get a full list of all file extensions supported by ASSIMP.
 	 *
 	 * This function is provided for backward compatibility.
-	 * See the aiString version for detailled docs.
-	 * @see GetExtensionList(aiString&)
-	 */
+	 * See the aiString version for detailed and up-to-date docs.
+	 * @see GetExtensionList(aiString&)*/
 	inline void GetExtensionList(std::string& szOut);
 
+
 	// -------------------------------------------------------------------
 	/** Find the loader corresponding to a specific file extension.
 	*
 	*  This is quite similar to IsExtensionSupported() except a
 	*  BaseImporter instance is returned.
-	*  @param szExtension Extension to be checked, cases insensitive,
-	*    must include a trailing dot.
-	*  @return NULL if there is no loader for the extension.
-	*/
+	*  @param szExtension Extension to check for. The following formats
+	*    are recgnized (BAH being the file extension): "BAH" (comparison
+	*    is case-insensitive), ".bah", "*.bah" (wild card and dot
+	*    characters at the beginning of the extension are skipped).
+	*  @return NULL if there is no loader for the extension.*/
 	BaseImporter* FindLoader (const char* szExtension);
 
+
 	// -------------------------------------------------------------------
 	/** Returns the scene loaded by the last successful call to ReadFile()
 	 *
-	 * @return Current scene or NULL if there is currently no scene loaded
-	 */
+	 * @return Current scene or NULL if there is currently no scene loaded */
 	const aiScene* GetScene() const;
 
 	// -------------------------------------------------------------------
@@ -488,9 +491,9 @@ public:
 	 *  will return NULL - until a new scene has been loaded via ReadFile().
 	 *
 	 * @return Current scene or NULL if there is currently no scene loaded
-	 * @note Under windows, deleting the returned scene manually will 
-	 * probably not work properly in applications using static runtime linkage.
-	 */
+	 * @note --- you know that the aiScene is allocated on Assimp's heap,
+	 *   so you need to call Assimp's delete if the heap is not shared?
+	 *   And that's why you shouldn't use this method at all. Thanks.*/
 	aiScene* GetOrphanedScene();
 
 	// -------------------------------------------------------------------
@@ -499,17 +502,18 @@ public:
 	 *
 	 * This refers to the currently loaded file, see #ReadFile().
 	 * @param in Data structure to be filled. 
-	*/
+	 * @note The returned memory statistics refer to the actual
+	 *   size of the use data of the aiScene. Heap-related overhead
+	 *   is (naturally) not included.*/
 	void GetMemoryRequirements(aiMemoryInfo& in) const;
 
 	// -------------------------------------------------------------------
 	/** Enables "extra verbose" mode. 
 	 *
-	 * In this mode the data structure is validated after every single
-	 * post processing step to make sure everyone modifies the data
-	 * structure in the defined manner. This is a debug feature and not
-	 * intended for public use.
-	 */
+	 * 'Extra verbose' means the data structure is validated after *every*
+	 * single post processing step to make sure everyone modifies the data
+	 * structure in a well-defined manner. This is a debug feature and not
+	 * intended for use in production environments. */
 	void SetExtraVerbose(bool bDo);
 
 protected:

+ 1 - 0
test/unit/Main.cpp

@@ -30,6 +30,7 @@ int main (int argc, char* argv[])
 		aiDefaultLogStream_FILE,
 		"AssimpLog_C.txt"));
 
+
 	// ............................................................................
 
     // Informiert Test-Listener ueber Testresultate

+ 9 - 6
test/unit/utImporter.cpp

@@ -2,7 +2,6 @@
 #include "UnitTestPCH.h"
 #include "utImporter.h"
 
-
 #define InputData_BLOCK_SIZE 1310
 
 // test data for Importer::ReadFileFromMemory() - ./test/3DS/CameraRollAnim.3ds
@@ -71,9 +70,12 @@ bool TestPlugin :: CanRead( const std::string& pFile,
 		extension == ".linux" || extension == ".windows" );
 }
 
-void TestPlugin :: GetExtensionList(std::string& append)
+void TestPlugin :: GetExtensionList(std::set<std::string>& extensions)
 {
-	append.append("*.apple;*.mac;*.linux;*.windows");
+	extensions.insert("apple");
+	extensions.insert("mac");
+	extensions.insert("linux");
+	extensions.insert("windows");
 }
 
 void TestPlugin :: InternReadFile( const std::string& pFile, 
@@ -135,12 +137,13 @@ void ImporterTest :: testStringProperty (void)
 
 void ImporterTest :: testPluginInterface (void)
 {
+	
 	pImp->RegisterLoader(new TestPlugin());
 	CPPUNIT_ASSERT(pImp->IsExtensionSupported(".apple"));
 	CPPUNIT_ASSERT(pImp->IsExtensionSupported(".mac"));
-	CPPUNIT_ASSERT(pImp->IsExtensionSupported(".linux"));
-	CPPUNIT_ASSERT(pImp->IsExtensionSupported(".windows"));
-	CPPUNIT_ASSERT(pImp->IsExtensionSupported(".x")); /* x and 3ds must be available of course */
+	CPPUNIT_ASSERT(pImp->IsExtensionSupported("*.linux"));
+	CPPUNIT_ASSERT(pImp->IsExtensionSupported("windows"));
+	CPPUNIT_ASSERT(pImp->IsExtensionSupported(".x")); /* x and 3ds must be available in this Assimp build, of course! */
 	CPPUNIT_ASSERT(pImp->IsExtensionSupported(".3ds"));
 	CPPUNIT_ASSERT(!pImp->IsExtensionSupported("."));
 

+ 1 - 1
test/unit/utImporter.h

@@ -49,7 +49,7 @@ public:
 		IOSystem* pIOHandler, bool test) const;
 
 	// overriden
-	void GetExtensionList(std::string& append);
+	void GetExtensionList(std::set<std::string>& extensions);
 
 	// overriden
 	void InternReadFile( const std::string& pFile, 

+ 3 - 3
test/unit/utLimitBoneWeights.cpp

@@ -37,15 +37,15 @@ void LimitBoneWeightsTest :: setUp (void)
 // ------------------------------------------------------------------------------------------------
 void LimitBoneWeightsTest :: tearDown (void)
 {
-	delete this->pcMesh;
-	delete this->piProcess;
+	delete pcMesh;
+	delete piProcess;
 }
 
 // ------------------------------------------------------------------------------------------------
 void LimitBoneWeightsTest :: testProcess(void)
 {
 	// execute the step on the given data
-	this->piProcess->ProcessMesh(this->pcMesh);
+	piProcess->ProcessMesh(pcMesh);
 
 	// check whether everything is ok ...
 	typedef std::vector<LimitBoneWeightsProcess::Weight> VertexWeightList;

+ 32 - 2
tools/assimp_cmd/Main.cpp

@@ -48,6 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 const char* AICMD_MSG_ABOUT = 
 "------------------------------------------------------ \n"
 "Open Asset Import Library (Assimp) \n"
+"http://assimp.sourceforge.net \n"
 "Command-line tools \n"
 "------------------------------------------------------ \n\n"
 
@@ -58,8 +59,15 @@ const char* AICMD_MSG_ABOUT =
 
 
 const char* AICMD_MSG_HELP = 
-"todo help";
-
+"assimp <verb> <arguments>\n\n"
+"\tverbs:\n"
+"\t\tversion - Display Assimp version\n"
+"\t\tlistext - List all known file extension\n"
+"\t\tknowext - Check whether a file extension is recognized by Assimp\n"
+"\t\textract - Extract an embedded texture from a model\n"
+"\t\tdump    - Convert a model to binary or XML dumps (ASSBIN/ASSXML)\n"
+"\n\n\tUse \'assimp <verb> --help\' to get detailed help for a command.\n"
+;
 
 /*extern*/ Assimp::Importer* globalImporter = NULL;
 
@@ -103,6 +111,28 @@ int main (int argc, char* argv[])
 	Assimp::Importer imp;
 	globalImporter = &imp;
 
+	// assimp listext
+	// List all file extensions supported by Assimp
+	if (! ::strcmp(argv[1], "listext")) {
+		aiString s;
+		imp.GetExtensionList(s);
+
+		printf(s.data);
+		return 0;
+	}
+
+	// assimp knowext
+	// Check whether a particular file extension is known by us, return 0 on success
+	if (! ::strcmp(argv[1], "knowext")) {
+		if (argc<3) {
+			printf("Expected a file extension to check for!");
+			return -10;
+		}
+		const bool b = imp.IsExtensionSupported(argv[2]);
+		printf("File extension %s is %sknown",argv[2],(b?"":"not "));
+		return b?0:-1;
+	}
+
 	// assimp dump 
 	// Dump a model to a file 
 	if (! ::strcmp(argv[1], "dump")) {

+ 1 - 1
tools/assimp_cmd/WriteDumb.cpp

@@ -934,7 +934,7 @@ void WriteDump(const aiScene* scene, FILE* out, const char* src, const char* cmd
 int Assimp_Dump (const char** params, unsigned int num)
 {
 	if (num < 1) {
-		::printf("assimp dump: Invalid number of arguments. See \'assimp extract --help\'\r\n");
+		::printf("assimp dump: Invalid number of arguments. See \'assimp dump --help\'\r\n");
 		return 1;
 	}
 

+ 64 - 0
workspaces/vc8/assimp.vcproj

@@ -3410,6 +3410,14 @@
 								UsePrecompiledHeader="0"
 							/>
 						</FileConfiguration>
+						<FileConfiguration
+							Name="debug|x64"
+							>
+							<Tool
+								Name="VCCLCompilerTool"
+								UsePrecompiledHeader="0"
+							/>
+						</FileConfiguration>
 						<FileConfiguration
 							Name="release|Win32"
 							>
@@ -3418,6 +3426,14 @@
 								UsePrecompiledHeader="0"
 							/>
 						</FileConfiguration>
+						<FileConfiguration
+							Name="release|x64"
+							>
+							<Tool
+								Name="VCCLCompilerTool"
+								UsePrecompiledHeader="0"
+							/>
+						</FileConfiguration>
 						<FileConfiguration
 							Name="release-dll|Win32"
 							>
@@ -3426,6 +3442,14 @@
 								UsePrecompiledHeader="0"
 							/>
 						</FileConfiguration>
+						<FileConfiguration
+							Name="release-dll|x64"
+							>
+							<Tool
+								Name="VCCLCompilerTool"
+								UsePrecompiledHeader="0"
+							/>
+						</FileConfiguration>
 						<FileConfiguration
 							Name="debug-dll|Win32"
 							>
@@ -3434,6 +3458,14 @@
 								UsePrecompiledHeader="0"
 							/>
 						</FileConfiguration>
+						<FileConfiguration
+							Name="debug-dll|x64"
+							>
+							<Tool
+								Name="VCCLCompilerTool"
+								UsePrecompiledHeader="0"
+							/>
+						</FileConfiguration>
 						<FileConfiguration
 							Name="release-noboost-st|Win32"
 							>
@@ -3442,6 +3474,14 @@
 								UsePrecompiledHeader="0"
 							/>
 						</FileConfiguration>
+						<FileConfiguration
+							Name="release-noboost-st|x64"
+							>
+							<Tool
+								Name="VCCLCompilerTool"
+								UsePrecompiledHeader="0"
+							/>
+						</FileConfiguration>
 						<FileConfiguration
 							Name="debug-noboost-st|Win32"
 							>
@@ -3450,6 +3490,14 @@
 								UsePrecompiledHeader="0"
 							/>
 						</FileConfiguration>
+						<FileConfiguration
+							Name="debug-noboost-st|x64"
+							>
+							<Tool
+								Name="VCCLCompilerTool"
+								UsePrecompiledHeader="0"
+							/>
+						</FileConfiguration>
 						<FileConfiguration
 							Name="debug-st|Win32"
 							>
@@ -3458,6 +3506,14 @@
 								UsePrecompiledHeader="0"
 							/>
 						</FileConfiguration>
+						<FileConfiguration
+							Name="debug-st|x64"
+							>
+							<Tool
+								Name="VCCLCompilerTool"
+								UsePrecompiledHeader="0"
+							/>
+						</FileConfiguration>
 						<FileConfiguration
 							Name="release-st|Win32"
 							>
@@ -3466,6 +3522,14 @@
 								UsePrecompiledHeader="0"
 							/>
 						</FileConfiguration>
+						<FileConfiguration
+							Name="release-st|x64"
+							>
+							<Tool
+								Name="VCCLCompilerTool"
+								UsePrecompiledHeader="0"
+							/>
+						</FileConfiguration>
 					</File>
 					<File
 						RelativePath="..\..\contrib\ConvertUTF\ConvertUTF.h"