Răsfoiți Sursa

Merge remote-tracking branch 'official/master' into contrib

Léo Terziman 10 ani în urmă
părinte
comite
2274c96e3b
64 a modificat fișierele cu 436 adăugiri și 295 ștergeri
  1. 3 0
      .gitignore
  2. 12 4
      .travis.yml
  3. 12 7
      CMakeLists.txt
  4. 8 4
      assimp-config.cmake.in
  5. 7 0
      code/3DSLoader.cpp
  6. 29 11
      code/CMakeLists.txt
  7. 41 0
      code/ColladaLoader.cpp
  8. 3 1
      code/FBXParser.cpp
  9. 4 4
      code/IFCCurve.cpp
  10. 3 3
      code/IFCGeometry.cpp
  11. 1 1
      code/IFCOpenings.cpp
  12. 1 1
      code/IFCUtil.cpp
  13. 8 0
      code/LWOBLoader.cpp
  14. 5 0
      code/LWOLoader.cpp
  15. 7 0
      code/OFFLoader.cpp
  16. 0 1
      code/PlyLoader.cpp
  17. 1 1
      code/PlyParser.cpp
  18. 8 2
      code/STLLoader.cpp
  19. 4 0
      code/XFileParser.cpp
  20. 12 0
      contrib/zlib/CMakeLists.txt
  21. 1 1
      include/assimp/DefaultLogger.hpp
  22. 2 2
      include/assimp/Exporter.hpp
  23. 1 1
      include/assimp/IOStream.hpp
  24. 1 1
      include/assimp/IOSystem.hpp
  25. 1 1
      include/assimp/Importer.hpp
  26. 1 1
      include/assimp/LogStream.hpp
  27. 1 1
      include/assimp/NullLogger.hpp
  28. 1 1
      include/assimp/ProgressHandler.hpp
  29. 1 1
      include/assimp/ai_assert.h
  30. 2 5
      include/assimp/cexport.h
  31. 1 1
      include/assimp/cfileio.h
  32. 45 11
      include/assimp/cimport.h
  33. 1 1
      include/assimp/color4.h
  34. 1 1
      include/assimp/color4.inl
  35. 13 12
      include/assimp/config.h
  36. 1 1
      include/assimp/defs.h
  37. 1 2
      include/assimp/importerdesc.h
  38. 8 38
      include/assimp/material.h
  39. 1 1
      include/assimp/material.inl
  40. 1 1
      include/assimp/matrix3x3.inl
  41. 2 2
      include/assimp/matrix4x4.inl
  42. 1 2
      include/assimp/mesh.h
  43. 1 0
      include/assimp/metadata.h
  44. 4 4
      include/assimp/postprocess.h
  45. 2 3
      include/assimp/quaternion.inl
  46. 6 8
      include/assimp/scene.h
  47. 7 3
      include/assimp/types.h
  48. 3 3
      include/assimp/vector2.h
  49. 1 1
      include/assimp/vector2.inl
  50. 3 3
      include/assimp/vector3.h
  51. 1 1
      include/assimp/vector3.inl
  52. 1 1
      include/assimp/version.h
  53. 23 38
      port/PyAssimp/pyassimp/core.py
  54. 41 0
      port/PyAssimp/pyassimp/formats.py
  55. 10 0
      port/PyAssimp/pyassimp/structs.py
  56. 5 5
      samples/SimpleOpenGL/CMakeLists.txt
  57. 4 4
      samples/SimpleTexturedOpenGL/CMakeLists.txt
  58. 1 1
      test/CMakeLists.txt
  59. 22 7
      test/regression/gen_db.py
  60. 30 10
      test/regression/run.py
  61. 8 69
      test/regression/utils.py
  62. 2 2
      tools/assimp_cmd/CMakeLists.txt
  63. 2 2
      tools/assimp_cmd/Info.cpp
  64. 2 2
      tools/assimp_view/CMakeLists.txt

+ 3 - 0
.gitignore

@@ -51,3 +51,6 @@ test/gtest/src/gtest-stamp/Debug/gtest-build
 *.lib
 test/gtest/src/gtest-stamp/Debug/
 tools/assimp_view/assimp_viewer.vcxproj.user
+
+# Unix editor backups
+*~

+ 12 - 4
.travis.yml

@@ -2,10 +2,15 @@ before_install:
   - sudo apt-get install cmake python3
 
 env:
-  - TRAVIS_NO_EXPORT=YES
-  - TRAVIS_NO_EXPORT=NO
-  - TRAVIS_STATIC_BUILD=ON
-  - TRAVIS_STATIC_BUILD=OFF
+    matrix:
+    - LINUX=1 TRAVIS_NO_EXPORT=YES
+    - LINUX=1 TRAVIS_NO_EXPORT=NO
+    - LINUX=1 TRAVIS_STATIC_BUILD=ON
+    - LINUX=1 TRAVIS_STATIC_BUILD=OFF
+    - WINDOWS=1 TRAVIS_NO_EXPORT=YES
+    - WINDOWS=1 TRAVIS_NO_EXPORT=NO
+    - WINDOWS=1 TRAVIS_STATIC_BUILD=ON
+    - WINDOWS=1 TRAVIS_STATIC_BUILD=OFF
 
 language: cpp
 
@@ -13,6 +18,9 @@ compiler:
   - gcc
   - clang
 
+install:
+  - if [ $WINDOWS ]; then travis_retry sudo apt-get install -q -y gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 binutils-mingw-w64-x86-64; fi 
+
 script:
   - cmake -G "Unix Makefiles" -DASSIMP_ENABLE_BOOST_WORKAROUND=YES -DASSIMP_NO_EXPORT=$TRAVIS_NO_EXPORT -STATIC_BUILD=$TRAVIS_STATIC_BUILD
   - make

+ 12 - 7
CMakeLists.txt

@@ -1,4 +1,4 @@
-cmake_minimum_required( VERSION 2.6 )
+cmake_minimum_required( VERSION 2.8 )
 PROJECT( Assimp )
 
 # Define here the needed parameters
@@ -47,6 +47,11 @@ set(ASSIMP_LIBRARY_SUFFIX "" CACHE STRING "Suffix to append to library names")
 
 option(ASSIMP_ANDROID_JNIIOSYSTEM "Android JNI IOSystem support is active" OFF)
 
+# Workaround to be able to deal with compiler bug "Too many sections" with mingw.
+if( CMAKE_COMPILER_IS_MINGW )
+    ADD_DEFINITIONS(-DASSIMP_BUILD_NO_IFC_IMPORTER )
+endif()
+
 if((CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) AND NOT CMAKE_COMPILER_IS_MINGW)
     add_definitions(-fPIC) # this is a very important switch and some libraries seem now to have it....
     # hide all not-exported symbols
