Commit d819a380 authored by Sven D's avatar Sven D Committed by Wayne Stambaugh
Browse files

Fix VRML V2 parser bug. (fixes lp:1417217)

* Add support for VRML DEF coordinate key word.
* Coding policy fixes by Blair Bonnett <blair.bonnett@gmail.com>
* Debugging output clean up.
parent 1e2af7fe
Loading
Loading
Loading
Loading
+59 −64
Original line number Original line Diff line number Diff line
@@ -2,7 +2,7 @@
 * This program source code file is part of KiCad, a free EDA CAD application.
 * This program source code file is part of KiCad, a free EDA CAD application.
 *
 *
 * Copyright (C) 2014 Mario Luzeiro <mrluzeiro@gmail.com>
 * Copyright (C) 2014 Mario Luzeiro <mrluzeiro@gmail.com>
 * Copyright (C) 1992-2014 KiCad Developers, see AUTHORS.txt for contributors.
 * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
 *
 *
 * This program is free software; you can redistribute it and/or
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * modify it under the terms of the GNU General Public License
@@ -59,6 +59,7 @@ S3D_MESH::~S3D_MESH()
    }
    }
}
}



void S3D_MESH::openGL_RenderAllChilds()
void S3D_MESH::openGL_RenderAllChilds()
{
{
    //DBG( printf( "openGL_RenderAllChilds") );
    //DBG( printf( "openGL_RenderAllChilds") );
@@ -82,7 +83,6 @@ void S3D_MESH::openGL_RenderAllChilds()
    SetOpenGlDefaultMaterial();
    SetOpenGlDefaultMaterial();


    glPopMatrix();
    glPopMatrix();

}
}




@@ -94,15 +94,10 @@ void S3D_MESH::openGL_Render()
                        && g_Parm_3D_Visu.GetFlag( FL_RENDER_SMOOTH );
                        && g_Parm_3D_Visu.GetFlag( FL_RENDER_SMOOTH );


    if( m_Materials )
    if( m_Materials )
    {
        m_Materials->SetOpenGLMaterial( 0, useMaterial );
        m_Materials->SetOpenGLMaterial( 0, useMaterial );
    }


    if( m_CoordIndex.size() == 0 )
    if( m_CoordIndex.size() == 0 )
    {

        return;
        return;
    }


    glPushMatrix();
    glPushMatrix();
    glTranslatef( m_translation.x, m_translation.y, m_translation.z );
    glTranslatef( m_translation.x, m_translation.y, m_translation.z );
@@ -117,27 +112,29 @@ void S3D_MESH::openGL_Render()
    if( m_PerVertexNormalsNormalized.size() == 0 )
    if( m_PerVertexNormalsNormalized.size() == 0 )
    {
    {
        if( smoothShapes )
        if( smoothShapes )
        {
            calcPerPointNormals();
            calcPerPointNormals();
    }
    }
    }


    for( unsigned int idx = 0; idx < m_CoordIndex.size(); idx++ )
    for( unsigned int idx = 0; idx < m_CoordIndex.size(); idx++ )
    {
    {
        if( m_MaterialIndex.size() > 1 )
        if( m_MaterialIndex.size() > 1 )
        {
        {
            if( m_Materials )
            if( m_Materials )
            {
                m_Materials->SetOpenGLMaterial( m_MaterialIndex[idx], useMaterial );
                m_Materials->SetOpenGLMaterial( m_MaterialIndex[idx], useMaterial );
        }
        }
        }




        switch( m_CoordIndex[idx].size() )
        switch( m_CoordIndex[idx].size() )
        {
        {
        case 3:     glBegin( GL_TRIANGLES );break;
        case 3:
        case 4:     glBegin( GL_QUADS );    break;
            glBegin( GL_TRIANGLES );
        default:    glBegin( GL_POLYGON );  break;
            break;
        case 4:
            glBegin( GL_QUADS );
            break;
        default:
            glBegin( GL_POLYGON );
            break;
        }
        }




@@ -192,24 +189,26 @@ void S3D_MESH::calcPointNormalized ()
    //DBG( printf( "calcPointNormalized\n" ) );
    //DBG( printf( "calcPointNormalized\n" ) );


    if( isPointNormalizedComputed == true )
    if( isPointNormalizedComputed == true )
    {
        return;
        return;
    }

    isPointNormalizedComputed = true;
    isPointNormalizedComputed = true;


    if( m_PerVertexNormalsNormalized.size() > 0 )
    if( m_PerVertexNormalsNormalized.size() > 0 )
    {
        return;
        return;
    }


    m_PointNormalized.clear();
    m_PointNormalized.clear();


    float biggerPoint = 0.0f;
    float biggerPoint = 0.0f;
    for( unsigned int i = 0; i< m_Point.size(); i++ )
    for( unsigned int i = 0; i< m_Point.size(); i++ )
    {
    {
        if( fabs( m_Point[i].x ) > biggerPoint) biggerPoint = fabs( m_Point[i].x );
        if( fabs( m_Point[i].x ) > biggerPoint )
        if( fabs( m_Point[i].y ) > biggerPoint) biggerPoint = fabs( m_Point[i].y );
            biggerPoint = fabs( m_Point[i].x );
        if( fabs( m_Point[i].z ) > biggerPoint) biggerPoint = fabs( m_Point[i].z );

        if( fabs( m_Point[i].y ) > biggerPoint )
            biggerPoint = fabs( m_Point[i].y );

        if( fabs( m_Point[i].z ) > biggerPoint )
            biggerPoint = fabs( m_Point[i].z );
    }
    }


    biggerPoint = 1.0 / biggerPoint;
    biggerPoint = 1.0 / biggerPoint;
@@ -242,25 +241,17 @@ void S3D_MESH::calcPerFaceNormals ()
    //DBG( printf( "calcPerFaceNormals" ) );
    //DBG( printf( "calcPerFaceNormals" ) );


    if( isPerFaceNormalsComputed == true )
    if( isPerFaceNormalsComputed == true )
    {

        return;
        return;
    }
    isPerFaceNormalsComputed = true;


    isPerFaceNormalsComputed = true;


    if( m_PerVertexNormalsNormalized.size() > 0 )
    if( m_PerVertexNormalsNormalized.size() > 0 )
    {

        return;
        return;
    }


    bool haveAlreadyNormals_from_model_file = false;
    bool haveAlreadyNormals_from_model_file = false;


    if( m_PerFaceNormalsNormalized.size() > 0 )
    if( m_PerFaceNormalsNormalized.size() > 0 )
    {
        haveAlreadyNormals_from_model_file = true;
        haveAlreadyNormals_from_model_file = true;
    }


    m_PerFaceNormalsRaw.clear();
    m_PerFaceNormalsRaw.clear();
    m_PerFaceSquaredArea.clear();
    m_PerFaceSquaredArea.clear();
@@ -268,9 +259,15 @@ void S3D_MESH::calcPerFaceNormals ()
    //DBG( printf("m_CoordIndex.size %u\n", m_CoordIndex.size()) );
    //DBG( printf("m_CoordIndex.size %u\n", m_CoordIndex.size()) );
    //DBG( printf("m_PointNormalized.size %u\n", m_PointNormalized.size()) );
    //DBG( printf("m_PointNormalized.size %u\n", m_PointNormalized.size()) );


    for( unsigned int idx = 0; idx < m_CoordIndex.size(); idx++ )
    // There are no points defined for the coordIndex
    if( m_PointNormalized.size() == 0 )
    {
    {
        m_CoordIndex.clear();
        return;
    }


    for( unsigned int idx = 0; idx < m_CoordIndex.size(); idx++ )
    {
        // User normalized and multiply to get better resolution
        // User normalized and multiply to get better resolution
        glm::vec3 v0 = m_PointNormalized[m_CoordIndex[idx][0]];
        glm::vec3 v0 = m_PointNormalized[m_CoordIndex[idx][0]];
        glm::vec3 v1 = m_PointNormalized[m_CoordIndex[idx][1]];
        glm::vec3 v1 = m_PointNormalized[m_CoordIndex[idx][1]];
@@ -300,14 +297,10 @@ void S3D_MESH::calcPerFaceNormals ()
        float area = glm::dot( cross_prod, cross_prod );
        float area = glm::dot( cross_prod, cross_prod );


        if( cross_prod[2] < 0.0 )
        if( cross_prod[2] < 0.0 )
        {
            area = -area;
            area = -area;
        }


        if( area < FLT_EPSILON )
        if( area < FLT_EPSILON )
        {
            area = FLT_EPSILON * 2.0f;
            area = FLT_EPSILON * 2.0f;
        }


        m_PerFaceSquaredArea.push_back( area );
        m_PerFaceSquaredArea.push_back( area );


@@ -315,7 +308,6 @@ void S3D_MESH::calcPerFaceNormals ()


        if( haveAlreadyNormals_from_model_file == false )
        if( haveAlreadyNormals_from_model_file == false )
        {
        {

            // normalize vertex normal
            // normalize vertex normal
            float l = glm::length( cross_prod );
            float l = glm::length( cross_prod );


@@ -328,23 +320,30 @@ void S3D_MESH::calcPerFaceNormals ()
                // Cannot calc normal
                // Cannot calc normal
                if( ( cross_prod.x > cross_prod.y ) && ( cross_prod.x > cross_prod.z ) )
                if( ( cross_prod.x > cross_prod.y ) && ( cross_prod.x > cross_prod.z ) )
                {
                {
                    cross_prod.x = 1.0;    cross_prod.y = 0.0; cross_prod.z = 0.0;
                    cross_prod.x = 1.0;
                } else if( ( cross_prod.y > cross_prod.x ) && ( cross_prod.y > cross_prod.z ))
                    cross_prod.y = 0.0;
                    cross_prod.z = 0.0;
                }
                else if( ( cross_prod.y > cross_prod.x ) && ( cross_prod.y > cross_prod.z ) )
                {
                {
                    cross_prod.x = 0.0;    cross_prod.y = 1.0; cross_prod.z = 0.0;
                    cross_prod.x = 0.0;
                } else
                    cross_prod.y = 1.0;
                    cross_prod.z = 0.0;
                }
                else
                {
                {
                    cross_prod.x = 0.0;    cross_prod.y = 1.0; cross_prod.z = 0.0;
                    cross_prod.x = 0.0;
                    cross_prod.y = 0.0;
                    cross_prod.z = 1.0;
                }
                }
            }
            }


            m_PerFaceNormalsNormalized.push_back( cross_prod );
            m_PerFaceNormalsNormalized.push_back( cross_prod );
        }
        }

    }
    }

}
}



// http://www.bytehazard.com/code/vertnorm.html
// http://www.bytehazard.com/code/vertnorm.html
// http://www.emeyex.com/site/tuts/VertexNormals.pdf
// http://www.emeyex.com/site/tuts/VertexNormals.pdf
void S3D_MESH::calcPerPointNormals()
void S3D_MESH::calcPerPointNormals()
@@ -352,15 +351,12 @@ void S3D_MESH::calcPerPointNormals ()
    //DBG( printf( "calcPerPointNormals" ) );
    //DBG( printf( "calcPerPointNormals" ) );


    if( isPerPointNormalsComputed == true )
    if( isPerPointNormalsComputed == true )
    {
        return;
        return;
    }

    isPerPointNormalsComputed = true;
    isPerPointNormalsComputed = true;


    if( m_PerVertexNormalsNormalized.size() > 0 )
    if( m_PerVertexNormalsNormalized.size() > 0 )
    {
        return;
        return;
    }


    m_PerFaceVertexNormals.clear();
    m_PerFaceVertexNormals.clear();


@@ -371,6 +367,7 @@ void S3D_MESH::calcPerPointNormals ()
    #ifdef USE_OPENMP
    #ifdef USE_OPENMP
    #pragma omp parallel for
    #pragma omp parallel for
    #endif /* USE_OPENMP */
    #endif /* USE_OPENMP */

    for( unsigned int each_face_A_idx = 0; each_face_A_idx < m_CoordIndex.size(); each_face_A_idx++ )
    for( unsigned int each_face_A_idx = 0; each_face_A_idx < m_CoordIndex.size(); each_face_A_idx++ )
    {
    {
        // n = face A facet normal
        // n = face A facet normal
@@ -392,13 +389,14 @@ void S3D_MESH::calcPerPointNormals ()
                //if A != B { // ignore self
                //if A != B { // ignore self
                if( each_face_A_idx != each_face_B_idx )
                if( each_face_A_idx != each_face_B_idx )
                {
                {
                    if( (m_CoordIndex[each_face_B_idx][0] == vertexIndex) ||
                    if( (m_CoordIndex[each_face_B_idx][0] == vertexIndex)
                        (m_CoordIndex[each_face_B_idx][1] == vertexIndex) ||
                      || (m_CoordIndex[each_face_B_idx][1] == vertexIndex)
                        (m_CoordIndex[each_face_B_idx][2] == vertexIndex) )
                      || (m_CoordIndex[each_face_B_idx][2] == vertexIndex) )
                    {
                    {
                        glm::vec3 vector_face_B = m_PerFaceNormalsNormalized[each_face_B_idx];
                        glm::vec3 vector_face_B = m_PerFaceNormalsNormalized[each_face_B_idx];


                        float dot_prod = glm::dot( vector_face_A, vector_face_B );
                        float dot_prod = glm::dot( vector_face_A, vector_face_B );

                        if( dot_prod > 0.05f )
                        if( dot_prod > 0.05f )
                        {
                        {
                            face_A_normals[each_vert_A_idx] += m_PerFaceNormalsRaw[each_face_B_idx] * (m_PerFaceSquaredArea[each_face_B_idx] * dot_prod);
                            face_A_normals[each_vert_A_idx] += m_PerFaceNormalsRaw[each_face_B_idx] * (m_PerFaceSquaredArea[each_face_B_idx] * dot_prod);
@@ -411,10 +409,7 @@ void S3D_MESH::calcPerPointNormals ()
            float l = glm::length( face_A_normals[each_vert_A_idx] );
            float l = glm::length( face_A_normals[each_vert_A_idx] );


            if( l > FLT_EPSILON ) // avoid division by zero
            if( l > FLT_EPSILON ) // avoid division by zero
            {
                face_A_normals[each_vert_A_idx] /= l;
                face_A_normals[each_vert_A_idx] /= l;
        }
        }

        }
    }
    }
}
}
+29 −23
Original line number Original line Diff line number Diff line
@@ -2,7 +2,7 @@
 * This program source code file is part of KiCad, a free EDA CAD application.
 * This program source code file is part of KiCad, a free EDA CAD application.
 *
 *
 * Copyright (C) 2013 Tuomas Vaherkoski <tuomasvaherkoski@gmail.com>
 * Copyright (C) 2013 Tuomas Vaherkoski <tuomasvaherkoski@gmail.com>
 * Copyright (C) 1992-2013 KiCad Developers, see AUTHORS.txt for contributors.
 * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
 *
 *
 * This program is free software; you can redistribute it and/or
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * modify it under the terms of the GNU General Public License
@@ -142,6 +142,7 @@ private:
};
};




typedef std::map< std::string, std::vector< glm::vec3 > > VRML2_COORDINATE_MAP;


