KiCad PCB EDA Suite
Loading...
Searching...
No Matches
lset.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 (C) 2014 SoftPLC Corporation, Dick Hollenbeck <[email protected]>
5 * Copyright (C) 2014-2023 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, you may find one here:
19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20 * or you may search the http://www.gnu.org website for the version 2 license,
21 * or you may write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
25#include <algorithm>
26#include <bitset> // for bitset, __bitset<>::ref...
27#include <cassert>
28#include <cstdarg>
29#include <iostream> // for string, endl, basic_ost...
30#include <cstddef> // for size_t
31#include <map>
32
33#include <core/arraydim.h>
34#include <layer_ids.h> // for PCB_LAYER_ID
35#include <layer_range.h>
36#include <lseq.h>
37#include <macros.h> // for arrayDim
38#include <wx/debug.h> // for wxASSERT, wxASSERT_MSG
39#include <wx/string.h>
40
41#include <lset.h>
42
43
44LSET::LSET( std::initializer_list<PCB_LAYER_ID> aList ) :
45 LSET()
46{
47 for( PCB_LAYER_ID layer : aList )
48 {
49 if( layer >= 0 )
50 set( layer );
51 }
52}
53
54
55LSET::LSET( const LSEQ& aSeq ) :
56 LSET()
57{
58 for( PCB_LAYER_ID layer : aSeq )
59 {
60 if( layer >= 0 )
61 set( layer );
62 }
63}
64
65
66LSET::LSET( const LAYER_RANGE& aRange )
67{
68 for( PCB_LAYER_ID layer : aRange )
69 {
70 if( layer >= 0 )
71 set( layer );
72 }
73}
74
75
76int LSET::LayerCount( PCB_LAYER_ID aStart, PCB_LAYER_ID aEnd, int aCopperLayerCount )
77{
78 int start = aStart;
79 int end = aEnd;
80
81 // Both layers need to be copper
82 wxCHECK( IsCopperLayer( aStart ) && IsCopperLayer( aEnd ), aCopperLayerCount );
83
84 if( aStart == B_Cu )
85 std::swap( start, end );
86
87 if( aStart == aEnd )
88 return 1;
89
90 if( aStart == F_Cu )
91 {
92 if ( aEnd == B_Cu )
93 return aCopperLayerCount;
94 else
95 return ( end - start ) / 2 - 1;
96 }
97 else if ( aEnd == B_Cu )
98 {
99 // Add 1 for the B_Cu layer
100 return aCopperLayerCount - start / 2 + 1;
101 }
102
103 return ( end - start ) / 2;
104}
105
106
107int LSET::NameToLayer( wxString& aName )
108{
109 std::map<wxString, PCB_LAYER_ID> layerMap = {
110 { "F.Cu", F_Cu },
111 { "B.Cu", B_Cu },
112 { "F.Adhes", F_Adhes },
113 { "B.Adhes", B_Adhes },
114 { "F.Paste", F_Paste },
115 { "B.Paste", B_Paste },
116 { "F.SilkS", F_SilkS },
117 { "B.SilkS", B_SilkS },
118 { "F.Mask", F_Mask },
119 { "B.Mask", B_Mask },
120 { "Dwgs.User", Dwgs_User },
121 { "Cmts.User", Cmts_User },
122 { "Eco1.User", Eco1_User },
123 { "Eco2.User", Eco2_User },
124 { "Edge.Cuts", Edge_Cuts },
125 { "Margin", Margin },
126 { "F.CrtYd", F_CrtYd },
127 { "B.CrtYd", B_CrtYd },
128 { "F.Fab", F_Fab },
129 { "B.Fab", B_Fab },
130 { "Rescue", Rescue },
131 { "B.Cu", B_Cu },
132 };
133
134 if( auto it = layerMap.find( aName ); it != layerMap.end() )
135 return static_cast<int>( it->second );
136
137 if( aName.StartsWith( "User." ) )
138 {
139 long offset;
140
141 if( aName.Mid( 5 ).ToLong( &offset ) && offset > 0 )
142 return static_cast<int>( User_1 ) + ( offset - 1 ) * 2;
143 }
144
145 if( aName.StartsWith( "In" ) )
146 {
147 long offset;
148 wxString str_num = aName.Mid( 2 );
149 str_num.RemoveLast( 3 ); // Removes .Cu
150
151 if( str_num.ToLong( &offset ) && offset > 0 )
152 return static_cast<int>( In1_Cu ) + ( offset - 1 ) * 2;
153 }
154
155 return -1;
156}
157
158
160{
161 if( aLayer == aStart || aLayer == aEnd )
162 return true;
163
164 int start = std::min( aStart, aEnd );
165 int end = std::max( aStart, aEnd );
166 int layer = aLayer;
167
168 if( end == B_Cu )
169 {
170 //Reassign the end layer to the largest possible positive even number
171 end = std::numeric_limits<PCB_LAYER_ID>::max() & ~1;
172 }
173
174 return !( layer & 1 ) && ( layer >= start ) && ( layer <= end );
175}
176
177
183wxString LSET::Name( PCB_LAYER_ID aLayerId )
184{
185 wxString txt;
186
187 // using a switch to explicitly show the mapping more clearly
188 switch( aLayerId )
189 {
190 case F_Cu: txt = wxT( "F.Cu" ); break;
191 case B_Cu: txt = wxT( "B.Cu" ); break;
192
193 // Technicals
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;
202
203 // Users
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;
210
211 // Footprint
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;
216
217 // Rescue
218 case Rescue: txt = wxT( "Rescue" ); break;
219
220 default:
221
222 if( static_cast<int>( aLayerId ) & 1 )
223 {
224 int offset = ( aLayerId - Rescue ) / 2;
225 txt = wxString::Format( wxT( "User.%d" ), offset );
226 }
227 else
228 {
229 int offset = ( aLayerId - B_Cu ) / 2;
230 txt = wxString::Format( wxT( "In%d.Cu" ), offset );
231 }
232
233
234 }
235
236 return txt;
237}
238
239
241{
242 LSEQ ret;
243
244 ret.reserve( 32 );
245
246 for( auto it = copper_layers_begin(); it != copper_layers_end(); ++it )
247 ret.push_back( *it );
248
249 return ret;
250}
251
252
254{
255 LSEQ ret;
256
257 ret.reserve( 32 );
258
259 ret = Seq( {
260 F_Adhes,
261 B_Adhes,
262 F_Paste,
263 B_Paste,
264 F_SilkS,
265 B_SilkS,
266 F_Mask,
267 B_Mask,
268 Dwgs_User,
269 Cmts_User,
270 Eco1_User,
271 Eco2_User,
272 Edge_Cuts,
273 Margin,
274 F_CrtYd,
275 B_CrtYd,
276 F_Fab,
277 B_Fab
278 } );
279
280 for( auto it = non_copper_layers_begin(); it != non_copper_layers_end(); ++it )
281 {
282 if( *it >= User_1 )
283 ret.push_back( *it );
284 }
285
286 return ret;
287}
288
289
290std::string LSET::FmtBin() const
291{
292 std::string ret;
293
294 int bit_count = size();
295
296 for( int bit=0; bit<bit_count; ++bit )
297 {
298 if( bit )
299 {
300 if( !( bit % 8 ) )
301 ret += '|';
302 else if( !( bit % 4 ) )
303 ret += '_';
304 }
305
306 ret += (*this)[bit] ? '1' : '0';
307 }
308
309 // reverse of string
310 return std::string( ret.rbegin(), ret.rend() );
311}
312
313
314std::string LSET::FmtHex() const
315{
316 std::string ret;
317
318 static const char hex[] = "0123456789abcdef";
319
320 size_t nibble_count = ( size() + 3 ) / 4;
321
322 for( size_t nibble = 0; nibble < nibble_count; ++nibble )
323 {
324 unsigned int ndx = 0;
325
326 // test 4 consecutive bits and set ndx to 0-15
327 for( size_t nibble_bit = 0; nibble_bit < 4; ++nibble_bit )
328 {
329 size_t nibble_pos = nibble_bit + ( nibble * 4 );
330 // make sure it's not extra bits that don't exist in the bitset but need to in the
331 // hex format
332 if( nibble_pos >= size() )
333 break;
334
335 if( ( *this )[nibble_pos] )
336 ndx |= ( 1 << nibble_bit );
337 }
338
339 if( nibble && !( nibble % 8 ) )
340 ret += '_';
341
342 assert( ndx < arrayDim( hex ) );
343
344 ret += hex[ndx];
345 }
346
347 // reverse of string
348 return std::string( ret.rbegin(), ret.rend() );
349}
350
351
352int LSET::ParseHex( const std::string& str )
353{
354 return ParseHex( str.c_str(), str.length() );
355}
356
357
358int LSET::ParseHex( const char* aStart, int aCount )
359{
360 LSET tmp;
361
362 const char* rstart = aStart + aCount - 1;
363 const char* rend = aStart - 1;
364
365 const int bitcount = size();
366
367 int nibble_ndx = 0;
368
369 while( rstart > rend )
370 {
371 int cc = *rstart--;
372
373 if( cc == '_' )
374 continue;
375
376 int nibble;
377
378 if( cc >= '0' && cc <= '9' )
379 nibble = cc - '0';
380 else if( cc >= 'a' && cc <= 'f' )
381 nibble = cc - 'a' + 10;
382 else if( cc >= 'A' && cc <= 'F' )
383 nibble = cc - 'A' + 10;
384 else
385 break;
386
387 int bit = nibble_ndx * 4;
388
389 for( int ndx=0; bit<bitcount && ndx<4; ++bit, ++ndx )
390 if( nibble & (1<<ndx) )
391 tmp.set( bit );
392
393 if( bit >= bitcount )
394 break;
395
396 ++nibble_ndx;
397 }
398
399 int byte_count = aStart + aCount - 1 - rstart;
400
401 assert( byte_count >= 0 );
402
403 if( byte_count > 0 )
404 *this = tmp;
405
406 return byte_count;
407}
408
409
410LSEQ LSET::Seq( const LSEQ& aSequence ) const
411{
412 LSEQ ret;
413
414 for( PCB_LAYER_ID layer : aSequence )
415 {
416 if( test( layer ) )
417 ret.push_back( layer );
418 }
419
420 return ret;
421}
422
423
425{
426 LSEQ ret;
427
428 ret.reserve( size() );
429
430 for( unsigned i = 0; i < size(); ++i )
431 {
432 if( test( i ) )
433 ret.push_back( PCB_LAYER_ID( i ) );
434 }
435
436 return ret;
437}
438
439
441{
442 LSEQ base_sequence = Seq( {
443 Edge_Cuts,
444 Margin,
445 Dwgs_User,
446 Cmts_User,
447 Eco1_User,
449 } );
450
451 LSEQ top_tech_sequence = Seq( {
452 F_Fab,
453 F_SilkS,
454 F_Paste,
455 F_Adhes,
456 F_Mask,
457 F_CrtYd,
458 } );
459
460 LSEQ bottom_tech_sequence = Seq( {
461 B_CrtYd,
462 B_Mask,
463 B_Adhes,
464 B_Paste,
465 B_SilkS,
466 B_Fab,
467 } );
468
469
470 LSEQ seq = Seq( base_sequence );
471
472 for( auto it = non_copper_layers_begin(); it != non_copper_layers_end(); ++it )
473 {
474 if( *it >= User_1 )
475 seq.push_back( *it );
476 }
477
478 std::copy( top_tech_sequence.begin(), top_tech_sequence.end(), std::back_inserter( seq ) );
479
480 for( auto it = copper_layers_begin(); it != copper_layers_end(); ++it )
481 seq.push_back( *it );
482
483 std::copy( bottom_tech_sequence.begin(), bottom_tech_sequence.end(), std::back_inserter( seq ) );
484
485 if( aSelectedLayer != UNDEFINED_LAYER )
486 {
487 auto it = std::find( seq.begin(), seq.end(), aSelectedLayer );
488
489 if( it != seq.end() )
490 {
491 seq.erase( it );
492 seq.insert( seq.begin(), aSelectedLayer );
493 }
494 }
495
496 return seq;
497}
498
499
501{
502 // bottom-to-top stack-up layers
503 // Note that the bottom technical layers are flipped so that when plotting a bottom-side view,
504 // they appear in the correct sequence.
505 LSEQ bottom_tech_sequence = Seq( {
506 B_Cu,
507 B_Mask,
508 B_Paste,
509 B_SilkS,
510 B_Adhes,
511 B_CrtYd,
512 B_Fab,
513 } );
514
515 // Copper layers go here
516
517 LSEQ top_tech_sequence = Seq( {
518 F_Mask,
519 F_Paste,
520 F_SilkS,
521 F_Adhes,
522 F_CrtYd,
523 F_Fab,
524 } );
525
526 LSEQ user_sequence = Seq( {
527 Dwgs_User,
528 Cmts_User,
529 Eco1_User,
530 Eco2_User,
531 } );
532
533 // User layers go here
534
535 LSEQ base_sequence = Seq( {
536 Margin,
537 Edge_Cuts,
538 } );
539
540
541
542 LSEQ seq = Seq( bottom_tech_sequence );
543
544 std::vector<PCB_LAYER_ID> temp_layers;
545
546 // We are going to reverse the copper layers and then add them to the sequence
547 // because the plotting order is bottom-to-top
548 for( auto it = copper_layers_begin(); it != copper_layers_end(); ++it )
549 {
550 // Skip B_Cu because it is already in the sequence (if it exists)
551 if( *it != B_Cu )
552 temp_layers.push_back( *it );
553 }
554
555 for( auto it = temp_layers.rbegin(); it != temp_layers.rend(); ++it )
556 seq.push_back( *it );
557
558 std::copy( top_tech_sequence.begin(), top_tech_sequence.end(), std::back_inserter( seq ) );
559
560 std::copy( user_sequence.begin(), user_sequence.end(), std::back_inserter( seq ) );
561
562 temp_layers.clear();
563
564 for( auto it = non_copper_layers_begin(); it != non_copper_layers_end(); ++it )
565 {
566 if( *it >= User_1 )
567 temp_layers.push_back( *it );
568 }
569
570 for( auto it = temp_layers.rbegin(); it != temp_layers.rend(); ++it )
571 {
572 seq.push_back( *it );
573 }
574
575 std::copy( base_sequence.begin(), base_sequence.end(), std::back_inserter( seq ) );
576
577 return seq;
578}
579
580
581LSET& LSET::Flip( int aCopperLayersCount )
582{
583 LSET oldMask = *this;
584
585 reset();
586
587 // Mapping for Copper and Non-Copper layers
588 const std::map<PCB_LAYER_ID, PCB_LAYER_ID> flip_map =
589 {
590 {F_Cu, B_Cu},
591 {B_Cu, F_Cu},
592 {F_SilkS, B_SilkS},
593 {B_SilkS, F_SilkS},
594 {F_Adhes, B_Adhes},
595 {B_Adhes, F_Adhes},
596 {F_Mask, B_Mask},
597 {B_Mask, F_Mask},
598 {F_Paste, B_Paste},
599 {B_Paste, F_Paste},
600 {F_CrtYd, B_CrtYd},
601 {B_CrtYd, F_CrtYd},
602 {F_Fab, B_Fab},
603 {B_Fab, F_Fab}
604 };
605
606 for( const auto& pair : flip_map )
607 {
608 if( oldMask.test( pair.first ) )
609 set( pair.second );
610 }
611
612 if( aCopperLayersCount >= 4 )
613 {
614 LSET internalMask = oldMask & InternalCuMask();
615 int innerLayerCount = aCopperLayersCount - 2;
616
617 for( int ii = 1; ii <= innerLayerCount; ii++ )
618 {
619 if( internalMask.test( ( innerLayerCount - ii ) * 2 + B_Cu ) )
620 {
621 set( ii * 2 + B_Cu );
622 }
623 }
624 }
625
626 return *this;
627}
628
629
631{
632 unsigned set_count = count();
633
634 if( !set_count )
635 return UNSELECTED_LAYER;
636 else if( set_count > 1 )
637 return UNDEFINED_LAYER;
638
639 for( unsigned i=0; i < size(); ++i )
640 {
641 if( test( i ) )
642 return PCB_LAYER_ID( i );
643 }
644
645 wxASSERT( 0 ); // set_count was verified as 1 above, what did you break?
646
647 return UNDEFINED_LAYER;
648}
649
650
652{
653 static const LSET saved( { F_SilkS, F_Mask, F_Fab, F_CrtYd } );
654 return saved;
655}
656
657
659{
660 static const LSET saved( { B_SilkS, B_Mask, B_Fab, B_CrtYd } );
661 return saved;
662}
663
664
666{
667 static const LSET saved( { In1_Cu, In2_Cu, In3_Cu, In4_Cu, In5_Cu, In6_Cu,
672 return saved;
673}
674
675
676LSET LSET::AllCuMask( int aCuLayerCount )
677{
678 LSET ret;
679
680 for( PCB_LAYER_ID layer : LAYER_RANGE( F_Cu, B_Cu, aCuLayerCount ) )
681 ret.set( layer );
682
683 return ret;
684}
685
686
688{
689 static const LSET saved = LSET().set() & ~AllCuMask();
690 return saved;
691}
692
693
695{
696 static const LSET saved( { F_Cu, B_Cu } );
697 return saved;
698}
699
700
702{
703 static const LSET saved = LSET().set();
704 return saved;
705}
706
707
709{
710 static const LSET saved( { B_SilkS, B_Mask, B_Adhes, B_Paste, B_CrtYd, B_Fab } );
711 return saved;
712}
713
715{
716 static const LSET saved( { B_SilkS, B_Mask, B_Adhes, B_Paste } );
717 return saved;
718}
719
721{
722 static const LSET saved( { F_SilkS, F_Mask, F_Adhes, F_Paste, F_CrtYd, F_Fab } );
723 return saved;
724}
725
726
728{
729 static const LSET saved( { F_SilkS, F_Mask, F_Adhes, F_Paste } );
730 return saved;
731}
732
733
735{
736 static const LSET saved = BackTechMask() | FrontTechMask();
737 return saved;
738}
739
740
742{
743 static const LSET saved = BackBoardTechMask() | FrontBoardTechMask();
744 return saved;
745}
746
747
749{
750 static const LSET saved( { Dwgs_User, Cmts_User, Eco1_User, Eco2_User, Edge_Cuts, Margin } );
751
752 return saved;
753}
754
755
757{
758 static const LSET saved = AllBoardTechMask() | AllCuMask();
759 return saved;
760}
761
762
764{
765 static const LSET saved(
767
768 return saved;
769}
770
771
773{
774 static const LSET saved = FrontTechMask().set( F_Cu );
775 return saved;
776}
777
778
780{
781 static const LSET saved = BackTechMask().set( B_Cu );
782 return saved;
783}
784
786{
787 static const LSET saved = BackTechMask() | FrontTechMask() | AllCuMask();
788 return saved;
789}
790
791
793{
794 static const LSET saved = InternalCuMask();
795 return saved;
796}
797
798
800{
801 LSEQ order = CuStack();
802 LSEQ techuser = TechAndUserUIOrder();
803
804 order.insert( order.end(), techuser.begin(), techuser.end() );
805
806 return order;
807}
808
809
811{
812 // We use std::numeric_limits<int>::max() to represent B_Cu for the connectivity_rtree
813 if( aLayer == std::numeric_limits<int>::max() )
814 return B_Cu;
815
816 wxASSERT( aLayer < GAL_LAYER_ID_END );
817 return PCB_LAYER_ID( aLayer );
818}
819
820
821GAL_SET::GAL_SET( const GAL_LAYER_ID* aArray, unsigned aCount ) : GAL_SET()
822{
823 for( unsigned i = 0; i < aCount; ++i )
824 set( aArray[i] );
825}
826
827
828std::vector<GAL_LAYER_ID> GAL_SET::Seq() const
829{
830 std::vector<GAL_LAYER_ID> ret;
831
832 for( size_t i = 0; i < size(); ++i )
833 {
834 if( test( i ) )
835 ret.push_back( static_cast<GAL_LAYER_ID>( i + GAL_LAYER_ID_START ) );
836 }
837
838 return ret;
839}
840
841
843{
844 static const GAL_LAYER_ID visible[] = {
849 // LAYER_HIDDEN_TEXT, // DEPCREATED SINCE 9.0. Invisible text hidden by default
869 // LAYER_DRC_EXCLUSION, // DRC exclusions hidden by default
882 };
883
884 static const GAL_SET saved( visible, arrayDim( visible ) );
885 return saved;
886}
887
888#ifndef SWIG // Skip SWIG generators for the iterators because it requires a default constructor
889// Custom iterators for Copper and Non-Copper layers
890
892 BASE_SET::set_bits_iterator( set, index )
893{
894 m_index = ( index + 1 ) & ~1;
896}
897
899{
900 return static_cast<PCB_LAYER_ID>( m_index );
901}
902
904{
905 next_copper_layer();
906 advance_to_next_set_copper_bit();
907 return *this;
908}
909
911{
912 if( m_index == F_Cu )
913 {
914 m_index += 4;
915 }
916 else if( m_index == B_Cu )
917 {
918 m_index = m_baseSet.size();
919 return;
920 }
921 else
922 {
923 m_index += 2;
924
925 if( m_index >= m_baseSet.size() )
926 m_index = B_Cu;
927 }
928}
929
931{
932 while( m_index < m_baseSet.size() && !m_baseSet.test( m_index ) )
933 next_copper_layer();
934}
935
938{
940}
941
943{
944 return static_cast<PCB_LAYER_ID>( m_index );
945}
946
948{
949 ++m_index;
950 advance_to_next_set_non_copper_bit();
951 return *this;
952}
953
955{
956 while( m_index < m_baseSet.size() && ( m_index % 2 != 1 || !m_baseSet.test( m_index ) ) )
957 {
958 ++m_index;
959 }
960}
961
963{
964 return copper_layers_iterator( *this, 0 );
965}
966
968{
969 return copper_layers_iterator( *this, size() );
970}
971
973{
974 return non_copper_layers_iterator( *this, 0 );
975}
976
978{
979 return non_copper_layers_iterator( *this, size() );
980}
981
982
983#endif
constexpr std::size_t arrayDim(T const (&)[N]) noexcept
Returns # of elements in an array.
Definition: arraydim.h:31
BASE_SET & set()
Definition: base_set.h:135
BASE_SET & reset()
Definition: base_set.h:152
BASE_SET & set(size_t pos)
Definition: base_set.h:115
Helper for storing and iterating over GAL_LAYER_IDs.
Definition: layer_ids.h:307
GAL_SET()
Definition: layer_ids.h:313
GAL_SET & set()
Definition: layer_ids.h:323
static GAL_SET DefaultVisible()
Definition: lset.cpp:842
std::vector< GAL_LAYER_ID > Seq() const
Definition: lset.cpp:828
LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
Definition: lseq.h:47
copper_layers_iterator & operator++()
Definition: lset.cpp:903
PCB_LAYER_ID operator*() const
Definition: lset.cpp:898
void advance_to_next_set_copper_bit()
Definition: lset.cpp:930
copper_layers_iterator(const BASE_SET &set, size_t index)
Definition: lset.cpp:891
PCB_LAYER_ID operator*() const
Definition: lset.cpp:942
non_copper_layers_iterator & operator++()
Definition: lset.cpp:947
non_copper_layers_iterator(const BASE_SET &set, size_t index)
Definition: lset.cpp:936
LSET is a set of PCB_LAYER_IDs.
Definition: lset.h:36
LSET & Flip(int aCopperLayersCount=0)
Flip the layers in this set.
Definition: lset.cpp:581
static LSET ExternalCuMask()
Return a mask holding the Front and Bottom layers.
Definition: lset.cpp:694
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.
Definition: lset.cpp:358
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.
Definition: lset.cpp:159
copper_layers_iterator copper_layers_end() const
Definition: lset.cpp:967
LSEQ UIOrder() const
Returns the copper, technical and user layers in the order shown in layer widget.
Definition: lset.cpp:799
static LSET AllBoardTechMask()
Return a mask holding board technical layers (no CU layer) on both side.
Definition: lset.cpp:741
static LSET AllLayersMask()
Definition: lset.cpp:701
static LSET UserDefinedLayers()
Return a mask with all of the allowable user defined layers.
Definition: lset.cpp:763
LSEQ CuStack() const
Return a sequence of copper layers in starting from the front/top and extending to the back/bottom.
Definition: lset.cpp:240
PCB_LAYER_ID ExtractLayer() const
Find the first set PCB_LAYER_ID.
Definition: lset.cpp:630
LSEQ SeqStackupForPlotting() const
Return the sequence that is typical for a bottom-to-top stack-up.
Definition: lset.cpp:500
static LSET FrontBoardTechMask()
Return a mask holding technical layers used in a board fabrication (no CU layer) on front side.
Definition: lset.cpp:727
static LSET AllNonCuMask()
Return a mask holding all layer minus CU layers.
Definition: lset.cpp:687
static LSET FrontAssembly()
Return a complete set of all top assembly layers which is all F_SilkS and F_Mask.
Definition: lset.cpp:651
LSEQ TechAndUserUIOrder() const
Returns the technical and user layers in the order shown in layer widget.
Definition: lset.cpp:253
static LSET UserMask()
Definition: lset.cpp:748
static LSET AllTechMask()
Return a mask holding all technical layers (no CU layer) on both side.
Definition: lset.cpp:734
static LSET InternalCuMask()
Return a complete set of internal copper layers which is all Cu layers except F_Cu and B_Cu.
Definition: lset.cpp:665
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:676
static LSET SideSpecificMask()
Definition: lset.cpp:785
static LSET PhysicalLayersMask()
Return a mask holding all layers which are physically realized.
Definition: lset.cpp:756
all_set_layers_iterator end() const
Definition: lset.h:313
LSEQ Seq() const
Return a LSEQ from this LSET in ascending PCB_LAYER_ID order.
Definition: lset.cpp:424
std::string FmtHex() const
Return a hex string showing contents of this LSEQ.
Definition: lset.cpp:314
copper_layers_iterator copper_layers_begin() const
Definition: lset.cpp:962
non_copper_layers_iterator non_copper_layers_begin() const
Definition: lset.cpp:972
static int NameToLayer(wxString &aName)
Return the layer number from a layer name.
Definition: lset.cpp:107
static LSET ForbiddenFootprintLayers()
Layers which are not allowed within footprint definitions.
Definition: lset.cpp:792
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.
Definition: lset.cpp:440
non_copper_layers_iterator non_copper_layers_end() const
Definition: lset.cpp:977
std::string FmtBin() const
Return a binary string showing contents of this LSEQ.
Definition: lset.cpp:290
static LSET FrontTechMask()
Return a mask holding all technical layers (no CU layer) on front side.
Definition: lset.cpp:720
static LSET BackBoardTechMask()
Return a mask holding technical layers used in a board fabrication (no CU layer) on Back side.
Definition: lset.cpp:714
static LSET BackTechMask()
Return a mask holding all technical layers (no CU layer) on back side.
Definition: lset.cpp:708
static LSET BackAssembly()
Return a complete set of all bottom assembly layers which is all B_SilkS and B_Mask.
Definition: lset.cpp:658
static LSET FrontMask()
Return a mask holding all technical layers and the external CU layer on front side.
Definition: lset.cpp:772
static LSET BackMask()
Return a mask holding all technical layers and the external CU layer on back side.
Definition: lset.cpp:779
static wxString Name(PCB_LAYER_ID aLayerId)
Return the fixed name association with aLayerId.
Definition: lset.cpp:183
LSET()
Create an empty (cleared) set.
Definition: lset.h:42
static int LayerCount(PCB_LAYER_ID aStart, PCB_LAYER_ID aEnd, int aCopperLayerCount)
Return the number of layers between aStart and aEnd, inclusive.
Definition: lset.cpp:76
bool IsCopperLayer(int aLayerId)
Tests whether a layer is a copper layer.
Definition: layer_ids.h:531
GAL_LAYER_ID
GAL layers are "virtual" layers, i.e.
Definition: layer_ids.h:191
@ LAYER_GRID
Definition: layer_ids.h:206
@ GAL_LAYER_ID_START
Definition: layer_ids.h:192
@ LAYER_LOCKED_ITEM_SHADOW
shadow layer for locked items
Definition: layer_ids.h:240
@ LAYER_VIA_HOLEWALLS
Definition: layer_ids.h:235
@ LAYER_GRID_AXES
Definition: layer_ids.h:207
@ LAYER_CONFLICTS_SHADOW
shadow layer for items flagged conficting
Definition: layer_ids.h:242
@ LAYER_FOOTPRINTS_FR
show footprints on front
Definition: layer_ids.h:209
@ LAYER_DRC_SHAPE1
Custom shape for DRC marker.
Definition: layer_ids.h:245
@ LAYER_NON_PLATEDHOLES
handle color for not plated holes (holes, not pads)
Definition: layer_ids.h:198
@ LAYER_DRAWINGSHEET
drawingsheet frame and titleblock
Definition: layer_ids.h:218
@ LAYER_DRAW_BITMAPS
to handle and draw images bitmaps
Definition: layer_ids.h:224
@ LAYER_FP_REFERENCES
show footprints references (when texts are visible)
Definition: layer_ids.h:212
@ LAYER_PCB_BACKGROUND
PCB background color.
Definition: layer_ids.h:221
@ LAYER_ZONES
Control for copper zone opacity/visibility (color ignored)
Definition: layer_ids.h:232
@ LAYER_SHAPES
Copper graphic shape opacity/visibility (color ignored)
Definition: layer_ids.h:243
@ LAYER_PADS
Meta control for all pads opacity/visibility (color ignored)
Definition: layer_ids.h:231
@ LAYER_DRC_WARNING
layer for drc markers with SEVERITY_WARNING
Definition: layer_ids.h:236
@ LAYER_PAD_PLATEDHOLES
to draw pad holes (plated)
Definition: layer_ids.h:215
@ GAL_LAYER_ID_END
Definition: layer_ids.h:268
@ LAYER_GP_OVERLAY
general purpose overlay
Definition: layer_ids.h:219
@ LAYER_TRACKS
Definition: layer_ids.h:213
@ LAYER_CURSOR
PCB cursor.
Definition: layer_ids.h:222
@ LAYER_AUX_ITEMS
Auxiliary items (guides, rule, etc)
Definition: layer_ids.h:223
@ LAYER_RATSNEST
Definition: layer_ids.h:205
@ LAYER_DRC_SHAPE2
Custom shape for DRC marker.
Definition: layer_ids.h:246
@ LAYER_FP_TEXT
Definition: layer_ids.h:199
@ LAYER_FOOTPRINTS_BK
show footprints on back
Definition: layer_ids.h:210
@ LAYER_ANCHOR
anchor of items having an anchor point (texts, footprints)
Definition: layer_ids.h:202
@ LAYER_VIA_HOLES
to draw via holes (pad holes do not use this layer)
Definition: layer_ids.h:216
@ LAYER_FP_VALUES
show footprints values (when texts are visible)
Definition: layer_ids.h:211
@ LAYER_VIA_MICROVIA
to draw micro vias
Definition: layer_ids.h:195
@ LAYER_SELECT_OVERLAY
currently selected items overlay
Definition: layer_ids.h:220
@ LAYER_VIA_THROUGH
to draw usual through hole vias
Definition: layer_ids.h:197
@ LAYER_DRC_ERROR
layer for drc markers with SEVERITY_ERROR
Definition: layer_ids.h:217
@ LAYER_VIAS
Meta control for all vias opacity/visibility.
Definition: layer_ids.h:194
@ LAYER_VIA_BBLIND
to draw blind/buried vias
Definition: layer_ids.h:196
@ LAYER_PAD_HOLEWALLS
Definition: layer_ids.h:234
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:60
@ In22_Cu
Definition: layer_ids.h:87
@ In11_Cu
Definition: layer_ids.h:76
@ In29_Cu
Definition: layer_ids.h:94
@ In30_Cu
Definition: layer_ids.h:95
@ User_8
Definition: layer_ids.h:131
@ F_CrtYd
Definition: layer_ids.h:116
@ In17_Cu
Definition: layer_ids.h:82
@ B_Adhes
Definition: layer_ids.h:103
@ Edge_Cuts
Definition: layer_ids.h:112
@ Dwgs_User
Definition: layer_ids.h:107
@ F_Paste
Definition: layer_ids.h:104
@ In9_Cu
Definition: layer_ids.h:74
@ Cmts_User
Definition: layer_ids.h:108
@ User_6
Definition: layer_ids.h:129
@ User_7
Definition: layer_ids.h:130
@ In19_Cu
Definition: layer_ids.h:84
@ In7_Cu
Definition: layer_ids.h:72
@ In28_Cu
Definition: layer_ids.h:93
@ In26_Cu
Definition: layer_ids.h:91
@ F_Adhes
Definition: layer_ids.h:102
@ B_Mask
Definition: layer_ids.h:98
@ B_Cu
Definition: layer_ids.h:65
@ User_5
Definition: layer_ids.h:128
@ Eco1_User
Definition: layer_ids.h:109
@ F_Mask
Definition: layer_ids.h:97
@ In21_Cu
Definition: layer_ids.h:86
@ In23_Cu
Definition: layer_ids.h:88
@ B_Paste
Definition: layer_ids.h:105
@ In15_Cu
Definition: layer_ids.h:80
@ In2_Cu
Definition: layer_ids.h:67
@ User_9
Definition: layer_ids.h:132
@ UNSELECTED_LAYER
Definition: layer_ids.h:62
@ F_Fab
Definition: layer_ids.h:119
@ In10_Cu
Definition: layer_ids.h:75
@ Margin
Definition: layer_ids.h:113
@ F_SilkS
Definition: layer_ids.h:100
@ In4_Cu
Definition: layer_ids.h:69
@ B_CrtYd
Definition: layer_ids.h:115
@ UNDEFINED_LAYER
Definition: layer_ids.h:61
@ Eco2_User
Definition: layer_ids.h:110
@ In16_Cu
Definition: layer_ids.h:81
@ In24_Cu
Definition: layer_ids.h:89
@ In1_Cu
Definition: layer_ids.h:66
@ Rescue
Definition: layer_ids.h:121
@ User_3
Definition: layer_ids.h:126
@ User_1
Definition: layer_ids.h:124
@ B_SilkS
Definition: layer_ids.h:101
@ In13_Cu
Definition: layer_ids.h:78
@ User_4
Definition: layer_ids.h:127
@ In8_Cu
Definition: layer_ids.h:73
@ In14_Cu
Definition: layer_ids.h:79
@ User_2
Definition: layer_ids.h:125
@ In12_Cu
Definition: layer_ids.h:77
@ In27_Cu
Definition: layer_ids.h:92
@ In6_Cu
Definition: layer_ids.h:71
@ In5_Cu
Definition: layer_ids.h:70
@ In3_Cu
Definition: layer_ids.h:68
@ In20_Cu
Definition: layer_ids.h:85
@ F_Cu
Definition: layer_ids.h:64
@ In18_Cu
Definition: layer_ids.h:83
@ In25_Cu
Definition: layer_ids.h:90
@ B_Fab
Definition: layer_ids.h:118
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:810
This file contains miscellaneous commonly used macros and functions.