Просмотр исходного кода

Merge remote-tracking branch 'upstream/master'

Paul Holland 9 лет назад
Родитель
Сommit
fe68765df9
52 измененных файлов с 1244 добавлено и 500 удалено
  1. 30 12
      CHANGES
  2. 6 11
      Readme.md
  3. 14 3
      appveyor.yml
  4. 9 6
      cmake-modules/AddGTest.cmake
  5. 6 5
      code/3DSConverter.cpp
  6. 7 1
      code/Assimp.cpp
  7. 1 1
      code/CMakeLists.txt
  8. 42 0
      code/ColladaHelper.h
  9. 148 1
      code/ColladaParser.cpp
  10. 14 0
      code/ColladaParser.h
  11. 10 4
      code/FBXMeshGeometry.cpp
  12. 13 12
      code/JoinVerticesProcess.cpp
  13. 6 1
      code/LWOAnimation.cpp
  14. 11 12
      code/ObjFileImporter.cpp
  15. 23 28
      code/ObjFileParser.cpp
  16. 1 1
      code/OpenGEXExporter.cpp
  17. 1 1
      code/OpenGEXExporter.h
  18. 13 8
      code/OpenGEXImporter.cpp
  19. 1 1
      code/OpenGEXImporter.h
  20. 1 1
      code/OpenGEXStructs.h
  21. 1 1
      code/Q3BSPZipArchive.cpp
  22. 21 16
      code/SIBImporter.cpp
  23. 4 3
      code/SceneCombiner.cpp
  24. 1 1
      code/SmoothingGroups.inl
  25. 16 0
      contrib/openddlparser/CREDITS
  26. 22 0
      contrib/openddlparser/LICENSE
  27. 40 15
      contrib/openddlparser/README.md
  28. 1 1
      contrib/openddlparser/code/DDLNode.cpp
  29. 27 26
      contrib/openddlparser/code/OpenDDLCommon.cpp
  30. 1 1
      contrib/openddlparser/code/OpenDDLExport.cpp
  31. 72 69
      contrib/openddlparser/code/OpenDDLParser.cpp
  32. 85 51
      contrib/openddlparser/code/Value.cpp
  33. 2 2
      contrib/openddlparser/include/openddlparser/DDLNode.h
  34. 11 31
      contrib/openddlparser/include/openddlparser/OpenDDLCommon.h
  35. 4 0
      contrib/openddlparser/include/openddlparser/OpenDDLExport.h
  36. 5 8
      contrib/openddlparser/include/openddlparser/OpenDDLParser.h
  37. 1 6
      contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h
  38. 13 5
      contrib/openddlparser/include/openddlparser/Value.h
  39. 195 77
      include/assimp/Compiler/pstdint.h
  40. 12 2
      include/assimp/color4.h
  41. 19 9
      include/assimp/matrix3x3.h
  42. 23 13
      include/assimp/matrix4x4.h
  43. 11 11
      include/assimp/port/AndroidJNI/AndroidJNIIOSystem.h
  44. 13 2
      include/assimp/vector2.h
  45. 12 3
      include/assimp/vector3.h
  46. 12 12
      port/AndroidJNI/AndroidJNIIOSystem.cpp
  47. 11 13
      port/AndroidJNI/README.md
  48. 40 0
      scripts/appveyor/compiler_setup.bat
  49. 14 13
      test/CMakeLists.txt
  50. 61 0
      test/models/Collada/library_animation_clips.dae
  51. 28 0
      test/models/OBJ/box_without_lineending.obj
  52. 109 0
      test/unit/utIssues.cpp

+ 30 - 12
CHANGES

@@ -2,6 +2,24 @@
 CHANGELOG
 ----------------------------------------------------------------------
 
+3.2.0 (2015-11-03)
+
+FEATURES:
+  - OpenDDL-Parser is part of contrib-source.
+  - Experimental OpenGEX-support
+  - CI-check for linux and windows
+  - Coverity check added
+  - New regression testsuite.
+
+FIXES/HOUSEKEEPING:
+  - Hundreds of bugfixes  in all parts of the library
+  - Unified line endings
+
+
+API COMPATIBILITY:
+  - Removed precompiled header to increase build speed for linux
+
+
 3.1.1 (2014-06-15)
 
 FEATURES:
@@ -18,18 +36,18 @@ FEATURES:
 FIXES/HOUSEKEEPING:
     - Hundreds of bugfixes in all parts of the library
     - CMake is now the primary build system
-    
+
 API COMPATIBILITY:
     - 3.1.1 is not binary compatible to 3.0 due to aiNode::mMetaData
       and aiMesh::mName
     - Export interface has been cleaned up and unified
     - Other than that no relevant changes
-   
+
 
 3.0 (2012-07-07)
 
 FEATURES:
-   - new export interface similar to the import API. 
+   - new export interface similar to the import API.
    - Supported export formats: Collada, OBJ, PLY and STL
    - added new import formats: XGL/ZGL, M3 (experimental)
    - new postprocessing steps: Debone
@@ -46,11 +64,11 @@ FIXES/HOUSEKEEPING:
    - improved CMake build system
    - templatized math library
    - reduce dependency on boost.thread, only remaining spot
-     is synchronization for the C logging API 
+     is synchronization for the C logging API
 
 API COMPATIBILITY:
    - renamed headers, export interface, C API properties and meta data
-     prevent compatibility with code written for 2.0, but in 
+     prevent compatibility with code written for 2.0, but in
      most cases these can be easily resolved
    - Note: 3.0 is not binary compatible with 2.0
 
@@ -68,9 +86,9 @@ FEATURES:
      spatial structure) in some expensive postprocessing steps
    - AssimpView now uses a reworked layout which leaves more space
      to the scene hierarchy window
-     
+
    - Add C# bindings ('Assimp.NET')
-   - Keep BSD-licensed and otherwise free test files in separate 
+   - Keep BSD-licensed and otherwise free test files in separate
      folders (./test/models and ./test/models-nonbsd).
 
 FIXES:
@@ -80,20 +98,20 @@ FIXES:
    - OpenGL-sample now works with MinGW
    - Fix Importer::FindLoader failing on uppercase file extensions
    - Fix flawed path handling when locating external files
-   - Limit the maximum number of vertices, faces, face indices and 
+   - Limit the maximum number of vertices, faces, face indices and
      weights that Assimp is able to handle. This is to avoid
      crashes due to overflowing counters.
-   
+
    - Updated XCode project files
    - Further CMAKE build improvements
-   
+
 
 API CHANGES:
    - Add data structures for vertex-based animations (These are not
      currently used, however ...)
    - Some Assimp::Importer methods are const now.
- 
- 
+
+
 
 
 

+ 6 - 11
Readme.md

@@ -1,6 +1,5 @@
 Open Asset Import Library (assimp)
-========
-
+==================================
 Open Asset Import Library is a library to load various 3d file formats into a shared, in-memory format. It supports more than __40 file formats__ for import and a growing selection of file formats for export.
 
 APIs are provided for C and C++. There are various bindings to other languages (C#, Java, Python, Delphi, D). Assimp also runs on Android and iOS.
@@ -80,14 +79,15 @@ __Exporters__:
 - glTF
 
 ### Building ###
-
-
 Take a look into the `INSTALL` file. Our build system is CMake, if you used CMake before there is a good chance you know what to do.
 
+### Ports ###
+* [Android](port/AndroidJNI/README.md)
+* [Python](port/PyAssimp/README.md)
+* [.NET](port/AssimpNET/Readme.md)
+* [Pascal](port/AssimpPascal/Readme.md)
 
 #### Repository structure ####
-
-
 Open Asset Import Library is implemented in C++. The directory structure is:
 
 	/code		Source code
@@ -105,8 +105,6 @@ Open Asset Import Library is implemented in C++. The directory structure is:
 
 
 ### Where to get help ###
-
-
 For more information, visit [our website](http://assimp.sourceforge.net/). Or check out the `./doc`- folder, which contains the official documentation in HTML format.
 (CHMs for Windows are included in some release packages and should be located right here in the root folder).
 
@@ -119,12 +117,10 @@ And we also have an IRC-channel at freenode: #assetimporterlib . You can easily
 > /join #assetimporterlib
 
 ### Contributing ###
-
 Contributions to assimp are highly appreciated. The easiest way to get involved is to submit
 a pull request with your changes against the main repository's `master` branch.
 
 ### License ###
-
 Our license is based on the modified, __3-clause BSD__-License.
 
 An _informal_ summary is: do whatever you want, but include Assimp's license text with your product -
@@ -132,5 +128,4 @@ and don't sue us if our code doesn't work. Note that, unlike LGPLed code, you ma
 For the legal details, see the `LICENSE` file.
 
 ### Why this name ###
-
 Sorry, we're germans :-), no english native speakers ...

+ 14 - 3
appveyor.yml

@@ -13,11 +13,22 @@ branches:
 platform:
     - x86
     - x64
-configuration: Release
 
-build:
+configuration:
+  - 2015
+  - 2013
+  - 2012
+  #- MinGW
+  - 2010 # only works for x86
+
+init:
+- if "%platform%" EQU "x64" ( for %%a in (2008 2010 MinGW) do ( if "%Configuration%"=="%%a" (echo "Skipping unsupported configuration" && exit /b 1 ) ) )
+
+install:
+# Make compiler command line tools available
+- call c:\projects\assimp\appveyor\compiler_setup.bat
 
 build_script:
  - cd c:\projects\assimp
- - cmake CMakeLists.txt -G "Visual Studio 11"
+ - cmake CMakeLists.txt -G "Visual Studio %Configuration%"
  - msbuild /m /p:Configuration=Release /p:Platform="Win32" Assimp.sln

+ 9 - 6
cmake-modules/AddGTest.cmake

@@ -21,7 +21,8 @@ endif()
 set(GTEST_CMAKE_ARGS
   "-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}"
   "-Dgtest_force_shared_crt=ON"
-  "-Dgtest_disable_pthreads:BOOL=${DISABLE_PTHREADS}")
+  "-Dgtest_disable_pthreads:BOOL=${DISABLE_PTHREADS}"
+  "-DBUILD_GTEST=ON")
 set(GTEST_RELEASE_LIB_DIR "")
 set(GTEST_DEBUGLIB_DIR "")
 if (MSVC)
@@ -41,7 +42,7 @@ else(NOT GIT_FOUND)
   set(AddGTest_FOUND true CACHE BOOL "Was gtest setup correctly?")
 
   ExternalProject_Add(gtest
-    GIT_REPOSITORY https://chromium.googlesource.com/external/googletest
+    GIT_REPOSITORY https://github.com/google/googletest.git
     TIMEOUT 10
     PREFIX "${GTEST_PREFIX}"
     CMAKE_ARGS "${GTEST_CMAKE_ARGS}"
@@ -56,10 +57,10 @@ else(NOT GIT_FOUND)
   set(LIB_SUFFIX "${CMAKE_STATIC_LIBRARY_SUFFIX}")
   set(GTEST_LOCATION "${GTEST_PREFIX}/src/gtest-build")
   set(GTEST_DEBUG_LIBRARIES
-    "${GTEST_LOCATION}/${DEBUG_LIB_DIR}/${LIB_PREFIX}gtest${LIB_SUFFIX}"
+    "${LIB_PREFIX}gtest${LIB_SUFFIX}"
     "${CMAKE_THREAD_LIBS_INIT}")
   SET(GTEST_RELEASE_LIBRARIES
-    "${GTEST_LOCATION}/${RELEASE_LIB_DIR}/${LIB_PREFIX}gtest${LIB_SUFFIX}"
+    "${LIB_PREFIX}gtest${LIB_SUFFIX}"
     "${CMAKE_THREAD_LIBS_INIT}")
 
   if(MSVC_VERSION EQUAL 1700)
@@ -67,9 +68,11 @@ else(NOT GIT_FOUND)
   endif()
 
   ExternalProject_Get_Property(gtest source_dir)
-  include_directories(${source_dir}/include)
+  include_directories(${source_dir}/googletest/include)
   include_directories(${source_dir}/gtest/include)
 
   ExternalProject_Get_Property(gtest binary_dir)
-  link_directories(${binary_dir})
+  link_directories(${binary_dir}/googlemock/gtest)
+  link_directories(${binary_dir}/googlemock/gtest/${RELEASE_LIB_DIR})
+  link_directories(${binary_dir}/googlemock/gtest/${DEBUG_LIB_DIR})
 endif(NOT GIT_FOUND)

+ 6 - 5
code/3DSConverter.cpp

@@ -70,8 +70,9 @@ void Discreet3DSImporter::ReplaceDefaultMaterial()
     for (unsigned int i = 0; i < mScene->mMaterials.size();++i)
     {
         std::string s = mScene->mMaterials[i].mName;
-        for (std::string::iterator it = s.begin(); it != s.end(); ++it)
-            *it = ::tolower(*it);
+        for ( std::string::iterator it = s.begin(); it != s.end(); ++it ) {
+            *it = static_cast< char >( ::tolower( *it ) );
+        }
 
         if (std::string::npos == s.find("default"))continue;
 
@@ -663,14 +664,14 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,
             nda->mRotationKeys = new aiQuatKey[nda->mNumRotationKeys];
 
             // Rotations are quaternion offsets
-            aiQuaternion abs;
+            aiQuaternion abs1;
             for (unsigned int n = 0; n < nda->mNumRotationKeys;++n)
             {
                 const aiQuatKey& q = pcIn->aRotationKeys[n];
 
-                abs = (n ? abs * q.mValue : q.mValue);
+                abs1 = (n ? abs1 * q.mValue : q.mValue);
                 nda->mRotationKeys[n].mTime  = q.mTime;
-                nda->mRotationKeys[n].mValue = abs.Normalize();
+                nda->mRotationKeys[n].mValue = abs1.Normalize();
             }
         }
 

+ 7 - 1
code/Assimp.cpp

@@ -429,12 +429,18 @@ ASSIMP_API void aiDetachAllLogStreams(void)
 #ifndef ASSIMP_BUILD_SINGLETHREADED
     boost::mutex::scoped_lock lock(gLogStreamMutex);
 #endif
+    Logger *logger( DefaultLogger::get() );
+    if ( NULL == logger ) {
+        return;
+    }
+
     for (LogStreamMap::iterator it = gActiveLogStreams.begin(); it != gActiveLogStreams.end(); ++it) {
-        DefaultLogger::get()->detatchStream( it->second );
+        logger->detatchStream( it->second );
         delete it->second;
     }
     gActiveLogStreams.clear();
     DefaultLogger::kill();
+    
     ASSIMP_END_EXCEPTION_REGION(void);
 }
 

+ 1 - 1
code/CMakeLists.txt

@@ -798,7 +798,7 @@ if (ASSIMP_ANDROID_JNIIOSYSTEM)
 endif(ASSIMP_ANDROID_JNIIOSYSTEM)
 
 if(MSVC AND ASSIMP_INSTALL_PDB)
-  install(FILES ${Assimp_BINARY_DIR}/code/Debug/assimp${CMAKE_DEBUG_POSTFIX}.pdb
+  install(FILES ${Assimp_BINARY_DIR}/code/Debug/assimp${LIBRARY_SUFFIX}${CMAKE_DEBUG_POSTFIX}.pdb
     DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
     CONFIGURATIONS Debug
   )

+ 42 - 0
code/ColladaHelper.h

@@ -597,6 +597,48 @@ struct Animation
         for( std::vector<Animation*>::iterator it = mSubAnims.begin(); it != mSubAnims.end(); ++it)
             delete *it;
     }
+
+	/** Collect all channels in the animation hierarchy into a single channel list. */
+	void CollectChannelsRecursively(std::vector<AnimationChannel> &channels)
+	{
+		channels.insert(channels.end(), mChannels.begin(), mChannels.end());
+
+		for (std::vector<Animation*>::iterator it = mSubAnims.begin(); it != mSubAnims.end(); ++it)
+		{
+			Animation *pAnim = (*it);
+
+			pAnim->CollectChannelsRecursively(channels);
+		}
+	}
+
+	/** Combine all single-channel animations' channel into the same (parent) animation channel list. */
+	void CombineSingleChannelAnimations()
+	{
+		CombineSingleChannelAnimationsRecursively(this);
+	}
+
+	void CombineSingleChannelAnimationsRecursively(Animation *pParent)
+	{
+		for (std::vector<Animation*>::iterator it = pParent->mSubAnims.begin(); it != pParent->mSubAnims.end();)
+		{
+			Animation *anim = *it;
+
+			CombineSingleChannelAnimationsRecursively(anim);
+
+			if (anim->mChannels.size() == 1)
+			{
+				pParent->mChannels.push_back(anim->mChannels[0]);
+
+				it = pParent->mSubAnims.erase(it);
+
+				delete anim;
+			}
+			else
+			{
+				++it;
+			}
+		}
+	}
 };
 
 /** Description of a collada animation channel which has been determined to affect the current node */

