Bladeren bron

- work on export API prototype, now relies on IOStreams.

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@893 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
aramis_acg 14 jaren geleden
bovenliggende
commit
553b3567c8
5 gewijzigde bestanden met toevoegingen van 260 en 93 verwijderingen
  1. 1 1
      code/AssimpPCH.h
  2. 161 6
      code/Exporter.cpp
  3. 2 1
      include/assimp.hpp
  4. 31 18
      include/export.h
  5. 65 67
      include/export.hpp

+ 1 - 1
code/AssimpPCH.h

@@ -137,7 +137,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "../include/aiScene.h"
 #include "../include/aiPostProcess.h"
 #include "../include/assimp.hpp"
-#include "../include/export.h"
+#include "../include/export.hpp"
 
 // Internal utility headers
 #include "BaseImporter.h"

+ 161 - 6
code/Exporter.cpp

@@ -39,16 +39,31 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ---------------------------------------------------------------------------
 */
 
+/** @file Exporter.cpp
+
+Assimp export interface. While it's public interface bears many similarities
+to the import interface (in fact, it is largely symmetric), the internal
+implementations differs a lot. Exporters are considered stateless and are
+simple callbacks which we maintain in a global list along with their
+description strings.
+*/
+
 #include "AssimpPCH.h"
 
 #ifndef ASSIMP_BUILD_NO_EXPORT
 
+#include "DefaultIOStream.h"
+#include "DefaultIOSystem.h"
+
 namespace Assimp {
 
 // ------------------------------------------------------------------------------------------------
 // Exporter worker function prototypes. Should not be necessary to #ifndef them, it's just a prototype
-void ExportSceneCollada(aiExportDataBlob*, const aiScene*);
-void ExportScene3DS(aiExportDataBlob*, const aiScene*);
+	void ExportSceneCollada(aiExportDataBlob*, const aiScene*) {
+	}
+
+	void ExportScene3DS(aiExportDataBlob*, const aiScene*) {
+	}
 
 /// Function pointer type of a Export worker function
 typedef void (*fpExportFunc)(aiExportDataBlob*, const aiScene*);
@@ -85,8 +100,141 @@ ExportFormatEntry gExporters[] =
 #endif
 };
 
+
+class ExporterPimpl {
+public:
+
+	ExporterPimpl()
+		: blob()
+		, mIOSystem(new Assimp::DefaultIOSystem())
+		, mIsDefaultIOHandler(true)
+	{
+		
+	}
+
+	~ExporterPimpl() 
+	{
+		delete blob;
+	}
+
+public:
+		
+	aiExportDataBlob* blob;
+	boost::shared_ptr< Assimp::IOSystem > mIOSystem;
+	bool mIsDefaultIOHandler;
+};
+
 } // end of namespace Assimp
 
