Merge ~ross-schlaikjer/kicad:footprint-keepouts into ~kicad-product-committers/kicad:master
- Git
- lp:~ross-schlaikjer/kicad
- footprint-keepouts
- Merge into master
Status: | Merged | ||||
---|---|---|---|---|---|
Merge reported by: | jean-pierre charras | ||||
Merged at revision: | 97a18d2f2ba8f0ba6d58557a7c2f6ae9b94ac6a3 | ||||
Proposed branch: | ~ross-schlaikjer/kicad:footprint-keepouts | ||||
Merge into: | ~kicad-product-committers/kicad:master | ||||
Diff against target: |
854 lines (+302/-62) 23 files modified
include/base_struct.h (+19/-0) include/commit.h (+3/-3) pcbnew/board_commit.cpp (+24/-0) pcbnew/board_commit.h (+4/-0) pcbnew/board_item_container.h (+21/-0) pcbnew/class_board.cpp (+23/-0) pcbnew/class_board.h (+6/-4) pcbnew/class_module.cpp (+80/-0) pcbnew/class_module.h (+11/-3) pcbnew/class_zone.cpp (+5/-5) pcbnew/class_zone.h (+1/-1) pcbnew/collectors.cpp (+4/-13) pcbnew/footprint_editor_utils.cpp (+32/-0) pcbnew/kicad_plugin.cpp (+4/-0) pcbnew/kicad_plugin.h (+2/-1) pcbnew/menubar_footprint_editor.cpp (+7/-6) pcbnew/pcb_parser.cpp (+18/-8) pcbnew/pcb_parser.h (+2/-1) pcbnew/toolbars_footprint_editor.cpp (+13/-11) pcbnew/tools/drc.cpp (+4/-2) pcbnew/tools/selection_tool.cpp (+15/-0) pcbnew/tools/zone_create_helper.cpp (+3/-2) pcbnew/zone_filler.cpp (+1/-2) |
||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Seth Hillbrand | Approve | ||
Review via email: mp+361410@code.launchpad.net |
Commit message
This changeset adds support for specifying keep-out zones inside of footprints.
It is based off of the incomplete changeset by Oliver Walters, which was pulled from his exchange from Jean-Pierre Charras here: https:/
This does necessitate a version bump for the module format in order to allow zones to be present.
Description of the change
The following features have been added:
- Keepout zones can now be defined in the footprint editor, and can be applied to any combination of copper layers.
- DRC respects keepout zones defined in footprints
- Keepouts defined in footprints are taken into account when generating copper pours.
I am fairly confident in the functionality of this changeset, but would appreciate a review from someone more familiar with the KiCad codebase to ensure it follows the current best practices.
Wayne Stambaugh (stambaughw) wrote : | # |
Seth Hillbrand (sethh) wrote : | # |
@Ross-
Could you rebase your changeset to the current master so that we can review this now that v6 is open for development?
A couple changes I see needed:
- Please use the DECL_DEQ_FOR_SWIG instead of the dlist
- Instead of hotkey definition, please use the hotkey actions
- Code formatting (use tools/check_
Jeff Young (jeyjey) wrote : | # |
@Ross, I've got some time to help out with this. If you could rebase on the current master and incorporate the comments that would be great. If you have any questions (or don't have time to do it) let me know.
(Probably better to use the developer's email list than do it here, as I'm more likely to see it there.)
- 97a18d2... by Ross Schlaikjer
-
Add keepout zones in footprints
This changeset allows the creation of keepout zones in footprints.
This necessitates a change to the pcbnew file format version.
Ross Schlaikjer (ross-schlaikjer) wrote : | # |
@Jeff,
Thanks for the review. I've finally had enough time to go through and rebuild this PR against current master. If you wouldn't mind taking another look that would be great. I've applied for membership to the developer's email list, so if that comes through we can move the conversation there if that's easier for you.
@Seth,
About the code formatting - if I go through and run clang-format on the changed files, there are a large number of collateral changes - is this acceptable? Or should I go through, clang-format, and then only add the changes to code I have already changed?
Thanks.
Seth Hillbrand (sethh) wrote : | # |
@Ross-
The collateral (I assume that this is re-ordering headers) is fine. This reflects our long-term plan but we haven't gone through all files specifically to do this, so it comes up as we edit.
Please squash these into a single commit for pushing to the main branch.
Thanks again!
Ross Schlaikjer (ross-schlaikjer) wrote : | # |
Turns out that the extra changes I was seeing were due to me running a bare `clang-format` as opposed to a `git clang-format`, which gives a different result even with the same style file.
Changes have been formatted with `git clang-format master` and squashed.
Seth Hillbrand (sethh) wrote : | # |
I gave this a run and it's basically ready. I attached a few minor comments to fix below.
The biggest issue I find is that once the footprint is placed in pcbnew, the keepout zone is not treated as part of the footprint. That is to say, it can be moved independently of the footprint and selecting it does not select the footprint itself. This should be compared with the polygon tool for reference to expected behavior.
Once that last issue is addressed, I think this is ready to merge, barring other dev comments. Nice work!
Ross Schlaikjer (ross-schlaikjer) wrote : | # |
Hi Seth,
Thanks for the review. I've squashed your smaller review comments in, but I'm having trouble finding where the move tool handles the case where the item is part of a module - do you have any pointers on where to look in the codebase / what keywords to grep for?
Seth Hillbrand (sethh) wrote : | # |
Hi Ross-
Sure thing! You are actually looking for where items get selected (not moved). The logic is that you cannot select just the _part_ of the footprint, you want to select the footprint object itself. As long as your footprint hittest includes the zone, you just need to exclude the zone from the possible selections. This is in SELECTION_
Ross Schlaikjer (ross-schlaikjer) wrote : | # |
Seth,
Alright, finally had a chance to finish this up. Keepouts specified in footprints are now treated like polygons for selection and can't be independently modified on the PCB.
Thanks for your help.
Seth Hillbrand (sethh) wrote : | # |
This looks good to me. Thanks Ross! Any objections to this patch?
Oliver (schrodingersgat) wrote : | # |
Ross, I'm very excited that you have taken up the baton on this one!
Ian McInerney (imcinerney) wrote : | # |
This appears to have been committed by JP in https:/
Ross Schlaikjer (ross-schlaikjer) wrote : | # |
And it looks like they fixed some bugs / missing functionality as well. Apologies for not being able to get to those in time! I very much appreciate the hard work, thank you all for helping to get this feature added.
Wayne Stambaugh (stambaughw) wrote : | # |
@JP, did you intend to merge this? The status wasn't set to approved yet so I'm curious if you did some more testing to confirm if there are any other issues. I trust your judgement but the merge just came as a bit of a surprise. If everything is good to go, please set the status of the merge request to merged so it gets closed out. Thanks.
jean-pierre charras (jp-charras) wrote : | # |
@Wayne, I merged this a few time ago, with a *lot* of fixes and added missing features.
I forgot to set the status to merged.
I just updated it now.
Wayne Stambaugh (stambaughw) wrote : | # |
@JP, thanks for fixing and merging this and thank you @Ross for you contribution to KiCad. This knocks out one of the road map tasks for V6!
Ian McInerney (imcinerney) wrote : | # |
Does this fully close out the associated wishlist item [1] for this?
Wayne Stambaugh (stambaughw) wrote : | # |
I think the status of lp:1081846 can be changed to "Fix Committed".
Ian McInerney (imcinerney) wrote : | # |
Sounds good. I just switched it over to "Fix Committed".
Preview Diff
1 | diff --git a/include/base_struct.h b/include/base_struct.h |
2 | index e0c6db6..bf60b05 100644 |
3 | --- a/include/base_struct.h |
4 | +++ b/include/base_struct.h |
5 | @@ -451,6 +451,25 @@ public: |
6 | } |
7 | |
8 | /** |
9 | + * @copydoc SEARCH_RESULT IterateForward( EDA_ITEM*, INSPECTOR, void*, const KICAD_T ) |
10 | + * |
11 | + * This changes first parameter to avoid the DList and use std::vector instead |
12 | + */ |
13 | + template <class T> |
14 | + static SEARCH_RESULT IterateForward( |
15 | + std::vector<T>& aList, INSPECTOR inspector, void* testData, const KICAD_T scanTypes[] ) |
16 | + { |
17 | + for( auto it : aList ) |
18 | + { |
19 | + if( static_cast<EDA_ITEM*>( it )->Visit( inspector, testData, scanTypes ) |
20 | + == SEARCH_QUIT ) |
21 | + return SEARCH_QUIT; |
22 | + } |
23 | + |
24 | + return SEARCH_CONTINUE; |
25 | + } |
26 | + |
27 | + /** |
28 | * Function GetClass |
29 | * returns the class name. |
30 | * @return wxString |
31 | diff --git a/include/commit.h b/include/commit.h |
32 | index 9498a51..5b8927e 100644 |
33 | --- a/include/commit.h |
34 | +++ b/include/commit.h |
35 | @@ -123,11 +123,11 @@ public: |
36 | |
37 | |
38 | ///> Adds a change of the item aItem of type aChangeType to the change list. |
39 | - COMMIT& Stage( EDA_ITEM* aItem, CHANGE_TYPE aChangeType ); |
40 | + virtual COMMIT& Stage( EDA_ITEM* aItem, CHANGE_TYPE aChangeType ); |
41 | |
42 | - COMMIT& Stage( std::vector<EDA_ITEM*>& container, CHANGE_TYPE aChangeType ); |
43 | + virtual COMMIT& Stage( std::vector<EDA_ITEM*>& container, CHANGE_TYPE aChangeType ); |
44 | |
45 | - COMMIT& Stage( const PICKED_ITEMS_LIST& aItems, UNDO_REDO_T aModFlag = UR_UNSPECIFIED ); |
46 | + virtual COMMIT& Stage( const PICKED_ITEMS_LIST& aItems, UNDO_REDO_T aModFlag = UR_UNSPECIFIED ); |
47 | |
48 | ///> Executes the changes. |
49 | virtual void Push( const wxString& aMessage = wxT( "A commit" ), |
50 | diff --git a/pcbnew/board_commit.cpp b/pcbnew/board_commit.cpp |
51 | index 82ba02a..ed09984 100644 |
52 | --- a/pcbnew/board_commit.cpp |
53 | +++ b/pcbnew/board_commit.cpp |
54 | @@ -56,6 +56,30 @@ BOARD_COMMIT::~BOARD_COMMIT() |
55 | { |
56 | } |
57 | |
58 | +COMMIT& BOARD_COMMIT::Stage( EDA_ITEM* aItem, CHANGE_TYPE aChangeType ) |
59 | +{ |
60 | + // if aItem belongs a footprint, the full footprint will be saved |
61 | + // because undo/redo does not handle "sub items" modifications |
62 | + if( aItem && aItem->Type() != PCB_MODULE_T && aChangeType == CHT_MODIFY ) |
63 | + { |
64 | + EDA_ITEM* item = aItem->GetParent(); |
65 | + |
66 | + if( item && item->Type() == PCB_MODULE_T ) // means aItem belongs a footprint |
67 | + aItem = item; |
68 | + } |
69 | + |
70 | + return COMMIT::Stage( aItem, aChangeType ); |
71 | +} |
72 | + |
73 | +COMMIT& BOARD_COMMIT::Stage( std::vector<EDA_ITEM*>& container, CHANGE_TYPE aChangeType ) |
74 | +{ |
75 | + return COMMIT::Stage( container, aChangeType ); |
76 | +} |
77 | + |
78 | +COMMIT& BOARD_COMMIT::Stage( const PICKED_ITEMS_LIST& aItems, UNDO_REDO_T aModFlag ) |
79 | +{ |
80 | + return COMMIT::Stage( aItems, aModFlag ); |
81 | +} |
82 | |
83 | void BOARD_COMMIT::Push( const wxString& aMessage, bool aCreateUndoEntry, bool aSetDirtyBit ) |
84 | { |
85 | diff --git a/pcbnew/board_commit.h b/pcbnew/board_commit.h |
86 | index 45fe90b..1f90b5c 100644 |
87 | --- a/pcbnew/board_commit.h |
88 | +++ b/pcbnew/board_commit.h |
89 | @@ -46,6 +46,10 @@ public: |
90 | bool aCreateUndoEntry = true, bool aSetDirtyBit = true ) override; |
91 | |
92 | virtual void Revert() override; |
93 | + COMMIT& Stage( EDA_ITEM* aItem, CHANGE_TYPE aChangeType ) override; |
94 | + COMMIT& Stage( std::vector<EDA_ITEM*>& container, CHANGE_TYPE aChangeType ) override; |
95 | + COMMIT& Stage( |
96 | + const PICKED_ITEMS_LIST& aItems, UNDO_REDO_T aModFlag = UR_UNSPECIFIED ) override; |
97 | |
98 | private: |
99 | TOOL_MANAGER* m_toolMgr; |
100 | diff --git a/pcbnew/board_item_container.h b/pcbnew/board_item_container.h |
101 | index aa967b0..0d3869b 100644 |
102 | --- a/pcbnew/board_item_container.h |
103 | +++ b/pcbnew/board_item_container.h |
104 | @@ -28,6 +28,7 @@ |
105 | #define BOARD_ITEM_CONTAINER_H |
106 | |
107 | #include <class_board_item.h> |
108 | +#include <zone_settings.h> |
109 | |
110 | enum ADD_MODE { ADD_INSERT, ADD_APPEND }; |
111 | |
112 | @@ -63,6 +64,26 @@ public: |
113 | Remove( aItem ); |
114 | delete aItem; |
115 | } |
116 | + |
117 | + /** |
118 | + * @brief Fetch the zone settings for this container |
119 | + */ |
120 | + const ZONE_SETTINGS& GetZoneSettings() const |
121 | + { |
122 | + return m_zoneSettings; |
123 | + } |
124 | + |
125 | + /** |
126 | + * @brief Set the zone settings for this container |
127 | + * @param aSettings new Zone settings for this container |
128 | + */ |
129 | + void SetZoneSettings( const ZONE_SETTINGS& aSettings ) |
130 | + { |
131 | + m_zoneSettings = aSettings; |
132 | + } |
133 | + |
134 | +private: |
135 | + ZONE_SETTINGS m_zoneSettings; |
136 | }; |
137 | |
138 | #endif /* BOARD_ITEM_CONTAINER_H */ |
139 | diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp |
140 | index 26d4b3d..2ce34c8 100644 |
141 | --- a/pcbnew/class_board.cpp |
142 | +++ b/pcbnew/class_board.cpp |
143 | @@ -1519,6 +1519,29 @@ MODULE* BOARD::GetFootprint( const wxPoint& aPosition, PCB_LAYER_ID aActiveLayer |
144 | return NULL; |
145 | } |
146 | |
147 | +std::list<ZONE_CONTAINER*> BOARD::GetZoneList( bool aIncludeZonesInFootprints ) |
148 | +{ |
149 | + std::list<ZONE_CONTAINER*> zones; |
150 | + |
151 | + for( int ii = 0; ii < GetAreaCount(); ii++ ) |
152 | + { |
153 | + zones.push_back( GetArea( ii ) ); |
154 | + } |
155 | + |
156 | + if( aIncludeZonesInFootprints ) |
157 | + { |
158 | + for( MODULE* mod : m_modules ) |
159 | + { |
160 | + for( ZONE_CONTAINER* zone : mod->Zones() ) |
161 | + { |
162 | + zones.push_back( zone ); |
163 | + } |
164 | + } |
165 | + } |
166 | + |
167 | + return zones; |
168 | +} |
169 | + |
170 | |
171 | ZONE_CONTAINER* BOARD::AddArea( PICKED_ITEMS_LIST* aNewZonesList, int aNetcode, |
172 | PCB_LAYER_ID aLayer, wxPoint aStartPointPosition, int aHatch ) |
173 | diff --git a/pcbnew/class_board.h b/pcbnew/class_board.h |
174 | index 25bc1f7..919bd18 100644 |
175 | --- a/pcbnew/class_board.h |
176 | +++ b/pcbnew/class_board.h |
177 | @@ -192,7 +192,6 @@ private: |
178 | std::shared_ptr<CONNECTIVITY_DATA> m_connectivity; |
179 | |
180 | BOARD_DESIGN_SETTINGS m_designSettings; |
181 | - ZONE_SETTINGS m_zoneSettings; |
182 | PCB_GENERAL_SETTINGS* m_generalSettings; ///< reference only; I have no ownership |
183 | PAGE_INFO m_paper; |
184 | TITLE_BLOCK m_titles; ///< text in lower right of screen and plots |
185 | @@ -561,9 +560,6 @@ public: |
186 | TITLE_BLOCK& GetTitleBlock() { return m_titles; } |
187 | void SetTitleBlock( const TITLE_BLOCK& aTitleBlock ) { m_titles = aTitleBlock; } |
188 | |
189 | - const ZONE_SETTINGS& GetZoneSettings() const { return m_zoneSettings; } |
190 | - void SetZoneSettings( const ZONE_SETTINGS& aSettings ) { m_zoneSettings = aSettings; } |
191 | - |
192 | wxString GetSelectMenuText( EDA_UNITS_T aUnits ) const override; |
193 | |
194 | /** |
195 | @@ -949,6 +945,12 @@ public: |
196 | } |
197 | |
198 | /** |
199 | + * Function GetZoneList |
200 | + * @return a std::list of pointers to all board zones (possibly including zones in footprints) |
201 | + */ |
202 | + std::list<ZONE_CONTAINER*> GetZoneList( bool aIncludeZonesInFootprints = false ); |
203 | + |
204 | + /** |
205 | * Function GetAreaCount |
206 | * @return int - The number of Areas or ZONE_CONTAINER. |
207 | */ |
208 | diff --git a/pcbnew/class_module.cpp b/pcbnew/class_module.cpp |
209 | index 06ce251..416fc0d 100644 |
210 | --- a/pcbnew/class_module.cpp |
211 | +++ b/pcbnew/class_module.cpp |
212 | @@ -108,6 +108,10 @@ MODULE::MODULE( const MODULE& aModule ) : |
213 | Add( new D_PAD( *pad ) ); |
214 | } |
215 | |
216 | + // Copy auxiliary data: Zones |
217 | + for( auto item : aModule.Zones() ) |
218 | + Add( static_cast<ZONE_CONTAINER*>( item->Clone() ) ); |
219 | + |
220 | // Copy auxiliary data: Drawings |
221 | for( auto item : aModule.GraphicalItems() ) |
222 | { |
223 | @@ -152,6 +156,11 @@ MODULE::~MODULE() |
224 | |
225 | m_pads.clear(); |
226 | |
227 | + for( auto p : m_zones ) |
228 | + delete p; |
229 | + |
230 | + m_zones.clear(); |
231 | + |
232 | for( auto d : m_drawings ) |
233 | delete d; |
234 | |
235 | @@ -197,6 +206,14 @@ MODULE& MODULE::operator=( const MODULE& aOther ) |
236 | Add( new D_PAD( *pad ) ); |
237 | } |
238 | |
239 | + // Copy auxiliary data: Zones |
240 | + m_zones.clear(); |
241 | + |
242 | + for( auto item : aOther.Zones() ) |
243 | + { |
244 | + Add( static_cast<ZONE_CONTAINER*>( item->Clone() ) ); |
245 | + } |
246 | + |
247 | // Copy auxiliary data: Drawings |
248 | m_drawings.clear(); |
249 | |
250 | @@ -261,6 +278,13 @@ void MODULE::Add( BOARD_ITEM* aBoardItem, ADD_MODE aMode ) |
251 | m_pads.push_front( static_cast<D_PAD*>( aBoardItem ) ); |
252 | break; |
253 | |
254 | + case PCB_ZONE_AREA_T: |
255 | + if( aMode == ADD_APPEND ) |
256 | + m_zones.push_back( static_cast<ZONE_CONTAINER*>( aBoardItem ) ); |
257 | + else |
258 | + m_zones.insert( m_zones.begin(), static_cast<ZONE_CONTAINER*>( aBoardItem ) ); |
259 | + break; |
260 | + |
261 | default: |
262 | { |
263 | wxString msg; |
264 | @@ -313,6 +337,18 @@ void MODULE::Remove( BOARD_ITEM* aBoardItem ) |
265 | |
266 | break; |
267 | |
268 | + case PCB_ZONE_AREA_T: |
269 | + for( auto it = m_zones.begin(); it != m_zones.end(); ++it ) |
270 | + { |
271 | + if( *it == static_cast<ZONE_CONTAINER*>( aBoardItem ) ) |
272 | + { |
273 | + m_zones.erase( it ); |
274 | + break; |
275 | + } |
276 | + } |
277 | + |
278 | + break; |
279 | + |
280 | default: |
281 | { |
282 | wxString msg; |
283 | @@ -329,6 +365,9 @@ void MODULE::Print( PCB_BASE_FRAME* aFrame, wxDC* aDC, const wxPoint& aOffset ) |
284 | for( auto pad : m_pads ) |
285 | pad->Print( aFrame, aDC, aOffset ); |
286 | |
287 | + for( auto zone : m_zones ) |
288 | + zone->Print( aFrame, aDC, aOffset ); |
289 | + |
290 | BOARD* brd = GetBoard(); |
291 | |
292 | // Draw graphic items |
293 | @@ -385,6 +424,9 @@ EDA_RECT MODULE::GetFootprintRect() const |
294 | for( auto pad : m_pads ) |
295 | area.Merge( pad->GetBoundingBox() ); |
296 | |
297 | + for( auto zone : m_zones ) |
298 | + area.Merge( zone->GetBoundingBox() ); |
299 | + |
300 | return area; |
301 | } |
302 | |
303 | @@ -590,6 +632,12 @@ bool MODULE::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) co |
304 | return true; |
305 | } |
306 | |
307 | + for( auto zone : m_zones ) |
308 | + { |
309 | + if( zone->HitTest( arect, false, 0 ) ) |
310 | + return true; |
311 | + } |
312 | + |
313 | for( auto item : m_drawings ) |
314 | { |
315 | if( item->HitTest( arect, false, 0 ) ) |
316 | @@ -742,6 +790,11 @@ SEARCH_RESULT MODULE::Visit( INSPECTOR inspector, void* testData, const KICAD_T |
317 | ++p; |
318 | break; |
319 | |
320 | + case PCB_ZONE_AREA_T: |
321 | + result = IterateForward<ZONE_CONTAINER*>( m_zones, inspector, testData, p ); |
322 | + ++p; |
323 | + break; |
324 | + |
325 | case PCB_MODULE_TEXT_T: |
326 | result = inspector( m_Reference, testData ); |
327 | |
328 | @@ -819,6 +872,9 @@ void MODULE::RunOnChildren( const std::function<void (BOARD_ITEM*)>& aFunction ) |
329 | for( auto pad : m_pads ) |
330 | aFunction( static_cast<BOARD_ITEM*>( pad ) ); |
331 | |
332 | + for( auto zone : m_zones ) |
333 | + aFunction( static_cast<ZONE_CONTAINER*>( zone ) ); |
334 | + |
335 | for( auto drawing : m_drawings ) |
336 | aFunction( static_cast<BOARD_ITEM*>( drawing ) ); |
337 | |
338 | @@ -1023,6 +1079,10 @@ void MODULE::Flip( const wxPoint& aCentre, bool aFlipLeftRight ) |
339 | for( auto pad : m_pads ) |
340 | pad->Flip( m_Pos, false ); |
341 | |
342 | + // Mirror zones to other side of board. |
343 | + for( auto zone : m_zones ) |
344 | + zone->Flip( m_Pos, aFlipLeftRight ); |
345 | + |
346 | // Mirror reference and value. |
347 | m_Reference->Flip( m_Pos, false ); |
348 | m_Value->Flip( m_Pos, false ); |
349 | @@ -1068,6 +1128,9 @@ void MODULE::SetPosition( const wxPoint& newpos ) |
350 | pad->SetPosition( pad->GetPosition() + delta ); |
351 | } |
352 | |
353 | + for( auto zone : m_zones ) |
354 | + zone->Move( delta ); |
355 | + |
356 | for( auto item : m_drawings ) |
357 | { |
358 | switch( item->Type() ) |
359 | @@ -1167,6 +1230,11 @@ void MODULE::SetOrientation( double newangle ) |
360 | pad->SetDrawCoord(); |
361 | } |
362 | |
363 | + for( auto zone : m_zones ) |
364 | + { |
365 | + zone->Rotate( GetPosition(), angleChange ); |
366 | + } |
367 | + |
368 | // Update of the reference and value. |
369 | m_Reference->SetDrawCoord(); |
370 | m_Value->SetDrawCoord(); |
371 | @@ -1193,6 +1261,7 @@ BOARD_ITEM* MODULE::Duplicate( const BOARD_ITEM* aItem, |
372 | { |
373 | BOARD_ITEM* new_item = NULL; |
374 | D_PAD* new_pad = NULL; |
375 | + ZONE_CONTAINER* new_zone = NULL; |
376 | |
377 | switch( aItem->Type() ) |
378 | { |
379 | @@ -1207,6 +1276,17 @@ BOARD_ITEM* MODULE::Duplicate( const BOARD_ITEM* aItem, |
380 | break; |
381 | } |
382 | |
383 | + case PCB_ZONE_AREA_T: |
384 | + { |
385 | + new_zone = new ZONE_CONTAINER( *static_cast<const ZONE_CONTAINER*>( aItem ) ); |
386 | + |
387 | + if( aAddToModule ) |
388 | + m_zones.push_back( new_zone ); |
389 | + |
390 | + new_item = new_zone; |
391 | + break; |
392 | + } |
393 | + |
394 | case PCB_MODULE_TEXT_T: |
395 | { |
396 | const TEXTE_MODULE* old_text = static_cast<const TEXTE_MODULE*>( aItem ); |
397 | diff --git a/pcbnew/class_module.h b/pcbnew/class_module.h |
398 | index 2b3eee9..3e09bd6 100644 |
399 | --- a/pcbnew/class_module.h |
400 | +++ b/pcbnew/class_module.h |
401 | @@ -41,8 +41,9 @@ |
402 | #include <lib_id.h> |
403 | #include <list> |
404 | |
405 | -#include <class_text_mod.h> |
406 | #include "zones.h" |
407 | +#include <class_text_mod.h> |
408 | +#include <class_zone.h> |
409 | |
410 | #include <core/iterators.h> |
411 | |
412 | @@ -105,6 +106,7 @@ class MODULE_3D_SETTINGS |
413 | |
414 | DECL_DEQ_FOR_SWIG( PADS, D_PAD* ) |
415 | DECL_DEQ_FOR_SWIG( DRAWINGS, BOARD_ITEM* ) |
416 | +DECL_VEC_FOR_SWIG( ZONE_CONTAINERS, ZONE_CONTAINER* ) |
417 | DECL_DEQ_FOR_SWIG( MODULES, MODULE* ) |
418 | |
419 | class MODULE : public BOARD_ITEM_CONTAINER |
420 | @@ -177,6 +179,11 @@ public: |
421 | return m_drawings; |
422 | } |
423 | |
424 | + const ZONE_CONTAINERS& Zones() const |
425 | + { |
426 | + return m_zones; |
427 | + } |
428 | + |
429 | const DRAWINGS& GraphicalItems() const |
430 | { |
431 | return m_drawings; |
432 | @@ -662,8 +669,9 @@ public: |
433 | #endif |
434 | |
435 | private: |
436 | - DRAWINGS m_drawings; // BOARD_ITEMs for drawings on the board, owned by pointer. |
437 | - PADS m_pads; // D_PAD items, owned by pointer |
438 | + DRAWINGS m_drawings; // BOARD_ITEMs for drawings on the board, owned by pointer. |
439 | + PADS m_pads; // D_PAD items, owned by pointer |
440 | + ZONE_CONTAINERS m_zones; // ZONE items, owned by pointer |
441 | std::list<MODULE_3D_SETTINGS> m_3D_Drawings; // Linked list of 3D models. |
442 | |
443 | double m_Orient; // Orientation in tenths of a degree, 900=90.0 degrees. |
444 | diff --git a/pcbnew/class_zone.cpp b/pcbnew/class_zone.cpp |
445 | index ee91511..970f35e 100644 |
446 | --- a/pcbnew/class_zone.cpp |
447 | +++ b/pcbnew/class_zone.cpp |
448 | @@ -42,8 +42,8 @@ |
449 | #include <polygon_test_point_inside.h> |
450 | |
451 | |
452 | -ZONE_CONTAINER::ZONE_CONTAINER( BOARD* aBoard ) : |
453 | - BOARD_CONNECTED_ITEM( aBoard, PCB_ZONE_AREA_T ) |
454 | +ZONE_CONTAINER::ZONE_CONTAINER( BOARD_ITEM_CONTAINER* aParent ) |
455 | + : BOARD_CONNECTED_ITEM( aParent, PCB_ZONE_AREA_T ) |
456 | { |
457 | m_CornerSelection = nullptr; // no corner is selected |
458 | m_IsFilled = false; // fill status : true when the zone is filled |
459 | @@ -67,14 +67,14 @@ ZONE_CONTAINER::ZONE_CONTAINER( BOARD* aBoard ) : |
460 | SetLocalFlags( 0 ); // flags tempoarry used in zone calculations |
461 | m_Poly = new SHAPE_POLY_SET(); // Outlines |
462 | m_FilledPolysUseThickness = true; // set the "old" way to build filled polygon areas (before 6.0.x) |
463 | - aBoard->GetZoneSettings().ExportSetting( *this ); |
464 | + aParent->GetZoneSettings().ExportSetting( *this ); |
465 | |
466 | m_needRefill = false; // True only after some edition. |
467 | } |
468 | |
469 | |
470 | -ZONE_CONTAINER::ZONE_CONTAINER( const ZONE_CONTAINER& aZone ) : |
471 | - BOARD_CONNECTED_ITEM( aZone ) |
472 | +ZONE_CONTAINER::ZONE_CONTAINER( const ZONE_CONTAINER& aZone ) |
473 | + : BOARD_CONNECTED_ITEM( aZone.GetParent(), PCB_ZONE_AREA_T ) |
474 | { |
475 | // Should the copy be on the same net? |
476 | SetNetCode( aZone.GetNetCode() ); |
477 | diff --git a/pcbnew/class_zone.h b/pcbnew/class_zone.h |
478 | index 22f7b00..9a5fa86 100644 |
479 | --- a/pcbnew/class_zone.h |
480 | +++ b/pcbnew/class_zone.h |
481 | @@ -63,7 +63,7 @@ public: |
482 | */ |
483 | typedef enum HATCH_STYLE { NO_HATCH, DIAGONAL_FULL, DIAGONAL_EDGE } HATCH_STYLE; |
484 | |
485 | - ZONE_CONTAINER( BOARD* parent ); |
486 | + ZONE_CONTAINER( BOARD_ITEM_CONTAINER* parent ); |
487 | |
488 | ZONE_CONTAINER( const ZONE_CONTAINER& aZone ); |
489 | ZONE_CONTAINER& operator=( const ZONE_CONTAINER &aOther ); |
490 | diff --git a/pcbnew/collectors.cpp b/pcbnew/collectors.cpp |
491 | index 4760bbb..91be17c 100644 |
492 | --- a/pcbnew/collectors.cpp |
493 | +++ b/pcbnew/collectors.cpp |
494 | @@ -107,21 +107,12 @@ const KICAD_T GENERAL_COLLECTOR::PadsOrTracks[] = { |
495 | }; |
496 | |
497 | |
498 | -const KICAD_T GENERAL_COLLECTOR::ModulesAndTheirItems[] = { |
499 | - PCB_MODULE_TEXT_T, |
500 | - PCB_MODULE_EDGE_T, |
501 | - PCB_PAD_T, |
502 | - PCB_MODULE_T, |
503 | - EOT |
504 | -}; |
505 | +const KICAD_T GENERAL_COLLECTOR::ModulesAndTheirItems[] = { PCB_MODULE_TEXT_T, PCB_MODULE_EDGE_T, |
506 | + PCB_PAD_T, PCB_MODULE_T, PCB_ZONE_AREA_T, EOT }; |
507 | |
508 | |
509 | -const KICAD_T GENERAL_COLLECTOR::ModuleItems[] = { |
510 | - PCB_MODULE_TEXT_T, |
511 | - PCB_MODULE_EDGE_T, |
512 | - PCB_PAD_T, |
513 | - EOT |
514 | -}; |
515 | +const KICAD_T GENERAL_COLLECTOR::ModuleItems[] = { PCB_MODULE_TEXT_T, PCB_MODULE_EDGE_T, PCB_PAD_T, |
516 | + PCB_ZONE_AREA_T, EOT }; |
517 | |
518 | |
519 | const KICAD_T GENERAL_COLLECTOR::Tracks[] = { |
520 | diff --git a/pcbnew/footprint_editor_utils.cpp b/pcbnew/footprint_editor_utils.cpp |
521 | index 35f1909..c85748d 100644 |
522 | --- a/pcbnew/footprint_editor_utils.cpp |
523 | +++ b/pcbnew/footprint_editor_utils.cpp |
524 | @@ -385,6 +385,38 @@ void FOOTPRINT_EDIT_FRAME::OnEditItemRequest( BOARD_ITEM* aItem ) |
525 | InstallGraphicItemPropertiesDialog( aItem ); |
526 | break; |
527 | |
528 | + case PCB_ZONE_AREA_T: |
529 | + { |
530 | + ZONE_CONTAINER* zone = static_cast<ZONE_CONTAINER*>( aItem ); |
531 | + bool success = false; |
532 | + if( zone ) |
533 | + { |
534 | + ZONE_SETTINGS zoneSettings; |
535 | + zoneSettings << *zone; |
536 | + if( zone->GetIsKeepout() ) |
537 | + { |
538 | + success = InvokeKeepoutAreaEditor( this, &zoneSettings ); |
539 | + } |
540 | + else if( zone->IsOnCopperLayer() ) |
541 | + { |
542 | + success = InvokeCopperZonesEditor( this, &zoneSettings ); |
543 | + } |
544 | + else |
545 | + { |
546 | + success = InvokeNonCopperZonesEditor( this, &zoneSettings ); |
547 | + } |
548 | + |
549 | + if( success ) |
550 | + { |
551 | + BOARD_COMMIT commit( this ); |
552 | + commit.Modify( zone ); |
553 | + commit.Push( _( "Edit Zone" ) ); |
554 | + zoneSettings.ExportSetting( *zone ); |
555 | + } |
556 | + } |
557 | + } |
558 | + break; |
559 | + |
560 | default: |
561 | break; |
562 | } |
563 | diff --git a/pcbnew/kicad_plugin.cpp b/pcbnew/kicad_plugin.cpp |
564 | index 22a6ef3..b80c195 100644 |
565 | --- a/pcbnew/kicad_plugin.cpp |
566 | +++ b/pcbnew/kicad_plugin.cpp |
567 | @@ -1140,6 +1140,10 @@ void PCB_IO::format( MODULE* aModule, int aNestLevel ) const |
568 | for( auto pad : aModule->Pads() ) |
569 | format( pad, aNestLevel+1 ); |
570 | |
571 | + // Save zones. |
572 | + for( auto zone : aModule->Zones() ) |
573 | + format( zone, aNestLevel + 1 ); |
574 | + |
575 | // Save 3D info. |
576 | auto bs3D = aModule->Models().begin(); |
577 | auto es3D = aModule->Models().end(); |
578 | diff --git a/pcbnew/kicad_plugin.h b/pcbnew/kicad_plugin.h |
579 | index a9d6eeb..81fc723 100644 |
580 | --- a/pcbnew/kicad_plugin.h |
581 | +++ b/pcbnew/kicad_plugin.h |
582 | @@ -62,7 +62,8 @@ class TEXTE_PCB; |
583 | //#define SEXPR_BOARD_FILE_VERSION 20190421 // curves in custom pads |
584 | //#define SEXPR_BOARD_FILE_VERSION 20190516 // Remove segment count from zones |
585 | //#define SEXPR_BOARD_FILE_VERSION 20190605 // Add layer defaults |
586 | -#define SEXPR_BOARD_FILE_VERSION 20190905 // Add board physical stackup info in setup section |
587 | +//#define SEXPR_BOARD_FILE_VERSION 20190905 // Add board physical stackup info in setup section |
588 | +#define SEXPR_BOARD_FILE_VERSION 20190907 // Keepout areas in footprints |
589 | |
590 | #define CTL_STD_LAYER_NAMES (1 << 0) ///< Use English Standard layer names |
591 | #define CTL_OMIT_NETS (1 << 1) ///< Omit pads net names (useless in library) |
592 | diff --git a/pcbnew/menubar_footprint_editor.cpp b/pcbnew/menubar_footprint_editor.cpp |
593 | index c9ee37f..60a9d83 100644 |
594 | --- a/pcbnew/menubar_footprint_editor.cpp |
595 | +++ b/pcbnew/menubar_footprint_editor.cpp |
596 | @@ -228,15 +228,16 @@ void FOOTPRINT_EDIT_FRAME::ReCreateMenuBar() |
597 | placeMenu->AddItem( PCB_ACTIONS::placePad, haveFootprintCondition ); |
598 | |
599 | placeMenu->AddSeparator(); |
600 | - placeMenu->AddItem( PCB_ACTIONS::placeText, haveFootprintCondition ); |
601 | - placeMenu->AddItem( PCB_ACTIONS::drawArc, haveFootprintCondition ); |
602 | - placeMenu->AddItem( PCB_ACTIONS::drawCircle, haveFootprintCondition ); |
603 | - placeMenu->AddItem( PCB_ACTIONS::drawLine, haveFootprintCondition ); |
604 | + placeMenu->AddItem( PCB_ACTIONS::placeText, haveFootprintCondition ); |
605 | + placeMenu->AddItem( PCB_ACTIONS::drawArc, haveFootprintCondition ); |
606 | + placeMenu->AddItem( PCB_ACTIONS::drawCircle, haveFootprintCondition ); |
607 | + placeMenu->AddItem( PCB_ACTIONS::drawLine, haveFootprintCondition ); |
608 | placeMenu->AddItem( PCB_ACTIONS::drawPolygon, haveFootprintCondition ); |
609 | + placeMenu->AddItem( PCB_ACTIONS::drawZoneKeepout, haveFootprintCondition ); |
610 | |
611 | placeMenu->AddSeparator(); |
612 | - placeMenu->AddItem( PCB_ACTIONS::setAnchor, haveFootprintCondition ); |
613 | - placeMenu->AddItem( ACTIONS::gridSetOrigin, haveFootprintCondition ); |
614 | + placeMenu->AddItem( PCB_ACTIONS::setAnchor, haveFootprintCondition ); |
615 | + placeMenu->AddItem( ACTIONS::gridSetOrigin, haveFootprintCondition ); |
616 | |
617 | placeMenu->Resolve(); |
618 | |
619 | diff --git a/pcbnew/pcb_parser.cpp b/pcbnew/pcb_parser.cpp |
620 | index fba802e..a314519 100644 |
621 | --- a/pcbnew/pcb_parser.cpp |
622 | +++ b/pcbnew/pcb_parser.cpp |
623 | @@ -74,6 +74,7 @@ void PCB_PARSER::init() |
624 | } |
625 | |
626 | m_layerMasks[ "*.Cu" ] = LSET::AllCuMask(); |
627 | + m_layerMasks["*In.Cu"] = LSET::InternalCuMask(); |
628 | m_layerMasks[ "F&B.Cu" ] = LSET( 2, F_Cu, B_Cu ); |
629 | m_layerMasks[ "*.Adhes" ] = LSET( 2, B_Adhes, F_Adhes ); |
630 | m_layerMasks[ "*.Paste" ] = LSET( 2, B_Paste, F_Paste ); |
631 | @@ -590,7 +591,7 @@ BOARD* PCB_PARSER::parseBOARD_unchecked() |
632 | break; |
633 | |
634 | case T_zone: |
635 | - m_board->Add( parseZONE_CONTAINER(), ADD_APPEND ); |
636 | + m_board->Add( parseZONE_CONTAINER( m_board ), ADD_APPEND ); |
637 | break; |
638 | |
639 | case T_target: |
640 | @@ -2511,12 +2512,21 @@ MODULE* PCB_PARSER::parseMODULE_unchecked( wxArrayString* aInitialComments ) |
641 | module->Add3DModel( parse3DModel() ); |
642 | break; |
643 | |
644 | + case T_zone: |
645 | + { |
646 | + ZONE_CONTAINER* zone = parseZONE_CONTAINER( module.get() ); |
647 | + module->Add( zone, ADD_APPEND ); |
648 | + } |
649 | + break; |
650 | + |
651 | default: |
652 | - Expecting( "locked, placed, tedit, tstamp, at, descr, tags, path, " |
653 | - "autoplace_cost90, autoplace_cost180, solder_mask_margin, " |
654 | - "solder_paste_margin, solder_paste_ratio, clearance, " |
655 | - "zone_connect, thermal_width, thermal_gap, attr, fp_text, " |
656 | - "fp_arc, fp_circle, fp_curve, fp_line, fp_poly, pad, or model" ); |
657 | + Expecting( |
658 | + "locked, placed, tedit, tstamp, at, descr, tags, path, " |
659 | + "autoplace_cost90, autoplace_cost180, solder_mask_margin, " |
660 | + "solder_paste_margin, solder_paste_ratio, clearance, " |
661 | + "zone_connect, thermal_width, thermal_gap, attr, fp_text, " |
662 | + "fp_arc, fp_circle, fp_curve, fp_line, fp_poly, pad, " |
663 | + "zone, or model" ); |
664 | } |
665 | } |
666 | |
667 | @@ -3390,7 +3400,7 @@ VIA* PCB_PARSER::parseVIA() |
668 | } |
669 | |
670 | |
671 | -ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER() |
672 | +ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER( BOARD_ITEM_CONTAINER* aParent ) |
673 | { |
674 | wxCHECK_MSG( CurTok() == T_zone, NULL, |
675 | wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + |
676 | @@ -3407,7 +3417,7 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER() |
677 | // bigger scope since each filled_polygon is concatenated in here |
678 | SHAPE_POLY_SET pts; |
679 | |
680 | - std::unique_ptr< ZONE_CONTAINER > zone( new ZONE_CONTAINER( m_board ) ); |
681 | + std::unique_ptr<ZONE_CONTAINER> zone( new ZONE_CONTAINER( aParent ) ); |
682 | |
683 | zone->SetPriority( 0 ); |
684 | |
685 | diff --git a/pcbnew/pcb_parser.h b/pcbnew/pcb_parser.h |
686 | index 0cbfd3c..92b7a99 100644 |
687 | --- a/pcbnew/pcb_parser.h |
688 | +++ b/pcbnew/pcb_parser.h |
689 | @@ -41,6 +41,7 @@ |
690 | |
691 | class BOARD; |
692 | class BOARD_ITEM; |
693 | +class BOARD_ITEM_CONTAINER; |
694 | class D_PAD; |
695 | class BOARD_DESIGN_SETTINGS; |
696 | class DIMENSION; |
697 | @@ -156,7 +157,7 @@ class PCB_PARSER : public PCB_LEXER |
698 | bool parseD_PAD_option( D_PAD* aPad ); |
699 | TRACK* parseTRACK(); |
700 | VIA* parseVIA(); |
701 | - ZONE_CONTAINER* parseZONE_CONTAINER(); |
702 | + ZONE_CONTAINER* parseZONE_CONTAINER( BOARD_ITEM_CONTAINER* aParent ); |
703 | PCB_TARGET* parsePCB_TARGET(); |
704 | BOARD* parseBOARD(); |
705 | |
706 | diff --git a/pcbnew/toolbars_footprint_editor.cpp b/pcbnew/toolbars_footprint_editor.cpp |
707 | index 370350c..374dd9a 100644 |
708 | --- a/pcbnew/toolbars_footprint_editor.cpp |
709 | +++ b/pcbnew/toolbars_footprint_editor.cpp |
710 | @@ -53,7 +53,7 @@ void FOOTPRINT_EDIT_FRAME::ReCreateHToolbar() |
711 | #ifdef KICAD_SCRIPTING |
712 | m_mainToolBar->Add( PCB_ACTIONS::createFootprint ); |
713 | #endif |
714 | - |
715 | + |
716 | if( IsCurrentFPFromBoard() ) |
717 | m_mainToolBar->Add( PCB_ACTIONS::saveToBoard ); |
718 | else |
719 | @@ -129,18 +129,19 @@ void FOOTPRINT_EDIT_FRAME::ReCreateVToolbar() |
720 | m_drawToolBar->Add( ACTIONS::selectionTool, ACTION_TOOLBAR::TOGGLE ); |
721 | |
722 | KiScaledSeparator( m_drawToolBar, this ); |
723 | - m_drawToolBar->Add( PCB_ACTIONS::placePad, ACTION_TOOLBAR::TOGGLE ); |
724 | - m_drawToolBar->Add( PCB_ACTIONS::drawLine, ACTION_TOOLBAR::TOGGLE ); |
725 | - m_drawToolBar->Add( PCB_ACTIONS::drawCircle, ACTION_TOOLBAR::TOGGLE ); |
726 | - m_drawToolBar->Add( PCB_ACTIONS::drawArc, ACTION_TOOLBAR::TOGGLE ); |
727 | - m_drawToolBar->Add( PCB_ACTIONS::drawPolygon, ACTION_TOOLBAR::TOGGLE ); |
728 | - m_drawToolBar->Add( PCB_ACTIONS::placeText, ACTION_TOOLBAR::TOGGLE ); |
729 | - m_drawToolBar->Add( ACTIONS::deleteTool, ACTION_TOOLBAR::TOGGLE ); |
730 | + m_drawToolBar->Add( PCB_ACTIONS::placePad, ACTION_TOOLBAR::TOGGLE ); |
731 | + m_drawToolBar->Add( PCB_ACTIONS::drawLine, ACTION_TOOLBAR::TOGGLE ); |
732 | + m_drawToolBar->Add( PCB_ACTIONS::drawCircle, ACTION_TOOLBAR::TOGGLE ); |
733 | + m_drawToolBar->Add( PCB_ACTIONS::drawArc, ACTION_TOOLBAR::TOGGLE ); |
734 | + m_drawToolBar->Add( PCB_ACTIONS::drawPolygon, ACTION_TOOLBAR::TOGGLE ); |
735 | + m_drawToolBar->Add( PCB_ACTIONS::drawZoneKeepout, ACTION_TOOLBAR::TOGGLE ); |
736 | + m_drawToolBar->Add( PCB_ACTIONS::placeText, ACTION_TOOLBAR::TOGGLE ); |
737 | + m_drawToolBar->Add( ACTIONS::deleteTool, ACTION_TOOLBAR::TOGGLE ); |
738 | |
739 | KiScaledSeparator( m_drawToolBar, this ); |
740 | - m_drawToolBar->Add( PCB_ACTIONS::setAnchor, ACTION_TOOLBAR::TOGGLE ); |
741 | - m_drawToolBar->Add( PCB_ACTIONS::gridSetOrigin, ACTION_TOOLBAR::TOGGLE ); |
742 | - m_drawToolBar->Add( ACTIONS::measureTool, ACTION_TOOLBAR::TOGGLE ); |
743 | + m_drawToolBar->Add( PCB_ACTIONS::setAnchor, ACTION_TOOLBAR::TOGGLE ); |
744 | + m_drawToolBar->Add( PCB_ACTIONS::gridSetOrigin, ACTION_TOOLBAR::TOGGLE ); |
745 | + m_drawToolBar->Add( ACTIONS::measureTool, ACTION_TOOLBAR::TOGGLE ); |
746 | |
747 | m_drawToolBar->Realize(); |
748 | } |
749 | @@ -205,6 +206,7 @@ void FOOTPRINT_EDIT_FRAME::SyncToolbars() |
750 | TOGGLE_TOOL( m_drawToolBar, PCB_ACTIONS::drawCircle ); |
751 | TOGGLE_TOOL( m_drawToolBar, PCB_ACTIONS::drawArc ); |
752 | TOGGLE_TOOL( m_drawToolBar, PCB_ACTIONS::drawPolygon ); |
753 | + TOGGLE_TOOL( m_drawToolBar, PCB_ACTIONS::drawZoneKeepout ); |
754 | TOGGLE_TOOL( m_drawToolBar, PCB_ACTIONS::placeText ); |
755 | TOGGLE_TOOL( m_drawToolBar, ACTIONS::deleteTool ); |
756 | TOGGLE_TOOL( m_drawToolBar, PCB_ACTIONS::setAnchor ); |
757 | diff --git a/pcbnew/tools/drc.cpp b/pcbnew/tools/drc.cpp |
758 | index c651699..d569588 100644 |
759 | --- a/pcbnew/tools/drc.cpp |
760 | +++ b/pcbnew/tools/drc.cpp |
761 | @@ -882,10 +882,12 @@ void DRC::testZones() |
762 | |
763 | void DRC::testKeepoutAreas() |
764 | { |
765 | + // Get a list of all zones to inspect, from both board and footprints |
766 | + std::list<ZONE_CONTAINER*> areasToInspect = m_pcb->GetZoneList( true ); |
767 | + |
768 | // Test keepout areas for vias, tracks and pads inside keepout areas |
769 | - for( int ii = 0; ii < m_pcb->GetAreaCount(); ii++ ) |
770 | + for( ZONE_CONTAINER* area : areasToInspect ) |
771 | { |
772 | - ZONE_CONTAINER* area = m_pcb->GetArea( ii ); |
773 | |
774 | if( !area->GetIsKeepout() ) |
775 | continue; |
776 | diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp |
777 | index 58482c9..fbd2078 100644 |
778 | --- a/pcbnew/tools/selection_tool.cpp |
779 | +++ b/pcbnew/tools/selection_tool.cpp |
780 | @@ -1461,6 +1461,14 @@ bool SELECTION_TOOL::Selectable( const BOARD_ITEM* aItem, bool checkVisibilityOn |
781 | switch( aItem->Type() ) |
782 | { |
783 | case PCB_ZONE_AREA_T: |
784 | + { |
785 | + // Check to see if this keepout is part of a footprint |
786 | + // If it is, and we are not editing the footprint, it should not be selectable |
787 | + const bool zoneInFootprint = |
788 | + aItem->GetParent() != nullptr && aItem->GetParent()->Type() == PCB_MODULE_T; |
789 | + if( zoneInFootprint && !m_editModules && !checkVisibilityOnly ) |
790 | + return false; |
791 | + |
792 | // Keepout zones can exist on multiple layers! |
793 | { |
794 | auto* zone = static_cast<const ZONE_CONTAINER*>( aItem ); |
795 | @@ -1481,6 +1489,7 @@ bool SELECTION_TOOL::Selectable( const BOARD_ITEM* aItem, bool checkVisibilityOn |
796 | return false; |
797 | } |
798 | } |
799 | + } |
800 | break; |
801 | |
802 | case PCB_TRACE_T: |
803 | @@ -1543,6 +1552,12 @@ bool SELECTION_TOOL::Selectable( const BOARD_ITEM* aItem, bool checkVisibilityOn |
804 | return true; |
805 | } |
806 | |
807 | + for( auto zone : module->Zones() ) |
808 | + { |
809 | + if( Selectable( zone, true ) ) |
810 | + return true; |
811 | + } |
812 | + |
813 | return false; |
814 | } |
815 | |
816 | diff --git a/pcbnew/tools/zone_create_helper.cpp b/pcbnew/tools/zone_create_helper.cpp |
817 | index 321858f..f210874 100644 |
818 | --- a/pcbnew/tools/zone_create_helper.cpp |
819 | +++ b/pcbnew/tools/zone_create_helper.cpp |
820 | @@ -51,8 +51,9 @@ ZONE_CREATE_HELPER::~ZONE_CREATE_HELPER() |
821 | |
822 | std::unique_ptr<ZONE_CONTAINER> ZONE_CREATE_HELPER::createNewZone( bool aKeepout ) |
823 | { |
824 | - auto& frame = *m_tool.getEditFrame<PCB_BASE_FRAME>(); |
825 | + auto& frame = *m_tool.getEditFrame<PCB_BASE_EDIT_FRAME>(); |
826 | auto& board = *m_tool.getModel<BOARD>(); |
827 | + BOARD_ITEM_CONTAINER* parent = m_tool.m_frame->GetModel(); |
828 | KIGFX::VIEW_CONTROLS* controls = m_tool.GetManager()->GetViewControls(); |
829 | |
830 | // Get the current default settings for zones |
831 | @@ -84,7 +85,7 @@ std::unique_ptr<ZONE_CONTAINER> ZONE_CREATE_HELPER::createNewZone( bool aKeepout |
832 | controls->WarpCursor( controls->GetCursorPosition(), true ); |
833 | } |
834 | |
835 | - auto newZone = std::make_unique<ZONE_CONTAINER>( &board ); |
836 | + auto newZone = std::make_unique<ZONE_CONTAINER>( parent ); |
837 | |
838 | // Apply the selected settings |
839 | zoneInfo.ExportSetting( *newZone ); |
840 | diff --git a/pcbnew/zone_filler.cpp b/pcbnew/zone_filler.cpp |
841 | index 750cf6e..fded744 100644 |
842 | --- a/pcbnew/zone_filler.cpp |
843 | +++ b/pcbnew/zone_filler.cpp |
844 | @@ -620,9 +620,8 @@ void ZONE_FILLER::buildCopperItemClearances( const ZONE_CONTAINER* aZone, SHAPE_ |
845 | |
846 | // Add zones outlines having an higher priority and keepout |
847 | // |
848 | - for( int ii = 0; ii < m_board->GetAreaCount(); ii++ ) |
849 | + for( ZONE_CONTAINER* zone : m_board->GetZoneList( true ) ) |
850 | { |
851 | - ZONE_CONTAINER* zone = m_board->GetArea( ii ); |
852 | |
853 | // If the zones share no common layers |
854 | if( !aZone->CommonLayerExists( zone->GetLayerSet() ) ) |
We are in feature freeze for 5.1 so no new changes are permitted until v6 opens for development. Once 5.1 is released, we can review and consider merging this merge request.