diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index 2bac9b97a8..f58e516e84 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -280,7 +280,7 @@ set( PCBNEW_CLASS_SRCS tracepcb.cpp tr_modif.cpp undo_redo.cpp - zones_convert_brd_items_to_polygons_with_Boost.cpp + zone_filler.cpp zones_convert_to_polygons_aux_functions.cpp zones_by_polygon.cpp zones_by_polygon_fill_functions.cpp diff --git a/pcbnew/drc.cpp b/pcbnew/drc.cpp index 461581afb2..c444100f4b 100644 --- a/pcbnew/drc.cpp +++ b/pcbnew/drc.cpp @@ -621,9 +621,9 @@ void DRC::testKeepoutAreas() ZONE_CONTAINER* area = m_pcb->GetArea( ii ); if( !area->GetIsKeepout() ) - { + { continue; - } + } for( TRACK* segm = m_pcb->m_Track; segm != NULL; segm = segm->Next() ) { @@ -632,8 +632,8 @@ void DRC::testKeepoutAreas() if( ! area->GetDoNotAllowTracks() ) continue; - // Ignore if the keepout zone is not on the same layer - if( !area->IsOnLayer( segm->GetLayer() ) ) + // Ignore if the keepout zone is not on the same layer + if( !area->IsOnLayer( segm->GetLayer() ) ) continue; if( area->Outline()->Distance( SEG( segm->GetStart(), segm->GetEnd() ), @@ -649,9 +649,9 @@ void DRC::testKeepoutAreas() if( ! area->GetDoNotAllowVias() ) continue; - auto viaLayers = segm->GetLayerSet(); - - if( !area->CommonLayerExists( viaLayers ) ) + auto viaLayers = segm->GetLayerSet(); + + if( !area->CommonLayerExists( viaLayers ) ) continue; if( area->Outline()->Distance( segm->GetPosition() ) < segm->GetWidth()/2 ) @@ -806,7 +806,7 @@ bool DRC::doTrackKeepoutDrc( TRACK* aRefSeg ) if( ! area->GetDoNotAllowTracks() ) continue; - if( !area->IsOnLayer( aRefSeg->GetLayer() ) ) + if( !area->IsOnLayer( aRefSeg->GetLayer() ) ) continue; if( area->Outline()->Distance( SEG( aRefSeg->GetStart(), aRefSeg->GetEnd() ), @@ -822,9 +822,9 @@ bool DRC::doTrackKeepoutDrc( TRACK* aRefSeg ) if( ! area->GetDoNotAllowVias() ) continue; - auto viaLayers = aRefSeg->GetLayerSet(); - - if( !area->CommonLayerExists( viaLayers ) ) + auto viaLayers = aRefSeg->GetLayerSet(); + + if( !area->CommonLayerExists( viaLayers ) ) continue; if( area->Outline()->Distance( aRefSeg->GetPosition() ) < aRefSeg->GetWidth()/2 ) diff --git a/pcbnew/edit.cpp b/pcbnew/edit.cpp index 153d50a800..3177df8c5a 100644 --- a/pcbnew/edit.cpp +++ b/pcbnew/edit.cpp @@ -56,6 +56,8 @@ #include #include +#include + #include #include @@ -674,11 +676,14 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) break; case ID_POPUP_PCB_FILL_ZONE: + { m_canvas->MoveCursorToCrossHair(); - Fill_Zone( (ZONE_CONTAINER*) GetCurItem() ); + ZONE_FILLER filler( GetBoard() ); + filler.Fill( { (ZONE_CONTAINER*) GetCurItem() } ); SetMsgPanel( GetBoard() ); m_canvas->Refresh(); break; + } case ID_POPUP_PCB_MOVE_TEXTEPCB_REQUEST: StartMoveTextePcb( (TEXTE_PCB*) GetCurItem(), &dc ); diff --git a/pcbnew/tools/zone_create_helper.cpp b/pcbnew/tools/zone_create_helper.cpp index f72409032d..1e14a91e29 100644 --- a/pcbnew/tools/zone_create_helper.cpp +++ b/pcbnew/tools/zone_create_helper.cpp @@ -34,6 +34,7 @@ #include #include +#include ZONE_CREATE_HELPER::ZONE_CREATE_HELPER( DRAWING_TOOL& aTool, const PARAMS& aParams ): @@ -133,8 +134,8 @@ void ZONE_CREATE_HELPER::performZoneCutout( ZONE_CONTAINER& aExistingZone, // Re-fill if needed if( aExistingZone.IsFilled() ) { - PCB_EDIT_FRAME* frame = m_tool.getEditFrame(); - frame->Fill_Zone( &aExistingZone ); + ZONE_FILLER filler( board ); + filler.Fill( { &aExistingZone } ); } } @@ -142,6 +143,7 @@ void ZONE_CREATE_HELPER::performZoneCutout( ZONE_CONTAINER& aExistingZone, void ZONE_CREATE_HELPER::commitZone( std::unique_ptr aZone ) { auto& frame = *m_tool.getEditFrame(); + auto board = m_tool.getModel(); BOARD_COMMIT bCommit( &m_tool ); @@ -160,7 +162,10 @@ void ZONE_CREATE_HELPER::commitZone( std::unique_ptr aZone ) aZone->Hatch(); if( !m_params.m_keepout ) - frame.Fill_Zone( aZone.get() ); + { + ZONE_FILLER filler( board ); + filler.Fill( { aZone.get() } ); + } bCommit.Add( aZone.release() ); bCommit.Push( _( "Add a zone" ) ); diff --git a/pcbnew/tools/zone_filler_tool.cpp b/pcbnew/tools/zone_filler_tool.cpp index 667f8dc05a..2ec3cf76a8 100644 --- a/pcbnew/tools/zone_filler_tool.cpp +++ b/pcbnew/tools/zone_filler_tool.cpp @@ -26,13 +26,7 @@ #include #include -#include -#include -#include -#include -#include #include -#include #include #include #include @@ -45,10 +39,7 @@ #include "pcb_actions.h" #include "selection_tool.h" #include "zone_filler_tool.h" - -#ifdef USE_OPENMP -#include -#endif /* USE_OPENMP */ +#include "zone_filler.h" // Zone actions TOOL_ACTION PCB_ACTIONS::zoneFill( "pcbnew.ZoneFiller.zoneFill", @@ -67,135 +58,6 @@ TOOL_ACTION PCB_ACTIONS::zoneUnfillAll( "pcbnew.ZoneFiller.zoneUnfillAll", AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_ZONE_REMOVE_FILLED ), _( "Unfill All" ), _( "Unfill all zones" ) ); - -class ZONE_FILLER -{ -public: - ZONE_FILLER( BOARD* aBoard, COMMIT* aCommit ); - ~ZONE_FILLER(); - - void SetProgressReporter( PROGRESS_REPORTER* aReporter ); - void Fill( std::vector aZones ); - void Unfill( std::vector aZones ); - -private: - COMMIT* m_commit; - PROGRESS_REPORTER* m_progressReporter; - BOARD* m_board; -}; - -ZONE_FILLER::ZONE_FILLER( BOARD* aBoard, COMMIT* aCommit ) : - m_commit( aCommit ), - m_board( aBoard ) -{ -} - - -ZONE_FILLER::~ZONE_FILLER() -{ -} - - -void ZONE_FILLER::SetProgressReporter( PROGRESS_REPORTER* aReporter ) -{ - m_progressReporter = aReporter; -} - - -void ZONE_FILLER::Fill( std::vector aZones ) -{ - std::vector toFill; - - assert( m_commit ); - - // Remove segment zones - m_board->m_Zone.DeleteAll(); - - int ii; - - 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 ); - } - - int zoneCount = m_board->GetAreaCount(); - - for( int i = 0; i < toFill.size(); i++ ) - { - 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 for schedule(dynamic) - #endif - for( int i = 0; i < toFill.size(); i++ ) - { - toFill[i].m_zone->BuildFilledSolidAreasPolygons( m_board ); - - m_progressReporter->AdvanceProgress(); - } - - if( m_progressReporter ) - { - m_progressReporter->AdvancePhase(); - m_progressReporter->Report( _( "Removing insulated copper islands..." ) ); - } - - m_board->GetConnectivity()->SetProgressReporter( m_progressReporter ); - m_board->GetConnectivity()->FindIsolatedCopperIslands( toFill ); - - for( auto& zone : toFill ) - { - std::sort( zone.m_islands.begin(), zone.m_islands.end(), std::greater() ); - SHAPE_POLY_SET poly = zone.m_zone->GetFilledPolysList(); - - for( auto idx : zone.m_islands ) - { - poly.DeletePolygon( idx ); - } - - zone.m_zone->AddFilledPolysList( poly ); - } - - if( m_progressReporter ) - { - m_progressReporter->AdvancePhase(); - m_progressReporter->Report( _( "Caching polygon triangulations..." ) ); - m_progressReporter->SetMaxProgress( toFill.size() ); - } - - #ifdef USE_OPENMP - #pragma omp parallel for schedule(dynamic) - #endif - for( int i = 0; i < toFill.size(); i++ ) - { - m_progressReporter->AdvanceProgress(); - toFill[i].m_zone->CacheTriangulation(); - } - - m_progressReporter->AdvancePhase(); - m_progressReporter->Report( _( "Committing changes..." ) ); - - m_commit->Push( _( "Fill Zones" ), false ); -} - - - - ZONE_FILLER_TOOL::ZONE_FILLER_TOOL() : PCB_TOOL( "pcbnew.ZoneFiller" ) { @@ -214,13 +76,11 @@ void ZONE_FILLER_TOOL::Reset( RESET_REASON aReason ) // Zone actions int ZONE_FILLER_TOOL::ZoneFill( const TOOL_EVENT& aEvent ) { - auto selTool = m_toolMgr->GetTool(); - const auto& selection = selTool->GetSelection(); std::vector toFill; BOARD_COMMIT commit( this ); - for( auto item : selection ) + for( auto item : selection() ) { assert( item->Type() == PCB_ZONE_AREA_T ); @@ -230,7 +90,7 @@ int ZONE_FILLER_TOOL::ZoneFill( const TOOL_EVENT& aEvent ) } std::unique_ptr progressReporter( - new WX_PROGRESS_REPORTER( frame(), _( "Fill Zones" ), 3 ) + new WX_PROGRESS_REPORTER( frame(), _( "Fill Zone" ), 3 ) ); ZONE_FILLER filler( board(), &commit ); @@ -266,13 +126,9 @@ int ZONE_FILLER_TOOL::ZoneFillAll( const TOOL_EVENT& aEvent ) int ZONE_FILLER_TOOL::ZoneUnfill( const TOOL_EVENT& aEvent ) { - auto selTool = m_toolMgr->GetTool(); - const auto& selection = selTool->GetSelection(); - auto connectivity = getModel()->GetConnectivity(); - BOARD_COMMIT commit( this ); - for( auto item : selection ) + for( auto item : selection() ) { assert( item->Type() == PCB_ZONE_AREA_T ); @@ -286,23 +142,16 @@ int ZONE_FILLER_TOOL::ZoneUnfill( const TOOL_EVENT& aEvent ) commit.Push( _( "Unfill Zone" ) ); - connectivity->RecalculateRatsnest(); - return 0; } int ZONE_FILLER_TOOL::ZoneUnfillAll( const TOOL_EVENT& aEvent ) { - BOARD* board = getModel(); - auto connectivity = getModel()->GetConnectivity(); - BOARD_COMMIT commit( this ); - for( int i = 0; i < board->GetAreaCount(); ++i ) + for ( auto zone : board()->Zones() ) { - ZONE_CONTAINER* zone = board->GetArea( i ); - commit.Modify( zone ); zone->SetIsFilled( false ); @@ -311,8 +160,6 @@ int ZONE_FILLER_TOOL::ZoneUnfillAll( const TOOL_EVENT& aEvent ) commit.Push( _( "Unfill All Zones" ) ); - connectivity->RecalculateRatsnest(); - return 0; } diff --git a/pcbnew/zone_filler.cpp b/pcbnew/zone_filler.cpp new file mode 100644 index 0000000000..8fca130cea --- /dev/null +++ b/pcbnew/zone_filler.cpp @@ -0,0 +1,173 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2014-2017 CERN + * Copyright (C) 2014-2017 KiCad Developers, see AUTHORS.txt for contributors. + * @author Tomasz Włostowski + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "zone_filler.h" + +#ifdef USE_OPENMP +#include +#endif /* USE_OPENMP */ + + +ZONE_FILLER::ZONE_FILLER( BOARD* aBoard, COMMIT* aCommit ) : + m_commit( aCommit ), + m_board( aBoard ), + m_progressReporter( nullptr ) +{ +} + + +ZONE_FILLER::~ZONE_FILLER() +{ +} + + +void ZONE_FILLER::SetProgressReporter( PROGRESS_REPORTER* aReporter ) +{ + m_progressReporter = aReporter; +} + + +void ZONE_FILLER::Fill( std::vector aZones ) +{ + std::vector toFill; + auto connectivity = m_board->GetConnectivity(); + + // Remove segment zones + m_board->m_Zone.DeleteAll(); + + int ii; + + 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 ); + } + + int zoneCount = m_board->GetAreaCount(); + + for( int 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 for schedule(dynamic) + #endif + for( int i = 0; i < toFill.size(); i++ ) + { + toFill[i].m_zone->BuildFilledSolidAreasPolygons( m_board ); + + if( m_progressReporter ) + { + m_progressReporter->AdvanceProgress(); + } + } + + 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() ); + SHAPE_POLY_SET poly = zone.m_zone->GetFilledPolysList(); + + for( auto idx : zone.m_islands ) + { + poly.DeletePolygon( idx ); + } + + zone.m_zone->AddFilledPolysList( poly ); + } + + if( m_progressReporter ) + { + m_progressReporter->AdvancePhase(); + m_progressReporter->Report( _( "Caching polygon triangulations..." ) ); + m_progressReporter->SetMaxProgress( toFill.size() ); + } + + #ifdef USE_OPENMP + #pragma omp parallel for schedule(dynamic) + #endif + + for( int i = 0; i < toFill.size(); i++ ) + { + if( m_progressReporter ) + { + m_progressReporter->AdvanceProgress(); + } + toFill[i].m_zone->CacheTriangulation(); + } + + 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( int i = 0; i < toFill.size(); i++ ) + { + connectivity->Update( toFill[i].m_zone ); + } + } +} diff --git a/pcbnew/zone_filler.h b/pcbnew/zone_filler.h new file mode 100644 index 0000000000..ade9d23a1e --- /dev/null +++ b/pcbnew/zone_filler.h @@ -0,0 +1,52 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2014-2017 CERN + * Copyright (C) 2014-2017 KiCad Developers, see AUTHORS.txt for contributors. + * @author Tomasz Włostowski + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __ZONE_FILLER_H +#define __ZONE_FILLER_H + +#include + +class PROGRESS_REPORTER; +class BOARD; +class COMMIT; +class ZONE_CONTAINER; + +class ZONE_FILLER +{ +public: + ZONE_FILLER( BOARD* aBoard, COMMIT* aCommit = nullptr ); + ~ZONE_FILLER(); + + void SetProgressReporter( PROGRESS_REPORTER* aReporter ); + void Fill( std::vector aZones ); + void Unfill( std::vector aZones ); + +private: + COMMIT* m_commit; + PROGRESS_REPORTER* m_progressReporter; + BOARD* m_board; +}; + +#endif diff --git a/pcbnew/zones_by_polygon.cpp b/pcbnew/zones_by_polygon.cpp index 72e3b5552e..52fd08db66 100644 --- a/pcbnew/zones_by_polygon.cpp +++ b/pcbnew/zones_by_polygon.cpp @@ -47,6 +47,8 @@ #include #include +#include + // Outline creation: static void Abort_Zone_Create_Outline( EDA_DRAW_PANEL* Panel, wxDC* DC ); static void Show_New_Edge_While_Move_Mouse( EDA_DRAW_PANEL* aPanel, wxDC* aDC, @@ -954,7 +956,8 @@ void PCB_EDIT_FRAME::Edit_Zone_Params( wxDC* DC, ZONE_CONTAINER* aZone ) if( zone->IsFilled() ) { - Fill_Zone( zone ); + ZONE_FILLER filler ( GetBoard() ); + filler.Fill( { zone } ); } } diff --git a/pcbnew/zones_by_polygon_fill_functions.cpp b/pcbnew/zones_by_polygon_fill_functions.cpp index 13c3ae0d07..73f48c1ff5 100644 --- a/pcbnew/zones_by_polygon_fill_functions.cpp +++ b/pcbnew/zones_by_polygon_fill_functions.cpp @@ -46,7 +46,8 @@ #include #include -#define FORMAT_STRING _( "Filling zone %d out of %d (net %s)..." ) +#include +#include /** @@ -89,118 +90,24 @@ void PCB_EDIT_FRAME::Delete_OldZone_Fill( SEGZONE* aZone, time_t aTimestamp ) } } - -int PCB_EDIT_FRAME::Fill_Zone( ZONE_CONTAINER* aZone ) +int PCB_EDIT_FRAME::Fill_All_Zones( wxWindow * aActiveWindow, bool aVerbose ) { - aZone->ClearFilledPolysList(); - aZone->UnFill(); - - // Cannot fill keepout zones: - if( aZone->GetIsKeepout() ) - return 1; - - wxString msg; - - ClearMsgPanel(); - - // Shows the net - ZONE_SETTINGS zoneInfo = GetZoneSettings(); - zoneInfo.m_NetcodeSelection = aZone->GetNetCode(); - SetZoneSettings( zoneInfo ); - - msg = aZone->GetNetname(); - - if( msg.IsEmpty() ) - msg = wxT( "No net" ); - - AppendMsgPanel( _( "NetName" ), msg, RED ); - - wxBusyCursor dummy; // Shows an hourglass cursor (removed by its destructor) + std::vector toFill; BOARD_COMMIT commit( this ); - commit.Modify( aZone ); - aZone->BuildFilledSolidAreasPolygons( GetBoard() ); - commit.Push( _( "Fill Zone" ), false ); - //GetGalCanvas()->GetView()->Update( aZone, KIGFX::ALL ); - //GetBoard()->GetConnectivity()->Update( aZone ); - - //OnModify(); - - return 0; - -} - -int PCB_EDIT_FRAME::Fill_All_Zones( wxWindow * aActiveWindow, bool aVerbose ) -{ - return 0; -} - -/* -int PCB_EDIT_FRAME::Fill_All_Zones( wxWindow * aActiveWindow, bool aVerbose ) -{ - int errorLevel = 0; - int areaCount = GetBoard()->GetAreaCount(); - wxBusyCursor dummyCursor; - wxString msg; - wxProgressDialog * progressDialog = NULL; - - // Create a message with a long net name, and build a wxProgressDialog - // with a correct size to show this long net name - msg.Printf( FORMAT_STRING, 000, areaCount, wxT("XXXXXXXXXXXXXXXXX" ) ); - - if( aActiveWindow ) - progressDialog = new wxProgressDialog( _( "Fill All Zones" ), msg, - areaCount+2, aActiveWindow, - wxPD_AUTO_HIDE | wxPD_CAN_ABORT | - wxPD_APP_MODAL | wxPD_ELAPSED_TIME ); - // Display the actual message - if( progressDialog ) - progressDialog->Update( 0, _( "Starting zone fill..." ) ); - - // Remove segment zones - GetBoard()->m_Zone.DeleteAll(); - - int ii; - - for( ii = 0; ii < areaCount; ii++ ) + for( auto zone : GetBoard()->Zones() ) { - ZONE_CONTAINER* zoneContainer = GetBoard()->GetArea( ii ); - - // Keepout zones are not filled - if( zoneContainer->GetIsKeepout() ) - continue; - - msg.Printf( FORMAT_STRING, ii + 1, areaCount, GetChars( zoneContainer->GetNetname() ) ); - - if( progressDialog ) - { - if( !progressDialog->Update( ii+1, msg ) ) - break; // Aborted by user - } - - errorLevel = Fill_Zone( zoneContainer ); - - if( errorLevel && !aVerbose ) - break; + toFill.push_back(zone); } - if( progressDialog ) - { - progressDialog->Update( ii+2, _( "Updating ratsnest..." ) ); -#ifdef __WXMAC__ - // Work around a dialog z-order issue on OS X - aActiveWindow->Raise(); -#endif - } - //TestConnections(); + std::unique_ptr progressReporter( + new WX_PROGRESS_REPORTER( aActiveWindow, _( "Fill All Zones" ), 3 ) + ); - // Recalculate the active ratsnest, i.e. the unconnected links - //TestForActiveLinksInRatsnest( 0 ); + ZONE_FILLER filler( GetBoard() ); + filler.SetProgressReporter( progressReporter.get() ); + filler.Fill( toFill ); - if( progressDialog ) - progressDialog->Destroy(); - - return errorLevel; + return 0; } -*/