+
+
+
+
+using namespace Assimp;
+
+
+// ------------------------------------------------------------------------------------------------
+Exporter :: Exporter() 
+: pimpl(new ExporterPimpl())
+{
+}
+
+
+// ------------------------------------------------------------------------------------------------
+Exporter :: ~Exporter()
+{
+	delete pimpl;
+}
+
+
+// ------------------------------------------------------------------------------------------------
+void Exporter :: SetIOHandler( IOSystem* pIOHandler)
+{
+	pimpl->mIsDefaultIOHandler = !pIOHandler;
+	pimpl->mIOSystem.reset(pIOHandler);
+}
+
+
+// ------------------------------------------------------------------------------------------------
+IOSystem* Exporter :: GetIOHandler() const
+{
+	return pimpl->mIOSystem.get();
+}
+
+
+// ------------------------------------------------------------------------------------------------
+bool Exporter :: IsDefaultIOHandler() const
+{
+	return pimpl->mIsDefaultIOHandler;
+}
+
+
+// ------------------------------------------------------------------------------------------------
+const aiExportDataBlob* Exporter :: ExportToBlob(  const aiScene* pScene, const char* pFormatId )
+{
+	if (pimpl->blob) {
+		delete pimpl->blob;
+		pimpl->blob = NULL;
+	}
+
+	/* TODO (ALEX)
+
+	boost::shared_ptr<IOSystem*> old = pimpl->mIOSystem;
+
+	BlobIOSystem* blobio;
+	pimpl->mIOSystem = blobio = new BlobIOSystem();
+
+	if (AI_SUCCESS != Export(pScene,pFormatId)) {
+		pimpl->mIOSystem = old;
+		return NULL;
+	}
+
+	pimpl->blob = blobio->GetBlob();
+	pimpl->mIOSystem = old;
+
+	return pimpl->blob;
+	*/
+	return NULL;
+}
+
+
+// ------------------------------------------------------------------------------------------------
+aiReturn Exporter :: Export( const aiScene* pScene, const char* pFormatId, const char* pPath )
+{
+	return AI_FAILURE;
+}
+
+
+// ------------------------------------------------------------------------------------------------
+const aiExportDataBlob* Exporter :: GetBlob() const 
+{
+	return pimpl->blob;
+}
+
+
+// ------------------------------------------------------------------------------------------------
+const aiExportDataBlob* Exporter :: GetOrphanedBlob() const 
+{
+	const aiExportDataBlob* tmp = pimpl->blob;
+	pimpl->blob = NULL;
+	return tmp;
+}
+
+
+// ------------------------------------------------------------------------------------------------
+size_t Exporter :: aiGetExportFormatCount() const 
+{
+	return ::aiGetExportFormatCount();
+}
+
+// ------------------------------------------------------------------------------------------------
+const aiExportFormatDesc* Exporter :: aiGetExportFormatDescription( size_t pIndex ) const 
+{
+	return ::aiGetExportFormatDescription(pIndex);
+}
+
+
+
 // ------------------------------------------------------------------------------------------------
 ASSIMP_API size_t aiGetExportFormatCount(void)
 {
@@ -95,7 +243,7 @@ ASSIMP_API size_t aiGetExportFormatCount(void)
 
 
 // ------------------------------------------------------------------------------------------------
-ASSIMP_API const C_STRUCT aiExportFormatDesc* aiGetExportFormatDescription( size_t pIndex)
+ASSIMP_API const aiExportFormatDesc* aiGetExportFormatDescription( size_t pIndex)
 {
 	if( pIndex >= aiGetExportFormatCount() )
 		return NULL;
@@ -105,19 +253,26 @@ ASSIMP_API const C_STRUCT aiExportFormatDesc* aiGetExportFormatDescription( size
 
 
 // ------------------------------------------------------------------------------------------------
-ASSIMP_API const C_STRUCT aiExportDataBlob* aiExportScene( const aiScene* pScene, const char* pFormatId )
+ASSIMP_API aiReturn aiExportScene( const aiScene* pScene, const char* pFormatId, const char* pFileName )
 {
-	return NULL;
+	return ::aiExportSceneEx(pScene,pFormatId,pFileName,NULL);
 }
 
 
 // ------------------------------------------------------------------------------------------------
-ASSIMP_API C_STRUCT aiReturn aiWriteBlobToFile( const C_STRUCT aiExportDataBlob* pBlob, const char* pPath, const aiFileIO* pIOSystem )
+ASSIMP_API aiReturn aiExportSceneEx( const aiScene* pScene, const char* pFormatId, const char* pFileName, const aiFileIO* pIO)
 {
 	return AI_FAILURE;
 }
 
 
+
+// ------------------------------------------------------------------------------------------------
+ASSIMP_API const C_STRUCT aiExportDataBlob* aiExportSceneToBlob( const aiScene* pScene, const char* pFormatId )
+{
+	return NULL;
+}
+
 // ------------------------------------------------------------------------------------------------
 ASSIMP_API C_STRUCT void aiReleaseExportData( const aiExportDataBlob* pData )
 {

+ 2 - 1
include/assimp.hpp

@@ -72,11 +72,12 @@ namespace Assimp	{
 	class BaseImporter;
 	class BaseProcess;
 	class SharedPostProcessInfo;
-	class BatchLoader;
+	class BatchLoader; 
 
 	// =======================================================================
 	// Holy stuff, only for members of the high council of the Jedi.
 	class ImporterPimpl;
+	class ExporterPimpl; // export.hpp
 } //! namespace Assimp
 
 #define AI_PROPERTY_WAS_NOT_EXISTING 0xffffffff

+ 31 - 18
include/export.h

@@ -49,10 +49,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include "aiTypes.h"
 
-#ifdef __cplusplus
-#include <boost/utility.hpp>
-#endif  //__cplusplus
-
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -115,35 +111,52 @@ struct aiExportDataBlob
 };
 
 
+// --------------------------------------------------------------------------------
+/** Exports the given scene to a chosen file format and writes the result file(s) to disk.
+* @param pScene The scene to export. Stays in possession of the caller, is not changed by the function.
+* @param pFormatId ID string to specify to which format you want to export to. Use 
+* aiGetExportFormatCount() / aiGetExportFormatDescription() to learn which export formats are available.
+* @param pFileName Output file to write
+* @param pIO custom IO implementation to be used. Use this if you use your own storage methods.
+*   If none is supplied, a default implementation using standard file IO is used. Note that
+*   #aiExportSceneToBlob is provided as convienience function to export to memory buffers.
+* @return a status code indicating the result of the export
+*/
+ASSIMP_API aiReturn aiExportScene( const C_STRUCT aiScene* pScene, const char* pFormatId, const char* pFileName);
+
+
+// --------------------------------------------------------------------------------
+/** Exports the given scene to a chosen file format using custom IO logic supplied by you.
+* @param pScene The scene to export. Stays in possession of the caller, is not changed by the function.
+* @param pFormatId ID string to specify to which format you want to export to. Use 
+* aiGetExportFormatCount() / aiGetExportFormatDescription() to learn which export formats are available.
+* @param pFileName Output file to write
+* @param pIO custom IO implementation to be used. Use this if you use your own storage methods.
+*   If none is supplied, a default implementation using standard file IO is used. Note that
+*   #aiExportSceneToBlob is provided as convienience function to export to memory buffers.
+* @return a status code indicating the result of the export
+*/
+ASSIMP_API aiReturn aiExportSceneEx( const C_STRUCT aiScene* pScene, const char* pFormatId, const char* pFileName, const C_STRUCT aiFileIO* pIO );
+
 // --------------------------------------------------------------------------------
 /** Exports the given scene to a chosen file format. Returns the exported data as a binary blob which
-* you can write into a file or something. When you're done with the data, use aiReleaseExportedData()
+* you can write into a file or something. When you're done with the data, use aiReleaseExportedBlob()
 * to free the resources associated with the export. 
 * @param pScene The scene to export. Stays in possession of the caller, is not changed by the function.
 * @param pFormatId ID string to specify to which format you want to export to. Use 
 * aiGetExportFormatCount() / aiGetExportFormatDescription() to learn which export formats are available.
 * @return the exported data or NULL in case of error
 */
-ASSIMP_API const C_STRUCT aiExportDataBlob* aiExportScene( const C_STRUCT aiScene* pScene, const char* pFormatId );
+ASSIMP_API const C_STRUCT aiExportDataBlob* aiExportSceneToBlob( const C_STRUCT aiScene* pScene, const char* pFormatId );
 
 
-// --------------------------------------------------------------------------------
-/** Convenience function to write a blob to a file. The file is written using standard C
- *  file IO functionality or via a user-supplied IOSystem implementation. 
- *  @param pBlob A data blob obtained from a previous call to #aiExportScene. Must not be NULL.
- *  @param pPath Full target file name. Target must be accessible.
- *  @param pIOSystem Custom IO implementation to be used for writing. Pass NULL to
- *    use the default implementation, which uses the standard C file IO functionality.
- *  @return AI_SUCCESS if everything was fine. */
-ASSIMP_API aiReturn aiWriteBlobToFile( const C_STRUCT aiExportDataBlob* pBlob, const char* pPath, const C_STRUCT aiFileIO* pIOSystem );
-
 
 // --------------------------------------------------------------------------------
 /** Releases the memory associated with the given exported data. Use this function to free a data blob
 * returned by aiExportScene(). 
-* @param pData the data blob returned by aiExportScene
+* @param pData the data blob returned by aiExportScenetoBlob
 */
-ASSIMP_API C_STRUCT void aiReleaseExportData( const C_STRUCT aiExportDataBlob* pData );
+ASSIMP_API C_STRUCT void aiReleaseExportBlob( const C_STRUCT aiExportDataBlob* pData );
 
 #ifdef __cplusplus
 }

+ 65 - 67
include/export.hpp

@@ -50,26 +50,66 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "export.h"
 
 namespace Assimp	{
-
+	class ExporterPimpl;
+
+// ----------------------------------------------------------------------------------
+/** CPP-API: The Exporter class forms an C++ interface to the export functionality 
+ * of the Open Asset Import Library. Note that the export interface is available
+ * only if Assimp has been built with ASSIMP_BUILD_NO_EXPORT not defined.
+ * 
+ * The interface is modelled after the importer interface and mostly
+ * symmetric. The same rules for threading etc. apply.
+*/
 class ASSIMP_API Exporter
-#ifdef __cplusplus
-	: public boost::noncopyable
-#endif // __cplusplus
+	// TODO: causes good ol' base class has no dll interface warning
+//#ifdef __cplusplus
+//	: public boost::noncopyable
+//#endif // __cplusplus
 {
 public:
 
 	
-	Exporter() : blob() {
-	}
+	Exporter();
+	~Exporter();
+
+public:
 
 
-	~Exporter() {
-		if (blob) {
-			::aiReleaseExportData(blob);
-		}
-	}
+	// -------------------------------------------------------------------
+	/** Supplies a custom IO handler to the exporter to use to open and
+	 * access files. If you need the exporter to use custion IO logic to 
+	 * access the files, you need to supply a custom implementation of 
+	 * IOSystem and IOFile to the exporter. 
+	 *
+	 * #Exporter takes ownership of the object and will destroy it 
+	 * afterwards. The previously assigned handler will be deleted.
+	 * Pass NULL to take again ownership of your IOSystem and reset Assimp
+	 * to use its default implementation, which uses plain file IO.
+	 *
+	 * @param pIOHandler The IO handler to be used in all file accesses 
+	 *   of the Importer. 
+	 */
+	void SetIOHandler( IOSystem* pIOHandler);
+
+	// -------------------------------------------------------------------
+	/** Retrieves the IO handler that is currently set.
+	 * You can use #IsDefaultIOHandler() to check whether the returned
+	 * interface is the default IO handler provided by ASSIMP. The default
+	 * handler is active as long the application doesn't supply its own
+	 * custom IO handler via #SetIOHandler().
+	 * @return A valid IOSystem interface, never NULL.
+	 */
+	IOSystem* GetIOHandler() const;
+
+	// -------------------------------------------------------------------
+	/** Checks whether a default IO handler is active 
+	 * A default handler is active as long the application doesn't 
+	 * supply its own custom IO handler via #SetIOHandler().
+	 * @return true by default
+	 */
+	bool IsDefaultIOHandler() const;
+
 
-public:
 
 	// -------------------------------------------------------------------
 	/** Exports the given scene to a chosen file format. Returns the exported 
@@ -85,77 +125,37 @@ public:
 	* @return the exported data or NULL in case of error.
 	* @note If the Exporter instance did already hold a blob from
 	*   a previous call to #ExportToBlob, it will be disposed. */
-	const aiExportDataBlob* ExportToBlob(  const aiScene* pScene, const char* pFormatId ) {
-		if (blob) {
-			::aiReleaseExportData(blob);
-		}
-
-		return blob = ::aiExportScene(pScene,pFormatId);
-	}
+	const aiExportDataBlob* ExportToBlob(  const aiScene* pScene, const char* pFormatId );
 
 
 	// -------------------------------------------------------------------
-	/** Convenience function to export directly to a file.
+	/** Convenience function to export directly to a file. Use
+	 *  #SetIOSystem to supply a custom IOSystem to gain fine-grained control
+	 *  about the output data flow of the export process.
 	 * @param pBlob A data blob obtained from a previous call to #aiExportScene. Must not be NULL.
 	 * @param pPath Full target file name. Target must be accessible.
 	 * @return AI_SUCCESS if everything was fine. */
-	aiReturn ExportToFile( const aiScene* pScene, const char* pFormatId, const char* pPath ) {
-		
-		if(!ExportToBlob(pScene,pFormatId)) {
-			return AI_FAILURE;
-		}
+	aiReturn Export( const aiScene* pScene, const char* pFormatId, const char* pPath );
 
 
-		return WriteBlobToFile(pPath);
-	}
-
-
-	// -------------------------------------------------------------------
-	/** Convenience function to write a blob to a file. 
-	 * @param pBlob A data blob obtained from a previous call to #aiExportScene. Must not be NULL.
-	 * @param pPath Full target file name. Target must be accessible.
-	 * @return AI_SUCCESS if everything was fine. */
-	aiReturn WriteBlobToFile( const char* pPath ) const {
-		if (!blob) {
-			return AI_FAILURE;
-		}
-
-		// TODO
-		return AI_FAILURE; // ::aiWriteBlobToFile(blob,pPath,mIOSystem);
-	}
-
-
-	// -------------------------------------------------------------------
-	aiReturn WriteBlobToFile( const std::string& pPath ) const {
-		return WriteBlobToFile(pPath.c_str());
-	}
-
 
 	// -------------------------------------------------------------------
 	/** Return the blob obtained from the last call to #ExportToBlob */
-	const aiExportDataBlob* GetBlob() const {
-		return blob;
-	}
+	const aiExportDataBlob* GetBlob() const;
 
 
 	// -------------------------------------------------------------------
-	/** Orphan the blob from the last call to #ExportToBlob. That means
+	/** Orphan the blob from the last call to #ExportToBlob. This means
 	 *  the caller takes ownership and is thus responsible for calling
 	 *  #aiReleaseExportData to free the data again. */
-	const aiExportDataBlob* GetOrphanedBlob() const {
-		const aiExportDataBlob* tmp = blob;
-		blob = NULL;
-		return tmp;
-	}
+	const aiExportDataBlob* GetOrphanedBlob() const;
 
 
 	// -------------------------------------------------------------------
 	/** Returns the number of export file formats available in the current
 	 *  Assimp build. Use #Exporter::GetExportFormatDescription to
 	 *  retrieve infos of a specific export format */
-	size_t aiGetExportFormatCount() const {
-		return ::aiGetExportFormatCount();
-	}
+	size_t aiGetExportFormatCount() const;
 
 
 	// -------------------------------------------------------------------
@@ -166,15 +166,13 @@ public:
 	 *  for. Valid range is 0 to #Exporter::GetExportFormatCount
 	 * @return A description of that specific export format. 
 	 *  NULL if pIndex is out of range. */
-	const aiExportFormatDesc* aiGetExportFormatDescription( size_t pIndex ) const {
-		return ::aiGetExportFormatDescription(pIndex);
-	}
+	const aiExportFormatDesc* aiGetExportFormatDescription( size_t pIndex ) const;
 
 
-private:
+protected:
 
-	const aiExportDataBlob* blob;
-	Assimp::IOSystem* mIOSystem;
+	// Just because we don't want you to know how we're hacking around.
+	ExporterPimpl* pimpl;
 };
 
 } // namespace Assimp