Ver código fonte

update:
- merge master into branch
- fix metrix header parsing.

Signed-off-by: Kim Kulling <[email protected]>

Kim Kulling 11 anos atrás
pai
commit
6843c42da1
2 arquivos alterados com 98 adições e 37 exclusões
  1. 82 35
      code/OpenGEXParser.cpp
  2. 16 2
      code/OpenGEXParser.h

+ 82 - 35
code/OpenGEXParser.cpp

@@ -55,8 +55,7 @@ static const std::string Metric         = "Metric";
 static const std::string GeometryNode   = "GeometryNode";
 static const std::string GeometryObject = "GeometryObject";
 static const std::string Material       = "Material";
-static const size_t NumObjects = 4;
-
+static const size_t      NumObjects     = 4;
 static const std::string RootNodes[ NumObjects ] = {
     Metric,
     GeometryNode,
@@ -64,9 +63,31 @@ static const std::string RootNodes[ NumObjects ] = {
     Material
 };
 
-static bool containsNode( const char *bufferPtr, size_t size, const std::string *nodes, size_t numNodes,
-                          const std::string *tokenFound ) {
-    tokenFound = NULL;
+static const size_t      NumSeparator = 4;
+static const std::string Separator[ NumSeparator ] = {
+    "(", ")", "{", "}"
+};
+
+
+static const size_t      NumToken = 8;
+static const std::string Token[ NumToken ] = {
+    RootNodes[ 0 ],
+    RootNodes[ 1 ],
+    RootNodes[ 2 ],
+    RootNodes[ 3 ],
+    Separator[ 0 ],
+    Separator[ 1 ],
+    Separator[ 2 ],
+    Separator[ 3 ]
+};
+
+static bool isSeparator( char in ) {
+    return ( in == '(' || in == ')' || in == '{' || in == '}' );
+}
+
+static bool containsNode( const char *bufferPtr, size_t size, const std::string *nodes, 
+                          size_t numNodes, std::string &tokenFound ) {
+    tokenFound = "";
     if( 0 == numNodes ) {
         return false;
     }
@@ -74,7 +95,7 @@ static bool containsNode( const char *bufferPtr, size_t size, const std::string
     bool found( false );
     for( size_t i = 0; i < numNodes; ++i ) {
         if( TokenMatch( bufferPtr, nodes[ i ].c_str(), nodes[ i ].size() ) ) {
-            tokenFound = &nodes[ i ];
+            tokenFound = nodes[ i ];
             found = true;
             break;
         }
@@ -83,12 +104,27 @@ static bool containsNode( const char *bufferPtr, size_t size, const std::string
     return found;
 }
 
+static OpenGEXParser::TokenType getTokenTypeByName( const char *in ) {
+    ai_assert( NULL != in );
+
+    OpenGEXParser::TokenType type( OpenGEXParser::None );
+    for( size_t i = 0; i < NumToken; ++i ) {
+        if( TokenMatch( in, Token[ i ].c_str(), Token[ i ].size() ) ) {
+            type = static_cast<OpenGEXParser::TokenType>( i+1 );
+            break;
+        }
+    }
+
+    return type;
+}
+
 //------------------------------------------------------------------------------------------------
 OpenGEXParser::OpenGEXParser( const std::vector<char> &buffer ) 
 : m_buffer( buffer ) 
 , m_index( 0 )
-, m_buffersize( buffer.size() ) {
-
+, m_buffersize( buffer.size() )
+, m_nodeTypeStack() {
+    // empty
 }
 
 //------------------------------------------------------------------------------------------------
@@ -107,10 +143,10 @@ void OpenGEXParser::parse() {
 std::string OpenGEXParser::getNextToken() {
     std::string token;
     while( m_index < m_buffersize && IsSpace( m_buffer[ m_index ] ) ) {
-        ++m_index;
+        m_index++;
     }
 
-    while( m_index < m_buffersize && !IsSpace( m_buffer[ m_index ] ) ) {
+    while( m_index < m_buffersize && !IsSpace( m_buffer[ m_index ] ) && !isSeparator( m_buffer[ m_index ] ) ) {
         token += m_buffer[ m_index ];
         m_index++;
     }
@@ -120,6 +156,13 @@ std::string OpenGEXParser::getNextToken() {
         token = getNextToken();
     }
 
+    if( token.empty() ) {
+        if( isSeparator( m_buffer[ m_index ] ) ) {
+            token += m_buffer[ m_index ];
+            m_index++;
+        }
+    }
+
     return token;
 }
 
@@ -140,7 +183,8 @@ bool OpenGEXParser::skipComments() {
 bool OpenGEXParser::parseNextNode() {
     std::string token( getNextToken() );
     std::string rootNodeName;
-    if( containsNode( token.c_str(), token.size(), RootNodes, NumObjects, &rootNodeName ) ) {
+    if( containsNode( token.c_str(), token.size(), RootNodes, NumObjects, rootNodeName ) ) {
+        m_nodeTypeStack.push_back( getTokenTypeByName( rootNodeName.c_str() ) );
         if( !getNodeHeader( rootNodeName ) ) {
             return false;
         }
@@ -148,6 +192,8 @@ bool OpenGEXParser::parseNextNode() {
         if( !getNodeData() ) {
             return false;
         }
+
+        m_nodeTypeStack.pop_back();
     }
 
     return true;
@@ -155,12 +201,15 @@ bool OpenGEXParser::parseNextNode() {
 
 //------------------------------------------------------------------------------------------------
 bool OpenGEXParser::getNodeHeader( const std::string &name ) {
-    if( name == Metric ) {
-        std::string token( getNextToken() );
-
+    bool success( false );
+    if( m_nodeTypeStack.back() == MetricNode ) {
+        std::string attribName, value;
+        if( getMetricAttributeKey( attribName, value ) ) {
+            success = true;
+        }
     }
 
-    return false;
+    return success;
 }
 
 //------------------------------------------------------------------------------------------------
@@ -226,33 +275,31 @@ bool OpenGEXParser::getFloatData( size_t num, float *data ) {
 
 //------------------------------------------------------------------------------------------------
 bool OpenGEXParser::getNodeData() {
-    if( !getBracketOpen() ) {
-        return false;
-    }
-
-    if( !onMetricNode() ) {
-        return false;
-    }
-
-    if( !getBracketClose() ) {
-        return false;
-    }
-
     return true;
 }
 
 //------------------------------------------------------------------------------------------------
-bool OpenGEXParser::getMetricAttribute( std::string &attribName ) {
-    return false;
+bool OpenGEXParser::getMetricAttributeKey( std::string &attribName, std::string &value ) {
+    bool ok( false );
+    attribName = "";
+    std::string token( getNextToken() );
+    if( token[ 0 ] == '(' ) {
+        // get attribute
+        attribName = getNextToken();
+        std::string equal = getNextToken();
+        value = getNextToken();
+        
+        token = getNextToken();
+        if( token[ 0 ] == ')' ) {
+            ok = true;
+        }
+    }
+
+    return ok;
 }
 
 //------------------------------------------------------------------------------------------------
-bool OpenGEXParser::onMetricNode() {
-    std::string attribName;
-    if( !getMetricAttribute( attribName ) ) {
-        return false;
-    }
-
+bool OpenGEXParser::onMetricNode( const std::string &attribName ) {
     if( "distance" == attribName ) {
         float distance( 0.0f );
         getFloatData( 1, &distance );

+ 16 - 2
code/OpenGEXParser.h

@@ -47,6 +47,19 @@ namespace Assimp {
 namespace OpenGEX {
 
 class OpenGEXParser {
+public:
+    enum TokenType {
+        None = 0,
+        MetricNode,
+        GeometryNode,
+        GeometryObject,
+        Material,
+        BracketIn,
+        BracketOut,
+        CurlyBracketIn,
+        CurlyBracketOut,
+    };
+
 public:
     OpenGEXParser( const std::vector<char> &buffer );
     ~OpenGEXParser();
@@ -62,8 +75,8 @@ protected:
     bool getStringData( std::string &data );
     bool getFloatData( size_t num, float *data );
     bool getNodeData();
-    bool getMetricAttribute( std::string &attribName );
-    bool onMetricNode();
+    bool getMetricAttributeKey( std::string &attribName, std::string &value );
+    bool onMetricNode( const std::string &attribName );
 
 private:
     OpenGEXParser( const OpenGEXParser & );
@@ -71,6 +84,7 @@ private:
 
 private:
     const std::vector<char> &m_buffer;
+    std::vector<TokenType> m_nodeTypeStack;
     size_t m_index;
     size_t m_buffersize;
 };