diff --git a/code/BoostWorkaround/boost/timer.hpp b/code/BoostWorkaround/boost/timer.hpp new file mode 100644 index 000000000..0fc826620 --- /dev/null +++ b/code/BoostWorkaround/boost/timer.hpp @@ -0,0 +1,72 @@ +// boost timer.hpp header file ---------------------------------------------// + +// Copyright Beman Dawes 1994-99. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/timer for documentation. + +// Revision History +// 01 Apr 01 Modified to use new header. (JMaddock) +// 12 Jan 01 Change to inline implementation to allow use without library +// builds. See docs for more rationale. (Beman Dawes) +// 25 Sep 99 elapsed_max() and elapsed_min() added (John Maddock) +// 16 Jul 99 Second beta +// 6 Jul 99 Initial boost version + +#ifndef BOOST_TIMER_HPP +#define BOOST_TIMER_HPP + +//#include +#include +//#include + +# ifdef BOOST_NO_STDC_NAMESPACE + namespace std { using ::clock_t; using ::clock; } +# endif + + +namespace boost { + +// timer -------------------------------------------------------------------// + +// A timer object measures elapsed time. + +// It is recommended that implementations measure wall clock rather than CPU +// time since the intended use is performance measurement on systems where +// total elapsed time is more important than just process or CPU time. + +// Warnings: The maximum measurable elapsed time may well be only 596.5+ hours +// due to implementation limitations. The accuracy of timings depends on the +// accuracy of timing information provided by the underlying platform, and +// this varies a great deal from platform to platform. + +class timer +{ + public: + timer() { _start_time = std::clock(); } // postcondition: elapsed()==0 +// timer( const timer& src ); // post: elapsed()==src.elapsed() +// ~timer(){} +// timer& operator=( const timer& src ); // post: elapsed()==src.elapsed() + void restart() { _start_time = std::clock(); } // post: elapsed()==0 + double elapsed() const // return elapsed time in seconds + { return double(std::clock() - _start_time) / CLOCKS_PER_SEC; } + + double elapsed_max() const // return estimated maximum value for elapsed() + // Portability warning: elapsed_max() may return too high a value on systems + // where std::clock_t overflows or resets at surprising values. + { + return (double((std::numeric_limits::max)()) + - double(_start_time)) / double(CLOCKS_PER_SEC); + } + + double elapsed_min() const // return minimum value for elapsed() + { return double(1)/double(CLOCKS_PER_SEC); } + + private: + std::clock_t _start_time; +}; // timer + +} // namespace boost + +#endif // BOOST_TIMER_HPP \ No newline at end of file diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index 3d1c1c684..b6b3d8245 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -141,6 +141,7 @@ SOURCE_GROUP( Common FILES Vertex.h LineSplitter.h TinyFormatter.h + Profiler.h ) SOURCE_GROUP( 3DS FILES @@ -720,6 +721,7 @@ ADD_LIBRARY( assimp SHARED BlenderIntermediate.h BlenderModifier.h BlenderModifier.cpp + Profiler.h # Necessary to show the headers in the project when using the VC++ generator: BoostWorkaround/boost/math/common_factor_rt.hpp diff --git a/code/Importer.cpp b/code/Importer.cpp index 7b0bb7203..2ea3fefd8 100644 --- a/code/Importer.cpp +++ b/code/Importer.cpp @@ -67,6 +67,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "ProcessHelper.h" #include "ScenePreprocessor.h" #include "MemoryIOWrapper.h" +#include "Profiler.h" + +using namespace Assimp::Profiling; // ------------------------------------------------------------------------------------------------ // Importers @@ -837,20 +840,25 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags) { // Check whether this Importer instance has already loaded // a scene. In this case we need to delete the old one - if (pimpl->mScene) - { - DefaultLogger::get()->debug("Deleting previous scene"); + if (pimpl->mScene) { + + DefaultLogger::get()->debug("(Deleting previous scene)"); FreeScene(); } // First check if the file is accessable at all - if( !pimpl->mIOHandler->Exists( pFile)) - { + if( !pimpl->mIOHandler->Exists( pFile)) { + pimpl->mErrorString = "Unable to open file \"" + pFile + "\"."; DefaultLogger::get()->error(pimpl->mErrorString); return NULL; } + boost::scoped_ptr profiler(GetPropertyInteger(AI_CONFIG_GLOB_MEASURE_TIME,0)?new Profiler():NULL); + if (profiler) { + profiler->BeginRegion("total"); + } + // Find an worker class which can handle the file BaseImporter* imp = NULL; for( unsigned int a = 0; a < pimpl->mImporter.size(); a++) { @@ -861,10 +869,9 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags) } } - if (!imp) - { + if (!imp) { // not so bad yet ... try format auto detection. - std::string::size_type s = pFile.find_last_of('.'); + const std::string::size_type s = pFile.find_last_of('.'); if (s != std::string::npos) { DefaultLogger::get()->info("File extension now known, trying signature-based detection"); for( unsigned int a = 0; a < pimpl->mImporter.size(); a++) { @@ -885,9 +892,18 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags) // Dispatch the reading to the worker class for this format DefaultLogger::get()->info("Found a matching importer for this file format"); + + if (profiler) { + profiler->BeginRegion("import"); + } + imp->SetupProperties( this ); pimpl->mScene = imp->ReadFile( pFile, pimpl->mIOHandler); + if (profiler) { + profiler->EndRegion("import"); + } + // If successful, apply all active post processing steps to the imported data if( pimpl->mScene) { @@ -904,9 +920,17 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags) #endif // no validation // Preprocess the scene and prepare it for post-processing + if (profiler) { + profiler->BeginRegion("preprocess"); + } + ScenePreprocessor pre(pimpl->mScene); pre.ProcessScene(); + if (profiler) { + profiler->EndRegion("preprocess"); + } + // Ensure that the validation process won't be called twice ApplyPostProcessing(pFlags & (~aiProcess_ValidateDataStructure)); } @@ -917,6 +941,10 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags) // clear any data allocated by post-process steps pimpl->mPPShared->Clean(); + + if (profiler) { + profiler->EndRegion("total"); + } } #ifdef ASSIMP_CATCH_GLOBAL_EXCEPTIONS catch (std::exception &e) @@ -979,16 +1007,27 @@ const aiScene* Importer::ApplyPostProcessing(unsigned int pFlags) pFlags |= aiProcess_ValidateDataStructure; } #else - if (pimpl->bExtraVerbose) + if (pimpl->bExtraVerbose) { DefaultLogger::get()->warn("Not a debug build, ignoring extra verbose setting"); + } #endif // ! DEBUG + + boost::scoped_ptr profiler(GetPropertyInteger(AI_CONFIG_GLOB_MEASURE_TIME,0)?new Profiler():NULL); for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) { BaseProcess* process = pimpl->mPostProcessingSteps[a]; if( process->IsActive( pFlags)) { + if (profiler) { + profiler->BeginRegion("postprocess"); + } + process->SetupProperties( this ); process->ExecuteOnScene ( this ); + + if (profiler) { + profiler->EndRegion("postprocess"); + } } if( !pimpl->mScene) { break; diff --git a/code/Profiler.h b/code/Profiler.h new file mode 100644 index 000000000..68f7a14df --- /dev/null +++ b/code/Profiler.h @@ -0,0 +1,97 @@ +/* +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 Profiler.h + * @brief Utility to measure the respective runtime of each import step + */ +#ifndef INCLUDED_PROFILER_H +#define INCLUDED_PROFILER_H + +#include "boost/timer.hpp" + +#include "../include/DefaultLogger.h" +#include "TinyFormatter.h" + +namespace Assimp { + namespace Profiling { + + using namespace Formatter; + + +// ------------------------------------------------------------------------------------------------ +/** Simple wrapper around boost::timer to simplify reporting. Timings are automatically + * dumped to the log file. + */ +class Profiler +{ + +public: + + Profiler() {} + +public: + + /** Start a named timer */ + void BeginRegion(const std::string& region) { + regions[region] = boost::timer(); + DefaultLogger::get()->debug((format("START `"),region,"`")); + } + + + /** End a specific named timer and write its end time to the log */ + void EndRegion(const std::string& region) { + RegionMap::const_iterator it = regions.find(region); + if (it == regions.end()) { + return; + } + + DefaultLogger::get()->debug((format("END `"),region,"`, dt= ",(*it).second.elapsed()," s")); + } + +private: + + typedef std::map RegionMap; + RegionMap regions; +}; + + } +} + +#endif diff --git a/doc/AssimpDoc_Html/AssimpDoc.chm b/doc/AssimpDoc_Html/AssimpDoc.chm index ca3932310..b36e076d8 100644 Binary files a/doc/AssimpDoc_Html/AssimpDoc.chm and b/doc/AssimpDoc_Html/AssimpDoc.chm differ diff --git a/doc/dox.h b/doc/dox.h index de1f9d6ca..9e1c29b6b 100644 --- a/doc/dox.h +++ b/doc/dox.h @@ -461,23 +461,6 @@ surely enough for almost any purpose. The process is simple:
  • .. and pass it as last parameter to #aiImportFileEx -@section threadsafety Thread-safety and internal multi-threading - -The ASSIMP library can be accessed by multiple threads simultaneously, as long as the -following prerequisites are fulfilled: -
      -
    • When using the C++-API make sure you create a new Importer instance for each thread. - Constructing instances of Importer is expensive, so it might be a good idea to - let every thread maintain its own thread-local instance (use it to - load as many models as you want).
    • -
    • The C-API is threadsafe as long as AI_C_THREADSAFE is defined. That's the default.
    • -
    • When supplying custom IO logic, make sure your underyling implementation is thead-safe.
    • -
    • Custom log streams or logger replacements have to be thread-safe, too.
    • -
    - -See the @ref assimp_st section @endlink to learn how to build a lightweight variant -of ASSIMP which is not thread-safe and does not utilize multiple threads for loading. - @section logging Logging The ASSIMP library provides an easy mechanism to log messages. For instance if you want to check the state of your @@ -1264,7 +1247,7 @@ mat->Get(AI_MATKEY_COLOR_DIFFUSE,color); @endcode Note: Get() is actually a template with explicit specializations for aiColor3D, aiColor4D, aiString, float, int and some others. -Make sure that the type of the second parameter is matching the expected data type of the material property (no compile-time check yet!). +Make sure that the type of the second parameter matches the expected data type of the material property (no compile-time check yet!). Don't follow this advice if you wish to encounter very strange results. @section C C-API @@ -1466,16 +1449,139 @@ Build: alles von CustomBuild + DirectX + MFC? */ +/** +@page perf Performance + +@section perf_overview Overview + +This page discusses Assimps general performance and some ways to finetune and profile it. You will see that an +intelligent choice of postprocessing steps is essential for quick loading. + +@section perf_profile Profiling + +Assimp has builtin support for basic profiling and reporting. To turn it on, set the GLOB_MEASURE_TIME +configuration switch to true (nonzero). Results are dumped to the logfile, so you need to setup +an appropriate logger implementation with at least one output stream first. See the @link logging Logging Page @endlink +for the details. + +A sample report looks like this (some unrelated log messages omitted, grouped entries for clarity): + +@verbatim +Debug, T5488: START `total` +Info, T5488: Found a matching importer for this file format + +Debug, T5488: START `import` +Info, T5488: BlendModifier: Applied the `Subdivision` modifier to `OBMonkey` +Debug, T5488: END `import`, dt= 3.516 s + + +Debug, T5488: START `preprocess` +Debug, T5488: END `preprocess`, dt= 0.001 s +Info, T5488: Entering post processing pipeline + +Debug, T5488: START `postprocess` +Debug, T5488: RemoveRedundantMatsProcess begin +Debug, T5488: RemoveRedundantMatsProcess finished +Debug, T5488: END `postprocess`, dt= 0.001 s + +Debug, T5488: START `postprocess` +Debug, T5488: TriangulateProcess begin +Info, T5488: TriangulateProcess finished. All polygons have been triangulated. +Debug, T5488: END `postprocess`, dt= 3.415 s + +Debug, T5488: START `postprocess` +Debug, T5488: SortByPTypeProcess begin +Info, T5488: Points: 0, Lines: 0, Triangles: 1, Polygons: 0 (Meshes, X = removed) +Debug, T5488: SortByPTypeProcess finished +Debug, T5488: START `postprocess` +Debug, T5488: JoinVerticesProcess begin +Debug, T5488: Mesh 0 (unnamed) | Verts in: 503808 out: 126345 | ~74.922 +Info, T5488: JoinVerticesProcess finished | Verts in: 503808 out: 126345 | ~74.9 +Debug, T5488: END `postprocess`, dt= 2.052 s +Debug, T5488: START `postprocess` +Debug, T5488: FlipWindingOrderProcess begin +Debug, T5488: FlipWindingOrderProcess finished +Debug, T5488: END `postprocess`, dt= 0.006 s + +Debug, T5488: START `postprocess` +Debug, T5488: LimitBoneWeightsProcess begin +Debug, T5488: LimitBoneWeightsProcess end +Debug, T5488: END `postprocess`, dt= 0.001 s + +Debug, T5488: START `postprocess` +Debug, T5488: ImproveCacheLocalityProcess begin +Debug, T5488: Mesh 0 | ACMR in: 0.851622 out: 0.718139 | ~15.7 +Info, T5488: Cache relevant are 1 meshes (251904 faces). Average output ACMR is 0.718139 +Debug, T5488: ImproveCacheLocalityProcess finished. +Debug, T5488: END `postprocess`, dt= 1.903 s + +Info, T5488: Leaving post processing pipeline +Debug, T5488: END `total`, dt= 11.269 s +@endverbatim + +So, only one fourth of the total import time was used for the actual model import, while the rest of the +time was consumed by the #aiProcess_Triangulate, #aiProcess_JoinIdenticalVertices and #aiProcess_ImproveCacheLocality +postprocessing steps. It is therefore not a good idea to specify *all* postprocessing flags just because they +sound so nice. +*/ + +/** +@page threading Threading + +@section overview Overview + +This page discusses both Assimps scalability in threaded environments, the precautions to be taken in order to +use it from multiple threads concurrently and finally its own ability to parallelize certain tasks internally. + +@section threadsafety Thread-safety / Using Assimp concurrently from several threads + +The library can be accessed by multiple threads simultaneously, as long as the +following prerequisites are fulfilled: +
      +
    • When using the C++-API make sure you create a new Importer instance for each thread. + Constructing instances of Importer is expensive, so it might be a good idea to + let every thread maintain its own thread-local instance (use it to + load as many models as you want).
    • +
    • The C-API is threadsafe as long as AI_C_THREADSAFE is defined. That's the default.
    • +
    • When supplying custom IO logic, make sure your underyling implementation is thead-safe.
    • +
    • Custom log streams or logger replacements have to be thread-safe, too.
    • +
    + + + +Multiple concurrent imports may or may not be beneficial, however. For certain file formats in conjunction with +little postprocessing IO times tend to be the performance bottleneck, using multiple threads does therefore not +help. Intense postprocessing (especially the O(nlogn) steps #aiProcess_JoinIdenticalVertices, +#aiProcess_GenSmoothNormals and #aiProcess_CalcTangentSpace) together with file formats like X or Collada, +which are slow to parse, might scale well with multiple concurrent imports. + + +@section automt Internal threading + +Automatic multi-threading is not currently implemented. +*/ /** @page importer_notes Importer Notes +@section blender Blender +@subsection bl_overview Overview + +Assimp provides a self-contained reimplementation of Blender's so called SDNA system (http://www.blender.org/development/architecture/notes-on-sdna/). +SDNA allows Blender to be fully backward AND forward compatible and to exchange +files created on any of the various platforms blender runs on with any other. Quick processing is another design goal - +BLEND is a fully-fledged binary monster and Assimp tries to read the most of it. Naturally, if Blender is the only modelling tool +in your asset work flow, consider writing a custom exporter from Blender if Assimp's format coverage does not meet your requirements. + +@subsection bl_status Current status + +@subsection bl_notes Notes + + + @section ogre Ogre - @subsection overview Overview -Ogre importer is currently optimized for the Blender Ogre exporter, because thats the only one that i use. - -You can find the Blender Ogre exporter at: http://www.ogre3d.org/forums/viewtopic.php?f=8&t=45922 +Ogre importer is currently optimized for the Blender Ogre exporter, because thats the only one that i use. You can find the Blender Ogre exporter at: http://www.ogre3d.org/forums/viewtopic.php?f=8&t=45922 @subsection what What will be loaded? diff --git a/include/aiConfig.h b/include/aiConfig.h index 1db4a34d7..b10682577 100644 --- a/include/aiConfig.h +++ b/include/aiConfig.h @@ -59,6 +59,44 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define INCLUDED_AI_CONFIG_H +// ########################################################################### +// LIBRARY SETTINGS +// General, global settings +// ########################################################################### + +// --------------------------------------------------------------------------- +/** @brief Enables time measurements. + * + * If enabled, measures the time needed for each part of the loading + * process (i.e. IO time, importing, postprocessing, ..) and dumps + * these timings to the DefaultLogger. See the @link perf Performance + * Page@endlink for more information on this topic. + * + * Property type: bool. Default value: false. + */ +#define AI_CONFIG_GLOB_MEASURE_TIME \ + "GLOB_MEASURE_TIME" + +# if 0 // not implemented yet +// --------------------------------------------------------------------------- +/** @brief Set Assimp's multithreading policy. + * + * This setting is ignored if Assimp was built without boost.thread + * support (ASSIMP_BUILD_NO_THREADING, which is implied by ASSIMP_BUILD_BOOST_WORKAROUND). + * Possible values are: -1 to let Assimp decide what to do, 0 to disable + * multithreading entirely and any number larger than 0 to force a specific + * number of threads. Assimp is always free to ignore this settings, which is + * merely a hint. Usually, the default value (-1) will be fine. However, if + * Assimp is used concurrently from multiple user threads, it might be useful + * to limit each Importer instance to a specific number of cores. + * + * For more information, see the @link threading Threading page@endlink. + * Property type: int, default value: -1. + */ +#define AI_CONFIG_GLOB_MULTITHREADING \ + "GLOB_MULTITHREADING" +#endif + // ########################################################################### // POST PROCESSING SETTINGS // Various stuff to fine-tune the behavior of a specific post processing step. @@ -136,7 +174,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * important additional information which you intend to parse. * For rendering, you can still render all meshes in the scene without * any transformations. - * Property type: integer (0: false; !0: true). Default value: false. + * Property type: bool. Default value: false. */ #define AI_CONFIG_PP_PTV_KEEP_HIERARCHY \ "PP_PTV_KEEP_HIERARCHY" @@ -159,7 +197,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * degenerated lines to points. See the documentation to the * #aiProcess_FindDegenerates step for a detailed example of the various ways * to get rid of these lines and points if you don't want them. - * Property type: integer (0: false; !0: true). Default value: false. + * Property type: bool. Default value: false. */ #define AI_CONFIG_PP_FD_REMOVE \ "PP_FD_REMOVE" @@ -402,7 +440,7 @@ enum aiComponent // ########################################################################### // IMPORTER SETTINGS -// Various stuff to fine-tune the behaviour of a specific importer plugin. +// Various stuff to fine-tune the behaviour of specific importer plugins. // ########################################################################### @@ -433,7 +471,7 @@ enum aiComponent /** @brief Configures the AC loader to collect all surfaces which have the * "Backface cull" flag set in separate meshes. * - * Property type: integer (0: false; !0: true). Default value: true. + * Property type: bool. Default value: true. */ #define AI_CONFIG_IMPORT_AC_SEPARATE_BFCULL \ "IMPORT_AC_SEPARATE_BFCULL" @@ -444,7 +482,7 @@ enum aiComponent * default, Assimp performs the subdivision using the standard * Catmull-Clark algorithm * - * Property type: integer (0: false; !0: true). Default value: true. + * * Property type: bool. Default value: true. */ #define AI_CONFIG_IMPORT_AC_EVAL_SUBDIVISION \ "IMPORT_AC_EVAL_SUBDIVISION" @@ -453,7 +491,7 @@ enum aiComponent /** @brief Configures the UNREAL 3D loader to separate faces with different * surface flags (e.g. two-sided vs. single-sided). * - * Property type: integer (0: false; !0: true). Default value: true. + * * Property type: bool. Default value: true. */ #define AI_CONFIG_IMPORT_UNREAL_HANDLE_FLAGS \ "UNREAL_HANDLE_FLAGS" @@ -466,7 +504,7 @@ enum aiComponent * want to compute them on your own, if you need them. This option is intended * for model viewers which want to offer an easy way to apply textures to * terrains. - * Property type: integer (0: false; !0: true). Default value: false. + * * Property type: bool. Default value: false. */ #define AI_CONFIG_IMPORT_TER_MAKE_UVS \ "IMPORT_TER_MAKE_UVS" @@ -475,19 +513,20 @@ enum aiComponent /** @brief Configures the ASE loader to always reconstruct normal vectors * basing on the smoothing groups loaded from the file. * - * Many ASE files have invalid normals (they're not orthonormal). - * Property type: integer (0: false; !0: true). Default value: true. + * Some ASE files have carry invalid normals, other don't. + * * Property type: bool. Default value: true. */ #define AI_CONFIG_IMPORT_ASE_RECONSTRUCT_NORMALS \ "IMPORT_ASE_RECONSTRUCT_NORMALS" // --------------------------------------------------------------------------- -/** @brief Configures the M3D loader to process multi-part player models. +/** @brief Configures the M3D loader to detect and process multi-part + * Quake player models. * * These models usually consist of 3 files, lower.md3, upper.md3 and * head.md3. If this property is set to true, Assimp will try to load and * combine all three files if one of them is loaded. - * Property type: integer (0: false; !0: true). Default value: true. + * Property type: bool. Default value: true. */ #define AI_CONFIG_IMPORT_MD3_HANDLE_MULTIPART \ "IMPORT_MD3_HANDLE_MULTIPART" @@ -545,7 +584,7 @@ enum aiComponent * and combined with the MD5MESH file. This configuration option can be * used to disable this behaviour. * - * Property type: integer (0: false; !0: true). Default value: false. + * * Property type: bool. Default value: false. */ #define AI_CONFIG_IMPORT_MD5_NO_ANIM_AUTOLOAD \ "IMPORT_MD5_NO_ANIM_AUTOLOAD" diff --git a/test/models/BLEND/MirroredCube_252.blend b/test/models/BLEND/MirroredCube_252.blend new file mode 100644 index 000000000..d433e3eb7 Binary files /dev/null and b/test/models/BLEND/MirroredCube_252.blend differ diff --git a/tools/assimp_view/assimp_view.cpp b/tools/assimp_view/assimp_view.cpp index 9e8369436..f5c29482a 100644 --- a/tools/assimp_view/assimp_view.cpp +++ b/tools/assimp_view/assimp_view.cpp @@ -151,7 +151,7 @@ DWORD WINAPI LoadThreadProc(LPVOID lpParameter) aiSetImportPropertyFloat(AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE,g_smoothAngle); aiSetImportPropertyInteger(AI_CONFIG_PP_SBP_REMOVE,nopointslines ? aiPrimitiveType_LINE | aiPrimitiveType_POINT : 0 ); - //aiSetImportPropertyInteger(AI_CONFIG_PP_FD_REMOVE,1); + aiSetImportPropertyInteger(AI_CONFIG_GLOB_MEASURE_TIME,1); //aiSetImportPropertyInteger(AI_CONFIG_PP_PTV_KEEP_HIERARCHY,1); // Call ASSIMPs C-API to load the file diff --git a/workspaces/vc9/assimp.vcproj b/workspaces/vc9/assimp.vcproj index e1a85c4f4..d6cf618f4 100644 --- a/workspaces/vc9/assimp.vcproj +++ b/workspaces/vc9/assimp.vcproj @@ -2425,6 +2425,10 @@ RelativePath="..\..\code\ParsingUtils.h" > + +