ADDED: Independent control of front/back via tenting

This commit is contained in:
Jon Evans 2024-06-09 18:28:19 -04:00
parent 4aab9f59aa
commit 5fc0f1f51e
24 changed files with 2273 additions and 1670 deletions

View File

@ -883,7 +883,7 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
{
if( track->Type() == PCB_VIA_T
&& static_cast<const PCB_VIA*>( track )->FlashLayer( layer )
&& !static_cast<const PCB_VIA*>( track )->IsTented() )
&& !static_cast<const PCB_VIA*>( track )->IsTented( layer ) )
{
createViaWithMargin( track, layerContainer, maskExpansion );
}
@ -975,7 +975,7 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
{
if( track->Type() == PCB_VIA_T
&& static_cast<const PCB_VIA*>( track )->FlashLayer( layer )
&& !static_cast<const PCB_VIA*>( track )->IsTented() )
&& !static_cast<const PCB_VIA*>( track )->IsTented( layer ) )
{
track->TransformShapeToPolygon( *layerPoly, layer, maskExpansion, maxError,
ERROR_INSIDE );

View File

@ -726,8 +726,8 @@ public:
double m_SolderPasteMarginRatio; // Solder mask margin ratio value of pad size
// The final margin is the sum of these 2 values
bool m_AllowSoldermaskBridgesInFPs;
bool m_TentVias; // The default tenting option if not overridden on an
// individual via
bool m_TentViasFront; // The default tenting option if not overridden on an
bool m_TentViasBack; // individual via
std::shared_ptr<NET_SETTINGS> m_NetSettings;

View File

@ -163,7 +163,14 @@ public:
return false;
}
virtual bool IsTented() const
/**
* Checks if the given object is tented (its copper shape is covered by solder mask) on a given
* side of the board.
* @param aLayer is the layer to check tenting mode for: F_Cu and F_Mask are treated identically
* as are B_Cu and B_Mask
* @return true if the object is tented on the given side
*/
virtual bool IsTented( PCB_LAYER_ID aLayer ) const
{
return false;
}

View File

