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
================================================
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros">
<FBX_SDK_DIR>C:\Program Files\Autodesk\FBX\FBX SDK\2020.0.1\</FBX_SDK_DIR>
</PropertyGroup>
<PropertyGroup />
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(FBX_SDK_DIR)include\;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
<PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<AdditionalLibraryDirectories Condition="$(Configuration) == 'Debug'">$(FBX_SDK_DIR)lib\vs2017\x64\debug\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories Condition="$(Configuration) == 'Release'">$(FBX_SDK_DIR)lib\vs2017\x64\release\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>libfbxsdk-mt.lib;zlib-mt.lib;libxml2-mt.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
</Project>
================================================
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
================================================
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<ProjectGuid>{9E46203A-785A-41A3-BD18-2DE2A7A7E4D7}</ProjectGuid>
<RootNamespace>FbxFormatConverter</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="FbxFormatConverter.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="FbxFormatConverter.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="FbxFormatConverter.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="FbxFormatConverter.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<IntDir>_Build\$(Platform)_$(Configuration)\</IntDir>
<OutDir>$(SolutionDir)Bin\$(Platform)_$(Configuration)\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)Bin\$(Platform)_$(Configuration)\</OutDir>
<IntDir>_Build\$(Platform)_$(Configuration)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="main.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="cmdParser.h" />
</ItemGroup>
<ItemGroup>
<None Include="FbxFormatConverter.props" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
================================================
FILE: FbxFormatConverter.vcxproj.filters
================================================
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="main.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="cmdParser.h" />
</ItemGroup>
<ItemGroup>
<None Include="FbxFormatConverter.props" />
</ItemGroup>
</Project>
================================================
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 <iostream>
#include <stdexcept>
#include <string>
#include <vector>
#include <sstream>
#include <functional>
namespace cli {
struct CallbackArgs {
const std::vector<std::string>& 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<std::string> 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<typename T>
struct ArgumentCountChecker
{
static constexpr bool Variadic = false;
};
template<typename T>
struct ArgumentCountChecker<std::vector<T>>
{
static constexpr bool Variadic = true;
};
template<typename T>
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<T>::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<T( CallbackArgs& )> callback;
T value;
};
template<typename T>
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<T>::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<std::string>& elements, const int& ) {
//if ( elements.size() != 1 )
// throw std::bad_cast();
return std::stoi( elements[0] );
}
static bool parse( const std::vector<std::string>& 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<std::string>& elements, const double& ) {
//if ( elements.size() != 1 )
// throw std::bad_cast();
return std::stod( elements[0] );
}
static float parse( const std::vector<std::string>& elements, const float& ) {
//if ( elements.size() != 1 )
// throw std::bad_cast();
return std::stof( elements[0] );
}
static long double parse( const std::vector<std::string>& elements, const long double& ) {
//if ( elements.size() != 1 )
// throw std::bad_cast();
return std::stold( elements[0] );
}
static unsigned int parse( const std::vector<std::string>& elements, const unsigned int& ) {
//if ( elements.size() != 1 )
// throw std::bad_cast();
return static_cast<unsigned int>( std::stoul( elements[0] ) );
}
static unsigned long parse( const std::vector<std::string>& elements, const unsigned long& ) {
//if ( elements.size() != 1 )
// throw std::bad_cast();
return std::stoul( elements[0] );
}
static long parse( const std::vector<std::string>& elements, const long& ) {
//if ( elements.size() != 1 )
// throw std::bad_cast();
return std::stol( elements[0] );
}
static std::string parse( const std::vector<std::string>& elements, const std::string& ) {
//if ( elements.size() != 1 )
// throw std::bad_cast();
return elements[0];
}
template<class T>
static std::vector<T> parse( const std::vector<std::string>& elements, const std::vector<T>& ) {
const T defval = T();
std::vector<T> values{};
std::vector<std::string> buffer( 1 );
for ( const auto& element : elements )
{
buffer[0] = element;
values.push_back( parse( buffer, defval ) );
}
return values;
}
template<class T>
static std::string stringify( const T& value ) {
return std::to_string( value );
}
template<class T>
static std::string stringify( const std::vector<T>& 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<bool( CallbackArgs& )>( [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<typename T>
void set_default( bool is_required, const std::string& description = "" ) {
auto command = new CmdArgument<T>{ "", "", description, is_required, false };
_commands.push_back( command );
}
template<typename T>
void set_required( const std::string& name, const std::string& alternative, const std::string& description = "", bool dominant = false ) {
auto command = new CmdArgument<T>{ name, alternative, description, true, dominant };
_commands.push_back( command );
}
template<typename T>
void set_optional( const std::string& name, const std::string& alternative, T defaultValue, const std::string& description = "", bool dominant = false ) {
auto command = new CmdArgument<T>{ name, alternative, description, false, dominant };
command->value = defaultValue;
_commands.push_back( command );
}
template<typename T>
void set_callback( const std::string& name, const std::string& alternative, std::function<T( CallbackArgs& )> callback, const std::string& description = "", bool dominant = false ) {
auto command = new CmdFunction<T>{ 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<typename T>
T get( const std::string& name ) const {
for ( const auto& command : _commands )
{
if ( command->name == name )
{
auto cmd = dynamic_cast<CmdArgument<T>*>( 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<typename T>
T get_if( const std::string& name, std::function<T( T )> callback ) const {
auto value = get<T>( 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<int>( _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<std::string> _arguments;
std::vector<CmdBase*> _commands;
};
}
================================================
FILE: main.cpp
================================================
#include <fbxsdk.h>
#include <windows.h>
#include <shlwapi.h>
#include <shlobj.h>
#include <shellapi.h>
#include <assert.h>
#include <functional>
#include <algorithm>
#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<std::string>& 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<int&>( m_binaryWriteID ) = i;
}
else if ( strcmp( pDescription, "FBX ascii (*.fbx)" ) == 0 )
{
const_cast<int&>( 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 <path> [-o <output path>] {-binary|-ascii}\n" );
printf( "Query: -q <path>\n" );
}
static void PrintFileFormat( std::string const& filePath )
{
FileFormat const fileFormat = FileSystemHelpers::GetFileFormat( filePath.c_str() );
if ( fileFormat == FileFormat::Binary )
{
printf( "%s - binary\n", filePath.c_str() );
}
else if ( fileFormat == FileFormat::Ascii )
{
printf( "%s - ascii\n", filePath.c_str() );
}
else
{
printf( "%s doesnt exist or is not an FBX file!\n", filePath.c_str() );
}
}
//-------------------------------------------------------------------------
int main( int argc, char* argv[] )
{
cli::Parser cmdParser( argc, argv );
cmdParser.disable_help();
cmdParser.set_optional<std::string>( "c", "convert", "" );
cmdParser.set_optional<std::string>( "o", "output", "" );
cmdParser.set_optional<std::string>( "q", "query", "" );
cmdParser.set_optional<bool>( "binary", "", false, "" );
cmdParser.set_optional<bool>( "ascii", "", false, "" );
if ( cmdParser.run() )
{
FbxConverter fbxConverter;
//-------------------------------------------------------------------------
auto inputConvertPath = cmdParser.get<std::string>( "c" );
if ( !inputConvertPath.empty() )
{
bool const outputAsBinary = cmdParser.get<bool>( "binary" );
bool const outputAsAscii = cmdParser.get<bool>( "ascii" );
if ( outputAsAscii && outputAsBinary )
{
PrintErrorAndHelp( "Having both -ascii and -binary arguments is not allowed." );
}
else if ( !outputAsAscii && !outputAsBinary )
{
PrintErrorAndHelp( "Either -ascii or -binary required!" );
}
else
{
FileFormat const outputFormat = outputAsBinary ? FileFormat::Binary : FileFormat::Ascii;
inputConvertPath = FileSystemHelpers::GetFullPathString( inputConvertPath );
if ( FileSystemHelpers::IsValidDirectoryPath( inputConvertPath ) )
{
std::vector<std::string> directoryContents;
FileSystemHelpers::GetDirectoryContents( inputConvertPath, directoryContents );
auto outputPath = cmdParser.get<std::string>( "o" );
if ( outputPath.empty() )
{
for ( auto& filePath : directoryContents )
{
if ( !fbxConverter.IsFbxFile( filePath.c_str() ) )
{
continue;
}
fbxConverter.ConvertFbxFile( filePath.c_str(), filePath.c_str(), outputFormat );
}
return 0;
}
else // Convert and copy
{
outputPath = FileSystemHelpers::GetFullPathString( outputPath );
for ( auto& filePath : directoryContents )
{
if ( !fbxConverter.IsFbxFile( filePath ) )
{
continue;
}
std::string newOutputPath = filePath;
newOutputPath.replace( 0, inputConvertPath.length() - 1, outputPath.c_str() );
fbxConverter.ConvertFbxFile( filePath, newOutputPath, outputFormat );
}
return 0;
}
}
else
{
auto outputPath = cmdParser.get<std::string>( "o" );
if ( outputPath.empty() )
{
return fbxConverter.ConvertFbxFile( inputConvertPath, inputConvertPath, outputFormat );
}
else
{
outputPath = FileSystemHelpers::GetFullPathString( outputPath );
return fbxConverter.ConvertFbxFile( inputConvertPath, outputPath, outputFormat );
}
}
}
}
else // check for query cmd line arg
{
auto inputQueryPath = cmdParser.get<std::string>( "q" );
if ( !inputQueryPath.empty() )
{
inputQueryPath = FileSystemHelpers::GetFullPathString( inputQueryPath );
if ( FileSystemHelpers::IsValidDirectoryPath( inputQueryPath ) )
{
std::vector<std::string> directoryContents;
FileSystemHelpers::GetDirectoryContents( inputQueryPath, directoryContents );
for ( auto& filePath : directoryContents )
{
if ( !fbxConverter.IsFbxFile( filePath ) )
{
continue;
}
PrintFileFormat( filePath );
}
}
else
{
PrintFileFormat( inputQueryPath );
}
}
else
{
PrintErrorAndHelp( "Invalid Arguments!" );
}
}
return 0;
}
else
{
PrintErrorAndHelp();
}
return 1;
}
================================================
FILE: readme.md
================================================
# Fbx Format Converter
This project allows you to convert binary fbx files to asciis and vice versa. This is especially useful when trying to import fbx files into blender since blender cannot read ascii FBX files.
## Features
* Single file conversion between binary and ascii
* Batch folder conversion
* Single file/folder query
## To build:
* You need to have the FBX SDK installed (https://www.autodesk.com/developer-network/platform-technologies/fbx-sdk-2020-0)
* Open the FbxFormatConverter.props file and change the FBX_SDK_DIR macro to point to the FBXSDK install directory.
* Open the sln file using visual studio and hit build.
## Conversion:
If you want to convert an ascii file into a binary one or vice versa.
`FbxFormatConverter.exe -c <filepath|folderpath> [-o <filepath|folderpath>] {-ascii|-binary}`
* -c : convert the file/folder specified
* -o : (optional) the outputpath for the converted files, if not supplied then the source file will be overwritten
* -binary/-ascii : the required output file format. Only one is allowed.
## Query:
If you want to find out if an FBX file is an ascii or a binary file.
`FbxFormatConverter.exe -q <filepath|folderpath>`
* -q : query the file/folder specified
## Examples
If you want to covert file "anim_temp_final_0_v2.fbx" to binary.
`FbxFormatConverter.exe -c "c:\anim_temp_final_0_v2.fbx" -binary`
If you want to convert all the files in folder a to ascii and store the converted files in folder b:
`FbxFormatConverter.exe -c "c:\a" -o "c:\b" -ascii`
If you want to know if file "dancingbaby.fbx" is a binary file.
`FbxFormatConverter.exe -q "c:\dancingbaby.fbx"`
## Notes:
This project uses CmdParser ( https://github.com/FlorianRappl/CmdParser )
gitextract_0xistjo3/ ├── .gitignore ├── FbxFormatConverter.args.json ├── FbxFormatConverter.props ├── FbxFormatConverter.sln ├── FbxFormatConverter.vcxproj ├── FbxFormatConverter.vcxproj.filters ├── LICENSE ├── cmdParser.h ├── main.cpp └── readme.md
SYMBOL INDEX (34 symbols across 2 files)
FILE: cmdParser.h
type CallbackArgs (line 15) | struct CallbackArgs {
function class (line 20) | class Parser {
function CmdFunction (line 70) | CmdFunction final : public CmdBase {
function parse (line 123) | static int parse( const std::vector<std::string>& elements, const int& ) {
function parse (line 130) | static bool parse( const std::vector<std::string>& elements, const bool&...
function parse (line 137) | static double parse( const std::vector<std::string>& elements, const dou...
function parse (line 144) | static float parse( const std::vector<std::string>& elements, const floa...
function parse (line 151) | static long double parse( const std::vector<std::string>& elements, cons...
function parse (line 158) | static unsigned int parse( const std::vector<std::string>& elements, con...
function parse (line 165) | static unsigned long parse( const std::vector<std::string>& elements, co...
function parse (line 172) | static long parse( const std::vector<std::string>& elements, const long&...
function std (line 179) | static std::string parse( const std::vector<std::string>& elements, cons...
function run_and_exit_if_error (line 307) | inline void run_and_exit_if_error() {
function run (line 314) | inline bool run() {
function run (line 318) | inline bool run( std::ostream& output ) {
function run (line 322) | bool run( std::ostream& output, std::ostream& error ) {
FILE: main.cpp
type FileFormat (line 24) | enum class FileFormat
type FileSystemHelpers (line 33) | namespace FileSystemHelpers
function GetFullPathString (line 35) | static std::string GetFullPathString( char const* pPath )
function GetFullPathString (line 54) | static std::string GetFullPathString( std::string const& path )
function GetParentDirectoryPath (line 59) | static std::string GetParentDirectoryPath( std::string const& path )
function IsValidDirectoryPath (line 71) | static bool IsValidDirectoryPath( std::string const& directoryPath )
function FileFormat (line 82) | static FileFormat GetFileFormat( std::string const& filePath )
function GetDirectoryContents (line 118) | static void GetDirectoryContents( std::string const& directoryPath, st...
function MakeDir (line 160) | static bool MakeDir( char const* pDirectoryPath )
class FbxConverter (line 169) | class FbxConverter
method FbxConverter (line 173) | FbxConverter()
method ConvertFbxFile (line 209) | int ConvertFbxFile( std::string const& inputFilepath, std::string cons...
method IsFbxFile (line 269) | bool IsFbxFile( std::string const& inputFilepath )
method FbxConverter (line 280) | FbxConverter( FbxConverter const& ) = delete;
method FbxConverter (line 281) | FbxConverter& operator=( FbxConverter const& ) = delete;
function PrintErrorAndHelp (line 292) | static void PrintErrorAndHelp( char const* pErrorMessage = nullptr )
function PrintFileFormat (line 308) | static void PrintFileFormat( std::string const& filePath )
function main (line 328) | int main( int argc, char* argv[] )
Condensed preview — 10 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (52K chars).
[
{
"path": ".gitignore",
"chars": 109,
"preview": "*.ipch\r\nBrowse.VC.db\r\nBrowse.VC.opendb\r\n.suo\r\n_Build/*\r\nBin/*\r\n.vs/*\r\n*.user\r\nFbxFormatConverter.vcxproj.user"
},
{
"path": "FbxFormatConverter.args.json",
"chars": 1638,
"preview": "{\r\n \"FileVersion\": 2,\r\n \"Id\": \"9e46203a-785a-41a3-bd18-2de2a7a7e4d7\",\r\n \"Items\": [\r\n {\r\n \"Id\": \"048f9f3d-b4f7"
},
{
"path": "FbxFormatConverter.props",
"chars": 1144,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbui"
},
{
"path": "FbxFormatConverter.sln",
"chars": 1092,
"preview": "\r\nMicrosoft Visual Studio Solution File, Format Version 12.00\r\n# Visual Studio Version 16\r\nVisualStudioVersion = 16.0.2"
},
{
"path": "FbxFormatConverter.vcxproj",
"chars": 7992,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/ms"
},
{
"path": "FbxFormatConverter.vcxproj.filters",
"chars": 362,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbui"
},
{
"path": "LICENSE",
"chars": 1071,
"preview": "MIT License\n\nCopyright (c) 2020 Bobby Anguelov\n\nPermission is hereby granted, free of charge, to any person obtaining a "
},
{
"path": "cmdParser.h",
"chars": 17218,
"preview": "/*\r\nThis file is part of the C++ CmdParser utility.\r\nCopyright (c) 2015 - 2016 Florian Rappl\r\n*/\r\n\r\n#pragma once\r\n#inclu"
},
{
"path": "main.cpp",
"chars": 15939,
"preview": "#include <fbxsdk.h>\r\n#include <windows.h>\r\n#include <shlwapi.h>\r\n#include <shlobj.h>\r\n#include <shellapi.h>\r\n#include <a"
},
{
"path": "readme.md",
"chars": 1781,
"preview": "# Fbx Format Converter\r\n\r\nThis project allows you to convert binary fbx files to asciis and vice versa. This is especial"
}
]
About this extraction
This page contains the full source code of the BobbyAnguelov/FbxFormatConverter GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 10 files (47.2 KB), approximately 10.9k tokens, and a symbol index with 34 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.