95 std::swap( start,
end );
103 return aCopperLayerCount;
105 return (
end - start ) / 2 - 1;
107 else if ( aEnd ==
B_Cu )
110 return aCopperLayerCount - start / 2 + 1;
113 return (
end - start ) / 2;
119 std::map<wxString, PCB_LAYER_ID> layerMap = {
144 if(
auto it = layerMap.find( aName ); it != layerMap.end() )
145 return static_cast<int>( it->second );
147 if( aName.StartsWith(
"User." ) )
151 if( aName.Mid( 5 ).ToLong( &offset ) && offset > 0 )
152 return static_cast<int>(
User_1 ) + ( offset - 1 ) * 2;
155 if( aName.StartsWith(
"In" ) )
158 wxString str_num = aName.Mid( 2 );
159 str_num.RemoveLast( 3 );
161 if( str_num.ToLong( &offset ) && offset > 0 )
162 return static_cast<int>(
In1_Cu ) + ( offset - 1 ) * 2;
171 if( aLayer == aStart || aLayer == aEnd )
174 int start = std::min( aStart, aEnd );
175 int end = std::max( aStart, aEnd );
181 end = std::numeric_limits<PCB_LAYER_ID>::max() & ~1;
184 return !( layer & 1 ) && ( layer >= start ) && ( layer <=
end );
200 case F_Cu: txt = wxT(
"F.Cu" );
break;
201 case B_Cu: txt = wxT(
"B.Cu" );
break;
204 case B_Adhes: txt = wxT(
"B.Adhes" );
break;
205 case F_Adhes: txt = wxT(
"F.Adhes" );
break;
206 case B_Paste: txt = wxT(
"B.Paste" );
break;
207 case F_Paste: txt = wxT(
"F.Paste" );
break;
208 case B_SilkS: txt = wxT(
"B.SilkS" );
break;
209 case F_SilkS: txt = wxT(
"F.SilkS" );
break;
210 case B_Mask: txt = wxT(
"B.Mask" );
break;
211 case F_Mask: txt = wxT(
"F.Mask" );
break;
214 case Dwgs_User: txt = wxT(
"Dwgs.User" );
break;
215 case Cmts_User: txt = wxT(
"Cmts.User" );
break;
216 case Eco1_User: txt = wxT(
"Eco1.User" );
break;
217 case Eco2_User: txt = wxT(
"Eco2.User" );
break;
218 case Edge_Cuts: txt = wxT(
"Edge.Cuts" );
break;
219 case Margin: txt = wxT(
"Margin" );
break;
222 case F_CrtYd: txt = wxT(
"F.CrtYd" );
break;
223 case B_CrtYd: txt = wxT(
"B.CrtYd" );
break;
224 case F_Fab: txt = wxT(
"F.Fab" );
break;
225 case B_Fab: txt = wxT(
"B.Fab" );
break;
228 case Rescue: txt = wxT(
"Rescue" );
break;
232 if(
static_cast<int>( aLayerId ) & 1 )
234 int offset = ( aLayerId -
Rescue ) / 2;
235 txt = wxString::Format( wxT(
"User.%d" ), offset );
239 int offset = ( aLayerId -
B_Cu ) / 2;
240 txt = wxString::Format( wxT(
"In%d.Cu" ), offset );
257 ret.push_back( *it );
293 ret.push_back( *it );
304 int bit_count = size();
306 for(
int bit=0; bit<bit_count; ++bit )
312 else if( !( bit % 4 ) )
316 ret += (*this)[bit] ?
'1' :
'0';
320 return std::string( ret.rbegin(), ret.rend() );
328 static const char hex[] =
"0123456789abcdef";
330 size_t nibble_count = ( size() + 3 ) / 4;
332 for(
size_t nibble = 0; nibble < nibble_count; ++nibble )
334 unsigned int ndx = 0;
337 for(
size_t nibble_bit = 0; nibble_bit < 4; ++nibble_bit )
339 size_t nibble_pos = nibble_bit + ( nibble * 4 );
342 if( nibble_pos >= size() )
345 if( ( *
this )[nibble_pos] )
346 ndx |= ( 1 << nibble_bit );
349 if( nibble && !( nibble % 8 ) )
358 return std::string( ret.rbegin(), ret.rend() );
364 return ParseHex( str.c_str(), str.length() );
372 const char* rstart = aStart + aCount - 1;
373 const char* rend = aStart - 1;
375 const int bitcount = size();
379 while( rstart > rend )
388 if( cc >=
'0' && cc <=
'9' )
390 else if( cc >=
'a' && cc <=
'f' )
391 nibble = cc -
'a' + 10;
392 else if( cc >=
'A' && cc <=
'F' )
393 nibble = cc -
'A' + 10;
397 int bit = nibble_ndx * 4;
399 for(
int ndx=0; bit<bitcount && ndx<4; ++bit, ++ndx )
400 if( nibble & (1<<ndx) )
403 if( bit >= bitcount )
409 int byte_count = aStart + aCount - 1 - rstart;
411 assert( byte_count >= 0 );
427 ret.push_back( layer );
438 ret.reserve( size() );
440 for(
unsigned i = 0; i < size(); ++i )
461 LSEQ top_tech_sequence =
Seq( {
470 LSEQ bottom_tech_sequence =
Seq( {
480 LSEQ seq =
Seq( base_sequence );
485 seq.push_back( *it );
488 std::copy( top_tech_sequence.begin(), top_tech_sequence.end(), std::back_inserter( seq ) );
491 seq.push_back( *it );
493 std::copy( bottom_tech_sequence.begin(), bottom_tech_sequence.end(), std::back_inserter( seq ) );
497 auto it = std::find( seq.begin(), seq.end(), aSelectedLayer );
499 if( it != seq.end() )
502 seq.insert( seq.begin(), aSelectedLayer );
515 LSEQ bottom_tech_sequence =
Seq( {
527 LSEQ top_tech_sequence =
Seq( {
552 LSEQ seq =
Seq( bottom_tech_sequence );
554 std::vector<PCB_LAYER_ID> temp_layers;
562 temp_layers.push_back( *it );
565 for(
auto it = temp_layers.rbegin(); it != temp_layers.rend(); ++it )
566 seq.push_back( *it );
568 std::copy( top_tech_sequence.begin(), top_tech_sequence.end(), std::back_inserter( seq ) );
570 std::copy( user_sequence.begin(), user_sequence.end(), std::back_inserter( seq ) );
577 temp_layers.push_back( *it );
580 for(
auto it = temp_layers.rbegin(); it != temp_layers.rend(); ++it )
582 seq.push_back( *it );
585 std::copy( base_sequence.begin(), base_sequence.end(), std::back_inserter( seq ) );
593 LSET oldMask = *
this;
598 const std::map<PCB_LAYER_ID, PCB_LAYER_ID> flip_map =
616 for(
const auto& pair : flip_map )
618 if( oldMask.test( pair.first ) )
622 if( aCopperLayersCount >= 4 )
625 int innerLayerCount = aCopperLayersCount - 2;
627 for(
int ii = 1; ii <= innerLayerCount; ii++ )
629 if( internalMask.test( ( innerLayerCount - ii + 1 ) * 2 +
B_Cu ) )
642 unsigned set_count = count();
646 else if( set_count > 1 )
649 for(
unsigned i=0; i < size(); ++i )
699 static const LSET saved =
LSET().set() & ~AllCuMask();
713 static const LSET saved =
LSET().set();
775 static const LSET saved(
814 order.insert( order.end(), techuser.begin(), techuser.end() );
823 if( aLayer == std::numeric_limits<int>::max() )
833 for(
unsigned i = 0; i < aCount; ++i )
840 std::vector<GAL_LAYER_ID> ret;
842 for(
size_t i = 0; i < size(); ++i )
916 advance_to_next_set_copper_bit();
922 if( m_index ==
F_Cu )
926 else if( m_index ==
B_Cu )
928 m_index = m_baseSet.size();
935 if( m_index >= m_baseSet.size() )
942 while( m_index < m_baseSet.size() && !m_baseSet.test( m_index ) )
960 advance_to_next_set_non_copper_bit();
966 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.