2019-02-08 22:25:43 +00:00
/*
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Open Asset Import Library ( assimp )
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2024-12-09 20:22:47 +00:00
Copyright ( c ) 2006 - 2024 , assimp team
2019-02-08 22:25:43 +00:00
All rights reserved .
Redistribution and use of this software in source and binary forms ,
with or without modification , are permitted provided that the following
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 .
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
" AS IS " AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT
LIMITED TO , THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT , INDIRECT , INCIDENTAL ,
SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT NOT
LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE ,
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
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
2019-03-05 20:39:38 +00:00
# include <assimp/BlobIOSystem.h>
2019-02-08 22:25:43 +00:00
# include <assimp/SceneCombiner.h>
2019-03-05 20:39:38 +00:00
# include <assimp/DefaultIOSystem.h>
# include <assimp/Exporter.hpp>
# include <assimp/mesh.h>
# include <assimp/postprocess.h>
# include <assimp/scene.h>
# include <assimp/Exceptional.h>
2019-11-10 14:40:50 +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"
2019-02-08 22:25:43 +00:00
2019-03-05 20:39:38 +00:00
# include <memory>
2019-02-08 22:25:43 +00:00
namespace Assimp {
2022-04-26 16:56:24 +00:00
# ifdef _MSC_VER
# pragma warning( disable : 4800 )
# endif // _MSC_VER
2019-02-08 22:25:43 +00:00
// PostStepRegistry.cpp
void GetPostProcessingStepInstanceList ( std : : vector < BaseProcess * > & out ) ;
// ------------------------------------------------------------------------------------------------
2022-04-26 16:56:24 +00:00
// Exporter worker function prototypes. Do not use const, because some exporter need to convert
// the scene temporary
# ifndef ASSIMP_BUILD_NO_COLLADA_EXPORTER
2019-02-08 22:25:43 +00:00
void ExportSceneCollada ( const char * , IOSystem * , const aiScene * , const ExportProperties * ) ;
2022-04-26 16:56:24 +00:00
# endif
# ifndef ASSIMP_BUILD_NO_X_EXPORTER
2019-02-08 22:25:43 +00:00
void ExportSceneXFile ( const char * , IOSystem * , const aiScene * , const ExportProperties * ) ;
2022-04-26 16:56:24 +00:00
# endif
# ifndef ASSIMP_BUILD_NO_STEP_EXPORTER
2019-02-08 22:25:43 +00:00
void ExportSceneStep ( const char * , IOSystem * , const aiScene * , const ExportProperties * ) ;
2022-04-26 16:56:24 +00:00
# endif
# ifndef ASSIMP_BUILD_NO_OBJ_EXPORTER
2019-02-08 22:25:43 +00:00
void ExportSceneObj ( const char * , IOSystem * , const aiScene * , const ExportProperties * ) ;
void ExportSceneObjNoMtl ( const char * , IOSystem * , const aiScene * , const ExportProperties * ) ;
2022-04-26 16:56:24 +00:00
# endif
# ifndef ASSIMP_BUILD_NO_STL_EXPORTER
2019-02-08 22:25:43 +00:00
void ExportSceneSTL ( const char * , IOSystem * , const aiScene * , const ExportProperties * ) ;
void ExportSceneSTLBinary ( const char * , IOSystem * , const aiScene * , const ExportProperties * ) ;
2022-04-26 16:56:24 +00:00
# endif
# ifndef ASSIMP_BUILD_NO_PLY_EXPORTER
2019-02-08 22:25:43 +00:00
void ExportScenePly ( const char * , IOSystem * , const aiScene * , const ExportProperties * ) ;
void ExportScenePlyBinary ( const char * , IOSystem * , const aiScene * , const ExportProperties * ) ;
2022-04-26 16:56:24 +00:00
# endif
# ifndef ASSIMP_BUILD_NO_3DS_EXPORTER
2019-02-08 22:25:43 +00:00
void ExportScene3DS ( const char * , IOSystem * , const aiScene * , const ExportProperties * ) ;
2022-04-26 16:56:24 +00:00
# endif
# ifndef ASSIMP_BUILD_NO_GLTF_EXPORTER
2019-02-08 22:25:43 +00:00
void ExportSceneGLTF ( const char * , IOSystem * , const aiScene * , const ExportProperties * ) ;
void ExportSceneGLB ( const char * , IOSystem * , const aiScene * , const ExportProperties * ) ;
void ExportSceneGLTF2 ( const char * , IOSystem * , const aiScene * , const ExportProperties * ) ;
2019-03-05 20:39:38 +00:00
void ExportSceneGLB2 ( const char * , IOSystem * , const aiScene * , const ExportProperties * ) ;
2022-04-26 16:56:24 +00:00
# endif
# ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER
2019-02-08 22:25:43 +00:00
void ExportSceneAssbin ( const char * , IOSystem * , const aiScene * , const ExportProperties * ) ;
2022-04-26 16:56:24 +00:00
# endif
# ifndef ASSIMP_BUILD_NO_ASSXML_EXPORTER
2019-02-08 22:25:43 +00:00
void ExportSceneAssxml ( const char * , IOSystem * , const aiScene * , const ExportProperties * ) ;
2022-04-26 16:56:24 +00:00
# endif
# ifndef ASSIMP_BUILD_NO_X3D_EXPORTER
2019-02-08 22:25:43 +00:00
void ExportSceneX3D ( const char * , IOSystem * , const aiScene * , const ExportProperties * ) ;
2022-04-26 16:56:24 +00:00
# endif
# ifndef ASSIMP_BUILD_NO_FBX_EXPORTER
2019-03-05 20:39:38 +00:00
void ExportSceneFBX ( const char * , IOSystem * , const aiScene * , const ExportProperties * ) ;
void ExportSceneFBXA ( const char * , IOSystem * , const aiScene * , const ExportProperties * ) ;
2022-04-26 16:56:24 +00:00
# endif
# ifndef ASSIMP_BUILD_NO_3MF_EXPORTER
2019-02-08 22:25:43 +00:00
void ExportScene3MF ( const char * , IOSystem * , const aiScene * , const ExportProperties * ) ;
2022-04-26 16:56:24 +00:00
# endif
# ifndef ASSIMP_BUILD_NO_M3D_EXPORTER
void ExportSceneM3D ( const char * , IOSystem * , const aiScene * , const ExportProperties * ) ;
void ExportSceneM3DA ( const char * , IOSystem * , const aiScene * , const ExportProperties * ) ;
# endif
# ifndef ASSIMP_BUILD_NO_ASSJSON_EXPORTER
2019-11-10 14:40:50 +00:00
void ExportAssimp2Json ( const char * , IOSystem * , const aiScene * , const Assimp : : ExportProperties * ) ;
2022-04-26 16:56:24 +00:00
# endif
# ifndef ASSIMP_BUILD_NO_PBRT_EXPORTER
void ExportScenePbrt ( const char * , IOSystem * , const aiScene * , const ExportProperties * ) ;
# endif
static void setupExporterArray ( std : : vector < Exporter : : ExportFormatEntry > & exporters ) {
( void ) exporters ;
2019-02-08 22:25:43 +00:00
# ifndef ASSIMP_BUILD_NO_COLLADA_EXPORTER
2022-10-02 18:02:49 +00:00
exporters . emplace_back ( " collada " , " COLLADA - Digital Asset Exchange Schema " , " dae " , & ExportSceneCollada ) ;
2019-02-08 22:25:43 +00:00
# endif
# ifndef ASSIMP_BUILD_NO_X_EXPORTER
2022-10-02 18:02:49 +00:00
exporters . emplace_back ( " x " , " X Files " , " x " , & ExportSceneXFile ,
aiProcess_MakeLeftHanded | aiProcess_FlipWindingOrder | aiProcess_FlipUVs ) ;
2019-02-08 22:25:43 +00:00
# endif
# ifndef ASSIMP_BUILD_NO_STEP_EXPORTER
2022-10-02 18:02:49 +00:00
exporters . emplace_back ( " stp " , " Step Files " , " stp " , & ExportSceneStep , 0 ) ;
2019-02-08 22:25:43 +00:00
# endif
# ifndef ASSIMP_BUILD_NO_OBJ_EXPORTER
2022-10-02 18:02: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 */ ) ;
2019-02-08 22:25:43 +00:00
# endif
# ifndef ASSIMP_BUILD_NO_STL_EXPORTER
2022-10-02 18:02: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 ) ;
2019-02-08 22:25:43 +00:00
# endif
# ifndef ASSIMP_BUILD_NO_PLY_EXPORTER
2022-10-02 18:02: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 ) ;
2019-02-08 22:25:43 +00:00
# endif
# ifndef ASSIMP_BUILD_NO_3DS_EXPORTER
2022-10-02 18:02:49 +00:00
exporters . emplace_back ( " 3ds " , " Autodesk 3DS (legacy) " , " 3ds " , & ExportScene3DS ,
aiProcess_Triangulate | aiProcess_SortByPType | aiProcess_JoinIdenticalVertices ) ;
2019-02-08 22:25:43 +00:00
# endif
2022-04-26 16:56:24 +00:00
# if !defined(ASSIMP_BUILD_NO_GLTF_EXPORTER) && !defined(ASSIMP_BUILD_NO_GLTF2_EXPORTER)
2022-10-02 18:02: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 ) ;
2022-04-26 16:56:24 +00:00
# endif
# if !defined(ASSIMP_BUILD_NO_GLTF_EXPORTER) && !defined(ASSIMP_BUILD_NO_GLTF1_EXPORTER)
2022-10-02 18:02: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 ) ;
2019-02-08 22:25:43 +00:00
# endif
# ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER
2022-10-02 18:02:49 +00:00
exporters . emplace_back ( " assbin " , " Assimp Binary File " , " assbin " , & ExportSceneAssbin , 0 ) ;
2019-02-08 22:25:43 +00:00
# endif
# ifndef ASSIMP_BUILD_NO_ASSXML_EXPORTER
2022-10-02 18:02:49 +00:00
exporters . emplace_back ( " assxml " , " Assimp XML Document " , " assxml " , & ExportSceneAssxml , 0 ) ;
2019-02-08 22:25:43 +00:00
# endif
# ifndef ASSIMP_BUILD_NO_X3D_EXPORTER
2022-10-02 18:02:49 +00:00
exporters . emplace_back ( " x3d " , " Extensible 3D " , " x3d " , & ExportSceneX3D , 0 ) ;
2019-02-08 22:25:43 +00:00
# endif
2019-03-05 20:39:38 +00:00
# ifndef ASSIMP_BUILD_NO_FBX_EXPORTER
2022-10-02 18:02:49 +00:00
exporters . emplace_back ( " fbx " , " Autodesk FBX (binary) " , " fbx " , & ExportSceneFBX , 0 ) ;
exporters . emplace_back ( " fbxa " , " Autodesk FBX (ascii) " , " fbx " , & ExportSceneFBXA , 0 ) ;
2019-02-08 22:25:43 +00:00
# endif
2022-04-26 16:56:24 +00:00
# ifndef ASSIMP_BUILD_NO_M3D_EXPORTER
exporters . push_back ( Exporter : : ExportFormatEntry ( " m3d " , " Model 3D (binary) " , " m3d " , & ExportSceneM3D , 0 ) ) ;
exporters . push_back ( Exporter : : ExportFormatEntry ( " m3da " , " Model 3D (ascii) " , " a3d " , & ExportSceneM3DA , 0 ) ) ;
2019-11-10 14:40:50 +00:00
# endif
2019-02-08 22:25:43 +00:00
2022-04-26 16:56:24 +00:00
# ifndef ASSIMP_BUILD_NO_3MF_EXPORTER
2022-10-02 18:02:49 +00:00
exporters . emplace_back ( " 3mf " , " The 3MF-File-Format " , " 3mf " , & ExportScene3MF , 0 ) ;
2019-11-10 14:40:50 +00:00
# endif
2021-10-22 01:14:55 +00:00
2022-04-26 16:56:24 +00:00
# ifndef ASSIMP_BUILD_NO_PBRT_EXPORTER
2024-12-09 20:22:47 +00:00
exporters . emplace_back ( " pbrt " , " pbrt-v4 scene description file " , " pbrt " , & ExportScenePbrt , aiProcess_ConvertToLeftHanded | aiProcess_Triangulate | aiProcess_SortByPType ) ;
2022-04-26 16:56:24 +00:00
# endif
2021-10-22 01:14:55 +00:00
2022-04-26 16:56:24 +00:00
# ifndef ASSIMP_BUILD_NO_ASSJSON_EXPORTER
2022-10-02 18:02:49 +00:00
exporters . emplace_back ( " assjson " , " Assimp JSON Document " , " json " , & ExportAssimp2Json , 0 ) ;
2022-04-26 16:56:24 +00:00
# endif
}
2019-02-08 22:25:43 +00:00
class ExporterPimpl {
public :
ExporterPimpl ( )
2019-03-05 20:39:38 +00:00
: blob ( )
, mIOSystem ( new Assimp : : DefaultIOSystem ( ) )
, mIsDefaultIOHandler ( true )
, mProgressHandler ( nullptr )
, mIsDefaultProgressHandler ( true )
, mPostProcessingSteps ( )
, mError ( )
, mExporters ( ) {
2019-02-08 22:25:43 +00:00
GetPostProcessingStepInstanceList ( mPostProcessingSteps ) ;
// grab all built-in exporters
2022-04-26 16:56:24 +00:00
setupExporterArray ( mExporters ) ;
2019-02-08 22:25:43 +00:00
}
2019-03-05 20:39:38 +00:00
~ ExporterPimpl ( ) {
2019-02-08 22:25:43 +00:00
delete blob ;
// Delete all post-processing plug-ins
for ( unsigned int a = 0 ; a < mPostProcessingSteps . size ( ) ; a + + ) {
delete mPostProcessingSteps [ a ] ;
}
2019-03-05 20:39:38 +00:00
delete mProgressHandler ;
2019-02-08 22:25:43 +00:00
}
public :
aiExportDataBlob * blob ;
std : : shared_ptr < Assimp : : IOSystem > mIOSystem ;
bool mIsDefaultIOHandler ;
2019-03-05 20:39:38 +00:00
/** The progress handler */
ProgressHandler * mProgressHandler ;
bool mIsDefaultProgressHandler ;
2019-02-08 22:25:43 +00:00
/** Post processing steps we can apply at the imported data. */
std : : vector < BaseProcess * > mPostProcessingSteps ;
/** Last fatal export error */
std : : string mError ;
/** Exporters, this includes those registered using #Assimp::Exporter::RegisterExporter */
std : : vector < Exporter : : ExportFormatEntry > mExporters ;
} ;
} // end of namespace Assimp
using namespace Assimp ;
// ------------------------------------------------------------------------------------------------
Exporter : : Exporter ( )
: pimpl ( new ExporterPimpl ( ) ) {
2019-03-05 20:39:38 +00:00
pimpl - > mProgressHandler = new DefaultProgressHandler ( ) ;
2019-02-08 22:25:43 +00:00
}
// ------------------------------------------------------------------------------------------------
Exporter : : ~ Exporter ( ) {
2022-04-26 16:56:24 +00:00
ai_assert ( nullptr ! = pimpl ) ;
FreeBlob ( ) ;
2019-02-08 22:25:43 +00:00
delete pimpl ;
}
// ------------------------------------------------------------------------------------------------
void Exporter : : SetIOHandler ( IOSystem * pIOHandler ) {
2022-04-26 16:56:24 +00:00
ai_assert ( nullptr ! = pimpl ) ;
pimpl - > mIsDefaultIOHandler = ! pIOHandler ;
2019-02-08 22:25:43 +00:00
pimpl - > mIOSystem . reset ( pIOHandler ) ;
}
// ------------------------------------------------------------------------------------------------
IOSystem * Exporter : : GetIOHandler ( ) const {
2022-04-26 16:56:24 +00:00
ai_assert ( nullptr ! = pimpl ) ;
return pimpl - > mIOSystem . get ( ) ;
2019-02-08 22:25:43 +00:00
}
// ------------------------------------------------------------------------------------------------
bool Exporter : : IsDefaultIOHandler ( ) const {
2022-04-26 16:56:24 +00:00
ai_assert ( nullptr ! = pimpl ) ;
return pimpl - > mIsDefaultIOHandler ;
2019-02-08 22:25:43 +00:00
}
2019-03-05 20:39:38 +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 ;
}
2019-02-08 22:25:43 +00:00
// ------------------------------------------------------------------------------------------------
const aiExportDataBlob * Exporter : : ExportToBlob ( const aiScene * pScene , const char * pFormatId ,
2019-11-10 14:40:50 +00:00
unsigned int pPreprocessing , const ExportProperties * pProperties ) {
2022-04-26 16:56:24 +00:00
ai_assert ( nullptr ! = pimpl ) ;
2019-02-08 22:25:43 +00:00
if ( pimpl - > blob ) {
delete pimpl - > blob ;
2019-03-05 20:39:38 +00:00
pimpl - > blob = nullptr ;
2019-02-08 22:25:43 +00:00
}
2022-04-26 16:56:24 +00:00
auto baseName = pProperties ? pProperties - > GetPropertyString ( AI_CONFIG_EXPORT_BLOB_NAME , AI_BLOBIO_MAGIC ) : AI_BLOBIO_MAGIC ;
2019-02-08 22:25:43 +00:00
std : : shared_ptr < IOSystem > old = pimpl - > mIOSystem ;
2022-04-26 16:56:24 +00:00
BlobIOSystem * blobio = new BlobIOSystem ( baseName ) ;
2019-02-08 22:25:43 +00:00
pimpl - > mIOSystem = std : : shared_ptr < IOSystem > ( blobio ) ;
2019-11-10 14:40:50 +00:00
if ( AI_SUCCESS ! = Export ( pScene , pFormatId , blobio - > GetMagicFileName ( ) , pPreprocessing , pProperties ) ) {
2019-02-08 22:25:43 +00:00
pimpl - > mIOSystem = old ;
2019-03-05 20:39:38 +00:00
return nullptr ;
2019-02-08 22:25:43 +00:00
}
pimpl - > blob = blobio - > GetBlobChain ( ) ;
pimpl - > mIOSystem = old ;
return pimpl - > blob ;
}
// ------------------------------------------------------------------------------------------------
2019-03-05 20:39:38 +00:00
aiReturn Exporter : : Export ( const aiScene * pScene , const char * pFormatId , const char * pPath ,
unsigned int pPreprocessing , const ExportProperties * pProperties ) {
2019-02-08 22:25:43 +00:00
ASSIMP_BEGIN_EXCEPTION_REGION ( ) ;
2022-04-26 16:56:24 +00:00
ai_assert ( nullptr ! = pimpl ) ;
2019-02-08 22:25:43 +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-11-10 14:40:50 +00:00
const bool is_verbose_format = ! ( pScene - > mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT ) | | MakeVerboseFormatProcess : : IsVerboseFormat ( pScene ) ;
2019-02-08 22:25:43 +00:00
2019-03-05 20:39:38 +00:00
pimpl - > mProgressHandler - > UpdateFileWrite ( 0 , 4 ) ;
2019-02-08 22:25:43 +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.
2019-03-05 20:39:38 +00:00
aiScene * scenecopy_tmp = nullptr ;
2019-02-08 22:25:43 +00:00
SceneCombiner : : CopyScene ( & scenecopy_tmp , pScene ) ;
2019-03-05 20:39:38 +00:00
pimpl - > mProgressHandler - > UpdateFileWrite ( 1 , 4 ) ;
2019-02-08 22:25:43 +00:00
std : : unique_ptr < aiScene > scenecopy ( scenecopy_tmp ) ;
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 ) ;
// If no extra post-processing was specified, and we obtained this scene from an
// 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);
//}
// If the input scene is not in verbose format, but there is at least post-processing step that relies on it,
// 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 ) ) {
2019-03-05 20:39:38 +00:00
ASSIMP_LOG_DEBUG ( " export: Scene data not in verbose format, applying MakeVerboseFormat step first " ) ;
2019-02-08 22:25:43 +00:00
MakeVerboseFormatProcess proc ;
proc . Execute ( scenecopy . get ( ) ) ;
if ( ! ( exp . mEnforcePP & aiProcess_JoinIdenticalVertices ) ) {
must_join_again = true ;
}
}
}
2019-03-05 20:39:38 +00:00
pimpl - > mProgressHandler - > UpdateFileWrite ( 2 , 4 ) ;
2019-02-08 22:25:43 +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 ( ) ) ;
}
}
2019-03-05 20:39:38 +00:00
bool exportPointCloud ( false ) ;
if ( nullptr ! = pProperties ) {
exportPointCloud = pProperties - > GetPropertyBool ( AI_CONFIG_EXPORT_POINT_CLOUDS ) ;
}
2019-02-08 22:25:43 +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 ) ) {
2019-03-05 20:39:38 +00:00
if ( dynamic_cast < PretransformVertices * > ( p ) & & exportPointCloud ) {
continue ;
}
2019-02-08 22:25:43 +00:00
p - > Execute ( scenecopy . get ( ) ) ;
}
}
ScenePrivateData * const privOut = ScenePriv ( scenecopy . get ( ) ) ;
2019-03-05 20:39:38 +00:00
ai_assert ( nullptr ! = privOut ) ;
2019-02-08 22:25:43 +00:00
privOut - > mPPStepsApplied | = pp ;
}
2019-03-05 20:39:38 +00:00
pimpl - > mProgressHandler - > UpdateFileWrite ( 3 , 4 ) ;
2019-02-08 22:25:43 +00:00
if ( must_join_again ) {
JoinVerticesProcess proc ;
proc . Execute ( scenecopy . get ( ) ) ;
}
2022-04-26 16:56:24 +00:00
ExportProperties emptyProperties ; // Never pass nullptr ExportProperties so Exporters don't have to worry.
2019-11-10 14:40:50 +00:00
ExportProperties * pProp = pProperties ? ( ExportProperties * ) pProperties : & emptyProperties ;
2022-04-26 16:56:24 +00:00
pProp - > SetPropertyBool ( " bJoinIdenticalVertices " , pp & aiProcess_JoinIdenticalVertices ) ;
2019-11-10 14:40:50 +00:00
exp . mExportFunction ( pPath , pimpl - > mIOSystem . get ( ) , scenecopy . get ( ) , pProp ) ;
2019-03-05 20:39:38 +00:00
pimpl - > mProgressHandler - > UpdateFileWrite ( 4 , 4 ) ;
2019-02-08 22:25:43 +00:00
} catch ( DeadlyExportError & err ) {
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 ) ;
2019-03-05 20:39:38 +00:00
2019-02-08 22:25:43 +00:00
return AI_FAILURE ;
}
// ------------------------------------------------------------------------------------------------
const char * Exporter : : GetErrorString ( ) const {
2022-04-26 16:56:24 +00:00
ai_assert ( nullptr ! = pimpl ) ;
2019-02-08 22:25:43 +00:00
return pimpl - > mError . c_str ( ) ;
}
// ------------------------------------------------------------------------------------------------
void Exporter : : FreeBlob ( ) {
2022-04-26 16:56:24 +00:00
ai_assert ( nullptr ! = pimpl ) ;
2019-02-08 22:25:43 +00:00
delete pimpl - > blob ;
2019-03-05 20:39:38 +00:00
pimpl - > blob = nullptr ;
2019-02-08 22:25:43 +00:00
pimpl - > mError = " " ;
}
// ------------------------------------------------------------------------------------------------
const aiExportDataBlob * Exporter : : GetBlob ( ) const {
2022-04-26 16:56:24 +00:00
ai_assert ( nullptr ! = pimpl ) ;
return pimpl - > blob ;
2019-02-08 22:25:43 +00:00
}
// ------------------------------------------------------------------------------------------------
const aiExportDataBlob * Exporter : : GetOrphanedBlob ( ) const {
2022-04-26 16:56:24 +00:00
ai_assert ( nullptr ! = pimpl ) ;
const aiExportDataBlob * tmp = pimpl - > blob ;
2019-03-05 20:39:38 +00:00
pimpl - > blob = nullptr ;
2019-02-08 22:25:43 +00:00
return tmp ;
}
// ------------------------------------------------------------------------------------------------
size_t Exporter : : GetExportFormatCount ( ) const {
2022-04-26 16:56:24 +00:00
ai_assert ( nullptr ! = pimpl ) ;
2019-02-08 22:25:43 +00:00
return pimpl - > mExporters . size ( ) ;
}
// ------------------------------------------------------------------------------------------------
const aiExportFormatDesc * Exporter : : GetExportFormatDescription ( size_t index ) const {
2022-04-26 16:56:24 +00:00
ai_assert ( nullptr ! = pimpl ) ;
if ( index > = GetExportFormatCount ( ) ) {
2019-03-05 20:39:38 +00:00
return nullptr ;
2019-02-08 22:25:43 +00:00
}
// Return from static storage if the requested index is built-in.
2022-04-26 16:56:24 +00:00
if ( index < pimpl - > mExporters . size ( ) ) {
return & pimpl - > mExporters [ index ] . mDescription ;
2019-02-08 22:25:43 +00:00
}
return & pimpl - > mExporters [ index ] . mDescription ;
}
// ------------------------------------------------------------------------------------------------
aiReturn Exporter : : RegisterExporter ( const ExportFormatEntry & desc ) {
2022-04-26 16:56:24 +00:00
ai_assert ( nullptr ! = pimpl ) ;
for ( const ExportFormatEntry & e : pimpl - > mExporters ) {
2019-02-08 22:25:43 +00:00
if ( ! strcmp ( e . mDescription . id , desc . mDescription . id ) ) {
return aiReturn_FAILURE ;
}
}
pimpl - > mExporters . push_back ( desc ) ;
return aiReturn_SUCCESS ;
}
// ------------------------------------------------------------------------------------------------
void Exporter : : UnregisterExporter ( const char * id ) {
2022-04-26 16:56:24 +00:00
ai_assert ( nullptr ! = pimpl ) ;
for ( std : : vector < ExportFormatEntry > : : iterator it = pimpl - > mExporters . begin ( ) ;
2019-03-05 20:39:38 +00:00
it ! = pimpl - > mExporters . end ( ) ; + + it ) {
2019-02-08 22:25:43 +00:00
if ( ! strcmp ( ( * it ) . mDescription . id , id ) ) {
pimpl - > mExporters . erase ( it ) ;
break ;
}
}
}
// ------------------------------------------------------------------------------------------------
2022-10-02 18:02:49 +00:00
ExportProperties : : ExportProperties ( ) = default ;
2019-02-08 22:25:43 +00:00
// ------------------------------------------------------------------------------------------------
2022-10-02 18:02:49 +00:00
ExportProperties : : ExportProperties ( const ExportProperties & other ) = default ;
2019-02-08 22:25:43 +00:00
2022-04-26 16:56:24 +00:00
bool ExportProperties : : SetPropertyCallback ( const char * szName , const std : : function < void * ( void * ) > & f ) {
return SetGenericProperty < std : : function < void * ( void * ) > > ( mCallbackProperties , szName , f ) ;
}
std : : function < void * ( void * ) > ExportProperties : : GetPropertyCallback ( const char * szName ) const {
2024-12-09 20:22:47 +00:00
return GetGenericProperty < std : : function < void * ( void * ) > > ( mCallbackProperties , szName , nullptr ) ;
2022-04-26 16:56:24 +00:00
}
bool ExportProperties : : HasPropertyCallback ( const char * szName ) const {
return HasGenericProperty < std : : function < void * ( void * ) > > ( mCallbackProperties , szName ) ;
}
2019-02-08 22:25:43 +00:00
// ------------------------------------------------------------------------------------------------
// Set a configuration property
bool ExportProperties : : SetPropertyInteger ( const char * szName , int iValue ) {
return SetGenericProperty < int > ( mIntProperties , szName , iValue ) ;
}
// ------------------------------------------------------------------------------------------------
// Set a configuration property
bool ExportProperties : : SetPropertyFloat ( const char * szName , ai_real iValue ) {
return SetGenericProperty < ai_real > ( mFloatProperties , szName , iValue ) ;
}
// ------------------------------------------------------------------------------------------------
// Set a configuration property
2019-03-05 20:39:38 +00:00
bool ExportProperties : : SetPropertyString ( const char * szName , const std : : string & value ) {
2019-02-08 22:25:43 +00:00
return SetGenericProperty < std : : string > ( mStringProperties , szName , value ) ;
}
// ------------------------------------------------------------------------------------------------
// Set a configuration property
2019-03-05 20:39:38 +00:00
bool ExportProperties : : SetPropertyMatrix ( const char * szName , const aiMatrix4x4 & value ) {
2019-02-08 22:25:43 +00:00
return SetGenericProperty < aiMatrix4x4 > ( mMatrixProperties , szName , value ) ;
}
// ------------------------------------------------------------------------------------------------
// Get a configuration property
2019-03-05 20:39:38 +00:00
int ExportProperties : : GetPropertyInteger ( const char * szName , int iErrorReturn /*= 0xffffffff*/ ) const {
2019-02-08 22:25:43 +00:00
return GetGenericProperty < int > ( mIntProperties , szName , iErrorReturn ) ;
}
// ------------------------------------------------------------------------------------------------
// Get a configuration property
2019-03-05 20:39:38 +00:00
ai_real ExportProperties : : GetPropertyFloat ( const char * szName , ai_real iErrorReturn /*= 10e10*/ ) const {
2019-02-08 22:25:43 +00:00
return GetGenericProperty < ai_real > ( mFloatProperties , szName , iErrorReturn ) ;
}
// ------------------------------------------------------------------------------------------------
// Get a configuration property
2019-03-05 20:39:38 +00:00
const std : : string ExportProperties : : GetPropertyString ( const char * szName ,
const std : : string & iErrorReturn /*= ""*/ ) const {
2019-02-08 22:25:43 +00:00
return GetGenericProperty < std : : string > ( mStringProperties , szName , iErrorReturn ) ;
}
// ------------------------------------------------------------------------------------------------
// Has a configuration property
2019-03-05 20:39:38 +00:00
const aiMatrix4x4 ExportProperties : : GetPropertyMatrix ( const char * szName ,
const aiMatrix4x4 & iErrorReturn /*= aiMatrix4x4()*/ ) const {
2019-02-08 22:25:43 +00:00
return GetGenericProperty < aiMatrix4x4 > ( mMatrixProperties , szName , iErrorReturn ) ;
}
// ------------------------------------------------------------------------------------------------
// Has a configuration property
2019-03-05 20:39:38 +00:00
bool ExportProperties : : HasPropertyInteger ( const char * szName ) const {
2019-02-08 22:25:43 +00:00
return HasGenericProperty < int > ( mIntProperties , szName ) ;
}
// ------------------------------------------------------------------------------------------------
// Has a configuration property
2019-03-05 20:39:38 +00:00
bool ExportProperties : : HasPropertyBool ( const char * szName ) const {
2019-02-08 22:25:43 +00:00
return HasGenericProperty < int > ( mIntProperties , szName ) ;
}
// ------------------------------------------------------------------------------------------------
// Has a configuration property
2019-03-05 20:39:38 +00:00
bool ExportProperties : : HasPropertyFloat ( const char * szName ) const {
2019-02-08 22:25:43 +00:00
return HasGenericProperty < ai_real > ( mFloatProperties , szName ) ;
}
// ------------------------------------------------------------------------------------------------
// Has a configuration property
2019-03-05 20:39:38 +00:00
bool ExportProperties : : HasPropertyString ( const char * szName ) const {
2019-02-08 22:25:43 +00:00
return HasGenericProperty < std : : string > ( mStringProperties , szName ) ;
}
// ------------------------------------------------------------------------------------------------
// Has a configuration property
2019-03-05 20:39:38 +00:00
bool ExportProperties : : HasPropertyMatrix ( const char * szName ) const {
2019-02-08 22:25:43 +00:00
return HasGenericProperty < aiMatrix4x4 > ( mMatrixProperties , szName ) ;
}
# endif // !ASSIMP_BUILD_NO_EXPORT