nuclear@0: /* nuclear@0: --------------------------------------------------------------------------- nuclear@0: Open Asset Import Library (assimp) nuclear@0: --------------------------------------------------------------------------- nuclear@0: nuclear@0: Copyright (c) 2006-2011, assimp team nuclear@0: nuclear@0: All rights reserved. nuclear@0: nuclear@0: Redistribution and use of this software in source and binary forms, nuclear@0: with or without modification, are permitted provided that the following nuclear@0: conditions are met: nuclear@0: nuclear@0: * Redistributions of source code must retain the above nuclear@0: copyright notice, this list of conditions and the nuclear@0: following disclaimer. nuclear@0: nuclear@0: * Redistributions in binary form must reproduce the above nuclear@0: copyright notice, this list of conditions and the nuclear@0: following disclaimer in the documentation and/or other nuclear@0: materials provided with the distribution. nuclear@0: nuclear@0: * Neither the name of the assimp team, nor the names of its nuclear@0: contributors may be used to endorse or promote products nuclear@0: derived from this software without specific prior nuclear@0: written permission of the assimp team. nuclear@0: nuclear@0: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS nuclear@0: "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT nuclear@0: LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR nuclear@0: A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT nuclear@0: OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, nuclear@0: SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT nuclear@0: LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, nuclear@0: DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY nuclear@0: THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT nuclear@0: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE nuclear@0: OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. nuclear@0: --------------------------------------------------------------------------- nuclear@0: */ nuclear@0: nuclear@0: /** @file export.hpp nuclear@0: * @brief Defines the CPP-API for the Assimp export interface nuclear@0: */ nuclear@0: #ifndef AI_EXPORT_HPP_INC nuclear@0: #define AI_EXPORT_HPP_INC nuclear@0: nuclear@0: #ifndef ASSIMP_BUILD_NO_EXPORT nuclear@0: nuclear@0: #include "cexport.h" nuclear@0: nuclear@0: namespace Assimp { nuclear@0: class ExporterPimpl; nuclear@0: class IOSystem; nuclear@0: nuclear@0: nuclear@0: // ---------------------------------------------------------------------------------- nuclear@0: /** CPP-API: The Exporter class forms an C++ interface to the export functionality nuclear@0: * of the Open Asset Import Library. Note that the export interface is available nuclear@0: * only if Assimp has been built with ASSIMP_BUILD_NO_EXPORT not defined. nuclear@0: * nuclear@0: * The interface is modelled after the importer interface and mostly nuclear@0: * symmetric. The same rules for threading etc. apply. nuclear@0: * nuclear@0: * In a nutshell, there are two export interfaces: #Export, which writes the nuclear@0: * output file(s) either to the regular file system or to a user-supplied nuclear@0: * #IOSystem, and #ExportToBlob which returns a linked list of memory nuclear@0: * buffers (blob), each referring to one output file (in most cases nuclear@0: * there will be only one output file of course, but this extra complexity is nuclear@0: * needed since Assimp aims at supporting a wide range of file formats). nuclear@0: * nuclear@0: * #ExportToBlob is especially useful if you intend to work nuclear@0: * with the data in-memory. nuclear@0: */ nuclear@0: class ASSIMP_API Exporter nuclear@0: // TODO: causes good ol' base class has no dll interface warning nuclear@0: //#ifdef __cplusplus nuclear@0: // : public boost::noncopyable nuclear@0: //#endif // __cplusplus nuclear@0: { nuclear@0: public: nuclear@0: nuclear@0: /** Function pointer type of a Export worker function */ nuclear@0: typedef void (*fpExportFunc)(const char*,IOSystem*,const aiScene*); nuclear@0: nuclear@0: /** Internal description of an Assimp export format option */ nuclear@0: struct ExportFormatEntry nuclear@0: { nuclear@0: /// Public description structure to be returned by aiGetExportFormatDescription() nuclear@0: aiExportFormatDesc mDescription; nuclear@0: nuclear@0: // Worker function to do the actual exporting nuclear@0: fpExportFunc mExportFunction; nuclear@0: nuclear@0: // Postprocessing steps to be executed PRIOR to invoking mExportFunction nuclear@0: unsigned int mEnforcePP; nuclear@0: nuclear@0: // Constructor to fill all entries nuclear@0: ExportFormatEntry( const char* pId, const char* pDesc, const char* pExtension, fpExportFunc pFunction, unsigned int pEnforcePP = 0u) nuclear@0: { nuclear@0: mDescription.id = pId; nuclear@0: mDescription.description = pDesc; nuclear@0: mDescription.fileExtension = pExtension; nuclear@0: mExportFunction = pFunction; nuclear@0: mEnforcePP = pEnforcePP; nuclear@0: } nuclear@0: nuclear@0: ExportFormatEntry() : mExportFunction(), mEnforcePP() {} nuclear@0: }; nuclear@0: nuclear@0: nuclear@0: public: nuclear@0: nuclear@0: nuclear@0: Exporter(); nuclear@0: ~Exporter(); nuclear@0: nuclear@0: public: nuclear@0: nuclear@0: nuclear@0: // ------------------------------------------------------------------- nuclear@0: /** Supplies a custom IO handler to the exporter to use to open and nuclear@0: * access files. nuclear@0: * nuclear@0: * If you need #Export to use custom IO logic to access the files, nuclear@0: * you need to supply a custom implementation of IOSystem and nuclear@0: * IOFile to the exporter. nuclear@0: * nuclear@0: * #Exporter takes ownership of the object and will destroy it nuclear@0: * afterwards. The previously assigned handler will be deleted. nuclear@0: * Pass NULL to take again ownership of your IOSystem and reset Assimp nuclear@0: * to use its default implementation, which uses plain file IO. nuclear@0: * nuclear@0: * @param pIOHandler The IO handler to be used in all file accesses nuclear@0: * of the Importer. */ nuclear@0: void SetIOHandler( IOSystem* pIOHandler); nuclear@0: nuclear@0: // ------------------------------------------------------------------- nuclear@0: /** Retrieves the IO handler that is currently set. nuclear@0: * You can use #IsDefaultIOHandler() to check whether the returned nuclear@0: * interface is the default IO handler provided by ASSIMP. The default nuclear@0: * handler is active as long the application doesn't supply its own nuclear@0: * custom IO handler via #SetIOHandler(). nuclear@0: * @return A valid IOSystem interface, never NULL. */ nuclear@0: IOSystem* GetIOHandler() const; nuclear@0: nuclear@0: // ------------------------------------------------------------------- nuclear@0: /** Checks whether a default IO handler is active nuclear@0: * A default handler is active as long the application doesn't nuclear@0: * supply its own custom IO handler via #SetIOHandler(). nuclear@0: * @return true by default */ nuclear@0: bool IsDefaultIOHandler() const; nuclear@0: nuclear@0: nuclear@0: nuclear@0: // ------------------------------------------------------------------- nuclear@0: /** Exports the given scene to a chosen file format. Returns the exported nuclear@0: * data as a binary blob which you can write into a file or something. nuclear@0: * When you're done with the data, simply let the #Exporter instance go nuclear@0: * out of scope to have it released automatically. nuclear@0: * @param pScene The scene to export. Stays in possession of the caller, nuclear@0: * is not changed by the function. nuclear@0: * @param pFormatId ID string to specify to which format you want to nuclear@0: * export to. Use nuclear@0: * #GetExportFormatCount / #GetExportFormatDescription to learn which nuclear@0: * export formats are available. nuclear@0: * @param pPreprocessing See the documentation for #Export nuclear@0: * @return the exported data or NULL in case of error. nuclear@0: * @note If the Exporter instance did already hold a blob from nuclear@0: * a previous call to #ExportToBlob, it will be disposed. nuclear@0: * Any IO handlers set via #SetIOHandler are ignored here.*/ nuclear@0: const aiExportDataBlob* ExportToBlob( const aiScene* pScene, const char* pFormatId, unsigned int pPreprocessing = 0u ); nuclear@0: inline const aiExportDataBlob* ExportToBlob( const aiScene* pScene, const std::string& pFormatId, unsigned int pPreprocessing = 0u ); nuclear@0: nuclear@0: nuclear@0: // ------------------------------------------------------------------- nuclear@0: /** Convenience function to export directly to a file. Use nuclear@0: * #SetIOSystem to supply a custom IOSystem to gain fine-grained control nuclear@0: * about the output data flow of the export process. nuclear@0: * @param pBlob A data blob obtained from a previous call to #aiExportScene. Must not be NULL. nuclear@0: * @param pPath Full target file name. Target must be accessible. nuclear@0: * @param pPreprocessing Accepts any choice of the #aiPostProcessing enumerated nuclear@0: * flags, but in reality only a subset of them makes sense here. Specifying nuclear@0: * 'preprocessing' flags is useful if the input scene does not conform to nuclear@0: * Assimp's default conventions as specified in the @link data Data Structures Page @endlink. nuclear@0: * In short, this means the geometry data should use a right-handed coordinate systems, face nuclear@0: * winding should be counter-clockwise and the UV coordinate origin is assumed to be in nuclear@0: * the upper left. The #aiProcess_MakeLeftHanded, #aiProcess_FlipUVs and nuclear@0: * #aiProcess_FlipWindingOrder flags are used in the import side to allow users nuclear@0: * to have those defaults automatically adapted to their conventions. Specifying those flags nuclear@0: * for exporting has the opposite effect, respectively. Some other of the nuclear@0: * #aiPostProcessSteps enumerated values may be useful as well, but you'll need nuclear@0: * to try out what their effect on the exported file is. Many formats impose nuclear@0: * their own restrictions on the structure of the geometry stored therein, nuclear@0: * so some preprocessing may have little or no effect at all, or may be nuclear@0: * redundant as exporters would apply them anyhow. A good example nuclear@0: * is triangulation - whilst you can enforce it by specifying nuclear@0: * the #aiProcess_Triangulate flag, most export formats support only nuclear@0: * triangulate data so they would run the step even if it wasn't requested. nuclear@0: * @return AI_SUCCESS if everything was fine. */ nuclear@0: aiReturn Export( const aiScene* pScene, const char* pFormatId, const char* pPath, unsigned int pPreprocessing = 0u); nuclear@0: inline aiReturn Export( const aiScene* pScene, const std::string& pFormatId, const std::string& pPath, unsigned int pPreprocessing = 0u); nuclear@0: nuclear@0: nuclear@0: // ------------------------------------------------------------------- nuclear@0: /** Returns an error description of an error that occurred in #Export nuclear@0: * or #ExportToBlob nuclear@0: * nuclear@0: * Returns an empty string if no error occurred. nuclear@0: * @return A description of the last error, an empty string if no nuclear@0: * error occurred. The string is never NULL. nuclear@0: * nuclear@0: * @note The returned function remains valid until one of the nuclear@0: * following methods is called: #Export, #ExportToBlob, #FreeBlob */ nuclear@0: const char* GetErrorString() const; nuclear@0: nuclear@0: nuclear@0: // ------------------------------------------------------------------- nuclear@0: /** Return the blob obtained from the last call to #ExportToBlob */ nuclear@0: const aiExportDataBlob* GetBlob() const; nuclear@0: nuclear@0: nuclear@0: // ------------------------------------------------------------------- nuclear@0: /** Orphan the blob from the last call to #ExportToBlob. This means nuclear@0: * the caller takes ownership and is thus responsible for calling nuclear@0: * the C API function #aiReleaseExportBlob to release it. */ nuclear@0: const aiExportDataBlob* GetOrphanedBlob() const; nuclear@0: nuclear@0: nuclear@0: // ------------------------------------------------------------------- nuclear@0: /** Frees the current blob. nuclear@0: * nuclear@0: * The function does nothing if no blob has previously been nuclear@0: * previously produced via #ExportToBlob. #FreeBlob is called nuclear@0: * automatically by the destructor. The only reason to call nuclear@0: * it manually would be to reclain as much storage as possible nuclear@0: * without giving up the #Exporter instance yet. */ nuclear@0: void FreeBlob( ); nuclear@0: nuclear@0: nuclear@0: // ------------------------------------------------------------------- nuclear@0: /** Returns the number of export file formats available in the current nuclear@0: * Assimp build. Use #Exporter::GetExportFormatDescription to nuclear@0: * retrieve infos of a specific export format */ nuclear@0: size_t GetExportFormatCount() const; nuclear@0: nuclear@0: nuclear@0: // ------------------------------------------------------------------- nuclear@0: /** Returns a description of the nth export file format. Use # nuclear@0: * #Exporter::GetExportFormatCount to learn how many export nuclear@0: * formats are supported. nuclear@0: * @param pIndex Index of the export format to retrieve information nuclear@0: * for. Valid range is 0 to #Exporter::GetExportFormatCount nuclear@0: * @return A description of that specific export format. nuclear@0: * NULL if pIndex is out of range. */ nuclear@0: const aiExportFormatDesc* GetExportFormatDescription( size_t pIndex ) const; nuclear@0: nuclear@0: nuclear@0: // ------------------------------------------------------------------- nuclear@0: /** Register a custom exporter. Custom export formats are limited to nuclear@0: * to the current #Exporter instance and do not affect the nuclear@0: * library globally. nuclear@0: * @param desc Exporter description. nuclear@0: * @return aiReturn_SUCCESS if the export format was successfully nuclear@0: * registered. A common cause that would prevent an exporter nuclear@0: * from being registered is that its format id is already nuclear@0: * occupied by another format. */ nuclear@0: aiReturn RegisterExporter(const ExportFormatEntry& desc); nuclear@0: nuclear@0: nuclear@0: // ------------------------------------------------------------------- nuclear@0: /** Remove an export format previously registered with #RegisterExporter nuclear@0: * from the #Exporter instance (this can also be used to drop nuclear@0: * builtin exporters because those are implicitly registered nuclear@0: * using #RegisterExporter). nuclear@0: * @param id Format id to be unregistered, this refers to the nuclear@0: * 'id' field of #aiExportFormatDesc. nuclear@0: * @note Calling this method on a format description not yet registered nuclear@0: * has no effect.*/ nuclear@0: void UnregisterExporter(const char* id); nuclear@0: nuclear@0: nuclear@0: protected: nuclear@0: nuclear@0: // Just because we don't want you to know how we're hacking around. nuclear@0: ExporterPimpl* pimpl; nuclear@0: }; nuclear@0: nuclear@0: nuclear@0: // ---------------------------------------------------------------------------------- nuclear@0: inline const aiExportDataBlob* Exporter :: ExportToBlob( const aiScene* pScene, const std::string& pFormatId,unsigned int pPreprocessing ) nuclear@0: { nuclear@0: return ExportToBlob(pScene,pFormatId.c_str(),pPreprocessing); nuclear@0: } nuclear@0: nuclear@0: // ---------------------------------------------------------------------------------- nuclear@0: inline aiReturn Exporter :: Export( const aiScene* pScene, const std::string& pFormatId, const std::string& pPath, unsigned int pPreprocessing ) nuclear@0: { nuclear@0: return Export(pScene,pFormatId.c_str(),pPath.c_str(),pPreprocessing); nuclear@0: } nuclear@0: nuclear@0: } // namespace Assimp nuclear@0: #endif // ASSIMP_BUILD_NO_EXPORT nuclear@0: #endif // AI_EXPORT_HPP_INC nuclear@0: