Loading 3d-viewer/3d_mesh_model.cpp +59 −64 Original line number Original line Diff line number Diff line Loading @@ -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 Loading Loading @@ -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") ); Loading @@ -82,7 +83,6 @@ void S3D_MESH::openGL_RenderAllChilds() SetOpenGlDefaultMaterial(); SetOpenGlDefaultMaterial(); glPopMatrix(); glPopMatrix(); } } Loading @@ -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 ); Loading @@ -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; } } Loading Loading @@ -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; Loading Loading @@ -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(); Loading @@ -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]]; Loading Loading @@ -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 ); Loading @@ -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 ); Loading @@ -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() Loading @@ -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(); Loading @@ -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 Loading @@ -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); Loading @@ -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; } } } } } } } 3d-viewer/modelparsers.h +29 −23 Original line number Original line Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 Loading @@ -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; Loading @@ -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; }; }; Loading 3d-viewer/vrml_v2_modelparser.cpp +139 −79 Original line number Original line Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 ) { { Loading @@ -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 ) Loading Loading @@ -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++ ) Loading @@ -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 == ']' ) Loading @@ -145,7 +150,6 @@ int VRML2_MODEL_PARSER::read_Transform() if( *text == '}' ) if( *text == '}' ) { { // DBG( printf( " } Exit Transform\n" ) ); break; break; } } Loading Loading @@ -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, '}' ); } } } } Loading @@ -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; } } Loading Loading @@ -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 ) ) { { Loading @@ -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 ) Loading @@ -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; } } Loading @@ -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 == ']' ) Loading @@ -377,7 +439,7 @@ int VRML2_MODEL_PARSER::read_Appearance() } } } } // DBG( printf( " Appearance failed\n" ) ); wxLogTrace( traceVrmlV2Parser, wxT( " Appearance failed" ) ); return -1; return -1; } } Loading @@ -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 ) Loading @@ -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 ); Loading @@ -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 ); Loading @@ -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; } } Loading @@ -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 == ']' ) Loading @@ -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 ); Loading @@ -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 ) { { Loading @@ -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 ) { { Loading @@ -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 ) { { Loading @@ -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 ) { { Loading @@ -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; } } Loading @@ -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; Loading @@ -566,7 +605,6 @@ int VRML2_MODEL_PARSER::read_IndexedFaceSet() if( *text == '}' ) if( *text == '}' ) { { // DBG( printf( " } Exit IndexedFaceSet\n") ); return 0; return 0; } } Loading @@ -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; } } } } Loading @@ -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 Loading Loading @@ -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 ) Loading Loading @@ -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; Loading @@ -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; Loading @@ -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; } } Loading @@ -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 == ']' ) Loading @@ -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; } } Loading @@ -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; } } Loading @@ -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 == ']' ) Loading @@ -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; } } Loading @@ -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() ) ); } } } } } } Loading @@ -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 == ']' ) Loading @@ -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; } } Loading @@ -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; } Loading
3d-viewer/3d_mesh_model.cpp +59 −64 Original line number Original line Diff line number Diff line Loading @@ -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 Loading Loading @@ -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") ); Loading @@ -82,7 +83,6 @@ void S3D_MESH::openGL_RenderAllChilds() SetOpenGlDefaultMaterial(); SetOpenGlDefaultMaterial(); glPopMatrix(); glPopMatrix(); } } Loading @@ -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 ); Loading @@ -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; } } Loading Loading @@ -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; Loading Loading @@ -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(); Loading @@ -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]]; Loading Loading @@ -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 ); Loading @@ -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 ); Loading @@ -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() Loading @@ -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(); Loading @@ -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 Loading @@ -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); Loading @@ -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; } } } } } } }
3d-viewer/modelparsers.h +29 −23 Original line number Original line Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 Loading @@ -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; Loading @@ -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; }; }; Loading
3d-viewer/vrml_v2_modelparser.cpp +139 −79 Original line number Original line Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 ) { { Loading @@ -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 ) Loading Loading @@ -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++ ) Loading @@ -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 == ']' ) Loading @@ -145,7 +150,6 @@ int VRML2_MODEL_PARSER::read_Transform() if( *text == '}' ) if( *text == '}' ) { { // DBG( printf( " } Exit Transform\n" ) ); break; break; } } Loading Loading @@ -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, '}' ); } } } } Loading @@ -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; } } Loading Loading @@ -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 ) ) { { Loading @@ -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 ) Loading @@ -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; } } Loading @@ -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 == ']' ) Loading @@ -377,7 +439,7 @@ int VRML2_MODEL_PARSER::read_Appearance() } } } } // DBG( printf( " Appearance failed\n" ) ); wxLogTrace( traceVrmlV2Parser, wxT( " Appearance failed" ) ); return -1; return -1; } } Loading @@ -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 ) Loading @@ -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 ); Loading @@ -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 ); Loading @@ -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; } } Loading @@ -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 == ']' ) Loading @@ -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 ); Loading @@ -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 ) { { Loading @@ -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 ) { { Loading @@ -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 ) { { Loading @@ -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 ) { { Loading @@ -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; } } Loading @@ -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; Loading @@ -566,7 +605,6 @@ int VRML2_MODEL_PARSER::read_IndexedFaceSet() if( *text == '}' ) if( *text == '}' ) { { // DBG( printf( " } Exit IndexedFaceSet\n") ); return 0; return 0; } } Loading @@ -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; } } } } Loading @@ -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 Loading Loading @@ -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 ) Loading Loading @@ -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; Loading @@ -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; Loading @@ -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; } } Loading @@ -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 == ']' ) Loading @@ -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; } } Loading @@ -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; } } Loading @@ -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 == ']' ) Loading @@ -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; } } Loading @@ -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() ) ); } } } } } } Loading @@ -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 == ']' ) Loading @@ -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; } } Loading @@ -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; }