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 );
454 via->SetLayerPair( aTop, aBottom );
457 via->SetPosition( aPos );
458 via->SetNetCode( aNet );
468 auto board = std::make_unique<BOARD>();
469 board->SetCopperLayerCount( 4 );
474 std::vector<BOARD_ITEM*> items;
493 auto board = std::make_unique<BOARD>();
494 board->SetCopperLayerCount( 4 );
499 std::vector<BOARD_ITEM*> items;
511 auto board = std::make_unique<BOARD>();
512 board->SetCopperLayerCount( 4 );
544 found =
via->GetPosition();
549 BOOST_CHECK_MESSAGE( found == last,
"the end layer via is the last hop, not the stack position" );
556 auto board = std::make_unique<BOARD>();
557 board->SetCopperLayerCount( 4 );
560 board->Add(
new NETINFO_ITEM( board.get(), wxT(
"sig" ), 1 ) );
561 board->Add(
new NETINFO_ITEM( board.get(), wxT(
"other" ), 2 ) );
564 preset.
m_Name = wxT(
"fanout" );
568 std::vector<PENDING_STACK_EXPANSION> pending = { {
F_Cu,
In2_Cu, 1, preset, dropped } };
569 std::set<KIID> preRoute;
577 std::vector<PENDING_STACK_EXPANSION> upward = { {
In2_Cu,
F_Cu, 1, preset, dropped } };
591 std::vector<PENDING_STACK_EXPANSION> armed = { {
F_Cu,
In2_Cu, 1, preset, std::nullopt } };
595 preRoute.insert( match->
m_Uuid );
604 nlohmann::json entries = nlohmann::json::array();
606 entries.push_back( { {
"name",
"HDI" }, {
"start_layer",
"F.Cu" }, {
"end_layer",
"In1.Cu" } } );
607 entries.push_back( { {
"name",
"hdi" }, {
"start_layer",
"F.Cu" }, {
"end_layer",
"In2.Cu" } } );
608 entries.push_back( { {
"name",
"Other" }, {
"start_layer",
"F.Cu" }, {
"end_layer",
"In1.Cu" } } );
610 bds.
Set(
"via_stack_presets", entries );
625 nlohmann::json entries = nlohmann::json::array();
628 entries.push_back( { {
"name",
"wrong unit" }, {
"via_size", 300000.0 }, {
"via_drill", 150000.0 } } );
629 entries.push_back( { {
"name",
"negative" }, {
"via_size", -5000.0 }, {
"via_drill", -5000.0 } } );
630 entries.push_back( { {
"name",
"sane" }, {
"via_size", 0.3 }, {
"via_drill", 0.15 } } );
632 bds.
Set(
"via_stack_presets", entries );
652 auto board = std::make_unique<BOARD>();
655 auto capped = [](
PCB_VIA* aVia )
657 aVia->Padstack().Drill().is_capped =
true;
669 BOOST_CHECK_MESSAGE( topAnchored->IsCapped(),
"capping was dropped on a stack anchored at the front" );
679 BOOST_CHECK_MESSAGE( bottomAnchored->IsCapped(),
"capping was dropped on a stack anchored at the back" );
687 auto board = std::make_unique<BOARD>();
703 BOOST_CHECK_MESSAGE( stack->GetHops()->PointCount() == 3,
704 "hop chain has " << stack->GetHops()->PointCount() <<
" points for 3 vias" );
706 BOOST_CHECK( stack->GetHops()->CPoint( 0 ) == at );
707 BOOST_CHECK( stack->GetHops()->CPoint( 1 ) == at );
708 BOOST_CHECK( stack->GetHops()->CPoint( 2 ) == offset );
715 auto board = std::make_unique<BOARD>();
716 board->SetCopperLayerCount( 4 );
719 board->Add(
new NETINFO_ITEM( board.get(), wxT(
"A" ), 1 ) );
720 board->Add(
new NETINFO_ITEM( board.get(), wxT(
"B" ), 2 ) );
730 std::vector<BOARD_ITEM*> items = { upper, lower };
747 auto board = std::make_unique<BOARD>();
748 board->SetCopperLayerCount( 4 );
756 std::vector<BOARD_ITEM*> items = { upper, lower };
761 BOOST_CHECK( !error.IsEmpty() );
772 BOOST_CHECK( stack );
785 props.
set(
"start_layer", wxString( wxS(
"Not.A.Layer" ) ) );
786 props.
set(
"end_layer", wxString( wxS(
"B.Adhes" ) ) );
814 auto board = std::make_unique<BOARD>();
815 board->SetCopperLayerCount( 4 );
818 board->Add(
new NETINFO_ITEM( board.get(), wxT(
"A" ), 1 ) );
819 board->Add(
new NETINFO_ITEM( board.get(), wxT(
"B" ), 2 ) );
844 std::vector<BOARD_ITEM*> items = { hop0, hop1, connector, offLanding, otherNet, loose, zeroLength };
845 std::vector<BOARD_ITEM*> members;
853 for(
PCB_TRACK* stray : { offLanding, otherNet, loose, zeroLength } )
855 BOOST_CHECK_MESSAGE( std::count( members.begin(), members.end(), (
BOARD_ITEM*) stray ) == 0,
856 "a trace that does not link two hops joined the stack" );
864 auto board = std::make_unique<BOARD>();
865 board->SetCopperLayerCount( 4 );
879 std::vector<BOARD_ITEM*> items;
882 items.push_back( item );
884 BOOST_REQUIRE_EQUAL( items.size(), 2u );
893 auto board = std::make_unique<BOARD>();
894 board->SetCopperLayerCount( 4 );
906 BOOST_REQUIRE_EQUAL( board->Generators().size(), 1u );
918 BOOST_CHECK(
via->GetPosition() == pos );
926 for(
PCB_TRACK* track : board->Tracks() )
931 BOOST_CHECK(
via->GetParentGroup() !=
nullptr );
955 auto countVias = [&]() ->
size_t
968 BOOST_REQUIRE_EQUAL( countVias(), 1u );
977 BOOST_REQUIRE_EQUAL( countVias(), 1u );
990 commit.
Push( wxT(
"Expand Microvia Stacks" ) );
992 BOOST_REQUIRE_EQUAL( board.
Generators().size(), 1u );
998 BOOST_CHECK( track->GetParentGroup() !=
nullptr );
1008 auto board = std::make_unique<BOARD>();
1009 board->SetCopperLayerCount( 4 );
1025 board->Add( stack );
1028 board->BuildConnectivity();
1030 std::vector<PCB_VIA*> vias;
1035 vias.push_back(
static_cast<PCB_VIA*
>( item ) );
1038 BOOST_REQUIRE_EQUAL( vias.size(), 2u );
1040 std::vector<BOARD_CONNECTED_ITEM*> connected = board->GetConnectivity()->GetConnectedItems( vias[0] );
1042 bool otherFound = std::find( connected.begin(), connected.end(),
static_cast<BOARD_CONNECTED_ITEM*
>( vias[1] ) )
1045 BOOST_CHECK_MESSAGE( otherFound,
"Coaxial microvia hops sharing the inner layer must be connected." );
1055 mgr.
SetEnvironment( &board,
nullptr,
nullptr,
nullptr,
nullptr );
1080 stack->
EditStart(
nullptr, &board, &commit );
1081 stack->
Update(
nullptr, &board, &commit );
1082 stack->
EditFinish(
nullptr, &board, &commit );
1085 commit.
Push( wxT(
"Place Microvia Stack" ) );
1087 BOOST_REQUIRE_EQUAL( board.
Generators().size(), 1u );
1091 std::vector<PCB_VIA*> boardVias;
1096 boardVias.push_back(
static_cast<PCB_VIA*
>( track ) );
1099 BOOST_REQUIRE_EQUAL( boardVias.size(), 2u );
1125 BOOST_CHECK( stack->
HitTest( pos, 0 ) );
1129 BOOST_CHECK( stack->
HitTest( around,
false, 0 ) );
1130 BOOST_CHECK( stack->
HitTest( around,
true, 0 ) );
1135 BOOST_CHECK( std::find( viewLayers.begin(), viewLayers.end(), (
int) stack->
GetLayer() ) != viewLayers.end() );
1143 auto board = std::make_unique<BOARD>();
1144 board->SetCopperLayerCount( 6 );
1161 board->Add( stack );
1182 for(
PCB_TRACK* track : board->Tracks() )
1193 auto board = std::make_unique<BOARD>();
1194 board->SetCopperLayerCount( 4 );
1211 pad->SetPosition( padPos );
1215 pad->SetNetCode( 1 );
1224 board->Add( track );
1239 board->Add( stack );
1266 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
1267 board->SetCopperLayerCount( 4 );
1270 board->Add(
new NETINFO_ITEM( board.get(), wxT(
"inner" ), 1 ) );
1280 board->Add( track );
1295 board->Add( stack );
1310 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
1311 board->SetCopperLayerCount( 4 );
1314 board->Add(
new NETINFO_ITEM( board.get(), wxT(
"sig" ), 1 ) );
1324 board->Add( track );
1330 PAD* hole =
new PAD( fp );
1340 BOOST_REQUIRE_EQUAL( hole->
GetNetCode(), 0 );
1379 auto board = std::make_unique<BOARD>();
1380 board->SetCopperLayerCount( 4 );
1392 board->Add( stack );
1400 int viasCollected = 0;
1402 for(
int i = 0; i < collector.
GetCount(); i++ )
1408 BOOST_CHECK_MESSAGE( viasCollected == 2,
"Expected both member vias in the click collection, got "
1409 << viasCollected <<
" of " << collector.
GetCount()
1410 <<
" collected items" );
1413 for(
int i = 0; i < collector.
GetCount(); i++ )
1432 mgr.
SetEnvironment( &board,
nullptr,
nullptr,
nullptr,
nullptr );
1451 BOOST_REQUIRE_EQUAL( stack->
GetItems().size(), 2u );
1460 BOOST_REQUIRE_EQUAL( stack->
GetItems().size(), 3u );
1465 BOOST_REQUIRE_EQUAL( stack->
GetItems().size(), 2u );
1467 std::vector<PCB_VIA*> boardVias;
1472 boardVias.push_back(
static_cast<PCB_VIA*
>( track ) );
1475 BOOST_CHECK_MESSAGE( boardVias.size() == 2,
1476 "Revert left " << boardVias.size() <<
" vias on the board, expected 2" );
1483 BOOST_CHECK_MESSAGE(
via->GetParentGroup() ==
static_cast<EDA_GROUP*
>( stack ),
1484 "Member via at " <<
via->GetPosition().x <<
"," <<
via->GetPosition().y
1485 <<
" lost its back-pointer to the stack after revert" );
1491 BOOST_CHECK_MESSAGE( std::find( board.
Tracks().begin(), board.
Tracks().end(), item ) != board.
Tracks().end(),
1492 "Stack holds a member that is not on the board after revert" );
1502 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
1504 board->SetCopperLayerCount( 6 );
1517 board->Add( stack );
1527 BOOST_CHECK_MESSAGE( reloaded.
GetStartLayer() ==
In1_Cu,
"Start layer lost in the properties round trip" );
1529 <<
" does not track the start layer " <<
In1_Cu
1530 <<
" after a properties round trip" );
1534 BOOST_CHECK( std::find( viewLayers.begin(), viewLayers.end(), (
int)
In1_Cu ) != viewLayers.end() );
1545 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
1547 board->SetCopperLayerCount( 4 );
1561 board->Add( stack );
1564 BOOST_REQUIRE_MESSAGE( stack->
GetItems().empty(),
"Precondition failed: the stack has members, so this test is "
1565 "not exercising a ghost" );
1567 auto path = std::filesystem::temp_directory_path() /
"via_stack_ghost_tst.kicad_pcb";
1572 BOOST_CHECK_MESSAGE( reloaded->Generators().empty(),
1573 "A member-less via stack was written to the board file; it reloads "
1574 "invisible, unpickable and on no net" );
1582 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
1584 board->SetCopperLayerCount( 4 );
1598 board->Add( stack );
1601 BOOST_REQUIRE_EQUAL( stack->
GetItems().size(), 2u );
1603 auto path = std::filesystem::temp_directory_path() /
"via_stack_netkeep_tst.kicad_pcb";
1608 BOOST_REQUIRE_EQUAL( reloaded->Generators().size(), 1u );
1613 NETINFO_ITEM* loadedNet = reloaded->FindNet( wxT(
"MICROVIA_NET" ) );
1617 "Reloaded stack reports net " << loaded->
GetNetCode() <<
", expected "
1630 for(
const wxString&
name : { wxT(
"Start Layer" ), wxT(
"End Layer" ), wxT(
"Style" ), wxT(
"Net" ),
1631 wxT(
"Pitch" ), wxT(
"Via Diameter" ), wxT(
"Via Hole" ), wxT(
"Copper-filled" ),
1632 wxT(
"Capped" ), wxT(
"Use Netclass Values" ) } )
1636 BOOST_REQUIRE_MESSAGE( prop,
"Property \"" <<
name
1637 <<
"\" is missing, so the Properties "
1638 "panel cannot show it" );
1639 BOOST_CHECK_MESSAGE( !prop->
Writeable(
nullptr ),
"Property \"" <<
name
1640 <<
"\" is editable, but editing it cannot "
1641 "rebuild the stack" );
1646 "The inherited \"Layer\" property should be masked for a via stack" );
1652 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
1654 board->SetCopperLayerCount( 6 );
1660 via->SetViaType( aType );
1661 via->SetLayerPair( aTop, aBottom );
1664 via->SetPosition( aPos );
1678 board->Add( stack );
1685 BOOST_CHECK_MESSAGE( ids.count( multiHop->
m_Uuid ) == 1,
1686 "A loose multi-hop microvia must be reported as expandable" );
1687 BOOST_CHECK_MESSAGE( ids.count( owned->
m_Uuid ) == 0,
"A via already in a stack is not expandable" );
1714 via->SetPosition( pos );
1723 std::vector<VECTOR2I> positions;
1727 if( track->Type() ==
PCB_VIA_T && !track->GetParentGroup()
1730 positions.push_back( track->GetPosition() );
1742 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
1749 return aVia->GetNetCode() == 1 ? &preset :
nullptr;
1760 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
1762 board->SetCopperLayerCount( 6 );
1768 auto addMultiHop = [&](
const VECTOR2I& aPos )
1775 via->SetPosition( aPos );
1783 BOOST_REQUIRE_EQUAL( beforeRouting.size(), 1u );
1798 BOOST_REQUIRE_EQUAL( board->Generators().size(), 1u );
1799 BOOST_CHECK_MESSAGE( board->Generators().front()->GetPosition() ==
ROUTED_POS,
1800 "The stack was built at the wrong via" );
1804 BOOST_REQUIRE_MESSAGE( loose.size() == 1,
1805 "Expected the pre-existing via to be left loose, found " << loose.size() );
1806 BOOST_CHECK_MESSAGE( loose.front() ==
PRE_ROUTE_POS,
"A via that predates the route was swallowed into a stack" );
1814 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
1816 board->SetCopperLayerCount( 4 );
1819 board->Add(
new NETINFO_ITEM( board.get(), wxT(
"SHARED" ), 1 ) );
1829 std::vector<PENDING_STACK_EXPANSION> pending = { {
F_Cu,
In2_Cu, 1, preset, dropped } };
1830 std::set<KIID> preRoute;
1839 BOOST_REQUIRE_EQUAL( board->Generators().size(), 1u );
1840 BOOST_CHECK_MESSAGE( board->Generators().front()->GetPosition() == dropped,
1841 "The stack was built at the wrong via" );
1845 BOOST_REQUIRE_EQUAL( loose.size(), 1u );
1846 BOOST_CHECK_MESSAGE( loose.front() == bystander,
"A via the drop did not arm was swallowed into a stack" );
1852 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
1854 board->SetCopperLayerCount( 6 );
1867 board->Add( stack );
1870 auto memberIds = [&]()
1875 ids.insert( item->m_Uuid );
1880 auto countVias = [&]() ->
size_t
1884 for(
PCB_TRACK* track : board->Tracks() )
1893 const std::set<KIID> before = memberIds();
1894 const size_t viasBefore = countVias();
1899 for(
int step = 0; step < 5; ++step )
1905 BOOST_CHECK_MESSAGE( memberIds() == before,
"Moving the stack replaced its members instead of moving them, so a "
1906 "drag would stage one generation of vias per motion event" );
1908 BOOST_CHECK_MESSAGE( countVias() == viasBefore,
"The board gained or lost vias while the stack was moved: "
1909 << countVias() <<
" now, " << viasBefore <<
" before" );
1920 BOOST_REQUIRE_EQUAL( board->Generators().size(), 2u );
1965 BOOST_CHECK( item->GetParentGroup() ==
static_cast<EDA_GROUP*
>( stacked ) );
1976 <<
" capping disagrees with the generator" );
1986 mgr.
SetEnvironment( &board,
nullptr,
nullptr,
nullptr,
nullptr );
2002 auto countVias = [&]() ->
size_t
2015 const size_t before = countVias();
2016 BOOST_REQUIRE_EQUAL( before, 2u );
2021 stack->
Remove(
nullptr, &board, &reverted );
2024 BOOST_CHECK_MESSAGE( countVias() == before,
2025 "Reverting the delete left " << countVias() <<
" vias, expected " << before );
2031 stack->
Remove(
nullptr, &board, &commit );
2032 commit.
Push( wxT(
"Delete Microvia Stack" ) );
2045 preset.
m_Name = wxS(
"HDI 1+N+1" );
2066 std::optional<nlohmann::json> stored = bds.
Get<nlohmann::json>(
"via_stack_presets" );
2081 nlohmann::json entries = nlohmann::json::array();
2083 entries.push_back( { {
"name",
"unknown layer" }, {
"start_layer",
"Nonsense" }, {
"end_layer",
"" } } );
2084 entries.push_back( { {
"start_layer",
"F.Cu" }, {
"end_layer",
"In1.Cu" } } );
2085 entries.push_back(
"not an object" );
2086 entries.push_back( { {
"name",
"not copper" }, {
"start_layer",
"F.SilkS" }, {
"end_layer",
"Edge.Cuts" } } );
2087 entries.push_back( { {
"name",
"still numeric" }, {
"start_layer", 0 }, {
"end_layer", 4 } } );
2089 bds.
Set(
"via_stack_presets", entries );
2097 "Preset \"" << p.
m_Name <<
"\" kept a non-copper layer" );
2105 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
2107 board->SetCopperLayerCount( 6 );
2117 board->Add( stack );
2120 BOOST_REQUIRE_EQUAL( stack->
GetItems().size(), 1u );
2125 std::set<std::pair<int, int>> pairs;
2129 BOOST_REQUIRE_EQUAL( item->Type(),
PCB_VIA_T );
2131 pairs.insert( { (int)
via->TopLayer(), (int)
via->BottomLayer() } );
2139 for(
PCB_TRACK* track : board->Tracks() )
2145 BOOST_CHECK_MESSAGE( vias == 4,
"Widening the span left " << vias <<
" vias on the board, "
2153 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
2155 board->SetCopperLayerCount( 6 );
2163 via->SetViaType( aType );
2164 via->SetLayerPair( aTop, aBottom );
2167 via->SetPosition( pos );
2178 "A selection containing a non-microvia was accepted as a stack" );
2186 BOOST_CHECK( made !=
nullptr );
2195 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
2197 board->SetCopperLayerCount( 6 );
2208 board->Add( stack );
2211 BOOST_REQUIRE_EQUAL( stack->
GetItems().size(), 3u );
2219 BOOST_CHECK_MESSAGE(
via->Padstack().Drill().is_filled.value_or(
false ),
2220 "Every hop of a stacked stack must be filled" );
2222 if(
via->Padstack().Drill().is_capped.value_or(
false ) )
2228 "A buried hop was marked capped" );
2232 BOOST_CHECK_MESSAGE( capped == 1,
"Expected exactly the outer hop to be capped, found " << capped );
2239 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
2241 board->SetCopperLayerCount( 6 );
2252 board->Add( stack );
2255 BOOST_REQUIRE_EQUAL( stack->
GetItems().size(), 2u );
2261 BOOST_CHECK_MESSAGE( !
via->Padstack().Drill().is_capped.value_or(
false ),
2262 "A wholly internal stack has no outer face to cap" );
2277 preset.
m_Name = wxT(
"buried" );
2284 BOOST_CHECK_MESSAGE( stack.
GetLayer() ==
In1_Cu,
"the stack's own layer must follow the preset's start layer" );
2288 BOOST_CHECK_MESSAGE( std::find( layers.begin(), layers.end(),
In1_Cu ) != layers.end(),
2289 "the stack must register in the view on its start layer" );
2313 auto traceWidth = [&]() ->
int
2318 return static_cast<PCB_TRACK*
>( item )->GetWidth();
2324 int placed = traceWidth();
2334 BOOST_CHECK_MESSAGE( traceWidth() == placed,
"trace width changed from " << placed <<
" to " << traceWidth()
2335 <<
" without the user touching it" );
2343 std::unique_ptr<BOARD> board;
2354 auto checkWidth = [&](
const wxString& aNetName,
double aWidthMm )
2366 int width =
static_cast<PCB_TRACK*
>( item )->GetWidth();
2369 BOOST_CHECK_MESSAGE( width ==
pcbIUScale.mmToIU( aWidthMm ), aNetName <<
" trace is " << width );
2378 checkWidth( wxS(
"/DDR4-PS.RSTN" ), 0.1 );
2379 checkWidth( wxS(
"/DDR4-PS.CK_P" ), 0.1 );
2386 checkWidth( wxS(
"/DDR4-PS.RSTN" ), 0.08 );
2387 checkWidth( wxS(
"/DDR4-PS.CK_P" ), 0.1 );
2413 BOOST_CHECK(
copy->m_Uuid != stack->
m_Uuid );
2433 const int netclassDia =
pcbIUScale.mmToIU( 0.25 );
2434 const int netclassDrill =
pcbIUScale.mmToIU( 0.12 );
2442 board.
Add( netinfo );
2455 preset.
m_Name = wxT(
"netclass stack" );
2464 BOOST_REQUIRE_EQUAL( expanded, 1 );
2465 BOOST_REQUIRE_EQUAL( board.
Generators().size(), 1u );
2508 BOOST_CHECK_MESSAGE( stack->
GetBoardItems().size() == 2u,
"hops were destroyed, leaving an invisible stack: "
2546 std::vector<VECTOR2I> centres;
2551 centres.push_back( item->GetPosition() );
2555 auto has = [&](
const VECTOR2I& aPoint )
2557 return std::find( centres.begin(), centres.end(), aPoint ) != centres.end();
2560 BOOST_REQUIRE_EQUAL( centres.size(), 3u );
2565 BOOST_CHECK_MESSAGE( has( origin +
VECTOR2I( 0, 2 * pitch ) ),
"the new hop did not continue the chain" );
2566 BOOST_CHECK_MESSAGE( !has( origin +
VECTOR2I( 2 * pitch, 0 ) ),
"the new hop fell back onto the +X axis" );
2573 for(
bool boardFills : {
false,
true } )
2585 std::vector<BOARD_ITEM*> items;
2592 via->SetLayerPair( pair.first, pair.second );
2595 via->SetPosition( hop++ == 0 ? at :
next );
2597 items.push_back(
via );
2604 BOOST_CHECK_MESSAGE( stack->IsFilled() == boardFills,
2605 "board fill " << boardFills <<
" gave stack fill " << stack->IsFilled() );
2624 via->SetViaType( aType );
2628 via->SetPosition( aPos );
2640 preset.
m_Name = wxT(
"p" );
2645 return aVia->GetNetCode() == net->
GetNetCode() ? &preset :
nullptr;
2650 BOOST_REQUIRE_EQUAL( board.
Generators().size(), 1u );
2653 std::set<KIID> remaining;
2656 remaining.insert( track->m_Uuid );
2658 BOOST_CHECK_MESSAGE( remaining.count( throughId ),
"a through via was converted" );
2659 BOOST_CHECK_MESSAGE( remaining.count( buriedId ),
"a buried via was converted" );
2660 BOOST_CHECK_MESSAGE( !remaining.count( microId ),
"the microvia should have been expanded" );
2687 mgr.
SetEnvironment( board.get(),
nullptr,
nullptr,
nullptr,
nullptr );
2703 std::set<KIID> before;
2706 before.insert( item->m_Uuid );
2708 const size_t tracks = board->Tracks().size();
2716 edit.Add( pending );
2726 std::set<KIID> after;
2729 after.insert( item->m_Uuid );
2732 BOOST_CHECK( after == before );
2740 std::unique_ptr<BOARD> board;
2752 auto checkSize = [&](
const VECTOR2I& aPos,
double aDiameterMm,
double aDrillMm )
2757 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)
void SetEnabledLayers(const LSET &aLayerMask)
A proxy function that calls the correspondent function in m_BoardSettings.
BOARD_DESIGN_SETTINGS & GetDesignSettings()
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(const BOARD_ITEM &aItem, const EDA_GROUP *aScope, bool isFootprintEditor)
Search for highest level group inside of aScope, containing item.
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.
std::unique_ptr< BOARD > RequireBoardFromPcbnewQAData(const std::filesystem::path &aFilename)
Require a board from the path relative to the pcbnew QA data directory.
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