54 wxT(
"[conns mismatch n1 %d n2 %d c-ref %d c-other %d thispin %s-%s "
67 wxLogTrace(
traceTopoMatch, wxT(
"%s-%s " ), c->m_parent->m_reference, c->m_ref );
74 wxLogTrace(
traceTopoMatch, wxT(
"%s-%s " ), c->m_parent->m_reference, c->m_ref );
88 std::vector<bool> matches(
m_conns.size() );
90 for(
int i = 0; i <
m_conns.size(); i++ )
97 for(
int i = 0; i <
m_conns.size(); i++ )
99 if( b.
m_conns[i]->IsTopologicallySimilar( *cref ) )
101 matches[nref] =
true;
109 for(
int i = 0; i <
m_conns.size(); i++ )
125 std::map<PIN*, PIN*> pairs;
126 std::vector<PIN*> pref, ptgt;
131 for(
PIN* p : m.second->Pins() )
136 for(
PIN* p : m.first->Pins() )
152 if( pref.size() != ptgt.size() )
157 for(
unsigned int i = 0; i < pref.size(); i++ )
159 pairs[pref[i]] = ptgt[i];
162 for(
PIN* refPin : aRef->
Pins() )
167 std::optional<int> prevNet;
171 for(
PIN* ppin : refCmp->Pins() )
173 if ( ppin->GetNetCode() != refPin->GetNetCode() )
177 ppin->GetParent()->GetParent()->GetReferenceAsString(),
178 ppin->GetReference(), ppin->GetNetCode() );
180 auto tpin = pairs.find( ppin );
182 if( tpin != pairs.end() )
184 int nc = tpin->second->GetNetCode();
186 if( prevNet && ( *prevNet != nc ) )
202std::vector<COMPONENT*>
206 std::vector<COMPONENT*> matches;
210 if( partialMatches.
m_locked.find( cmpTarget ) != partialMatches.
m_locked.end() )
216 cmpTarget->m_reference );
226 matches.push_back( cmpTarget );
230 wxLogTrace(
traceTopoMatch, wxT(
"Reject [net topo mismatch]\n") );
243 for(
int i=0;i<a->
m_pins.size();i++)
246 PIN* pb = b->m_pins[i];
252 return (
double)n / (double) a->
m_pins.size();
258 return padSimilarity( aRef,a ) > padSimilarity( aRef, b );
271 return a->GetReference() < b->GetReference();
278 std::map<int, std::vector<PIN*>> nets;
286 for(
auto p : c->Pins() )
288 if( p->GetNetCode() > 0 )
289 nets[p->GetNetCode()].push_back( p );
293 for(
auto iter : nets )
295 wxLogTrace(
traceTopoMatch, wxT(
"net %d: %d connections\n" ), iter.first,
296 (
int) iter.second.size() );
298 for(
auto p : iter.second )
300 for(
auto p2 : iter.second )
304 p->m_conns.push_back( p2 );
326 std::vector<BACKTRACK_STAGE> stack;
338 stack.push_back( top );
340 bool matchFound =
false;
343 while( !stack.empty() )
346 auto& current = stack.back();
348 for(
auto it = current.m_locked.begin(); it != current.m_locked.end(); it++ )
350 if (it->second == current.m_ref)
352 wxLogTrace(
traceTopoMatch, wxT(
"stk: Remove %s from locked\n" ),
353 current.m_ref->m_reference );
354 current.m_locked.erase( it );
365 if( current.m_currentMatch < 0 )
368 current.m_currentMatch = 0;
371 wxLogTrace(
traceTopoMatch, wxT(
"stk: Current '%s' stack %d cm %d/%d locked %d/%d\n" ),
372 current.m_ref->m_reference, (
int) stack.size(), current.m_currentMatch,
373 (
int) current.m_matches.size(), (
int) current.m_locked.size(),
376 if ( current.m_matches.empty() )
378 wxLogTrace(
traceTopoMatch, wxT(
"stk: No matches at all, going up [level=%d]\n" ),
379 (
int) stack.size() );
384 if( current.m_currentMatch >= 0 && current.m_currentMatch >= current.m_matches.size() )
386 wxLogTrace(
traceTopoMatch, wxT(
"stk: No more matches, going up [level=%d]\n" ),
387 (
int) stack.size() );
392 auto& match = current.m_matches[current.m_currentMatch];
394 wxLogTrace(
traceTopoMatch, wxT(
"stk: candidate '%s', match list : ( " ),
395 current.m_matches[current.m_currentMatch]->m_reference, current.m_refIndex );
397 for(
auto m : current.m_matches )
398 wxLogTrace(
traceTopoMatch, wxT(
"%s " ), m->GetParent()->GetReferenceAsString() );
402 current.m_currentMatch++;
403 current.m_locked[match] = current.m_ref;
407 current.m_nloops = nloops;
411 for(
auto iter : current.m_locked )
412 aResult[ iter.second->GetParent() ] = iter.first->GetParent();
418 int minMatches = std::numeric_limits<int>::max();
421 int bestRefIndex = 0;
428 if( cmp == current.m_ref )
433 for(
auto it = current.m_locked.begin(); it != current.m_locked.end(); it++ )
435 if( it->second == cmp )
447 int nMatches = matches.size();
455 else if( nMatches == 0 )
460 else if( nMatches < minMatches )
462 minMatches = nMatches;
469 next.m_currentMatch = -1;
473 next.m_ref = bestNextRef;
474 next.m_refIndex = bestRefIndex;
478 next.m_ref = altNextRef;
479 next.m_refIndex = altRefIndex;
482 stack.push_back(
next );
493 FILE * f = fopen(
"connectivity.dump",
"rb" );
494 auto cgRef = loadCGraph(f);
495 auto cgTarget = loadCGraph(f);
497 cgRef->buildConnectivity();
498 cgTarget->buildConnectivity();
508 const BacktrackStage latest = cgRef->matchCGraphs( cgTarget );
510 if( !latest.locked.size() )
512 printf(
"MATCH FAIL\n");
528 if( latest.nloops > max_loops )
530 max_loops = latest.nloops;
533 if (attempts % 10000 == 0)
535 printf(
"attempts: %d maxloops: %d\n", attempts, max_loops );
551 std::optional<VECTOR2I> aRaOffset ) :
553 m_parentFootprint( aParentFp ), m_raOffset( aRaOffset )
607 pin->m_netcode =
pad->GetNetCode();
608 pin->m_ref =
pad->GetNumber();
616std::unique_ptr<CONNECTION_GRAPH>
619 auto cgraph = std::make_unique<CONNECTION_GRAPH>();
622 if( aFps.size() > 0 )
623 ref = (*aFps.begin())->GetPosition();
625 for(
auto fp : aFps )
627 cgraph->AddFootprint( fp, fp->GetPosition() - ref );
630 cgraph->BuildConnectivity();
632 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