25#include <wx/translation.h>
34constexpr std::array<std::pair<const char*, SECTION>, 27> LAYER_FUNCTION_SECTIONS = { {
37 {
"DRILL", SECTION::DRILL_ROUT },
38 {
"ROUT", SECTION::DRILL_ROUT },
39 {
"V_CUT", SECTION::DRILL_ROUT },
40 {
"EDGE_CHAMFER", SECTION::DRILL_ROUT },
41 {
"SOLDERMASK", SECTION::SOLDERMASK },
42 {
"SOLDERPASTE", SECTION::SOLDERPASTE },
43 {
"SILKSCREEN", SECTION::SILKSCREEN },
44 {
"LEGEND", SECTION::SILKSCREEN },
45 {
"DOCUMENT", SECTION::DOCUMENTATION },
46 {
"GRAPHIC", SECTION::DOCUMENTATION },
47 {
"BOARD_OUTLINE", SECTION::DOCUMENTATION },
48 {
"REWORK", SECTION::DOCUMENTATION },
49 {
"FIXTURE", SECTION::DOCUMENTATION },
50 {
"PROBE", SECTION::DOCUMENTATION },
51 {
"COURTYARD", SECTION::DOCUMENTATION },
52 {
"ASSEMBLY", SECTION::COMPONENTS },
53 {
"COATINGCOND", SECTION::MISC_FAB },
54 {
"COATINGNONCOND", SECTION::MISC_FAB },
55 {
"CONDUCTIVE_ADHESIVE", SECTION::MISC_FAB },
56 {
"GLUE", SECTION::MISC_FAB },
57 {
"HOLEFILL", SECTION::MISC_FAB },
58 {
"SOLDERBUMP", SECTION::MISC_FAB },
59 {
"THIEVING_KEEP_INOUT", SECTION::MISC_FAB },
60 {
"EDGE_PLATING", SECTION::MISC_FAB },
61 {
"STIFFENER", SECTION::MISC_FAB },
62 {
"CAPACITIVE", SECTION::MISC_FAB },
63 {
"RESISTIVE", SECTION::MISC_FAB },
73 return aMode != MODE::DFX;
86 return SECTION::MISC_FAB;
90 return SECTION::SOLDERPASTE;
94 return SECTION::SILKSCREEN;
98 return SECTION::SOLDERMASK;
101 return SECTION::PROFILE;
106 return SECTION::DOCUMENTATION;
111 return SECTION::COMPONENTS;
115 return SECTION::DOCUMENTATION;
123 const wxString& aSide )
125 for(
const auto& entry : LAYER_FUNCTION_SECTIONS )
127 if( aLayerFunction == wxString::FromAscii( entry.first ) )
131 if( aLayerFunction.StartsWith( wxT(
"DIEL" ) ) )
132 return SECTION::DIELECTRIC;
136 if( aLayerFunction.StartsWith( wxT(
"COMPONENT" ) )
137 || aLayerFunction == wxT(
"EMBEDDED_COMPONENT" ) )
139 return SECTION::COMPONENTS;
143 static const std::array<const char*, 6> conductors = {
"CONDUCTOR",
"CONDFILM",
"CONDFOIL",
144 "PLANE",
"SIGNAL",
"MIXED" };
146 for(
const char* function : conductors )
148 if( aLayerFunction == wxString::FromAscii( function ) )
150 if( aSide == wxT(
"INTERNAL" ) )
151 return SECTION::INNER_COPPER;
153 return aSide.IsEmpty() ? std::nullopt
154 : std::optional<SECTION>( SECTION::OUTER_COPPER );
168 result.m_conflicts.push_back( { std::nullopt, std::nullopt,
_(
"Cannot produce this IPC-2581 data set." ) } );
176 if(
result.m_included.none() )
178 result.m_conflicts.push_back( { std::nullopt, std::nullopt,
_(
"No IPC-2581 content selected." ) } );
182 const bool haveBom =
result.m_included.Contains( SECTION::BOM_AVL );
183 const bool havePackages =
result.m_included.Contains( SECTION::PACKAGES );
184 const bool haveComponents =
result.m_included.Contains( SECTION::COMPONENTS );
185 const bool havePadstacks =
result.m_included.Contains( SECTION::PADSTACKS );
186 const bool haveOuterCopper =
result.m_included.Contains( SECTION::OUTER_COPPER );
190 if( haveComponents && !haveOuterCopper )
192 result.m_conflicts.push_back(
193 { SECTION::COMPONENTS, SECTION::OUTER_COPPER,
194 _(
"Cannot export assembly data without outer copper layers." ) } );
198 if(
result.m_included.Contains( SECTION::PHYSICAL_NET ) && !haveOuterCopper )
200 result.m_conflicts.push_back(
201 { SECTION::PHYSICAL_NET, SECTION::OUTER_COPPER,
202 _(
"Cannot export physical netlist without outer copper layers." ) } );
210 if( haveBom && !havePackages )
214 if( haveBom && !haveOuterCopper )
231 if( haveComponents && !havePackages )
233 result.m_conflicts.push_back(
234 { SECTION::COMPONENTS, SECTION::PACKAGES,
235 _(
"Component assembly data cannot be exported without component "
236 "packages in IPC-2581B." ) } );
240 if( !haveComponents )
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:
JOB_EXPORT_PCB_FAB::DATA_SET MODE
Columns of Table 4 The job owns the enum so that every layer shares one type.
SECTION_SET RequiredSections(MODE aMode)
Schema sections that Table 4 marks Y for aMode.
SECTION_SET OptionalSections(MODE aMode)
Schema sections that Table 4 marks O for aMode.
SECTION_SET UnsupportedSections()
Schema sections that no KiCad board supplies.
bool NeedsCadData(const SECTION_SET &aSet)
True if an included schema section needs an Ecad/CadData element.
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.
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 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.
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.