diff --git a/pcbnew/board_stackup_manager/class_board_stackup.cpp b/pcbnew/board_stackup_manager/class_board_stackup.cpp index 6265740e89..f0fb81ec92 100644 --- a/pcbnew/board_stackup_manager/class_board_stackup.cpp +++ b/pcbnew/board_stackup_manager/class_board_stackup.cpp @@ -62,16 +62,19 @@ BOARD_STACKUP_ITEM::BOARD_STACKUP_ITEM( BOARD_STACKUP_ITEM_TYPE aType ) case BS_ITEM_TYPE_SOLDERMASK: m_TypeName = "soldermask"; - m_Color = NOT_SPECIFIED; + m_Color = "Green"; + m_Material = NOT_SPECIFIED; // or other solder mask material name m_Thickness = GetMaskDefaultThickness(); - m_EpsilonR = 3.5; + m_EpsilonR = DEFAULT_EPSILON_R_SOLDERMASK; m_LossTangent = 0.0; break; case BS_ITEM_TYPE_SILKSCREEN: m_TypeName = "silkscreen"; m_Color = NOT_SPECIFIED; - m_Thickness = 0.0; // Not used + m_Material = NOT_SPECIFIED; // or other silkscreen material name + m_EpsilonR = DEFAULT_EPSILON_R_SILKSCREEN; + m_Thickness = 0.0; // to be specified break; case BS_ITEM_TYPE_UNDEFINED: @@ -114,20 +117,35 @@ int BOARD_STACKUP_ITEM::GetMaskDefaultThickness() bool BOARD_STACKUP_ITEM::HasEpsilonRValue() { - return m_Type == BS_ITEM_TYPE_DIELECTRIC || m_Type == BS_ITEM_TYPE_SOLDERMASK; + return m_Type == BS_ITEM_TYPE_DIELECTRIC + || m_Type == BS_ITEM_TYPE_SOLDERMASK + //|| m_Type == BS_ITEM_TYPE_SILKSCREEN + ; }; bool BOARD_STACKUP_ITEM::HasLossTangentValue() { - return m_Type == BS_ITEM_TYPE_DIELECTRIC || m_Type == BS_ITEM_TYPE_SOLDERMASK; + return m_Type == BS_ITEM_TYPE_DIELECTRIC + || m_Type == BS_ITEM_TYPE_SOLDERMASK + //|| m_Type == BS_ITEM_TYPE_SILKSCREEN + ; }; +bool BOARD_STACKUP_ITEM::HasMaterialValue() +{ + // return true if the material is specified + return IsMaterialEditable() && ( m_Material.CmpNoCase( NOT_SPECIFIED ) != 0 ); +} + + bool BOARD_STACKUP_ITEM::IsMaterialEditable() { // The material is editable only for dielectric - return m_Type == BS_ITEM_TYPE_DIELECTRIC; + return m_Type == BS_ITEM_TYPE_DIELECTRIC || + m_Type == BS_ITEM_TYPE_SOLDERMASK || + m_Type == BS_ITEM_TYPE_SILKSCREEN; } @@ -505,14 +523,14 @@ void BOARD_STACKUP::FormatBoardStackup( OUTPUTFORMATTER* aFormatter, FormatInternalUnits( (int)item->m_Thickness ).c_str() ); } - if( item->m_Type == BS_ITEM_TYPE_DIELECTRIC ) + if( item->HasMaterialValue() ) aFormatter->Print( 0, " (material %s)", aFormatter->Quotew( item->m_Material ).c_str() ); - if( item->HasEpsilonRValue() ) + if( item->HasEpsilonRValue()&& item->HasMaterialValue() ) aFormatter->Print( 0, " (epsilon_r %g)", item->m_EpsilonR ); - if( item->HasLossTangentValue() ) + if( item->HasLossTangentValue()&& item->HasMaterialValue() ) aFormatter->Print( 0, " (loss_tangent %s)", Double2Str(item->m_LossTangent ).c_str() ); diff --git a/pcbnew/board_stackup_manager/class_board_stackup.h b/pcbnew/board_stackup_manager/class_board_stackup.h index 03cf8e92ee..97e124cf58 100644 --- a/pcbnew/board_stackup_manager/class_board_stackup.h +++ b/pcbnew/board_stackup_manager/class_board_stackup.h @@ -44,6 +44,7 @@ enum BOARD_STACKUP_ITEM_TYPE // dielectric between copper layers BS_ITEM_TYPE_SOLDERPASTE, // A initialized BOARD_STACKUP_ITEM item for solder paste layers BS_ITEM_TYPE_SOLDERMASK, // A initialized BOARD_STACKUP_ITEM item for solder mask layers + // note: this is a specialized dielectric material BS_ITEM_TYPE_SILKSCREEN, // A initialized BOARD_STACKUP_ITEM item for silkscreen layers }; @@ -70,7 +71,7 @@ public: /// false to ignore it. Mainly used in dialog stackup editor. wxString m_LayerName; /// name of layer as shown in layer manager. Usefull to create reports wxString m_TypeName; /// type name of layer (copper, silk screen, core, prepreg ...) - wxString m_Material; /// type of material (has meaning only for dielectric + wxString m_Material; /// type of material (has meaning only for dielectric and solder mask) int m_DielectricLayerId;/// the "layer" id for dielectric layers, /// from 1 (top) to 31 (bottom) wxString m_Color; /// mainly for silkscreen and solder mask @@ -91,6 +92,9 @@ public: /// namely dielectric layers: dielectric and solder mask bool HasLossTangentValue(); + /// @return true if the material is specified + bool HasMaterialValue(); + /// @return true if the material is editable bool IsMaterialEditable(); diff --git a/pcbnew/board_stackup_manager/dielectric_material.cpp b/pcbnew/board_stackup_manager/dielectric_material.cpp index 81dfff79a1..a5e5ff9a5a 100644 --- a/pcbnew/board_stackup_manager/dielectric_material.cpp +++ b/pcbnew/board_stackup_manager/dielectric_material.cpp @@ -50,6 +50,21 @@ static DIELECTRIC_SUBSTRATE substrateMaterial[] = // Other names are free }; +static DIELECTRIC_SUBSTRATE solderMaskMaterial[] = +{ + { NOT_SPECIFIED, DEFAULT_EPSILON_R_SOLDERMASK, 0.0 }, // Not specified, not in .gbrjob file + { "Epoxy", DEFAULT_EPSILON_R_SOLDERMASK, 0.0 }, // Epoxy Liquid material (usual) + { "Liquid Ink", DEFAULT_EPSILON_R_SOLDERMASK, 0.0 }, // Liquid Ink Photoimageable + { "Dry Film", DEFAULT_EPSILON_R_SOLDERMASK, 0.0 } // Dry Film Photoimageable +}; + +static DIELECTRIC_SUBSTRATE silkscreenMaterial[] = +{ + { NOT_SPECIFIED, DEFAULT_EPSILON_R_SILKSCREEN, 0.0 }, // Not specified, not in .gbrjob file + { "Liquid Photo", DEFAULT_EPSILON_R_SILKSCREEN, 0.0 }, // Liquid Ink Photoimageable + { "Direct Printing", DEFAULT_EPSILON_R_SILKSCREEN, 0.0 } // Direct Legend Printing +}; + wxString DIELECTRIC_SUBSTRATE::FormatEpsilonR() { @@ -69,11 +84,26 @@ wxString DIELECTRIC_SUBSTRATE::FormatLossTangent() } -DIELECTRIC_SUBSTRATE_LIST::DIELECTRIC_SUBSTRATE_LIST() +DIELECTRIC_SUBSTRATE_LIST::DIELECTRIC_SUBSTRATE_LIST( DL_MATERIAL_LIST_TYPE aListType ) { // Fills the m_substrateList with predefined params: - for( unsigned ii = 0; ii < arrayDim( substrateMaterial ); ++ii ) - m_substrateList.push_back( substrateMaterial[ii] ); + switch( aListType ) + { + case DL_MATERIAL_DIELECTRIC: + for( unsigned ii = 0; ii < arrayDim( substrateMaterial ); ++ii ) + m_substrateList.push_back( substrateMaterial[ii] ); + break; + + case DL_MATERIAL_SOLDERMASK: + for( unsigned ii = 0; ii < arrayDim( solderMaskMaterial ); ++ii ) + m_substrateList.push_back( solderMaskMaterial[ii] ); + break; + + case DL_MATERIAL_SILKSCREEN: + for( unsigned ii = 0; ii < arrayDim( silkscreenMaterial ); ++ii ) + m_substrateList.push_back( silkscreenMaterial[ii] ); + break; + } } diff --git a/pcbnew/board_stackup_manager/dielectric_material.h b/pcbnew/board_stackup_manager/dielectric_material.h index bbbd3b804b..63f158e6d3 100644 --- a/pcbnew/board_stackup_manager/dielectric_material.h +++ b/pcbnew/board_stackup_manager/dielectric_material.h @@ -51,7 +51,19 @@ class DIELECTRIC_SUBSTRATE_LIST std::vector m_substrateList; public: - DIELECTRIC_SUBSTRATE_LIST(); + enum DL_MATERIAL_LIST_TYPE + { + DL_MATERIAL_DIELECTRIC, + DL_MATERIAL_SOLDERMASK, + DL_MATERIAL_SILKSCREEN + }; + + /** Ctor + * @param aForDielectric = + * DL_MATERIAL_DIELECTRIC to build a dielectric material list + * DL_MATERIAL_SOLDERMASK to build a solder mask material list + */ + DIELECTRIC_SUBSTRATE_LIST( DL_MATERIAL_LIST_TYPE aListType); /** * @return the number of substrates in list diff --git a/pcbnew/board_stackup_manager/panel_board_stackup.cpp b/pcbnew/board_stackup_manager/panel_board_stackup.cpp index 387776ee51..127a3b15a7 100644 --- a/pcbnew/board_stackup_manager/panel_board_stackup.cpp +++ b/pcbnew/board_stackup_manager/panel_board_stackup.cpp @@ -62,7 +62,10 @@ static void drawBitmap( wxBitmap& aBitmap, wxColor aColor ); PANEL_SETUP_BOARD_STACKUP::PANEL_SETUP_BOARD_STACKUP( PAGED_DIALOG* aParent, PCB_EDIT_FRAME* aFrame, PANEL_SETUP_LAYERS* aPanelLayers ): - PANEL_SETUP_BOARD_STACKUP_BASE( aParent->GetTreebook() ) + PANEL_SETUP_BOARD_STACKUP_BASE( aParent->GetTreebook() ), + m_delectricMatList( DIELECTRIC_SUBSTRATE_LIST::DL_MATERIAL_DIELECTRIC ), + m_solderMaskMatList( DIELECTRIC_SUBSTRATE_LIST::DL_MATERIAL_SOLDERMASK ), + m_silkscreenMatList( DIELECTRIC_SUBSTRATE_LIST::DL_MATERIAL_SILKSCREEN ) { m_frame = aFrame; m_panelLayers = aPanelLayers; @@ -967,32 +970,64 @@ void PANEL_SETUP_BOARD_STACKUP::onColorSelected( wxCommandEvent& event ) void PANEL_SETUP_BOARD_STACKUP::onMaterialChange( wxCommandEvent& event ) { - // Ensure m_materialList contains all materials already in use in stacjup list + // Ensure m_materialList contains all materials already in use in stackup list // and add it is missing if( !transferDataFromUIToStackup() ) return; for( BOARD_STACKUP_ITEM* item : m_stackup.GetList() ) { - if( item->m_Type == BS_ITEM_TYPE_DIELECTRIC ) - { - int idx = m_materialList.FindSubstrate( item->m_Material, - item->m_EpsilonR, - item->m_LossTangent ); + DIELECTRIC_SUBSTRATE_LIST* mat_list = nullptr; - if( idx < 0 && !item->m_Material.IsEmpty() ) - { - // This material is not in list: add it - DIELECTRIC_SUBSTRATE new_mat; - new_mat.m_Name = item->m_Material; - new_mat.m_EpsilonR = item->m_EpsilonR; - new_mat.m_LossTangent = item->m_LossTangent; - m_materialList.AppendSubstrate( new_mat ); - } + if( item->m_Type == BS_ITEM_TYPE_DIELECTRIC ) + mat_list = &m_delectricMatList; + else if( item->m_Type == BS_ITEM_TYPE_SOLDERMASK ) + mat_list = &m_solderMaskMatList; + else if( item->m_Type == BS_ITEM_TYPE_SILKSCREEN ) + mat_list = &m_silkscreenMatList; + + else + continue; + + int idx = mat_list->FindSubstrate( item->m_Material, + item->m_EpsilonR, + item->m_LossTangent ); + + if( idx < 0 && !item->m_Material.IsEmpty() ) + { + // This material is not in list: add it + DIELECTRIC_SUBSTRATE new_mat; + new_mat.m_Name = item->m_Material; + new_mat.m_EpsilonR = item->m_EpsilonR; + new_mat.m_LossTangent = item->m_LossTangent; + mat_list->AppendSubstrate( new_mat ); } } - DIALOG_DIELECTRIC_MATERIAL dlg( this, m_materialList ); + int row = event.GetId() - ID_ITEM_MATERIAL; + BOARD_STACKUP_ITEM* item = GetStackupItem( row ); + DIELECTRIC_SUBSTRATE_LIST* item_mat_list = nullptr; + + switch( item->m_Type ) + { + case BS_ITEM_TYPE_DIELECTRIC: + item_mat_list = &m_delectricMatList; + break; + + case BS_ITEM_TYPE_SOLDERMASK: + item_mat_list = &m_solderMaskMatList; + break; + + case BS_ITEM_TYPE_SILKSCREEN: + item_mat_list = &m_silkscreenMatList; + break; + + default: + item_mat_list = nullptr; + break; + } + + DIALOG_DIELECTRIC_MATERIAL dlg( this, *item_mat_list ); if( dlg.ShowModal() != wxID_OK ) return; @@ -1002,10 +1037,7 @@ void PANEL_SETUP_BOARD_STACKUP::onMaterialChange( wxCommandEvent& event ) if( substrate.m_Name.IsEmpty() ) // No substrate specified return; - int row = event.GetId() - ID_ITEM_MATERIAL; - // Update Name, Epsilon R and Loss tg - BOARD_STACKUP_ITEM* item = GetStackupItem( row ); item->m_Material = substrate.m_Name; item->m_EpsilonR = substrate.m_EpsilonR; item->m_LossTangent = substrate.m_LossTangent; diff --git a/pcbnew/board_stackup_manager/panel_board_stackup.h b/pcbnew/board_stackup_manager/panel_board_stackup.h index dff15d9248..abc675c1de 100644 --- a/pcbnew/board_stackup_manager/panel_board_stackup.h +++ b/pcbnew/board_stackup_manager/panel_board_stackup.h @@ -75,7 +75,9 @@ struct BOARD_STACKUP_ROW_UI_ITEM class PANEL_SETUP_BOARD_STACKUP : public PANEL_SETUP_BOARD_STACKUP_BASE { public: - PANEL_SETUP_BOARD_STACKUP( PAGED_DIALOG* aParent, PCB_EDIT_FRAME* aFrame, PANEL_SETUP_LAYERS* aPanelLayers ); + PANEL_SETUP_BOARD_STACKUP( PAGED_DIALOG* aParent, + PCB_EDIT_FRAME* aFrame, + PANEL_SETUP_LAYERS* aPanelLayers ); ~PANEL_SETUP_BOARD_STACKUP(); void ImportSettingsFrom( BOARD* aBoard ); @@ -182,8 +184,14 @@ private: // restricted to allowed layers in stackup. // when do not match the enabled layers // in PANEL_SETUP_LAYERS the stackup is not up to date - DIELECTRIC_SUBSTRATE_LIST m_materialList; // a list of currently available materials - std::vector m_rowUiItemsList; // List of items in m_fgGridSizer + // a list of currently available dielectric materials + DIELECTRIC_SUBSTRATE_LIST m_delectricMatList; + // a list of currently available solder mask materials + DIELECTRIC_SUBSTRATE_LIST m_solderMaskMatList; + // a list of currently available solder mask materials + DIELECTRIC_SUBSTRATE_LIST m_silkscreenMatList; + // List of items in m_fgGridSizer + std::vector m_rowUiItemsList; BOARD* m_board; BOARD_DESIGN_SETTINGS* m_brdSettings; EDA_UNITS_T m_units; diff --git a/pcbnew/board_stackup_manager/panel_board_stackup_base.cpp b/pcbnew/board_stackup_manager/panel_board_stackup_base.cpp index 85650ebb5a..84b6f6d7ad 100644 --- a/pcbnew/board_stackup_manager/panel_board_stackup_base.cpp +++ b/pcbnew/board_stackup_manager/panel_board_stackup_base.cpp @@ -63,7 +63,7 @@ PANEL_SETUP_BOARD_STACKUP_BASE::PANEL_SETUP_BOARD_STACKUP_BASE( wxWindow* parent m_staticTextLayer->Wrap( -1 ); m_staticTextLayer->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, false, wxEmptyString ) ); - m_fgGridSizer->Add( m_staticTextLayer, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 2 ); + m_fgGridSizer->Add( m_staticTextLayer, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_HORIZONTAL, 2 ); m_staticText8 = new wxStaticText( m_scGridWin, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT ); m_staticText8->Wrap( -1 ); @@ -75,40 +75,40 @@ PANEL_SETUP_BOARD_STACKUP_BASE::PANEL_SETUP_BOARD_STACKUP_BASE( wxWindow* parent m_staticTextType->Wrap( -1 ); m_staticTextType->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, false, wxEmptyString ) ); - m_fgGridSizer->Add( m_staticTextType, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 2 ); + m_fgGridSizer->Add( m_staticTextType, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_HORIZONTAL, 2 ); m_staticTextMaterial = new wxStaticText( m_scGridWin, wxID_ANY, _("Material"), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT ); m_staticTextMaterial->Wrap( -1 ); m_staticTextMaterial->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, false, wxEmptyString ) ); - m_fgGridSizer->Add( m_staticTextMaterial, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 2 ); + m_fgGridSizer->Add( m_staticTextMaterial, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_HORIZONTAL, 2 ); m_staticTextThickness = new wxStaticText( m_scGridWin, wxID_ANY, _("Thickness"), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT ); m_staticTextThickness->Wrap( -1 ); m_staticTextThickness->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, false, wxEmptyString ) ); - m_fgGridSizer->Add( m_staticTextThickness, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 2 ); + m_fgGridSizer->Add( m_staticTextThickness, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_HORIZONTAL, 2 ); m_bitmapLockThickness = new wxStaticBitmap( m_scGridWin, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 ); - m_fgGridSizer->Add( m_bitmapLockThickness, 0, wxALIGN_CENTER_VERTICAL, 5 ); + m_fgGridSizer->Add( m_bitmapLockThickness, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL, 5 ); m_staticTextColor = new wxStaticText( m_scGridWin, wxID_ANY, _("Color"), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT ); m_staticTextColor->Wrap( -1 ); m_staticTextColor->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, false, wxEmptyString ) ); - m_fgGridSizer->Add( m_staticTextColor, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 2 ); + m_fgGridSizer->Add( m_staticTextColor, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_HORIZONTAL, 2 ); m_staticTextEpsilonR = new wxStaticText( m_scGridWin, wxID_ANY, _("Epsilon R"), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT ); m_staticTextEpsilonR->Wrap( -1 ); m_staticTextEpsilonR->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, false, wxEmptyString ) ); - m_fgGridSizer->Add( m_staticTextEpsilonR, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 2 ); + m_fgGridSizer->Add( m_staticTextEpsilonR, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_HORIZONTAL, 2 ); - m_staticTextLossTg = new wxStaticText( m_scGridWin, wxID_ANY, _("Loss Tan"), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT ); + m_staticTextLossTg = new wxStaticText( m_scGridWin, wxID_ANY, _("Loss Tg"), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT ); m_staticTextLossTg->Wrap( -1 ); m_staticTextLossTg->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, false, wxEmptyString ) ); - m_fgGridSizer->Add( m_staticTextLossTg, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 2 ); + m_fgGridSizer->Add( m_staticTextLossTg, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_HORIZONTAL, 2 ); m_scGridWin->SetSizer( m_fgGridSizer ); diff --git a/pcbnew/board_stackup_manager/panel_board_stackup_base.fbp b/pcbnew/board_stackup_manager/panel_board_stackup_base.fbp index 731ad8346b..f1496c589b 100644 --- a/pcbnew/board_stackup_manager/panel_board_stackup_base.fbp +++ b/pcbnew/board_stackup_manager/panel_board_stackup_base.fbp @@ -558,7 +558,7 @@ 0 2 - wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT + wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_HORIZONTAL 0 1 @@ -680,7 +680,7 @@ 2 - wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT + wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_HORIZONTAL 0 1 @@ -741,7 +741,7 @@ 2 - wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT + wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_HORIZONTAL 0 1 @@ -802,7 +802,7 @@ 2 - wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT + wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_HORIZONTAL 0 1 @@ -863,7 +863,7 @@ 5 - wxALIGN_CENTER_VERTICAL + wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL 0 1 @@ -921,7 +921,7 @@ 2 - wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT + wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_HORIZONTAL 0 1 @@ -982,7 +982,7 @@ 2 - wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT + wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_HORIZONTAL 0 1 @@ -1043,7 +1043,7 @@ 2 - wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT + wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_HORIZONTAL 0 1 @@ -1073,7 +1073,7 @@ 0 0 wxID_ANY - Loss Tan + Loss Tg 0 0 diff --git a/pcbnew/board_stackup_manager/stackup_predefined_prms.cpp b/pcbnew/board_stackup_manager/stackup_predefined_prms.cpp index bbe473ceb6..828178401a 100644 --- a/pcbnew/board_stackup_manager/stackup_predefined_prms.cpp +++ b/pcbnew/board_stackup_manager/stackup_predefined_prms.cpp @@ -61,12 +61,13 @@ static wxString CopperFinishType[] = // A list of available colors for solder mask and silkscreen // These names are used in .gbrjob file, so they are not fully free. // Use only what is allowed in .gbrjob files. -// for other colors (user defined), the defined value is the html color syntax +// for other colors (user defined), the defined value is the +// html color syntax in .kicad_pcb files // and RGB In gbrjob file. static FAB_LAYER_COLOR solderMaskColors[] = { { _HKI( NOT_SPECIFIED ), wxColor( 80, 80, 80 ) }, // Not specified, not in .gbrjob file - { _HKI( "Green" ), wxColor( 60, 150, 80 ) }, // used in .gbrjob file + { _HKI( "Green" ), wxColor( 60, 150, 80 ) }, // used in .gbrjob file { _HKI( "Red" ), wxColor( 128, 0, 0 ) }, // used in .gbrjob file { _HKI( "Blue" ), wxColor( 0, 0, 128 ) }, // used in .gbrjob file { _HKI( "Black" ), wxColor( 20, 20, 20 ) }, // used in .gbrjob file diff --git a/pcbnew/board_stackup_manager/stackup_predefined_prms.h b/pcbnew/board_stackup_manager/stackup_predefined_prms.h index 51733c9e59..a364440355 100644 --- a/pcbnew/board_stackup_manager/stackup_predefined_prms.h +++ b/pcbnew/board_stackup_manager/stackup_predefined_prms.h @@ -45,6 +45,12 @@ // String in wxChoice to use user defined material or solder mask color #define USER_DEFINED "user defined" +// A reasonable Epsilon R value for solder mask dielectric +#define DEFAULT_EPSILON_R_SOLDERMASK 3.3 + +// A default Epsilon R value for silkscreen dielectric +#define DEFAULT_EPSILON_R_SILKSCREEN 1.0 + // A minor struct to handle color in gerber job file and dialog struct FAB_LAYER_COLOR { diff --git a/pcbnew/exporters/gerber_jobfile_writer.cpp b/pcbnew/exporters/gerber_jobfile_writer.cpp index 448dca46e8..a156341e8f 100644 --- a/pcbnew/exporters/gerber_jobfile_writer.cpp +++ b/pcbnew/exporters/gerber_jobfile_writer.cpp @@ -676,15 +676,25 @@ void GERBER_JOBFILE_WRITER::addJSONMaterialStackup() if( item->m_Type == BS_ITEM_TYPE_DIELECTRIC ) { - addJSONObject( wxString::Format( "\"Material\": \"%s\",\n", item->m_Material ) ); - - // These constrains are only written if the board has impedance controlled tracks. - // If the board is not impedance controlled, they are useless. - // Do not add constrains that create more expensive boards. - if( brd_stackup.m_HasDielectricConstrains ) + if( item->HasMaterialValue() ) { - addJSONObject( wxString::Format( "\"DielectricConstant\": %s,\n", item->FormatEpsilonR() ) ); - addJSONObject( wxString::Format( "\"LossTangent\": %s,\n", item->FormatLossTangent() ) ); + addJSONObject( wxString::Format( "\"Material\": \"%s\",\n", item->m_Material ) ); + + // These constrains are only written if the board has impedance controlled tracks. + // If the board is not impedance controlled, they are useless. + // Do not add constrains that create more expensive boards. + if( brd_stackup.m_HasDielectricConstrains ) + { + // Generate Epsilon R if > 1.0 (value <= 1.0 means not specified: it is not + // a possible value + if( item->m_EpsilonR > 1.0 ) + addJSONObject( wxString::Format( "\"DielectricConstant\": %s,\n", item->FormatEpsilonR() ) ); + + // Generate LossTangent > 0.0 (value <= 0.0 means not specified: it is not + // a possible value + if( item->m_LossTangent > 0.0 ) + addJSONObject( wxString::Format( "\"LossTangent\": %s,\n", item->FormatLossTangent() ) ); + } } PCB_LAYER_ID next_copper_layer = (PCB_LAYER_ID) (last_copper_layer+1); @@ -712,6 +722,31 @@ void GERBER_JOBFILE_WRITER::addJSONMaterialStackup() addJSONObject( note ); } + else if( item->m_Type == BS_ITEM_TYPE_SOLDERMASK || item->m_Type == BS_ITEM_TYPE_SILKSCREEN ) + { + if( item->HasMaterialValue() ) + { + addJSONObject( wxString::Format( "\"Material\": \"%s\",\n", item->m_Material ) ); + + // These constrains are only written if the board has impedance controlled tracks. + // If the board is not impedance controlled, they are useless. + // Do not add constrains that create more expensive boards. + if( brd_stackup.m_HasDielectricConstrains ) + { + // Generate Epsilon R if > 1.0 (value <= 1.0 means not specified: it is not + // a possible value + if( item->m_EpsilonR > 1.0 ) + addJSONObject( wxString::Format( "\"DielectricConstant\": %s,\n", item->FormatEpsilonR() ) ); + + // Generate LossTangent > 0.0 (value <= 0.0 means not specified: it is not + // a possible value + if( item->m_LossTangent > 0.0 ) + addJSONObject( wxString::Format( "\"LossTangent\": %s,\n", item->FormatLossTangent() ) ); + } + } + + addJSONObject( wxString::Format( "\"Name\": \"%s\",\n", layer_name.c_str() ) ); + } else { addJSONObject( wxString::Format( "\"Name\": \"%s\",\n", layer_name.c_str() ) );