Browse Source

Adding a file system filter layer to correct invalid paths automatically.

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@381 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
aramis_acg 16 years ago
parent
commit
a3b32f306c

+ 21 - 54
code/BaseImporter.cpp

@@ -45,10 +45,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
 #include "AssimpPCH.h"
 #include "AssimpPCH.h"
 #include "BaseImporter.h"
 #include "BaseImporter.h"
+#include "FileSystemFilter.h"
 
 
 using namespace Assimp;
 using namespace Assimp;
 
 
-
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Constructor to be privately used by Importer
 // Constructor to be privately used by Importer
 BaseImporter::BaseImporter()
 BaseImporter::BaseImporter()
@@ -67,13 +67,16 @@ BaseImporter::~BaseImporter()
 // Imports the given file and returns the imported data.
 // Imports the given file and returns the imported data.
 aiScene* BaseImporter::ReadFile( const std::string& pFile, IOSystem* pIOHandler)
 aiScene* BaseImporter::ReadFile( const std::string& pFile, IOSystem* pIOHandler)
 {
 {
+	// Construct a file system filter to improve our success ratio reading external files
+	FileSystemFilter filter(pFile,pIOHandler);
+
 	// create a scene object to hold the data
 	// create a scene object to hold the data
 	aiScene* scene = new aiScene();
 	aiScene* scene = new aiScene();
 
 
 	// dispatch importing
 	// dispatch importing
 	try
 	try
 	{
 	{
-		InternReadFile( pFile, scene, pIOHandler);
+		InternReadFile( pFile, scene, &filter);
 	} catch( ImportErrorException* exception)
 	} catch( ImportErrorException* exception)
 	{
 	{
 		// extract error description
 		// extract error description
@@ -291,71 +294,38 @@ BatchLoader::BatchLoader(IOSystem* pIO)
 
 
 	data = new BatchData();
 	data = new BatchData();
 	data->pIOSystem = pIO;
 	data->pIOSystem = pIO;
+
 	data->pImporter = new Importer();
 	data->pImporter = new Importer();
+	data->pImporter->SetIOHandler(data->pIOSystem);
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 BatchLoader::~BatchLoader()
 BatchLoader::~BatchLoader()
 {
 {
 	// delete all scenes wthat have not been polled by the user
 	// delete all scenes wthat have not been polled by the user
-	for (std::list<LoadRequest>::iterator it = data->requests.begin();
-		it != data->requests.end(); ++it)
-	{
+	for (std::list<LoadRequest>::iterator it = data->requests.begin();it != data->requests.end(); ++it)	{
+
 		delete (*it).scene;
 		delete (*it).scene;
 	}
 	}
+	data->pImporter->SetIOHandler(NULL); /* get pointer back into our posession */
 	delete data->pImporter;
 	delete data->pImporter;
 	delete data;
 	delete data;
 }
 }
 
 
-// ------------------------------------------------------------------------------------------------
-void BatchLoader::SetBasePath (const std::string& pBase)
-{
-	data->pathBase = pBase;
-
-	// file name? we just need the directory
-	std::string::size_type ss,ss2;
-	if (std::string::npos != (ss = data->pathBase.find_first_of('.')))
-	{
-		if (std::string::npos != (ss2 = data->pathBase.find_last_of("\\/")))
-		{
-			if (ss > ss2)
-				data->pathBase.erase(ss2,data->pathBase.length()-ss2);
-		}
-		else {
-			data->pathBase = "";
-			return;
-		}
-	}
-
-	// make sure the directory is terminated properly
-	char s;
-	if ((s = *(data->pathBase.end()-1)) != '\\' && s != '/')
-		data->pathBase.append("\\");
-}
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 unsigned int BatchLoader::AddLoadRequest	(const std::string& file,
 unsigned int BatchLoader::AddLoadRequest	(const std::string& file,
 	unsigned int steps /*= 0*/, const PropertyMap* map /*= NULL*/)
 	unsigned int steps /*= 0*/, const PropertyMap* map /*= NULL*/)
 {
 {
 	ai_assert(!file.empty());
 	ai_assert(!file.empty());
-
-	// no threaded implementation for the moment
-	std::string real;
-
-	// build a full path if this is a relative path and 
-	// we have a new base directory given
-	if (file.length() > 2 && file[1] != ':' && data->pathBase.length()) {
-		real = data->pathBase + file;
-	}
-	else real = file;
 	
 	
 	// check whether we have this loading request already
 	// check whether we have this loading request already
 	std::list<LoadRequest>::iterator it;
 	std::list<LoadRequest>::iterator it;
-	for (it = data->requests.begin();it != data->requests.end(); ++it)
-	{
+	for (it = data->requests.begin();it != data->requests.end(); ++it)	{
+
 		// Call IOSystem's path comparison function here
 		// Call IOSystem's path comparison function here
-		if (data->pIOSystem->ComparePaths((*it).file,real))
-		{
+		if (data->pIOSystem->ComparePaths((*it).file,file))	{
+
 			if (map) {
 			if (map) {
 				if (!((*it).map == *map))
 				if (!((*it).map == *map))
 					continue;
 					continue;
@@ -369,20 +339,19 @@ unsigned int BatchLoader::AddLoadRequest	(const std::string& file,
 	}
 	}
 
 
 	// no, we don't have it. So add it to the queue ...
 	// no, we don't have it. So add it to the queue ...
-	data->requests.push_back(LoadRequest(real,steps,map,data->next_id));
+	data->requests.push_back(LoadRequest(file,steps,map,data->next_id));
 	return data->next_id++;
 	return data->next_id++;
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 aiScene* BatchLoader::GetImport		(unsigned int which)
 aiScene* BatchLoader::GetImport		(unsigned int which)
 {
 {
-	for (std::list<LoadRequest>::iterator it = data->requests.begin();it != data->requests.end(); ++it)
-	{
-		if ((*it).id == which && (*it).loaded)
-		{
+	for (std::list<LoadRequest>::iterator it = data->requests.begin();it != data->requests.end(); ++it)	{
+
+		if ((*it).id == which && (*it).loaded)	{
+
 			aiScene* sc = (*it).scene;
 			aiScene* sc = (*it).scene;
-			if (!(--(*it).refCnt))
-			{
+			if (!(--(*it).refCnt))	{
 				data->requests.erase(it);
 				data->requests.erase(it);
 			}
 			}
 			return sc;
 			return sc;
@@ -395,9 +364,7 @@ aiScene* BatchLoader::GetImport		(unsigned int which)
 void BatchLoader::LoadAll()
 void BatchLoader::LoadAll()
 {
 {
 	// no threaded implementation for the moment
 	// no threaded implementation for the moment
-	for (std::list<LoadRequest>::iterator it = data->requests.begin();
-		it != data->requests.end(); ++it)
-	{
+	for (std::list<LoadRequest>::iterator it = data->requests.begin();it != data->requests.end(); ++it)	{
 		// force validation in debug builds
 		// force validation in debug builds
 		unsigned int pp = (*it).flags;
 		unsigned int pp = (*it).flags;
 #ifdef _DEBUG
 #ifdef _DEBUG

+ 0 - 11
code/BaseImporter.h

@@ -356,17 +356,6 @@ public:
 	~BatchLoader();
 	~BatchLoader();
 
 
 
 
-	/** Sets the base path to be used for all subsequent load
-	 *  calls. This is the working directory of Assimp. 
-	 *
-	 *  Every (inplicit) occurence of '.\' will be replaced with it.
-	 *
-	 *  @param pBase Base path. This *may* also be the path to
-	 *  a file (the directory of the file is taken then, of course)
-	 */
-	void SetBasePath (const std::string& pBase);
-
-
 	/** Add a new file to the list of files to be loaded.
 	/** Add a new file to the list of files to be loaded.
 	 *
 	 *
 	 *  @param file File to be loaded
 	 *  @param file File to be loaded

+ 220 - 0
code/FileSystemFilter.h

@@ -0,0 +1,220 @@
+/*
+Open Asset Import Library (ASSIMP)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2008, ASSIMP Development Team
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms, 
+with or without modification, are permitted provided that the 
+following conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the ASSIMP team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the ASSIMP Development Team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+----------------------------------------------------------------------
+*/
+
+/** @file FileSystemFilter.h
+ *  Implements a filter system to filter calls to Exists() and Open()
+ *  in order to improve the sucess rate of file opening ...
+ */
+#ifndef AI_FILESYSTEMFILTER_H_INC
+#define AI_FILESYSTEMFILTER_H_INC
+
+#include "../include/IOSystem.h"
+#include "fast_atof.h"
+#include "ParsingUtils.h"
+namespace Assimp	{
+
+// ---------------------------------------------------------------------------
+/** File system filter  
+ */
+class FileSystemFilter : public IOSystem
+{
+public:
+	/** Constructor. */
+	FileSystemFilter(const std::string& file, IOSystem* old)
+		: wrapped  (old)
+		, src_file (file)
+	{
+		ai_assert(NULL != wrapped);
+
+		// Determine base directory
+		base = src_file;
+		std::string::size_type ss2;
+		if (std::string::npos != (ss2 = base.find_last_of("\\/")))	{
+			base.erase(ss2,base.length()-ss2);
+		}
+		else {
+			base = "";
+			return;
+		}
+
+		// make sure the directory is terminated properly
+		char s;
+
+		if (base.length() == 0) {
+			base = ".\\";
+		}
+		else if ((s = *(base.end()-1)) != '\\' && s != '/')
+			base.append("\\"); 
+
+		DefaultLogger::get()->info("Import root directory is \'" + base + "\'");
+	}
+
+	/** Destructor. */
+	~FileSystemFilter()
+	{
+		// haha
+	}
+
+	// -------------------------------------------------------------------
+	/** Tests for the existence of a file at the given path. */
+	bool Exists( const char* pFile) const
+	{
+		std::string tmp = pFile;
+
+		// Currently this IOSystem is also used to open THE ONE FILE.
+		if (tmp != src_file)	{
+			BuildPath(tmp);
+			Cleanup(tmp);
+		}
+
+		return wrapped->Exists(tmp);
+	}
+
+	// -------------------------------------------------------------------
+	/** Returns the directory separator. */
+	char getOsSeparator() const
+	{
+		return wrapped->getOsSeparator();
+	}
+
+	// -------------------------------------------------------------------
+	/** Open a new file with a given path. */
+	IOStream* Open( const char* pFile, const char* pMode = "rb")
+	{
+		std::string tmp = pFile;
+
+		// Currently this IOSystem is also used to open THE ONE FILE.
+		if (tmp != src_file)	{
+			BuildPath(tmp);
+			Cleanup(tmp);
+		}
+
+		return wrapped->Open(tmp,pMode);
+	}
+
+	// -------------------------------------------------------------------
+	/** Closes the given file and releases all resources associated with it. */
+	void Close( IOStream* pFile)
+	{
+		return wrapped->Close(pFile);
+	}
+
+	// -------------------------------------------------------------------
+	/** Compare two paths */
+	bool ComparePaths (const char* one, const char* second) const
+	{
+		return wrapped->ComparePaths (one,second);
+	}
+
+private:
+	IOSystem* wrapped;
+	std::string src_file, base;
+
+	// -------------------------------------------------------------------
+	/** Build a valid path from a given relative or absolute path.
+	 */
+	void BuildPath (std::string& in) const
+	{
+		// if we can already access the file, great.
+		if (in.length() < 3 || wrapped->Exists(in.c_str())) {
+			return;
+		}
+
+		// Determine whether this is a relative path. 
+		if (in[1] != ':') {
+		
+			// append base path and try 
+			in = base + in;
+			if (wrapped->Exists(in.c_str())) {
+				return;
+			}
+		}
+
+		// hopefully the underyling file system has another few tricks to access this file ...
+	}
+
+	// -------------------------------------------------------------------
+	/** Cleanup the given path
+	 */
+	void Cleanup (std::string& in) const
+	{
+		char last = 0;
+
+		// Remove a very common issue when we're parsing file names: spaces at the
+		// beginning of the path.
+		std::string::iterator it = in.begin();
+		while (IsSpaceOrNewLine( *it ))++it;
+		if (it != in.begin())
+			in.erase(in.begin(),it+1);
+
+		const char sep = getOsSeparator();
+		for (it = in.begin(); it != in.end(); ++it) {
+			
+			// Both Windows and Linux accept both separators, but to avoid conflicts
+			// or mixed seperators in a single path we're cleaning up.
+			if (*it == '/' || (*it) == '\\') {
+				*it = sep;
+
+				// And we're removing double delimiters, frequent issue with
+				// incorrectly composited paths ...
+				if (last == *it) {
+					it = in.erase(it);
+					--it;
+				}
+			}
+			else if (*it == '%' && in.end() - it > 2) {
+			
+				// Hex sequence, common _artifact_ in URIs
+				uint32_t tmp;
+				if( 0xffffffff != (tmp = HexOctetToDecimal(&*it))) {
+					*it = (char)tmp;
+					it = in.erase(it+1,it+2);
+					--it;
+				}
+			}
+
+			last = *it;
+		}
+	}
+};
+
+} //!ns Assimp
+
+#endif //AI_DEFAULTIOSYSTEM_H_INC

+ 1 - 1
code/IRRLoader.cpp

@@ -906,7 +906,7 @@ void IRRImporter::InternReadFile( const std::string& pFile,
 
 
 	// Batch loader used to load external models
 	// Batch loader used to load external models
 	BatchLoader batch(pIOHandler);
 	BatchLoader batch(pIOHandler);
-	batch.SetBasePath(pFile);
+//	batch.SetBasePath(pFile);
 	
 	
 	cameras.reserve(5);
 	cameras.reserve(5);
 	lights.reserve(5);
 	lights.reserve(5);

+ 2 - 1
code/Importer.cpp

@@ -559,7 +559,8 @@ void Importer::SetIOHandler( IOSystem* pIOHandler)
 	// If the new handler is zero, allocate a default IO implementation.
 	// If the new handler is zero, allocate a default IO implementation.
 	if (!pIOHandler)
 	if (!pIOHandler)
 	{
 	{
-		delete mIOHandler;
+		// Release pointer in the possession of the caller
+		// delete mIOHandler; 
 		mIOHandler = new DefaultIOSystem();
 		mIOHandler = new DefaultIOSystem();
 		mIsDefaultHandler = true;
 		mIsDefaultHandler = true;
 	}
 	}

+ 3 - 4
code/LWOAnimation.cpp

@@ -318,9 +318,9 @@ void AnimResolver::DoInterpolation2(std::vector<LWO::Key>::const_iterator beg,
 void AnimResolver::SubsampleAnimTrack(std::vector<aiVectorKey>& out,
 void AnimResolver::SubsampleAnimTrack(std::vector<aiVectorKey>& out,
 	double time,double sample_delta)
 	double time,double sample_delta)
 {
 {
-	ai_assert(!out.empty() && sample_delta);
+	ai_assert(out.empty() && sample_delta);
 
 
-	const double time_start = out.back().mTime;
+	//const double time_start = out.back().mTime;
 //	for ()
 //	for ()
 }
 }
 
 
@@ -512,8 +512,7 @@ void AnimResolver::ExtractAnimChannel(aiNodeAnim** out, unsigned int flags /*= 0
 		return;
 		return;
 	}
 	}
 
 
-	// We won't spawn an animation channel if we don't have at least one
-	// envelope with more than one keyframe defined.
+	// We won't spawn an animation channel if we don't have at least one envelope with more than one keyframe defined.
 	const bool trans = (trans_x && trans_x->keys.size() > 1 || trans_y && trans_y->keys.size() > 1 || trans_z && trans_z->keys.size() > 1);
 	const bool trans = (trans_x && trans_x->keys.size() > 1 || trans_y && trans_y->keys.size() > 1 || trans_z && trans_z->keys.size() > 1);
 	const bool rotat = (rotat_x && rotat_x->keys.size() > 1 || rotat_y && rotat_y->keys.size() > 1 || rotat_z && rotat_z->keys.size() > 1);
 	const bool rotat = (rotat_x && rotat_x->keys.size() > 1 || rotat_y && rotat_y->keys.size() > 1 || rotat_z && rotat_z->keys.size() > 1);
 	const bool scale = (scale_x && scale_x->keys.size() > 1 || scale_y && scale_y->keys.size() > 1 || scale_z && scale_z->keys.size() > 1);
 	const bool scale = (scale_x && scale_x->keys.size() > 1 || scale_y && scale_y->keys.size() > 1 || scale_z && scale_z->keys.size() > 1);

+ 8 - 9
code/LWSLoader.cpp

@@ -312,10 +312,10 @@ void LWSImporter::BuildGraph(aiNode* nd, LWS::NodeDesc& src, std::vector<Attachm
 	// Setup a very cryptic name for the node, we want the user to be happy
 	// Setup a very cryptic name for the node, we want the user to be happy
 	SetupNodeName(nd,src);
 	SetupNodeName(nd,src);
 
 
-	// If this is an object from an external file - get the scene
-	// and setup proper attachment tags
+	// If this is an object from an external file - get the scene and setup proper attachment tags
+	aiScene* obj = NULL;
 	if (src.type == LWS::NodeDesc::OBJECT && src.path.length() ) {
 	if (src.type == LWS::NodeDesc::OBJECT && src.path.length() ) {
-		aiScene* obj = batch.GetImport(src.id);
+		obj = batch.GetImport(src.id);
 		if (!obj) {
 		if (!obj) {
 			DefaultLogger::get()->error("LWS: Failed to read external file " + src.path);
 			DefaultLogger::get()->error("LWS: Failed to read external file " + src.path);
 		}
 		}
@@ -370,7 +370,7 @@ void LWSImporter::BuildGraph(aiNode* nd, LWS::NodeDesc& src, std::vector<Attachm
 
 
 	// .. and construct animation channels
 	// .. and construct animation channels
 	aiNodeAnim* anim = NULL;
 	aiNodeAnim* anim = NULL;
-#if 1 /* not yet */
+
 	if (first != last) {
 	if (first != last) {
 		resolver.SetAnimationRange(first,last);
 		resolver.SetAnimationRange(first,last);
 		resolver.ExtractAnimChannel(&anim,AI_LWO_ANIM_FLAG_SAMPLE_ANIMS|AI_LWO_ANIM_FLAG_START_AT_ZERO);
 		resolver.ExtractAnimChannel(&anim,AI_LWO_ANIM_FLAG_SAMPLE_ANIMS|AI_LWO_ANIM_FLAG_START_AT_ZERO);
@@ -379,7 +379,6 @@ void LWSImporter::BuildGraph(aiNode* nd, LWS::NodeDesc& src, std::vector<Attachm
 			animOut.push_back(anim);
 			animOut.push_back(anim);
 		}
 		}
 	}
 	}
-#endif
 
 
 	// process pivot point, if any
 	// process pivot point, if any
 	if (src.pivotPos != aiVector3D()) {
 	if (src.pivotPos != aiVector3D()) {
@@ -397,7 +396,7 @@ void LWSImporter::BuildGraph(aiNode* nd, LWS::NodeDesc& src, std::vector<Attachm
 			// Maybe the final optimization here will be done during postprocessing.
 			// Maybe the final optimization here will be done during postprocessing.
 
 
 			aiNode* pivot = new aiNode();
 			aiNode* pivot = new aiNode();
-			pivot->mName.Set("$Pivot");
+			pivot->mName.length = sprintf( pivot->mName.data, "$Pivot_%s",nd->mName.data);
 			pivot->mTransformation = tmp;
 			pivot->mTransformation = tmp;
 
 
 			pivot->mChildren = new aiNode*[pivot->mNumChildren = 1];
 			pivot->mChildren = new aiNode*[pivot->mNumChildren = 1];
@@ -406,11 +405,11 @@ void LWSImporter::BuildGraph(aiNode* nd, LWS::NodeDesc& src, std::vector<Attachm
 			pivot->mParent = nd->mParent;
 			pivot->mParent = nd->mParent;
 			nd->mParent    = pivot;
 			nd->mParent    = pivot;
 			
 			
-			// swap children ad hope the parents wont see a huge difference
+			// swap children and hope the parents wont see a huge difference
 			pivot->mParent->mChildren[pivot->mParent->mNumChildren-1] = pivot;
 			pivot->mParent->mChildren[pivot->mParent->mNumChildren-1] = pivot;
 		}
 		}
 		else {
 		else {
-			nd->mTransformation = tmp * nd->mTransformation;
+			nd->mTransformation = tmp*nd->mTransformation;
 		}
 		}
 	}
 	}
 
 
@@ -484,7 +483,7 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
 
 
 	// Construct a Batchimporter to read more files recursively
 	// Construct a Batchimporter to read more files recursively
 	BatchLoader batch(pIOHandler);
 	BatchLoader batch(pIOHandler);
-	batch.SetBasePath(pFile);
+//	batch.SetBasePath(pFile);
 
 
 	// Construct an array to receive the flat output graph
 	// Construct an array to receive the flat output graph
 	std::list<LWS::NodeDesc> nodes;
 	std::list<LWS::NodeDesc> nodes;

+ 4 - 4
include/aiVector3D.h

@@ -78,12 +78,12 @@ public:
 	aiVector3D& operator *= (const aiMatrix4x4& mat);
 	aiVector3D& operator *= (const aiMatrix4x4& mat);
 
 
 	// access a single element
 	// access a single element
-	inline float operator[](unsigned int i) const;
-	inline float& operator[](unsigned int i);
+	float operator[](unsigned int i) const;
+	float& operator[](unsigned int i);
 
 
 	// comparison
 	// comparison
-	inline bool operator== (const aiVector3D& other) const;
-	inline bool operator!= (const aiVector3D& other) const;
+	bool operator== (const aiVector3D& other) const;
+	bool operator!= (const aiVector3D& other) const;
 
 
 public:
 public:
 
 

+ 3 - 1
include/assimp.hpp

@@ -273,9 +273,11 @@ public:
 	 *
 	 *
 	 * The Importer takes ownership of the object and will destroy it 
 	 * The Importer takes ownership of the object and will destroy it 
 	 * afterwards. The previously assigned handler will be deleted.
 	 * afterwards. The previously assigned handler will be deleted.
+	 * Pass NULL to take again ownership of your IOSystem and reset Assimp
+	 * to use its default implementation.
 	 *
 	 *
 	 * @param pIOHandler The IO handler to be used in all file accesses 
 	 * @param pIOHandler The IO handler to be used in all file accesses 
-	 *   of the Importer. NULL resets it to the default handler.
+	 *   of the Importer. 
 	 */
 	 */
 	void SetIOHandler( IOSystem* pIOHandler);
 	void SetIOHandler( IOSystem* pIOHandler);
 
 

+ 1 - 1
mkutil/mkrev.bat

@@ -7,7 +7,7 @@ rem It is included by assimp.rc.
 rem -----------------------------------------------------
 rem -----------------------------------------------------
 
 
 rem This is not very elegant, but it works.
 rem This is not very elegant, but it works.
-rem ./bin shouldn't have any alocal modifications
+rem ./bin shouldn't have any local modifications
 
 
 cd ..\bin
 cd ..\bin
 svnversion > tmpfile.txt
 svnversion > tmpfile.txt

+ 125 - 121
workspaces/vc9/assimp.vcproj

@@ -1300,126 +1300,6 @@
 		<Filter
 		<Filter
 			Name="sources"
 			Name="sources"
 			>
 			>
-			<File
-				RelativePath="..\..\code\aiAssert.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\..\code\Assimp.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\..\code\BaseImporter.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\..\code\BaseImporter.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\code\BaseProcess.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\..\code\BaseProcess.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\code\IFF.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\code\Importer.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\..\code\MaterialSystem.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\..\code\MaterialSystem.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\code\RemoveComments.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\..\code\RemoveComments.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\code\SceneCombiner.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\..\code\SceneCombiner.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\code\ScenePreprocessor.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\..\code\ScenePreprocessor.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\code\SGSpatialSort.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\..\code\SGSpatialSort.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\code\SkeletonMeshBuilder.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\..\code\SkeletonMeshBuilder.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\code\SmoothingGroups.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\code\SmoothingGroups.inl"
-				>
-			</File>
-			<File
-				RelativePath="..\..\code\SpatialSort.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\..\code\SpatialSort.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\code\StandardShapes.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\..\code\StandardShapes.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\code\TargetAnimation.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\..\code\TargetAnimation.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\code\VertexTriangleAdjacency.cpp"
-				>
-			</File>
-			<File
-				RelativePath="..\..\code\VertexTriangleAdjacency.h"
-				>
-			</File>
 			<Filter
 			<Filter
 				Name="extra"
 				Name="extra"
 				>
 				>
@@ -2363,14 +2243,42 @@
 					RelativePath="..\..\code\DefaultIOSystem.h"
 					RelativePath="..\..\code\DefaultIOSystem.h"
 					>
 					>
 				</File>
 				</File>
+				<File
+					RelativePath="..\..\code\FileSystemFilter.h"
+					>
+				</File>
 				<File
 				<File
 					RelativePath="..\..\code\StreamReader.h"
 					RelativePath="..\..\code\StreamReader.h"
 					>
 					>
 				</File>
 				</File>
 			</Filter>
 			</Filter>
 			<Filter
 			<Filter
-				Name="Util"
+				Name="core"
 				>
 				>
+				<File
+					RelativePath="..\..\code\aiAssert.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\code\Assimp.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\code\BaseImporter.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\code\BaseImporter.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\code\BaseProcess.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\code\BaseProcess.h"
+					>
+				</File>
 				<File
 				<File
 					RelativePath="..\..\code\ByteSwap.h"
 					RelativePath="..\..\code\ByteSwap.h"
 					>
 					>
@@ -2387,6 +2295,22 @@
 					RelativePath="..\..\code\Hash.h"
 					RelativePath="..\..\code\Hash.h"
 					>
 					>
 				</File>
 				</File>
+				<File
+					RelativePath="..\..\code\IFF.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\code\Importer.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\code\MaterialSystem.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\code\MaterialSystem.h"
+					>
+				</File>
 				<File
 				<File
 					RelativePath="..\..\code\ParsingUtils.h"
 					RelativePath="..\..\code\ParsingUtils.h"
 					>
 					>
@@ -2395,10 +2319,90 @@
 					RelativePath="..\..\code\qnan.h"
 					RelativePath="..\..\code\qnan.h"
 					>
 					>
 				</File>
 				</File>
+				<File
+					RelativePath="..\..\code\RemoveComments.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\code\RemoveComments.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\code\SceneCombiner.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\code\SceneCombiner.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\code\ScenePreprocessor.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\code\ScenePreprocessor.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\code\SGSpatialSort.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\code\SGSpatialSort.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\code\SkeletonMeshBuilder.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\code\SkeletonMeshBuilder.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\code\SmoothingGroups.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\code\SmoothingGroups.inl"
+					>
+				</File>
+				<File
+					RelativePath="..\..\code\SpatialSort.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\code\SpatialSort.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\code\StandardShapes.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\code\StandardShapes.h"
+					>
+				</File>
 				<File
 				<File
 					RelativePath="..\..\code\StringComparison.h"
 					RelativePath="..\..\code\StringComparison.h"
 					>
 					>
 				</File>
 				</File>
+				<File
+					RelativePath="..\..\code\TargetAnimation.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\code\TargetAnimation.h"
+					>
+				</File>
+				<File
+					RelativePath="..\..\code\VertexTriangleAdjacency.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\..\code\VertexTriangleAdjacency.h"
+					>
+				</File>
 			</Filter>
 			</Filter>
 			<Filter
 			<Filter
 				Name="extern"
 				Name="extern"