diff --git a/3d-viewer/3d_read_mesh.cpp b/3d-viewer/3d_read_mesh.cpp index 326d99b941..c91b2ff859 100644 --- a/3d-viewer/3d_read_mesh.cpp +++ b/3d-viewer/3d_read_mesh.cpp @@ -35,20 +35,33 @@ #include <3d_viewer.h> #include +#include "3d_struct.h" +#include "modelparsers.h" // Imported function: extern void Set_Object_Data( std::vector< S3D_VERTEX >& aVertices, double aBiuTo3DUnits ); -// separator chars -static const char* sep_chars = " \t\n\r"; +S3D_MODEL_PARSER* S3D_MODEL_PARSER::Create( S3D_MASTER* aMaster, + 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() { - char line[1024], * text; wxFileName fn; wxString FullFilename; - FILE* file; - int LineNum = 0; if( m_Shape3DName.IsEmpty() ) { @@ -65,6 +78,7 @@ int S3D_MASTER::ReadData() if( wxFileName::FileExists( shape3DNname ) ) { FullFilename = shape3DNname; + fn.Assign(FullFilename); } else { @@ -79,512 +93,22 @@ int S3D_MASTER::ReadData() } } - file = wxFopen( FullFilename, wxT( "rt" ) ); - - if( file == NULL ) + wxString extension = fn.GetExt(); + S3D_MODEL_PARSER* parser = S3D_MODEL_PARSER::Create(this, extension); + if(parser) { - return -1; - } - - // 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" ) ); + parser->Load(FullFilename); + delete parser; return 0; - } - - if( stricmp( command, "DEF" ) == 0 || stricmp( command, "Material") == 0) + } + else { - material = new S3D_MATERIAL( this, mat_name ); - - 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 ); - } - } + wxLogDebug( wxT( "Unknown file type <%s>" ), GetChars( extension ) ); } 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 ) { char line[512]; diff --git a/3d-viewer/3d_struct.h b/3d-viewer/3d_struct.h index 26e6738339..4c1d2be577 100644 --- a/3d-viewer/3d_struct.h +++ b/3d-viewer/3d_struct.h @@ -115,26 +115,6 @@ public: void Copy( S3D_MASTER* pattern ); 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 ); #if defined(DEBUG) diff --git a/3d-viewer/CMakeLists.txt b/3d-viewer/CMakeLists.txt index c48af8613b..94cc9d396e 100644 --- a/3d-viewer/CMakeLists.txt +++ b/3d-viewer/CMakeLists.txt @@ -19,6 +19,8 @@ set(3D-VIEWER_SRCS 3d_toolbar.cpp info3d_visu.cpp trackball.cpp + x3dmodelparser.cpp + vrmlmodelparser.cpp ) add_library(3d-viewer STATIC ${3D-VIEWER_SRCS}) diff --git a/3d-viewer/modelparsers.h b/3d-viewer/modelparsers.h new file mode 100644 index 0000000000..55e2dc738e --- /dev/null +++ b/3d-viewer/modelparsers.h @@ -0,0 +1,176 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2013 Tuomas Vaherkoski + * 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 +#include +#include + + +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 vrml_materials; + std::vector vrml_points; + std::vector 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 diff --git a/3d-viewer/vrmlmodelparser.cpp b/3d-viewer/vrmlmodelparser.cpp new file mode 100644 index 0000000000..cbb3205e41 --- /dev/null +++ b/3d-viewer/vrmlmodelparser.cpp @@ -0,0 +1,557 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2013 Tuomas Vaherkoski + * Copyright (C) 2012 Jean-Pierre Charras, jp.charras@wanadoo.fr + * Copyright (C) 2011 Wayne Stambaugh + * 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 +#include +#include +#include +#include + +#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; +} diff --git a/3d-viewer/x3dmodelparser.cpp b/3d-viewer/x3dmodelparser.cpp new file mode 100644 index 0000000000..8402164547 --- /dev/null +++ b/3d-viewer/x3dmodelparser.cpp @@ -0,0 +1,458 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2013 Tuomas Vaherkoski + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#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::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); +} + diff --git a/common/class_page_info.cpp b/common/class_page_info.cpp index e7c111213d..9e61f04365 100644 --- a/common/class_page_info.cpp +++ b/common/class_page_info.cpp @@ -330,8 +330,8 @@ void PAGE_INFO::Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aContro GetCustomWidthMils() * 25.4 / 1000.0, GetCustomHeightMils() * 25.4 / 1000.0 ); - if( IsCustom() && IsPortrait() ) - aFormatter->Print( 0, " portrait" ); + if( IsPortrait() ) + aFormatter->Print( 0, " portrait" ); aFormatter->Print( 0, ")\n" ); } diff --git a/common/wildcards_and_files_ext.cpp b/common/wildcards_and_files_ext.cpp index 0d0333b84e..2a09e046fb 100644 --- a/common/wildcards_and_files_ext.cpp +++ b/common/wildcards_and_files_ext.cpp @@ -95,4 +95,4 @@ const wxString PdfFileWildcard( _( "Portable document format files (*.pdf)|*.pdf const wxString PSFileWildcard( _( "PostScript files (.ps)|*.ps" ) ); const wxString ReportFileWildcard = _( "Report files (*.rpt)|*.rpt" ); 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" ) ); diff --git a/eeschema/dialogs/dialog_build_BOM.cpp b/eeschema/dialogs/dialog_build_BOM.cpp index 224ba98b87..eac045fc38 100644 --- a/eeschema/dialogs/dialog_build_BOM.cpp +++ b/eeschema/dialogs/dialog_build_BOM.cpp @@ -481,7 +481,7 @@ void DIALOG_BUILD_BOM::CreateSpreadSheetPartsShortList( ) bom_lister.SetCvsFormOn( s_ExportSeparatorSymbol ); // 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 ) ) bom_lister.AddFieldIdToPrintList( ii ); // Write the list of components grouped by values: @@ -530,7 +530,7 @@ void DIALOG_BUILD_BOM::CreateSpreadSheetPartsFullList( bool aIncludeSubComponent aIncludeSubComponents ); // 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 ) ) bom_lister.AddFieldIdToPrintList( ii ); @@ -564,7 +564,7 @@ void DIALOG_BUILD_BOM::CreatePartsAndLabelsFullList( bool aIncludeSubComponents bom_lister.SetCvsFormOff(); bom_lister.SetPrintLocation( s_Add_Location ); // 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 ) ) bom_lister.AddFieldIdToPrintList( ii ); diff --git a/include/wildcards_and_files_ext.h b/include/wildcards_and_files_ext.h index 4408ae09d3..9f1368eabb 100644 --- a/include/wildcards_and_files_ext.h +++ b/include/wildcards_and_files_ext.h @@ -91,7 +91,7 @@ extern const wxString DrillFileWildcard; extern const wxString SVGFileWildcard; extern const wxString ReportFileWildcard; extern const wxString FootprintPlaceFileWildcard; -extern const wxString VrmlFileWildcard; +extern const wxString Shapes3DFileWildcard; extern const wxString DocModulesFileName; extern const wxString LegacyFootprintLibPathWildcard; extern const wxString KiCadFootprintLibFileWildcard; diff --git a/pcbnew/dialogs/dialog_edit_module_for_BoardEditor.cpp b/pcbnew/dialogs/dialog_edit_module_for_BoardEditor.cpp index 6f00d9ee68..c5a14ca726 100644 --- a/pcbnew/dialogs/dialog_edit_module_for_BoardEditor.cpp +++ b/pcbnew/dialogs/dialog_edit_module_for_BoardEditor.cpp @@ -431,17 +431,18 @@ void DIALOG_MODULE_BOARD_EDITOR::Browse3DLib( wxCommandEvent& event ) #ifdef __WINDOWS__ fullpath.Replace( wxT( "/" ), wxT( "\\" ) ); #endif + fullfilename = EDA_FileSelector( _( "3D Shape:" ), fullpath, wxEmptyString, - VrmlFileExtension, - wxGetTranslation( VrmlFileWildcard ), + wxEmptyString, + wxGetTranslation( Shapes3DFileWildcard ), this, wxFD_OPEN, true ); - if( fullfilename == wxEmptyString ) + if( fullfilename.IsEmpty() ) return; wxFileName fn = fullfilename; diff --git a/pcbnew/dialogs/dialog_edit_module_for_Modedit.cpp b/pcbnew/dialogs/dialog_edit_module_for_Modedit.cpp index d11bd5f277..811607e3ce 100644 --- a/pcbnew/dialogs/dialog_edit_module_for_Modedit.cpp +++ b/pcbnew/dialogs/dialog_edit_module_for_Modedit.cpp @@ -302,17 +302,18 @@ void DIALOG_MODULE_MODULE_EDITOR::BrowseAndAdd3DLib( wxCommandEvent& event ) #ifdef __WINDOWS__ fullpath.Replace( wxT( "/" ), wxT( "\\" ) ); #endif + fullfilename = EDA_FileSelector( _( "3D Shape:" ), fullpath, wxEmptyString, - VrmlFileExtension, - wxGetTranslation( VrmlFileWildcard ), + wxEmptyString, + wxGetTranslation( Shapes3DFileWildcard ), this, wxFD_OPEN, true ); - if( fullfilename == wxEmptyString ) + if( fullfilename.IsEmpty() ) return; wxFileName fn = fullfilename; diff --git a/pcbnew/dialogs/dialog_gendrill_base.cpp b/pcbnew/dialogs/dialog_gendrill_base.cpp index 69efb248ed..59f9bb910f 100644 --- a/pcbnew/dialogs/dialog_gendrill_base.cpp +++ b/pcbnew/dialogs/dialog_gendrill_base.cpp @@ -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/ // // 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 ); m_outputDirectoryName = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_outputDirectoryName->SetMaxLength( 0 ); bdirnameSizer->Add( m_outputDirectoryName, 1, wxBOTTOM|wxRIGHT|wxLEFT, 5 ); 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 ); 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 ); 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 ); - 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(); 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 ); m_messagesBox = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY ); + m_messagesBox->SetMaxLength( 0 ); m_messagesBox->SetMinSize( wxSize( -1,90 ) ); bmsgSizer->Add( m_messagesBox, 1, wxALL|wxEXPAND, 5 ); diff --git a/pcbnew/dialogs/dialog_gendrill_base.fbp b/pcbnew/dialogs/dialog_gendrill_base.fbp index ca554b9996..1f53eb1c23 100644 --- a/pcbnew/dialogs/dialog_gendrill_base.fbp +++ b/pcbnew/dialogs/dialog_gendrill_base.fbp @@ -697,7 +697,7 @@ 0 wxID_ANY - Options: + Drill File Options: sbOptSizer wxVERTICAL @@ -1673,7 +1673,7 @@ 0 0 ID_GEN_DRILL_FILE - Drill Fille + Drill File 0 diff --git a/pcbnew/dialogs/dialog_gendrill_base.h b/pcbnew/dialogs/dialog_gendrill_base.h index a3b9680676..a71232832d 100644 --- a/pcbnew/dialogs/dialog_gendrill_base.h +++ b/pcbnew/dialogs/dialog_gendrill_base.h @@ -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/ // // PLEASE DO "NOT" EDIT THIS FILE! @@ -11,6 +11,8 @@ #include #include #include +class DIALOG_SHIM; + #include "dialog_shim.h" #include #include diff --git a/pcbnew/export_vrml.cpp b/pcbnew/export_vrml.cpp index 1aea2044cf..7ccbd48081 100755 --- a/pcbnew/export_vrml.cpp +++ b/pcbnew/export_vrml.cpp @@ -40,6 +40,8 @@ #include #include +#include "../3d-viewer/modelparsers.h" + #include #include @@ -1149,11 +1151,28 @@ static void export_vrml_module( BOARD* aPcb, MODULE* aModule, vrmlm->m_MatScale.y * aVRMLModelsToBiu, vrmlm->m_MatScale.z * aVRMLModelsToBiu ); - fprintf( aOutputFile, -// " children [\n Inline {\n url \"file://%s\"\n } ]\n", - " children [\n Inline {\n url \"%s\"\n } ]\n", - TO_UTF8( fname ) ); - fprintf( aOutputFile, " }\n" ); + if( fname.EndsWith( wxT( "x3d" ) ) ) + { + X3D_MODEL_PARSER* parser = new X3D_MODEL_PARSER(vrmlm); + + 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" ); + } + } }