/**
/**
 * class VRML2_MODEL_PARSER
 * class VRML2_MODEL_PARSER
@@ -165,17 +166,21 @@ public:
private:
private:
    int read_Transform();
    int read_Transform();
    int read_DEF();
    int read_DEF();
    int read_DEF_Coordinate();
    int read_Shape();
    int read_Shape();
    int read_Appearance();
    int read_Appearance();
    int read_material();
    int read_material();
    int read_Material();
    int read_Material();
    int read_IndexedFaceSet();
    int read_IndexedFaceSet();
    int read_IndexedLineSet();
    int read_Coordinate();
    int read_Coordinate();
    int read_CoordinateDef();
    int read_Normal();
    int read_Normal();
    int read_NormalIndex();
    int read_NormalIndex();
    int read_Color();
    int read_Color();
    int read_coordIndex();
    int read_coordIndex();
    int read_colorIndex();
    int read_colorIndex();
    int read_USE();


    bool                      m_normalPerVertex;
    bool                      m_normalPerVertex;
    bool                      colorPerVertex;
    bool                      colorPerVertex;
@@ -184,6 +189,7 @@ private:
    FILE*                     m_file;
    FILE*                     m_file;
    S3D_MATERIAL*             m_Materials;
    S3D_MATERIAL*             m_Materials;
    wxString                  m_Filename;
    wxString                  m_Filename;
    VRML2_COORDINATE_MAP      m_defCoordinateMap;
};
};




+139 −79
Original line number Original line Diff line number Diff line
@@ -5,7 +5,7 @@
 * Copyright (C) 2013 Tuomas Vaherkoski <tuomasvaherkoski@gmail.com>
 * Copyright (C) 2013 Tuomas Vaherkoski <tuomasvaherkoski@gmail.com>
 * Copyright (C) 2012 Jean-Pierre Charras, jp.charras@wanadoo.fr
 * Copyright (C) 2012 Jean-Pierre Charras, jp.charras@wanadoo.fr
 * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
 * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
 * Copyright (C) 1992-2014 KiCad Developers, see AUTHORS.txt for contributors.
 * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
 *
 *
 * This program is free software; you can redistribute it and/or
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * modify it under the terms of the GNU General Public License
@@ -39,6 +39,16 @@
#include "modelparsers.h"
#include "modelparsers.h"
#include "vrml_aux.h"
#include "vrml_aux.h"



/**
 * Trace mask used to enable or disable the trace output of the VRML V2 parser code.
 * The debug output can be turned on by setting the WXTRACE environment variable to
 * "KI_TRACE_VRML_V2_PARSER".  See the wxWidgets documentation on wxLogTrace for
 * more information.
 */
static const wxChar* traceVrmlV2Parser = wxT( "KI_TRACE_VRML_V2_PARSER" );


