354 auto optimizeZoneAnchor =
356 const std::shared_ptr<const CN_ANCHOR>& aAnchor,
357 const std::function<void( std::shared_ptr<const CN_ANCHOR> )>& setOptimizedTo )
359 SEG::ecoord closest_dist_sq = ( aAnchor->Pos() - aPos ).SquaredEuclideanNorm();
361 CN_ITEM* closest_item =
nullptr;
366 if( aAnchor->Item()->Net() != item->Net() )
371 if( zoneLayer && aLayerSet.test( zoneLayer->
GetBoardLayer() ) )
377 SEG::ecoord dist_sq = ( pt - aPos ).SquaredEuclideanNorm();
379 if( dist_sq < closest_dist_sq )
382 closest_item = zoneLayer;
383 closest_dist_sq = dist_sq;
390 setOptimizedTo( std::make_shared<CN_ANCHOR>( closest_pt, closest_item ) );
393 auto optimizeZoneToZoneAnchors =
394 [&](
const std::shared_ptr<const CN_ANCHOR>& a,
395 const std::shared_ptr<const CN_ANCHOR>& b,
396 const std::function<void(
const std::shared_ptr<const CN_ANCHOR>& )>&
398 const std::function<void(
const std::shared_ptr<const CN_ANCHOR>& )>&
409 DIST_PAIR( int64_t aDistSq,
size_t aIdA,
size_t aIdB )
410 : dist_sq( aDistSq ), idA( aIdA ), idB( aIdB )
418 const std::vector<CN_ITEM*>& connectedItemsA = a->Item()->ConnectedItems();
419 const std::vector<CN_ITEM*>& connectedItemsB = b->Item()->ConnectedItems();
421 std::vector<CENTER> centersA( connectedItemsA.size() );
422 std::vector<CENTER> centersB( connectedItemsB.size() );
424 for(
size_t i = 0; i < connectedItemsA.size(); i++ )
426 CN_ITEM* itemA = connectedItemsA[i];
434 centersA[i].valid =
true;
437 for(
size_t i = 0; i < connectedItemsB.size(); i++ )
439 CN_ITEM* itemB = connectedItemsB[i];
447 centersB[i].valid =
true;
450 std::vector<DIST_PAIR> pairsToTest;
452 for(
size_t ia = 0; ia < centersA.size(); ia++ )
454 for(
size_t ib = 0; ib < centersB.size(); ib++ )
456 const CENTER& ca = centersA[ia];
457 const CENTER& cb = centersB[ib];
459 if( !ca.valid || !cb.valid )
465 int64_t dist_sq = ( pB - pA ).SquaredEuclideanNorm();
466 pairsToTest.emplace_back( dist_sq, ia, ib );
470 std::sort( pairsToTest.begin(), pairsToTest.end(),
471 [](
const DIST_PAIR& dp_a,
const DIST_PAIR& dp_b )
473 return dp_a.dist_sq < dp_b.dist_sq;
476 const int c_polyPairsLimit = 3;
478 for(
size_t i = 0; i < pairsToTest.size() && i < c_polyPairsLimit; i++ )
480 const DIST_PAIR& pair = pairsToTest[i];
485 if( zoneLayerA == zoneLayerB )
496 setOptimizedATo( std::make_shared<CN_ANCHOR>( ptA, zoneLayerA ) );
497 setOptimizedBTo( std::make_shared<CN_ANCHOR>( ptB, zoneLayerB ) );
504 const std::shared_ptr<const CN_ANCHOR>& source = edge.GetSourceNode();
505 const std::shared_ptr<const CN_ANCHOR>& target = edge.GetTargetNode();
507 wxCHECK2( source && !source->Dirty() && target && !target->Dirty(),
continue );
509 if( source->ConnectedItemsCount() == 0 )
511 optimizeZoneAnchor( source->Pos(), source->Parent()->GetLayerSet(), target,
512 [&](
const std::shared_ptr<const CN_ANCHOR>& optimized )
514 edge.SetTargetNode( optimized );
517 else if( target->ConnectedItemsCount() == 0 )
519 optimizeZoneAnchor( target->Pos(), target->Parent()->GetLayerSet(), source,
520 [&](
const std::shared_ptr<const CN_ANCHOR>& optimized )
522 edge.SetSourceNode( optimized );
527 optimizeZoneToZoneAnchors( source, target,
528 [&](
const std::shared_ptr<const CN_ANCHOR>& optimized )
530 edge.SetSourceNode( optimized );
532 [&](
const std::shared_ptr<const CN_ANCHOR>& optimized )
534 edge.SetTargetNode( optimized );
580 std::shared_ptr<CN_ANCHOR> firstAnchor;
582 for(
CN_ITEM* item : *aCluster )
584 std::vector<std::shared_ptr<CN_ANCHOR>>& anchors = item->Anchors();
585 unsigned int nAnchors =
dynamic_cast<CN_ZONE_LAYER*
>( item ) ? 1 : anchors.size();
587 if( nAnchors > anchors.size() )
588 nAnchors = anchors.size();
590 for(
unsigned int i = 0; i < nAnchors; i++ )
592 anchors[i]->SetCluster( aCluster );
597 if( firstAnchor != anchors[i] )
598 m_boardEdges.emplace_back( firstAnchor, anchors[i], 0 );
602 firstAnchor = anchors[i];
616 [&](
const std::shared_ptr<CN_ANCHOR>& aTestNode1,
617 const std::shared_ptr<CN_ANCHOR>& aTestNode2 )
619 VECTOR2I diff = aTestNode1->Pos() - aTestNode2->Pos();
622 if( dist_sq < distMax_sq )
625 distMax_sq = dist_sq;
626 aPos1 = aTestNode1->Pos();
627 aPos2 = aTestNode2->Pos();
634 for(
const std::shared_ptr<CN_ANCHOR>& nodeA : aOtherNet->
m_nodes )
637 if( nodeA->GetNoLine() )
643 auto fwd_it =
m_nodes.lower_bound( nodeA );
644 auto rev_it = std::make_reverse_iterator( fwd_it );
646 for( ; fwd_it !=
m_nodes.end(); ++fwd_it )
648 const std::shared_ptr<CN_ANCHOR>& nodeB = *fwd_it;
650 if( nodeB->GetNoLine() )
657 if( distX_sq > distMax_sq )
660 verify( nodeA, nodeB );
664 for( ; rev_it !=
m_nodes.rend(); ++rev_it )
666 const std::shared_ptr<CN_ANCHOR>& nodeB = *rev_it;
668 if( nodeB->GetNoLine() )
673 if( distX_sq > distMax_sq )
676 verify( nodeA, nodeB );