From 553b3567c8c5f7fdff4748614dfc857195f50407 Mon Sep 17 00:00:00 2001 From: aramis_acg Date: Tue, 11 Jan 2011 22:15:28 +0000 Subject: [PATCH] - 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 --- code/AssimpPCH.h | 2 +- code/Exporter.cpp | 167 +++++++++++++++++++++++++++++++++++++++++++-- include/assimp.hpp | 3 +- include/export.h | 49 ++++++++----- include/export.hpp | 132 ++++++++++++++++++----------------- 5 files changed, 260 insertions(+), 93 deletions(-) diff --git a/code/AssimpPCH.h b/code/AssimpPCH.h index 08d800804..19e809c24 100644 --- a/code/AssimpPCH.h +++ b/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" diff --git a/code/Exporter.cpp b/code/Exporter.cpp index 7d12d47a5..c45c5cf6f 100644 --- a/code/Exporter.cpp +++ b/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 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 ) { diff --git a/include/assimp.hpp b/include/assimp.hpp index 94e7fb1a5..1d254551b 100644 --- a/include/assimp.hpp +++ b/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 diff --git a/include/export.h b/include/export.h index 759ecd944..a8e3f0790 100644 --- a/include/export.h +++ b/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 -#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 } diff --git a/include/export.hpp b/include/export.hpp index 2049d2f9b..2a807ae52 100644 --- a/include/export.hpp +++ b/include/export.hpp @@ -50,27 +50,67 @@ 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() { - if (blob) { - ::aiReleaseExportData(blob); - } - } + Exporter(); + ~Exporter(); public: + + // ------------------------------------------------------------------- + /** 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; + + + // ------------------------------------------------------------------- /** 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. @@ -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