2015-05-19 03:48:29 +00:00
/*
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Open Asset Import Library ( assimp )
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2024-02-23 21:30:05 +00:00
Copyright ( c ) 2006 - 2024 , assimp team
2018-01-28 18:42:05 +00:00
2015-05-19 03:48:29 +00:00
All rights reserved .
2015-05-19 03:52:10 +00:00
Redistribution and use of this software in source and binary forms ,
with or without modification , are permitted provided that the following
2015-05-19 03:48:29 +00:00
conditions are met :
* Redistributions of source code must retain the above
copyright notice , this list of conditions and the
following disclaimer .
* Redistributions in binary form must reproduce the above
copyright notice , this list of conditions and the
following disclaimer in the documentation and / or other
materials provided with the distribution .
* Neither the name of the assimp team , nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team .
2015-05-19 03:52:10 +00:00
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
" AS IS " AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT
2015-05-19 03:48:29 +00:00
LIMITED TO , THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2015-05-19 03:52:10 +00:00
A PARTICULAR PURPOSE ARE DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT
2015-05-19 03:48:29 +00:00
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT , INDIRECT , INCIDENTAL ,
2015-05-19 03:52:10 +00:00
SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT NOT
2015-05-19 03:48:29 +00:00
LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE ,
2015-05-19 03:52:10 +00:00
DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE
2015-05-19 03:48:29 +00:00
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 .
Here we implement only the C + + interface ( Assimp : : Exporter ) .
*/
# ifndef ASSIMP_BUILD_NO_EXPORT
2018-01-06 00:18:33 +00:00
# include <assimp/BlobIOSystem.h>
2017-06-21 13:24:06 +00:00
# include <assimp/SceneCombiner.h>
2018-11-12 21:26:10 +00:00
# include <assimp/DefaultIOSystem.h>
# include <assimp/Exporter.hpp>
# include <assimp/mesh.h>
# include <assimp/postprocess.h>
# include <assimp/scene.h>
2018-01-06 00:18:33 +00:00
# include <assimp/Exceptional.h>
2019-06-10 21:26:00 +00:00
# include "Common/DefaultProgressHandler.h"
# include "Common/BaseProcess.h"
# include "Common/ScenePrivate.h"
# include "PostProcessing/CalcTangentsProcess.h"
# include "PostProcessing/MakeVerboseFormat.h"
# include "PostProcessing/JoinVerticesProcess.h"
# include "PostProcessing/ConvertToLHProcess.h"
# include "PostProcessing/PretransformVertices.h"
2017-02-28 02:31:56 +00:00
2018-11-12 21:26:10 +00:00
# include <memory>
2015-05-19 03:48:29 +00:00
namespace Assimp {
2020-07-17 13:58:51 +00:00
# ifdef _MSC_VER
2020-07-07 15:35:03 +00:00
# pragma warning( disable : 4800 )
2020-07-17 13:58:51 +00:00
# endif // _MSC_VER
2020-03-18 18:31:30 +00:00
2015-05-19 03:48:29 +00:00
// PostStepRegistry.cpp
void GetPostProcessingStepInstanceList ( std : : vector < BaseProcess * > & out ) ;
// ------------------------------------------------------------------------------------------------
2021-07-29 11:28:51 +00:00
// Exporter worker function prototypes. Do not use const, because some exporter need to convert
2020-03-05 01:15:09 +00:00
// the scene temporary
# ifndef ASSIMP_BUILD_NO_COLLADA_EXPORTER
2015-05-19 03:48:29 +00:00
void ExportSceneCollada ( const char * , IOSystem * , const aiScene * , const ExportProperties * ) ;
2020-03-05 01:15:09 +00:00
# endif
# ifndef ASSIMP_BUILD_NO_X_EXPORTER
2015-05-19 03:48:29 +00:00
void ExportSceneXFile ( const char * , IOSystem * , const aiScene * , const ExportProperties * ) ;
2020-03-05 01:15:09 +00:00
# endif
# ifndef ASSIMP_BUILD_NO_STEP_EXPORTER
2015-05-19 03:48:29 +00:00
void ExportSceneStep ( const char * , IOSystem * , const aiScene * , const ExportProperties * ) ;
2020-03-05 01:15:09 +00:00
# endif
# ifndef ASSIMP_BUILD_NO_OBJ_EXPORTER
2015-05-19 03:48:29 +00:00
void ExportSceneObj ( const char * , IOSystem * , const aiScene * , const ExportProperties * ) ;
2017-10-26 15:59:09 +00:00
void ExportSceneObjNoMtl ( const char * , IOSystem * , const aiScene * , const ExportProperties * ) ;
2020-03-05 01:15:09 +00:00
# endif
2020-04-16 08:23:50 +00:00
# ifndef ASSIMP_BUILD_NO_STL_EXPORTER
2015-05-19 03:48:29 +00:00
void ExportSceneSTL ( const char * , IOSystem * , const aiScene * , const ExportProperties * ) ;
void ExportSceneSTLBinary ( const char * , IOSystem * , const aiScene * , const ExportProperties * ) ;
2020-03-05 01:15:09 +00:00
# endif
# ifndef ASSIMP_BUILD_NO_PLY_EXPORTER
2015-05-19 03:48:29 +00:00
void ExportScenePly ( const char * , IOSystem * , const aiScene * , const ExportProperties * ) ;
void ExportScenePlyBinary ( const char * , IOSystem * , const aiScene * , const ExportProperties * ) ;
2020-03-05 01:15:09 +00:00
# endif
# ifndef ASSIMP_BUILD_NO_3DS_EXPORTER
2015-05-19 03:48:29 +00:00
void ExportScene3DS ( const char * , IOSystem * , const aiScene * , const ExportProperties * ) ;
2020-03-05 01:15:09 +00:00
# endif
# ifndef ASSIMP_BUILD_NO_GLTF_EXPORTER
2015-11-27 00:16:48 +00:00
void ExportSceneGLTF ( const char * , IOSystem * , const aiScene * , const ExportProperties * ) ;
void ExportSceneGLB ( const char * , IOSystem * , const aiScene * , const ExportProperties * ) ;
2017-07-20 17:59:21 +00:00
void ExportSceneGLTF2 ( const char * , IOSystem * , const aiScene * , const ExportProperties * ) ;
2017-12-14 15:11:12 +00:00
void ExportSceneGLB2 ( const char * , IOSystem * , const aiScene * , const ExportProperties * ) ;
2020-03-05 01:15:09 +00:00
# endif
# ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER
2015-05-19 03:48:29 +00:00
void ExportSceneAssbin ( const char * , IOSystem * , const aiScene * , const ExportProperties * ) ;
2020-03-05 01:15:09 +00:00
# endif
# ifndef ASSIMP_BUILD_NO_ASSXML_EXPORTER
2015-05-19 03:48:29 +00:00
void ExportSceneAssxml ( const char * , IOSystem * , const aiScene * , const ExportProperties * ) ;
2020-03-05 01:15:09 +00:00
# endif
# ifndef ASSIMP_BUILD_NO_X3D_EXPORTER
2016-10-04 20:55:08 +00:00
void ExportSceneX3D ( const char * , IOSystem * , const aiScene * , const ExportProperties * ) ;
2020-03-05 01:15:09 +00:00
# endif
# ifndef ASSIMP_BUILD_NO_FBX_EXPORTER
2018-02-19 12:46:02 +00:00
void ExportSceneFBX ( const char * , IOSystem * , const aiScene * , const ExportProperties * ) ;
2018-03-28 19:40:26 +00:00
void ExportSceneFBXA ( const char * , IOSystem * , const aiScene * , const ExportProperties * ) ;
2020-03-05 01:15:09 +00:00
# endif
# ifndef ASSIMP_BUILD_NO_3MF_EXPORTER
2017-11-21 17:41:16 +00:00
void ExportScene3MF ( const char * , IOSystem * , const aiScene * , const ExportProperties * ) ;
2020-03-05 01:15:09 +00:00
# endif
# ifndef ASSIMP_BUILD_NO_M3D_EXPORTER
2019-10-29 13:14:00 +00:00
void ExportSceneM3D ( const char * , IOSystem * , const aiScene * , const ExportProperties * ) ;
2019-12-09 11:23:57 +00:00
void ExportSceneM3DA ( const char * , IOSystem * , const aiScene * , const ExportProperties * ) ;
2020-03-05 01:15:09 +00:00
# endif
# ifndef ASSIMP_BUILD_NO_ASSJSON_EXPORTER
2019-07-11 15:43:03 +00:00
void ExportAssimp2Json ( const char * , IOSystem * , const aiScene * , const Assimp : : ExportProperties * ) ;
2020-03-05 01:15:09 +00:00
# endif
2021-01-12 03:57:10 +00:00
# ifndef ASSIMP_BUILD_NO_PBRT_EXPORTER
void ExportScenePbrt ( const char * , IOSystem * , const aiScene * , const ExportProperties * ) ;
# endif
2019-11-10 08:47:50 +00:00
static void setupExporterArray ( std : : vector < Exporter : : ExportFormatEntry > & exporters ) {
2020-09-05 21:17:11 +00:00
( void ) exporters ;
2015-05-19 03:48:29 +00:00
# ifndef ASSIMP_BUILD_NO_COLLADA_EXPORTER
2022-08-23 15:41:49 +00:00
exporters . emplace_back ( " collada " , " COLLADA - Digital Asset Exchange Schema " , " dae " , & ExportSceneCollada ) ;
2015-05-19 03:48:29 +00:00
# endif
2016-12-05 09:12:46 +00:00
# ifndef ASSIMP_BUILD_NO_X_EXPORTER
2022-08-23 15:41:49 +00:00
exporters . emplace_back ( " x " , " X Files " , " x " , & ExportSceneXFile ,
aiProcess_MakeLeftHanded | aiProcess_FlipWindingOrder | aiProcess_FlipUVs ) ;
2015-05-19 03:48:29 +00:00
# endif
# ifndef ASSIMP_BUILD_NO_STEP_EXPORTER
2022-08-23 15:41:49 +00:00
exporters . emplace_back ( " stp " , " Step Files " , " stp " , & ExportSceneStep , 0 ) ;
2015-05-19 03:48:29 +00:00
# endif
# ifndef ASSIMP_BUILD_NO_OBJ_EXPORTER
2022-08-23 15:41:49 +00:00
exporters . emplace_back ( " obj " , " Wavefront OBJ format " , " obj " , & ExportSceneObj ,
aiProcess_GenSmoothNormals /*| aiProcess_PreTransformVertices */ ) ;
exporters . emplace_back ( " objnomtl " , " Wavefront OBJ format without material file " , " obj " , & ExportSceneObjNoMtl ,
aiProcess_GenSmoothNormals /*| aiProcess_PreTransformVertices */ ) ;
2015-05-19 03:48:29 +00:00
# endif
# ifndef ASSIMP_BUILD_NO_STL_EXPORTER
2022-08-23 15:41:49 +00:00
exporters . emplace_back ( " stl " , " Stereolithography " , " stl " , & ExportSceneSTL ,
aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_PreTransformVertices ) ;
exporters . emplace_back ( " stlb " , " Stereolithography (binary) " , " stl " , & ExportSceneSTLBinary ,
aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_PreTransformVertices ) ;
2015-05-19 03:48:29 +00:00
# endif
# ifndef ASSIMP_BUILD_NO_PLY_EXPORTER
2022-08-23 15:41:49 +00:00
exporters . emplace_back ( " ply " , " Stanford Polygon Library " , " ply " , & ExportScenePly ,
aiProcess_PreTransformVertices ) ;
exporters . emplace_back ( " plyb " , " Stanford Polygon Library (binary) " , " ply " , & ExportScenePlyBinary ,
aiProcess_PreTransformVertices ) ;
2015-05-19 03:48:29 +00:00
# endif
# ifndef ASSIMP_BUILD_NO_3DS_EXPORTER
2022-08-23 15:41:49 +00:00
exporters . emplace_back ( " 3ds " , " Autodesk 3DS (legacy) " , " 3ds " , & ExportScene3DS ,
aiProcess_Triangulate | aiProcess_SortByPType | aiProcess_JoinIdenticalVertices ) ;
2015-05-19 03:48:29 +00:00
# endif
2020-07-05 18:22:31 +00:00
# if !defined(ASSIMP_BUILD_NO_GLTF_EXPORTER) && !defined(ASSIMP_BUILD_NO_GLTF2_EXPORTER)
2022-08-23 15:41:49 +00:00
exporters . emplace_back ( " gltf2 " , " GL Transmission Format v. 2 " , " gltf " , & ExportSceneGLTF2 ,
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ) ;
exporters . emplace_back ( " glb2 " , " GL Transmission Format v. 2 (binary) " , " glb " , & ExportSceneGLB2 ,
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ) ;
2020-07-05 18:22:31 +00:00
# endif
# if !defined(ASSIMP_BUILD_NO_GLTF_EXPORTER) && !defined(ASSIMP_BUILD_NO_GLTF1_EXPORTER)
2022-08-23 15:41:49 +00:00
exporters . emplace_back ( " gltf " , " GL Transmission Format " , " gltf " , & ExportSceneGLTF ,
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ) ;
exporters . emplace_back ( " glb " , " GL Transmission Format (binary) " , " glb " , & ExportSceneGLB ,
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ) ;
2015-11-27 00:16:48 +00:00
# endif
2015-05-19 03:48:29 +00:00
# ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER
2022-08-23 15:41:49 +00:00
exporters . emplace_back ( " assbin " , " Assimp Binary File " , " assbin " , & ExportSceneAssbin , 0 ) ;
2015-05-19 03:48:29 +00:00
# endif
# ifndef ASSIMP_BUILD_NO_ASSXML_EXPORTER
2022-08-23 15:41:49 +00:00
exporters . emplace_back ( " assxml " , " Assimp XML Document " , " assxml " , & ExportSceneAssxml , 0 ) ;
2015-05-19 03:48:29 +00:00
# endif
2016-10-04 20:55:08 +00:00
# ifndef ASSIMP_BUILD_NO_X3D_EXPORTER
2022-08-23 15:41:49 +00:00
exporters . emplace_back ( " x3d " , " Extensible 3D " , " x3d " , & ExportSceneX3D , 0 ) ;
2017-11-21 17:41:16 +00:00
# endif
2018-02-19 12:46:02 +00:00
# ifndef ASSIMP_BUILD_NO_FBX_EXPORTER
2022-08-23 15:41:49 +00:00
exporters . emplace_back ( " fbx " , " Autodesk FBX (binary) " , " fbx " , & ExportSceneFBX , 0 ) ;
exporters . emplace_back ( " fbxa " , " Autodesk FBX (ascii) " , " fbx " , & ExportSceneFBXA , 0 ) ;
2018-02-19 12:46:02 +00:00
# endif
2019-10-29 13:14:00 +00:00
# ifndef ASSIMP_BUILD_NO_M3D_EXPORTER
2019-11-10 08:47:50 +00:00
exporters . push_back ( Exporter : : ExportFormatEntry ( " m3d " , " Model 3D (binary) " , " m3d " , & ExportSceneM3D , 0 ) ) ;
2019-12-09 11:23:57 +00:00
exporters . push_back ( Exporter : : ExportFormatEntry ( " m3da " , " Model 3D (ascii) " , " a3d " , & ExportSceneM3DA , 0 ) ) ;
2019-10-29 13:14:00 +00:00
# endif
2017-12-11 15:26:00 +00:00
# ifndef ASSIMP_BUILD_NO_3MF_EXPORTER
2022-08-23 15:41:49 +00:00
exporters . emplace_back ( " 3mf " , " The 3MF-File-Format " , " 3mf " , & ExportScene3MF , 0 ) ;
2019-07-11 15:43:03 +00:00
# endif
2020-04-06 19:12:37 +00:00
# ifndef ASSIMP_BUILD_NO_PBRT_EXPORTER
2023-05-03 14:49:27 +00:00
exporters . emplace_back ( " pbrt " , " pbrt-v4 scene description file " , " pbrt " , & ExportScenePbrt , aiProcess_ConvertToLeftHanded | aiProcess_Triangulate | aiProcess_SortByPType ) ;
2020-04-06 19:12:37 +00:00
# endif
2019-07-25 12:38:49 +00:00
# ifndef ASSIMP_BUILD_NO_ASSJSON_EXPORTER
2022-08-23 15:41:49 +00:00
exporters . emplace_back ( " assjson " , " Assimp JSON Document " , " json " , & ExportAssimp2Json , 0 ) ;
2016-10-04 20:55:08 +00:00
# endif
2019-11-10 08:47:50 +00:00
}
2015-05-19 03:48:29 +00:00
class ExporterPimpl {
public :
2015-05-19 03:57:13 +00:00
ExporterPimpl ( )
2018-11-12 21:26:10 +00:00
: blob ( )
, mIOSystem ( new Assimp : : DefaultIOSystem ( ) )
, mIsDefaultIOHandler ( true )
, mProgressHandler ( nullptr )
, mIsDefaultProgressHandler ( true )
, mPostProcessingSteps ( )
, mError ( )
, mExporters ( ) {
2015-05-19 03:57:13 +00:00
GetPostProcessingStepInstanceList ( mPostProcessingSteps ) ;
2015-05-19 03:48:29 +00:00
2016-11-30 14:05:06 +00:00
// grab all built-in exporters
2019-11-10 08:47:50 +00:00
setupExporterArray ( mExporters ) ;
2015-05-19 03:57:13 +00:00
}
2015-05-19 03:48:29 +00:00
2018-11-12 21:26:10 +00:00
~ ExporterPimpl ( ) {
2015-05-19 03:57:13 +00:00
delete blob ;
2015-05-19 03:48:29 +00:00
2015-05-19 03:57:13 +00:00
// Delete all post-processing plug-ins
for ( unsigned int a = 0 ; a < mPostProcessingSteps . size ( ) ; a + + ) {
delete mPostProcessingSteps [ a ] ;
}
2018-11-13 12:10:16 +00:00
delete mProgressHandler ;
2015-05-19 03:57:13 +00:00
}
2015-05-19 03:48:29 +00:00
public :
2015-05-19 03:57:13 +00:00
aiExportDataBlob * blob ;
2016-04-05 21:23:53 +00:00
std : : shared_ptr < Assimp : : IOSystem > mIOSystem ;
2015-05-19 03:57:13 +00:00
bool mIsDefaultIOHandler ;
2015-05-19 03:48:29 +00:00
2018-11-12 21:26:10 +00:00
/** The progress handler */
ProgressHandler * mProgressHandler ;
bool mIsDefaultProgressHandler ;
2015-05-19 03:57:13 +00:00
/** Post processing steps we can apply at the imported data. */
std : : vector < BaseProcess * > mPostProcessingSteps ;
2015-05-19 03:48:29 +00:00
2015-05-19 03:57:13 +00:00
/** Last fatal export error */
std : : string mError ;
2015-05-19 03:48:29 +00:00
2015-05-19 03:57:13 +00:00
/** Exporters, this includes those registered using #Assimp::Exporter::RegisterExporter */
std : : vector < Exporter : : ExportFormatEntry > mExporters ;
2015-05-19 03:48:29 +00:00
} ;
} // end of namespace Assimp
using namespace Assimp ;
// ------------------------------------------------------------------------------------------------
2015-05-19 03:52:10 +00:00
Exporter : : Exporter ( )
2017-02-04 17:32:04 +00:00
: pimpl ( new ExporterPimpl ( ) ) {
2018-11-12 21:26:10 +00:00
pimpl - > mProgressHandler = new DefaultProgressHandler ( ) ;
2015-05-19 03:48:29 +00:00
}
// ------------------------------------------------------------------------------------------------
2017-02-04 17:32:04 +00:00
Exporter : : ~ Exporter ( ) {
2019-11-10 08:47:50 +00:00
ai_assert ( nullptr ! = pimpl ) ;
FreeBlob ( ) ;
2015-05-19 03:57:13 +00:00
delete pimpl ;
2015-05-19 03:48:29 +00:00
}
// ------------------------------------------------------------------------------------------------
2017-02-04 17:32:04 +00:00
void Exporter : : SetIOHandler ( IOSystem * pIOHandler ) {
2019-11-10 08:47:50 +00:00
ai_assert ( nullptr ! = pimpl ) ;
pimpl - > mIsDefaultIOHandler = ! pIOHandler ;
2015-05-19 03:57:13 +00:00
pimpl - > mIOSystem . reset ( pIOHandler ) ;
2015-05-19 03:48:29 +00:00
}
// ------------------------------------------------------------------------------------------------
2017-02-04 17:32:04 +00:00
IOSystem * Exporter : : GetIOHandler ( ) const {
2019-11-10 08:47:50 +00:00
ai_assert ( nullptr ! = pimpl ) ;
return pimpl - > mIOSystem . get ( ) ;
2015-05-19 03:48:29 +00:00
}
// ------------------------------------------------------------------------------------------------
2017-02-04 17:32:04 +00:00
bool Exporter : : IsDefaultIOHandler ( ) const {
2019-11-10 08:47:50 +00:00
ai_assert ( nullptr ! = pimpl ) ;
return pimpl - > mIsDefaultIOHandler ;
2015-05-19 03:48:29 +00:00
}
2018-11-12 21:26:10 +00:00
// ------------------------------------------------------------------------------------------------
void Exporter : : SetProgressHandler ( ProgressHandler * pHandler ) {
ai_assert ( nullptr ! = pimpl ) ;
if ( nullptr = = pHandler ) {
// Release pointer in the possession of the caller
pimpl - > mProgressHandler = new DefaultProgressHandler ( ) ;
pimpl - > mIsDefaultProgressHandler = true ;
return ;
}
if ( pimpl - > mProgressHandler = = pHandler ) {
return ;
}
delete pimpl - > mProgressHandler ;
pimpl - > mProgressHandler = pHandler ;
pimpl - > mIsDefaultProgressHandler = false ;
}
2015-05-19 03:48:29 +00:00
// ------------------------------------------------------------------------------------------------
2017-02-28 02:31:56 +00:00
const aiExportDataBlob * Exporter : : ExportToBlob ( const aiScene * pScene , const char * pFormatId ,
2019-01-17 13:55:05 +00:00
unsigned int pPreprocessing , const ExportProperties * pProperties ) {
2019-11-10 08:47:50 +00:00
ai_assert ( nullptr ! = pimpl ) ;
2015-05-19 03:57:13 +00:00
if ( pimpl - > blob ) {
delete pimpl - > blob ;
2018-11-12 21:26:10 +00:00
pimpl - > blob = nullptr ;
2015-05-19 03:57:13 +00:00
}
2021-07-29 11:28:51 +00:00
2021-05-07 15:31:30 +00:00
auto baseName = pProperties ? pProperties - > GetPropertyString ( AI_CONFIG_EXPORT_BLOB_NAME , AI_BLOBIO_MAGIC ) : AI_BLOBIO_MAGIC ;
2015-05-19 03:48:29 +00:00
2016-04-05 21:23:53 +00:00
std : : shared_ptr < IOSystem > old = pimpl - > mIOSystem ;
2021-05-07 15:31:30 +00:00
BlobIOSystem * blobio = new BlobIOSystem ( baseName ) ;
2016-04-05 21:23:53 +00:00
pimpl - > mIOSystem = std : : shared_ptr < IOSystem > ( blobio ) ;
2015-05-19 03:48:29 +00:00
2019-01-17 13:55:05 +00:00
if ( AI_SUCCESS ! = Export ( pScene , pFormatId , blobio - > GetMagicFileName ( ) , pPreprocessing , pProperties ) ) {
2015-05-19 03:57:13 +00:00
pimpl - > mIOSystem = old ;
2018-11-12 21:26:10 +00:00
return nullptr ;
2015-05-19 03:57:13 +00:00
}
2015-05-19 03:48:29 +00:00
2015-05-19 03:57:13 +00:00
pimpl - > blob = blobio - > GetBlobChain ( ) ;
pimpl - > mIOSystem = old ;
2015-05-19 03:48:29 +00:00
2015-05-19 03:57:13 +00:00
return pimpl - > blob ;
2015-05-19 03:48:29 +00:00
}
// ------------------------------------------------------------------------------------------------
2018-03-20 13:10:08 +00:00
aiReturn Exporter : : Export ( const aiScene * pScene , const char * pFormatId , const char * pPath ,
unsigned int pPreprocessing , const ExportProperties * pProperties ) {
2015-05-19 03:57:13 +00:00
ASSIMP_BEGIN_EXCEPTION_REGION ( ) ;
2019-11-10 08:47:50 +00:00
ai_assert ( nullptr ! = pimpl ) ;
2015-05-19 03:57:13 +00:00
// when they create scenes from scratch, users will likely create them not in verbose
// 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.
2019-08-30 10:42:23 +00:00
const bool is_verbose_format = ! ( pScene - > mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT ) | | MakeVerboseFormatProcess : : IsVerboseFormat ( pScene ) ;
2015-05-19 03:57:13 +00:00
2018-11-12 21:26:10 +00:00
pimpl - > mProgressHandler - > UpdateFileWrite ( 0 , 4 ) ;
2015-05-19 03:57:13 +00:00
pimpl - > mError = " " ;
for ( size_t i = 0 ; i < pimpl - > mExporters . size ( ) ; + + i ) {
const Exporter : : ExportFormatEntry & exp = pimpl - > mExporters [ i ] ;
if ( ! strcmp ( exp . mDescription . id , pFormatId ) ) {
try {
// Always create a full copy of the scene. We might optimize this one day,
// but for now it is the most pragmatic way.
2018-11-12 21:26:10 +00:00
aiScene * scenecopy_tmp = nullptr ;
2015-05-19 03:57:13 +00:00
SceneCombiner : : CopyScene ( & scenecopy_tmp , pScene ) ;
2018-11-12 21:26:10 +00:00
pimpl - > mProgressHandler - > UpdateFileWrite ( 1 , 4 ) ;
2016-04-05 20:56:11 +00:00
std : : unique_ptr < aiScene > scenecopy ( scenecopy_tmp ) ;
2015-05-19 03:57:13 +00:00
const ScenePrivateData * const priv = ScenePriv ( pScene ) ;
// steps that are not idempotent, i.e. we might need to run them again, usually to get back to the
// original state before the step was applied first. When checking which steps we don't need
// to run, those are excluded.
const unsigned int nonIdempotentSteps = aiProcess_FlipWindingOrder | aiProcess_FlipUVs | aiProcess_MakeLeftHanded ;
// Erase all pp steps that were already applied to this scene
const unsigned int pp = ( exp . mEnforcePP | pPreprocessing ) & ~ ( priv & & ! priv - > mIsCopy
? ( priv - > mPPStepsApplied & ~ nonIdempotentSteps )
: 0u ) ;
2017-02-04 17:32:04 +00:00
// If no extra post-processing was specified, and we obtained this scene from an
2015-05-19 03:57:13 +00:00
// Assimp importer, apply the reverse steps automatically.
// TODO: either drop this, or document it. Otherwise it is just a bad surprise.
//if (!pPreprocessing && priv) {
// pp |= (nonIdempotentSteps & priv->mPPStepsApplied);
//}
2017-02-04 17:32:04 +00:00
// If the input scene is not in verbose format, but there is at least post-processing step that relies on it,
2015-05-19 03:57:13 +00:00
// we need to run the MakeVerboseFormat step first.
bool must_join_again = false ;
if ( ! is_verbose_format ) {
bool verbosify = false ;
for ( unsigned int a = 0 ; a < pimpl - > mPostProcessingSteps . size ( ) ; a + + ) {
BaseProcess * const p = pimpl - > mPostProcessingSteps [ a ] ;
if ( p - > IsActive ( pp ) & & p - > RequireVerboseFormat ( ) ) {
verbosify = true ;
break ;
}
}
if ( verbosify | | ( exp . mEnforcePP & aiProcess_JoinIdenticalVertices ) ) {
2018-04-20 14:23:24 +00:00
ASSIMP_LOG_DEBUG ( " export: Scene data not in verbose format, applying MakeVerboseFormat step first " ) ;
2015-05-19 03:57:13 +00:00
MakeVerboseFormatProcess proc ;
proc . Execute ( scenecopy . get ( ) ) ;
if ( ! ( exp . mEnforcePP & aiProcess_JoinIdenticalVertices ) ) {
must_join_again = true ;
}
}
}
2018-11-12 21:26:10 +00:00
pimpl - > mProgressHandler - > UpdateFileWrite ( 2 , 4 ) ;
2015-05-19 03:57:13 +00:00
if ( pp ) {
// the three 'conversion' steps need to be executed first because all other steps rely on the standard data layout
{
FlipWindingOrderProcess step ;
if ( step . IsActive ( pp ) ) {
step . Execute ( scenecopy . get ( ) ) ;
}
}
{
FlipUVsProcess step ;
if ( step . IsActive ( pp ) ) {
step . Execute ( scenecopy . get ( ) ) ;
}
}
{
MakeLeftHandedProcess step ;
if ( step . IsActive ( pp ) ) {
step . Execute ( scenecopy . get ( ) ) ;
}
}
2018-05-01 11:28:53 +00:00
bool exportPointCloud ( false ) ;
if ( nullptr ! = pProperties ) {
exportPointCloud = pProperties - > GetPropertyBool ( AI_CONFIG_EXPORT_POINT_CLOUDS ) ;
}
2015-05-19 03:57:13 +00:00
// dispatch other processes
for ( unsigned int a = 0 ; a < pimpl - > mPostProcessingSteps . size ( ) ; a + + ) {
BaseProcess * const p = pimpl - > mPostProcessingSteps [ a ] ;
if ( p - > IsActive ( pp )
& & ! dynamic_cast < FlipUVsProcess * > ( p )
& & ! dynamic_cast < FlipWindingOrderProcess * > ( p )
& & ! dynamic_cast < MakeLeftHandedProcess * > ( p ) ) {
2018-05-01 11:28:53 +00:00
if ( dynamic_cast < PretransformVertices * > ( p ) & & exportPointCloud ) {
continue ;
}
2015-05-19 03:57:13 +00:00
p - > Execute ( scenecopy . get ( ) ) ;
}
}
ScenePrivateData * const privOut = ScenePriv ( scenecopy . get ( ) ) ;
2018-11-12 21:26:10 +00:00
ai_assert ( nullptr ! = privOut ) ;
2015-05-19 03:57:13 +00:00
privOut - > mPPStepsApplied | = pp ;
}
2018-11-12 21:26:10 +00:00
pimpl - > mProgressHandler - > UpdateFileWrite ( 3 , 4 ) ;
2015-05-19 03:57:13 +00:00
if ( must_join_again ) {
JoinVerticesProcess proc ;
proc . Execute ( scenecopy . get ( ) ) ;
}
2020-06-23 19:05:42 +00:00
ExportProperties emptyProperties ; // Never pass nullptr ExportProperties so Exporters don't have to worry.
2019-08-13 01:10:43 +00:00
ExportProperties * pProp = pProperties ? ( ExportProperties * ) pProperties : & emptyProperties ;
2019-12-01 21:46:48 +00:00
pProp - > SetPropertyBool ( " bJoinIdenticalVertices " , pp & aiProcess_JoinIdenticalVertices ) ;
2019-08-13 01:10:43 +00:00
exp . mExportFunction ( pPath , pimpl - > mIOSystem . get ( ) , scenecopy . get ( ) , pProp ) ;
2018-11-12 21:26:10 +00:00
pimpl - > mProgressHandler - > UpdateFileWrite ( 4 , 4 ) ;
2017-02-04 17:32:04 +00:00
} catch ( DeadlyExportError & err ) {
2015-05-19 03:57:13 +00:00
pimpl - > mError = err . what ( ) ;
return AI_FAILURE ;
}
return AI_SUCCESS ;
}
}
pimpl - > mError = std : : string ( " Found no exporter to handle this file format: " ) + pFormatId ;
ASSIMP_END_EXCEPTION_REGION ( aiReturn ) ;
2017-12-14 15:11:12 +00:00
2015-05-19 03:57:13 +00:00
return AI_FAILURE ;
2015-05-19 03:48:29 +00:00
}
// ------------------------------------------------------------------------------------------------
2017-02-04 17:32:04 +00:00
const char * Exporter : : GetErrorString ( ) const {
2019-11-10 08:47:50 +00:00
ai_assert ( nullptr ! = pimpl ) ;
2015-05-19 03:57:13 +00:00
return pimpl - > mError . c_str ( ) ;
2015-05-19 03:48:29 +00:00
}
// ------------------------------------------------------------------------------------------------
2017-02-04 17:32:04 +00:00
void Exporter : : FreeBlob ( ) {
2019-11-10 08:47:50 +00:00
ai_assert ( nullptr ! = pimpl ) ;
2015-05-19 03:57:13 +00:00
delete pimpl - > blob ;
2018-11-12 21:26:10 +00:00
pimpl - > blob = nullptr ;
2015-05-19 03:48:29 +00:00
2015-05-19 03:57:13 +00:00
pimpl - > mError = " " ;
2015-05-19 03:48:29 +00:00
}
// ------------------------------------------------------------------------------------------------
2017-02-04 17:32:04 +00:00
const aiExportDataBlob * Exporter : : GetBlob ( ) const {
2019-11-10 08:47:50 +00:00
ai_assert ( nullptr ! = pimpl ) ;
return pimpl - > blob ;
2015-05-19 03:48:29 +00:00
}
// ------------------------------------------------------------------------------------------------
2017-02-04 17:32:04 +00:00
const aiExportDataBlob * Exporter : : GetOrphanedBlob ( ) const {
2019-11-10 08:47:50 +00:00
ai_assert ( nullptr ! = pimpl ) ;
const aiExportDataBlob * tmp = pimpl - > blob ;
2018-11-12 21:26:10 +00:00
pimpl - > blob = nullptr ;
2015-05-19 03:57:13 +00:00
return tmp ;
2015-05-19 03:48:29 +00:00
}
// ------------------------------------------------------------------------------------------------
2017-02-04 17:32:04 +00:00
size_t Exporter : : GetExportFormatCount ( ) const {
2019-11-10 08:47:50 +00:00
ai_assert ( nullptr ! = pimpl ) ;
2015-05-19 03:57:13 +00:00
return pimpl - > mExporters . size ( ) ;
2015-05-19 03:48:29 +00:00
}
// ------------------------------------------------------------------------------------------------
2017-02-04 17:32:04 +00:00
const aiExportFormatDesc * Exporter : : GetExportFormatDescription ( size_t index ) const {
2019-11-10 08:47:50 +00:00
ai_assert ( nullptr ! = pimpl ) ;
if ( index > = GetExportFormatCount ( ) ) {
2018-05-01 13:06:56 +00:00
return nullptr ;
2015-05-19 03:57:13 +00:00
}
2015-05-19 03:52:10 +00:00
2015-05-19 03:57:13 +00:00
// Return from static storage if the requested index is built-in.
2019-11-10 08:47:50 +00:00
if ( index < pimpl - > mExporters . size ( ) ) {
return & pimpl - > mExporters [ index ] . mDescription ;
2015-05-19 03:57:13 +00:00
}
2015-05-19 03:48:29 +00:00
2017-02-04 17:32:04 +00:00
return & pimpl - > mExporters [ index ] . mDescription ;
2015-05-19 03:48:29 +00:00
}
// ------------------------------------------------------------------------------------------------
2017-02-04 17:32:04 +00:00
aiReturn Exporter : : RegisterExporter ( const ExportFormatEntry & desc ) {
2019-11-10 08:47:50 +00:00
ai_assert ( nullptr ! = pimpl ) ;
for ( const ExportFormatEntry & e : pimpl - > mExporters ) {
2015-05-19 03:57:13 +00:00
if ( ! strcmp ( e . mDescription . id , desc . mDescription . id ) ) {
return aiReturn_FAILURE ;
}
}
2015-05-19 03:48:29 +00:00
2015-05-19 03:57:13 +00:00
pimpl - > mExporters . push_back ( desc ) ;
return aiReturn_SUCCESS ;
2015-05-19 03:48:29 +00:00
}
// ------------------------------------------------------------------------------------------------
2017-02-04 17:32:04 +00:00
void Exporter : : UnregisterExporter ( const char * id ) {
2019-11-10 08:47:50 +00:00
ai_assert ( nullptr ! = pimpl ) ;
for ( std : : vector < ExportFormatEntry > : : iterator it = pimpl - > mExporters . begin ( ) ;
2018-05-01 11:28:53 +00:00
it ! = pimpl - > mExporters . end ( ) ; + + it ) {
2015-05-19 03:57:13 +00:00
if ( ! strcmp ( ( * it ) . mDescription . id , id ) ) {
pimpl - > mExporters . erase ( it ) ;
break ;
}
}
2015-05-19 03:48:29 +00:00
}
2017-02-04 17:32:04 +00:00
// ------------------------------------------------------------------------------------------------
2022-08-25 16:20:13 +00:00
ExportProperties : : ExportProperties ( ) = default ;
2015-05-19 03:48:29 +00:00
2017-02-04 17:32:04 +00:00
// ------------------------------------------------------------------------------------------------
2022-08-25 16:20:13 +00:00
ExportProperties : : ExportProperties ( const ExportProperties & other ) = default ;
2015-05-19 03:48:29 +00:00
2020-06-10 20:23:29 +00:00
bool ExportProperties : : SetPropertyCallback ( const char * szName , const std : : function < void * ( void * ) > & f ) {
2020-06-09 18:20:48 +00:00
return SetGenericProperty < std : : function < void * ( void * ) > > ( mCallbackProperties , szName , f ) ;
}
2020-06-12 00:37:06 +00:00
2020-06-09 18:20:48 +00:00
std : : function < void * ( void * ) > ExportProperties : : GetPropertyCallback ( const char * szName ) const {
2022-11-08 16:03:55 +00:00
return GetGenericProperty < std : : function < void * ( void * ) > > ( mCallbackProperties , szName , nullptr ) ;
2020-06-09 18:20:48 +00:00
}
2020-06-12 00:37:06 +00:00
2020-06-09 18:20:48 +00:00
bool ExportProperties : : HasPropertyCallback ( const char * szName ) const {
return HasGenericProperty < std : : function < void * ( void * ) > > ( mCallbackProperties , szName ) ;
}
2015-05-19 03:48:29 +00:00
// ------------------------------------------------------------------------------------------------
// Set a configuration property
2017-02-04 17:32:04 +00:00
bool ExportProperties : : SetPropertyInteger ( const char * szName , int iValue ) {
2015-05-19 03:57:13 +00:00
return SetGenericProperty < int > ( mIntProperties , szName , iValue ) ;
2015-05-19 03:48:29 +00:00
}
// ------------------------------------------------------------------------------------------------
// Set a configuration property
2017-02-04 17:32:04 +00:00
bool ExportProperties : : SetPropertyFloat ( const char * szName , ai_real iValue ) {
2016-07-15 03:20:16 +00:00
return SetGenericProperty < ai_real > ( mFloatProperties , szName , iValue ) ;
2015-05-19 03:48:29 +00:00
}
// ------------------------------------------------------------------------------------------------
// Set a configuration property
2018-05-01 13:06:56 +00:00
bool ExportProperties : : SetPropertyString ( const char * szName , const std : : string & value ) {
2015-05-19 03:57:13 +00:00
return SetGenericProperty < std : : string > ( mStringProperties , szName , value ) ;
2015-05-19 03:48:29 +00:00
}
// ------------------------------------------------------------------------------------------------
// Set a configuration property
2018-11-12 21:26:10 +00:00
bool ExportProperties : : SetPropertyMatrix ( const char * szName , const aiMatrix4x4 & value ) {
2015-05-19 03:57:13 +00:00
return SetGenericProperty < aiMatrix4x4 > ( mMatrixProperties , szName , value ) ;
2015-05-19 03:48:29 +00:00
}
// ------------------------------------------------------------------------------------------------
// Get a configuration property
2018-11-12 21:26:10 +00:00
int ExportProperties : : GetPropertyInteger ( const char * szName , int iErrorReturn /*= 0xffffffff*/ ) const {
2015-05-19 03:57:13 +00:00
return GetGenericProperty < int > ( mIntProperties , szName , iErrorReturn ) ;
2015-05-19 03:48:29 +00:00
}
// ------------------------------------------------------------------------------------------------
// Get a configuration property
2018-11-12 21:26:10 +00:00
ai_real ExportProperties : : GetPropertyFloat ( const char * szName , ai_real iErrorReturn /*= 10e10*/ ) const {
2016-07-15 03:20:16 +00:00
return GetGenericProperty < ai_real > ( mFloatProperties , szName , iErrorReturn ) ;
2015-05-19 03:48:29 +00:00
}
// ------------------------------------------------------------------------------------------------
// Get a configuration property
2018-11-12 21:26:10 +00:00
const std : : string ExportProperties : : GetPropertyString ( const char * szName ,
const std : : string & iErrorReturn /*= ""*/ ) const {
2015-05-19 03:57:13 +00:00
return GetGenericProperty < std : : string > ( mStringProperties , szName , iErrorReturn ) ;
2015-05-19 03:48:29 +00:00
}
// ------------------------------------------------------------------------------------------------
// Has a configuration property
2018-11-12 21:26:10 +00:00
const aiMatrix4x4 ExportProperties : : GetPropertyMatrix ( const char * szName ,
const aiMatrix4x4 & iErrorReturn /*= aiMatrix4x4()*/ ) const {
2015-05-19 03:57:13 +00:00
return GetGenericProperty < aiMatrix4x4 > ( mMatrixProperties , szName , iErrorReturn ) ;
2015-05-19 03:48:29 +00:00
}
// ------------------------------------------------------------------------------------------------
// Has a configuration property
2018-11-12 21:26:10 +00:00
bool ExportProperties : : HasPropertyInteger ( const char * szName ) const {
2015-05-19 03:57:13 +00:00
return HasGenericProperty < int > ( mIntProperties , szName ) ;
2015-05-19 03:48:29 +00:00
}
// ------------------------------------------------------------------------------------------------
// Has a configuration property
2018-11-12 21:26:10 +00:00
bool ExportProperties : : HasPropertyBool ( const char * szName ) const {
2015-05-19 03:57:13 +00:00
return HasGenericProperty < int > ( mIntProperties , szName ) ;
2016-11-24 12:26:18 +00:00
}
2015-05-19 03:48:29 +00:00
// ------------------------------------------------------------------------------------------------
// Has a configuration property
2018-11-12 21:26:10 +00:00
bool ExportProperties : : HasPropertyFloat ( const char * szName ) const {
2016-07-15 03:20:16 +00:00
return HasGenericProperty < ai_real > ( mFloatProperties , szName ) ;
2016-11-24 12:26:18 +00:00
}
2015-05-19 03:48:29 +00:00
// ------------------------------------------------------------------------------------------------
// Has a configuration property
2018-11-12 21:26:10 +00:00
bool ExportProperties : : HasPropertyString ( const char * szName ) const {
2015-05-19 03:57:13 +00:00
return HasGenericProperty < std : : string > ( mStringProperties , szName ) ;
2016-11-24 12:26:18 +00:00
}
2015-05-19 03:48:29 +00:00
// ------------------------------------------------------------------------------------------------
// Has a configuration property
2018-11-12 21:26:10 +00:00
bool ExportProperties : : HasPropertyMatrix ( const char * szName ) const {
2015-05-19 03:57:13 +00:00
return HasGenericProperty < aiMatrix4x4 > ( mMatrixProperties , szName ) ;
2016-11-24 12:26:18 +00:00
}
2015-05-19 03:48:29 +00:00
# endif // !ASSIMP_BUILD_NO_EXPORT