26#include <unordered_map>
112 if( aPower && !bPower )
114 else if( bPower && !aPower )
120 bool a_lowQualityName = a_name.Contains(
"-Pad" );
121 bool b_lowQualityName = b_name.Contains(
"-Pad" );
123 if( a_lowQualityName && !b_lowQualityName )
125 else if( b_lowQualityName && !a_lowQualityName )
128 return a_name < b_name;
135 return a_name < b_name;
139 std::set<
SCH_ITEM*,
decltype( candidate_cmp )> candidates( candidate_cmp );
140 std::set<
SCH_ITEM*,
decltype( strong_cmp )> strong_drivers( strong_cmp );
156 && !
static_cast<SCH_PIN*
>( item )->GetParentSymbol()->IsInNetlist() )
160 strong_drivers.insert( item );
162 if( item_priority > highest_priority )
165 candidates.insert( item );
166 highest_priority = item_priority;
168 else if( !candidates.empty() && ( item_priority == highest_priority ) )
170 candidates.insert( item );
180 if( !candidates.empty() )
182 if( candidates.size() > 1 )
193 if( p->
GetShape() == LABEL_FLAG_SHAPE::L_OUTPUT )
206 if( strong_drivers.size() > 1 )
213 m_drivers.insert( strong_drivers.begin(), strong_drivers.end() );
243 aSubgraphs.insert( sg );
247 aItems.emplace(
m_sheet, item );
261#ifdef CONNECTIVITY_DEBUG
262 wxASSERT_MSG(
false, wxS(
"Tried to get the net name of an item with no connection" ) );
274 std::vector<SCH_ITEM*> labels;
278 switch( item->Type() )
286 if( type == CONNECTION_TYPE::BUS || type == CONNECTION_TYPE::BUS_GROUP )
287 labels.push_back( item );
303 std::vector<SCH_ITEM*> labels;
307 switch( item->Type() )
315 if( label_conn->
Type() == CONNECTION_TYPE::BUS )
316 labels.push_back( item );
332 switch( aItem->
Type() )
338 return pin->GetDefaultNetName(
m_sheet, forceNoConnect );
356 wxFAIL_MSG( wxS(
"Unhandled item type in GetNameForDriver" ) );
360 return wxEmptyString;
387 SCH_FIELD* field = static_cast<SCH_FIELD*>( aChild );
389 if( field->GetCanonicalName() == wxT(
"Netclass" ) )
391 netclass = field->GetText();
425 child->m_absorbed_by =
this;
428 set_absorbed_by( subchild );
436 set_absorbed_by( aOther );
486 switch( aDriver->
Type() )
513 std::back_inserter(
m_items ) );
573 if( subgraph->m_graph ==
this )
597 std::function<
void(
SCH_ITEM* )>* aChangedItemHandler )
599 PROF_TIMER recalc_time(
"CONNECTION_GRAPH::Recalculate" );
604 PROF_TIMER update_items(
"updateItemConnectivity" );
607 std::set<SCH_ITEM*> dirty_items;
611 std::vector<SCH_ITEM*> items;
614 std::vector<std::pair<SCH_SYMBOL*, int>> symbolsChanged;
616 for(
SCH_ITEM* item : sheet.LastScreen()->Items() )
618 if( item->IsConnectable() && ( aUnconditional || item->IsConnectivityDirty() ) )
620 wxLogTrace(
ConnTrace, wxT(
"Adding item %s to connectivity graph update" ),
621 item->GetTypeDesc() );
622 items.push_back( item );
623 dirty_items.insert( item );
634 if( symbol->
GetUnit() != new_unit )
635 symbolsChanged.push_back( { symbol, symbol->
GetUnit() } );
637 symbol->UpdateUnit( new_unit );
646 sheet.LastScreen()->TestDanglingEnds( &sheet, aChangedItemHandler );
650 for(
auto& item : symbolsChanged )
652 item.first->UpdateUnit( item.second );
657 item->SetConnectivityDirty(
false );
662 PROF_TIMER build_graph(
"buildConnectionGraph" );
664 buildConnectionGraph( aChangedItemHandler );
676 const std::set<SCH_ITEM*> &aItems )
678 std::set<std::pair<SCH_SHEET_PATH, SCH_ITEM*>> retvals;
679 std::set<CONNECTION_SUBGRAPH*> subgraphs;
684 while( aSubgraph->m_absorbed_by )
686 wxASSERT( aSubgraph->m_graph == aSubgraph->m_absorbed_by->m_graph );
687 aSubgraph = aSubgraph->m_absorbed_by;
691 while( aSubgraph->m_hier_parent )
693 wxASSERT( aSubgraph->m_graph == aSubgraph->m_hier_parent->m_graph );
694 aSubgraph = aSubgraph->m_hier_parent;
698 aSubgraph->getAllConnectedItems( retvals, subgraphs );
710 traverse_subgraph( sg );
715 traverse_subgraph( bus_sg );
721 traverse_subgraph( bus_sg );
737 std::set<int> codes_to_remove;
741 std::sort( el.second.begin(), el.second.end() );
746 for(
auto& it : sg->m_bus_neighbors )
752 for(
auto test = parents.begin();
test != parents.end(); )
760 if( parents.empty() )
765 for(
auto& it : sg->m_bus_parents )
771 for(
auto test = neighbors.begin();
test != neighbors.end(); )
779 if( neighbors.empty() )
800 auto it = std::lower_bound( el.second.begin(), el.second.end(), sg );
802 while( it != el.second.end() && *it == sg )
803 it = el.second.erase( it );
806 auto remove_sg = [sg](
auto it ) ->
bool
819 if( remove_sg( it ) )
827 if( remove_sg( it ) )
835 if( remove_sg( it ) )
837 codes_to_remove.insert( it->first.Netcode );
846 if( remove_sg( it ) )
854 if( it->second == sg )
865 if( codes_to_remove.find( it->second ) != codes_to_remove.end() )
873 if( codes_to_remove.find( it->second ) != codes_to_remove.end() )
882 sg->m_graph =
nullptr;
889 const std::vector<SCH_ITEM*>& aItemList )
891 std::map<VECTOR2I, std::vector<SCH_ITEM*>> connection_map;
895 std::vector<VECTOR2I> points = item->GetConnectionPoints();
896 item->ConnectedItems( aSheet ).clear();
902 pin->InitializeConnection( aSheet,
this );
904 pin->ConnectedItems( aSheet ).clear();
906 connection_map[
pin->GetTextPos() ].push_back(
pin );
921 wxString
name =
pin->GetDefaultNetName( aSheet );
922 pin->ConnectedItems( aSheet ).clear();
925 if(
pin->IsGlobalPower() )
931 connection_map[ pos ].push_back(
pin );
938 SCH_CONNECTION* conn = item->InitializeConnection( aSheet,
this );
941 switch( item->Type() )
945 CONNECTION_TYPE::NET );
949 conn->
SetType( CONNECTION_TYPE::BUS );
956 conn->
SetType( CONNECTION_TYPE::NET );
960 conn->
SetType( CONNECTION_TYPE::NET );
969 for(
const VECTOR2I& point : points )
970 connection_map[ point ].push_back( item );
974 for(
const auto& it : connection_map )
976 std::vector<SCH_ITEM*> connection_vec = it.second;
977 std::sort( connection_vec.begin(), connection_vec.end() );
983 std::mutex update_mutex;
985 auto update_lambda = [&](
SCH_ITEM* connected_item ) ->
size_t
999 if( connection_vec.size() == 1 )
1012 if( connection_vec.size() < 2 )
1018 if( it.first == bus_entry->GetPosition() )
1021 bus_entry->m_connected_bus_items[1] = busLine;
1023 std::lock_guard<std::mutex> lock( update_mutex );
1036 SCH_ITEM_SET& connected_set = connected_item->ConnectedItems( aSheet );
1037 connected_set.reserve( connection_vec.size() );
1039 for(
SCH_ITEM* test_item : connection_vec )
1041 bool bus_connection_ok =
true;
1043 if( test_item == connected_item )
1049 if( test_item->GetLayer() ==
LAYER_BUS )
1068 if( connected_item->ConnectionPropagatesTo( test_item ) &&
1069 test_item->ConnectionPropagatesTo( connected_item ) &&
1072 connected_set.push_back( test_item );
1083 if( !bus_entry->m_connected_bus_item )
1089 bus_entry->m_connected_bus_item = bus;
1098 tp.push_loop( connection_vec.size(),
1099 [&](
const int a,
const int b)
1101 for( int ii = a; ii < b; ++ii )
1102 update_lambda( connection_vec[ii] );
1104 tp.wait_for_tasks();
1112 wxCHECK_RET(
m_schematic, wxS(
"Connection graph cannot be built without schematic pointer" ) );
1116 for(
unsigned i = 0; i < all_sheets.size(); i++ )
1118 for(
const std::shared_ptr<BUS_ALIAS>& alias : all_sheets[i].LastScreen()->GetBusAliases() )
1126 for(
const auto& it : item->m_connection_map )
1143 std::list<SCH_ITEM*> memberlist;
1148 SCH_CONNECTION* conn = aItem->GetOrInitConnection( sheet,
this );
1149 bool unique = !( aItem->GetFlags() &
CANDIDATE );
1154 return ( unique && conn && ( conn->
SubgraphCode() == 0 ) );
1157 std::copy_if( item->ConnectedItems( sheet ).begin(),
1158 item->ConnectedItems( sheet ).end(),
1159 std::back_inserter( memberlist ), get_items );
1161 for(
SCH_ITEM* connected_item : memberlist )
1166 SCH_CONNECTION* connected_conn = connected_item->Connection( &sheet );
1168 wxASSERT( connected_conn );
1174 subgraph->
AddItem( connected_item );
1175 SCH_ITEM_SET& citemset = connected_item->ConnectedItems( sheet );
1182 if( get_items( citem ) )
1183 memberlist.push_back( citem );
1188 for(
SCH_ITEM* connected_item : memberlist )
1189 connected_item->ClearFlags(
CANDIDATE );
1202 std::vector<CONNECTION_SUBGRAPH*> dirty_graphs;
1207 return candidate->m_dirty;
1210 std::vector<std::future<size_t>> returns( dirty_graphs.size() );
1214 if( !subgraph->m_dirty )
1218 for(
SCH_ITEM* item : subgraph->m_items )
1220 switch( item->
Type() )
1223 subgraph->m_no_connect = item;
1227 subgraph->m_bus_entry = item;
1234 if(
pin->GetType() == ELECTRICAL_PINTYPE::PT_NC )
1235 subgraph->m_no_connect = item;
1245 subgraph->ResolveDrivers(
true );
1246 subgraph->m_dirty =
false;
1253 tp.push_loop( dirty_graphs.size(),
1254 [&](
const int a,
const int b)
1256 for( int ii = a; ii < b; ++ii )
1257 update_lambda( dirty_graphs[ii] );
1259 tp.wait_for_tasks();
1266 return candidate->m_driver;
1279 wxString full_name = subgraph->m_driver_connection->Name();
1280 wxString
name = subgraph->m_driver_connection->Name(
true );
1287 if( subgraph->m_driver_connection->Type() == CONNECTION_TYPE::BUS )
1289 wxString prefixOnly = full_name.BeforeFirst(
'[' ) + wxT(
"[]" );
1293 subgraph->m_dirty =
true;
1295 if( subgraph->m_strong_driver )
1297 SCH_ITEM* driver = subgraph->m_driver;
1300 switch( driver->
Type() )
1316 wxASSERT(
pin->IsGlobalPower() );
1324 wxLogTrace(
ConnTrace, wxS(
"Unexpected strong driver %s" ),
1336 std::vector<CONNECTION_SUBGRAPH*> new_subgraphs;
1347 dummy.SetGraph(
this );
1352 for(
const auto& conn :
dummy.Members() )
1354 wxString
name = conn->FullLocalName();
1361 new_conn->
SetType( CONNECTION_TYPE::NET );
1364 wxLogTrace(
ConnTrace, wxS(
"SG(%ld), Adding full local name (%s) with sg (%d) on subsheet %s" ), subgraph->m_code,
1365 name, code, subgraph->m_sheet.PathHumanReadable() );
1378 new_subgraphs.push_back( new_sg );
1383 std::copy( new_subgraphs.begin(), new_subgraphs.end(), std::back_inserter(
m_driver_subgraphs ) );
1393 std::unordered_map<int, CONNECTION_SUBGRAPH*> global_power_pin_subgraphs;
1400 if( !
pin->ConnectedItems( sheet ).empty() && !
pin->GetLibPin()->GetParent()->IsPower() )
1415 if(
pin->GetLibPin()->GetParent()->IsPower() )
1416 connection->
SetName(
pin->GetParentSymbol()->GetValueFieldText(
true, &sheet,
false ) );
1425 auto jj = global_power_pin_subgraphs.find( code );
1427 if( jj != global_power_pin_subgraphs.end() )
1429 subgraph = jj->second;
1447 global_power_pin_subgraphs[code] = subgraph;
1464 std::unordered_set<CONNECTION_SUBGRAPH*> invalidated_subgraphs;
1468 if( subgraph->m_absorbed )
1473 wxString
name = connection->
Name();
1476 unsigned suffix = 1;
1478 auto create_new_name =
1482 wxString suffixStr = std::to_wstring( suffix );
1487 if( aConn->Type() == CONNECTION_TYPE::BUS_GROUP )
1489 wxString prefix = aConn->BusPrefix();
1491 if( prefix.empty() )
1492 prefix = wxT(
"BUS" );
1494 wxString oldName = aConn->Name().AfterFirst(
'{' );
1496 newName << prefix << wxT(
"_" ) << suffixStr << wxT(
"{" ) << oldName;
1498 aConn->ConfigureFromLabel( newName );
1502 newName << aConn->Name() << wxT(
"_" ) << suffixStr;
1503 aConn->SetSuffix( wxString( wxT(
"_" ) ) << suffixStr );
1510 if( !subgraph->m_strong_driver )
1516 if( vec->size() <= 1 && subgraph->m_driver_connection->Type() == CONNECTION_TYPE::BUS )
1518 wxString prefixOnly =
name.BeforeFirst(
'[' ) + wxT(
"[]" );
1522 if( vec->size() > 1 )
1524 wxString new_name = create_new_name( connection );
1527 new_name = create_new_name( connection );
1529 wxLogTrace(
ConnTrace, wxS(
"%ld (%s) is weakly driven and not unique. Changing to %s." ),
1530 subgraph->m_code,
name, new_name );
1538 else if( subgraph->m_driver )
1550 bool conflict =
false;
1551 wxString global_name = connection->
Name(
true );
1558 std::vector<CONNECTION_SUBGRAPH*>& candidates = kk->second;
1562 if( candidate->m_sheet == sheet )
1570 wxS(
"%ld (%s) skipped for promotion due to potential conflict" ),
1571 subgraph->m_code,
name );
1578 wxS(
"%ld (%s) weakly driven by unique sheet pin %s, promoting" ),
1579 subgraph->m_code,
name,
1580 subgraph->m_driver->GetItemDescription( &unitsProvider ) );
1582 subgraph->m_strong_driver =
true;
1590 if( connection->
IsBus() )
1614 subgraph->m_dirty =
true;
1623 if( !subgraph->m_strong_driver )
1631 std::vector<CONNECTION_SUBGRAPH*> candidate_subgraphs;
1634 std::back_inserter( candidate_subgraphs ),
1637 return ( !candidate->m_absorbed &&
1638 candidate->m_strong_driver &&
1639 candidate != subgraph );
1645 std::vector< std::shared_ptr<SCH_CONNECTION> > connections_to_check;
1648 connections_to_check.push_back( std::make_shared<SCH_CONNECTION>( *connection ) );
1650 auto add_connections_to_check =
1653 for(
SCH_ITEM* possible_driver : aSubgraph->m_items )
1655 if( possible_driver == aSubgraph->m_driver )
1662 if( c->Type() != aSubgraph->m_driver_connection->Type() )
1665 if( c->Name(
true ) == aSubgraph->m_driver_connection->Name(
true ) )
1668 connections_to_check.push_back( c );
1670 wxS(
"%lu (%s): Adding secondary driver %s" ), aSubgraph->m_code,
1671 aSubgraph->m_driver_connection->Name(
true ),
1680 add_connections_to_check( subgraph );
1682 std::set<SCH_CONNECTION*> checked_connections;
1684 for(
unsigned i = 0; i < connections_to_check.size(); i++ )
1686 auto member = connections_to_check[i];
1689 if( !checked_connections.insert( member.get() ).second )
1692 if( member->IsBus() )
1694 connections_to_check.insert( connections_to_check.end(),
1695 member->Members().begin(),
1696 member->Members().end() );
1699 wxString test_name = member->Name(
true );
1703 if( candidate->
m_absorbed || candidate == subgraph )
1719 if( driver == candidate->
m_driver )
1730 if(
pin->IsGlobalPower()
1731 &&
pin->GetDefaultNetName( sheet ) == test_name )
1743 if( subgraph->GetNameForDriver( driver ) == test_name )
1756 wxLogTrace(
ConnTrace, wxS(
"%lu (%s) has bus child %lu (%s)" ), subgraph->m_code,
1757 connection->
Name(), candidate->
m_code, member->Name() );
1759 subgraph->m_bus_neighbors[member].insert( candidate );
1764 wxLogTrace(
ConnTrace, wxS(
"%lu (%s) absorbs neighbor %lu (%s)" ),
1765 subgraph->m_code, connection->
Name(),
1769 add_connections_to_check( candidate );
1771 subgraph->Absorb( candidate );
1772 invalidated_subgraphs.insert( subgraph );
1782 if( subgraph->m_absorbed )
1785 if( !subgraph->ResolveDrivers() )
1788 if( subgraph->m_driver_connection->IsBus() )
1793 wxLogTrace(
ConnTrace, wxS(
"Re-resolving drivers for %lu (%s)" ), subgraph->m_code,
1794 subgraph->m_driver_connection->Name() );
1815 wxCHECK_RET(
m_schematic, wxT(
"Connection graph cannot be built without schematic pointer" ) );
1819 for(
unsigned i = 0; i < all_sheets.size(); i++ )
1821 for(
const std::shared_ptr<BUS_ALIAS>& alias : all_sheets[i].LastScreen()->GetBusAliases() )
1825 PROF_TIMER sub_graph(
"buildItemSubGraphs" );
1845 PROF_TIMER proc_sub_graph(
"ProcessSubGraphs" );
1849 proc_sub_graph.
Show();
1858 std::vector<CONNECTION_SUBGRAPH*> global_subgraphs;
1860 std::back_inserter( global_subgraphs ),
1863 return !candidate->m_local_driver;
1875 [&](
const int a,
const int b)
1877 for( int ii = a; ii < b; ++ii )
1878 m_driver_subgraphs[ii]->UpdateItemConnections();
1880 tp.wait_for_tasks();
1888 if( !subgraph->m_dirty )
1891 wxLogTrace(
ConnTrace, wxS(
"Processing %lu (%s) for propagation" ), subgraph->m_code,
1892 subgraph->m_driver_connection->Name() );
1898 if( !subgraph->m_local_driver && subgraph->m_multiple_drivers )
1900 for(
SCH_ITEM* driver : subgraph->m_drivers )
1902 if( driver == subgraph->m_driver )
1905 const wxString& secondary_name = subgraph->GetNameForDriver( driver );
1907 if( secondary_name == subgraph->m_driver_connection->Name() )
1915 if( candidate == subgraph )
1918 if( !secondary_is_global && candidate->
m_sheet != subgraph->m_sheet )
1923 if( conn->
Name() == secondary_name )
1925 wxLogTrace(
ConnTrace, wxS(
"Global %lu (%s) promoted to %s" ), candidate->
m_code,
1926 conn->
Name(), subgraph->m_driver_connection->Name() );
1928 conn->
Clone( *subgraph->m_driver_connection );
1947 if( subgraph->m_dirty )
1964 wxASSERT_MSG( !subgraph->m_dirty, wxS(
"Subgraph not processed by propagateToNeighbors!" ) );
1966 if( subgraph->m_bus_parents.size() < 2 )
1971 wxLogTrace(
ConnTrace, wxS(
"%lu (%s) has multiple bus parents" ),
1972 subgraph->m_code, conn->
Name() );
1974 wxASSERT( conn->
IsNet() );
1976 for(
const auto& ii : subgraph->m_bus_parents )
1989 wxLogTrace(
ConnTrace, wxS(
"Warning: could not match %s inside %lu (%s)" ),
1994 if( conn->
Name() != match->
Name() )
1996 wxString old_name = match->
Name();
1998 wxLogTrace(
ConnTrace, wxS(
"Updating %lu (%s) member %s to %s" ), parent->
m_code,
2001 match->
Clone( *conn );
2021 auto updateItemConnectionsTask =
2025 if( !subgraph->m_strong_driver && subgraph->m_drivers.size() == 1 &&
2026 subgraph->m_driver->Type() ==
SCH_PIN_T )
2029 wxString
name =
pin->GetDefaultNetName( subgraph->m_sheet,
true );
2031 subgraph->m_driver_connection->ConfigureFromLabel(
name );
2034 subgraph->m_dirty =
false;
2035 subgraph->UpdateItemConnections();
2038 if( subgraph->m_driver_connection->IsBus() )
2044 if( subgraph->m_driver && subgraph->m_driver->Type() ==
SCH_SHEET_PIN_T )
2050 wxString pinText =
pin->GetText();
2057 if( label->
GetText() == pinText )
2060 path.push_back( sheet );
2064 if( parent_conn && parent_conn->
IsBus() )
2065 subgraph->m_driver_connection->
SetType( CONNECTION_TYPE::BUS );
2071 if( subgraph->m_driver_connection->IsBus() )
2080 [&](
const int a,
const int b)
2082 for(
int ii = a; ii < b; ++ii )
2085 tp.wait_for_tasks();
2093 subgraph->m_driver_connection->NetCode() };
2100 std::map<wxString, wxString> oldAssignments = netSettings->m_NetClassLabelAssignments;
2102 netSettings->m_NetClassLabelAssignments.clear();
2104 auto dirtySubgraphs =
2105 [&](
const std::vector<CONNECTION_SUBGRAPH*>& subgraphs )
2107 if( aChangedItemHandler )
2111 for(
SCH_ITEM* item : subgraph->m_items )
2112 (*aChangedItemHandler)( item );
2117 auto checkNetclassDrivers =
2118 [&](
const std::vector<CONNECTION_SUBGRAPH*>& subgraphs )
2123 wxCHECK_RET( !subgraphs.empty(), wxT(
"Invalid empty subgraph" ) );
2127 for(
SCH_ITEM* item : subgraph->m_items )
2129 netclass = subgraph->GetNetclassForDriver( item );
2131 if( !netclass.IsEmpty() )
2135 if( !netclass.IsEmpty() )
2137 driverSubgraph = subgraph;
2142 if( netclass.IsEmpty() )
2145 if( !driverSubgraph )
2146 driverSubgraph = subgraphs.front();
2148 const wxString netname = driverSubgraph->
GetNetName();
2154 netSettings->m_NetClassLabelAssignments[ member->Name() ] = netclass;
2159 dirtySubgraphs( ii->second );
2163 netSettings->m_NetClassLabelAssignments[ netname ] = netclass;
2165 if( oldAssignments[ netname ] != netclass )
2166 dirtySubgraphs( subgraphs );
2170 checkNetclassDrivers( subgraphs );
2206 std::vector<std::shared_ptr<SCH_CONNECTION>> connections_to_check( aConnection->
Members() );
2208 for(
unsigned i = 0; i < connections_to_check.size(); i++ )
2210 const std::shared_ptr<SCH_CONNECTION>& member = connections_to_check[i];
2212 if( member->IsBus() )
2214 connections_to_check.insert( connections_to_check.end(),
2215 member->Members().begin(),
2216 member->Members().end() );
2228 std::vector<CONNECTION_SUBGRAPH*> search_list;
2229 std::unordered_set<CONNECTION_SUBGRAPH*> visited;
2230 std::unordered_set<SCH_CONNECTION*> stale_bus_members;
2237 path.push_back(
pin->GetParent() );
2248 || visited.count( candidate ) )
2257 wxLogTrace(
ConnTrace, wxS(
"%lu: found child %lu (%s)" ), aParent->m_code,
2263 wxASSERT( candidate->
m_graph == aParent->m_graph );
2265 search_list.push_back( candidate );
2285 || visited.count( candidate )
2291 const KIID& last_parent_uuid = aParent->m_sheet.Last()->m_Uuid;
2296 if(
pin->GetParent()->m_Uuid != last_parent_uuid )
2302 if( pin_path != aParent->m_sheet )
2307 wxLogTrace(
ConnTrace, wxS(
"%lu: found additional parent %lu (%s)" ),
2308 aParent->m_code, candidate->
m_code,
2311 aParent->m_hier_children.insert( candidate );
2312 search_list.push_back( candidate );
2322 for(
const auto&
kv : aParentGraph->m_bus_neighbors )
2364 wxLogTrace(
ConnTrace, wxS(
"Could not match bus member %s in %s" ),
2365 kv.first->Name(), parent->
Name() );
2370 auto neighbor_name = neighbor_conn->
Name();
2373 if( neighbor_name == member->
Name() )
2377 if( neighbor_conn->Sheet() != neighbor->
m_sheet )
2381 wxASSERT( neighbor_conn->IsNet() );
2383 wxLogTrace(
ConnTrace, wxS(
"%lu (%s) connected to bus member %s (local %s)" ),
2390 member->
Clone( *neighbor_conn );
2391 stale_bus_members.insert( member );
2395 neighbor_conn->Clone( *member );
2409 propagate_bus_neighbors( aSubgraph );
2416 wxLogTrace(
ConnTrace, wxS(
"%lu (%s) has both hier ports and pins; deferring processing" ),
2422 wxLogTrace(
ConnTrace, wxS(
"%lu (%s) has no hier pins or ports on sheet %s; marking clean" ),
2428 visited.insert( aSubgraph );
2430 wxLogTrace(
ConnTrace, wxS(
"Propagating %lu (%s) to subsheets" ),
2435 for(
unsigned i = 0; i < search_list.size(); i++ )
2437 auto child = search_list[i];
2439 if( visited.insert( child ).second )
2442 child->m_dirty =
false;
2457 if( subgraph == aSubgraph )
2464 wxString candidateName = subgraph->m_driver_connection->Name();
2465 bool shorterPath = subgraph->m_sheet.size() < bestDriver->
m_sheet.
size();
2466 bool asGoodPath = subgraph->m_sheet.size() <= bestDriver->
m_sheet.
size();
2476 ( !bestIsStrong && candidateStrong ) ||
2477 ( priority > highest && candidateStrong ) ||
2478 ( priority == highest && candidateStrong && shorterPath ) ||
2479 ( ( bestIsStrong == candidateStrong ) && asGoodPath && ( priority == highest ) &&
2480 ( candidateName < bestName ) ) )
2482 bestDriver = subgraph;
2484 bestIsStrong = candidateStrong;
2485 bestName = candidateName;
2490 if( bestDriver != aSubgraph )
2492 wxLogTrace(
ConnTrace, wxS(
"%lu (%s) overridden by new driver %lu (%s)" ),
2501 wxString old_name = subgraph->m_driver_connection->
Name();
2503 subgraph->m_driver_connection->Clone( *conn );
2505 if( old_name != conn->
Name() )
2509 propagate_bus_neighbors( subgraph );
2515 if( conn->
IsBus() && !stale_bus_members.empty() )
2517 std::unordered_set<SCH_CONNECTION*> cached_members = stale_bus_members;
2528 wxLogTrace(
ConnTrace, wxS(
"WARNING: failed to match stale member %s in %s." ),
2529 stale_member->Name(), subgraph->m_driver_connection->Name() );
2533 wxLogTrace(
ConnTrace, wxS(
"Updating %lu (%s) member %s to %s" ), subgraph->m_code,
2534 subgraph->m_driver_connection->Name(), member->
LocalName(),
2535 stale_member->Name() );
2537 member->
Clone( *stale_member );
2539 propagate_bus_neighbors( subgraph );
2551 std::shared_ptr<SCH_CONNECTION> c = std::shared_ptr<SCH_CONNECTION>(
nullptr );
2553 switch( aItem->
Type() )
2559 if(
pin->IsGlobalPower() )
2560 c = std::make_shared<SCH_CONNECTION>( aItem, aSubgraph->
m_sheet );
2569 c = std::make_shared<SCH_CONNECTION>( aItem, aSubgraph->
m_sheet );
2579 c->SetGraph(
this );
2590 wxASSERT( aBusConnection->
IsBus() );
2594 if( aBusConnection->
Type() == CONNECTION_TYPE::BUS )
2599 for(
const std::shared_ptr<SCH_CONNECTION>& bus_member : aBusConnection->
Members() )
2601 if( bus_member->VectorIndex() == aSearch->
VectorIndex() )
2603 match = bus_member.get();
2611 for(
const std::shared_ptr<SCH_CONNECTION>& c : aBusConnection->
Members() )
2616 if( c->Type() == CONNECTION_TYPE::BUS )
2618 for(
const std::shared_ptr<SCH_CONNECTION>& bus_member : c->Members() )
2620 if( bus_member->LocalName() == aSearch->
LocalName() )
2622 match = bus_member.get();
2627 else if( c->LocalName() == aSearch->
LocalName() )
2640 const wxString& aOldName )
2646 std::vector<CONNECTION_SUBGRAPH*>& vec = it->second;
2650 wxLogTrace(
ConnTrace, wxS(
"recacheSubgraphName: %s => %s" ), aOldName,
2667 std::vector<const CONNECTION_SUBGRAPH*> ret;
2672 wxASSERT( !subgraph->m_dirty );
2674 if( !subgraph->m_driver )
2679 if( !connection->
IsBus() )
2682 auto labels = subgraph->GetVectorBusLabels();
2684 if( labels.size() > 1 )
2686 bool different =
false;
2687 wxString first =
static_cast<SCH_TEXT*
>( labels.at( 0 ) )->GetShownText(
false );
2689 for(
unsigned i = 1; i < labels.size(); ++i )
2701 wxLogTrace(
ConnTrace, wxS(
"SG %ld (%s) has multiple bus labels" ), subgraph->m_code,
2702 connection->
Name() );
2704 ret.push_back( subgraph );
2724 if( graph == aSubGraph )
2765 wxASSERT( !it->second.empty() );
2767 return it->second[0];
2784 const wxString& aNetName )
const
2786 std::vector<CONNECTION_SUBGRAPH*> subgraphs;
2799 int error_count = 0;
2801 wxCHECK_MSG(
m_schematic,
true, wxS(
"Null m_schematic in CONNECTION_GRAPH::RunERC" ) );
2807 std::set<SCH_ITEM*> seenDriverInstances;
2812 wxCHECK2( subgraph,
continue );
2815 wxASSERT( !subgraph->m_dirty );
2817 if( subgraph->m_absorbed )
2820 if( seenDriverInstances.count( subgraph->m_driver ) )
2823 if( subgraph->m_driver )
2824 seenDriverInstances.insert( subgraph->m_driver );
2842 subgraph->ResolveDrivers(
false );
2906 wxCHECK( aSubgraph,
false );
2912 if( driver == aSubgraph->
m_driver )
2924 if( primaryName == secondaryName )
2927 wxString msg = wxString::Format(
_(
"Both %s and %s are attached to the same "
2928 "items; %s will be used in the netlist" ),
2929 primaryName, secondaryName, primaryName );
2932 ercItem->SetItems( aSubgraph->
m_driver, driver );
2933 ercItem->SetErrorMessage( msg );
2949 wxString firstNetclass;
2950 SCH_ITEM* firstNetclassDriver =
nullptr;
2954 for(
SCH_ITEM* item : subgraph->m_items )
2956 const wxString netclass = subgraph->GetNetclassForDriver( item );
2958 if( netclass.IsEmpty() )
2961 if( netclass != firstNetclass )
2963 if( !firstNetclassDriver )
2965 firstNetclass = netclass;
2966 firstNetclassDriver = item;
2971 ercItem->SetItems( firstNetclassDriver, item );
2974 subgraph->m_sheet.LastScreen()->Append( marker );
2996 switch( item->
Type() )
3001 bus_item = ( !bus_item ) ? item : bus_item;
3003 net_item = ( !net_item ) ? item : net_item;
3016 bus_item = ( !bus_item ) ? item : bus_item;
3018 net_item = ( !net_item ) ? item : net_item;
3027 if( net_item && bus_item )
3030 ercItem->SetItems( net_item, bus_item );
3033 screen->
Append( marker );
3052 switch( item->
Type() )
3083 if(
test != member && member->Name() ==
test->Name() )
3097 ercItem->SetItems( label, port );
3100 screen->
Append( marker );
3112 bool conflict =
false;
3128 switch( item->
Type() )
3158 std::set<wxString> test_names;
3168 if( member->Type() == CONNECTION_TYPE::BUS )
3170 for(
const auto& sub_member : member->Members() )
3172 if( test_names.count( sub_member->Name() ) )
3176 else if( test_names.count( member->Name() ) )
3195 wxString msg = wxString::Format(
_(
"Net %s is graphically connected to bus %s but is not a"
3196 " member of that bus" ),
3200 ercItem->SetItems( bus_entry, bus_wire );
3201 ercItem->SetErrorMessage( msg );
3204 screen->
Append( marker );
3222 std::set<SCH_PIN*> unique_pins;
3223 std::set<SCH_LABEL_BASE*> unique_labels;
3232 for(
SCH_ITEM* item : aProcessGraph->m_items )
3234 switch( item->
Type() )
3241 if( aProcessGraph == aSubgraph )
3244 if( std::none_of( unique_pins.begin(), unique_pins.end(),
3251 unique_pins.insert( test_pin );
3274 process_subgraph( subgraph );
3279 process_subgraph( aSubgraph );
3292 pos =
pin->GetTransformedPosition();
3301 screen->
Append( marker );
3312 screen->
Append( marker );
3319 bool has_other_connections =
false;
3320 std::vector<SCH_PIN*> pins;
3327 switch( item->
Type() )
3332 if( !has_other_connections && !pins.empty() )
3336 for(
SCH_PIN* other_pin : pins )
3340 has_other_connections =
true;
3346 pins.emplace_back(
static_cast<SCH_PIN*
>( item ) );
3353 has_other_connections =
true;
3360 pin = pins.empty() ? nullptr : pins[0];
3363 for(
SCH_PIN* test_pin : pins )
3365 if( test_pin->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN )
3376 if(
pin && !has_other_connections
3377 &&
pin->IsGlobalPower()
3378 && !
pin->GetLibPin()->GetParent()->IsPower() )
3380 wxString
name =
pin->Connection( &sheet )->Name();
3381 wxString local_name =
pin->Connection( &sheet )->Name(
true );
3386 has_other_connections =
true;
3391 if(
pin && !has_other_connections
3392 &&
pin->GetType() != ELECTRICAL_PINTYPE::PT_NC
3393 &&
pin->GetType() != ELECTRICAL_PINTYPE::PT_NIC
3397 ercItem->SetItems(
pin );
3400 screen->
Append( marker );
3408 if( pins.size() > 1 )
3410 for(
SCH_PIN* testPin : pins )
3415 if( testPin->GetLibPin()->GetParent()->IsPower()
3416 && testPin->ConnectedItems( sheet ).empty()
3420 ercItem->SetItems( testPin );
3423 testPin->GetTransformedPosition() );
3424 screen->
Append( marker );
3441 std::vector<SCH_ITEM*> wires;
3449 wires.emplace_back( item );
3451 wires.emplace_back( item );
3454 if( !wires.empty() )
3459 ercItem->SetItems( wires[0],
3460 wires.size() > 1 ? wires[1] :
nullptr,
3461 wires.size() > 2 ? wires[2] :
nullptr,
3462 wires.size() > 3 ? wires[3] :
nullptr );
3465 screen->
Append( marker );
3496 std::map<KICAD_T, std::vector<SCH_TEXT*>> label_map;
3503 std::count_if( aLocSubgraph->m_items.begin(), aLocSubgraph->m_items.end(), [](
const SCH_ITEM* item )
3504 { return item->Type() == SCH_PIN_T; } );
3507 auto reportError = [&](
SCH_TEXT* aText,
int errCode )
3512 ercItem->SetItems( aText );
3519 pinCount =
hasPins( aSubgraph );
3523 switch( item->
Type() )
3531 label_map[item->
Type()].push_back(
text );
3536 if(
text->IsDangling() )
3550 if( label_map.empty() )
3555 wxCHECK_MSG(
m_schematic,
true, wxS(
"Null m_schematic in CONNECTION_GRAPH::ercCheckLabels" ) );
3562 for(
auto& [type, label_vec] : label_map )
3581 int allPins = pinCount;
3589 if( neighbor == aSubgraph )
3595 allPins +=
hasPins( neighbor );
3599 if( allPins == 1 && !has_nc )
3627 for(
SCH_ITEM* item : sheet.LastScreen()->Items() )
3634 std::map<wxString, SCH_SHEET_PIN*> pins;
3635 std::map<wxString, SCH_HIERLABEL*> labels;
3640 pins[
pin->GetText()] =
pin;
3645 ercItem->SetItems(
pin );
3648 sheet.LastScreen()->Append( marker );
3656 std::set<wxString> matchedPins;
3664 if( !pins.count( label->
GetText() ) )
3665 labels[label->
GetText()] = label;
3667 matchedPins.insert( label->
GetText() );
3671 for(
const wxString& matched : matchedPins )
3672 pins.erase( matched );
3674 for(
const std::pair<const wxString, SCH_SHEET_PIN*>& unmatched : pins )
3676 wxString msg = wxString::Format(
_(
"Sheet pin %s has no matching hierarchical "
3677 "label inside the sheet" ),
3681 ercItem->SetItems( unmatched.second );
3682 ercItem->SetErrorMessage( msg );
3683 ercItem->SetSheetSpecificPath( sheet );
3684 ercItem->SetItemsSheetPaths( sheet );
3687 sheet.LastScreen()->Append( marker );
3692 for(
const std::pair<const wxString, SCH_HIERLABEL*>& unmatched : labels )
3694 wxString msg = wxString::Format(
_(
"Hierarchical label %s has no matching "
3695 "sheet pin in the parent sheet" ),
3699 parentSheetPath.
push_back( parentSheet );
3702 ercItem->SetItems( unmatched.second );
3703 ercItem->SetErrorMessage( msg );
3704 ercItem->SetSheetSpecificPath( parentSheetPath );
3705 ercItem->SetItemsSheetPaths( parentSheetPath );
constexpr EDA_IU_SCALE schIUScale
Calculates the connectivity of a schematic and generates netlists.
int RunERC()
Runs electrical rule checks on the connectivity graph.
bool ercCheckBusToBusConflicts(const CONNECTION_SUBGRAPH *aSubgraph)
Checks one subgraph for conflicting connections between two bus items.
void processSubGraphs()
Process all subgraphs to assign netcodes and merge subgraphs based on labels.
bool ercCheckNetclassConflicts(const std::vector< CONNECTION_SUBGRAPH * > &subgraphs)
bool ercCheckLabels(const CONNECTION_SUBGRAPH *aSubgraph)
Checks one subgraph for proper connection of labels.
void collectAllDriverValues()
Maps the driver values for each subgraph.
CONNECTION_SUBGRAPH * FindSubgraphByName(const wxString &aNetName, const SCH_SHEET_PATH &aPath)
Returns the subgraph for a given net name on a given sheet.
void recacheSubgraphName(CONNECTION_SUBGRAPH *aSubgraph, const wxString &aOldName)
static SCH_CONNECTION * matchBusMember(SCH_CONNECTION *aBusConnection, SCH_CONNECTION *aSearch)
Search for a matching bus member inside a bus connection.
std::unordered_map< wxString, std::shared_ptr< BUS_ALIAS > > m_bus_alias_cache
SCHEMATIC * m_schematic
The schematic this graph represents.
std::unordered_map< SCH_SHEET_PATH, std::vector< CONNECTION_SUBGRAPH * > > m_sheet_to_subgraphs_map
CONNECTION_SUBGRAPH * FindFirstSubgraphByName(const wxString &aNetName)
Retrieves a subgraph for the given net name, if one exists.
void propagateToNeighbors(CONNECTION_SUBGRAPH *aSubgraph, bool aForce)
Updates all neighbors of a subgraph with this one's connectivity info.
void buildItemSubGraphs()
Generates individual item subgraphs on a per-sheet basis.
bool ercCheckMultipleDrivers(const CONNECTION_SUBGRAPH *aSubgraph)
If the subgraph has multiple drivers of equal priority that are graphically connected,...
CONNECTION_SUBGRAPH * GetSubgraphForItem(SCH_ITEM *aItem)
SCH_SHEET_LIST m_sheetList
void generateGlobalPowerPinSubGraphs()
Iterate through the global power pins to collect the global labels as drivers.
const std::vector< CONNECTION_SUBGRAPH * > GetAllSubgraphs(const wxString &aNetName) const
std::unordered_map< wxString, int > m_net_name_to_code_map
void buildConnectionGraph(std::function< void(SCH_ITEM *)> *aChangedItemHandler)
Generates the connection graph (after all item connectivity has been updated)
int ercCheckHierSheets()
Checks that a hierarchical sheet has at least one matching label inside the sheet for each port on th...
bool ercCheckBusToNetConflicts(const CONNECTION_SUBGRAPH *aSubgraph)
Checks one subgraph for conflicting connections between net and bus labels.
std::shared_ptr< SCH_CONNECTION > getDefaultConnection(SCH_ITEM *aItem, CONNECTION_SUBGRAPH *aSubgraph)
Builds a new default connection for the given item based on its properties.
std::vector< const CONNECTION_SUBGRAPH * > GetBusesNeedingMigration()
Determines which subgraphs have more than one conflicting bus label.
int assignNewNetCode(SCH_CONNECTION &aConnection)
Helper to assign a new net code to a connection.
std::map< std::pair< SCH_SHEET_PATH, wxString >, std::vector< const CONNECTION_SUBGRAPH * > > m_local_label_cache
int getOrCreateNetCode(const wxString &aNetName)
void assignNetCodesToBus(SCH_CONNECTION *aConnection)
Ensures all members of the bus connection have a valid net code assigned.
std::unordered_map< wxString, int > m_bus_name_to_code_map
std::unordered_map< wxString, std::vector< const CONNECTION_SUBGRAPH * > > m_global_label_cache
std::vector< CONNECTION_SUBGRAPH * > m_subgraphs
std::vector< std::pair< SCH_SHEET_PATH, SCH_PIN * > > m_global_power_pins
bool ercCheckNoConnects(const CONNECTION_SUBGRAPH *aSubgraph)
Checks one subgraph for proper presence or absence of no-connect symbols.
size_t hasPins(const CONNECTION_SUBGRAPH *aLocSubgraph)
Get the number of pins in a given subgraph.
std::vector< SCH_ITEM * > m_items
std::unordered_map< wxString, std::vector< CONNECTION_SUBGRAPH * > > m_net_name_to_subgraphs_map
std::shared_ptr< BUS_ALIAS > GetBusAlias(const wxString &aName)
Returns a bus alias pointer for the given name if it exists (from cache)
void removeSubgraphs(std::set< CONNECTION_SUBGRAPH * > &aSubgraphs)
Removes references to the given subgraphs from all structures in the connection graph.
std::unordered_map< SCH_ITEM *, CONNECTION_SUBGRAPH * > m_item_to_subgraph_map
std::set< std::pair< SCH_SHEET_PATH, SCH_ITEM * > > ExtractAffectedItems(const std::set< SCH_ITEM * > &aItems)
For a set of items, this will remove the connected items and their associated data including subgraph...
wxString GetResolvedSubgraphName(const CONNECTION_SUBGRAPH *aSubGraph) const
Returns the fully-resolved netname for a given subgraph.
bool ercCheckBusToBusEntryConflicts(const CONNECTION_SUBGRAPH *aSubgraph)
Checks one subgraph for conflicting bus entry to bus connections.
std::vector< CONNECTION_SUBGRAPH * > m_driver_subgraphs
NET_MAP m_net_code_to_subgraphs_map
bool ercCheckFloatingWires(const CONNECTION_SUBGRAPH *aSubgraph)
Checks one subgraph for floating wires.
void Merge(CONNECTION_GRAPH &aGraph)
Combines the input graph contents into the current graph.
void resolveAllDrivers()
Finds all subgraphs in the connection graph and calls ResolveDrivers() in parallel.
void updateItemConnectivity(const SCH_SHEET_PATH &aSheet, const std::vector< SCH_ITEM * > &aItemList)
Updates the graphical connectivity between items (i.e.
void Recalculate(const SCH_SHEET_LIST &aSheetList, bool aUnconditional=false, std::function< void(SCH_ITEM *)> *aChangedItemHandler=nullptr)
Updates the connection graph for the given list of sheets.
void generateBusAliasMembers()
Iterate through labels to create placeholders for bus elements.
A subgraph is a set of items that are electrically connected on a single sheet.
wxString driverName(SCH_ITEM *aItem) const
PRIORITY GetDriverPriority()
bool m_strong_driver
True if the driver is "strong": a label or power object.
SCH_ITEM * m_no_connect
No-connect item in graph, if any.
std::set< CONNECTION_SUBGRAPH * > m_absorbed_subgraphs
Set of subgraphs that have been absorbed by this subgraph.
static PRIORITY GetDriverPriority(SCH_ITEM *aDriver)
Return the priority (higher is more important) of a candidate driver.
SCH_SHEET_PATH m_sheet
On which logical sheet is the subgraph contained.
void UpdateItemConnections()
Updates all items to match the driver connection.
const wxString GetNetclassForDriver(SCH_ITEM *aItem) const
std::set< SCH_SHEET_PIN * > m_hier_pins
std::unordered_map< std::shared_ptr< SCH_CONNECTION >, std::unordered_set< CONNECTION_SUBGRAPH * > > m_bus_neighbors
If a subgraph is a bus, this map contains links between the bus members and any local sheet neighbors...
CONNECTION_GRAPH * m_graph
std::vector< SCH_ITEM * > GetAllBusLabels() const
Returns all the all bus labels attached to this subgraph (if any)
std::unordered_map< SCH_ITEM *, wxString > m_driver_name_cache
A cache of escaped netnames from schematic items.
const wxString & GetNameForDriver(SCH_ITEM *aItem) const
Returns the candidate net name for a driver.
wxString GetNetName() const
Returns the fully-qualified net name for this subgraph (if one exists)
std::vector< SCH_ITEM * > GetVectorBusLabels() const
Returns all the vector-based bus labels attached to this subgraph (if any)
bool m_multiple_drivers
True if this subgraph contains more than one driver that should be shorted together in the netlist.
bool ResolveDrivers(bool aCheckMultipleDrivers=false)
Determines which potential driver should drive the subgraph.
std::set< SCH_ITEM * > m_drivers
bool m_absorbed
True if this subgraph has been absorbed into another. No pointers here are safe if so!
SCH_CONNECTION * m_driver_connection
Cache for driver connection.
CONNECTION_SUBGRAPH * m_absorbed_by
If this subgraph is absorbed, points to the absorbing (and valid) subgraph.
std::unordered_set< CONNECTION_SUBGRAPH * > m_hier_children
void AddItem(SCH_ITEM *aItem)
Adds a new item to the subgraph.
void Absorb(CONNECTION_SUBGRAPH *aOther)
Combines another subgraph on the same sheet into this one.
std::set< SCH_ITEM * > m_items
Contents of the subgraph.
std::unordered_map< std::shared_ptr< SCH_CONNECTION >, std::unordered_set< CONNECTION_SUBGRAPH * > > m_bus_parents
If this is a net, this vector contains links to any same-sheet buses that contain it.
SCH_ITEM * m_driver
Fully-resolved driver for the subgraph (might not exist in this subgraph)
bool m_is_bus_member
True if the subgraph is not actually part of a net.
CONNECTION_SUBGRAPH * m_hier_parent
void RemoveItem(SCH_ITEM *aItem)
bool m_local_driver
True if the driver is a local (i.e. non-global) type.
std::set< SCH_HIERLABEL * > m_hier_ports
void getAllConnectedItems(std::set< std::pair< SCH_SHEET_PATH, SCH_ITEM * > > &aItems, std::set< CONNECTION_SUBGRAPH * > &aSubgraphs)
Finds all items in the subgraph as well as child subgraphs recursively.
virtual VECTOR2I GetPosition() const
KICAD_T Type() const
Returns the type of object.
virtual wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider) const
Return a user-visible description string of this item.
virtual const wxString & GetText() const
Return the string associated with the text object.
EE_TYPE OfType(KICAD_T aType) const
static std::shared_ptr< ERC_ITEM > Create(int aErrorCode)
Constructs an ERC_ITEM for the given error code.
Container for ERC settings.
bool IsTestEnabled(int aErrorCode) const
LIB_SYMBOL * GetParent() const
A small class to help profiling.
void Show(std::ostream &aStream=std::cerr)
Print the elapsed time (in a suitable unit) to a stream.
std::shared_ptr< NET_SETTINGS > m_NetSettings
Net settings for this project (owned here)
virtual PROJECT_FILE & GetProjectFile() const
SCH_SHEET_LIST GetSheets() const override
Builds and returns an updated schematic hierarchy TODO: can this be cached?
PROJECT & Prj() const override
Return a reference to the project this schematic is part of.
ERC_SETTINGS & ErcSettings() const
Class for a bus to bus entry.
SCH_ITEM * m_connected_bus_items[2]
Pointer to the bus items (usually bus wires) connected to this bus-bus entry (either or both may be n...
VECTOR2I GetPosition() const override
Class for a wire to bus entry.
SCH_ITEM * m_connected_bus_item
Pointer to the bus item (usually a bus wire) connected to this bus-wire entry, if it is connected to ...
Each graphical item can have a SCH_CONNECTION describing its logical connection (to a bus or net).
void ConfigureFromLabel(const wxString &aLabel)
Configures the connection given a label.
void SetSubgraphCode(int aCode)
void SetBusCode(int aCode)
void SetName(const wxString &aName)
CONNECTION_TYPE Type() const
void SetNetCode(int aCode)
SCH_ITEM * m_driver
The SCH_ITEM that drives this connection's net.
bool IsDriver() const
Checks if the SCH_ITEM this connection is attached to can drive connections Drivers can be labels,...
void SetType(CONNECTION_TYPE aType)
wxString LocalName() const
wxString Name(bool aIgnoreSheet=false) const
bool IsSubsetOf(SCH_CONNECTION *aOther) const
Returns true if this connection is contained within aOther (but not the same as aOther)
void SetDriver(SCH_ITEM *aItem)
void Clone(const SCH_CONNECTION &aOther)
Copies connectivity information (but not parent) from another connection.
void SetGraph(CONNECTION_GRAPH *aGraph)
const std::vector< std::shared_ptr< SCH_CONNECTION > > & Members() const
Base class for any item which can be embedded within the SCHEMATIC container class,...
virtual const wxString & GetCachedDriverName() const
void AddConnectionTo(const SCH_SHEET_PATH &aPath, SCH_ITEM *aItem)
Add a connection link between this item and another.
SCH_LAYER_ID GetLayer() const
Return the layer this item is on.
virtual void RunOnChildren(const std::function< void(SCH_ITEM *)> &aFunction)
void SetConnectionGraph(CONNECTION_GRAPH *aGraph)
Updates the connection graph for all connections in this item.
virtual bool HasCachedDriverName() const
SCH_CONNECTION * Connection(const SCH_SHEET_PATH *aSheet=nullptr) const
Retrieve the connection associated with this object in the given sheet.
LABEL_FLAG_SHAPE GetShape() const
Segment description base class to describe items which have 2 end points (track, wire,...
bool IsGlobalPower() const
LIB_PIN * GetLibPin() const
bool IsStacked(const SCH_PIN *aPin) const
SCH_SYMBOL * GetParentSymbol() const
void Append(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
EE_RTREE & Items()
Gets the full RTree, usually for iterating.
SCH_LINE * GetBus(const VECTOR2I &aPosition, int aAccuracy=0, SCH_LINE_TEST_T aSearchType=ENTIRE_LENGTH_T) const
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
const SCH_SHEET * GetSheet(unsigned aIndex) const
wxString PathHumanReadable(bool aUseShortRootName=true, bool aStripTrailingSeparator=false) const
Return the sheet path in a human readable form made from the sheet names.
SCH_SCREEN * LastScreen()
void push_back(SCH_SHEET *aSheet)
Forwarded method from std::vector.
size_t size() const
Forwarded method from std::vector.
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
SCH_SCREEN * GetScreen() const
std::vector< SCH_SHEET_PIN * > & GetPins()
std::vector< SCH_PIN * > GetPins(const SCH_SHEET_PATH *aSheet=nullptr) const
Retrieve a list of the SCH_PINs for the given sheet path.
int GetUnitSelection(const SCH_SHEET_PATH *aSheet) const
Return the instance-specific unit selection for the given sheet path.
bool GetExcludedFromBoard() const
std::unique_ptr< LIB_SYMBOL > & GetLibSymbolRef()
VECTOR2I GetPosition() const override
virtual wxString GetShownText(const SCH_SHEET_PATH *aPath, bool aAllowExtraText, int aDepth=0) const
static const wxChar DanglingProfileMask[]
static const wxChar ConnTrace[]
#define CANDIDATE
flag indicating that the structure is connected
@ ERCE_DRIVER_CONFLICT
Conflicting drivers (labels, etc) on a subgraph.
@ ERCE_LABEL_NOT_CONNECTED
Label not connected to anything.
@ ERCE_BUS_TO_BUS_CONFLICT
A connection between bus objects doesn't share at least one net.
@ ERCE_BUS_ENTRY_CONFLICT
A wire connected to a bus doesn't match the bus.
@ ERCE_NETCLASS_CONFLICT
Multiple labels assign different netclasses to same net.
@ ERCE_GLOBLABEL
A global label is unique.
@ ERCE_BUS_TO_NET_CONFLICT
A bus wire is graphically connected to a net port/pin (or vice versa).
@ ERCE_NOCONNECT_NOT_CONNECTED
A no connect symbol is not connected to anything.
@ ERCE_PIN_NOT_CONNECTED
Pin not connected and not no connect symbol.
@ ERCE_NOCONNECT_CONNECTED
A no connect symbol is connected to more than 1 pin.
@ ERCE_HIERACHICAL_LABEL
Mismatch between hierarchical labels and pins sheets.
@ ERCE_WIRE_DANGLING
Some wires are not connected to anything else.
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
void delete_if(_Container &__c, _Function &&__f)
Deletes all values from __c for which __f returns true.
void remove_duplicates(_Container &__c)
Deletes all duplicate values from __c.
void delete_matching(_Container &__c, _Value __value)
Covers for the horrifically named std::remove and std::remove_if (neither of which remove anything).
std::vector< SCH_ITEM * > SCH_ITEM_SET
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
std::vector< FAB_LAYER_COLOR > dummy
wxString UnescapeString(const wxString &aSource)
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...
BS::thread_pool thread_pool
thread_pool & GetKiCadThreadPool()
Get a reference to the current thread pool.
Functions to provide common constants and other functions to assist in making a consistent UI.