26#include <api/board/board_types.pb.h>
29#include <magic_enum.hpp>
66 for( std::shared_ptr<PCB_SHAPE>& shape :
CopperLayer( aLayer ).custom_shapes )
103 if( shape == PAD_SHAPE::CUSTOM )
109 SetShape( PAD_SHAPE::RECTANGLE, aLayer );
148 bool copperMatches =
true;
154 copperMatches =
false;
157 return copperMatches;
164 PCB_LAYER_ID layer = FromProtoEnum<PCB_LAYER_ID, BoardLayer>( aProto.layer() );
173 SetShape( FromProtoEnum<PAD_SHAPE>( aProto.shape() ), layer );
175 SetAnchorShape( FromProtoEnum<PAD_SHAPE>( aProto.custom_anchor_shape() ), layer );
181 if(
Shape( layer ) == PAD_SHAPE::TRAPEZOID && aProto.has_trapezoid_delta() )
184 if( aProto.chamfered_corners().top_left() )
187 if( aProto.chamfered_corners().top_right() )
190 if( aProto.chamfered_corners().bottom_left() )
193 if( aProto.chamfered_corners().bottom_right() )
197 google::protobuf::Any a;
199 for(
const BoardGraphicShape& shapeProto : aProto.custom_shapes() )
201 a.PackFrom( shapeProto );
202 std::unique_ptr<PCB_SHAPE> shape = std::make_unique<PCB_SHAPE>(
m_parent );
204 if( shape->Deserialize( a ) )
217 auto unpackOptional = []<
typename ProtoEnum>(
const ProtoEnum& aProto,
218 std::optional<bool>& aDest, ProtoEnum aTrueValue,
219 ProtoEnum aFalseValue )
221 if( aProto == aTrueValue )
223 else if( aProto == aFalseValue )
226 aDest = std::nullopt;
229 if( !aContainer.UnpackTo( &padstack ) )
232 m_mode = FromProtoEnum<MODE>( padstack.type() );
237 Drill().
start = FromProtoEnum<PCB_LAYER_ID>( padstack.drill().start_layer() );
238 Drill().
end = FromProtoEnum<PCB_LAYER_ID>( padstack.drill().end_layer() );
239 unpackOptional( padstack.drill().capped(),
Drill().is_capped, VDCM_CAPPED, VDCM_UNCAPPED );
240 unpackOptional( padstack.drill().filled(),
Drill().is_filled, VDFM_FILLED, VDFM_UNFILLED );
242 for(
const PadStackLayer& layer : padstack.copper_layers() )
251 if( padstack.has_zone_settings() )
254 FromProtoEnum<ZONE_CONNECTION>( padstack.zone_settings().zone_connection() );
256 if( padstack.zone_settings().has_thermal_spokes() )
258 const ThermalSpokeSettings& thermals = padstack.zone_settings().thermal_spokes();
260 if( thermals.has_gap() )
263 if( thermals.has_width() )
276 FromProtoEnum<UNCONNECTED_LAYER_MODE>( padstack.unconnected_layer_removal() ) );
278 unpackOptional( padstack.front_outer_layers().solder_mask_mode(),
281 unpackOptional( padstack.back_outer_layers().solder_mask_mode(),
284 unpackOptional( padstack.front_outer_layers().covering_mode(),
FrontOuterLayers().has_covering,
285 VCM_COVERED, VCM_UNCOVERED );
287 unpackOptional( padstack.back_outer_layers().covering_mode(),
BackOuterLayers().has_covering,
288 VCM_COVERED, VCM_UNCOVERED );
290 unpackOptional( padstack.front_outer_layers().plugging_mode(),
FrontOuterLayers().has_plugging,
291 VPM_PLUGGED, VPM_UNPLUGGED );
293 unpackOptional( padstack.back_outer_layers().plugging_mode(),
BackOuterLayers().has_plugging,
294 VPM_PLUGGED, VPM_UNPLUGGED );
296 unpackOptional( padstack.front_outer_layers().solder_paste_mode(),
299 unpackOptional( padstack.back_outer_layers().solder_paste_mode(),
302 if( padstack.front_outer_layers().has_solder_mask_settings()
303 && padstack.front_outer_layers().solder_mask_settings().has_solder_mask_margin() )
306 padstack.front_outer_layers().solder_mask_settings().solder_mask_margin().value_nm();
313 if( padstack.back_outer_layers().has_solder_mask_settings()
314 && padstack.back_outer_layers().solder_mask_settings().has_solder_mask_margin() )
317 padstack.back_outer_layers().solder_mask_settings().solder_mask_margin().value_nm();
324 if( padstack.front_outer_layers().has_solder_paste_settings()
325 && padstack.front_outer_layers().solder_paste_settings().has_solder_paste_margin() )
328 padstack.front_outer_layers().solder_paste_settings().solder_paste_margin().value_nm();
335 if( padstack.back_outer_layers().has_solder_paste_settings()
336 && padstack.back_outer_layers().solder_paste_settings().has_solder_paste_margin() )
339 padstack.back_outer_layers().solder_paste_settings().solder_paste_margin().value_nm();
346 if( padstack.front_outer_layers().has_solder_paste_settings()
347 && padstack.front_outer_layers().solder_paste_settings().has_solder_paste_margin_ratio() )
350 padstack.front_outer_layers().solder_paste_settings().solder_paste_margin_ratio().value();
357 if( padstack.back_outer_layers().has_solder_paste_settings()
358 && padstack.back_outer_layers().solder_paste_settings().has_solder_paste_margin_ratio() )
361 padstack.back_outer_layers().solder_paste_settings().solder_paste_margin_ratio().value();
377 PadStackLayer* stackLayer = aProto.add_copper_layers();
379 stackLayer->set_layer( ToProtoEnum<PCB_LAYER_ID, BoardLayer>( aLayer ) );
383 stackLayer->set_shape( ToProtoEnum<PAD_SHAPE, PadStackShape>(
Shape( aLayer ) ) );
385 stackLayer->set_custom_anchor_shape(
386 ToProtoEnum<PAD_SHAPE, PadStackShape>(
AnchorShape( aLayer ) ) );
388 stackLayer->set_chamfer_ratio(
CopperLayer( aLayer ).shape.chamfered_rect_ratio );
389 stackLayer->set_corner_rounding_ratio(
CopperLayer( aLayer ).shape.round_rect_radius_ratio );
391 if(
Shape( aLayer ) == PAD_SHAPE::TRAPEZOID )
397 google::protobuf::Any a;
399 for(
const std::shared_ptr<PCB_SHAPE>& shape :
Primitives( aLayer ) )
401 shape->Serialize( a );
402 BoardGraphicShape* s = stackLayer->add_custom_shapes();
419 auto packOptional = []<
typename ProtoEnum>(
const std::optional<bool>& aVal, ProtoEnum aTrueVal,
421 ProtoEnum aNullVal ) -> ProtoEnum
423 if( aVal.has_value() )
424 return *aVal ? aTrueVal : aFalseVal;
429 padstack.set_type( ToProtoEnum<MODE, PadStackType>(
m_mode ) );
433 DrillProperties* drill = padstack.mutable_drill();
434 drill->set_start_layer( ToProtoEnum<PCB_LAYER_ID, BoardLayer>(
StartLayer() ) );
435 drill->set_end_layer( ToProtoEnum<PCB_LAYER_ID, BoardLayer>(
EndLayer() ) );
437 packOptional(
Drill().is_filled, VDFM_FILLED, VDFM_UNFILLED, VDFM_FROM_DESIGN_RULES ) );
440 packOptional(
Drill().is_capped, VDCM_CAPPED, VDCM_UNCAPPED, VDCM_FROM_DESIGN_RULES ) );
449 ZoneConnectionSettings* zoneSettings = padstack.mutable_zone_settings();
450 ThermalSpokeSettings* thermalSettings = zoneSettings->mutable_thermal_spokes();
454 zoneSettings->set_zone_connection( ToProtoEnum<ZONE_CONNECTION, ZoneConnectionStyle>(
459 thermalSettings->mutable_width()->set_value_nm( *width );
462 thermalSettings->mutable_gap()->set_value_nm( *gap );
466 padstack.set_unconnected_layer_removal(
469 PadStackOuterLayer* frontOuter = padstack.mutable_front_outer_layers();
470 PadStackOuterLayer* backOuter = padstack.mutable_back_outer_layers();
472 frontOuter->set_solder_mask_mode( packOptional(
FrontOuterLayers().has_solder_mask, SMM_MASKED,
473 SMM_UNMASKED, SMM_FROM_DESIGN_RULES ) );
475 backOuter->set_solder_mask_mode( packOptional(
BackOuterLayers().has_solder_mask, SMM_MASKED,
476 SMM_UNMASKED, SMM_FROM_DESIGN_RULES ) );
478 frontOuter->set_plugging_mode( packOptional(
FrontOuterLayers().has_plugging, VPM_PLUGGED,
479 VPM_UNPLUGGED, VPM_FROM_DESIGN_RULES ) );
481 backOuter->set_plugging_mode( packOptional(
BackOuterLayers().has_plugging, VPM_PLUGGED,
482 VPM_UNPLUGGED, VPM_FROM_DESIGN_RULES ) );
484 frontOuter->set_covering_mode( packOptional(
FrontOuterLayers().has_covering, VCM_COVERED,
485 VCM_UNCOVERED, VCM_FROM_DESIGN_RULES ) );
487 backOuter->set_covering_mode( packOptional(
BackOuterLayers().has_covering, VCM_COVERED,
488 VCM_UNCOVERED, VCM_FROM_DESIGN_RULES ) );
490 frontOuter->set_solder_paste_mode( packOptional(
FrontOuterLayers().has_solder_paste, SPM_PASTE,
491 SPM_NO_PASTE, SPM_FROM_DESIGN_RULES ) );
493 backOuter->set_solder_paste_mode( packOptional(
BackOuterLayers().has_solder_paste, SPM_PASTE,
494 SPM_NO_PASTE, SPM_FROM_DESIGN_RULES ) );
498 frontOuter->mutable_solder_mask_settings()->mutable_solder_mask_margin()->set_value_nm(
504 backOuter->mutable_solder_mask_settings()->mutable_solder_mask_margin()->set_value_nm(
510 frontOuter->mutable_solder_paste_settings()->mutable_solder_paste_margin()->set_value_nm(
516 backOuter->mutable_solder_paste_settings()->mutable_solder_paste_margin()->set_value_nm(
522 frontOuter->mutable_solder_paste_settings()->mutable_solder_paste_margin_ratio()->set_value(
528 backOuter->mutable_solder_paste_settings()->mutable_solder_paste_margin_ratio()->set_value(
532 aContainer.PackFrom( padstack );
540 auto compareCopperProps =
543 if( ( diff =
static_cast<int>( aPadstackRef->
Shape( aLayer ) ) -
544 static_cast<int>( aPadstackCmp->
Shape( aLayer ) ) ) != 0 )
547 if( ( diff = aPadstackRef->
Size( aLayer ).
x - aPadstackCmp->
Size( aLayer ).
x ) != 0 )
550 if( ( diff = aPadstackRef->
Size( aLayer ).
y - aPadstackCmp->
Size( aLayer ).
y ) != 0 )
553 if( ( diff = aPadstackRef->
Offset( aLayer ).
x
554 - aPadstackCmp->
Offset( aLayer ).
x ) != 0 )
557 if( ( diff = aPadstackRef->
Offset( aLayer ).
y
558 - aPadstackCmp->
Offset( aLayer ).
y ) != 0 )
590 if( ( diff =
static_cast<int>( aPadstackRef->
Primitives( aLayer ).size() ) -
591 static_cast<int>( aPadstackCmp->
Primitives( aLayer ).size() ) ) != 0 )
603 if( ( diff =
static_cast<int>( aPadstackRef->
DrillShape() ) -
604 static_cast<int>( aPadstackCmp->
DrillShape() ) ) != 0 )
619 double similarity = 1.0;
624 if(
Shape( aLayer ) != aOther.
Shape( aLayer ) )
627 if(
Size( aLayer ) != aOther.
Size( aLayer ) )
704 return wxEmptyString;
730 if( aCopperLayerCount > 2 )
732 int innerCount = ( aCopperLayerCount - 2 );
733 int halfInnerLayerCount = innerCount / 2;
742 magic_enum::enum_cast<PCB_LAYER_ID>( lastInner - ( layer -
In1_Cu ) );
743 wxCHECK2_MSG( conjugate.has_value() &&
m_copperProps.contains( conjugate.value() ),
744 continue,
"Invalid inner layer conjugate!" );
763 round_rect_corner_radius( 0 ),
764 round_rect_radius_ratio( 0.25 ),
765 chamfered_rect_ratio( 0.2 ),
773 return shape == aOther.
shape && offset == aOther.
offset
783 if( shape != aOther.
shape )
801 if( !std::equal( custom_shapes.begin(), custom_shapes.end(),
803 [](
const std::shared_ptr<PCB_SHAPE>& aFirst,
804 const std::shared_ptr<PCB_SHAPE>& aSecond )
806 return *aFirst == *aSecond;
828 return size == aOther.
size && shape == aOther.
shape
842 [](
const auto& aEntry )
844 const auto& [key, value] = aEntry;
878 parentPad->SetDirty();
922 std::vector<PCB_LAYER_ID> layers;
926 layers.push_back( layer );
936 switch(
static_cast<int>( aLayer ) )
987 wxString::Format( wxT(
"Unhandled layer %d in PADSTACK::EffectiveLayerFor" ),
1004 wxFAIL_MSG(
"Asked for inner padstack layer not present on the board" );
1009 return boardCuLayer;
1029 wxT(
"Expected both padstacks to have the same board copper layer count" ) );
1055 wxString::Format( wxT(
"Attempt to retrieve layer %d from a padstack that does not contain it" ),
1159 int min_r = std::min( size.
x, size.
y );
1289 return ( defaults.
shape.
shape == PAD_SHAPE::CIRCLE
1290 || ( defaults.
shape.
shape == PAD_SHAPE::CUSTOM
1332 for(
const std::shared_ptr<PCB_SHAPE>& prim : aPrimitivesList )
1342 if( aPrimitivesList.size() )
1361 wxCHECK_MSG(
false, std::nullopt,
"IsTented expects a front or back layer" );
1372 wxCHECK_MSG(
false, std::nullopt,
"IsCovered expects a front or back layer" );
1383 wxCHECK_MSG(
false, std::nullopt,
"IsPlugged expects a front or back layer" );
@ NORMAL
Use all material properties from model file.
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
int compare(const BASE_SET &other) const
BASE_SET & set(size_t pos)
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
virtual int BoardCopperLayerCount() const
Return the total number of copper layers for the board that this item resides on.
Information pertinent to a Pcbnew printed circuit board.
bool IsFootprintHolder() const
Find out if the board is being used to hold a single footprint for editing/viewing.
const LSET & GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
Represent basic circle geometry with utility geometry functions.
virtual void SetParent(EDA_ITEM *aParent)
LSET is a set of PCB_LAYER_IDs.
bool Contains(PCB_LAYER_ID aLayer) const
See if the layer set contains a PCB layer.
A PADSTACK defines the characteristics of a single or multi-layer pad, in the IPC sense of the word.
std::optional< bool > IsFilled() const
bool operator==(const PADSTACK &aOther) const
CUSTOM_SHAPE_ZONE_MODE CustomShapeInZoneMode() const
std::optional< int > & Clearance(PCB_LAYER_ID aLayer=F_Cu)
void AddPrimitive(PCB_SHAPE *aShape, PCB_LAYER_ID aLayer)
Adds a custom shape primitive to the padstack.
void ReplacePrimitives(const std::vector< std::shared_ptr< PCB_SHAPE > > &aPrimitivesList, PCB_LAYER_ID aLayer)
Clears the existing primitive list (freeing the owned shapes) and adds copies of the given shapes to ...
void packCopperLayer(PCB_LAYER_ID aLayer, kiapi::board::types::PadStack &aProto) const
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
MASK_LAYER_PROPS & FrontOuterLayers()
double Similarity(const PADSTACK &aOther) const
Return a measure of how likely the other object is to represent the same object.
int RoundRectRadius(PCB_LAYER_ID aLayer) const
void SetDrillShape(PAD_DRILL_SHAPE aShape)
std::optional< double > & SolderPasteMarginRatio(PCB_LAYER_ID aLayer=F_Cu)
wxString m_customName
! An override for the IPC-7351 padstack name
DRILL_PROPS m_drill
! The primary drill parameters, which also define the start and end layers for through-hole vias and ...
void ForEachUniqueLayer(const std::function< void(PCB_LAYER_ID)> &aMethod) const
Runs the given callable for each active unique copper layer in this padstack, meaning F_Cu for MODE::...
void SetThermalSpokeAngle(EDA_ANGLE aAngle, PCB_LAYER_ID aLayer=F_Cu)
void SetRoundRectRadiusRatio(double aRatio, PCB_LAYER_ID aLayer)
UNCONNECTED_LAYER_MODE m_unconnectedLayerMode
void ClearPrimitives(PCB_LAYER_ID aLayer)
void SetUnconnectedLayerMode(UNCONNECTED_LAYER_MODE aMode)
std::optional< bool > IsTented(PCB_LAYER_ID aSide) const
Checks if this padstack is tented (covered in soldermask) on the given side.
std::optional< int > & ThermalSpokeWidth(PCB_LAYER_ID aLayer=F_Cu)
std::optional< int > & SolderPasteMargin(PCB_LAYER_ID aLayer=F_Cu)
std::optional< int > & SolderMaskMargin(PCB_LAYER_ID aLayer=F_Cu)
void SetChamferRatio(double aRatio, PCB_LAYER_ID aLayer)
const LSET & LayerSet() const
PCB_LAYER_ID EffectiveLayerFor(PCB_LAYER_ID aLayer) const
Determines which geometry layer should be used for the given input layer.
PADSTACK & operator=(const PADSTACK &aOther)
void SetShape(PAD_SHAPE aShape, PCB_LAYER_ID aLayer)
EDA_ANGLE DefaultThermalSpokeAngleForShape(PCB_LAYER_ID aLayer=F_Cu) const
VECTOR2I & TrapezoidDeltaSize(PCB_LAYER_ID aLayer)
DRILL_PROPS m_secondaryDrill
! Secondary drill, used to define back-drilling
VECTOR2I & Offset(PCB_LAYER_ID aLayer)
MASK_LAYER_PROPS m_backMaskProps
! The overrides applied to back outer technical layers
COPPER_LAYER_PROPS & CopperLayer(PCB_LAYER_ID aLayer)
EDA_ANGLE ThermalSpokeAngle(PCB_LAYER_ID aLayer=F_Cu) const
void FlipLayers(int aCopperLayerCount)
Flips the padstack layers in the case that the pad's parent footprint is flipped to the other side of...
CUSTOM_SHAPE_ZONE_MODE m_customShapeInZoneMode
How to build the custom shape in zone, to create the clearance area: CUSTOM_SHAPE_ZONE_MODE::OUTLINE ...
bool unpackCopperLayer(const kiapi::board::types::PadStackLayer &aProto)
PAD_DRILL_SHAPE DrillShape() const
void SetChamferPositions(int aPositions, PCB_LAYER_ID aLayer)
void SetRoundRectRadius(double aRadius, PCB_LAYER_ID aLayer)
std::optional< bool > IsPlugged(PCB_LAYER_ID aSide) const
LSET RelevantShapeLayers(const PADSTACK &aOther) const
Returns the set of layers that must be considered if checking one padstack against another.
std::optional< int > & ThermalGap(PCB_LAYER_ID aLayer=F_Cu)
PAD_SHAPE Shape(PCB_LAYER_ID aLayer) const
void SetAnchorShape(PAD_SHAPE aShape, PCB_LAYER_ID aLayer)
BOARD_ITEM * m_parent
! The BOARD_ITEM this PADSTACK belongs to; will be used as the parent for owned shapes
PADSTACK(BOARD_ITEM *aParent)
std::optional< bool > IsCapped() const
std::vector< PCB_LAYER_ID > UniqueLayers() const
LSET m_layerSet
! The board layers that this padstack is active on
std::unordered_map< PCB_LAYER_ID, COPPER_LAYER_PROPS > m_copperProps
! The properties applied to copper layers if they aren't overridden
static int Compare(const PADSTACK *aPadstackRef, const PADSTACK *aPadstackCmp)
Compare two padstacks and return 0 if they are equal.
PCB_LAYER_ID EndLayer() const
std::optional< bool > IsCovered(PCB_LAYER_ID aSide) const
int & ChamferPositions(PCB_LAYER_ID aLayer)
MASK_LAYER_PROPS m_frontMaskProps
! The overrides applied to front outer technical layers
const VECTOR2I & Size(PCB_LAYER_ID aLayer) const
MODE
! Copper geometry mode: controls how many unique copper layer shapes this padstack has
@ NORMAL
Shape is the same on all layers.
@ CUSTOM
Shapes can be defined on arbitrary layers.
@ FRONT_INNER_BACK
Up to three shapes can be defined (F_Cu, inner copper layers, B_Cu)
void AppendPrimitives(const std::vector< std::shared_ptr< PCB_SHAPE > > &aPrimitivesList, PCB_LAYER_ID aLayer)
Appends a copy of each shape in the given list to this padstack's custom shape list.
double RoundRectRadiusRatio(PCB_LAYER_ID aLayer) const
UNCONNECTED_LAYER_MODE
! Whether or not to remove the copper shape for unconnected layers
PCB_LAYER_ID StartLayer() const
PAD_SHAPE AnchorShape(PCB_LAYER_ID aLayer) const
MASK_LAYER_PROPS & BackOuterLayers()
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
wxString Name() const
! Returns the name of this padstack in IPC-7351 format
void SetSize(const VECTOR2I &aSize, PCB_LAYER_ID aLayer)
double ChamferRatio(PCB_LAYER_ID aLayer) const
static constexpr PCB_LAYER_ID ALL_LAYERS
! Temporary layer identifier to identify code that is not padstack-aware
EDA_ANGLE GetOrientation() const
static constexpr PCB_LAYER_ID INNER_LAYERS
! The layer identifier to use for "inner layers" on top/inner/bottom padstacks
void SetLayerSet(const LSET &aSet)
std::optional< ZONE_CONNECTION > & ZoneConnection(PCB_LAYER_ID aLayer=F_Cu)
MODE m_mode
! The copper layer variation mode this padstack is in
EDA_ANGLE m_orientation
! The rotation of the pad relative to an outer reference frame
std::vector< std::shared_ptr< PCB_SHAPE > > & Primitives(PCB_LAYER_ID aLayer)
@ RECT_CHAMFER_BOTTOM_RIGHT
@ RECT_CHAMFER_BOTTOM_LEFT
static constexpr EDA_ANGLE ANGLE_0
static constexpr EDA_ANGLE ANGLE_90
static constexpr EDA_ANGLE ANGLE_45
@ LAYER_PAD_FR_NETNAMES
Additional netnames layers (not associated with a PCB layer).
bool IsPadCopperLayer(int aLayer)
bool IsFrontLayer(PCB_LAYER_ID aLayerId)
Layer classification: check if it's a front layer.
bool IsBackLayer(PCB_LAYER_ID aLayerId)
Layer classification: check if it's a back layer.
bool IsClearanceLayer(int aLayer)
bool IsCopperLayer(int aLayerId)
Test whether a layer is a copper layer.
@ LAYER_LOCKED_ITEM_SHADOW
Shadow layer for locked items.
@ LAYER_PAD_COPPER_START
Virtual layers for pad copper on a given copper layer.
@ LAYER_PADS
Meta control for all pads opacity/visibility (color ignored).
@ LAYER_PAD_PLATEDHOLES
to draw pad holes (plated)
@ LAYER_VIA_COPPER_START
Virtual layers for via copper on a given copper layer.
@ LAYER_CLEARANCE_START
Virtual layers for pad/via/track clearance outlines for a given copper layer.
@ LAYER_VIA_HOLES
Draw via holes (pad holes do not use this layer).
bool IsViaCopperLayer(int aLayer)
PCB_LAYER_ID
A quick note on layer IDs:
PCB_LAYER_ID ToLAYER_ID(int aLayer)
This file contains miscellaneous commonly used macros and functions.
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
void PackLayerSet(google::protobuf::RepeatedField< int > &aOutput, const LSET &aLayerSet)
LSET UnpackLayerSet(const google::protobuf::RepeatedField< int > &aProtoLayerSet)
KICOMMON_API VECTOR2I UnpackVector2(const types::Vector2 &aInput)
KICOMMON_API void PackVector2(types::Vector2 &aOutput, const VECTOR2I &aInput)
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
PAD_DRILL_SHAPE
The set of pad drill shapes, used with PAD::{Set,Get}DrillShape()
PAD_SHAPE
The set of pad shapes, used with PAD::{Set,Get}Shape()
#define IMPLEMENT_ENUM_TO_WXANY(type)
The features of a padstack that can vary between copper layers All parameters are optional; leaving t...
std::optional< ZONE_CONNECTION > zone_connection
std::optional< int > thermal_spoke_width
std::vector< std::shared_ptr< PCB_SHAPE > > custom_shapes
bool operator==(const COPPER_LAYER_PROPS &aOther) const
std::optional< EDA_ANGLE > thermal_spoke_angle
std::optional< int > clearance
std::optional< int > thermal_gap
! The properties of a padstack drill. Drill position is always the pad position (origin).
bool operator==(const DRILL_PROPS &aOther) const
VECTOR2I size
Drill diameter (x == y) or slot dimensions (x != y)
std::optional< bool > is_capped
True if the drill hole should be capped.
std::optional< bool > is_filled
True if the drill hole should be filled completely.
! The features of a padstack that can vary on outer layers.
bool operator==(const MASK_LAYER_PROPS &aOther) const
std::optional< int > solder_mask_margin
std::optional< bool > has_covering
True if the pad on this side should have covering.
std::optional< int > solder_paste_margin
std::optional< double > solder_paste_margin_ratio
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.
std::optional< bool > has_plugging
True if the drill hole should be plugged on this side.
! The set of properties that define a pad's shape on a given layer
int chamfered_rect_positions
VECTOR2I trapezoid_delta_size
Delta for PAD_SHAPE::TRAPEZOID; half the delta squeezes one end and half expands the other.
double round_rect_corner_radius
VECTOR2I offset
Offset of the shape center from the pad center.
bool operator==(const SHAPE_PROPS &aOther) const
VECTOR2I size
Size of the shape, or of the anchor pad for custom shape pads.
double chamfered_rect_ratio
Size of chamfer: ratio of smallest of X,Y size.
double round_rect_radius_ratio
PAD_SHAPE shape
Shape of the pad.
PAD_SHAPE anchor_shape
Shape of the anchor when shape == PAD_SHAPE::CUSTOM.