KiCad PCB EDA Suite
Loading...
Searching...
No Matches
dialog_microvia_stack.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
21#include <confirm.h>
22#include <lset.h>
23#include <pcb_base_edit_frame.h>
25#include <pcb_track.h>
26
29
30
33 m_stack( aStack ),
34 m_explicitViaSize( aStack->GetViaSize() ),
35 m_explicitViaDrill( aStack->GetViaDrill() ),
39{
40 for( PCB_LAYER_BOX_SELECTOR* selector : { m_startLayer, m_endLayer } )
41 {
42 selector->SetLayersHotkeys( false );
43 selector->SetNotAllowedLayerSet( LSET::AllNonCuMask() );
44 selector->SetBoardFrame( aParent );
45 selector->Resync();
46 }
47
48 m_typeChoice->Bind( wxEVT_CHOICE, &DIALOG_MICROVIA_STACK::onTypeChanged, this );
49 m_useNetclass->Bind( wxEVT_CHECKBOX, &DIALOG_MICROVIA_STACK::onUseNetclass, this );
50
53}
54
55
57{
58 m_startLayer->SetLayerSelection( m_stack->GetStartLayer() );
59 m_endLayer->SetLayerSelection( m_stack->GetEndLayer() );
60 m_typeChoice->SetSelection( m_stack->GetStyle() == VIA_STACK_STYLE::STAGGERED ? 1 : 0 );
61
62 m_useNetclass->SetValue( m_stack->GetUseNetclass() );
63 m_filled->SetValue( m_stack->IsFilled() );
64 m_capped->SetValue( m_stack->IsCapped() );
65
66 m_viaSize.SetValue( m_explicitViaSize );
68 m_pitch.SetValue( m_stack->GetPitch() );
69
70 if( m_useNetclass->GetValue() )
72
74 return true;
75}
76
77
79{
80 PCB_LAYER_ID startLayer = ToLAYER_ID( m_startLayer->GetLayerSelection() );
81 PCB_LAYER_ID endLayer = ToLAYER_ID( m_endLayer->GetLayerSelection() );
82 bool staggered = m_typeChoice->GetSelection() == 1;
83
84 if( startLayer == endLayer )
85 {
86 DisplayErrorMessage( this, _( "The start and end layers must be different." ) );
87 return false;
88 }
89
90 if( !PCB_VIA_STACK::IsSpanValid( m_stack->GetBoard(), startLayer, endLayer ) )
91 {
92 DisplayErrorMessage( this, _( "Select a start and an end layer present on this board." ) );
93 return false;
94 }
95
96 if( staggered && m_pitch.GetIntValue() <= 0 )
97 {
98 DisplayErrorMessage( this, _( "Staggered stacks need a pitch greater than zero." ) );
99 return false;
100 }
101
102 if( m_pitch.GetIntValue() > pcbIUScale.mmToIU( MAX_MICROVIA_STACK_PITCH_MM ) )
103 {
106
107 DisplayErrorMessage( this, wxString::Format( _( "The pitch must be %s or less." ), limit ) );
108 return false;
109 }
110
111 m_stack->SetStartLayer( startLayer );
112 m_stack->SetEndLayer( endLayer );
114
115 m_stack->SetUseNetclass( m_useNetclass->GetValue() );
116
117 // Stacked stacks land on filled copper, so fill is forced on.
118 m_stack->SetFilled( staggered ? m_filled->GetValue() : true );
119 m_stack->SetCapped( m_capped->GetValue() );
120
121 if( m_useNetclass->GetValue() )
122 {
123 m_stack->SetViaSize( 0 );
124 m_stack->SetViaDrill( 0 );
125 }
126 else
127 {
128 if( std::optional<PCB_VIA::VIA_PARAMETER_ERROR> error = PCB_VIA::ValidateViaParameters(
129 m_viaSize.GetIntValue(), m_viaDrill.GetIntValue(), startLayer, endLayer ) )
130 {
131 DisplayErrorMessage( this, error->m_Message );
132 return false;
133 }
134
135 m_stack->SetViaSize( m_viaSize.GetIntValue() );
136 m_stack->SetViaDrill( m_viaDrill.GetIntValue() );
137 }
138
139 m_stack->SetPitch( m_pitch.GetIntValue() );
140 return true;
141}
142
143
145{
146 bool staggered = m_typeChoice->GetSelection() == 1;
147 bool useNetclass = m_useNetclass->GetValue();
148
149 // Pitch only applies to staggered stacks.
150 m_pitch.Enable( staggered );
151
152 // Size and drill come from the netclass when requested.
153 m_viaSize.Enable( !useNetclass );
154 m_viaDrill.Enable( !useNetclass );
155
156 // Stacked stacks are always copper filled.
157 m_filled->Enable( staggered );
158
159 if( !staggered )
160 m_filled->SetValue( true );
161}
162
163
164void DIALOG_MICROVIA_STACK::onTypeChanged( wxCommandEvent& aEvent )
165{
167}
168
169
171{
172 auto [size, drill] = PCB_VIA_STACK::GetNetclassViaSize( m_stack->GetBoard(), m_stack->GetNetCode() );
173
174 m_viaSize.SetValue( size );
175 m_viaDrill.SetValue( drill );
176}
177
178
179void DIALOG_MICROVIA_STACK::onUseNetclass( wxCommandEvent& aEvent )
180{
181 if( m_useNetclass->GetValue() )
182 {
183 m_explicitViaSize = m_viaSize.GetIntValue();
184 m_explicitViaDrill = m_viaDrill.GetIntValue();
186 }
187 else
188 {
189 // A zero size was never explicit, so the net class value is the better starting point
190 if( m_explicitViaSize > 0 )
191 m_viaSize.SetValue( m_explicitViaSize );
192
193 if( m_explicitViaDrill > 0 )
194 m_viaDrill.SetValue( m_explicitViaDrill );
195 }
196
198}
constexpr EDA_IU_SCALE pcbIUScale
Definition base_units.h:128
#define MAX_MICROVIA_STACK_PITCH_MM
PCB_LAYER_BOX_SELECTOR * m_startLayer
PCB_LAYER_BOX_SELECTOR * m_endLayer
DIALOG_MICROVIA_STACK_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxString &title=_("Microvia Stack"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxDEFAULT_DIALOG_STYLE)
DIALOG_MICROVIA_STACK(PCB_BASE_EDIT_FRAME *aParent, PCB_VIA_STACK *aStack)
void onUseNetclass(wxCommandEvent &aEvent)
bool TransferDataFromWindow() override
void onTypeChanged(wxCommandEvent &aEvent)
void SetupStandardButtons(std::map< int, wxString > aLabels={})
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
EDA_UNITS GetUserUnits() const
static LSET AllNonCuMask()
Return a mask holding all layer minus CU layers.
Definition lset.cpp:623
Common, abstract interface for edit frames.
Class to display a pcb layer list in a wxBitmapComboBox.
A microvia stack: several single hop microvias, plus connecting traces for staggered stacks,...
static bool IsSpanValid(BOARD *aBoard, PCB_LAYER_ID aStart, PCB_LAYER_ID aEnd)
True when both span ends are copper layers within the board's copper layer count.
static std::pair< int, int > GetNetclassViaSize(BOARD *aBoard, int aNetCode)
The microvia diameter and drill that "use netclass values" gives hops on aNetCode,...
static std::optional< VIA_PARAMETER_ERROR > ValidateViaParameters(std::optional< int > aDiameter, std::optional< int > aPrimaryDrill, std::optional< PCB_LAYER_ID > aPrimaryStartLayer=std::nullopt, std::optional< PCB_LAYER_ID > aPrimaryEndLayer=std::nullopt, std::optional< int > aSecondaryDrill=std::nullopt, std::optional< PCB_LAYER_ID > aSecondaryStartLayer=std::nullopt, std::optional< PCB_LAYER_ID > aSecondaryEndLayer=std::nullopt, std::optional< int > aTertiaryDrill=std::nullopt, std::optional< PCB_LAYER_ID > aTertiaryStartLayer=std::nullopt, std::optional< PCB_LAYER_ID > aTertiaryEndLayer=std::nullopt, int aCopperLayerCount=0)
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition confirm.cpp:217
This file is part of the common library.
#define _(s)
PCB_LAYER_ID
A quick note on layer IDs:
Definition layer_ids.h:56
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition lset.cpp:750
KICOMMON_API wxString MessageTextFromValue(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnits, double aValue, bool aAddUnitsText=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
A helper to convert the double length aValue to a string in inches, millimeters, or unscaled units.