kicad-source/3d-viewer/vrml_v2_modelparser.cpp
unknown d40ea8adcb 3D viewer: fix issues with transparencies in some models (material issues in VRML2 parser)
Fix some issues in filling zones normals.
Fix an issue with some models that have materials but didn't defined the diffuse color.
Workaround for Bug #1443431.
Implement some missing "code logic" for pervertexperface normals.
Remove some not used functions.
Calculate normals using double type.
2015-04-16 09:43:27 +02:00

1755 lines
54 KiB
C++

/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2014-2015 Mario Luzeiro <mrluzeiro@gmail.com>
* Copyright (C) 2013 Tuomas Vaherkoski <tuomasvaherkoski@gmail.com>
* Copyright (C) 2012 Jean-Pierre Charras, jp.charras@wanadoo.fr
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
* 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_v2_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 1024
/**
* 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_MODEL_PARSER* aModelParser )
{
m_ModelParser = aModelParser;
m_Master = m_ModelParser->GetMaster();
m_model.reset();
m_file = NULL;
m_normalPerVertex = true;
colorPerVertex = true;
m_debugSpacer = "";
m_counter_DEF_GROUP = 0;
m_counter_USE_GROUP = 0;
m_discardLastGeometry = false;
}
VRML2_MODEL_PARSER::~VRML2_MODEL_PARSER()
{
}
void VRML2_MODEL_PARSER::debug_enter()
{
m_debugSpacer.Append(' ');
}
void VRML2_MODEL_PARSER::debug_exit()
{
m_debugSpacer.RemoveLast();
}
bool VRML2_MODEL_PARSER::Load( const wxString& aFilename )
{
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "Loading: %s" ), GetChars( aFilename ) );
debug_enter();
m_file = wxFopen( aFilename, wxT( "rt" ) );
if( m_file == NULL )
{
debug_exit();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "Failed to open file: %s" ),
GetChars( aFilename ) );
return false;
}
m_Filename = aFilename;
// Switch the locale to standard C (needed to print floating point numbers)
LOCALE_IO toggle;
loadFileModel( S3D_MESH_PTR() );
fclose( m_file );
debug_exit();
return true;
}
bool VRML2_MODEL_PARSER::Load( const wxString& aFilename, S3D_MESH_PTR aTransformationModel )
{
if( aTransformationModel )
{
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "Loading: %s" ),
GetChars( aFilename ) );
debug_enter();
m_file = wxFopen( aFilename, wxT( "rt" ) );
if( m_file == NULL )
{
debug_exit();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "Failed to open file: %s" ),
GetChars( aFilename ) );
return false;
}
m_Filename = aFilename;
// Switch the locale to standard C (needed to print floating point numbers)
LOCALE_IO toggle;
loadFileModel( aTransformationModel );
fclose( m_file );
debug_exit();
return true;
}
debug_exit();
return false;
}
int VRML2_MODEL_PARSER::loadFileModel( S3D_MESH_PTR aTransformationModel )
{
char text[BUFLINE_SIZE];
debug_enter();
while( GetNextTag( m_file, text, sizeof(text) ) )
{
if( ( *text == '}' ) || ( *text == ']' ) )
{
continue;
}
if( strcmp( text, "Transform" ) == 0 )
{
m_model.reset( new S3D_MESH() );
S3D_MESH_PTR save_ptr( m_model );
if( read_Transform() == 0 )
{
m_model = save_ptr;
if( ((m_model->m_Point.size() == 0) || (m_model->m_CoordIndex.size() == 0)) &&
(m_model->childs.size() == 0) )
{
m_model.reset();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "loadFileModel: skipping model with no points or childs" ) );
}
else
{
if( aTransformationModel.get() != NULL )
{
m_model->m_translation = aTransformationModel->m_translation;
m_model->m_rotation = aTransformationModel->m_rotation;
m_model->m_scale = aTransformationModel->m_scale;
}
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "loadFileModel: Add model with %zu points, %zu coordIndex, %zu childs." ),
m_model->m_Point.size(),
m_model->m_CoordIndex.size(),
m_model->childs.size() );
m_ModelParser->childs.push_back( m_model );
}
}
else
{
m_model.reset();
}
}
else if( strcmp( text, "DEF" ) == 0 )
{
m_model.reset( new S3D_MESH() );
S3D_MESH_PTR save_ptr( m_model );
if( read_DEF() == 0 )
{
m_model = save_ptr;
if( ((m_model->m_Point.size() == 0) || (m_model->m_CoordIndex.size() == 0)) &&
(m_model->childs.size() == 0) )
{
m_model.reset();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "loadFileModel: skipping model with no points or childs" ) );
}
else
{
if( aTransformationModel.get() != NULL )
{
m_model->m_translation = aTransformationModel->m_translation;
m_model->m_rotation = aTransformationModel->m_rotation;
m_model->m_scale = aTransformationModel->m_scale;
}
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "loadFileModel: Add model with %zu points, %zu coordIndex, %zu childs." ),
m_model->m_Point.size(),
m_model->m_CoordIndex.size(),
m_model->childs.size() );
m_ModelParser->childs.push_back( m_model );
}
}
else
{
m_model.reset();
}
}
else if( strcmp( text, "Shape" ) == 0 )
{
m_model.reset( new S3D_MESH() );
S3D_MESH_PTR save_ptr = m_model;
if( read_Shape() == 0 )
{
m_model = save_ptr;
if( ((m_model->m_Point.size() == 0) || (m_model->m_CoordIndex.size() == 0)) &&
(m_model->childs.size() == 0) )
{
m_model.reset();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "loadFileModel: skipping model with no points or childs" ) );
}
else
{
if( aTransformationModel.get() != NULL )
{
m_model->m_translation = aTransformationModel->m_translation;
m_model->m_rotation = aTransformationModel->m_rotation;
m_model->m_scale = aTransformationModel->m_scale;
}
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "loadFileModel: Add model with %zu points, %zu coordIndex, %zu childs." ),
m_model->m_Point.size(),
m_model->m_CoordIndex.size(),
m_model->childs.size() );
m_ModelParser->childs.push_back( m_model );
}
}
else
{
m_model.reset();
}
}
}
// There are VRML2 files, as an example, exported by:
// "Generated by TraceParts CAD VRML Translator" that define the group (DEF * GROUP)
// but don't use it in the end, so force it to add the DEF GROUP
if( ( m_counter_DEF_GROUP > 0 ) && (m_counter_USE_GROUP == 0 ) )
{
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "loadFileModel: groups defined with DEF * GROUP but not used with USE, forcing add it..." ) );
if( m_defGroupMap.size() > 0 )
{
for( VRML2_DEF_GROUP_MAP::iterator groupIt = m_defGroupMap.begin(); groupIt!=m_defGroupMap.end(); ++groupIt )
{
wxString groupName = groupIt->first;
S3D_MESH_PTR ptrModel( groupIt->second );
if( ((ptrModel->m_Point.size() == 0) || (ptrModel->m_CoordIndex.size() == 0)) &&
(ptrModel->childs.size() == 0) )
{
// Skip this because dont have data to add
continue;
}
else
{
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "loadFileModel: forced added %s group" ), groupName );
m_ModelParser->childs.push_back( ptrModel );
}
}
}
}
debug_exit();
return 0;
}
int VRML2_MODEL_PARSER::read_Transform()
{
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_Transform" ) );
debug_enter();
char text[BUFLINE_SIZE];
while( GetNextTag( m_file, text, sizeof(text) ) )
{
if( *text == ']' )
{
continue;
}
if( *text == '}' )
{
debug_exit();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_Transform exit" ) );
return 0;
}
if( strcmp( text, "Transform" ) == 0 )
{
m_model.reset( new S3D_MESH() );
S3D_MESH_PTR save_ptr( m_model );
if( read_Transform() == 0 )
{
m_model = save_ptr;
if( ((m_model->m_Point.size() == 0) || (m_model->m_CoordIndex.size() == 0)) &&
(m_model->childs.size() == 0) )
{
m_model.reset();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_Transform: skipping model with no points or childs" ) );
}
else
{
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_Transform: Add child model with %zu points, %zu coordIndex, %zu childs." ),
m_model->m_Point.size(),
m_model->m_CoordIndex.size(),
m_model->childs.size() );
m_ModelParser->childs.push_back( m_model );
}
}
else
{
m_model.reset();
}
}
else if( strcmp( text, "translation" ) == 0 )
{
ParseVertex( m_file, m_model->m_translation );
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "translation (%f,%f,%f)" ),
m_model->m_translation.x,
m_model->m_translation.y,
m_model->m_translation.z );
}
else if( strcmp( text, "rotation" ) == 0 )
{
if( fscanf( m_file, "%f %f %f %f", &m_model->m_rotation[0],
&m_model->m_rotation[1],
&m_model->m_rotation[2],
&m_model->m_rotation[3] ) != 4 )
{
m_model->m_rotation[0] = 0.0f;
m_model->m_rotation[1] = 0.0f;
m_model->m_rotation[2] = 0.0f;
m_model->m_rotation[3] = 0.0f;
wxLogTrace( traceVrmlV2Parser,
m_debugSpacer + wxT( "rotation failed, setting to zeros" ) );
}
else
{
m_model->m_rotation[3] = m_model->m_rotation[3] * 180.0f / 3.14f; // !TODO: use constants or functions
}
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "rotation (%f,%f,%f,%f)" ),
m_model->m_rotation[0],
m_model->m_rotation[1],
m_model->m_rotation[2],
m_model->m_rotation[3] );
}
else if( strcmp( text, "scale" ) == 0 )
{
ParseVertex( m_file, m_model->m_scale );
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "scale (%f,%f,%f)" ),
m_model->m_scale.x, m_model->m_scale.y, m_model->m_scale.z );
}
else if( strcmp( text, "scaleOrientation" ) == 0 )
{
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "scaleOrientation is not implemented, but it will be parsed" ) );
glm::vec4 vecDummy;
if( fscanf( m_file, "%f %f %f %f", &vecDummy[0],
&vecDummy[1],
&vecDummy[2],
&vecDummy[3] ) != 4 )
{
vecDummy[0] = 0.0f;
vecDummy[1] = 0.0f;
vecDummy[2] = 0.0f;
vecDummy[3] = 0.0f;
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "scaleOrientation failed, setting to zeros" ) );
}
//wxLogTrace( traceVrmlV2Parser, wxT( " scaleOrientation (%f,%f,%f,%f)" ),
// m_model->m_scaleOrientation[0],
// m_model->m_scaleOrientation[1],
// m_model->m_scaleOrientation[2],
// m_model->m_scaleOrientation[3] );
}
else if( strcmp( text, "center" ) == 0 )
{
// this is not used
glm::vec3 vecDummy;
ParseVertex( m_file, vecDummy );
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "center is not implemented (%f,%f,%f)" ), vecDummy.x, vecDummy.y, vecDummy.z );
}
else if( strcmp( text, "children" ) == 0 )
{
// skip
}
else if( strcmp( text, "Switch" ) == 0 )
{
// skip
}
else if( strcmp( text, "whichChoice" ) == 0 )
{
int dummy;
if( fscanf( m_file, "%d", &dummy ) != 1 )
{
// !TODO: log errors
}
}
else if( strcmp( text, "choice" ) == 0 )
{
// skip
}
else if( strcmp( text, "Group" ) == 0 )
{
// Keep looking for things in a transform
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "Group" ) );
read_Transform();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "Transform Group exit" ) );
//return ret;
}
else if( strcmp( text, "Inline" ) == 0 )
{
read_Inline();
}
else if( strcmp( text, "Shape" ) == 0 )
{
// Save the pointer
S3D_MESH_PTR parent( m_model );
S3D_MESH_PTR new_mesh_model( new S3D_MESH() );
// Assign the current pointer
m_model = new_mesh_model;
S3D_MESH_PTR save_ptr = m_model;
if( read_Shape() == 0 )
{
if( m_discardLastGeometry == false )
{
m_model = save_ptr;
if( ((m_model->m_Point.size() == 0) || (m_model->m_CoordIndex.size() == 0))
&& (m_model->childs.size() == 0) )
{
m_model.reset();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_Transform: Shape, skipping model with no points or childs" ) );
}
else
{
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_Transform: Shape, Add child model with %zu points, %zu coordIndex, %zu childs." ),
m_model->m_Point.size(),
m_model->m_CoordIndex.size(),
m_model->childs.size() );
parent->childs.push_back( m_model );
}
}
else
{
m_model.reset();
wxLogTrace( traceVrmlV2Parser,
m_debugSpacer + wxT( "read_Transform: Shape, discard child." ) );
}
}
else
{
m_model.reset();
}
m_model = parent;
}
else if( strcmp( text, "DEF" ) == 0 )
{
read_DEF();
}
else if( strcmp( text, "USE" ) == 0 )
{
char useLabel[BUFLINE_SIZE];
if( GetNextTag( m_file, useLabel, sizeof(useLabel) ) )
{
// Check if a ',' is at the end and remove it
if( useLabel[strlen(useLabel) - 1] == ',' )
{
useLabel[strlen(useLabel) - 1] = 0;
}
std::string strUseLabel = useLabel;
// Look for it in our group map.
VRML2_DEF_GROUP_MAP::iterator groupIt;
groupIt = m_defGroupMap.find( strUseLabel );
// Checf if not previously defined.
if( groupIt == m_defGroupMap.end() )
{
debug_exit();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "USE: group %s not previously defined "
"in a DEF section." ), strUseLabel );
return -1;
}
S3D_MESH_PTR ptrModel( groupIt->second );
if( ((ptrModel->m_Point.size() == 0) || (ptrModel->m_CoordIndex.size() == 0)) &&
(ptrModel->childs.size() == 0) )
{
// !TODO: delete in the end
//delete ptrModel;
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_Transform: USE %s, skipping model with no points or childs" ), useLabel );
}
else
{
m_counter_USE_GROUP++;
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_Transform: USE %s Add child model with %zu points, %zu coordIndex, %zu childs." ),
useLabel,
ptrModel->m_Point.size(),
ptrModel->m_CoordIndex.size(),
ptrModel->childs.size() );
m_model->childs.push_back( ptrModel );
}
}
else
{
debug_exit();
wxLogTrace( traceVrmlV2Parser,
m_debugSpacer + wxT( "read_Transform: USE Failed to get the label name" ) );
return -1;
}
}
else
{
wxLogTrace( traceVrmlV2Parser,
m_debugSpacer + wxT( "read_Transform: %s NotImplemented" ), text );
Read_NotImplemented( m_file, '}' );
}
}
debug_exit();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_Transform failed" ) );
return -1;
}
int VRML2_MODEL_PARSER::read_Inline()
{
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_Inline" ) );
debug_enter();
char text[BUFLINE_SIZE];
while( GetNextTag( m_file, text, sizeof(text) ) )
{
if( *text == ']' )
continue;
if( *text == '}' )
{
debug_exit();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_Inline exit" ) );
return 0;
}
if( strcmp( text, "url" ) == 0 )
{
if( GetString( m_file, text, sizeof(text) ) )
{
wxString filename;
filename = filename.FromUTF8( text );
#ifdef __WINDOWS__
filename.Replace( wxT( "/" ), wxT( "\\" ) );
#else
filename.Replace( wxT( "\\" ), wxT( "/" ) );
#endif
bool fileExists = false;
if( wxFileName::FileExists( filename ) )
{
fileExists = true;
}
else
{
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "URL Failed to open file as a full path: \"%s\", will try now a relative path..." ), filename );
#ifdef __WINDOWS__
filename = m_Filename.GetPath() + '\\' + filename;
#else
filename = m_Filename.GetPath() + '/' + filename;
#endif
if( wxFileName::FileExists( filename ) )
{
fileExists = true;
}
else
{
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "URL Failed to open file: \"%s\"" ), filename );
}
}
if( fileExists )
{
// Will now create a new parser and set the default
// transfomation model to apply on the root
VRML2_MODEL_PARSER *newParser = new VRML2_MODEL_PARSER( this->m_ModelParser );
newParser->Load( filename, m_model );
delete newParser;
}
else
{
wxLogTrace( traceVrmlV2Parser,
m_debugSpacer + wxT( "URL Failed to open file: %s" ), text );
}
}
else
{
// If fail get url text, exit with failure
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "URL failed read url string" ) );
break;
}
}
}
debug_exit();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_Inline failed" ) );
return -1;
}
int VRML2_MODEL_PARSER::read_DEF_Coordinate()
{
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_DEF_Coordinate" ) );
debug_enter();
char text[BUFLINE_SIZE];
// Get the name of the definition.
if( !GetNextTag( m_file, text, sizeof(text) ) )
{
debug_exit();
wxLogTrace( traceVrmlV2Parser,
m_debugSpacer + wxT( "read_DEF_Coordinate failed to get next tag" ) );
return -1;
}
std::string coordinateName = text;
while( GetNextTag( m_file, text, sizeof(text) ) )
{
if( *text == ']' )
continue;
if( *text == '}' )
{
debug_exit();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_DEF_Coordinate exit" ) );
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 ) );
wxLogTrace( traceVrmlV2Parser,
m_debugSpacer + wxT( "read_DEF_Coordinate insert %s" ), coordinateName );
}
debug_exit();
return retVal;
}
}
debug_exit();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_DEF_Coordinate failed" ) );
return -1;
}
int VRML2_MODEL_PARSER::read_DEF()
{
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_DEF" ) );
debug_enter();
char text[BUFLINE_SIZE];
char tagName[BUFLINE_SIZE];
if( !GetNextTag( m_file, tagName, sizeof(tagName) ) )
{
debug_exit();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "DEF failed GetNextTag first" ) );
return -1;
}
while( GetNextTag( m_file, text, sizeof(text) ) )
{
if( *text == ']' )
{
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "skipping %c" ), *text );
continue;
}
if( *text == '}' )
{
debug_exit();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_DEF exit" ) );
return 0;
}
if( strcmp( text, "Transform" ) == 0 )
{
int ret = read_Transform();
debug_exit();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_DEF exit after Transform, please check and validate" ) );
return ret;
}
else if( strcmp( text, "children" ) == 0 )
{
// skip
}
else if( strcmp( text, "Switch" ) == 0 )
{
// skip
}
else if( strcmp( text, "whichChoice" ) == 0 )
{
// skip
}
else if( strcmp( text, "choice" ) == 0 )
{
// skip
}
else if( strcmp( text, "Shape" ) == 0 )
{
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "Shape" ) );
// Save the pointer
S3D_MESH_PTR parent = m_model;
S3D_MESH_PTR new_mesh_model( new S3D_MESH() );
// Assign the current pointer
m_model = new_mesh_model;
S3D_MESH_PTR save_ptr = m_model;
if( read_Shape() == 0 )
{
m_model = save_ptr;
if( ((m_model->m_Point.size() == 0) || (m_model->m_CoordIndex.size() == 0)) &&
(m_model->childs.size() == 0) )
{
m_model.reset();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_DEF: Shape, skipping model with no points or childs" ) );
}
else
{
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_DEF: Shape, Add child model with %zu points, %zu coordIndex, %zu childs." ),
m_model->m_Point.size(),
m_model->m_CoordIndex.size(),
m_model->childs.size() );
parent->childs.push_back( m_model );
}
}
else
{
m_model.reset();
}
m_model = parent;
}
else if( strcmp( text, "IndexedFaceSet" ) == 0 )
{
m_discardLastGeometry = false;
read_IndexedFaceSet();
}
else if( strcmp( text, "Group" ) == 0 )
{
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "Group %s" ), tagName );
// Save the pointer
S3D_MESH_PTR parent = m_model;
S3D_MESH_PTR new_mesh_model( new S3D_MESH() );
// Assign the current pointer
m_model = new_mesh_model;
// It will be the same as read a new Transform
if( read_Transform() == 0 )
{
m_counter_DEF_GROUP++;
std::string groupName = tagName;
m_defGroupMap[groupName] = new_mesh_model;
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "Group %s: inserted model with %zu points, %zu coordIndex, %zu childs." ),
tagName,
new_mesh_model->m_Point.size(),
new_mesh_model->m_CoordIndex.size(),
new_mesh_model->childs.size() );
}
else
{
m_model.reset();
}
// Restore current model pointer
m_model = parent;
debug_exit();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_DEF %s Group exit" ), tagName );
return 0;
}
else
{
debug_exit();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_DEF %s %s NotImplemented, skipping." ), tagName, text );
Read_NotImplemented( m_file, '}' );
return 0;
}
}
debug_exit();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "DEF failed" ) );
return -1;
}
int VRML2_MODEL_PARSER::read_IndexedFaceSet_USE()
{
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_IndexedFaceSet_USE" ) );
debug_enter();
char text[BUFLINE_SIZE];
// Get the name of the definition.
if( !GetNextTag( m_file, text, sizeof(text) ) )
{
debug_exit();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_IndexedFaceSet_USE failed to get next tag" ) );
return -1;
}
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() )
{
debug_exit();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_IndexedFaceSet_USE: coordinate %s not previously defined "
"in a DEF section." ), text );
return -1;
}
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_IndexedFaceSet_USE %s" ), text );
m_model->m_Point = coordinate->second;
debug_exit();
return 0;
}
int VRML2_MODEL_PARSER::read_Shape()
{
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_Shape" ) );
debug_enter();
char text[BUFLINE_SIZE];
while( GetNextTag( m_file, text, sizeof(text) ) )
{
if( *text == ']' )
{
continue;
}
if( *text == '}' )
{
debug_exit();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_Shape exit" ) );
return 0;
}
if( strcmp( text, "appearance" ) == 0 )
{
read_appearance();
}
else if( strcmp( text, "geometry" ) == 0 )
{
read_geometry();
}
else if( strcmp( text, "IndexedFaceSet" ) == 0 )
{
m_discardLastGeometry = false;
read_IndexedFaceSet();
}
else if( strcmp( text, "IndexedLineSet" ) == 0 )
{
m_discardLastGeometry = true;
read_IndexedLineSet();
}
else
{
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_Shape %s NotImplemented" ), text );
Read_NotImplemented( m_file, '}' );
}
}
debug_exit();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "Shape failed" ) );
return -1;
}
int VRML2_MODEL_PARSER::read_geometry()
{
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_geometry" ) );
debug_enter();
char text[BUFLINE_SIZE];
char tagName[BUFLINE_SIZE];
tagName[0] = 0;
while( GetNextTag( m_file, text, sizeof(text) ) )
{
if( *text == ']' )
{
continue;
}
if( *text == '}' )
{
debug_exit();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_geometry exit" ) );
return 0;
}
if( strcmp( text, "DEF" ) == 0 )
{
if( !GetNextTag( m_file, tagName, sizeof(tagName) ) )
{
debug_exit();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "DEF failed GetNextTag first" ) );
return -1;
}
}
else if( strcmp( text, "IndexedFaceSet" ) == 0 )
{
m_discardLastGeometry = false;
int ret = read_IndexedFaceSet();
debug_exit();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_geometry exit, after IndexedFaceSet" ) );
return ret;
}
else if( strcmp( text, "IndexedLineSet" ) == 0 )
{
m_discardLastGeometry = true;
int ret = read_IndexedLineSet();
debug_exit();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_geometry exit, after IndexedLineSet" ) );
return ret;
}
else
{
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_geometry: %s NotImplemented" ), text );
int ret = Read_NotImplemented( m_file, '}' );
debug_exit();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_geometry exit, after %s" ), text);
return ret;
}
}
debug_exit();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_geometry failed" ) );
return -1;
}
int VRML2_MODEL_PARSER::read_appearance()
{
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_appearance" ) );
debug_enter();
S3D_MATERIAL* material = NULL;
char text[BUFLINE_SIZE];
while( GetNextTag( m_file, text, sizeof(text) ) )
{
if( *text == ']' )
{
continue;
}
if( *text == '}' )
{
debug_exit();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_appearance exit" ) );
return 0;
}
if( strcmp( text, "Appearance" ) == 0 )
{
int ret = read_Appearance();
debug_exit();
return ret;
}
else if( strcmp( text, "DEF" ) == 0 )
{
if( GetNextTag( m_file, text, sizeof(text) ) )
{
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_appearance adding new material %s" ), text );
wxString mat_name;
mat_name = FROM_UTF8( text );
material = new S3D_MATERIAL( m_Master, mat_name );
m_Master->Insert( material );
m_model->m_Materials = material;
if( GetNextTag( m_file, text, sizeof(text) ) )
{
if( strcmp( text, "Appearance" ) == 0 )
{
int ret = read_Appearance();
debug_exit();
return ret;
}
}
}
// Exit loop with error
break;
}
else if( strcmp( text, "USE" ) == 0 )
{
if( GetNextTag( m_file, text, sizeof(text) ) )
{
wxString mat_name;
mat_name = FROM_UTF8( text );
S3D_MATERIAL* found_material = NULL;
for( material = m_Master->m_Materials; material; material = material->Next() )
{
if( material->m_Name == mat_name )
{
found_material = material;
// We dont exit here, since it seems that VRML can have
// multiple material defined, so, it will copy the latest one that was defined.
}
}
debug_exit();
if( found_material )
{
// Create a new material instead of assign a pointer because
// the indexfaceset can set color pervertex and that will be stored in the material.
m_model->m_Materials = new S3D_MATERIAL( m_Master, found_material->m_Name );
m_model->m_Materials->m_AmbientColor = found_material->m_AmbientColor;
m_model->m_Materials->m_DiffuseColor = found_material->m_DiffuseColor;
m_model->m_Materials->m_EmissiveColor = found_material->m_EmissiveColor;
m_model->m_Materials->m_SpecularColor = found_material->m_SpecularColor;
m_model->m_Materials->m_Shininess = found_material->m_Shininess;
m_model->m_Materials->m_Transparency = found_material->m_Transparency;
m_model->m_Materials->m_ColorPerVertex = false;
return 0;
}
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_appearance error: material not found" ) );
return -1;
}
// Exit loop with error
break;
}
else
{
// Exit loop with error
break;
}
}
debug_exit();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_appearance failed" ) );
return -1;
}
int VRML2_MODEL_PARSER::read_Appearance()
{
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_Appearance" ) );
debug_enter();
char text[BUFLINE_SIZE];
while( GetNextTag( m_file, text, sizeof(text) ) )
{
if( *text == ']' )
{
continue;
}
if( *text == '}' )
{
debug_exit();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_Appearance exit" ) );
return 0;
}
if( strcmp( text, "material" ) == 0 )
{
read_material();
}
}
debug_exit();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "Appearance failed" ) );
return -1;
}
int VRML2_MODEL_PARSER::read_material()
{
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_material" ) );
debug_enter();
S3D_MATERIAL* material = NULL;
char text[BUFLINE_SIZE];
if( GetNextTag( m_file, text, sizeof(text) ) )
{
if( strcmp( text, "Material" ) == 0 )
{
// Check if it is NULL, if not, it is because we come
// from an appearance DEF and already have a pointer
if( m_model->m_Materials == NULL )
{
wxString mat_name;
material = new S3D_MATERIAL( m_Master, mat_name );
m_Master->Insert( material );
m_model->m_Materials = material;
}
int ret = read_Material();
debug_exit();
return ret;
}
else if( strcmp( text, "DEF" ) == 0 )
{
if( GetNextTag( m_file, text, sizeof(text) ) )
{
wxString mat_name;
mat_name = FROM_UTF8( text );
material = new S3D_MATERIAL( m_Master, mat_name );
m_Master->Insert( material );
m_model->m_Materials = material;
if( GetNextTag( m_file, text, sizeof(text) ) )
{
if( strcmp( text, "Material" ) == 0 )
{
int ret = read_Material();
debug_exit();
return ret;
}
}
}
}
else if( strcmp( text, "USE" ) == 0 )
{
if( GetNextTag( m_file, text, sizeof(text) ) )
{
wxString mat_name;
mat_name = FROM_UTF8( text );
S3D_MATERIAL* found_material = NULL;
for( material = m_Master->m_Materials; material; material = material->Next() )
{
if( material->m_Name == mat_name )
{
found_material = material;
// We dont exit here, since it seems that VRML can have
// multiple material defined, so, it will copy the latest one that was defined.
}
}
debug_exit();
if( found_material )
{
// Create a new material instead of assign a pointer because
// the indexfaceset can set color pervertex and that will be stored in the material.
m_model->m_Materials = new S3D_MATERIAL( m_Master, found_material->m_Name );
m_model->m_Materials->m_AmbientColor = found_material->m_AmbientColor;
m_model->m_Materials->m_DiffuseColor = found_material->m_DiffuseColor;
m_model->m_Materials->m_EmissiveColor = found_material->m_EmissiveColor;
m_model->m_Materials->m_SpecularColor = found_material->m_SpecularColor;
m_model->m_Materials->m_Shininess = found_material->m_Shininess;
m_model->m_Materials->m_Transparency = found_material->m_Transparency;
m_model->m_Materials->m_ColorPerVertex = false;
return 0;
}
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_material error: material not found" ) );
return -1;
}
}
}
debug_exit();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "failed material" ) );
return -1;
}
int VRML2_MODEL_PARSER::read_Material()
{
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_Material" ) );
debug_enter();
char text[BUFLINE_SIZE];
glm::vec3 vertex;
while( GetNextTag( m_file, text, sizeof(text) ) )
{
if( *text == ']' )
{
continue;
}
if( *text == '}' )
{
debug_exit();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_Material exit" ) );
return 0;
}
if( strcmp( text, "diffuseColor" ) == 0 )
{
ParseVertex( m_file, vertex );
m_model->m_Materials->m_DiffuseColor.push_back( vertex );
}
else if( strcmp( text, "emissiveColor" ) == 0 )
{
ParseVertex( m_file, vertex );
if( m_Master->m_use_modelfile_emissiveColor == true )
{
m_model->m_Materials->m_EmissiveColor.push_back( vertex );
}
}
else if( strcmp( text, "specularColor" ) == 0 )
{
ParseVertex( m_file, vertex );
if( m_Master->m_use_modelfile_specularColor == true )
{
m_model->m_Materials->m_SpecularColor.push_back( vertex );
}
}
else if( strcmp( text, "ambientIntensity" ) == 0 )
{
float ambientIntensity;
ParseFloat( m_file, &ambientIntensity, 0.8 );
if( m_Master->m_use_modelfile_ambientIntensity == true )
{
m_model->m_Materials->m_AmbientColor.push_back( glm::vec3( ambientIntensity,
ambientIntensity, ambientIntensity ) );
}
}
else if( strcmp( text, "transparency" ) == 0 )
{
float transparency;
ParseFloat( m_file, &transparency, 0.0 );
if( m_Master->m_use_modelfile_transparency == true )
{
m_model->m_Materials->m_Transparency.push_back( transparency );
}
}
else if( strcmp( text, "shininess" ) == 0 )
{
float shininess;
ParseFloat( m_file, &shininess, 1.0 );
// VRML value is normalized and openGL expects a value 0 - 128
if( m_Master->m_use_modelfile_shininess == true )
{
shininess = shininess * 128.0f;
m_model->m_Materials->m_Shininess.push_back( shininess );
}
}
}
debug_exit();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "Material failed" ) );
return -1;
}
int VRML2_MODEL_PARSER::read_IndexedFaceSet()
{
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_IndexedFaceSet" ) );
debug_enter();
char text[BUFLINE_SIZE];
m_normalPerVertex = false;
colorPerVertex = false;
while( GetNextTag( m_file, text, sizeof(text) ) )
{
if( *text == ']' )
{
continue;
}
if( *text == '}' )
{
debug_exit();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_IndexedFaceSet exit" ) );
return 0;
}
if( strcmp( text, "normalPerVertex" ) == 0 )
{
if( GetNextTag( m_file, text, sizeof(text) ) )
{
if( strcmp( text, "TRUE" ) == 0 )
{
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_IndexedFaceSet m_normalPerVertex TRUE" ) );
m_normalPerVertex = true;
}
}
}
else if( strcmp( text, "colorPerVertex" ) == 0 )
{
GetNextTag( m_file, text, sizeof(text) );
if( strcmp( text, "TRUE" ) == 0 )
{
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_IndexedFaceSet colorPerVertex TRUE" ) );
colorPerVertex = true;
m_model->m_Materials->m_ColorPerVertex = true;
}
else
{
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_IndexedFaceSet colorPerVertex FALSE" ) );
colorPerVertex = false;
}
}
else if( strcmp( text, "Coordinate" ) == 0 )
{
read_Coordinate();
}
else if( strcmp( text, "Normal" ) == 0 )
{
read_Normal();
}
else if( strcmp( text, "normalIndex" ) == 0 )
{
read_NormalIndex();
}
else if( strcmp( text, "Color" ) == 0 )
{
read_Color();
}
else if( strcmp( text, "coordIndex" ) == 0 )
{
read_coordIndex();
}
else if( strcmp( text, "colorIndex" ) == 0 )
{
read_colorIndex();
}
else if( strcmp( text, "USE" ) == 0 )
{
read_IndexedFaceSet_USE();
}
}
debug_exit();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "IndexedFaceSet failed %s" ), text );
return -1;
}
int VRML2_MODEL_PARSER::read_IndexedLineSet()
{
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_IndexedLineSet" ) );
debug_enter();
char text[BUFLINE_SIZE];
while( GetNextTag( m_file, text, sizeof(text) ) )
{
if( *text == ']' )
continue;
if( *text == '}' )
{
debug_exit();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_IndexedLineSet exit" ) );
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();
}
debug_exit();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_IndexedLineSet failed" ) );
return -1;
}
int VRML2_MODEL_PARSER::read_colorIndex()
{
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_colorIndex" ) );
debug_enter();
m_model->m_MaterialIndexPerFace.clear();
m_model->m_MaterialIndexPerVertex.clear();
if( colorPerVertex == true )
{
int index;
if( m_model->m_CoordIndex.size() > 0 )
m_model->m_MaterialIndexPerVertex.reserve( m_model->m_CoordIndex.size() );
std::vector<int> materialIndexPerVertex;
materialIndexPerVertex.reserve( 3 ); // Start at least with 3
while( fscanf( m_file, "%d, ", &index ) == 1 )
{
if( index == -1 )
{
m_model->m_MaterialIndexPerVertex.push_back( materialIndexPerVertex );
materialIndexPerVertex.clear();
materialIndexPerVertex.reserve( 3 );
}
else
{
materialIndexPerVertex.push_back( index );
}
}
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_colorIndex m_MaterialIndexPerVertex.size: %lu" ), m_model->m_MaterialIndexPerVertex.size() );
}
else
{
int index;
if( m_model->m_CoordIndex.size() > 0 )
m_model->m_MaterialIndexPerFace.reserve( m_model->m_CoordIndex.size() );
while( fscanf( m_file, "%d,", &index ) )
{
m_model->m_MaterialIndexPerFace.push_back( index );
}
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_colorIndex m_MaterialIndexPerFace.size: %lu" ), m_model->m_MaterialIndexPerFace.size() );
}
debug_exit();
return 0;
}
int VRML2_MODEL_PARSER::read_NormalIndex()
{
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_NormalIndex" ) );
debug_enter();
m_model->m_NormalIndex.clear();
glm::ivec3 coord;
int dummy; // should be -1
std::vector<int> coord_list;
coord_list.clear();
while( fscanf( m_file, "%d, ", &dummy ) == 1 )
{
if( dummy == -1 )
{
m_model->m_NormalIndex.push_back( coord_list );
coord_list.clear();
}
else
{
coord_list.push_back( dummy );
}
}
//wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_NormalIndex m_NormalIndex.size: %u" ), (unsigned int)m_model->m_NormalIndex.size() );
debug_exit();
return 0;
}
int VRML2_MODEL_PARSER::read_coordIndex()
{
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_coordIndex" ) );
debug_enter();
m_model->m_CoordIndex.clear();
glm::ivec3 coord;
int coordIdx; // should be -1
std::vector<int> coord_list;
coord_list.clear();
while( fscanf( m_file, "%d, ", &coordIdx ) == 1 )
{
if( coordIdx == -1 )
{
m_model->m_CoordIndex.push_back( coord_list );
coord_list.clear();
}
else
{
coord_list.push_back( coordIdx );
}
}
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_coordIndex m_CoordIndex.size: %zu" ),
m_model->m_CoordIndex.size() );
debug_exit();
return 0;
}
int VRML2_MODEL_PARSER::read_Color()
{
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_Color" ) );
debug_enter();
char text[BUFLINE_SIZE];
while( GetNextTag( m_file, text, sizeof(text) ) )
{
if( *text == ']' )
{
continue;
}
if( *text == '}' )
{
debug_exit();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_Color exit" ) );
return 0;
}
if( strcmp( text, "color" ) == 0 )
{
m_model->m_Materials->m_DiffuseColor.clear();
ParseVertexList( m_file, m_model->m_Materials->m_DiffuseColor );
}
}
debug_exit();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_Color failed" ) );
return -1;
}
int VRML2_MODEL_PARSER::read_Normal()
{
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_Normal" ) );
debug_enter();
char text[BUFLINE_SIZE];
while( GetNextTag( m_file, text, sizeof(text) ) )
{
if( *text == ']' )
{
continue;
}
if( *text == '}' )
{
// Debug
if( m_normalPerVertex == false )
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_Normal m_PerFaceNormalsNormalized.size: %zu" ), m_model->m_PerFaceNormalsNormalized.size() );
else
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_Normal m_PerVertexNormalsNormalized.size: %zu" ), m_model->m_PerVertexNormalsNormalized.size() );
debug_exit();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_Normal exit" ) );
return 0;
}
if( strcmp( text, "vector" ) == 0 )
{
if( m_normalPerVertex == false )
{
ParseVertexList( m_file, m_model->m_PerFaceNormalsNormalized );
}
else
{
ParseVertexList( m_file, m_model->m_PerVertexNormalsNormalized );
}
}
}
debug_exit();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_Normal failed" ) );
return -1;
}
int VRML2_MODEL_PARSER::read_Coordinate()
{
debug_enter();
char text[BUFLINE_SIZE];
while( GetNextTag( m_file, text, sizeof(text) ) )
{
if( *text == ']' )
{
continue;
}
if( *text == '}' )
{
wxLogTrace( traceVrmlV2Parser,
m_debugSpacer + wxT( "read_Coordinate m_Point.size: %zu" ),
m_model->m_Point.size() );
debug_exit();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_Coordinate exit" ) );
return 0;
}
if( strcmp( text, "point" ) == 0 )
{
ParseVertexList( m_file, m_model->m_Point );
}
}
debug_exit();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_Coordinate failed" ) );
return -1;
}
/**
* Read the point of the Coordinate for a DEF
*/
int VRML2_MODEL_PARSER::read_CoordinateDef()
{
debug_enter();
char text[BUFLINE_SIZE];
while( GetNextTag( m_file, text, sizeof(text) ) )
{
if( *text == ']' )
continue;
if( *text == '}' )
{
debug_exit();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_CoordinateDef exit" ) );
//wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_CoordinateDef m_Point.size: %u" ), (unsigned int)m_model->m_Point.size() );
return 0;
}
if( strcmp( text, "point" ) == 0 )
ParseVertexList( m_file, m_model->m_Point );
}
debug_exit();
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_CoordinateDef failed" ) );
return -1;
}