Explorar o código

Merge branch 'master' into coverity_scan

Kim Kulling %!s(int64=8) %!d(string=hai) anos
pai
achega
342b572281

+ 7 - 2
code/ObjExporter.cpp

@@ -87,11 +87,16 @@ static const std::string MaterialExt = ".mtl";
 ObjExporter::ObjExporter(const char* _filename, const aiScene* pScene)
 ObjExporter::ObjExporter(const char* _filename, const aiScene* pScene)
 : filename(_filename)
 : filename(_filename)
 , pScene(pScene)
 , pScene(pScene)
-, endl("\n")
 , vp()
 , vp()
 , vn()
 , vn()
 , vt()
 , vt()
-, vc() {
+, vc() 
+, vpMap()
+, vnMap()
+, vtMap()
+, vcMap()
+, meshes()
+, endl("\n") {
     // make sure that all formatting happens using the standard, C locale and not the user's current locale
     // make sure that all formatting happens using the standard, C locale and not the user's current locale
     const std::locale& l = std::locale("C");
     const std::locale& l = std::locale("C");
     mOutput.imbue(l);
     mOutput.imbue(l);

+ 0 - 3
code/ObjExporter.h

@@ -98,16 +98,13 @@ private:
     void WriteHeader(std::ostringstream& out);
     void WriteHeader(std::ostringstream& out);
     void WriteMaterialFile();
     void WriteMaterialFile();
     void WriteGeometryFile();
     void WriteGeometryFile();
-
     std::string GetMaterialName(unsigned int index);
     std::string GetMaterialName(unsigned int index);
-
     void AddMesh(const aiString& name, const aiMesh* m, const aiMatrix4x4& mat);
     void AddMesh(const aiString& name, const aiMesh* m, const aiMatrix4x4& mat);
     void AddNode(const aiNode* nd, const aiMatrix4x4& mParent);
     void AddNode(const aiNode* nd, const aiMatrix4x4& mParent);
 
 
 private:
 private:
     std::string filename;
     std::string filename;
     const aiScene* const pScene;
     const aiScene* const pScene;
-
     std::vector<aiVector3D> vp, vn, vt;
     std::vector<aiVector3D> vp, vn, vt;
     std::vector<aiColor4D> vc;
     std::vector<aiColor4D> vc;
 
 

+ 1 - 1
code/ObjFileMtlImporter.h

@@ -113,4 +113,4 @@ private:
 
 
 } // Namespace Assimp
 } // Namespace Assimp
 
 
-#endif
+#endif // OBJFILEMTLIMPORTER_H_INC

+ 25 - 14
code/ObjFileParser.cpp

@@ -57,8 +57,17 @@ namespace Assimp {
 
 
 const std::string ObjFileParser::DEFAULT_MATERIAL = AI_DEFAULT_MATERIAL_NAME;
 const std::string ObjFileParser::DEFAULT_MATERIAL = AI_DEFAULT_MATERIAL_NAME;
 
 
-// -------------------------------------------------------------------
-//  Constructor with loaded data and directories.
+ObjFileParser::ObjFileParser()
+: m_DataIt()
+, m_DataItEnd()
+, m_pModel( NULL )
+, m_uiLine( 0 )
+, m_pIO( nullptr )
+, m_progress( nullptr )
+, m_originalObjFileName( "" ) {
+    // empty
+}
+
 ObjFileParser::ObjFileParser( IOStreamBuffer<char> &streamBuffer, const std::string &modelName,
 ObjFileParser::ObjFileParser( IOStreamBuffer<char> &streamBuffer, const std::string &modelName,
                               IOSystem *io, ProgressHandler* progress,
                               IOSystem *io, ProgressHandler* progress,
                               const std::string &originalObjFileName) :
                               const std::string &originalObjFileName) :
@@ -86,18 +95,20 @@ ObjFileParser::ObjFileParser( IOStreamBuffer<char> &streamBuffer, const std::str
     parseFile( streamBuffer );
     parseFile( streamBuffer );
 }
 }
 
 
-// -------------------------------------------------------------------
-//  Destructor
 ObjFileParser::~ObjFileParser() {
 ObjFileParser::~ObjFileParser() {
     delete m_pModel;
     delete m_pModel;
     m_pModel = NULL;
     m_pModel = NULL;
 }
 }
 
 
