25#include <boost/test/data/test_case.hpp>
66 for(
PAD*
pad : m_board->Footprints()[0]->Pads() )
68 if(
pad->GetNumber() ==
"2" ||
pad->GetNumber() ==
"4" ||
pad->GetNumber() ==
"6" )
79 for(
PCB_TRACK* track : m_board->Tracks() )
88 track->SetWidth( track->GetWidth() +
delta +
delta );
92 arc12 = track->m_Uuid;
98 bool foundPad2Error =
false;
99 bool foundPad4Error =
false;
100 bool foundPad6Error =
false;
101 bool foundArc8Error =
false;
102 bool foundArc12Error =
false;
103 bool foundOtherError =
false;
108 [&](
const std::shared_ptr<DRC_ITEM>& aItem,
const VECTOR2I& aPos,
int aLayer,
109 const std::function<
void(
PCB_MARKER* )>& aPathGenerator )
113 BOARD_ITEM* item_a = m_board->ResolveItem( aItem->GetMainItemID() );
114 PAD* pad_a =
dynamic_cast<PAD*
>( item_a );
117 BOARD_ITEM* item_b = m_board->ResolveItem( aItem->GetAuxItemID() );
118 PAD* pad_b =
dynamic_cast<PAD*
>( item_b );
121 if( pad_a && pad_a->
GetNumber() ==
"2" ) foundPad2Error =
true;
122 else if( pad_a && pad_a->
GetNumber() ==
"4" ) foundPad4Error =
true;
123 else if( pad_a && pad_a->
GetNumber() ==
"6" ) foundPad6Error =
true;
124 else if( pad_b && pad_b->
GetNumber() ==
"2" ) foundPad2Error =
true;
125 else if( pad_b && pad_b->
GetNumber() ==
"4" ) foundPad4Error =
true;
126 else if( pad_b && pad_b->
GetNumber() ==
"6" ) foundPad6Error =
true;
127 else if( trk_a && trk_a->
m_Uuid == arc8 ) foundArc8Error =
true;
128 else if( trk_a && trk_a->
m_Uuid == arc12 ) foundArc12Error =
true;
129 else if( trk_b && trk_b->
m_Uuid == arc8 ) foundArc8Error =
true;
130 else if( trk_b && trk_b->
m_Uuid == arc12 ) foundArc12Error =
true;
131 else foundOtherError =
true;
161 for(
ZONE* zone : m_board->Zones() )
163 if( zone->GetLayerSet().Contains(
F_Cu ) )
200 std::vector<DRC_ITEM> violations;
203 [&](
const std::shared_ptr<DRC_ITEM>& aItem,
const VECTOR2I& aPos,
int aLayer,
204 const std::function<
void(
PCB_MARKER* )>& aPathGenerator )
207 violations.push_back( *aItem );
212 if( violations.empty() )
221 std::map<KIID, EDA_ITEM*> itemMap;
222 m_board->FillItemMap( itemMap );
224 for(
const DRC_ITEM& item : violations )
227 BOOST_ERROR( wxString::Format(
"Zone fill regression: %s failed", relPath ) );
247 std::vector<DRC_ITEM> violations;
250 [&](
const std::shared_ptr<DRC_ITEM>& aItem,
const VECTOR2I& aPos,
int aLayer,
251 const std::function<
void(
PCB_MARKER* )>& aPathGenerator )
254 violations.push_back( *aItem );
259 if( violations.empty() )
262 BOOST_TEST_MESSAGE( wxString::Format(
"Zone fill copper sliver regression: %s passed", relPath ) );
268 std::map<KIID, EDA_ITEM*> itemMap;
269 m_board->FillItemMap( itemMap );
271 for(
const DRC_ITEM& item : violations )
274 BOOST_ERROR( wxString::Format(
"Zone fill copper sliver regression: %s failed", relPath ) );
280 {
"teardrop_issue_JPC2", 5 },
287 const wxString& relPath =
test.first;
288 const int count =
test.second;
298 for(
ZONE* zone : m_board->Zones() )
300 if( zone->IsTeardropArea() )
304 BOOST_CHECK_MESSAGE( zoneCount == count,
"Expected " << count <<
" teardrop zones in "
305 << relPath <<
", found "
313 std::vector<wxString> tests = { {
"issue19956/issue19956" }
316 for(
const wxString& relPath : tests )
322 for(
ZONE* zone : m_board->Zones() )
326 std::shared_ptr<SHAPE> a_shape( zone->GetEffectiveShape( layer ) );
328 for(
PAD*
pad : m_board->GetPads() )
330 std::shared_ptr<SHAPE> pad_shape(
pad->GetEffectiveShape( layer ) );
331 int clearance = pad_shape->GetClearance( a_shape.get() );
332 BOOST_CHECK_MESSAGE(
pad->GetNetCode() == zone->GetNetCode() ||
clearance != 0,
333 wxString::Format(
"Pad %s from Footprint %s has net code %s and "
334 "is connected to zone with net code %s",
336 pad->GetParentFootprint()->GetReferenceAsString(),
338 zone->GetNetname() ) );
368 struct ScopeGuard {
bool& ref;
bool orig; ~ScopeGuard() { ref = orig; } } guard{ cfg.
m_ZoneFillIterativeRefill, originalIterativeRefill };
375 ZONE* gndZone =
nullptr;
377 for(
ZONE* zone : m_board->Zones() )
379 if( zone->GetNetname() ==
"GND" )
386 BOOST_REQUIRE_MESSAGE( gndZone !=
nullptr,
"GND zone not found in test board" );
390 bool hasOutline = m_board->GetBoardPolygonOutlines( boardOutline,
true );
391 BOOST_REQUIRE_MESSAGE( hasOutline,
"Board outline not found" );
393 double boardArea = 0.0;
404 double fillRatio = gndFilledArea / boardArea;
406 BOOST_TEST_MESSAGE( wxString::Format(
"Board area: %.2f sq mm, GND filled area: %.2f sq mm, "
407 "Fill ratio: %.1f%%",
408 boardArea / 1e6, gndFilledArea / 1e6,
409 fillRatio * 100.0 ) );
411 BOOST_CHECK_MESSAGE( fillRatio >= 0.25,
412 wxString::Format(
"GND zone fill ratio %.1f%% is less than expected 25%%. "
413 "This indicates issue 21746 - lower priority zones not "
414 "filling areas where higher priority isolated islands "
416 fillRatio * 100.0 ) );
441 int viasWithUnreachableFlashing = 0;
442 int totalConditionalVias = 0;
444 PCB_LAYER_ID in1Cu = m_board->GetLayerID( wxT(
"In1.Cu" ) );
445 PCB_LAYER_ID in2Cu = m_board->GetLayerID( wxT(
"In2.Cu" ) );
447 for(
PCB_TRACK* track : m_board->Tracks() )
454 if( !
via->GetRemoveUnconnected() )
457 totalConditionalVias++;
460 bool flashedOnIn1 =
via->FlashLayer( in1Cu );
461 bool flashedOnIn2 =
via->FlashLayer( in2Cu );
463 if( !flashedOnIn1 && !flashedOnIn2 )
467 int holeRadius =
via->GetDrillValue() / 2;
470 bool zoneReachesVia =
false;
472 for(
ZONE* zone : m_board->Zones() )
474 if( zone->GetIsRuleArea() )
477 if( zone->GetNetCode() !=
via->GetNetCode() )
482 if( !zone->IsOnLayer( layer ) )
485 if( !zone->HasFilledPolysForLayer( layer ) )
488 const std::shared_ptr<SHAPE_POLY_SET>& fill = zone->GetFilledPolysList( layer );
490 if( fill->Contains( viaCenter, -1, holeRadius ) )
492 zoneReachesVia =
true;
502 if( !zoneReachesVia && ( flashedOnIn1 || flashedOnIn2 ) )
503 viasWithUnreachableFlashing++;
506 BOOST_TEST_MESSAGE( wxString::Format(
"Total conditional vias: %d, Vias with unreachable "
507 "flashing: %d", totalConditionalVias,
508 viasWithUnreachableFlashing ) );
510 BOOST_CHECK_MESSAGE( viasWithUnreachableFlashing == 0,
511 wxString::Format(
"Found %d vias flashed on zone layers where the zone "
512 "fill doesn't actually reach them. This indicates "
513 "issue 22010 is not fixed.",
514 viasWithUnreachableFlashing ) );
536 int viasShortingZones = 0;
537 int totalConditionalVias = 0;
539 for(
PCB_TRACK* track : m_board->Tracks() )
546 if( !
via->GetRemoveUnconnected() )
549 totalConditionalVias++;
553 for(
ZONE* zone : m_board->Zones() )
555 if( zone->GetIsRuleArea() )
558 if( zone->GetNetCode() ==
via->GetNetCode() )
563 if( !
via->FlashLayer( layer ) )
566 if( !zone->HasFilledPolysForLayer( layer ) )
569 const std::shared_ptr<SHAPE_POLY_SET>& fill = zone->GetFilledPolysList( layer );
570 int viaRadius =
via->GetWidth( layer ) / 2;
572 if( fill->Contains( viaCenter, -1, viaRadius ) )
575 "Via at (%d, %d) on net %s is flashing on layer %s where zone "
576 "net %s is filled - this creates a short!",
577 viaCenter.
x, viaCenter.
y,
via->GetNetname(),
578 m_board->GetLayerName( layer ), zone->GetNetname() ) );
585 BOOST_TEST_MESSAGE( wxString::Format(
"Total conditional vias: %d, Vias shorting zones: %d",
586 totalConditionalVias, viasShortingZones ) );
588 BOOST_CHECK_MESSAGE( viasShortingZones == 0,
589 wxString::Format(
"Found %d vias flashed on layers where they short to "
590 "zones with different nets. This indicates issue 12964 "
592 viasShortingZones ) );
610 KI_TEST::LoadBoard( m_settingsManager,
"hatch_thermal_connectivity/hatch_thermal_connectivity",
615 m_board->BuildConnectivity();
617 int unconnectedCount = m_board->GetConnectivity()->GetUnconnectedCount(
false );
619 BOOST_CHECK_MESSAGE( unconnectedCount == 0,
620 wxString::Format(
"Found %d unconnected items after zone fill. "
621 "Hatch zone thermal reliefs should maintain connectivity "
622 "even with large hatch gaps.",
623 unconnectedCount ) );
constexpr EDA_IU_SCALE pcbIUScale
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
Container for design settings for a BOARD object.
std::shared_ptr< DRC_ENGINE > m_DRCEngine
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
void RunTests(EDA_UNITS aUnits, bool aReportAllTrackErrors, bool aTestFootprints, BOARD_COMMIT *aCommit=nullptr)
Run the DRC tests.
void SetViolationHandler(DRC_VIOLATION_HANDLER aHandler)
Set an optional DRC violation handler (receives DRC_ITEMs and positions).
void InitEngine(const wxFileName &aRulePath)
Initialize the DRC engine.
static constexpr PCB_LAYER_ID ALL_LAYERS
! Temporary layer identifier to identify code that is not padstack-aware
const wxString & GetNumber() const
double Area(bool aAbsolute=true) const
Return the area of this chain.
Represent a set of closed polygons.
void BooleanAdd(const SHAPE_POLY_SET &b)
Perform boolean polyset union.
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
int OutlineCount() const
Return the number of outlines in the set.
Handle a list of polygons defining a copper zone.
double GetFilledArea()
This area is cached from the most recent call to CalculateFilledArea().
double CalculateFilledArea()
Compute the area currently occupied by the zone fill.
bool m_ZoneFillIterativeRefill
Enable iterative zone filling to handle isolated islands in higher priority zones.
PCB_LAYER_ID
A quick note on layer IDs:
void LoadBoard(SETTINGS_MANAGER &aSettingsManager, const wxString &aRelPath, std::unique_ptr< BOARD > &aBoard)
void FillZones(BOARD *m_board)
std::unique_ptr< BOARD > m_board
SETTINGS_MANAGER m_settingsManager
BOOST_TEST_MESSAGE("Polyline has "<< chain.PointCount()<< " points")
BOOST_CHECK_EQUAL(result, "25.4")
static const std::vector< wxString > RegressionZoneFillTests_tests
static const std::vector< std::pair< wxString, int > > RegressionTeardropFill_tests
BOOST_DATA_TEST_CASE_F(ZONE_FILL_TEST_FIXTURE, RegressionZoneFillTests, boost::unit_test::data::make(RegressionZoneFillTests_tests), relPath)
static const std::vector< wxString > RegressionSliverZoneFillTests_tests
BOOST_FIXTURE_TEST_CASE(BasicZoneFills, ZONE_FILL_TEST_FIXTURE)
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
VECTOR2< int32_t > VECTOR2I