diff --git a/api/proto/board/board_types.proto b/api/proto/board/board_types.proto index 2e0b27de67..ed75c4c595 100644 --- a/api/proto/board/board_types.proto +++ b/api/proto/board/board_types.proto @@ -206,6 +206,9 @@ message PadStackLayer ChamferedRectCorners chamfered_corners = 6; repeated GraphicShape custom_shapes = 7; + + // If shape == PSS_CUSTOM, defines the shape of the anchor (only PSS_CIRCLE and PSS_RECTANGLE supported at present) + PadStackShape custom_anchor_shape = 8; } // A pad stack definition for a multilayer pad or via. diff --git a/pcbnew/api/api_pcb_enums.cpp b/pcbnew/api/api_pcb_enums.cpp index 79b2a94298..382953e8d1 100644 --- a/pcbnew/api/api_pcb_enums.cpp +++ b/pcbnew/api/api_pcb_enums.cpp @@ -160,7 +160,7 @@ VIATYPE FromProtoEnum( types::ViaType aValue ) case types::ViaType::VT_MICRO: return VIATYPE::MICROVIA; default: - wxCHECK_MSG( false, VIATYPE::THROUGH, + wxCHECK_MSG( false, VIATYPE::THROUGH, "Unhandled case in FromProtoEnum" ); } } diff --git a/pcbnew/pad.cpp b/pcbnew/pad.cpp index 16e05f4f01..64786c74b8 100644 --- a/pcbnew/pad.cpp +++ b/pcbnew/pad.cpp @@ -67,7 +67,8 @@ using KIGFX::PCB_RENDER_SETTINGS; PAD::PAD( FOOTPRINT* parent ) : - BOARD_CONNECTED_ITEM( parent, PCB_PAD_T ) + BOARD_CONNECTED_ITEM( parent, PCB_PAD_T ), + m_padStack( this ) { VECTOR2I& drill = m_padStack.Drill().size; VECTOR2I& size = m_padStack.Size(); @@ -105,7 +106,8 @@ PAD::PAD( FOOTPRINT* parent ) : PAD::PAD( const PAD& aOther ) : - BOARD_CONNECTED_ITEM( aOther.GetParent(), PCB_PAD_T ) + BOARD_CONNECTED_ITEM( aOther.GetParent(), PCB_PAD_T ), + m_padStack( this ) { PAD::operator=( aOther ); @@ -655,7 +657,7 @@ void PAD::BuildEffectiveShapes( PCB_LAYER_ID aLayer ) const if( GetShape() == PAD_SHAPE::CUSTOM ) { - for( const std::shared_ptr& primitive : m_editPrimitives ) + for( const std::shared_ptr& primitive : m_padStack.Primitives() ) { if( !primitive->IsProxyItem() ) { @@ -882,7 +884,7 @@ void PAD::Flip( const VECTOR2I& aCentre, bool aFlipLeftRight ) void PAD::FlipPrimitives( bool aFlipLeftRight ) { - for( std::shared_ptr& primitive : m_editPrimitives ) + for( std::shared_ptr& primitive : m_padStack.Primitives() ) primitive->Flip( VECTOR2I( 0, 0 ), aFlipLeftRight ); SetDirty(); @@ -1363,8 +1365,8 @@ int PAD::Compare( const PAD* aPadRef, const PAD* aPadCmp ) if( ( diff = aPadRef->m_padStack.ChamferRatio() - aPadCmp->m_padStack.ChamferRatio() ) != 0 ) return diff; - if( ( diff = static_cast( aPadRef->m_editPrimitives.size() ) - - static_cast( aPadCmp->m_editPrimitives.size() ) ) != 0 ) + if( ( diff = static_cast( aPadRef->m_padStack.Primitives().size() ) - + static_cast( aPadCmp->m_padStack.Primitives().size() ) ) != 0 ) return diff; // @todo: Compare custom pad primitives for pads that have the same number of primitives @@ -2175,7 +2177,7 @@ bool PAD::operator==( const BOARD_ITEM& aOther ) const for( size_t ii = 0; ii < GetPrimitives().size(); ii++ ) { - if( GetPrimitives()[ii] != other.GetPrimitives()[ii] ) + if( *GetPrimitives()[ii] != *other.GetPrimitives()[ii] ) return false; } diff --git a/pcbnew/pad.h b/pcbnew/pad.h index 9cb8dc6565..e9db76940a 100644 --- a/pcbnew/pad.h +++ b/pcbnew/pad.h @@ -316,7 +316,7 @@ public: */ const std::vector>& GetPrimitives() const { - return m_editPrimitives; + return m_padStack.Primitives(); } void Flip( const VECTOR2I& VECTOR2I, bool aFlipLeftRight ) override; @@ -842,11 +842,6 @@ private: VECTOR2I m_pos; // Pad Position on board PADSTACK m_padStack; - /* - * Editing definitions of primitives for custom pad shapes. In local coordinates relative - * to m_Pos (NOT shapePos) at orient 0. - */ - std::vector> m_editPrimitives; // Must be set to true to force rebuild shapes to draw (after geometry change for instance) mutable bool m_shapesDirty; diff --git a/pcbnew/pad_custom_shape_functions.cpp b/pcbnew/pad_custom_shape_functions.cpp index 64cb290609..7d256f80b5 100644 --- a/pcbnew/pad_custom_shape_functions.cpp +++ b/pcbnew/pad_custom_shape_functions.cpp @@ -57,7 +57,7 @@ void PAD::AddPrimitivePoly( const SHAPE_POLY_SET& aPoly, int aThickness, bool aF item->SetPolyShape( poly_outline ); item->SetStroke( STROKE_PARAMS( aThickness, LINE_STYLE::SOLID ) ); item->SetParent( this ); - m_editPrimitives.emplace_back( item ); + m_padStack.AddPrimitive( item ); } SetDirty(); @@ -71,7 +71,7 @@ void PAD::AddPrimitivePoly( const std::vector& aPoly, int aThickness, item->SetPolyPoints( aPoly ); item->SetStroke( STROKE_PARAMS( aThickness, LINE_STYLE::SOLID ) ); item->SetParent( this ); - m_editPrimitives.emplace_back( item ); + m_padStack.AddPrimitive( item ); SetDirty(); } @@ -102,7 +102,7 @@ void PAD::AppendPrimitives( const std::vector>& aPrim void PAD::AddPrimitive( PCB_SHAPE* aPrimitive ) { aPrimitive->SetParent( this ); - m_editPrimitives.emplace_back( aPrimitive ); + m_padStack.AddPrimitive( aPrimitive ); SetDirty(); } @@ -111,8 +111,7 @@ void PAD::AddPrimitive( PCB_SHAPE* aPrimitive ) // clear the basic shapes list and associated data void PAD::DeletePrimitivesList() { - m_editPrimitives.clear(); - + m_padStack.ClearPrimitives(); SetDirty(); } @@ -122,7 +121,7 @@ void PAD::addPadPrimitivesToPolygon( SHAPE_POLY_SET* aMergedPolygon, int aError, { SHAPE_POLY_SET polyset; - for( const std::shared_ptr& primitive : m_editPrimitives ) + for( const std::shared_ptr& primitive : m_padStack.Primitives() ) { if( !primitive->IsProxyItem() ) primitive->TransformShapeToPolygon( polyset, UNDEFINED_LAYER, 0, aError, aErrorLoc ); diff --git a/pcbnew/padstack.cpp b/pcbnew/padstack.cpp index 61ff43991d..3f2d273100 100644 --- a/pcbnew/padstack.cpp +++ b/pcbnew/padstack.cpp @@ -24,9 +24,11 @@ #include #include #include +#include -PADSTACK::PADSTACK() : +PADSTACK::PADSTACK( BOARD_ITEM* aParent ) : + m_parent( aParent ), m_mode( MODE::NORMAL ), m_orientation( ANGLE_0 ), m_unconnectedLayerMode( UNCONNECTED_LAYER_MODE::KEEP_ALL ), @@ -112,6 +114,7 @@ bool PADSTACK::Deserialize( const google::protobuf::Any& aContainer ) Size() = kiapi::common::UnpackVector2( layer.size() ); SetLayerSet( kiapi::board::UnpackLayerSet( layer.layers() ) ); SetShape( FromProtoEnum( layer.shape() ) ); + SetAnchorShape( FromProtoEnum( layer.custom_anchor_shape() ) ); SHAPE_PROPS& props = CopperLayerDefaults().shape; props.chamfered_rect_ratio = layer.chamfer_ratio(); @@ -128,6 +131,18 @@ bool PADSTACK::Deserialize( const google::protobuf::Any& aContainer ) if( layer.chamfered_corners().bottom_right() ) props.chamfered_rect_positions |= RECT_CHAMFER_BOTTOM_RIGHT; + + ClearPrimitives(); + google::protobuf::Any a; + + for( const GraphicShape& shapeProto : layer.custom_shapes() ) + { + a.PackFrom( shapeProto ); + std::unique_ptr shape = std::make_unique( m_parent ); + + if( shape->Deserialize( a ) ) + AddPrimitive( shape.release() ); + } } SetUnconnectedLayerMode( @@ -152,9 +167,19 @@ void PADSTACK::Serialize( google::protobuf::Any& aContainer ) const kiapi::board::PackLayerSet( *stackLayer->mutable_layers(), LayerSet() ); kiapi::common::PackVector2( *stackLayer->mutable_size(), Size() ); stackLayer->set_shape( ToProtoEnum( Shape() ) ); + stackLayer->set_custom_anchor_shape( ToProtoEnum( AnchorShape() ) ); stackLayer->set_chamfer_ratio( CopperLayerDefaults().shape.chamfered_rect_ratio ); stackLayer->set_corner_rounding_ratio( CopperLayerDefaults().shape.round_rect_radius_ratio ); + google::protobuf::Any a; + + for( const std::shared_ptr& shape : Primitives() ) + { + shape->Serialize( a ); + GraphicShape* s = stackLayer->add_custom_shapes(); + a.UnpackTo( s ); + } + const int& corners = CopperLayerDefaults().shape.chamfered_rect_positions; stackLayer->mutable_chamfered_corners()->set_top_left( corners & RECT_CHAMFER_TOP_LEFT ); stackLayer->mutable_chamfered_corners()->set_top_right( corners & RECT_CHAMFER_TOP_RIGHT ); @@ -468,4 +493,46 @@ void PADSTACK::SetThermalSpokeAngle( EDA_ANGLE aAngle, PCB_LAYER_ID aLayer ) } +std::vector>& PADSTACK::Primitives( PCB_LAYER_ID aLayer ) +{ + return CopperLayerDefaults().custom_shapes; +} + + +const std::vector>& PADSTACK::Primitives( PCB_LAYER_ID aLayer ) const +{ + return CopperLayerDefaults().custom_shapes; +} + + +void PADSTACK::AddPrimitive( PCB_SHAPE* aShape, PCB_LAYER_ID aLayer ) +{ + CopperLayerDefaults().custom_shapes.emplace_back( aShape ); +} + + +void PADSTACK::AppendPrimitives( const std::vector>& aPrimitivesList, + PCB_LAYER_ID aLayer ) +{ + for( const std::shared_ptr& prim : aPrimitivesList ) + AddPrimitive( new PCB_SHAPE( *prim ) ); +} + + +void PADSTACK::ReplacePrimitives( const std::vector>& aPrimitivesList, + PCB_LAYER_ID aLayer ) +{ + ClearPrimitives( aLayer ); + + if( aPrimitivesList.size() ) + AppendPrimitives( aPrimitivesList, aLayer ); +} + + +void PADSTACK::ClearPrimitives( PCB_LAYER_ID aLayer ) +{ + CopperLayerDefaults().custom_shapes.clear(); +} + + IMPLEMENT_ENUM_TO_WXANY( PADSTACK::UNCONNECTED_LAYER_MODE ) diff --git a/pcbnew/padstack.h b/pcbnew/padstack.h index cc4faf4250..b6414a5b32 100644 --- a/pcbnew/padstack.h +++ b/pcbnew/padstack.h @@ -32,6 +32,7 @@ #include #include +class BOARD_ITEM; class PCB_SHAPE; @@ -196,6 +197,10 @@ public: std::optional thermal_gap; std::optional clearance; + /* + * Editing definitions of primitives for custom pad shapes. In local coordinates relative + * to m_Pos (NOT shapePos) at orient 0. + */ std::vector> custom_shapes; bool operator==( const COPPER_LAYER_PROPS& aOther ) const; @@ -226,7 +231,7 @@ public: }; public: - PADSTACK(); + PADSTACK( BOARD_ITEM* aParent ); virtual ~PADSTACK() = default; PADSTACK( const PADSTACK& aOther ); PADSTACK& operator=( const PADSTACK &aOther ); @@ -332,8 +337,40 @@ public: EDA_ANGLE ThermalSpokeAngle( PCB_LAYER_ID aLayer = F_Cu ) const; void SetThermalSpokeAngle( EDA_ANGLE aAngle, PCB_LAYER_ID aLayer = F_Cu ); -private: + std::vector>& Primitives( PCB_LAYER_ID aLayer = F_Cu ); + const std::vector>& Primitives( PCB_LAYER_ID aLayer = F_Cu ) const; + /** + * Adds a custom shape primitive to the padstack. + * @param aShape is a shape to add as a custom primitive. Ownership is passed to this PADSTACK. + * @param aLayer is the padstack layer to add to. + */ + void AddPrimitive( PCB_SHAPE* aShape, PCB_LAYER_ID aLayer = F_Cu ); + + /** + * Appends a copy of each shape in the given list to this padstack's custom shape list + * @param aPrimitivesList is a list of shapes to add copies of to this PADSTACK + * @param aLayer is the padstack layer to add to. + */ + void AppendPrimitives( const std::vector>& aPrimitivesList, + PCB_LAYER_ID aLayer = F_Cu ); + + /** + * Clears the existing primitive list (freeing the owned shapes) and adds copies of the given + * shapes to the padstack for the given layer. + * @param aPrimitivesList is a list of shapes to add copies of to this PADSTACK + * @param aLayer is the padstack layer to add to. + */ + void ReplacePrimitives( const std::vector>& aPrimitivesList, + PCB_LAYER_ID aLayer = F_Cu ); + + void ClearPrimitives( PCB_LAYER_ID aLayer = F_Cu ); + +private: + ///! The BOARD_ITEM this PADSTACK belongs to; will be used as the parent for owned shapes + BOARD_ITEM* m_parent; + + ///! The copper layer variation mode this padstack is in MODE m_mode; ///! The board layers that this padstack is active on diff --git a/pcbnew/pcb_track.cpp b/pcbnew/pcb_track.cpp index e48e68e127..ede9bf4d65 100644 --- a/pcbnew/pcb_track.cpp +++ b/pcbnew/pcb_track.cpp @@ -83,7 +83,8 @@ EDA_ITEM* PCB_ARC::Clone() const PCB_VIA::PCB_VIA( BOARD_ITEM* aParent ) : - PCB_TRACK( aParent, PCB_VIA_T ) + PCB_TRACK( aParent, PCB_VIA_T ), + m_padStack( this ) { SetViaType( VIATYPE::THROUGH ); Padstack().Drill().start = F_Cu; @@ -105,7 +106,8 @@ PCB_VIA::PCB_VIA( BOARD_ITEM* aParent ) : PCB_VIA::PCB_VIA( const PCB_VIA& aOther ) : - PCB_TRACK( aOther.GetParent(), PCB_VIA_T ) + PCB_TRACK( aOther.GetParent(), PCB_VIA_T ), + m_padStack( this ) { PCB_VIA::operator=( aOther ); diff --git a/qa/data/pcbnew/padstacks.kicad_pcb b/qa/data/pcbnew/padstacks.kicad_pcb index e26de35707..e294570f3b 100644 --- a/qa/data/pcbnew/padstacks.kicad_pcb +++ b/qa/data/pcbnew/padstacks.kicad_pcb @@ -275,6 +275,7 @@ (at 0 0 90) (size 2 2) (layers "F.Cu" "F.Mask") + (solder_mask_margin 0.45) (uuid "d37584cd-2e2f-40b5-822b-12791118953d") ) ) @@ -384,7 +385,7 @@ (at 0 0 315) (size 3 2) (rect_delta 1 0) - (layers "F.Cu" "F.Paste" "F.Mask") + (layers "F.Cu") (uuid "f98951ae-c7c4-445b-a39a-a4d57888a02e") ) ) @@ -493,13 +494,200 @@ (pad "Pad" smd roundrect (at 0 0 45) (size 3 2) - (layers "F.Cu" "F.Paste" "F.Mask") + (layers "F.Cu" "F.Adhes" "F.Paste" "F.Mask") (roundrect_rratio 0.1) (chamfer_ratio 0.21) (chamfer top_left bottom_right) (uuid "1ad1d3ed-e8f5-4c7f-b0f6-095051a53b11") ) ) + (footprint "Jumper:SolderJumper-2_P1.3mm_Open_TrianglePad1.0x1.5mm" + (layer "F.Cu") + (uuid "994d43d5-3164-48e7-8130-92441f7fe4c7") + (at 121 93.6) + (descr "SMD Solder Jumper, 1x1.5mm Triangular Pads, 0.3mm gap, open") + (tags "solder jumper open") + (property "Reference" "SB1" + (at 0 -1.8 0) + (layer "F.SilkS") + (uuid "920d4adc-c967-4af0-8187-11eef43919bd") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (property "Value" "SolderJumper-2_P1.3mm_Open_TrianglePad1.0x1.5mm" + (at 0 1.9 0) + (layer "F.Fab") + (hide yes) + (uuid "9cbcb47a-cb17-49df-98a5-2ee0e09b9db2") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (property "Footprint" "" + (at 0 0 0) + (layer "F.Fab") + (hide yes) + (uuid "8fade7e8-ee3e-4f94-a80d-182545e71e02") + (effects + (font + (size 1.27 1.27) + (thickness 0.15) + ) + ) + ) + (property "Datasheet" "" + (at 0 0 0) + (layer "F.Fab") + (hide yes) + (uuid "c10e0e36-fcc2-4aef-918b-47a57ed18826") + (effects + (font + (size 1.27 1.27) + (thickness 0.15) + ) + ) + ) + (property "Description" "" + (at 0 0 0) + (layer "F.Fab") + (hide yes) + (uuid "ffa7349c-a052-4067-9712-2626c99c5e92") + (effects + (font + (size 1.27 1.27) + (thickness 0.15) + ) + ) + ) + (attr exclude_from_pos_files exclude_from_bom) + (fp_line + (start -1.4 -1) + (end 1.4 -1) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "fba79c0f-cbb9-4f82-9dc8-56afbd8e27fc") + ) + (fp_line + (start -1.4 1) + (end -1.4 -1) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "421b6989-a0a8-4ca9-aba2-096742614893") + ) + (fp_line + (start 1.4 -1) + (end 1.4 1) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "9265368b-fb29-4426-9ff3-5e450c586e6f") + ) + (fp_line + (start 1.4 1) + (end -1.4 1) + (stroke + (width 0.12) + (type solid) + ) + (layer "F.SilkS") + (uuid "abada1f4-9fef-41eb-a371-594b0c5ff159") + ) + (fp_line + (start -1.65 -1.25) + (end -1.65 1.25) + (stroke + (width 0.05) + (type solid) + ) + (layer "F.CrtYd") + (uuid "711987ed-ea86-4296-af4a-9fbd6d608e10") + ) + (fp_line + (start -1.65 -1.25) + (end 1.65 -1.25) + (stroke + (width 0.05) + (type solid) + ) + (layer "F.CrtYd") + (uuid "5102f76a-c878-44bc-9d75-bfd6582ac9e4") + ) + (fp_line + (start 1.65 1.25) + (end -1.65 1.25) + (stroke + (width 0.05) + (type solid) + ) + (layer "F.CrtYd") + (uuid "267383d2-2581-47eb-8bca-88b2ba619d19") + ) + (fp_line + (start 1.65 1.25) + (end 1.65 -1.25) + (stroke + (width 0.05) + (type solid) + ) + (layer "F.CrtYd") + (uuid "a9960b84-0016-42a2-9d36-98c678386c44") + ) + (pad "1" smd custom + (at -0.725 0) + (size 0.3 0.3) + (layers "F.Cu" "F.Mask") + (zone_connect 2) + (options + (clearance outline) + (anchor rect) + ) + (primitives + (gr_poly + (pts + (xy -0.5 -0.75) (xy 0.5 -0.75) (xy 1 0) (xy 0.5 0.75) (xy -0.5 0.75) + ) + (width 0) + (fill yes) + ) + ) + (uuid "e59d970d-034f-45b4-8ede-1d68d925f15c") + ) + (pad "2" smd custom + (at 0.725 0) + (size 0.3 0.3) + (layers "F.Cu" "F.Mask") + (zone_connect 2) + (options + (clearance outline) + (anchor rect) + ) + (primitives + (gr_poly + (pts + (xy -0.65 -0.75) (xy 0.5 -0.75) (xy 0.5 0.75) (xy -0.65 0.75) (xy -0.15 0) + ) + (width 0) + (fill yes) + ) + ) + (uuid "9ac25e5d-8bf8-408a-8326-0eace0c875f1") + ) + ) (footprint "TestPoint:TestPoint_Pad_D2.0mm" (layer "F.Cu") (uuid "bccaa590-e277-424e-9452-8ccb31862c88") @@ -606,9 +794,161 @@ (at 0 0) (size 2 2) (layers "F.Cu" "F.Mask") + (solder_paste_margin_ratio -0.1) (uuid "bd1ca0c2-74bb-4a01-94e6-11796af0cb7e") ) ) + (footprint "TestPoint:TestPoint_Pad_D2.0mm" + (layer "F.Cu") + (uuid "d7793912-5b37-41ea-981f-8b3485a419dd") + (at 129.6 97.05) + (descr "SMD pad as test Point, diameter 2.0mm") + (tags "test point SMD pad") + (property "Reference" "P6" + (at 0 -1.998 0) + (layer "F.SilkS") + (uuid "1a511fee-ec16-41ea-9f60-e995339cb423") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (property "Value" "TestPoint_Pad_D2.0mm" + (at 0 2.05 0) + (layer "F.Fab") + (hide yes) + (uuid "b2f68c60-9795-4ccc-bdf0-90ed41f39d33") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (property "Footprint" "TestPoint:TestPoint_Pad_D2.0mm" + (at 0 0 0) + (unlocked yes) + (layer "F.Fab") + (hide yes) + (uuid "e3f4bba9-d277-449a-8236-60c189027a7b") + (effects + (font + (size 1.27 1.27) + (thickness 0.15) + ) + ) + ) + (property "Datasheet" "" + (at 0 0 0) + (unlocked yes) + (layer "F.Fab") + (hide yes) + (uuid "172e0c4d-4ac1-4260-ad36-41159a6f0c13") + (effects + (font + (size 1.27 1.27) + (thickness 0.15) + ) + ) + ) + (property "Description" "" + (at 0 0 0) + (unlocked yes) + (layer "F.Fab") + (hide yes) + (uuid "fc923c7b-2bfa-4584-853d-e343a09fb4d1") + (effects + (font + (size 1.27 1.27) + (thickness 0.15) + ) + ) + ) + (attr exclude_from_pos_files exclude_from_bom) + (fp_circle + (center 0 0) + (end 0 1.2) + (stroke + (width 0.12) + (type solid) + ) + (fill none) + (layer "F.SilkS") + (uuid "0a03171d-f929-46b5-94e5-fa9fb1b8b846") + ) + (fp_circle + (center 0 0) + (end 1.5 0) + (stroke + (width 0.05) + (type solid) + ) + (fill none) + (layer "F.CrtYd") + (uuid "ecd70ab6-bd3d-4cb7-8f2f-4a2911f02242") + ) + (fp_text user "${REFERENCE}" + (at 0 -2 0) + (layer "F.Fab") + (uuid "a4687195-271f-4635-bed0-9f2252a2826a") + (effects + (font + (size 1 1) + (thickness 0.15) + ) + ) + ) + (pad "1" smd custom + (at 0 0 90) + (size 2 2) + (layers "F.Cu" "F.Mask") + (thermal_bridge_angle 90) + (options + (clearance outline) + (anchor circle) + ) + (primitives + (gr_bbox + (start -3.175 -4.1275) + (end -5.08 -0.9525) + (fill no) + ) + (gr_poly + (pts + (xy -2.54 -2.54) (xy 0 -2.54) (xy 0 0) (xy -5.08 0) (xy -5.08 -5.08) (xy -2.54 -5.08) + ) + (width 0.2) + (fill yes) + ) + (gr_arc + (start 3.54 -2.54) + (mid 2.796051 -0.743949) + (end 1 0) + (width 0.25) + ) + (gr_circle + (center 3.54 -3.54) + (end 3.54 -2.54) + (width 0.1) + (fill yes) + ) + (gr_line + (start 0 0.635) + (end 1.905 3.81) + (width 0.2) + ) + (gr_rect + (start 3.175 3.81) + (end 1.905 5.08) + (width 0) + (fill yes) + ) + ) + (uuid "c263801a-e853-41ee-84f4-0bb4b91a2d15") + ) + ) (footprint "TestPoint:TestPoint_Pad_D2.0mm" (layer "F.Cu") (uuid "ecc0fb0f-74be-4cd5-a2b5-2009c7f9f73c") @@ -717,6 +1057,7 @@ (property pad_prop_bga) (layers "F.Cu" "F.Paste" "F.Mask") (die_length 1.8) + (clearance 1) (uuid "d4769495-2985-428a-a206-5d90728f6d88") ) ) diff --git a/qa/data/pcbnew/padstacks.kicad_pro b/qa/data/pcbnew/padstacks.kicad_pro index e10a238e79..36aa69edf6 100644 --- a/qa/data/pcbnew/padstacks.kicad_pro +++ b/qa/data/pcbnew/padstacks.kicad_pro @@ -73,6 +73,7 @@ "footprint_type_mismatch": "ignore", "hole_clearance": "error", "hole_near_hole": "error", + "hole_to_hole": "warning", "holes_co_located": "warning", "invalid_outline": "error", "isolated_copper": "warning", diff --git a/qa/tests/api/test_api_enums.cpp b/qa/tests/api/test_api_enums.cpp index 40574afe1e..1aee19e956 100644 --- a/qa/tests/api/test_api_enums.cpp +++ b/qa/tests/api/test_api_enums.cpp @@ -34,6 +34,7 @@ // Board-specific #include +#include #include using namespace kiapi::common; @@ -160,9 +161,26 @@ BOOST_AUTO_TEST_CASE( ZoneConnectionStyle ) testEnums(); } +BOOST_AUTO_TEST_CASE( PadType ) +{ + testEnums(); +} + +BOOST_AUTO_TEST_CASE( PadStackType ) +{ + testEnums(); +} + BOOST_AUTO_TEST_CASE( UnconnectedLayerRemoval ) { testEnums(); } +BOOST_AUTO_TEST_CASE( ViaType ) +{ + // VIATYPE::NOT_DEFINED is not mapped + testEnums( true ); +} + + BOOST_AUTO_TEST_SUITE_END()