353 auto optimizeZoneAnchor =
355 const std::shared_ptr<const CN_ANCHOR>& aAnchor,
356 const std::function<void( std::shared_ptr<const CN_ANCHOR> )>& setOptimizedTo )
358 SEG::ecoord closest_dist_sq = ( aAnchor->Pos() - aPos ).SquaredEuclideanNorm();
360 CN_ITEM* closest_item =
nullptr;
365 if( aAnchor->Item()->Net() != item->Net() )
370 if( zoneLayer && aLayerSet.test( zoneLayer->
GetBoardLayer() ) )
376 SEG::ecoord dist_sq = ( pt - aPos ).SquaredEuclideanNorm();
378 if( dist_sq < closest_dist_sq )
381 closest_item = zoneLayer;
382 closest_dist_sq = dist_sq;
389 setOptimizedTo( std::make_shared<CN_ANCHOR>( closest_pt, closest_item ) );
392 auto optimizeZoneToZoneAnchors =
393 [&](
const std::shared_ptr<const CN_ANCHOR>& a,
394 const std::shared_ptr<const CN_ANCHOR>& b,
395 const std::function<void(
const std::shared_ptr<const CN_ANCHOR>& )>&
397 const std::function<void(
const std::shared_ptr<const CN_ANCHOR>& )>&
408 DIST_PAIR( int64_t aDistSq,
size_t aIdA,
size_t aIdB )
409 : dist_sq( aDistSq ), idA( aIdA ), idB( aIdB )
417 const std::vector<CN_ITEM*>& connectedItemsA = a->Item()->ConnectedItems();
418 const std::vector<CN_ITEM*>& connectedItemsB = b->Item()->ConnectedItems();
420 std::vector<CENTER> centersA( connectedItemsA.size() );
421 std::vector<CENTER> centersB( connectedItemsB.size() );
423 for(
size_t i = 0; i < connectedItemsA.size(); i++ )
425 CN_ITEM* itemA = connectedItemsA[i];
433 centersA[i].valid =
true;
436 for(
size_t i = 0; i < connectedItemsB.size(); i++ )
438 CN_ITEM* itemB = connectedItemsB[i];
446 centersB[i].valid =
true;
449 std::vector<DIST_PAIR> pairsToTest;
451 for(
size_t ia = 0; ia < centersA.size(); ia++ )
453 for(
size_t ib = 0; ib < centersB.size(); ib++ )
455 const CENTER& ca = centersA[ia];
456 const CENTER& cb = centersB[ib];
458 if( !ca.valid || !cb.valid )
464 int64_t dist_sq = ( pB - pA ).SquaredEuclideanNorm();
465 pairsToTest.emplace_back( dist_sq, ia, ib );
469 std::sort( pairsToTest.begin(), pairsToTest.end(),
470 [](
const DIST_PAIR& dp_a,
const DIST_PAIR& dp_b )
472 return dp_a.dist_sq < dp_b.dist_sq;
475 const int c_polyPairsLimit = 3;
477 for(
size_t i = 0; i < pairsToTest.size() && i < c_polyPairsLimit; i++ )
479 const DIST_PAIR& pair = pairsToTest[i];
484 if( zoneLayerA == zoneLayerB )
495 setOptimizedATo( std::make_shared<CN_ANCHOR>( ptA, zoneLayerA ) );
496 setOptimizedBTo( std::make_shared<CN_ANCHOR>( ptB, zoneLayerB ) );
503 const std::shared_ptr<const CN_ANCHOR>& source = edge.GetSourceNode();
504 const std::shared_ptr<const CN_ANCHOR>& target = edge.GetTargetNode();
506 wxCHECK2( source && !source->Dirty() && target && !target->Dirty(),
continue );
508 if( source->ConnectedItemsCount() == 0 )
510 optimizeZoneAnchor( source->Pos(), source->Parent()->GetLayerSet(), target,
511 [&](
const std::shared_ptr<const CN_ANCHOR>& optimized )
513 edge.SetTargetNode( optimized );
516 else if( target->ConnectedItemsCount() == 0 )
518 optimizeZoneAnchor( target->Pos(), target->Parent()->GetLayerSet(), source,
519 [&](
const std::shared_ptr<const CN_ANCHOR>& optimized )
521 edge.SetSourceNode( optimized );
526 optimizeZoneToZoneAnchors( source, target,
527 [&](
const std::shared_ptr<const CN_ANCHOR>& optimized )
529 edge.SetSourceNode( optimized );
531 [&](
const std::shared_ptr<const CN_ANCHOR>& optimized )
533 edge.SetTargetNode( optimized );
579 std::shared_ptr<CN_ANCHOR> firstAnchor;
581 for(
CN_ITEM* item : *aCluster )
583 std::vector<std::shared_ptr<CN_ANCHOR>>& anchors = item->Anchors();
584 unsigned int nAnchors =
dynamic_cast<CN_ZONE_LAYER*
>( item ) ? 1 : anchors.size();
586 if( nAnchors > anchors.size() )
587 nAnchors = anchors.size();
589 for(
unsigned int i = 0; i < nAnchors; i++ )
591 anchors[i]->SetCluster( aCluster );
596 if( firstAnchor != anchors[i] )
597 m_boardEdges.emplace_back( firstAnchor, anchors[i], 0 );
601 firstAnchor = anchors[i];
615 [&](
const std::shared_ptr<CN_ANCHOR>& aTestNode1,
616 const std::shared_ptr<CN_ANCHOR>& aTestNode2 )
618 VECTOR2I diff = aTestNode1->Pos() - aTestNode2->Pos();
621 if( dist_sq < distMax_sq )
624 distMax_sq = dist_sq;
625 aPos1 = aTestNode1->Pos();
626 aPos2 = aTestNode2->Pos();
633 for(
const std::shared_ptr<CN_ANCHOR>& nodeA : aOtherNet->
m_nodes )
636 if( nodeA->GetNoLine() )
642 auto fwd_it =
m_nodes.lower_bound( nodeA );
643 auto rev_it = std::make_reverse_iterator( fwd_it );
645 for( ; fwd_it !=
m_nodes.end(); ++fwd_it )
647 const std::shared_ptr<CN_ANCHOR>& nodeB = *fwd_it;
649 if( nodeB->GetNoLine() )
656 if( distX_sq > distMax_sq )
659 verify( nodeA, nodeB );
663 for( ; rev_it !=
m_nodes.rend(); ++rev_it )
665 const std::shared_ptr<CN_ANCHOR>& nodeB = *rev_it;
667 if( nodeB->GetNoLine() )
672 if( distX_sq > distMax_sq )
675 verify( nodeA, nodeB );