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