=== modified file '3d-viewer/3d_read_mesh.cpp'
--- 3d-viewer/3d_read_mesh.cpp	2013-01-12 10:35:08 +0000
+++ 3d-viewer/3d_read_mesh.cpp	2013-03-19 15:09:56 +0000
@@ -44,11 +44,8 @@
 
 int S3D_MASTER::ReadData()
 {
-    char       line[1024], * text;
     wxFileName fn;
     wxString   FullFilename;
-    FILE*      file;
-    int        LineNum = 0;
 
     if( m_Shape3DName.IsEmpty() )
     {
@@ -65,6 +62,7 @@
     if( wxFileName::FileExists( shape3DNname ) )
     {
         FullFilename = shape3DNname;
+        fn.Assign(FullFilename);
     }
     else
     {
@@ -79,7 +77,33 @@
         }
     }
 
-    file = wxFopen( FullFilename, wxT( "rt" ) );
+    wxString extension = fn.GetExt();
+    if( extension == wxT( "wrl" ) )
+    {
+        return ParseVrmlFile(FullFilename);
+    }
+    else if( extension == wxT( "x3d" ) ) 
+    {
+        X3D_MODEL_PARSER parser(this);
+        parser.Load(FullFilename);
+        return 0;
+    }
+    else
+    {
+        wxLogDebug( wxT( "Unknown file type <%s>" ), GetChars( extension ) );
+    }
+
+    return -1;
+}
+
+
+int S3D_MASTER::ParseVrmlFile( const wxString& filename )
+{
+    char       line[1024], * text;
+    FILE*      file;
+    int        LineNum = 0;
+
+    file = wxFopen( filename, wxT( "rt" ) );
 
     if( file == NULL )
     {
@@ -119,6 +143,7 @@
 }
 
 
+
 int S3D_MASTER::ReadMaterial( FILE* file, int* LineNum )
 {
     char          line[512], * text, * command;

=== modified file '3d-viewer/3d_struct.h'
--- 3d-viewer/3d_struct.h	2012-08-21 10:45:54 +0000
+++ 3d-viewer/3d_struct.h	2013-03-19 13:37:30 +0000
@@ -32,6 +32,7 @@
 
 #include <common.h>
 #include <base_struct.h>
+#include "modelparsers.h"
 
 
 /* 3D modeling units -> PCB units conversion scale:
@@ -87,7 +88,6 @@
 #endif
 };
 
-
 /* Master structure for a 3D item description */
 class S3D_MASTER : public EDA_ITEM
 {
@@ -99,6 +99,9 @@
     STRUCT_3D_SHAPE* m_3D_Drawings;
     S3D_MATERIAL*   m_Materials;
 
+private:
+    int ParseVrmlFile( const wxString& filename );
+
 public:
     S3D_MASTER( EDA_ITEM* aParent );
     ~S3D_MASTER();

=== modified file '3d-viewer/CMakeLists.txt'
--- 3d-viewer/CMakeLists.txt	2012-08-26 13:59:55 +0000
+++ 3d-viewer/CMakeLists.txt	2013-03-18 21:02:22 +0000
@@ -19,6 +19,7 @@
     3d_toolbar.cpp
     info3d_visu.cpp
     trackball.cpp
+    x3dmodelparser.cpp
     )
 
 add_library(3d-viewer STATIC ${3D-VIEWER_SRCS})

=== added file '3d-viewer/modelparsers.h'
--- 3d-viewer/modelparsers.h	1970-01-01 00:00:00 +0000
+++ 3d-viewer/modelparsers.h	2013-03-19 16:34:07 +0000
@@ -0,0 +1,113 @@
+/*
+ * 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;
+
+/**
+ * class ABSTRACT_3D_MODEL_PARSER
+ * Base class for 3D model parsers.
+ */
+class ABSTRACT_3D_MODEL_PARSER
+{
+public:
+    ABSTRACT_3D_MODEL_PARSER(S3D_MASTER* aMaster)
+    :master(aMaster) 
+    {}
+
+    ~ABSTRACT_3D_MODEL_PARSER() 
+    {}
+
+    S3D_MASTER* GetMaster() 
+    {
+        return master;
+    }
+    
+    /**
+     * 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 ABSTRACT_3D_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);
+
+private:
+    void readTransform( wxXmlNode* aTransformNode );
+    void readMaterial( wxXmlNode* aMatNode );
+    void readIndexedFaceSet( wxXmlNode* aFaceNode, 
+                             PROPERTY_MAP& aTransfromProps );
+    bool parseDoubleTriplet( const wxString& aData, S3D_VERTEX& aResult );
+};
+
+#endif // MODELPARSERS_H

=== added file '3d-viewer/x3dmodelparser.cpp'
--- 3d-viewer/x3dmodelparser.cpp	1970-01-01 00:00:00 +0000
+++ 3d-viewer/x3dmodelparser.cpp	2013-03-19 16:41:38 +0000
@@ -0,0 +1,333 @@
+/*
+ * 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"
+
+extern void Set_Object_Data( std::vector< S3D_VERTEX >& aVertices, double aBiuTo3DUnits );
+
+X3D_MODEL_PARSER::X3D_MODEL_PARSER( S3D_MASTER* aMaster )
+:ABSTRACT_3D_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 );
+    }
+}
+
+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();
+    }
+    
+    // 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 )
+            {
+                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 ); 
+}
+
+/* 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 );
+
+    double vrmlunits_to_3Dunits = g_Parm_3D_Visu.m_BiuTo3Dunits * 
+                                  UNITS3D_TO_UNITSPCB;
+
+    /* Step 2: Read vertex triplets
+     * ---------------------------- */
+    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" ) );
+        }
+    }
+
+    /* Step 3: 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 );
+
+    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++ )
+            {
+                S3D_VERTEX vertex;
+                int triplet_indx = (*id) * 3;
+
+                // Create vertex from coordinates and apply transform
+                vertex.x = points.at( triplet_indx )     * scale.x;
+                vertex.y = points.at( triplet_indx + 1 ) * scale.y;
+                vertex.z = points.at( triplet_indx + 2 ) * scale.z;
+
+                // TODO: Transform rotation
+
+                vertex.x += translation.x;
+                vertex.y += translation.y;
+                vertex.z += translation.z;
+
+                vertices.push_back( vertex );
+            }
+
+            GetMaster()->Set_Object_Coords( vertices );
+            Set_Object_Data( vertices, vrmlunits_to_3Dunits );
+
+            vertices.clear();
+            coordIndex.clear();
+        }
+        else
+        {
+            coordIndex.push_back( index );
+        }
+    }
+}
+

=== modified file 'pcbnew/dialogs/dialog_edit_module_for_Modedit.cpp'
--- pcbnew/dialogs/dialog_edit_module_for_Modedit.cpp	2013-03-13 18:53:58 +0000
+++ pcbnew/dialogs/dialog_edit_module_for_Modedit.cpp	2013-03-19 17:06:59 +0000
@@ -302,11 +302,25 @@
 #ifdef __WINDOWS__
     fullpath.Replace( wxT( "/" ), wxT( "\\" ) );
 #endif
+
+    const wxString X3DFileWildcard( _( "X3D files (*.x3d)|*.x3d" ) );
+
+    const wxString filters[] = { VrmlFileWildcard, X3DFileWildcard };
+    wxString fileFilters;
+    for( unsigned i=0; i < DIM( filters ); i++ ) 
+    {
+        if( i > 0 )
+        {
+            fileFilters += wxChar( '|' );
+        }
+        fileFilters += wxGetTranslation( filters[i] );
+    }
+
     fullfilename = EDA_FileSelector( _( "3D Shape:" ),
                                      fullpath,
                                      wxEmptyString,
                                      VrmlFileExtension,
-                                     wxGetTranslation( VrmlFileWildcard ),
+                                     fileFilters,
                                      this,
                                      wxFD_OPEN,
                                      true

