/** * Function IsSame * test is 2 zones are equivalent: * 2 zones are equivalent if they have same parameters and same outlines * info relative to filling is not take in account * @param aZoneToCompare = zone to compare with "this" */ bool ZONE_CONTAINER::IsSame( const ZONE_CONTAINER& aZoneToCompare ) { // compare basic parameters: if( GetLayer() != aZoneToCompare.GetLayer() ) return false; if( GetNetCode() != aZoneToCompare.GetNetCode() ) return false; if( GetPriority() != aZoneToCompare.GetPriority() ) return false; // Compare zone specific parameters if( GetIsKeepout() != aZoneToCompare.GetIsKeepout() ) return false; if( GetIsKeepout() ) { if( GetDoNotAllowCopperPour() != aZoneToCompare.GetDoNotAllowCopperPour() ) return false; if( GetDoNotAllowVias() != aZoneToCompare.GetDoNotAllowVias() ) return false; if( GetDoNotAllowTracks() != aZoneToCompare.GetDoNotAllowTracks() ) return false; } if( m_ArcToSegmentsCount != aZoneToCompare.GetArcSegmentCount() ) return false; if( m_ZoneClearance != aZoneToCompare.m_ZoneClearance ) return false; if( m_ZoneMinThickness != aZoneToCompare.GetMinThickness() ) return false; if( m_FillMode != aZoneToCompare.GetFillMode() ) return false; if( m_PadConnection != aZoneToCompare.m_PadConnection ) return false; if( m_ThermalReliefGap != aZoneToCompare.m_ThermalReliefGap ) return false; if( m_ThermalReliefCopperBridge != aZoneToCompare.m_ThermalReliefCopperBridge ) return false; // Compare outlines wxASSERT( m_Poly ); // m_Poly == NULL Should never happen wxASSERT( aZoneToCompare.Outline() ); if( Outline()->m_CornersList.GetList() != aZoneToCompare.Outline()->m_CornersList.GetList() ) // Compare vector return false; return true; }
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(); }