@ -210,7 +210,8 @@ BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS( JSON_SETTINGS* aParent, const std:
m_SolderPasteMarginRatio = DEFAULT_SOLDERPASTE_RATIO;
m_AllowSoldermaskBridgesInFPs = false;
m_TentVias = true;
m_TentViasFront = true;
m_TentViasBack = true;
// Layer thickness for 3D viewer
m_boardThickness = pcbIUScale.mmToIU( DEFAULT_BOARD_THICKNESS_MM );
@ -956,7 +957,8 @@ void BOARD_DESIGN_SETTINGS::initFromOther( const BOARD_DESIGN_SETTINGS& aOther )
m_SolderPasteMargin = aOther.m_SolderPasteMargin;
m_SolderPasteMarginRatio = aOther.m_SolderPasteMarginRatio;
m_AllowSoldermaskBridgesInFPs = aOther.m_AllowSoldermaskBridgesInFPs;
m_TentVias = aOther.m_TentVias;
m_TentViasFront = aOther.m_TentViasFront;
m_TentViasBack = aOther.m_TentViasBack;
m_DefaultFPTextItems = aOther.m_DefaultFPTextItems;
std::copy( std::begin( aOther.m_LineThickness ), std::end( aOther.m_LineThickness ),
@ -1045,7 +1047,8 @@ bool BOARD_DESIGN_SETTINGS::operator==( const BOARD_DESIGN_SETTINGS& aOther ) co
if( m_SolderPasteMargin != aOther.m_SolderPasteMargin ) return false;
if( m_SolderPasteMarginRatio != aOther.m_SolderPasteMarginRatio ) return false;
if( m_AllowSoldermaskBridgesInFPs != aOther.m_AllowSoldermaskBridgesInFPs ) return false;
if( m_TentVias != aOther.m_TentVias ) return false;
if( m_TentViasFront != aOther.m_TentViasFront ) return false;
if( m_TentViasBack != aOther.m_TentViasBack ) return false;
if( m_DefaultFPTextItems != aOther.m_DefaultFPTextItems ) return false;
if( !std::equal( std::begin( m_LineThickness ), std::end( m_LineThickness ),

View File

@ -98,6 +98,11 @@ DIALOG_TRACK_VIA_PROPERTIES::DIALOG_TRACK_VIA_PROPERTIES( PCB_BASE_FRAME* aParen
m_ViaEndLayer->SetBoardFrame( aParent );
m_ViaEndLayer->Resync();
m_btnLinkTenting->SetBitmap( KiBitmapBundle( BITMAPS::edit_cmp_symb_links ) );
m_btnLinkTenting->SetValue( true );
m_tentingBackCtrl->Disable();
m_tentingBackLabel->Disable();
bool nets = false;
int net = 0;
bool hasLocked = false;
@ -125,11 +130,13 @@ DIALOG_TRACK_VIA_PROPERTIES::DIALOG_TRACK_VIA_PROPERTIES( PCB_BASE_FRAME* aParen
};
auto getTentingSelection =
[]( const PCB_VIA* via ) -> int
[]( const PCB_VIA* via, PCB_LAYER_ID aLayer ) -> int
{
if( via->Padstack().OuterLayerDefaults().has_solder_mask.has_value() )
std::optional<bool> tentingOverride = via->Padstack().IsTented( aLayer );
if( tentingOverride.has_value() )
{
if( *via->Padstack().OuterLayerDefaults().has_solder_mask )
if( *tentingOverride )
return 1; // Tented
return 2; // Not tented
@ -211,7 +218,17 @@ DIALOG_TRACK_VIA_PROPERTIES::DIALOG_TRACK_VIA_PROPERTIES( PCB_BASE_FRAME* aParen
viaType = v->GetViaType();
m_viaNotFree->SetValue( !v->GetIsFree() );
m_annularRingsCtrl->SetSelection( getAnnularRingSelection( v ) );
m_tentingCtrl->SetSelection( getTentingSelection( v ) );
m_tentingFrontCtrl->SetSelection( getTentingSelection( v, F_Mask ) );
m_tentingBackCtrl->SetSelection( getTentingSelection( v, B_Mask ) );
bool link = m_tentingFrontCtrl->GetSelection()
== m_tentingBackCtrl->GetSelection();
m_btnLinkTenting->SetValue( link );
m_tentingBackCtrl->Enable( !link );
m_tentingBackLabel->Enable( !link );
selection_first_layer = v->TopLayer();
selection_last_layer = v->BottomLayer();
@ -680,12 +697,20 @@ bool DIALOG_TRACK_VIA_PROPERTIES::TransferDataFromWindow()
break;
}
switch( m_tentingCtrl->GetSelection() )
switch( m_tentingFrontCtrl->GetSelection() )
{
default:
case 0: v->Padstack().OuterLayerDefaults().has_solder_mask.reset(); break;
case 1: v->Padstack().OuterLayerDefaults().has_solder_mask = true; break;
case 2: v->Padstack().OuterLayerDefaults().has_solder_mask = false; break;
case 0: v->Padstack().FrontOuterLayers().has_solder_mask.reset(); break;
case 1: v->Padstack().FrontOuterLayers().has_solder_mask = true; break;
case 2: v->Padstack().FrontOuterLayers().has_solder_mask = false; break;
}
switch( m_tentingBackCtrl->GetSelection() )
{
default:
case 0: v->Padstack().BackOuterLayers().has_solder_mask.reset(); break;
case 1: v->Padstack().BackOuterLayers().has_solder_mask = true; break;
case 2: v->Padstack().BackOuterLayers().has_solder_mask = false; break;
}
v->SanitizeLayers();
@ -893,6 +918,29 @@ void DIALOG_TRACK_VIA_PROPERTIES::onViaEdit( wxCommandEvent& aEvent )
}
void DIALOG_TRACK_VIA_PROPERTIES::onFrontTentingChanged( wxCommandEvent& event )
{
if( m_btnLinkTenting->GetValue() )
m_tentingBackCtrl->SetSelection( m_tentingFrontCtrl->GetSelection() );
event.Skip();
}
void DIALOG_TRACK_VIA_PROPERTIES::onTentingLinkToggle( wxCommandEvent& event )
{
bool link = m_btnLinkTenting->GetValue();
m_tentingBackCtrl->Enable( !link );
m_tentingBackLabel->Enable( !link );
if( link )
m_tentingBackCtrl->SetSelection( m_tentingFrontCtrl->GetSelection() );
event.Skip();
}
void DIALOG_TRACK_VIA_PROPERTIES::onTeardropsUpdateUi( wxUpdateUIEvent& event )
{
event.Enable( !m_frame->GetBoard()->LegacyTeardrops() );

View File

@ -48,6 +48,8 @@ private:
void onWidthEdit( wxCommandEvent& aEvent ) override;
void onViaSelect( wxCommandEvent& aEvent ) override;
void onViaEdit( wxCommandEvent& aEvent ) override;
void onTentingLinkToggle( wxCommandEvent& event ) override;
void onFrontTentingChanged( wxCommandEvent& event ) override;
void onUnitsChanged( wxCommandEvent& aEvent );
void onTeardropsUpdateUi( wxUpdateUIEvent& event ) override;

View File

@ -323,17 +323,38 @@ DIALOG_TRACK_VIA_PROPERTIES_BASE::DIALOG_TRACK_VIA_PROPERTIES_BASE( wxWindow* pa
m_annularRingsCtrl->SetSelection( 1 );
fgSizer4->Add( m_annularRingsCtrl, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxEXPAND, 5 );
m_tentingLabel = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Tenting:"), wxDefaultPosition, wxDefaultSize, 0 );
m_tentingLabel->Wrap( -1 );
fgSizer4->Add( m_tentingLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
m_tentingFrontLabel = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Front tenting:"), wxDefaultPosition, wxDefaultSize, 0 );
m_tentingFrontLabel->Wrap( -1 );
fgSizer4->Add( m_tentingFrontLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
wxString m_tentingCtrlChoices[] = { _("From design rules"), _("Tented"), _("Not tented") };
int m_tentingCtrlNChoices = sizeof( m_tentingCtrlChoices ) / sizeof( wxString );
m_tentingCtrl = new wxChoice( m_sbViaSizer->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, m_tentingCtrlNChoices, m_tentingCtrlChoices, 0 );
m_tentingCtrl->SetSelection( 0 );
m_tentingCtrl->SetToolTip( _("Whether to tent (cover with soldermask) this via") );
wxString m_tentingFrontCtrlChoices[] = { _("From design rules"), _("Tented"), _("Not tented") };
int m_tentingFrontCtrlNChoices = sizeof( m_tentingFrontCtrlChoices ) / sizeof( wxString );
m_tentingFrontCtrl = new wxChoice( m_sbViaSizer->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, m_tentingFrontCtrlNChoices, m_tentingFrontCtrlChoices, 0 );
m_tentingFrontCtrl->SetSelection( 0 );
m_tentingFrontCtrl->SetToolTip( _("Whether to tent (cover with soldermask) this via on the front side") );
fgSizer4->Add( m_tentingCtrl, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
fgSizer4->Add( m_tentingFrontCtrl, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxEXPAND, 5 );
m_btnLinkTenting = new wxBitmapToggleButton( m_sbViaSizer->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 );
m_btnLinkTenting->SetValue( true );
m_btnLinkTenting->SetToolTip( _("Link front and back tenting settings") );
fgSizer4->Add( m_btnLinkTenting, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
fgSizer4->Add( 0, 0, 1, wxEXPAND, 5 );
m_tentingBackLabel = new wxStaticText( m_sbViaSizer->GetStaticBox(), wxID_ANY, _("Back tenting:"), wxDefaultPosition, wxDefaultSize, 0 );
m_tentingBackLabel->Wrap( -1 );
fgSizer4->Add( m_tentingBackLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
wxString m_tentingBackCtrlChoices[] = { _("From design rules"), _("Tented"), _("Not tented") };
int m_tentingBackCtrlNChoices = sizeof( m_tentingBackCtrlChoices ) / sizeof( wxString );
m_tentingBackCtrl = new wxChoice( m_sbViaSizer->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, m_tentingBackCtrlNChoices, m_tentingBackCtrlChoices, 0 );
m_tentingBackCtrl->SetSelection( 0 );
m_tentingBackCtrl->SetToolTip( _("Whether to tent (cover with soldermask) this via on the back side") );
fgSizer4->Add( m_tentingBackCtrl, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
viaRightColumn->Add( fgSizer4, 0, wxEXPAND|wxBOTTOM, 3 );
@ -607,6 +628,8 @@ DIALOG_TRACK_VIA_PROPERTIES_BASE::DIALOG_TRACK_VIA_PROPERTIES_BASE( wxWindow* pa
m_ViaTypeChoice->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onViaEdit ), NULL, this );
m_ViaStartLayer->Connect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onViaEdit ), NULL, this );
m_ViaEndLayer->Connect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onViaEdit ), NULL, this );
m_tentingFrontCtrl->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onFrontTentingChanged ), NULL, this );
m_btnLinkTenting->Connect( wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTentingLinkToggle ), NULL, this );
m_cbTeardrops->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_cbTeardropsUseNextTrack->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_stHDRatio->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
@ -647,6 +670,8 @@ DIALOG_TRACK_VIA_PROPERTIES_BASE::~DIALOG_TRACK_VIA_PROPERTIES_BASE()
m_ViaTypeChoice->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onViaEdit ), NULL, this );
m_ViaStartLayer->Disconnect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onViaEdit ), NULL, this );
m_ViaEndLayer->Disconnect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onViaEdit ), NULL, this );
m_tentingFrontCtrl->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onFrontTentingChanged ), NULL, this );
m_btnLinkTenting->Disconnect( wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTentingLinkToggle ), NULL, this );
m_cbTeardrops->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_cbTeardropsUseNextTrack->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );
m_stHDRatio->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_TRACK_VIA_PROPERTIES_BASE::onTeardropsUpdateUi ), NULL, this );

