Commit patch for x3d file reader (with minor changes). Commit other minor patches and fixes
This commit is contained in:
parent
aae87178a7
commit
5874ac0f6f
|
@ -35,20 +35,33 @@
|
||||||
|
|
||||||
#include <3d_viewer.h>
|
#include <3d_viewer.h>
|
||||||
#include <info3d_visu.h>
|
#include <info3d_visu.h>
|
||||||
|
#include "3d_struct.h"
|
||||||
|
#include "modelparsers.h"
|
||||||
|
|
||||||
// Imported function:
|
// Imported function:
|
||||||
extern void Set_Object_Data( std::vector< S3D_VERTEX >& aVertices, double aBiuTo3DUnits );
|
extern void Set_Object_Data( std::vector< S3D_VERTEX >& aVertices, double aBiuTo3DUnits );
|
||||||
|
|
||||||
// separator chars
|
S3D_MODEL_PARSER* S3D_MODEL_PARSER::Create( S3D_MASTER* aMaster,
|
||||||
static const char* sep_chars = " \t\n\r";
|
const wxString aExtension )
|
||||||
|
{
|
||||||
|
if ( aExtension == wxT( "x3d" ) )
|
||||||
|
{
|
||||||
|
return new X3D_MODEL_PARSER(aMaster);
|
||||||
|
}
|
||||||
|
else if ( aExtension == wxT( "wrl" ) )
|
||||||
|
{
|
||||||
|
return new VRML_MODEL_PARSER(aMaster);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int S3D_MASTER::ReadData()
|
int S3D_MASTER::ReadData()
|
||||||
{
|
{
|
||||||
char line[1024], * text;
|
|
||||||
wxFileName fn;
|
wxFileName fn;
|
||||||
wxString FullFilename;
|
wxString FullFilename;
|
||||||
FILE* file;
|
|
||||||
int LineNum = 0;
|
|
||||||
|
|
||||||
if( m_Shape3DName.IsEmpty() )
|
if( m_Shape3DName.IsEmpty() )
|
||||||
{
|
{
|
||||||
|
@ -65,6 +78,7 @@ int S3D_MASTER::ReadData()
|
||||||
if( wxFileName::FileExists( shape3DNname ) )
|
if( wxFileName::FileExists( shape3DNname ) )
|
||||||
{
|
{
|
||||||
FullFilename = shape3DNname;
|
FullFilename = shape3DNname;
|
||||||
|
fn.Assign(FullFilename);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -79,512 +93,22 @@ int S3D_MASTER::ReadData()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
file = wxFopen( FullFilename, wxT( "rt" ) );
|
wxString extension = fn.GetExt();
|
||||||
|
S3D_MODEL_PARSER* parser = S3D_MODEL_PARSER::Create(this, extension);
|
||||||
if( file == NULL )
|
if(parser)
|
||||||
{
|
{
|
||||||
return -1;
|
parser->Load(FullFilename);
|
||||||
}
|
delete parser;
|
||||||
|
|
||||||
// Switch the locale to standard C (needed to print floating point numbers like 1.3)
|
|
||||||
SetLocaleTo_C_standard();
|
|
||||||
|
|
||||||
while( GetLine( file, line, &LineNum, 512 ) )
|
|
||||||
{
|
|
||||||
text = strtok( line, sep_chars );
|
|
||||||
|
|
||||||
if( stricmp( text, "DEF" ) == 0 || stricmp( text, "Group" ) == 0)
|
|
||||||
{
|
|
||||||
while( GetLine( file, line, &LineNum, 512 ) )
|
|
||||||
{
|
|
||||||
text = strtok( line, sep_chars );
|
|
||||||
|
|
||||||
if( text == NULL )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if( *text == '}' )
|
|
||||||
break;
|
|
||||||
|
|
||||||
if( stricmp( text, "children" ) == 0 )
|
|
||||||
{
|
|
||||||
ReadChildren( file, &LineNum );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose( file );
|
|
||||||
SetLocaleTo_Default(); // revert to the current locale
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int S3D_MASTER::ReadMaterial( FILE* file, int* LineNum )
|
|
||||||
{
|
|
||||||
char line[512], * text, * command;
|
|
||||||
wxString mat_name;
|
|
||||||
S3D_MATERIAL* material = NULL;
|
|
||||||
|
|
||||||
command = strtok( NULL, sep_chars );
|
|
||||||
text = strtok( NULL, sep_chars );
|
|
||||||
mat_name = FROM_UTF8( text );
|
|
||||||
|
|
||||||
if( stricmp( command, "USE" ) == 0 )
|
|
||||||
{
|
|
||||||
for( material = m_Materials; material; material = material->Next() )
|
|
||||||
{
|
|
||||||
if( material->m_Name == mat_name )
|
|
||||||
{
|
|
||||||
material->SetMaterial();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
D( printf( "ReadMaterial error: material not found\n" ) );
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if( stricmp( command, "DEF" ) == 0 || stricmp( command, "Material") == 0)
|
|
||||||
{
|
{
|
||||||
material = new S3D_MATERIAL( this, mat_name );
|
wxLogDebug( wxT( "Unknown file type <%s>" ), GetChars( extension ) );
|
||||||
|
|
||||||
Insert( material );
|
|
||||||
|
|
||||||
while( GetLine( file, line, LineNum, 512 ) )
|
|
||||||
{
|
|
||||||
text = strtok( line, sep_chars );
|
|
||||||
|
|
||||||
if( text == NULL )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if( text[0] == '}' )
|
|
||||||
{
|
|
||||||
material->SetMaterial();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( stricmp( text, "diffuseColor" ) == 0 )
|
|
||||||
{
|
|
||||||
text = strtok( NULL, sep_chars );
|
|
||||||
material->m_DiffuseColor.x = atof( text );
|
|
||||||
text = strtok( NULL, sep_chars );
|
|
||||||
material->m_DiffuseColor.y = atof( text );
|
|
||||||
text = strtok( NULL, sep_chars );
|
|
||||||
material->m_DiffuseColor.z = atof( text );
|
|
||||||
}
|
|
||||||
else if( stricmp( text, "emissiveColor" ) == 0 )
|
|
||||||
{
|
|
||||||
text = strtok( NULL, sep_chars );
|
|
||||||
material->m_EmissiveColor.x = atof( text );
|
|
||||||
text = strtok( NULL, sep_chars );
|
|
||||||
material->m_EmissiveColor.y = atof( text );
|
|
||||||
text = strtok( NULL, sep_chars );
|
|
||||||
material->m_EmissiveColor.z = atof( text );
|
|
||||||
}
|
|
||||||
else if( strnicmp( text, "specularColor", 13 ) == 0 )
|
|
||||||
{
|
|
||||||
text = strtok( NULL, sep_chars );
|
|
||||||
material->m_SpecularColor.x = atof( text );
|
|
||||||
text = strtok( NULL, sep_chars );
|
|
||||||
material->m_SpecularColor.y = atof( text );
|
|
||||||
text = strtok( NULL, sep_chars );
|
|
||||||
material->m_SpecularColor.z = atof( text );
|
|
||||||
}
|
|
||||||
else if( strnicmp( text, "ambientIntensity", 16 ) == 0 )
|
|
||||||
{
|
|
||||||
text = strtok( NULL, sep_chars );
|
|
||||||
material->m_AmbientIntensity = atof( text );
|
|
||||||
}
|
|
||||||
else if( strnicmp( text, "transparency", 12 ) == 0 )
|
|
||||||
{
|
|
||||||
text = strtok( NULL, sep_chars );
|
|
||||||
material->m_Transparency = atof( text );
|
|
||||||
}
|
|
||||||
else if( strnicmp( text, "shininess", 9 ) == 0 )
|
|
||||||
{
|
|
||||||
text = strtok( NULL, sep_chars );
|
|
||||||
material->m_Shininess = atof( text );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int S3D_MASTER::ReadChildren( FILE* file, int* LineNum )
|
|
||||||
{
|
|
||||||
char line[1024], * text;
|
|
||||||
|
|
||||||
while( GetLine( file, line, LineNum, 512 ) )
|
|
||||||
{
|
|
||||||
text = strtok( line, sep_chars );
|
|
||||||
|
|
||||||
if( *text == ']' )
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if( *text == ',' )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if( stricmp( text, "Shape" ) == 0 )
|
|
||||||
{
|
|
||||||
ReadShape( file, LineNum );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
D( printf( "ReadChildren error line %d <%s> \n", *LineNum, text ) );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int S3D_MASTER::ReadShape( FILE* file, int* LineNum )
|
|
||||||
{
|
|
||||||
char line[1024], * text;
|
|
||||||
int err = 1;
|
|
||||||
|
|
||||||
while( GetLine( file, line, LineNum, 512 ) )
|
|
||||||
{
|
|
||||||
text = strtok( line, sep_chars );
|
|
||||||
|
|
||||||
if( *text == '}' )
|
|
||||||
{
|
|
||||||
err = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( stricmp( text, "appearance" ) == 0 )
|
|
||||||
{
|
|
||||||
ReadAppearance( file, LineNum );
|
|
||||||
}
|
|
||||||
else if( stricmp( text, "geometry" ) == 0 )
|
|
||||||
{
|
|
||||||
ReadGeometry( file, LineNum );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
D( printf( "ReadShape error line %d <%s> \n", *LineNum, text ) );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int S3D_MASTER::ReadAppearance( FILE* file, int* LineNum )
|
|
||||||
{
|
|
||||||
char line[1024], * text;
|
|
||||||
int err = 1;
|
|
||||||
|
|
||||||
while( GetLine( file, line, LineNum, 512 ) )
|
|
||||||
{
|
|
||||||
text = strtok( line, sep_chars );
|
|
||||||
|
|
||||||
if( *text == '}' )
|
|
||||||
{
|
|
||||||
err = 0; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( stricmp( text, "material" ) == 0 )
|
|
||||||
{
|
|
||||||
ReadMaterial( file, LineNum );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
D( printf( "ReadAppearance error line %d <%s> \n", *LineNum, text ) );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#define BUFSIZE 2000
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function ReadCoordList
|
|
||||||
* reads 3D coordinate lists like:
|
|
||||||
* coord Coordinate { point [
|
|
||||||
* -5.24489 6.57640e-3 -9.42129e-2,
|
|
||||||
* -5.11821 6.57421e-3 0.542654,
|
|
||||||
* -3.45868 0.256565 1.32000 ] }
|
|
||||||
* or:
|
|
||||||
* normal Normal { vector [
|
|
||||||
* 0.995171 -6.08102e-6 9.81541e-2,
|
|
||||||
* 0.923880 -4.09802e-6 0.382683,
|
|
||||||
* 0.707107 -9.38186e-7 0.707107]
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* text_buffer contains the first line of this node :
|
|
||||||
* "coord Coordinate { point ["
|
|
||||||
*/
|
|
||||||
void ReadCoordsList( FILE* file, char* text_buffer, std::vector< double >& aList, int* LineNum )
|
|
||||||
{
|
|
||||||
unsigned int ii = 0, jj = 0;
|
|
||||||
char* text;
|
|
||||||
bool HasData = false;
|
|
||||||
bool StartData = false;
|
|
||||||
bool EndNode = false;
|
|
||||||
char string_num[512];
|
|
||||||
|
|
||||||
text = text_buffer;
|
|
||||||
|
|
||||||
while( !EndNode )
|
|
||||||
{
|
|
||||||
if( *text == 0 ) // Needs data !
|
|
||||||
{
|
|
||||||
text = text_buffer;
|
|
||||||
GetLine( file, text_buffer, LineNum, 512 );
|
|
||||||
}
|
|
||||||
|
|
||||||
while( !EndNode && *text )
|
|
||||||
{
|
|
||||||
switch( *text )
|
|
||||||
{
|
|
||||||
case '[':
|
|
||||||
StartData = true;
|
|
||||||
jj = 0;
|
|
||||||
string_num[jj] = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '}':
|
|
||||||
EndNode = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ']':
|
|
||||||
case '\t':
|
|
||||||
case ' ':
|
|
||||||
case ',':
|
|
||||||
jj = 0;
|
|
||||||
|
|
||||||
if( !StartData || !HasData )
|
|
||||||
break;
|
|
||||||
|
|
||||||
aList.push_back( atof( string_num ) );
|
|
||||||
string_num[jj] = 0;
|
|
||||||
ii++;
|
|
||||||
|
|
||||||
HasData = false;
|
|
||||||
|
|
||||||
if( *text == ']' )
|
|
||||||
{
|
|
||||||
StartData = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
if( !StartData )
|
|
||||||
break;
|
|
||||||
|
|
||||||
if( jj >= sizeof( string_num ) )
|
|
||||||
break;
|
|
||||||
|
|
||||||
string_num[jj] = *text;
|
|
||||||
jj++;
|
|
||||||
string_num[jj] = 0;
|
|
||||||
HasData = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
text++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int S3D_MASTER::ReadGeometry( FILE* file, int* LineNum )
|
|
||||||
{
|
|
||||||
char line[1024], buffer[1024], * text;
|
|
||||||
int err = 1;
|
|
||||||
std::vector< double > points;
|
|
||||||
std::vector< double > list;
|
|
||||||
double vrmlunits_to_3Dunits = g_Parm_3D_Visu.m_BiuTo3Dunits * UNITS3D_TO_UNITSPCB;
|
|
||||||
|
|
||||||
while( GetLine( file, line, LineNum, 512 ) )
|
|
||||||
{
|
|
||||||
strcpy( buffer, line );
|
|
||||||
text = strtok( buffer, sep_chars );
|
|
||||||
|
|
||||||
if( *text == '}' )
|
|
||||||
{
|
|
||||||
err = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( stricmp( text, "normalPerVertex" ) == 0 )
|
|
||||||
{
|
|
||||||
text = strtok( NULL, " ,\t\n\r" );
|
|
||||||
|
|
||||||
if( stricmp( text, "true" ) == 0 )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( stricmp( text, "colorPerVertex" ) == 0 )
|
|
||||||
{
|
|
||||||
text = strtok( NULL, " ,\t\n\r" );
|
|
||||||
|
|
||||||
if( stricmp( text, "true" ) == 0 )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( stricmp( text, "normal" ) == 0 )
|
|
||||||
{
|
|
||||||
ReadCoordsList( file, line, list, LineNum );
|
|
||||||
list.clear();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( stricmp( text, "normalIndex" ) == 0 )
|
|
||||||
{
|
|
||||||
while( GetLine( file, line, LineNum, 512 ) )
|
|
||||||
{
|
|
||||||
text = strtok( line, " ,\t\n\r" );
|
|
||||||
|
|
||||||
while( text )
|
|
||||||
{
|
|
||||||
if( *text == ']' )
|
|
||||||
break;
|
|
||||||
|
|
||||||
text = strtok( NULL, " ,\t\n\r" );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( text && (*text == ']') )
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( stricmp( text, "color" ) == 0 )
|
|
||||||
{
|
|
||||||
ReadCoordsList( file, line, list, LineNum );
|
|
||||||
list.clear();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( stricmp( text, "solid" ) == 0 )
|
|
||||||
{
|
|
||||||
// ignore solid
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( stricmp( text, "colorIndex" ) == 0 )
|
|
||||||
{
|
|
||||||
while( GetLine( file, line, LineNum, 512 ) )
|
|
||||||
{
|
|
||||||
text = strtok( line, " ,\t\n\r" );
|
|
||||||
|
|
||||||
while( text )
|
|
||||||
{
|
|
||||||
if( *text == ']' )
|
|
||||||
break;
|
|
||||||
|
|
||||||
text = strtok( NULL, " ,\t\n\r" );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( text && (*text == ']') )
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( stricmp( text, "coord" ) == 0 )
|
|
||||||
{
|
|
||||||
ReadCoordsList( file, line, points, LineNum );
|
|
||||||
}
|
|
||||||
else if( stricmp( text, "coordIndex" ) == 0 )
|
|
||||||
{
|
|
||||||
if( points.size() < 3 || points.size() % 3 != 0 )
|
|
||||||
{
|
|
||||||
wxLogError( wxT( "3D geometry read error <%s> at line %d." ),
|
|
||||||
GetChars( FROM_UTF8( text ) ), *LineNum );
|
|
||||||
err = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector< int > coordIndex;
|
|
||||||
std::vector< S3D_VERTEX > vertices;
|
|
||||||
|
|
||||||
while( GetLine( file, line, LineNum, 512 ) )
|
|
||||||
{
|
|
||||||
int jj;
|
|
||||||
text = strtok( line, " ,\t\n\r" );
|
|
||||||
|
|
||||||
while( text )
|
|
||||||
{
|
|
||||||
if( *text == ']' )
|
|
||||||
break;
|
|
||||||
|
|
||||||
jj = atoi( text );
|
|
||||||
|
|
||||||
if( jj < 0 )
|
|
||||||
{
|
|
||||||
for( jj = 0; jj < (int) coordIndex.size(); jj++ )
|
|
||||||
{
|
|
||||||
int kk = coordIndex[jj] * 3;
|
|
||||||
|
|
||||||
if( (kk < 0) || ((kk + 3) > (int)points.size()) )
|
|
||||||
{
|
|
||||||
wxLogError( wxT( "3D geometry index read error <%s> at line %d." ),
|
|
||||||
GetChars( FROM_UTF8( text ) ), *LineNum );
|
|
||||||
err = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
S3D_VERTEX vertex;
|
|
||||||
vertex.x = points[kk];
|
|
||||||
vertex.y = points[kk + 1];
|
|
||||||
vertex.z = points[kk + 2];
|
|
||||||
vertices.push_back( vertex );
|
|
||||||
}
|
|
||||||
|
|
||||||
Set_Object_Coords( vertices );
|
|
||||||
Set_Object_Data( vertices, vrmlunits_to_3Dunits );
|
|
||||||
vertices.clear();
|
|
||||||
coordIndex.clear();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
coordIndex.push_back( jj );
|
|
||||||
}
|
|
||||||
|
|
||||||
text = strtok( NULL, " ,\t\n\r" );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( text && (*text == ']') )
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
wxLogError( wxT( "3D geometry read error <%s> at line %d." ),
|
|
||||||
GetChars( FROM_UTF8( text ) ), *LineNum );
|
|
||||||
err = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int STRUCT_3D_SHAPE::ReadData( FILE* file, int* LineNum )
|
int STRUCT_3D_SHAPE::ReadData( FILE* file, int* LineNum )
|
||||||
{
|
{
|
||||||
char line[512];
|
char line[512];
|
||||||
|
|
|
@ -115,26 +115,6 @@ public:
|
||||||
|
|
||||||
void Copy( S3D_MASTER* pattern );
|
void Copy( S3D_MASTER* pattern );
|
||||||
int ReadData();
|
int ReadData();
|
||||||
|
|
||||||
/**
|
|
||||||
* Function ReadMaterial
|
|
||||||
* read the description of a 3D material definition in the form:
|
|
||||||
* DEF yellow material Material (
|
|
||||||
* DiffuseColor 1.00000 1.00000 0.00000e 0
|
|
||||||
* EmissiveColor 0.00000e 0 0.00000e 0 0.00000e 0
|
|
||||||
* SpecularColor 1.00000 1.00000 1.00000
|
|
||||||
* AmbientIntensity 1.00000
|
|
||||||
* Transparency 0.00000e 0
|
|
||||||
* Shininess 1.00000
|
|
||||||
*)
|
|
||||||
* Or type:
|
|
||||||
* USE yellow material
|
|
||||||
*/
|
|
||||||
int ReadMaterial( FILE* file, int* LineNum );
|
|
||||||
int ReadChildren( FILE* file, int* LineNum );
|
|
||||||
int ReadShape( FILE* file, int* LineNum );
|
|
||||||
int ReadAppearance( FILE* file, int* LineNum );
|
|
||||||
int ReadGeometry( FILE* file, int* LineNum );
|
|
||||||
void Set_Object_Coords( std::vector< S3D_VERTEX >& aVertices );
|
void Set_Object_Coords( std::vector< S3D_VERTEX >& aVertices );
|
||||||
|
|
||||||
#if defined(DEBUG)
|
#if defined(DEBUG)
|
||||||
|
|
|
@ -19,6 +19,8 @@ set(3D-VIEWER_SRCS
|
||||||
3d_toolbar.cpp
|
3d_toolbar.cpp
|
||||||
info3d_visu.cpp
|
info3d_visu.cpp
|
||||||
trackball.cpp
|
trackball.cpp
|
||||||
|
x3dmodelparser.cpp
|
||||||
|
vrmlmodelparser.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
add_library(3d-viewer STATIC ${3D-VIEWER_SRCS})
|
add_library(3d-viewer STATIC ${3D-VIEWER_SRCS})
|
||||||
|
|
|
@ -0,0 +1,176 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 Tuomas Vaherkoski <tuomasvaherkoski@gmail.com>
|
||||||
|
* Copyright (C) 1992-2013 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 modelparsers.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MODELPARSERS_H
|
||||||
|
#define MODELPARSERS_H
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
#include <wx/string.h>
|
||||||
|
|
||||||
|
|
||||||
|
class S3D_MASTER;
|
||||||
|
class S3D_VERTEX;
|
||||||
|
|
||||||
|
extern void Set_Object_Data( std::vector< S3D_VERTEX >& aVertices, double aBiuTo3DUnits );
|
||||||
|
|
||||||
|
class S3D_MODEL_PARSER;
|
||||||
|
class X3D_MODEL_PARSER;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* abstract class S3D_MODEL_PARSER
|
||||||
|
* Base class for 3D model parsers.
|
||||||
|
*/
|
||||||
|
class S3D_MODEL_PARSER
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
S3D_MODEL_PARSER(S3D_MASTER* aMaster)
|
||||||
|
:master(aMaster)
|
||||||
|
{}
|
||||||
|
|
||||||
|
virtual ~S3D_MODEL_PARSER()
|
||||||
|
{}
|
||||||
|
|
||||||
|
S3D_MASTER* GetMaster()
|
||||||
|
{
|
||||||
|
return master;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function Create
|
||||||
|
* Factory method for creating concrete 3D model parsers
|
||||||
|
* Notice that the caller is responible to delete created parser.
|
||||||
|
*
|
||||||
|
* @param aMaster is master object that the parser will fill.
|
||||||
|
* @param aExtension is file extension of the file you are going to parse.
|
||||||
|
*/
|
||||||
|
static S3D_MODEL_PARSER* Create( S3D_MASTER* aMaster,
|
||||||
|
const wxString aExtension );
|
||||||
|
/**
|
||||||
|
* Function Load
|
||||||
|
*
|
||||||
|
* Concrete parsers should implement this function
|
||||||
|
*/
|
||||||
|
virtual void Load(const wxString aFilename) = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
S3D_MASTER* master;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class wxXmlNode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* class X3D_MODEL_PARSER
|
||||||
|
* Implements parser for X3D file format (VRML2.0 successor)
|
||||||
|
* X3D files can be exported from eg. Blender */
|
||||||
|
class X3D_MODEL_PARSER: public S3D_MODEL_PARSER
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
X3D_MODEL_PARSER(S3D_MASTER* aMaster);
|
||||||
|
~X3D_MODEL_PARSER();
|
||||||
|
void Load(const wxString aFilename);
|
||||||
|
|
||||||
|
typedef std::map< wxString, wxString > PROPERTY_MAP;
|
||||||
|
typedef std::vector< wxXmlNode* > NODE_LIST;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function GetChildsByName
|
||||||
|
* Searches all child nodes with aName.
|
||||||
|
*
|
||||||
|
* @param aParent is node to search from
|
||||||
|
* @param aName is the name of node you try to find
|
||||||
|
* @param aResult contains found nodes
|
||||||
|
*/
|
||||||
|
static void GetChildsByName(wxXmlNode* aParent, const wxString aName,
|
||||||
|
NODE_LIST& aResult);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function GetNodeProperties
|
||||||
|
* Collects all node properties to map.
|
||||||
|
*
|
||||||
|
* @param aProps contains map of found properties
|
||||||
|
*/
|
||||||
|
static void GetNodeProperties(wxXmlNode* aNode, PROPERTY_MAP& aProps);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return string representing x3d file in vrml format
|
||||||
|
* Function Load must be called before this function, otherwise empty
|
||||||
|
* data set is returned.
|
||||||
|
*/
|
||||||
|
wxString VRML_representation();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<wxString> vrml_materials;
|
||||||
|
std::vector<wxString> vrml_points;
|
||||||
|
std::vector<wxString> vrml_coord_indexes;
|
||||||
|
|
||||||
|
void readTransform( wxXmlNode* aTransformNode );
|
||||||
|
void readMaterial( wxXmlNode* aMatNode );
|
||||||
|
void readIndexedFaceSet( wxXmlNode* aFaceNode,
|
||||||
|
PROPERTY_MAP& aTransfromProps );
|
||||||
|
bool parseDoubleTriplet( const wxString& aData, S3D_VERTEX& aResult );
|
||||||
|
|
||||||
|
void rotate( S3D_VERTEX& aCoordinate, S3D_VERTEX& aRotAxis, double angle);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* class WRL_MODEL_PARSER
|
||||||
|
* Parses
|
||||||
|
*/
|
||||||
|
class VRML_MODEL_PARSER: public S3D_MODEL_PARSER
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
VRML_MODEL_PARSER(S3D_MASTER* aMaster);
|
||||||
|
~VRML_MODEL_PARSER();
|
||||||
|
void Load(const wxString aFilename);
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Function ReadMaterial
|
||||||
|
* read the description of a 3D material definition in the form:
|
||||||
|
* DEF yellow material Material (
|
||||||
|
* DiffuseColor 1.00000 1.00000 0.00000e 0
|
||||||
|
* EmissiveColor 0.00000e 0 0.00000e 0 0.00000e 0
|
||||||
|
* SpecularColor 1.00000 1.00000 1.00000
|
||||||
|
* AmbientIntensity 1.00000
|
||||||
|
* Transparency 0.00000e 0
|
||||||
|
* Shininess 1.00000
|
||||||
|
*)
|
||||||
|
* Or type:
|
||||||
|
* USE yellow material
|
||||||
|
*/
|
||||||
|
int readMaterial( FILE* file, int* LineNum );
|
||||||
|
int readChildren( FILE* file, int* LineNum );
|
||||||
|
int readShape( FILE* file, int* LineNum );
|
||||||
|
int readAppearance( FILE* file, int* LineNum );
|
||||||
|
int readGeometry( FILE* file, int* LineNum );
|
||||||
|
void readCoordsList( FILE* file, char* text_buffer, std::vector< double >& aList, int* LineNum );
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MODELPARSERS_H
|
|
@ -0,0 +1,557 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* 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-2011 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 vrmlmodelparser.cpp
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <fctsys.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <macros.h>
|
||||||
|
#include <kicad_string.h>
|
||||||
|
#include <info3d_visu.h>
|
||||||
|
|
||||||
|
#include "3d_struct.h"
|
||||||
|
#include "modelparsers.h"
|
||||||
|
|
||||||
|
// separator chars
|
||||||
|
static const char* sep_chars = " \t\n\r";
|
||||||
|
|
||||||
|
VRML_MODEL_PARSER::VRML_MODEL_PARSER(S3D_MASTER* aMaster)
|
||||||
|
:S3D_MODEL_PARSER(aMaster)
|
||||||
|
{}
|
||||||
|
|
||||||
|
VRML_MODEL_PARSER::~VRML_MODEL_PARSER()
|
||||||
|
{}
|
||||||
|
|
||||||
|
void VRML_MODEL_PARSER::Load(const wxString aFilename)
|
||||||
|
{
|
||||||
|
char line[1024], * text;
|
||||||
|
FILE* file;
|
||||||
|
int LineNum = 0;
|
||||||
|
|
||||||
|
file = wxFopen( aFilename, wxT( "rt" ) );
|
||||||
|
|
||||||
|
if( file == NULL )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Switch the locale to standard C (needed to print floating point numbers like 1.3)
|
||||||
|
SetLocaleTo_C_standard();
|
||||||
|
|
||||||
|
while( GetLine( file, line, &LineNum, 512 ) )
|
||||||
|
{
|
||||||
|
text = strtok( line, sep_chars );
|
||||||
|
|
||||||
|
if( stricmp( text, "DEF" ) == 0 || stricmp( text, "Group" ) == 0)
|
||||||
|
{
|
||||||
|
while( GetLine( file, line, &LineNum, 512 ) )
|
||||||
|
{
|
||||||
|
text = strtok( line, sep_chars );
|
||||||
|
|
||||||
|
if( text == NULL )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if( *text == '}' )
|
||||||
|
break;
|
||||||
|
|
||||||
|
if( stricmp( text, "children" ) == 0 )
|
||||||
|
{
|
||||||
|
readChildren( file, &LineNum );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose( file );
|
||||||
|
SetLocaleTo_Default(); // revert to the current locale
|
||||||
|
}
|
||||||
|
|
||||||
|
int VRML_MODEL_PARSER::readMaterial( FILE* file, int* LineNum )
|
||||||
|
{
|
||||||
|
char line[512], * text, * command;
|
||||||
|
wxString mat_name;
|
||||||
|
S3D_MATERIAL* material = NULL;
|
||||||
|
|
||||||
|
command = strtok( NULL, sep_chars );
|
||||||
|
text = strtok( NULL, sep_chars );
|
||||||
|
mat_name = FROM_UTF8( text );
|
||||||
|
|
||||||
|
if( stricmp( command, "USE" ) == 0 )
|
||||||
|
{
|
||||||
|
for( material = GetMaster()->m_Materials; material; material = material->Next() )
|
||||||
|
{
|
||||||
|
if( material->m_Name == mat_name )
|
||||||
|
{
|
||||||
|
material->SetMaterial();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
D( printf( "ReadMaterial error: material not found\n" ) );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( stricmp( command, "DEF" ) == 0 || stricmp( command, "Material") == 0)
|
||||||
|
{
|
||||||
|
material = new S3D_MATERIAL( GetMaster(), mat_name );
|
||||||
|
|
||||||
|
GetMaster()->Insert( material );
|
||||||
|
|
||||||
|
while( GetLine( file, line, LineNum, 512 ) )
|
||||||
|
{
|
||||||
|
text = strtok( line, sep_chars );
|
||||||
|
|
||||||
|
if( text == NULL )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if( text[0] == '}' )
|
||||||
|
{
|
||||||
|
material->SetMaterial();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( stricmp( text, "diffuseColor" ) == 0 )
|
||||||
|
{
|
||||||
|
text = strtok( NULL, sep_chars );
|
||||||
|
material->m_DiffuseColor.x = atof( text );
|
||||||
|
text = strtok( NULL, sep_chars );
|
||||||
|
material->m_DiffuseColor.y = atof( text );
|
||||||
|
text = strtok( NULL, sep_chars );
|
||||||
|
material->m_DiffuseColor.z = atof( text );
|
||||||
|
}
|
||||||
|
else if( stricmp( text, "emissiveColor" ) == 0 )
|
||||||
|
{
|
||||||
|
text = strtok( NULL, sep_chars );
|
||||||
|
material->m_EmissiveColor.x = atof( text );
|
||||||
|
text = strtok( NULL, sep_chars );
|
||||||
|
material->m_EmissiveColor.y = atof( text );
|
||||||
|
text = strtok( NULL, sep_chars );
|
||||||
|
material->m_EmissiveColor.z = atof( text );
|
||||||
|
}
|
||||||
|
else if( strnicmp( text, "specularColor", 13 ) == 0 )
|
||||||
|
{
|
||||||
|
text = strtok( NULL, sep_chars );
|
||||||
|
material->m_SpecularColor.x = atof( text );
|
||||||
|
text = strtok( NULL, sep_chars );
|
||||||
|
material->m_SpecularColor.y = atof( text );
|
||||||
|
text = strtok( NULL, sep_chars );
|
||||||
|
material->m_SpecularColor.z = atof( text );
|
||||||
|
}
|
||||||
|
else if( strnicmp( text, "ambientIntensity", 16 ) == 0 )
|
||||||
|
{
|
||||||
|
text = strtok( NULL, sep_chars );
|
||||||
|
material->m_AmbientIntensity = atof( text );
|
||||||
|
}
|
||||||
|
else if( strnicmp( text, "transparency", 12 ) == 0 )
|
||||||
|
{
|
||||||
|
text = strtok( NULL, sep_chars );
|
||||||
|
material->m_Transparency = atof( text );
|
||||||
|
}
|
||||||
|
else if( strnicmp( text, "shininess", 9 ) == 0 )
|
||||||
|
{
|
||||||
|
text = strtok( NULL, sep_chars );
|
||||||
|
material->m_Shininess = atof( text );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int VRML_MODEL_PARSER::readChildren( FILE* file, int* LineNum )
|
||||||
|
{
|
||||||
|
char line[1024], * text;
|
||||||
|
|
||||||
|
while( GetLine( file, line, LineNum, 512 ) )
|
||||||
|
{
|
||||||
|
text = strtok( line, sep_chars );
|
||||||
|
|
||||||
|
if( *text == ']' )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if( *text == ',' )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if( stricmp( text, "Shape" ) == 0 )
|
||||||
|
{
|
||||||
|
readShape( file, LineNum );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
D( printf( "ReadChildren error line %d <%s> \n", *LineNum, text ) );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int VRML_MODEL_PARSER::readShape( FILE* file, int* LineNum )
|
||||||
|
{
|
||||||
|
char line[1024], * text;
|
||||||
|
int err = 1;
|
||||||
|
|
||||||
|
while( GetLine( file, line, LineNum, 512 ) )
|
||||||
|
{
|
||||||
|
text = strtok( line, sep_chars );
|
||||||
|
|
||||||
|
if( *text == '}' )
|
||||||
|
{
|
||||||
|
err = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( stricmp( text, "appearance" ) == 0 )
|
||||||
|
{
|
||||||
|
readAppearance( file, LineNum );
|
||||||
|
}
|
||||||
|
else if( stricmp( text, "geometry" ) == 0 )
|
||||||
|
{
|
||||||
|
readGeometry( file, LineNum );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
D( printf( "ReadShape error line %d <%s> \n", *LineNum, text ) );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int VRML_MODEL_PARSER::readAppearance( FILE* file, int* LineNum )
|
||||||
|
{
|
||||||
|
char line[1024], * text;
|
||||||
|
int err = 1;
|
||||||
|
|
||||||
|
while( GetLine( file, line, LineNum, 512 ) )
|
||||||
|
{
|
||||||
|
text = strtok( line, sep_chars );
|
||||||
|
|
||||||
|
if( *text == '}' )
|
||||||
|
{
|
||||||
|
err = 0; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( stricmp( text, "material" ) == 0 )
|
||||||
|
{
|
||||||
|
readMaterial( file, LineNum );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
D( printf( "ReadAppearance error line %d <%s> \n", *LineNum, text ) );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define BUFSIZE 2000
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function ReadCoordList
|
||||||
|
* reads 3D coordinate lists like:
|
||||||
|
* coord Coordinate { point [
|
||||||
|
* -5.24489 6.57640e-3 -9.42129e-2,
|
||||||
|
* -5.11821 6.57421e-3 0.542654,
|
||||||
|
* -3.45868 0.256565 1.32000 ] }
|
||||||
|
* or:
|
||||||
|
* normal Normal { vector [
|
||||||
|
* 0.995171 -6.08102e-6 9.81541e-2,
|
||||||
|
* 0.923880 -4.09802e-6 0.382683,
|
||||||
|
* 0.707107 -9.38186e-7 0.707107]
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* text_buffer contains the first line of this node :
|
||||||
|
* "coord Coordinate { point ["
|
||||||
|
*/
|
||||||
|
void VRML_MODEL_PARSER::readCoordsList( FILE* file, char* text_buffer, std::vector< double >& aList, int* LineNum )
|
||||||
|
{
|
||||||
|
unsigned int ii = 0, jj = 0;
|
||||||
|
char* text;
|
||||||
|
bool HasData = false;
|
||||||
|
bool StartData = false;
|
||||||
|
bool EndNode = false;
|
||||||
|
char string_num[512];
|
||||||
|
|
||||||
|
text = text_buffer;
|
||||||
|
|
||||||
|
while( !EndNode )
|
||||||
|
{
|
||||||
|
if( *text == 0 ) // Needs data !
|
||||||
|
{
|
||||||
|
text = text_buffer;
|
||||||
|
GetLine( file, text_buffer, LineNum, 512 );
|
||||||
|
}
|
||||||
|
|
||||||
|
while( !EndNode && *text )
|
||||||
|
{
|
||||||
|
switch( *text )
|
||||||
|
{
|
||||||
|
case '[':
|
||||||
|
StartData = true;
|
||||||
|
jj = 0;
|
||||||
|
string_num[jj] = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '}':
|
||||||
|
EndNode = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ']':
|
||||||
|
case '\t':
|
||||||
|
case ' ':
|
||||||
|
case ',':
|
||||||
|
jj = 0;
|
||||||
|
|
||||||
|
if( !StartData || !HasData )
|
||||||
|
break;
|
||||||
|
|
||||||
|
aList.push_back( atof( string_num ) );
|
||||||
|
string_num[jj] = 0;
|
||||||
|
ii++;
|
||||||
|
|
||||||
|
HasData = false;
|
||||||
|
|
||||||
|
if( *text == ']' )
|
||||||
|
{
|
||||||
|
StartData = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if( !StartData )
|
||||||
|
break;
|
||||||
|
|
||||||
|
if( jj >= sizeof( string_num ) )
|
||||||
|
break;
|
||||||
|
|
||||||
|
string_num[jj] = *text;
|
||||||
|
jj++;
|
||||||
|
string_num[jj] = 0;
|
||||||
|
HasData = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
text++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int VRML_MODEL_PARSER::readGeometry( FILE* file, int* LineNum )
|
||||||
|
{
|
||||||
|
char line[1024], buffer[1024], * text;
|
||||||
|
int err = 1;
|
||||||
|
std::vector< double > points;
|
||||||
|
std::vector< double > list;
|
||||||
|
double vrmlunits_to_3Dunits = g_Parm_3D_Visu.m_BiuTo3Dunits * UNITS3D_TO_UNITSPCB;
|
||||||
|
|
||||||
|
while( GetLine( file, line, LineNum, 512 ) )
|
||||||
|
{
|
||||||
|
strcpy( buffer, line );
|
||||||
|
text = strtok( buffer, sep_chars );
|
||||||
|
|
||||||
|
if( *text == '}' )
|
||||||
|
{
|
||||||
|
err = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( stricmp( text, "normalPerVertex" ) == 0 )
|
||||||
|
{
|
||||||
|
text = strtok( NULL, " ,\t\n\r" );
|
||||||
|
|
||||||
|
if( stricmp( text, "true" ) == 0 )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( stricmp( text, "colorPerVertex" ) == 0 )
|
||||||
|
{
|
||||||
|
text = strtok( NULL, " ,\t\n\r" );
|
||||||
|
|
||||||
|
if( stricmp( text, "true" ) == 0 )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( stricmp( text, "normal" ) == 0 )
|
||||||
|
{
|
||||||
|
readCoordsList( file, line, list, LineNum );
|
||||||
|
list.clear();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( stricmp( text, "normalIndex" ) == 0 )
|
||||||
|
{
|
||||||
|
while( GetLine( file, line, LineNum, 512 ) )
|
||||||
|
{
|
||||||
|
text = strtok( line, " ,\t\n\r" );
|
||||||
|
|
||||||
|
while( text )
|
||||||
|
{
|
||||||
|
if( *text == ']' )
|
||||||
|
break;
|
||||||
|
|
||||||
|
text = strtok( NULL, " ,\t\n\r" );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( text && (*text == ']') )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( stricmp( text, "color" ) == 0 )
|
||||||
|
{
|
||||||
|
readCoordsList( file, line, list, LineNum );
|
||||||
|
list.clear();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( stricmp( text, "solid" ) == 0 )
|
||||||
|
{
|
||||||
|
// ignore solid
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( stricmp( text, "colorIndex" ) == 0 )
|
||||||
|
{
|
||||||
|
while( GetLine( file, line, LineNum, 512 ) )
|
||||||
|
{
|
||||||
|
text = strtok( line, " ,\t\n\r" );
|
||||||
|
|
||||||
|
while( text )
|
||||||
|
{
|
||||||
|
if( *text == ']' )
|
||||||
|
break;
|
||||||
|
|
||||||
|
text = strtok( NULL, " ,\t\n\r" );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( text && (*text == ']') )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( stricmp( text, "coord" ) == 0 )
|
||||||
|
{
|
||||||
|
readCoordsList( file, line, points, LineNum );
|
||||||
|
}
|
||||||
|
else if( stricmp( text, "coordIndex" ) == 0 )
|
||||||
|
{
|
||||||
|
if( points.size() < 3 || points.size() % 3 != 0 )
|
||||||
|
{
|
||||||
|
wxLogError( wxT( "3D geometry read error <%s> at line %d." ),
|
||||||
|
GetChars( FROM_UTF8( text ) ), *LineNum );
|
||||||
|
err = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector< int > coordIndex;
|
||||||
|
std::vector< S3D_VERTEX > vertices;
|
||||||
|
|
||||||
|
while( GetLine( file, line, LineNum, 512 ) )
|
||||||
|
{
|
||||||
|
int jj;
|
||||||
|
text = strtok( line, " ,\t\n\r" );
|
||||||
|
|
||||||
|
while( text )
|
||||||
|
{
|
||||||
|
if( *text == ']' )
|
||||||
|
break;
|
||||||
|
|
||||||
|
jj = atoi( text );
|
||||||
|
|
||||||
|
if( jj < 0 )
|
||||||
|
{
|
||||||
|
for( jj = 0; jj < (int) coordIndex.size(); jj++ )
|
||||||
|
{
|
||||||
|
int kk = coordIndex[jj] * 3;
|
||||||
|
|
||||||
|
if( (kk < 0) || ((kk + 3) > (int)points.size()) )
|
||||||
|
{
|
||||||
|
wxLogError( wxT( "3D geometry index read error <%s> at line %d." ),
|
||||||
|
GetChars( FROM_UTF8( text ) ), *LineNum );
|
||||||
|
err = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
S3D_VERTEX vertex;
|
||||||
|
vertex.x = points[kk];
|
||||||
|
vertex.y = points[kk + 1];
|
||||||
|
vertex.z = points[kk + 2];
|
||||||
|
vertices.push_back( vertex );
|
||||||
|
}
|
||||||
|
|
||||||
|
GetMaster()->Set_Object_Coords( vertices );
|
||||||
|
Set_Object_Data( vertices, vrmlunits_to_3Dunits );
|
||||||
|
vertices.clear();
|
||||||
|
coordIndex.clear();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
coordIndex.push_back( jj );
|
||||||
|
}
|
||||||
|
|
||||||
|
text = strtok( NULL, " ,\t\n\r" );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( text && (*text == ']') )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wxLogError( wxT( "3D geometry read error <%s> at line %d." ),
|
||||||
|
GetChars( FROM_UTF8( text ) ), *LineNum );
|
||||||
|
err = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
|
@ -0,0 +1,458 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 Tuomas Vaherkoski <tuomasvaherkoski@gmail.com>
|
||||||
|
* Copyright (C) 1992-2013 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 x3dmodelparser.cpp
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <fctsys.h>
|
||||||
|
#include <macros.h>
|
||||||
|
#include <info3d_visu.h>
|
||||||
|
#include <wx/xml/xml.h>
|
||||||
|
#include <wx/tokenzr.h>
|
||||||
|
#include <wx/string.h>
|
||||||
|
#include <map>
|
||||||
|
#include <queue>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "3d_struct.h"
|
||||||
|
#include "modelparsers.h"
|
||||||
|
|
||||||
|
X3D_MODEL_PARSER::X3D_MODEL_PARSER( S3D_MASTER* aMaster )
|
||||||
|
:S3D_MODEL_PARSER( aMaster )
|
||||||
|
{}
|
||||||
|
|
||||||
|
X3D_MODEL_PARSER::~X3D_MODEL_PARSER()
|
||||||
|
{}
|
||||||
|
|
||||||
|
void X3D_MODEL_PARSER::Load( const wxString aFilename )
|
||||||
|
{
|
||||||
|
wxXmlDocument doc;
|
||||||
|
if( !doc.Load( aFilename ) )
|
||||||
|
{
|
||||||
|
wxLogError( wxT( "Error while parsing file <%s>" ), GetChars( aFilename ) );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( doc.GetRoot()->GetName() != wxT( "X3D" ) )
|
||||||
|
{
|
||||||
|
wxLogError( wxT( "Filetype is not X3D <%s>" ), GetChars( aFilename ) );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shapes are inside of Transform nodes
|
||||||
|
// Transform node contains information about
|
||||||
|
// transition, scale and rotation of the shape
|
||||||
|
NODE_LIST transforms;
|
||||||
|
GetChildsByName( doc.GetRoot(), wxT( "Transform" ), transforms );
|
||||||
|
for( NODE_LIST::iterator node_it = transforms.begin();
|
||||||
|
node_it != transforms.end();
|
||||||
|
node_it++ )
|
||||||
|
{
|
||||||
|
readTransform( *node_it );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wxString X3D_MODEL_PARSER::VRML_representation()
|
||||||
|
{
|
||||||
|
wxString output;
|
||||||
|
for( unsigned i = 0; i < vrml_points.size(); i++ )
|
||||||
|
{
|
||||||
|
output += wxT("Shape {\n"
|
||||||
|
" appearance Appearance {\n"
|
||||||
|
" material Material {\n" ) +
|
||||||
|
vrml_materials[i] +
|
||||||
|
wxT(" }\n"
|
||||||
|
" }\n"
|
||||||
|
" geometry IndexedFaceSet {\n"
|
||||||
|
" solid TRUE\n"
|
||||||
|
" coord Coordinate {\n"
|
||||||
|
" point [\n") +
|
||||||
|
vrml_points[i] +
|
||||||
|
wxT( " ]\n"
|
||||||
|
" }\n"
|
||||||
|
" coordIndex [\n" ) +
|
||||||
|
vrml_coord_indexes[i] +
|
||||||
|
wxT(" ]\n"
|
||||||
|
" }\n"
|
||||||
|
"},\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
void X3D_MODEL_PARSER::GetChildsByName( wxXmlNode* aParent,
|
||||||
|
const wxString aName,
|
||||||
|
std::vector< wxXmlNode* >& aResult )
|
||||||
|
{
|
||||||
|
// Breadth-first search (BFS)
|
||||||
|
std::queue< wxXmlNode* > found;
|
||||||
|
found.push( aParent );
|
||||||
|
while( !found.empty() )
|
||||||
|
{
|
||||||
|
wxXmlNode *elem = found.front();
|
||||||
|
for( wxXmlNode *child = elem->GetChildren();
|
||||||
|
child != NULL;
|
||||||
|
child = child->GetNext() )
|
||||||
|
{
|
||||||
|
if( child->GetName() == aName)
|
||||||
|
{
|
||||||
|
aResult.push_back( child );
|
||||||
|
}
|
||||||
|
found.push( child );
|
||||||
|
}
|
||||||
|
found.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void X3D_MODEL_PARSER::GetNodeProperties( wxXmlNode* aNode, PROPERTY_MAP& aProps ) {
|
||||||
|
wxXmlProperty *prop;
|
||||||
|
for( prop = aNode->GetProperties();
|
||||||
|
prop != NULL;
|
||||||
|
prop = prop->GetNext() )
|
||||||
|
{
|
||||||
|
aProps[ prop->GetName() ] = prop->GetValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Private ----- */
|
||||||
|
|
||||||
|
void X3D_MODEL_PARSER::readTransform( wxXmlNode* aTransformNode )
|
||||||
|
{
|
||||||
|
NODE_LIST childnodes;
|
||||||
|
GetChildsByName( aTransformNode, wxT( "Material" ), childnodes );
|
||||||
|
|
||||||
|
for( NODE_LIST::iterator node = childnodes.begin();
|
||||||
|
node != childnodes.end();
|
||||||
|
node++ )
|
||||||
|
{
|
||||||
|
readMaterial( *node );
|
||||||
|
}
|
||||||
|
childnodes.clear();
|
||||||
|
|
||||||
|
PROPERTY_MAP properties;
|
||||||
|
GetNodeProperties( aTransformNode, properties );
|
||||||
|
GetChildsByName( aTransformNode, wxT("IndexedFaceSet"), childnodes );
|
||||||
|
for( NODE_LIST::iterator node = childnodes.begin();
|
||||||
|
node != childnodes.end();
|
||||||
|
node++ )
|
||||||
|
{
|
||||||
|
readIndexedFaceSet( *node, properties );
|
||||||
|
}
|
||||||
|
childnodes.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void X3D_MODEL_PARSER::readMaterial( wxXmlNode* aMatNode )
|
||||||
|
{
|
||||||
|
PROPERTY_MAP properties;
|
||||||
|
GetNodeProperties( aMatNode, properties );
|
||||||
|
|
||||||
|
// DEFine new Material named as value of DEF
|
||||||
|
if( properties.find( wxT( "DEF" ) ) != properties.end() ) {
|
||||||
|
double amb, shine, transp;
|
||||||
|
|
||||||
|
S3D_MATERIAL* material = new S3D_MATERIAL( GetMaster(), properties[ wxT( "DEF" ) ] );
|
||||||
|
GetMaster()->Insert( material );
|
||||||
|
|
||||||
|
if( !parseDoubleTriplet( properties[ wxT( "diffuseColor" ) ],
|
||||||
|
material->m_DiffuseColor) )
|
||||||
|
{
|
||||||
|
D( printf("diffuseColor parsing error") );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !parseDoubleTriplet( properties[ wxT( "specularColor" ) ],
|
||||||
|
material->m_SpecularColor ) )
|
||||||
|
{
|
||||||
|
D( printf("specularColor parsing error") );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !parseDoubleTriplet( properties[ wxT( "emissiveColor" ) ],
|
||||||
|
material->m_EmissiveColor ) )
|
||||||
|
{
|
||||||
|
D( printf("emissiveColor parsing error") );
|
||||||
|
}
|
||||||
|
|
||||||
|
wxStringTokenizer values;
|
||||||
|
values.SetString( properties[ wxT( "ambientIntensity" ) ] );
|
||||||
|
if( values.GetNextToken().ToDouble( &amb ) )
|
||||||
|
{
|
||||||
|
material->m_AmbientIntensity = amb;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
D( printf("ambienterror") );
|
||||||
|
}
|
||||||
|
|
||||||
|
values.SetString( properties[ wxT( "shininess" ) ] );
|
||||||
|
if( values.GetNextToken().ToDouble(&shine) )
|
||||||
|
{
|
||||||
|
material->m_Shininess = shine;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
D( printf( "shininess error" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
values.SetString( properties[ wxT( "transparency" ) ] );
|
||||||
|
if( values.GetNextToken().ToDouble(&transp) )
|
||||||
|
{
|
||||||
|
material->m_Transparency = transp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
D( printf( "trans error") );
|
||||||
|
}
|
||||||
|
|
||||||
|
material->SetMaterial();
|
||||||
|
|
||||||
|
// VRML
|
||||||
|
wxString vrml_material;
|
||||||
|
PROPERTY_MAP::const_iterator p = ++properties.begin(); // skip DEF
|
||||||
|
for(;p != properties.end();p++) {
|
||||||
|
vrml_material.Append( p->first + wxT(" ") + p->second + wxT("\n") );
|
||||||
|
}
|
||||||
|
|
||||||
|
vrml_materials.push_back(vrml_material);
|
||||||
|
}
|
||||||
|
|
||||||
|
// USE existing material named by value of USE
|
||||||
|
else if( properties.find( wxT( "USE" ) ) != properties.end() ) {
|
||||||
|
S3D_MATERIAL* material = NULL;
|
||||||
|
wxString mat_name = properties[ wxT( "USE" ) ];
|
||||||
|
|
||||||
|
for( material = GetMaster()->m_Materials; material; material = material->Next() )
|
||||||
|
{
|
||||||
|
if( material->m_Name == mat_name )
|
||||||
|
{
|
||||||
|
|
||||||
|
wxString vrml_material;
|
||||||
|
vrml_material.Append( wxString::Format( wxT( "specularColor %f %f %f\n"),
|
||||||
|
material->m_SpecularColor.x,
|
||||||
|
material->m_SpecularColor.y,
|
||||||
|
material->m_SpecularColor.z) );
|
||||||
|
|
||||||
|
vrml_material.Append( wxString::Format( wxT( "diffuseColor %f %f %f\n"),
|
||||||
|
material->m_DiffuseColor.x,
|
||||||
|
material->m_DiffuseColor.y,
|
||||||
|
material->m_DiffuseColor.z) );
|
||||||
|
|
||||||
|
vrml_material.Append( wxString::Format( wxT( "emissiveColor %f %f %f\n"),
|
||||||
|
material->m_EmissiveColor.x,
|
||||||
|
material->m_EmissiveColor.y,
|
||||||
|
material->m_EmissiveColor.z) );
|
||||||
|
|
||||||
|
vrml_material.Append( wxString::Format( wxT( "ambientIntensity %f\n"),
|
||||||
|
material->m_AmbientIntensity) );
|
||||||
|
|
||||||
|
vrml_material.Append( wxString::Format( wxT( "shininess %f\n"),
|
||||||
|
material->m_Shininess) );
|
||||||
|
|
||||||
|
vrml_material.Append( wxString::Format( wxT( "transparency %f\n"),
|
||||||
|
material->m_Transparency) );
|
||||||
|
|
||||||
|
vrml_materials.push_back(vrml_material);
|
||||||
|
|
||||||
|
|
||||||
|
material->SetMaterial();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
D( printf( "ReadMaterial error: material not found\n" ) );
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool X3D_MODEL_PARSER::parseDoubleTriplet( const wxString& aData,
|
||||||
|
S3D_VERTEX& aResult )
|
||||||
|
{
|
||||||
|
wxStringTokenizer tokens(aData);
|
||||||
|
return tokens.GetNextToken().ToDouble( &aResult.x ) &&
|
||||||
|
tokens.GetNextToken().ToDouble( &aResult.y ) &&
|
||||||
|
tokens.GetNextToken().ToDouble( &aResult.z );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void X3D_MODEL_PARSER::rotate( S3D_VERTEX& aV,
|
||||||
|
S3D_VERTEX& aU,
|
||||||
|
double angle)
|
||||||
|
{
|
||||||
|
S3D_VERTEX rotated;
|
||||||
|
double C = cos(angle);
|
||||||
|
double S = sin(angle);
|
||||||
|
double t = 1.0 - C;
|
||||||
|
|
||||||
|
rotated.x = ( t * aU.x * aU.x + C ) * aV.x +
|
||||||
|
( t * aU.x * aU.y - S * aU.z ) * aV.y +
|
||||||
|
( t * aU.x * aU.z + S * aU.y ) * aV.z;
|
||||||
|
|
||||||
|
rotated.y = ( t * aU.x * aU.y + S * aU.z ) * aV.x +
|
||||||
|
( t * aU.y * aU.y + C ) * aV.y +
|
||||||
|
( t * aU.y * aU.z - S * aU.x ) * aV.z;
|
||||||
|
|
||||||
|
rotated.z = ( t * aU.x * aU.z - S * aU.y ) * aV.x +
|
||||||
|
( t * aU.y * aU.z + S * aU.x ) * aV.y +
|
||||||
|
( t * aU.z * aU.z + C) * aV.z;
|
||||||
|
|
||||||
|
aV.x = rotated.x;
|
||||||
|
aV.y = rotated.y;
|
||||||
|
aV.z = rotated.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Steps:
|
||||||
|
* 1. Read transform data
|
||||||
|
* 2. Read vectex triplets
|
||||||
|
* 3. Read coordinate indexes
|
||||||
|
* 4. Apply geometry to Master object
|
||||||
|
*/
|
||||||
|
void X3D_MODEL_PARSER::readIndexedFaceSet( wxXmlNode* aFaceNode,
|
||||||
|
PROPERTY_MAP& aTransformProps)
|
||||||
|
{
|
||||||
|
/* Step 1: Read transform data
|
||||||
|
* --------------------------- */
|
||||||
|
|
||||||
|
S3D_VERTEX translation;
|
||||||
|
parseDoubleTriplet( aTransformProps[ wxT( "translation" ) ],
|
||||||
|
translation );
|
||||||
|
|
||||||
|
S3D_VERTEX scale;
|
||||||
|
parseDoubleTriplet( aTransformProps[ wxT( "scale" ) ], scale );
|
||||||
|
|
||||||
|
S3D_VERTEX rotation;
|
||||||
|
double angle = 0.0;
|
||||||
|
wxStringTokenizer tokens(aTransformProps[ wxT( "rotation" ) ]);
|
||||||
|
if( !(tokens.GetNextToken().ToDouble( &rotation.x ) &&
|
||||||
|
tokens.GetNextToken().ToDouble( &rotation.y ) &&
|
||||||
|
tokens.GetNextToken().ToDouble( &rotation.z ) &&
|
||||||
|
tokens.GetNextToken().ToDouble( &angle ) ) )
|
||||||
|
{
|
||||||
|
D( printf("rotation read error") );
|
||||||
|
}
|
||||||
|
|
||||||
|
double vrmlunits_to_3Dunits = g_Parm_3D_Visu.m_BiuTo3Dunits *
|
||||||
|
UNITS3D_TO_UNITSPCB;
|
||||||
|
|
||||||
|
/* Step 2: Read all coordinate points
|
||||||
|
* ---------------------------- */
|
||||||
|
std::vector< double > points;
|
||||||
|
NODE_LIST coordinates;
|
||||||
|
GetChildsByName( aFaceNode, wxT( "Coordinate" ), coordinates);
|
||||||
|
|
||||||
|
PROPERTY_MAP coordinate_properties;
|
||||||
|
// IndexedFaceSet has one Coordinate child node
|
||||||
|
GetNodeProperties( coordinates[0], coordinate_properties );
|
||||||
|
|
||||||
|
// Save points to vector as doubles
|
||||||
|
wxStringTokenizer point_tokens( coordinate_properties[ wxT("point") ] );
|
||||||
|
double point = 0.0;
|
||||||
|
while( point_tokens.HasMoreTokens() )
|
||||||
|
{
|
||||||
|
if( point_tokens.GetNextToken().ToDouble( &point ) )
|
||||||
|
{
|
||||||
|
points.push_back( point );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wxLogError( wxT( "Error converting to double" ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(points.size() % 3 != 0) {
|
||||||
|
D( printf("Number of points is incorrect") );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create 3D vertex from 3 points and
|
||||||
|
* apply tansforms in order of SCALE, ROTATION, TRANSLATION
|
||||||
|
*/
|
||||||
|
wxString vrml_pointlist;
|
||||||
|
std::vector< S3D_VERTEX > triplets;
|
||||||
|
for( unsigned id = 0; id < points.size() / 3; id++ )
|
||||||
|
{
|
||||||
|
int triplet_indx = id * 3;
|
||||||
|
S3D_VERTEX point( points[ triplet_indx ],
|
||||||
|
points[ triplet_indx + 1 ],
|
||||||
|
points[ triplet_indx + 2 ] );
|
||||||
|
|
||||||
|
point.x *= scale.x;
|
||||||
|
point.y *= scale.y;
|
||||||
|
point.z *= scale.z;
|
||||||
|
|
||||||
|
rotate(point, rotation, angle);
|
||||||
|
|
||||||
|
point.x += translation.x;
|
||||||
|
point.y += translation.y;
|
||||||
|
point.z += translation.z;
|
||||||
|
|
||||||
|
triplets.push_back(point);
|
||||||
|
|
||||||
|
// VRML
|
||||||
|
vrml_pointlist.Append( wxString::Format(wxT("%f %f %f\n"), point.x, point.y, point.z) );
|
||||||
|
}
|
||||||
|
vrml_points.push_back(vrml_pointlist);
|
||||||
|
|
||||||
|
/* -- Read coordinate indexes -- */
|
||||||
|
PROPERTY_MAP faceset_properties;
|
||||||
|
GetNodeProperties( aFaceNode, faceset_properties );
|
||||||
|
|
||||||
|
std::vector< S3D_VERTEX > vertices;
|
||||||
|
std::vector< int > coordIndex;
|
||||||
|
|
||||||
|
wxString coordIndex_str = faceset_properties[ wxT( "coordIndex" ) ];
|
||||||
|
wxStringTokenizer index_tokens( coordIndex_str );
|
||||||
|
|
||||||
|
wxString vrml_coord_indx_list;
|
||||||
|
while( index_tokens.HasMoreTokens() )
|
||||||
|
{
|
||||||
|
long index = 0;
|
||||||
|
index_tokens.GetNextToken().ToLong(&index);
|
||||||
|
|
||||||
|
// -1 marks the end of polygon
|
||||||
|
if( index < 0 )
|
||||||
|
{
|
||||||
|
/* Step 4: Apply geometry to Master object
|
||||||
|
* --------------------------------------- */
|
||||||
|
std::vector<int>::const_iterator id;
|
||||||
|
for( id = coordIndex.begin();
|
||||||
|
id != coordIndex.end();
|
||||||
|
id++ )
|
||||||
|
{
|
||||||
|
vertices.push_back( triplets.at(*id) );
|
||||||
|
}
|
||||||
|
|
||||||
|
GetMaster()->Set_Object_Coords( vertices );
|
||||||
|
Set_Object_Data( vertices, vrmlunits_to_3Dunits );
|
||||||
|
|
||||||
|
vertices.clear();
|
||||||
|
coordIndex.clear();
|
||||||
|
vrml_coord_indx_list.Append( wxT("-1\n") );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
coordIndex.push_back( index );
|
||||||
|
vrml_coord_indx_list.Append( wxString::Format(wxT("%u "), index) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vrml_coord_indexes.push_back(vrml_coord_indx_list);
|
||||||
|
}
|
||||||
|
|
|
@ -330,8 +330,8 @@ void PAGE_INFO::Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aContro
|
||||||
GetCustomWidthMils() * 25.4 / 1000.0,
|
GetCustomWidthMils() * 25.4 / 1000.0,
|
||||||
GetCustomHeightMils() * 25.4 / 1000.0 );
|
GetCustomHeightMils() * 25.4 / 1000.0 );
|
||||||
|
|
||||||
if( IsCustom() && IsPortrait() )
|
if( IsPortrait() )
|
||||||
aFormatter->Print( 0, " portrait" );
|
aFormatter->Print( 0, " portrait" );
|
||||||
|
|
||||||
aFormatter->Print( 0, ")\n" );
|
aFormatter->Print( 0, ")\n" );
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,4 +95,4 @@ const wxString PdfFileWildcard( _( "Portable document format files (*.pdf)|*.pdf
|
||||||
const wxString PSFileWildcard( _( "PostScript files (.ps)|*.ps" ) );
|
const wxString PSFileWildcard( _( "PostScript files (.ps)|*.ps" ) );
|
||||||
const wxString ReportFileWildcard = _( "Report files (*.rpt)|*.rpt" );
|
const wxString ReportFileWildcard = _( "Report files (*.rpt)|*.rpt" );
|
||||||
const wxString FootprintPlaceFileWildcard = _( "Footprint place files (*.pos)|*.pos" );
|
const wxString FootprintPlaceFileWildcard = _( "Footprint place files (*.pos)|*.pos" );
|
||||||
const wxString VrmlFileWildcard( _( "Vrml files (*.wrl)|*.wrl" ) );
|
const wxString Shapes3DFileWildcard( _( "Vrml and x3d files (*.wrl *.x3d)|*.wrl;*.x3d" ) );
|
||||||
|
|
|
@ -481,7 +481,7 @@ void DIALOG_BUILD_BOM::CreateSpreadSheetPartsShortList( )
|
||||||
bom_lister.SetCvsFormOn( s_ExportSeparatorSymbol );
|
bom_lister.SetCvsFormOn( s_ExportSeparatorSymbol );
|
||||||
|
|
||||||
// Set the list of fields to add to list
|
// Set the list of fields to add to list
|
||||||
for( int ii = FOOTPRINT; ii < FIELD8; ii++ )
|
for( int ii = FOOTPRINT; ii <= FIELD8; ii++ )
|
||||||
if( IsFieldChecked( ii ) )
|
if( IsFieldChecked( ii ) )
|
||||||
bom_lister.AddFieldIdToPrintList( ii );
|
bom_lister.AddFieldIdToPrintList( ii );
|
||||||
// Write the list of components grouped by values:
|
// Write the list of components grouped by values:
|
||||||
|
@ -530,7 +530,7 @@ void DIALOG_BUILD_BOM::CreateSpreadSheetPartsFullList( bool aIncludeSubComponent
|
||||||
aIncludeSubComponents );
|
aIncludeSubComponents );
|
||||||
|
|
||||||
// Set the list of fields to add to list
|
// Set the list of fields to add to list
|
||||||
for( int ii = FOOTPRINT; ii < FIELD8; ii++ )
|
for( int ii = FOOTPRINT; ii <= FIELD8; ii++ )
|
||||||
if( IsFieldChecked( ii ) )
|
if( IsFieldChecked( ii ) )
|
||||||
bom_lister.AddFieldIdToPrintList( ii );
|
bom_lister.AddFieldIdToPrintList( ii );
|
||||||
|
|
||||||
|
@ -564,7 +564,7 @@ void DIALOG_BUILD_BOM::CreatePartsAndLabelsFullList( bool aIncludeSubComponents
|
||||||
bom_lister.SetCvsFormOff();
|
bom_lister.SetCvsFormOff();
|
||||||
bom_lister.SetPrintLocation( s_Add_Location );
|
bom_lister.SetPrintLocation( s_Add_Location );
|
||||||
// Set the list of fields to add to list
|
// Set the list of fields to add to list
|
||||||
for( int ii = FOOTPRINT; ii < FIELD8; ii++ )
|
for( int ii = FOOTPRINT; ii <= FIELD8; ii++ )
|
||||||
if( IsFieldChecked( ii ) )
|
if( IsFieldChecked( ii ) )
|
||||||
bom_lister.AddFieldIdToPrintList( ii );
|
bom_lister.AddFieldIdToPrintList( ii );
|
||||||
|
|
||||||
|
|
|
@ -91,7 +91,7 @@ extern const wxString DrillFileWildcard;
|
||||||
extern const wxString SVGFileWildcard;
|
extern const wxString SVGFileWildcard;
|
||||||
extern const wxString ReportFileWildcard;
|
extern const wxString ReportFileWildcard;
|
||||||
extern const wxString FootprintPlaceFileWildcard;
|
extern const wxString FootprintPlaceFileWildcard;
|
||||||
extern const wxString VrmlFileWildcard;
|
extern const wxString Shapes3DFileWildcard;
|
||||||
extern const wxString DocModulesFileName;
|
extern const wxString DocModulesFileName;
|
||||||
extern const wxString LegacyFootprintLibPathWildcard;
|
extern const wxString LegacyFootprintLibPathWildcard;
|
||||||
extern const wxString KiCadFootprintLibFileWildcard;
|
extern const wxString KiCadFootprintLibFileWildcard;
|
||||||
|
|
|
@ -431,17 +431,18 @@ void DIALOG_MODULE_BOARD_EDITOR::Browse3DLib( wxCommandEvent& event )
|
||||||
#ifdef __WINDOWS__
|
#ifdef __WINDOWS__
|
||||||
fullpath.Replace( wxT( "/" ), wxT( "\\" ) );
|
fullpath.Replace( wxT( "/" ), wxT( "\\" ) );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
fullfilename = EDA_FileSelector( _( "3D Shape:" ),
|
fullfilename = EDA_FileSelector( _( "3D Shape:" ),
|
||||||
fullpath,
|
fullpath,
|
||||||
wxEmptyString,
|
wxEmptyString,
|
||||||
VrmlFileExtension,
|
wxEmptyString,
|
||||||
wxGetTranslation( VrmlFileWildcard ),
|
wxGetTranslation( Shapes3DFileWildcard ),
|
||||||
this,
|
this,
|
||||||
wxFD_OPEN,
|
wxFD_OPEN,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
if( fullfilename == wxEmptyString )
|
if( fullfilename.IsEmpty() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
wxFileName fn = fullfilename;
|
wxFileName fn = fullfilename;
|
||||||
|
|
|
@ -302,17 +302,18 @@ void DIALOG_MODULE_MODULE_EDITOR::BrowseAndAdd3DLib( wxCommandEvent& event )
|
||||||
#ifdef __WINDOWS__
|
#ifdef __WINDOWS__
|
||||||
fullpath.Replace( wxT( "/" ), wxT( "\\" ) );
|
fullpath.Replace( wxT( "/" ), wxT( "\\" ) );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
fullfilename = EDA_FileSelector( _( "3D Shape:" ),
|
fullfilename = EDA_FileSelector( _( "3D Shape:" ),
|
||||||
fullpath,
|
fullpath,
|
||||||
wxEmptyString,
|
wxEmptyString,
|
||||||
VrmlFileExtension,
|
wxEmptyString,
|
||||||
wxGetTranslation( VrmlFileWildcard ),
|
wxGetTranslation( Shapes3DFileWildcard ),
|
||||||
this,
|
this,
|
||||||
wxFD_OPEN,
|
wxFD_OPEN,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
if( fullfilename == wxEmptyString )
|
if( fullfilename.IsEmpty() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
wxFileName fn = fullfilename;
|
wxFileName fn = fullfilename;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// C++ code generated with wxFormBuilder (version Apr 10 2012)
|
// C++ code generated with wxFormBuilder (version Oct 8 2012)
|
||||||
// http://www.wxformbuilder.org/
|
// http://www.wxformbuilder.org/
|
||||||
//
|
//
|
||||||
// PLEASE DO "NOT" EDIT THIS FILE!
|
// PLEASE DO "NOT" EDIT THIS FILE!
|
||||||
|
@ -23,6 +23,7 @@ DIALOG_GENDRILL_BASE::DIALOG_GENDRILL_BASE( wxWindow* parent, wxWindowID id, con
|
||||||
bdirnameSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Output directory:") ), wxHORIZONTAL );
|
bdirnameSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Output directory:") ), wxHORIZONTAL );
|
||||||
|
|
||||||
m_outputDirectoryName = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
m_outputDirectoryName = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
m_outputDirectoryName->SetMaxLength( 0 );
|
||||||
bdirnameSizer->Add( m_outputDirectoryName, 1, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
|
bdirnameSizer->Add( m_outputDirectoryName, 1, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
|
||||||
|
|
||||||
m_buttonBrowse = new wxButton( this, wxID_ANY, _("Browse"), wxDefaultPosition, wxDefaultSize, 0 );
|
m_buttonBrowse = new wxButton( this, wxID_ANY, _("Browse"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
@ -79,7 +80,7 @@ DIALOG_GENDRILL_BASE::DIALOG_GENDRILL_BASE( wxWindow* parent, wxWindowID id, con
|
||||||
bMiddleBoxSizer->Add( m_Choice_Drill_Map, 0, wxALL|wxEXPAND, 5 );
|
bMiddleBoxSizer->Add( m_Choice_Drill_Map, 0, wxALL|wxEXPAND, 5 );
|
||||||
|
|
||||||
wxStaticBoxSizer* sbOptSizer;
|
wxStaticBoxSizer* sbOptSizer;
|
||||||
sbOptSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Options:") ), wxVERTICAL );
|
sbOptSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Drill File Options:") ), wxVERTICAL );
|
||||||
|
|
||||||
m_Check_Mirror = new wxCheckBox( this, wxID_ANY, _("Mirror y axis"), wxDefaultPosition, wxDefaultSize, 0 );
|
m_Check_Mirror = new wxCheckBox( this, wxID_ANY, _("Mirror y axis"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
sbOptSizer->Add( m_Check_Mirror, 0, wxRIGHT|wxLEFT, 5 );
|
sbOptSizer->Add( m_Check_Mirror, 0, wxRIGHT|wxLEFT, 5 );
|
||||||
|
@ -163,7 +164,7 @@ DIALOG_GENDRILL_BASE::DIALOG_GENDRILL_BASE( wxWindow* parent, wxWindowID id, con
|
||||||
|
|
||||||
bSizerButtons->Add( 10, 20, 0, 0, 5 );
|
bSizerButtons->Add( 10, 20, 0, 0, 5 );
|
||||||
|
|
||||||
m_buttonDrill = new wxButton( this, ID_GEN_DRILL_FILE, _("Drill Fille"), wxDefaultPosition, wxDefaultSize, 0 );
|
m_buttonDrill = new wxButton( this, ID_GEN_DRILL_FILE, _("Drill File"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
m_buttonDrill->SetDefault();
|
m_buttonDrill->SetDefault();
|
||||||
bSizerButtons->Add( m_buttonDrill, 0, wxALL|wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 );
|
bSizerButtons->Add( m_buttonDrill, 0, wxALL|wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 );
|
||||||
|
|
||||||
|
@ -186,6 +187,7 @@ DIALOG_GENDRILL_BASE::DIALOG_GENDRILL_BASE( wxWindow* parent, wxWindowID id, con
|
||||||
bmsgSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Messages:") ), wxVERTICAL );
|
bmsgSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Messages:") ), wxVERTICAL );
|
||||||
|
|
||||||
m_messagesBox = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY );
|
m_messagesBox = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY );
|
||||||
|
m_messagesBox->SetMaxLength( 0 );
|
||||||
m_messagesBox->SetMinSize( wxSize( -1,90 ) );
|
m_messagesBox->SetMinSize( wxSize( -1,90 ) );
|
||||||
|
|
||||||
bmsgSizer->Add( m_messagesBox, 1, wxALL|wxEXPAND, 5 );
|
bmsgSizer->Add( m_messagesBox, 1, wxALL|wxEXPAND, 5 );
|
||||||
|
|
|
@ -697,7 +697,7 @@
|
||||||
<property name="proportion">0</property>
|
<property name="proportion">0</property>
|
||||||
<object class="wxStaticBoxSizer" expanded="1">
|
<object class="wxStaticBoxSizer" expanded="1">
|
||||||
<property name="id">wxID_ANY</property>
|
<property name="id">wxID_ANY</property>
|
||||||
<property name="label">Options:</property>
|
<property name="label">Drill File Options:</property>
|
||||||
<property name="minimum_size"></property>
|
<property name="minimum_size"></property>
|
||||||
<property name="name">sbOptSizer</property>
|
<property name="name">sbOptSizer</property>
|
||||||
<property name="orient">wxVERTICAL</property>
|
<property name="orient">wxVERTICAL</property>
|
||||||
|
@ -1673,7 +1673,7 @@
|
||||||
<property name="gripper">0</property>
|
<property name="gripper">0</property>
|
||||||
<property name="hidden">0</property>
|
<property name="hidden">0</property>
|
||||||
<property name="id">ID_GEN_DRILL_FILE</property>
|
<property name="id">ID_GEN_DRILL_FILE</property>
|
||||||
<property name="label">Drill Fille</property>
|
<property name="label">Drill File</property>
|
||||||
<property name="max_size"></property>
|
<property name="max_size"></property>
|
||||||
<property name="maximize_button">0</property>
|
<property name="maximize_button">0</property>
|
||||||
<property name="maximum_size"></property>
|
<property name="maximum_size"></property>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// C++ code generated with wxFormBuilder (version Apr 10 2012)
|
// C++ code generated with wxFormBuilder (version Oct 8 2012)
|
||||||
// http://www.wxformbuilder.org/
|
// http://www.wxformbuilder.org/
|
||||||
//
|
//
|
||||||
// PLEASE DO "NOT" EDIT THIS FILE!
|
// PLEASE DO "NOT" EDIT THIS FILE!
|
||||||
|
@ -11,6 +11,8 @@
|
||||||
#include <wx/artprov.h>
|
#include <wx/artprov.h>
|
||||||
#include <wx/xrc/xmlres.h>
|
#include <wx/xrc/xmlres.h>
|
||||||
#include <wx/intl.h>
|
#include <wx/intl.h>
|
||||||
|
class DIALOG_SHIM;
|
||||||
|
|
||||||
#include "dialog_shim.h"
|
#include "dialog_shim.h"
|
||||||
#include <wx/string.h>
|
#include <wx/string.h>
|
||||||
#include <wx/textctrl.h>
|
#include <wx/textctrl.h>
|
||||||
|
|
|
@ -40,6 +40,8 @@
|
||||||
#include <class_pcb_text.h>
|
#include <class_pcb_text.h>
|
||||||
#include <convert_from_iu.h>
|
#include <convert_from_iu.h>
|
||||||
|
|
||||||
|
#include "../3d-viewer/modelparsers.h"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
|
@ -1149,11 +1151,28 @@ static void export_vrml_module( BOARD* aPcb, MODULE* aModule,
|
||||||
vrmlm->m_MatScale.y * aVRMLModelsToBiu,
|
vrmlm->m_MatScale.y * aVRMLModelsToBiu,
|
||||||
vrmlm->m_MatScale.z * aVRMLModelsToBiu );
|
vrmlm->m_MatScale.z * aVRMLModelsToBiu );
|
||||||
|
|
||||||
fprintf( aOutputFile,
|
if( fname.EndsWith( wxT( "x3d" ) ) )
|
||||||
// " children [\n Inline {\n url \"file://%s\"\n } ]\n",
|
{
|
||||||
" children [\n Inline {\n url \"%s\"\n } ]\n",
|
X3D_MODEL_PARSER* parser = new X3D_MODEL_PARSER(vrmlm);
|
||||||
TO_UTF8( fname ) );
|
|
||||||
fprintf( aOutputFile, " }\n" );
|
if(parser)
|
||||||
|
{
|
||||||
|
// embed x3d model in vrml format
|
||||||
|
parser->Load(fname);
|
||||||
|
fprintf( aOutputFile,
|
||||||
|
" children [\n %s ]\n", TO_UTF8( parser->VRML_representation() ) );
|
||||||
|
fprintf( aOutputFile, " }\n" );
|
||||||
|
delete parser;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf( aOutputFile,
|
||||||
|
" children [\n Inline {\n url \"%s\"\n } ]\n",
|
||||||
|
TO_UTF8( fname ) );
|
||||||
|
fprintf( aOutputFile, " }\n" );
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue