Kicad manager: fix a recent bug: project tree not updated when kicad is launched by a command line with a project name to open.

Pcbnew: export vrml:
* move dialog functions to a new file: dialog_export_vrml.cpp (to be consistent with other dialogs).
* fix some coding style issues
* added patch from Cirilo Bernardo.
This commit is contained in:
jean-pierre charras 2013-01-13 19:41:15 +01:00
commit a864ab6f9e
9 changed files with 281 additions and 208 deletions

View File

@ -888,13 +888,14 @@ public:
* Function ExportVRML_File * Function ExportVRML_File
* Creates the file(s) exporting current BOARD to a VRML file. * Creates the file(s) exporting current BOARD to a VRML file.
* @param aFullFileName = the full filename of the file to create * @param aFullFileName = the full filename of the file to create
* @param aScale = the general scaling factor. 1.0 to export in inches * @param aMMtoWRMLunit = the VRML scaling factor:
* 1.0 to export in mm. 0.001 for meters
* @param aExport3DFiles = true to copy 3D shapes in the subir a3D_Subdir * @param aExport3DFiles = true to copy 3D shapes in the subir a3D_Subdir
* @param a3D_Subdir = sub directory where 3D shapes files are copied * @param a3D_Subdir = sub directory where 3D shapes files are copied
* used only when aExport3DFiles == true * used only when aExport3DFiles == true
* @return true if Ok. * @return true if Ok.
*/ */
bool ExportVRML_File( const wxString & aFullFileName, double aScale, bool ExportVRML_File( const wxString & aFullFileName, double aMMtoWRMLunit,
bool aExport3DFiles, const wxString & a3D_Subdir ); bool aExport3DFiles, const wxString & a3D_Subdir );
/** /**

View File

@ -97,36 +97,40 @@ bool EDA_APP::OnInit()
bool reopenLastUsedDirectory = argc == 1; bool reopenLastUsedDirectory = argc == 1;
GetSettings( reopenLastUsedDirectory ); GetSettings( reopenLastUsedDirectory );
/* Make nameless project translatable */
wxFileName namelessProject( wxGetCwd(), NAMELESS_PROJECT, ProjectFileExtension );
frame = new KICAD_MANAGER_FRAME( NULL, wxT( "KiCad" ), frame = new KICAD_MANAGER_FRAME( NULL, wxT( "KiCad" ),
wxDefaultPosition, wxDefaultSize ); wxDefaultPosition, wxDefaultSize );
SetTopWindow( frame ); SetTopWindow( frame );
bool prjloaded = false; // true when the project is loaded
if( argc > 1 ) if( argc > 1 )
{
frame->m_ProjectFileName = argv[1]; frame->m_ProjectFileName = argv[1];
}
else if( m_fileHistory.GetCount() ) else if( m_fileHistory.GetCount() )
{ {
// Try to open the last opened project,
// if a project name is not given when starting Kicad
frame->m_ProjectFileName = m_fileHistory.GetHistoryFile( 0 ); frame->m_ProjectFileName = m_fileHistory.GetHistoryFile( 0 );
if( !frame->m_ProjectFileName.FileExists() ) if( !frame->m_ProjectFileName.FileExists() )
{
m_fileHistory.RemoveFileFromHistory( 0 ); m_fileHistory.RemoveFileFromHistory( 0 );
}
else else
{ {
wxCommandEvent cmd( 0, wxID_FILE1 ); wxCommandEvent cmd( 0, wxID_FILE1 );
frame->OnFileHistory( cmd ); frame->OnFileHistory( cmd );
prjloaded = true; // OnFileHistory() loads the project
} }
} }
if( !frame->m_ProjectFileName.FileExists() ) if( !frame->m_ProjectFileName.FileExists() )
{ {
wxCommandEvent cmd( 0, wxID_ANY ); wxFileName namelessProject( wxGetCwd(), NAMELESS_PROJECT,
ProjectFileExtension );
frame->m_ProjectFileName = namelessProject; frame->m_ProjectFileName = namelessProject;
}
if( ! prjloaded )
{
wxCommandEvent cmd( 0, wxID_ANY );
frame->OnLoadProject( cmd ); frame->OnLoadProject( cmd );
} }

View File

@ -226,7 +226,7 @@ void KICAD_MANAGER_FRAME::OnLoadProject( wxCommandEvent& event )
#ifdef KICAD_USE_FILES_WATCHER #ifdef KICAD_USE_FILES_WATCHER
// Rebuild the list of watched paths. // Rebuild the list of watched paths.
// however this is possible only when the main loop event handler is running, // however this is possible only when the main loop event handler is running,
// so we use it to rub the rebuild function. // so we use it to run the rebuild function.
wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED, ID_INIT_WATCHED_PATHS ); wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED, ID_INIT_WATCHED_PATHS );
wxPostEvent( this, cmd); wxPostEvent( this, cmd);
#endif #endif