View File

@ -3293,7 +3293,7 @@
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Tenting:</property>
<property name="label">Front tenting:</property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
@ -3302,7 +3302,218 @@
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_tentingLabel</property>
<property name="name">m_tentingFrontLabel</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"></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>
<property name="wrap">-1</property>
</object>
</object>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxEXPAND</property>
<property name="proportion">0</property>
<object class="wxChoice" expanded="true">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</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="choices">&quot;From design rules&quot; &quot;Tented&quot; &quot;Not tented&quot;</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="drag_accept_files">0</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_tentingFrontCtrl</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="selection">0</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">Whether to tent (cover with soldermask) this via on the front side</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="OnChoice">onFrontTentingChanged</event>
</object>
</object>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT</property>
<property name="proportion">0</property>
<object class="wxBitmapToggleButton" expanded="true">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</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_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="drag_accept_files">0</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">Link</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_btnLinkTenting</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="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip">Link front and back tenting settings</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="value">1</property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnToggleButton">onTentingLinkToggle</event>
</object>
</object>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">1</property>
<object class="spacer" expanded="true">
<property name="height">0</property>
<property name="permission">protected</property>
<property name="width">0</property>
</object>
</object>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="true">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</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="drag_accept_files">0</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="label">Back tenting:</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_tentingBackLabel</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
@ -3363,7 +3574,7 @@
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_tentingCtrl</property>
<property name="name">m_tentingBackCtrl</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
@ -3377,7 +3588,7 @@
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip">Whether to tent (cover with soldermask) this via</property>
<property name="tooltip">Whether to tent (cover with soldermask) this via on the back side</property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>

View File

@ -28,6 +28,7 @@ class PCB_LAYER_BOX_SELECTOR;
#include <wx/choice.h>
#include <wx/gbsizer.h>
#include <wx/bmpcbox.h>
#include <wx/tglbtn.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/icon.h>
@ -101,8 +102,11 @@ class DIALOG_TRACK_VIA_PROPERTIES_BASE : public DIALOG_SHIM
PCB_LAYER_BOX_SELECTOR* m_ViaEndLayer;
wxStaticText* m_annularRingsLabel;
wxChoice* m_annularRingsCtrl;
wxStaticText* m_tentingLabel;
wxChoice* m_tentingCtrl;
wxStaticText* m_tentingFrontLabel;
wxChoice* m_tentingFrontCtrl;
wxBitmapToggleButton* m_btnLinkTenting;
wxStaticText* m_tentingBackLabel;
wxChoice* m_tentingBackCtrl;
wxStaticLine* m_staticline2;
wxBoxSizer* m_legacyTeardropsWarning;
wxStaticBitmap* m_legacyTeardropsIcon;
@ -138,6 +142,8 @@ class DIALOG_TRACK_VIA_PROPERTIES_BASE : public DIALOG_SHIM
virtual void onWidthEdit( wxCommandEvent& event ) { event.Skip(); }
virtual void onViaSelect( wxCommandEvent& event ) { event.Skip(); }
virtual void onViaEdit( wxCommandEvent& event ) { event.Skip(); }
virtual void onFrontTentingChanged( wxCommandEvent& event ) { event.Skip(); }
virtual void onTentingLinkToggle( wxCommandEvent& event ) { event.Skip(); }
virtual void onTeardropsUpdateUi( wxUpdateUIEvent& event ) { event.Skip(); }
virtual void onCurvedEdgesUpdateUi( wxUpdateUIEvent& event ) { event.Skip(); }

View File