VRML2_MODEL_PARSER::VRML2_MODEL_PARSER( S3D_MASTER* aMaster ) :
VRML2_MODEL_PARSER::VRML2_MODEL_PARSER( S3D_MASTER* aMaster ) :
    S3D_MODEL_PARSER( aMaster )
    S3D_MODEL_PARSER( aMaster )
{
{
@@ -59,7 +69,7 @@ void VRML2_MODEL_PARSER::Load( const wxString& aFilename, double aVrmlunits_to_3
{
{
    char text[128];
    char text[128];


    // DBG( printf( "Load %s\n", GetChars(aFilename) ) );
    wxLogTrace( traceVrmlV2Parser, wxT( "Load %s" ), GetChars( aFilename ) );
    m_file = wxFopen( aFilename, wxT( "rt" ) );
    m_file = wxFopen( aFilename, wxT( "rt" ) );


    if( m_file == NULL )
    if( m_file == NULL )
@@ -117,9 +127,6 @@ void VRML2_MODEL_PARSER::Load( const wxString& aFilename, double aVrmlunits_to_3


    fclose( m_file );
    fclose( m_file );



    // DBG( printf( "chils size:%lu\n", childs.size() ) );

    if( GetMaster()->IsOpenGlAllowed() )
    if( GetMaster()->IsOpenGlAllowed() )
    {
    {
        for( unsigned int idx = 0; idx < childs.size(); idx++ )
        for( unsigned int idx = 0; idx < childs.size(); idx++ )
@@ -134,8 +141,6 @@ int VRML2_MODEL_PARSER::read_Transform()
{
{
    char text[128];
    char text[128];


    // DBG( printf( "Transform\n" ) );

    while( GetNextTag( m_file, text ) )
    while( GetNextTag( m_file, text ) )
    {
    {
        if( *text == ']' )
        if( *text == ']' )
@@ -145,7 +150,6 @@ int VRML2_MODEL_PARSER::read_Transform()


        if( *text == '}' )
        if( *text == '}' )
        {
        {
            // DBG( printf( "  } Exit Transform\n" ) );
            break;
            break;
        }
        }


@@ -239,7 +243,7 @@ int VRML2_MODEL_PARSER::read_Transform()
        }
        }
        else
        else
        {
        {
            // DBG( printf( "    %s NotImplemented\n", text ) );
            wxLogTrace( traceVrmlV2Parser, wxT( "    %s NotImplemented" ), text );
            read_NotImplemented( m_file, '}' );
            read_NotImplemented( m_file, '}' );
        }
        }
    }
    }
@@ -248,24 +252,56 @@ int VRML2_MODEL_PARSER::read_Transform()
}
}




/**
 * Read the DEF for a Coordinate
 */
int VRML2_MODEL_PARSER::read_DEF_Coordinate()
{
    char text[128];

    // Get the name of the definition.
    GetNextTag( m_file, text );
    std::string coordinateName = text;

    while( GetNextTag( m_file, text ) )
    {
        if( ( text == NULL ) || ( *text == ']' ) )
            continue;

        if( ( *text == '}' ) )
            return 0;

        if( strcmp( text, "Coordinate" ) == 0 )
        {
            int retVal = read_CoordinateDef();

            if( retVal == 0 )
                m_defCoordinateMap.insert( std::make_pair( coordinateName, m_model->m_Point ) );

            return retVal;
        }
    }

    return -1;
}


int VRML2_MODEL_PARSER::read_DEF()
int VRML2_MODEL_PARSER::read_DEF()
{
{
    char text[128];
    char text[128];


    GetNextTag( m_file, text );
    GetNextTag( m_file, text );
    // DBG( printf( "DEF %s ", text ) );


    while( GetNextTag( m_file, text ) )
    while( GetNextTag( m_file, text ) )
    {
    {
        if( *text == ']' )
        if( *text == ']' )
        {
        {
            // DBG( printf( "  skiping %c\n", *text) );
            wxLogTrace( traceVrmlV2Parser, wxT( "  skipping %c" ), *text );
            continue;
            continue;
        }
        }


        if( *text == '}' )
        if( *text == '}' )
        {
        {
            // DBG( printf( "  } Exit DEF\n") );
            return 0;
            return 0;
        }
        }


@@ -301,16 +337,39 @@ int VRML2_MODEL_PARSER::read_DEF()
        }
        }
    }
    }


    // DBG( printf( "  DEF failed\n" ) );
    wxLogTrace( traceVrmlV2Parser, wxT( "  DEF failed" ) );
    return -1;
    return -1;
}
}




int VRML2_MODEL_PARSER::read_Shape()
int VRML2_MODEL_PARSER::read_USE()
{
{
    char text[128];
    char text[128];


    // DBG( printf( "  Shape\n") );
    // Get the name of the definition.
    GetNextTag( m_file, text );
    std::string coordinateName = text;

    // Look for it in our coordinate map.
    VRML2_COORDINATE_MAP::iterator coordinate;
    coordinate = m_defCoordinateMap.find( coordinateName );

    // Not previously defined.
    if( coordinate == m_defCoordinateMap.end() )
    {
        wxLogTrace( traceVrmlV2Parser, wxT( "USE: coordinate %s not previously defined "
                                            "in a DEF section." ), text );
        return -1;
    }

    m_model->m_Point = coordinate->second;
    return 0;
}


int VRML2_MODEL_PARSER::read_Shape()
{
    char text[128];


    while( GetNextTag( m_file, text ) )
    while( GetNextTag( m_file, text ) )
    {
    {
@@ -321,12 +380,12 @@ int VRML2_MODEL_PARSER::read_Shape()


        if( *text == '}' )
        if( *text == '}' )
        {
        {
            // DBG( printf( "  } Exit Shape\n") );
            return 0;
            return 0;
        }
        }


        if( strcmp( text, "appearance" ) == 0 )
        if( strcmp( text, "appearance" ) == 0 )
        {
        {
            wxLogTrace( traceVrmlV2Parser, wxT( "\"appearance\" key word not supported." ) );
            // skip
            // skip
        }
        }
        else if( strcmp( text, "Appearance" ) == 0 )
        else if( strcmp( text, "Appearance" ) == 0 )
@@ -335,20 +394,25 @@ int VRML2_MODEL_PARSER::read_Shape()
        }
        }
        else if( strcmp( text, "geometry" ) == 0 )
        else if( strcmp( text, "geometry" ) == 0 )
        {
        {
            wxLogTrace( traceVrmlV2Parser, wxT( "\"geometry\" key word not supported." ) );
            // skip
            // skip
        }
        }
        else if( strcmp( text, "IndexedFaceSet" ) == 0 )
        else if( strcmp( text, "IndexedFaceSet" ) == 0 )
        {
        {
            read_IndexedFaceSet();
            read_IndexedFaceSet();
        }
        }
        else if( strcmp( text, "IndexedLineSet" ) == 0 )
        {
            read_IndexedLineSet();
        }
        else
        else
        {
        {
            // DBG( printf( "    %s NotImplemented\n", text ) );
            wxLogTrace( traceVrmlV2Parser, wxT( "    %s NotImplemented" ), text );
            read_NotImplemented( m_file, '}' );
            read_NotImplemented( m_file, '}' );
        }
        }
    }
    }


    // DBG( printf( "  Shape failed\n" ) );
    wxLogTrace( traceVrmlV2Parser, wxT( "  Shape failed" ) );
    return -1;
    return -1;
}
}


@@ -357,8 +421,6 @@ int VRML2_MODEL_PARSER::read_Appearance()
{
{
    char text[128];
    char text[128];


    // DBG( printf( "  Appearance\n") );

    while( GetNextTag( m_file, text ) )
    while( GetNextTag( m_file, text ) )
    {
    {
        if( *text == ']' )
        if( *text == ']' )
@@ -377,7 +439,7 @@ int VRML2_MODEL_PARSER::read_Appearance()
        }
        }
    }
    }


    // DBG( printf( "  Appearance failed\n" ) );
    wxLogTrace( traceVrmlV2Parser, wxT( "  Appearance failed" ) );
    return -1;
    return -1;
}
}


