#include "Main.h"
const char* AICMD_MSG_ABOUT =
"------------------------------------------------------ \n"
"Open Asset Import Library (\"Assimp\", https://github.com/assimp/assimp) \n"
" -- Commandline toolchain --\n"
"------------------------------------------------------ \n\n"
"Version %i.%i %s%s%s%s%s(GIT commit %x)\n\n";
const char* AICMD_MSG_HELP =
"assimp <verb> <parameters>\n\n"
" verbs:\n"
" \tinfo - Quick file stats\n"
" \tlistext - List all known file extensions available for import\n"
" \tknowext - Check whether a file extension is recognized by Assimp\n"
#ifndef ASSIMP_BUILD_NO_EXPORT
" \texport - Export a file to one of the supported output formats\n"
" \tlistexport - List all supported export formats\n"
" \texportinfo - Show basic information on a specific export format\n"
#endif
" \textract - Extract embedded texture images\n"
" \tdump - Convert models to a binary or textual dump (ASSBIN/ASSXML)\n"
" \tcmpdump - Compare dumps created using \'assimp dump <file> -s ...\'\n"
" \tversion - Display Assimp version\n"
"\n Use \'assimp <verb> --help\' for detailed help on a command.\n"
;
Assimp::Importer* globalImporter = NULL;
#ifndef ASSIMP_BUILD_NO_EXPORT
Assimp::Exporter* globalExporter = NULL;
#endif
int main (int argc, char* argv[])
{
if (argc <= 1) {
printf("assimp: No command specified. Use \'assimp help\' for a detailed command list\n");
return 0;
}
if (! strcmp(argv[1], "version")) {
const unsigned int flags = aiGetCompileFlags();
printf(AICMD_MSG_ABOUT,
aiGetVersionMajor(),
aiGetVersionMinor(),
(flags & ASSIMP_CFLAGS_DEBUG ? "-debug " : ""),
(flags & ASSIMP_CFLAGS_NOBOOST ? "-noboost " : ""),
(flags & ASSIMP_CFLAGS_SHARED ? "-shared " : ""),
(flags & ASSIMP_CFLAGS_SINGLETHREADED ? "-st " : ""),
(flags & ASSIMP_CFLAGS_STLPORT ? "-stlport " : ""),
aiGetVersionRevision());
return 0;
}
if (!strcmp(argv[1], "help") || !strcmp(argv[1], "--help") || !strcmp(argv[1], "-h")) {
printf("%s",AICMD_MSG_HELP);
return 0;
}
if (! strcmp(argv[1], "cmpdump")) {
return Assimp_CompareDump (&argv[2],argc-2);
}
Assimp::Importer imp;
imp.SetPropertyBool("GLOB_MEASURE_TIME",true);
globalImporter = &imp;
#ifndef ASSIMP_BUILD_NO_EXPORT
Assimp::Exporter exp;
globalExporter = &exp;
#endif
if (! strcmp(argv[1], "listext")) {
aiString s;
imp.GetExtensionList(s);
printf("%s\n",s.data);
return 0;
}
#ifndef ASSIMP_BUILD_NO_EXPORT
if (! strcmp(argv[1], "listexport")) {
aiString s;
for(size_t i = 0, end = exp.GetExportFormatCount(); i < end; ++i) {
const aiExportFormatDesc* const e = exp.GetExportFormatDescription(i);
s.Append( e->id );
if (i!=end-1) {
s.Append("\n");
}
}
printf("%s\n",s.data);
return 0;
}
if (! strcmp(argv[1], "exportinfo")) {
aiString s;
if (argc<3) {
printf("Expected file format id\n");
return -11;
}
for(size_t i = 0, end = exp.GetExportFormatCount(); i < end; ++i) {
const aiExportFormatDesc* const e = exp.GetExportFormatDescription(i);
if (!strcmp(e->id,argv[2])) {
printf("%s\n%s\n%s\n",e->id,e->fileExtension,e->description);
return 0;
}
}
printf("Unknown file format id: \'%s\'\n",argv[2]);
return -12;
}
if (! strcmp(argv[1], "export")) {
return Assimp_Export (&argv[2],argc-2);
}
#endif
if (! strcmp(argv[1], "knowext")) {
if (argc<3) {
printf("Expected file extension");
return -10;
}
const bool b = imp.IsExtensionSupported(argv[2]);
printf("File extension \'%s\' is %sknown\n",argv[2],(b?"":"not "));
return b?0:-1;
}
if (! strcmp(argv[1], "info")) {
return Assimp_Info ((const char**)&argv[2],argc-2);
}
if (! strcmp(argv[1], "dump")) {
return Assimp_Dump (&argv[2],argc-2);
}
if (! strcmp(argv[1], "extract")) {
return Assimp_Extract (&argv[2],argc-2);
}
if (! strcmp(argv[1], "testbatchload")) {
return Assimp_TestBatchLoad (&argv[2],argc-2);
}
printf("Unrecognized command. Use \'assimp help\' for a detailed command list\n");
return 1;
}
void SetLogStreams(const ImportData& imp)
{
printf("\nAttaching log stream ... OK\n");
unsigned int flags = 0;
if (imp.logFile.length()) {
flags |= aiDefaultLogStream_FILE;
}
if (imp.showLog) {
flags |= aiDefaultLogStream_STDERR;
}
DefaultLogger::create(imp.logFile.c_str(),imp.verbose ? Logger::VERBOSE : Logger::NORMAL,flags);
}
void FreeLogStreams()
{
DefaultLogger::kill();
}
void PrintHorBar()
{
printf("-----------------------------------------------------------------\n");
}
const aiScene* ImportModel(
const ImportData& imp,
const std::string& path)
{
if (imp.log) {
SetLogStreams(imp);
}
printf("Launching asset import ... OK\n");
if(!globalImporter->ValidateFlags(imp.ppFlags)) {
printf("ERROR: Unsupported post-processing flags \n");
return NULL;
}
printf("Validating postprocessing flags ... OK\n");
if (imp.showLog) {
PrintHorBar();
}
const clock_t first = clock();
const aiScene* scene = globalImporter->ReadFile(path,imp.ppFlags);
if (imp.showLog) {
PrintHorBar();
}
if (!scene) {
printf("ERROR: Failed to load file: %s\n", globalImporter->GetErrorString());
return NULL;
}
const clock_t second = ::clock();
const double seconds = static_cast<double>(second-first) / CLOCKS_PER_SEC;
printf("Importing file ... OK \n import took approx. %.5f seconds\n"
"\n",seconds);
if (imp.log) {
FreeLogStreams();
}
return scene;
}
#ifndef ASSIMP_BUILD_NO_EXPORT
bool ExportModel(const aiScene* pOut,
const ImportData& imp,
const std::string& path,
const char* pID)
{
if (imp.log) {
SetLogStreams(imp);
}
printf("Launching asset export ... OK\n");
if (imp.showLog) {
PrintHorBar();
}
const clock_t first = clock();
const aiReturn res = globalExporter->Export(pOut,pID,path);
if (imp.showLog) {
PrintHorBar();
}
if (res != AI_SUCCESS) {
printf("ERROR: Failed to write file\n");
return false;
}
const clock_t second = ::clock();
const double seconds = static_cast<double>(second-first) / CLOCKS_PER_SEC;
printf("Exporting file ... OK \n export took approx. %.5f seconds\n"
"\n",seconds);
if (imp.log) {
FreeLogStreams();
}
return true;
}
#endif
int ProcessStandardArguments(
ImportData& fill,
const char* const * params,
unsigned int num)
{
for (unsigned int i = 0; i < num;++i)
{
if (! strcmp(params[i], "-ptv") || ! strcmp(params[i], "--pretransform-vertices")) {
fill.ppFlags |= aiProcess_PreTransformVertices;
}
else if (! strcmp(params[i], "-gsn") || ! strcmp(params[i], "--gen-smooth-normals")) {
fill.ppFlags |= aiProcess_GenSmoothNormals;
}
else if (! strcmp(params[i], "-gn") || ! strcmp(params[i], "--gen-normals")) {
fill.ppFlags |= aiProcess_GenNormals;
}
else if (! strcmp(params[i], "-jiv") || ! strcmp(params[i], "--join-identical-vertices")) {
fill.ppFlags |= aiProcess_JoinIdenticalVertices;
}
else if (! strcmp(params[i], "-rrm") || ! strcmp(params[i], "--remove-redundant-materials")) {
fill.ppFlags |= aiProcess_RemoveRedundantMaterials;
}
else if (! strcmp(params[i], "-fd") || ! strcmp(params[i], "--find-degenerates")) {
fill.ppFlags |= aiProcess_FindDegenerates;
}
else if (! strcmp(params[i], "-slm") || ! strcmp(params[i], "--split-large-meshes")) {
fill.ppFlags |= aiProcess_SplitLargeMeshes;
}
else if (! strcmp(params[i], "-lbw") || ! strcmp(params[i], "--limit-bone-weights")) {
fill.ppFlags |= aiProcess_LimitBoneWeights;
}
else if (! strcmp(params[i], "-vds") || ! strcmp(params[i], "--validate-data-structure")) {
fill.ppFlags |= aiProcess_ValidateDataStructure;
}
else if (! strcmp(params[i], "-icl") || ! strcmp(params[i], "--improve-cache-locality")) {
fill.ppFlags |= aiProcess_ImproveCacheLocality;
}
else if (! strcmp(params[i], "-sbpt") || ! strcmp(params[i], "--sort-by-ptype")) {
fill.ppFlags |= aiProcess_SortByPType;
}
else if (! strcmp(params[i], "-lh") || ! strcmp(params[i], "--left-handed")) {
fill.ppFlags |= aiProcess_ConvertToLeftHanded;
}
else if (! strcmp(params[i], "-fuv") || ! strcmp(params[i], "--flip-uv")) {
fill.ppFlags |= aiProcess_FlipUVs;
}
else if (! strcmp(params[i], "-fwo") || ! strcmp(params[i], "--flip-winding-order")) {
fill.ppFlags |= aiProcess_FlipWindingOrder;
}
else if (! strcmp(params[i], "-tuv") || ! strcmp(params[i], "--transform-uv-coords")) {
fill.ppFlags |= aiProcess_TransformUVCoords;
}
else if (! strcmp(params[i], "-guv") || ! strcmp(params[i], "--gen-uvcoords")) {
fill.ppFlags |= aiProcess_GenUVCoords;
}
else if (! strcmp(params[i], "-fid") || ! strcmp(params[i], "--find-invalid-data")) {
fill.ppFlags |= aiProcess_FindInvalidData;
}
else if (! strcmp(params[i], "-fixn") || ! strcmp(params[i], "--fix-normals")) {
fill.ppFlags |= aiProcess_FixInfacingNormals;
}
else if (! strcmp(params[i], "-tri") || ! strcmp(params[i], "--triangulate")) {
fill.ppFlags |= aiProcess_Triangulate;
}
else if (! strcmp(params[i], "-cts") || ! strcmp(params[i], "--calc-tangent-space")) {
fill.ppFlags |= aiProcess_CalcTangentSpace;
}
else if (! strcmp(params[i], "-fi") || ! strcmp(params[i], "--find-instances")) {
fill.ppFlags |= aiProcess_FindInstances;
}
else if (! strcmp(params[i], "-og") || ! strcmp(params[i], "--optimize-graph")) {
fill.ppFlags |= aiProcess_OptimizeGraph;
}
else if (! strcmp(params[i], "-om") || ! strcmp(params[i], "--optimize-meshes")) {
fill.ppFlags |= aiProcess_OptimizeMeshes;
}
else if (! strcmp(params[i], "-db") || ! strcmp(params[i], "--debone")) {
fill.ppFlags |= aiProcess_Debone;
}
else if (! strcmp(params[i], "-sbc") || ! strcmp(params[i], "--split-by-bone-count")) {
fill.ppFlags |= aiProcess_SplitByBoneCount;
}
else if (! strncmp(params[i], "-c",2) || ! strncmp(params[i], "--config=",9)) {
const unsigned int ofs = (params[i][1] == '-' ? 9 : 2);
if (! strncmp(params[i]+ofs,"full",4)) {
fill.ppFlags |= aiProcessPreset_TargetRealtime_MaxQuality;
}
else if (! strncmp(params[i]+ofs,"default",7)) {
fill.ppFlags |= aiProcessPreset_TargetRealtime_Quality;
}
else if (! strncmp(params[i]+ofs,"fast",4)) {
fill.ppFlags |= aiProcessPreset_TargetRealtime_Fast;
}
}
else if (! strcmp(params[i], "-l") || ! strcmp(params[i], "--show-log")) {
fill.showLog = true;
}
else if (! strcmp(params[i], "-v") || ! strcmp(params[i], "--verbose")) {
fill.verbose = true;
}
else if (! strncmp(params[i], "--log-out=",10) || ! strncmp(params[i], "-lo",3)) {
fill.logFile = std::string(params[i]+(params[i][1] == '-' ? 10 : 3));
if (!fill.logFile.length()) {
fill.logFile = "assimp-log.txt";
}
}
}
if (fill.logFile.length() || fill.showLog || fill.verbose) {
fill.log = true;
}
return 0;
}
int Assimp_TestBatchLoad (
const char* const* params,
unsigned int num)
{
for(unsigned int i = 0; i < num; ++i) {
globalImporter->ReadFile(params[i],aiProcessPreset_TargetRealtime_MaxQuality);
}
return 0;
}