2
0
Эх сурвалжийг харах

+ Implement export utility into assimp_cmd.

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@929 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
aramis_acg 14 жил өмнө
parent
commit
eb4afe8f91

+ 168 - 0
tools/assimp_cmd/Export.cpp

@@ -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
+ 

+ 161 - 32
tools/assimp_cmd/Main.cpp

@@ -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"
-"http://assimp.sourceforge.net \n"
-"Command-line tools \n"
+"Open Asset Import Library (\"Assimp\", http://assimp.sourceforge.net) \n"
+" -- Commandline toolchain --\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"
-"\tverbs:\n"
-"\t\tinfo    - Display statistics and structure of a 3D model\n"
-"\t\tversion - Display Assimp version\n"
-"\t\tlistext - List all known file extension\n"
-"\t\tknowext - Check whether a file extension is recognized by Assimp\n"
-"\t\textract - Extract an embedded texture from a model\n"
-"\t\tdump    - Convert a model to binary or XML dumps (ASSBIN/ASSXML)\n"
-"\t\tcmpdump - Compare two file dumps produced with \'assimp dump <file> -s ...\'\n"
-"\n\n\tUse \'assimp <verb> --help\' to get detailed help for a command.\n"
+"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"
+" \tknowexport - Check whether a particular export format is supported\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
-	// because all further tools rely on it
+	// construct global importer and exporter instances
 	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");
-		
-		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);
+		SetLogStreams(imp);
 	}
 	}
-	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) 
-		printf("-----------------------------------------------------------------\n");
+	if (imp.showLog) {
+		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(

+ 33 - 1
tools/assimp_cmd/Main.h

@@ -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'