+ 148 - 1
code/ColladaParser.cpp

@@ -187,6 +187,8 @@ void ColladaParser::ReadStructure()
                 ReadAssetInfo();
             else if( IsElement( "library_animations"))
                 ReadAnimationLibrary();
+			else if (IsElement("library_animation_clips"))
+				ReadAnimationClipLibrary();
             else if( IsElement( "library_controllers"))
                 ReadControllerLibrary();
             else if( IsElement( "library_images"))
@@ -215,6 +217,8 @@ void ColladaParser::ReadStructure()
             break;
         }
     }
+
+	PostProcessRootAnimations();
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -271,6 +275,131 @@ void ColladaParser::ReadAssetInfo()
     }
 }
 
+// ------------------------------------------------------------------------------------------------
+// Reads the animation clips
+void ColladaParser::ReadAnimationClipLibrary()
+{
+	if (mReader->isEmptyElement())
+		return;
+
+	while (mReader->read())
+	{
+		if (mReader->getNodeType() == irr::io::EXN_ELEMENT)
+		{
+			if (IsElement("animation_clip"))
+			{
+				// optional name given as an attribute
+				std::string animName;
+				int indexName = TestAttribute("name");
+				int indexID = TestAttribute("id");
+				if (indexName >= 0)
+					animName = mReader->getAttributeValue(indexName);
+				else if (indexID >= 0)
+					animName = mReader->getAttributeValue(indexID);
+				else
+					animName = "animation_" + mAnimationClipLibrary.size();
+
+				std::pair<std::string, std::vector<std::string> > clip;
+
+				clip.first = animName;
+
+				while (mReader->read())
+				{
+					if (mReader->getNodeType() == irr::io::EXN_ELEMENT)
+					{
+						if (IsElement("instance_animation"))
+						{
+							int indexUrl = TestAttribute("url");
+							if (indexUrl >= 0)
+							{
+								const char* url = mReader->getAttributeValue(indexUrl);
+								if (url[0] != '#')
+									ThrowException("Unknown reference format");
+
+								url++;
+
+								clip.second.push_back(url);
+							}
+						}
+						else
+						{
+							// ignore the rest
+							SkipElement();
+						}
+					}
+					else if (mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
+					{
+						if (strcmp(mReader->getNodeName(), "animation_clip") != 0)
+							ThrowException("Expected end of <animation_clip> element.");
+
+						break;
+					}
+				}
+
+				if (clip.second.size() > 0)
+				{
+					mAnimationClipLibrary.push_back(clip);
+				}
+			}
+			else
+			{
+				// ignore the rest
+				SkipElement();
+			}
+		}
+		else if (mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
+		{
+			if (strcmp(mReader->getNodeName(), "library_animation_clips") != 0)
+				ThrowException("Expected end of <library_animation_clips> element.");
+
+			break;
+		}
+	}
+}
+
+// ------------------------------------------------------------------------------------------------
+// Re-build animations from animation clip library, if present, otherwise combine single-channel animations
+void ColladaParser::PostProcessRootAnimations()
+{
+	if (mAnimationClipLibrary.size() > 0)
+	{
+		Animation temp;
+
+		for (AnimationClipLibrary::iterator it = mAnimationClipLibrary.begin(); it != mAnimationClipLibrary.end(); ++it)
+		{
+			std::string clipName = it->first;
+
+			Animation *clip = new Animation();
+			clip->mName = clipName;
+
+			temp.mSubAnims.push_back(clip);
+
+			for (std::vector<std::string>::iterator a = it->second.begin(); a != it->second.end(); ++a)
+			{
+				std::string animationID = *a;
+
+				AnimationLibrary::iterator animation = mAnimationLibrary.find(animationID);
+
+				if (animation != mAnimationLibrary.end())
+				{
+					Animation *pSourceAnimation = animation->second;
+
+					pSourceAnimation->CollectChannelsRecursively(clip->mChannels);
+				}
+			}
+		}
+
+		mAnims = temp;
+
+		// Ensure no double deletes.
+		temp.mSubAnims.clear();
+	}
+	else
+	{
+		mAnims.CombineSingleChannelAnimations();
+	}
+}
+
 // ------------------------------------------------------------------------------------------------
 // Reads the animation library
 void ColladaParser::ReadAnimationLibrary()
@@ -318,12 +447,17 @@ void ColladaParser::ReadAnimation( Collada::Animation* pParent)
 
     // optional name given as an attribute
     std::string animName;
+	std::string animID;
     int indexName = TestAttribute( "name");
     int indexID = TestAttribute( "id");
+
+	if (indexID >= 0)
+		animID = mReader->getAttributeValue(indexID);
+
     if( indexName >= 0)
         animName = mReader->getAttributeValue( indexName);
     else if( indexID >= 0)
-        animName = mReader->getAttributeValue( indexID);
+        animName = animID;
     else
         animName = "animation";
 
@@ -395,11 +529,19 @@ void ColladaParser::ReadAnimation( Collada::Animation* pParent)
     // it turned out to have channels - add them
     if( !channels.empty())
     {
+		// FIXME: Is this essentially doing the same as "single-anim-node" codepath in 
+		//        ColladaLoader::StoreAnimations? For now, this has been deferred to after
+		//        all animations and all clips have been read. Due to handling of 
+		//        <library_animation_clips> this cannot be done here, as the channel owner 
+		//        is lost, and some exporters make up animations by referring to multiple
+		//        single-channel animations from an <instance_animation>.
+/*
         // special filtering for stupid exporters packing each channel into a separate animation
         if( channels.size() == 1)
         {
             pParent->mChannels.push_back( channels.begin()->second);
         } else
+*/
         {
             // else create the animation, if not done yet, and store the channels
             if( !anim)
@@ -410,6 +552,11 @@ void ColladaParser::ReadAnimation( Collada::Animation* pParent)
             }
             for( ChannelMap::const_iterator it = channels.begin(); it != channels.end(); ++it)
                 anim->mChannels.push_back( it->second);
+
+			if (indexID >= 0)
+			{
+				mAnimationLibrary[animID] = anim;
+			}
         }
     }
 }

+ 14 - 0
code/ColladaParser.h

@@ -82,6 +82,12 @@ namespace Assimp
         
         /** Reads the animation library */
         void ReadAnimationLibrary();
+
+		/** Reads the animation clip library */
+		void ReadAnimationClipLibrary();
+
+		/** Re-build animations from animation clip library, if present, otherwise combine single-channel animations */
+		void PostProcessRootAnimations();
         
         /** Reads an animation into the given parent structure */
         void ReadAnimation( Collada::Animation* pParent);
@@ -312,6 +318,14 @@ namespace Assimp
         /** Controller library: joint controllers by ID */
         typedef std::map<std::string, Collada::Controller> ControllerLibrary;
         ControllerLibrary mControllerLibrary;
+
+		/** Animation library: animation references by ID */
+		typedef std::map<std::string, Collada::Animation*> AnimationLibrary;
+		AnimationLibrary mAnimationLibrary;
+
+		/** Animation clip library: clip animation references by ID */
+		typedef std::vector<std::pair<std::string, std::vector<std::string> > > AnimationClipLibrary;
+		AnimationClipLibrary mAnimationClipLibrary;
         
         /** Pointer to the root node. Don't delete, it just points to one of
          the nodes in the node library. */

+ 10 - 4
code/FBXMeshGeometry.cpp

@@ -471,32 +471,38 @@ void MeshGeometry::ReadVertexDataColors(std::vector<aiColor4D>& colors_out, cons
         mappings);
 }
 
-
 // ------------------------------------------------------------------------------------------------
+static const std::string TangentIndexToken = "TangentIndex";
+static const std::string TangentsIndexToken = "TangentsIndex";
+
 void MeshGeometry::ReadVertexDataTangents(std::vector<aiVector3D>& tangents_out, const Scope& source,
     const std::string& MappingInformationType,
     const std::string& ReferenceInformationType)
 {
     const char * str = source.Elements().count( "Tangents" ) > 0 ? "Tangents" : "Tangent";
+    const char * strIdx = source.Elements().count( "Tangents" ) > 0 ? TangentsIndexToken.c_str() : TangentIndexToken.c_str();
     ResolveVertexDataArray(tangents_out,source,MappingInformationType,ReferenceInformationType,
         str,
-        "TangentIndex",
+        strIdx,
         vertices.size(),
         mapping_counts,
         mapping_offsets,
         mappings);
 }
 
-
 // ------------------------------------------------------------------------------------------------
