78 BOOST_CHECK(
dynamic_cast<PCB_VIA_STACK*
>( gen.get() ) !=
nullptr );
86 auto board = std::make_unique<BOARD>();
115 auto path = std::filesystem::temp_directory_path() /
"via_stack_saveload_tst.kicad_pcb";
120 BOOST_REQUIRE_EQUAL( reloaded->Generators().size(), 1u );
146 auto board = std::make_unique<BOARD>();
147 board->SetCopperLayerCount( 4 );
170 auto board = std::make_unique<BOARD>();
171 board->SetCopperLayerCount( 4 );
187 std::vector<PCB_VIA*> vias;
193 vias.push_back(
static_cast<PCB_VIA*
>( item ) );
201 std::set<std::pair<int, int>> pairs;
206 BOOST_CHECK(
via->GetPosition() == origin );
207 pairs.insert( { (int)
via->TopLayer(), (int)
via->BottomLayer() } );
218 auto board = std::make_unique<BOARD>();
219 board->SetCopperLayerCount( 4 );
242 std::vector<PCB_TRACK*> traces;
249 traces.push_back(
static_cast<PCB_TRACK*
>( item ) );
253 BOOST_REQUIRE_EQUAL( traces.size(), 1u );
257 BOOST_CHECK( trace->
GetStart() == p0 );
258 BOOST_CHECK( trace->
GetEnd() == p1 );
266 auto board = std::make_unique<BOARD>();
267 board->SetCopperLayerCount( 4 );
293 std::set<VECTOR2I> positions;
298 positions.insert(
static_cast<PCB_VIA*
>( item )->GetPosition() );
311 auto board = std::make_unique<BOARD>();
312 board->SetCopperLayerCount( 4 );
337 std::set<VECTOR2I> positions;
342 positions.insert(
static_cast<PCB_VIA*
>( item )->GetPosition() );
355 auto board = std::make_unique<BOARD>();
356 board->SetCopperLayerCount( 4 );
408 auto board = std::make_unique<BOARD>();
410 board->SetCopperLayerCount( 4 );
440 via->SetLayerPair( aTop, aBottom );
443 via->SetPosition( aPos );
444 via->SetNetCode( aNet );
454 auto board = std::make_unique<BOARD>();
455 board->SetCopperLayerCount( 4 );
460 std::vector<BOARD_ITEM*> items;
479 auto board = std::make_unique<BOARD>();
480 board->SetCopperLayerCount( 4 );
485 std::vector<BOARD_ITEM*> items;
497 auto board = std::make_unique<BOARD>();
498 board->SetCopperLayerCount( 4 );
530 found =
via->GetPosition();
535 BOOST_CHECK_MESSAGE( found == last,
"the end layer via is the last hop, not the stack position" );
542 auto board = std::make_unique<BOARD>();
543 board->SetCopperLayerCount( 4 );
546 board->Add(
new NETINFO_ITEM( board.get(), wxT(
"sig" ), 1 ) );
547 board->Add(
new NETINFO_ITEM( board.get(), wxT(
"other" ), 2 ) );
550 preset.
m_Name = wxT(
"fanout" );
554 std::vector<PENDING_STACK_EXPANSION> pending = { {
F_Cu,
In2_Cu, 1, preset, dropped } };
555 std::set<KIID> preRoute;
563 std::vector<PENDING_STACK_EXPANSION> upward = { {
In2_Cu,
F_Cu, 1, preset, dropped } };
577 std::vector<PENDING_STACK_EXPANSION> armed = { {
F_Cu,
In2_Cu, 1, preset, std::nullopt } };
581 preRoute.insert( match->
m_Uuid );
590 nlohmann::json entries = nlohmann::json::array();
592 entries.push_back( { {
"name",
"HDI" }, {
"start_layer",
"F.Cu" }, {
"end_layer",
"In1.Cu" } } );
593 entries.push_back( { {
"name",
"hdi" }, {
"start_layer",
"F.Cu" }, {
"end_layer",
"In2.Cu" } } );
594 entries.push_back( { {
"name",
"Other" }, {
"start_layer",
"F.Cu" }, {
"end_layer",
"In1.Cu" } } );
596 bds.
Set(
"via_stack_presets", entries );
611 nlohmann::json entries = nlohmann::json::array();
614 entries.push_back( { {
"name",
"wrong unit" }, {
"via_size", 300000.0 }, {
"via_drill", 150000.0 } } );
615 entries.push_back( { {
"name",
"negative" }, {
"via_size", -5000.0 }, {
"via_drill", -5000.0 } } );
616 entries.push_back( { {
"name",
"sane" }, {
"via_size", 0.3 }, {
"via_drill", 0.15 } } );
618 bds.
Set(
"via_stack_presets", entries );
638 auto board = std::make_unique<BOARD>();
641 auto capped = [](
PCB_VIA* aVia )
643 aVia->Padstack().Drill().is_capped =
true;
655 BOOST_CHECK_MESSAGE( topAnchored->IsCapped(),
"capping was dropped on a stack anchored at the front" );
665 BOOST_CHECK_MESSAGE( bottomAnchored->IsCapped(),
"capping was dropped on a stack anchored at the back" );
673 auto board = std::make_unique<BOARD>();
689 BOOST_CHECK_MESSAGE( stack->GetHops()->PointCount() == 3,
690 "hop chain has " << stack->GetHops()->PointCount() <<
" points for 3 vias" );
692 BOOST_CHECK( stack->GetHops()->CPoint( 0 ) == at );
693 BOOST_CHECK( stack->GetHops()->CPoint( 1 ) == at );
694 BOOST_CHECK( stack->GetHops()->CPoint( 2 ) == offset );
701 auto board = std::make_unique<BOARD>();
702 board->SetCopperLayerCount( 4 );
705 board->Add(
new NETINFO_ITEM( board.get(), wxT(
"A" ), 1 ) );
706 board->Add(
new NETINFO_ITEM( board.get(), wxT(
"B" ), 2 ) );
716 std::vector<BOARD_ITEM*> items = { upper, lower };
733 auto board = std::make_unique<BOARD>();
734 board->SetCopperLayerCount( 4 );
742 std::vector<BOARD_ITEM*> items = { upper, lower };
747 BOOST_CHECK( !error.IsEmpty() );
758 BOOST_CHECK( stack );
771 props.
set(
"start_layer", wxString( wxS(
"Not.A.Layer" ) ) );
772 props.
set(
"end_layer", wxString( wxS(
"B.Adhes" ) ) );
800 auto board = std::make_unique<BOARD>();
801 board->SetCopperLayerCount( 4 );
804 board->Add(
new NETINFO_ITEM( board.get(), wxT(
"A" ), 1 ) );
805 board->Add(
new NETINFO_ITEM( board.get(), wxT(
"B" ), 2 ) );
830 std::vector<BOARD_ITEM*> items = { hop0, hop1, connector, offLanding, otherNet, loose, zeroLength };
831 std::vector<BOARD_ITEM*> members;
839 for(
PCB_TRACK* stray : { offLanding, otherNet, loose, zeroLength } )
841 BOOST_CHECK_MESSAGE( std::count( members.begin(), members.end(), (
BOARD_ITEM*) stray ) == 0,
842 "a trace that does not link two hops joined the stack" );
850 auto board = std::make_unique<BOARD>();
851 board->SetCopperLayerCount( 4 );
865 std::vector<BOARD_ITEM*> items;
868 items.push_back( item );
870 BOOST_REQUIRE_EQUAL( items.size(), 2u );
879 auto board = std::make_unique<BOARD>();
880 board->SetCopperLayerCount( 4 );
892 BOOST_REQUIRE_EQUAL( board->Generators().size(), 1u );
904 BOOST_CHECK(
via->GetPosition() == pos );
912 for(
PCB_TRACK* track : board->Tracks() )
917 BOOST_CHECK(
via->GetParentGroup() !=
nullptr );
941 auto countVias = [&]() ->
size_t
954 BOOST_REQUIRE_EQUAL( countVias(), 1u );
963 BOOST_REQUIRE_EQUAL( countVias(), 1u );
976 commit.
Push( wxT(
"Expand Microvia Stacks" ) );
978 BOOST_REQUIRE_EQUAL( board.
Generators().size(), 1u );
984 BOOST_CHECK( track->GetParentGroup() !=
nullptr );
994 auto board = std::make_unique<BOARD>();
995 board->SetCopperLayerCount( 4 );
1011 board->Add( stack );
1014 board->BuildConnectivity();
1016 std::vector<PCB_VIA*> vias;
1021 vias.push_back(
static_cast<PCB_VIA*
>( item ) );
1024 BOOST_REQUIRE_EQUAL( vias.size(), 2u );
1026 std::vector<BOARD_CONNECTED_ITEM*> connected = board->GetConnectivity()->GetConnectedItems( vias[0] );
1028 bool otherFound = std::find( connected.begin(), connected.end(),
static_cast<BOARD_CONNECTED_ITEM*
>( vias[1] ) )
1031 BOOST_CHECK_MESSAGE( otherFound,
"Coaxial microvia hops sharing the inner layer must be connected." );
1041 mgr.
SetEnvironment( &board,
nullptr,
nullptr,
nullptr,
nullptr );
1066 stack->
EditStart(
nullptr, &board, &commit );
1067 stack->
Update(
nullptr, &board, &commit );
1068 stack->
EditFinish(
nullptr, &board, &commit );
1071 commit.
Push( wxT(
"Place Microvia Stack" ) );
1073 BOOST_REQUIRE_EQUAL( board.
Generators().size(), 1u );
1077 std::vector<PCB_VIA*> boardVias;
1082 boardVias.push_back(
static_cast<PCB_VIA*
>( track ) );
1085 BOOST_REQUIRE_EQUAL( boardVias.size(), 2u );
1111 BOOST_CHECK( stack->
HitTest( pos, 0 ) );
1115 BOOST_CHECK( stack->
HitTest( around,
false, 0 ) );
1116 BOOST_CHECK( stack->
HitTest( around,
true, 0 ) );
1121 BOOST_CHECK( std::find( viewLayers.begin(), viewLayers.end(), (
int) stack->
GetLayer() ) != viewLayers.end() );
1129 auto board = std::make_unique<BOARD>();
1130 board->SetCopperLayerCount( 6 );
1147 board->Add( stack );
1168 for(
PCB_TRACK* track : board->Tracks() )
1179 auto board = std::make_unique<BOARD>();
1180 board->SetCopperLayerCount( 4 );
1197 pad->SetPosition( padPos );
1201 pad->SetNetCode( 1 );
1210 board->Add( track );
1225 board->Add( stack );
1252 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
1253 board->SetCopperLayerCount( 4 );
1256 board->Add(
new NETINFO_ITEM( board.get(), wxT(
"inner" ), 1 ) );
1266 board->Add( track );
1281 board->Add( stack );
1296 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
1297 board->SetCopperLayerCount( 4 );
1300 board->Add(
new NETINFO_ITEM( board.get(), wxT(
"sig" ), 1 ) );
1310 board->Add( track );
1316 PAD* hole =
new PAD( fp );
1326 BOOST_REQUIRE_EQUAL( hole->
GetNetCode(), 0 );
1365 auto board = std::make_unique<BOARD>();
1366 board->SetCopperLayerCount( 4 );
1378 board->Add( stack );
1386 int viasCollected = 0;
1388 for(
int i = 0; i < collector.
GetCount(); i++ )
1394 BOOST_CHECK_MESSAGE( viasCollected == 2,
"Expected both member vias in the click collection, got "
1395 << viasCollected <<
" of " << collector.
GetCount()
1396 <<
" collected items" );
1399 for(
int i = 0; i < collector.
GetCount(); i++ )
1418 mgr.
SetEnvironment( &board,
nullptr,
nullptr,
nullptr,
nullptr );
1437 BOOST_REQUIRE_EQUAL( stack->
GetItems().size(), 2u );
1446 BOOST_REQUIRE_EQUAL( stack->
GetItems().size(), 3u );
1451 BOOST_REQUIRE_EQUAL( stack->
GetItems().size(), 2u );
1453 std::vector<PCB_VIA*> boardVias;
1458 boardVias.push_back(
static_cast<PCB_VIA*
>( track ) );
1461 BOOST_CHECK_MESSAGE( boardVias.size() == 2,
1462 "Revert left " << boardVias.size() <<
" vias on the board, expected 2" );
1469 BOOST_CHECK_MESSAGE(
via->GetParentGroup() ==
static_cast<EDA_GROUP*
>( stack ),
1470 "Member via at " <<
via->GetPosition().x <<
"," <<
via->GetPosition().y
1471 <<
" lost its back-pointer to the stack after revert" );
1477 BOOST_CHECK_MESSAGE( std::find( board.
Tracks().begin(), board.
Tracks().end(), item ) != board.
Tracks().end(),
1478 "Stack holds a member that is not on the board after revert" );
1488 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
1490 board->SetCopperLayerCount( 6 );
1503 board->Add( stack );
1513 BOOST_CHECK_MESSAGE( reloaded.
GetStartLayer() ==
In1_Cu,
"Start layer lost in the properties round trip" );
1515 <<
" does not track the start layer " <<
In1_Cu
1516 <<
" after a properties round trip" );
1520 BOOST_CHECK( std::find( viewLayers.begin(), viewLayers.end(), (
int)
In1_Cu ) != viewLayers.end() );
1531 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
1533 board->SetCopperLayerCount( 4 );
1547 board->Add( stack );
1550 BOOST_REQUIRE_MESSAGE( stack->
GetItems().empty(),
"Precondition failed: the stack has members, so this test is "
1551 "not exercising a ghost" );
1553 auto path = std::filesystem::temp_directory_path() /
"via_stack_ghost_tst.kicad_pcb";
1558 BOOST_CHECK_MESSAGE( reloaded->Generators().empty(),
1559 "A member-less via stack was written to the board file; it reloads "
1560 "invisible, unpickable and on no net" );
1568 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
1570 board->SetCopperLayerCount( 4 );
1584 board->Add( stack );
1587 BOOST_REQUIRE_EQUAL( stack->
GetItems().size(), 2u );
1589 auto path = std::filesystem::temp_directory_path() /
"via_stack_netkeep_tst.kicad_pcb";
1594 BOOST_REQUIRE_EQUAL( reloaded->Generators().size(), 1u );
1599 NETINFO_ITEM* loadedNet = reloaded->FindNet( wxT(
"MICROVIA_NET" ) );
1603 "Reloaded stack reports net " << loaded->
GetNetCode() <<
", expected "
1616 for(
const wxString&
name : { wxT(
"Start Layer" ), wxT(
"End Layer" ), wxT(
"Style" ), wxT(
"Net" ),
1617 wxT(
"Pitch" ), wxT(
"Via Diameter" ), wxT(
"Via Hole" ), wxT(
"Copper-filled" ),
1618 wxT(
"Capped" ), wxT(
"Use Netclass Values" ) } )
1622 BOOST_REQUIRE_MESSAGE( prop,
"Property \"" <<
name
1623 <<
"\" is missing, so the Properties "
1624 "panel cannot show it" );
1625 BOOST_CHECK_MESSAGE( !prop->
Writeable(
nullptr ),
"Property \"" <<
name
1626 <<
"\" is editable, but editing it cannot "
1627 "rebuild the stack" );
1632 "The inherited \"Layer\" property should be masked for a via stack" );
1638 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
1640 board->SetCopperLayerCount( 6 );
1646 via->SetViaType( aType );
1647 via->SetLayerPair( aTop, aBottom );
1650 via->SetPosition( aPos );
1664 board->Add( stack );
1671 BOOST_CHECK_MESSAGE( ids.count( multiHop->
m_Uuid ) == 1,
1672 "A loose multi-hop microvia must be reported as expandable" );
1673 BOOST_CHECK_MESSAGE( ids.count( owned->
m_Uuid ) == 0,
"A via already in a stack is not expandable" );
1700 via->SetPosition( pos );
1709 std::vector<VECTOR2I> positions;
1713 if( track->Type() ==
PCB_VIA_T && !track->GetParentGroup()
1716 positions.push_back( track->GetPosition() );
1728 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
1735 return aVia->GetNetCode() == 1 ? &preset :
nullptr;
1746 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
1748 board->SetCopperLayerCount( 6 );
1754 auto addMultiHop = [&](
const VECTOR2I& aPos )
1761 via->SetPosition( aPos );
1769 BOOST_REQUIRE_EQUAL( beforeRouting.size(), 1u );
1784 BOOST_REQUIRE_EQUAL( board->Generators().size(), 1u );
1785 BOOST_CHECK_MESSAGE( board->Generators().front()->GetPosition() ==
ROUTED_POS,
1786 "The stack was built at the wrong via" );
1790 BOOST_REQUIRE_MESSAGE( loose.size() == 1,
1791 "Expected the pre-existing via to be left loose, found " << loose.size() );
1792 BOOST_CHECK_MESSAGE( loose.front() ==
PRE_ROUTE_POS,
"A via that predates the route was swallowed into a stack" );
1800 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
1802 board->SetCopperLayerCount( 4 );
1805 board->Add(
new NETINFO_ITEM( board.get(), wxT(
"SHARED" ), 1 ) );
1815 std::vector<PENDING_STACK_EXPANSION> pending = { {
F_Cu,
In2_Cu, 1, preset, dropped } };
1816 std::set<KIID> preRoute;
1825 BOOST_REQUIRE_EQUAL( board->Generators().size(), 1u );
1826 BOOST_CHECK_MESSAGE( board->Generators().front()->GetPosition() == dropped,
1827 "The stack was built at the wrong via" );
1831 BOOST_REQUIRE_EQUAL( loose.size(), 1u );
1832 BOOST_CHECK_MESSAGE( loose.front() == bystander,
"A via the drop did not arm was swallowed into a stack" );
1838 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
1840 board->SetCopperLayerCount( 6 );
1853 board->Add( stack );
1856 auto memberIds = [&]()
1861 ids.insert( item->m_Uuid );
1866 auto countVias = [&]() ->
size_t
1870 for(
PCB_TRACK* track : board->Tracks() )
1879 const std::set<KIID> before = memberIds();
1880 const size_t viasBefore = countVias();
1885 for(
int step = 0; step < 5; ++step )
1891 BOOST_CHECK_MESSAGE( memberIds() == before,
"Moving the stack replaced its members instead of moving them, so a "
1892 "drag would stage one generation of vias per motion event" );
1894 BOOST_CHECK_MESSAGE( countVias() == viasBefore,
"The board gained or lost vias while the stack was moved: "
1895 << countVias() <<
" now, " << viasBefore <<
" before" );
1909 BOOST_REQUIRE_EQUAL( board->Generators().size(), 2u );
1954 BOOST_CHECK( item->GetParentGroup() ==
static_cast<EDA_GROUP*
>( stacked ) );
1965 <<
" capping disagrees with the generator" );
1975 mgr.
SetEnvironment( &board,
nullptr,
nullptr,
nullptr,
nullptr );
1991 auto countVias = [&]() ->
size_t
2004 const size_t before = countVias();
2005 BOOST_REQUIRE_EQUAL( before, 2u );
2010 stack->
Remove(
nullptr, &board, &reverted );
2013 BOOST_CHECK_MESSAGE( countVias() == before,
2014 "Reverting the delete left " << countVias() <<
" vias, expected " << before );
2020 stack->
Remove(
nullptr, &board, &commit );
2021 commit.
Push( wxT(
"Delete Microvia Stack" ) );
2034 preset.
m_Name = wxS(
"HDI 1+N+1" );
2055 std::optional<nlohmann::json> stored = bds.
Get<nlohmann::json>(
"via_stack_presets" );
2070 nlohmann::json entries = nlohmann::json::array();
2072 entries.push_back( { {
"name",
"unknown layer" }, {
"start_layer",
"Nonsense" }, {
"end_layer",
"" } } );
2073 entries.push_back( { {
"start_layer",
"F.Cu" }, {
"end_layer",
"In1.Cu" } } );
2074 entries.push_back(
"not an object" );
2075 entries.push_back( { {
"name",
"not copper" }, {
"start_layer",
"F.SilkS" }, {
"end_layer",
"Edge.Cuts" } } );
2076 entries.push_back( { {
"name",
"still numeric" }, {
"start_layer", 0 }, {
"end_layer", 4 } } );
2078 bds.
Set(
"via_stack_presets", entries );
2086 "Preset \"" << p.
m_Name <<
"\" kept a non-copper layer" );
2094 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
2096 board->SetCopperLayerCount( 6 );
2106 board->Add( stack );
2109 BOOST_REQUIRE_EQUAL( stack->
GetItems().size(), 1u );
2114 std::set<std::pair<int, int>> pairs;
2118 BOOST_REQUIRE_EQUAL( item->Type(),
PCB_VIA_T );
2120 pairs.insert( { (int)
via->TopLayer(), (int)
via->BottomLayer() } );
2128 for(
PCB_TRACK* track : board->Tracks() )
2134 BOOST_CHECK_MESSAGE( vias == 4,
"Widening the span left " << vias <<
" vias on the board, "
2142 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
2144 board->SetCopperLayerCount( 6 );
2152 via->SetViaType( aType );
2153 via->SetLayerPair( aTop, aBottom );
2156 via->SetPosition( pos );
2167 "A selection containing a non-microvia was accepted as a stack" );
2175 BOOST_CHECK( made !=
nullptr );
2184 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
2186 board->SetCopperLayerCount( 6 );
2197 board->Add( stack );
2200 BOOST_REQUIRE_EQUAL( stack->
GetItems().size(), 3u );
2208 BOOST_CHECK_MESSAGE(
via->Padstack().Drill().is_filled.value_or(
false ),
2209 "Every hop of a stacked stack must be filled" );
2211 if(
via->Padstack().Drill().is_capped.value_or(
false ) )
2217 "A buried hop was marked capped" );
2221 BOOST_CHECK_MESSAGE( capped == 1,
"Expected exactly the outer hop to be capped, found " << capped );
2228 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
2230 board->SetCopperLayerCount( 6 );
2241 board->Add( stack );
2244 BOOST_REQUIRE_EQUAL( stack->
GetItems().size(), 2u );
2250 BOOST_CHECK_MESSAGE( !
via->Padstack().Drill().is_capped.value_or(
false ),
2251 "A wholly internal stack has no outer face to cap" );
2266 preset.
m_Name = wxT(
"buried" );
2273 BOOST_CHECK_MESSAGE( stack.
GetLayer() ==
In1_Cu,
"the stack's own layer must follow the preset's start layer" );
2277 BOOST_CHECK_MESSAGE( std::find( layers.begin(), layers.end(),
In1_Cu ) != layers.end(),
2278 "the stack must register in the view on its start layer" );
2302 auto traceWidth = [&]() ->
int
2307 return static_cast<PCB_TRACK*
>( item )->GetWidth();
2313 int placed = traceWidth();
2323 BOOST_CHECK_MESSAGE( traceWidth() == placed,
"trace width changed from " << placed <<
" to " << traceWidth()
2324 <<
" without the user touching it" );
2332 std::unique_ptr<BOARD> board;
2343 auto checkWidth = [&](
const wxString& aNetName,
double aWidthMm )
2355 int width =
static_cast<PCB_TRACK*
>( item )->GetWidth();
2358 BOOST_CHECK_MESSAGE( width ==
pcbIUScale.mmToIU( aWidthMm ), aNetName <<
" trace is " << width );
2367 checkWidth( wxS(
"/DDR4-PS.RSTN" ), 0.1 );
2368 checkWidth( wxS(
"/DDR4-PS.CK_P" ), 0.1 );
2375 checkWidth( wxS(
"/DDR4-PS.RSTN" ), 0.08 );
2376 checkWidth( wxS(
"/DDR4-PS.CK_P" ), 0.1 );
2402 BOOST_CHECK(
copy->m_Uuid != stack->
m_Uuid );
2422 const int netclassDia =
pcbIUScale.mmToIU( 0.25 );
2423 const int netclassDrill =
pcbIUScale.mmToIU( 0.12 );
2431 board.
Add( netinfo );
2444 preset.
m_Name = wxT(
"netclass stack" );
2453 BOOST_REQUIRE_EQUAL( expanded, 1 );
2454 BOOST_REQUIRE_EQUAL( board.
Generators().size(), 1u );
2497 BOOST_CHECK_MESSAGE( stack->
GetBoardItems().size() == 2u,
"hops were destroyed, leaving an invisible stack: "
2535 std::vector<VECTOR2I> centres;
2540 centres.push_back( item->GetPosition() );
2544 auto has = [&](
const VECTOR2I& aPoint )
2546 return std::find( centres.begin(), centres.end(), aPoint ) != centres.end();
2549 BOOST_REQUIRE_EQUAL( centres.size(), 3u );
2554 BOOST_CHECK_MESSAGE( has( origin +
VECTOR2I( 0, 2 * pitch ) ),
"the new hop did not continue the chain" );
2555 BOOST_CHECK_MESSAGE( !has( origin +
VECTOR2I( 2 * pitch, 0 ) ),
"the new hop fell back onto the +X axis" );
2562 for(
bool boardFills : {
false,
true } )
2574 std::vector<BOARD_ITEM*> items;
2581 via->SetLayerPair( pair.first, pair.second );
2584 via->SetPosition( hop++ == 0 ? at :
next );
2586 items.push_back(
via );
2593 BOOST_CHECK_MESSAGE( stack->IsFilled() == boardFills,
2594 "board fill " << boardFills <<
" gave stack fill " << stack->IsFilled() );
2613 via->SetViaType( aType );
2617 via->SetPosition( aPos );
2629 preset.
m_Name = wxT(
"p" );
2634 return aVia->GetNetCode() == net->
GetNetCode() ? &preset :
nullptr;
2639 BOOST_REQUIRE_EQUAL( board.
Generators().size(), 1u );
2642 std::set<KIID> remaining;
2645 remaining.insert( track->m_Uuid );
2647 BOOST_CHECK_MESSAGE( remaining.count( throughId ),
"a through via was converted" );
2648 BOOST_CHECK_MESSAGE( remaining.count( buriedId ),
"a buried via was converted" );
2649 BOOST_CHECK_MESSAGE( !remaining.count( microId ),
"the microvia should have been expanded" );
2673 std::unique_ptr<BOARD> board =
2678 mgr.
SetEnvironment( board.get(),
nullptr,
nullptr,
nullptr,
nullptr );
2694 std::set<KIID> before;
2697 before.insert( item->m_Uuid );
2699 const size_t tracks = board->Tracks().size();
2707 edit.Add( pending );
2717 std::set<KIID> after;
2720 after.insert( item->m_Uuid );
2723 BOOST_CHECK( after == before );
2731 std::unique_ptr<BOARD> board;
2743 auto checkSize = [&](
const VECTOR2I& aPos,
double aDiameterMm,
double aDrillMm )
2748 BOOST_REQUIRE_EQUAL( members.size(), 1u );
constexpr EDA_IU_SCALE pcbIUScale
General utilities for PCB file IO for QA programs.
void Push(const wxString &aMessage=wxEmptyString, int aCommitFlags=0) override
Execute the changes.
void Revert() override
Revert the commit by restoring the modified items state.
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
virtual bool SetNetCode(int aNetCode, bool aNoAssert)
Set net using a net code.
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
Container for design settings for a BOARD object.
void UseCustomTrackViaSize(bool aEnabled)
Enables/disables custom track/via size settings.
std::shared_ptr< NET_SETTINGS > m_NetSettings
void SetCustomTrackWidth(int aWidth)
Sets custom width for track (i.e.
std::shared_ptr< DRC_ENGINE > m_DRCEngine
std::vector< VIA_STACK_PRESET > m_ViaStackPresets
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
void SetUuidDirect(const KIID &aUuid)
Raw UUID assignment.
Information pertinent to a Pcbnew printed circuit board.
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Removes an item from the container.
const GENERATORS & Generators() const
const TRACKS & Tracks() const
void SetCopperLayerCount(int aCount)
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
void SetEnabledLayers(const LSET &aLayerMask)
A proxy function that calls the correspondent function in m_BoardSettings.
constexpr bool Contains(const Vec &aPoint) const
An abstract base class whose derivatives may be passed to a GENERAL_COLLECTOR telling it what should ...
int GetCount() const
Return the number of objects in the list.
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr, RECURSE_MODE aRecurse=RECURSE_MODE::NO_RECURSE)
Modify a given item in the model.
~COUNTED_TRACK() override
COUNTED_TRACK(BOARD *aBoard, int &aDestroyed)
void InitEngine(const wxFileName &aRulePath)
Initialize the DRC engine.
A set of EDA_ITEMs (i.e., without duplicates).
std::unordered_set< EDA_ITEM * > & GetItems()
void AddItem(EDA_ITEM *aItem)
Add item to group.
void SetFlags(EDA_ITEM_FLAGS aMask)
virtual EDA_GROUP * GetParentGroup() const
void ClearFlags(EDA_ITEM_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
bool HasFlag(EDA_ITEM_FLAGS aFlag) const
virtual void SetParent(EDA_ITEM *aParent)
Used when the right click button is pressed, or when the select tool is in effect.
static const std::vector< KICAD_T > AllBoardItems
A scan list for all editable board items.
void Collect(BOARD_ITEM *aItem, const std::vector< KICAD_T > &aScanList, const VECTOR2I &aRefPos, const COLLECTORS_GUIDE &aGuide)
Scan a BOARD_ITEM using this class's Inspector method, which does the collection.
static GENERATORS_MGR & Instance()
void Set(const std::string &aPath, ValueType aVal)
Stores a value into the JSON document Will throw an exception if ValueType isn't something that the l...
virtual void Load()
Updates the parameters of this object based on the current JSON document contents.
std::optional< ValueType > Get(const std::string &aPath) const
Fetches a value from within the JSON document.
virtual bool Store()
Stores the current parameters into the JSON document represented by this object Note: this doesn't do...
LSET is a set of PCB_LAYER_IDs.
static const LSET & AllTechMask()
Return a mask holding all technical layers (no CU layer) on both side.
static LSET AllCuMask(int aCuLayerCount)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
static wxString Name(PCB_LAYER_ID aLayerId)
Return the fixed name association with aLayerId.
void SetuViaDiameter(int aSize)
void SetuViaDrill(int aSize)
Handle the data for a net.
void SetNetClass(const std::shared_ptr< NETCLASS > &aNetClass)
std::shared_ptr< NETCLASS > GetDefaultNetclass() const
Gets the default netclass for the project.
static constexpr PCB_LAYER_ID ALL_LAYERS
! The layer identifier to use for the single defintion on normal padstacks
void SetAttribute(PAD_ATTRIB aAttribute)
void SetShape(PCB_LAYER_ID aLayer, PAD_SHAPE aShape)
Set the new shape of this pad.
void SetDrillShape(PAD_DRILL_SHAPE aShape)
void SetPosition(const VECTOR2I &aPos) override
void SetDrillSize(const VECTOR2I &aSize)
void SetSize(PCB_LAYER_ID aLayer, const VECTOR2I &aSize)
void SetLayerSet(const LSET &aLayers) override
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
void SetPosition(const VECTOR2I &aPos) override
VECTOR2I GetPosition() const override
A set of BOARD_ITEMs (i.e., without duplicates).
static EDA_GROUP * TopLevelGroup(BOARD_ITEM *aItem, EDA_GROUP *aScope, bool isFootprintEditor)
std::unordered_set< BOARD_ITEM * > GetBoardItems() const
PCB_GROUP * DeepDuplicate(bool addToParentGroup, BOARD_COMMIT *aCommit=nullptr, std::map< KIID, KIID > *aKIIDMap=nullptr) const
void SetEnd(const VECTOR2I &aEnd)
void SetStart(const VECTOR2I &aStart)
const VECTOR2I & GetStart() const
const VECTOR2I & GetEnd() const
PCB_TRACK(BOARD_ITEM *aParent, KICAD_T idtype=PCB_TRACE_T)
virtual void SetWidth(int aWidth)
A microvia stack: several single hop microvias, plus connecting traces for staggered stacks,...
void SetHops(const SHAPE_LINE_CHAIN &aHops)
bool Update(GENERATOR_TOOL *aTool, BOARD *aBoard, BOARD_COMMIT *aCommit) override
void Rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle) override
Rotate this object.
void ApplyPreset(const VIA_STACK_PRESET &aPreset)
static int ExpandMultiHopMicrovias(BOARD *aBoard, BOARD_COMMIT *aCommit, const std::function< const VIA_STACK_PRESET *(PCB_VIA *)> &aMatcher=nullptr)
Replace loose microvias spanning more than one hop with stacks of single hop microvias.
void SetProperties(const STRING_ANY_MAP &aProps) override
void SetPitch(int aPitch)
static PCB_VIA_STACK * CreateFromItems(const std::vector< BOARD_ITEM * > &aItems, BOARD *aBoard, std::vector< BOARD_ITEM * > *aMembers=nullptr, wxString *aError=nullptr)
Build a stack from existing board items (microvias plus optional connecting traces).
static std::set< KIID > CollectExpandableMicrovias(BOARD *aBoard)
Ids of the vias ExpandMultiHopMicrovias would consider right now.
void EditStart(GENERATOR_TOOL *aTool, BOARD *aBoard, BOARD_COMMIT *aCommit) override
void Mirror(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection) override
Mirror this object relative to a given horizontal axis the layer is not changed.
static int FindNetAtPosition(BOARD *aBoard, const VECTOR2I &aPosition, PCB_LAYER_ID aLayer)
Net of the copper under a point on the given layer, pads first, then tracks, then filled zones.
void Flip(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection) override
Flip this object, i.e.
void EditFinish(GENERATOR_TOOL *aTool, BOARD *aBoard, BOARD_COMMIT *aCommit) override
void Remove(GENERATOR_TOOL *aTool, BOARD *aBoard, BOARD_COMMIT *aCommit) override
void Regenerate(BOARD *aBoard, BOARD_COMMIT *aCommit)
Rebuild the member vias (and, for a staggered stack, the connecting traces) from the current stack se...
const std::optional< SHAPE_LINE_CHAIN > & GetHops() const
const BOX2I ViewBBox() const override
Return the bounding box of the item covering all its layers.
VIA_STACK_STYLE GetStyle() const
std::vector< int > ViewGetLayers() const override
Return the all the layers within the VIEW the object is painted on.
void SetFilled(bool aFilled)
void SetPresetName(const wxString &aName)
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
const wxString & GetPresetName() const
PCB_LAYER_ID GetStartLayer() const
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
void SetStartLayer(PCB_LAYER_ID aLayer)
PCB_LAYER_ID GetEndLayer() const
bool GetUseNetclass() const
std::vector< BOARD_ITEM * > BuildMembers(BOARD *aBoard, int aNetCode) const
Build the member vias/traces for the current settings and return them without adding them anywhere.
static bool IsSpanValid(BOARD *aBoard, PCB_LAYER_ID aStart, PCB_LAYER_ID aEnd)
True when both span ends are copper layers within the board's copper layer count.
void SetViaSize(int aSize)
void SetCapped(bool aCapped)
void SetViaDrill(int aDrill)
bool HitTest(const VECTOR2I &aPosition, int aAccuracy=0) const override
Test if aPosition is inside or on the boundary of this item.
const STRING_ANY_MAP GetProperties() const override
void SetUseNetclass(bool aUse)
void SetStyle(VIA_STACK_STYLE aStyle)
void Move(const VECTOR2I &aMoveVector) override
Move this object.
void SetEndLayer(PCB_LAYER_ID aLayer)
void SetNetCode(int aNet)
PCB_LAYER_ID BottomLayer() const
const PADSTACK & Padstack() const
void SetDrill(int aDrill)
int GetWidth() const override
PCB_LAYER_ID TopLayer() const
int GetDrillValue() const
Calculate the drill value for vias (m_drill if > 0, or default drill value for the board).
VIATYPE GetViaType() const
void SetWidth(int aWidth) override
virtual bool Writeable(INSPECTABLE *aObject) const
static PROPERTY_MANAGER & Instance()
void Rebuild()
Rebuild the list of all registered properties.
PROPERTY_BASE * GetProperty(TYPE_ID aType, const wxString &aProperty) const
Return a property for a specific type.
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
A name/value tuple with unique names and wxAny values.
void set(const std::string &aKey, const T &aVar)
bool IgnoreMicroVias() const override
bool IgnoreThroughHolePads() const override
bool IgnoreBlindBuriedVias() const override
bool IgnorePadsOnFront() const override
int Accuracy() const override
bool IgnoreFootprintsOnFront() const override
bool IgnoreFPReferences() const override
bool IgnoreTracks() const override
bool IgnoreFPTextOnFront() const override
bool IgnoreNoNets() const override
bool IsLayerVisible(PCB_LAYER_ID) const override
bool IgnoreFootprintsOnBack() const override
PCB_LAYER_ID GetPreferredLayer() const override
bool IgnoreZoneFills() const override
bool IncludeSecondary() const override
Determine if the secondary criteria or 2nd choice items should be included.
bool IgnoreThroughVias() const override
bool IgnoreFPValues() const override
double OnePixelInIU() const override
bool IgnorePadsOnBack() const override
bool IgnoreLockedItems() const override
bool IgnoreFPTextOnBack() const override
static std::string ToStdString(const wxString &aStr)
#define IGNORE_PARENT_GROUP
#define IS_NEW
New item, just created.
#define IN_EDIT
Item currently edited.
static PCB_TRACK * makeSegment(BOARD *aBoard, const VECTOR2I &aStart, const VECTOR2I &aEnd)
bool IsCopperLayer(int aLayerId)
Test whether a layer is a copper layer.
bool IsExternalCopperLayer(int aLayerId)
Test whether a layer is an external (F_Cu or B_Cu) copper layer.
PCB_LAYER_ID
A quick note on layer IDs:
@ LEFT_RIGHT
Flip left to right (around the Y axis)
std::string GetPcbnewTestDataDir()
Utility which returns a path to the data directory where the test board files are stored.
void LoadBoard(SETTINGS_MANAGER &aSettingsManager, const wxString &aRelPath, std::unique_ptr< BOARD > &aBoard)
std::unique_ptr< BOARD > ReadBoardFromFileOrStream(const std::string &aFilename, std::istream &aFallback)
Read a board from a file, or another stream, as appropriate.
void DumpBoardToFile(BOARD &board, const std::filesystem::path &aFilename)
Utility function to simply write a Board out to a file.
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
@ NPTH
like PAD_PTH, but not plated mechanical use only, no connection allowed
Class to handle a set of BOARD_ITEMs.
#define TYPE_HASH(x)
Macro to generate unique identifier for a type.
std::optional< bool > is_capped
True if the drill hole should be capped.
A named microvia stack definition, chosen while routing instead of entering the values each time.
PCB_LAYER_ID m_StartLayer
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
KIBIS top(path, &reporter)
BOOST_TEST_MESSAGE("Polyline has "<< chain.PointCount()<< " points")
BOOST_CHECK_EQUAL(result, "25.4")
BOOST_AUTO_TEST_CASE(FactoryRegistered)
static PCB_VIA * makeMicrovia(BOARD *aBoard, const VECTOR2I &aPos, PCB_LAYER_ID aTop, PCB_LAYER_ID aBottom, int aNet=0)
static std::vector< VECTOR2I > looseMicroviaPositions(BOARD *aBoard)
static PCB_TRACK * makeSegment(BOARD *aBoard, const VECTOR2I &aStart, const VECTOR2I &aEnd)
static const VECTOR2I ROUTED_POS(pcbIUScale.mmToIU(10), pcbIUScale.mmToIU(10))
static void makeSharedNetMultiHopPair(BOARD *aBoard)
static const VECTOR2I PRE_ROUTE_POS(pcbIUScale.mmToIU(50), pcbIUScale.mmToIU(50))
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
VECTOR2< int32_t > VECTOR2I