View File

@ -47,7 +47,8 @@ set(PCBNEW_DIALOGS
dialogs/dialog_edit_module_text.cpp dialogs/dialog_edit_module_text.cpp
dialogs/dialog_edit_module_text_base.cpp dialogs/dialog_edit_module_text_base.cpp
dialogs/dialog_exchange_modules_base.cpp dialogs/dialog_exchange_modules_base.cpp
dialogs/dialog_export_3Dfiles_base.cpp dialogs/dialog_export_vrml_base.cpp
dialogs/dialog_export_vrml.cpp
dialogs/dialog_find_base.cpp dialogs/dialog_find_base.cpp
dialogs/dialog_find.cpp dialogs/dialog_find.cpp
dialogs/dialog_fp_lib_table_base.cpp dialogs/dialog_fp_lib_table_base.cpp

View File

@ -0,0 +1,146 @@
/**
* @file dialog_export_vrml.cpp
*/
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2009-2013 Lorenzo Mercantonio
* Copyright (C) 2013 Jean-Pierre Charras jp.charras at wanadoo.fr
* Copyright (C) 2004-2013 KiCad Developers, see change_log.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
*/
#include <fctsys.h>
#include <wxPcbStruct.h>
#include <appl_wxstruct.h>
#include <pcbnew.h>
#include <class_board.h>
/* the dialog to create VRML files, derived from DIALOG_EXPORT_3DFILE_BASE,
* created by wxFormBuilder
*/
#include <dialog_export_vrml_base.h> // the wxFormBuilder header file
#define OPTKEY_OUTPUT_UNIT wxT("VrmlExportUnit" )
#define OPTKEY_3DFILES_OPT wxT("VrmlExport3DShapeFilesOpt" )
class DIALOG_EXPORT_3DFILE : public DIALOG_EXPORT_3DFILE_BASE
{
private:
PCB_EDIT_FRAME* m_parent;
wxConfig* m_config;
int m_unitsOpt; // to remember last option
int m_3DFilesOpt; // to remember last option
void OnCancelClick( wxCommandEvent& event ){ EndModal( wxID_CANCEL ); }
void OnOkClick( wxCommandEvent& event ){ EndModal( wxID_OK ); }
public:
DIALOG_EXPORT_3DFILE( PCB_EDIT_FRAME* parent ) :
DIALOG_EXPORT_3DFILE_BASE( parent )
{
m_parent = parent;
m_config = wxGetApp().GetSettings();
SetFocus();
m_config->Read( OPTKEY_OUTPUT_UNIT, &m_unitsOpt );
m_config->Read( OPTKEY_3DFILES_OPT, &m_3DFilesOpt );
m_rbSelectUnits->SetSelection(m_unitsOpt);
m_rb3DFilesOption->SetSelection(m_3DFilesOpt);
GetSizer()->SetSizeHints( this );
Centre();
}
~DIALOG_EXPORT_3DFILE()
{
m_unitsOpt = GetUnits( );
m_3DFilesOpt = Get3DFilesOption( );
m_config->Write( OPTKEY_OUTPUT_UNIT, m_unitsOpt );
m_config->Write( OPTKEY_3DFILES_OPT, m_3DFilesOpt );
};
void SetSubdir( const wxString & aDir )
{
m_SubdirNameCtrl->SetValue( aDir);
}
wxString GetSubdir( )
{
return m_SubdirNameCtrl->GetValue( );
}
wxFilePickerCtrl* FilePicker()
{
return m_filePicker;
}
int GetUnits( )
{
return m_unitsOpt = m_rbSelectUnits->GetSelection();
}
int Get3DFilesOption( )
{
return m_3DFilesOpt = m_rb3DFilesOption->GetSelection();
}
};
/**
* Function OnExportVRML
* will export the current BOARD to a VRML file.
*/
void PCB_EDIT_FRAME::OnExportVRML( wxCommandEvent& event )
{
wxFileName fn;
static wxString subDirFor3Dshapes = wxT("shapes3D");
// The general VRML scale factor
// Assuming the VRML default unit is the mm
// this is the mm to VRML scaling factor for inch, mm and meter
double scaleList[3] = { 1.0/25.4, 1, 0.001 };
// Build default file name
wxString ext = wxT( "wrl" );
fn = GetBoard()->GetFileName();
fn.SetExt( ext );
DIALOG_EXPORT_3DFILE dlg( this );
dlg.FilePicker()->SetPath( fn.GetFullPath() );
dlg.SetSubdir( subDirFor3Dshapes );
if( dlg.ShowModal() != wxID_OK )
return;
double scale = scaleList[dlg.GetUnits( )]; // final scale export
bool export3DFiles = dlg.Get3DFilesOption( ) == 0;
wxBusyCursor dummy;
wxString fullFilename = dlg.FilePicker()->GetPath();
subDirFor3Dshapes = dlg.GetSubdir();
if( ! wxDirExists( subDirFor3Dshapes ) )
wxMkdir( subDirFor3Dshapes );
if( ! ExportVRML_File( fullFilename, scale, export3DFiles, subDirFor3Dshapes ) )
{
wxString msg = _( "Unable to create " ) + fullFilename;
wxMessageBox( msg );
return;
}
}

View File

@ -1,11 +1,11 @@
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// 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!
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
#include "dialog_export_3Dfiles_base.h" #include "dialog_export_vrml_base.h"
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
@ -32,6 +32,7 @@ DIALOG_EXPORT_3DFILE_BASE::DIALOG_EXPORT_3DFILE_BASE( wxWindow* parent, wxWindow
bUpperSizer->Add( m_staticText3, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); bUpperSizer->Add( m_staticText3, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
m_SubdirNameCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); m_SubdirNameCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
m_SubdirNameCtrl->SetMaxLength( 0 );
bUpperSizer->Add( m_SubdirNameCtrl, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); bUpperSizer->Add( m_SubdirNameCtrl, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );

View File

@ -11,11 +11,11 @@
<property name="embedded_files_path">res</property> <property name="embedded_files_path">res</property>
<property name="encoding">UTF-8</property> <property name="encoding">UTF-8</property>
<property name="event_generation">connect</property> <property name="event_generation">connect</property>
<property name="file">dialog_export_3Dfiles_base</property> <property name="file">dialog_export_vrml_base</property>
<property name="first_id">1000</property> <property name="first_id">1000</property>
<property name="help_provider">none</property> <property name="help_provider">none</property>
<property name="internationalize">1</property> <property name="internationalize">1</property>
<property name="name">dialog_export_3Dfiles</property> <property name="name">dialog_export_vrml</property>
<property name="namespace"></property> <property name="namespace"></property>
<property name="path">.</property> <property name="path">.</property>
<property name="precompiled_header"></property> <property name="precompiled_header"></property>

View File

@ -1,16 +1,18 @@
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// 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!
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
#ifndef __DIALOG_EXPORT_3DFILES_BASE_H__ #ifndef __DIALOG_EXPORT_VRML_BASE_H__
#define __DIALOG_EXPORT_3DFILES_BASE_H__ #define __DIALOG_EXPORT_VRML_BASE_H__
#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/stattext.h> #include <wx/stattext.h>
@ -59,4 +61,4 @@ class DIALOG_EXPORT_3DFILE_BASE : public DIALOG_SHIM
}; };
#endif //__DIALOG_EXPORT_3DFILES_BASE_H__ #endif //__DIALOG_EXPORT_VRML_BASE_H__

