53 wxLogTrace(
traceTopoMatch, wxT(
"[conns mismatch n1 %d n2 %d c-ref %d c-other %d thispin %s-%s otherpin %s-%s"),
65 wxLogTrace(
traceTopoMatch, wxT(
"%s-%s "), c->m_parent->m_reference, c->m_ref );
72 wxLogTrace(
traceTopoMatch, wxT(
"%s-%s "), c->m_parent->m_reference, c->m_ref );
86 std::vector<bool> matches(
m_conns.size() );
88 for(
int i = 0; i <
m_conns.size(); i++ )
96 for(
int i = 0; i <
m_conns.size(); i++ )
98 if( b.
m_conns[i]->IsTopologicallySimilar( *cref ) )
101 matches[nref] =
true;
109 for(
int i = 0; i <
m_conns.size(); i++ )
123 std::map<PIN*, PIN*> pairs;
124 std::vector<PIN*> pref, ptgt;
129 for(
PIN* p : m.second->Pins() )
134 for(
PIN* p : m.first->Pins() )
150 if( pref.size() != ptgt.size() )
155 for(
unsigned int i = 0; i < pref.size(); i++ )
157 pairs[pref[i]] = ptgt[i];
160 for(
PIN* refPin : aRef->
Pins() )
164 std::optional<int> prevNet;
168 for(
PIN* ppin : refCmp->Pins() )
170 if ( ppin->GetNetCode() != refPin->GetNetCode() )
173 wxLogTrace(
traceTopoMatch, wxT(
"{ref %s-%s:%d} "), ppin->GetParent()->GetParent()->GetReferenceAsString(), ppin->GetReference(), ppin->GetNetCode() );
175 auto tpin = pairs.find( ppin );
177 if( tpin != pairs.end() )
179 int nc = tpin->second->GetNetCode();
183 if( prevNet && ( *prevNet != nc ) )
199std::vector<COMPONENT*>
202 std::vector<COMPONENT*> matches;
206 if( partialMatches.
m_locked.find( cmpTarget ) != partialMatches.
m_locked.end() )
220 matches.push_back( cmpTarget );
224 wxLogTrace(
traceTopoMatch, wxT(
"Reject [net topo mismatch]\n") );
235 for(
int i=0;i<a->
m_pins.size();i++)
238 PIN* pb = b->m_pins[i];
242 return (
double)n / (double) a->
m_pins.size();
248 return padSimilarity( aRef,a ) > padSimilarity( aRef, b );
260 return a->GetReference() < b->GetReference();
266 std::map<int, std::vector<PIN*>> nets;
274 for(
auto p : c->Pins() )
276 if( p->GetNetCode() > 0 )
277 nets[p->GetNetCode()].push_back( p );
281 for(
auto iter : nets )
283 wxLogTrace(
traceTopoMatch, wxT(
"net %d: %d connections\n"), iter.first, (
int) iter.second.size() );
284 for(
auto p : iter.second )
286 for(
auto p2 : iter.second )
289 p->m_conns.push_back( p2 );
310 std::vector<BACKTRACK_STAGE> stack;
322 stack.push_back( top );
324 bool matchFound =
false;
326 while( !stack.empty() )
329 auto& current = stack.back();
331 for(
auto it = current.m_locked.begin(); it != current.m_locked.end(); it++ )
333 if (it->second == current.m_ref)
335 wxLogTrace(
traceTopoMatch, wxT(
"stk: Remove %s from locked\n"), current.m_ref->m_reference );
336 current.m_locked.erase( it );
347 if( current.m_currentMatch < 0 )
350 current.m_currentMatch = 0;
353 wxLogTrace(
traceTopoMatch, wxT(
"stk: Current '%s' stack %d cm %d/%d locked %d/%d\n" ),
354 current.m_ref->m_reference, (
int) stack.size(),
355 current.m_currentMatch, (
int) current.m_matches.size(),
356 (
int) current.m_locked.size(), (
int)
m_components.size() );
358 if ( current.m_matches.empty() )
360 wxLogTrace(
traceTopoMatch, wxT(
"stk: No matches at all, going up [level=%d]\n"), (
int) stack.size() );
365 if( current.m_currentMatch >= 0 && current.m_currentMatch >= current.m_matches.size() )
367 wxLogTrace(
traceTopoMatch, wxT(
"stk: No more matches, going up [level=%d]\n"), (
int) stack.size() );
372 auto& match = current.m_matches[current.m_currentMatch];
374 wxLogTrace(
traceTopoMatch, wxT(
"stk: candidate '%s', match list : ( "),
375 current.m_matches[current.m_currentMatch]->m_reference,
376 current.m_refIndex );
378 for(
auto m : current.m_matches )
379 wxLogTrace(
traceTopoMatch, wxT(
"%s "), m->GetParent()->GetReferenceAsString() );
385 current.m_currentMatch++;
386 current.m_locked[match] = current.m_ref;
391 current.m_nloops = nloops;
395 for(
auto iter : current.m_locked )
396 aResult[ iter.second->GetParent() ] = iter.first->GetParent();
402 int minMatches = std::numeric_limits<int>::max();
412 if( cmp == current.m_ref )
417 for(
auto it = current.m_locked.begin(); it != current.m_locked.end(); it++ )
419 if( it->second == cmp )
431 int nMatches = matches.size();
438 else if( nMatches == 0 )
443 else if( nMatches < minMatches )
445 minMatches = nMatches;
452 next.m_currentMatch = -1;
456 next.m_ref = bestNextRef;
457 next.m_refIndex = bestRefIndex;
461 next.m_ref = altNextRef;
462 next.m_refIndex = altRefIndex;
465 stack.push_back(
next );
475 FILE * f = fopen(
"connectivity.dump",
"rb" );
476 auto cgRef = loadCGraph(f);
477 auto cgTarget = loadCGraph(f);
479 cgRef->buildConnectivity();
480 cgTarget->buildConnectivity();
490 const BacktrackStage latest = cgRef->matchCGraphs( cgTarget );
492 if( !latest.locked.size() )
494 printf(
"MATCH FAIL\n");
510 if( latest.nloops > max_loops )
512 max_loops = latest.nloops;
515 if (attempts % 10000 == 0)
517 printf(
"attempts: %d maxloops: %d\n", attempts, max_loops );
532 m_reference( aRef ), m_parentFootprint( aParentFp ), m_raOffset( aRaOffset )
581 pin->m_netcode =
pad->GetNetCode();
582 pin->m_ref =
pad->GetNumber();
591 auto cgraph = std::make_unique<CONNECTION_GRAPH>();
594 if( aFps.size() > 0 )
595 ref = (*aFps.begin())->GetPosition();
597 for(
auto fp : aFps )
599 cgraph->AddFootprint( fp, fp->GetPosition() - ref );
602 cgraph->BuildConnectivity();
604 return std::move(cgraph);
const std::map< COMPONENT *, COMPONENT * > & GetMatchingComponentPairs() const
std::map< COMPONENT *, COMPONENT * > m_locked
bool MatchesWith(COMPONENT *b)
bool IsSameKind(const COMPONENT &b) const
COMPONENT(const wxString &aRef, FOOTPRINT *aParentFp, std::optional< VECTOR2I > aRaOffset=std::optional< VECTOR2I >())
FOOTPRINT * m_parentFootprint
std::vector< PIN * > & Pins()
std::vector< PIN * > m_pins
FOOTPRINT * GetParent() const
STATUS FindIsomorphism(CONNECTION_GRAPH *target, COMPONENT_MATCHES &result)
std::vector< COMPONENT * > findMatchingComponents(CONNECTION_GRAPH *aRefGraph, COMPONENT *ref, const BACKTRACK_STAGE &partialMatches)
std::vector< COMPONENT * > & Components()
@ ST_COMPONENT_COUNT_MISMATCH
@ ST_ITERATION_COUNT_EXCEEDED
std::vector< COMPONENT * > m_components
void AddFootprint(FOOTPRINT *aFp, const VECTOR2I &aOffset)
static std::unique_ptr< CONNECTION_GRAPH > BuildFromFootprintSet(const std::set< FOOTPRINT * > &aFps)
std::vector< PIN * > m_conns
void SetParent(COMPONENT *parent)
bool IsIsomorphic(const PIN &b) const
std::map< FOOTPRINT *, FOOTPRINT * > COMPONENT_MATCHES
bool checkIfPadNetsMatch(const BACKTRACK_STAGE &aMatches, CONNECTION_GRAPH *aRefGraph, COMPONENT *aRef, COMPONENT *aTgt)
wxString GetRefDesPrefix(const wxString &aRefDes)
Get the (non-numeric) prefix from a refdes - e.g.
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
Collection of utility functions for component reference designators (refdes)
static const wxString traceTopoMatch