KiCad PCB EDA Suite
Loading...
Searching...
No Matches
zones_functions_for_undo_redo.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2009 Jean-Pierre Charras <[email protected]>
5 * Copyright (C) 2007-2022 KiCad Developers, see change_log.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, you may find one here:
19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20 * or you may search the http://www.gnu.org website for the version 2 license,
21 * or you may write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
25
26/* These functions are relative to undo redo function, when zones are involved.
27 *
28 * When a zone outline is modified (or created) this zone, or others zones on the same layer
29 * and with the same netcode can change or can be deleted due to the fact overlapping zones are
30 * merged. Also, when a zone outline is modified by adding a cutout area, this zone can be
31 * converted to more than one area, if the outline is break to 2 or more outlines and therefore
32 * new zones are created
33 *
34 * Due to the complexity of potential changes, and the fact there are only few zones in a board,
35 * and a zone has only few segments outlines, the more easy way to undo redo changes is to make
36 * a copy of all zones that can be changed and see after zone editing or creation what zones that
37 * are really modified, and ones they are modified (changes, deletion or addition)
38 */
39
40#include <pcb_edit_frame.h>
41
42#include <board.h>
43#include <zone.h>
44#include <zones.h>
45#include <zones_functions_for_undo_redo.h>
46
54bool ZONE::IsSame( const ZONE& aZoneToCompare )
55{
56 // compare basic parameters:
57 if( GetLayerSet() != aZoneToCompare.GetLayerSet() )
58 return false;
59
60 if( GetNetCode() != aZoneToCompare.GetNetCode() )
61 return false;
62
63 if( GetAssignedPriority() != aZoneToCompare.GetAssignedPriority() )
64 return false;
65
66 // Compare zone specific parameters
67 if( GetIsRuleArea() != aZoneToCompare.GetIsRuleArea() )
68 return false;
69
70 if( GetIsRuleArea() && GetRuleAreaType() == RULE_AREA_TYPE::KEEPOUT )
71 {
72 if( GetDoNotAllowCopperPour() != aZoneToCompare.GetDoNotAllowCopperPour() )
73 return false;
74
75 if( GetDoNotAllowVias() != aZoneToCompare.GetDoNotAllowVias() )
76 return false;
77
78 if( GetDoNotAllowTracks() != aZoneToCompare.GetDoNotAllowTracks() )
79 return false;
80
81 if( GetDoNotAllowPads() != aZoneToCompare.GetDoNotAllowPads() )
82 return false;
83
84 if( GetDoNotAllowFootprints() != aZoneToCompare.GetDoNotAllowFootprints() )
85 return false;
86 }
87
88 if( GetIsRuleArea() && GetRuleAreaType() == RULE_AREA_TYPE::PLACEMENT )
89 {
90 if( GetRuleAreaExpression() != aZoneToCompare.GetRuleAreaExpression() )
91 return false;
92 }
93
94 if( m_ZoneClearance != aZoneToCompare.m_ZoneClearance )
95 return false;
96
97 if( m_ZoneMinThickness != aZoneToCompare.GetMinThickness() )
98 return false;
99
100 if( m_fillMode != aZoneToCompare.GetFillMode() )
101 return false;
102
103 if( m_PadConnection != aZoneToCompare.m_PadConnection )
104 return false;
105
106 if( m_thermalReliefGap != aZoneToCompare.m_thermalReliefGap )
107 return false;
108
110 return false;
111
112 if( m_zoneName != aZoneToCompare.m_zoneName )
113 return false;
114
115 if( m_islandRemovalMode != aZoneToCompare.m_islandRemovalMode )
116 return false;
117
118 if( m_minIslandArea != aZoneToCompare.m_minIslandArea )
119 return false;
120
121
122 // Compare outlines
123 wxASSERT( m_Poly ); // m_Poly == NULL Should never happen
124 wxASSERT( aZoneToCompare.Outline() );
125
126 if( Outline() != aZoneToCompare.Outline() ) // Compare vector
127 return false;
128
129 return true;
130}
131
132
142void SaveCopyOfZones( PICKED_ITEMS_LIST& aPickList, BOARD* aPcb )
143{
144 for( ZONE* zone : aPcb->Zones() )
145 {
146 ZONE* zoneDup = new ZONE( *zone );
147 zoneDup->SetParent( aPcb );
148 zoneDup->SetParentGroup( nullptr );
149
150 ITEM_PICKER picker( nullptr, zone, UNDO_REDO::CHANGED );
151 picker.SetLink( zoneDup );
152 aPickList.PushItem( picker );
153 }
154}
155
156
193 BOARD* aPcb )
194{
195 for( unsigned kk = 0; kk < aPickList.GetCount(); kk++ )
196 {
197 UNDO_REDO status = aPickList.GetPickedItemStatus( kk );
198
199 ZONE* ref = (ZONE*) aPickList.GetPickedItem( kk );
200
201 for( unsigned ii = 0; ; ii++ ) // analyse the main picked list
202 {
203 ZONE* zone = aPcb->GetArea( ii );
204
205 if( zone == nullptr )
206 {
207 /* End of list: the stored item is not found:
208 * it must be in aDeletedList:
209 * search it and restore initial values
210 * or
211 * if flagged NEWITEM: remove it definitively
212 */
213 if( status == UNDO_REDO::NEWITEM )
214 {
215 delete ref;
216 ref = nullptr;
217 aPickList.RemovePicker( kk );
218 kk--;
219 }
220 else
221 {
222 ZONE* zcopy = (ZONE*) aPickList.GetPickedItemLink( kk );
224
225 wxASSERT_MSG( zcopy != nullptr,
226 wxT( "UpdateCopyOfZonesList() error: link = NULL" ) );
227
228 ref->SwapItemData( zcopy );
229
230 // the copy was deleted; the link does not exists now.
231 aPickList.SetPickedItemLink( nullptr, kk );
232 delete zcopy;
233 }
234
235 // Remove this item from aAuxiliaryList, mainly for tests purpose
236 bool notfound = true;
237
238 for( unsigned nn = 0; nn < aAuxiliaryList.GetCount(); nn++ )
239 {
240 if( ref != nullptr && aAuxiliaryList.GetPickedItem( nn ) == ref )
241 {
242 aAuxiliaryList.RemovePicker( nn );
243 notfound = false;
244 break;
245 }
246 }
247
248 if( notfound ) // happens when the new zone overlaps an existing zone
249 // and these zones are combined
250 {
251#if defined(DEBUG)
252 printf( "UpdateCopyOfZonesList(): item not found in aAuxiliaryList,"
253 "combined with another zone\n" );
254 fflush(nullptr);
255#endif
256 }
257
258 break;
259 }
260
261 if( zone == ref ) // picked zone found
262 {
263 if( aPickList.GetPickedItemStatus( kk ) != UNDO_REDO::NEWITEM )
264 {
265 ZONE* zcopy = (ZONE*) aPickList.GetPickedItemLink( kk );
266
267 if( zone->IsSame( *zcopy ) ) // Remove picked, because no changes
268 {
269 delete zcopy; // Delete copy
270 aPickList.RemovePicker( kk );
271 kk--;
272 }
273 }
274
275 break;
276 }
277 }
278 }
279
280 // Add new zones in main pick list, and remove pickers from Auxiliary List
281 for( unsigned ii = 0; ii < aAuxiliaryList.GetCount(); )
282 {
283 if( aAuxiliaryList.GetPickedItemStatus( ii ) == UNDO_REDO::NEWITEM )
284 {
285 ITEM_PICKER picker = aAuxiliaryList.GetItemWrapper( ii );
286 aPickList.PushItem( picker );
287 aAuxiliaryList.RemovePicker( ii );
288 }
289 else if( aAuxiliaryList.GetPickedItemStatus( ii ) == UNDO_REDO::DELETED )
290 {
291 delete aAuxiliaryList.GetPickedItemLink( ii );
292 aAuxiliaryList.RemovePicker( ii );
293 }
294 else
295 {
296 ii++;
297 }
298 }
299
300 // Should not occur:
301 wxASSERT_MSG( aAuxiliaryList.GetCount() == 0,
302 wxT( "UpdateCopyOfZonesList() error: aAuxiliaryList not empty." ) );
303}
void SetParentGroup(PCB_GROUP *aGroup)
Definition: board_item.h:92
void SwapItemData(BOARD_ITEM *aImage)
Swap data between aItem and aImage.
Definition: board_item.cpp:226
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:289
ZONE * GetArea(int index) const
Return the Zone at a given index.
Definition: board.h:1021
const ZONES & Zones() const
Definition: board.h:334
virtual void SetParent(EDA_ITEM *aParent)
Definition: eda_item.h:104
void SetLink(EDA_ITEM *aItem)
A holder to handle information on schematic or board items.
bool SetPickedItemStatus(UNDO_REDO aStatus, unsigned aIdx)
Set the type of undo/redo operation for a given picked item.
void PushItem(const ITEM_PICKER &aItem)
Push aItem to the top of the list.
UNDO_REDO GetPickedItemStatus(unsigned int aIdx) const
ITEM_PICKER GetItemWrapper(unsigned int aIdx) const
EDA_ITEM * GetPickedItemLink(unsigned int aIdx) const
bool RemovePicker(unsigned aIdx)
Remove one entry (one picker) from the list of picked items.
unsigned GetCount() const
bool SetPickedItemLink(EDA_ITEM *aLink, unsigned aIdx)
Set the link associated to a given picked item.
EDA_ITEM * GetPickedItem(unsigned int aIdx) const
Handle a list of polygons defining a copper zone.
Definition: zone.h:73
bool GetIsRuleArea() const
Accessors to parameters used in Rule Area zones:
Definition: zone.h:711
bool GetDoNotAllowVias() const
Definition: zone.h:715
ZONE_FILL_MODE m_fillMode
How to fill areas:
Definition: zone.h:882
int m_ZoneMinThickness
Definition: zone.h:851
int m_thermalReliefSpokeWidth
Definition: zone.h:873
wxString m_zoneName
An optional unique name for this zone, used for identifying it in DRC checking.
Definition: zone.h:817
RULE_AREA_TYPE GetRuleAreaType() const
Definition: zone.h:712
bool GetDoNotAllowPads() const
Definition: zone.h:717
const wxString & GetRuleAreaExpression() const
Definition: zone.h:713
bool GetDoNotAllowTracks() const
Definition: zone.h:716
SHAPE_POLY_SET * Outline()
Definition: zone.h:337
SHAPE_POLY_SET * m_Poly
Outline of the zone.
Definition: zone.h:812
int m_ZoneClearance
Definition: zone.h:850
int GetMinThickness() const
Definition: zone.h:270
bool GetDoNotAllowFootprints() const
Definition: zone.h:718
ZONE_FILL_MODE GetFillMode() const
Definition: zone.h:193
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
Definition: zone.h:130
bool GetDoNotAllowCopperPour() const
Definition: zone.h:714
ISLAND_REMOVAL_MODE m_islandRemovalMode
Definition: zone.h:854
int m_thermalReliefGap
Definition: zone.h:872
ZONE_CONNECTION m_PadConnection
Definition: zone.h:849
unsigned GetAssignedPriority() const
Definition: zone.h:120
long long int m_minIslandArea
When island removal mode is set to AREA, islands below this area will be removed.
Definition: zone.h:860
UNDO_REDO
Undo Redo considerations: Basically we have 3 cases New item Deleted item Modified item there is also...
void UpdateCopyOfZonesList(PICKED_ITEMS_LIST &aPickList, PICKED_ITEMS_LIST &aAuxiliaryList, BOARD *aPcb)
Function UpdateCopyOfZonesList Check a pick list to remove zones identical to their copies and set th...
void SaveCopyOfZones(PICKED_ITEMS_LIST &aPickList, BOARD *aPcb)
Function SaveCopyOfZones creates a copy of zones having a given netcode on a given layer,...