+ Implement export utility into assimp_cmd.

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@929 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
pull/1/head
aramis_acg 2011-04-03 10:45:27 +00:00
parent 6dea8f2ecd
commit eb4afe8f91
3 changed files with 362 additions and 33 deletions

View File

@ -0,0 +1,168 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (ASSIMP)
---------------------------------------------------------------------------
Copyright (c) 2006-2010, ASSIMP Development 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 Development Team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
/** @file Export.cpp
* @brief Implementation of the 'assimp export' utility
*/
#include "Main.h"
#ifndef ASSIMP_BUILD_NO_EXPORT
const char* AICMD_MSG_EXPORT_HELP_E =
"assimp export <model> [<out>] [-f<h>] [common parameters]\n"
"\t -f<h> Specify the file format. If ommitted, the output format is \n"
"\t\tderived from the file extension of the given output file \n"
"\t[See the assimp_cmd docs for a full list of all common parameters] \n"
;
// -----------------------------------------------------------------------------------
size_t GetMatchingFormat(const std::string& outf,bool byext=false)
{
for(size_t i = 0, end = globalExporter->GetExportFormatCount(); i < end; ++i) {
const aiExportFormatDesc* const e = globalExporter->GetExportFormatDescription(i);
if (outf == (byext ? e->fileExtension : e->id)) {
return i;
}
}
return SIZE_MAX;
}
// -----------------------------------------------------------------------------------
int Assimp_Export(const char* const* params, unsigned int num)
{
const char* const invalid = "assimp export: Invalid number of arguments. See \'assimp export --help\'\n";
if (num < 1) {
printf(invalid);
return 1;
}
// --help
if (!strcmp( params[0], "-h") || !strcmp( params[0], "--help") || !strcmp( params[0], "-?") ) {
printf("%s",AICMD_MSG_EXPORT_HELP_E);
return 0;
}
std::string in = std::string(params[0]);
std::string out = (num > 1 ? std::string(params[1]) : "-"), outext;
//
const std::string::size_type s = out.find_last_of('.');
if (s != std::string::npos) {
outext = out.substr(s+1,in.length()-(s+1));
out = out.substr(0,s);
}
// get import flags
ImportData import;
ProcessStandardArguments(import,params+1,num-1);
// process other flags
std::string outf = "";
for (unsigned int i = (out[0] == '-' ? 1 : 2); i < num;++i) {
if (!params[i]) {
continue;
}
if (!strncmp( params[i], "-f",2)) {
outf = std::string(params[i]+2);
}
else if ( !strncmp( params[i], "--format=",9)) {
outf = std::string(params[i]+9);
}
}
std::transform(outf.begin(),outf.end(),outf.begin(),::tolower);
// convert the output format to a format id
size_t outfi = GetMatchingFormat(outf);
if (outfi == SIZE_MAX) {
if (outf.length()) {
printf("assimp export: warning, format id \'%s\' is unknown\n",outf.c_str());
}
// retry to see if we know it as file extension
outfi = GetMatchingFormat(outf,true);
if (outfi == SIZE_MAX) {
// retry to see if we know the file extension of the output file
outfi = GetMatchingFormat(outext,true);
if (outfi == SIZE_MAX) {
// still no match -> failure
printf("assimp export: no output format specified and I failed to guess it");
return -23;
}
}
else {
outext = outf;
}
}
// if no output file is specified, take the file name from input file
if (out[0] == '-') {
std::string::size_type s = in.find_last_of('.');
if (s == std::string::npos) {
s = in.length();
}
out = in.substr(0,s);
}
const aiExportFormatDesc* const e = globalExporter->GetExportFormatDescription(outfi);
printf("assimp export: select file format: \'%s\' (%s)\n",e->id,e->description);
// import the model
const aiScene* scene = ImportModel(import,in);
// derive the final file name
out += "."+outext;
// and call the export routine
if(!ExportModel(scene, import, out,e->id)) {
return -25;
}
printf("assimp export: wrote output file: %s",out.c_str());
return 0;
}
#endif // no export

View File

