Commit cfdb2839 authored by charras's avatar charras

Pcbnew: Work on undo/redo in Pcbnew almost finished.

parent 856b7c79
......@@ -4,6 +4,11 @@ KiCad ChangeLog 2009
Please add newer entries at the top, list the date and your name with
email address.
2009-aug-23 UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
================================================================================
++pcbnew
Work on undo/redo in pcbnew almost finished.
2009-Aug-16 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================
++pcbnew
......
......@@ -479,12 +479,11 @@ public:
* The zone outline is a frontier, and can be complex (with holes)
* The filling starts from starting points like pads, tracks.
* If exists the old filling is removed
* @param DC = current Device Context
* @param zone_container = zone to fill
* @param verbose = true to show error messages
* @return error level (0 = no error)
*/
int Fill_Zone( wxDC* DC, ZONE_CONTAINER* zone_container, bool verbose = TRUE );
int Fill_Zone( ZONE_CONTAINER* zone_container, bool verbose = TRUE );
/** Function Fill_All_Zones()
* Fill all zones on the board
......
......@@ -149,8 +149,10 @@ set(PCBNEW_SRCS
work.cpp
xchgmod.cpp
zones_by_polygon.cpp
zones_by_polygon_fill_functions.cpp
zones_convert_brd_items_to_polygons.cpp
zone_filling_algorithm.cpp
zones_functions_for_undo_redo.cpp
zones_polygons_insulated_copper_islands.cpp
zones_polygons_test_connections.cpp
zones_test_and_combine_areas.cpp
......
......@@ -424,7 +424,8 @@ void WinEDA_PcbFrame::SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList,
*/
if( commandToUndo->GetPickedItemLink( ii ) == NULL )
commandToUndo->SetPickedItemLink( DuplicateStruct( item ), ii );
wxASSERT( commandToUndo->GetPickedItemLink( ii ) );
if( commandToUndo->GetPickedItemLink( ii ) == NULL )
wxMessageBox( wxT( "SaveCopyInUndoList() in UR_CHANGED mode: NULL link" ) );
break;
case UR_MOVED:
......
......@@ -252,7 +252,14 @@ void BOARD::Add( BOARD_ITEM* aBoardItem, int aControl )
// other types may use linked list
default:
wxFAIL_MSG( wxT( "BOARD::Add() needs work: BOARD_ITEM type not handled" ) );
{
wxString msg;
msg.Printf(
wxT( "BOARD::Add() needs work: BOARD_ITEM type (%d) not handled" ),
aBoardItem->Type() );
wxFAIL_MSG(msg );
}
break;
}
}
......
/**************************************************************/
/*************************************************/
/* class_board.h - Class BOARD to handle a board */
/**************************************************************/
/*************************************************/
#ifndef CLASS_BOARD_H
#define CLASS_BOARD_H
......@@ -474,19 +474,18 @@ public:
/* Functions used in test, merge and cut outlines */
/**
* Function AddArea
* add empty copper area to net
/** Function AddArea
* Add an empty copper area to board areas list
* @param aNewZonesList = a PICKED_ITEMS_LIST * where to store new areas pickers (useful in undo commands)
* can be NULL
* @param aNetcode = the necode of the copper area (0 = no net)
* @param aLayer = the layer of area
* @param aStartPointPosition = position of the first point of the polygon outline of this area
* @param aHatch = hacth option
* @return pointer to the new area
*/
ZONE_CONTAINER* AddArea( int netcode, int layer, int x, int y, int hatch );
/**
* remove copper area from net
* @param area = area to remove
* @return 0
*/
int RemoveArea( ZONE_CONTAINER* area_to_remove );
ZONE_CONTAINER* AddArea( PICKED_ITEMS_LIST* aNewZonesList, int aNetcode,
int aLayer, wxPoint aStartPointPosition, int aHatch );
/**
* Function InsertArea
......@@ -522,15 +521,20 @@ public:
* Function ClipAreaPolygon
* Process an area that has been modified, by clipping its polygon against itself.
* This may change the number and order of copper areas in the net.
* @param bMessageBoxInt == TRUE, shows message when clipping occurs.
* @param bMessageBoxArc == TRUE, shows message when clipping can't be done due to arcs.
* @param aNewZonesList = a PICKED_ITEMS_LIST * where to store new areas pickers (useful in undo commands)
* can be NULL
* @param aCurrArea = the zone to process
* @param bMessageBoxInt == true, shows message when clipping occurs.
* @param bMessageBoxArc == true, shows message when clipping can't be done due to arcs.
* @param bRetainArcs = true to handle arcs (not really used in kicad)
* @return:
* -1 if arcs intersect other sides, so polygon can't be clipped
* 0 if no intersecting sides
* 1 if intersecting sides
* Also sets areas->utility1 flags if areas are modified
*/
int ClipAreaPolygon( ZONE_CONTAINER* CurrArea,
int ClipAreaPolygon( PICKED_ITEMS_LIST * aNewZonesList,
ZONE_CONTAINER* aCurrArea,
bool bMessageBoxArc,
bool bMessageBoxInt,
bool bRetainArcs = TRUE );
......@@ -539,6 +543,8 @@ public:
* Process an area that has been modified, by clipping its polygon against
* itself and the polygons for any other areas on the same net.
* This may change the number and order of copper areas in the net.
* @param aModifiedZonesList = a PICKED_ITEMS_LIST * where to store deleted or added areas
* (useful in undo commands. Can be NULL
* @param modified_area = area to test
* @param bMessageBox : if TRUE, shows message boxes when clipping occurs.
* @return :
......@@ -546,20 +552,31 @@ public:
* 0 if no intersecting sides
* 1 if intersecting sides, polygon clipped
*/
int AreaPolygonModified( ZONE_CONTAINER* modified_area,
int AreaPolygonModified( PICKED_ITEMS_LIST* aModifiedZonesList,
ZONE_CONTAINER* modified_area,
bool bMessageBoxArc,
bool bMessageBoxInt );
/**
* Function CombineAllAreasInNet
* Checks all copper areas in net for intersections, combining them if found
* @param aDeletedList = a PICKED_ITEMS_LIST * where to store deleted areas (useful in undo commands
* can be NULL
* @param aNetCode = net to consider
* @param bMessageBox : if true display warning message box
* @param bUseUtility : if true, don't check areas if both utility flags are 0
* Sets utility flag = 1 for any areas modified
* If an area has self-intersecting arcs, doesn't try to combine it
*/
int CombineAllAreasInNet( int aNetCode, bool bMessageBox, bool bUseUtility );
int CombineAllAreasInNet( PICKED_ITEMS_LIST* aDeletedList, int aNetCode, bool bMessageBox, bool bUseUtility );
/** Function RemoveArea
* remove copper area from net, and put it in a deleted list (if exists)
* @param aDeletedList = a PICKED_ITEMS_LIST * where to store deleted areas (useful in undo commands
* can be NULL
* @param area_to_remove = area to delete or put in deleted list
*/
void RemoveArea( PICKED_ITEMS_LIST* aDeletedList, ZONE_CONTAINER* area_to_remove );
/**
* Function TestAreaIntersections
......@@ -583,13 +600,17 @@ public:
/**
* Function CombineAreas
* If possible, combine 2 copper areas
* @param aDeletedList = a PICKED_ITEMS_LIST * where to store deleted areas (useful in undo commands
* can be NULL
* @param area_ref = tje main area (zone)
* @param area_to_combine = the zone that can be merged with area_ref
* area_ref must be BEFORE area_to_combine
* area_to_combine will be deleted, if areas are combined
* @return : 0 if no intersection
* 1 if intersection
* 2 if arcs intersect
*/
int CombineAreas( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_to_combine );
int CombineAreas( PICKED_ITEMS_LIST* aDeletedList, ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_to_combine );
/**
* Function Test_Drc_Areas_Outlines_To_Areas_Outlines
......
......@@ -1133,13 +1133,19 @@ void ZONE_CONTAINER::Copy( ZONE_CONTAINER* src )
m_Layer = src->m_Layer;
SetNet( src->GetNet() );
m_TimeStamp = src->m_TimeStamp;
m_Poly->RemoveAllContours();
m_Poly->Copy( src->m_Poly ); // copy outlines
m_CornerSelection = -1; // For corner moving, corner index to drag, or -1 if no selection
m_ZoneClearance = src->m_ZoneClearance; // clearance value
m_FillMode = src->m_FillMode; // Grid used for filling
m_FillMode = src->m_FillMode; // Filling mode (segments/polygons)
m_ArcToSegmentsCount = src->m_ArcToSegmentsCount;
m_PadOption = src->m_PadOption;
m_ThermalReliefGapValue = src->m_ThermalReliefGapValue;
m_ThermalReliefCopperBridgeValue = src->m_ThermalReliefCopperBridgeValue;
m_Poly->SetHatch( src->m_Poly->GetHatchStyle() );
m_FilledPolysList.clear();
m_FilledPolysList = src->m_FilledPolysList;
m_FillSegmList.clear();
m_FillSegmList = src->m_FillSegmList;
}
......
......@@ -42,7 +42,7 @@ public:
int m_ZoneClearance; // clearance value
int m_ZoneMinThickness; // Min thickness value in filled areas
int m_FillMode; // How to fillingareas: 0 = use polygonal areas , != 0 fill with segments
int m_ArcToSegmentsCount; // number of segments to convert a cirlce to a polygon (uses 16 or 32)
int m_ArcToSegmentsCount; // number of segments to convert a circle to a polygon (uses 16 or 32)
int m_PadOption; //
int m_ThermalReliefGapValue; // tickness of the gap in thermal reliefs
int m_ThermalReliefCopperBridgeValue; // tickness of the copper bridge in thermal reliefs
......@@ -369,6 +369,13 @@ public:
{
return m_Poly->GetHatchStyle();
}
/** function IsSame()
* test is 2 zones are equivalent:
* 2 zones are equivalent if they have same parameters and same outlines
* info relative to filling is not take in account
* @param aZoneToCompare = zone to compare with "this"
*/
bool IsSame( const ZONE_CONTAINER &aZoneToCompare);
};
......
......@@ -6,7 +6,7 @@
/// Licence: GNU License
/////////////////////////////////////////////////////////////////////////////
#if defined (__GNUG__) && !defined (NO_GCC_PRAGMA)
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
#pragma implementation "zones.h"
#endif
......@@ -33,6 +33,8 @@ dialog_copper_zone::dialog_copper_zone( WinEDA_PcbFrame* parent, ZONE_SETTING* z
m_Config = wxGetApp().m_EDA_Config;
m_Zone_Setting = zone_setting;
m_NetSorting = 1; // 0 = alphabetic sort, 1 = pad count sort, and filtering net names
m_OnExitCode = ZONE_ABORT;
if( m_Config )
{
m_NetSorting = m_Config->Read( ZONE_NET_SORT_OPTION_KEY, 1l );
......@@ -207,7 +209,7 @@ void dialog_copper_zone::OnInitDialog( wxInitDialogEvent& event )
void dialog_copper_zone::OnButtonCancelClick( wxCommandEvent& event )
/********************************************************************/
{
EndModal( ZONE_ABORT );
EndModal( m_OnExitCode );
}
......@@ -270,7 +272,7 @@ bool dialog_copper_zone::AcceptOptions( bool aPromptForErrors, bool aUseExportab
// Test if this is a reasonnable value for this parameter
// A too large value can hang pcbnew
#define CLEARANCE_MAX_VALUE 5000 // in 1/10000 inch
if ( m_Zone_Setting->m_ZoneClearance > CLEARANCE_MAX_VALUE )
if( m_Zone_Setting->m_ZoneClearance > CLEARANCE_MAX_VALUE )
{
DisplayError( this, _( "Error : Zone clearance is set to an unreasonnable value" ) );
return false;
......@@ -336,13 +338,13 @@ bool dialog_copper_zone::AcceptOptions( bool aPromptForErrors, bool aUseExportab
return false;
}
if ( ii == 0 ) // the not connected option was selected: this is not a good practice: warn:
if( ii == 0 ) // the not connected option was selected: this is not a good practice: warn:
{
if( ! IsOK( this, _(
"You have chosen the \"not connected\" option. This will create insulated copper islands. Are you sure ?") )
if( !IsOK( this, _(
"You have chosen the \"not connected\" option. This will create insulated copper islands. Are you sure ?" ) )
)
return false;
}
return false;
}
wxString net_name = m_ListNetNameSelection->GetString( ii );
......@@ -351,7 +353,7 @@ bool dialog_copper_zone::AcceptOptions( bool aPromptForErrors, bool aUseExportab
/* Search net_code for this net, if a net was selected */
if( m_ListNetNameSelection->GetSelection() > 0 )
{
NETINFO_ITEM* net = m_Parent->GetBoard()->FindNet(net_name);
NETINFO_ITEM* net = m_Parent->GetBoard()->FindNet( net_name );
if( net )
g_Zone_Default_Setting.m_NetcodeSelection = net->GetNet();
}
......@@ -435,6 +437,7 @@ void dialog_copper_zone::ExportSetupToOtherCopperZones( wxCommandEvent& event )
m_Zone_Setting->ExportSetting( *zone, false ); // false = partiel export
m_Parent->GetScreen()->SetModify();
}
m_OnExitCode = ZONE_EXPORT_VALUES; // values are exported to others zones
}
......
......@@ -6,25 +6,30 @@
#include "dialog_copper_zones_base.h"
/* here is the derivated class from dialog_copper_zone_frame created by wxFormBuilder
*/
class dialog_copper_zone: public dialog_copper_zone_base
*/
class dialog_copper_zone : public dialog_copper_zone_base
{
public:
WinEDA_PcbFrame* m_Parent;
wxConfig* m_Config; // Current config
ZONE_SETTING * m_Zone_Setting;
long m_NetSorting;
int m_LayerId[LAYER_COUNT]; // Handle the real layer number from layer name position in m_LayerSelectionCtrl
wxConfig* m_Config; // Current config
int m_OnExitCode; /* exit code: ZONE_ABORT if no change,
* ZONE_OK if new values accepted
* ZONE_EXPORT_VALUES if values are exported to others zones
*/
ZONE_SETTING* m_Zone_Setting;
long m_NetSorting;
int m_LayerId[LAYER_COUNT]; // Handle the real layer number from layer name position in m_LayerSelectionCtrl
public:
dialog_copper_zone( WinEDA_PcbFrame* parent, ZONE_SETTING * zone_setting);
dialog_copper_zone( WinEDA_PcbFrame* parent, ZONE_SETTING* zone_setting );
void OnInitDialog( wxInitDialogEvent& event );
void OnButtonOkClick( wxCommandEvent& event );
void OnButtonCancelClick( wxCommandEvent& event );
bool AcceptOptions(bool aPromptForErrors, bool aUseExportableSetupOnly = false);
void OnButtonOkClick( wxCommandEvent& event );
void OnButtonCancelClick( wxCommandEvent& event );
bool AcceptOptions( bool aPromptForErrors, bool aUseExportableSetupOnly = false );
void OnNetSortingOptionSelected( wxCommandEvent& event );
void ExportSetupToOtherCopperZones( wxCommandEvent& event );
void OnPadsInZoneClick( wxCommandEvent& event );
void ExportSetupToOtherCopperZones( wxCommandEvent& event );
void OnPadsInZoneClick( wxCommandEvent& event );
};
#endif // #ifndef DIALOG_COPPER_ZONES
......@@ -66,13 +66,14 @@ public:
public:
DialogPadProperties( WinEDA_BasePcbFrame* parent, D_PAD* Pad, wxDC* DC );
void InitDialog( wxInitDialogEvent& event );
void Init( );
void OnPadShapeSelection( wxCommandEvent& event );
void OnDrillShapeSelected( wxCommandEvent& event );
void PadOrientEvent( wxCommandEvent& event );
void PadTypeSelected( wxCommandEvent& event );
void PadPropertiesAccept( wxCommandEvent& event );
void SetPadLayersList( long layer_mask );
void OnCancelButtonClick( wxCommandEvent& event );
};
......@@ -90,6 +91,12 @@ DialogPadProperties::DialogPadProperties( WinEDA_BasePcbFrame* parent, D_PAD* Pa
Current_PadNetName = m_CurrentPad->GetNetname();
g_Current_PadName = m_CurrentPad->ReturnStringPadName();
}
Init( );
if( GetSizer() )
{
GetSizer()->SetSizeHints( this );
}
}
......@@ -104,7 +111,7 @@ void WinEDA_BasePcbFrame::InstallPadOptionsFrame( D_PAD* Pad, wxDC* DC, const wx
/**************************************************************/
void DialogPadProperties::InitDialog( wxInitDialogEvent& event )
void DialogPadProperties::Init( )
/**************************************************************/
{
int tmp;
......@@ -235,11 +242,6 @@ void DialogPadProperties::InitDialog( wxInitDialogEvent& event )
cmd_event.SetId( m_PadType->GetSelection() );
PadTypeSelected( cmd_event );
}
if( GetSizer() )
{
GetSizer()->SetSizeHints( this );
}
}
......@@ -475,8 +477,8 @@ void DialogPadProperties::PadPropertiesAccept( wxCommandEvent& event )
if( m_CurrentPad ) // Set Pad Name & Num
{
m_Parent->SaveCopyInUndoList( m_Parent->GetBoard()->m_Modules, UR_CHANGED );
MODULE* Module = (MODULE*) m_CurrentPad->GetParent();
m_Parent->SaveCopyInUndoList( Module, UR_CHANGED );
Module->m_LastEdit_Time = time( NULL );
if( m_DC ) // redraw the area where the pad was, without pad (delete pad on screen)
......@@ -580,10 +582,18 @@ void DialogPadProperties::PadPropertiesAccept( wxCommandEvent& event )
m_Parent->GetScreen()->SetModify();
}
Close();
EndModal(1);
if( m_DC )
m_Parent->DrawPanel->CursorOn( m_DC );
if( RastnestIsChanged ) // The net ratsnest must be recalculated
m_Parent->GetBoard()->m_Status_Pcb = 0;
}
/*********************************************************************/
void DialogPadProperties::OnCancelButtonClick( wxCommandEvent& event )
/*********************************************************************/
{
EndModal(0);
}
......@@ -166,21 +166,21 @@ DialogPadPropertiesBase::DialogPadPropertiesBase( wxWindow* parent, wxWindowID i
this->Centre( wxBOTH );
// Connect Events
this->Connect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( DialogPadPropertiesBase::InitDialog ) );
m_PadShape->Connect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DialogPadPropertiesBase::OnPadShapeSelection ), NULL, this );
m_DrillShapeCtrl->Connect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DialogPadPropertiesBase::OnDrillShapeSelected ), NULL, this );
m_PadOrient->Connect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DialogPadPropertiesBase::PadOrientEvent ), NULL, this );
m_PadType->Connect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DialogPadPropertiesBase::PadTypeSelected ), NULL, this );
m_buttonOk->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DialogPadPropertiesBase::PadPropertiesAccept ), NULL, this );
m_buttonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DialogPadPropertiesBase::OnCancelButtonClick ), NULL, this );
}
DialogPadPropertiesBase::~DialogPadPropertiesBase()
{
// Disconnect Events
this->Disconnect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( DialogPadPropertiesBase::InitDialog ) );
m_PadShape->Disconnect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DialogPadPropertiesBase::OnPadShapeSelection ), NULL, this );
m_DrillShapeCtrl->Disconnect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DialogPadPropertiesBase::OnDrillShapeSelected ), NULL, this );
m_PadOrient->Disconnect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DialogPadPropertiesBase::PadOrientEvent ), NULL, this );
m_PadType->Disconnect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DialogPadPropertiesBase::PadTypeSelected ), NULL, this );
m_buttonOk->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DialogPadPropertiesBase::PadPropertiesAccept ), NULL, this );
m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DialogPadPropertiesBase::OnCancelButtonClick ), NULL, this );
}
......@@ -49,7 +49,7 @@
<event name="OnHibernate"></event>
<event name="OnIconize"></event>
<event name="OnIdle"></event>
<event name="OnInitDialog">InitDialog</event>
<event name="OnInitDialog"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
......@@ -760,7 +760,7 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnButtonClick"></event>
<event name="OnButtonClick">OnCancelButtonClick</event>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
......
......@@ -78,12 +78,12 @@ class DialogPadPropertiesBase : public wxDialog
wxCheckBox* m_PadLayerDraft;
// Virtual event handlers, overide them in your derived class
virtual void InitDialog( wxInitDialogEvent& event ){ event.Skip(); }
virtual void OnPadShapeSelection( wxCommandEvent& event ){ event.Skip(); }
virtual void OnDrillShapeSelected( wxCommandEvent& event ){ event.Skip(); }
virtual void PadOrientEvent( wxCommandEvent& event ){ event.Skip(); }
virtual void PadTypeSelected( wxCommandEvent& event ){ event.Skip(); }
virtual void PadPropertiesAccept( wxCommandEvent& event ){ event.Skip(); }
virtual void OnCancelButtonClick( wxCommandEvent& event ){ event.Skip(); }
public:
......
......@@ -609,8 +609,7 @@ void WinEDA_PcbFrame::Process_Special_Functions( wxCommandEvent& event )
*/
zone_cont->Draw( DrawPanel, &dc, GR_XOR );
zone_cont->m_Poly->InsertCorner( zone_cont->m_CornerSelection,
pos.x,
pos.y );
pos.x, pos.y );
zone_cont->m_CornerSelection++;
zone_cont->Draw( DrawPanel, &dc, GR_XOR );
DrawPanel->m_AutoPAN_Request = true;
......@@ -669,7 +668,7 @@ void WinEDA_PcbFrame::Process_Special_Functions( wxCommandEvent& event )
case ID_POPUP_PCB_FILL_ZONE:
DrawPanel->MouseToCursorSchema();
Fill_Zone( NULL, (ZONE_CONTAINER*) GetCurItem() );
Fill_Zone( (ZONE_CONTAINER*) GetCurItem() );
test_1_net_connexion( NULL, ( (ZONE_CONTAINER*) GetCurItem() )->GetNet() );
GetBoard()->DisplayInfo( this );
DrawPanel->Refresh();
......
......@@ -16,9 +16,11 @@
#define ZONE_THERMAL_RELIEF_GAP_STRING_KEY wxT( "Zone_TH_Gap" )
#define ZONE_THERMAL_RELIEF_COPPER_WIDTH_STRING_KEY wxT( "Zone_TH_Copper_Width" )
// Exit codes for dialog edit zones
enum zone_cmd {
ZONE_ABORT,
ZONE_OK
ZONE_ABORT, // if no change
ZONE_OK, // if new values accepted
ZONE_EXPORT_VALUES // if values are exported to others zones
};
......
This diff is collapsed.
/////////////////////////////////////////////////////////////////////////////
// Name: zones_by_polygon_fill_functions.cpp
/////////////////////////////////////////////////////////////////////////////
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 2009 Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
* Copyright (C) 2007 Kicad Developers, see change_log.txt for contributors.
*
* 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 "fctsys.h"
#include "appl_wxstruct.h"
#include "common.h"
#include "class_drawpanel.h"
#include "pcbnew.h"
#include "wxPcbStruct.h"
#include "zones.h"
/**********************************************************************************/
void WinEDA_PcbFrame::Delete_Zone_Fill( SEGZONE* aZone, long aTimestamp )
/**********************************************************************************/
/** Function Delete_Zone_Fill
* Remove the zone fillig which include the segment aZone, or the zone which have the given time stamp.
* A zone is a group of segments which have the same TimeStamp
* @param DC = current Device Context (can be NULL)
* @param aZone = zone segment within the zone to delete. Can be NULL
* @param aTimestamp = Timestamp for the zone to delete, used if aZone == NULL
*/
{
bool modify = false;
unsigned long TimeStamp;
if( aZone == NULL )
TimeStamp = aTimestamp;
else
TimeStamp = aZone->m_TimeStamp; // Save reference time stamp (aZone will be deleted)
SEGZONE* next;
for( SEGZONE* zone = GetBoard()->m_Zone; zone != NULL; zone = next )
{
next = zone->Next();
if( zone->m_TimeStamp == TimeStamp )
{
modify = TRUE;
/* remove item from linked list and free memory */
zone->DeleteStructure();
}
}
// Now delete the outlines of the corresponding copper areas (deprecated)
for( int ii = 0; ii < GetBoard()->GetAreaCount(); ii++ )
{
ZONE_CONTAINER* zone = GetBoard()->GetArea( ii );
if( zone->m_TimeStamp == TimeStamp )
{
modify = TRUE;
zone->m_FilledPolysList.clear();
zone->m_FillSegmList.clear();
zone->m_IsFilled = false;
}
}
if( modify )
{
GetScreen()->SetModify();
GetScreen()->SetRefreshReq();
}
}
/***************************************************************************************/
int WinEDA_PcbFrame::Fill_Zone( ZONE_CONTAINER* zone_container, bool verbose )
/***************************************************************************************/
/** Function Fill_Zone()
* Calculate the zone filling for the outline zone_container
* The zone outline is a frontier, and can be complex (with holes)
* The filling starts from starting points like pads, tracks.
* If exists, the old filling is removed
* @param zone_container = zone to fill
* @param verbose = true to show error messages
* @return error level (0 = no error)
*/
{
wxString msg;
MsgPanel->EraseMsgBox();
if( GetBoard()->ComputeBoundaryBox() == false )
{
if( verbose )
wxMessageBox( wxT( "Board is empty!" ) );
return -1;
}
/* Shows the Net */
g_Zone_Default_Setting.m_NetcodeSelection = zone_container->GetNet();
if( zone_container->GetNet() > 0 )
{
NETINFO_ITEM* net = GetBoard()->FindNet( zone_container->GetNet() );
if( net == NULL )
{
if( verbose )
wxMessageBox( wxT( "Unable to find Net name" ) );
return -2;
}
else
msg = net->GetNetname();
}
else
msg = _( "No Net" );
Affiche_1_Parametre( this, 22, _( "NetName" ), msg, RED );
wxBusyCursor dummy; // Shows an hourglass cursor (removed by its destructor)
zone_container->m_FilledPolysList.clear();
Delete_Zone_Fill( NULL, zone_container->m_TimeStamp );
zone_container->BuildFilledPolysListData( GetBoard() );
GetScreen()->SetModify();
return 0;
}
/************************************************************/
int WinEDA_PcbFrame::Fill_All_Zones( bool verbose )
/************************************************************/
/** Function Fill_All_Zones()
* Fill all zones on the board
* The old fillings are removed
* @param verbose = true to show error messages
* @return error level (0 = no error)
*/
{
ZONE_CONTAINER* zone_container;
int error_level = 0;
// Remove all zones :
GetBoard()->m_Zone.DeleteAll();
for( int ii = 0; ii < GetBoard()->GetAreaCount(); ii++ )
{
zone_container = GetBoard()->GetArea( ii );
error_level = Fill_Zone( zone_container, verbose );
if( error_level && !verbose )
break;
}
test_connexions( NULL );
Tst_Ratsnest( NULL, 0 ); // Recalculate the active ratsnest, i.e. the unconnected links */
DrawPanel->Refresh( true );
return error_level;
}
......@@ -356,8 +356,8 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
}
// Now we remove all unused thermal stubs.
//define REMOVE_UNUSED_THERMAL_STUBS // Can be commented to skip unused thermal stubs calculations
//#ifdef REMOVE_UNUSED_THERMAL_STUBS
#define REMOVE_UNUSED_THERMAL_STUBS // Can be commented to skip unused thermal stubs calculations
#ifdef REMOVE_UNUSED_THERMAL_STUBS
/* Add the main (corrected) polygon (i.e. the filled area using only one outline)
* in GroupA in Bool_Engine to do a BOOL_A_SUB_B operation
......@@ -500,7 +500,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
delete booleng;
//#endif
#endif
}
......@@ -807,7 +807,7 @@ void AddThermalReliefPadPolygon( Bool_Engine* aBooleng,
// this seems a bug in kbool polygon (exists in 1.9 kbool version)
// angle = 450 (45.0 degrees orientation) seems work fine.
// angle = 0 with thermal shapes without angle < 90 deg has problems in rare circumstances
// Note: with the 2 step build ( thermal shpaes after correr areas build), 0 seems work
// Note: with the 2 step build ( thermal shapes added after areas are built), 0 seems work
angle = 450;
int angle_pad = aPad.m_Orient; // Pad orientation
for( unsigned ihole = 0; ihole < 4; ihole++ )
......@@ -1247,7 +1247,7 @@ void AddTextBoxWithClearancePolygon( Bool_Engine* aBooleng,
corners[3].y = corners[2].y;
corners[3].x = corners[0].x;
if( aBooleng->StartPolygonAdd( GROUP_B ) )
{
for( int ii = 0; ii < 4; ii ++ )
......
This diff is collapsed.
/////////////////////////////////////////////////////////////////////////////
// Name: zones_functions_for_undo_redo.h
/////////////////////////////////////////////////////////////////////////////
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 2009 Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
* Copyright (C) 2007 Kicad Developers, see change_log.txt for contributors.
*
* 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
*/
/* These functions are relative to undo redo function, when zones are involved.
* When a zone outline is modified (or created) this zone, or others zones on the same layer
* and with the same netcode can change or can be deleted
* This is due to the fact overlapping zones are merged
* Also, when a zone outline is modified by adding a cutout area,
* this zone can be converted to more than one area, if the outline is break to 2 or more outlines
* and therefore new zones are created
*
* Due to the complexity of potential changes, and the fact there are only few zones
* in a board, and a zone has only few segments outlines, the more easy way to
* undo redo changes is to make a copy of all zones that can be changed
* and see after zone edition or creation what zones that are really modified,
* and ones they are modified (changes, deletion or addition)
*/
#ifndef ZONES_FUNCTIONS_TO_UNDO_REDO_H
#define ZONES_FUNCTIONS_TO_UNDO_REDO_H
/** function SaveCopyOfZones()
* creates a copy of zones having a given netcode on a given layer,
* and fill a pick list with pickers to handle these copies
* @param aPickList = the pick list
* @param aPcb = the Board
* @param aNetCode = the reference netcode. if aNetCode < 0 all netcodes are used
* @param aLayer = the layer of zones. if aLayer < 0, all layers are used
* @return the count of saved copies
*/
int SaveCopyOfZones(PICKED_ITEMS_LIST & aPickList, BOARD* aPcb, int aNetCode, int aLayer );
/** function UpdateCopyOfZonesList()
* check a pick list to remove zones identical to their copies
* and set the type of operation in picker (UR_DELETED, UR_CHANGED)
* @param aPickList = the main pick list
* @param aDeletedList = the list of dleted items
* @param aPcb = the Board
*/
void UpdateCopyOfZonesList( PICKED_ITEMS_LIST& aPickList, PICKED_ITEMS_LIST& aDeletedList, BOARD* aPcb );
#endif // ZONES_FUNCTIONS_TO_UNDO_REDO_H
This diff is collapsed.
......@@ -1489,14 +1489,11 @@ bool CPolyLine::TestPointInsideContour( int icont, int px, int py )
void CPolyLine::Copy( CPolyLine* src )
{
Undraw();
// copy corners
for( unsigned ii = 0; ii < src->corner.size(); ii++ )
corner.push_back( src->corner[ii] );
// copy side styles
for( unsigned ii = 0; ii < src->side_style.size(); ii++ )
side_style.push_back( src->side_style[ii] );
m_HatchStyle = src->m_HatchStyle;
// copy corners, using vector copy
corner = src->corner;
// copy side styles, using vector copy
side_style = src->side_style;
}
......
......@@ -102,6 +102,12 @@ public:
int y;
bool end_contour;
int utility;
bool operator == (const CPolyPt& cpt2 ) const
{ return (x == cpt2.x) && (y == cpt2.y) && (end_contour == cpt2.end_contour); }
bool operator != (CPolyPt& cpt2 ) const
{ return (x != cpt2.x) || (y != cpt2.y) || (end_contour != cpt2.end_contour); }
};
#include "polygon_test_point_inside.h"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment