Ver código fonte

Merge branch 'master' into hide_gpg_signature

Kim Kulling 7 anos atrás
pai
commit
370681fe66

+ 3 - 1
code/BlenderLoader.cpp

@@ -1045,7 +1045,9 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
                 }
             }
         }
-        matTexUvMappings.insert(std::make_pair(m, texuv));
+        if (texuv.size()) {
+            matTexUvMappings.insert(std::make_pair(m, texuv));
+        }
     }
 
     // collect texture coordinates, they're stored in a separate per-face buffer

+ 0 - 1
code/BlenderScene.cpp

@@ -800,7 +800,6 @@ template <> void Structure::Convert<CustomData>(
     ) const
 {
     ReadFieldArray<ErrorPolicy_Warn>(dest.typemap, "typemap", db);
-    ReadField<ErrorPolicy_Igno>(dest.pad_i1, "pad_i1", db);
     ReadField<ErrorPolicy_Warn>(dest.totlayer, "totlayer", db);
     ReadField<ErrorPolicy_Warn>(dest.maxlayer, "maxlayer", db);
     ReadField<ErrorPolicy_Warn>(dest.totsize, "totsize", db);

+ 0 - 1
code/BlenderScene.h

@@ -432,7 +432,6 @@ CustomData 208
 struct CustomData : ElemBase {
     vector<std::shared_ptr<struct CustomDataLayer> > layers;
     int typemap[42];    // CD_NUMTYPES
-    int pad_i1;
     int totlayer;
     int maxlayer;
     int totsize;

+ 4 - 3
code/ColladaHelper.h

@@ -272,12 +272,13 @@ struct Node
     /** Node instances at this node */
     std::vector<NodeInstance> mNodeInstances;
 
-    /** Rootnodes: Name of primary camera, if any */
+    /** Root-nodes: Name of primary camera, if any */
     std::string mPrimaryCamera;
 
     //! Constructor. Begin with a zero parent
-    Node() {
-        mParent = NULL;
+    Node()
+    : mParent( nullptr ){
+        // empty
     }
 
     //! Destructor: delete all children subsequently

+ 23 - 25
code/ColladaLoader.cpp

@@ -181,26 +181,27 @@ void ColladaLoader::InternReadFile( const std::string& pFile, aiScene* pScene, I
     // ... then fill the materials with the now adjusted settings
     FillMaterials(parser, pScene);
 
-        // Apply unitsize scale calculation
-        pScene->mRootNode->mTransformation *= aiMatrix4x4(parser.mUnitSize, 0,  0,  0,
-                                                          0,  parser.mUnitSize,  0,  0,
-                                                          0,  0,  parser.mUnitSize,  0,
-                                                          0,  0,  0,  1);
-        if( !ignoreUpDirection ) {
-        // Convert to Y_UP, if different orientation
-        if( parser.mUpDirection == ColladaParser::UP_X)
-            pScene->mRootNode->mTransformation *= aiMatrix4x4(
-                 0, -1,  0,  0,
-                 1,  0,  0,  0,
-                 0,  0,  1,  0,
-                 0,  0,  0,  1);
-        else if( parser.mUpDirection == ColladaParser::UP_Z)
-            pScene->mRootNode->mTransformation *= aiMatrix4x4(
-                 1,  0,  0,  0,
-                 0,  0,  1,  0,
-                 0, -1,  0,  0,
-                 0,  0,  0,  1);
-        }
+    // Apply unitsize scale calculation
+    pScene->mRootNode->mTransformation *= aiMatrix4x4(parser.mUnitSize, 0,  0,  0,
+                                                        0,  parser.mUnitSize,  0,  0,
+                                                        0,  0,  parser.mUnitSize,  0,
+                                                        0,  0,  0,  1);
+    if( !ignoreUpDirection ) {
+    // Convert to Y_UP, if different orientation
+    if( parser.mUpDirection == ColladaParser::UP_X)
+        pScene->mRootNode->mTransformation *= aiMatrix4x4(
+                0, -1,  0,  0,
+                1,  0,  0,  0,
+                0,  0,  1,  0,
+                0,  0,  0,  1);
+    else if( parser.mUpDirection == ColladaParser::UP_Z)
+        pScene->mRootNode->mTransformation *= aiMatrix4x4(
+                1,  0,  0,  0,
+                0,  0,  1,  0,
+                0, -1,  0,  0,
+                0,  0,  0,  1);
+    }
+
     // store all meshes
     StoreSceneMeshes( pScene);
 
@@ -740,10 +741,6 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada::
     // create bones if given
     if( pSrcController && pSrcController->mType == Collada::Skin)
     {
-        // refuse if the vertex count does not match
-//      if( pSrcController->mWeightCounts.size() != dstMesh->mNumVertices)
-//          throw DeadlyImportError( "Joint Controller vertex count does not match mesh vertex count");
-
         // resolve references - joint names
         const Collada::Accessor& jointNamesAcc = pParser.ResolveLibraryReference( pParser.mAccessorLibrary, pSrcController->mJointNameSource);
         const Collada::Data& jointNames = pParser.ResolveLibraryReference( pParser.mDataLibrary, jointNamesAcc.mSource);
@@ -971,7 +968,8 @@ void ColladaLoader::StoreAnimations( aiScene* pScene, const ColladaParser& pPars
             for( size_t b = a+1; b < mAnims.size(); ++b)
             {
                 aiAnimation* other = mAnims[b];
-                if( other->mNumChannels == 1 && other->mDuration == templateAnim->mDuration && other->mTicksPerSecond == templateAnim->mTicksPerSecond )
+                if( other->mNumChannels == 1 && other->mDuration == templateAnim->mDuration && 
+                        other->mTicksPerSecond == templateAnim->mTicksPerSecond )
                     collectedAnimIndices.push_back( b);
             }
 

+ 14 - 14
code/ColladaParser.cpp

@@ -68,7 +68,7 @@ using namespace Assimp::Formatter;
 // Constructor to be privately used by Importer
 ColladaParser::ColladaParser( IOSystem* pIOHandler, const std::string& pFile)
     : mFileName( pFile )
-    , mReader( NULL )
+    , mReader( nullptr )
     , mDataLibrary()
     , mAccessorLibrary()
     , mMeshLibrary()
@@ -79,20 +79,20 @@ ColladaParser::ColladaParser( IOSystem* pIOHandler, const std::string& pFile)
     , mLightLibrary()
     , mCameraLibrary()
     , mControllerLibrary()
-    , mRootNode( NULL )
+    , mRootNode( nullptr )
     , mAnims()
     , mUnitSize( 1.0f )
     , mUpDirection( UP_Y )
     , mFormat(FV_1_5_n )    // We assume the newest file format by default
 {
     // validate io-handler instance
-    if ( NULL == pIOHandler ) {
+    if (nullptr == pIOHandler ) {
         throw DeadlyImportError("IOSystem is NULL." );
     }
 
     // open the file
     std::unique_ptr<IOStream> file( pIOHandler->Open(pFile ) );
-    if (file.get() == NULL) {
+    if (file.get() == nullptr) {
         throw DeadlyImportError( "Failed to open file " + pFile + "." );
     }
 
@@ -363,17 +363,17 @@ void ColladaParser::ReadAnimationClipLibrary()
 
 void ColladaParser::PostProcessControllers()
 {
-  for (ControllerLibrary::iterator it = mControllerLibrary.begin(); it != mControllerLibrary.end(); ++it)
-  {
-    std::string meshId = it->second.mMeshId;
-    ControllerLibrary::iterator findItr = mControllerLibrary.find(meshId);
-    while(findItr != mControllerLibrary.end()) {
-      meshId = findItr->second.mMeshId;
-      findItr = mControllerLibrary.find(meshId);
-    }
+    std::string meshId;
+    for (ControllerLibrary::iterator it = mControllerLibrary.begin(); it != mControllerLibrary.end(); ++it) {
+        meshId = it->second.mMeshId;
+        ControllerLibrary::iterator findItr = mControllerLibrary.find(meshId);
+        while(findItr != mControllerLibrary.end()) {
+            meshId = findItr->second.mMeshId;
+            findItr = mControllerLibrary.find(meshId);
+        }
     
-    it->second.mMeshId = meshId;
-  }
+        it->second.mMeshId = meshId;
+    }
 }
 
 // ------------------------------------------------------------------------------------------------

+ 4 - 4
code/Exporter.cpp

@@ -150,14 +150,14 @@ Exporter::ExportFormatEntry gExporters[] =
 #endif
 
 #ifndef ASSIMP_BUILD_NO_GLTF_EXPORTER
-    Exporter::ExportFormatEntry( "gltf", "GL Transmission Format", "gltf", &ExportSceneGLTF,
-        aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
-    Exporter::ExportFormatEntry( "glb", "GL Transmission Format (binary)", "glb", &ExportSceneGLB,
-        aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
     Exporter::ExportFormatEntry( "gltf2", "GL Transmission Format v. 2", "gltf", &ExportSceneGLTF2,
         aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
     Exporter::ExportFormatEntry( "glb2", "GL Transmission Format v. 2 (binary)", "glb", &ExportSceneGLB2,
         aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
+    Exporter::ExportFormatEntry( "gltf", "GL Transmission Format", "gltf", &ExportSceneGLTF,
+        aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
+    Exporter::ExportFormatEntry( "glb", "GL Transmission Format (binary)", "glb", &ExportSceneGLB,
+        aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
 #endif
 
 #ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER

+ 200 - 222
code/PlyLoader.cpp

@@ -55,7 +55,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <assimp/scene.h>
 #include <assimp/importerdesc.h>
 
-using namespace Assimp;
+using namespace ::Assimp;
 
 static const aiImporterDesc desc = {
     "Stanford Polygon Library (PLY) Importer",
@@ -73,22 +73,20 @@ static const aiImporterDesc desc = {
 
 // ------------------------------------------------------------------------------------------------
 // Internal stuff
-namespace
-{
-  // ------------------------------------------------------------------------------------------------
-  // Checks that property index is within range
-  template <class T>
-  const T &GetProperty(const std::vector<T> &props, int idx)
-  {
-    if (static_cast<size_t>(idx) >= props.size()) {
-      throw DeadlyImportError("Invalid .ply file: Property index is out of range.");
-    }
+namespace {
+    // ------------------------------------------------------------------------------------------------
+    // Checks that property index is within range
+    template <class T>
+    inline
+    const T &GetProperty(const std::vector<T> &props, int idx) {
+        if (static_cast<size_t>(idx) >= props.size()) {
+            throw DeadlyImportError("Invalid .ply file: Property index is out of range.");
+        }
 
-    return props[idx];
-  }
+        return props[idx];
+    }
 }
 
-
 // ------------------------------------------------------------------------------------------------
 // Constructor to be privately used by Importer
 PLYImporter::PLYImporter()
@@ -129,7 +127,7 @@ const aiImporterDesc* PLYImporter::GetInfo() const {
 
 // ------------------------------------------------------------------------------------------------
 static bool isBigEndian(const char* szMe) {
-    ai_assert(NULL != szMe);
+    ai_assert(nullptr != szMe);
 
     // binary_little_endian
     // binary_big_endian
@@ -150,7 +148,7 @@ static bool isBigEndian(const char* szMe) {
 // ------------------------------------------------------------------------------------------------
 // Imports the given file into the given scene structure.
 void PLYImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) {
-    static const std::string mode = "rb";
+    const std::string mode = "rb";
     std::unique_ptr<IOStream> fileStream(pIOHandler->Open(pFile, mode));
     if (!fileStream.get()) {
         throw DeadlyImportError("Failed to open file " + pFile + ".");
@@ -184,7 +182,7 @@ void PLYImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSy
     char* szMe = (char*)&this->mBuffer[0];
     SkipSpacesAndLineEnd(szMe, (const char**)&szMe);
 
-    // determine the format of the file data and construct the aimesh
+    // determine the format of the file data and construct the aiMesh
     PLY::DOM sPlyDom;   
     this->pcDOM = &sPlyDom;
 
@@ -192,7 +190,7 @@ void PLYImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSy
         if (TokenMatch(szMe, "ascii", 5)) {
             SkipLine(szMe, (const char**)&szMe);
             if (!PLY::DOM::ParseInstance(streamedBuffer, &sPlyDom, this)) {
-                if (mGeneratedMesh != NULL) {
+                if (mGeneratedMesh != nullptr) {
                     delete(mGeneratedMesh);
                     mGeneratedMesh = nullptr;
                 }
@@ -206,7 +204,7 @@ void PLYImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSy
 
             // skip the line, parse the rest of the header and build the DOM
             if (!PLY::DOM::ParseInstanceBinary(streamedBuffer, &sPlyDom, this, bIsBE)) {
-                if (mGeneratedMesh != NULL) {
+                if (mGeneratedMesh != nullptr) {
                     delete(mGeneratedMesh);
                     mGeneratedMesh = nullptr;
                 }
@@ -215,7 +213,7 @@ void PLYImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSy
                 throw DeadlyImportError("Invalid .ply file: Unable to build DOM (#2)");
             }
         } else {
-            if (mGeneratedMesh != NULL) {
+            if (mGeneratedMesh != nullptr) {
                 delete(mGeneratedMesh);
                 mGeneratedMesh = nullptr;
             }
@@ -225,7 +223,7 @@ void PLYImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSy
         }
     } else {
         AI_DEBUG_INVALIDATE_PTR(this->mBuffer);
-        if (mGeneratedMesh != NULL) {
+        if (mGeneratedMesh != nullptr) {
             delete(mGeneratedMesh);
             mGeneratedMesh = nullptr;
         }
@@ -237,13 +235,13 @@ void PLYImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSy
     //free the file buffer
     streamedBuffer.close();
 
-    if (mGeneratedMesh == NULL) {
+    if (mGeneratedMesh == nullptr) {
         throw DeadlyImportError("Invalid .ply file: Unable to extract mesh data ");
     }
 
     // if no face list is existing we assume that the vertex
     // list is containing a list of points
-    bool pointsOnly = mGeneratedMesh->mFaces == NULL ? true : false;
+    bool pointsOnly = mGeneratedMesh->mFaces == nullptr ? true : false;
     if (pointsOnly) {
       mGeneratedMesh->mPrimitiveTypes = aiPrimitiveType::aiPrimitiveType_POINT;
     }
@@ -277,8 +275,8 @@ void PLYImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSy
 }
 
 void PLYImporter::LoadVertex(const PLY::Element* pcElement, const PLY::ElementInstance* instElement, unsigned int pos) {
-    ai_assert(NULL != pcElement);
-    ai_assert(NULL != instElement);
+    ai_assert(nullptr != pcElement);
+    ai_assert(nullptr != instElement);
 
     ai_uint aiPositions[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
     PLY::EDataType aiTypes[3] = { EDT_Char, EDT_Char, EDT_Char };
@@ -416,7 +414,7 @@ void PLYImporter::LoadVertex(const PLY::Element* pcElement, const PLY::ElementIn
             haveColor = true;
         }
 
-        // assume 1.0 for the alpha channel ifit is not set
+        // assume 1.0 for the alpha channel if it is not set
         if (0xFFFFFFFF == aiColors[3]) {
             cOut.a = 1.0;
         } else {
@@ -481,225 +479,205 @@ void PLYImporter::LoadVertex(const PLY::Element* pcElement, const PLY::ElementIn
 // ------------------------------------------------------------------------------------------------
 // Convert a color component to [0...1]
 ai_real PLYImporter::NormalizeColorValue(PLY::PropertyInstance::ValueUnion val, PLY::EDataType eType) {
-  switch (eType)
-  {
-  case EDT_Float:
-    return val.fFloat;
-  case EDT_Double:
-    return (ai_real)val.fDouble;
-
-  case EDT_UChar:
-    return (ai_real)val.iUInt / (ai_real)0xFF;
-  case EDT_Char:
-    return (ai_real)(val.iInt + (0xFF / 2)) / (ai_real)0xFF;
-  case EDT_UShort:
-    return (ai_real)val.iUInt / (ai_real)0xFFFF;
-  case EDT_Short:
-    return (ai_real)(val.iInt + (0xFFFF / 2)) / (ai_real)0xFFFF;
-  case EDT_UInt:
-    return (ai_real)val.iUInt / (ai_real)0xFFFF;
-  case EDT_Int:
-    return ((ai_real)val.iInt / (ai_real)0xFF) + 0.5f;
-  default:;
-  };
-  return 0.0f;
+    switch (eType) {
+        case EDT_Float:
+            return val.fFloat;
+        case EDT_Double:
+            return (ai_real)val.fDouble;
+        case EDT_UChar:
+            return (ai_real)val.iUInt / (ai_real)0xFF;
+        case EDT_Char:
+            return (ai_real)(val.iInt + (0xFF / 2)) / (ai_real)0xFF;
+        case EDT_UShort:
+            return (ai_real)val.iUInt / (ai_real)0xFFFF;
+        case EDT_Short:
+            return (ai_real)(val.iInt + (0xFFFF / 2)) / (ai_real)0xFFFF;
+        case EDT_UInt:
+            return (ai_real)val.iUInt / (ai_real)0xFFFF;
+        case EDT_Int:
+            return ((ai_real)val.iInt / (ai_real)0xFF) + 0.5f;
+        default:
+            break;
+    }
+
+    return 0.0f;
 }
 
 // ------------------------------------------------------------------------------------------------
 // Try to extract proper faces from the PLY DOM
-void PLYImporter::LoadFace(const PLY::Element* pcElement, const PLY::ElementInstance* instElement, unsigned int pos)
-{
-  ai_assert(NULL != pcElement);
-  ai_assert(NULL != instElement);
-
-  if (mGeneratedMesh == NULL)
-    throw DeadlyImportError("Invalid .ply file: Vertices should be declared before faces");
-
-  bool bOne = false;
-
-  // index of the vertex index list
-  unsigned int iProperty = 0xFFFFFFFF;
-  PLY::EDataType eType = EDT_Char;
-  bool bIsTriStrip = false;
+void PLYImporter::LoadFace(const PLY::Element* pcElement, const PLY::ElementInstance* instElement,
+        unsigned int pos) {
+    ai_assert(nullptr != pcElement);
+    ai_assert(nullptr != instElement);
 
-  // index of the material index property
-  //unsigned int iMaterialIndex = 0xFFFFFFFF;
-  //PLY::EDataType eType2 = EDT_Char;
-
-  // texture coordinates
-  unsigned int iTextureCoord = 0xFFFFFFFF;
-  PLY::EDataType eType3 = EDT_Char;
+    if (mGeneratedMesh == nullptr) {
+        throw DeadlyImportError("Invalid .ply file: Vertices should be declared before faces");
+    }
 
-  // face = unique number of vertex indices
-  if (PLY::EEST_Face == pcElement->eSemantic)
-  {
-    unsigned int _a = 0;
-    for (std::vector<PLY::Property>::const_iterator a = pcElement->alProperties.begin();
-      a != pcElement->alProperties.end(); ++a, ++_a)
-    {
-      if (PLY::EST_VertexIndex == (*a).Semantic)
-      {
-        // must be a dynamic list!
-        if (!(*a).bIsList)
-          continue;
+    bool bOne = false;
+
+    // index of the vertex index list
+    unsigned int iProperty = 0xFFFFFFFF;
+    PLY::EDataType eType = EDT_Char;
+    bool bIsTriStrip = false;
+
+    // index of the material index property
+    //unsigned int iMaterialIndex = 0xFFFFFFFF;
+    //PLY::EDataType eType2 = EDT_Char;
+
+    // texture coordinates
+    unsigned int iTextureCoord = 0xFFFFFFFF;
+    PLY::EDataType eType3 = EDT_Char;
+
+    // face = unique number of vertex indices
+    if (PLY::EEST_Face == pcElement->eSemantic) {
+        unsigned int _a = 0;
+        for (std::vector<PLY::Property>::const_iterator a = pcElement->alProperties.begin();
+                a != pcElement->alProperties.end(); ++a, ++_a) {
+            if (PLY::EST_VertexIndex == (*a).Semantic) {
+                // must be a dynamic list!
+                if (!(*a).bIsList) {
+                    continue;
+                }
 
-        iProperty = _a;
-        bOne = true;
-        eType = (*a).eType;
-      }
-      /*else if (PLY::EST_MaterialIndex == (*a).Semantic)
-      {
-      if ((*a).bIsList)
-      continue;
-      iMaterialIndex = _a;
-      bOne = true;
-      eType2 = (*a).eType;
-      }*/
-      else if (PLY::EST_TextureCoordinates == (*a).Semantic)
-      {
-        // must be a dynamic list!
-        if (!(*a).bIsList)
-          continue;
-        iTextureCoord = _a;
-        bOne = true;
-        eType3 = (*a).eType;
-      }
-    }
-  }
-  // triangle strip
-  // TODO: triangle strip and material index support???
-  else if (PLY::EEST_TriStrip == pcElement->eSemantic)
-  {
-    unsigned int _a = 0;
-    for (std::vector<PLY::Property>::const_iterator a = pcElement->alProperties.begin();
-      a != pcElement->alProperties.end(); ++a, ++_a)
-    {
-      // must be a dynamic list!
-      if (!(*a).bIsList)
-        continue;
-      iProperty = _a;
-      bOne = true;
-      bIsTriStrip = true;
-      eType = (*a).eType;
-      break;
+                iProperty = _a;
+                bOne = true;
+                eType = (*a).eType;
+            } else if (PLY::EST_TextureCoordinates == (*a).Semantic) {
+                // must be a dynamic list!
+                if (!(*a).bIsList) {
+                    continue;
+                }
+                iTextureCoord = _a;
+                bOne = true;
+                eType3 = (*a).eType;
+            }
+        }
     }
-  }
-
-  // check whether we have at least one per-face information set
-  if (bOne)
-  {
-    if (mGeneratedMesh->mFaces == NULL)
-    {
-      mGeneratedMesh->mNumFaces = pcElement->NumOccur;
-      mGeneratedMesh->mFaces = new aiFace[mGeneratedMesh->mNumFaces];
+    // triangle strip
+    // TODO: triangle strip and material index support???
+    else if (PLY::EEST_TriStrip == pcElement->eSemantic) {
+        unsigned int _a = 0;
+        for (std::vector<PLY::Property>::const_iterator a = pcElement->alProperties.begin();
+                a != pcElement->alProperties.end(); ++a, ++_a) {
+            // must be a dynamic list!
+            if (!(*a).bIsList) {
+                continue;
+            }
+            iProperty = _a;
+            bOne = true;
+            bIsTriStrip = true;
+            eType = (*a).eType;
+            break;
+        }
     }
 
-    if (!bIsTriStrip)
-    {
-      // parse the list of vertex indices
-      if (0xFFFFFFFF != iProperty)
-      {
-        const unsigned int iNum = (unsigned int)GetProperty(instElement->alProperties, iProperty).avList.size();
-        mGeneratedMesh->mFaces[pos].mNumIndices = iNum;
-        mGeneratedMesh->mFaces[pos].mIndices = new unsigned int[iNum];
-
-        std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator p =
-          GetProperty(instElement->alProperties, iProperty).avList.begin();
-
-        for (unsigned int a = 0; a < iNum; ++a, ++p)
-        {
-          mGeneratedMesh->mFaces[pos].mIndices[a] = PLY::PropertyInstance::ConvertTo<unsigned int>(*p, eType);
+    // check whether we have at least one per-face information set
+    if (bOne) {
+        if (mGeneratedMesh->mFaces == nullptr) {
+            mGeneratedMesh->mNumFaces = pcElement->NumOccur;
+            mGeneratedMesh->mFaces = new aiFace[mGeneratedMesh->mNumFaces];
         }
-      }
 
-      // parse the material index
-      // cannot be handled without processing the whole file first
-      /*if (0xFFFFFFFF != iMaterialIndex)
-      {
-      mGeneratedMesh->mFaces[pos]. = PLY::PropertyInstance::ConvertTo<unsigned int>(
-      GetProperty(instElement->alProperties, iMaterialIndex).avList.front(), eType2);
-      }*/
+        if (!bIsTriStrip) {
+            // parse the list of vertex indices
+            if (0xFFFFFFFF != iProperty) {
+                const unsigned int iNum = (unsigned int)GetProperty(instElement->alProperties, iProperty).avList.size();
+                mGeneratedMesh->mFaces[pos].mNumIndices = iNum;
+                mGeneratedMesh->mFaces[pos].mIndices = new unsigned int[iNum];
 
-      if (0xFFFFFFFF != iTextureCoord)
-      {
-        const unsigned int iNum = (unsigned int)GetProperty(instElement->alProperties, iTextureCoord).avList.size();
+                std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator p =
+                GetProperty(instElement->alProperties, iProperty).avList.begin();
 
-        //should be 6 coords
-        std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator p =
-          GetProperty(instElement->alProperties, iTextureCoord).avList.begin();
+                for (unsigned int a = 0; a < iNum; ++a, ++p) {
+                    mGeneratedMesh->mFaces[pos].mIndices[a] = PLY::PropertyInstance::ConvertTo<unsigned int>(*p, eType);
+                }
+            }
 
-        if ((iNum / 3) == 2) // X Y coord
+        // parse the material index
+        // cannot be handled without processing the whole file first
+        /*if (0xFFFFFFFF != iMaterialIndex)
         {
-          for (unsigned int a = 0; a < iNum; ++a, ++p)
-          {
-            unsigned int vindex = mGeneratedMesh->mFaces[pos].mIndices[a / 2];
-            if (vindex < mGeneratedMesh->mNumVertices)
-            {
-              if (mGeneratedMesh->mTextureCoords[0] == NULL)
-              {
-                mGeneratedMesh->mNumUVComponents[0] = 2;
-                mGeneratedMesh->mTextureCoords[0] = new aiVector3D[mGeneratedMesh->mNumVertices];
-              }
-
-              if (a % 2 == 0)
-                mGeneratedMesh->mTextureCoords[0][vindex].x = PLY::PropertyInstance::ConvertTo<ai_real>(*p, eType3);
-              else
-                mGeneratedMesh->mTextureCoords[0][vindex].y = PLY::PropertyInstance::ConvertTo<ai_real>(*p, eType3);
-
-              mGeneratedMesh->mTextureCoords[0][vindex].z = 0;
+            mGeneratedMesh->mFaces[pos]. = PLY::PropertyInstance::ConvertTo<unsigned int>(
+            GetProperty(instElement->alProperties, iMaterialIndex).avList.front(), eType2);
+        }*/
+
+            if (0xFFFFFFFF != iTextureCoord) {
+                const unsigned int iNum = (unsigned int)GetProperty(instElement->alProperties, iTextureCoord).avList.size();
+
+                //should be 6 coords
+                std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator p =
+                GetProperty(instElement->alProperties, iTextureCoord).avList.begin();
+
+                if ((iNum / 3) == 2) // X Y coord
+                {
+                    for (unsigned int a = 0; a < iNum; ++a, ++p) {
+                        unsigned int vindex = mGeneratedMesh->mFaces[pos].mIndices[a / 2];
+                        if (vindex < mGeneratedMesh->mNumVertices) {
+                            if (mGeneratedMesh->mTextureCoords[0] == nullptr ) {
+                                mGeneratedMesh->mNumUVComponents[0] = 2;
+                                mGeneratedMesh->mTextureCoords[0] = new aiVector3D[mGeneratedMesh->mNumVertices];
+                            }
+
+                            if (a % 2 == 0) {
+                                mGeneratedMesh->mTextureCoords[0][vindex].x = PLY::PropertyInstance::ConvertTo<ai_real>(*p, eType3);
+                            } else {
+                                mGeneratedMesh->mTextureCoords[0][vindex].y = PLY::PropertyInstance::ConvertTo<ai_real>(*p, eType3);
+                            }
+
+                            mGeneratedMesh->mTextureCoords[0][vindex].z = 0;
+                        }
+                    }
+                }
             }
-          }
-        }
-      }
-    }
-    else // triangle strips
-    {
-      // normally we have only one triangle strip instance where
-      // a value of -1 indicates a restart of the strip
-      bool flip = false;
-      const std::vector<PLY::PropertyInstance::ValueUnion>& quak = GetProperty(instElement->alProperties, iProperty).avList;
-      //pvOut->reserve(pvOut->size() + quak.size() + (quak.size()>>2u)); //Limits memory consumption
-
-      int aiTable[2] = { -1, -1 };
-      for (std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator a = quak.begin(); a != quak.end(); ++a)  {
-        const int p = PLY::PropertyInstance::ConvertTo<int>(*a, eType);
+        } else { // triangle strips
+            // normally we have only one triangle strip instance where
+            // a value of -1 indicates a restart of the strip
+            bool flip = false;
+            const std::vector<PLY::PropertyInstance::ValueUnion>& quak = GetProperty(instElement->alProperties, iProperty).avList;
+            //pvOut->reserve(pvOut->size() + quak.size() + (quak.size()>>2u)); //Limits memory consumption
+
+            int aiTable[2] = { -1, -1 };
+            for (std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator a = quak.begin(); a != quak.end(); ++a)  {
+                const int p = PLY::PropertyInstance::ConvertTo<int>(*a, eType);
+
+                if (-1 == p) {
+                    // restart the strip ...
+                    aiTable[0] = aiTable[1] = -1;
+                    flip = false;
+                    continue;
+                }
+                if (-1 == aiTable[0]) {
+                    aiTable[0] = p;
+                    continue;
+                }
+                if (-1 == aiTable[1]) {
+                    aiTable[1] = p;
+                    continue;
+                }
 
-        if (-1 == p)    {
-          // restart the strip ...
-          aiTable[0] = aiTable[1] = -1;
-          flip = false;
-          continue;
-        }
-        if (-1 == aiTable[0]) {
-          aiTable[0] = p;
-          continue;
-        }
-        if (-1 == aiTable[1]) {
-          aiTable[1] = p;
-          continue;
-        }
+                if (mGeneratedMesh->mFaces == nullptr) {
+                    mGeneratedMesh->mNumFaces = pcElement->NumOccur;
+                    mGeneratedMesh->mFaces = new aiFace[mGeneratedMesh->mNumFaces];
+                }
 
-        if (mGeneratedMesh->mFaces == NULL)
-        {
-          mGeneratedMesh->mNumFaces = pcElement->NumOccur;
-          mGeneratedMesh->mFaces = new aiFace[mGeneratedMesh->mNumFaces];
-        }
+                mGeneratedMesh->mFaces[pos].mNumIndices = 3;
+                mGeneratedMesh->mFaces[pos].mIndices = new unsigned int[3];
+                mGeneratedMesh->mFaces[pos].mIndices[0] = aiTable[0];
+                mGeneratedMesh->mFaces[pos].mIndices[1] = aiTable[1];
+                mGeneratedMesh->mFaces[pos].mIndices[2] = p;
 
-        mGeneratedMesh->mFaces[pos].mNumIndices = 3;
-        mGeneratedMesh->mFaces[pos].mIndices = new unsigned int[3];
-        mGeneratedMesh->mFaces[pos].mIndices[0] = aiTable[0];
-        mGeneratedMesh->mFaces[pos].mIndices[1] = aiTable[1];
-        mGeneratedMesh->mFaces[pos].mIndices[2] = p;
+                // every second pass swap the indices.
+                flip = !flip;
+                if ( flip ) {
+                    std::swap(mGeneratedMesh->mFaces[pos].mIndices[0], mGeneratedMesh->mFaces[pos].mIndices[1]);
+                }
 
-        if ((flip = !flip)) {
-          std::swap(mGeneratedMesh->mFaces[pos].mIndices[0], mGeneratedMesh->mFaces[pos].mIndices[1]);
+                aiTable[0] = aiTable[1];
+                aiTable[1] = p;
+            }
         }
-
-        aiTable[0] = aiTable[1];
-        aiTable[1] = p;
-      }
     }
-  }
 }
 
 // ------------------------------------------------------------------------------------------------

+ 11 - 5
port/PyAssimp/pyassimp/helper.py

@@ -27,7 +27,7 @@ additional_dirs, ext_whitelist = [],[]
 if os.name=='posix':
     additional_dirs.append('./')
     additional_dirs.append('/usr/lib/')
-    additional_dirs.append('/usr/lib/x86_64-linux-gnu')
+    additional_dirs.append('/usr/lib/x86_64-linux-gnu/')
     additional_dirs.append('/usr/local/lib/')
 
     if 'LD_LIBRARY_PATH' in os.environ:
@@ -222,11 +222,17 @@ def search_library():
             for filename in os.listdir(curfolder):
                 # our minimum requirement for candidates is that
                 # they should contain 'assimp' somewhere in
-                # their name
-                if filename.lower().find('assimp')==-1 or\
-                    os.path.splitext(filename)[-1].lower() not in ext_whitelist:
+                # their name                                  
+                if filename.lower().find('assimp')==-1 : 
                     continue
-
+                is_out=1
+                for et in ext_whitelist:
+                  if et in filename.lower():
+                    is_out=0
+                    break
+                if is_out:
+                  continue
+                
                 library_path = os.path.join(curfolder, filename)
                 logger.debug('Try ' + library_path)
                 try:

+ 1 - 0
test/CMakeLists.txt

@@ -106,6 +106,7 @@ SET( IMPORTERS
   unit/utBlendImportAreaLight.cpp
   unit/utBlenderImportExport.cpp
   unit/utBlendImportMaterials.cpp
+  unit/utBlenderWork.cpp
   unit/utBVHImportExport.cpp
   unit/utColladaExportCamera.cpp
   unit/utColladaExportLight.cpp

BIN
test/models/BLEND/test_279.blend


BIN
test/models/IRR/instancing.irr


+ 83 - 0
test/unit/utBlenderWork.cpp

@@ -0,0 +1,83 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2018, 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/cexport.h>
+#include <assimp/Importer.hpp>
+#include <assimp/scene.h>
+#include <assimp/postprocess.h>
+
+using namespace ::Assimp;
+
+class BlenderWorkTest : public ::testing::Test {
+public:
+    virtual void SetUp()
+    {
+        im = new Assimp::Importer();
+    }
+
+    virtual void TearDown()
+    {
+        delete im;
+    }
+
+protected:
+
+    Assimp::Importer* im;
+};
+
+TEST_F(BlenderWorkTest,work_279) {
+    const aiScene* pTest = im->ReadFile(ASSIMP_TEST_MODELS_DIR "/BLEND/test_279.blend", aiProcess_ValidateDataStructure);
+    ASSERT_TRUE(pTest != NULL);
+
+    // material has 2 diffuse textures
+    ASSERT_TRUE(pTest->HasMaterials());
+    ASSERT_TRUE(pTest->HasMeshes());
+    ASSERT_TRUE(pTest->mMeshes[0]->mNumVertices > 0);
+    ASSERT_EQ(44, pTest->mMeshes[0]->mNumFaces);
+    EXPECT_EQ(1, pTest->mNumMaterials);
+}
+
+
+
+
+

+ 6 - 5
tools/assimp_qt_viewer/glview.cpp

@@ -1261,9 +1261,10 @@ void CGLView::Camera_Set(const size_t pCameraNumber)
 	gluLookAt(hcam.Position.x, hcam.Position.y, hcam.Position.z, hcam.Target.x, hcam.Target.y, hcam.Target.z, up.x, up.y, up.z);
 }
 
-void CGLView::Camera_RotateScene(const GLfloat pAngle_X, const GLfloat pAngle_Y, const GLfloat pAngle_Z, const aiMatrix4x4* pMatrix_Rotation_Initial)
-{
-auto deg2rad = [](const GLfloat pDegree) -> GLfloat { return pDegree * M_PI / 180.0; };
+void CGLView::Camera_RotateScene(const GLfloat pAngle_X, const GLfloat pAngle_Y, const GLfloat pAngle_Z, const aiMatrix4x4* pMatrix_Rotation_Initial) {
+    auto deg2rad = [](const GLfloat pDegree) -> GLfloat { 
+        return pDegree * AI_MATH_PI / 180.0;
+    };
 
 	aiMatrix4x4 mat_rot;
 
@@ -1276,7 +1277,7 @@ auto deg2rad = [](const GLfloat pDegree) -> GLfloat { return pDegree * M_PI / 18
 
 void CGLView::Camera_Rotate(const GLfloat pAngle_X, const GLfloat pAngle_Y, const GLfloat pAngle_Z, const aiMatrix4x4* pMatrix_Rotation_Initial)
 {
-auto deg2rad = [](const GLfloat pDegree) -> GLfloat { return pDegree * M_PI / 180.0; };
+    auto deg2rad = [](const GLfloat pDegree) -> GLfloat { return pDegree * AI_MATH_PI / 180.0; };
 
 	aiMatrix4x4 mat_rot;
 
@@ -1289,7 +1290,7 @@ auto deg2rad = [](const GLfloat pDegree) -> GLfloat { return pDegree * M_PI / 18
 
 void CGLView::Camera_Translate(const GLfloat pTranslate_X, const GLfloat pTranslate_Y, const GLfloat pTranslate_Z)
 {
-aiVector3D vect_tr(pTranslate_X, pTranslate_Y, pTranslate_Z);
+    aiVector3D vect_tr(pTranslate_X, pTranslate_Y, pTranslate_Z);
 
 	vect_tr *= mHelper_Camera.Rotation_AroundCamera;
 	mHelper_Camera.Translation_ToScene += vect_tr;

+ 19 - 25
tools/assimp_qt_viewer/mainwindow.cpp

@@ -132,9 +132,8 @@ void MainWindow::LogError(const QString& pMessage)
 
 void MainWindow::mousePressEvent(QMouseEvent* pEvent)
 {
-const QPoint ms_pt = pEvent->pos();
-
-__unused aiVector3D temp_v3;
+    const QPoint ms_pt = pEvent->pos();
+    aiVector3D temp_v3;
 
 	// Check if GLView is pointed.
 	if(childAt(ms_pt) == mGLView)
@@ -305,30 +304,32 @@ void MainWindow::SceneObject_LightSource(const QString& pName)
 	ui->lstLight->selectAll();
 }
 
-void MainWindow::on_butOpenFile_clicked()
-{
-aiString filter_temp;
-QString filename, filter;
+void MainWindow::on_butOpenFile_clicked() {
+    aiString filter_temp;
+    mImporter.GetExtensionList( filter_temp );
 
-	mImporter.GetExtensionList(filter_temp);
-	filter = filter_temp.C_Str();
+    QString filename, filter;
+    filter = filter_temp.C_Str();
 	filter.replace(';', ' ');
 	filter.append(" ;; All (*.*)");
 	filename = QFileDialog::getOpenFileName(this, "Choose the file", "", filter);
 
-	if(!filename.isEmpty()) ImportFile(filename);
+    if (!filename.isEmpty()) {
+        ImportFile( filename );
+    }
 }
 
 void MainWindow::on_butExport_clicked()
 {
-using namespace Assimp;
+    using namespace Assimp;
 
-QString filename, filter, format_id;
-Exporter exporter;
-QTime time_begin;
-aiReturn rv;
-QStringList exportersList;
-QMap<QString, const aiExportFormatDesc*> exportersMap;
+#ifndef ASSIMP_BUILD_NO_EXPORT
+    QString filename, filter, format_id;
+    Exporter exporter;
+    QTime time_begin;
+    aiReturn rv;
+    QStringList exportersList;
+    QMap<QString, const aiExportFormatDesc*> exportersMap;
 
 
 	if(mScene == nullptr)
@@ -373,6 +374,7 @@ QMap<QString, const aiExportFormatDesc*> exportersMap;
 		LogError(errorMessage);
 		QMessageBox::critical(this, "Export error", errorMessage);
 	}
+#endif
 }
 
 void MainWindow::on_cbxLighting_clicked(bool pChecked)
@@ -382,11 +384,7 @@ void MainWindow::on_cbxLighting_clicked(bool pChecked)
 	else
 		mGLView->Lighting_Disable();
 
-#if ASSIMP_QT4_VIEWER
-	mGLView->updateGL();
-#else
 	mGLView->update();
-#endif // ASSIMP_QT4_VIEWER
 }
 
 void MainWindow::on_lstLight_itemSelectionChanged()
@@ -438,9 +436,5 @@ void MainWindow::on_cbxDrawAxes_clicked(bool checked)
 void MainWindow::on_cbxTextures_clicked(bool checked)
 {
 	mGLView->Enable_Textures(checked);
-#if ASSIMP_QT4_VIEWER
-	mGLView->updateGL();
-#else
 	mGLView->update();
-#endif // ASSIMP_QT4_VIEWER
 }

+ 1 - 1
tools/assimp_qt_viewer/mainwindow.hpp

@@ -6,7 +6,7 @@
 #pragma once
 
 // Header files, Qt.
-#if ASSIMP_QT4_VIEWER
+#if defined ASSIMP_QT4_VIEWER
 #	include <QMainWindow>
 #else
 #	include <QtWidgets>