-// -------------------------------------------------------------------
-//  Returns a pointer to the model instance.
+void ObjFileParser::setBuffer( std::vector<char> &buffer ) {
+    m_DataIt = buffer.begin();
+    m_DataItEnd = buffer.end();
+}
+
 ObjFile::Model *ObjFileParser::GetModel() const {
 ObjFile::Model *ObjFileParser::GetModel() const {
     return m_pModel;
     return m_pModel;
 }
 }
+
 void ignoreNewLines(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer)
 void ignoreNewLines(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer)
 {
 {
     auto curPosition = buffer.begin();
     auto curPosition = buffer.begin();
@@ -119,8 +130,7 @@ void ignoreNewLines(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffe
         }
         }
     } while (*curPosition!='\n');
     } while (*curPosition!='\n');
 }
 }
-// -------------------------------------------------------------------
-//  File parsing method.
+
 void ObjFileParser::parseFile( IOStreamBuffer<char> &streamBuffer ) {
 void ObjFileParser::parseFile( IOStreamBuffer<char> &streamBuffer ) {
     // only update every 100KB or it'll be too slow
     // only update every 100KB or it'll be too slow
     //const unsigned int updateProgressEveryBytes = 100 * 1024;
     //const unsigned int updateProgressEveryBytes = 100 * 1024;
@@ -144,7 +154,7 @@ void ObjFileParser::parseFile( IOStreamBuffer<char> &streamBuffer ) {
             progressCounter++;
             progressCounter++;
             m_progress->UpdateFileRead( progressOffset + processed * 2, progressTotal );
             m_progress->UpdateFileRead( progressOffset + processed * 2, progressTotal );
         }
         }
-		ignoreNewLines(streamBuffer, buffer);
+		//ignoreNewLines(streamBuffer, buffer);
         // parse line
         // parse line
         switch (*m_DataIt) {
         switch (*m_DataIt) {
         case 'v': // Parse a vertex texture coordinate
         case 'v': // Parse a vertex texture coordinate
@@ -243,11 +253,14 @@ pf_skip_line:
     }
     }
 }
 }
 
 
