From 05073c15edd92611d672bf286cdfc8dc956e1326 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 20 Dec 2014 17:13:51 +0100 Subject: [PATCH] Add option to VRML Export for Plain PCB (patch from Cirilo Bernardo) --- include/wxPcbStruct.h | 7 +- pcbnew/dialogs/dialog_export_vrml.cpp | 25 ++++-- pcbnew/dialogs/dialog_export_vrml_base.cpp | 5 +- pcbnew/dialogs/dialog_export_vrml_base.fbp | 90 +++++++++++++++++++++- pcbnew/dialogs/dialog_export_vrml_base.h | 3 +- pcbnew/exporters/export_vrml.cpp | 67 ++++++++++------ 6 files changed, 161 insertions(+), 36 deletions(-) diff --git a/include/wxPcbStruct.h b/include/wxPcbStruct.h index d44bfd89e5..74d03e692c 100644 --- a/include/wxPcbStruct.h +++ b/include/wxPcbStruct.h @@ -938,7 +938,7 @@ public: * @todo Use mm inside the file. A general scale transform is applied to the whole * file (1.0 to have the actual WRML unit im mm, 0.001 to have the actual WRML * unit in meters. - * @note For 3D models built by a 3D modeler, the unit is 0,1 inches. A specfic scale + * @note For 3D models built by a 3D modeler, the unit is 0,1 inches. A specific scale * is applied to 3D models to convert them to internal units. * * @param aFullFileName = the full filename of the file to create @@ -947,13 +947,16 @@ public: * @param aExport3DFiles = true to copy 3D shapes in the subir a3D_Subdir * @param aUseRelativePaths set to true to use relative paths instead of absolute paths * in the board VRML file URLs. + * @param aUsePlainPCB set to true to export a board with no copper or silkskreen; + * this is useful for generating a VRML file which can be + * converted to a STEP model. * @param a3D_Subdir = sub directory where 3D shapes files are copied. This is only used * when aExport3DFiles == true * @return true if Ok. */ bool ExportVRML_File( const wxString & aFullFileName, double aMMtoWRMLunit, bool aExport3DFiles, bool aUseRelativePaths, - const wxString & a3D_Subdir ); + bool aUsePlainPCB, const wxString & a3D_Subdir ); /** * Function ExportToIDF3 diff --git a/pcbnew/dialogs/dialog_export_vrml.cpp b/pcbnew/dialogs/dialog_export_vrml.cpp index 47b4cb1d34..61cd2a0d8c 100644 --- a/pcbnew/dialogs/dialog_export_vrml.cpp +++ b/pcbnew/dialogs/dialog_export_vrml.cpp @@ -41,6 +41,7 @@ #define OPTKEY_OUTPUT_UNIT wxT( "VrmlExportUnit" ) #define OPTKEY_3DFILES_OPT wxT( "VrmlExportCopyFiles" ) #define OPTKEY_USE_RELATIVE_PATHS wxT( "VrmlUseRelativePaths" ) +#define OPTKEY_USE_PLAIN_PCB wxT( "VrmlUsePlainPCB" ) class DIALOG_EXPORT_3DFILE : public DIALOG_EXPORT_3DFILE_BASE @@ -48,9 +49,10 @@ class DIALOG_EXPORT_3DFILE : public DIALOG_EXPORT_3DFILE_BASE private: PCB_EDIT_FRAME* m_parent; wxConfigBase* m_config; - int m_unitsOpt; // Remember last units option - bool m_copy3DFilesOpt; // Remember last copy model files option - bool m_useRelativePathsOpt; // Remember last use absolut paths option + int m_unitsOpt; // Remember last units option + bool m_copy3DFilesOpt; // Remember last copy model files option + bool m_useRelativePathsOpt; // Remember last use absolut paths option + bool m_usePlainPCBOpt; // Remember last Plain Board option public: DIALOG_EXPORT_3DFILE( PCB_EDIT_FRAME* parent ) : @@ -59,12 +61,14 @@ public: m_parent = parent; m_config = Kiface().KifaceSettings(); m_filePicker->SetFocus(); - m_config->Read( OPTKEY_OUTPUT_UNIT, &m_unitsOpt ); - m_config->Read( OPTKEY_3DFILES_OPT, &m_copy3DFilesOpt ); - m_config->Read( OPTKEY_USE_RELATIVE_PATHS, &m_useRelativePathsOpt ); + m_config->Read( OPTKEY_OUTPUT_UNIT, &m_unitsOpt, 1 ); + m_config->Read( OPTKEY_3DFILES_OPT, &m_copy3DFilesOpt, false ); + m_config->Read( OPTKEY_USE_RELATIVE_PATHS, &m_useRelativePathsOpt, false ); + m_config->Read( OPTKEY_USE_PLAIN_PCB, &m_usePlainPCBOpt, false ); m_rbSelectUnits->SetSelection( m_unitsOpt ); m_cbCopyFiles->SetValue( m_copy3DFilesOpt ); m_cbUseRelativePaths->SetValue( m_useRelativePathsOpt ); + m_cbPlainPCB->SetValue( m_usePlainPCBOpt ); wxButton* okButton = (wxButton*) FindWindowByLabel( wxT( "OK" ) ); if( okButton ) @@ -84,6 +88,7 @@ public: m_config->Write( OPTKEY_OUTPUT_UNIT, m_unitsOpt ); m_config->Write( OPTKEY_3DFILES_OPT, m_copy3DFilesOpt ); m_config->Write( OPTKEY_USE_RELATIVE_PATHS, m_useRelativePathsOpt ); + m_config->Write( OPTKEY_USE_PLAIN_PCB, m_usePlainPCBOpt ); }; void SetSubdir( const wxString & aDir ) @@ -116,6 +121,11 @@ public: return m_useRelativePathsOpt = m_cbUseRelativePaths->GetValue(); } + bool GetUsePlainPCBOption() + { + return m_usePlainPCBOpt = m_cbPlainPCB->GetValue(); + } + void OnUpdateUseRelativePath( wxUpdateUIEvent& event ) { // Making path relative or absolute has no meaning when VRML files are not copied. @@ -158,6 +168,7 @@ void PCB_EDIT_FRAME::OnExportVRML( wxCommandEvent& event ) double scale = scaleList[dlg.GetUnits()]; // final scale export bool export3DFiles = dlg.GetCopyFilesOption(); bool useRelativePaths = dlg.GetUseRelativePathsOption(); + bool usePlainPCB = dlg.GetUsePlainPCBOption(); wxString fullFilename = dlg.FilePicker()->GetPath(); wxFileName modelPath = fullFilename; wxBusyCursor dummy; @@ -174,7 +185,7 @@ void PCB_EDIT_FRAME::OnExportVRML( wxCommandEvent& event ) } if( !ExportVRML_File( fullFilename, scale, export3DFiles, useRelativePaths, - modelPath.GetPath() ) ) + usePlainPCB, modelPath.GetPath() ) ) { wxString msg = _( "Unable to create " ) + fullFilename; wxMessageBox( msg ); diff --git a/pcbnew/dialogs/dialog_export_vrml_base.cpp b/pcbnew/dialogs/dialog_export_vrml_base.cpp index ba37d8fdcf..e24c10ce85 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 Nov 6 2013) +// C++ code generated with wxFormBuilder (version Aug 17 2014) // http://www.wxformbuilder.org/ // // PLEASE DO "NOT" EDIT THIS FILE! @@ -52,6 +52,9 @@ DIALOG_EXPORT_3DFILE_BASE::DIALOG_EXPORT_3DFILE_BASE( wxWindow* parent, wxWindow bSizer4->Add( m_cbUseRelativePaths, 0, wxALL, 5 ); + m_cbPlainPCB = new wxCheckBox( this, wxID_ANY, _("Plain PCB (no copper or silk)"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer4->Add( m_cbPlainPCB, 0, wxALL, 5 ); + bLowerSizer->Add( bSizer4, 3, wxEXPAND, 5 ); diff --git a/pcbnew/dialogs/dialog_export_vrml_base.fbp b/pcbnew/dialogs/dialog_export_vrml_base.fbp index 8e056bc0a8..a0dd3d75dd 100644 --- a/pcbnew/dialogs/dialog_export_vrml_base.fbp +++ b/pcbnew/dialogs/dialog_export_vrml_base.fbp @@ -1,6 +1,6 @@ - + C++ @@ -644,6 +644,94 @@ + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Plain PCB (no copper or silk) + + 0 + + + 0 + + 1 + m_cbPlainPCB + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pcbnew/dialogs/dialog_export_vrml_base.h b/pcbnew/dialogs/dialog_export_vrml_base.h index 2116ff82cb..1c1b3fe924 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 Nov 6 2013) +// C++ code generated with wxFormBuilder (version Aug 17 2014) // http://www.wxformbuilder.org/ // // PLEASE DO "NOT" EDIT THIS FILE! @@ -50,6 +50,7 @@ class DIALOG_EXPORT_3DFILE_BASE : public DIALOG_SHIM wxTextCtrl* m_SubdirNameCtrl; wxCheckBox* m_cbCopyFiles; wxCheckBox* m_cbUseRelativePaths; + wxCheckBox* m_cbPlainPCB; wxRadioBox* m_rbSelectUnits; wxStaticLine* m_staticline1; wxStdDialogButtonSizer* m_sdbSizer1; diff --git a/pcbnew/exporters/export_vrml.cpp b/pcbnew/exporters/export_vrml.cpp index 705962e6ca..d3186cbab1 100644 --- a/pcbnew/exporters/export_vrml.cpp +++ b/pcbnew/exporters/export_vrml.cpp @@ -148,6 +148,8 @@ public: VRML_LAYER bot_tin; VRML_LAYER plated_holes; + bool plainPCB; + double scale; // board internal units to output scaling double minLineWidth; // minimum width of a VRML line segment int precision; // precision of output units @@ -403,6 +405,9 @@ static void write_layers( MODEL_VRML& aModel, std::ofstream& output_file, BOARD* write_triangle_bag( output_file, aModel.GetColor( VRML_COLOR_PCB ), &aModel.board, false, false, brdz, -brdz, aModel.precision ); + if( aModel.plainPCB ) + return; + // VRML_LAYER top_copper; aModel.top_copper.Tesselate( &aModel.holes ); write_triangle_bag( output_file, aModel.GetColor( VRML_COLOR_TRACK ), @@ -791,6 +796,9 @@ static void export_round_padstack( MODEL_VRML& aModel, BOARD* pcb, if( thru && hole > 0 ) aModel.holes.AddCircle( x, -y, hole, true ); + if( aModel.plainPCB ) + return; + while( 1 ) { if( layer == B_Cu ) @@ -846,7 +854,8 @@ static void export_vrml_tracks( MODEL_VRML& aModel, BOARD* pcb ) { export_vrml_via( aModel, pcb, (const VIA*) track ); } - else if( track->GetLayer() == B_Cu || track->GetLayer() == F_Cu ) + else if( ( track->GetLayer() == B_Cu || track->GetLayer() == F_Cu ) + && !aModel.plainPCB ) export_vrml_line( aModel, track->GetLayer(), track->GetStart().x * aModel.scale, track->GetStart().y * aModel.scale, @@ -1102,7 +1111,8 @@ static void export_vrml_pad( MODEL_VRML& aModel, BOARD* pcb, D_PAD* aPad ) { bool pth = false; - if( aPad->GetAttribute() != PAD_HOLE_NOT_PLATED ) + if( ( aPad->GetAttribute() != PAD_HOLE_NOT_PLATED ) + && !aModel.plainPCB ) pth = true; if( aPad->GetDrillShape() == PAD_DRILL_OBLONG ) @@ -1127,6 +1137,9 @@ static void export_vrml_pad( MODEL_VRML& aModel, BOARD* pcb, D_PAD* aPad ) } } + if( aModel.plainPCB ) + return; + // The pad proper, on the selected layers LSET layer_mask = aPad->GetLayerSet(); @@ -1188,29 +1201,32 @@ static void export_vrml_module( MODEL_VRML& aModel, BOARD* aPcb, MODULE* aModule bool aExport3DFiles, bool aUseRelativePaths, const wxString& a3D_Subdir ) { - // Reference and value - if( aModule->Reference().IsVisible() ) - export_vrml_text_module( &aModule->Reference() ); - - if( aModule->Value().IsVisible() ) - export_vrml_text_module( &aModule->Value() ); - - // Export module edges - for( EDA_ITEM* item = aModule->GraphicalItems(); item; item = item->Next() ) + if( !aModel.plainPCB ) { - switch( item->Type() ) + // Reference and value + if( aModule->Reference().IsVisible() ) + export_vrml_text_module( &aModule->Reference() ); + + if( aModule->Value().IsVisible() ) + export_vrml_text_module( &aModule->Value() ); + + // Export module edges + for( EDA_ITEM* item = aModule->GraphicalItems(); item; item = item->Next() ) { - case PCB_MODULE_TEXT_T: - export_vrml_text_module( static_cast( item ) ); - break; + switch( item->Type() ) + { + case PCB_MODULE_TEXT_T: + export_vrml_text_module( static_cast( item ) ); + break; - case PCB_MODULE_EDGE_T: - export_vrml_edge_module( aModel, static_cast( item ), - aModule->GetOrientation() ); - break; + case PCB_MODULE_EDGE_T: + export_vrml_edge_module( aModel, static_cast( item ), + aModule->GetOrientation() ); + break; - default: - break; + default: + break; + } } } @@ -1340,13 +1356,14 @@ static void export_vrml_module( MODEL_VRML& aModel, BOARD* aPcb, MODULE* aModule bool PCB_EDIT_FRAME::ExportVRML_File( const wxString& aFullFileName, double aMMtoWRMLunit, bool aExport3DFiles, bool aUseRelativePaths, - const wxString& a3D_Subdir ) + bool aUsePlainPCB, const wxString& a3D_Subdir ) { wxString msg; BOARD* pcb = GetBoard(); bool ok = true; MODEL_VRML model3d; + model3d.plainPCB = aUsePlainPCB; model_vrml = &model3d; std::ofstream output_file; @@ -1387,13 +1404,15 @@ bool PCB_EDIT_FRAME::ExportVRML_File( const wxString& aFullFileName, double aMMt export_vrml_board( model3d, pcb ); // Drawing and text on the board - export_vrml_drawings( model3d, pcb ); + if( !aUsePlainPCB ) + export_vrml_drawings( model3d, pcb ); // Export vias and trackage export_vrml_tracks( model3d, pcb ); // Export zone fills - export_vrml_zones( model3d, pcb); + if( !aUsePlainPCB ) + export_vrml_zones( model3d, pcb); /* scaling factor to convert 3D models to board units (decimils) * Usually we use Wings3D to create thems.