@@ -387,8 +449,6 @@ int VRML2_MODEL_PARSER::read_material()
    S3D_MATERIAL* material = NULL;
    S3D_MATERIAL* material = NULL;
    char text[128];
    char text[128];


    // DBG( printf( "  material ") );

    if( GetNextTag( m_file, text ) )
    if( GetNextTag( m_file, text ) )
    {
    {
        if( strcmp( text, "Material" ) == 0 )
        if( strcmp( text, "Material" ) == 0 )
@@ -405,12 +465,8 @@ int VRML2_MODEL_PARSER::read_material()
        }
        }
        else if( strcmp( text, "DEF" ) == 0 )
        else if( strcmp( text, "DEF" ) == 0 )
        {
        {
            // DBG( printf( "DEF") );

            if( GetNextTag( m_file, text ) )
            if( GetNextTag( m_file, text ) )
            {
            {
                // DBG( printf( "%s", text ) );

                wxString mat_name;
                wxString mat_name;
                mat_name = FROM_UTF8( text );
                mat_name = FROM_UTF8( text );


@@ -429,12 +485,8 @@ int VRML2_MODEL_PARSER::read_material()
        }
        }
        else if( strcmp( text, "USE" ) == 0 )
        else if( strcmp( text, "USE" ) == 0 )
        {
        {
            // DBG( printf( "USE") );

            if( GetNextTag( m_file, text ) )
            if( GetNextTag( m_file, text ) )
            {
            {
                // DBG( printf( "%s\n", text ) );

                wxString mat_name;
                wxString mat_name;
                mat_name = FROM_UTF8( text );
                mat_name = FROM_UTF8( text );


@@ -447,12 +499,12 @@ int VRML2_MODEL_PARSER::read_material()
                    }
                    }
                }
                }


                DBG( printf( "   read_material error: material not found\n" ) );
                wxLogTrace( traceVrmlV2Parser, wxT( "   read_material error: material not found" ) );
            }
            }
        }
        }
    }
    }


    // DBG( printf( "  failed material\n" ) );
    wxLogTrace( traceVrmlV2Parser, wxT( "  failed material" ) );
    return -1;
    return -1;
}
}


