Main.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  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. "Major version: %i\n"
  45. "Minor version: %i\n"
  46. "SVN revision : %i\n"
  47. "Build flags : %s %s %s %s %s\n\n";
  48. const char* AICMD_MSG_HELP =
  49. "assimp <verb> <arguments>\n\n"
  50. "\tverbs:\n"
  51. "\t\tversion - Display Assimp version\n"
  52. "\t\tlistext - List all known file extension\n"
  53. "\t\tknowext - Check whether a file extension is recognized by Assimp\n"
  54. "\t\textract - Extract an embedded texture from a model\n"
  55. "\t\tdump - Convert a model to binary or XML dumps (ASSBIN/ASSXML)\n"
  56. "\n\n\tUse \'assimp <verb> --help\' to get detailed help for a command.\n"
  57. ;
  58. /*extern*/ Assimp::Importer* globalImporter = NULL;
  59. // ------------------------------------------------------------------------------
  60. // Application entry point
  61. int main (int argc, char* argv[])
  62. {
  63. if (argc <= 1) {
  64. printf("assimp: No command specified. Use \'assimp help\' for a detailed command list\n");
  65. return 0;
  66. }
  67. // assimp version
  68. // Display a version string
  69. if (! ::strcmp(argv[1], "version")) {
  70. const unsigned int flags = aiGetCompileFlags();
  71. printf(AICMD_MSG_ABOUT,
  72. aiGetVersionMajor(),
  73. aiGetVersionMinor(),
  74. aiGetVersionRevision(),
  75. (flags & ASSIMP_CFLAGS_DEBUG ? "-debug" : ""),
  76. (flags & ASSIMP_CFLAGS_NOBOOST ? "-noboost" : ""),
  77. (flags & ASSIMP_CFLAGS_SHARED ? "-shared" : ""),
  78. (flags & ASSIMP_CFLAGS_SINGLETHREADED ? "-st" : ""),
  79. (flags & ASSIMP_CFLAGS_STLPORT ? "-stlport" : ""));
  80. return 0;
  81. }
  82. // assimp help
  83. // Display some basic help
  84. if (! ::strcmp(argv[1], "help")) {
  85. printf(AICMD_MSG_HELP);
  86. return 0;
  87. }
  88. // construct a global Assimp::Importer instance
  89. Assimp::Importer imp;
  90. globalImporter = &imp;
  91. // assimp listext
  92. // List all file extensions supported by Assimp
  93. if (! ::strcmp(argv[1], "listext")) {
  94. aiString s;
  95. imp.GetExtensionList(s);
  96. printf(s.data);
  97. return 0;
  98. }
  99. // assimp knowext
  100. // Check whether a particular file extension is known by us, return 0 on success
  101. if (! ::strcmp(argv[1], "knowext")) {
  102. if (argc<3) {
  103. printf("Expected a file extension to check for!");
  104. return -10;
  105. }
  106. const bool b = imp.IsExtensionSupported(argv[2]);
  107. printf("File extension %s is %sknown",argv[2],(b?"":"not "));
  108. return b?0:-1;
  109. }
  110. // assimp dump
  111. // Dump a model to a file
  112. if (! ::strcmp(argv[1], "dump")) {
  113. return Assimp_Dump ((const char**)&argv[2],argc-2);
  114. }
  115. // assimp extract
  116. // Extract an embedded texture from a file
  117. if (! ::strcmp(argv[1], "extract")) {
  118. return Assimp_Extract ((const char**)&argv[2],argc-2);
  119. }
  120. ::printf("Unrecognized command. Use \'assimp help\' for a detailed command list\n");
  121. return 1;
  122. }
  123. // ------------------------------------------------------------------------------
  124. // Import a specific file
  125. const aiScene* ImportModel(const ImportData& imp, const std::string& path)
  126. {
  127. // Attach log streams
  128. if (imp.log) {
  129. ::printf("\nAttaching log stream ... OK\n");
  130. unsigned int flags = 0;
  131. if (imp.logFile.length())
  132. flags |= aiDefaultLogStream_FILE;
  133. if (imp.showLog)
  134. flags |= aiDefaultLogStream_STDERR;
  135. DefaultLogger::create(imp.logFile.c_str(),imp.verbose ? Logger::VERBOSE : Logger::NORMAL,flags);
  136. }
  137. ::printf("Launching model import ... OK\n");
  138. // Now validate this flag combination
  139. if(!globalImporter->ValidateFlags(imp.ppFlags)) {
  140. ::printf("ERROR: Unsupported post-processing flags \n");
  141. return NULL;
  142. }
  143. ::printf("Validating postprocessing flags ... OK\n");
  144. if (imp.showLog)
  145. ::printf("-----------------------------------------------------------------\n");
  146. // do the actual import, measure time
  147. const clock_t first = ::clock();
  148. const aiScene* scene = globalImporter->ReadFile(path,imp.ppFlags);
  149. if (imp.showLog)
  150. ::printf("-----------------------------------------------------------------\n");
  151. if (!scene) {
  152. printf("ERROR: Failed to load file\n");
  153. return NULL;
  154. }
  155. const clock_t second = ::clock();
  156. const float seconds = (float)(second-first) / CLOCKS_PER_SEC;
  157. ::printf("Importing file ... OK \n import took approx. %.5f seconds\n"
  158. "\n",seconds);
  159. if (imp.log) {
  160. DefaultLogger::kill();
  161. }
  162. return scene;
  163. }
  164. // ------------------------------------------------------------------------------
  165. // Process standard arguments
  166. int ProcessStandardArguments(ImportData& fill, const char** params,
  167. unsigned int num)
  168. {
  169. // -ptv --pretransform-vertices
  170. // -gsn --gen-smooth-normals
  171. // -gn --gen-normals
  172. // -cts --calc-tangent-space
  173. // -jiv --join-identical-vertices
  174. // -rrm --remove-redundant-materials
  175. // -fd --find-degenerates
  176. // -slm --split-large-meshes
  177. // -lbw --limit-bone-weights
  178. // -vds --validate-data-structure
  179. // -icl --improve-cache-locality
  180. // -sbpt --sort-by-ptype
  181. // -lh --convert-to-lh
  182. // -fuv --flip-uv
  183. // -fwo --flip-winding-order
  184. // -tuv --transform-uv-coords
  185. // -guv --gen-uvcoords
  186. // -fid --find-invalid-data
  187. // -fixn --fix normals
  188. // -tri --triangulate
  189. // -fi --find-instances
  190. // -fi --find-instances
  191. // -og --optimize-graph
  192. // -om --optimize-meshes
  193. //
  194. // -c<file> --config-file=<file>
  195. for (unsigned int i = 0; i < num;++i)
  196. {
  197. if (!params[i]) { // could happen if some args have already been processed
  198. continue;
  199. }
  200. bool has = true;
  201. if (! ::strcmp(params[i], "-ptv") || ! ::strcmp(params[i], "--pretransform-vertices")) {
  202. fill.ppFlags |= aiProcess_PreTransformVertices;
  203. }
  204. else if (! ::strcmp(params[i], "-gsn") || ! ::strcmp(params[i], "--gen-smooth-normals")) {
  205. fill.ppFlags |= aiProcess_GenSmoothNormals;
  206. }
  207. else if (! ::strcmp(params[i], "-gn") || ! ::strcmp(params[i], "--gen-normals")) {
  208. fill.ppFlags |= aiProcess_GenNormals;
  209. }
  210. else if (! ::strcmp(params[i], "-jiv") || ! ::strcmp(params[i], "--join-identical-vertices")) {
  211. fill.ppFlags |= aiProcess_JoinIdenticalVertices;
  212. }
  213. else if (! ::strcmp(params[i], "-rrm") || ! ::strcmp(params[i], "--remove-redundant-materials")) {
  214. fill.ppFlags |= aiProcess_RemoveRedundantMaterials;
  215. }
  216. else if (! ::strcmp(params[i], "-fd") || ! ::strcmp(params[i], "--find-degenerates")) {
  217. fill.ppFlags |= aiProcess_FindDegenerates;
  218. }
  219. else if (! ::strcmp(params[i], "-slm") || ! ::strcmp(params[i], "--split-large-meshes")) {
  220. fill.ppFlags |= aiProcess_SplitLargeMeshes;
  221. }
  222. else if (! ::strcmp(params[i], "-lbw") || ! ::strcmp(params[i], "--limit-bone-weights")) {
  223. fill.ppFlags |= aiProcess_LimitBoneWeights;
  224. }
  225. else if (! ::strcmp(params[i], "-vds") || ! ::strcmp(params[i], "--validate-data-structure")) {
  226. fill.ppFlags |= aiProcess_ValidateDataStructure;
  227. }
  228. else if (! ::strcmp(params[i], "-icl") || ! ::strcmp(params[i], "--improve-cache-locality")) {
  229. fill.ppFlags |= aiProcess_ImproveCacheLocality;
  230. }
  231. else if (! ::strcmp(params[i], "-sbpt") || ! ::strcmp(params[i], "--sort-by-ptype")) {
  232. fill.ppFlags |= aiProcess_SortByPType;
  233. }
  234. else if (! ::strcmp(params[i], "-lh") || ! ::strcmp(params[i], "--left-handed")) {
  235. fill.ppFlags |= aiProcess_ConvertToLeftHanded;
  236. }
  237. else if (! ::strcmp(params[i], "-fuv") || ! ::strcmp(params[i], "--flip-uv")) {
  238. fill.ppFlags |= aiProcess_FlipUVs;
  239. }
  240. else if (! ::strcmp(params[i], "-fwo") || ! ::strcmp(params[i], "--flip-winding-order")) {
  241. fill.ppFlags |= aiProcess_FlipWindingOrder;
  242. }
  243. else if (! ::strcmp(params[i], "-tuv") || ! ::strcmp(params[i], "--transform-uv-coords")) {
  244. fill.ppFlags |= aiProcess_TransformUVCoords;
  245. }
  246. else if (! ::strcmp(params[i], "-guv") || ! ::strcmp(params[i], "--gen-uvcoords")) {
  247. fill.ppFlags |= aiProcess_GenUVCoords;
  248. }
  249. else if (! ::strcmp(params[i], "-fid") || ! ::strcmp(params[i], "--find-invalid-data")) {
  250. fill.ppFlags |= aiProcess_FindInvalidData;
  251. }
  252. else if (! ::strcmp(params[i], "-fixn") || ! ::strcmp(params[i], "--fix-normals")) {
  253. fill.ppFlags |= aiProcess_FixInfacingNormals;
  254. }
  255. else if (! ::strcmp(params[i], "-tri") || ! ::strcmp(params[i], "--triangulate")) {
  256. fill.ppFlags |= aiProcess_Triangulate;
  257. }
  258. else if (! ::strcmp(params[i], "-cts") || ! ::strcmp(params[i], "--calc-tangent-space")) {
  259. fill.ppFlags |= aiProcess_CalcTangentSpace;
  260. }
  261. else if (! ::strcmp(params[i], "-fi") || ! ::strcmp(params[i], "--find-instances")) {
  262. fill.ppFlags |= aiProcess_FindInstances;
  263. }
  264. else if (! ::strcmp(params[i], "-og") || ! ::strcmp(params[i], "--optimize-graph")) {
  265. fill.ppFlags |= aiProcess_OptimizeGraph;
  266. }
  267. else if (! ::strcmp(params[i], "-om") || ! ::strcmp(params[i], "--optimize-meshes")) {
  268. fill.ppFlags |= aiProcess_OptimizeMeshes;
  269. }
  270. #if 0
  271. else if (! ::strcmp(params[i], "-oa") || ! ::strcmp(params[i], "--optimize-anims")) {
  272. fill.ppFlags |= aiProcess_OptimizeAnims;
  273. }
  274. else if (! ::strcmp(params[i], "-gem") || ! ::strcmp(params[i], "--gen-entity-meshes")) {
  275. fill.ppFlags |= aiProcess_GenEntityMeshes;
  276. }
  277. else if (! ::strcmp(params[i], "-ftp") || ! ::strcmp(params[i], "--fix-texture-paths")) {
  278. fill.ppFlags |= aiProcess_FixTexturePaths;
  279. }
  280. #endif
  281. else if (! ::strncmp(params[i], "-c",2) || ! ::strncmp(params[i], "--config=",9)) {
  282. const unsigned int ofs = (params[i][1] == '-' ? 9 : 2);
  283. // use default configurations
  284. if (! ::strncmp(params[i]+ofs,"full",4))
  285. fill.ppFlags |= aiProcessPreset_TargetRealtime_MaxQuality;
  286. else if (! ::strncmp(params[i]+ofs,"default",7))
  287. fill.ppFlags |= aiProcessPreset_TargetRealtime_Quality;
  288. else if (! ::strncmp(params[i]+ofs,"fast",4))
  289. fill.ppFlags |= aiProcessPreset_TargetRealtime_Fast;
  290. }
  291. else if (! ::strcmp(params[i], "-l") || ! ::strcmp(params[i], "--show-log")) {
  292. fill.showLog = true;
  293. }
  294. else if (! ::strcmp(params[i], "-v") || ! ::strcmp(params[i], "--verbose")) {
  295. fill.verbose = true;
  296. }
  297. else if (! ::strncmp(params[i], "--log-out=",10) || ! ::strncmp(params[i], "-lo",3)) {
  298. fill.logFile = std::string(params[i]+(params[i][1] == '-' ? 10 : 3));
  299. if (!fill.logFile.length())
  300. fill.logFile = "assimp-log.txt";
  301. }
  302. else has = false;
  303. if (has) {
  304. params[i] = NULL;
  305. }
  306. }
  307. if (fill.logFile.length() || fill.showLog || fill.verbose)
  308. fill.log = true;
  309. return 0;
  310. }