mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-09-14 18:23:15 +02:00
3dviewer: back to double (from float) in class S3D_MASTER for 3 members (m_MatScale, m_MatRotation, m_MatPosition) which are used in dialogs and r/w file functions, which expect double. Using float create minor but unwanted issues in r/w file functions. S3D_MATERIAL: enable all color options: if a 3d shape has bad color parameters, the shape must be modified, not the 3d rendering. The rendering now matches what we see in other vrml viewer like FreeCAD. Some minor coding style fixes.
456 lines
11 KiB
C++
456 lines
11 KiB
C++
/*
|
|
* 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-2014 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"
|
|
|
|
VRML1_MODEL_PARSER::VRML1_MODEL_PARSER( S3D_MASTER* aMaster ) :
|
|
S3D_MODEL_PARSER( aMaster )
|
|
{
|
|
m_model = NULL;
|
|
m_file = NULL;
|
|
}
|
|
|
|
|
|
VRML1_MODEL_PARSER::~VRML1_MODEL_PARSER()
|
|
{
|
|
for( unsigned int idx = 0; idx < childs.size(); idx++ )
|
|
{
|
|
delete childs[idx];
|
|
}
|
|
}
|
|
|
|
|
|
void VRML1_MODEL_PARSER::Load( const wxString aFilename )
|
|
{
|
|
char text[128];
|
|
|
|
//DBG( printf( "Load %s\n", static_cast<const char*>(aFilename.mb_str()) ) );
|
|
m_file = wxFopen( aFilename, wxT( "rt" ) );
|
|
|
|
if( m_file == NULL )
|
|
{
|
|
return;
|
|
}
|
|
|
|
glShadeModel( GL_SMOOTH );
|
|
glEnable( GL_NORMALIZE );
|
|
|
|
float vrmlunits_to_3Dunits = g_Parm_3D_Visu.m_BiuTo3Dunits * UNITS3D_TO_UNITSPCB;
|
|
glScalef( vrmlunits_to_3Dunits, vrmlunits_to_3Dunits, vrmlunits_to_3Dunits );
|
|
|
|
glm::vec3 matScale( GetMaster()->m_MatScale.x, GetMaster()->m_MatScale.y, GetMaster()->m_MatScale.z );
|
|
glm::vec3 matRot( GetMaster()->m_MatRotation.x, GetMaster()->m_MatRotation.y, GetMaster()->m_MatRotation.z );
|
|
glm::vec3 matPos( GetMaster()->m_MatPosition.x, GetMaster()->m_MatPosition.y, GetMaster()->m_MatPosition.z );
|
|
|
|
|
|
#define SCALE_3D_CONV ((IU_PER_MILS * 1000.0f) / UNITS3D_TO_UNITSPCB)
|
|
|
|
//glPushMatrix();
|
|
glTranslatef( matPos.x * SCALE_3D_CONV, matPos.y * SCALE_3D_CONV, matPos.z * SCALE_3D_CONV );
|
|
|
|
glRotatef(-matRot.z, 0.0f, 0.0f, 1.0f );
|
|
glRotatef(-matRot.y, 0.0f, 1.0f, 0.0f );
|
|
glRotatef(-matRot.x, 1.0f, 0.0f, 0.0f );
|
|
|
|
glScalef( matScale.x, matScale.y, matScale.z );
|
|
|
|
// Switch the locale to standard C (needed to print floating point numbers like 1.3)
|
|
SetLocaleTo_C_standard();
|
|
|
|
childs.clear();
|
|
|
|
while( GetNextTag( m_file, text ) )
|
|
{
|
|
|
|
if ( ( text == NULL ) || ( *text == '}' ) || ( *text == ']' ) )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if( strcmp( text, "Separator" ) == 0 )
|
|
{
|
|
m_model = new S3D_MESH();
|
|
childs.push_back( m_model );
|
|
read_separator();
|
|
}
|
|
}
|
|
|
|
fclose( m_file );
|
|
SetLocaleTo_Default(); // revert to the current locale
|
|
|
|
|
|
//DBG( printf( "chils size:%lu\n", childs.size() ) );
|
|
|
|
if( GetMaster()->IsOpenGlAllowed() )
|
|
{
|
|
for( unsigned int idx = 0; idx < childs.size(); idx++ )
|
|
{
|
|
childs[idx]->openGL_RenderAllChilds();
|
|
}
|
|
}
|
|
}
|
|
|
|
int VRML1_MODEL_PARSER::read_separator()
|
|
{
|
|
char text[128];
|
|
|
|
//DBG( printf( "Separator\n" ) );
|
|
|
|
while( GetNextTag( m_file, 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 *parent = m_model;
|
|
|
|
S3D_MESH *new_mesh_model = new S3D_MESH();
|
|
|
|
m_model->childs.push_back( new_mesh_model );
|
|
|
|
m_model = new_mesh_model;
|
|
|
|
// recursive
|
|
read_separator();
|
|
|
|
m_model = parent;
|
|
}
|
|
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[128];
|
|
S3D_MATERIAL* material = NULL;
|
|
|
|
//DBG( printf( " readMaterial\n" ) );
|
|
|
|
wxString mat_name;
|
|
|
|
material = new S3D_MATERIAL( GetMaster(), mat_name );
|
|
|
|
GetMaster()->Insert( material );
|
|
|
|
m_model->m_Materials = material;
|
|
|
|
while( GetNextTag( m_file, text ) )
|
|
{
|
|
if ( ( text == NULL ) || ( *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( );
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
|
|
int VRML1_MODEL_PARSER::readCoordinate3( )
|
|
{
|
|
char text[128];
|
|
|
|
//DBG( printf( " readCoordinate3\n" ) );
|
|
|
|
while( GetNextTag( m_file, text ) )
|
|
{
|
|
if ( ( text == NULL ) || ( *text == ']' ) )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if ( ( *text == '}' ) )
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if( strcmp( text, "point" ) == 0 )
|
|
{
|
|
readCoordinate3_point( );
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
|
|
int VRML1_MODEL_PARSER::readIndexedFaceSet( )
|
|
{
|
|
char text[128];
|
|
|
|
//DBG( printf( " readIndexedFaceSet\n" ) );
|
|
|
|
while( GetNextTag( m_file, text ) )
|
|
{
|
|
if ( ( text == NULL ) || ( *text == ']' ) )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if ( ( *text == '}' ) )
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if( strcmp( text, "coordIndex" ) == 0 )
|
|
{
|
|
readIndexedFaceSet_coordIndex( );
|
|
}
|
|
else if( strcmp( text, "materialIndex" ) == 0 )
|
|
{
|
|
readIndexedFaceSet_materialIndex( );
|
|
}
|
|
}
|
|
|
|
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( GetMaster()->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( GetMaster()->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( GetMaster()->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( GetMaster()->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;
|
|
}
|
|
|
|
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]) )
|
|
{
|
|
//DBG( printf( " invalid coordIndex at index %lu (%d, %d, %d, %d)\n", m_model->m_CoordIndex.size()+1,coord[0], coord[1], coord[2], dummy ) );
|
|
}
|
|
|
|
if (dummy != -1)
|
|
{
|
|
//DBG( printf( " Error at index %lu, -1 Expected, got %d\n", 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_MaterialIndex.clear();
|
|
|
|
int index;
|
|
while( fscanf( m_file, "%d,", &index ) )
|
|
{
|
|
m_model->m_MaterialIndex.push_back( index );
|
|
}
|
|
|
|
//DBG( printf( " m_MaterialIndex.size: %ld\n", m_model->m_MaterialIndex.size() ) );
|
|
|
|
return 0;
|
|
}
|