@@ -462,8 +514,6 @@ int VRML2_MODEL_PARSER::read_Material()
    char text[128];
    char text[128];
    glm::vec3 vertex;
    glm::vec3 vertex;


    // DBG( printf( "  Material\n") );

    while( GetNextTag( m_file, text ) )
    while( GetNextTag( m_file, text ) )
    {
    {
        if( *text == ']' )
        if( *text == ']' )
@@ -478,17 +528,13 @@ int VRML2_MODEL_PARSER::read_Material()


        if( strcmp( text, "diffuseColor" ) == 0 )
        if( strcmp( text, "diffuseColor" ) == 0 )
        {
        {
            // DBG( printf( "  diffuseColor") );
            parseVertex( m_file, vertex );
            parseVertex( m_file, vertex );
            // DBG( printf( "\n") );
            m_model->m_Materials->m_DiffuseColor.push_back( vertex );
            m_model->m_Materials->m_DiffuseColor.push_back( vertex );
        }
        }
        else if( strcmp( text, "emissiveColor" ) == 0 )
        else if( strcmp( text, "emissiveColor" ) == 0 )
        {
        {
            // DBG( printf( "  emissiveColor") );
            parseVertex( m_file, vertex );
            parseVertex( m_file, vertex );


            // DBG( printf( "\n") );
            if( GetMaster()->m_use_modelfile_emissiveColor == true )
            if( GetMaster()->m_use_modelfile_emissiveColor == true )
            {
            {
                m_model->m_Materials->m_EmissiveColor.push_back( vertex );
                m_model->m_Materials->m_EmissiveColor.push_back( vertex );
@@ -496,9 +542,7 @@ int VRML2_MODEL_PARSER::read_Material()
        }
        }
        else if( strcmp( text, "specularColor" ) == 0 )
        else if( strcmp( text, "specularColor" ) == 0 )
        {
        {
            // DBG( printf( "  specularColor") );
            parseVertex( m_file, vertex );
            parseVertex( m_file, vertex );
            // DBG( printf( "\n") );


            if( GetMaster()->m_use_modelfile_specularColor == true )
            if( GetMaster()->m_use_modelfile_specularColor == true )
            {
            {
@@ -509,7 +553,6 @@ int VRML2_MODEL_PARSER::read_Material()
        {
        {
            float ambientIntensity;
            float ambientIntensity;
            parseFloat( m_file, &ambientIntensity );
            parseFloat( m_file, &ambientIntensity );
            // DBG( printf( "  ambientIntensity %f\n", ambientIntensity) );


            if( GetMaster()->m_use_modelfile_ambientIntensity == true )
            if( GetMaster()->m_use_modelfile_ambientIntensity == true )
            {
            {
@@ -521,7 +564,6 @@ int VRML2_MODEL_PARSER::read_Material()
        {
        {
            float transparency;
            float transparency;
            parseFloat( m_file, &transparency );
            parseFloat( m_file, &transparency );
            // DBG( printf( "  transparency %f\n", transparency) );


            if( GetMaster()->m_use_modelfile_transparency == true )
            if( GetMaster()->m_use_modelfile_transparency == true )
            {
            {
@@ -533,7 +575,6 @@ int VRML2_MODEL_PARSER::read_Material()
            float shininess;
            float shininess;
            parseFloat( m_file, &shininess );
            parseFloat( m_file, &shininess );


            // DBG( printf( "  shininess %f\n", shininess) );
            // VRML value is normalized and openGL expects a value 0 - 128
            // VRML value is normalized and openGL expects a value 0 - 128
            if( GetMaster()->m_use_modelfile_shininess == true )
            if( GetMaster()->m_use_modelfile_shininess == true )
            {
            {
@@ -543,7 +584,7 @@ int VRML2_MODEL_PARSER::read_Material()
        }
        }
    }
    }


    // DBG( printf( "  Material failed\n" ) );
    wxLogTrace( traceVrmlV2Parser, wxT( "  Material failed\n" ) );
    return -1;
    return -1;
}
}


@@ -552,8 +593,6 @@ int VRML2_MODEL_PARSER::read_IndexedFaceSet()
{
{
    char text[128];
    char text[128];


    // DBG( printf( "  IndexedFaceSet\n") );

    m_normalPerVertex = false;
    m_normalPerVertex = false;
    colorPerVertex = false;
    colorPerVertex = false;


@@ -566,7 +605,6 @@ int VRML2_MODEL_PARSER::read_IndexedFaceSet()


        if( *text == '}' )
        if( *text == '}' )
        {
        {
            // DBG( printf( "  } Exit IndexedFaceSet\n") );
            return 0;
            return 0;
        }
        }


@@ -576,7 +614,6 @@ int VRML2_MODEL_PARSER::read_IndexedFaceSet()
            {
            {
                if( strcmp( text, "TRUE" ) == 0 )
                if( strcmp( text, "TRUE" ) == 0 )
                {
                {
                    // DBG( printf( "  m_normalPerVertex TRUE\n") );
                    m_normalPerVertex = true;
                    m_normalPerVertex = true;
                }
                }
            }
            }
@@ -587,7 +624,6 @@ int VRML2_MODEL_PARSER::read_IndexedFaceSet()


            if( strcmp( text, "TRUE" ) )
            if( strcmp( text, "TRUE" ) )
            {
            {
                // DBG( printf( "  colorPerVertex = true\n") );
                colorPerVertex = true;
                colorPerVertex = true;
            }
            }
            else
            else
@@ -619,17 +655,43 @@ int VRML2_MODEL_PARSER::read_IndexedFaceSet()
        {
        {
            read_colorIndex();
            read_colorIndex();
        }
        }
        else if( strcmp( text, "USE" ) == 0 )
        {
            read_USE();
        }
    }
    }


    // DBG( printf( "  IndexedFaceSet failed %s\n", text ) );
    wxLogTrace( traceVrmlV2Parser, wxT( "  IndexedFaceSet failed %s" ), text );
    return -1;
    return -1;
}
}




int VRML2_MODEL_PARSER::read_colorIndex()
int VRML2_MODEL_PARSER::read_IndexedLineSet()
{
    char text[128];

    while( GetNextTag( m_file, text ) )
    {
    {
    // DBG( printf( "    read_colorIndex\n" ) );
        if( ( text == NULL ) || ( *text == ']' ) )
            continue;


        if( ( *text == '}' ) )
            return 0;

        if( strcmp( text, "Coordinate" ) == 0 )
            read_Coordinate();
        else if( strcmp( text, "coordIndex" ) == 0 )
            read_coordIndex();
        else if( strcmp( text, "DEF" ) == 0 )
            read_DEF_Coordinate();
    }

    return -1;
}


int VRML2_MODEL_PARSER::read_colorIndex()
{
    m_model->m_MaterialIndex.clear();
    m_model->m_MaterialIndex.clear();


    if( colorPerVertex == true )
    if( colorPerVertex == true )
@@ -660,16 +722,12 @@ int VRML2_MODEL_PARSER::read_colorIndex()
        }
        }
    }
    }


    // DBG( printf( "    m_MaterialIndex.size: %ld\n", m_model->m_MaterialIndex.size() ) );

    return 0;
    return 0;
}
}




int VRML2_MODEL_PARSER::read_NormalIndex()
int VRML2_MODEL_PARSER::read_NormalIndex()
{
{
    // DBG( printf( "    read_NormalIndex\n" ) );

    m_model->m_NormalIndex.clear();
    m_model->m_NormalIndex.clear();


    glm::ivec3 coord;
    glm::ivec3 coord;
@@ -684,26 +742,20 @@ int VRML2_MODEL_PARSER::read_NormalIndex()
        if( dummy == -1 )
        if( dummy == -1 )
        {
        {
            m_model->m_NormalIndex.push_back( coord_list );
            m_model->m_NormalIndex.push_back( coord_list );
            // DBG( printf( " size: %lu ", coord_list.size()) );
            coord_list.clear();
            coord_list.clear();
        }
        }
        else
        else
        {
        {
            coord_list.push_back( dummy );
            coord_list.push_back( dummy );
            // DBG( printf( "%d ", dummy) );
        }
        }
    }
    }


    // DBG( printf( "    m_NormalIndex.size: %ld\n", m_model->m_NormalIndex.size() ) );

    return 0;
    return 0;
}
}




int VRML2_MODEL_PARSER::read_coordIndex()
int VRML2_MODEL_PARSER::read_coordIndex()
{
{
    // DBG( printf( "    read_coordIndex\n" ) );

    m_model->m_CoordIndex.clear();
    m_model->m_CoordIndex.clear();


    glm::ivec3 coord;
    glm::ivec3 coord;
@@ -718,18 +770,14 @@ int VRML2_MODEL_PARSER::read_coordIndex()
        if( dummy == -1 )
        if( dummy == -1 )
        {
        {
            m_model->m_CoordIndex.push_back( coord_list );
            m_model->m_CoordIndex.push_back( coord_list );
            // DBG( printf( " size: %lu ", coord_list.size()) );
            coord_list.clear();
            coord_list.clear();
        }
        }
        else
        else
        {
        {
            coord_list.push_back( dummy );
            coord_list.push_back( dummy );
            // DBG( printf( "%d ", dummy) );
        }
        }
    }
    }


    // DBG( printf( "    m_CoordIndex.size: %ld\n", m_model->m_CoordIndex.size() ) );

    return 0;
    return 0;
}
}


@@ -738,8 +786,6 @@ int VRML2_MODEL_PARSER::read_Color()
{
{
    char text[128];
    char text[128];


    // DBG( printf( "  read_Color\n") );

    while( GetNextTag( m_file, text ) )
    while( GetNextTag( m_file, text ) )
    {
    {
        if( *text == ']' )
        if( *text == ']' )
@@ -749,7 +795,6 @@ int VRML2_MODEL_PARSER::read_Color()


        if( *text == '}' )
        if( *text == '}' )
        {
        {
            // DBG( printf( "    m_DiffuseColor.size: %ld\n", m_model->m_Materials->m_DiffuseColor.size() ) );
            return 0;
            return 0;
        }
        }


@@ -759,7 +804,7 @@ int VRML2_MODEL_PARSER::read_Color()
        }
        }
    }
    }


    // DBG( printf( "  read_Color failed\n") );
    wxLogTrace( traceVrmlV2Parser, wxT( "  read_Color failed" ) );
    return -1;
    return -1;
}
}


