KiCad PCB EDA Suite
Loading...
Searching...
No Matches
zone_settings_bag.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) 2023 Ethan Chien <[email protected]>
5 * Copyright The KiCad Developers, see AUTHORS.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, see <https://www.gnu.org/licenses/>.
19 */
20
21#include "zone_settings_bag.h"
22
23#include <zone.h>
24#include <memory>
25#include <algorithm>
26
27
29{
30 for( ZONE* zone : aBoard->Zones() )
31 {
32 if( !zone->GetIsRuleArea() && !zone->IsTeardropArea() && !zone->IsCopperThieving()
33 && zone->IsOnCopperLayer() )
34 {
35 auto zone_clone = std::shared_ptr<ZONE>( static_cast<ZONE*>( zone->Clone() ) );
36 m_zonesCloneMap.try_emplace( zone, zone_clone );
37 m_clonedZoneList.push_back( zone_clone.get() );
38 }
39 }
40
41 for( ZONE* zone : m_clonedZoneList )
42 {
43 m_zoneSettings[zone] = std::make_shared<ZONE_SETTINGS>();
44 *m_zoneSettings[zone] << *zone;
45 }
46
47 std::vector<ZONE*> sortedClonedZones = m_clonedZoneList;
48
49 std::sort( sortedClonedZones.begin(), sortedClonedZones.end(),
50 []( ZONE* const& l, ZONE* const& r )
51 {
52 return l->HigherPriority( r );
53 } );
54
55 unsigned currentPriority = sortedClonedZones.size() - 1;
56
57 for( ZONE* zone : sortedClonedZones )
58 {
59 m_zonePriorities[zone] = std::make_pair<>( currentPriority, currentPriority );
60 --currentPriority;
61 }
62}
63
64
66{
67 m_zoneSettings[aZone] = std::make_shared<ZONE_SETTINGS>( *aSettings );
68}
69
70
71std::shared_ptr<ZONE_SETTINGS> ZONE_SETTINGS_BAG::GetZoneSettings( ZONE* aZone )
72{
73 return m_zoneSettings[aZone];
74}
75
76
78{
79 return m_zonePriorities[aZone].second;
80}
81
82
83void ZONE_SETTINGS_BAG::SwapPriority( ZONE* aZone, ZONE* otherZone )
84{
85 std::swap( m_zonePriorities[aZone].second, m_zonePriorities[otherZone].second );
86}
87
88
89wxString ZONE_SETTINGS_BAG::GetUniqueZoneName( const BOARD& aBoard, const wxString& aBaseName, const ZONE* aZone ) const
90{
91 auto inUse =
92 [&]( const wxString& aName )
93 {
94 for( ZONE* zone : aBoard.Zones() )
95 {
96 ZONE* working = zone;
97
98 if( auto clone = m_zonesCloneMap.find( zone ); clone != m_zonesCloneMap.end() )
99 working = clone->second.get();
100
101 if( working == aZone )
102 continue;
103
104 auto settings = m_zoneSettings.find( working );
105 wxString name = working->GetZoneName();
106
107 if( settings != m_zoneSettings.end() && settings->second )
108 name = settings->second->m_Name;
109
110 if( name == aName )
111 return true;
112 }
113
114 return false;
115 };
116
117 return BOARD::MakeUniqueZoneName( aBaseName, inUse );
118}
119
120
121void ZONE_SETTINGS_BAG::SetZonePriority( ZONE* aClone, unsigned aPriority )
122{
123 m_zonePriorities[aClone].second = aPriority;
124
125 if( m_zoneSettings.contains( aClone ) )
126 m_zoneSettings[aClone]->m_ZonePriority = aPriority;
127}
128
129
131{
132 auto it = m_zonesCloneMap.find( aOriginalZone );
133
134 if( it != m_zonesCloneMap.end() )
135 {
136 ZONE* clone = it->second.get();
137
138 // Remove from cloned list
139 m_clonedZoneList.erase( std::remove( m_clonedZoneList.begin(), m_clonedZoneList.end(), clone ),
140 m_clonedZoneList.end() );
141
142
143 // Remove from zone settings and priorities maps
144 m_zoneSettings.erase( clone );
145 m_zonePriorities.erase( clone );
146
147 // Remove from clone map
148 m_zonesCloneMap.erase( it );
149 }
150}
151
152
154{
155 for( ZONE* zone : m_clonedZoneList )
156 {
157 if( m_zoneSettings.contains( zone ) )
158 m_zoneSettings[zone]->ExportSetting( *zone );
159 }
160
161 // Prevent version-control churn by not updating potentially sparse priorities if their
162 // order didn't change.
163 bool priorityChanged = false;
164
165 for( ZONE* zone : m_clonedZoneList )
166 {
167 if( m_zonePriorities[zone].first != m_zonePriorities[zone].second )
168 {
169 priorityChanged = true;
170 break;
171 }
172 }
173
174 if( priorityChanged )
175 {
176 for( ZONE* zone : m_clonedZoneList )
177 zone->SetAssignedPriority( m_zonePriorities[zone].second );
178 }
179}
const char * name
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:411
const ZONES & Zones() const
Definition board.h:469
static wxString MakeUniqueZoneName(const wxString &aBaseName, const std::function< bool(const wxString &)> &aInUse)
Return a name based on aBaseName for which aInUse returns false, adding or incrementing a _<number> s...
Definition board.cpp:1483
void SetZonePriority(ZONE *aClone, unsigned aPriority)
Update the tracked priority for a cloned zone.
unsigned GetZonePriority(ZONE *aZone)
ZONE_SETTINGS_BAG()=default
std::unordered_map< ZONE *, std::shared_ptr< ZONE > > m_zonesCloneMap
void RemoveZone(ZONE *aOriginalZone)
Remove a zone from the bag (used when marking for deletion)
void UpdateClonedZones()
The cloned list is the working storage.
std::vector< ZONE * > m_clonedZoneList
wxString GetUniqueZoneName(const BOARD &aBoard, const wxString &aBaseName, const ZONE *aZone) const
Return a name based on aBaseName that no other zone on aBoard uses.
void SwapPriority(ZONE *aZOne, ZONE *otherZone)
std::unordered_map< ZONE *, std::shared_ptr< ZONE_SETTINGS > > m_zoneSettings
std::shared_ptr< ZONE_SETTINGS > GetZoneSettings(ZONE *aZone)
std::unordered_map< ZONE *, std::pair< unsigned, unsigned > > m_zonePriorities
Handle zones parameters.
Handle a list of polygons defining a copper zone.
Definition zone.h:70
const wxString & GetZoneName() const
Definition zone.h:160