25#include <wx/translation.h>
33constexpr size_t SECTION_COUNT =
static_cast<size_t>(
SECTION::COUNT );
34constexpr size_t MODE_COUNT =
static_cast<size_t>(
MODE::COUNT );
42constexpr std::array<std::array<SECTION_RULE, MODE_COUNT>, SECTION_COUNT> TABLE_4 = { {
44 { { O,
N,
N, O, O,
N,
N,
N } },
45 { { O, Y, O, O, Y, Y,
N,
N } },
46 { { O,
N,
N,
N, Y, Y, O,
N } },
47 { { O,
N,
N,
N, Y, Y,
N,
N } },
48 { { O,
N, Y, Y,
N,
N,
N,
N } },
49 { { O,
N, O, Y, Y, Y, Y,
N } },
50 { { O,
N,
N, Y,
N,
N, O,
N } },
51 { { O,
N,
N,
N, O,
N, Y,
N } },
52 { { O,
N,
N, Y, Y, Y, O,
N } },
53 { { O,
N, O, Y, Y, Y, O,
N } },
54 { { O,
N, O, O, O, O, O,
N } },
55 { { O,
N, Y, Y, Y, Y, O,
N } },
56 { { O,
N, Y, Y,
N,
N,
N,
N } },
57 { { O,
N, O, O,
N,
N,
N,
N } },
58 { { O,
N, O, O,
N,
N,
N,
N } },
59 { { O,
N,
N, O, O, O,
N,
N } },
60 { { O,
N,
N, Y, O, Y,
N,
N } },
61 { { O, O, O, O, O, O, O, Y } },
64constexpr std::array<char, SECTION_COUNT> SECTION_KEYS = {
65 'K',
'B',
'C',
'A',
'S',
'U',
'M',
'P',
'L',
'R',
'D',
'O',
'I',
'E',
'F',
'G',
'Y',
'X'
68constexpr std::array<const char*, MODE_COUNT> MODE_TOKENS = {
69 "USERDEF",
"BOM",
"STACKUP",
"FABRICATION",
"ASSEMBLY",
"TEST",
"STENCIL",
"DFX"
73static_assert( MODE_TOKENS[
static_cast<size_t>(
MODE::DFX )][0] ==
'D',
74 "MODE_TOKENS is out of step with MODE" );
77constexpr std::array<std::pair<const char*, SECTION>, 27> LAYER_FUNCTION_SECTIONS = { {
114 for(
size_t ii = 0; ii < SECTION_COUNT; ++ii )
130 return SECTION_KEYS[
static_cast<size_t>( aSection )];
136 for(
size_t ii = 0; ii < SECTION_COUNT; ++ii )
138 if( SECTION_KEYS[ii] == aKey )
139 return static_cast<SECTION>( ii );
148 return TABLE_4[
static_cast<size_t>( aSection )][
static_cast<size_t>( aMode )];
213 return inCadData.any();
221 for(
size_t ii = 0; ii < SECTION_COUNT; ++ii )
223 if( aSet.test( ii ) )
224 key << SECTION_KEYS[ii];
235 for( wxUniChar ch : aKey )
255 return wxString::FromAscii( MODE_TOKENS[
static_cast<size_t>( aMode )] );
265 for( wxUniChar ch : aToken )
267 if( ch >=
'a' && ch <=
'z' )
268 token << static_cast<wxChar>( ch -
'a' +
'A' );
273 for(
size_t ii = 0; ii < MODE_COUNT; ++ii )
275 if( token == wxString::FromAscii( MODE_TOKENS[ii] ) )
276 return static_cast<MODE>( ii );
336 const wxString& aSide )
338 for(
const auto& entry : LAYER_FUNCTION_SECTIONS )
340 if( aLayerFunction == wxString::FromAscii( entry.first ) )
344 if( aLayerFunction.StartsWith( wxT(
"DIEL" ) ) )
349 if( aLayerFunction.StartsWith( wxT(
"COMPONENT" ) )
350 || aLayerFunction == wxT(
"EMBEDDED_COMPONENT" ) )
356 static const std::array<const char*, 6> conductors = {
"CONDUCTOR",
"CONDFILM",
"CONDFOIL",
357 "PLANE",
"SIGNAL",
"MIXED" };
359 for(
const char* function : conductors )
361 if( aLayerFunction == wxString::FromAscii( function ) )
363 if( aSide == wxT(
"INTERNAL" ) )
366 return aSide.IsEmpty() ? std::nullopt
381 result.m_conflicts.push_back( { std::nullopt, std::nullopt,
_(
"Cannot produce this IPC-2581 data set." ) } );
389 if(
result.m_included.none() )
391 result.m_conflicts.push_back( { std::nullopt, std::nullopt,
_(
"No IPC-2581 content selected." ) } );
403 if( haveComponents && !haveOuterCopper )
405 result.m_conflicts.push_back(
407 _(
"Cannot export assembly data without outer copper layers." ) } );
413 result.m_conflicts.push_back(
415 _(
"Cannot export physical netlist without outer copper layers." ) } );
423 if( haveBom && !havePackages )
427 if( haveBom && !haveOuterCopper )
444 if( haveComponents && !havePackages )
446 result.m_conflicts.push_back(
448 _(
"Component assembly data cannot be exported without component "
449 "packages in IPC-2581B." ) } );
453 if( !haveComponents )
SECTION_SET & Set(SECTION aSection, bool aOn=true)
bool IsUserLayer(PCB_LAYER_ID aLayerId)
Test whether a layer is a non copper and a non tech layer.
bool IsCopperLayer(int aLayerId)
Test whether a layer is a copper layer.
bool IsExternalCopperLayer(int aLayerId)
Test whether a layer is an external (F_Cu or B_Cu) copper layer.
PCB_LAYER_ID
A quick note on layer IDs:
SECTION_SET RecommendedOptionalSections(MODE aMode)
Optional schema sections that aMode selects by default.
wxString ModeToken(MODE aMode)
Table 4 function mode token such as FABRICATION.
SECTION_SET UnsupportedSections()
Schema sections that no KiCad board supplies.
bool SectionSetFromKeyString(const wxString &aKey, SECTION_SET &aResult)
Read a sectionKey attribute value Return false for an unknown character.
std::optional< SECTION > SectionFromKeyChar(char aKey)
Return the schema section for a Table 4 key character.
SECTION_SET RequiredSections(MODE aMode)
Schema sections that Table 4 marks Y for aMode.
SECTION_SET LegacySections()
Schema sections of the content that KiCad wrote before the function modes.
SECTION_RULE
Table 4 cell values N O and Y.
SECTION
Schema sections of the IPC-2581C function mode table, Table 4 p 80.
RESOLVE_RESULT ResolveSections(REVISION aRevision, MODE aMode, const SECTION_SET &aRequested)
Compare aRequested with Table 4 and give the attributes to remove and the conflicts.
char SectionKeyChar(SECTION aSection)
Return the Table 4 key character for aSection.
REVISION
Schema revision The two revisions declare different identity constraints.
std::optional< SECTION > SectionForLayerFunction(const wxString &aLayerFunction, const wxString &aSide)
Schema section that holds the layers with aLayerFunction.
bool NeedsCadData(const SECTION_SET &aSet)
True if an included schema section needs an Ecad/CadData element.
bool ModeSupported(MODE aMode, REVISION)
True if KiCad can write aMode for aRevision.
@ PINREF_COMPONENTREF
Pad/PinRef@componentRef and LogicalNet/PinRef@componentRef.
@ BOM_HEADER_STEPREF
Bom/BomHeader/StepRef.
@ COMPONENT_REFDES
Component@refDes.
@ PAD_PADSTACKDEFREF
Pad@padstackDefRef, and the PadStackDef elements themselves.
@ COMPONENT_PACKAGEREF
Component@packageRef.
@ BOM_REFDES_PACKAGEREF
Bom/BomItem/RefDes@packageRef.
@ BOM_REFDES
Bom/BomItem/RefDes and all its attributes.
@ BOM_REFDES_LAYERREF
Bom/BomItem/RefDes@layerRef.
wxString SectionKeyString(const SECTION_SET &aSet)
Give aSet as a sectionKey attribute value.
SECTION_RULE SectionRule(MODE aMode, SECTION aSection)
Return the Table 4 cell for aMode and aSection.
SECTION_SET OptionalSections(MODE aMode)
Schema sections that Table 4 marks O for aMode.
std::optional< MODE > ModeFromToken(const wxString &aToken)
Read a Table 4 function mode token in upper case or in lower case.
std::optional< SECTION > SectionForBoardLayer(PCB_LAYER_ID aLayer)
Schema section that holds the artwork of aLayer.
wxString result
Test unit parsing edge cases and error handling.