diff --git a/pcbnew/dialogs/dialog_export_vrml.cpp b/pcbnew/dialogs/dialog_export_vrml.cpp index 72acc378bf..ee2bf2c0e6 100644 --- a/pcbnew/dialogs/dialog_export_vrml.cpp +++ b/pcbnew/dialogs/dialog_export_vrml.cpp @@ -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 #include @@ -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(); diff --git a/pcbnew/dialogs/dialog_export_vrml_base.cpp b/pcbnew/dialogs/dialog_export_vrml_base.cpp index 71078e17f3..b42bca3b77 100644 --- a/pcbnew/dialogs/dialog_export_vrml_base.cpp +++ b/pcbnew/dialogs/dialog_export_vrml_base.cpp @@ -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 ); + } diff --git a/pcbnew/dialogs/dialog_export_vrml_base.fbp b/pcbnew/dialogs/dialog_export_vrml_base.fbp index ff798e3402..e721791cc1 100644 --- a/pcbnew/dialogs/dialog_export_vrml_base.fbp +++ b/pcbnew/dialogs/dialog_export_vrml_base.fbp @@ -14,10 +14,9 @@ dialog_export_vrml_base 1000 none - 1 - dialog_export_vrml + dialog_export_vrml_base . @@ -26,8 +25,7 @@ 1 1 UI - 0 - 1 + 0 0 0 @@ -328,23 +326,89 @@ 0 - bSizer12 + bSizerOptions wxHORIZONTAL none 5 - wxEXPAND + wxALL|wxEXPAND + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + "User defined origin" "Board center origin" + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Coordinate origin options: + 1 + + 0 + + + 0 + + 1 + m_rbCoordOrigin + 1 + + + protected + 1 + + Resizable + 0 + 1 + + wxRA_SPECIFY_COLS + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + 5 + wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT 1 - bSizer5 + bSizerVrmlUnits wxVERTICAL none - + 5 - wxEXPAND | wxALL - 1 - + wxALL + 0 + 1 1 1 @@ -372,6 +436,8 @@ 0 0 wxID_ANY + User defined origin: + 0 0 @@ -379,7 +445,7 @@ 0 1 - m_panel1 + m_staticText6 1 @@ -389,470 +455,405 @@ Resizable 1 + 0 - wxTAB_TRAVERSAL - - - bSizer9 - wxVERTICAL - none - - 5 - wxALL - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Grid reference point: - 0 - - 0 - - - 0 - - 1 - m_staticText6 - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - - - -1 - + + -1 + + + + 5 + wxEXPAND + 1 + + 2 + wxBOTH + 1 + + 0 + + fgSizerOptions + wxFLEX_GROWMODE_SPECIFIED + none + 0 + 0 + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Units: + 0 + + 0 + + + 0 + + 1 + m_staticText61 + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 - - 5 - wxEXPAND - 1 - - 2 - wxBOTH - 1 - - 0 - - fgSizerOptions - wxFLEX_GROWMODE_SPECIFIED - none - 0 - 0 - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Units: - 0 - - 0 - - - 0 - - 1 - m_staticText61 - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - - - -1 - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - "mm" "inch" - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - - 0 - - - 0 - - 1 - m_VRML_RefUnitChoice - 1 - - - protected - 1 - - Resizable - 0 - 1 - - - - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - X: - 0 - - 0 - - - 0 - - 1 - m_staticText4 - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - - - -1 - - - - 5 - wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - - 0 - - 8 - - 0 - - 1 - m_VRML_Xref - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - wxFILTER_NUMERIC - wxDefaultValidator - - 0 - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Y: - 0 - - 0 - - - 0 - - 1 - m_staticText5 - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - - - -1 - - - - 5 - wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - - 0 - - 8 - - 0 - - 1 - m_VRML_Yref - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - wxFILTER_NUMERIC - wxDefaultValidator - - 0 - - - - - - + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + "mm" "inch" + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_VRML_RefUnitChoice + 1 + + + protected + 1 + + Resizable + 0 + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + X: + 0 + + 0 + + + 0 + + 1 + m_staticText4 + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + 8 + + 0 + + 1 + m_VRML_Xref + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NUMERIC + wxDefaultValidator + + 0 + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Y: + 0 + + 0 + + + 0 + + 1 + m_staticText5 + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + 8 + + 0 + + 1 + m_VRML_Yref + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NUMERIC + wxDefaultValidator + + 0 + + + @@ -892,7 +893,7 @@ 0 0 wxID_ANY - Output Units + Vrml Units for Output Files 1 0 @@ -963,7 +964,7 @@ 1 0 - 1 + 0 1 1 @@ -999,7 +1000,7 @@ 0 - + If checked: copy footprints 3D models in a folder If not checked: merge footprints 3D models in the vrml board file wxFILTER_NONE wxDefaultValidator @@ -1041,7 +1042,7 @@ 0 0 - ID_USE_ABS_PATH + wxID_ANY Use relative paths to model files in board VRML file 0 @@ -1071,6 +1072,7 @@ + OnUpdateUseRelativePath @@ -1223,7 +1225,7 @@ 0 0 - m_sdbSizer1 + m_sdbSizer protected diff --git a/pcbnew/dialogs/dialog_export_vrml_base.h b/pcbnew/dialogs/dialog_export_vrml_base.h index 0c5ecf0cda..5c3d4d1f04 100644 --- a/pcbnew/dialogs/dialog_export_vrml_base.h +++ b/pcbnew/dialogs/dialog_export_vrml_base.h @@ -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 #include #include -#include -#include #include +#include #include #include #include @@ -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: diff --git a/pcbnew/exporters/export_vrml.cpp b/pcbnew/exporters/export_vrml.cpp index ef2b647086..00b57bbfef 100644 --- a/pcbnew/exporters/export_vrml.cpp +++ b/pcbnew/exporters/export_vrml.cpp @@ -54,25 +54,21 @@ #include -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 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 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 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( item ) ); + ExportVrmlFpText( static_cast( 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; diff --git a/pcbnew/exporters/export_vrml.h b/pcbnew/exporters/export_vrml.h index d2b3dc19b0..926b8dbe1f 100644 --- a/pcbnew/exporters/export_vrml.h +++ b/pcbnew/exporters/export_vrml.h @@ -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); } }; \ No newline at end of file diff --git a/pcbnew/exporters/exporter_vrml.h b/pcbnew/exporters/exporter_vrml.h index da8b502bbd..94abb5ab28 100644 --- a/pcbnew/exporters/exporter_vrml.h +++ b/pcbnew/exporters/exporter_vrml.h @@ -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 ); + }; diff --git a/pcbnew/pcbnew_settings.cpp b/pcbnew/pcbnew_settings.cpp index 0cf601250c..f829aff013 100644 --- a/pcbnew/pcbnew_settings.cpp +++ b/pcbnew/pcbnew_settings.cpp @@ -312,6 +312,9 @@ PCBNEW_SETTINGS::PCBNEW_SETTINGS() m_params.emplace_back( new PARAM( "export_vrml.ref_y", &m_ExportVrml.ref_y, 0 ) ); + m_params.emplace_back( new PARAM( "export_vrml.origin_mode", + &m_ExportVrml.origin_mode, 0 ) ); + m_params.emplace_back( new PARAM( "zones.hatching_style", &m_Zones.hatching_style, 0 ) ); @@ -647,6 +650,7 @@ bool PCBNEW_SETTINGS::MigrateFromLegacy( wxConfigBase* aCfg ) ret &= fromLegacy( aCfg, "VrmlRefUnits", "export_vrml.ref_units" ); ret &= fromLegacy( aCfg, "VrmlRefX", "export_vrml.ref_x" ); ret &= fromLegacy( aCfg, "VrmlRefY", "export_vrml.ref_y" ); + ret &= fromLegacy ( aCfg, "VrmlOriginMode", "export_vrml.origin_mode" ); ret &= fromLegacy( aCfg, "Zone_Ouline_Hatch_Opt", "zones.hatching_style" ); ret &= fromLegacyString( aCfg, "Zone_Filter_Opt", "zones.net_filter" ); diff --git a/pcbnew/pcbnew_settings.h b/pcbnew/pcbnew_settings.h index 81600b53f6..ad0e8f2436 100644 --- a/pcbnew/pcbnew_settings.h +++ b/pcbnew/pcbnew_settings.h @@ -128,6 +128,7 @@ public: int ref_units; double ref_x; double ref_y; + int origin_mode; }; struct DIALOG_FOOTPRINT_WIZARD_LIST