KiCad PCB EDA Suite
Loading...
Searching...
No Matches
conn_navigation.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20#include "conn_navigation.h"
21
22#include <connection_graph.h>
23#include <schematic.h>
24#include <sch_item.h>
25#include <algorithm>
26
28{
29NAVIGATION_QUERY::NAVIGATION_QUERY( const SCHEMATIC& aSchematic ) : m_schematic( aSchematic )
30{}
31
32
33std::vector<wxString> NAVIGATION_QUERY::NetNames() const
34{
35 if( !m_schematic.IsValid() )
36 return {};
37
38 std::set<wxString> names;
39
40 for( const auto& [key, subgraphs] : m_schematic.ConnectionGraph()->GetNetMap() )
41 {
42 if( !key.Name.IsEmpty() )
43 names.insert( key.Name );
44 }
45
46 return { names.begin(), names.end() };
47}
48
49
50std::vector<SCH_ITEM*> NAVIGATION_QUERY::WholeNetItems( const std::vector<SCH_ITEM*>& aSeeds,
51 const SCH_SHEET_PATH& aSheet ) const
52{
53 std::set<wxString> names;
54
55 for( SCH_ITEM* seed : aSeeds )
56 {
57 if( !seed )
58 continue;
59
60 if( const auto name = seed->GetConnectionName( &aSheet ); name && !name->IsEmpty() )
61 names.insert( *name );
62 }
63
64 std::unordered_set<SCH_ITEM*> items;
65
66 for( const wxString& name : names )
67 CollectNetItems( name, aSheet, items );
68
69 return { items.begin(), items.end() };
70}
71
72
73std::vector<wxString> NAVIGATION_QUERY::SignalNames( const wxString& aName ) const
74{
75 if( !m_schematic.IsValid() )
76 return {};
77
78 std::set<wxString> names;
79
80 for( const CONNECTION_SUBGRAPH* subgraph : m_schematic.ConnectionGraph()->GetAllSubgraphs( aName ) )
81 {
82 const SCH_CONNECTION* connection = subgraph->GetDriverConnection();
83
84 if( !connection )
85 continue;
86
87 if( connection->IsNet() )
88 names.insert( connection->Name() );
89
90 for( const auto& member : connection->AllMembers() )
91 {
92 if( member && member->IsNet() )
93 names.insert( member->Name() );
94 }
95 }
96
97 names.erase( wxString() );
98 return { names.begin(), names.end() };
99}
100
101
102std::set<const CONNECTION_SUBGRAPH*> NAVIGATION_QUERY::netSubgraphs( const wxString& aName,
103 bool aIncludeBusParents,
104 bool aIncludeBusMembers ) const
105{
106 if( !m_schematic.IsValid() )
107 return {};
108
109 const auto& graph = *m_schematic.ConnectionGraph();
110 std::set<const CONNECTION_SUBGRAPH*> subgraphs;
111 std::vector<const CONNECTION_SUBGRAPH*> pending;
112 auto add = [&]( const wxString& name )
113 {
114 for( const CONNECTION_SUBGRAPH* subgraph : graph.GetAllSubgraphs( name ) )
115 {
116 if( subgraph && subgraphs.insert( subgraph ).second )
117 pending.push_back( subgraph );
118 }
119 };
120 add( aName );
121
122 if( aIncludeBusMembers )
123 {
124 for( const wxString& member : SignalNames( aName ) )
125 add( member );
126 }
127
128 if( aIncludeBusParents )
129 {
130 for( const wxString& equivalent : graph.GetEquivalentBusNames( aName ) )
131 add( equivalent );
132
133 for( size_t i = 0; i < pending.size(); ++i )
134 {
135 for( const auto& [member, parents] : pending[i]->GetBusParents() )
136 {
137 for( const CONNECTION_SUBGRAPH* parent : parents )
138 {
139 if( parent )
140 add( parent->GetNetName() );
141 }
142 }
143 }
144 }
145
146 std::erase_if( subgraphs,
147 []( const CONNECTION_SUBGRAPH* subgraph )
148 {
149 return !subgraph->GetSheet().LastScreen() || subgraph->GetItems().empty();
150 } );
151
152 return subgraphs;
153}
154
155
156bool NAVIGATION_QUERY::HasNet( const wxString& aName ) const
157{
158 return !netSubgraphs( aName, false, false ).empty();
159}
160
161
162std::set<KIID_PATH> NAVIGATION_QUERY::NetSheets( const wxString& aName ) const
163{
164 std::set<KIID_PATH> sheets;
165
166 for( const CONNECTION_SUBGRAPH* subgraph : netSubgraphs( aName, false, false ) )
167 sheets.insert( subgraph->GetSheet().PathRef() );
168
169 return sheets;
170}
171
172
173NET_ITEMS_BY_SHEET NAVIGATION_QUERY::NetItems( const wxString& aName, bool aIncludeBusParents,
174 bool aIncludeBusMembers ) const
175{
177
178 for( const CONNECTION_SUBGRAPH* subgraph : netSubgraphs( aName, aIncludeBusParents, aIncludeBusMembers ) )
179 {
180 auto& items = result[subgraph->GetSheet()];
181 items.insert( items.end(), subgraph->GetItems().begin(), subgraph->GetItems().end() );
182 }
183
184 for( auto& [path, items] : result )
185 {
186 std::ranges::sort( items, std::less<>{}, &SCH_ITEM::m_Uuid );
187 items.erase( std::unique( items.begin(), items.end() ), items.end() );
188 }
189
190 return result;
191}
192
193
194void NAVIGATION_QUERY::CollectNetItems( const wxString& aName, const SCH_SHEET_PATH& aSheet,
195 std::unordered_set<SCH_ITEM*>& aItems, bool aIncludeBusParents,
196 bool aIncludeBusMembers ) const
197{
198 for( const CONNECTION_SUBGRAPH* subgraph : netSubgraphs( aName, aIncludeBusParents, aIncludeBusMembers ) )
199 {
200 if( subgraph->GetSheet() == aSheet )
201 aItems.insert( subgraph->GetItems().begin(), subgraph->GetItems().end() );
202 }
203}
204}
const char * name
A subgraph is a set of items that are electrically connected on a single sheet.
const std::set< SCH_ITEM * > & GetItems() const
Provide a read-only reference to the items in the subgraph.
const SCH_SHEET_PATH & GetSheet() const
const KIID m_Uuid
Definition eda_item.h:597
Holds all the data relating to one schematic.
Definition schematic.h:148
Each graphical item can have a SCH_CONNECTION describing its logical connection (to a bus or net).
bool IsNet() const
const std::vector< std::shared_ptr< SCH_CONNECTION > > AllMembers() const
wxString Name(bool aIgnoreSheet=false) const
void CollectNetItems(const wxString &aName, const SCH_SHEET_PATH &aSheet, std::unordered_set< SCH_ITEM * > &aItems, bool aIncludeBusParents=false, bool aIncludeBusMembers=false) const
Add the items of a net on one sheet to aItems without building other sheets.
bool HasNet(const wxString &aName) const
std::vector< wxString > SignalNames(const wxString &aName) const
Signal itself or leaf signals of a bus, suitable for PCB cross-probing.
std::set< const CONNECTION_SUBGRAPH * > netSubgraphs(const wxString &aName, bool aIncludeBusParents, bool aIncludeBusMembers) const
NET_ITEMS_BY_SHEET NetItems(const wxString &aName, bool aIncludeBusParents, bool aIncludeBusMembers=false) const
NAVIGATION_QUERY(const SCHEMATIC &aSchematic)
std::vector< SCH_ITEM * > WholeNetItems(const std::vector< SCH_ITEM * > &aSeeds, const SCH_SHEET_PATH &aSheet) const
Whole nets containing the seeds on this instance; excludes bus parents and members.
std::set< KIID_PATH > NetSheets(const wxString &aName) const
std::vector< wxString > NetNames() const
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition sch_item.h:165
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
SCH_SCREEN * LastScreen()
bool equivalent(SIM_MODEL::DEVICE_T a, SIM_MODEL::DEVICE_T b)
std::map< SCH_SHEET_PATH, std::vector< SCH_ITEM * >, SHEET_PATH_CMP > NET_ITEMS_BY_SHEET
std::string path
wxString result
Test unit parsing edge cases and error handling.