浏览代码

Add ExportProperties

Madrich 10 年之前
父节点
当前提交
8b1b12682f

+ 5 - 0
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
+

+ 1 - 1
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) {

+ 1 - 1
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 );

+ 1 - 1
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;

+ 1 - 1
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;

+ 2 - 0
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;

+ 133 - 15
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

+ 13 - 0
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

+ 1 - 1
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);

+ 2 - 2
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);

+ 2 - 2
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);

+ 20 - 6
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();

+ 4 - 1
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);	
 

+ 178 - 9
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:
 };
 
 
+class ASSIMP_API ExportProperties
+{
+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 ) 
+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);
+	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