KiCad PCB EDA Suite
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 <dick@softplc.com>
5  * Copyright (C) 2014-2017 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 
26 #include <stdarg.h>
27 #include <assert.h>
28 
30 #include <class_board.h>
31 
32 
33 LSET::LSET( const PCB_LAYER_ID* aArray, unsigned aCount ) :
34  BASE_SET()
35 {
36  for( unsigned i=0; i<aCount; ++i )
37  set( aArray[i] );
38 }
39 
40 
41 LSET::LSET( unsigned aIdCount, int aFirst, ... ) :
42  BASE_SET()
43 {
44  // The constructor, without the mandatory aFirst argument, could have been confused
45  // by the compiler with the LSET( PCB_LAYER_ID ). With aFirst, that ambiguity is not
46  // present. Therefore aIdCount must always be >=1.
47  wxASSERT_MSG( aIdCount > 0, wxT( "aIdCount must be >= 1" ) );
48 
49  set( aFirst );
50 
51  if( --aIdCount )
52  {
53  va_list ap;
54 
55  va_start( ap, aFirst );
56 
57  for( unsigned i=0; i<aIdCount; ++i )
58  {
59  PCB_LAYER_ID id = (PCB_LAYER_ID) va_arg( ap, int );
60 
61  // printf( "%s: id:%d PCB_LAYER_ID_COUNT:%d\n", __func__, id, PCB_LAYER_ID_COUNT );
62 
63  assert( unsigned( id ) < PCB_LAYER_ID_COUNT );
64 
65  set( id );
66  }
67 
68  va_end( ap );
69  }
70 }
71 
72 
73 const wxChar* LSET::Name( PCB_LAYER_ID aLayerId )
74 {
75  const wxChar* txt;
76 
77  // using a switch to explicitly show the mapping more clearly
78  switch( aLayerId )
79  {
80  case F_Cu: txt = wxT( "F.Cu" ); break;
81  case In1_Cu: txt = wxT( "In1.Cu" ); break;
82  case In2_Cu: txt = wxT( "In2.Cu" ); break;
83  case In3_Cu: txt = wxT( "In3.Cu" ); break;
84  case In4_Cu: txt = wxT( "In4.Cu" ); break;
85  case In5_Cu: txt = wxT( "In5.Cu" ); break;
86  case In6_Cu: txt = wxT( "In6.Cu" ); break;
87  case In7_Cu: txt = wxT( "In7.Cu" ); break;
88  case In8_Cu: txt = wxT( "In8.Cu" ); break;
89  case In9_Cu: txt = wxT( "In9.Cu" ); break;
90  case In10_Cu: txt = wxT( "In10.Cu" ); break;
91  case In11_Cu: txt = wxT( "In11.Cu" ); break;
92  case In12_Cu: txt = wxT( "In12.Cu" ); break;
93  case In13_Cu: txt = wxT( "In13.Cu" ); break;
94  case In14_Cu: txt = wxT( "In14.Cu" ); break;
95  case In15_Cu: txt = wxT( "In15.Cu" ); break;
96  case In16_Cu: txt = wxT( "In16.Cu" ); break;
97  case In17_Cu: txt = wxT( "In17.Cu" ); break;
98  case In18_Cu: txt = wxT( "In18.Cu" ); break;
99  case In19_Cu: txt = wxT( "In19.Cu" ); break;
100  case In20_Cu: txt = wxT( "In20.Cu" ); break;
101  case In21_Cu: txt = wxT( "In21.Cu" ); break;
102  case In22_Cu: txt = wxT( "In22.Cu" ); break;
103  case In23_Cu: txt = wxT( "In23.Cu" ); break;
104  case In24_Cu: txt = wxT( "In24.Cu" ); break;
105  case In25_Cu: txt = wxT( "In25.Cu" ); break;
106  case In26_Cu: txt = wxT( "In26.Cu" ); break;
107  case In27_Cu: txt = wxT( "In27.Cu" ); break;
108  case In28_Cu: txt = wxT( "In28.Cu" ); break;
109  case In29_Cu: txt = wxT( "In29.Cu" ); break;
110  case In30_Cu: txt = wxT( "In30.Cu" ); break;
111  case B_Cu: txt = wxT( "B.Cu" ); break;
112 
113  // Technicals
114  case B_Adhes: txt = wxT( "B.Adhes" ); break;
115  case F_Adhes: txt = wxT( "F.Adhes" ); break;
116  case B_Paste: txt = wxT( "B.Paste" ); break;
117  case F_Paste: txt = wxT( "F.Paste" ); break;
118  case B_SilkS: txt = wxT( "B.SilkS" ); break;
119  case F_SilkS: txt = wxT( "F.SilkS" ); break;
120  case B_Mask: txt = wxT( "B.Mask" ); break;
121  case F_Mask: txt = wxT( "F.Mask" ); break;
122 
123  // Users
124  case Dwgs_User: txt = wxT( "Dwgs.User" ); break;
125  case Cmts_User: txt = wxT( "Cmts.User" ); break;
126  case Eco1_User: txt = wxT( "Eco1.User" ); break;
127  case Eco2_User: txt = wxT( "Eco2.User" ); break;
128  case Edge_Cuts: txt = wxT( "Edge.Cuts" ); break;
129  case Margin: txt = wxT( "Margin" ); break;
130 
131  // Footprint
132  case F_CrtYd: txt = wxT( "F.CrtYd" ); break;
133  case B_CrtYd: txt = wxT( "B.CrtYd" ); break;
134  case F_Fab: txt = wxT( "F.Fab" ); break;
135  case B_Fab: txt = wxT( "B.Fab" ); break;
136 
137  default:
138  std::cout << aLayerId << std::endl;
139  wxASSERT_MSG( 0, wxT( "aLayerId out of range" ) );
140  txt = wxT( "BAD INDEX!" ); break;
141  }
142 
143  return txt;
144 }
145 
146 
148 {
149  // desired sequence
150  static const PCB_LAYER_ID sequence[] = {
151  F_Cu,
152  In1_Cu,
153  In2_Cu,
154  In3_Cu,
155  In4_Cu,
156  In5_Cu,
157  In6_Cu,
158  In7_Cu,
159  In8_Cu,
160  In9_Cu,
161  In10_Cu,
162  In11_Cu,
163  In12_Cu,
164  In13_Cu,
165  In14_Cu,
166  In15_Cu,
167  In16_Cu,
168  In17_Cu,
169  In18_Cu,
170  In19_Cu,
171  In20_Cu,
172  In21_Cu,
173  In22_Cu,
174  In23_Cu,
175  In24_Cu,
176  In25_Cu,
177  In26_Cu,
178  In27_Cu,
179  In28_Cu,
180  In29_Cu,
181  In30_Cu,
182  B_Cu, // 31
183  };
184 
185  return Seq( sequence, DIM( sequence ) );
186 }
187 
188 
189 LSEQ LSET::Technicals( LSET aSetToOmit ) const
190 {
191  // desired sequence
192  static const PCB_LAYER_ID sequence[] = {
193  F_Adhes,
194  B_Adhes,
195  F_Paste,
196  B_Paste,
197  F_SilkS,
198  B_SilkS,
199  F_Mask,
200  B_Mask,
201  F_CrtYd,
202  B_CrtYd,
203  F_Fab,
204  B_Fab,
205  };
206 
207  LSET subset = ~aSetToOmit & *this;
208 
209  return subset.Seq( sequence, DIM( sequence ) );
210 }
211 
212 
214 {
215  // desired
216  static const PCB_LAYER_ID sequence[] = {
217  Dwgs_User,
218  Cmts_User,
219  Eco1_User,
220  Eco2_User,
221  Edge_Cuts,
222  Margin,
223  };
224 
225  return Seq( sequence, DIM( sequence ) );
226 }
227 
228 
230 {
231  static const PCB_LAYER_ID sequence[] = {
232  F_Adhes,
233  B_Adhes,
234  F_Paste,
235  B_Paste,
236  F_SilkS,
237  B_SilkS,
238  F_Mask,
239  B_Mask,
240  Dwgs_User,
241  Cmts_User,
242  Eco1_User,
243  Eco2_User,
244  Edge_Cuts,
245  Margin,
246  F_CrtYd,
247  B_CrtYd,
248  F_Fab,
249  B_Fab,
250  };
251 
252  return Seq( sequence, DIM( sequence ) );
253 }
254 
255 
256 std::string LSET::FmtBin() const
257 {
258  std::string ret;
259 
260  int bit_count = size();
261 
262  for( int bit=0; bit<bit_count; ++bit )
263  {
264  if( bit )
265  {
266  if( !( bit % 8 ) )
267  ret += '|';
268  else if( !( bit % 4 ) )
269  ret += '_';
270  }
271 
272  ret += (*this)[bit] ? '1' : '0';
273  }
274 
275  // reverse of string
276  return std::string( ret.rbegin(), ret.rend() );
277 }
278 
279 
280 std::string LSET::FmtHex() const
281 {
282  std::string ret;
283 
284  static const char hex[] = "0123456789abcdef";
285 
286  int nibble_count = ( size() + 3 ) / 4;
287 
288  for( int nibble=0; nibble<nibble_count; ++nibble )
289  {
290  unsigned ndx = 0;
291 
292  // test 4 consecutive bits and set ndx to 0-15:
293  for( int nibble_bit=0; nibble_bit<4; ++nibble_bit )
294  {
295  if( (*this)[nibble_bit + nibble*4] )
296  ndx |= (1 << nibble_bit);
297  }
298 
299  if( nibble && !( nibble % 8 ) )
300  ret += '_';
301 
302  assert( ndx < DIM( hex ) );
303 
304  ret += hex[ndx];
305  }
306 
307  // reverse of string
308  return std::string( ret.rbegin(), ret.rend() );
309 }
310 
311 
312 int LSET::ParseHex( const char* aStart, int aCount )
313 {
314  LSET tmp;
315 
316  const char* rstart = aStart + aCount - 1;
317  const char* rend = aStart - 1;
318 
319  const int bitcount = size();
320 
321  int nibble_ndx = 0;
322 
323  while( rstart > rend )
324  {
325  int cc = *rstart--;
326 
327  if( cc == '_' )
328  continue;
329 
330  int nibble;
331 
332  if( cc >= '0' && cc <= '9' )
333  nibble = cc - '0';
334  else if( cc >= 'a' && cc <= 'f' )
335  nibble = cc - 'a' + 10;
336  else if( cc >= 'A' && cc <= 'F' )
337  nibble = cc - 'A' + 10;
338  else
339  break;
340 
341  int bit = nibble_ndx * 4;
342 
343  for( int ndx=0; bit<bitcount && ndx<4; ++bit, ++ndx )
344  if( nibble & (1<<ndx) )
345  tmp.set( bit );
346 
347  if( bit >= bitcount )
348  break;
349 
350  ++nibble_ndx;
351  }
352 
353  int byte_count = aStart + aCount - 1 - rstart;
354 
355  assert( byte_count >= 0 );
356 
357  if( byte_count > 0 )
358  *this = tmp;
359 
360  return byte_count;
361 }
362 
363 
364 LSEQ LSET::Seq( const PCB_LAYER_ID* aWishListSequence, unsigned aCount ) const
365 {
366  LSEQ ret;
367 
368 #if defined(DEBUG) && 0
369  LSET dup_detector;
370 
371  for( unsigned i=0; i<aCount; ++i )
372  {
373  PCB_LAYER_ID id = aWishListSequence[i];
374 
375  if( test( id ) )
376  {
377  wxASSERT_MSG( !dup_detector[id], wxT( "Duplicate in aWishListSequence" ) );
378  dup_detector[id] = true;
379 
380  ret.push_back( id );
381  }
382  }
383 #else
384 
385  for( unsigned i=0; i<aCount; ++i )
386  {
387  PCB_LAYER_ID id = aWishListSequence[i];
388 
389  if( test( id ) )
390  ret.push_back( id );
391  }
392 #endif
393 
394  return ret;
395 }
396 
397 
399 {
400  LSEQ ret;
401 
402  for( unsigned i=0; i<size(); ++i )
403  {
404  if( test(i) )
405  ret.push_back( PCB_LAYER_ID( i ) );
406  }
407 
408  return ret;
409 }
410 
411 
413 {
414  // bottom-to-top stack-up layers
415  static const PCB_LAYER_ID sequence[] = {
416  B_Fab,
417  B_CrtYd,
418  B_Adhes,
419  B_SilkS,
420  B_Paste,
421  B_Mask,
422  B_Cu,
423  In30_Cu,
424  In29_Cu,
425  In28_Cu,
426  In27_Cu,
427  In26_Cu,
428  In25_Cu,
429  In24_Cu,
430  In23_Cu,
431  In22_Cu,
432  In21_Cu,
433  In20_Cu,
434  In19_Cu,
435  In18_Cu,
436  In17_Cu,
437  In16_Cu,
438  In15_Cu,
439  In14_Cu,
440  In13_Cu,
441  In12_Cu,
442  In11_Cu,
443  In10_Cu,
444  In9_Cu,
445  In8_Cu,
446  In7_Cu,
447  In6_Cu,
448  In5_Cu,
449  In4_Cu,
450  In3_Cu,
451  In2_Cu,
452  In1_Cu,
453  F_Cu,
454  F_Mask,
455  F_Paste,
456  F_SilkS,
457  F_Adhes,
458  F_CrtYd,
459  F_Fab,
460  Dwgs_User,
461  Cmts_User,
462  Eco1_User,
463  Eco2_User,
464  Margin,
465  Edge_Cuts,
466  };
467 
468  return Seq( sequence, DIM( sequence ) );
469 }
470 
471 
472 PCB_LAYER_ID FlipLayer( PCB_LAYER_ID aLayerId, int aCopperLayersCount )
473 {
474  switch( aLayerId )
475  {
476  case B_Cu: return F_Cu;
477  case F_Cu: return B_Cu;
478 
479  case B_SilkS: return F_SilkS;
480  case F_SilkS: return B_SilkS;
481 
482  case B_Adhes: return F_Adhes;
483  case F_Adhes: return B_Adhes;
484 
485  case B_Mask: return F_Mask;
486  case F_Mask: return B_Mask;
487 
488  case B_Paste: return F_Paste;
489  case F_Paste: return B_Paste;
490 
491  case B_CrtYd: return F_CrtYd;
492  case F_CrtYd: return B_CrtYd;
493 
494  case B_Fab: return F_Fab;
495  case F_Fab: return B_Fab;
496 
497  default: // change internal layer if aCopperLayersCount is >= 4
498  if( IsCopperLayer( aLayerId ) && aCopperLayersCount >= 4 )
499  {
500  // internal copper layers count is aCopperLayersCount-2
501  PCB_LAYER_ID fliplayer = PCB_LAYER_ID(aCopperLayersCount - 2 - ( aLayerId - In1_Cu ) );
502  // Ensure fliplayer has a value which does not crash pcbnew:
503  if( fliplayer < F_Cu )
504  fliplayer = F_Cu;
505 
506  if( fliplayer > B_Cu )
507  fliplayer = B_Cu;
508 
509  return fliplayer;
510  }
511 
512  // No change for the other layers
513  return aLayerId;
514  }
515 }
516 
517 
518 LSET FlipLayerMask( LSET aMask, int aCopperLayersCount )
519 {
520  // layers on physical outside of a board:
521  const static LSET and_mask( 16, // !! update count
522  B_Cu, F_Cu,
523  B_SilkS, F_SilkS,
524  B_Adhes, F_Adhes,
525  B_Mask, F_Mask,
526  B_Paste, F_Paste,
527  B_Adhes, F_Adhes,
528  B_CrtYd, F_CrtYd,
529  B_Fab, F_Fab
530  );
531 
532  LSET newMask = aMask & ~and_mask;
533 
534  if( aMask[B_Cu] )
535  newMask.set( F_Cu );
536 
537  if( aMask[F_Cu] )
538  newMask.set( B_Cu );
539 
540  if( aMask[B_SilkS] )
541  newMask.set( F_SilkS );
542 
543  if( aMask[F_SilkS] )
544  newMask.set( B_SilkS );
545 
546  if( aMask[B_Adhes] )
547  newMask.set( F_Adhes );
548 
549  if( aMask[F_Adhes] )
550  newMask.set( B_Adhes );
551 
552  if( aMask[B_Mask] )
553  newMask.set( F_Mask );
554 
555  if( aMask[F_Mask] )
556  newMask.set( B_Mask );
557 
558  if( aMask[B_Paste] )
559  newMask.set( F_Paste );
560 
561  if( aMask[F_Paste] )
562  newMask.set( B_Paste );
563 
564  if( aMask[B_Adhes] )
565  newMask.set( F_Adhes );
566 
567  if( aMask[F_Adhes] )
568  newMask.set( B_Adhes );
569 
570  if( aMask[B_CrtYd] )
571  newMask.set( F_CrtYd );
572 
573  if( aMask[F_CrtYd] )
574  newMask.set( B_CrtYd );
575 
576  if( aMask[B_Fab] )
577  newMask.set( F_Fab );
578 
579  if( aMask[F_Fab] )
580  newMask.set( B_Fab );
581 
582  if( aCopperLayersCount >= 4 ) // Internal layers exist
583  {
584  LSET internalMask = aMask & LSET::InternalCuMask();
585 
586  if( internalMask != LSET::InternalCuMask() )
587  {
588  // the mask does not include all internal layers. Therefore
589  // the flipped mask for internal copper layers must be built
590  int innerLayerCnt = aCopperLayersCount -2;
591 
592  // the flipped mask is the innerLayerCnt bits rewritten in reverse order
593  // ( bits innerLayerCnt to 1 rewritten in bits 1 to innerLayerCnt )
594  for( int ii = 0; ii < innerLayerCnt; ii++ )
595  {
596  if( internalMask[innerLayerCnt - ii] )
597  {
598  newMask.set( ii + In1_Cu );
599  }
600  else
601  {
602  newMask.reset( ii + In1_Cu );
603  }
604  }
605  }
606  }
607 
608  return newMask;
609 }
610 
611 
613 {
614  unsigned set_count = count();
615 
616  if( !set_count )
617  return UNSELECTED_LAYER;
618  else if( set_count > 1 )
619  return UNDEFINED_LAYER;
620 
621  for( unsigned i=0; i < size(); ++i )
622  {
623  if( test( i ) )
624  return PCB_LAYER_ID( i );
625  }
626 
627  wxASSERT( 0 ); // set_count was verified as 1 above, what did you break?
628 
629  return UNDEFINED_LAYER;
630 }
631 
632 
634 {
635  static const PCB_LAYER_ID cu_internals[] = {
636  In1_Cu,
637  In2_Cu,
638  In3_Cu,
639  In4_Cu,
640  In5_Cu,
641  In6_Cu,
642  In7_Cu,
643  In8_Cu,
644  In9_Cu,
645  In10_Cu,
646  In11_Cu,
647  In12_Cu,
648  In13_Cu,
649  In14_Cu,
650  In15_Cu,
651  In16_Cu,
652  In17_Cu,
653  In18_Cu,
654  In19_Cu,
655  In20_Cu,
656  In21_Cu,
657  In22_Cu,
658  In23_Cu,
659  In24_Cu,
660  In25_Cu,
661  In26_Cu,
662  In27_Cu,
663  In28_Cu,
664  In29_Cu,
665  In30_Cu,
666  };
667 
668  static const LSET saved( cu_internals, DIM( cu_internals ) );
669  return saved;
670 }
671 
672 
673 LSET LSET::AllCuMask( int aCuLayerCount )
674 {
675  // retain all in static as the full set, which is a common case.
676  static const LSET all = InternalCuMask().set( F_Cu ).set( B_Cu );
677 
678  if( aCuLayerCount == MAX_CU_LAYERS )
679  return all;
680 
681  // subtract out some Cu layers not wanted in the mask.
682  LSET ret = all;
683  int clear_count = MAX_CU_LAYERS - aCuLayerCount;
684 
685  clear_count = Clamp( 0, clear_count, MAX_CU_LAYERS - 2 );
686 
687  for( LAYER_NUM elem=In30_Cu; clear_count; --elem, --clear_count )
688  {
689  ret.set( elem, false );
690  }
691 
692  return ret;
693 }
694 
695 
697 {
698  static const LSET saved = LSET().set() & ~AllCuMask();
699  return saved;
700 }
701 
702 
704 {
705  static const LSET saved( 2, F_Cu, B_Cu );
706  return saved;
707 }
708 
709 
711 {
712  static const LSET saved = LSET().set();
713  return saved;
714 }
715 
716 
718 {
719  static const LSET saved( 6, B_SilkS, B_Mask, B_Adhes, B_Paste, B_CrtYd, B_Fab );
720  return saved;
721 }
722 
724 {
725  static const LSET saved( 4, B_SilkS, B_Mask, B_Adhes, B_Paste );
726  return saved;
727 }
728 
730 {
731  static const LSET saved( 6, F_SilkS, F_Mask, F_Adhes, F_Paste, F_CrtYd, F_Fab );
732  return saved;
733 }
734 
735 
737 {
738  static const LSET saved( 4, F_SilkS, F_Mask, F_Adhes, F_Paste );
739  return saved;
740 }
741 
742 
744 {
745  static const LSET saved = BackTechMask() | FrontTechMask();
746  return saved;
747 }
748 
749 
751 {
752  static const LSET saved = BackBoardTechMask() | FrontBoardTechMask();
753  return saved;
754 }
755 
756 
758 {
759  static const LSET saved( 6,
760  Dwgs_User,
761  Cmts_User,
762  Eco1_User,
763  Eco2_User,
764  Edge_Cuts,
765  Margin
766  );
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 
785 
787 {
788  LSEQ order = CuStack();
789  LSEQ techuser = TechAndUserUIOrder();
790  order.insert( order.end(), techuser.begin(), techuser.end() );
791 
792  return order;
793 }
794 
795 
797 {
798  wxASSERT( unsigned( aLayer ) < GAL_LAYER_ID_END );
799  return PCB_LAYER_ID( aLayer );
800 }
801 
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Function AllCuMask returns a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:673
static LSET FrontBoardTechMask()
Function FrontBoardTechMask returns a mask holding technical layers used in a board fabrication (no C...
Definition: lset.cpp:736
#define DIM(x)
of elements in an array
Definition: macros.h:98
LSET FlipLayerMask(LSET aMask, int aCopperLayersCount)
Calculate the mask layer when flipping a footprint BACK and FRONT copper layers, mask, paste, solder layers are swapped internal layers are flipped only if the copper layers count is known.
Definition: lset.cpp:518
std::string FmtHex() const
Function FmtHex returns a hex string showing contents of this LSEQ.
Definition: lset.cpp:280
const T & Clamp(const T &lower, const T &value, const T &upper)
Function Clamp limits value within the range lower <= value <= upper.
Definition: macros.h:127
static LSET BackTechMask()
Function BackTechMask returns a mask holding all technical layers (no CU layer) on back side...
Definition: lset.cpp:717
LSEQ TechAndUserUIOrder() const
Returns the technical and user layers in the order shown in layer widget.
Definition: lset.cpp:229
LSEQ CuStack() const
Function CuStack returns a sequence of copper layers in starting from the front/top and extending to ...
Definition: lset.cpp:147
Class BOARD to handle a board.
PCB_LAYER_ID FlipLayer(PCB_LAYER_ID aLayerId, int aCopperLayersCount)
Function FlippedLayerNumber.
Definition: lset.cpp:472
static LSET AllNonCuMask()
Function AllNonCuMask returns a mask holding all layer minus CU layers.
Definition: lset.cpp:696
static LSET FrontTechMask()
Function FrontTechMask returns a mask holding all technical layers (no CU layer) on front side...
Definition: lset.cpp:729
Add new GAL layers here.
static LSET AllTechMask()
Function AllTechMask returns a mask holding all technical layers (no CU layer) on both side...
Definition: lset.cpp:743
static LSET FrontMask()
Function FrontMask returns a mask holding all technical layers and the external CU layer on front sid...
Definition: lset.cpp:772
LSEQ SeqStackupBottom2Top() const
Function SeqStackBottom2Top returns the sequence that is typical for a bottom-to-top stack-up...
Definition: lset.cpp:412
PCB_LAYER_ID ExtractLayer() const
Find the first set PCB_LAYER_ID.
Definition: lset.cpp:612
LSEQ Seq(const PCB_LAYER_ID *aWishListSequence, unsigned aCount) const
Function Seq returns an LSEQ from the union of this LSET and a desired sequence.
Definition: lset.cpp:364
LSEQ Seq() const
Function Seq returns a LSEQ from this LSET in ascending PCB_LAYER_ID order.
Definition: lset.cpp:398
std::bitset< PCB_LAYER_ID_COUNT > BASE_SET
PCB_LAYER_ID
A quick note on layer IDs:
Class LSET is a set of PCB_LAYER_IDs.
static const wxChar * Name(PCB_LAYER_ID aLayerId)
Function Name returns the fixed name association with aLayerId.
Definition: lset.cpp:73
static LSET InternalCuMask()
Function InternalCuMask() returns a complete set of internal copper layers, which is all Cu layers ex...
Definition: lset.cpp:633
static LSET ExternalCuMask()
Function ExternalCuMask returns a mask holding the Front and Bottom layers.
Definition: lset.cpp:703
static LSET AllLayersMask()
Definition: lset.cpp:710
LSEQ Technicals(LSET aSubToOmit=LSET()) const
Function Technicals returns a sequence of technical layers.
Definition: lset.cpp:189
Class LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
int LAYER_NUM
Type LAYER_NUM can be replaced with int and removed.
Board layer functions and definitions.
LSET()
Constructor LSET() creates an empty (cleared) set.
static LSET BackBoardTechMask()
Function BackBoardTechMask returns a mask holding technical layers used in a board fabrication (no CU...
Definition: lset.cpp:723
size_t i
Definition: json11.cpp:597
std::string FmtBin() const
Function FmtBin returns a binary string showing contents of this LSEQ.
Definition: lset.cpp:256
static long bit[8][9]
Definition: solve.cpp:826
static LSET BackMask()
Function BackMask returns a mask holding all technical layers and the external CU layer on back side...
Definition: lset.cpp:779
bool IsCopperLayer(LAYER_NUM aLayerId)
Function IsCopperLayer tests whether a layer is a copper layer.
static LSET AllBoardTechMask()
Function AllTechMask returns a mask holding board technical layers (no CU layer) on both side...
Definition: lset.cpp:750
LSEQ Users() const
*_User layers.
Definition: lset.cpp:213
static LSET UserMask()
Definition: lset.cpp:757
int ParseHex(const char *aStart, int aCount)
Function ParseHex understands the output of FmtHex() and replaces this set&#39;s values with those given ...
Definition: lset.cpp:312
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:796
LSEQ UIOrder() const
Definition: lset.cpp:786