pcbnew: factored out ZONE_FILLER to a separate file
This commit is contained in:
parent
56336fdafe
commit
fdd5023aee
|
@ -280,7 +280,7 @@ set( PCBNEW_CLASS_SRCS
|
||||||
tracepcb.cpp
|
tracepcb.cpp
|
||||||
tr_modif.cpp
|
tr_modif.cpp
|
||||||
undo_redo.cpp
|
undo_redo.cpp
|
||||||
zones_convert_brd_items_to_polygons_with_Boost.cpp
|
zone_filler.cpp
|
||||||
zones_convert_to_polygons_aux_functions.cpp
|
zones_convert_to_polygons_aux_functions.cpp
|
||||||
zones_by_polygon.cpp
|
zones_by_polygon.cpp
|
||||||
zones_by_polygon_fill_functions.cpp
|
zones_by_polygon_fill_functions.cpp
|
||||||
|
|
|
@ -621,9 +621,9 @@ void DRC::testKeepoutAreas()
|
||||||
ZONE_CONTAINER* area = m_pcb->GetArea( ii );
|
ZONE_CONTAINER* area = m_pcb->GetArea( ii );
|
||||||
|
|
||||||
if( !area->GetIsKeepout() )
|
if( !area->GetIsKeepout() )
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for( TRACK* segm = m_pcb->m_Track; segm != NULL; segm = segm->Next() )
|
for( TRACK* segm = m_pcb->m_Track; segm != NULL; segm = segm->Next() )
|
||||||
{
|
{
|
||||||
|
@ -632,8 +632,8 @@ void DRC::testKeepoutAreas()
|
||||||
if( ! area->GetDoNotAllowTracks() )
|
if( ! area->GetDoNotAllowTracks() )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Ignore if the keepout zone is not on the same layer
|
// Ignore if the keepout zone is not on the same layer
|
||||||
if( !area->IsOnLayer( segm->GetLayer() ) )
|
if( !area->IsOnLayer( segm->GetLayer() ) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if( area->Outline()->Distance( SEG( segm->GetStart(), segm->GetEnd() ),
|
if( area->Outline()->Distance( SEG( segm->GetStart(), segm->GetEnd() ),
|
||||||
|
@ -649,9 +649,9 @@ void DRC::testKeepoutAreas()
|
||||||
if( ! area->GetDoNotAllowVias() )
|
if( ! area->GetDoNotAllowVias() )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto viaLayers = segm->GetLayerSet();
|
auto viaLayers = segm->GetLayerSet();
|
||||||
|
|
||||||
if( !area->CommonLayerExists( viaLayers ) )
|
if( !area->CommonLayerExists( viaLayers ) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if( area->Outline()->Distance( segm->GetPosition() ) < segm->GetWidth()/2 )
|
if( area->Outline()->Distance( segm->GetPosition() ) < segm->GetWidth()/2 )
|
||||||
|
@ -806,7 +806,7 @@ bool DRC::doTrackKeepoutDrc( TRACK* aRefSeg )
|
||||||
if( ! area->GetDoNotAllowTracks() )
|
if( ! area->GetDoNotAllowTracks() )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if( !area->IsOnLayer( aRefSeg->GetLayer() ) )
|
if( !area->IsOnLayer( aRefSeg->GetLayer() ) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if( area->Outline()->Distance( SEG( aRefSeg->GetStart(), aRefSeg->GetEnd() ),
|
if( area->Outline()->Distance( SEG( aRefSeg->GetStart(), aRefSeg->GetEnd() ),
|
||||||
|
@ -822,9 +822,9 @@ bool DRC::doTrackKeepoutDrc( TRACK* aRefSeg )
|
||||||
if( ! area->GetDoNotAllowVias() )
|
if( ! area->GetDoNotAllowVias() )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto viaLayers = aRefSeg->GetLayerSet();
|
auto viaLayers = aRefSeg->GetLayerSet();
|
||||||
|
|
||||||
if( !area->CommonLayerExists( viaLayers ) )
|
if( !area->CommonLayerExists( viaLayers ) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if( area->Outline()->Distance( aRefSeg->GetPosition() ) < aRefSeg->GetWidth()/2 )
|
if( area->Outline()->Distance( aRefSeg->GetPosition() ) < aRefSeg->GetWidth()/2 )
|
||||||
|
|
|
@ -56,6 +56,8 @@
|
||||||
#include <array_creator.h>
|
#include <array_creator.h>
|
||||||
#include <connectivity_data.h>
|
#include <connectivity_data.h>
|
||||||
|
|
||||||
|
#include <zone_filler.h>
|
||||||
|
|
||||||
#include <dialog_move_exact.h>
|
#include <dialog_move_exact.h>
|
||||||
|
|
||||||
#include <tool/tool_manager.h>
|
#include <tool/tool_manager.h>
|
||||||
|
@ -674,11 +676,14 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ID_POPUP_PCB_FILL_ZONE:
|
case ID_POPUP_PCB_FILL_ZONE:
|
||||||
|
{
|
||||||
m_canvas->MoveCursorToCrossHair();
|
m_canvas->MoveCursorToCrossHair();
|
||||||
Fill_Zone( (ZONE_CONTAINER*) GetCurItem() );
|
ZONE_FILLER filler( GetBoard() );
|
||||||
|
filler.Fill( { (ZONE_CONTAINER*) GetCurItem() } );
|
||||||
SetMsgPanel( GetBoard() );
|
SetMsgPanel( GetBoard() );
|
||||||
m_canvas->Refresh();
|
m_canvas->Refresh();
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case ID_POPUP_PCB_MOVE_TEXTEPCB_REQUEST:
|
case ID_POPUP_PCB_MOVE_TEXTEPCB_REQUEST:
|
||||||
StartMoveTextePcb( (TEXTE_PCB*) GetCurItem(), &dc );
|
StartMoveTextePcb( (TEXTE_PCB*) GetCurItem(), &dc );
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include <tools/pcb_actions.h>
|
#include <tools/pcb_actions.h>
|
||||||
#include <tools/selection_tool.h>
|
#include <tools/selection_tool.h>
|
||||||
|
|
||||||
|
#include <zone_filler.h>
|
||||||
|
|
||||||
ZONE_CREATE_HELPER::ZONE_CREATE_HELPER( DRAWING_TOOL& aTool,
|
ZONE_CREATE_HELPER::ZONE_CREATE_HELPER( DRAWING_TOOL& aTool,
|
||||||
const PARAMS& aParams ):
|
const PARAMS& aParams ):
|
||||||
|
@ -133,8 +134,8 @@ void ZONE_CREATE_HELPER::performZoneCutout( ZONE_CONTAINER& aExistingZone,
|
||||||
// Re-fill if needed
|
// Re-fill if needed
|
||||||
if( aExistingZone.IsFilled() )
|
if( aExistingZone.IsFilled() )
|
||||||
{
|
{
|
||||||
PCB_EDIT_FRAME* frame = m_tool.getEditFrame<PCB_EDIT_FRAME>();
|
ZONE_FILLER filler( board );
|
||||||
frame->Fill_Zone( &aExistingZone );
|
filler.Fill( { &aExistingZone } );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,6 +143,7 @@ void ZONE_CREATE_HELPER::performZoneCutout( ZONE_CONTAINER& aExistingZone,
|
||||||
void ZONE_CREATE_HELPER::commitZone( std::unique_ptr<ZONE_CONTAINER> aZone )
|
void ZONE_CREATE_HELPER::commitZone( std::unique_ptr<ZONE_CONTAINER> aZone )
|
||||||
{
|
{
|
||||||
auto& frame = *m_tool.getEditFrame<PCB_EDIT_FRAME>();
|
auto& frame = *m_tool.getEditFrame<PCB_EDIT_FRAME>();
|
||||||
|
auto board = m_tool.getModel<BOARD>();
|
||||||
|
|
||||||
BOARD_COMMIT bCommit( &m_tool );
|
BOARD_COMMIT bCommit( &m_tool );
|
||||||
|
|
||||||
|
@ -160,7 +162,10 @@ void ZONE_CREATE_HELPER::commitZone( std::unique_ptr<ZONE_CONTAINER> aZone )
|
||||||
aZone->Hatch();
|
aZone->Hatch();
|
||||||
|
|
||||||
if( !m_params.m_keepout )
|
if( !m_params.m_keepout )
|
||||||
frame.Fill_Zone( aZone.get() );
|
{
|
||||||
|
ZONE_FILLER filler( board );
|
||||||
|
filler.Fill( { aZone.get() } );
|
||||||
|
}
|
||||||
|
|
||||||
bCommit.Add( aZone.release() );
|
bCommit.Add( aZone.release() );
|
||||||
bCommit.Push( _( "Add a zone" ) );
|
bCommit.Push( _( "Add a zone" ) );
|
||||||
|
|
|
@ -26,13 +26,7 @@
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
#include <painter.h>
|
|
||||||
#include <project.h>
|
|
||||||
#include <pcbnew_id.h>
|
|
||||||
#include <wxPcbStruct.h>
|
|
||||||
#include <class_board.h>
|
|
||||||
#include <class_zone.h>
|
#include <class_zone.h>
|
||||||
#include <pcb_draw_panel_gal.h>
|
|
||||||
#include <class_module.h>
|
#include <class_module.h>
|
||||||
#include <connectivity_data.h>
|
#include <connectivity_data.h>
|
||||||
#include <board_commit.h>
|
#include <board_commit.h>
|
||||||
|
@ -45,10 +39,7 @@
|
||||||
#include "pcb_actions.h"
|
#include "pcb_actions.h"
|
||||||
#include "selection_tool.h"
|
#include "selection_tool.h"
|
||||||
#include "zone_filler_tool.h"
|
#include "zone_filler_tool.h"
|
||||||
|
#include "zone_filler.h"
|
||||||
#ifdef USE_OPENMP
|
|
||||||
#include <omp.h>
|
|
||||||
#endif /* USE_OPENMP */
|
|
||||||
|
|
||||||
// Zone actions
|
// Zone actions
|
||||||
TOOL_ACTION PCB_ACTIONS::zoneFill( "pcbnew.ZoneFiller.zoneFill",
|
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 ),
|
AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_ZONE_REMOVE_FILLED ),
|
||||||
_( "Unfill All" ), _( "Unfill all zones" ) );
|
_( "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<ZONE_CONTAINER*> aZones );
|
|
||||||
void Unfill( std::vector<ZONE_CONTAINER*> 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<ZONE_CONTAINER*> aZones )
|
|
||||||
{
|
|
||||||
std::vector<CN_ZONE_ISOLATED_ISLAND_LIST> 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<int>() );
|
|
||||||
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() :
|
ZONE_FILLER_TOOL::ZONE_FILLER_TOOL() :
|
||||||
PCB_TOOL( "pcbnew.ZoneFiller" )
|
PCB_TOOL( "pcbnew.ZoneFiller" )
|
||||||
{
|
{
|
||||||
|
@ -214,13 +76,11 @@ void ZONE_FILLER_TOOL::Reset( RESET_REASON aReason )
|
||||||
// Zone actions
|
// Zone actions
|
||||||
int ZONE_FILLER_TOOL::ZoneFill( const TOOL_EVENT& aEvent )
|
int ZONE_FILLER_TOOL::ZoneFill( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
auto selTool = m_toolMgr->GetTool<SELECTION_TOOL>();
|
|
||||||
const auto& selection = selTool->GetSelection();
|
|
||||||
std::vector<ZONE_CONTAINER*> toFill;
|
std::vector<ZONE_CONTAINER*> toFill;
|
||||||
|
|
||||||
BOARD_COMMIT commit( this );
|
BOARD_COMMIT commit( this );
|
||||||
|
|
||||||
for( auto item : selection )
|
for( auto item : selection() )
|
||||||
{
|
{
|
||||||
assert( item->Type() == PCB_ZONE_AREA_T );
|
assert( item->Type() == PCB_ZONE_AREA_T );
|
||||||
|
|
||||||
|
@ -230,7 +90,7 @@ int ZONE_FILLER_TOOL::ZoneFill( const TOOL_EVENT& aEvent )
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<WX_PROGRESS_REPORTER> progressReporter(
|
std::unique_ptr<WX_PROGRESS_REPORTER> progressReporter(
|
||||||
new WX_PROGRESS_REPORTER( frame(), _( "Fill Zones" ), 3 )
|
new WX_PROGRESS_REPORTER( frame(), _( "Fill Zone" ), 3 )
|
||||||
);
|
);
|
||||||
|
|
||||||
ZONE_FILLER filler( board(), &commit );
|
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 )
|
int ZONE_FILLER_TOOL::ZoneUnfill( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
auto selTool = m_toolMgr->GetTool<SELECTION_TOOL>();
|
|
||||||
const auto& selection = selTool->GetSelection();
|
|
||||||
auto connectivity = getModel<BOARD>()->GetConnectivity();
|
|
||||||
|
|
||||||
BOARD_COMMIT commit( this );
|
BOARD_COMMIT commit( this );
|
||||||
|
|
||||||
for( auto item : selection )
|
for( auto item : selection() )
|
||||||
{
|
{
|
||||||
assert( item->Type() == PCB_ZONE_AREA_T );
|
assert( item->Type() == PCB_ZONE_AREA_T );
|
||||||
|
|
||||||
|
@ -286,23 +142,16 @@ int ZONE_FILLER_TOOL::ZoneUnfill( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
commit.Push( _( "Unfill Zone" ) );
|
commit.Push( _( "Unfill Zone" ) );
|
||||||
|
|
||||||
connectivity->RecalculateRatsnest();
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int ZONE_FILLER_TOOL::ZoneUnfillAll( const TOOL_EVENT& aEvent )
|
int ZONE_FILLER_TOOL::ZoneUnfillAll( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
BOARD* board = getModel<BOARD>();
|
|
||||||
auto connectivity = getModel<BOARD>()->GetConnectivity();
|
|
||||||
|
|
||||||
BOARD_COMMIT commit( this );
|
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 );
|
commit.Modify( zone );
|
||||||
|
|
||||||
zone->SetIsFilled( false );
|
zone->SetIsFilled( false );
|
||||||
|
@ -311,8 +160,6 @@ int ZONE_FILLER_TOOL::ZoneUnfillAll( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
commit.Push( _( "Unfill All Zones" ) );
|
commit.Push( _( "Unfill All Zones" ) );
|
||||||
|
|
||||||
connectivity->RecalculateRatsnest();
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 <tomasz.wlostowski@cern.ch>
|
||||||
|
*
|
||||||
|
* 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 <cstdint>
|
||||||
|
#include <thread>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
#include <class_board.h>
|
||||||
|
#include <class_zone.h>
|
||||||
|
#include <class_module.h>
|
||||||
|
#include <connectivity_data.h>
|
||||||
|
#include <board_commit.h>
|
||||||
|
|
||||||
|
#include <widgets/progress_reporter.h>
|
||||||
|
|
||||||
|
#include "zone_filler.h"
|
||||||
|
|
||||||
|
#ifdef USE_OPENMP
|
||||||
|
#include <omp.h>
|
||||||
|
#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<ZONE_CONTAINER*> aZones )
|
||||||
|
{
|
||||||
|
std::vector<CN_ZONE_ISOLATED_ISLAND_LIST> 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<int>() );
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 <tomasz.wlostowski@cern.ch>
|
||||||
|
*
|
||||||
|
* 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 <vector>
|
||||||
|
|
||||||
|
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<ZONE_CONTAINER*> aZones );
|
||||||
|
void Unfill( std::vector<ZONE_CONTAINER*> aZones );
|
||||||
|
|
||||||
|
private:
|
||||||
|
COMMIT* m_commit;
|
||||||
|
PROGRESS_REPORTER* m_progressReporter;
|
||||||
|
BOARD* m_board;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -47,6 +47,8 @@
|
||||||
#include <drc_stuff.h>
|
#include <drc_stuff.h>
|
||||||
#include <connectivity_data.h>
|
#include <connectivity_data.h>
|
||||||
|
|
||||||
|
#include <zone_filler.h>
|
||||||
|
|
||||||
// Outline creation:
|
// Outline creation:
|
||||||
static void Abort_Zone_Create_Outline( EDA_DRAW_PANEL* Panel, wxDC* DC );
|
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,
|
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() )
|
if( zone->IsFilled() )
|
||||||
{
|
{
|
||||||
Fill_Zone( zone );
|
ZONE_FILLER filler ( GetBoard() );
|
||||||
|
filler.Fill( { zone } );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,8 @@
|
||||||
#include <connectivity_data.h>
|
#include <connectivity_data.h>
|
||||||
#include <board_commit.h>
|
#include <board_commit.h>
|
||||||
|
|
||||||
#define FORMAT_STRING _( "Filling zone %d out of %d (net %s)..." )
|
#include <widgets/progress_reporter.h>
|
||||||
|
#include <zone_filler.h>
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -89,118 +90,24 @@ void PCB_EDIT_FRAME::Delete_OldZone_Fill( SEGZONE* aZone, time_t aTimestamp )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int PCB_EDIT_FRAME::Fill_All_Zones( wxWindow * aActiveWindow, bool aVerbose )
|
||||||
int PCB_EDIT_FRAME::Fill_Zone( ZONE_CONTAINER* aZone )
|
|
||||||
{
|
{
|
||||||
aZone->ClearFilledPolysList();
|
std::vector<ZONE_CONTAINER*> toFill;
|
||||||
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)
|
|
||||||
|
|
||||||
BOARD_COMMIT commit( this );
|
BOARD_COMMIT commit( this );
|
||||||
commit.Modify( aZone );
|
|
||||||
aZone->BuildFilledSolidAreasPolygons( GetBoard() );
|
|
||||||
commit.Push( _( "Fill Zone" ), false );
|
|
||||||
|
|
||||||
//GetGalCanvas()->GetView()->Update( aZone, KIGFX::ALL );
|
for( auto zone : GetBoard()->Zones() )
|
||||||
//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++ )
|
|
||||||
{
|
{
|
||||||
ZONE_CONTAINER* zoneContainer = GetBoard()->GetArea( ii );
|
toFill.push_back(zone);
|
||||||
|
|
||||||
// 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( progressDialog )
|
std::unique_ptr<WX_PROGRESS_REPORTER> progressReporter(
|
||||||
{
|
new WX_PROGRESS_REPORTER( aActiveWindow, _( "Fill All Zones" ), 3 )
|
||||||
progressDialog->Update( ii+2, _( "Updating ratsnest..." ) );
|
);
|
||||||
#ifdef __WXMAC__
|
|
||||||
// Work around a dialog z-order issue on OS X
|
|
||||||
aActiveWindow->Raise();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
//TestConnections();
|
|
||||||
|
|
||||||
// Recalculate the active ratsnest, i.e. the unconnected links
|
ZONE_FILLER filler( GetBoard() );
|
||||||
//TestForActiveLinksInRatsnest( 0 );
|
filler.SetProgressReporter( progressReporter.get() );
|
||||||
|
filler.Fill( toFill );
|
||||||
|
|
||||||
if( progressDialog )
|
return 0;
|
||||||
progressDialog->Destroy();
|
|
||||||
|
|
||||||
return errorLevel;
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
Loading…
Reference in New Issue