@@ -54,7 +59,7 @@ if((CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) AND NOT CMAKE_COMPILER_
 elseif(MSVC)
     # enable multi-core compilation with MSVC
     add_definitions(/MP)
-    endif()
+endif()
 
 INCLUDE (FindPkgConfig)
 INCLUDE_DIRECTORIES( include )
@@ -79,7 +84,7 @@ SET( ASSIMP_INCLUDE_INSTALL_DIR "include" CACHE PATH
 SET( ASSIMP_BIN_INSTALL_DIR "bin" CACHE PATH
     "Path the tool executables are installed to." )
 
-SET(ASSIMP_DEBUG_POSTFIX "d" CACHE STRING "Debug Postfitx for lib, samples and tools")
+SET(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "Debug Postfitx for lib, samples and tools")
 
 # Allow the user to build a shared or static library
 option ( BUILD_SHARED_LIBS "Build a shared version of the library" ON )
@@ -103,7 +108,7 @@ IF ( ASSIMP_ENABLE_BOOST_WORKAROUND )
     MESSAGE( STATUS "Building a non-boost version of Assimp." )
 ELSE ( ASSIMP_ENABLE_BOOST_WORKAROUND )
     SET( Boost_DETAILED_FAILURE_MSG ON )
-    SET( Boost_ADDITIONAL_VERSIONS "1.47" "1.47.0" "1.48.0" "1.48" "1.49" "1.49.0" "1.50" "1.50.0" "1.51" "1.51.0" "1.52.0" "1.53.0" "1.54.0" "1.55" "1.55.0" "1.56" "1.56.0" "1.57" "1.57.0" )	
+    SET( Boost_ADDITIONAL_VERSIONS "1.47" "1.47.0" "1.48.0" "1.48" "1.49" "1.49.0" "1.50" "1.50.0" "1.51" "1.51.0" "1.52.0" "1.53.0" "1.54.0" "1.55" "1.55.0" "1.56" "1.56.0" "1.57" "1.57.0" "1.58" "1.58.0" )
     FIND_PACKAGE( Boost )
     IF ( NOT Boost_FOUND )
         MESSAGE( FATAL_ERROR
@@ -159,7 +164,7 @@ IF ( ASSIMP_NO_EXPORT )
     MESSAGE( STATUS "Build an import-only version of Assimp." )
 ENDIF( ASSIMP_NO_EXPORT )
 
-SET ( ASSIMP_BUILD_ARCHITECTURE "" CACHE STRING 
+SET ( ASSIMP_BUILD_ARCHITECTURE "" CACHE STRING
     "describe the current architecture."
 )
 IF    ( ASSIMP_BUILD_ARCHITECTURE STREQUAL "")
@@ -168,7 +173,7 @@ ELSE  ( ASSIMP_BUILD_ARCHITECTURE STREQUAL "")
 ENDIF ( ASSIMP_BUILD_ARCHITECTURE STREQUAL "")
 
 # ${CMAKE_GENERATOR}
-SET ( ASSIMP_BUILD_COMPILER "" CACHE STRING 
+SET ( ASSIMP_BUILD_COMPILER "" CACHE STRING
     "describe the current compiler."
 )
 IF    ( ASSIMP_BUILD_COMPILER STREQUAL "")
@@ -206,7 +211,7 @@ option ( ASSIMP_BUILD_TESTS
     "If the test suite for Assimp is built in addition to the library."
     ON
 )
-    
+
 IF ( ASSIMP_BUILD_TESTS )
     ADD_SUBDIRECTORY( test/ )
 ENDIF ( ASSIMP_BUILD_TESTS )

+ 8 - 4
assimp-config.cmake.in

@@ -23,8 +23,14 @@ if( MSVC )
     set(MSVC_PREFIX "vc80")
   elseif( MSVC90 )
     set(MSVC_PREFIX "vc90")
-  else()
+  elseif( MSVC10 )
     set(MSVC_PREFIX "vc100")
+  elseif( MSVC11 )
+    set(MSVC_PREFIX "vc110")
+  elseif( MSVC12 )
+    set(MSVC_PREFIX "vc120")
+  else()
+    set(MSVC_PREFIX "vc130")
   endif()
   set(ASSIMP_LIBRARY_SUFFIX "@ASSIMP_LIBRARY_SUFFIX@-${MSVC_PREFIX}-mt" CACHE STRING "the suffix for the assimp windows library" FORCE)
 else()
@@ -40,9 +46,7 @@ set( ASSIMP_LINK_FLAGS "" )
 set( ASSIMP_LIBRARY_DIRS "${ASSIMP_ROOT_DIR}/@ASSIMP_LIB_INSTALL_DIR@")
 set( ASSIMP_INCLUDE_DIRS "${ASSIMP_ROOT_DIR}/@ASSIMP_INCLUDE_INSTALL_DIR@")
 set( ASSIMP_LIBRARIES assimp${ASSIMP_LIBRARY_SUFFIX})
-if (CMAKE_BUILD_TYPE EQUAL "DEBUG")
-	set( ASSIMP_LIBRARIES ${ASSIMP_LIBRARIES}D)
-endif (CMAKE_BUILD_TYPE EQUAL "DEBUG")
+set( ASSIMP_LIBRARIES ${ASSIMP_LIBRARIES}@CMAKE_DEBUG_POSTFIX@)
 
 # search for the boost version assimp was compiled with
 #set(Boost_USE_MULTITHREAD ON)

+ 7 - 0
code/3DSLoader.cpp

@@ -175,6 +175,10 @@ void Discreet3DSImporter::InternReadFile( const std::string& pFile,
 	// file.
 	for (std::vector<D3DS::Mesh>::iterator i = mScene->mMeshes.begin(),
 		 end = mScene->mMeshes.end(); i != end;++i)	{
+		if ((*i).mFaces.size() > 0 && (*i).mPositions.size() == 0)	{
+			delete mScene;
+			throw DeadlyImportError("3DS file contains faces but no vertices: " + pFile);
+		}
 		CheckIndices(*i);
 		MakeUnique  (*i);
 		ComputeNormalsWithSmoothingsGroups<D3DS::Face>(*i);
@@ -944,6 +948,9 @@ void Discreet3DSImporter::ParseFaceChunk()
 		// This is the list of smoothing groups - a bitfield for every face. 
 		// Up to 32 smoothing groups assigned to a single face.
 		unsigned int num = chunkSize/4, m = 0;
+		if (num > mMesh.mFaces.size())	{
+			throw DeadlyImportError("3DS: More smoothing groups than faces");
+		}
 		for (std::vector<D3DS::Face>::iterator i =  mMesh.mFaces.begin(); m != num;++i, ++m)	{
 			// nth bit is set for nth smoothing group
 			(*i).iSmoothGroup = stream->GetI4();

+ 29 - 11
code/CMakeLists.txt

@@ -205,7 +205,7 @@ SET( Collada_SRCS
 	ColladaParser.cpp
 	ColladaParser.h
 	ColladaExporter.h
-	ColladaExporter.cpp	
+	ColladaExporter.cpp
 )
 SOURCE_GROUP( Collada FILES ${Collada_SRCS})
 
@@ -332,7 +332,7 @@ SET( Obj_SRCS
 	ObjFileParser.cpp
 	ObjFileParser.h
 	ObjTools.h
-	
+
 	ObjExporter.h
 	ObjExporter.cpp
 )
@@ -596,14 +596,14 @@ SET( ConvertUTF_SRCS
 )
 SOURCE_GROUP( ConvertUTF FILES ${ConvertUTF_SRCS})
 
-SET( Clipper_SRCS 
+SET( Clipper_SRCS
 	../contrib/clipper/clipper.hpp
 	../contrib/clipper/clipper.cpp
 )
 SOURCE_GROUP( Clipper FILES ${Clipper_SRCS})
 
 
-SET( Poly2Tri_SRCS 
+SET( Poly2Tri_SRCS
 	../contrib/poly2tri/poly2tri/common/shapes.cc
 	../contrib/poly2tri/poly2tri/common/shapes.h
 	../contrib/poly2tri/poly2tri/common/utils.h
@@ -699,7 +699,7 @@ SET( assimp_src
 	${IFC_SRCS}
 	${XGL_SRCS}
 	${FBX_SRCS}
-	
+
 	# Third-party libraries
 	${IrrXML_SRCS}
 	${ConvertUTF_SRCS}
@@ -711,7 +711,7 @@ SET( assimp_src
 
 	${PUBLIC_HEADERS}
 	${COMPILER_HEADERS}
-	
+
 	# Old precompiled header
 	# (removed because the precompiled header is not updated when visual studio switch configuration which leads to failed compilation.
 	# Moreover it's a drag to recompile assimp entirely each time a modification is made to one of the included header, which is definitely counter-productive.)
@@ -722,8 +722,6 @@ SET( assimp_src
 
 ADD_LIBRARY( assimp ${assimp_src} )
 
-SET_PROPERTY(TARGET assimp PROPERTY DEBUG_POSTFIX ${ASSIMP_DEBUG_POSTFIX})
-
 TARGET_LINK_LIBRARIES(assimp ${ZLIB_LIBRARIES})
 
 if(ANDROID AND ASSIMP_ANDROID_JNIIOSYSTEM)
@@ -732,10 +730,30 @@ if(ANDROID AND ASSIMP_ANDROID_JNIIOSYSTEM)
 	target_link_libraries(assimp android_jniiosystem)
 endif(ANDROID AND ASSIMP_ANDROID_JNIIOSYSTEM)
 
+if( MSVC )
+  # in order to prevent DLL hell, each of the DLLs have to be suffixed with the major version and msvc prefix
+  if( MSVC70 OR MSVC71 )
+    set(MSVC_PREFIX "vc70")
+  elseif( MSVC80 )
+    set(MSVC_PREFIX "vc80")
+  elseif( MSVC90 )
+    set(MSVC_PREFIX "vc90")
+  elseif( MSVC10 )
+    set(MSVC_PREFIX "vc100")
+  elseif( MSVC11 )
+    set(MSVC_PREFIX "vc110")
+  elseif( MSVC12 )
+    set(MSVC_PREFIX "vc120")
+  else()
+    set(MSVC_PREFIX "vc130")
+  endif()
+  set(LIBRARY_SUFFIX "${ASSIMP_LIBRARY_SUFFIX}-${MSVC_PREFIX}-mt" CACHE STRING "the suffix for the assimp windows library" FORCE)
+endif()
+
 SET_TARGET_PROPERTIES( assimp PROPERTIES
 	VERSION ${ASSIMP_VERSION}
-	SOVERSION ${ASSIMP_SOVERSION} # use full version 
-    OUTPUT_NAME assimp${ASSIMP_LIBRARY_SUFFIX}
+	SOVERSION ${ASSIMP_SOVERSION} # use full version
+    OUTPUT_NAME assimp${LIBRARY_SUFFIX}
 )
 
 if (APPLE)
@@ -765,7 +783,7 @@ if (ASSIMP_ANDROID_JNIIOSYSTEM)
 endif(ASSIMP_ANDROID_JNIIOSYSTEM)
 
 if(MSVC AND ASSIMP_INSTALL_PDB)
-	install(FILES ${Assimp_BINARY_DIR}/code/Debug/assimp${ASSIMP_DEBUG_POSTFIX}.pdb
+	install(FILES ${Assimp_BINARY_DIR}/code/Debug/assimp${CMAKE_DEBUG_POSTFIX}.pdb
 		DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
 		CONFIGURATIONS Debug
 	)

+ 41 - 0
code/ColladaLoader.cpp

@@ -986,6 +986,47 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars
 				entry.mTransformId = srcChannel.mTarget.substr( slashPos+1);
 			}
 
+			std::string::size_type bracketPos = srcChannel.mTarget.find('(');
+			if (bracketPos != std::string::npos)
+			{
+				entry.mTransformId = srcChannel.mTarget.substr(slashPos + 1, bracketPos - slashPos - 1);
+				std::string subElement = srcChannel.mTarget.substr(bracketPos);
+			
+				if (subElement == "(0)(0)")
+					entry.mSubElement = 0; 
+				else if (subElement == "(1)(0)")
+					entry.mSubElement = 1;
+				else if (subElement == "(2)(0)")
+					entry.mSubElement = 2;
+				else if (subElement == "(3)(0)")
+					entry.mSubElement = 3;
+				else if (subElement == "(0)(1)")
+					entry.mSubElement = 4;
+				else if (subElement == "(1)(1)")
+					entry.mSubElement = 5;
+				else if (subElement == "(2)(1)")
+					entry.mSubElement = 6;
+				else if (subElement == "(3)(1)")
+					entry.mSubElement = 7;
+				else if (subElement == "(0)(2)")
+					entry.mSubElement = 8;
+				else if (subElement == "(1)(2)")
+					entry.mSubElement = 9;
+				else if (subElement == "(2)(2)")
+					entry.mSubElement = 10;
+				else if (subElement == "(3)(2)")
+					entry.mSubElement = 11;
+				else if (subElement == "(0)(3)")
+					entry.mSubElement = 12;
+				else if (subElement == "(1)(3)")
+					entry.mSubElement = 13;
+				else if (subElement == "(2)(3)")
+					entry.mSubElement = 14;
+				else if (subElement == "(3)(3)")
+					entry.mSubElement = 15;
+
+			}
+
 			// determine which transform step is affected by this channel
 			entry.mTransformIndex = SIZE_MAX;
 			for( size_t a = 0; a < srcNode->mTransforms.size(); ++a)

+ 3 - 1
code/FBXParser.cpp

@@ -549,7 +549,9 @@ void ReadBinaryDataArray(char type, uint32_t count, const char*& data, const cha
 		zstream.data_type = Z_BINARY;
 
 		// http://hewgill.com/journal/entries/349-how-to-decompress-gzip-stream-with-zlib
-		inflateInit(&zstream);
+		if(Z_OK != inflateInit(&zstream)) {
+			ParseError("failure initializing zlib");
+		}
 
 		zstream.next_in   = reinterpret_cast<Bytef*>( const_cast<char*>(data) );
 		zstream.avail_in  = comp_len;

+ 4 - 4
code/IFCCurve.cpp

@@ -91,7 +91,7 @@ public:
 		a = std::fmod(a,static_cast<IfcFloat>( AI_MATH_TWO_PI ));
 		b = std::fmod(b,static_cast<IfcFloat>( AI_MATH_TWO_PI ));
 		const IfcFloat setting = static_cast<IfcFloat>( AI_MATH_PI * conv.settings.conicSamplingAngle / 180.0 );
-		return static_cast<size_t>( std::ceil(abs( b-a)) / setting);
+		return static_cast<size_t>( std::ceil(std::abs( b-a)) / setting);
 	}
 
 	// --------------------------------------------------
@@ -276,7 +276,7 @@ public:
 		IfcFloat acc = 0;
 		BOOST_FOREACH(const CurveEntry& entry, curves) {
 			const ParamRange& range = entry.first->GetParametricRange();
-			const IfcFloat delta = abs(range.second-range.first);
+			const IfcFloat delta = std::abs(range.second-range.first);
 			if (u < acc+delta) {
 				return entry.first->Eval( entry.second ? (u-acc) + range.first : range.second-(u-acc));
 			}
@@ -295,7 +295,7 @@ public:
 		IfcFloat acc = 0;
 		BOOST_FOREACH(const CurveEntry& entry, curves) {
 			const ParamRange& range = entry.first->GetParametricRange();
-			const IfcFloat delta = abs(range.second-range.first);
+			const IfcFloat delta = std::abs(range.second-range.first);
 			if (a <= acc+delta && b >= acc) {
 				const IfcFloat at =  std::max(static_cast<IfcFloat>( 0. ),a-acc), bt = std::min(delta,b-acc);
 				cnt += entry.first->EstimateSampleCount( entry.second ? at + range.first : range.second - bt, entry.second ? bt + range.first : range.second - at );
@@ -569,7 +569,7 @@ bool Curve :: InRange(IfcFloat u) const
 IfcFloat Curve :: GetParametricRangeDelta() const
 {
 	const ParamRange& range = GetParametricRange();
-	return abs(range.second - range.first);
+	return std::abs(range.second - range.first);
 }
 
 // ------------------------------------------------------------------------------------------------

+ 3 - 3
code/IFCGeometry.cpp

@@ -375,21 +375,21 @@ void ProcessSweptDiskSolid(const IfcSweptDiskSolid solid, TempMesh& result, Conv
 		bool take_any = false;
 
 		for (unsigned int i = 0; i < 2; ++i, take_any = true) {
-			if ((last_dir == 0 || take_any) && abs(d.x) > 1e-6) {
+			if ((last_dir == 0 || take_any) && std::abs(d.x) > 1e-6) {
 				q.y = startvec.y;
 				q.z = startvec.z;
 				q.x = -(d.y * q.y + d.z * q.z) / d.x;
 				last_dir = 0;
 				break;
 			}
-			else if ((last_dir == 1 || take_any) && abs(d.y) > 1e-6) {
+			else if ((last_dir == 1 || take_any) && std::abs(d.y) > 1e-6) {
 				q.x = startvec.x;
 				q.z = startvec.z;
 				q.y = -(d.x * q.x + d.z * q.z) / d.y;
 				last_dir = 1;
 				break;
 			}
-			else if ((last_dir == 2 && abs(d.z) > 1e-6) || take_any) { 
+			else if ((last_dir == 2 && std::abs(d.z) > 1e-6) || take_any) {
 				q.y = startvec.y;
 				q.x = startvec.x;
 				q.z = -(d.y * q.y + d.x * q.x) / d.z;

+ 1 - 1
code/IFCOpenings.cpp

@@ -1244,7 +1244,7 @@ bool GenerateOpenings(std::vector<TempOpening>& openings,
 				const IfcVector3& face_nor = ((profile_verts[vi_total+2] - profile_verts[vi_total]) ^
 					(profile_verts[vi_total+1] - profile_verts[vi_total])).Normalize();
 
-				const IfcFloat abs_dot_face_nor = abs(nor * face_nor);
+				const IfcFloat abs_dot_face_nor = std::abs(nor * face_nor);
 				if (abs_dot_face_nor < 0.9) {
 					vi_total += profile_vertcnts[f];
 					continue;

+ 1 - 1
code/IFCUtil.cpp

@@ -122,7 +122,7 @@ void TempMesh::Transform(const IfcMatrix4& mat)
 // ------------------------------------------------------------------------------
 IfcVector3 TempMesh::Center() const
 {
-	return std::accumulate(verts.begin(),verts.end(),IfcVector3()) / static_cast<IfcFloat>(verts.size());
+	return (verts.size() == 0) ? IfcVector3(0.0f, 0.0f, 0.0f) : (std::accumulate(verts.begin(),verts.end(),IfcVector3()) / static_cast<IfcFloat>(verts.size()));
 }
 
 // ------------------------------------------------------------------------------------------------

+ 8 - 0
code/LWOBLoader.cpp

@@ -139,7 +139,15 @@ void LWOImporter::CountVertsAndFacesLWOB(unsigned int& verts, unsigned int& face
 	while (cursor < end && max--)
 	{
 		uint16_t numIndices;
+		// must have 2 shorts left for numIndices and surface
+		if (end - cursor < 2) {
+			throw DeadlyImportError("LWOB: Unexpected end of file");
+		}
 		::memcpy(&numIndices, cursor++, 2);
+		// must have enough left for indices and surface
+		if (end - cursor < (1 + numIndices)) {
+			throw DeadlyImportError("LWOB: Unexpected end of file");
+		}
 		verts += numIndices;
 		faces++;
 		cursor += numIndices;

+ 5 - 0
code/LWOLoader.cpp

@@ -730,6 +730,11 @@ void LWOImporter::LoadLWOPoints(unsigned int length)
 	// --- this function is used for both LWO2 and LWOB but for
 	// LWO2 we need to allocate 25% more storage - it could be we'll 
 	// need to duplicate some points later.
+	const size_t vertexLen = 12;
+	if ((length % vertexLen) != 0)
+	{
+		throw DeadlyImportError( "LWO2: Points chunk length is not multiple of vertexLen (12)");
+	}
 	register unsigned int regularSize = (unsigned int)mCurLayer->mTempPoints.size() + length / 12;
 	if (mIsLWO2)
 	{

+ 7 - 0
code/OFFLoader.cpp

@@ -127,6 +127,13 @@ void OFFImporter::InternReadFile( const std::string& pFile,
 	const unsigned int numVertices = strtoul10(sz,&sz);SkipSpaces(&sz);
 	const unsigned int numFaces = strtoul10(sz,&sz);
 
+	if (!numVertices) {
+		throw DeadlyImportError("OFF: There are no valid vertices");
+	}
+	if (!numFaces) {
+		throw DeadlyImportError("OFF: There are no valid faces");
+	}
+
 	pScene->mMeshes = new aiMesh*[ pScene->mNumMeshes = 1 ];
 	aiMesh* mesh = pScene->mMeshes[0] = new aiMesh();
 	aiFace* faces = mesh->mFaces = new aiFace [mesh->mNumFaces = numFaces];

+ 0 - 1
code/PlyLoader.cpp

@@ -156,7 +156,6 @@ void PLYImporter::InternReadFile( const std::string& pFile,
 	}
 	else
 	{
-		delete[] this->mBuffer;
 		AI_DEBUG_INVALIDATE_PTR(this->mBuffer);
 		throw DeadlyImportError( "Invalid .ply file: Missing format specification");
 	}

+ 1 - 1
code/PlyParser.cpp

@@ -436,7 +436,7 @@ bool PLY::DOM::ParseHeader (const char* pCur,const char** pCurOut,bool isBinary)
 	*pCurOut = pCur;
 
 	// parse all elements
-	while (true)
+	while ((*pCur) != '\0')
 	{
 		// skip all comments
 		PLY::DOM::SkipComments(pCur,&pCur);

+ 8 - 2
code/STLLoader.cpp

@@ -229,6 +229,9 @@ void STLImporter::LoadASCIIFile()
 	size_t temp;
 	// setup the name of the node
 	if ((temp = (size_t)(sz-szMe)))	{
+		if (temp >= MAXLEN) {
+			throw DeadlyImportError( "STL: Node name too long" );
+		}
 
 		pScene->mRootNode->mName.length = temp;
 		memcpy(pScene->mRootNode->mName.data,szMe,temp);
@@ -305,6 +308,7 @@ void STLImporter::LoadASCIIFile()
 		{
 			if (3 == curVertex)	{
 				DefaultLogger::get()->error("STL: a facet with more than 3 vertices has been found");
+				++sz;
 			}
 			else
 			{
@@ -323,8 +327,10 @@ void STLImporter::LoadASCIIFile()
 			break;
 		}
 		// else skip the whole identifier
-		else while (!::IsSpaceOrNewLine(*sz)) {
-			++sz;
+		else {
+			do {
+				++sz;
+			} while (!::IsSpaceOrNewLine(*sz));
 		}
 	}
 

+ 4 - 0
code/XFileParser.cpp

@@ -214,6 +214,10 @@ XFileParser::XFileParser( const std::vector<char>& pBuffer)
 			AI_SWAP2(ofs); 
 			P += 4;
 
+			if (P + ofs > End + 2) {
+				throw DeadlyImportError("X: Unexpected EOF in compressed chunk");
+			}
+
 			// push data to the stream
 			stream.next_in   = (Bytef*)P;
 			stream.avail_in  = ofs;

+ 12 - 0
contrib/zlib/CMakeLists.txt

@@ -1,7 +1,14 @@
 cmake_minimum_required(VERSION 2.4.4)
 set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON)
 
+# CMake 3.0 changed the project command, setting policy CMP0048 reverts to the old behaviour.
+# See http://www.cmake.org/cmake/help/v3.0/policy/CMP0048.html
+cmake_policy(PUSH)
+if(CMAKE_MAJOR_VERSION GREATER 2)
+	cmake_policy(SET CMP0048 OLD)
+endif()
 project(zlib C)
+cmake_policy(POP)
 
 set(VERSION "1.2.8")
 
@@ -185,3 +192,8 @@ if(MINGW)
 endif(MINGW)
 
 add_library(zlibstatic STATIC ${ZLIB_SRCS} ${ZLIB_ASMS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS})
+INSTALL( TARGETS zlibstatic
+         LIBRARY DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
+         ARCHIVE DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
+         RUNTIME DESTINATION ${ASSIMP_BIN_INSTALL_DIR}
+         COMPONENT ${LIBASSIMP_COMPONENT})

+ 1 - 1
include/assimp/DefaultLogger.hpp

@@ -37,7 +37,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 ----------------------------------------------------------------------
 */
-/** @file DefaultLogger.h
+/** @file DefaultLogger.hpp
 */
 
 #ifndef INCLUDED_AI_DEFAULTLOGGER

+ 2 - 2
include/assimp/Exporter.hpp

@@ -39,7 +39,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ---------------------------------------------------------------------------
 */
 
-/** @file  export.hpp
+/** @file  Exporter.hpp
 *  @brief Defines the CPP-API for the Assimp export interface
 */
 #ifndef AI_EXPORT_HPP_INC
@@ -181,7 +181,7 @@ public:
 	 *  about the output data flow of the export process.
 	 * @param pBlob A data blob obtained from a previous call to #aiExportScene. Must not be NULL.
 	 * @param pPath Full target file name. Target must be accessible.
-	 * @param pPreprocessing Accepts any choice of the #aiPostProcessing enumerated
+	 * @param pPreprocessing Accepts any choice of the #aiPostProcessSteps enumerated
 	 *   flags, but in reality only a subset of them makes sense here. Specifying
 	 *   'preprocessing' flags is useful if the input scene does not conform to 
 	 *   Assimp's default conventions as specified in the @link data Data Structures Page @endlink. 

+ 1 - 1
include/assimp/IOStream.hpp

@@ -38,7 +38,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ---------------------------------------------------------------------------
 */
-/** @file IOStream.h
+/** @file IOStream.hpp
  *  @brief File I/O wrappers for C++. 
  */
 

+ 1 - 1
include/assimp/IOSystem.hpp

@@ -39,7 +39,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ---------------------------------------------------------------------------
 */
 
-/** @file IOSystem.h
+/** @file IOSystem.hpp
  *  @brief File system wrapper for C++. Inherit this class to supply
  *  custom file handling logic to the Import library.
 */

+ 1 - 1
include/assimp/Importer.hpp

@@ -39,7 +39,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ---------------------------------------------------------------------------
 */
 
-/** @file  assimp.hpp
+/** @file  Importer.hpp
  *  @brief Defines the C++-API to the Open Asset Import Library.
  */
 #ifndef INCLUDED_AI_ASSIMP_HPP

+ 1 - 1
include/assimp/LogStream.hpp

@@ -38,7 +38,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ----------------------------------------------------------------------
 */
 
-/** @file LogStream.h
+/** @file LogStream.hpp
  *  @brief Abstract base class 'LogStream', representing an output log stream.
  */
 #ifndef INCLUDED_AI_LOGSTREAM_H

+ 1 - 1
include/assimp/NullLogger.hpp

@@ -38,7 +38,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ----------------------------------------------------------------------
 */
 
-/** @file  NullLogger.h
+/** @file  NullLogger.hpp
  *  @brief Dummy logger
 */
 

+ 1 - 1
include/assimp/ProgressHandler.hpp

@@ -38,7 +38,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ----------------------------------------------------------------------
 */
 
-/** @file ProgressHandler.h
+/** @file ProgressHandler.hpp
  *  @brief Abstract base class 'ProgressHandler'.
  */
 #ifndef INCLUDED_AI_PROGRESSHANDLER_H

+ 1 - 1
include/assimp/ai_assert.h

@@ -1,4 +1,4 @@
-/** @file assert.h
+/** @file ai_assert.h
  */
 #ifndef AI_DEBUG_H_INC
 #define AI_DEBUG_H_INC

+ 2 - 5
include/assimp/cexport.h

@@ -122,10 +122,7 @@ ASSIMP_API void aiFreeScene(const C_STRUCT aiScene* pIn);
 * @param pFormatId ID string to specify to which format you want to export to. Use 
 * aiGetExportFormatCount() / aiGetExportFormatDescription() to learn which export formats are available.
 * @param pFileName Output file to write
-* @param pIO custom IO implementation to be used. Use this if you use your own storage methods.
-*   If none is supplied, a default implementation using standard file IO is used. Note that
-*   #aiExportSceneToBlob is provided as convenience function to export to memory buffers.
-* @param pPreprocessing Accepts any choice of the #aiPostProcessing enumerated
+* @param pPreprocessing Accepts any choice of the #aiPostProcessSteps enumerated
 *   flags, but in reality only a subset of them makes sense here. Specifying
 *   'preprocessing' flags is useful if the input scene does not conform to 
 *   Assimp's default conventions as specified in the @link data Data Structures Page @endlink. 
@@ -183,7 +180,7 @@ ASSIMP_API aiReturn aiExportSceneEx( const C_STRUCT aiScene* pScene,
 
 // --------------------------------------------------------------------------------
 /** Describes a blob of exported scene data. Use #aiExportSceneToBlob() to create a blob containing an
-* exported scene. The memory referred by this structure is owned by Assimp. Use #aiReleaseExportedFile()
+* exported scene. The memory referred by this structure is owned by Assimp. 
 * to free its resources. Don't try to free the memory on your side - it will crash for most build configurations
 * due to conflicting heaps.
 *

+ 1 - 1
include/assimp/cfileio.h

@@ -39,7 +39,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ---------------------------------------------------------------------------
 */
 
-/** @file aiFileIO.h
+/** @file cfileio.h
  *  @brief Defines generic C routines to access memory-mapped files
  */
 #ifndef AI_FILEIO_H_INC

+ 45 - 11
include/assimp/cimport.h

@@ -39,7 +39,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ---------------------------------------------------------------------------
 */
 
-/** @file  assimp.h
+/** @file  cimport.h
  *  @brief Defines the C-API to the Open Asset Import Library. 
  */
 #ifndef AI_ASSIMP_H_INC
@@ -139,7 +139,17 @@ ASSIMP_API const C_STRUCT aiScene* aiImportFileEx(
 // --------------------------------------------------------------------------------
 /** Same as #aiImportFileEx, but adds an extra parameter containing importer settings.
  *
+ * @param pFile Path and filename of the file to be imported, 
+ *   expected to be a null-terminated c-string. NULL is not a valid value.
+ * @param pFlags Optional post processing steps to be executed after 
+ *   a successful import. Provide a bitwise combination of the
+ *   #aiPostProcessSteps flags.
+ * @param pFS aiFileIO structure. Will be used to open the model file itself
+ *   and any other files the loader needs to open.  Pass NULL to use the default
+ *   implementation.
  * @param pProps #aiPropertyStore instance containing import settings. 
+ * @return Pointer to the imported data or NULL if the import failed.  
+ * @note Include <aiFileIO.h> for the definition of #aiFileIO.
  * @see aiImportFileEx
  */
 ASSIMP_API const C_STRUCT aiScene* aiImportFileExWithProperties( 
@@ -188,7 +198,29 @@ ASSIMP_API const C_STRUCT aiScene* aiImportFileFromMemory(
 // --------------------------------------------------------------------------------
 /** Same as #aiImportFileFromMemory, but adds an extra parameter containing importer settings.
  *
+ * @param pBuffer Pointer to the file data
+ * @param pLength Length of pBuffer, in bytes
+ * @param pFlags Optional post processing steps to be executed after 
+ *   a successful import. Provide a bitwise combination of the 
+ *   #aiPostProcessSteps flags. If you wish to inspect the imported
+ *   scene first in order to fine-tune your post-processing setup,
+ *   consider to use #aiApplyPostProcessing().
+ * @param pHint An additional hint to the library. If this is a non empty string,
+ *   the library looks for a loader to support the file extension specified by pHint
+ *   and passes the file to the first matching loader. If this loader is unable to 
+ *   completely the request, the library continues and tries to determine the file
+ *   format on its own, a task that may or may not be successful. 
+ *   Check the return value, and you'll know ...
  * @param pProps #aiPropertyStore instance containing import settings. 
+ * @return A pointer to the imported data, NULL if the import failed.
+ *
+ * @note This is a straightforward way to decode models from memory
+ * buffers, but it doesn't handle model formats that spread their 
+ * data across multiple files or even directories. Examples include
+ * OBJ or MD3, which outsource parts of their material info into
+ * external scripts. If you need full functionality, provide
+ * a custom IOSystem to make Assimp find these files and use
+ * the regular aiImportFileEx()/aiImportFileExWithProperties() API.
  * @see aiImportFileFromMemory
  */
 ASSIMP_API const C_STRUCT aiScene* aiImportFileFromMemoryWithProperties( 
@@ -210,7 +242,7 @@ ASSIMP_API const C_STRUCT aiScene* aiImportFileFromMemoryWithProperties(
  *   meaning this is still the same #aiScene which you passed for pScene. However,
  *   _if_ post-processing failed, the scene could now be NULL. That's quite a rare
  *   case, post processing steps are not really designed to 'fail'. To be exact, 
- *   the #aiProcess_ValidateDS flag is currently the only post processing step 
+ *   the #aiProcess_ValidateDataStructure flag is currently the only post processing step 
  *   which can actually cause the scene to be reset to NULL.
  */
 ASSIMP_API const C_STRUCT aiScene* aiApplyPostProcessing(
@@ -266,7 +298,7 @@ ASSIMP_API void aiEnableVerboseLogging(aiBool d);
 // --------------------------------------------------------------------------------
 /** Detach a custom log stream from the libraries' logging system.
  *
- *  This is the counterpart of #aiAttachPredefinedLogStream. If you attached a stream,
+ *  This is the counterpart of #aiAttachLogStream. If you attached a stream,
  *  don't forget to detach it again.
  *  @param stream The log stream to be detached.
  *  @return AI_SUCCESS if the log stream has been detached successfully.
@@ -356,8 +388,9 @@ ASSIMP_API void aiReleasePropertyStore(C_STRUCT aiPropertyStore* p);
  *  interface, properties are always shared by all imports. It is not possible to 
  *  specify them per import.
  *
+ * @param store Store to modify. Use #aiCreatePropertyStore to obtain a store.
  * @param szName Name of the configuration property to be set. All supported 
- *   public properties are defined in the config.h header file (#AI_CONFIG_XXX).
+ *   public properties are defined in the config.h header file (AI_CONFIG_XXX).
  * @param value New value for the property
  */
 ASSIMP_API void aiSetImportPropertyInteger(
@@ -372,8 +405,9 @@ ASSIMP_API void aiSetImportPropertyInteger(
  *  interface, properties are always shared by all imports. It is not possible to 
  *  specify them per import.
  *
+ * @param store Store to modify. Use #aiCreatePropertyStore to obtain a store.
  * @param szName Name of the configuration property to be set. All supported 
- *   public properties are defined in the config.h header file (#AI_CONFIG_XXX).
+ *   public properties are defined in the config.h header file (AI_CONFIG_XXX).
  * @param value New value for the property
  */
 ASSIMP_API void aiSetImportPropertyFloat(
@@ -388,10 +422,10 @@ ASSIMP_API void aiSetImportPropertyFloat(
  *  interface, properties are always shared by all imports. It is not possible to 
  *  specify them per import.
  *
- * @param property store to modify. Use #aiCreatePropertyStore to obtain a store.
+ * @param store Store to modify. Use #aiCreatePropertyStore to obtain a store.
  * @param szName Name of the configuration property to be set. All supported 
- *   public properties are defined in the config.h header file (#AI_CONFIG_XXX).
- * @param value New value for the property
+ *   public properties are defined in the config.h header file (AI_CONFIG_XXX).
+ * @param st New value for the property
  */
 ASSIMP_API void aiSetImportPropertyString(
 	C_STRUCT aiPropertyStore* store,
@@ -405,10 +439,10 @@ ASSIMP_API void aiSetImportPropertyString(
  *  interface, properties are always shared by all imports. It is not possible to 
  *  specify them per import.
  *
- * @param property store to modify. Use #aiCreatePropertyStore to obtain a store.
+ * @param store Store to modify. Use #aiCreatePropertyStore to obtain a store.
  * @param szName Name of the configuration property to be set. All supported 
- *   public properties are defined in the config.h header file (#AI_CONFIG_XXX).
- * @param value New value for the property
+ *   public properties are defined in the config.h header file (AI_CONFIG_XXX).
+ * @param mat New value for the property
  */
 ASSIMP_API void aiSetImportPropertyMatrix(
 	C_STRUCT aiPropertyStore* store,

+ 1 - 1
include/assimp/color4.h

@@ -38,7 +38,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ---------------------------------------------------------------------------
 */
-/** @file aiColor4D.h
+/** @file color4.h
  *  @brief RGBA color structure, including operators when compiling in C++
  */
 #ifndef AI_COLOR4D_H_INC

+ 1 - 1
include/assimp/color4.inl

@@ -39,7 +39,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ---------------------------------------------------------------------------
 */
 
-/** @file  aiColor4D.inl
+/** @file  color4.inl
  *  @brief Inline implementation of aiColor4t<TReal> operators
  */
 #ifndef AI_COLOR4D_INL_INC

+ 13 - 12
include/assimp/config.h

@@ -209,7 +209,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 	"PP_RRM_EXCLUDE_LIST"
 
 // ---------------------------------------------------------------------------
-/** @brief Configures the #aiProcess_PretransformVertices step to
+/** @brief Configures the #aiProcess_PreTransformVertices step to
  *  keep the scene hierarchy. Meshes are moved to worldspace, but
  *  no optimization is performed (read: meshes with equal materials are not 
  *  joined. The total number of meshes won't change).
@@ -224,7 +224,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 	"PP_PTV_KEEP_HIERARCHY"
 
 // ---------------------------------------------------------------------------
-/** @brief Configures the #aiProcess_PretransformVertices step to normalize
+/** @brief Configures the #aiProcess_PreTransformVertices step to normalize
  *  all vertex components into the [-1,1] range. That is, a bounding box
  *  for the whole scene is computed, the maximum component is taken and all
  *  meshes are scaled appropriately (uniformly of course!).
@@ -234,7 +234,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 	"PP_PTV_NORMALIZE"
 
 // ---------------------------------------------------------------------------
-/** @brief Configures the #aiProcess_PretransformVertices step to use
+/** @brief Configures the #aiProcess_PreTransformVertices step to use
  *  a users defined matrix as the scene root node transformation before
  *  transforming vertices. 
  *  Property type: bool. Default value: false.
@@ -243,7 +243,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 	"PP_PTV_ADD_ROOT_TRANSFORMATION"
 
 // ---------------------------------------------------------------------------
-/** @brief Configures the #aiProcess_PretransformVertices step to use
+/** @brief Configures the #aiProcess_PreTransformVertices step to use
  *  a users defined matrix as the scene root node transformation before
  *  transforming vertices. This property correspond to the 'a1' component
  *  of the transformation matrix.
@@ -376,7 +376,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 // ---------------------------------------------------------------------------
 /** @brief Enumerates components of the aiScene and aiMesh data structures
- *  that can be excluded from the import using the #aiPrpcess_RemoveComponent step.
+ *  that can be excluded from the import using the #aiProcess_RemoveComponent step.
  *
  *  See the documentation to #aiProcess_RemoveComponent for more details.
  */
@@ -715,7 +715,7 @@ enum aiComponent
 /** @brief  Tells the MD3 loader which skin files to load.
  *
  * When loading MD3 files, Assimp checks whether a file 
- * <md3_file_name>_<skin_name>.skin is existing. These files are used by
+ * [md3_file_name]_[skin_name].skin is existing. These files are used by
  * Quake III to be able to assign different skins (e.g. red and blue team) 
  * to models. 'default', 'red', 'blue' are typical skin names.
  * Property type: String. Default value: "default".
@@ -728,14 +728,14 @@ enum aiComponent
  *  MD3 file. This can also be a search path.
  *
  * By default Assimp's behaviour is as follows: If a MD3 file 
- * <tt><any_path>/models/<any_q3_subdir>/<model_name>/<file_name>.md3</tt> is 
+ * <tt>any_path/models/any_q3_subdir/model_name/file_name.md3</tt> is 
  * loaded, the library tries to locate the corresponding shader file in
- * <tt><any_path>/scripts/<model_name>.shader</tt>. This property overrides this
+ * <tt>any_path/scripts/model_name.shader</tt>. This property overrides this
  * behaviour. It can either specify a full path to the shader to be loaded
  * or alternatively the path (relative or absolute) to the directory where
  * the shaders for all MD3s to be loaded reside. Assimp attempts to open 
- * <tt><dir>/<model_name>.shader</tt> first, <tt><dir>/<file_name>.shader</tt> 
- * is the fallback file. Note that <dir> should have a terminal (back)slash.
+ * <tt>IMPORT_MD3_SHADER_SRC/model_name.shader</tt> first, <tt>IMPORT_MD3_SHADER_SRC/file_name.shader</tt> 
+ * is the fallback file. Note that IMPORT_MD3_SHADER_SRC should have a terminal (back)slash.
  * Property type: String. Default value: n/a.
  */
 #define AI_CONFIG_IMPORT_MD3_SHADER_SRC \
@@ -818,12 +818,13 @@ enum aiComponent
 /** @brief Ogre Importer detect the texture usage from its filename.
  *
  * Ogre material texture units do not define texture type, the textures usage
- * depends on the used shader or Ogres fixed pipeline. If this config property
+ * depends on the used shader or Ogre's fixed pipeline. If this config property
  * is true Assimp will try to detect the type from the textures filename postfix:
  * _n, _nrm, _nrml, _normal, _normals and _normalmap for normal map, _s, _spec,
  * _specular and _specularmap for specular map, _l, _light, _lightmap, _occ 
  * and _occlusion for light map, _disp and _displacement for displacement map.
- * The matching is case insensitive. Post fix is taken between last "_" and last ".".
+ * The matching is case insensitive. Post fix is taken between the last 
+ * underscore and the last period.
  * Default behavior is to detect type from lower cased texture unit name by 
  * matching against: normalmap, specularmap, lightmap and displacementmap.
  * For both cases if no match is found aiTextureType_DIFFUSE is used.

+ 1 - 1
include/assimp/defs.h

@@ -39,7 +39,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ---------------------------------------------------------------------------
 */
 
-/** @file aiDefines.h
+/** @file defs.h
  *  @brief Assimp build configuration setup. See the notes in the comment
  *  blocks to find out how to customize _your_ Assimp build.
  */

+ 1 - 2
include/assimp/importerdesc.h

@@ -98,8 +98,7 @@ struct aiImporterDesc
 	/** Implementation comments, i.e. unimplemented features*/
 	const char* mComments;
 
-	/** Any combination of the #aiLoaderFlags enumerated values.
-	    These flags indicate some characteristics common to many
+	/** These flags indicate some characteristics common to many
 		importers. */
 	unsigned int mFlags;
 

+ 8 - 38
include/assimp/material.h

@@ -95,14 +95,9 @@ enum aiTextureOp
 	aiTextureOp_SignedAdd = 0x5,
 
 
-	/** @cond never 
-	 *  This value is not used. It forces the compiler to use at least
-	 *  32 Bit integers to represent this enum.
-	 */
 #ifndef SWIG
 	_aiTextureOp_Force32Bit = INT_MAX
 #endif
-	//! @endcond
 };
 
 // ---------------------------------------------------------------------------
@@ -131,14 +126,9 @@ enum aiTextureMapMode
      */
     aiTextureMapMode_Mirror = 0x2,
 
-	 /** @cond never 
-	  *  This value is not used. It forces the compiler to use at least
-	  *  32 Bit integers to represent this enum.
-	  */
 #ifndef SWIG
 	_aiTextureMapMode_Force32Bit = INT_MAX
 #endif
-	//! @endcond
 };
 
 // ---------------------------------------------------------------------------
@@ -176,14 +166,9 @@ enum aiTextureMapping
     aiTextureMapping_OTHER = 0x5,
 
 
-	 /** @cond never 
-	  *  This value is not used. It forces the compiler to use at least
-	  *  32 Bit integers to represent this enum.
-	  */
 #ifndef SWIG
 	_aiTextureMapping_Force32Bit = INT_MAX
 #endif
-	//! @endcond
 };
 
 // ---------------------------------------------------------------------------
@@ -296,14 +281,9 @@ enum aiTextureType
     aiTextureType_UNKNOWN = 0xC,
 
 
-	 /** @cond never 
-	  *  This value is not used. It forces the compiler to use at least
-	  *  32 Bit integers to represent this enum.
-	  */
 #ifndef SWIG
 	_aiTextureType_Force32Bit = INT_MAX
 #endif
-	//! @endcond
 };
 
 #define AI_TEXTURE_TYPE_MAX  aiTextureType_UNKNOWN
@@ -374,14 +354,9 @@ enum aiShadingMode
     aiShadingMode_Fresnel = 0xa,
 
 
-	 /** @cond never 
-	  *  This value is not used. It forces the compiler to use at least
-	  *  32 Bit integers to represent this enum.
-	  */
 #ifndef SWIG
 	_aiShadingMode_Force32Bit = INT_MAX
 #endif
-	//! @endcond
 };
 
 
@@ -420,14 +395,9 @@ enum aiTextureFlags
 	 */
 	aiTextureFlags_IgnoreAlpha = 0x4,
 	
-	 /** @cond never 
-	  *  This value is not used. It forces the compiler to use at least
-	  *  32 Bit integers to represent this enum.
-	  */
 #ifndef SWIG
 	  _aiTextureFlags_Force32Bit = INT_MAX
 #endif
-	//! @endcond
 };
 
 
@@ -442,8 +412,8 @@ enum aiTextureFlags
  *  @code
  *    SourceColor * SourceBlend + DestColor * DestBlend
  *  @endcode
- *  where <DestColor> is the previous color in the framebuffer at this
- *  position and <SourceColor> is the material colro before the transparency
+ *  where DestColor is the previous color in the framebuffer at this
+ *  position and SourceColor is the material colro before the transparency
  *  calculation.<br>
  *  This corresponds to the #AI_MATKEY_BLEND_FUNC property.
 */
@@ -469,14 +439,9 @@ enum aiBlendMode
 	// we don't need more for the moment, but we might need them
 	// in future versions ...
 
-	 /** @cond never 
-	  *  This value is not used. It forces the compiler to use at least
-	  *  32 Bit integers to represent this enum.
-	  */
 #ifndef SWIG
 	_aiBlendMode_Force32Bit = INT_MAX
 #endif
-	//! @endcond
 };
 
 
@@ -862,7 +827,9 @@ public:
 	/** @brief Remove a given key from the list.
 	 *
 	 *  The function fails if the key isn't found
-	 *  @param pKey Key to be deleted */
+	 *  @param pKey Key to be deleted 
+	 *  @param type Set by the AI_MATKEY_XXX macro
+	 *  @param index Set by the AI_MATKEY_XXX macro  */
 	aiReturn RemoveProperty (const char* pKey,
 		unsigned int type  = 0,
 		unsigned int index = 0);
@@ -1330,6 +1297,8 @@ extern "C" {
 #define AI_MATKEY_TEXFLAGS_UNKNOWN(N)	\
 	AI_MATKEY_TEXFLAGS(aiTextureType_UNKNOWN,N)
 
+//! @endcond
+//!
 // ---------------------------------------------------------------------------
 /** @brief Retrieve a material property with a specific key from the material
  *
@@ -1537,6 +1506,7 @@ ASSIMP_API unsigned int aiGetMaterialTextureCount(const C_STRUCT aiMaterial* pMa
  *      Pass NULL if you're not interested in this information. Otherwise,
  *      pass a pointer to an array of two aiTextureMapMode's (one for each
  *      axis, UV order).
+ *  @param[out] flags Receives the the texture flags.
  *  @return AI_SUCCESS on success, otherwise something else. Have fun.*/
 // ---------------------------------------------------------------------------
 #ifdef __cplusplus

+ 1 - 1
include/assimp/material.inl

@@ -39,7 +39,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ---------------------------------------------------------------------------
 */
 
-/** @file aiMaterial.inl
+/** @file material.inl
  *  @brief Defines the C++ getters for the material system
  */
 

+ 1 - 1
include/assimp/matrix3x3.inl

@@ -39,7 +39,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ---------------------------------------------------------------------------
 */
 
-/** @file aiMatrix3x3.inl
+/** @file matrix3x3.inl
  *  @brief Inline implementation of the 3x3 matrix operators
  */
 #ifndef AI_MATRIX3x3_INL_INC

+ 2 - 2
include/assimp/matrix4x4.inl

@@ -39,7 +39,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ---------------------------------------------------------------------------
 */
 
-/** @file aiMatrix4x4t<TReal>.inl
+/** @file matrix4x4.inl
  *  @brief Inline implementation of the 4x4 matrix operators
  */
 #ifndef AI_MATRIX4x4_INL_INC
@@ -52,7 +52,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "quaternion.h"
 
 #include <algorithm>
-#include <limits>
+#include <limits>
 #include <cmath>
 
 // ----------------------------------------------------------------------------------------

+ 1 - 2
include/assimp/mesh.h

@@ -668,8 +668,7 @@ struct aiMesh
 	}
 
 	//! Check whether the mesh contains positions. Provided no special
-	//! scene flags are set (such as #AI_SCENE_FLAGS_ANIM_SKELETON_ONLY), 
-	//! this will always be true 
+	//! scene flags are set, this will always be true 
 	bool HasPositions() const 
 		{ return mVertices != NULL && mNumVertices > 0; }
 

+ 1 - 0
include/assimp/metadata.h

@@ -50,6 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #if defined(_MSC_VER) && (_MSC_VER <= 1500)
 #include "Compiler/pstdint.h"
 #else
+#include <limits.h>
 #include <stdint.h>
 #endif
 

+ 4 - 4
include/assimp/postprocess.h

@@ -282,7 +282,7 @@ enum aiPostProcessSteps
 	/** <hr>Searches for redundant/unreferenced materials and removes them.
 	 *
 	 * This is especially useful in combination with the 
-	 * #aiProcess_PretransformVertices and #aiProcess_OptimizeMeshes flags. 
+	 * #aiProcess_PreTransformVertices and #aiProcess_OptimizeMeshes flags. 
 	 * Both join small meshes with equal characteristics, but they can't do 
 	 * their work if two meshes have different materials. Because several
 	 * material settings are lost during Assimp's import filters,
@@ -335,7 +335,7 @@ enum aiPostProcessSteps
 	 * To have the degenerate stuff not only detected and collapsed but
 	 * removed, try one of the following procedures:
 	 * <br><b>1.</b> (if you support lines and points for rendering but don't
-	 *    want the degenerates)</br>
+	 *    want the degenerates)<br>
 	 * <ul>
 	 *   <li>Specify the #aiProcess_FindDegenerates flag.
 	 *   </li>
@@ -345,7 +345,7 @@ enum aiPostProcessSteps
 	 *       pipeline steps.
 	 *   </li>
 	 * </ul>
-	 * <br><b>2.</b>(if you don't support lines and points at all)</br>
+	 * <br><b>2.</b>(if you don't support lines and points at all)<br>
 	 * <ul>
 	 *   <li>Specify the #aiProcess_FindDegenerates flag.
 	 *   </li>
@@ -550,7 +550,7 @@ enum aiPostProcessSteps
 
 
 // ---------------------------------------------------------------------------------------
-/** @def aiProcessPreset_TargetRealtimeUse_Fast
+/** @def aiProcessPreset_TargetRealtime_Fast
  *  @brief Default postprocess configuration optimizing the data for real-time rendering.
  *  
  *  Applications would want to use this preset to load models on end-user PCs,

+ 2 - 3
include/assimp/quaternion.inl

@@ -39,7 +39,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ---------------------------------------------------------------------------
 */
 
-/** @file  aiQuaterniont.inl
+/** @file  quaternion.inl
  *  @brief Inline implementation of aiQuaterniont<TReal> operators
  */
 #ifndef AI_QUATERNION_INL_INC
@@ -273,11 +273,10 @@ template<typename TReal>
 inline aiVector3t<TReal> aiQuaterniont<TReal>::Rotate (const aiVector3t<TReal>& v)
 {
 	aiQuaterniont q2(0.f,v.x,v.y,v.z), q = *this, qinv = q;
-	q.Conjugate();
+	qinv.Conjugate();
 
 	q = q*q2*qinv;
 	return aiVector3t<TReal>(q.x,q.y,q.z);
-
 }
 
 #endif

+ 6 - 8
include/assimp/scene.h

@@ -39,7 +39,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ---------------------------------------------------------------------------
 */
 
-/** @file aiScene.h
+/** @file scene.h
  *  @brief Defines the data structures in which the imported scene is returned.
  */
 #ifndef __AI_SCENE_H_INC__
@@ -182,8 +182,6 @@ struct aiNode
 	}
 
 
-	/** @override
-	 */
 	inline const aiNode* FindNode(const char* name) const
 	{
 		if (!::strcmp( mName.data,name))return this;
@@ -217,7 +215,7 @@ struct aiNode
 
 
 // -------------------------------------------------------------------------------
-/** @def AI_SCENE_FLAGS_INCOMPLETE
+/**
  * Specifies that the scene data structure that was imported is not complete.
  * This flag bypasses some internal validations and allows the import 
  * of animation skeletons, material libraries or camera animation paths 
@@ -225,14 +223,14 @@ struct aiNode
  */
 #define AI_SCENE_FLAGS_INCOMPLETE	0x1
 
-/** @def AI_SCENE_FLAGS_VALIDATED
+/**
  * This flag is set by the validation postprocess-step (aiPostProcess_ValidateDS)
  * if the validation is successful. In a validated scene you can be sure that
  * any cross references in the data structure (e.g. vertex indices) are valid.
  */
 #define AI_SCENE_FLAGS_VALIDATED	0x2
 
-/** @def AI_SCENE_FLAGS_VALIDATION_WARNING
+/**
  * This flag is set by the validation postprocess-step (aiPostProcess_ValidateDS)
  * if the validation is successful but some issues have been found.
  * This can for example mean that a texture that does not exist is referenced 
@@ -242,7 +240,7 @@ struct aiNode
  */
 #define AI_SCENE_FLAGS_VALIDATION_WARNING  	0x4
 
-/** @def AI_SCENE_FLAGS_NON_VERBOSE_FORMAT
+/**
  * This flag is currently only set by the aiProcess_JoinIdenticalVertices step.
  * It indicates that the vertices of the output meshes aren't in the internal
  * verbose format anymore. In the verbose format all vertices are unique,
@@ -250,7 +248,7 @@ struct aiNode
  */
 #define AI_SCENE_FLAGS_NON_VERBOSE_FORMAT  	0x8
 
- /** @def AI_SCENE_FLAGS_TERRAIN
+ /**
  * Denotes pure height-map terrain data. Pure terrains usually consist of quads, 
  * sometimes triangles, in a regular grid. The x,y coordinates of all vertex 
  * positions refer to the x,y coordinates on the terrain height map, the z-axis

+ 7 - 3
include/assimp/types.h

@@ -241,7 +241,7 @@ struct aiColor3D
  *  For most applications, it will be absolutely sufficient to interpret the
  *  aiString as ASCII data and work with it as one would work with a plain char*. 
  *  Windows users in need of proper support for i.e asian characters can use the
- *  #MultiByteToWideChar(), #WideCharToMultiByte() WinAPI functionality to convert the
+ *  MultiByteToWideChar(), WideCharToMultiByte() WinAPI functionality to convert the
  *  UTF-8 strings to their working character set (i.e. MBCS, WideChar).
  *
  *  We use this representation instead of std::string to be C-compatible. The 
@@ -388,6 +388,8 @@ typedef enum aiReturn
 	 *  Force 32-bit size enum
 	 */
 	_AI_ENFORCE_ENUM_SIZE = 0x7fffffff 
+
+    /// @endcond
 } aiReturn;  // !enum aiReturn
 
 // just for backwards compatibility, don't use these constants anymore
@@ -414,13 +416,14 @@ enum aiOrigin
 	 *   Force 32-bit size enum 
 	 */
 	_AI_ORIGIN_ENFORCE_ENUM_SIZE = 0x7fffffff 
+	
+	/// @endcond
 }; // !enum aiOrigin
 
 // ----------------------------------------------------------------------------------
 /** @brief Enumerates predefined log streaming destinations. 
  *  Logging to these streams can be enabled with a single call to 
- *   #LogStream::createDefaultStream or #aiAttachPredefinedLogStream(),
- *   respectively.
+ *   #LogStream::createDefaultStream.
  */
 enum aiDefaultLogStream	
 {
@@ -442,6 +445,7 @@ enum aiDefaultLogStream
 	 *  Force 32-bit size enum 
 	 */
 	_AI_DLS_ENFORCE_ENUM_SIZE = 0x7fffffff 
+	/// @endcond
 }; // !enum aiDefaultLogStream
 
 // just for backwards compatibility, don't use these constants anymore

+ 3 - 3
include/assimp/vector2.h

@@ -38,18 +38,18 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ---------------------------------------------------------------------------
 */
-/** @file aiVector2t.h
+/** @file vector2.h
  *  @brief 2D vector structure, including operators when compiling in C++
  */
 #ifndef AI_VECTOR2D_H_INC
 #define AI_VECTOR2D_H_INC
-
+
 #ifdef __cplusplus
 #   include <cmath>
 #else
 #   include <math.h>
 #endif
-
+
 #include "./Compiler/pushpack1.h"
 
 // ----------------------------------------------------------------------------------

+ 1 - 1
include/assimp/vector2.inl

@@ -39,7 +39,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ---------------------------------------------------------------------------
 */
 
-/** @file  aiVector2D.inl
+/** @file  vector2.inl
  *  @brief Inline implementation of aiVector2t<TReal> operators
  */
 #ifndef AI_VECTOR2D_INL_INC

+ 3 - 3
include/assimp/vector3.h

@@ -38,18 +38,18 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ---------------------------------------------------------------------------
 */
-/** @file aiVector3D.h
+/** @file vector3.h
  *  @brief 3D vector structure, including operators when compiling in C++
  */
 #ifndef AI_VECTOR3D_H_INC
 #define AI_VECTOR3D_H_INC
-
+
 #ifdef __cplusplus
 #   include <cmath>
 #else
 #   include <math.h>
 #endif
-
+
 #include "./Compiler/pushpack1.h"
 
 #ifdef __cplusplus

+ 1 - 1
include/assimp/vector3.inl

@@ -39,7 +39,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ---------------------------------------------------------------------------
 */
 
-/** @file  aiVector3D.inl
+/** @file  vector3.inl
  *  @brief Inline implementation of aiVector3t<TReal> operators
  */
 #ifndef AI_VECTOR3D_INL_INC

+ 1 - 1
include/assimp/version.h

@@ -39,7 +39,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ---------------------------------------------------------------------------
 */
 
-/** @file  aiVersion.h
+/** @file  version.h
  *  @brief Functions to query the version of the Assimp runtime, check
  *    compile flags, ...
  */

+ 23 - 38
port/PyAssimp/pyassimp/core.py

@@ -1,5 +1,3 @@
-#-*- coding: UTF-8 -*-
-
 """
 PyAssimp
 
@@ -21,37 +19,31 @@ logger = logging.getLogger("pyassimp")
 logger.addHandler(logging.NullHandler())
 
 from . import structs
-from .errors import AssimpError
 from . import helper
+from . import postprocess
+from .errors import AssimpError
+from .formats import available_formats
 
-assimp_structs_as_tuple = (
-        structs.Matrix4x4, 
-        structs.Matrix3x3, 
-        structs.Vector2D, 
-        structs.Vector3D, 
-        structs.Color3D, 
-        structs.Color4D, 
-        structs.Quaternion, 
-        structs.Plane, 
-        structs.Texel)
+class AssimpLib(object):
+    """
+    Assimp-Singleton
+    """
+    load, load_mem, release, dll = helper.search_library()
+_assimp_lib = AssimpLib()
 
 def make_tuple(ai_obj, type = None):
     res = None
-
     if isinstance(ai_obj, structs.Matrix4x4):
         res = numpy.array([getattr(ai_obj, e[0]) for e in ai_obj._fields_]).reshape((4,4))
-        #import pdb;pdb.set_trace()
     elif isinstance(ai_obj, structs.Matrix3x3):
         res = numpy.array([getattr(ai_obj, e[0]) for e in ai_obj._fields_]).reshape((3,3))
     else:
         res = numpy.array([getattr(ai_obj, e[0]) for e in ai_obj._fields_])
-
     return res
 
 # It is faster and more correct to have an init function for each assimp class
 def _init_face(aiFace):
     aiFace.indices = [aiFace.mIndices[i] for i in range(aiFace.mNumIndices)]
-    
 assimp_struct_inits =  { structs.Face : _init_face }
     
 def call_init(obj, caller = None):
@@ -112,7 +104,7 @@ def _init(self, target = None, parent = None):
         obj = getattr(self, m)
 
         # Create tuples
-        if isinstance(obj, assimp_structs_as_tuple):
+        if isinstance(obj, structs.assimp_structs_as_tuple):
             setattr(target, name, make_tuple(obj))
             logger.debug(str(self) + ": Added array " + str(getattr(target, name)) +  " as self." + name.lower())
             continue
@@ -142,7 +134,7 @@ def _init(self, target = None, parent = None):
                 
 
                 try:
-                    if obj._type_ in assimp_structs_as_tuple:
+                    if obj._type_ in structs.assimp_structs_as_tuple:
                         setattr(target, name, numpy.array([make_tuple(obj[i]) for i in range(length)], dtype=numpy.float32))
 
                         logger.debug(str(self) + ": Added an array of numpy arrays (type "+ str(type(obj)) + ") as self." + name)
@@ -178,19 +170,16 @@ def _init(self, target = None, parent = None):
                                      " a post-processing to triangulate your"
                                      " faces.")
                     raise e
+                    
 
 
             else: # starts with 'm' but not iterable
-
                 setattr(target, name, obj)
                 logger.debug("Added " + name + " as self." + name + " (type: " + str(type(obj)) + ")")
         
                 if _is_init_type(obj):
                     call_init(obj, target)
 
-
-
-
     if isinstance(self, structs.Mesh):
         _finalize_mesh(self, target)
 
@@ -200,14 +189,6 @@ def _init(self, target = None, parent = None):
 
     return self
 
-class AssimpLib(object):
-    """
-    Assimp-Singleton
-    """
-    load, load_mem, release, dll = helper.search_library()
-
-#the loader as singleton
-_assimp_lib = AssimpLib()
 
 def pythonize_assimp(type, obj, scene):
     """ This method modify the Assimp data structures
@@ -247,17 +228,16 @@ def recur_pythonize(node, scene):
     pythonize the assimp datastructures.
     '''
     node.meshes = pythonize_assimp("MESH", node.meshes, scene)
-    
     for mesh in node.meshes:
         mesh.material = scene.materials[mesh.materialindex]
-
     for cam in scene.cameras:
         pythonize_assimp("ADDTRANSFORMATION", cam, scene)
-
     for c in node.children:
         recur_pythonize(c, scene)
 
-def load(filename, processing=0, file_type=None):
+def load(filename, 
+         file_type  = None,
+         processing = postprocess.aiProcess_Triangulate):
     '''
     Load a model into a scene. On failure throws AssimpError.
     
@@ -267,12 +247,17 @@ def load(filename, processing=0, file_type=None):
                 If a file object is passed, file_type MUST be specified
                 Otherwise Assimp has no idea which importer to use.
                 This is named 'filename' so as to not break legacy code. 
-    processing: assimp processing parameters
-    file_type:  string, such as 'stl'
+    processing: assimp postprocessing parameters. Verbose keywords are imported
+                from postprocessing, and the parameters can be combined bitwise to
+                generate the final processing value. Note that the default value will
+                triangulate quad faces. Example of generating other possible values:
+                processing = (pyassimp.postprocess.aiProcess_Triangulate | 
+                              pyassimp.postprocess.aiProcess_OptimizeMeshes)
+    file_type:  string of file extension, such as 'stl'
         
     Returns
     ---------
-    Scene object with model-data
+    Scene object with model data
     '''
     
     if hasattr(filename, 'read'):

+ 41 - 0
port/PyAssimp/pyassimp/formats.py

@@ -0,0 +1,41 @@
+FORMATS = ["CSM", 
+            "LWS", 
+            "B3D", 
+            "COB", 
+            "PLY", 
+            "IFC", 
+            "OFF", 
+            "SMD", 
+            "IRRMESH", 
+            "3D", 
+            "DAE", 
+            "MDL", 
+            "HMP", 
+            "TER", 
+            "WRL", 
+            "XML", 
+            "NFF", 
+            "AC", 
+            "OBJ", 
+            "3DS", 
+            "STL", 
+            "IRR", 
+            "Q3O",
+            "Q3D"
+            "MS3D", 
+            "Q3S", 
+            "ZGL", 
+            "MD2", 
+            "X", 
+            "BLEND", 
+            "XGL", 
+            "MD5MESH", 
+            "MAX", 
+            "LXO", 
+            "DXF", 
+            "BVH", 
+            "LWO",
+            "NDO"]
+
+def available_formats():
+    return FORMATS

+ 10 - 0
port/PyAssimp/pyassimp/structs.py

@@ -897,3 +897,13 @@ class Scene(Structure):
             # the scene.
             ("mCameras", POINTER(POINTER(Camera))),
         ]
+
+assimp_structs_as_tuple = (Matrix4x4,
+                           Matrix3x3,
+                           Vector2D,
+                           Vector3D,
+                           Color3D,
+                           Color4D,
+                           Quaternion,
+                           Plane,
+                           Texel)

+ 5 - 5
samples/SimpleOpenGL/CMakeLists.txt

@@ -19,16 +19,16 @@ INCLUDE_DIRECTORIES(
 	${GLUT_INCLUDE_DIR}
 )
 
-LINK_DIRECTORIES( 
-	${Assimp_BINARY_DIR} 
-	${Assimp_BINARY_DIR}/lib 
+LINK_DIRECTORIES(
+	${Assimp_BINARY_DIR}
+	${Assimp_BINARY_DIR}/lib
 )
 
 ADD_EXECUTABLE( assimp_simpleogl
 	Sample_SimpleOpenGL.c
 )
 
-SET_PROPERTY(TARGET assimp_simpleogl PROPERTY DEBUG_POSTFIX ${ASSIMP_DEBUG_POSTFIX})
+SET_PROPERTY(TARGET assimp_simpleogl PROPERTY DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
 
 TARGET_LINK_LIBRARIES( assimp_simpleogl assimp ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES} ${M_LIB} )
 SET_TARGET_PROPERTIES( assimp_simpleogl PROPERTIES
@@ -37,4 +37,4 @@ SET_TARGET_PROPERTIES( assimp_simpleogl PROPERTIES
 
 INSTALL( TARGETS assimp_simpleogl
 	DESTINATION "${ASSIMP_BIN_INSTALL_DIR}" COMPONENT assimp-dev
-) 
+)

+ 4 - 4
samples/SimpleTexturedOpenGL/CMakeLists.txt

@@ -19,8 +19,8 @@ INCLUDE_DIRECTORIES(
 	${Assimp_SOURCE_DIR}/samples/DevIL/include/
 )
 
-LINK_DIRECTORIES( 
-	${Assimp_BINARY_DIR} 
+LINK_DIRECTORIES(
+	${Assimp_BINARY_DIR}
 	${Assimp_BINARY_DIR}/lib/
 	${Assimp_SOURCE_DIR}/samples/DevIL/lib/
 )
@@ -30,7 +30,7 @@ ADD_EXECUTABLE( assimp_simpletexturedogl WIN32
 	SimpleTexturedOpenGL/src/model_loading.cpp
 )
 
-SET_PROPERTY(TARGET assimp_simpletexturedogl PROPERTY DEBUG_POSTFIX ${ASSIMP_DEBUG_POSTFIX})
+SET_PROPERTY(TARGET assimp_simpletexturedogl PROPERTY DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
 
 TARGET_LINK_LIBRARIES( assimp_simpletexturedogl assimp ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES} DevIL.lib )
 
@@ -40,4 +40,4 @@ SET_TARGET_PROPERTIES( assimp_simpletexturedogl PROPERTIES
 
 INSTALL( TARGETS assimp_simpletexturedogl
 	DESTINATION "${ASSIMP_BIN_INSTALL_DIR}" COMPONENT assimp-dev
-) 
+)

+ 1 - 1
test/CMakeLists.txt

@@ -52,7 +52,7 @@ add_executable( unit
     ${TEST_SRCS}
 )
 
-SET_PROPERTY( TARGET assimp PROPERTY DEBUG_POSTFIX ${ASSIMP_DEBUG_POSTFIX} )
+SET_PROPERTY( TARGET assimp PROPERTY DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX} )
 
 add_dependencies( unit gtest )
 target_link_libraries( unit assimp

+ 22 - 7
test/regression/gen_db.py

@@ -40,8 +40,15 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 # ---------------------------------------------------------------------------
 
-"""Generate the regression database db.zip from the files in the <root>
-/test/models directory. Older databases are overwritten with no prompt.
+"""
+Generate the regression database db.zip from the files in the <root>/test/models
+directory. Older databases are overwritten with no prompt but can be restored
+using Git as needed.
+
+Use --help for usage.
+
+On Windows, use ``py run.py <arguments>`` to make sure command line parameters
+are forwarded to the script.
 """
 
 import sys
@@ -52,9 +59,14 @@ import zipfile
 import settings
 import utils
 
-usage = """gen_db [-i=...] [-e=...] [-p] [-n]
+usage = """gen_db [assimp_binary] [-i=...] [-e=...] [-p] [-n]
+
+The assimp_cmd (or assimp) binary to use is specified by the first
+command line argument and defaults to ``assimp``.
+
+To build, set ``ASSIMP_BUILD_ASSIMP_TOOLS=ON`` in CMake. If generating
+configs for an IDE, make sure to build the assimp_cmd project.
 
-(lists of file extensions are comma delimited, i.e. `3ds,lwo,x`)
 -i,--include: List of file extensions to update dumps for. If omitted,
          all file extensions are updated except those in `exclude`.
 
@@ -66,6 +78,8 @@ usage = """gen_db [-i=...] [-e=...] [-p] [-n]
          Dont' change anything.
 
 -n,--nozip: Don't pack to ZIP archive. Keep all dumps in individual files.
+
+(lists of file extensions are comma delimited, i.e. `3ds,lwo,x`)
 """
 
 # -------------------------------------------------------------------------------
@@ -87,7 +101,7 @@ def process_dir(d, outfile, file_filter):
                 outf = os.path.join(os.getcwd(), settings.database_name,
                     utils.hashing(fullp, pp))
 
-                cmd = [utils.assimp_bin_path,"dump",fullp,outf,"-b","-s","-l"] + pp.split()
+                cmd = [ assimp_bin_path, "dump", fullp, outf, "-b", "-s", "-l" ] + pp.split()
                 outfile.write("assimp dump "+"-"*80+"\n")
                 outfile.flush()
                 if subprocess.call(cmd, stdout=outfile, stderr=outfile, shell=False):
@@ -158,7 +172,8 @@ def gen_db(ext_list,outfile):
 
 # -------------------------------------------------------------------------------
 if __name__ == "__main__":
-    utils.find_assimp_or_die()
+    assimp_bin_path = sys.argv[1] if len(sys.argv) > 1 else 'assimp'
+
     def clean(f):
         f = f.strip("* \'")
         return "."+f if f[:1] != '.' else f
@@ -184,7 +199,7 @@ if __name__ == "__main__":
             
     outfile = open(os.path.join("..", "results", "gen_regression_db_output.txt"), "w")
     if ext_list is None:
-        (ext_list, err) = subprocess.Popen([utils.assimp_bin_path, "listext"],
+        (ext_list, err) = subprocess.Popen([assimp_bin_path, "listext"],
             stdout=subprocess.PIPE).communicate()
         ext_list = str(ext_list).lower().split(";")
 

+ 30 - 10
test/regression/run.py

@@ -41,8 +41,16 @@
 # ---------------------------------------------------------------------------
 
 """
-Run the regression test suite using the settings from settings.py.
+Run the regression test suite using settings from settings.py.
 
+The assimp_cmd (or assimp) binary to use is specified by the first
+command line argument and defaults to ``assimp``.
+
+To build, set ``ASSIMP_BUILD_ASSIMP_TOOLS=ON`` in CMake. If generating
+configs for an IDE, make sure to build the assimp_cmd project.
+
+On Windows, use ``py run.py <path to assimp>`` to make sure the command
+line parameter is forwarded to the script.
 """
 
 import sys
@@ -124,8 +132,11 @@ class results:
     def report_results(self):
         """Write results to ../results/run_regression_suite_failures.txt"""
 
+        count_success = len(self.success)
+        count_fail = len(self.failures)
+        percent_good = float(count_success) / (count_success + count_fail)
         print("\n" + ('='*60) + "\n" + "SUCCESS: {0}\nFAILURE: {1}\nPercentage good: {2}".format(
-            len(self.success), len(self.failures), len(self.success)/(len(self.success)+len(self.failures))  ) + 
+            count_success, count_fail, percent_good) + 
               "\n" + ('='*60) + "\n")
 
         with open(os.path.join('..', 'results',outfilename_failur), "wt") as f:
@@ -138,7 +149,7 @@ class results:
                  + " for more details\n\n") 
     
 # -------------------------------------------------------------------------------
-def mkoutputdir_andgetpath(fullpath, myhash, app):
+def prepare_output_dir(fullpath, myhash, app):
     outfile = os.path.join(settings.results, "tmp", os.path.split(fullpath)[1] + "_" + myhash)
     try:
         os.mkdir(outfile)
@@ -154,7 +165,7 @@ def process_dir(d, outfile_results, zipin, result):
     shellparams = {'stdout':outfile_results, 'stderr':outfile_results, 'shell':False}
 
     print("Processing directory " + d)
-    for f in os.listdir(d):
+    for f in sorted(os.listdir(d)):
         fullpath = os.path.join(d, f)
         if os.path.isdir(fullpath) and not f == ".svn":
             process_dir(fullpath, outfile_results, zipin, result)
@@ -167,13 +178,16 @@ def process_dir(d, outfile_results, zipin, result):
         for pppreset in settings.pp_configs_to_test:
             filehash = utils.hashing(fullpath, pppreset)
             failure = False
+
             try:
                 input_expected = zipin.open(filehash, "r").read()
                 # empty dump files indicate 'expected import failure'
                 if not len(input_expected):
                    failure = True
             except KeyError:
-                #print("Didn't find "+fullpath+" (Hash is "+filehash+") in database")
+                # TODO(acgessler): Keep track of this and report as error in the end.
+                print("Didn't find "+fullpath+" (Hash is "+filehash+") in database. Outdated "+\
+                    "regression database? Use gen_db.zip to re-generate.")
                 continue
 
             # Ignore extensions via settings.py configured list
@@ -184,13 +198,18 @@ def process_dir(d, outfile_results, zipin, result):
 
             print("-"*60 + "\n  " + os.path.realpath(fullpath) + " pp: " + pppreset) 
             
-            outfile_actual = mkoutputdir_andgetpath(fullpath, filehash, "ACTUAL")
-            outfile_expect = mkoutputdir_andgetpath(fullpath, filehash, "EXPECT")
+            outfile_actual = prepare_output_dir(fullpath, filehash, "ACTUAL")
+            outfile_expect = prepare_output_dir(fullpath, filehash, "EXPECT")
             outfile_results.write("assimp dump    "+"-"*80+"\n")
             outfile_results.flush()
 
-            command = [utils.assimp_bin_path,"dump",fullpath,outfile_actual,"-b","-s","-l"]+pppreset.split()
+            command = [assimp_bin_path,
+                "dump",
+                fullpath, outfile_actual, "-b", "-s", "-l" ] +\
+                pppreset.split()
+
             r = subprocess.call(command, **shellparams)
+            print(r)
 
             if r and not failure:
                 result.fail(fullpath, outfile_expect, pppreset, IMPORT_FAILURE, r)
@@ -216,7 +235,7 @@ def process_dir(d, outfile_results, zipin, result):
             outfile_results.write("assimp cmpdump "+"-"*80+"\n")
             outfile_results.flush()
 
-            command = [utils.assimp_bin_path,'cmpdump',outfile_actual,outfile_expect]
+            command = [ assimp_bin_path, 'cmpdump', outfile_actual, outfile_expect ]
             if subprocess.call(command, **shellparams) != 0:
                 result.fail(fullpath, outfile_expect, pppreset, DATABASE_VALUE_MISMATCH)
                 continue 
@@ -235,7 +254,6 @@ def del_folder_with_contents(folder):
 
 # -------------------------------------------------------------------------------
 def run_test():
-    utils.find_assimp_or_die()
     tmp_target_path = os.path.join(settings.results, "tmp")
     try: 
         os.mkdir(tmp_target_path) 
@@ -261,6 +279,8 @@ def run_test():
 
 # -------------------------------------------------------------------------------
 if __name__ == "__main__":
+    assimp_bin_path = sys.argv[1] if len(sys.argv) > 1 else 'assimp'
+    print('Using assimp binary: ' + assimp_bin_path)
     run_test()
 
 # vim: ai ts=4 sts=4 et sw=4

+ 8 - 69
test/regression/utils.py

@@ -40,7 +40,7 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 # ---------------------------------------------------------------------------
 
-"""Shared stuff for the gen_db and run scripts """
+"""Shared stuff for the gen_db and run scripts"""
 
 # -------------------------------------------------------------------------------
 def hashing(file,pp):
@@ -51,75 +51,14 @@ def hashing(file,pp):
     and platforms, so we implement the hashing manually.
     """
 
-    def myhash(instring):
-        # sdbm hash
-        res = 0
-        for t in instring:
-            res = (ord(t) + (res<<6) + (res<<16) - res) % 2**32
-        return res
+    file = file.replace('\\','/')+":"+pp
+    # SDBM hash
+    res = 0
+    for t in file:
+        res = (ord(t) + (res<<6) + (res<<16) - res) % 2**32
 
-    return hex(myhash(file.replace('\\','/')+":"+pp))
+    # Python 2.7 normalization: strip 'L' suffix.
+    return hex(res).rstrip('L')
 
 
-assimp_bin_path = None
-# -------------------------------------------------------------------------------
-def find_assimp_or_die():
-    """Find assimp_cmd's binary for the current platform.
-    
-    The path to the binary is stored in assimp_bin_path, the process
-    is aborted if it can't be found.
-
-    """
-
-    import os
-    import platform
-    import sys
-
-    def locate_file(f_list):
-        for f in f_list:
-            try:
-                fl = open(f,"rb")
-            except IOError:
-                continue
-            fl.close()
-            return f
-        return None
-
-    global assimp_bin_path
-    if os.name == "nt":
-        search_x86 = [
-            os.path.join("assimp.exe"),
-            os.path.join("..","..","bin","assimpcmd_release-dll_Win32","assimp.exe"),
-            os.path.join("..","..","bin","x86","assimp"),
-            os.path.join("..","..","bin","Release","assimp.exe")
-        ]
-        if platform.machine() == "x86":
-            search = search_x86
-        else: # amd64, hopefully
-            search = [
-                os.path.join("..","..","bin","assimpcmd_release-dll_x64","assimp.exe"),
-                os.path.join("..","..","bin","x64","assimp")
-            ]
-            # x64 platform does not guarantee a x64 build. Also look for x86 as last paths.
-            search += search_x86
-        
-        assimp_bin_path = locate_file(search)
-        if assimp_bin_path is None:
-            print("Can't locate assimp_cmd binary")
-            print("Looked in", search)
-            sys.exit(-5)
-
-        print("Located assimp/assimp_cmd binary from", assimp_bin_path)
-    elif os.name == "posix":
-        #search = [os.path.join("..","..","bin","gcc","assimp"),
-        #    os.path.join("/usr","local","bin",'assimp')]
-        assimp_bin_path = "assimp"
-        print("Taking system-wide assimp binary")
-    else:
-        print("Unsupported operating system")
-        sys.exit(-5)
-
-if __name__ == '__main__':
-    find_assimp_or_die()
-
  # vim: ai ts=4 sts=4 et sw=4

+ 2 - 2
tools/assimp_cmd/CMakeLists.txt

@@ -19,7 +19,7 @@ ADD_EXECUTABLE( assimp_cmd
 	Export.cpp
 )
 
-SET_PROPERTY(TARGET assimp_cmd PROPERTY DEBUG_POSTFIX ${ASSIMP_DEBUG_POSTFIX})
+SET_PROPERTY(TARGET assimp_cmd PROPERTY DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
 
 IF( WIN32 )
 	ADD_CUSTOM_COMMAND(TARGET assimp_cmd
@@ -35,4 +35,4 @@ SET_TARGET_PROPERTIES( assimp_cmd PROPERTIES
 
 INSTALL( TARGETS assimp_cmd
 	DESTINATION "${ASSIMP_BIN_INSTALL_DIR}" COMPONENT assimp-bin
-) 
+)

+ 2 - 2
tools/assimp_cmd/Info.cpp

@@ -112,12 +112,12 @@ unsigned int CountAnimChannels(const aiScene* scene)
 
 // -----------------------------------------------------------------------------------
 unsigned int GetAvgFacePerMesh(const aiScene* scene) {
-	return static_cast<unsigned int>(CountFaces(scene)/scene->mNumMeshes);
+	return (scene->mNumMeshes != 0) ? static_cast<unsigned int>(CountFaces(scene)/scene->mNumMeshes) : 0;
 }
 
 // -----------------------------------------------------------------------------------
 unsigned int GetAvgVertsPerMesh(const aiScene* scene) {
-	return static_cast<unsigned int>(CountVertices(scene)/scene->mNumMeshes);
+	return (scene->mNumMeshes != 0) ? static_cast<unsigned int>(CountVertices(scene)/scene->mNumMeshes) : 0;
 }
 
 // -----------------------------------------------------------------------------------

+ 2 - 2
tools/assimp_view/CMakeLists.txt

@@ -42,7 +42,7 @@ ADD_EXECUTABLE(  assimp_viewer WIN32
 	txi.bmp
 )
 
-SET_PROPERTY(TARGET assimp_viewer PROPERTY DEBUG_POSTFIX ${ASSIMP_DEBUG_POSTFIX})
+SET_PROPERTY(TARGET assimp_viewer PROPERTY DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
 
 
 IF ( MSVC )
@@ -52,7 +52,7 @@ ENDIF ( MSVC )
 
 
 #
-ADD_CUSTOM_COMMAND(TARGET assimp_viewer 
+ADD_CUSTOM_COMMAND(TARGET assimp_viewer
 	PRE_BUILD
 	COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:assimp> $<TARGET_FILE_DIR:assimp_viewer>
 	MAIN_DEPENDENCY assimp)