@@ -768,8 +813,6 @@ int VRML2_MODEL_PARSER::read_Normal()
{
{
    char text[128];
    char text[128];


    // DBG( printf( "  Normal\n") );

    while( GetNextTag( m_file, text ) )
    while( GetNextTag( m_file, text ) )
    {
    {
        if( *text == ']' )
        if( *text == ']' )
@@ -779,7 +822,6 @@ int VRML2_MODEL_PARSER::read_Normal()


        if( *text == '}' )
        if( *text == '}' )
        {
        {
            // DBG( printf( "    m_PerFaceNormalsNormalized.size: %lu\n", m_model->m_PerFaceNormalsNormalized.size() ) );
            return 0;
            return 0;
        }
        }


@@ -792,8 +834,6 @@ int VRML2_MODEL_PARSER::read_Normal()
            else
            else
            {
            {
                parseVertexList( m_file, m_model->m_PerVertexNormalsNormalized );
                parseVertexList( m_file, m_model->m_PerVertexNormalsNormalized );

                // DBG( printf( "    m_PerVertexNormalsNormalized.size: %lu\n", m_model->m_PerVertexNormalsNormalized.size() ) );
            }
            }
        }
        }
    }
    }
@@ -806,8 +846,6 @@ int VRML2_MODEL_PARSER::read_Coordinate()
{
{
    char text[128];
    char text[128];


    // DBG( printf( "  Coordinate\n") );

    while( GetNextTag( m_file, text ) )
    while( GetNextTag( m_file, text ) )
    {
    {
        if( *text == ']' )
        if( *text == ']' )
@@ -817,7 +855,6 @@ int VRML2_MODEL_PARSER::read_Coordinate()


        if( *text == '}' )
        if( *text == '}' )
        {
        {
            // DBG( printf( "    m_Point.size: %lu\n", m_model->m_Point.size() ) );
            return 0;
            return 0;
        }
        }


@@ -829,3 +866,26 @@ int VRML2_MODEL_PARSER::read_Coordinate()


    return -1;
    return -1;
}
}


/**
 * Read the point of the Coordinate for a DEF
 */
int VRML2_MODEL_PARSER::read_CoordinateDef()
{
    char text[128];

    while( GetNextTag( m_file, text ) )
    {
        if( ( text == NULL ) || ( *text == ']' ) )
            continue;

        if( ( *text == '}' ) )
            return 0;

        if( strcmp( text, "point" ) == 0 )
            parseVertexList( m_file, m_model->m_Point );
    }

    return -1;
}