vrml exporter: more cleaning code and enhancements. Dialog exporter: Add option to use board center as coord origin.
This commit is contained in:
parent
b050823c98
commit
074f0432f0
|
@ -1,7 +1,3 @@
|
|||
/**
|
||||
* @file dialog_export_vrml.cpp
|
||||
*/
|
||||
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
|
@ -26,6 +22,10 @@
|
|||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
/**
|
||||
* @file dialog_export_vrml.cpp
|
||||
*/
|
||||
|
||||
#include <wx/dir.h>
|
||||
|
||||
#include <board.h>
|
||||
|
@ -53,6 +53,8 @@ private:
|
|||
int m_RefUnits; // Remember last units for Reference Point
|
||||
double m_XRef; // Remember last X Reference Point
|
||||
double m_YRef; // Remember last Y Reference Point
|
||||
int m_originMode; // Origin selection option
|
||||
// (0 = user, 1 = board center)
|
||||
|
||||
public:
|
||||
DIALOG_EXPORT_3DFILE( PCB_EDIT_FRAME* parent ) :
|
||||
|
@ -60,7 +62,7 @@ public:
|
|||
{
|
||||
m_filePicker->SetFocus();
|
||||
|
||||
auto cfg = m_parent->GetPcbNewSettings();
|
||||
PCBNEW_SETTINGS* cfg = m_parent->GetPcbNewSettings();
|
||||
|
||||
m_unitsOpt = cfg->m_ExportVrml.units;
|
||||
m_copy3DFilesOpt = cfg->m_ExportVrml.copy_3d_models;
|
||||
|
@ -69,7 +71,10 @@ public:
|
|||
m_RefUnits = cfg->m_ExportVrml.ref_units;
|
||||
m_XRef = cfg->m_ExportVrml.ref_x;
|
||||
m_YRef = cfg->m_ExportVrml.ref_y;
|
||||
m_originMode = cfg->m_ExportVrml.origin_mode;
|
||||
|
||||
|
||||
m_rbCoordOrigin->SetSelection( m_originMode );
|
||||
m_rbSelectUnits->SetSelection( m_unitsOpt );
|
||||
m_cbCopyFiles->SetValue( m_copy3DFilesOpt );
|
||||
m_cbUseRelativePaths->SetValue( m_useRelativePathsOpt );
|
||||
|
@ -81,13 +86,10 @@ public:
|
|||
tmpStr = wxT( "" );
|
||||
tmpStr << m_YRef;
|
||||
m_VRML_Yref->SetValue( tmpStr );
|
||||
m_sdbSizer1OK->SetDefault();
|
||||
m_sdbSizerOK->SetDefault();
|
||||
|
||||
// Now all widgets have the size fixed, call FinishDialogSettings
|
||||
finishDialogSettings();
|
||||
|
||||
Connect( ID_USE_ABS_PATH, wxEVT_UPDATE_UI,
|
||||
wxUpdateUIEventHandler( DIALOG_EXPORT_3DFILE::OnUpdateUseRelativePath ) );
|
||||
}
|
||||
|
||||
~DIALOG_EXPORT_3DFILE()
|
||||
|
@ -95,13 +97,14 @@ public:
|
|||
m_unitsOpt = GetUnits();
|
||||
m_copy3DFilesOpt = GetCopyFilesOption();
|
||||
|
||||
auto cfg = m_parent->GetPcbNewSettings();
|
||||
PCBNEW_SETTINGS* cfg = m_parent->GetPcbNewSettings();
|
||||
|
||||
cfg->m_ExportVrml.units = m_unitsOpt;
|
||||
cfg->m_ExportVrml.copy_3d_models = m_copy3DFilesOpt;
|
||||
cfg->m_ExportVrml.use_relative_paths = m_useRelativePathsOpt;
|
||||
cfg->m_ExportVrml.use_plain_pcb = m_usePlainPCBOpt;
|
||||
cfg->m_ExportVrml.ref_units = m_VRML_RefUnitChoice->GetSelection();
|
||||
cfg->m_ExportVrml.origin_mode = m_rbCoordOrigin->GetSelection();
|
||||
|
||||
double val = 0.0;
|
||||
m_VRML_Xref->GetValue().ToDouble( &val );
|
||||
|
@ -131,6 +134,11 @@ public:
|
|||
return m_VRML_RefUnitChoice->GetSelection();
|
||||
}
|
||||
|
||||
int GetOriginChoice()
|
||||
{
|
||||
return m_rbCoordOrigin->GetSelection();
|
||||
}
|
||||
|
||||
double GetXRef()
|
||||
{
|
||||
return DoubleValueFromString( EDA_UNITS::UNSCALED, m_VRML_Xref->GetValue() );
|
||||
|
@ -161,7 +169,7 @@ public:
|
|||
return m_usePlainPCBOpt = m_cbPlainPCB->GetValue();
|
||||
}
|
||||
|
||||
void OnUpdateUseRelativePath( wxUpdateUIEvent& event )
|
||||
void OnUpdateUseRelativePath( wxUpdateUIEvent& event ) override
|
||||
{
|
||||
// Making path relative or absolute has no meaning when VRML files are not copied.
|
||||
event.Enable( m_cbCopyFiles->GetValue() );
|
||||
|
@ -226,6 +234,15 @@ void PCB_EDIT_FRAME::OnExportVRML( wxCommandEvent& event )
|
|||
aYRef *= 25.4;
|
||||
}
|
||||
|
||||
if( dlg.GetOriginChoice() == 1 )
|
||||
{
|
||||
// Origin = board center:
|
||||
BOARD* pcb = GetBoard();
|
||||
wxPoint center = pcb->GetBoundingBox().GetCenter();
|
||||
aXRef = Iu2Millimeter( center.x );
|
||||
aYRef = Iu2Millimeter( center.y );
|
||||
}
|
||||
|
||||
double scale = scaleList[dlg.GetUnits()]; // final scale export
|
||||
bool export3DFiles = dlg.GetCopyFilesOption();
|
||||
bool useRelativePaths = dlg.GetUseRelativePathsOption();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 3.9.0 Nov 1 2020)
|
||||
// C++ code generated with wxFormBuilder (version Oct 26 2018)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
|
@ -38,19 +38,21 @@ DIALOG_EXPORT_3DFILE_BASE::DIALOG_EXPORT_3DFILE_BASE( wxWindow* parent, wxWindow
|
|||
|
||||
bSizer1->Add( bUpperSizer, 0, wxALL|wxEXPAND, 5 );
|
||||
|
||||
wxBoxSizer* bSizer12;
|
||||
bSizer12 = new wxBoxSizer( wxHORIZONTAL );
|
||||
wxBoxSizer* bSizerOptions;
|
||||
bSizerOptions = new wxBoxSizer( wxHORIZONTAL );
|
||||
|
||||
wxBoxSizer* bSizer5;
|
||||
bSizer5 = new wxBoxSizer( wxVERTICAL );
|
||||
wxString m_rbCoordOriginChoices[] = { _("User defined origin"), _("Board center origin") };
|
||||
int m_rbCoordOriginNChoices = sizeof( m_rbCoordOriginChoices ) / sizeof( wxString );
|
||||
m_rbCoordOrigin = new wxRadioBox( this, wxID_ANY, _("Coordinate origin options:"), wxDefaultPosition, wxDefaultSize, m_rbCoordOriginNChoices, m_rbCoordOriginChoices, 1, wxRA_SPECIFY_COLS );
|
||||
m_rbCoordOrigin->SetSelection( 0 );
|
||||
bSizerOptions->Add( m_rbCoordOrigin, 1, wxALL|wxEXPAND, 5 );
|
||||
|
||||
m_panel1 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
|
||||
wxBoxSizer* bSizer9;
|
||||
bSizer9 = new wxBoxSizer( wxVERTICAL );
|
||||
wxBoxSizer* bSizerVrmlUnits;
|
||||
bSizerVrmlUnits = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
m_staticText6 = new wxStaticText( m_panel1, wxID_ANY, _("Grid reference point:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText6 = new wxStaticText( this, wxID_ANY, _("User defined origin:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText6->Wrap( -1 );
|
||||
bSizer9->Add( m_staticText6, 0, wxALL, 5 );
|
||||
bSizerVrmlUnits->Add( m_staticText6, 0, wxALL, 5 );
|
||||
|
||||
wxFlexGridSizer* fgSizerOptions;
|
||||
fgSizerOptions = new wxFlexGridSizer( 0, 2, 0, 0 );
|
||||
|
@ -58,21 +60,21 @@ DIALOG_EXPORT_3DFILE_BASE::DIALOG_EXPORT_3DFILE_BASE( wxWindow* parent, wxWindow
|
|||
fgSizerOptions->SetFlexibleDirection( wxBOTH );
|
||||
fgSizerOptions->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
|
||||
|
||||
m_staticText61 = new wxStaticText( m_panel1, wxID_ANY, _("Units:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText61 = new wxStaticText( this, wxID_ANY, _("Units:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText61->Wrap( -1 );
|
||||
fgSizerOptions->Add( m_staticText61, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
wxString m_VRML_RefUnitChoiceChoices[] = { _("mm"), _("inch") };
|
||||
int m_VRML_RefUnitChoiceNChoices = sizeof( m_VRML_RefUnitChoiceChoices ) / sizeof( wxString );
|
||||
m_VRML_RefUnitChoice = new wxChoice( m_panel1, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_VRML_RefUnitChoiceNChoices, m_VRML_RefUnitChoiceChoices, 0 );
|
||||
m_VRML_RefUnitChoice = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_VRML_RefUnitChoiceNChoices, m_VRML_RefUnitChoiceChoices, 0 );
|
||||
m_VRML_RefUnitChoice->SetSelection( 0 );
|
||||
fgSizerOptions->Add( m_VRML_RefUnitChoice, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
|
||||
|
||||
m_staticText4 = new wxStaticText( m_panel1, wxID_ANY, _("X:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText4 = new wxStaticText( this, wxID_ANY, _("X:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText4->Wrap( -1 );
|
||||
fgSizerOptions->Add( m_staticText4, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
m_VRML_Xref = new wxTextCtrl( m_panel1, wxID_ANY, _("0"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_VRML_Xref = new wxTextCtrl( this, wxID_ANY, _("0"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
#ifdef __WXGTK__
|
||||
if ( !m_VRML_Xref->HasFlag( wxTE_MULTILINE ) )
|
||||
{
|
||||
|
@ -83,11 +85,11 @@ DIALOG_EXPORT_3DFILE_BASE::DIALOG_EXPORT_3DFILE_BASE( wxWindow* parent, wxWindow
|
|||
#endif
|
||||
fgSizerOptions->Add( m_VRML_Xref, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
m_staticText5 = new wxStaticText( m_panel1, wxID_ANY, _("Y:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText5 = new wxStaticText( this, wxID_ANY, _("Y:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText5->Wrap( -1 );
|
||||
fgSizerOptions->Add( m_staticText5, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
m_VRML_Yref = new wxTextCtrl( m_panel1, wxID_ANY, _("0"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_VRML_Yref = new wxTextCtrl( this, wxID_ANY, _("0"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
#ifdef __WXGTK__
|
||||
if ( !m_VRML_Yref->HasFlag( wxTE_MULTILINE ) )
|
||||
{
|
||||
|
@ -99,25 +101,19 @@ DIALOG_EXPORT_3DFILE_BASE::DIALOG_EXPORT_3DFILE_BASE( wxWindow* parent, wxWindow
|
|||
fgSizerOptions->Add( m_VRML_Yref, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
|
||||
bSizer9->Add( fgSizerOptions, 1, wxEXPAND, 5 );
|
||||
bSizerVrmlUnits->Add( fgSizerOptions, 1, wxEXPAND, 5 );
|
||||
|
||||
|
||||
m_panel1->SetSizer( bSizer9 );
|
||||
m_panel1->Layout();
|
||||
bSizer9->Fit( m_panel1 );
|
||||
bSizer5->Add( m_panel1, 1, wxEXPAND | wxALL, 5 );
|
||||
|
||||
|
||||
bSizer12->Add( bSizer5, 1, wxEXPAND, 5 );
|
||||
bSizerOptions->Add( bSizerVrmlUnits, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
wxString m_rbSelectUnitsChoices[] = { _("mm"), _("meter"), _("0.1 Inch"), _("Inch") };
|
||||
int m_rbSelectUnitsNChoices = sizeof( m_rbSelectUnitsChoices ) / sizeof( wxString );
|
||||
m_rbSelectUnits = new wxRadioBox( this, wxID_ANY, _("Output Units"), wxDefaultPosition, wxDefaultSize, m_rbSelectUnitsNChoices, m_rbSelectUnitsChoices, 1, wxRA_SPECIFY_COLS );
|
||||
m_rbSelectUnits = new wxRadioBox( this, wxID_ANY, _("Vrml Units for Output Files"), wxDefaultPosition, wxDefaultSize, m_rbSelectUnitsNChoices, m_rbSelectUnitsChoices, 1, wxRA_SPECIFY_COLS );
|
||||
m_rbSelectUnits->SetSelection( 0 );
|
||||
bSizer12->Add( m_rbSelectUnits, 1, wxALL|wxEXPAND, 5 );
|
||||
bSizerOptions->Add( m_rbSelectUnits, 1, wxALL|wxEXPAND, 5 );
|
||||
|
||||
|
||||
bSizer1->Add( bSizer12, 0, wxEXPAND, 5 );
|
||||
bSizer1->Add( bSizerOptions, 0, wxEXPAND, 5 );
|
||||
|
||||
wxBoxSizer* bLowerSizer;
|
||||
bLowerSizer = new wxBoxSizer( wxHORIZONTAL );
|
||||
|
@ -126,10 +122,11 @@ DIALOG_EXPORT_3DFILE_BASE::DIALOG_EXPORT_3DFILE_BASE( wxWindow* parent, wxWindow
|
|||
bSizer4 = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
m_cbCopyFiles = new wxCheckBox( this, wxID_ANY, _("Copy 3D model files to 3D model path"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_cbCopyFiles->SetValue(true);
|
||||
m_cbCopyFiles->SetToolTip( _("If checked: copy footprints 3D models in a folder\nIf not checked: merge footprints 3D models in the vrml board file\n") );
|
||||
|
||||
bSizer4->Add( m_cbCopyFiles, 0, wxALL, 5 );
|
||||
|
||||
m_cbUseRelativePaths = new wxCheckBox( this, ID_USE_ABS_PATH, _("Use relative paths to model files in board VRML file"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_cbUseRelativePaths = new wxCheckBox( this, wxID_ANY, _("Use relative paths to model files in board VRML file"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_cbUseRelativePaths->SetToolTip( _("Use paths for model files in board VRML file relative to the vrml file") );
|
||||
|
||||
bSizer4->Add( m_cbUseRelativePaths, 0, wxALL, 5 );
|
||||
|
@ -149,21 +146,27 @@ DIALOG_EXPORT_3DFILE_BASE::DIALOG_EXPORT_3DFILE_BASE( wxWindow* parent, wxWindow
|
|||
m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
|
||||
bSizer1->Add( m_staticline1, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
m_sdbSizer1 = new wxStdDialogButtonSizer();
|
||||
m_sdbSizer1OK = new wxButton( this, wxID_OK );
|
||||
m_sdbSizer1->AddButton( m_sdbSizer1OK );
|
||||
m_sdbSizer1Cancel = new wxButton( this, wxID_CANCEL );
|
||||
m_sdbSizer1->AddButton( m_sdbSizer1Cancel );
|
||||
m_sdbSizer1->Realize();
|
||||
m_sdbSizer = new wxStdDialogButtonSizer();
|
||||
m_sdbSizerOK = new wxButton( this, wxID_OK );
|
||||
m_sdbSizer->AddButton( m_sdbSizerOK );
|
||||
m_sdbSizerCancel = new wxButton( this, wxID_CANCEL );
|
||||
m_sdbSizer->AddButton( m_sdbSizerCancel );
|
||||
m_sdbSizer->Realize();
|
||||
|
||||
bSizer1->Add( m_sdbSizer1, 0, wxEXPAND|wxALL, 5 );
|
||||
bSizer1->Add( m_sdbSizer, 0, wxEXPAND|wxALL, 5 );
|
||||
|
||||
|
||||
this->SetSizer( bSizer1 );
|
||||
this->Layout();
|
||||
bSizer1->Fit( this );
|
||||
|
||||
// Connect Events
|
||||
m_cbUseRelativePaths->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_EXPORT_3DFILE_BASE::OnUpdateUseRelativePath ), NULL, this );
|
||||
}
|
||||
|
||||
DIALOG_EXPORT_3DFILE_BASE::~DIALOG_EXPORT_3DFILE_BASE()
|
||||
{
|
||||
// Disconnect Events
|
||||
m_cbUseRelativePaths->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_EXPORT_3DFILE_BASE::OnUpdateUseRelativePath ), NULL, this );
|
||||
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,5 @@
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 3.9.0 Nov 1 2020)
|
||||
// C++ code generated with wxFormBuilder (version Oct 26 2018)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
|
@ -20,9 +20,8 @@
|
|||
#include <wx/filepicker.h>
|
||||
#include <wx/textctrl.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/choice.h>
|
||||
#include <wx/panel.h>
|
||||
#include <wx/radiobox.h>
|
||||
#include <wx/choice.h>
|
||||
#include <wx/checkbox.h>
|
||||
#include <wx/statline.h>
|
||||
#include <wx/button.h>
|
||||
|
@ -30,6 +29,7 @@
|
|||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// Class DIALOG_EXPORT_3DFILE_BASE
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -38,16 +38,11 @@ class DIALOG_EXPORT_3DFILE_BASE : public DIALOG_SHIM
|
|||
private:
|
||||
|
||||
protected:
|
||||
enum
|
||||
{
|
||||
ID_USE_ABS_PATH = 1000
|
||||
};
|
||||
|
||||
wxStaticText* m_staticText1;
|
||||
wxFilePickerCtrl* m_filePicker;
|
||||
wxStaticText* m_staticText3;
|
||||
wxTextCtrl* m_SubdirNameCtrl;
|
||||
wxPanel* m_panel1;
|
||||
wxRadioBox* m_rbCoordOrigin;
|
||||
wxStaticText* m_staticText6;
|
||||
wxStaticText* m_staticText61;
|
||||
wxChoice* m_VRML_RefUnitChoice;
|
||||
|
@ -60,9 +55,13 @@ class DIALOG_EXPORT_3DFILE_BASE : public DIALOG_SHIM
|
|||
wxCheckBox* m_cbUseRelativePaths;
|
||||
wxCheckBox* m_cbPlainPCB;
|
||||
wxStaticLine* m_staticline1;
|
||||
wxStdDialogButtonSizer* m_sdbSizer1;
|
||||
wxButton* m_sdbSizer1OK;
|
||||
wxButton* m_sdbSizer1Cancel;
|
||||
wxStdDialogButtonSizer* m_sdbSizer;
|
||||
wxButton* m_sdbSizerOK;
|
||||
wxButton* m_sdbSizerCancel;
|
||||
|
||||
// Virtual event handlers, overide them in your derived class
|
||||
virtual void OnUpdateUseRelativePath( wxUpdateUIEvent& event ) { event.Skip(); }
|
||||
|
||||
|
||||
public:
|
||||
|
||||
|
|
|
@ -54,25 +54,21 @@
|
|||
#include <exporter_vrml.h>
|
||||
|
||||
|
||||
static bool USE_INLINES; // true to use legacy inline{} behavior
|
||||
static bool USE_DEFS; // true to reuse component definitions
|
||||
static bool USE_RELPATH; // true to use relative paths in VRML inline{}
|
||||
static double WORLD_SCALE = 1.0; // scaling from 0.1 in to desired VRML unit
|
||||
static double BOARD_SCALE; // scaling from mm to desired VRML world scale
|
||||
static const int PRECISION = 6; // legacy precision factor (now set to 6)
|
||||
static wxString SUBDIR_3D; // legacy 3D subdirectory
|
||||
static wxString PROJ_DIR; // project directory
|
||||
|
||||
|
||||
static S3D_CACHE* cache;
|
||||
VRML_COLOR colors[VRML_COLOR_LAST];
|
||||
VRML_COLOR vrml_colors_list[VRML_COLOR_LAST];
|
||||
static SGNODE* sgmaterial[VRML_COLOR_LAST] = { NULL };
|
||||
|
||||
|
||||
|
||||
MODEL_VRML::MODEL_VRML() :
|
||||
m_OutputPCB( (SGNODE*) NULL )
|
||||
{
|
||||
m_ReuseDef = true;
|
||||
m_precision = 6;
|
||||
m_WorldScale = 1.0;
|
||||
|
||||
for( unsigned i = 0; i < arrayDim( m_layer_z ); ++i )
|
||||
m_layer_z[i] = 0;
|
||||
|
||||
|
@ -82,16 +78,16 @@ MODEL_VRML::MODEL_VRML() :
|
|||
m_brd_thickness = 1.6;
|
||||
|
||||
// pcb green
|
||||
colors[VRML_COLOR_PCB] = VRML_COLOR(
|
||||
vrml_colors_list[VRML_COLOR_PCB] = VRML_COLOR(
|
||||
0.07f, 0.3f, 0.12f, 0.01f, 0.03f, 0.01f, 0.0f, 0.0f, 0.0f, 0.8f, 0.0f, 0.02f );
|
||||
// copper color
|
||||
colors[VRML_COLOR_COPPER] = VRML_COLOR(
|
||||
vrml_colors_list[VRML_COLOR_COPPER] = VRML_COLOR(
|
||||
0.72f, 0.45f, 0.2f, 0.01f, 0.05f, 0.01f, 0.0f, 0.0f, 0.0f, 0.8f, 0.0f, 0.02f );
|
||||
// silkscreen white
|
||||
colors[VRML_COLOR_SILK] = VRML_COLOR(
|
||||
vrml_colors_list[VRML_COLOR_SILK] = VRML_COLOR(
|
||||
0.9f, 0.9f, 0.9f, 0.1f, 0.1f, 0.1f, 0.0f, 0.0f, 0.0f, 0.9f, 0.0f, 0.02f );
|
||||
// solder paste silver
|
||||
colors[VRML_COLOR_TIN] = VRML_COLOR( 0.749f, 0.756f, 0.761f, 0.749f, 0.756f, 0.761f, 0.0f,
|
||||
vrml_colors_list[VRML_COLOR_TIN] = VRML_COLOR( 0.749f, 0.756f, 0.761f, 0.749f, 0.756f, 0.761f, 0.0f,
|
||||
0.0f, 0.0f, 0.8f, 0.0f, 0.8f );
|
||||
|
||||
m_plainPCB = false;
|
||||
|
@ -136,7 +132,7 @@ bool MODEL_VRML::SetScale( double aWorldScale )
|
|||
throw( std::runtime_error( "WorldScale out of range (valid range is 0.001 to 10.0)" ) );
|
||||
|
||||
m_OutputPCB.SetScale( aWorldScale * 2.54 );
|
||||
WORLD_SCALE = aWorldScale * 2.54;
|
||||
m_WorldScale = aWorldScale * 2.54;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -175,6 +171,7 @@ bool MODEL_VRML::GetLayer3D( LAYER_NUM layer, VRML_LAYER** vlayer )
|
|||
|
||||
void MODEL_VRML::ExportVrmlSolderMask( BOARD* aPcb )
|
||||
{
|
||||
//TODO
|
||||
}
|
||||
|
||||
|
||||
|
@ -182,13 +179,7 @@ void MODEL_VRML::ExportVrmlSolderMask( BOARD* aPcb )
|
|||
static MODEL_VRML* model_vrml;
|
||||
|
||||
|
||||
static void create_vrml_shell( IFSG_TRANSFORM& PcbOutput, VRML_COLOR_INDEX colorID,
|
||||
VRML_LAYER* layer, double top_z, double bottom_z );
|
||||
|
||||
static void create_vrml_plane( IFSG_TRANSFORM& PcbOutput, VRML_COLOR_INDEX colorID,
|
||||
VRML_LAYER* layer, double aHeight, bool aTopPlane );
|
||||
|
||||
static void write_triangle_bag( std::ostream& aOut_file, const VRML_COLOR& aColor,
|
||||
void MODEL_VRML::write_triangle_bag( std::ostream& aOut_file, const VRML_COLOR& aColor,
|
||||
VRML_LAYER* aLayer, bool aPlane, bool aTop,
|
||||
double aTop_z, double aBottom_z )
|
||||
{
|
||||
|
@ -265,9 +256,9 @@ static void write_triangle_bag( std::ostream& aOut_file, const VRML_COLOR& aColo
|
|||
case 2:
|
||||
|
||||
if( aPlane )
|
||||
aLayer->WriteVertices( aTop_z, aOut_file, PRECISION );
|
||||
aLayer->WriteVertices( aTop_z, aOut_file, m_precision );
|
||||
else
|
||||
aLayer->Write3DVertices( aTop_z, aBottom_z, aOut_file, PRECISION );
|
||||
aLayer->Write3DVertices( aTop_z, aBottom_z, aOut_file, m_precision );
|
||||
|
||||
aOut_file << "\n";
|
||||
break;
|
||||
|
@ -292,144 +283,142 @@ static void write_triangle_bag( std::ostream& aOut_file, const VRML_COLOR& aColo
|
|||
}
|
||||
|
||||
|
||||
static void write_layers( MODEL_VRML& aModel, BOARD* aPcb, const char* aFileName,
|
||||
OSTREAM* aOutputFile )
|
||||
void MODEL_VRML::writeLayers( BOARD* aPcb, const char* aFileName,
|
||||
OSTREAM* aOutputFile )
|
||||
{
|
||||
// VRML_LAYER board;
|
||||
aModel.m_board.Tesselate( &aModel.m_holes );
|
||||
double brdz = aModel.m_brd_thickness / 2.0
|
||||
- ( Millimeter2iu( ART_OFFSET / 2.0 ) ) * BOARD_SCALE;
|
||||
m_board.Tesselate( &m_holes );
|
||||
double brdz = m_brd_thickness / 2.0
|
||||
- ( Millimeter2iu( ART_OFFSET / 2.0 ) ) * m_BoardToVrmlScale;
|
||||
|
||||
if( USE_INLINES )
|
||||
if( m_UseInlineModelsInBrdfile )
|
||||
{
|
||||
write_triangle_bag( *aOutputFile, aModel.GetColor( VRML_COLOR_PCB ),
|
||||
&aModel.m_board, false, false, brdz, -brdz );
|
||||
write_triangle_bag( *aOutputFile, GetColor( VRML_COLOR_PCB ),
|
||||
&m_board, false, false, brdz, -brdz );
|
||||
}
|
||||
else
|
||||
{
|
||||
create_vrml_shell( aModel.m_OutputPCB, VRML_COLOR_PCB, &aModel.m_board, brdz, -brdz );
|
||||
create_vrml_shell( m_OutputPCB, VRML_COLOR_PCB, &m_board, brdz, -brdz );
|
||||
}
|
||||
|
||||
if( aModel.m_plainPCB )
|
||||
if( m_plainPCB )
|
||||
{
|
||||
if( !USE_INLINES )
|
||||
S3D::WriteVRML( aFileName, true, aModel.m_OutputPCB.GetRawPtr(), USE_DEFS, true );
|
||||
if( !m_UseInlineModelsInBrdfile )
|
||||
S3D::WriteVRML( aFileName, true, m_OutputPCB.GetRawPtr(), m_ReuseDef, true );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// VRML_LAYER m_top_copper;
|
||||
aModel.m_top_copper.Tesselate( &aModel.m_holes );
|
||||
m_top_copper.Tesselate( &m_holes );
|
||||
|
||||
if( USE_INLINES )
|
||||
if( m_UseInlineModelsInBrdfile )
|
||||
{
|
||||
write_triangle_bag( *aOutputFile, aModel.GetColor( VRML_COLOR_COPPER ),
|
||||
&aModel.m_top_copper, true, true,
|
||||
aModel.GetLayerZ( F_Cu ), 0 );
|
||||
write_triangle_bag( *aOutputFile, GetColor( VRML_COLOR_COPPER ),
|
||||
&m_top_copper, true, true, GetLayerZ( F_Cu ), 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
create_vrml_plane( aModel.m_OutputPCB, VRML_COLOR_COPPER, &aModel.m_top_copper,
|
||||
aModel.GetLayerZ( F_Cu ), true );
|
||||
create_vrml_plane( m_OutputPCB, VRML_COLOR_COPPER, &m_top_copper,
|
||||
GetLayerZ( F_Cu ), true );
|
||||
}
|
||||
|
||||
// VRML_LAYER m_top_tin;
|
||||
aModel.m_top_tin.Tesselate( &aModel.m_holes );
|
||||
m_top_tin.Tesselate( &m_holes );
|
||||
|
||||
if( USE_INLINES )
|
||||
if( m_UseInlineModelsInBrdfile )
|
||||
{
|
||||
write_triangle_bag( *aOutputFile, aModel.GetColor( VRML_COLOR_TIN ),
|
||||
&aModel.m_top_tin, true, true,
|
||||
aModel.GetLayerZ( F_Cu ) + Millimeter2iu( ART_OFFSET / 2.0 ) * BOARD_SCALE,
|
||||
write_triangle_bag( *aOutputFile, GetColor( VRML_COLOR_TIN ),
|
||||
&m_top_tin, true, true,
|
||||
GetLayerZ( F_Cu ) + Millimeter2iu( ART_OFFSET / 2.0 ) * m_BoardToVrmlScale,
|
||||
0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
create_vrml_plane( aModel.m_OutputPCB, VRML_COLOR_TIN, &aModel.m_top_tin,
|
||||
aModel.GetLayerZ( F_Cu ) + Millimeter2iu( ART_OFFSET / 2.0 ) * BOARD_SCALE,
|
||||
create_vrml_plane( m_OutputPCB, VRML_COLOR_TIN, &m_top_tin,
|
||||
GetLayerZ( F_Cu ) + Millimeter2iu( ART_OFFSET / 2.0 ) * m_BoardToVrmlScale,
|
||||
true );
|
||||
}
|
||||
|
||||
// VRML_LAYER m_bot_copper;
|
||||
aModel.m_bot_copper.Tesselate( &aModel.m_holes );
|
||||
m_bot_copper.Tesselate( &m_holes );
|
||||
|
||||
if( USE_INLINES )
|
||||
if( m_UseInlineModelsInBrdfile )
|
||||
{
|
||||
write_triangle_bag( *aOutputFile, aModel.GetColor( VRML_COLOR_COPPER ),
|
||||
&aModel.m_bot_copper, true, false,
|
||||
aModel.GetLayerZ( B_Cu ), 0 );
|
||||
write_triangle_bag( *aOutputFile, GetColor( VRML_COLOR_COPPER ),
|
||||
&m_bot_copper, true, false, GetLayerZ( B_Cu ), 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
create_vrml_plane( aModel.m_OutputPCB, VRML_COLOR_COPPER, &aModel.m_bot_copper,
|
||||
aModel.GetLayerZ( B_Cu ), false );
|
||||
create_vrml_plane( m_OutputPCB, VRML_COLOR_COPPER, &m_bot_copper,
|
||||
GetLayerZ( B_Cu ), false );
|
||||
}
|
||||
|
||||
// VRML_LAYER m_bot_tin;
|
||||
aModel.m_bot_tin.Tesselate( &aModel.m_holes );
|
||||
m_bot_tin.Tesselate( &m_holes );
|
||||
|
||||
if( USE_INLINES )
|
||||
if( m_UseInlineModelsInBrdfile )
|
||||
{
|
||||
write_triangle_bag( *aOutputFile, aModel.GetColor( VRML_COLOR_TIN ),
|
||||
&aModel.m_bot_tin, true, false,
|
||||
aModel.GetLayerZ( B_Cu )
|
||||
- Millimeter2iu( ART_OFFSET / 2.0 ) * BOARD_SCALE,
|
||||
write_triangle_bag( *aOutputFile, GetColor( VRML_COLOR_TIN ),
|
||||
&m_bot_tin, true, false,
|
||||
GetLayerZ( B_Cu )
|
||||
- Millimeter2iu( ART_OFFSET / 2.0 ) * m_BoardToVrmlScale,
|
||||
0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
create_vrml_plane( aModel.m_OutputPCB, VRML_COLOR_TIN, &aModel.m_bot_tin,
|
||||
aModel.GetLayerZ( B_Cu ) - Millimeter2iu( ART_OFFSET / 2.0 ) * BOARD_SCALE,
|
||||
create_vrml_plane( m_OutputPCB, VRML_COLOR_TIN, &m_bot_tin,
|
||||
GetLayerZ( B_Cu ) - Millimeter2iu( ART_OFFSET / 2.0 ) * m_BoardToVrmlScale,
|
||||
false );
|
||||
}
|
||||
|
||||
// VRML_LAYER PTH;
|
||||
aModel.m_plated_holes.Tesselate( NULL, true );
|
||||
m_plated_holes.Tesselate( NULL, true );
|
||||
|
||||
if( USE_INLINES )
|
||||
if( m_UseInlineModelsInBrdfile )
|
||||
{
|
||||
write_triangle_bag( *aOutputFile, aModel.GetColor( VRML_COLOR_TIN ),
|
||||
&aModel.m_plated_holes, false, false,
|
||||
aModel.GetLayerZ( F_Cu ) + Millimeter2iu( ART_OFFSET / 2.0 ) * BOARD_SCALE,
|
||||
aModel.GetLayerZ( B_Cu ) - Millimeter2iu( ART_OFFSET / 2.0 ) * BOARD_SCALE );
|
||||
write_triangle_bag( *aOutputFile, GetColor( VRML_COLOR_TIN ),
|
||||
&m_plated_holes, false, false,
|
||||
GetLayerZ( F_Cu ) + Millimeter2iu( ART_OFFSET / 2.0 ) * m_BoardToVrmlScale,
|
||||
GetLayerZ( B_Cu ) - Millimeter2iu( ART_OFFSET / 2.0 ) * m_BoardToVrmlScale );
|
||||
}
|
||||
else
|
||||
{
|
||||
create_vrml_shell( aModel.m_OutputPCB, VRML_COLOR_TIN, &aModel.m_plated_holes,
|
||||
aModel.GetLayerZ( F_Cu ) + Millimeter2iu( ART_OFFSET / 2.0 ) * BOARD_SCALE,
|
||||
aModel.GetLayerZ( B_Cu ) - Millimeter2iu( ART_OFFSET / 2.0 ) * BOARD_SCALE );
|
||||
create_vrml_shell( m_OutputPCB, VRML_COLOR_TIN, &m_plated_holes,
|
||||
GetLayerZ( F_Cu ) + Millimeter2iu( ART_OFFSET / 2.0 ) * m_BoardToVrmlScale,
|
||||
GetLayerZ( B_Cu ) - Millimeter2iu( ART_OFFSET / 2.0 ) * m_BoardToVrmlScale );
|
||||
}
|
||||
|
||||
// VRML_LAYER m_top_silk;
|
||||
aModel.m_top_silk.Tesselate( &aModel.m_holes );
|
||||
m_top_silk.Tesselate( &m_holes );
|
||||
|
||||
if( USE_INLINES )
|
||||
if( m_UseInlineModelsInBrdfile )
|
||||
{
|
||||
write_triangle_bag( *aOutputFile, aModel.GetColor( VRML_COLOR_SILK ), &aModel.m_top_silk,
|
||||
true, true, aModel.GetLayerZ( F_SilkS ), 0 );
|
||||
write_triangle_bag( *aOutputFile, GetColor( VRML_COLOR_SILK ), &m_top_silk,
|
||||
true, true, GetLayerZ( F_SilkS ), 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
create_vrml_plane( aModel.m_OutputPCB, VRML_COLOR_SILK, &aModel.m_top_silk,
|
||||
aModel.GetLayerZ( F_SilkS ), true );
|
||||
create_vrml_plane( m_OutputPCB, VRML_COLOR_SILK, &m_top_silk,
|
||||
GetLayerZ( F_SilkS ), true );
|
||||
}
|
||||
|
||||
// VRML_LAYER m_bot_silk;
|
||||
aModel.m_bot_silk.Tesselate( &aModel.m_holes );
|
||||
m_bot_silk.Tesselate( &m_holes );
|
||||
|
||||
if( USE_INLINES )
|
||||
if( m_UseInlineModelsInBrdfile )
|
||||
{
|
||||
write_triangle_bag( *aOutputFile, aModel.GetColor( VRML_COLOR_SILK ), &aModel.m_bot_silk,
|
||||
true, false, aModel.GetLayerZ( B_SilkS ), 0 );
|
||||
write_triangle_bag( *aOutputFile, GetColor( VRML_COLOR_SILK ), &m_bot_silk,
|
||||
true, false, GetLayerZ( B_SilkS ), 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
create_vrml_plane( aModel.m_OutputPCB, VRML_COLOR_SILK, &aModel.m_bot_silk,
|
||||
aModel.GetLayerZ( B_SilkS ), false );
|
||||
create_vrml_plane( m_OutputPCB, VRML_COLOR_SILK, &m_bot_silk,
|
||||
GetLayerZ( B_SilkS ), false );
|
||||
}
|
||||
|
||||
if( !USE_INLINES )
|
||||
S3D::WriteVRML( aFileName, true, aModel.m_OutputPCB.GetRawPtr(), true, true );
|
||||
if( !m_UseInlineModelsInBrdfile )
|
||||
S3D::WriteVRML( aFileName, true, m_OutputPCB.GetRawPtr(), true, true );
|
||||
}
|
||||
|
||||
|
||||
|
@ -438,7 +427,7 @@ void MODEL_VRML::ComputeLayer3D_Zpos( BOARD* pcb )
|
|||
int copper_layers = pcb->GetCopperLayerCount();
|
||||
|
||||
// We call it 'layer' thickness, but it's the whole board thickness!
|
||||
m_brd_thickness = pcb->GetDesignSettings().GetBoardThickness() * BOARD_SCALE;
|
||||
m_brd_thickness = pcb->GetDesignSettings().GetBoardThickness() * m_BoardToVrmlScale;
|
||||
double half_thickness = m_brd_thickness / 2;
|
||||
|
||||
// Compute each layer's Z value, more or less like the 3d view
|
||||
|
@ -453,7 +442,7 @@ void MODEL_VRML::ComputeLayer3D_Zpos( BOARD* pcb )
|
|||
}
|
||||
|
||||
// To avoid rounding interference, we apply an epsilon to each successive layer
|
||||
double epsilon_z = Millimeter2iu( ART_OFFSET ) * BOARD_SCALE;
|
||||
double epsilon_z = Millimeter2iu( ART_OFFSET ) * m_BoardToVrmlScale;
|
||||
SetLayerZ( B_Paste, -half_thickness - epsilon_z * 4 );
|
||||
SetLayerZ( B_Adhes, -half_thickness - epsilon_z * 3 );
|
||||
SetLayerZ( B_SilkS, -half_thickness - epsilon_z * 2 );
|
||||
|
@ -574,8 +563,8 @@ void MODEL_VRML::ExportVrmlPolygon( LAYER_NUM layer, PCB_SHAPE *aOutline,
|
|||
|
||||
for( int j = 0; j < outline.PointCount(); j++ )
|
||||
{
|
||||
if( !vlayer->AddVertex( seg, outline.CPoint( j ).x * BOARD_SCALE,
|
||||
-outline.CPoint( j ).y * BOARD_SCALE ) )
|
||||
if( !vlayer->AddVertex( seg, outline.CPoint( j ).x * m_BoardToVrmlScale,
|
||||
-outline.CPoint( j ).y * m_BoardToVrmlScale ) )
|
||||
throw( std::runtime_error( vlayer->GetError() ) );
|
||||
}
|
||||
|
||||
|
@ -587,11 +576,11 @@ void MODEL_VRML::ExportVrmlPolygon( LAYER_NUM layer, PCB_SHAPE *aOutline,
|
|||
void MODEL_VRML::ExportVrmlDrawsegment( PCB_SHAPE* drawseg )
|
||||
{
|
||||
LAYER_NUM layer = drawseg->GetLayer();
|
||||
double w = drawseg->GetWidth() * BOARD_SCALE;
|
||||
double x = drawseg->GetStart().x * BOARD_SCALE;
|
||||
double y = drawseg->GetStart().y * BOARD_SCALE;
|
||||
double xf = drawseg->GetEnd().x * BOARD_SCALE;
|
||||
double yf = drawseg->GetEnd().y * BOARD_SCALE;
|
||||
double w = drawseg->GetWidth() * m_BoardToVrmlScale;
|
||||
double x = drawseg->GetStart().x * m_BoardToVrmlScale;
|
||||
double y = drawseg->GetStart().y * m_BoardToVrmlScale;
|
||||
double xf = drawseg->GetEnd().x * m_BoardToVrmlScale;
|
||||
double yf = drawseg->GetEnd().y * m_BoardToVrmlScale;
|
||||
double r = sqrt( pow( x - xf, 2 ) + pow( y - yf, 2 ) );
|
||||
|
||||
// Items on the edge layer are handled elsewhere; just return
|
||||
|
@ -602,10 +591,10 @@ void MODEL_VRML::ExportVrmlDrawsegment( PCB_SHAPE* drawseg )
|
|||
{
|
||||
case S_ARC:
|
||||
ExportVrmlArc( layer,
|
||||
(double) drawseg->GetCenter().x * BOARD_SCALE,
|
||||
(double) drawseg->GetCenter().y * BOARD_SCALE,
|
||||
(double) drawseg->GetArcStart().x * BOARD_SCALE,
|
||||
(double) drawseg->GetArcStart().y * BOARD_SCALE,
|
||||
(double) drawseg->GetCenter().x * m_BoardToVrmlScale,
|
||||
(double) drawseg->GetCenter().y * m_BoardToVrmlScale,
|
||||
(double) drawseg->GetArcStart().x * m_BoardToVrmlScale,
|
||||
(double) drawseg->GetArcStart().y * m_BoardToVrmlScale,
|
||||
w, drawseg->GetAngle() / 10 );
|
||||
break;
|
||||
|
||||
|
@ -630,10 +619,10 @@ void MODEL_VRML::ExportVrmlDrawsegment( PCB_SHAPE* drawseg )
|
|||
std::vector<VECTOR2D> pointCtrl;
|
||||
|
||||
pointCtrl.emplace_back( x, y );
|
||||
pointCtrl.emplace_back( drawseg->GetBezControl1().x * BOARD_SCALE,
|
||||
drawseg->GetBezControl1().y * BOARD_SCALE );
|
||||
pointCtrl.emplace_back( drawseg->GetBezControl2().x * BOARD_SCALE,
|
||||
drawseg->GetBezControl2().y * BOARD_SCALE );
|
||||
pointCtrl.emplace_back( drawseg->GetBezControl1().x * m_BoardToVrmlScale,
|
||||
drawseg->GetBezControl1().y * m_BoardToVrmlScale );
|
||||
pointCtrl.emplace_back( drawseg->GetBezControl2().x * m_BoardToVrmlScale,
|
||||
drawseg->GetBezControl2().y * m_BoardToVrmlScale );
|
||||
pointCtrl.emplace_back( xf, yf );
|
||||
|
||||
BEZIER_POLY converter( pointCtrl );
|
||||
|
@ -661,17 +650,20 @@ void MODEL_VRML::ExportVrmlDrawsegment( PCB_SHAPE* drawseg )
|
|||
}
|
||||
|
||||
|
||||
/* C++ doesn't have closures and neither continuation forms... this is
|
||||
* for coupling the vrml_text_callback with the common parameters */
|
||||
/* GRText needs a callback function to return the shape of the text to plot...
|
||||
* this is for coupling the vrml_text_callback with the vrml exporter parameters
|
||||
*/
|
||||
static void vrml_text_callback( int x0, int y0, int xf, int yf, void* aData )
|
||||
{
|
||||
LAYER_NUM m_text_layer = model_vrml->m_text_layer;
|
||||
int m_text_width = model_vrml->m_text_width;
|
||||
|
||||
model_vrml->ExportVrmlLine( m_text_layer,
|
||||
x0 * BOARD_SCALE, y0 * BOARD_SCALE,
|
||||
xf * BOARD_SCALE, yf * BOARD_SCALE,
|
||||
m_text_width * BOARD_SCALE );
|
||||
x0 * model_vrml->m_BoardToVrmlScale,
|
||||
y0 * model_vrml->m_BoardToVrmlScale,
|
||||
xf * model_vrml->m_BoardToVrmlScale,
|
||||
yf * model_vrml->m_BoardToVrmlScale,
|
||||
m_text_width * model_vrml->m_BoardToVrmlScale );
|
||||
}
|
||||
|
||||
|
||||
|
@ -758,8 +750,8 @@ void MODEL_VRML::ExportVrmlBoard( BOARD* aPcb )
|
|||
|
||||
for( int j = 0; j < outline.PointCount(); j++ )
|
||||
{
|
||||
m_board.AddVertex( seg, (double)outline.CPoint(j).x * BOARD_SCALE,
|
||||
-((double)outline.CPoint(j).y * BOARD_SCALE ) );
|
||||
m_board.AddVertex( seg, (double)outline.CPoint(j).x * m_BoardToVrmlScale,
|
||||
-((double)outline.CPoint(j).y * m_BoardToVrmlScale ) );
|
||||
|
||||
}
|
||||
|
||||
|
@ -780,8 +772,8 @@ void MODEL_VRML::ExportVrmlBoard( BOARD* aPcb )
|
|||
|
||||
for( int j = 0; j < hole.PointCount(); j++ )
|
||||
{
|
||||
m_holes.AddVertex( seg, (double) hole.CPoint(j).x * BOARD_SCALE,
|
||||
-( (double) hole.CPoint(j).y * BOARD_SCALE ) );
|
||||
m_holes.AddVertex( seg, (double) hole.CPoint(j).x * m_BoardToVrmlScale,
|
||||
-( (double) hole.CPoint(j).y * m_BoardToVrmlScale ) );
|
||||
}
|
||||
|
||||
m_holes.EnsureWinding( seg, true );
|
||||
|
@ -840,10 +832,10 @@ void MODEL_VRML::ExportVrmlVia( BOARD* aPcb, const VIA* aVia )
|
|||
double x, y, r, hole;
|
||||
PCB_LAYER_ID top_layer, bottom_layer;
|
||||
|
||||
hole = aVia->GetDrillValue() * BOARD_SCALE / 2.0;
|
||||
r = aVia->GetWidth() * BOARD_SCALE / 2.0;
|
||||
x = aVia->GetStart().x * BOARD_SCALE;
|
||||
y = aVia->GetStart().y * BOARD_SCALE;
|
||||
hole = aVia->GetDrillValue() * m_BoardToVrmlScale / 2.0;
|
||||
r = aVia->GetWidth() * m_BoardToVrmlScale / 2.0;
|
||||
x = aVia->GetStart().x * m_BoardToVrmlScale;
|
||||
y = aVia->GetStart().y * m_BoardToVrmlScale;
|
||||
aVia->LayerPair( &top_layer, &bottom_layer );
|
||||
|
||||
// do not render a buried via
|
||||
|
@ -877,36 +869,36 @@ void MODEL_VRML::ExportVrmlTracks( BOARD* pcb )
|
|||
if( arc_angle_degree < -1.0 || arc_angle_degree > 1.0 )
|
||||
{
|
||||
ExportVrmlArc( track->GetLayer(),
|
||||
center.x * BOARD_SCALE, center.y * BOARD_SCALE,
|
||||
arc->GetStart().x * BOARD_SCALE,
|
||||
arc->GetStart().y * BOARD_SCALE,
|
||||
arc->GetWidth() * BOARD_SCALE, arc_angle_degree );
|
||||
center.x * m_BoardToVrmlScale, center.y * m_BoardToVrmlScale,
|
||||
arc->GetStart().x * m_BoardToVrmlScale,
|
||||
arc->GetStart().y * m_BoardToVrmlScale,
|
||||
arc->GetWidth() * m_BoardToVrmlScale, arc_angle_degree );
|
||||
}
|
||||
else
|
||||
{
|
||||
ExportVrmlLine( arc->GetLayer(),
|
||||
arc->GetStart().x * BOARD_SCALE,
|
||||
arc->GetStart().y * BOARD_SCALE,
|
||||
arc->GetEnd().x * BOARD_SCALE,
|
||||
arc->GetEnd().y * BOARD_SCALE,
|
||||
arc->GetWidth() * BOARD_SCALE );
|
||||
arc->GetStart().x * m_BoardToVrmlScale,
|
||||
arc->GetStart().y * m_BoardToVrmlScale,
|
||||
arc->GetEnd().x * m_BoardToVrmlScale,
|
||||
arc->GetEnd().y * m_BoardToVrmlScale,
|
||||
arc->GetWidth() * m_BoardToVrmlScale );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ExportVrmlLine( track->GetLayer(),
|
||||
track->GetStart().x * BOARD_SCALE,
|
||||
track->GetStart().y * BOARD_SCALE,
|
||||
track->GetEnd().x * BOARD_SCALE,
|
||||
track->GetEnd().y * BOARD_SCALE,
|
||||
track->GetWidth() * BOARD_SCALE );
|
||||
track->GetStart().x * m_BoardToVrmlScale,
|
||||
track->GetStart().y * m_BoardToVrmlScale,
|
||||
track->GetEnd().x * m_BoardToVrmlScale,
|
||||
track->GetEnd().y * m_BoardToVrmlScale,
|
||||
track->GetWidth() * m_BoardToVrmlScale );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MODEL_VRML::ExportVrmlZones( BOARD* aPcb, COMMIT* aCommit )
|
||||
void MODEL_VRML::ExportVrmlZones( BOARD* aPcb )
|
||||
{
|
||||
for( ZONE* zone : aPcb->Zones() )
|
||||
{
|
||||
|
@ -918,16 +910,7 @@ void MODEL_VRML::ExportVrmlZones( BOARD* aPcb, COMMIT* aCommit )
|
|||
continue;
|
||||
|
||||
if( !zone->IsFilled() )
|
||||
{
|
||||
ZONE_FILLER filler( aPcb, aCommit );
|
||||
zone->SetFillMode( ZONE_FILL_MODE::POLYGONS ); // use filled polygons
|
||||
|
||||
// If the zone fill failed, don't try adding it to the export
|
||||
std::vector<ZONE*> toFill = { zone };
|
||||
|
||||
if( !filler.Fill( toFill ) )
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
|
||||
const SHAPE_POLY_SET& poly = zone->GetFilledPolysList( layer );
|
||||
|
||||
|
@ -939,8 +922,8 @@ void MODEL_VRML::ExportVrmlZones( BOARD* aPcb, COMMIT* aCommit )
|
|||
|
||||
for( int j = 0; j < outline.PointCount(); j++ )
|
||||
{
|
||||
if( !vl->AddVertex( seg, (double) outline.CPoint( j ).x * BOARD_SCALE,
|
||||
-( (double) outline.CPoint( j ).y * BOARD_SCALE ) ) )
|
||||
if( !vl->AddVertex( seg, (double) outline.CPoint( j ).x * m_BoardToVrmlScale,
|
||||
-( (double) outline.CPoint( j ).y * m_BoardToVrmlScale ) ) )
|
||||
{
|
||||
throw( std::runtime_error( vl->GetError() ) );
|
||||
}
|
||||
|
@ -953,7 +936,7 @@ void MODEL_VRML::ExportVrmlZones( BOARD* aPcb, COMMIT* aCommit )
|
|||
}
|
||||
|
||||
|
||||
static void export_vrml_fp_text( FP_TEXT* item )
|
||||
void MODEL_VRML::ExportVrmlFpText( FP_TEXT* item )
|
||||
{
|
||||
if( item->IsVisible() )
|
||||
{
|
||||
|
@ -978,11 +961,11 @@ static void export_vrml_fp_text( FP_TEXT* item )
|
|||
void MODEL_VRML::ExportVrmlFpShape( FP_SHAPE* aOutline, FOOTPRINT* aFootprint )
|
||||
{
|
||||
LAYER_NUM layer = aOutline->GetLayer();
|
||||
double x = aOutline->GetStart().x * BOARD_SCALE;
|
||||
double y = aOutline->GetStart().y * BOARD_SCALE;
|
||||
double xf = aOutline->GetEnd().x * BOARD_SCALE;
|
||||
double yf = aOutline->GetEnd().y * BOARD_SCALE;
|
||||
double w = aOutline->GetWidth() * BOARD_SCALE;
|
||||
double x = aOutline->GetStart().x * m_BoardToVrmlScale;
|
||||
double y = aOutline->GetStart().y * m_BoardToVrmlScale;
|
||||
double xf = aOutline->GetEnd().x * m_BoardToVrmlScale;
|
||||
double yf = aOutline->GetEnd().y * m_BoardToVrmlScale;
|
||||
double w = aOutline->GetWidth() * m_BoardToVrmlScale;
|
||||
|
||||
switch( aOutline->GetShape() )
|
||||
{
|
||||
|
@ -1009,10 +992,10 @@ void MODEL_VRML::ExportVrmlFpShape( FP_SHAPE* aOutline, FOOTPRINT* aFootprint )
|
|||
std::vector<VECTOR2D> pointCtrl;
|
||||
|
||||
pointCtrl.emplace_back( x, y );
|
||||
pointCtrl.emplace_back( aOutline->GetBezControl1().x * BOARD_SCALE,
|
||||
aOutline->GetBezControl1().y * BOARD_SCALE );
|
||||
pointCtrl.emplace_back( aOutline->GetBezControl2().x * BOARD_SCALE,
|
||||
aOutline->GetBezControl2().y * BOARD_SCALE );
|
||||
pointCtrl.emplace_back( aOutline->GetBezControl1().x * m_BoardToVrmlScale,
|
||||
aOutline->GetBezControl1().y * m_BoardToVrmlScale );
|
||||
pointCtrl.emplace_back( aOutline->GetBezControl2().x * m_BoardToVrmlScale,
|
||||
aOutline->GetBezControl2().y * m_BoardToVrmlScale );
|
||||
pointCtrl.emplace_back( xf, yf );
|
||||
|
||||
BEZIER_POLY converter( pointCtrl );
|
||||
|
@ -1044,15 +1027,15 @@ void MODEL_VRML::ExportVrmlPadshape( VRML_LAYER* aTinLayer, PAD* aPad )
|
|||
{
|
||||
// The (maybe offset) pad position
|
||||
wxPoint pad_pos = aPad->ShapePos();
|
||||
double pad_x = pad_pos.x * BOARD_SCALE;
|
||||
double pad_y = pad_pos.y * BOARD_SCALE;
|
||||
double pad_x = pad_pos.x * m_BoardToVrmlScale;
|
||||
double pad_y = pad_pos.y * m_BoardToVrmlScale;
|
||||
wxSize pad_delta = aPad->GetDelta();
|
||||
|
||||
double pad_dx = pad_delta.x * BOARD_SCALE / 2.0;
|
||||
double pad_dy = pad_delta.y * BOARD_SCALE / 2.0;
|
||||
double pad_dx = pad_delta.x * m_BoardToVrmlScale / 2.0;
|
||||
double pad_dy = pad_delta.y * m_BoardToVrmlScale / 2.0;
|
||||
|
||||
double pad_w = aPad->GetSize().x * BOARD_SCALE / 2.0;
|
||||
double pad_h = aPad->GetSize().y * BOARD_SCALE / 2.0;
|
||||
double pad_w = aPad->GetSize().x * m_BoardToVrmlScale / 2.0;
|
||||
double pad_h = aPad->GetSize().y * m_BoardToVrmlScale / 2.0;
|
||||
|
||||
switch( aPad->GetShape() )
|
||||
{
|
||||
|
@ -1085,7 +1068,7 @@ void MODEL_VRML::ExportVrmlPadshape( VRML_LAYER* aTinLayer, PAD* aPad )
|
|||
cornerList.reserve( poly.PointCount() );
|
||||
for( int ii = 0; ii < poly.PointCount(); ++ii )
|
||||
cornerList.emplace_back(
|
||||
poly.CPoint( ii ).x * BOARD_SCALE, -poly.CPoint( ii ).y * BOARD_SCALE );
|
||||
poly.CPoint( ii ).x * m_BoardToVrmlScale, -poly.CPoint( ii ).y * m_BoardToVrmlScale );
|
||||
|
||||
// Close polygon
|
||||
cornerList.push_back( cornerList[0] );
|
||||
|
@ -1108,7 +1091,7 @@ void MODEL_VRML::ExportVrmlPadshape( VRML_LAYER* aTinLayer, PAD* aPad )
|
|||
|
||||
for( int ii = 0; ii < poly.PointCount(); ++ii )
|
||||
cornerList.emplace_back(
|
||||
poly.CPoint( ii ).x * BOARD_SCALE, -poly.CPoint( ii ).y * BOARD_SCALE );
|
||||
poly.CPoint( ii ).x * m_BoardToVrmlScale, -poly.CPoint( ii ).y * m_BoardToVrmlScale );
|
||||
|
||||
// Close polygon
|
||||
cornerList.push_back( cornerList[0] );
|
||||
|
@ -1175,11 +1158,11 @@ void MODEL_VRML::ExportVrmlPadshape( VRML_LAYER* aTinLayer, PAD* aPad )
|
|||
|
||||
void MODEL_VRML::ExportVrmlPad( BOARD* aPcb, PAD* aPad )
|
||||
{
|
||||
double hole_drill_w = (double) aPad->GetDrillSize().x * BOARD_SCALE / 2.0;
|
||||
double hole_drill_h = (double) aPad->GetDrillSize().y * BOARD_SCALE / 2.0;
|
||||
double hole_drill_w = (double) aPad->GetDrillSize().x * m_BoardToVrmlScale / 2.0;
|
||||
double hole_drill_h = (double) aPad->GetDrillSize().y * m_BoardToVrmlScale / 2.0;
|
||||
double hole_drill = std::min( hole_drill_w, hole_drill_h );
|
||||
double hole_x = aPad->GetPosition().x * BOARD_SCALE;
|
||||
double hole_y = aPad->GetPosition().y * BOARD_SCALE;
|
||||
double hole_x = aPad->GetPosition().x * m_BoardToVrmlScale;
|
||||
double hole_y = aPad->GetPosition().y * m_BoardToVrmlScale;
|
||||
|
||||
// Export the hole on the edge layer
|
||||
if( hole_drill > 0 )
|
||||
|
@ -1297,10 +1280,10 @@ void MODEL_VRML::ExportVrmlFootprint( BOARD* aPcb, FOOTPRINT* aFootprint,
|
|||
{
|
||||
// Reference and value
|
||||
if( aFootprint->Reference().IsVisible() )
|
||||
export_vrml_fp_text( &aFootprint->Reference() );
|
||||
ExportVrmlFpText( &aFootprint->Reference() );
|
||||
|
||||
if( aFootprint->Value().IsVisible() )
|
||||
export_vrml_fp_text( &aFootprint->Value() );
|
||||
ExportVrmlFpText( &aFootprint->Value() );
|
||||
|
||||
// Export footprint graphics
|
||||
|
||||
|
@ -1309,7 +1292,7 @@ void MODEL_VRML::ExportVrmlFootprint( BOARD* aPcb, FOOTPRINT* aFootprint,
|
|||
switch( item->Type() )
|
||||
{
|
||||
case PCB_FP_TEXT_T:
|
||||
export_vrml_fp_text( static_cast<FP_TEXT*>( item ) );
|
||||
ExportVrmlFpText( static_cast<FP_TEXT*>( item ) );
|
||||
break;
|
||||
|
||||
case PCB_FP_SHAPE_T:
|
||||
|
@ -1332,7 +1315,7 @@ void MODEL_VRML::ExportVrmlFootprint( BOARD* aPcb, FOOTPRINT* aFootprint,
|
|||
auto sM = aFootprint->Models().begin();
|
||||
auto eM = aFootprint->Models().end();
|
||||
|
||||
wxFileName subdir( SUBDIR_3D, "" );
|
||||
wxFileName subdir( m_Subdir3DFpModels, "" );
|
||||
|
||||
while( sM != eM )
|
||||
{
|
||||
|
@ -1390,15 +1373,15 @@ void MODEL_VRML::ExportVrmlFootprint( BOARD* aPcb, FOOTPRINT* aFootprint,
|
|||
RotatePoint( &offsetx, &offsety, aFootprint->GetOrientation() );
|
||||
|
||||
SGPOINT trans;
|
||||
trans.x = ( offsetx + aFootprint->GetPosition().x ) * BOARD_SCALE + m_tx;
|
||||
trans.y = -( offsety + aFootprint->GetPosition().y) * BOARD_SCALE - m_ty;
|
||||
trans.z = (offsetz * BOARD_SCALE ) + GetLayerZ( aFootprint->GetLayer() );
|
||||
trans.x = ( offsetx + aFootprint->GetPosition().x ) * m_BoardToVrmlScale + m_tx;
|
||||
trans.y = -( offsety + aFootprint->GetPosition().y) * m_BoardToVrmlScale - m_ty;
|
||||
trans.z = (offsetz * m_BoardToVrmlScale ) + GetLayerZ( aFootprint->GetLayer() );
|
||||
|
||||
if( USE_INLINES )
|
||||
if( m_UseInlineModelsInBrdfile )
|
||||
{
|
||||
wxFileName srcFile = cache->GetResolver()->ResolvePath( sM->m_Filename );
|
||||
wxFileName dstFile;
|
||||
dstFile.SetPath( SUBDIR_3D );
|
||||
dstFile.SetPath( m_Subdir3DFpModels );
|
||||
dstFile.SetName( srcFile.GetName() );
|
||||
dstFile.SetExt( "wrl" );
|
||||
|
||||
|
@ -1425,7 +1408,7 @@ void MODEL_VRML::ExportVrmlFootprint( BOARD* aPcb, FOOTPRINT* aFootprint,
|
|||
}
|
||||
else
|
||||
{
|
||||
if( !S3D::WriteVRML( dstFile.GetFullPath().ToUTF8(), true, mod3d, USE_DEFS, true ) )
|
||||
if( !S3D::WriteVRML( dstFile.GetFullPath().ToUTF8(), true, mod3d, m_ReuseDef, true ) )
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -1439,7 +1422,7 @@ void MODEL_VRML::ExportVrmlFootprint( BOARD* aPcb, FOOTPRINT* aFootprint,
|
|||
(*aOutputFile) << rot[0] << " " << rot[1] << " " << rot[2] << " " << rot[3] << "\n";
|
||||
}
|
||||
|
||||
(*aOutputFile) << " translation " << std::setprecision( PRECISION );
|
||||
(*aOutputFile) << " translation " << std::setprecision( m_precision );
|
||||
(*aOutputFile) << trans.x << " ";
|
||||
(*aOutputFile) << trans.y << " ";
|
||||
(*aOutputFile) << trans.z << "\n";
|
||||
|
@ -1451,7 +1434,7 @@ void MODEL_VRML::ExportVrmlFootprint( BOARD* aPcb, FOOTPRINT* aFootprint,
|
|||
|
||||
(*aOutputFile) << " children [\n Inline {\n url \"";
|
||||
|
||||
if( USE_RELPATH )
|
||||
if( m_UseRelPathIn3DModelFilename )
|
||||
{
|
||||
wxFileName tmp = dstFile;
|
||||
tmp.SetExt( "" );
|
||||
|
@ -1500,28 +1483,25 @@ bool PCB_EDIT_FRAME::ExportVRML_File( const wxString& aFullFileName, double aMMt
|
|||
{
|
||||
BOARD* pcb = GetBoard();
|
||||
bool ok = true;
|
||||
BOARD_COMMIT commit( this ); // We may need to modify the board (for instance to
|
||||
// fill zones), so make sure we can revert.
|
||||
|
||||
USE_INLINES = aExport3DFiles;
|
||||
USE_DEFS = true;
|
||||
USE_RELPATH = aUseRelativePaths;
|
||||
|
||||
cache = Prj().Get3DCacheManager();
|
||||
PROJ_DIR = Prj().GetProjectPath();
|
||||
SUBDIR_3D = a3D_Subdir;
|
||||
MODEL_VRML model3d;
|
||||
model_vrml = &model3d;
|
||||
model3d.SetScale( aMMtoWRMLunit );
|
||||
model3d.m_UseInlineModelsInBrdfile = aExport3DFiles;
|
||||
model3d.m_Subdir3DFpModels = a3D_Subdir;
|
||||
model3d.m_UseRelPathIn3DModelFilename = aUseRelativePaths;
|
||||
|
||||
if( USE_INLINES )
|
||||
if( model3d.m_UseInlineModelsInBrdfile )
|
||||
{
|
||||
BOARD_SCALE = MM_PER_IU / 2.54;
|
||||
model3d.m_BoardToVrmlScale = MM_PER_IU / 2.54;
|
||||
model3d.SetOffset( -aXRef / 2.54, aYRef / 2.54 );
|
||||
}
|
||||
else
|
||||
{
|
||||
BOARD_SCALE = MM_PER_IU;
|
||||
model3d.m_BoardToVrmlScale = MM_PER_IU;
|
||||
model3d.SetOffset( -aXRef, aYRef );
|
||||
}
|
||||
|
||||
|
@ -1549,64 +1529,22 @@ bool PCB_EDIT_FRAME::ExportVRML_File( const wxString& aFullFileName, double aMMt
|
|||
|
||||
// Export zone fills
|
||||
if( !aUsePlainPCB )
|
||||
model3d.ExportVrmlZones( pcb, &commit );
|
||||
model3d.ExportVrmlZones( pcb );
|
||||
|
||||
if( USE_INLINES )
|
||||
if( model3d.m_UseInlineModelsInBrdfile )
|
||||
{
|
||||
// check if the 3D Subdir exists - create if not
|
||||
wxFileName subdir( SUBDIR_3D, "" );
|
||||
|
||||
if( ! subdir.DirExists() )
|
||||
{
|
||||
if( !wxDir::Make( subdir.GetFullPath() ) )
|
||||
throw( std::runtime_error( "Could not create 3D model subdirectory" ) );
|
||||
}
|
||||
|
||||
OPEN_OSTREAM( output_file, TO_UTF8( aFullFileName ) );
|
||||
|
||||
if( output_file.fail() )
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
ostr << "Could not open file '" << TO_UTF8( aFullFileName ) << "'";
|
||||
throw( std::runtime_error( ostr.str().c_str() ) );
|
||||
}
|
||||
|
||||
output_file.imbue( std::locale::classic() );
|
||||
|
||||
// Begin with the usual VRML boilerplate
|
||||
wxString fn = aFullFileName;
|
||||
fn.Replace( "\\" , "/" );
|
||||
output_file << "#VRML V2.0 utf8\n";
|
||||
output_file << "WorldInfo {\n";
|
||||
output_file << " title \"" << TO_UTF8( fn ) << " - Generated by Pcbnew\"\n";
|
||||
output_file << "}\n";
|
||||
output_file << "Transform {\n";
|
||||
output_file << " scale " << std::setprecision( PRECISION );
|
||||
output_file << WORLD_SCALE << " ";
|
||||
output_file << WORLD_SCALE << " ";
|
||||
output_file << WORLD_SCALE << "\n";
|
||||
output_file << " children [\n";
|
||||
|
||||
// Export footprints
|
||||
for( FOOTPRINT* footprint : pcb->Footprints() )
|
||||
model3d.ExportVrmlFootprint( pcb, footprint, &output_file );
|
||||
|
||||
// write out the board and all layers
|
||||
write_layers( model3d, pcb, TO_UTF8( aFullFileName ), &output_file );
|
||||
|
||||
// Close the outer 'transform' node
|
||||
output_file << "]\n}\n";
|
||||
|
||||
CLOSE_STREAM( output_file );
|
||||
// Copy fp 3D models in a folder, and link these files in
|
||||
// the board .vrml file
|
||||
model3d.ExportFp3DModelsAsLinkedFile( pcb, aFullFileName );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Export footprints
|
||||
// merge footprints in the .vrml board file
|
||||
for( FOOTPRINT* footprint : pcb->Footprints() )
|
||||
model3d.ExportVrmlFootprint( pcb, footprint, NULL );
|
||||
|
||||
// write out the board and all layers
|
||||
write_layers( model3d, pcb, TO_UTF8( aFullFileName ), NULL );
|
||||
model3d.writeLayers( pcb, TO_UTF8( aFullFileName ), NULL );
|
||||
}
|
||||
}
|
||||
catch( const std::exception& e )
|
||||
|
@ -1618,10 +1556,57 @@ bool PCB_EDIT_FRAME::ExportVRML_File( const wxString& aFullFileName, double aMMt
|
|||
ok = false;
|
||||
}
|
||||
|
||||
commit.Revert();
|
||||
return ok;
|
||||
}
|
||||
|
||||
void MODEL_VRML::ExportFp3DModelsAsLinkedFile( BOARD* aPcb, const wxString& aFullFileName )
|
||||
{
|
||||
// check if the 3D Subdir exists - create if not
|
||||
wxFileName subdir( m_Subdir3DFpModels, "" );
|
||||
|
||||
if( ! subdir.DirExists() )
|
||||
{
|
||||
if( !wxDir::Make( subdir.GetFullPath() ) )
|
||||
throw( std::runtime_error( "Could not create 3D model subdirectory" ) );
|
||||
}
|
||||
|
||||
OPEN_OSTREAM( output_file, TO_UTF8( aFullFileName ) );
|
||||
|
||||
if( output_file.fail() )
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
ostr << "Could not open file '" << TO_UTF8( aFullFileName ) << "'";
|
||||
throw( std::runtime_error( ostr.str().c_str() ) );
|
||||
}
|
||||
|
||||
output_file.imbue( std::locale::classic() );
|
||||
|
||||
// Begin with the usual VRML boilerplate
|
||||
wxString fn = aFullFileName;
|
||||
fn.Replace( "\\" , "/" );
|
||||
output_file << "#VRML V2.0 utf8\n";
|
||||
output_file << "WorldInfo {\n";
|
||||
output_file << " title \"" << TO_UTF8( fn ) << " - Generated by Pcbnew\"\n";
|
||||
output_file << "}\n";
|
||||
output_file << "Transform {\n";
|
||||
output_file << " scale " << std::setprecision( m_precision );
|
||||
output_file << m_WorldScale << " ";
|
||||
output_file << m_WorldScale << " ";
|
||||
output_file << m_WorldScale << "\n";
|
||||
output_file << " children [\n";
|
||||
|
||||
// Export footprints
|
||||
for( FOOTPRINT* footprint : aPcb->Footprints() )
|
||||
ExportVrmlFootprint( aPcb, footprint, &output_file );
|
||||
|
||||
// write out the board and all layers
|
||||
writeLayers( aPcb, TO_UTF8( aFullFileName ), &output_file );
|
||||
|
||||
// Close the outer 'transform' node
|
||||
output_file << "]\n}\n";
|
||||
|
||||
CLOSE_STREAM( output_file );
|
||||
}
|
||||
|
||||
static SGNODE* getSGColor( VRML_COLOR_INDEX colorIdx )
|
||||
{
|
||||
|
@ -1634,7 +1619,7 @@ static SGNODE* getSGColor( VRML_COLOR_INDEX colorIdx )
|
|||
return sgmaterial[colorIdx];
|
||||
|
||||
IFSG_APPEARANCE vcolor( (SGNODE*) NULL );
|
||||
VRML_COLOR* cp = &colors[colorIdx];
|
||||
VRML_COLOR* cp = &vrml_colors_list[colorIdx];
|
||||
|
||||
vcolor.SetSpecular( cp->spec_red, cp->spec_grn, cp->spec_blu );
|
||||
vcolor.SetDiffuse( cp->diffuse_red, cp->diffuse_grn, cp->diffuse_blu );
|
||||
|
@ -1650,8 +1635,8 @@ static SGNODE* getSGColor( VRML_COLOR_INDEX colorIdx )
|
|||
}
|
||||
|
||||
|
||||
static void create_vrml_plane( IFSG_TRANSFORM& PcbOutput, VRML_COLOR_INDEX colorID,
|
||||
VRML_LAYER* layer, double top_z, bool aTopPlane )
|
||||
void MODEL_VRML::create_vrml_plane( IFSG_TRANSFORM& PcbOutput, VRML_COLOR_INDEX colorID,
|
||||
VRML_LAYER* layer, double top_z, bool aTopPlane )
|
||||
{
|
||||
std::vector< double > vertices;
|
||||
std::vector< int > idxPlane;
|
||||
|
@ -1708,8 +1693,8 @@ static void create_vrml_plane( IFSG_TRANSFORM& PcbOutput, VRML_COLOR_INDEX color
|
|||
}
|
||||
|
||||
|
||||
static void create_vrml_shell( IFSG_TRANSFORM& PcbOutput, VRML_COLOR_INDEX colorID,
|
||||
VRML_LAYER* layer, double top_z, double bottom_z )
|
||||
void MODEL_VRML::create_vrml_shell( IFSG_TRANSFORM& PcbOutput, VRML_COLOR_INDEX colorID,
|
||||
VRML_LAYER* layer, double top_z, double bottom_z )
|
||||
{
|
||||
std::vector< double > vertices;
|
||||
std::vector< int > idxPlane;
|
||||
|
|
|
@ -34,13 +34,29 @@ class VRML_WRITER
|
|||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Exports the board and its footprint shapes 3D (vrml files only) as a
|
||||
* vrml file
|
||||
* @param aFullFileName is the full filename of the board vrml file to create
|
||||
* @param aMMtoWRMLunit is the convert factor from mm to the desired vrml file
|
||||
* @param aExport3DFiles = true to copy 3D fp vrml models to a folder,
|
||||
* and use " { inline fp_3d_model_filename }" keyword in vrml board file
|
||||
* false to include them in the vrml board file
|
||||
* @param aUseRelativePaths = true to use fp 3D relative paths,
|
||||
* false to use absolute paths
|
||||
* @param aUsePlainPCB = true to create a body board shape only,
|
||||
* false to create a full board shape with tracks, vias ...
|
||||
* @param a3D_Subdir is the folder to copy 3D fp models
|
||||
* @param aXRef = X position of board (in mm)
|
||||
* @param aYRef = Y position of board (in mm)
|
||||
*/
|
||||
bool ExportVRML_File( const wxString& aFullFileName, double aMMtoWRMLunit,
|
||||
bool aExport3DFiles, bool aUseRelativePaths,
|
||||
bool aUsePlainPCB, const wxString& a3D_Subdir,
|
||||
double aXRef, double aYRef )
|
||||
{
|
||||
return ExportVRML(aFullFileName, aMMtoWRMLunit,
|
||||
aExport3DFiles, aUseRelativePaths,
|
||||
aUsePlainPCB, a3D_Subdir, aXRef, aYRef);
|
||||
return ExportVRML( aFullFileName, aMMtoWRMLunit,
|
||||
aExport3DFiles, aUseRelativePaths,
|
||||
aUsePlainPCB, a3D_Subdir, aXRef, aYRef);
|
||||
}
|
||||
};
|
|
@ -101,7 +101,7 @@ struct VRML_COLOR
|
|||
};
|
||||
|
||||
|
||||
extern VRML_COLOR colors[VRML_COLOR_LAST];
|
||||
extern VRML_COLOR vrml_colors_list[VRML_COLOR_LAST];
|
||||
|
||||
|
||||
// Handle the board ans its board items to convert them to a VRML representation:
|
||||
|
@ -113,6 +113,8 @@ private:
|
|||
|
||||
int m_iMaxSeg; // max. sides to a small circle
|
||||
double m_arcMinLen, m_arcMaxLen; // min and max lengths of an arc chord
|
||||
int m_precision; // precision factor when exportin fp shapes
|
||||
// to separate files
|
||||
|
||||
public:
|
||||
IFSG_TRANSFORM m_OutputPCB;
|
||||
|
@ -130,6 +132,28 @@ public:
|
|||
|
||||
bool m_plainPCB;
|
||||
|
||||
/* true to use VRML inline{} syntax for footprint 3D models, like:
|
||||
* Inline { url "F:/tmp/pic_programmer/shapes3D/DIP-18_W7.62mm_Socket.wrl" }
|
||||
* false to merge VRML 3D modeles in the .wrl board file
|
||||
*/
|
||||
bool m_UseInlineModelsInBrdfile;
|
||||
|
||||
// 3D subdirectory to copy footprint vrml 3D models when not merged in board file
|
||||
wxString m_Subdir3DFpModels;
|
||||
|
||||
// true to use relative paths in VRML inline{} for footprint 3D models
|
||||
// used only if m_UseInlineModelsInBrdfile = true
|
||||
bool m_UseRelPathIn3DModelFilename;
|
||||
|
||||
// true to reuse component definitions
|
||||
bool m_ReuseDef;
|
||||
|
||||
// scaling from 0.1 inch to desired VRML unit
|
||||
double m_WorldScale = 1.0;
|
||||
|
||||
// scaling from mm to desired VRML world scale
|
||||
double m_BoardToVrmlScale;
|
||||
|
||||
double m_minLineWidth; // minimum width of a VRML line segment
|
||||
|
||||
double m_tx; // global translation along X
|
||||
|
@ -145,7 +169,7 @@ public:
|
|||
|
||||
VRML_COLOR& GetColor( VRML_COLOR_INDEX aIndex )
|
||||
{
|
||||
return colors[aIndex];
|
||||
return vrml_colors_list[aIndex];
|
||||
}
|
||||
|
||||
void SetOffset( double aXoff, double aYoff );
|
||||
|
@ -172,7 +196,7 @@ public:
|
|||
// Build and exports the board outlines (board body)
|
||||
void ExportVrmlBoard( BOARD* aPcb );
|
||||
|
||||
void ExportVrmlZones( BOARD* aPcb, COMMIT* aCommit );
|
||||
void ExportVrmlZones( BOARD* aPcb );
|
||||
|
||||
void ExportVrmlTracks( BOARD* pcb );
|
||||
|
||||
|
@ -182,6 +206,10 @@ public:
|
|||
|
||||
void ExportVrmlPcbtext( PCB_TEXT* text );
|
||||
|
||||
void ExportVrmlFpText( FP_TEXT* item );
|
||||
|
||||
void ExportFp3DModelsAsLinkedFile( BOARD* aPcb, const wxString& aFullFileName );
|
||||
|
||||
void ExportRoundPadstack( BOARD* pcb,
|
||||
double x, double y, double r,
|
||||
LAYER_NUM bottom_layer, LAYER_NUM top_layer,
|
||||
|
@ -215,6 +243,8 @@ public:
|
|||
void ExportVrmlPolygon( LAYER_NUM layer, PCB_SHAPE *aOutline,
|
||||
double aOrientation, wxPoint aPos );
|
||||
|
||||
void writeLayers( BOARD* aPcb, const char* aFileName, OSTREAM* aOutputFile );
|
||||
|
||||
// select the VRML layer object to draw on
|
||||
// return true if a layer has been selected.
|
||||
bool GetLayer3D( LAYER_NUM layer, VRML_LAYER** vlayer );
|
||||
|
@ -222,4 +252,15 @@ public:
|
|||
// Build the Z position of 3D layers
|
||||
void ComputeLayer3D_Zpos(BOARD* pcb );
|
||||
|
||||
private:
|
||||
void write_triangle_bag( std::ostream& aOut_file, const VRML_COLOR& aColor,
|
||||
VRML_LAYER* aLayer, bool aPlane, bool aTop,
|
||||
double aTop_z, double aBottom_z );
|
||||
|
||||
void create_vrml_shell( IFSG_TRANSFORM& PcbOutput, VRML_COLOR_INDEX colorID,
|
||||
VRML_LAYER* layer, double top_z, double bottom_z );
|
||||
|
||||
void create_vrml_plane( IFSG_TRANSFORM& PcbOutput, VRML_COLOR_INDEX colorID,
|
||||
VRML_LAYER* layer, double aHeight, bool aTopPlane );
|
||||
|
||||
};
|
||||
|
|
|
@ -312,6 +312,9 @@ PCBNEW_SETTINGS::PCBNEW_SETTINGS()
|
|||
m_params.emplace_back( new PARAM<double>( "export_vrml.ref_y",
|
||||
&m_ExportVrml.ref_y, 0 ) );
|
||||
|
||||
m_params.emplace_back( new PARAM<int>( "export_vrml.origin_mode",
|
||||
&m_ExportVrml.origin_mode, 0 ) );
|
||||
|
||||
m_params.emplace_back( new PARAM<int>( "zones.hatching_style",
|
||||
&m_Zones.hatching_style, 0 ) );
|
||||
|
||||
|
@ -647,6 +650,7 @@ bool PCBNEW_SETTINGS::MigrateFromLegacy( wxConfigBase* aCfg )
|
|||
ret &= fromLegacy<int>( aCfg, "VrmlRefUnits", "export_vrml.ref_units" );
|
||||
ret &= fromLegacy<double>( aCfg, "VrmlRefX", "export_vrml.ref_x" );
|
||||
ret &= fromLegacy<double>( aCfg, "VrmlRefY", "export_vrml.ref_y" );
|
||||
ret &= fromLegacy<int> ( aCfg, "VrmlOriginMode", "export_vrml.origin_mode" );
|
||||
|
||||
ret &= fromLegacy<int>( aCfg, "Zone_Ouline_Hatch_Opt", "zones.hatching_style" );
|
||||
ret &= fromLegacyString( aCfg, "Zone_Filter_Opt", "zones.net_filter" );
|
||||
|
|
|
@ -128,6 +128,7 @@ public:
|
|||
int ref_units;
|
||||
double ref_x;
|
||||
double ref_y;
|
||||
int origin_mode;
|
||||
};
|
||||
|
||||
struct DIALOG_FOOTPRINT_WIZARD_LIST
|
||||
|
|
Loading…
Reference in New Issue