85 std::swap( start,
end );
93 return aCopperLayerCount;
95 return (
end - start ) / 2 - 1;
97 else if ( aEnd ==
B_Cu )
100 return aCopperLayerCount - start / 2 + 1;
103 return (
end - start ) / 2;
109 std::map<wxString, PCB_LAYER_ID> layerMap = {
134 if(
auto it = layerMap.find( aName ); it != layerMap.end() )
135 return static_cast<int>( it->second );
137 if( aName.StartsWith(
"User." ) )
141 if( aName.Mid( 5 ).ToLong( &offset ) && offset > 0 )
142 return static_cast<int>(
User_1 ) + ( offset - 1 ) * 2;
145 if( aName.StartsWith(
"In" ) )
148 wxString str_num = aName.Mid( 2 );
149 str_num.RemoveLast( 3 );
151 if( str_num.ToLong( &offset ) && offset > 0 )
152 return static_cast<int>(
In1_Cu ) + ( offset - 1 ) * 2;
161 if( aLayer == aStart || aLayer == aEnd )
164 int start = std::min( aStart, aEnd );
165 int end = std::max( aStart, aEnd );
171 end = std::numeric_limits<PCB_LAYER_ID>::max() & ~1;
174 return !( layer & 1 ) && ( layer >= start ) && ( layer <=
end );
190 case F_Cu: txt = wxT(
"F.Cu" );
break;
191 case B_Cu: txt = wxT(
"B.Cu" );
break;
194 case B_Adhes: txt = wxT(
"B.Adhes" );
break;
195 case F_Adhes: txt = wxT(
"F.Adhes" );
break;
196 case B_Paste: txt = wxT(
"B.Paste" );
break;
197 case F_Paste: txt = wxT(
"F.Paste" );
break;
198 case B_SilkS: txt = wxT(
"B.SilkS" );
break;
199 case F_SilkS: txt = wxT(
"F.SilkS" );
break;
200 case B_Mask: txt = wxT(
"B.Mask" );
break;
201 case F_Mask: txt = wxT(
"F.Mask" );
break;
204 case Dwgs_User: txt = wxT(
"Dwgs.User" );
break;
205 case Cmts_User: txt = wxT(
"Cmts.User" );
break;
206 case Eco1_User: txt = wxT(
"Eco1.User" );
break;
207 case Eco2_User: txt = wxT(
"Eco2.User" );
break;
208 case Edge_Cuts: txt = wxT(
"Edge.Cuts" );
break;
209 case Margin: txt = wxT(
"Margin" );
break;
212 case F_CrtYd: txt = wxT(
"F.CrtYd" );
break;
213 case B_CrtYd: txt = wxT(
"B.CrtYd" );
break;
214 case F_Fab: txt = wxT(
"F.Fab" );
break;
215 case B_Fab: txt = wxT(
"B.Fab" );
break;
218 case Rescue: txt = wxT(
"Rescue" );
break;
222 if(
static_cast<int>( aLayerId ) & 1 )
224 int offset = ( aLayerId -
Rescue ) / 2;
225 txt = wxString::Format( wxT(
"User.%d" ), offset );
229 int offset = ( aLayerId -
B_Cu ) / 2;
230 txt = wxString::Format( wxT(
"In%d.Cu" ), offset );
247 ret.push_back( *it );
283 ret.push_back( *it );
294 int bit_count = size();
296 for(
int bit=0; bit<bit_count; ++bit )
302 else if( !( bit % 4 ) )
306 ret += (*this)[bit] ?
'1' :
'0';
310 return std::string( ret.rbegin(), ret.rend() );
318 static const char hex[] =
"0123456789abcdef";
320 size_t nibble_count = ( size() + 3 ) / 4;
322 for(
size_t nibble = 0; nibble < nibble_count; ++nibble )
324 unsigned int ndx = 0;
327 for(
size_t nibble_bit = 0; nibble_bit < 4; ++nibble_bit )
329 size_t nibble_pos = nibble_bit + ( nibble * 4 );
332 if( nibble_pos >= size() )
335 if( ( *
this )[nibble_pos] )
336 ndx |= ( 1 << nibble_bit );
339 if( nibble && !( nibble % 8 ) )
348 return std::string( ret.rbegin(), ret.rend() );
354 return ParseHex( str.c_str(), str.length() );
362 const char* rstart = aStart + aCount - 1;
363 const char* rend = aStart - 1;
365 const int bitcount = size();
369 while( rstart > rend )
378 if( cc >=
'0' && cc <=
'9' )
380 else if( cc >=
'a' && cc <=
'f' )
381 nibble = cc -
'a' + 10;
382 else if( cc >=
'A' && cc <=
'F' )
383 nibble = cc -
'A' + 10;
387 int bit = nibble_ndx * 4;
389 for(
int ndx=0; bit<bitcount && ndx<4; ++bit, ++ndx )
390 if( nibble & (1<<ndx) )
393 if( bit >= bitcount )
399 int byte_count = aStart + aCount - 1 - rstart;
401 assert( byte_count >= 0 );
417 ret.push_back( layer );
428 ret.reserve( size() );
430 for(
unsigned i = 0; i < size(); ++i )
451 LSEQ top_tech_sequence =
Seq( {
460 LSEQ bottom_tech_sequence =
Seq( {
470 LSEQ seq =
Seq( base_sequence );
475 seq.push_back( *it );
478 std::copy( top_tech_sequence.begin(), top_tech_sequence.end(), std::back_inserter( seq ) );
481 seq.push_back( *it );
483 std::copy( bottom_tech_sequence.begin(), bottom_tech_sequence.end(), std::back_inserter( seq ) );
487 auto it = std::find( seq.begin(), seq.end(), aSelectedLayer );
489 if( it != seq.end() )
492 seq.insert( seq.begin(), aSelectedLayer );
505 LSEQ bottom_tech_sequence =
Seq( {
517 LSEQ top_tech_sequence =
Seq( {
542 LSEQ seq =
Seq( bottom_tech_sequence );
544 std::vector<PCB_LAYER_ID> temp_layers;
552 temp_layers.push_back( *it );
555 for(
auto it = temp_layers.rbegin(); it != temp_layers.rend(); ++it )
556 seq.push_back( *it );
558 std::copy( top_tech_sequence.begin(), top_tech_sequence.end(), std::back_inserter( seq ) );
560 std::copy( user_sequence.begin(), user_sequence.end(), std::back_inserter( seq ) );
567 temp_layers.push_back( *it );
570 for(
auto it = temp_layers.rbegin(); it != temp_layers.rend(); ++it )
572 seq.push_back( *it );
575 std::copy( base_sequence.begin(), base_sequence.end(), std::back_inserter( seq ) );
583 LSET oldMask = *
this;
588 const std::map<PCB_LAYER_ID, PCB_LAYER_ID> flip_map =
606 for(
const auto& pair : flip_map )
608 if( oldMask.test( pair.first ) )
612 if( aCopperLayersCount >= 4 )
615 int innerLayerCount = aCopperLayersCount - 2;
617 for(
int ii = 1; ii <= innerLayerCount; ii++ )
619 if( internalMask.test( ( innerLayerCount - ii ) * 2 +
B_Cu ) )
632 unsigned set_count = count();
636 else if( set_count > 1 )
639 for(
unsigned i=0; i < size(); ++i )
689 static const LSET saved =
LSET().set() & ~AllCuMask();
703 static const LSET saved =
LSET().set();
765 static const LSET saved(
804 order.insert( order.end(), techuser.begin(), techuser.end() );
813 if( aLayer == std::numeric_limits<int>::max() )
823 for(
unsigned i = 0; i < aCount; ++i )
830 std::vector<GAL_LAYER_ID> ret;
832 for(
size_t i = 0; i < size(); ++i )
906 advance_to_next_set_copper_bit();
912 if( m_index ==
F_Cu )
916 else if( m_index ==
B_Cu )
918 m_index = m_baseSet.size();
925 if( m_index >= m_baseSet.size() )
932 while( m_index < m_baseSet.size() && !m_baseSet.test( m_index ) )
950 advance_to_next_set_non_copper_bit();
956 while( m_index < m_baseSet.size() && ( m_index % 2 != 1 || !m_baseSet.test( m_index ) ) )
constexpr std::size_t arrayDim(T const (&)[N]) noexcept
Returns # of elements in an array.
BASE_SET & set(size_t pos)
Helper for storing and iterating over GAL_LAYER_IDs.
static GAL_SET DefaultVisible()
std::vector< GAL_LAYER_ID > Seq() const
LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
copper_layers_iterator & operator++()
PCB_LAYER_ID operator*() const
void advance_to_next_set_copper_bit()
copper_layers_iterator(const BASE_SET &set, size_t index)
void advance_to_next_set_non_copper_bit()
PCB_LAYER_ID operator*() const
non_copper_layers_iterator & operator++()
non_copper_layers_iterator(const BASE_SET &set, size_t index)
LSET is a set of PCB_LAYER_IDs.
LSET & Flip(int aCopperLayersCount=0)
Flip the layers in this set.
static LSET ExternalCuMask()
Return a mask holding the Front and Bottom layers.
int ParseHex(const char *aStart, int aCount)
Convert the output of FmtHex() and replaces this set's values with those given in the input string.
static bool IsBetween(PCB_LAYER_ID aStart, PCB_LAYER_ID aEnd, PCB_LAYER_ID aLayer)
Return true if aLayer is between aStart and aEnd, inclusive.
copper_layers_iterator copper_layers_end() const
LSEQ UIOrder() const
Returns the copper, technical and user layers in the order shown in layer widget.
static LSET AllBoardTechMask()
Return a mask holding board technical layers (no CU layer) on both side.
static LSET AllLayersMask()
static LSET UserDefinedLayers()
Return a mask with all of the allowable user defined layers.
LSEQ CuStack() const
Return a sequence of copper layers in starting from the front/top and extending to the back/bottom.
PCB_LAYER_ID ExtractLayer() const
Find the first set PCB_LAYER_ID.
LSEQ SeqStackupForPlotting() const
Return the sequence that is typical for a bottom-to-top stack-up.
static LSET FrontBoardTechMask()
Return a mask holding technical layers used in a board fabrication (no CU layer) on front side.
static LSET AllNonCuMask()
Return a mask holding all layer minus CU layers.
static LSET FrontAssembly()
Return a complete set of all top assembly layers which is all F_SilkS and F_Mask.
LSEQ TechAndUserUIOrder() const
Returns the technical and user layers in the order shown in layer widget.
static LSET AllTechMask()
Return a mask holding all technical layers (no CU layer) on both side.
static LSET InternalCuMask()
Return a complete set of internal copper layers which is all Cu layers except F_Cu and B_Cu.
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
static LSET SideSpecificMask()
static LSET PhysicalLayersMask()
Return a mask holding all layers which are physically realized.
all_set_layers_iterator end() const
LSEQ Seq() const
Return a LSEQ from this LSET in ascending PCB_LAYER_ID order.
std::string FmtHex() const
Return a hex string showing contents of this LSEQ.
copper_layers_iterator copper_layers_begin() const
non_copper_layers_iterator non_copper_layers_begin() const
static int NameToLayer(wxString &aName)
Return the layer number from a layer name.
static LSET ForbiddenFootprintLayers()
Layers which are not allowed within footprint definitions.
LSEQ SeqStackupTop2Bottom(PCB_LAYER_ID aSelectedLayer=UNDEFINED_LAYER) const
Generate a sequence of layers that represent a top to bottom stack of this set of layers.
non_copper_layers_iterator non_copper_layers_end() const
std::string FmtBin() const
Return a binary string showing contents of this LSEQ.
static LSET FrontTechMask()
Return a mask holding all technical layers (no CU layer) on front side.
static LSET BackBoardTechMask()
Return a mask holding technical layers used in a board fabrication (no CU layer) on Back side.
static LSET BackTechMask()
Return a mask holding all technical layers (no CU layer) on back side.
static LSET BackAssembly()
Return a complete set of all bottom assembly layers which is all B_SilkS and B_Mask.
static LSET FrontMask()
Return a mask holding all technical layers and the external CU layer on front side.
static LSET BackMask()
Return a mask holding all technical layers and the external CU layer on back side.
static wxString Name(PCB_LAYER_ID aLayerId)
Return the fixed name association with aLayerId.
LSET()
Create an empty (cleared) set.
static int LayerCount(PCB_LAYER_ID aStart, PCB_LAYER_ID aEnd, int aCopperLayerCount)
Return the number of layers between aStart and aEnd, inclusive.
bool IsCopperLayer(int aLayerId)
Tests whether a layer is a copper layer.
GAL_LAYER_ID
GAL layers are "virtual" layers, i.e.
@ LAYER_LOCKED_ITEM_SHADOW
shadow layer for locked items
@ LAYER_CONFLICTS_SHADOW
shadow layer for items flagged conficting
@ LAYER_FOOTPRINTS_FR
show footprints on front
@ LAYER_DRC_SHAPE1
Custom shape for DRC marker.
@ LAYER_NON_PLATEDHOLES
handle color for not plated holes (holes, not pads)
@ LAYER_DRAWINGSHEET
drawingsheet frame and titleblock
@ LAYER_DRAW_BITMAPS
to handle and draw images bitmaps
@ LAYER_FP_REFERENCES
show footprints references (when texts are visible)
@ LAYER_PCB_BACKGROUND
PCB background color.
@ LAYER_ZONES
Control for copper zone opacity/visibility (color ignored)
@ LAYER_SHAPES
Copper graphic shape opacity/visibility (color ignored)
@ LAYER_PADS
Meta control for all pads opacity/visibility (color ignored)
@ LAYER_DRC_WARNING
layer for drc markers with SEVERITY_WARNING
@ LAYER_PAD_PLATEDHOLES
to draw pad holes (plated)
@ LAYER_GP_OVERLAY
general purpose overlay
@ LAYER_CURSOR
PCB cursor.
@ LAYER_AUX_ITEMS
Auxiliary items (guides, rule, etc)
@ LAYER_DRC_SHAPE2
Custom shape for DRC marker.
@ LAYER_FOOTPRINTS_BK
show footprints on back
@ LAYER_ANCHOR
anchor of items having an anchor point (texts, footprints)
@ LAYER_VIA_HOLES
to draw via holes (pad holes do not use this layer)
@ LAYER_FP_VALUES
show footprints values (when texts are visible)
@ LAYER_VIA_MICROVIA
to draw micro vias
@ LAYER_SELECT_OVERLAY
currently selected items overlay
@ LAYER_VIA_THROUGH
to draw usual through hole vias
@ LAYER_DRC_ERROR
layer for drc markers with SEVERITY_ERROR
@ LAYER_VIAS
Meta control for all vias opacity/visibility.
@ LAYER_VIA_BBLIND
to draw blind/buried vias
PCB_LAYER_ID
A quick note on layer IDs:
PCB_LAYER_ID ToLAYER_ID(int aLayer)
This file contains miscellaneous commonly used macros and functions.