32#include <fmt/format.h>
42#include <magic_enum.hpp>
83#include <wx/mstream.h>
92constexpr double INT_LIMIT = std::numeric_limits<int>::max() - 10;
94using namespace PCB_KEYS_T;
134 for(
int i=1; i<=14; ++i )
136 std::string key = fmt::format(
"Inner{}.Cu", i );
147 TIME_PT curTime = CLOCK::now();
148 unsigned curLine = reader->LineNumber();
151 if(
delta > std::chrono::milliseconds( 250 ) )
170 while( ( token = NextTok() ) != T_EOF )
172 if( token == T_LEFT )
175 if( token == T_RIGHT )
192 m_netCodes.resize(
static_cast<std::size_t
>( aIndex ) + 1 );
234 else if( token == T_no )
237 Expecting(
"yes or no" );
249 else if( token == T_no )
251 else if( token == T_none )
254 Expecting(
"yes, no or none" );
265 bool ret = aDefaultValue;
267 if( PrevTok() == T_LEFT )
272 if(
static_cast<int>( token ) ==
DSN_RIGHT )
273 return aDefaultValue;
275 if( token == T_yes || token == T_true )
277 else if( token == T_no || token == T_false )
280 Expecting(
"yes or no" );
287 return aDefaultValue;
296 int token = NextTok();
305 _(
"Invalid net ID in\nfile: %s;\nline: %d\noffset: %d." ),
306 CurSource(), CurLineNumber(), CurOffset() );
313 if( !IsSymbol( token ) )
315 Expecting(
"net name" );
321 wxString netName( FromUTF8() );
345 int year, month, day;
354 if( day <= 0 || month <= 0 || month > 12 ||
355 day > wxDateTime::GetNumberOfDays( (wxDateTime::Month)( month - 1 ), year ) )
362 wxDateTime date( day, (wxDateTime::Month)( month - 1 ), year, 0, 0, 0, 0 );
363 return date.FormatDate();
369 if( CurTok() != T_LEFT )
389 if( CurTok() != T_LEFT )
408 bool has_start =
false;
409 bool has_mid =
false;
410 bool has_end =
false;
412 VECTOR2I arc_start, arc_mid, arc_end;
414 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
416 if( token != T_LEFT )
442 Expecting(
"start, mid or end" );
449 Expecting(
"start" );
457 SHAPE_ARC arc( arc_start, arc_mid, arc_end, 0 );
461 if( token != T_RIGHT )
462 Expecting( T_RIGHT );
467 Expecting(
"xy or arc" );
504 return { pName, pValue };
514 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
516 if( token == T_LEFT )
519 if( token == T_variant )
521 wxString variantName;
522 wxString description;
524 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
526 if( token == T_LEFT )
533 variantName = FromUTF8();
539 description = FromUTF8();
544 Expecting(
"name or description" );
548 if( !variantName.IsEmpty() )
550 m_board->AddVariant( variantName );
552 if( !description.IsEmpty() )
553 m_board->SetVariantDescription( variantName, description );
558 Expecting( T_variant );
568 wxString variantName;
571 bool hasExcludeFromBOM =
false;
572 bool excludeFromBOM =
false;
573 bool hasExcludeFromPosFiles =
false;
574 bool excludeFromPosFiles =
false;
575 std::vector<std::pair<wxString, wxString>> fields;
577 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
579 if( token == T_LEFT )
586 variantName = FromUTF8();
595 case T_exclude_from_bom:
597 hasExcludeFromBOM =
true;
600 case T_exclude_from_pos_files:
602 hasExcludeFromPosFiles =
true;
610 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
612 if( token == T_LEFT )
615 if( token == T_name )
618 fieldName = FromUTF8();
621 else if( token == T_value )
624 fieldValue = FromUTF8();
629 Expecting(
"name or value" );
633 if( !fieldName.IsEmpty() )
634 fields.emplace_back( fieldName, fieldValue );
640 Expecting(
"name, dnp, exclude_from_bom, exclude_from_pos_files, or field" );
644 if( variantName.IsEmpty() )
655 if( hasExcludeFromBOM )
658 if( hasExcludeFromPosFiles )
661 for(
const auto& [fieldName, fieldValue] : fields )
672 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
674 if( token == T_LEFT )
683 case T_allow_two_segments:
687 case T_prefer_zone_connections:
691 case T_best_length_ratio:
701 case T_best_width_ratio:
727 Expecting(
"enabled, allow_two_segments, prefer_zone_connections, best_length_ratio, "
728 "max_length, best_width_ratio, max_width, curve_points or filter_ratio" );
736 wxCHECK_RET( CurTok() == T_effects,
737 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as EDA_TEXT." ) );
755 bool foundTextSize =
false;
757 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
759 if( token == T_LEFT )
765 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
767 if( token == T_LEFT )
786 foundTextSize =
true;
809 Expecting(
"face, size, line_spacing, thickness, bold, or italic" );
816 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
818 if( token == T_LEFT )
828 default: Expecting(
"left, right, top, bottom, or mirror" );
845 Expecting(
"font, justify, or hide" );
853 const double defaultTextSize = 1.524 *
pcbIUScale.IU_PER_MM;
864 NeedSYMBOLorNUMBER();
865 wxString cacheText =
From_UTF8( CurText() );
868 text->SetupRenderCache( cacheText,
text->GetFont(), cacheAngle, { 0, 0 } );
870 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
872 if( token != T_LEFT )
877 if( token != T_polygon )
878 Expecting( T_polygon );
882 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
884 if( token != T_LEFT )
894 while( (token = NextTok() ) != T_RIGHT )
905 text->AddRenderCacheGlyph( poly );
912 if( !aFileNameAlreadyParsed )
914 wxCHECK_MSG( CurTok() == T_model,
nullptr,
915 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as FP_3DMODEL." ) );
917 NeedSYMBOLorNUMBER();
925 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
927 if( token == T_LEFT )
1004 if( token != T_xyz )
1016 Expecting(
"at, hide, opacity, offset, scale, or rotate" );
1033 if( CurTok() != T_LEFT )
1036 if( NextTok() != T_kicad_pcb)
1053 std::unique_ptr<wxArrayString> initial_comments( ReadCommentLines() );
1058 Unexpected( token );
1060 if( token != T_LEFT )
1061 Expecting( T_LEFT );
1082 err.Printf(
_(
"Unknown token '%s'" ), FromUTF8() );
1092 textItem->ResolveFont( embeddedFonts );
1121 std::map<wxString, wxString> properties;
1135 std::vector<BOARD_ITEM*> bulkAddedItems;
1138 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1142 if( token != T_LEFT )
1143 Expecting( T_LEFT );
1154 m_board->SetGenerator( FromUTF8() );
1165 m_board->SetGenerator( FromUTF8() );
1169 case T_generator_version:
1223 m_board->m_LegacyNetclassesLoaded =
true;
1233 case T_gr_ellipse_arc:
1236 bulkAddedItems.push_back( item );
1242 bulkAddedItems.push_back( item );
1248 bulkAddedItems.push_back( item );
1254 bulkAddedItems.push_back( item );
1260 bulkAddedItems.push_back( item );
1266 bulkAddedItems.push_back( item );
1272 bulkAddedItems.push_back( item );
1279 bulkAddedItems.push_back( item );
1286 bulkAddedItems.push_back( track );
1295 bulkAddedItems.push_back( arc );
1311 bulkAddedItems.push_back( item );
1328 bulkAddedItems.push_back( item );
1335 bulkAddedItems.push_back( item );
1341 bulkAddedItems.push_back( item );
1344 case T_embedded_fonts:
1351 case T_embedded_files:
1354 embeddedFilesParser.SyncLineReaderWith( *
this );
1368 for(
int tok = embeddedFilesParser.NextTok();
1370 tok = embeddedFilesParser.NextTok() )
1374 else if( tok ==
DSN_RIGHT && --depth < 0 )
1379 SyncLineReaderWith( embeddedFilesParser );
1385 err.Printf(
_(
"Unknown token '%s'" ), FromUTF8() );
1390 if( bulkAddedItems.size() > 0 )
1391 m_board->FinalizeBulkAdd( bulkAddedItems );
1393 m_board->SetProperties( properties );
1402 static_cast<PCB_BARCODE*
>( bc_item )->AssembleBarcode();
1407 for(
BOARD_ITEM* bc_item : fp->GraphicalItems() )
1410 static_cast<PCB_BARCODE*
>( bc_item )->AssembleBarcode();
1417 wxString msg, undefinedLayerNames, destLayerName;
1421 if( !undefinedLayerNames.IsEmpty() )
1422 undefinedLayerNames += wxT(
", " );
1424 undefinedLayerNames += layerName;
1427 destLayerName =
m_board->GetLayerName( destLayer );
1431 msg.Printf(
_(
"Items found on undefined layers (%s).\n"
1432 "Do you wish to rescue them to the %s layer?\n"
1434 "Zones will need to be refilled." ),
1435 undefinedLayerNames, destLayerName );
1446 const auto visitItem = [&](
BOARD_ITEM& curr_item )
1448 LSET layers = curr_item.GetLayerSet();
1450 if( !layers.test(
Rescue ) )
1453 layers.
set( destLayer );
1458 if( layers.count() == 1 )
1459 curr_item.SetLayer( destLayer );
1461 curr_item.SetLayerSet( layers );
1474 via->LayerPair( &top_layer, &bottom_layer );
1478 if( top_layer ==
Rescue )
1481 if( bottom_layer ==
Rescue )
1482 bottom_layer =
B_Cu;
1484 via->SetLayerPair( top_layer, bottom_layer );
1489 visitItem( *track );
1497 visitItem( *drawing );
1501 for(
BOARD_ITEM* drawing : fp->GraphicalItems() )
1502 visitItem( *drawing );
1507 for(
PCB_FIELD* field : fp->GetFields() )
1508 visitItem( *field );
1518 THROW_IO_ERROR( wxString::Format(
_(
"One or more items were found on undefined "
1519 "layers (%s). Open the board in the PCB Editor "
1521 undefinedLayerNames ) );
1531 ZONE* z =
static_cast<ZONE*
>( zone );
1543 for(
int i = 0; i < 2; ++i )
1545 const KIID& original = net->GetTerminalPadUuid( i );
1552 net->SetTerminalPadUuid( i, it->second );
1557 net->ResolveTerminalPads(
m_board );
1566 BOARD* board =
dynamic_cast<BOARD*
>( aParent );
1571 std::unordered_map<KIID, BOARD_ITEM*> fpItemMap;
1578 fpItemMap.insert( { child->
m_Uuid, child } );
1589 auto it = cache.find( aId );
1591 return it != cache.end() ? it->second :
nullptr;
1593 else if( footprint )
1595 auto it = fpItemMap.find( aId );
1597 return it != fpItemMap.end() ? it->second :
nullptr;
1608 std::vector<const GROUP_INFO*> groupTypeObjects;
1611 groupTypeObjects.emplace_back( &groupInfo );
1614 groupTypeObjects.emplace_back( &genInfo );
1616 for(
const GROUP_INFO* groupInfo : groupTypeObjects )
1629 THROW_IO_ERROR( wxString::Format(
_(
"Cannot create generated object of type '%s'" ),
1630 genInfo->genType ) );
1639 group->SetName( groupInfo->name );
1642 group->SetUuidDirect( groupInfo->uuid );
1644 if( groupInfo->libId.IsValid() )
1645 group->SetDesignBlockLibId( groupInfo->libId );
1647 if( groupInfo->locked )
1648 group->SetLocked(
true );
1656 fpItemMap.insert( {
group->m_Uuid,
group } );
1664 for(
const GROUP_INFO* groupInfo : groupTypeObjects )
1668 for(
const KIID& aUuid : groupInfo->memberUuids )
1675 item = getItem( aUuid );
1681 group->AddItem( item );
1687 for(
BOARD_ITEM* item : gen->GetBoardItems() )
1691 gen->SetLayer( track->GetLayer() );
1701 m_board->GroupsSanityCheck(
true );
1707 wxCHECK_RET( CurTok() == T_kicad_pcb,
1708 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a header." ) );
1714 if( tok == T_version )
1736 wxCHECK_RET( CurTok() == T_general,
1737 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a general section." ) );
1741 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1743 if( token != T_LEFT )
1744 Expecting( T_LEFT );
1755 case T_legacy_teardrops:
1760 while( ( token = NextTok() ) != T_RIGHT )
1762 if( !IsSymbol( token ) && token != T_NUMBER )
1763 Expecting(
"symbol or number" );
1772 wxCHECK_RET( ( CurTok() == T_page &&
m_requiredVersion <= 20200119 ) || CurTok() == T_paper,
1773 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a PAGE_INFO." ) );
1780 wxString pageType = FromUTF8();
1782 if( !pageInfo.
SetType( pageType ) )
1785 err.Printf(
_(
"Page type '%s' is not valid." ), FromUTF8() );
1812 if( token == T_portrait )
1817 else if( token != T_RIGHT )
1819 Expecting(
"portrait|)" );
1822 m_board->SetPageSettings( pageInfo );
1828 wxCHECK_RET( CurTok() == T_title_block,
1829 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as TITLE_BLOCK." ) );
1834 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
1836 if( token != T_LEFT )
1837 Expecting( T_LEFT );
1850 titleBlock.
SetDate( FromUTF8() );
1865 int commentNumber =
parseInt(
"comment" );
1867 switch( commentNumber )
1916 err.Printf( wxT(
"%d is not a valid title block comment number" ), commentNumber );
1924 Expecting(
"title, date, rev, company, or comment" );
1930 m_board->SetTitleBlock( titleBlock );
1939 std::string userName;
1941 bool isVisible =
true;
1945 if( CurTok() != T_LEFT )
1946 Expecting( T_LEFT );
1949 int layer_num =
parseInt(
"layer index" );
1951 NeedSYMBOLorNUMBER();
1960 if( token == T_hide )
1965 else if( token == T_STRING )
1967 userName = CurText();
1970 else if( token != T_RIGHT )
1972 Expecting(
"hide, user defined name, or )" );
1975 aLayer->
m_type = LAYER::ParseType( type.c_str() );
1995 int dielectric_idx = 1;
2003 std::set<PCB_LAYER_ID> seenBrdLayers;
2004 bool duplicatedStackup =
false;
2006 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2008 if( CurTok() != T_LEFT )
2009 Expecting( T_LEFT );
2013 if( token != T_layer )
2017 case T_copper_finish:
2023 case T_edge_plating:
2029 case T_dielectric_constraints:
2035 case T_edge_connector:
2039 if( token == T_yes )
2041 else if( token == T_bevelled )
2047 case T_castellated_pads:
2081 else if( !( layerId & 1 ) )
2084 std::unique_ptr<BOARD_STACKUP_ITEM> itemOwner;
2087 if( layerId !=
UNDEFINED_LAYER && !seenBrdLayers.insert( layerId ).second )
2088 duplicatedStackup =
true;
2096 static constexpr int MAX_STACKUP_ITEMS = 128;
2098 itemOwner = std::make_unique<BOARD_STACKUP_ITEM>( type );
2099 item = itemOwner.get();
2105 if( !duplicatedStackup && stackup.
GetCount() < MAX_STACKUP_ITEMS )
2106 stackup.
Add( itemOwner.release() );
2110 Expecting(
"layer_name" );
2113 bool has_next_sublayer =
true;
2114 int sublayer_idx = 0;
2116 wxString specFreqUnits;
2117 wxString dielectricModel;
2119 while( has_next_sublayer )
2121 has_next_sublayer =
false;
2123 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2125 if( token == T_addsublayer )
2127 has_next_sublayer =
true;
2131 if( token == T_LEFT )
2147 if( token == T_LEFT )
2150 if( token == T_locked )
2173 case T_loss_tangent:
2179 case T_spec_frequency:
2185 case T_dielectric_model:
2194 case T_djordjevic_sarkar:
2199 Expecting(
"constant or djordjevic_sarkar" );
2220 wxColour wx_color = color.
ToColour();
2223 name.Printf( wxT(
"#%02X%02X%02X%02X" ),
2243 if( has_next_sublayer )
2252 if( token != T_RIGHT )
2258 m_board->GetDesignSettings().m_HasStackup =
true;
2269 aMap[
"Adesivo.Retro"] =
"B.Adhes";
2270 aMap[
"Adesivo.Fronte"] =
"F.Adhes";
2271 aMap[
"Pasta.Retro"] =
"B.Paste";
2272 aMap[
"Pasta.Fronte"] =
"F.Paste";
2273 aMap[
"Serigrafia.Retro"] =
"B.SilkS";
2274 aMap[
"Serigrafia.Fronte"] =
"F.SilkS";
2275 aMap[
"Maschera.Retro"] =
"B.Mask";
2276 aMap[
"Maschera.Fronte"] =
"F.Mask";
2277 aMap[
"Grafica"] =
"Dwgs.User";
2278 aMap[
"Commenti"] =
"Cmts.User";
2279 aMap[
"Eco1"] =
"Eco1.User";
2280 aMap[
"Eco2"] =
"Eco2.User";
2281 aMap[
"Contorno.scheda"] =
"Edge.Cuts";
2284 aMap[
"Kleju_Dolna"] =
"B.Adhes";
2285 aMap[
"Kleju_Gorna"] =
"F.Adhes";
2286 aMap[
"Pasty_Dolna"] =
"B.Paste";
2287 aMap[
"Pasty_Gorna"] =
"F.Paste";
2288 aMap[
"Opisowa_Dolna"] =
"B.SilkS";
2289 aMap[
"Opisowa_Gorna"] =
"F.SilkS";
2290 aMap[
"Maski_Dolna"] =
"B.Mask";
2291 aMap[
"Maski_Gorna"] =
"F.Mask";
2292 aMap[
"Rysunkowa"] =
"Dwgs.User";
2293 aMap[
"Komentarzy"] =
"Cmts.User";
2294 aMap[
"ECO1"] =
"Eco1.User";
2295 aMap[
"ECO2"] =
"Eco2.User";
2296 aMap[
"Krawedziowa"] =
"Edge.Cuts";
2299 aMap[
"Dessous.Adhes"] =
"B.Adhes";
2300 aMap[
"Dessus.Adhes"] =
"F.Adhes";
2301 aMap[
"Dessous.Pate"] =
"B.Paste";
2302 aMap[
"Dessus.Pate"] =
"F.Paste";
2303 aMap[
"Dessous.SilkS"] =
"B.SilkS";
2304 aMap[
"Dessus.SilkS"] =
"F.SilkS";
2305 aMap[
"Dessous.Masque"] =
"B.Mask";
2306 aMap[
"Dessus.Masque"] =
"F.Mask";
2307 aMap[
"Dessin.User"] =
"Dwgs.User";
2308 aMap[
"Contours.Ci"] =
"Edge.Cuts";
2314 wxCHECK_RET( CurTok() == T_layers,
2315 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as layers." ) );
2320 int copperLayerCount = 0;
2322 bool anyHidden =
false;
2324 std::unordered_map< std::string, std::string > v3_layer_names;
2325 std::vector<LAYER> cu;
2330 std::vector<LAYER> appendedLayers;
2334 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
2341 cu.push_back( layer );
2354 for(
size_t i = 1; i < cu.size() - 1; i++ )
2359 tmpLayer = ( i + 1 ) * 2;
2361 cu[i].m_number = tmpLayer;
2364 cu[0].m_number =
F_Cu;
2365 cu[cu.size()-1].m_number =
B_Cu;
2367 for(
auto& cu_layer : cu )
2369 enabledLayers.
set( cu_layer.m_number );
2371 if( cu_layer.m_visible )
2372 visibleLayers.
set( cu_layer.m_number );
2386 appendedLayers.push_back( cu_layer );
2389 copperLayerCount = cu.size();
2393 while( token != T_RIGHT )
2399 auto new_layer_it = v3_layer_names.find( layer.
m_name.ToStdString() );
2401 if( new_layer_it != v3_layer_names.end() )
2407 error.Printf(
_(
"Layer '%s' in file '%s' at line %d is not in fixed layer hash." ),
2420 layer.
m_name = it->first;
2432 m_board->SetLayerDescr( it->second, layer );
2434 appendedLayers.push_back( layer );
2438 if( token != T_LEFT )
2445 if( copperLayerCount < 2 || (copperLayerCount % 2) != 0 )
2447 wxString err = wxString::Format(
_(
"%d is not a valid layer count" ), copperLayerCount );
2454 m_board->SetCopperLayerCount( std::max( copperLayerCount,
m_board->GetCopperLayerCount() ) );
2455 m_board->SetEnabledLayers( enabledLayers |
m_board->GetEnabledLayers() );
2459 m_board->SetCopperLayerCount( copperLayerCount );
2460 m_board->SetEnabledLayers( enabledLayers );
2465 m_board->m_LegacyVisibleLayers = visibleLayers;
2474 const LSET& aDestInitialEnabled,
int aDestInitialCopperCount )
2478 int srcCopperCount = 0;
2479 bool mismatch =
false;
2481 for(
const LAYER& src : aSourceLayers )
2488 if( !aDestInitialEnabled.
Contains(
id ) )
2490 else if( !src.m_userName.IsEmpty() && src.m_userName !=
m_board->GetLayerName(
id ) )
2497 std::vector<INPUT_LAYER_DESC> descs;
2499 for(
const LAYER& src : aSourceLayers )
2502 desc.
Name = src.m_userName.IsEmpty() ? src.m_name : src.m_userName;
2521 descs.push_back( desc );
2527 if( progressWindow )
2528 progressWindow->Hide();
2532 if( progressWindow )
2533 progressWindow->Show();
2537 for(
const LAYER& src : aSourceLayers )
2539 wxString key = src.m_userName.IsEmpty() ? src.m_name : src.m_userName;
2540 auto it = remap.find( key );
2557 if( !aDestInitialEnabled.
Contains( target ) )
2561 m_board->SetLayerDescr( target, descr );
2564 enabled.
set( target );
2567 m_board->SetEnabledLayers( enabled );
2573 LSET_MAP::const_iterator it = aMap.find( curText );
2575 if( it == aMap.end() )
2585 LAYER_ID_MAP::const_iterator it = aMap.find( curText );
2587 if( it == aMap.end() )
2594 if( it->second ==
Rescue )
2604 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as layer." ) );
2618 wxCHECK_MSG( CurTok() == T_layers,
LSET(),
2619 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as item layers." ) );
2623 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
2637 Expecting(
"single copper layer" );
2640 Expecting(
"max one soldermask layer" );
2645 Expecting(
"no mask layer when track is on internal layer" );
2649 Expecting(
"copper and mask on the same side" );
2652 Expecting(
"copper and mask on the same side" );
2660 wxCHECK_RET( CurTok() == T_setup,
2661 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as setup." ) );
2671 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
2673 if( token != T_LEFT )
2674 Expecting( T_LEFT );
2687 case T_last_trace_width:
2692 case T_user_trace_width:
2703 m_board->m_LegacyDesignSettingsLoaded =
true;
2708 case T_trace_clearance:
2709 defaultNetClass->SetClearance(
parseBoardUnits( T_trace_clearance ) );
2710 m_board->m_LegacyDesignSettingsLoaded =
true;
2714 case T_zone_clearance:
2716 m_board->m_LegacyDesignSettingsLoaded =
true;
2720 case T_zone_45_only:
2722 m_board->m_LegacyDesignSettingsLoaded =
true;
2726 case T_clearance_min:
2728 m_board->m_LegacyDesignSettingsLoaded =
true;
2734 m_board->m_LegacyDesignSettingsLoaded =
true;
2740 m_board->m_LegacyDesignSettingsLoaded =
true;
2746 m_board->m_LegacyDesignSettingsLoaded =
true;
2750 case T_via_min_annulus:
2752 m_board->m_LegacyDesignSettingsLoaded =
true;
2756 case T_via_min_size:
2758 m_board->m_LegacyDesignSettingsLoaded =
true;
2762 case T_through_hole_min:
2764 m_board->m_LegacyDesignSettingsLoaded =
true;
2769 case T_via_min_drill:
2771 m_board->m_LegacyDesignSettingsLoaded =
true;
2775 case T_hole_to_hole_min:
2777 m_board->m_LegacyDesignSettingsLoaded =
true;
2794 m_board->m_LegacyDesignSettingsLoaded =
true;
2801 m_board->m_LegacyDesignSettingsLoaded =
true;
2807 m_board->m_LegacyDesignSettingsLoaded =
true;
2811 case T_uvias_allowed:
2813 m_board->m_LegacyDesignSettingsLoaded =
true;
2817 case T_blind_buried_vias_allowed:
2819 m_board->m_LegacyDesignSettingsLoaded =
true;
2823 case T_uvia_min_size:
2825 m_board->m_LegacyDesignSettingsLoaded =
true;
2829 case T_uvia_min_drill:
2831 m_board->m_LegacyDesignSettingsLoaded =
true;
2835 case T_user_diff_pair:
2845 m_board->m_LegacyDesignSettingsLoaded =
true;
2850 case T_segment_width:
2852 m_board->m_LegacyDesignSettingsLoaded =
true;
2858 m_board->m_LegacyDesignSettingsLoaded =
true;
2862 case T_mod_edge_width:
2864 m_board->m_LegacyDesignSettingsLoaded =
true;
2868 case T_pcb_text_width:
2870 m_board->m_LegacyDesignSettingsLoaded =
true;
2874 case T_mod_text_width:
2876 m_board->m_LegacyDesignSettingsLoaded =
true;
2880 case T_pcb_text_size:
2883 m_board->m_LegacyDesignSettingsLoaded =
true;
2887 case T_mod_text_size:
2890 m_board->m_LegacyDesignSettingsLoaded =
true;
2896 m_board->m_LegacyDesignSettingsLoaded =
true;
2905 m_board->m_LegacyDesignSettingsLoaded =
true;
2914 m_board->m_LegacyDesignSettingsLoaded =
true;
2919 case T_pad_to_mask_clearance:
2924 case T_solder_mask_min_width:
2929 case T_pad_to_paste_clearance:
2934 case T_pad_to_paste_clearance_ratio:
2939 case T_allow_soldermask_bridges_in_footprints:
2982 case T_aux_axis_origin:
3006 case T_visible_elements:
3013 for(
size_t i = 0; i <
sizeof( int ) * CHAR_BIT; i++ )
3014 m_board->m_LegacyVisibleItems.set( i, visible & ( 1u << i ) );
3022 m_board->m_LegacyDesignSettingsLoaded =
true;
3026 case T_filled_areas_thickness:
3032 case T_pcbplotparams:
3038 parser.SyncLineReaderWith( *
this );
3040 plotParams.
Parse( &parser );
3041 SyncLineReaderWith( parser );
3043 m_board->SetPlotOptions( plotParams );
3048 m_board->GetDesignSettings().m_TentViasFront = tent;
3049 m_board->GetDesignSettings().m_TentViasBack = tent;
3054 case T_zone_defaults:
3059 Unexpected( CurText() );
3078 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3080 if( token != T_LEFT )
3082 Expecting( T_LEFT );
3093 Unexpected( CurText() );
3100 std::map<PCB_LAYER_ID, ZONE_LAYER_PROPERTIES>& aProperties )
3107 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3109 if( token != T_LEFT )
3111 Expecting( T_LEFT );
3122 case T_hatch_position:
3129 Unexpected( CurText() );
3134 aProperties.emplace( layer, properties );
3142 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3144 if( token != T_LEFT )
3145 Expecting( T_LEFT );
3151 case T_edge_clearance:
3153 m_board->m_LegacyCopperEdgeClearanceLoaded =
true;
3157 case T_copper_line_width:
3162 case T_copper_text_dims:
3166 case T_courtyard_line_width:
3171 case T_edge_cuts_line_width:
3176 case T_silk_line_width:
3181 case T_silk_text_dims:
3185 case T_fab_layers_line_width:
3190 case T_fab_layers_text_dims:
3194 case T_other_layers_line_width:
3199 case T_other_layers_text_dims:
3203 case T_dimension_units:
3209 case T_dimension_precision:
3216 Unexpected( CurText() );
3226 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3228 if( token == T_LEFT )
3248 case T_keep_upright:
3253 Expecting(
"size, thickness, italic or keep_upright" );
3261 wxCHECK_RET( CurTok() == T_net,
3262 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as net." ) );
3264 int netCode =
parseInt(
"net number" );
3266 NeedSYMBOLorNUMBER();
3267 wxString
name = FromUTF8();
3293 for(
T token = NextTok(); token != T_EOF; token = NextTok() )
3295 if( token == T_RIGHT )
3297 else if( token == T_LEFT )
3300 if( token != T_net_chain )
3307 std::vector<int> netCodes;
3308 std::vector<wxString> netNames;
3312 for(
T t = NextTok(); t != T_EOF; t = NextTok() )
3316 else if( t == T_LEFT )
3322 NeedSYMBOLorNUMBER();
3329 for(
T mt = NextTok(); mt != T_RIGHT; mt = NextTok() )
3337 if( tok == T_NUMBER )
3339 netCodes.push_back( (
int) strtol( CurText(),
nullptr, 10 ) );
3343 netNames.push_back( FromUTF8() );
3347 else if( mt == T_member )
3350 T inner = NextTok();
3351 if( inner == T_LEFT )
3353 if( inner == T_net )
3356 if( tok2 == T_NUMBER )
3357 netCodes.push_back( (
int) strtol( CurText(),
nullptr, 10 ) );
3359 netNames.push_back( FromUTF8() );
3370 case T_terminal_pad:
3373 NeedSYMBOLorNUMBER();
3374 padUuids[padCount++] =
KIID( FromUTF8() );
3389 std::vector<NETINFO_ITEM*> resolvedNets;
3391 for(
int code : netCodes )
3393 int internalCode = code;
3399 resolvedNets.push_back( net );
3402 for(
const wxString& netName : netNames )
3405 resolvedNets.push_back( net );
3410 net->SetNetChain(
name );
3412 for(
int i = 0; i < padCount && i < 2; ++i )
3414 net->SetTerminalPadUuid( i, padUuids[i] );
3417 net->SetTerminalPad( i,
pad );
3426 wxCHECK_RET( CurTok() == T_net_class,
3427 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as net class." ) );
3431 std::shared_ptr<NETCLASS> nc = std::make_shared<NETCLASS>( wxEmptyString );
3434 NeedSYMBOLorNUMBER();
3435 nc->SetName( FromUTF8() );
3437 nc->SetDescription( FromUTF8() );
3439 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3441 if( token != T_LEFT )
3442 Expecting( T_LEFT );
3472 case T_diff_pair_width:
3476 case T_diff_pair_gap:
3482 NeedSYMBOLorNUMBER();
3484 wxString netName = FromUTF8();
3491 m_board->GetDesignSettings().m_NetSettings->SetNetclassPatternAssignment(
3492 netName, nc->GetName() );
3498 Expecting(
"clearance, trace_width, via_dia, via_drill, uvia_dia, uvia_drill, "
3499 "diff_pair_width, diff_pair_gap or add_net" );
3505 std::shared_ptr<NET_SETTINGS>& netSettings =
m_board->GetDesignSettings().m_NetSettings;
3507 if( netSettings->HasNetclass( nc->GetName() ) )
3512 error.Printf(
_(
"Duplicate NETCLASS name '%s' in file '%s' at line %d, offset %d." ),
3513 nc->GetName().GetData(), CurSource().GetData(), CurLineNumber(),
3517 else if( nc->GetName() == netSettings->GetDefaultNetclass()->GetName() )
3519 netSettings->SetDefaultNetclass( nc );
3523 netSettings->SetNetclass( nc->GetName(), nc );
3530 wxCHECK_MSG( CurTok() == T_fp_arc || CurTok() == T_fp_circle || CurTok() == T_fp_curve || CurTok() == T_fp_rect
3531 || CurTok() == T_fp_line || CurTok() == T_fp_poly || CurTok() == T_fp_ellipse
3532 || CurTok() == T_fp_ellipse_arc || CurTok() == T_gr_arc || CurTok() == T_gr_circle
3533 || CurTok() == T_gr_curve || CurTok() == T_gr_rect || CurTok() == T_gr_bbox
3534 || CurTok() == T_gr_line || CurTok() == T_gr_poly || CurTok() == T_gr_vector
3535 || CurTok() == T_gr_ellipse || CurTok() == T_gr_ellipse_arc,
3536 nullptr, wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_SHAPE." ) );
3541 std::unique_ptr<PCB_SHAPE> shape = std::make_unique<PCB_SHAPE>( aParent );
3544 int ellipseMajor = 0;
3545 int ellipseMinor = 0;
3557 if( token == T_locked )
3559 shape->SetLocked(
true );
3563 if( token != T_LEFT )
3564 Expecting( T_LEFT );
3571 if( token != T_start )
3572 Expecting( T_start );
3576 shape->SetCenter( pt );
3582 if( token != T_end )
3587 shape->SetStart( pt );
3592 if( token != T_angle )
3593 Expecting( T_angle );
3600 VECTOR2I arc_start, arc_mid, arc_end;
3602 if( token != T_start )
3603 Expecting( T_start );
3611 if( token != T_mid )
3620 if( token != T_end )
3627 shape->SetArcGeometry( arc_start, arc_mid, arc_end );
3637 if( token == T_locked )
3639 shape->SetLocked(
true );
3643 if( token != T_LEFT )
3644 Expecting( T_LEFT );
3648 if( token != T_center )
3649 Expecting( T_center );
3653 shape->SetStart( pt );
3659 if( token != T_end )
3664 shape->SetEnd( pt );
3673 if( token == T_locked )
3675 shape->SetLocked(
true );
3679 if( token != T_LEFT )
3680 Expecting( T_LEFT );
3684 if( token != T_pts )
3688 shape->SetBezierC1(
parseXY());
3689 shape->SetBezierC2(
parseXY());
3693 shape->RebuildBezierToSegmentsPointsList(
m_board->GetDesignSettings().m_MaxError );
3695 shape->RebuildBezierToSegmentsPointsList(
ARC_HIGH_DEF );
3706 if( token == T_locked )
3708 shape->SetLocked(
true );
3712 if( token != T_LEFT )
3713 Expecting( T_LEFT );
3717 if( token != T_start )
3718 Expecting( T_start );
3722 shape->SetStart( pt );
3727 if( token != T_end )
3732 shape->SetEnd( pt );
3753 if( token == T_locked )
3755 shape->SetLocked(
true );
3759 if( token != T_LEFT )
3760 Expecting( T_LEFT );
3764 if( token != T_start )
3765 Expecting( T_start );
3769 shape->SetStart( pt );
3774 if( token != T_end )
3779 shape->SetEnd( pt );
3787 shape->SetPolyPoints( {} );
3793 if( token == T_locked )
3795 shape->SetLocked(
true );
3799 if( token != T_LEFT )
3800 Expecting( T_LEFT );
3804 if( token != T_pts )
3807 while( (token = NextTok() ) != T_RIGHT )
3816 case T_gr_ellipse_arc:
3822 Expecting(
"fp_arc, fp_circle, fp_curve, fp_ellipse, fp_ellipse_arc, "
3823 "fp_line, fp_poly or fp_rect" );
3827 Expecting(
"gr_arc, gr_circle, gr_curve, gr_ellipse, gr_ellipse_arc, "
3828 "gr_vector, gr_line, gr_poly, gr_rect or gr_bbox" );
3832 bool foundFill =
false;
3834 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3836 if( token != T_LEFT )
3837 Expecting( T_LEFT );
3857 case T_solder_mask_margin:
3858 shape->SetLocalSolderMaskMargin(
parseBoardUnits(
"local solder mask margin value" ) );
3875 strokeParser.SyncLineReaderWith( *
this );
3878 SyncLineReaderWith( strokeParser );
3892 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
3894 if( token == T_LEFT )
3911 default: Expecting(
"yes, no, solid, none, hatch, reverse_hatch or cross_hatch" );
3937 case T_major_radius:
3942 case T_minor_radius:
3947 case T_rotation_angle:
3963 Expecting(
"layer, width, fill, tstamp, uuid, locked, net, status, "
3964 "solder_mask_margin, center, major_radius, minor_radius, "
3965 "rotation_angle, start_angle, or end_angle" );
3976 shape->SetFilled(
true );
3981 shape->SetFilled(
true );
3987 if( stroke.
GetWidth() <= 0 && !shape->IsAnyFill() )
3992 shape->SetStroke( stroke );
3994 if( shape->GetParentFootprint() )
3995 shape->SetLibStrokeWidth( stroke.
GetWidth() );
3999 shape->SetLibraryEllipse( ellipseCenter, ellipseMajor, ellipseMinor, ellipseRotation, ellipseStart,
4002 if( shape->GetParentFootprint() )
4003 shape->RebakeFromLib();
4005 else if( shape->GetParentFootprint() )
4007 const VECTOR2I libStart = shape->GetStart();
4008 const VECTOR2I libEnd = shape->GetEnd();
4011 shape->OverrideLibCoords( libStart, libEnd, libArcMid );
4014 shape->OverrideLibBezier( shape->GetBezierC1(), shape->GetBezierC2() );
4017 shape->OverrideLibPoly( shape->GetPolyShape() );
4019 shape->RebakeFromLib();
4022 return shape.release();
4028 wxCHECK_MSG( CurTok() == T_image,
nullptr,
4029 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a reference image." ) );
4032 std::unique_ptr<PCB_REFERENCE_IMAGE> bitmap = std::make_unique<PCB_REFERENCE_IMAGE>( aParent );
4034 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4036 if( token != T_LEFT )
4037 Expecting( T_LEFT );
4048 bitmap->SetPosition( pos );
4077 data.reserve( 1 << 19 );
4079 while( token != T_RIGHT )
4081 if( !IsSymbol( token ) )
4082 Expecting(
"base64 image data" );
4088 wxMemoryBuffer buffer = wxBase64Decode( data );
4101 bitmap->SetLocked(
locked );
4116 Expecting(
"at, layer, scale, data, locked or uuid" );
4127 int legacyPPI =
image.GetLegacyPPI();
4129 if( legacyPPI > 0 &&
image.GetPPI() != legacyPPI )
4133 return bitmap.release();
4139 wxCHECK_MSG( CurTok() == T_gr_text || CurTok() == T_fp_text,
nullptr,
4140 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_TEXT." ) );
4143 std::unique_ptr<PCB_TEXT>
text;
4145 T token = NextTok();
4150 text = std::unique_ptr<PCB_TEXT>( aBaseText );
4165 text = std::make_unique<PCB_TEXT>( parentFP );
4169 THROW_IO_ERROR( wxString::Format(
_(
"Cannot handle footprint text type %s" ),
4177 text = std::make_unique<PCB_TEXT>( aParent );
4181 if( token == T_locked )
4183 text->SetLocked(
true );
4187 if( !IsSymbol( token ) && (
int) token !=
DSN_NUMBER )
4188 Expecting(
"text value" );
4190 wxString value = FromUTF8();
4191 value.Replace( wxT(
"%V" ), wxT(
"${VALUE}" ) );
4192 value.Replace( wxT(
"%R" ), wxT(
"${REFERENCE}" ) );
4193 text->SetText( value );
4211 text->SetVisible(
true );
4214 return text.release();
4221 bool hasAngle =
false;
4223 bool hasPos =
false;
4229 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
4231 if( token == T_LEFT )
4250 if( CurTok() == T_NUMBER )
4258 if( parentFP && CurTok() == T_unlocked )
4275 if( token == T_knockout )
4302 Expecting(
"layer, effects, locked, render_cache, uuid or tstamp" );
4318 Expecting(
"layer, effects, locked, render_cache or tstamp" );
4327 case T_render_cache:
4333 Expecting(
"layer, hide, effects, locked, render_cache or tstamp" );
4335 Expecting(
"layer, effects, locked, render_cache or tstamp" );
4370 wxCHECK_MSG( CurTok() == T_barcode,
nullptr,
4371 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_BARCODE." ) );
4373 std::unique_ptr<PCB_BARCODE> barcode = std::make_unique<PCB_BARCODE>( aParent );
4375 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
4377 if( token != T_LEFT )
4378 Expecting( T_LEFT );
4389 barcode->SetPosition( pos );
4392 if( CurTok() == T_NUMBER )
4408 barcode->SetWidth( w );
4409 barcode->SetHeight( h );
4416 if( NextTok() != T_STRING )
4417 Expecting( T_STRING );
4419 barcode->SetText( FromUTF8() );
4426 barcode->SetTextSize( h );
4434 std::string kind = CurText();
4435 if( kind ==
"code39" )
4437 else if( kind ==
"code128" )
4439 else if( kind ==
"datamatrix" || kind ==
"data_matrix" )
4441 else if( kind ==
"qr" || kind ==
"qrcode" )
4443 else if( kind ==
"microqr" || kind ==
"micro_qr" )
4446 Expecting(
"barcode type" );
4454 std::string ecc = CurText();
4455 if( ecc ==
"L" || ecc ==
"l" )
4457 else if( ecc ==
"M" || ecc ==
"m" )
4459 else if( ecc ==
"Q" || ecc ==
"q" )
4461 else if( ecc ==
"H" || ecc ==
"h" )
4464 Expecting(
"ecc level" );
4495 barcode->SetMargin(
VECTOR2I( marginX, marginY ) );
4501 Expecting(
"at, layer, size, text, text_height, type, ecc_level, locked, hide, knockout, margins or uuid" );
4505 barcode->AssembleBarcode();
4507 return barcode.release();
4528 aTextBox->EDA_TEXT::SetTextAngle( aTextBox->
GetTextAngle() );
4534 wxCHECK_MSG( CurTok() == T_gr_text_box || CurTok() == T_fp_text_box,
nullptr,
4535 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_TEXTBOX." ) );
4537 std::unique_ptr<PCB_TEXTBOX> textbox = std::make_unique<PCB_TEXTBOX>( aParent );
4542 return textbox.release();
4548 wxCHECK_MSG( CurTok() == T_table_cell,
nullptr,
4549 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a table cell." ) );
4551 std::unique_ptr<PCB_TABLECELL> cell = std::make_unique<PCB_TABLECELL>( aParent );
4556 return cell.release();
4567 bool foundMargins =
false;
4569 T token = NextTok();
4572 if( token == T_locked )
4578 if( !IsSymbol( token ) && (
int) token !=
DSN_NUMBER )
4579 Expecting(
"text value" );
4581 aTextBox->
SetText( FromUTF8() );
4583 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4585 if( token != T_LEFT )
4586 Expecting( T_LEFT );
4606 if( token != T_end )
4622 while( (token = NextTok() ) != T_RIGHT )
4638 strokeParser.SyncLineReaderWith( *
this );
4641 SyncLineReaderWith( strokeParser );
4656 foundMargins =
true;
4673 cell->SetColSpan(
parseInt(
"column span" ) );
4674 cell->SetRowSpan(
parseInt(
"row span" ) );
4678 Expecting(
"locked, start, pts, angle, width, stroke, border, margins, knockout, "
4679 "layer, effects, render_cache, uuid or tstamp" );
4696 case T_render_cache:
4703 Expecting(
"locked, start, pts, angle, width, margins, knockout, layer, effects, "
4704 "span, render_cache, uuid or tstamp" );
4708 Expecting(
"locked, start, pts, angle, width, stroke, border, margins, knockout,"
4709 "layer, effects, render_cache, uuid or tstamp" );
4732 wxCHECK_MSG( CurTok() == T_table,
nullptr,
4733 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as a table." ) );
4738 std::unique_ptr<PCB_TABLE>
table = std::make_unique<PCB_TABLE>( aParent, -1 );
4740 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4742 if( token != T_LEFT )
4743 Expecting( T_LEFT );
4749 case T_column_count:
4774 case T_column_widths:
4778 while( ( token = NextTok() ) != T_RIGHT )
4788 while( ( token = NextTok() ) != T_RIGHT )
4795 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4797 if( token != T_LEFT )
4798 Expecting( T_LEFT );
4802 if( token != T_table_cell )
4803 Expecting(
"table_cell" );
4811 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4813 if( token != T_LEFT )
4814 Expecting( T_LEFT );
4833 strokeParser.SyncLineReaderWith( *
this );
4836 SyncLineReaderWith( strokeParser );
4838 table->SetBorderStroke( borderStroke );
4843 Expecting(
"external, header or stroke" );
4851 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4853 if( token != T_LEFT )
4854 Expecting( T_LEFT );
4873 strokeParser.SyncLineReaderWith( *
this );
4876 SyncLineReaderWith( strokeParser );
4878 table->SetSeparatorsStroke( separatorsStroke );
4883 Expecting(
"rows, cols, or stroke" );
4891 Expecting(
"columns, layer, col_widths, row_heights, border, separators, header or "
4896 return table.release();
4902 wxCHECK_MSG( CurTok() == T_dimension,
nullptr,
4903 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as DIMENSION." ) );
4907 std::unique_ptr<PCB_DIMENSION_BASE> dim;
4912 if( token == T_locked )
4919 if( token != T_LEFT )
4924 bool isLegacyDimension =
false;
4925 bool isStyleKnown =
false;
4928 if( token == T_width )
4930 isLegacyDimension =
true;
4931 dim = std::make_unique<PCB_DIM_ALIGNED>( aParent );
4937 if( token != T_type )
4938 Expecting( T_type );
4942 case T_aligned: dim = std::make_unique<PCB_DIM_ALIGNED>( aParent );
break;
4943 case T_orthogonal: dim = std::make_unique<PCB_DIM_ORTHOGONAL>( aParent );
break;
4944 case T_leader: dim = std::make_unique<PCB_DIM_LEADER>( aParent );
break;
4945 case T_center: dim = std::make_unique<PCB_DIM_CENTER>( aParent );
break;
4946 case T_radial: dim = std::make_unique<PCB_DIM_RADIAL>( aParent );
break;
4947 default: wxFAIL_MSG( wxT(
"Cannot parse unknown dimension type " )
4948 + GetTokenString( CurTok() ) );
4958 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
4960 if( token != T_LEFT )
4961 Expecting( T_LEFT );
4986 bool is_aligned = dim->GetKeepTextAligned();
4992 dim->SetKeepTextAligned(
false );
4997 if( isLegacyDimension )
5002 dim->SetAutoUnits(
true );
5004 dim->SetUnits( units );
5009 dim->SetKeepTextAligned( is_aligned );
5010 dim->SetTextPositionMode( t_dim_pos );
5021 dim->SetStart( point );
5023 dim->SetEnd( point );
5043 case T_leader_length:
5059 int orientation =
parseInt(
"orthogonal dimension orientation" );
5065 orientation = std::clamp( orientation, 0, 1 );
5074 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5082 NeedSYMBOLorNUMBER();
5083 dim->SetPrefix( FromUTF8() );
5088 NeedSYMBOLorNUMBER();
5089 dim->SetSuffix( FromUTF8() );
5095 int mode =
parseInt(
"dimension units mode" );
5096 mode = std::max( 0, std::min( 4, mode ) );
5102 case T_units_format:
5104 int format =
parseInt(
"dimension units format" );
5105 format = std::clamp( format, 0, 3 );
5116 case T_override_value:
5117 NeedSYMBOLorNUMBER();
5118 dim->SetOverrideTextEnabled(
true );
5119 dim->SetOverrideText( FromUTF8() );
5123 case T_suppress_zeroes:
5128 std::cerr <<
"Unknown format token: " << GetTokenString( token ) << std::endl;
5129 Expecting(
"prefix, suffix, units, units_format, precision, override_value, "
5130 "suppress_zeroes" );
5138 isStyleKnown =
true;
5141 dim->SetKeepTextAligned(
false );
5143 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5151 dim->SetLineThickness(
parseBoardUnits(
"extension line thickness value" ) );
5155 case T_arrow_direction:
5159 if( token == T_inward )
5161 else if( token == T_outward )
5164 Expecting(
"inward or outward" );
5169 case T_arrow_length:
5175 case T_text_position_mode:
5177 int mode =
parseInt(
"text position mode" );
5178 mode = std::max( 0, std::min( 3, mode ) );
5184 case T_extension_height:
5187 wxCHECK_MSG( aligned,
nullptr, wxT(
"Invalid extension_height token" ) );
5193 case T_extension_offset:
5194 dim->SetExtensionOffset(
parseBoardUnits(
"extension offset value" ) );
5198 case T_keep_text_aligned:
5205 wxT(
"Invalid text_frame token" ) );
5209 int textFrame =
parseInt(
"text frame mode" );
5210 textFrame = std::clamp( textFrame, 0, 3 );
5217 Expecting(
"thickness, arrow_length, arrow_direction, text_position_mode, "
5218 "extension_height, extension_offset" );
5231 if( token != T_pts )
5237 dim->SetStart( point );
5251 if( token != T_pts )
5257 dim->SetEnd( point );
5271 if( token == T_pts )
5293 if( token != T_pts )
5307 if( token != T_pts )
5321 if( token != T_pts )
5335 if( token != T_pts )
5349 dim->SetLocked( isLocked );
5354 Expecting(
"layer, tstamp, uuid, gr_text, feature1, feature2, crossbar, arrow1a, "
5355 "arrow1b, arrow2a, or arrow2b" );
5360 dim->SetLocked(
true );
5364 return dim.release();
5386 wxCHECK_MSG( CurTok() == T_module || CurTok() == T_footprint,
nullptr,
5387 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as FOOTPRINT." ) );
5394 double parsedScaleX = 1.0;
5395 double parsedScaleY = 1.0;
5397 std::unique_ptr<FOOTPRINT> footprint = std::make_unique<FOOTPRINT>(
m_board );
5399 footprint->SetInitialComments( aInitialComments );
5403 footprint->SetStaticComponentClass(
5404 m_board->GetComponentClassManager().GetNoneComponentClass() );
5409 if( !IsSymbol( token ) && token != T_NUMBER )
5410 Expecting(
"symbol|number" );
5416 THROW_IO_ERROR( wxString::Format(
_(
"Invalid footprint ID in\nfile: %s\nline: %d\n"
5418 CurSource(), CurLineNumber(), CurOffset() ) );
5431 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5433 if( token == T_LEFT )
5443 int this_version =
parseInt( FromUTF8().mb_str( wxConvUTF8 ) );
5448 footprint->SetFileFormatVersionAtLoad( this_version );
5459 case T_generator_version:
5512 footprint->SetPosition( pt );
5515 if( token == T_NUMBER )
5520 else if( token != T_RIGHT )
5522 Expecting( T_RIGHT );
5532 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5534 if( token != T_LEFT )
5535 Expecting( T_LEFT );
5558 if( !std::isfinite( parsedScaleX ) || parsedScaleX <= 0.0 )
5561 if( !std::isfinite( parsedScaleY ) || parsedScaleY <= 0.0 )
5568 Expecting(
"translate, rotate, or scale" );
5572 footprint->SetPosition( trsTranslate );
5573 footprint->SetOrientation( trsRotate );
5574 footprint->SetTransformScale( parsedScaleX, parsedScaleY );
5579 NeedSYMBOLorNUMBER();
5580 footprint->SetLibDescription( FromUTF8() );
5585 NeedSYMBOLorNUMBER();
5586 footprint->SetKeywords( FromUTF8() );
5593 wxString pName = FromUTF8();
5595 wxString pValue = FromUTF8();
5603 if( pName ==
"ki_keywords" || pName ==
"ki_locked" )
5611 if( pName ==
"ki_description" )
5619 if( pName ==
"Sheetfile" || pName ==
"Sheet file" )
5621 footprint->SetSheetfile( pValue );
5626 if( pName ==
"Sheetname" || pName ==
"Sheet name" )
5628 footprint->SetSheetname( pValue );
5635 std::unique_ptr<PCB_FIELD> unusedField;
5639 if( pName ==
"ki_fp_filters" )
5641 footprint->SetFilters( pValue );
5646 unusedField = std::make_unique<PCB_FIELD>( footprint.get(),
FIELD_T::USER );
5647 field = unusedField.get();
5649 else if( pName ==
"Footprint" )
5655 field = unusedField.get();
5657 else if( footprint->HasField( pName ) )
5659 field = footprint->GetField( pName );
5665 footprint->Add( field );
5686 NeedSYMBOLorNUMBER();
5687 footprint->SetPath(
KIID_PATH( FromUTF8() ) );
5693 footprint->SetSheetname( FromUTF8() );
5699 footprint->SetSheetfile( FromUTF8() );
5705 std::vector<FOOTPRINT::FP_UNIT_INFO> unitInfos;
5708 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5710 if( token == T_LEFT )
5713 if( token == T_unit )
5717 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5719 if( token == T_LEFT )
5722 if( token == T_name )
5724 NeedSYMBOLorNUMBER();
5725 info.m_unitName = FromUTF8();
5728 else if( token == T_pins )
5731 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5733 if( token == T_STRING || token == T_NUMBER )
5735 info.m_pins.emplace_back( FromUTF8() );
5739 Expecting(
"pin number" );
5750 unitInfos.push_back(
info );
5759 if( !unitInfos.empty() )
5760 footprint->SetUnitInfo( unitInfos );
5765 case T_autoplace_cost90:
5766 case T_autoplace_cost180:
5767 parseInt(
"legacy auto-place cost" );
5771 case T_private_layers:
5775 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5780 privateLayers.
set( it->second );
5782 Expecting(
"layer name" );
5791 footprint->SetPrivateLayers( privateLayers );
5795 case T_net_tie_pad_groups:
5796 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5797 footprint->AddNetTiePadGroup( CurStr() );
5801 case T_duplicate_pad_numbers_are_jumpers:
5802 footprint->SetDuplicatePadNumbersAreJumpers(
parseBool() );
5806 case T_jumper_pad_groups:
5809 std::vector<std::set<wxString>>& groups = footprint->JumperPadGroups();
5810 std::set<wxString>* currentGroup =
nullptr;
5812 for( token = NextTok(); currentGroup || token != T_RIGHT; token = NextTok() )
5814 switch(
static_cast<int>( token ) )
5817 currentGroup = &groups.emplace_back();
5822 currentGroup->insert( FromUTF8() );
5827 currentGroup =
nullptr;
5831 Expecting(
"list of pad names" );
5838 case T_solder_mask_margin:
5839 footprint->SetLocalSolderMaskMargin(
parseBoardUnits(
"local solder mask margin value" ) );
5844 footprint->SetLocalSolderMaskMargin( {} );
5848 case T_solder_paste_margin:
5849 footprint->SetLocalSolderPasteMargin(
parseBoardUnits(
"local solder paste margin value" ) );
5854 footprint->SetLocalSolderPasteMargin( {} );
5858 case T_solder_paste_ratio:
5859 case T_solder_paste_margin_ratio:
5860 footprint->SetLocalSolderPasteMarginRatio(
parseDouble(
"local solder paste margin ratio value" ) );
5865 footprint->SetLocalSolderPasteMarginRatio( {} );
5870 footprint->SetLocalClearance(
parseBoardUnits(
"local clearance value" ) );
5875 footprint->SetLocalClearance( {} );
5879 case T_zone_connect:
5884 case T_thermal_width:
5892 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
5900 case T_through_hole:
5912 case T_exclude_from_pos_files:
5916 case T_exclude_from_bom:
5920 case T_allow_missing_courtyard:
5921 footprint->SetAllowMissingCourtyard(
true );
5928 case T_allow_soldermask_bridges:
5929 footprint->SetAllowSolderMaskBridges(
true );
5933 Expecting(
"through_hole, smd, virtual, board_only, exclude_from_pos_files, "
5934 "exclude_from_bom or allow_solder_mask_bridges" );
5937 footprint->SetAttributes( attributes );
5946 switch( field->GetId() )
5950 footprint->Reference().SetUuidDirect(
text->m_Uuid );
5956 footprint->Value().SetUuidDirect(
text->m_Uuid );
5997 case T_fp_ellipse_arc:
6036 if( token == T_LEFT )
6041 if( token != T_type )
6042 Expecting( T_type );
6046 if( CurTok() == T_extruded )
6052 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6054 if( token != T_LEFT )
6055 Expecting( T_LEFT );
6068 case T_overall_height:
6073 case T_body_pcb_gap:
6081 wxString layerName =
From_UTF8( CurText() );
6083 if( layerName == wxT(
"auto" ) )
6087 else if( layerName == wxT(
"pad_bbox" ) )
6106 wxString matName =
From_UTF8( CurText() );
6108 if( matName == wxT(
"matte" ) )
6110 else if( matName == wxT(
"metal" ) )
6112 else if( matName == wxT(
"copper" ) )
6123 NeedSYMBOLorNUMBER();
6124 wxString first =
From_UTF8( CurText() );
6126 if( first == wxT(
"unspecified" ) )
6146 if( token != T_xyz )
6160 if( token != T_xyz )
6174 if( token != T_xyz )
6185 Expecting(
"hide, overall_height, body_pcb_gap, layer, material, "
6186 "color, offset, scale, or rotate" );
6192 Expecting(
"extruded" );
6199 footprint->Add3DModel(
model );
6244 case T_embedded_fonts:
6246 footprint->GetEmbeddedFiles()->SetAreFontsEmbedded(
parseBool() );
6251 case T_embedded_files:
6254 embeddedFilesParser.SyncLineReaderWith( *
this );
6258 embeddedFilesParser.
ParseEmbedded( footprint->GetEmbeddedFiles() );
6266 for(
int tok = embeddedFilesParser.NextTok();
6268 tok = embeddedFilesParser.NextTok() )
6272 else if( tok ==
DSN_RIGHT && --depth < 0 )
6277 SyncLineReaderWith( embeddedFilesParser );
6281 case T_component_classes:
6283 std::unordered_set<wxString> componentClassNames;
6285 while( ( token = NextTok() ) != T_RIGHT )
6287 if( token != T_LEFT )
6288 Expecting( T_LEFT );
6290 if( ( token = NextTok() ) != T_class )
6291 Expecting( T_class );
6293 NeedSYMBOLorNUMBER();
6294 componentClassNames.insert(
From_UTF8( CurText() ) );
6298 footprint->SetTransientComponentClassNames( componentClassNames );
6301 footprint->ResolveComponentClassNames(
m_board, componentClassNames );
6311 Expecting(
"at, descr, locked, placed, tedit, tstamp, uuid, variant, "
6312 "autoplace_cost90, autoplace_cost180, attr, clearance, "
6313 "embedded_files, fp_arc, fp_circle, fp_curve, fp_line, fp_poly, "
6314 "fp_rect, fp_text, pad, group, generator, model, path, solder_mask_margin, "
6315 "solder_paste_margin, solder_paste_margin_ratio, tags, thermal_gap, "
6316 "version, zone, zone_connect, or component_classes" );
6320 footprint->FixUpPadsForBoard(
m_board );
6332 if( footprint->GetKeywords().StartsWith( wxT(
"net tie" ) ) )
6336 for(
PAD*
pad : footprint->Pads() )
6338 if( !padGroup.IsEmpty() )
6339 padGroup += wxS(
", " );
6341 padGroup +=
pad->GetNumber();
6344 if( !padGroup.IsEmpty() )
6345 footprint->AddNetTiePadGroup( padGroup );
6349 footprint->SetAttributes( attributes );
6351 footprint->SetFPID( fpid );
6353 return footprint.release();
6359 wxCHECK_RET( CurTok() == T_stackup,
"Expected stackup token" );
6365 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
6367 if( CurTok() != T_LEFT )
6368 Expecting( T_LEFT );
6376 NeedSYMBOLorNUMBER();
6381 Expecting(
"layer name" );
6385 layers.
set( it->second );
6393 Expecting(
"layer" );
6403 if( gotCuLayers.count() % 2 != 0 )
6406 "odd number of copper layers (%d)." ),
6407 gotCuLayers.count() ) );
6411 if( gotCuLayers != expectedCuLayers )
6414 "copper layers are not contiguous." ) ) );
6420 "technology layers are implicit in footprints and "
6421 "should not be specified in the stackup." ) ) );
6432 wxCHECK_MSG( CurTok() == T_pad,
nullptr,
6433 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PAD." ) );
6437 bool foundNet =
false;
6438 bool foundNetcode =
false;
6440 std::unique_ptr<PAD>
pad = std::make_unique<PAD>( aParent );
6442 NeedSYMBOLorNUMBER();
6443 pad->SetNumber( FromUTF8() );
6445 T token = NextTok();
6474 case T_np_thru_hole:
6479 Expecting(
"thru_hole, smd, connect, or np_thru_hole" );
6513 Expecting(
"circle, rectangle, roundrect, oval, trapezoid or custom" );
6516 std::optional<EDA_ANGLE> thermalBrAngleOverride;
6518 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6520 if( token == T_locked )
6526 if( token != T_LEFT )
6527 Expecting( T_LEFT );
6543 pad->SetFPRelativePosition( pt );
6549 if( token == T_NUMBER )
6554 else if( token == T_RIGHT )
6560 Expecting(
") or angle value" );
6577 bool haveWidth =
false;
6580 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6582 if( token == T_LEFT )
6596 drillSize.
y = drillSize.
x;
6615 Expecting(
"oval, size, or offset" );
6624 pad->SetLibDrillSize( drillSize );
6636 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6638 if( token != T_LEFT )
6639 Expecting( T_LEFT );
6664 Expecting(
"size or layers" );
6671 case T_tertiary_drill:
6676 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6678 if( token != T_LEFT )
6679 Expecting( T_LEFT );
6704 Expecting(
"size or layers" );
6715 pad->SetLayerSet( layerMask );
6731 _(
"Invalid net ID in\nfile: %s\nline: %d offset: %d" ),
6732 CurSource(), CurLineNumber(), CurOffset() );
6736 foundNetcode =
true;
6742 if( !IsSymbol( token ) )
6744 Expecting(
"net name" );
6750 wxString netName( FromUTF8() );
6759 if( netName !=
m_board->FindNet(
pad->GetNetCode() )->GetNetname() )
6763 _(
"Net name doesn't match ID in\nfile: %s\nline: %d offset: %d" ),
6764 CurSource(), CurLineNumber(), CurOffset() );
6777 pad->SetNet( netinfo );
6785 NeedSYMBOLorNUMBER();
6786 pad->SetPinFunction( FromUTF8() );
6791 NeedSYMBOLorNUMBER();
6792 pad->SetPinType( FromUTF8() );
6796 case T_sim_electrical_type:
6804 default: Expecting(
"sink or source" );
6827 case T_solder_mask_margin:
6828 pad->SetLocalSolderMaskMargin(
parseBoardUnits(
"local solder mask margin value" ) );
6833 pad->SetLocalSolderMaskMargin( {} );
6837 case T_solder_paste_margin:
6838 pad->SetLocalSolderPasteMargin(
parseBoardUnits(
"local solder paste margin value" ) );
6843 pad->SetLocalSolderPasteMargin( {} );
6847 case T_solder_paste_margin_ratio:
6848 pad->SetLocalSolderPasteMarginRatio(
parseDouble(
"local solder paste margin ratio value" ) );
6853 pad->SetLocalSolderPasteMarginRatio( {} );
6863 pad->SetLocalClearance( {} );
6871 case T_zone_connect:
6876 case T_thermal_width:
6877 case T_thermal_bridge_width:
6882 case T_thermal_bridge_angle:
6893 case T_roundrect_rratio:
6899 case T_chamfer_ratio:
6911 bool end_list =
false;
6931 case T_bottom_right:
6941 Expecting(
"chamfer_top_left chamfer_top_right chamfer_bottom_left or "
6942 "chamfer_bottom_right" );
6953 while( token != T_RIGHT )
6968 case T_RIGHT:
break;
6972 Expecting(
"pad_prop_bga pad_prop_fiducial_glob pad_prop_fiducial_loc"
6973 " pad_prop_heatsink or pad_prop_castellated" );
6990 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
6992 if( token == T_LEFT )
7023 Expecting(
"gr_line, gr_arc, gr_circle, gr_curve, gr_rect, gr_bbox or gr_poly" );
7030 case T_remove_unused_layers:
7033 pad->SetRemoveUnconnected( remove );
7037 case T_keep_end_layers:
7040 pad->SetKeepTopBottom( keep );
7047 pad->Padstack().FrontOuterLayers().has_solder_mask = front;
7048 pad->Padstack().BackOuterLayers().has_solder_mask = back;
7052 case T_zone_layer_connections:
7059 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7064 Expecting(
"copper layer name" );
7085 case T_front_post_machining:
7089 case T_back_post_machining:
7094 Expecting(
"at, locked, drill, layers, net, die_length, roundrect_rratio, "
7095 "solder_mask_margin, solder_paste_margin, solder_paste_margin_ratio, uuid, "
7096 "clearance, tstamp, primitives, remove_unused_layers, keep_end_layers, "
7097 "pinfunction, pintype, zone_connect, thermal_width, thermal_gap, padstack, "
7098 "teardrops, front_post_machining, or back_post_machining" );
7105 pad->SetNetCode( 0,
true );
7108 if( thermalBrAngleOverride )
7110 pad->SetThermalSpokeAngle( *thermalBrAngleOverride );
7133 if( !
pad->CanHaveNumber() )
7137 pad->SetNumber( wxEmptyString );
7141 if(
pad->GetSizeX() <= 0 ||
pad->GetSizeY() <= 0 )
7147 wxString::Format(
_(
"Invalid zero-sized pad pinned to %s in\nfile: %s\nline: %d\noffset: %d" ),
7148 wxT(
"1µm" ), CurSource(), CurLineNumber(), CurOffset() ) );
7151 return pad.release();
7158 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
7160 if( token != T_LEFT )
7161 Expecting( T_LEFT );
7182 Expecting(
"circle or rect" );
7203 Expecting(
"outline or convexhull" );
7211 Expecting(
"anchor or clearance" );
7225 T token = NextTok();
7238 Expecting(
"counterbore or countersink" );
7242 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7244 if( token != T_LEFT )
7245 Expecting( T_LEFT );
7267 Expecting(
"size, depth, or angle" );
7277 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
7279 if( token != T_LEFT )
7280 Expecting( T_LEFT );
7291 case T_front_inner_back:
7300 Expecting(
"front_inner_back or custom" );
7311 if( curText ==
"Inner" )
7315 THROW_IO_ERROR( wxString::Format(
_(
"Invalid padstack layer in\nfile: %s\n"
7316 "line: %d\noffset: %d." ),
7317 CurSource(), CurLineNumber(), CurOffset() ) );
7330 error.Printf(
_(
"Invalid padstack layer '%s' in file '%s' at line %d, offset %d." ),
7331 curText, CurSource().GetData(), CurLineNumber(), CurOffset() );
7339 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7341 if( token != T_LEFT )
7342 Expecting( T_LEFT );
7380 Expecting(
"circle, rectangle, roundrect, oval, trapezoid or custom" );
7416 case T_roundrect_rratio:
7421 case T_chamfer_ratio:
7436 bool end_list =
false;
7456 case T_bottom_right:
7466 Expecting(
"chamfer_top_left chamfer_top_right chamfer_bottom_left or "
7467 "chamfer_bottom_right" );
7477 case T_thermal_bridge_width:
7487 case T_thermal_bridge_angle:
7492 case T_zone_connect:
7494 magic_enum::enum_cast<ZONE_CONNECTION>(
parseInt(
"zone connection value" ) );
7514 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7516 if( token != T_LEFT )
7517 Expecting( T_LEFT );
7556 while( ( token = NextTok() ) != T_RIGHT )
7569 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7571 if( token == T_LEFT )
7602 Expecting(
"gr_line, gr_arc, gr_circle, gr_curve, gr_rect, gr_bbox or gr_poly" );
7619 Expecting(
"mode or layer" );
7630 while( ( token = NextTok() ) != T_RIGHT )
7635 KIID uuid( CurStr() );
7643 wxCHECK_RET( CurTok() == T_group,
7644 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_GROUP." ) );
7650 groupInfo.
parent = aParent;
7652 while( ( token = NextTok() ) != T_LEFT )
7654 if( token == T_STRING )
7655 groupInfo.
name = FromUTF8();
7656 else if( token == T_locked )
7659 Expecting(
"group name or locked" );
7662 for( ; token != T_RIGHT; token = NextTok() )
7664 if( token != T_LEFT )
7665 Expecting( T_LEFT );
7683 if( !IsSymbol( token ) && token != T_NUMBER )
7684 Expecting(
"symbol|number" );
7686 wxString
name = FromUTF8();
7690 name.Replace(
"{slash}",
"/" );
7696 if(
static_cast<int>(
name.size() ) > bad_pos )
7698 wxString msg = wxString::Format(
_(
"Group library link %s contains invalid character '%c'" ),
7705 THROW_PARSE_ERROR(
_(
"Invalid library ID" ), CurSource(), CurLine(), CurLineNumber(), CurOffset() );
7722 Expecting(
"uuid, locked, lib_id, or members" );
7730 wxCHECK_RET( CurTok() == T_generated,
7731 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_GENERATOR." ) );
7739 genInfo.
parent = aParent;
7746 if( token != T_uuid && token != T_id )
7747 Expecting( T_uuid );
7753 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7755 if( token != T_LEFT )
7756 Expecting( T_LEFT );
7770 genInfo.
name = FromUTF8();
7776 genInfo.
locked = token == T_yes;
7791 wxString pName = FromUTF8();
7797 genInfo.
properties.emplace( pName, wxAny(
true ) );
7802 genInfo.
properties.emplace( pName, wxAny(
false ) );
7809 genInfo.
properties.emplace( pName, wxAny( pValue ) );
7816 wxString pValue = FromUTF8();
7836 genInfo.
properties.emplace( pName, wxAny( pt ) );
7846 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7855 Expecting(
"xy or pts" );
7862 Expecting(
"a number, symbol, string or (" );
7878 wxCHECK_MSG( CurTok() == T_arc,
nullptr,
7879 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as ARC." ) );
7884 std::unique_ptr<PCB_ARC> arc = std::make_unique<PCB_ARC>(
m_board );
7886 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7889 if( token == T_locked )
7891 arc->SetLocked(
true );
7895 if( token != T_LEFT )
7896 Expecting( T_LEFT );
7905 arc->SetStart( pt );
7937 case T_solder_mask_margin:
7938 arc->SetLocalSolderMaskMargin(
parseBoardUnits(
"local solder mask margin value" ) );
7964 Expecting(
"start, mid, end, width, layer, solder_mask_margin, net, tstamp, uuid or status" );
7974 return arc.release();
7980 wxCHECK_MSG( CurTok() == T_segment,
nullptr,
7981 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_TRACK." ) );
7986 std::unique_ptr<PCB_TRACK> track = std::make_unique<PCB_TRACK>(
m_board );
7988 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
7991 if( token == T_locked )
7993 track->SetLocked(
true );
7997 if( token != T_LEFT )
7998 Expecting( T_LEFT );
8007 track->SetStart( pt );
8014 track->SetEnd( pt );
8032 case T_solder_mask_margin:
8033 track->SetLocalSolderMaskMargin(
parseBoardUnits(
"local solder mask margin value" ) );
8059 Expecting(
"start, end, width, layer, solder_mask_margin, net, tstamp, uuid or locked" );
8069 return track.release();
8075 wxCHECK_MSG( CurTok() == T_via,
nullptr,
8076 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_VIA." ) );
8081 std::unique_ptr<PCB_VIA>
via = std::make_unique<PCB_VIA>(
m_board );
8090 via->Padstack().FrontOuterLayers().has_covering =
false;
8091 via->Padstack().BackOuterLayers().has_covering =
false;
8092 via->Padstack().FrontOuterLayers().has_plugging =
false;
8093 via->Padstack().BackOuterLayers().has_plugging =
false;
8094 via->Padstack().Drill().is_filled =
false;
8095 via->Padstack().Drill().is_capped =
false;
8098 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
8101 if( token == T_locked )
8103 via->SetLocked(
true );
8107 if( token == T_LEFT )
8127 via->SetStart( pt );
8149 via->SetLayerPair( layer1, layer2 );
8152 Expecting(
"layer name" );
8162 case T_remove_unused_layers:
8164 via->SetRemoveUnconnected(
true );
8168 case T_keep_end_layers:
8170 via->SetKeepStartEnd(
true );
8174 case T_start_end_only:
8180 case T_zone_layer_connections:
8188 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
8193 Expecting(
"copper layer name" );
8212 via->Padstack().FrontOuterLayers().has_solder_mask = front;
8213 via->Padstack().BackOuterLayers().has_solder_mask = back;
8220 via->Padstack().FrontOuterLayers().has_covering = front;
8221 via->Padstack().BackOuterLayers().has_covering = back;
8228 via->Padstack().FrontOuterLayers().has_plugging = front;
8229 via->Padstack().BackOuterLayers().has_plugging = back;
8269 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
8271 if( token != T_LEFT )
8272 Expecting( T_LEFT );
8297 Expecting(
"size or layers" );
8304 case T_tertiary_drill:
8309 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
8311 if( token != T_LEFT )
8312 Expecting( T_LEFT );
8337 Expecting(
"size or layers" );
8344 case T_front_post_machining:
8348 case T_back_post_machining:
8353 Expecting(
"blind, micro, at, size, drill, layers, net, free, tstamp, uuid, status, "
8354 "teardrops, backdrill, tertiary_drill, front_post_machining, or "
8355 "back_post_machining" );
8359 return via.release();
8363std::pair<std::optional<bool>, std::optional<bool>>
8366 T token = NextTok();
8368 std::optional<bool> front{};
8369 std::optional<bool> back{};
8371 if( token != T_LEFT && aAllowLegacyFormat )
8374 while( token != T_RIGHT )
8376 if( token == T_front )
8380 else if( token == T_back )
8384 else if( token == T_none )
8391 Expecting(
"front, back or none" );
8399#if defined( __GNUC__ ) && !defined( __clang__ )
8400#pragma GCC diagnostic push
8401#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
8403 return { front, back };
8404#if defined( __GNUC__ ) && !defined( __clang__ )
8405#pragma GCC diagnostic pop
8409 while( token != T_RIGHT )
8411 if( token != T_LEFT )
8416 if( token == T_front )
8418 else if( token == T_back )
8421 Expecting(
"front or back" );
8428 return { front, back };
8436 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
8438 if( token != T_LEFT )
8439 Expecting( T_LEFT );
8450 case T_front_inner_back:
8459 Expecting(
"front_inner_back or custom" );
8470 if( curText ==
"Inner" )
8474 THROW_IO_ERROR( wxString::Format(
_(
"Invalid padstack layer in\nfile: %s\n"
8475 "line: %d\noffset: %d." ),
8476 CurSource(), CurLineNumber(), CurOffset() ) );
8489 error.Printf(
_(
"Invalid padstack layer '%s' in file '%s' at line %d, offset %d." ),
8490 curText, CurSource().GetData(), CurLineNumber(), CurOffset() );
8494 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
8496 if( token != T_LEFT )
8497 Expecting( T_LEFT );
8507 padstack.
SetSize( { diameter, diameter }, curLayer );
8514 Expecting(
"size" );
8522 Expecting(
"mode or layer" );
8531 wxCHECK_MSG( CurTok() == T_zone,
nullptr,
8532 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as ZONE." ) );
8539 wxString legacyNetnameFromFile;
8542 std::map<PCB_LAYER_ID, SHAPE_POLY_SET> pts;
8543 std::map<PCB_LAYER_ID, std::vector<SEG>> legacySegs;
8545 bool addedFilledPolygons =
false;
8551 std::unique_ptr<ZONE> zone = std::make_unique<ZONE>( aParent );
8553 zone->SetAssignedPriority( 0 );
8558 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
8561 if( token == T_locked )
8563 zone->SetLocked(
true );
8567 if( token == T_LEFT )
8577 NeedSYMBOLorNUMBER();
8578 legacyNetnameFromFile = FromUTF8();
8605 if( token != T_none && token != T_edge && token != T_full )
8606 Expecting(
"none, edge, or full" );
8621 zone->SetAssignedPriority(
parseInt(
"zone priority" ) );
8625 case T_connect_pads:
8626 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
8628 if( token == T_LEFT )
8641 case T_thru_hole_only:
8651 Expecting(
"yes, no, or clearance" );
8657 case T_min_thickness:
8662 case T_filled_areas_thickness:
8669 isStrokedFill =
false;
8675 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
8677 if( token == T_LEFT )
8683 zone->SetIsFilled(
true );
8689 if( token != T_segment && token != T_hatch && token != T_polygon
8690 && token != T_thieving )
8692 Expecting(
"segment, hatch, polygon or thieving" );
8704 Expecting(
"segment, hatch or polygon "
8705 "(thieving requires file version >= 20260513)" );
8721 case T_hatch_thickness:
8731 case T_hatch_orientation:
8734 zone->SetHatchOrientation( orientation );
8739 case T_hatch_smoothing_level:
8740 zone->SetHatchSmoothingLevel(
parseDouble( T_hatch_smoothing_level ) );
8744 case T_hatch_smoothing_value:
8745 zone->SetHatchSmoothingValue(
parseDouble( T_hatch_smoothing_value ) );
8749 case T_hatch_border_algorithm:
8752 if( token != T_hatch_thickness && token != T_min_thickness )
8753 Expecting(
"hatch_thickness or min_thickness" );
8755 zone->SetHatchBorderAlgorithm( token == T_hatch_thickness ? 1 : 0 );
8759 case T_hatch_min_hole_area:
8760 zone->SetHatchHoleMinArea(
parseDouble( T_hatch_min_hole_area ) );
8768 Expecting(
"thieving requires file version >= 20260513" );
8773 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
8775 if( token == T_LEFT )
8788 default: Expecting(
"dots, squares or hatch" );
8843 Expecting(
"type, size, gap, width, stagger or orientation" );
8847 zone->SetThievingSettings( thieving );
8851 case T_arc_segments:
8861 case T_thermal_bridge_width:
8862 zone->SetThermalReliefSpokeWidth(
parseBoardUnits( T_thermal_bridge_width ) );
8874 if( !zone->GetIsRuleArea() )
8880 if( !zone->GetIsRuleArea() )
8886 Expecting(
"none, chamfer, or fillet" );
8895 if( !zone->GetIsRuleArea() )
8896 zone->SetCornerRadius( tmp );
8901 case T_island_removal_mode:
8902 tmp =
parseInt(
"island_removal_mode" );
8904 if( tmp >= 0 && tmp <= 2 )
8910 case T_island_area_min:
8913 zone->SetMinIslandArea( area *
pcbIUScale.IU_PER_MM );
8919 Expecting(
"mode, arc_segments, thermal_gap, thermal_bridge_width, "
8920 "hatch_thickness, hatch_gap, hatch_orientation, "
8921 "hatch_smoothing_level, hatch_smoothing_value, "
8922 "hatch_border_algorithm, hatch_min_hole_area, thieving, "
8923 "smoothing, radius, island_removal_mode, or island_area_min" );
8930 zone->SetIsRuleArea(
true );
8932 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
8934 if( token == T_LEFT )
8943 zone->SetPlacementAreaSource( FromUTF8() );
8946 case T_component_class:
8950 zone->SetPlacementAreaSource( FromUTF8() );
8957 zone->SetPlacementAreaSource( FromUTF8() );
8964 if( token == T_yes )
8965 zone->SetPlacementAreaEnabled(
true );
8966 else if( token == T_no )
8967 zone->SetPlacementAreaEnabled(
false );
8969 Expecting(
"yes or no" );
8975 Expecting(
"enabled, sheetname, component_class, or group" );
8987 zone->SetIsRuleArea(
true );
8990 zone->SetDoNotAllowPads(
false );
8991 zone->SetDoNotAllowFootprints(
false );
8993 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
8995 if( token == T_LEFT )
9003 if( token != T_allowed && token != T_not_allowed )
9004 Expecting(
"allowed or not_allowed" );
9006 zone->SetDoNotAllowTracks( token == T_not_allowed );
9012 if( token != T_allowed && token != T_not_allowed )
9013 Expecting(
"allowed or not_allowed" );
9015 zone->SetDoNotAllowVias( token == T_not_allowed );
9021 if( token != T_allowed && token != T_not_allowed )
9022 Expecting(
"allowed or not_allowed" );
9024 zone->SetDoNotAllowZoneFills( token == T_not_allowed );
9030 if( token != T_allowed && token != T_not_allowed )
9031 Expecting(
"allowed or not_allowed" );
9033 zone->SetDoNotAllowPads( token == T_not_allowed );
9039 if( token != T_allowed && token != T_not_allowed )
9040 Expecting(
"allowed or not_allowed" );
9042 zone->SetDoNotAllowFootprints( token == T_not_allowed );
9046 Expecting(
"tracks, vias or copperpour" );
9061 if( token != T_pts )
9064 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
9076 zone->AddPolygon( outline );
9080 case T_filled_polygon:
9086 if( token == T_layer )
9092 if( token != T_LEFT )
9093 Expecting( T_LEFT );
9100 filledLayer = zone->GetFirstLayer();
9103 bool island =
false;
9105 if( token == T_island )
9112 if( token != T_pts )
9115 if( !pts.count( filledLayer ) )
9124 zone->SetIsIsland( filledLayer, idx );
9126 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
9131 addedFilledPolygons |= !poly.
IsEmpty();
9136 case T_fill_segments:
9140 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
9142 if( token != T_LEFT )
9143 Expecting( T_LEFT );
9147 if( token != T_pts )
9151 filledLayer = zone->GetFirstLayer();
9158 legacySegs[filledLayer].push_back( fillSegment );
9168 zone->SetZoneName( FromUTF8() );
9173 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
9175 if( token == T_LEFT )
9181 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
9183 if( token == T_LEFT )
9191 if( token == T_padvia )
9193 else if( token == T_track_end )
9196 Expecting(
"padvia or track_end" );
9202 Expecting(
"type" );
9209 Expecting(
"teardrop" );
9220 Expecting(
"net, layer/layers, tstamp, hatch, priority, connect_pads, min_thickness, "
9221 "fill, polygon, filled_polygon, fill_segments, attr, locked, uuid, or name" );
9225 if( zone->GetNumCorners() > 2 )
9227 if( !zone->IsOnCopperLayer() )
9234 zone->SetBorderDisplayStyle( hatchStyle, hatchPitch,
true );
9237 if( addedFilledPolygons )
9239 if( isStrokedFill && !zone->GetIsRuleArea() )
9243 m_parseWarnings.push_back(
_(
"Legacy zone fill strategy is not supported anymore.\n"
9244 "Zone fills will be converted on best-effort basis." ) );
9249 if( zone->GetMinThickness() > 0 )
9251 for(
auto& [layer, polyset] : pts )
9253 polyset.InflateWithLinkedHoles( zone->GetMinThickness() / 2,
9260 for(
auto& [layer, polyset] : pts )
9261 zone->SetFilledPolysList( layer, polyset );
9263 zone->CalculateFilledArea();
9265 else if( legacySegs.size() > 0 )
9273 m_parseWarnings.push_back(
_(
"The legacy segment zone fill mode is no longer supported.\n"
9274 "Zone fills will be converted on a best-effort basis." ) );
9280 for(
const auto& [layer, segments] : legacySegs )
9284 if( zone->HasFilledPolysForLayer( layer ) )
9287 for(
const auto& seg : segments )
9298 zone->SetFilledPolysList( layer, layerFill );
9299 zone->CalculateFilledArea();
9307 bool zone_has_net = zone->IsOnCopperLayer() && !zone->GetIsRuleArea();
9313 if( !legacyNetnameFromFile.IsEmpty() && zone->GetNetname() != legacyNetnameFromFile )
9326 int newnetcode =
m_board->GetNetCount();
9339 m_board->SetLegacyTeardrops(
true );
9342 zone->SetNeedRefill(
false );
9344 return zone.release();
9350 wxCHECK_MSG( CurTok() == T_point,
nullptr,
9351 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_POINT." ) );
9353 std::unique_ptr<PCB_POINT> point = std::make_unique<PCB_POINT>(
nullptr );
9355 for(
T token = NextTok(); token != T_RIGHT; token = NextTok() )
9357 if( token == T_LEFT )
9367 point->SetPosition( pt );
9390 default: Expecting(
"at, size, layer or uuid" );
9394 return point.release();
9400 wxCHECK_MSG( CurTok() == T_target,
nullptr,
9401 wxT(
"Cannot parse " ) + GetTokenString( CurTok() ) + wxT(
" as PCB_TARGET." ) );
9406 std::unique_ptr<PCB_TARGET> target = std::make_unique<PCB_TARGET>(
nullptr );
9408 for( token = NextTok(); token != T_RIGHT; token = NextTok() )
9410 if( token == T_LEFT )
9416 target->SetShape( 1 );
9420 target->SetShape( 0 );
9426 target->SetPosition( pt );
9453 Expecting(
"x, plus, at, size, width, layer, uuid, or tstamp" );
9457 return target.release();
9464 std::string idStr( CurStr() );
9467 if( *idStr.begin() ==
'"' && *idStr.rbegin() ==
'"' )
9468 idStr = idStr.substr( 1, idStr.length() - 1 );
9477 aId =
KIID( idStr );
constexpr int ARC_HIGH_DEF
constexpr EDA_IU_SCALE pcbIUScale
#define DEFAULT_LINE_WIDTH
@ ZLO_FORCE_NO_ZONE_CONNECTION
@ BS_EDGE_CONNECTOR_BEVELLED
@ BS_EDGE_CONNECTOR_IN_USE
@ BS_ITEM_TYPE_SILKSCREEN
@ BS_ITEM_TYPE_DIELECTRIC
@ BS_ITEM_TYPE_SOLDERPASTE
@ BS_ITEM_TYPE_SOLDERMASK
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
BASE_SET & reset(size_t pos)
BASE_SET & set(size_t pos)
This class handle bitmap images in KiCad.
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
virtual bool SetNetCode(int aNetCode, bool aNoAssert)
Set net using a net code.
virtual void SetNet(NETINFO_ITEM *aNetInfo)
Set a NET_INFO object for the item.
Container for design settings for a BOARD object.
DIM_PRECISION m_DimensionPrecision
Number of digits after the decimal.
std::shared_ptr< NET_SETTINGS > m_NetSettings
int m_CopperEdgeClearance
void SetGridOrigin(const VECTOR2I &aOrigin)
bool m_TextUpright[LAYER_CLASS_COUNT]
std::vector< DIFF_PAIR_DIMENSION > m_DiffPairDimensionsList
bool m_AllowSoldermaskBridgesInFPs
std::unique_ptr< PAD > m_Pad_Master
void SetAuxOrigin(const VECTOR2I &aOrigin)
int m_SolderMaskExpansion
BOARD_STACKUP & GetStackupDescriptor()
int m_TextThickness[LAYER_CLASS_COUNT]
std::vector< int > m_TrackWidthList
int m_LineThickness[LAYER_CLASS_COUNT]
double m_SolderPasteMarginRatio
ZONE_SETTINGS & GetDefaultZoneSettings()
VECTOR2I m_TextSize[LAYER_CLASS_COUNT]
bool m_TextItalic[LAYER_CLASS_COUNT]
DIM_UNITS_MODE m_DimensionUnitsMode
std::vector< VIA_DIMENSION > m_ViasDimensionsList
int m_ViasMinAnnularWidth
Abstract interface for BOARD_ITEMs capable of storing other items inside.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
void SetUuidDirect(const KIID &aUuid)
Raw UUID assignment.
void SetLocked(bool aLocked) override
virtual void SetIsKnockout(bool aKnockout)
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
FOOTPRINT * GetParentFootprint() const
virtual void RunOnChildren(const std::function< void(BOARD_ITEM *)> &aFunction, RECURSE_MODE aMode) const
Invoke a function on all children.
BOARD_ITEM_CONTAINER * GetParent() const
Manage one layer needed to make a physical board.
void AddDielectricPrms(int aDielectricPrmsIdx)
Add (insert) a DIELECTRIC_PRMS item to m_DielectricPrmsList all values are set to default.
void SetDielectricLayerId(int aLayerId)
void SetThickness(int aThickness, int aDielectricSubLayer=0)
void SetDielectricModel(DIELECTRIC_MODEL aModel, int aDielectricSubLayer=0)
void SetThicknessLocked(bool aLocked, int aDielectricSubLayer=0)
void SetSpecFreq(double aSpecFreq, int aDielectricSubLayer=0)
void SetMaterial(const wxString &aName, int aDielectricSubLayer=0)
void SetLossTangent(double aTg, int aDielectricSubLayer=0)
BOARD_STACKUP_ITEM_TYPE GetType() const
void SetBrdLayerId(PCB_LAYER_ID aBrdLayerId)
void SetTypeName(const wxString &aName)
void SetColor(const wxString &aColorName, int aDielectricSubLayer=0)
void SetEpsilonR(double aEpsilon, int aDielectricSubLayer=0)
Manage layers needed to make a physical board.
void RemoveAll()
Delete all items in list and clear the list.
bool m_HasDielectricConstrains
True if some layers have impedance controlled tracks or have specific constrains for micro-wave appli...
void Add(BOARD_STACKUP_ITEM *aItem)
Add a new item in stackup layer.
void BuildDefaultStackupList(const BOARD_DESIGN_SETTINGS *aSettings, int aActiveCopperLayersCount=0)
Create a default stackup, according to the current BOARD_DESIGN_SETTINGS settings.
bool m_EdgePlating
True if the edge board is plated.
BS_EDGE_CONNECTOR_CONSTRAINTS m_EdgeConnectorConstraints
If the board has edge connector cards, some constrains can be specified in job file: BS_EDGE_CONNECTO...
wxString m_FinishType
The name of external copper finish.
Information pertinent to a Pcbnew printed circuit board.
const std::unordered_map< KIID, BOARD_ITEM * > & GetItemByIdCache() const
KICAD_T Type() const
Returns the type of object.
virtual EMBEDDED_FILES * GetEmbeddedFiles()
SHAPE_POLY_SET & GetPolyShape()
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
virtual void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
void SetUnresolvedFontName(const wxString &aFontName)
virtual const wxString & GetText() const
Return the string associated with the text object.
virtual void SetTextPos(const VECTOR2I &aPoint)
void SetMirrored(bool isMirrored)
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
void SetBoldFlag(bool aBold)
Set only the bold flag, without changing the font.
virtual void SetVisible(bool aVisible)
bool GetAutoThickness() const
void SetLineSpacing(double aLineSpacing)
virtual void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
void SetItalicFlag(bool aItalic)
Set only the italic flag, without changing the font.
void SetKeepUpright(bool aKeepUpright)
virtual void SetText(const wxString &aText)
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
void ParseEmbedded(EMBEDDED_FILES *aFiles)
const std::vector< wxString > * UpdateFontFiles()
Helper function to get a list of fonts for fontconfig to add to the library.
EXTRUSION_MATERIAL m_material
VECTOR3D m_Offset
3D model offset (mm)
VECTOR3D m_Rotation
3D model rotation (degrees)
VECTOR3D m_Scale
3D model scaling factor (dimensionless)
wxString m_Filename
The 3D shape filename in 3D library.
bool m_Show
Include model in rendering.
static GAL_SET DefaultVisible()
A factory which returns an instance of a PCB_GENERATOR.
PCB_GENERATOR * CreateFromType(const wxString &aTypeStr)
static GENERATORS_MGR & Instance()
virtual const wxString What() const
A composite of Problem() and Where()
A color representation with 4 components: red, green, blue, alpha.
COLOR4D WithAlpha(double aAlpha) const
Return a color with the same color, but the given alpha.
wxColour ToColour() const
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
wxString AsString() const
A logical library item identifier and consists of various portions much like a URI.
int Parse(const UTF8 &aId, bool aFix=false)
Parse LIB_ID with the information from aId.
LSET is a set of PCB_LAYER_IDs.
static const LSET & AllCuMask()
return AllCuMask( MAX_CU_LAYERS );
static int NameToLayer(wxString &aName)
Return the layer number from a layer name.
LSEQ Seq(const LSEQ &aSequence) const
Return an LSEQ from the union of this LSET and a desired sequence.
static const LSET & AllTechMask()
Return a mask holding all technical layers (no CU layer) on both side.
static LSET AllCuMask(int aCuLayerCount)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
static const LSET & InternalCuMask()
Return a complete set of internal copper layers which is all Cu layers except F_Cu and B_Cu.
static wxString Name(PCB_LAYER_ID aLayerId)
Return the fixed name association with aLayerId.
bool Contains(PCB_LAYER_ID aLayer) const
See if the layer set contains a PCB layer.
Handle the data for a net.
static const int UNCONNECTED
Constant that holds the "unconnected net" number (typically 0) all items "connected" to this net are ...
static const int ORPHANED
Constant that forces initialization of a netinfo item to the NETINFO_ITEM ORPHANED (typically -1) whe...
std::shared_ptr< NETCLASS > GetDefaultNetclass() const
Gets the default netclass for the project.
A PADSTACK defines the characteristics of a single or multi-layer pad, in the IPC sense of the word.
std::optional< int > & Clearance(PCB_LAYER_ID aLayer=F_Cu)
void AddPrimitive(PCB_SHAPE *aShape, PCB_LAYER_ID aLayer)
Adds a custom shape primitive to the padstack.
MASK_LAYER_PROPS & FrontOuterLayers()
void SetThermalSpokeAngle(EDA_ANGLE aAngle, PCB_LAYER_ID aLayer=F_Cu)
std::optional< int > & ThermalSpokeWidth(PCB_LAYER_ID aLayer=F_Cu)
std::optional< int > & ThermalGap(PCB_LAYER_ID aLayer=F_Cu)
void SetAnchorShape(PAD_SHAPE aShape, PCB_LAYER_ID aLayer)
@ CUSTOM
Shapes can be defined on arbitrary layers.
@ FRONT_INNER_BACK
Up to three shapes can be defined (F_Cu, inner copper layers, B_Cu)
MASK_LAYER_PROPS & BackOuterLayers()
void SetSize(const VECTOR2I &aSize, PCB_LAYER_ID aLayer)
static constexpr PCB_LAYER_ID ALL_LAYERS
! Temporary layer identifier to identify code that is not padstack-aware
static constexpr PCB_LAYER_ID INNER_LAYERS
! The layer identifier to use for "inner layers" on top/inner/bottom padstacks
std::optional< ZONE_CONNECTION > & ZoneConnection(PCB_LAYER_ID aLayer=F_Cu)
void SetAnchorPadShape(PCB_LAYER_ID aLayer, PAD_SHAPE aShape)
Set the shape of the anchor pad for custom shaped pads.
void SetShape(PCB_LAYER_ID aLayer, PAD_SHAPE aShape)
Set the new shape of this pad.
void SetDelta(PCB_LAYER_ID aLayer, const VECTOR2I &aSize)
void SetCustomShapeInZoneOpt(CUSTOM_SHAPE_ZONE_MODE aOption)
Set the option for the custom pad shape to use as clearance area in copper zones.
void SetChamferRectRatio(PCB_LAYER_ID aLayer, double aChamferScale)
Has meaning only for chamfered rectangular pads.
const PADSTACK & Padstack() const
void SetDrillSize(const VECTOR2I &aSize)
void SetLibOffset(PCB_LAYER_ID aLayer, const VECTOR2I &aOffset)
void SetLibSize(PCB_LAYER_ID aLayer, const VECTOR2I &aSize)
void SetSize(PCB_LAYER_ID aLayer, const VECTOR2I &aSize)
void SetChamferPositions(PCB_LAYER_ID aLayer, int aPositions)
Has meaning only for chamfered rectangular pads.
void SetRoundRectRadiusRatio(PCB_LAYER_ID aLayer, double aRadiusScale)
Has meaning only for rounded rectangle pads.
Describe the page size and margins of a paper page on which to eventually print or plot.
void SetPortrait(bool aIsPortrait)
Rotate the paper page 90 degrees.
bool SetType(PAGE_SIZE_TYPE aPageSize, bool aIsPortrait=false)
Set the name of the page type and also the sizes and margins commonly associated with that type name.
void SetWidthMM(double aWidthInMM)
void SetHeightMM(double aHeightInMM)
const PAGE_SIZE_TYPE & GetType() const
For better understanding of the points that make a dimension:
void SetExtensionHeight(int aHeight)
void UpdateHeight(const VECTOR2I &aCrossbarStart, const VECTOR2I &aCrossbarEnd)
Update the stored height basing on points coordinates.
void SetHeight(int aHeight)
Set the distance from the feature points to the crossbar line.
A leader is a dimension-like object pointing to a specific point.
void SetTextBorder(DIM_TEXT_BORDER aBorder)
An orthogonal dimension is like an aligned dimension, but the extension lines are locked to the X or ...
A radial dimension indicates either the radius or diameter of an arc or circle.
void SetLeaderLength(int aLength)
virtual void SetProperties(const STRING_ANY_MAP &aProps)
virtual void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
A set of BOARD_ITEMs (i.e., without duplicates).
wxString m_generatorVersion
Set to the generator version this board requires.
PCB_TABLECELL * parsePCB_TABLECELL(BOARD_ITEM *aParent)
std::unordered_map< std::string, PCB_LAYER_ID > LAYER_ID_MAP
std::vector< int > m_netCodes
net codes mapping for boards being loaded
void parseOutlinePoints(SHAPE_LINE_CHAIN &aPoly)
Parses possible outline points and stores them into aPoly.
BOARD * parseBOARD_unchecked()
std::set< wxString > m_undefinedLayers
set of layers not defined in layers section
LAYER_MAPPING_HANDLER m_layerMappingHandler
optional remap of appended layers onto dest
void parseZoneLayerProperty(std::map< PCB_LAYER_ID, ZONE_LAYER_PROPERTIES > &aProperties)
PROGRESS_REPORTER * m_progressReporter
optional; may be nullptr
int getNetCode(int aNetCode)
void parseFootprintStackup(FOOTPRINT &aFootprint)
void createOldLayerMapping(std::unordered_map< std::string, std::string > &aMap)
Create a mapping from the (short-lived) bug where layer names were translated.
void parseZoneDefaults(ZONE_SETTINGS &aZoneSettings)
std::unordered_map< std::string, LSET > LSET_MAP
void parsePadstack(PAD *aPad)
void parseEDA_TEXT(EDA_TEXT *aText)
Parse the common settings for any object derived from EDA_TEXT.
bool m_tooRecent
true if version parses as later than supported
PCB_LAYER_ID lookUpLayer(const LAYER_ID_MAP &aMap)
Parse the current token for the layer definition of a BOARD_ITEM object.
void remapAppendedLayers(const std::vector< LAYER > &aSourceLayers, const LSET &aDestInitialEnabled, int aDestInitialCopperCount)
Remap the appended layers onto the destination using m_layerMappingHandler, on mismatch.
void parseNET_CHAINS_SECTION()
PCB_REFERENCE_IMAGE * parsePCB_REFERENCE_IMAGE(BOARD_ITEM *aParent)
LAYER_ID_MAP m_layerIndices
map layer name to it's index
void parsePostMachining(PADSTACK::POST_MACHINING_PROPS &aProps)
FP_3DMODEL * parse3DModel(bool aFileNameAlreadyParsed=false)
void parseTextBoxContent(PCB_TEXTBOX *aTextBox)
FOOTPRINT * parseFOOTPRINT(wxArrayString *aInitialComments=nullptr)
PCB_POINT * parsePCB_POINT()
void pushValueIntoMap(int aIndex, int aValue)
Add aValue value in netcode mapping (m_netCodes) at aIndex.
bool parsePAD_option(PAD *aPad)
bool m_preserveDestinationStackup
append keeps destination stackup
void parseGeneralSection()
void init()
Clear and re-establish m_layerMap with the default layer names.
void parseGROUP(BOARD_ITEM *aParent)
void parseLayer(LAYER *aLayer)
std::pair< std::optional< bool >, std::optional< bool > > parseFrontBackOptBool(bool aAllowLegacyFormat=false)
void skipCurrent()
Skip the current token level, i.e search for the RIGHT parenthesis which closes the current descripti...
void parseMargins(int &aLeft, int &aTop, int &aRight, int &aBottom)
PCB_LAYER_ID parseBoardItemLayer()
Parse the layer definition of a BOARD_ITEM object.
LSET parseLayersForCuItemWithSoldermask()
Parse the layers definition of a BOARD_ITEM object that has a single copper layer and optional solder...
void parseGENERATOR(BOARD_ITEM *aParent)
LSET parseBoardItemLayersAsMask()
Parse the layers definition of a BOARD_ITEM object.
void resolveGroups(BOARD_ITEM *aParent)
Called after parsing a footprint definition or board to build the group membership lists.
void parseDefaultTextDims(BOARD_DESIGN_SETTINGS &aSettings, int aLayer)
std::vector< GROUP_INFO > m_groupInfos
std::optional< bool > parseOptBool()
ZONE * parseZONE(BOARD_ITEM_CONTAINER *aParent)
PCB_TABLE * parsePCB_TABLE(BOARD_ITEM *aParent)
std::vector< GENERATOR_INFO > m_generatorInfos
PCB_TEXTBOX * parsePCB_TEXTBOX(BOARD_ITEM *aParent)
std::chrono::time_point< CLOCK > TIME_PT
PCB_TEXT * parsePCB_TEXT(BOARD_ITEM *aParent, PCB_TEXT *aBaseText=nullptr)
unsigned m_lineCount
for progress reporting
VECTOR2I parseXY()
Parse a coordinate pair (xy X Y) in board units (mm).
void parseTEARDROP_PARAMETERS(TEARDROP_PARAMETERS *tdParams)
PCB_TRACK * parsePCB_TRACK()
int m_requiredVersion
set to the KiCad format version this board requires
PAD * parsePAD(FOOTPRINT *aParent=nullptr)
std::function< bool(wxString aTitle, int aIcon, wxString aMsg, wxString aAction)> m_queryUserCallback
bool m_showLegacySegmentZoneWarning
void parseNet(BOARD_CONNECTED_ITEM *aItem)
FOOTPRINT * parseFOOTPRINT_unchecked(wxArrayString *aInitialComments=nullptr)
void parseRenderCache(EDA_TEXT *text)
Parse the render cache for any object derived from EDA_TEXT.
TIME_PT m_lastProgressTime
for progress reporting
void parseGROUP_members(GROUP_INFO &aGroupInfo)
bool IsValidBoardHeader()
Partially parse the input and check if it matches expected header.
void parseFootprintVariant(FOOTPRINT *aFootprint)
std::pair< wxString, wxString > parseBoardProperty()
LSET_MAP m_layerMasks
map layer names to their masks
bool parseMaybeAbsentBool(bool aDefaultValue)
Parses a boolean flag inside a list that existed before boolean normalization.
int parseBoardUnits()
Parse the current token as an ASCII numeric string with possible leading whitespace into a double pre...
void parseViastack(PCB_VIA *aVia)
void bakeTextBoxLib(PCB_TEXTBOX *aTextBox)
Lift disk-parsed values into PCB_TEXTBOX lib storage for new format files.
bool m_showLegacy5ZoneWarning
PCB_DIMENSION_BASE * parseDIMENSION(BOARD_ITEM *aParent)
LSET lookUpLayerSet(const LSET_MAP &aMap)
std::vector< wxString > m_parseWarnings
Non-fatal warnings collected during parsing.
bool m_appendToExisting
reading into an existing board; reset UUIDs
void parsePCB_TEXT_effects(PCB_TEXT *aText, PCB_TEXT *aBaseText=nullptr)
PCB_SHAPE * parsePCB_SHAPE(BOARD_ITEM *aParent)
void parseDefaults(BOARD_DESIGN_SETTINGS &aSettings)
wxString GetRequiredVersion()
Return a string representing the version of KiCad required to open this file.
PCB_TARGET * parsePCB_TARGET()
PCB_BARCODE * parsePCB_BARCODE(BOARD_ITEM *aParent)
The parser for PCB_PLOT_PARAMS.
Parameters and options when plotting/printing a board.
std::optional< bool > GetLegacyPlotViaOnMaskLayer() const
void Parse(PCB_PLOT_PARAMS_PARSER *aParser)
A PCB_POINT is a 0-dimensional point that is used to mark a position on a PCB, or more usually a foot...
Object to handle a bitmap image that can be inserted in a PCB.
void OverrideLibPoly(const SHAPE_POLY_SET &aPoly)
void SetEnd(const VECTOR2I &aEnd) override
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
void OverrideLibCoords(const VECTOR2I &aStart, const VECTOR2I &aEnd, const VECTOR2I &aArcMid=VECTOR2I(0, 0))
void SetIsProxyItem(bool aIsProxy=true) override
void SetStart(const VECTOR2I &aStart) override
void SetStroke(const STROKE_PARAMS &aStroke) override
void SetLibTextAngle(const EDA_ANGLE &aAngle)
EDA_ANGLE GetTextAngle() const override
void SetBorderEnabled(bool enabled)
void OnFootprintTransformed() override
Hook for items inside a footprint to refresh after the FP transform changes (translate,...
void SetShape(SHAPE_T aShape) override
void SetMarginTop(int aTop)
void SetMarginLeft(int aLeft)
void SetMarginBottom(int aBottom)
void SetMarginRight(int aRight)
int GetLegacyTextMargin() const
void StyleFromSettings(const BOARD_DESIGN_SETTINGS &settings, bool aCheckSide) override
EDA_ANGLE GetTextAngle() const override
void SetLibTextThickness(int aWidth)
void SetLibTextSize(const VECTOR2I &aSize)
void Move(const VECTOR2I &aMoveVector) override
Move this object.
int GetTextThickness() const override
void SetTextAngle(const EDA_ANGLE &aAngle) override
VECTOR2I GetTextSize() const override
void Rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle) override
Rotate this object.
void SetLibTextPos(const VECTOR2I &aPos)
const PADSTACK & Padstack() const
A REFERENCE_IMAGE is a wrapper around a BITMAP_IMAGE that is displayed in an editor as a reference fo...
bool ReadImageFile(const wxString &aFullFilename)
Read and store an image file.
const BITMAP_BASE & GetImage() const
Get the underlying image.
double GetImageScale() const
void SetImageScale(double aScale)
Set the image "zoom" value.
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
int PointCount() const
Return the number of points (vertices) in this line chain.
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
Represent a set of closed polygons.
void RemoveAllContours()
Remove all outlines & holes (clears) the polygon set.
void BooleanAdd(const SHAPE_POLY_SET &b)
Perform boolean polyset union.
ITERATOR IterateWithHoles(int aOutline)
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new outline to the set and returns its index.
void SetVertex(const VERTEX_INDEX &aIndex, const VECTOR2I &aPos)
Accessor function to set the position of a specific point.
bool IsEmpty() const
Return true if the set is empty (no polygons at all)
int AddHole(const SHAPE_LINE_CHAIN &aHole, int aOutline=-1)
Adds a new hole to the given outline (default: last) and returns its index.
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
int NewOutline()
Creates a new empty polygon in the set and returns its index.
int OutlineCount() const
Return the number of outlines in the set.
A name/value tuple with unique names and wxAny values.
void ParseStroke(STROKE_PARAMS &aStroke)
Simple container to manage line stroke parameters.
void SetWidth(int aWidth)
TEARDROP_PARAMETARS is a helper class to handle parameters needed to build teardrops for a board thes...
double m_BestWidthRatio
The height of a teardrop as ratio between height and size of pad/via.
int m_TdMaxLen
max allowed length for teardrops in IU. <= 0 to disable
bool m_AllowUseTwoTracks
True to create teardrops using 2 track segments if the first in too small.
int m_TdMaxWidth
max allowed height for teardrops in IU. <= 0 to disable
double m_BestLengthRatio
The length of a teardrop as ratio between length and size of pad/via.
double m_WidthtoSizeFilterRatio
The ratio (H/D) between the via/pad size and the track width max value to create a teardrop 1....
bool m_TdOnPadsInZones
A filter to exclude pads inside zone fills.
bool m_Enabled
Flag to enable teardrops.
bool m_CurvedEdges
True if the teardrop should be curved.
Hold the information shown in the lower right corner of a plot, printout, or editing view.
void SetRevision(const wxString &aRevision)
void SetComment(int aIdx, const wxString &aComment)
void SetTitle(const wxString &aTitle)
void SetCompany(const wxString &aCompany)
void SetDate(const wxString &aDate)
Set the date field, and defaults to the current time and date.
An 8 bit string that is assuredly encoded in UTF8, and supplies special conversion support to and fro...
ZONE_SETTINGS handles zones parameters.
std::map< PCB_LAYER_ID, ZONE_LAYER_PROPERTIES > m_LayerProperties
Handle a list of polygons defining a copper zone.
void HatchBorder()
Compute the hatch lines depending on the hatch parameters and stores it in the zone's attribute m_bor...
SHAPE_POLY_SET * Outline()
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
void SetLayerSetAndRemoveUnusedFills(const LSET &aLayerSet)
Set the zone to be on the aLayerSet layers and only remove the fill polygons from the unused layers,...
static int GetDefaultHatchPitch()
int GetNumCorners(void) const
Access to m_Poly parameters.
A type-safe container of any type.
constexpr any() noexcept
Default constructor, creates an empty object.
This file is part of the common library.
void TransformOvalToPolygon(SHAPE_POLY_SET &aBuffer, const VECTOR2I &aStart, const VECTOR2I &aEnd, int aWidth, int aError, ERROR_LOC aErrorLoc, int aMinSegCount=0)
Convert a oblong shape to a polygon, using multiple segments.
@ RECT_CHAMFER_BOTTOM_RIGHT
@ RECT_CHAMFER_BOTTOM_LEFT
@ ROUND_ALL_CORNERS
All angles are rounded.
static constexpr EDA_ANGLE ANGLE_0
static constexpr EDA_ANGLE ANGLE_90
static constexpr EDA_ANGLE ANGLE_45
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
@ FILLED_SHAPE
Fill with object color.
EDA_DATA_TYPE
The type of unit.
const wxChar *const traceKicadPcbPlugin
Flag to enable KiCad PCB plugin debug output.
void ignore_unused(const T &)
#define THROW_IO_ERROR(msg)
macro which captures the "call site" values of FILE_, __FUNCTION & LINE
#define THROW_PARSE_ERROR(aProblem, aSource, aInputLine, aLineNumber, aByteIndex)
#define MIN_VISIBILITY_MASK
bool IsCopperLayer(int aLayerId)
Test whether a layer is a copper layer.
PCB_LAYER_ID
A quick note on layer IDs:
This file contains miscellaneous commonly used macros and functions.
KICOMMON_API bool FetchUnitsFromString(const wxString &aTextValue, EDA_UNITS &aUnits)
Write any unit info found in the string to aUnits.
KICOMMON_API double GetScaleForInternalUnitType(const EDA_IU_SCALE &aIuScale, EDA_DATA_TYPE aDataType)
Returns the scaling parameter for the given units data type.
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
@ NPTH
like PAD_PTH, but not plated mechanical use only, no connection allowed
@ SMD
Smd pad, appears on the solder paste layer (default)
@ PTH
Plated through hole pad.
@ CONN
Like smd, does not appear on the solder paste layer (default) Note: also has a special attribute in G...
@ FIDUCIAL_LOCAL
a fiducial (usually a smd) local to the parent footprint
@ FIDUCIAL_GLBL
a fiducial (usually a smd) for the full board
@ MECHANICAL
a pad used for mechanical support
@ PRESSFIT
a PTH with a hole diameter with tight tolerances for press fit pin
@ HEATSINK
a pad used as heat sink, usually in SMD footprints
@ NONE
no special fabrication property
@ TESTPOINT
a test point pad
@ CASTELLATED
a pad with a castellated through hole
@ BGA
Smd pad, used in BGA footprints.
#define MAX_PAGE_SIZE_PCBNEW_MM
#define MIN_PAGE_SIZE_MM
Min and max page sizes for clamping, in mm.
BARCODE class definition.
DIM_TEXT_POSITION
Where to place the text on a dimension.
@ MANUAL
Text placement is manually set by the user.
DIM_UNITS_FORMAT
How to display the units in a dimension's text.
DIM_UNITS_MODE
Used for storing the units selection in the file because EDA_UNITS alone doesn't cut it.
DIM_TEXT_BORDER
Frame to show around dimension text.
Class to handle a set of BOARD_ITEMs.
#define FIRST_FP_AFFINE_TRANSFORM
First version that stores footprint children in library frame.
#define SEXPR_BOARD_FILE_VERSION
Current s-expression file format version. 2 was the last legacy format version.
#define LEGACY_ARC_FORMATTING
These were the last to use old arc formatting.
#define LEGACY_NET_TIES
These were the last to use the keywords field to indicate a net-tie.
#define BOARD_FILE_HOST_VERSION
Earlier files than this include the host tag.
constexpr double INT_LIMIT
Pcbnew s-expression file format parser definition.
PGM_BASE & Pgm()
The global program "get" accessor.
static bool IsNumber(char x)
double parseDouble(LINE_READER &aReader, const char *aLine, const char **aOutput)
Parses an ASCII point string with possible leading whitespace into a double precision floating point ...
#define DEFAULT_SOLDERMASK_OPACITY
wxString ConvertToNewOverbarNotation(const wxString &aOldStr)
Convert the old ~...~ overbar notation to the new ~{...} one.
wxString From_UTF8(const char *cstring)
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Container to handle a stock of specific differential pairs each with unique track width,...
Container to hold information pertinent to a layer of a BOARD.
LAYER_T m_type
The type of the layer.
wxString m_name
The canonical name of the layer.
wxString m_userName
The user defined name of the layer.
int m_number
The layer ID.
! The properties of a padstack drill. Drill position is always the pad position (origin).
VECTOR2I size
Drill diameter (x == y) or slot dimensions (x != y)
std::optional< bool > has_solder_mask
True if this outer layer has mask (is not tented)
std::optional< PAD_DRILL_POST_MACHINING_MODE > mode
A filename or source description, a problem input line, a line number, a byte offset,...
Convert net code using the mapping table if available, otherwise returns unchanged net code if < 0 or...
STRING_ANY_MAP properties
std::vector< KIID > memberUuids
Parameters that drive copper-thieving fill generation.
Container to handle a stock of specific vias each with unique diameter and drill sizes in the BOARD c...
std::optional< VECTOR2I > hatching_offset
wxString GetUserFieldName(int aFieldNdx, bool aTranslateForHI)
@ USER
The field ID hasn't been set yet; field is invalid.
@ DESCRIPTION
Field Description of part, i.e. "1/4W 1% Metal Film Resistor".
@ FOOTPRINT
Field Name Module PCB, i.e. "16DIP300".
@ REFERENCE
Field Reference of part, i.e. "IC21".
@ VALUE
Field Value of part, i.e. "3.3K".
KIBIS top(path, &reporter)
std::vector< std::vector< std::string > > table
const SHAPE_LINE_CHAIN chain
wxLogTrace helper definitions.
@ PCB_DIM_ORTHOGONAL_T
class PCB_DIM_ORTHOGONAL, a linear dimension constrained to x/y
@ PCB_DIM_LEADER_T
class PCB_DIM_LEADER, a leader dimension (graphic item)
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
@ PCB_BARCODE_T
class PCB_BARCODE, a barcode (graphic item)
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
@ PCB_DIM_ALIGNED_T
class PCB_DIM_ALIGNED, a linear dimension (graphic item)
@ PCB_DIM_RADIAL_T
class PCB_DIM_RADIAL, a radius or diameter dimension
VECTOR2< int32_t > VECTOR2I
ISLAND_REMOVAL_MODE
Whether or not to remove isolated islands from a zone.
ZONE_BORDER_DISPLAY_STYLE
Zone border styles.
ZONE_CONNECTION
How pads are covered by copper in zone.
@ THT_THERMAL
Thermal relief only for THT pads.
@ NONE
Pads are not covered.
@ FULL
pads are covered by copper