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 );