Board stackup manager: prepare code to allow multiple dielectric material by layer.

For advanced microwave applications, sometime a dielectric between 2 copper layers
must be itself created by a stack of different materials.
This commit is contained in:
jean-pierre charras 2019-11-11 19:34:48 +01:00
parent f333d1b974
commit 2b201487e1
10 changed files with 713 additions and 237 deletions

View File

@ -48,13 +48,13 @@ wxString BuildStackupReport( BOARD_STACKUP& aStackup, EDA_UNITS_T aUnits )
for( const auto item : aStackup.GetList() )
{
// Skip stackup items useless for the current board
if( !item->m_Enabled )
if( !item->IsEnabled() )
{
row++;
continue;
}
txt.Printf( "layer \"%s\" type \"%s\"", item->m_LayerName, item->m_TypeName );
txt.Printf( "layer \"%s\" type \"%s\"", item->GetLayerName(), item->GetTypeName() );
report << txt;
if( item->HasEpsilonRValue() )
@ -71,23 +71,23 @@ wxString BuildStackupReport( BOARD_STACKUP& aStackup, EDA_UNITS_T aUnits )
if( item->IsMaterialEditable() )
{
txt.Printf( " Material \"%s\"", item->m_Material );
txt.Printf( " Material \"%s\"", item->GetMaterial() );
report << txt;
}
if( item->m_Type == BS_ITEM_TYPE_DIELECTRIC )
if( item->GetType() == BS_ITEM_TYPE_DIELECTRIC )
{
txt.Printf( " \"%s\"", item->m_TypeName );
txt.Printf( " \"%s\"", item->GetTypeName() );
report << txt;
}
if( item->IsThicknessEditable() )
{
txt.Printf( " Thickness %s",
StringFromValue( aUnits, item->m_Thickness, true, true ) );
StringFromValue( aUnits, item->GetThickness(), true, true ) );
report << txt;
if( item->m_Type == BS_ITEM_TYPE_DIELECTRIC && item->m_ThicknessLocked )
if( item->GetType() == BS_ITEM_TYPE_DIELECTRIC && item->IsThicknessLocked() )
{
txt.Printf( " Locked" );
report << txt;
@ -96,7 +96,7 @@ wxString BuildStackupReport( BOARD_STACKUP& aStackup, EDA_UNITS_T aUnits )
if( item->IsColorEditable() )
{
txt.Printf( " Color \"%s\"", item->m_Color );
txt.Printf( " Color \"%s\"", item->GetColor() );
report << txt;
}
row++;

View File

@ -31,55 +31,48 @@
BOARD_STACKUP_ITEM::BOARD_STACKUP_ITEM( BOARD_STACKUP_ITEM_TYPE aType )
{
DIELECTRIC_PRMS item_prms;
m_DielectricPrmsList.emplace_back( item_prms );
m_LayerId = UNDEFINED_LAYER;
m_Type = aType;
m_Enabled = true;
m_DielectricLayerId = 0;
m_EpsilonR = 0;
m_LossTangent = 0.0;
m_ThicknessLocked = false;
SetEnabled( true );
// Initialize parameters to a usual value for allowed types:
switch( m_Type )
{
case BS_ITEM_TYPE_COPPER:
m_TypeName = KEY_COPPER;
m_Thickness = GetCopperDefaultThickness();
SetThickness( GetCopperDefaultThickness() );
break;
case BS_ITEM_TYPE_DIELECTRIC:
m_TypeName = KEY_CORE; // or prepreg
m_Material = "FR4"; // or other dielectric name
m_DielectricLayerId = 1;
m_Thickness = 0; // will be set later
m_LossTangent = 0.02; // for FR4
m_EpsilonR = 4.5; // for FR4
SetMaterial( "FR4" ); // or other dielectric name
SetDielectricLayerId( 1 );
SetLossTangent( 0.02 ); // for FR4
SetEpsilonR( 4.5 ); // for FR4
break;
case BS_ITEM_TYPE_SOLDERPASTE:
m_TypeName = "solderpaste";
m_Thickness = 0.0; // Not used
break;
case BS_ITEM_TYPE_SOLDERMASK:
m_TypeName = "soldermask";
m_Color = "Green";
m_Material = NotSpecifiedPrm(); // or other solder mask material name
m_Thickness = GetMaskDefaultThickness();
m_EpsilonR = DEFAULT_EPSILON_R_SOLDERMASK;
m_LossTangent = 0.0;
SetMaterial( NotSpecifiedPrm() ); // or other solder mask material name
SetThickness( GetMaskDefaultThickness() );
SetEpsilonR( DEFAULT_EPSILON_R_SOLDERMASK );
break;
case BS_ITEM_TYPE_SILKSCREEN:
m_TypeName = "silkscreen";
m_Color = NotSpecifiedPrm();
m_Material = NotSpecifiedPrm(); // or other silkscreen material name
m_EpsilonR = DEFAULT_EPSILON_R_SILKSCREEN;
m_Thickness = 0.0; // to be specified
SetMaterial( NotSpecifiedPrm() ); // or other silkscreen material name
SetEpsilonR( DEFAULT_EPSILON_R_SILKSCREEN );
break;
case BS_ITEM_TYPE_UNDEFINED:
m_Thickness = 0.0;
break;
}
}
@ -89,16 +82,11 @@ BOARD_STACKUP_ITEM::BOARD_STACKUP_ITEM( BOARD_STACKUP_ITEM& aOther )
{
m_LayerId = aOther.m_LayerId;
m_Type = aOther.m_Type;
m_Enabled = aOther.m_Enabled;
m_DielectricLayerId = aOther.m_DielectricLayerId;
m_enabled = aOther.m_enabled;
m_DielectricPrmsList = aOther.m_DielectricPrmsList;
m_TypeName = aOther.m_TypeName;
m_LayerName = aOther.m_LayerName;
m_Material = aOther.m_Material;
m_Color = aOther.m_Color;
m_Thickness = aOther.m_Thickness;
m_ThicknessLocked = aOther.m_ThicknessLocked;
m_EpsilonR = aOther.m_EpsilonR;
m_LossTangent = aOther.m_LossTangent;
m_Color = aOther.GetColor();
}
@ -115,6 +103,79 @@ int BOARD_STACKUP_ITEM::GetMaskDefaultThickness()
return Millimeter2iu( 0.01 );
}
// Getters:
int BOARD_STACKUP_ITEM::GetThickness( int aDielectricSubLayer )
{
return m_DielectricPrmsList[aDielectricSubLayer].m_Thickness;
}
double BOARD_STACKUP_ITEM::GetLossTangent( int aDielectricSubLayer )
{
return m_DielectricPrmsList[aDielectricSubLayer].m_LossTangent;
}
double BOARD_STACKUP_ITEM::GetEpsilonR( int aDielectricSubLayer )
{
return m_DielectricPrmsList[aDielectricSubLayer].m_EpsilonR;
}
bool BOARD_STACKUP_ITEM::IsThicknessLocked( int aDielectricSubLayer )
{
return m_DielectricPrmsList[aDielectricSubLayer].m_ThicknessLocked;
}
int BOARD_STACKUP_ITEM::GetDielectricLayerId( int aDielectricSubLayer )
{
return m_DielectricPrmsList[aDielectricSubLayer].m_DielectricLayerId;
}
wxString BOARD_STACKUP_ITEM::GetMaterial( int aDielectricSubLayer )
{
return m_DielectricPrmsList[aDielectricSubLayer].m_Material;
}
// Setters:
void BOARD_STACKUP_ITEM::SetThickness( int aThickness, int aDielectricSubLayer )
{
m_DielectricPrmsList[aDielectricSubLayer].m_Thickness = aThickness;
}
void BOARD_STACKUP_ITEM::SetLossTangent( double aTg, int aDielectricSubLayer )
{
m_DielectricPrmsList[aDielectricSubLayer].m_LossTangent = aTg;
}
void BOARD_STACKUP_ITEM::SetEpsilonR( double aEpsilon, int aDielectricSubLayer )
{
m_DielectricPrmsList[aDielectricSubLayer].m_EpsilonR = aEpsilon;
}
void BOARD_STACKUP_ITEM::SetThicknessLocked( bool aLocked, int aDielectricSubLayer )
{
m_DielectricPrmsList[aDielectricSubLayer].m_ThicknessLocked = aLocked;
}
void BOARD_STACKUP_ITEM::SetDielectricLayerId( int aLayerId, int aDielectricSubLayer )
{
m_DielectricPrmsList[aDielectricSubLayer].m_DielectricLayerId = aLayerId;
}
void BOARD_STACKUP_ITEM::SetMaterial( const wxString& aName, int aDielectricSubLayer )
{
m_DielectricPrmsList[aDielectricSubLayer].m_Material = aName;
}
bool BOARD_STACKUP_ITEM::HasEpsilonRValue()
{
@ -137,7 +198,7 @@ bool BOARD_STACKUP_ITEM::HasLossTangentValue()
bool BOARD_STACKUP_ITEM::HasMaterialValue()
{
// return true if the material is specified
return IsMaterialEditable() && IsPrmSpecified( m_Material );
return IsMaterialEditable() && IsPrmSpecified( GetMaterial() );
}
@ -187,7 +248,7 @@ wxString BOARD_STACKUP_ITEM::FormatEpsilonR()
{
// return a wxString to print/display Epsilon R
wxString txt;
txt.Printf( "%.1f", m_EpsilonR );
txt.Printf( "%.1f", GetEpsilonR() );
return txt;
}
@ -196,11 +257,20 @@ wxString BOARD_STACKUP_ITEM::FormatLossTangent()
{
// return a wxString to print/display Loss Tangent
wxString txt;
txt.Printf( "%g", m_LossTangent );
txt.Printf( "%g", GetLossTangent() );
return txt;
}
wxString BOARD_STACKUP_ITEM::FormatDielectricLayerName()
{
// return a wxString to print/display a dielectriv name
wxString lname;
lname.Printf( _( "Dielectric %d" ), GetDielectricLayerId() );
return lname;
}
BOARD_STACKUP::BOARD_STACKUP()
{
@ -279,8 +349,8 @@ int BOARD_STACKUP::BuildBoardTicknessFromStackup() const
for( auto item : m_list )
{
if( item->IsThicknessEditable() && item->m_Enabled )
thickness += item->m_Thickness;
if( item->IsThicknessEditable() && item->IsEnabled() )
thickness += item->GetThickness();
}
return thickness;
@ -301,7 +371,7 @@ bool BOARD_STACKUP::SynchronizeWithBoard( BOARD_DESIGN_SETTINGS* aSettings )
for( BOARD_STACKUP_ITEM* item: stackup.GetList() )
{
if( item->m_LayerId == old_item->m_LayerId )
if( item->GetBrdLayerId() == old_item->GetBrdLayerId() )
{
found = true;
break;
@ -322,9 +392,9 @@ bool BOARD_STACKUP::SynchronizeWithBoard( BOARD_DESIGN_SETTINGS* aSettings )
// Search for initial settings:
for( BOARD_STACKUP_ITEM* initial_item: m_list )
{
if( item->m_LayerId != UNDEFINED_LAYER )
if( item->GetBrdLayerId() != UNDEFINED_LAYER )
{
if( item->m_LayerId == initial_item->m_LayerId )
if( item->GetBrdLayerId() == initial_item->GetBrdLayerId() )
{
*item = *initial_item;
found = true;
@ -333,7 +403,7 @@ bool BOARD_STACKUP::SynchronizeWithBoard( BOARD_DESIGN_SETTINGS* aSettings )
}
else // dielectric layer: see m_DielectricLayerId for identification
{
if( item->m_DielectricLayerId == initial_item->m_DielectricLayerId )
if( item->GetDielectricLayerId() == initial_item->GetDielectricLayerId() )
{
*item = *initial_item;
found = true;
@ -393,24 +463,24 @@ void BOARD_STACKUP::BuildDefaultStackupList( BOARD_DESIGN_SETTINGS* aSettings,
if( enabledLayer[F_SilkS] )
{
BOARD_STACKUP_ITEM* item = new BOARD_STACKUP_ITEM( BS_ITEM_TYPE_SILKSCREEN );
item->m_LayerId = F_SilkS;
item->m_TypeName = _HKI( "Top Silk Screen" );
item->SetBrdLayerId( F_SilkS );
item->SetTypeName( _HKI( "Top Silk Screen" ) );
Add( item );
}
if( enabledLayer[F_Paste] )
{
BOARD_STACKUP_ITEM* item = new BOARD_STACKUP_ITEM( BS_ITEM_TYPE_SOLDERPASTE );
item->m_LayerId = F_Paste;
item->m_TypeName = _HKI( "Top Solder Paste" );
item->SetBrdLayerId( F_Paste );
item->SetTypeName( _HKI( "Top Solder Paste" ) );
Add( item );
}
if( enabledLayer[F_Mask] )
{
BOARD_STACKUP_ITEM* item = new BOARD_STACKUP_ITEM( BS_ITEM_TYPE_SOLDERMASK );
item->m_LayerId = F_Mask;
item->m_TypeName = _HKI( "Top Solder Mask" );
item->SetBrdLayerId( F_Mask );
item->SetTypeName( _HKI( "Top Solder Mask" ) );
Add( item );
}
@ -418,31 +488,31 @@ void BOARD_STACKUP::BuildDefaultStackupList( BOARD_DESIGN_SETTINGS* aSettings,
for( int ii = 0; ii < copperLayerCount; ii++ )
{
BOARD_STACKUP_ITEM* item = new BOARD_STACKUP_ITEM( BS_ITEM_TYPE_COPPER );
item->m_LayerId = ( PCB_LAYER_ID )ii;
item->m_TypeName = KEY_COPPER;
item->SetBrdLayerId( ( PCB_LAYER_ID )ii );
item->SetTypeName( KEY_COPPER );
Add( item );
if( ii == copperLayerCount-1 )
{
item->m_LayerId = B_Cu;
item->SetBrdLayerId( B_Cu );
break;
}
// Add the dielectric layer:
item = new BOARD_STACKUP_ITEM( BS_ITEM_TYPE_DIELECTRIC );
item->m_Thickness = diel_thickness;
item->m_DielectricLayerId = dielectric_idx + 1;
item->SetThickness( diel_thickness );
item->SetDielectricLayerId( dielectric_idx + 1 );
// Display a dielectric default layer name:
if( (dielectric_idx & 1) == 0 )
{
item->m_TypeName = KEY_CORE;
item->m_Material = "FR4";
item->SetTypeName( KEY_CORE );
item->SetMaterial( "FR4" );
}
else
{
item->m_TypeName = KEY_PREPREG;
item->m_Material = "FR4";
item->SetTypeName( KEY_PREPREG );
item->SetMaterial( "FR4" );
}
Add( item );
@ -453,24 +523,24 @@ void BOARD_STACKUP::BuildDefaultStackupList( BOARD_DESIGN_SETTINGS* aSettings,
if( enabledLayer[B_Mask] )
{
BOARD_STACKUP_ITEM* item = new BOARD_STACKUP_ITEM( BS_ITEM_TYPE_SOLDERMASK );
item->m_LayerId = B_Mask;
item->m_TypeName = _HKI( "Bottom Solder Mask" );
item->SetBrdLayerId( B_Mask );
item->SetTypeName( _HKI( "Bottom Solder Mask" ) );
Add( item );
}
if( enabledLayer[B_Paste] )
{
BOARD_STACKUP_ITEM* item = new BOARD_STACKUP_ITEM( BS_ITEM_TYPE_SOLDERPASTE );
item->m_LayerId = B_Paste;
item->m_TypeName = _HKI( "Bottom Solder Paste" );
item->SetBrdLayerId( B_Paste );
item->SetTypeName( _HKI( "Bottom Solder Paste" ) );
Add( item );
}
if( enabledLayer[B_SilkS] )
{
BOARD_STACKUP_ITEM* item = new BOARD_STACKUP_ITEM( BS_ITEM_TYPE_SILKSCREEN );
item->m_LayerId = B_SilkS;
item->m_TypeName = _HKI( "Bottom Silk Screen" );
item->SetBrdLayerId( B_SilkS );
item->SetTypeName( _HKI( "Bottom Silk Screen" ) );
Add( item );
}
@ -505,41 +575,41 @@ void BOARD_STACKUP::FormatBoardStackup( OUTPUTFORMATTER* aFormatter,
{
wxString layer_name;
if( item->m_LayerId == UNDEFINED_LAYER )
if( item->GetBrdLayerId() == UNDEFINED_LAYER )
{
layer_name.Printf( "dielectric %d", item->m_DielectricLayerId );
layer_name.Printf( "dielectric %d", item->GetDielectricLayerId() );
}
else
layer_name = aBoard->GetLayerName( item->m_LayerId );
layer_name = aBoard->GetLayerName( item->GetBrdLayerId() );
aFormatter->Print( nest_level, "(layer %s (type %s)",
aFormatter->Quotew( layer_name ).c_str(),
aFormatter->Quotew( item->m_TypeName ).c_str() );
aFormatter->Quotew( item->GetTypeName() ).c_str() );
if( item->IsThicknessEditable() )
{
if( item->m_Type == BS_ITEM_TYPE_DIELECTRIC && item->m_ThicknessLocked )
if( item->GetType() == BS_ITEM_TYPE_DIELECTRIC && item->IsThicknessLocked() )
aFormatter->Print( 0, " (thickness %s locked)",
FormatInternalUnits( (int)item->m_Thickness ).c_str() );
FormatInternalUnits( item->GetThickness() ).c_str() );
else
aFormatter->Print( 0, " (thickness %s)",
FormatInternalUnits( (int)item->m_Thickness ).c_str() );
FormatInternalUnits( item->GetThickness() ).c_str() );
}
if( item->HasMaterialValue() )
aFormatter->Print( 0, " (material %s)",
aFormatter->Quotew( item->m_Material ).c_str() );
aFormatter->Quotew( item->GetMaterial() ).c_str() );
if( item->HasEpsilonRValue() && item->HasMaterialValue() )
aFormatter->Print( 0, " (epsilon_r %g)", item->m_EpsilonR );
aFormatter->Print( 0, " (epsilon_r %g)", item->GetEpsilonR() );
if( item->HasLossTangentValue() && item->HasMaterialValue() )
aFormatter->Print( 0, " (loss_tangent %s)",
Double2Str(item->m_LossTangent ).c_str() );
Double2Str(item->GetLossTangent() ).c_str() );
if( item->IsColorEditable() && IsPrmSpecified( item->m_Color ) )
if( item->IsColorEditable() && IsPrmSpecified( item->GetColor() ) )
aFormatter->Print( 0, " (color %s)",
aFormatter->Quotew( item->m_Color ).c_str() );
aFormatter->Quotew( item->GetColor() ).c_str() );
aFormatter->Print( 0, ")\n" );
}

View File

@ -56,6 +56,33 @@ enum BS_EDGE_CONNECTOR_CONSTRAINTS
BS_EDGE_CONNECTOR_BEVELLED // Some connector in board, and the connector must be bevelled
};
/**
* A helper class to manage a dielectric parameters
*/
class DIELECTRIC_PRMS
{
friend class BOARD_STACKUP_ITEM;
private:
int m_DielectricLayerId;/// the "layer" id for dielectric layers,
/// from 1 (top) to 31 (bottom)
wxString m_Material; /// type of material (for dielectric and solder mask)
int m_Thickness; /// the physical layer thickness in internal units
bool m_ThicknessLocked; /// true for dielectric layers with a fixed thickness
/// (for impendace controled purposes), unused for other layers
double m_EpsilonR; /// For dielectric (and solder mask) the dielectric constant
double m_LossTangent; /// For dielectric (and solder mask) the dielectric loss
public:
DIELECTRIC_PRMS() :
m_DielectricLayerId(-1),
m_Thickness(0), m_ThicknessLocked( false ),
m_EpsilonR( 1.0 ), m_LossTangent( 0.0 )
{}
};
/**
* this class manage one layer needed to make a physical board
* it can be a solder mask, silk screen, copper or a dielectric
@ -66,24 +93,25 @@ public:
BOARD_STACKUP_ITEM( BOARD_STACKUP_ITEM_TYPE aType );
BOARD_STACKUP_ITEM( BOARD_STACKUP_ITEM& aOther );
private:
BOARD_STACKUP_ITEM_TYPE m_Type;
bool m_Enabled; /// true if this stackup item must be taken in account,
/// 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 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
int m_Thickness; /// the physical layer thickness in internal units
bool m_ThicknessLocked; /// true for dielectric layers with a fixed thickness
/// (for impendace controled purposes), unused for other layers
double m_EpsilonR; /// For dielectric (and solder mask) the dielectric constant
double m_LossTangent; /// For dielectric (and solder mask) the dielectric loss
PCB_LAYER_ID m_LayerId; /// the layer id (F.Cu to B.Cu, F.Silk, B.silk, F.Mask, B.Mask)
/// and UNDEFINED_LAYER (-1) for dielectic layers that are not
/// really layers for the board editor
/// List of dielectric parameters
/// usually only one item, but in complex (microwave) boards, one can have
/// more than one dielectic layer between 2 copper layers, and therfore
/// more than one item in list
std::vector<DIELECTRIC_PRMS> m_DielectricPrmsList;
bool m_enabled; /// true if this stackup item must be taken in account,
/// false to ignore it. Mainly used in dialog stackup editor.
public:
/// @return true if the layer has a meaningfull Epsilon R parameter
/// namely dielectric layers: dielectric and solder mask
bool HasEpsilonRValue();
@ -115,6 +143,39 @@ public:
/// @return a wxString to print/display Loss Tangent
wxString FormatLossTangent();
/// @return a wxString to print/display a dielectric name
wxString FormatDielectricLayerName();
// Getters:
bool IsEnabled() {return m_enabled; }
BOARD_STACKUP_ITEM_TYPE GetType() { return m_Type; }
PCB_LAYER_ID GetBrdLayerId() { return m_LayerId; }
wxString GetColor(){ return m_Color; }
wxString GetLayerName() { return m_LayerName; }
wxString GetTypeName() { return m_TypeName; }
int GetThickness( int aDielectricSubLayer = 0 );
bool IsThicknessLocked( int aDielectricSubLayer = 0 );
double GetEpsilonR( int aDielectricSubLayer = 0 );
double GetLossTangent( int aDielectricSubLayer = 0 );
int GetDielectricLayerId( int aDielectricSubLayer = 0 );
wxString GetMaterial( int aDielectricSubLayer = 0 );
// Setters:
void SetEnabled( bool aEnable) { m_enabled = aEnable; }
void SetBrdLayerId( PCB_LAYER_ID aBrdLayerId ) { m_LayerId = aBrdLayerId; }
void SetColor( const wxString& aColorName ){ m_Color = aColorName; }
void SetLayerName( const wxString& aName ) { m_LayerName = aName; }
void SetTypeName( const wxString& aName ) { m_TypeName = aName; }
void SetThickness( int aThickness, int aDielectricSubLayer = 0 );
void SetThicknessLocked( bool aLocked, int aDielectricSubLayer = 0 );
void SetEpsilonR( double aEpsilon, int aDielectricSubLayer = 0 );
void SetLossTangent( double aTg, int aDielectricSubLayer = 0 );
void SetDielectricLayerId( int aLayerId, int aDielectricSubLayer = 0 );
void SetMaterial( const wxString& aName, int aDielectricSubLayer = 0 );
};

View File

@ -102,6 +102,10 @@ PANEL_SETUP_BOARD_STACKUP::PANEL_SETUP_BOARD_STACKUP( PAGED_DIALOG* aParent, PCB
buildLayerStackPanel();
synchronizeWithBoard( true );
// Currently: disable not yet usable buttons:
m_buttonAddDielectricLayer->Hide();
m_buttonRemoveDielectricLayer->Hide();
}
@ -140,6 +144,98 @@ void PANEL_SETUP_BOARD_STACKUP::disconnectEvents()
}
void PANEL_SETUP_BOARD_STACKUP::onAddDielectricLayer( wxCommandEvent& event )
{
// Build Dielectric layers list:
wxArrayString d_list;
for( BOARD_STACKUP_ROW_UI_ITEM& item : m_rowUiItemsList )
{
if( !item.m_isEnabled )
continue;
if( item.m_Item->GetType() == BS_ITEM_TYPE_DIELECTRIC )
d_list.Add( item.m_LayerName->GetLabel() );
}
// Show list
int index = wxGetSingleChoiceIndex( wxEmptyString, _("Dielectric Layers List"),
d_list);
if( index < 0 )
return;
}
void PANEL_SETUP_BOARD_STACKUP::onRemoveDielectricLayer( wxCommandEvent& event )
{
// Build deletable Dielectric layers list.
// A lyer can be deleted if there are 2 (or more) dielectric layers
// between 2 copper layers
wxArrayString d_list;
wxString previousD_Layer;
int dielectric_layer_count = 0;
for( auto item : m_stackup.GetList() )
{
if( !item->IsEnabled() )
continue;
if( item->GetType() == BS_ITEM_TYPE_COPPER )
dielectric_layer_count = 0;
else if( item->GetType() == BS_ITEM_TYPE_DIELECTRIC )
{
dielectric_layer_count++;
if( dielectric_layer_count == 1 )
previousD_Layer = item->FormatDielectricLayerName();
if( dielectric_layer_count == 2 )
d_list.Add( previousD_Layer );
if( dielectric_layer_count >= 2 )
d_list.Add( item->FormatDielectricLayerName() );
}
}
// Show list
int index = wxGetSingleChoiceIndex( wxEmptyString, _("Dielectric Layers List"),
d_list);
if( index < 0 )
return;
}
void PANEL_SETUP_BOARD_STACKUP::onRemoveDielUI( wxUpdateUIEvent& event )
{
// The m_buttonRemoveDielectricLayer wxButton is enabled only if a dielectric
// layer can be removed, i.e. if 2 (or more) dielectric layers are found
// between 3 copper layers
int dielectric_layer_count = 0;
for( auto item : m_stackup.GetList() )
{
if( !item->IsEnabled() )
continue;
if( item->GetType() == BS_ITEM_TYPE_COPPER )
dielectric_layer_count = 0;
if( item->GetType() == BS_ITEM_TYPE_DIELECTRIC )
dielectric_layer_count++;
if( dielectric_layer_count >= 2 )
{
m_buttonRemoveDielectricLayer->Enable( true );
return;
}
}
m_buttonRemoveDielectricLayer->Enable( false );
}
void PANEL_SETUP_BOARD_STACKUP::onExportToClipboard( wxCommandEvent& event )
{
if( !transferDataFromUIToStackup() )
@ -178,8 +274,8 @@ void PANEL_SETUP_BOARD_STACKUP::onUpdateThicknessValue( wxUpdateUIEvent& event )
for( auto item : m_stackup.GetList() )
{
if( item->IsThicknessEditable() && item->m_Enabled )
thickness += item->m_Thickness;
if( item->IsThicknessEditable() && item->IsEnabled() )
thickness += item->GetThickness();
}
m_tcCTValue->SetValue( StringFromValue( m_units, thickness, true, true ) );
@ -239,16 +335,16 @@ void PANEL_SETUP_BOARD_STACKUP::synchronizeWithBoard( bool aFullSync )
// test for existing stackup items in board:
for( BOARD_STACKUP_ITEM* brd_item : brd_stackup.GetList() )
{
if( item->m_Type == BS_ITEM_TYPE_DIELECTRIC )
if( item->GetType() == BS_ITEM_TYPE_DIELECTRIC )
{
// Compare only BS_ITEM_TYPE_DIELECTRIC items
if( brd_item->m_Type != BS_ITEM_TYPE_DIELECTRIC )
if( brd_item->GetType() != BS_ITEM_TYPE_DIELECTRIC )
continue;
if( item->m_DielectricLayerId == brd_item->m_DielectricLayerId )
if( item->GetDielectricLayerId() == brd_item->GetDielectricLayerId() )
brd_stack_item = brd_item;
}
else if( item->m_LayerId == brd_item->m_LayerId )
else if( item->GetBrdLayerId() == brd_item->GetBrdLayerId() )
brd_stack_item = brd_item;
if( brd_stack_item )
@ -267,8 +363,8 @@ void PANEL_SETUP_BOARD_STACKUP::synchronizeWithBoard( bool aFullSync )
if( matName )
{
if( IsPrmSpecified( item->m_Material ) )
matName->SetValue( item->m_Material );
if( IsPrmSpecified( item->GetMaterial() ) )
matName->SetValue( item->GetMaterial() );
else
matName->SetValue( wxGetTranslation( NotSpecifiedPrm() ) );
}
@ -279,14 +375,14 @@ void PANEL_SETUP_BOARD_STACKUP::synchronizeWithBoard( bool aFullSync )
wxTextCtrl* textCtrl = dynamic_cast<wxTextCtrl*>( ui_row_item.m_ThicknessCtrl );
if( textCtrl )
textCtrl->SetValue( StringFromValue( m_units, item->m_Thickness, true, true ) );
textCtrl->SetValue( StringFromValue( m_units, item->GetThickness(), true, true ) );
if( item->m_Type == BS_ITEM_TYPE_DIELECTRIC )
if( item->GetType() == BS_ITEM_TYPE_DIELECTRIC )
{
wxCheckBox* cb_box = dynamic_cast<wxCheckBox*> ( ui_row_item.m_ThicknessLockCtrl );
if( cb_box )
cb_box->SetValue( item->m_ThicknessLocked );
cb_box->SetValue( item->IsThicknessLocked() );
}
}
@ -295,9 +391,9 @@ void PANEL_SETUP_BOARD_STACKUP::synchronizeWithBoard( bool aFullSync )
auto bm_combo = dynamic_cast<wxBitmapComboBox*>( ui_row_item.m_ColorCtrl );
int color_idx = 0;
if( item->m_Color.StartsWith( "#" ) ) // User defined color
if( item->GetColor().StartsWith( "#" ) ) // User defined color
{
wxColour color( item->m_Color );
wxColour color( item->GetColor() );
m_UserColors[row] = color;
color_idx = GetColorUserDefinedListIdx();
@ -315,7 +411,7 @@ void PANEL_SETUP_BOARD_STACKUP::synchronizeWithBoard( bool aFullSync )
for( int ii = 0; ii < GetColorStandardListCount(); ii++ )
{
if( color_list[ii].m_ColorName == item->m_Color )
if( color_list[ii].m_ColorName == item->GetColor() )
{
color_idx = ii;
break;
@ -330,7 +426,7 @@ void PANEL_SETUP_BOARD_STACKUP::synchronizeWithBoard( bool aFullSync )
if( item->HasEpsilonRValue() )
{
wxString txt;
txt.Printf( "%.1f", item->m_EpsilonR );
txt.Printf( "%.1f", item->GetEpsilonR() );
wxTextCtrl* textCtrl = dynamic_cast<wxTextCtrl*>( ui_row_item.m_EpsilonCtrl );
if( textCtrl )
@ -340,7 +436,7 @@ void PANEL_SETUP_BOARD_STACKUP::synchronizeWithBoard( bool aFullSync )
if( item->HasLossTangentValue() )
{
wxString txt;
txt.Printf( "%g", item->m_LossTangent );
txt.Printf( "%g", item->GetLossTangent() );
wxTextCtrl* textCtrl = dynamic_cast<wxTextCtrl*>( ui_row_item.m_LossTgCtrl );
if( textCtrl )
@ -351,13 +447,13 @@ void PANEL_SETUP_BOARD_STACKUP::synchronizeWithBoard( bool aFullSync )
// Now enable/disable stackup items, according to the m_enabledLayers config
bool show_item;
if( item->m_Type == BS_ITEM_TYPE_DIELECTRIC )
if( item->GetType() == BS_ITEM_TYPE_DIELECTRIC )
// the m_DielectricLayerId is not a copper layer id, it is a dielectric idx from 1
show_item = item->m_DielectricLayerId < copperLayersCount;
show_item = item->GetDielectricLayerId() < copperLayersCount;
else
show_item = m_enabledLayers[item->m_LayerId];
show_item = m_enabledLayers[item->GetBrdLayerId()];
item->m_Enabled = show_item;
item->SetEnabled( show_item );
ui_row_item.m_isEnabled = show_item;
@ -440,9 +536,9 @@ void PANEL_SETUP_BOARD_STACKUP::buildLayerStackPanel()
const FAB_LAYER_COLOR* color_list = GetColorStandardList();
for( auto item : m_stackup.GetList() )
for( BOARD_STACKUP_ITEM* item : m_stackup.GetList() )
{
BOARD_STACKUP_ROW_UI_ITEM ui_row_item;
BOARD_STACKUP_ROW_UI_ITEM ui_row_item( item );
bool show_item = true;//false;
ui_row_item.m_isEnabled = true;
@ -456,35 +552,34 @@ void PANEL_SETUP_BOARD_STACKUP::buildLayerStackPanel()
m_fgGridSizer->Add( bitmap, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT );
ui_row_item.m_Icon = bitmap;
if( item->m_Type == BS_ITEM_TYPE_DIELECTRIC )
if( item->GetType() == BS_ITEM_TYPE_DIELECTRIC )
{
wxString lname;
lname.Printf( _( "Dielectric %d" ), item->m_DielectricLayerId );
wxString lname = item->FormatDielectricLayerName();
wxStaticText* st_text = new wxStaticText( m_scGridWin, wxID_ANY, lname );
m_fgGridSizer->Add( st_text, 0, wxRIGHT|wxALIGN_CENTER_VERTICAL, 2 );
ui_row_item.m_LayerName = st_text;
wxChoice* choice = new wxChoice( m_scGridWin, wxID_ANY, wxDefaultPosition,
wxDefaultSize, m_core_prepreg_choice );
choice->SetSelection( item->m_TypeName == KEY_CORE ? 0 : 1 );
choice->SetSelection( item->GetTypeName() == KEY_CORE ? 0 : 1 );
m_fgGridSizer->Add( choice, 0, wxEXPAND|wxLEFT|wxRIGHT|wxALIGN_CENTER_VERTICAL, 2 );
ui_row_item.m_LayerTypeCtrl = choice;
}
else
{
item->m_LayerName = m_board->GetLayerName( item->m_LayerId );
wxStaticText* st_text = new wxStaticText( m_scGridWin, wxID_ANY, item->m_LayerName );
item->GetLayerName() = m_board->GetLayerName( item->GetBrdLayerId() );
wxStaticText* st_text = new wxStaticText( m_scGridWin, wxID_ANY, item->GetLayerName() );
m_fgGridSizer->Add( st_text, 0, wxALL|wxALIGN_CENTER_VERTICAL, 1 );
st_text->Show( show_item );
ui_row_item.m_LayerName = st_text;
wxString lname;
if( item->m_TypeName == KEY_COPPER )
if( item->GetTypeName() == KEY_COPPER )
lname = _( "Copper" );
else
lname = wxGetTranslation( item->m_TypeName );
lname = wxGetTranslation( item->GetTypeName() );
st_text = new wxStaticText( m_scGridWin, wxID_ANY, lname );
m_fgGridSizer->Add( st_text, 0, wxLEFT|wxRIGHT|wxALIGN_CENTER_VERTICAL, 2 );
@ -493,7 +588,8 @@ void PANEL_SETUP_BOARD_STACKUP::buildLayerStackPanel()
if( item->IsMaterialEditable() )
{
addMaterialChooser( ID_ITEM_MATERIAL+row, &item->m_Material, ui_row_item );
wxString matName = item->GetMaterial();
addMaterialChooser( ID_ITEM_MATERIAL+row, &matName, ui_row_item );
}
else
{
@ -504,7 +600,7 @@ void PANEL_SETUP_BOARD_STACKUP::buildLayerStackPanel()
{
wxTextCtrl* textCtrl = new wxTextCtrl( m_scGridWin, ID_ITEM_THICKNESS+row );
textCtrl->SetMinSize( m_numericTextCtrlSize );
textCtrl->SetValue( StringFromValue( m_units, item->m_Thickness, true, true ) );
textCtrl->SetValue( StringFromValue( m_units, item->GetThickness(), true, true ) );
m_fgGridSizer->Add( textCtrl, 0, wxLEFT|wxRIGHT|wxALIGN_CENTER_VERTICAL, 2 );
m_controlItemsList.push_back( textCtrl );
textCtrl->Connect( wxEVT_COMMAND_TEXT_UPDATED,
@ -512,11 +608,11 @@ void PANEL_SETUP_BOARD_STACKUP::buildLayerStackPanel()
NULL, this );
ui_row_item.m_ThicknessCtrl = textCtrl;
if( item->m_Type == BS_ITEM_TYPE_DIELECTRIC )
if( item->GetType() == BS_ITEM_TYPE_DIELECTRIC )
{
wxCheckBox* cb_box = new wxCheckBox( m_scGridWin, ID_ITEM_THICKNESS_LOCKED+row,
wxEmptyString );
cb_box->SetValue( item->m_ThicknessLocked );
cb_box->SetValue( item->IsThicknessLocked() );
m_fgGridSizer->Add( cb_box, 0, wxALIGN_CENTER_VERTICAL, 2 );
ui_row_item.m_ThicknessLockCtrl = cb_box;
}
@ -535,9 +631,9 @@ void PANEL_SETUP_BOARD_STACKUP::buildLayerStackPanel()
{
int color_idx = 0;
if( item->m_Color.StartsWith( "#" ) ) // User defined color
if( item->GetColor().StartsWith( "#" ) ) // User defined color
{
wxColour color( item->m_Color );
wxColour color( item->GetColor() );
m_UserColors[row] = color;
color_idx = GetColorUserDefinedListIdx();
}
@ -545,7 +641,7 @@ void PANEL_SETUP_BOARD_STACKUP::buildLayerStackPanel()
{
for( int ii = 0; ii < GetColorStandardListCount(); ii++ )
{
if( color_list[ii].m_ColorName == item->m_Color )
if( color_list[ii].m_ColorName == item->GetColor() )
{
color_idx = ii;
break;
@ -568,7 +664,7 @@ void PANEL_SETUP_BOARD_STACKUP::buildLayerStackPanel()
if( item->HasEpsilonRValue() )
{
wxString txt;
txt.Printf( "%.1f", item->m_EpsilonR );
txt.Printf( "%.1f", item->GetEpsilonR() );
wxTextCtrl* textCtrl = new wxTextCtrl( m_scGridWin, wxID_ANY, wxEmptyString,
wxDefaultPosition, m_numericFieldsSize );
textCtrl->SetValue( txt );
@ -583,7 +679,7 @@ void PANEL_SETUP_BOARD_STACKUP::buildLayerStackPanel()
if( item->HasLossTangentValue() )
{
wxString txt;
txt.Printf( "%g", item->m_LossTangent );
txt.Printf( "%g", item->GetLossTangent() );
wxTextCtrl* textCtrl = new wxTextCtrl( m_scGridWin, wxID_ANY, wxEmptyString,
wxDefaultPosition, m_numericFieldsSize );
textCtrl->SetValue( txt );
@ -635,11 +731,11 @@ bool PANEL_SETUP_BOARD_STACKUP::transferDataFromUIToStackup()
for( auto item : m_stackup.GetList() )
{
if( item->IsThicknessEditable() && item->m_Enabled )
if( item->IsThicknessEditable() && item->IsEnabled() )
{
stackup_thickness += item->m_Thickness;
stackup_thickness += item->GetThickness();
if( item->m_Thickness < 0 )
if( item->GetThickness() < 0 )
thickness_error = true;
}
}
@ -680,13 +776,13 @@ bool PANEL_SETUP_BOARD_STACKUP::transferDataFromUIToStackup()
for( auto item : m_stackup.GetList() )
{
// Skip stackup items useless for the current board
if( !item->m_Enabled )
if( !item->IsEnabled() )
{
row++;
continue;
}
item->m_LayerName = m_rowUiItemsList[row].m_LayerName->GetLabel();
item->SetLayerName( m_rowUiItemsList[row].m_LayerName->GetLabel() );
if( item->HasEpsilonRValue() )
{
@ -694,9 +790,9 @@ bool PANEL_SETUP_BOARD_STACKUP::transferDataFromUIToStackup()
txt = textCtrl->GetValue();
if( txt.ToDouble( &value ) && value >= 0.0 )
item->m_EpsilonR = value;
item->SetEpsilonR( value );
else if( txt.ToCDouble( &value ) && value >= 0.0 )
item->m_EpsilonR = value;
item->SetEpsilonR( value );
else
{
success = false;
@ -710,9 +806,9 @@ bool PANEL_SETUP_BOARD_STACKUP::transferDataFromUIToStackup()
txt = textCtrl->GetValue();
if( txt.ToDouble( &value ) && value >= 0.0 )
item->m_LossTangent = value;
item->SetLossTangent( value );
else if( txt.ToCDouble( &value ) && value >= 0.0 )
item->m_LossTangent = value;
item->SetLossTangent( value );
else
{
success = false;
@ -725,15 +821,15 @@ bool PANEL_SETUP_BOARD_STACKUP::transferDataFromUIToStackup()
if( item->IsMaterialEditable() )
{
wxTextCtrl* textCtrl = static_cast<wxTextCtrl*>( m_rowUiItemsList[row].m_MaterialCtrl );
item->m_Material = textCtrl->GetValue();
item->SetMaterial( textCtrl->GetValue() );
// Ensure the not specified mat name is the keyword, not its translation
// to avoid any issue is the language setting changes
if( !IsPrmSpecified( item->m_Material ) )
item->m_Material = NotSpecifiedPrm();
if( !IsPrmSpecified( item->GetMaterial() ) )
item->SetMaterial( NotSpecifiedPrm() );
}
if( item->m_Type == BS_ITEM_TYPE_DIELECTRIC )
if( item->GetType() == BS_ITEM_TYPE_DIELECTRIC )
{
// Choice is Core or Prepreg:
wxChoice* choice = static_cast<wxChoice*>( m_rowUiItemsList[row].m_LayerTypeCtrl );
@ -741,9 +837,9 @@ bool PANEL_SETUP_BOARD_STACKUP::transferDataFromUIToStackup()
int idx = choice->GetSelection();
if( idx == 0 )
item->m_TypeName = KEY_CORE;
item->SetTypeName( KEY_CORE );
else
item->m_TypeName = KEY_PREPREG;
item->SetTypeName( KEY_PREPREG );
}
if( item->IsThicknessEditable() )
@ -751,14 +847,14 @@ bool PANEL_SETUP_BOARD_STACKUP::transferDataFromUIToStackup()
wxTextCtrl* textCtrl = static_cast<wxTextCtrl*>( m_rowUiItemsList[row].m_ThicknessCtrl );
txt = textCtrl->GetValue();
item->m_Thickness = ValueFromString( m_frame->GetUserUnits(), txt, true );
item->SetThickness( ValueFromString( m_frame->GetUserUnits(), txt, true ) );
if( item->m_Type == BS_ITEM_TYPE_DIELECTRIC )
if( item->GetType() == BS_ITEM_TYPE_DIELECTRIC )
{
// Dielectric thickness layer can have a locked thickness:
wxCheckBox* cb_box = static_cast<wxCheckBox*>
( m_rowUiItemsList[row].m_ThicknessLockCtrl );
item->m_ThicknessLocked = cb_box && cb_box->GetValue();
item->SetThicknessLocked( cb_box && cb_box->GetValue() );
}
}
@ -770,9 +866,9 @@ bool PANEL_SETUP_BOARD_STACKUP::transferDataFromUIToStackup()
int idx = choice->GetSelection();
if( idx == GetColorUserDefinedListIdx() )
item->m_Color = m_UserColors[row].GetAsString( wxC2S_HTML_SYNTAX );
item->SetColor( m_UserColors[row].GetAsString( wxC2S_HTML_SYNTAX ) );
else
item->m_Color = color_list[idx].m_ColorName;
item->SetColor( color_list[idx].m_ColorName );
}
row++;
}
@ -813,7 +909,7 @@ bool PANEL_SETUP_BOARD_STACKUP::TransferDataFromWindow()
for( auto item : m_stackup.GetList() )
{
if( item->m_Enabled )
if( item->IsEnabled() )
brd_stackup.Add( new BOARD_STACKUP_ITEM( *item ) );
}
@ -872,13 +968,13 @@ void PANEL_SETUP_BOARD_STACKUP::onCalculateDielectricThickness( wxCommandEvent&
int row = 0;
for( auto item : m_stackup.GetList() )
{
if( !item->IsThicknessEditable() || !item->m_Enabled )
if( !item->IsThicknessEditable() || !item->IsEnabled() )
{
row++;
continue;
}
if( item->m_Type == BS_ITEM_TYPE_DIELECTRIC )
if( item->GetType() == BS_ITEM_TYPE_DIELECTRIC )
{
wxCheckBox* checkBox = static_cast<wxCheckBox*>( m_rowUiItemsList[row].m_ThicknessLockCtrl );
@ -891,12 +987,12 @@ void PANEL_SETUP_BOARD_STACKUP::onCalculateDielectricThickness( wxCommandEvent&
{
fixed_thickness_cnt++;
if( item->m_Thickness < 0 )
if( item->GetThickness() < 0 )
thickness_error = true;
}
}
thickness += item->m_Thickness;
thickness += item->GetThickness();
row++;
}
@ -936,15 +1032,15 @@ void PANEL_SETUP_BOARD_STACKUP::onCalculateDielectricThickness( wxCommandEvent&
row = 0;
for( auto item : m_stackup.GetList() )
{
if( item->m_Type == BS_ITEM_TYPE_DIELECTRIC && item->m_Enabled )
if( item->GetType() == BS_ITEM_TYPE_DIELECTRIC && item->IsEnabled() )
{
wxCheckBox* checkBox = static_cast<wxCheckBox*>( m_rowUiItemsList[row].m_ThicknessLockCtrl );
if( !checkBox->GetValue() ) // Not locked thickness: can be modified
{
item->m_Thickness = dielectric_thickness;
item->SetThickness( dielectric_thickness );
wxTextCtrl* textCtrl = static_cast<wxTextCtrl*>( m_rowUiItemsList[row].m_ThicknessCtrl );
textCtrl->SetValue( StringFromValue( m_units, item->m_Thickness, true, true ) );
textCtrl->SetValue( StringFromValue( m_units, item->GetThickness(), true, true ) );
}
}
@ -995,27 +1091,27 @@ void PANEL_SETUP_BOARD_STACKUP::onMaterialChange( wxCommandEvent& event )
{
DIELECTRIC_SUBSTRATE_LIST* mat_list = nullptr;
if( item->m_Type == BS_ITEM_TYPE_DIELECTRIC )
if( item->GetType() == BS_ITEM_TYPE_DIELECTRIC )
mat_list = &m_delectricMatList;
else if( item->m_Type == BS_ITEM_TYPE_SOLDERMASK )
else if( item->GetType() == BS_ITEM_TYPE_SOLDERMASK )
mat_list = &m_solderMaskMatList;
else if( item->m_Type == BS_ITEM_TYPE_SILKSCREEN )
else if( item->GetType() == BS_ITEM_TYPE_SILKSCREEN )
mat_list = &m_silkscreenMatList;
else
continue;
int idx = mat_list->FindSubstrate( item->m_Material,
item->m_EpsilonR,
item->m_LossTangent );
int idx = mat_list->FindSubstrate( item->GetMaterial(),
item->GetEpsilonR(),
item->GetLossTangent() );
if( idx < 0 && !item->m_Material.IsEmpty() )
if( idx < 0 && !item->GetMaterial().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;
new_mat.m_Name = item->GetMaterial();
new_mat.m_EpsilonR = item->GetEpsilonR();
new_mat.m_LossTangent = item->GetLossTangent();
mat_list->AppendSubstrate( new_mat );
}
}
@ -1024,7 +1120,7 @@ void PANEL_SETUP_BOARD_STACKUP::onMaterialChange( wxCommandEvent& event )
BOARD_STACKUP_ITEM* item = GetStackupItem( row );
DIELECTRIC_SUBSTRATE_LIST* item_mat_list = nullptr;
switch( item->m_Type )
switch( item->GetType() )
{
case BS_ITEM_TYPE_DIELECTRIC:
item_mat_list = &m_delectricMatList;
@ -1054,13 +1150,13 @@ void PANEL_SETUP_BOARD_STACKUP::onMaterialChange( wxCommandEvent& event )
return;
// Update Name, Epsilon R and Loss tg
item->m_Material = substrate.m_Name;
item->m_EpsilonR = substrate.m_EpsilonR;
item->m_LossTangent = substrate.m_LossTangent;
item->SetMaterial( substrate.m_Name );
item->SetEpsilonR( substrate.m_EpsilonR );
item->SetLossTangent( substrate.m_LossTangent );
wxTextCtrl* textCtrl;
textCtrl = static_cast<wxTextCtrl*>( m_rowUiItemsList[row].m_MaterialCtrl );
textCtrl->SetValue( item->m_Material );
textCtrl->SetValue( item->GetMaterial() );
// some layers have a material choice but not EpsilonR ctrl
if( item->HasEpsilonRValue() )
@ -1088,7 +1184,7 @@ void PANEL_SETUP_BOARD_STACKUP::onThicknessChange( wxCommandEvent& event )
wxString value = event.GetString();
BOARD_STACKUP_ITEM* item = GetStackupItem( row );
item->m_Thickness = ValueFromString( m_frame->GetUserUnits(), value, true );
item->SetThickness( ValueFromString( m_frame->GetUserUnits(), value, true ) );
}
@ -1103,7 +1199,7 @@ wxColor PANEL_SETUP_BOARD_STACKUP::getColorIconItem( int aRow )
BOARD_STACKUP_ITEM* layer = GetStackupItem( aRow );
wxColor color;
switch( layer->m_Type )
switch( layer->GetType() )
{
case BS_ITEM_TYPE_COPPER:
color = copperColor;
@ -1176,10 +1272,10 @@ wxBitmapComboBox* PANEL_SETUP_BOARD_STACKUP::createBmComboBox( BOARD_STACKUP_ITE
label = wxGetTranslation( item.m_ColorName );
else // Append the user color, if specified, else add a default user color
{
if( aStackupItem && aStackupItem->m_Color.StartsWith( "#" ) )
if( aStackupItem && aStackupItem->GetColor().StartsWith( "#" ) )
{
curr_color = wxColour( aStackupItem->m_Color );
label = aStackupItem->m_Color;
curr_color = wxColour( aStackupItem->GetColor() );
label = aStackupItem->GetColor();
}
else
label = curr_color.GetAsString( wxC2S_HTML_SYNTAX );

View File

@ -48,6 +48,7 @@ class PANEL_SETUP_LAYERS;
// row by row
struct BOARD_STACKUP_ROW_UI_ITEM
{
BOARD_STACKUP_ITEM* m_Item; // The BOARD_STACKUP_ITEM managed by this BOARD_STACKUP_ROW_UI_ITEM
bool m_isEnabled; // True if the row is in board
// false if not (this row is not shown on the panel)
wxStaticBitmap* m_Icon; // Color icon in first column (column 1)
@ -61,7 +62,8 @@ struct BOARD_STACKUP_ROW_UI_ITEM
wxControl* m_EpsilonCtrl; // control shown in column 8
wxControl* m_LossTgCtrl; // control shown in column 9
BOARD_STACKUP_ROW_UI_ITEM() :
BOARD_STACKUP_ROW_UI_ITEM( BOARD_STACKUP_ITEM* aItem ) :
m_Item( aItem ),
m_isEnabled( true ), m_Icon( nullptr ), m_LayerName( nullptr ),
m_LayerTypeCtrl( nullptr ),
m_MaterialCtrl( nullptr ),m_MaterialButt( nullptr ),
@ -141,13 +143,16 @@ private:
*/
bool transferDataFromUIToStackup();
void onUpdateThicknessValue( wxUpdateUIEvent& event ) override;
void onCalculateDielectricThickness( wxCommandEvent& event ) override;
void onUpdateThicknessValue( wxUpdateUIEvent& event ) override;
void onCalculateDielectricThickness( wxCommandEvent& event ) override;
void onColorSelected( wxCommandEvent& event );
void onMaterialChange( wxCommandEvent& event );
void onThicknessChange( wxCommandEvent& event );
void onExportToClipboard( wxCommandEvent& event ) override;
void onMaterialChange( wxCommandEvent& event );
void onThicknessChange( wxCommandEvent& event );
void onExportToClipboard( wxCommandEvent& event ) override;
void onAddDielectricLayer( wxCommandEvent& event ) override;
void onRemoveDielectricLayer( wxCommandEvent& event ) override;
void onRemoveDielUI( wxUpdateUIEvent& event ) override;
/** Update the icons color (swatches in first grid column)
* @param aRow is the row (index in m_rowUiItemsList) that manages the icon to update.

View File

@ -130,11 +130,20 @@ PANEL_SETUP_BOARD_STACKUP_BASE::PANEL_SETUP_BOARD_STACKUP_BASE( wxWindow* parent
bSizerRight->Add( m_rbDielectricConstraint, 0, wxEXPAND|wxTOP|wxBOTTOM|wxRIGHT, 5 );
m_buttonAddDielectricLayer = new wxButton( this, wxID_ANY, _("Add Dielectric Layer"), wxDefaultPosition, wxDefaultSize, 0 );
bSizerRight->Add( m_buttonAddDielectricLayer, 0, wxEXPAND|wxTOP|wxBOTTOM|wxRIGHT, 5 );
m_buttonRemoveDielectricLayer = new wxButton( this, wxID_ANY, _("Remove Dielectric Layer"), wxDefaultPosition, wxDefaultSize, 0 );
bSizerRight->Add( m_buttonRemoveDielectricLayer, 0, wxTOP|wxBOTTOM|wxRIGHT|wxEXPAND, 5 );
m_staticline2 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
bSizerRight->Add( m_staticline2, 0, wxEXPAND|wxTOP|wxBOTTOM|wxRIGHT, 5 );
wxStaticBoxSizer* sbSizerBrdOptions;
sbSizerBrdOptions = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Board Finish") ), wxVERTICAL );
m_cbCastellatedPads = new wxCheckBox( sbSizerBrdOptions->GetStaticBox(), wxID_ANY, _("Has castellated pads"), wxDefaultPosition, wxDefaultSize, 0 );
sbSizerBrdOptions->Add( m_cbCastellatedPads, 0, wxBOTTOM, 5 );
sbSizerBrdOptions->Add( m_cbCastellatedPads, 0, wxTOP|wxBOTTOM, 5 );
m_cbEgdesPlated = new wxCheckBox( sbSizerBrdOptions->GetStaticBox(), wxID_ANY, _("Plated board edge"), wxDefaultPosition, wxDefaultSize, 0 );
sbSizerBrdOptions->Add( m_cbEgdesPlated, 0, wxBOTTOM, 5 );
@ -161,7 +170,10 @@ PANEL_SETUP_BOARD_STACKUP_BASE::PANEL_SETUP_BOARD_STACKUP_BASE( wxWindow* parent
sbSizerBrdOptions->Add( m_choiceEdgeConn, 0, wxEXPAND|wxTOP|wxBOTTOM, 2 );
bSizerRight->Add( sbSizerBrdOptions, 1, wxEXPAND|wxRIGHT, 5 );
bSizerRight->Add( sbSizerBrdOptions, 0, wxEXPAND|wxTOP|wxRIGHT, 5 );
bSizerRight->Add( 0, 0, 1, wxEXPAND, 5 );
m_buttonExport = new wxButton( this, wxID_ANY, _("Export to Clipboard"), wxDefaultPosition, wxDefaultSize, 0 );
bSizerRight->Add( m_buttonExport, 0, wxEXPAND|wxTOP|wxBOTTOM|wxRIGHT, 5 );
@ -175,11 +187,13 @@ PANEL_SETUP_BOARD_STACKUP_BASE::PANEL_SETUP_BOARD_STACKUP_BASE( wxWindow* parent
this->SetSizer( bMainSizer );
this->Layout();
bMainSizer->Fit( this );
// Connect Events
m_thicknessCtrl->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( PANEL_SETUP_BOARD_STACKUP_BASE::onUpdateThicknessValue ), NULL, this );
m_buttonSetDielectricThickness->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_BOARD_STACKUP_BASE::onCalculateDielectricThickness ), NULL, this );
m_buttonAddDielectricLayer->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_BOARD_STACKUP_BASE::onAddDielectricLayer ), NULL, this );
m_buttonRemoveDielectricLayer->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_BOARD_STACKUP_BASE::onRemoveDielectricLayer ), NULL, this );
m_buttonRemoveDielectricLayer->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( PANEL_SETUP_BOARD_STACKUP_BASE::onRemoveDielUI ), NULL, this );
m_buttonExport->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_BOARD_STACKUP_BASE::onExportToClipboard ), NULL, this );
}
@ -188,6 +202,9 @@ PANEL_SETUP_BOARD_STACKUP_BASE::~PANEL_SETUP_BOARD_STACKUP_BASE()
// Disconnect Events
m_thicknessCtrl->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( PANEL_SETUP_BOARD_STACKUP_BASE::onUpdateThicknessValue ), NULL, this );
m_buttonSetDielectricThickness->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_BOARD_STACKUP_BASE::onCalculateDielectricThickness ), NULL, this );
m_buttonAddDielectricLayer->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_BOARD_STACKUP_BASE::onAddDielectricLayer ), NULL, this );
m_buttonRemoveDielectricLayer->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_BOARD_STACKUP_BASE::onRemoveDielectricLayer ), NULL, this );
m_buttonRemoveDielectricLayer->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( PANEL_SETUP_BOARD_STACKUP_BASE::onRemoveDielUI ), NULL, this );
m_buttonExport->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_BOARD_STACKUP_BASE::onExportToClipboard ), NULL, this );
}

View File

@ -45,7 +45,7 @@
<property name="minimum_size"></property>
<property name="name">PANEL_SETUP_BOARD_STACKUP_BASE</property>
<property name="pos"></property>
<property name="size">-1,-1</property>
<property name="size">670,420</property>
<property name="subclass">; ; forward_declare</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
@ -1184,8 +1184,213 @@
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxRIGHT</property>
<property name="proportion">1</property>
<property name="flag">wxEXPAND|wxTOP|wxBOTTOM|wxRIGHT</property>
<property name="proportion">0</property>
<object class="wxButton" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="bitmap"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="current"></property>
<property name="default">0</property>
<property name="default_pane">0</property>
<property name="disabled"></property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="focus"></property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Add Dielectric Layer</property>
<property name="margins"></property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_buttonAddDielectricLayer</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="position"></property>
<property name="pressed"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnButtonClick">onAddDielectricLayer</event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxTOP|wxBOTTOM|wxRIGHT|wxEXPAND</property>
<property name="proportion">0</property>
<object class="wxButton" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="bitmap"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="current"></property>
<property name="default">0</property>
<property name="default_pane">0</property>
<property name="disabled"></property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="focus"></property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Remove Dielectric Layer</property>
<property name="margins"></property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_buttonRemoveDielectricLayer</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="position"></property>
<property name="pressed"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnButtonClick">onRemoveDielectricLayer</event>
<event name="OnUpdateUI">onRemoveDielUI</event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxTOP|wxBOTTOM|wxRIGHT</property>
<property name="proportion">0</property>
<object class="wxStaticLine" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_staticline2</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style">wxLI_HORIZONTAL</property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxTOP|wxRIGHT</property>
<property name="proportion">0</property>
<object class="wxStaticBoxSizer" expanded="1">
<property name="id">wxID_ANY</property>
<property name="label">Board Finish</property>
@ -1196,7 +1401,7 @@
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxBOTTOM</property>
<property name="flag">wxTOP|wxBOTTOM</property>
<property name="proportion">0</property>
<object class="wxCheckBox" expanded="1">
<property name="BottomDockable">1</property>
@ -1574,6 +1779,16 @@
</object>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">1</property>
<object class="spacer" expanded="1">
<property name="height">0</property>
<property name="permission">protected</property>
<property name="width">0</property>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxTOP|wxBOTTOM|wxRIGHT</property>

View File

@ -61,6 +61,9 @@ class PANEL_SETUP_BOARD_STACKUP_BASE : public wxPanel
wxStaticText* m_staticTextEpsilonR;
wxStaticText* m_staticTextLossTg;
wxRadioBox* m_rbDielectricConstraint;
wxButton* m_buttonAddDielectricLayer;
wxButton* m_buttonRemoveDielectricLayer;
wxStaticLine* m_staticline2;
wxCheckBox* m_cbCastellatedPads;
wxCheckBox* m_cbEgdesPlated;
wxStaticText* m_staticTextFinish;
@ -72,12 +75,15 @@ class PANEL_SETUP_BOARD_STACKUP_BASE : public wxPanel
// Virtual event handlers, overide them in your derived class
virtual void onUpdateThicknessValue( wxUpdateUIEvent& event ) { event.Skip(); }
virtual void onCalculateDielectricThickness( wxCommandEvent& event ) { event.Skip(); }
virtual void onAddDielectricLayer( wxCommandEvent& event ) { event.Skip(); }
virtual void onRemoveDielectricLayer( wxCommandEvent& event ) { event.Skip(); }
virtual void onRemoveDielUI( wxUpdateUIEvent& event ) { event.Skip(); }
virtual void onExportToClipboard( wxCommandEvent& event ) { event.Skip(); }
public:
PANEL_SETUP_BOARD_STACKUP_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL, const wxString& name = wxEmptyString );
PANEL_SETUP_BOARD_STACKUP_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 670,420 ), long style = wxTAB_TRAVERSAL, const wxString& name = wxEmptyString );
~PANEL_SETUP_BOARD_STACKUP_BASE();
};

View File

@ -614,31 +614,31 @@ void GERBER_JOBFILE_WRITER::addJSONMaterialStackup()
for( int ii = 0; ii < brd_stackup.GetCount(); ++ii )
{
BOARD_STACKUP_ITEM* item = brd_stackup.GetStackupLayer( ii );
double thickness = item->m_Thickness*m_conversionUnits; // layer thickness is always in mm
double thickness = item->GetThickness()*m_conversionUnits; // layer thickness is always in mm
wxString layer_type;
std::string layer_name; // for comment
switch( item->m_Type )
switch( item->GetType() )
{
case BS_ITEM_TYPE_COPPER:
layer_type = "Copper";
layer_name = formatStringFromUTF32( m_pcb->GetLayerName( item->m_LayerId ) );
last_copper_layer = item->m_LayerId;
layer_name = formatStringFromUTF32( m_pcb->GetLayerName( item->GetBrdLayerId() ) );
last_copper_layer = item->GetBrdLayerId();
break;
case BS_ITEM_TYPE_SILKSCREEN:
layer_type = "Legend";
layer_name = formatStringFromUTF32( item->m_TypeName );
layer_name = formatStringFromUTF32( item->GetTypeName() );
break;
case BS_ITEM_TYPE_SOLDERMASK:
layer_type = "SolderMask";
layer_name = formatStringFromUTF32( item->m_TypeName );
layer_name = formatStringFromUTF32( item->GetTypeName() );
break;
case BS_ITEM_TYPE_SOLDERPASTE:
layer_type = "SolderPaste";
layer_name = formatStringFromUTF32( item->m_TypeName );
layer_name = formatStringFromUTF32( item->GetTypeName() );
break;
case BS_ITEM_TYPE_DIELECTRIC:
@ -646,7 +646,7 @@ void GERBER_JOBFILE_WRITER::addJSONMaterialStackup()
// The option core or prepreg is not added here, as it creates constraints
// in build process, not necessary wanted.
layer_name = formatStringFromUTF32( wxString::Format( "dielectric layer %d",
item->m_DielectricLayerId ) );
item->GetDielectricLayerId() ) );
break;
default:
@ -658,9 +658,9 @@ void GERBER_JOBFILE_WRITER::addJSONMaterialStackup()
if( item->IsColorEditable() && uptodate )
{
if( IsPrmSpecified( item->m_Color ) )
if( IsPrmSpecified( item->GetColor() ) )
{
wxString colorName = item->m_Color;
wxString colorName = item->GetColor();
if( colorName.StartsWith( "#" ) ) // This is a user defined color.
{
@ -676,11 +676,11 @@ void GERBER_JOBFILE_WRITER::addJSONMaterialStackup()
if( item->IsThicknessEditable() && uptodate )
addJSONObject( wxString::Format( "\"Thickness\": %.3f,\n", thickness ) );
if( item->m_Type == BS_ITEM_TYPE_DIELECTRIC )
if( item->GetType() == BS_ITEM_TYPE_DIELECTRIC )
{
if( item->HasMaterialValue() )
{
addJSONObject( wxString::Format( "\"Material\": \"%s\",\n", item->m_Material ) );
addJSONObject( wxString::Format( "\"Material\": \"%s\",\n", item->GetMaterial() ) );
// These constrains are only written if the board has impedance controlled tracks.
// If the board is not impedance controlled, they are useless.
@ -689,13 +689,15 @@ void GERBER_JOBFILE_WRITER::addJSONMaterialStackup()
{
// 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() ) );
if( item->GetEpsilonR() > 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() ) );
if( item->GetLossTangent() > 0.0 )
addJSONObject( wxString::Format( "\"LossTangent\": %s,\n",
item->FormatLossTangent() ) );
}
}
@ -722,11 +724,11 @@ void GERBER_JOBFILE_WRITER::addJSONMaterialStackup()
addJSONObject( note );
}
else if( item->m_Type == BS_ITEM_TYPE_SOLDERMASK || item->m_Type == BS_ITEM_TYPE_SILKSCREEN )
else if( item->GetType() == BS_ITEM_TYPE_SOLDERMASK || item->GetType() == BS_ITEM_TYPE_SILKSCREEN )
{
if( item->HasMaterialValue() )
{
addJSONObject( wxString::Format( "\"Material\": \"%s\",\n", item->m_Material ) );
addJSONObject( wxString::Format( "\"Material\": \"%s\",\n", item->GetMaterial() ) );
// These constrains are only written if the board has impedance controlled tracks.
// If the board is not impedance controlled, they are useless.
@ -735,13 +737,15 @@ void GERBER_JOBFILE_WRITER::addJSONMaterialStackup()
{
// 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() ) );
if( item->GetEpsilonR() > 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() ) );
if( item->GetLossTangent() > 0.0 )
addJSONObject( wxString::Format( "\"LossTangent\": %s,\n",
item->FormatLossTangent() ) );
}
}

View File

@ -1065,10 +1065,10 @@ void PCB_PARSER::parseBoardStackup()
if( type != BS_ITEM_TYPE_UNDEFINED )
{
item = new BOARD_STACKUP_ITEM( type );
item->m_LayerId = layerId;
item->SetBrdLayerId( layerId );
if( type == BS_ITEM_TYPE_DIELECTRIC )
item->m_DielectricLayerId = dielectric_idx++;
item->SetDielectricLayerId( dielectric_idx++ );
stackup.Add( item );
}
@ -1088,15 +1088,17 @@ void PCB_PARSER::parseBoardStackup()
{
case T_type:
NeedSYMBOL();
item->m_TypeName = FromUTF8();
item->SetTypeName( FromUTF8() );
NeedRIGHT();
break;
case T_thickness:
item->m_Thickness = parseBoardUnits( T_thickness );
item->SetThickness( parseBoardUnits( T_thickness ) );
token = NextTok();
if( token == T_LEFT )
break;
if( token == T_locked )
{
thickness_locked = true;
@ -1106,25 +1108,25 @@ void PCB_PARSER::parseBoardStackup()
case T_material:
NeedSYMBOL();
item->m_Material = FromUTF8();
item->SetMaterial( FromUTF8() );
NeedRIGHT();
break;
case T_epsilon_r:
NextTok();
item->m_EpsilonR = parseDouble();
item->SetEpsilonR( parseDouble() );
NeedRIGHT();
break;
case T_loss_tangent:
NextTok();
item->m_LossTangent = parseDouble();
item->SetLossTangent( parseDouble() );
NeedRIGHT();
break;
case T_color:
NeedSYMBOL();
item->m_Color = FromUTF8();
item->SetColor( FromUTF8() );
NeedRIGHT();
break;
@ -1138,7 +1140,7 @@ void PCB_PARSER::parseBoardStackup()
}
if( type == BS_ITEM_TYPE_DIELECTRIC && thickness_locked )
item->m_ThicknessLocked = true;
item->SetThicknessLocked( true );
}
if( token != T_RIGHT )