-// -------------------------------------------------------------------
-//  Copy the next word in a temporary buffer
 void ObjFileParser::copyNextWord(char *pBuffer, size_t length) {
 void ObjFileParser::copyNextWord(char *pBuffer, size_t length) {
     size_t index = 0;
     size_t index = 0;
     m_DataIt = getNextWord<DataArrayIt>(m_DataIt, m_DataItEnd);
     m_DataIt = getNextWord<DataArrayIt>(m_DataIt, m_DataItEnd);
+    if ( *m_DataIt == '\\' ) {
+        m_DataIt++;
+        m_DataIt++;
+        m_DataIt = getNextWord<DataArrayIt>( m_DataIt, m_DataItEnd );
+    }
     while( m_DataIt != m_DataItEnd && !IsSpaceOrNewLine( *m_DataIt ) ) {
     while( m_DataIt != m_DataItEnd && !IsSpaceOrNewLine( *m_DataIt ) ) {
         pBuffer[index] = *m_DataIt;
         pBuffer[index] = *m_DataIt;
         index++;
         index++;
@@ -264,7 +277,7 @@ void ObjFileParser::copyNextWord(char *pBuffer, size_t length) {
 size_t ObjFileParser::getNumComponentsInLine() {
 size_t ObjFileParser::getNumComponentsInLine() {
     size_t numComponents( 0 );
     size_t numComponents( 0 );
     const char* tmp( &m_DataIt[0] );
     const char* tmp( &m_DataIt[0] );
-    while( !IsLineEnd( *tmp ) ) {
+    while( !IsLineEnd( *tmp ) ) {        
         if ( !SkipSpaces( &tmp ) ) {
         if ( !SkipSpaces( &tmp ) ) {
             break;
             break;
         }
         }
@@ -300,8 +313,6 @@ void ObjFileParser::getVector( std::vector<aiVector3D> &point3d_array ) {
     m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
     m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
 }
 }
 
 
-// -------------------------------------------------------------------
-//  Get values for a new 3D vector instance
 void ObjFileParser::getVector3( std::vector<aiVector3D> &point3d_array ) {
 void ObjFileParser::getVector3( std::vector<aiVector3D> &point3d_array ) {
     ai_real x, y, z;
     ai_real x, y, z;
     copyNextWord(m_buffer, Buffersize);
     copyNextWord(m_buffer, Buffersize);

+ 10 - 6
code/ObjFileParser.h

@@ -65,7 +65,7 @@ class ProgressHandler;
 
 
 /// \class  ObjFileParser
 /// \class  ObjFileParser
 /// \brief  Parser for a obj waveform file
 /// \brief  Parser for a obj waveform file
-class ObjFileParser {
+class ASSIMP_API ObjFileParser {
 public:
 public:
     static const size_t Buffersize = 4096;
     static const size_t Buffersize = 4096;
     typedef std::vector<char> DataArray;
     typedef std::vector<char> DataArray;
@@ -73,14 +73,18 @@ public:
     typedef std::vector<char>::const_iterator ConstDataArrayIt;
     typedef std::vector<char>::const_iterator ConstDataArrayIt;
 
 
 public:
 public:
-    /// \brief  Constructor with data array.
-    ObjFileParser( IOStreamBuffer<char> &streamBuffer, const std::string &strModelName, IOSystem* io, ProgressHandler* progress, const std::string &originalObjFileName);
-    /// \brief  Destructor
+    /// @brief  The default constructor.
+    ObjFileParser();
+    /// @brief  Constructor with data array.
+    ObjFileParser( IOStreamBuffer<char> &streamBuffer, const std::string &modelName, IOSystem* io, ProgressHandler* progress, const std::string &originalObjFileName);
+    /// @brief  Destructor
     ~ObjFileParser();
     ~ObjFileParser();
-    /// \brief  Model getter.
+    /// @brief  If you want to load in-core data.
+    void setBuffer( std::vector<char> &buffer );
+    /// @brief  Model getter.
     ObjFile::Model *GetModel() const;
     ObjFile::Model *GetModel() const;
 
 
-private:
+protected:
     /// Parse the loaded file
     /// Parse the loaded file
     void parseFile( IOStreamBuffer<char> &streamBuffer );
     void parseFile( IOStreamBuffer<char> &streamBuffer );
     /// Method to copy the new delimited word in the current line.
     /// Method to copy the new delimited word in the current line.

+ 4 - 2
code/ObjTools.h

@@ -79,8 +79,10 @@ inline Char_T getNextWord( Char_T pBuffer, Char_T pEnd )
 {
 {
     while ( !isEndOfBuffer( pBuffer, pEnd ) )
     while ( !isEndOfBuffer( pBuffer, pEnd ) )
     {
     {
-        if( !IsSpaceOrNewLine( *pBuffer ) || IsLineEnd( *pBuffer ) )
-            break;
+        if ( !IsSpaceOrNewLine( *pBuffer ) || IsLineEnd( *pBuffer ) ) {
+            //if ( *pBuffer != '\\' )
+                break;
+        }
         pBuffer++;
         pBuffer++;
     }
     }
     return pBuffer;
     return pBuffer;

+ 12 - 15
code/SIBImporter.cpp

@@ -66,7 +66,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
 #include <map>
 #include <map>
 
 
-
 using namespace Assimp;
 using namespace Assimp;
 
 
 static const aiImporterDesc desc = {
 static const aiImporterDesc desc = {
@@ -80,25 +79,26 @@ static const aiImporterDesc desc = {
     "sib"
     "sib"
 };
 };
 
 
-struct SIBChunk
-{
+struct SIBChunk {
     uint32_t    Tag;
     uint32_t    Tag;
     uint32_t    Size;
     uint32_t    Size;
 } PACK_STRUCT;
 } PACK_STRUCT;
 
 
-enum { POS, NRM, UV,    N };
+enum { 
+    POS, 
+    NRM, 
+    UV,    
+    N
+};
 
 
 typedef std::pair<uint32_t, uint32_t> SIBPair;
 typedef std::pair<uint32_t, uint32_t> SIBPair;
-static SIBPair makePair(uint32_t a, uint32_t b) { return (a<b) ? SIBPair(a, b) : SIBPair(b, a); }
 
 
-struct SIBEdge
-{
+struct SIBEdge {
     uint32_t faceA, faceB;
     uint32_t faceA, faceB;
     bool creased;
     bool creased;
 };
 };
 
 
-struct SIBMesh
-{
+struct SIBMesh {
     aiMatrix4x4 axis;
     aiMatrix4x4 axis;
     uint32_t numPts;
     uint32_t numPts;
     std::vector<aiVector3D> pos, nrm, uv;
     std::vector<aiVector3D> pos, nrm, uv;
@@ -109,15 +109,13 @@ struct SIBMesh
     std::map<SIBPair, uint32_t> edgeMap;
     std::map<SIBPair, uint32_t> edgeMap;
 };
 };
 
 
-struct SIBObject
-{
+struct SIBObject {
     aiString name;
     aiString name;
     aiMatrix4x4 axis;
     aiMatrix4x4 axis;
     size_t meshIdx, meshCount;
     size_t meshIdx, meshCount;
 };
 };
 
 
-struct SIB
-{
+struct SIB {
     std::vector<aiMaterial*> mtls;
     std::vector<aiMaterial*> mtls;
     std::vector<aiMesh*> meshes;
     std::vector<aiMesh*> meshes;
     std::vector<aiLight*> lights;
     std::vector<aiLight*> lights;
@@ -125,8 +123,7 @@ struct SIB
 };
 };
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
-static SIBEdge& GetEdge(SIBMesh* mesh, uint32_t posA, uint32_t posB)
-{
+static SIBEdge& GetEdge(SIBMesh* mesh, uint32_t posA, uint32_t posB) {
     SIBPair pair = (posA < posB) ? SIBPair(posA, posB) : SIBPair(posB, posA);
     SIBPair pair = (posA < posB) ? SIBPair(posA, posB) : SIBPair(posB, posA);
     std::map<SIBPair, uint32_t>::iterator it = mesh->edgeMap.find(pair);
     std::map<SIBPair, uint32_t>::iterator it = mesh->edgeMap.find(pair);
     if (it != mesh->edgeMap.end())
     if (it != mesh->edgeMap.end())

+ 7 - 3
code/glTFAsset.h

@@ -46,8 +46,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *   KHR_binary_glTF: full
  *   KHR_binary_glTF: full
  *   KHR_materials_common: full
  *   KHR_materials_common: full
  */
  */
-#ifndef glTFAsset_H_INC
-#define glTFAsset_H_INC
+#ifndef GLTFASSET_H_INC
+#define GLTFASSET_H_INC
+
+#ifndef ASSIMP_BUILD_NO_GLTF_IMPORTER
 
 
 #include <map>
 #include <map>
 #include <string>
 #include <string>
@@ -1187,4 +1189,6 @@ namespace glTF
 // Include the implementation of the methods
 // Include the implementation of the methods
 #include "glTFAsset.inl"
 #include "glTFAsset.inl"
 
 
-#endif
+#endif // ASSIMP_BUILD_NO_GLTF_IMPORTER
+
+#endif // GLTFASSET_H_INC

+ 7 - 3
code/glTFAssetWriter.h

@@ -46,8 +46,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *   KHR_binary_glTF: full
  *   KHR_binary_glTF: full
  *   KHR_materials_common: full
  *   KHR_materials_common: full
  */
  */
-#ifndef glTFAssetWriter_H_INC
-#define glTFAssetWriter_H_INC
+#ifndef GLTFASSETWRITER_H_INC
+#define GLTFASSETWRITER_H_INC
+
+#ifndef ASSIMP_BUILD_NO_GLTF_IMPORTER
 
 
 #include "glTFAsset.h"
 #include "glTFAsset.h"
 
 
@@ -88,4 +90,6 @@ public:
 // Include the implementation of the methods
 // Include the implementation of the methods
 #include "glTFAssetWriter.inl"
 #include "glTFAssetWriter.inl"
 
 
-#endif
+#endif // ASSIMP_BUILD_NO_GLTF_IMPORTER
+
+#endif // GLTFASSETWRITER_H_INC

+ 5 - 1
code/glTFExporter.h

@@ -45,6 +45,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef AI_GLTFEXPORTER_H_INC
 #ifndef AI_GLTFEXPORTER_H_INC
 #define AI_GLTFEXPORTER_H_INC
 #define AI_GLTFEXPORTER_H_INC
 
 
+#ifndef ASSIMP_BUILD_NO_GLTF_IMPORTER
+
 #include <assimp/types.h>
 #include <assimp/types.h>
 #include <assimp/material.h>
 #include <assimp/material.h>
 
 
@@ -111,4 +113,6 @@ namespace Assimp
 
 
 }
 }
 
 
-#endif
+#endif // ASSIMP_BUILD_NO_GLTF_IMPORTER
+
+#endif // AI_GLTFEXPORTER_H_INC

+ 8 - 1
include/assimp/metadata.h

@@ -134,7 +134,6 @@ struct aiMetadata {
         // empty
         // empty
     }
     }
 
 
-
     /** 
     /** 
      *  @brief The destructor.
      *  @brief The destructor.
      */
      */
@@ -199,6 +198,14 @@ struct aiMetadata {
         return data;
         return data;
     }
     }
 
 
+    /**
+     *  @brief Deallocates property fields + keys.
+     */
+    static inline
+    void Dealloc( aiMetadata *metadata ) {
+        delete metadata;
+    }
+
 	template<typename T>
 	template<typename T>
 	inline void Add(const std::string& key, const T& value)
 	inline void Add(const std::string& key, const T& value)
 	{
 	{

+ 1 - 1
test/CMakeLists.txt

@@ -38,7 +38,6 @@
 #----------------------------------------------------------------------
 #----------------------------------------------------------------------
 cmake_minimum_required( VERSION 2.6 )
 cmake_minimum_required( VERSION 2.6 )
 
 
-#INCLUDE( AddGTest )
 include( CTest )
 include( CTest )
 enable_testing()
 enable_testing()
 
 
@@ -106,6 +105,7 @@ SET( TEST_SRCS
   unit/SceneDiffer.cpp
   unit/SceneDiffer.cpp
   unit/utSIBImporter.cpp
   unit/utSIBImporter.cpp
   unit/utObjImportExport.cpp
   unit/utObjImportExport.cpp
+  unit/utObjTools.cpp
   unit/utOpenGEXImportExport.cpp
   unit/utOpenGEXImportExport.cpp
   unit/utPretransformVertices.cpp
   unit/utPretransformVertices.cpp
   unit/utPLYImportExport.cpp
   unit/utPLYImportExport.cpp

+ 3 - 3
test/unit/utBlendImportMaterials.cpp

@@ -70,7 +70,7 @@ TEST_F(BlendImportMaterials, testImportMaterial)
     ASSERT_TRUE(pTest != NULL);
     ASSERT_TRUE(pTest != NULL);
     ASSERT_TRUE(pTest->HasMaterials());
     ASSERT_TRUE(pTest->HasMaterials());
 
 
-    ASSERT_EQ(1, pTest->mNumMaterials);
+    ASSERT_EQ(1U, pTest->mNumMaterials);
 
 
     auto alpha = pTest->mMaterials[0];
     auto alpha = pTest->mMaterials[0];
 
 
@@ -86,8 +86,8 @@ TEST_F(BlendImportMaterials, testImportMaterial)
 
 
     ASSERT_PROPERTY_EQ(aiColor3D(0.1f, 0.2f, 0.3f), "diffuse.color", diffuseColor);
     ASSERT_PROPERTY_EQ(aiColor3D(0.1f, 0.2f, 0.3f), "diffuse.color", diffuseColor);
     ASSERT_PROPERTY_EQ(0.4f, "diffuse.intensity", diffuseIntensity);
     ASSERT_PROPERTY_EQ(0.4f, "diffuse.intensity", diffuseIntensity);
-    ASSERT_PROPERTY_EQ(1, "diffuse.shader", diffuseShader);
-    ASSERT_PROPERTY_EQ(0, "diffuse.ramp", diffuseRamp);
+    ASSERT_PROPERTY_EQ(1U, "diffuse.shader", diffuseShader);
+    ASSERT_PROPERTY_EQ(0U, "diffuse.ramp", diffuseRamp);
 
 
     ASSERT_PROPERTY_EQ(aiColor3D(0.5f, 0.6f, 0.7f), "specular.color", specularColor);
     ASSERT_PROPERTY_EQ(aiColor3D(0.5f, 0.6f, 0.7f), "specular.color", specularColor);
     ASSERT_PROPERTY_EQ(0.8f, "specular.intensity", specularIntensity);
     ASSERT_PROPERTY_EQ(0.8f, "specular.intensity", specularIntensity);

+ 4 - 3
test/unit/utIOSystem.cpp

@@ -63,12 +63,13 @@ protected:
 
 
 TEST_F( IOSystemTest, accessDirectoryStackTest ) {
 TEST_F( IOSystemTest, accessDirectoryStackTest ) {
     EXPECT_FALSE( pImp->PopDirectory() );
     EXPECT_FALSE( pImp->PopDirectory() );
-    EXPECT_EQ( 0, pImp->StackSize() );
+    EXPECT_EQ( 0U, pImp->StackSize() );
     EXPECT_FALSE( pImp->PushDirectory( "" ) );
     EXPECT_FALSE( pImp->PushDirectory( "" ) );
     std::string path = "test/";
     std::string path = "test/";
     EXPECT_TRUE( pImp->PushDirectory( path ) );
     EXPECT_TRUE( pImp->PushDirectory( path ) );
-    EXPECT_EQ( 1, pImp->StackSize() );
+    EXPECT_EQ( 1U, pImp->StackSize() );
     EXPECT_EQ( path, pImp->CurrentDirectory() );
     EXPECT_EQ( path, pImp->CurrentDirectory() );
     EXPECT_TRUE( pImp->PopDirectory() );
     EXPECT_TRUE( pImp->PopDirectory() );
-    EXPECT_EQ( 0, pImp->StackSize() );
+    EXPECT_EQ( 0U, pImp->StackSize() );
 }
 }
+

+ 1 - 1
test/unit/utMetadata.cpp

@@ -55,7 +55,7 @@ protected:
     }
     }
 
 
     virtual void TearDown() {
     virtual void TearDown() {
-        delete m_data;
+        aiMetadata::Dealloc( m_data );
     }
     }
 
 
 };
 };

+ 93 - 0
test/unit/utObjTools.cpp

@@ -0,0 +1,93 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2017, 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 "ObjTools.h"
+#include "ObjFileParser.h"
+
+using namespace ::Assimp;
+
+class utObjTools : public ::testing::Test {
+    // empty
+};
+
+class TestObjFileParser : public ObjFileParser {
+public:
+    TestObjFileParser() : ObjFileParser(){}
+    ~TestObjFileParser() {}
+    void testCopyNextWord( char *pBuffer, size_t length ) {
+        copyNextWord( pBuffer, length );
+    }
+
+};
+TEST_F( utObjTools, skipDataLine_OneLine_Success ) {
+    std::vector<char> buffer;
+    std::string data( "v -0.5 -0.5 0.5\nend" );
+    buffer.resize( data.size() );
+    ::memcpy( &buffer[ 0 ], &data[ 0 ], data.size() );
+    std::vector<char>::iterator itBegin( buffer.begin() ), itEnd( buffer.end() );
+    unsigned int line = 0;
+    std::vector<char>::iterator current = skipLine<std::vector<char>::iterator>( itBegin, itEnd, line );
+    EXPECT_EQ( 'e', *current );
+}
+
+TEST_F( utObjTools, skipDataLine_TwoLines_Success ) {
+    TestObjFileParser test_parser;
+    std::string data( "vn -2.061493116917992e-15 -0.9009688496589661 \\n-0.4338837265968323" );
+    std::vector<char> buffer;
+    buffer.resize( data.size() );
+    ::memcpy( &buffer[ 0 ], &data[ 0 ], data.size() );
+    test_parser.setBuffer( buffer );
+    static const size_t Size = 4096UL;
+    char data_buffer[ Size ];
+    
+    test_parser.testCopyNextWord( data_buffer, Size );
+    EXPECT_EQ( 0, strncmp( data_buffer, "vn", 2 ) );
+
+    test_parser.testCopyNextWord( data_buffer, Size );
+    EXPECT_EQ( data_buffer[0], '-' );
+
+    test_parser.testCopyNextWord( data_buffer, Size );
+    EXPECT_EQ( data_buffer[0], '-' );
+
+    test_parser.testCopyNextWord( data_buffer, Size );
+    EXPECT_EQ( data_buffer[ 0 ], '-' );
+}

+ 1 - 0
test/unit/utOpenGEXImportExport.cpp

@@ -66,5 +66,6 @@ TEST_F( utOpenGEXImportExport, importLWSFromFileTest ) {
 TEST_F( utOpenGEXImportExport, Importissue1262_NoCrash ) {
 TEST_F( utOpenGEXImportExport, Importissue1262_NoCrash ) {
     Assimp::Importer importer;
     Assimp::Importer importer;
     const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/OpenGEX/light_issue1262.ogex", 0 );
     const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/OpenGEX/light_issue1262.ogex", 0 );
+    EXPECT_NE( nullptr, scene );
 
 
 }
 }