26#include <unordered_map>
70 std::vector<SCH_ITEM*> candidates;
71 std::vector<SCH_ITEM*> strong_drivers;
87 && !
static_cast<SCH_PIN*
>( item )->GetParentSymbol()->IsInNetlist() )
91 strong_drivers.push_back( item );
93 if( item_priority > highest_priority )
96 candidates.push_back( item );
97 highest_priority = item_priority;
99 else if( !candidates.empty() && ( item_priority == highest_priority ) )
101 candidates.push_back( item );
111 if( !candidates.empty() )
113 if( candidates.size() > 1 )
124 if( p->
GetShape() == LABEL_FLAG_SHAPE::L_OUTPUT )
134 std::sort( candidates.begin(), candidates.end(),
141 SCH_CONNECTION* ac = a->Connection( &m_sheet );
142 SCH_CONNECTION* bc = b->Connection( &m_sheet );
145 if( ac->IsBus() && bc->IsBus() )
146 return bc->IsSubsetOf( ac );
150 if( a->Type() == SCH_PIN_T && b->Type() == SCH_PIN_T )
152 SCH_PIN* pa = static_cast<SCH_PIN*>( a );
153 SCH_PIN* pb = static_cast<SCH_PIN*>( b );
155 bool aPower = pa->GetLibPin()->GetParent()->IsPower();
156 bool bPower = pb->GetLibPin()->GetParent()->IsPower();
158 if( aPower && !bPower )
160 else if( bPower && !aPower )
166 bool a_lowQualityName = a_name.Contains(
"-Pad" );
167 bool b_lowQualityName = b_name.Contains(
"-Pad" );
169 if( a_lowQualityName && !b_lowQualityName )
171 else if( b_lowQualityName && !a_lowQualityName )
174 return a_name < b_name;
183 if( strong_drivers.size() > 1 )
184 m_multiple_drivers =
true;
187 if( m_strong_driver )
188 m_drivers = strong_drivers;
193 m_driver_connection = m_driver->
Connection( &m_sheet );
195 m_driver_connection->SetDriver( m_driver );
196 m_driver_connection->ClearDirty();
198 else if( !m_is_bus_member )
200 m_driver_connection =
nullptr;
203 if( aCheckMultipleDrivers && m_multiple_drivers )
207 const wxString& first = GetNameForDriver( candidates[0] );
210 for(
unsigned i = 1; i < candidates.size(); i++ )
212 if( GetNameForDriver( candidates[i] ) != first )
214 second_item = candidates[i];
222 m_first_driver = m_driver;
223 m_second_driver = second_item;
227 return ( m_driver !=
nullptr );
238 aSubgraphs.insert( sg );
242 aItems.emplace(
m_sheet, item );
256#ifdef CONNECTIVITY_DEBUG
257 wxASSERT_MSG(
false, wxS(
"Tried to get the net name of an item with no connection" ) );
269 std::vector<SCH_ITEM*> labels;
273 switch( item->Type() )
281 if( type == CONNECTION_TYPE::BUS || type == CONNECTION_TYPE::BUS_GROUP )
282 labels.push_back( item );
298 std::vector<SCH_ITEM*> labels;
302 switch( item->Type() )
310 if( label_conn->
Type() == CONNECTION_TYPE::BUS )
311 labels.push_back( item );
327 switch( aItem->
Type() )
333 return pin->GetDefaultNetName(
m_sheet, forceNoConnect );
350 wxFAIL_MSG( wxS(
"Unhandled item type in GetNameForDriver" ) );
354 return wxEmptyString;
375 SCH_FIELD* field = static_cast<SCH_FIELD*>( aChild );
377 if( field->GetCanonicalName() == wxT(
"Netclass" ) )
379 netclass = field->GetText();
413 child->m_absorbed_by =
this;
416 set_absorbed_by( subchild );
424 set_absorbed_by( aOther );
474 switch( aDriver->
Type() )
501 std::back_inserter(
m_items ) );
555 if( subgraph->m_graph ==
this )
579 std::function<
void(
SCH_ITEM* )>* aChangedItemHandler )
581 PROF_TIMER recalc_time(
"CONNECTION_GRAPH::Recalculate" );
586 PROF_TIMER update_items(
"updateItemConnectivity" );
592 std::vector<SCH_ITEM*> items;
595 std::vector<std::pair<SCH_SYMBOL*, int>> symbolsChanged;
597 for(
SCH_ITEM* item : sheet.LastScreen()->Items() )
599 if( item->IsConnectable() && ( aUnconditional || item->IsConnectivityDirty() ) )
600 items.push_back( item );
611 if( symbol->
GetUnit() != new_unit )
612 symbolsChanged.push_back( { symbol, symbol->
GetUnit() } );
614 symbol->UpdateUnit( new_unit );
623 sheet.LastScreen()->TestDanglingEnds( &sheet, aChangedItemHandler );
627 for(
auto& item : symbolsChanged )
629 item.first->UpdateUnit( item.second );
636 PROF_TIMER build_graph(
"buildConnectionGraph" );
638 buildConnectionGraph( aChangedItemHandler );
650 const std::set<SCH_ITEM*> &aItems )
652 std::set<std::pair<SCH_SHEET_PATH, SCH_ITEM*>> retvals;
653 std::set<CONNECTION_SUBGRAPH*> subgraphs;
658 while( aSubgraph->m_absorbed_by )
659 aSubgraph = aSubgraph->m_absorbed_by;
662 while( aSubgraph->m_hier_parent )
663 aSubgraph = aSubgraph->m_hier_parent;
666 aSubgraph->getAllConnectedItems( retvals, subgraphs );
678 traverse_subgraph( sg );
683 traverse_subgraph( bus_sg );
689 traverse_subgraph( bus_sg );
705 std::set<int> codes_to_remove;
709 std::sort( el.second.begin(), el.second.end() );
714 for(
auto it : sg->m_bus_neighbors )
720 for(
auto test = parents.begin();
test != parents.end(); )
728 if( parents.empty() )
733 for(
auto it : sg->m_bus_parents )
739 for(
auto test = neighbors.begin();
test != neighbors.end(); )
747 if( neighbors.empty() )
768 auto it = std::lower_bound( el.second.begin(), el.second.end(), sg );
770 if( it != el.second.end() )
771 el.second.erase( it );
774 auto remove_sg = [sg](
auto it ) ->
bool
787 if( remove_sg( it ) )
795 if( remove_sg( it ) )
803 if( remove_sg( it ) )
805 codes_to_remove.insert( it->first.Netcode );
814 if( remove_sg( it ) )
822 if( it->second == sg )
833 if( codes_to_remove.find( it->second ) != codes_to_remove.end() )
841 if( codes_to_remove.find( it->second ) != codes_to_remove.end() )
856 const std::vector<SCH_ITEM*>& aItemList )
858 std::map<VECTOR2I, std::vector<SCH_ITEM*>> connection_map;
862 std::vector<VECTOR2I> points = item->GetConnectionPoints();
863 item->ConnectedItems( aSheet ).clear();
869 pin->InitializeConnection( aSheet,
this );
871 pin->ConnectedItems( aSheet ).clear();
873 connection_map[
pin->GetTextPos() ].push_back(
pin );
888 wxString
name =
pin->GetDefaultNetName( aSheet );
889 pin->ConnectedItems( aSheet ).clear();
892 if(
pin->IsGlobalPower() )
898 connection_map[ pos ].push_back(
pin );
905 SCH_CONNECTION* conn = item->InitializeConnection( aSheet,
this );
908 switch( item->Type() )
912 CONNECTION_TYPE::NET );
916 conn->
SetType( CONNECTION_TYPE::BUS );
923 conn->
SetType( CONNECTION_TYPE::NET );
927 conn->
SetType( CONNECTION_TYPE::NET );
936 for(
const VECTOR2I& point : points )
937 connection_map[ point ].push_back( item );
943 for(
const auto& it : connection_map )
945 std::vector<SCH_ITEM*> connection_vec = it.second;
946 std::sort( connection_vec.begin(), connection_vec.end() );
947 connection_vec.erase( std::unique( connection_vec.begin(), connection_vec.end() ),
948 connection_vec.end() );
953 std::mutex update_mutex;
955 auto update_lambda = [&](
SCH_ITEM* connected_item ) ->
size_t
969 if( connection_vec.size() == 1 )
982 if( connection_vec.size() < 2 )
988 if( it.first == bus_entry->GetPosition() )
991 bus_entry->m_connected_bus_items[1] = busLine;
993 std::lock_guard<std::mutex> lock( update_mutex );
1006 SCH_ITEM_SET& connected_set = connected_item->ConnectedItems( aSheet );
1007 connected_set.reserve( connection_vec.size() );
1009 for(
SCH_ITEM* test_item : connection_vec )
1011 bool bus_connection_ok =
true;
1013 if( test_item == connected_item )
1019 if( test_item->GetLayer() ==
LAYER_BUS )
1038 if( connected_item->ConnectionPropagatesTo( test_item ) &&
1039 test_item->ConnectionPropagatesTo( connected_item ) &&
1042 connected_set.push_back( test_item );
1053 if( !bus_entry->m_connected_bus_item )
1059 bus_entry->m_connected_bus_item = bus;
1068 tp.push_loop( connection_vec.size(),
1069 [&](
const int a,
const int b)
1071 for( int ii = a; ii < b; ++ii )
1072 update_lambda( connection_vec[ii] );
1074 tp.wait_for_tasks();
1082 wxCHECK_RET(
m_schematic, wxS(
"Connection graph cannot be built without schematic pointer" ) );
1086 for(
unsigned i = 0; i < all_sheets.size(); i++ )
1088 for(
const std::shared_ptr<BUS_ALIAS>& alias : all_sheets[i].LastScreen()->GetBusAliases() )
1096 for(
const auto& it : item->m_connection_map )
1113 std::list<SCH_ITEM*> memberlist;
1118 SCH_CONNECTION* conn = aItem->GetOrInitConnection( sheet,
this );
1119 bool unique = !( aItem->GetFlags() &
CANDIDATE );
1124 return ( unique && conn && ( conn->
SubgraphCode() == 0 ) );
1127 std::copy_if( item->ConnectedItems( sheet ).begin(),
1128 item->ConnectedItems( sheet ).end(),
1129 std::back_inserter( memberlist ), get_items );
1131 for(
SCH_ITEM* connected_item : memberlist )
1136 SCH_CONNECTION* connected_conn = connected_item->Connection( &sheet );
1138 wxASSERT( connected_conn );
1144 subgraph->
AddItem( connected_item );
1145 SCH_ITEM_SET& citemset = connected_item->ConnectedItems( sheet );
1152 if( get_items( citem ) )
1153 memberlist.push_back( citem );
1158 for(
SCH_ITEM* connected_item : memberlist )
1159 connected_item->ClearFlags(
CANDIDATE );
1172 std::vector<CONNECTION_SUBGRAPH*> dirty_graphs;
1177 return candidate->m_dirty;
1180 std::vector<std::future<size_t>> returns( dirty_graphs.size() );
1184 if( !subgraph->m_dirty )
1188 for(
SCH_ITEM* item : subgraph->m_items )
1190 switch( item->
Type() )
1193 subgraph->m_no_connect = item;
1197 subgraph->m_bus_entry = item;
1204 if(
pin->GetType() == ELECTRICAL_PINTYPE::PT_NC )
1205 subgraph->m_no_connect = item;
1215 subgraph->ResolveDrivers(
true );
1216 subgraph->m_dirty =
false;
1223 tp.push_loop( dirty_graphs.size(),
1224 [&](
const int a,
const int b)
1226 for( int ii = a; ii < b; ++ii )
1227 update_lambda( dirty_graphs[ii] );
1229 tp.wait_for_tasks();
1236 return candidate->m_driver;
1249 wxString full_name = subgraph->m_driver_connection->Name();
1250 wxString
name = subgraph->m_driver_connection->Name(
true );
1257 if( subgraph->m_driver_connection->Type() == CONNECTION_TYPE::BUS )
1259 wxString prefixOnly = full_name.BeforeFirst(
'[' ) + wxT(
"[]" );
1263 subgraph->m_dirty =
true;
1265 if( subgraph->m_strong_driver )
1267 SCH_ITEM* driver = subgraph->m_driver;
1270 switch( driver->
Type() )
1286 wxASSERT(
pin->IsGlobalPower() );
1294 wxLogTrace(
ConnTrace, wxS(
"Unexpected strong driver %s" ),
1306 std::vector<CONNECTION_SUBGRAPH*> new_subgraphs;
1312 auto vec = subgraph->GetAllBusLabels();
1314 for(
auto& item : vec )
1322 for(
auto& conn :
dummy.Members() )
1324 wxString
name = conn->FullLocalName();
1330 new_conn->
SetType( CONNECTION_TYPE::NET );
1333 wxLogTrace(
ConnTrace, wxS(
"SG(%ld), Adding full local name (%s) with sg (%d)" ), subgraph->m_code,
1347 new_subgraphs.push_back( new_sg );
1352 std::copy( new_subgraphs.begin(), new_subgraphs.end(), std::back_inserter(
m_driver_subgraphs ) );
1362 std::unordered_map<int, CONNECTION_SUBGRAPH*> global_power_pin_subgraphs;
1369 if( !
pin->ConnectedItems( sheet ).empty() && !
pin->GetLibPin()->GetParent()->IsPower() )
1384 if(
pin->GetLibPin()->GetParent()->IsPower() )
1385 connection->
SetName(
pin->GetParentSymbol()->GetValueFieldText(
true, &sheet,
false ) );
1394 auto jj = global_power_pin_subgraphs.find( code );
1396 if( jj != global_power_pin_subgraphs.end() )
1398 subgraph = jj->second;
1416 global_power_pin_subgraphs[code] = subgraph;
1433 std::unordered_set<CONNECTION_SUBGRAPH*> invalidated_subgraphs;
1437 if( subgraph->m_absorbed )
1442 wxString
name = connection->
Name();
1445 unsigned suffix = 1;
1447 auto create_new_name =
1451 wxString suffixStr = std::to_wstring( suffix );
1456 if( aConn->Type() == CONNECTION_TYPE::BUS_GROUP )
1458 wxString prefix = aConn->BusPrefix();
1460 if( prefix.empty() )
1461 prefix = wxT(
"BUS" );
1463 wxString oldName = aConn->Name().AfterFirst(
'{' );
1465 newName << prefix << wxT(
"_" ) << suffixStr << wxT(
"{" ) << oldName;
1467 aConn->ConfigureFromLabel( newName );
1471 newName << aConn->Name() << wxT(
"_" ) << suffixStr;
1472 aConn->SetSuffix( wxString( wxT(
"_" ) ) << suffixStr );
1479 if( !subgraph->m_strong_driver )
1485 if( vec->size() <= 1 && subgraph->m_driver_connection->Type() == CONNECTION_TYPE::BUS )
1487 wxString prefixOnly =
name.BeforeFirst(
'[' ) + wxT(
"[]" );
1491 if( vec->size() > 1 )
1493 wxString new_name = create_new_name( connection );
1496 new_name = create_new_name( connection );
1498 wxLogTrace(
ConnTrace, wxS(
"%ld (%s) is weakly driven and not unique. Changing to %s." ),
1499 subgraph->m_code,
name, new_name );
1507 else if( subgraph->m_driver )
1519 bool conflict =
false;
1520 wxString global_name = connection->
Name(
true );
1527 std::vector<CONNECTION_SUBGRAPH*>& candidates = kk->second;
1531 if( candidate->m_sheet == sheet )
1539 wxS(
"%ld (%s) skipped for promotion due to potential conflict" ),
1540 subgraph->m_code,
name );
1547 wxS(
"%ld (%s) weakly driven by unique sheet pin %s, promoting" ),
1548 subgraph->m_code,
name,
1549 subgraph->m_driver->GetItemDescription( &unitsProvider ) );
1551 subgraph->m_strong_driver =
true;
1559 if( connection->
IsBus() )
1583 subgraph->m_dirty =
true;
1592 if( !subgraph->m_strong_driver )
1600 std::vector<CONNECTION_SUBGRAPH*> candidate_subgraphs;
1603 std::back_inserter( candidate_subgraphs ),
1606 return ( !candidate->m_absorbed &&
1607 candidate->m_strong_driver &&
1608 candidate != subgraph );
1614 std::vector< std::shared_ptr<SCH_CONNECTION> > connections_to_check;
1617 connections_to_check.push_back( std::make_shared<SCH_CONNECTION>( *connection ) );
1619 auto add_connections_to_check =
1622 for(
SCH_ITEM* possible_driver : aSubgraph->m_items )
1624 if( possible_driver == aSubgraph->m_driver )
1631 if( c->Type() != aSubgraph->m_driver_connection->Type() )
1634 if( c->Name(
true ) == aSubgraph->m_driver_connection->Name(
true ) )
1637 connections_to_check.push_back( c );
1639 wxS(
"%lu (%s): Adding secondary driver %s" ), aSubgraph->m_code,
1640 aSubgraph->m_driver_connection->Name(
true ),
1649 add_connections_to_check( subgraph );
1651 for(
unsigned i = 0; i < connections_to_check.size(); i++ )
1653 auto member = connections_to_check[i];
1655 if( member->IsBus() )
1657 connections_to_check.insert( connections_to_check.end(),
1658 member->Members().begin(),
1659 member->Members().end() );
1662 wxString test_name = member->Name(
true );
1666 if( candidate->
m_absorbed || candidate == subgraph )
1682 if( driver == candidate->
m_driver )
1693 if(
pin->IsGlobalPower()
1694 &&
pin->GetDefaultNetName( sheet ) == test_name )
1706 if( subgraph->GetNameForDriver( driver ) == test_name )
1719 wxLogTrace(
ConnTrace, wxS(
"%lu (%s) has bus child %lu (%s)" ), subgraph->m_code,
1720 connection->
Name(), candidate->
m_code, member->Name() );
1722 subgraph->m_bus_neighbors[member].insert( candidate );
1727 wxLogTrace(
ConnTrace, wxS(
"%lu (%s) absorbs neighbor %lu (%s)" ),
1728 subgraph->m_code, connection->
Name(),
1732 add_connections_to_check( candidate );
1734 subgraph->Absorb( candidate );
1735 invalidated_subgraphs.insert( subgraph );
1745 if( subgraph->m_absorbed )
1748 if( !subgraph->ResolveDrivers() )
1751 if( subgraph->m_driver_connection->IsBus() )
1756 wxLogTrace(
ConnTrace, wxS(
"Re-resolving drivers for %lu (%s)" ), subgraph->m_code,
1757 subgraph->m_driver_connection->Name() );
1778 wxCHECK_RET(
m_schematic, wxT(
"Connection graph cannot be built without schematic pointer" ) );
1782 for(
unsigned i = 0; i < all_sheets.size(); i++ )
1784 for(
const std::shared_ptr<BUS_ALIAS>& alias : all_sheets[i].LastScreen()->GetBusAliases() )
1788 PROF_TIMER sub_graph(
"buildItemSubGraphs" );
1808 PROF_TIMER proc_sub_graph(
"ProcessSubGraphs" );
1812 proc_sub_graph.
Show();
1821 std::vector<CONNECTION_SUBGRAPH*> global_subgraphs;
1823 std::back_inserter( global_subgraphs ),
1826 return !candidate->m_local_driver;
1838 [&](
const int a,
const int b)
1840 for( int ii = a; ii < b; ++ii )
1841 m_driver_subgraphs[ii]->UpdateItemConnections();
1843 tp.wait_for_tasks();
1851 if( !subgraph->m_dirty )
1854 wxLogTrace(
ConnTrace, wxS(
"Processing %lu (%s) for propagation" ), subgraph->m_code,
1855 subgraph->m_driver_connection->Name() );
1861 if( !subgraph->m_local_driver && subgraph->m_multiple_drivers )
1863 for(
SCH_ITEM* driver : subgraph->m_drivers )
1865 if( driver == subgraph->m_driver )
1868 const wxString& secondary_name = subgraph->GetNameForDriver( driver );
1870 if( secondary_name == subgraph->m_driver_connection->Name() )
1878 if( candidate == subgraph )
1881 if( !secondary_is_global && candidate->
m_sheet != subgraph->m_sheet )
1886 if( conn->
Name() == secondary_name )
1888 wxLogTrace(
ConnTrace, wxS(
"Global %lu (%s) promoted to %s" ), candidate->
m_code,
1889 conn->
Name(), subgraph->m_driver_connection->Name() );
1891 conn->
Clone( *subgraph->m_driver_connection );
1910 if( subgraph->m_dirty )
1927 wxASSERT_MSG( !subgraph->m_dirty, wxS(
"Subgraph not processed by propagateToNeighbors!" ) );
1929 if( subgraph->m_bus_parents.size() < 2 )
1934 wxLogTrace(
ConnTrace, wxS(
"%lu (%s) has multiple bus parents" ),
1935 subgraph->m_code, conn->
Name() );
1937 wxASSERT( conn->
IsNet() );
1939 for(
const auto& ii : subgraph->m_bus_parents )
1952 wxLogTrace(
ConnTrace, wxS(
"Warning: could not match %s inside %lu (%s)" ),
1957 if( conn->
Name() != match->
Name() )
1959 wxString old_name = match->
Name();
1961 wxLogTrace(
ConnTrace, wxS(
"Updating %lu (%s) member %s to %s" ), parent->
m_code,
1964 match->
Clone( *conn );
1984 auto updateItemConnectionsTask =
1988 if( !subgraph->m_strong_driver && subgraph->m_drivers.size() == 1 &&
1989 subgraph->m_driver->Type() ==
SCH_PIN_T )
1992 wxString
name =
pin->GetDefaultNetName( subgraph->m_sheet,
true );
1994 subgraph->m_driver_connection->ConfigureFromLabel(
name );
1997 subgraph->m_dirty =
false;
1998 subgraph->UpdateItemConnections();
2001 if( subgraph->m_driver_connection->IsBus() )
2007 if( subgraph->m_driver && subgraph->m_driver->Type() ==
SCH_SHEET_PIN_T )
2013 wxString pinText =
pin->GetText();
2020 if( label->
GetText() == pinText )
2023 path.push_back( sheet );
2027 if( parent_conn && parent_conn->
IsBus() )
2028 subgraph->m_driver_connection->
SetType( CONNECTION_TYPE::BUS );
2034 if( subgraph->m_driver_connection->IsBus() )
2043 [&](
const int a,
const int b)
2045 for(
int ii = a; ii < b; ++ii )
2048 tp.wait_for_tasks();
2056 subgraph->m_driver_connection->NetCode() };
2063 std::map<wxString, wxString> oldAssignments = netSettings->m_NetClassLabelAssignments;
2065 netSettings->m_NetClassLabelAssignments.clear();
2067 auto dirtySubgraphs =
2068 [&](
const std::vector<CONNECTION_SUBGRAPH*>& subgraphs )
2070 if( aChangedItemHandler )
2074 for(
SCH_ITEM* item : subgraph->m_items )
2075 (*aChangedItemHandler)( item );
2080 auto checkNetclassDrivers =
2081 [&](
const std::vector<CONNECTION_SUBGRAPH*>& subgraphs )
2086 wxCHECK_RET( !subgraphs.empty(), wxT(
"Invalid empty subgraph" ) );
2090 for(
SCH_ITEM* item : subgraph->m_items )
2092 netclass = subgraph->GetNetclassForDriver( item );
2094 if( !netclass.IsEmpty() )
2098 if( !netclass.IsEmpty() )
2100 driverSubgraph = subgraph;
2105 if( netclass.IsEmpty() )
2108 if( !driverSubgraph )
2109 driverSubgraph = subgraphs.front();
2111 const wxString netname = driverSubgraph->
GetNetName();
2117 netSettings->m_NetClassLabelAssignments[ member->Name() ] = netclass;
2122 dirtySubgraphs( ii->second );
2126 netSettings->m_NetClassLabelAssignments[ netname ] = netclass;
2128 if( oldAssignments[ netname ] != netclass )
2129 dirtySubgraphs( subgraphs );
2133 checkNetclassDrivers( subgraphs );
2169 std::vector<std::shared_ptr<SCH_CONNECTION>> connections_to_check( aConnection->
Members() );
2171 for(
unsigned i = 0; i < connections_to_check.size(); i++ )
2173 const std::shared_ptr<SCH_CONNECTION>& member = connections_to_check[i];
2175 if( member->IsBus() )
2177 connections_to_check.insert( connections_to_check.end(),
2178 member->Members().begin(),
2179 member->Members().end() );
2191 std::vector<CONNECTION_SUBGRAPH*> search_list;
2192 std::unordered_set<CONNECTION_SUBGRAPH*> visited;
2193 std::vector<SCH_CONNECTION*> stale_bus_members;
2201 path.push_back(
pin->GetParent() );
2212 || visited.count( candidate ) )
2221 wxLogTrace(
ConnTrace, wxS(
"%lu: found child %lu (%s)" ), aParent->m_code,
2227 search_list.push_back( candidate );
2236 for(
const auto&
kv : aParentGraph->m_bus_neighbors )
2278 wxLogTrace(
ConnTrace, wxS(
"Could not match bus member %s in %s" ),
2279 kv.first->Name(), parent->
Name() );
2284 auto neighbor_name = neighbor_conn->
Name();
2287 if( neighbor_name == member->
Name() )
2291 if( neighbor_conn->Sheet() != neighbor->
m_sheet )
2295 wxASSERT( neighbor_conn->IsNet() );
2297 wxLogTrace(
ConnTrace, wxS(
"%lu (%s) connected to bus member %s (local %s)" ),
2304 member->
Clone( *neighbor_conn );
2305 stale_bus_members.push_back( member );
2309 neighbor_conn->Clone( *member );
2323 propagate_bus_neighbors( aSubgraph );
2330 wxLogTrace(
ConnTrace, wxS(
"%lu (%s) has both hier ports and pins; deferring processing" ),
2336 wxLogTrace(
ConnTrace, wxS(
"%lu (%s) has no hier pins or ports; marking clean" ),
2342 visited.insert( aSubgraph );
2344 wxLogTrace(
ConnTrace, wxS(
"Propagating %lu (%s) to subsheets" ),
2349 for(
unsigned i = 0; i < search_list.size(); i++ )
2351 auto child = search_list[i];
2353 visited.insert( child );
2357 child->m_dirty =
false;
2372 if( subgraph == aSubgraph )
2379 wxString candidateName = subgraph->m_driver_connection->Name();
2380 bool shorterPath = subgraph->m_sheet.size() < bestDriver->
m_sheet.
size();
2381 bool asGoodPath = subgraph->m_sheet.size() <= bestDriver->
m_sheet.
size();
2391 ( !bestIsStrong && candidateStrong ) ||
2392 ( priority > highest && candidateStrong ) ||
2393 ( priority == highest && candidateStrong && shorterPath ) ||
2394 ( ( bestIsStrong == candidateStrong ) && asGoodPath && ( priority == highest ) &&
2395 ( candidateName < bestName ) ) )
2397 bestDriver = subgraph;
2399 bestIsStrong = candidateStrong;
2400 bestName = candidateName;
2405 if( bestDriver != aSubgraph )
2407 wxLogTrace(
ConnTrace, wxS(
"%lu (%s) overridden by new driver %lu (%s)" ),
2416 wxString old_name = subgraph->m_driver_connection->
Name();
2418 subgraph->m_driver_connection->Clone( *conn );
2420 if( old_name != conn->
Name() )
2424 propagate_bus_neighbors( subgraph );
2430 if( conn->
IsBus() && !stale_bus_members.empty() )
2441 wxLogTrace(
ConnTrace, wxS(
"WARNING: failed to match stale member %s in %s." ),
2442 stale_member->Name(), subgraph->m_driver_connection->Name() );
2446 wxLogTrace(
ConnTrace, wxS(
"Updating %lu (%s) member %s to %s" ), subgraph->m_code,
2447 subgraph->m_driver_connection->Name(), member->
LocalName(),
2448 stale_member->Name() );
2450 member->
Clone( *stale_member );
2452 propagate_bus_neighbors( subgraph );
2464 std::shared_ptr<SCH_CONNECTION> c = std::shared_ptr<SCH_CONNECTION>(
nullptr );
2466 switch( aItem->
Type() )
2472 if(
pin->IsGlobalPower() )
2473 c = std::make_shared<SCH_CONNECTION>( aItem, aSubgraph->
m_sheet );
2482 c = std::make_shared<SCH_CONNECTION>( aItem, aSubgraph->
m_sheet );
2492 c->SetGraph(
this );
2503 wxASSERT( aBusConnection->
IsBus() );
2507 if( aBusConnection->
Type() == CONNECTION_TYPE::BUS )
2512 for(
const std::shared_ptr<SCH_CONNECTION>& bus_member : aBusConnection->
Members() )
2514 if( bus_member->VectorIndex() == aSearch->
VectorIndex() )
2516 match = bus_member.get();
2524 for(
const std::shared_ptr<SCH_CONNECTION>& c : aBusConnection->
Members() )
2529 if( c->Type() == CONNECTION_TYPE::BUS )
2531 for(
const std::shared_ptr<SCH_CONNECTION>& bus_member : c->Members() )
2533 if( bus_member->LocalName() == aSearch->
LocalName() )
2535 match = bus_member.get();
2540 else if( c->LocalName() == aSearch->
LocalName() )
2553 const wxString& aOldName )
2559 std::vector<CONNECTION_SUBGRAPH*>& vec = it->second;
2563 wxLogTrace(
ConnTrace, wxS(
"recacheSubgraphName: %s => %s" ), aOldName,
2580 std::vector<const CONNECTION_SUBGRAPH*> ret;
2585 wxASSERT( !subgraph->m_dirty );
2587 if( !subgraph->m_driver )
2592 if( !connection->
IsBus() )
2595 auto labels = subgraph->GetVectorBusLabels();
2597 if( labels.size() > 1 )
2599 bool different =
false;
2600 wxString first =
static_cast<SCH_TEXT*
>( labels.at( 0 ) )->GetShownText(
false );
2602 for(
unsigned i = 1; i < labels.size(); ++i )
2614 wxLogTrace(
ConnTrace, wxS(
"SG %ld (%s) has multiple bus labels" ), subgraph->m_code,
2615 connection->
Name() );
2617 ret.push_back( subgraph );
2637 if( graph == aSubGraph )
2678 wxASSERT( !it->second.empty() );
2680 return it->second[0];
2697 const wxString& aNetName )
const
2699 std::vector<CONNECTION_SUBGRAPH*> subgraphs;
2712 int error_count = 0;
2714 wxCHECK_MSG(
m_schematic,
true, wxS(
"Null m_schematic in CONNECTION_GRAPH::RunERC" ) );
2720 std::set<SCH_ITEM*> seenDriverInstances;
2725 wxCHECK2( subgraph,
continue );
2728 wxASSERT( !subgraph->m_dirty );
2730 if( subgraph->m_absorbed )
2733 if( seenDriverInstances.count( subgraph->m_driver ) )
2736 if( subgraph->m_driver )
2737 seenDriverInstances.insert( subgraph->m_driver );
2755 subgraph->ResolveDrivers(
false );
2819 wxCHECK( aSubgraph,
false );
2832 static_cast<SCH_PIN*
>( primary )->GetTransformedPosition() :
2838 wxString msg = wxString::Format(
_(
"Both %s and %s are attached to the same "
2839 "items; %s will be used in the netlist" ),
2840 primaryName, secondaryName, primaryName );
2843 ercItem->SetItems( primary, secondary );
2844 ercItem->SetErrorMessage( msg );
2856 if( driver == aSubgraph->
m_driver )
2868 if( primaryName == secondaryName )
2871 wxString msg = wxString::Format(
_(
"Both %s and %s are attached to the same "
2872 "items; %s will be used in the netlist" ),
2873 primaryName, secondaryName, primaryName );
2876 ercItem->SetItems( aSubgraph->
m_driver, driver );
2877 ercItem->SetErrorMessage( msg );
2894 wxString firstNetclass;
2895 SCH_ITEM* firstNetclassDriver =
nullptr;
2899 for(
SCH_ITEM* item : subgraph->m_items )
2901 const wxString netclass = subgraph->GetNetclassForDriver( item );
2903 if( netclass.IsEmpty() )
2906 if( netclass != firstNetclass )
2908 if( !firstNetclassDriver )
2910 firstNetclass = netclass;
2911 firstNetclassDriver = item;
2916 ercItem->SetItems( firstNetclassDriver, item );
2919 subgraph->m_sheet.LastScreen()->Append( marker );
2941 switch( item->
Type() )
2946 bus_item = ( !bus_item ) ? item : bus_item;
2948 net_item = ( !net_item ) ? item : net_item;
2961 bus_item = ( !bus_item ) ? item : bus_item;
2963 net_item = ( !net_item ) ? item : net_item;
2972 if( net_item && bus_item )
2975 ercItem->SetItems( net_item, bus_item );
2978 screen->
Append( marker );
2997 switch( item->
Type() )
3028 if(
test != member && member->Name() ==
test->Name() )
3042 ercItem->SetItems( label, port );
3045 screen->
Append( marker );
3057 bool conflict =
false;
3073 switch( item->
Type() )
3103 std::set<wxString> test_names;
3113 if( member->Type() == CONNECTION_TYPE::BUS )
3115 for(
const auto& sub_member : member->Members() )
3117 if( test_names.count( sub_member->Name() ) )
3121 else if( test_names.count( member->Name() ) )
3140 wxString msg = wxString::Format(
_(
"Net %s is graphically connected to bus %s but is not a"
3141 " member of that bus" ),
3145 ercItem->SetItems( bus_entry, bus_wire );
3146 ercItem->SetErrorMessage( msg );
3149 screen->
Append( marker );
3167 std::set<SCH_PIN*> unique_pins;
3168 std::set<SCH_LABEL_BASE*> unique_labels;
3177 for(
SCH_ITEM* item : aProcessGraph->m_items )
3179 switch( item->
Type() )
3186 if( aProcessGraph == aSubgraph )
3189 if( std::none_of( unique_pins.begin(), unique_pins.end(),
3196 unique_pins.insert( test_pin );
3219 process_subgraph( subgraph );
3224 process_subgraph( aSubgraph );
3237 pos =
pin->GetTransformedPosition();
3246 screen->
Append( marker );
3257 screen->
Append( marker );
3264 bool has_other_connections =
false;
3265 std::vector<SCH_PIN*> pins;
3272 switch( item->
Type() )
3277 if( !has_other_connections && !pins.empty() )
3281 for(
SCH_PIN* other_pin : pins )
3285 has_other_connections =
true;
3291 pins.emplace_back(
static_cast<SCH_PIN*
>( item ) );
3298 has_other_connections =
true;
3305 pin = pins.empty() ? nullptr : pins[0];
3308 for(
SCH_PIN* test_pin : pins )
3310 if( test_pin->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN )
3321 if(
pin && !has_other_connections
3322 &&
pin->IsGlobalPower()
3323 && !
pin->GetLibPin()->GetParent()->IsPower() )
3325 wxString
name =
pin->Connection( &sheet )->Name();
3326 wxString local_name =
pin->Connection( &sheet )->Name(
true );
3331 has_other_connections =
true;
3336 if(
pin && !has_other_connections
3337 &&
pin->GetType() != ELECTRICAL_PINTYPE::PT_NC
3338 &&
pin->GetType() != ELECTRICAL_PINTYPE::PT_NIC
3342 ercItem->SetItems(
pin );
3345 screen->
Append( marker );
3353 if( pins.size() > 1 )
3355 for(
SCH_PIN* testPin : pins )
3360 if( testPin->GetLibPin()->GetParent()->IsPower()
3361 && testPin->ConnectedItems( sheet ).empty()
3365 ercItem->SetItems( testPin );
3368 testPin->GetTransformedPosition() );
3369 screen->
Append( marker );
3386 std::vector<SCH_ITEM*> wires;
3394 wires.emplace_back( item );
3396 wires.emplace_back( item );
3399 if( !wires.empty() )
3404 ercItem->SetItems( wires[0],
3405 wires.size() > 1 ? wires[1] :
nullptr,
3406 wires.size() > 2 ? wires[2] :
nullptr,
3407 wires.size() > 3 ? wires[3] :
nullptr );
3410 screen->
Append( marker );
3441 std::map<KICAD_T, std::vector<SCH_TEXT*>> label_map;
3448 std::count_if( aLocSubgraph->m_items.begin(), aLocSubgraph->m_items.end(), [](
const SCH_ITEM* item )
3449 { return item->Type() == SCH_PIN_T; } );
3452 auto reportError = [&](
SCH_TEXT* aText,
int errCode )
3457 ercItem->SetItems( aText );
3464 pinCount =
hasPins( aSubgraph );
3468 switch( item->
Type() )
3476 label_map[item->
Type()].push_back(
text );
3481 if(
text->IsDangling() )
3495 if( label_map.empty() )
3500 wxCHECK_MSG(
m_schematic,
true, wxS(
"Null m_schematic in CONNECTION_GRAPH::ercCheckLabels" ) );
3507 for(
auto& [type, label_vec] : label_map )
3526 int allPins = pinCount;
3534 if( neighbor == aSubgraph )
3540 allPins +=
hasPins( neighbor );
3544 if( allPins == 1 && !has_nc )
3572 for(
SCH_ITEM* item : sheet.LastScreen()->Items() )
3579 std::map<wxString, SCH_SHEET_PIN*> pins;
3580 std::map<wxString, SCH_HIERLABEL*> labels;
3585 pins[
pin->GetText()] =
pin;
3590 ercItem->SetItems(
pin );
3593 sheet.LastScreen()->Append( marker );
3601 std::set<wxString> matchedPins;
3609 if( !pins.count( label->
GetText() ) )
3610 labels[label->
GetText()] = label;
3612 matchedPins.insert( label->
GetText() );
3616 for(
const wxString& matched : matchedPins )
3617 pins.erase( matched );
3619 for(
const std::pair<const wxString, SCH_SHEET_PIN*>& unmatched : pins )
3621 wxString msg = wxString::Format(
_(
"Sheet pin %s has no matching hierarchical "
3622 "label inside the sheet" ),
3626 ercItem->SetItems( unmatched.second );
3627 ercItem->SetErrorMessage( msg );
3628 ercItem->SetSheetSpecificPath( sheet );
3629 ercItem->SetItemsSheetPaths( sheet );
3632 sheet.LastScreen()->Append( marker );
3637 for(
const std::pair<const wxString, SCH_HIERLABEL*>& unmatched : labels )
3639 wxString msg = wxString::Format(
_(
"Hierarchical label %s has no matching "
3640 "sheet pin in the parent sheet" ),
3644 parentSheetPath.
push_back( parentSheet );
3647 ercItem->SetItems( unmatched.second );
3648 ercItem->SetErrorMessage( msg );
3649 ercItem->SetSheetSpecificPath( parentSheetPath );
3650 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.
std::vector< SCH_ITEM * > m_items
Contents of the subgraph.
SCH_ITEM * m_no_connect
No-connect item in graph, if any.
std::vector< SCH_ITEM * > m_drivers
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::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.
SCH_ITEM * m_first_driver
Stores the primary driver for the multiple drivers ERC check.
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::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)
std::vector< SCH_HIERLABEL * > m_hier_ports
std::vector< SCH_SHEET_PIN * > m_hier_pins
bool m_is_bus_member
True if the subgraph is not actually part of a net.
CONNECTION_SUBGRAPH * m_hier_parent
SCH_ITEM * m_second_driver
Used for multiple drivers ERC message; stores the second possible driver (or nullptr)
bool m_local_driver
True if the driver is a local (i.e. non-global) type.
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
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
void Clone(const SCH_CONNECTION &aOther)
Copies connectivity information (but not parent) from another connection.
const std::vector< std::shared_ptr< SCH_CONNECTION > > & Members() const
Base class for any item which can be embedded within the SCHEMATIC container class,...
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 SetConnectivityDirty(bool aDirty=true)
void SetConnectionGraph(CONNECTION_GRAPH *aGraph)
Updates the connection graph for all connections in this item.
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 override
Segment description base class to describe items which have 2 end points (track, wire,...
bool IsGlobalPower() 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()
bool GetIncludeOnBoard() const
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.
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 ConnProfileMask[]
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 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:...
thread_pool & GetKiCadThreadPool()
Get a reference to the current thread pool.
BS::thread_pool thread_pool
Functions to provide common constants and other functions to assist in making a consistent UI.