Repository: BobbyAnguelov/FbxFormatConverter
Branch: master
Commit: 8ac24511f3f5
Files: 10
Total size: 47.2 KB
Directory structure:
gitextract_0xistjo3/
├── .gitignore
├── FbxFormatConverter.args.json
├── FbxFormatConverter.props
├── FbxFormatConverter.sln
├── FbxFormatConverter.vcxproj
├── FbxFormatConverter.vcxproj.filters
├── LICENSE
├── cmdParser.h
├── main.cpp
└── readme.md
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
*.ipch
Browse.VC.db
Browse.VC.opendb
.suo
_Build/*
Bin/*
.vs/*
*.user
FbxFormatConverter.vcxproj.user
================================================
FILE: FbxFormatConverter.args.json
================================================
{
"FileVersion": 2,
"Id": "9e46203a-785a-41a3-bd18-2de2a7a7e4d7",
"Items": [
{
"Id": "048f9f3d-b4f7-421a-88a2-8208d935e75d",
"Command": "",
"Items": [
{
"Id": "02d89d7e-4960-4457-bcb6-3425ba20ab07",
"Command": "-q blah.fbx"
},
{
"Id": "28299385-031f-4af4-91dd-1c590319b3ef",
"Command": "-q SK_Chr_Attach_Female_Armor_02.fbx"
},
{
"Id": "c55eea3c-9a11-4ef5-b3c6-dbf81f43e261",
"Command": "-q TestData"
}
]
},
{
"Id": "5fa48bfb-6393-481a-b2ab-c0bd71ed50f1",
"Command": "",
"Items": [
{
"Id": "5ae255c1-876e-4bcd-b400-edd0be3b171f",
"Command": "-c SM_Bld_Apartment_01.fbx"
},
{
"Id": "778e8d89-1616-468a-a9b1-623270e645a3",
"Command": "-o TestFileOut.fbx"
},
{
"Id": "12a719b6-1313-4bc5-802f-5255a8f72766",
"Command": "-binary"
},
{
"Id": "d8f98b79-6ee4-4bf0-bc49-bf92c8666b44",
"Command": "-ascii"
}
]
},
{
"Id": "3f90e0f3-43db-4bbe-9976-f82862fc5ebb",
"Command": "",
"Items": [
{
"Id": "5a09faa8-7239-44a1-bd45-ab3d7e42064b",
"Command": "-c TestData"
},
{
"Id": "730b2ceb-ba4c-4251-9406-2251cb22ba37",
"Command": "-o Converted.fbx"
},
{
"Id": "289c0524-0c30-4d5a-8195-359af124689c",
"Command": "-ascii"
}
]
}
]
}
================================================
FILE: FbxFormatConverter.props
================================================
C:\Program Files\Autodesk\FBX\FBX SDK\2020.0.1\
$(FBX_SDK_DIR)include\;%(AdditionalIncludeDirectories);
%(PreprocessorDefinitions)
$(FBX_SDK_DIR)lib\vs2017\x64\debug\;%(AdditionalLibraryDirectories)
$(FBX_SDK_DIR)lib\vs2017\x64\release\;%(AdditionalLibraryDirectories)
libfbxsdk-mt.lib;zlib-mt.lib;libxml2-mt.lib;%(AdditionalDependencies)
================================================
FILE: FbxFormatConverter.sln
================================================
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29905.134
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FbxFormatConverter", "FbxFormatConverter.vcxproj", "{9E46203A-785A-41A3-BD18-2DE2A7A7E4D7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{9E46203A-785A-41A3-BD18-2DE2A7A7E4D7}.Debug|x64.ActiveCfg = Debug|x64
{9E46203A-785A-41A3-BD18-2DE2A7A7E4D7}.Debug|x64.Build.0 = Debug|x64
{9E46203A-785A-41A3-BD18-2DE2A7A7E4D7}.Release|x64.ActiveCfg = Release|x64
{9E46203A-785A-41A3-BD18-2DE2A7A7E4D7}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {DAC409EE-F3F3-4A2C-B22F-316A9B8CAEFA}
EndGlobalSection
EndGlobal
================================================
FILE: FbxFormatConverter.vcxproj
================================================
Debug
Win32
Release
Win32
Debug
x64
Release
x64
16.0
{9E46203A-785A-41A3-BD18-2DE2A7A7E4D7}
FbxFormatConverter
10.0
Application
true
v142
Unicode
Application
false
v142
true
Unicode
Application
true
v142
Unicode
Application
false
v142
true
Unicode
true
true
_Build\$(Platform)_$(Configuration)\
$(SolutionDir)Bin\$(Platform)_$(Configuration)\
false
false
$(SolutionDir)Bin\$(Platform)_$(Configuration)\
_Build\$(Platform)_$(Configuration)\
Level3
true
_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
true
Console
true
Level4
true
_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
true
MultiThreadedDebug
true
Console
true
Level3
true
true
true
NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
true
Console
true
true
true
Level4
true
true
true
NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
true
MultiThreaded
true
Console
true
true
true
================================================
FILE: FbxFormatConverter.vcxproj.filters
================================================
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2020 Bobby Anguelov
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: cmdParser.h
================================================
/*
This file is part of the C++ CmdParser utility.
Copyright (c) 2015 - 2016 Florian Rappl
*/
#pragma once
#include
#include
#include
#include
#include
#include
namespace cli {
struct CallbackArgs {
const std::vector& arguments;
std::ostream& output;
std::ostream& error;
};
class Parser {
private:
class CmdBase {
public:
explicit CmdBase( const std::string& name, const std::string& alternative, const std::string& description, bool required, bool dominant, bool variadic ) :
name( name ),
command( name.size() > 0 ? "-" + name : "" ),
alternative( alternative.size() > 0 ? "--" + alternative : "" ),
description( description ),
required( required ),
handled( false ),
arguments( {} ),
dominant( dominant ),
variadic( variadic ) {
}
virtual ~CmdBase() {
}
std::string name;
std::string command;
std::string alternative;
std::string description;
bool required;
bool handled;
std::vector arguments;
bool const dominant;
bool const variadic;
virtual std::string print_value() const = 0;
virtual bool parse( std::ostream& output, std::ostream& error ) = 0;
bool is( const std::string& given ) const {
return given == command || given == alternative;
}
};
template
struct ArgumentCountChecker
{
static constexpr bool Variadic = false;
};
template
struct ArgumentCountChecker>
{
static constexpr bool Variadic = true;
};
template
class CmdFunction final : public CmdBase {
public:
explicit CmdFunction( const std::string& name, const std::string& alternative, const std::string& description, bool required, bool dominant ) :
CmdBase( name, alternative, description, required, dominant, ArgumentCountChecker::Variadic ) {
}
virtual bool parse( std::ostream& output, std::ostream& error ) {
try
{
CallbackArgs args{ arguments, output, error };
value = callback( args );
return true;
}
catch ( ... )
{
return false;
}
}
virtual std::string print_value() const {
return "";
}
std::function callback;
T value;
};
template
class CmdArgument final : public CmdBase {
public:
explicit CmdArgument( const std::string& name, const std::string& alternative, const std::string& description, bool required, bool dominant ) :
CmdBase( name, alternative, description, required, dominant, ArgumentCountChecker::Variadic ) {
}
virtual bool parse( std::ostream&, std::ostream& ) {
try
{
value = Parser::parse( arguments, value );
return true;
}
catch ( ... )
{
return false;
}
}
virtual std::string print_value() const {
return stringify( value );
}
T value;
};
static int parse( const std::vector& elements, const int& ) {
//if ( elements.size() != 1 )
// throw std::bad_cast();
return std::stoi( elements[0] );
}
static bool parse( const std::vector& elements, const bool& defval ) {
if ( elements.size() != 0 )
throw std::runtime_error( "A boolean command line parameter cannot have any arguments." );
return !defval;
}
static double parse( const std::vector& elements, const double& ) {
//if ( elements.size() != 1 )
// throw std::bad_cast();
return std::stod( elements[0] );
}
static float parse( const std::vector& elements, const float& ) {
//if ( elements.size() != 1 )
// throw std::bad_cast();
return std::stof( elements[0] );
}
static long double parse( const std::vector& elements, const long double& ) {
//if ( elements.size() != 1 )
// throw std::bad_cast();
return std::stold( elements[0] );
}
static unsigned int parse( const std::vector& elements, const unsigned int& ) {
//if ( elements.size() != 1 )
// throw std::bad_cast();
return static_cast( std::stoul( elements[0] ) );
}
static unsigned long parse( const std::vector& elements, const unsigned long& ) {
//if ( elements.size() != 1 )
// throw std::bad_cast();
return std::stoul( elements[0] );
}
static long parse( const std::vector& elements, const long& ) {
//if ( elements.size() != 1 )
// throw std::bad_cast();
return std::stol( elements[0] );
}
static std::string parse( const std::vector& elements, const std::string& ) {
//if ( elements.size() != 1 )
// throw std::bad_cast();
return elements[0];
}
template
static std::vector parse( const std::vector& elements, const std::vector& ) {
const T defval = T();
std::vector values{};
std::vector buffer( 1 );
for ( const auto& element : elements )
{
buffer[0] = element;
values.push_back( parse( buffer, defval ) );
}
return values;
}
template
static std::string stringify( const T& value ) {
return std::to_string( value );
}
template
static std::string stringify( const std::vector& values ) {
std::stringstream ss{};
ss << "[ ";
for ( const auto& value : values )
{
ss << stringify( value ) << " ";
}
ss << "]";
return ss.str();
}
static std::string stringify( const std::string& str ) {
return str;
}
public:
explicit Parser( int argc, const char** argv ) :
_appname( argv[0] ) {
for ( int i = 1; i < argc; ++i )
{
_arguments.push_back( argv[i] );
}
enable_help();
}
explicit Parser( int argc, char** argv ) :
_appname( argv[0] ) {
for ( int i = 1; i < argc; ++i )
{
_arguments.push_back( argv[i] );
}
enable_help();
}
~Parser() {
for ( int i = 0, n = _commands.size(); i < n; ++i )
{
delete _commands[i];
}
}
bool has_help() const {
for ( const auto command : _commands )
{
if ( command->name == "h" && command->alternative == "--help" )
{
return true;
}
}
return false;
}
void enable_help() {
set_callback( "h", "help", std::function( [this] ( CallbackArgs& args ) {
args.output << this->usage();
exit( 0 );
return false;
} ), "", true );
}
void disable_help() {
for ( auto command = _commands.begin(); command != _commands.end(); ++command )
{
if ( ( *command )->name == "h" && ( *command )->alternative == "--help" )
{
_commands.erase( command );
break;
}
}
}
template
void set_default( bool is_required, const std::string& description = "" ) {
auto command = new CmdArgument{ "", "", description, is_required, false };
_commands.push_back( command );
}
template
void set_required( const std::string& name, const std::string& alternative, const std::string& description = "", bool dominant = false ) {
auto command = new CmdArgument{ name, alternative, description, true, dominant };
_commands.push_back( command );
}
template
void set_optional( const std::string& name, const std::string& alternative, T defaultValue, const std::string& description = "", bool dominant = false ) {
auto command = new CmdArgument{ name, alternative, description, false, dominant };
command->value = defaultValue;
_commands.push_back( command );
}
template
void set_callback( const std::string& name, const std::string& alternative, std::function callback, const std::string& description = "", bool dominant = false ) {
auto command = new CmdFunction{ name, alternative, description, false, dominant };
command->callback = callback;
_commands.push_back( command );
}
inline void run_and_exit_if_error() {
if ( run() == false )
{
exit( 1 );
}
}
inline bool run() {
return run( std::cout, std::cerr );
}
inline bool run( std::ostream& output ) {
return run( output, std::cerr );
}
bool run( std::ostream& output, std::ostream& error ) {
if ( _arguments.size() > 0 )
{
auto current = find_default();
for ( int i = 0, n = _arguments.size(); i < n; ++i )
{
auto isarg = _arguments[i].size() > 0 && _arguments[i][0] == '-';
auto associated = isarg ? find( _arguments[i] ) : nullptr;
if ( associated != nullptr )
{
current = associated;
associated->handled = true;
}
else if ( current == nullptr )
{
//error << no_default();
return false;
}
else
{
current->arguments.push_back( _arguments[i] );
current->handled = true;
if ( !current->variadic )
{
// If the current command is not variadic, then no more arguments
// should be added to it. In this case, switch back to the default
// command.
current = find_default();
}
}
}
}
// First, parse dominant arguments since they succeed even if required
// arguments are missing.
for ( auto command : _commands )
{
if ( command->handled && command->dominant && !command->parse( output, error ) )
{
error << howto_use( command );
return false;
}
}
// Next, check for any missing arguments.
for ( auto command : _commands )
{
if ( command->required && !command->handled )
{
error << howto_required( command );
return false;
}
}
// Finally, parse all remaining arguments.
for ( auto command : _commands )
{
if ( command->handled && !command->dominant && !command->parse( output, error ) )
{
error << howto_use( command );
return false;
}
}
return true;
}
template
T get( const std::string& name ) const {
for ( const auto& command : _commands )
{
if ( command->name == name )
{
auto cmd = dynamic_cast*>( command );
if ( cmd == nullptr )
{
throw std::runtime_error( "Invalid usage of the parameter " + name + " detected." );
}
return cmd->value;
}
}
throw std::runtime_error( "The parameter " + name + " could not be found." );
}
template
T get_if( const std::string& name, std::function callback ) const {
auto value = get( name );
return callback( value );
}
int requirements() const {
int count = 0;
for ( const auto& command : _commands )
{
if ( command->required )
{
++count;
}
}
return count;
}
int commands() const {
return static_cast( _commands.size() );
}
inline const std::string& app_name() const {
return _appname;
}
protected:
CmdBase* find( const std::string& name ) {
for ( auto command : _commands )
{
if ( command->is( name ) )
{
return command;
}
}
return nullptr;
}
CmdBase* find_default() {
for ( auto command : _commands )
{
if ( command->name == "" )
{
return command;
}
}
return nullptr;
}
std::string usage() const {
std::stringstream ss{};
ss << "Available parameters:\n\n";
for ( const auto& command : _commands )
{
ss << " " << command->command << "\t" << command->alternative;
if ( command->required == true )
{
ss << "\t(required)";
}
ss << "\n " << command->description;
if ( command->required == false )
{
ss << "\n " << "This parameter is optional. The default value is '" + command->print_value() << "'.";
}
ss << "\n\n";
}
return ss.str();
}
void print_help( std::stringstream& ss ) const {
if ( has_help() )
{
ss << "For more help use --help or -h.\n";
}
}
std::string howto_required( CmdBase* command ) const {
std::stringstream ss{};
ss << "The parameter " << command->name << " is required.\n";
ss << command->description << '\n';
print_help( ss );
return ss.str();
}
std::string howto_use( CmdBase* command ) const {
std::stringstream ss{};
ss << "The parameter " << command->name << " has invalid arguments.\n";
ss << command->description << '\n';
print_help( ss );
return ss.str();
}
std::string no_default() const {
std::stringstream ss{};
ss << "No default parameter has been specified.\n";
ss << "The given argument must be used with a parameter.\n";
print_help( ss );
return ss.str();
}
private:
const std::string _appname;
std::vector _arguments;
std::vector _commands;
};
}
================================================
FILE: main.cpp
================================================
#include
#include
#include
#include
#include
#include
#include
#include
#if _MSC_VER
#pragma warning(push, 0)
#pragma warning(disable: 4702)
#endif
// Note: this has been modified for this application
#include "cmdParser.h"
#if _MSC_VER
#pragma warning(pop)
#endif
//-------------------------------------------------------------------------
enum class FileFormat
{
Unknown,
Binary,
Ascii
};
//-------------------------------------------------------------------------
namespace FileSystemHelpers
{
static std::string GetFullPathString( char const* pPath )
{
assert( pPath != nullptr && pPath[0] != 0 );
char fullpath[256] = { 0 };
DWORD length = GetFullPathNameA( pPath, 256, fullpath, nullptr );
assert( length != 0 && length != 255 );
// We always append the trailing slash to simplify further operations
DWORD const result = GetFileAttributesA( fullpath );
if ( result != INVALID_FILE_ATTRIBUTES && ( result & FILE_ATTRIBUTE_DIRECTORY ) && fullpath[length - 1] != '\\' )
{
fullpath[length] = '\\';
fullpath[length + 1] = 0;
}
return std::string( fullpath );
}
static std::string GetFullPathString( std::string const& path )
{
return GetFullPathString( path.c_str() );
}
static std::string GetParentDirectoryPath( std::string const& path )
{
std::string dirPath;
size_t const lastSlashIdx = path.rfind( '\\' );
if ( lastSlashIdx != std::string::npos )
{
dirPath = path.substr( 0, lastSlashIdx + 1 );
}
return dirPath;
}
static bool IsValidDirectoryPath( std::string const& directoryPath )
{
DWORD const result = GetFileAttributesA( directoryPath.c_str() );
if ( result != INVALID_FILE_ATTRIBUTES && ( result & FILE_ATTRIBUTE_DIRECTORY ) )
{
return true;
}
return false;
}
static FileFormat GetFileFormat( std::string const& filePath )
{
FileFormat fileFormat = FileFormat::Unknown;
FILE* fp = nullptr;
int errcode = fopen_s( &fp, filePath.c_str(), "r" );
if ( errcode != 0 )
{
return fileFormat;
}
//-------------------------------------------------------------------------
fseek( fp, 0, SEEK_END );
size_t filesize = (size_t) ftell( fp );
fseek( fp, 0, SEEK_SET );
void* pFileData = malloc( filesize );
size_t readLength = fread( pFileData, 1, filesize, fp );
fclose( fp );
//-------------------------------------------------------------------------
// Ascii files cannot contain the null character
if ( memchr( pFileData, '\0', readLength ) != NULL )
{
fileFormat = FileFormat::Binary;
}
else
{
fileFormat = FileFormat::Ascii;
}
return fileFormat;
}
static void GetDirectoryContents( std::string const& directoryPath, std::vector& directoryContents )
{
if ( !IsValidDirectoryPath( directoryPath ) )
{
printf( "Error! %s is not a valid directory!", directoryPath.c_str() );
return;
}
//-------------------------------------------------------------------------
std::string const directorySearchPath = directoryPath + "*";
//-------------------------------------------------------------------------
WIN32_FIND_DATAA findData;
HANDLE foundFileHandle = FindFirstFileA( directorySearchPath.c_str(), &findData );
assert( foundFileHandle != INVALID_HANDLE_VALUE );
//-------------------------------------------------------------------------
char stringBuffer[1024] = { 0 };
do
{
if ( strcmp( findData.cFileName, "." ) == 0 || strcmp( findData.cFileName, ".." ) == 0 )
{
continue;
}
if ( findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
{
sprintf_s( stringBuffer, 1024, "%s%s\\", directoryPath.c_str(), findData.cFileName );
GetDirectoryContents( stringBuffer, directoryContents );
}
else
{
sprintf_s( stringBuffer, 1024, "%s%s", directoryPath.c_str(), findData.cFileName );
directoryContents.emplace_back( GetFullPathString( stringBuffer ) );
}
} while ( FindNextFileA( foundFileHandle, &findData ) != 0 );
}
static bool MakeDir( char const* pDirectoryPath )
{
assert( pDirectoryPath != nullptr );
return SUCCEEDED( SHCreateDirectoryExA( nullptr, pDirectoryPath, nullptr ) );
}
}
//-------------------------------------------------------------------------
class FbxConverter
{
public:
FbxConverter()
: m_pManager( FbxManager::Create() )
{
assert( m_pManager != nullptr );
auto pIOPluginRegistry = m_pManager->GetIOPluginRegistry();
// Find the IDs for the ascii and binary writers
int const numWriters = pIOPluginRegistry->GetWriterFormatCount();
for ( int i = 0; i < numWriters; i++ )
{
if ( pIOPluginRegistry->WriterIsFBX( i ) )
{
char const* pDescription = pIOPluginRegistry->GetWriterFormatDescription( i );
if ( strcmp( pDescription, "FBX binary (*.fbx)" ) == 0 )
{
const_cast( m_binaryWriteID ) = i;
}
else if ( strcmp( pDescription, "FBX ascii (*.fbx)" ) == 0 )
{
const_cast( m_asciiWriterID ) = i;
}
}
}
//-------------------------------------------------------------------------
// This should never occur but I'm leaving it here in case someone updates the plugin with a new SDK and names change
assert( m_binaryWriteID != -1 && m_asciiWriterID != -1 );
}
~FbxConverter()
{
m_pManager->Destroy();
m_pManager = nullptr;
}
int ConvertFbxFile( std::string const& inputFilepath, std::string const& outputFilepath, FileFormat outputFormat )
{
// Import
//-------------------------------------------------------------------------
FbxImporter* pImporter = FbxImporter::Create( m_pManager, "FBX Importer" );
if ( !pImporter->Initialize( inputFilepath.c_str(), -1, m_pManager->GetIOSettings() ) )
{
printf( "Error! Failed to load specified FBX file ( %s ): %s\n\n", inputFilepath.c_str(), pImporter->GetStatus().GetErrorString() );
return 1;
}
auto pScene = FbxScene::Create( m_pManager, "ImportScene" );
if ( !pImporter->Import( pScene ) )
{
printf( "Error! Failed to import scene from file ( %s ): %s\n\n", inputFilepath.c_str(), pImporter->GetStatus().GetErrorString() );
pImporter->Destroy();
return 1;
}
pImporter->Destroy();
// Set output format
//-------------------------------------------------------------------------
int const fileFormatIDToUse = ( outputFormat == FileFormat::Binary ) ? m_binaryWriteID : m_asciiWriterID;
// Export
//-------------------------------------------------------------------------
std::string const parentDirPath = FileSystemHelpers::GetParentDirectoryPath( outputFilepath );
if ( !FileSystemHelpers::MakeDir( parentDirPath.c_str() ) )
{
printf( "Error! Failed to create output directory (%s)!\n\n", outputFilepath.c_str() );
}
//-------------------------------------------------------------------------
FbxExporter* pExporter = FbxExporter::Create( m_pManager, "FBX Exporter" );
if ( !pExporter->Initialize( outputFilepath.c_str(), fileFormatIDToUse, m_pManager->GetIOSettings() ) )
{
printf( "Error! Failed to initialize exporter: %s\n\n", pExporter->GetStatus().GetErrorString() );
return 1;
}
if ( pExporter->Export( pScene ) )
{
printf( "Success!\nIn: %s \nOut (%s): %s\n\n", inputFilepath.c_str(), outputFormat == FileFormat::Binary ? "binary" : "ascii", outputFilepath.c_str() );
}
else
{
printf( "Error! File export failed: - %s\n\n", pExporter->GetStatus().GetErrorString() );
}
pExporter->Destroy();
//-------------------------------------------------------------------------
return 0;
}
bool IsFbxFile( std::string const& inputFilepath )
{
assert( !inputFilepath.empty() );
int readerID = -1;
auto pIOPluginRegistry = m_pManager->GetIOPluginRegistry();
pIOPluginRegistry->DetectReaderFileFormat( inputFilepath.c_str(), readerID );
return pIOPluginRegistry->ReaderIsFBX( readerID );
}
private:
FbxConverter( FbxConverter const& ) = delete;
FbxConverter& operator=( FbxConverter const& ) = delete;
private:
FbxManager* m_pManager = nullptr;
int const m_binaryWriteID = -1;
int const m_asciiWriterID = -1;
};
//-------------------------------------------------------------------------
static void PrintErrorAndHelp( char const* pErrorMessage = nullptr )
{
printf( "================================================\n" );
printf( "FBX File Format Converter\n" );
printf( "================================================\n" );
printf( "2020 - Bobby Anguelov - MIT License\n\n" );
if ( pErrorMessage != nullptr )
{
printf( "Error! %s\n\n", pErrorMessage );
}
printf( "Convert: -c [-o