|
|
/*
* This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2014 Mario Luzeiro <mrluzeiro@gmail.com> * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, you may find one here: * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
/**
* @file vrml_v1_modelparser.cpp */
#include <fctsys.h>
#include <vector>
#include <macros.h>
#include <kicad_string.h>
#include <info3d_visu.h>
#include "3d_struct.h"
#include "modelparsers.h"
#include "vrml_aux.h"
#define BUFLINE_SIZE 32
/**
* Trace mask used to enable or disable the trace output of the VRML V1 parser code. * The debug output can be turned on by setting the WXTRACE environment variable to * "KI_TRACE_VRML_V1_PARSER". See the wxWidgets documentation on wxLogTrace for * more information. */static const wxChar* traceVrmlV1Parser = wxT( "KI_TRACE_VRML_V1_PARSER" );
VRML1_MODEL_PARSER::VRML1_MODEL_PARSER( S3D_MODEL_PARSER* aModelParser ){ m_ModelParser = aModelParser; m_Master = m_ModelParser->GetMaster(); m_model.reset(); m_file = NULL; m_normalPerVertex = true; colorPerVertex = true;}
VRML1_MODEL_PARSER::~VRML1_MODEL_PARSER(){}
bool VRML1_MODEL_PARSER::Load( const wxString& aFilename ){ char text[BUFLINE_SIZE];
wxLogTrace( traceVrmlV1Parser, wxT( "Loading: %s" ), GetChars( aFilename ) );
m_file = wxFopen( aFilename, wxT( "rt" ) );
if( m_file == NULL ) return false;
// Switch the locale to standard C (needed to print floating point numbers)
LOCALE_IO toggle;
m_ModelParser->childs.clear();
while( GetNextTag( m_file, text, sizeof(text) ) ) { if( ( *text == '}' ) || ( *text == ']' ) ) { continue; }
if( strcmp( text, "Separator" ) == 0 ) { m_model.reset( new S3D_MESH() ); m_ModelParser->childs.push_back( m_model ); read_separator(); } }
fclose( m_file );
return true;}
int VRML1_MODEL_PARSER::read_separator(){ char text[BUFLINE_SIZE];
// DBG( printf( "Separator\n" ) );
while( GetNextTag( m_file, text, sizeof(text) ) ) { if( strcmp( text, "Material" ) == 0 ) { readMaterial(); } else if( strcmp( text, "Coordinate3" ) == 0 ) { readCoordinate3(); } else if( strcmp( text, "IndexedFaceSet" ) == 0 ) { readIndexedFaceSet(); } else if( strcmp( text, "Separator" ) == 0 ) { S3D_MESH_PTR parent( m_model.get() );
S3D_MESH_PTR new_mesh_model( new S3D_MESH() );
m_model->childs.push_back( new_mesh_model );
m_model.reset( new_mesh_model.get() );
// recursive
read_separator();
m_model.reset( parent.get() ); } else if( ( *text != '}' ) ) { // DBG( printf( "read_NotImplemented %s\n", text ) );
Read_NotImplemented( m_file, '}' ); } else break; }
return 0;}
int VRML1_MODEL_PARSER::readMaterial(){ char text[BUFLINE_SIZE]; S3D_MATERIAL* material = NULL;
// DBG( printf( " readMaterial\n" ) );
wxString mat_name;
material = new S3D_MATERIAL( m_Master, mat_name );
m_Master->Insert( material );
m_model->m_Materials = material;
while( GetNextTag( m_file, text, sizeof(text) ) ) { if( *text == ']' ) { continue; }
if( *text == '}' ) { return 0; }
if( strcmp( text, "ambientColor" ) == 0 ) { readMaterial_ambientColor(); } else if( strcmp( text, "diffuseColor" ) == 0 ) { readMaterial_diffuseColor(); } else if( strcmp( text, "emissiveColor" ) == 0 ) { readMaterial_emissiveColor(); } else if( strcmp( text, "specularColor" ) == 0 ) { readMaterial_specularColor(); } else if( strcmp( text, "shininess" ) == 0 ) { readMaterial_shininess(); } else if( strcmp( text, "transparency" ) == 0 ) { readMaterial_transparency(); } }
wxLogTrace( traceVrmlV1Parser, wxT( " readMaterial failed" ) ); return -1;}
int VRML1_MODEL_PARSER::readCoordinate3(){ char text[BUFLINE_SIZE];
// DBG( printf( " readCoordinate3\n" ) );
while( GetNextTag( m_file, text, sizeof( text ) ) ) { if( *text == ']' ) { continue; }
if( *text == '}' ) { return 0; }
if( strcmp( text, "point" ) == 0 ) { readCoordinate3_point(); } }
wxLogTrace( traceVrmlV1Parser, wxT( " readCoordinate3 failed" ) ); return -1;}
int VRML1_MODEL_PARSER::readIndexedFaceSet(){ char text[BUFLINE_SIZE];
// DBG( printf( " readIndexedFaceSet\n" ) );
while( GetNextTag( m_file, text, sizeof(text) ) ) { if( *text == ']' ) { continue; }
if( *text == '}' ) { return 0; }
if( strcmp( text, "coordIndex" ) == 0 ) { readIndexedFaceSet_coordIndex(); } else if( strcmp( text, "materialIndex" ) == 0 ) { readIndexedFaceSet_materialIndex(); } }
wxLogTrace( traceVrmlV1Parser, wxT( " readIndexedFaceSet failed" ) ); return -1;}
int VRML1_MODEL_PARSER::readMaterial_ambientColor(){ // DBG( printf( " readMaterial_ambientColor\n" ) );
return ParseVertexList( m_file, m_model->m_Materials->m_AmbientColor );}
int VRML1_MODEL_PARSER::readMaterial_diffuseColor(){ // DBG( printf( " readMaterial_diffuseColor\n" ) );
return ParseVertexList( m_file, m_model->m_Materials->m_DiffuseColor );}
int VRML1_MODEL_PARSER::readMaterial_emissiveColor(){ // DBG( printf( " readMaterial_emissiveColor\n" ) );
int ret = ParseVertexList( m_file, m_model->m_Materials->m_EmissiveColor );
if( m_Master->m_use_modelfile_emissiveColor == false ) { m_model->m_Materials->m_EmissiveColor.clear(); }
return ret;}
int VRML1_MODEL_PARSER::readMaterial_specularColor(){ // DBG( printf( " readMaterial_specularColor\n" ) );
int ret = ParseVertexList( m_file, m_model->m_Materials->m_SpecularColor );
if( m_Master->m_use_modelfile_specularColor == false ) { m_model->m_Materials->m_SpecularColor.clear(); }
return ret;}
int VRML1_MODEL_PARSER::readMaterial_shininess(){ // DBG( printf( " readMaterial_shininess\n" ) );
m_model->m_Materials->m_Shininess.clear();
float shininess_value;
while( fscanf( m_file, "%f,", &shininess_value ) ) { // VRML value is normalized and openGL expects a value 0 - 128
shininess_value = shininess_value * 128.0f; m_model->m_Materials->m_Shininess.push_back( shininess_value ); }
if( m_Master->m_use_modelfile_shininess == false ) { m_model->m_Materials->m_Shininess.clear(); }
// DBG( printf( " m_Shininess.size: %ld\n", m_model->m_Materials->m_Shininess.size() ) );
return 0;}
int VRML1_MODEL_PARSER::readMaterial_transparency(){ // DBG( printf( " readMaterial_transparency\n" ) );
m_model->m_Materials->m_Transparency.clear();
float tmp;
while( fscanf( m_file, "%f,", &tmp ) ) { m_model->m_Materials->m_Transparency.push_back( tmp ); }
if( m_Master->m_use_modelfile_transparency == false ) { m_model->m_Materials->m_Transparency.clear(); }
// DBG( printf( " m_Transparency.size: %ld\n", m_model->m_Materials->m_Transparency.size() ) );
return 0;}
int VRML1_MODEL_PARSER::readCoordinate3_point(){ // DBG( printf( " readCoordinate3_point\n" ) );
if( ParseVertexList( m_file, m_model->m_Point ) == 0 ) { return 0; }
wxLogTrace( traceVrmlV1Parser, wxT( " readCoordinate3_point failed" ) ); return -1;}
int VRML1_MODEL_PARSER::readIndexedFaceSet_coordIndex(){ // DBG( printf( " readIndexedFaceSet_coordIndex\n" ) );
m_model->m_CoordIndex.clear();
glm::ivec3 coord;
int dummy; // should be -1
while( fscanf( m_file, "%d,%d,%d,%d,", &coord[0], &coord[1], &coord[2], &dummy ) ) { std::vector<int> coord_list;
coord_list.resize( 3 ); coord_list[0] = coord[0]; coord_list[1] = coord[1]; coord_list[2] = coord[2];
if( (coord[0] == coord[1]) || (coord[0] == coord[2]) || (coord[2] == coord[1]) ) { wxLogTrace( traceVrmlV1Parser, wxT( " invalid coordIndex at index %zu (%d, %d, %d, %d)" ), m_model->m_CoordIndex.size() + 1, coord[0], coord[1], coord[2], dummy ); }
if( dummy != -1 ) { wxLogTrace( traceVrmlV1Parser, wxT( " Error at index %zu, -1 Expected, got %d" ), m_model->m_CoordIndex.size() + 1, dummy ); }
m_model->m_CoordIndex.push_back( coord_list ); }
// DBG( printf( " m_CoordIndex.size: %ld\n", m_model->m_CoordIndex.size() ) );
return 0;}
int VRML1_MODEL_PARSER::readIndexedFaceSet_materialIndex(){ // DBG( printf( " readIndexedFaceSet_materialIndex\n" ) );
m_model->m_MaterialIndexPerFace.clear();
int index;
while( fscanf( m_file, "%d,", &index ) ) { m_model->m_MaterialIndexPerFace.push_back( index ); }
// DBG( printf( " m_MaterialIndexPerFace.size: %ld\n", m_model->m_MaterialIndexPerFace.size() ) );
return 0;}
|