View File

@ -1,3 +1,27 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2009-2013 Lorenzo Mercantonio
* Copyright (C) 2013 Jean-Pierre Charras jp.charras at wanadoo.fr
* Copyright (C) 2004-2013 KiCad Developers, see change_log.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
*/
#include <fctsys.h> #include <fctsys.h>
#include <kicad_string.h> #include <kicad_string.h>
#include <wxPcbStruct.h> #include <wxPcbStruct.h>
@ -19,8 +43,10 @@
#include <vector> #include <vector>
#include <cmath> #include <cmath>
// Number of segments to approximate a circle per segments:
#define SEGM_COUNT_PER_360 32 // Number of segments to approximate a circle per segments #define SEGM_COUNT_PER_360 32
// basic angle to approximate a circle per segments
static const double INC_ANGLE = M_PI*2 / SEGM_COUNT_PER_360;
/* helper function: /* helper function:
* some characters cannot be used in names, * some characters cannot be used in names,
@ -28,137 +54,25 @@
*/ */
static void ChangeIllegalCharacters( wxString & aFileName, bool aDirSepIsIllegal ); static void ChangeIllegalCharacters( wxString & aFileName, bool aDirSepIsIllegal );
/* the dialog to create VRML files, derived from DIALOG_EXPORT_3DFILE_BASE,
* created by wxFormBuilder
*/
#include <dialog_export_3Dfiles_base.h> // the wxFormBuilder header file
#define OPTKEY_OUTPUT_UNIT wxT("VrmlExportUnit" )
#define OPTKEY_3DFILES_OPT wxT("VrmlExport3DShapeFilesOpt" )
class DIALOG_EXPORT_3DFILE : public DIALOG_EXPORT_3DFILE_BASE
{
private:
PCB_EDIT_FRAME* m_parent;
wxConfig* m_config;
int m_unitsOpt; // to remember last option
int m_3DFilesOpt; // to remember last option
void OnCancelClick( wxCommandEvent& event ){ EndModal( wxID_CANCEL ); }
void OnOkClick( wxCommandEvent& event ){ EndModal( wxID_OK ); }
public:
DIALOG_EXPORT_3DFILE( PCB_EDIT_FRAME* parent ) :
DIALOG_EXPORT_3DFILE_BASE( parent )
{
m_parent = parent;
m_config = wxGetApp().GetSettings();
SetFocus();
m_config->Read( OPTKEY_OUTPUT_UNIT, &m_unitsOpt );
m_config->Read( OPTKEY_3DFILES_OPT, &m_3DFilesOpt );
m_rbSelectUnits->SetSelection(m_unitsOpt);
m_rb3DFilesOption->SetSelection(m_3DFilesOpt);
GetSizer()->SetSizeHints( this );
Centre();
}
~DIALOG_EXPORT_3DFILE()
{
m_unitsOpt = GetUnits( );
m_3DFilesOpt = Get3DFilesOption( );
m_config->Write( OPTKEY_OUTPUT_UNIT, m_unitsOpt );
m_config->Write( OPTKEY_3DFILES_OPT, m_3DFilesOpt );
};
void SetSubdir( const wxString & aDir )
{
m_SubdirNameCtrl->SetValue( aDir);
}
wxString GetSubdir( )
{
return m_SubdirNameCtrl->GetValue( );
}
wxFilePickerCtrl* FilePicker()
{
return m_filePicker;
}
int GetUnits( )
{
return m_unitsOpt = m_rbSelectUnits->GetSelection();
}
int Get3DFilesOption( )
{
return m_3DFilesOpt = m_rb3DFilesOption->GetSelection();
}
};
/**
* Function OnExportVRML
* will export the current BOARD to a VRML file.
*/
void PCB_EDIT_FRAME::OnExportVRML( wxCommandEvent& event )
{
wxFileName fn;
static wxString subDirFor3Dshapes = wxT("shapes3D");
// The general VRML scale factor
// Assuming the VRML default unit is the mm
// this is the mm to VRML scaling factor for inch, mm and meter
double scaleList[3] = { 1.0/25.4, 1, 0.001 };
// Build default file name
wxString ext = wxT( "wrl" );
fn = GetBoard()->GetFileName();
fn.SetExt( ext );
DIALOG_EXPORT_3DFILE dlg( this );
dlg.FilePicker()->SetPath( fn.GetFullPath() );
dlg.SetSubdir( subDirFor3Dshapes );
if( dlg.ShowModal() != wxID_OK )
return;
double scale = scaleList[dlg.GetUnits( )]; // final scale export
bool export3DFiles = dlg.Get3DFilesOption( ) == 0;
wxBusyCursor dummy;
wxString fullFilename = dlg.FilePicker()->GetPath();
subDirFor3Dshapes = dlg.GetSubdir();
if( ! wxDirExists( subDirFor3Dshapes ) )
wxMkdir( subDirFor3Dshapes );
if( ! ExportVRML_File( fullFilename, scale, export3DFiles, subDirFor3Dshapes ) )
{
wxString msg = _( "Unable to create " ) + fullFilename;
wxMessageBox( msg );
return;
}
}
// I use this a lot... // I use this a lot...
static const double PI2 = M_PI / 2; static const double PI2 = M_PI / 2;
// Absolutely not optimized triangle bag :D struct POINT_3D
struct VRMLPt
{ {
double x, y, z; double x, y, z;
}; };
struct FlatPt
struct POINT_2D
{ {
FlatPt( double _x = 0, double _y = 0 ) : x( _x ), y( _y ) POINT_2D( double _x = 0, double _y = 0 ) : x( _x ), y( _y )
{ } { }
double x, y; double x, y;
}; };
struct Triangle
// Absolutely not optimized triangle bag :D
struct TRIANGLE
{ {
Triangle( double x1, double y1, double z1, TRIANGLE( double x1, double y1, double z1,
double x2, double y2, double z2, double x2, double y2, double z2,
double x3, double y3, double z3 ) double x3, double y3, double z3 )
{ {
@ -166,36 +80,36 @@ struct Triangle
p2.x = x2; p2.y = y2; p2.z = z2; p2.x = x2; p2.y = y2; p2.z = z2;
p3.x = x3; p3.y = y3; p3.z = z3; p3.x = x3; p3.y = y3; p3.z = z3;
} }
Triangle() { } TRIANGLE() { }
VRMLPt p1, p2, p3; POINT_3D p1, p2, p3;
}; };
typedef std::vector<Triangle> TriangleBag; typedef std::vector<TRIANGLE> TRIANGLEBAG;
// A flat triangle fan // A flat triangle fan
struct FlatFan struct FLAT_FAN
{ {
FlatPt c; POINT_2D c;
std::vector<FlatPt> pts; std::vector<POINT_2D> pts;
void add( double x, double y ) void add( double x, double y )
{ {
pts.push_back( FlatPt( x, y ) ); pts.push_back( POINT_2D( x, y ) );
} }
void bag( int layer, bool close = true ); void bag( int layer, bool close = true );
}; };
// A flat quad ring // A flat quad ring
struct FlatRing struct FLAT_RING
{ {
std::vector<FlatPt> inner; std::vector<POINT_2D> inner;
std::vector<FlatPt> outer; std::vector<POINT_2D> outer;
void add_inner( double x, double y ) void add_inner( double x, double y )
{ {
inner.push_back( FlatPt( x, y ) ); inner.push_back( POINT_2D( x, y ) );
} }
void add_outer( double x, double y ) void add_outer( double x, double y )
{ {
outer.push_back( FlatPt( x, y ) ); outer.push_back( POINT_2D( x, y ) );
} }
void bag( int layer, bool close = true ); void bag( int layer, bool close = true );
@ -204,19 +118,19 @@ struct FlatRing
// A vertical quad loop // A vertical quad loop
struct VLoop struct VLoop
{ {
std::vector<FlatPt> pts; std::vector<POINT_2D> pts;
double z_top, z_bottom; double z_top, z_bottom;
void add( double x, double y ) void add( double x, double y )
{ {
pts.push_back( FlatPt( x, y ) ); pts.push_back( POINT_2D( x, y ) );
} }
void bag( TriangleBag& triangles, bool close = true ); void bag( TRIANGLEBAG& triangles, bool close = true );
}; };
// The bags for all the layers // The bags for all the layers
static TriangleBag layer_triangles[LAYER_COUNT]; static TRIANGLEBAG layer_triangles[LAYER_COUNT];
static TriangleBag via_triangles[4]; static TRIANGLEBAG via_triangles[4];
static double layer_z[LAYER_COUNT]; static double layer_z[LAYER_COUNT];
static void bag_flat_triangle( int layer, //{{{ static void bag_flat_triangle( int layer, //{{{
@ -226,11 +140,11 @@ static void bag_flat_triangle( int layer, //{{{
{ {
double z = layer_z[layer]; double z = layer_z[layer];
layer_triangles[layer].push_back( Triangle( x1, y1, z, x2, y2, z, x3, y3, z ) ); layer_triangles[layer].push_back( TRIANGLE( x1, y1, z, x2, y2, z, x3, y3, z ) );
} }
void FlatFan::bag( int layer, bool close ) //{{{ void FLAT_FAN::bag( int layer, bool close ) //{{{
{ {
unsigned i; unsigned i;
@ -253,7 +167,7 @@ static void bag_flat_quad( int layer, //{{{
} }
void FlatRing::bag( int layer, bool close ) //{{{ void FLAT_RING::bag( int layer, bool close ) //{{{
{ {
unsigned i; unsigned i;
@ -273,20 +187,20 @@ void FlatRing::bag( int layer, bool close ) //{{{
} }
static void bag_vquad( TriangleBag& triangles, //{{{ static void bag_vquad( TRIANGLEBAG& triangles, //{{{
double x1, double y1, double x2, double y2, double x1, double y1, double x2, double y2,
double z1, double z2 ) double z1, double z2 )
{ {
triangles.push_back( Triangle( x1, y1, z1, triangles.push_back( TRIANGLE( x1, y1, z1,
x2, y2, z1, x2, y2, z1,
x2, y2, z2 ) ); x2, y2, z2 ) );
triangles.push_back( Triangle( x1, y1, z1, triangles.push_back( TRIANGLE( x1, y1, z1,
x2, y2, z2, x2, y2, z2,
x1, y1, z2 ) ); x1, y1, z2 ) );
} }
void VLoop::bag( TriangleBag& triangles, bool close ) //{{{ void VLoop::bag( TRIANGLEBAG& triangles, bool close ) //{{{
{ {
unsigned i; unsigned i;
@ -303,16 +217,14 @@ void VLoop::bag( TriangleBag& triangles, bool close ) //{{{
static void write_triangle_bag( FILE* output_file, int color_index, //{{{ static void write_triangle_bag( FILE* output_file, int color_index, //{{{
const TriangleBag& triangles ) const TRIANGLEBAG& triangles,
double boardIU2WRML )
{ {
/* A lot of nodes are not required, but blender sometimes chokes /* A lot of nodes are not required, but blender sometimes chokes
* without them */ * without them */
static const char* shape_boiler[] = static const char* shape_boiler[] =
{ {
"Transform {\n", "Transform {\n",
" translation 0.0 0.0 0.0\n",
" rotation 1.0 0.0 0.0 0.0\n",
" scale 1.0 1.0 1.0\n",
" children [\n", " children [\n",
" Group {\n", " Group {\n",
" children [\n", " children [\n",
@ -375,16 +287,19 @@ static void write_triangle_bag( FILE* output_file, int color_index, //{{{
case 2: case 2:
{ {
// Coordinates marker // Coordinates marker
for( TriangleBag::const_iterator i = triangles.begin(); for( TRIANGLEBAG::const_iterator i = triangles.begin();
i != triangles.end(); i != triangles.end();
i++ ) i++ )
{ {
fprintf( output_file, "%g %g %g\n", fprintf( output_file, "%.8g %.8g %.8g\n",
i->p1.x, -i->p1.y, i->p1.z ); i->p1.x * boardIU2WRML, -i->p1.y * boardIU2WRML,
fprintf( output_file, "%g %g %g\n", i->p1.z * boardIU2WRML );
i->p2.x, -i->p2.y, i->p2.z ); fprintf( output_file, "%.8g %.8g %.8g\n",
fprintf( output_file, "%g %g %g\n", i->p2.x * boardIU2WRML, -i->p2.y * boardIU2WRML,
i->p3.x, -i->p3.y, i->p3.z ); i->p2.z * boardIU2WRML );
fprintf( output_file, "%.8g %.8g %.8g\n",
i->p3.x * boardIU2WRML, -i->p3.y * boardIU2WRML,
i->p3.z * boardIU2WRML );
} }
} }
break; break;
@ -394,7 +309,7 @@ static void write_triangle_bag( FILE* output_file, int color_index, //{{{
// Index marker // Index marker
// OK, that's sick ... // OK, that's sick ...
int j = 0; int j = 0;
for( TriangleBag::const_iterator i = triangles.begin(); for( TRIANGLEBAG::const_iterator i = triangles.begin();
i != triangles.end(); i != triangles.end();
i++ ) i++ )
{ {
@ -455,7 +370,7 @@ static void export_vrml_line( int layer, double startx, double starty, //{{{
double r = width / 2; double r = width / 2;
double angle = atan2( endy - starty, endx - startx ); double angle = atan2( endy - starty, endx - startx );
double alpha; double alpha;
FlatFan fan; FLAT_FAN fan;
// Output the 'bone' as a triangle fan, this is the fan centre // Output the 'bone' as a triangle fan, this is the fan centre
fan.c.x = (startx + endx) / 2; fan.c.x = (startx + endx) / 2;
@ -482,12 +397,12 @@ static void export_vrml_circle( int layer, double startx, double starty,
double endx, double endy, double width ) double endx, double endy, double width )
{ {
double hole, radius; double hole, radius;
FlatRing ring; FLAT_RING ring;
radius = hypot( startx - endx, starty - endy ) + ( width / 2); radius = hypot( startx - endx, starty - endy ) + ( width / 2);
hole = radius - width; hole = radius - width;
for( double alpha = 0; alpha < M_PI * 2; alpha += M_PI * 2 / SEGM_COUNT_PER_360 ) for( double alpha = 0; alpha < M_PI * 2; alpha += INC_ANGLE )
{ {
ring.add_inner( startx + hole * cos( alpha ), starty + hole * sin( alpha ) ); ring.add_inner( startx + hole * cos( alpha ), starty + hole * sin( alpha ) );
ring.add_outer( startx + radius * cos( alpha ), starty + radius * sin( alpha ) ); ring.add_outer( startx + radius * cos( alpha ), starty + radius * sin( alpha ) );
@ -497,7 +412,7 @@ static void export_vrml_circle( int layer, double startx, double starty,
} }
static void export_vrml_slot( TriangleBag& triangles, //{{{ static void export_vrml_slot( TRIANGLEBAG& triangles, //{{{
int top_layer, int bottom_layer, double xc, double yc, int top_layer, int bottom_layer, double xc, double yc,
double dx, double dy, int orient ) double dx, double dy, int orient )
{ {
@ -541,7 +456,8 @@ static void export_vrml_slot( TriangleBag& triangles, //{{{
} }
static void export_vrml_hole( TriangleBag& triangles, int top_layer, int bottom_layer, static void export_vrml_hole( TRIANGLEBAG& triangles,
int top_layer, int bottom_layer,
double xc, double yc, double hole ) double xc, double yc, double hole )
{ {
VLoop loop; VLoop loop;
@ -549,7 +465,7 @@ static void export_vrml_hole( TriangleBag& triangles, int top_layer, int bottom_
loop.z_top = layer_z[top_layer]; loop.z_top = layer_z[top_layer];
loop.z_bottom = layer_z[bottom_layer]; loop.z_bottom = layer_z[bottom_layer];
for( double alpha = 0; alpha < M_PI * 2; alpha += M_PI * 2 / SEGM_COUNT_PER_360 ) for( double alpha = 0; alpha < M_PI * 2; alpha += INC_ANGLE )
loop.add( xc + cos( alpha ) * hole, yc + sin( alpha ) * hole ); loop.add( xc + cos( alpha ) * hole, yc + sin( alpha ) * hole );
loop.bag( triangles ); loop.bag( triangles );
@ -560,7 +476,7 @@ static void export_vrml_oval_pad( int layer, double xc, double yc,
double dx, double dy, int orient ) double dx, double dy, int orient )
{ {
double capx, capy; // Cap center double capx, capy; // Cap center
FlatFan fan; FLAT_FAN fan;
fan.c.x = xc; fan.c.x = xc;
fan.c.y = yc; fan.c.y = yc;
@ -603,7 +519,7 @@ static void export_vrml_arc( int layer, double centerx, double centery,
double arc_startx, double arc_starty, double arc_startx, double arc_starty,
double width, double arc_angle ) double width, double arc_angle )
{ {
FlatRing ring; FLAT_RING ring;
double start_angle = atan2( arc_starty - centery, arc_startx - centerx ); double start_angle = atan2( arc_starty - centery, arc_startx - centerx );
int count = KiROUND( arc_angle / 360.0 * SEGM_COUNT_PER_360 ); int count = KiROUND( arc_angle / 360.0 * SEGM_COUNT_PER_360 );
@ -630,7 +546,7 @@ static void export_vrml_arc( int layer, double centerx, double centery,
ring.bag( layer, false ); ring.bag( layer, false );
} }
static void export_vrml_varc( TriangleBag& triangles, static void export_vrml_varc( TRIANGLEBAG& triangles,
int top_layer, int bottom_layer, int top_layer, int bottom_layer,
double centerx, double centery, double centerx, double centery,
double arc_startx, double arc_starty, double arc_startx, double arc_starty,
@ -803,7 +719,8 @@ static void export_vrml_drawings( BOARD* pcb ) //{{{
} }
static void export_round_padstack( BOARD* pcb, double x, double y, double r, //{{{ static void export_round_padstack( BOARD* pcb, double x, double y,
double r,
int bottom_layer, int top_layer ) int bottom_layer, int top_layer )
{ {
int copper_layers = pcb->GetCopperLayerCount( ); int copper_layers = pcb->GetCopperLayerCount( );
@ -1098,7 +1015,8 @@ static void compose_quat( double q1[4], double q2[4], double qr[4] )
static void export_vrml_module( BOARD* aPcb, MODULE* aModule, static void export_vrml_module( BOARD* aPcb, MODULE* aModule,
FILE* aOutputFile, FILE* aOutputFile,
double aVRMLModelsToBiu, double aVRMLModelsToBiu,
bool aExport3DFiles, const wxString & a3D_Subdir ) bool aExport3DFiles, const wxString & a3D_Subdir,
double boardIU2WRML )
{ {
// Reference and value // Reference and value
export_vrml_text_module( aModule->m_Reference ); export_vrml_text_module( aModule->m_Reference );
@ -1206,9 +1124,9 @@ static void export_vrml_module( BOARD* aPcb, MODULE* aModule,
RotatePoint(&offsetx, &offsety, aModule->GetOrientation()); RotatePoint(&offsetx, &offsety, aModule->GetOrientation());
fprintf( aOutputFile, " translation %g %g %g\n", fprintf( aOutputFile, " translation %g %g %g\n",
(double) (offsetx + aModule->m_Pos.x), (double) (offsetx + aModule->m_Pos.x) * boardIU2WRML,
- (double)(offsety + aModule->m_Pos.y), // Y axis is reversed in Pcbnew - (double)(offsety + aModule->m_Pos.y) * boardIU2WRML, // Y axis is reversed in Pcbnew
offsetz + layer_z[aModule->GetLayer()] ); offsetz + layer_z[aModule->GetLayer()] * boardIU2WRML);
fprintf( aOutputFile, " scale %g %g %g\n", fprintf( aOutputFile, " scale %g %g %g\n",
vrmlm->m_MatScale.x * aVRMLModelsToBiu, vrmlm->m_MatScale.x * aVRMLModelsToBiu,
@ -1216,6 +1134,7 @@ static void export_vrml_module( BOARD* aPcb, MODULE* aModule,
vrmlm->m_MatScale.z * aVRMLModelsToBiu ); vrmlm->m_MatScale.z * aVRMLModelsToBiu );
fprintf( aOutputFile, fprintf( aOutputFile,
// " children [\n Inline {\n url \"file://%s\"\n } ]\n",
" children [\n Inline {\n url \"%s\"\n } ]\n", " children [\n Inline {\n url \"%s\"\n } ]\n",
TO_UTF8( fname ) ); TO_UTF8( fname ) );
fprintf( aOutputFile, " }\n" ); fprintf( aOutputFile, " }\n" );
@ -1223,24 +1142,23 @@ static void export_vrml_module( BOARD* aPcb, MODULE* aModule,
} }
static void write_and_empty_triangle_bag( FILE* output_file, TriangleBag& triangles, int color ) static void write_and_empty_triangle_bag( FILE* output_file, TRIANGLEBAG& triangles,
int color, double boardIU2WRML )
{ {
if( !triangles.empty() ) if( !triangles.empty() )
{ {
write_triangle_bag( output_file, color, triangles ); write_triangle_bag( output_file, color, triangles, boardIU2WRML );
triangles.clear( ); triangles.clear( );
} }
} }
/** /* ExportVRML_File
* Function ExportVRML_File
* Creates the file(s) exporting current BOARD to a VRML file. * Creates the file(s) exporting current BOARD to a VRML file.
* @param aFullFileName = the full filename of the file to create * aFullFileName = the full filename of the file to create
* @param aMMtoWRMLunit = the general scaling factor. 1.0 to export in mm * aMMtoWRMLunit = the general WRML scaling factor. 1.0 to export in mm
* @param aExport3DFiles = true to copy 3D shapes in the subdir a3D_Subdir * @param aExport3DFiles = true to copy 3D shapes in the subdir a3D_Subdir
* @param a3D_Subdir = sub directory where 3D shapes files are copied * a3D_Subdir = sub directory where 3D shapes files are copied
* used only when aExport3DFiles == true * used only when aExport3DFiles == true
* @return true if Ok.
*/ */
/* Note1: /* Note1:
* When copying 3D shapes files, the new filename is build from * When copying 3D shapes files, the new filename is build from
@ -1290,8 +1208,6 @@ bool PCB_EDIT_FRAME::ExportVRML_File( const wxString & aFullFileName,
// (aMMtoWRMLScale = 1.0 to export in mm) // (aMMtoWRMLScale = 1.0 to export in mm)
double boardIU2WRML = aMMtoWRMLunit / MM_PER_IU; double boardIU2WRML = aMMtoWRMLunit / MM_PER_IU;
fprintf( output_file, "Transform {\n" ); fprintf( output_file, "Transform {\n" );
fprintf( output_file, " scale %g %g %g\n",
boardIU2WRML , boardIU2WRML, boardIU2WRML );
/* Define the translation to have the board centre to the 2D axis origin /* Define the translation to have the board centre to the 2D axis origin
* more easy for rotations... * more easy for rotations...
@ -1302,7 +1218,6 @@ bool PCB_EDIT_FRAME::ExportVRML_File( const wxString & aFullFileName,
double dy = boardIU2WRML * bbbox.Centre().y; double dy = boardIU2WRML * bbbox.Centre().y;
fprintf( output_file, " translation %g %g 0.0\n", -dx, dy ); fprintf( output_file, " translation %g %g 0.0\n", -dx, dy );
fprintf( output_file, " children [\n" ); fprintf( output_file, " children [\n" );
// Preliminary computation: the z value for each layer // Preliminary computation: the z value for each layer
@ -1322,27 +1237,30 @@ bool PCB_EDIT_FRAME::ExportVRML_File( const wxString & aFullFileName,
* Usually we use Wings3D to create thems. * Usually we use Wings3D to create thems.
* One can consider the 3D units is 0.1 inch (2.54 mm) * One can consider the 3D units is 0.1 inch (2.54 mm)
* So the scaling factor from 0.1 inch to board units * So the scaling factor from 0.1 inch to board units
* is 0.1 / general_scaling_factor * is 2.54 * aMMtoWRMLunit
*/ */
double wrml_3D_models_scaling_factor = 2.54 / boardIU2WRML; double wrml_3D_models_scaling_factor = 2.54 * aMMtoWRMLunit;
// Export footprints // Export footprints
for( MODULE* module = pcb->m_Modules; module != 0; module = module->Next() ) for( MODULE* module = pcb->m_Modules; module != 0; module = module->Next() )
export_vrml_module( pcb, module, output_file, export_vrml_module( pcb, module, output_file,
wrml_3D_models_scaling_factor, wrml_3D_models_scaling_factor,
aExport3DFiles, a3D_Subdir ); aExport3DFiles, a3D_Subdir,
boardIU2WRML );
/* Output the bagged triangles for each layer /* Output the bagged triangles for each layer
* Each layer will be a separate shape */ * Each layer will be a separate shape */
for( int layer = 0; layer < LAYER_COUNT; layer++ ) for( int layer = 0; layer < LAYER_COUNT; layer++ )
write_and_empty_triangle_bag( output_file, write_and_empty_triangle_bag( output_file,
layer_triangles[layer], layer_triangles[layer],
pcb->GetLayerColor(layer) ); pcb->GetLayerColor(layer),
boardIU2WRML );
// Same thing for the via layers // Same thing for the via layers
for( int i = 0; i < 4; i++ ) for( int i = 0; i < 4; i++ )
write_and_empty_triangle_bag( output_file, write_and_empty_triangle_bag( output_file,
via_triangles[i], via_triangles[i],
pcb->GetVisibleElementColor( VIAS_VISIBLE + i ) ); pcb->GetVisibleElementColor( VIAS_VISIBLE + i ),
boardIU2WRML );
// Close the outer 'transform' node // Close the outer 'transform' node
fputs( "]\n}\n", output_file ); fputs( "]\n}\n", output_file );