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  B_Adhes,
194  F_Adhes,
195  B_Paste,
196  F_Paste,
197  B_SilkS,
198  F_SilkS,
199  B_Mask,
200  F_Mask,
201  B_CrtYd,
202  F_CrtYd,
203  B_Fab,
204  F_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 
229 std::string LSET::FmtBin() const
230 {
231  std::string ret;
232 
233  int bit_count = size();
234 
235  for( int bit=0; bit<bit_count; ++bit )
236  {
237  if( bit )
238  {
239  if( !( bit % 8 ) )
240  ret += '|';
241  else if( !( bit % 4 ) )
242  ret += '_';
243  }
244 
245  ret += (*this)[bit] ? '1' : '0';
246  }
247 
248  // reverse of string
249  return std::string( ret.rbegin(), ret.rend() );
250 }
251 
252 
253 std::string LSET::FmtHex() const
254 {
255  std::string ret;
256 
257  static const char hex[] = "0123456789abcdef";
258 
259  int nibble_count = ( size() + 3 ) / 4;
260 
261  for( int nibble=0; nibble<nibble_count; ++nibble )
262  {
263  unsigned ndx = 0;
264 
265  // test 4 consecutive bits and set ndx to 0-15:
266  for( int nibble_bit=0; nibble_bit<4; ++nibble_bit )
267  {
268  if( (*this)[nibble_bit + nibble*4] )
269  ndx |= (1 << nibble_bit);
270  }
271 
272  if( nibble && !( nibble % 8 ) )
273  ret += '_';
274 
275  assert( ndx < DIM( hex ) );
276 
277  ret += hex[ndx];
278  }
279 
280  // reverse of string
281  return std::string( ret.rbegin(), ret.rend() );
282 }
283 
284 
285 int LSET::ParseHex( const char* aStart, int aCount )
286 {
287  LSET tmp;
288 
289  const char* rstart = aStart + aCount - 1;
290  const char* rend = aStart - 1;
291 
292  const int bitcount = size();
293 
294  int nibble_ndx = 0;
295 
296  while( rstart > rend )
297  {
298  int cc = *rstart--;
299 
300  if( cc == '_' )
301  continue;
302 
303  int nibble;
304 
305  if( cc >= '0' && cc <= '9' )
306  nibble = cc - '0';
307  else if( cc >= 'a' && cc <= 'f' )
308  nibble = cc - 'a' + 10;
309  else if( cc >= 'A' && cc <= 'F' )
310  nibble = cc - 'A' + 10;
311  else
312  break;
313 
314  int bit = nibble_ndx * 4;
315 
316  for( int ndx=0; bit<bitcount && ndx<4; ++bit, ++ndx )
317  if( nibble & (1<<ndx) )
318  tmp.set( bit );
319 
320  if( bit >= bitcount )
321  break;
322 
323  ++nibble_ndx;
324  }
325 
326  int byte_count = aStart + aCount - 1 - rstart;
327 
328  assert( byte_count >= 0 );
329 
330  if( byte_count > 0 )
331  *this = tmp;
332 
333  return byte_count;
334 }
335 
336 
337 LSEQ LSET::Seq( const PCB_LAYER_ID* aWishListSequence, unsigned aCount ) const
338 {
339  LSEQ ret;
340 
341 #if defined(DEBUG) && 0
342  LSET dup_detector;
343 
344  for( unsigned i=0; i<aCount; ++i )
345  {
346  PCB_LAYER_ID id = aWishListSequence[i];
347 
348  if( test( id ) )
349  {
350  wxASSERT_MSG( !dup_detector[id], wxT( "Duplicate in aWishListSequence" ) );
351  dup_detector[id] = true;
352 
353  ret.push_back( id );
354  }
355  }
356 #else
357 
358  for( unsigned i=0; i<aCount; ++i )
359  {
360  PCB_LAYER_ID id = aWishListSequence[i];
361 
362  if( test( id ) )
363  ret.push_back( id );
364  }
365 #endif
366 
367  return ret;
368 }
369 
370 
372 {
373  LSEQ ret;
374 
375  for( unsigned i=0; i<size(); ++i )
376  {
377  if( test(i) )
378  ret.push_back( PCB_LAYER_ID( i ) );
379  }
380 
381  return ret;
382 }
383 
384 
386 {
387  // bottom-to-top stack-up layers
388  static const PCB_LAYER_ID sequence[] = {
389  B_Fab,
390  B_CrtYd,
391  B_Adhes,
392  B_SilkS,
393  B_Paste,
394  B_Mask,
395  B_Cu,
396  In30_Cu,
397  In29_Cu,
398  In28_Cu,
399  In27_Cu,
400  In26_Cu,
401  In25_Cu,
402  In24_Cu,
403  In23_Cu,
404  In22_Cu,
405  In21_Cu,
406  In20_Cu,
407  In19_Cu,
408  In18_Cu,
409  In17_Cu,
410  In16_Cu,
411  In15_Cu,
412  In14_Cu,
413  In13_Cu,
414  In12_Cu,
415  In11_Cu,
416  In10_Cu,
417  In9_Cu,
418  In8_Cu,
419  In7_Cu,
420  In6_Cu,
421  In5_Cu,
422  In4_Cu,
423  In3_Cu,
424  In2_Cu,
425  In1_Cu,
426  F_Cu,
427  F_Mask,
428  F_Paste,
429  F_SilkS,
430  F_Adhes,
431  F_CrtYd,
432  F_Fab,
433  Dwgs_User,
434  Cmts_User,
435  Eco1_User,
436  Eco2_User,
437  Margin,
438  Edge_Cuts,
439  };
440 
441  return Seq( sequence, DIM( sequence ) );
442 }
443 
444 
445 PCB_LAYER_ID FlipLayer( PCB_LAYER_ID aLayerId, int aCopperLayersCount )
446 {
447  switch( aLayerId )
448  {
449  case B_Cu: return F_Cu;
450  case F_Cu: return B_Cu;
451 
452  case B_SilkS: return F_SilkS;
453  case F_SilkS: return B_SilkS;
454 
455  case B_Adhes: return F_Adhes;
456  case F_Adhes: return B_Adhes;
457 
458  case B_Mask: return F_Mask;
459  case F_Mask: return B_Mask;
460 
461  case B_Paste: return F_Paste;
462  case F_Paste: return B_Paste;
463 
464  case B_CrtYd: return F_CrtYd;
465  case F_CrtYd: return B_CrtYd;
466 
467  case B_Fab: return F_Fab;
468  case F_Fab: return B_Fab;
469 
470  default: // change internal layer if aCopperLayersCount is >= 4
471  if( IsCopperLayer( aLayerId ) && aCopperLayersCount >= 4 )
472  {
473  // internal copper layers count is aCopperLayersCount-2
474  PCB_LAYER_ID fliplayer = PCB_LAYER_ID(aCopperLayersCount - 2 - ( aLayerId - In1_Cu ) );
475  // Ensure fliplayer has a value which does not crash pcbnew:
476  if( fliplayer < F_Cu )
477  fliplayer = F_Cu;
478 
479  if( fliplayer > B_Cu )
480  fliplayer = B_Cu;
481 
482  return fliplayer;
483  }
484 
485  // No change for the other layers
486  return aLayerId;
487  }
488 }
489 
490 
491 LSET FlipLayerMask( LSET aMask, int aCopperLayersCount )
492 {
493  // layers on physical outside of a board:
494  const static LSET and_mask( 16, // !! update count
495  B_Cu, F_Cu,
496  B_SilkS, F_SilkS,
497  B_Adhes, F_Adhes,
498  B_Mask, F_Mask,
499  B_Paste, F_Paste,
500  B_Adhes, F_Adhes,
501  B_CrtYd, F_CrtYd,
502  B_Fab, F_Fab
503  );
504 
505  LSET newMask = aMask & ~and_mask;
506 
507  if( aMask[B_Cu] )
508  newMask.set( F_Cu );
509 
510  if( aMask[F_Cu] )
511  newMask.set( B_Cu );
512 
513  if( aMask[B_SilkS] )
514  newMask.set( F_SilkS );
515 
516  if( aMask[F_SilkS] )
517  newMask.set( B_SilkS );
518 
519  if( aMask[B_Adhes] )
520  newMask.set( F_Adhes );
521 
522  if( aMask[F_Adhes] )
523  newMask.set( B_Adhes );
524 
525  if( aMask[B_Mask] )
526  newMask.set( F_Mask );
527 
528  if( aMask[F_Mask] )
529  newMask.set( B_Mask );
530 
531  if( aMask[B_Paste] )
532  newMask.set( F_Paste );
533 
534  if( aMask[F_Paste] )
535  newMask.set( B_Paste );
536 
537  if( aMask[B_Adhes] )
538  newMask.set( F_Adhes );
539 
540  if( aMask[F_Adhes] )
541  newMask.set( B_Adhes );
542 
543  if( aMask[B_CrtYd] )
544  newMask.set( F_CrtYd );
545 
546  if( aMask[F_CrtYd] )
547  newMask.set( B_CrtYd );
548 
549  if( aMask[B_Fab] )
550  newMask.set( F_Fab );
551 
552  if( aMask[F_Fab] )
553  newMask.set( B_Fab );
554 
555  if( aCopperLayersCount >= 4 ) // Internal layers exist
556  {
557  LSET internalMask = aMask & LSET::InternalCuMask();
558 
559  if( internalMask != LSET::InternalCuMask() )
560  {
561  // the mask does not include all internal layers. Therefore
562  // the flipped mask for internal copper layers must be built
563  int innerLayerCnt = aCopperLayersCount -2;
564 
565  // the flipped mask is the innerLayerCnt bits rewritten in reverse order
566  // ( bits innerLayerCnt to 1 rewritten in bits 1 to innerLayerCnt )
567  for( int ii = 0; ii < innerLayerCnt; ii++ )
568  {
569  if( internalMask[innerLayerCnt - ii] )
570  {
571  newMask.set( ii + In1_Cu );
572  }
573  else
574  {
575  newMask.reset( ii + In1_Cu );
576  }
577  }
578  }
579  }
580 
581  return newMask;
582 }
583 
584 
586 {
587  unsigned set_count = count();
588 
589  if( !set_count )
590  return UNSELECTED_LAYER;
591  else if( set_count > 1 )
592  return UNDEFINED_LAYER;
593 
594  for( unsigned i=0; i < size(); ++i )
595  {
596  if( test( i ) )
597  return PCB_LAYER_ID( i );
598  }
599 
600  wxASSERT( 0 ); // set_count was verified as 1 above, what did you break?
601 
602  return UNDEFINED_LAYER;
603 }
604 
605 
607 {
608  static const PCB_LAYER_ID cu_internals[] = {
609  In1_Cu,
610  In2_Cu,
611  In3_Cu,
612  In4_Cu,
613  In5_Cu,
614  In6_Cu,
615  In7_Cu,
616  In8_Cu,
617  In9_Cu,
618  In10_Cu,
619  In11_Cu,
620  In12_Cu,
621  In13_Cu,
622  In14_Cu,
623  In15_Cu,
624  In16_Cu,
625  In17_Cu,
626  In18_Cu,
627  In19_Cu,
628  In20_Cu,
629  In21_Cu,
630  In22_Cu,
631  In23_Cu,
632  In24_Cu,
633  In25_Cu,
634  In26_Cu,
635  In27_Cu,
636  In28_Cu,
637  In29_Cu,
638  In30_Cu,
639  };
640 
641  static const LSET saved( cu_internals, DIM( cu_internals ) );
642  return saved;
643 }
644 
645 
646 LSET LSET::AllCuMask( int aCuLayerCount )
647 {
648  // retain all in static as the full set, which is a common case.
649  static const LSET all = InternalCuMask().set( F_Cu ).set( B_Cu );
650 
651  if( aCuLayerCount == MAX_CU_LAYERS )
652  return all;
653 
654  // subtract out some Cu layers not wanted in the mask.
655  LSET ret = all;
656  int clear_count = MAX_CU_LAYERS - aCuLayerCount;
657 
658  clear_count = Clamp( 0, clear_count, MAX_CU_LAYERS - 2 );
659 
660  for( LAYER_NUM elem=In30_Cu; clear_count; --elem, --clear_count )
661  {
662  ret.set( elem, false );
663  }
664 
665  return ret;
666 }
667 
668 
670 {
671  static const LSET saved = LSET().set() & ~AllCuMask();
672  return saved;
673 }
674 
675 
677 {
678  static const LSET saved( 2, F_Cu, B_Cu );
679  return saved;
680 }
681 
682 
684 {
685  static const LSET saved = LSET().set();
686  return saved;
687 }
688 
689 
691 {
692  static const LSET saved( 6, B_SilkS, B_Mask, B_Adhes, B_Paste, B_CrtYd, B_Fab );
693  return saved;
694 }
695 
697 {
698  static const LSET saved( 4, B_SilkS, B_Mask, B_Adhes, B_Paste );
699  return saved;
700 }
701 
703 {
704  static const LSET saved( 6, F_SilkS, F_Mask, F_Adhes, F_Paste, F_CrtYd, F_Fab );
705  return saved;
706 }
707 
708 
710 {
711  static const LSET saved( 4, F_SilkS, F_Mask, F_Adhes, F_Paste );
712  return saved;
713 }
714 
715 
717 {
718  static const LSET saved = BackTechMask() | FrontTechMask();
719  return saved;
720 }
721 
722 
724 {
725  static const LSET saved = BackBoardTechMask() | FrontBoardTechMask();
726  return saved;
727 }
728 
729 
731 {
732  static const LSET saved( 6,
733  Dwgs_User,
734  Cmts_User,
735  Eco1_User,
736  Eco2_User,
737  Edge_Cuts,
738  Margin
739  );
740 
741  return saved;
742 }
743 
744 
746 {
747  static const LSET saved = FrontTechMask().set( F_Cu );
748  return saved;
749 }
750 
751 
753 {
754  static const LSET saved = BackTechMask().set( B_Cu );
755  return saved;
756 }
757 
758 
760 {
762 
763  // Assmuming that the PCB_LAYER_ID order is according to preferred UI order, as of
764  // today this is true. When that becomes not true, its easy to change the order
765  // in here to compensate.
766 
767  for( unsigned i=0; i<DIM(order); ++i )
768  order[i] = PCB_LAYER_ID( i );
769 
770  return Seq( order, DIM( order ) );
771 }
772 
773 
775 {
776  wxASSERT( unsigned( aLayer ) < PCB_LAYER_ID_COUNT );
777  return PCB_LAYER_ID( aLayer );
778 }
779 
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:646
static LSET FrontBoardTechMask()
Function FrontBoardTechMask returns a mask holding technical layers used in a board fabrication (no C...
Definition: lset.cpp:709
#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:491
std::string FmtHex() const
Function FmtHex returns a hex string showing contents of this LSEQ.
Definition: lset.cpp:253
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:690
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:445
static LSET AllNonCuMask()
Function AllNonCuMask returns a mask holding all layer minus CU layers.
Definition: lset.cpp:669
static LSET FrontTechMask()
Function FrontTechMask returns a mask holding all technical layers (no CU layer) on front side...
Definition: lset.cpp:702
static LSET AllTechMask()
Function AllTechMask returns a mask holding all technical layers (no CU layer) on both side...
Definition: lset.cpp:716
static LSET FrontMask()
Function FrontMask returns a mask holding all technical layers and the external CU layer on front sid...
Definition: lset.cpp:745
LSEQ SeqStackupBottom2Top() const
Function SeqStackBottom2Top returns the sequence that is typical for a bottom-to-top stack-up...
Definition: lset.cpp:385
PCB_LAYER_ID ExtractLayer() const
Find the first set PCB_LAYER_ID.
Definition: lset.cpp:585
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:337
LSEQ Seq() const
Function Seq returns a LSEQ from this LSET in ascending PCB_LAYER_ID order.
Definition: lset.cpp:371
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:606
static LSET ExternalCuMask()
Function ExternalCuMask returns a mask holding the Front and Bottom layers.
Definition: lset.cpp:676
static LSET AllLayersMask()
Definition: lset.cpp:683
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:696
std::string FmtBin() const
Function FmtBin returns a binary string showing contents of this LSEQ.
Definition: lset.cpp:229
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:752
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:723
LSEQ Users() const
*_User layers.
Definition: lset.cpp:213
static LSET UserMask()
Definition: lset.cpp:730
int ParseHex(const char *aStart, int aCount)
Function ParseHex understands the output of FmtHex() and replaces this set's values with those given ...
Definition: lset.cpp:285
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:774
LSEQ UIOrder() const
Definition: lset.cpp:759