KiCad PCB EDA Suite
Loading...
Searching...
No Matches
padstack.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 (C) 2024 Jon Evans <[email protected]>
5 * Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <convert_basic_shapes_to_polygon.h> // RECT_CHAMFER_POSITIONS
22#include "padstack.h"
23#include <api/api_enums.h>
24#include <api/api_utils.h>
25#include <api/api_pcb_utils.h>
26#include <api/board/board_types.pb.h>
27#include <pcb_shape.h>
28
29
31 m_parent( aParent ),
32 m_mode( MODE::NORMAL ),
33 m_orientation( ANGLE_0 ),
34 m_unconnectedLayerMode( UNCONNECTED_LAYER_MODE::KEEP_ALL ),
35 m_customShapeInZoneMode( CUSTOM_SHAPE_ZONE_MODE::OUTLINE )
36{
38 m_defaultCopperProps.zone_connection = ZONE_CONNECTION::INHERITED;
41 m_defaultCopperProps.thermal_gap = std::nullopt;
42
43 m_drill.shape = PAD_DRILL_SHAPE::CIRCLE;
46
49}
50
51
53{
54 *this = aOther;
55}
56
57
59{
60 m_mode = aOther.m_mode;
61 m_layerSet = aOther.m_layerSet;
68 m_drill = aOther.m_drill;
70 return *this;
71}
72
73
74bool PADSTACK::operator==( const PADSTACK& aOther ) const
75{
76 return m_mode == aOther.m_mode
77 && m_layerSet == aOther.m_layerSet
78 && m_customName == aOther.m_customName
84 && m_drill == aOther.m_drill
86}
87
88
89bool PADSTACK::Deserialize( const google::protobuf::Any& aContainer )
90{
91 using namespace kiapi::board::types;
92 PadStack padstack;
93
94 if( !aContainer.UnpackTo( &padstack ) )
95 return false;
96
97 m_mode = FromProtoEnum<MODE>( padstack.type() );
98
99 // TODO
100 m_layerSet.reset();
101
102 m_orientation = EDA_ANGLE( padstack.angle().value_degrees(), DEGREES_T );
103
104 Drill().size = kiapi::common::UnpackVector2( padstack.drill_diameter() );
105 Drill().start = FromProtoEnum<PCB_LAYER_ID>( padstack.start_layer() );
106 Drill().end = FromProtoEnum<PCB_LAYER_ID>( padstack.end_layer() );
107
108 // We don't yet support complex padstacks
109 if( padstack.layers_size() == 1 )
110 {
111 const PadStackLayer& layer = padstack.layers( 0 );
112 Size() = kiapi::common::UnpackVector2( layer.size() );
113 SetLayerSet( kiapi::board::UnpackLayerSet( layer.layers() ) );
114 SetShape( FromProtoEnum<PAD_SHAPE>( layer.shape() ) );
115 SetAnchorShape( FromProtoEnum<PAD_SHAPE>( layer.custom_anchor_shape() ) );
116
118 props.chamfered_rect_ratio = layer.chamfer_ratio();
119 props.round_rect_radius_ratio = layer.corner_rounding_ratio();
120
121 if( layer.chamfered_corners().top_left() )
123
124 if( layer.chamfered_corners().top_right() )
126
127 if( layer.chamfered_corners().bottom_left() )
129
130 if( layer.chamfered_corners().bottom_right() )
132
134 google::protobuf::Any a;
135
136 for( const GraphicShape& shapeProto : layer.custom_shapes() )
137 {
138 a.PackFrom( shapeProto );
139 std::unique_ptr<PCB_SHAPE> shape = std::make_unique<PCB_SHAPE>( m_parent );
140
141 if( shape->Deserialize( a ) )
142 AddPrimitive( shape.release() );
143 }
144 }
145
147 FromProtoEnum<UNCONNECTED_LAYER_MODE>( padstack.unconnected_layer_removal() ) );
148
149 return true;
150}
151
152
153void PADSTACK::Serialize( google::protobuf::Any& aContainer ) const
154{
155 using namespace kiapi::board::types;
156 PadStack padstack;
157
158 padstack.set_type( ToProtoEnum<MODE, PadStackType>( m_mode ) );
159 padstack.set_start_layer( ToProtoEnum<PCB_LAYER_ID, BoardLayer>( StartLayer() ) );
160 padstack.set_end_layer( ToProtoEnum<PCB_LAYER_ID, BoardLayer>( EndLayer() ) );
161 kiapi::common::PackVector2( *padstack.mutable_drill_diameter(), Drill().size );
162 padstack.mutable_angle()->set_value_degrees( m_orientation.AsDegrees() );
163
164 PadStackLayer* stackLayer = padstack.add_layers();
165 kiapi::board::PackLayerSet( *stackLayer->mutable_layers(), LayerSet() );
166 kiapi::common::PackVector2( *stackLayer->mutable_size(), Size() );
167 stackLayer->set_shape( ToProtoEnum<PAD_SHAPE, PadStackShape>( Shape() ) );
168 stackLayer->set_custom_anchor_shape( ToProtoEnum<PAD_SHAPE, PadStackShape>( AnchorShape() ) );
169 stackLayer->set_chamfer_ratio( CopperLayerDefaults().shape.chamfered_rect_ratio );
170 stackLayer->set_corner_rounding_ratio( CopperLayerDefaults().shape.round_rect_radius_ratio );
171
172 google::protobuf::Any a;
173
174 for( const std::shared_ptr<PCB_SHAPE>& shape : Primitives() )
175 {
176 shape->Serialize( a );
177 GraphicShape* s = stackLayer->add_custom_shapes();
178 a.UnpackTo( s );
179 }
180
182 stackLayer->mutable_chamfered_corners()->set_top_left( corners & RECT_CHAMFER_TOP_LEFT );
183 stackLayer->mutable_chamfered_corners()->set_top_right( corners & RECT_CHAMFER_TOP_RIGHT );
184 stackLayer->mutable_chamfered_corners()->set_bottom_left( corners & RECT_CHAMFER_BOTTOM_LEFT );
185 stackLayer->mutable_chamfered_corners()->set_bottom_right( corners & RECT_CHAMFER_BOTTOM_RIGHT );
186
187 padstack.set_unconnected_layer_removal(
188 ToProtoEnum<UNCONNECTED_LAYER_MODE, UnconnectedLayerRemoval>( m_unconnectedLayerMode ) );
189
190 aContainer.PackFrom( padstack );
191}
192
193
194wxString PADSTACK::Name() const
195{
196 // TODO
197 return wxEmptyString;
198}
199
200
202{
203 return m_drill.start;
204}
205
206
208{
209 return m_drill.end;
210}
211
212
214 shape( PAD_SHAPE::CIRCLE ),
215 anchor_shape( PAD_SHAPE::CIRCLE ),
216 round_rect_corner_radius( 0 ),
217 round_rect_radius_ratio( 0.25 ),
218 chamfered_rect_ratio( 0.2 ),
219 chamfered_rect_positions( RECT_NO_CHAMFER )
220{
221}
222
223
225{
226 return shape == aOther.shape && offset == aOther.offset
227 && round_rect_corner_radius == aOther.round_rect_corner_radius
228 && round_rect_radius_ratio == aOther.round_rect_radius_ratio
229 && chamfered_rect_ratio == aOther.chamfered_rect_ratio
230 && chamfered_rect_positions == aOther.chamfered_rect_positions;
231}
232
233
235{
236 return shape == aOther.shape && zone_connection == aOther.zone_connection
237 && thermal_spoke_width == aOther.thermal_spoke_width
238 && thermal_spoke_angle == aOther.thermal_spoke_angle
239 && thermal_gap == aOther.thermal_gap
240 && custom_shapes == aOther.custom_shapes;
241}
242
243
245{
246 return solder_mask_margin == aOther.solder_mask_margin
247 && solder_paste_margin == aOther.solder_paste_margin
248 && solder_paste_margin_ratio == aOther.solder_paste_margin_ratio
249 && has_solder_mask == aOther.has_solder_mask
250 && has_solder_paste == aOther.has_solder_paste;
251}
252
253
255{
256 return size == aOther.size && shape == aOther.shape
257 && start == aOther.start && end == aOther.end;
258}
259
260
262{
264}
265
266
268{
270}
271
272
274{
276}
277
278
280{
282}
283
284
286{
287 return m_drill.shape;
288}
289
290
292{
293 m_drill.shape = aShape;
294}
295
296
298{
300}
301
302
304{
306}
307
308
310{
312}
313
314
316{
318}
319
320
322{
324}
325
326
328{
330}
331
332
334{
336}
337
338
340{
342}
343
344
346{
347 const VECTOR2I& size = Size( aLayer );
348 return KiROUND( std::min( size.x, size.y ) * RoundRectRadiusRatio( aLayer ) );
349}
350
351
352void PADSTACK::SetRoundRectRadius( double aRadius, PCB_LAYER_ID aLayer )
353{
354 const VECTOR2I& size = Size( aLayer );
355 int min_r = std::min( size.x, size.y );
356
357 if( min_r > 0 )
358 SetRoundRectRadiusRatio( aRadius / min_r, aLayer );
359}
360
361
363{
365}
366
367
368void PADSTACK::SetChamferRatio( double aRatio, PCB_LAYER_ID aLayer )
369{
371}
372
373
375{
377}
378
379
380const int& PADSTACK::ChamferPositions( PCB_LAYER_ID aLayer ) const
381{
383}
384
385
386void PADSTACK::SetChamferPositions( int aPositions, PCB_LAYER_ID aLayer )
387{
389}
390
391
392std::optional<int>& PADSTACK::Clearance( PCB_LAYER_ID aLayer )
393{
395}
396
397
398const std::optional<int>& PADSTACK::Clearance( PCB_LAYER_ID aLayer ) const
399{
401}
402
403
404std::optional<int>& PADSTACK::SolderMaskMargin( PCB_LAYER_ID aLayer )
405{
408}
409
410
411const std::optional<int>& PADSTACK::SolderMaskMargin( PCB_LAYER_ID aLayer ) const
412{
415}
416
417
418std::optional<int>& PADSTACK::SolderPasteMargin( PCB_LAYER_ID aLayer )
419{
422}
423
424
425const std::optional<int>& PADSTACK::SolderPasteMargin( PCB_LAYER_ID aLayer ) const
426{
429
430
431std::optional<double>& PADSTACK::SolderPasteMarginRatio( PCB_LAYER_ID aLayer )
432{
435}
436
437
438const std::optional<double>& PADSTACK::SolderPasteMarginRatio( PCB_LAYER_ID aLayer ) const
439{
442
443
444std::optional<ZONE_CONNECTION>& PADSTACK::ZoneConnection( PCB_LAYER_ID aLayer )
445{
447}
448
449
450const std::optional<ZONE_CONNECTION>& PADSTACK::ZoneConnection( PCB_LAYER_ID aLayer ) const
451{
453}
454
455
456std::optional<int>& PADSTACK::ThermalSpokeWidth( PCB_LAYER_ID aLayer )
457{
459}
460
461
462const std::optional<int>& PADSTACK::ThermalSpokeWidth( PCB_LAYER_ID aLayer ) const
463{
465}
466
467
468std::optional<int>& PADSTACK::ThermalGap( PCB_LAYER_ID aLayer )
469{
471}
472
473
474const std::optional<int>& PADSTACK::ThermalGap( PCB_LAYER_ID aLayer ) const
475{
477}
478
479
481{
482 const COPPER_LAYER_PROPS& defaults = CopperLayerDefaults();
483
484 return defaults.thermal_spoke_angle.value_or(
485 ( defaults.shape.shape == PAD_SHAPE::CIRCLE
486 || ( defaults.shape.shape == PAD_SHAPE::CUSTOM
487 && defaults.shape.anchor_shape == PAD_SHAPE::CIRCLE ) )
488 ? ANGLE_45 : ANGLE_90 );
489}
490
491
493{
495}
496
497
498std::vector<std::shared_ptr<PCB_SHAPE>>& PADSTACK::Primitives( PCB_LAYER_ID aLayer )
499{
501}
502
503
504const std::vector<std::shared_ptr<PCB_SHAPE>>& PADSTACK::Primitives( PCB_LAYER_ID aLayer ) const
505{
507}
508
509
511{
512 CopperLayerDefaults().custom_shapes.emplace_back( aShape );
513}
514
515
516void PADSTACK::AppendPrimitives( const std::vector<std::shared_ptr<PCB_SHAPE>>& aPrimitivesList,
517 PCB_LAYER_ID aLayer )
518{
519 for( const std::shared_ptr<PCB_SHAPE>& prim : aPrimitivesList )
520 AddPrimitive( new PCB_SHAPE( *prim ) );
521}
522
523
524void PADSTACK::ReplacePrimitives( const std::vector<std::shared_ptr<PCB_SHAPE>>& aPrimitivesList,
525 PCB_LAYER_ID aLayer )
526{
527 ClearPrimitives( aLayer );
528
529 if( aPrimitivesList.size() )
530 AppendPrimitives( aPrimitivesList, aLayer );
531}
532
533
535{
537}
538
539
540std::optional<bool> PADSTACK::IsTented( PCB_LAYER_ID aSide ) const
541{
542 if( IsFrontLayer( aSide ) )
544
545 if( IsBackLayer( aSide ) )
547
548 wxCHECK_MSG( false, std::nullopt, "IsTented expects a front or back layer" );
549}
550
551
@ NORMAL
Use all material properties from model file.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:79
Represent basic circle geometry with utility geometry functions.
Definition: circle.h:33
double AsDegrees() const
Definition: eda_angle.h:113
A PADSTACK defines the characteristics of a single or multi-layer pad, in the IPC sense of the word.
Definition: padstack.h:117
void SetRoundRectRadius(double aRadius, PCB_LAYER_ID aLayer=F_Cu)
Definition: padstack.cpp:352
bool operator==(const PADSTACK &aOther) const
Definition: padstack.cpp:74
std::optional< int > & Clearance(PCB_LAYER_ID aLayer=F_Cu)
Definition: padstack.cpp:392
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
Definition: padstack.cpp:89
void SetChamferRatio(double aRatio, PCB_LAYER_ID aLayer=F_Cu)
Definition: padstack.cpp:368
std::vector< std::shared_ptr< PCB_SHAPE > > & Primitives(PCB_LAYER_ID aLayer=F_Cu)
Definition: padstack.cpp:498
void SetChamferPositions(int aPositions, PCB_LAYER_ID aLayer=F_Cu)
Definition: padstack.cpp:386
std::optional< double > & SolderPasteMarginRatio(PCB_LAYER_ID aLayer=F_Cu)
Definition: padstack.cpp:431
wxString m_customName
! An override for the IPC-7351 padstack name
Definition: padstack.h:392
void SetAnchorShape(PAD_SHAPE aShape, PCB_LAYER_ID aLayer=F_Cu)
Definition: padstack.cpp:315
void SetRoundRectRadiusRatio(double aRatio, PCB_LAYER_ID aLayer=F_Cu)
Definition: padstack.cpp:339
DRILL_PROPS m_drill
! The primary drill parameters, which also define the start and end layers for through-hole vias and ...
Definition: padstack.h:423
void SetThermalSpokeAngle(EDA_ANGLE aAngle, PCB_LAYER_ID aLayer=F_Cu)
Definition: padstack.cpp:492
UNCONNECTED_LAYER_MODE m_unconnectedLayerMode
Definition: padstack.h:406
void SetUnconnectedLayerMode(UNCONNECTED_LAYER_MODE aMode)
Definition: padstack.h:273
COPPER_LAYER_PROPS & CopperLayerDefaults()
Definition: padstack.h:275
std::optional< bool > IsTented(PCB_LAYER_ID aSide) const
Checks if this padstack is tented (covered in soldermask) on the given side.
Definition: padstack.cpp:540
std::optional< int > & ThermalSpokeWidth(PCB_LAYER_ID aLayer=F_Cu)
Definition: padstack.cpp:456
std::optional< int > & SolderPasteMargin(PCB_LAYER_ID aLayer=F_Cu)
Definition: padstack.cpp:418
std::optional< int > & SolderMaskMargin(PCB_LAYER_ID aLayer=F_Cu)
Definition: padstack.cpp:404
const LSET & LayerSet() const
Definition: padstack.h:246
PADSTACK & operator=(const PADSTACK &aOther)
Definition: padstack.cpp:58
std::unordered_map< PCB_LAYER_ID, COPPER_LAYER_PROPS > m_copperOverrides
! Any entries here override the copper layer settings on the given copper layer.
Definition: padstack.h:419
DRILL_PROPS m_secondaryDrill
! Secondary drill, used to define back-drilling
Definition: padstack.h:426
PAD_SHAPE AnchorShape(PCB_LAYER_ID aLayer=F_Cu) const
Definition: padstack.cpp:309
MASK_LAYER_PROPS m_backMaskProps
! The overrides applied to back outer technical layers
Definition: padstack.h:404
COPPER_LAYER_PROPS m_defaultCopperProps
! The properties applied to copper layers if they aren't overridden
Definition: padstack.h:398
int RoundRectRadius(PCB_LAYER_ID aLayer=F_Cu) const
Definition: padstack.cpp:345
EDA_ANGLE ThermalSpokeAngle(PCB_LAYER_ID aLayer=F_Cu) const
Definition: padstack.cpp:480
void AppendPrimitives(const std::vector< std::shared_ptr< PCB_SHAPE > > &aPrimitivesList, PCB_LAYER_ID aLayer=F_Cu)
Appends a copy of each shape in the given list to this padstack's custom shape list.
Definition: padstack.cpp:516
void AddPrimitive(PCB_SHAPE *aShape, PCB_LAYER_ID aLayer=F_Cu)
Adds a custom shape primitive to the padstack.
Definition: padstack.cpp:510
int & ChamferPositions(PCB_LAYER_ID aLayer=F_Cu)
Definition: padstack.cpp:374
std::optional< int > & ThermalGap(PCB_LAYER_ID aLayer=F_Cu)
Definition: padstack.cpp:468
DRILL_PROPS & Drill()
Definition: padstack.h:266
BOARD_ITEM * m_parent
! The BOARD_ITEM this PADSTACK belongs to; will be used as the parent for owned shapes
Definition: padstack.h:383
PADSTACK(BOARD_ITEM *aParent)
Definition: padstack.cpp:30
LSET m_layerSet
! The board layers that this padstack is active on
Definition: padstack.h:389
double RoundRectRadiusRatio(PCB_LAYER_ID aLayer=F_Cu) const
Definition: padstack.cpp:333
VECTOR2I & TrapezoidDeltaSize(PCB_LAYER_ID aLayer=F_Cu)
Definition: padstack.cpp:321
CUSTOM_SHAPE_ZONE_MODE
Definition: padstack.h:144
PCB_LAYER_ID EndLayer() const
Definition: padstack.cpp:207
PAD_DRILL_SHAPE DrillShape(PCB_LAYER_ID aLayer=F_Cu) const
Definition: padstack.cpp:285
MASK_LAYER_PROPS m_frontMaskProps
! The overrides applied to front outer technical layers
Definition: padstack.h:401
VECTOR2I & Offset(PCB_LAYER_ID aLayer=F_Cu)
Definition: padstack.cpp:297
void ClearPrimitives(PCB_LAYER_ID aLayer=F_Cu)
Definition: padstack.cpp:534
VECTOR2I & Size(PCB_LAYER_ID aLayer=F_Cu)
Definition: padstack.cpp:273
void SetDrillShape(PAD_DRILL_SHAPE aShape, PCB_LAYER_ID aLayer=F_Cu)
Definition: padstack.cpp:291
UNCONNECTED_LAYER_MODE
! Whether or not to remove the copper shape for unconnected layers
Definition: padstack.h:137
PCB_LAYER_ID StartLayer() const
Definition: padstack.cpp:201
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
Definition: padstack.cpp:153
wxString Name() const
! Returns the name of this padstack in IPC-7351 format
Definition: padstack.cpp:194
double ChamferRatio(PCB_LAYER_ID aLayer=F_Cu) const
Definition: padstack.cpp:362
PAD_SHAPE Shape(PCB_LAYER_ID aLayer=F_Cu) const
Definition: padstack.cpp:261
void ReplacePrimitives(const std::vector< std::shared_ptr< PCB_SHAPE > > &aPrimitivesList, PCB_LAYER_ID aLayer=F_Cu)
Clears the existing primitive list (freeing the owned shapes) and adds copies of the given shapes to ...
Definition: padstack.cpp:524
void SetLayerSet(const LSET &aSet)
Definition: padstack.h:248
std::optional< ZONE_CONNECTION > & ZoneConnection(PCB_LAYER_ID aLayer=F_Cu)
Definition: padstack.cpp:444
MODE m_mode
! The copper layer variation mode this padstack is in
Definition: padstack.h:386
void SetShape(PAD_SHAPE aShape, PCB_LAYER_ID aLayer=F_Cu)
Definition: padstack.cpp:267
EDA_ANGLE m_orientation
! The rotation of the pad relative to an outer reference frame
Definition: padstack.h:395
static constexpr EDA_ANGLE ANGLE_0
Definition: eda_angle.h:401
static constexpr EDA_ANGLE ANGLE_90
Definition: eda_angle.h:403
@ DEGREES_T
Definition: eda_angle.h:31
static constexpr EDA_ANGLE ANGLE_45
Definition: eda_angle.h:402
bool IsFrontLayer(PCB_LAYER_ID aLayerId)
Layer classification: check if it's a front layer.
Definition: layer_ids.h:605
bool IsBackLayer(PCB_LAYER_ID aLayerId)
Layer classification: check if it's a back layer.
Definition: layer_ids.h:628
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:60
@ B_Cu
Definition: layer_ids.h:95
@ UNDEFINED_LAYER
Definition: layer_ids.h:61
@ F_Cu
Definition: layer_ids.h:64
void PackLayerSet(google::protobuf::RepeatedField< int > &aOutput, const LSET &aLayerSet)
LSET UnpackLayerSet(const google::protobuf::RepeatedField< int > &aProtoLayerSet)
void PackVector2(kiapi::common::types::Vector2 &aOutput, const VECTOR2I aInput)
Definition: api_utils.cpp:69
VECTOR2I UnpackVector2(const types::Vector2 &aInput)
Definition: api_utils.cpp:75
PAD_DRILL_SHAPE
The set of pad drill shapes, used with PAD::{Set,Get}DrillShape()
Definition: padstack.h:63
PAD_SHAPE
The set of pad shapes, used with PAD::{Set,Get}Shape()
Definition: padstack.h:46
#define IMPLEMENT_ENUM_TO_WXANY(type)
Definition: property.h:763
The features of a padstack that can vary between copper layers All parameters are optional; leaving t...
Definition: padstack.h:193
std::optional< ZONE_CONNECTION > zone_connection
Definition: padstack.h:195
std::optional< int > thermal_spoke_width
Definition: padstack.h:196
std::vector< std::shared_ptr< PCB_SHAPE > > custom_shapes
Definition: padstack.h:205
bool operator==(const COPPER_LAYER_PROPS &aOther) const
Definition: padstack.cpp:234
std::optional< EDA_ANGLE > thermal_spoke_angle
Definition: padstack.h:197
std::optional< int > clearance
Definition: padstack.h:199
std::optional< int > thermal_gap
Definition: padstack.h:198
! The properties of a padstack drill. Drill position is always the pad position (origin).
Definition: padstack.h:225
PCB_LAYER_ID start
Definition: padstack.h:228
PCB_LAYER_ID end
Definition: padstack.h:229
bool operator==(const DRILL_PROPS &aOther) const
Definition: padstack.cpp:254
VECTOR2I size
Drill diameter (x == y) or slot dimensions (x != y)
Definition: padstack.h:226
PAD_DRILL_SHAPE shape
Definition: padstack.h:227
! The features of a padstack that can vary on outer layers.
Definition: padstack.h:213
bool operator==(const MASK_LAYER_PROPS &aOther) const
Definition: padstack.cpp:244
std::optional< int > solder_mask_margin
Definition: padstack.h:214
std::optional< int > solder_paste_margin
Definition: padstack.h:215
std::optional< double > solder_paste_margin_ratio
Definition: padstack.h:216
std::optional< bool > has_solder_mask
True if this outer layer has mask (is not tented)
Definition: padstack.h:217
std::optional< bool > has_solder_paste
True if this outer layer has solder paste.
Definition: padstack.h:218
! The set of properties that define a pad's shape on a given layer
Definition: padstack.h:151
VECTOR2I trapezoid_delta_size
Delta for PAD_SHAPE::TRAPEZOID; half the delta squeezes one end and half expands the other.
Definition: padstack.h:174
double round_rect_corner_radius
Definition: padstack.h:165
VECTOR2I offset
Offset of the shape center from the pad center.
Definition: padstack.h:163
bool operator==(const SHAPE_PROPS &aOther) const
Definition: padstack.cpp:224
VECTOR2I size
Size of the shape, or of the anchor pad for custom shape pads.
Definition: padstack.h:154
double chamfered_rect_ratio
Size of chamfer: ratio of smallest of X,Y size.
Definition: padstack.h:167
double round_rect_radius_ratio
Definition: padstack.h:166
PAD_SHAPE shape
Shape of the pad.
Definition: padstack.h:152
PAD_SHAPE anchor_shape
Shape of the anchor when shape == PAD_SHAPE::CUSTOM.
Definition: padstack.h:153
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:121