KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_fabmaster_import.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
24
28
30
31#include <board.h>
32#include <footprint.h>
33#include <pad.h>
34#include <padstack.h>
35#include <zone.h>
36
37
44
45
46BOOST_FIXTURE_TEST_SUITE( FabmasterImport, FABMASTER_IMPORT_FIXTURE )
47
48
49
58BOOST_AUTO_TEST_CASE( EmptyRefdesInPins )
59{
60 std::string dataPath =
61 KI_TEST::GetPcbnewTestDataDir() + "plugins/fabmaster/cds2f_only_2_comp.txt";
62
63 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
64
65 m_fabmasterPlugin.LoadBoard( dataPath, board.get(), nullptr );
66
67 BOOST_REQUIRE( board );
68
69 // The board should have footprints
70 BOOST_REQUIRE_GT( board->Footprints().size(), 0 );
71
72 // Each footprint should have pads (before the fix, pads were missing because
73 // the lookup by empty REFDES failed)
74 int totalPads = 0;
75
76 for( const FOOTPRINT* fp : board->Footprints() )
77 {
78 totalPads += fp->Pads().size();
79 }
80
81 BOOST_CHECK_MESSAGE( totalPads > 0,
82 "Footprints should have pads when REFDES is empty in PIN section" );
83}
84
85
97BOOST_AUTO_TEST_CASE( StaticShapesPreserved )
98{
99 std::string dataPath =
100 KI_TEST::GetPcbnewTestDataDir() + "plugins/fabmaster/cds2f_14066-20316FBRD.txt";
101
102 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
103
104 m_fabmasterPlugin.LoadBoard( dataPath, board.get(), nullptr );
105
106 BOOST_REQUIRE( board );
107
108 // Count zones - static shapes should be preserved as zones with net codes
109 int zonesWithNets = 0;
110
111 for( ZONE* zone : board->Zones() )
112 {
113 if( zone->GetNetCode() > 0 )
114 zonesWithNets++;
115 }
116
117 // The board should have some zones with nets assigned (static shapes).
118 // Before the fix, all netted zones were deleted because they were considered
119 // redundant fills. With the fix, unmatched static shapes are preserved.
120 BOOST_CHECK_MESSAGE( zonesWithNets > 0,
121 "Static shape zones with nets should be preserved" );
122}
123
124
128static const PAD* findPadByNumber( const FOOTPRINT* aFp, const wxString& aNumber )
129{
130 for( const PAD* pad : aFp->Pads() )
131 {
132 if( pad->GetNumber() == aNumber )
133 return pad;
134 }
135
136 return nullptr;
137}
138
139
149BOOST_AUTO_TEST_CASE( PadStackDifferentLayers )
150{
151 std::string dataPath =
152 KI_TEST::GetPcbnewTestDataDir() + "plugins/fabmaster/cds2f_padstack_test.txt";
153
154 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
155
156 m_fabmasterPlugin.LoadBoard( dataPath, board.get(), nullptr );
157
158 BOOST_REQUIRE( board );
159 BOOST_REQUIRE_GT( board->Footprints().size(), 0 );
160
161 const FOOTPRINT* fp = board->Footprints().front();
162 BOOST_REQUIRE_EQUAL( fp->Pads().size(), 3 );
163
164 // Pin 1 uses DIFF_PAD which has CIRCLE on TOP and RECTANGLE on BOTTOM.
165 // This should use FRONT_INNER_BACK padstack mode.
166 const PAD* pad1 = findPadByNumber( fp, wxT( "1" ) );
167 BOOST_REQUIRE( pad1 );
168 BOOST_CHECK_EQUAL( static_cast<int>( pad1->Padstack().Mode() ),
169 static_cast<int>( PADSTACK::MODE::FRONT_INNER_BACK ) );
170 BOOST_CHECK_EQUAL( static_cast<int>( pad1->GetShape( F_Cu ) ),
171 static_cast<int>( PAD_SHAPE::CIRCLE ) );
172 BOOST_CHECK_EQUAL( static_cast<int>( pad1->GetShape( B_Cu ) ),
173 static_cast<int>( PAD_SHAPE::RECTANGLE ) );
174
175 // Verify front layer size (2.0mm circle)
176 VECTOR2I pad1_front_size = pad1->GetSize( F_Cu );
177 BOOST_CHECK_GT( pad1_front_size.x, 0 );
178 BOOST_CHECK_EQUAL( pad1_front_size.x, pad1_front_size.y );
179
180 // Verify back layer size (1.5x3.0mm rectangle, height > width)
181 VECTOR2I pad1_back_size = pad1->GetSize( B_Cu );
182 BOOST_CHECK_GT( pad1_back_size.x, 0 );
183 BOOST_CHECK_GT( pad1_back_size.y, pad1_back_size.x );
184
185 // Verify drill is present
186 BOOST_CHECK_EQUAL( static_cast<int>( pad1->GetAttribute() ),
187 static_cast<int>( PAD_ATTRIB::PTH ) );
188 BOOST_CHECK_GT( pad1->GetDrillSizeX(), 0 );
189}
190
191
195BOOST_AUTO_TEST_CASE( PadStackSameLayers )
196{
197 std::string dataPath =
198 KI_TEST::GetPcbnewTestDataDir() + "plugins/fabmaster/cds2f_padstack_test.txt";
199
200 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
201
202 m_fabmasterPlugin.LoadBoard( dataPath, board.get(), nullptr );
203
204 BOOST_REQUIRE( board );
205 BOOST_REQUIRE_GT( board->Footprints().size(), 0 );
206
207 const FOOTPRINT* fp = board->Footprints().front();
208
209 // Pin 2 uses SAME_PAD which has RECTANGLE 1.0x2.0 on both TOP and BOTTOM.
210 // This should stay in NORMAL mode since shapes are identical.
211 const PAD* pad2 = findPadByNumber( fp, wxT( "2" ) );
212 BOOST_REQUIRE( pad2 );
213 BOOST_CHECK_EQUAL( static_cast<int>( pad2->Padstack().Mode() ),
214 static_cast<int>( PADSTACK::MODE::NORMAL ) );
215 BOOST_CHECK_EQUAL( static_cast<int>( pad2->GetShape( F_Cu ) ),
216 static_cast<int>( PAD_SHAPE::RECTANGLE ) );
217}
218
219
223BOOST_AUTO_TEST_CASE( PadStackSmdPad )
224{
225 std::string dataPath =
226 KI_TEST::GetPcbnewTestDataDir() + "plugins/fabmaster/cds2f_padstack_test.txt";
227
228 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
229
230 m_fabmasterPlugin.LoadBoard( dataPath, board.get(), nullptr );
231
232 BOOST_REQUIRE( board );
233 BOOST_REQUIRE_GT( board->Footprints().size(), 0 );
234
235 const FOOTPRINT* fp = board->Footprints().front();
236
237 // Pin 3 uses SMD_DIFF which is an OVAL on TOP only (no BOTTOM pad, no drill).
238 const PAD* pad3 = findPadByNumber( fp, wxT( "3" ) );
239 BOOST_REQUIRE( pad3 );
240 BOOST_CHECK_EQUAL( static_cast<int>( pad3->GetAttribute() ),
241 static_cast<int>( PAD_ATTRIB::SMD ) );
242 BOOST_CHECK_EQUAL( static_cast<int>( pad3->GetShape( F_Cu ) ),
243 static_cast<int>( PAD_SHAPE::OVAL ) );
244}
245
246
General utilities for PCB file IO for QA programs.
std::deque< PAD * > & Pads()
Definition footprint.h:375
@ NORMAL
Shape is the same on all layers.
Definition padstack.h:171
@ FRONT_INNER_BACK
Up to three shapes can be defined (F_Cu, inner copper layers, B_Cu)
Definition padstack.h:172
MODE Mode() const
Definition padstack.h:335
Definition pad.h:61
PAD_ATTRIB GetAttribute() const
Definition pad.h:555
int GetDrillSizeX() const
Definition pad.h:317
PAD_SHAPE GetShape(PCB_LAYER_ID aLayer) const
Definition pad.h:202
VECTOR2I GetSize(PCB_LAYER_ID aLayer) const
Definition pad.cpp:287
const PADSTACK & Padstack() const
Definition pad.h:326
Handle a list of polygons defining a copper zone.
Definition zone.h:70
@ B_Cu
Definition layer_ids.h:61
@ F_Cu
Definition layer_ids.h:60
std::string GetPcbnewTestDataDir()
Utility which returns a path to the data directory where the test board files are stored.
@ SMD
Smd pad, appears on the solder paste layer (default)
Definition padstack.h:99
@ PTH
Plated through hole pad.
Definition padstack.h:98
@ RECTANGLE
Definition padstack.h:54
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
static const PAD * findPadByNumber(const FOOTPRINT *aFp, const wxString &aNumber)
Helper to find a pad by its number within a footprint.
BOOST_AUTO_TEST_CASE(EmptyRefdesInPins)
Test that footprints with pads are properly imported when the REFDES column is empty in the PIN secti...
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
BOOST_CHECK_MESSAGE(totalMismatches==0, std::to_string(totalMismatches)+" board(s) with strategy disagreements")
BOOST_CHECK_EQUAL(result, "25.4")
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683