Board stackup manager: add material selector to solder mask and silkscreen layers.

This commit is contained in:
jean-pierre charras 2019-09-24 14:33:28 +02:00
parent 9f156aa115
commit cd6c1c48a4
11 changed files with 211 additions and 65 deletions

View File

@ -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() );

View File

@ -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();

View File

@ -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;
}
}

View File

@ -51,7 +51,19 @@ class DIELECTRIC_SUBSTRATE_LIST
std::vector<DIELECTRIC_SUBSTRATE> 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

View File

@ -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;

View File

@ -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<BOARD_STACKUP_ROW_UI_ITEM> 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<BOARD_STACKUP_ROW_UI_ITEM> m_rowUiItemsList;
BOARD* m_board;
BOARD_DESIGN_SETTINGS* m_brdSettings;
EDA_UNITS_T m_units;

View File

@ -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 );

View File

@ -558,7 +558,7 @@
<property name="vgap">0</property>
<object class="sizeritem" expanded="1">
<property name="border">2</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_HORIZONTAL</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="1">
<property name="BottomDockable">1</property>
@ -680,7 +680,7 @@
</object>
<object class="sizeritem" expanded="1">
<property name="border">2</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_HORIZONTAL</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="1">
<property name="BottomDockable">1</property>
@ -741,7 +741,7 @@
</object>
<object class="sizeritem" expanded="1">
<property name="border">2</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_HORIZONTAL</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="1">
<property name="BottomDockable">1</property>
@ -802,7 +802,7 @@
</object>
<object class="sizeritem" expanded="1">
<property name="border">2</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_HORIZONTAL</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="1">
<property name="BottomDockable">1</property>
@ -863,7 +863,7 @@
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL</property>
<property name="proportion">0</property>
<object class="wxStaticBitmap" expanded="1">
<property name="BottomDockable">1</property>
@ -921,7 +921,7 @@
</object>
<object class="sizeritem" expanded="1">
<property name="border">2</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_HORIZONTAL</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="1">
<property name="BottomDockable">1</property>
@ -982,7 +982,7 @@
</object>
<object class="sizeritem" expanded="1">
<property name="border">2</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_HORIZONTAL</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="1">
<property name="BottomDockable">1</property>
@ -1043,7 +1043,7 @@
</object>
<object class="sizeritem" expanded="1">
<property name="border">2</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_HORIZONTAL</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="1">
<property name="BottomDockable">1</property>
@ -1073,7 +1073,7 @@
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Loss Tan</property>
<property name="label">Loss Tg</property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>

View File

@ -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 R<integer>G<integer>B<integer> 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

View File

@ -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
{

View File

@ -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() ) );