Exemplo n.º 1
0
void ZONE_FILLER::Fill( std::vector<ZONE_CONTAINER*> aZones )
{
    std::vector<CN_ZONE_ISOLATED_ISLAND_LIST> toFill;
    auto connectivity = m_board->GetConnectivity();

    connectivity->Lock();

    // Remove segment zones
    m_board->m_Zone.DeleteAll();

    for( auto zone : aZones )
    {
        // Keepout zones are not filled
        if( zone->GetIsKeepout() )
            continue;

        CN_ZONE_ISOLATED_ISLAND_LIST l;
        l.m_zone = zone;
        toFill.push_back( l );
    }

    for( unsigned i = 0; i < toFill.size(); i++ )
    {
        if( m_commit )
        {
            m_commit->Modify( toFill[i].m_zone );
        }
    }

    if( m_progressReporter )
    {
        m_progressReporter->Report( _( "Calculating zone fills..." ) );
        m_progressReporter->SetMaxProgress( toFill.size() );
    }


    #ifdef USE_OPENMP
        #pragma omp parallel
    #endif
    {
        #ifdef USE_OPENMP
            #pragma omp master
            if( m_progressReporter )
            {
                m_progressReporter->KeepRefreshing( true );
            }
        #endif

        #ifdef USE_OPENMP
            #pragma omp for schedule(dynamic)
        #endif
        for( unsigned i = 0; i < toFill.size(); i++ )
        {
            SHAPE_POLY_SET rawPolys, finalPolys;
            ZONE_SEGMENT_FILL segFill;
            fillSingleZone( toFill[i].m_zone, rawPolys, finalPolys );

            toFill[i].m_zone->SetRawPolysList( rawPolys );
            toFill[i].m_zone->SetFilledPolysList( finalPolys );
            toFill[i].m_zone->SetIsFilled( true );

            if( m_progressReporter )
            {
                m_progressReporter->AdvanceProgress();
            }
        }
    }

    // Now remove insulated copper islands
    if( m_progressReporter )
    {
        m_progressReporter->AdvancePhase();
        m_progressReporter->Report( _( "Removing insulated copper islands..." ) );
    }

    connectivity->SetProgressReporter( m_progressReporter );
    connectivity->FindIsolatedCopperIslands( toFill );

    for( auto& zone : toFill )
    {
        std::sort( zone.m_islands.begin(), zone.m_islands.end(), std::greater<int>() );
        SHAPE_POLY_SET poly = zone.m_zone->GetFilledPolysList();

        for( auto idx : zone.m_islands )
        {
            poly.DeletePolygon( idx );
        }

        zone.m_zone->SetFilledPolysList( poly );
    }

    if( m_progressReporter )
    {
        m_progressReporter->AdvancePhase();
        m_progressReporter->Report( _( "Caching polygon triangulations..." ) );
        m_progressReporter->SetMaxProgress( toFill.size() );
    }
    #ifdef USE_OPENMP
        #pragma omp parallel
    #endif
    {
        #ifdef USE_OPENMP
            #pragma omp master
            if( m_progressReporter )
            {
                m_progressReporter->KeepRefreshing( true );
            }
        #endif

        #ifdef USE_OPENMP
            #pragma omp for schedule(dynamic)
        #endif
        for( unsigned i = 0; i < toFill.size(); i++ )
        {
            if( m_progressReporter )
            {
                m_progressReporter->AdvanceProgress();
            }

            toFill[i].m_zone->CacheTriangulation();
        }
    }

    // If some zones must be filled by segments, create the filling segments
    // (note, this is a outdated option, but it exists)
    int zones_to_fill_count = 0;

    for( unsigned i = 0; i < toFill.size(); i++ )
    {
        if( toFill[i].m_zone->GetFillMode() == ZFM_SEGMENTS )
            zones_to_fill_count++;
    }

    if( zones_to_fill_count )
    {
        if( m_progressReporter )
        {
            m_progressReporter->AdvancePhase();
            m_progressReporter->Report( _( "Fill with segments..." ) );
            m_progressReporter->SetMaxProgress( zones_to_fill_count );
        }

        // TODO: use OPENMP to speedup calculations:
        for( unsigned i = 0; i < toFill.size(); i++ )
        {
            ZONE_CONTAINER* zone = toFill[i].m_zone;

            if( zone->GetFillMode() != ZFM_SEGMENTS )
                continue;

            if( m_progressReporter )
            {
                m_progressReporter->AdvanceProgress();
            }

            ZONE_SEGMENT_FILL segFill;

            fillZoneWithSegments( zone, zone->GetFilledPolysList(), segFill );
            toFill[i].m_zone->SetFillSegments( segFill );
        }
    }

    if( m_progressReporter )
    {
        m_progressReporter->AdvancePhase();
        m_progressReporter->Report( _( "Committing changes..." ) );
    }

    connectivity->SetProgressReporter( nullptr );

    if( m_commit )
    {
        m_commit->Push( _( "Fill Zone(s)" ), false );
    }
    else
    {
        for( unsigned i = 0; i < toFill.size(); i++ )
        {
            connectivity->Update( toFill[i].m_zone );
        }

        connectivity->RecalculateRatsnest();
    }

    connectivity->Unlock();
}