55 for(
const std::shared_ptr<CN_ANCHOR>& node :
m_nodes )
56 node->SetTag( tag++ );
62 size_t candidateCount = 0;
64 for(
size_t ii = 0; ii < aEdges.size(); ++ii )
66 const std::shared_ptr<const CN_ANCHOR>& source = aEdges[ii].GetSourceNode();
67 const std::shared_ptr<const CN_ANCHOR>& target = aEdges[ii].GetTargetNode();
69 wxCHECK2( source && !source->Dirty() && target && !target->Dirty(),
continue );
71 if( aEdges[ii].GetWeight() > 0 )
73 if( candidateCount != ii )
74 aEdges[candidateCount] = std::move( aEdges[ii] );
80 forest.
Unite( source->GetTag(), target->GetTag() );
87 return std::pair<size_t, size_t>( aEdge.GetSourceNode()->GetTag(),
88 aEdge.GetTargetNode()->GetTag() );
96 const std::shared_ptr<const CN_ANCHOR>& source = aEdge.GetSourceNode();
97 const std::shared_ptr<const CN_ANCHOR>& target = aEdge.GetTargetNode();
99 std::tuple<int, int, int> first( source->Pos().x, source->Pos().y,
101 std::tuple<int, int, int> second( target->Pos().x, target->Pos().y,
105 std::swap( first, second );
107 return std::tuple_cat( std::tuple( aEdge.GetWeight() ), first, second );
113 return orderKey( aLhs ) < orderKey( aRhs );
122 m_rnEdges.push_back( aEdge );
342 auto optimizeZoneAnchor =
344 const std::shared_ptr<const CN_ANCHOR>& aAnchor,
345 const std::function<void( std::shared_ptr<const CN_ANCHOR> )>& setOptimizedTo )
347 SEG::ecoord closest_dist_sq = ( aAnchor->Pos() - aPos ).SquaredEuclideanNorm();
349 CN_ITEM* closest_item =
nullptr;
354 if( aAnchor->Item()->Net() != item->Net() )
359 if( zoneLayer && aLayerSet.test( zoneLayer->
GetBoardLayer() ) )
365 SEG::ecoord dist_sq = ( pt - aPos ).SquaredEuclideanNorm();
367 if( dist_sq < closest_dist_sq )
370 closest_item = zoneLayer;
371 closest_dist_sq = dist_sq;
378 setOptimizedTo( std::make_shared<CN_ANCHOR>( closest_pt, closest_item ) );
381 auto optimizeZoneToZoneAnchors =
382 [&](
const std::shared_ptr<const CN_ANCHOR>& a,
383 const std::shared_ptr<const CN_ANCHOR>& b,
384 const std::function<void(
const std::shared_ptr<const CN_ANCHOR>& )>&
386 const std::function<void(
const std::shared_ptr<const CN_ANCHOR>& )>&
397 DIST_PAIR( int64_t aDistSq,
size_t aIdA,
size_t aIdB )
398 : dist_sq( aDistSq ), idA( aIdA ), idB( aIdB )
406 const std::vector<CN_ITEM*>& connectedItemsA = a->Item()->ConnectedItems();
407 const std::vector<CN_ITEM*>& connectedItemsB = b->Item()->ConnectedItems();
409 std::vector<CENTER> centersA( connectedItemsA.size() );
410 std::vector<CENTER> centersB( connectedItemsB.size() );
412 for(
size_t i = 0; i < connectedItemsA.size(); i++ )
414 CN_ITEM* itemA = connectedItemsA[i];
422 centersA[i].valid =
true;
425 for(
size_t i = 0; i < connectedItemsB.size(); i++ )
427 CN_ITEM* itemB = connectedItemsB[i];
435 centersB[i].valid =
true;
438 std::vector<DIST_PAIR> pairsToTest;
440 for(
size_t ia = 0; ia < centersA.size(); ia++ )
442 for(
size_t ib = 0; ib < centersB.size(); ib++ )
444 const CENTER& ca = centersA[ia];
445 const CENTER& cb = centersB[ib];
447 if( !ca.valid || !cb.valid )
453 int64_t dist_sq = ( pB - pA ).SquaredEuclideanNorm();
454 pairsToTest.emplace_back( dist_sq, ia, ib );
458 std::sort( pairsToTest.begin(), pairsToTest.end(),
459 [](
const DIST_PAIR& dp_a,
const DIST_PAIR& dp_b )
461 return dp_a.dist_sq < dp_b.dist_sq;
464 const int c_polyPairsLimit = 3;
466 for(
size_t i = 0; i < pairsToTest.size() && i < c_polyPairsLimit; i++ )
468 const DIST_PAIR& pair = pairsToTest[i];
473 if( zoneLayerA == zoneLayerB )
484 setOptimizedATo( std::make_shared<CN_ANCHOR>( ptA, zoneLayerA ) );
485 setOptimizedBTo( std::make_shared<CN_ANCHOR>( ptB, zoneLayerB ) );
492 const std::shared_ptr<const CN_ANCHOR>& source = edge.GetSourceNode();
493 const std::shared_ptr<const CN_ANCHOR>& target = edge.GetTargetNode();
495 wxCHECK2( source && !source->Dirty() && target && !target->Dirty(),
continue );
497 if( source->ConnectedItemsCount() == 0 )
499 optimizeZoneAnchor( source->Pos(), source->Parent()->GetLayerSet(), target,
500 [&](
const std::shared_ptr<const CN_ANCHOR>& optimized )
502 edge.SetTargetNode( optimized );
505 else if( target->ConnectedItemsCount() == 0 )
507 optimizeZoneAnchor( target->Pos(), target->Parent()->GetLayerSet(), source,
508 [&](
const std::shared_ptr<const CN_ANCHOR>& optimized )
510 edge.SetSourceNode( optimized );
515 optimizeZoneToZoneAnchors( source, target,
516 [&](
const std::shared_ptr<const CN_ANCHOR>& optimized )
518 edge.SetSourceNode( optimized );
520 [&](
const std::shared_ptr<const CN_ANCHOR>& optimized )
522 edge.SetTargetNode( optimized );
568 std::shared_ptr<CN_ANCHOR> firstAnchor;
570 for(
CN_ITEM* item : *aCluster )
572 std::vector<std::shared_ptr<CN_ANCHOR>>& anchors = item->Anchors();
573 unsigned int nAnchors =
dynamic_cast<CN_ZONE_LAYER*
>( item ) ? 1 : anchors.size();
575 if( nAnchors > anchors.size() )
576 nAnchors = anchors.size();
578 for(
unsigned int i = 0; i < nAnchors; i++ )
580 anchors[i]->SetCluster( aCluster );
585 if( firstAnchor != anchors[i] )
586 m_boardEdges.emplace_back( firstAnchor, anchors[i], 0 );
590 firstAnchor = anchors[i];
604 [&](
const std::shared_ptr<CN_ANCHOR>& aTestNode1,
605 const std::shared_ptr<CN_ANCHOR>& aTestNode2 )
607 VECTOR2I diff = aTestNode1->Pos() - aTestNode2->Pos();
610 if( dist_sq < distMax_sq )
613 distMax_sq = dist_sq;
614 aPos1 = aTestNode1->Pos();
615 aPos2 = aTestNode2->Pos();
622 for(
const std::shared_ptr<CN_ANCHOR>& nodeA : aOtherNet->
m_nodes )
625 if( nodeA->GetNoLine() )
631 auto fwd_it =
m_nodes.lower_bound( nodeA );
632 auto rev_it = std::make_reverse_iterator( fwd_it );
634 for( ; fwd_it !=
m_nodes.end(); ++fwd_it )
636 const std::shared_ptr<CN_ANCHOR>& nodeB = *fwd_it;
638 if( nodeB->GetNoLine() )
645 if( distX_sq > distMax_sq )
648 verify( nodeA, nodeB );
652 for( ; rev_it !=
m_nodes.rend(); ++rev_it )
654 const std::shared_ptr<CN_ANCHOR>& nodeB = *rev_it;
656 if( nodeB->GetNoLine() )
661 if( distX_sq > distMax_sq )
664 verify( nodeA, nodeB );