+static const std::string BinormalIndexToken = "BinormalIndex";
+static const std::string BinormalsIndexToken = "BinormalsIndex";
+
 void MeshGeometry::ReadVertexDataBinormals(std::vector<aiVector3D>& binormals_out, const Scope& source,
     const std::string& MappingInformationType,
     const std::string& ReferenceInformationType)
 {
     const char * str = source.Elements().count( "Binormals" ) > 0 ? "Binormals" : "Binormal";
+    const char * strIdx = source.Elements().count( "Binormals" ) > 0 ? BinormalsIndexToken.c_str() : BinormalIndexToken.c_str();
     ResolveVertexDataArray(binormals_out,source,MappingInformationType,ReferenceInformationType,
         str,
-        "BinormalIndex",
+        strIdx,
         vertices.size(),
         mapping_counts,
         mapping_offsets,

+ 13 - 12
code/JoinVerticesProcess.cpp

@@ -357,23 +357,24 @@ int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
     }
 
     // adjust bone vertex weights.
-    for( int a = 0; a < (int)pMesh->mNumBones; a++)
-    {
+    for( int a = 0; a < (int)pMesh->mNumBones; a++) {
         aiBone* bone = pMesh->mBones[a];
         std::vector<aiVertexWeight> newWeights;
         newWeights.reserve( bone->mNumWeights);
 
-        for( unsigned int b = 0; b < bone->mNumWeights; b++)
-        {
-            const aiVertexWeight& ow = bone->mWeights[b];
-            // if the vertex is a unique one, translate it
-            if( !(replaceIndex[ow.mVertexId] & 0x80000000))
-            {
-                aiVertexWeight nw;
-                nw.mVertexId = replaceIndex[ow.mVertexId];
-                nw.mWeight = ow.mWeight;
-                newWeights.push_back( nw);
+        if ( NULL != bone->mWeights ) {
+            for ( unsigned int b = 0; b < bone->mNumWeights; b++ ) {
+                const aiVertexWeight& ow = bone->mWeights[ b ];
+                // if the vertex is a unique one, translate it
+                if ( !( replaceIndex[ ow.mVertexId ] & 0x80000000 ) ) {
+                    aiVertexWeight nw;
+                    nw.mVertexId = replaceIndex[ ow.mVertexId ];
+                    nw.mWeight = ow.mWeight;
+                    newWeights.push_back( nw );
+                }
             }
+        } else {
+            DefaultLogger::get()->error( "X-Export: aiBone shall contain weights, but pointer to them is NULL." );
         }
 
         if (newWeights.size() > 0) {

+ 6 - 1
code/LWOAnimation.cpp

@@ -328,7 +328,12 @@ void AnimResolver::DoInterpolation2(std::vector<LWO::Key>::const_iterator beg,
             break;
     }
     // linear interpolation - default
-    fill = (*beg).value + ((*end).value - (*beg).value)*(float)(((time - (*beg).time) / ((*end).time - (*beg).time)));
+    double duration = (*end).time - (*beg).time;
+    if (duration > 0.0) {
+        fill = (*beg).value + ((*end).value - (*beg).value)*(float)(((time - (*beg).time) / duration));
+    } else {
+        fill = (*beg).value;
+    }
 }
 
 // ------------------------------------------------------------------------------------------------

+ 11 - 12
code/ObjFileImporter.cpp

@@ -114,35 +114,34 @@ const aiImporterDesc* ObjFileImporter::GetInfo () const
 
 // ------------------------------------------------------------------------------------------------
 //  Obj-file import implementation
-void ObjFileImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
-{
+void ObjFileImporter::InternReadFile( const std::string &file, aiScene* pScene, IOSystem* pIOHandler) {
     // Read file into memory
-    const std::string mode = "rb";
-    boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, mode));
-    if( !file.get() ) {
-        throw DeadlyImportError( "Failed to open file " + pFile + "." );
+    static const std::string mode = "rb";
+    boost::scoped_ptr<IOStream> fileStream( pIOHandler->Open( file, mode));
+    if( !fileStream.get() ) {
+        throw DeadlyImportError( "Failed to open file " + file + "." );
     }
 
     // Get the file-size and validate it, throwing an exception when fails
-    size_t fileSize = file->FileSize();
+    size_t fileSize = fileStream->FileSize();
     if( fileSize < ObjMinSize ) {
         throw DeadlyImportError( "OBJ-file is too small.");
     }
 
     // Allocate buffer and read file into it
-    TextFileToBuffer(file.get(),m_Buffer);
+    TextFileToBuffer( fileStream.get(),m_Buffer);
 
     // Get the model name
     std::string  modelName, folderName;
-    std::string::size_type pos = pFile.find_last_of( "\\/" );
+    std::string::size_type pos = file.find_last_of( "\\/" );
     if ( pos != std::string::npos ) {
-        modelName = pFile.substr(pos+1, pFile.size() - pos - 1);
-        folderName = pFile.substr( 0, pos );
+        modelName = file.substr(pos+1, file.size() - pos - 1);
+        folderName = file.substr( 0, pos );
         if ( !folderName.empty() ) {
             pIOHandler->PushDirectory( folderName );
         }
     } else {
-        modelName = pFile;
+        modelName = file;
     }
 
     // This next stage takes ~ 1/3th of the total readFile task

+ 23 - 28
code/ObjFileParser.cpp

@@ -293,7 +293,7 @@ void ObjFileParser::getVector( std::vector<aiVector3D> &point3d_array ) {
 
 // -------------------------------------------------------------------
 //  Get values for a new 3D vector instance
-void ObjFileParser::getVector3(std::vector<aiVector3D> &point3d_array) {
+void ObjFileParser::getVector3( std::vector<aiVector3D> &point3d_array ) {
     float x, y, z;
     copyNextWord(m_buffer, Buffersize);
     x = (float) fast_atof(m_buffer);
@@ -323,19 +323,18 @@ void ObjFileParser::getVector2( std::vector<aiVector2D> &point2d_array ) {
     m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
 }
 
+static const std::string DefaultObjName = "defaultobject";
+
 // -------------------------------------------------------------------
 //  Get values for a new face instance
-void ObjFileParser::getFace(aiPrimitiveType type)
-{
+void ObjFileParser::getFace(aiPrimitiveType type) {
     copyNextLine(m_buffer, Buffersize);
-    if (m_DataIt == m_DataItEnd)
-        return;
-
     char *pPtr = m_buffer;
     char *pEnd = &pPtr[Buffersize];
     pPtr = getNextToken<char*>(pPtr, pEnd);
-    if (pPtr == pEnd || *pPtr == '\0')
+    if ( pPtr == pEnd || *pPtr == '\0' ) {
         return;
+    }
 
     std::vector<unsigned int> *pIndices = new std::vector<unsigned int>;
     std::vector<unsigned int> *pTexID = new std::vector<unsigned int>;
@@ -349,20 +348,18 @@ void ObjFileParser::getFace(aiPrimitiveType type)
     const bool vt = (!m_pModel->m_TextureCoord.empty());
     const bool vn = (!m_pModel->m_Normals.empty());
     int iStep = 0, iPos = 0;
-    while (pPtr != pEnd)
-    {
+    while (pPtr != pEnd) {
         iStep = 1;
 
-        if (IsLineEnd(*pPtr))
+        if ( IsLineEnd( *pPtr ) ) {
             break;
+        }
 
-        if (*pPtr=='/' )
-        {
+        if (*pPtr=='/' ) {
             if (type == aiPrimitiveType_POINT) {
                 DefaultLogger::get()->error("Obj: Separator unexpected in point statement");
             }
-            if (iPos == 0)
-            {
+            if (iPos == 0) {
                 //if there are no texture coordinates in the file, but normals
                 if (!vt && vn) {
                     iPos = 1;
@@ -370,22 +367,20 @@ void ObjFileParser::getFace(aiPrimitiveType type)
                 }
             }
             iPos++;
-        }
-        else if( IsSpaceOrNewLine( *pPtr ) )
-        {
+        } else if( IsSpaceOrNewLine( *pPtr ) ) {
             iPos = 0;
-        }
-        else
-        {
+        } else {
             //OBJ USES 1 Base ARRAYS!!!!
-            const int iVal = atoi( pPtr );
+            const int iVal( ::atoi( pPtr ) );
 
             // increment iStep position based off of the sign and # of digits
             int tmp = iVal;
-            if (iVal < 0)
+            if ( iVal < 0 ) {
                 ++iStep;
-            while ( ( tmp = tmp / 10 )!=0 )
+            }
+            while ( ( tmp = tmp / 10 ) != 0 ) {
                 ++iStep;
+            }
 
             if ( iVal > 0 )
             {
@@ -455,12 +450,12 @@ void ObjFileParser::getFace(aiPrimitiveType type)
 
     // Create a default object, if nothing is there
     if( NULL == m_pModel->m_pCurrent ) {
-        createObject( "defaultobject" );
+        createObject( DefaultObjName );
     }
 
     // Assign face to mesh
     if ( NULL == m_pModel->m_pCurrentMesh ) {
-        createMesh( "defaultobject" );
+        createMesh( DefaultObjName );
     }
 
     // Store the face
@@ -780,15 +775,15 @@ void ObjFileParser::createMesh( const std::string &meshName )
 
 // -------------------------------------------------------------------
 //  Returns true, if a new mesh must be created.
-bool ObjFileParser::needsNewMesh( const std::string &rMaterialName )
+bool ObjFileParser::needsNewMesh( const std::string &materialName )
 {
+    // If no mesh data yet
     if(m_pModel->m_pCurrentMesh == 0)
     {
-        // No mesh data yet
         return true;
     }
     bool newMat = false;
-    int matIdx = getMaterialIndex( rMaterialName );
+    int matIdx = getMaterialIndex( materialName );
     int curMatIdx = m_pModel->m_pCurrentMesh->m_uiMaterialIndex;
     if ( curMatIdx != int(ObjFile::Mesh::NoMaterial) && curMatIdx != matIdx )
     {

+ 1 - 1
code/OpenGEXExporter.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2014, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,

+ 1 - 1
code/OpenGEXExporter.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2014, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,

+ 13 - 8
code/OpenGEXImporter.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2014, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,
@@ -225,6 +225,7 @@ OpenGEXImporter::OpenGEXImporter()
 , m_tokenType( Grammar::NoneType )
 , m_nodeStack()
 , m_unresolvedRefStack() {
+    // empty
 }
 
 //------------------------------------------------------------------------------------------------
@@ -423,7 +424,7 @@ static void getRefNames( DDLNode *node, std::vector<std::string> &names ) {
         for( size_t i = 0; i < ref->m_numRefs; i++ )  {
             Name *currentName( ref->m_referencedName[ i ] );
             if( NULL != currentName && NULL != currentName->m_id ) {
-                const std::string name( currentName->m_id->m_text.m_buffer );
+                const std::string name( currentName->m_id->m_buffer );
                 if( !name.empty() ) {
                     names.push_back( name );
                 }
@@ -541,7 +542,7 @@ static void propId2StdString( Property *prop, std::string &name, std::string &ke
     }
 
     if( NULL != prop->m_key ) {
-        name = prop->m_key->m_text.m_buffer;
+        name = prop->m_key->m_buffer;
         if( Value::ddl_string == prop->m_value->m_type ) {
             key = prop->m_value->getString();
         }
@@ -714,7 +715,7 @@ void OpenGEXImporter::handleIndexArrayNode( ODDLParser::DDLNode *node, aiScene *
         current.mIndices = new unsigned int[ current.mNumIndices ];
         Value *next( vaList->m_dataList );
         for( size_t indices = 0; indices < current.mNumIndices; indices++ ) {
-            const int idx = next->getInt32();
+            const int idx( next->getUnsignedInt32() );
             ai_assert( static_cast<size_t>( idx ) <= m_currentVertices.m_numVerts );
 
             aiVector3D &pos = ( m_currentVertices.m_vertices[ idx ] );
@@ -758,12 +759,16 @@ enum ColorType {
 };
 
 //------------------------------------------------------------------------------------------------
-static ColorType getColorType( Identifier *id ) {
-    if( id->m_text == Grammar::DiffuseColorToken ) {
+static ColorType getColorType( Text *id ) {
+    if ( NULL == id ) {
+        return NoneColor;
+    }
+
+    if( *id == Grammar::DiffuseColorToken ) {
         return DiffuseColor;
-    } else if( id->m_text == Grammar::SpecularColorToken ) {
+    } else if( *id == Grammar::SpecularColorToken ) {
         return SpecularColor;
-    } else if( id->m_text == Grammar::EmissionColorToken ) {
+    } else if( *id == Grammar::EmissionColorToken ) {
         return EmissionColor;
     }
 

+ 1 - 1
code/OpenGEXImporter.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2014, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,

+ 1 - 1
code/OpenGEXStructs.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2014, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,

+ 1 - 1
code/Q3BSPZipArchive.cpp

@@ -292,7 +292,7 @@ bool Q3BSPZipArchive::mapArchive() {
                         // The file has EXACTLY the size of uncompressed_size. In C
                         // you need to mark the last character with '\0', so add
                         // another character
-                        if(unzOpenCurrentFile(m_ZipFileHandle) == UNZ_OK) {
+                        if(fileInfo.uncompressed_size != 0 && unzOpenCurrentFile(m_ZipFileHandle) == UNZ_OK) {
                             std::pair<std::map<std::string, ZipFile*>::iterator, bool> result = m_ArchiveMap.insert(std::make_pair(filename, new ZipFile(fileInfo.uncompressed_size)));
 
                             if(unzReadCurrentFile(m_ZipFileHandle, result.first->second->m_Buffer, fileInfo.uncompressed_size) == (long int) fileInfo.uncompressed_size) {

+ 21 - 16
code/SIBImporter.cpp

@@ -40,7 +40,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
 /** @file  SIBImporter.cpp
- *  @brief Implementation of the SIB importer class
+ *  @brief Implementation of the SIB importer class.
  *
  *  The Nevercenter Silo SIB format is undocumented.
  *  All details here have been reverse engineered from
@@ -163,7 +163,12 @@ static aiColor3D ReadColor(StreamReaderLE* stream)
 
 static void UnknownChunk(StreamReaderLE* stream, const SIBChunk& chunk)
 {
-    char temp[5] = { (chunk.Tag>>24)&0xff, (chunk.Tag>>16)&0xff, (chunk.Tag>>8)&0xff, chunk.Tag&0xff, '\0' };
+    char temp[5] = { 
+        static_cast<char>(( chunk.Tag>>24 ) & 0xff),
+        static_cast<char>(( chunk.Tag>>16 ) & 0xff),
+        static_cast<char>(( chunk.Tag>>8 ) & 0xff),
+        static_cast<char>(chunk.Tag & 0xff), '\0'
+    };
     
     DefaultLogger::get()->warn((Formatter::format(), "SIB: Skipping unknown '",temp,"' chunk."));
 }
@@ -512,7 +517,7 @@ static void ReadShape(SIB* sib, StreamReaderLE* stream)
     aiString name;
 
     while (stream->GetRemainingSizeToLimit() >= sizeof(SIBChunk))
-	{
+    {
         SIBChunk chunk = ReadChunk(stream);
         unsigned oldLimit = stream->SetReadLimit(stream->GetCurrentPos() + chunk.Size);
 
@@ -720,7 +725,7 @@ static void ReadLight(SIB* sib, StreamReaderLE* stream)
     aiLight* light = new aiLight();
 
     while (stream->GetRemainingSizeToLimit() >= sizeof(SIBChunk))
-	{
+    {
         SIBChunk chunk = ReadChunk(stream);
         unsigned oldLimit = stream->SetReadLimit(stream->GetCurrentPos() + chunk.Size);
 
@@ -768,18 +773,18 @@ static void ReadInstance(SIB* sib, StreamReaderLE* stream)
     uint32_t shapeIndex = 0;
 
     while (stream->GetRemainingSizeToLimit() >= sizeof(SIBChunk))
-	{
+    {
         SIBChunk chunk = ReadChunk(stream);
         unsigned oldLimit = stream->SetReadLimit(stream->GetCurrentPos() + chunk.Size);
 
         switch (chunk.Tag)
         {
-		case TAG('D','I','N','F'): break; // display info, not needed
-		case TAG('P','I','N','F'): break; // ?
+        case TAG('D','I','N','F'): break; // display info, not needed
+        case TAG('P','I','N','F'): break; // ?
         case TAG('A','X','I','S'): ReadAxis(inst.axis, stream); break;
-		case TAG('I','N','S','I'): shapeIndex = stream->GetU4(); break;
-		case TAG('S','M','T','X'): ReadScale(inst.axis, stream); break;
-		case TAG('S','N','A','M'): inst.name = ReadString(stream, chunk.Size/2); break;
+        case TAG('I','N','S','I'): shapeIndex = stream->GetU4(); break;
+        case TAG('S','M','T','X'): ReadScale(inst.axis, stream); break;
+        case TAG('S','N','A','M'): inst.name = ReadString(stream, chunk.Size/2); break;
         default:                   UnknownChunk(stream, chunk); break;
         }
 
@@ -808,7 +813,7 @@ static void ReadScene(SIB* sib, StreamReaderLE* stream)
 {
     // Parse each chunk in turn.
     while (stream->GetRemainingSizeToLimit() >= sizeof(SIBChunk))
-	{
+    {
         SIBChunk chunk = ReadChunk(stream);
         unsigned oldLimit = stream->SetReadLimit(stream->GetCurrentPos() + chunk.Size);
 
@@ -860,9 +865,9 @@ void SIBImporter::InternReadFile(const std::string& pFile,
     pScene->mNumMaterials = sib.mtls.size();
     pScene->mNumMeshes = sib.meshes.size();
     pScene->mNumLights = sib.lights.size();
-    pScene->mMaterials = new aiMaterial* [pScene->mNumMaterials];
-    pScene->mMeshes = new aiMesh* [pScene->mNumMeshes];
-    pScene->mLights = new aiLight* [pScene->mNumLights];
+    pScene->mMaterials = pScene->mNumMaterials ? new aiMaterial*[pScene->mNumMaterials] : NULL;
+    pScene->mMeshes = pScene->mNumMeshes ? new aiMesh*[pScene->mNumMeshes] : NULL;
+    pScene->mLights = pScene->mNumLights ? new aiLight*[pScene->mNumLights] : NULL;
     if (pScene->mNumMaterials)
         memcpy(pScene->mMaterials, &sib.mtls[0], sizeof(aiMaterial*) * pScene->mNumMaterials);
     if (pScene->mNumMeshes)
@@ -875,7 +880,7 @@ void SIBImporter::InternReadFile(const std::string& pFile,
     aiNode *root = new aiNode();
     root->mName.Set("<SIBRoot>");
     root->mNumChildren = sib.objs.size() + sib.lights.size();
-    root->mChildren = new aiNode* [root->mNumChildren];
+    root->mChildren = root->mNumChildren ? new aiNode*[root->mNumChildren] : NULL;
     pScene->mRootNode = root;
 
     // Add nodes for each object.
@@ -889,7 +894,7 @@ void SIBImporter::InternReadFile(const std::string& pFile,
         node->mTransformation = obj.axis;
 
         node->mNumMeshes = obj.meshCount;
-        node->mMeshes = new unsigned[node->mNumMeshes];
+        node->mMeshes = node->mNumMeshes ? new unsigned[node->mNumMeshes] : NULL;
         for (unsigned i=0;i<node->mNumMeshes;i++)
             node->mMeshes[i] = obj.meshIdx + i;
 

+ 4 - 3
code/SceneCombiner.cpp

@@ -1128,10 +1128,11 @@ void SceneCombiner::Copy  (aiTexture** _dest, const aiTexture* src)
 }
 
 // ------------------------------------------------------------------------------------------------
-void SceneCombiner::Copy     (aiAnimation** _dest, const aiAnimation* src)
+void SceneCombiner::Copy( aiAnimation** _dest, const aiAnimation* src )
 {
-    ai_assert(NULL != _dest && NULL != src);
-
+    ai_assert( NULL != _dest );
+    ai_assert( NULL != src );
+    
     aiAnimation* dest = *_dest = new aiAnimation();
 
     // get a flat copy

+ 1 - 1
code/SmoothingGroups.inl

@@ -119,7 +119,7 @@ void ComputeNormalsWithSmoothingsGroups(MeshWithSmoothingGroups<T>& sMesh)
             {
                 vNormals += sMesh.mNormals[(*a)];
             }
-            vNormals.Normalize();
+            vNormals.NormalizeSafe();
 
             // write back into all affected normals
             for (std::vector<unsigned int>::const_iterator

+ 16 - 0
contrib/openddlparser/CREDITS

@@ -0,0 +1,16 @@
+===============================================================
+OpenDDL-Parser
+Developers and Contributors
+===============================================================
+
+- Kim Kulling ( kimmi ):
+Founder
+
+- Fredrik Hansson ( FredrikHson ):
+Improvements value interface, serveral bugfixes.
+
+- Henry Read ( henrya2 ):
+Static build option, Interface improvements
+
+- Paul Holland ( pkholland ):
+Bugfixes.

+ 22 - 0
contrib/openddlparser/LICENSE

@@ -0,0 +1,22 @@
+The MIT License (MIT)
+
+Copyright (c) 2014 Kim Kulling
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+

+ 40 - 15
contrib/openddlparser/README.md

@@ -1,29 +1,39 @@
 The OpenDDL-Parser
 ==================
 
-A simple and fast OpenDDL Parser
-Current build status: [![Build Status](https://travis-ci.org/kimkulling/openddl-parser.png)](https://travis-ci.org/kimkulling/openddl-parser)
+The OpenDDL-Parser is a small and easy to use library for OpenDDL-file-format-parsing. OpenDDL is the shortcut for Open Data Description Language, a data-declaration language introduced by Eric Lengyel. Please check http://openddl.org/ if you want to learn more about it.
+
+Build status
+============
+Linux build status: [![Build Status](https://travis-ci.org/kimkulling/openddl-parser.png)](https://travis-ci.org/kimkulling/openddl-parser)
+Current coverity check status:
+<a href="https://scan.coverity.com/projects/5606">
+  <img alt="Coverity Scan Build Status"
+       src="https://scan.coverity.com/projects/5606/badge.svg"/>
+</a>
 
 Get the source code
 ===================
-You can get the code from our git repository, which is located at GitHub. You can clone the repository like:
+You can get the code from our git repository, which is located at GitHub. You can clone the repository with the following command:
 
 > git clone https://github.com/kimkulling/openddl-parser.git
 
-Build from repo
-===============
-To build the library you need to install cmake first ( see http://www.cmake.org/ for more information ). Make also sure that a compiler toolchain is installed on your machine.
-After installing it you can open a console and type:
+Building the source from the GitHub-Repo
+========================================
+To build the library you need to install cmake first ( see http://www.cmake.org/ for more information ). Make also sure that a compiler tool-chain is installed on your machine.
+After installing it you can open a console and enter:
 
 > cmake CMakeLists.txt
 
-This command will generate a build environment for your installed build enrironment ( for Visual Studio the project files will be generated, for gcc the makefiles will be generated ).
+This command will generate a build environment for your installed build enrironment ( for Visual-Studio-users the project files will be generated, for gcc-users the makefiles will be generated ).
 When using an IDE open the IDE and run the build. When using GNU-make type in your console:
 
 > make
 
 and that's all.
 
+When using Visual Studio CMake will generate you a solution for ythe library. Just build it there.
+
 Use the library
 ===============
 To use the OpenDDL-parser you need to build the lib first. Now add the 
@@ -88,24 +98,39 @@ int main( int argc, char *argv[] ) {
 
 How to access the imported data
 ===============================
-The data is organized as a tree. You can get the root tree with the following code:
+The data is organized as a tree. You can get the root-node of the tree with the following code:
 
-```
+```cpp
 OpenDDLParser theParser;
 theParser.setBuffer( buffer, size );
 const bool result( theParser.parse() );
 if ( result ) {
     DDLNode *root = theParser.getRoot();
-
     DDLNode::DllNodeList childs = root->getChildNodeList();
     for ( size_t i=0; i<childs.size(); i++ ) {
         DDLNode *child = childs[ i ];
-        Property *prop = child->getProperty(); // to get properties
-        std:.string type = child->getType();   // to get the node type
-        Value *values = child->getValue();     // to get the data;
+        Property *prop   = child->getProperty(); // to get properties
+        std::string type = child->getType();     // to get the node type
+        Value *values    = child->getValue();    // to get the data;
+        
+        // to loop through all values
+        while ( values != ddl_nullptr ) {
+            int current = values->getInt32();
+            values = value->getNext();
+        }
     }
 }
 
 ```
 
-The instance called root contains the data.
+The node instance called root contains the data.
+
+All data lists are organized as linked lists.
+
+Reference documentation
+=======================
+Please check http://kimkulling.github.io/openddl-parser/doxygen_html/index.html.
+
+Projects using OpenDDL-Parser
+=============================
+- Asset Importer Lib: https://github.com/assimp/assimp .

+ 1 - 1
contrib/openddlparser/code/DDLNode.cpp

@@ -153,7 +153,7 @@ Property *DDLNode::findPropertyByName( const std::string &name ) {
 
     Property *current( m_properties );
     while( ddl_nullptr != current ) {
-        int res = strncmp( current->m_key->m_text.m_buffer, name.c_str(), name.size() );
+        int res = strncmp( current->m_key->m_buffer, name.c_str(), name.size() );
         if( 0 == res ) {
             return current;
         }

+ 27 - 26
contrib/openddlparser/code/OpenDDLCommon.cpp

@@ -73,31 +73,14 @@ bool Text::operator == ( const Text &rhs ) const {
     return ( 0 == res );
 }
 
-Identifier::Identifier( const char buffer[], size_t len )
-: m_text( buffer, len ) {
-    // empty
-}
-
-Identifier::Identifier( const char buffer[] )
-: m_text( buffer, strlen( buffer ) ) {
-    // empty
-}
-
-Identifier::~Identifier() {
-    // empty
-}
-
-bool Identifier::operator == ( const Identifier &rhs ) const {
-    return m_text == rhs.m_text;
-}
-
-Name::Name( NameType type, Identifier *id )
+Name::Name( NameType type, Text *id )
 : m_type( type )
 , m_id( id ) {
     // empty
 }
 
 Name::~Name() {
+    delete m_id;
     m_id = ddl_nullptr;
 }
 
@@ -110,10 +93,12 @@ Reference::Reference()
 Reference::Reference( size_t numrefs, Name **names )
 : m_numRefs( numrefs )
 , m_referencedName( ddl_nullptr ) {
-    m_referencedName = new Name *[ numrefs ];
-    for( size_t i = 0; i < numrefs; i++ ) {
-        Name *name = new Name( names[ i ]->m_type, names[ i ]->m_id );
-        m_referencedName[ i ] = name;
+    if ( numrefs > 0 ) {
+        m_referencedName = new Name *[ numrefs ];
+        for ( size_t i = 0; i < numrefs; i++ ) {
+            Name *name = new Name( names[ i ]->m_type, names[ i ]->m_id );
+            m_referencedName[ i ] = name;
+        }
     }
 }
 
@@ -125,7 +110,23 @@ Reference::~Reference() {
     m_referencedName = ddl_nullptr;
 }
 
-Property::Property( Identifier *id )
+size_t Reference::sizeInBytes() {
+    if ( 0 == m_numRefs ) {
+        return 0;
+    }
+
+    size_t size( 0 );
+    for ( size_t i = 0; i < m_numRefs; i++ ) {
+        Name *name( m_referencedName[ i ] );
+        if ( ddl_nullptr != name ) {
+            size += name->m_id->m_len;
+        }
+    }
+
+    return size;
+}
+
+Property::Property( Text *id )
 : m_key( id )
 , m_value( ddl_nullptr )
 , m_ref( ddl_nullptr )
@@ -152,7 +153,7 @@ DataArrayList::~DataArrayList() {
 }
 
 size_t DataArrayList::size() {
-    size_t result=1;
+    size_t result( 0 );
     DataArrayList *n=m_next;
     while( n!=ddl_nullptr ) {
         result++;
@@ -167,7 +168,7 @@ Context::Context()
 }
 
 Context::~Context() {
-    m_root = ddl_nullptr;
+    clear();
 }
 
 void Context::clear() {

+ 1 - 1
contrib/openddlparser/code/OpenDDLExport.cpp

@@ -256,7 +256,7 @@ bool OpenDDLExport::writeProperties( DDLNode *node, std::string &statement ) {
             } else {
                 first = false;
             }
-            statement += std::string( prop->m_key->m_text.m_buffer );
+            statement += std::string( prop->m_key->m_buffer );
             statement += " = ";
             writeValue( prop->m_value, statement );
             prop = prop->m_next;

+ 72 - 69
contrib/openddlparser/code/OpenDDLParser.cpp

@@ -97,12 +97,12 @@ static bool isUnsignedIntegerType( Value::ValueType integerType ) {
     return true;
 }
 
-static DDLNode *createDDLNode( Identifier *id, OpenDDLParser *parser ) {
+static DDLNode *createDDLNode( Text *id, OpenDDLParser *parser ) {
     if( ddl_nullptr == id || ddl_nullptr == parser ) {
         return ddl_nullptr;
     }
 
-    const std::string type( id->m_text.m_buffer );
+    const std::string type( id->m_buffer );
     DDLNode *parent( parser->top() );
     DDLNode *node = DDLNode::create( type, "", parent );
 
@@ -135,7 +135,7 @@ OpenDDLParser::OpenDDLParser()
     // empty
 }
 
-OpenDDLParser::OpenDDLParser( char *buffer, size_t len )
+OpenDDLParser::OpenDDLParser( const char *buffer, size_t len )
 : m_logCallback( &logMessage )
 , m_buffer()
 , m_context( ddl_nullptr ) {
@@ -162,7 +162,7 @@ OpenDDLParser::logCallback OpenDDLParser::getLogCallback() const {
     return m_logCallback;
 }
 
-void OpenDDLParser::setBuffer( char *buffer, size_t len ) {
+void OpenDDLParser::setBuffer( const char *buffer, size_t len ) {
     clear();
     if( 0 == len ) {
         return;
@@ -192,7 +192,7 @@ size_t OpenDDLParser::getBufferSize() const {
 
 void OpenDDLParser::clear() {
     m_buffer.resize( 0 );
-    if( m_context ) {
+    if( ddl_nullptr != m_context ) {
         m_context->m_root = ddl_nullptr;
     }
 
@@ -255,7 +255,7 @@ char *OpenDDLParser::parseHeader( char *in, char *end ) {
         return in;
     }
 
-    Identifier *id( ddl_nullptr );
+    Text *id( ddl_nullptr );
     in = OpenDDLParser::parseIdentifier( in, end, &id );
 
 #ifdef DEBUG_HEADER_NAME
@@ -263,33 +263,7 @@ char *OpenDDLParser::parseHeader( char *in, char *end ) {
 #endif // DEBUG_HEADER_NAME
 
     in = lookForNextToken( in, end );
-    Property *first( ddl_nullptr );
     if( ddl_nullptr != id ) {
-        if( *in == Grammar::OpenPropertyToken[ 0 ] ) {
-            in++;
-            Property *prop( ddl_nullptr ), *prev( ddl_nullptr );
-            while( *in != Grammar::ClosePropertyToken[ 0 ] && in != end ) {
-                in = OpenDDLParser::parseProperty( in, end, &prop );
-                in = lookForNextToken( in, end );
-
-                if( *in != Grammar::CommaSeparator[ 0 ] && *in != Grammar::ClosePropertyToken[ 0 ] ) {
-                    logInvalidTokenError( in, Grammar::ClosePropertyToken, m_logCallback );
-                    return ddl_nullptr;
-                }
-
-                if( ddl_nullptr != prop && *in != Grammar::CommaSeparator[ 0 ] ) {
-                    if( ddl_nullptr == first ) {
-                        first = prop;
-                    }
-                    if( ddl_nullptr != prev ) {
-                        prev->m_next = prop;
-                    }
-                    prev = prop;
-                }
-            }
-            in++;
-        }
-
         // store the node
         DDLNode *node( createDDLNode( id, this ) );
         if( ddl_nullptr != node ) {
@@ -298,17 +272,44 @@ char *OpenDDLParser::parseHeader( char *in, char *end ) {
             std::cerr << "nullptr returned by creating DDLNode." << std::endl;
         }
 
-        // set the properties
-        if( ddl_nullptr != first && ddl_nullptr != node ) {
-            node->setProperties( first );
-        }
-
-        Name *name( ddl_nullptr );
-        in = OpenDDLParser::parseName( in, end, &name );
+		Name *name(ddl_nullptr);
+		in = OpenDDLParser::parseName(in, end, &name);
         if( ddl_nullptr != name && ddl_nullptr != node ) {
-            const std::string nodeName( name->m_id->m_text.m_buffer );
+            const std::string nodeName( name->m_id->m_buffer );
             node->setName( nodeName );
         }
+
+		Property *first(ddl_nullptr);
+		in = lookForNextToken(in, end);
+		if (*in == Grammar::OpenPropertyToken[0]) {
+			in++;
+			Property *prop(ddl_nullptr), *prev(ddl_nullptr);
+			while (*in != Grammar::ClosePropertyToken[0] && in != end) {
+				in = OpenDDLParser::parseProperty(in, end, &prop);
+				in = lookForNextToken(in, end);
+
+				if (*in != Grammar::CommaSeparator[0] && *in != Grammar::ClosePropertyToken[0]) {
+					logInvalidTokenError(in, Grammar::ClosePropertyToken, m_logCallback);
+					return ddl_nullptr;
+				}
+
+				if (ddl_nullptr != prop && *in != Grammar::CommaSeparator[0]) {
+					if (ddl_nullptr == first) {
+						first = prop;
+					}
+					if (ddl_nullptr != prev) {
+						prev->m_next = prop;
+					}
+					prev = prop;
+				}
+			}
+			in++;
+		}
+
+		// set the properties
+		if (ddl_nullptr != first && ddl_nullptr != node) {
+			node->setProperties(first);
+		}
     }
 
     return in;
@@ -499,7 +500,7 @@ char *OpenDDLParser::parseName( char *in, char *end, Name **name ) {
     }
     in++;
     Name *currentName( ddl_nullptr );
-    Identifier *id( ddl_nullptr );
+    Text *id( ddl_nullptr );
     in = parseIdentifier( in, end, &id );
     if( id ) {
         currentName = new Name( ntype, id );
@@ -511,7 +512,7 @@ char *OpenDDLParser::parseName( char *in, char *end, Name **name ) {
     return in;
 }
 
-char *OpenDDLParser::parseIdentifier( char *in, char *end, Identifier **id ) {
+char *OpenDDLParser::parseIdentifier( char *in, char *end, Text **id ) {
     *id = ddl_nullptr;
     if( ddl_nullptr == in || in == end ) {
         return in;
@@ -534,7 +535,7 @@ char *OpenDDLParser::parseIdentifier( char *in, char *end, Identifier **id ) {
     }
 
     const size_t len( idLen );
-    Identifier *newId = new Identifier( start, len );
+    Text *newId = new Text( start, len );
     *id = newId;
 
     return in;
@@ -715,6 +716,11 @@ char *OpenDDLParser::parseFloatingLiteral( char *in, char *end, Value **floating
 
     // parse the float value
     bool ok( false );
+    if ( isHexLiteral( start, end ) ) {
+        parseHexaLiteral( start, end, floating );
+        return in;
+    }
+
     if( isNumeric( *start ) ) {
         ok = true;
     } else {
@@ -767,7 +773,7 @@ char *OpenDDLParser::parseStringLiteral( char *in, char *end, Value **stringData
     return in;
 }
 
-static void createPropertyWithData( Identifier *id, Value *primData, Property **prop ) {
+static void createPropertyWithData( Text *id, Value *primData, Property **prop ) {
     if( ddl_nullptr != primData ) {
         ( *prop ) = new Property( id );
         ( *prop )->m_value = primData;
@@ -830,7 +836,7 @@ char *OpenDDLParser::parseProperty( char *in, char *end, Property **prop ) {
     }
 
     in = lookForNextToken( in, end );
-    Identifier *id( ddl_nullptr );
+    Text *id( ddl_nullptr );
     in = parseIdentifier( in, end, &id );
     if( ddl_nullptr != id ) {
         in = lookForNextToken( in, end );
@@ -847,7 +853,7 @@ char *OpenDDLParser::parseProperty( char *in, char *end, Property **prop ) {
             } else if( isStringLiteral( *in ) ) { // string data
                 in = parseStringLiteral( in, end, &primData );
                 createPropertyWithData( id, primData, prop );
-            } else {                          // reference data
+            } else {                              // reference data
                 std::vector<Name*> names;
                 in = parseReference( in, end, names );
                 if( !names.empty() ) {
@@ -862,7 +868,8 @@ char *OpenDDLParser::parseProperty( char *in, char *end, Property **prop ) {
     return in;
 }
 
-char *OpenDDLParser::parseDataList( char *in, char *end, Value::ValueType type, Value **data, size_t &numValues, Reference **refs, size_t &numRefs ) {
+char *OpenDDLParser::parseDataList( char *in, char *end, Value::ValueType type, Value **data, 
+                                    size_t &numValues, Reference **refs, size_t &numRefs ) {
     *data = ddl_nullptr;
     numValues = numRefs = 0;
     if( ddl_nullptr == in || in == end ) {
@@ -876,28 +883,24 @@ char *OpenDDLParser::parseDataList( char *in, char *end, Value::ValueType type,
         while( '}' != *in ) {
             current = ddl_nullptr;
             in = lookForNextToken( in, end );
-            if (Value::ddl_none == type) {
+            if ( Value::ddl_ref == type ) {
+                std::vector<Name*> names;
+                in = parseReference( in, end, names );
+                if ( !names.empty() ) {
+                    Reference *ref = new Reference( names.size(), &names[ 0 ] );
+                    *refs = ref;
+                    numRefs = names.size();
+                }
+            } else  if ( Value::ddl_none == type ) {
                 if (isInteger( in, end )) {
                     in = parseIntegerLiteral( in, end, &current );
-                }
-                else if (isFloat( in, end )) {
+                } else if (isFloat( in, end )) {
                     in = parseFloatingLiteral( in, end, &current );
-                }
-                else if (isStringLiteral( *in )) {
+                } else if (isStringLiteral( *in )) {
                     in = parseStringLiteral( in, end, &current );
-                }
-                else if (isHexLiteral( in, end )) {
+                } else if (isHexLiteral( in, end )) {
                     in = parseHexaLiteral( in, end, &current );
                 }
-                else {                          // reference data
-                    std::vector<Name*> names;
-                    in = parseReference( in, end, names );
-                    if (!names.empty()) {
-                        Reference *ref = new Reference( names.size(), &names[ 0 ] );
-                        *refs = ref;
-                        numRefs = names.size();
-                    }
-                }
             } else {
                 switch(type){
                     case Value::ddl_int8:
@@ -951,10 +954,10 @@ static DataArrayList *createDataArrayList( Value *currentValue, size_t numValues
     dataList->m_numItems = numValues;
 
     return dataList;
-
 }
-char *OpenDDLParser::parseDataArrayList( char *in, char *end,Value::ValueType type, DataArrayList **dataList ) {
-    *dataList = ddl_nullptr;
+
+char *OpenDDLParser::parseDataArrayList( char *in, char *end,Value::ValueType type, DataArrayList **dataArrayList ) {
+    *dataArrayList = ddl_nullptr;
     if( ddl_nullptr == in || in == end ) {
         return in;
     }
@@ -970,10 +973,10 @@ char *OpenDDLParser::parseDataArrayList( char *in, char *end,Value::ValueType ty
             currentValue = ddl_nullptr;
 
             in = parseDataList( in, end, type, &currentValue, numValues, &refs, numRefs );
-            if( ddl_nullptr != currentValue ) {
+            if( ddl_nullptr != currentValue || 0 != numRefs ) {
                 if( ddl_nullptr == prev ) {
-                    *dataList = createDataArrayList( currentValue, numValues );
-                    prev = *dataList;
+                    *dataArrayList = createDataArrayList( currentValue, numValues );
+                    prev = *dataArrayList;
                 } else {
                     currentDataList = createDataArrayList( currentValue, numValues );
                     if( ddl_nullptr != prev ) {

+ 85 - 51
contrib/openddlparser/code/Value.cpp

@@ -240,10 +240,16 @@ void Value::setDouble( double value ) {
 }
 
 double Value::getDouble() const {
-    assert( ddl_double == m_type );
-    double v;
-    ::memcpy( &v, m_data, m_size );
-    return v;
+    if ( m_type == ddl_double ) {
+        double v;
+        ::memcpy( &v, m_data, m_size );
+        return ( float ) v;
+    }
+    else {
+        double tmp;
+        ::memcpy( &tmp, m_data, 4 );
+        return ( double ) tmp;
+    }
 }
 
 void Value::setString( const std::string &str ) {
@@ -251,60 +257,88 @@ void Value::setString( const std::string &str ) {
     ::memcpy( m_data, str.c_str(), str.size() );
     m_data[ str.size() ] = '\0';
 }
+
 const char *Value::getString() const {
     assert( ddl_string == m_type );
     return (const char*) m_data;
 }
 
+void Value::setRef( Reference *ref ) {
+    assert( ddl_ref == m_type );
+
+    if ( ddl_nullptr != ref ) {
+        const size_t sizeInBytes( ref->sizeInBytes() );
+        if ( sizeInBytes > 0 ) {
+            if ( ddl_nullptr != m_data ) {
+                delete [] m_data;
+            }
+
+            m_data = new unsigned char[ sizeof( Reference ) ];
+            Reference *myRef = ( Reference * ) m_data;
+            myRef->m_numRefs = ref->m_numRefs;
+            myRef->m_referencedName =  new Name *[ myRef->m_numRefs ];
+            for ( size_t i = 0; i < myRef->m_numRefs; i++ ) {
+                myRef->m_referencedName[ i ] = new Name( ref->m_referencedName[ i ]->m_type, ref->m_referencedName[ i ]->m_id );
+            }
+        }
+    }
+}
+
+Reference *Value::getRef() const {
+    assert( ddl_ref == m_type );
+
+    return (Reference*) m_data;
+}
+
 void Value::dump() {
     switch( m_type ) {
-    case ddl_none:
-        std::cout << "None" << std::endl;
-        break;
-    case ddl_bool:
-        std::cout << getBool() << std::endl;
-        break;
-    case ddl_int8:
-        std::cout << getInt8() << std::endl;
-        break;
-    case ddl_int16:
-        std::cout << getInt16() << std::endl;
-        break;
-    case ddl_int32:
-        std::cout << getInt32() << std::endl;
-        break;
-    case ddl_int64:
-        std::cout << getInt64() << std::endl;
-        break;
-    case ddl_unsigned_int8:
-        std::cout << "Not supported" << std::endl;
-        break;
-    case ddl_unsigned_int16:
-        std::cout << "Not supported" << std::endl;
-        break;
-    case ddl_unsigned_int32:
-        std::cout << "Not supported" << std::endl;
-        break;
-    case ddl_unsigned_int64:
-        std::cout << "Not supported" << std::endl;
-        break;
-    case ddl_half:
-        std::cout << "Not supported" << std::endl;
-        break;
-    case ddl_float:
-        std::cout << getFloat() << std::endl;
-        break;
-    case ddl_double:
-        std::cout << getDouble() << std::endl;
-        break;
-    case ddl_string:
-        std::cout << "Not supported" << std::endl;
-        break;
-    case ddl_ref:
-        std::cout << "Not supported" << std::endl;
-        break;
-    default:
-        break;
+        case ddl_none:
+            std::cout << "None" << std::endl;
+            break;
+        case ddl_bool:
+            std::cout << getBool() << std::endl;
+            break;
+        case ddl_int8:
+            std::cout << getInt8() << std::endl;
+            break;
+        case ddl_int16:
+            std::cout << getInt16() << std::endl;
+            break;
+        case ddl_int32:
+            std::cout << getInt32() << std::endl;
+            break;
+        case ddl_int64:
+            std::cout << getInt64() << std::endl;
+            break;
+        case ddl_unsigned_int8:
+            std::cout << "Not supported" << std::endl;
+            break;
+        case ddl_unsigned_int16:
+            std::cout << "Not supported" << std::endl;
+            break;
+        case ddl_unsigned_int32:
+            std::cout << "Not supported" << std::endl;
+            break;
+        case ddl_unsigned_int64:
+            std::cout << "Not supported" << std::endl;
+            break;
+        case ddl_half:
+            std::cout << "Not supported" << std::endl;
+            break;
+        case ddl_float:
+            std::cout << getFloat() << std::endl;
+            break;
+        case ddl_double:
+            std::cout << getDouble() << std::endl;
+            break;
+        case ddl_string:
+            std::cout << getString() << std::endl;
+            break;
+        case ddl_ref:
+            std::cout << "Not supported" << std::endl;
+            break;
+        default:
+            break;
     }
 }
 

+ 2 - 2
contrib/openddlparser/include/openddlparser/DDLNode.h

@@ -144,8 +144,8 @@ public:
 private:
     DDLNode( const std::string &type, const std::string &name, size_t idx, DDLNode *parent = ddl_nullptr );
     DDLNode();
-    DDLNode( const DDLNode & );
-    DDLNode &operator = ( const DDLNode & );
+    DDLNode( const DDLNode & ) ddl_no_copy;
+    DDLNode &operator = ( const DDLNode & ) ddl_no_copy;
     static void releaseNodes();
 
 private:

+ 11 - 31
contrib/openddlparser/include/openddlparser/OpenDDLCommon.h

@@ -32,7 +32,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #  include <inttypes.h>
 #endif
 
-#ifdef _MSC_VER
+#if defined(_MSC_VER) && !defined( OPENDDL_STATIC_LIBARY )
+
 #   define TAG_DLL_EXPORT __declspec(dllexport)
 #   define TAG_DLL_IMPORT __declspec(dllimport )
 #   ifdef OPENDDLPARSER_BUILD
@@ -132,31 +133,6 @@ private:
     Text &operator = ( const Text & ) ddl_no_copy;
 };
 
-///	@brief  Stores an OpenDDL-specific identifier type.
-struct DLL_ODDLPARSER_EXPORT Identifier {
-    Text m_text;    ///< The text element.
-
-    ///	@brief  The constructor with a sized buffer full of characters.
-    ///	@param  buffer  [in] The identifier buffer.
-    ///	@param  len     [in] The length of the buffer
-    Identifier( const char buffer[], size_t len );
-
-    ///	@brief  The constructor with a buffer full of characters.
-    ///	@param  buffer  [in] The identifier buffer.
-    /// @remark Buffer must be null-terminated.
-    Identifier( const char buffer[] );
-
-    ///	@brief  The destructor.
-    ~Identifier();
-
-    ///	@brief  The compare operator.
-    bool operator == ( const Identifier &rhs ) const;
-
-private:
-    Identifier( const Identifier & ) ddl_no_copy;
-    Identifier &operator = ( const Identifier & ) ddl_no_copy;
-};
-
 ///	@brief  Description of the type of a name.
 enum NameType {
     GlobalName, ///< Name is global.
@@ -166,12 +142,12 @@ enum NameType {
 ///	@brief  Stores an OpenDDL-specific name
 struct DLL_ODDLPARSER_EXPORT Name {
     NameType    m_type; ///< The type of the name ( @see NameType ).
-    Identifier *m_id;   ///< The id.
+    Text        *m_id;  ///< The id.
 
     ///	@brief  The constructor with the type and the id.
     ///	@param  type    [in] The name type.
     ///	@param  id      [in] The id.
-    Name( NameType type, Identifier *id );
+    Name( NameType type, Text *id );
 
     ///	@brief  The destructor.
     ~Name();
@@ -197,6 +173,10 @@ struct DLL_ODDLPARSER_EXPORT Reference {
     ///	@brief  The destructor.
     ~Reference();
 
+    /// @brief  Returns the size in bytes to store one deep reference copy.
+    /// @return The size on bytes.
+    size_t sizeInBytes();
+
 private:
     Reference( const Reference & ) ddl_no_copy;
     Reference &operator = ( const Reference & ) ddl_no_copy;
@@ -204,7 +184,7 @@ private:
 
 ///	@brief  Stores a property list.
 struct DLL_ODDLPARSER_EXPORT Property {
-    Identifier *m_key;      ///< The identifier / key of the property.
+    Text       *m_key;      ///< The identifier / key of the property.
     Value      *m_value;    ///< The value assigned to its key / id ( ddl_nullptr if none ).
     Reference  *m_ref;      ///< References assigned to its key / id ( ddl_nullptr if none ).
     Property   *m_next;     ///< The next property ( ddl_nullptr if none ).
@@ -214,7 +194,7 @@ struct DLL_ODDLPARSER_EXPORT Property {
 
     ///	@brief  The constructor for initialization.
     /// @param  id      [in] The identifier
-    Property( Identifier *id );
+    Property( Text *id );
 
     ///	@brief  The destructor.
     ~Property();
@@ -227,7 +207,7 @@ private:
 ///	@brief  Stores a data array list.
 struct DLL_ODDLPARSER_EXPORT DataArrayList {
     size_t         m_numItems;  ///< The number of items in the list.
-    Value         *m_dataList;  ///< The data list ( ee Value ).
+    Value         *m_dataList;  ///< The data list ( a Value ).
     DataArrayList *m_next;      ///< The next data array list ( ddl_nullptr if last ).
 
     ///	@brief  The default constructor for initialization.

+ 4 - 0
contrib/openddlparser/include/openddlparser/OpenDDLExport.h

@@ -93,6 +93,10 @@ protected:
     bool writeValue( Value *val, std::string &statement );
     bool writeValueArray( DataArrayList *al, std::string &statement );
 
+private:
+    OpenDDLExport( const OpenDDLExport & ) ddl_no_copy;
+    OpenDDLExport &operator = ( const OpenDDLExport  & ) ddl_no_copy;
+
 private:
     IOStreamBase *m_stream;
 };

+ 5 - 8
contrib/openddlparser/include/openddlparser/OpenDDLParser.h

@@ -63,9 +63,6 @@ inline
 T *getNextToken( T *in, T *end ) {
     T *tmp( in );
     in = lookForNextToken( in, end );
-    /*while( ( isSpace( *in ) || isNewLine( *in ) || ',' == *in ) && ( in != end ) ) {
-        in++;
-    }*/
     if( tmp == in ) {
         in++;
     }
@@ -103,7 +100,7 @@ public:
     ///	@brief  The class constructor.
     ///	@param  buffer      [in] The buffer
     ///	@param  len         [in] Size of the buffer
-    OpenDDLParser( char *buffer, size_t len );
+    OpenDDLParser( const char *buffer, size_t len );
 
     ///	@brief  The class destructor.
     ~OpenDDLParser();
@@ -119,7 +116,7 @@ public:
     ///	@brief  Assigns a new buffer to parse.
     ///	@param  buffer      [in] The buffer
     ///	@param  len         [in] Size of the buffer
-    void setBuffer( char *buffer, size_t len );
+    void setBuffer( const char *buffer, size_t len );
 
     ///	@brief  Assigns a new buffer to parse.
     /// @param  buffer      [in] The buffer as a std::vector.
@@ -161,7 +158,7 @@ public: // parser helpers
     DDLNode *top();
     static void normalizeBuffer( std::vector<char> &buffer );
     static char *parseName( char *in, char *end, Name **name );
-    static char *parseIdentifier( char *in, char *end, Identifier **id );
+    static char *parseIdentifier( char *in, char *end, Text **id );
     static char *parsePrimitiveDataType( char *in, char *end, Value::ValueType &type, size_t &len );
     static char *parseReference( char *in, char *end, std::vector<Name*> &names );
     static char *parseBooleanLiteral( char *in, char *end, Value **boolean );
@@ -175,8 +172,8 @@ public: // parser helpers
     static const char *getVersion();
 
 private:
-    OpenDDLParser( const OpenDDLParser & );
-    OpenDDLParser &operator = ( const OpenDDLParser & );
+    OpenDDLParser( const OpenDDLParser & ) ddl_no_copy;
+    OpenDDLParser &operator = ( const OpenDDLParser & ) ddl_no_copy;
 
 private:
     logCallback m_logCallback;

+ 1 - 6
contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h

@@ -84,12 +84,7 @@ static const unsigned char chartype_table[ 256 ] = {
 template<class T>
 inline
 bool isNumeric( const T in ) {
-    return ( in >= '0' && in <= '9' );
-	//return ( chartype_table[in] );
-    /*if (in >= '0' &&  in <= '9' )
-    return true;
-
-    return false;*/
+	return ( chartype_table[ in ] == 1 );
 }
 
 template<class T>

+ 13 - 5
contrib/openddlparser/include/openddlparser/Value.h

@@ -220,6 +220,14 @@ public:
     /// @return The std::string value.
     const char *getString() const;
 
+    /// @brief  Set the reference.
+    /// @param  ref     [in] Pointer showing to the reference.
+    void setRef( Reference *ref );
+
+    /// @brief  Returns the pointer showing to the reference.
+    /// @return Pointer showing to the reference.
+    Reference *getRef() const;
+
     ///	@brief  Dumps the value.
     void dump();
 
@@ -241,8 +249,8 @@ public:
     Value *m_next;
 
 private:
-    Value &operator =( const Value & );
-    Value( const Value  & );
+    Value &operator =( const Value & ) ddl_no_copy;
+    Value( const Value  & ) ddl_no_copy;
 };
 
 ///------------------------------------------------------------------------------------------------
@@ -253,9 +261,9 @@ struct DLL_ODDLPARSER_EXPORT ValueAllocator {
     static void releasePrimData( Value **data );
 
 private:
-    ValueAllocator();
-    ValueAllocator( const ValueAllocator  & );
-    ValueAllocator &operator = ( const ValueAllocator & );
+    ValueAllocator() ddl_no_copy;
+    ValueAllocator( const ValueAllocator  & ) ddl_no_copy;
+    ValueAllocator &operator = ( const ValueAllocator & ) ddl_no_copy;
 };
 
 END_ODDLPARSER_NS

+ 195 - 77
include/assimp/Compiler/pstdint.h

@@ -3,13 +3,13 @@
  *  BSD License:
  ****************************************************************************
  *
- *  Copyright (c) 2005-2007 Paul Hsieh
+ *  Copyright (c) 2005-2011 Paul Hsieh
  *  All rights reserved.
- *
+ *  
  *  Redistribution and use in source and binary forms, with or without
  *  modification, are permitted provided that the following conditions
  *  are met:
- *
+ *  
  *  1. Redistributions of source code must retain the above copyright
  *     notice, this list of conditions and the following disclaimer.
  *  2. Redistributions in binary form must reproduce the above copyright
@@ -17,7 +17,7 @@
  *     documentation and/or other materials provided with the distribution.
  *  3. The name of the author may not be used to endorse or promote products
  *     derived from this software without specific prior written permission.
- *
+ *  
  *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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.
@@ -31,7 +31,7 @@
  *
  ****************************************************************************
  *
- *  Version 0.1.10
+ *  Version 0.1.12
  *
  *  The ANSI C standard committee, for the C99 standard, specified the
  *  inclusion of a new standard include file called stdint.h.  This is
@@ -172,12 +172,15 @@
  *
  *  Acknowledgements
  *
+ *  Edited by Philip G. Lee <[email protected]> 2011 to avoid overlap with sys/types.h
+ *
  *  The following people have made significant contributions to the
  *  development and testing of this file:
  *
  *  Chris Howie
  *  John Steele Scott
  *  Dave Thorup
+ *  John Dill
  *
  */
 
@@ -190,7 +193,7 @@
  *  do nothing else.  On the Mac OS X version of gcc this is _STDINT_H_.
  */
 
-#if ((defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) || (defined (__WATCOMC__) && (defined (_STDINT_H_INCLUDED) || __WATCOMC__ >= 1250)) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_)))) && !defined (_PSTDINT_H_INCLUDED) && !defined(_STDINT)
+#if ((defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) || (defined (__WATCOMC__) && (defined (_STDINT_H_INCLUDED) || __WATCOMC__ >= 1250)) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_) || defined (__UINT_FAST64_TYPE__)) )) && !defined (_PSTDINT_H_INCLUDED)
 #include <stdint.h>
 #define _PSTDINT_H_INCLUDED
 # ifndef PRINTF_INT64_MODIFIER
@@ -300,17 +303,10 @@
  *  definitions.
  */
 
-#ifndef UINT8_MAX
-# define UINT8_MAX 0xff
-#endif
-#ifndef uint8_t
-# if (UCHAR_MAX == UINT8_MAX) || defined (S_SPLINT_S)
-    typedef unsigned char uint8_t;
-#   define UINT8_C(v) ((uint8_t) v)
-# else
-#   error "Platform not supported"
-# endif
-#endif
+
+// Avoid overlap with sys/types.h
+#ifndef __int8_t_defined
+#define __int8_t_defined
 
 #ifndef INT8_MAX
 # define INT8_MAX 0x7f
@@ -320,34 +316,13 @@
 #endif
 #ifndef int8_t
 # if (SCHAR_MAX == INT8_MAX) || defined (S_SPLINT_S)
-    typedef signed char int8_t;
+typedef signed char int8_t;
 #   define INT8_C(v) ((int8_t) v)
 # else
 #   error "Platform not supported"
 # endif
 #endif
 
-#ifndef UINT16_MAX
-# define UINT16_MAX 0xffff
-#endif
-#ifndef uint16_t
-#if (UINT_MAX == UINT16_MAX) || defined (S_SPLINT_S)
-  typedef unsigned int uint16_t;
-# ifndef PRINTF_INT16_MODIFIER
-#  define PRINTF_INT16_MODIFIER ""
-# endif
-# define UINT16_C(v) ((uint16_t) (v))
-#elif (USHRT_MAX == UINT16_MAX)
-  typedef unsigned short uint16_t;
-# define UINT16_C(v) ((uint16_t) (v))
-# ifndef PRINTF_INT16_MODIFIER
-#  define PRINTF_INT16_MODIFIER "h"
-# endif
-#else
-#error "Platform not supported"
-#endif
-#endif
-
 #ifndef INT16_MAX
 # define INT16_MAX 0x7fff
 #endif
@@ -356,13 +331,13 @@
 #endif
 #ifndef int16_t
 #if (INT_MAX == INT16_MAX) || defined (S_SPLINT_S)
-  typedef signed int int16_t;
+typedef signed int int16_t;
 # define INT16_C(v) ((int16_t) (v))
 # ifndef PRINTF_INT16_MODIFIER
 #  define PRINTF_INT16_MODIFIER ""
 # endif
 #elif (SHRT_MAX == INT16_MAX)
-  typedef signed short int16_t;
+typedef signed short int16_t;
 # define INT16_C(v) ((int16_t) (v))
 # ifndef PRINTF_INT16_MODIFIER
 #  define PRINTF_INT16_MODIFIER "h"
@@ -372,25 +347,28 @@
 #endif
 #endif
 
-#ifndef UINT32_MAX
-# define UINT32_MAX (0xffffffffUL)
+#ifndef INT32_MAX
+# define INT32_MAX (0x7fffffffL)
 #endif
-#ifndef uint32_t
-#if (ULONG_MAX == UINT32_MAX) || defined (S_SPLINT_S)
-  typedef unsigned long uint32_t;
-# define UINT32_C(v) v ## UL
+#ifndef INT32_MIN
+# define INT32_MIN INT32_C(0x80000000)
+#endif
+#ifndef int32_t
+#if ((LONG_MAX == INT32_MAX) || defined (S_SPLINT_S)) && ! defined(__FreeBSD__)
+typedef signed long int32_t;
+# define INT32_C(v) v ## L
 # ifndef PRINTF_INT32_MODIFIER
 #  define PRINTF_INT32_MODIFIER "l"
 # endif
-#elif (UINT_MAX == UINT32_MAX)
-  typedef unsigned int uint32_t;
+#elif (INT_MAX == INT32_MAX)
+typedef signed int int32_t;
+# define INT32_C(v) v
 # ifndef PRINTF_INT32_MODIFIER
 #  define PRINTF_INT32_MODIFIER ""
 # endif
-# define UINT32_C(v) v ## U
-#elif (USHRT_MAX == UINT32_MAX)
-  typedef unsigned short uint32_t;
-# define UINT32_C(v) ((unsigned short) (v))
+#elif (SHRT_MAX == INT32_MAX)
+typedef signed short int32_t;
+# define INT32_C(v) ((short) (v))
 # ifndef PRINTF_INT32_MODIFIER
 #  define PRINTF_INT32_MODIFIER ""
 # endif
@@ -399,28 +377,89 @@
 #endif
 #endif
 
-#ifndef INT32_MAX
-# define INT32_MAX (0x7fffffffL)
+// 64-bit shit seems more tricky. Philip Lee <[email protected]>
+/*
+*  The macro stdint_int64_defined is temporarily used to record
+*  whether or not 64 integer support is available.  It must be
+*  defined for any 64 integer extensions for new platforms that are
+*  added.
+*/
+#undef stdint_int64_defined
+#if (defined(__STDC__) && defined(__STDC_VERSION__)) || defined (S_SPLINT_S)
+# if (__STDC__ && __STDC_VERSION__ >= 199901L) || defined (S_SPLINT_S)
+#  define stdint_int64_defined
+typedef long long int64_t;
+# endif
 #endif
-#ifndef INT32_MIN
-# define INT32_MIN INT32_C(0x80000000)
+#if !defined (stdint_int64_defined)
+# if defined(__GNUC__)
+#  define stdint_int64_defined
+#  ifndef __FreeBSD__
+      __extension__ typedef long long int64_t;
+#  endif
+# elif defined(__MWERKS__) || defined (__SUNPRO_C) || defined (__SUNPRO_CC) || defined (__APPLE_CC__) || defined (_LONG_LONG) || defined (_CRAYC) || defined (S_SPLINT_S)
+#  define stdint_int64_defined
+typedef long long int64_t;
+# elif (defined(__WATCOMC__) && defined(__WATCOM_INT64__)) || (defined(_MSC_VER) && _INTEGRAL_MAX_BITS >= 64) || (defined (__BORLANDC__) && __BORLANDC__ > 0x460) || defined (__alpha) || defined (__DECC)
+#  define stdint_int64_defined
+typedef __int64 int64_t;
+# endif
 #endif
-#ifndef int32_t
-#if (LONG_MAX == INT32_MAX) || defined (S_SPLINT_S)
-  typedef signed long int32_t;
-# define INT32_C(v) v ## L
+
+#endif /*ifndef __int8_t_defined*/
+
+#ifndef UINT8_MAX
+# define UINT8_MAX 0xff
+#endif
+#ifndef uint8_t
+# if (UCHAR_MAX == UINT8_MAX) || defined (S_SPLINT_S)
+    typedef unsigned char uint8_t;
+#   define UINT8_C(v) ((uint8_t) v)
+# else
+#   error "Platform not supported"
+# endif
+#endif
+
+#ifndef UINT16_MAX
+# define UINT16_MAX 0xffff
+#endif
+#ifndef uint16_t
+#if (UINT_MAX == UINT16_MAX) || defined (S_SPLINT_S)
+  typedef unsigned int uint16_t;
+# ifndef PRINTF_INT16_MODIFIER
+#  define PRINTF_INT16_MODIFIER ""
+# endif
+# define UINT16_C(v) ((uint16_t) (v))
+#elif (USHRT_MAX == UINT16_MAX)
+  typedef unsigned short uint16_t;
+# define UINT16_C(v) ((uint16_t) (v))
+# ifndef PRINTF_INT16_MODIFIER
+#  define PRINTF_INT16_MODIFIER "h"
+# endif
+#else
+#error "Platform not supported"
+#endif
+#endif
+
+#ifndef UINT32_MAX
+# define UINT32_MAX (0xffffffffUL)
+#endif
+#ifndef uint32_t
+#if ((ULONG_MAX == UINT32_MAX) || defined (S_SPLINT_S)) && ! defined(__FreeBSD__)
+  typedef unsigned long uint32_t;
+# define UINT32_C(v) v ## UL
 # ifndef PRINTF_INT32_MODIFIER
 #  define PRINTF_INT32_MODIFIER "l"
 # endif
-#elif (INT_MAX == INT32_MAX)
-  typedef signed int int32_t;
-# define INT32_C(v) v
+#elif (UINT_MAX == UINT32_MAX)
+  typedef unsigned int uint32_t;
 # ifndef PRINTF_INT32_MODIFIER
 #  define PRINTF_INT32_MODIFIER ""
 # endif
-#elif (SHRT_MAX == INT32_MAX)
-  typedef signed short int32_t;
-# define INT32_C(v) ((short) (v))
+# define UINT32_C(v) v ## U
+#elif (USHRT_MAX == UINT32_MAX)
+  typedef unsigned short uint32_t;
+# define UINT32_C(v) ((unsigned short) (v))
 # ifndef PRINTF_INT32_MODIFIER
 #  define PRINTF_INT32_MODIFIER ""
 # endif
@@ -438,10 +477,11 @@
 
 #undef stdint_int64_defined
 #if (defined(__STDC__) && defined(__STDC_VERSION__)) || defined (S_SPLINT_S)
-# if (__STDC__ && __STDC_VERSION >= 199901L) || defined (S_SPLINT_S)
+# if (__STDC__ && __STDC_VERSION__ >= 199901L) || defined (S_SPLINT_S)
 #  define stdint_int64_defined
-   typedef long long int64_t;
-   typedef unsigned long long uint64_t;
+#  ifndef __FreeBSD__
+      typedef unsigned long long uint64_t;
+#  endif
 #  define UINT64_C(v) v ## ULL
 #  define  INT64_C(v) v ## LL
 #  ifndef PRINTF_INT64_MODIFIER
@@ -453,8 +493,9 @@
 #if !defined (stdint_int64_defined)
 # if defined(__GNUC__)
 #  define stdint_int64_defined
-   __extension__ typedef long long int64_t;
-   __extension__ typedef unsigned long long uint64_t;
+#  ifndef __FreeBSD__
+      __extension__ typedef unsigned long long uint64_t;
+#  endif
 #  define UINT64_C(v) v ## ULL
 #  define  INT64_C(v) v ## LL
 #  ifndef PRINTF_INT64_MODIFIER
@@ -462,7 +503,6 @@
 #  endif
 # elif defined(__MWERKS__) || defined (__SUNPRO_C) || defined (__SUNPRO_CC) || defined (__APPLE_CC__) || defined (_LONG_LONG) || defined (_CRAYC) || defined (S_SPLINT_S)
 #  define stdint_int64_defined
-   typedef long long int64_t;
    typedef unsigned long long uint64_t;
 #  define UINT64_C(v) v ## ULL
 #  define  INT64_C(v) v ## LL
@@ -471,7 +511,6 @@
 #  endif
 # elif (defined(__WATCOMC__) && defined(__WATCOM_INT64__)) || (defined(_MSC_VER) && _INTEGRAL_MAX_BITS >= 64) || (defined (__BORLANDC__) && __BORLANDC__ > 0x460) || defined (__alpha) || defined (__DECC)
 #  define stdint_int64_defined
-   typedef __int64 int64_t;
    typedef unsigned __int64 uint64_t;
 #  define UINT64_C(v) v ## UI64
 #  define  INT64_C(v) v ## I64
@@ -616,10 +655,12 @@
  *  stdint.h.
  */
 
+#ifndef __FreeBSD__
 typedef   int_least8_t   int_fast8_t;
 typedef  uint_least8_t  uint_fast8_t;
 typedef  int_least16_t  int_fast16_t;
 typedef uint_least16_t uint_fast16_t;
+#endif
 typedef  int_least32_t  int_fast32_t;
 typedef uint_least32_t uint_fast32_t;
 #define  UINT_FAST8_MAX  UINT_LEAST8_MAX
@@ -677,7 +718,7 @@ typedef uint_least32_t uint_fast32_t;
 # elif defined (__i386__) || defined (_WIN32) || defined (WIN32)
 #  define stdint_intptr_bits 32
 # elif defined (__INTEL_COMPILER)
-/* TODO -- what will Intel do about x86-64? */
+/* TODO -- what did Intel do about x86-64? */
 # endif
 
 # ifdef stdint_intptr_bits
@@ -707,8 +748,15 @@ typedef uint_least32_t uint_fast32_t;
 #  ifndef UINTPTR_C
 #    define UINTPTR_C(x)                stdint_intptr_glue3(UINT,stdint_intptr_bits,_C)(x)
 #  endif
-  typedef stdint_intptr_glue3(uint,stdint_intptr_bits,_t) uintptr_t;
-  typedef stdint_intptr_glue3( int,stdint_intptr_bits,_t)  intptr_t;
+// Philip <[email protected]>, need to check if [u]intprt_t is already defined...
+#  ifndef __uintptr_t_defined
+#    define __uintptr_t_defined
+     typedef stdint_intptr_glue3(uint,stdint_intptr_bits,_t) uintptr_t;
+#  endif /*uintptr_t*/
+#  ifndef __intptr_t_defined
+#    define __intptr_t_defined
+     typedef stdint_intptr_glue3( int,stdint_intptr_bits,_t)  intptr_t;
+#  endif /*__intptr_t_defined*/
 # else
 /* TODO -- This following is likely wrong for some platforms, and does
    nothing for the definition of uintptr_t. */
@@ -727,3 +775,73 @@ typedef uint_least32_t uint_fast32_t;
 
 #endif
 
+#if defined (__TEST_PSTDINT_FOR_CORRECTNESS)
+
+/* 
+ *  Please compile with the maximum warning settings to make sure macros are not
+ *  defined more than once.
+ */
+ 
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+ 
+#define glue3_aux(x,y,z) x ## y ## z
+#define glue3(x,y,z) glue3_aux(x,y,z)
+
+#define DECLU(bits) glue3(uint,bits,_t) glue3(u,bits,=) glue3(UINT,bits,_C) (0);
+#define DECLI(bits) glue3(int,bits,_t) glue3(i,bits,=) glue3(INT,bits,_C) (0);
+
+#define DECL(us,bits) glue3(DECL,us,) (bits)
+
+#define TESTUMAX(bits) glue3(u,bits,=) glue3(~,u,bits); if (glue3(UINT,bits,_MAX) glue3(!=,u,bits)) printf ("Something wrong with UINT%d_MAX\n", bits)
+ 
+int main () {
+   DECL(I,8)
+   DECL(U,8)
+   DECL(I,16)
+   DECL(U,16)
+   DECL(I,32)
+   DECL(U,32)
+#ifdef INT64_MAX
+   DECL(I,64)
+   DECL(U,64)
+#endif
+   intmax_t imax = INTMAX_C(0);
+   uintmax_t umax = UINTMAX_C(0);
+   char str0[256], str1[256];
+
+   sprintf (str0, "%d %x\n", 0, ~0);
+   
+   sprintf (str1, "%d %x\n",  i8, ~0);
+   if (0 != strcmp (str0, str1)) printf ("Something wrong with i8 : %s\n", str1);
+   sprintf (str1, "%u %x\n",  u8, ~0);
+   if (0 != strcmp (str0, str1)) printf ("Something wrong with u8 : %s\n", str1);
+   sprintf (str1, "%d %x\n",  i16, ~0);
+   if (0 != strcmp (str0, str1)) printf ("Something wrong with i16 : %s\n", str1);
+   sprintf (str1, "%u %x\n",  u16, ~0);
+   if (0 != strcmp (str0, str1)) printf ("Something wrong with u16 : %s\n", str1);  
+   sprintf (str1, "%" PRINTF_INT32_MODIFIER "d %x\n",  i32, ~0);
+   if (0 != strcmp (str0, str1)) printf ("Something wrong with i32 : %s\n", str1);
+   sprintf (str1, "%" PRINTF_INT32_MODIFIER "u %x\n",  u32, ~0);
+   if (0 != strcmp (str0, str1)) printf ("Something wrong with u32 : %s\n", str1);
+#ifdef INT64_MAX  
+   sprintf (str1, "%" PRINTF_INT64_MODIFIER "d %x\n",  i64, ~0);
+   if (0 != strcmp (str0, str1)) printf ("Something wrong with i64 : %s\n", str1);
+#endif
+   sprintf (str1, "%" PRINTF_INTMAX_MODIFIER "d %x\n",  imax, ~0);
+   if (0 != strcmp (str0, str1)) printf ("Something wrong with imax : %s\n", str1);
+   sprintf (str1, "%" PRINTF_INTMAX_MODIFIER "u %x\n",  umax, ~0);
+   if (0 != strcmp (str0, str1)) printf ("Something wrong with umax : %s\n", str1); 
+   
+   TESTUMAX(8);
+   TESTUMAX(16);
+   TESTUMAX(32);
+#ifdef INT64_MAX
+   TESTUMAX(64);
+#endif
+
+   return EXIT_SUCCESS;
+}
+
+#endif

+ 12 - 2
include/assimp/color4.h

@@ -86,7 +86,12 @@ public:
 public:
 
     // Red, green, blue and alpha color values
-    TReal r, g, b, a;
+    union {
+        struct {
+            TReal r, g, b, a;
+        };
+        TReal c[ 4 ];
+    };
 } PACK_STRUCT;  // !struct aiColor4D
 
 typedef aiColor4t<float> aiColor4D;
@@ -94,7 +99,12 @@ typedef aiColor4t<float> aiColor4D;
 #else
 
 struct aiColor4D {
-    float r, g, b, a;
+    union {
+        struct {
+            float r, g, b, a;
+        };
+        float c[ 4 ];
+    };
 } PACK_STRUCT;
 
 #endif // __cplusplus

+ 19 - 9
include/assimp/matrix3x3.h

@@ -161,10 +161,15 @@ public:
 
 public:
 
-
-    TReal a1, a2, a3;
-    TReal b1, b2, b3;
-    TReal c1, c2, c3;
+    union {
+        struct {
+            TReal a1, a2, a3;
+            TReal b1, b2, b3;
+            TReal c1, c2, c3;
+        };
+        TReal m[ 3 ][ 3 ];
+        TReal mData[ 9 ];
+    };
 } PACK_STRUCT;
 
 typedef aiMatrix3x3t<float> aiMatrix3x3;
@@ -172,13 +177,18 @@ typedef aiMatrix3x3t<float> aiMatrix3x3;
 #else
 
 struct aiMatrix3x3 {
-
-    float a1, a2, a3;
-    float b1, b2, b3;
-    float c1, c2, c3;
+    union {
+        struct {
+            float a1, a2, a3;
+            float b1, b2, b3;
+            float c1, c2, c3;
+        };
+        float m[ 3 ][ 3 ];
+        float mData[ 9 ];
+    };
 } PACK_STRUCT;
 
-#endif
+#endif // __cplusplus
 
 #include "./Compiler/poppack1.h"
 

+ 23 - 13
include/assimp/matrix4x4.h

@@ -213,8 +213,8 @@ public:
     /** @brief A function for creating a rotation matrix that rotates a
      *  vector called "from" into another vector called "to".
      * Input : from[3], to[3] which both must be *normalized* non-zero vectors
-     * Output: mtx[3][3] -- a 3x3 matrix in colum-major form
-     * Authors: Tomas Mller, John Hughes
+     * Output: mtx[3][3] -- a 3x3 matrix in column-major form
+     * Authors: Tomas Mueller, John Hughes
      *          "Efficiently Building a Matrix to Rotate One Vector to Another"
      *          Journal of Graphics Tools, 4(4):1-4, 1999
      */
@@ -222,12 +222,16 @@ public:
         const aiVector3t<TReal>& to, aiMatrix4x4t& out);
 
 public:
-
-    TReal a1, a2, a3, a4;
-    TReal b1, b2, b3, b4;
-    TReal c1, c2, c3, c4;
-    TReal d1, d2, d3, d4;
-
+    union {
+        struct {
+            TReal a1, a2, a3, a4;
+            TReal b1, b2, b3, b4;
+            TReal c1, c2, c3, c4;
+            TReal d1, d2, d3, d4;
+        };
+        TReal m[ 4 ][ 4 ];
+        TReal mData[ 16 ];
+    };
 } PACK_STRUCT;
 
 typedef aiMatrix4x4t<float> aiMatrix4x4;
@@ -235,11 +239,17 @@ typedef aiMatrix4x4t<float> aiMatrix4x4;
 #else
 
 struct aiMatrix4x4 {
-    float a1, a2, a3, a4;
-    float b1, b2, b3, b4;
-    float c1, c2, c3, c4;
-    float d1, d2, d3, d4;
-};
+    union {
+        struct {
+            float a1, a2, a3, a4;
+            float b1, b2, b3, b4;
+            float c1, c2, c3, c4;
+            float d1, d2, d3, d4;
+        };
+        float m[ 4 ][ 4 ];
+        float mData[ 16 ];
+    };
+} PACK_STRUCT;
 
 
 #endif // __cplusplus

+ 11 - 11
include/assimp/port/AndroidJNI/AndroidJNIIOSystem.h

@@ -2,11 +2,11 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2012, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
-Redistribution and use of this software in source and binary forms, 
-with or without modification, are permitted provided that the 
+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
@@ -23,16 +23,16 @@ following conditions are met:
   derived from this software without specific prior
   written permission of the assimp team.
 
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+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 
+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 
+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 
+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.
 
 ----------------------------------------------------------------------
@@ -54,7 +54,7 @@ namespace Assimp	{
 
 // ---------------------------------------------------------------------------
 /** Android extension to DefaultIOSystem using the standard C file functions */
-class AndroidJNIIOSystem : public DefaultIOSystem
+class ASSIMP_API AndroidJNIIOSystem : public DefaultIOSystem
 {
 public:
 

+ 13 - 2
include/assimp/vector2.h

@@ -95,7 +95,13 @@ public:
     template <typename TOther>
     operator aiVector2t<TOther> () const;
 
-    TReal x, y;
+    union {
+        struct {
+            TReal x, y;
+        };
+        TReal v[ 2 ];
+    };
+
 } PACK_STRUCT;
 
 typedef aiVector2t<float> aiVector2D;
@@ -103,7 +109,12 @@ typedef aiVector2t<float> aiVector2D;
 #else
 
 struct aiVector2D {
-    float x,y;
+    union {
+        struct {
+            float x, y;
+        };
+        float v[ 2 ];
+    };
 };
 
 #endif // __cplusplus

+ 12 - 3
include/assimp/vector3.h

@@ -125,7 +125,12 @@ public:
      *  @param o Second factor */
     const aiVector3t SymMul(const aiVector3t& o);
 
-    TReal x, y, z;
+    union {
+        struct {
+            TReal x, y, z;
+        };
+        TReal v[ 3 ];
+    };
 } PACK_STRUCT;
 
 
@@ -134,8 +139,12 @@ typedef aiVector3t<float> aiVector3D;
 #else
 
 struct aiVector3D {
-
-    float x,y,z;
+    union {
+        struct {
+            float x, y, z;
+        };
+        float v[ 3 ];
+    };
 } PACK_STRUCT;
 
 #endif // __cplusplus

+ 12 - 12
port/AndroidJNI/AndroidJNIIOSystem.cpp

@@ -3,12 +3,12 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2012, assimp team
+Copyright (c) 2006-2016, assimp 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 
+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
@@ -25,16 +25,16 @@ conditions are met:
   derived from this software without specific prior
   written permission of the assimp team.
 
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+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 
+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 
+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 
+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.
 ---------------------------------------------------------------------------
 */
@@ -59,14 +59,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 using namespace Assimp;
 
 // ------------------------------------------------------------------------------------------------
-// Constructor. 
+// Constructor.
 AndroidJNIIOSystem::AndroidJNIIOSystem(ANativeActivity* activity)
 {
 	AndroidActivityInit(activity);
 }
 
 // ------------------------------------------------------------------------------------------------
-// Destructor. 
+// Destructor.
 AndroidJNIIOSystem::~AndroidJNIIOSystem()
 {
 	// nothing to do here

+ 11 - 13
port/AndroidJNI/README.txt → port/AndroidJNI/README.md

@@ -1,27 +1,25 @@
---- Description ---
-
-This module provides a facade to io stream access to files
-behind android asset manager within Android native application.
+Build Asset Importer Lib for Android
+====================================
+This module provides a fascade for the io-stream-access to files behind the
+android-asset-management within an Android native application.
 - It is built as a static library
 - It requires Android NDK with android API > 9 support.
 
---- Building ---
-
+### Building ###
 To use this module please provide following cmake defines:
-
+```
 -DASSIMP_ANDROID_JNIIOSYSTEM=ON
 -DCMAKE_TOOLCHAIN_FILE=$SOME_PATH/android.toolchain.cmake
+```
 
 "SOME_PATH" is a path to your cmake android toolchain script.
 
---- Code ---
-
+### Code ###
+A small example how to wrap assimp for Android:
+```cpp
 #include <assimp/port/AndroidJNI/AndroidJNIIOSystem.h>
 
-...
-
 Assimp::Importer* importer = new Assimp::Importer();
 Assimp::AndroidJNIIOSystem* ioSystem = new Assimp::AndroidJNIIOSystem(app->activity);
 importer->SetIOHandler(ioSystem);
-
-...
+```

+ 40 - 0
scripts/appveyor/compiler_setup.bat

@@ -0,0 +1,40 @@
+@echo off
+
+:: Now we declare a scope
+Setlocal EnableDelayedExpansion EnableExtensions
+
+if not defined Configuration set Configuration=2015
+
+if "%Configuration%"=="MinGW" ( goto :mingw )
+
+set arch=x86
+
+if "%platform%" EQU "x64" ( set arch=x86_amd64 )
+
+if "%Configuration%"=="2015" (
+	set SET_VS_ENV="C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"
+)
+
+if "%Configuration%"=="2013" (
+	set SET_VS_ENV="C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat"
+)
+
+if "%Configuration%"=="2012" (
+	set SET_VS_ENV="C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\vcvarsall.bat"
+)
+
+if "%Configuration%"=="2010" (
+	set SET_VS_ENV="C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat"
+)
+
+if "%Configuration%"=="2008" (
+	set SET_VS_ENV="C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcvarsall.bat"
+)
+
+:: Visual Studio detected
+endlocal & call %SET_VS_ENV% %arch%
+goto :eof
+
+:: MinGW detected
+:mingw
+endlocal & set PATH=c:\mingw\bin;%PATH%

+ 14 - 13
test/CMakeLists.txt

@@ -44,26 +44,27 @@ SET( TEST_SRCS
   unit/utNoBoostTest.cpp
   unit/utColladaExportCamera.cpp
   unit/utColladaExportLight.cpp
+  unit/utIssues.cpp
 )
 
 SOURCE_GROUP( tests FILES  ${TEST_SRCS} )
 
 if(AddGTest_FOUND)
-add_executable( unit
-  unit/CCompilerTest.c
-  unit/Main.cpp
-  ../code/Version.cpp
-  ${TEST_SRCS}
-)
+    add_executable( unit
+      unit/CCompilerTest.c
+      unit/Main.cpp
+      ../code/Version.cpp
+      ${TEST_SRCS}
+    )
 
-add_definitions(-DASSIMP_TEST_MODELS_DIR="${CMAKE_CURRENT_LIST_DIR}/models")
+    add_definitions(-DASSIMP_TEST_MODELS_DIR="${CMAKE_CURRENT_LIST_DIR}/models")
 
-SET_PROPERTY( TARGET assimp PROPERTY DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX} )
+    SET_PROPERTY( TARGET assimp PROPERTY DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX} )
 
-add_dependencies( unit gtest )
-target_link_libraries( unit assimp
-  debug ${GTEST_DEBUG_LIBRARIES}
-  optimized ${GTEST_RELEASE_LIBRARIES}
-)
+    add_dependencies( unit gtest )
+    target_link_libraries( unit assimp
+      debug ${GTEST_DEBUG_LIBRARIES}
+      optimized ${GTEST_RELEASE_LIBRARIES}
+    )
 endif(AddGTest_FOUND)
 add_subdirectory(headercheck)

Разница между файлами не показана из-за своего большого размера
+ 61 - 0
test/models/Collada/library_animation_clips.dae


+ 28 - 0
test/models/OBJ/box_without_lineending.obj

@@ -0,0 +1,28 @@
+#	                Vertices: 8
+#	                  Points: 0
+#	                   Lines: 0
+#	                   Faces: 6
+#	               Materials: 1
+
+o 1
+
+# Vertex list
+
+v -0.5 -0.5 0.5
+v -0.5 -0.5 -0.5
+v -0.5 0.5 -0.5
+v -0.5 0.5 0.5
+v 0.5 -0.5 0.5
+v 0.5 -0.5 -0.5
+v 0.5 0.5 -0.5
+v 0.5 0.5 0.5
+
+# Point/Line/Face list
+
+usemtl Default
+f 4 3 2 1
+f 2 6 5 1
+f 3 7 6 2
+f 8 7 3 4
+f 5 8 4 1
+f 6 7 8 5

+ 109 - 0
test/unit/utIssues.cpp

@@ -0,0 +1,109 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2016, assimp 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 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.
+---------------------------------------------------------------------------
+*/
+#include "UnitTestPCH.h"
+
+#include <assimp/scene.h>
+#include <assimp/Importer.hpp>
+#include <assimp/Exporter.hpp>
+
+using namespace Assimp;
+
+class utIssues : public ::testing::Test {
+
+};
+
+#ifndef ASSIMP_BUILD_NO_EXPORT
+
+TEST_F( utIssues, OpacityBugWhenExporting_727 ) {
+    aiScene *scene( new aiScene );
+
+    scene->mNumMaterials = 1;
+    scene->mMaterials = new aiMaterial*;
+    scene->mMaterials[ 0 ] = new aiMaterial;
+    aiColor3D color( 1, 0, 0 );
+    EXPECT_EQ( AI_SUCCESS, scene->mMaterials[ 0 ]->AddProperty( &color, 1, AI_MATKEY_COLOR_DIFFUSE ) );
+
+    ::srand( static_cast<unsigned int>( ::time( NULL ) ) );
+    float opacity( float( rand() ) / float( RAND_MAX ) );
+    EXPECT_EQ( AI_SUCCESS, scene->mMaterials[ 0 ]->AddProperty( &opacity, 1, AI_MATKEY_OPACITY ) );
+
+    scene->mNumMeshes = 1;
+    scene->mMeshes = new aiMesh*;
+    scene->mMeshes[ 0 ] = new aiMesh;
+    scene->mMeshes[ 0 ]->mMaterialIndex = 0;
+    scene->mMeshes[ 0 ]->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
+    scene->mMeshes[ 0 ]->mNumVertices = 3;
+    scene->mMeshes[ 0 ]->mVertices = new aiVector3D[ 3 ];
+    scene->mMeshes[ 0 ]->mVertices[ 0 ] = aiVector3D( 1, 0, 0 );
+    scene->mMeshes[ 0 ]->mVertices[ 1 ] = aiVector3D( 0, 1, 0 );
+    scene->mMeshes[ 0 ]->mVertices[ 2 ] = aiVector3D( 0, 0, 1 );
+    scene->mMeshes[ 0 ]->mNumFaces = 1;
+    scene->mMeshes[ 0 ]->mFaces = new aiFace;
+    scene->mMeshes[ 0 ]->mFaces[ 0 ].mNumIndices = 3;
+    scene->mMeshes[ 0 ]->mFaces[ 0 ].mIndices = new unsigned int[ 3 ];
+    scene->mMeshes[ 0 ]->mFaces[ 0 ].mIndices[ 0 ] = 0;
+    scene->mMeshes[ 0 ]->mFaces[ 0 ].mIndices[ 1 ] = 1;
+    scene->mMeshes[ 0 ]->mFaces[ 0 ].mIndices[ 2 ] = 2;
+
+    scene->mRootNode = new aiNode;
+    scene->mRootNode->mNumMeshes = 1;
+    scene->mRootNode->mMeshes = new unsigned int( 0 );
+
+    Assimp::Importer importer;
+    Assimp::Exporter exporter;
+    for ( std::size_t i( 0 ); i < exporter.GetExportFormatCount(); ++i ) {
+        /*const aiExportFormatDesc *desc( exporter.GetExportFormatDescription( i ) );
+        std::cout << "[" << desc->id << "] ";
+        std::string path( "scene." );
+        path.append( desc->fileExtension );
+
+        ASSERT_EQ( AI_SUCCESS, exporter.Export( scene, desc->id, path ) );
+        const aiScene *newScene( importer.ReadFile( path, 0 ) );
+        ASSERT_TRUE( NULL != newScene );
+        float newOpacity;                    
+        if ( newScene->mNumMaterials > 0 ) {
+            //ASSERT_EQ( AI_SUCCESS, newScene->mMaterials[ 0 ]->Get( AI_MATKEY_OPACITY, newOpacity ) );
+            //EXPECT_EQ( opacity, newOpacity );
+        }*/
+    }
+}
+
+#endif // ASSIMP_BUILD_NO_EXPORT

Некоторые файлы не были показаны из-за большого количества измененных файлов