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 )
 
 
  148    bool copperMatches = 
true;
 
  154                    copperMatches = 
false;
 
  157    return copperMatches;
 
 
  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 ) )
 
  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() )
 
  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() )
 
  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();
 
  385    stackLayer->set_custom_anchor_shape(
 
  388    stackLayer->set_chamfer_ratio( 
CopperLayer( aLayer ).shape.chamfered_rect_ratio );
 
  389    stackLayer->set_corner_rounding_ratio( 
CopperLayer( aLayer ).shape.round_rect_radius_ratio );
 
  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;
 
  431    padstack.mutable_angle()->set_value_degrees( 
m_orientation.AsDegrees() );
 
  433    DrillProperties* drill = padstack.mutable_drill();
 
  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();
 
  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!" );
 
 
  803                     []( 
const std::shared_ptr<PCB_SHAPE>& aFirst,
 
  804                         const std::shared_ptr<PCB_SHAPE>& aSecond )
 
  806                         return *aFirst == *aSecond;
 
 
  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" ),
 
  996        if( 
board && !
board->GetEnabledLayers().Contains( boardCuLayer ) )
 
 1003            if( !
board->IsFootprintHolder() )
 
 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 );
 
 
 1332    for( 
const std::shared_ptr<PCB_SHAPE>& prim : aPrimitivesList )
 
 
 1342    if( aPrimitivesList.size() )
 
 
types::KiCadObjectType ToProtoEnum(KICAD_T aValue)
 
KICAD_T FromProtoEnum(types::KiCadObjectType aValue)
 
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 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.
 
virtual void SetParent(EDA_ITEM *aParent)
 
LSET is a set of PCB_LAYER_IDs.
 
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
 
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)
 
@ NORMAL
Padstack for a footprint pad.
 
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)
 
bool operator==(const MASK_LAYER_PROPS &aOther) const
 
std::optional< int > solder_mask_margin
 
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.
 
! 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.
 
VECTOR2< int32_t > VECTOR2I