KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_board_connected_items.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 modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <boost/test/unit_test.hpp>
21
22#include <board.h>
24#include <footprint.h>
25#include <pad.h>
26#include <pcb_shape.h>
27#include <pcb_track.h>
28#include <zone.h>
29#include <netinfo.h>
31
32
34{
36 {
37 m_board = std::make_unique<BOARD>();
38 }
39
40 std::unique_ptr<BOARD> m_board;
41};
42
43
44BOOST_FIXTURE_TEST_SUITE( BoardConnectedItems, BOARD_CONNECTED_ITEMS_FIXTURE )
45
46
47
53BOOST_AUTO_TEST_CASE( AllConnectedItems_IncludesFootprintShapes )
54{
55 FOOTPRINT* fp = new FOOTPRINT( m_board.get() );
56 m_board->Add( fp );
57
58 PAD* pad = new PAD( fp );
60 pad->SetSize( PADSTACK::ALL_LAYERS, VECTOR2I( pcbIUScale.mmToIU( 1 ), pcbIUScale.mmToIU( 1 ) ) );
61 fp->Add( pad );
62
63 PCB_SHAPE* shape = new PCB_SHAPE( fp, SHAPE_T::SEGMENT );
64 shape->SetLayer( F_Cu );
65 shape->SetStart( VECTOR2I( 0, 0 ) );
66 shape->SetEnd( VECTOR2I( pcbIUScale.mmToIU( 5 ), 0 ) );
67 fp->Add( shape );
68
69 auto items = m_board->AllConnectedItems();
70
71 bool foundPad = false;
72 bool foundShape = false;
73
74 for( BOARD_CONNECTED_ITEM* item : items )
75 {
76 if( item == pad )
77 foundPad = true;
78
79 if( item == shape )
80 foundShape = true;
81 }
82
83 BOOST_CHECK_MESSAGE( foundPad, "AllConnectedItems should include footprint pads" );
84 BOOST_CHECK_MESSAGE( foundShape, "AllConnectedItems should include footprint copper shapes" );
85}
86
87
91BOOST_AUTO_TEST_CASE( AllConnectedItems_IncludesFootprintZones )
92{
93 FOOTPRINT* fp = new FOOTPRINT( m_board.get() );
94 m_board->Add( fp );
95
96 ZONE* zone = new ZONE( fp );
97 zone->SetLayer( F_Cu );
98 zone->AppendCorner( VECTOR2I( 0, 0 ), -1 );
99 zone->AppendCorner( VECTOR2I( pcbIUScale.mmToIU( 5 ), 0 ), -1 );
100 zone->AppendCorner( VECTOR2I( pcbIUScale.mmToIU( 5 ), pcbIUScale.mmToIU( 5 ) ), -1 );
101 zone->AppendCorner( VECTOR2I( 0, pcbIUScale.mmToIU( 5 ) ), -1 );
102 fp->Add( zone );
103
104 auto items = m_board->AllConnectedItems();
105
106 bool foundZone = false;
107
108 for( BOARD_CONNECTED_ITEM* item : items )
109 {
110 if( item == zone )
111 foundZone = true;
112 }
113
114 BOOST_CHECK_MESSAGE( foundZone, "AllConnectedItems should include footprint zones" );
115}
116
117
123BOOST_AUTO_TEST_CASE( MapNets_RemapsFootprintShapes )
124{
125 // Source board simulates the clipboard board
126 std::unique_ptr<BOARD> srcBoard = std::make_unique<BOARD>();
127
128 NETINFO_ITEM* srcNet = new NETINFO_ITEM( srcBoard.get(), wxT( "TestNet" ), 1 );
129 srcBoard->Add( srcNet );
130
131 FOOTPRINT* fp = new FOOTPRINT( srcBoard.get() );
132 srcBoard->Add( fp );
133
134 PAD* pad = new PAD( fp );
136 pad->SetSize( PADSTACK::ALL_LAYERS, VECTOR2I( pcbIUScale.mmToIU( 1 ), pcbIUScale.mmToIU( 1 ) ) );
137 pad->SetNet( srcNet );
138 fp->Add( pad );
139
140 PCB_SHAPE* shape = new PCB_SHAPE( fp, SHAPE_T::SEGMENT );
141 shape->SetLayer( F_Cu );
142 shape->SetStart( VECTOR2I( 0, 0 ) );
143 shape->SetEnd( VECTOR2I( pcbIUScale.mmToIU( 5 ), 0 ) );
144 shape->SetNet( srcNet );
145 fp->Add( shape );
146
147 // Destination board
148 NETINFO_ITEM* destNet = new NETINFO_ITEM( m_board.get(), wxT( "TestNet" ), 1 );
149 m_board->Add( destNet );
150
151 // Remap nets from source to destination
152 srcBoard->MapNets( m_board.get() );
153
154 // After MapNets, all connected items should point to destination board nets
155 BOOST_CHECK_MESSAGE( pad->GetNet() != srcNet,
156 "Pad net should be remapped away from source net" );
157 BOOST_CHECK_MESSAGE( shape->GetNet() != srcNet,
158 "Footprint shape net should be remapped away from source net" );
159 BOOST_CHECK( pad->GetNetname() == wxT( "TestNet" ) );
160 BOOST_CHECK( shape->GetNetname() == wxT( "TestNet" ) );
161}
162
163
168BOOST_AUTO_TEST_CASE( MapNets_FootprintShapeSurvivesSourceBoardDeletion )
169{
170 FOOTPRINT* fp = nullptr;
171
172 {
173 // Source board (clipboard) - will be destroyed at end of this scope
174 std::unique_ptr<BOARD> srcBoard = std::make_unique<BOARD>();
175
176 NETINFO_ITEM* srcNet = new NETINFO_ITEM( srcBoard.get(), wxT( "GND" ), 1 );
177 srcBoard->Add( srcNet );
178
179 fp = new FOOTPRINT( srcBoard.get() );
180 srcBoard->Add( fp );
181
182 PAD* pad = new PAD( fp );
184 pad->SetSize( PADSTACK::ALL_LAYERS,
185 VECTOR2I( pcbIUScale.mmToIU( 1 ), pcbIUScale.mmToIU( 1 ) ) );
186 pad->SetNet( srcNet );
187 fp->Add( pad );
188
189 PCB_SHAPE* shape = new PCB_SHAPE( fp, SHAPE_T::SEGMENT );
190 shape->SetLayer( F_Cu );
191 shape->SetStart( VECTOR2I( 0, 0 ) );
192 shape->SetEnd( VECTOR2I( pcbIUScale.mmToIU( 5 ), 0 ) );
193 shape->SetNet( srcNet );
194 fp->Add( shape );
195
196 // Remap nets to destination board before source goes away
197 srcBoard->MapNets( m_board.get() );
198
199 // Remove footprint from source board (simulates placeBoardItems calling RemoveAll)
200 srcBoard->Remove( fp );
201 }
202
203 // Source board and its NETINFO_LIST are now destroyed.
204 // Move the footprint to the destination board.
205 fp->SetParent( m_board.get() );
206 m_board->Add( fp );
207
208 // Attempt to format the board. Before the fix, GetNetname() on the footprint
209 // shape would dereference a dangling pointer and crash.
210 STRING_FORMATTER formatter;
212 io.SetOutputFormatter( &formatter );
213 BOOST_CHECK_NO_THROW( io.Format( static_cast<const BOARD_ITEM*>( fp ) ) );
214
215 // Verify the formatted output contains the net name
216 std::string output = formatter.GetString();
217 BOOST_CHECK_MESSAGE( output.find( "GND" ) != std::string::npos,
218 "Formatted footprint should contain the remapped net name" );
219}
220
221
constexpr EDA_IU_SCALE pcbIUScale
Definition base_units.h:112
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
NETINFO_ITEM * GetNet() const
Return #NET_INFO object for a given item.
void SetNet(NETINFO_ITEM *aNetInfo)
Set a NET_INFO object for the item.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition board_item.h:84
virtual void SetParent(EDA_ITEM *aParent)
Definition eda_item.cpp:93
void SetStart(const VECTOR2I &aStart)
Definition eda_shape.h:178
void SetEnd(const VECTOR2I &aEnd)
Definition eda_shape.h:220
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
Handle the data for a net.
Definition netinfo.h:54
static constexpr PCB_LAYER_ID ALL_LAYERS
! Temporary layer identifier to identify code that is not padstack-aware
Definition padstack.h:177
Definition pad.h:55
A #PLUGIN derivation for saving and loading Pcbnew s-expression formatted files.
void Format(const BOARD_ITEM *aItem) const
Output aItem to aFormatter in s-expression format.
void SetOutputFormatter(OUTPUTFORMATTER *aFormatter)
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
Implement an OUTPUTFORMATTER to a memory buffer.
Definition richio.h:422
const std::string & GetString()
Definition richio.h:445
Handle a list of polygons defining a copper zone.
Definition zone.h:73
virtual void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
Definition zone.cpp:550
bool AppendCorner(VECTOR2I aPosition, int aHoleIdx, bool aAllowDuplication=false)
Add a new corner to the zone outline (to the main outline or a hole)
Definition zone.cpp:1183
@ SEGMENT
Definition eda_shape.h:45
@ F_Cu
Definition layer_ids.h:64
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_CASE(AllConnectedItems_IncludesFootprintShapes)
Verify that AllConnectedItems includes copper shapes inside footprints.
BOOST_AUTO_TEST_SUITE_END()
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:695