Main.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. /*
  2. ---------------------------------------------------------------------------
  3. Open Asset Import Library (ASSIMP)
  4. ---------------------------------------------------------------------------
  5. Copyright (c) 2006-2008, ASSIMP Development Team
  6. All rights reserved.
  7. Redistribution and use of this software in source and binary forms,
  8. with or without modification, are permitted provided that the following
  9. conditions are met:
  10. * Redistributions of source code must retain the above
  11. copyright notice, this list of conditions and the
  12. following disclaimer.
  13. * Redistributions in binary form must reproduce the above
  14. copyright notice, this list of conditions and the
  15. following disclaimer in the documentation and/or other
  16. materials provided with the distribution.
  17. * Neither the name of the ASSIMP team, nor the names of its
  18. contributors may be used to endorse or promote products
  19. derived from this software without specific prior
  20. written permission of the ASSIMP Development Team.
  21. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  22. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  23. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  24. A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  25. OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  26. SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  27. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  28. DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  29. THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  30. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  31. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32. ---------------------------------------------------------------------------
  33. */
  34. /** @file Main.cpp
  35. * @brief main() function of assimp_cmd
  36. */
  37. #include "Main.h"
  38. const char* AICMD_MSG_ABOUT =
  39. "------------------------------------------------------ \n"
  40. "Open Asset Import Library - Assimp \n"
  41. "http://assimp.sourceforge.net \n"
  42. "Command-line tools \n"
  43. "------------------------------------------------------ \n\n"
  44. "Version %i.%i-%s%s%s%s%s (SVNREV %i)\n\n";
  45. const char* AICMD_MSG_HELP =
  46. "assimp <verb> <arguments>\n\n"
  47. "\tverbs:\n"
  48. "\t\tinfo - Display statistics and structure of a 3D model\n"
  49. "\t\tversion - Display Assimp version\n"
  50. "\t\tlistext - List all known file extension\n"
  51. "\t\tknowext - Check whether a file extension is recognized by Assimp\n"
  52. "\t\textract - Extract an embedded texture from a model\n"
  53. "\t\tdump - Convert a model to binary or XML dumps (ASSBIN/ASSXML)\n"
  54. "\t\tcmpdump - Compare two file dumps produced with \'assimp dump <file> -s ...\'\n"
  55. "\n\n\tUse \'assimp <verb> --help\' to get detailed help for a command.\n"
  56. ;
  57. /*extern*/ Assimp::Importer* globalImporter = NULL;
  58. // ------------------------------------------------------------------------------
  59. // Application entry point
  60. int main (int argc, char* argv[])
  61. {
  62. if (argc <= 1) {
  63. printf("assimp: No command specified. Use \'assimp help\' for a detailed command list\n");
  64. return 0;
  65. }
  66. // assimp version
  67. // Display version information
  68. if (! strcmp(argv[1], "version")) {
  69. const unsigned int flags = aiGetCompileFlags();
  70. printf(AICMD_MSG_ABOUT,
  71. aiGetVersionMajor(),
  72. aiGetVersionMinor(),
  73. (flags & ASSIMP_CFLAGS_DEBUG ? "-debug " : ""),
  74. (flags & ASSIMP_CFLAGS_NOBOOST ? "-noboost " : ""),
  75. (flags & ASSIMP_CFLAGS_SHARED ? "-shared " : ""),
  76. (flags & ASSIMP_CFLAGS_SINGLETHREADED ? "-st " : ""),
  77. (flags & ASSIMP_CFLAGS_STLPORT ? "-stlport " : ""),
  78. aiGetVersionRevision());
  79. return 0;
  80. }
  81. // assimp help
  82. // Display some basic help (--help and -h work as well
  83. // because people could try them intuitively)
  84. if (!strcmp(argv[1], "help") || !strcmp(argv[1], "--help") || !strcmp(argv[1], "-h")) {
  85. printf("%s",AICMD_MSG_HELP);
  86. return 0;
  87. }
  88. // assimp cmpdump
  89. // Compare two mini model dumps (regression suite)
  90. if (! strcmp(argv[1], "cmpdump")) {
  91. return Assimp_CompareDump (&argv[2],argc-2);
  92. }
  93. // construct a global Assimp::Importer instance
  94. // because all further tools rely on it
  95. Assimp::Importer imp;
  96. globalImporter = &imp;
  97. // assimp listext
  98. // List all file extensions supported by Assimp
  99. if (! strcmp(argv[1], "listext")) {
  100. aiString s;
  101. imp.GetExtensionList(s);
  102. printf("%s",s.data);
  103. return 0;
  104. }
  105. // assimp knowext
  106. // Check whether a particular file extension is known by us, return 0 on success
  107. if (! strcmp(argv[1], "knowext")) {
  108. if (argc<3) {
  109. printf("Expected a file extension to check for!");
  110. return -10;
  111. }
  112. const bool b = imp.IsExtensionSupported(argv[2]);
  113. printf("File extension %s is %sknown",argv[2],(b?"":"not "));
  114. return b?0:-1;
  115. }
  116. // assimp info
  117. // Print basic model statistics
  118. if (! strcmp(argv[1], "info")) {
  119. return Assimp_Info ((const char**)&argv[2],argc-2);
  120. }
  121. // assimp dump
  122. // Dump a model to a file
  123. if (! strcmp(argv[1], "dump")) {
  124. return Assimp_Dump (&argv[2],argc-2);
  125. }
  126. // assimp extract
  127. // Extract an embedded texture from a file
  128. if (! strcmp(argv[1], "extract")) {
  129. return Assimp_Extract (&argv[2],argc-2);
  130. }
  131. printf("Unrecognized command. Use \'assimp help\' for a detailed command list\n");
  132. return 1;
  133. }
  134. // ------------------------------------------------------------------------------
  135. // Import a specific file
  136. const aiScene* ImportModel(
  137. const ImportData& imp,
  138. const std::string& path)
  139. {
  140. // Attach log streams
  141. if (imp.log) {
  142. printf("\nAttaching log stream ... OK\n");
  143. unsigned int flags = 0;
  144. if (imp.logFile.length()) {
  145. flags |= aiDefaultLogStream_FILE;
  146. }
  147. if (imp.showLog) {
  148. flags |= aiDefaultLogStream_STDERR;
  149. }
  150. DefaultLogger::create(imp.logFile.c_str(),imp.verbose ? Logger::VERBOSE : Logger::NORMAL,flags);
  151. }
  152. printf("Launching model import ... OK\n");
  153. // Now validate this flag combination
  154. if(!globalImporter->ValidateFlags(imp.ppFlags)) {
  155. printf("ERROR: Unsupported post-processing flags \n");
  156. return NULL;
  157. }
  158. printf("Validating postprocessing flags ... OK\n");
  159. if (imp.showLog)
  160. printf("-----------------------------------------------------------------\n");
  161. // do the actual import, measure time
  162. const clock_t first = clock();
  163. const aiScene* scene = globalImporter->ReadFile(path,imp.ppFlags);
  164. if (imp.showLog) {
  165. printf("-----------------------------------------------------------------\n");
  166. }
  167. if (!scene) {
  168. printf("ERROR: Failed to load file\n");
  169. return NULL;
  170. }
  171. const clock_t second = ::clock();
  172. const float seconds = (float)(second-first) / CLOCKS_PER_SEC;
  173. printf("Importing file ... OK \n import took approx. %.5f seconds\n"
  174. "\n",seconds);
  175. if (imp.log) {
  176. DefaultLogger::kill();
  177. }
  178. return scene;
  179. }
  180. // ------------------------------------------------------------------------------
  181. // Process standard arguments
  182. int ProcessStandardArguments(
  183. ImportData& fill,
  184. const char* const * params,
  185. unsigned int num)
  186. {
  187. // -ptv --pretransform-vertices
  188. // -gsn --gen-smooth-normals
  189. // -gn --gen-normals
  190. // -cts --calc-tangent-space
  191. // -jiv --join-identical-vertices
  192. // -rrm --remove-redundant-materials
  193. // -fd --find-degenerates
  194. // -slm --split-large-meshes
  195. // -lbw --limit-bone-weights
  196. // -vds --validate-data-structure
  197. // -icl --improve-cache-locality
  198. // -sbpt --sort-by-ptype
  199. // -lh --convert-to-lh
  200. // -fuv --flip-uv
  201. // -fwo --flip-winding-order
  202. // -tuv --transform-uv-coords
  203. // -guv --gen-uvcoords
  204. // -fid --find-invalid-data
  205. // -fixn --fix normals
  206. // -tri --triangulate
  207. // -fi --find-instances
  208. // -fi --find-instances
  209. // -og --optimize-graph
  210. // -om --optimize-meshes
  211. //
  212. // -c<file> --config-file=<file>
  213. for (unsigned int i = 0; i < num;++i)
  214. {
  215. //if (!params[i]) { // could happen if some args have already been processed
  216. // continue;
  217. //}
  218. // bool has = true;
  219. if (! strcmp(params[i], "-ptv") || ! strcmp(params[i], "--pretransform-vertices")) {
  220. fill.ppFlags |= aiProcess_PreTransformVertices;
  221. }
  222. else if (! strcmp(params[i], "-gsn") || ! strcmp(params[i], "--gen-smooth-normals")) {
  223. fill.ppFlags |= aiProcess_GenSmoothNormals;
  224. }
  225. else if (! strcmp(params[i], "-gn") || ! strcmp(params[i], "--gen-normals")) {
  226. fill.ppFlags |= aiProcess_GenNormals;
  227. }
  228. else if (! strcmp(params[i], "-jiv") || ! strcmp(params[i], "--join-identical-vertices")) {
  229. fill.ppFlags |= aiProcess_JoinIdenticalVertices;
  230. }
  231. else if (! strcmp(params[i], "-rrm") || ! strcmp(params[i], "--remove-redundant-materials")) {
  232. fill.ppFlags |= aiProcess_RemoveRedundantMaterials;
  233. }
  234. else if (! strcmp(params[i], "-fd") || ! strcmp(params[i], "--find-degenerates")) {
  235. fill.ppFlags |= aiProcess_FindDegenerates;
  236. }
  237. else if (! strcmp(params[i], "-slm") || ! strcmp(params[i], "--split-large-meshes")) {
  238. fill.ppFlags |= aiProcess_SplitLargeMeshes;
  239. }
  240. else if (! strcmp(params[i], "-lbw") || ! strcmp(params[i], "--limit-bone-weights")) {
  241. fill.ppFlags |= aiProcess_LimitBoneWeights;
  242. }
  243. else if (! strcmp(params[i], "-vds") || ! strcmp(params[i], "--validate-data-structure")) {
  244. fill.ppFlags |= aiProcess_ValidateDataStructure;
  245. }
  246. else if (! strcmp(params[i], "-icl") || ! strcmp(params[i], "--improve-cache-locality")) {
  247. fill.ppFlags |= aiProcess_ImproveCacheLocality;
  248. }
  249. else if (! strcmp(params[i], "-sbpt") || ! strcmp(params[i], "--sort-by-ptype")) {
  250. fill.ppFlags |= aiProcess_SortByPType;
  251. }
  252. else if (! strcmp(params[i], "-lh") || ! strcmp(params[i], "--left-handed")) {
  253. fill.ppFlags |= aiProcess_ConvertToLeftHanded;
  254. }
  255. else if (! strcmp(params[i], "-fuv") || ! strcmp(params[i], "--flip-uv")) {
  256. fill.ppFlags |= aiProcess_FlipUVs;
  257. }
  258. else if (! strcmp(params[i], "-fwo") || ! strcmp(params[i], "--flip-winding-order")) {
  259. fill.ppFlags |= aiProcess_FlipWindingOrder;
  260. }
  261. else if (! strcmp(params[i], "-tuv") || ! strcmp(params[i], "--transform-uv-coords")) {
  262. fill.ppFlags |= aiProcess_TransformUVCoords;
  263. }
  264. else if (! strcmp(params[i], "-guv") || ! strcmp(params[i], "--gen-uvcoords")) {
  265. fill.ppFlags |= aiProcess_GenUVCoords;
  266. }
  267. else if (! strcmp(params[i], "-fid") || ! strcmp(params[i], "--find-invalid-data")) {
  268. fill.ppFlags |= aiProcess_FindInvalidData;
  269. }
  270. else if (! strcmp(params[i], "-fixn") || ! strcmp(params[i], "--fix-normals")) {
  271. fill.ppFlags |= aiProcess_FixInfacingNormals;
  272. }
  273. else if (! strcmp(params[i], "-tri") || ! strcmp(params[i], "--triangulate")) {
  274. fill.ppFlags |= aiProcess_Triangulate;
  275. }
  276. else if (! strcmp(params[i], "-cts") || ! strcmp(params[i], "--calc-tangent-space")) {
  277. fill.ppFlags |= aiProcess_CalcTangentSpace;
  278. }
  279. else if (! strcmp(params[i], "-fi") || ! strcmp(params[i], "--find-instances")) {
  280. fill.ppFlags |= aiProcess_FindInstances;
  281. }
  282. else if (! strcmp(params[i], "-og") || ! strcmp(params[i], "--optimize-graph")) {
  283. fill.ppFlags |= aiProcess_OptimizeGraph;
  284. }
  285. else if (! strcmp(params[i], "-om") || ! strcmp(params[i], "--optimize-meshes")) {
  286. fill.ppFlags |= aiProcess_OptimizeMeshes;
  287. }
  288. #if 0
  289. else if (! strcmp(params[i], "-oa") || ! strcmp(params[i], "--optimize-anims")) {
  290. fill.ppFlags |= aiProcess_OptimizeAnims;
  291. }
  292. else if (! strcmp(params[i], "-gem") || ! strcmp(params[i], "--gen-entity-meshes")) {
  293. fill.ppFlags |= aiProcess_GenEntityMeshes;
  294. }
  295. else if (! strcmp(params[i], "-ftp") || ! strcmp(params[i], "--fix-texture-paths")) {
  296. fill.ppFlags |= aiProcess_FixTexturePaths;
  297. }
  298. #endif
  299. else if (! strncmp(params[i], "-c",2) || ! strncmp(params[i], "--config=",9)) {
  300. const unsigned int ofs = (params[i][1] == '-' ? 9 : 2);
  301. // use default configurations
  302. if (! strncmp(params[i]+ofs,"full",4))
  303. fill.ppFlags |= aiProcessPreset_TargetRealtime_MaxQuality;
  304. else if (! strncmp(params[i]+ofs,"default",7))
  305. fill.ppFlags |= aiProcessPreset_TargetRealtime_Quality;
  306. else if (! strncmp(params[i]+ofs,"fast",4))
  307. fill.ppFlags |= aiProcessPreset_TargetRealtime_Fast;
  308. }
  309. else if (! strcmp(params[i], "-l") || ! strcmp(params[i], "--show-log")) {
  310. fill.showLog = true;
  311. }
  312. else if (! strcmp(params[i], "-v") || ! strcmp(params[i], "--verbose")) {
  313. fill.verbose = true;
  314. }
  315. else if (! strncmp(params[i], "--log-out=",10) || ! strncmp(params[i], "-lo",3)) {
  316. fill.logFile = std::string(params[i]+(params[i][1] == '-' ? 10 : 3));
  317. if (!fill.logFile.length())
  318. fill.logFile = "assimp-log.txt";
  319. }
  320. //else has = false;
  321. //if (has) {
  322. // params[i] = NULL;
  323. //}
  324. }
  325. if (fill.logFile.length() || fill.showLog || fill.verbose)
  326. fill.log = true;
  327. return 0;
  328. }