From 8b1b12682f039f2d5831aa39de609edc10ff47fd Mon Sep 17 00:00:00 2001
From: Madrich <rsteffen@messbild.de>
Date: Sat, 14 Mar 2015 14:03:14 +0100
Subject: [PATCH 1/6] Add ExportProperties

---
 CREDITS                     |   5 +
 code/3DSExporter.cpp        |   2 +-
 code/AssbinExporter.cpp     |   2 +-
 code/AssxmlExporter.cpp     |   2 +-
 code/ColladaExporter.cpp    |   2 +-
 code/ColladaParser.cpp      |   2 +
 code/Exporter.cpp           | 148 +++++++++++++++++++++++++---
 code/GenericProperty.h      |  13 +++
 code/ObjExporter.cpp        |   2 +-
 code/PlyExporter.cpp        |   4 +-
 code/STLExporter.cpp        |   4 +-
 code/XFileExporter.cpp      |  26 +++--
 code/XFileExporter.h        |   5 +-
 include/assimp/Exporter.hpp | 189 ++++++++++++++++++++++++++++++++++--
 14 files changed, 365 insertions(+), 41 deletions(-)

diff --git a/CREDITS b/CREDITS
index 2e7485fb7..5028bc306 100644
--- a/CREDITS
+++ b/CREDITS
@@ -151,3 +151,8 @@ Ogre Binary format support
 
 - Filip Wasil, Tieto Poland Sp. z o.o.
 Android JNI asset extraction support
