closes https://github.com/assimp/assimp/issues/2199: introduce first version for exporter.

pull/2217/head
Kim Kulling 2018-11-12 22:26:10 +01:00
parent 3fbe9095d1
commit b6af80f2fd
8 changed files with 194 additions and 65 deletions

View File

@ -52,9 +52,7 @@ namespace Assimp {
// ------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------
/** @brief Internal default implementation of the #ProgressHandler interface. */ /** @brief Internal default implementation of the #ProgressHandler interface. */
class DefaultProgressHandler class DefaultProgressHandler : public ProgressHandler {
: public ProgressHandler {
virtual bool Update(float /*percentage*/) { virtual bool Update(float /*percentage*/) {
return false; return false;

View File

@ -56,22 +56,22 @@ Here we implement only the C++ interface (Assimp::Exporter).
#include <assimp/BlobIOSystem.h> #include <assimp/BlobIOSystem.h>
#include <assimp/SceneCombiner.h> #include <assimp/SceneCombiner.h>
#include "BaseProcess.h" #include <assimp/DefaultIOSystem.h>
#include "Importer.h" // need this for GetPostProcessingStepInstanceList() #include <assimp/Exporter.hpp>
#include <assimp/mesh.h>
#include <assimp/postprocess.h>
#include <assimp/scene.h>
#include "DefaultProgressHandler.h"
#include "BaseProcess.h"
#include "JoinVerticesProcess.h" #include "JoinVerticesProcess.h"
#include "MakeVerboseFormat.h" #include "MakeVerboseFormat.h"
#include "ConvertToLHProcess.h" #include "ConvertToLHProcess.h"
#include "PretransformVertices.h" #include "PretransformVertices.h"
#include <assimp/Exceptional.h> #include <assimp/Exceptional.h>
#include "ScenePrivate.h" #include "ScenePrivate.h"
#include <memory>
#include <assimp/DefaultIOSystem.h> #include <memory>
#include <assimp/Exporter.hpp>
#include <assimp/mesh.h>
#include <assimp/postprocess.h>
#include <assimp/scene.h>
namespace Assimp { namespace Assimp {
@ -188,10 +188,14 @@ Exporter::ExportFormatEntry gExporters[] =
class ExporterPimpl { class ExporterPimpl {
public: public:
ExporterPimpl() ExporterPimpl()
: blob() : blob()
, mIOSystem(new Assimp::DefaultIOSystem()) , mIOSystem(new Assimp::DefaultIOSystem())
, mIsDefaultIOHandler(true) , mIsDefaultIOHandler(true)
{ , mProgressHandler( nullptr )
, mIsDefaultProgressHandler( true )
, mPostProcessingSteps()
, mError()
, mExporters() {
GetPostProcessingStepInstanceList(mPostProcessingSteps); GetPostProcessingStepInstanceList(mPostProcessingSteps);
// grab all built-in exporters // grab all built-in exporters
@ -201,8 +205,7 @@ public:
} }
} }
~ExporterPimpl() ~ExporterPimpl() {
{
delete blob; delete blob;
// Delete all post-processing plug-ins // Delete all post-processing plug-ins
@ -216,6 +219,10 @@ public:
std::shared_ptr< Assimp::IOSystem > mIOSystem; std::shared_ptr< Assimp::IOSystem > mIOSystem;
bool mIsDefaultIOHandler; bool mIsDefaultIOHandler;
/** The progress handler */
ProgressHandler *mProgressHandler;
bool mIsDefaultProgressHandler;
/** Post processing steps we can apply at the imported data. */ /** Post processing steps we can apply at the imported data. */
std::vector< BaseProcess* > mPostProcessingSteps; std::vector< BaseProcess* > mPostProcessingSteps;
@ -233,13 +240,16 @@ using namespace Assimp;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
Exporter :: Exporter() Exporter :: Exporter()
: pimpl(new ExporterPimpl()) { : pimpl(new ExporterPimpl()) {
// empty pimpl->mProgressHandler = new DefaultProgressHandler();
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
Exporter::~Exporter() { Exporter::~Exporter() {
FreeBlob(); FreeBlob();
if (pimpl->mIsDefaultProgressHandler) {
delete pimpl->mProgressHandler;
pimpl->mProgressHandler = nullptr;
}
delete pimpl; delete pimpl;
} }
@ -259,12 +269,32 @@ bool Exporter::IsDefaultIOHandler() const {
return pimpl->mIsDefaultIOHandler; return pimpl->mIsDefaultIOHandler;
} }
// ------------------------------------------------------------------------------------------------
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;
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
const aiExportDataBlob* Exporter::ExportToBlob( const aiScene* pScene, const char* pFormatId, const aiExportDataBlob* Exporter::ExportToBlob( const aiScene* pScene, const char* pFormatId,
unsigned int, const ExportProperties* /*pProperties*/ ) { unsigned int, const ExportProperties* /*pProperties*/ ) {
if (pimpl->blob) { if (pimpl->blob) {
delete pimpl->blob; delete pimpl->blob;
pimpl->blob = NULL; pimpl->blob = nullptr;
} }
std::shared_ptr<IOSystem> old = pimpl->mIOSystem; std::shared_ptr<IOSystem> old = pimpl->mIOSystem;
@ -273,7 +303,7 @@ const aiExportDataBlob* Exporter::ExportToBlob( const aiScene* pScene, const cha
if (AI_SUCCESS != Export(pScene,pFormatId,blobio->GetMagicFileName())) { if (AI_SUCCESS != Export(pScene,pFormatId,blobio->GetMagicFileName())) {
pimpl->mIOSystem = old; pimpl->mIOSystem = old;
return NULL; return nullptr;
} }
pimpl->blob = blobio->GetBlobChain(); pimpl->blob = blobio->GetBlobChain();
@ -295,6 +325,7 @@ bool IsVerboseFormat(const aiMesh* mesh) {
} }
} }
} }
return true; return true;
} }
@ -305,6 +336,7 @@ bool IsVerboseFormat(const aiScene* pScene) {
return false; return false;
} }
} }
return true; return true;
} }
@ -319,6 +351,8 @@ aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const c
// meshes upfront. // meshes upfront.
const bool is_verbose_format = !(pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) || IsVerboseFormat(pScene); const bool is_verbose_format = !(pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) || IsVerboseFormat(pScene);
pimpl->mProgressHandler->UpdateFileWrite(0, 4);
pimpl->mError = ""; pimpl->mError = "";
for (size_t i = 0; i < pimpl->mExporters.size(); ++i) { for (size_t i = 0; i < pimpl->mExporters.size(); ++i) {
const Exporter::ExportFormatEntry& exp = pimpl->mExporters[i]; const Exporter::ExportFormatEntry& exp = pimpl->mExporters[i];
@ -326,9 +360,11 @@ aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const c
try { try {
// Always create a full copy of the scene. We might optimize this one day, // Always create a full copy of the scene. We might optimize this one day,
// but for now it is the most pragmatic way. // but for now it is the most pragmatic way.
aiScene* scenecopy_tmp = NULL; aiScene* scenecopy_tmp = nullptr;
SceneCombiner::CopyScene(&scenecopy_tmp,pScene); SceneCombiner::CopyScene(&scenecopy_tmp,pScene);
pimpl->mProgressHandler->UpdateFileWrite(1, 4);
std::unique_ptr<aiScene> scenecopy(scenecopy_tmp); std::unique_ptr<aiScene> scenecopy(scenecopy_tmp);
const ScenePrivateData* const priv = ScenePriv(pScene); const ScenePrivateData* const priv = ScenePriv(pScene);
@ -375,6 +411,8 @@ aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const c
} }
} }
pimpl->mProgressHandler->UpdateFileWrite(2, 4);
if (pp) { if (pp) {
// the three 'conversion' steps need to be executed first because all other steps rely on the standard data layout // the three 'conversion' steps need to be executed first because all other steps rely on the standard data layout
{ {
@ -418,11 +456,13 @@ aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const c
} }
} }
ScenePrivateData* const privOut = ScenePriv(scenecopy.get()); ScenePrivateData* const privOut = ScenePriv(scenecopy.get());
ai_assert(privOut); ai_assert(nullptr != privOut);
privOut->mPPStepsApplied |= pp; privOut->mPPStepsApplied |= pp;
} }
pimpl->mProgressHandler->UpdateFileWrite(3, 4);
if(must_join_again) { if(must_join_again) {
JoinVerticesProcess proc; JoinVerticesProcess proc;
proc.Execute(scenecopy.get()); proc.Execute(scenecopy.get());
@ -430,6 +470,8 @@ aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const c
ExportProperties emptyProperties; // Never pass NULL ExportProperties so Exporters don't have to worry. ExportProperties emptyProperties; // Never pass NULL ExportProperties so Exporters don't have to worry.
exp.mExportFunction(pPath,pimpl->mIOSystem.get(),scenecopy.get(), pProperties ? pProperties : &emptyProperties); exp.mExportFunction(pPath,pimpl->mIOSystem.get(),scenecopy.get(), pProperties ? pProperties : &emptyProperties);
pimpl->mProgressHandler->UpdateFileWrite(4, 4);
} catch (DeadlyExportError& err) { } catch (DeadlyExportError& err) {
pimpl->mError = err.what(); pimpl->mError = err.what();
return AI_FAILURE; return AI_FAILURE;
@ -452,7 +494,7 @@ const char* Exporter::GetErrorString() const {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Exporter::FreeBlob() { void Exporter::FreeBlob() {
delete pimpl->blob; delete pimpl->blob;
pimpl->blob = NULL; pimpl->blob = nullptr;
pimpl->mError = ""; pimpl->mError = "";
} }
@ -465,7 +507,7 @@ const aiExportDataBlob* Exporter::GetBlob() const {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
const aiExportDataBlob* Exporter::GetOrphanedBlob() const { const aiExportDataBlob* Exporter::GetOrphanedBlob() const {
const aiExportDataBlob* tmp = pimpl->blob; const aiExportDataBlob* tmp = pimpl->blob;
pimpl->blob = NULL; pimpl->blob = nullptr;
return tmp; return tmp;
} }
@ -545,75 +587,63 @@ bool ExportProperties::SetPropertyString(const char* szName, const std::string&
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Set a configuration property // Set a configuration property
bool ExportProperties :: SetPropertyMatrix(const char* szName, const aiMatrix4x4& value) bool ExportProperties::SetPropertyMatrix(const char* szName, const aiMatrix4x4& value) {
{
return SetGenericProperty<aiMatrix4x4>(mMatrixProperties, szName,value); return SetGenericProperty<aiMatrix4x4>(mMatrixProperties, szName,value);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Get a configuration property // Get a configuration property
int ExportProperties :: GetPropertyInteger(const char* szName, int ExportProperties::GetPropertyInteger(const char* szName, int iErrorReturn /*= 0xffffffff*/) const {
int iErrorReturn /*= 0xffffffff*/) const
{
return GetGenericProperty<int>(mIntProperties,szName,iErrorReturn); return GetGenericProperty<int>(mIntProperties,szName,iErrorReturn);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Get a configuration property // Get a configuration property
ai_real ExportProperties :: GetPropertyFloat(const char* szName, ai_real ExportProperties::GetPropertyFloat(const char* szName, ai_real iErrorReturn /*= 10e10*/) const {
ai_real iErrorReturn /*= 10e10*/) const
{
return GetGenericProperty<ai_real>(mFloatProperties,szName,iErrorReturn); return GetGenericProperty<ai_real>(mFloatProperties,szName,iErrorReturn);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Get a configuration property // Get a configuration property
const std::string ExportProperties :: GetPropertyString(const char* szName, const std::string ExportProperties::GetPropertyString(const char* szName,
const std::string& iErrorReturn /*= ""*/) const const std::string& iErrorReturn /*= ""*/) const {
{
return GetGenericProperty<std::string>(mStringProperties,szName,iErrorReturn); return GetGenericProperty<std::string>(mStringProperties,szName,iErrorReturn);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Has a configuration property // Has a configuration property
const aiMatrix4x4 ExportProperties :: GetPropertyMatrix(const char* szName, const aiMatrix4x4 ExportProperties::GetPropertyMatrix(const char* szName,
const aiMatrix4x4& iErrorReturn /*= aiMatrix4x4()*/) const const aiMatrix4x4& iErrorReturn /*= aiMatrix4x4()*/) const {
{
return GetGenericProperty<aiMatrix4x4>(mMatrixProperties,szName,iErrorReturn); return GetGenericProperty<aiMatrix4x4>(mMatrixProperties,szName,iErrorReturn);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Has a configuration property // Has a configuration property
bool ExportProperties :: HasPropertyInteger(const char* szName) const bool ExportProperties::HasPropertyInteger(const char* szName) const {
{
return HasGenericProperty<int>(mIntProperties, szName); return HasGenericProperty<int>(mIntProperties, szName);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Has a configuration property // Has a configuration property
bool ExportProperties :: HasPropertyBool(const char* szName) const bool ExportProperties::HasPropertyBool(const char* szName) const {
{
return HasGenericProperty<int>(mIntProperties, szName); return HasGenericProperty<int>(mIntProperties, szName);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Has a configuration property // Has a configuration property
bool ExportProperties :: HasPropertyFloat(const char* szName) const bool ExportProperties::HasPropertyFloat(const char* szName) const {
{
return HasGenericProperty<ai_real>(mFloatProperties, szName); return HasGenericProperty<ai_real>(mFloatProperties, szName);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Has a configuration property // Has a configuration property
bool ExportProperties :: HasPropertyString(const char* szName) const bool ExportProperties::HasPropertyString(const char* szName) const {
{
return HasGenericProperty<std::string>(mStringProperties, szName); return HasGenericProperty<std::string>(mStringProperties, szName);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Has a configuration property // Has a configuration property
bool ExportProperties :: HasPropertyMatrix(const char* szName) const bool ExportProperties::HasPropertyMatrix(const char* szName) const {
{
return HasGenericProperty<aiMatrix4x4>(mMatrixProperties, szName); return HasGenericProperty<aiMatrix4x4>(mMatrixProperties, szName);
} }

View File

@ -315,22 +315,19 @@ void Importer::SetIOHandler( IOSystem* pIOHandler)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Get the currently set IO handler // Get the currently set IO handler
IOSystem* Importer::GetIOHandler() const IOSystem* Importer::GetIOHandler() const {
{
return pimpl->mIOHandler; return pimpl->mIOHandler;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Check whether a custom IO handler is currently set // Check whether a custom IO handler is currently set
bool Importer::IsDefaultIOHandler() const bool Importer::IsDefaultIOHandler() const {
{
return pimpl->mIsDefaultHandler; return pimpl->mIsDefaultHandler;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Supplies a custom progress handler to get regular callbacks during importing // Supplies a custom progress handler to get regular callbacks during importing
void Importer::SetProgressHandler ( ProgressHandler* pHandler ) void Importer::SetProgressHandler ( ProgressHandler* pHandler ) {
{
ASSIMP_BEGIN_EXCEPTION_REGION(); ASSIMP_BEGIN_EXCEPTION_REGION();
// If the new handler is zero, allocate a default implementation. // If the new handler is zero, allocate a default implementation.
if (!pHandler) if (!pHandler)
@ -351,15 +348,13 @@ void Importer::SetProgressHandler ( ProgressHandler* pHandler )
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Get the currently set progress handler // Get the currently set progress handler
ProgressHandler* Importer::GetProgressHandler() const ProgressHandler* Importer::GetProgressHandler() const {
{
return pimpl->mProgressHandler; return pimpl->mProgressHandler;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Check whether a custom progress handler is currently set // Check whether a custom progress handler is currently set
bool Importer::IsDefaultProgressHandler() const bool Importer::IsDefaultProgressHandler() const {
{
return pimpl->mIsDefaultProgressHandler; return pimpl->mIsDefaultProgressHandler;
} }

View File

@ -57,6 +57,7 @@ namespace Assimp {
class ExporterPimpl; class ExporterPimpl;
class IOSystem; class IOSystem;
class ProgressHandler;
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
/** CPP-API: The Exporter class forms an C++ interface to the export functionality /** CPP-API: The Exporter class forms an C++ interface to the export functionality
@ -84,8 +85,7 @@ public:
typedef void (*fpExportFunc)(const char*, IOSystem*, const aiScene*, const ExportProperties*); typedef void (*fpExportFunc)(const char*, IOSystem*, const aiScene*, const ExportProperties*);
/** Internal description of an Assimp export format option */ /** Internal description of an Assimp export format option */
struct ExportFormatEntry struct ExportFormatEntry {
{
/// Public description structure to be returned by aiGetExportFormatDescription() /// Public description structure to be returned by aiGetExportFormatDescription()
aiExportFormatDesc mDescription; aiExportFormatDesc mDescription;
@ -158,6 +158,19 @@ public:
* @return true by default */ * @return true by default */
bool IsDefaultIOHandler() const; bool IsDefaultIOHandler() const;
// -------------------------------------------------------------------
/** Supplies a custom progress handler to the exporter. This
* interface exposes an #Update() callback, which is called
* more or less periodically (please don't sue us if it
* isn't as periodically as you'd like it to have ...).
* This can be used to implement progress bars and loading
* timeouts.
* @param pHandler Progress callback interface. Pass nullptr to
* disable progress reporting.
* @note Progress handlers can be used to abort the loading
* at almost any time.*/
void SetProgressHandler(ProgressHandler* pHandler);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Exports the given scene to a chosen file format. Returns the exported /** 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. * data as a binary blob which you can write into a file or something.

View File

@ -330,7 +330,7 @@ public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Supplies a custom progress handler to the importer. This /** Supplies a custom progress handler to the importer. This
* interface exposes a #Update() callback, which is called * interface exposes an #Update() callback, which is called
* more or less periodically (please don't sue us if it * more or less periodically (please don't sue us if it
* isn't as periodically as you'd like it to have ...). * isn't as periodically as you'd like it to have ...).
* This can be used to implement progress bars and loading * This can be used to implement progress bars and loading

View File

@ -62,11 +62,13 @@ class ASSIMP_API ProgressHandler
#endif #endif
{ {
protected: protected:
/** @brief Default constructor */ /// @brief Default constructor
ProgressHandler () AI_NO_EXCEPT { ProgressHandler () AI_NO_EXCEPT {
// empty
} }
public: public:
/** @brief Virtual destructor */ /// @brief Virtual destructor.
virtual ~ProgressHandler () { virtual ~ProgressHandler () {
} }
@ -120,8 +122,24 @@ public:
Update( f * 0.5f + 0.5f ); Update( f * 0.5f + 0.5f );
} }
// -------------------------------------------------------------------
/** @brief Progress callback for export steps.
* @param numberOfSteps The number of total processing
* steps
* @param currentStep The index of the current post-processing
* step that will run, or equal to numberOfSteps if all of
* them has finished. This number is always strictly monotone
* increasing, although not necessarily linearly.
* */
virtual void UpdateFileWrite(int currentStep /*= 0*/, int numberOfSteps /*= 0*/) {
float f = numberOfSteps ? currentStep / (float)numberOfSteps : 1.0f;
Update(f * 0.5f);
}
}; // !class ProgressHandler }; // !class ProgressHandler
// ------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------
} // Namespace Assimp } // Namespace Assimp
#endif // AI_PROGRESSHANDLER_H_INC #endif // AI_PROGRESSHANDLER_H_INC

View File

@ -87,6 +87,7 @@ SET( IMPORTERS
unit/utIFCImportExport.cpp unit/utIFCImportExport.cpp
unit/utFBXImporterExporter.cpp unit/utFBXImporterExporter.cpp
unit/utImporter.cpp unit/utImporter.cpp
unit/ImportExport/utExporter.cpp
unit/ut3DImportExport.cpp unit/ut3DImportExport.cpp
unit/ut3DSImportExport.cpp unit/ut3DSImportExport.cpp
unit/utACImportExport.cpp unit/utACImportExport.cpp

View File

@ -0,0 +1,74 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2018, assimp team
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.
---------------------------------------------------------------------------
*/
#include "UnitTestPCH.h"
#include <assimp/Exporter.hpp>
#include <assimp/ProgressHandler.hpp>
using namespace Assimp;
class TestProgressHandler : public ProgressHandler {
public:
TestProgressHandler() : ProgressHandler() {
// empty
}
virtual ~TestProgressHandler() {
// empty
}
bool Update(float percentage = -1.f) override {
return true;
}
};
class ExporterTest : public ::testing::Test {
// empty
};
TEST_F(ExporterTest, ProgressHandlerTest) {
Exporter exporter;
TestProgressHandler *ph(new TestProgressHandler);
exporter.SetProgressHandler(ph);
delete ph;
}