KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_padstack_clone.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
22#include <board.h>
23#include <footprint.h>
24#include <pad.h>
25#include <pcb_shape.h>
26
27
28BOOST_AUTO_TEST_SUITE( PadstackClone )
29
30
31// A front/inner/back pad with no inner entry reads its inner layer through the base entry
32// fails on revert, since cloning adds a blank inner entry that hides the inherited size
33BOOST_AUTO_TEST_CASE( InnerLayerKeepsInheritedSize )
34{
35 BOARD board;
36 FOOTPRINT footprint( &board );
37 PAD pad( &footprint );
38
39 pad.SetSize( F_Cu, VECTOR2I( 1500000, 1200000 ) );
40 pad.SetShape( F_Cu, PAD_SHAPE::OVAL );
41 pad.Padstack().SetMode( PADSTACK::MODE::FRONT_INNER_BACK );
42
43 BOOST_REQUIRE_EQUAL( pad.GetSize( In1_Cu ).x, 1500000 );
44
45 std::unique_ptr<PAD> clone( static_cast<PAD*>( pad.Clone() ) );
46
47 BOOST_CHECK_EQUAL( clone->GetSize( In1_Cu ).x, 1500000 );
48 BOOST_CHECK_EQUAL( clone->GetSize( In1_Cu ).y, 1200000 );
49 BOOST_CHECK( clone->GetShape( In1_Cu ) == PAD_SHAPE::OVAL );
50}
51
52
53// A layer that starts from the base entry owns its primitives, or flipping one layer would flip the other too
54BOOST_AUTO_TEST_CASE( NewLayerOwnsItsPrimitives )
55{
56 BOARD board;
57 FOOTPRINT footprint( &board );
58 PAD pad( &footprint );
59
60 auto* shape = new PCB_SHAPE( &footprint, SHAPE_T::SEGMENT );
61 pad.AddPrimitive( F_Cu, shape );
62 pad.Padstack().SetMode( PADSTACK::MODE::FRONT_INNER_BACK );
63
64 // writing the back layer seeds it from the base entry
65 pad.SetSize( B_Cu, VECTOR2I( 1000000, 1000000 ) );
66
67 BOOST_REQUIRE_EQUAL( pad.GetPrimitives( B_Cu ).size(), 1 );
68 BOOST_CHECK( pad.GetPrimitives( B_Cu ).front().get() != pad.GetPrimitives( F_Cu ).front().get() );
69}
70
71
72// Editing a layer a custom padstack does not define starts from what the layer read through to
73// fails on revert, since the new entry starts blank and the layer loses its size
74BOOST_AUTO_TEST_CASE( CustomLayerEditKeepsInheritedSize )
75{
76 BOARD board;
77 FOOTPRINT footprint( &board );
78 PAD pad( &footprint );
79
80 pad.SetSize( F_Cu, VECTOR2I( 1500000, 1200000 ) );
81 pad.Padstack().SetMode( PADSTACK::MODE::CUSTOM );
82 pad.Padstack().FlipLayers( nullptr );
83
84 BOOST_REQUIRE( !pad.Padstack().HasExplicitDefinitionForLayer( F_Cu ) );
85
86 pad.SetShape( F_Cu, PAD_SHAPE::OVAL );
87
88 BOOST_CHECK_EQUAL( pad.GetSize( F_Cu ).x, 1500000 );
89 BOOST_CHECK_EQUAL( pad.GetSize( F_Cu ).y, 1200000 );
90}
91
92
93// A half turned pad is the same pad only when it is symmetric about its centre
94// fails on revert, since the library comparison then treats a turned pad of another padstack mode as unchanged
95BOOST_AUTO_TEST_CASE( HalfTurnedPadComparison )
96{
97 BOARD board;
98
99 auto makeFootprint = [&]( const VECTOR2I& aOffset, double aAngle )
100 {
101 FOOTPRINT* footprint = new FOOTPRINT( &board );
102 PAD* pad = new PAD( footprint );
103
104 pad->SetNumber( wxS( "1" ) );
106 pad->SetSize( PADSTACK::ALL_LAYERS, VECTOR2I( 2000000, 1000000 ) );
107 pad->SetOffset( PADSTACK::ALL_LAYERS, aOffset );
108 pad->SetOrientation( EDA_ANGLE( aAngle, DEGREES_T ) );
109 footprint->Add( pad );
110 board.Add( footprint );
111 return footprint;
112 };
113
114 FOOTPRINT* centred = makeFootprint( VECTOR2I( 0, 0 ), 0 );
115 FOOTPRINT* centredTurned = makeFootprint( VECTOR2I( 0, 0 ), 180 );
116 FOOTPRINT* shifted = makeFootprint( VECTOR2I( 500000, 0 ), 0 );
117 FOOTPRINT* shiftedTurned = makeFootprint( VECTOR2I( 500000, 0 ), 180 );
118
119 BOOST_CHECK( !centredTurned->FootprintNeedsUpdate( centred, BOARD_ITEM::COMPARE_FLAGS::DRC ) );
120 BOOST_CHECK( shiftedTurned->FootprintNeedsUpdate( shifted, BOARD_ITEM::COMPARE_FLAGS::DRC ) );
121
122 // a different padstack mode is a different pad, whatever the turn
123 centredTurned->Pads().front()->Padstack().SetMode( PADSTACK::MODE::FRONT_INNER_BACK );
124
125 BOOST_CHECK( centredTurned->FootprintNeedsUpdate( centred, BOARD_ITEM::COMPARE_FLAGS::DRC ) );
126}
127
128
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:411
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
Definition board.cpp:1520
bool FootprintNeedsUpdate(const FOOTPRINT *aLibFP, int aCompareFlags=0, REPORTER *aReporter=nullptr)
Return true if a board footprint differs from the library version.
std::deque< PAD * > & Pads()
Definition footprint.h:355
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Adds an item to the container.
@ CUSTOM
Shapes can be defined on arbitrary layers.
Definition padstack.h:172
@ FRONT_INNER_BACK
Up to three shapes can be defined (F_Cu, inner copper layers, B_Cu)
Definition padstack.h:171
static constexpr PCB_LAYER_ID ALL_LAYERS
! The layer identifier to use for the single defintion on normal padstacks
Definition padstack.h:179
Definition pad.h:61
@ DEGREES_T
Definition eda_angle.h:30
@ SEGMENT
Definition eda_shape.h:56
@ B_Cu
Definition layer_ids.h:61
@ In1_Cu
Definition layer_ids.h:62
@ F_Cu
Definition layer_ids.h:60
@ RECTANGLE
Definition padstack.h:53
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_CASE(InnerLayerKeepsInheritedSize)
BOOST_CHECK_EQUAL(result, "25.4")
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:708