KiCad PCB EDA Suite
Loading...
Searching...
No Matches
zone_filler.h
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) 2014-2017 CERN
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 * @author Tomasz Włostowski <[email protected]>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
22#ifndef ZONE_FILLER_H
23#define ZONE_FILLER_H
24
25#include <map>
26#include <mutex>
27#include <vector>
28#include <zone.h>
31#include <hash_128.h>
32
34class BOARD;
35class COMMIT;
36class FOOTPRINT;
38
39
41{
42public:
43 ZONE_FILLER( BOARD* aBoard, COMMIT* aCommit );
45
46 void SetProgressReporter( PROGRESS_REPORTER* aReporter );
48
59 bool Fill( const std::vector<ZONE*>& aZones, bool aCheck = false, wxWindow* aParent = nullptr );
60
61 bool IsDebug() const { return m_debugZoneFiller; }
62
63private:
64
65 void addKnockout( BOARD_ITEM* aItem, PCB_LAYER_ID aLayer, int aGap, SHAPE_POLY_SET& aHoles );
66
67 void addKnockout( BOARD_ITEM* aItem, PCB_LAYER_ID aLayer, int aGap, bool aIgnoreLineWidth,
68 SHAPE_POLY_SET& aHoles );
69
70 void addHoleKnockout( PAD* aPad, int aGap, SHAPE_POLY_SET& aHoles );
71
72 void knockoutThermalReliefs( const ZONE* aZone, PCB_LAYER_ID aLayer, SHAPE_POLY_SET& aFill,
73 std::vector<BOARD_ITEM*>& aThermalConnectionPads, std::vector<PAD*>& aNoConnectionPads,
74 std::vector<BOARD_ITEM*>& aSolidConnectionItems );
75
76 void buildCopperItemClearances( const ZONE* aZone, PCB_LAYER_ID aLayer,
77 const std::vector<PAD*>& aNoConnectionPads,
78 SHAPE_POLY_SET& aHoles,
79 bool aIncludeZoneClearances = true );
80
85 void buildDifferentNetZoneClearances( const ZONE* aZone, PCB_LAYER_ID aLayer,
86 SHAPE_POLY_SET& aHoles );
87
93 bool zoneKnockoutMayInteract( const ZONE* aZone, const ZONE* aKnockout ) const;
94
98 BOX2I zoneKnockoutQueryBox( const ZONE* aZone ) const;
99
103 bool mayHoldOutOfBoardCopper( const ZONE* aZone ) const;
104
105 void subtractHigherPriorityZones( const ZONE* aZone, PCB_LAYER_ID aLayer,
106 SHAPE_POLY_SET& aRawFill );
107
119 bool fillCopperZone( const ZONE* aZone, PCB_LAYER_ID aLayer, PCB_LAYER_ID aDebugLayer,
120 const SHAPE_POLY_SET& aSmoothedOutline,
121 const SHAPE_POLY_SET& aMaxExtents, SHAPE_POLY_SET& aFillPolys );
122
123 bool fillNonCopperZone( const ZONE* candidate, PCB_LAYER_ID aLayer,
124 const SHAPE_POLY_SET& aSmoothedOutline, SHAPE_POLY_SET& aFillPolys );
129 void buildThermalSpokes( const ZONE* box, PCB_LAYER_ID aLayer,
130 const std::vector<BOARD_ITEM*>& aSpokedPadsList,
131 std::deque<SHAPE_LINE_CHAIN>& aSpokes );
132
141 void buildHatchZoneThermalRings( const ZONE* aZone, PCB_LAYER_ID aLayer,
142 const SHAPE_POLY_SET& aSmoothedOutline,
143 const std::vector<BOARD_ITEM*>& aThermalConnectionPads,
144 SHAPE_POLY_SET& aFillPolys,
145 SHAPE_POLY_SET& aThermalRings );
146
152 void connect_nearby_polys( SHAPE_POLY_SET& aPolys, double aDistance );
153
166 bool fillSingleZone( ZONE* aZone, PCB_LAYER_ID aLayer, SHAPE_POLY_SET& aFillPolys );
167
177 bool addHatchFillTypeOnZone( const ZONE* aZone, PCB_LAYER_ID aLayer, PCB_LAYER_ID aDebugLayer,
178 SHAPE_POLY_SET& aFillPolys,
179 const SHAPE_POLY_SET& aThermalRings );
180
196 bool addCopperThievingPattern( const ZONE* aZone, PCB_LAYER_ID aLayer,
197 SHAPE_POLY_SET& aFillPolys );
198
208 void postKnockoutMinWidthPrune( const ZONE* aZone, SHAPE_POLY_SET& aFillPolys,
209 const SHAPE_POLY_SET& aSameNetApron );
210
214 using FillSnapshot = std::map<std::pair<const ZONE*, PCB_LAYER_ID>, SHAPE_POLY_SET>;
215
225 bool refillZoneFromCache( ZONE* aZone, PCB_LAYER_ID aLayer, SHAPE_POLY_SET& aFillPolys,
226 const FillSnapshot* aSnapshot = nullptr );
227
233 {
235 FOOTPRINT* m_owner; // the footprint that owns a graphic item, else nullptr
236 int m_seq;
237 };
238
240
242 static void queryIndex( const ITEM_RTREE& aIndex, const BOX2I& aBBox,
243 std::vector<INDEXED_ITEM>& aResult );
244
246 void buildItemIndexes();
247
249 SHAPE_POLY_SET m_boardOutline; // the board outlines, if exists
250 bool m_brdOutlinesValid; // true if m_boardOutline is well-formed
253
254 // Rebuilt per fill, then read-only, so the fill workers can share them.
255 ITEM_RTREE m_graphicIndex; // fp reference/value/graphics + drawings
256 ITEM_RTREE m_footprintIndex; // footprints, for the courtyard knockout
258 std::map<PCB_LAYER_ID, ITEM_RTREE> m_trackIndex;
259 std::map<PCB_LAYER_ID, ITEM_RTREE> m_zoneIndex;
260
263
264 // ExtraClearance plus max approximation error, part of the knockout reach
266
267 // Largest corner radius on the board. Widens the knockout query window.
269
271
272 // Cache of pre-knockout fills for iterative refill optimization (issue 21746)
273 // Key: (zone pointer, layer), Value: fill polygon before higher-priority zone knockout
274 std::map<std::pair<const ZONE*, PCB_LAYER_ID>, SHAPE_POLY_SET> m_preKnockoutFillCache;
275
276 // Un-hatched extent per (zone, layer); lets the refiller re-border carved hatch zones (#24758).
277 std::map<std::pair<const ZONE*, PCB_LAYER_ID>, SHAPE_POLY_SET> m_preHatchSolidFillCache;
278
279 // Band just outside each (zone, layer) that an abutting same-net zone pours into. Buffers the
280 // refiller's min-width cycle the way the smoothed outline buffers the initial one (#23790).
281 std::map<std::pair<const ZONE*, PCB_LAYER_ID>, SHAPE_POLY_SET> m_sameNetApronCache;
282
283 // Refill result keyed by (zone, layer); value is the knockout-geometry hash + cached fill.
284 // Hit lets an unchanged-knockout zone skip the refill subtract + prune. Cleared each Fill().
285 std::map<std::pair<const ZONE*, PCB_LAYER_ID>, std::pair<HASH_128, SHAPE_POLY_SET>>
287 mutable std::mutex m_cacheMutex;
288};
289
290#endif
BOX2< VECTOR2I > BOX2I
Definition box2.h:927
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition board_item.h:84
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:409
Represent a set of changes (additions, deletions or modifications) of a data model (e....
Definition commit.h:68
Static (immutable) packed R-tree built via Hilbert-curve bulk loading.
Definition pad.h:61
A progress reporter interface for use in multi-threaded environments.
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
Represent a set of closed polygons.
ITEM_RTREE m_footprintIndex
COMMIT * m_commit
void buildItemIndexes()
Index the static board items once per fill.
std::map< std::pair< const ZONE *, PCB_LAYER_ID >, SHAPE_POLY_SET > m_sameNetApronCache
void buildCopperItemClearances(const ZONE *aZone, PCB_LAYER_ID aLayer, const std::vector< PAD * > &aNoConnectionPads, SHAPE_POLY_SET &aHoles, bool aIncludeZoneClearances=true)
Removes clearance from the shape for copper items which share the zone's layer but are not connected ...
int m_worstClearance
bool m_debugZoneFiller
BOX2I zoneKnockoutQueryBox(const ZONE *aZone) const
A window that holds every zone zoneKnockoutMayInteract() can accept for aZone.
void buildHatchZoneThermalRings(const ZONE *aZone, PCB_LAYER_ID aLayer, const SHAPE_POLY_SET &aSmoothedOutline, const std::vector< BOARD_ITEM * > &aThermalConnectionPads, SHAPE_POLY_SET &aFillPolys, SHAPE_POLY_SET &aThermalRings)
Build thermal rings for pads in hatch zones.
void connect_nearby_polys(SHAPE_POLY_SET &aPolys, double aDistance)
Create strands of zero-width between elements of SHAPE_POLY_SET that are within aDistance of each oth...
std::map< PCB_LAYER_ID, ITEM_RTREE > m_zoneIndex
void knockoutThermalReliefs(const ZONE *aZone, PCB_LAYER_ID aLayer, SHAPE_POLY_SET &aFill, std::vector< BOARD_ITEM * > &aThermalConnectionPads, std::vector< PAD * > &aNoConnectionPads, std::vector< BOARD_ITEM * > &aSolidConnectionItems)
Removes thermal reliefs from the shape for any pads connected to the zone.
void buildThermalSpokes(const ZONE *box, PCB_LAYER_ID aLayer, const std::vector< BOARD_ITEM * > &aSpokedPadsList, std::deque< SHAPE_LINE_CHAIN > &aSpokes)
Function buildThermalSpokes Constructs a list of all thermal spokes for the given zone.
void postKnockoutMinWidthPrune(const ZONE *aZone, SHAPE_POLY_SET &aFillPolys, const SHAPE_POLY_SET &aSameNetApron)
Remove minimum-width violations introduced by zone-to-zone knockouts.
std::map< PCB_LAYER_ID, ITEM_RTREE > m_trackIndex
void buildDifferentNetZoneClearances(const ZONE *aZone, PCB_LAYER_ID aLayer, SHAPE_POLY_SET &aHoles)
Build clearance knockout holes for higher-priority zones on different nets.
std::map< std::pair< const ZONE *, PCB_LAYER_ID >, SHAPE_POLY_SET > FillSnapshot
Snapshot of zone fill polygons captured before an iterative refill wave.
static void queryIndex(const ITEM_RTREE &aIndex, const BOX2I &aBBox, std::vector< INDEXED_ITEM > &aResult)
Collect the items whose bounding box overlaps aBBox, in board order.
ZONE_FILLER(BOARD *aBoard, COMMIT *aCommit)
void subtractHigherPriorityZones(const ZONE *aZone, PCB_LAYER_ID aLayer, SHAPE_POLY_SET &aRawFill)
Removes the outlines of higher-proirity zones with the same net.
void addKnockout(BOARD_ITEM *aItem, PCB_LAYER_ID aLayer, int aGap, SHAPE_POLY_SET &aHoles)
Add a knockout for a pad or via.
SHAPE_POLY_SET m_boardOutline
std::map< std::pair< const ZONE *, PCB_LAYER_ID >, SHAPE_POLY_SET > m_preKnockoutFillCache
bool m_brdOutlinesValid
void SetProgressReporter(PROGRESS_REPORTER *aReporter)
std::map< std::pair< const ZONE *, PCB_LAYER_ID >, SHAPE_POLY_SET > m_preHatchSolidFillCache
ITEM_RTREE m_padIndex
std::mutex m_cacheMutex
PROGRESS_REPORTER * GetProgressReporter() const
Definition zone_filler.h:47
BOARD * m_board
KIRTREE::PACKED_RTREE< INDEXED_ITEM, int, 2 > ITEM_RTREE
std::map< std::pair< const ZONE *, PCB_LAYER_ID >, std::pair< HASH_128, SHAPE_POLY_SET > > m_refillResultCache
PROGRESS_REPORTER * m_progressReporter
bool refillZoneFromCache(ZONE *aZone, PCB_LAYER_ID aLayer, SHAPE_POLY_SET &aFillPolys, const FillSnapshot *aSnapshot=nullptr)
Refill a zone from cached pre-knockout fill.
bool zoneKnockoutMayInteract(const ZONE *aZone, const ZONE *aKnockout) const
Test whether aKnockout's fill can knock out any part of aZone's fill.
bool mayHoldOutOfBoardCopper(const ZONE *aZone) const
True if the fill of aZone can reach outside the board outline.
bool addCopperThievingPattern(const ZONE *aZone, PCB_LAYER_ID aLayer, SHAPE_POLY_SET &aFillPolys)
Stamp a regular grid of pattern shapes onto a zone's filled area for copper thieving.
bool fillCopperZone(const ZONE *aZone, PCB_LAYER_ID aLayer, PCB_LAYER_ID aDebugLayer, const SHAPE_POLY_SET &aSmoothedOutline, const SHAPE_POLY_SET &aMaxExtents, SHAPE_POLY_SET &aFillPolys)
Function fillCopperZone Add non copper areas polygons (pads and tracks with clearance) to a filled co...
void addHoleKnockout(PAD *aPad, int aGap, SHAPE_POLY_SET &aHoles)
Add a knockout for a pad's hole.
bool fillNonCopperZone(const ZONE *candidate, PCB_LAYER_ID aLayer, const SHAPE_POLY_SET &aSmoothedOutline, SHAPE_POLY_SET &aFillPolys)
ITEM_RTREE m_graphicIndex
int m_maxZoneCornerRadius
bool addHatchFillTypeOnZone(const ZONE *aZone, PCB_LAYER_ID aLayer, PCB_LAYER_ID aDebugLayer, SHAPE_POLY_SET &aFillPolys, const SHAPE_POLY_SET &aThermalRings)
for zones having the ZONE_FILL_MODE::ZONE_FILL_MODE::HATCH_PATTERN, create a grid pattern in filled a...
int m_zoneKnockoutSlack
bool fillSingleZone(ZONE *aZone, PCB_LAYER_ID aLayer, SHAPE_POLY_SET &aFillPolys)
Build the filled solid areas polygons from zone outlines (stored in m_Poly) The solid areas can be mo...
bool Fill(const std::vector< ZONE * > &aZones, bool aCheck=false, wxWindow *aParent=nullptr)
Fills the given list of zones.
bool IsDebug() const
Definition zone_filler.h:61
Handle a list of polygons defining a copper zone.
Definition zone.h:70
PCB_LAYER_ID
A quick note on layer IDs:
Definition layer_ids.h:56
An item in one of the fill indexes.