vrshoot

diff libs/assimp/BaseImporter.cpp @ 0:b2f14e535253

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 01 Feb 2014 19:58:19 +0200
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/libs/assimp/BaseImporter.cpp	Sat Feb 01 19:58:19 2014 +0200
     1.3 @@ -0,0 +1,560 @@
     1.4 +/*
     1.5 +---------------------------------------------------------------------------
     1.6 +Open Asset Import Library (assimp)
     1.7 +---------------------------------------------------------------------------
     1.8 +
     1.9 +Copyright (c) 2006-2012, assimp team
    1.10 +
    1.11 +All rights reserved.
    1.12 +
    1.13 +Redistribution and use of this software in source and binary forms, 
    1.14 +with or without modification, are permitted provided that the following 
    1.15 +conditions are met:
    1.16 +
    1.17 +* Redistributions of source code must retain the above
    1.18 +  copyright notice, this list of conditions and the
    1.19 +  following disclaimer.
    1.20 +
    1.21 +* Redistributions in binary form must reproduce the above
    1.22 +  copyright notice, this list of conditions and the
    1.23 +  following disclaimer in the documentation and/or other
    1.24 +  materials provided with the distribution.
    1.25 +
    1.26 +* Neither the name of the assimp team, nor the names of its
    1.27 +  contributors may be used to endorse or promote products
    1.28 +  derived from this software without specific prior
    1.29 +  written permission of the assimp team.
    1.30 +
    1.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
    1.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
    1.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    1.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
    1.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    1.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
    1.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    1.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
    1.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
    1.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
    1.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    1.42 +---------------------------------------------------------------------------
    1.43 +*/
    1.44 +
    1.45 +/** @file  BaseImporter.cpp
    1.46 + *  @brief Implementation of BaseImporter 
    1.47 + */
    1.48 +
    1.49 +#include "AssimpPCH.h"
    1.50 +#include "BaseImporter.h"
    1.51 +#include "FileSystemFilter.h"
    1.52 +
    1.53 +#include "Importer.h"
    1.54 +
    1.55 +using namespace Assimp;
    1.56 +
    1.57 +// ------------------------------------------------------------------------------------------------
    1.58 +// Constructor to be privately used by Importer
    1.59 +BaseImporter::BaseImporter()
    1.60 +: progress()
    1.61 +{
    1.62 +	// nothing to do here
    1.63 +}
    1.64 +
    1.65 +// ------------------------------------------------------------------------------------------------
    1.66 +// Destructor, private as well
    1.67 +BaseImporter::~BaseImporter()
    1.68 +{
    1.69 +	// nothing to do here
    1.70 +}
    1.71 +
    1.72 +// ------------------------------------------------------------------------------------------------
    1.73 +// Imports the given file and returns the imported data.
    1.74 +aiScene* BaseImporter::ReadFile(const Importer* pImp, const std::string& pFile, IOSystem* pIOHandler)
    1.75 +{
    1.76 +	progress = pImp->GetProgressHandler();
    1.77 +	ai_assert(progress);
    1.78 +
    1.79 +	// Gather configuration properties for this run
    1.80 +	SetupProperties( pImp );
    1.81 +
    1.82 +	// Construct a file system filter to improve our success ratio at reading external files
    1.83 +	FileSystemFilter filter(pFile,pIOHandler);
    1.84 +
    1.85 +	// create a scene object to hold the data
    1.86 +	ScopeGuard<aiScene> sc(new aiScene());
    1.87 +
    1.88 +	// dispatch importing
    1.89 +	try
    1.90 +	{
    1.91 +		InternReadFile( pFile, sc, &filter);
    1.92 +
    1.93 +	} catch( const std::exception& err )	{
    1.94 +		// extract error description
    1.95 +		mErrorText = err.what();
    1.96 +		DefaultLogger::get()->error(mErrorText);
    1.97 +		return NULL;
    1.98 +	}
    1.99 +
   1.100 +	// return what we gathered from the import. 
   1.101 +	sc.dismiss();
   1.102 +	return sc;
   1.103 +}
   1.104 +
   1.105 +// ------------------------------------------------------------------------------------------------
   1.106 +void BaseImporter::SetupProperties(const Importer* /*pImp*/)
   1.107 +{
   1.108 +	// the default implementation does nothing
   1.109 +}
   1.110 +
   1.111 +// ------------------------------------------------------------------------------------------------
   1.112 +void BaseImporter::GetExtensionList(std::set<std::string>& extensions)
   1.113 +{
   1.114 +	const aiImporterDesc* desc = GetInfo();
   1.115 +	ai_assert(desc != NULL);
   1.116 +
   1.117 +	const char* ext = desc->mFileExtensions;
   1.118 +	ai_assert(ext != NULL);
   1.119 +
   1.120 +	const char* last = ext;
   1.121 +	do {
   1.122 +		if (!*ext || *ext == ' ') {
   1.123 +			extensions.insert(std::string(last,ext-last));
   1.124 +			ai_assert(ext-last > 0);
   1.125 +			last = ext;
   1.126 +			while(*last == ' ') {
   1.127 +				++last;
   1.128 +			}
   1.129 +		}
   1.130 +	}
   1.131 +	while(*ext++);
   1.132 +}
   1.133 +
   1.134 +// ------------------------------------------------------------------------------------------------
   1.135 +/*static*/ bool BaseImporter::SearchFileHeaderForToken(IOSystem* pIOHandler,
   1.136 +	const std::string&	pFile,
   1.137 +	const char**		tokens, 
   1.138 +	unsigned int		numTokens,
   1.139 +	unsigned int		searchBytes /* = 200 */,
   1.140 +	bool				tokensSol /* false */)
   1.141 +{
   1.142 +	ai_assert(NULL != tokens && 0 != numTokens && 0 != searchBytes);
   1.143 +	if (!pIOHandler)
   1.144 +		return false;
   1.145 +
   1.146 +	boost::scoped_ptr<IOStream> pStream (pIOHandler->Open(pFile));
   1.147 +	if (pStream.get() )	{
   1.148 +		// read 200 characters from the file
   1.149 +		boost::scoped_array<char> _buffer (new char[searchBytes+1 /* for the '\0' */]);
   1.150 +		char* buffer = _buffer.get();
   1.151 +
   1.152 +		const unsigned int read = pStream->Read(buffer,1,searchBytes);
   1.153 +		if (!read)
   1.154 +			return false;
   1.155 +
   1.156 +		for (unsigned int i = 0; i < read;++i)
   1.157 +			buffer[i] = ::tolower(buffer[i]);
   1.158 +
   1.159 +		// It is not a proper handling of unicode files here ...
   1.160 +		// ehm ... but it works in most cases.
   1.161 +		char* cur = buffer,*cur2 = buffer,*end = &buffer[read];
   1.162 +		while (cur != end)	{
   1.163 +			if (*cur)
   1.164 +				*cur2++ = *cur;
   1.165 +			++cur;
   1.166 +		}
   1.167 +		*cur2 = '\0';
   1.168 +
   1.169 +		for (unsigned int i = 0; i < numTokens;++i)	{
   1.170 +			ai_assert(NULL != tokens[i]);
   1.171 +
   1.172 +
   1.173 +			const char* r = strstr(buffer,tokens[i]);
   1.174 +			if (!r) 
   1.175 +				continue;
   1.176 +			// We got a match, either we don't care where it is, or it happens to
   1.177 +			// be in the beginning of the file / line
   1.178 +			if (!tokensSol || r == buffer || r[-1] == '\r' || r[-1] == '\n') {
   1.179 +				DefaultLogger::get()->debug(std::string("Found positive match for header keyword: ") + tokens[i]);
   1.180 +				return true;
   1.181 +			}
   1.182 +		}
   1.183 +	}
   1.184 +	return false;
   1.185 +}
   1.186 +
   1.187 +// ------------------------------------------------------------------------------------------------
   1.188 +// Simple check for file extension
   1.189 +/*static*/ bool BaseImporter::SimpleExtensionCheck (const std::string& pFile, 
   1.190 +	const char* ext0,
   1.191 +	const char* ext1,
   1.192 +	const char* ext2)
   1.193 +{
   1.194 +	std::string::size_type pos = pFile.find_last_of('.');
   1.195 +
   1.196 +	// no file extension - can't read
   1.197 +	if( pos == std::string::npos)
   1.198 +		return false;
   1.199 +	
   1.200 +	const char* ext_real = & pFile[ pos+1 ];
   1.201 +	if( !ASSIMP_stricmp(ext_real,ext0) )
   1.202 +		return true;
   1.203 +
   1.204 +	// check for other, optional, file extensions
   1.205 +	if (ext1 && !ASSIMP_stricmp(ext_real,ext1))
   1.206 +		return true;
   1.207 +
   1.208 +	if (ext2 && !ASSIMP_stricmp(ext_real,ext2))
   1.209 +		return true;
   1.210 +
   1.211 +	return false;
   1.212 +}
   1.213 +
   1.214 +// ------------------------------------------------------------------------------------------------
   1.215 +// Get file extension from path
   1.216 +/*static*/ std::string BaseImporter::GetExtension (const std::string& pFile)
   1.217 +{
   1.218 +	std::string::size_type pos = pFile.find_last_of('.');
   1.219 +
   1.220 +	// no file extension at all
   1.221 +	if( pos == std::string::npos)
   1.222 +		return "";
   1.223 +
   1.224 +	std::string ret = pFile.substr(pos+1);
   1.225 +	std::transform(ret.begin(),ret.end(),ret.begin(),::tolower); // thanks to Andy Maloney for the hint
   1.226 +	return ret;
   1.227 +}
   1.228 +
   1.229 +// ------------------------------------------------------------------------------------------------
   1.230 +// Check for magic bytes at the beginning of the file.
   1.231 +/* static */ bool BaseImporter::CheckMagicToken(IOSystem* pIOHandler, const std::string& pFile, 
   1.232 +	const void* _magic, unsigned int num, unsigned int offset, unsigned int size)
   1.233 +{
   1.234 +	ai_assert(size <= 16 && _magic);
   1.235 +
   1.236 +	if (!pIOHandler) {
   1.237 +		return false;
   1.238 +	}
   1.239 +	union {
   1.240 +		const char* magic;
   1.241 +		const uint16_t* magic_u16;
   1.242 +		const uint32_t* magic_u32;
   1.243 +	};
   1.244 +	magic = reinterpret_cast<const char*>(_magic);
   1.245 +	boost::scoped_ptr<IOStream> pStream (pIOHandler->Open(pFile));
   1.246 +	if (pStream.get() )	{
   1.247 +
   1.248 +		// skip to offset
   1.249 +		pStream->Seek(offset,aiOrigin_SET);
   1.250 +
   1.251 +		// read 'size' characters from the file
   1.252 +		union {
   1.253 +			char data[16];
   1.254 +			uint16_t data_u16[8];
   1.255 +			uint32_t data_u32[4];
   1.256 +		};
   1.257 +		if(size != pStream->Read(data,1,size)) {
   1.258 +			return false;
   1.259 +		}
   1.260 +
   1.261 +		for (unsigned int i = 0; i < num; ++i) {
   1.262 +			// also check against big endian versions of tokens with size 2,4
   1.263 +			// that's just for convinience, the chance that we cause conflicts
   1.264 +			// is quite low and it can save some lines and prevent nasty bugs
   1.265 +			if (2 == size) {
   1.266 +				uint16_t rev = *magic_u16; 
   1.267 +				ByteSwap::Swap(&rev);
   1.268 +				if (data_u16[0] == *magic_u16 || data_u16[0] == rev) {
   1.269 +					return true;
   1.270 +				}
   1.271 +			}
   1.272 +			else if (4 == size) {
   1.273 +				uint32_t rev = *magic_u32;
   1.274 +				ByteSwap::Swap(&rev);
   1.275 +				if (data_u32[0] == *magic_u32 || data_u32[0] == rev) {
   1.276 +					return true;
   1.277 +				}
   1.278 +			}
   1.279 +			else {
   1.280 +				// any length ... just compare
   1.281 +				if(!memcmp(magic,data,size)) {
   1.282 +					return true;
   1.283 +				}
   1.284 +			}
   1.285 +			magic += size;
   1.286 +		}
   1.287 +	}
   1.288 +	return false;
   1.289 +}
   1.290 +
   1.291 +#include "ConvertUTF/ConvertUTF.h"
   1.292 +
   1.293 +// ------------------------------------------------------------------------------------------------
   1.294 +void ReportResult(ConversionResult res)
   1.295 +{
   1.296 +	if(res == sourceExhausted) {
   1.297 +		DefaultLogger::get()->error("Source ends with incomplete character sequence, transformation to UTF-8 fails");
   1.298 +	}
   1.299 +	else if(res == sourceIllegal) {
   1.300 +		DefaultLogger::get()->error("Source contains illegal character sequence, transformation to UTF-8 fails");
   1.301 +	}
   1.302 +}
   1.303 +
   1.304 +// ------------------------------------------------------------------------------------------------
   1.305 +// Convert to UTF8 data
   1.306 +void BaseImporter::ConvertToUTF8(std::vector<char>& data)
   1.307 +{
   1.308 +	ConversionResult result;
   1.309 +	if(data.size() < 8) {
   1.310 +		throw DeadlyImportError("File is too small");
   1.311 +	}
   1.312 +
   1.313 +	// UTF 8 with BOM
   1.314 +	if((uint8_t)data[0] == 0xEF && (uint8_t)data[1] == 0xBB && (uint8_t)data[2] == 0xBF) {
   1.315 +		DefaultLogger::get()->debug("Found UTF-8 BOM ...");
   1.316 +
   1.317 +		std::copy(data.begin()+3,data.end(),data.begin());
   1.318 +		data.resize(data.size()-3);
   1.319 +		return;
   1.320 +	}
   1.321 +
   1.322 +	// UTF 32 BE with BOM
   1.323 +	if(*((uint32_t*)&data.front()) == 0xFFFE0000) {
   1.324 +	
   1.325 +		// swap the endianess ..
   1.326 +		for(uint32_t* p = (uint32_t*)&data.front(), *end = (uint32_t*)&data.back(); p <= end; ++p) {
   1.327 +			AI_SWAP4P(p);
   1.328 +		}
   1.329 +	}
   1.330 +	
   1.331 +	// UTF 32 LE with BOM
   1.332 +	if(*((uint32_t*)&data.front()) == 0x0000FFFE) {
   1.333 +		DefaultLogger::get()->debug("Found UTF-32 BOM ...");
   1.334 +
   1.335 +		const uint32_t* sstart = (uint32_t*)&data.front()+1, *send = (uint32_t*)&data.back()+1;
   1.336 +		char* dstart,*dend;
   1.337 +		std::vector<char> output;
   1.338 +		do {
   1.339 +			output.resize(output.size()?output.size()*3/2:data.size()/2);
   1.340 +			dstart = &output.front(),dend = &output.back()+1;
   1.341 +
   1.342 +			result = ConvertUTF32toUTF8((const UTF32**)&sstart,(const UTF32*)send,(UTF8**)&dstart,(UTF8*)dend,lenientConversion);
   1.343 +		} while(result == targetExhausted);
   1.344 +
   1.345 +		ReportResult(result);
   1.346 +
   1.347 +		// copy to output buffer. 
   1.348 +		const size_t outlen = (size_t)(dstart-&output.front());
   1.349 +		data.assign(output.begin(),output.begin()+outlen);
   1.350 +		return;
   1.351 +	}
   1.352 +
   1.353 +	// UTF 16 BE with BOM
   1.354 +	if(*((uint16_t*)&data.front()) == 0xFFFE) {
   1.355 +	
   1.356 +		// swap the endianess ..
   1.357 +		for(uint16_t* p = (uint16_t*)&data.front(), *end = (uint16_t*)&data.back(); p <= end; ++p) {
   1.358 +			ByteSwap::Swap2(p);
   1.359 +		}
   1.360 +	}
   1.361 +	
   1.362 +	// UTF 16 LE with BOM
   1.363 +	if(*((uint16_t*)&data.front()) == 0xFEFF) {
   1.364 +		DefaultLogger::get()->debug("Found UTF-16 BOM ...");
   1.365 +
   1.366 +		const uint16_t* sstart = (uint16_t*)&data.front()+1, *send = (uint16_t*)(&data.back()+1);
   1.367 +		char* dstart,*dend;
   1.368 +		std::vector<char> output;
   1.369 +		do {
   1.370 +			output.resize(output.size()?output.size()*3/2:data.size()*3/4);
   1.371 +			dstart = &output.front(),dend = &output.back()+1;
   1.372 +
   1.373 +			result = ConvertUTF16toUTF8((const UTF16**)&sstart,(const UTF16*)send,(UTF8**)&dstart,(UTF8*)dend,lenientConversion);
   1.374 +		} while(result == targetExhausted);
   1.375 +
   1.376 +		ReportResult(result);
   1.377 +
   1.378 +		// copy to output buffer.
   1.379 +		const size_t outlen = (size_t)(dstart-&output.front());
   1.380 +		data.assign(output.begin(),output.begin()+outlen);
   1.381 +		return;
   1.382 +	}
   1.383 +}
   1.384 +
   1.385 +// ------------------------------------------------------------------------------------------------
   1.386 +void BaseImporter::TextFileToBuffer(IOStream* stream,
   1.387 +	std::vector<char>& data)
   1.388 +{
   1.389 +	ai_assert(NULL != stream);
   1.390 +
   1.391 +	const size_t fileSize = stream->FileSize();
   1.392 +	if(!fileSize) {
   1.393 +		throw DeadlyImportError("File is empty");
   1.394 +	}
   1.395 +
   1.396 +	data.reserve(fileSize+1); 
   1.397 +	data.resize(fileSize); 
   1.398 +	if(fileSize != stream->Read( &data[0], 1, fileSize)) {
   1.399 +		throw DeadlyImportError("File read error");
   1.400 +	}
   1.401 +
   1.402 +	ConvertToUTF8(data);
   1.403 +
   1.404 +	// append a binary zero to simplify string parsing
   1.405 +	data.push_back(0);
   1.406 +}
   1.407 +
   1.408 +// ------------------------------------------------------------------------------------------------
   1.409 +namespace Assimp
   1.410 +{
   1.411 +	// Represents an import request
   1.412 +	struct LoadRequest
   1.413 +	{
   1.414 +		LoadRequest(const std::string& _file, unsigned int _flags,const BatchLoader::PropertyMap* _map, unsigned int _id)
   1.415 +			: file(_file), flags(_flags), refCnt(1),scene(NULL), loaded(false), id(_id)
   1.416 +		{
   1.417 +			if (_map)
   1.418 +				map = *_map;
   1.419 +		}
   1.420 +
   1.421 +		const std::string file;
   1.422 +		unsigned int flags;
   1.423 +		unsigned int refCnt;
   1.424 +		aiScene* scene;
   1.425 +		bool loaded;
   1.426 +		BatchLoader::PropertyMap map;
   1.427 +		unsigned int id;
   1.428 +
   1.429 +		bool operator== (const std::string& f) {
   1.430 +			return file == f;
   1.431 +		}
   1.432 +	};
   1.433 +}
   1.434 +
   1.435 +// ------------------------------------------------------------------------------------------------
   1.436 +// BatchLoader::pimpl data structure
   1.437 +struct Assimp::BatchData
   1.438 +{
   1.439 +	BatchData()
   1.440 +		:	next_id(0xffff)
   1.441 +	{}
   1.442 +
   1.443 +	// IO system to be used for all imports
   1.444 +	IOSystem* pIOSystem;
   1.445 +
   1.446 +	// Importer used to load all meshes
   1.447 +	Importer* pImporter;
   1.448 +
   1.449 +	// List of all imports
   1.450 +	std::list<LoadRequest> requests;
   1.451 +
   1.452 +	// Base path
   1.453 +	std::string pathBase;
   1.454 +
   1.455 +	// Id for next item
   1.456 +	unsigned int next_id;
   1.457 +};
   1.458 +
   1.459 +// ------------------------------------------------------------------------------------------------
   1.460 +BatchLoader::BatchLoader(IOSystem* pIO)
   1.461 +{
   1.462 +	ai_assert(NULL != pIO);
   1.463 +
   1.464 +	data = new BatchData();
   1.465 +	data->pIOSystem = pIO;
   1.466 +
   1.467 +	data->pImporter = new Importer();
   1.468 +	data->pImporter->SetIOHandler(data->pIOSystem);
   1.469 +}
   1.470 +
   1.471 +// ------------------------------------------------------------------------------------------------
   1.472 +BatchLoader::~BatchLoader()
   1.473 +{
   1.474 +	// delete all scenes wthat have not been polled by the user
   1.475 +	for (std::list<LoadRequest>::iterator it = data->requests.begin();it != data->requests.end(); ++it)	{
   1.476 +
   1.477 +		delete (*it).scene;
   1.478 +	}
   1.479 +	data->pImporter->SetIOHandler(NULL); /* get pointer back into our posession */
   1.480 +	delete data->pImporter;
   1.481 +	delete data;
   1.482 +}
   1.483 +
   1.484 +
   1.485 +// ------------------------------------------------------------------------------------------------
   1.486 +unsigned int BatchLoader::AddLoadRequest	(const std::string& file,
   1.487 +	unsigned int steps /*= 0*/, const PropertyMap* map /*= NULL*/)
   1.488 +{
   1.489 +	ai_assert(!file.empty());
   1.490 +	
   1.491 +	// check whether we have this loading request already
   1.492 +	std::list<LoadRequest>::iterator it;
   1.493 +	for (it = data->requests.begin();it != data->requests.end(); ++it)	{
   1.494 +
   1.495 +		// Call IOSystem's path comparison function here
   1.496 +		if (data->pIOSystem->ComparePaths((*it).file,file))	{
   1.497 +
   1.498 +			if (map) {
   1.499 +				if (!((*it).map == *map))
   1.500 +					continue;
   1.501 +			}
   1.502 +			else if (!(*it).map.empty())
   1.503 +				continue;
   1.504 +
   1.505 +			(*it).refCnt++;
   1.506 +			return (*it).id;
   1.507 +		}
   1.508 +	}
   1.509 +
   1.510 +	// no, we don't have it. So add it to the queue ...
   1.511 +	data->requests.push_back(LoadRequest(file,steps,map,data->next_id));
   1.512 +	return data->next_id++;
   1.513 +}
   1.514 +
   1.515 +// ------------------------------------------------------------------------------------------------
   1.516 +aiScene* BatchLoader::GetImport		(unsigned int which)
   1.517 +{
   1.518 +	for (std::list<LoadRequest>::iterator it = data->requests.begin();it != data->requests.end(); ++it)	{
   1.519 +
   1.520 +		if ((*it).id == which && (*it).loaded)	{
   1.521 +
   1.522 +			aiScene* sc = (*it).scene;
   1.523 +			if (!(--(*it).refCnt))	{
   1.524 +				data->requests.erase(it);
   1.525 +			}
   1.526 +			return sc;
   1.527 +		}
   1.528 +	}
   1.529 +	return NULL;
   1.530 +}
   1.531 +
   1.532 +// ------------------------------------------------------------------------------------------------
   1.533 +void BatchLoader::LoadAll()
   1.534 +{
   1.535 +	// no threaded implementation for the moment
   1.536 +	for (std::list<LoadRequest>::iterator it = data->requests.begin();it != data->requests.end(); ++it)	{
   1.537 +		// force validation in debug builds
   1.538 +		unsigned int pp = (*it).flags;
   1.539 +#ifdef _DEBUG
   1.540 +		pp |= aiProcess_ValidateDataStructure;
   1.541 +#endif
   1.542 +		// setup config properties if necessary
   1.543 +		ImporterPimpl* pimpl = data->pImporter->Pimpl();
   1.544 +		pimpl->mFloatProperties  = (*it).map.floats;
   1.545 +		pimpl->mIntProperties    = (*it).map.ints;
   1.546 +		pimpl->mStringProperties = (*it).map.strings;
   1.547 +
   1.548 +		if (!DefaultLogger::isNullLogger())
   1.549 +		{
   1.550 +			DefaultLogger::get()->info("%%% BEGIN EXTERNAL FILE %%%");
   1.551 +			DefaultLogger::get()->info("File: " + (*it).file);
   1.552 +		}
   1.553 +		data->pImporter->ReadFile((*it).file,pp);
   1.554 +		(*it).scene = data->pImporter->GetOrphanedScene();
   1.555 +		(*it).loaded = true;
   1.556 +
   1.557 +		DefaultLogger::get()->info("%%% END EXTERNAL FILE %%%");
   1.558 +	}
   1.559 +}
   1.560 +
   1.561 +
   1.562 +
   1.563 +