@ -47,28 +47,37 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
const char* AICMD_MSG_ABOUT = const char* AICMD_MSG_ABOUT =
"------------------------------------------------------ \n" "------------------------------------------------------ \n"
"Open Asset Import Library - Assimp \n" "Open Asset Import Library (\"Assimp\", http://assimp.sourceforge.net) \n"
"http://assimp.sourceforge.net \n" " -- Commandline toolchain --\n"
"Command-line tools \n"
"------------------------------------------------------ \n\n" "------------------------------------------------------ \n\n"
"Version %i.%i-%s%s%s%s%s (SVNREV %i)\n\n"; "Version %i.%i-%s%s%s%s%s (SVNREV %i)\n\n";
const char* AICMD_MSG_HELP = const char* AICMD_MSG_HELP =
"assimp <verb> <arguments>\n\n" "assimp <verb> <parameters>\n\n"
"\tverbs:\n" " verbs:\n"
"\t\tinfo - Display statistics and structure of a 3D model\n" " \tinfo - Quick file stats\n"
"\t\tversion - Display Assimp version\n" " \tlistext - List all known file extensions available for import\n"
"\t\tlistext - List all known file extension\n" " \tknowext - Check whether a file extension is recognized by Assimp\n"
"\t\tknowext - Check whether a file extension is recognized by Assimp\n" #ifndef ASSIMP_BUILD_NO_EXPORT
"\t\textract - Extract an embedded texture from a model\n" " \texport - Export a file to one of the supported output formats\n"
"\t\tdump - Convert a model to binary or XML dumps (ASSBIN/ASSXML)\n" " \tlistexport - List all supported export formats\n"
"\t\tcmpdump - Compare two file dumps produced with \'assimp dump <file> -s ...\'\n" " \tknowexport - Check whether a particular export format is supported\n"
"\n\n\tUse \'assimp <verb> --help\' to get detailed help for a command.\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\n Use \'assimp <verb> --help\' for detailed help on a command.\n"
; ;
/*extern*/ Assimp::Importer* globalImporter = NULL; /*extern*/ Assimp::Importer* globalImporter = NULL;
#ifndef ASSIMP_BUILD_NO_EXPORT
/*extern*/ Assimp::Exporter* globalExporter = NULL;
#endif
// ------------------------------------------------------------------------------ // ------------------------------------------------------------------------------
// Application entry point // Application entry point
int main (int argc, char* argv[]) int main (int argc, char* argv[])
@ -109,12 +118,17 @@ int main (int argc, char* argv[])
return Assimp_CompareDump (&argv[2],argc-2); return Assimp_CompareDump (&argv[2],argc-2);
} }
// construct a global Assimp::Importer instance // construct global importer and exporter instances
// because all further tools rely on it
Assimp::Importer imp; Assimp::Importer imp;
imp.SetPropertyBool("GLOB_MEASURE_TIME",true); imp.SetPropertyBool("GLOB_MEASURE_TIME",true);
globalImporter = &imp; globalImporter = &imp;
#ifndef ASSIMP_BUILD_NO_EXPORT
//
Assimp::Exporter exp;
globalExporter = &exp;
#endif
// assimp listext // assimp listext
// List all file extensions supported by Assimp // List all file extensions supported by Assimp
if (! strcmp(argv[1], "listext")) { if (! strcmp(argv[1], "listext")) {
@ -125,11 +139,59 @@ int main (int argc, char* argv[])
return 0; return 0;
} }
#ifndef ASSIMP_BUILD_NO_EXPORT
// assimp listexport
// List all export file formats supported by Assimp (not the file extensions, just the format identifiers!)
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",s.data);
return 0;
}
// assimp exportinfo
// stat an export format
if (! strcmp(argv[1], "exportinfo")) {
aiString s;
if (argc<3) {
printf("Expected file format id");
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",e->id,e->fileExtension,e->description);
return 0;
}
}
printf("Unknown file format id: %s",argv[2]);
return -12;
}
// assimp export
// Export a model to a file
if (! strcmp(argv[1], "export")) {
return Assimp_Export (&argv[2],argc-2);
}
#endif
// assimp knowext // assimp knowext
// Check whether a particular file extension is known by us, return 0 on success // Check whether a particular file extension is known by us, return 0 on success
if (! strcmp(argv[1], "knowext")) { if (! strcmp(argv[1], "knowext")) {
if (argc<3) { if (argc<3) {
printf("Expected a file extension to check for!"); printf("Expected file extension");
return -10; return -10;
} }
const bool b = imp.IsExtensionSupported(argv[2]); const bool b = imp.IsExtensionSupported(argv[2]);
@ -167,6 +229,37 @@ int main (int argc, char* argv[])
return 1; 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");
}
// ------------------------------------------------------------------------------ // ------------------------------------------------------------------------------
// Import a specific file // Import a specific file
const aiScene* ImportModel( const aiScene* ImportModel(
@ -175,18 +268,9 @@ const aiScene* ImportModel(
{ {
// Attach log streams // Attach log streams
if (imp.log) { if (imp.log) {
printf("\nAttaching log stream ... OK\n"); SetLogStreams(imp);
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);
} }
printf("Launching model import ... OK\n"); printf("Launching asset import ... OK\n");
// Now validate this flag combination // Now validate this flag combination
if(!globalImporter->ValidateFlags(imp.ppFlags)) { if(!globalImporter->ValidateFlags(imp.ppFlags)) {
@ -194,15 +278,17 @@ const aiScene* ImportModel(
return NULL; return NULL;
} }
printf("Validating postprocessing flags ... OK\n"); printf("Validating postprocessing flags ... OK\n");
if (imp.showLog) if (imp.showLog) {
printf("-----------------------------------------------------------------\n"); PrintHorBar();
}
// do the actual import, measure time // do the actual import, measure time
const clock_t first = clock(); const clock_t first = clock();
const aiScene* scene = globalImporter->ReadFile(path,imp.ppFlags); const aiScene* scene = globalImporter->ReadFile(path,imp.ppFlags);
if (imp.showLog) { if (imp.showLog) {
printf("-----------------------------------------------------------------\n"); PrintHorBar();
} }
if (!scene) { if (!scene) {
printf("ERROR: Failed to load file\n"); printf("ERROR: Failed to load file\n");
@ -210,17 +296,60 @@ const aiScene* ImportModel(
} }
const clock_t second = ::clock(); const clock_t second = ::clock();
const float seconds = (float)(second-first) / CLOCKS_PER_SEC; const double seconds = static_cast<double>(second-first) / CLOCKS_PER_SEC;
printf("Importing file ... OK \n import took approx. %.5f seconds\n" printf("Importing file ... OK \n import took approx. %.5f seconds\n"
"\n",seconds); "\n",seconds);
if (imp.log) { if (imp.log) {
DefaultLogger::kill(); FreeLogStreams();
} }
return scene; return scene;
} }
#ifndef ASSIMP_BUILD_NO_EXPORT
// ------------------------------------------------------------------------------
bool ExportModel(const aiScene* pOut,
const ImportData& imp,
const std::string& path,
const char* pID)
{
// Attach log streams
if (imp.log) {
SetLogStreams(imp);
}
printf("Launching asset export ... OK\n");
if (imp.showLog) {
PrintHorBar();
}
// do the actual export, measure time
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
// ------------------------------------------------------------------------------ // ------------------------------------------------------------------------------
// Process standard arguments // Process standard arguments
int ProcessStandardArguments( int ProcessStandardArguments(

View File

@ -58,6 +58,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp.hpp> #include <assimp.hpp>
#include <DefaultLogger.h> #include <DefaultLogger.h>
#ifndef ASSIMP_BUILD_NO_EXPORT
# include <export.hpp>
#endif
#include <../code/AssimpPCH.h> /* to get stdint.h */ #include <../code/AssimpPCH.h> /* to get stdint.h */
#include <../code/fast_atof.h> #include <../code/fast_atof.h>
#include <../code/StringComparison.h> #include <../code/StringComparison.h>
@ -67,9 +71,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp; using namespace Assimp;
// Global assimp importer instance // Global assimp importer instance
extern Assimp::Importer* globalImporter; extern Assimp::Importer* globalImporter;
#ifndef ASSIMP_BUILD_NO_EXPORT
// Global assimp exporter instance
extern Assimp::Exporter* globalExporter;
#endif
// ------------------------------------------------------------------------------ // ------------------------------------------------------------------------------
/** Defines common import parameters */ /** Defines common import parameters */
struct ImportData struct ImportData
@ -113,11 +123,24 @@ int ProcessStandardArguments(ImportData& fill,
// ------------------------------------------------------------------------------ // ------------------------------------------------------------------------------
/** Import a specific model file /** Import a specific model file
* @param imp Import configuration to be used * @param imp Import configuration to be used
* @param path Path to the file to be opened */ * @param path Path to the file to be read */
const aiScene* ImportModel( const aiScene* ImportModel(
const ImportData& imp, const ImportData& imp,
const std::string& path); const std::string& path);
#ifndef ASSIMP_BUILD_NO_EXPORT
// ------------------------------------------------------------------------------
/** Export a specific model file
* @param imp Import configuration to be used
* @param path Path to the file to be written
* @param format Format id*/
bool ExportModel(const aiScene* pOut,
const ImportData& imp,
const std::string& path,
const char* pID);
#endif
// ------------------------------------------------------------------------------ // ------------------------------------------------------------------------------
/** assimp_dump utility /** assimp_dump utility
@ -128,6 +151,15 @@ int Assimp_Dump (
const char* const* params, const char* const* params,
unsigned int num); unsigned int num);
// ------------------------------------------------------------------------------
/** assimp_export utility
* @param params Command line parameters to 'assimp export'
* @param Number of params
* @return 0 for success*/
int Assimp_Export (
const char* const* params,
unsigned int num);
// ------------------------------------------------------------------------------ // ------------------------------------------------------------------------------
/** assimp_extract utility /** assimp_extract utility
* @param params Command line parameters to 'assimp extract' * @param params Command line parameters to 'assimp extract'