KiCad PCB EDA Suite
Loading...
Searching...
No Matches
fab_layer_index.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 The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20#include "fab_layer_index.h"
21
22#include "fab_item_order.h"
23#include <algorithm>
24#include <board.h>
26#include <eda_text.h>
27#include <footprint.h>
28#include <pad.h>
29#include <pcb_field.h>
30#include <pcb_shape.h>
31#include <pcb_track.h>
32#include <zone.h>
33
34
36{
37 LSET enabled = aBoard.GetEnabledLayers();
38
39 for( PCB_TRACK* track : aBoard.Tracks() )
40 {
41 if( track->Type() == PCB_VIA_T )
42 {
43 PCB_VIA* via = static_cast<PCB_VIA*>( track );
44
45 for( PCB_LAYER_ID layer : enabled )
46 {
47 if( via->FlashLayer( layer ) )
48 m_items[layer][via->GetNetCode()].push_back( via );
49 }
50 }
51 else
52 {
53 for( PCB_LAYER_ID layer : track->GetLayerSet().Seq() )
54 m_items[layer][track->GetNetCode()].push_back( track );
55 }
56 }
57
58 for( ZONE* zone : aBoard.Zones() )
59 {
60 for( PCB_LAYER_ID layer : zone->GetLayerSet().Seq() )
61 m_items[layer][zone->GetNetCode()].push_back( zone );
62 }
63
64 for( BOARD_ITEM* item : aBoard.Drawings() )
65 {
66 int netCode = 0;
67
68 if( BOARD_CONNECTED_ITEM* connected = dynamic_cast<BOARD_CONNECTED_ITEM*>( item ) )
69 netCode = connected->GetNetCode();
70
71 for( PCB_LAYER_ID layer : item->GetLayerSet().Seq() )
72 m_items[layer][netCode].push_back( item );
73 }
74
75 for( FOOTPRINT* footprint : aBoard.Footprints() )
76 {
77 for( PCB_FIELD* field : footprint->GetFields() )
78 m_items[field->GetLayer()][0].push_back( field );
79
80 for( BOARD_ITEM* item : footprint->GraphicalItems() )
81 {
82 for( PCB_LAYER_ID layer : item->GetLayerSet().Seq() )
83 m_items[layer][0].push_back( item );
84 }
85
86 for( PAD* pad : footprint->Pads() )
87 {
88 for( PCB_LAYER_ID layer : pad->GetLayerSet().Seq() )
89 {
90 if( pad->FlashLayer( layer ) )
91 m_items[layer][pad->GetNetCode()].push_back( pad );
92 }
93 }
94 }
95
96 for( auto& [layer, nets] : m_items )
97 {
98 for( auto& [netCode, items] : nets )
99 std::stable_sort( items.begin(), items.end(), FabItemLess );
100 }
101}
102
103
105{
106 static const NET_ITEMS empty;
107 auto it = m_items.find( aLayer );
108 return it != m_items.end() ? it->second : empty;
109}
110
111
112int FabTrackWidth( const PCB_TRACK& aTrack, PCB_LAYER_ID aLayer )
113{
114 int width = aTrack.GetWidth();
115
116 if( IsSolderMaskLayer( aLayer ) )
117 width += 2 * aTrack.GetSolderMaskExpansion();
118
119 return width;
120}
121
122
123bool FabMaskShape( const PCB_SHAPE& aShape, PCB_LAYER_ID aLayer, PCB_SHAPE& aResult )
124{
125 if( !IsSolderMaskLayer( aLayer ) || !aShape.HasSolderMask() || !IsExternalCopperLayer( aShape.GetLayer() )
126 || !aShape.GetSolderMaskExpansion() )
127 {
128 return false;
129 }
130
131 aResult = aShape;
132 int expansion = aShape.GetSolderMaskExpansion();
133 int thickness = aShape.GetWidth() + 2 * expansion;
134 aResult.SetWidth( std::max( thickness, 0 ) );
135
136 // Negative expansion also shrinks closed shapes
137 if( thickness < 0 )
138 {
139 int excess = -thickness;
140
141 switch( aShape.GetShape() )
142 {
143 case SHAPE_T::CIRCLE: aResult.SetRadius( std::max( aShape.GetRadius() - excess, 1 ) ); break;
144
146 aResult.SetRectangleWidth( aShape.GetRectangleWidth() - 2 * excess );
147 aResult.SetRectangleHeight( aShape.GetRectangleHeight() - 2 * excess );
148 aResult.SetCornerRadius( std::max( aShape.GetCornerRadius() - excess, 0 ) );
149 break;
150
151 case SHAPE_T::POLY:
152 if( aShape.IsPolyShapeValid() )
153 {
154 SHAPE_POLY_SET& poly = aResult.GetPolyShape();
155 poly.Fracture();
157 }
158
159 break;
160
161 default: break;
162 }
163 }
164
165 return true;
166}
167
168
169bool FabLayerHasVisibleItems( const BOARD& aBoard, PCB_LAYER_ID aLayer )
170{
171 if( !aBoard.IsLayerEnabled( aLayer ) )
172 return false;
173
174 auto visible = [aLayer]( const BOARD_ITEM* aItem )
175 {
176 const EDA_TEXT* text = dynamic_cast<const EDA_TEXT*>( aItem );
177 return aItem->IsOnLayer( aLayer ) && ( !text || text->IsVisible() );
178 };
179
180 for( const BOARD_ITEM* item : aBoard.Drawings() )
181 {
182 if( visible( item ) )
183 return true;
184 }
185
186 for( const ZONE* zone : aBoard.Zones() )
187 {
188 if( visible( zone ) )
189 return true;
190 }
191
192 for( const FOOTPRINT* footprint : aBoard.Footprints() )
193 {
194 for( const BOARD_ITEM* item : footprint->GraphicalItems() )
195 {
196 if( visible( item ) )
197 return true;
198 }
199
200 for( const PCB_FIELD* field : footprint->GetFields() )
201 {
202 if( visible( field ) )
203 return true;
204 }
205
206 for( const ZONE* zone : footprint->Zones() )
207 {
208 if( visible( zone ) )
209 return true;
210 }
211 }
212
213 return false;
214}
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition board_item.h:84
int GetMaxError() const
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:410
const ZONES & Zones() const
Definition board.h:468
bool IsLayerEnabled(PCB_LAYER_ID aLayer) const
A proxy function that calls the correspondent function in m_BoardSettings tests whether a given layer...
Definition board.cpp:1212
const FOOTPRINTS & Footprints() const
Definition board.h:464
const TRACKS & Tracks() const
Definition board.h:462
const LSET & GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
Definition board.cpp:1185
const DRAWINGS & Drawings() const
Definition board.h:466
int GetRectangleWidth() const
SHAPE_POLY_SET & GetPolyShape()
int GetRadius() const
SHAPE_T GetShape() const
Definition eda_shape.h:175
void SetRectangleHeight(const int &aHeight)
void SetRadius(int aX)
Definition eda_shape.h:350
void SetRectangleWidth(const int &aWidth)
int GetRectangleHeight() const
int GetCornerRadius() const
bool IsPolyShapeValid() const
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition eda_text.h:94
FAB_LAYER_INDEX(BOARD &aBoard)
const NET_ITEMS & Items(PCB_LAYER_ID aLayer) const
std::map< PCB_LAYER_ID, NET_ITEMS > m_items
std::map< int, std::vector< BOARD_ITEM * > > NET_ITEMS
LSET is a set of PCB_LAYER_IDs.
Definition lset.h:37
Definition pad.h:61
void SetCornerRadius(int aCornerRadius) override
void SetWidth(int aWidth) override
int GetWidth() const override
bool HasSolderMask() const
Definition pcb_shape.h:344
int GetSolderMaskExpansion() const
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
Definition pcb_shape.h:68
int GetSolderMaskExpansion() const
virtual int GetWidth() const
Definition pcb_track.h:92
Represent a set of closed polygons.
void Deflate(int aAmount, CORNER_STRATEGY aCornerStrategy, int aMaxError)
void Fracture(bool aSimplify=true)
Convert a set of polygons with holes to a single outline with "slits"/"fractures" connecting the oute...
Handle a list of polygons defining a copper zone.
Definition zone.h:70
@ ROUND_ALL_CORNERS
All angles are rounded.
static bool empty(const wxTextEntryBase *aCtrl)
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
Definition eda_shape.h:57
bool FabItemLess(const BOARD_ITEM *aFirst, const BOARD_ITEM *aSecond)
Order by footprint UUID so feature output is independent of allocation order.
int FabTrackWidth(const PCB_TRACK &aTrack, PCB_LAYER_ID aLayer)
Use only for traces and arcs; vias require a layer-specific width.
bool FabMaskShape(const PCB_SHAPE &aShape, PCB_LAYER_ID aLayer, PCB_SHAPE &aResult)
Build an expanded mask copy of an exposed copper shape when needed.
bool FabLayerHasVisibleItems(const BOARD &aBoard, PCB_LAYER_ID aLayer)
True if the board draws visible text, graphics or zones on aLayer.
bool IsSolderMaskLayer(int aLayer)
Definition layer_ids.h:774
bool IsExternalCopperLayer(int aLayerId)
Test whether a layer is an external (F_Cu or B_Cu) copper layer.
Definition layer_ids.h:714
PCB_LAYER_ID
A quick note on layer IDs:
Definition layer_ids.h:56
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
Definition typeinfo.h:89