2011-10-17 20:01:27 +00:00
|
|
|
/*
|
|
|
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
|
|
|
*
|
2015-01-22 12:06:34 +00:00
|
|
|
* Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
2012-06-08 09:56:42 +00:00
|
|
|
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
|
|
|
* Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
|
2017-09-27 07:59:12 +00:00
|
|
|
* Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors.
|
2011-10-17 20:01:27 +00:00
|
|
|
*
|
|
|
|
* 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
|
|
|
|
*/
|
|
|
|
|
2011-09-23 13:57:12 +00:00
|
|
|
/**
|
|
|
|
* @file zones_by_polygon.cpp
|
|
|
|
*/
|
2007-12-19 16:44:53 +00:00
|
|
|
|
2012-01-23 04:33:36 +00:00
|
|
|
#include <fctsys.h>
|
* KIWAY Milestone A): Make major modules into DLL/DSOs.
! The initial testing of this commit should be done using a Debug build so that
all the wxASSERT()s are enabled. Also, be sure and keep enabled the
USE_KIWAY_DLLs option. The tree won't likely build without it. Turning it
off is senseless anyways. If you want stable code, go back to a prior version,
the one tagged with "stable".
* Relocate all functionality out of the wxApp derivative into more finely
targeted purposes:
a) DLL/DSO specific
b) PROJECT specific
c) EXE or process specific
d) configuration file specific data
e) configuration file manipulations functions.
All of this functionality was blended into an extremely large wxApp derivative
and that was incompatible with the desire to support multiple concurrently
loaded DLL/DSO's ("KIFACE")s and multiple concurrently open projects.
An amazing amount of organization come from simply sorting each bit of
functionality into the proper box.
* Switch to wxConfigBase from wxConfig everywhere except instantiation.
* Add classes KIWAY, KIFACE, KIFACE_I, SEARCH_STACK, PGM_BASE, PGM_KICAD,
PGM_SINGLE_TOP,
* Remove "Return" prefix on many function names.
* Remove obvious comments from CMakeLists.txt files, and from else() and endif()s.
* Fix building boost for use in a DSO on linux.
* Remove some of the assumptions in the CMakeLists.txt files that windows had
to be the host platform when building windows binaries.
* Reduce the number of wxStrings being constructed at program load time via
static construction.
* Pass wxConfigBase* to all SaveSettings() and LoadSettings() functions so that
these functions are useful even when the wxConfigBase comes from another
source, as is the case in the KICAD_MANAGER_FRAME.
* Move the setting of the KIPRJMOD environment variable into class PROJECT,
so that it can be moved into a project variable soon, and out of FP_LIB_TABLE.
* Add the KIWAY_PLAYER which is associated with a particular PROJECT, and all
its child wxFrames and wxDialogs now have a Kiway() member function which
returns a KIWAY& that that window tree branch is in support of. This is like
wxWindows DNA in that child windows get this member with proper value at time
of construction.
* Anticipate some of the needs for milestones B) and C) and make code
adjustments now in an effort to reduce work in those milestones.
* No testing has been done for python scripting, since milestone C) has that
being largely reworked and re-thought-out.
2014-03-20 00:42:08 +00:00
|
|
|
#include <kiface_i.h>
|
2012-01-23 04:33:36 +00:00
|
|
|
#include <class_drawpanel.h>
|
|
|
|
#include <confirm.h>
|
2018-01-29 20:58:58 +00:00
|
|
|
#include <pcb_edit_frame.h>
|
2016-06-21 15:06:28 +00:00
|
|
|
#include <board_commit.h>
|
2017-02-24 12:26:25 +00:00
|
|
|
#include <view/view.h>
|
2011-09-23 13:57:12 +00:00
|
|
|
|
2012-01-23 04:33:36 +00:00
|
|
|
#include <class_board.h>
|
|
|
|
#include <class_zone.h>
|
2011-09-23 13:57:12 +00:00
|
|
|
|
2012-01-23 04:33:36 +00:00
|
|
|
#include <pcbnew.h>
|
|
|
|
#include <zones.h>
|
|
|
|
#include <pcbnew_id.h>
|
|
|
|
#include <protos.h>
|
|
|
|
#include <zones_functions_for_undo_redo.h>
|
2018-01-28 21:02:31 +00:00
|
|
|
#include <drc.h>
|
2017-11-15 17:33:06 +00:00
|
|
|
#include <connectivity_data.h>
|
2007-12-19 16:44:53 +00:00
|
|
|
|
2018-01-14 10:27:11 +00:00
|
|
|
#include <widgets/progress_reporter.h>
|
|
|
|
|
2017-11-30 16:22:45 +00:00
|
|
|
#include <zone_filler.h>
|
|
|
|
|
2008-01-10 20:53:41 +00:00
|
|
|
// Outline creation:
|
2011-01-21 19:30:59 +00:00
|
|
|
static void Abort_Zone_Create_Outline( EDA_DRAW_PANEL* Panel, wxDC* DC );
|
2011-02-03 19:27:28 +00:00
|
|
|
static void Show_New_Edge_While_Move_Mouse( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
|
|
|
|
const wxPoint& aPosition, bool aErase );
|
2007-12-30 18:20:51 +00:00
|
|
|
|
2007-12-29 19:15:58 +00:00
|
|
|
// Corner moving
|
2011-01-21 19:30:59 +00:00
|
|
|
static void Abort_Zone_Move_Corner_Or_Outlines( EDA_DRAW_PANEL* Panel, wxDC* DC );
|
2011-02-03 19:27:28 +00:00
|
|
|
static void Show_Zone_Corner_Or_Outline_While_Move_Mouse( EDA_DRAW_PANEL* aPanel,
|
|
|
|
wxDC* aDC,
|
|
|
|
const wxPoint& aPosition,
|
|
|
|
bool aErase );
|
2007-12-19 16:44:53 +00:00
|
|
|
|
2012-02-06 05:44:19 +00:00
|
|
|
// Local variables
|
2009-08-23 15:22:44 +00:00
|
|
|
static wxPoint s_CornerInitialPosition; // Used to abort a move corner command
|
2011-09-23 13:57:12 +00:00
|
|
|
static bool s_CornerIsNew; // Used to abort a move corner command (if it is a new corner, it must be deleted)
|
2011-10-17 20:01:27 +00:00
|
|
|
static bool s_AddCutoutToCurrentZone; // if true, the next outline will be added to s_CurrentZone
|
2011-09-23 13:57:12 +00:00
|
|
|
static ZONE_CONTAINER* s_CurrentZone; // if != NULL, these ZONE_CONTAINER params will be used for the next zone
|
|
|
|
static wxPoint s_CursorLastPosition; // in move zone outline, last cursor position. Used to calculate the move vector
|
2009-08-23 15:22:44 +00:00
|
|
|
static PICKED_ITEMS_LIST s_PickedList; // a picked list to save zones for undo/redo command
|
2012-08-04 09:43:27 +00:00
|
|
|
static PICKED_ITEMS_LIST s_AuxiliaryList; // a picked list to store zones that are deleted or added when combined
|
2007-12-19 16:44:53 +00:00
|
|
|
|
|
|
|
|
2012-02-06 05:44:19 +00:00
|
|
|
void PCB_EDIT_FRAME::Add_Similar_Zone( wxDC* DC, ZONE_CONTAINER* aZone )
|
2008-01-04 12:27:16 +00:00
|
|
|
{
|
2012-02-06 05:44:19 +00:00
|
|
|
if( !aZone )
|
2008-10-17 06:17:48 +00:00
|
|
|
return;
|
2011-10-17 20:01:27 +00:00
|
|
|
|
2008-01-04 12:27:16 +00:00
|
|
|
s_AddCutoutToCurrentZone = false;
|
2012-02-06 05:44:19 +00:00
|
|
|
s_CurrentZone = aZone;
|
2008-10-19 18:18:45 +00:00
|
|
|
|
2012-02-06 05:44:19 +00:00
|
|
|
// set zone settings to the current zone
|
|
|
|
ZONE_SETTINGS zoneInfo = GetZoneSettings();
|
|
|
|
zoneInfo << *aZone;
|
|
|
|
SetZoneSettings( zoneInfo );
|
2008-10-19 18:18:45 +00:00
|
|
|
|
2012-02-06 05:44:19 +00:00
|
|
|
// Use the general event handler to set others params (like toolbar)
|
2008-01-04 12:27:16 +00:00
|
|
|
wxCommandEvent evt;
|
2012-07-13 18:55:29 +00:00
|
|
|
evt.SetId( aZone->GetIsKeepout() ? ID_PCB_KEEPOUT_AREA_BUTT : ID_PCB_ZONES_BUTT );
|
2011-02-23 21:34:28 +00:00
|
|
|
OnSelectTool( evt );
|
2008-01-04 12:27:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-02-06 05:44:19 +00:00
|
|
|
void PCB_EDIT_FRAME::Add_Zone_Cutout( wxDC* DC, ZONE_CONTAINER* aZone )
|
2008-01-04 12:27:16 +00:00
|
|
|
{
|
2012-02-06 05:44:19 +00:00
|
|
|
if( !aZone )
|
2008-10-17 06:17:48 +00:00
|
|
|
return;
|
2011-09-07 19:41:04 +00:00
|
|
|
|
2008-01-04 12:27:16 +00:00
|
|
|
s_AddCutoutToCurrentZone = true;
|
2012-02-06 05:44:19 +00:00
|
|
|
s_CurrentZone = aZone;
|
2008-10-19 18:18:45 +00:00
|
|
|
|
2012-02-06 05:44:19 +00:00
|
|
|
// set zones setup to the current zone
|
|
|
|
ZONE_SETTINGS zoneInfo = GetZoneSettings();
|
|
|
|
zoneInfo << *aZone;
|
|
|
|
SetZoneSettings( zoneInfo );
|
2008-10-19 18:18:45 +00:00
|
|
|
|
2012-02-06 05:44:19 +00:00
|
|
|
// Use the general event handle to set others params (like toolbar)
|
2008-01-04 12:27:16 +00:00
|
|
|
wxCommandEvent evt;
|
2012-07-13 18:55:29 +00:00
|
|
|
evt.SetId( aZone->GetIsKeepout() ? ID_PCB_KEEPOUT_AREA_BUTT : ID_PCB_ZONES_BUTT );
|
2011-02-23 21:34:28 +00:00
|
|
|
OnSelectTool( evt );
|
2008-01-04 12:27:16 +00:00
|
|
|
}
|
|
|
|
|
2007-12-19 16:44:53 +00:00
|
|
|
|
2012-06-05 11:44:22 +00:00
|
|
|
void PCB_EDIT_FRAME::duplicateZone( wxDC* aDC, ZONE_CONTAINER* aZone )
|
|
|
|
{
|
2016-05-31 08:27:52 +00:00
|
|
|
ZONE_CONTAINER* newZone = new ZONE_CONTAINER( *aZone );
|
2012-06-05 11:44:22 +00:00
|
|
|
newZone->UnFill();
|
|
|
|
ZONE_SETTINGS zoneSettings;
|
|
|
|
zoneSettings << *aZone;
|
|
|
|
|
2012-07-13 18:55:29 +00:00
|
|
|
bool success;
|
|
|
|
|
|
|
|
if( aZone->GetIsKeepout() )
|
|
|
|
success = InvokeKeepoutAreaEditor( this, &zoneSettings );
|
|
|
|
else if( aZone->IsOnCopperLayer() )
|
|
|
|
success = InvokeCopperZonesEditor( this, &zoneSettings );
|
|
|
|
else
|
|
|
|
success = InvokeNonCopperZonesEditor( this, aZone, &zoneSettings );
|
|
|
|
|
2018-04-29 19:26:56 +00:00
|
|
|
// If the new zone is on the same layer as the the initial zone we'll end up combining
|
|
|
|
// them which will result in a no-op. Might as well exit here.
|
2017-09-27 07:59:12 +00:00
|
|
|
if( success )
|
2015-05-10 19:10:10 +00:00
|
|
|
{
|
2017-09-27 07:59:12 +00:00
|
|
|
if( aZone->GetIsKeepout() && ( aZone->GetLayerSet() == zoneSettings.m_Layers ) )
|
|
|
|
{
|
|
|
|
DisplayErrorMessage(
|
|
|
|
this, _( "The duplicated zone cannot be on the same layers as the original zone." ) );
|
|
|
|
success = false;
|
|
|
|
}
|
|
|
|
else if( !aZone->GetIsKeepout() && ( aZone->GetLayer() == zoneSettings.m_CurrentZone_Layer ) )
|
|
|
|
{
|
|
|
|
DisplayErrorMessage(
|
|
|
|
this, _( "The duplicated zone cannot be on the same layer as the original zone." ) );
|
|
|
|
success = false;
|
|
|
|
}
|
2015-05-10 19:10:10 +00:00
|
|
|
}
|
|
|
|
|
2012-07-13 18:55:29 +00:00
|
|
|
if( success )
|
2012-06-05 11:44:22 +00:00
|
|
|
{
|
|
|
|
zoneSettings.ExportSetting( *newZone );
|
2017-03-07 12:06:00 +00:00
|
|
|
newZone->Hatch();
|
2012-06-05 11:44:22 +00:00
|
|
|
|
2012-08-04 09:43:27 +00:00
|
|
|
s_AuxiliaryList.ClearListAndDeleteItems();
|
2012-06-05 11:44:22 +00:00
|
|
|
s_PickedList.ClearListAndDeleteItems();
|
2014-02-25 10:47:27 +00:00
|
|
|
SaveCopyOfZones( s_PickedList, GetBoard(), newZone->GetNetCode(), newZone->GetLayer() );
|
2012-06-05 11:44:22 +00:00
|
|
|
GetBoard()->Add( newZone );
|
|
|
|
|
|
|
|
ITEM_PICKER picker( newZone, UR_NEW );
|
|
|
|
s_PickedList.PushItem( picker );
|
|
|
|
|
|
|
|
GetScreen()->SetCurItem( NULL ); // This outline may be deleted when merging outlines
|
|
|
|
|
|
|
|
// Combine zones if possible
|
2012-08-04 09:43:27 +00:00
|
|
|
GetBoard()->OnAreaPolygonModified( &s_AuxiliaryList, newZone );
|
2012-06-05 11:44:22 +00:00
|
|
|
|
|
|
|
// Redraw zones
|
|
|
|
GetBoard()->RedrawAreasOutlines( m_canvas, aDC, GR_OR, newZone->GetLayer() );
|
|
|
|
GetBoard()->RedrawFilledAreas( m_canvas, aDC, GR_OR, newZone->GetLayer() );
|
|
|
|
|
2017-12-08 10:25:13 +00:00
|
|
|
DRC drc( this );
|
|
|
|
|
2012-06-05 11:44:22 +00:00
|
|
|
if( GetBoard()->GetAreaIndex( newZone ) >= 0
|
2017-12-08 10:25:13 +00:00
|
|
|
&& drc.TestZoneToZoneOutline( newZone, true ) )
|
2012-06-05 11:44:22 +00:00
|
|
|
{
|
2015-12-08 12:02:44 +00:00
|
|
|
DisplayInfoMessage( this, _( "Warning: The new zone fails DRC" ) );
|
2012-06-05 11:44:22 +00:00
|
|
|
}
|
|
|
|
|
2012-08-04 09:43:27 +00:00
|
|
|
UpdateCopyOfZonesList( s_PickedList, s_AuxiliaryList, GetBoard() );
|
2012-06-05 11:44:22 +00:00
|
|
|
SaveCopyInUndoList( s_PickedList, UR_UNSPECIFIED );
|
|
|
|
s_PickedList.ClearItemsList();
|
|
|
|
|
|
|
|
OnModify();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
delete newZone;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-09-07 19:41:04 +00:00
|
|
|
int PCB_EDIT_FRAME::Delete_LastCreatedCorner( wxDC* DC )
|
2007-12-19 16:44:53 +00:00
|
|
|
{
|
2009-01-05 05:21:35 +00:00
|
|
|
ZONE_CONTAINER* zone = GetBoard()->m_CurrentZoneContour;
|
2007-12-19 16:44:53 +00:00
|
|
|
|
2012-02-06 05:44:19 +00:00
|
|
|
if( !zone )
|
2008-01-31 20:53:44 +00:00
|
|
|
return 0;
|
2007-12-19 16:44:53 +00:00
|
|
|
|
2012-02-06 05:44:19 +00:00
|
|
|
if( !zone->GetNumCorners() )
|
2008-01-31 20:53:44 +00:00
|
|
|
return 0;
|
2007-12-19 16:44:53 +00:00
|
|
|
|
2011-12-22 13:28:11 +00:00
|
|
|
zone->DrawWhileCreateOutline( m_canvas, DC, GR_XOR );
|
2007-12-19 16:44:53 +00:00
|
|
|
|
2008-02-01 11:01:32 +00:00
|
|
|
if( zone->GetNumCorners() > 2 )
|
2007-12-19 16:44:53 +00:00
|
|
|
{
|
2017-03-07 12:06:00 +00:00
|
|
|
zone->Outline()->RemoveVertex( zone->GetNumCorners() - 1 );
|
2011-02-03 19:27:28 +00:00
|
|
|
|
2011-12-22 13:28:11 +00:00
|
|
|
if( m_canvas->IsMouseCaptured() )
|
2011-12-29 20:11:42 +00:00
|
|
|
m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
|
2007-12-19 16:44:53 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-12-22 13:28:11 +00:00
|
|
|
m_canvas->SetMouseCapture( NULL, NULL );
|
2007-12-19 16:44:53 +00:00
|
|
|
SetCurItem( NULL );
|
2008-01-31 20:53:44 +00:00
|
|
|
zone->RemoveAllContours();
|
2011-12-21 13:42:02 +00:00
|
|
|
zone->ClearFlags();
|
2007-12-19 16:44:53 +00:00
|
|
|
}
|
2011-09-07 19:41:04 +00:00
|
|
|
|
2008-01-31 20:53:44 +00:00
|
|
|
return zone->GetNumCorners();
|
2007-12-19 16:44:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2007-12-29 19:15:58 +00:00
|
|
|
* Function Abort_Zone_Create_Outline
|
2008-01-20 19:55:22 +00:00
|
|
|
* cancels the Begin_Zone command if at least one EDGE_ZONE was created.
|
2007-12-19 16:44:53 +00:00
|
|
|
*/
|
2011-09-07 19:41:04 +00:00
|
|
|
static void Abort_Zone_Create_Outline( EDA_DRAW_PANEL* Panel, wxDC* DC )
|
2007-12-19 16:44:53 +00:00
|
|
|
{
|
2011-03-01 19:26:17 +00:00
|
|
|
PCB_EDIT_FRAME* pcbframe = (PCB_EDIT_FRAME*) Panel->GetParent();
|
|
|
|
ZONE_CONTAINER* zone = pcbframe->GetBoard()->m_CurrentZoneContour;
|
2007-12-19 16:44:53 +00:00
|
|
|
|
2008-01-31 20:53:44 +00:00
|
|
|
if( zone )
|
2007-12-19 16:44:53 +00:00
|
|
|
{
|
2008-01-31 20:53:44 +00:00
|
|
|
zone->DrawWhileCreateOutline( Panel, DC, GR_XOR );
|
|
|
|
zone->RemoveAllContours();
|
2014-03-31 18:14:01 +00:00
|
|
|
if( zone->IsNew() )
|
|
|
|
{
|
|
|
|
delete zone;
|
|
|
|
pcbframe->GetBoard()->m_CurrentZoneContour = NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
zone->ClearFlags();
|
2007-12-19 16:44:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pcbframe->SetCurItem( NULL );
|
2008-01-04 12:27:16 +00:00
|
|
|
s_AddCutoutToCurrentZone = false;
|
|
|
|
s_CurrentZone = NULL;
|
2011-02-13 09:07:30 +00:00
|
|
|
Panel->SetMouseCapture( NULL, NULL );
|
2007-12-19 16:44:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-02-06 05:44:19 +00:00
|
|
|
void PCB_EDIT_FRAME::Start_Move_Zone_Corner( wxDC* DC, ZONE_CONTAINER* aZone,
|
2011-09-07 19:41:04 +00:00
|
|
|
int corner_id, bool IsNewCorner )
|
2007-12-29 19:15:58 +00:00
|
|
|
{
|
2012-02-06 05:44:19 +00:00
|
|
|
if( aZone->IsOnCopperLayer() ) // Show the Net
|
2007-12-30 18:20:51 +00:00
|
|
|
{
|
2011-09-14 20:04:58 +00:00
|
|
|
if( GetBoard()->IsHighLightNetON() && DC )
|
2008-09-26 19:51:36 +00:00
|
|
|
{
|
2011-10-17 20:01:27 +00:00
|
|
|
HighLight( DC ); // Remove old highlight selection
|
2008-09-26 19:51:36 +00:00
|
|
|
}
|
2007-12-30 18:20:51 +00:00
|
|
|
|
2012-02-06 05:44:19 +00:00
|
|
|
ZONE_SETTINGS zoneInfo = GetZoneSettings();
|
2014-02-25 10:47:27 +00:00
|
|
|
zoneInfo.m_NetcodeSelection = aZone->GetNetCode();
|
2012-02-06 05:44:19 +00:00
|
|
|
SetZoneSettings( zoneInfo );
|
|
|
|
|
2014-02-25 10:47:27 +00:00
|
|
|
GetBoard()->SetHighLightNet( aZone->GetNetCode() );
|
2011-09-07 19:41:04 +00:00
|
|
|
|
2008-09-26 19:51:36 +00:00
|
|
|
if( DC )
|
2011-10-17 20:01:27 +00:00
|
|
|
HighLight( DC );
|
2008-09-26 19:51:36 +00:00
|
|
|
}
|
2007-12-30 18:20:51 +00:00
|
|
|
|
2009-08-23 15:22:44 +00:00
|
|
|
|
|
|
|
// Prepare copy of old zones, for undo/redo.
|
|
|
|
// if the corner is new, remove it from list, save and insert it in list
|
2017-03-07 12:06:00 +00:00
|
|
|
VECTOR2I corner = aZone->Outline()->Vertex( corner_id );
|
2009-08-23 15:22:44 +00:00
|
|
|
|
|
|
|
if ( IsNewCorner )
|
2017-03-07 12:06:00 +00:00
|
|
|
aZone->Outline()->RemoveVertex( corner_id );
|
2009-08-23 15:22:44 +00:00
|
|
|
|
2012-08-04 09:43:27 +00:00
|
|
|
s_AuxiliaryList.ClearListAndDeleteItems();
|
2009-08-23 15:22:44 +00:00
|
|
|
s_PickedList.ClearListAndDeleteItems();
|
|
|
|
|
2014-02-25 10:47:27 +00:00
|
|
|
SaveCopyOfZones( s_PickedList, GetBoard(), aZone->GetNetCode(), aZone->GetLayer() );
|
2011-09-07 19:41:04 +00:00
|
|
|
|
2009-08-23 15:22:44 +00:00
|
|
|
if ( IsNewCorner )
|
2017-03-07 12:06:00 +00:00
|
|
|
aZone->Outline()->InsertVertex(corner_id-1, corner );
|
2009-08-23 15:22:44 +00:00
|
|
|
|
2012-02-06 05:44:19 +00:00
|
|
|
aZone->SetFlags( IN_EDIT );
|
2011-12-22 13:28:11 +00:00
|
|
|
m_canvas->SetMouseCapture( Show_Zone_Corner_Or_Outline_While_Move_Mouse,
|
2011-12-21 13:42:02 +00:00
|
|
|
Abort_Zone_Move_Corner_Or_Outlines );
|
2017-03-07 12:06:00 +00:00
|
|
|
s_CornerInitialPosition = static_cast<wxPoint>( aZone->GetCornerPosition( corner_id ) );
|
2007-12-30 18:20:51 +00:00
|
|
|
s_CornerIsNew = IsNewCorner;
|
2008-01-04 12:27:16 +00:00
|
|
|
s_AddCutoutToCurrentZone = false;
|
|
|
|
s_CurrentZone = NULL;
|
2007-12-29 19:15:58 +00:00
|
|
|
}
|
|
|
|
|
2008-01-31 20:53:44 +00:00
|
|
|
|
2011-09-07 19:41:04 +00:00
|
|
|
void PCB_EDIT_FRAME::Start_Move_Zone_Drag_Outline_Edge( wxDC* DC,
|
2012-02-06 05:44:19 +00:00
|
|
|
ZONE_CONTAINER* aZone,
|
2011-09-07 19:41:04 +00:00
|
|
|
int corner_id )
|
2008-02-01 21:30:45 +00:00
|
|
|
{
|
2012-02-06 05:44:19 +00:00
|
|
|
aZone->SetFlags( IS_DRAGGED );
|
2013-03-20 14:50:12 +00:00
|
|
|
aZone->SetSelectedCorner( corner_id );
|
2011-12-22 13:28:11 +00:00
|
|
|
m_canvas->SetMouseCapture( Show_Zone_Corner_Or_Outline_While_Move_Mouse,
|
2011-09-07 19:41:04 +00:00
|
|
|
Abort_Zone_Move_Corner_Or_Outlines );
|
2013-08-03 05:15:23 +00:00
|
|
|
s_CursorLastPosition = s_CornerInitialPosition = GetCrossHairPosition();
|
2008-02-01 21:30:45 +00:00
|
|
|
s_AddCutoutToCurrentZone = false;
|
|
|
|
s_CurrentZone = NULL;
|
2009-08-23 15:22:44 +00:00
|
|
|
|
|
|
|
s_PickedList.ClearListAndDeleteItems();
|
2012-08-04 09:43:27 +00:00
|
|
|
s_AuxiliaryList.ClearListAndDeleteItems();
|
2014-02-25 10:47:27 +00:00
|
|
|
SaveCopyOfZones( s_PickedList, GetBoard(), aZone->GetNetCode(), aZone->GetLayer() );
|
2008-02-01 21:30:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-02-06 05:44:19 +00:00
|
|
|
void PCB_EDIT_FRAME::Start_Move_Zone_Outlines( wxDC* DC, ZONE_CONTAINER* aZone )
|
2008-01-16 20:37:50 +00:00
|
|
|
{
|
2012-02-06 05:44:19 +00:00
|
|
|
// Show the Net
|
|
|
|
if( aZone->IsOnCopperLayer() ) // Show the Net
|
2008-01-16 20:37:50 +00:00
|
|
|
{
|
2011-09-14 20:04:58 +00:00
|
|
|
if( GetBoard()->IsHighLightNetON() )
|
2008-09-26 19:51:36 +00:00
|
|
|
{
|
2011-10-17 20:01:27 +00:00
|
|
|
HighLight( DC ); // Remove old highlight selection
|
2008-09-26 19:51:36 +00:00
|
|
|
}
|
2008-01-16 20:37:50 +00:00
|
|
|
|
2012-02-06 05:44:19 +00:00
|
|
|
ZONE_SETTINGS zoneInfo = GetZoneSettings();
|
2014-02-25 10:47:27 +00:00
|
|
|
zoneInfo.m_NetcodeSelection = aZone->GetNetCode();
|
2012-02-06 05:44:19 +00:00
|
|
|
SetZoneSettings( zoneInfo );
|
|
|
|
|
2014-02-25 10:47:27 +00:00
|
|
|
GetBoard()->SetHighLightNet( aZone->GetNetCode() );
|
2011-10-17 20:01:27 +00:00
|
|
|
HighLight( DC );
|
2008-09-26 19:51:36 +00:00
|
|
|
}
|
2008-01-16 20:37:50 +00:00
|
|
|
|
2009-08-23 15:22:44 +00:00
|
|
|
s_PickedList.ClearListAndDeleteItems();
|
2012-08-04 09:43:27 +00:00
|
|
|
s_AuxiliaryList.ClearListAndDeleteItems();
|
2014-02-25 10:47:27 +00:00
|
|
|
SaveCopyOfZones( s_PickedList, GetBoard(), aZone->GetNetCode(), aZone->GetLayer() );
|
2009-08-23 15:22:44 +00:00
|
|
|
|
2012-02-06 05:44:19 +00:00
|
|
|
aZone->SetFlags( IS_MOVED );
|
2011-12-22 13:28:11 +00:00
|
|
|
m_canvas->SetMouseCapture( Show_Zone_Corner_Or_Outline_While_Move_Mouse,
|
2011-09-07 19:41:04 +00:00
|
|
|
Abort_Zone_Move_Corner_Or_Outlines );
|
2013-08-03 05:15:23 +00:00
|
|
|
s_CursorLastPosition = s_CornerInitialPosition = GetCrossHairPosition();
|
2008-01-16 20:37:50 +00:00
|
|
|
s_CornerIsNew = false;
|
|
|
|
s_AddCutoutToCurrentZone = false;
|
|
|
|
s_CurrentZone = NULL;
|
|
|
|
}
|
|
|
|
|
2007-12-30 18:20:51 +00:00
|
|
|
|
2012-02-06 05:44:19 +00:00
|
|
|
void PCB_EDIT_FRAME::End_Move_Zone_Corner_Or_Outlines( wxDC* DC, ZONE_CONTAINER* aZone )
|
2007-12-29 19:15:58 +00:00
|
|
|
{
|
2012-02-06 05:44:19 +00:00
|
|
|
aZone->ClearFlags();
|
2011-12-22 13:28:11 +00:00
|
|
|
m_canvas->SetMouseCapture( NULL, NULL );
|
2011-02-11 20:48:13 +00:00
|
|
|
|
2008-01-31 20:53:44 +00:00
|
|
|
if( DC )
|
2012-02-06 05:44:19 +00:00
|
|
|
aZone->Draw( m_canvas, DC, GR_OR );
|
2011-02-11 20:48:13 +00:00
|
|
|
|
2010-02-19 13:23:58 +00:00
|
|
|
OnModify();
|
2008-01-04 12:27:16 +00:00
|
|
|
s_AddCutoutToCurrentZone = false;
|
|
|
|
s_CurrentZone = NULL;
|
|
|
|
|
2008-01-31 20:53:44 +00:00
|
|
|
SetCurItem( NULL ); // This outline can be deleted when merging outlines
|
2008-01-04 12:27:16 +00:00
|
|
|
|
2012-02-06 05:44:19 +00:00
|
|
|
// Combine zones if possible
|
2012-08-04 09:43:27 +00:00
|
|
|
GetBoard()->OnAreaPolygonModified( &s_AuxiliaryList, aZone );
|
2011-12-22 13:28:11 +00:00
|
|
|
m_canvas->Refresh();
|
2008-05-02 06:27:06 +00:00
|
|
|
|
2012-02-06 05:44:19 +00:00
|
|
|
int ii = GetBoard()->GetAreaIndex( aZone ); // test if aZone exists
|
2011-09-07 19:41:04 +00:00
|
|
|
|
2008-01-31 20:53:44 +00:00
|
|
|
if( ii < 0 )
|
2012-02-06 05:44:19 +00:00
|
|
|
aZone = NULL; // was removed by combining zones
|
2008-05-02 06:27:06 +00:00
|
|
|
|
2012-08-04 09:43:27 +00:00
|
|
|
UpdateCopyOfZonesList( s_PickedList, s_AuxiliaryList, GetBoard() );
|
2009-08-23 15:22:44 +00:00
|
|
|
SaveCopyInUndoList(s_PickedList, UR_UNSPECIFIED);
|
|
|
|
s_PickedList.ClearItemsList(); // s_ItemsListPicker is no more owner of picked items
|
|
|
|
|
2017-12-08 10:25:13 +00:00
|
|
|
DRC drc( this );
|
|
|
|
int error_count = drc.TestZoneToZoneOutline( aZone, true );
|
2011-09-07 19:41:04 +00:00
|
|
|
|
2008-01-31 20:53:44 +00:00
|
|
|
if( error_count )
|
|
|
|
{
|
2017-07-20 14:06:41 +00:00
|
|
|
DisplayErrorMessage( this, _( "Area: DRC outline error" ) );
|
2008-01-31 20:53:44 +00:00
|
|
|
}
|
2008-01-04 12:27:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-02-06 05:44:19 +00:00
|
|
|
void PCB_EDIT_FRAME::Remove_Zone_Corner( wxDC* DC, ZONE_CONTAINER* aZone )
|
2008-01-04 12:27:16 +00:00
|
|
|
{
|
2010-02-19 13:23:58 +00:00
|
|
|
OnModify();
|
2008-01-10 20:53:41 +00:00
|
|
|
|
2017-03-07 12:06:00 +00:00
|
|
|
if( aZone->Outline()->TotalVertices() <= 3 )
|
2008-01-31 20:53:44 +00:00
|
|
|
{
|
2012-02-06 05:44:19 +00:00
|
|
|
m_canvas->RefreshDrawingRect( aZone->GetBoundingBox() );
|
2011-09-07 19:41:04 +00:00
|
|
|
|
2008-09-26 19:51:36 +00:00
|
|
|
if( DC )
|
2008-11-28 20:10:05 +00:00
|
|
|
{ // Remove the full zone because this is no more an area
|
2012-02-06 05:44:19 +00:00
|
|
|
aZone->UnFill();
|
|
|
|
aZone->DrawFilledArea( m_canvas, DC, GR_XOR );
|
2008-09-26 19:51:36 +00:00
|
|
|
}
|
2011-09-07 19:41:04 +00:00
|
|
|
|
2012-02-06 05:44:19 +00:00
|
|
|
GetBoard()->Delete( aZone );
|
2008-01-31 20:53:44 +00:00
|
|
|
return;
|
|
|
|
}
|
2008-01-04 12:27:16 +00:00
|
|
|
|
2017-03-13 03:19:33 +00:00
|
|
|
PCB_LAYER_ID layer = aZone->GetLayer();
|
2008-01-04 12:27:16 +00:00
|
|
|
|
2008-09-26 19:51:36 +00:00
|
|
|
if( DC )
|
|
|
|
{
|
2011-12-22 13:28:11 +00:00
|
|
|
GetBoard()->RedrawAreasOutlines( m_canvas, DC, GR_XOR, layer );
|
|
|
|
GetBoard()->RedrawFilledAreas( m_canvas, DC, GR_XOR, layer );
|
2008-09-26 19:51:36 +00:00
|
|
|
}
|
2008-01-31 20:53:44 +00:00
|
|
|
|
2012-08-04 09:43:27 +00:00
|
|
|
s_AuxiliaryList.ClearListAndDeleteItems();
|
2009-08-23 15:22:44 +00:00
|
|
|
s_PickedList. ClearListAndDeleteItems();
|
2014-02-25 10:47:27 +00:00
|
|
|
SaveCopyOfZones( s_PickedList, GetBoard(), aZone->GetNetCode(), aZone->GetLayer() );
|
2017-03-07 12:06:00 +00:00
|
|
|
aZone->Outline()->RemoveVertex( aZone->GetSelectedCorner() );
|
2008-01-04 12:27:16 +00:00
|
|
|
|
2012-02-06 05:44:19 +00:00
|
|
|
// modify zones outlines according to the new aZone shape
|
2012-08-04 09:43:27 +00:00
|
|
|
GetBoard()->OnAreaPolygonModified( &s_AuxiliaryList, aZone );
|
2011-09-07 19:41:04 +00:00
|
|
|
|
2008-09-26 19:51:36 +00:00
|
|
|
if( DC )
|
|
|
|
{
|
2011-12-22 13:28:11 +00:00
|
|
|
GetBoard()->RedrawAreasOutlines( m_canvas, DC, GR_OR, layer );
|
|
|
|
GetBoard()->RedrawFilledAreas( m_canvas, DC, GR_OR, layer );
|
2008-09-26 19:51:36 +00:00
|
|
|
}
|
2008-01-31 20:53:44 +00:00
|
|
|
|
2012-08-04 09:43:27 +00:00
|
|
|
UpdateCopyOfZonesList( s_PickedList, s_AuxiliaryList, GetBoard() );
|
2009-08-23 15:22:44 +00:00
|
|
|
SaveCopyInUndoList(s_PickedList, UR_UNSPECIFIED);
|
|
|
|
s_PickedList.ClearItemsList(); // s_ItemsListPicker is no more owner of picked items
|
|
|
|
|
2012-02-06 05:44:19 +00:00
|
|
|
int ii = GetBoard()->GetAreaIndex( aZone ); // test if aZone exists
|
2011-09-07 19:41:04 +00:00
|
|
|
|
2008-01-31 20:53:44 +00:00
|
|
|
if( ii < 0 )
|
2012-02-06 05:44:19 +00:00
|
|
|
aZone = NULL; // aZone does not exist anymore, after combining zones
|
2011-09-07 19:41:04 +00:00
|
|
|
|
2017-12-08 10:25:13 +00:00
|
|
|
DRC drc( this );
|
|
|
|
int error_count = drc.TestZoneToZoneOutline( aZone, true );
|
2011-09-07 19:41:04 +00:00
|
|
|
|
2008-01-31 20:53:44 +00:00
|
|
|
if( error_count )
|
|
|
|
{
|
2017-07-20 14:06:41 +00:00
|
|
|
DisplayErrorMessage( this, _( "Area: DRC outline error" ) );
|
2008-01-31 20:53:44 +00:00
|
|
|
}
|
2007-12-29 19:15:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2008-01-16 20:37:50 +00:00
|
|
|
* Function Abort_Zone_Move_Corner_Or_Outlines
|
2007-12-29 19:15:58 +00:00
|
|
|
* cancels the Begin_Zone state if at least one EDGE_ZONE has been created.
|
|
|
|
*/
|
2011-09-07 19:41:04 +00:00
|
|
|
void Abort_Zone_Move_Corner_Or_Outlines( EDA_DRAW_PANEL* Panel, wxDC* DC )
|
2007-12-29 19:15:58 +00:00
|
|
|
{
|
2011-03-01 19:26:17 +00:00
|
|
|
PCB_EDIT_FRAME* pcbframe = (PCB_EDIT_FRAME*) Panel->GetParent();
|
2012-02-06 05:44:19 +00:00
|
|
|
ZONE_CONTAINER* zone = (ZONE_CONTAINER*) pcbframe->GetCurItem();
|
2007-12-30 18:20:51 +00:00
|
|
|
|
2012-02-06 05:44:19 +00:00
|
|
|
if( zone->IsMoving() )
|
2008-01-31 20:53:44 +00:00
|
|
|
{
|
|
|
|
wxPoint offset;
|
|
|
|
offset = s_CornerInitialPosition - s_CursorLastPosition;
|
2012-02-06 05:44:19 +00:00
|
|
|
zone->Move( offset );
|
2008-01-31 20:53:44 +00:00
|
|
|
}
|
2012-02-06 05:44:19 +00:00
|
|
|
else if( zone->IsDragging() )
|
2008-02-01 21:30:45 +00:00
|
|
|
{
|
2014-05-04 17:08:36 +00:00
|
|
|
wxPoint offset = s_CornerInitialPosition - s_CursorLastPosition;
|
|
|
|
int selection = zone->GetSelectedCorner();
|
|
|
|
zone->MoveEdge( offset, selection );
|
2008-02-01 21:30:45 +00:00
|
|
|
}
|
2008-01-31 20:53:44 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
if( s_CornerIsNew )
|
|
|
|
{
|
2017-03-07 12:06:00 +00:00
|
|
|
zone->Outline()->RemoveVertex( zone->GetSelectedCorner() );
|
2008-01-31 20:53:44 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
wxPoint pos = s_CornerInitialPosition;
|
2017-03-07 12:06:00 +00:00
|
|
|
zone->Outline()->Vertex( zone->GetSelectedCorner() ) = pos;
|
2008-01-31 20:53:44 +00:00
|
|
|
}
|
|
|
|
}
|
2008-05-02 06:27:06 +00:00
|
|
|
|
2011-02-13 09:07:30 +00:00
|
|
|
Panel->SetMouseCapture( NULL, NULL );
|
2012-08-04 09:43:27 +00:00
|
|
|
s_AuxiliaryList.ClearListAndDeleteItems();
|
2009-08-23 15:22:44 +00:00
|
|
|
s_PickedList. ClearListAndDeleteItems();
|
2008-05-02 06:27:06 +00:00
|
|
|
Panel->Refresh();
|
|
|
|
|
2007-12-29 19:15:58 +00:00
|
|
|
pcbframe->SetCurItem( NULL );
|
2012-02-06 05:44:19 +00:00
|
|
|
zone->ClearFlags();
|
2008-01-04 12:27:16 +00:00
|
|
|
s_AddCutoutToCurrentZone = false;
|
|
|
|
s_CurrentZone = NULL;
|
2007-12-29 19:15:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-02-06 05:44:19 +00:00
|
|
|
/// Redraws the zone outline when moving a corner according to the cursor position
|
2011-02-03 19:27:28 +00:00
|
|
|
void Show_Zone_Corner_Or_Outline_While_Move_Mouse( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
|
|
|
|
const wxPoint& aPosition, bool aErase )
|
2007-12-29 19:15:58 +00:00
|
|
|
{
|
2011-03-01 19:26:17 +00:00
|
|
|
PCB_EDIT_FRAME* pcbframe = (PCB_EDIT_FRAME*) aPanel->GetParent();
|
|
|
|
ZONE_CONTAINER* zone = (ZONE_CONTAINER*) pcbframe->GetCurItem();
|
2007-12-29 19:15:58 +00:00
|
|
|
|
2012-02-06 05:44:19 +00:00
|
|
|
if( aErase ) // Undraw edge in old position
|
2007-12-29 19:15:58 +00:00
|
|
|
{
|
2011-02-03 19:27:28 +00:00
|
|
|
zone->Draw( aPanel, aDC, GR_XOR );
|
2007-12-29 19:15:58 +00:00
|
|
|
}
|
|
|
|
|
2013-08-03 05:15:23 +00:00
|
|
|
wxPoint pos = pcbframe->GetCrossHairPosition();
|
2011-02-03 19:27:28 +00:00
|
|
|
|
2011-12-21 13:42:02 +00:00
|
|
|
if( zone->IsMoving() )
|
2008-01-31 20:53:44 +00:00
|
|
|
{
|
|
|
|
wxPoint offset;
|
2008-02-01 21:30:45 +00:00
|
|
|
offset = pos - s_CursorLastPosition;
|
|
|
|
zone->Move( offset );
|
|
|
|
s_CursorLastPosition = pos;
|
|
|
|
}
|
2011-12-21 13:42:02 +00:00
|
|
|
else if( zone->IsDragging() )
|
2008-02-01 21:30:45 +00:00
|
|
|
{
|
2014-05-04 17:08:36 +00:00
|
|
|
wxPoint offset = pos - s_CursorLastPosition;
|
|
|
|
int selection = zone->GetSelectedCorner();
|
|
|
|
zone->MoveEdge( offset, selection );
|
2008-01-31 20:53:44 +00:00
|
|
|
s_CursorLastPosition = pos;
|
|
|
|
}
|
|
|
|
else
|
2011-09-07 19:41:04 +00:00
|
|
|
{
|
2017-03-07 12:06:00 +00:00
|
|
|
zone->Outline()->Vertex( zone->GetSelectedCorner() ) = pos;
|
2011-09-07 19:41:04 +00:00
|
|
|
}
|
2008-01-16 20:37:50 +00:00
|
|
|
|
2011-02-03 19:27:28 +00:00
|
|
|
zone->Draw( aPanel, aDC, GR_XOR );
|
2007-12-29 19:15:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-10-17 20:01:27 +00:00
|
|
|
|
2011-09-07 19:41:04 +00:00
|
|
|
int PCB_EDIT_FRAME::Begin_Zone( wxDC* DC )
|
2007-12-19 16:44:53 +00:00
|
|
|
{
|
2012-02-06 05:44:19 +00:00
|
|
|
ZONE_SETTINGS zoneInfo = GetZoneSettings();
|
|
|
|
|
2008-10-17 06:17:48 +00:00
|
|
|
// verify if s_CurrentZone exists (could be deleted since last selection) :
|
2008-01-31 20:53:44 +00:00
|
|
|
int ii;
|
2009-01-05 05:21:35 +00:00
|
|
|
for( ii = 0; ii < GetBoard()->GetAreaCount(); ii++ )
|
2007-12-30 18:20:51 +00:00
|
|
|
{
|
2009-01-05 05:21:35 +00:00
|
|
|
if( s_CurrentZone == GetBoard()->GetArea( ii ) )
|
2008-01-04 12:27:16 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2009-01-05 05:21:35 +00:00
|
|
|
if( ii >= GetBoard()->GetAreaCount() ) // Not found: could be deleted since last selection
|
2008-01-04 12:27:16 +00:00
|
|
|
{
|
|
|
|
s_AddCutoutToCurrentZone = false;
|
|
|
|
s_CurrentZone = NULL;
|
|
|
|
}
|
2007-12-30 18:20:51 +00:00
|
|
|
|
2014-03-31 18:14:01 +00:00
|
|
|
ZONE_CONTAINER* zone = GetBoard()->m_CurrentZoneContour;
|
|
|
|
|
|
|
|
// Verify if a new zone is allowed on this layer:
|
|
|
|
if( zone == NULL )
|
2012-07-13 18:55:29 +00:00
|
|
|
{
|
2014-04-02 13:38:59 +00:00
|
|
|
if( GetToolId() == ID_PCB_KEEPOUT_AREA_BUTT && !IsCopperLayer( GetActiveLayer() ) )
|
2012-07-13 18:55:29 +00:00
|
|
|
{
|
2017-07-20 14:06:41 +00:00
|
|
|
DisplayErrorMessage( this,
|
2012-07-13 18:55:29 +00:00
|
|
|
_( "Error: a keepout area is allowed only on copper layers" ) );
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
2007-12-30 18:20:51 +00:00
|
|
|
|
2014-03-31 18:14:01 +00:00
|
|
|
// If no zone contour in progress, a new zone is being created,
|
|
|
|
if( zone == NULL )
|
|
|
|
{
|
|
|
|
zone = GetBoard()->m_CurrentZoneContour = new ZONE_CONTAINER( GetBoard() );
|
|
|
|
zone->SetFlags( IS_NEW );
|
|
|
|
zone->SetTimeStamp( GetNewTimeStamp() );
|
|
|
|
}
|
2011-09-07 19:41:04 +00:00
|
|
|
|
|
|
|
if( zone->GetNumCorners() == 0 ) // Start a new contour: init zone params (net, layer ...)
|
2008-01-04 12:27:16 +00:00
|
|
|
{
|
2012-02-06 05:44:19 +00:00
|
|
|
if( !s_CurrentZone ) // A new outline is created, from scratch
|
2008-01-04 12:27:16 +00:00
|
|
|
{
|
2012-02-06 05:44:19 +00:00
|
|
|
ZONE_EDIT_T edited;
|
|
|
|
|
2008-10-17 06:17:48 +00:00
|
|
|
// Prompt user for parameters:
|
2011-12-29 20:11:42 +00:00
|
|
|
m_canvas->SetIgnoreMouseEvents( true );
|
2011-09-07 19:41:04 +00:00
|
|
|
|
2017-09-27 07:59:12 +00:00
|
|
|
if( IsCopperLayer( GetActiveLayer() ) )
|
2012-02-06 05:44:19 +00:00
|
|
|
{
|
|
|
|
// Put a zone on a copper layer
|
|
|
|
if( GetBoard()->GetHighLightNetCode() > 0 )
|
2008-10-13 12:01:12 +00:00
|
|
|
{
|
2012-02-06 05:44:19 +00:00
|
|
|
zoneInfo.m_NetcodeSelection = GetBoard()->GetHighLightNetCode();
|
2014-02-25 10:47:27 +00:00
|
|
|
zone->SetNetCode( zoneInfo.m_NetcodeSelection );
|
2008-10-13 12:01:12 +00:00
|
|
|
}
|
2014-03-31 18:14:01 +00:00
|
|
|
|
2012-06-25 20:59:19 +00:00
|
|
|
double tmp = ZONE_THERMAL_RELIEF_GAP_MIL;
|
* KIWAY Milestone A): Make major modules into DLL/DSOs.
! The initial testing of this commit should be done using a Debug build so that
all the wxASSERT()s are enabled. Also, be sure and keep enabled the
USE_KIWAY_DLLs option. The tree won't likely build without it. Turning it
off is senseless anyways. If you want stable code, go back to a prior version,
the one tagged with "stable".
* Relocate all functionality out of the wxApp derivative into more finely
targeted purposes:
a) DLL/DSO specific
b) PROJECT specific
c) EXE or process specific
d) configuration file specific data
e) configuration file manipulations functions.
All of this functionality was blended into an extremely large wxApp derivative
and that was incompatible with the desire to support multiple concurrently
loaded DLL/DSO's ("KIFACE")s and multiple concurrently open projects.
An amazing amount of organization come from simply sorting each bit of
functionality into the proper box.
* Switch to wxConfigBase from wxConfig everywhere except instantiation.
* Add classes KIWAY, KIFACE, KIFACE_I, SEARCH_STACK, PGM_BASE, PGM_KICAD,
PGM_SINGLE_TOP,
* Remove "Return" prefix on many function names.
* Remove obvious comments from CMakeLists.txt files, and from else() and endif()s.
* Fix building boost for use in a DSO on linux.
* Remove some of the assumptions in the CMakeLists.txt files that windows had
to be the host platform when building windows binaries.
* Reduce the number of wxStrings being constructed at program load time via
static construction.
* Pass wxConfigBase* to all SaveSettings() and LoadSettings() functions so that
these functions are useful even when the wxConfigBase comes from another
source, as is the case in the KICAD_MANAGER_FRAME.
* Move the setting of the KIPRJMOD environment variable into class PROJECT,
so that it can be moved into a project variable soon, and out of FP_LIB_TABLE.
* Add the KIWAY_PLAYER which is associated with a particular PROJECT, and all
its child wxFrames and wxDialogs now have a Kiway() member function which
returns a KIWAY& that that window tree branch is in support of. This is like
wxWindows DNA in that child windows get this member with proper value at time
of construction.
* Anticipate some of the needs for milestones B) and C) and make code
adjustments now in an effort to reduce work in those milestones.
* No testing has been done for python scripting, since milestone C) has that
being largely reworked and re-thought-out.
2014-03-20 00:42:08 +00:00
|
|
|
|
|
|
|
wxConfigBase* cfg = Kiface().KifaceSettings();
|
|
|
|
cfg->Read( ZONE_THERMAL_RELIEF_GAP_STRING_KEY, &tmp );
|
2012-06-25 20:59:19 +00:00
|
|
|
zoneInfo.m_ThermalReliefGap = KiROUND( tmp * IU_PER_MILS);
|
2008-10-13 12:01:12 +00:00
|
|
|
|
2012-06-25 20:59:19 +00:00
|
|
|
tmp = ZONE_THERMAL_RELIEF_COPPER_WIDTH_MIL;
|
2014-03-31 18:14:01 +00:00
|
|
|
cfg->Read( ZONE_THERMAL_RELIEF_COPPER_WIDTH_STRING_KEY, &tmp );
|
2012-06-25 20:59:19 +00:00
|
|
|
zoneInfo.m_ThermalReliefCopperBridge = KiROUND( tmp * IU_PER_MILS );
|
|
|
|
|
|
|
|
tmp = ZONE_CLEARANCE_MIL;
|
2014-03-31 18:14:01 +00:00
|
|
|
cfg->Read( ZONE_CLEARANCE_WIDTH_STRING_KEY, &tmp );
|
2012-06-25 20:59:19 +00:00
|
|
|
zoneInfo.m_ZoneClearance = KiROUND( tmp * IU_PER_MILS );
|
|
|
|
|
|
|
|
tmp = ZONE_THICKNESS_MIL;
|
2014-03-31 18:14:01 +00:00
|
|
|
cfg->Read( ZONE_MIN_THICKNESS_WIDTH_STRING_KEY, &tmp );
|
2012-06-25 20:59:19 +00:00
|
|
|
zoneInfo.m_ZoneMinThickness = KiROUND( tmp * IU_PER_MILS );
|
2012-02-06 05:44:19 +00:00
|
|
|
|
2012-07-13 18:55:29 +00:00
|
|
|
if( GetToolId() == ID_PCB_KEEPOUT_AREA_BUTT )
|
|
|
|
{
|
|
|
|
zoneInfo.SetIsKeepout( true );
|
2016-02-02 20:32:11 +00:00
|
|
|
// Netcode, netname and some other settings are irrelevant,
|
2013-03-01 19:59:29 +00:00
|
|
|
// so ensure they are cleared
|
2014-02-25 10:47:27 +00:00
|
|
|
zone->SetNetCode( NETINFO_LIST::UNCONNECTED );
|
2016-02-02 20:32:11 +00:00
|
|
|
zoneInfo.SetCornerSmoothingType( ZONE_SETTINGS::SMOOTHING_NONE );
|
|
|
|
zoneInfo.SetCornerRadius( 0 );
|
|
|
|
|
2012-07-13 18:55:29 +00:00
|
|
|
edited = InvokeKeepoutAreaEditor( this, &zoneInfo );
|
|
|
|
}
|
|
|
|
else
|
2013-01-07 07:46:01 +00:00
|
|
|
{
|
2017-09-27 07:59:12 +00:00
|
|
|
zoneInfo.m_CurrentZone_Layer = GetActiveLayer(); // Preselect a layer
|
2013-01-07 07:46:01 +00:00
|
|
|
zoneInfo.SetIsKeepout( false );
|
2012-07-13 18:55:29 +00:00
|
|
|
edited = InvokeCopperZonesEditor( this, &zoneInfo );
|
2013-01-07 07:46:01 +00:00
|
|
|
}
|
2008-09-26 19:51:36 +00:00
|
|
|
}
|
|
|
|
else // Put a zone on a non copper layer (technical layer)
|
|
|
|
{
|
2017-09-27 07:59:12 +00:00
|
|
|
zone->SetLayer( GetActiveLayer() ); // Preselect a layer
|
2013-01-07 07:46:01 +00:00
|
|
|
zoneInfo.SetIsKeepout( false );
|
2017-09-27 07:59:12 +00:00
|
|
|
zoneInfo.m_NetcodeSelection = 0; // No net for non copper zones
|
2012-02-06 05:44:19 +00:00
|
|
|
edited = InvokeNonCopperZonesEditor( this, zone, &zoneInfo );
|
2008-09-26 19:51:36 +00:00
|
|
|
}
|
2011-09-07 19:41:04 +00:00
|
|
|
|
2011-12-22 13:28:11 +00:00
|
|
|
m_canvas->MoveCursorToCrossHair();
|
2011-12-29 20:11:42 +00:00
|
|
|
m_canvas->SetIgnoreMouseEvents( false );
|
2007-12-30 18:20:51 +00:00
|
|
|
|
2012-02-06 05:44:19 +00:00
|
|
|
if( edited == ZONE_ABORT )
|
2014-03-31 18:14:01 +00:00
|
|
|
{
|
|
|
|
GetBoard()->m_CurrentZoneContour = NULL;
|
|
|
|
delete zone;
|
2008-01-31 20:53:44 +00:00
|
|
|
return 0;
|
2014-03-31 18:14:01 +00:00
|
|
|
}
|
2008-04-01 05:21:50 +00:00
|
|
|
|
2011-10-17 20:01:27 +00:00
|
|
|
// Switch active layer to the selected zone layer
|
2014-03-21 10:17:47 +00:00
|
|
|
SetActiveLayer( zoneInfo.m_CurrentZone_Layer );
|
2012-02-06 05:44:19 +00:00
|
|
|
SetZoneSettings( zoneInfo );
|
2018-01-01 20:42:54 +00:00
|
|
|
OnModify();
|
2008-01-04 12:27:16 +00:00
|
|
|
}
|
2012-02-06 05:44:19 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
// Start a new contour: init zone params (net and layer) from an existing
|
|
|
|
// zone (add cutout or similar zone)
|
|
|
|
|
|
|
|
zoneInfo.m_CurrentZone_Layer = s_CurrentZone->GetLayer();
|
2014-03-21 10:17:47 +00:00
|
|
|
SetActiveLayer( s_CurrentZone->GetLayer() );
|
2012-02-06 05:44:19 +00:00
|
|
|
|
|
|
|
zoneInfo << *s_CurrentZone;
|
|
|
|
|
|
|
|
SetZoneSettings( zoneInfo );
|
2018-01-01 20:42:54 +00:00
|
|
|
OnModify();
|
2008-01-04 12:27:16 +00:00
|
|
|
}
|
2008-01-08 17:44:20 +00:00
|
|
|
|
2012-02-06 05:44:19 +00:00
|
|
|
// Show the Net for zones on copper layers
|
2014-03-31 18:14:01 +00:00
|
|
|
if( IsCopperLayer( zoneInfo.m_CurrentZone_Layer ) &&
|
|
|
|
!zoneInfo.GetIsKeepout() )
|
2007-12-30 18:20:51 +00:00
|
|
|
{
|
2008-10-17 06:17:48 +00:00
|
|
|
if( s_CurrentZone )
|
2012-02-06 05:44:19 +00:00
|
|
|
{
|
2014-02-25 10:47:27 +00:00
|
|
|
zoneInfo.m_NetcodeSelection = s_CurrentZone->GetNetCode();
|
2012-02-06 05:44:19 +00:00
|
|
|
GetBoard()->SetZoneSettings( zoneInfo );
|
|
|
|
}
|
2011-09-07 19:41:04 +00:00
|
|
|
|
2011-09-14 20:04:58 +00:00
|
|
|
if( GetBoard()->IsHighLightNetON() )
|
2008-09-26 19:51:36 +00:00
|
|
|
{
|
2012-02-06 05:44:19 +00:00
|
|
|
HighLight( DC ); // Remove old highlight selection
|
2008-09-26 19:51:36 +00:00
|
|
|
}
|
2008-01-04 12:27:16 +00:00
|
|
|
|
2012-02-06 05:44:19 +00:00
|
|
|
GetBoard()->SetHighLightNet( zoneInfo.m_NetcodeSelection );
|
2011-10-17 20:01:27 +00:00
|
|
|
HighLight( DC );
|
2008-09-26 19:51:36 +00:00
|
|
|
}
|
2011-09-07 19:41:04 +00:00
|
|
|
|
2008-01-04 12:27:16 +00:00
|
|
|
if( !s_AddCutoutToCurrentZone )
|
2008-10-17 06:17:48 +00:00
|
|
|
s_CurrentZone = NULL; // the zone is used only once ("add similar zone" command)
|
2007-12-30 18:20:51 +00:00
|
|
|
}
|
2007-12-19 16:44:53 +00:00
|
|
|
|
|
|
|
// if first segment
|
2012-02-06 05:44:19 +00:00
|
|
|
if( zone->GetNumCorners() == 0 )
|
2008-01-31 20:53:44 +00:00
|
|
|
{
|
2012-02-06 05:44:19 +00:00
|
|
|
zoneInfo.ExportSetting( *zone );
|
|
|
|
|
2017-03-07 12:06:00 +00:00
|
|
|
// A duplicated corner is needed; null segments are removed when the zone is finished.
|
2017-06-19 11:29:57 +00:00
|
|
|
zone->AppendCorner( GetCrossHairPosition(), -1 );
|
|
|
|
// Add the duplicate corner:
|
|
|
|
zone->AppendCorner( GetCrossHairPosition(), -1, true );
|
2011-09-07 19:41:04 +00:00
|
|
|
|
2018-06-04 08:44:25 +00:00
|
|
|
if( Settings().m_legacyDrcOn && (m_drc->DrcOnCreatingZone( zone, 0 ) == BAD_DRC)
|
|
|
|
&& zone->IsOnCopperLayer() )
|
2008-01-31 20:53:44 +00:00
|
|
|
{
|
2011-12-21 13:42:02 +00:00
|
|
|
zone->ClearFlags();
|
2008-01-31 20:53:44 +00:00
|
|
|
zone->RemoveAllContours();
|
|
|
|
|
|
|
|
// use the form of SetCurItem() which does not write to the msg panel,
|
|
|
|
// SCREEN::SetCurItem(), so the DRC error remains on screen.
|
2011-03-01 19:26:17 +00:00
|
|
|
// PCB_EDIT_FRAME::SetCurItem() calls DisplayInfo().
|
2008-01-31 20:53:44 +00:00
|
|
|
GetScreen()->SetCurItem( NULL );
|
2017-07-20 14:06:41 +00:00
|
|
|
DisplayErrorMessage( this,
|
2018-04-08 10:28:59 +00:00
|
|
|
_( "DRC error: this start point is inside or too close another area" ) );
|
2008-01-31 20:53:44 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2007-12-19 16:44:53 +00:00
|
|
|
|
2008-01-31 20:53:44 +00:00
|
|
|
SetCurItem( zone );
|
2011-12-22 13:28:11 +00:00
|
|
|
m_canvas->SetMouseCapture( Show_New_Edge_While_Move_Mouse, Abort_Zone_Create_Outline );
|
2007-12-19 16:44:53 +00:00
|
|
|
}
|
2011-09-07 19:41:04 +00:00
|
|
|
else // edge in progress:
|
2007-12-30 18:20:51 +00:00
|
|
|
{
|
2008-01-31 20:53:44 +00:00
|
|
|
ii = zone->GetNumCorners() - 1;
|
|
|
|
|
2012-08-31 13:58:23 +00:00
|
|
|
// edge in progress : the current corner coordinate was set
|
|
|
|
// by Show_New_Edge_While_Move_Mouse
|
2008-01-31 20:53:44 +00:00
|
|
|
if( zone->GetCornerPosition( ii - 1 ) != zone->GetCornerPosition( ii ) )
|
2007-12-19 16:44:53 +00:00
|
|
|
{
|
2018-06-04 08:44:25 +00:00
|
|
|
if( !Settings().m_legacyDrcOn || !zone->IsOnCopperLayer()
|
|
|
|
|| ( m_drc->DrcOnCreatingZone( zone, ii - 1 ) == OK_DRC ) )
|
2012-02-06 05:44:19 +00:00
|
|
|
{
|
|
|
|
// Ok, we can add a new corner
|
2012-07-30 07:40:25 +00:00
|
|
|
if( m_canvas->IsMouseCaptured() )
|
|
|
|
m_canvas->CallMouseCapture( DC, wxPoint(0,0), false );
|
2017-03-07 12:06:00 +00:00
|
|
|
|
|
|
|
// It is necessary to allow duplication of the points, as we have to handle the
|
|
|
|
// continuous drawing while creating the zone at the same time as we build it. Null
|
|
|
|
// segments are removed when the zone is finished, in End_Zone.
|
2017-06-22 10:10:48 +00:00
|
|
|
zone->AppendCorner( GetCrossHairPosition(), -1, true );
|
2017-03-07 12:06:00 +00:00
|
|
|
|
2009-04-17 08:51:02 +00:00
|
|
|
SetCurItem( zone ); // calls DisplayInfo().
|
2017-03-07 12:06:00 +00:00
|
|
|
|
2012-07-30 07:40:25 +00:00
|
|
|
if( m_canvas->IsMouseCaptured() )
|
|
|
|
m_canvas->CallMouseCapture( DC, wxPoint(0,0), false );
|
2008-02-01 21:30:45 +00:00
|
|
|
}
|
2007-12-19 16:44:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-01-31 20:53:44 +00:00
|
|
|
return zone->GetNumCorners();
|
2007-12-19 16:44:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-09-07 19:41:04 +00:00
|
|
|
bool PCB_EDIT_FRAME::End_Zone( wxDC* DC )
|
2007-12-19 16:44:53 +00:00
|
|
|
{
|
2009-01-05 05:21:35 +00:00
|
|
|
ZONE_CONTAINER* zone = GetBoard()->m_CurrentZoneContour;
|
2008-01-31 20:53:44 +00:00
|
|
|
|
2012-02-06 05:44:19 +00:00
|
|
|
if( !zone )
|
2008-01-31 20:53:44 +00:00
|
|
|
return true;
|
|
|
|
|
2009-08-23 15:22:44 +00:00
|
|
|
// Validate the current outline:
|
2008-01-31 20:53:44 +00:00
|
|
|
if( zone->GetNumCorners() <= 2 ) // An outline must have 3 corners or more
|
|
|
|
{
|
2011-12-22 13:28:11 +00:00
|
|
|
Abort_Zone_Create_Outline( m_canvas, DC );
|
2008-01-31 20:53:44 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-08-31 13:58:23 +00:00
|
|
|
// Remove the last corner if is is at the same location as the prevoius corner
|
2013-03-20 14:50:12 +00:00
|
|
|
zone->Outline()->RemoveNullSegments();
|
2012-08-31 13:58:23 +00:00
|
|
|
|
2008-01-31 20:53:44 +00:00
|
|
|
// Validate the current edge:
|
|
|
|
int icorner = zone->GetNumCorners() - 1;
|
2008-09-26 19:51:36 +00:00
|
|
|
if( zone->IsOnCopperLayer() )
|
2008-01-31 20:53:44 +00:00
|
|
|
{
|
2018-06-04 08:44:25 +00:00
|
|
|
if( Settings().m_legacyDrcOn &&
|
|
|
|
m_drc->DrcOnCreatingZone( zone, icorner - 1 ) == BAD_DRC ) // we can't validate last edge
|
2008-09-26 19:51:36 +00:00
|
|
|
return false;
|
2011-09-07 19:41:04 +00:00
|
|
|
|
2018-06-04 08:44:25 +00:00
|
|
|
if( Settings().m_legacyDrcOn &&
|
|
|
|
m_drc->DrcOnCreatingZone( zone, icorner ) == BAD_DRC ) // we can't validate the closing edge
|
2008-09-26 19:51:36 +00:00
|
|
|
{
|
2017-07-20 14:06:41 +00:00
|
|
|
DisplayErrorMessage( this,
|
2018-04-08 10:28:59 +00:00
|
|
|
_( "DRC error: closing this area creates a DRC error with another area" ) );
|
2011-12-22 13:28:11 +00:00
|
|
|
m_canvas->MoveCursorToCrossHair();
|
2008-09-26 19:51:36 +00:00
|
|
|
return false;
|
|
|
|
}
|
2008-01-31 20:53:44 +00:00
|
|
|
}
|
|
|
|
|
2011-12-21 13:42:02 +00:00
|
|
|
zone->ClearFlags();
|
2007-12-19 16:44:53 +00:00
|
|
|
|
2011-12-22 13:28:11 +00:00
|
|
|
zone->DrawWhileCreateOutline( m_canvas, DC, GR_XOR );
|
2007-12-19 16:44:53 +00:00
|
|
|
|
2011-12-22 13:28:11 +00:00
|
|
|
m_canvas->SetMouseCapture( NULL, NULL );
|
2007-12-30 18:20:51 +00:00
|
|
|
|
2008-01-04 12:27:16 +00:00
|
|
|
// Undraw old drawings, because they can have important changes
|
2017-03-13 03:19:33 +00:00
|
|
|
PCB_LAYER_ID layer = zone->GetLayer();
|
2011-12-22 13:28:11 +00:00
|
|
|
GetBoard()->RedrawAreasOutlines( m_canvas, DC, GR_XOR, layer );
|
|
|
|
GetBoard()->RedrawFilledAreas( m_canvas, DC, GR_XOR, layer );
|
2008-01-04 12:27:16 +00:00
|
|
|
|
2009-08-23 15:22:44 +00:00
|
|
|
// Save initial zones configuration, for undo/redo, before adding new zone
|
2012-08-04 09:43:27 +00:00
|
|
|
s_AuxiliaryList.ClearListAndDeleteItems();
|
2009-08-23 15:22:44 +00:00
|
|
|
s_PickedList.ClearListAndDeleteItems();
|
2014-02-25 10:47:27 +00:00
|
|
|
SaveCopyOfZones(s_PickedList, GetBoard(), zone->GetNetCode(), zone->GetLayer() );
|
2009-08-23 15:22:44 +00:00
|
|
|
|
2012-02-06 05:44:19 +00:00
|
|
|
// Put new zone in list
|
|
|
|
if( !s_CurrentZone )
|
2008-01-04 12:27:16 +00:00
|
|
|
{
|
2009-01-05 05:21:35 +00:00
|
|
|
GetBoard()->Add( zone );
|
2012-02-06 05:44:19 +00:00
|
|
|
|
2009-08-23 15:22:44 +00:00
|
|
|
// Add this zone in picked list, as new item
|
|
|
|
ITEM_PICKER picker( zone, UR_NEW );
|
|
|
|
s_PickedList.PushItem( picker );
|
2007-12-30 18:20:51 +00:00
|
|
|
}
|
2008-01-04 12:27:16 +00:00
|
|
|
else // Append this outline as a cutout to an existing zone
|
|
|
|
{
|
2017-03-07 12:06:00 +00:00
|
|
|
s_CurrentZone->Outline()->AddHole( zone->Outline()->Outline( 0 ) );
|
2007-12-30 18:20:51 +00:00
|
|
|
|
2008-01-31 20:53:44 +00:00
|
|
|
zone->RemoveAllContours(); // All corners are copied in s_CurrentZone. Free corner list.
|
|
|
|
zone = s_CurrentZone;
|
2008-01-04 12:27:16 +00:00
|
|
|
}
|
2007-12-30 18:20:51 +00:00
|
|
|
|
2008-01-04 12:27:16 +00:00
|
|
|
s_AddCutoutToCurrentZone = false;
|
|
|
|
s_CurrentZone = NULL;
|
2016-10-05 13:12:10 +00:00
|
|
|
GetBoard()->m_CurrentZoneContour = NULL;
|
2007-12-30 18:20:51 +00:00
|
|
|
|
2011-10-17 20:01:27 +00:00
|
|
|
GetScreen()->SetCurItem( NULL ); // This outline can be deleted when merging outlines
|
2008-01-04 12:27:16 +00:00
|
|
|
|
|
|
|
// Combine zones if possible :
|
2012-08-04 09:43:27 +00:00
|
|
|
GetBoard()->OnAreaPolygonModified( &s_AuxiliaryList, zone );
|
2008-01-04 12:27:16 +00:00
|
|
|
|
|
|
|
// Redraw the real edge zone :
|
2011-12-22 13:28:11 +00:00
|
|
|
GetBoard()->RedrawAreasOutlines( m_canvas, DC, GR_OR, layer );
|
|
|
|
GetBoard()->RedrawFilledAreas( m_canvas, DC, GR_OR, layer );
|
2007-12-30 18:20:51 +00:00
|
|
|
|
2012-02-06 05:44:19 +00:00
|
|
|
int ii = GetBoard()->GetAreaIndex( zone ); // test if zone exists
|
2011-09-07 19:41:04 +00:00
|
|
|
|
2008-01-31 20:53:44 +00:00
|
|
|
if( ii < 0 )
|
|
|
|
zone = NULL; // was removed by combining zones
|
2009-08-23 15:22:44 +00:00
|
|
|
|
2017-12-08 10:25:13 +00:00
|
|
|
DRC drc( this );
|
|
|
|
int error_count = drc.TestZoneToZoneOutline( zone, true );
|
2011-09-07 19:41:04 +00:00
|
|
|
|
2008-01-31 20:53:44 +00:00
|
|
|
if( error_count )
|
|
|
|
{
|
2017-07-20 14:06:41 +00:00
|
|
|
DisplayErrorMessage( this, _( "Area: DRC outline error" ) );
|
2008-01-31 20:53:44 +00:00
|
|
|
}
|
2008-01-10 20:53:41 +00:00
|
|
|
|
2012-08-04 09:43:27 +00:00
|
|
|
UpdateCopyOfZonesList( s_PickedList, s_AuxiliaryList, GetBoard() );
|
2009-08-23 15:22:44 +00:00
|
|
|
SaveCopyInUndoList(s_PickedList, UR_UNSPECIFIED);
|
|
|
|
s_PickedList.ClearItemsList(); // s_ItemsListPicker is no more owner of picked items
|
|
|
|
|
2010-02-19 13:23:58 +00:00
|
|
|
OnModify();
|
2008-01-31 20:53:44 +00:00
|
|
|
return true;
|
2007-12-19 16:44:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-08-23 15:22:44 +00:00
|
|
|
/* Redraws the zone outlines when moving mouse
|
2007-12-19 16:44:53 +00:00
|
|
|
*/
|
2011-02-03 19:27:28 +00:00
|
|
|
static void Show_New_Edge_While_Move_Mouse( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
|
|
|
|
const wxPoint& aPosition, bool aErase )
|
2007-12-19 16:44:53 +00:00
|
|
|
{
|
2011-03-01 19:26:17 +00:00
|
|
|
PCB_EDIT_FRAME* pcbframe = (PCB_EDIT_FRAME*) aPanel->GetParent();
|
2013-08-03 05:15:23 +00:00
|
|
|
wxPoint c_pos = pcbframe->GetCrossHairPosition();
|
2011-03-01 19:26:17 +00:00
|
|
|
ZONE_CONTAINER* zone = pcbframe->GetBoard()->m_CurrentZoneContour;
|
2007-12-19 16:44:53 +00:00
|
|
|
|
2012-02-06 05:44:19 +00:00
|
|
|
if( !zone )
|
2007-12-19 16:44:53 +00:00
|
|
|
return;
|
|
|
|
|
2008-01-31 20:53:44 +00:00
|
|
|
int icorner = zone->GetNumCorners() - 1;
|
2011-02-03 19:27:28 +00:00
|
|
|
|
2012-02-06 05:44:19 +00:00
|
|
|
if( icorner < 1 )
|
2008-10-17 06:17:48 +00:00
|
|
|
return; // We must have 2 (or more) corners
|
2008-01-31 20:53:44 +00:00
|
|
|
|
2012-02-06 05:44:19 +00:00
|
|
|
if( aErase ) // Undraw edge in old position
|
2007-12-19 16:44:53 +00:00
|
|
|
{
|
2011-02-03 19:27:28 +00:00
|
|
|
zone->DrawWhileCreateOutline( aPanel, aDC );
|
2007-12-19 16:44:53 +00:00
|
|
|
}
|
|
|
|
|
2012-02-06 05:44:19 +00:00
|
|
|
// Redraw the current edge in its new position
|
|
|
|
if( pcbframe->GetZoneSettings().m_Zone_45_Only )
|
2007-12-19 16:44:53 +00:00
|
|
|
{
|
2007-12-29 19:15:58 +00:00
|
|
|
// calculate the new position as allowed
|
2017-03-07 12:06:00 +00:00
|
|
|
wxPoint StartPoint = static_cast<wxPoint>( zone->GetCornerPosition( icorner - 1 ) );
|
2017-05-04 06:54:30 +00:00
|
|
|
c_pos = CalculateSegmentEndPoint( c_pos, StartPoint );
|
2007-12-19 16:44:53 +00:00
|
|
|
}
|
|
|
|
|
2008-01-31 20:53:44 +00:00
|
|
|
zone->SetCornerPosition( icorner, c_pos );
|
|
|
|
|
2011-02-03 19:27:28 +00:00
|
|
|
zone->DrawWhileCreateOutline( aPanel, aDC );
|
2007-12-19 16:44:53 +00:00
|
|
|
}
|
|
|
|
|
2012-02-06 05:44:19 +00:00
|
|
|
void PCB_EDIT_FRAME::Edit_Zone_Params( wxDC* DC, ZONE_CONTAINER* aZone )
|
2007-12-19 16:44:53 +00:00
|
|
|
{
|
2012-02-06 05:44:19 +00:00
|
|
|
ZONE_EDIT_T edited;
|
|
|
|
ZONE_SETTINGS zoneInfo = GetZoneSettings();
|
|
|
|
|
2016-06-21 15:06:28 +00:00
|
|
|
BOARD_COMMIT commit( this );
|
2011-12-29 20:11:42 +00:00
|
|
|
m_canvas->SetIgnoreMouseEvents( true );
|
2009-08-23 15:22:44 +00:00
|
|
|
|
2012-02-06 05:44:19 +00:00
|
|
|
// Save initial zones configuration, for undo/redo, before adding new zone
|
|
|
|
// note the net name and the layer can be changed, so we must save all zones
|
2012-08-04 09:43:27 +00:00
|
|
|
s_AuxiliaryList.ClearListAndDeleteItems();
|
2009-08-23 15:22:44 +00:00
|
|
|
s_PickedList.ClearListAndDeleteItems();
|
2016-06-21 15:06:28 +00:00
|
|
|
SaveCopyOfZones( s_PickedList, GetBoard(), -1, UNDEFINED_LAYER );
|
2009-08-23 15:22:44 +00:00
|
|
|
|
2012-07-13 18:55:29 +00:00
|
|
|
if( aZone->GetIsKeepout() )
|
|
|
|
{
|
|
|
|
// edit a keepout area on a copper layer
|
|
|
|
zoneInfo << *aZone;
|
|
|
|
edited = InvokeKeepoutAreaEditor( this, &zoneInfo );
|
|
|
|
}
|
2014-06-24 16:17:18 +00:00
|
|
|
else if( IsCopperLayer( aZone->GetLayer() ) )
|
2012-02-06 05:44:19 +00:00
|
|
|
{
|
|
|
|
// edit a zone on a copper layer
|
|
|
|
zoneInfo << *aZone;
|
|
|
|
edited = InvokeCopperZonesEditor( this, &zoneInfo );
|
2008-09-26 19:51:36 +00:00
|
|
|
}
|
2012-02-06 05:44:19 +00:00
|
|
|
else
|
2011-09-07 19:41:04 +00:00
|
|
|
{
|
2018-03-14 17:48:55 +00:00
|
|
|
zoneInfo << *aZone;
|
2012-02-06 05:44:19 +00:00
|
|
|
edited = InvokeNonCopperZonesEditor( this, aZone, &zoneInfo );
|
2011-09-07 19:41:04 +00:00
|
|
|
}
|
2007-12-19 16:44:53 +00:00
|
|
|
|
2011-12-22 13:28:11 +00:00
|
|
|
m_canvas->MoveCursorToCrossHair();
|
2011-12-29 20:11:42 +00:00
|
|
|
m_canvas->SetIgnoreMouseEvents( false );
|
2007-12-19 16:44:53 +00:00
|
|
|
|
2012-02-06 05:44:19 +00:00
|
|
|
if( edited == ZONE_ABORT )
|
2009-08-23 15:22:44 +00:00
|
|
|
{
|
2012-08-04 09:43:27 +00:00
|
|
|
s_AuxiliaryList.ClearListAndDeleteItems();
|
2009-08-23 15:22:44 +00:00
|
|
|
s_PickedList.ClearListAndDeleteItems();
|
|
|
|
return;
|
|
|
|
}
|
2011-09-07 19:41:04 +00:00
|
|
|
|
2012-02-06 05:44:19 +00:00
|
|
|
SetZoneSettings( zoneInfo );
|
2018-01-01 20:42:54 +00:00
|
|
|
OnModify();
|
2012-02-06 05:44:19 +00:00
|
|
|
|
|
|
|
if( edited == ZONE_EXPORT_VALUES )
|
2009-08-23 15:22:44 +00:00
|
|
|
{
|
2012-08-04 09:43:27 +00:00
|
|
|
UpdateCopyOfZonesList( s_PickedList, s_AuxiliaryList, GetBoard() );
|
2016-06-21 15:06:28 +00:00
|
|
|
commit.Stage( s_PickedList );
|
|
|
|
commit.Push( _( "Modify zone properties" ) );
|
2009-08-23 15:22:44 +00:00
|
|
|
s_PickedList.ClearItemsList(); // s_ItemsListPicker is no more owner of picked items
|
2007-12-19 16:44:53 +00:00
|
|
|
return;
|
2009-08-23 15:22:44 +00:00
|
|
|
}
|
2007-12-19 16:44:53 +00:00
|
|
|
|
2018-01-14 10:27:11 +00:00
|
|
|
wxBusyCursor dummy;
|
|
|
|
|
2008-01-31 20:53:44 +00:00
|
|
|
// Undraw old zone outlines
|
2009-01-05 05:21:35 +00:00
|
|
|
for( int ii = 0; ii < GetBoard()->GetAreaCount(); ii++ )
|
2008-01-04 12:27:16 +00:00
|
|
|
{
|
2009-01-05 05:21:35 +00:00
|
|
|
ZONE_CONTAINER* edge_zone = GetBoard()->GetArea( ii );
|
2011-12-22 13:28:11 +00:00
|
|
|
edge_zone->Draw( m_canvas, DC, GR_XOR );
|
2017-02-24 12:26:25 +00:00
|
|
|
|
|
|
|
if( IsGalCanvasActive() )
|
|
|
|
{
|
|
|
|
GetGalCanvas()->GetView()->Update( edge_zone );
|
|
|
|
}
|
2008-01-04 12:27:16 +00:00
|
|
|
}
|
2007-12-29 19:15:58 +00:00
|
|
|
|
2012-02-06 05:44:19 +00:00
|
|
|
zoneInfo.ExportSetting( *aZone );
|
|
|
|
|
|
|
|
NETINFO_ITEM* net = GetBoard()->FindNet( zoneInfo.m_NetcodeSelection );
|
2011-09-07 19:41:04 +00:00
|
|
|
|
2009-08-23 15:22:44 +00:00
|
|
|
if( net ) // net == NULL should not occur
|
2014-02-25 10:47:27 +00:00
|
|
|
aZone->SetNetCode( net->GetNet() );
|
2008-10-10 11:31:46 +00:00
|
|
|
|
2012-02-06 05:44:19 +00:00
|
|
|
// Combine zones if possible
|
2012-08-04 09:43:27 +00:00
|
|
|
GetBoard()->OnAreaPolygonModified( &s_AuxiliaryList, aZone );
|
2008-01-04 12:27:16 +00:00
|
|
|
|
2012-02-06 05:44:19 +00:00
|
|
|
// Redraw the real new zone outlines
|
2013-03-31 13:27:46 +00:00
|
|
|
GetBoard()->RedrawAreasOutlines( m_canvas, DC, GR_OR, UNDEFINED_LAYER );
|
2007-12-30 18:20:51 +00:00
|
|
|
|
2012-08-04 09:43:27 +00:00
|
|
|
UpdateCopyOfZonesList( s_PickedList, s_AuxiliaryList, GetBoard() );
|
2017-03-21 16:21:41 +00:00
|
|
|
|
|
|
|
// refill zones with the new properties applied
|
2018-01-14 10:27:11 +00:00
|
|
|
std::vector<ZONE_CONTAINER*> zones_to_refill;
|
|
|
|
|
2017-03-21 16:21:41 +00:00
|
|
|
for( unsigned i = 0; i < s_PickedList.GetCount(); ++i )
|
|
|
|
{
|
2018-01-14 10:27:11 +00:00
|
|
|
ZONE_CONTAINER* zone = dyn_cast<ZONE_CONTAINER*>( s_PickedList.GetPickedItem( i ) );
|
2017-03-21 16:21:41 +00:00
|
|
|
|
|
|
|
if( zone == nullptr )
|
|
|
|
{
|
|
|
|
wxASSERT_MSG( false, "Expected a zone after zone properties edit" );
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( zone->IsFilled() )
|
2018-01-14 10:27:11 +00:00
|
|
|
zones_to_refill.push_back( zone );
|
|
|
|
}
|
|
|
|
|
|
|
|
if( zones_to_refill.size() )
|
|
|
|
{
|
|
|
|
ZONE_FILLER filler ( GetBoard() );
|
|
|
|
wxString title;
|
|
|
|
title.Printf( _( "Refill %d Zones" ), (int)zones_to_refill.size() );
|
|
|
|
std::unique_ptr<WX_PROGRESS_REPORTER> progressReporter(
|
2018-09-21 12:21:12 +00:00
|
|
|
new WX_PROGRESS_REPORTER( this, title, 4 ) );
|
2018-01-14 10:27:11 +00:00
|
|
|
|
|
|
|
filler.SetProgressReporter( progressReporter.get() );
|
|
|
|
filler.Fill( zones_to_refill );
|
2017-03-21 16:21:41 +00:00
|
|
|
}
|
|
|
|
|
2016-06-21 15:06:28 +00:00
|
|
|
commit.Stage( s_PickedList );
|
|
|
|
commit.Push( _( "Modify zone properties" ) );
|
2017-03-28 16:30:49 +00:00
|
|
|
GetBoard()->GetConnectivity()->RecalculateRatsnest();
|
2012-02-06 05:44:19 +00:00
|
|
|
|
|
|
|
s_PickedList.ClearItemsList(); // s_ItemsListPicker is no longer owner of picked items
|
2018-03-14 17:48:55 +00:00
|
|
|
|
|
|
|
if( !IsGalCanvasActive() )
|
|
|
|
m_canvas->Refresh();
|
2007-12-29 19:15:58 +00:00
|
|
|
}
|
|
|
|
|
2008-01-31 20:53:44 +00:00
|
|
|
|
2012-02-06 05:44:19 +00:00
|
|
|
void PCB_EDIT_FRAME::Delete_Zone_Contour( wxDC* DC, ZONE_CONTAINER* aZone )
|
2008-01-05 13:37:51 +00:00
|
|
|
{
|
2017-03-07 12:06:00 +00:00
|
|
|
// Get contour in which the selected corner is
|
|
|
|
SHAPE_POLY_SET::VERTEX_INDEX indices;
|
|
|
|
|
|
|
|
// If the selected corner does not exist, abort
|
|
|
|
if( !aZone->Outline()->GetRelativeIndices( aZone->GetSelectedCorner(), &indices ) )
|
|
|
|
throw( std::out_of_range( "Zone selected corner does not exist" ) );
|
2008-01-31 20:53:44 +00:00
|
|
|
|
2012-02-06 05:44:19 +00:00
|
|
|
EDA_RECT dirty = aZone->GetBoundingBox();
|
2008-01-31 20:53:44 +00:00
|
|
|
|
2011-07-16 16:04:49 +00:00
|
|
|
// For compatibility with old boards: remove old SEGZONE fill segments
|
2012-02-06 05:44:19 +00:00
|
|
|
Delete_OldZone_Fill( NULL, aZone->GetTimeStamp() );
|
2011-07-16 16:04:49 +00:00
|
|
|
|
|
|
|
// Remove current filling:
|
2012-02-06 05:44:19 +00:00
|
|
|
aZone->UnFill();
|
2008-01-31 20:53:44 +00:00
|
|
|
|
2017-03-07 12:06:00 +00:00
|
|
|
if( indices.m_contour == 0 ) // This is the main outline: remove all
|
2009-07-31 05:33:11 +00:00
|
|
|
{
|
2012-02-06 05:44:19 +00:00
|
|
|
SaveCopyInUndoList( aZone, UR_DELETED );
|
|
|
|
GetBoard()->Remove( aZone );
|
2009-07-31 05:33:11 +00:00
|
|
|
}
|
2008-01-31 20:53:44 +00:00
|
|
|
|
|
|
|
else
|
|
|
|
{
|
2012-08-31 15:59:14 +00:00
|
|
|
SaveCopyInUndoList( aZone, UR_CHANGED );
|
2017-03-07 12:06:00 +00:00
|
|
|
aZone->Outline()->RemoveContour( indices.m_contour, indices.m_polygon );
|
2008-01-31 20:53:44 +00:00
|
|
|
}
|
2008-05-02 05:16:35 +00:00
|
|
|
|
2011-12-22 13:28:11 +00:00
|
|
|
m_canvas->RefreshDrawingRect( dirty );
|
2008-05-02 05:16:35 +00:00
|
|
|
|
2010-02-19 13:23:58 +00:00
|
|
|
OnModify();
|
2008-01-05 13:37:51 +00:00
|
|
|
}
|