KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pads_layer_mapper.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 modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include "pads_layer_mapper.h"
21
22#include <algorithm>
23#include <cctype>
24
25#include <wx/string.h>
26
27
30{
31 // Initialize standard PADS layer name mappings (case-insensitive)
37
43
49
55
58 m_layerNameMap["solder paste top"] = PADS_LAYER_TYPE::PASTE_TOP;
60
62 m_layerNameMap["paste mask bottom"] = PADS_LAYER_TYPE::PASTE_BOTTOM;
63 m_layerNameMap["solder paste bottom"] = PADS_LAYER_TYPE::PASTE_BOTTOM;
65
69 m_layerNameMap["component outline top"] = PADS_LAYER_TYPE::ASSEMBLY_TOP;
70
74 m_layerNameMap["component outline bottom"] = PADS_LAYER_TYPE::ASSEMBLY_BOTTOM;
75
80
83}
84
85
87{
88 if( aLayerCount < 1 )
89 aLayerCount = 1;
90
91 m_copperLayerCount = aLayerCount;
92}
93
94
95std::string PADS_LAYER_MAPPER::normalizeLayerName( const std::string& aName ) const
96{
97 std::string normalized;
98 normalized.reserve( aName.size() );
99
100 for( char c : aName )
101 {
102 normalized += static_cast<char>( std::tolower( static_cast<unsigned char>( c ) ) );
103 }
104
105 return normalized;
106}
107
108
110{
111 // Pad stack special values
112 if( aPadsLayer == LAYER_PAD_STACK_TOP )
114
115 if( aPadsLayer == LAYER_PAD_STACK_BOTTOM )
117
118 if( aPadsLayer == LAYER_PAD_STACK_INNER )
120
121 // Copper layers: 1 = Top, m_copperLayerCount = Bottom, 2 to N-1 = Inner
122 if( aPadsLayer == 1 )
124
125 if( aPadsLayer == m_copperLayerCount && m_copperLayerCount > 1 )
127
128 if( aPadsLayer > 1 && aPadsLayer < m_copperLayerCount )
130
131 // Non-copper layers by number
132 if( aPadsLayer == LAYER_DRILL_DRAWING )
134
135 if( aPadsLayer == LAYER_DIMENSIONS || aPadsLayer == LAYER_PLACEMENT_OUTLINE )
137
138 if( aPadsLayer == LAYER_ASSEMBLY_TOP )
140
141 if( aPadsLayer == LAYER_ASSEMBLY_BOTTOM )
143
144 if( aPadsLayer == LAYER_SOLDERMASK_TOP )
146
147 if( aPadsLayer == LAYER_SILKSCREEN_TOP )
149
150 if( aPadsLayer == LAYER_SILKSCREEN_BOTTOM )
152
153 if( aPadsLayer == LAYER_SOLDERMASK_BOTTOM )
155
156 if( aPadsLayer == LAYER_PASTE_TOP )
158
159 if( aPadsLayer == LAYER_PASTE_BOTTOM )
161
163}
164
165
166PADS_LAYER_TYPE PADS_LAYER_MAPPER::ParseLayerName( const std::string& aLayerName ) const
167{
168 std::string normalized = normalizeLayerName( aLayerName );
169
170 auto it = m_layerNameMap.find( normalized );
171
172 if( it != m_layerNameMap.end() )
173 return it->second;
174
175 // Check for copper layer naming patterns like "Layer 1", "Inner 1", etc.
176 if( normalized.find( "top" ) != std::string::npos ||
177 normalized.find( "layer 1" ) != std::string::npos ||
178 normalized == "1" )
179 {
181 }
182
183 if( normalized.find( "bottom" ) != std::string::npos ||
184 normalized.find( "bot" ) != std::string::npos )
185 {
187 }
188
189 if( normalized.find( "inner" ) != std::string::npos ||
190 normalized.find( "mid" ) != std::string::npos ||
191 normalized.find( "internal" ) != std::string::npos )
192 {
194 }
195
197}
198
199
201{
202 // PADS inner layers are numbered 2 through (m_copperLayerCount - 1)
203 // KiCad inner layers are In1_Cu, In2_Cu, etc. with IDs spaced by 2
204 int innerIndex = aPadsLayer - 2;
205
206 if( innerIndex < 0 )
207 innerIndex = 0;
208
209 if( innerIndex >= 30 )
210 innerIndex = 29;
211
212 return static_cast<PCB_LAYER_ID>( In1_Cu + innerIndex * 2 );
213}
214
215
217{
218 // If type is not provided, determine it from layer number
219 if( aType == PADS_LAYER_TYPE::UNKNOWN )
220 aType = GetLayerType( aPadsLayer );
221
222 switch( aType )
223 {
225 return F_Cu;
226
228 return B_Cu;
229
231 return mapInnerCopperLayer( aPadsLayer );
232
234 return F_SilkS;
235
237 return B_SilkS;
238
240 return F_Mask;
241
243 return B_Mask;
244
246 return F_Paste;
247
249 return B_Paste;
250
252 return F_Fab;
253
255 return B_Fab;
256
258 return Edge_Cuts;
259
261 return Cmts_User;
262
264 return Dwgs_User;
265
267 default:
268 return UNDEFINED_LAYER;
269 }
270}
271
272
274{
275 switch( aType )
276 {
280 return LSET::AllCuMask();
281
284 return LSET( { F_SilkS, B_SilkS } );
285
288 return LSET( { F_Mask, B_Mask } );
289
292 return LSET( { F_Paste, B_Paste } );
293
296 return LSET( { F_Fab, B_Fab, F_CrtYd, B_CrtYd } );
297
299 return LSET( { Edge_Cuts } );
300
302 return LSET::AllNonCuMask();
303
305 return LSET( { Dwgs_User, F_Fab, B_Fab, Cmts_User } );
306
308 default:
309 return LSET::AllLayersMask();
310 }
311}
312
313
315 const std::vector<PADS_LAYER_INFO>& aLayerInfos ) const
316{
317 std::vector<INPUT_LAYER_DESC> descs;
318 descs.reserve( aLayerInfos.size() );
319
320 for( const PADS_LAYER_INFO& info : aLayerInfos )
321 {
322 INPUT_LAYER_DESC desc;
323
324 desc.Name = wxString::FromUTF8( info.name );
326 desc.AutoMapLayer = GetAutoMapLayer( info.padsLayerNum, info.type );
327 desc.Required = info.required;
328
329 descs.push_back( desc );
330 }
331
332 return descs;
333}
334
335
336void PADS_LAYER_MAPPER::AddLayerNameMapping( const std::string& aName, PADS_LAYER_TYPE aType )
337{
338 std::string normalized = normalizeLayerName( aName );
339 m_layerNameMap[normalized] = aType;
340}
341
342
344{
345 switch( aType )
346 {
347 case PADS_LAYER_TYPE::COPPER_TOP: return "Copper Top";
348 case PADS_LAYER_TYPE::COPPER_BOTTOM: return "Copper Bottom";
349 case PADS_LAYER_TYPE::COPPER_INNER: return "Copper Inner";
350 case PADS_LAYER_TYPE::SILKSCREEN_TOP: return "Silkscreen Top";
351 case PADS_LAYER_TYPE::SILKSCREEN_BOTTOM: return "Silkscreen Bottom";
352 case PADS_LAYER_TYPE::SOLDERMASK_TOP: return "Solder Mask Top";
353 case PADS_LAYER_TYPE::SOLDERMASK_BOTTOM: return "Solder Mask Bottom";
354 case PADS_LAYER_TYPE::PASTE_TOP: return "Paste Top";
355 case PADS_LAYER_TYPE::PASTE_BOTTOM: return "Paste Bottom";
356 case PADS_LAYER_TYPE::ASSEMBLY_TOP: return "Assembly Top";
357 case PADS_LAYER_TYPE::ASSEMBLY_BOTTOM: return "Assembly Bottom";
358 case PADS_LAYER_TYPE::DOCUMENTATION: return "Documentation";
359 case PADS_LAYER_TYPE::BOARD_OUTLINE: return "Board Outline";
360 case PADS_LAYER_TYPE::DRILL_DRAWING: return "Drill Drawing";
362 default: return "Unknown";
363 }
364}
LSET is a set of PCB_LAYER_IDs.
Definition lset.h:37
static LSET AllNonCuMask()
Return a mask holding all layer minus CU layers.
Definition lset.cpp:627
static const LSET & AllLayersMask()
Definition lset.cpp:641
static LSET AllCuMask()
return AllCuMask( MAX_CU_LAYERS );
Definition lset.cpp:608
LSET GetPermittedLayers(PADS_LAYER_TYPE aType) const
Get the permitted KiCad layers for a given PADS layer type.
PADS_LAYER_TYPE ParseLayerName(const std::string &aLayerName) const
Parse a PADS layer name and return its type.
static constexpr int LAYER_ASSEMBLY_TOP
static constexpr int LAYER_SILKSCREEN_BOTTOM
static constexpr int LAYER_PASTE_TOP
static constexpr int LAYER_SILKSCREEN_TOP
PADS_LAYER_TYPE GetLayerType(int aPadsLayer) const
Parse a PADS layer number and return its type.
static constexpr int LAYER_PLACEMENT_OUTLINE
static constexpr int LAYER_SOLDERMASK_TOP
static constexpr int LAYER_ASSEMBLY_BOTTOM
PCB_LAYER_ID mapInnerCopperLayer(int aPadsLayer) const
static constexpr int LAYER_DIMENSIONS
PCB_LAYER_ID GetAutoMapLayer(int aPadsLayer, PADS_LAYER_TYPE aType=PADS_LAYER_TYPE::UNKNOWN) const
Get the suggested KiCad layer for a PADS layer.
static constexpr int LAYER_PAD_STACK_BOTTOM
Pad stack: Bottom copper.
std::string normalizeLayerName(const std::string &aName) const
static constexpr int LAYER_PAD_STACK_TOP
Pad stack: Top copper.
static constexpr int LAYER_PASTE_BOTTOM
static std::string LayerTypeToString(PADS_LAYER_TYPE aType)
Convert a layer type to a human-readable string.
void SetCopperLayerCount(int aLayerCount)
Set the total number of copper layers in the PADS design.
static constexpr int LAYER_PAD_STACK_INNER
Pad stack: Inner copper.
std::map< std::string, PADS_LAYER_TYPE > m_layerNameMap
std::vector< INPUT_LAYER_DESC > BuildInputLayerDescriptions(const std::vector< PADS_LAYER_INFO > &aLayerInfos) const
Build a vector of INPUT_LAYER_DESC from parsed PADS layer information.
void AddLayerNameMapping(const std::string &aName, PADS_LAYER_TYPE aType)
Add or update a layer name to type mapping.
static constexpr int LAYER_DRILL_DRAWING
static constexpr int LAYER_SOLDERMASK_BOTTOM
PCB_LAYER_ID
A quick note on layer IDs:
Definition layer_ids.h:60
@ F_CrtYd
Definition layer_ids.h:116
@ Edge_Cuts
Definition layer_ids.h:112
@ Dwgs_User
Definition layer_ids.h:107
@ F_Paste
Definition layer_ids.h:104
@ Cmts_User
Definition layer_ids.h:108
@ B_Mask
Definition layer_ids.h:98
@ B_Cu
Definition layer_ids.h:65
@ F_Mask
Definition layer_ids.h:97
@ B_Paste
Definition layer_ids.h:105
@ F_Fab
Definition layer_ids.h:119
@ F_SilkS
Definition layer_ids.h:100
@ B_CrtYd
Definition layer_ids.h:115
@ UNDEFINED_LAYER
Definition layer_ids.h:61
@ In1_Cu
Definition layer_ids.h:66
@ B_SilkS
Definition layer_ids.h:101
@ F_Cu
Definition layer_ids.h:64
@ B_Fab
Definition layer_ids.h:118
PADS_LAYER_TYPE
PADS layer types.
Describes an imported layer and how it could be mapped to KiCad Layers.
PCB_LAYER_ID AutoMapLayer
Best guess as to what the equivalent KiCad layer might be.
bool Required
Should we require the layer to be assigned?
LSET PermittedLayers
KiCad layers that the imported layer can be mapped onto.
wxString Name
Imported layer name as displayed in original application.
Information about a single PADS layer.