+
+- Richard Steffen
+Contributed X File exporter
+Contributed ExportProperties interface
+
diff --git a/code/3DSExporter.cpp b/code/3DSExporter.cpp
index 1b870181c..681a85cbb 100644
--- a/code/3DSExporter.cpp
+++ b/code/3DSExporter.cpp
@@ -144,7 +144,7 @@ namespace {
 
 // ------------------------------------------------------------------------------------------------
 // Worker function for exporting a scene to 3DS. Prototyped and registered in Exporter.cpp
-void ExportScene3DS(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene)
+void ExportScene3DS(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
 {
 	boost::shared_ptr<IOStream> outfile (pIOSystem->Open(pFile, "wb"));
 	if(!outfile) {
diff --git a/code/AssbinExporter.cpp b/code/AssbinExporter.cpp
index 6b4da3e30..405b676be 100644
--- a/code/AssbinExporter.cpp
+++ b/code/AssbinExporter.cpp
@@ -754,7 +754,7 @@ inline size_t WriteArray(IOStream * stream, const T* in, unsigned int size)
 		}
 	};
 
-void ExportSceneAssbin(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene)
+void ExportSceneAssbin(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
 {
 	AssbinExport exporter;
 	exporter.WriteBinaryDump( pFile, pIOSystem, pScene );
diff --git a/code/AssxmlExporter.cpp b/code/AssxmlExporter.cpp
index c2e3f1833..b6aabd393 100644
--- a/code/AssxmlExporter.cpp
+++ b/code/AssxmlExporter.cpp
@@ -621,7 +621,7 @@ void WriteDump(const aiScene* scene, IOStream* io, bool shortened)
 
 } // end of namespace AssxmlExport
 
-void ExportSceneAssxml(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene)
+void ExportSceneAssxml(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
 {
 	IOStream * out = pIOSystem->Open( pFile, "wt" );
 	if (!out) return;
diff --git a/code/ColladaExporter.cpp b/code/ColladaExporter.cpp
index db76e38a9..e4cbab02c 100644
--- a/code/ColladaExporter.cpp
+++ b/code/ColladaExporter.cpp
@@ -59,7 +59,7 @@ namespace Assimp
 
 // ------------------------------------------------------------------------------------------------
 // Worker function for exporting a scene to Collada. Prototyped and registered in Exporter.cpp
-void ExportSceneCollada(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene)
+void ExportSceneCollada(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
 {
 	std::string path = "";
 	std::string file = pFile;
diff --git a/code/ColladaParser.cpp b/code/ColladaParser.cpp
index b7b5a7908..d67ff33c5 100644
--- a/code/ColladaParser.cpp
+++ b/code/ColladaParser.cpp
@@ -1952,7 +1952,9 @@ void ColladaParser::ReadIndexData( Mesh* pMesh)
 
 	// small sanity check
 	if (primType != Prim_TriFans && primType != Prim_TriStrips)
+	{
 		ai_assert(actualPrimitives == numPrimitives);
+	}
 
 	// only when we're done reading all <p> tags (and thus know the final vertex count) can we commit the submesh
 	subgroup.mNumFaces = actualPrimitives;
diff --git a/code/Exporter.cpp b/code/Exporter.cpp
index 238430fa6..07f92de4c 100644
--- a/code/Exporter.cpp
+++ b/code/Exporter.cpp
@@ -72,16 +72,16 @@ void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out);
 // ------------------------------------------------------------------------------------------------
 // Exporter worker function prototypes. Should not be necessary to #ifndef them, it's just a prototype
 // do not use const, because some exporter need to convert the scene temporary
-void ExportSceneCollada(const char*,IOSystem*, const aiScene*);
-void ExportSceneXFile(const char*,IOSystem*, const aiScene*); 
-void ExportSceneObj(const char*,IOSystem*, const aiScene*);
-void ExportSceneSTL(const char*,IOSystem*, const aiScene*);
-void ExportSceneSTLBinary(const char*,IOSystem*, const aiScene*);
-void ExportScenePly(const char*,IOSystem*, const aiScene*);
-void ExportScenePlyBinary(const char*, IOSystem*, const aiScene*);
-void ExportScene3DS(const char*, IOSystem*, const aiScene*);
-void ExportSceneAssbin(const char*, IOSystem*, const aiScene*);
-void ExportSceneAssxml(const char*, IOSystem*, const aiScene*);
+void ExportSceneCollada(const char*,IOSystem*, const aiScene*, const ExportProperties*);
+void ExportSceneXFile(const char*,IOSystem*, const aiScene*, const ExportProperties*); 
+void ExportSceneObj(const char*,IOSystem*, const aiScene*, const ExportProperties*);
+void ExportSceneSTL(const char*,IOSystem*, const aiScene*, const ExportProperties*);
+void ExportSceneSTLBinary(const char*,IOSystem*, const aiScene*, const ExportProperties*);
+void ExportScenePly(const char*,IOSystem*, const aiScene*, const ExportProperties*);
+void ExportScenePlyBinary(const char*, IOSystem*, const aiScene*, const ExportProperties*);
+void ExportScene3DS(const char*, IOSystem*, const aiScene*, const ExportProperties*);
+void ExportSceneAssbin(const char*, IOSystem*, const aiScene*, const ExportProperties*);
+void ExportSceneAssxml(const char*, IOSystem*, const aiScene*, const ExportProperties*);
 
 // ------------------------------------------------------------------------------------------------
 // global array of all export formats which Assimp supports in its current build
@@ -91,7 +91,7 @@ Exporter::ExportFormatEntry gExporters[] =
 	Exporter::ExportFormatEntry( "collada", "COLLADA - Digital Asset Exchange Schema", "dae", &ExportSceneCollada),
 #endif
 
-#ifndef ASSIMP_BUILD_NO_FXILE_EXPORTER
+#ifndef ASSIMP_BUILD_NO_XFILE_EXPORTER
 	Exporter::ExportFormatEntry( "x", "X Files", "x", &ExportSceneXFile,
 		aiProcess_MakeLeftHanded | aiProcess_FlipWindingOrder | aiProcess_FlipUVs),
 #endif
@@ -226,7 +226,7 @@ bool Exporter :: IsDefaultIOHandler() const
 
 
 // ------------------------------------------------------------------------------------------------
-const aiExportDataBlob* Exporter :: ExportToBlob(  const aiScene* pScene, const char* pFormatId, unsigned int )
+const aiExportDataBlob* Exporter :: ExportToBlob(  const aiScene* pScene, const char* pFormatId, unsigned int, const ExportProperties* pProperties)
 {
 	if (pimpl->blob) {
 		delete pimpl->blob;
@@ -282,7 +282,7 @@ bool IsVerboseFormat(const aiScene* pScene)
 
 
 // ------------------------------------------------------------------------------------------------
-aiReturn Exporter :: Export( const aiScene* pScene, const char* pFormatId, const char* pPath, unsigned int pPreprocessing )
+aiReturn Exporter :: Export( const aiScene* pScene, const char* pFormatId, const char* pPath, unsigned int pPreprocessing, const ExportProperties* pProperties)
 {
 	ASSIMP_BEGIN_EXCEPTION_REGION();
 
@@ -290,7 +290,7 @@ aiReturn Exporter :: Export( const aiScene* pScene, const char* pFormatId, const
 	// format. They will likely not be aware that there is a flag in the scene to indicate
 	// this, however. To avoid surprises and bug reports, we check for duplicates in
 	// meshes upfront.
-	const bool is_verbose_format = !(pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) || IsVerboseFormat(pScene);
+	const bool is_verbose_format = !(pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) || IsVerboseFormat(pScene);	
 
 	pimpl->mError = "";
 	for (size_t i = 0; i < pimpl->mExporters.size(); ++i) {
@@ -397,7 +397,7 @@ aiReturn Exporter :: Export( const aiScene* pScene, const char* pFormatId, const
 					proc.Execute(scenecopy.get());
 				}
 
-				exp.mExportFunction(pPath,pimpl->mIOSystem.get(),scenecopy.get());
+				exp.mExportFunction(pPath,pimpl->mIOSystem.get(),scenecopy.get(), pProperties);
 			}
 			catch (DeadlyExportError& err) {
 				pimpl->mError = err.what();
@@ -492,4 +492,122 @@ void Exporter :: UnregisterExporter(const char* id)
 	}
 }
 
+void ExportProperties :: CopyProperties(ExportProperties* dest,const ExportProperties* source)
+{
+	if (!source || !dest) return;
+	dest->mIntProperties = IntPropertyMap(source->mIntProperties);
+	dest->mFloatProperties = FloatPropertyMap(source->mFloatProperties);
+	dest->mStringProperties = StringPropertyMap(source->mStringProperties);
+	dest->mMatrixProperties = MatrixPropertyMap(source->mMatrixProperties);
+}
+
+
+// ------------------------------------------------------------------------------------------------
+// Set a configuration property
+void ExportProperties :: SetPropertyInteger(const char* szName, int iValue, 
+	bool* bWasExisting /*= NULL*/)
+{
+	ASSIMP_BEGIN_EXCEPTION_REGION();
+		SetGenericProperty<int>(mIntProperties, szName,iValue,bWasExisting);	
+	ASSIMP_END_EXCEPTION_REGION(void);
+}
+
+// ------------------------------------------------------------------------------------------------
+// Set a configuration property
+void ExportProperties :: SetPropertyFloat(const char* szName, float iValue, 
+	bool* bWasExisting /*= NULL*/)
+{
+	ASSIMP_BEGIN_EXCEPTION_REGION();
+		SetGenericProperty<float>(mFloatProperties, szName,iValue,bWasExisting);	
+	ASSIMP_END_EXCEPTION_REGION(void);
+}
+
+// ------------------------------------------------------------------------------------------------
+// Set a configuration property
+void ExportProperties :: SetPropertyString(const char* szName, const std::string& value, 
+	bool* bWasExisting /*= NULL*/)
+{
+	ASSIMP_BEGIN_EXCEPTION_REGION();
+		SetGenericProperty<std::string>(mStringProperties, szName,value,bWasExisting);	
+	ASSIMP_END_EXCEPTION_REGION(void);
+}
+
+// ------------------------------------------------------------------------------------------------
+// Set a configuration property
+void ExportProperties :: SetPropertyMatrix(const char* szName, const aiMatrix4x4& value, 
+	bool* bWasExisting /*= NULL*/)
+{
+	ASSIMP_BEGIN_EXCEPTION_REGION();
+	SetGenericProperty<aiMatrix4x4>(mMatrixProperties, szName,value,bWasExisting);	
+	ASSIMP_END_EXCEPTION_REGION(void);
+}
+
+// ------------------------------------------------------------------------------------------------
+// Get a configuration property
+int ExportProperties :: GetPropertyInteger(const char* szName, 
+	int iErrorReturn /*= 0xffffffff*/) const
+{
+	return GetGenericProperty<int>(mIntProperties,szName,iErrorReturn);
+}
+
+// ------------------------------------------------------------------------------------------------
+// Get a configuration property
+float ExportProperties :: GetPropertyFloat(const char* szName, 
+	float iErrorReturn /*= 10e10*/) const
+{
+	return GetGenericProperty<float>(mFloatProperties,szName,iErrorReturn);
+}
+
+// ------------------------------------------------------------------------------------------------
+// Get a configuration property
+const std::string ExportProperties :: GetPropertyString(const char* szName, 
+	const std::string& iErrorReturn /*= ""*/) const
+{
+	return GetGenericProperty<std::string>(mStringProperties,szName,iErrorReturn);
+}
+
+// ------------------------------------------------------------------------------------------------
+// Has a configuration property
+const aiMatrix4x4 ExportProperties :: GetPropertyMatrix(const char* szName, 
+	const aiMatrix4x4& iErrorReturn /*= aiMatrix4x4()*/) const
+{
+	return GetGenericProperty<aiMatrix4x4>(mMatrixProperties,szName,iErrorReturn);
+}
+
+// ------------------------------------------------------------------------------------------------
+// Has a configuration property
+bool ExportProperties :: HasPropertyInteger(const char* szName) const
+{
+	return HasGenericProperty<int>(mIntProperties, szName);
+}
+
+// ------------------------------------------------------------------------------------------------
+// Has a configuration property
+bool ExportProperties :: HasPropertyBool(const char* szName) const
+{
+	return HasGenericProperty<int>(mIntProperties, szName);
+};
+
+// ------------------------------------------------------------------------------------------------
+// Has a configuration property
+bool ExportProperties :: HasPropertyFloat(const char* szName) const
+{
+	return HasGenericProperty<float>(mFloatProperties, szName);
+};
+
+// ------------------------------------------------------------------------------------------------
+// Has a configuration property
+bool ExportProperties :: HasPropertyString(const char* szName) const
+{
+	return HasGenericProperty<std::string>(mStringProperties, szName);
+};
+
+// ------------------------------------------------------------------------------------------------
+// Has a configuration property
+bool ExportProperties :: HasPropertyMatrix(const char* szName) const
+{
+	return HasGenericProperty<aiMatrix4x4>(mMatrixProperties, szName);
+};
+
+
 #endif // !ASSIMP_BUILD_NO_EXPORT
diff --git a/code/GenericProperty.h b/code/GenericProperty.h
index 32d846850..0e89015ab 100644
--- a/code/GenericProperty.h
+++ b/code/GenericProperty.h
@@ -108,5 +108,18 @@ inline void SetGenericPropertyPtr(std::map< unsigned int, T* >& list,
 		*bWasExisting = true;
 }
 
+// ------------------------------------------------------------------------------------------------
+template <class T>
+inline const bool HasGenericProperty(const std::map< unsigned int, T >& list, 
+	const char* szName)
+{
+	ai_assert(NULL != szName);
+	const uint32_t hash = SuperFastHash(szName);
+
+	typename std::map<unsigned int, T>::const_iterator it = list.find(hash);
+	if (it == list.end()) return false;
+	
+	return true;
+}
 
 #endif // !! AI_GENERIC_PROPERTY_H_INCLUDED
diff --git a/code/ObjExporter.cpp b/code/ObjExporter.cpp
index 7ebb55b3e..c10c367b4 100644
--- a/code/ObjExporter.cpp
+++ b/code/ObjExporter.cpp
@@ -51,7 +51,7 @@ namespace Assimp	{
 
 // ------------------------------------------------------------------------------------------------
 // Worker function for exporting a scene to Wavefront OBJ. Prototyped and registered in Exporter.cpp
-void ExportSceneObj(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene)
+void ExportSceneObj(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
 {
 	// invoke the exporter 
 	ObjExporter exporter(pFile, pScene);
diff --git a/code/PlyExporter.cpp b/code/PlyExporter.cpp
index a214d1371..692b02668 100644
--- a/code/PlyExporter.cpp
+++ b/code/PlyExporter.cpp
@@ -50,7 +50,7 @@ namespace Assimp	{
 
 // ------------------------------------------------------------------------------------------------
 // Worker function for exporting a scene to PLY. Prototyped and registered in Exporter.cpp
-void ExportScenePly(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene)
+void ExportScenePly(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
 {
 	// invoke the exporter 
 	PlyExporter exporter(pFile, pScene);
@@ -64,7 +64,7 @@ void ExportScenePly(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene
 	outfile->Write( exporter.mOutput.str().c_str(), static_cast<size_t>(exporter.mOutput.tellp()),1);
 }
 
-void ExportScenePlyBinary(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene)
+void ExportScenePlyBinary(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
 {
 	// invoke the exporter 
 	PlyExporter exporter(pFile, pScene, true);
diff --git a/code/STLExporter.cpp b/code/STLExporter.cpp
index e3df2fbff..d45ece1ec 100644
--- a/code/STLExporter.cpp
+++ b/code/STLExporter.cpp
@@ -50,7 +50,7 @@ namespace Assimp	{
 
 // ------------------------------------------------------------------------------------------------
 // Worker function for exporting a scene to Stereolithograpy. Prototyped and registered in Exporter.cpp
-void ExportSceneSTL(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene)
+void ExportSceneSTL(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
 {
 	// invoke the exporter 
 	STLExporter exporter(pFile, pScene);
@@ -63,7 +63,7 @@ void ExportSceneSTL(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene
 
 	outfile->Write( exporter.mOutput.str().c_str(), static_cast<size_t>(exporter.mOutput.tellp()),1);
 }
-void ExportSceneSTLBinary(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene)
+void ExportSceneSTLBinary(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
 {
 	// invoke the exporter 
 	STLExporter exporter(pFile, pScene, true);
diff --git a/code/XFileExporter.cpp b/code/XFileExporter.cpp
index 2cd3c4d37..8e95be289 100644
--- a/code/XFileExporter.cpp
+++ b/code/XFileExporter.cpp
@@ -59,7 +59,7 @@ namespace Assimp
 
 // ------------------------------------------------------------------------------------------------
 // Worker function for exporting a scene to Collada. Prototyped and registered in Exporter.cpp
-void ExportSceneXFile(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene)
+void ExportSceneXFile(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
 {
 	std::string path = "";
 	std::string file = pFile;
@@ -78,13 +78,21 @@ void ExportSceneXFile(const char* pFile,IOSystem* pIOSystem, const aiScene* pSce
 		}
 	}
 
+	// create/copy Properties
+	ExportProperties props;
+	ExportProperties::CopyProperties(&props, pProperties);
+
+	// set standard properties if not set
+	if (!props.HasPropertyBool("AI_CONFIG_XFILE_64BIT")) props.SetPropertyBool("AI_CONFIG_XFILE_64BIT", false);
+	if (!props.HasPropertyBool("AI_CONFIG_XFILE_BAKETRANSFORM")) props.SetPropertyBool("AI_CONFIG_XFILE_BAKETRANSFORM", false);
+
 	// invoke the exporter 
-	XFileExporter iDoTheExportThing( pScene, pIOSystem, path, file);
+	XFileExporter iDoTheExportThing( pScene, pIOSystem, path, file, &props);
 
 	// we're still here - export successfully completed. Write result to the given IOSYstem
 	boost::scoped_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
 	if(outfile == NULL) {
-		throw DeadlyExportError("could not open output .dae file: " + std::string(pFile));
+		throw DeadlyExportError("could not open output .x file: " + std::string(pFile));
 	}
 
 	// XXX maybe use a small wrapper around IOStream that behaves like std::stringstream in order to avoid the extra copy.
@@ -96,8 +104,11 @@ void ExportSceneXFile(const char* pFile,IOSystem* pIOSystem, const aiScene* pSce
 
 // ------------------------------------------------------------------------------------------------
 // Constructor for a specific scene to export
-XFileExporter::XFileExporter(const aiScene* pScene, IOSystem* pIOSystem, const std::string& path, const std::string& file) : mIOSystem(pIOSystem), mPath(path), mFile(file)
+XFileExporter::XFileExporter(const aiScene* pScene, IOSystem* pIOSystem, const std::string& path, const std::string& file, const ExportProperties* pProperties) : mIOSystem(pIOSystem), mPath(path), mFile(file), mProperties(pProperties)
 {
+	//DefaultLogger::get()->debug(boost::str( boost::format( "AI_CONFIG_XFILE_64BIT <%i>.") % mProperties->GetPropertyBool("AI_CONFIG_XFILE_64BIT", false)));
+	//DefaultLogger::get()->debug(boost::str( boost::format( "AI_CONFIG_XFILE_BAKETRANSFORM <%i>.") % mProperties->GetPropertyBool("AI_CONFIG_XFILE_BAKETRANSFORM", false)));
+
 	// make sure that all formatting happens using the standard, C locale and not the user's current locale
 	mOutput.imbue( std::locale("C") );
 
@@ -126,7 +137,7 @@ void XFileExporter::WriteFile()
 {
 	// note, that all realnumber values must be comma separated in x files
 	mOutput.setf(std::ios::fixed);
-	mOutput.precision(6); // precission for float
+	mOutput.precision(16); // precission for double
 
 	// entry of writing the file
 	WriteHeader();
@@ -148,7 +159,10 @@ void XFileExporter::WriteFile()
 // Writes the asset header
 void XFileExporter::WriteHeader()
 {
-	mOutput << startstr << "xof 0303txt 0032" << endstr;
+	if (mProperties->GetPropertyBool("AI_CONFIG_XFILE_64BIT") == true)
+		mOutput << startstr << "xof 0303txt 0064" << endstr;
+	else
+		mOutput << startstr << "xof 0303txt 0032" << endstr;
 	mOutput << endstr;
 	mOutput << startstr << "template Frame {" << endstr;
 	PushTag();
diff --git a/code/XFileExporter.h b/code/XFileExporter.h
index fa4e6d38e..1b59e4461 100644
--- a/code/XFileExporter.h
+++ b/code/XFileExporter.h
@@ -61,7 +61,7 @@ class XFileExporter
 {
 public:
 	/// Constructor for a specific scene to export
-	XFileExporter(const aiScene* pScene, IOSystem* pIOSystem, const std::string& path, const std::string& file);
+	XFileExporter(const aiScene* pScene, IOSystem* pIOSystem, const std::string& path, const std::string& file, const ExportProperties* pProperties);
 
 	/// Destructor
 	virtual ~XFileExporter();
@@ -94,6 +94,9 @@ public:
 
 protected:
 
+	/// hold the properties pointer
+	const ExportProperties* mProperties;
+
 	/// write a path
 	void writePath(aiString path);	
 
diff --git a/include/assimp/Exporter.hpp b/include/assimp/Exporter.hpp
index 8ed98b3a2..168edfefa 100644
--- a/include/assimp/Exporter.hpp
+++ b/include/assimp/Exporter.hpp
@@ -72,6 +72,9 @@ namespace Assimp	{
  * #ExportToBlob is especially useful if you intend to work 
  * with the data in-memory. 
 */
+
+class ASSIMP_API ExportProperties;
+
 class ASSIMP_API Exporter
 	// TODO: causes good ol' base class has no dll interface warning
 //#ifdef __cplusplus
@@ -81,7 +84,7 @@ class ASSIMP_API Exporter
 public:
 
 	/** Function pointer type of a Export worker function */
-	typedef void (*fpExportFunc)(const char*,IOSystem*, const aiScene*);
+	typedef void (*fpExportFunc)(const char*, IOSystem*, const aiScene*, const ExportProperties*);
 
 	/** Internal description of an Assimp export format option */
 	struct ExportFormatEntry
@@ -171,8 +174,8 @@ public:
 	*   Any IO handlers set via #SetIOHandler are ignored here.
 	* @note Use aiCopyScene() to get a modifiable copy of a previously
 	*   imported scene. */
-	const aiExportDataBlob* ExportToBlob(  const aiScene* pScene, const char* pFormatId, unsigned int pPreprocessing = 0u );
-	inline const aiExportDataBlob* ExportToBlob(  const aiScene* pScene, const std::string& pFormatId, unsigned int pPreprocessing = 0u );
+	const aiExportDataBlob* ExportToBlob(  const aiScene* pScene, const char* pFormatId, unsigned int pPreprocessing = 0u, const ExportProperties* pProperties = NULL);
+	inline const aiExportDataBlob* ExportToBlob(  const aiScene* pScene, const std::string& pFormatId, unsigned int pPreprocessing = 0u, const ExportProperties* pProperties = NULL);
 
 
 	// -------------------------------------------------------------------
@@ -208,8 +211,8 @@ public:
 	 * @return AI_SUCCESS if everything was fine. 
 	 * @note Use aiCopyScene() to get a modifiable copy of a previously
 	 *   imported scene.*/
-	aiReturn Export( const aiScene* pScene, const char* pFormatId, const char* pPath, unsigned int pPreprocessing = 0u);
-	inline aiReturn Export( const aiScene* pScene, const std::string& pFormatId, const std::string& pPath,  unsigned int pPreprocessing = 0u);
+	aiReturn Export( const aiScene* pScene, const char* pFormatId, const char* pPath, unsigned int pPreprocessing = 0u, const ExportProperties* pProperties = NULL);
+	inline aiReturn Export( const aiScene* pScene, const std::string& pFormatId, const std::string& pPath,  unsigned int pPreprocessing = 0u, const ExportProperties* pProperties = NULL);
 
 
 	// -------------------------------------------------------------------
@@ -309,16 +312,182 @@ protected:
 };
 
 
-// ----------------------------------------------------------------------------------
-inline const aiExportDataBlob* Exporter :: ExportToBlob(  const aiScene* pScene, const std::string& pFormatId,unsigned int pPreprocessing ) 
+class ASSIMP_API ExportProperties
 {
-	return ExportToBlob(pScene,pFormatId.c_str(),pPreprocessing);
+public:
+	// Data type to store the key hash
+	typedef unsigned int KeyType;
+	
+	// typedefs for our four configuration maps.
+	// We don't need more, so there is no need for a generic solution
+	typedef std::map<KeyType, int> IntPropertyMap;
+	typedef std::map<KeyType, float> FloatPropertyMap;
+	typedef std::map<KeyType, std::string> StringPropertyMap;
+	typedef std::map<KeyType, aiMatrix4x4> MatrixPropertyMap;
+
+public:
+
+	// -------------------------------------------------------------------
+	/** Get a deep copy of a scene
+	 *
+	 *  @param dest Receives a pointer to the destination scene
+	 *  @param src Source scene - remains unmodified.
+	 */
+	static void CopyProperties(ExportProperties* dest,const ExportProperties* source);
+
+	// -------------------------------------------------------------------
+	/** Set an integer configuration property.
+	 * @param szName Name of the property. All supported properties
+	 *   are defined in the aiConfig.g header (all constants share the
+	 *   prefix AI_CONFIG_XXX and are simple strings).
+	 * @param iValue New value of the property
+	 * @param bWasExisting Optional pointer to receive true if the
+	 *   property was set before. The new value replaces the previous value
+	 *   in this case.
+	 * @note Property of different types (float, int, string ..) are kept
+	 *   on different stacks, so calling SetPropertyInteger() for a 
+	 *   floating-point property has no effect - the loader will call
+	 *   GetPropertyFloat() to read the property, but it won't be there.
+	 */
+	void SetPropertyInteger(const char* szName, int iValue, 
+		bool* bWasExisting = NULL);
+
+	// -------------------------------------------------------------------
+	/** Set a boolean configuration property. Boolean properties
+	 *  are stored on the integer stack internally so it's possible
+	 *  to set them via #SetPropertyBool and query them with
+	 *  #GetPropertyBool and vice versa.
+	 * @see SetPropertyInteger()
+	 */
+	void SetPropertyBool(const char* szName, bool value, bool* bWasExisting = NULL)	{
+		SetPropertyInteger(szName,value,bWasExisting);
+	}
+
+	// -------------------------------------------------------------------
+	/** Set a floating-point configuration property.
+	 * @see SetPropertyInteger()
+	 */
+	void SetPropertyFloat(const char* szName, float fValue, 
+		bool* bWasExisting = NULL);
+
+	// -------------------------------------------------------------------
+	/** Set a string configuration property.
+	 * @see SetPropertyInteger()
+	 */
+	void SetPropertyString(const char* szName, const std::string& sValue, 
+		bool* bWasExisting = NULL);
+
+	// -------------------------------------------------------------------
+	/** Set a matrix configuration property.
+	 * @see SetPropertyInteger()
+	 */
+	void SetPropertyMatrix(const char* szName, const aiMatrix4x4& sValue, 
+		bool* bWasExisting = NULL);
+
+	// -------------------------------------------------------------------
+	/** Get a configuration property.
+	 * @param szName Name of the property. All supported properties
+	 *   are defined in the aiConfig.g header (all constants share the
+	 *   prefix AI_CONFIG_XXX).
+	 * @param iErrorReturn Value that is returned if the property 
+	 *   is not found. 
+	 * @return Current value of the property
+	 * @note Property of different types (float, int, string ..) are kept
+	 *   on different lists, so calling SetPropertyInteger() for a 
+	 *   floating-point property has no effect - the loader will call
+	 *   GetPropertyFloat() to read the property, but it won't be there.
+	 */
+	int GetPropertyInteger(const char* szName, 
+		int iErrorReturn = 0xffffffff) const;
+
+	// -------------------------------------------------------------------
+	/** Get a boolean configuration property. Boolean properties
+	 *  are stored on the integer stack internally so it's possible
+	 *  to set them via #SetPropertyBool and query them with
+	 *  #GetPropertyBool and vice versa.
+	 * @see GetPropertyInteger()
+	 */
+	bool GetPropertyBool(const char* szName, bool bErrorReturn = false) const {
+		return GetPropertyInteger(szName,bErrorReturn)!=0;
+	}
+
+	// -------------------------------------------------------------------
+	/** Get a floating-point configuration property
+	 * @see GetPropertyInteger()
+	 */
+	float GetPropertyFloat(const char* szName, 
+		float fErrorReturn = 10e10f) const;
+
+	// -------------------------------------------------------------------
+	/** Get a string configuration property
+	 *
+	 *  The return value remains valid until the property is modified.
+	 * @see GetPropertyInteger()
+	 */
+	const std::string GetPropertyString(const char* szName,
+		const std::string& sErrorReturn = "") const;
+
+	// -------------------------------------------------------------------
+	/** Get a matrix configuration property
+	 *
+	 *  The return value remains valid until the property is modified.
+	 * @see GetPropertyInteger()
+	 */
+	const aiMatrix4x4 GetPropertyMatrix(const char* szName,
+		const aiMatrix4x4& sErrorReturn = aiMatrix4x4()) const;
+
+	// -------------------------------------------------------------------
+	/** Determine a integer configuration property has been set.
+	* @see HasPropertyInteger()
+	 */
+	bool HasPropertyInteger(const char* szName) const;
+
+	/** Determine a boolean configuration property has been set.
+	* @see HasPropertyBool()
+	 */
+	bool HasPropertyBool(const char* szName) const;
+
+	/** Determine a boolean configuration property has been set.
+	* @see HasPropertyFloat()
+	 */
+	bool HasPropertyFloat(const char* szName) const;
+
+	/** Determine a String configuration property has been set.
+	* @see HasPropertyString()
+	 */
+	bool HasPropertyString(const char* szName) const;
+
+	/** Determine a Matrix configuration property has been set.
+	* @see HasPropertyMatrix()
+	 */
+	bool HasPropertyMatrix(const char* szName) const;
+
+protected:
+
+	/** List of integer properties */
+	IntPropertyMap mIntProperties;
+
+	/** List of floating-point properties */
+	FloatPropertyMap mFloatProperties;
+
+	/** List of string properties */
+	StringPropertyMap mStringProperties;
+
+	/** List of Matrix properties */
+	MatrixPropertyMap mMatrixProperties;
+};
+
+
+// ----------------------------------------------------------------------------------
+inline const aiExportDataBlob* Exporter :: ExportToBlob(  const aiScene* pScene, const std::string& pFormatId,unsigned int pPreprocessing, const ExportProperties* pProperties) 
+{
+	return ExportToBlob(pScene,pFormatId.c_str(),pPreprocessing, pProperties);
 }
 
 // ----------------------------------------------------------------------------------
-inline aiReturn Exporter :: Export( const aiScene* pScene, const std::string& pFormatId, const std::string& pPath, unsigned int pPreprocessing )
+inline aiReturn Exporter :: Export( const aiScene* pScene, const std::string& pFormatId, const std::string& pPath, unsigned int pPreprocessing, const ExportProperties* pProperties)
 {
-	return Export(pScene,pFormatId.c_str(),pPath.c_str(),pPreprocessing);
+	return Export(pScene,pFormatId.c_str(),pPath.c_str(),pPreprocessing, pProperties);
 }
 
 } // namespace Assimp

From 37572f0f52320d3508f1a7ab28ffd831cec80f25 Mon Sep 17 00:00:00 2001
From: Madrich <rsteffen@messbild.de>
Date: Sat, 14 Mar 2015 14:22:55 +0100
Subject: [PATCH 2/6] Missing include map

---
 include/assimp/Exporter.hpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/assimp/Exporter.hpp b/include/assimp/Exporter.hpp
index 168edfefa..0e32d4397 100644
--- a/include/assimp/Exporter.hpp
+++ b/include/assimp/Exporter.hpp
@@ -48,6 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef ASSIMP_BUILD_NO_EXPORT
 
 #include "cexport.h"
+#include <map>
 
 namespace Assimp	{
 	class ExporterPimpl;

From 290a16eea5156eb1e98dc146d23641d959cdb885 Mon Sep 17 00:00:00 2001
From: Madrich <rsteffen@messbild.de>
Date: Sat, 14 Mar 2015 16:31:33 +0100
Subject: [PATCH 3/6] Copy constructor for ExportProperties Export Propertie
 defines in config.h Remove unnecessary

---
 code/Exporter.cpp           | 33 +++++++++++++++------------------
 code/XFileExporter.cpp      | 12 ++++--------
 include/assimp/Exporter.hpp | 18 +++++++++++-------
 include/assimp/config.h     | 17 +++++++++++++++++
 4 files changed, 47 insertions(+), 33 deletions(-)

diff --git a/code/Exporter.cpp b/code/Exporter.cpp
index 07f92de4c..3eb406c35 100644
--- a/code/Exporter.cpp
+++ b/code/Exporter.cpp
@@ -492,13 +492,18 @@ void Exporter :: UnregisterExporter(const char* id)
 	}
 }
 
-void ExportProperties :: CopyProperties(ExportProperties* dest,const ExportProperties* source)
+ExportProperties :: ExportProperties()
 {
-	if (!source || !dest) return;
-	dest->mIntProperties = IntPropertyMap(source->mIntProperties);
-	dest->mFloatProperties = FloatPropertyMap(source->mFloatProperties);
-	dest->mStringProperties = StringPropertyMap(source->mStringProperties);
-	dest->mMatrixProperties = MatrixPropertyMap(source->mMatrixProperties);
+
+}
+
+ExportProperties :: ExportProperties(const ExportProperties* source)
+{
+	if (!source) return;
+	mIntProperties = IntPropertyMap(source->mIntProperties);
+	mFloatProperties = FloatPropertyMap(source->mFloatProperties);
+	mStringProperties = StringPropertyMap(source->mStringProperties);
+	mMatrixProperties = MatrixPropertyMap(source->mMatrixProperties);
 }
 
 
@@ -507,9 +512,7 @@ void ExportProperties :: CopyProperties(ExportProperties* dest,const ExportPrope
 void ExportProperties :: SetPropertyInteger(const char* szName, int iValue, 
 	bool* bWasExisting /*= NULL*/)
 {
-	ASSIMP_BEGIN_EXCEPTION_REGION();
-		SetGenericProperty<int>(mIntProperties, szName,iValue,bWasExisting);	
-	ASSIMP_END_EXCEPTION_REGION(void);
+	SetGenericProperty<int>(mIntProperties, szName,iValue,bWasExisting);
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -517,9 +520,7 @@ void ExportProperties :: SetPropertyInteger(const char* szName, int iValue,
 void ExportProperties :: SetPropertyFloat(const char* szName, float iValue, 
 	bool* bWasExisting /*= NULL*/)
 {
-	ASSIMP_BEGIN_EXCEPTION_REGION();
-		SetGenericProperty<float>(mFloatProperties, szName,iValue,bWasExisting);	
-	ASSIMP_END_EXCEPTION_REGION(void);
+	SetGenericProperty<float>(mFloatProperties, szName,iValue,bWasExisting);
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -527,9 +528,7 @@ void ExportProperties :: SetPropertyFloat(const char* szName, float iValue,
 void ExportProperties :: SetPropertyString(const char* szName, const std::string& value, 
 	bool* bWasExisting /*= NULL*/)
 {
-	ASSIMP_BEGIN_EXCEPTION_REGION();
-		SetGenericProperty<std::string>(mStringProperties, szName,value,bWasExisting);	
-	ASSIMP_END_EXCEPTION_REGION(void);
+	SetGenericProperty<std::string>(mStringProperties, szName,value,bWasExisting);
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -537,9 +536,7 @@ void ExportProperties :: SetPropertyString(const char* szName, const std::string
 void ExportProperties :: SetPropertyMatrix(const char* szName, const aiMatrix4x4& value, 
 	bool* bWasExisting /*= NULL*/)
 {
-	ASSIMP_BEGIN_EXCEPTION_REGION();
-	SetGenericProperty<aiMatrix4x4>(mMatrixProperties, szName,value,bWasExisting);	
-	ASSIMP_END_EXCEPTION_REGION(void);
+	SetGenericProperty<aiMatrix4x4>(mMatrixProperties, szName,value,bWasExisting);
 }
 
 // ------------------------------------------------------------------------------------------------
diff --git a/code/XFileExporter.cpp b/code/XFileExporter.cpp
index 8e95be289..bb9579708 100644
--- a/code/XFileExporter.cpp
+++ b/code/XFileExporter.cpp
@@ -79,12 +79,11 @@ void ExportSceneXFile(const char* pFile,IOSystem* pIOSystem, const aiScene* pSce
 	}
 
 	// create/copy Properties
-	ExportProperties props;
-	ExportProperties::CopyProperties(&props, pProperties);
+	ExportProperties props(pProperties);
 
 	// set standard properties if not set
-	if (!props.HasPropertyBool("AI_CONFIG_XFILE_64BIT")) props.SetPropertyBool("AI_CONFIG_XFILE_64BIT", false);
-	if (!props.HasPropertyBool("AI_CONFIG_XFILE_BAKETRANSFORM")) props.SetPropertyBool("AI_CONFIG_XFILE_BAKETRANSFORM", false);
+	if (!props.HasPropertyBool(AI_CONFIG_EXPORT_XFILE_64BIT)) props.SetPropertyBool(AI_CONFIG_EXPORT_XFILE_64BIT, false);
+	if (!props.HasPropertyBool(AI_CONFIG_EXPORT_XFILE_BAKETRANSFORM)) props.SetPropertyBool(AI_CONFIG_EXPORT_XFILE_BAKETRANSFORM, false);
 
 	// invoke the exporter 
 	XFileExporter iDoTheExportThing( pScene, pIOSystem, path, file, &props);
@@ -106,9 +105,6 @@ void ExportSceneXFile(const char* pFile,IOSystem* pIOSystem, const aiScene* pSce
 // Constructor for a specific scene to export
 XFileExporter::XFileExporter(const aiScene* pScene, IOSystem* pIOSystem, const std::string& path, const std::string& file, const ExportProperties* pProperties) : mIOSystem(pIOSystem), mPath(path), mFile(file), mProperties(pProperties)
 {
-	//DefaultLogger::get()->debug(boost::str( boost::format( "AI_CONFIG_XFILE_64BIT <%i>.") % mProperties->GetPropertyBool("AI_CONFIG_XFILE_64BIT", false)));
-	//DefaultLogger::get()->debug(boost::str( boost::format( "AI_CONFIG_XFILE_BAKETRANSFORM <%i>.") % mProperties->GetPropertyBool("AI_CONFIG_XFILE_BAKETRANSFORM", false)));
-
 	// make sure that all formatting happens using the standard, C locale and not the user's current locale
 	mOutput.imbue( std::locale("C") );
 
@@ -159,7 +155,7 @@ void XFileExporter::WriteFile()
 // Writes the asset header
 void XFileExporter::WriteHeader()
 {
-	if (mProperties->GetPropertyBool("AI_CONFIG_XFILE_64BIT") == true)
+	if (mProperties->GetPropertyBool(AI_CONFIG_EXPORT_XFILE_64BIT) == true)
 		mOutput << startstr << "xof 0303txt 0064" << endstr;
 	else
 		mOutput << startstr << "xof 0303txt 0032" << endstr;
diff --git a/include/assimp/Exporter.hpp b/include/assimp/Exporter.hpp
index 0e32d4397..fb88f8e16 100644
--- a/include/assimp/Exporter.hpp
+++ b/include/assimp/Exporter.hpp
@@ -328,13 +328,17 @@ public:
 
 public:
 
-	// -------------------------------------------------------------------
-	/** Get a deep copy of a scene
-	 *
-	 *  @param dest Receives a pointer to the destination scene
-	 *  @param src Source scene - remains unmodified.
-	 */
-	static void CopyProperties(ExportProperties* dest,const ExportProperties* source);
+	/** Standard constructor
+	* @see ExportProperties()
+	*/
+
+	ExportProperties();
+
+	/** Copy constructor
+	* @see ExportProperties(const ExportProperties* source)
+	*/
+	ExportProperties(const ExportProperties* source);
+
 
 	// -------------------------------------------------------------------
 	/** Set an integer configuration property.
diff --git a/include/assimp/config.h b/include/assimp/config.h
index abe3f1102..0e8457995 100644
--- a/include/assimp/config.h
+++ b/include/assimp/config.h
@@ -879,4 +879,21 @@ enum aiComponent
 
 #define AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION "IMPORT_COLLADA_IGNORE_UP_DIRECTION"
 
+
+// ---------- All the Export defines ------------
+
+/** @brief Specifies the xfile use double for real values of float
+ *
+ * Property type: Bool. Default value: false.
+ */
+
+#define AI_CONFIG_EXPORT_XFILE_64BIT "EXPORT_XFILE_64BIT"
+
+/** @brief Specifies the xfile applies all transformations to the coordinates, normals
+ * so all motions are identities
+ * Property type: Bool. Default value: false.
+ */
+
+#define AI_CONFIG_EXPORT_XFILE_BAKETRANSFORM "EXPORT_XFILE_BAKETRANSFORM"
+
 #endif // !! AI_CONFIG_H_INC

From 56da80bc6e5baed97e745815f72f30c147c943c6 Mon Sep 17 00:00:00 2001
From: Madrich <rsteffen@messbild.de>
Date: Sat, 14 Mar 2015 19:03:44 +0100
Subject: [PATCH 4/6] Copy constructor ExportProperties Fix name dummy node in
 PreTransformVertices

---
 code/Exporter.cpp             | 19 +++++++++----------
 code/PretransformVertices.cpp |  2 +-
 code/XFileExporter.cpp        |  3 +--
 include/assimp/Exporter.hpp   | 12 +++++++-----
 include/assimp/config.h       |  6 ------
 5 files changed, 18 insertions(+), 24 deletions(-)

diff --git a/code/Exporter.cpp b/code/Exporter.cpp
index 3eb406c35..74b6a7344 100644
--- a/code/Exporter.cpp
+++ b/code/Exporter.cpp
@@ -492,18 +492,17 @@ void Exporter :: UnregisterExporter(const char* id)
 	}
 }
 
-ExportProperties :: ExportProperties()
-{
+ExportProperties :: ExportProperties() {}
 
-}
-
-ExportProperties :: ExportProperties(const ExportProperties* source)
+ExportProperties::ExportProperties(const ExportProperties &other)
 {
-	if (!source) return;
-	mIntProperties = IntPropertyMap(source->mIntProperties);
-	mFloatProperties = FloatPropertyMap(source->mFloatProperties);
-	mStringProperties = StringPropertyMap(source->mStringProperties);
-	mMatrixProperties = MatrixPropertyMap(source->mMatrixProperties);
+	new(this) ExportProperties();
+	
+	mIntProperties    = other.mIntProperties;
+	mFloatProperties  = other.mFloatProperties;
+	mStringProperties = other.mStringProperties;
+	mMatrixProperties = other.mMatrixProperties;
+	
 }
 
 
diff --git a/code/PretransformVertices.cpp b/code/PretransformVertices.cpp
index 007897c93..5cb661405 100644
--- a/code/PretransformVertices.cpp
+++ b/code/PretransformVertices.cpp
@@ -625,7 +625,7 @@ void PretransformVertices::Execute( aiScene* pScene)
 		// flat node graph with a root node and some level 1 children
 		delete pScene->mRootNode;
 		pScene->mRootNode = new aiNode();
-		pScene->mRootNode->mName.Set("<dummy_root>");
+		pScene->mRootNode->mName.Set("dummy_root");
 
 		if (1 == pScene->mNumMeshes && !pScene->mNumLights && !pScene->mNumCameras)
 		{
diff --git a/code/XFileExporter.cpp b/code/XFileExporter.cpp
index bb9579708..8c2d9b55b 100644
--- a/code/XFileExporter.cpp
+++ b/code/XFileExporter.cpp
@@ -79,11 +79,10 @@ void ExportSceneXFile(const char* pFile,IOSystem* pIOSystem, const aiScene* pSce
 	}
 
 	// create/copy Properties
-	ExportProperties props(pProperties);
+	ExportProperties props(*pProperties);
 
 	// set standard properties if not set
 	if (!props.HasPropertyBool(AI_CONFIG_EXPORT_XFILE_64BIT)) props.SetPropertyBool(AI_CONFIG_EXPORT_XFILE_64BIT, false);
-	if (!props.HasPropertyBool(AI_CONFIG_EXPORT_XFILE_BAKETRANSFORM)) props.SetPropertyBool(AI_CONFIG_EXPORT_XFILE_BAKETRANSFORM, false);
 
 	// invoke the exporter 
 	XFileExporter iDoTheExportThing( pScene, pIOSystem, path, file, &props);
diff --git a/include/assimp/Exporter.hpp b/include/assimp/Exporter.hpp
index fb88f8e16..692830f02 100644
--- a/include/assimp/Exporter.hpp
+++ b/include/assimp/Exporter.hpp
@@ -334,11 +334,13 @@ public:
 
 	ExportProperties();
 
-	/** Copy constructor
-	* @see ExportProperties(const ExportProperties* source)
-	*/
-	ExportProperties(const ExportProperties* source);
-
+	// -------------------------------------------------------------------
+	/** Copy constructor.
+	 * 
+	 * This copies the configuration properties of another ExportProperties.
+	 * @see ExportProperties(const ExportProperties& other)
+	 */
+	ExportProperties(const ExportProperties& other);
 
 	// -------------------------------------------------------------------
 	/** Set an integer configuration property.
diff --git a/include/assimp/config.h b/include/assimp/config.h
index 0e8457995..6b598f2a9 100644
--- a/include/assimp/config.h
+++ b/include/assimp/config.h
@@ -889,11 +889,5 @@ enum aiComponent
 
 #define AI_CONFIG_EXPORT_XFILE_64BIT "EXPORT_XFILE_64BIT"
 
-/** @brief Specifies the xfile applies all transformations to the coordinates, normals
- * so all motions are identities
- * Property type: Bool. Default value: false.
- */
-
-#define AI_CONFIG_EXPORT_XFILE_BAKETRANSFORM "EXPORT_XFILE_BAKETRANSFORM"
 
 #endif // !! AI_CONFIG_H_INC

From edd3ed9e8f387058190ce4e849198d8d89d16cfe Mon Sep 17 00:00:00 2001
From: Madrich <rsteffen@messbild.de>
Date: Sat, 14 Mar 2015 19:48:08 +0100
Subject: [PATCH 5/6] Back PretransformVertice Change Fix Node Name in
 XFileExport

---
 code/PretransformVertices.cpp |  2 +-
 code/XFileExporter.cpp        | 13 ++++++++++---
 code/XFileExporter.h          |  5 ++++-
 3 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/code/PretransformVertices.cpp b/code/PretransformVertices.cpp
index 5cb661405..007897c93 100644
--- a/code/PretransformVertices.cpp
+++ b/code/PretransformVertices.cpp
@@ -625,7 +625,7 @@ void PretransformVertices::Execute( aiScene* pScene)
 		// flat node graph with a root node and some level 1 children
 		delete pScene->mRootNode;
 		pScene->mRootNode = new aiNode();
-		pScene->mRootNode->mName.Set("dummy_root");
+		pScene->mRootNode->mName.Set("<dummy_root>");
 
 		if (1 == pScene->mNumMeshes && !pScene->mNumLights && !pScene->mNumCameras)
 		{
diff --git a/code/XFileExporter.cpp b/code/XFileExporter.cpp
index 8c2d9b55b..981d8a4c1 100644
--- a/code/XFileExporter.cpp
+++ b/code/XFileExporter.cpp
@@ -307,7 +307,7 @@ void XFileExporter::WriteNode( aiNode* pNode)
 		ss << "Node_" << pNode;
 		pNode->mName.Set(ss.str());
 	}
-	mOutput << startstr << "Frame " << pNode->mName.C_Str() << " {" << endstr;
+	mOutput << startstr << "Frame " << toXFileString(pNode->mName) << " {" << endstr;
 
 	PushTag();
 
@@ -327,9 +327,9 @@ void XFileExporter::WriteNode( aiNode* pNode)
 	mOutput << startstr << "}" << endstr << endstr;
 }
 
-void XFileExporter::WriteMesh(const aiMesh* mesh)
+void XFileExporter::WriteMesh(aiMesh* mesh)
 {
-	mOutput << startstr << "Mesh " << mesh->mName.C_Str() << "_mShape" << " {" << endstr;
+	mOutput << startstr << "Mesh " << toXFileString(mesh->mName) << "_mShape" << " {" << endstr;
 
 	PushTag();
 
@@ -505,6 +505,13 @@ void XFileExporter::WriteMesh(const aiMesh* mesh)
 
 }
 
+std::string XFileExporter::toXFileString(aiString &name)
+{
+	std::string str = std::string(name.C_Str());
+	std::replace(str.begin(), str.end(), '<', '_');
+	std::replace(str.begin(), str.end(), '>', '_');
+	return str;
+}
 
 void XFileExporter::writePath(aiString path)
 {
diff --git a/code/XFileExporter.h b/code/XFileExporter.h
index 1b59e4461..5c9f56701 100644
--- a/code/XFileExporter.h
+++ b/code/XFileExporter.h
@@ -80,7 +80,7 @@ protected:
 	void WriteNode( aiNode* pNode );
 
 	/// write a mesh entry of the scene
-	void WriteMesh(const aiMesh* mesh);
+	void WriteMesh( aiMesh* mesh);
 
 	/// Enters a new xml element, which increases the indentation
 	void PushTag() { startstr.append( "  "); }
@@ -94,6 +94,9 @@ public:
 
 protected:
 
+	/// normalize the name to be accepted by xfile readers
+	std::string toXFileString(aiString &name);
+
 	/// hold the properties pointer
 	const ExportProperties* mProperties;
 

From c4eb04bb8cc7452bf60abdf5a55b9c7a6576e650 Mon Sep 17 00:00:00 2001
From: Madrich <rsteffen@messbild.de>
Date: Sat, 14 Mar 2015 20:52:53 +0100
Subject: [PATCH 6/6] Fix XFile name for $ and {} Memleak copy constructor

---
 code/Exporter.cpp      | 10 ++++------
 code/XFileExporter.cpp |  3 +++
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/code/Exporter.cpp b/code/Exporter.cpp
index 74b6a7344..203070f8f 100644
--- a/code/Exporter.cpp
+++ b/code/Exporter.cpp
@@ -495,13 +495,11 @@ void Exporter :: UnregisterExporter(const char* id)
 ExportProperties :: ExportProperties() {}
 
 ExportProperties::ExportProperties(const ExportProperties &other)
+	 : mIntProperties(other.mIntProperties),
+   mFloatProperties(other.mFloatProperties),
+   mStringProperties(other.mStringProperties),
+   mMatrixProperties(other.mMatrixProperties)
 {
-	new(this) ExportProperties();
-	
-	mIntProperties    = other.mIntProperties;
-	mFloatProperties  = other.mFloatProperties;
-	mStringProperties = other.mStringProperties;
-	mMatrixProperties = other.mMatrixProperties;
 	
 }
 
diff --git a/code/XFileExporter.cpp b/code/XFileExporter.cpp
index 981d8a4c1..ce87f3168 100644
--- a/code/XFileExporter.cpp
+++ b/code/XFileExporter.cpp
@@ -510,6 +510,9 @@ std::string XFileExporter::toXFileString(aiString &name)
 	std::string str = std::string(name.C_Str());
 	std::replace(str.begin(), str.end(), '<', '_');
 	std::replace(str.begin(), str.end(), '>', '_');
+	std::replace(str.begin(), str.end(), '{', '_');
+	std::replace(str.begin(), str.end(), '}', '_');
+	std::replace(str.begin(), str.end(), '$', '_');
 	return str;
 }