@ -56,7 +56,8 @@ bool PANEL_SETUP_MASK_AND_PASTE::TransferDataToWindow()
m_maskExpansion.SetValue( m_BrdSettings->m_SolderMaskExpansion );
m_maskMinWidth.SetValue( m_BrdSettings->m_SolderMaskMinWidth );
m_maskToCopperClearance.SetValue( m_BrdSettings->m_SolderMaskToCopperClearance );
m_tentVias->SetValue( m_BrdSettings->m_TentVias );
m_tentViasFront->SetValue( m_BrdSettings->m_TentViasFront );
m_tentViasBack->SetValue( m_BrdSettings->m_TentViasBack );
m_pasteMargin.SetValue( m_BrdSettings->m_SolderPasteMargin );
m_pasteMarginRatio.SetDoubleValue( m_BrdSettings->m_SolderPasteMarginRatio * 100.0 );
@ -73,7 +74,8 @@ bool PANEL_SETUP_MASK_AND_PASTE::TransferDataFromWindow()
m_BrdSettings->m_SolderMaskExpansion = m_maskExpansion.GetValue();
m_BrdSettings->m_SolderMaskMinWidth = m_maskMinWidth.GetValue();
m_BrdSettings->m_SolderMaskToCopperClearance = m_maskToCopperClearance.GetValue();
m_BrdSettings->m_TentVias = m_tentVias->GetValue();
m_BrdSettings->m_TentViasFront = m_tentViasFront->GetValue();
m_BrdSettings->m_TentViasBack = m_tentViasBack->GetValue();
m_BrdSettings->m_SolderPasteMargin = m_pasteMargin.GetValue();
m_BrdSettings->m_SolderPasteMarginRatio = m_pasteMarginRatio.GetDoubleValue() / 100.0;

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 3.10.1-282-g1fa54006)
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6-dirty)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@ -23,7 +23,7 @@ PANEL_SETUP_MASK_AND_PASTE_BASE::PANEL_SETUP_MASK_AND_PASTE_BASE( wxWindow* pare
bMessages->Add( 4, 0, 0, wxEXPAND, 5 );
m_bitmapWarning = new wxStaticBitmap( this, wxID_ANY, wxArtProvider::GetBitmap( wxART_WARNING, wxART_OTHER ), wxDefaultPosition, wxDefaultSize, 0 );
m_bitmapWarning = new wxStaticBitmap( this, wxID_ANY, wxArtProvider::GetBitmap( wxASCII_STR(wxART_WARNING), wxASCII_STR(wxART_OTHER) ), wxDefaultPosition, wxDefaultSize, 0 );
bMessages->Add( m_bitmapWarning, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxRIGHT, 5 );
wxBoxSizer* bSizer4;
@ -95,10 +95,25 @@ PANEL_SETUP_MASK_AND_PASTE_BASE::PANEL_SETUP_MASK_AND_PASTE_BASE( wxWindow* pare
m_allowBridges = new wxCheckBox( this, wxID_ANY, _("Allow bridged solder mask apertures between pads within footprints"), wxDefaultPosition, wxDefaultSize, 0 );
gbSizer1->Add( m_allowBridges, wxGBPosition( 3, 0 ), wxGBSpan( 1, 3 ), wxALL, 5 );
m_tentVias = new wxCheckBox( this, wxID_ANY, _("Tent vias"), wxDefaultPosition, wxDefaultSize, 0 );
m_tentVias->SetToolTip( _("Tented vias: not plotted on soldermask layer\nNot tented: vias are plotted on soldermask layer\n(Solder mask is a negative layer)") );
wxBoxSizer* bSizer6;
bSizer6 = new wxBoxSizer( wxHORIZONTAL );
gbSizer1->Add( m_tentVias, wxGBPosition( 4, 0 ), wxGBSpan( 1, 3 ), wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_stTenting = new wxStaticText( this, wxID_ANY, _("Tenting:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stTenting->Wrap( -1 );
bSizer6->Add( m_stTenting, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxLEFT|wxRIGHT, 5 );
m_tentViasFront = new wxCheckBox( this, wxID_ANY, _("Front"), wxDefaultPosition, wxDefaultSize, 0 );
m_tentViasFront->SetToolTip( _("Tented vias: not plotted on soldermask layer\nNot tented: vias are plotted on soldermask layer\n(Solder mask is a negative layer)") );
bSizer6->Add( m_tentViasFront, 0, wxALL, 5 );
m_tentViasBack = new wxCheckBox( this, wxID_ANY, _("Back"), wxDefaultPosition, wxDefaultSize, 0 );
m_tentViasBack->SetToolTip( _("Tented vias: not plotted on soldermask layer\nNot tented: vias are plotted on soldermask layer\n(Solder mask is a negative layer)") );
bSizer6->Add( m_tentViasBack, 0, wxALL, 5 );
gbSizer1->Add( bSizer6, wxGBPosition( 4, 0 ), wxGBSpan( 0, 2 ), wxEXPAND, 5 );
m_pasteMarginLabel = new wxStaticText( this, wxID_ANY, _("Solder paste absolute clearance:"), wxDefaultPosition, wxDefaultSize, 0 );
m_pasteMarginLabel->Wrap( -1 );

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 3.10.1-282-g1fa54006)
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6-dirty)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@ -51,7 +51,9 @@ class PANEL_SETUP_MASK_AND_PASTE_BASE : public wxPanel
wxTextCtrl* m_maskToCopperClearanceCtrl;
wxStaticText* m_maskToCopperClearanceUnits;
wxCheckBox* m_allowBridges;
wxCheckBox* m_tentVias;
wxStaticText* m_stTenting;
wxCheckBox* m_tentViasFront;
wxCheckBox* m_tentViasBack;
wxStaticText* m_pasteMarginLabel;
wxTextCtrl* m_pasteMarginCtrl;
wxStaticText* m_pasteMarginUnits;

View File

@ -190,7 +190,7 @@ bool DRC_TEST_PROVIDER_SILK_CLEARANCE::Run()
if( isInvisibleText( refItem ) || isInvisibleText( testItem ) )
return true;
if( testItem->IsTented() )
if( testItem->IsTented( aLayers.first ) )
{
if( testItem->HasHole() )
{

View File

@ -525,12 +525,12 @@ void DRC_TEST_PROVIDER_SOLDER_MASK::testItemAgainstItems( BOARD_ITEM* aItem, con
if( pad )
clearance += pad->GetSolderMaskExpansion();
else if( via && !via->IsTented() )
else if( via && !via->IsTented( aRefLayer ) )
clearance += via->GetSolderMaskExpansion();
if( otherPad )
clearance += otherPad->GetSolderMaskExpansion();
else if( otherVia && !otherVia->IsTented() )
else if( otherVia && !otherVia->IsTented( aRefLayer ) )
clearance += otherVia->GetSolderMaskExpansion();
if( itemShape->Collide( otherShape.get(), clearance, &actual, &pos ) )

View File

@ -61,11 +61,10 @@ PADSTACK& PADSTACK::operator=( const PADSTACK &aOther )
m_layerSet = aOther.m_layerSet;
m_customName = aOther.m_customName;
m_defaultCopperProps = aOther.m_defaultCopperProps;
m_defaultOuterProps = aOther.m_defaultOuterProps;
m_frontMaskProps = aOther.m_frontMaskProps;
m_backMaskProps = aOther.m_backMaskProps;
m_unconnectedLayerMode = aOther.m_unconnectedLayerMode;
m_copperOverrides = aOther.m_copperOverrides;
m_topOverrides = aOther.m_topOverrides;
m_bottomOverrides = aOther.m_bottomOverrides;
m_drill = aOther.m_drill;
m_secondaryDrill = aOther.m_secondaryDrill;
return *this;
@ -78,11 +77,10 @@ bool PADSTACK::operator==( const PADSTACK& aOther ) const
&& m_layerSet == aOther.m_layerSet
&& m_customName == aOther.m_customName
&& m_defaultCopperProps == aOther.m_defaultCopperProps
&& m_defaultOuterProps == aOther.m_defaultOuterProps
&& m_frontMaskProps == aOther.m_frontMaskProps
&& m_backMaskProps == aOther.m_backMaskProps
&& m_unconnectedLayerMode == aOther.m_unconnectedLayerMode
&& m_copperOverrides == aOther.m_copperOverrides
&& m_topOverrides == aOther.m_topOverrides
&& m_bottomOverrides == aOther.m_bottomOverrides
&& m_drill == aOther.m_drill
&& m_secondaryDrill == aOther.m_secondaryDrill;
}
@ -243,7 +241,7 @@ bool PADSTACK::COPPER_LAYER_PROPS::operator==( const COPPER_LAYER_PROPS& aOther
}
bool PADSTACK::OUTER_LAYER_PROPS::operator==( const OUTER_LAYER_PROPS& aOther ) const
bool PADSTACK::MASK_LAYER_PROPS::operator==( const MASK_LAYER_PROPS& aOther ) const
{
return solder_mask_margin == aOther.solder_mask_margin
&& solder_paste_margin == aOther.solder_paste_margin
@ -405,38 +403,42 @@ const std::optional<int>& PADSTACK::Clearance( PCB_LAYER_ID aLayer ) const
std::optional<int>& PADSTACK::SolderMaskMargin( PCB_LAYER_ID aLayer )
{
return OuterLayerDefaults().solder_mask_margin;
return IsFrontLayer( aLayer ) ? m_frontMaskProps.solder_mask_margin
: m_backMaskProps.solder_mask_margin;
}
const std::optional<int>& PADSTACK::SolderMaskMargin( PCB_LAYER_ID aLayer ) const
{
return OuterLayerDefaults().solder_mask_margin;
return IsFrontLayer( aLayer ) ? m_frontMaskProps.solder_mask_margin
: m_backMaskProps.solder_mask_margin;
}
std::optional<int>& PADSTACK::SolderPasteMargin( PCB_LAYER_ID aLayer )
{
return OuterLayerDefaults().solder_paste_margin;
return IsFrontLayer( aLayer ) ? m_frontMaskProps.solder_paste_margin
: m_backMaskProps.solder_paste_margin;
}
const std::optional<int>& PADSTACK::SolderPasteMargin( PCB_LAYER_ID aLayer ) const
{
return OuterLayerDefaults().solder_paste_margin;
}
return IsFrontLayer( aLayer ) ? m_frontMaskProps.solder_paste_margin
: m_backMaskProps.solder_paste_margin;}
std::optional<double>& PADSTACK::SolderPasteMarginRatio( PCB_LAYER_ID aLayer )
{
return OuterLayerDefaults().solder_paste_margin_ratio;
return IsFrontLayer( aLayer ) ? m_frontMaskProps.solder_paste_margin_ratio
: m_backMaskProps.solder_paste_margin_ratio;
}
const std::optional<double>& PADSTACK::SolderPasteMarginRatio( PCB_LAYER_ID aLayer ) const
{
return OuterLayerDefaults().solder_paste_margin_ratio;
}
return IsFrontLayer( aLayer ) ? m_frontMaskProps.solder_paste_margin_ratio
: m_backMaskProps.solder_paste_margin_ratio;}
std::optional<ZONE_CONNECTION>& PADSTACK::ZoneConnection( PCB_LAYER_ID aLayer )
@ -535,4 +537,16 @@ void PADSTACK::ClearPrimitives( PCB_LAYER_ID aLayer )
}
std::optional<bool> PADSTACK::IsTented( PCB_LAYER_ID aSide ) const
{
if( IsFrontLayer( aSide ) )
return m_frontMaskProps.has_solder_mask;
if( IsBackLayer( aSide ) )
return m_backMaskProps.has_solder_mask;
wxCHECK_MSG( false, std::nullopt, "IsTented expects a front or back layer" );
}
IMPLEMENT_ENUM_TO_WXANY( PADSTACK::UNCONNECTED_LAYER_MODE )

View File

@ -208,7 +208,7 @@ public:
///! The features of a padstack that can vary on outer layers.
///! All parameters are optional; leaving them un-set means "use parent/rule defaults"
struct OUTER_LAYER_PROPS
struct MASK_LAYER_PROPS
{
std::optional<int> solder_mask_margin;
std::optional<int> solder_paste_margin;
@ -216,7 +216,7 @@ public:
std::optional<bool> has_solder_mask; ///< True if this outer layer has mask (is not tented)
std::optional<bool> has_solder_paste; ///< True if this outer layer has solder paste
bool operator==( const OUTER_LAYER_PROPS& aOther ) const;
bool operator==( const MASK_LAYER_PROPS& aOther ) const;
};
///! The properties of a padstack drill. Drill position is always the pad position (origin).
@ -274,8 +274,19 @@ public:
COPPER_LAYER_PROPS& CopperLayerDefaults() { return m_defaultCopperProps; }
const COPPER_LAYER_PROPS& CopperLayerDefaults() const { return m_defaultCopperProps; }
OUTER_LAYER_PROPS& OuterLayerDefaults() { return m_defaultOuterProps; }
const OUTER_LAYER_PROPS& OuterLayerDefaults() const { return m_defaultOuterProps; }
MASK_LAYER_PROPS& FrontOuterLayers() { return m_frontMaskProps; }
const MASK_LAYER_PROPS& FrontOuterLayers() const { return m_frontMaskProps; }
MASK_LAYER_PROPS& BackOuterLayers() { return m_backMaskProps; }
const MASK_LAYER_PROPS& BackOuterLayers() const { return m_backMaskProps; }
/**
* Checks if this padstack is tented (covered in soldermask) on the given side
* @param aSide is a front or back layer (any will do)
* @return true or false if this padstack contains a tenting override on the given layer, or
* std::nullopt if there is no override (meaning design rules should be used)
*/
std::optional<bool> IsTented( PCB_LAYER_ID aSide ) const;
CUSTOM_SHAPE_ZONE_MODE CustomShapeInZoneMode() const { return m_customShapeInZoneMode; }
void SetCustomShapeInZoneMode( CUSTOM_SHAPE_ZONE_MODE aM ) { m_customShapeInZoneMode = aM; }
@ -385,8 +396,11 @@ private:
///! The properties applied to copper layers if they aren't overridden
COPPER_LAYER_PROPS m_defaultCopperProps;
///! The properties applied to outer technical layers if they aren't overridden
OUTER_LAYER_PROPS m_defaultOuterProps;
///! The overrides applied to front outer technical layers
MASK_LAYER_PROPS m_frontMaskProps;
///! The overrides applied to back outer technical layers
MASK_LAYER_PROPS m_backMaskProps;
UNCONNECTED_LAYER_MODE m_unconnectedLayerMode;
@ -403,12 +417,6 @@ private:
///! If m_mode == MODE::NORMAL, this map is ignored.
std::unordered_map<PCB_LAYER_ID, COPPER_LAYER_PROPS> m_copperOverrides;
///! Any non-null optional values here override the mask/paste settings for the top layers
OUTER_LAYER_PROPS m_topOverrides;
///! Any non-null optional values here override the mask/paste settings for bottom layers
OUTER_LAYER_PROPS m_bottomOverrides;
///! The primary drill parameters, which also define the start and end layers for through-hole
///! vias and pads (F_Cu to B_Cu for normal holes; a subset of layers for blind/buried vias)
DRILL_PROPS m_drill;

View File

@ -928,7 +928,11 @@ void PCB_IO_KICAD_LEGACY::loadSETUP()
m_board->SetPlotOptions( plot_opts );
if( plot_opts.GetLegacyPlotViaOnMaskLayer().has_value() )
m_board->GetDesignSettings().m_TentVias = *plot_opts.GetLegacyPlotViaOnMaskLayer();
{
bool tent = *plot_opts.GetLegacyPlotViaOnMaskLayer();
m_board->GetDesignSettings().m_TentViasFront = tent;
m_board->GetDesignSettings().m_TentViasBack = tent;
}
}
else if( TESTLINE( "AuxiliaryAxisOrg" ) )

View File

@ -587,11 +587,21 @@ void PCB_IO_KICAD_SEXPR::formatSetup( const BOARD* aBoard, int aNestLevel ) cons
KICAD_FORMAT::FormatBool( m_out, aNestLevel + 1, "allow_soldermask_bridges_in_footprints",
dsnSettings.m_AllowSoldermaskBridgesInFPs );
// TODO support tenting top or bottom individually
if( dsnSettings.m_TentVias )
m_out->Print( 0, " (tenting front back)" );
m_out->Print( 0, " (tenting " );
if( dsnSettings.m_TentViasFront || dsnSettings.m_TentViasBack )
{
if( dsnSettings.m_TentViasFront )
m_out->Print( 0, "front " );
if( dsnSettings.m_TentViasBack )
m_out->Print( 0, "back " );
m_out->Print( 0, ")" );
}
else
m_out->Print( 0, " (tenting none)" );
{
m_out->Print( 0, " none)" );
}
VECTOR2I origin = dsnSettings.GetAuxOrigin();
@ -2240,13 +2250,23 @@ void PCB_IO_KICAD_SEXPR::format( const PCB_TRACK* aTrack, int aNestLevel ) const
m_out->Print( 0, ")" );
}
if( via->Padstack().OuterLayerDefaults().has_solder_mask.has_value() )
bool front = via->Padstack().FrontOuterLayers().has_solder_mask.value_or( false );
bool back = via->Padstack().BackOuterLayers().has_solder_mask.value_or( false );
if( front || back )
{
// TODO support tenting top or bottom individually
if( *via->Padstack().OuterLayerDefaults().has_solder_mask )
m_out->Print( 0, " (tenting top bottom)" );
else
m_out->Print( 0, " (tenting none)" );
m_out->Print( 0, " (tenting " );
if( via->Padstack().FrontOuterLayers().has_solder_mask.value_or( false ) )
m_out->Print( 0, " front" );
if( via->Padstack().BackOuterLayers().has_solder_mask.value_or( false ) )
m_out->Print( 0, " back" );
m_out->Print( 0, ")" );
}
else
{
m_out->Print( 0, " (tenting none)" );
}
if( !isDefaultTeardropParameters( via->GetTeardropParams() ) )

View File

@ -2320,11 +2320,12 @@ void PCB_IO_KICAD_SEXPR_PARSER::parseSetup()
{
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{
// TODO support tenting top or bottom individually
if( token == T_front || token == T_back )
bds.m_TentVias = true;
if( token == T_front )
bds.m_TentViasFront = true;
else if( token == T_back )
bds.m_TentViasBack = true;
else if( token == T_none )
bds.m_TentVias = false;
bds.m_TentViasFront = bds.m_TentViasBack = false;
else
Expecting( "front, back, or none" );
}
@ -2395,7 +2396,11 @@ void PCB_IO_KICAD_SEXPR_PARSER::parseSetup()
m_board->SetPlotOptions( plotParams );
if( plotParams.GetLegacyPlotViaOnMaskLayer().has_value() )
m_board->GetDesignSettings().m_TentVias = !*plotParams.GetLegacyPlotViaOnMaskLayer();
{
bool tent = *plotParams.GetLegacyPlotViaOnMaskLayer();
m_board->GetDesignSettings().m_TentViasFront = tent;
m_board->GetDesignSettings().m_TentViasBack = tent;
}
break;
}
@ -5836,17 +5841,23 @@ PCB_VIA* PCB_IO_KICAD_SEXPR_PARSER::parsePCB_VIA()
case T_tenting:
{
bool front = false;
bool back = false;
// If the via has a tenting token, it means this individual via has a tenting override
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{
// TODO support tenting top or bottom individually
if( token == T_front || token == T_back )
via->Padstack().OuterLayerDefaults().has_solder_mask = true;
else if( token == T_none )
via->Padstack().OuterLayerDefaults().has_solder_mask = false;
else
if( token == T_front )
front = true;
else if( token == T_back )
back = true;
else if( token != T_none )
Expecting( "front, back, or none" );
}
via->Padstack().FrontOuterLayers().has_solder_mask = front;
via->Padstack().BackOuterLayers().has_solder_mask = back;
break;
}

View File

@ -769,22 +769,22 @@ std::shared_ptr<SHAPE_SEGMENT> PCB_VIA::GetEffectiveHoleShape() const
}
void PCB_VIA::SetTentingMode( TENTING_MODE aMode )
void PCB_VIA::SetFrontTentingMode( TENTING_MODE aMode )
{
switch( aMode )
{
case TENTING_MODE::FROM_RULES: m_padStack.OuterLayerDefaults().has_solder_mask.reset(); break;
case TENTING_MODE::TENTED: m_padStack.OuterLayerDefaults().has_solder_mask = true; break;
case TENTING_MODE::NOT_TENTED: m_padStack.OuterLayerDefaults().has_solder_mask = false; break;
case TENTING_MODE::FROM_RULES: m_padStack.FrontOuterLayers().has_solder_mask.reset(); break;
case TENTING_MODE::TENTED: m_padStack.FrontOuterLayers().has_solder_mask = true; break;
case TENTING_MODE::NOT_TENTED: m_padStack.FrontOuterLayers().has_solder_mask = false; break;
}
}
TENTING_MODE PCB_VIA::TentingMode() const
TENTING_MODE PCB_VIA::GetFrontTentingMode() const
{
if( m_padStack.OuterLayerDefaults().has_solder_mask.has_value() )
if( m_padStack.FrontOuterLayers().has_solder_mask.has_value() )
{
return *m_padStack.OuterLayerDefaults().has_solder_mask ?
return *m_padStack.FrontOuterLayers().has_solder_mask ?
TENTING_MODE::TENTED : TENTING_MODE::NOT_TENTED;
}
@ -792,14 +792,47 @@ TENTING_MODE PCB_VIA::TentingMode() const
}
bool PCB_VIA::IsTented() const
void PCB_VIA::SetBackTentingMode( TENTING_MODE aMode )
{
// TODO support tenting top or bottom individually
if( m_padStack.OuterLayerDefaults().has_solder_mask.has_value() )
return *m_padStack.OuterLayerDefaults().has_solder_mask;
switch( aMode )
{
case TENTING_MODE::FROM_RULES: m_padStack.BackOuterLayers().has_solder_mask.reset(); break;
case TENTING_MODE::TENTED: m_padStack.BackOuterLayers().has_solder_mask = true; break;
case TENTING_MODE::NOT_TENTED: m_padStack.BackOuterLayers().has_solder_mask = false; break;
}
}
TENTING_MODE PCB_VIA::GetBackTentingMode() const
{
if( m_padStack.BackOuterLayers().has_solder_mask.has_value() )
{
return *m_padStack.BackOuterLayers().has_solder_mask ?
TENTING_MODE::TENTED : TENTING_MODE::NOT_TENTED;
}
return TENTING_MODE::FROM_RULES;
}
bool PCB_VIA::IsTented( PCB_LAYER_ID aLayer ) const
{
wxCHECK_MSG( IsFrontLayer( aLayer ) || IsBackLayer( aLayer ), true,
"Invalid layer passed to IsTented" );
bool front = IsFrontLayer( aLayer );
if( front && m_padStack.FrontOuterLayers().has_solder_mask.has_value() )
return *m_padStack.FrontOuterLayers().has_solder_mask;
if( !front && m_padStack.BackOuterLayers().has_solder_mask.has_value() )
return *m_padStack.BackOuterLayers().has_solder_mask;
if( const BOARD* board = GetBoard() )
return board->GetDesignSettings().m_TentVias;
{
return front ? board->GetDesignSettings().m_TentViasFront
: board->GetDesignSettings().m_TentViasBack;
}
return true;
}
@ -824,13 +857,10 @@ bool PCB_VIA::IsOnLayer( PCB_LAYER_ID aLayer ) const
if( aLayer >= Padstack().Drill().start && aLayer <= Padstack().Drill().end )
return true;
if( !IsTented() )
{
if( aLayer == F_Mask )
return IsOnLayer( F_Cu );
else if( aLayer == B_Mask )
return IsOnLayer( B_Cu );
}
if( aLayer == F_Mask )
return !IsTented( F_Mask );
else if( aLayer == B_Mask )
return !IsTented( B_Mask );
return false;
}
@ -864,14 +894,11 @@ LSET PCB_VIA::GetLayerSet() const
for( int id = Padstack().Drill().start; id <= Padstack().Drill().end; ++id )
layermask.set( id );
if( !IsTented() )
{
if( layermask.test( F_Cu ) )
layermask.set( F_Mask );
if( !IsTented( F_Mask ) && layermask.test( F_Cu ) )
layermask.set( F_Mask );
if( layermask.test( B_Cu ) )
layermask.set( B_Mask );
}
if( !IsTented( B_Mask ) && layermask.test( B_Cu ) )
layermask.set( B_Mask );
return layermask;
}
@ -1730,8 +1757,10 @@ static struct TRACK_VIA_DESC
&PCB_VIA::SetBottomLayer, &PCB_VIA::BottomLayer ), groupVia );
propMgr.AddProperty( new PROPERTY_ENUM<PCB_VIA, VIATYPE>( _HKI( "Via Type" ),
&PCB_VIA::SetViaType, &PCB_VIA::GetViaType ), groupVia );
propMgr.AddProperty( new PROPERTY_ENUM<PCB_VIA, TENTING_MODE>( _HKI( "Tenting" ),
&PCB_VIA::SetTentingMode, &PCB_VIA::TentingMode ), groupVia );
propMgr.AddProperty( new PROPERTY_ENUM<PCB_VIA, TENTING_MODE>( _HKI( "Front tenting" ),
&PCB_VIA::SetFrontTentingMode, &PCB_VIA::GetFrontTentingMode ), groupVia );
propMgr.AddProperty( new PROPERTY_ENUM<PCB_VIA, TENTING_MODE>( _HKI( "Back tenting" ),
&PCB_VIA::SetBackTentingMode, &PCB_VIA::GetBackTentingMode ), groupVia );
}
} _TRACK_VIA_DESC;

