350 auto optimizeZoneAnchor =
352 const std::shared_ptr<const CN_ANCHOR>& aAnchor,
353 const std::function<void( std::shared_ptr<const CN_ANCHOR> )>& setOptimizedTo )
355 SEG::ecoord closest_dist_sq = ( aAnchor->Pos() - aPos ).SquaredEuclideanNorm();
357 CN_ITEM* closest_item =
nullptr;
362 if( aAnchor->Item()->Net() != item->Net() )
367 if( zoneLayer && aLayerSet.test( zoneLayer->
GetBoardLayer() ) )
373 SEG::ecoord dist_sq = ( pt - aPos ).SquaredEuclideanNorm();
375 if( dist_sq < closest_dist_sq )
378 closest_item = zoneLayer;
379 closest_dist_sq = dist_sq;
386 setOptimizedTo( std::make_shared<CN_ANCHOR>( closest_pt, closest_item ) );
389 auto optimizeZoneToZoneAnchors =
390 [&](
const std::shared_ptr<const CN_ANCHOR>& a,
391 const std::shared_ptr<const CN_ANCHOR>& b,
392 const std::function<void(
const std::shared_ptr<const CN_ANCHOR>& )>&
394 const std::function<void(
const std::shared_ptr<const CN_ANCHOR>& )>&
405 DIST_PAIR( int64_t aDistSq,
size_t aIdA,
size_t aIdB )
406 : dist_sq( aDistSq ), idA( aIdA ), idB( aIdB )
414 const std::vector<CN_ITEM*>& connectedItemsA = a->Item()->ConnectedItems();
415 const std::vector<CN_ITEM*>& connectedItemsB = b->Item()->ConnectedItems();
417 std::vector<CENTER> centersA( connectedItemsA.size() );
418 std::vector<CENTER> centersB( connectedItemsB.size() );
420 for(
size_t i = 0; i < connectedItemsA.size(); i++ )
422 CN_ITEM* itemA = connectedItemsA[i];
430 centersA[i].valid =
true;
433 for(
size_t i = 0; i < connectedItemsB.size(); i++ )
435 CN_ITEM* itemB = connectedItemsB[i];
443 centersB[i].valid =
true;
446 std::vector<DIST_PAIR> pairsToTest;
448 for(
size_t ia = 0; ia < centersA.size(); ia++ )
450 for(
size_t ib = 0; ib < centersB.size(); ib++ )
452 const CENTER& ca = centersA[ia];
453 const CENTER& cb = centersB[ib];
455 if( !ca.valid || !cb.valid )
461 int64_t dist_sq = ( pB - pA ).SquaredEuclideanNorm();
462 pairsToTest.emplace_back( dist_sq, ia, ib );
466 std::sort( pairsToTest.begin(), pairsToTest.end(),
467 [](
const DIST_PAIR& dp_a,
const DIST_PAIR& dp_b )
469 return dp_a.dist_sq < dp_b.dist_sq;
472 const int c_polyPairsLimit = 3;
474 for(
size_t i = 0; i < pairsToTest.size() && i < c_polyPairsLimit; i++ )
476 const DIST_PAIR& pair = pairsToTest[i];
481 if( zoneLayerA == zoneLayerB )
492 setOptimizedATo( std::make_shared<CN_ANCHOR>( ptA, zoneLayerA ) );
493 setOptimizedBTo( std::make_shared<CN_ANCHOR>( ptB, zoneLayerB ) );
500 const std::shared_ptr<const CN_ANCHOR>& source = edge.GetSourceNode();
501 const std::shared_ptr<const CN_ANCHOR>& target = edge.GetTargetNode();
503 wxCHECK2( source && !source->Dirty() && target && !target->Dirty(),
continue );
505 if( source->ConnectedItemsCount() == 0 )
507 optimizeZoneAnchor( source->Pos(), source->Parent()->GetLayerSet(), target,
508 [&](
const std::shared_ptr<const CN_ANCHOR>& optimized )
510 edge.SetTargetNode( optimized );
513 else if( target->ConnectedItemsCount() == 0 )
515 optimizeZoneAnchor( target->Pos(), target->Parent()->GetLayerSet(), source,
516 [&](
const std::shared_ptr<const CN_ANCHOR>& optimized )
518 edge.SetSourceNode( optimized );
523 optimizeZoneToZoneAnchors( source, target,
524 [&](
const std::shared_ptr<const CN_ANCHOR>& optimized )
526 edge.SetSourceNode( optimized );
528 [&](
const std::shared_ptr<const CN_ANCHOR>& optimized )
530 edge.SetTargetNode( optimized );
576 std::shared_ptr<CN_ANCHOR> firstAnchor;
578 for(
CN_ITEM* item : *aCluster )
580 std::vector<std::shared_ptr<CN_ANCHOR>>& anchors = item->Anchors();
581 unsigned int nAnchors =
dynamic_cast<CN_ZONE_LAYER*
>( item ) ? 1 : anchors.size();
583 if( nAnchors > anchors.size() )
584 nAnchors = anchors.size();
586 for(
unsigned int i = 0; i < nAnchors; i++ )
588 anchors[i]->SetCluster( aCluster );
593 if( firstAnchor != anchors[i] )
594 m_boardEdges.emplace_back( firstAnchor, anchors[i], 0 );
598 firstAnchor = anchors[i];
612 [&](
const std::shared_ptr<CN_ANCHOR>& aTestNode1,
613 const std::shared_ptr<CN_ANCHOR>& aTestNode2 )
615 VECTOR2I diff = aTestNode1->Pos() - aTestNode2->Pos();
618 if( dist_sq < distMax_sq )
621 distMax_sq = dist_sq;
622 aPos1 = aTestNode1->Pos();
623 aPos2 = aTestNode2->Pos();
630 for(
const std::shared_ptr<CN_ANCHOR>& nodeA : aOtherNet->
m_nodes )
633 if( nodeA->GetNoLine() )
639 auto fwd_it =
m_nodes.lower_bound( nodeA );
640 auto rev_it = std::make_reverse_iterator( fwd_it );
642 for( ; fwd_it !=
m_nodes.end(); ++fwd_it )
644 const std::shared_ptr<CN_ANCHOR>& nodeB = *fwd_it;
646 if( nodeB->GetNoLine() )
653 if( distX_sq > distMax_sq )
656 verify( nodeA, nodeB );
660 for( ; rev_it !=
m_nodes.rend(); ++rev_it )
662 const std::shared_ptr<CN_ANCHOR>& nodeB = *rev_it;
664 if( nodeB->GetNoLine() )
669 if( distX_sq > distMax_sq )
672 verify( nodeA, nodeB );