View File

@ -414,10 +414,12 @@ public:
MINOPTMAX<int> GetWidthConstraint( wxString* aSource = nullptr ) const override;
MINOPTMAX<int> GetDrillConstraint( wxString* aSource = nullptr ) const;
void SetTentingMode( TENTING_MODE aMode );
TENTING_MODE TentingMode() const;
void SetFrontTentingMode( TENTING_MODE aMode );
TENTING_MODE GetFrontTentingMode() const;
void SetBackTentingMode( TENTING_MODE aMode );
TENTING_MODE GetBackTentingMode() const;
bool IsTented() const override;
bool IsTented( PCB_LAYER_ID aLayer ) const override;
int GetSolderMaskExpansion() const;
PCB_LAYER_ID GetLayer() const override;

View File

@ -1006,7 +1006,7 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
if( aItem->IsOnLayer( correspondingMask ) )
return true;
if( aItem->IsTented() && aItem->IsOnLayer( correspondingCopper ) )
if( aItem->IsTented( correspondingMask ) && aItem->IsOnLayer( correspondingCopper ) )
{
*aWarning = wxString::Format( _( "Note: %s is tented; clearance will only be "
"applied to holes." ),

View File

@ -1079,6 +1079,7 @@
(size 0.6)
(drill 0.3)
(layers "F.Cu" "B.Cu")
(tenting none)
(net 0)
(uuid "453c7569-dd77-45eb-bcc3-30db3a0f40a9")
)
@ -1087,6 +1088,7 @@
(size 0.6)
(drill 0.3)
(layers "In1.Cu" "In4.Cu")
(tenting none)
(net 0)
(uuid "68434c33-7a9f-42fc-987d-91fe3a581387")
)
@ -1095,6 +1097,7 @@
(size 0.6)
(drill 0.3)
(layers "In2.Cu" "In3.Cu")
(tenting none)
(net 0)
(uuid "13486125-e7d8-4fb9-bf37-cba2e8c45ed4")
)
@ -1103,6 +1106,7 @@
(size 0.6)
(drill 0.3)
(layers "In2.Cu" "In3.Cu")
(tenting none)
(net 0)
(uuid "8b2bd992-9b12-4445-b400-250bd7889789")
)
@ -1112,6 +1116,7 @@
(drill 0.3)
(layers "F.Cu" "B.Cu")
(free yes)
(tenting none)
(net 1)
(uuid "2ff08d6b-d2fa-498c-aa0a-437903b48438")
)
@ -1121,15 +1126,38 @@
(drill 0.3)
(layers "F.Cu" "B.Cu")
(free yes)
(tenting none)
(net 1)
(uuid "b86ba856-d576-4a99-a8e8-6d1c7f1f8e54")
)
(via
(at 122 83)
(size 0.7)
(drill 0.35)
(layers "F.Cu" "B.Cu")
(free yes)
(tenting front)
(teardrops
(best_length_ratio 0.2)
(max_length 0)
(best_width_ratio 0.8)
(max_width 10)
(curve_points 10)
(filter_ratio 0.75)
(enabled yes)
(allow_two_segments yes)
(prefer_zone_connections yes)
)
(net 2)
(uuid "13ce42b0-06c2-44cb-9836-26127897dd66")
)
(via
(at 122 80)
(size 0.6)
(drill 0.3)
(layers "F.Cu" "B.Cu")
(free yes)
(tenting none)
(net 2)
(uuid "4da21d74-ca51-4030-841d-9fa4271dd639")
)
@ -1142,9 +1170,31 @@
(keep_end_layers no)
(free yes)
(zone_layer_connections)
(tenting none)
(net 2)
(uuid "993f27ea-49bf-4980-b2ed-b2764a799bb9")
)
(via
(at 123 83)
(size 0.7)
(drill 0.35)
(layers "F.Cu" "B.Cu")
(free yes)
(tenting back)
(teardrops
(best_length_ratio 0.2)
(max_length 0)
(best_width_ratio 0.8)
(max_width 10)
(curve_points 10)
(filter_ratio 0.75)
(enabled yes)
(allow_two_segments yes)
(prefer_zone_connections yes)
)
(net 2)
(uuid "aff7cd99-a442-4592-b93d-20bb191ac90d")
)
(via
(at 122 82)
(size 0.7)
@ -1194,6 +1244,7 @@
(layers "F.Cu" "B.Cu")
(locked yes)
(free yes)
(tenting none)
(net 2)
(uuid "dab5afb6-716e-4443-b91e-13650cfba71f")
)
@ -1204,6 +1255,7 @@
(layers "F.Cu" "In4.Cu")
(locked yes)
(free yes)
(tenting none)
(net 2)
(uuid "dd040225-30f9-4c79-ad3e-e43383b2fb35")
)
@ -1214,6 +1266,7 @@
(layers "In3.Cu" "B.Cu")
(locked yes)
(free yes)
(tenting none)
(net 2)
(uuid "878e8a3b-77d9-402e-9019-c139f6ee7548")
)
@ -1224,6 +1277,7 @@
(layers "In4.Cu" "B.Cu")
(locked yes)
(free yes)
(tenting none)
(net 2)
(uuid "c5a1f081-1841-48f2-858c-598a487445a0")
)